@adatechnology/game-weapons-three 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -38,6 +38,8 @@ var GameWeaponsThree = (() => {
38
38
  GUNSHOT_PROFILES: () => GUNSHOT_PROFILES,
39
39
  GUNSHOT_SAMPLE: () => GUNSHOT_SAMPLE,
40
40
  GUNSHOT_SAMPLE_IDS: () => GUNSHOT_SAMPLE_IDS,
41
+ LAUNCH_SAMPLE: () => LAUNCH_SAMPLE,
42
+ LAUNCH_SOUND_IDS: () => LAUNCH_SOUND_IDS,
41
43
  MECHANICAL_SOUNDS: () => MECHANICAL_SOUNDS,
42
44
  MODEL_ENTRIES: () => MODEL_ENTRIES,
43
45
  MOUNTED_M134_ITEM_ID: () => MOUNTED_M134_ITEM_ID,
@@ -117,6 +119,13 @@ var GameWeaponsThree = (() => {
117
119
  const scaled2 = 0.067 * Math.sqrt(1 + (z / 0.23) ** 4) / (z * z * Math.cbrt(1 + (z / 1.55) ** 3));
118
120
  return scaled2 * w3 * 100;
119
121
  }
122
+ var ATMOSPHERE = 101325;
123
+ function sideOnOverpressure(tnt, distance3) {
124
+ if (!(tnt > 0)) return 0;
125
+ const z = Math.max(distance3, NEAREST) / Math.cbrt(tnt);
126
+ const ratio = 808 * (1 + (z / 4.5) ** 2) / (Math.sqrt(1 + (z / 0.048) ** 2) * Math.sqrt(1 + (z / 0.32) ** 2) * Math.sqrt(1 + (z / 1.35) ** 2));
127
+ return ratio * ATMOSPHERE;
128
+ }
120
129
  function bodyImpulse(tnt, distance3) {
121
130
  if (!(tnt > 0)) return 0;
122
131
  const z = Math.max(distance3, NEAREST) / Math.cbrt(tnt);
@@ -24607,9 +24616,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24607
24616
  var BREACH_AREA = 0.25;
24608
24617
  var BREACH_BLAST_REACH = 0.12;
24609
24618
  var MEMBER_CUT_REACH = 0.5;
24619
+ var FAR_MEMBER_HP_FLOOR = 0.25;
24610
24620
  var BLAST_REFERENCE_RESISTANCE = 200 * 1900 * 0.13;
24611
24621
  var BLAST_EDGE_RAGGED = 0.3;
24612
24622
  var BLAST_EDGE_LOOSE = 1.35;
24623
+ var PANEL_PRESSURE = 7e4;
24624
+ var PANEL_IMPULSE = 150;
24625
+ var PANEL_PI = 6e6;
24626
+ var PANEL_POINTS = [[0, 0], [-0.3, 0], [0.3, 0], [0, -0.3], [0, 0.3]];
24627
+ var PANEL_POINTS_LOADED = 4;
24613
24628
  var BLAST_EDGE_WEAR = 0.6;
24614
24629
  var RESIDUAL_CAPACITY = 0.15;
24615
24630
  var SEVER_BAND = 0.1;
@@ -24634,23 +24649,42 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24634
24649
  const v = table[mat.penetrationClass ?? mat.id] ?? table[mat.id];
24635
24650
  return v === void 0 ? void 0 : v * (mat.penetrationScale ?? 1);
24636
24651
  };
24637
- var capacityScale = (p) => {
24652
+ var BURIED_BLAST_REACH = 0.5;
24653
+ var GIVE_AT_CUT_HP = 0.5;
24654
+ var capacityScale = (p, borne, through) => {
24638
24655
  const residual = p.spec.reinforcement?.residualCapacity ?? RESIDUAL_CAPACITY;
24639
24656
  if (p.st.stripped) return residual;
24640
- const kept = Math.min(p.rt.removed ? 1 - p.rt.removed / p.mass0 : 1, 1 - sectionLoss(p));
24657
+ const kept = Math.min(p.rt.removed ? 1 - p.rt.removed / p.mass0 : 1, sectionKept(p, residual, borne, through));
24641
24658
  return Math.max(p.spec.reinforcement ? residual : 0.05, kept);
24642
24659
  };
24643
- var sectionLoss = (p) => {
24660
+ var sectionKept = (p, residual, borne, through) => {
24661
+ let kept = 1;
24662
+ forEachSection(p, borne, (c, along, gone) => {
24663
+ const share = through?.(c.center, along) ?? 1;
24664
+ if (share <= 0) return;
24665
+ kept = Math.min(kept, Math.max(p.spec.reinforcement ? residual : 0, 1 - gone) / share);
24666
+ });
24667
+ return kept;
24668
+ };
24669
+ var sectionLoss = (p, borne) => {
24670
+ let worst = 0;
24671
+ forEachSection(p, borne, (_c, _along, gone) => {
24672
+ worst = Math.max(worst, gone);
24673
+ });
24674
+ return Math.min(1, worst);
24675
+ };
24676
+ var forEachSection = (p, borne, visit) => {
24644
24677
  const cells = p.st.chipped;
24645
- if (!cells?.length) return 0;
24678
+ if (!cells?.length) return;
24646
24679
  const [u, v] = planeAxes(p.thin);
24647
24680
  const role = p.spec.structure?.role;
24648
24681
  const up = rotateVec(p.q, [0, 0, 0].map((_, k) => k === v ? 1 : 0));
24649
24682
  const upright = Math.abs(up[1]) > 0.7 ? v : Math.abs(rotateVec(p.q, [0, 0, 0].map((_, k) => k === u ? 1 : 0))[1]) > 0.7 ? u : -1;
24650
24683
  const along = (role === "wall" || role === "partition" || role === "column") && upright >= 0 ? upright : p.dims[u] >= p.dims[v] ? u : v;
24651
24684
  const across2 = along === u ? v : u;
24652
- let worst = 0;
24685
+ const lying = along !== upright || upright < 0;
24653
24686
  for (const c of cells) {
24687
+ if (lying && borne?.(c.center, along)) continue;
24654
24688
  const spans = [];
24655
24689
  for (const d of cells) if (Math.abs(d.center[along] - c.center[along]) < d.size[along] / 2 + 1e-6) spans.push([d.center[across2] - d.size[across2] / 2, d.center[across2] + d.size[across2] / 2]);
24656
24690
  spans.sort((a, b) => a[0] - b[0]);
@@ -24660,9 +24694,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24660
24694
  gone += b - Math.max(a, end3);
24661
24695
  end3 = b;
24662
24696
  }
24663
- worst = Math.max(worst, gone / Math.max(p.dims[across2], 1e-6));
24697
+ visit(c, along, Math.min(1, gone / Math.max(p.dims[across2], 1e-6)));
24664
24698
  }
24665
- return Math.min(1, worst);
24666
24699
  };
24667
24700
  var isLost = (p) => p.st.status === "broken" || p.st.status === "melted" || p.st.status === "ashes";
24668
24701
  var clone = (v) => structuredClone(v);
@@ -24973,6 +25006,26 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24973
25006
  byTouching.set(support, { version: poseVersion, box: box5 });
24974
25007
  return box5;
24975
25008
  };
25009
+ const throughOf = (p) => {
25010
+ const load = p.st.load ?? 0;
25011
+ if (load <= 0) return void 0;
25012
+ const above2 = Math.max(0, load - p.st.mass);
25013
+ const up = rotateVec(p.q, [0, 1, 0]);
25014
+ return (local2, along) => {
25015
+ const axis2 = [0, 0, 0];
25016
+ axis2[along] = 1;
25017
+ const sign2 = Math.sign(rotateVec(p.q, axis2)[1]);
25018
+ if (Math.abs(up[1]) < 0.7 && Math.abs(rotateVec(p.q, axis2)[1]) < 0.7) return 1;
25019
+ const half = p.dims[along] / 2;
25020
+ const share = clamp2((half - sign2 * local2[along]) / Math.max(p.dims[along], 1e-6), 0, 1);
25021
+ return (above2 + p.st.mass * share) / load;
25022
+ };
25023
+ };
25024
+ const borneOn = (p, supports) => {
25025
+ if (supports.length === 0) return void 0;
25026
+ const boxes = supports.map((support) => contactBox(p, support));
25027
+ return (local2, along) => boxes.some(([lo, hi]) => local2[along] >= lo[along] - SUPPORT_TOLERANCE && local2[along] <= hi[along] + SUPPORT_TOLERANCE);
25028
+ };
24976
25029
  const measureContact = (p, support) => {
24977
25030
  const A = aabbOf(p.spec.shape, p.pos, p.q), B = aabbOf(support.spec.shape, support.pos, support.q);
24978
25031
  const lo = [0, 0, 0], hi = [0, 0, 0];
@@ -25180,7 +25233,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
25180
25233
  o.unsup[i] = o.anyAnchor && !isLost(p) && !p.orphan;
25181
25234
  continue;
25182
25235
  }
25183
- p.st.stress = p.st.load * structureSafety / (p.cap * capacityScale(p));
25236
+ p.st.stress = p.st.load * structureSafety / (p.cap * capacityScale(p, borneOn(p, (lowerOf.get(i) ?? []).map((k) => parts[k])), throughOf(p)));
25184
25237
  if (p.bend) {
25185
25238
  p.bendLoad = p.st.mass + bending[i];
25186
25239
  const bent = restFlexure(o, p, lowerOf.get(i) ?? []);
@@ -26165,7 +26218,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26165
26218
  return BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3) * clamp2(Math.cbrt(BLAST_REFERENCE_RESISTANCE / resistance), 0.3, 2);
26166
26219
  };
26167
26220
  const blastUnits = (o, p, wp, energy, dist2, src) => {
26168
- var _a, _b;
26221
+ var _a;
26169
26222
  if (!p.staged || p.st.stripped || isLost(p) || chipEnergy <= 0) return false;
26170
26223
  const reach = blastReachOf(p, energy);
26171
26224
  if (dist2 >= reach) return false;
@@ -26195,6 +26248,62 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26195
26248
  }
26196
26249
  }
26197
26250
  if (out.length === 0) return false;
26251
+ return knockOutUnits(o, p, wp, energy, out, src);
26252
+ };
26253
+ const blastPanel = (o, p, point, energy, src) => {
26254
+ var _a;
26255
+ if (!p.staged || p.st.stripped || isLost(p) || !p.spec.units || p.spec.units.mortar === p.spec.material || p.spec.reinforcement) return false;
26256
+ const [u, v] = planeAxes(p.thin);
26257
+ const lp = toLocal(p.pos, p.q, objLocal(o, point));
26258
+ const half = p.dims[u] / 2;
26259
+ const posts = [];
26260
+ for (const m of o.parts) {
26261
+ if (m === p || !m.spec.reinforcement || isLost(m) || m.spec.shape.kind !== "box") continue;
26262
+ const mp = toLocal(p.pos, p.q, m.pos);
26263
+ if (Math.abs(mp[p.thin]) > p.dims[p.thin] + 0.15 || Math.abs(mp[u]) > half + 0.15 || m.dims[v] < p.dims[v] * 0.5) continue;
26264
+ posts.push(mp[u]);
26265
+ }
26266
+ let from = -half, to = half;
26267
+ for (const x of posts) {
26268
+ if (x <= lp[u] && x > from) from = x;
26269
+ if (x >= lp[u] && x < to) to = x;
26270
+ }
26271
+ if (to - from < 0.2) return false;
26272
+ const tnt = energy * DEFAULT_BLAST_IMPULSE.tntPerJoule;
26273
+ const centre = objLocal(o, point);
26274
+ const span = to - from, height = p.dims[v];
26275
+ let loaded = 0;
26276
+ for (const [fu, fv] of PANEL_POINTS) {
26277
+ const at4 = [0, 0, 0];
26278
+ at4[u] = (from + to) / 2 + fu * span;
26279
+ at4[v] = fv * height;
26280
+ at4[p.thin] = Math.sign(lp[p.thin]) * p.dims[p.thin] / 2;
26281
+ const r = vec.distance(toWorld(p.pos, p.q, at4), centre);
26282
+ const side = sideOnOverpressure(tnt, r);
26283
+ const reflected = 2 * side + 6 * side * side / (side + 7 * 101325);
26284
+ const impulse = bodyImpulse(tnt, r);
26285
+ if (reflected > PANEL_PRESSURE && impulse > PANEL_IMPULSE && (reflected - PANEL_PRESSURE) * (impulse - PANEL_IMPULSE) >= PANEL_PI) loaded++;
26286
+ }
26287
+ if (loaded < PANEL_POINTS_LOADED) return false;
26288
+ const grid = gridOf(p);
26289
+ const worn = (_a = p.rt).chips ?? (_a.chips = {});
26290
+ const out = [];
26291
+ for (let i = 0; i < grid.length; i++) {
26292
+ const cell = grid[i];
26293
+ if (worn[i] === -1) continue;
26294
+ if (cell.center[u] - cell.size[u] / 2 >= from - 1e-6 && cell.center[u] + cell.size[u] / 2 <= to + 1e-6) out.push(i);
26295
+ }
26296
+ if (out.length === 0) return false;
26297
+ for (const i of out) worn[i] = -1;
26298
+ return knockOutUnits(o, p, point, energy, out, src);
26299
+ };
26300
+ const knockOutUnits = (o, p, wp, energy, out, src) => {
26301
+ var _a, _b;
26302
+ const [u, v] = planeAxes(p.thin);
26303
+ const op = p.st.opening ? toLocal(p.pos, p.q, p.st.opening.center) : null;
26304
+ const grid = gridOf(p);
26305
+ const worn = (_a = p.rt).chips ?? (_a.chips = {});
26306
+ for (const i of out) worn[i] = -1;
26198
26307
  const loose = unsupportedCells(grid, p.thin, p.dims, (i) => worn[i] !== -1 && !(op && p.st.opening && Math.hypot(grid[i].center[u] - op[u], grid[i].center[v] - op[v]) <= p.st.opening.radius));
26199
26308
  for (const i of loose) worn[i] = -1;
26200
26309
  const blown = out.map((i) => grid[i]), fallen = loose.map((i) => grid[i]);
@@ -26270,6 +26379,27 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26270
26379
  debris2(o, p, p.mat.breakDebris, center, [0, -1, 0], 6, 1, src);
26271
26380
  return loose.length;
26272
26381
  };
26382
+ const giveAtCut = (o, p, src) => {
26383
+ if (!p.spec.reinforcement || !p.spec.units || !p.st.chipped?.length || sectionLoss(p) <= 0) return false;
26384
+ const opened = [];
26385
+ for (const j of o.byPart.get(p.spec.id) ?? []) {
26386
+ if (j.st.open) continue;
26387
+ const onIt = j.bears === "a_on_b" && j.spec.b === p.spec.id || j.bears === "b_on_a" && j.spec.a === p.spec.id;
26388
+ if (!onIt) continue;
26389
+ j.st.open = true;
26390
+ j.st.openedBy = "break";
26391
+ opened.push(j);
26392
+ }
26393
+ if (opened.length === 0) return false;
26394
+ p.st.hp = Math.max(p.st.hp, p.st.maxHp * GIVE_AT_CUT_HP);
26395
+ markDamaged(p);
26396
+ solveStructure(o);
26397
+ recomputeGroups(o);
26398
+ detachEvents(o, opened, "break", src);
26399
+ exposeRebar(o, p, src);
26400
+ collapseCheck(o, src);
26401
+ return true;
26402
+ };
26273
26403
  const stripPart = (o, p, reinforcement, src) => {
26274
26404
  const bars = rebarBars(p.dims, p.thin, reinforcement.spacing);
26275
26405
  p.st.stripped = true;
@@ -26327,6 +26457,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26327
26457
  hingeDrop(o, p, src);
26328
26458
  return;
26329
26459
  }
26460
+ if (!force && giveAtCut(o, p, src)) return;
26330
26461
  const ex = p.spec.explodes;
26331
26462
  const style = force ?? (p.snap ? "snap" : p.mat.fracture === "none" ? "snap" : p.mat.fracture);
26332
26463
  const { c, q } = partXf(o, p);
@@ -26655,12 +26786,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26655
26786
  return reach;
26656
26787
  }
26657
26788
  if (Ein > 20 && p.layers.length > 0) spallOuter(o, p, wp, faceOf(o, p, wn), wn, clamp2(0.05 + Math.sqrt(Ein) * 2e-3, 0.05, 0.4), src);
26658
- const dealt = applyDamage(o, p, amount, "explosive", point, null, Ein * 0.3, 40, src);
26789
+ const breachReach = BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3);
26790
+ const farMember = Boolean(p.spec.reinforcement && p.spec.units) && dist2 > MEMBER_CUT_REACH * breachReach;
26791
+ const dealt = farMember ? applyDamage(o, p, Math.min(amount, Math.max(0, p.st.hp - p.st.maxHp * FAR_MEMBER_HP_FLOOR)), "explosive", null, null, Ein * 0.3, 40, src) : applyDamage(o, p, amount, "explosive", point, null, Ein * 0.3, 40, src);
26659
26792
  res.damage += dealt;
26660
26793
  if (p.bend && flexure.enabled) bendByBlast(o, p, point, energy, radius, reach, src);
26661
- const breachReach = BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3);
26662
- if (p.spec.units && p.spec.units.mortar !== p.spec.material) blastUnits(o, p, wp, energy, dist2, src);
26663
- else if (p.spec.reinforcement && p.spec.units && dist2 > MEMBER_CUT_REACH * breachReach) blastUnits(o, p, wp, energy, dist2, src);
26794
+ if (p.spec.units && p.spec.units.mortar !== p.spec.material) {
26795
+ blastPanel(o, p, point, energy, src);
26796
+ if (!isLost(p)) blastUnits(o, p, wp, energy, dist2, src);
26797
+ } else if (farMember) blastUnits(o, p, wp, energy, dist2, src);
26664
26798
  else if (dist2 <= breachReach) addBreach(o, p, wp, breachAreaOf(p, dealt, true), Ein, null, src);
26665
26799
  return reach;
26666
26800
  };
@@ -26673,7 +26807,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
26673
26807
  const dx = local2[0] - p.pos[0];
26674
26808
  const dy = local2[1] - p.pos[1];
26675
26809
  const dz = local2[2] - p.pos[2];
26676
- if (dx * dx + dy * dy + dz * dz < reach * reach) near.push(p);
26810
+ if (dx * dx + dy * dy + dz * dz >= reach * reach) continue;
26811
+ if (p.spec.anchored && p.spec.structure?.role === "foundation" && distToPart(o, p, point) > BURIED_BLAST_REACH) continue;
26812
+ near.push(p);
26677
26813
  }
26678
26814
  blastProbe.partsTested += o.parts.length;
26679
26815
  blastProbe.partsNear += near.length;
@@ -28769,27 +28905,27 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28769
28905
  });
28770
28906
  return changed ? { parts, supports: input.supports } : input;
28771
28907
  }
28772
- function supportBondBeam(context, plate2) {
28908
+ function supportBondBeam(context, plate3) {
28773
28909
  const { options } = context;
28774
- const dir = plate2.aabb[2] - plate2.aabb[0] >= plate2.aabb[3] - plate2.aabb[1] ? "u" : "v";
28775
- const line = lineOf(plate2.aabb, dir);
28776
- const width = dir === "u" ? plate2.aabb[3] - plate2.aabb[1] : plate2.aabb[2] - plate2.aabb[0];
28910
+ const dir = plate3.aabb[2] - plate3.aabb[0] >= plate3.aabb[3] - plate3.aabb[1] ? "u" : "v";
28911
+ const line = lineOf(plate3.aabb, dir);
28912
+ const width = dir === "u" ? plate3.aabb[3] - plate3.aabb[1] : plate3.aabb[2] - plate3.aabb[0];
28777
28913
  const dist2 = distancesOf(context);
28778
- const floor2 = plate2.floor;
28779
- const props = propsUnder(context, dist2, plate2.y0, plate2.y1, floor2);
28914
+ const floor2 = plate3.floor;
28915
+ const props = propsUnder(context, dist2, plate3.y0, plate3.y1, floor2);
28780
28916
  const storey = { floor: floor2, below: floor2 >= 1 ? `slab_${floor2}` : void 0, bottom: context.structure.levels[floor2] ?? 0 };
28781
28917
  const spots = [];
28782
28918
  const near = props.length ? Math.min(...props.map((p) => p.dist)) : pillarDist(context, dist2, storey);
28783
28919
  const held = pillarsFor(line, width, props, spots, near, options, false);
28784
28920
  const span = beamSpan(line.to - line.from, held).span;
28785
28921
  if (span > 1.5) {
28786
- const depth = Math.max(plate2.y1 - plate2.y0, beamDepthFor(Math.min(span, options.maxSpan), options));
28787
- plate2.y0 = round2(plate2.y1 - depth);
28788
- plate2.mass = Math.max(1, Math.round((plate2.aabb[2] - plate2.aabb[0]) * (plate2.aabb[3] - plate2.aabb[1]) * depth * densityOf(plate2.material)));
28922
+ const depth = Math.max(plate3.y1 - plate3.y0, beamDepthFor(Math.min(span, options.maxSpan), options));
28923
+ plate3.y0 = round2(plate3.y1 - depth);
28924
+ plate3.mass = Math.max(1, Math.round((plate3.aabb[2] - plate3.aabb[0]) * (plate3.aabb[3] - plate3.aabb[1]) * depth * densityOf(plate3.material)));
28789
28925
  }
28790
28926
  for (const spot of spots) {
28791
- const pillar = addPillar(context, spot, storey.bottom, plate2.y0 + PLAN_TOLERANCE, floor2, storey.below, plate2.id);
28792
- rest(context, pillar, plate2, "rebar");
28927
+ const pillar = addPillar(context, spot, storey.bottom, plate3.y0 + PLAN_TOLERANCE, floor2, storey.below, plate3.id);
28928
+ rest(context, pillar, plate3, "rebar");
28793
28929
  }
28794
28930
  }
28795
28931
  function applySlabPanels(input, structure, options) {
@@ -29693,7 +29829,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29693
29829
  const tributary = bay[0] * bay[1];
29694
29830
  const load = COLUMN_SHARE * tributary * storeys * (o.superimposed + slab * 2500);
29695
29831
  const columnSize = o.columnSize ?? Math.max(TOWER_DEFAULTS.columnSize, round23(ceilTo2(Math.sqrt(load / COLUMN_KG_M2), 0.1)));
29696
- const plate2 = [round23(span[0] + columnSize + 0.2), round23(span[1] + columnSize + 0.2)];
29832
+ const plate3 = [round23(span[0] + columnSize + 0.2), round23(span[1] + columnSize + 0.2)];
29697
29833
  const mech = o.mechanicalEvery === false ? void 0 : o.mechanicalEvery;
29698
29834
  const relays = o.mechanical === false ? [] : mechanicalStoreys(storeys, o.mechanical === void 0 ? mech : o.mechanical.every ?? mech);
29699
29835
  const mechanical = o.mechanical === false ? [] : [...relays, storeys - 1];
@@ -29707,11 +29843,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29707
29843
  const shaft = given2.shaft ?? CORE_DEFAULTS.shaft;
29708
29844
  const fit = Math.max(1, Math.floor((bay[1] - 2 * CORE_CLEARANCE - 0.2 - 2 * wallThickness + ti) / (shaft + ti)));
29709
29845
  const probe = coreSize({ ...given2, wallThickness, elevators: 2 });
29710
- const wanted = given2.elevators ?? Math.max(2, Math.ceil((o.coreRatio * plate2[0] * plate2[1] / probe[0] - 2 * wallThickness + ti) / (shaft + ti)));
29846
+ const wanted = given2.elevators ?? Math.max(2, Math.ceil((o.coreRatio * plate3[0] * plate3[1] / probe[0] - 2 * wallThickness + ti) / (shaft + ti)));
29711
29847
  const elevators = Math.max(1, Math.min(wanted, fit));
29712
29848
  const narrow = coreSize({ ...given2, wallThickness, elevators });
29713
29849
  const room = bay[0] - columnSize - 2 * CORE_CLEARANCE - narrow[0];
29714
- const extra = given2.shaftDepth !== void 0 ? 0 : Math.max(0, Math.min(room, o.coreRatio * plate2[0] * plate2[1] / narrow[1] - narrow[0]));
29850
+ const extra = given2.shaftDepth !== void 0 ? 0 : Math.max(0, Math.min(room, o.coreRatio * plate3[0] * plate3[1] / narrow[1] - narrow[0]));
29715
29851
  const xs = Array.from({ length: bays[0] + 1 }, (_, i) => -span[0] / 2 + i * bay[0]);
29716
29852
  const middle = Math.floor(bays[0] / 2);
29717
29853
  const center = given2.center ?? [bays[0] % 2 === 1 ? (xs[middle] + xs[middle + 1]) / 2 : xs[middle] + bay[0] / 2, 0];
@@ -29755,9 +29891,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29755
29891
  columnsZ: bays[1] + 1,
29756
29892
  columnSize,
29757
29893
  beamHeight,
29758
- plate: plate2,
29894
+ plate: plate3,
29759
29895
  core: coreLayout,
29760
- coreRatio: coreLayout ? coreLayout.size[0] * coreLayout.size[1] / (plate2[0] * plate2[1]) : 0,
29896
+ coreRatio: coreLayout ? coreLayout.size[0] * coreLayout.size[1] / (plate3[0] * plate3[1]) : 0,
29761
29897
  facade: o.facade,
29762
29898
  mechanical,
29763
29899
  damper: damperOn,
@@ -29815,7 +29951,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29815
29951
  }
29816
29952
  var storeyKinds = (layout) => Array.from({ length: layout.storeys }, (_, f) => f === 0 ? "ground" : layout.mechanical.includes(f) ? "mechanical" : "typical");
29817
29953
  var EDGE = 1e-6;
29818
- function exteriorWindows(id, rect, plate2, ceiling, o = {}) {
29954
+ function exteriorWindows(id, rect, plate3, ceiling, o = {}) {
29819
29955
  const [u0, v0, u1, v1] = rect;
29820
29956
  const spacing = o.spacing ?? 3;
29821
29957
  const out = [];
@@ -29824,9 +29960,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29824
29960
  out.push({ room: id, side, n, width: Math.min(o.width ?? 2.4, length2 / n * 0.8), y0: o.y0 ?? 0.3, y1: o.y1 ?? r2(ceiling - 0.5) });
29825
29961
  };
29826
29962
  if (Math.abs(v0) < EDGE) add2("front", u1 - u0);
29827
- if (Math.abs(v1 - plate2.d) < EDGE) add2("back", u1 - u0);
29963
+ if (Math.abs(v1 - plate3.d) < EDGE) add2("back", u1 - u0);
29828
29964
  if (Math.abs(u0) < EDGE) add2("left", v1 - v0);
29829
- if (Math.abs(u1 - plate2.w) < EDGE) add2("right", v1 - v0);
29965
+ if (Math.abs(u1 - plate3.w) < EDGE) add2("right", v1 - v0);
29830
29966
  return out;
29831
29967
  }
29832
29968
  var stripDoor = (id, strip, floor2, width = 1) => ({ a: id, b: `${strip.circulation}_${floor2}`, width, opensTo: id });
@@ -29834,33 +29970,33 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29834
29970
  const id = `plant_${floor2}_${strip.id}`;
29835
29971
  return { rooms: [{ id, type: "storage", label: "plant_room", rect: [...strip.rect] }], doors: [stripDoor(id, strip, floor2, 1.2)], windows: [] };
29836
29972
  };
