@adatechnology/game-items-three 0.6.0 → 0.6.2

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.
@@ -1731,6 +1731,90 @@ var GameItemsThree = (() => {
1731
1731
  return mesh2;
1732
1732
  });
1733
1733
  }
1734
+ var isTexture = (v) => !!v && typeof v === "object" && v.isTexture === true;
1735
+ function texturesOf(material, out) {
1736
+ for (const value of Object.values(material)) if (isTexture(value)) out.add(value);
1737
+ const uniforms = material.uniforms;
1738
+ if (uniforms) {
1739
+ for (const u of Object.values(uniforms)) if (isTexture(u?.value)) out.add(u.value);
1740
+ }
1741
+ }
1742
+ function collect(roots) {
1743
+ const geometries = /* @__PURE__ */ new Set();
1744
+ const materials = /* @__PURE__ */ new Set();
1745
+ const textures = /* @__PURE__ */ new Set();
1746
+ const skeletons = /* @__PURE__ */ new Set();
1747
+ for (const root of roots) {
1748
+ root.traverse((object2) => {
1749
+ const o = object2;
1750
+ if (o.geometry && typeof o.geometry.dispose === "function") geometries.add(o.geometry);
1751
+ if (o.skeleton && typeof o.skeleton.dispose === "function") skeletons.add(o.skeleton);
1752
+ const list2 = Array.isArray(o.material) ? o.material : o.material ? [o.material] : [];
1753
+ for (const m of list2) {
1754
+ if (!m || typeof m.dispose !== "function") continue;
1755
+ materials.add(m);
1756
+ texturesOf(m, textures);
1757
+ }
1758
+ });
1759
+ }
1760
+ return { geometries, materials, textures, skeletons };
1761
+ }
1762
+ var marked = /* @__PURE__ */ new WeakSet();
1763
+ var shared = (r) => r.userData?.shared === true || marked.has(r);
1764
+ function releaseObject3D(roots, options = {}) {
1765
+ const list2 = Array.isArray(roots) ? roots : [roots];
1766
+ const report = { geometries: 0, materials: 0, textures: 0 };
1767
+ if (list2.length === 0) return report;
1768
+ const found = collect(list2);
1769
+ const keepRoots = options.keep === void 0 ? [] : Array.isArray(options.keep) ? options.keep : [options.keep];
1770
+ const releasing = new Set(list2);
1771
+ for (const keep of keepRoots) {
1772
+ const walk = (o) => {
1773
+ if (releasing.has(o)) return;
1774
+ const owner = o;
1775
+ if (owner.geometry) found.geometries.delete(owner.geometry);
1776
+ if (owner.skeleton) found.skeletons.delete(owner.skeleton);
1777
+ const mats = Array.isArray(owner.material) ? owner.material : owner.material ? [owner.material] : [];
1778
+ for (const m of mats) {
1779
+ if (!m) continue;
1780
+ found.materials.delete(m);
1781
+ const t = /* @__PURE__ */ new Set();
1782
+ texturesOf(m, t);
1783
+ for (const x of t) found.textures.delete(x);
1784
+ }
1785
+ for (const c of o.children) walk(c);
1786
+ };
1787
+ walk(keep);
1788
+ }
1789
+ for (const g of found.geometries) {
1790
+ if (shared(g)) continue;
1791
+ g.dispose();
1792
+ report.geometries++;
1793
+ }
1794
+ for (const m of found.materials) {
1795
+ if (shared(m)) continue;
1796
+ m.dispose();
1797
+ report.materials++;
1798
+ }
1799
+ for (const t of found.textures) {
1800
+ if (shared(t)) continue;
1801
+ t.dispose();
1802
+ report.textures++;
1803
+ }
1804
+ for (const s of found.skeletons) s.dispose();
1805
+ return report;
1806
+ }
1807
+ function discardObject3D(objects, options = {}) {
1808
+ const list2 = Array.isArray(objects) ? objects : [objects];
1809
+ const keep = options.keep === void 0 ? [] : Array.isArray(options.keep) ? [...options.keep] : [options.keep];
1810
+ for (const object2 of list2) {
1811
+ let top = object2;
1812
+ while (top.parent) top = top.parent;
1813
+ object2.removeFromParent();
1814
+ if (top !== object2 && !keep.includes(top)) keep.push(top);
1815
+ }
1816
+ return releaseObject3D(list2, { keep });
1817
+ }
1734
1818
 
1735
1819
  // src/kit.ts
1736
1820
  var WEAR_TAGS = ["metal", "wood", "cloth", "plastic", "paper", "food", "glass"];
@@ -15340,6 +15424,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
15340
15424
  var CHIP_ENERGY = 200;
15341
15425
  var CHIP_SPLASH = 0.5;
15342
15426
  var CRATER_SPENT = 0.6;
15427
+ var EDGE_REACH = 1.5;
15343
15428
  var BAR_BOW = 0.08;
15344
15429
  var BULLET_JOINT_SPAN = 0.3;
15345
15430
  var CUT_SLICE = 1;
@@ -16713,6 +16798,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
16713
16798
  const lo = cell.center[a] - cell.size[a] / 2 + w / 2, hi = cell.center[a] + cell.size[a] / 2 - w / 2;
16714
16799
  size[a] = w;
16715
16800
  center[a] = clamp2(lp[a], lo, hi);
16801
+ const [from, to] = tornToEdge({ p, cell, a, b: a === u ? v : u, at: lp[a], crater: [center[a] - w / 2, center[a] + w / 2], reach: w * EDGE_REACH, gone: (k) => worn[k] === -1 });
16802
+ size[a] = to - from;
16803
+ center[a] = (from + to) / 2;
16716
16804
  }
16717
16805
  const taken2 = (cut[i] ?? 0) + size[u] * size[v];
16718
16806
  if (taken2 >= cell.size[u] * cell.size[v] * CRATER_SPENT) {
@@ -16750,6 +16838,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
16750
16838
  collapseCheck(o, src);
16751
16839
  }
16752
16840
  };
16841
+ const tornToEdge = (o) => {
16842
+ const { p, cell, a, b, at, crater: crater2, reach, gone } = o;
16843
+ const half = p.dims[a] / 2;
16844
+ const lo = cell.center[a] - cell.size[a] / 2, hi = cell.center[a] + cell.size[a] / 2;
16845
+ const free = (side, sign2) => {
16846
+ if (sign2 > 0 ? side >= half - 1e-6 : side <= -half + 1e-6) return sign2 > 0 || a !== planeAxes(p.thin)[1];
16847
+ const probe = side + sign2 * 1e-3;
16848
+ return gridOf(p).some((c, k) => gone(k) && Math.abs(probe - c.center[a]) <= c.size[a] / 2 && Math.abs(cell.center[b] - c.center[b]) <= c.size[b] / 2);
16849
+ };
16850
+ if (at - lo <= reach && free(lo, -1)) return [lo, Math.max(crater2[1], lo)];
16851
+ if (hi - at <= reach && free(hi, 1)) return [Math.min(crater2[0], hi), hi];
16852
+ return crater2;
16853
+ };
16753
16854
  const craterAcross = (energy) => clamp2(0.03 + 12e-4 * Math.sqrt(Math.max(0, energy)), 0.03, 0.14);
