@adatechnology/game-floorplan-three 0.2.0 → 0.2.1

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.
@@ -54,6 +54,7 @@ var GameFloorplanThree = (() => {
54
54
  create: () => create,
55
55
  createNodeSkin: () => createNodeSkin,
56
56
  createRecorder: () => createRecorder,
57
+ createShapeRecorder: () => createShapeRecorder,
57
58
  hex: () => hex,
58
59
  listTypes: () => listTypes,
59
60
  locales: () => locales,
@@ -64,6 +65,228 @@ var GameFloorplanThree = (() => {
64
65
  seedOf: () => seedOf,
65
66
  shade: () => shade
66
67
  });
68
+
69
+ // ../game-shapes/dist/chunk-R4RY23RH.js
70
+ function normalMatrix(me) {
71
+ const n11 = me[0], n21 = me[1], n31 = me[2];
72
+ const n12 = me[4], n22 = me[5], n32 = me[6];
73
+ const n13 = me[8], n23 = me[9], n33 = me[10];
74
+ const t11 = n33 * n22 - n32 * n23;
75
+ const t12 = n32 * n13 - n33 * n12;
76
+ const t13 = n23 * n12 - n22 * n13;
77
+ const det = n11 * t11 + n21 * t12 + n31 * t13;
78
+ if (det === 0) return [0, 0, 0, 0, 0, 0, 0, 0, 0];
79
+ const detInv = 1 / det;
80
+ const te = [
81
+ t11 * detInv,
82
+ (n31 * n23 - n33 * n21) * detInv,
83
+ (n32 * n21 - n31 * n22) * detInv,
84
+ t12 * detInv,
85
+ (n33 * n11 - n31 * n13) * detInv,
86
+ (n31 * n12 - n32 * n11) * detInv,
87
+ t13 * detInv,
88
+ (n21 * n13 - n23 * n11) * detInv,
89
+ (n22 * n11 - n21 * n12) * detInv
90
+ ];
91
+ let tmp = te[1];
92
+ te[1] = te[3];
93
+ te[3] = tmp;
94
+ tmp = te[2];
95
+ te[2] = te[6];
96
+ te[6] = tmp;
97
+ tmp = te[5];
98
+ te[5] = te[7];
99
+ te[7] = tmp;
100
+ return te;
101
+ }
102
+ function transformPoint(e, x, y, z) {
103
+ const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]);
104
+ return [(e[0] * x + e[4] * y + e[8] * z + e[12]) * w, (e[1] * x + e[5] * y + e[9] * z + e[13]) * w, (e[2] * x + e[6] * y + e[10] * z + e[14]) * w];
105
+ }
106
+ var num = (v) => typeof v === "number" && Number.isFinite(v) ? null : "expected a finite number";
107
+ var bool = (v) => typeof v === "boolean" ? null : "expected a boolean";
108
+ var str = (v) => typeof v === "string" ? null : "expected a string";
109
+ var int = (min) => (v) => typeof v === "number" && Number.isInteger(v) && v >= min ? null : `expected an integer >= ${min}`;
110
+ var range = (lo, hi, loOpen = false) => (v) => typeof v === "number" && (loOpen ? v > lo : v >= lo) && v <= hi ? null : `expected a number in ${loOpen ? "(" : "["}${lo}, ${hi}]`;
111
+ var tuple = (n, item = num) => (v) => {
112
+ if (!Array.isArray(v) || v.length !== n) return `expected an array of ${n}`;
113
+ for (const x of v) if (item(x)) return `expected an array of ${n} numbers`;
114
+ return null;
115
+ };
116
+ var list = (item, min = 0) => (v) => {
117
+ if (!Array.isArray(v)) return "expected an array";
118
+ if (v.length < min) return `expected at least ${min} items`;
119
+ for (let i = 0; i < v.length; i++) {
120
+ const e = item(v[i]);
121
+ if (e) return `[${i}]: ${e}`;
122
+ }
123
+ return null;
124
+ };
125
+ var color = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0 && v <= 16777215 || typeof v === "string" && /^#[0-9a-fA-F]{6}$/.test(v) ? null : 'expected 0xRRGGBB or "#rrggbb"';
126
+ var oneOf = (values) => (v) => values.includes(v) ? null : `expected one of ${values.map((x) => JSON.stringify(x)).join(", ")}`;
127
+ var object = (fields, required = []) => (v) => {
128
+ if (!v || typeof v !== "object" || Array.isArray(v)) return "expected an object";
129
+ const record = v;
130
+ for (const key of required) if (record[key] === void 0) return `${key}: required`;
131
+ for (const key of Object.keys(record)) {
132
+ if (record[key] === void 0) continue;
133
+ const check = fields[key];
134
+ if (!check) return `${key}: unknown field`;
135
+ const e = check(record[key]);
136
+ if (e) return `${key}: ${e}`;
137
+ }
138
+ return null;
139
+ };
140
+ var ORDERS = ["XYZ", "YXZ", "ZXY", "ZYX", "YZX", "XZY"];
141
+ var TRANSFORM = {
142
+ position: tuple(3),
143
+ rotation: tuple(3),
144
+ rotationOrder: oneOf(ORDERS),
145
+ scale: (v) => typeof v === "number" ? num(v) : tuple(3)(v),
146
+ heading: num,
147
+ matrix: tuple(16)
148
+ };
149
+ var UV = object({ u0: num, v0: num, u1: num, v1: num }, ["u0", "v0", "u1", "v1"]);
150
+ var INSTANCE = object({ ...TRANSFORM, color });
151
+ var COMMON = {
152
+ ...TRANSFORM,
153
+ kind: str,
154
+ name: str,
155
+ part: str,
156
+ material: str,
157
+ color,
158
+ uv: UV,
159
+ instances: list(INSTANCE),
160
+ minDetail: range(0, 1, true),
161
+ tags: list(str)
162
+ };
163
+ var vec2 = tuple(2);
164
+ var BEVEL = (v) => v === false ? null : object({ thickness: num, size: num, offset: num, segments: int(1) })(v);
165
+ var KINDS = {
166
+ group: { fields: {} },
167
+ box: { fields: { size: tuple(3), segments: tuple(3, int(1)) } },
168
+ cylinder: { fields: { radiusTop: num, radiusBottom: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },
169
+ cone: { fields: { radius: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },
170
+ sphere: { fields: { radius: num, widthSegments: int(3), heightSegments: int(2), phiStart: num, phiLength: num, thetaStart: num, thetaLength: num } },
171
+ plane: { fields: { width: num, height: num, widthSegments: int(1), heightSegments: int(1) } },
172
+ circle: { fields: { radius: num, segments: int(3), thetaStart: num, thetaLength: num } },
173
+ ring: { fields: { innerRadius: num, outerRadius: num, thetaSegments: int(3), phiSegments: int(1), thetaStart: num, thetaLength: num } },
174
+ lathe: { fields: { points: list(vec2, 2), segments: int(1), phiStart: num, phiLength: num }, required: ["points"] },
175
+ torus: { fields: { radius: num, tube: num, radialSegments: int(1), tubularSegments: int(1), arc: num } },
176
+ extrude: {
177
+ fields: { shape: object({ outer: list(vec2, 3), holes: list(list(vec2, 3)) }, ["outer"]), depth: num, steps: int(1), bevel: BEVEL },
178
+ required: ["shape"]
179
+ },
180
+ difference: { fields: { size: tuple(3), subtract: list(object({ min: vec2, max: vec2 }, ["min", "max"])) }, required: ["size", "subtract"] },
181
+ mesh: {
182
+ fields: {
183
+ positions: (v) => list(num)(v) ?? (v.length % 3 === 0 ? null : "expected a multiple of 3 numbers"),
184
+ normals: list(num),
185
+ uvs: list(num),
186
+ indices: list(int(0))
187
+ },
188
+ required: ["positions"]
189
+ },
190
+ point: { fields: { data: () => null } },
191
+ custom: { fields: { generator: str, params: () => null }, required: ["generator"] }
192
+ };
193
+ function mergeTransformed(pieces) {
194
+ let total = 0;
195
+ for (const piece2 of pieces) total += piece2.indices ? piece2.indices.length : piece2.positions.length / 3;
196
+ const positions = new Float32Array(total * 3);
197
+ const normals = new Float32Array(total * 3);
198
+ const uvs = new Float32Array(total * 2);
199
+ let at = 0;
200
+ for (const piece2 of pieces) {
201
+ const e = piece2.matrix;
202
+ const nm = normalMatrix(e);
203
+ const count = piece2.indices ? piece2.indices.length : piece2.positions.length / 3;
204
+ const p = new Float32Array(count * 3);
205
+ const n = new Float32Array(count * 3);
206
+ for (let k = 0; k < count; k++) {
207
+ const i = piece2.indices ? piece2.indices[k] : k;
208
+ for (let c = 0; c < 3; c++) {
209
+ p[k * 3 + c] = piece2.positions[i * 3 + c];
210
+ if (piece2.normals) n[k * 3 + c] = piece2.normals[i * 3 + c];
211
+ }
212
+ if (piece2.uvs) {
213
+ uvs[(at + k) * 2] = piece2.uvs[i * 2];
214
+ uvs[(at + k) * 2 + 1] = piece2.uvs[i * 2 + 1];
215
+ }
216
+ }
217
+ for (let k = 0; k < count; k++) {
218
+ const q = transformPoint(e, p[k * 3], p[k * 3 + 1], p[k * 3 + 2]);
219
+ positions[(at + k) * 3] = q[0];
220
+ positions[(at + k) * 3 + 1] = q[1];
221
+ positions[(at + k) * 3 + 2] = q[2];
222
+ const x = n[k * 3];
223
+ const y = n[k * 3 + 1];
224
+ const z = n[k * 3 + 2];
225
+ const vx = nm[0] * x + nm[3] * y + nm[6] * z;
226
+ const vy = nm[1] * x + nm[4] * y + nm[7] * z;
227
+ const vz = nm[2] * x + nm[5] * y + nm[8] * z;
228
+ const s = 1 / (Math.sqrt(vx * vx + vy * vy + vz * vz) || 1);
229
+ normals[(at + k) * 3] = vx * s;
230
+ normals[(at + k) * 3 + 1] = vy * s;
231
+ normals[(at + k) * 3 + 2] = vz * s;
232
+ }
233
+ at += count;
234
+ }
235
+ return { positions, normals, uvs };
236
+ }
237
+
238
+ // ../game-shapes-three/dist/index.js
239
+ var isVisible = (object2) => {
240
+ for (let node = object2; node; node = node.parent) if (!node.visible) return false;
241
+ return true;
242
+ };
243
+ var plain = (attribute) => attribute !== void 0 && !attribute.isInterleavedBufferAttribute && attribute.array instanceof Float32Array && !attribute.normalized;
244
+ function piece(geometry, matrix) {
245
+ const position = geometry.getAttribute("position");
246
+ const normal = geometry.getAttribute("normal");
247
+ const uv = geometry.getAttribute("uv");
248
+ const ok = plain(position) && (normal === void 0 || plain(normal)) && (uv === void 0 || plain(uv)) && position.itemSize === 3 && (uv === void 0 || uv.itemSize === 2);
249
+ if (ok) {
250
+ return { positions: position.array, ...normal ? { normals: normal.array } : {}, ...uv ? { uvs: uv.array } : {}, indices: geometry.index ? geometry.index.array : null, matrix: matrix.elements };
251
+ }
252
+ const flat = geometry.index ? geometry.toNonIndexed() : geometry;
253
+ const read = (name, size) => {
254
+ const attribute = flat.getAttribute(name);
255
+ if (!attribute) return void 0;
256
+ const out = new Float32Array(attribute.count * size);
257
+ for (let i = 0; i < attribute.count; i++) for (let c = 0; c < size; c++) out[i * size + c] = c === 0 ? attribute.getX(i) : c === 1 ? attribute.getY(i) : attribute.getZ(i);
258
+ return out;
259
+ };
260
+ const positions = read("position", 3);
261
+ const normals = read("normal", 3);
262
+ const uvs = read("uv", 2);
263
+ if (flat !== geometry) flat.dispose();
264
+ return { positions, ...normals ? { normals } : {}, ...uvs ? { uvs } : {}, indices: null, matrix: matrix.elements };
265
+ }
266
+ function mergeByMaterial(THREE, root, space) {
267
+ const toSpace = space.matrixWorld.clone().invert();
268
+ const byMaterial = /* @__PURE__ */ new Map();
269
+ root.traverse((object2) => {
270
+ const mesh = object2;
271
+ if (!mesh.isMesh || Array.isArray(mesh.material) || !isVisible(mesh)) return;
272
+ const list2 = byMaterial.get(mesh.material) ?? [];
273
+ list2.push(piece(mesh.geometry, new THREE.Matrix4().multiplyMatrices(toSpace, mesh.matrixWorld)));
274
+ byMaterial.set(mesh.material, list2);
275
+ });
276
+ return [...byMaterial].map(([material, pieces]) => {
277
+ const merged = mergeTransformed(pieces);
278
+ const geometry = new THREE.BufferGeometry();
279
+ geometry.setAttribute("position", new THREE.BufferAttribute(merged.positions, 3));
280
+ geometry.setAttribute("normal", new THREE.BufferAttribute(merged.normals, 3));
281
+ geometry.setAttribute("uv", new THREE.BufferAttribute(merged.uvs, 2));
282
+ const mesh = new THREE.Mesh(geometry, material);
283
+ mesh.castShadow = false;
284
+ mesh.receiveShadow = true;
285
+ return mesh;
286
+ });
287
+ }
288
+
289
+ // ../game-props3d/dist/index.js
67
290
  function rng(seed) {
68
291
  let s = seed >>> 0;
69
292
  return () => {
@@ -567,10 +790,10 @@ var GameFloorplanThree = (() => {
567
790
  if (on) K.light(0, t - 0.15, 0, 16771256, 6, "ceiling_light");
568
791
  };
569
792
  B.pendant = (M, a) => {
570
- const K = kit(M, a), t = K.ceiling(), { h } = K.dim("pendant"), ys = t - h, color = K.main(2763306);
793
+ const K = kit(M, a), t = K.ceiling(), { h } = K.dim("pendant"), ys = t - h, color2 = K.main(2763306);
571
794
  K.box("plain", 0, ys + 0.1, 0, 0.012, h - 0.1, 0.012, 1710618);
572
795
  K.cyl("plain", 0, t - 0.03, 0, 0.05, 0.03, 15262940);
573
- K.cyl("plain", 0, ys, 0, 0.17, 0.14, color, 0, 0, "sphere");
796
+ K.cyl("plain", 0, ys, 0, 0.17, 0.14, color2, 0, 0, "sphere");
574
797
  K.cyl("emissive", 0, ys - 0.035, 0, 0.045, 0.09, 16769184, 0, 0, "sphere");
575
798
  if (M.light) K.light(0, ys - 0.1, 0, 16763008, 6, "pendant");
576
799
  };
@@ -939,9 +1162,9 @@ var GameFloorplanThree = (() => {
939
1162
  K.box("plain", sx + 0.15, 0.012, sz + 0.05, 0.09, 0.07, 0.27, 2763306, 0.9);
940
1163
  };
941
1164
  B.fallen_chair = (M, a) => {
942
- const g = Math.PI / 2, dy = 0.23, api = { box: (Mm, mat, x, y, z, w, h, d, color, ry, rx, rz) => {
1165
+ const g = Math.PI / 2, dy = 0.23, api = { box: (Mm, mat, x, y, z, w, h, d, color2, ry, rx, rz) => {
943
1166
  const cy = y + h / 2;
944
- a.box(Mm, mat, -cy + 0, dy + x - h / 2 + 0 - 0, z, w, h, d, color, ry, rx, g + (rz || 0));
1167
+ a.box(Mm, mat, -cy + 0, dy + x - h / 2 + 0 - 0, z, w, h, d, color2, ry, rx, g + (rz || 0));
945
1168
  } };
946
1169
  const K = kit(M, api), c = K.main(6965808);
947
1170
  K.box("wood", 0, 0.44, 0, 0.42, 0.04, 0.42, c);
@@ -1031,20 +1254,20 @@ var GameFloorplanThree = (() => {
1031
1254
  K.plane("atlas_picture", 0, y + h / 2, d / 2 + 3e-3, w - 0.05, h - 0.05, 16777215, 0, 0, 0, A.mirror());
1032
1255
  };
1033
1256
  B.curtain = (M, a) => {
1034
- const K = kit(M, a), { w, h } = K.dim("curtain"), y = M.y != null && M.y > 0 ? M.y : 0.1, color = K.fabric(pick(K, [14208436, 10465470, 12953740, 14736592])), isOpen = M.open !== false, top = y + h;
1257
+ const K = kit(M, a), { w, h } = K.dim("curtain"), y = M.y != null && M.y > 0 ? M.y : 0.1, color2 = K.fabric(pick(K, [14208436, 10465470, 12953740, 14736592])), isOpen = M.open !== false, top = y + h;
1035
1258
  K.box("metal", 0, top, 0, w + 0.1, 0.025, 0.025, K.metal(5918792));
1036
1259
  for (const s of [-1, 1]) K.cyl("metal", s * (w / 2 + 0.07), top - 0.02, 0, 0.03, 0.07, 5918792, 0, 0, "sphere");
1037
1260
  const pw = isOpen ? Math.min(0.5, w * 0.3) : w / 2 + 0.03, n = Math.max(4, Math.round(pw / 0.08));
1038
1261
  for (const s of [-1, 1]) for (let i = 0; i < n; i++) {
1039
1262
  const ux = isOpen ? s * (w / 2 + 0.03 - pw + (i + 0.5) * pw / n) : s * ((i + 0.5) * pw / n);
1040
- K.box("fabric", ux, y, i % 2 ? 0.025 : -0.01, pw / n * 1.15, h - 0.02, 0.02, i % 2 ? shade(color, 0.9) : color);
1263
+ K.box("fabric", ux, y, i % 2 ? 0.025 : -0.01, pw / n * 1.15, h - 0.02, 0.02, i % 2 ? shade(color2, 0.9) : color2);
1041
1264
  }
1042
- if (isOpen) for (const s of [-1, 1]) K.box("fabric", s * (w / 2 - pw * 0.25), y + h * 0.4, 0.04, pw * 0.5, 0.05, 0.02, shade(color, 0.7));
1265
+ if (isOpen) for (const s of [-1, 1]) K.box("fabric", s * (w / 2 - pw * 0.25), y + h * 0.4, 0.04, pw * 0.5, 0.05, 0.02, shade(color2, 0.7));
1043
1266
  };
1044
1267
  B.blinds = (M, a) => {
1045
- const K = kit(M, a), { w, h } = K.dim("blinds"), y = M.y || 1, retract = M.retracted != null ? M.retracted : 0.15, isWood = M.variant === "wood", color = isWood ? K.wood(10123858) : K.color("wall_living", 15262420), mat = isWood ? "wood" : "plain", yb = y + h * retract, n = Math.floor((y + h - yb) / 0.055);
1268
+ const K = kit(M, a), { w, h } = K.dim("blinds"), y = M.y || 1, retract = M.retracted != null ? M.retracted : 0.15, isWood = M.variant === "wood", color2 = isWood ? K.wood(10123858) : K.color("wall_living", 15262420), mat = isWood ? "wood" : "plain", yb = y + h * retract, n = Math.floor((y + h - yb) / 0.055);
1046
1269
  K.box("plain", 0, y + h - 0.05, 0, w, 0.05, 0.06, 14473424);
1047
- for (let i = 0; i < n; i++) K.box(mat, 0, y + h - 0.06 - (i + 1) * 0.055, 0, w - 0.05, 0.01, 0.035, color, 0, 0.3);
1270
+ for (let i = 0; i < n; i++) K.box(mat, 0, y + h - 0.06 - (i + 1) * 0.055, 0, w - 0.05, 0.01, 0.035, color2, 0, 0.3);
1048
1271
  for (const s of [-1, 1]) K.box("plain", s * (w / 2 - 0.05), yb, 0.02, 8e-3, y + h - 0.05 - yb, 8e-3, 12104876);
1049
1272
  K.box("plain", 0, yb - 0.02, 0, w - 0.03, 0.025, 0.04, 14473424);
1050
1273
  };
@@ -1337,13 +1560,13 @@ var GameFloorplanThree = (() => {
1337
1560
  const size = o.size || A.size(kind);
1338
1561
  const nv = A.variants(kind);
1339
1562
  const y = o.y != null ? o.y : HEIGHTS[kind] || 0.03;
1340
- const color = o.color != null ? hex(o.color) : 16777215;
1563
+ const color2 = o.color != null ? hex(o.color) : 16777215;
1341
1564
  const poly = o.poly || M.poly;
1342
1565
  const sd = seedOf(M);
1343
1566
  const rnd = rng(sd);
1344
1567
  const tint = () => {
1345
1568
  const v = 0.93 + rnd() * 0.07;
1346
- return mix(0, color, v);
1569
+ return mix(0, color2, v);
1347
1570
  };
1348
1571
  const quad = (cx, cz, qw, qd, uv) => api.plane(M, "atlas_floor", cx, y, cz, qw, qd, tint(), 0, -Math.PI / 2, 0, uv);
1349
1572
  if (!poly) {
@@ -1393,13 +1616,13 @@ var GameFloorplanThree = (() => {
1393
1616
  M,
1394
1617
  api,
1395
1618
  rnd: rng(seedOf(M)),
1396
- box: (material, x, y, z, w, h, d, color, ry, rx, rz) => api.box(M, material, x, y, z, w, h, d, hex(color), ry || 0, rx || 0, rz || 0),
1397
- cyl: (material, x, y, z, r, h, color, rx, rz, shape) => api.cylinder(M, material, x, y, z, r, h, hex(color), rx || 0, rz || 0, shape),
1398
- leaf: (x, y, z, w, h, color, ry, rx) => api.leaf(M, x, y, z, w, h, hex(color), ry || 0, rx || 0),
1399
- plane: (material, x, y, z, w, h, color, ry, rx, rz, uv) => api.plane(M, material, x, y, z, w, h, hex(color), ry || 0, rx || 0, rz || 0, uv),
1400
- light: (x, y, z, color, range, kind) => {
1401
- if (api.light) api.light(M, x, y, z, hex(color), range, kind);
1402
- else emit("light", { M, x, y, z, color: hex(color), range, kind });
1619
+ box: (material, x, y, z, w, h, d, color2, ry, rx, rz) => api.box(M, material, x, y, z, w, h, d, hex(color2), ry || 0, rx || 0, rz || 0),
1620
+ cyl: (material, x, y, z, r, h, color2, rx, rz, shape) => api.cylinder(M, material, x, y, z, r, h, hex(color2), rx || 0, rz || 0, shape),
1621
+ leaf: (x, y, z, w, h, color2, ry, rx) => api.leaf(M, x, y, z, w, h, hex(color2), ry || 0, rx || 0),
1622
+ plane: (material, x, y, z, w, h, color2, ry, rx, rz, uv) => api.plane(M, material, x, y, z, w, h, hex(color2), ry || 0, rx || 0, rz || 0, uv),
1623
+ light: (x, y, z, color2, range2, kind) => {
1624
+ if (api.light) api.light(M, x, y, z, hex(color2), range2, kind);
1625
+ else emit("light", { M, x, y, z, color: hex(color2), range: range2, kind });
1403
1626
  },
1404
1627
  // colours: role in the house palette (M.palette) or the default; main = M.color
1405
1628
  color: (name, fallback) => role(name) ?? hex(fallback),
@@ -1414,10 +1637,10 @@ var GameFloorplanThree = (() => {
1414
1637
  },
1415
1638
  ceiling: () => M.ceiling || 2.9,
1416
1639
  // long tilted box: starts at (x, y, z) and follows u = (0, sin a, -cos a) for L meters
1417
- ramp(material, x, y, z, w, t, L, color, alpha) {
1640
+ ramp(material, x, y, z, w, t, L, color2, alpha) {
1418
1641
  const cy = y + Math.sin(alpha) * L / 2;
1419
1642
  const cz = z - Math.cos(alpha) * L / 2;
1420
- K.box(material, x, cy - t / 2, cz, w, t, L, color, 0, alpha + Math.PI, 0);
1643
+ K.box(material, x, cy - t / 2, cz, w, t, L, color2, 0, alpha + Math.PI, 0);
1421
1644
  }
1422
1645
  };
1423
1646
  return K;
@@ -1598,19 +1821,19 @@ var GameFloorplanThree = (() => {
1598
1821
  for (const key in owner) if (!skip.includes(key)) walk(owner[key], 0);
1599
1822
  return found;
1600
1823
  };
1601
- var isVisibleInTree = (object) => {
1602
- for (let node = object; node; node = node.parent) if (!node.visible) return false;
1824
+ var isVisibleInTree = (object2) => {
1825
+ for (let node = object2; node; node = node.parent) if (!node.visible) return false;
1603
1826
  return true;
1604
1827
  };
1605
1828
  var createNodeSkin = (THREE, root, options = {}) => {
1606
1829
  const referenced = new Set(options.nodes ?? []);
1607
1830
  const nodes = [];
1608
1831
  const indexOf = /* @__PURE__ */ new Map();
1609
- root.traverse((object) => {
1610
- const mesh2 = object;
1611
- if (!mesh2.isMesh || object.children.length > 0 || referenced.has(object)) {
1612
- indexOf.set(object, nodes.length);
1613
- nodes.push(object);
1832
+ root.traverse((object2) => {
1833
+ const mesh2 = object2;
1834
+ if (!mesh2.isMesh || object2.children.length > 0 || referenced.has(object2)) {
1835
+ indexOf.set(object2, nodes.length);
1836
+ nodes.push(object2);
1614
1837
  }
1615
1838
  });
1616
1839
  const positions = [];
@@ -1619,7 +1842,7 @@ var GameFloorplanThree = (() => {
1619
1842
  const surfaces = [];
1620
1843
  const nodeIndices = [];
1621
1844
  const samples = /* @__PURE__ */ new Map();
1622
- const color = new THREE.Color();
1845
+ const color2 = new THREE.Color();
1623
1846
  const vertex = new THREE.Vector3();
1624
1847
  const normal = new THREE.Vector3();
1625
1848
  const sampleOf = (texture) => {
@@ -1633,22 +1856,22 @@ var GameFloorplanThree = (() => {
1633
1856
  samples.set(texture, sample);
1634
1857
  return sample;
1635
1858
  };
1636
- root.traverse((object) => {
1637
- const mesh2 = object;
1638
- if (!mesh2.isMesh || !isVisibleInTree(object)) return;
1859
+ root.traverse((object2) => {
1860
+ const mesh2 = object2;
1861
+ if (!mesh2.isMesh || !isVisibleInTree(object2)) return;
1639
1862
  const material2 = Array.isArray(mesh2.material) ? mesh2.material[0] : mesh2.material;
1640
1863
  const geometry2 = mesh2.geometry;
1641
1864
  const position = geometry2.attributes.position;
1642
1865
  const normalAttribute = geometry2.attributes.normal;
1643
1866
  const uv = geometry2.attributes.uv;
1644
1867
  const matrix = new THREE.Matrix4();
1645
- let nodeIndex = indexOf.get(object);
1868
+ let nodeIndex = indexOf.get(object2);
1646
1869
  if (nodeIndex === void 0) {
1647
- nodeIndex = indexOf.get(object.parent) ?? 0;
1648
- object.updateMatrix();
1649
- matrix.copy(object.matrix);
1870
+ nodeIndex = indexOf.get(object2.parent) ?? 0;
1871
+ object2.updateMatrix();
1872
+ matrix.copy(object2.matrix);
1650
1873
  }
1651
- const normalMatrix = new THREE.Matrix3().getNormalMatrix(matrix);
1874
+ const normalMatrix2 = new THREE.Matrix3().getNormalMatrix(matrix);
1652
1875
  const sample = material2.map ? sampleOf(material2.map) : void 0;
1653
1876
  const emissive = material2.emissive ? (material2.emissive.r + material2.emissive.g + material2.emissive.b) * (material2.emissiveIntensity ?? 1) : 0;
1654
1877
  const index = geometry2.index ? geometry2.index.array : null;
@@ -1657,10 +1880,10 @@ var GameFloorplanThree = (() => {
1657
1880
  const at = index ? index[item] : item;
1658
1881
  vertex.fromBufferAttribute(position, at).applyMatrix4(matrix);
1659
1882
  positions.push(vertex.x, vertex.y, vertex.z);
1660
- if (normalAttribute) normal.fromBufferAttribute(normalAttribute, at).applyMatrix3(normalMatrix).normalize();
1883
+ if (normalAttribute) normal.fromBufferAttribute(normalAttribute, at).applyMatrix3(normalMatrix2).normalize();
1661
1884
  else normal.set(0, 1, 0);
1662
1885
  normals.push(normal.x, normal.y, normal.z);
1663
- color.copy(material2.color || color.set(1, 1, 1)).convertLinearToSRGB();
1886
+ color2.copy(material2.color || color2.set(1, 1, 1)).convertLinearToSRGB();
1664
1887
  if (sample && uv && material2.map) {
1665
1888
  const repeat = material2.map.repeat;
1666
1889
  const u = (uv.getX(at) * repeat.x % 1 + 1) % 1;
@@ -1668,10 +1891,10 @@ var GameFloorplanThree = (() => {
1668
1891
  const pixelX = Math.min(sample.width - 1, u * sample.width | 0);
1669
1892
  const pixelY = Math.min(sample.height - 1, (1 - v) * sample.height | 0);
1670
1893
  const offset = (pixelY * sample.width + pixelX) * 4;
1671
- color.multiply(new THREE.Color().setRGB(sample.data[offset] / 255, sample.data[offset + 1] / 255, sample.data[offset + 2] / 255, THREE.SRGBColorSpace));
1894
+ color2.multiply(new THREE.Color().setRGB(sample.data[offset] / 255, sample.data[offset + 1] / 255, sample.data[offset + 2] / 255, THREE.SRGBColorSpace));
1672
1895
  }
1673
- if (emissive > 0.3) color.lerp(material2.emissive, 0.7);
1674
- tints.push(color.r, color.g, color.b);
1896
+ if (emissive > 0.3) color2.lerp(material2.emissive, 0.7);
1897
+ tints.push(color2.r, color2.g, color2.b);
1675
1898
  surfaces.push(material2.roughness ?? 0.8, material2.metalness ?? 0, emissive > 0.3 ? 1 : 0);
1676
1899
  nodeIndices.push(nodeIndex);
1677
1900
  }
@@ -1718,64 +1941,120 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
1718
1941
  function createRecorder(options = {}) {
1719
1942
  const primitives = [];
1720
1943
  const api = {
1721
- box: (M, material, x, y, z, w, h, d, color, ry, rx, rz) => void primitives.push({ kind: "box", M, material, x, y, z, w, h, d, color, ry, rx, rz }),
1722
- cylinder: (M, material, x, y, z, r, h, color, rx, rz, shape) => void primitives.push({ kind: "cylinder", M, material, x, y, z, r, h, color, rx, rz, shape }),
1723
- leaf: (M, x, y, z, w, h, color, ry, rx) => void primitives.push({ kind: "leaf", M, x, y, z, w, h, color, ry, rx }),
1724
- plane: (M, material, x, y, z, w, h, color, ry, rx, rz, uv) => void primitives.push({ kind: "plane", M, material, x, y, z, w, h, color, ry, rx, rz, uv })
1944
+ box: (M, material, x, y, z, w, h, d, color2, ry, rx, rz) => void primitives.push({ kind: "box", M, material, x, y, z, w, h, d, color: color2, ry, rx, rz }),
1945
+ cylinder: (M, material, x, y, z, r, h, color2, rx, rz, shape) => void primitives.push({ kind: "cylinder", M, material, x, y, z, r, h, color: color2, rx, rz, shape }),
1946
+ leaf: (M, x, y, z, w, h, color2, ry, rx) => void primitives.push({ kind: "leaf", M, x, y, z, w, h, color: color2, ry, rx }),
1947
+ plane: (M, material, x, y, z, w, h, color2, ry, rx, rz, uv) => void primitives.push({ kind: "plane", M, material, x, y, z, w, h, color: color2, ry, rx, rz, uv })
1725
1948
  };
1726
1949
  if (options.light !== false) {
1727
- api.light = (M, x, y, z, color, range, lightKind) => void primitives.push({ kind: "light", M, x, y, z, color, range, lightKind });
1950
+ api.light = (M, x, y, z, color2, range2, lightKind) => void primitives.push({ kind: "light", M, x, y, z, color: color2, range: range2, lightKind });
1728
1951
  }
1729
1952
  return { api, primitives };
1730
1953
  }
1731
- var ATTRIBUTES = ["position", "normal", "uv"];
1732
- var isVisible = (object) => {
1733
- for (let node = object; node; node = node.parent) if (!node.visible) return false;
1734
- return true;
1735
- };
1736
- var bake = (THREE, mesh, matrix) => {
1737
- const source = mesh.geometry.index ? mesh.geometry.toNonIndexed() : mesh.geometry.clone();
1738
- const baked = new THREE.BufferGeometry();
1739
- const count = source.getAttribute("position").count;
1740
- for (const name of ATTRIBUTES) {
1741
- const attribute = source.getAttribute(name);
1742
- baked.setAttribute(name, attribute ?? new THREE.BufferAttribute(new Float32Array(count * (name === "uv" ? 2 : 3)), name === "uv" ? 2 : 3));
1743
- }
1744
- source.dispose();
1745
- return baked.applyMatrix4(matrix);
1746
- };
1747
- var join = (THREE, geometries) => {
1748
- const merged = new THREE.BufferGeometry();
1749
- for (const name of ATTRIBUTES) {
1750
- const size = (geometries[0]?.getAttribute(name)).itemSize;
1751
- const total = geometries.reduce((sum, geometry) => sum + geometry.getAttribute(name).count, 0);
1752
- const array = new Float32Array(total * size);
1753
- let offset = 0;
1754
- for (const geometry of geometries) {
1755
- array.set(geometry.getAttribute(name).array, offset);
1756
- offset += geometry.getAttribute(name).count * size;
1757
- }
1758
- merged.setAttribute(name, new THREE.BufferAttribute(array, size));
1759
- }
1760
- return merged;
1761
- };
1762
- function mergeByMaterial(THREE, root, space) {
1763
- const toSpace = space.matrixWorld.clone().invert();
1764
- const byMaterial = /* @__PURE__ */ new Map();
1765
- root.traverse((object) => {
1766
- const mesh = object;
1767
- if (!mesh.isMesh || Array.isArray(mesh.material) || !isVisible(mesh)) return;
1768
- const list = byMaterial.get(mesh.material) ?? [];
1769
- list.push(bake(THREE, mesh, new THREE.Matrix4().multiplyMatrices(toSpace, mesh.matrixWorld)));
1770
- byMaterial.set(mesh.material, list);
1771
- });
1772
- return [...byMaterial].map(([material, geometries]) => {
1773
- const merged = new THREE.Mesh(join(THREE, geometries), material);
1774
- for (const geometry of geometries) geometry.dispose();
1775
- merged.castShadow = false;
1776
- merged.receiveShadow = true;
1777
- return merged;
1778
- });
1954
+ var LEAF = (() => {
1955
+ const f = [0, 0, 0, -0.5, 0.4, 0, 0.5, 0.4, 0, 0, 1, 0];
1956
+ const positions = [];
1957
+ const normals = [];
1958
+ const uvs = [];
1959
+ const indices = [];
1960
+ for (const side of [1, -1]) {
1961
+ const base = positions.length / 3;
1962
+ for (let i = 0; i < 4; i++) {
1963
+ positions.push(f[i * 3], f[i * 3 + 1], f[i * 3 + 2]);
1964
+ normals.push(0, 0, side);
1965
+ uvs.push(f[i * 3] + 0.5, f[i * 3 + 1]);
1966
+ }
1967
+ if (side === 1) indices.push(base, base + 2, base + 1, base + 1, base + 2, base + 3);
1968
+ else indices.push(base, base + 1, base + 2, base + 1, base + 3, base + 2);
1969
+ }
1970
+ return { positions, normals, uvs, indices };
1971
+ })();
1972
+ function createShapeRecorder(options = {}) {
1973
+ const cyl = options.cylinderSegments ?? 12;
1974
+ const hex2 = options.hexSegments ?? 6;
1975
+ const [sphereW, sphereH] = options.sphereSegments ?? [12, 8];
1976
+ const root = [];
1977
+ const parts = [];
1978
+ const partChildren = /* @__PURE__ */ new Map();
1979
+ let current = root;
1980
+ let lastFrame = null;
1981
+ const into = (M) => {
1982
+ const x = M?.x ?? 0;
1983
+ const z = M?.z ?? 0;
1984
+ const ry = M?.ry ?? 0;
1985
+ const last = lastFrame;
1986
+ if (last && last.list === current && current[current.length - 1] === last.group && Object.is(last.x, x) && Object.is(last.z, z) && Object.is(last.ry, ry)) return last.group.children;
1987
+ const group = { kind: "group", position: [x, 0, z], heading: ry, children: [] };
1988
+ current.push(group);
1989
+ lastFrame = { list: current, group, x, z, ry };
1990
+ return group.children;
1991
+ };
1992
+ const api = {
1993
+ box(M, material, x, y, z, w, h, d, color2, ry, rx, rz) {
1994
+ into(M).push({ kind: "box", material, color: color2, position: [x, y + h / 2, z], rotation: [rx, ry, rz], rotationOrder: "YXZ", scale: [w, h, d] });
1995
+ },
1996
+ cylinder(M, material, x, y, z, r, h, color2, rx, rz, shape) {
1997
+ const tilted = rx !== 0 || rz !== 0;
1998
+ const cy = shape === "sphere" ? y + h / 2 : tilted ? y : y + h / 2;
1999
+ const sy = shape === "sphere" ? h / 2 : h;
2000
+ const place = { material, color: color2, position: [x, cy, z], rotation: [rx, 0, rz], rotationOrder: "YXZ", scale: [r, sy, r] };
2001
+ const list2 = into(M);
2002
+ switch (shape) {
2003
+ case "cyl6":
2004
+ list2.push({ kind: "cylinder", radiusTop: 1, radiusBottom: 1, height: 1, radialSegments: hex2, ...place });
2005
+ break;
2006
+ case "cone":
2007
+ list2.push({ kind: "cylinder", radiusTop: 0, radiusBottom: 1, height: 1, radialSegments: cyl, ...place });
2008
+ break;
2009
+ case "sphere":
2010
+ list2.push({ kind: "sphere", radius: 1, widthSegments: sphereW, heightSegments: sphereH, ...place });
2011
+ break;
2012
+ default:
2013
+ list2.push({ kind: "cylinder", radiusTop: 1, radiusBottom: 1, height: 1, radialSegments: cyl, ...place });
2014
+ }
2015
+ },
2016
+ leaf(M, x, y, z, w, h, color2, ry, rx) {
2017
+ into(M).push({ kind: "mesh", ...LEAF, material: "plant", color: color2, position: [x, y, z], rotation: [rx, ry, 0], rotationOrder: "YXZ", scale: [w, h, 1] });
2018
+ },
2019
+ plane(M, material, x, y, z, w, h, color2, ry, rx, rz, uv) {
2020
+ into(M).push({
2021
+ kind: "plane",
2022
+ width: 1,
2023
+ height: 1,
2024
+ material,
2025
+ color: color2,
2026
+ position: [x, y, z],
2027
+ rotation: [rx, ry, rz],
2028
+ rotationOrder: "YXZ",
2029
+ scale: [w, h, 1],
2030
+ ...uv ? { uv: { u0: uv.u0, v0: uv.v0, u1: uv.u1, v1: uv.v1 } } : {}
2031
+ });
2032
+ },
2033
+ light(M, x, y, z, color2, range2, kind) {
2034
+ into(M).push({ kind: "point", position: [x, y, z], data: { light: true, color: color2, range: range2, kind } });
2035
+ },
2036
+ part(id, pivot, ry, draw) {
2037
+ let children = partChildren.get(id);
2038
+ if (!children) {
2039
+ children = [];
2040
+ partChildren.set(id, children);
2041
+ parts.push({ id, pivot: [pivot[0], pivot[1], pivot[2]], ry });
2042
+ current.push({ kind: "group", part: id, position: [pivot[0], pivot[1], pivot[2]], rotation: [0, ry, 0], children });
2043
+ }
2044
+ const outer = current;
2045
+ current = children;
2046
+ try {
2047
+ draw();
2048
+ } finally {
2049
+ current = outer;
2050
+ }
2051
+ }
2052
+ };
2053
+ return {
2054
+ api,
2055
+ parts,
2056
+ schema: () => ({ version: 1, ...options.name !== void 0 ? { name: options.name } : {}, root: { kind: "group", children: root } })
2057
+ };
1779
2058
  }
1780
2059
 
1781
2060
  // src/locale.ts
@@ -1987,7 +2266,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
1987
2266
  _col.setHex(h);
1988
2267
  return [_col.r, _col.g, _col.b];
1989
2268
  };
1990
- function put(mat, geo, px, py, pz, q, sx, sy, sz, color, uvr) {
2269
+ function put(mat, geo, px, py, pz, q, sx, sy, sz, color2, uvr) {
1991
2270
  {
1992
2271
  const O = cursor.org, RY = cursor.ry;
1993
2272
  if (RY) {
@@ -2009,7 +2288,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2009
2288
  const x = q.x, y = q.y, z = q.z, w = q.w, x2 = x + x, y2 = y + y, z2 = z + z;
2010
2289
  const xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2, wx = w * x2, wy = w * y2, wz = w * z2;
2011
2290
  const m00 = 1 - (yy + zz), m01 = xy - wz, m02 = xz + wy, m10 = xy + wz, m11 = 1 - (xx + zz), m12 = yz - wx, m20 = xz - wy, m21 = yz + wx, m22 = 1 - (xx + yy);
2012
- const [cr, cg, cb] = rgbOf(color), scale = UV_SCALE[mat], b = A.nv;
2291
+ const [cr, cg, cb] = rgbOf(color2), scale = UV_SCALE[mat], b = A.nv;
2013
2292
  for (let k = 0; k < G.nv; k++) {
2014
2293
  const lx = G.p[k * 3] * sx, ly = G.p[k * 3 + 1] * sy, lz = G.p[k * 3 + 2] * sz;
2015
2294
  const wx_ = m00 * lx + m01 * ly + m02 * lz + px, wy_ = m10 * lx + m11 * ly + m12 * lz + py, wz_ = m20 * lx + m21 * ly + m22 * lz + pz;
@@ -2064,21 +2343,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2064
2343
  A.nv += G.nv;
2065
2344
  A.ni += G.i ? G.i.length : G.nv;
2066
2345
  }
2067
- function boxC(mat, cx, cy, cz, sx, sy, sz, color, rx = 0, ry = 0, rz = 0, uvr) {
2346
+ function boxC(mat, cx, cy, cz, sx, sy, sz, color2, rx = 0, ry = 0, rz = 0, uvr) {
2068
2347
  if (rx || ry || rz) _q.setFromEuler(_e.set(rx, ry, rz, "YXZ"));
2069
2348
  else _q.identity();
2070
- put(mat, "box", cx, cy, cz, _q, sx, sy, sz, color, uvr);
2349
+ put(mat, "box", cx, cy, cz, _q, sx, sy, sz, color2, uvr);
2071
2350
  }
2072
- function bxBase(mat, x0, y0, z0, x1, y1, z1, color) {
2351
+ function bxBase(mat, x0, y0, z0, x1, y1, z1, color2) {
2073
2352
  if (x1 - x0 < 1e-4 || y1 - y0 < 1e-4 || z1 - z0 < 1e-4) return;
2074
2353
  _q.identity();
2075
- put(mat, "box", (x0 + x1) / 2, (y0 + y1) / 2, (z0 + z1) / 2, _q, x1 - x0, y1 - y0, z1 - z0, color);
2354
+ put(mat, "box", (x0 + x1) / 2, (y0 + y1) / 2, (z0 + z1) / 2, _q, x1 - x0, y1 - y0, z1 - z0, color2);
2076
2355
  }
2077
- function cylBase(mat, x, y, z, r, h, color, seg = "cyl") {
2356
+ function cylBase(mat, x, y, z, r, h, color2, seg = "cyl") {
2078
2357
  _q.identity();
2079
- put(mat, seg, x, y + h / 2, z, _q, r * 2, h, r * 2, color);
2358
+ put(mat, seg, x, y + h / 2, z, _q, r * 2, h, r * 2, color2);
2080
2359
  }
2081
- function polyFace(mat, pts, color, hint) {
2360
+ function polyFace(mat, pts, color2, hint) {
2082
2361
  const A = accFor(mat), n = pts.length, O = cursor.org, RY = cursor.ry;
2083
2362
  A.ensure(n, (n - 2) * 3);
2084
2363
  if (RY) {
@@ -2105,7 +2384,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2105
2384
  nz = -nz;
2106
2385
  [a, b] = [pts[0], pts[1]];
2107
2386
  }
2108
- const [cr, cg, cb] = rgbOf(color), scale = UV_SCALE[mat] || 1, base = A.nv;
2387
+ const [cr, cg, cb] = rgbOf(color2), scale = UV_SCALE[mat] || 1, base = A.nv;
2109
2388
  let e1x = b[0] - a[0], e1y = b[1] - a[1], e1z = b[2] - a[2];
2110
2389
  const l1 = Math.hypot(e1x, e1y, e1z) || 1;
2111
2390
  e1x /= l1;
@@ -2564,16 +2843,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2564
2843
  const R = shared.ctx.r, F = R.facade;
2565
2844
  if (id === "outside" || !shared.ctx.roomById[id]) {
2566
2845
  const ac = F.finish;
2567
- let mat = "plaster", color = shared.ctx.colors.facade;
2846
+ let mat = "plaster", color2 = shared.ctx.colors.facade;
2568
2847
  if (ac === "roughcast") mat = "roughcast";
2569
2848
  else if (ac === "exposed_block") {
2570
2849
  mat = "block";
2571
- color = 12894392;
2850
+ color2 = 12894392;
2572
2851
  } else if (ac === "partial_plaster" && !frontLine) {
2573
2852
  mat = "block";
2574
- color = 12894392;
2853
+ color2 = 12894392;
2575
2854
  }
2576
- return { color, mat, exterior: true };
2855
+ return { color: color2, mat, exterior: true };
2577
2856
  }
2578
2857
  return { color: wallColor(shared.ctx.roomById[id]), mat: "plaster", exterior: false };
2579
2858
  }
@@ -2683,7 +2962,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2683
2962
  wallBox(alongU, L, a, b, y0 + dH, y0 + effectiveHeight(f, wallHeight), th, lL.color, lH.color, lL.mat, lH.mat);
2684
2963
  cursor.pc = null;
2685
2964
  }
2686
- const fb = (u0, y_0, u1, y_1, tt = th + 0.02, color = frame) => alongU ? bx("wood", u0, y0 + y_0, L - tt / 2, u1, y0 + y_1, L + tt / 2, color) : bx("wood", L - tt / 2, y0 + y_0, u0, L + tt / 2, y0 + y_1, u1, color);
2965
+ const fb = (u0, y_0, u1, y_1, tt = th + 0.02, color2 = frame) => alongU ? bx("wood", u0, y0 + y_0, L - tt / 2, u1, y0 + y_1, L + tt / 2, color2) : bx("wood", L - tt / 2, y0 + y_0, u0, L + tt / 2, y0 + y_1, u1, color2);
2687
2966
  const jw = 0.05;
2688
2967
  cursor.pc = pieceRecord("jamb:" + p.id, "wood_hard", null, { floor: f });
2689
2968
  fb(a, 0, a + jw, visH);
@@ -2697,7 +2976,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2697
2976
  if (cL && cL.id === p.opensTo) sw = -1;
2698
2977
  else if (cH && cH.id === p.opensTo) sw = 1;
2699
2978
  }
2700
- const leaf = (u0, u1, y_0, y_1, tt, color, mat = "wood") => alongU ? bx(mat, u0, y0 + y_0, L - tt / 2, u1, y0 + y_1, L + tt / 2, color) : bx(mat, L - tt / 2, y0 + y_0, u0, L + tt / 2, y0 + y_1, u1, color);
2979
+ const leaf = (u0, u1, y_0, y_1, tt, color2, mat = "wood") => alongU ? bx(mat, u0, y0 + y_0, L - tt / 2, u1, y0 + y_1, L + tt / 2, color2) : bx(mat, L - tt / 2, y0 + y_0, u0, L + tt / 2, y0 + y_1, u1, color2);
2701
2980
  const extC = wood;
2702
2981
  const open0 = p.blocked ? false : shared.doorState.has(p.id) ? shared.doorState.get(p.id) : !!p.open;
2703
2982
  shared.doorState.set(p.id, open0);
@@ -2706,19 +2985,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2706
2985
  const colR = { type: "door", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b, off: open0 };
2707
2986
  shared.ctx.colliders.push(colR);
2708
2987
  fo.col = colR;
2709
- const leafBox = (hu, d0, d1, y_0, y_1, tt, color, mat) => alongU ? bx(mat, d0, y_0, -tt / 2, d1, y_1, tt / 2, color) : bx(mat, -tt / 2, y_0, d0, tt / 2, y_1, d1, color);
2988
+ const leafBox = (hu, d0, d1, y_0, y_1, tt, color2, mat) => alongU ? bx(mat, d0, y_0, -tt / 2, d1, y_1, tt / 2, color2) : bx(mat, -tt / 2, y_0, d0, tt / 2, y_1, d1, color2);
2710
2989
  const newGroup = (k, hu, topY) => {
2711
2990
  cursor.group = "dyn:" + p.id + ":" + k;
2712
2991
  fo.groups.push({ name: cursor.group, pos: alongU ? [hu, topY != null ? y0 + topY : y0, L] : [L, topY != null ? y0 + topY : y0, hu] });
2713
2992
  };
2714
2993
  if (p.model === "steel") {
2715
- const light = [14276044, 13223615, 14999766], pal = ((R.seed | 0) + p.id.length * 7) % 4, color = pal === 3 ? wood : light[pal], mid = (a + b) / 2;
2994
+ const light = [14276044, 13223615, 14999766], pal = ((R.seed | 0) + p.id.length * 7) % 4, color2 = pal === 3 ? wood : light[pal], mid = (a + b) / 2;
2716
2995
  newGroup(0, mid, visH);
2717
- const la = a + jw - mid, lb = b - jw - mid, nSec = Math.max(4, Math.round(visH / 0.5)), hs = visH / nSec, grv = sh(color, 0.55);
2718
- leafBox(0, la, lb, -visH, 0, 0.05, color, "metal");
2996
+ const la = a + jw - mid, lb = b - jw - mid, nSec = Math.max(4, Math.round(visH / 0.5)), hs = visH / nSec, grv = sh(color2, 0.55);
2997
+ leafBox(0, la, lb, -visH, 0, 0.05, color2, "metal");
2719
2998
  for (let k = 1; k < nSec; k++) leafBox(0, la, lb, -k * hs - 0.012, -k * hs + 0.012, 0.07, grv, "metal");
2720
2999
  const np = Math.max(2, Math.round((lb - la) / 0.8)), pw = (lb - la) / np;
2721
- for (let k = 0; k < nSec; k++) for (let i = 0; i < np; i++) leafBox(0, la + i * pw + 0.07, la + (i + 1) * pw - 0.07, -(k + 1) * hs + 0.07, -k * hs - 0.07, 0.062, sh(color, k % 2 ? 0.93 : 1.06), "metal");
3000
+ for (let k = 0; k < nSec; k++) for (let i = 0; i < np; i++) leafBox(0, la + i * pw + 0.07, la + (i + 1) * pw - 0.07, -(k + 1) * hs + 0.07, -k * hs - 0.07, 0.062, sh(color2, k % 2 ? 0.93 : 1.06), "metal");
2722
3001
  for (let i = 0; i < np; i++) leafBox(0, la + i * pw + 0.14, la + (i + 1) * pw - 0.14, -hs + 0.12, -0.12, 0.072, 5924464, "glass");
2723
3002
  leafBox(0, -0.1, 0.1, -visH + 0.5, -visH + 0.55, 0.085, 3815998, "metal");
2724
3003
  fo.minScale = Math.min(1, 0.28 / visH);
@@ -2726,13 +3005,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2726
3005
  } else {
2727
3006
  const nf = p.model === "double" ? 2 : 1, aa = a + jw, bb = b - jw;
2728
3007
  for (let k = 0; k < nf; k++) {
2729
- const u0 = nf === 2 ? k ? (aa + bb) / 2 : aa : aa, u1 = nf === 2 ? k ? bb : (aa + bb) / 2 : bb, color = p.exterior ? extC : wood;
3008
+ const u0 = nf === 2 ? k ? (aa + bb) / 2 : aa : aa, u1 = nf === 2 ? k ? bb : (aa + bb) / 2 : bb, color2 = p.exterior ? extC : wood;
2730
3009
  const hingeAt = nf === 2 ? k ? u1 : u0 : p.hinge === "end" ? u1 : u0, dir = hingeAt === u0 ? 1 : -1, len = u1 - u0;
2731
3010
  newGroup(k, hingeAt);
2732
3011
  const d0 = dir > 0 ? 5e-3 : -len + 5e-3, d1 = dir > 0 ? len - 5e-3 : -5e-3;
2733
- leafBox(hingeAt, d0, d1, 0, visH, 0.04, color, PMAT);
3012
+ leafBox(hingeAt, d0, d1, 0, visH, 0.04, color2, PMAT);
2734
3013
  {
2735
- const e0 = Math.min(d0, d1) + 0.1, e1 = Math.max(d0, d1) - 0.1, pc = sh(color, 0.82);
3014
+ const e0 = Math.min(d0, d1) + 0.1, e1 = Math.max(d0, d1) - 0.1, pc = sh(color2, 0.82);
2736
3015
  if (e1 - e0 > 0.2 && visH > 1.2) {
2737
3016
  leafBox(hingeAt, e0, e1, 0.15, visH * 0.45, 0.055, pc, PMAT);
2738
3017
  leafBox(hingeAt, e0, e1, visH * 0.5, visH - 0.15, 0.055, pc, PMAT);
@@ -2769,9 +3048,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2769
3048
  if (p.blocked) {
2770
3049
  part("window_boards", [0, 0, 0], () => {
2771
3050
  const rb = rngString(SEED() + "|" + seedKey(p.id) + "|tabua"), cx0 = alongU ? p.at : L, cz0 = alongU ? L : p.at, nT = Math.max(4, Math.round((visH - 0.3) / 0.3)), Lg = p.width + 0.34, WOODS = [8017460, 7031338, 9071172, 6177320, 7559746];
2772
- const puts = (along, y, off, comp, alt, thickness, color, tilt) => {
3051
+ const puts = (along, y, off, comp, alt, thickness, color2, tilt) => {
2773
3052
  const x = alongU ? along : L + off, z = alongU ? L + off : along;
2774
- boxC("wood", x, y0 + y, z, comp, alt, thickness, color, 0, alongU ? 0 : K.PE, tilt);
3053
+ boxC("wood", x, y0 + y, z, comp, alt, thickness, color2, 0, alongU ? 0 : K.PE, tilt);
2775
3054
  };
2776
3055
  const nailColor = (along, y, off) => {
2777
3056
  const x = alongU ? along : L + off, z = alongU ? L + off : along;
@@ -2784,8 +3063,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2784
3063
  puts(alongU ? cx0 : cz0, visH / 2, o1, Math.hypot(p.width + 0.2, visH - 0.4) + 0.1, 0.12, 0.028, sh(WOODS[rb() * 5 | 0], 0.85), a2);
2785
3064
  }
2786
3065
  for (let k = 0; k < nT; k++) {
2787
- const y = 0.18 + k * (visH - 0.4) / (nT - 1) + (rb() - 0.5) * 0.04, comp = Lg + (rb() - 0.5) * 0.12, tilt = (rb() - 0.5) * 0.05, alt = 0.13 + rb() * 0.03, c0 = alongU ? cx0 : cz0, color = WOODS[rb() * WOODS.length | 0];
2788
- puts(c0 + (rb() - 0.5) * 0.06, y, o2, comp, alt, 0.03, color, tilt);
3066
+ const y = 0.18 + k * (visH - 0.4) / (nT - 1) + (rb() - 0.5) * 0.04, comp = Lg + (rb() - 0.5) * 0.12, tilt = (rb() - 0.5) * 0.05, alt = 0.13 + rb() * 0.03, c0 = alongU ? cx0 : cz0, color2 = WOODS[rb() * WOODS.length | 0];
3067
+ puts(c0 + (rb() - 0.5) * 0.06, y, o2, comp, alt, 0.03, color2, tilt);
2789
3068
  for (const e of [-1, 1]) {
2790
3069
  nailColor(c0 + e * (comp / 2 - 0.07), y + Math.sin(tilt) * e * comp / 2, o2 + sd * 0.019);
2791
3070
  }
@@ -2817,7 +3096,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2817
3096
  yb = Math.min(yb, 1.2);
2818
3097
  }
2819
3098
  const wref = R.walls.find((w) => w.floor === f && w.axis === j.axis && Math.abs((alongU ? w.v0 : w.u0) - L) < EPS), th = wref ? wref.thickness || 0.15 : 0.15, t = 0.05, tt = th + 0.02;
2820
- const bar = (u0, y_0, u1, y_1, mat, color, tw = tt) => alongU ? bx(mat, u0, y0 + y_0, L - tw / 2, u1, y0 + y_1, L + tw / 2, color) : bx(mat, L - tw / 2, y0 + y_0, u0, L + tw / 2, y0 + y_1, u1, color);
3099
+ const bar = (u0, y_0, u1, y_1, mat, color2, tw = tt) => alongU ? bx(mat, u0, y0 + y_0, L - tw / 2, u1, y0 + y_1, L + tw / 2, color2) : bx(mat, L - tw / 2, y0 + y_0, u0, L + tw / 2, y0 + y_1, u1, color2);
2821
3100
  cursor.pc = pieceRecord("window_frame:" + j.id, "aluminium", null, { floor: f });
2822
3101
  bar(a, ya, a + t, yb, "metal", fr);
2823
3102
  bar(b - t, ya, b, yb, "metal", fr);
@@ -2929,9 +3208,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
2929
3208
  const y0 = Y0(f), H = Y0(m.link.to) - y0, n = Math.max(8, Math.round(H / 0.18)), c = Math.cos(m.ry), s = Math.sin(m.ry);
2930
3209
  const wood = shared.ctx.colors.wood != null ? shared.ctx.colors.wood : 9071176, under = sh(wood, 0.7);
2931
3210
  const P = (lx, lz) => [m.x + lx * c + lz * s, m.z - lx * s + lz * c];
2932
- const boxL = (mat, lx, y, lz, w, h, d, color, rx = 0) => {
3211
+ const boxL = (mat, lx, y, lz, w, h, d, color2, rx = 0) => {
2933
3212
  const [px, pz] = P(lx, lz);
2934
- boxC(mat, px, y, pz, w, h, d, color, rx, m.ry, 0);
3213
+ boxC(mat, px, y, pz, w, h, d, color2, rx, m.ry, 0);
2935
3214
  };
2936
3215
  for (let i = 0; i < n; i++) {
2937
3216
  const top = (i + 1) * H / n, lz = m.d / 2 - (i + 0.5) * Dr / n;
@@ -3002,20 +3281,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
3002
3281
  get A() {
3003
3282
  return api;
3004
3283
  },
3005
- b: (mat, x, y, z, w, h, d, color, ry, rx, rz) => api.box(M, mat, x, y0 + y, z, w, h, d, color, ry || 0, rx || 0, rz || 0),
3006
- c: (mat, x, y, z, r, h, color, seg) => api.cylinder(M, mat, x, y0 + y, z, r, h, color, 0, 0, seg),
3007
- e: (mat, x, y, z, r, h, color) => api.cylinder(M, mat, x, y0 + y - h / 2, z, r, h, color, 0, 0, "sphere"),
3008
- t(mat, p, q, r, color, seg) {
3284
+ b: (mat, x, y, z, w, h, d, color2, ry, rx, rz) => api.box(M, mat, x, y0 + y, z, w, h, d, color2, ry || 0, rx || 0, rz || 0),
3285
+ c: (mat, x, y, z, r, h, color2, seg) => api.cylinder(M, mat, x, y0 + y, z, r, h, color2, 0, 0, seg),
3286
+ e: (mat, x, y, z, r, h, color2) => api.cylinder(M, mat, x, y0 + y - h / 2, z, r, h, color2, 0, 0, "sphere"),
3287
+ t(mat, p, q, r, color2, seg) {
3009
3288
  const dx = q[0] - p[0], dy = q[1] - p[1], dz = q[2] - p[2], L = Math.hypot(dx, dy, dz);
3010
3289
  if (L < 1e-5) return;
3011
3290
  const nx = dx / L, ny = dy / L, nz = dz / L;
3012
3291
  if (Math.abs(nx) < 1e-4 && Math.abs(nz) < 1e-4) {
3013
- api.cylinder(M, mat, p[0], y0 + Math.min(p[1], q[1]), p[2], r, L, color, 0, 0, seg);
3292
+ api.cylinder(M, mat, p[0], y0 + Math.min(p[1], q[1]), p[2], r, L, color2, 0, 0, seg);
3014
3293
  return;
3015
3294
  }
3016
- api.cylinder(M, mat, (p[0] + q[0]) / 2, y0 + (p[1] + q[1]) / 2, (p[2] + q[2]) / 2, r, L, color, Math.atan2(nz, ny), -Math.asin(nx), seg);
3295
+ api.cylinder(M, mat, (p[0] + q[0]) / 2, y0 + (p[1] + q[1]) / 2, (p[2] + q[2]) / 2, r, L, color2, Math.atan2(nz, ny), -Math.asin(nx), seg);
3017
3296
  },
3018
- polyFace: (mat, pts, color, hint) => polyFace(mat, pts.map((p) => W(p[0], p[1], p[2])), color, hint && [hint[0] * c + hint[2] * s, hint[1], -hint[0] * s + hint[2] * c]),
3297
+ polyFace: (mat, pts, color2, hint) => polyFace(mat, pts.map((p) => W(p[0], p[1], p[2])), color2, hint && [hint[0] * c + hint[2] * s, hint[1], -hint[0] * s + hint[2] * c]),
3019
3298
  part(type, lx, ly, lz, fn, meta) {
3020
3299
  if (type === "lamp" && String(cursor.group).startsWith("ix:light:")) {
3021
3300
  fn();
@@ -3056,28 +3335,28 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
3056
3335
  return v < 0.28 ? "recessed" : v < 0.5 ? "track" : v < 0.75 ? social ? "pendant" : "recessed" : /living|dining|hall/.test(tp) ? "chandelier" : "recessed";
3057
3336
  }
3058
3337
  function ceilingLamp(M, A, type) {
3059
- const K2 = kit2(M, A, 0), t = M.ceiling || 2.8, color = colorTemperature(M), r = rngString(SEED() + "|" + seedKey(M.seed) + "|lz");
3060
- const id = "lamp_" + (M.seed || hashString(M.x + "," + M.z)), meta = { id, room: M.room, on: !!M.on, color, lightType: type, hidden: !M.on };
3338
+ const K2 = kit2(M, A, 0), t = M.ceiling || 2.8, color2 = colorTemperature(M), r = rngString(SEED() + "|" + seedKey(M.seed) + "|lz");
3339
+ const id = "lamp_" + (M.seed || hashString(M.x + "," + M.z)), meta = { id, room: M.room, on: !!M.on, color: color2, lightType: type, hidden: !M.on };
3061
3340
  const white = 16052972, offset = 15329247;
3062
- let yLight = t - 0.18, range = 6;
3341
+ let yLight = t - 0.18, range2 = 6;
3063
3342
  const emitter = (fn) => K2.part("lamp", 0, t, 0, fn, meta);
3064
3343
  if (type === "bare") {
3065
3344
  K2.c("plain", 0, t - 0.03, 0, 0.05, 0.03, white);
3066
3345
  K2.c("metal", 0, t - 0.085, 0, 0.022, 0.055, 6974054);
3067
3346
  K2.c("plain", 0, t - 0.105, 0, 0.026, 0.02, 14209208);
3068
3347
  K2.e("plain", 0, t - 0.165, 0, 0.036, 0.085, 15987178);
3069
- emitter(() => K2.e("emissive", 0, t - 0.165, 0, 0.0385, 0.088, color));
3348
+ emitter(() => K2.e("emissive", 0, t - 0.165, 0, 0.0385, 0.088, color2));
3070
3349
  yLight = t - 0.22;
3071
- range = 5.5;
3350
+ range2 = 5.5;
3072
3351
  } else if (type === "round") {
3073
3352
  K2.c("plain", 0, t - 0.05, 0, 0.19, 0.05, white);
3074
3353
  K2.c("plain", 0, t - 0.07, 0, 0.165, 0.02, offset);
3075
- emitter(() => K2.c("emissive", 0, t - 0.073, 0, 0.1675, 0.023, color));
3354
+ emitter(() => K2.c("emissive", 0, t - 0.073, 0, 0.1675, 0.023, color2));
3076
3355
  yLight = t - 0.2;
3077
3356
  } else if (type === "square") {
3078
3357
  K2.b("plain", 0, t - 0.05, 0, 0.36, 0.05, 0.36, white);
3079
3358
  K2.b("plain", 0, t - 0.07, 0, 0.3, 0.02, 0.3, offset);
3080
- emitter(() => K2.b("emissive", 0, t - 0.073, 0, 0.3025, 0.023, 0.3025, color));
3359
+ emitter(() => K2.b("emissive", 0, t - 0.073, 0, 0.3025, 0.023, 0.3025, color2));
3081
3360
  yLight = t - 0.2;
3082
3361
  } else if (type === "recessed") {
3083
3362
  const o = 0.5;
@@ -3086,10 +3365,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
3086
3365
  K2.c("plain", x, t - 0.026, z, 0.05, 0.012, offset);
3087
3366
  }
3088
3367
  emitter(() => {
3089
- for (const [x, z] of [[-o, -o], [o, -o], [-o, o], [o, o]]) K2.c("emissive", x, t - 0.028, z, 0.0505, 0.014, color);
3368
+ for (const [x, z] of [[-o, -o], [o, -o], [-o, o], [o, o]]) K2.c("emissive", x, t - 0.028, z, 0.0505, 0.014, color2);
3090
3369
  });
3091
3370
  yLight = t - 0.3;
3092
- range = 6.5;
3371
+ range2 = 6.5;
3093
3372
  } else if (type === "track") {
3094
3373
  const len = 1.1, angle = r() < 0.5 ? 0 : Math.PI / 2, c = Math.cos(angle), s = Math.sin(angle);
3095
3374
  K2.b("metal", 0, t - 0.03, 0, angle ? 0.035 : len, 0.03, angle ? len : 0.035, 2763308);
@@ -3105,16 +3384,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
3105
3384
  for (const [q, d] of cab) K2.t("emissive", [q[0] - d[0] * 3e-3, q[1] - d[1] * 3e-3, q[2] - d[2] * 3e-3], [q[0] + d[0] * 0.012, q[1] + d[1] * 0.012, q[2] + d[2] * 0.012], 0.029);
3106
3385
  });
3107
3386
  yLight = t - 0.3;
3108
- range = 6.5;
3387
+ range2 = 6.5;
3109
3388
  } else if (type === "pendant") {
3110
3389
  const drop = Math.max(0.4, Math.min(1.1, t - 2.05)), yc = t - drop, cs = [2763308, 15262420, 12094036, 3495534][r() * 4 | 0];
3111
3390
  K2.c("plain", 0, t - 0.025, 0, 0.05, 0.025, white);
3112
3391
  K2.c("metal", 0, yc, 0, 6e-3, drop - 0.02, 1710618);
3113
3392
  K2.e("plain", 0, yc - 0.09, 0, 0.19, 0.2, cs);
3114
3393
  K2.e("plain", 0, yc - 0.2, 0, 0.065, 0.085, 15987178);
3115
- emitter(() => K2.e("emissive", 0, yc - 0.2, 0, 0.069, 0.089, color));
3394
+ emitter(() => K2.e("emissive", 0, yc - 0.2, 0, 0.069, 0.089, color2));
3116
3395
  yLight = yc - 0.3;
3117
- range = 6.5;
3396
+ range2 = 6.5;
3118
3397
  } else if (type === "chandelier") {
3119
3398
  const yc = t - 0.5, gold = shared.ctx.colors && shared.ctx.colors.metal != null ? shared.ctx.colors.metal : 9075290, N = 6;
3120
3399
  K2.c("metal", 0, yc, 0, 0.012, 0.5, gold);
@@ -3131,57 +3410,57 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
3131
3410
  emitter(() => {
3132
3411
  for (let i = 0; i < N; i++) {
3133
3412
  const an = i * Math.PI * 2 / N;
3134
- K2.e("emissive", Math.cos(an) * 0.28, yc + 0.07, Math.sin(an) * 0.28, 0.0155, 0.036, color);
3413
+ K2.e("emissive", Math.cos(an) * 0.28, yc + 0.07, Math.sin(an) * 0.28, 0.0155, 0.036, color2);
3135
3414
  }
3136
3415
  });
3137
3416
  yLight = yc - 0.05;
3138
- range = 7;
3417
+ range2 = 7;
3139
3418
  } else if (type === "trough") {
3140
3419
  K2.b("metal", 0, t - 0.045, 0, 1.2, 0.045, 0.1, 14474456);
3141
3420
  K2.b("plain", 0, t - 0.058, 0, 1.12, 0.013, 0.06, 15329764);
3142
- emitter(() => K2.b("emissive", 0, t - 0.0605, 0, 1.125, 0.0155, 0.0625, color));
3421
+ emitter(() => K2.b("emissive", 0, t - 0.0605, 0, 1.125, 0.0155, 0.0625, color2));
3143
3422
  yLight = t - 0.2;
3144
- range = 7;
3423
+ range2 = 7;
3145
3424
  }
3146
- if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, yLight, 0, color, range, "ceiling_light");
3425
+ if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, yLight, 0, color2, range2, "ceiling_light");
3147
3426
  }
3148
3427
  function tableLamp(M, A, y) {
3149
- const K2 = kit2(M, A, 0), color = colorTemperature(M), id = "lamp_ab_" + M.seed, cp = [15786688, 15262420, 13621470][hashString(seedKey(M.seed) + "cp") % 3], meta = { id, room: M.room, on: !!M.on, color, lightType: "table_lamp", hidden: !M.on };
3428
+ const K2 = kit2(M, A, 0), color2 = colorTemperature(M), id = "lamp_ab_" + M.seed, cp = [15786688, 15262420, 13621470][hashString(seedKey(M.seed) + "cp") % 3], meta = { id, room: M.room, on: !!M.on, color: color2, lightType: "table_lamp", hidden: !M.on };
3150
3429
  K2.e("plain", 0, y + 0.045, 0, 0.065, 0.09, 3813928);
3151
3430
  K2.c("metal", 0, y + 0.08, 0, 8e-3, 0.14, 9075290);
3152
3431
  K2.c("plain", 0, y + 0.2, 0, 0.115, 0.15, cp);
3153
- K2.part("lamp", 0, y + 0.2, 0, () => K2.c("emissive", 0, y + 0.2, 0, 0.118, 0.152, color), meta);
3154
- if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, y + 0.3, 0, color, 3.5, "table_lamp");
3432
+ K2.part("lamp", 0, y + 0.2, 0, () => K2.c("emissive", 0, y + 0.2, 0, 0.118, 0.152, color2), meta);
3433
+ if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, y + 0.3, 0, color2, 3.5, "table_lamp");
3155
3434
  }
3156
3435
  function floorLamp(M, A) {
3157
- const K2 = kit2(M, A, M.y || 0), color = colorTemperature(M), id = "lamp_pe_" + M.seed, h = Math.min(1.6, M.h || 1.5), meta = { id, room: M.room, on: !!M.on, color, lightType: "floor", hidden: !M.on };
3436
+ const K2 = kit2(M, A, M.y || 0), color2 = colorTemperature(M), id = "lamp_pe_" + M.seed, h = Math.min(1.6, M.h || 1.5), meta = { id, room: M.room, on: !!M.on, color: color2, lightType: "floor", hidden: !M.on };
3158
3437
  K2.c("metal", 0, 0, 0, 0.13, 0.025, 2763308);
3159
3438
  K2.c("metal", 0, 0.025, 0, 0.011, h - 0.3, 2763308);
3160
3439
  K2.c("plain", 0, h - 0.28, 0, 0.17, 0.26, 15656656);
3161
- K2.part("lamp", 0, h - 0.28, 0, () => K2.c("emissive", 0, h - 0.28, 0, 0.173, 0.262, color), meta);
3162
- if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, h - 0.15, 0, color, 5, "floor");
3440
+ K2.part("lamp", 0, h - 0.28, 0, () => K2.c("emissive", 0, h - 0.28, 0, 0.173, 0.262, color2), meta);
3441
+ if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, h - 0.15, 0, color2, 5, "floor");
3163
3442
  }
3164
3443
  function sconce(M, A) {
3165
- const K2 = kit2(M, A, M.y || 1.7), color = colorTemperature(M), id = "lamp_ar_" + M.seed, meta = { id, room: M.room, on: !!M.on, color, lightType: "sconce", hidden: !M.on };
3444
+ const K2 = kit2(M, A, M.y || 1.7), color2 = colorTemperature(M), id = "lamp_ar_" + M.seed, meta = { id, room: M.room, on: !!M.on, color: color2, lightType: "sconce", hidden: !M.on };
3166
3445
  K2.b("metal", 0, -0.07, 8e-3, 0.07, 0.14, 0.016, 14210248);
3167
3446
  K2.t("metal", [0, 0, 0.016], [0, 0, 0.075], 0.011, 11577480);
3168
3447
  K2.e("plain", 0, 0, 0.1, 0.06, 0.15, 15920348);
3169
- K2.part("lamp", 0, 0, 0.1, () => K2.e("emissive", 0, 0, 0.1, 0.0625, 0.153, color), meta);
3170
- if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, 0.02, 0.2, color, 3, "sconce");
3448
+ K2.part("lamp", 0, 0, 0.1, () => K2.e("emissive", 0, 0, 0.1, 0.0625, 0.153, color2), meta);
3449
+ if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, 0.02, 0.2, color2, 3, "sconce");
3171
3450
  }
3172
3451
  function outdoorLamp(M, A) {
3173
- const K2 = kit2(M, A, M.y || 2.2), color = colorTemperature(M), id = "lamp_ext_" + M.seed, structure = STYLE(), meta = { id, room: "outside", on: !!M.on, color, lightType: "outdoor", hidden: !M.on };
3452
+ const K2 = kit2(M, A, M.y || 2.2), color2 = colorTemperature(M), id = "lamp_ext_" + M.seed, structure = STYLE(), meta = { id, room: "outside", on: !!M.on, color: color2, lightType: "outdoor", hidden: !M.on };
3174
3453
  if (structure === "budget") {
3175
3454
  K2.c("plain", 0, -0, 0.01, 0.05, 0.02, 15921386);
3176
3455
  K2.t("metal", [0, 0, 0], [0, 0, 0.07], 0.022, 6974054);
3177
3456
  K2.e("plain", 0, 0, 0.115, 0.036, 0.085, 15987178);
3178
- K2.part("lamp", 0, 0, 0.115, () => K2.e("emissive", 0, 0, 0.115, 0.0385, 0.088, color), meta);
3457
+ K2.part("lamp", 0, 0, 0.115, () => K2.e("emissive", 0, 0, 0.115, 0.0385, 0.088, color2), meta);
3179
3458
  } else {
3180
3459
  K2.b("metal", 0, -0.08, 0.01, 0.12, 0.16, 0.02, 2763308);
3181
3460
  K2.b("plain", 0, -0.09, 0.07, 0.11, 0.18, 0.1, 15263454);
3182
- K2.part("lamp", 0, -0.09, 0.07, () => K2.b("emissive", 0, -0.09, 0.07, 0.1125, 0.1825, 0.1025, color), meta);
3461
+ K2.part("lamp", 0, -0.09, 0.07, () => K2.b("emissive", 0, -0.09, 0.07, 0.1125, 0.1825, 0.1025, color2), meta);
3183
3462
  }
3184
- if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, (M.y != null ? M.y : 2.2) - (structure === "budget" ? 0 : 0.09), structure === "budget" ? 0.2 : 0.2, color, 3.2, "outdoor", { lumens: 3.2, dist: 5.5, decay: 2 });
3463
+ if (M.on && A.light) A.light(Object.assign({}, M, { lampId: id }), 0, (M.y != null ? M.y : 2.2) - (structure === "budget" ? 0 : 0.09), structure === "budget" ? 0.2 : 0.2, color2, 3.2, "outdoor", { lumens: 3.2, dist: 5.5, decay: 2 });
3185
3464
  }
3186
3465
  function lightSwitch(M, A) {
3187
3466
  const K2 = kit2(M, A, M.y != null && M.y > 0 ? M.y : 1.1), two = !!M.double;
@@ -3332,13 +3611,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
3332
3611
  for (const s of lt.perimeter) {
3333
3612
  const alongU = Math.abs(s.v1 - s.v0) < EPS, L = alongU ? s.v0 : s.u0, a = Math.min(alongU ? s.u0 : s.v0, alongU ? s.u1 : s.v1), b = Math.max(alongU ? s.u0 : s.v0, alongU ? s.u1 : s.v1);
3334
3613
  cursor.pc = pieceRecord("lot_wall:" + s.id, s.type === "wall" ? "brick" : s.type === "fence" ? "wood_soft" : "steel", null, { tags: ["wall"] });
3335
- const th = s.thickness || 0.15, h = s.height, color = colorOf(s.color) != null ? colorOf(s.color) : C.wall || 12104874, len = b - a;
3614
+ const th = s.thickness || 0.15, h = s.height, color2 = colorOf(s.color) != null ? colorOf(s.color) : C.wall || 12104874, len = b - a;
3336
3615
  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);
3337
3616
  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 };
3338
3617
  shared.ctx.colliders.push(col);
3339
3618
  if (s.type === "wall") {
3340
- B("plaster", a, 0, b, h, th, color);
3341
- B("plaster", a, h, b, h + 0.05, th + 0.06, sh(color, 1.15));
3619
+ B("plaster", a, 0, b, h, th, color2);
3620
+ B("plaster", a, h, b, h + 0.05, th + 0.06, sh(color2, 1.15));
3342
3621
  } else if (s.type === "fence") {
3343
3622
  const np = Math.max(2, Math.round(len / 2.4) + 1);
3344
3623
  for (let k = 0; k < np; k++) {
@@ -3350,8 +3629,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
3350
3629
  B("metal", a, 0.08, b, 0.12, 0.03, 9080466);
3351
3630
  } else {
3352
3631
  const gc = C.gate != null ? C.gate : 2763310, mh = 0.5;
3353
- B("plaster", a, 0, b, mh, th, color);
3354
- B("plaster", a, mh, b, mh + 0.04, th + 0.05, sh(color, 1.15));
3632
+ B("plaster", a, 0, b, mh, th, color2);
3633
+ B("plaster", a, mh, b, mh + 0.04, th + 0.05, sh(color2, 1.15));
3355
3634
  const n = Math.max(2, Math.round(len / 0.13));
3356
3635
  for (let k = 0; k <= n; k++) {
3357
3636
  const u = a + k * len / n;
@@ -3400,9 +3679,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
3400
3679
  cursor.group = "lot";
3401
3680
  for (const c of lt.paths) {
3402
3681
  if (c.type === "vehicle" && c.id !== "cargo_path") continue;
3403
- const color = c.type === "pedestrian" ? 13617856 : 11841704;
3682
+ const color2 = c.type === "pedestrian" ? 13617856 : 11841704;
3404
3683
  for (const [u0, v0, u1, v1] of c.rects) {
3405
- bx("sidewalk", u0, 0, v0, u1, 0.05, v1, color);
3684
+ bx("sidewalk", u0, 0, v0, u1, 0.05, v1, color2);
3406
3685
  }
3407
3686
  }
3408
3687
  }
@@ -3758,7 +4037,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
3758
4037
  const { UV_SCALE, _Y, _h2, _q, accFor, cursor, put, rgbOf, structurePiece } = K;
3759
4038
  const sh = (...a) => K.sh(...a);
3760
4039
  const R_STYLE = () => shared.ctx.r && shared.ctx.r.style || "budget";
3761
- function tileRelief(mat, pts, color, type) {
4040
+ function tileRelief(mat, pts, color2, type) {
3762
4041
  const n = pts.length;
3763
4042
  if (n < 3) return;
3764
4043
  const [a, b, c] = pts;
@@ -3822,7 +4101,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
3822
4101
  }
3823
4102
  col.push(lo <= hi ? [lo, hi] : null);
3824
4103
  }
3825
- const AC = accFor(mat), m = L.length, [cr, cg, cb] = rgbOf(color), O = cursor.org;
4104
+ const AC = accFor(mat), m = L.length, [cr, cg, cb] = rgbOf(color2), O = cursor.org;
3826
4105
  AC.ensure(m * 2, (m - 1) * 6);
3827
4106
  const base = AC.nv, w2 = 2 * Math.PI / P;
3828
4107
  for (let j = 0; j < m; j++) {
@@ -4200,15 +4479,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4200
4479
  }
4201
4480
  });
4202
4481
  const parts = [];
4203
- for (const { m, list, vc } of byMaterial.values()) {
4482
+ for (const { m, list: list2, vc } of byMaterial.values()) {
4204
4483
  let nv = 0, ni = 0;
4205
- for (const e of list) {
4484
+ for (const e of list2) {
4206
4485
  nv += e.P.length / 3;
4207
4486
  ni += e.I ? e.I.length : e.P.length / 3;
4208
4487
  }
4209
4488
  const P = new Float32Array(nv * 3), N = new Float32Array(nv * 3), U = new Float32Array(nv * 2), I = new Uint32Array(ni);
4210
4489
  let ov = 0, oi = 0;
4211
- for (const e of list) {
4490
+ for (const e of list2) {
4212
4491
  const n = e.P.length / 3;
4213
4492
  P.set(e.P, ov * 3);
4214
4493
  N.set(e.N, ov * 3);
@@ -4225,7 +4504,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4225
4504
  if (vc) {
4226
4505
  const C = new Float32Array(nv * 3);
4227
4506
  let q = 0;
4228
- for (const e of list) {
4507
+ for (const e of list2) {
4229
4508
  const n = e.P.length / 3, cr = e.color;
4230
4509
  for (let i = 0; i < n; i++, q++) {
4231
4510
  C[q * 3] = cr.r;
@@ -4336,7 +4615,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4336
4615
  const x = u.ry ? [u.u - uw, u.u] : [u.u, u.u + uw], z = u.ry ? [u.v - ud, u.v] : [u.v, u.v + ud];
4337
4616
  return [x[0], z[0], x[1], z[1]];
4338
4617
  };
4339
- const un0 = unitBox(un[0]), color = P.corridor, hall = P.hall, el = P.elevator.rect, es = P.stairs.rect;
4618
+ const un0 = unitBox(un[0]), color2 = P.corridor, hall = P.hall, el = P.elevator.rect, es = P.stairs.rect;
4340
4619
  const sel = un[shared.ctx.pu] || un[0], selR = unitBox(sel);
4341
4620
  const shell = (rc, y0, y1, thickness = 0.15) => {
4342
4621
  const [a, b, c, d] = rc;
@@ -4356,10 +4635,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4356
4635
  bx("glass", rc[0] + 0.5, y0 + 0.9, u.ry ? rc[1] - 1e-3 : rc[3] + 1e-3, rc[2] - 0.5, y0 + 2, u.ry ? rc[1] + 1e-3 : rc[3] + 2e-3, 16777215);
4357
4636
  }
4358
4637
  }
4359
- for (const rc of [color, hall]) {
4638
+ for (const rc of [color2, hall]) {
4360
4639
  bx("plaster", rc[0], y0 - 0.2, rc[1], rc[2], y0, rc[3], 12104874);
4361
4640
  }
4362
- shell([Math.min(color[0], hall[0]), hall[1], color[2], color[3]], y0, y0 + pe - 0.2);
4641
+ shell([Math.min(color2[0], hall[0]), hall[1], color2[2], color2[3]], y0, y0 + pe - 0.2);
4363
4642
  bx("metal", el[0] + 0.05, y0, el[1] + 0.05, el[2] - 0.05, y0 + pe, el[3] - 0.05, 8291466);
4364
4643
  bx("building", es[0], y0, es[1], es[2], y0 + pe - 0.2, es[3], 13618114);
4365
4644
  const ns = 16, rise = pe / ns, wl = es[2] - es[0] - 0.2;
@@ -4375,8 +4654,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4375
4654
  }
4376
4655
  }
4377
4656
  const ytop = N * pe - 0.2;
4378
- bx("plaster", Math.min(hall[0] - 3, color[0]), ytop, Math.min(un[1] ? unitBox(un[1])[1] : 0, el[1]), Math.max(color[2], un0[2]), ytop + 0.2, Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0), 11841704);
4379
- shared.ctx.limits = { x0: Math.min(hall[0] - 3, color[0]), z0: Math.min(el[1], un[1] ? unitBox(un[1])[1] : 0), x1: Math.max(color[2], un0[2]), z1: Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0) };
4657
+ 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);
4658
+ shared.ctx.limits = { x0: Math.min(hall[0] - 3, color2[0]), z0: Math.min(el[1], un[1] ? unitBox(un[1])[1] : 0), x1: Math.max(color2[2], un0[2]), z1: Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0) };
4380
4659
  }
4381
4660
  Object.assign(K, { building });
4382
4661
  }
@@ -4466,11 +4745,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4466
4745
  return api;
4467
4746
  }
4468
4747
  const PIPE_COLOR = 11897429;
4469
- function pipe(a, b, diameter, color) {
4748
+ function pipe(a, b, diameter, color2) {
4470
4749
  const dx = b[0] - a[0], dy = b[1] - a[1], dz = b[2] - a[2], L = Math.hypot(dx, dy, dz);
4471
4750
  if (L < 1e-3) return;
4472
4751
  _q.setFromUnitVectors(_Y, _v3.set(dx / L, dy / L, dz / L));
4473
- put("plain", "cyl", (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, _q, diameter, L, diameter, color);
4752
+ put("plain", "cyl", (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, _q, diameter, L, diameter, color2);
4474
4753
  }
4475
4754
  const _v3 = new THREE.Vector3();
4476
4755
  function waterPipes() {
@@ -4567,9 +4846,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4567
4846
  const g0 = cursor.group, noDrawing = !!(KV && KV.picture);
4568
4847
  cursor.group = "f" + Math.max(0, Math.min(nA - 1, Q.floor || 0));
4569
4848
  const frontU = Q.frontU || 0, frontV = Q.frontV || 0, w = Q.w || 0.3, h = Q.h || 0.4, hw = w / 2, d = 0.05;
4570
- const bq = (a0, y0_, a1, y1_, o0, o1, mat, color) => {
4571
- if (frontV) bx(mat, Q.u + a0, Q.y + y0_, Q.v + (frontV > 0 ? o0 : -o1), Q.u + a1, Q.y + y1_, Q.v + (frontV > 0 ? o1 : -o0), color);
4572
- else bx(mat, Q.u + (frontU > 0 ? o0 : -o1), Q.y + y0_, Q.v + a0, Q.u + (frontU > 0 ? o1 : -o0), Q.y + y1_, Q.v + a1, color);
4849
+ const bq = (a0, y0_, a1, y1_, o0, o1, mat, color2) => {
4850
+ if (frontV) bx(mat, Q.u + a0, Q.y + y0_, Q.v + (frontV > 0 ? o0 : -o1), Q.u + a1, Q.y + y1_, Q.v + (frontV > 0 ? o1 : -o0), color2);
4851
+ else bx(mat, Q.u + (frontU > 0 ? o0 : -o1), Q.y + y0_, Q.v + a0, Q.u + (frontU > 0 ? o1 : -o0), Q.y + y1_, Q.v + a1, color2);
4573
4852
  };
4574
4853
  if (!noDrawing) {
4575
4854
  bq(-hw, -h / 2, hw, h / 2, -0.015, 0.06, "plain", 13619926);
@@ -4613,11 +4892,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4613
4892
  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 });
4614
4893
  shared.ctx.electricalInfo = info;
4615
4894
  }
4616
- function pipe2(a, b, diameter, color) {
4895
+ function pipe2(a, b, diameter, color2) {
4617
4896
  const dx = b[0] - a[0], dy = b[1] - a[1], dz = b[2] - a[2], L = Math.hypot(dx, dy, dz);
4618
4897
  if (L < 1e-3) return;
4619
4898
  _q.setFromUnitVectors(_Y, _v3.set(dx / L, dy / L, dz / L));
4620
- put("plain", "cyl", (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, _q, diameter, L, diameter, color);
4899
+ put("plain", "cyl", (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, _q, diameter, L, diameter, color2);
4621
4900
  }
4622
4901
  Object.assign(K, { electricalStructure, pipe2 });
4623
4902
  }
@@ -4627,7 +4906,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4627
4906
  const { Y0, bx, cursor, sideOf } = K;
4628
4907
  const sh = (...a) => K.sh(...a);
4629
4908
  function baseboardAndSidewalk() {
4630
- const R = shared.ctx.r, W = 0.6, t = 0.012, ht = 0.35, color = sh(shared.ctx.colors.facade != null ? shared.ctx.colors.facade : 14209216, 0.62), y0 = Y0(0), cal = 13947078;
4909
+ const R = shared.ctx.r, W = 0.6, t = 0.012, ht = 0.35, color2 = sh(shared.ctx.colors.facade != null ? shared.ctx.colors.facade : 14209216, 0.62), y0 = Y0(0), cal = 13947078;
4631
4910
  const ws = R.walls.filter((w) => w.floor === 0 && w.type === "wall").map((w) => {
4632
4911
  const au = w.axis === "u";
4633
4912
  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 };
@@ -4653,7 +4932,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4653
4932
  if (A.au) bx(mat, s0, y1, lo, s1, y2, hi, c);
4654
4933
  else bx(mat, lo, y1, s0, hi, y2, s1, c);
4655
4934
  };
4656
- strip(t, y0, y0 + ht, 0, t, "plaster", color);
4935
+ strip(t, y0, y0 + ht, 0, t, "plaster", color2);
4657
4936
  strip(W, y0, y0 + 0.045, 0, W, "sidewalk", cal);
4658
4937
  }
4659
4938
  }
@@ -4702,7 +4981,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4702
4981
  tilt = Math.atan2(yA - yB, d);
4703
4982
  yc = yC + 0.13;
4704
4983
  }
4705
- const co = Math.cos(tilt), si = Math.sin(tilt), pb = (lx, ly, lz, sx, sy, sz, mat, color) => boxC(mat, p.u + lx, yc + ly * co - lz * si, p.v + ly * si + lz * co, sx, sy, sz, color, tilt, 0, 0), L = p.length;
4984
+ const co = Math.cos(tilt), si = Math.sin(tilt), pb = (lx, ly, lz, sx, sy, sz, mat, color2) => boxC(mat, p.u + lx, yc + ly * co - lz * si, p.v + ly * si + lz * co, sx, sy, sz, color2, tilt, 0, 0), L = p.length;
4706
4985
  pb(0, 0, 0, p.w, 0.04, L, "metal", silver);
4707
4986
  pb(0, 0.0205, 0, p.w - 0.07, 6e-3, L - 0.07, "plain", blue);
4708
4987
  for (let k = 1; k < 4; k++) pb(-hw + 0.035 + k * (p.w - 0.07) / 4, 0.0245, 0, 6e-3, 3e-3, L - 0.07, "metal", line);
@@ -4794,39 +5073,39 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4794
5073
  return [M.x + lx * c + lz * s, M.z - lx * s + lz * c];
4795
5074
  };
4796
5075
  return {
4797
- box(M, mat, x, y, z, w, h, d, color, ry = 0, rx = 0, rz = 0) {
5076
+ box(M, mat, x, y, z, w, h, d, color2, ry = 0, rx = 0, rz = 0) {
4798
5077
  const [px, pz] = loc(M, x, z);
4799
- boxC(mm(mat), px, M.base + y + h / 2, pz, w, h, d, color, rx, M.ry + ry, rz);
5078
+ boxC(mm(mat), px, M.base + y + h / 2, pz, w, h, d, color2, rx, M.ry + ry, rz);
4800
5079
  },
4801
- cylinder(M, mat, x, y, z, r, h, color, rx = 0, rz = 0, seg) {
5080
+ cylinder(M, mat, x, y, z, r, h, color2, rx = 0, rz = 0, seg) {
4802
5081
  const [px, pz] = loc(M, x, z);
4803
5082
  _q.setFromEuler(_e.set(rx || 0, M.ry, rz || 0, "YXZ"));
4804
- put(mm(mat), seg || "cyl", px, M.base + y + (rx || rz ? 0 : h / 2), pz, _q, r * 2, h, r * 2, color);
5083
+ put(mm(mat), seg || "cyl", px, M.base + y + (rx || rz ? 0 : h / 2), pz, _q, r * 2, h, r * 2, color2);
4805
5084
  },
4806
- leaf(M, x, y, z, w, h, color, ry = 0, rx = 0) {
5085
+ leaf(M, x, y, z, w, h, color2, ry = 0, rx = 0) {
4807
5086
  const [px, pz] = loc(M, x, z), a = M.ry + (ry || 0), ca = Math.cos(a), sa = Math.sin(a), t1 = (rx || 0) * 0.8, t2 = (rx || 0) * 1.5, y0 = M.base + y;
4808
5087
  const P = (lx, ly, lz) => [px + lx * ca + lz * sa, y0 + ly, pz - lx * sa + lz * ca];
4809
5088
  const my = Math.cos(t1) * h * 0.5, mz = Math.sin(t1) * h * 0.5, ty = my + Math.cos(t2) * h * 0.5, tz = mz + Math.sin(t2) * h * 0.5, f = w * 0.5, dn = f * 0.32;
4810
5089
  const B = P(0, 0, 0), Mi = P(0, my + 4e-3, mz), T2 = P(0, ty, tz), L = P(-f, my - dn, mz - dn * 0.3), R = P(f, my - dn, mz - dn * 0.3);
4811
- polyFace("plant", [B, L, T2, Mi], color, [0, 1, 0]);
4812
- polyFace("plant", [B, Mi, T2, R], sh(color, 0.92), [0, 1, 0]);
5090
+ polyFace("plant", [B, L, T2, Mi], color2, [0, 1, 0]);
5091
+ polyFace("plant", [B, Mi, T2, R], sh(color2, 0.92), [0, 1, 0]);
4813
5092
  },
4814
- plane(M, mat, x, y, z, w, h, color, ry = 0, rx = 0, rz = 0, uv) {
5093
+ plane(M, mat, x, y, z, w, h, color2, ry = 0, rx = 0, rz = 0, uv) {
4815
5094
  const [px, pz] = loc(M, x, z);
4816
5095
  _q.setFromEuler(_e.set(rx || 0, M.ry + (ry || 0), rz || 0, "YXZ"));
4817
5096
  if (uv && mat === "atlas_floor") {
4818
5097
  const col = Math.floor(uv.u0 * 4 + 1e-6), lin = uv.v0 < 0.5 ? 1 : 0, cell = col + 4 * lin, h0 = _h2(Math.round(px * 8), Math.round(pz * 8)), type = cell === 5 ? "dirt" : cell === 0 || cell === 1 ? "lawn" : null;
4819
5098
  if (type === "dirt") {
4820
- put("dirt", "plane", px, M.base + y, pz, _q, w, h, 1, sh(color, 1 / 0.965));
5099
+ put("dirt", "plane", px, M.base + y, pz, _q, w, h, 1, sh(color2, 1 / 0.965));
4821
5100
  return;
4822
5101
  }
4823
5102
  if (type) uv = { u0: uv.u0, u1: uv.u1, v0: uv.v0, v1: uv.v1, rot: h0 * 4 | 0, fx: h0 > 0.5 ? 1 : 0, vc: (wx, wz) => macroGround(wx, wz, type) };
4824
5103
  }
4825
- put(mm(mat), "plane", px, M.base + y, pz, _q, w, h, 1, color, uv);
5104
+ put(mm(mat), "plane", px, M.base + y, pz, _q, w, h, 1, color2, uv);
4826
5105
  },
4827
- light(M, x, y, z, color, range, type, ex) {
5106
+ light(M, x, y, z, color2, range2, type, ex) {
4828
5107
  const [px, pz] = loc(M, x, z);
4829
- LIGHTS.push(Object.assign({ x: px, y: M.base + y, z: pz, color, range, type, floor: M.floor, group: cursor.group, base: M.base, room: M.room, id: M.lampId }, ex || null));
5108
+ LIGHTS.push(Object.assign({ x: px, y: M.base + y, z: pz, color: color2, range: range2, type, floor: M.floor, group: cursor.group, base: M.base, room: M.room, id: M.lampId }, ex || null));
4830
5109
  }
4831
5110
  };
4832
5111
  }
@@ -4841,7 +5120,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4841
5120
  }
4842
5121
  function kk(M, A) {
4843
5122
  const y0 = M.y || 0;
4844
- return { b: (mat, x, y, z, w, h, d, color, ry, rx, rz) => A.box(M, mat, x, y0 + y, z, w, h, d, color, ry || 0, rx || 0, rz || 0), c: (mat, x, y, z, r, h, color, rx, rz, seg) => A.cylinder(M, mat, x, y0 + y, z, r, h, color, rx || 0, rz || 0, seg), rnd: rngOf(M), wood: paletteColor(M, "wood", 8016948), met: paletteColor(M, "metal", 10133154) };
5123
+ return { b: (mat, x, y, z, w, h, d, color2, ry, rx, rz) => A.box(M, mat, x, y0 + y, z, w, h, d, color2, ry || 0, rx || 0, rz || 0), c: (mat, x, y, z, r, h, color2, rx, rz, seg) => A.cylinder(M, mat, x, y0 + y, z, r, h, color2, rx || 0, rz || 0, seg), rnd: rngOf(M), wood: paletteColor(M, "wood", 8016948), met: paletteColor(M, "metal", 10133154) };
4845
5124
  }
4846
5125
  const PE = Math.PI / 2;
4847
5126
  Object.assign(K, { MATERIAL_MAP: MATERIAL_MAP2, mm, LIGHTS, makeApi, sh, paletteColor, rngOf, kk, PE });
@@ -5016,13 +5295,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5016
5295
  lb("metal", 0, h - 0.23, d / 2 + 0.04, w - 0.12, 0.02, 0.02, 10526880);
5017
5296
  },
5018
5297
  kitchen_cabinet(M, A, o = {}) {
5019
- const { b: lb, c: lc } = kk(M, A), w = M.w, d = M.d, h = M.h || 0.95, color = paletteColor(M, "wall_kitchen", 15262420), wood = paletteColor(M, "wood", 11571296);
5020
- lb("plain", 0, 0.08, -0.02, w, h - 0.15, d - 0.05, color);
5298
+ const { b: lb, c: lc } = kk(M, A), w = M.w, d = M.d, h = M.h || 0.95, color2 = paletteColor(M, "wall_kitchen", 15262420), wood = paletteColor(M, "wood", 11571296);
5299
+ lb("plain", 0, 0.08, -0.02, w, h - 0.15, d - 0.05, color2);
5021
5300
  lb("plain", 0, 0, 0, w - 0.04, 0.08, d - 0.12, 2763306);
5022
5301
  const nd = Math.max(2, Math.round(w / 0.55));
5023
5302
  for (let k = 0; k < nd; k++) {
5024
5303
  const u = -w / 2 + (k + 0.5) * w / nd;
5025
- lb("plain", u, 0.12, d / 2 - 0.02, w / nd - 0.03, h - 0.28, 0.02, sh(color, 1.06));
5304
+ lb("plain", u, 0.12, d / 2 - 0.02, w / nd - 0.03, h - 0.28, 0.02, sh(color2, 1.06));
5026
5305
  lb("metal", u + (k % 2 ? -0.2 : 0.2) * (w / nd), h * 0.62, d / 2, 0.012, 0.12, 0.015, 9079434);
5027
5306
  }
5028
5307
  if (o.noBasin) lb("plain", 0, h - 0.07, 0, w + 0.03, 0.035, d + 0.03, 4868164);
@@ -5044,13 +5323,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5044
5323
  }
5045
5324
  if (!o.noOverhead && (M.overhead === true || M.overhead == null && w >= 1.2)) {
5046
5325
  const ya = 1.55;
5047
- lb("plain", 0, ya, -d / 2 + 0.18, w, 0.6, 0.35, color);
5048
- for (let k = 0; k < 3; k++) lb("plain", -w / 2 + (k + 0.5) * w / 3, ya + 0.02, -d / 2 + 0.36, w / 3 - 0.03, 0.56, 0.015, sh(color, 1.06));
5326
+ lb("plain", 0, ya, -d / 2 + 0.18, w, 0.6, 0.35, color2);
5327
+ for (let k = 0; k < 3; k++) lb("plain", -w / 2 + (k + 0.5) * w / 3, ya + 0.02, -d / 2 + 0.36, w / 3 - 0.03, 0.56, 0.015, sh(color2, 1.06));
5049
5328
  }
5050
5329
  },
5051
5330
  counter(M, A, o = {}) {
5052
- const { b: lb } = kk(M, A), w = M.w, d = M.d, h = M.h, color = o.color != null ? o.color : paletteColor(M, "wood", 9071176), top = o.top != null ? o.top : 14210252;
5053
- lb("plain", 0, 0, 0, w, h * (o.glass ? 0.45 : 1) - 0.04, d, color);
5331
+ const { b: lb } = kk(M, A), w = M.w, d = M.d, h = M.h, color2 = o.color != null ? o.color : paletteColor(M, "wood", 9071176), top = o.top != null ? o.top : 14210252;
5332
+ lb("plain", 0, 0, 0, w, h * (o.glass ? 0.45 : 1) - 0.04, d, color2);
5054
5333
  lb("plain", 0, h * (o.glass ? 0.45 : 1) - 0.04, 0, w + 0.03, 0.04, d + 0.03, top);
5055
5334
  if (o.glass) {
5056
5335
  lb("glass", 0, h * 0.45, 0, w - 0.04, h * 0.55, d - 0.04, 16777215);
@@ -5320,9 +5599,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5320
5599
  lb("glass", w * 0.28, 1, d / 2 + 0.01, 0.8, 0.9, 0.02, 16777215);
5321
5600
  },
5322
5601
  motorcycle(M, A) {
5323
- const { b: lb, c: lc } = kk(M, A), d = M.d, color = M.color != null ? M.color : 11024948;
5602
+ const { b: lb, c: lc } = kk(M, A), d = M.d, color2 = M.color != null ? M.color : 11024948;
5324
5603
  for (const s of [-1, 1]) lc("plain", 0, 0.3, s * d * 0.34, 0.3, 0.12, 1710618, 0, PE);
5325
- lb("plain", 0, 0.35, 0, 0.18, 0.28, d * 0.5, color);
5604
+ lb("plain", 0, 0.35, 0, 0.18, 0.28, d * 0.5, color2);
5326
5605
  lb("plain", 0, 0.62, -0.1, 0.22, 0.1, 0.6, 2236962);
5327
5606
  lb("metal", 0, 0.7, d * 0.28, 0.5, 0.04, 0.04, 11580600);
5328
5607
  },
@@ -5667,13 +5946,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5667
5946
  };
5668
5947
  FURNITURE.curtain = function(M, A) {
5669
5948
  const w = M.w || 1.6, h = M.h || 2.3, y = M.y != null && M.y > 0 ? M.y : 0.1, K2 = kit2(M, A, 0), top = y + h;
5670
- const rnd = rngString(SEED() + "|" + seedKey(M.seed) + "|cort"), color = M.color != null ? M.color : [14208436, 10465470, 12953740, 14736592][rnd() * 4 | 0], gold = M.palette && M.palette.metal != null ? M.palette.metal : 5918792;
5949
+ const rnd = rngString(SEED() + "|" + seedKey(M.seed) + "|cort"), color2 = M.color != null ? M.color : [14208436, 10465470, 12953740, 14736592][rnd() * 4 | 0], gold = M.palette && M.palette.metal != null ? M.palette.metal : 5918792;
5671
5950
  K2.t("metal", [-w / 2 - 0.05, top + 0.02, 0], [w / 2 + 0.05, top + 0.02, 0], 0.012, gold);
5672
5951
  for (const s of [-1, 1]) K2.e("metal", s * (w / 2 + 0.07), top + 0.02, 0, 0.022, 0.045, gold);
5673
5952
  const pw = w / 2 + 0.03, n = Math.max(8, Math.round(pw / 0.075));
5674
5953
  for (const s of [-1, 1]) for (let i = 0; i < n; i++) {
5675
5954
  const ux = s * (i + 0.5) * pw / n;
5676
- K2.b("fabric", ux, y, i % 2 ? 0.03 : -0.012, pw / n * 1.12, h - 0.04, 0.018, i % 2 ? sh(color, 0.88) : color);
5955
+ K2.b("fabric", ux, y, i % 2 ? 0.03 : -0.012, pw / n * 1.12, h - 0.04, 0.018, i % 2 ? sh(color2, 0.88) : color2);
5677
5956
  }
5678
5957
  for (const s of [-1, 1]) for (let i = 0; i < n; i += 2) K2.e("metal", s * (i + 0.5) * pw / n, top + 0.012, 0, 0.012, 0.024, gold);
5679
5958
  };
@@ -5696,15 +5975,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5696
5975
  }
5697
5976
  }
5698
5977
  }
5699
- function potModel(K2, x, y, z, r, h, color, soil = true) {
5978
+ function potModel(K2, x, y, z, r, h, color2, soil = true) {
5700
5979
  const rimR = r * 1.1;
5701
- K2.c("plain", x, y, z, r * 0.62, h * 0.55, sh(color, 0.92));
5702
- K2.c("plain", x, y + h * 0.5, z, r * 0.84, h * 0.34, color);
5703
- K2.c("plain", x, y + h * 0.82, z, rimR, h * 0.18, sh(color, 1.08));
5980
+ K2.c("plain", x, y, z, r * 0.62, h * 0.55, sh(color2, 0.92));
5981
+ K2.c("plain", x, y + h * 0.5, z, r * 0.84, h * 0.34, color2);
5982
+ K2.c("plain", x, y + h * 0.82, z, rimR, h * 0.18, sh(color2, 1.08));
5704
5983
  if (soil) K2.c("plain", x, y + h * 0.995, z, r * 0.92, h * 0.012, 3811870);
5705
5984
  return y + h;
5706
5985
  }
5707
- function arcLeaf(K2, bx_, by, bz, az, len, elev, drop, wmax, color, serrated, nSeg = 6) {
5986
+ function arcLeaf(K2, bx_, by, bz, az, len, elev, drop, wmax, color2, serrated, nSeg = 6) {
5708
5987
  const c = Math.cos(az), s = Math.sin(az), pts = [];
5709
5988
  for (let i = 0; i <= nSeg; i++) {
5710
5989
  const f = i / nSeg, d = f * len;
@@ -5713,14 +5992,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5713
5992
  const px = -s, pz = c;
5714
5993
  for (let i = 0; i < nSeg; i++) {
5715
5994
  const f0 = i / nSeg, f1 = (i + 1) / nSeg, w0 = wmax * Math.sin(Math.PI * Math.min(1, f0 * 0.85 + 0.12)) * (serrated && i % 2 ? 0.7 : 1), w1 = wmax * Math.sin(Math.PI * Math.min(1, f1 * 0.85 + 0.12)) * (serrated && i % 2 ? 1 : 0.7), dn = 0.35;
5716
- for (const sd of [-1, 1]) K2.polyFace("plant", [pts[i], pts[i + 1], [pts[i + 1][0] + px * sd * w1, pts[i + 1][1] - w1 * dn, pts[i + 1][2] + pz * sd * w1], [pts[i][0] + px * sd * w0, pts[i][1] - w0 * dn, pts[i][2] + pz * sd * w0]], i % 2 ? sh(color, 0.9) : color, [0, 1, 0]);
5995
+ for (const sd of [-1, 1]) K2.polyFace("plant", [pts[i], pts[i + 1], [pts[i + 1][0] + px * sd * w1, pts[i + 1][1] - w1 * dn, pts[i + 1][2] + pz * sd * w1], [pts[i][0] + px * sd * w0, pts[i][1] - w0 * dn, pts[i][2] + pz * sd * w0]], i % 2 ? sh(color2, 0.9) : color2, [0, 1, 0]);
5717
5996
  }
5718
5997
  return pts[nSeg];
5719
5998
  }
5720
- function tuft(K2, x, y, z, r, n, color, rnd) {
5999
+ function tuft(K2, x, y, z, r, n, color2, rnd) {
5721
6000
  for (let i = 0; i < n; i++) {
5722
6001
  const a = rnd() * 6.283, d0 = rnd() * r * 0.35, L = r * (0.8 + rnd() * 1.1), bw = 0.012 + rnd() * 8e-3, lean = 0.25 + rnd() * 0.5, c = Math.cos(a), s = Math.sin(a), px = -s, pz = c, x0 = x + c * d0, z0 = z + s * d0;
5723
- const m = [x0 + c * lean * L * 0.35, y + L * 0.55, z0 + s * lean * L * 0.35], t = [x0 + c * lean * L, y + L * (0.95 - lean * 0.2), z0 + s * lean * L], vc = sh(color, 0.78 + rnd() * 0.4);
6002
+ const m = [x0 + c * lean * L * 0.35, y + L * 0.55, z0 + s * lean * L * 0.35], t = [x0 + c * lean * L, y + L * (0.95 - lean * 0.2), z0 + s * lean * L], vc = sh(color2, 0.78 + rnd() * 0.4);
5724
6003
  K2.polyFace("plant", [[x0 - px * bw, y, z0 - pz * bw], [x0 + px * bw, y, z0 + pz * bw], [m[0] + px * bw * 0.6, m[1], m[2] + pz * bw * 0.6], t, [m[0] - px * bw * 0.6, m[1], m[2] - pz * bw * 0.6]], vc, [0, 1, 0]);
5725
6004
  }
5726
6005
  }
@@ -5811,31 +6090,31 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5811
6090
  const seedKey = (id) => K.seedKey(id);
5812
6091
  const { FURNITURE, SEED, STYLE, kit2, rngString, sh, wallTap } = K;
5813
6092
  FURNITURE.laundry_tub = function(M, A) {
5814
- const K2 = kit2(M, A), w = M.w || 0.6, d = M.d || 0.55, H = M.h || 0.9, structure = STYLE(), upper = structure === "budget", color = upper ? 11841700 : 15790058, int = upper ? 10134694 : 14870248, rim = sh(color, 1.06);
6093
+ const K2 = kit2(M, A), w = M.w || 0.6, d = M.d || 0.55, H = M.h || 0.9, structure = STYLE(), upper = structure === "budget", color2 = upper ? 11841700 : 15790058, int2 = upper ? 10134694 : 14870248, rim = sh(color2, 1.06);
5815
6094
  const yb = H - 0.36, t = 0.04, rc = 0.055, zw = -d / 2;
5816
- for (const sx of [-1, 1]) for (const sz of [-1, 1]) K2.c("plain", sx * (w / 2 - rc), yb, sz * (d / 2 - rc), rc, 0.36, color);
5817
- K2.b("plain", 0, yb, d / 2 - t / 2, w - 2 * rc + 0.01, 0.36, t, color);
5818
- K2.b("plain", 0, yb, -d / 2 + t / 2, w - 2 * rc + 0.01, 0.36, t, color);
5819
- K2.b("plain", -w / 2 + t / 2, yb, 0, t, 0.36, d - 2 * rc + 0.01, color);
5820
- K2.b("plain", w / 2 - t / 2, yb, 0, t, 0.36, d - 2 * rc + 0.01, color);
5821
- K2.b("plain", 0, yb, 0, w - 2 * t, 0.06, d - 2 * t, int);
6095
+ for (const sx of [-1, 1]) for (const sz of [-1, 1]) K2.c("plain", sx * (w / 2 - rc), yb, sz * (d / 2 - rc), rc, 0.36, color2);
6096
+ K2.b("plain", 0, yb, d / 2 - t / 2, w - 2 * rc + 0.01, 0.36, t, color2);
6097
+ K2.b("plain", 0, yb, -d / 2 + t / 2, w - 2 * rc + 0.01, 0.36, t, color2);
6098
+ K2.b("plain", -w / 2 + t / 2, yb, 0, t, 0.36, d - 2 * rc + 0.01, color2);
6099
+ K2.b("plain", w / 2 - t / 2, yb, 0, t, 0.36, d - 2 * rc + 0.01, color2);
6100
+ K2.b("plain", 0, yb, 0, w - 2 * t, 0.06, d - 2 * t, int2);
5822
6101
  for (const sx of [-1, 1]) for (const sz of [-1, 1]) K2.c("plain", sx * (w / 2 - rc), H - 4e-3, sz * (d / 2 - rc), rc + 8e-3, 0.012, rim);
5823
6102
  K2.b("plain", 0, H - 4e-3, d / 2 - 0.011, w - 2 * rc, 0.012, 0.022, rim);
5824
6103
  K2.b("plain", 0, H - 4e-3, -d / 2 + 0.011, w - 2 * rc, 0.012, 0.022, rim);
5825
6104
  K2.b("plain", -w / 2 + 0.011, H - 4e-3, 0, 0.022, 0.012, d - 2 * rc, rim);
5826
6105
  K2.b("plain", w / 2 - 0.011, H - 4e-3, 0, 0.022, 0.012, d - 2 * rc, rim);
5827
6106
  const tw = Math.min(0.2, w * 0.34), tx = -w / 2 + t + tw / 2 + 0.01, zt1 = d / 2 - t - 0.01, zt0 = -d / 2 + t + 0.08, ytop = H - 0.03, ybot = yb + 0.14, L = Math.hypot(zt1 - zt0, ytop - ybot), al = Math.atan2(ytop - ybot, zt1 - zt0);
5828
- K2.b("plain", tx, (ytop + ybot) / 2 - 0.015, (zt0 + zt1) / 2, tw, 0.03, L, sh(color, 0.96), 0, -al, 0);
6107
+ K2.b("plain", tx, (ytop + ybot) / 2 - 0.015, (zt0 + zt1) / 2, tw, 0.03, L, sh(color2, 0.96), 0, -al, 0);
5829
6108
  const nr = 7;
5830
6109
  for (let i = 0; i < nr; i++) {
5831
6110
  const f = (i + 0.5) / nr, zz = zt0 + (zt1 - zt0) * f, yy = ybot + (ytop - ybot) * f;
5832
- K2.b("plain", tx, yy + 3e-3, zz, tw - 0.02, 0.014, 0.018, sh(color, 0.88), 0, -al, 0);
6111
+ K2.b("plain", tx, yy + 3e-3, zz, tw - 0.02, 0.014, 0.018, sh(color2, 0.88), 0, -al, 0);
5833
6112
  }
5834
6113
  K2.c("metal", 0.1, yb + 0.06, 0, 0.034, 8e-3, 11580600);
5835
6114
  K2.c("plain", 0.1, yb + 0.068, 0, 0.026, 0.01, 3817026);
5836
6115
  if (upper) {
5837
- for (const sx of [-1, 1]) K2.b("plain", sx * (w / 2 - 0.035), 0, 0, 0.07, yb, d - 0.05, sh(color, 0.94));
5838
- K2.b("plain", 0, yb - 0.04, 0, w - 0.1, 0.04, d - 0.06, sh(color, 0.9));
6116
+ for (const sx of [-1, 1]) K2.b("plain", sx * (w / 2 - 0.035), 0, 0, 0.07, yb, d - 0.05, sh(color2, 0.94));
6117
+ K2.b("plain", 0, yb - 0.04, 0, w - 0.1, 0.04, d - 0.06, sh(color2, 0.9));
5839
6118
  } else for (const sx of [-1, 1]) for (const sz of [-1, 1]) {
5840
6119
  K2.c("metal", sx * (w / 2 - 0.07), 0, sz * (d / 2 - 0.07), 0.022, yb, 11843772);
5841
6120
  K2.c("metal", sx * (w / 2 - 0.07), 0, sz * (d / 2 - 0.07), 0.03, 0.012, 6975090);
@@ -5843,30 +6122,30 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5843
6122
  wallTap(K2, 0, H + 0.14, zw + 0, 1, yb + 0.06, { laundry_tub: true });
5844
6123
  };
5845
6124
  const CLOTHES_COLORS = [14209208, 4876938, 12077114, 15262936, 6982234, 14856266, 9067146, 3099242, 13925002, 8038072];
5846
- function strip(K2, rows, zc, rot, color, cx) {
6125
+ function strip(K2, rows, zc, rot, color2, cx) {
5847
6126
  const c = Math.cos(rot), s = Math.sin(rot), P = (x, y) => [cx + (x - cx) * c, y, zc + (x - cx) * s];
5848
6127
  for (let i = 0; i < rows.length - 1; i++) {
5849
6128
  const a = rows[i], b = rows[i + 1];
5850
- K2.polyFace("clothes", [P(a[1], a[0]), P(a[2], a[0]), P(b[2], b[0]), P(b[1], b[0])], i % 2 ? sh(color, 0.96) : color, [0, 0, 1]);
6129
+ K2.polyFace("clothes", [P(a[1], a[0]), P(a[2], a[0]), P(b[2], b[0]), P(b[1], b[0])], i % 2 ? sh(color2, 0.96) : color2, [0, 0, 1]);
5851
6130
  }
5852
6131
  }
5853
- function garment(K2, type, cx, ly, zc, rot, color, rnd) {
6132
+ function garment(K2, type, cx, ly, zc, rot, color2, rnd) {
5854
6133
  const sh0 = (rows, dx = 0) => rows.map((r) => [ly + r[0], cx + dx + r[1], cx + dx + r[2]]);
5855
- if (type === "shirt") strip(K2, sh0([[0, -0.13, 0.13], [-0.03, -0.27, 0.27], [-0.15, -0.3, 0.3], [-0.2, -0.2, 0.2], [-0.62, -0.2, 0.2], [-0.63, -0.2, 0.2]]), zc, rot, color, cx);
6134
+ if (type === "shirt") strip(K2, sh0([[0, -0.13, 0.13], [-0.03, -0.27, 0.27], [-0.15, -0.3, 0.3], [-0.2, -0.2, 0.2], [-0.62, -0.2, 0.2], [-0.63, -0.2, 0.2]]), zc, rot, color2, cx);
5856
6135
  else if (type === "trousers") {
5857
- strip(K2, sh0([[0, -0.19, -0.01], [-0.4, -0.18, -0.02], [-0.78, -0.16, -0.03], [-0.79, -0.16, -0.03]]), zc, rot, color, cx);
5858
- strip(K2, sh0([[0, 0.01, 0.19], [-0.4, 0.02, 0.18], [-0.78, 0.03, 0.16], [-0.79, 0.03, 0.16]]), zc, rot, sh(color, 0.95), cx);
6136
+ strip(K2, sh0([[0, -0.19, -0.01], [-0.4, -0.18, -0.02], [-0.78, -0.16, -0.03], [-0.79, -0.16, -0.03]]), zc, rot, color2, cx);
6137
+ strip(K2, sh0([[0, 0.01, 0.19], [-0.4, 0.02, 0.18], [-0.78, 0.03, 0.16], [-0.79, 0.03, 0.16]]), zc, rot, sh(color2, 0.95), cx);
5859
6138
  } else if (type === "shorts") {
5860
- strip(K2, sh0([[0, -0.2, -0.01], [-0.3, -0.2, -0.02], [-0.31, -0.2, -0.02]]), zc, rot, color, cx);
5861
- strip(K2, sh0([[0, 0.01, 0.2], [-0.3, 0.02, 0.2], [-0.31, 0.02, 0.2]]), zc, rot, sh(color, 0.95), cx);
6139
+ strip(K2, sh0([[0, -0.2, -0.01], [-0.3, -0.2, -0.02], [-0.31, -0.2, -0.02]]), zc, rot, color2, cx);
6140
+ strip(K2, sh0([[0, 0.01, 0.2], [-0.3, 0.02, 0.2], [-0.31, 0.02, 0.2]]), zc, rot, sh(color2, 0.95), cx);
5862
6141
  } else if (type === "towel") {
5863
- strip(K2, sh0([[0, -0.32, 0.32], [-0.2, -0.32, 0.32], [-0.22, -0.32, 0.32], [-0.5, -0.32, 0.32], [-0.9, -0.32, 0.32], [-0.91, -0.32, 0.32]]), zc, rot, color, cx);
5864
- strip(K2, sh0([[-0.22, -0.32, 0.32], [-0.3, -0.32, 0.32]]), zc, rot, sh(color, 1.25), cx);
5865
- } else if (type === "sheet") strip(K2, sh0([[0, -0.5, 0.5], [-0.35, -0.5, 0.5], [-0.7, -0.5, 0.5], [-1.05, -0.5, 0.5], [-1.06, -0.5, 0.5]]), zc, rot, color, cx);
5866
- else if (type === "dress") strip(K2, sh0([[0, -0.14, 0.14], [-0.06, -0.2, 0.2], [-0.3, -0.16, 0.16], [-0.62, -0.28, 0.28], [-0.63, -0.28, 0.28]]), zc, rot, color, cx);
6142
+ strip(K2, sh0([[0, -0.32, 0.32], [-0.2, -0.32, 0.32], [-0.22, -0.32, 0.32], [-0.5, -0.32, 0.32], [-0.9, -0.32, 0.32], [-0.91, -0.32, 0.32]]), zc, rot, color2, cx);
6143
+ strip(K2, sh0([[-0.22, -0.32, 0.32], [-0.3, -0.32, 0.32]]), zc, rot, sh(color2, 1.25), cx);
6144
+ } else if (type === "sheet") strip(K2, sh0([[0, -0.5, 0.5], [-0.35, -0.5, 0.5], [-0.7, -0.5, 0.5], [-1.05, -0.5, 0.5], [-1.06, -0.5, 0.5]]), zc, rot, color2, cx);
6145
+ else if (type === "dress") strip(K2, sh0([[0, -0.14, 0.14], [-0.06, -0.2, 0.2], [-0.3, -0.16, 0.16], [-0.62, -0.28, 0.28], [-0.63, -0.28, 0.28]]), zc, rot, color2, cx);
5867
6146
  else {
5868
- strip(K2, sh0([[0, -0.05, 0.05], [-0.14, -0.05, 0.05], [-0.15, -0.05, 0.05]], -0.06), zc, rot, color, cx);
5869
- strip(K2, sh0([[0, -0.05, 0.05], [-0.14, -0.05, 0.05], [-0.15, -0.05, 0.05]], 0.06), zc, rot, sh(color, 0.9), cx);
6147
+ strip(K2, sh0([[0, -0.05, 0.05], [-0.14, -0.05, 0.05], [-0.15, -0.05, 0.05]], -0.06), zc, rot, color2, cx);
6148
+ strip(K2, sh0([[0, -0.05, 0.05], [-0.14, -0.05, 0.05], [-0.15, -0.05, 0.05]], 0.06), zc, rot, sh(color2, 0.9), cx);
5870
6149
  }
5871
6150
  K2.b("plain", cx - 0.05, ly - 0.02, zc, 0.018, 0.05, 0.016, 15261896);
5872
6151
  K2.b("plain", cx + 0.05, ly - 0.02, zc, 0.018, 0.05, 0.016, 13125690);
@@ -5900,7 +6179,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5900
6179
  (shared.ctx.clotheslines || (shared.ctx.clotheslines = [])).push(M.seed);
5901
6180
  };
5902
6181
  FURNITURE.water_tank = function(M, A) {
5903
- const K2 = kit2(M, A), w = M.w || 1, d = M.d || 1, onGround = !M.onSlab && (M.y || 0) < 0.5, color = M.palette && M.palette.tank_water != null ? M.palette.tank_water : 3107496, r = Math.min(w, d) * 0.46, rc = 11841700;
6182
+ 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;
5904
6183
  let y0 = 0;
5905
6184
  if (onGround) {
5906
6185
  for (const sx of [-1, 1]) for (const sz of [-1, 1]) K2.b("plain", sx * (w / 2 - 0.08), 0, sz * (d / 2 - 0.08), 0.14, 1, 0.14, rc);
@@ -5912,10 +6191,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5912
6191
  }
5913
6192
  const H = Math.max(0.7, (M.h || 1.8) - (onGround ? 1.12 : 0.1) - 0), th = Math.min(0.95, H * 0.88);
5914
6193
  K2.part("water_tank", 0, y0, 0, () => {
5915
- K2.c("plain", 0, y0, 0, r, th, color);
5916
- for (const f of [0.18, 0.5, 0.82]) K2.c("plain", 0, y0 + th * f - 0.025, 0, r * 1.028, 0.05, sh(color, 0.88));
5917
- K2.e("plain", 0, y0 + th + 0.03, 0, r * 1, 0.16, sh(color, 0.95));
5918
- K2.c("plain", 0, y0 + th + 0.09, 0, r * 0.5, 0.05, sh(color, 0.8));
6194
+ K2.c("plain", 0, y0, 0, r, th, color2);
6195
+ for (const f of [0.18, 0.5, 0.82]) K2.c("plain", 0, y0 + th * f - 0.025, 0, r * 1.028, 0.05, sh(color2, 0.88));
6196
+ K2.e("plain", 0, y0 + th + 0.03, 0, r * 1, 0.16, sh(color2, 0.95));
6197
+ K2.c("plain", 0, y0 + th + 0.09, 0, r * 0.5, 0.05, sh(color2, 0.8));
5919
6198
  K2.c("plain", 0, y0 + th + 0.14, 0, r * 0.18, 0.035, 1916262);
5920
6199
  }, { id: "tank_" + M.seed, breakable: true, fluid: "water", volume: Math.PI * r * r * th, radius: r, height: th });
5921
6200
  K2.t("metal", [r * 0.7, y0 + th * 0.25, 0], [r * 0.7, y0 + 0.03, 0], 0.02, 3159096);
@@ -5924,13 +6203,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5924
6203
  K2.t("metal", [-r * 0.5, y0 + th + 0.35, 0], [-r * 0.2, y0 + th + 0.35, 0], 0.014, 2763306);
5925
6204
  };
5926
6205
  FURNITURE.cooking_gas_cylinder = function(M, A) {
5927
- const K2 = kit2(M, A), r = Math.min(M.w || 0.36, M.d || 0.36) / 2, H = M.h || 0.47, color = 4157096, scale = sh(color, 0.7), brass = 13214282, c = Math.cos(M.ry || 0), s = Math.sin(M.ry || 0);
6206
+ const K2 = kit2(M, A), r = Math.min(M.w || 0.36, M.d || 0.36) / 2, H = M.h || 0.47, color2 = 4157096, scale = sh(color2, 0.7), brass = 13214282, c = Math.cos(M.ry || 0), s = Math.sin(M.ry || 0);
5928
6207
  K2.part("gas_cylinder", 0, 0, 0, () => {
5929
6208
  K2.c("plain", 0, 0, 0, r * 0.88, 0.05, scale);
5930
- K2.c("plain", 0, 0.04, 0, r, H * 0.5, color);
5931
- K2.e("plain", 0, 0.04 + H * 0.5, 0, r * 0.99, 0.08, sh(color, 0.9));
6209
+ K2.c("plain", 0, 0.04, 0, r, H * 0.5, color2);
6210
+ K2.e("plain", 0, 0.04 + H * 0.5, 0, r * 0.99, 0.08, sh(color2, 0.9));
5932
6211
  K2.c("plain", 0, H * 0.5 + 0.04, 0, r * 1.012, 0.018, scale);
5933
- K2.e("plain", 0, H * 0.77, 0, r * 0.98, H * 0.36, color);
6212
+ K2.e("plain", 0, H * 0.77, 0, r * 0.98, H * 0.36, color2);
5934
6213
  K2.c("metal", 0, H * 0.86, 0, 0.05, 0.05, 9080466);
5935
6214
  for (let k = 0; k < 3; k++) {
5936
6215
  const a = k * 2.0944 + 0.5, x = Math.cos(a) * r * 0.62, z = Math.sin(a) * r * 0.62;
@@ -5989,8 +6268,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
5989
6268
  function extraTypes(T2, props) {
5990
6269
  const origCar = T2.garage_car;
5991
6270
  const car = (M, A) => {
5992
- const structure = STYLE(), list = CAR_BY_STYLE[structure] || CAR_BY_STYLE.mid, r = rngString(SEED() + "|" + (seedKey(M.seed) || M.id || "") + "|" + Math.round((M.x || 0) * 10) + "|" + Math.round((M.z || 0) * 10) + "|carro");
5993
- const k = list[Math.floor(r() * list.length)], paint = 1 + Math.floor(r() * 8);
6271
+ const structure = STYLE(), list2 = CAR_BY_STYLE[structure] || CAR_BY_STYLE.mid, r = rngString(SEED() + "|" + (seedKey(M.seed) || M.id || "") + "|" + Math.round((M.x || 0) * 10) + "|" + Math.round((M.z || 0) * 10) + "|carro");
6272
+ const k = list2[Math.floor(r() * list2.length)], paint = 1 + Math.floor(r() * 8);
5994
6273
  if (!carModel(k, paint)) {
5995
6274
  if (origCar) origCar.f(M, A);
5996
6275
  return;
@@ -6050,14 +6329,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
6050
6329
  const vegItem = (...a) => K.vegItem(...a);
6051
6330
  function houseItems() {
6052
6331
  const R = shared.ctx.r, T2 = shared.ctx.types, api = makeApi(), noModel = /* @__PURE__ */ new Map();
6053
- const list = R.items.concat(R.stateItems.filter((e) => e.w != null && e.d != null && e.type !== "razor_wire" && e.type !== "barbed_wire"));
6332
+ const list2 = R.items.concat(R.stateItems.filter((e) => e.w != null && e.d != null && e.type !== "razor_wire" && e.type !== "barbed_wire"));
6054
6333
  const rect = (poly) => {
6055
6334
  let a = 0;
6056
6335
  for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) a += poly[j][0] * poly[i][1] - poly[i][0] * poly[j][1];
6057
6336
  const xs = poly.map((p) => p[0]), zs = poly.map((p) => p[1]);
6058
6337
  return Math.abs(a) / 2 > 0.98 * (Math.max(...xs) - Math.min(...xs)) * (Math.max(...zs) - Math.min(...zs));
6059
6338
  };
6060
- for (const m of list) {
6339
+ for (const m of list2) {
6061
6340
  if (m.type === "stairs") continue;
6062
6341
  const exterior = m.outdoor || m.floor < 0, f = exterior ? -1 : Math.min(m.floor, R.floors.length - 1);
6063
6342
  cursor.group = exterior ? "lot" : "f" + f;
@@ -6111,19 +6390,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
6111
6390
  const base = lc ? cd.platform.topY : cd.y + (shared.ctx.r.rooms.some((c) => c.id === cd.room && c.type === "terrace") ? 0 : 0.2 + (slab ? 0.03 : 0));
6112
6391
  cursor.group = slab ? "f" + f : "attic_tank";
6113
6392
  if (lc) {
6114
- const P = cd.platform, [x0, z0, x1, z1] = P.aabb, e = P.thickness, color = shared.ctx.colors.slab != null ? shared.ctx.colors.slab : 12170668;
6393
+ const P = cd.platform, [x0, z0, x1, z1] = P.aabb, e = P.thickness, color2 = shared.ctx.colors.slab != null ? shared.ctx.colors.slab : 12170668;
6115
6394
  cursor.pc = structurePiece("tank_slab");
6116
- boxC("plain", (x0 + x1) / 2, P.topY - e / 2, (z0 + z1) / 2, x1 - x0, e, z1 - z0, color, 0, 0, 0);
6395
+ boxC("plain", (x0 + x1) / 2, P.topY - e / 2, (z0 + z1) / 2, x1 - x0, e, z1 - z0, color2, 0, 0, 0);
6117
6396
  P.pillars.forEach((p, k) => {
6118
6397
  cursor.pc = structurePiece("tank_column_" + k);
6119
- boxC("plain", p.u, (P.baseY + P.topY - e) / 2, p.v, p.side, P.topY - e - P.baseY, p.side, color, 0, 0, 0);
6398
+ boxC("plain", p.u, (P.baseY + P.topY - e) / 2, p.v, p.side, P.topY - e - P.baseY, p.side, color2, 0, 0, 0);
6120
6399
  });
6121
6400
  cursor.pc = null;
6122
6401
  }
6123
6402
  if (!slab) {
6124
- const color = shared.ctx.colors.slab != null ? shared.ctx.colors.slab : 12170668, yp = Y0(f), hw = cd.w / 2 + 0.1, hd = cd.d / 2 + 0.1;
6125
- boxC("plain", cd.u, base - 0.06, cd.v, hw * 2, 0.12, hd * 2, color);
6126
- 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, color);
6403
+ const color2 = shared.ctx.colors.slab != null ? shared.ctx.colors.slab : 12170668, yp = Y0(f), hw = cd.w / 2 + 0.1, hd = cd.d / 2 + 0.1;
6404
+ boxC("plain", cd.u, base - 0.06, cd.v, hw * 2, 0.12, hd * 2, color2);
6405
+ 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);
6127
6406
  }
6128
6407
  const M = { x: cd.u, z: cd.v, ry: 0, w: cd.w, d: cd.d, h: cd.h + 0.12, y: 0, base, floor: f, colors: shared.ctx.colors, seed: "water_tank", room: cd.room, onSlab: true, ceiling: 2.9 };
6129
6408
  shared.ctx.waterTankPos = { x: cd.u, z: cd.v, y: base, group: cursor.group };
@@ -6135,8 +6414,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
6135
6414
  return _col.setHSL((h >>> 0) % 360 / 360, 0.45, 0.55).getHex();
6136
6415
  }
6137
6416
  function labeledBox(m, M, group) {
6138
- const color = M.color != null ? M.color : hashColor(m.category || m.type), h = Math.max(0.05, m.h || 0.5);
6139
- boxC("plain", m.x, M.base + (m.y || 0) + h / 2, m.z, m.w, h, m.d, color, 0, m.ry || 0, 0);
6417
+ const color2 = M.color != null ? M.color : hashColor(m.category || m.type), h = Math.max(0.05, m.h || 0.5);
6418
+ boxC("plain", m.x, M.base + (m.y || 0) + h / 2, m.z, m.w, h, m.d, color2, 0, m.ry || 0, 0);
6140
6419
  shared.ctx.labels.push({ pos: new THREE.Vector3(m.x, M.base + (m.y || 0) + h + 0.15, m.z), text: m.type, group, type: "no_model" });
6141
6420
  }
6142
6421
  Object.assign(K, { houseItems, waterTankOfHouse, hashColor, labeledBox });
@@ -6650,10 +6929,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
6650
6929
  if (!lt) return;
6651
6930
  const cz0 = (lt.rect[1] + lt.rect[3]) / 2;
6652
6931
  const orig = K.getBx(), gs = lt.gates, opening = gs.map((g) => g.open), reg = gs.map((g) => {
6653
- const color = g.model === "sliding", dx = color ? slideDirection(g, lt) : 0, a = g.u - g.width / 2, b = g.u + g.width / 2, zc = g.v + (cz0 - g.v >= 0 ? 1 : -1) * 0.19;
6654
- return { g, a, b, v: g.v, x0: Infinity, x1: -Infinity, y1: 0, color, dx, zc, lo: color ? dx > 0 ? a + 0.04 : a - 0.9 : a + 0.05, hi: color ? dx > 0 ? b + 0.9 + 0.01 : b - 0.04 : b + 0.01, zv: color ? 0.07 : 0.04, zm: color ? zc : g.v };
6932
+ const color2 = g.model === "sliding", dx = color2 ? slideDirection(g, lt) : 0, a = g.u - g.width / 2, b = g.u + g.width / 2, zc = g.v + (cz0 - g.v >= 0 ? 1 : -1) * 0.19;
6933
+ return { g, a, b, v: g.v, x0: Infinity, x1: -Infinity, y1: 0, color: color2, dx, zc, lo: color2 ? dx > 0 ? a + 0.04 : a - 0.9 : a + 0.05, hi: color2 ? dx > 0 ? b + 0.9 + 0.01 : b - 0.04 : b + 0.01, zv: color2 ? 0.07 : 0.04, zm: color2 ? zc : g.v };
6655
6934
  });
6656
- K.setBx(function(mat, x0, y0, z0, x1, y1, z1, color) {
6935
+ K.setBx(function(mat, x0, y0, z0, x1, y1, z1, color2) {
6657
6936
  if (mat === "metal") {
6658
6937
  for (const r of reg) if (r.g.axis === "u" && x0 >= r.lo && x1 <= r.hi && z0 >= r.zm - r.zv && z1 <= r.zm + r.zv && y0 >= 0.03) {
6659
6938
  r.x0 = Math.min(r.x0, x0);
@@ -6661,12 +6940,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
6661
6940
  r.y1 = Math.max(r.y1, y1);
6662
6941
  const g0 = cursor.group;
6663
6942
  cursor.group = "ix:gate:" + r.g.id;
6664
- orig(mat, x0, y0, z0, x1, y1, z1, color);
6943
+ orig(mat, x0, y0, z0, x1, y1, z1, color2);
6665
6944
  cursor.group = g0;
6666
6945
  return;
6667
6946
  }
6668
6947
  }
6669
- return orig(mat, x0, y0, z0, x1, y1, z1, color);
6948
+ return orig(mat, x0, y0, z0, x1, y1, z1, color2);
6670
6949
  });
6671
6950
  const n0 = shared.ctx.colliders.length;
6672
6951
  try {
@@ -6741,10 +7020,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
6741
7020
  else bx("plain", Math.min(f2, f3), yc - 0.032, u - 0.016, Math.max(f2, f3), yc + 0.032, u + 0.016, 16250092);
6742
7021
  cursor.group = g0;
6743
7022
  const pv = alongU ? [u, yc, f2] : [f2, yc, u];
6744
- const piece = definePiece("ix:int:" + roomId, { kind: "light_switch", pivot: pv, ry: 0, parent: "f" + f, axis: alongU ? "x" : "z", sgn: alongU ? sd : -sd, t0: lightOn(roomId) ? 1 : 0 });
6745
- piece.t = piece.target = lightOn(roomId) ? 1 : 0;
7023
+ const piece2 = definePiece("ix:int:" + roomId, { kind: "light_switch", pivot: pv, ry: 0, parent: "f" + f, axis: alongU ? "x" : "z", sgn: alongU ? sd : -sd, t0: lightOn(roomId) ? 1 : 0 });
7024
+ piece2.t = piece2.target = lightOn(roomId) ? 1 : 0;
6746
7025
  const an = alongU ? [u, yc, face + sd * 0.12] : [face + sd * 0.12, yc, u];
6747
- shared.inter.items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [piece], text: () => t(lightOn(roomId) ? "prompt.lightOff" : "prompt.lightOn"), action: () => toggleLight(roomId) });
7026
+ shared.inter.items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [piece2], text: () => t(lightOn(roomId) ? "prompt.lightOff" : "prompt.lightOn"), action: () => toggleLight(roomId) });
6748
7027
  return true;
6749
7028
  }
6750
7029
  return false;
@@ -6914,11 +7193,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
6914
7193
  const IV_WIRE = { conduit: 13618628, cable: 2762532, drop: 1381653, cord: 1776413, earth: 3111482, hose: 11556124 };
6915
7194
  const IV_DOOR = /^(door|drawer)/;
6916
7195
  const ivGroup = (e) => e.floor < 0 ? "lot" : "f" + Math.min(e.floor, shared.ctx.r.floors.length - 1);
6917
- function ivAccumulate(mat, g, ox, oy, oz, ry, color) {
6918
- const P = g.attributes.position, N = g.attributes.normal, C = color == null ? g.attributes.color : null, U = g.attributes.uv, I = g.index, nv = P.count, ni = I ? I.count : nv;
7196
+ function ivAccumulate(mat, g, ox, oy, oz, ry, color2) {
7197
+ 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;
6919
7198
  const A = accFor(mat);
6920
7199
  A.ensure(nv, ni);
6921
- const c = Math.cos(ry), s = Math.sin(ry), b = A.nv, rgb = color != null ? rgbOf(color) : [1, 1, 1];
7200
+ const c = Math.cos(ry), s = Math.sin(ry), b = A.nv, rgb = color2 != null ? rgbOf(color2) : [1, 1, 1];
6922
7201
  for (let k = 0; k < nv; k++) {
6923
7202
  const x = P.getX(k), y = P.getY(k), z = P.getZ(k), o = b + k;
6924
7203
  A.p[o * 3] = x * c + z * s + ox;
@@ -6959,14 +7238,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
6959
7238
  function ivBuild(h, water) {
6960
7239
  const ik = K.IVK, r = shared.ctx.r, A = ik.A, world0 = null;
6961
7240
  void world0;
6962
- const plane = A.plan(r, { seed: r.seed });
6963
- const IV = { k: ik, plane, world: null, water, entries: /* @__PURE__ */ new Map(), roots: [], replace: /* @__PURE__ */ new Set(), roomStates: /* @__PURE__ */ new Map(), lampRoom: /* @__PURE__ */ new Map(), anim: /* @__PURE__ */ new Map(), screens: /* @__PURE__ */ new Map(), efx: null, items: null, itemsDirty: true, itemsT: 0, dirty: true, list: null, listT: 0, t: 0, circuits: [], switchRooms: /* @__PURE__ */ new Set(), warnings: [], tBuild: 0 };
7241
+ const plane2 = A.plan(r, { seed: r.seed });
7242
+ const IV = { k: ik, plane: plane2, world: null, water, entries: /* @__PURE__ */ new Map(), roots: [], replace: /* @__PURE__ */ new Set(), roomStates: /* @__PURE__ */ new Map(), lampRoom: /* @__PURE__ */ new Map(), anim: /* @__PURE__ */ new Map(), screens: /* @__PURE__ */ new Map(), efx: null, items: null, itemsDirty: true, itemsT: 0, dirty: true, list: null, listT: 0, t: 0, circuits: [], switchRooms: /* @__PURE__ */ new Set(), warnings: [], tBuild: 0 };
6964
7243
  h.IV = IV;
6965
7244
  const t0 = performance.now();
6966
- const lamps = new Set(plane.items.filter((e) => e.type === "lamp").map((e) => e.id));
6967
- for (const id of plane.mapped) if (!lamps.has(id)) IV.replace.add(id);
7245
+ const lamps = new Set(plane2.items.filter((e) => e.type === "lamp").map((e) => e.id));
7246
+ for (const id of plane2.mapped) if (!lamps.has(id)) IV.replace.add(id);
6968
7247
  const furnitureById = new Map(r.items.map((m) => [m.id, m]));
6969
- for (const e of plane.items) {
7248
+ for (const e of plane2.items) {
6970
7249
  if (e.type !== "lamp") continue;
6971
7250
  const m = furnitureById.get(e.id);
6972
7251
  if (!m || !LIGHT_TYPES.has(m.type) || !m.room) continue;
@@ -6976,8 +7255,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
6976
7255
  IV.lampRoom.set(e.id, m.room);
6977
7256
  }
6978
7257
  const wants = (roomId) => lightBase(roomId);
6979
- const entById = new Map(plane.items.map((e) => [e.id, e]));
6980
- const entByItem = new Map(plane.items.map((e) => [e.item, e]));
7258
+ const entById = new Map(plane2.items.map((e) => [e.id, e]));
7259
+ const entByItem = new Map(plane2.items.map((e) => [e.item, e]));
6981
7260
  IV.mats = { plain: shared.mats.plain, metal: shared.mats.metal, wood: shared.mats.wood, glass: shared.mats.glass, fabric: shared.mats.fabric, plant: shared.mats.plant, water: shared.mats.water, emissive: shared.mats.emissive, atlas_picture: shared.mats.picture, atlas_floor: shared.mats.floor };
6982
7261
  const ev = (e) => ivEvent(h, e);
6983
7262
  const world = IV.world = A.createWorld(r, { water, seed: r.seed, onEvent: ev });
@@ -6997,7 +7276,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
6997
7276
  }
6998
7277
  return add0(id, spec, tr);
6999
7278
  };
7000
- const added = A.add(world, plane, { isBlocked: A.blockedOf(r), build: (type, item) => ivDraw(IV, entByItem.get(item), type, item) });
7279
+ const added = A.add(world, plane2, { isBlocked: A.blockedOf(r), build: (type, item) => ivDraw(IV, entByItem.get(item), type, item) });
7001
7280
  world.add = add0;
7002
7281
  IV.warnings = added.warnings;
7003
7282
  IV.added = added;
@@ -7023,7 +7302,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7023
7302
  console.warn("interactables: state", err);
7024
7303
  }
7025
7304
  }
7026
- for (const e of plane.items) if (e.type === "wall_switch") for (const l of e.connections.controls || []) {
7305
+ for (const e of plane2.items) if (e.type === "wall_switch") for (const l of e.connections.controls || []) {
7027
7306
  const roomId = IV.lampRoom.get(l);
7028
7307
  if (roomId) {
7029
7308
  IV.switchRooms.add(roomId);
@@ -7102,10 +7381,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7102
7381
  }
7103
7382
  function ivCords(IV) {
7104
7383
  const ik = IV.k, w = IV.world, wl = (o, p) => ik.GI.localToWorld(o.transform, p), g0 = cursor.group;
7105
- const tube = (pts, radius, color, ox, oy, oz, ry) => {
7384
+ const tube = (pts, radius, color2, ox, oy, oz, ry) => {
7106
7385
  try {
7107
7386
  const m = ik.gfx.createCord(pts, radius, shared.mats.plain);
7108
- ivAccumulate("plain", m.geometry, ox, oy, oz, ry, color);
7387
+ ivAccumulate("plain", m.geometry, ox, oy, oz, ry, color2);
7109
7388
  m.geometry.dispose();
7110
7389
  } catch (e) {
7111
7390
  }
@@ -7288,7 +7567,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7288
7567
  function ivItems(IV, h) {
7289
7568
  IV.itemsDirty = false;
7290
7569
  IV.itemsT = IV.t;
7291
- const w = IV.world, items = IV.k.A.household.items, f = IV.focus, g0 = cursor.group, list = [];
7570
+ const w = IV.world, items = IV.k.A.household.items, f = IV.focus, g0 = cursor.group, list2 = [];
7292
7571
  let fl = null;
7293
7572
  if (f) {
7294
7573
  h.houseGroup.updateWorldMatrix(true, false);
@@ -7302,23 +7581,23 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7302
7581
  if (c.access && w.partT(E.id, c.access) < 0.02) continue;
7303
7582
  const st = w.contents(E.id, c.id);
7304
7583
  for (let i = 0; i < st.length; i++) {
7305
- if (st[i] && items[st[i].type]) list.push([E, c.id, i, items[st[i].type]]);
7584
+ if (st[i] && items[st[i].type]) list2.push([E, c.id, i, items[st[i].type]]);
7306
7585
  }
7307
7586
  }
7308
7587
  }
7309
- if (!list.length) {
7588
+ if (!list2.length) {
7310
7589
  if (IV.items) IV.items.visible = false;
7311
7590
  return;
7312
7591
  }
7313
7592
  cursor.group = "iv-items";
7314
7593
  try {
7315
- for (const [E, cid, slot, def] of list) {
7594
+ for (const [E, cid, slot, def] of list2) {
7316
7595
  const p = w.slotPosition(E.id, cid, slot), form = IV_SHAPE[def.shape] || IV_SHAPE.box;
7317
7596
  for (const [geo, fx, fy, fz, y0, tone] of form) {
7318
7597
  const sx = def.size[0] * fx, sy = def.size[1] * fy, sz = def.size[2] * fz;
7319
7598
  _q.setFromAxisAngle(_Y, E.ry);
7320
- const color = def.color == null ? 13421772 : def.color;
7321
- put("plain", geo, p[0], p[1] + def.size[1] * y0 + sy / 2, p[2], _q, sx, sy, sz, tone === 1 ? color : sh(color, tone));
7599
+ const color2 = def.color == null ? 13421772 : def.color;
7600
+ put("plain", geo, p[0], p[1] + def.size[1] * y0 + sy / 2, p[2], _q, sx, sy, sz, tone === 1 ? color2 : sh(color2, tone));
7322
7601
  }
7323
7602
  }
7324
7603
  const A = cursor.accs.get("iv-items|plain");
@@ -7443,7 +7722,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7443
7722
  })),
7444
7723
  seatInfo: () => ivSeat(IV),
7445
7724
  // {object, seat, pose: 'sit'|'lie', eye, yaw, pitch, exit, floor} if the player is sitting/lying
7446
- sit: com((object, seatInfo) => !!w.sit(object, seatInfo, "player")),
7725
+ sit: com((object2, seatInfo) => !!w.sit(object2, seatInfo, "player")),
7447
7726
  stand: com(() => w.stand("player")),
7448
7727
  opens: com((mid, target) => {
7449
7728
  for (const E of IV.entries.values()) if (E.origin === mid) {
@@ -8091,10 +8370,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
8091
8370
  const f = (res.floors || []).find((x) => x.index === floor);
8092
8371
  return r3(o.base + (f ? f.y0 : 0));
8093
8372
  }
8094
- function colorOf(res, color) {
8095
- if (color == null) return void 0;
8096
- if (typeof color === "number") return color;
8097
- const v = res.colors && res.colors[color];
8373
+ function colorOf(res, color2) {
8374
+ if (color2 == null) return void 0;
8375
+ if (typeof color2 === "number") return color2;
8376
+ const v = res.colors && res.colors[color2];
8098
8377
  return typeof v === "number" ? v : void 0;
8099
8378
  }
8100
8379
  function paletteOf(res) {
@@ -8237,8 +8516,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
8237
8516
  seed: seedOf2(m.id),
8238
8517
  palette
8239
8518
  };
8240
- const color = colorOf(res, m.color);
8241
- if (color != null) item.color = color;
8519
+ const color2 = colorOf(res, m.color);
8520
+ if (color2 != null) item.color = color2;
8242
8521
  return item;
8243
8522
  }
8244
8523
  function entry2(id, type, item, origin, floor, extra) {
@@ -8385,17 +8664,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
8385
8664
  item.seed = seedOf2(id);
8386
8665
  return entry2(id, type, item, m.id, m.floor);
8387
8666
  };
8388
- const list = [];
8667
+ const list2 = [];
8389
8668
  const overhead = contents[m.id + "#overhead"];
8390
8669
  if (kind === "rustic_sink") {
8391
8670
  const dd = Math.max(m.d, 0.56);
8392
8671
  const basin = part(m.id, "sink_kitchen", m.w, dd, m.h + 0.3, 0, 0, -(dd - m.d) / 2);
8393
- list.push(basin);
8672
+ list2.push(basin);
8394
8673
  const over = overhead || [];
8395
8674
  if (m.overhead !== false && over.length) {
8396
8675
  const wall = part(m.id + "#overhead", "kitchen_cabinet_wall", m.w, 0.35, 0.6, 1.55, 0, -(m.d / 2) + 0.175);
8397
8676
  store([["kitchen_cabinet_wall", wall.item]], over);
8398
- list.push(wall);
8677
+ list2.push(wall);
8399
8678
  }
8400
8679
  if (contents[m.id]) store([["sink_kitchen", basin.item]], contents[m.id]);
8401
8680
  if (m.outlet) basin.connections.outlet = m.outlet;
@@ -8405,33 +8684,33 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
8405
8684
  const rest = r3(width - basinW);
8406
8685
  const left = seedOf2(m.id) % 2 === 0;
8407
8686
  const sink = part(m.id, "sink_kitchen", basinW, m.d, m.h + 0.25, 0, left ? -(width / 2) + basinW / 2 : width / 2 - basinW / 2, 0);
8408
- list.push(sink);
8687
+ list2.push(sink);
8409
8688
  let cabinet = null;
8410
8689
  if (rest >= 0.35) {
8411
8690
  cabinet = part(m.id + "#cabinet", "kitchen_cabinet_base", rest, m.d, m.h, 0, left ? width / 2 - rest / 2 : -(width / 2) + rest / 2, 0);
8412
- list.push(cabinet);
8691
+ list2.push(cabinet);
8413
8692
  }
8414
8693
  if (contents[m.id]) store(cabinet ? [["kitchen_cabinet_base", cabinet.item], ["sink_kitchen", sink.item]] : [["sink_kitchen", sink.item]], contents[m.id]);
8415
8694
  if (m.overhead !== false) {
8416
8695
  const wall = part(m.id + "#overhead", "kitchen_cabinet_wall", width, 0.35, 0.6, 1.55, 0, -(m.d / 2) + 0.175);
8417
8696
  store([["kitchen_cabinet_wall", wall.item]], overhead || []);
8418
- list.push(wall);
8697
+ list2.push(wall);
8419
8698
  }
8420
8699
  if (m.outlet) sink.connections.outlet = m.outlet;
8421
8700
  } else {
8422
8701
  const basin = part(m.id, "sink_bathroom", m.w, m.d, m.h + 0.2, 0, 0, 0);
8423
- list.push(basin);
8702
+ list2.push(basin);
8424
8703
  if (contents[m.id]) {
8425
8704
  if (contents[m.id].length) {
8426
8705
  const cabinet = part(m.id + "#cabinet", "bathroom_cabinet", Math.max(0.45, Math.min(0.6, m.w)), 0.15, 0.75, 1.3, 0, -(m.d / 2) + 0.075);
8427
- list.push(cabinet);
8706
+ list2.push(cabinet);
8428
8707
  store([["bathroom_cabinet", cabinet.item], ["sink_bathroom", basin.item]], contents[m.id]);
8429
8708
  } else {
8430
8709
  store([["sink_bathroom", basin.item]], []);
8431
8710
  }
8432
8711
  }
8433
8712
  }
8434
- for (const e of list) push(e);
8713
+ for (const e of list2) push(e);
8435
8714
  }
8436
8715
  function circuitOfLight(id) {
8437
8716
  const direct = circuits.find((c) => (c.lamps || []).indexOf(id) >= 0);
@@ -8755,9 +9034,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
8755
9034
  }
8756
9035
  return function blocked(x, z, floor) {
8757
9036
  const a = floor == null || floor < 0 ? 0 : floor;
8758
- const list = grid.get(key(a, Math.floor(x / CELL2), Math.floor(z / CELL2)));
8759
- if (!list) return false;
8760
- for (const s of list) if (x > s.x0 && x < s.x1 && z > s.z0 && z < s.z1) return true;
9037
+ const list2 = grid.get(key(a, Math.floor(x / CELL2), Math.floor(z / CELL2)));
9038
+ if (!list2) return false;
9039
+ for (const s of list2) if (x > s.x0 && x < s.x1 && z > s.z0 && z < s.z1) return true;
8761
9040
  return false;
8762
9041
  };
8763
9042
  }
@@ -8975,13 +9254,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
8975
9254
  }
8976
9255
  for (const g of by.values()) {
8977
9256
  const ls = g.ls, n = ls.length;
8978
- let cx = 0, cy = 0, cz = 0, range = 0;
9257
+ let cx = 0, cy = 0, cz = 0, range2 = 0;
8979
9258
  for (const l of ls) {
8980
9259
  _p.set(l.x, l.y, l.z).applyMatrix4(M);
8981
9260
  cx += _p.x;
8982
9261
  cy += _p.y;
8983
9262
  cz += _p.z;
8984
- range = Math.max(range, l.range || 5);
9263
+ range2 = Math.max(range2, l.range || 5);
8985
9264
  }
8986
9265
  cx /= n;
8987
9266
  cy /= n;
@@ -8989,7 +9268,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
8989
9268
  g.pos = [cx, cy, cz];
8990
9269
  g.color = ls[0].color;
8991
9270
  g.n = n;
8992
- g.range = range;
9271
+ g.range = range2;
8993
9272
  if (g.exterior) {
8994
9273
  g.rects = [[cx - 7, cz - 7, cx + 7, cz + 7]];
8995
9274
  g.y = [cy - 3.2, cy + 4];
@@ -10262,8 +10541,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10262
10541
  const resting = /* @__PURE__ */ new Map();
10263
10542
  const carrying = /* @__PURE__ */ new Map();
10264
10543
  const push = (map, key, value) => {
10265
- const list = map.get(key);
10266
- if (list) list.push(value);
10544
+ const list2 = map.get(key);
10545
+ if (list2) list2.push(value);
10267
10546
  else map.set(key, [value]);
10268
10547
  };
10269
10548
  for (const support of supports) {
@@ -10319,7 +10598,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10319
10598
  if (!splits.size) return input;
10320
10599
  const boxes = new Map(input.parts.map((part) => [part.id, part.aabb]));
10321
10600
  const pieceBox = /* @__PURE__ */ new Map();
10322
- for (const split of splits.values()) for (const piece of split.pieces) pieceBox.set(piece.id, piece.aabb);
10601
+ for (const split of splits.values()) for (const piece2 of split.pieces) pieceBox.set(piece2.id, piece2.aabb);
10323
10602
  const parts = input.parts.flatMap((part) => splits.get(part.id)?.pieces ?? [part]);
10324
10603
  const supports = [];
10325
10604
  for (const support of input.supports) {
@@ -10367,12 +10646,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10367
10646
  for (const [a, b] of cutAt(from, to, openings.filter((o) => o.wall === wall.id), y0, y1)) for (const [x0, x1] of unitsOf(a, b, row, spec)) cells.push({ from: x0, to: x1, row, y0, y1 });
10368
10647
  }
10369
10648
  const total = cells.reduce((sum, cell) => sum + (cell.to - cell.from) * (cell.y1 - cell.y0), 0);
10370
- const box = (cell) => alongU ? [cell.from, cross[0], cell.to, cross[1]] : [cross[0], cell.from, cross[1], cell.to];
10649
+ const box2 = (cell) => alongU ? [cell.from, cross[0], cell.to, cross[1]] : [cross[0], cell.from, cross[1], cell.to];
10371
10650
  const pieces = cells.map((cell, index) => ({
10372
10651
  id: `${wall.id}_${spec.unitLength ? "u" : "log"}${cell.row}_${index}`,
10373
10652
  role: wall.role,
10374
10653
  material: wall.material,
10375
- aabb: box(cell),
10654
+ aabb: box2(cell),
10376
10655
  y0: cell.y0,
10377
10656
  y1: cell.y1,
10378
10657
  floor: wall.floor,
@@ -10498,9 +10777,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10498
10777
  const capacity = input.capacities.get(id);
10499
10778
  capacities.delete(id);
10500
10779
  if (capacity === void 0) continue;
10501
- const along = (box) => Math.max(box[2] - box[0], box[3] - box[1]);
10780
+ const along = (box2) => Math.max(box2[2] - box2[0], box2[3] - box2[1]);
10502
10781
  const length = along(input.parts.find((part) => part.id === id).aabb);
10503
- for (const piece of split.pieces) capacities.set(piece.id, Math.max(1, capacity * along(piece.aabb) / length));
10782
+ for (const piece2 of split.pieces) capacities.set(piece2.id, Math.max(1, capacity * along(piece2.aabb) / length));
10504
10783
  }
10505
10784
  return { ...next, capacities };
10506
10785
  }
@@ -10777,7 +11056,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10777
11056
  const per = Math.max(1, Math.round(len / ul));
10778
11057
  const w = len / per;
10779
11058
  const edge = fragmentMaterial(part.material).color.getHex();
10780
- const list = [];
11059
+ const list2 = [];
10781
11060
  for (let r = 0; r < rows; r++) {
10782
11061
  const shift = units.bond === "running" && r & 1 ? w / 2 : 0;
10783
11062
  const cells = per + (shift ? 1 : 0);
@@ -10792,10 +11071,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10792
11071
  const y = part.y0 + (r + 0.5) * rowH;
10793
11072
  const d = Math.hypot(x - opening.center[0], y - opening.center[1], z - opening.center[2]);
10794
11073
  if (d < opening.radius) continue;
10795
- list.push({ x, y, z, sx: alongU ? b - a : thick, sy: rowH, sz: alongU ? thick : b - a, colour: d < opening.radius + 0.25 || paint === null ? edge : paint });
11074
+ list2.push({ x, y, z, sx: alongU ? b - a : thick, sy: rowH, sz: alongU ? thick : b - a, colour: d < opening.radius + 0.25 || paint === null ? edge : paint });
10796
11075
  }
10797
11076
  }
10798
- return list;
11077
+ return list2;
10799
11078
  }
10800
11079
  function open(event) {
10801
11080
  if (lod !== 0 || views.has(event.part) || !event.opening) return false;
@@ -10804,27 +11083,27 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10804
11083
  if (!part || !spec || !spec.units) return false;
10805
11084
  const items = structure.meshesOf(event.part).filter((it) => it.mesh);
10806
11085
  if (!items.length) return false;
10807
- const list = courses(part, spec.units, event.opening, wallColour(items));
10808
- const mesh = new THREE.InstancedMesh(unitGeometry, unitMaterial, Math.max(1, list.length));
11086
+ const list2 = courses(part, spec.units, event.opening, wallColour(items));
11087
+ const mesh = new THREE.InstancedMesh(unitGeometry, unitMaterial, Math.max(1, list2.length));
10809
11088
  mesh.name = "breach:" + event.part;
10810
- list.forEach((u, i) => {
11089
+ list2.forEach((u, i) => {
10811
11090
  tmp.m.compose(tmp.p.set(u.x, u.y, u.z), tmp.q.identity(), tmp.s.set(u.sx, u.sy, u.sz));
10812
11091
  mesh.setMatrixAt(i, tmp.m);
10813
11092
  mesh.setColorAt(i, tmp.c.setHex(u.colour));
10814
11093
  });
10815
- mesh.count = list.length;
11094
+ mesh.count = list2.length;
10816
11095
  mesh.instanceMatrix.needsUpdate = true;
10817
11096
  if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true;
10818
11097
  mesh.castShadow = true;
10819
11098
  mesh.receiveShadow = true;
10820
11099
  house.add(mesh);
10821
11100
  const saved = items.map((it) => ({ it, v0: it.v0, data: collapseRange(it.mesh, it.v0, it.v1) }));
10822
- views.set(event.part, { mesh, saved, units: list.length, opening: event.opening });
11101
+ views.set(event.part, { mesh, saved, units: list2.length, opening: event.opening });
10823
11102
  invalidate();
10824
11103
  invalidateShadow();
10825
11104
  return true;
10826
11105
  }
10827
- function plain(view, shown) {
11106
+ function plain2(view, shown) {
10828
11107
  for (const s of view.saved) {
10829
11108
  if (shown) restoreRange(s.it.mesh, s.v0, s.data);
10830
11109
  else s.data = collapseRange(s.it.mesh, s.v0, s.it.v1);
@@ -10850,7 +11129,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10850
11129
  if (was === 0 === (level === 0)) return;
10851
11130
  for (const v of views.values()) {
10852
11131
  v.mesh.visible = level === 0;
10853
- plain(v, level !== 0);
11132
+ plain2(v, level !== 0);
10854
11133
  }
10855
11134
  invalidate();
10856
11135
  invalidateShadow();
@@ -10860,7 +11139,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10860
11139
  for (const v of views.values()) {
10861
11140
  v.mesh.removeFromParent();
10862
11141
  v.mesh.dispose();
10863
- if (lod === 0) plain(v, true);
11142
+ if (lod === 0) plain2(v, true);
10864
11143
  }
10865
11144
  views.clear();
10866
11145
  },
@@ -10967,7 +11246,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10967
11246
  };
10968
11247
  D.dropPiece = (id) => {
10969
11248
  if (hiddenPieces.has(id) || bodies.has(id)) return;
10970
- const list = [], rr = rngString(id);
11249
+ const list2 = [], rr = rngString(id);
10971
11250
  for (const it of structure.meshesOf(id)) {
10972
11251
  if (it.obj) {
10973
11252
  hide(it);
@@ -10976,10 +11255,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10976
11255
  const m = extract(it);
10977
11256
  hide(it);
10978
11257
  const hy = (m.geometry.boundingBox.max.y - m.geometry.boundingBox.min.y) / 2;
10979
- list.push({ mesh: m, vy: 0, hy, y0: m.position.y, rot: 0, w: [(rr() - 0.5) * 0.5, (rr() - 0.5) * 0.3, (rr() - 0.5) * 0.5], landing: false });
11258
+ list2.push({ mesh: m, vy: 0, hy, y0: m.position.y, rot: 0, w: [(rr() - 0.5) * 0.5, (rr() - 0.5) * 0.3, (rr() - 0.5) * 0.5], landing: false });
10980
11259
  }
10981
11260
  hiddenPieces.add(id);
10982
- if (list.length) bodies.set(id, list);
11261
+ if (list2.length) bodies.set(id, list2);
10983
11262
  invalidate();
10984
11263
  invalidateShadow();
10985
11264
  };
@@ -11151,8 +11430,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
11151
11430
  D.animate = (dt) => {
11152
11431
  if (R) return;
11153
11432
  let moved = false;
11154
- for (const [id, list] of bodies) {
11155
- for (const b of list) {
11433
+ for (const [id, list2] of bodies) {
11434
+ for (const b of list2) {
11156
11435
  if (b.landing) continue;
11157
11436
  moved = true;
11158
11437
  b.vy -= 9.8 * dt;
@@ -11168,10 +11447,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
11168
11447
  b.landing = true;
11169
11448
  }
11170
11449
  }
11171
- if (!list.impacted && list.every((b) => b.landing)) {
11172
- list.impacted = true;
11450
+ if (!list2.impacted && list2.every((b) => b.landing)) {
11451
+ list2.impacted = true;
11173
11452
  const ps = D.active ? D.world.part(D.id, id) : null;
11174
- const b = list[0];
11453
+ const b = list2[0];
11175
11454
  if (ps && ps.status !== "broken") {
11176
11455
  const h = Math.max(0.5, b.y0 - b.hy), c = worldPoint(b.mesh.parent, b.mesh.position);
11177
11456
  D.world.hitPart(D.id, id, { type: "blunt", point: [c.x, c.y, c.z], energy: ps.mass * 9.8 * h, radius: 0.5, source: "fall" });
@@ -12102,20 +12381,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
12102
12381
  const g = c.grids[floor];
12103
12382
  if (!g) return 0;
12104
12383
  let x0, z0, x1, z1;
12105
- const circle = "circle" in shape ? shape.circle : null;
12106
- if (circle) {
12107
- x0 = circle[0] - circle[2];
12108
- z0 = circle[1] - circle[2];
12109
- x1 = circle[0] + circle[2];
12110
- z1 = circle[1] + circle[2];
12384
+ const circle2 = "circle" in shape ? shape.circle : null;
12385
+ if (circle2) {
12386
+ x0 = circle2[0] - circle2[2];
12387
+ z0 = circle2[1] - circle2[2];
12388
+ x1 = circle2[0] + circle2[2];
12389
+ z1 = circle2[1] + circle2[2];
12111
12390
  } else [x0, z0, x1, z1] = shape.rect;
12112
12391
  const i0 = Math.max(0, Math.ceil((Math.min(x0, x1) - c.ox) / CELL - 0.5)), i1 = Math.min(c.nx - 1, Math.floor((Math.max(x0, x1) - c.ox) / CELL - 0.5));
12113
12392
  const j0 = Math.max(0, Math.ceil((Math.min(z0, z1) - c.oz) / CELL - 0.5)), j1 = Math.min(c.nz - 1, Math.floor((Math.max(z0, z1) - c.oz) / CELL - 0.5));
12114
12393
  let n = 0;
12115
12394
  for (let j = j0; j <= j1; j++) for (let i = i0; i <= i1; i++) {
12116
- if (circle) {
12117
- const dx = c.ox + (i + 0.5) * CELL - circle[0], dz = c.oz + (j + 0.5) * CELL - circle[1];
12118
- if (dx * dx + dz * dz > circle[2] * circle[2]) continue;
12395
+ if (circle2) {
12396
+ const dx = c.ox + (i + 0.5) * CELL - circle2[0], dz = c.oz + (j + 0.5) * CELL - circle2[1];
12397
+ if (dx * dx + dz * dz > circle2[2] * circle2[2]) continue;
12119
12398
  }
12120
12399
  fn(g, j * c.nx + i);
12121
12400
  n++;
@@ -12352,11 +12631,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
12352
12631
  };
12353
12632
  const role = (p) => p.structure && p.structure.role;
12354
12633
  const events = (room) => {
12355
- const list = [];
12356
- room.world.on("*", (e) => list.push(e));
12357
- return list;
12634
+ const list2 = [];
12635
+ room.world.on("*", (e) => list2.push(e));
12636
+ return list2;
12358
12637
  };
12359
- const collapsed = (list) => list.filter((e) => e.type === "collapse").flatMap((e) => e.parts.map((p) => p.id || p));
12638
+ const collapsed = (list2) => list2.filter((e) => e.type === "collapse").flatMap((e) => e.parts.map((p) => p.id || p));
12360
12639
  const whole = (room, oid, pid) => {
12361
12640
  const p = room.world.part(oid, pid);
12362
12641
  return !!p && p.status !== "broken" && !p.stripped;
@@ -12375,14 +12654,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
12375
12654
  name: text.scenarios.house_one_pillar,
12376
12655
  run({ room, step, expect }) {
12377
12656
  const { oid, parts, centre } = spawn(room, "house_casa_portico");
12378
- const list = events(room);
12657
+ const list2 = events(room);
12379
12658
  const columns = groundColumns(parts);
12380
12659
  const laj = slabs(parts);
12381
12660
  blunt(room, oid, columns[0].id, centre(columns[0].id), 3e6);
12382
12661
  step(20);
12383
12662
  expect(!whole(room, oid, columns[0].id), fill(T2.one_pillar_broke, { id: columns[0].id }));
12384
12663
  expect(laj.length > 0 && laj.every((id) => whole(room, oid, id)), T2.slabs_whole);
12385
- expect(!collapsed(list).some((id) => laj.includes(id)), T2.no_slab_fell);
12664
+ expect(!collapsed(list2).some((id) => laj.includes(id)), T2.no_slab_fell);
12386
12665
  }
12387
12666
  },
12388
12667
  {
@@ -12390,17 +12669,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
12390
12669
  name: text.scenarios.house_two_pillars,
12391
12670
  run({ room, step, expect }) {
12392
12671
  const { oid, parts, centre } = spawn(room, "house_casa_portico");
12393
- const list = events(room);
12672
+ const list2 = events(room);
12394
12673
  const columns = groundColumns(parts);
12395
12674
  const laj = slabs(parts);
12396
12675
  blunt(room, oid, columns[0].id, centre(columns[0].id), 3e6);
12397
12676
  blunt(room, oid, columns[1].id, centre(columns[1].id), 3e6);
12398
12677
  step(90);
12399
- for (let next = 2; next < columns.length && !slabs(parts).some((id) => collapsed(list).includes(id)); next++) {
12678
+ for (let next = 2; next < columns.length && !slabs(parts).some((id) => collapsed(list2).includes(id)); next++) {
12400
12679
  blunt(room, oid, columns[next].id, centre(columns[next].id), 3e6);
12401
12680
  step(90);
12402
12681
  }
12403
- const fell = collapsed(list);
12682
+ const fell = collapsed(list2);
12404
12683
  expect(laj.some((id) => fell.includes(id)), fill(T2.two_slab_fell, { n: fell.length }));
12405
12684
  expect(parts.filter((p) => role(p) === "roof").some((p) => fell.includes(p.id)), T2.two_roof_fell);
12406
12685
  }
@@ -12410,13 +12689,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
12410
12689
  name: text.scenarios.house_partition,
12411
12690
  run({ room, step, expect }) {
12412
12691
  const { oid, parts, centre } = spawn(room, "house_casa_inteira");
12413
- const list = events(room);
12692
+ const list2 = events(room);
12414
12693
  const partition = parts.find((p) => role(p) === "partition");
12415
12694
  const laj = slabs(parts);
12416
12695
  blunt(room, oid, partition.id, centre(partition.id), 3e6);
12417
12696
  step(20);
12418
12697
  expect(!whole(room, oid, partition.id), fill(T2.partition_broke, { id: partition.id }));
12419
- expect(laj.every((id) => whole(room, oid, id)) && !collapsed(list).some((id) => laj.includes(id)), T2.slab_stayed);
12698
+ expect(laj.every((id) => whole(room, oid, id)) && !collapsed(list2).some((id) => laj.includes(id)), T2.slab_stayed);
12420
12699
  }
12421
12700
  },
12422
12701
  {
@@ -12455,12 +12734,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
12455
12734
  name: text.scenarios.house_gas_explodes,
12456
12735
  run({ room, step, expect }) {
12457
12736
  const { oid, parts, centre } = spawn(room, "house_casa_inteira");
12458
- const list = events(room);
12737
+ const list2 = events(room);
12459
12738
  const bottle = parts.find((p) => p.explodes);
12460
12739
  room.world.hitPart(oid, bottle.id, { type: "fire", point: centre(bottle.id), temperature: 900, radius: 0.6, duration: 8 });
12461
12740
  step(12);
12462
- expect(list.filter((e) => e.type === "explode").length > 0, T2.gas_exploded);
12463
- const damage = list.filter((e) => e.type === "damage" && e.part !== bottle.id && e.damageType === "explosive");
12741
+ expect(list2.filter((e) => e.type === "explode").length > 0, T2.gas_exploded);
12742
+ const damage = list2.filter((e) => e.type === "damage" && e.part !== bottle.id && e.damageType === "explosive");
12464
12743
  expect(damage.length > 0, fill(T2.gas_damaged, { n: new Set(damage.map((e) => e.part)).size }));
12465
12744
  }
12466
12745
  }