29837
- function coreRooms(plate2, floor2, storeys) {
29973
+ function coreRooms(plate3, floor2, storeys) {
29838
29974
  const id = (name) => `${name}_${floor2}`;
29839
29975
  const link = floor2 < storeys - 1 ? [floor2, floor2 + 1] : [floor2 - 1, floor2];
29840
29976
  const rooms = [
29841
- { id: id("stairs"), type: "stairs", label: "stairs", rect: [...plate2.stairs], link },
29842
- ...plate2.service ? [{ id: id("service"), type: "storage", label: "service_shaft", rect: [...plate2.service] }] : [],
29843
- ...plate2.shafts.map((rect, k) => ({ id: id(`elevator_${k}`), type: "elevator", label: "elevator", rect: [...rect] })),
29844
- { id: id("lobby"), type: "hall", label: "elevator_lobby", rect: [...plate2.lobby] },
29845
- { id: id("corridor_w"), type: "corridor", label: "corridor", rect: [...plate2.corridors.w] },
29846
- { id: id("corridor_s"), type: "corridor", label: "corridor", rect: [...plate2.corridors.s] },
29847
- { id: id("corridor_n"), type: "corridor", label: "corridor", rect: [...plate2.corridors.n] }
29977
+ { id: id("stairs"), type: "stairs", label: "stairs", rect: [...plate3.stairs], link },
29978
+ ...plate3.service ? [{ id: id("service"), type: "storage", label: "service_shaft", rect: [...plate3.service] }] : [],
29979
+ ...plate3.shafts.map((rect, k) => ({ id: id(`elevator_${k}`), type: "elevator", label: "elevator", rect: [...rect] })),
29980
+ { id: id("lobby"), type: "hall", label: "elevator_lobby", rect: [...plate3.lobby] },
29981
+ { id: id("corridor_w"), type: "corridor", label: "corridor", rect: [...plate3.corridors.w] },
29982
+ { id: id("corridor_s"), type: "corridor", label: "corridor", rect: [...plate3.corridors.s] },
29983
+ { id: id("corridor_n"), type: "corridor", label: "corridor", rect: [...plate3.corridors.n] }
29848
29984
  ];
29849
29985
  const doors = [
29850
29986
  { a: id("stairs"), b: id("corridor_w"), width: 1, opensTo: id("corridor_w") },
29851
- ...plate2.service ? [{ a: id("service"), b: id("corridor_w"), width: 0.8, opensTo: id("service") }] : [],
29852
- ...plate2.shafts.map((_, k) => ({ a: id(`elevator_${k}`), b: id("lobby"), width: 1.2, opensTo: id("lobby") }))
29987
+ ...plate3.service ? [{ a: id("service"), b: id("corridor_w"), width: 0.8, opensTo: id("service") }] : [],
29988
+ ...plate3.shafts.map((_, k) => ({ a: id(`elevator_${k}`), b: id("lobby"), width: 1.2, opensTo: id("lobby") }))
29853
29989
  ];
29854
29990
  const openPairs = [[id("lobby"), id("corridor_s")], [id("lobby"), id("corridor_n")], [id("corridor_w"), id("corridor_s")], [id("corridor_w"), id("corridor_n")]];
29855
29991
  return { rooms, doors, openPairs };
29856
29992
  }
29857
29993
  function towerFloors(layout, plan) {
29858
- const plate2 = towerPlate(layout, plan);
29994
+ const plate3 = towerPlate(layout, plan);
29859
29995
  const fillers = { ground: plan.ground ?? plan.typical, typical: plan.typical, mechanical: plan.mechanical ?? plantRooms };
29860
29996
  return storeyKinds(layout).map((kind, floor2) => {
29861
- const context = { floor: floor2, kind, layout, plate: plate2, ceiling: layout.pitch };
29862
- const fills = plate2.strips.map((strip) => fillers[kind](strip, context));
29863
- const core = coreRooms(plate2, floor2, layout.storeys);
29997
+ const context = { floor: floor2, kind, layout, plate: plate3, ceiling: layout.pitch };
29998
+ const fills = plate3.strips.map((strip) => fillers[kind](strip, context));
29999
+ const core = coreRooms(plate3, floor2, layout.storeys);
29864
30000
  return {
29865
30001
  label: kind === "ground" ? "ground_floor" : kind === "mechanical" ? "mechanical_floor" : "typical_floor",
29866
30002
  ceiling: layout.pitch,
@@ -29873,7 +30009,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29873
30009
  }
29874
30010
  var towerLocales = { en: { labels: en_default.labels }, "pt-BR": { labels: pt_BR_default.labels } };
29875
30011
 
29876
- // ../game-floorplan-three/dist/chunk-JZQA7G63.js
30012
+ // ../game-floorplan-three/dist/chunk-PJ4WEP6U.js
29877
30013
  var __defProp3 = Object.defineProperty;
29878
30014
  var __defNormalProp2 = (obj, key2, value) => key2 in obj ? __defProp3(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
29879
30015
  var __publicField2 = (obj, key2, value) => __defNormalProp2(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
@@ -29938,7 +30074,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29938
30074
  var OPEN_ROOM_TYPES2 = /* @__PURE__ */ new Set(["balcony", "terrace", "veranda", "balcony_gourmet"]);
29939
30075
  var rectsOf = (c) => c.parts && c.parts.length ? c.parts : [[c.u0, c.v0, c.u1, c.v1]];
29940
30076
  var isOpenArea = (c) => OPEN_ROOM_TYPES2.has(c.type) || c.outdoor === true;
29941
- function installKernelGeometry(K, shared2) {
30077
+ function installKernelGeometry(K, shared3) {
29942
30078
  const { THREE } = K;
29943
30079
  const GEO = {};
29944
30080
  {
@@ -30011,9 +30147,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30011
30147
  const cursor = { group: "lot", accs: /* @__PURE__ */ new Map(), rot: [], org: [0, 0, 0], ry: 0 };
30012
30148
  const PARTS = [];
30013
30149
  const MIRRORS = [];
30014
- shared2.partCount = 0;
30150
+ shared3.partCount = 0;
30015
30151
  function part(type, pos, fn, meta = {}, parent, ry = 0) {
30016
- const gA = cursor.group, oA = cursor.org, rA = cursor.ry, pieceA = cursor.pc, name = "part:" + (meta.id || type) + ":" + shared2.partCount++;
30152
+ const gA = cursor.group, oA = cursor.org, rA = cursor.ry, pieceA = cursor.pc, name = "part:" + (meta.id || type) + ":" + shared3.partCount++;
30017
30153
  PARTS.push({ name, parent: parent || gA, pos: pos.slice(), type, meta, ry });
30018
30154
  cursor.group = name;
30019
30155
  cursor.org = pos;
@@ -30049,7 +30185,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30049
30185
  }
30050
30186
  const _Y = new THREE.Vector3(0, 1, 0), _qa = new THREE.Quaternion(), _qb = new THREE.Quaternion();
30051
30187
  function pieceRecord(id, mat, role, extra) {
30052
- const M = shared2.ctx.pieces;
30188
+ const M = shared3.ctx.pieces;
30053
30189
  let p = M.get(id);
30054
30190
  if (!p) {
30055
30191
  p = Object.assign({ id, mat, role: role || null }, extra);
@@ -30058,7 +30194,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30058
30194
  return p;
30059
30195
  }
30060
30196
  const structurePiece = (id) => {
30061
- const e = shared2.ctx.structureIndex && shared2.ctx.structureIndex[id];
30197
+ const e = shared3.ctx.structureIndex && shared3.ctx.structureIndex[id];
30062
30198
  return e ? pieceRecord(id, e.material, e.role, { floor: e.floor }) : null;
30063
30199
  };
30064
30200
  function accFor(mat) {
@@ -30516,14 +30652,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30516
30652
  const defined = { createMaterials: createMaterials2, antiTile, dirtMaterial, CLOTHES_UNIFORMS, clothesMaterial, ORDER: ORDER2, NO_SHADOW };
30517
30653
  Object.assign(K, defined);
30518
30654
  }
30519
- function installKernelCloseScene(K, shared2) {
30655
+ function installKernelCloseScene(K, shared3) {
30520
30656
  const { THREE, NO_SHADOW, ORDER: ORDER2, PARTS, applyPart, cursor } = K;
30521
30657
  const assembleCars = (...a) => K.assembleCars(...a);
30522
30658
  const assembleMirrors = (...a) => K.assembleMirrors(...a);
30523
30659
  const assembleVegetation = (...a) => K.assembleVegetation(...a);
30524
30660
  function markMesh(m, A) {
30525
30661
  const L = A.lim, fx = [];
30526
- const pieces = shared2.ctx.pieces;
30662
+ const pieces = shared3.ctx.pieces;
30527
30663
  for (let k = 0; k < L.length; k++) {
30528
30664
  const lim = L[k], pc = lim.pc;
30529
30665
  if (!pc) continue;
@@ -30585,7 +30721,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30585
30721
  if (P.meta.t0) applyPart(g, P.meta.t0);
30586
30722
  }
30587
30723
  (groups[P.parent] || (groups[P.parent] = new THREE.Group())).add(g);
30588
- if (P.meta.id) (shared2.ctx.parts || (shared2.ctx.parts = {}))[P.meta.id] = g;
30724
+ if (P.meta.id) (shared3.ctx.parts || (shared3.ctx.parts = {}))[P.meta.id] = g;
30589
30725
  }
30590
30726
  PARTS.length = 0;
30591
30727
  assembleMirrors(groups);
@@ -30596,20 +30732,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30596
30732
  const defined = { markMesh, closeScene };
30597
30733
  Object.assign(K, defined);
30598
30734
  }
30599
- function installHouseHelpers(K, shared2) {
30600
- shared2.ctx = {};
30735
+ function installHouseHelpers(K, shared3) {
30736
+ shared3.ctx = {};
30601
30737
  const OPEN_ROOM_TYPES22 = /* @__PURE__ */ new Set(["balcony", "terrace", "veranda", "balcony_gourmet"]);
30602
30738
  const NO_CEILING = OPEN_ROOM_TYPES22;
30603
30739
  const OPEN_AREA = (c) => OPEN_ROOM_TYPES22.has(c.type) || c.outdoor === true;
30604
30740
  const EPS6 = 1e-3;
30605
30741
  const Y0 = (f) => {
30606
- const A = shared2.ctx.r.floors;
30742
+ const A = shared3.ctx.r.floors;
30607
30743
  return A[Math.max(0, Math.min(A.length - 1, f))].y0;
30608
30744
  };
30609
- const colorOf = (v) => typeof v === "number" ? v : typeof v === "string" && shared2.ctx.colors[v] != null ? shared2.ctx.colors[v] : null;
30745
+ const colorOf = (v) => typeof v === "number" ? v : typeof v === "string" && shared3.ctx.colors[v] != null ? shared3.ctx.colors[v] : null;
30610
30746
  const rectsOf2 = (c) => c.parts && c.parts.length ? c.parts : [[c.u0, c.v0, c.u1, c.v1]];
30611
30747
  function roomAt(f, u, v) {
30612
- for (const c of shared2.ctx.r.rooms) if (c.floor === f) {
30748
+ for (const c of shared3.ctx.r.rooms) if (c.floor === f) {
30613
30749
  for (const [a, b, c2, d] of rectsOf2(c)) if (u > a + EPS6 && u < c2 - EPS6 && v > b + EPS6 && v < d - EPS6) return c;
30614
30750
  }
30615
30751
  return null;
@@ -30643,7 +30779,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30643
30779
  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]))];
30644
30780
  }
30645
30781
  function effectiveHeight(f, h) {
30646
- const A = shared2.ctx.r.floors;
30782
+ const A = shared3.ctx.r.floors;
30647
30783
  if (f + 1 >= A.length) return h;
30648
30784
  const pitch = A[f + 1].y0 - A[f].y0;
30649
30785
  return h > pitch && h - pitch <= 0.45 ? pitch : h;
@@ -30651,7 +30787,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30651
30787
  const defined = { OPEN_ROOM_TYPES: OPEN_ROOM_TYPES22, NO_CEILING, OPEN_AREA, EPS: EPS6, Y0, colorOf, rectsOf: rectsOf2, roomAt, subRect, subRects, wallColor, floorColor, stairFootprint, effectiveHeight };
30652
30788
  Object.assign(K, defined);
30653
30789
  }
30654
- function installHouseWalls(K, shared2) {
30790
+ function installHouseWalls(K, shared3) {
30655
30791
  const { EPS: EPS6, Y0, boxC, bx, cursor, effectiveHeight, pieceRecord, structurePiece, wallColor } = K;
30656
30792
  const sh = (...a) => K.sh(...a);
30657
30793
  function wallBox(alongU, L, a, b, ya, yb, th, cL, cH, mL, mH) {
@@ -30665,10 +30801,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30665
30801
  }
30666
30802
  }
30667
30803
  function sideOf(id, frontLine) {
30668
- const R = shared2.ctx.r, F = R.facade;
30669
- if (id === "outside" || !shared2.ctx.roomById[id]) {
30804
+ const R = shared3.ctx.r, F = R.facade;
30805
+ if (id === "outside" || !shared3.ctx.roomById[id]) {
30670
30806
  const ac = F.finish;
30671
- let mat = "plaster", color2 = shared2.ctx.colors.facade;
30807
+ let mat = "plaster", color2 = shared3.ctx.colors.facade;
30672
30808
  if (ac === "roughcast") mat = "roughcast";
30673
30809
  else if (ac === "exposed_block") {
30674
30810
  mat = "block";
@@ -30679,12 +30815,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30679
30815
  }
30680
30816
  return { color: color2, mat, exterior: true };
30681
30817
  }
30682
- return { color: wallColor(shared2.ctx.roomById[id]), mat: "plaster", exterior: false };
30818
+ return { color: wallColor(shared3.ctx.roomById[id]), mat: "plaster", exterior: false };
30683
30819
  }
30684
30820
  const pieceOf = (w) => !w.id ? null : structurePiece(w.id) || pieceRecord(w.id, w.material || "brick", w.role || "partition", { floor: w.floor });
30685
30821
  function nearestWall(f, axis2, L, c) {
30686
30822
  let m = null, md = 1e9;
30687
- for (const w of shared2.ctx.r.walls) {
30823
+ for (const w of shared3.ctx.r.walls) {
30688
30824
  if (w.floor !== f || w.axis !== axis2 || w.type !== "wall" || Math.abs((axis2 === "u" ? w.v0 : w.u0) - L) > EPS6) continue;
30689
30825
  const a = Math.min(axis2 === "u" ? w.u0 : w.v0, axis2 === "u" ? w.u1 : w.v1), b = Math.max(axis2 === "u" ? w.u0 : w.v0, axis2 === "u" ? w.u1 : w.v1), d = c < a ? a - c : c > b ? c - b : 0;
30690
30826
  if (d < md) {
@@ -30695,11 +30831,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30695
30831
  return m;
30696
30832
  }
30697
30833
  function walls() {
30698
- 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)));
30834
+ const R = shared3.ctx.r, cut = shared3.ctx.cut, nA = R.floors.length, vMin = Math.min(...R.walls.map((w) => w.axis === "u" ? w.v0 : Math.min(w.v0, w.v1)));
30699
30835
  const corners = /* @__PURE__ */ new Map();
30700
30836
  const looks = /* @__PURE__ */ new Map();
30701
30837
  for (const w of R.walls) {
30702
- const f = w.floor, colliders = shared2.ctx.colliders;
30838
+ const f = w.floor, colliders = shared3.ctx.colliders;
30703
30839
  cursor.group = "f" + f;
30704
30840
  cursor.pc = pieceOf(w);
30705
30841
  const y0 = Y0(f), pitch = f + 1 < nA ? Y0(f + 1) - y0 : Infinity, th = w.thickness || 0.15, alongU = w.axis === "u";
@@ -30713,7 +30849,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30713
30849
  }
30714
30850
  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 });
30715
30851
  if (w.type === "railing") {
30716
- const c0 = shared2.ctx.colors.metal != null ? shared2.ctx.colors.metal : 9080466;
30852
+ const c0 = shared3.ctx.colors.metal != null ? shared3.ctx.colors.metal : 9080466;
30717
30853
  const sx = alongU ? 1 : 0, sz = alongU ? 0 : 1, len = s1 - s0, n = Math.max(1, Math.round(len / 1.4));
30718
30854
  const cx_ = alongU ? (s0 + s1) / 2 : L, cz_ = alongU ? L : (s0 + s1) / 2;
30719
30855
  boxC("glass", cx_, y0 + 0.55, cz_, alongU ? len : 0.02, 0.85, alongU ? 0.02 : len, 16777215);
@@ -30757,7 +30893,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30757
30893
  cursor.group = "f" + e.f;
30758
30894
  bx(e.color.mat, e.pu - e.th / 2, e.y0, e.pv - e.th / 2, e.pu + e.th / 2, e.y0 + e.hh, e.pv + e.th / 2, e.color.color);
30759
30895
  }
30760
- if (shared2.ctx.showPillars) wallPillars(looks);
30896
+ if (shared3.ctx.showPillars) wallPillars(looks);
30761
30897
  }
30762
30898
  const PILLAR_IN_WALL = /^(wall_column_|column_\d|jamb_column_)/;
30763
30899
  const wallOf = (pillar, parts) => {
@@ -30765,7 +30901,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30765
30901
  return parts.find((q) => (q.role === "wall" || q.role === "partition") && q.assembly !== void 0 && q.floor === pillar.floor && u >= q.aabb[0] - 1e-3 && u <= q.aabb[2] + 1e-3 && v >= q.aabb[1] - 1e-3 && v <= q.aabb[3] + 1e-3);
30766
30902
  };
30767
30903
  function wallPillars(looks) {
30768
- const parts = Object.values(shared2.ctx.structureIndex);
30904
+ const parts = Object.values(shared3.ctx.structureIndex);
30769
30905
  for (const e of parts) {
30770
30906
  if (e.role !== "column" || !PILLAR_IN_WALL.test(e.id)) continue;
30771
30907
  const host = wallOf(e, parts);
@@ -30780,7 +30916,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30780
30916
  const defined = { wallBox, sideOf, pieceOf, nearestWall, walls, wallPillars };
30781
30917
  Object.assign(K, defined);
30782
30918
  }
30783
- function installHouseDoors(K, shared2) {
30919
+ function installHouseDoors(K, shared3) {
30784
30920
  const seedKey = (id) => K.seedKey(id);
30785
30921
  const { EPS: EPS6, Y0, boxC, bx, cursor, effectiveHeight, nearestWall, part, pieceOf, pieceRecord, roomAt, sideOf, wallBox } = K;
30786
30922
  const SEED = (...a) => K.SEED(...a);
@@ -30788,15 +30924,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30788
30924
  const rngString = (...a) => K.rngString(...a);
30789
30925
  const sh = (...a) => K.sh(...a);
30790
30926
  function doorLineSides(p) {
30791
- const R = shared2.ctx.r, alongU = p.axis === "u", a = p.at - p.width / 2, b = p.at + p.width / 2;
30927
+ const R = shared3.ctx.r, alongU = p.axis === "u", a = p.at - p.width / 2, b = p.at + p.width / 2;
30792
30928
  const w = R.walls.find((w2) => w2.floor === p.floor && w2.axis === p.axis && Math.abs((alongU ? w2.v0 : w2.u0) - p.pos) < EPS6 && w2.type === "wall" && (Math.abs((alongU ? w2.u1 : w2.v1) - a) < 0.02 || Math.abs((alongU ? w2.u0 : w2.v0) - b) < 0.02));
30793
30929
  const sides = w ? w.sides : [p.a, p.b];
30794
30930
  return [sideOf(sides[0], false), sideOf(sides[1], false)];
30795
30931
  }
30796
- shared2.doorState = /* @__PURE__ */ new Map();
30932
+ shared3.doorState = /* @__PURE__ */ new Map();
30797
30933
  function doors() {
30798
- const leaves = shared2.ctx.leaves = [], doorState = shared2.doorState, colliders = shared2.ctx.colliders;
30799
- 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);
30934
+ const leaves = shared3.ctx.leaves = [], doorState = shared3.doorState, colliders = shared3.ctx.colliders;
30935
+ const R = shared3.ctx.r, cut = shared3.ctx.cut, C = shared3.ctx.colors, wood = C.wood != null ? C.wood : 8016948, frame2 = sh(wood, 0.55);
30800
30936
  for (const p of R.doors) {
30801
30937
  const f = p.floor;
30802
30938
  cursor.group = "f" + f;
@@ -30926,12 +31062,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30926
31062
  const defined = { doorLineSides, doors };
30927
31063
  Object.assign(K, defined);
30928
31064
  }
30929
- function installHouseWindows(K, shared2) {
31065
+ function installHouseWindows(K, shared3) {
30930
31066
  const { EPS: EPS6, Y0, boxC, bx, cursor, pieceRecord, roomAt } = K;
30931
31067
  const FRAME_COLORS = { budget: 15856110, mid: 12830924, high: 2829875, commercial: 11844287 };
30932
31068
  const SILL_COLORS = { budget: 15131870, mid: 14277076, high: 3816770, commercial: 13225166 };
30933
31069
  function windows() {
30934
- 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;
31070
+ const R = shared3.ctx.r, cut = shared3.ctx.cut, C = shared3.ctx.colors, structure = R.style, fr = FRAME_COLORS[structure] || FRAME_COLORS.budget, pe_ = SILL_COLORS[structure] || SILL_COLORS.budget;
30935
31071
  const boardItems = new Set(R.stateItems.filter((e) => e.type === "window_boards" && e.window).map((e) => e.window));
30936
31072
  for (const j of R.windows) {
30937
31073
  const f = j.floor;
@@ -30985,11 +31121,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30985
31121
  const defined = { FRAME_COLORS, SILL_COLORS, windows };
30986
31122
  Object.assign(K, defined);
30987
31123
  }
30988
- function installHouseFloors(K, shared2) {
31124
+ function installHouseFloors(K, shared3) {
30989
31125
  const { rectsOf: rectsOf2, EPS: EPS6, OPEN_AREA, Y0, bx, cursor, floorColor, stairFootprint, structurePiece, subRects } = K;
30990
31126
  function flights() {
30991
- if (shared2.ctx._flights && shared2.ctx._flights.r === shared2.ctx.r) return shared2.ctx._flights.l;
30992
- const R = shared2.ctx.r, mp = /* @__PURE__ */ new Map();
31127
+ if (shared3.ctx._flights && shared3.ctx._flights.r === shared3.ctx.r) return shared3.ctx._flights.l;
31128
+ const R = shared3.ctx.r, mp = /* @__PURE__ */ new Map();
30993
31129
  for (const m of R.items) {
30994
31130
  if (m.type !== "stairs" || !m.link || typeof m.link !== "object") continue;
30995
31131
  const k = [m.link.from, m.link.to, m.x.toFixed(2), m.z.toFixed(2), (m.ry || 0).toFixed(2)].join("|");
@@ -31005,12 +31141,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31005
31141
  v.LP = LP;
31006
31142
  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 });
31007
31143
  }
31008
- shared2.ctx._flights = { r: R, l };
31144
+ shared3.ctx._flights = { r: R, l };
31009
31145
  return l;
31010
31146
  }
31011
31147
  const panelRects = (p) => p.footprint && p.footprint.length ? p.footprint : [p.aabb];
31012
31148
  function tilesOf(parent, rc) {
31013
- const ps = parent ? shared2.ctx.panelsOf && shared2.ctx.panelsOf.get(parent) : void 0;
31149
+ const ps = parent ? shared3.ctx.panelsOf && shared3.ctx.panelsOf.get(parent) : void 0;
31014
31150
  if (!ps) return [[parent ? structurePiece(parent) : null, rc]];
31015
31151
  const out = [], taken = [];
31016
31152
  for (const p of ps) for (const q of panelRects(p)) {
@@ -31024,14 +31160,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31024
31160
  return out;
31025
31161
  }
31026
31162
  function panelAt(parent, x, z) {
31027
- const ps = shared2.ctx.panelsOf && shared2.ctx.panelsOf.get(parent);
31163
+ const ps = shared3.ctx.panelsOf && shared3.ctx.panelsOf.get(parent);
31028
31164
  if (!ps) return structurePiece(parent);
31029
31165
  for (const p of ps) for (const q of panelRects(p)) if (x >= q[0] - EPS6 && x <= q[2] + EPS6 && z >= q[1] - EPS6 && z <= q[3] + EPS6) return structurePiece(p.id);
31030
31166
  return null;
31031
31167
  }
31032
- const hasSlab = (id) => !!(shared2.ctx.structureIndex[id] || shared2.ctx.panelsOf && shared2.ctx.panelsOf.has(id));
31168
+ const hasSlab = (id) => !!(shared3.ctx.structureIndex[id] || shared3.ctx.panelsOf && shared3.ctx.panelsOf.has(id));
31033
31169
  function floorsAndSlabs() {
31034
- const R = shared2.ctx.r, nA = R.floors.length, C = shared2.ctx.colors;
31170
+ const R = shared3.ctx.r, nA = R.floors.length, C = shared3.ctx.colors;
31035
31171
  const V3 = flights(), holes = (f) => V3.filter((v) => v.to === f).flatMap((v) => {
31036
31172
  let rs = [v.rect];
31037
31173
  if (v.top) rs = subRects(rs, [v.top]);
@@ -31068,17 +31204,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31068
31204
  }
31069
31205
  Object.assign(K, { flights, floorsAndSlabs, tilesOf, panelAt });
31070
31206
  }
31071
- function installHouseStairs(K, shared2) {
31207
+ function installHouseStairs(K, shared3) {
31072
31208
  const { rectsOf: rectsOf2, Y0, boxC, bx, cursor, flights, stairFootprint, structurePiece } = K;
31073
31209
  const sh = (...a) => K.sh(...a);
31074
31210
  function buildStairs() {
31075
- const R = shared2.ctx.r, stairs = shared2.ctx.stairs = [];
31211
+ const R = shared3.ctx.r, stairs = shared3.ctx.stairs = [];
31076
31212
  for (const vo of flights()) {
31077
31213
  const m = vo.m, f = vo.from, Dr = m.d - (vo.LP || 0);
31078
31214
  cursor.group = "f" + f;
31079
31215
  cursor.pc = structurePiece("stairs_" + vo.from + "_" + vo.to);
31080
31216
  const y0 = Y0(f), H = Y0(vo.to) - y0, n = Math.max(8, Math.round(H / 0.18)), c = Math.cos(m.ry), s = Math.sin(m.ry);
31081
- const wood = shared2.ctx.colors.wood != null ? shared2.ctx.colors.wood : 9071176, under = sh(wood, 0.7);
31217
+ const wood = shared3.ctx.colors.wood != null ? shared3.ctx.colors.wood : 9071176, under = sh(wood, 0.7);
31082
31218
  const P = (lx, lz) => [m.x + lx * c + lz * s, m.z - lx * s + lz * c];
31083
31219
  const boxL = (mat, lx, y, lz, w, h, d, color2, rx = 0) => {
31084
31220
  const [px, pz] = P(lx, lz);
@@ -31104,12 +31240,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31104
31240
  }
31105
31241
  }
31106
31242
  function elevator() {
31107
- const R = shared2.ctx.r;
31243
+ const R = shared3.ctx.r;
31108
31244
  for (const c of R.rooms.filter((c2) => c2.type === "elevator" && c2.floor === 0)) {
31109
31245
  cursor.group = "f0";
31110
31246
  const [u0, v0, u1, v1] = rectsOf2(c)[0], y0 = Y0(0);
31111
31247
  bx("metal", u0 + 0.15, y0 + 0.05, v0 + 0.15, u1 - 0.15, y0 + 2.3, v1 - 0.15, 10133670);
31112
- 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);
31248
+ bx("emissive", u0 + 0.3, y0 + 2.28, v0 + 0.3, u1 - 0.3, y0 + 2.3, v1 - 0.3, shared3.ctx.night ? 16773320 : 13619924);
31113
31249
  for (const f of R.floors) {
31114
31250
  const yy = Y0(f.index);
31115
31251
  cursor.group = "f" + f.index;
@@ -31120,7 +31256,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31120
31256
  const defined = { buildStairs, elevator };
31121
31257
  Object.assign(K, defined);
31122
31258
  }
31123
- function installLightsFixtures(K, shared2) {
31259
+ function installLightsFixtures(K, shared3) {
31124
31260
  const seedKey = (id) => K.seedKey(id);
31125
31261
  const { cursor, part, polyFace } = K;
31126
31262
  const makeApi = (...a) => K.makeApi(...a);
@@ -31138,9 +31274,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31138
31274
  return ((t ^ t >>> 14) >>> 0) / 4294967296;
31139
31275
  };
31140
31276
  }
31141
- const SEED = () => shared2.ctx.r && shared2.ctx.r.seed || 0;
31142
- const STYLE = () => shared2.ctx.r && shared2.ctx.r.style || "budget";
31143
- shared2.api0 = null;
31277
+ const SEED = () => shared3.ctx.r && shared3.ctx.r.seed || 0;
31278
+ const STYLE = () => shared3.ctx.r && shared3.ctx.r.style || "budget";
31279
+ shared3.api0 = null;
31144
31280
  function kit2(M, A, y0 = M.y || 0) {
31145
31281
  const c = Math.cos(M.ry), s = Math.sin(M.ry);
31146
31282
  let api = A;
@@ -31173,7 +31309,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31173
31309
  return null;
31174
31310
  }
31175
31311
  const a0 = api;
31176
- api = shared2.api0 || (shared2.api0 = makeApi());
31312
+ api = shared3.api0 || (shared3.api0 = makeApi());
31177
31313
  try {
31178
31314
  return part(type, W(lx, ly, lz), fn, meta || {}, void 0, M.ry);
31179
31315
  } finally {
@@ -31267,7 +31403,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31267
31403
  yLight = yc - 0.3;
31268
31404
  range3 = 6.5;
31269
31405
  } else if (type === "chandelier") {
31270
- const yc = t - 0.5, gold = shared2.ctx.colors && shared2.ctx.colors.metal != null ? shared2.ctx.colors.metal : 9075290, N = 6;
31406
+ const yc = t - 0.5, gold = shared3.ctx.colors && shared3.ctx.colors.metal != null ? shared3.ctx.colors.metal : 9075290, N = 6;
31271
31407
  K2.c("metal", 0, yc, 0, 0.012, 0.5, gold);
31272
31408
  K2.e("metal", 0, yc - 0.03, 0, 0.055, 0.08, gold);
31273
31409
  K2.c("metal", 0, yc - 0.06, 0, 0.14, 0.015, gold);
@@ -31346,24 +31482,24 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31346
31482
  const defined = { hashString, rngString, SEED, STYLE, kit2, arcPoints, TEMP_WARM, TEMP_NEUTRAL, TEMP_COOL, colorTemperature, lightStyle, ceilingLamp, tableLamp, floorLamp, sconce, outdoorLamp, lightSwitch };
31347
31483
  Object.assign(K, defined);
31348
31484
  }
31349
- function installLightsDecor(K, shared2) {
31485
+ function installLightsDecor(K, shared3) {
31350
31486
  const { EPS: EPS6, OPEN_AREA, SEED, Y0, cursor, rngString, roomAt, stairFootprint } = K;
31351
31487
  const lightItem = (...a) => K.lightItem(...a);
31352
31488
  function decorLights(api) {
31353
- const R = shared2.ctx.r, T2 = shared2.ctx.types, structure = R.style, chance = structure === "budget" ? 0.35 : structure === "mid" ? 0.75 : 1, rnd2 = rngString(SEED() + "|decorluz");
31489
+ const R = shared3.ctx.r, T2 = shared3.ctx.types, structure = R.style, chance = structure === "budget" ? 0.35 : structure === "mid" ? 0.75 : 1, rnd2 = rngString(SEED() + "|decorluz");
31354
31490
  const itemsF = (f) => R.items.filter((m) => (m.outdoor ? -1 : m.floor) === f && m.type !== "stairs");
31355
31491
  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));
31356
31492
  const free = (f, x, z, margin) => {
31357
31493
  if (!roomAt(f, x, z)) return false;
31358
- 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;
31494
+ for (const c of shared3.ctx.colliders) if (c.f === f && x > c.x0 - margin && x < c.x1 + margin && z > c.z0 - margin && z < c.z1 + margin) return false;
31359
31495
  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;
31360
31496
  return true;
31361
31497
  };
31362
31498
  const puts = (f, type, m0, extra) => {
31363
31499
  const ent = T2[type];
31364
31500
  if (!ent) return;
31365
- const com = shared2.ctx.roomById[m0.room], g = "f" + f, base = Y0(f);
31366
- 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 || {});
31501
+ const com = shared3.ctx.roomById[m0.room], g = "f" + f, base = Y0(f);
31502
+ 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: shared3.ctx.colors, seed: m0.id, room: m0.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.8, on: shared3.ctx.night, light: shared3.ctx.night, lit: shared3.ctx.night }, extra || {});
31367
31503
  cursor.group = g;
31368
31504
  lightItem({ id: m0.id, room: m0.room }, M, ent, api, g);
31369
31505
  };
@@ -31412,18 +31548,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31412
31548
  const defined = { decorLights };
31413
31549
  Object.assign(K, defined);
31414
31550
  }
31415
- function installLotTerrain(K, shared2) {
31551
+ function installLotTerrain(K, shared3) {
31416
31552
  const { rectsOf: rectsOf2, MIRRORS, PARTS, bx, cursor } = K;
31417
31553
  function terrain() {
31418
31554
  PARTS.length = 0;
31419
31555
  MIRRORS.length = 0;
31420
31556
  K.CARS.length = 0;
31421
- shared2.partCount = 0;
31422
- shared2.ctx.parts = {};
31423
- shared2.tapCount = 0;
31424
- shared2.ctx.clotheslines = [];
31425
- if (shared2.ctx.noTerrain) return;
31426
- const R = shared2.ctx.r, lt2 = R.lot, C = shared2.ctx.colors;
31557
+ shared3.partCount = 0;
31558
+ shared3.ctx.parts = {};
31559
+ shared3.tapCount = 0;
31560
+ shared3.ctx.clotheslines = [];
31561
+ if (shared3.ctx.noTerrain) return;
31562
+ const R = shared3.ctx.r, lt2 = R.lot, C = shared3.ctx.colors;
31427
31563
  cursor.group = "floor";
31428
31564
  const light = (c, f) => {
31429
31565
  const m = (k) => Math.round((c >> k & 255) * (1 - f) + 255 * f);
@@ -31437,13 +31573,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31437
31573
  bx("sidewalk", u0 - 40, -0.06, v0 - 1.8, u1 + 40, 0.02, v0, 14999766);
31438
31574
  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);
31439
31575
  } else {
31440
- const b = shared2.ctx.limits;
31576
+ const b = shared3.ctx.limits;
31441
31577
  bx("sidewalk", b.x0 - 6, -0.09, b.z0 - 6, b.x1 + 6, -0.03, b.z1 + 6, 14605010);
31442
31578
  }
31443
31579
  }
31444
31580
  function freeSpans(alongU, L, a, b) {
31445
31581
  const blocks = [];
31446
- for (const c of shared2.ctx.r.rooms) {
31582
+ for (const c of shared3.ctx.r.rooms) {
31447
31583
  if (c.type === "void" || c.floor < 0) continue;
31448
31584
  for (const [u0, v0, u1, v1] of rectsOf2(c)) {
31449
31585
  const c0 = alongU ? v0 : u0, c1 = alongU ? v1 : u1, lo = alongU ? u0 : v0, hi = alongU ? u1 : v1;
@@ -31464,12 +31600,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31464
31600
  const defined = { terrain, freeSpans };
31465
31601
  Object.assign(K, defined);
31466
31602
  }
31467
- function installLotPerimeter(K, shared2) {
31603
+ function installLotPerimeter(K, shared3) {
31468
31604
  const { EPS: EPS6, boxC, bx, colorOf, cursor, freeSpans, pieceRecord } = K;
31469
31605
  const makeApi = (...a) => K.makeApi(...a);
31470
31606
  const sh = (...a) => K.sh(...a);
31471
31607
  function perimeter() {
31472
- const R = shared2.ctx.r, lt2 = R.lot, C = shared2.ctx.colors;
31608
+ const R = shared3.ctx.r, lt2 = R.lot, C = shared3.ctx.colors;
31473
31609
  if (!lt2) return;
31474
31610
  cursor.group = "lot";
31475
31611
  const rnd2 = /* @__PURE__ */ (() => {
@@ -31483,7 +31619,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31483
31619
  const th = s.thickness || 0.15, h = s.height, color2 = colorOf(s.color) ?? (C.wall || 12104874), len = b - a;
31484
31620
  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);
31485
31621
  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 };
31486
- shared2.ctx.colliders.push(col);
31622
+ shared3.ctx.colliders.push(col);
31487
31623
  if (s.type === "wall") {
31488
31624
  B("plaster", a, 0, b, h, th, color2);
31489
31625
  B("plaster", a, h, b, h + 0.05, th + 0.06, sh(color2, 1.15));
@@ -31522,7 +31658,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31522
31658
  const w2 = x1 - x0, cm = (x0 + x1) / 2;
31523
31659
  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 };
31524
31660
  try {
31525
- shared2.ctx.mv.builders[top](M, api);
31661
+ shared3.ctx.mv.builders[top](M, api);
31526
31662
  } catch (e) {
31527
31663
  console.warn(e);
31528
31664
  }
@@ -31543,7 +31679,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31543
31679
  }
31544
31680
  }
31545
31681
  function paths() {
31546
- const lt2 = shared2.ctx.r.lot;
31682
+ const lt2 = shared3.ctx.r.lot;
31547
31683
  if (!lt2 || !lt2.paths) return;
31548
31684
  cursor.group = "lot";
31549
31685
  for (const c of lt2.paths) {
@@ -31557,14 +31693,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31557
31693
  const defined = { perimeter, paths };
31558
31694
  Object.assign(K, defined);
31559
31695
  }
31560
- function installLotGates(K, shared2) {
31696
+ function installLotGates(K, shared3) {
31561
31697
  const { bx, colorOf, cursor, cylBase } = K;
31562
31698
  const sh = (...a) => K.sh(...a);
31563
31699
  function slideDirection(g, lt2) {
31564
31700
  return g.u + g.width / 2 + g.width + 1.2 <= lt2.rect[2] ? 1 : -1;
31565
31701
  }
31566
31702
  function gates() {
31567
- const R = shared2.ctx.r, lt2 = R.lot, C = shared2.ctx.colors;
31703
+ const R = shared3.ctx.r, lt2 = R.lot, C = shared3.ctx.colors;
31568
31704
  if (!lt2) return;
31569
31705
  cursor.group = "lot";
31570
31706
  const structure = R.style, auto = structure !== "budget", wall = colorOf("wall") || 12104874, cu = (lt2.rect[0] + lt2.rect[2]) / 2, cz = (lt2.rect[1] + lt2.rect[3]) / 2;
@@ -31638,13 +31774,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31638
31774
  bx("emissive", mx + 0.1, 0.28, zc + sd * 0.452, mx + 0.14, 0.31, zc + sd * 0.455, 6479994);
31639
31775
  }
31640
31776
  }
31641
- if (!g.open || ped) shared2.ctx.colliders.push({ type: "gate", f: -1, x0: a, z0: v - 0.1, x1: b, z1: v + 0.1 });
31777
+ if (!g.open || ped) shared3.ctx.colliders.push({ type: "gate", f: -1, x0: a, z0: v - 0.1, x1: b, z1: v + 0.1 });
31642
31778
  }
31643
31779
  }
31644
31780
  const defined = { slideDirection, gates };
31645
31781
  Object.assign(K, defined);
31646
31782
  }
31647
- function installRoofRoofs(K, shared2) {
31783
+ function installRoofRoofs(K, shared3) {
31648
31784
  const { rectsOf: rectsOf2, EPS: EPS6, OPEN_AREA, Y0, bx, cursor } = K;
31649
31785
  const gutter = (...a) => K.gutter(...a);
31650
31786
  const gutterConfig = (...a) => K.gutterConfig(...a);
@@ -31652,14 +31788,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31652
31788
  const sh = (...a) => K.sh(...a);
31653
31789
  const slabs = (...a) => K.slabs(...a);
31654
31790
  function roofs() {
31655
- const R = shared2.ctx.r, F = R.facade, C = shared2.ctx.colors, nA = R.floors.length, type = F.roof;
31791
+ const R = shared3.ctx.r, F = R.facade, C = shared3.ctx.colors, nA = R.floors.length, type = F.roof;
31656
31792
  cursor.group = "roof";
31657
- const roofRects = shared2.ctx.roofRects = [];
31658
- const G = shared2.ctx.gutter = gutterConfig();
31793
+ const roofRects = shared3.ctx.roofRects = [];
31794
+ const G = shared3.ctx.gutter = gutterConfig();
31659
31795
  G.ncond = 0;
31660
31796
  G.nbuz = 0;
31661
31797
  G.bz = /* @__PURE__ */ new Set();
31662
- shared2.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] };
31798
+ shared3.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] };
31663
31799
  const roofColor = C.roof != null ? C.roof : 11031610, gable = (Number(R.seed) | 0) % 2 === 0;
31664
31800
  for (let f = 0; f < nA; f++) {
31665
31801
  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);
@@ -31712,7 +31848,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31712
31848
  if (G.on) gutter(type, f, x0, z0, x1, z1, ybq, touchesU);
31713
31849
  }
31714
31850
  }
31715
- for (const e of shared2.ctx.outbuildingList || []) {
31851
+ for (const e of shared3.ctx.outbuildingList || []) {
31716
31852
  const [x0, z0, x1, z1] = e.aabb, yb = Y0(0) + (e.ceiling || 2.6) + 0.2;
31717
31853
  roofRects.push({ f: 0, r: [x0, z0, x1, z1], outbuilding: e.id });
31718
31854
  if (type === "slab") {
@@ -31721,10 +31857,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31721
31857
  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);
31722
31858
  continue;
31723
31859
  }
31724
- shared2.ctx.noPiece = true;
31860
+ shared3.ctx.noPiece = true;
31725
31861
  roofRect(type, x0, z0, x1, z1, yb, roofColor, true, F, [0, 0, 0, 0]);
31726
31862
  cursor.pc = null;
31727
- shared2.ctx.noPiece = false;
31863
+ shared3.ctx.noPiece = false;
31728
31864
  if (G.on) gutter(type, 0, x0, z0, x1, z1, yb, [0, 0, 0, 0]);
31729
31865
  }
31730
31866
  }
@@ -31732,11 +31868,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31732
31868
  Object.assign(K, defined);
31733
31869
  }
31734
31870
  var paletteMeta = (colors) => colors.meta;
31735
- function installRoofGutters(K, shared2) {
31871
+ function installRoofGutters(K, shared3) {
31736
31872
  const { boxC, bx, cursor, roomAt } = K;
31737
31873
  const sh = (...a) => K.sh(...a);
31738
31874
  function gutterConfig() {
31739
- const R = shared2.ctx.r, structure = R.style, high = structure === "high" || structure === "luxury", p = high || structure === "mid" ? 0.6 : 0.3;
31875
+ const R = shared3.ctx.r, structure = R.style, high = structure === "high" || structure === "luxury", p = high || structure === "mid" ? 0.6 : 0.3;
31740
31876
  let h = 2166136261;
31741
31877
  for (const ch of String(R.seed) + "|" + K.seedKey(R.template) + "|calha") h = Math.imul(h ^ ch.charCodeAt(0), 16777619);
31742
31878
  const rnd2 = () => {
@@ -31748,10 +31884,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31748
31884
  const draw2 = rnd2() < p, light = rnd2() < 0.6;
31749
31885
  void draw2;
31750
31886
  const on = true;
31751
- return { on, rnd: rnd2, color: high ? 3816770 : light ? 15527921 : 10857392, bad: paletteMeta(shared2.ctx.colors)?.state === "abandoned" || R.state === "abandoned", fallback: false };
31887
+ return { on, rnd: rnd2, color: high ? 3816770 : light ? 15527921 : 10857392, bad: paletteMeta(shared3.ctx.colors)?.state === "abandoned" || R.state === "abandoned", fallback: false };
31752
31888
  }
31753
31889
  function gutter(type, f, X0, Z0, X1, Z1, yb, touchesU) {
31754
- 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;
31890
+ const G = shared3.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;
31755
31891
  const run = (ax, a, b, p, outside, breaks) => {
31756
31892
  const seg2 = (u0, u1, tilt) => {
31757
31893
  const L = u1 - u0, m = (u0 + u1) / 2, dy = tilt ? -Math.abs(tilt) * L * 0.5 : 0;
@@ -31775,7 +31911,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31775
31911
  sides.forEach((l, i) => {
31776
31912
  if (l[0]) run(l[1], l[2], l[3], l[4], l[5], G.bad && !G.fallback && i === larger && (G.fallback = true));
31777
31913
  });
31778
- const INF = shared2.ctx.gutterInfo || (shared2.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] });
31914
+ const INF = shared3.ctx.gutterInfo || (shared3.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] });
31779
31915
  sides.forEach((l, i) => {
31780
31916
  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 });
31781
31917
  });
@@ -31838,7 +31974,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31838
31974
  const defined = { gutterConfig, gutter, drain };
31839
31975
  Object.assign(K, defined);
31840
31976
  }
31841
- function installRoofSlabs(K, shared2) {
31977
+ function installRoofSlabs(K, shared3) {
31842
31978
  const { boxC, bx, cursor, drain, roomAt, structurePiece } = K;
31843
31979
  const sh = (...a) => K.sh(...a);
31844
31980
  function slabs(f, xs, zs, O, U, nx, nz, full, pe, C) {
@@ -31868,7 +32004,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31868
32004
  side(free(j, i + 1), x1 + o - t, z0 - ez0, x1 + o, z1 + ez1);
31869
32005
  side(free(j - 1, i), x0 - ex0, z0 - o, x1 + ex1, z0 - o + t);
31870
32006
  side(free(j + 1, i), x0 - ex0, z1 + o - t, x1 + ex1, z1 + o);
31871
- const G = shared2.ctx.gutter;
32007
+ const G = shared3.ctx.gutter;
31872
32008
  if (G && G.on && G.bz) 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]]) {
31873
32009
  const kd = f + ":" + dx + ":" + dz;
31874
32010
  if (!ok || G.bz.has(kd)) continue;
@@ -31890,8 +32026,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31890
32026
  boxC("plain", tx, 0.9, tz, 0.12, 0.04, 0.12, sh(cc, 0.8));
31891
32027
  const rx = tx + dx * 0.24, rz = tz + dz * 0.24;
31892
32028
  drain(rx, rz, tx, tz, cc);
31893
- (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 });
31894
- shared2.ctx.gutterInfo.drains.push({ x: rx, z: rz });
32029
+ (shared3.ctx.gutterInfo || (shared3.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] })).downpipes.push({ f, x: tx, z: tz, y0: 0.045, y1: yb + 0.04, drain: [rx, rz], hornBox: true });
32030
+ shared3.ctx.gutterInfo.drains.push({ x: rx, z: rz });
31895
32031
  }
31896
32032
  }
31897
32033
  }
@@ -31900,10 +32036,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31900
32036
  const defined = { slabs };
31901
32037
  Object.assign(K, defined);
31902
32038
  }
31903
- function installRoofTiles(K, shared2) {
32039
+ function installRoofTiles(K, shared3) {
31904
32040
  const { UV_SCALE, _Y, _h2, _q, accFor, cursor, put, rgbOf, structurePiece } = K;
31905
32041
  const sh = (...a) => K.sh(...a);
31906
- const R_STYLE = () => shared2.ctx.r && shared2.ctx.r.style || "budget";
32042
+ const R_STYLE = () => shared3.ctx.r && shared3.ctx.r.style || "budget";
31907
32043
  function tileRelief(mat, pts, color2, type) {
31908
32044
  const n = pts.length;
31909
32045
  if (n < 3) return;
@@ -31944,7 +32080,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31944
32080
  S.push(rx * ex + ry * ey + rz * ez);
31945
32081
  T2.push(rx * dx + ry * dy + rz * dz);
31946
32082
  }
31947
- 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;
32083
+ const colonial = type !== "fiber_cement", P = colonial ? 0.2 : 0.177, A = colonial ? 0.032 : 0.0255, seg2 = shared3.quality === "game" ? colonial ? 4 : 4 : colonial ? 8 : 6, h = P / seg2;
31948
32084
  const smin = Math.min(...S), smax = Math.max(...S);
31949
32085
  if (smax - smin < 1e-4) return;
31950
32086
  const xs = new Set(S.map((v) => +v.toFixed(5)));
@@ -32016,9 +32152,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32016
32152
  }
32017
32153
  }
32018
32154
  function pieceOfPane(x, z) {
32019
- if (shared2.ctx.noPiece || !shared2.ctx.panes.length) return null;
32155
+ if (shared3.ctx.noPiece || !shared3.ctx.panes.length) return null;
32020
32156
  let m = null, md = 1e9;
32021
- for (const a of shared2.ctx.panes) {
32157
+ for (const a of shared3.ctx.panes) {
32022
32158
  const b = a.aabb;
32023
32159
  if (!b) continue;
32024
32160
  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;
@@ -32032,11 +32168,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32032
32168
  const defined = { R_STYLE, tileRelief, ridge, pieceOfPane };
32033
32169
  Object.assign(K, defined);
32034
32170
  }
32035
- function installRoofRect(K, shared2) {
32171
+ function installRoofRect(K, shared3) {
32036
32172
  const { R_STYLE, bx, cursor, pieceOfPane, polyFace, ridge, tileRelief } = K;
32037
32173
  const sh = (...a) => K.sh(...a);
32038
32174
  function roofRect(type, X0, Z0, X1, Z1, yb, roofColor, gable, F, touchesU = [0, 0, 0, 0]) {
32039
- 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;
32175
+ const C = shared3.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;
32040
32176
  const mat = type === "fiber_cement" ? "fiber_cement" : "tile", tp = type === "fiber_cement" ? 0.2 : 0.5, alongX = dx >= dz, up = [0, 1, 0];
32041
32177
  const Q = (pts) => {
32042
32178
  let cx = 0, cz = 0;
@@ -32074,7 +32210,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32074
32210
  }
32075
32211
  const rm = alongX ? dz / 2 : dx / 2;
32076
32212
  {
32077
- const roofRects = shared2.ctx.roofRects, rr = roofRects[roofRects.length - 1];
32213
+ const roofRects = shared3.ctx.roofRects, rr = roofRects[roofRects.length - 1];
32078
32214
  if (rr && !rr.yb) Object.assign(rr, { yb, tp, gable: !!gable, alongX, exterior: [x0, z0, x1, z1], rm });
32079
32215
  }
32080
32216
  if (gable) {
@@ -32114,12 +32250,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32114
32250
  const defined = { roofRect };
32115
32251
  Object.assign(K, defined);
32116
32252
  }
32117
- function installMirrors(K, shared2) {
32253
+ function installMirrors(K, shared3) {
32118
32254
  const { DOC, THREE, Reflector, MIRRORS, Y0, _Y, roomAt } = K;
32119
- shared2.mirrorEnv = null;
32120
- shared2.mirrorMat = null;
32255
+ shared3.mirrorEnv = null;
32256
+ shared3.mirrorMat = null;
32121
32257
  function mirrorEnv() {
32122
- if (shared2.mirrorEnv) return shared2.mirrorEnv;
32258
+ if (shared3.mirrorEnv) return shared3.mirrorEnv;
32123
32259
  const mk = (f) => {
32124
32260
  if (!DOC) throw new Error("game-floorplan-three: the mirrors need a document (options.document)");
32125
32261
  const c = DOC.createElement("canvas");
@@ -32157,18 +32293,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32157
32293
  const t = new THREE.CubeTexture(faces);
32158
32294
  t.colorSpace = THREE.SRGBColorSpace;
32159
32295
  t.needsUpdate = true;
32160
- shared2.mirrorEnv = t;
32161
- shared2.mirrorMat = new THREE.MeshStandardMaterial({ color: 16054008, metalness: 1, roughness: 0.06, envMap: t, envMapIntensity: 1 });
32296
+ shared3.mirrorEnv = t;
32297
+ shared3.mirrorMat = new THREE.MeshStandardMaterial({ color: 16054008, metalness: 1, roughness: 0.06, envMap: t, envMapIntensity: 1 });
32162
32298
  return t;
32163
32299
  }
32164
32300
  const newMirrorState = () => ({ list: [], active: null, tmp: new THREE.Vector3(), house: null });
32165
- shared2.mirrors = newMirrorState();
32301
+ shared3.mirrors = newMirrorState();
32166
32302
  function assembleMirrors(groups) {
32167
- shared2.mirrors.list.length = 0;
32168
- shared2.mirrors.active = null;
32303
+ shared3.mirrors.list.length = 0;
32304
+ shared3.mirrors.active = null;
32169
32305
  if (!MIRRORS.length) return;
32170
32306
  mirrorEnv();
32171
- if (shared2.quality === "game" || !Reflector) {
32307
+ if (shared3.quality === "game" || !Reflector) {
32172
32308
  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();
32173
32309
  for (const E of MIRRORS) {
32174
32310
  const geo = new THREE.PlaneGeometry(E.w, E.h);
@@ -32195,7 +32331,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32195
32331
  g.setAttribute("uv", new THREE.Float32BufferAttribute(B.U, 2));
32196
32332
  g.setIndex(B.I);
32197
32333
  g.computeBoundingSphere();
32198
- const m = new THREE.Mesh(g, shared2.mirrorMat);
32334
+ const m = new THREE.Mesh(g, shared3.mirrorMat);
32199
32335
  m.name = "mirror/environment";
32200
32336
  m.userData.part = "mirror";
32201
32337
  (groups[parent] || (groups[parent] = new THREE.Group())).add(m);
@@ -32210,7 +32346,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32210
32346
  g.userData.part = "mirror";
32211
32347
  g.userData.room = E.room;
32212
32348
  const geo = new THREE.PlaneGeometry(E.w, E.h);
32213
- const fake = new THREE.Mesh(geo, shared2.mirrorMat);
32349
+ const fake = new THREE.Mesh(geo, shared3.mirrorMat);
32214
32350
  fake.userData.part = "mirror";
32215
32351
  fake.name = "mirror/environment";
32216
32352
  g.add(fake);
@@ -32226,27 +32362,27 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32226
32362
  console.warn("mirror real", e);
32227
32363
  }
32228
32364
  (groups[E.parent] || (groups[E.parent] = new THREE.Group())).add(g);
32229
- shared2.mirrors.list.push({ E, g, fake, real });
32365
+ shared3.mirrors.list.push({ E, g, fake, real });
32230
32366
  }
32231
32367
  }
32232
32368
  function floorAtY(y) {
32233
- const A = shared2.ctx.r.floors;
32369
+ const A = shared3.ctx.r.floors;
32234
32370
  let f = 0;
32235
32371
  for (let i = 0; i < A.length; i++) if (y >= A[i].y0 - 0.2) f = i;
32236
32372
  return f;
32237
32373
  }
32238
32374
  function chooseMirror(camera2) {
32239
- if (!shared2.mirrors.list.length) return;
32375
+ if (!shared3.mirrors.list.length) return;
32240
32376
  let target = null;
32241
- if (shared2.mirrors.house && shared2.ctx.r) {
32242
- shared2.mirrors.tmp.copy(camera2.position);
32243
- shared2.mirrors.house.worldToLocal(shared2.mirrors.tmp);
32244
- const f = floorAtY(shared2.mirrors.tmp.y), c = roomAt(f, shared2.mirrors.tmp.x, shared2.mirrors.tmp.z);
32245
- if (c && shared2.mirrors.tmp.y > Y0(f) && shared2.mirrors.tmp.y < Y0(f) + 4) {
32377
+ if (shared3.mirrors.house && shared3.ctx.r) {
32378
+ shared3.mirrors.tmp.copy(camera2.position);
32379
+ shared3.mirrors.house.worldToLocal(shared3.mirrors.tmp);
32380
+ const f = floorAtY(shared3.mirrors.tmp.y), c = roomAt(f, shared3.mirrors.tmp.x, shared3.mirrors.tmp.z);
32381
+ if (c && shared3.mirrors.tmp.y > Y0(f) && shared3.mirrors.tmp.y < Y0(f) + 4) {
32246
32382
  let best = 1e9;
32247
- for (const m of shared2.mirrors.list) {
32383
+ for (const m of shared3.mirrors.list) {
32248
32384
  if (m.E.room !== c.id || m.E.floor !== f || !m.g.parent || !m.g.parent.visible) continue;
32249
- const d = Math.hypot(m.E.x - shared2.mirrors.tmp.x, m.E.z - shared2.mirrors.tmp.z);
32385
+ const d = Math.hypot(m.E.x - shared3.mirrors.tmp.x, m.E.z - shared3.mirrors.tmp.z);
32250
32386
  if (d < best) {
32251
32387
  best = d;
32252
32388
  target = m;
@@ -32254,9 +32390,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32254
32390
  }
32255
32391
  }
32256
32392
  }
32257
- if (target === shared2.mirrors.active) return;
32258
- shared2.mirrors.active = target;
32259
- for (const m of shared2.mirrors.list) {
32393
+ if (target === shared3.mirrors.active) return;
32394
+ shared3.mirrors.active = target;
32395
+ for (const m of shared3.mirrors.list) {
32260
32396
  const on = m === target && !!m.real;
32261
32397
  if (m.real) m.real.visible = on;
32262
32398
  m.fake.visible = !on;
@@ -32265,7 +32401,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32265
32401
  const defined = { mirrorEnv, newMirrorState, assembleMirrors, floorAtY, chooseMirror };
32266
32402
  Object.assign(K, defined);
32267
32403
  }
32268
- function installCars(K, shared2) {
32404
+ function installCars(K, shared3) {
32269
32405
  const { THREE, FLEET, _Y } = K;
32270
32406
  const CARS = [];
32271
32407
  const CAR_BY_STYLE = Object.assign({
@@ -32294,12 +32430,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32294
32430
  return b;
32295
32431
  }
32296
32432
  function carModel(k, seed) {
32297
- const kc = k + "|" + shared2.quality + "|" + (seed || 0);
32433
+ const kc = k + "|" + shared3.quality + "|" + (seed || 0);
32298
32434
  if (CAR_CACHE.has(kc)) return CAR_CACHE.get(kc) ?? null;
32299
32435
  if (!FLEET) return null;
32300
32436
  let res = null;
32301
32437
  try {
32302
- const v0 = FLEET.build(k, { quality: shared2.quality, seed: seed || 0 }), c = { root: v0.group, g: v0.group };
32438
+ const v0 = FLEET.build(k, { quality: shared3.quality, seed: seed || 0 }), c = { root: v0.group, g: v0.group };
32303
32439
  c.root.updateMatrixWorld(true);
32304
32440
  const inv = new THREE.Matrix4();
32305
32441
  const byMaterial = /* @__PURE__ */ new Map(), tmp = new THREE.Matrix4(), v = new THREE.Vector3(), nm = new THREE.Matrix3(), bb = new THREE.Box3();
@@ -32421,7 +32557,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32421
32557
  return g;
32422
32558
  }
32423
32559
  function assembleCars(groups) {
32424
- if (shared2.quality === "game") {
32560
+ if (shared3.quality === "game") {
32425
32561
  assembleMergedCars(groups);
32426
32562
  return;
32427
32563
  }
@@ -32478,10 +32614,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32478
32614
  const defined = { CARS, CAR_BY_STYLE, CAR_CACHE, materialSignature, BUCKETS, bucketMaterial, carModel, carGroup, assembleCars, assembleMergedCars };
32479
32615
  Object.assign(K, defined);
32480
32616
  }
32481
- function installHouseBuilding(K, shared2) {
32617
+ function installHouseBuilding(K, shared3) {
32482
32618
  const { bx, cursor } = K;
32483
32619
  function building() {
32484
- 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;
32620
+ const R = shared3.ctx.r, P = R.building, C = shared3.ctx.colors, N = shared3.ctx.pa, uf = shared3.ctx.pf, pe = P.ceilingHeight, fa = C.facade != null ? C.facade : 14209216;
32485
32621
  cursor.group = "building";
32486
32622
  const uw = P.unit.w, ud = P.unit.d, un = P.units;
32487
32623
  const unitBox = (u) => {
@@ -32489,7 +32625,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32489
32625
  return [x[0], z[0], x[1], z[1]];
32490
32626
  };
32491
32627
  const un0 = unitBox(un[0]), color2 = P.corridor, hall = P.hall, el = P.elevator.rect, es = P.stairs.rect;
32492
- const sel = un[shared2.ctx.pu] || un[0], selR = unitBox(sel);
32628
+ const sel = un[shared3.ctx.pu] || un[0], selR = unitBox(sel);
32493
32629
  const shell = (rc, y0, y1, thickness = 0.15) => {
32494
32630
  const [a, b, c, d] = rc;
32495
32631
  bx("building", a, y0, b, c, y1, b + thickness, fa);
@@ -32528,12 +32664,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32528
32664
  }
32529
32665
  const ytop = N * pe - 0.2;
32530
32666
  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);
32531
- 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) };
32667
+ shared3.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) };
32532
32668
  }
32533
32669
  const defined = { building };
32534
32670
  Object.assign(K, defined);
32535
32671
  }
32536
- function installUtilitiesWater(K, shared2) {
32672
+ function installUtilitiesWater(K, shared3) {
32537
32673
  const { THREE, _Y, _q, cursor, cylBase, part, pieceRecord, put } = K;
32538
32674
  function createWater(r, state) {
32539
32675
  const H = r.utilities?.plumbing, cap = H ? +H.capacityL || 0 : 0, ls = { dry: [], full: [] }, points = {}, itemPoint = {};
@@ -32625,14 +32761,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32625
32761
  }
32626
32762
  const _v3 = new THREE.Vector3();
32627
32763
  function waterPipes() {
32628
- const H = shared2.ctx.r.utilities?.plumbing;
32764
+ const H = shared3.ctx.r.utilities?.plumbing;
32629
32765
  if (!H || !H.visibleRuns) return;
32630
- const nA = shared2.ctx.r.floors.length;
32766
+ const nA = shared3.ctx.r.floors.length;
32631
32767
  const groupOf = (c) => c && c.floor >= 0 ? "f" + Math.min(c.floor, nA - 1) : "lot", xyz = (p) => [p[0], p[2], p[1]];
32632
32768
  for (const tr of H.visibleRuns) {
32633
32769
  const pts = tr.points.map(xyz), d = tr.diameter || 0.025;
32634
32770
  if (tr.exposed === "wall") {
32635
- const pt = H.points.find((p) => p.run === tr.id), com = tr.to != null ? shared2.ctx.roomById[tr.to] : void 0, g2 = groupOf(com || pt && { floor: pt.floor });
32771
+ const pt = H.points.find((p) => p.run === tr.id), com = tr.to != null ? shared3.ctx.roomById[tr.to] : void 0, g2 = groupOf(com || pt && { floor: pt.floor });
32636
32772
  part("wall_pipe", [0, 0, 0], () => {
32637
32773
  for (let i = 0; i + 1 < pts.length; i++) pipe(pts[i], pts[i + 1], d, PIPE_COLOR);
32638
32774
  for (const p of pts) cylBase("plain", p[0], p[1] - d, p[2], d * 0.7, d * 2, PIPE_COLOR);
@@ -32640,7 +32776,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32640
32776
  continue;
32641
32777
  }
32642
32778
  let g;
32643
- if (tr.exposed === "tank_outlet") g = shared2.ctx.waterTankPos && shared2.ctx.waterTankPos.group || "f0";
32779
+ if (tr.exposed === "tank_outlet") g = shared3.ctx.waterTankPos && shared3.ctx.waterTankPos.group || "f0";
32644
32780
  else {
32645
32781
  const pt = H.points.find((p) => p.id === tr.to);
32646
32782
  g = groupOf(pt);
@@ -32657,15 +32793,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32657
32793
  const defined = { createWater, PIPE_COLOR, pipe, _v3, waterPipes };
32658
32794
  Object.assign(K, defined);
32659
32795
  }
32660
- function installUtilitiesElectrical(K, shared2) {
32796
+ function installUtilitiesElectrical(K, shared3) {
32661
32797
  const { _Y, _q, _v3, bx, cursor, cylBase, pieceRecord, put } = K;
32662
32798
  const sh = (...a) => K.sh(...a);
32663
32799
  function electricalStructure() {
32664
- const R = shared2.ctx.r, E = R.utilities?.electrical;
32665
- shared2.ctx.electricalInfo = null;
32800
+ const R = shared3.ctx.r, E = R.utilities?.electrical;
32801
+ shared3.ctx.electricalInfo = null;
32666
32802
  if (!E) return;
32667
32803
  const 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 };
32668
- const en22 = E.serviceEntrance, KV = shared2.ctx.iv ? shared2.ctx.iv.plane : null;
32804
+ const en22 = E.serviceEntrance, KV = shared3.ctx.iv ? shared3.ctx.iv.plane : null;
32669
32805
  const wireL = (a, b, r_ = 8e-3) => {
32670
32806
  const L = Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
32671
32807
  if (L < 1e-3) return;
@@ -32743,7 +32879,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32743
32879
  info.conduits.push(t.id);
32744
32880
  continue;
32745
32881
  }
32746
- const c = circ[t.circuit], com = c && shared2.ctx.roomById[c.room];
32882
+ const c = circ[t.circuit], com = c && shared3.ctx.roomById[c.room];
32747
32883
  cursor.group = "f" + Math.max(0, Math.min(nA - 1, com ? com.floor : 0));
32748
32884
  const d = t.diameter || 0.02, P = t.points.map((p) => [p[0], p[2], p[1]]), seg2 = [];
32749
32885
  for (let i = 0; i + 1 < P.length; i++) {
@@ -32761,7 +32897,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32761
32897
  }
32762
32898
  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 });
32763
32899
  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 });
32764
- shared2.ctx.electricalInfo = info;
32900
+ shared3.ctx.electricalInfo = info;
32765
32901
  }
32766
32902
  function pipe2(a, b, diameter, color2) {
32767
32903
  const dx = b[0] - a[0], dy = b[1] - a[1], dz = b[2] - a[2], L = Math.hypot(dx, dy, dz);
@@ -32772,11 +32908,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32772
32908
  const defined = { electricalStructure, pipe2 };
32773
32909
  Object.assign(K, defined);
32774
32910
  }
32775
- function installHouseBaseboard(K, shared2) {
32776
- const { Y0, bx, cursor, sideOf } = K;
32911
+ var BASEBOARD_TILES = { length: 0.6, joint: 3e-3, material: "ceramic", density: 2300 };
32912
+ var SIDEWALK_SLABS = { length: 1.2, joint: 0.01, material: "concrete", density: 2400 };
32913
+ function installHouseBaseboard(K, shared3) {
32914
+ const { Y0, bx, cursor, pieceRecord, sideOf } = K;
32777
32915
  const sh = (...a) => K.sh(...a);
32778
32916
  function baseboardAndSidewalk() {
32779
- 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;
32917
+ const R = shared3.ctx.r, W = 0.6, t = 0.012, ht = 0.35, color2 = sh(shared3.ctx.colors.facade != null ? shared3.ctx.colors.facade : 14209216, 0.62), y0 = Y0(0), cal = 13947078;
32780
32918
  const ws = R.walls.filter((w) => w.floor === 0 && w.type === "wall").map((w) => {
32781
32919
  const au = w.axis === "u";
32782
32920
  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 };
@@ -32795,25 +32933,39 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32795
32933
  };
32796
32934
  for (const A of ws) for (const [side, sd] of [[A.w.sides[0], -1], [A.w.sides[1], 1]]) {
32797
32935
  if (!sideOf(side, false).exterior) continue;
32798
- const strip = (k, y1, y2, o0, o1, mat, c, y1b) => {
32936
+ const strip = (k, y1, y2, o0, o1, mat, c, piece2, laid = BASEBOARD_TILES) => {
32799
32937
  const ea = junction(A, A.a, sd) > 0 ? A.th / 2 + k : junction(A, A.a, sd) < 0 ? -A.th / 2 : 0, eb = junction(A, A.b, sd) > 0 ? A.th / 2 + k : junction(A, A.b, sd) < 0 ? -A.th / 2 : 0;
32800
32938
  const s0 = A.a - ea, s1 = A.b + eb, f0 = A.L + sd * (A.th / 2 + o0), f1 = A.L + sd * (A.th / 2 + o1), lo = Math.min(f0, f1), hi = Math.max(f0, f1);
32801
32939
  if (s1 - s0 < 1e-3) return;
32802
- if (A.au) bx(mat, s0, y1, lo, s1, y2, hi, c);
32803
- else bx(mat, lo, y1, s0, hi, y2, s1, c);
32940
+ const box5 = (a, b) => {
32941
+ if (A.au) bx(mat, a, y1, lo, b, y2, hi, c);
32942
+ else bx(mat, lo, y1, a, hi, y2, b, c);
32943
+ };
32944
+ const tag = laid === BASEBOARD_TILES ? "baseboard" : "sidewalk";
32945
+ const tile = (id, a, b) => {
32946
+ cursor.pc = pieceRecord(id, laid.material, null, { floor: 0, mass: Math.round((b - a) * (y2 - y1) * (hi - lo) * laid.density * 100) / 100, tags: [tag] });
32947
+ box5(a, b);
32948
+ };
32949
+ if (!piece2) box5(s0, s1);
32950
+ else if (shared3.ctx.baseboardBand) tile(piece2, s0, s1);
32951
+ else {
32952
+ const n = Math.max(1, Math.round((s1 - s0) / laid.length)), w = (s1 - s0) / n, j = laid.joint / 2;
32953
+ for (let i = 0; i < n; i++) tile(`${piece2}:${i}`, s0 + i * w + (i > 0 ? j : 0), s0 + (i + 1) * w - (i < n - 1 ? j : 0));
32954
+ }
32955
+ cursor.pc = null;
32804
32956
  };
32805
- strip(t, y0, y0 + ht, 0, t, "plaster", color2);
32806
- strip(W, y0, y0 + 0.045, 0, W, "sidewalk", cal);
32957
+ strip(t, y0, y0 + ht, 0, t, "plaster", color2, A.w.id ? `baseboard:${A.w.id}:${sd < 0 ? 0 : 1}` : void 0);
32958
+ strip(W, y0, y0 + 0.045, 0, W, "sidewalk", cal, A.w.id ? `sidewalk:${A.w.id}:${sd < 0 ? 0 : 1}` : void 0, SIDEWALK_SLABS);
32807
32959
  }
32808
32960
  }
32809
32961
  const defined = { baseboardAndSidewalk };
32810
32962
  Object.assign(K, defined);
32811
32963
  }
32812
- function installUtilitiesSolar(K, shared2) {
32964
+ function installUtilitiesSolar(K, shared3) {
32813
32965
  const { Y0, boxC, bx, cursor, cylBase } = K;
32814
32966
  function roofHeightAt(u, v, f) {
32815
32967
  let y = null;
32816
- for (const rr of shared2.ctx.roofRects || []) {
32968
+ for (const rr of shared3.ctx.roofRects || []) {
32817
32969
  if (rr.yb == null || f != null && rr.f !== f) continue;
32818
32970
  if (rr.slab) {
32819
32971
  const [a, b, c, d] = rr.r;
@@ -32829,8 +32981,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32829
32981
  return y;
32830
32982
  }
32831
32983
  function solar() {
32832
- const R = shared2.ctx.r, S = R.utilities?.solar;
32833
- shared2.ctx.solarInfo = null;
32984
+ const R = shared3.ctx.r, S = R.utilities?.solar;
32985
+ shared3.ctx.solarInfo = null;
32834
32986
  if (!S || !S.panels || !S.panels.length) return;
32835
32987
  cursor.group = "roof";
32836
32988
  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";
@@ -32872,16 +33024,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32872
33024
  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);
32873
33025
  bx("emissive", iv.u - 0.03, y0 - 0.12, iv.v + fa0, iv.u + 0.03, y0 - 0.09, iv.v + fa1, 6479994);
32874
33026
  }
32875
- const top = Math.max(...(shared2.ctx.roofRects || []).flatMap((t2) => t2.yb != null ? [t2.yb] : []), Y0(fa) + 2.8);
33027
+ const top = Math.max(...(shared3.ctx.roofRects || []).flatMap((t2) => t2.yb != null ? [t2.yb] : []), Y0(fa) + 2.8);
32876
33028
  cylBase("plain", iv.u, y0 + h / 2, iv.v, 0.016, Math.max(0.2, top - 0.2 - (y0 + h / 2)), 15262936);
32877
33029
  info.inverter = { id: iv.id, pos: [iv.u, y0, iv.v], side: iv.side, link: iv.link };
32878
33030
  }
32879
- shared2.ctx.solarInfo = info;
33031
+ shared3.ctx.solarInfo = info;
32880
33032
  }
32881
33033
  const defined = { roofHeightAt, solar };
32882
33034
  Object.assign(K, defined);
32883
33035
  }
32884
- function installHouseOutbuildings(K, shared2) {
33036
+ function installHouseOutbuildings(K, shared3) {
32885
33037
  const { t, bx, cursor, floorColor } = K;
32886
33038
  const sh = (...a) => K.sh(...a);
32887
33039
  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")] };
@@ -32928,17 +33080,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32928
33080
  return Object.assign({}, r, { rooms, walls, doors, windows, items });
32929
33081
  }
32930
33082
  function outbuildings() {
32931
- const E = (shared2.ctx.r.outbuildings || []).filter((e) => shared2.ctx.roomById[e.id] && shared2.ctx.roomById[e.id].outbuilding);
32932
- shared2.ctx.outbuildingList = E;
33083
+ const E = (shared3.ctx.r.outbuildings || []).filter((e) => shared3.ctx.roomById[e.id] && shared3.ctx.roomById[e.id].outbuilding);
33084
+ shared3.ctx.outbuildingList = E;
32933
33085
  if (!E.length) return;
32934
33086
  cursor.group = "f0";
32935
33087
  for (const e of E) {
32936
- const c = shared2.ctx.roomById[e.id], col = floorColor(c);
33088
+ const c = shared3.ctx.roomById[e.id], col = floorColor(c);
32937
33089
  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);
32938
33090
  for (const p of e.doors || []) {
32939
33091
  const alongU = p.axis === "u", th = e.thickness || 0.15;
32940
- 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));
32941
- 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));
33092
+ 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(shared3.ctx.colors.facade || 14209216, 0.8));
33093
+ 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(shared3.ctx.colors.facade || 14209216, 0.8));
32942
33094
  }
32943
33095
  }
32944
33096
  }
@@ -33677,10 +33829,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33677
33829
  const defined = { typeTable };
33678
33830
  Object.assign(K, defined);
33679
33831
  }
33680
- function installFurnitureTaps(K, shared2) {
33681
- shared2.tapCount = 0;
33832
+ function installFurnitureTaps(K, shared3) {
33833
+ shared3.tapCount = 0;
33682
33834
  function counterTap(K2, x, y, z, reach, back, meta = {}) {
33683
- const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared2.tapCount++;
33835
+ const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared3.tapCount++;
33684
33836
  K2.c("metal", x, y, z, 0.028, 0.012, cr);
33685
33837
  K2.c("metal", x, y + 0.012, z, 0.014, 0.12, cr);
33686
33838
  const pts = [];
@@ -33711,7 +33863,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33711
33863
  return id;
33712
33864
  }
33713
33865
  function wallTap(K2, x, y, zw, direction, back, meta = {}) {
33714
- const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared2.tapCount++, s = direction || 1;
33866
+ const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared3.tapCount++, s = direction || 1;
33715
33867
  K2.t("metal", [x, y, zw], [x, y, zw + s * 0.025], 0.03, cr);
33716
33868
  K2.t("metal", [x, y, zw + s * 0.02], [x, y, zw + s * 0.1], 0.016, cr);
33717
33869
  K2.e("metal", x, y, zw + s * 0.105, 0.019, 0.04, cr);
@@ -33963,7 +34115,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33963
34115
  const defined = { GREENS: GREENS2, FLOWERS, blobs, potModel, arcLeaf, tuft, palm_tree, treeModel, shrubModel, potPlant, tablePot, planterModel };
33964
34116
  Object.assign(K, defined);
33965
34117
  }
33966
- function installFurnitureYard(K, shared2) {
34118
+ function installFurnitureYard(K, shared3) {
33967
34119
  const seedKey = (id) => K.seedKey(id);
33968
34120
  const { FURNITURE, SEED, STYLE, kit2, rngString, sh, wallTap } = K;
33969
34121
  FURNITURE.laundry_tub = function(M, A) {
@@ -34053,7 +34205,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34053
34205
  }
34054
34206
  }
34055
34207
  }, { id: "laundry_" + M.seed, swing: true, room: "yard" });
34056
- (shared2.ctx.clotheslines || (shared2.ctx.clotheslines = [])).push(M.seed);
34208
+ (shared3.ctx.clotheslines || (shared3.ctx.clotheslines = [])).push(M.seed);
34057
34209
  };
34058
34210
  FURNITURE.water_tank = function(M, A) {
34059
34211
  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;
@@ -34197,13 +34349,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34197
34349
  const defined = { extraTypes };
34198
34350
  Object.assign(K, defined);
34199
34351
  }
34200
- function installFurniturePlaceItems(K, shared2) {
34352
+ function installFurniturePlaceItems(K, shared3) {
34201
34353
  const { THREE, Y0, _col, boxC, colorOf, cursor, decorLights, makeApi, structurePiece } = K;
34202
34354
  const buildItem2 = (...a) => K.buildItem(...a);
34203
34355
  const registerCollision = (...a) => K.registerCollision(...a);
34204
34356
  const vegItem = (...a) => K.vegItem(...a);
34205
34357
  function houseItems() {
34206
- const R = shared2.ctx.r, T2 = shared2.ctx.types, api = makeApi(), noModel = /* @__PURE__ */ new Map();
34358
+ const R = shared3.ctx.r, T2 = shared3.ctx.types, api = makeApi(), noModel = /* @__PURE__ */ new Map();
34207
34359
  const list2 = R.items.concat(R.stateItems.filter((e) => e.w != null && e.d != null && e.type !== "razor_wire" && e.type !== "barbed_wire"));
34208
34360
  const rect = (poly) => {
34209
34361
  let a = 0;
@@ -34215,8 +34367,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34215
34367
  if (m.type === "stairs") continue;
34216
34368
  const exterior = m.outdoor || m.floor < 0, f = exterior ? -1 : Math.min(m.floor, R.floors.length - 1);
34217
34369
  cursor.group = exterior ? "lot" : "f" + f;
34218
- const com = m.room != null ? shared2.ctx.roomById[m.room] : void 0, base = exterior ? 0 : Y0(f);
34219
- 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) ?? 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 };
34370
+ const com = m.room != null ? shared3.ctx.roomById[m.room] : void 0, base = exterior ? 0 : Y0(f);
34371
+ 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: shared3.ctx.colors, color: m.category === "ground_cover" ? void 0 : colorOf(m.color) ?? void 0, seed: m.id, room: m.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.9, on: shared3.ctx.night, light: shared3.ctx.night, lit: shared3.ctx.night, open: !!m.doorOpen, overhead: m.overhead, assembly: m.assembly, hose: m.hose };
34220
34372
  if (m.category === "ground_cover" && m.polygon) {
34221
34373
  const xs = m.polygon.map((p) => p[0]), zs = m.polygon.map((p) => p[1]);
34222
34374
  M.x = (Math.min(...xs) + Math.max(...xs)) / 2;
@@ -34226,8 +34378,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34226
34378
  M.ry = 0;
34227
34379
  if (!rect(m.polygon)) M.poly = m.polygon.map((p) => [p[0] - M.x, p[1] - M.z]);
34228
34380
  }
34229
- if (shared2.ctx.veg && vegItem(m, M, exterior ? "lot" : "f" + f)) continue;
34230
- if (shared2.ctx.iv && shared2.ctx.iv.replace.has(m.id)) {
34381
+ if (shared3.ctx.veg && vegItem(m, M, exterior ? "lot" : "f" + f)) continue;
34382
+ if (shared3.ctx.iv && shared3.ctx.iv.replace.has(m.id)) {
34231
34383
  registerCollision(m, M);
34232
34384
  continue;
34233
34385
  }
@@ -34259,13 +34411,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34259
34411
  return noModel;
34260
34412
  }
34261
34413
  function waterTankOfHouse(api) {
34262
- const cd = shared2.ctx.r.waterTank;
34263
- if (!cd || !shared2.ctx.types.water_tank) return;
34264
- 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));
34265
- 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));
34414
+ const cd = shared3.ctx.r.waterTank;
34415
+ if (!cd || !shared3.ctx.types.water_tank) return;
34416
+ const lc = cd.place === "raised_slab" && cd.platform, slab = cd.place === "slab" || !!lc, nA = shared3.ctx.r.floors.length, f = Math.max(0, Math.min(nA - 1, cd.floor));
34417
+ const base = lc ? cd.platform.topY : cd.y + (shared3.ctx.r.rooms.some((c) => c.id === cd.room && c.type === "terrace") ? 0 : 0.2 + (slab ? 0.03 : 0));
34266
34418
  cursor.group = slab ? "f" + f : "attic_tank";
34267
34419
  if (lc) {
34268
- const P = cd.platform, [x0, z0, x1, z1] = P.aabb, e = P.thickness, color2 = shared2.ctx.colors.slab != null ? shared2.ctx.colors.slab : 12170668;
34420
+ const P = cd.platform, [x0, z0, x1, z1] = P.aabb, e = P.thickness, color2 = shared3.ctx.colors.slab != null ? shared3.ctx.colors.slab : 12170668;
34269
34421
  cursor.pc = structurePiece("tank_slab");
34270
34422
  boxC("plain", (x0 + x1) / 2, P.topY - e / 2, (z0 + z1) / 2, x1 - x0, e, z1 - z0, color2, 0, 0, 0);
34271
34423
  P.pillars.forEach((p, k) => {
@@ -34275,13 +34427,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34275
34427
  cursor.pc = null;
34276
34428
  }
34277
34429
  if (!slab) {
34278
- 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;
34430
+ const color2 = shared3.ctx.colors.slab != null ? shared3.ctx.colors.slab : 12170668, yp = Y0(f), hw = cd.w / 2 + 0.1, hd = cd.d / 2 + 0.1;
34279
34431
  boxC("plain", cd.u, base - 0.06, cd.v, hw * 2, 0.12, hd * 2, color2);
34280
34432
  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);
34281
34433
  }
34282
- 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 };
34283
- shared2.ctx.waterTankPos = { x: cd.u, z: cd.v, y: base, group: cursor.group };
34284
- shared2.ctx.types.water_tank.f(M, api);
34434
+ 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: shared3.ctx.colors, seed: "water_tank", room: cd.room, onSlab: true, ceiling: 2.9 };
34435
+ shared3.ctx.waterTankPos = { x: cd.u, z: cd.v, y: base, group: cursor.group };
34436
+ shared3.ctx.types.water_tank.f(M, api);
34285
34437
  }
34286
34438
  function hashColor(s) {
34287
34439
  let h = 7;
@@ -34291,12 +34443,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34291
34443
  function labeledBox(m, M, group) {
34292
34444
  const color2 = M.color != null ? M.color : hashColor(m.category || m.type), h = Math.max(0.05, m.h || 0.5);
34293
34445
  boxC("plain", m.x, M.base + (m.y || 0) + h / 2, m.z, m.w, h, m.d, color2, 0, m.ry || 0, 0);
34294
- 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" });
34446
+ shared3.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" });
34295
34447
  }
34296
34448
  const defined = { houseItems, waterTankOfHouse, hashColor, labeledBox };
34297
34449
  Object.assign(K, defined);
34298
34450
  }
34299
- function installVegetationBridge(K, shared2) {
34451
+ function installVegetationBridge(K, shared3) {
34300
34452
  const seedKey = (id) => K.seedKey(id);
34301
34453
  const { THREE, SEED, rngString } = K;
34302
34454
  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" };
@@ -34322,7 +34474,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34322
34474
  for (const k of Object.keys(VEG_CACTUS)) VEG_MAP[k] = [VEG_CACTUS[k]];
34323
34475
  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"] };
34324
34476
  function vegItem(m, M, group) {
34325
- const V3 = shared2.ctx.veg;
34477
+ const V3 = shared3.ctx.veg;
34326
34478
  if (!V3) return false;
34327
34479
  const ids = VEG_MAP[m.type], can2 = VEG_PLANTER[m.type];
34328
34480
  if (!ids && !can2) return false;
@@ -34363,7 +34515,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34363
34515
  return true;
34364
34516
  }
34365
34517
  function assembleVegetation(groups) {
34366
- const V3 = shared2.ctx.veg;
34518
+ const V3 = shared3.ctx.veg;
34367
34519
  if (!V3) return;
34368
34520
  let pl = 0, tri = 0;
34369
34521
  const col = [], lod = [0, 0, 0], mats = V3.mats();
@@ -34386,18 +34538,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34386
34538
  for (const c of lot.colliders) col.push(Object.assign({ y: G.y, group: G.group }, c));
34387
34539
  for (let i = 0; i < 3; i++) lod[i] += lot.lodCounts[i];
34388
34540
  }
34389
- shared2.ctx.vegInfo = { plants: pl, triangles: tri, colliders: col, lodCounts: lod, materials: mats };
34541
+ shared3.ctx.vegInfo = { plants: pl, triangles: tri, colliders: col, lodCounts: lod, materials: mats };
34390
34542
  }
34391
34543
  const defined = { VEG_POT, VEG_CACTUS, VEG_MAP, VEG_PLANTER, vegItem, assembleVegetation };
34392
34544
  Object.assign(K, defined);
34393
34545
  }
34394
- function installInteractionState(K, shared2) {
34546
+ function installInteractionState(K, shared3) {
34395
34547
  const { THREE, cfg, colliderChanged, invalidateShadow, invalidate, UV_SCALE, applyPart, texture } = K;
34396
34548
  const ivRoomEffective = (...a) => K.ivRoomEffective(...a);
34397
34549
  const ivRoomLight = (...a) => K.ivRoomLight(...a);
34398
- shared2.partState = /* @__PURE__ */ new Map();
34550
+ shared3.partState = /* @__PURE__ */ new Map();
34399
34551
  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 });
34400
- shared2.inter = newInteractiveState();
34552
+ shared3.inter = newInteractiveState();
34401
34553
  const MESSAGE_MS = 2200;
34402
34554
  UV_SCALE.doorWood = 1;
34403
34555
  UV_SCALE.doorPaint = 1;
@@ -34452,15 +34604,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34452
34604
  }
34453
34605
  const _EY = new THREE.Vector3(0, 1, 0), _UM3 = new THREE.Vector3(1, 1, 1);
34454
34606
  const hudMessage = (text) => {
34455
- shared2.inter.msg = { text, until: performance.now() + MESSAGE_MS };
34607
+ shared3.inter.msg = { text, until: performance.now() + MESSAGE_MS };
34456
34608
  if (cfg.onMessage) cfg.onMessage(text);
34457
34609
  };
34458
- const I = () => shared2.inter;
34610
+ const I = () => shared3.inter;
34459
34611
  function definePiece(name, definition) {
34460
34612
  const def = definition;
34461
34613
  def.name = name;
34462
34614
  def.meshes = [];
34463
- def.t = def.target = shared2.partState.has(name) ? shared2.partState.get(name) : def.t0 || 0;
34615
+ def.t = def.target = shared3.partState.has(name) ? shared3.partState.get(name) : def.t0 || 0;
34464
34616
  I().defs.set(name, def);
34465
34617
  I().pieces.push(def);
34466
34618
  return def;
@@ -34561,20 +34713,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34561
34713
  }
34562
34714
  function togglePiece(p) {
34563
34715
  p.target = p.target > 0.5 ? 0 : 1;
34564
- shared2.partState.set(p.name, p.target);
34716
+ shared3.partState.set(p.name, p.target);
34565
34717
  if (p.col && p.col.off !== p.target > 0.5) {
34566
34718
  p.col.off = p.target > 0.5;
34567
34719
  colliderChanged(p.col);
34568
34720
  }
34569
34721
  I().anim.add(p);
34570
34722
  }
34571
- const lightBase = (roomId) => roomId == null ? true : shared2.partState.has("light:" + roomId) ? !!shared2.partState.get("light:" + roomId) : !!shared2.ctx.night;
34723
+ const lightBase = (roomId) => roomId == null ? true : shared3.partState.has("light:" + roomId) ? !!shared3.partState.get("light:" + roomId) : !!shared3.ctx.night;
34572
34724
  const lightOn = (roomId) => {
34573
- const S = roomId != null && shared2.ctx.iv && shared2.ctx.iv.roomStates.get(roomId);
34725
+ const S = roomId != null && shared3.ctx.iv && shared3.ctx.iv.roomStates.get(roomId);
34574
34726
  return S ? S.ef : lightBase(roomId);
34575
34727
  };
34576
34728
  function applyLight(roomId) {
34577
- const on = lightOn(roomId), inter = I(), mats = shared2.mats;
34729
+ const on = lightOn(roomId), inter = I(), mats = shared3.mats;
34578
34730
  for (const d of inter.lights.get(roomId) || []) for (const m of d.meshes) if (m.name.endsWith("/emissive")) m.material = on ? mats.emissive : mats.off;
34579
34731
  const sw = inter.defs.get("ix:int:" + roomId);
34580
34732
  if (sw) {
@@ -34584,9 +34736,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34584
34736
  invalidate();
34585
34737
  }
34586
34738
  function toggleLight(roomId) {
34587
- const S = shared2.ctx.iv && shared2.ctx.iv.roomStates.get(roomId);
34739
+ const S = shared3.ctx.iv && shared3.ctx.iv.roomStates.get(roomId);
34588
34740
  if (S) {
34589
- const IV = shared2.ctx.iv;
34741
+ const IV = shared3.ctx.iv;
34590
34742
  ivRoomLight(IV, roomId, !S.ef);
34591
34743
  const ef = ivRoomEffective(IV, S);
34592
34744
  if (ef !== S.ef) {
@@ -34596,15 +34748,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34596
34748
  }
34597
34749
  return;
34598
34750
  }
34599
- shared2.partState.set("light:" + roomId, !lightOn(roomId));
34751
+ shared3.partState.set("light:" + roomId, !lightOn(roomId));
34600
34752
  applyLight(roomId);
34601
34753
  if (cfg.onLight) cfg.onLight(roomId, lightOn(roomId));
34602
34754
  }
34603
34755
  const defined = { newInteractiveState, MESSAGE_MS, createInteractiveMaterials, _EY, _UM3, hudMessage, definePiece, localOf, visibleChain, assembleInteractive, applyPiece, DURATION, animateInteractive, togglePiece, lightBase, lightOn, applyLight, toggleLight };
34604
34756
  Object.assign(K, defined);
34605
34757
  }
34606
- function installInteractionCollision(K, shared2) {
34607
- const inter = () => shared2.inter;
34758
+ function installInteractionCollision(K, shared3) {
34759
+ const inter = () => shared3.inter;
34608
34760
  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)/;
34609
34761
  function registerCollision(m, M) {
34610
34762
  const h = m.h || 0, y = M.y || 0;
@@ -34632,7 +34784,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34632
34784
  function collideAt(x, z, floor2, opt) {
34633
34785
  opt = opt || {};
34634
34786
  const R = opt.radius != null ? opt.radius : 0.24;
34635
- for (const c of shared2.ctx.colliders) {
34787
+ for (const c of shared3.ctx.colliders) {
34636
34788
  if (c.off) continue;
34637
34789
  if (c.f !== -1 && c.f !== floor2) continue;
34638
34790
  if (c.f === -1 && floor2 !== 0) continue;
@@ -34645,12 +34797,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34645
34797
  const defined = { NO_COLLIDE, registerCollision, objectDistance, collideObject, collideAt };
34646
34798
  Object.assign(K, defined);
34647
34799
  }
34648
- function installInteractionItems(K, shared2) {
34800
+ function installInteractionItems(K, shared3) {
34649
34801
  const { t, LIGHTS, cursor, definePiece, localOf, registerCollision, togglePiece } = K;
34650
34802
  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)$/;
34651
34803
  const DRAWER_ITEM = /^(console_table|dresser|nightstand|vanity_table)$/;
34652
34804
  const LIGHT_TYPES = /* @__PURE__ */ new Set(["ceiling_light", "pendant", "chandelier", "track_spot", "hanging_plant"]);
34653
- const I = () => shared2.inter;
34805
+ const I = () => shared3.inter;
34654
34806
  function objectName(type, drawer) {
34655
34807
  return drawer ? "drawer" : /^wardrobe/.test(type) ? "wardrobe" : /fridge|refrig|freezer/.test(type) ? "fridge" : /pantry/.test(type) ? "pantry" : "cabinet";
34656
34808
  }
@@ -34671,7 +34823,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34671
34823
  }
34672
34824
  function lightItem(m, M, ent, api, parent) {
34673
34825
  M.on = M.light = M.lit = true;
34674
- const n0 = LIGHTS.length, name = shared2.quality === "game" ? "ix:light:" + m.room + "@" + parent : "ix:light:" + m.id;
34826
+ const n0 = LIGHTS.length, name = shared3.quality === "game" ? "ix:light:" + m.room + "@" + parent : "ix:light:" + m.id;
34675
34827
  cursor.group = name;
34676
34828
  try {
34677
34829
  ent.f(M, api);
@@ -34713,7 +34865,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34713
34865
  const al = first.target > 0.5 ? 0 : 1;
34714
34866
  for (const p of parts) {
34715
34867
  p.target = al;
34716
- shared2.partState.set(p.name, al);
34868
+ shared3.partState.set(p.name, al);
34717
34869
  I().anim.add(p);
34718
34870
  }
34719
34871
  } });
@@ -34803,10 +34955,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34803
34955
  const defined = { DOOR_ITEM, DRAWER_ITEM, LIGHT_TYPES, objectName, recordApi, buildItem: buildItem2, lightItem, curtainItem, furnitureItem };
34804
34956
  Object.assign(K, defined);
34805
34957
  }
34806
- function installInteractionFittings(K, shared2) {
34958
+ function installInteractionFittings(K, shared3) {
34807
34959
  const { t, EPS: EPS6, OPEN_AREA, Y0, applyPiece, bx, cursor, definePiece, gates, lightOn, roomAt, slideDirection, toggleLight, togglePiece } = K;
34808
- const I = () => shared2.inter;
34809
- const house = () => shared2.ctx.r;
34960
+ const I = () => shared3.inter;
34961
+ const house = () => shared3.ctx.r;
34810
34962
  function gatesInteractive() {
34811
34963
  const lt2 = house().lot;
34812
34964
  if (!lt2) return;
@@ -34830,7 +34982,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34830
34982
  }
34831
34983
  orig(mat, x0, y0, z0, x1, y1, z1, color2);
34832
34984
  });
34833
- const colliders = shared2.ctx.colliders, n0 = colliders.length;
34985
+ const colliders = shared3.ctx.colliders, n0 = colliders.length;
34834
34986
  try {
34835
34987
  gs.forEach((g) => {
34836
34988
  g.open = false;
@@ -34857,7 +35009,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34857
35009
  function mailboxInteractive() {
34858
35010
  for (const m of house().items) {
34859
35011
  if (m.type !== "mailbox") continue;
34860
- const g = shared2.ctx.parts && shared2.ctx.parts["mailbox_" + m.id];
35012
+ const g = shared3.ctx.parts && shared3.ctx.parts["mailbox_" + m.id];
34861
35013
  if (!g) continue;
34862
35014
  const name = "ix:correio:" + m.id, def = definePiece(name, { kind: "part", pivot: [0, 0, 0], ry: 0, parent: "lot" });
34863
35015
  def.inner = g;
@@ -34869,7 +35021,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34869
35021
  function placeSwitches() {
34870
35022
  const R = house(), used = /* @__PURE__ */ new Set();
34871
35023
  for (const c of R.rooms) {
34872
- if (c.type === "void" || OPEN_AREA(c) || !I().litRooms.has(c.id) || used.has(c.id) || shared2.ctx.iv && shared2.ctx.iv.switchRooms.has(c.id)) continue;
35024
+ if (c.type === "void" || OPEN_AREA(c) || !I().litRooms.has(c.id) || used.has(c.id) || shared3.ctx.iv && shared3.ctx.iv.switchRooms.has(c.id)) continue;
34873
35025
  const doors = R.doors.filter((p) => p.floor === c.floor && (p.a === c.id || p.b === c.id));
34874
35026
  doors.sort((p, q) => ((q.exterior ? 1 : 0) - (p.exterior ? 1 : 0)) * (c.type === "living" ? 1 : -1));
34875
35027
  for (const p of doors) if (putSwitch(c, p)) {
@@ -34914,11 +35066,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34914
35066
  const defined = { gatesInteractive, mailboxInteractive, placeSwitches, putSwitch };
34915
35067
  Object.assign(K, defined);
34916
35068
  }
34917
- function installInteractionDoors(K, shared2) {
35069
+ function installInteractionDoors(K, shared3) {
34918
35070
  const { t, colliderChanged, invalidateShadow, applyPiece, hudMessage } = K;
34919
- const leaves = () => shared2.ctx.leaves;
35071
+ const leaves = () => shared3.ctx.leaves;
34920
35072
  function linkDoorLeaves() {
34921
- const I = shared2.inter;
35073
+ const I = shared3.inter;
34922
35074
  for (const fo of leaves()) fo.handles = (fo.handleNames || []).map((n) => I.defs.get(n)).filter((d) => !!d);
34923
35075
  }
34924
35076
  function handleApply(fo) {
@@ -34932,7 +35084,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34932
35084
  const col = fo.col;
34933
35085
  if (fo.phase === "handle" || fo.phase === "swing") {
34934
35086
  fo.open = !fo.open;
34935
- shared2.doorState.set(fo.id, fo.open);
35087
+ shared3.doorState.set(fo.id, fo.open);
34936
35088
  col.off = fo.open;
34937
35089
  colliderChanged(col);
34938
35090
  fo.anim = true;
@@ -34942,23 +35094,23 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34942
35094
  if (fo.blockedFlag || fo.locked) {
34943
35095
  fo.phase = "rattle";
34944
35096
  fo.jig = 0.7;
34945
- shared2.ctx.animateDoorsOn = true;
35097
+ shared3.ctx.animateDoorsOn = true;
34946
35098
  hudMessage(t(fo.blockedFlag ? "message.boarded" : "message.locked"));
34947
35099
  return;
34948
35100
  }
34949
35101
  fo.open = !fo.open;
34950
- shared2.doorState.set(fo.id, fo.open);
35102
+ shared3.doorState.set(fo.id, fo.open);
34951
35103
  col.off = fo.open;
34952
35104
  colliderChanged(col);
34953
35105
  fo.anim = true;
34954
- shared2.ctx.animateDoorsOn = true;
35106
+ shared3.ctx.animateDoorsOn = true;
34955
35107
  if (fo.handles && fo.handles.length) {
34956
35108
  fo.phase = "handle";
34957
35109
  fo.hT = fo.hT || 0;
34958
35110
  } else fo.phase = "swing";
34959
35111
  }
34960
35112
  function animateDoors(dt) {
34961
- if (!shared2.ctx.animateDoorsOn) return;
35113
+ if (!shared3.ctx.animateDoorsOn) return;
34962
35114
  let active = false;
34963
35115
  for (const fo of leaves()) {
34964
35116
  if (!fo.phase) continue;
@@ -34990,11 +35142,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34990
35142
  }
34991
35143
  }
34992
35144
  }
34993
- shared2.ctx.animateDoorsOn = active;
35145
+ shared3.ctx.animateDoorsOn = active;
34994
35146
  invalidateShadow();
34995
35147
  }
34996
35148
  function wallBlocks(ex, ez, ax, az, floor2) {
34997
- const n = shared2.ctx.wallColliders != null ? shared2.ctx.wallColliders : 0, colliders = shared2.ctx.colliders;
35149
+ const n = shared3.ctx.wallColliders != null ? shared3.ctx.wallColliders : 0, colliders = shared3.ctx.colliders;
34998
35150
  for (let i = 0; i < n; i++) {
34999
35151
  const c = colliders[i];
35000
35152
  if (c.f !== floor2 && !(c.f === -1 && floor2 === 0)) continue;
@@ -35029,19 +35181,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35029
35181
  const defined = { linkDoorLeaves, handleApply, toggleDoor, animateDoors, wallBlocks, doorText, applyLeaf };
35030
35182
  Object.assign(K, defined);
35031
35183
  }
35032
- function installInteractionTarget(K, shared2) {
35184
+ function installInteractionTarget(K, shared3) {
35033
35185
  const { doorText, toggleDoor, visibleChain, wallBlocks } = K;
35034
35186
  const ivTarget = (...a) => K.ivTarget(...a);
35035
35187
  function targetOf(o, opt) {
35036
35188
  if (!o) return null;
35037
35189
  opt = opt || {};
35038
- const I = shared2.inter;
35190
+ const I = shared3.inter;
35039
35191
  const ex = o.x, ey = o.y, ez = o.z, floor2 = o.floor, cp = Math.cos(o.pitch || 0), vx2 = Math.sin(o.yaw) * cp, vy2 = Math.sin(o.pitch || 0), vz2 = Math.cos(o.yaw) * cp;
35040
35192
  let best = null;
35041
35193
  const tries = (score, text, action, target) => {
35042
35194
  if (!best || score < best.score) best = { score, text, action, target };
35043
35195
  };
35044
- for (const fo of shared2.ctx.leaves) {
35196
+ for (const fo of shared3.ctx.leaves) {
35045
35197
  if (fo.floor !== floor2) continue;
35046
35198
  const d = Math.hypot(fo.cx - ex, fo.cz - ez);
35047
35199
  if (d > 1.7) continue;
@@ -35050,7 +35202,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35050
35202
  tries(angle * 1.6 + d * 0.5 + (angle < 0.25 ? 0 : 0.6), doorText(fo), () => toggleDoor(fo), fo);
35051
35203
  }
35052
35204
  const vis = I.pieces.flatMap((p) => p.meshes).filter(visibleChain), hit = vis.length && opt.strike ? opt.strike(vis) : null;
35053
- const kitA = shared2.ctx.iv ? ivTarget(shared2.ctx.iv, o, opt && opt.interactives) : null;
35205
+ const kitA = shared3.ctx.iv ? ivTarget(shared3.ctx.iv, o, opt && opt.interactives) : null;
35054
35206
  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;
35055
35207
  const pieceHit = hit && !nearKit && hit.object.userData.piece;
35056
35208
  for (const it of I.items) {
@@ -35069,14 +35221,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35069
35221
  const defined = { targetOf };
35070
35222
  Object.assign(K, defined);
35071
35223
  }
35072
- function installInteractablesBridge(K, shared2) {
35224
+ function installInteractablesBridge(K, shared3) {
35073
35225
  const { t, THREE, invalidate, invalidateShadow, cfg, DOC, LIGHT_TYPES, _Y, _q, _v3, accFor, applyLight, cursor, hashString, hudMessage, lightBase, pieceRecord, put, rgbOf, sh, wallBlocks } = K;
35074
35226
  const enter = (...a) => K.enter(...a);
35075
35227
  const roomLightMask = (...a) => K.roomLightMask(...a);
35076
35228
  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" };
35077
35229
  const IV_WIRE = { conduit: 13618628, cable: 2762532, drop: 1381653, cord: 1776413, earth: 3111482, hose: 11556124 };
35078
35230
  const IV_DOOR = /^(door|drawer)/;
35079
- const ivGroup = (e) => e.floor < 0 ? "lot" : "f" + Math.min(e.floor, shared2.ctx.r.floors.length - 1);
35231
+ const ivGroup = (e) => e.floor < 0 ? "lot" : "f" + Math.min(e.floor, shared3.ctx.r.floors.length - 1);
35080
35232
  function ivAccumulate(mat, g, ox, oy, oz, ry, color2) {
35081
35233
  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;
35082
35234
  const A = accFor(mat);
@@ -35120,7 +35272,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35120
35272
  A.ni += ni;
35121
35273
  }
35122
35274
  function ivBuild(h, water) {
35123
- const ik = K.IVK, r = shared2.ctx.r, A = ik.A, world0 = null;
35275
+ const ik = K.IVK, r = shared3.ctx.r, A = ik.A, world0 = null;
35124
35276
  void world0;
35125
35277
  const source = r;
35126
35278
  const plane2 = A.plan(source, { seed: r.seed });
@@ -35142,8 +35294,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35142
35294
  const wants = (roomId) => lightBase(roomId);
35143
35295
  const entById = new Map(plane2.items.map((e) => [e.id, e]));
35144
35296
  const entByItem = new Map(plane2.items.map((e) => [e.item, e]));
35145
- const mats = shared2.mats;
35146
- IV.mats = { plain: 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 };
35297
+ const mats = shared3.mats;
35298
+ IV.mats = { plain: mats.plain, metal: shared3.mats.metal, wood: shared3.mats.wood, glass: shared3.mats.glass, fabric: shared3.mats.fabric, plant: shared3.mats.plant, water: shared3.mats.water, emissive: shared3.mats.emissive, atlas_picture: shared3.mats.picture, atlas_floor: shared3.mats.floor };
35147
35299
  const ev = (e) => ivEvent(h, e);
35148
35300
  const world = IV.world = A.createWorld(source, { water, seed: r.seed, onEvent: ev });
35149
35301
  const add0 = world.add;
@@ -35151,7 +35303,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35151
35303
  const e = entById.get(id);
35152
35304
  if (e && e.type === "lamp") {
35153
35305
  const roomId = IV.lampRoom.get(id);
35154
- spec.devices[0].on = roomId ? wants(roomId) : !!shared2.ctx.night;
35306
+ spec.devices[0].on = roomId ? wants(roomId) : !!shared3.ctx.night;
35155
35307
  spec.parts = (spec.parts || []).concat([{ id: "_x", pivot: [0, 0, 0], motion: { kind: "slide", axis: [0, 1, 0], distance: 1e-3 }, label: "" }]);
35156
35308
  spec.interactions = [{ id: "device.lamp", pos: [0, 0, 0], action: { do: "toggle_device", device: "lamp" }, label: "", requires: { object: id, part: "_x" } }];
35157
35309
  } else if (e && e.type === "wall_switch") {
@@ -35177,7 +35329,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35177
35329
  }
35178
35330
  if (e.type === "lamp" && o.devices && o.devices.lamp) {
35179
35331
  const roomId = IV.lampRoom.get(id);
35180
- o.devices.lamp.on = roomId ? wants(roomId) : !!shared2.ctx.night;
35332
+ o.devices.lamp.on = roomId ? wants(roomId) : !!shared3.ctx.night;
35181
35333
  } else if (e.type === "wall_switch" && o.parts && o.parts.rocker !== void 0) {
35182
35334
  const l = (e.connections.controls || [])[0], roomId = l && IV.lampRoom.get(l);
35183
35335
  if (roomId) o.parts.rocker = wants(roomId) ? 1 : 0;
@@ -35270,7 +35422,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35270
35422
  const ik = IV.k, w = IV.world, wl = (o, p) => ik.GI.localToWorld(o.transform, p), g0 = cursor.group;
35271
35423
  const tube2 = (pts, radius, color2, ox, oy, oz, ry) => {
35272
35424
  try {
35273
- const m = ik.gfx.createCord(pts, radius, shared2.mats.plain);
35425
+ const m = ik.gfx.createCord(pts, radius, shared3.mats.plain);
35274
35426
  ivAccumulate("plain", m.geometry, ox, oy, oz, ry, color2);
35275
35427
  m.geometry.dispose();
35276
35428
  } catch (e) {
@@ -35313,7 +35465,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35313
35465
  for (const E of IV.roots) {
35314
35466
  (gs[E.group] || (gs[E.group] = new THREE.Group())).add(E.root);
35315
35467
  }
35316
- for (const [roomId] of IV.roomStates) if (!shared2.inter.litRooms.has(roomId)) IV.roomStates.delete(roomId);
35468
+ for (const [roomId] of IV.roomStates) if (!shared3.inter.litRooms.has(roomId)) IV.roomStates.delete(roomId);
35317
35469
  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 });
35318
35470
  for (const E of IV.entries.values()) if (E.screen) ivScreen(IV, E);
35319
35471
  }
@@ -35345,7 +35497,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35345
35497
  break;
35346
35498
  case "device": {
35347
35499
  const roomId = IV.lampRoom.get(e.object);
35348
- if (roomId) shared2.partState.set("light:" + roomId, !!e.on);
35500
+ if (roomId) shared3.partState.set("light:" + roomId, !!e.on);
35349
35501
  invalidate();
35350
35502
  break;
35351
35503
  }
@@ -35501,7 +35653,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35501
35653
  gm.setIndex(new THREE.BufferAttribute(A.i.slice(0, A.ni), 1));
35502
35654
  gm.computeBoundingSphere();
35503
35655
  if (!IV.items) {
35504
- const mesh3 = new THREE.Mesh(gm, shared2.mats.plain);
35656
+ const mesh3 = new THREE.Mesh(gm, shared3.mats.plain);
35505
35657
  IV.items = mesh3;
35506
35658
  mesh3.name = "iv-items";
35507
35659
  mesh3.castShadow = false;
@@ -35644,17 +35796,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35644
35796
  const defined = { 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 };
35645
35797
  Object.assign(K, defined);
35646
35798
  }
35647
- function installAnimationClotheslines(K, shared2) {
35799
+ function installAnimationClotheslines(K, shared3) {
35648
35800
  const { invalidate, CLOTHES_UNIFORMS } = K;
35649
35801
  const WIND = { t0: performance.now(), last: 0, base: 0.55 };
35650
35802
  function animateClotheslines(now) {
35651
- if (!shared2.ctx.clotheslines || !shared2.ctx.clotheslines.length) return;
35803
+ if (!shared3.ctx.clotheslines || !shared3.ctx.clotheslines.length) return;
35652
35804
  if (now - WIND.last < 33) return;
35653
35805
  WIND.last = now;
35654
35806
  const t = (now - WIND.t0) / 1e3;
35655
35807
  CLOTHES_UNIFORMS.uTime.value = t;
35656
35808
  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));
35657
- const g = shared2.ctx.parts && shared2.ctx.parts["laundry_" + shared2.ctx.clotheslines[0]];
35809
+ const g = shared3.ctx.parts && shared3.ctx.parts["laundry_" + shared3.ctx.clotheslines[0]];
35658
35810
  if (g) {
35659
35811
  let vis = true;
35660
35812
  for (let n = g; n; n = n.parent) if (!n.visible) {
@@ -35668,31 +35820,31 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35668
35820
  const defined = { WIND, animateClotheslines };
35669
35821
  Object.assign(K, defined);
35670
35822
  }
35671
- function installBuildInstance(K, shared2) {
35823
+ function installBuildInstance(K, shared3) {
35672
35824
  const { PROPS, THREE, DOC, cfg, HP, createInteractiveMaterials, createMaterials: createMaterials2, typeTable } = K;
35673
35825
  const props = PROPS.create(THREE, { document: DOC, emit: () => {
35674
35826
  } });
35675
35827
  const TYPES = typeTable(props);
35676
- shared2.mats = createMaterials2(props);
35677
- createInteractiveMaterials(shared2.mats);
35828
+ shared3.mats = createMaterials2(props);
35829
+ createInteractiveMaterials(shared3.mats);
35678
35830
  if (cfg.materials) for (const k of Object.keys(cfg.materials)) {
35679
35831
  const v = cfg.materials[k];
35680
- shared2.mats[k] = typeof v === "function" ? v(shared2.mats[k], k) || shared2.mats[k] : v;
35832
+ shared3.mats[k] = typeof v === "function" ? v(shared3.mats[k], k) || shared3.mats[k] : v;
35681
35833
  }
35682
35834
  const newState = () => ({ doors: /* @__PURE__ */ new Map(), inter: /* @__PURE__ */ new Map(), water: null, iv: null });
35683
35835
  function enter(h) {
35684
- shared2.ctx = h.ctx;
35685
- shared2.inter = h.inter;
35686
- shared2.doorState = h.state.doors;
35687
- shared2.partState = h.state.inter;
35688
- shared2.mirrors = h.mirrors;
35689
- shared2.quality = h.quality;
35836
+ shared3.ctx = h.ctx;
35837
+ shared3.inter = h.inter;
35838
+ shared3.doorState = h.state.doors;
35839
+ shared3.partState = h.state.inter;
35840
+ shared3.mirrors = h.mirrors;
35841
+ shared3.quality = h.quality;
35690
35842
  }
35691
35843
  const tagDamage = (type) => ({ type, hp: HP[type], hpMax: HP[type] });
35692
35844
  const defined = { props, TYPES, newState, enter, tagDamage };
35693
35845
  Object.assign(K, defined);
35694
35846
  }
35695
- function installInteractablesKit(K, shared2) {
35847
+ function installInteractablesKit(K, shared3) {
35696
35848
  const { t, THREE, DOC, cfg, Reflector } = K;
35697
35849
  const roomLightMask = (...a) => K.roomLightMask(...a);
35698
35850
  const IVK = (() => {
@@ -35710,8 +35862,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35710
35862
  const l = cfg.vegetation || null, G = l && (l.GameVegetation || (l.buildLot ? l : null)), S = l && (l.GameVegetationSpecies || (l.toSpec ? l : null));
35711
35863
  return G && S && G.buildLot && S.toSpec ? { G, S } : null;
35712
35864
  })();
35713
- shared2.vegMaterials = null;
35714
- const vegMaterials = () => shared2.vegMaterials || (shared2.vegMaterials = (() => {
35865
+ shared3.vegMaterials = null;
35866
+ const vegMaterials = () => shared3.vegMaterials || (shared3.vegMaterials = (() => {
35715
35867
  const m = VEG.G.createVegetationMaterials(THREE);
35716
35868
  for (const k of ["wood", "foliage", "flowers", "fruit", "spines"]) roomLightMask(m[k]);
35717
35869
  return m;
@@ -35720,7 +35872,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35720
35872
  Object.assign(K, defined);
35721
35873
  }
35722
35874
  var newGroup = (k, house, exterior) => ({ k, house, ls: [], exterior, pos: [0, 0, 0], color: 0, n: 0, range: 0, rects: [], y: [0, 0], exclusion: null, lumens: 0, dist: 0, decay: 0, floor: 0, roomId: null, dm: 0, d: 0 });
35723
- function installLightsRoomLight(K, shared2) {
35875
+ function installLightsRoomLight(K, shared3) {
35724
35876
  const { THREE, rectsOf: rectsOf2, cfg } = K;
35725
35877
  const MAX_LIGHTS = 12, EMPTY = [1e9, 1e9, -1e9, -1e9];
35726
35878
  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 } };
@@ -35760,7 +35912,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35760
35912
  function lighting(options) {
35761
35913
  const o = options || {};
35762
35914
  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;
35763
- const mats = shared2.mats;
35915
+ const mats = shared3.mats;
35764
35916
  for (const k of Object.keys(mats)) roomLightMask(mats[k]);
35765
35917
  const budget = o.budget, lease = budget ? budget.lease({ owner: "floorplan.rooms", point: N, shadows: NS }) : null;
35766
35918
  if (budget && !lease) throw new Error("lighting: the LightBudget has no " + N + " free point slots (" + NS + " with shadow) for the rooms");
@@ -36086,9 +36238,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
36086
36238
  }
36087
36239
  return view;
36088
36240
  }
36089
- function installDestructionPieces(K, shared2) {
36241
+ function installDestructionPieces(K, shared3) {
36090
36242
  const { THREE, floorAtY, pieceRecord } = K;
36091
- shared2.destructionSeq = 0;
36243
+ shared3.destructionSeq = 0;
36092
36244
  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 };
36093
36245
  const FRAGMENT_GEO = new THREE.BoxGeometry(1, 1, 1), FRAGMENT_MAT = {};
36094
36246
  const fragmentMaterial = (m) => FRAGMENT_MAT[m] || (FRAGMENT_MAT[m] = new THREE.MeshLambertMaterial({ color: FRAGMENT_COLOR[m] != null ? FRAGMENT_COLOR[m] : 9079428 }));
@@ -36097,7 +36249,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
36097
36249
  objs = objs.filter(Boolean);
36098
36250
  if (!objs.length) return;
36099
36251
  const pc = pieceRecord(id, mat, role, extra);
36100
- shared2.ctx.pieceObjects.set(id, objs);
36252
+ shared3.ctx.pieceObjects.set(id, objs);
36101
36253
  for (const o of objs) o.traverse((m) => {
36102
36254
  if (!m.isMesh) return;
36103
36255
  const u = m.userData;
@@ -36108,22 +36260,22 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
36108
36260
  if (pc.explodes) u.destructionExplodes = pc.explodes;
36109
36261
  });
36110
36262
  };
36111
- for (const fo of shared2.ctx.leaves) {
36263
+ for (const fo of shared3.ctx.leaves) {
36112
36264
  const pr = r.doors.find((p) => p.id === fo.id);
36113
36265
  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"] });
36114
36266
  }
36115
36267
  const cap = r.utilities.plumbing ? +r.utilities.plumbing.capacityL || 0 : 0;
36116
- for (const [id, g] of Object.entries(shared2.ctx.parts || {})) {
36268
+ for (const [id, g] of Object.entries(shared3.ctx.parts || {})) {
36117
36269
  const tp = g.userData.part;
36118
36270
  if (tp === "water_tank") {
36119
- const e = shared2.ctx.structureIndex.water_tank, L = cap || (g.userData.volume ? Math.round(g.userData.volume * 1e3) : 0);
36271
+ const e = shared3.ctx.structureIndex.water_tank, L = cap || (g.userData.volume ? Math.round(g.userData.volume * 1e3) : 0);
36120
36272
  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"] });
36121
36273
  } 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"] });
36122
36274
  else if (tp === "wall_pipe") tagObject(id, [g], "plastic", null, { mass: 3, tags: ["pipe"] });
36123
36275
  else if (tp === "shower_door") tagObject(id, [g], "tempered_glass", null, { mass: 25 });
36124
36276
  else if (tp === "gate_leaf" || tp === "mailbox_door") tagObject(id, [g], "steel", null, { mass: 30 });
36125
36277
  }
36126
- for (const def of shared2.inter.defs.values()) {
36278
+ for (const def of shared3.inter.defs.values()) {
36127
36279
  if (!def.outer) continue;
36128
36280
  if (/^gate/.test(def.kind)) tagObject(def.name, [def.outer], "steel", null, { mass: 80, tags: ["gate"] });
36129
36281
  else if (def.kind === "swing" || def.kind === "drawer") tagObject(def.name, [def.outer], "mdf", null, { mass: 6 });
@@ -36143,13 +36295,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
36143
36295
  for (const f of o.userData.ranges) add2(f.id, { mesh: o, v0: f.v0, v1: f.v1, i0: f.i0, i1: f.i1, whole: f.v0 === 0 && f.v1 === nv });
36144
36296
  }
36145
36297
  });
36146
- for (const [id, objs] of shared2.ctx.pieceObjects) for (const o of objs) add2(id, { obj: o });
36298
+ for (const [id, objs] of shared3.ctx.pieceObjects) for (const o of objs) add2(id, { obj: o });
36147
36299
  const box32 = (id) => {
36148
36300
  const b = new THREE.Box3(), v = new THREE.Vector3();
36149
36301
  for (const it of meshes.get(id) || []) {
36150
36302
  if (it.obj) {
36151
36303
  const bb = new THREE.Box3().setFromObject(it.obj);
36152
- 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));
36304
+ 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(shared3.ctx.unitInverse));
36153
36305
  } else {
36154
36306
  const P = it.mesh.geometry.attributes.position.array;
36155
36307
  for (let k = it.v0; k < it.v1; k++) b.expandByPoint(v.set(P[k * 3], P[k * 3 + 1], P[k * 3 + 2]));
@@ -36159,21 +36311,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
36159
36311
  };
36160
36312
  const parts = [], byId = /* @__PURE__ */ new Map(), supports = E0.supports.map((a) => Object.assign({}, a));
36161
36313
  for (const e of E0.parts) {
36162
- const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared2.ctx.pieces.get(e.id);
36314
+ const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared3.ctx.pieces.get(e.id);
36163
36315
  if (pc) {
36164
36316
  for (const k of ["contains", "explodes", "tags", "form", "thickness", "fill"]) if (pc[k] != null && p[k] == null) p[k] = pc[k];
36165
36317
  }
36166
36318
  parts.push(p);
36167
36319
  byId.set(p.id, p);
36168
36320
  }
36169
- const base = parts.length, view = shared2.ctx.panelView || panelViewOf(null, false), panelIds = new Set(view.panels.map((e) => e.id));
36170
- for (const [id, pc] of shared2.ctx.pieces) {
36321
+ const base = parts.length, view = shared3.ctx.panelView || panelViewOf(null, false), panelIds = new Set(view.panels.map((e) => e.id));
36322
+ for (const [id, pc] of shared3.ctx.pieces) {
36171
36323
  if (byId.has(id) || panelIds.has(id) || !meshes.has(id)) continue;
36172
36324
  const b = box32(id);
36173
36325
  if (!b) continue;
36174
36326
  const vol = Math.max(1e-6, (b[3] - b[0]) * (b[4] - b[1]) * (b[5] - b[2]));
36175
36327
  const p = { id, role: "none", material: pc.mat, aabb: [b[0], b[2], b[3], b[5]], y0: b[1], y1: b[4], floor: pc.floor != null ? pc.floor : floorAtY(b[1] + 0.1), mass: pc.mass != null ? pc.mass : Math.max(0.5, vol * (DENSITY[pc.mat] || 800) * (pc.fill != null ? pc.fill : 0.15)), meshes: meshes.get(id).length, extra: true };
36176
- for (const k of ["contains", "explodes", "tags", "form", "thickness", "fill"]) if (pc[k] != null) p[k] = pc[k];
36328
+ for (const k of ["contains", "explodes", "tags", "form", "thickness", "fill", "units"]) if (pc[k] != null) p[k] = pc[k];
36177
36329
  parts.push(p);
36178
36330
  byId.set(id, p);
36179
36331
  }
@@ -36182,7 +36334,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
36182
36334
  return cx >= q.aabb[0] - m && cx <= q.aabb[2] + m && cz >= q.aabb[1] - m && cz <= q.aabb[3] + m && cy >= q.y0 - m && cy <= q.y1 + m;
36183
36335
  };
36184
36336
  for (const p of parts.slice(base)) {
36185
- if (!/^(window|window_pane|door|jamb|pipe|water_tank)/.test(p.id)) continue;
36337
+ if (/^sidewalk:/.test(p.id)) {
36338
+ supports.push({ part: p.id, on: "ground", joint: "mortar", extra: true });
36339
+ continue;
36340
+ }
36341
+ if (!/^(window|window_pane|door|jamb|pipe|water_tank|baseboard)/.test(p.id)) continue;
36186
36342
  const target = /^water_tank/.test(p.id) ? ["slab"] : ["wall", "partition"];
36187
36343
  let m = null, md = 1e9;
36188
36344
  for (const q of parts.slice(0, base)) {
@@ -36193,7 +36349,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
36193
36349
  m = q;
36194
36350
  }
36195
36351
  }
36196
- if (m) supports.push({ part: p.id, on: m.id, joint: /^(window|jamb)/.test(p.id) ? "glue" : "clip", bears: false, extra: true });
36352
+ if (m) supports.push({ part: p.id, on: m.id, joint: /^(window|jamb|baseboard)/.test(p.id) ? "glue" : "clip", bears: false, extra: true });
36197
36353
  }
36198
36354
  const specParts = parts.slice(), specSupports = supports.slice();
36199
36355
  if (view.panels.length) {
@@ -36201,7 +36357,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
36201
36357
  parts.splice(0, parts.length, ...parts.filter((p) => !gone.has(p.id)));
36202
36358
  for (const id of gone) byId.delete(id);
36203
36359
  for (const e of view.panels) {
36204
- const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared2.ctx.pieces.get(e.id);
36360
+ const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared3.ctx.pieces.get(e.id);
36205
36361
  if (pc) {
36206
36362
  for (const k of ["contains", "explodes", "tags", "form", "thickness", "fill"]) if (pc[k] != null && p[k] == null) p[k] = pc[k];
36207
36363
  }
@@ -36864,7 +37020,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
36864
37020
  Object.assign(K, { createBreachView, breachPaintQueue: paintQueue });
36865
37021
  }
36866
37022
  var FOLLOW_FLUSH_FALLBACK_MS = 100;
36867
- function installDestructionWorld(K, shared2) {
37023
+ function installDestructionWorld(K, shared3) {
36868
37024
  const { THREE, cfg, invalidateShadow, invalidate, rngString, FRAGMENT_GEO, fragmentMaterial, createBreachView } = K;
36869
37025
  function createHouseDestruction(root, house, structure, parts, colliders, water) {
36870
37026
  const D = { world: cfg.destruction || null, id: null, active: false }, hiddenPieces = /* @__PURE__ */ new Set(), bodies = /* @__PURE__ */ new Map(), frags = [], facets = /* @__PURE__ */ new Map();
@@ -37100,7 +37256,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37100
37256
  house.matrixWorld.decompose(p, q, sc);
37101
37257
  D.specOptions = specOptions || null;
37102
37258
  D.spec = structure.spec(specOptions);
37103
- 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] });
37259
+ D.id = D.world.add(D.spec, { id: "house3d:" + ++shared3.destructionSeq, position: [p.x, p.y, p.z], rotation: [q.x, q.y, q.z, q.w] });
37104
37260
  breach.claim();
37105
37261
  if (R) R.bind(D.id, house, { parts: rangesOf(), onFrame: () => breach.flush() });
37106
37262
  off = D.world.on("*", handleEvent);
@@ -37248,7 +37404,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37248
37404
  }
37249
37405
  Object.assign(K, { createHouseDestruction });
37250
37406
  }
37251
- function installBuildBuild(K, shared2) {
37407
+ function installBuildBuild(K, shared3) {
37252
37408
  const { THREE, cfg, rectsOf: rectsOf2, invalidateShadow, colliderChanged, VERSION: VERSION2, CARS, EPS: EPS6, 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;
37253
37409
  function build(r0, options) {
37254
37410
  const opts = options || {};
@@ -37259,44 +37415,45 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37259
37415
  cursor.accs.clear();
37260
37416
  LIGHTS.length = 0;
37261
37417
  const pr = opts.building || {};
37262
- shared2.ctx.r = r;
37263
- shared2.ctx.colors = r.colors;
37264
- shared2.ctx.cut = !!opts.cut;
37265
- shared2.ctx.night = !!opts.night;
37266
- shared2.ctx.labels = [];
37267
- shared2.ctx.colliders = [];
37268
- shared2.ctx.stairs = [];
37269
- shared2.ctx.noTerrain = opts.terrain === false;
37270
- shared2.ctx.roomById = {};
37271
- for (const c of r.rooms) shared2.ctx.roomById[c.id] = c;
37272
- shared2.ctx.pieces = /* @__PURE__ */ new Map();
37273
- shared2.ctx.pieceObjects = /* @__PURE__ */ new Map();
37274
- shared2.ctx.structureIndex = {};
37275
- for (const e of r0.structure?.parts || []) shared2.ctx.structureIndex[e.id] = e;
37418
+ shared3.ctx.r = r;
37419
+ shared3.ctx.colors = r.colors;
37420
+ shared3.ctx.cut = !!opts.cut;
37421
+ shared3.ctx.night = !!opts.night;
37422
+ shared3.ctx.labels = [];
37423
+ shared3.ctx.colliders = [];
37424
+ shared3.ctx.stairs = [];
37425
+ shared3.ctx.noTerrain = opts.terrain === false;
37426
+ shared3.ctx.roomById = {};
37427
+ for (const c of r.rooms) shared3.ctx.roomById[c.id] = c;
37428
+ shared3.ctx.pieces = /* @__PURE__ */ new Map();
37429
+ shared3.ctx.pieceObjects = /* @__PURE__ */ new Map();
37430
+ shared3.ctx.structureIndex = {};
37431
+ for (const e of r0.structure?.parts || []) shared3.ctx.structureIndex[e.id] = e;
37276
37432
  {
37277
- const view = shared2.ctx.panelView = panelViewOf(r0.structure, !!cfg.destruction);
37278
- shared2.ctx.panelsOf = /* @__PURE__ */ new Map();
37279
- for (const id of view.replaced) delete shared2.ctx.structureIndex[id];
37433
+ const view = shared3.ctx.panelView = panelViewOf(r0.structure, !!cfg.destruction);
37434
+ shared3.ctx.panelsOf = /* @__PURE__ */ new Map();
37435
+ for (const id of view.replaced) delete shared3.ctx.structureIndex[id];
37280
37436
  for (const e of view.panels) {
37281
- shared2.ctx.structureIndex[e.id] = e;
37282
- const l = shared2.ctx.panelsOf.get(e.slab);
37437
+ shared3.ctx.structureIndex[e.id] = e;
37438
+ const l = shared3.ctx.panelsOf.get(e.slab);
37283
37439
  if (l) l.push(e);
37284
- else shared2.ctx.panelsOf.set(e.slab, [e]);
37440
+ else shared3.ctx.panelsOf.set(e.slab, [e]);
37285
37441
  }
37286
37442
  }
37287
- shared2.ctx.panes = r0.roof?.panes || [];
37288
- shared2.ctx.noPiece = false;
37443
+ shared3.ctx.panes = r0.roof?.panes || [];
37444
+ shared3.ctx.noPiece = false;
37289
37445
  cursor.separate = opts.pieces === "meshes";
37290
37446
  cursor.pc = null;
37291
- shared2.ctx.showPillars = opts.pillars !== "hidden";
37292
- shared2.ctx.apartment = r.template === "apartment_modern";
37293
- shared2.ctx.pa = Math.max(3, Math.min(20, pr.floors != null ? pr.floors : 5));
37294
- shared2.ctx.pf = Math.max(1, Math.min(shared2.ctx.pa, pr.floor != null ? pr.floor : 3));
37295
- shared2.ctx.pu = Math.max(0, pr.unit != null ? pr.unit : 0);
37296
- shared2.ctx.showBuilding = shared2.ctx.apartment && (pr.showIt == null ? true : !!pr.showIt);
37297
- shared2.ctx.limits = { x0: -2, z0: -2, x1: r.w + 2, z1: r.d + 2 };
37298
- 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" } : { quality: "high", lod: 0, triangleBudget: 6e4 } } : null;
37299
- shared2.ctx.vegInfo = null;
37447
+ shared3.ctx.showPillars = opts.pillars !== "hidden";
37448
+ shared3.ctx.baseboardBand = opts.baseboard === "band";
37449
+ shared3.ctx.apartment = r.template === "apartment_modern";
37450
+ shared3.ctx.pa = Math.max(3, Math.min(20, pr.floors != null ? pr.floors : 5));
37451
+ shared3.ctx.pf = Math.max(1, Math.min(shared3.ctx.pa, pr.floor != null ? pr.floor : 3));
37452
+ shared3.ctx.pu = Math.max(0, pr.unit != null ? pr.unit : 0);
37453
+ shared3.ctx.showBuilding = shared3.ctx.apartment && (pr.showIt == null ? true : !!pr.showIt);
37454
+ shared3.ctx.limits = { x0: -2, z0: -2, x1: r.w + 2, z1: r.d + 2 };
37455
+ shared3.ctx.veg = VEG ? { G: VEG.G, S: VEG.S, mats: vegMaterials, groups: /* @__PURE__ */ new Map(), ok: /* @__PURE__ */ new Map(), opts: shared3.quality === "game" ? { quality: "game" } : { quality: "high", lod: 0, triangleBudget: 6e4 } } : null;
37456
+ shared3.ctx.vegInfo = null;
37300
37457
  terrain();
37301
37458
  if (r.lot) {
37302
37459
  if (!opts.noPerimeter) {
@@ -37307,7 +37464,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37307
37464
  }
37308
37465
  walls();
37309
37466
  baseboardAndSidewalk();
37310
- shared2.ctx.wallColliders = shared2.ctx.colliders.length;
37467
+ shared3.ctx.wallColliders = shared3.ctx.colliders.length;
37311
37468
  doors();
37312
37469
  windows();
37313
37470
  floorsAndSlabs();
@@ -37315,14 +37472,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37315
37472
  buildStairs();
37316
37473
  elevator();
37317
37474
  const water = createWater(r, h.state);
37318
- shared2.ctx.iv = null;
37475
+ shared3.ctx.iv = null;
37319
37476
  h.IV = null;
37320
37477
  if (IVK) {
37321
37478
  try {
37322
- h.IV = shared2.ctx.iv = ivBuild(h, water);
37479
+ h.IV = shared3.ctx.iv = ivBuild(h, water);
37323
37480
  } catch (e) {
37324
37481
  console.warn("interactables", e);
37325
- shared2.ctx.iv = h.IV = null;
37482
+ shared3.ctx.iv = h.IV = null;
37326
37483
  }
37327
37484
  }
37328
37485
  const noModel = houseItems();
@@ -37331,14 +37488,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37331
37488
  electricalStructure();
37332
37489
  roofs();
37333
37490
  solar();
37334
- if (shared2.ctx.showBuilding) building();
37491
+ if (shared3.ctx.showBuilding) building();
37335
37492
  for (const c of r.rooms) {
37336
37493
  if (c.type === "void") continue;
37337
37494
  const [a, b, c2, d] = rectsOf2(c)[0];
37338
- 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 });
37495
+ shared3.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 });
37339
37496
  }
37340
- const mirrorsCopy = MIRRORS.map((E, i) => Object.assign({ i }, E)), gs = closeScene(shared2.mats);
37341
- for (const fo of shared2.ctx.leaves) {
37497
+ const mirrorsCopy = MIRRORS.map((E, i) => Object.assign({ i }, E)), gs = closeScene(shared3.mats);
37498
+ for (const fo of shared3.ctx.leaves) {
37342
37499
  const parent = gs["f" + fo.floor] || (gs["f" + fo.floor] = new THREE.Group());
37343
37500
  fo.gs = [];
37344
37501
  for (const gd of fo.groups) {
@@ -37351,22 +37508,22 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37351
37508
  }
37352
37509
  applyLeaf(fo);
37353
37510
  }
37354
- if (shared2.ctx.iv) ivAssemble(shared2.ctx.iv, gs);
37511
+ if (shared3.ctx.iv) ivAssemble(shared3.ctx.iv, gs);
37355
37512
  assembleInteractive(gs);
37356
37513
  linkDoorLeaves();
37357
37514
  mailboxInteractive();
37358
37515
  const root = markKitOrigin(new THREE.Group(), { owner: "game-floorplan-three", kind: "structure", id: r.template }), house = new THREE.Group();
37359
37516
  root.name = "house3d";
37360
37517
  root.add(house);
37361
- shared2.mirrors.house = house;
37362
- if (shared2.ctx.apartment) {
37363
- const units = r.building.units, u = units[Math.min(shared2.ctx.pu, units.length - 1)];
37364
- house.position.set(u.u, shared2.ctx.showBuilding ? 0 : -r.floors[0].y0, u.v);
37518
+ shared3.mirrors.house = house;
37519
+ if (shared3.ctx.apartment) {
37520
+ const units = r.building.units, u = units[Math.min(shared3.ctx.pu, units.length - 1)];
37521
+ house.position.set(u.u, shared3.ctx.showBuilding ? 0 : -r.floors[0].y0, u.v);
37365
37522
  house.rotation.y = u.ry;
37366
- shared2.ctx.unitRy = u.ry;
37523
+ shared3.ctx.unitRy = u.ry;
37367
37524
  }
37368
37525
  house.updateMatrixWorld(true);
37369
- shared2.ctx.unitInverse = house.matrixWorld.clone().invert();
37526
+ shared3.ctx.unitInverse = house.matrixWorld.clone().invert();
37370
37527
  for (const [k, g] of Object.entries(gs)) {
37371
37528
  g.name = k;
37372
37529
  (k === "floor" || k === "building" ? root : house).add(g);
@@ -37375,31 +37532,31 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37375
37532
  h.root = root;
37376
37533
  h.house = house;
37377
37534
  h.houseGroup = house;
37378
- shared2.ctx.noModel = noModel;
37379
- shared2.ctx.lights = LIGHTS.filter((l) => l.type !== "lantern" && l.type !== "candles" || shared2.ctx.night).map((l) => ({ ...l }));
37380
- shared2.ctx.animateDoorsOn = shared2.ctx.animateDoorsOn || false;
37381
- for (const c of shared2.ctx.colliders) {
37535
+ shared3.ctx.noModel = noModel;
37536
+ shared3.ctx.lights = LIGHTS.filter((l) => l.type !== "lantern" && l.type !== "candles" || shared3.ctx.night).map((l) => ({ ...l }));
37537
+ shared3.ctx.animateDoorsOn = shared3.ctx.animateDoorsOn || false;
37538
+ for (const c of shared3.ctx.colliders) {
37382
37539
  c.aabb = [c.x0, c.z0, c.x1, c.z1];
37383
37540
  if (c.type === "wall") c.damageable = tagDamage("masonry");
37384
37541
  }
37385
- 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 })));
37542
+ const colliders = shared3.ctx.colliders.concat(shared3.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 })));
37386
37543
  const parts = {}, setOpen = (def, t) => {
37387
37544
  def.target = t;
37388
37545
  def.t = t;
37389
- shared2.partState.set(def.name, t);
37546
+ shared3.partState.set(def.name, t);
37390
37547
  if (def.col) {
37391
37548
  def.col.off = t > 0.5;
37392
37549
  colliderChanged(def.col);
37393
37550
  }
37394
37551
  applyPiece(def);
37395
- shared2.inter.anim.delete(def);
37552
+ shared3.inter.anim.delete(def);
37396
37553
  invalidateShadow();
37397
37554
  };
37398
37555
  const mark = (o, id) => {
37399
37556
  if (o) o.userData.partId = id;
37400
37557
  };
37401
37558
  const PART_DAMAGE = { water_tank: "water", shower_door: "glass", gate_leaf: "metal", mailbox_door: "metal", mirror: "glass", cooking_gas_cylinder: "gas" };
37402
- for (const [id, g] of Object.entries(shared2.ctx.parts || {})) {
37559
+ for (const [id, g] of Object.entries(shared3.ctx.parts || {})) {
37403
37560
  const tp = g.userData.part, dn = PART_DAMAGE[tp];
37404
37561
  if (dn) g.userData.damageable = tagDamage(dn);
37405
37562
  mark(g, id);
@@ -37419,7 +37576,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37419
37576
  return g.userData.t || 0;
37420
37577
  }, meta: g.userData };
37421
37578
  }
37422
- for (const fo of shared2.ctx.leaves) {
37579
+ for (const fo of shared3.ctx.leaves) {
37423
37580
  const id = "door:" + fo.id, dn = tagDamage(fo.type === "steel" ? "metal" : "wood");
37424
37581
  fo.damageable = dn;
37425
37582
  for (const g of fo.gs) mark(g, id);
@@ -37431,14 +37588,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37431
37588
  fo.col.off = fo.open;
37432
37589
  colliderChanged(fo.col);
37433
37590
  }
37434
- shared2.doorState.set(fo.id, fo.open);
37591
+ shared3.doorState.set(fo.id, fo.open);
37435
37592
  applyLeaf(fo);
37436
37593
  invalidateShadow();
37437
37594
  }, get t() {
37438
37595
  return fo.t;
37439
37596
  }, leaf: fo };
37440
37597
  }
37441
- for (const def of shared2.inter.defs.values()) {
37598
+ for (const def of shared3.inter.defs.values()) {
37442
37599
  if (!def.outer) continue;
37443
37600
  const cab = def.kind === "swing" || def.kind === "drawer", gate = /^gate/.test(def.kind);
37444
37601
  const dn = cab ? tagDamage("wood") : gate ? tagDamage("metal") : null;
@@ -37448,7 +37605,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37448
37605
  return def.t;
37449
37606
  }, def };
37450
37607
  }
37451
- if (shared2.ctx.iv) ivParts(shared2.ctx.iv, parts, tagDamage);
37608
+ if (shared3.ctx.iv) ivParts(shared3.ctx.iv, parts, tagDamage);
37452
37609
  const cars = [];
37453
37610
  CARS.forEach((C, i) => {
37454
37611
  const mod2 = carModel(C.k, C.seed);
@@ -37489,18 +37646,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37489
37646
  const actOn = (e, a) => {
37490
37647
  enter(h);
37491
37648
  if (cfg.onInteract && cfg.onInteract(e, a) === false) return false;
37492
- shared2.inter.target = a || { target: e.ref, text: e.label, action: e._action };
37649
+ shared3.inter.target = a || { target: e.ref, text: e.label, action: e._action };
37493
37650
  e._action();
37494
37651
  return true;
37495
37652
  };
37496
- for (const fo of shared2.ctx.leaves) {
37653
+ for (const fo of shared3.ctx.leaves) {
37497
37654
  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() {
37498
37655
  return doorText(fo);
37499
37656
  }, ref: fo, _action: () => toggleDoor(fo) };
37500
37657
  e.act = () => actOn(e);
37501
37658
  interactables.push(e);
37502
37659
  }
37503
- for (const it of shared2.inter.items) {
37660
+ for (const it of shared3.inter.items) {
37504
37661
  const k = it.type + ":" + it.id, n = usedMap.get(k) || 0;
37505
37662
  usedMap.set(k, n + 1);
37506
37663
  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() {
@@ -37510,12 +37667,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37510
37667
  interactables.push(e);
37511
37668
  it.pub = e;
37512
37669
  }
37513
- for (const fo of shared2.ctx.leaves) fo.pub = interactables.find((e) => e.ref === fo);
37670
+ for (const fo of shared3.ctx.leaves) fo.pub = interactables.find((e) => e.ref === fo);
37514
37671
  const lodObjects = [];
37515
- 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);
37516
- for (const [id, g] of Object.entries(shared2.ctx.parts || {})) if (/^(handle|shower_door)$/.test(g.userData.part) && g.visible !== false) lodObjects.push(g);
37517
- if (shared2.ctx.iv) {
37518
- for (const E of shared2.ctx.iv.roots) lodObjects.push(E.root);
37672
+ for (const def of shared3.inter.defs.values()) if (def.outer && /^(light|drawer|swing|curtain|light_switch|handle)$/.test(def.kind)) lodObjects.push(def.outer);
37673
+ for (const [id, g] of Object.entries(shared3.ctx.parts || {})) if (/^(handle|shower_door)$/.test(g.userData.part) && g.visible !== false) lodObjects.push(g);
37674
+ if (shared3.ctx.iv) {
37675
+ for (const E of shared3.ctx.iv.roots) lodObjects.push(E.root);
37519
37676
  }
37520
37677
  const countDraw = () => {
37521
37678
  let n = 0, t = 0;
@@ -37533,7 +37690,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37533
37690
  for (const o of lodObjects) o.visible = true;
37534
37691
  const budget = opts.drawCallBudget != null ? opts.drawCallBudget : cfg.drawCallBudget;
37535
37692
  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 };
37536
- shared2.ctx.tBuild = stats2.tBuild;
37693
+ shared3.ctx.tBuild = stats2.tBuild;
37537
37694
  const applyLod = (level) => {
37538
37695
  const n = Math.max(0, Math.min(2, level | 0));
37539
37696
  if (n === h.lodCurrent) return;
@@ -37599,39 +37756,39 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37599
37756
  building: gs.building || null,
37600
37757
  waterTank: r.waterTank ? (() => {
37601
37758
  const pt = Object.values(parts).find((p) => p.type === "water_tank") || null;
37602
- return { part: pt, group: pt ? pt.group : null, pos: shared2.ctx.waterTankPos || null, plant: r.waterTank };
37759
+ return { part: pt, group: pt ? pt.group : null, pos: shared3.ctx.waterTankPos || null, plant: r.waterTank };
37603
37760
  })() : null,
37604
37761
  colliders,
37605
37762
  parts,
37606
37763
  cars,
37607
37764
  interactables,
37608
- doors: shared2.ctx.leaves,
37609
- stairs: shared2.ctx.stairs,
37610
- labels: shared2.ctx.labels,
37765
+ doors: shared3.ctx.leaves,
37766
+ stairs: shared3.ctx.stairs,
37767
+ labels: shared3.ctx.labels,
37611
37768
  noModel,
37612
37769
  lights: (() => {
37613
37770
  const by = {};
37614
- for (const l of shared2.ctx.lights) {
37771
+ for (const l of shared3.ctx.lights) {
37615
37772
  const k = String(l.roomId != null ? l.roomId : l.room);
37616
37773
  (by[k] || (by[k] = [])).push(l);
37617
37774
  }
37618
- return { list: shared2.ctx.lights, byRoom: by };
37775
+ return { list: shared3.ctx.lights, byRoom: by };
37619
37776
  })(),
37620
- limits: shared2.ctx.limits,
37621
- apartment: shared2.ctx.apartment,
37622
- showBuilding: shared2.ctx.showBuilding,
37623
- buildingConfig: { floors: shared2.ctx.pa, floor: shared2.ctx.pf, unit: shared2.ctx.pu },
37624
- unitRy: shared2.ctx.unitRy || 0,
37625
- night: shared2.ctx.night,
37626
- cut: shared2.ctx.cut,
37777
+ limits: shared3.ctx.limits,
37778
+ apartment: shared3.ctx.apartment,
37779
+ showBuilding: shared3.ctx.showBuilding,
37780
+ buildingConfig: { floors: shared3.ctx.pa, floor: shared3.ctx.pf, unit: shared3.ctx.pu },
37781
+ unitRy: shared3.ctx.unitRy || 0,
37782
+ night: shared3.ctx.night,
37783
+ cut: shared3.ctx.cut,
37627
37784
  interactives: h.IV ? ivPublish(h) : null,
37628
37785
  state: h.state,
37629
37786
  stats: stats2,
37630
- vegetation: shared2.ctx.vegInfo || null,
37631
- solar: shared2.ctx.solarInfo || null,
37787
+ vegetation: shared3.ctx.vegInfo || null,
37788
+ solar: shared3.ctx.solarInfo || null,
37632
37789
  water,
37633
- electrical: shared2.ctx.electricalInfo || null,
37634
- gutters: shared2.ctx.gutterInfo || null,
37790
+ electrical: shared3.ctx.electricalInfo || null,
37791
+ gutters: shared3.ctx.gutterInfo || null,
37635
37792
  // 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
37636
37793
  update(dt, time, focus) {
37637
37794
  enter(h);
@@ -37641,9 +37798,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37641
37798
  if (destruction.active || destruction.statistics().falling || destruction.statistics().fragments) destruction.animate(dt);
37642
37799
  if (h.IV) ivUpdate(h, dt, time, focus);
37643
37800
  if (time != null) animateClotheslines(time);
37644
- if (shared2.vegMaterials) {
37645
- shared2.vegMaterials.update((time != null ? time : performance.now()) / 1e3);
37646
- shared2.vegMaterials.setActors(focus ? [{ x: focus.x, y: focus.y, z: focus.z, radius: 0.9 }] : []);
37801
+ if (shared3.vegMaterials) {
37802
+ shared3.vegMaterials.update((time != null ? time : performance.now()) / 1e3);
37803
+ shared3.vegMaterials.setActors(focus ? [{ x: focus.x, y: focus.y, z: focus.z, radius: 0.9 }] : []);
37647
37804
  }
37648
37805
  if (focus && cfg.lod !== false) {
37649
37806
  const L = Object.assign({ interior: 45, hide: 220 }, cfg.lod), d = distance3(focus), at4 = h.lodCurrent;
@@ -37655,12 +37812,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37655
37812
  show(options2) {
37656
37813
  enter(h);
37657
37814
  const o = options2 || {};
37658
- const rr = shared2.ctx.r, nA = rr.floors.length, a = o.floor == null ? -1 : o.floor, sel = a >= nA ? -1 : a, cut = !!o.cut;
37815
+ const rr = shared3.ctx.r, nA = rr.floors.length, a = o.floor == null ? -1 : o.floor, sel = a >= nA ? -1 : a, cut = !!o.cut;
37659
37816
  for (const [k, g] of Object.entries(gs)) {
37660
37817
  let v = true;
37661
37818
  if (k[0] === "f") v = sel < 0 || +k.slice(1) <= sel;
37662
37819
  else if (k[0] === "t") v = !cut && (sel < 0 || +k.slice(1) < sel);
37663
- else if (k === "roof") v = !cut && sel < 0 && (!shared2.ctx.apartment || !shared2.ctx.showBuilding || shared2.ctx.pf === shared2.ctx.pa);
37820
+ else if (k === "roof") v = !cut && sel < 0 && (!shared3.ctx.apartment || !shared3.ctx.showBuilding || shared3.ctx.pf === shared3.ctx.pa);
37664
37821
  else if (k === "attic_tank") v = (cut || sel >= 0) && (sel < 0 || nA - 1 <= sel);
37665
37822
  else if (k === "lot") v = o.lot == null ? true : !!o.lot;
37666
37823
  g.visible = v;
@@ -37677,11 +37834,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37677
37834
  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, floor: 0, pos: [], radius: 0 }, a);
37678
37835
  },
37679
37836
  message() {
37680
- return shared2.inter.msg && performance.now() < shared2.inter.msg.until ? shared2.inter.msg.text : null;
37837
+ return shared3.inter.msg && performance.now() < shared3.inter.msg.until ? shared3.inter.msg.text : null;
37681
37838
  },
37682
37839
  toggleDoor(fo) {
37683
37840
  enter(h);
37684
- toggleDoor(typeof fo === "string" ? shared2.ctx.leaves.find((f) => f.id === fo) : fo);
37841
+ toggleDoor(typeof fo === "string" ? shared3.ctx.leaves.find((f) => f.id === fo) : fo);
37685
37842
  },
37686
37843
  lightOn(roomId) {
37687
37844
  enter(h);
@@ -37753,14 +37910,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37753
37910
  });
37754
37911
  root.removeFromParent();
37755
37912
  },
37756
- internal: { h, ctx: shared2.ctx, inter: shared2.inter, partState: shared2.partState, doorState: shared2.doorState, mirrors: shared2.mirrors }
37913
+ internal: { h, ctx: shared3.ctx, inter: shared3.inter, partState: shared3.partState, doorState: shared3.doorState, mirrors: shared3.mirrors }
37757
37914
  };
37758
37915
  return res;
37759
37916
  }
37760
37917
  const defined = { build };
37761
37918
  Object.assign(K, defined);
37762
37919
  }
37763
- function buildApi(K, shared2) {
37920
+ function buildApi(K, shared3) {
37764
37921
  const { cfg, VERSION: VERSION2, ATLAS, TEX, applyPart, carGroup, carModel, props, TYPES, roomLightMask, lighting, effectLights, newState, build } = K;
37765
37922
  return {
37766
37923
  version: VERSION2,
@@ -37770,15 +37927,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37770
37927
  mv: props,
37771
37928
  applyPart,
37772
37929
  // 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
37773
- internals: { K, shared: shared2 },
37930
+ internals: { K, shared: shared3 },
37774
37931
  get materials() {
37775
- return shared2.mats;
37932
+ return shared3.mats;
37776
37933
  },
37777
37934
  roomLightMask,
37778
37935
  lighting,
37779
37936
  effectLights,
37780
37937
  setNight(n) {
37781
- const glass = shared2.mats.glass;
37938
+ const glass = shared3.mats.glass;
37782
37939
  glass.emissive.set(n ? 9067040 : 0);
37783
37940
  glass.opacity = n ? 0.4 : 0.24;
37784
37941
  },
@@ -37790,11 +37947,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37790
37947
  return m && { parts: m.parts.length, tris: m.tris, L: m.L, W: m.W, H: m.H };
37791
37948
  } },
37792
37949
  dispose() {
37793
- if (shared2.vegMaterials) {
37794
- shared2.vegMaterials.dispose();
37795
- shared2.vegMaterials = null;
37950
+ if (shared3.vegMaterials) {
37951
+ shared3.vegMaterials.dispose();
37952
+ shared3.vegMaterials = null;
37796
37953
  }
37797
- for (const m of Object.values(shared2.mats)) {
37954
+ for (const m of Object.values(shared3.mats)) {
37798
37955
  if (m && m.dispose) m.dispose();
37799
37956
  }
37800
37957
  for (const [k, t] of Object.entries(TEX)) if (t && t.dispose && !(cfg.textures && cfg.textures[k])) t.dispose();
@@ -37819,7 +37976,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37819
37976
  const colliderChanged = (c) => {
37820
37977
  if (c && cfg.onCollider) cfg.onCollider(c);
37821
37978
  };
37822
- const shared2 = { mats: null, quality: cfg.quality === "game" ? "game" : "high" };
37979
+ const shared3 = { mats: null, quality: cfg.quality === "game" ? "game" : "high" };
37823
37980
  const seedKey = (id) => {
37824
37981
  if (cfg.seedKey && id != null) {
37825
37982
  const k = cfg.seedKey(String(id));
@@ -37828,61 +37985,61 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37828
37985
  return id;
37829
37986
  };
37830
37987
  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 };
37831
- installKernelGeometry(K, shared2);
37832
- installKernelNoise(K, shared2);
37833
- installMaterialsTextures(K, shared2);
37834
- installMaterialsMaterials(K, shared2);
37835
- installKernelCloseScene(K, shared2);
37836
- installHouseHelpers(K, shared2);
37837
- installHouseWalls(K, shared2);
37838
- installHouseDoors(K, shared2);
37839
- installHouseWindows(K, shared2);
37840
- installHouseFloors(K, shared2);
37841
- installHouseStairs(K, shared2);
37842
- installLightsFixtures(K, shared2);
37843
- installLightsDecor(K, shared2);
37844
- installLotTerrain(K, shared2);
37845
- installLotPerimeter(K, shared2);
37846
- installLotGates(K, shared2);
37847
- installRoofRoofs(K, shared2);
37848
- installRoofGutters(K, shared2);
37849
- installRoofSlabs(K, shared2);
37850
- installRoofTiles(K, shared2);
37851
- installRoofRect(K, shared2);
37852
- installMirrors(K, shared2);
37853
- installCars(K, shared2);
37854
- installHouseBuilding(K, shared2);
37855
- installUtilitiesWater(K, shared2);
37856
- installUtilitiesElectrical(K, shared2);
37857
- installHouseBaseboard(K, shared2);
37858
- installUtilitiesSolar(K, shared2);
37859
- installHouseOutbuildings(K, shared2);
37860
- installFurnitureApi(K, shared2);
37861
- installFurnitureBuilders(K, shared2);
37862
- installFurnitureTypeTable(K, shared2);
37863
- installFurnitureTaps(K, shared2);
37864
- installFurnitureFixtures(K, shared2);
37865
- installFurniturePlants(K, shared2);
37866
- installFurnitureYard(K, shared2);
37867
- installFurnitureExtraTypes(K, shared2);
37868
- installFurniturePlaceItems(K, shared2);
37869
- installVegetationBridge(K, shared2);
37870
- installInteractionState(K, shared2);
37871
- installInteractionCollision(K, shared2);
37872
- installInteractionItems(K, shared2);
37873
- installInteractionFittings(K, shared2);
37874
- installInteractionDoors(K, shared2);
37875
- installInteractionTarget(K, shared2);
37876
- installInteractablesBridge(K, shared2);
37877
- installAnimationClotheslines(K, shared2);
37878
- installBuildInstance(K, shared2);
37879
- installInteractablesKit(K, shared2);
37880
- installLightsRoomLight(K, shared2);
37881
- installDestructionPieces(K, shared2);
37882
- installDestructionBreach(K, shared2);
37883
- installDestructionWorld(K, shared2);
37884
- installBuildBuild(K, shared2);
37885
- return buildApi(K, shared2);
37988
+ installKernelGeometry(K, shared3);
37989
+ installKernelNoise(K, shared3);
37990
+ installMaterialsTextures(K, shared3);
37991
+ installMaterialsMaterials(K, shared3);
37992
+ installKernelCloseScene(K, shared3);
37993
+ installHouseHelpers(K, shared3);
37994
+ installHouseWalls(K, shared3);
37995
+ installHouseDoors(K, shared3);
37996
+ installHouseWindows(K, shared3);
37997
+ installHouseFloors(K, shared3);
37998
+ installHouseStairs(K, shared3);
37999
+ installLightsFixtures(K, shared3);
38000
+ installLightsDecor(K, shared3);
38001
+ installLotTerrain(K, shared3);
38002
+ installLotPerimeter(K, shared3);
38003
+ installLotGates(K, shared3);
38004
+ installRoofRoofs(K, shared3);
38005
+ installRoofGutters(K, shared3);
38006
+ installRoofSlabs(K, shared3);
38007
+ installRoofTiles(K, shared3);
38008
+ installRoofRect(K, shared3);
38009
+ installMirrors(K, shared3);
38010
+ installCars(K, shared3);
38011
+ installHouseBuilding(K, shared3);
38012
+ installUtilitiesWater(K, shared3);
38013
+ installUtilitiesElectrical(K, shared3);
38014
+ installHouseBaseboard(K, shared3);
38015
+ installUtilitiesSolar(K, shared3);
38016
+ installHouseOutbuildings(K, shared3);
38017
+ installFurnitureApi(K, shared3);
38018
+ installFurnitureBuilders(K, shared3);
38019
+ installFurnitureTypeTable(K, shared3);
38020
+ installFurnitureTaps(K, shared3);
38021
+ installFurnitureFixtures(K, shared3);
38022
+ installFurniturePlants(K, shared3);
38023
+ installFurnitureYard(K, shared3);
38024
+ installFurnitureExtraTypes(K, shared3);
38025
+ installFurniturePlaceItems(K, shared3);
38026
+ installVegetationBridge(K, shared3);
38027
+ installInteractionState(K, shared3);
38028
+ installInteractionCollision(K, shared3);
38029
+ installInteractionItems(K, shared3);
38030
+ installInteractionFittings(K, shared3);
38031
+ installInteractionDoors(K, shared3);
38032
+ installInteractionTarget(K, shared3);
38033
+ installInteractablesBridge(K, shared3);
38034
+ installAnimationClotheslines(K, shared3);
38035
+ installBuildInstance(K, shared3);
38036
+ installInteractablesKit(K, shared3);
38037
+ installLightsRoomLight(K, shared3);
38038
+ installDestructionPieces(K, shared3);
38039
+ installDestructionBreach(K, shared3);
38040
+ installDestructionWorld(K, shared3);
38041
+ installBuildBuild(K, shared3);
38042
+ return buildApi(K, shared3);
37886
38043
  }
37887
38044
 
37888
38045
  // ../game-floorplan-residential/dist/index.js
@@ -38982,7 +39139,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
38982
39139
  if (strip.alongU) return strip.side === "front" ? [r22(u0 + a0), r22(v0 + b0), r22(u0 + a1), r22(v0 + b1)] : [r22(u0 + a0), r22(v1 - b1), r22(u0 + a1), r22(v1 - b0)];
38983
39140
  return strip.side === "left" ? [r22(u0 + b0), r22(v0 + a0), r22(u0 + b1), r22(v0 + a1)] : [r22(u1 - b1), r22(v0 + a0), r22(u1 - b0), r22(v0 + a1)];
38984
39141
  };
38985
- function apartment(strip, floor2, k, from, to, plate2, ceiling, win) {
39142
+ function apartment(strip, floor2, k, from, to, plate3, ceiling, win) {
38986
39143
  const wide2 = to - from, depth = strip.depth, facade = r22(depth * 0.56);
38987
39144
  const id = (name) => `apt_${floor2}_${strip.id}_${k}_${name}`;
38988
39145
  const at4 = (f0, f1, b0, b1) => boxOf2(strip, r22(from + wide2 * f0), r22(from + wide2 * f1), b0, b1);
@@ -39000,7 +39157,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39000
39157
  { a: id("hall"), b: id("bedroom"), width: 0.85, opensTo: id("bedroom") },
39001
39158
  { a: id("hall"), b: id("bath"), width: 0.8, opensTo: id("bath") }
39002
39159
  ];
39003
- const windows = rooms.filter((r) => r.type === "living" || r.type === "bedroom").flatMap((r) => exteriorWindows(r.id, r.rect, plate2, ceiling, { ...win, width: 2.2, spacing: 4.5 }));
39160
+ const windows = rooms.filter((r) => r.type === "living" || r.type === "bedroom").flatMap((r) => exteriorWindows(r.id, r.rect, plate3, ceiling, { ...win, width: 2.2, spacing: 4.5 }));
39004
39161
  if (strip.side === "back") {
39005
39162
  const [u0, , u1, v1] = rooms[0].rect;
39006
39163
  rooms.push({ id: id("balcony"), type: "balcony", label: "balcony", library: "balcony", rect: [r22(u0 + 0.6), v1, r22(u1 - 0.6), r22(v1 + 1.6)] });
@@ -39010,19 +39167,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39010
39167
  return { rooms, doors, windows };
39011
39168
  }
39012
39169
  var SHARED_ROOMS = { west: { type: "laundry", label: "laundry_room" }, east: { type: "storage", label: "storage_room" } };
39013
- var apartments = (plan) => (strip, { floor: floor2, plate: plate2, ceiling }) => {
39170
+ var apartments = (plan) => (strip, { floor: floor2, plate: plate3, ceiling }) => {
39014
39171
  if (strip.length < plan.apartmentMin) {
39015
- const shared2 = SHARED_ROOMS[strip.id] ?? SHARED_ROOMS.east;
39016
- const id = `${shared2.label}_${floor2}_${strip.id}`;
39017
- return { rooms: [{ id, type: shared2.type, label: shared2.label, rect: [...strip.rect] }], doors: [stripDoor(id, strip, floor2, 0.9)], windows: exteriorWindows(id, strip.rect, plate2, ceiling, { ...plan.window, width: 1.2 }) };
39172
+ const shared3 = SHARED_ROOMS[strip.id] ?? SHARED_ROOMS.east;
39173
+ const id = `${shared3.label}_${floor2}_${strip.id}`;
39174
+ return { rooms: [{ id, type: shared3.type, label: shared3.label, rect: [...strip.rect] }], doors: [stripDoor(id, strip, floor2, 0.9)], windows: exteriorWindows(id, strip.rect, plate3, ceiling, { ...plan.window, width: 1.2 }) };
39018
39175
  }
39019
39176
  const count = Math.max(1, Math.round(strip.length / plan.apartment)), wide2 = strip.length / count;
39020
- const parts = Array.from({ length: count }, (_, k) => apartment(strip, floor2, k, r22(k * wide2), r22((k + 1) * wide2), plate2, ceiling, plan.window));
39177
+ const parts = Array.from({ length: count }, (_, k) => apartment(strip, floor2, k, r22(k * wide2), r22((k + 1) * wide2), plate3, ceiling, plan.window));
39021
39178
  return { rooms: parts.flatMap((p) => p.rooms), doors: parts.flatMap((p) => p.doors), windows: parts.flatMap((p) => p.windows) };
39022
39179
  };
39023
39180
  var groundFiller = (plan) => (strip, context) => {
39024
39181
  if (strip.id !== "south") return apartments(plan)(strip, context);
39025
- const { floor: floor2, plate: plate2, ceiling } = context;
39182
+ const { floor: floor2, plate: plate3, ceiling } = context;
39026
39183
  const lobby = `lobby_${floor2}_entrance`, concierge = `concierge_${floor2}`, bikes = `bike_room_${floor2}`;
39027
39184
  const at4 = (f0, f1) => boxOf2(strip, r22(strip.length * f0), r22(strip.length * f1), 0, strip.depth);
39028
39185
  const [left, middle, right] = [at4(0, 0.3), at4(0.3, 0.7), at4(0.7, 1)];
@@ -39037,7 +39194,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39037
39194
  { a: concierge, b: lobby, width: 1.2, opensTo: concierge },
39038
39195
  { a: bikes, b: lobby, width: 1.2, opensTo: bikes }
39039
39196
  ];
39040
- return { rooms, doors, windows: exteriorWindows(concierge, left, plate2, ceiling, plan.window) };
39197
+ return { rooms, doors, windows: exteriorWindows(concierge, left, plate3, ceiling, plan.window) };
39041
39198
  };
39042
39199
  var summary = (l) => ({ storeys: l.storeys, height: l.height, slab: l.slab, pitch: l.pitch, total: l.total, bay: l.bay, plate: l.plate, mechanical: l.mechanical, facade: l.facade, damper: l.damper });
39043
39200
  function residentialTowerTemplate(preset = RESIDENTIAL_TOWER_DEFAULTS, planOptions = {}) {
@@ -39288,21 +39445,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39288
39445
  const seed = Math.round(opts.seed ?? 1);
39289
39446
  const plain2 = SHELVING.test(type) ? "paper" : "plastic";
39290
39447
  const root = { x: seed, z: 0, ry: 0, w, d, h, y: 0, base: 0, palette: o.palette, seed: `furniture_${type}_${seed}` };
39291
- const { K, shared: shared2 } = renderer.internals;
39448
+ const { K, shared: shared3 } = renderer.internals;
39292
39449
  const before = K.PARTS.length;
39293
39450
  const made = recordSpec(
39294
39451
  THREE,
39295
39452
  type,
39296
39453
  root,
39297
39454
  (A) => {
39298
- const saved = { api0: shared2.api0, ctx: shared2.ctx };
39299
- shared2.api0 = A;
39300
- shared2.ctx = shared2.ctx ?? {};
39455
+ const saved = { api0: shared3.api0, ctx: shared3.ctx };
39456
+ shared3.api0 = A;
39457
+ shared3.ctx = shared3.ctx ?? {};
39301
39458
  try {
39302
39459
  ent.f(root, A);
39303
39460
  } finally {
39304
- shared2.api0 = saved.api0;
39305
- shared2.ctx = saved.ctx;
39461
+ shared3.api0 = saved.api0;
39462
+ shared3.ctx = saved.ctx;
39306
39463
  }
39307
39464
  },
39308
39465
  { materials: { plain: plain2, ...o.materials }, chairs: o.chairs, carcass: SHELVING.test(type) }
@@ -41170,8 +41327,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41170
41327
  h: 0.04,
41171
41328
  gl: 0.125,
41172
41329
  deagle: 1,
41173
- steel: 1,
41174
- rel: 1.8
41330
+ rel: 1.8,
41331
+ chrome: 1
41175
41332
  }
41176
41333
  },
41177
41334
  taurus_82: {
@@ -41498,7 +41655,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41498
41655
  barrel: 415,
41499
41656
  options: {
41500
41657
  wood: 1,
41501
- stock: "wood",
41658
+ stock: "ak",
41502
41659
  mag: "curved",
41503
41660
  hg: "wood",
41504
41661
  hgFrac: 0.42,
@@ -41508,7 +41665,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41508
41665
  rod: 1,
41509
41666
  bayo: 1,
41510
41667
  rpm: 600,
41511
- rel: 0.4
41668
+ rel: 0.4,
41669
+ kalashnikov: 1
41512
41670
  }
41513
41671
  },
41514
41672
  akm: {
@@ -41518,7 +41676,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41518
41676
  barrel: 415,
41519
41677
  options: {
41520
41678
  wood: 1,
41521
- stock: "wood",
41679
+ stock: "ak",
41522
41680
  mag: "curved",
41523
41681
  hg: "wood",
41524
41682
  hgFrac: 0.42,
@@ -41528,7 +41686,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41528
41686
  rod: 1,
41529
41687
  rpm: 600,
41530
41688
  magMat: "bakelite",
41531
- rel: 0.45
41689
+ rel: 0.45,
41690
+ kalashnikov: 1
41532
41691
  }
41533
41692
  },
41534
41693
  ak_74: {
@@ -41537,7 +41696,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41537
41696
  length: 943,
41538
41697
  barrel: 415,
41539
41698
  options: {
41540
- stock: "fixed",
41699
+ stock: "ak",
41541
41700
  mag: "curved",
41542
41701
  hg: "poly",
41543
41702
  hgFrac: 0.42,
@@ -41547,7 +41706,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41547
41706
  ak: 1,
41548
41707
  rod: 1,
41549
41708
  rpm: 650,
41550
- magMat: "bakelite"
41709
+ magMat: "bakelite",
41710
+ kalashnikov: 1,
41711
+ wood: 1
41551
41712
  }
41552
41713
  },
41553
41714
  ak_12: {
@@ -41742,7 +41903,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41742
41903
  barrel: 620,
41743
41904
  options: {
41744
41905
  wood: 1,
41745
- stock: "skeleton",
41906
+ stock: "svd",
41746
41907
  stockLen: 0.32,
41747
41908
  mag: "box",
41748
41909
  curve: 0.09,
@@ -41752,7 +41913,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41752
41913
  scope: 4,
41753
41914
  brake: 1,
41754
41915
  ak: 1,
41755
- charge: 1
41916
+ charge: 1,
41917
+ svd: 1
41756
41918
  }
41757
41919
  },
41758
41920
  fn_scar_h: {
@@ -41817,7 +41979,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41817
41979
  barrel: 650,
41818
41980
  options: {
41819
41981
  olive: 1,
41820
- stock: "trad",
41982
+ stock: "sporter",
41821
41983
  mag: "internal",
41822
41984
  scope: 3,
41823
41985
  bolt: 1,
@@ -41873,7 +42035,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41873
42035
  barrel: 610,
41874
42036
  options: {
41875
42037
  wood: 1,
41876
- stock: "trad",
42038
+ stock: "sporter",
41877
42039
  mag: "internal",
41878
42040
  scope: 3,
41879
42041
  bolt: 1,
@@ -41887,7 +42049,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
41887
42049
  barrel: 610,
41888
42050
  options: {
41889
42051
  olive: 1,
41890
- stock: "trad",
42052
+ stock: "sporter",
41891
42053
  mag: "internal",
41892
42054
  scope: 3,
41893
42055
  bolt: 1,
@@ -42051,7 +42213,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
42051
42213
  barrel: 560,
42052
42214
  options: {
42053
42215
  wood: 1,
42054
- stock: "trad",
42216
+ stock: "sporter",
42055
42217
  mag: "internal",
42056
42218
  scope: 3,
42057
42219
  bolt: 1,
@@ -42180,13 +42342,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
42180
42342
  barrel: 610,
42181
42343
  options: {
42182
42344
  wood: 1,
42183
- stock: "trad",
42345
+ stock: "sporter",
42184
42346
  mag: "internal",
42185
42347
  scope: 3,
42186
42348
  bolt: 1,
42187
42349
  round: 1
42188
- },
42189
- variantOf: "remington_700"
42350
+ }
42190
42351
  },
42191
42352
  hk_mp5sd3: {
42192
42353
  builder: "rifle",
@@ -42483,7 +42644,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
42483
42644
  barrel: 590,
42484
42645
  options: {
42485
42646
  wood: 1,
42486
- stock: "wood",
42647
+ stock: "ak",
42487
42648
  mag: "curved",
42488
42649
  hg: "wood",
42489
42650
  hgFrac: 0.42,
@@ -42495,9 +42656,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
42495
42656
  rpm: 600,
42496
42657
  rel: 0.4,
42497
42658
  bipod: 1,
42498
- magLen: 1.4
42499
- },
42500
- variantOf: "ak_47"
42659
+ magLen: 1.4,
42660
+ kalashnikov: 1
42661
+ }
42501
42662
  },
42502
42663
  sig_mpx: {
42503
42664
  builder: "rifle",
@@ -42597,9 +42758,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
42597
42758
  rod: 1,
42598
42759
  rpm: 700,
42599
42760
  magMat: "bakelite",
42600
- stockLen: 0.22
42601
- },
42602
- variantOf: "ak_74"
42761
+ stockLen: 0.22,
42762
+ kalashnikov: 1
42763
+ }
42603
42764
  },
42604
42765
  fn_scar_l: {
42605
42766
  builder: "rifle",
@@ -42956,6 +43117,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
42956
43117
  metal: standard(3422010, 0.42, 0.75),
42957
43118
  steel: standard(7106418, 0.32, 0.85),
42958
43119
  steelL: standard(9080208, 0.28, 0.9),
43120
+ // polished steel: bright and glossy under plain lights too (the rooms have no environment map for a fully metallic surface to mirror)
43121
+ chrome: standard(13949148, 0.16, 0.5),
42959
43122
  dark: standard(1711133, 0.55, 0.5),
42960
43123
  poly: standard(2369058, 0.8, 0.05),
42961
43124
  olive: standard(4936241, 0.8, 0.05),
@@ -43335,6 +43498,107 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43335
43498
  for (let i = 0; i < 9; i++) kit.cylinderX(parts.mag, 45e-4, 0.042, kit.M.brass, 2e-3 + i * 1e-3, -0.01 - i * 0.0115, i % 2 ? 4e-3 : -4e-3, 8);
43336
43499
  }
43337
43500
 
43501
+ // src/models/wood-profile.ts
43502
+ var SLICE_LENGTH = 0.02;
43503
+ var at2 = (points, x) => {
43504
+ const last = points[points.length - 1];
43505
+ if (x >= last[0]) return [last[1], last[2]];
43506
+ const nextIndex = points.findIndex((point) => point[0] >= x);
43507
+ const next = points[Math.max(nextIndex, 1)];
43508
+ const previous = points[Math.max(nextIndex, 1) - 1];
43509
+ const fraction = (x - previous[0]) / (next[0] - previous[0]);
43510
+ return [previous[1] + (next[1] - previous[1]) * fraction, previous[2] + (next[2] - previous[2]) * fraction];
43511
+ };
43512
+ function profileBlock(kit, parent, points, width, material) {
43513
+ const first = points[0];
43514
+ const last = points[points.length - 1];
43515
+ const count = Math.max(1, Math.ceil((last[0] - first[0]) / SLICE_LENGTH));
43516
+ const step = (last[0] - first[0]) / count;
43517
+ for (let index = 0; index < count; index++) {
43518
+ const [rearTop, rearBottom] = at2(points, first[0] + step * index);
43519
+ const [frontTop, frontBottom] = at2(points, first[0] + step * (index + 1));
43520
+ const rise = (frontTop + frontBottom - rearTop - rearBottom) / 2;
43521
+ const height = (frontTop - frontBottom + rearTop - rearBottom) / 2;
43522
+ const centre = (rearTop + rearBottom + frontTop + frontBottom) / 4;
43523
+ kit.box(parent, Math.hypot(step, rise) * 1.12, height, width, material, first[0] + step * (index + 0.5), centre, 0, Math.atan2(rise, step));
43524
+ }
43525
+ }
43526
+ var BEVEL2 = 25e-4;
43527
+ var solids = /* @__PURE__ */ new WeakMap();
43528
+ function profileSolid(kit, parent, points, width, material, hole) {
43529
+ const key2 = JSON.stringify([points, width, hole ?? null]);
43530
+ const cache = solids.get(kit) ?? /* @__PURE__ */ new Map();
43531
+ solids.set(kit, cache);
43532
+ let geometry = cache.get(key2);
43533
+ if (!geometry) {
43534
+ geometry = buildSolid(kit, points, width, hole);
43535
+ markShared(geometry);
43536
+ cache.set(key2, geometry);
43537
+ }
43538
+ const { THREE } = kit;
43539
+ const mesh3 = new THREE.Mesh(geometry, material);
43540
+ mesh3.castShadow = true;
43541
+ mesh3.receiveShadow = true;
43542
+ parent.add(mesh3);
43543
+ return mesh3;
43544
+ }
43545
+ function buildSolid(kit, points, width, hole) {
43546
+ const { THREE } = kit;
43547
+ const top = points.map(([x, y]) => new THREE.Vector2(x, y));
43548
+ const bottom = [...points].reverse().map(([x, , y]) => new THREE.Vector2(x, y));
43549
+ const first = top[0];
43550
+ const shape = new THREE.Shape();
43551
+ shape.moveTo(first.x, first.y);
43552
+ shape.splineThru(top.slice(1));
43553
+ shape.lineTo(bottom[0].x, bottom[0].y);
43554
+ shape.splineThru(bottom.slice(1));
43555
+ shape.closePath();
43556
+ if (hole) {
43557
+ const loop = hole.map(([x, y]) => new THREE.Vector2(x, y));
43558
+ const path = new THREE.Path();
43559
+ path.moveTo(loop[0].x, loop[0].y);
43560
+ path.splineThru([...loop.slice(1), loop[0]]);
43561
+ shape.holes.push(path);
43562
+ }
43563
+ const depth = Math.max(2e-3, width - BEVEL2 * 2);
43564
+ const geometry = new THREE.ExtrudeGeometry(shape, { depth, curveSegments: 16, bevelEnabled: true, bevelThickness: BEVEL2, bevelSize: BEVEL2, bevelSegments: 2 });
43565
+ geometry.translate(0, 0, -depth / 2);
43566
+ return geometry;
43567
+ }
43568
+
43569
+ // src/models/rifle-svd.ts
43570
+ function buildSvdStock(context) {
43571
+ const { kit, group, furniture: furn, stockLength: S } = context;
43572
+ const width = 0.034;
43573
+ profileSolid(
43574
+ kit,
43575
+ group,
43576
+ [
43577
+ [6e-3, 0.02, -0.142],
43578
+ [0.07, 0.022, -0.13],
43579
+ [0.16, 0.024, -0.122],
43580
+ [S - 0.03, 0.027, -0.124],
43581
+ [S + 6e-3, 0.028, -0.128],
43582
+ [S + 0.035, -0.02, -0.13]
43583
+ ],
43584
+ width,
43585
+ furn,
43586
+ [[0.125, -0.02], [0.2, -0.018], [S - 0.01, -0.022], [S + 0.012, -0.05], [S - 0.01, -0.094], [0.2, -0.095], [0.125, -0.09], [0.112, -0.055]]
43587
+ );
43588
+ profileSolid(kit, group, [[0.06, 0.044, 0.016], [0.11, 0.05, 0.016], [0.2, 0.046, 0.016]], width * 0.9, furn);
43589
+ buttpad(kit, group, 3e-3, -0.06, 0.16, width);
43590
+ }
43591
+ function buildSvdHandguard(context) {
43592
+ const { kit, group, furniture: furn, receiverEnd: x1, receiverWidth: wR, barrelRadius: r, barrelY: by } = context;
43593
+ const { M, box: box5, cylinderX } = kit;
43594
+ const length2 = 0.27;
43595
+ profileSolid(kit, group, [[x1, by + 0.024, by - 0.03], [x1 + 0.06, by + 0.026, by - 0.03], [x1 + length2, by + 0.02, by - 0.024]], wR * 1.12, furn);
43596
+ for (let i = 0; i < 3; i++) for (const side of [-1, 1]) box5(group, 0.028, 8e-3, 2e-3, M.hole, x1 + 0.07 + i * 0.06, by + 4e-3, side * wR * 0.57);
43597
+ cylinderX(group, wR * 0.5, 0.012, M.metal, x1 + length2 + 6e-3, by, 0, 16);
43598
+ cylinderX(group, r * 1.2, 0.05, M.metal, x1 + length2 + 0.035, by + r * 2.4, 0, 12);
43599
+ box5(group, 0.016, r * 3.4, wR * 0.5, M.metal, x1 + length2 + 0.05, by + r * 1.2, 0);
43600
+ }
43601
+
43338
43602
  // src/models/rifle-forend.ts
43339
43603
  var PI4 = Math.PI;
43340
43604
  function buildForend(context) {
@@ -43344,6 +43608,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43344
43608
  buildG36Handguard(context);
43345
43609
  return;
43346
43610
  }
43611
+ if (o.svd) {
43612
+ buildSvdHandguard(context);
43613
+ return;
43614
+ }
43347
43615
  const hasLongScope = (o.scope ?? 0) >= 3;
43348
43616
  if (!context.isTraditional && o.hg !== "none") {
43349
43617
  const handguardLength = (L - x1) * (o.hgFrac || 0.5);
@@ -43424,6 +43692,82 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43424
43692
  return x;
43425
43693
  }
43426
43694
 
43695
+ // src/models/geometry-cache.ts
43696
+ var shared2 = /* @__PURE__ */ new WeakMap();
43697
+ function sharedGeometry(kit, key2, build) {
43698
+ const cache = shared2.get(kit) ?? /* @__PURE__ */ new Map();
43699
+ shared2.set(kit, cache);
43700
+ let geometry = cache.get(key2);
43701
+ if (!geometry) {
43702
+ geometry = build();
43703
+ markShared(geometry);
43704
+ cache.set(key2, geometry);
43705
+ }
43706
+ return geometry;
43707
+ }
43708
+
43709
+ // src/models/rifle-kalashnikov.ts
43710
+ function buildKalashnikovReceiver(context) {
43711
+ const { kit, group, receiverStart: x0, receiverEnd: x1, receiverWidth: wR, receiverLength: RL, receiverHeight: hR, barrelY: by } = context;
43712
+ const { M, box: box5, cylinderZ } = kit;
43713
+ const bottom = -hR / 2;
43714
+ profileSolid(kit, group, [[x0, 0.015, bottom + 0.012], [x0 + 0.035, 0.015, bottom], [x1, 0.015, bottom]], wR * 0.9, M.metal);
43715
+ profileSolid(kit, group, [[x0 + 2e-3, 0.021, 0.012], [x0 + RL * 0.5, 0.027, 0.012], [x1 - 4e-3, 0.031, 0.012]], wR * 0.8, M.metal);
43716
+ for (let i = 0; i < 4; i++) box5(group, 4e-3, 3e-3, wR * 0.6, M.dark, x0 + 0.03 + i * 0.012, 0.024 + i * 6e-4, 0);
43717
+ box5(group, 8e-3, 8e-3, 0.01, M.metal, x0 + 4e-3, 0.02, 0);
43718
+ profileSolid(kit, group, [[x1 - 8e-3, 0.034, by - 0.012], [x1 + 0.02, 0.031, by - 0.012], [x1 + 0.046, 0.024, by - 8e-3]], wR * 0.7, M.metal);
43719
+ box5(group, 0.036, 4e-3, wR * 0.5, M.dark, x1 + 0.018, 0.037, 0, -0.04);
43720
+ box5(group, 6e-3, 8e-3, wR * 0.5, M.dark, x1 + 2e-3, 0.039, 0);
43721
+ box5(group, RL * 0.48, 0.011, 3e-3, M.metal, x0 + RL * 0.36, 4e-3, wR * 0.46 + 15e-4, -0.05);
43722
+ box5(group, 0.012, 0.016, 3e-3, M.metal, x0 + RL * 0.62, -6e-3, wR * 0.46 + 15e-4, -0.3);
43723
+ for (const [x, y] of [[x0 + 0.012, -0.012], [x0 + 0.026, -0.012], [x1 - 0.03, -0.014], [x1 - 0.016, -0.014], [x1 - 0.03, 2e-3]]) {
43724
+ cylinderZ(group, 2e-3, wR * 0.9 + 2e-3, M.dark, x, y, 0, 8);
43725
+ }
43726
+ }
43727
+ var arcBand = (kit, parent, centre, radii, angles, depth, material) => {
43728
+ const { THREE } = kit;
43729
+ const geometry = sharedGeometry(kit, `arc:${JSON.stringify([centre, radii, angles, depth])}`, () => {
43730
+ const [inner, outer] = radii;
43731
+ const [start, end3] = angles;
43732
+ const shape = new THREE.Shape();
43733
+ shape.absarc(centre[0], centre[1], outer, start, end3, false);
43734
+ shape.absarc(centre[0], centre[1], inner, end3, start, true);
43735
+ shape.closePath();
43736
+ const bevel = Math.min(12e-4, depth / 6);
43737
+ const extruded = new THREE.ExtrudeGeometry(shape, { depth: depth - bevel * 2, curveSegments: 24, bevelEnabled: true, bevelThickness: bevel, bevelSize: bevel, bevelSegments: 1 });
43738
+ extruded.translate(0, 0, -(depth - bevel * 2) / 2);
43739
+ return extruded;
43740
+ });
43741
+ const mesh3 = new THREE.Mesh(geometry, material);
43742
+ mesh3.castShadow = true;
43743
+ mesh3.receiveShadow = true;
43744
+ parent.add(mesh3);
43745
+ return mesh3;
43746
+ };
43747
+ var CURVE_RADIUS = 0.33;
43748
+ var MAGAZINE_DEPTH2 = 0.052;
43749
+ var MAGAZINE_WIDTH = 0.024;
43750
+ var LENGTH_PER_SCALE = 0.2;
43751
+ function buildBananaMagazine(kit, magazine, material, scale) {
43752
+ const { M, box: box5 } = kit;
43753
+ const length2 = LENGTH_PER_SCALE * scale;
43754
+ const span = length2 / CURVE_RADIUS;
43755
+ const centre = [CURVE_RADIUS, 0];
43756
+ const start = Math.PI;
43757
+ const end3 = Math.PI + span;
43758
+ const half = MAGAZINE_DEPTH2 / 2;
43759
+ arcBand(kit, magazine, centre, [CURVE_RADIUS - half, CURVE_RADIUS + half], [start, end3], MAGAZINE_WIDTH, material);
43760
+ for (const radius of [CURVE_RADIUS - half * 0.45, CURVE_RADIUS + half * 0.45]) {
43761
+ arcBand(kit, magazine, centre, [radius - 25e-4, radius + 25e-4], [start + span * 0.08, end3 - span * 0.06], MAGAZINE_WIDTH + 3e-3, material);
43762
+ }
43763
+ box5(magazine, 0.01, 8e-3, MAGAZINE_WIDTH * 0.7, M.metal, half - 2e-3, 2e-3, 0);
43764
+ const bottom = [centre[0] + CURVE_RADIUS * Math.cos(end3), centre[1] + CURVE_RADIUS * Math.sin(end3)];
43765
+ const plate3 = box5(magazine, MAGAZINE_DEPTH2 + 6e-3, 6e-3, MAGAZINE_WIDTH + 4e-3, material, bottom[0], bottom[1], 0, span);
43766
+ plate3.position.x += Math.sin(span) * 2e-3;
43767
+ plate3.position.y -= Math.cos(span) * 2e-3;
43768
+ return length2 + 0.04;
43769
+ }
43770
+
43427
43771
  // src/models/rifle-controls.ts
43428
43772
  function buildGrip(context) {
43429
43773
  const { kit, group, parts, options: o, furniture: furn, receiverStart: x0, receiverHeight: hR, receiverWidth: wR } = context;
@@ -43452,7 +43796,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43452
43796
  const magazine = kit.pivot(group, mx, -hR / 2, 0);
43453
43797
  parts.mag = magazine;
43454
43798
  const finish = o.magMat === "bakelite" ? M.bakelite : o.magMat === "poly" ? M.polyMag : o.magMat === "smoke" ? M.smoke : void 0;
43455
- if (o.mag === "curved") {
43799
+ if (o.mag === "curved" && o.kalashnikov) {
43800
+ parts.magDrop = buildBananaMagazine(kit, magazine, finish ?? M.metal, scale);
43801
+ } else if (o.mag === "curved") {
43456
43802
  let px = 0;
43457
43803
  let py = 0;
43458
43804
  const material = finish ?? M.metal;
@@ -43575,10 +43921,56 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43575
43921
  return { group, parts };
43576
43922
  }
43577
43923
 
43924
+ // src/models/rifle-sporter.ts
43925
+ function buildSporterStock(context, magazineX) {
43926
+ const { kit, group, furniture: furn, length: L, stockLength: S, receiverEnd: x1, receiverHeight: hR } = context;
43927
+ const { M, box: box5 } = kit;
43928
+ const forendTip = x1 + (L - x1) * (context.options.fore ?? 0.5);
43929
+ const bottom = -hR / 2;
43930
+ const bedTop = context.options.round ? context.barrelY - hR * 0.36 + 3e-3 : bottom + 0.012;
43931
+ profileSolid(
43932
+ kit,
43933
+ group,
43934
+ [
43935
+ [6e-3, -0.016, -0.15],
43936
+ [0.14, -0.012, -0.118],
43937
+ [S - 0.11, -0.016, -0.084],
43938
+ [S - 0.05, -0.018, -0.114],
43939
+ [S - 0.01, -0.016, -0.09],
43940
+ [S + 0.03, bedTop, bottom - 0.03],
43941
+ [x1, bedTop, bottom - 0.026],
43942
+ [x1 + 0.08, bedTop, bottom - 0.024],
43943
+ [forendTip, bottom + 0.02, bottom - 0.012]
43944
+ ],
43945
+ 0.04,
43946
+ furn
43947
+ );
43948
+ buttpad(kit, group, 0, -0.083, 0.136, 0.04);
43949
+ box5(group, 0.024, 6e-3, 0.03, M.dark, S - 0.05, -0.116, 0, -0.5);
43950
+ const guard = kit.torus(group, new kit.THREE.TorusGeometry(0.024, 25e-4, 6, 16, Math.PI), M.metal, S + 0.075, bottom - 0.022, 0);
43951
+ guard.rotation.z = Math.PI;
43952
+ box5(group, 0.07, 4e-3, 0.03, M.metal, magazineX, bottom - 0.03, 0);
43953
+ swivel(kit, group, 0.12, -0.12);
43954
+ swivel(kit, group, forendTip - 0.05, bottom - 0.02);
43955
+ }
43956
+ function buildKalashnikovStock(context) {
43957
+ const { kit, group, furniture: furn, stockLength: S, receiverHeight: hR } = context;
43958
+ const { M, box: box5 } = kit;
43959
+ profileSolid(kit, group, [[8e-3, -0.034, -0.15], [S * 0.5, -0.014, -0.1], [S + 4e-3, hR * 0.2, -hR / 2 - 2e-3]], 0.036, furn);
43960
+ box5(group, 8e-3, 0.118, 0.038, M.metal, 4e-3, -0.092, 0, -0.06);
43961
+ const loopX = 0.1;
43962
+ const belly = -0.15 + (loopX - 8e-3) / (S * 0.5 - 8e-3) * 0.05;
43963
+ box5(group, 0.03, 6e-3, 6e-3, M.metal, loopX, belly + 0.032, -0.019, 0.3);
43964
+ }
43965
+
43578
43966
  // src/models/rifle-stock.ts
43579
43967
  function buildStock(context, magazineX) {
43580
43968
  const { kit, group, options: o, furniture: furn, length: L, stockLength: S, receiverStart: x0, receiverEnd: x1, receiverHeight: hR } = context;
43581
43969
  const { M, box: box5, cylinderX } = kit;
43970
+ if (o.stock === "sporter") {
43971
+ buildSporterStock(context, magazineX);
43972
+ return;
43973
+ }
43582
43974
  if (context.isTraditional) {
43583
43975
  buttpad(kit, group, 6e-3, -0.04, 0.13, 0.038);
43584
43976
  box5(group, 0.03, 0.13, 0.038, furn, 0.024, -0.04, 0);
@@ -43610,6 +44002,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43610
44002
  buttpad(kit, group, 3e-3, -0.025, 0.11, 0.036);
43611
44003
  } else if (o.stock === "g36") {
43612
44004
  buildG36Stock(context);
44005
+ } else if (o.stock === "ak") {
44006
+ buildKalashnikovStock(context);
44007
+ } else if (o.stock === "svd") {
44008
+ buildSvdStock(context);
43613
44009
  } else if (o.stock === "fold") {
43614
44010
  box5(group, S, 6e-3, 6e-3, M.metal, S / 2, 0.01, 0.012);
43615
44011
  box5(group, S, 6e-3, 6e-3, M.metal, S / 2, -0.04, 0.012, -0.12);
@@ -43625,6 +44021,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43625
44021
  const receiverMaterial = o.tan ? M.tan : M.metal;
43626
44022
  const middle = (x0 + x1) / 2;
43627
44023
  if (o.g36) buildG36Receiver(context);
44024
+ else if (o.kalashnikov) buildKalashnikovReceiver(context);
43628
44025
  else if (o.round) {
43629
44026
  cylinderX(group, hR * 0.36, RL, M.steel, middle, by, 0, 20);
43630
44027
  cylinderX(group, hR * 0.32, 0.05, M.steel, x0 - 0.01, by, 0, 18);
@@ -43637,7 +44034,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43637
44034
  box5(group, 0.03, 8e-3, 0.012, M.dark, x0 + 0.02, hR / 2 + 4e-3, 0);
43638
44035
  box5(group, 0.012, 6e-3, 4e-3, M.dark, x0 + RL * 0.55, -hR * 0.15, -wR / 2 - 2e-3);
43639
44036
  } else box5(group, RL, hR, wR, receiverMaterial, middle, 0, 0);
43640
- if (o.ak) {
44037
+ if (o.ak && !o.kalashnikov) {
43641
44038
  box5(group, RL * 0.86, hR * 0.28, wR * 0.95, M.metal, middle - 8e-3, hR / 2 + 4e-3, 0);
43642
44039
  for (let i = 0; i < 3; i++) box5(group, 4e-3, hR * 0.3, wR * 0.97, M.dark, x0 + RL * 0.25 + i * 0.02, hR / 2 + 4e-3, 0);
43643
44040
  box5(group, RL * 0.5, 0.012, 3e-3, M.metal, x0 + RL * 0.55, -hR * 0.02, wR / 2 + 15e-4, -0.05);
@@ -43700,7 +44097,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
43700
44097
  const parts = { family: "rifle", glow: [] };
43701
44098
  const length2 = (options.L ?? 0) / 1e3;
43702
44099
  const barrelLength = (options.B ?? 0) / 1e3;
43703
- const isTraditional = options.stock === "trad" || options.stock === "straight";
44100
+ const isTraditional = options.stock === "trad" || options.stock === "straight" || options.stock === "sporter";
43704
44101
  const stockLength = options.stock === "none" ? 0 : options.stockLen || Math.min(0.36, Math.max(0.2, 0.3 * length2));
43705
44102
  const receiverStart = stockLength;
43706
44103
  const receiverEnd = Math.max(receiverStart + 0.12, length2 - barrelLength * 0.92);
@@ -44633,7 +45030,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
44633
45030
 
44634
45031
  // src/models/ps90.ts
44635
45032
  var WIDTH = 0.046;
44636
- var BEVEL2 = 5e-3;
45033
+ var BEVEL3 = 5e-3;
44637
45034
  var BODY_OUTLINE = [
44638
45035
  [0.017, -0.078],
44639
45036
  [0.03, -0.09],
@@ -44675,8 +45072,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
44675
45072
  const toVector = ([x, y]) => new THREE.Vector2(x, y);
44676
45073
  const shape = new THREE.Shape(outline.map(toVector));
44677
45074
  for (const hole of holes) shape.holes.push(new THREE.Path(hole.map(toVector)));
44678
- const geometry = new THREE.ExtrudeGeometry(shape, { depth: width - 2 * BEVEL2, bevelEnabled: true, bevelThickness: BEVEL2, bevelSize: BEVEL2, bevelSegments: 2 });
44679
- geometry.translate(0, 0, -(width - 2 * BEVEL2) / 2);
45075
+ const geometry = new THREE.ExtrudeGeometry(shape, { depth: width - 2 * BEVEL3, bevelEnabled: true, bevelThickness: BEVEL3, bevelSize: BEVEL3, bevelSegments: 2 });
45076
+ geometry.translate(0, 0, -(width - 2 * BEVEL3) / 2);
44680
45077
  const mesh3 = new THREE.Mesh(geometry, material);
44681
45078
  mesh3.castShadow = true;
44682
45079
  mesh3.receiveShadow = true;
@@ -44949,6 +45346,135 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
44949
45346
  return { group, parts };
44950
45347
  }
44951
45348
 
45349
+ // src/models/pistol-deagle.ts
45350
+ var SLIDE_HEIGHT = 0.036;
45351
+ var WIDTH2 = 0.032;
45352
+ var FRAME_HEIGHT = 0.015;
45353
+ var FRAME_BOTTOM = -SLIDE_HEIGHT / 2 - FRAME_HEIGHT;
45354
+ var GRIP = { angle: -0.314, depth: 0.052, width: 0.034, length: 0.1, rearX: 0.014 };
45355
+ var GUARD = { drop: 0.038, front: 0.064, bar: 65e-4, depth: 0.011 };
45356
+ var SLIDE_SHARE = 0.55;
45357
+ var plate = (kit, parent, outline, hole, depth, material) => {
45358
+ const { THREE } = kit;
45359
+ const geometry = sharedGeometry(kit, `plate:${JSON.stringify([outline, hole, depth])}`, () => {
45360
+ const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));
45361
+ if (hole) shape.holes.push(new THREE.Path(hole.map(([x, y]) => new THREE.Vector2(x, y))));
45362
+ const extruded = new THREE.ExtrudeGeometry(shape, { depth, bevelEnabled: true, bevelThickness: 8e-4, bevelSize: 8e-4, bevelSegments: 1 });
45363
+ extruded.translate(0, 0, -depth / 2);
45364
+ return extruded;
45365
+ });
45366
+ const mesh3 = new THREE.Mesh(geometry, material);
45367
+ mesh3.castShadow = true;
45368
+ mesh3.receiveShadow = true;
45369
+ parent.add(mesh3);
45370
+ return mesh3;
45371
+ };
45372
+ var buildUpper = (kit, group, slide2, parts, length2, metal2) => {
45373
+ const { M, box: box5, cylinderX } = kit;
45374
+ const slideLength = length2 * SLIDE_SHARE;
45375
+ const barrelLength = length2 - slideLength;
45376
+ kit.roundness = 0.06;
45377
+ box5(slide2, slideLength, SLIDE_HEIGHT, WIDTH2, metal2, slideLength / 2, 0, 0);
45378
+ const barrel = heatify(parts.glow ?? [], box5(group, barrelLength, SLIDE_HEIGHT, WIDTH2, metal2, slideLength + barrelLength / 2, 0, 0));
45379
+ barrel.name = "barrel";
45380
+ kit.roundness = null;
45381
+ box5(group, 12e-4, SLIDE_HEIGHT * 0.9, WIDTH2 + 4e-4, M.dark, slideLength, 0, 0);
45382
+ for (let i = 0; i < 9; i++) box5(slide2, 22e-4, SLIDE_HEIGHT * 0.66, WIDTH2 + 12e-4, M.dark, 8e-3 + i * 48e-4, -3e-3, 0);
45383
+ box5(slide2, length2 * 0.08, 3e-3, WIDTH2 * 0.5, M.hole, length2 * 0.42, SLIDE_HEIGHT / 2, WIDTH2 * 0.12);
45384
+ box5(slide2, 7e-3, 6e-3, 0.014, M.dark, 8e-3, SLIDE_HEIGHT / 2 + 3e-3, 0);
45385
+ box5(slide2, 3e-3, 2e-3, 4e-3, M.hole, 8e-3, SLIDE_HEIGHT / 2 + 5e-3, 0);
45386
+ box5(group, barrelLength * 0.9, 4e-3, WIDTH2 * 0.42, metal2, slideLength + barrelLength * 0.5, SLIDE_HEIGHT / 2 + 2e-3, 0);
45387
+ for (let i = 0; i < 7; i++) box5(group, 4e-3, 15e-4, WIDTH2 * 0.43, M.hole, slideLength + 0.01 + i * 0.013, SLIDE_HEIGHT / 2 + 4e-3, 0);
45388
+ box5(group, 4e-3, 6e-3, 4e-3, M.dark, length2 - 6e-3, SLIDE_HEIGHT / 2 + 6e-3, 0);
45389
+ const nose = plate(kit, group, [[-WIDTH2 / 2, -SLIDE_HEIGHT / 2 + 2e-3], [WIDTH2 / 2, -SLIDE_HEIGHT / 2 + 2e-3], [WIDTH2 * 0.16, SLIDE_HEIGHT / 2 - 2e-3], [-WIDTH2 * 0.16, SLIDE_HEIGHT / 2 - 2e-3]], null, 3e-3, metal2);
45390
+ nose.rotation.y = Math.PI / 2;
45391
+ nose.position.set(length2 + 15e-4, 0, 0);
45392
+ const boreY = -SLIDE_HEIGHT * 0.12;
45393
+ cylinderX(group, 64e-4, 4e-3, M.hole, length2 + 3e-3, boreY, 0, 14);
45394
+ return boreY;
45395
+ };
45396
+ var buildGrip2 = (kit, group, parts, metal2) => {
45397
+ const { M, box: box5 } = kit;
45398
+ const { angle, depth, width, length: length2 } = GRIP;
45399
+ const sin2 = Math.sin(angle);
45400
+ const cos2 = Math.cos(angle);
45401
+ const topY = FRAME_BOTTOM + 6e-3;
45402
+ const centerX = GRIP.rearX + depth / 2 * cos2 + length2 / 2 * sin2;
45403
+ const centerY = topY - length2 / 2 * cos2 + depth / 2 * sin2;
45404
+ const grip = kit.pivot(group, centerX, centerY, 0);
45405
+ grip.rotation.z = angle;
45406
+ parts.grip = grip;
45407
+ kit.roundness = 0.22;
45408
+ box5(grip, depth, length2, width * 0.86, metal2, 0, 0, 0);
45409
+ box5(grip, depth * 0.86, length2 * 0.84, width, M.rubber, -2e-3, 2e-3, 0);
45410
+ kit.roundness = null;
45411
+ for (let i = 0; i < 8; i++) box5(grip, depth * 0.66, 2e-3, width + 12e-4, M.dark, -3e-3, -length2 * 0.36 + i * 0.0105, 0);
45412
+ const magazine = kit.pivot(grip);
45413
+ parts.mag = magazine;
45414
+ parts.magDrop = length2 * 1.15;
45415
+ box5(magazine, depth * 0.62, length2 * 0.94, width * 0.66, M.dark, 2e-3, -4e-3, 0);
45416
+ box5(magazine, depth * 0.98, 6e-3, width * 0.9, metal2, 0, -length2 / 2 + 3e-3, 0);
45417
+ const frontTopX = centerX + depth / 2 * cos2 - length2 / 2 * sin2;
45418
+ const frontTopY = centerY + depth / 2 * sin2 + length2 / 2 * cos2;
45419
+ return (y) => frontTopX + (frontTopY - y) * Math.tan(angle);
45420
+ };
45421
+ var buildGuard = (kit, group, frontStrapAt, metal2) => {
45422
+ const top = FRAME_BOTTOM + 2e-3;
45423
+ const bottom = FRAME_BOTTOM - GUARD.drop;
45424
+ const backTop = frontStrapAt(top) - 4e-3;
45425
+ const backBottom = frontStrapAt(bottom) - 4e-3;
45426
+ const front = backTop + GUARD.front;
45427
+ const bar2 = GUARD.bar;
45428
+ const corner = 8e-3;
45429
+ const outline = [
45430
+ [backTop, top],
45431
+ [backBottom, bottom],
45432
+ [front - corner, bottom],
45433
+ [front, bottom + corner],
45434
+ [front + 2e-3, top]
45435
+ ];
45436
+ const hole = [
45437
+ [backTop + bar2 + 2e-3, top - 2e-3],
45438
+ [front - bar2 + 1e-3, top - 2e-3],
45439
+ [front - bar2, bottom + bar2 + corner * 0.6],
45440
+ [front - bar2 - corner * 0.6, bottom + bar2],
45441
+ [backBottom + bar2 + 4e-3, bottom + bar2]
45442
+ ];
45443
+ plate(kit, group, outline, hole, GUARD.depth, metal2);
45444
+ return bottom;
45445
+ };
45446
+ function buildDeagle(kit, options) {
45447
+ const { M, box: box5, torus: torus2, THREE } = kit;
45448
+ const length2 = (options.L ?? 0) / 1e3 * 0.97;
45449
+ const metal2 = options.chrome ? M.chrome : options.steel ? M.steel : options.stain ? M.steelL : M.metal;
45450
+ const group = kit.group();
45451
+ const parts = { family: "pistol", kick: 1.8, glow: [] };
45452
+ const slide2 = kit.pivot(group);
45453
+ parts.slide = slide2;
45454
+ parts.stroke = length2 * 0.12;
45455
+ const boreY = buildUpper(kit, group, slide2, parts, length2, metal2);
45456
+ kit.roundness = 0.1;
45457
+ box5(group, length2 * 0.95, FRAME_HEIGHT, WIDTH2 * 0.94, metal2, length2 * 0.5 - 2e-3, -SLIDE_HEIGHT / 2 - FRAME_HEIGHT / 2, 0);
45458
+ kit.roundness = null;
45459
+ box5(group, length2 * 0.3, 3e-3, WIDTH2 * 0.94 + 1e-3, M.dark, length2 * 0.72, -SLIDE_HEIGHT / 2 - FRAME_HEIGHT * 0.6, 0);
45460
+ box5(group, 0.026, 9e-3, WIDTH2 * 0.9, metal2, -2e-3, FRAME_BOTTOM + 4e-3, 0, 0.3);
45461
+ box5(group, 0.016, 5e-3, 4e-3, M.dark, length2 * 0.36, -SLIDE_HEIGHT / 2 - 5e-3, -WIDTH2 / 2 - 14e-4);
45462
+ const frontStrapAt = buildGrip2(kit, group, parts, metal2);
45463
+ buildGuard(kit, group, frontStrapAt, metal2);
45464
+ const triggerX = frontStrapAt(FRAME_BOTTOM) + 0.02;
45465
+ parts.trigger = box5(group, 6e-3, 0.026, 7e-3, M.steel, triggerX, FRAME_BOTTOM - 8e-3, 0, 0.28);
45466
+ const hammer2 = kit.pivot(group, 2e-3, SLIDE_HEIGHT * 0.05, 0);
45467
+ parts.hammer = hammer2;
45468
+ box5(hammer2, 0.012, 0.02, 0.01, M.dark, -4e-3, 4e-3, 0, 0.35);
45469
+ const ring3 = torus2(hammer2, new THREE.TorusGeometry(68e-4, 24e-4, 8, 16), M.dark, -0.01, 0.014, 0);
45470
+ ring3.scale.z = 2;
45471
+ parts.safety = box5(slide2, 0.014, 8e-3, 4e-3, M.dark, 0.02, SLIDE_HEIGHT * 0.1, -WIDTH2 / 2 - 2e-3, 0.2);
45472
+ box5(slide2, 0.014, 8e-3, 4e-3, M.dark, 0.02, SLIDE_HEIGHT * 0.1, WIDTH2 / 2 + 2e-3, 0.2);
45473
+ parts.muzzle = kit.mark(group, length2 + 6e-3, boreY, 0);
45474
+ parts.eject = kit.mark(group, length2 * 0.42, SLIDE_HEIGHT / 2, WIDTH2 * 0.25);
45475
+ return { group, parts };
45476
+ }
45477
+
44952
45478
  // src/models/pistol-slide.ts
44953
45479
  var PI9 = Math.PI;
44954
45480
  function buildSlide(kit, slide2, parts, options, style, size, metal2) {
@@ -45101,6 +45627,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
45101
45627
  }
45102
45628
  function buildPistol(kit, options) {
45103
45629
  if (options.design && isDesignName(options.design)) return buildDesignedPistol(kit, options, options.design);
45630
+ if (options.st === "deagle") return buildDeagle(kit, options);
45104
45631
  const { M, box: box5 } = kit;
45105
45632
  const style = { ...STYLES[options.st ?? "glock"] };
45106
45633
  const group = kit.group();
@@ -45273,32 +45800,6 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
45273
45800
  return { group, parts };
45274
45801
  }
45275
45802
 
45276
- // src/models/wood-profile.ts
45277
- var SLICE_LENGTH = 0.02;
45278
- var at2 = (points, x) => {
45279
- const last = points[points.length - 1];
45280
- if (x >= last[0]) return [last[1], last[2]];
45281
- const nextIndex = points.findIndex((point) => point[0] >= x);
45282
- const next = points[Math.max(nextIndex, 1)];
45283
- const previous = points[Math.max(nextIndex, 1) - 1];
45284
- const fraction = (x - previous[0]) / (next[0] - previous[0]);
45285
- return [previous[1] + (next[1] - previous[1]) * fraction, previous[2] + (next[2] - previous[2]) * fraction];
45286
- };
45287
- function profileBlock(kit, parent, points, width, material) {
45288
- const first = points[0];
45289
- const last = points[points.length - 1];
45290
- const count = Math.max(1, Math.ceil((last[0] - first[0]) / SLICE_LENGTH));
45291
- const step = (last[0] - first[0]) / count;
45292
- for (let index = 0; index < count; index++) {
45293
- const [rearTop, rearBottom] = at2(points, first[0] + step * index);
45294
- const [frontTop, frontBottom] = at2(points, first[0] + step * (index + 1));
45295
- const rise = (frontTop + frontBottom - rearTop - rearBottom) / 2;
45296
- const height = (frontTop - frontBottom + rearTop - rearBottom) / 2;
45297
- const centre = (rearTop + rearBottom + frontTop + frontBottom) / 4;
45298
- kit.box(parent, Math.hypot(step, rise) * 1.12, height, width, material, first[0] + step * (index + 0.5), centre, 0, Math.atan2(rise, step));
45299
- }
45300
- }
45301
-
45302
45803
  // src/models/rifle-kar98.ts
45303
45804
  var RECEIVER_START3 = 0.29;
45304
45805
  var RECEIVER_END3 = 0.5;
@@ -45841,14 +46342,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
45841
46342
  movable: false
45842
46343
  };
45843
46344
  }
45844
- function showcaseSheet(arsenal, text, weapon) {
45845
- const name = arsenal.name(weapon);
46345
+ function showcasePhoto(arsenal, text, weapon) {
45846
46346
  const photo2 = PHOTOS[weapon];
45847
- if (!photo2) return { kicker: text.kicker, title: name, note: text.noPhoto };
45848
- return { kicker: text.kicker, title: name, image: { url: photo2.url, alt: fill(text.alt, { weapon: name }), credit: `${photo2.author} \xB7 ${photo2.license}`, page: photo2.page } };
46347
+ if (!photo2) return void 0;
46348
+ return { url: photo2.url, alt: fill(text.alt, { weapon: arsenal.name(weapon) }), credit: `${photo2.author} \xB7 ${photo2.license}`, page: photo2.page };
45849
46349
  }
45850
46350
  function createWeaponShowcase(options) {
45851
- const { arsenal, host, text } = options;
46351
+ const { arsenal, host, text, referencePhotos = false } = options;
45852
46352
  const THREE = host.THREE;
45853
46353
  const scene = host.scene;
45854
46354
  const centre = [SHOWCASE.at[0], SHOWCASE.height + SHOWCASE.lift, SHOWCASE.at[2]];
@@ -45858,7 +46358,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
45858
46358
  if (!shown) return;
45859
46359
  discardObject3D(shown.root);
45860
46360
  shown = null;
45861
- host.bench?.sheet?.(null);
46361
+ if (referencePhotos) host.cornerImage?.(null);
45862
46362
  };
45863
46363
  const look = () => host.bench?.look([centre[0] + SHOWCASE.eye[0], centre[1] + SHOWCASE.eye[1], centre[2] + SHOWCASE.eye[2]], centre);
45864
46364
  const show = (weapon) => {
@@ -45872,7 +46372,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
45872
46372
  holder.position.set(...centre);
45873
46373
  scene.add(holder);
45874
46374
  shown = { id: weapon, root: holder };
45875
- host.bench?.sheet?.(showcaseSheet(arsenal, text, weapon));
46375
+ if (referencePhotos) host.cornerImage?.(showcasePhoto(arsenal, text, weapon) ?? null);
45876
46376
  host.log(fill(text.shown, { weapon: arsenal.name(weapon) }), { weapon, photo: weapon in PHOTOS });
45877
46377
  look();
45878
46378
  };
@@ -45905,26 +46405,22 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
45905
46405
  en: {
45906
46406
  pedestal: "Weapon showcase",
45907
46407
  weapon: "Showcase",
45908
- weaponHint: "Puts the weapon on the pedestal, turning slowly, takes the camera to it and shows a photo of the real one to compare with",
46408
+ weaponHint: "Puts the weapon on the pedestal, turning slowly, and takes the camera to it",
45909
46409
  none: "None",
45910
46410
  spin: "Turn the weapon",
45911
46411
  look: "Look at the showcase",
45912
- kicker: "The real weapon",
45913
46412
  alt: "Photo of a real {weapon}",
45914
- shown: "{weapon} on the showcase",
45915
- noPhoto: "No free photo of this exact model was found: it is listed in missing of assets/weapon-references.json."
46413
+ shown: "{weapon} on the showcase"
45916
46414
  },
45917
46415
  "pt-BR": {
45918
46416
  pedestal: "Vitrine de armas",
45919
46417
  weapon: "Vitrine",
45920
- weaponHint: "P\xF5e a arma no pedestal, girando devagar, leva a c\xE2mera at\xE9 ela e mostra uma foto da arma real para comparar",
46418
+ weaponHint: "P\xF5e a arma no pedestal, girando devagar, e leva a c\xE2mera at\xE9 ela",
45921
46419
  none: "Nenhuma",
45922
46420
  spin: "Girar a arma",
45923
46421
  look: "Olhar a vitrine",
45924
- kicker: "A arma real",
45925
46422
  alt: "Foto de um(a) {weapon} real",
45926
- shown: "{weapon} na vitrine",
45927
- noPhoto: "N\xE3o h\xE1 foto livre deste modelo exato: ele est\xE1 em missing de assets/weapon-references.json."
46423
+ shown: "{weapon} na vitrine"
45928
46424
  }
45929
46425
  };
45930
46426
  var showcaseTextOf = (locale) => TEXT[locale] ?? TEXT.en;
@@ -45985,7 +46481,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
45985
46481
  return { id: options.id, samples };
45986
46482
  }
45987
46483
 
45988
- // ../game-audio/dist/chunk-UUWKSG4J.js
46484
+ // ../game-audio/dist/chunk-BUYBYP4L.js
45989
46485
  var DISTANCE_CURVES = {
45990
46486
  /** The game's `sfx`: `vol / (1 + d² × 0.004)`, cutoff `/ (1 + d × 0.01)`, silent below 0.01 (jogo L62091–62092, L62101). */
45991
46487
  game_sfx: { model: "inverse_square", k: 4e-3, cutoffK: 0.01, minGain: 0.01 },
@@ -47858,7 +48354,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
47858
48354
  const registry = createSoundRegistry(options.banks);
47859
48355
  const voices = createVoiceManager({ ...options.groups ? { groups: options.groups } : {}, ...options.maxVoices === void 0 ? {} : { maxVoices: options.maxVoices } });
47860
48356
  const engineRandom = createRng3(seed);
47861
- const shared2 = createNoiseStore(engineRandom);
48357
+ const shared3 = createNoiseStore(engineRandom);
47862
48358
  const busSettings = /* @__PURE__ */ new Map();
47863
48359
  const busNodes = /* @__PURE__ */ new Map();
47864
48360
  const meters = /* @__PURE__ */ new Map();
@@ -47934,7 +48430,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
47934
48430
  if (!created) return null;
47935
48431
  context = created;
47936
48432
  chain = buildChain(created, mix3, engineRandom);
47937
- if (mix3.noise.create === "eager") noiseBuffer(shared2, created, mix3.noise.seconds);
48433
+ if (mix3.noise.create === "eager") noiseBuffer(shared3, created, mix3.noise.seconds);
47938
48434
  for (const [bus, setting] of Object.entries(mix3.buses ?? {})) {
47939
48435
  busSettings.set(bus, { ...setting, ...busSettings.get(bus) });
47940
48436
  }
@@ -48160,8 +48656,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
48160
48656
  const loopHost = {
48161
48657
  ready,
48162
48658
  output: outputFor,
48163
- prepareNoise: () => context && prepareNoise(shared2, context, mix3.noise.seconds),
48164
- noise: () => noiseBuffer(shared2, context, mix3.noise.seconds),
48659
+ prepareNoise: () => context && prepareNoise(shared3, context, mix3.noise.seconds),
48660
+ noise: () => noiseBuffer(shared3, context, mix3.noise.seconds),
48165
48661
  register: (loop) => void loops.add(loop),
48166
48662
  unregister: (loop) => void loops.delete(loop),
48167
48663
  listener: () => listener,
@@ -48206,7 +48702,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
48206
48702
  watchers.add(listener2);
48207
48703
  return () => void watchers.delete(listener2);
48208
48704
  },
48209
- play: (id, playOptions = {}) => playWith(id, playOptions, randomFor(playOptions), shared2),
48705
+ play: (id, playOptions = {}) => playWith(id, playOptions, randomFor(playOptions), shared3),
48210
48706
  playPlan(plan, playOptions = {}) {
48211
48707
  const audio = ready();
48212
48708
  if (!audio) return null;
@@ -48214,8 +48710,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
48214
48710
  const recipe2 = { id: plan.id, bus: plan.bus, layers: [], sources: [], priority: plan.priority, ...plan.group ? { group: plan.group } : {} };
48215
48711
  const voiceId = plan.silent ? void 0 : admit(recipe2, plan.level, plan.distance);
48216
48712
  if (voiceId === null) return null;
48217
- if (planUsesNoise(plan)) prepareNoise(shared2, audio, mix3.noise.seconds);
48218
- return start(plan, shared2, voiceId, playOptions.delay);
48713
+ if (planUsesNoise(plan)) prepareNoise(shared3, audio, mix3.noise.seconds);
48714
+ return start(plan, shared3, voiceId, playOptions.delay);
48219
48715
  },
48220
48716
  loop(id, loopOptions = {}) {
48221
48717
  const sample = registry.sample(id);
@@ -48241,7 +48737,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
48241
48737
  },
48242
48738
  channel(channelOptions) {
48243
48739
  const random = channelOptions.random ?? (channelOptions.seed === void 0 ? engineRandom : createRng3(channelOptions.seed));
48244
- const store = channelOptions.ownNoise ? createNoiseStore(random) : shared2;
48740
+ const store = channelOptions.ownNoise ? createNoiseStore(random) : shared3;
48245
48741
  return {
48246
48742
  random,
48247
48743
  play: (id, playOptions = {}) => playWith(id, playOptions, random, store),
@@ -48263,7 +48759,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
48263
48759
  if (!context || !chain) return;
48264
48760
  const old = chain;
48265
48761
  chain = buildChain(context, mix3, engineRandom);
48266
- if (mix3.noise.seconds !== previous.noise.seconds) shared2.reset();
48762
+ if (mix3.noise.seconds !== previous.noise.seconds) shared3.reset();
48267
48763
  for (const node of busNodes.values()) {
48268
48764
  node.disconnect();
48269
48765
  node.connect(chain.master);
@@ -48282,7 +48778,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
48282
48778
  warmUp() {
48283
48779
  const audio = ready();
48284
48780
  if (!audio) return false;
48285
- noiseBuffer(shared2, audio, mix3.noise.seconds);
48781
+ noiseBuffer(shared3, audio, mix3.noise.seconds);
48286
48782
  return true;
48287
48783
  },
48288
48784
  level(bus) {
@@ -48318,7 +48814,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
48318
48814
  chain = null;
48319
48815
  busNodes.clear();
48320
48816
  meters.clear();
48321
- shared2.reset();
48817
+ shared3.reset();
48322
48818
  sampleStore.clear();
48323
48819
  memory.clear();
48324
48820
  sampleLimiters.clear();
@@ -48380,6 +48876,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
48380
48876
  ["revolver_38_357", 2, "sfx_pistol"],
48381
48877
  ["revolver_44_50ae", 3, "sfx_pistol"],
48382
48878
  ["smg_9mm_auto", 1, "sfx_pistol"],
48879
+ ["launcher_40mm", 2],
48880
+ ["rocket_launch", 2],
48383
48881
  ["shotgun_12", 1, "sfx_shotgun"],
48384
48882
  ["rifle_5_56", 1, "sfx_rifle"],
48385
48883
  ["rifle_7_62x39", 1, "sfx_rifle"],
@@ -51520,6 +52018,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
51520
52018
  priority: 3
51521
52019
  };
51522
52020
  var SUPPRESSED_SAMPLE = { ...GUNSHOT_SAMPLE, gain: 0.55, crossover: { from: 10, to: 50 }, falloff: { model: "inverse_square", k: 4e-3, minGain: 8e-4 } };
52021
+ var LAUNCH_SAMPLE = { bus: "weapons", gain: 0.9, pitch: 0.04, falloff: { model: "inverse_square", k: 1e-3, minGain: 1e-3 }, cutoffK: 0.03, priority: 3 };
52022
+ var LAUNCH_IDS = /* @__PURE__ */ new Set(["launcher_40mm", "rocket_launch"]);
51523
52023
  var RELOAD_SAMPLE = { bus: "weapons", gain: 0.32, pitch: 0.05, falloff: { model: "inverse_square", k: 0.05, minGain: 2e-3 }, cutoffK: 0.02, priority: 2 };
51524
52024
  var CASING_SAMPLE = { bus: "weapons", gain: 0.22, pitch: 0.06, falloff: { model: "inverse_square", k: 0.08, minGain: 3e-3 }, cutoffK: 0.03, priority: 1 };
51525
52025
  var casingSampleId = (sample) => sample.replace(/_(pistol|rifle|shell)$/, "");
@@ -51529,7 +52029,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
51529
52029
  var isGunshot = (id) => GUNSHOT_SAMPLE_IDS.includes(id);
51530
52030
  function weaponSampleDefaults(sound3, overrides = {}) {
51531
52031
  if (sound3.category !== "armas") return void 0;
51532
- const base = sound3.id.startsWith("suppressed_") ? SUPPRESSED_SAMPLE : isGunshot(sound3.id) ? GUNSHOT_SAMPLE : sound3.id.startsWith("casing_drop_") || sound3.id.startsWith("mag_drop_") ? CASING_SAMPLE : RELOAD_SAMPLE;
52032
+ const base = LAUNCH_IDS.has(sound3.id) ? LAUNCH_SAMPLE : sound3.id.startsWith("suppressed_") ? SUPPRESSED_SAMPLE : isGunshot(sound3.id) ? GUNSHOT_SAMPLE : sound3.id.startsWith("casing_drop_") || sound3.id.startsWith("mag_drop_") ? CASING_SAMPLE : RELOAD_SAMPLE;
51533
52033
  return { ...base, ...overrides[sound3.id] };
51534
52034
  }
51535
52035
  function weaponSampleBank(options) {
@@ -51550,6 +52050,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
51550
52050
  }
51551
52051
 
51552
52052
  // src/audio.ts
52053
+ var LAUNCH_SOUND_IDS = { grenade: "launcher_40mm", rocket: "rocket_launch" };
52054
+ var LAUNCH_HALF_AT = 40;
51553
52055
  var NOISE_SECONDS = 1.5;
51554
52056
  var DEFAULT_SEED = 1;
51555
52057
  function createWeaponAudio(volume = 0.6, options = {}) {
@@ -51558,15 +52060,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
51558
52060
  const distanceCurve = { ...GAME_DISTANCE_CURVE, ...options.distance };
51559
52061
  const mechanicalTable = { ...MECHANICAL_SOUNDS, ...options.mechanical };
51560
52062
  const cueTable = { ...RELOAD_CUES, ...options.reloadCues };
51561
- const shared2 = options.engine;
51562
- if (!shared2) warnOnce("game-weapons-three.own-audio-engine", "game-weapons-three made an audio engine of its own because the host lent none (options.engine); pass the host engine so the sounds share one mix and one voice limit");
51563
- const engine = shared2 ?? createAudioEngine({
52063
+ const shared3 = options.engine;
52064
+ if (!shared3) warnOnce("game-weapons-three.own-audio-engine", "game-weapons-three made an audio engine of its own because the host lent none (options.engine); pass the host engine so the sounds share one mix and one voice limit");
52065
+ const engine = shared3 ?? createAudioEngine({
51564
52066
  seed,
51565
52067
  mix: { ...MIX_PROFILES.game, master: volume, noise: { seconds: NOISE_SECONDS, create: "eager" } },
51566
52068
  maxVoices: Number.POSITIVE_INFINITY,
51567
52069
  ...options.createContext ? { createContext: options.createContext } : {}
51568
52070
  });
51569
- const channel = shared2 && options.seed !== void 0 ? shared2.channel({ seed }) : engine.channel({});
52071
+ const channel = shared3 && options.seed !== void 0 ? shared3.channel({ seed }) : engine.channel({});
51570
52072
  engine.register({ id: `weapons_three@${classBurstId(distanceCurve)}`, sounds: weaponRecipes(distanceCurve) });
51571
52073
  const classBurst = classBurstId(distanceCurve);
51572
52074
  const sampleBank = options.samples ? weaponSampleBank(options.samples) : null;
@@ -51756,13 +52258,24 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
51756
52258
  }
51757
52259
  burst2({ seconds: 0.09, gain: 0.35 * (input.speed === void 0 ? 1 : Math.min(1, Math.max(0.3, input.speed / 2.5))) * ((input.bounce ?? 0) === 0 ? 1 : 0.5), filter: "lowpass", frequency: 380 });
51758
52260
  },
52261
+ launch(kind, volume2 = 1, distance3 = 0) {
52262
+ const level = Math.min(1, volume2 / (1 + distance3 / LAUNCH_HALF_AT));
52263
+ const id = LAUNCH_SOUND_IDS[kind];
52264
+ if (hostReady(id)) {
52265
+ channel.play(id, { volume: level });
52266
+ return;
52267
+ }
52268
+ burst2({ seconds: kind === "rocket" ? 0.22 : 0.16, gain: 0.7 * level, filter: "lowpass", frequency: kind === "rocket" ? 220 : 170 });
52269
+ burst2({ seconds: 0.035, gain: 0.25 * level, filter: "highpass", frequency: 1800 });
52270
+ if (kind === "rocket") burst2({ seconds: 0.8, gain: 0.3 * level, filter: "highpass", frequency: 1100, at: 0.04 });
52271
+ },
51759
52272
  setVolume(next) {
51760
52273
  const level = Math.max(0, Math.min(1, next));
51761
- if (shared2) shared2.setBus("weapons", { gain: level });
52274
+ if (shared3) shared3.setBus("weapons", { gain: level });
51762
52275
  else engine.setMaster(level);
51763
52276
  },
51764
52277
  dispose() {
51765
- if (!shared2) engine.dispose();
52278
+ if (!shared3) engine.dispose();
51766
52279
  }
51767
52280
  };
51768
52281
  }
@@ -57465,7 +57978,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
57465
57978
  var ballisticVest = ({ mesh: mesh3, bx, G, cloth: cloth2, metal: metal2, plastic }) => {
57466
57979
  const shell = cloth2(4936761);
57467
57980
  const strap = cloth2(3817776);
57468
- const plate2 = plastic(2764074);
57981
+ const plate3 = plastic(2764074);
57469
57982
  const buckle = metal2(9080208);
57470
57983
  return G(
57471
57984
  mesh3(bx(0.34, 0.045, 0.34), shell, [0, 0.0225, 0.055]),
@@ -57473,7 +57986,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
57473
57986
  mesh3(bx(0.08, 0.022, 0.1), strap, [0.1, 0.011, -0.175]),
57474
57987
  mesh3(bx(0.03, 0.04, 0.22), strap, [-0.185, 0.02, 0.1]),
57475
57988
  mesh3(bx(0.03, 0.04, 0.22), strap, [0.185, 0.02, 0.1]),
57476
- mesh3(bx(0.24, 0.025, 0.24), plate2, [0, 0.0575, 0.03]),
57989
+ mesh3(bx(0.24, 0.025, 0.24), plate3, [0, 0.0575, 0.03]),
57477
57990
  mesh3(bx(0.07, 0.02, 0.05), strap, [-0.1, 0.055, 0.19]),
57478
57991
  mesh3(bx(0.07, 0.02, 0.05), strap, [0, 0.055, 0.19]),
57479
57992
  mesh3(bx(0.07, 0.02, 0.05), strap, [0.1, 0.055, 0.19]),
@@ -59366,7 +59879,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
59366
59879
 
59367
59880
  // src/models/melee.ts
59368
59881
  var QUARTER = Math.PI / 2;
59369
- var plate = (kit, parent, profile, thickness, y, material) => {
59882
+ var plate2 = (kit, parent, profile, thickness, y, material) => {
59370
59883
  const shape = new kit.THREE.Shape();
59371
59884
  profile.forEach(([x, z], index) => index === 0 ? shape.moveTo(x, -z) : shape.lineTo(x, -z));
59372
59885
  const mesh3 = new kit.THREE.Mesh(new kit.THREE.ExtrudeGeometry(shape, { depth: thickness, bevelEnabled: false }), material);
@@ -59385,7 +59898,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
59385
59898
  box5(group, 7e-3, 0.012, 0.052, M.metal, 0.1325, axis2, 0);
59386
59899
  box5(group, 0.012, 0.012, 4e-3, M.metal, 0.136, axis2, 0.026);
59387
59900
  box5(group, 0.012, 0.012, 4e-3, M.metal, 0.136, axis2, -0.026);
59388
- plate(kit, group, [[0.136, -0.0165], [0.248, -0.0165], [0.272, -0.0135], [0.2995, -6e-3], [0.3, -1e-3], [0.282, 8e-3], [0.255, 0.0165], [0.136, 0.0165]], 45e-4, axis2 - 225e-5, M.metal);
59901
+ plate2(kit, group, [[0.136, -0.0165], [0.248, -0.0165], [0.272, -0.0135], [0.2995, -6e-3], [0.3, -1e-3], [0.282, 8e-3], [0.255, 0.0165], [0.136, 0.0165]], 45e-4, axis2 - 225e-5, M.metal);
59389
59902
  box5(group, 0.095, 16e-4, 45e-4, M.dark, 0.19, axis2 + 23e-4, 6e-3);
59390
59903
  return { handle: [0.07, axis2, 0] };
59391
59904
  };
@@ -59420,7 +59933,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
59420
59933
  spine.push([x, bow(t) + halfWidth(t)]);
59421
59934
  }
59422
59935
  const tip = [KATANA_TIP, bow(1) + 4e-3];
59423
- plate(kit, group, [...edge, tip, ...spine.reverse()], 55e-4, axis2 - 275e-5, M.steelL);
59936
+ plate2(kit, group, [...edge, tip, ...spine.reverse()], 55e-4, axis2 - 275e-5, M.steelL);
59424
59937
  return { handle: [0.2, axis2, 0], support: [0.07, axis2, 0] };
59425
59938
  };
59426
59939
  var RING_Z = [-0.0455, -0.0155, 0.0155, 0.0455];
@@ -65774,12 +66287,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
65774
66287
  }
65775
66288
  function drawing(entry2, action) {
65776
66289
  const context = engine.context;
65777
- const shared2 = context.random;
66290
+ const shared3 = context.random;
65778
66291
  if (entry2.random) context.random = entry2.random;
65779
66292
  try {
65780
66293
  action();
65781
66294
  } finally {
65782
- context.random = shared2;
66295
+ context.random = shared3;
65783
66296
  }
65784
66297
  }
65785
66298
  return {
@@ -65986,7 +66499,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
65986
66499
  const size = random.between(0.12, 0.26) * Math.min(1.6, 0.6 + radius * 0.4);
65987
66500
  const px = x + Math.cos(angle) * distance3;
65988
66501
  const pz = z + Math.sin(angle) * distance3;
65989
- const plate2 = random.next() < 0.6;
66502
+ const plate3 = random.next() < 0.6;
65990
66503
  const color2 = RIM_COLORS[random.next() < 0.5 ? 0 : 1];
65991
66504
  const tiltX = random.between(-0.5, 0.5);
65992
66505
  const tiltZ = random.between(-0.6, 0.2);
@@ -65997,7 +66510,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
65997
66510
  z: pz,
65998
66511
  scale: [size * 2, size * 0.35, size * 1.4],
65999
66512
  rotation: [tiltX, angle, tiltZ],
66000
- plate: plate2,
66513
+ plate: plate3,
66001
66514
  color: color2
66002
66515
  });
66003
66516
  }
@@ -66304,8 +66817,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
66304
66817
  if (direction) normalize2(addScaled(d, direction, 0.8));
66305
66818
  const speed = random.between(4, 11) * (chunks.speed ?? 1);
66306
66819
  const s = random.between(0.07, 0.2) * (chunks.size ?? 1);
66307
- const plate2 = chunks.plate ? random.next() < 0.6 : random.next() < 0.15;
66308
- const sy = plate2 ? s * 0.3 : s * random.between(0.6, 1);
66820
+ const plate3 = chunks.plate ? random.next() < 0.6 : random.next() < 0.15;
66821
+ const sy = plate3 ? s * 0.3 : s * random.between(0.6, 1);
66309
66822
  const color2 = hexToRgb2(chunks.colors.length > 0 ? pick22(random, chunks.colors) : DEFAULT_CHUNK_COLOR);
66310
66823
  const hot = random.next() < chunks.hot;
66311
66824
  addChunk(core, random, {
@@ -66315,11 +66828,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
66315
66828
  vx: d.x * speed,
66316
66829
  vy: d.y * speed + 2,
66317
66830
  vz: d.z * speed,
66318
- sx: plate2 ? s * 1.6 : s,
66831
+ sx: plate3 ? s * 1.6 : s,
66319
66832
  sy,
66320
- sz: plate2 ? s * 1.1 : s,
66833
+ sz: plate3 ? s * 1.1 : s,
66321
66834
  color: color2,
66322
- plate: plate2,
66835
+ plate: plate3,
66323
66836
  hot
66324
66837
  });
66325
66838
  }
@@ -66851,8 +67364,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
66851
67364
  id: "dust",
66852
67365
  additive: false,
66853
67366
  life: [
66854
- 1,
66855
- 2
67367
+ 2,
67368
+ 5
66856
67369
  ],
66857
67370
  size: [
66858
67371
  0.08,
@@ -66919,8 +67432,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
66919
67432
  id: "chips",
66920
67433
  additive: false,
66921
67434
  life: [
66922
- 0.8,
66923
- 1.5
67435
+ 2,
67436
+ 4
66924
67437
  ],
66925
67438
  size: [
66926
67439
  0.025,
@@ -68336,7 +68849,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
68336
68849
  };
68337
68850
  }
68338
68851
 
68339
- // ../game-vfx-three/dist/chunk-CPRCWTSQ.js
68852
+ // ../game-vfx-three/dist/chunk-IOGYK5RO.js
68340
68853
  var GLOW_VERTEX = `attribute vec4 aP;attribute vec4 aC;varying vec2 vU;varying vec4 vC;
68341
68854
  void main(){vec3 R=vec3(viewMatrix[0][0],viewMatrix[1][0],viewMatrix[2][0]);vec3 Up=vec3(viewMatrix[0][1],viewMatrix[1][1],viewMatrix[2][1]);
68342
68855
  vec3 wp=aP.xyz+(R*position.x+Up*position.y)*aP.w;vU=position.xy;vC=aC;gl_Position=projectionMatrix*viewMatrix*vec4(wp,1.);}`;
@@ -68383,10 +68896,15 @@ void main(){
68383
68896
  if(n<diss*1.08-.04)discard;
68384
68897
  float lam=max(dot(N,uLight),0.);
68385
68898
  float band=lam>.55?1.:lam>.15?.68:.42;
68386
- vec3 col=vC*(vec3(.5,.56,.7)*band*1.05+vec3(.2,.19,.18)+uGround*(.4-.4*N.y));
68899
+ // soot: a dark smoke still scatters some light, so it never goes flat black, and its rim takes the sky so its volume reads (only the dark puffs; the rest as the Lab)
68900
+ float dark=1.-smoothstep(.02,.12,dot(vC,vec3(.2126,.7152,.0722)));
68901
+ vec3 alb=max(vC,vec3(.055)*dark);
68902
+ vec3 col=alb*(vec3(.5,.56,.7)*band*1.05+vec3(.2,.19,.18)+uGround*(.4-.4*N.y));
68903
+ float rim=pow(1.-clamp(abs(dot(N,normalize(cameraPosition-vWP))),0.,1.),2.);
68904
+ col+=dark*rim*(uSky*.9+alb);
68387
68905
  vec3 tg=uGlowPos-vWP;float dg=length(tg)+.001;
68388
68906
  float gi=uGlowI/(1.+dg*dg*.05)*(.3+.7*max(dot(N,tg/dg),0.));
68389
- col+=uGlowCol*gi*vC*1.6;
68907
+ col+=uGlowCol*gi*alb*1.6;
68390
68908
  float h=heat*(.72+.56*n)+heat*(-N.y)*.18;
68391
68909
  if(h>.05){
68392
68910
  float hq=floor(h*5.+.5)/5.;
@@ -71140,13 +71658,14 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
71140
71658
  else if (tool2.suppressed !== void 0) current.suppressed = tool2.suppressed;
71141
71659
  else current.suppressed = hasSuppressor(tool2.attachments ? fittedOf2(tool2.attachments) : current.def.fitted ?? []);
71142
71660
  if (tool2.underbarrelActive && current.model.parts.uglMuzzle) {
71143
- audio?.play("explosion", LAUNCH_VOLUME, distance3());
71661
+ audio?.launch("grenade", LAUNCH_VOLUME, distance3());
71144
71662
  return;
71145
71663
  }
71146
71664
  const action = current.def.action;
71147
71665
  if (action.kind === "launcher") {
71148
- if (current.model.parts.family === "rocket") launchRocket(heavy(current), options.flyRocket !== false);
71149
- audio?.play("explosion", LAUNCH_VOLUME, distance3());
71666
+ const isRocket = current.model.parts.family === "rocket";
71667
+ if (isRocket) launchRocket(heavy(current), options.flyRocket !== false);
71668
+ audio?.launch(isRocket ? "rocket" : "grenade", LAUNCH_VOLUME, distance3());
71150
71669
  }
71151
71670
  if (action.kind !== "firearm") return;
71152
71671
  const caliber = caliberOf(arsenal, current.def);
@@ -72886,7 +73405,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
72886
73405
  fx = created;
72887
73406
  const camera2 = lent.camera;
72888
73407
  const accessories = createAccessoryBench({ arsenal, host: lent, text: accessoryText });
72889
- const showcase = createWeaponShowcase({ arsenal, host: lent, text: showcaseText });
73408
+ const showcase = createWeaponShowcase({ arsenal, host: lent, text: showcaseText, referencePhotos: options.referencePhotos === true });
72890
73409
  const offBench = lent.bench?.onChange((change) => {
72891
73410
  if (accessories.handleChange(change) || showcase.handleChange(change)) return;
72892
73411
  if (change.kind === "layer") {