16754
16855
  const craterFragments = (o, p, cell, dir, speed, mass, tag) => {
16755
16856
  const { c, q } = partXf(o, p);
@@ -21443,9 +21544,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
21443
21544
  var SHARED_ROOMS = { west: { type: "laundry", label: "laundry_room" }, east: { type: "storage", label: "storage_room" } };
21444
21545
  var apartments = (plan) => (strip, { floor, plate, ceiling }) => {
21445
21546
  if (strip.length < plan.apartmentMin) {
21446
- const shared = SHARED_ROOMS[strip.id] ?? SHARED_ROOMS.east;
21447
- const id = `${shared.label}_${floor}_${strip.id}`;
21448
- return { rooms: [{ id, type: shared.type, label: shared.label, rect: [...strip.rect] }], doors: [stripDoor(id, strip, floor, 0.9)], windows: exteriorWindows(id, strip.rect, plate, ceiling, { ...plan.window, width: 1.2 }) };
21547
+ const shared2 = SHARED_ROOMS[strip.id] ?? SHARED_ROOMS.east;
21548
+ const id = `${shared2.label}_${floor}_${strip.id}`;
21549
+ return { rooms: [{ id, type: shared2.type, label: shared2.label, rect: [...strip.rect] }], doors: [stripDoor(id, strip, floor, 0.9)], windows: exteriorWindows(id, strip.rect, plate, ceiling, { ...plan.window, width: 1.2 }) };
21449
21550
  }
21450
21551
  const count = Math.max(1, Math.round(strip.length / plan.apartment)), wide = strip.length / count;
21451
21552
  const parts = Array.from({ length: count }, (_, k) => apartment(strip, floor, k, r22(k * wide), r22((k + 1) * wide), plate, ceiling, plan.window));
@@ -21559,7 +21660,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
21559
21660
  var OPEN_ROOM_TYPES2 = /* @__PURE__ */ new Set(["balcony", "terrace", "veranda", "balcony_gourmet"]);
21560
21661
  var rectsOf = (c) => c.parts && c.parts.length ? c.parts : [[c.u0, c.v0, c.u1, c.v1]];
21561
21662
  var isOpenArea = (c) => OPEN_ROOM_TYPES2.has(c.type) || c.outdoor === true;
21562
- function installKernelGeometry(K, shared) {
21663
+ function installKernelGeometry(K, shared2) {
21563
21664
  const { THREE } = K;
21564
21665
  const GEO = {};
21565
21666
  {
@@ -21618,9 +21719,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
21618
21719
  const cursor = { group: "lot", accs: /* @__PURE__ */ new Map(), rot: [], org: [0, 0, 0], ry: 0 };
21619
21720
  const PARTS = [];
21620
21721
  const MIRRORS = [];
21621
- shared.partCount = 0;
21722
+ shared2.partCount = 0;
21622
21723
  function part(type, pos, fn, meta = {}, parent, ry = 0) {
21623
- const gA = cursor.group, oA = cursor.org, rA = cursor.ry, pieceA = cursor.pc, name = "part:" + (meta.id || type) + ":" + shared.partCount++;
21724
+ const gA = cursor.group, oA = cursor.org, rA = cursor.ry, pieceA = cursor.pc, name = "part:" + (meta.id || type) + ":" + shared2.partCount++;
21624
21725
  PARTS.push({ name, parent: parent || gA, pos: pos.slice(), type, meta, ry });
21625
21726
  cursor.group = name;
21626
21727
  cursor.org = pos;
@@ -21655,7 +21756,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
21655
21756
  }
21656
21757
  const _Y = new THREE.Vector3(0, 1, 0), _qa = new THREE.Quaternion(), _qb = new THREE.Quaternion();
21657
21758
  function pieceRecord(id, mat, role, extra) {
21658
- const M = shared.ctx.pieces;
21759
+ const M = shared2.ctx.pieces;
21659
21760
  let p = M.get(id);
21660
21761
  if (!p) {
21661
21762
  p = Object.assign({ id, mat, role: role || null }, extra);
@@ -21664,7 +21765,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
21664
21765
  return p;
21665
21766
  }
21666
21767
  const structurePiece = (id) => {
21667
- const e = shared.ctx.structureIndex && shared.ctx.structureIndex[id];
21768
+ const e = shared2.ctx.structureIndex && shared2.ctx.structureIndex[id];
21668
21769
  return e ? pieceRecord(id, e.material, e.role, { floor: e.floor }) : null;
21669
21770
  };
21670
21771
  function accFor(mat) {
@@ -22113,7 +22214,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22113
22214
  const NO_SHADOW = /* @__PURE__ */ new Set(["dirt", "glass", "water", "screen", "building", "picture", "floor", "emissive"]);
22114
22215
  Object.assign(K, { createMaterials, antiTile, dirtMaterial, CLOTHES_UNIFORMS, clothesMaterial, ORDER, NO_SHADOW });
22115
22216
  }
22116
- function installKernelCloseScene(K, shared) {
22217
+ function installKernelCloseScene(K, shared2) {
22117
22218
  const { THREE, NO_SHADOW, ORDER, PARTS, applyPart, cursor } = K;
22118
22219
  const assembleCars = (...a) => K.assembleCars(...a);
22119
22220
  const assembleMirrors = (...a) => K.assembleMirrors(...a);
@@ -22128,7 +22229,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22128
22229
  if (!fx.length) return;
22129
22230
  const u = m.userData, ids = [...new Set(fx.map((f) => f.id))], weight = {};
22130
22231
  for (const f of fx) {
22131
- const mt = shared.ctx.pieces.get(f.id).mat;
22232
+ const mt = shared2.ctx.pieces.get(f.id).mat;
22132
22233
  weight[mt] = (weight[mt] || 0) + f.v1 - f.v0;
22133
22234
  }
22134
22235
  u.ranges = fx;
@@ -22136,7 +22237,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22136
22237
  u.destructionMaterial = Object.keys(weight).sort((a, b) => weight[b] - weight[a])[0];
22137
22238
  if (ids.length === 1) {
22138
22239
  u.destructionPart = ids[0];
22139
- const pc = shared.ctx.pieces.get(ids[0]);
22240
+ const pc = shared2.ctx.pieces.get(ids[0]);
22140
22241
  if (pc.role) u.structuralRole = pc.role;
22141
22242
  }
22142
22243
  }
@@ -22179,7 +22280,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22179
22280
  if (P.meta.t0) applyPart(g, P.meta.t0);
22180
22281
  }
22181
22282
  (groups[P.parent] || (groups[P.parent] = new THREE.Group())).add(g);
22182
- if (P.meta.id) (shared.ctx.parts || (shared.ctx.parts = {}))[P.meta.id] = g;
22283
+ if (P.meta.id) (shared2.ctx.parts || (shared2.ctx.parts = {}))[P.meta.id] = g;
22183
22284
  }
22184
22285
  PARTS.length = 0;
22185
22286
  assembleMirrors(groups);
@@ -22189,20 +22290,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22189
22290
  }
22190
22291
  Object.assign(K, { markMesh, closeScene });
22191
22292
  }
22192
- function installHouseHelpers(K, shared) {
22193
- shared.ctx = {};
22293
+ function installHouseHelpers(K, shared2) {
22294
+ shared2.ctx = {};
22194
22295
  const OPEN_ROOM_TYPES22 = /* @__PURE__ */ new Set(["balcony", "terrace", "veranda", "balcony_gourmet"]);
22195
22296
  const NO_CEILING = OPEN_ROOM_TYPES22;
22196
22297
  const OPEN_AREA = (c) => OPEN_ROOM_TYPES22.has(c.type) || c.outdoor === true;
22197
22298
  const EPS3 = 1e-3;
22198
22299
  const Y0 = (f) => {
22199
- const A = shared.ctx.r.floors;
22300
+ const A = shared2.ctx.r.floors;
22200
22301
  return A[Math.max(0, Math.min(A.length - 1, f))].y0;
22201
22302
  };
22202
- const colorOf = (v) => typeof v === "number" ? v : typeof v === "string" && shared.ctx.colors[v] != null ? shared.ctx.colors[v] : null;
22303
+ const colorOf = (v) => typeof v === "number" ? v : typeof v === "string" && shared2.ctx.colors[v] != null ? shared2.ctx.colors[v] : null;
22203
22304
  const rectsOf2 = (c) => c.parts && c.parts.length ? c.parts : [[c.u0, c.v0, c.u1, c.v1]];
22204
22305
  function roomAt(f, u, v) {
22205
- for (const c of shared.ctx.r.rooms) if (c.floor === f) {
22306
+ for (const c of shared2.ctx.r.rooms) if (c.floor === f) {
22206
22307
  for (const [a, b, c2, d] of rectsOf2(c)) if (u > a + EPS3 && u < c2 - EPS3 && v > b + EPS3 && v < d - EPS3) return c;
22207
22308
  }
22208
22309
  return null;
@@ -22230,14 +22331,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22230
22331
  return [Math.min(...pts.map((p) => p[0])), Math.min(...pts.map((p) => p[1])), Math.max(...pts.map((p) => p[0])), Math.max(...pts.map((p) => p[1]))];
22231
22332
  }
22232
22333
  function effectiveHeight(f, h) {
22233
- const A = shared.ctx.r.floors;
22334
+ const A = shared2.ctx.r.floors;
22234
22335
  if (f + 1 >= A.length) return h;
22235
22336
  const pitch = A[f + 1].y0 - A[f].y0;
22236
22337
  return h > pitch && h - pitch <= 0.45 ? pitch : h;
22237
22338
  }
22238
22339
  Object.assign(K, { OPEN_ROOM_TYPES: OPEN_ROOM_TYPES22, NO_CEILING, OPEN_AREA, EPS: EPS3, Y0, colorOf, rectsOf: rectsOf2, roomAt, subRect, subRects, wallColor, floorColor, stairFootprint, effectiveHeight });
22239
22340
  }
22240
- function installHouseWalls(K, shared) {
22341
+ function installHouseWalls(K, shared2) {
22241
22342
  const { EPS: EPS3, Y0, boxC, bx, cursor, effectiveHeight, pieceRecord, structurePiece, wallColor } = K;
22242
22343
  function wallBox(alongU, L, a, b, ya, yb, th, cL, cH, mL, mH) {
22243
22344
  if (yb - ya < 1e-4 || b - a < 1e-4) return;
@@ -22250,10 +22351,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22250
22351
  }
22251
22352
  }
22252
22353
  function sideOf(id, frontLine) {
22253
- const R = shared.ctx.r, F = R.facade;
22254
- if (id === "outside" || !shared.ctx.roomById[id]) {
22354
+ const R = shared2.ctx.r, F = R.facade;
22355
+ if (id === "outside" || !shared2.ctx.roomById[id]) {
22255
22356
  const ac = F.finish;
22256
- let mat = "plaster", color2 = shared.ctx.colors.facade;
22357
+ let mat = "plaster", color2 = shared2.ctx.colors.facade;
22257
22358
  if (ac === "roughcast") mat = "roughcast";
22258
22359
  else if (ac === "exposed_block") {
22259
22360
  mat = "block";
@@ -22264,12 +22365,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22264
22365
  }
22265
22366
  return { color: color2, mat, exterior: true };
22266
22367
  }
22267
- return { color: wallColor(shared.ctx.roomById[id]), mat: "plaster", exterior: false };
22368
+ return { color: wallColor(shared2.ctx.roomById[id]), mat: "plaster", exterior: false };
22268
22369
  }
22269
22370
  const pieceOf = (w) => !w.id ? null : structurePiece(w.id) || pieceRecord(w.id, w.material || "brick", w.role || "partition", { floor: w.floor });
22270
22371
  function nearestWall(f, axis, L, c) {
22271
22372
  let m = null, md = 1e9;
22272
- for (const w of shared.ctx.r.walls) {
22373
+ for (const w of shared2.ctx.r.walls) {
22273
22374
  if (w.floor !== f || w.axis !== axis || w.type !== "wall" || Math.abs((axis === "u" ? w.v0 : w.u0) - L) > EPS3) continue;
22274
22375
  const a = Math.min(axis === "u" ? w.u0 : w.v0, axis === "u" ? w.u1 : w.v1), b = Math.max(axis === "u" ? w.u0 : w.v0, axis === "u" ? w.u1 : w.v1), d = c < a ? a - c : c > b ? c - b : 0;
22275
22376
  if (d < md) {
@@ -22280,7 +22381,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22280
22381
  return m;
22281
22382
  }
22282
22383
  function walls() {
22283
- const R = shared.ctx.r, cut = shared.ctx.cut, nA = R.floors.length, vMin = Math.min(...R.walls.map((w) => w.axis === "u" ? w.v0 : Math.min(w.v0, w.v1)));
22384
+ const R = shared2.ctx.r, cut = shared2.ctx.cut, nA = R.floors.length, vMin = Math.min(...R.walls.map((w) => w.axis === "u" ? w.v0 : Math.min(w.v0, w.v1)));
22284
22385
  const corners = /* @__PURE__ */ new Map();
22285
22386
  for (const w of R.walls) {
22286
22387
  const f = w.floor;
@@ -22291,9 +22392,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22291
22392
  const hh = cut ? Math.min(h, 1.2) : h, L = alongU ? w.v0 : w.u0, s0 = Math.min(alongU ? w.u0 : w.v0, alongU ? w.u1 : w.v1), s1 = Math.max(alongU ? w.u0 : w.v0, alongU ? w.u1 : w.v1);
22292
22393
  const front = alongU && Math.abs(L - vMin) < 0.05;
22293
22394
  const sideL = sideOf(w.sides[0], front), sideH = sideOf(w.sides[1], front);
22294
- shared.ctx.colliders.push({ type: "wall", piece: w.id, f, x0: alongU ? s0 : L - th / 2, z0: alongU ? L - th / 2 : s0, x1: alongU ? s1 : L + th / 2, z1: alongU ? L + th / 2 : s1 });
22395
+ shared2.ctx.colliders.push({ type: "wall", piece: w.id, f, x0: alongU ? s0 : L - th / 2, z0: alongU ? L - th / 2 : s0, x1: alongU ? s1 : L + th / 2, z1: alongU ? L + th / 2 : s1 });
22295
22396
  if (w.type === "railing") {
22296
- const c0 = shared.ctx.colors.metal != null ? shared.ctx.colors.metal : 9080466;
22397
+ const c0 = shared2.ctx.colors.metal != null ? shared2.ctx.colors.metal : 9080466;
22297
22398
  const sx = alongU ? 1 : 0, sz = alongU ? 0 : 1, len = s1 - s0, n = Math.max(1, Math.round(len / 1.4));
22298
22399
  const cx_ = alongU ? (s0 + s1) / 2 : L, cz_ = alongU ? L : (s0 + s1) / 2;
22299
22400
  boxC("glass", cx_, y0 + 0.55, cz_, alongU ? len : 0.02, 0.85, alongU ? 0.02 : len, 16777215);
@@ -22340,7 +22441,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22340
22441
  }
22341
22442
  Object.assign(K, { wallBox, sideOf, pieceOf, nearestWall, walls });
22342
22443
  }
22343
- function installHouseDoors(K, shared) {
22444
+ function installHouseDoors(K, shared2) {
22344
22445
  const seedKey = (id) => K.seedKey(id);
22345
22446
  const { EPS: EPS3, Y0, boxC, bx, cursor, effectiveHeight, nearestWall, part, pieceOf, pieceRecord, roomAt, sideOf, wallBox } = K;
22346
22447
  const SEED = (...a) => K.SEED(...a);
@@ -22348,15 +22449,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22348
22449
  const rngString = (...a) => K.rngString(...a);
22349
22450
  const sh = (...a) => K.sh(...a);
22350
22451
  function doorLineSides(p) {
22351
- const R = shared.ctx.r, alongU = p.axis === "u", a = p.at - p.width / 2, b = p.at + p.width / 2;
22452
+ const R = shared2.ctx.r, alongU = p.axis === "u", a = p.at - p.width / 2, b = p.at + p.width / 2;
22352
22453
  const w = R.walls.find((w2) => w2.floor === p.floor && w2.axis === p.axis && Math.abs((alongU ? w2.v0 : w2.u0) - p.pos) < EPS3 && w2.type === "wall" && (Math.abs((alongU ? w2.u1 : w2.v1) - a) < 0.02 || Math.abs((alongU ? w2.u0 : w2.v0) - b) < 0.02));
22353
22454
  const sides = w ? w.sides : [p.a, p.b];
22354
22455
  return [sideOf(sides[0], false), sideOf(sides[1], false)];
22355
22456
  }
22356
- shared.doorState = /* @__PURE__ */ new Map();
22457
+ shared2.doorState = /* @__PURE__ */ new Map();
22357
22458
  function doors() {
22358
- shared.ctx.leaves = [];
22359
- const R = shared.ctx.r, cut = shared.ctx.cut, C = shared.ctx.colors, wood = C.wood != null ? C.wood : 8016948, frame2 = sh(wood, 0.55);
22459
+ shared2.ctx.leaves = [];
22460
+ const R = shared2.ctx.r, cut = shared2.ctx.cut, C = shared2.ctx.colors, wood = C.wood != null ? C.wood : 8016948, frame2 = sh(wood, 0.55);
22360
22461
  for (const p of R.doors) {
22361
22462
  const f = p.floor;
22362
22463
  cursor.group = "f" + f;
@@ -22386,12 +22487,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22386
22487
  }
22387
22488
  const leaf = (u0, u1, y_0, y_1, tt, color2, mat = "wood") => alongU ? bx(mat, u0, y0 + y_0, L - tt / 2, u1, y0 + y_1, L + tt / 2, color2) : bx(mat, L - tt / 2, y0 + y_0, u0, L + tt / 2, y0 + y_1, u1, color2);
22388
22489
  const extC = wood;
22389
- const open0 = p.blocked ? false : shared.doorState.has(p.id) ? shared.doorState.get(p.id) : !!p.open;
22390
- shared.doorState.set(p.id, open0);
22490
+ const open0 = p.blocked ? false : shared2.doorState.has(p.id) ? shared2.doorState.get(p.id) : !!p.open;
22491
+ shared2.doorState.set(p.id, open0);
22391
22492
  const dc = alongU ? [p.at, L] : [L, p.at];
22392
22493
  const fo = { id: p.id, floor: f, type: p.model === "steel" ? "steel" : "swing", open: open0, t: open0 ? 1 : 0, blockedFlag: !!p.blocked, locked: R.state === "fortified" && !!p.exterior, handleNames: [], hT: 0, cx: dc[0], cz: dc[1], visH, groups: [], col: null };
22393
22494
  const colR = { type: "door", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b, off: open0 };
22394
- shared.ctx.colliders.push(colR);
22495
+ shared2.ctx.colliders.push(colR);
22395
22496
  fo.col = colR;
22396
22497
  const leafBox = (hu, d0, d1, y_0, y_1, tt, color2, mat) => alongU ? bx(mat, d0, y_0, -tt / 2, d1, y_1, tt / 2, color2) : bx(mat, -tt / 2, y_0, d0, tt / 2, y_1, d1, color2);
22397
22498
  const newGroup = (k, hu, topY) => {
@@ -22451,7 +22552,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22451
22552
  fo.rot = Math.atan2(n[0] * A[1] - n[1] * A[0], A[0] * n[0] + A[1] * n[1]);
22452
22553
  }
22453
22554
  }
22454
- shared.ctx.leaves.push(fo);
22555
+ shared2.ctx.leaves.push(fo);
22455
22556
  cursor.group = "f" + f;
22456
22557
  if (p.blocked) {
22457
22558
  part("window_boards", [0, 0, 0], () => {
@@ -22479,18 +22580,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22479
22580
  }
22480
22581
  }
22481
22582
  }, { id: "boards:" + p.id }, "f" + f);
22482
- shared.ctx.colliders.push({ type: "board", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b });
22583
+ shared2.ctx.colliders.push({ type: "board", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b });
22483
22584
  }
22484
22585
  }
22485
22586
  }
22486
22587
  Object.assign(K, { doorLineSides, doors });
22487
22588
  }
22488
- function installHouseWindows(K, shared) {
22589
+ function installHouseWindows(K, shared2) {
22489
22590
  const { EPS: EPS3, Y0, boxC, bx, cursor, pieceRecord, roomAt } = K;
22490
22591
  const FRAME_COLORS = { budget: 15856110, mid: 12830924, high: 2829875, commercial: 11844287 };
22491
22592
  const SILL_COLORS = { budget: 15131870, mid: 14277076, high: 3816770, commercial: 13225166 };
22492
22593
  function windows() {
22493
- const R = shared.ctx.r, cut = shared.ctx.cut, C = shared.ctx.colors, structure = R.style, fr = FRAME_COLORS[structure] || FRAME_COLORS.budget, pe_ = SILL_COLORS[structure] || SILL_COLORS.budget;
22594
+ const R = shared2.ctx.r, cut = shared2.ctx.cut, C = shared2.ctx.colors, structure = R.style, fr = FRAME_COLORS[structure] || FRAME_COLORS.budget, pe_ = SILL_COLORS[structure] || SILL_COLORS.budget;
22494
22595
  const boardItems = new Set(R.stateItems.filter((e) => e.type === "window_boards" && e.window).map((e) => e.window));
22495
22596
  for (const j of R.windows) {
22496
22597
  const f = j.floor;
@@ -22543,11 +22644,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22543
22644
  }
22544
22645
  Object.assign(K, { FRAME_COLORS, SILL_COLORS, windows });
22545
22646
  }
22546
- function installHouseFloors(K, shared) {
22647
+ function installHouseFloors(K, shared2) {
22547
22648
  const { rectsOf: rectsOf2, EPS: EPS3, OPEN_AREA, Y0, bx, cursor, floorColor, stairFootprint, structurePiece, subRects } = K;
22548
22649
  function flights() {
22549
- if (shared.ctx._flights && shared.ctx._flights.r === shared.ctx.r) return shared.ctx._flights.l;
22550
- const R = shared.ctx.r, mp = /* @__PURE__ */ new Map();
22650
+ if (shared2.ctx._flights && shared2.ctx._flights.r === shared2.ctx.r) return shared2.ctx._flights.l;
22651
+ const R = shared2.ctx.r, mp = /* @__PURE__ */ new Map();
22551
22652
  for (const m of R.items) {
22552
22653
  if (m.type !== "stairs" || !m.link) continue;
22553
22654
  const k = [m.link.from, m.link.to, m.x.toFixed(2), m.z.toFixed(2), (m.ry || 0).toFixed(2)].join("|");
@@ -22563,12 +22664,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22563
22664
  v.LP = LP;
22564
22665
  v.top = stairFootprint({ x: m.x + lz * Math.sin(m.ry), z: m.z + lz * Math.cos(m.ry), ry: m.ry, w: m.w, d: LP });
22565
22666
  }
22566
- shared.ctx._flights = { r: R, l };
22667
+ shared2.ctx._flights = { r: R, l };
22567
22668
  return l;
22568
22669
  }
22569
22670
  const panelRects = (p) => p.footprint && p.footprint.length ? p.footprint : [p.aabb];
22570
22671
  function tilesOf(parent, rc) {
22571
- const ps = parent && shared.ctx.panelsOf && shared.ctx.panelsOf.get(parent);
22672
+ const ps = parent && shared2.ctx.panelsOf && shared2.ctx.panelsOf.get(parent);
22572
22673
  if (!ps) return [[parent ? structurePiece(parent) : null, rc]];
22573
22674
  const out = [], taken = [];
22574
22675
  for (const p of ps) for (const q of panelRects(p)) {
@@ -22582,14 +22683,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22582
22683
  return out;
22583
22684
  }
22584
22685
  function panelAt(parent, x, z) {
22585
- const ps = shared.ctx.panelsOf && shared.ctx.panelsOf.get(parent);
22686
+ const ps = shared2.ctx.panelsOf && shared2.ctx.panelsOf.get(parent);
22586
22687
  if (!ps) return structurePiece(parent);
22587
22688
  for (const p of ps) for (const q of panelRects(p)) if (x >= q[0] - EPS3 && x <= q[2] + EPS3 && z >= q[1] - EPS3 && z <= q[3] + EPS3) return structurePiece(p.id);
22588
22689
  return null;
22589
22690
  }
22590
- const hasSlab = (id) => !!(shared.ctx.structureIndex[id] || shared.ctx.panelsOf && shared.ctx.panelsOf.has(id));
22691
+ const hasSlab = (id) => !!(shared2.ctx.structureIndex[id] || shared2.ctx.panelsOf && shared2.ctx.panelsOf.has(id));
22591
22692
  function floorsAndSlabs() {
22592
- const R = shared.ctx.r, nA = R.floors.length, C = shared.ctx.colors;
22693
+ const R = shared2.ctx.r, nA = R.floors.length, C = shared2.ctx.colors;
22593
22694
  const V = flights(), holes = (f) => V.filter((v) => v.to === f).flatMap((v) => {
22594
22695
  let rs = [v.rect];
22595
22696
  if (v.top) rs = subRects(rs, [v.top]);
@@ -22626,18 +22727,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22626
22727
  }
22627
22728
  Object.assign(K, { flights, floorsAndSlabs, tilesOf, panelAt });
22628
22729
  }
22629
- function installHouseStairs(K, shared) {
22730
+ function installHouseStairs(K, shared2) {
22630
22731
  const { rectsOf: rectsOf2, Y0, boxC, bx, cursor, flights, stairFootprint, structurePiece } = K;
22631
22732
  const sh = (...a) => K.sh(...a);
22632
22733
  function buildStairs() {
22633
- const R = shared.ctx.r;
22634
- shared.ctx.stairs = [];
22734
+ const R = shared2.ctx.r;
22735
+ shared2.ctx.stairs = [];
22635
22736
  for (const vo of flights()) {
22636
22737
  const m = vo.m, f = vo.from, Dr = m.d - (vo.LP || 0);
22637
22738
  cursor.group = "f" + f;
22638
22739
  cursor.pc = structurePiece("stairs_" + vo.from + "_" + vo.to);
22639
22740
  const y0 = Y0(f), H = Y0(m.link.to) - y0, n = Math.max(8, Math.round(H / 0.18)), c = Math.cos(m.ry), s = Math.sin(m.ry);
22640
- const wood = shared.ctx.colors.wood != null ? shared.ctx.colors.wood : 9071176, under = sh(wood, 0.7);
22741
+ const wood = shared2.ctx.colors.wood != null ? shared2.ctx.colors.wood : 9071176, under = sh(wood, 0.7);
22641
22742
  const P = (lx, lz) => [m.x + lx * c + lz * s, m.z - lx * s + lz * c];
22642
22743
  const boxL = (mat, lx, y, lz, w, h, d, color2, rx = 0) => {
22643
22744
  const [px, pz] = P(lx, lz);
@@ -22659,16 +22760,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22659
22760
  }
22660
22761
  }
22661
22762
  cursor.pc = null;
22662
- shared.ctx.stairs.push({ m, f, to: vo.to, y0, H, rect: stairFootprint(m), landingPoint: (vo.LP || 0) / m.d });
22763
+ shared2.ctx.stairs.push({ m, f, to: vo.to, y0, H, rect: stairFootprint(m), landingPoint: (vo.LP || 0) / m.d });
22663
22764
  }
22664
22765
  }
22665
22766
  function elevator() {
22666
- const R = shared.ctx.r;
22767
+ const R = shared2.ctx.r;
22667
22768
  for (const c of R.rooms.filter((c2) => c2.type === "elevator" && c2.floor === 0)) {
22668
22769
  cursor.group = "f0";
22669
22770
  const [u0, v0, u1, v1] = rectsOf2(c)[0], y0 = Y0(0);
22670
22771
  bx("metal", u0 + 0.15, y0 + 0.05, v0 + 0.15, u1 - 0.15, y0 + 2.3, v1 - 0.15, 10133670);
22671
- bx("emissive", u0 + 0.3, y0 + 2.28, v0 + 0.3, u1 - 0.3, y0 + 2.3, v1 - 0.3, shared.ctx.night ? 16773320 : 13619924);
22772
+ bx("emissive", u0 + 0.3, y0 + 2.28, v0 + 0.3, u1 - 0.3, y0 + 2.3, v1 - 0.3, shared2.ctx.night ? 16773320 : 13619924);
22672
22773
  for (const f of R.floors) {
22673
22774
  const yy = Y0(f.index);
22674
22775
  cursor.group = "f" + f.index;
@@ -22678,7 +22779,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22678
22779
  }
22679
22780
  Object.assign(K, { buildStairs, elevator });
22680
22781
  }
22681
- function installLightsFixtures(K, shared) {
22782
+ function installLightsFixtures(K, shared2) {
22682
22783
  const seedKey = (id) => K.seedKey(id);
22683
22784
  const { cursor, part, polyFace } = K;
22684
22785
  const makeApi = (...a) => K.makeApi(...a);
@@ -22696,9 +22797,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22696
22797
  return ((t ^ t >>> 14) >>> 0) / 4294967296;
22697
22798
  };
22698
22799
  }
22699
- const SEED = () => shared.ctx.r && shared.ctx.r.seed || 0;
22700
- const STYLE = () => shared.ctx.r && shared.ctx.r.style || "budget";
22701
- shared.api0 = null;
22800
+ const SEED = () => shared2.ctx.r && shared2.ctx.r.seed || 0;
22801
+ const STYLE = () => shared2.ctx.r && shared2.ctx.r.style || "budget";
22802
+ shared2.api0 = null;
22702
22803
  function kit2(M, A, y0 = M.y || 0) {
22703
22804
  const c = Math.cos(M.ry), s = Math.sin(M.ry);
22704
22805
  let api = A;
@@ -22730,7 +22831,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22730
22831
  return null;
22731
22832
  }
22732
22833
  const a0 = api;
22733
- api = shared.api0 || (shared.api0 = makeApi());
22834
+ api = shared2.api0 || (shared2.api0 = makeApi());
22734
22835
  try {
22735
22836
  return part(type, W(lx, ly, lz), fn, meta || {}, void 0, M.ry);
22736
22837
  } finally {
@@ -22824,7 +22925,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22824
22925
  yLight = yc - 0.3;
22825
22926
  range2 = 6.5;
22826
22927
  } else if (type === "chandelier") {
22827
- const yc = t - 0.5, gold = shared.ctx.colors && shared.ctx.colors.metal != null ? shared.ctx.colors.metal : 9075290, N = 6;
22928
+ const yc = t - 0.5, gold = shared2.ctx.colors && shared2.ctx.colors.metal != null ? shared2.ctx.colors.metal : 9075290, N = 6;
22828
22929
  K2.c("metal", 0, yc, 0, 0.012, 0.5, gold);
22829
22930
  K2.e("metal", 0, yc - 0.03, 0, 0.055, 0.08, gold);
22830
22931
  K2.c("metal", 0, yc - 0.06, 0, 0.14, 0.015, gold);
@@ -22902,24 +23003,24 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22902
23003
  }
22903
23004
  Object.assign(K, { hashString: hashString2, rngString, SEED, STYLE, kit2, arcPoints, TEMP_WARM, TEMP_NEUTRAL, TEMP_COOL, colorTemperature, lightStyle, ceilingLamp, tableLamp, floorLamp, sconce, outdoorLamp, lightSwitch });
22904
23005
  }
22905
- function installLightsDecor(K, shared) {
23006
+ function installLightsDecor(K, shared2) {
22906
23007
  const { EPS: EPS3, OPEN_AREA, SEED, Y0, cursor, rngString, roomAt, stairFootprint } = K;
22907
23008
  const lightItem = (...a) => K.lightItem(...a);
22908
23009
  function decorLights(api) {
22909
- const R = shared.ctx.r, T2 = shared.ctx.types, structure = R.style, chance = structure === "budget" ? 0.35 : structure === "mid" ? 0.75 : 1, rnd = rngString(SEED() + "|decorluz");
23010
+ const R = shared2.ctx.r, T2 = shared2.ctx.types, structure = R.style, chance = structure === "budget" ? 0.35 : structure === "mid" ? 0.75 : 1, rnd = rngString(SEED() + "|decorluz");
22910
23011
  const itemsF = (f) => R.items.filter((m) => (m.outdoor ? -1 : m.floor) === f && m.type !== "stairs");
22911
23012
  const rectsF = (f) => itemsF(f).filter((m) => (m.h || 0) > 0.3 && !/rug|floor|concrete|dirt|lawn|ceiling_light|curtain|blinds|picture|mirror|pendant|chandelier|spot/.test(m.type)).map((m) => stairFootprint(m));
22912
23013
  const free = (f, x, z, margin) => {
22913
23014
  if (!roomAt(f, x, z)) return false;
22914
- for (const c of shared.ctx.colliders) if (c.f === f && x > c.x0 - margin && x < c.x1 + margin && z > c.z0 - margin && z < c.z1 + margin) return false;
23015
+ for (const c of shared2.ctx.colliders) if (c.f === f && x > c.x0 - margin && x < c.x1 + margin && z > c.z0 - margin && z < c.z1 + margin) return false;
22915
23016
  for (const r of rectsF(f)) if (x > r[0] - margin && x < r[2] + margin && z > r[1] - margin && z < r[3] + margin) return false;
22916
23017
  return true;
22917
23018
  };
22918
23019
  const puts = (f, type, m0, extra) => {
22919
23020
  const ent = T2[type];
22920
23021
  if (!ent) return;
22921
- const com = shared.ctx.roomById[m0.room], g = "f" + f, base = Y0(f);
22922
- const M = Object.assign({ x: m0.x, z: m0.z, ry: m0.ry || 0, w: m0.w || 0.3, d: m0.d || 0.3, h: m0.h || 0.3, y: 0, base, floor: f, colors: shared.ctx.colors, seed: m0.id, room: m0.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.8, on: shared.ctx.night, light: shared.ctx.night, lit: shared.ctx.night }, extra || {});
23022
+ const com = shared2.ctx.roomById[m0.room], g = "f" + f, base = Y0(f);
23023
+ const M = Object.assign({ x: m0.x, z: m0.z, ry: m0.ry || 0, w: m0.w || 0.3, d: m0.d || 0.3, h: m0.h || 0.3, y: 0, base, floor: f, colors: shared2.ctx.colors, seed: m0.id, room: m0.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.8, on: shared2.ctx.night, light: shared2.ctx.night, lit: shared2.ctx.night }, extra || {});
22923
23024
  cursor.group = g;
22924
23025
  lightItem({ id: m0.id, room: m0.room }, M, ent, api, g);
22925
23026
  };
@@ -22967,18 +23068,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22967
23068
  }
22968
23069
  Object.assign(K, { decorLights });
22969
23070
  }
22970
- function installLotTerrain(K, shared) {
23071
+ function installLotTerrain(K, shared2) {
22971
23072
  const { rectsOf: rectsOf2, MIRRORS, PARTS, bx, cursor } = K;
22972
23073
  function terrain() {
22973
23074
  PARTS.length = 0;
22974
23075
  MIRRORS.length = 0;
22975
23076
  K.CARS.length = 0;
22976
- shared.partCount = 0;
22977
- shared.ctx.parts = {};
22978
- shared.tapCount = 0;
22979
- shared.ctx.clotheslines = [];
22980
- if (shared.ctx.noTerrain) return;
22981
- const R = shared.ctx.r, lt = R.lot, C = shared.ctx.colors;
23077
+ shared2.partCount = 0;
23078
+ shared2.ctx.parts = {};
23079
+ shared2.tapCount = 0;
23080
+ shared2.ctx.clotheslines = [];
23081
+ if (shared2.ctx.noTerrain) return;
23082
+ const R = shared2.ctx.r, lt = R.lot, C = shared2.ctx.colors;
22982
23083
  cursor.group = "floor";
22983
23084
  const light = (c, f) => {
22984
23085
  const m = (k) => Math.round((c >> k & 255) * (1 - f) + 255 * f);
@@ -22992,13 +23093,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22992
23093
  bx("sidewalk", u0 - 40, -0.06, v0 - 1.8, u1 + 40, 0.02, v0, 14999766);
22993
23094
  for (let x = u0 - 38; x < u1 + 40; x += 6) bx("plaster", x, 0, v0 - 5.6, x + 2.6, 5e-3, v0 - 5.4, 15262904);
22994
23095
  } else {
22995
- const b = shared.ctx.limits;
23096
+ const b = shared2.ctx.limits;
22996
23097
  bx("sidewalk", b.x0 - 6, -0.09, b.z0 - 6, b.x1 + 6, -0.03, b.z1 + 6, 14605010);
22997
23098
  }
22998
23099
  }
22999
23100
  function freeSpans(alongU, L, a, b) {
23000
23101
  const blocks = [];
23001
- for (const c of shared.ctx.r.rooms) {
23102
+ for (const c of shared2.ctx.r.rooms) {
23002
23103
  if (c.type === "void" || c.floor < 0) continue;
23003
23104
  for (const [u0, v0, u1, v1] of rectsOf2(c)) {
23004
23105
  const c0 = alongU ? v0 : u0, c1 = alongU ? v1 : u1, lo = alongU ? u0 : v0, hi = alongU ? u1 : v1;
@@ -23018,12 +23119,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23018
23119
  }
23019
23120
  Object.assign(K, { terrain, freeSpans });
23020
23121
  }
23021
- function installLotPerimeter(K, shared) {
23122
+ function installLotPerimeter(K, shared2) {
23022
23123
  const { EPS: EPS3, boxC, bx, colorOf, cursor, freeSpans, pieceRecord } = K;
23023
23124
  const makeApi = (...a) => K.makeApi(...a);
23024
23125
  const sh = (...a) => K.sh(...a);
23025
23126
  function perimeter() {
23026
- const R = shared.ctx.r, lt = R.lot, C = shared.ctx.colors;
23127
+ const R = shared2.ctx.r, lt = R.lot, C = shared2.ctx.colors;
23027
23128
  if (!lt) return;
23028
23129
  cursor.group = "lot";
23029
23130
  const rnd = /* @__PURE__ */ (() => {
@@ -23037,7 +23138,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23037
23138
  const th = s.thickness || 0.15, h = s.height, color2 = colorOf(s.color) != null ? colorOf(s.color) : C.wall || 12104874, len = b - a;
23038
23139
  const B = (mat, u0, y0, u1, y1, t, c, off = 0) => alongU ? bx(mat, u0, y0, L + off - t / 2, u1, y1, L + off + t / 2, c) : bx(mat, L + off - t / 2, y0, u0, L + off + t / 2, y1, u1, c);
23039
23140
  const col = { type: "lot_wall", f: -1, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b };
23040
- shared.ctx.colliders.push(col);
23141
+ shared2.ctx.colliders.push(col);
23041
23142
  if (s.type === "wall") {
23042
23143
  B("plaster", a, 0, b, h, th, color2);
23043
23144
  B("plaster", a, h, b, h + 0.05, th + 0.06, sh(color2, 1.15));
@@ -23076,7 +23177,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23076
23177
  const w2 = x1 - x0, cm = (x0 + x1) / 2;
23077
23178
  const M = top === "razor_wire" ? { x: alongU ? cm : L, z: alongU ? L : cm, ry: alongU ? 0 : K.PE, w: w2, d: 0.4, h: 0.4, y: ym, base: 0, floor: -1, colors: C, seed: s.id } : { x: alongU ? cm : L, z: alongU ? L : cm, ry: alongU ? 0 : K.PE, w: w2, d: 0.1, h: 0.3, y: 0, base: ym, floor: -1, colors: C, seed: s.id };
23078
23179
  try {
23079
- shared.ctx.mv.builders[top](M, api);
23180
+ shared2.ctx.mv.builders[top](M, api);
23080
23181
  } catch (e) {
23081
23182
  console.warn(e);
23082
23183
  }
@@ -23097,7 +23198,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23097
23198
  }
23098
23199
  }
23099
23200
  function paths() {
23100
- const lt = shared.ctx.r.lot;
23201
+ const lt = shared2.ctx.r.lot;
23101
23202
  if (!lt || !lt.paths) return;
23102
23203
  cursor.group = "lot";
23103
23204
  for (const c of lt.paths) {
@@ -23110,14 +23211,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23110
23211
  }
23111
23212
  Object.assign(K, { perimeter, paths });
23112
23213
  }
23113
- function installLotGates(K, shared) {
23214
+ function installLotGates(K, shared2) {
23114
23215
  const { bx, colorOf, cursor, cylBase } = K;
23115
23216
  const sh = (...a) => K.sh(...a);
23116
23217
  function slideDirection(g, lt) {
23117
23218
  return g.u + g.width / 2 + g.width + 1.2 <= lt.rect[2] ? 1 : -1;
23118
23219
  }
23119
23220
  function gates() {
23120
- const R = shared.ctx.r, lt = R.lot, C = shared.ctx.colors;
23221
+ const R = shared2.ctx.r, lt = R.lot, C = shared2.ctx.colors;
23121
23222
  if (!lt) return;
23122
23223
  cursor.group = "lot";
23123
23224
  const structure = R.style, auto = structure !== "budget", wall = colorOf("wall") || 12104874, cu = (lt.rect[0] + lt.rect[2]) / 2, cz = (lt.rect[1] + lt.rect[3]) / 2;
@@ -23191,12 +23292,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23191
23292
  bx("emissive", mx + 0.1, 0.28, zc + sd * 0.452, mx + 0.14, 0.31, zc + sd * 0.455, 6479994);
23192
23293
  }
23193
23294
  }
23194
- if (!g.open || ped) shared.ctx.colliders.push({ type: "gate", f: -1, x0: a, z0: v - 0.1, x1: b, z1: v + 0.1 });
23295
+ if (!g.open || ped) shared2.ctx.colliders.push({ type: "gate", f: -1, x0: a, z0: v - 0.1, x1: b, z1: v + 0.1 });
23195
23296
  }
23196
23297
  }
23197
23298
  Object.assign(K, { slideDirection, gates });
23198
23299
  }
23199
- function installRoofRoofs(K, shared) {
23300
+ function installRoofRoofs(K, shared2) {
23200
23301
  const { rectsOf: rectsOf2, EPS: EPS3, OPEN_AREA, Y0, bx, cursor } = K;
23201
23302
  const gutter = (...a) => K.gutter(...a);
23202
23303
  const gutterConfig = (...a) => K.gutterConfig(...a);
@@ -23204,14 +23305,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23204
23305
  const sh = (...a) => K.sh(...a);
23205
23306
  const slabs = (...a) => K.slabs(...a);
23206
23307
  function roofs() {
23207
- const R = shared.ctx.r, F = R.facade, C = shared.ctx.colors, nA = R.floors.length, type = F.roof;
23308
+ const R = shared2.ctx.r, F = R.facade, C = shared2.ctx.colors, nA = R.floors.length, type = F.roof;
23208
23309
  cursor.group = "roof";
23209
- shared.ctx.roofRects = [];
23210
- shared.ctx.gutter = gutterConfig();
23211
- shared.ctx.gutter.ncond = 0;
23212
- shared.ctx.gutter.nbuz = 0;
23213
- shared.ctx.gutter.bz = /* @__PURE__ */ new Set();
23214
- shared.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] };
23310
+ shared2.ctx.roofRects = [];
23311
+ shared2.ctx.gutter = gutterConfig();
23312
+ shared2.ctx.gutter.ncond = 0;
23313
+ shared2.ctx.gutter.nbuz = 0;
23314
+ shared2.ctx.gutter.bz = /* @__PURE__ */ new Set();
23315
+ shared2.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] };
23215
23316
  const roofColor = C.roof != null ? C.roof : 11031610, gable = (R.seed | 0) % 2 === 0;
23216
23317
  for (let f = 0; f < nA; f++) {
23217
23318
  const rs = R.rooms.filter((c) => c.floor === f && c.type !== "void" && !c.outbuilding && !OPEN_AREA(c)).flatMap(rectsOf2), up = R.rooms.filter((c) => c.floor === f + 1 && c.type !== "void").flatMap(rectsOf2);
@@ -23234,7 +23335,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23234
23335
  return Y0(f) + Math.max(...cs.map((c) => c.ceiling)) + 0.2;
23235
23336
  };
23236
23337
  if (type === "slab") {
23237
- for (let j = 0; j < nz; j++) for (let i = 0; i < nx; i++) if (O(j, i)) shared.ctx.roofRects.push({ f, r: [xs[i], zs[j], xs[i + 1], zs[j + 1]], slab: true, yb: pe(xs[i], zs[j], xs[i + 1], zs[j + 1]) + 0.03 });
23338
+ for (let j = 0; j < nz; j++) for (let i = 0; i < nx; i++) if (O(j, i)) shared2.ctx.roofRects.push({ f, r: [xs[i], zs[j], xs[i + 1], zs[j + 1]], slab: true, yb: pe(xs[i], zs[j], xs[i + 1], zs[j + 1]) + 0.03 });
23238
23339
  slabs(f, xs, zs, O, U, nx, nz, full, pe, C);
23239
23340
  cursor.pc = null;
23240
23341
  continue;
@@ -23257,36 +23358,36 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23257
23358
  if (U(q.j0 - 1, i)) touchesU[1] = 1;
23258
23359
  if (U(q.j1 + 1, i)) touchesU[3] = 1;
23259
23360
  }
23260
- shared.ctx.roofRects.push({ f, r: [x0, z0, x1, z1], touchesU });
23361
+ shared2.ctx.roofRects.push({ f, r: [x0, z0, x1, z1], touchesU });
23261
23362
  const ybq = pe(x0, z0, x1, z1);
23262
23363
  roofRect(type, x0, z0, x1, z1, ybq, roofColor, gable && single, F, touchesU);
23263
23364
  cursor.pc = null;
23264
- if (shared.ctx.gutter.on) gutter(type, f, x0, z0, x1, z1, ybq, touchesU);
23365
+ if (shared2.ctx.gutter.on) gutter(type, f, x0, z0, x1, z1, ybq, touchesU);
23265
23366
  }
23266
23367
  }
23267
- for (const e of shared.ctx.outbuildingList || []) {
23368
+ for (const e of shared2.ctx.outbuildingList || []) {
23268
23369
  const [x0, z0, x1, z1] = e.aabb, yb = Y0(0) + (e.ceiling || 2.6) + 0.2;
23269
- shared.ctx.roofRects.push({ f: 0, r: [x0, z0, x1, z1], outbuilding: e.id });
23370
+ shared2.ctx.roofRects.push({ f: 0, r: [x0, z0, x1, z1], outbuilding: e.id });
23270
23371
  if (type === "slab") {
23271
23372
  const c = C.facade != null ? C.facade : 14209216;
23272
23373
  bx("plaster", x0 - 0.08, yb, z0 - 0.08, x1 + 0.08, yb + 0.03, z1 + 0.08, sh(C.ceiling != null ? C.ceiling : 12104876, 0.85));
23273
23374
  for (const [a, b, c2, d] of [[x0 - 0.08, z0 - 0.08, x1 + 0.08, z0 - 0.04], [x0 - 0.08, z1 + 0.04, x1 + 0.08, z1 + 0.08], [x0 - 0.08, z0 - 0.08, x0 - 0.04, z1 + 0.08], [x1 + 0.04, z0 - 0.08, x1 + 0.08, z1 + 0.08]]) bx("plaster", a, yb, b, c2, yb + 0.4, d, c);
23274
23375
  continue;
23275
23376
  }
23276
- shared.ctx.noPiece = true;
23377
+ shared2.ctx.noPiece = true;
23277
23378
  roofRect(type, x0, z0, x1, z1, yb, roofColor, true, F, [0, 0, 0, 0]);
23278
23379
  cursor.pc = null;
23279
- shared.ctx.noPiece = false;
23280
- if (shared.ctx.gutter.on) gutter(type, 0, x0, z0, x1, z1, yb, [0, 0, 0, 0]);
23380
+ shared2.ctx.noPiece = false;
23381
+ if (shared2.ctx.gutter.on) gutter(type, 0, x0, z0, x1, z1, yb, [0, 0, 0, 0]);
23281
23382
  }
23282
23383
  }
23283
23384
  Object.assign(K, { roofs });
23284
23385
  }
23285
- function installRoofGutters(K, shared) {
23386
+ function installRoofGutters(K, shared2) {
23286
23387
  const { boxC, bx, cursor, roomAt } = K;
23287
23388
  const sh = (...a) => K.sh(...a);
23288
23389
  function gutterConfig() {
23289
- const R = shared.ctx.r, structure = R.style, high = structure === "high" || structure === "luxury", p = high || structure === "mid" ? 0.6 : 0.3;
23390
+ const R = shared2.ctx.r, structure = R.style, high = structure === "high" || structure === "luxury", p = high || structure === "mid" ? 0.6 : 0.3;
23290
23391
  let h = 2166136261;
23291
23392
  for (const ch of String(R.seed) + "|" + K.seedKey(R.template) + "|calha") h = Math.imul(h ^ ch.charCodeAt(0), 16777619);
23292
23393
  const rnd = () => {
@@ -23298,10 +23399,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23298
23399
  const draw2 = rnd() < p, light = rnd() < 0.6;
23299
23400
  void draw2;
23300
23401
  const on = true;
23301
- return { on, rnd, color: high ? 3816770 : light ? 15527921 : 10857392, bad: (shared.ctx.colors.meta && shared.ctx.colors.meta.state) === "abandoned" || R.state === "abandoned", fallback: false };
23402
+ return { on, rnd, color: high ? 3816770 : light ? 15527921 : 10857392, bad: (shared2.ctx.colors.meta && shared2.ctx.colors.meta.state) === "abandoned" || R.state === "abandoned", fallback: false };
23302
23403
  }
23303
23404
  function gutter(type, f, X0, Z0, X1, Z1, yb, touchesU) {
23304
- const G = shared.ctx.gutter, o = type === "fiber_cement" ? 0.3 : 0.45, x0 = X0 - (touchesU[0] ? 0 : o), x1 = X1 + (touchesU[2] ? 0 : o), z0 = Z0 - (touchesU[1] ? 0 : o), z1 = Z1 + (touchesU[3] ? 0 : o), c = G.color, y = yb - 0.05;
23405
+ const G = shared2.ctx.gutter, o = type === "fiber_cement" ? 0.3 : 0.45, x0 = X0 - (touchesU[0] ? 0 : o), x1 = X1 + (touchesU[2] ? 0 : o), z0 = Z0 - (touchesU[1] ? 0 : o), z1 = Z1 + (touchesU[3] ? 0 : o), c = G.color, y = yb - 0.05;
23305
23406
  const run = (ax, a, b, p, outside, breaks) => {
23306
23407
  const seg2 = (u0, u1, tilt) => {
23307
23408
  const L = u1 - u0, m = (u0 + u1) / 2, dy = tilt ? -Math.abs(tilt) * L * 0.5 : 0;
@@ -23325,7 +23426,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23325
23426
  sides.forEach((l, i) => {
23326
23427
  if (l[0]) run(l[1], l[2], l[3], l[4], l[5], G.bad && !G.fallback && i === larger && (G.fallback = true));
23327
23428
  });
23328
- const INF = shared.ctx.gutterInfo || (shared.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] });
23429
+ const INF = shared2.ctx.gutterInfo || (shared2.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] });
23329
23430
  sides.forEach((l, i) => {
23330
23431
  if (l[0]) INF.gutters.push({ f, side: ["z0", "z1", "x0", "x1"][i], axis: l[1], a: l[2], b: l[3], p: l[4], y });
23331
23432
  });
@@ -23387,7 +23488,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23387
23488
  }
23388
23489
  Object.assign(K, { gutterConfig, gutter, drain });
23389
23490
  }
23390
- function installRoofSlabs(K, shared) {
23491
+ function installRoofSlabs(K, shared2) {
23391
23492
  const { boxC, bx, cursor, drain, roomAt, structurePiece } = K;
23392
23493
  const sh = (...a) => K.sh(...a);
23393
23494
  function slabs(f, xs, zs, O, U, nx, nz, full, pe, C) {
@@ -23417,15 +23518,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23417
23518
  side(free(j, i + 1), x1 + o - t, z0 - ez0, x1 + o, z1 + ez1);
23418
23519
  side(free(j - 1, i), x0 - ex0, z0 - o, x1 + ex1, z0 - o + t);
23419
23520
  side(free(j + 1, i), x0 - ex0, z1 + o - t, x1 + ex1, z1 + o);
23420
- if (shared.ctx.gutter && shared.ctx.gutter.on) for (const [ok, dx, dz] of [[free(j - 1, i), 0, -1], [free(j + 1, i), 0, 1], [free(j, i - 1), -1, 0], [free(j, i + 1), 1, 0]]) {
23521
+ if (shared2.ctx.gutter && shared2.ctx.gutter.on) for (const [ok, dx, dz] of [[free(j - 1, i), 0, -1], [free(j + 1, i), 0, 1], [free(j, i - 1), -1, 0], [free(j, i + 1), 1, 0]]) {
23421
23522
  const kd = f + ":" + dx + ":" + dz;
23422
- if (!ok || shared.ctx.gutter.bz.has(kd)) continue;
23423
- shared.ctx.gutter.bz.add(kd);
23424
- shared.ctx.gutter.nbuz++;
23425
- const mx = (x0 + x1) / 2, mz = (z0 + z1) / 2, ex = dx ? dx < 0 ? x0 - o : x1 + o : mx, ez = dz ? dz < 0 ? z0 - o : z1 + o : mz, cc = shared.ctx.gutter.color;
23523
+ if (!ok || shared2.ctx.gutter.bz.has(kd)) continue;
23524
+ shared2.ctx.gutter.bz.add(kd);
23525
+ shared2.ctx.gutter.nbuz++;
23526
+ const mx = (x0 + x1) / 2, mz = (z0 + z1) / 2, ex = dx ? dx < 0 ? x0 - o : x1 + o : mx, ez = dz ? dz < 0 ? z0 - o : z1 + o : mz, cc = shared2.ctx.gutter.color;
23426
23527
  boxC("plain", ex + dx * 0.15, yb + 0.1, ez + dz * 0.15, dx ? 0.42 : 0.14, 0.1, dz ? 0.42 : 0.14, cc);
23427
23528
  boxC("plain", ex + dx * 0.36, yb + 0.1, ez + dz * 0.36, dx ? 0.04 : 0.18, 0.14, dz ? 0.04 : 0.18, sh(cc, 0.8));
23428
- if (shared.ctx.gutter.bad) boxC("plain", ex + dx * 0.05, yb + 0.5 * 0, ez + dz * 0.05, dx ? 0.06 : 0.3, 0.02, dz ? 0.06 : 0.3, 4868674);
23529
+ if (shared2.ctx.gutter.bad) boxC("plain", ex + dx * 0.05, yb + 0.5 * 0, ez + dz * 0.05, dx ? 0.06 : 0.3, 0.02, dz ? 0.06 : 0.3, 4868674);
23429
23530
  {
23430
23531
  const tx = ex + dx * 0.38, tz = ez + dz * 0.38;
23431
23532
  let lv = true;
@@ -23438,8 +23539,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23438
23539
  boxC("plain", tx, 0.9, tz, 0.12, 0.04, 0.12, sh(cc, 0.8));
23439
23540
  const rx = tx + dx * 0.24, rz = tz + dz * 0.24;
23440
23541
  drain(rx, rz, tx, tz, cc);
23441
- (shared.ctx.gutterInfo || (shared.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] })).downpipes.push({ f, x: tx, z: tz, y0: 0.045, y1: yb + 0.04, drain: [rx, rz], hornBox: true });
23442
- shared.ctx.gutterInfo.drains.push({ x: rx, z: rz });
23542
+ (shared2.ctx.gutterInfo || (shared2.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] })).downpipes.push({ f, x: tx, z: tz, y0: 0.045, y1: yb + 0.04, drain: [rx, rz], hornBox: true });
23543
+ shared2.ctx.gutterInfo.drains.push({ x: rx, z: rz });
23443
23544
  }
23444
23545
  }
23445
23546
  }
@@ -23447,10 +23548,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23447
23548
  }
23448
23549
  Object.assign(K, { slabs });
23449
23550
  }
23450
- function installRoofTiles(K, shared) {
23551
+ function installRoofTiles(K, shared2) {
23451
23552
  const { UV_SCALE, _Y, _h2, _q, accFor, cursor, put, rgbOf, structurePiece } = K;
23452
23553
  const sh = (...a) => K.sh(...a);
23453
- const R_STYLE = () => shared.ctx.r && shared.ctx.r.style || "budget";
23554
+ const R_STYLE = () => shared2.ctx.r && shared2.ctx.r.style || "budget";
23454
23555
  function tileRelief(mat, pts, color2, type) {
23455
23556
  const n = pts.length;
23456
23557
  if (n < 3) return;
@@ -23491,7 +23592,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23491
23592
  S.push(rx * ex + ry * ey + rz * ez);
23492
23593
  T2.push(rx * dx + ry * dy + rz * dz);
23493
23594
  }
23494
- const colonial = type !== "fiber_cement", P = colonial ? 0.2 : 0.177, A = colonial ? 0.032 : 0.0255, seg2 = shared.quality === "game" ? colonial ? 4 : 4 : colonial ? 8 : 6, h = P / seg2;
23595
+ const colonial = type !== "fiber_cement", P = colonial ? 0.2 : 0.177, A = colonial ? 0.032 : 0.0255, seg2 = shared2.quality === "game" ? colonial ? 4 : 4 : colonial ? 8 : 6, h = P / seg2;
23495
23596
  const smin = Math.min(...S), smax = Math.max(...S);
23496
23597
  if (smax - smin < 1e-4) return;
23497
23598
  const xs = new Set(S.map((v) => +v.toFixed(5)));
@@ -23563,9 +23664,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23563
23664
  }
23564
23665
  }
23565
23666
  function pieceOfPane(x, z) {
23566
- if (shared.ctx.noPiece || !shared.ctx.panes.length) return null;
23667
+ if (shared2.ctx.noPiece || !shared2.ctx.panes.length) return null;
23567
23668
  let m = null, md = 1e9;
23568
- for (const a of shared.ctx.panes) {
23669
+ for (const a of shared2.ctx.panes) {
23569
23670
  const b = a.aabb;
23570
23671
  if (!b) continue;
23571
23672
  const dx = x < b[0] ? b[0] - x : x > b[2] ? x - b[2] : 0, dz = z < b[1] ? b[1] - z : z > b[3] ? z - b[3] : 0, d = Math.hypot(dx, dz) * 1e3 + (b[2] - b[0]) * (b[3] - b[1]) * 1e-3;
@@ -23578,11 +23679,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23578
23679
  }
23579
23680
  Object.assign(K, { R_STYLE, tileRelief, ridge, pieceOfPane });
23580
23681
  }
23581
- function installRoofRect(K, shared) {
23682
+ function installRoofRect(K, shared2) {
23582
23683
  const { R_STYLE, bx, cursor, pieceOfPane, polyFace, ridge, tileRelief } = K;
23583
23684
  const sh = (...a) => K.sh(...a);
23584
23685
  function roofRect(type, X0, Z0, X1, Z1, yb, roofColor, gable, F, touchesU = [0, 0, 0, 0]) {
23585
- const C = shared.ctx.colors, o = type === "fiber_cement" ? 0.3 : 0.45, x0 = X0 - (touchesU[0] ? 0 : o), x1 = X1 + (touchesU[2] ? 0 : o), z0 = Z0 - (touchesU[1] ? 0 : o), z1 = Z1 + (touchesU[3] ? 0 : o), dx = x1 - x0, dz = z1 - z0, xm = (x0 + x1) / 2, zm = (z0 + z1) / 2;
23686
+ const C = shared2.ctx.colors, o = type === "fiber_cement" ? 0.3 : 0.45, x0 = X0 - (touchesU[0] ? 0 : o), x1 = X1 + (touchesU[2] ? 0 : o), z0 = Z0 - (touchesU[1] ? 0 : o), z1 = Z1 + (touchesU[3] ? 0 : o), dx = x1 - x0, dz = z1 - z0, xm = (x0 + x1) / 2, zm = (z0 + z1) / 2;
23586
23687
  const mat = type === "fiber_cement" ? "fiber_cement" : "tile", tp = type === "fiber_cement" ? 0.2 : 0.5, alongX = dx >= dz, up = [0, 1, 0];
23587
23688
  const Q = (pts) => {
23588
23689
  let cx = 0, cz = 0;
@@ -23620,7 +23721,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23620
23721
  }
23621
23722
  const rm = alongX ? dz / 2 : dx / 2;
23622
23723
  {
23623
- const rr = shared.ctx.roofRects[shared.ctx.roofRects.length - 1];
23724
+ const rr = shared2.ctx.roofRects[shared2.ctx.roofRects.length - 1];
23624
23725
  if (rr && !rr.yb) Object.assign(rr, { yb, tp, gable: !!gable, alongX, exterior: [x0, z0, x1, z1], rm });
23625
23726
  }
23626
23727
  if (gable) {
@@ -23659,12 +23760,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23659
23760
  }
23660
23761
  Object.assign(K, { roofRect });
23661
23762
  }
23662
- function installMirrors(K, shared) {
23763
+ function installMirrors(K, shared2) {
23663
23764
  const { DOC, THREE, Reflector, MIRRORS, Y0, _Y, roomAt } = K;
23664
- shared.mirrorEnv = null;
23665
- shared.mirrorMat = null;
23765
+ shared2.mirrorEnv = null;
23766
+ shared2.mirrorMat = null;
23666
23767
  function mirrorEnv() {
23667
- if (shared.mirrorEnv) return shared.mirrorEnv;
23768
+ if (shared2.mirrorEnv) return shared2.mirrorEnv;
23668
23769
  const mk = (f) => {
23669
23770
  const c = DOC.createElement("canvas");
23670
23771
  c.width = c.height = 64;
@@ -23700,18 +23801,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23700
23801
  const t = new THREE.CubeTexture(faces);
23701
23802
  t.colorSpace = THREE.SRGBColorSpace;
23702
23803
  t.needsUpdate = true;
23703
- shared.mirrorEnv = t;
23704
- shared.mirrorMat = new THREE.MeshStandardMaterial({ color: 16054008, metalness: 1, roughness: 0.06, envMap: t, envMapIntensity: 1 });
23804
+ shared2.mirrorEnv = t;
23805
+ shared2.mirrorMat = new THREE.MeshStandardMaterial({ color: 16054008, metalness: 1, roughness: 0.06, envMap: t, envMapIntensity: 1 });
23705
23806
  return t;
23706
23807
  }
23707
23808
  const newMirrorState = () => ({ list: [], active: null, tmp: new THREE.Vector3(), house: null });
23708
- shared.mirrors = newMirrorState();
23809
+ shared2.mirrors = newMirrorState();
23709
23810
  function assembleMirrors(groups) {
23710
- shared.mirrors.list.length = 0;
23711
- shared.mirrors.active = null;
23811
+ shared2.mirrors.list.length = 0;
23812
+ shared2.mirrors.active = null;
23712
23813
  if (!MIRRORS.length) return;
23713
23814
  mirrorEnv();
23714
- if (shared.quality === "game" || !Reflector) {
23815
+ if (shared2.quality === "game" || !Reflector) {
23715
23816
  const by = /* @__PURE__ */ new Map(), m4 = new THREE.Matrix4(), qy = new THREE.Quaternion(), um = new THREE.Vector3(1, 1, 1), ps = new THREE.Vector3(), nm = new THREE.Matrix3(), v = new THREE.Vector3();
23716
23817
  for (const E of MIRRORS) {
23717
23818
  const geo = new THREE.PlaneGeometry(E.w, E.h);
@@ -23738,7 +23839,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23738
23839
  g.setAttribute("uv", new THREE.Float32BufferAttribute(B.U, 2));
23739
23840
  g.setIndex(B.I);
23740
23841
  g.computeBoundingSphere();
23741
- const m = new THREE.Mesh(g, shared.mirrorMat);
23842
+ const m = new THREE.Mesh(g, shared2.mirrorMat);
23742
23843
  m.name = "mirror/environment";
23743
23844
  m.userData.part = "mirror";
23744
23845
  (groups[parent] || (groups[parent] = new THREE.Group())).add(m);
@@ -23753,7 +23854,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23753
23854
  g.userData.part = "mirror";
23754
23855
  g.userData.room = E.room;
23755
23856
  const geo = new THREE.PlaneGeometry(E.w, E.h);
23756
- const fake = new THREE.Mesh(geo, shared.mirrorMat);
23857
+ const fake = new THREE.Mesh(geo, shared2.mirrorMat);
23757
23858
  fake.userData.part = "mirror";
23758
23859
  fake.name = "mirror/environment";
23759
23860
  g.add(fake);
@@ -23769,27 +23870,27 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23769
23870
  console.warn("mirror real", e);
23770
23871
  }
23771
23872
  (groups[E.parent] || (groups[E.parent] = new THREE.Group())).add(g);
23772
- shared.mirrors.list.push({ E, g, fake, real });
23873
+ shared2.mirrors.list.push({ E, g, fake, real });
23773
23874
  }
23774
23875
  }
23775
23876
  function floorAtY(y) {
23776
- const A = shared.ctx.r.floors;
23877
+ const A = shared2.ctx.r.floors;
23777
23878
  let f = 0;
23778
23879
  for (let i = 0; i < A.length; i++) if (y >= A[i].y0 - 0.2) f = i;
23779
23880
  return f;
23780
23881
  }
23781
23882
  function chooseMirror(camera) {
23782
- if (!shared.mirrors.list.length) return;
23883
+ if (!shared2.mirrors.list.length) return;
23783
23884
  let target = null;
23784
- if (shared.mirrors.house && shared.ctx.r) {
23785
- shared.mirrors.tmp.copy(camera.position);
23786
- shared.mirrors.house.worldToLocal(shared.mirrors.tmp);
23787
- const f = floorAtY(shared.mirrors.tmp.y), c = roomAt(f, shared.mirrors.tmp.x, shared.mirrors.tmp.z);
23788
- if (c && shared.mirrors.tmp.y > Y0(f) && shared.mirrors.tmp.y < Y0(f) + 4) {
23885
+ if (shared2.mirrors.house && shared2.ctx.r) {
23886
+ shared2.mirrors.tmp.copy(camera.position);
23887
+ shared2.mirrors.house.worldToLocal(shared2.mirrors.tmp);
23888
+ const f = floorAtY(shared2.mirrors.tmp.y), c = roomAt(f, shared2.mirrors.tmp.x, shared2.mirrors.tmp.z);
23889
+ if (c && shared2.mirrors.tmp.y > Y0(f) && shared2.mirrors.tmp.y < Y0(f) + 4) {
23789
23890
  let best = 1e9;
23790
- for (const m of shared.mirrors.list) {
23891
+ for (const m of shared2.mirrors.list) {
23791
23892
  if (m.E.room !== c.id || m.E.floor !== f || !m.g.parent || !m.g.parent.visible) continue;
23792
- const d = Math.hypot(m.E.x - shared.mirrors.tmp.x, m.E.z - shared.mirrors.tmp.z);
23893
+ const d = Math.hypot(m.E.x - shared2.mirrors.tmp.x, m.E.z - shared2.mirrors.tmp.z);
23793
23894
  if (d < best) {
23794
23895
  best = d;
23795
23896
  target = m;
@@ -23797,9 +23898,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23797
23898
  }
23798
23899
  }
23799
23900
  }
23800
- if (target === shared.mirrors.active) return;
23801
- shared.mirrors.active = target;
23802
- for (const m of shared.mirrors.list) {
23901
+ if (target === shared2.mirrors.active) return;
23902
+ shared2.mirrors.active = target;
23903
+ for (const m of shared2.mirrors.list) {
23803
23904
  const on = m === target && !!m.real;
23804
23905
  if (m.real) m.real.visible = on;
23805
23906
  m.fake.visible = !on;
@@ -23807,7 +23908,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23807
23908
  }
23808
23909
  Object.assign(K, { mirrorEnv, newMirrorState, assembleMirrors, floorAtY, chooseMirror });
23809
23910
  }
23810
- function installCars(K, shared) {
23911
+ function installCars(K, shared2) {
23811
23912
  const { THREE, FLEET, _Y } = K;
23812
23913
  const CARS = [];
23813
23914
  const CAR_BY_STYLE = Object.assign({
@@ -23833,12 +23934,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23833
23934
  return b;
23834
23935
  }
23835
23936
  function carModel(k, seed) {
23836
- const kc = k + "|" + shared.quality + "|" + (seed || 0);
23937
+ const kc = k + "|" + shared2.quality + "|" + (seed || 0);
23837
23938
  if (CAR_CACHE.has(kc)) return CAR_CACHE.get(kc);
23838
23939
  if (!FLEET) return null;
23839
23940
  let res = null;
23840
23941
  try {
23841
- const v0 = FLEET.build(k, { quality: shared.quality, seed: seed || 0 }), c = { root: v0.group, g: v0.group };
23942
+ const v0 = FLEET.build(k, { quality: shared2.quality, seed: seed || 0 }), c = { root: v0.group, g: v0.group };
23842
23943
  c.root.updateMatrixWorld(true);
23843
23944
  const inv = new THREE.Matrix4();
23844
23945
  const byMaterial = /* @__PURE__ */ new Map(), tmp = new THREE.Matrix4(), v = new THREE.Vector3(), nm = new THREE.Matrix3(), bb = new THREE.Box3();
@@ -23958,7 +24059,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23958
24059
  return g;
23959
24060
  }
23960
24061
  function assembleCars(groups) {
23961
- if (shared.quality === "game") return assembleMergedCars(groups);
24062
+ if (shared2.quality === "game") return assembleMergedCars(groups);
23962
24063
  for (const C of CARS) {
23963
24064
  const g = carGroup(C.k, C.w, C.d, C.seed);
23964
24065
  if (!g) continue;
@@ -24011,10 +24112,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24011
24112
  }
24012
24113
  Object.assign(K, { CARS, CAR_BY_STYLE, CAR_CACHE, materialSignature, BUCKETS, bucketMaterial, carModel, carGroup, assembleCars, assembleMergedCars });
24013
24114
  }
24014
- function installHouseBuilding(K, shared) {
24115
+ function installHouseBuilding(K, shared2) {
24015
24116
  const { bx, cursor } = K;
24016
24117
  function building() {
24017
- const R = shared.ctx.r, P = R.building, C = shared.ctx.colors, N = shared.ctx.pa, uf = shared.ctx.pf, pe = P.ceilingHeight, fa = C.facade != null ? C.facade : 14209216;
24118
+ const R = shared2.ctx.r, P = R.building, C = shared2.ctx.colors, N = shared2.ctx.pa, uf = shared2.ctx.pf, pe = P.ceilingHeight, fa = C.facade != null ? C.facade : 14209216;
24018
24119
  cursor.group = "building";
24019
24120
  const uw = P.unit.w, ud = P.unit.d, un = P.units;
24020
24121
  const unitBox = (u) => {
@@ -24022,7 +24123,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24022
24123
  return [x[0], z[0], x[1], z[1]];
24023
24124
  };
24024
24125
  const un0 = unitBox(un[0]), color2 = P.corridor, hall = P.hall, el = P.elevator.rect, es = P.stairs.rect;
24025
- const sel = un[shared.ctx.pu] || un[0], selR = unitBox(sel);
24126
+ const sel = un[shared2.ctx.pu] || un[0], selR = unitBox(sel);
24026
24127
  const shell = (rc, y0, y1, thickness = 0.15) => {
24027
24128
  const [a, b, c, d] = rc;
24028
24129
  bx("building", a, y0, b, c, y1, b + thickness, fa);
@@ -24061,11 +24162,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24061
24162
  }
24062
24163
  const ytop = N * pe - 0.2;
24063
24164
  bx("plaster", Math.min(hall[0] - 3, color2[0]), ytop, Math.min(un[1] ? unitBox(un[1])[1] : 0, el[1]), Math.max(color2[2], un0[2]), ytop + 0.2, Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0), 11841704);
24064
- shared.ctx.limits = { x0: Math.min(hall[0] - 3, color2[0]), z0: Math.min(el[1], un[1] ? unitBox(un[1])[1] : 0), x1: Math.max(color2[2], un0[2]), z1: Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0) };
24165
+ shared2.ctx.limits = { x0: Math.min(hall[0] - 3, color2[0]), z0: Math.min(el[1], un[1] ? unitBox(un[1])[1] : 0), x1: Math.max(color2[2], un0[2]), z1: Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0) };
24065
24166
  }
24066
24167
  Object.assign(K, { building });
24067
24168
  }
24068
- function installUtilitiesWater(K, shared) {
24169
+ function installUtilitiesWater(K, shared2) {
24069
24170
  const { THREE, _Y, _q, cursor, cylBase, part, pieceRecord, put } = K;
24070
24171
  function createWater(r, state) {
24071
24172
  const H = r.utilities.plumbing, cap = H ? +H.capacityL || 0 : 0, ls = { dry: [], full: [] }, points = {}, itemPoint = {};
@@ -24157,14 +24258,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24157
24258
  }
24158
24259
  const _v3 = new THREE.Vector3();
24159
24260
  function waterPipes() {
24160
- const H = shared.ctx.r.utilities.plumbing;
24261
+ const H = shared2.ctx.r.utilities.plumbing;
24161
24262
  if (!H || !H.visibleRuns) return;
24162
- const nA = shared.ctx.r.floors.length;
24263
+ const nA = shared2.ctx.r.floors.length;
24163
24264
  const groupOf = (c) => c && c.floor >= 0 ? "f" + Math.min(c.floor, nA - 1) : "lot", xyz = (p) => [p[0], p[2], p[1]];
24164
24265
  for (const tr of H.visibleRuns) {
24165
24266
  const pts = tr.points.map(xyz), d = tr.diameter || 0.025;
24166
24267
  if (tr.exposed === "wall") {
24167
- const pt = H.points.find((p) => p.run === tr.id), com = shared.ctx.roomById[tr.to], g2 = groupOf(com || pt && { floor: pt.floor });
24268
+ const pt = H.points.find((p) => p.run === tr.id), com = shared2.ctx.roomById[tr.to], g2 = groupOf(com || pt && { floor: pt.floor });
24168
24269
  part("wall_pipe", [0, 0, 0], () => {
24169
24270
  for (let i = 0; i + 1 < pts.length; i++) pipe(pts[i], pts[i + 1], d, PIPE_COLOR);
24170
24271
  for (const p of pts) cylBase("plain", p[0], p[1] - d, p[2], d * 0.7, d * 2, PIPE_COLOR);
@@ -24172,7 +24273,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24172
24273
  continue;
24173
24274
  }
24174
24275
  let g;
24175
- if (tr.exposed === "tank_outlet") g = shared.ctx.waterTankPos && shared.ctx.waterTankPos.group || "f0";
24276
+ if (tr.exposed === "tank_outlet") g = shared2.ctx.waterTankPos && shared2.ctx.waterTankPos.group || "f0";
24176
24277
  else {
24177
24278
  const pt = H.points.find((p) => p.id === tr.to);
24178
24279
  g = groupOf(pt);
@@ -24188,15 +24289,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24188
24289
  }
24189
24290
  Object.assign(K, { createWater, PIPE_COLOR, pipe, _v3, waterPipes });
24190
24291
  }
24191
- function installUtilitiesElectrical(K, shared) {
24292
+ function installUtilitiesElectrical(K, shared2) {
24192
24293
  const { _Y, _q, _v3, bx, cursor, cylBase, pieceRecord, put } = K;
24193
24294
  const sh = (...a) => K.sh(...a);
24194
24295
  function electricalStructure() {
24195
- const E = shared.ctx.r.utilities.electrical;
24196
- shared.ctx.electricalInfo = null;
24296
+ const E = shared2.ctx.r.utilities.electrical;
24297
+ shared2.ctx.electricalInfo = null;
24197
24298
  if (!E) return;
24198
- const R = shared.ctx.r, nA = R.floors.length, lotGroup = R.lot ? "lot" : "f0", concreteColor = 11973547, iron = 4869200, wireRun = 1842206, info = { pole: null, meter: null, panel: null, conduits: [], outlets: [], switches: [], circuits: E.circuits || [], exposed: !!E.exposed };
24199
- const en22 = E.serviceEntrance, KV = shared.ctx.iv ? shared.ctx.iv.plane : null;
24299
+ const R = shared2.ctx.r, nA = R.floors.length, lotGroup = R.lot ? "lot" : "f0", concreteColor = 11973547, iron = 4869200, wireRun = 1842206, info = { pole: null, meter: null, panel: null, conduits: [], outlets: [], switches: [], circuits: E.circuits || [], exposed: !!E.exposed };
24300
+ const en22 = E.serviceEntrance, KV = shared2.ctx.iv ? shared2.ctx.iv.plane : null;
24200
24301
  const wireL = (a, b, r_ = 8e-3) => {
24201
24302
  const L = Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
24202
24303
  if (L < 1e-3) return;
@@ -24274,7 +24375,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24274
24375
  info.conduits.push(t.id);
24275
24376
  continue;
24276
24377
  }
24277
- const c = circ[t.circuit], com = c && shared.ctx.roomById[c.room];
24378
+ const c = circ[t.circuit], com = c && shared2.ctx.roomById[c.room];
24278
24379
  cursor.group = "f" + Math.max(0, Math.min(nA - 1, com ? com.floor : 0));
24279
24380
  const d = t.diameter || 0.02, P = t.points.map((p) => [p[0], p[2], p[1]]), seg2 = [];
24280
24381
  for (let i = 0; i + 1 < P.length; i++) {
@@ -24292,7 +24393,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24292
24393
  }
24293
24394
  for (const t of E.outlets || []) info.outlets.push({ id: t.id, pos: [t.u, t.y, t.v], normal: [t.frontU || 0, 0, t.frontV || 0], room: t.room, floor: t.floor, type: t.type, voltage: t.voltage });
24294
24395
  for (const t of E.switches || []) info.switches.push({ id: t.id, pos: [t.u, t.y, t.v], normal: [t.frontU || 0, 0, t.frontV || 0], room: t.room, floor: t.floor, controls: t.controls });
24295
- shared.ctx.electricalInfo = info;
24396
+ shared2.ctx.electricalInfo = info;
24296
24397
  }
24297
24398
  function pipe2(a, b, diameter, color2) {
24298
24399
  const dx = b[0] - a[0], dy = b[1] - a[1], dz = b[2] - a[2], L = Math.hypot(dx, dy, dz);
@@ -24302,11 +24403,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24302
24403
  }
24303
24404
  Object.assign(K, { electricalStructure, pipe2 });
24304
24405
  }
24305
- function installHouseBaseboard(K, shared) {
24406
+ function installHouseBaseboard(K, shared2) {
24306
24407
  const { Y0, bx, cursor, sideOf } = K;
24307
24408
  const sh = (...a) => K.sh(...a);
24308
24409
  function baseboardAndSidewalk() {
24309
- const R = shared.ctx.r, W = 0.6, t = 0.012, ht = 0.35, color2 = sh(shared.ctx.colors.facade != null ? shared.ctx.colors.facade : 14209216, 0.62), y0 = Y0(0), cal = 13947078;
24410
+ const R = shared2.ctx.r, W = 0.6, t = 0.012, ht = 0.35, color2 = sh(shared2.ctx.colors.facade != null ? shared2.ctx.colors.facade : 14209216, 0.62), y0 = Y0(0), cal = 13947078;
24310
24411
  const ws = R.walls.filter((w) => w.floor === 0 && w.type === "wall").map((w) => {
24311
24412
  const au = w.axis === "u";
24312
24413
  return { w, au, L: au ? w.v0 : w.u0, a: Math.min(au ? w.u0 : w.v0, au ? w.u1 : w.v1), b: Math.max(au ? w.u0 : w.v0, au ? w.u1 : w.v1), th: w.thickness || 0.15 };
@@ -24338,11 +24439,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24338
24439
  }
24339
24440
  Object.assign(K, { baseboardAndSidewalk });
24340
24441
  }
24341
- function installUtilitiesSolar(K, shared) {
24442
+ function installUtilitiesSolar(K, shared2) {
24342
24443
  const { Y0, boxC, bx, cursor, cylBase } = K;
24343
24444
  function roofHeightAt(u, v, f) {
24344
24445
  let y = null;
24345
- for (const rr of shared.ctx.roofRects || []) {
24446
+ for (const rr of shared2.ctx.roofRects || []) {
24346
24447
  if (rr.yb == null || f != null && rr.f !== f) continue;
24347
24448
  if (rr.slab) {
24348
24449
  const [a, b, c, d] = rr.r;
@@ -24357,8 +24458,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24357
24458
  return y;
24358
24459
  }
24359
24460
  function solar() {
24360
- const R = shared.ctx.r, S = R.utilities.solar;
24361
- shared.ctx.solarInfo = null;
24461
+ const R = shared2.ctx.r, S = R.utilities.solar;
24462
+ shared2.ctx.solarInfo = null;
24362
24463
  if (!S || !S.panels || !S.panels.length) return;
24363
24464
  cursor.group = "roof";
24364
24465
  const silver = 13225426, blue = 1780302, line = 9279142, sv = S.north === "front" ? -1 : 1, info = { type: S.type, panels: [], inverter: null }, onRack = S.type === "slab_rack";
@@ -24400,15 +24501,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24400
24501
  bx("plain", iv.u - W * 0.6, y0 + 0.05, iv.v + fa0, iv.u + W * 0.6, y0 + 0.17, iv.v + fa1, 2106924);
24401
24502
  bx("emissive", iv.u - 0.03, y0 - 0.12, iv.v + fa0, iv.u + 0.03, y0 - 0.09, iv.v + fa1, 6479994);
24402
24503
  }
24403
- const top = Math.max(...(shared.ctx.roofRects || []).filter((t2) => t2.yb != null).map((t2) => t2.yb), Y0(fa) + 2.8);
24504
+ const top = Math.max(...(shared2.ctx.roofRects || []).filter((t2) => t2.yb != null).map((t2) => t2.yb), Y0(fa) + 2.8);
24404
24505
  cylBase("plain", iv.u, y0 + h / 2, iv.v, 0.016, Math.max(0.2, top - 0.2 - (y0 + h / 2)), 15262936);
24405
24506
  info.inverter = { id: iv.id, pos: [iv.u, y0, iv.v], side: iv.side, link: iv.link };
24406
24507
  }
24407
- shared.ctx.solarInfo = info;
24508
+ shared2.ctx.solarInfo = info;
24408
24509
  }
24409
24510
  Object.assign(K, { roofHeightAt, solar });
24410
24511
  }
24411
- function installHouseOutbuildings(K, shared) {
24512
+ function installHouseOutbuildings(K, shared2) {
24412
24513
  const { t, bx, cursor, floorColor } = K;
24413
24514
  const sh = (...a) => K.sh(...a);
24414
24515
  const OUTBUILDING_USE = { guest_room: ["bedroom", "bedroom", t("outbuilding.guest_room")], office: ["office", "office", t("outbuilding.office")], storage: ["stockroom", "stockroom", t("outbuilding.storage")], gourmet: ["living", "gourmet", t("outbuilding.gourmet")] };
@@ -24440,17 +24541,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24440
24541
  return Object.assign({}, r, { rooms, walls, doors, windows, items });
24441
24542
  }
24442
24543
  function outbuildings() {
24443
- const E = (shared.ctx.r.outbuildings || []).filter((e) => shared.ctx.roomById[e.id] && shared.ctx.roomById[e.id].outbuilding);
24444
- shared.ctx.outbuildingList = E;
24544
+ const E = (shared2.ctx.r.outbuildings || []).filter((e) => shared2.ctx.roomById[e.id] && shared2.ctx.roomById[e.id].outbuilding);
24545
+ shared2.ctx.outbuildingList = E;
24445
24546
  if (!E.length) return;
24446
24547
  cursor.group = "f0";
24447
24548
  for (const e of E) {
24448
- const c = shared.ctx.roomById[e.id], col = floorColor(c);
24549
+ const c = shared2.ctx.roomById[e.id], col = floorColor(c);
24449
24550
  for (const [a, b, c2, d] of e.interior) bx("plaster", a - 0.075, 0, b - 0.075, c2 + 0.075, 0.04, d + 0.075, col);
24450
24551
  for (const p of e.doors || []) {
24451
24552
  const alongU = p.axis === "u", th = e.thickness || 0.15;
24452
- if (alongU) bx("plaster", p.at - p.width / 2, 0, p.pos - th / 2 - 0.12, p.at + p.width / 2, 0.03, p.pos + th / 2 + 0.12, sh(shared.ctx.colors.facade || 14209216, 0.8));
24453
- else bx("plaster", p.pos - th / 2 - 0.12, 0, p.at - p.width / 2, p.pos + th / 2 + 0.12, 0.03, p.at + p.width / 2, sh(shared.ctx.colors.facade || 14209216, 0.8));
24553
+ if (alongU) bx("plaster", p.at - p.width / 2, 0, p.pos - th / 2 - 0.12, p.at + p.width / 2, 0.03, p.pos + th / 2 + 0.12, sh(shared2.ctx.colors.facade || 14209216, 0.8));
24554
+ else bx("plaster", p.pos - th / 2 - 0.12, 0, p.at - p.width / 2, p.pos + th / 2 + 0.12, 0.03, p.at + p.width / 2, sh(shared2.ctx.colors.facade || 14209216, 0.8));
24454
24555
  }
24455
24556
  }
24456
24557
  }
@@ -25184,10 +25285,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25184
25285
  }
25185
25286
  Object.assign(K, { typeTable });
25186
25287
  }
25187
- function installFurnitureTaps(K, shared) {
25188
- shared.tapCount = 0;
25288
+ function installFurnitureTaps(K, shared2) {
25289
+ shared2.tapCount = 0;
25189
25290
  function counterTap(K2, x, y, z, reach, back, meta = {}) {
25190
- const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared.tapCount++;
25291
+ const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared2.tapCount++;
25191
25292
  K2.c("metal", x, y, z, 0.028, 0.012, cr);
25192
25293
  K2.c("metal", x, y + 0.012, z, 0.014, 0.12, cr);
25193
25294
  const pts = [];
@@ -25218,7 +25319,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25218
25319
  return id;
25219
25320
  }
25220
25321
  function wallTap(K2, x, y, zw, direction, back, meta = {}) {
25221
- const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared.tapCount++, s = direction || 1;
25322
+ const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared2.tapCount++, s = direction || 1;
25222
25323
  K2.t("metal", [x, y, zw], [x, y, zw + s * 0.025], 0.03, cr);
25223
25324
  K2.t("metal", [x, y, zw + s * 0.02], [x, y, zw + s * 0.1], 0.016, cr);
25224
25325
  K2.e("metal", x, y, zw + s * 0.105, 0.019, 0.04, cr);
@@ -25468,7 +25569,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25468
25569
  }
25469
25570
  Object.assign(K, { GREENS: GREENS2, FLOWERS, blobs, potModel, arcLeaf, tuft, palm_tree, treeModel, shrubModel, potPlant, tablePot, planterModel });
25470
25571
  }
25471
- function installFurnitureYard(K, shared) {
25572
+ function installFurnitureYard(K, shared2) {
25472
25573
  const seedKey = (id) => K.seedKey(id);
25473
25574
  const { FURNITURE, SEED, STYLE, kit2, rngString, sh, wallTap } = K;
25474
25575
  FURNITURE.laundry_tub = function(M, A) {
@@ -25558,7 +25659,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25558
25659
  }
25559
25660
  }
25560
25661
  }, { id: "laundry_" + M.seed, swing: true, room: "yard" });
25561
- (shared.ctx.clotheslines || (shared.ctx.clotheslines = [])).push(M.seed);
25662
+ (shared2.ctx.clotheslines || (shared2.ctx.clotheslines = [])).push(M.seed);
25562
25663
  };
25563
25664
  FURNITURE.water_tank = function(M, A) {
25564
25665
  const K2 = kit2(M, A), w = M.w || 1, d = M.d || 1, onGround = !M.onSlab && (M.y || 0) < 0.5, color2 = M.palette && M.palette.tank_water != null ? M.palette.tank_water : 3107496, r = Math.min(w, d) * 0.46, rc = 11841700;
@@ -25700,13 +25801,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25700
25801
  }
25701
25802
  Object.assign(K, { extraTypes });
25702
25803
  }
25703
- function installFurniturePlaceItems(K, shared) {
25804
+ function installFurniturePlaceItems(K, shared2) {
25704
25805
  const { THREE, Y0, _col, boxC, colorOf, cursor, decorLights, makeApi, structurePiece } = K;
25705
25806
  const buildItem2 = (...a) => K.buildItem(...a);
25706
25807
  const registerCollision = (...a) => K.registerCollision(...a);
25707
25808
  const vegItem = (...a) => K.vegItem(...a);
25708
25809
  function houseItems() {
25709
- const R = shared.ctx.r, T2 = shared.ctx.types, api = makeApi(), noModel = /* @__PURE__ */ new Map();
25810
+ const R = shared2.ctx.r, T2 = shared2.ctx.types, api = makeApi(), noModel = /* @__PURE__ */ new Map();
25710
25811
  const list2 = R.items.concat(R.stateItems.filter((e) => e.w != null && e.d != null && e.type !== "razor_wire" && e.type !== "barbed_wire"));
25711
25812
  const rect = (poly) => {
25712
25813
  let a = 0;
@@ -25718,8 +25819,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25718
25819
  if (m.type === "stairs") continue;
25719
25820
  const exterior = m.outdoor || m.floor < 0, f = exterior ? -1 : Math.min(m.floor, R.floors.length - 1);
25720
25821
  cursor.group = exterior ? "lot" : "f" + f;
25721
- const com = shared.ctx.roomById[m.room], base = exterior ? 0 : Y0(f);
25722
- const M = { x: m.x, z: m.z, ry: m.ry || 0, w: m.w, d: m.d, h: m.h, y: m.y || 0, base, floor: exterior ? -1 : f, palette: shared.ctx.colors, color: m.category === "ground_cover" ? void 0 : colorOf(m.color) != null ? colorOf(m.color) : void 0, seed: m.id, room: m.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.9, on: shared.ctx.night, light: shared.ctx.night, lit: shared.ctx.night, open: !!m.doorOpen, overhead: m.overhead, assembly: m.assembly, hose: m.hose };
25822
+ const com = shared2.ctx.roomById[m.room], base = exterior ? 0 : Y0(f);
25823
+ const M = { x: m.x, z: m.z, ry: m.ry || 0, w: m.w, d: m.d, h: m.h, y: m.y || 0, base, floor: exterior ? -1 : f, palette: shared2.ctx.colors, color: m.category === "ground_cover" ? void 0 : colorOf(m.color) != null ? colorOf(m.color) : void 0, seed: m.id, room: m.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.9, on: shared2.ctx.night, light: shared2.ctx.night, lit: shared2.ctx.night, open: !!m.doorOpen, overhead: m.overhead, assembly: m.assembly, hose: m.hose };
25723
25824
  if (m.category === "ground_cover" && m.polygon) {
25724
25825
  const xs = m.polygon.map((p) => p[0]), zs = m.polygon.map((p) => p[1]);
25725
25826
  M.x = (Math.min(...xs) + Math.max(...xs)) / 2;
@@ -25729,8 +25830,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25729
25830
  M.ry = 0;
25730
25831
  if (!rect(m.polygon)) M.poly = m.polygon.map((p) => [p[0] - M.x, p[1] - M.z]);
25731
25832
  }
25732
- if (shared.ctx.veg && vegItem(m, M, exterior ? "lot" : "f" + f)) continue;
25733
- if (shared.ctx.iv && shared.ctx.iv.replace.has(m.id)) {
25833
+ if (shared2.ctx.veg && vegItem(m, M, exterior ? "lot" : "f" + f)) continue;
25834
+ if (shared2.ctx.iv && shared2.ctx.iv.replace.has(m.id)) {
25734
25835
  registerCollision(m, M);
25735
25836
  continue;
25736
25837
  }
@@ -25762,13 +25863,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25762
25863
  return noModel;
25763
25864
  }
25764
25865
  function waterTankOfHouse(api) {
25765
- const cd = shared.ctx.r.waterTank;
25766
- if (!cd || !shared.ctx.types.water_tank) return;
25767
- const lc = cd.place === "raised_slab" && cd.platform, slab = cd.place === "slab" || !!lc, nA = shared.ctx.r.floors.length, f = Math.max(0, Math.min(nA - 1, cd.floor));
25768
- const base = lc ? cd.platform.topY : cd.y + (shared.ctx.r.rooms.some((c) => c.id === cd.room && c.type === "terrace") ? 0 : 0.2 + (slab ? 0.03 : 0));
25866
+ const cd = shared2.ctx.r.waterTank;
25867
+ if (!cd || !shared2.ctx.types.water_tank) return;
25868
+ const lc = cd.place === "raised_slab" && cd.platform, slab = cd.place === "slab" || !!lc, nA = shared2.ctx.r.floors.length, f = Math.max(0, Math.min(nA - 1, cd.floor));
25869
+ const base = lc ? cd.platform.topY : cd.y + (shared2.ctx.r.rooms.some((c) => c.id === cd.room && c.type === "terrace") ? 0 : 0.2 + (slab ? 0.03 : 0));
25769
25870
  cursor.group = slab ? "f" + f : "attic_tank";
25770
25871
  if (lc) {
25771
- const P = cd.platform, [x0, z0, x1, z1] = P.aabb, e = P.thickness, color2 = shared.ctx.colors.slab != null ? shared.ctx.colors.slab : 12170668;
25872
+ const P = cd.platform, [x0, z0, x1, z1] = P.aabb, e = P.thickness, color2 = shared2.ctx.colors.slab != null ? shared2.ctx.colors.slab : 12170668;
25772
25873
  cursor.pc = structurePiece("tank_slab");
25773
25874
  boxC("plain", (x0 + x1) / 2, P.topY - e / 2, (z0 + z1) / 2, x1 - x0, e, z1 - z0, color2, 0, 0, 0);
25774
25875
  P.pillars.forEach((p, k) => {
@@ -25778,13 +25879,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25778
25879
  cursor.pc = null;
25779
25880
  }
25780
25881
  if (!slab) {
25781
- const color2 = shared.ctx.colors.slab != null ? shared.ctx.colors.slab : 12170668, yp = Y0(f), hw = cd.w / 2 + 0.1, hd = cd.d / 2 + 0.1;
25882
+ const color2 = shared2.ctx.colors.slab != null ? shared2.ctx.colors.slab : 12170668, yp = Y0(f), hw = cd.w / 2 + 0.1, hd = cd.d / 2 + 0.1;
25782
25883
  boxC("plain", cd.u, base - 0.06, cd.v, hw * 2, 0.12, hd * 2, color2);
25783
25884
  for (const sx of [-1, 1]) for (const sz of [-1, 1]) boxC("plain", cd.u + sx * (hw - 0.07), (yp + base - 0.12) / 2, cd.v + sz * (hd - 0.07), 0.1, base - 0.12 - yp, 0.1, color2);
25784
25885
  }
25785
- const M = { x: cd.u, z: cd.v, ry: 0, w: cd.w, d: cd.d, h: cd.h + 0.12, y: 0, base, floor: f, colors: shared.ctx.colors, seed: "water_tank", room: cd.room, onSlab: true, ceiling: 2.9 };
25786
- shared.ctx.waterTankPos = { x: cd.u, z: cd.v, y: base, group: cursor.group };
25787
- shared.ctx.types.water_tank.f(M, api);
25886
+ const M = { x: cd.u, z: cd.v, ry: 0, w: cd.w, d: cd.d, h: cd.h + 0.12, y: 0, base, floor: f, colors: shared2.ctx.colors, seed: "water_tank", room: cd.room, onSlab: true, ceiling: 2.9 };
25887
+ shared2.ctx.waterTankPos = { x: cd.u, z: cd.v, y: base, group: cursor.group };
25888
+ shared2.ctx.types.water_tank.f(M, api);
25788
25889
  }
25789
25890
  function hashColor(s) {
25790
25891
  let h = 7;
@@ -25794,11 +25895,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25794
25895
  function labeledBox(m, M, group) {
25795
25896
  const color2 = M.color != null ? M.color : hashColor(m.category || m.type), h = Math.max(0.05, m.h || 0.5);
25796
25897
  boxC("plain", m.x, M.base + (m.y || 0) + h / 2, m.z, m.w, h, m.d, color2, 0, m.ry || 0, 0);
25797
- shared.ctx.labels.push({ pos: new THREE.Vector3(m.x, M.base + (m.y || 0) + h + 0.15, m.z), text: m.type, group, type: "no_model" });
25898
+ shared2.ctx.labels.push({ pos: new THREE.Vector3(m.x, M.base + (m.y || 0) + h + 0.15, m.z), text: m.type, group, type: "no_model" });
25798
25899
  }
25799
25900
  Object.assign(K, { houseItems, waterTankOfHouse, hashColor, labeledBox });
25800
25901
  }
25801
- function installVegetationBridge(K, shared) {
25902
+ function installVegetationBridge(K, shared2) {
25802
25903
  const seedKey = (id) => K.seedKey(id);
25803
25904
  const { THREE, SEED, rngString } = K;
25804
25905
  const VEG_POT = ["potted_areca", "potted_snake_plant", "potted_fern"], VEG_CACTUS = { cactus_mandacaru: "mandacaru", cactus_palm: "prickly_pear", cactus_crown: "crown_cactus", cactus_xique: "xique_xique", cactus_pot: "potted_cactus" };
@@ -25824,7 +25925,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25824
25925
  for (const k of Object.keys(VEG_CACTUS)) VEG_MAP[k] = [VEG_CACTUS[k]];
25825
25926
  const VEG_PLANTER = { planter_bed: ["rose_bush_red", "rose_bush_pink", "rose_bush_white", "marigold", "periwinkle_pink", "periwinkle_white", "daisy"], planter_bed_small: ["rose_bush_red", "marigold", "periwinkle_pink", "daisy"], garden_bed: ["lawn_tuft", "wild_flowers"] };
25826
25927
  function vegItem(m, M, group) {
25827
- const V = shared.ctx.veg;
25928
+ const V = shared2.ctx.veg;
25828
25929
  if (!V) return false;
25829
25930
  const ids = VEG_MAP[m.type], can2 = VEG_PLANTER[m.type];
25830
25931
  if (!ids && !can2) return false;
@@ -25865,7 +25966,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25865
25966
  return true;
25866
25967
  }
25867
25968
  function assembleVegetation(groups) {
25868
- const V = shared.ctx.veg;
25969
+ const V = shared2.ctx.veg;
25869
25970
  if (!V) return;
25870
25971
  let pl = 0, tri = 0;
25871
25972
  const col = [], lod = [0, 0, 0], mats = V.mats();
@@ -25888,17 +25989,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25888
25989
  for (const c of lot.colliders) col.push(Object.assign({ y: G.y, group: G.group }, c));
25889
25990
  for (let i = 0; i < 3; i++) lod[i] += lot.lodCounts[i];
25890
25991
  }
25891
- shared.ctx.vegInfo = { plants: pl, triangles: tri, colliders: col, lodCounts: lod, materials: mats };
25992
+ shared2.ctx.vegInfo = { plants: pl, triangles: tri, colliders: col, lodCounts: lod, materials: mats };
25892
25993
  }
25893
25994
  Object.assign(K, { VEG_POT, VEG_CACTUS, VEG_MAP, VEG_PLANTER, vegItem, assembleVegetation });
25894
25995
  }
25895
- function installInteractionState(K, shared) {
25996
+ function installInteractionState(K, shared2) {
25896
25997
  const { THREE, cfg, colliderChanged, invalidateShadow, invalidate, UV_SCALE, applyPart, texture } = K;
25897
25998
  const ivRoomEffective = (...a) => K.ivRoomEffective(...a);
25898
25999
  const ivRoomLight = (...a) => K.ivRoomLight(...a);
25899
- shared.partState = /* @__PURE__ */ new Map();
26000
+ shared2.partState = /* @__PURE__ */ new Map();
25900
26001
  const newInteractiveState = () => ({ defs: /* @__PURE__ */ new Map(), items: [], pieces: [], lights: /* @__PURE__ */ new Map(), litRooms: /* @__PURE__ */ new Set(), objs: [], anim: /* @__PURE__ */ new Set(), msg: null, target: null });
25901
- shared.inter = newInteractiveState();
26002
+ shared2.inter = newInteractiveState();
25902
26003
  const MESSAGE_MS = 2200;
25903
26004
  UV_SCALE.doorWood = 1;
25904
26005
  UV_SCALE.doorPaint = 1;
@@ -25953,15 +26054,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25953
26054
  }
25954
26055
  const _EY = new THREE.Vector3(0, 1, 0), _UM3 = new THREE.Vector3(1, 1, 1);
25955
26056
  const hudMessage = (text) => {
25956
- shared.inter.msg = { text, until: performance.now() + MESSAGE_MS };
26057
+ shared2.inter.msg = { text, until: performance.now() + MESSAGE_MS };
25957
26058
  if (cfg.onMessage) cfg.onMessage(text);
25958
26059
  };
25959
26060
  function definePiece(name, def) {
25960
26061
  def.name = name;
25961
26062
  def.meshes = [];
25962
- def.t = def.target = shared.partState.has(name) ? shared.partState.get(name) : def.t0 || 0;
25963
- shared.inter.defs.set(name, def);
25964
- shared.inter.pieces.push(def);
26063
+ def.t = def.target = shared2.partState.has(name) ? shared2.partState.get(name) : def.t0 || 0;
26064
+ shared2.inter.defs.set(name, def);
26065
+ shared2.inter.pieces.push(def);
25965
26066
  return def;
25966
26067
  }
25967
26068
  const localOf = (M, lx, lz) => {
@@ -25973,7 +26074,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25973
26074
  return true;
25974
26075
  }
25975
26076
  function assembleInteractive(gs) {
25976
- for (const [name, def] of shared.inter.defs) {
26077
+ for (const [name, def] of shared2.inter.defs) {
25977
26078
  const g = gs[name];
25978
26079
  if (!g) continue;
25979
26080
  delete gs[name];
@@ -25995,13 +26096,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25995
26096
  const parent = def.leaf ? def.leaf.gs[def.k] : gs[def.parent] || (gs[def.parent] = new THREE.Group());
25996
26097
  if (parent) parent.add(outer);
25997
26098
  if (def.roomId) {
25998
- if (!shared.inter.lights.has(def.roomId)) shared.inter.lights.set(def.roomId, []);
25999
- shared.inter.lights.get(def.roomId).push(def);
26099
+ if (!shared2.inter.lights.has(def.roomId)) shared2.inter.lights.set(def.roomId, []);
26100
+ shared2.inter.lights.get(def.roomId).push(def);
26000
26101
  }
26001
26102
  applyPiece(def);
26002
26103
  }
26003
- for (const roomId of shared.inter.litRooms) applyLight(roomId);
26004
- shared.inter.defs.forEach((d) => {
26104
+ for (const roomId of shared2.inter.litRooms) applyLight(roomId);
26105
+ shared2.inter.defs.forEach((d) => {
26005
26106
  if (d.col) d.col.off = d.t > 0.5;
26006
26107
  });
26007
26108
  }
@@ -26041,8 +26142,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26041
26142
  }
26042
26143
  const DURATION = { swing: 0.55, drawer: 0.4, curtain: 0.9, gate_swing: 0.9, gate_tilt: 1.4, gate_slide: 1.6, lightSwitch: 0.12, part: 0.4 };
26043
26144
  function animateInteractive(dt) {
26044
- if (!shared.inter.anim.size) return;
26045
- for (const p of shared.inter.anim) {
26145
+ if (!shared2.inter.anim.size) return;
26146
+ for (const p of shared2.inter.anim) {
26046
26147
  const step = dt / (DURATION[p.kind] || 0.5), d = p.target - p.t;
26047
26148
  p.t = Math.abs(d) <= step ? p.target : p.t + Math.sign(d) * step;
26048
26149
  applyPiece(p);
@@ -26050,39 +26151,39 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26050
26151
  p.col.off = p.target > 0.5;
26051
26152
  colliderChanged(p.col);
26052
26153
  }
26053
- if (p.t === p.target) shared.inter.anim.delete(p);
26154
+ if (p.t === p.target) shared2.inter.anim.delete(p);
26054
26155
  }
26055
26156
  invalidateShadow();
26056
26157
  }
26057
26158
  function togglePiece(p) {
26058
26159
  p.target = p.target > 0.5 ? 0 : 1;
26059
- shared.partState.set(p.name, p.target);
26160
+ shared2.partState.set(p.name, p.target);
26060
26161
  if (p.col && p.col.off !== p.target > 0.5) {
26061
26162
  p.col.off = p.target > 0.5;
26062
26163
  colliderChanged(p.col);
26063
26164
  }
26064
- shared.inter.anim.add(p);
26165
+ shared2.inter.anim.add(p);
26065
26166
  }
26066
- const lightBase = (roomId) => roomId == null ? true : shared.partState.has("light:" + roomId) ? !!shared.partState.get("light:" + roomId) : !!shared.ctx.night;
26167
+ const lightBase = (roomId) => roomId == null ? true : shared2.partState.has("light:" + roomId) ? !!shared2.partState.get("light:" + roomId) : !!shared2.ctx.night;
26067
26168
  const lightOn = (roomId) => {
26068
- const S = roomId != null && shared.ctx.iv && shared.ctx.iv.roomStates.get(roomId);
26169
+ const S = roomId != null && shared2.ctx.iv && shared2.ctx.iv.roomStates.get(roomId);
26069
26170
  return S ? S.ef : lightBase(roomId);
26070
26171
  };
26071
26172
  function applyLight(roomId) {
26072
26173
  const on = lightOn(roomId);
26073
- for (const d of shared.inter.lights.get(roomId) || []) for (const m of d.meshes) if (m.name.endsWith("/emissive")) m.material = on ? shared.mats.emissive : shared.mats.off;
26074
- const sw = shared.inter.defs.get("ix:int:" + roomId);
26174
+ for (const d of shared2.inter.lights.get(roomId) || []) for (const m of d.meshes) if (m.name.endsWith("/emissive")) m.material = on ? shared2.mats.emissive : shared2.mats.off;
26175
+ const sw = shared2.inter.defs.get("ix:int:" + roomId);
26075
26176
  if (sw) {
26076
26177
  sw.target = on ? 1 : 0;
26077
- if (sw.t !== sw.target) shared.inter.anim.add(sw);
26178
+ if (sw.t !== sw.target) shared2.inter.anim.add(sw);
26078
26179
  }
26079
26180
  invalidate();
26080
26181
  }
26081
26182
  function toggleLight(roomId) {
26082
- const S = shared.ctx.iv && shared.ctx.iv.roomStates.get(roomId);
26183
+ const S = shared2.ctx.iv && shared2.ctx.iv.roomStates.get(roomId);
26083
26184
  if (S) {
26084
- ivRoomLight(shared.ctx.iv, roomId, !S.ef);
26085
- const ef = ivRoomEffective(shared.ctx.iv, S);
26185
+ ivRoomLight(shared2.ctx.iv, roomId, !S.ef);
26186
+ const ef = ivRoomEffective(shared2.ctx.iv, S);
26086
26187
  if (ef !== S.ef) {
26087
26188
  S.ef = ef;
26088
26189
  applyLight(roomId);
@@ -26090,13 +26191,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26090
26191
  }
26091
26192
  return;
26092
26193
  }
26093
- shared.partState.set("light:" + roomId, !lightOn(roomId));
26194
+ shared2.partState.set("light:" + roomId, !lightOn(roomId));
26094
26195
  applyLight(roomId);
26095
26196
  if (cfg.onLight) cfg.onLight(roomId, lightOn(roomId));
26096
26197
  }
26097
26198
  Object.assign(K, { newInteractiveState, MESSAGE_MS, createInteractiveMaterials, _EY, _UM3, hudMessage, definePiece, localOf, visibleChain, assembleInteractive, applyPiece, DURATION, animateInteractive, togglePiece, lightBase, lightOn, applyLight, toggleLight });
26098
26199
  }
26099
- function installInteractionCollision(K, shared) {
26200
+ function installInteractionCollision(K, shared2) {
26100
26201
  const NO_COLLIDE = /(^|_)(rug|floor|concrete|dirt|lawn|deck|ceiling_light|pendant|chandelier|spot|picture|curtain|blinds|wall_shelving|plank_shelf|wall_ac|ac_condenser|pool|soaking_tub|pergola|stairs|mirror)/;
26101
26202
  function registerCollision(m, M) {
26102
26203
  const h = m.h || 0, y = M.y || 0;
@@ -26106,7 +26207,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26106
26207
  w = Math.min(w, 0.5);
26107
26208
  d = Math.min(d, 0.5);
26108
26209
  }
26109
- shared.inter.objs.push({ f: M.floor, cx: m.x, cz: m.z, c: Math.cos(M.ry), s: Math.sin(M.ry), hw: w / 2, hd: d / 2, type: m.type });
26210
+ shared2.inter.objs.push({ f: M.floor, cx: m.x, cz: m.z, c: Math.cos(M.ry), s: Math.sin(M.ry), hw: w / 2, hd: d / 2, type: m.type });
26110
26211
  }
26111
26212
  function objectDistance(o, x, z) {
26112
26213
  const dx = x - o.cx, dz = z - o.cz, lx = dx * o.c - dz * o.s, lz = dx * o.s + dz * o.c, ex = Math.abs(lx) - o.hw, ez = Math.abs(lz) - o.hd;
@@ -26114,7 +26215,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26114
26215
  }
26115
26216
  function collideObject(x, z, fx, fz, floor) {
26116
26217
  const R = 0.2;
26117
- for (const o of shared.inter.objs) {
26218
+ for (const o of shared2.inter.objs) {
26118
26219
  if (o.f !== -1 ? o.f !== floor : floor !== 0) continue;
26119
26220
  const d1 = objectDistance(o, x, z);
26120
26221
  if (d1 < R && d1 < objectDistance(o, fx, fz) - 1e-6) return true;
@@ -26124,7 +26225,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26124
26225
  function collideAt(x, z, floor, opt) {
26125
26226
  opt = opt || {};
26126
26227
  const R = opt.radius != null ? opt.radius : 0.24;
26127
- for (const c of shared.ctx.colliders) {
26228
+ for (const c of shared2.ctx.colliders) {
26128
26229
  if (c.off) continue;
26129
26230
  if (c.f !== -1 && c.f !== floor) continue;
26130
26231
  if (c.f === -1 && floor !== 0) continue;
@@ -26136,7 +26237,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26136
26237
  }
26137
26238
  Object.assign(K, { NO_COLLIDE, registerCollision, objectDistance, collideObject, collideAt });
26138
26239
  }
26139
- function installInteractionItems(K, shared) {
26240
+ function installInteractionItems(K, shared2) {
26140
26241
  const { t, LIGHTS, cursor, definePiece, localOf, registerCollision, togglePiece } = K;
26141
26242
  const DOOR_ITEM = /^(tv_unit|tv_unit_small|tv_unit_large|sideboard|china_cabinet|filing_cabinet|pantry|laundry_cabinet|wardrobe|wardrobe_small|wardrobe_large|closet_wardrobe|kitchen_cabinet|kitchen_cabinet_large|kitchen_cabinet_small|fridge|fridge_large|display_fridge_medium|display_fridge)$/;
26142
26243
  const DRAWER_ITEM = /^(console_table|dresser|nightstand|vanity_table)$/;
@@ -26161,7 +26262,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26161
26262
  }
26162
26263
  function lightItem(m, M, ent, api, parent) {
26163
26264
  M.on = M.light = M.lit = true;
26164
- const n0 = LIGHTS.length, name = shared.quality === "game" ? "ix:light:" + m.room + "@" + parent : "ix:light:" + m.id;
26265
+ const n0 = LIGHTS.length, name = shared2.quality === "game" ? "ix:light:" + m.room + "@" + parent : "ix:light:" + m.id;
26165
26266
  cursor.group = name;
26166
26267
  try {
26167
26268
  ent.f(M, api);
@@ -26169,8 +26270,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26169
26270
  cursor.group = parent;
26170
26271
  }
26171
26272
  for (let i = n0; i < LIGHTS.length; i++) LIGHTS[i].roomId = m.room;
26172
- if (!shared.inter.defs.has(name)) definePiece(name, { kind: "light", pivot: [0, 0, 0], ry: 0, parent, roomId: m.room });
26173
- shared.inter.litRooms.add(m.room);
26273
+ if (!shared2.inter.defs.has(name)) definePiece(name, { kind: "light", pivot: [0, 0, 0], ry: 0, parent, roomId: m.room });
26274
+ shared2.inter.litRooms.add(m.room);
26174
26275
  }
26175
26276
  function curtainItem(m, M, ent, api, parent) {
26176
26277
  M.open = false;
@@ -26198,12 +26299,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26198
26299
  for (const c of body) api[c[0]](M, ...c[1]);
26199
26300
  if (!parts.length) return;
26200
26301
  const [ax, az] = localOf(M, 0, 0.2);
26201
- shared.inter.items.push({ type: "curtain", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (m.h || 2) * 0.5, az], range: 2.4, angle: 1, pieces: parts, text: () => t(parts[0].target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.curtain") }), action: () => {
26302
+ shared2.inter.items.push({ type: "curtain", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (m.h || 2) * 0.5, az], range: 2.4, angle: 1, pieces: parts, text: () => t(parts[0].target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.curtain") }), action: () => {
26202
26303
  const al = parts[0].target > 0.5 ? 0 : 1;
26203
26304
  for (const p of parts) {
26204
26305
  p.target = al;
26205
- shared.partState.set(p.name, al);
26206
- shared.inter.anim.add(p);
26306
+ shared2.partState.set(p.name, al);
26307
+ shared2.inter.anim.add(p);
26207
26308
  }
26208
26309
  } });
26209
26310
  }
@@ -26273,8 +26374,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26273
26374
  p.def = def;
26274
26375
  parts.push(def);
26275
26376
  const [ax, az] = localOf(M, cx, front + 0.08);
26276
- shared.inter.items.push({ type: drawer ? "drawer" : "cabinet", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (p.y0 + p.y1) / 2, az], range: 1.6, angle: 0.4, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what." + name) }), action: () => togglePiece(def) });
26277
- def.item = shared.inter.items[shared.inter.items.length - 1];
26377
+ shared2.inter.items.push({ type: drawer ? "drawer" : "cabinet", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (p.y0 + p.y1) / 2, az], range: 1.6, angle: 0.4, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what." + name) }), action: () => togglePiece(def) });
26378
+ def.item = shared2.inter.items[shared2.inter.items.length - 1];
26278
26379
  });
26279
26380
  calls.forEach((c, i) => {
26280
26381
  const p = owner.get(i);
@@ -26290,10 +26391,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26290
26391
  }
26291
26392
  Object.assign(K, { DOOR_ITEM, DRAWER_ITEM, LIGHT_TYPES, objectName, recordApi, buildItem: buildItem2, lightItem, curtainItem, furnitureItem });
26292
26393
  }
26293
- function installInteractionFittings(K, shared) {
26394
+ function installInteractionFittings(K, shared2) {
26294
26395
  const { t, EPS: EPS3, OPEN_AREA, Y0, applyPiece, bx, cursor, definePiece, gates, lightOn, roomAt, slideDirection, toggleLight, togglePiece } = K;
26295
26396
  function gatesInteractive() {
26296
- const lt = shared.ctx.r.lot;
26397
+ const lt = shared2.ctx.r.lot;
26297
26398
  if (!lt) return;
26298
26399
  const cz0 = (lt.rect[1] + lt.rect[3]) / 2;
26299
26400
  const orig = K.getBx(), gs = lt.gates, opening = gs.map((g) => g.open), reg = gs.map((g) => {
@@ -26315,7 +26416,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26315
26416
  }
26316
26417
  return orig(mat, x0, y0, z0, x1, y1, z1, color2);
26317
26418
  });
26318
- const n0 = shared.ctx.colliders.length;
26419
+ const n0 = shared2.ctx.colliders.length;
26319
26420
  try {
26320
26421
  gs.forEach((g) => {
26321
26422
  g.open = false;
@@ -26327,7 +26428,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26327
26428
  g.open = opening[i];
26328
26429
  });
26329
26430
  }
26330
- const cols = shared.ctx.colliders.slice(n0), cz = (lt.rect[1] + lt.rect[3]) / 2, cu = (lt.rect[0] + lt.rect[2]) / 2;
26431
+ const cols = shared2.ctx.colliders.slice(n0), cz = (lt.rect[1] + lt.rect[3]) / 2, cu = (lt.rect[0] + lt.rect[2]) / 2;
26331
26432
  reg.forEach((r, i) => {
26332
26433
  const g = r.g;
26333
26434
  if (!isFinite(r.x0)) return;
@@ -26336,25 +26437,25 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26336
26437
  const p = ped ? definePiece(name, Object.assign(base, { kind: "gate_swing", pivot: [r.x0, 0, g.v], angle: -sd * 1.65 })) : tilt ? definePiece(name, Object.assign(base, { kind: "gate_tilting", pivot: [(r.x0 + r.x1) / 2, r.y1, g.v], angle: -sd * 1.45 })) : definePiece(name, Object.assign(base, { kind: "gate_sliding", pivot: [r.x0, 0, r.zm], travel: r.dx * g.width }));
26337
26438
  if (p.col) p.col.off = p.target > 0.5;
26338
26439
  const text = () => t(p.target > 0.5 ? "prompt.close" : "prompt.open", { what: t(ped ? "what.pedestrianGate" : "what.garageGate") });
26339
- shared.inter.items.push({ type: "gate", id: g.id, floor: -1, anchor: [g.u, 1, g.v + sd * 0.4], range: 2.8, angle: 0.9, pieces: [p], text, action: () => togglePiece(p), noWall: true });
26440
+ shared2.inter.items.push({ type: "gate", id: g.id, floor: -1, anchor: [g.u, 1, g.v + sd * 0.4], range: 2.8, angle: 0.9, pieces: [p], text, action: () => togglePiece(p), noWall: true });
26340
26441
  });
26341
26442
  }
26342
26443
  function mailboxInteractive() {
26343
- for (const m of shared.ctx.r.items) {
26444
+ for (const m of shared2.ctx.r.items) {
26344
26445
  if (m.type !== "mailbox") continue;
26345
- const g = shared.ctx.parts && shared.ctx.parts["mailbox_" + m.id];
26446
+ const g = shared2.ctx.parts && shared2.ctx.parts["mailbox_" + m.id];
26346
26447
  if (!g) continue;
26347
26448
  const name = "ix:correio:" + m.id, def = definePiece(name, { kind: "part", pivot: [0, 0, 0], ry: 0, parent: "lot" });
26348
26449
  def.inner = g;
26349
26450
  const fx = Math.sin(m.ry || 0), fz = Math.cos(m.ry || 0), ay = (m.y || 1) + (m.h || 0.3) * 0.4;
26350
- shared.inter.items.push({ type: "mailbox", id: m.id, floor: -1, anchor: [m.x + fx * 0.2, ay, m.z + fz * 0.2], range: 2.2, angle: 0.7, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.mailbox") }), action: () => togglePiece(def), noWall: true });
26451
+ shared2.inter.items.push({ type: "mailbox", id: m.id, floor: -1, anchor: [m.x + fx * 0.2, ay, m.z + fz * 0.2], range: 2.2, angle: 0.7, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.mailbox") }), action: () => togglePiece(def), noWall: true });
26351
26452
  applyPiece(def);
26352
26453
  }
26353
26454
  }
26354
26455
  function placeSwitches() {
26355
- const R = shared.ctx.r, used = /* @__PURE__ */ new Set();
26456
+ const R = shared2.ctx.r, used = /* @__PURE__ */ new Set();
26356
26457
  for (const c of R.rooms) {
26357
- if (c.type === "void" || OPEN_AREA(c) || !shared.inter.litRooms.has(c.id) || used.has(c.id) || shared.ctx.iv && shared.ctx.iv.switchRooms.has(c.id)) continue;
26458
+ if (c.type === "void" || OPEN_AREA(c) || !shared2.inter.litRooms.has(c.id) || used.has(c.id) || shared2.ctx.iv && shared2.ctx.iv.switchRooms.has(c.id)) continue;
26358
26459
  const doors = R.doors.filter((p) => p.floor === c.floor && (p.a === c.id || p.b === c.id));
26359
26460
  doors.sort((p, q) => ((q.exterior ? 1 : 0) - (p.exterior ? 1 : 0)) * (c.type === "living" ? 1 : -1));
26360
26461
  for (const p of doors) if (putSwitch(c, p)) {
@@ -26364,7 +26465,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26364
26465
  }
26365
26466
  }
26366
26467
  function putSwitch(c, p) {
26367
- const R = shared.ctx.r, f = p.floor, alongU = p.axis === "u", L = p.pos, a = p.at - p.width / 2, b = p.at + p.width / 2;
26468
+ const R = shared2.ctx.r, f = p.floor, alongU = p.axis === "u", L = p.pos, a = p.at - p.width / 2, b = p.at + p.width / 2;
26368
26469
  const wref = R.walls.find((w) => w.floor === f && w.axis === p.axis && Math.abs((alongU ? w.v0 : w.u0) - L) < EPS3), th = wref ? wref.thickness || 0.15 : 0.15;
26369
26470
  const inside2 = (sd2) => {
26370
26471
  const cc = roomAt(f, alongU ? p.at : L + sd2 * 0.4, alongU ? L + sd2 * 0.4 : p.at);
@@ -26391,17 +26492,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26391
26492
  const piece2 = definePiece("ix:int:" + roomId, { kind: "light_switch", pivot: pv, ry: 0, parent: "f" + f, axis: alongU ? "x" : "z", sgn: alongU ? sd : -sd, t0: lightOn(roomId) ? 1 : 0 });
26392
26493
  piece2.t = piece2.target = lightOn(roomId) ? 1 : 0;
26393
26494
  const an = alongU ? [u, yc, face + sd * 0.12] : [face + sd * 0.12, yc, u];
26394
- shared.inter.items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [piece2], text: () => t(lightOn(roomId) ? "prompt.lightOff" : "prompt.lightOn"), action: () => toggleLight(roomId) });
26495
+ shared2.inter.items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [piece2], text: () => t(lightOn(roomId) ? "prompt.lightOff" : "prompt.lightOn"), action: () => toggleLight(roomId) });
26395
26496
  return true;
26396
26497
  }
26397
26498
  return false;
26398
26499
  }
26399
26500
  Object.assign(K, { gatesInteractive, mailboxInteractive, placeSwitches, putSwitch });
26400
26501
  }
26401
- function installInteractionDoors(K, shared) {
26502
+ function installInteractionDoors(K, shared2) {
26402
26503
  const { t, colliderChanged, invalidateShadow, applyPiece, hudMessage } = K;
26403
26504
  function linkDoorLeaves() {
26404
- for (const fo of shared.ctx.leaves) fo.handles = (fo.handleNames || []).map((n) => shared.inter.defs.get(n)).filter(Boolean);
26505
+ for (const fo of shared2.ctx.leaves) fo.handles = (fo.handleNames || []).map((n) => shared2.inter.defs.get(n)).filter(Boolean);
26405
26506
  }
26406
26507
  function handleApply(fo) {
26407
26508
  for (const mc of fo.handles || []) {
@@ -26413,7 +26514,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26413
26514
  if (fo.phase === "rattle") return;
26414
26515
  if (fo.phase === "handle" || fo.phase === "swing") {
26415
26516
  fo.open = !fo.open;
26416
- shared.doorState.set(fo.id, fo.open);
26517
+ shared2.doorState.set(fo.id, fo.open);
26417
26518
  fo.col.off = fo.open;
26418
26519
  colliderChanged(fo.col);
26419
26520
  fo.anim = true;
@@ -26423,25 +26524,25 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26423
26524
  if (fo.blockedFlag || fo.locked) {
26424
26525
  fo.phase = "rattle";
26425
26526
  fo.jig = 0.7;
26426
- shared.ctx.animateDoorsOn = true;
26527
+ shared2.ctx.animateDoorsOn = true;
26427
26528
  hudMessage(t(fo.blockedFlag ? "message.boarded" : "message.locked"));
26428
26529
  return;
26429
26530
  }
26430
26531
  fo.open = !fo.open;
26431
- shared.doorState.set(fo.id, fo.open);
26532
+ shared2.doorState.set(fo.id, fo.open);
26432
26533
  fo.col.off = fo.open;
26433
26534
  colliderChanged(fo.col);
26434
26535
  fo.anim = true;
26435
- shared.ctx.animateDoorsOn = true;
26536
+ shared2.ctx.animateDoorsOn = true;
26436
26537
  if (fo.handles && fo.handles.length) {
26437
26538
  fo.phase = "handle";
26438
26539
  fo.hT = fo.hT || 0;
26439
26540
  } else fo.phase = "swing";
26440
26541
  }
26441
26542
  function animateDoors(dt) {
26442
- if (!shared.ctx.animateDoorsOn) return;
26543
+ if (!shared2.ctx.animateDoorsOn) return;
26443
26544
  let active = false;
26444
- for (const fo of shared.ctx.leaves) {
26545
+ for (const fo of shared2.ctx.leaves) {
26445
26546
  if (!fo.phase) continue;
26446
26547
  active = true;
26447
26548
  if (fo.phase === "handle") {
@@ -26471,13 +26572,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26471
26572
  }
26472
26573
  }
26473
26574
  }
26474
- shared.ctx.animateDoorsOn = active;
26575
+ shared2.ctx.animateDoorsOn = active;
26475
26576
  invalidateShadow();
26476
26577
  }
26477
26578
  function wallBlocks(ex, ez, ax, az, floor) {
26478
- const n = shared.ctx.wallColliders != null ? shared.ctx.wallColliders : 0;
26579
+ const n = shared2.ctx.wallColliders != null ? shared2.ctx.wallColliders : 0;
26479
26580
  for (let i = 0; i < n; i++) {
26480
- const c = shared.ctx.colliders[i];
26581
+ const c = shared2.ctx.colliders[i];
26481
26582
  if (c.f !== floor && !(c.f === -1 && floor === 0)) continue;
26482
26583
  let t0 = 0, t1 = 1;
26483
26584
  const dx = ax - ex, dz = az - ez;
@@ -26509,7 +26610,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26509
26610
  }
26510
26611
  Object.assign(K, { linkDoorLeaves, handleApply, toggleDoor, animateDoors, wallBlocks, doorText, applyLeaf });
26511
26612
  }
26512
- function installInteractionTarget(K, shared) {
26613
+ function installInteractionTarget(K, shared2) {
26513
26614
  const { doorText, toggleDoor, visibleChain, wallBlocks } = K;
26514
26615
  const ivTarget = (...a) => K.ivTarget(...a);
26515
26616
  function targetOf(o, opt) {
@@ -26520,7 +26621,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26520
26621
  const tries = (score, text, action, target) => {
26521
26622
  if (!best || score < best.score) best = { score, text, action, target };
26522
26623
  };
26523
- for (const fo of shared.ctx.leaves) {
26624
+ for (const fo of shared2.ctx.leaves) {
26524
26625
  if (fo.floor !== floor) continue;
26525
26626
  const d = Math.hypot(fo.cx - ex, fo.cz - ez);
26526
26627
  if (d > 1.7) continue;
@@ -26528,11 +26629,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26528
26629
  if (angle > 1.35 && d > 0.9) continue;
26529
26630
  tries(angle * 1.6 + d * 0.5 + (angle < 0.25 ? 0 : 0.6), doorText(fo), () => toggleDoor(fo), fo);
26530
26631
  }
26531
- const vis = shared.inter.pieces.flatMap((p) => p.meshes).filter(visibleChain), hit = vis.length && opt.strike ? opt.strike(vis) : null;
26532
- const kitA = shared.ctx.iv ? ivTarget(shared.ctx.iv, o, opt && opt.interactives) : null;
26632
+ const vis = shared2.inter.pieces.flatMap((p) => p.meshes).filter(visibleChain), hit = vis.length && opt.strike ? opt.strike(vis) : null;
26633
+ const kitA = shared2.ctx.iv ? ivTarget(shared2.ctx.iv, o, opt && opt.interactives) : null;
26533
26634
  const nearKit = kitA && hit && Math.hypot(kitA.target.pos[0] - ex, kitA.target.pos[1] - ey, kitA.target.pos[2] - ez) < hit.distance + 0.1;
26534
26635
  const pieceHit = hit && !nearKit && hit.object.userData.piece;
26535
- for (const it of shared.inter.items) {
26636
+ for (const it of shared2.inter.items) {
26536
26637
  if (it.floor !== floor && !(it.floor === -1 && floor === 0)) continue;
26537
26638
  const [ax, ay, az] = it.anchor, dx = ax - ex, dy = ay - ey, dz = az - ez, d = Math.hypot(dx, dy, dz), dh = Math.hypot(dx, dz);
26538
26639
  if (dh > it.range + 0.4) continue;
@@ -26547,14 +26648,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26547
26648
  }
26548
26649
  Object.assign(K, { targetOf });
26549
26650
  }
26550
- function installInteractablesBridge(K, shared) {
26651
+ function installInteractablesBridge(K, shared2) {
26551
26652
  const { t, THREE, invalidate, invalidateShadow, cfg, DOC, LIGHT_TYPES, _Y, _q, _v3, accFor, applyLight, cursor, hashString: hashString2, hudMessage, lightBase, pieceRecord, put, rgbOf, sh, wallBlocks } = K;
26552
26653
  const enter = (...a) => K.enter(...a);
26553
26654
  const roomLightMask = (...a) => K.roomLightMask(...a);
26554
26655
  const IV_MATERIAL = { plain: "plain", metal: "metal", wood: "wood", glass: "glass", fabric: "fabric", plant: "plant", water: "water", emissive: "emissive", atlas_picture: "picture", atlas_floor: "floor" };
26555
26656
  const IV_WIRE = { conduit: 13618628, cable: 2762532, drop: 1381653, cord: 1776413, earth: 3111482, hose: 11556124 };
26556
26657
  const IV_DOOR = /^(door|drawer)/;
26557
- const ivGroup = (e) => e.floor < 0 ? "lot" : "f" + Math.min(e.floor, shared.ctx.r.floors.length - 1);
26658
+ const ivGroup = (e) => e.floor < 0 ? "lot" : "f" + Math.min(e.floor, shared2.ctx.r.floors.length - 1);
26558
26659
  function ivAccumulate(mat, g, ox, oy, oz, ry, color2) {
26559
26660
  const P = g.attributes.position, N = g.attributes.normal, C = color2 == null ? g.attributes.color : null, U = g.attributes.uv, I = g.index, nv = P.count, ni = I ? I.count : nv;
26560
26661
  const A = accFor(mat);
@@ -26598,7 +26699,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26598
26699
  A.ni += ni;
26599
26700
  }
26600
26701
  function ivBuild(h, water) {
26601
- const ik = K.IVK, r = shared.ctx.r, A = ik.A, world0 = null;
26702
+ const ik = K.IVK, r = shared2.ctx.r, A = ik.A, world0 = null;
26602
26703
  void world0;
26603
26704
  const plane2 = A.plan(r, { seed: r.seed });
26604
26705
  const IV = { k: ik, plane: plane2, world: null, water, entries: /* @__PURE__ */ new Map(), roots: [], replace: /* @__PURE__ */ new Set(), roomStates: /* @__PURE__ */ new Map(), lampRoom: /* @__PURE__ */ new Map(), anim: /* @__PURE__ */ new Map(), screens: /* @__PURE__ */ new Map(), efx: null, items: null, itemsDirty: true, itemsT: 0, dirty: true, list: null, listT: 0, t: 0, circuits: [], switchRooms: /* @__PURE__ */ new Set(), warnings: [], tBuild: 0 };
@@ -26619,7 +26720,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26619
26720
  const wants = (roomId) => lightBase(roomId);
26620
26721
  const entById = new Map(plane2.items.map((e) => [e.id, e]));
26621
26722
  const entByItem = new Map(plane2.items.map((e) => [e.item, e]));
26622
- IV.mats = { plain: shared.mats.plain, metal: shared.mats.metal, wood: shared.mats.wood, glass: shared.mats.glass, fabric: shared.mats.fabric, plant: shared.mats.plant, water: shared.mats.water, emissive: shared.mats.emissive, atlas_picture: shared.mats.picture, atlas_floor: shared.mats.floor };
26723
+ IV.mats = { plain: shared2.mats.plain, metal: shared2.mats.metal, wood: shared2.mats.wood, glass: shared2.mats.glass, fabric: shared2.mats.fabric, plant: shared2.mats.plant, water: shared2.mats.water, emissive: shared2.mats.emissive, atlas_picture: shared2.mats.picture, atlas_floor: shared2.mats.floor };
26623
26724
  const ev = (e) => ivEvent(h, e);
26624
26725
  const world = IV.world = A.createWorld(r, { water, seed: r.seed, onEvent: ev });
26625
26726
  const add0 = world.add;
@@ -26627,7 +26728,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26627
26728
  const e = entById.get(id);
26628
26729
  if (e && e.type === "lamp") {
26629
26730
  const roomId = IV.lampRoom.get(id);
26630
- spec.devices[0].on = roomId ? wants(roomId) : !!shared.ctx.night;
26731
+ spec.devices[0].on = roomId ? wants(roomId) : !!shared2.ctx.night;
26631
26732
  spec.parts = (spec.parts || []).concat([{ id: "_x", pivot: [0, 0, 0], motion: { kind: "slide", axis: [0, 1, 0], distance: 1e-3 }, label: "" }]);
26632
26733
  spec.interactions = [{ id: "device.lamp", pos: [0, 0, 0], action: { do: "toggle_device", device: "lamp" }, label: "", requires: { object: id, part: "_x" } }];
26633
26734
  } else if (e && e.type === "wall_switch") {
@@ -26653,7 +26754,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26653
26754
  }
26654
26755
  if (e.type === "lamp" && o.devices && o.devices.lamp) {
26655
26756
  const roomId = IV.lampRoom.get(id);
26656
- o.devices.lamp.on = roomId ? wants(roomId) : !!shared.ctx.night;
26757
+ o.devices.lamp.on = roomId ? wants(roomId) : !!shared2.ctx.night;
26657
26758
  } else if (e.type === "wall_switch" && o.parts && o.parts.rocker !== void 0) {
26658
26759
  const l = (e.connections.controls || [])[0], roomId = l && IV.lampRoom.get(l);
26659
26760
  if (roomId) o.parts.rocker = wants(roomId) ? 1 : 0;
@@ -26745,7 +26846,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26745
26846
  const ik = IV.k, w = IV.world, wl = (o, p) => ik.GI.localToWorld(o.transform, p), g0 = cursor.group;
26746
26847
  const tube2 = (pts, radius, color2, ox, oy, oz, ry) => {
26747
26848
  try {
26748
- const m = ik.gfx.createCord(pts, radius, shared.mats.plain);
26849
+ const m = ik.gfx.createCord(pts, radius, shared2.mats.plain);
26749
26850
  ivAccumulate("plain", m.geometry, ox, oy, oz, ry, color2);
26750
26851
  m.geometry.dispose();
26751
26852
  } catch (e) {
@@ -26788,7 +26889,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26788
26889
  for (const E of IV.roots) {
26789
26890
  (gs[E.group] || (gs[E.group] = new THREE.Group())).add(E.root);
26790
26891
  }
26791
- for (const [roomId] of IV.roomStates) if (!shared.inter.litRooms.has(roomId)) IV.roomStates.delete(roomId);
26892
+ for (const [roomId] of IV.roomStates) if (!shared2.inter.litRooms.has(roomId)) IV.roomStates.delete(roomId);
26792
26893
  for (const E of IV.entries.values()) if (E.parts && Object.keys(E.parts).length) IV.k.gfx.syncObject(IV.world, E.id, E.parts, { time: 0 });
26793
26894
  for (const E of IV.entries.values()) if (E.screen) ivScreen(IV, E);
26794
26895
  }
@@ -26819,7 +26920,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26819
26920
  break;
26820
26921
  case "device": {
26821
26922
  const roomId = IV.lampRoom.get(e.object);
26822
- if (roomId) shared.partState.set("light:" + roomId, !!e.on);
26923
+ if (roomId) shared2.partState.set("light:" + roomId, !!e.on);
26823
26924
  invalidate();
26824
26925
  break;
26825
26926
  }
@@ -26972,7 +27073,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26972
27073
  gm.setIndex(new THREE.BufferAttribute(A.i.slice(0, A.ni), 1));
26973
27074
  gm.computeBoundingSphere();
26974
27075
  if (!IV.items) {
26975
- IV.items = new THREE.Mesh(gm, shared.mats.plain);
27076
+ IV.items = new THREE.Mesh(gm, shared2.mats.plain);
26976
27077
  IV.items.name = "iv-items";
26977
27078
  IV.items.castShadow = false;
26978
27079
  IV.items.receiveShadow = true;
@@ -27113,17 +27214,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27113
27214
  }
27114
27215
  Object.assign(K, { IV_MATERIAL, IV_WIRE, IV_DOOR, ivGroup, ivAccumulate, ivBuild, ivRoomEffective, ivDraw, ivCords, ivAssemble, ivScreen, ivEvent, ivSeat, ivUpdate, IV_SHAPE, ivItems, ivTarget, ivRoomLight, ivParts, ivDispose, ivPublish });
27115
27216
  }
27116
- function installAnimationClotheslines(K, shared) {
27217
+ function installAnimationClotheslines(K, shared2) {
27117
27218
  const { invalidate, CLOTHES_UNIFORMS } = K;
27118
27219
  const WIND = { t0: performance.now(), last: 0, base: 0.55 };
27119
27220
  function animateClotheslines(now) {
27120
- if (!shared.ctx.clotheslines || !shared.ctx.clotheslines.length) return;
27221
+ if (!shared2.ctx.clotheslines || !shared2.ctx.clotheslines.length) return;
27121
27222
  if (now - WIND.last < 33) return;
27122
27223
  WIND.last = now;
27123
27224
  const t = (now - WIND.t0) / 1e3;
27124
27225
  CLOTHES_UNIFORMS.uTime.value = t;
27125
27226
  CLOTHES_UNIFORMS.uVento.value = WIND.base + 0.45 * Math.sin(t * 0.23) * Math.sin(t * 0.11 + 1.3) + 0.25 * Math.max(0, Math.sin(t * 0.57));
27126
- const g = shared.ctx.parts && shared.ctx.parts["laundry_" + shared.ctx.clotheslines[0]];
27227
+ const g = shared2.ctx.parts && shared2.ctx.parts["laundry_" + shared2.ctx.clotheslines[0]];
27127
27228
  if (g) {
27128
27229
  let vis = true;
27129
27230
  for (let n = g; n; n = n.parent) if (!n.visible) {
@@ -27136,30 +27237,30 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27136
27237
  }
27137
27238
  Object.assign(K, { WIND, animateClotheslines });
27138
27239
  }
27139
- function installBuildInstance(K, shared) {
27240
+ function installBuildInstance(K, shared2) {
27140
27241
  const { PROPS, THREE, DOC, cfg, HP, createInteractiveMaterials, createMaterials, typeTable } = K;
27141
27242
  const props = PROPS.create(THREE, { document: DOC, emit: () => {
27142
27243
  } });
27143
27244
  const TYPES = typeTable(props);
27144
- shared.mats = createMaterials(props);
27145
- createInteractiveMaterials(shared.mats);
27245
+ shared2.mats = createMaterials(props);
27246
+ createInteractiveMaterials(shared2.mats);
27146
27247
  if (cfg.materials) for (const k of Object.keys(cfg.materials)) {
27147
27248
  const v = cfg.materials[k];
27148
- shared.mats[k] = typeof v === "function" ? v(shared.mats[k], k) || shared.mats[k] : v;
27249
+ shared2.mats[k] = typeof v === "function" ? v(shared2.mats[k], k) || shared2.mats[k] : v;
27149
27250
  }
27150
27251
  const newState = () => ({ doors: /* @__PURE__ */ new Map(), inter: /* @__PURE__ */ new Map(), water: null, iv: null });
27151
27252
  function enter(h) {
27152
- shared.ctx = h.ctx;
27153
- shared.inter = h.inter;
27154
- shared.doorState = h.state.doors;
27155
- shared.partState = h.state.inter;
27156
- shared.mirrors = h.mirrors;
27157
- shared.quality = h.quality;
27253
+ shared2.ctx = h.ctx;
27254
+ shared2.inter = h.inter;
27255
+ shared2.doorState = h.state.doors;
27256
+ shared2.partState = h.state.inter;
27257
+ shared2.mirrors = h.mirrors;
27258
+ shared2.quality = h.quality;
27158
27259
  }
27159
27260
  const tagDamage = (type) => ({ type, hp: HP[type], hpMax: HP[type] });
27160
27261
  Object.assign(K, { props, TYPES, newState, enter, tagDamage });
27161
27262
  }
27162
- function installInteractablesKit(K, shared) {
27263
+ function installInteractablesKit(K, shared2) {
27163
27264
  const { t, THREE, DOC, cfg, Reflector } = K;
27164
27265
  const roomLightMask = (...a) => K.roomLightMask(...a);
27165
27266
  const IVK = (() => {
@@ -27177,15 +27278,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27177
27278
  const l = cfg.vegetation || null, G = l && (l.GameVegetation || (l.buildLot ? l : null)), S = l && (l.GameVegetationSpecies || (l.toSpec ? l : null));
27178
27279
  return G && S && G.buildLot && S.toSpec ? { G, S } : null;
27179
27280
  })();
27180
- shared.vegMaterials = null;
27181
- const vegMaterials = () => shared.vegMaterials || (shared.vegMaterials = (() => {
27281
+ shared2.vegMaterials = null;
27282
+ const vegMaterials = () => shared2.vegMaterials || (shared2.vegMaterials = (() => {
27182
27283
  const m = VEG.G.createVegetationMaterials(THREE);
27183
27284
  for (const k of ["wood", "foliage", "flowers", "fruit", "spines"]) roomLightMask(m[k]);
27184
27285
  return m;
27185
27286
  })());
27186
27287
  Object.assign(K, { IVK, VEG, vegMaterials });
27187
27288
  }
27188
- function installLightsRoomLight(K, shared) {
27289
+ function installLightsRoomLight(K, shared2) {
27189
27290
  const { THREE, rectsOf: rectsOf2 } = K;
27190
27291
  const MAX_LIGHTS = 12, EMPTY = [1e9, 1e9, -1e9, -1e9];
27191
27292
  const LZU = { uRB0: { value: new Float32Array(MAX_LIGHTS * 4) }, uRB1: { value: new Float32Array(MAX_LIGHTS * 4) }, uRB2: { value: new Float32Array(MAX_LIGHTS * 4) }, uRBY: { value: new Float32Array(MAX_LIGHTS * 2) }, uREx: { value: new Float32Array(MAX_LIGHTS * 4) }, uIndK: { value: 0.06 } };
@@ -27224,7 +27325,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27224
27325
  function lighting(o) {
27225
27326
  o = o || {};
27226
27327
  const scene = o.scene, N = Math.max(1, Math.min(MAX_LIGHTS, o.n || 6)), NS = Math.max(0, Math.min(N, o.shadows != null ? o.shadows : 2)), size = o.shadowSize || 512, MAX_EXTERNAL = o.external != null ? o.external : 2;
27227
- for (const k of Object.keys(shared.mats)) roomLightMask(shared.mats[k]);
27328
+ for (const k of Object.keys(shared2.mats)) roomLightMask(shared2.mats[k]);
27228
27329
  const PL = [], sig = new Array(N).fill(""), seg2 = { n: 0 };
27229
27330
  for (let i = 0; i < N; i++) {
27230
27331
  const l = new THREE.PointLight(16763008, 0, 8, 1.6);
@@ -27417,9 +27518,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27417
27518
  }
27418
27519
  return view;
27419
27520
  }
27420
- function installDestructionPieces(K, shared) {
27521
+ function installDestructionPieces(K, shared2) {
27421
27522
  const { THREE, floorAtY, pieceRecord } = K;
27422
- shared.destructionSeq = 0;
27523
+ shared2.destructionSeq = 0;
27423
27524
  const FRAGMENT_COLOR = { brick: 11031866, concrete: 10132118, plaster: 14210248, ceramic: 11821630, glass: 11456472, tempered_glass: 11456472, wood_soft: 11569752, wood_hard: 8016948, plywood: 12098154, mdf: 12098154, steel: 9080466, aluminium: 12106944, plastic: 3107496, copper: 12088115, stone: 9079428, fabric: 13616296 };
27424
27525
  const FRAGMENT_GEO = new THREE.BoxGeometry(1, 1, 1), FRAGMENT_MAT = {};
27425
27526
  const fragmentMaterial = (m) => FRAGMENT_MAT[m] || (FRAGMENT_MAT[m] = new THREE.MeshLambertMaterial({ color: FRAGMENT_COLOR[m] != null ? FRAGMENT_COLOR[m] : 9079428 }));
@@ -27428,7 +27529,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27428
27529
  objs = objs.filter(Boolean);
27429
27530
  if (!objs.length) return;
27430
27531
  const pc = pieceRecord(id, mat, role, extra);
27431
- shared.ctx.pieceObjects.set(id, objs);
27532
+ shared2.ctx.pieceObjects.set(id, objs);
27432
27533
  for (const o of objs) o.traverse((m) => {
27433
27534
  if (!m.isMesh) return;
27434
27535
  const u = m.userData;
@@ -27439,22 +27540,22 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27439
27540
  if (pc.explodes) u.destructionExplodes = pc.explodes;
27440
27541
  });
27441
27542
  };
27442
- for (const fo of shared.ctx.leaves) {
27543
+ for (const fo of shared2.ctx.leaves) {
27443
27544
  const pr = r.doors.find((p) => p.id === fo.id);
27444
27545
  tagObject("door:" + fo.id, fo.gs, fo.type === "steel" ? "steel" : pr && pr.exterior ? "wood_hard" : "mdf", null, { floor: fo.floor, mass: fo.type === "steel" ? 60 : 18, tags: ["door"] });
27445
27546
  }
27446
27547
  const cap = r.utilities.plumbing ? +r.utilities.plumbing.capacityL || 0 : 0;
27447
- for (const [id, g] of Object.entries(shared.ctx.parts || {})) {
27548
+ for (const [id, g] of Object.entries(shared2.ctx.parts || {})) {
27448
27549
  const tp = g.userData.part;
27449
27550
  if (tp === "water_tank") {
27450
- const e = shared.ctx.structureIndex.water_tank, L = cap || (g.userData.volume ? Math.round(g.userData.volume * 1e3) : 0);
27551
+ const e = shared2.ctx.structureIndex.water_tank, L = cap || (g.userData.volume ? Math.round(g.userData.volume * 1e3) : 0);
27451
27552
  tagObject("water_tank", [g], "plastic", e ? e.role : null, { floor: e ? e.floor : 0, contains: L ? { fluid: "water", liters: L } : void 0, mass: e ? e.mass : 25, thickness: 4e-3, fill: 0.05, tags: ["tank"] });
27452
27553
  } else if (tp === "gas_cylinder") tagObject(id, [g], "steel", null, { mass: 11, form: "cylinder", thickness: 3e-3, fill: 0.03, contains: { fluid: "gas", liters: 13, pressurized: true }, explodes: { energy: 12e4, radius: 5, atC: 300 }, tags: ["gas_bottle"] });
27453
27554
  else if (tp === "wall_pipe") tagObject(id, [g], "plastic", null, { mass: 3, tags: ["pipe"] });
27454
27555
  else if (tp === "shower_door") tagObject(id, [g], "tempered_glass", null, { mass: 25 });
27455
27556
  else if (tp === "gate_leaf" || tp === "mailbox_door") tagObject(id, [g], "steel", null, { mass: 30 });
27456
27557
  }
27457
- for (const def of shared.inter.defs.values()) {
27558
+ for (const def of shared2.inter.defs.values()) {
27458
27559
  if (!def.outer) continue;
27459
27560
  if (/^gate/.test(def.kind)) tagObject(def.name, [def.outer], "steel", null, { mass: 80, tags: ["gate"] });
27460
27561
  else if (def.kind === "swing" || def.kind === "drawer") tagObject(def.name, [def.outer], "mdf", null, { mass: 6 });
@@ -27473,13 +27574,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27473
27574
  for (const f of o.userData.ranges) add(f.id, { mesh: o, v0: f.v0, v1: f.v1, i0: f.i0, i1: f.i1, whole: f.v0 === 0 && f.v1 === nv });
27474
27575
  }
27475
27576
  });
27476
- for (const [id, objs] of shared.ctx.pieceObjects) for (const o of objs) add(id, { obj: o });
27577
+ for (const [id, objs] of shared2.ctx.pieceObjects) for (const o of objs) add(id, { obj: o });
27477
27578
  const box32 = (id) => {
27478
27579
  const b = new THREE.Box3(), v = new THREE.Vector3();
27479
27580
  for (const it of meshes.get(id) || []) {
27480
27581
  if (it.obj) {
27481
27582
  const bb = new THREE.Box3().setFromObject(it.obj);
27482
- if (!bb.isEmpty()) for (const x of [bb.min.x, bb.max.x]) for (const y of [bb.min.y, bb.max.y]) for (const z of [bb.min.z, bb.max.z]) b.expandByPoint(v.set(x, y, z).applyMatrix4(shared.ctx.unitInverse));
27583
+ if (!bb.isEmpty()) for (const x of [bb.min.x, bb.max.x]) for (const y of [bb.min.y, bb.max.y]) for (const z of [bb.min.z, bb.max.z]) b.expandByPoint(v.set(x, y, z).applyMatrix4(shared2.ctx.unitInverse));
27483
27584
  } else {
27484
27585
  const P = it.mesh.geometry.attributes.position.array;
27485
27586
  for (let k = it.v0; k < it.v1; k++) b.expandByPoint(v.set(P[k * 3], P[k * 3 + 1], P[k * 3 + 2]));
@@ -27489,15 +27590,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27489
27590
  };
27490
27591
  const parts = [], byId = /* @__PURE__ */ new Map(), supports = E0.supports.map((a) => Object.assign({}, a));
27491
27592
  for (const e of E0.parts) {
27492
- const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared.ctx.pieces.get(e.id);
27593
+ const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared2.ctx.pieces.get(e.id);
27493
27594
  if (pc) {
27494
27595
  for (const k of ["contains", "explodes", "tags", "form", "thickness", "fill"]) if (pc[k] != null && p[k] == null) p[k] = pc[k];
27495
27596
  }
27496
27597
  parts.push(p);
27497
27598
  byId.set(p.id, p);
27498
27599
  }
27499
- const base = parts.length, view = shared.ctx.panelView || panelViewOf(null, false), panelIds = new Set(view.panels.map((e) => e.id));
27500
- for (const [id, pc] of shared.ctx.pieces) {
27600
+ const base = parts.length, view = shared2.ctx.panelView || panelViewOf(null, false), panelIds = new Set(view.panels.map((e) => e.id));
27601
+ for (const [id, pc] of shared2.ctx.pieces) {
27501
27602
  if (byId.has(id) || panelIds.has(id) || !meshes.has(id)) continue;
27502
27603
  const b = box32(id);
27503
27604
  if (!b) continue;
@@ -27531,7 +27632,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27531
27632
  parts.splice(0, parts.length, ...parts.filter((p) => !gone.has(p.id)));
27532
27633
  for (const id of gone) byId.delete(id);
27533
27634
  for (const e of view.panels) {
27534
- const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared.ctx.pieces.get(e.id);
27635
+ const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared2.ctx.pieces.get(e.id);
27535
27636
  if (pc) {
27536
27637
  for (const k of ["contains", "explodes", "tags", "form", "thickness", "fill"]) if (pc[k] != null && p[k] == null) p[k] = pc[k];
27537
27638
  }
@@ -27638,6 +27739,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27638
27739
  var SPALL_RAGGED = 0.045;
27639
27740
  var COVER2 = 0.015;
27640
27741
  var MAX_FLAKES = 64;
27742
+ function clipToBox(unit, box4) {
27743
+ const lo = [Math.max(unit.x - unit.sx / 2, box4[0]), Math.max(unit.y - unit.sy / 2, box4[1]), Math.max(unit.z - unit.sz / 2, box4[2])];
27744
+ const hi = [Math.min(unit.x + unit.sx / 2, box4[3]), Math.min(unit.y + unit.sy / 2, box4[4]), Math.min(unit.z + unit.sz / 2, box4[5])];
27745
+ if (hi[0] - lo[0] <= 1e-4 || hi[1] - lo[1] <= 1e-4 || hi[2] - lo[2] <= 1e-4) return null;
27746
+ return { x: (lo[0] + hi[0]) / 2, y: (lo[1] + hi[1]) / 2, z: (lo[2] + hi[2]) / 2, sx: hi[0] - lo[0], sy: hi[1] - lo[1], sz: hi[2] - lo[2], colour: unit.colour };
27747
+ }
27641
27748
  function installDestructionBreach(K, _shared) {
27642
27749
  const { THREE, fragmentMaterial, invalidate, invalidateShadow } = K;
27643
27750
  function createBreachView(opts) {
@@ -27748,6 +27855,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27748
27855
  material.userData.breachCore = core;
27749
27856
  return material;
27750
27857
  }
27858
+ function drawnBounds(items) {
27859
+ house.updateMatrixWorld(true);
27860
+ const box4 = new THREE.Box3(), toHouse = new THREE.Matrix4().copy(house.matrixWorld).invert();
27861
+ for (const it of items) {
27862
+ const a = it.mesh.userData._p0 || it.mesh.geometry.attributes.position.array;
27863
+ tmp.m.multiplyMatrices(toHouse, it.mesh.matrixWorld);
27864
+ for (let k = it.v0; k < it.v1; k++) box4.expandByPoint(tmp.p.set(a[k * 3], a[k * 3 + 1], a[k * 3 + 2]).applyMatrix4(tmp.m));
27865
+ }
27866
+ return [box4.min.x, box4.min.y, box4.min.z, box4.max.x, box4.max.y, box4.max.z];
27867
+ }
27751
27868
  function maskOf(hostId, parts) {
27752
27869
  const host = structure.byId.get(hostId);
27753
27870
  const [u0, v0, u1, v1] = host.aabb;
@@ -27835,7 +27952,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27835
27952
  for (const { c, part, units: units2, thick, mid } of shown) {
27836
27953
  if (!near(c)) continue;
27837
27954
  const centre = mask.start + (c.a + c.b) / 2, y = (c.y0 + c.y1) / 2, len = c.b - c.a, h = c.y1 - c.y0;
27838
- const at = (s, dy, d, colour) => list2.push({ x: mask.alongU ? centre : mid, y, z: mask.alongU ? mid : centre, sx: mask.alongU ? s : d, sy: dy, sz: mask.alongU ? d : s, colour });
27955
+ const at = (s, dy, d, colour) => {
27956
+ const unit = clipToBox({ x: mask.alongU ? centre : mid, y, z: mask.alongU ? mid : centre, sx: mask.alongU ? s : d, sy: dy, sz: mask.alongU ? d : s, colour }, view.bounds);
27957
+ if (unit) list2.push(unit);
27958
+ };
27839
27959
  const base = fragmentMaterial(part.material).color.getHex();
27840
27960
  const n = noise2(centre * 3.1, y * 2.7, 0.07);
27841
27961
  if (units2.mortar === "concrete") {
@@ -27902,6 +28022,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
27902
28022
  units: null,
27903
28023
  gone: 0,
27904
28024
  pits: 0,
28025
+ bounds: drawnBounds(items),
27905
28026
  chips: new Map(parts.map((id) => [id, []])),
27906
28027
  spalls: new Map(parts.map((id) => [id, []])),
27907
28028
  openings: /* @__PURE__ */ new Map(),
@@ -28055,7 +28176,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28055
28176
  Object.assign(K, { createBreachView });
28056
28177
  }
28057
28178
  var FOLLOW_FLUSH_FALLBACK_MS = 100;
28058
- function installDestructionWorld(K, shared) {
28179
+ function installDestructionWorld(K, shared2) {
28059
28180
  const { THREE, cfg, invalidateShadow, invalidate, rngString, FRAGMENT_GEO, fragmentMaterial, createBreachView } = K;
28060
28181
  function createHouseDestruction(root, house, structure, parts, colliders, water) {
28061
28182
  const D = { world: cfg.destruction || null, id: null, active: false }, hiddenPieces = /* @__PURE__ */ new Set(), bodies = /* @__PURE__ */ new Map(), frags = [], facets = /* @__PURE__ */ new Map();
@@ -28291,7 +28412,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28291
28412
  house.matrixWorld.decompose(p, q, sc);
28292
28413
  D.specOptions = specOptions || null;
28293
28414
  D.spec = structure.spec(specOptions);
28294
- D.id = D.world.add(D.spec, { id: "house3d:" + ++shared.destructionSeq, position: [p.x, p.y, p.z], rotation: [q.x, q.y, q.z, q.w] });
28415
+ D.id = D.world.add(D.spec, { id: "house3d:" + ++shared2.destructionSeq, position: [p.x, p.y, p.z], rotation: [q.x, q.y, q.z, q.w] });
28295
28416
  breach.claim();
28296
28417
  if (R) R.bind(D.id, house, { parts: rangesOf(), onFrame: () => breach.flush() });
28297
28418
  off = D.world.on("*", handleEvent);
@@ -28437,7 +28558,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28437
28558
  }
28438
28559
  Object.assign(K, { createHouseDestruction });
28439
28560
  }
28440
- function installBuildBuild(K, shared) {
28561
+ function installBuildBuild(K, shared2) {
28441
28562
  const { THREE, cfg, rectsOf: rectsOf2, invalidateShadow, colliderChanged, VERSION: VERSION2, CARS, EPS: EPS3, LIGHTS, MIRRORS, Y0, animateClotheslines, animateDoors, animateInteractive, applyLeaf, applyOutbuildings, applyPart, applyPiece, assembleInteractive, baseboardAndSidewalk, buildStairs, building, carModel, chooseMirror, closeScene, collideAt, createWater, cursor, doorText, doors, electricalStructure, elevator, floorsAndSlabs, gatesInteractive, houseItems, ivAssemble, ivBuild, ivDispose, ivParts, ivPublish, ivUpdate, lightOn, linkDoorLeaves, mailboxInteractive, newInteractiveState, newMirrorState, outbuildings, paths, perimeter, placeSwitches, roofs, roomAt, solar, targetOf, terrain, toggleDoor, toggleLight, walls, waterPipes, windows, props, TYPES, IVK, VEG, vegMaterials, markGroups, assembleStructure, createHouseDestruction, newState, enter, tagDamage } = K;
28442
28563
  function build(r0, opts) {
28443
28564
  opts = opts || {};
@@ -28448,43 +28569,43 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28448
28569
  cursor.accs.clear();
28449
28570
  LIGHTS.length = 0;
28450
28571
  const pr = opts.building || {};
28451
- shared.ctx.r = r;
28452
- shared.ctx.colors = r.colors;
28453
- shared.ctx.cut = !!opts.cut;
28454
- shared.ctx.night = !!opts.night;
28455
- shared.ctx.labels = [];
28456
- shared.ctx.colliders = [];
28457
- shared.ctx.stairs = [];
28458
- shared.ctx.noTerrain = opts.terrain === false;
28459
- shared.ctx.roomById = {};
28460
- for (const c of r.rooms) shared.ctx.roomById[c.id] = c;
28461
- shared.ctx.pieces = /* @__PURE__ */ new Map();
28462
- shared.ctx.pieceObjects = /* @__PURE__ */ new Map();
28463
- shared.ctx.structureIndex = {};
28464
- for (const e of r0.structure && r0.structure.parts || []) shared.ctx.structureIndex[e.id] = e;
28572
+ shared2.ctx.r = r;
28573
+ shared2.ctx.colors = r.colors;
28574
+ shared2.ctx.cut = !!opts.cut;
28575
+ shared2.ctx.night = !!opts.night;
28576
+ shared2.ctx.labels = [];
28577
+ shared2.ctx.colliders = [];
28578
+ shared2.ctx.stairs = [];
28579
+ shared2.ctx.noTerrain = opts.terrain === false;
28580
+ shared2.ctx.roomById = {};
28581
+ for (const c of r.rooms) shared2.ctx.roomById[c.id] = c;
28582
+ shared2.ctx.pieces = /* @__PURE__ */ new Map();
28583
+ shared2.ctx.pieceObjects = /* @__PURE__ */ new Map();
28584
+ shared2.ctx.structureIndex = {};
28585
+ for (const e of r0.structure && r0.structure.parts || []) shared2.ctx.structureIndex[e.id] = e;
28465
28586
  {
28466
- const view = shared.ctx.panelView = panelViewOf(r0.structure, !!cfg.destruction);
28467
- shared.ctx.panelsOf = /* @__PURE__ */ new Map();
28468
- for (const id of view.replaced) delete shared.ctx.structureIndex[id];
28587
+ const view = shared2.ctx.panelView = panelViewOf(r0.structure, !!cfg.destruction);
28588
+ shared2.ctx.panelsOf = /* @__PURE__ */ new Map();
28589
+ for (const id of view.replaced) delete shared2.ctx.structureIndex[id];
28469
28590
  for (const e of view.panels) {
28470
- shared.ctx.structureIndex[e.id] = e;
28471
- const l = shared.ctx.panelsOf.get(e.slab);
28591
+ shared2.ctx.structureIndex[e.id] = e;
28592
+ const l = shared2.ctx.panelsOf.get(e.slab);
28472
28593
  if (l) l.push(e);
28473
- else shared.ctx.panelsOf.set(e.slab, [e]);
28594
+ else shared2.ctx.panelsOf.set(e.slab, [e]);
28474
28595
  }
28475
28596
  }
28476
- shared.ctx.panes = r0.roof && r0.roof.panes || [];
28477
- shared.ctx.noPiece = false;
28597
+ shared2.ctx.panes = r0.roof && r0.roof.panes || [];
28598
+ shared2.ctx.noPiece = false;
28478
28599
  cursor.separate = opts.pieces === "meshes";
28479
28600
  cursor.pc = null;
28480
- shared.ctx.apartment = r.template === "apartment_modern";
28481
- shared.ctx.pa = Math.max(3, Math.min(20, pr.floors != null ? pr.floors : 5));
28482
- shared.ctx.pf = Math.max(1, Math.min(shared.ctx.pa, pr.floor != null ? pr.floor : 3));
28483
- shared.ctx.pu = Math.max(0, pr.unit != null ? pr.unit : 0);
28484
- shared.ctx.showBuilding = shared.ctx.apartment && (pr.showIt == null ? true : !!pr.showIt);
28485
- shared.ctx.limits = { x0: -2, z0: -2, x1: r.w + 2, z1: r.d + 2 };
28486
- shared.ctx.veg = VEG ? { G: VEG.G, S: VEG.S, mats: vegMaterials, groups: /* @__PURE__ */ new Map(), ok: /* @__PURE__ */ new Map(), opts: shared.quality === "game" ? { quality: "game" } : { lod: 0, triangleBudget: 6e4 } } : null;
28487
- shared.ctx.vegInfo = null;
28601
+ shared2.ctx.apartment = r.template === "apartment_modern";
28602
+ shared2.ctx.pa = Math.max(3, Math.min(20, pr.floors != null ? pr.floors : 5));
28603
+ shared2.ctx.pf = Math.max(1, Math.min(shared2.ctx.pa, pr.floor != null ? pr.floor : 3));
28604
+ shared2.ctx.pu = Math.max(0, pr.unit != null ? pr.unit : 0);
28605
+ shared2.ctx.showBuilding = shared2.ctx.apartment && (pr.showIt == null ? true : !!pr.showIt);
28606
+ shared2.ctx.limits = { x0: -2, z0: -2, x1: r.w + 2, z1: r.d + 2 };
28607
+ shared2.ctx.veg = VEG ? { G: VEG.G, S: VEG.S, mats: vegMaterials, groups: /* @__PURE__ */ new Map(), ok: /* @__PURE__ */ new Map(), opts: shared2.quality === "game" ? { quality: "game" } : { lod: 0, triangleBudget: 6e4 } } : null;
28608
+ shared2.ctx.vegInfo = null;
28488
28609
  terrain();
28489
28610
  if (r.lot) {
28490
28611
  if (!opts.noPerimeter) {
@@ -28495,7 +28616,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28495
28616
  }
28496
28617
  walls();
28497
28618
  baseboardAndSidewalk();
28498
- shared.ctx.wallColliders = shared.ctx.colliders.length;
28619
+ shared2.ctx.wallColliders = shared2.ctx.colliders.length;
28499
28620
  doors();
28500
28621
  windows();
28501
28622
  floorsAndSlabs();
@@ -28503,14 +28624,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28503
28624
  buildStairs();
28504
28625
  elevator();
28505
28626
  const water = createWater(r, h.state);
28506
- shared.ctx.iv = null;
28627
+ shared2.ctx.iv = null;
28507
28628
  h.IV = null;
28508
28629
  if (IVK) {
28509
28630
  try {
28510
- h.IV = shared.ctx.iv = ivBuild(h, water);
28631
+ h.IV = shared2.ctx.iv = ivBuild(h, water);
28511
28632
  } catch (e) {
28512
28633
  console.warn("interactables", e);
28513
- shared.ctx.iv = h.IV = null;
28634
+ shared2.ctx.iv = h.IV = null;
28514
28635
  }
28515
28636
  }
28516
28637
  const noModel = houseItems();
@@ -28519,14 +28640,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28519
28640
  electricalStructure();
28520
28641
  roofs();
28521
28642
  solar();
28522
- if (shared.ctx.showBuilding) building();
28643
+ if (shared2.ctx.showBuilding) building();
28523
28644
  for (const c of r.rooms) {
28524
28645
  if (c.type === "void") continue;
28525
28646
  const [a, b, c2, d] = rectsOf2(c)[0];
28526
- shared.ctx.labels.push({ pos: new THREE.Vector3((a + c2) / 2, Y0(c.floor) + 1.1, (b + d) / 2), text: c.name, group: "f" + c.floor, type: "room", floor: c.floor });
28647
+ shared2.ctx.labels.push({ pos: new THREE.Vector3((a + c2) / 2, Y0(c.floor) + 1.1, (b + d) / 2), text: c.name, group: "f" + c.floor, type: "room", floor: c.floor });
28527
28648
  }
28528
- const mirrorsCopy = MIRRORS.map((E, i) => Object.assign({ i }, E)), gs = closeScene(shared.mats);
28529
- for (const fo of shared.ctx.leaves) {
28649
+ const mirrorsCopy = MIRRORS.map((E, i) => Object.assign({ i }, E)), gs = closeScene(shared2.mats);
28650
+ for (const fo of shared2.ctx.leaves) {
28530
28651
  const parent = gs["f" + fo.floor] || (gs["f" + fo.floor] = new THREE.Group());
28531
28652
  fo.gs = [];
28532
28653
  for (const gd of fo.groups) {
@@ -28539,22 +28660,22 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28539
28660
  }
28540
28661
  applyLeaf(fo);
28541
28662
  }
28542
- if (shared.ctx.iv) ivAssemble(shared.ctx.iv, gs);
28663
+ if (shared2.ctx.iv) ivAssemble(shared2.ctx.iv, gs);
28543
28664
  assembleInteractive(gs);
28544
28665
  linkDoorLeaves();
28545
28666
  mailboxInteractive();
28546
28667
  const root = markKitOrigin(new THREE.Group(), { owner: "game-floorplan-three", kind: "structure", id: r.template }), house = new THREE.Group();
28547
28668
  root.name = "house3d";
28548
28669
  root.add(house);
28549
- shared.mirrors.house = house;
28550
- if (shared.ctx.apartment) {
28551
- const u = r.building.units[Math.min(shared.ctx.pu, r.building.units.length - 1)];
28552
- house.position.set(u.u, shared.ctx.showBuilding ? 0 : -r.floors[0].y0, u.v);
28670
+ shared2.mirrors.house = house;
28671
+ if (shared2.ctx.apartment) {
28672
+ const u = r.building.units[Math.min(shared2.ctx.pu, r.building.units.length - 1)];
28673
+ house.position.set(u.u, shared2.ctx.showBuilding ? 0 : -r.floors[0].y0, u.v);
28553
28674
  house.rotation.y = u.ry;
28554
- shared.ctx.unitRy = u.ry;
28675
+ shared2.ctx.unitRy = u.ry;
28555
28676
  }
28556
28677
  house.updateMatrixWorld(true);
28557
- shared.ctx.unitInverse = house.matrixWorld.clone().invert();
28678
+ shared2.ctx.unitInverse = house.matrixWorld.clone().invert();
28558
28679
  for (const [k, g] of Object.entries(gs)) {
28559
28680
  g.name = k;
28560
28681
  (k === "floor" || k === "building" ? root : house).add(g);
@@ -28563,31 +28684,31 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28563
28684
  h.root = root;
28564
28685
  h.house = house;
28565
28686
  h.houseGroup = house;
28566
- shared.ctx.noModel = noModel;
28567
- shared.ctx.lights = LIGHTS.filter((l) => l.type !== "lantern" && l.type !== "candles" || shared.ctx.night).map((l) => ({ ...l }));
28568
- shared.ctx.animateDoorsOn = shared.ctx.animateDoorsOn || false;
28569
- for (const c of shared.ctx.colliders) {
28687
+ shared2.ctx.noModel = noModel;
28688
+ shared2.ctx.lights = LIGHTS.filter((l) => l.type !== "lantern" && l.type !== "candles" || shared2.ctx.night).map((l) => ({ ...l }));
28689
+ shared2.ctx.animateDoorsOn = shared2.ctx.animateDoorsOn || false;
28690
+ for (const c of shared2.ctx.colliders) {
28570
28691
  c.aabb = [c.x0, c.z0, c.x1, c.z1];
28571
28692
  if (c.type === "wall") c.damageable = tagDamage("masonry");
28572
28693
  }
28573
- const colliders = shared.ctx.colliders.concat(shared.inter.objs.map((o) => ({ type: "furniture", f: o.f, obb: { cx: o.cx, cz: o.cz, hw: o.hw, hd: o.hd, c: o.c, s: o.s }, item: o.type, off: false })));
28694
+ const colliders = shared2.ctx.colliders.concat(shared2.inter.objs.map((o) => ({ type: "furniture", f: o.f, obb: { cx: o.cx, cz: o.cz, hw: o.hw, hd: o.hd, c: o.c, s: o.s }, item: o.type, off: false })));
28574
28695
  const parts = {}, setOpen = (def, t) => {
28575
28696
  def.target = t;
28576
28697
  def.t = t;
28577
- shared.partState.set(def.name, t);
28698
+ shared2.partState.set(def.name, t);
28578
28699
  if (def.col) {
28579
28700
  def.col.off = t > 0.5;
28580
28701
  colliderChanged(def.col);
28581
28702
  }
28582
28703
  applyPiece(def);
28583
- shared.inter.anim.delete(def);
28704
+ shared2.inter.anim.delete(def);
28584
28705
  invalidateShadow();
28585
28706
  };
28586
28707
  const mark = (o, id) => {
28587
28708
  if (o) o.userData.partId = id;
28588
28709
  };
28589
28710
  const PART_DAMAGE = { water_tank: "water", shower_door: "glass", gate_leaf: "metal", mailbox_door: "metal", mirror: "glass", cooking_gas_cylinder: "gas" };
28590
- for (const [id, g] of Object.entries(shared.ctx.parts || {})) {
28711
+ for (const [id, g] of Object.entries(shared2.ctx.parts || {})) {
28591
28712
  const tp = g.userData.part, dn = PART_DAMAGE[tp];
28592
28713
  if (dn) g.userData.damageable = tagDamage(dn);
28593
28714
  mark(g, id);
@@ -28607,7 +28728,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28607
28728
  return g.userData.t || 0;
28608
28729
  }, meta: g.userData };
28609
28730
  }
28610
- for (const fo of shared.ctx.leaves) {
28731
+ for (const fo of shared2.ctx.leaves) {
28611
28732
  const id = "door:" + fo.id, dn = tagDamage(fo.type === "steel" ? "metal" : "wood");
28612
28733
  fo.damageable = dn;
28613
28734
  for (const g of fo.gs) mark(g, id);
@@ -28619,14 +28740,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28619
28740
  fo.col.off = fo.open;
28620
28741
  colliderChanged(fo.col);
28621
28742
  }
28622
- shared.doorState.set(fo.id, fo.open);
28743
+ shared2.doorState.set(fo.id, fo.open);
28623
28744
  applyLeaf(fo);
28624
28745
  invalidateShadow();
28625
28746
  }, get t() {
28626
28747
  return fo.t;
28627
28748
  }, leaf: fo };
28628
28749
  }
28629
- for (const def of shared.inter.defs.values()) {
28750
+ for (const def of shared2.inter.defs.values()) {
28630
28751
  if (!def.outer) continue;
28631
28752
  const cab = def.kind === "swing" || def.kind === "drawer", gate = /^gate/.test(def.kind);
28632
28753
  const dn = cab ? tagDamage("wood") : gate ? tagDamage("metal") : null;
@@ -28636,7 +28757,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28636
28757
  return def.t;
28637
28758
  }, def };
28638
28759
  }
28639
- if (shared.ctx.iv) ivParts(shared.ctx.iv, parts, tagDamage);
28760
+ if (shared2.ctx.iv) ivParts(shared2.ctx.iv, parts, tagDamage);
28640
28761
  const cars = [];
28641
28762
  CARS.forEach((C, i) => {
28642
28763
  const mod = carModel(C.k, C.seed);
@@ -28676,18 +28797,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28676
28797
  const actOn = (e, a) => {
28677
28798
  enter(h);
28678
28799
  if (cfg.onInteract && cfg.onInteract(e, a) === false) return false;
28679
- shared.inter.target = a || { target: e.ref, text: e.label, action: e._action };
28800
+ shared2.inter.target = a || { target: e.ref, text: e.label, action: e._action };
28680
28801
  e._action();
28681
28802
  return true;
28682
28803
  };
28683
- for (const fo of shared.ctx.leaves) {
28804
+ for (const fo of shared2.ctx.leaves) {
28684
28805
  const e = { id: "door:" + fo.id, type: fo.type === "steel" ? "garage_door" : "door", floor: fo.floor, pos: [fo.cx, Y0(fo.floor) + 1, fo.cz], radius: 1.7, get label() {
28685
28806
  return doorText(fo);
28686
28807
  }, ref: fo, _action: () => toggleDoor(fo) };
28687
28808
  e.act = () => actOn(e);
28688
28809
  interactables.push(e);
28689
28810
  }
28690
- for (const it of shared.inter.items) {
28811
+ for (const it of shared2.inter.items) {
28691
28812
  const k = it.type + ":" + it.id, n = usedMap.get(k) || 0;
28692
28813
  usedMap.set(k, n + 1);
28693
28814
  const e = { id: n ? k + "#" + n : k, type: it.type, floor: it.floor, pos: it.anchor.slice(), radius: it.range, angle: it.angle, get label() {
@@ -28697,12 +28818,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28697
28818
  interactables.push(e);
28698
28819
  it.pub = e;
28699
28820
  }
28700
- for (const fo of shared.ctx.leaves) fo.pub = interactables.find((e) => e.ref === fo);
28821
+ for (const fo of shared2.ctx.leaves) fo.pub = interactables.find((e) => e.ref === fo);
28701
28822
  const lodObjects = [];
28702
- for (const def of shared.inter.defs.values()) if (def.outer && /^(light|drawer|swing|curtain|light_switch|handle)$/.test(def.kind)) lodObjects.push(def.outer);
28703
- for (const [id, g] of Object.entries(shared.ctx.parts || {})) if (/^(handle|shower_door)$/.test(g.userData.part) && g.visible !== false) lodObjects.push(g);
28704
- if (shared.ctx.iv) {
28705
- for (const E of shared.ctx.iv.roots) lodObjects.push(E.root);
28823
+ for (const def of shared2.inter.defs.values()) if (def.outer && /^(light|drawer|swing|curtain|light_switch|handle)$/.test(def.kind)) lodObjects.push(def.outer);
28824
+ for (const [id, g] of Object.entries(shared2.ctx.parts || {})) if (/^(handle|shower_door)$/.test(g.userData.part) && g.visible !== false) lodObjects.push(g);
28825
+ if (shared2.ctx.iv) {
28826
+ for (const E of shared2.ctx.iv.roots) lodObjects.push(E.root);
28706
28827
  }
28707
28828
  const countDraw = () => {
28708
28829
  let n = 0, t = 0;
@@ -28720,7 +28841,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28720
28841
  for (const o of lodObjects) o.visible = true;
28721
28842
  const budget = opts.drawCallBudget != null ? opts.drawCallBudget : cfg.drawCallBudget;
28722
28843
  const stats2 = { quality: h.quality, drawCalls: s0.n, drawCallsLOD1: s1.n, triangles: s0.t, trianglesLod1: s1.t, budget: budget || null, overBudget: !!budget && s0.n > budget, tBuild: performance.now() - t0 };
28723
- shared.ctx.tBuild = stats2.tBuild;
28844
+ shared2.ctx.tBuild = stats2.tBuild;
28724
28845
  const applyLod = (n) => {
28725
28846
  n = Math.max(0, Math.min(2, n | 0));
28726
28847
  if (n === h.lodCurrent) return;
@@ -28786,39 +28907,39 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28786
28907
  building: gs.building || null,
28787
28908
  waterTank: r.waterTank ? (() => {
28788
28909
  const pt = Object.values(parts).find((p) => p.type === "water_tank") || null;
28789
- return { part: pt, group: pt ? pt.group : null, pos: shared.ctx.waterTankPos || null, plant: r.waterTank };
28910
+ return { part: pt, group: pt ? pt.group : null, pos: shared2.ctx.waterTankPos || null, plant: r.waterTank };
28790
28911
  })() : null,
28791
28912
  colliders,
28792
28913
  parts,
28793
28914
  cars,
28794
28915
  interactables,
28795
- doors: shared.ctx.leaves,
28796
- stairs: shared.ctx.stairs,
28797
- labels: shared.ctx.labels,
28916
+ doors: shared2.ctx.leaves,
28917
+ stairs: shared2.ctx.stairs,
28918
+ labels: shared2.ctx.labels,
28798
28919
  noModel,
28799
28920
  lights: (() => {
28800
28921
  const by = {};
28801
- for (const l of shared.ctx.lights) {
28922
+ for (const l of shared2.ctx.lights) {
28802
28923
  const k = l.roomId != null ? l.roomId : l.room;
28803
28924
  (by[k] || (by[k] = [])).push(l);
28804
28925
  }
28805
- return { list: shared.ctx.lights, byRoom: by };
28926
+ return { list: shared2.ctx.lights, byRoom: by };
28806
28927
  })(),
28807
- limits: shared.ctx.limits,
28808
- apartment: shared.ctx.apartment,
28809
- showBuilding: shared.ctx.showBuilding,
28810
- buildingConfig: { floors: shared.ctx.pa, floor: shared.ctx.pf, unit: shared.ctx.pu },
28811
- unitRy: shared.ctx.unitRy || 0,
28812
- night: shared.ctx.night,
28813
- cut: shared.ctx.cut,
28928
+ limits: shared2.ctx.limits,
28929
+ apartment: shared2.ctx.apartment,
28930
+ showBuilding: shared2.ctx.showBuilding,
28931
+ buildingConfig: { floors: shared2.ctx.pa, floor: shared2.ctx.pf, unit: shared2.ctx.pu },
28932
+ unitRy: shared2.ctx.unitRy || 0,
28933
+ night: shared2.ctx.night,
28934
+ cut: shared2.ctx.cut,
28814
28935
  interactives: h.IV ? ivPublish(h) : null,
28815
28936
  state: h.state,
28816
28937
  stats: stats2,
28817
- vegetation: shared.ctx.vegInfo || null,
28818
- solar: shared.ctx.solarInfo || null,
28938
+ vegetation: shared2.ctx.vegInfo || null,
28939
+ solar: shared2.ctx.solarInfo || null,
28819
28940
  water,
28820
- electrical: shared.ctx.electricalInfo || null,
28821
- gutters: shared.ctx.gutterInfo || null,
28941
+ electrical: shared2.ctx.electricalInfo || null,
28942
+ gutters: shared2.ctx.gutterInfo || null,
28822
28943
  // per frame: doors, parts, wind-blown laundry and (with a focus) distance LOD; dt in seconds, time in ms (rAF); focus = {x,y,z} in world coordinates
28823
28944
  update(dt, time, focus) {
28824
28945
  enter(h);
@@ -28828,9 +28949,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28828
28949
  if (destruction.active || destruction.statistics().falling || destruction.statistics().fragments) destruction.animate(dt);
28829
28950
  if (h.IV) ivUpdate(h, dt, time, focus);
28830
28951
  if (time != null) animateClotheslines(time);
28831
- if (shared.vegMaterials) {
28832
- shared.vegMaterials.update((time != null ? time : performance.now()) / 1e3);
28833
- shared.vegMaterials.setActors(focus ? [{ x: focus.x, y: focus.y, z: focus.z, radius: 0.9 }] : []);
28952
+ if (shared2.vegMaterials) {
28953
+ shared2.vegMaterials.update((time != null ? time : performance.now()) / 1e3);
28954
+ shared2.vegMaterials.setActors(focus ? [{ x: focus.x, y: focus.y, z: focus.z, radius: 0.9 }] : []);
28834
28955
  }
28835
28956
  if (focus && cfg.lod !== false) {
28836
28957
  const L = Object.assign({ interior: 45, hide: 220 }, cfg.lod), d = distance2(focus), at = h.lodCurrent;
@@ -28842,12 +28963,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28842
28963
  show(o) {
28843
28964
  enter(h);
28844
28965
  o = o || {};
28845
- const rr = shared.ctx.r, nA = rr.floors.length, a = o.floor == null ? -1 : o.floor, sel = a >= nA ? -1 : a, cut = !!o.cut;
28966
+ const rr = shared2.ctx.r, nA = rr.floors.length, a = o.floor == null ? -1 : o.floor, sel = a >= nA ? -1 : a, cut = !!o.cut;
28846
28967
  for (const [k, g] of Object.entries(gs)) {
28847
28968
  let v = true;
28848
28969
  if (k[0] === "f") v = sel < 0 || +k.slice(1) <= sel;
28849
28970
  else if (k[0] === "t") v = !cut && (sel < 0 || +k.slice(1) < sel);
28850
- else if (k === "roof") v = !cut && sel < 0 && (!shared.ctx.apartment || !shared.ctx.showBuilding || shared.ctx.pf === shared.ctx.pa);
28971
+ else if (k === "roof") v = !cut && sel < 0 && (!shared2.ctx.apartment || !shared2.ctx.showBuilding || shared2.ctx.pf === shared2.ctx.pa);
28851
28972
  else if (k === "attic_tank") v = (cut || sel >= 0) && (sel < 0 || nA - 1 <= sel);
28852
28973
  else if (k === "lot") v = o.lot == null ? true : !!o.lot;
28853
28974
  g.visible = v;
@@ -28864,11 +28985,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28864
28985
  return actOn(a.target && a.target.pub ? a.target.pub : { id: a.target && a.target.id || a.text, type: a.target && a.target.kit ? a.target.type : "door", label: a.text, ref: a.target, _action: a.action }, a);
28865
28986
  },
28866
28987
  message() {
28867
- return shared.inter.msg && performance.now() < shared.inter.msg.until ? shared.inter.msg.text : null;
28988
+ return shared2.inter.msg && performance.now() < shared2.inter.msg.until ? shared2.inter.msg.text : null;
28868
28989
  },
28869
28990
  toggleDoor(fo) {
28870
28991
  enter(h);
28871
- toggleDoor(typeof fo === "string" ? shared.ctx.leaves.find((f) => f.id === fo) : fo);
28992
+ toggleDoor(typeof fo === "string" ? shared2.ctx.leaves.find((f) => f.id === fo) : fo);
28872
28993
  },
28873
28994
  lightOn(roomId) {
28874
28995
  enter(h);
@@ -28940,13 +29061,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28940
29061
  });
28941
29062
  root.removeFromParent();
28942
29063
  },
28943
- internal: { h, ctx: shared.ctx, inter: shared.inter, partState: shared.partState, doorState: shared.doorState, mirrors: shared.mirrors }
29064
+ internal: { h, ctx: shared2.ctx, inter: shared2.inter, partState: shared2.partState, doorState: shared2.doorState, mirrors: shared2.mirrors }
28944
29065
  };
28945
29066
  return res;
28946
29067
  }
28947
29068
  Object.assign(K, { build });
28948
29069
  }
28949
- function buildApi(K, shared) {
29070
+ function buildApi(K, shared2) {
28950
29071
  const { cfg, VERSION: VERSION2, ATLAS, TEX, applyPart, carGroup, carModel, props, TYPES, roomLightMask, lighting, newState, build } = K;
28951
29072
  return {
28952
29073
  version: VERSION2,
@@ -28956,26 +29077,26 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28956
29077
  mv: props,
28957
29078
  applyPart,
28958
29079
  // the kernel and the shared state, for recorders that run the team's builders into something else than the house (`furnitureSpec`, `tapSpec`): not a stable api
28959
- internals: { K, shared },
29080
+ internals: { K, shared: shared2 },
28960
29081
  get materials() {
28961
- return shared.mats;
29082
+ return shared2.mats;
28962
29083
  },
28963
29084
  roomLightMask,
28964
29085
  lighting,
28965
29086
  setNight(n) {
28966
- shared.mats.glass.emissive.set(n ? 9067040 : 0);
28967
- shared.mats.glass.opacity = n ? 0.4 : 0.24;
29087
+ shared2.mats.glass.emissive.set(n ? 9067040 : 0);
29088
+ shared2.mats.glass.opacity = n ? 0.4 : 0.24;
28968
29089
  },
28969
29090
  cars: { model: carModel, group: carGroup, info: (k, seed) => {
28970
29091
  const m = carModel(k, seed);
28971
29092
  return m && { parts: m.parts.length, tris: m.tris, L: m.L, W: m.W, H: m.H };
28972
29093
  } },
28973
29094
  dispose() {
28974
- if (shared.vegMaterials) {
28975
- shared.vegMaterials.dispose();
28976
- shared.vegMaterials = null;
29095
+ if (shared2.vegMaterials) {
29096
+ shared2.vegMaterials.dispose();
29097
+ shared2.vegMaterials = null;
28977
29098
  }
28978
- for (const m of Object.values(shared.mats)) {
29099
+ for (const m of Object.values(shared2.mats)) {
28979
29100
  if (m && m.dispose) m.dispose();
28980
29101
  }
28981
29102
  for (const [k, t] of Object.entries(TEX)) if (t && t.dispose && !(cfg.textures && cfg.textures[k])) t.dispose();
@@ -29000,7 +29121,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29000
29121
  const colliderChanged = (c) => {
29001
29122
  if (c && cfg.onCollider) cfg.onCollider(c);
29002
29123
  };
29003
- const shared = { mats: null, quality: cfg.quality === "game" ? "game" : "high" };
29124
+ const shared2 = { mats: null, quality: cfg.quality === "game" ? "game" : "high" };
29004
29125
  const seedKey = (id) => {
29005
29126
  if (cfg.seedKey && id != null) {
29006
29127
  const k = cfg.seedKey(String(id));
@@ -29009,61 +29130,61 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29009
29130
  return id;
29010
29131
  };
29011
29132
  const K = { t: createTranslator2(cfg.locale), seedKey, THREE: shapeGeometries(THREE), cfg, DOC, PROPS, Reflector, FLEET, HP, invalidate, invalidateShadow, colliderChanged, VERSION, rectsOf, isOpenArea, OPEN_ROOM_TYPES: OPEN_ROOM_TYPES2 };
29012
- installKernelGeometry(K, shared);
29013
- installKernelNoise(K, shared);
29014
- installMaterialsTextures(K, shared);
29015
- installMaterialsMaterials(K, shared);
29016
- installKernelCloseScene(K, shared);
29017
- installHouseHelpers(K, shared);
29018
- installHouseWalls(K, shared);
29019
- installHouseDoors(K, shared);
29020
- installHouseWindows(K, shared);
29021
- installHouseFloors(K, shared);
29022
- installHouseStairs(K, shared);
29023
- installLightsFixtures(K, shared);
29024
- installLightsDecor(K, shared);
29025
- installLotTerrain(K, shared);
29026
- installLotPerimeter(K, shared);
29027
- installLotGates(K, shared);
29028
- installRoofRoofs(K, shared);
29029
- installRoofGutters(K, shared);
29030
- installRoofSlabs(K, shared);
29031
- installRoofTiles(K, shared);
29032
- installRoofRect(K, shared);
29033
- installMirrors(K, shared);
29034
- installCars(K, shared);
29035
- installHouseBuilding(K, shared);
29036
- installUtilitiesWater(K, shared);
29037
- installUtilitiesElectrical(K, shared);
29038
- installHouseBaseboard(K, shared);
29039
- installUtilitiesSolar(K, shared);
29040
- installHouseOutbuildings(K, shared);
29041
- installFurnitureApi(K, shared);
29042
- installFurnitureBuilders(K, shared);
29043
- installFurnitureTypeTable(K, shared);
29044
- installFurnitureTaps(K, shared);
29045
- installFurnitureFixtures(K, shared);
29046
- installFurniturePlants(K, shared);
29047
- installFurnitureYard(K, shared);
29048
- installFurnitureExtraTypes(K, shared);
29049
- installFurniturePlaceItems(K, shared);
29050
- installVegetationBridge(K, shared);
29051
- installInteractionState(K, shared);
29052
- installInteractionCollision(K, shared);
29053
- installInteractionItems(K, shared);
29054
- installInteractionFittings(K, shared);
29055
- installInteractionDoors(K, shared);
29056
- installInteractionTarget(K, shared);
29057
- installInteractablesBridge(K, shared);
29058
- installAnimationClotheslines(K, shared);
29059
- installBuildInstance(K, shared);
29060
- installInteractablesKit(K, shared);
29061
- installLightsRoomLight(K, shared);
29062
- installDestructionPieces(K, shared);
29063
- installDestructionBreach(K, shared);
29064
- installDestructionWorld(K, shared);
29065
- installBuildBuild(K, shared);
29066
- return buildApi(K, shared);
29133
+ installKernelGeometry(K, shared2);
29134
+ installKernelNoise(K, shared2);
29135
+ installMaterialsTextures(K, shared2);
29136
+ installMaterialsMaterials(K, shared2);
29137
+ installKernelCloseScene(K, shared2);
29138
+ installHouseHelpers(K, shared2);
29139
+ installHouseWalls(K, shared2);
29140
+ installHouseDoors(K, shared2);
29141
+ installHouseWindows(K, shared2);
29142
+ installHouseFloors(K, shared2);
29143
+ installHouseStairs(K, shared2);
29144
+ installLightsFixtures(K, shared2);
29145
+ installLightsDecor(K, shared2);
29146
+ installLotTerrain(K, shared2);
29147
+ installLotPerimeter(K, shared2);
29148
+ installLotGates(K, shared2);
29149
+ installRoofRoofs(K, shared2);
29150
+ installRoofGutters(K, shared2);
29151
+ installRoofSlabs(K, shared2);
29152
+ installRoofTiles(K, shared2);
29153
+ installRoofRect(K, shared2);
29154
+ installMirrors(K, shared2);
29155
+ installCars(K, shared2);
29156
+ installHouseBuilding(K, shared2);
29157
+ installUtilitiesWater(K, shared2);
29158
+ installUtilitiesElectrical(K, shared2);
29159
+ installHouseBaseboard(K, shared2);
29160
+ installUtilitiesSolar(K, shared2);
29161
+ installHouseOutbuildings(K, shared2);
29162
+ installFurnitureApi(K, shared2);
29163
+ installFurnitureBuilders(K, shared2);
29164
+ installFurnitureTypeTable(K, shared2);
29165
+ installFurnitureTaps(K, shared2);
29166
+ installFurnitureFixtures(K, shared2);
29167
+ installFurniturePlants(K, shared2);
29168
+ installFurnitureYard(K, shared2);
29169
+ installFurnitureExtraTypes(K, shared2);
29170
+ installFurniturePlaceItems(K, shared2);
29171
+ installVegetationBridge(K, shared2);
29172
+ installInteractionState(K, shared2);
29173
+ installInteractionCollision(K, shared2);
29174
+ installInteractionItems(K, shared2);
29175
+ installInteractionFittings(K, shared2);
29176
+ installInteractionDoors(K, shared2);
29177
+ installInteractionTarget(K, shared2);
29178
+ installInteractablesBridge(K, shared2);
29179
+ installAnimationClotheslines(K, shared2);
29180
+ installBuildInstance(K, shared2);
29181
+ installInteractablesKit(K, shared2);
29182
+ installLightsRoomLight(K, shared2);
29183
+ installDestructionPieces(K, shared2);
29184
+ installDestructionBreach(K, shared2);
29185
+ installDestructionWorld(K, shared2);
29186
+ installBuildBuild(K, shared2);
29187
+ return buildApi(K, shared2);
29067
29188
  }
29068
29189
  var WOOD_THIN = 0.035;
29069
29190
  var BOARD_TOP_THICK = 0.07;
@@ -29286,21 +29407,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29286
29407
  const seed = Math.round(opts.seed ?? 1);
29287
29408
  const plain2 = SHELVING.test(type) ? "paper" : "plastic";
29288
29409
  const root = { x: seed, z: 0, ry: 0, w, d, h, y: 0, base: 0, palette: o.palette, seed: `furniture_${type}_${seed}` };
29289
- const { K, shared } = renderer.internals;
29410
+ const { K, shared: shared2 } = renderer.internals;
29290
29411
  const before = K.PARTS.length;
29291
29412
  const made = recordSpec(
29292
29413
  THREE,
29293
29414
  type,
29294
29415
  root,
29295
29416
  (A) => {
29296
- const saved = { api0: shared.api0, ctx: shared.ctx };
29297
- shared.api0 = A;
29298
- shared.ctx = shared.ctx ?? {};
29417
+ const saved = { api0: shared2.api0, ctx: shared2.ctx };
29418
+ shared2.api0 = A;
29419
+ shared2.ctx = shared2.ctx ?? {};
29299
29420
  try {
29300
29421
  ent.f(root, A);
29301
29422
  } finally {
29302
- shared.api0 = saved.api0;
29303
- shared.ctx = saved.ctx;
29423
+ shared2.api0 = saved.api0;
29424
+ shared2.ctx = saved.ctx;
29304
29425
  }
29305
29426
  },
29306
29427
  { materials: { plain: plain2, ...o.materials }, chairs: o.chairs, carcass: SHELVING.test(type) }
@@ -30045,9 +30166,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30045
30166
  }
30046
30167
  };
30047
30168
  const clearBoxes = () => {
30048
- for (const box4 of boxes) {
30049
- box4.parent?.remove(box4);
30050
- }
30169
+ discardObject3D(boxes);
30051
30170
  boxes = [];
30052
30171
  };
30053
30172
  const applyBoxes = () => {
@@ -30066,7 +30185,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30066
30185
  };
30067
30186
  const clearFinds = () => {
30068
30187
  if (findsGroup) {
30069
- findsGroup.parent?.remove(findsGroup);
30188
+ discardObject3D(findsGroup);
30070
30189
  findsGroup = null;
30071
30190
  }
30072
30191
  };
@@ -30324,7 +30443,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30324
30443
  latestTHREE = lent.THREE;
30325
30444
  const offChange = lent.bench?.onChange(onChange);
30326
30445
  const offFrame = lent.onFrame((dt) => {
30327
- for (const entry2 of entries2) if (entry2.group === "showcase" && entry2.root.parent) entry2.root.rotation.y += dt * SPIN;
30446
+ for (let i = entries2.length - 1; i >= 0; i--) if (!entries2[i].root.parent) entries2.splice(i, 1);
30447
+ for (let i = shelfRoots.length - 1; i >= 0; i--) if (!shelfRoots[i].parent) shelfRoots.splice(i, 1);
30448
+ for (const entry2 of entries2) if (entry2.group === "showcase") entry2.root.rotation.y += dt * SPIN;
30328
30449
  });
30329
30450
  return () => {
30330
30451
  offChange?.();