@adatechnology/game-floorplan-three 0.1.1 → 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.
@@ -27,10 +27,10 @@ var GameFloorplanThree = (() => {
27
27
  VERSION: () => VERSION,
28
28
  bindNavigator: () => bindNavigator,
29
29
  buildSpecimenMeshes: () => buildSpecimenMeshes,
30
- create: () => create2,
30
+ create: () => create3,
31
31
  createFloorNavigator: () => createFloorNavigator,
32
32
  createFloorplanTestModule: () => createFloorplanTestModule,
33
- createHouseRenderer: () => create2,
33
+ createHouseRenderer: () => create3,
34
34
  createHouseScenarios: () => createHouseScenarios,
35
35
  createTranslator: () => createTranslator,
36
36
  en: () => en,
@@ -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
@@ -1795,7 +2074,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
1795
2074
  "what.fridge": "fridge",
1796
2075
  "what.pantry": "pantry",
1797
2076
  "what.cabinet": "cabinet",
1798
- "warn.interactablesIncomplete": "floorplan-three: cfg.interactives is incomplete (GameInteractables, GameInteractablesHousehold, GameInteractablesThree, adapter)",
2077
+ "warn.interactablesIncomplete": "floorplan-three: cfg.interactives is incomplete (GameInteractables, GameInteractablesHousehold, GameInteractablesThree)",
1799
2078
  "message.locked": "Locked.",
1800
2079
  "message.boarded": "Locked: the door is boarded up.",
1801
2080
  "message.pickedUp": "Picked up: {name}{qty}",
@@ -1820,7 +2099,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
1820
2099
  "what.fridge": "geladeira",
1821
2100
  "what.pantry": "despensa",
1822
2101
  "what.cabinet": "arm\xE1rio",
1823
- "warn.interactablesIncomplete": "floorplan-three: cfg.interactives incompleto (GameInteractables, GameInteractablesHousehold, GameInteractablesThree, adapter)",
2102
+ "warn.interactablesIncomplete": "floorplan-three: cfg.interactives incompleto (GameInteractables, GameInteractablesHousehold, GameInteractablesThree)",
1824
2103
  "message.locked": "Trancada.",
1825
2104
  "message.boarded": "Trancada: a porta est\xE1 bloqueada com t\xE1buas.",
1826
2105
  "message.pickedUp": "Pegou: {name}{qty}",
@@ -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() {
@@ -4515,7 +4794,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4515
4794
  shared.ctx.electricalInfo = null;
4516
4795
  if (!E) return;
4517
4796
  const R = shared.ctx.r, nA = R.floors.length, lotGroup = R.lot ? "lot" : "f0", concreteColor = 11973547, iron = 4869200, wireRun = 1842206, info = { pole: null, meter: null, panel: null, conduits: [], outlets: [], switches: [], circuits: E.circuits || [], exposed: !!E.exposed };
4518
- const en2 = E.serviceEntrance, KV = shared.ctx.iv ? shared.ctx.iv.plane : null;
4797
+ const en3 = E.serviceEntrance, KV = shared.ctx.iv ? shared.ctx.iv.plane : null;
4519
4798
  const wireL = (a, b, r_ = 8e-3) => {
4520
4799
  const L = Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
4521
4800
  if (L < 1e-3) return;
@@ -4531,25 +4810,25 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
4531
4810
  for (const dx of [-0.65, -0.2, 0.25, 0.7]) cylBase("plain", u + dx, h - 0.62, v, 0.025, 0.1, 13684680);
4532
4811
  cursor.pc = null;
4533
4812
  };
4534
- if (en2 && en2.pole) {
4535
- const P = en2.pole;
4813
+ if (en3 && en3.pole) {
4814
+ const P = en3.pole;
4536
4815
  if (!(KV && KV.serviceEntrance)) pole(P.u, P.v, P.h);
4537
4816
  info.pole = { pos: [P.u, 0, P.v], h: P.h };
4538
4817
  for (const k of [-1, 1]) pole(P.u + k * 22, P.v, P.h);
4539
4818
  cursor.pc = pieceRecord("wiring:grid", "copper", null, { tags: ["wiring"] });
4540
4819
  for (const dx of [-0.65, -0.2, 0.25, 0.7]) for (const k of [-1, 1]) wireL([P.u + dx, P.h - 0.5, P.v], [P.u + k * 22 + dx, P.h - 0.5, P.v], 7e-3);
4541
- if (en2.drop && en2.drop.length > 1 && !(KV && KV.serviceEntrance)) {
4542
- const r0 = en2.drop[0], r1 = en2.drop[en2.drop.length - 1];
4820
+ if (en3.drop && en3.drop.length > 1 && !(KV && KV.serviceEntrance)) {
4821
+ const r0 = en3.drop[0], r1 = en3.drop[en3.drop.length - 1];
4543
4822
  for (const dz of [0, 0.04]) wireL([r0[0], r0[2], r0[1]], [r1[0], r1[2], r1[1] + dz], 9e-3);
4544
4823
  wireL([P.u - 0.2, P.h - 0.5, P.v], [r0[0], r0[2], r0[1]], 8e-3);
4545
4824
  }
4546
4825
  cursor.pc = null;
4547
- if (en2.descent && en2.descent.length > 1 && !(KV && KV.serviceEntrance)) {
4548
- const d0 = en2.descent[0], d1 = en2.descent[en2.descent.length - 1];
4826
+ if (en3.descent && en3.descent.length > 1 && !(KV && KV.serviceEntrance)) {
4827
+ const d0 = en3.descent[0], d1 = en3.descent[en3.descent.length - 1];
4549
4828
  cylBase("metal", d0[0], d1[2], d0[1], 0.02, d0[2] - d1[2], 9080466);
4550
4829
  bx("metal", d0[0] - 0.05, d0[2] - 0.03, d0[1] - 0.05, d0[0] + 0.05, d0[2] + 0.08, d0[1] + 0.05, 8027780);
4551
4830
  }
4552
- const M = en2.meter;
4831
+ const M = en3.meter;
4553
4832
  if (M) {
4554
4833
  const hw = (M.w || 0.35) / 2, hd = (M.d || 0.2) / 2, hh = (M.h || 0.5) / 2, fr = M.side === "front" ? -1 : 1;
4555
4834
  if (!(KV && KV.meter)) bx("plain", M.u - hw, M.y - hh, M.v - hd, M.u + hw, M.y + hh, M.v + hd, 14277597);
@@ -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,9 +7255,9 @@ 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]));
6981
- 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.floorKind };
7258
+ const entById = new Map(plane2.items.map((e) => [e.id, e]));
7259
+ const entByItem = new Map(plane2.items.map((e) => [e.item, e]));
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 });
6984
7263
  const add0 = world.add;
@@ -6997,10 +7276,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
6997
7276
  }
6998
7277
  return add0(id, spec, tr);
6999
7278
  };
7000
- const exitPoint = 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
- IV.warnings = exitPoint.warnings;
7003
- IV.exitPoint = exitPoint;
7281
+ IV.warnings = added.warnings;
7282
+ IV.added = added;
7004
7283
  if (h.state.iv) {
7005
7284
  try {
7006
7285
  const st = JSON.parse(JSON.stringify(h.state.iv));
@@ -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);
@@ -7050,7 +7329,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7050
7329
  for (const l of out.lights) l.removeFromParent();
7051
7330
  const group = ivGroup(ent), g0 = cursor.group, root = new THREE.Group();
7052
7331
  root.name = "iv:" + ent.id;
7053
- root.position.set(item.x, ent.floorKind, item.z);
7332
+ root.position.set(item.x, ent.floorY, item.z);
7054
7333
  root.rotation.y = item.ry;
7055
7334
  root.userData.iv = ent.id;
7056
7335
  const screen = spec.devices && spec.devices.some((d) => d.kind === "screen");
@@ -7074,7 +7353,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7074
7353
  root.add(m);
7075
7354
  continue;
7076
7355
  }
7077
- ivAccumulate(IV_MATERIAL[m.userData.material] || "plain", m.geometry, item.x, ent.floorKind, item.z, item.ry, null);
7356
+ ivAccumulate(IV_MATERIAL[m.userData.material] || "plain", m.geometry, item.x, ent.floorY, item.z, item.ry, null);
7078
7357
  m.geometry.dispose();
7079
7358
  } else root.add(m);
7080
7359
  }
@@ -7095,17 +7374,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7095
7374
  roomLightMask(m);
7096
7375
  }
7097
7376
  });
7098
- const E = { id: ent.id, type, entry: ent, floor: ent.floor, group, root, parts: out.parts, spec, screen: body, pos: [item.x, ent.floorKind, item.z], ry: item.ry, origin: ent.origin };
7377
+ const E = { id: ent.id, type, entry: ent, floor: ent.floor, group, root, parts: out.parts, spec, screen: body, pos: [item.x, ent.floorY, item.z], ry: item.ry, origin: ent.origin };
7099
7378
  IV.entries.set(ent.id, E);
7100
7379
  if (root.children.length) IV.roots.push(E);
7101
7380
  return spec;
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) {
@@ -7454,7 +7733,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7454
7733
  breaker: com((circuit, on) => {
7455
7734
  if (on === void 0) return w.power.breaker(circuit);
7456
7735
  w.power.setBreaker(circuit, !!on);
7457
- const q = IV.plane.picture && IV.entries.get(IV.plane.picture);
7736
+ const q = IV.plane.panel && IV.entries.get(IV.plane.panel);
7458
7737
  if (q && q.parts["breaker_" + circuit]) w.setPart(q.id, "breaker_" + circuit, on ? 1 : 0);
7459
7738
  IV.dirty = true;
7460
7739
  return !!on;
@@ -7523,6 +7802,1345 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7523
7802
  Object.assign(K, { props, TYPES, newState, enter, tagDamage });
7524
7803
  }
7525
7804
 
7805
+ // ../game-floorplan-interactables/dist/index.js
7806
+ var en2 = {
7807
+ "error.missingKit": "game-floorplan-interactables: create needs GameInteractables and GameInteractablesHousehold",
7808
+ "error.unknownOwnType": "game-floorplan-interactables: unknown own type: {type}",
7809
+ "warn.cylinderNoCabinet": "cylinder {id} under the counter has no kitchen cabinet to hide it",
7810
+ "warn.cabinetNoDoor": "cabinet {cabinet} has no door for the cylinder {id}",
7811
+ "warn.switchUnknownLamp": "switch {id} controls {lamp}, which does not exist",
7812
+ "warn.pointNoObject": "point {id} ({kind}) has no object for {item}",
7813
+ "warn.buildEmpty": "build returned nothing for {id}"
7814
+ };
7815
+ var ptBR2 = {
7816
+ "error.missingKit": "game-floorplan-interactables: create precisa de GameInteractables e GameInteractablesHousehold",
7817
+ "error.unknownOwnType": "game-floorplan-interactables: tipo pr\xF3prio desconhecido: {type}",
7818
+ "warn.cylinderNoCabinet": "botij\xE3o {id} sob a bancada sem arm\xE1rio de cozinha para escond\xEA-lo",
7819
+ "warn.cabinetNoDoor": "arm\xE1rio {cabinet} sem porta para o botij\xE3o {id}",
7820
+ "warn.switchUnknownLamp": "interruptor {id} controla {lamp}, que n\xE3o existe",
7821
+ "warn.pointNoObject": "ponto {id} ({kind}) sem objeto para {item}",
7822
+ "warn.buildEmpty": "construir devolveu vazio para {id}"
7823
+ };
7824
+ function createTranslator2(locale, table) {
7825
+ const base = locale && /^pt/i.test(locale) ? ptBR2 : en2;
7826
+ const messages = { ...base, ...table ?? {} };
7827
+ return (key, params) => (messages[key] ?? key).replace(/\{(\w+)\}/g, (_m, name) => params && params[name] !== void 0 ? String(params[name]) : `{${name}}`);
7828
+ }
7829
+ var TYPE_MAP = Object.freeze({
7830
+ fridge: { type: "fridge" },
7831
+ // was `geladeira`
7832
+ fridge_large: { type: "fridge" },
7833
+ // was `geladeira2`
7834
+ display_fridge_medium: { type: "fridge", variant: "steel" },
7835
+ // was `geladeira_med`
7836
+ display_fridge: { type: "fridge", variant: "steel" },
7837
+ // was `refrig_exp`
7838
+ freezer: { type: "fridge_compact" },
7839
+ // was `freezer`
7840
+ kitchen_cabinet: { compound: "sink" },
7841
+ // was `armario_cozinha`
7842
+ kitchen_cabinet_small: { compound: "sink" },
7843
+ // was `armario_cozinha_p`
7844
+ kitchen_cabinet_large: { compound: "sink" },
7845
+ // was `armario_cozinha_g`
7846
+ washbasin: { compound: "basin" },
7847
+ // was `pia_b`
7848
+ pedestal_basin: { compound: "basin" },
7849
+ // was `pia_coluna`
7850
+ wardrobe: { type: "wardrobe" },
7851
+ // was `guarda`
7852
+ wardrobe_small: { type: "wardrobe" },
7853
+ // was `guarda_peq`
7854
+ wardrobe_large: { type: "wardrobe" },
7855
+ // was `guarda_g`
7856
+ closet_wardrobe: { type: "wardrobe" },
7857
+ // was `guarda_closet`
7858
+ dresser: { type: "dresser" },
7859
+ // was `comoda`
7860
+ nightstand: { type: "nightstand" },
7861
+ // was `criado`
7862
+ pantry: { type: "pantry" },
7863
+ // was `despensa`
7864
+ laundry_cabinet: { type: "pantry" },
7865
+ // was `armario_lav`
7866
+ china_cabinet: { type: "pantry" },
7867
+ // was `cristaleira`
7868
+ filing_cabinet: { type: "dresser" },
7869
+ // was `arquivo`
7870
+ console_table: { type: "dresser" },
7871
+ // was `aparador_c`
7872
+ tv_unit: { type: "kitchen_cabinet_base" },
7873
+ // was `rack`
7874
+ tv_unit_small: { type: "kitchen_cabinet_base" },
7875
+ // was `rack_peq`
7876
+ tv_unit_large: { type: "kitchen_cabinet_base" },
7877
+ // was `rack_grande`
7878
+ stove: { type: "stove" },
7879
+ // was `fogao`
7880
+ stove_4burner: { type: "stove" },
7881
+ // was `fogao4`
7882
+ cooking_gas_cylinder: { type: "gas_bottle", dim: "none" },
7883
+ // was `botijao_gas`
7884
+ gas_cylinder: { type: "gas_bottle", dim: "none" },
7885
+ // was `botijao`
7886
+ tv: { type: "tv" },
7887
+ // was `tv`
7888
+ tv_large: { type: "tv" },
7889
+ // was `tv_grande`
7890
+ microwave: { type: "microwave" },
7891
+ // was `microondas`
7892
+ washing_machine: { type: "washing_machine" },
7893
+ // was `maquina`
7894
+ shower: { type: "shower", dim: "wd" },
7895
+ // was `box`
7896
+ shower_large: { type: "shower", dim: "wd" },
7897
+ // was `box_g`
7898
+ toilet: { type: "toilet", dim: "wd" },
7899
+ // was `vaso`
7900
+ laundry_tub: { type: "utility_sink", dim: "wd" },
7901
+ // was `tanque`
7902
+ sofa_2seat: { type: "sofa" },
7903
+ // was `sofa2`
7904
+ sofa_3seat: { type: "sofa" },
7905
+ // was `sofa3`
7906
+ sofa_l: { type: "sofa" },
7907
+ // was `sofa_l`
7908
+ sofa_xl: { type: "sofa" },
7909
+ // was `sofa_xl`
7910
+ armchair: { type: "armchair" },
7911
+ // was `poltrona`
7912
+ armchair_high: { type: "armchair" },
7913
+ // was `poltrona_alta`
7914
+ stool: { type: "dining_chair" },
7915
+ // was `banqueta`
7916
+ camp_chair: { type: "camp_chair", dim: "wd" },
7917
+ // was `cadeira_camping`
7918
+ rocking_chair: { type: "armchair" },
7919
+ // was `cadeira_balanco`
7920
+ rustic_sink: { compound: "rustic_sink" },
7921
+ // was `pia_rustica`: the sink of the cabin or shack: the basin the whole width, no cabinet under it; a wall cabinet only if there is `overhead` content
7922
+ improvised_bed: { type: "bed_single", dim: "wd" },
7923
+ // was `cama_improvisada`
7924
+ log_bench: { type: "bench", dim: "wd" },
7925
+ // was `banco_tronco`
7926
+ plank_shelf: { type: "pantry", variant: "garage" },
7927
+ // was `prateleira_tabua`
7928
+ sideboard: { type: "dresser" },
7929
+ // was `aparador`
7930
+ buffet: { type: "dresser" },
7931
+ // was `bufe`
7932
+ single_bed: { type: "bed_single", dim: "wd" },
7933
+ // was `cama_solteiro`
7934
+ double_bed: { type: "bed_double", dim: "wd" },
7935
+ // was `cama_casal`
7936
+ queen_bed: { type: "bed_double", dim: "wd" },
7937
+ // was `cama_queen`
7938
+ king_bed: { type: "bed_double", dim: "wd" },
7939
+ // was `cama_king`
7940
+ bench: { type: "bench", dim: "wd" },
7941
+ // was `banco`
7942
+ garden_bench: { type: "bench", dim: "wd" },
7943
+ // was `banco_jardim`
7944
+ waiting_bench: { type: "bench", dim: "wd" },
7945
+ // was `espera`
7946
+ blinds: { type: "blinds" },
7947
+ // was `persiana`
7948
+ curtain: { type: "curtain" },
7949
+ // was `cortina`
7950
+ trash_bin: { type: "trash_bin" },
7951
+ // was `lixeira`
7952
+ outdoor_bin: { type: "wheelie_bin" },
7953
+ // was `lixeira_ext`
7954
+ mailbox: { type: "mailbox", dim: "none" },
7955
+ // was `caixa_correio`: the household draws the box on its post: position and rotation only
7956
+ doghouse: { type: "dog_house" },
7957
+ // was `casinha_cachorro`
7958
+ bbq_grill: { type: "bbq", dim: "wd" },
7959
+ // was `churrasqueira`
7960
+ bbq_simple: { type: "bbq", dim: "wd" },
7961
+ // was `churrasqueira_simples`
7962
+ clothesline: { type: "clothesline", dim: "wh" },
7963
+ // was `varal`
7964
+ tool_shelf: { type: "pantry", variant: "garage" },
7965
+ // was `estante_ferr`
7966
+ workbench: { type: "pantry", variant: "garage" },
7967
+ // was `bancada_ferr`
7968
+ // rural houses and campsite (types of the household pack: rural and camp)
7969
+ bunk_bed: { type: "bunk_bed", dim: "wd" },
7970
+ // was `beliche`
7971
+ wood_stove: { type: "wood_stove", dim: "wd" },
7972
+ // was `fogao_lenha`: the flue rises to the chimney height (cabin); the fireplace is handled in `planSimple` (it moves and changes height)
7973
+ fireplace: { type: "fireplace", dim: "w" },
7974
+ // was `lareira`
7975
+ outhouse: { type: "outhouse", dim: "wdh" },
7976
+ // was `privada`
7977
+ well: { type: "well", dim: "none" },
7978
+ // was `poco`
7979
+ cooler: { type: "cooler", dim: "wd" },
7980
+ // was `cooler`
7981
+ campfire: { type: "campfire", dim: "wd" },
7982
+ // was `fogueira`
7983
+ camp_stove: { type: "camp_stove", dim: "wd" },
7984
+ // was `fogareiro`
7985
+ camp_gas_canister: { type: "gas_canister", dim: "none" },
7986
+ // was `botijao_camping`
7987
+ camp_table: { type: "camp_table", dim: "wdh" },
7988
+ // was `mesa_camping`
7989
+ // kerosene/gas lanterns: a `lamp` device without electricity (the grid does not matter); the ceiling one is the `hanging` variant
7990
+ oil_lamp: { type: "lantern_lamp", dim: "x" },
7991
+ // was `lampiao`
7992
+ camp_lantern: { type: "lantern_lamp", dim: "x" },
7993
+ // was `lampiao_camping`
7994
+ ceiling_oil_lamp: { type: "lantern_lamp", variant: "hanging", dim: "x" },
7995
+ // was `lampiao_teto`
7996
+ // lamps: objects of the adapter (the kit has no lamp mesh; the house renderer draws the fixture)
7997
+ ceiling_light: { type: "lamp", watts: 15 },
7998
+ // was `plafon`
7999
+ pendant: { type: "lamp", watts: 20 },
8000
+ // was `pendente`
8001
+ track_spot: { type: "lamp", watts: 10 },
8002
+ // was `spot_trilho`
8003
+ chandelier: { type: "lamp", watts: 60 },
8004
+ // was `lustre`
8005
+ floor_lamp: { type: "lamp", watts: 12 },
8006
+ // was `luminaria`
8007
+ table_lamp: { type: "lamp", watts: 9 }
8008
+ // was `abajur`
8009
+ });
8010
+ var CHAIR_TABLES = Object.freeze({
8011
+ dining_table: "dining",
8012
+ // was `mesa`
8013
+ dining_table_small: "dining",
8014
+ // was `mesa_peq`
8015
+ dining_table_round: "dining",
8016
+ // was `mesa_red`
8017
+ dining_table_large: "dining",
8018
+ // was `mesa_grande`
8019
+ gourmet_table: "dining",
8020
+ // was `mesa_gourmet`
8021
+ gourmet_table_small: "dining",
8022
+ // was `mesa_gourmet_peq`
8023
+ outdoor_table: "dining",
8024
+ // was `mesa_ext`
8025
+ office_desk: "office",
8026
+ // was `mesa_escr`
8027
+ office_desk_large: "office",
8028
+ // was `mesa_escr_g`
8029
+ desk: "office"
8030
+ // was `escrivaninha`
8031
+ });
8032
+ var DINING_CHAIR_SIDE = 0.45;
8033
+ var CONTENT_MAP = Object.freeze({
8034
+ // food
8035
+ sugar: "sugar",
8036
+ // was `acucar`
8037
+ rice: "rice",
8038
+ // was `arroz`
8039
+ biscuits: "biscuits",
8040
+ // was `biscoito`
8041
+ coffee: "coffee",
8042
+ // was `cafe`
8043
+ raw_beef: "frozen_meat",
8044
+ // was `carne`
8045
+ packed_meat: "frozen_meat",
8046
+ // was `carne`
8047
+ flour: "flour",
8048
+ // was `farinha`
8049
+ beans: "beans",
8050
+ // was `feijao`
8051
+ apple: "apple",
8052
+ // was `fruta`
8053
+ fruit: "apple",
8054
+ // was `fruta`
8055
+ yogurt: "yogurt",
8056
+ // was `iogurte`
8057
+ canned_food: "canned_food",
8058
+ // was `lata_atum`
8059
+ canned_tuna: "canned_food",
8060
+ // was `lata_atum`
8061
+ canned_corn_and_peas: "canned_food",
8062
+ // was `lata_milho`
8063
+ canned_corn: "canned_food",
8064
+ // was `lata_milho`
8065
+ milk_carton: "milk_carton",
8066
+ // was `leite`
8067
+ pasta: "pasta",
8068
+ // was `macarrao`
8069
+ cooking_oil: "cooking_oil",
8070
+ // was `oleo`
8071
+ eggs: "eggs",
8072
+ // was `ovos`
8073
+ cheese: "cheese",
8074
+ // was `queijo`
8075
+ leftover_meal: "bowl",
8076
+ // was `sobras`
8077
+ leftovers: "bowl",
8078
+ // was `sobras`
8079
+ ice_cream: "ice_cream",
8080
+ // was `sorvete`
8081
+ seasoning: "salt",
8082
+ // was `tempero`
8083
+ spices: "salt",
8084
+ // was `tempero`
8085
+ // water and drink
8086
+ water_jug_5l: "water_bottle",
8087
+ // was `agua_galao`
8088
+ water_jug: "water_bottle",
8089
+ // was `agua_galao`
8090
+ water_bottle: "water_bottle",
8091
+ // was `agua_garrafa`
8092
+ soda_can: "soda_can",
8093
+ // was `refrigerante`
8094
+ soda: "soda_can",
8095
+ // was `refrigerante`
8096
+ // medicine
8097
+ alcohol_70: "alcohol_70",
8098
+ // was `alcool`
8099
+ rubbing_alcohol: "alcohol_70",
8100
+ // was `alcool`
8101
+ adhesive_bandages: "bandage",
8102
+ // was `curativo`
8103
+ bandages: "bandage",
8104
+ // was `curativo`
8105
+ insulin: "first_aid_kit",
8106
+ // was `insulina`
8107
+ painkillers: "painkillers",
8108
+ // was `paracetamol`
8109
+ painkiller: "painkillers",
8110
+ // was `paracetamol`
8111
+ maintenance_medication: "painkillers",
8112
+ // was `remedio`
8113
+ medicine: "painkillers",
8114
+ // was `remedio`
8115
+ // cleaning and hygiene
8116
+ bleach: "bleach",
8117
+ // was `agua_sanitaria`
8118
+ disinfectant: "bleach",
8119
+ // was `desinfetante`
8120
+ detergent: "detergent",
8121
+ // was `detergente`
8122
+ dish_soap: "detergent",
8123
+ // was `detergente`
8124
+ toothbrush: "toothbrush",
8125
+ // was `escova_dente`
8126
+ sponge: "sponge",
8127
+ // was `esponja`
8128
+ rubber_gloves: "sponge",
8129
+ // was `luvas`
8130
+ toilet_paper: "toilet_paper",
8131
+ // was `papel_higienico`
8132
+ laundry_powder: "detergent",
8133
+ // was `sabao_po`
8134
+ washing_powder: "detergent",
8135
+ // was `sabao_po`
8136
+ soap: "soap",
8137
+ // was `sabonete`
8138
+ shampoo: "shampoo",
8139
+ // was `shampoo`
8140
+ // clothes
8141
+ jeans: "jeans",
8142
+ // was `calca`
8143
+ trousers: "jeans",
8144
+ // was `calca`
8145
+ tshirt: "tshirt",
8146
+ // was `camisa`
8147
+ shirt: "tshirt",
8148
+ // was `camisa`
8149
+ t_shirt: "tshirt",
8150
+ // was `camiseta`
8151
+ jacket: "jacket",
8152
+ // was `casaco`
8153
+ coat: "jacket",
8154
+ // was `casaco`
8155
+ blanket: "blanket",
8156
+ // was `cobertor`
8157
+ socks: "socks",
8158
+ // was `meias`
8159
+ underwear: "underwear",
8160
+ // was `roupa_intima`
8161
+ sneakers: "sneakers",
8162
+ // was `sapato`
8163
+ shoes: "sneakers",
8164
+ // was `sapato`
8165
+ // utensils
8166
+ cup: "cup",
8167
+ // was `caneca`
8168
+ mug: "cup",
8169
+ // was `caneca`
8170
+ plate: "plate",
8171
+ // was `prato`
8172
+ china_plates: "plate",
8173
+ // was `prato`
8174
+ plates: "plate",
8175
+ // was `prato`
8176
+ wine_glass: "cup",
8177
+ // was `taca`
8178
+ wine_glasses: "cup",
8179
+ // was `taca`
8180
+ pot: "pot",
8181
+ // was `panela`
8182
+ // tools and electronics
8183
+ pliers: "screwdriver",
8184
+ // was `alicate`
8185
+ bucket: "paint_can",
8186
+ // was `balde`
8187
+ cable_bundle: "phone_charger",
8188
+ // was `cabos`
8189
+ cables: "phone_charger",
8190
+ // was `cabos`
8191
+ pen: "pen",
8192
+ // was `caneta`
8193
+ phone_charger: "phone_charger",
8194
+ // was `carregador`
8195
+ charger: "phone_charger",
8196
+ // was `carregador`
8197
+ screwdriver: "screwdriver",
8198
+ // was `chave_fenda`
8199
+ house_key: "wallet",
8200
+ // was `chaves`
8201
+ keys: "wallet",
8202
+ // was `chaves`
8203
+ remote_control: "batteries",
8204
+ // was `controle_remoto`
8205
+ rope: "rope",
8206
+ // was `corda`
8207
+ electrical_tape: "duct_tape",
8208
+ // was `fita_isolante`
8209
+ insulating_tape: "duct_tape",
8210
+ // was `fita_isolante`
8211
+ flashlight: "flashlight",
8212
+ // was `lanterna`
8213
+ backpack: "backpack",
8214
+ // was `mochila`
8215
+ eyeglasses: "wallet",
8216
+ // was `oculos`
8217
+ glasses: "wallet",
8218
+ // was `oculos`
8219
+ screws: "duct_tape",
8220
+ // was `parafusos`
8221
+ batteries: "batteries",
8222
+ // was `pilhas`
8223
+ nails: "duct_tape",
8224
+ // was `pregos`
8225
+ // improvised weapons
8226
+ knife: "knife",
8227
+ // was `faca`
8228
+ kitchen_knife: "knife",
8229
+ // was `faca`
8230
+ stapler: "scissors",
8231
+ // was `grampeador`
8232
+ hammer: "hammer",
8233
+ // was `martelo`
8234
+ handsaw: "hammer",
8235
+ // was `serrote`
8236
+ hand_saw: "hammer",
8237
+ // was `serrote`
8238
+ scissors: "scissors",
8239
+ // was `tesoura`
8240
+ broom: "rope",
8241
+ // was `vassoura`
8242
+ // papers
8243
+ letter: "letter",
8244
+ // was `carta`
8245
+ bill: "bill",
8246
+ // was `conta`
8247
+ documents: "documents",
8248
+ // was `documento`
8249
+ dvd: "notebook",
8250
+ // was `dvd`
8251
+ dvds: "notebook",
8252
+ // was `dvd`
8253
+ book: "notebook",
8254
+ // was `livro`
8255
+ // trash
8256
+ food_packaging: "plastic_bag",
8257
+ // was `embalagem`
8258
+ packaging: "plastic_bag",
8259
+ // was `embalagem`
8260
+ paint_can: "paint_can",
8261
+ // was `lata_tinta`
8262
+ empty_can: "empty_can",
8263
+ // was `lata_vazia`
8264
+ flyer: "flyer",
8265
+ // was `panfleto`
8266
+ crumpled_paper: "crumpled_paper",
8267
+ // was `papel_amassado`
8268
+ trash_bag: "plastic_bag",
8269
+ // was `saco_lixo`
8270
+ full_trash_bag: "plastic_bag"
8271
+ // was `saco_lixo_cheio`
8272
+ });
8273
+ var CONTENT_BY_GROUP = Object.freeze({
8274
+ food: "canned_food",
8275
+ // was `comida`
8276
+ water: "water_bottle",
8277
+ // was `agua`
8278
+ medicine: "painkillers",
8279
+ // was `remedio`
8280
+ tool: "duct_tape",
8281
+ // was `ferramenta`
8282
+ improvised_weapon: "hammer",
8283
+ // was `arma_improvisada`
8284
+ clothes: "tshirt",
8285
+ // was `roupa`
8286
+ document: "documents",
8287
+ // was `documento`
8288
+ cleaning: "detergent",
8289
+ // was `limpeza`
8290
+ trash: "crumpled_paper",
8291
+ // was `lixo`
8292
+ utensil: "plate"
8293
+ // was `utensilio`
8294
+ });
8295
+ var CONTENT_FALLBACK = "crumpled_paper";
8296
+ var FROZEN_ITEMS = Object.freeze(["ice_cream", "frozen_meat"]);
8297
+ var DRAWER_ITEMS = Object.freeze(["underwear", "socks"]);
8298
+ var DRAWER_GROUPS = Object.freeze(["improvised_weapon", "tool"]);
8299
+ var OBJECT_SUBSTITUTES = Object.freeze({ mailbox: ["flyer", "postcard", "letter"] });
8300
+ var FIXTURES_OF_POINT = Object.freeze({
8301
+ tap: ["tap"],
8302
+ // was `torneira`
8303
+ shower: ["shower"],
8304
+ // was `chuveiro`
8305
+ flush: ["flush"],
8306
+ // was `descarga`
8307
+ tub: ["tap", "basin"],
8308
+ // was `tanque`
8309
+ machine: ["inlet"]
8310
+ // was `maquina`
8311
+ });
8312
+ var OWN_TYPES = Object.freeze({ lamp: true, gas_piped: true });
8313
+ var ADAPTER_VERSION = "0.3.0";
8314
+ var r3 = (n) => Math.round(n * 1e3) / 1e3;
8315
+ function mergeRegistry(base, extra) {
8316
+ const out = { ...base };
8317
+ if (extra) {
8318
+ for (const [key, value] of Object.entries(extra)) {
8319
+ if (value == null) delete out[key];
8320
+ else out[key] = value;
8321
+ }
8322
+ }
8323
+ return out;
8324
+ }
8325
+ var PREFERENCE = Object.freeze({
8326
+ fridge: (s, c) => c.frozen(s) ? ["freezer", "fridge"] : ["fridge", "freezer"],
8327
+ fridge_compact: (s, c) => c.frozen(s) ? ["freezer", "fridge"] : ["fridge", "freezer"],
8328
+ kitchen_cabinet_base: (s, c) => DRAWER_GROUPS.includes(c.group(s)) ? ["drawer", "cupboard"] : ["cupboard", "drawer"],
8329
+ wardrobe: (s, c) => c.drawerItem(s) ? ["drawer_1", "drawer_2", "drawer_3", "shelves"] : ["shelves", "drawer_1", "drawer_2", "drawer_3"]
8330
+ });
8331
+ function create2(options = {}) {
8332
+ const opts = options || {};
8333
+ const GI = opts.GameInteractables;
8334
+ const HH = opts.GameInteractablesHousehold;
8335
+ const locale = opts.locale || "pt-BR";
8336
+ const msg = createTranslator2(locale, opts.messages);
8337
+ if (!GI || !HH) throw new Error(msg("error.missingKit"));
8338
+ const region = opts.region || "br";
8339
+ const hh = HH.createHousehold({ locale, region });
8340
+ const householdTypes = new Set(hh.types.map((t) => t.id));
8341
+ const worlds = /* @__PURE__ */ new WeakMap();
8342
+ const typeMap = mergeRegistry(TYPE_MAP, opts.typeMap);
8343
+ const contentMap = mergeRegistry(CONTENT_MAP, opts.contentMap);
8344
+ const contentByGroup = mergeRegistry(CONTENT_BY_GROUP, opts.contentByGroup);
8345
+ const chairTables = mergeRegistry(CHAIR_TABLES, opts.chairTables);
8346
+ const fixturesOfPoint = mergeRegistry(FIXTURES_OF_POINT, opts.fixturesOfPoint);
8347
+ const substitutes = mergeRegistry(OBJECT_SUBSTITUTES, opts.substitutes);
8348
+ const preference = mergeRegistry(PREFERENCE, opts.preference);
8349
+ const ownTypes = mergeRegistry(OWN_TYPES, opts.ownTypes);
8350
+ const frozenItems = new Set(opts.frozenItems ?? FROZEN_ITEMS);
8351
+ const drawerItems = new Set(opts.drawerItems ?? DRAWER_ITEMS);
8352
+ const chairSide = opts.chairSide ?? DINING_CHAIR_SIDE;
8353
+ const contentFallback = opts.contentFallback ?? CONTENT_FALLBACK;
8354
+ const seedKey = (id) => {
8355
+ if (!opts.seedKey) return id;
8356
+ const key = opts.seedKey(id);
8357
+ return key == null ? id : key;
8358
+ };
8359
+ function conv(o) {
8360
+ return {
8361
+ x: (u) => r3(o.ox + u),
8362
+ z: (v) => r3(o.oz + o.inw * v),
8363
+ ry: (fu, fv) => r3(Math.atan2(fu, o.inw * fv)),
8364
+ // local offset (lx, lz) of an object with rotation ry -> offset in the world (same convention as three.js)
8365
+ off: (ry, lx, lz) => [Math.cos(ry) * lx + Math.sin(ry) * lz, -Math.sin(ry) * lx + Math.cos(ry) * lz]
8366
+ };
8367
+ }
8368
+ function floorYOf(res, o, floor) {
8369
+ if (floor == null || floor < 0) return o.base;
8370
+ const f = (res.floors || []).find((x) => x.index === floor);
8371
+ return r3(o.base + (f ? f.y0 : 0));
8372
+ }
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];
8377
+ return typeof v === "number" ? v : void 0;
8378
+ }
8379
+ function paletteOf(res) {
8380
+ const c = res.colors || {};
8381
+ const p = {};
8382
+ if (c.wood != null) p.wood = c.wood;
8383
+ if (c.fabric_main != null) p.fabric_main = c.fabric_main;
8384
+ if (c.fabric_accent != null) p.fabric_accent = c.fabric_accent;
8385
+ if (c.metal != null) p.metal = c.metal;
8386
+ return p;
8387
+ }
8388
+ function lightsOfState(res) {
8389
+ const electrical = res.utilities && res.utilities.electrical;
8390
+ return res.state !== "abandoned" && !!electrical && electrical.mode !== "offgrid";
8391
+ }
8392
+ function initialLight(res, popts, id, entry2) {
8393
+ const v = popts && popts.lightsOn;
8394
+ if (typeof v === "function") return !!v(id, entry2);
8395
+ if (typeof v === "boolean") return v;
8396
+ return !!(popts && popts.night) && lightsOfState(res);
8397
+ }
8398
+ const stackGroup = (s) => s.group ?? (opts.groupOf ? opts.groupOf(s.itemId) : null) ?? null;
8399
+ const preferenceContext = {
8400
+ frozen: (s) => frozenItems.has(s.itemId),
8401
+ group: stackGroup,
8402
+ drawerItem: (s) => drawerItems.has(s.itemId)
8403
+ };
8404
+ const itemOfContent = (c) => {
8405
+ const id = contentMap[c.itemId] || (hh.items[c.itemId] ? c.itemId : null) || contentByGroup[stackGroup(c)] || contentFallback;
8406
+ return hh.items[id] ? id : contentFallback;
8407
+ };
8408
+ const volume = (d) => d.size[0] * d.size[1] * d.size[2];
8409
+ const candidates = (id, objectType) => {
8410
+ const def = hh.items[id];
8411
+ const siblings = Object.values(hh.items).filter((i) => i.category === def.category && i.id !== id).sort((a, b) => volume(a) - volume(b) || (a.id < b.id ? -1 : 1));
8412
+ return [id].concat(siblings.map((i) => i.id), substitutes[objectType] || []);
8413
+ };
8414
+ function distribute(type, probeItem, stacks) {
8415
+ const spec = hh.build(type, probeItem, HH.createRecorder().api);
8416
+ const conts = spec.containers || [];
8417
+ const contents = {};
8418
+ for (const c of conts) contents[c.id] = c.slots.map(() => null);
8419
+ const rejected = [];
8420
+ const pref = preference[type];
8421
+ for (const p of stacks || []) {
8422
+ const original = itemOfContent(p);
8423
+ const order = (pref ? pref(p, preferenceContext) : []).concat(conts.map((c) => c.id));
8424
+ let placed = false;
8425
+ for (const id of candidates(original, type)) {
8426
+ const def = hh.items[id];
8427
+ const qty = Math.max(1, Math.min(p.count || 1, def && def.stack || 1));
8428
+ for (const cid of order) {
8429
+ const c = conts.find((x) => x.id === cid);
8430
+ if (!c) continue;
8431
+ for (let i = 0; i < c.slots.length && !placed; i++) {
8432
+ if (contents[cid][i] || !GI.fitsSlot(id, c.slots[i], hh.items)) continue;
8433
+ const data = { source: p.itemId, group: p.group, pickable: p.pickable !== false };
8434
+ if (id !== original) data.substituteFor = original;
8435
+ contents[cid][i] = { type: id, qty, data };
8436
+ placed = true;
8437
+ }
8438
+ if (placed) break;
8439
+ }
8440
+ if (placed) break;
8441
+ }
8442
+ if (!placed) rejected.push(p);
8443
+ }
8444
+ return { contents, rejected };
8445
+ }
8446
+ function plan(res, popts = {}) {
8447
+ popts = popts || {};
8448
+ const o = { ox: popts.originX || 0, oz: popts.originZ || 0, inw: popts.inw || 1, base: popts.base || 0 };
8449
+ const K = conv(o);
8450
+ const floorSel = popts.floor;
8451
+ const externals = popts.externals !== false;
8452
+ const seed = popts.seed != null ? popts.seed : res.seed;
8453
+ const palette = paletteOf(res);
8454
+ const onFloor = (f, outdoor) => floorSel == null || f === floorSel || (outdoor || f < 0) && externals;
8455
+ const utilities = res.utilities || {};
8456
+ const electrical = utilities.electrical || null;
8457
+ const circuits = electrical && electrical.circuits || [];
8458
+ const contents = res.contents || {};
8459
+ const result = {
8460
+ version: ADAPTER_VERSION,
8461
+ template: res.template,
8462
+ seed: res.seed,
8463
+ floor: floorSel == null ? null : floorSel,
8464
+ items: [],
8465
+ outlets: [],
8466
+ // ids of the wall_socket entries
8467
+ switches: [],
8468
+ // ids of the wall_switch entries
8469
+ lights: [],
8470
+ // ids of the lamps (inside and outside)
8471
+ lanterns: [],
8472
+ // ids of the lanterns (lantern_lamp): kerosene/gas light, no grid
8473
+ canisters: [],
8474
+ // ids of the small camping cylinders (gas_canister)
8475
+ serviceEntrance: null,
8476
+ panel: null,
8477
+ // id of the electrical_panel entry (distribution board)
8478
+ meter: null,
8479
+ // id of the power_meter entry (meter box on the facade or the pillar)
8480
+ conduits: [],
8481
+ cylinders: [],
8482
+ // { id, stove, place }
8483
+ stoves: [],
8484
+ fixtures: [],
8485
+ // { object, fixture, global, point, pointKind }
8486
+ points: {},
8487
+ // global fixture -> point of the plumbing
8488
+ mapped: [],
8489
+ // ids of furniture of the plan that became objects of the kit (the renderer does not need to draw them)
8490
+ chairs: [],
8491
+ // ids of the chairs the adapter put around the tables (origin = the table, which the renderer keeps drawing)
8492
+ unmapped: {},
8493
+ // "category/type" -> count
8494
+ discarded: 0,
8495
+ // stacks of content that fit no slot
8496
+ warnings: [],
8497
+ origin: { x: o.ox, z: o.oz, inw: o.inw, base: o.base }
8498
+ };
8499
+ const byOrigin = /* @__PURE__ */ new Map();
8500
+ const seedOf2 = (id) => GI.hashString(String(seed) + ":" + seedKey(id));
8501
+ function push(e) {
8502
+ result.items.push(e);
8503
+ if (!byOrigin.has(e.origin)) byOrigin.set(e.origin, []);
8504
+ byOrigin.get(e.origin).push(e);
8505
+ return e;
8506
+ }
8507
+ function baseItem(m) {
8508
+ const item = {
8509
+ x: K.x(m.x),
8510
+ z: K.z(m.z),
8511
+ ry: m.frontU != null ? K.ry(m.frontU, m.frontV) : r3(m.ry || 0),
8512
+ w: m.w,
8513
+ d: m.d,
8514
+ h: m.h,
8515
+ y: m.y || 0,
8516
+ seed: seedOf2(m.id),
8517
+ palette
8518
+ };
8519
+ const color2 = colorOf(res, m.color);
8520
+ if (color2 != null) item.color = color2;
8521
+ return item;
8522
+ }
8523
+ function entry2(id, type, item, origin, floor, extra) {
8524
+ return Object.assign({ id, type, item, origin, floor, floorY: floorYOf(res, o, floor), connections: {} }, extra || {});
8525
+ }
8526
+ function store(targets, stacks) {
8527
+ let rest = stacks || [];
8528
+ for (const [type, item] of targets) {
8529
+ const d = distribute(type, item, rest);
8530
+ item.contents = Object.assign(item.contents || {}, d.contents);
8531
+ rest = d.rejected;
8532
+ }
8533
+ result.discarded += rest.length;
8534
+ }
8535
+ const hidden = [];
8536
+ function distRect(c, x, z) {
8537
+ const dx = x - c.item.x;
8538
+ const dz = z - c.item.z;
8539
+ const s = Math.sin(c.item.ry);
8540
+ const co = Math.cos(c.item.ry);
8541
+ const lx = dx * co - dz * s;
8542
+ const lz = dx * s + dz * co;
8543
+ return Math.hypot(Math.max(Math.abs(lx) - (c.item.w || 0) / 2, 0), Math.max(Math.abs(lz) - (c.item.d || 0) / 2, 0));
8544
+ }
8545
+ function hideCylinders() {
8546
+ for (const b of hidden) {
8547
+ let target = null;
8548
+ for (const c2 of result.items) {
8549
+ if (c2.type !== "kitchen_cabinet_base" || c2.floor !== b.floor) continue;
8550
+ const dist = distRect(c2, b.item.x, b.item.z);
8551
+ if (!target || dist < target.dist) target = { c: c2, dist };
8552
+ }
8553
+ if (!target) {
8554
+ result.warnings.push(msg("warn.cylinderNoCabinet", { id: b.id }));
8555
+ continue;
8556
+ }
8557
+ const c = target.c;
8558
+ const spec = hh.build(c.type, c.item, HH.createRecorder().api);
8559
+ const sn = Math.sin(c.item.ry);
8560
+ const cs = Math.cos(c.item.ry);
8561
+ let door = null;
8562
+ for (const it of spec.interactions || []) {
8563
+ const pt = it.action && it.action.do === "toggle_part" ? (spec.parts || []).find((q) => q.id === it.action.part) : null;
8564
+ if (!pt || pt.motion.kind !== "hinge") continue;
8565
+ const wx = c.item.x + it.pos[0] * cs + it.pos[2] * sn;
8566
+ const wz = c.item.z - it.pos[0] * sn + it.pos[2] * cs;
8567
+ const dist = Math.hypot(wx - b.item.x, wz - b.item.z);
8568
+ if (!door || dist < door.dist) door = { id: pt.id, dist };
8569
+ }
8570
+ if (!door) {
8571
+ result.warnings.push(msg("warn.cabinetNoDoor", { cabinet: c.id, id: b.id }));
8572
+ continue;
8573
+ }
8574
+ b.item.requires = { object: c.id, part: door.id };
8575
+ }
8576
+ }
8577
+ function initialLanternLight(id, e) {
8578
+ const v = popts.lightsOn;
8579
+ if (typeof v === "function") return !!v(id, e);
8580
+ if (typeof v === "boolean") return v;
8581
+ return !!popts.night && res.state !== "abandoned";
8582
+ }
8583
+ const chimney = res.structureExtras && res.structureExtras.chimney || null;
8584
+ const firstOfType = (type) => (res.items || []).find((m) => typeMap[m.type] && typeMap[m.type].type === type);
8585
+ function chimneyOf(m, role) {
8586
+ if (!chimney) return null;
8587
+ const named = role === "fireplace" ? chimney.fireplace : chimney.stove;
8588
+ if (named != null) return named === m.id ? chimney : null;
8589
+ const first = firstOfType(role === "fireplace" ? "fireplace" : "wood_stove");
8590
+ return chimney.kind === (role === "fireplace" ? "fireplace" : "flue") && first && first.id === m.id ? chimney : null;
8591
+ }
8592
+ const chimneyHeight = (ch) => ch.height != null ? ch.height : ch.top;
8593
+ const campStove = firstOfType("camp_stove");
8594
+ const campCylinder = firstOfType("gas_canister");
8595
+ function planFireplace(m, e, item) {
8596
+ const def = hh.types.find((t) => t.id === "fireplace");
8597
+ const lack = (def.d - m.d) / 2;
8598
+ item.x = r3(item.x + Math.sin(item.ry) * lack);
8599
+ item.z = r3(item.z + Math.cos(item.ry) * lack);
8600
+ const room = (res.rooms || []).find((c) => c.id === m.room && c.floor === m.floor);
8601
+ const f = (res.floors || []).find((x) => x.index === m.floor);
8602
+ item.h = r3(room && room.ceiling || f && f.ceiling || 2.6);
8603
+ const ch = chimneyOf(m, "fireplace");
8604
+ if (ch) {
8605
+ if (ch.material === "stone") item.variant = "stone";
8606
+ const cx = K.x((ch.aabb[0] + ch.aabb[2]) / 2);
8607
+ const cz = K.z((ch.aabb[1] + ch.aabb[3]) / 2);
8608
+ e.connections.chimneyTop = [cx, r3(o.base + chimneyHeight(ch)), cz];
8609
+ }
8610
+ }
8611
+ function planSimple(m, map) {
8612
+ const item = baseItem(m);
8613
+ const dim = map.dim === "none" ? "" : map.dim || "wdh";
8614
+ for (const k of ["w", "d", "h"]) if (dim.indexOf(k) < 0) delete item[k];
8615
+ if (map.dim === "none") delete item.y;
8616
+ if (map.variant) item.variant = map.variant;
8617
+ if (map.type === "tv") item.d = Math.max(item.d || 0, 0.2);
8618
+ const e = entry2(m.id, map.type, item, m.id, m.floor);
8619
+ if (contents[m.id]) store([[map.type, item]], contents[m.id]);
8620
+ if (m.outlet) e.connections.outlet = m.outlet;
8621
+ if (map.type === "shower") e.connections.shower = m.showerHeater || { electric: false };
8622
+ if (map.type === "stove") {
8623
+ result.stoves.push(e.id);
8624
+ e.connections.gas = m.gas || "cylinder";
8625
+ e.connections.cylinder = m.cylinder || null;
8626
+ }
8627
+ if (map.type === "gas_bottle") result.cylinders.push({ id: e.id, stove: m.link || null, place: m.placement || null });
8628
+ if (map.type === "gas_canister") {
8629
+ result.canisters.push(e.id);
8630
+ if (campCylinder && campCylinder.id === m.id && campStove) result.cylinders.push({ id: e.id, stove: campStove.id, place: null });
8631
+ }
8632
+ if (map.type === "wood_stove") {
8633
+ const ch = chimneyOf(m, "stove");
8634
+ if (ch && chimneyHeight(ch)) {
8635
+ const f = (res.floors || []).find((x) => x.index === m.floor);
8636
+ const high = r3(chimneyHeight(ch) - (f ? f.y0 : 0) - (m.y || 0));
8637
+ item.h = high;
8638
+ item.flueHeight = high;
8639
+ }
8640
+ }
8641
+ if (map.type === "fireplace") planFireplace(m, e, item);
8642
+ if (map.type === "lantern_lamp") {
8643
+ e.lit = initialLanternLight(m.id, e);
8644
+ item.on = e.lit;
8645
+ result.lanterns.push(e.id);
8646
+ }
8647
+ if (map.type === "gas_bottle" && m.placement === "under_counter") hidden.push(e);
8648
+ push(e);
8649
+ }
8650
+ function planCompound(m, kind) {
8651
+ const ry = m.frontU != null ? K.ry(m.frontU, m.frontV) : r3(m.ry || 0);
8652
+ const cx = K.x(m.x);
8653
+ const cz = K.z(m.z);
8654
+ const part = (id, type, w, d, h, y, lx, lz) => {
8655
+ const [dx, dz] = K.off(ry, lx, lz);
8656
+ const item = baseItem(m);
8657
+ item.x = r3(cx + dx);
8658
+ item.z = r3(cz + dz);
8659
+ item.ry = ry;
8660
+ item.w = r3(w);
8661
+ item.d = r3(d);
8662
+ item.h = r3(h);
8663
+ item.y = y;
8664
+ item.seed = seedOf2(id);
8665
+ return entry2(id, type, item, m.id, m.floor);
8666
+ };
8667
+ const list2 = [];
8668
+ const overhead = contents[m.id + "#overhead"];
8669
+ if (kind === "rustic_sink") {
8670
+ const dd = Math.max(m.d, 0.56);
8671
+ const basin = part(m.id, "sink_kitchen", m.w, dd, m.h + 0.3, 0, 0, -(dd - m.d) / 2);
8672
+ list2.push(basin);
8673
+ const over = overhead || [];
8674
+ if (m.overhead !== false && over.length) {
8675
+ const wall = part(m.id + "#overhead", "kitchen_cabinet_wall", m.w, 0.35, 0.6, 1.55, 0, -(m.d / 2) + 0.175);
8676
+ store([["kitchen_cabinet_wall", wall.item]], over);
8677
+ list2.push(wall);
8678
+ }
8679
+ if (contents[m.id]) store([["sink_kitchen", basin.item]], contents[m.id]);
8680
+ if (m.outlet) basin.connections.outlet = m.outlet;
8681
+ } else if (kind === "sink") {
8682
+ const width = m.w;
8683
+ const basinW = width >= 1.5 ? 1 : Math.max(0.6, Math.min(0.8, width - 0.3));
8684
+ const rest = r3(width - basinW);
8685
+ const left = seedOf2(m.id) % 2 === 0;
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);
8687
+ list2.push(sink);
8688
+ let cabinet = null;
8689
+ if (rest >= 0.35) {
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);
8691
+ list2.push(cabinet);
8692
+ }
8693
+ if (contents[m.id]) store(cabinet ? [["kitchen_cabinet_base", cabinet.item], ["sink_kitchen", sink.item]] : [["sink_kitchen", sink.item]], contents[m.id]);
8694
+ if (m.overhead !== false) {
8695
+ const wall = part(m.id + "#overhead", "kitchen_cabinet_wall", width, 0.35, 0.6, 1.55, 0, -(m.d / 2) + 0.175);
8696
+ store([["kitchen_cabinet_wall", wall.item]], overhead || []);
8697
+ list2.push(wall);
8698
+ }
8699
+ if (m.outlet) sink.connections.outlet = m.outlet;
8700
+ } else {
8701
+ const basin = part(m.id, "sink_bathroom", m.w, m.d, m.h + 0.2, 0, 0, 0);
8702
+ list2.push(basin);
8703
+ if (contents[m.id]) {
8704
+ if (contents[m.id].length) {
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);
8706
+ list2.push(cabinet);
8707
+ store([["bathroom_cabinet", cabinet.item], ["sink_bathroom", basin.item]], contents[m.id]);
8708
+ } else {
8709
+ store([["sink_bathroom", basin.item]], []);
8710
+ }
8711
+ }
8712
+ }
8713
+ for (const e of list2) push(e);
8714
+ }
8715
+ function circuitOfLight(id) {
8716
+ const direct = circuits.find((c) => (c.lamps || []).indexOf(id) >= 0);
8717
+ if (direct) return direct.id;
8718
+ const sw = (electrical && electrical.switches || []).find((s) => (s.controls || []).indexOf(id) >= 0);
8719
+ const viaSwitch = sw && circuits.find((c) => (c.switches || []).indexOf(sw.id) >= 0);
8720
+ return viaSwitch ? viaSwitch.id : "standalone_circuit";
8721
+ }
8722
+ function planLamp(m, map) {
8723
+ const item = baseItem(m);
8724
+ delete item.palette;
8725
+ const e = entry2(m.id, "lamp", item, m.id, m.floor, { watts: map.watts });
8726
+ e.connections.circuit = circuitOfLight(m.id);
8727
+ e.lit = initialLight(res, popts, m.id, e);
8728
+ push(e);
8729
+ result.lights.push(e.id);
8730
+ }
8731
+ for (const m of res.items || []) {
8732
+ if (!onFloor(m.floor, m.outdoor)) continue;
8733
+ const map = typeMap[m.type];
8734
+ if (!map) {
8735
+ const k = m.category + "/" + m.type;
8736
+ result.unmapped[k] = (result.unmapped[k] || 0) + 1;
8737
+ continue;
8738
+ }
8739
+ result.mapped.push(m.id);
8740
+ if (map.type === "lamp") planLamp(m, map);
8741
+ else if (map.compound) planCompound(m, map.compound);
8742
+ else planSimple(m, map);
8743
+ }
8744
+ result.chairs = [];
8745
+ if (opts.chairs !== false && popts.chairs !== false) {
8746
+ const blocked = blockedOf(res, { originX: o.ox, originZ: o.oz, inw: o.inw });
8747
+ const floorKind = (q) => !q.decor && !q.flat && (q.y || 0) < 0.9 && q.aabb;
8748
+ const placed = [];
8749
+ const free = (m, cu, cv, half) => {
8750
+ const a = [cu - half + 0.03, cv - half + 0.03, cu + half - 0.03, cv + half - 0.03];
8751
+ for (const [dx, dz] of [[-1, -1], [1, -1], [-1, 1], [1, 1], [0, 0]]) if (blocked(K.x(cu + dx * half * 0.9), K.z(cv + dz * half * 0.9), m.floor)) return false;
8752
+ for (const q of res.items || []) {
8753
+ if (q === m || !floorKind(q) || q.floor !== m.floor && !(q.outdoor && m.outdoor)) continue;
8754
+ if (a[0] < q.aabb[2] && a[2] > q.aabb[0] && a[1] < q.aabb[3] && a[3] > q.aabb[1]) return false;
8755
+ }
8756
+ for (const c of placed) if (a[0] < c[2] && a[2] > c[0] && a[1] < c[3] && a[3] > c[1] && c[4] === m.floor) return false;
8757
+ placed.push([a[0], a[1], a[2], a[3], m.floor]);
8758
+ return true;
8759
+ };
8760
+ for (const m of res.items || []) {
8761
+ const mode = chairTables[m.type];
8762
+ if (!mode || !onFloor(m.floor, m.outdoor) || m.frontU == null) continue;
8763
+ const f = [m.frontU, m.frontV];
8764
+ const pp = [-m.frontV, m.frontU];
8765
+ const seats = [];
8766
+ if (mode === "dining") {
8767
+ const n = Math.max(1, Math.min(3, Math.floor((m.w - 0.1) / 0.55)));
8768
+ for (const side of [1, -1]) {
8769
+ for (let i = 0; i < n; i++) seats.push([(i - (n - 1) / 2) * (m.w / n), side * (m.d / 2 + 0.17), [-side * f[0], -side * f[1]]]);
8770
+ }
8771
+ if (m.w >= 1.6) for (const side of [1, -1]) seats.push([side * (m.w / 2 + 0.17), 0, [-side * pp[0], -side * pp[1]]]);
8772
+ } else {
8773
+ seats.push([0, m.d / 2 + 0.2, [-f[0], -f[1]]]);
8774
+ }
8775
+ seats.forEach((lg, i) => {
8776
+ const cu = r3(m.x + pp[0] * lg[0] + f[0] * lg[1]);
8777
+ const cv = r3(m.z + pp[1] * lg[0] + f[1] * lg[1]);
8778
+ const half = mode === "dining" ? chairSide / 2 : 0.3;
8779
+ if (!free(m, cu, cv, half)) return;
8780
+ const id = m.id + "#chair" + (i + 1);
8781
+ const item = { x: K.x(cu), z: K.z(cv), ry: K.ry(lg[2][0], lg[2][1]), seed: seedOf2(id), palette };
8782
+ if (mode !== "dining") {
8783
+ item.w = 0.6;
8784
+ item.d = 0.6;
8785
+ item.h = 0.95;
8786
+ }
8787
+ const e = push(entry2(id, mode === "dining" ? "dining_chair" : "armchair", item, m.id, m.floor));
8788
+ result.chairs.push(e.id);
8789
+ });
8790
+ }
8791
+ }
8792
+ function conduit(id, pts, floor) {
8793
+ const x0 = K.x(pts[0][0]);
8794
+ const z0 = K.z(pts[0][1]);
8795
+ const item = {
8796
+ x: x0,
8797
+ z: z0,
8798
+ ry: 0,
8799
+ seed: seedOf2(id),
8800
+ // the points of the plan already have the absolute y of the world: the object stays on the base ground and not on the floor of the storey
8801
+ points: pts.map((p) => [r3(K.x(p[0]) - x0), p[2], r3(K.z(p[1]) - z0)])
8802
+ };
8803
+ const e = entry2(id, "conduit_run", item, id, floor);
8804
+ e.floorY = o.base;
8805
+ push(e);
8806
+ result.conduits.push(e.id);
8807
+ }
8808
+ if (electrical) {
8809
+ for (const l of electrical.outdoorLamps || []) {
8810
+ if (!onFloor(-1, true)) continue;
8811
+ const e = entry2(l.id, "lamp", { x: K.x(l.u), z: K.z(l.v), ry: 0, y: l.y, seed: seedOf2(l.id) }, l.id, -1, { watts: 15 });
8812
+ e.connections.circuit = circuitOfLight(l.id);
8813
+ e.lit = initialLight(res, popts, l.id, e);
8814
+ push(e);
8815
+ result.lights.push(e.id);
8816
+ }
8817
+ for (const t of electrical.outlets || []) {
8818
+ if (!onFloor(t.floor, false)) continue;
8819
+ const c = circuits.find((x) => (x.outlets || []).indexOf(t.id) >= 0);
8820
+ const item = { x: K.x(t.u), z: K.z(t.v), ry: K.ry(t.frontU, t.frontV), y: t.y, seed: seedOf2(t.id) };
8821
+ if (c) item.circuit = c.id;
8822
+ const e = entry2(t.id, "wall_socket", item, t.id, t.floor);
8823
+ e.connections.circuit = c ? c.id : null;
8824
+ push(e);
8825
+ result.outlets.push(e.id);
8826
+ }
8827
+ const lights = new Set(result.lights);
8828
+ for (const s of electrical.switches || []) {
8829
+ if (!onFloor(s.floor, false)) continue;
8830
+ const item = { x: K.x(s.u), z: K.z(s.v), ry: K.ry(s.frontU, s.frontV), y: s.y, seed: seedOf2(s.id) };
8831
+ item.controls = (s.controls || []).map((id) => id + ":lamp");
8832
+ const e = entry2(s.id, "wall_switch", item, s.id, s.floor);
8833
+ e.connections.controls = (s.controls || []).slice();
8834
+ e.lit = e.connections.controls.some((id) => (result.items.find((x) => x.id === id) || {}).lit === true);
8835
+ if (floorSel == null) {
8836
+ for (const id of s.controls || []) if (!lights.has(id)) result.warnings.push(msg("warn.switchUnknownLamp", { id: s.id, lamp: id }));
8837
+ }
8838
+ push(e);
8839
+ result.switches.push(e.id);
8840
+ }
8841
+ const ee = electrical.serviceEntrance;
8842
+ if (ee && ee.pole && onFloor(-1, true)) {
8843
+ const drop = ee.drop || [];
8844
+ const end = drop.length ? drop[drop.length - 1] : [ee.pole.u, ee.pole.v, 2.6];
8845
+ const px = K.x(ee.pole.u);
8846
+ const pz = K.z(ee.pole.v);
8847
+ const item = {
8848
+ x: px,
8849
+ z: pz,
8850
+ ry: 0,
8851
+ h: ee.pole.h,
8852
+ seed: seedOf2("service_entrance"),
8853
+ // point where the drop reaches the house, in local coordinates of the pole (absolute y)
8854
+ house: [r3(K.x(end[0]) - px), end[2], r3(K.z(end[1]) - pz)]
8855
+ };
8856
+ if (ee.tap || electrical.mode === "tap") item.variant = "gato";
8857
+ const e = entry2("service_entrance", "service_entrance", item, "service_entrance", -1);
8858
+ push(e);
8859
+ result.serviceEntrance = e.id;
8860
+ if (ee.descent && ee.descent.length > 1) conduit("conduit_descent", ee.descent, -1);
8861
+ }
8862
+ const q = electrical.panel;
8863
+ if (q && onFloor(q.floor, false)) {
8864
+ const hdq = 0.06;
8865
+ const ryq = K.ry(q.frontU, q.frontV);
8866
+ const item = {
8867
+ x: r3(K.x(q.u) + Math.sin(ryq) * hdq),
8868
+ z: r3(K.z(q.v) + Math.cos(ryq) * hdq),
8869
+ ry: ryq,
8870
+ y: q.y,
8871
+ seed: seedOf2("panel"),
8872
+ circuits: circuits.map((c) => ({ id: c.id, label: c.room }))
8873
+ };
8874
+ if (!item.circuits.length) delete item.circuits;
8875
+ const e = entry2("panel", "electrical_panel", item, "panel", q.floor);
8876
+ push(e);
8877
+ result.panel = e.id;
8878
+ }
8879
+ const med = ee && ee.meter;
8880
+ if (med && onFloor(-1, true)) {
8881
+ const hdm = 0.08;
8882
+ const item = { x: K.x(med.u), z: r3(K.z(med.v) - o.inw * hdm), ry: K.ry(0, -1), y: med.y, seed: seedOf2("meter") };
8883
+ const e = entry2("meter", "power_meter", item, "meter", -1);
8884
+ push(e);
8885
+ result.meter = e.id;
8886
+ }
8887
+ for (const ed of electrical.conduits || []) {
8888
+ if (!ed.exposed || !ed.points || ed.points.length < 2) continue;
8889
+ const circ = circuits.find((c) => c.id === ed.circuit);
8890
+ const floor = circ ? circ.floor : 0;
8891
+ if (!onFloor(floor, false)) continue;
8892
+ conduit(ed.id, ed.points, floor);
8893
+ }
8894
+ }
8895
+ const piped = result.items.filter((e) => e.type === "stove" && e.connections.gas === "piped");
8896
+ if (piped.length) {
8897
+ const med = utilities.gas && utilities.gas.meter;
8898
+ const ref = med ? { x: K.x(med.u), z: K.z(med.v), y: med.y || 1 } : { x: piped[0].item.x, z: piped[0].item.z, y: 0.3 };
8899
+ const e = entry2("piped_gas", "gas_piped", { x: ref.x, z: ref.z, ry: 0, y: ref.y, seed: seedOf2("piped_gas") }, "piped_gas", piped[0].floor);
8900
+ e.floorY = o.base;
8901
+ push(e);
8902
+ for (const f of piped) f.connections.fuel = "piped_gas:gas";
8903
+ }
8904
+ for (const b of result.cylinders) {
8905
+ const stove = result.items.find((e) => e.id === b.stove);
8906
+ if (stove) stove.connections.fuel = b.id + ":gas";
8907
+ }
8908
+ const plumbing = utilities.plumbing;
8909
+ if (plumbing) {
8910
+ const isCabinet = (t) => t === "kitchen_cabinet_base" || t === "kitchen_cabinet_wall" || t === "bathroom_cabinet";
8911
+ for (const p of plumbing.points || []) {
8912
+ const target = (byOrigin.get(p.item) || []).filter((e) => !isCabinet(e.type))[0];
8913
+ if (!target) {
8914
+ if (floorSel == null) result.warnings.push(msg("warn.pointNoObject", { id: p.id, kind: p.kind, item: p.item }));
8915
+ continue;
8916
+ }
8917
+ target.point = p.id;
8918
+ target.connections.flowLpm = p.flowLpm;
8919
+ for (const f of fixturesOfPoint[p.kind] || []) {
8920
+ result.fixtures.push({ object: target.id, fixture: f, global: target.id + ":" + f, point: p.id, pointKind: p.kind });
8921
+ result.points[target.id + ":" + f] = p.id;
8922
+ }
8923
+ }
8924
+ }
8925
+ hideCylinders();
8926
+ return result;
8927
+ }
8928
+ function ownSpec(entry2) {
8929
+ if (entry2.type === "lamp") {
8930
+ const dev = { id: "lamp", kind: "lamp", watts: entry2.watts || 15, on: !!entry2.lit };
8931
+ if (entry2.connections.circuit) dev.circuit = entry2.connections.circuit;
8932
+ return { type: "lamp", devices: [dev] };
8933
+ }
8934
+ if (entry2.type === "gas_piped") return { type: "gas_piped", fuels: [{ id: "gas", kind: "gas", capacity: 1e3, level: 1e3 }] };
8935
+ throw new Error(msg("error.unknownOwnType", { type: entry2.type }));
8936
+ }
8937
+ function connect(entry2, spec) {
8938
+ const L = entry2.connections || {};
8939
+ if (entry2.type === "wall_switch") {
8940
+ for (const p of spec.parts || []) if (p.id === "rocker") p.t0 = entry2.lit ? 1 : 0;
8941
+ }
8942
+ if (entry2.type !== "shower") {
8943
+ for (const dv of spec.devices || []) if (L.outlet && dv.socket === "auto") dv.socket = L.outlet + ":socket";
8944
+ } else {
8945
+ const sh = L.shower || {};
8946
+ const heater = (spec.devices || []).find((d) => d.id === "heater");
8947
+ if (heater && sh.electric === false) {
8948
+ spec.devices = spec.devices.filter((d) => d !== heater);
8949
+ for (const f of spec.fixtures || []) if (f.heater === "heater") delete f.heater;
8950
+ } else if (heater) {
8951
+ if (sh.powerW) heater.watts = sh.powerW;
8952
+ if (L.outletCircuit) heater.circuit = L.outletCircuit;
8953
+ }
8954
+ }
8955
+ if ((entry2.type === "stove" || entry2.type === "camp_stove") && L.fuel) {
8956
+ for (const b of spec.burners || []) if (b.fuel === "auto") b.fuel = L.fuel;
8957
+ }
8958
+ if (entry2.type === "fireplace" && L.chimneyTop) {
8959
+ const it = entry2.item;
8960
+ const dx = L.chimneyTop[0] - it.x;
8961
+ const dz = L.chimneyTop[2] - it.z;
8962
+ const lx = Math.cos(it.ry) * dx - Math.sin(it.ry) * dz;
8963
+ const lz = Math.sin(it.ry) * dx + Math.cos(it.ry) * dz;
8964
+ for (const em of spec.emitters || []) if (em.kind === "smoke") em.pos = [r3(lx), r3(L.chimneyTop[1] - entry2.floorY + 0.02), r3(lz)];
8965
+ }
8966
+ if (entry2.type === "washing_machine" && entry2.point) {
8967
+ spec.fixtures = spec.fixtures || [];
8968
+ const inlet = spec.fixtures.find((f) => f.id === "inlet");
8969
+ if (inlet) {
8970
+ if (L.flowLpm) inlet.flow = L.flowLpm;
8971
+ inlet.tank = "auto";
8972
+ } else {
8973
+ spec.fixtures.push({ id: "inlet", kind: "hose", outlet: [0, 0.3, -(entry2.item.d || 0.6) / 2], flow: L.flowLpm || 8, tank: "auto" });
8974
+ }
8975
+ }
8976
+ return spec;
8977
+ }
8978
+ function createWorld(res, copts = {}) {
8979
+ copts = copts || {};
8980
+ const info = { points: /* @__PURE__ */ new Map(), water: copts.water || null, lightsOn: copts.lightsOn };
8981
+ const electrical = res.utilities && res.utilities.electrical;
8982
+ const world = GI.createWorld({
8983
+ locale,
8984
+ strings: hh.strings,
8985
+ items: hh.items,
8986
+ loot: hh.loot,
8987
+ seed: copts.seed != null ? copts.seed : res.seed,
8988
+ // no grid: the cabin and the off-grid campsite have no service entrance, sockets or electric lamps (lanterns do not need a grid)
8989
+ grid: copts.grid != null ? !!copts.grid : !!electrical && electrical.mode !== "offgrid",
8990
+ onEvent: copts.onEvent,
8991
+ canInteract: copts.canInteract,
8992
+ waterSupply: {
8993
+ draw(fixtureId, l) {
8994
+ if (!info.water) return l;
8995
+ const point = info.points.get(fixtureId);
8996
+ return point == null ? l : info.water.consume(point, l);
8997
+ }
8998
+ }
8999
+ });
9000
+ worlds.set(world, info);
9001
+ return world;
9002
+ }
9003
+ function pointOf(world, fixtureId) {
9004
+ const info = worlds.get(world);
9005
+ return info ? info.points.get(fixtureId) : void 0;
9006
+ }
9007
+ function blockedOf(res, bopts = {}) {
9008
+ bopts = bopts || {};
9009
+ const ox = bopts.originX || 0;
9010
+ const oz = bopts.originZ || 0;
9011
+ const inw = bopts.inw || 1;
9012
+ const margin = bopts.margin != null ? bopts.margin : 0.02;
9013
+ const segs = (res.walls || []).map((p) => {
9014
+ const e = Math.max(0, p.thickness / 2 - margin);
9015
+ const u0 = Math.min(p.u0, p.u1) - (p.axis === "u" ? 0 : e);
9016
+ const u1 = Math.max(p.u0, p.u1) + (p.axis === "u" ? 0 : e);
9017
+ const v0 = Math.min(p.v0, p.v1) - (p.axis === "v" ? 0 : e);
9018
+ const v1 = Math.max(p.v0, p.v1) + (p.axis === "v" ? 0 : e);
9019
+ const za = oz + inw * v0;
9020
+ const zb = oz + inw * v1;
9021
+ return { floor: p.floor, x0: ox + u0, x1: ox + u1, z0: Math.min(za, zb), z1: Math.max(za, zb) };
9022
+ });
9023
+ const CELL2 = 0.5;
9024
+ const grid = /* @__PURE__ */ new Map();
9025
+ const key = (a, i, j) => (a * 4096 + (i + 2048)) * 4096 + (j + 2048);
9026
+ for (const s of segs) {
9027
+ for (let i = Math.floor(s.x0 / CELL2); i <= Math.floor(s.x1 / CELL2); i++) {
9028
+ for (let j = Math.floor(s.z0 / CELL2); j <= Math.floor(s.z1 / CELL2); j++) {
9029
+ const k = key(s.floor, i, j);
9030
+ if (!grid.has(k)) grid.set(k, []);
9031
+ grid.get(k).push(s);
9032
+ }
9033
+ }
9034
+ }
9035
+ return function blocked(x, z, floor) {
9036
+ const a = floor == null || floor < 0 ? 0 : floor;
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;
9040
+ return false;
9041
+ };
9042
+ }
9043
+ function add(world, planned, aopts = {}) {
9044
+ aopts = aopts || {};
9045
+ const info = worlds.get(world);
9046
+ const build = aopts.build || ((type, item) => hh.build(type, item, HH.createRecorder().api));
9047
+ const isBlocked = aopts.isBlocked || null;
9048
+ const out = { added: 0, parts: [], hinges: {}, moved: {}, warnings: [] };
9049
+ const override = aopts.lightsOn !== void 0 ? aopts.lightsOn : info && info.lightsOn;
9050
+ if (override !== void 0) {
9051
+ for (const e of planned.items) if (e.type === "lamp") e.lit = typeof override === "function" ? !!override(e.id, e) : !!override;
9052
+ for (const e of planned.items) if (e.type === "lantern_lamp") e.lit = typeof override === "function" ? !!override(e.id, e) : !!override;
9053
+ for (const e of planned.items) if (e.type === "wall_switch") e.lit = (e.connections.controls || []).some((id) => (planned.items.find((x) => x.id === id) || {}).lit === true);
9054
+ }
9055
+ for (const e of planned.items) if (e.type === "lantern_lamp") e.item.on = !!e.lit;
9056
+ let scratch = null;
9057
+ function probe(e, hinge, setback) {
9058
+ if (!scratch) scratch = GI.createWorld({ locale, strings: hh.strings, items: hh.items, loot: hh.loot, grid: false });
9059
+ const it = e.item;
9060
+ const x = it.x + Math.sin(it.ry) * setback;
9061
+ const z = it.z + Math.cos(it.ry) * setback;
9062
+ const spec = hh.build(e.type, Object.assign({}, it, { hinge }), HH.createRecorder().api);
9063
+ scratch.add("__probe", spec, { x, y: e.floorY, z, ry: it.ry });
9064
+ const blocks = (px, pz) => isBlocked(px, pz, e.floor);
9065
+ let sum = 0;
9066
+ let min = 1;
9067
+ let n = 0;
9068
+ for (const p of spec.parts || []) {
9069
+ if (p.motion.kind !== "hinge" || !(p.bounds || p.sweep)) continue;
9070
+ const t = scratch.fitSweep("__probe", p.id, blocks);
9071
+ sum += t;
9072
+ min = Math.min(min, t);
9073
+ n++;
9074
+ }
9075
+ scratch.remove("__probe");
9076
+ return { sum, min, n };
9077
+ }
9078
+ const better = (a, b) => a.sum > b.sum + 1e-9 || Math.abs(a.sum - b.sum) <= 1e-9 && a.min > b.min + 1e-9;
9079
+ function fitDoors(e) {
9080
+ if (!isBlocked || !householdTypes.has(e.type)) return;
9081
+ const standard = probe(e, void 0, 0);
9082
+ if (!standard.n || standard.min >= 1) return;
9083
+ let bestSide;
9084
+ let m = standard;
9085
+ for (const side of ["left", "right"]) {
9086
+ const r = probe(e, side, 0);
9087
+ if (better(r, m)) {
9088
+ m = r;
9089
+ bestSide = side;
9090
+ }
9091
+ }
9092
+ if (bestSide) {
9093
+ e.item.hinge = bestSide;
9094
+ out.hinges[e.id] = bestSide;
9095
+ }
9096
+ if (m.min >= 1) return;
9097
+ let target = { setback: 0, r: m };
9098
+ for (const setback of [0.01, 0.02, 0.03, 0.04]) {
9099
+ const r = probe(e, bestSide, setback);
9100
+ if (better(r, target.r)) target = { setback, r };
9101
+ if (r.min >= 1) break;
9102
+ }
9103
+ if (target.setback > 0 && target.r.sum > m.sum + 0.2) {
9104
+ e.item.x = r3(e.item.x + Math.sin(e.item.ry) * target.setback);
9105
+ e.item.z = r3(e.item.z + Math.cos(e.item.ry) * target.setback);
9106
+ e.moved = target.setback;
9107
+ out.moved[e.id] = target.setback;
9108
+ }
9109
+ }
9110
+ for (const e of planned.items) {
9111
+ if (e.type !== "shower" || !e.connections.outlet) continue;
9112
+ const t = planned.items.find((x) => x.id === e.connections.outlet);
9113
+ if (t && t.connections.circuit) e.connections.outletCircuit = t.connections.circuit;
9114
+ }
9115
+ for (const e of planned.items) {
9116
+ let spec;
9117
+ if (ownTypes[e.type]) {
9118
+ spec = ownSpec(e);
9119
+ } else {
9120
+ fitDoors(e);
9121
+ spec = build(e.type, e.item);
9122
+ if (!spec) {
9123
+ out.warnings.push(msg("warn.buildEmpty", { id: e.id }));
9124
+ continue;
9125
+ }
9126
+ }
9127
+ connect(e, spec);
9128
+ world.add(e.id, spec, { x: e.item.x, y: e.floorY, z: e.item.z, ry: e.item.ry });
9129
+ out.added++;
9130
+ if (!isBlocked) continue;
9131
+ for (const p of spec.parts || []) {
9132
+ if (!(p.bounds || p.sweep)) continue;
9133
+ const t = world.fitSweep(e.id, p.id, (x, z) => isBlocked(x, z, e.floor));
9134
+ if (t < 1) out.parts.push({ object: e.id, part: p.id, t });
9135
+ }
9136
+ }
9137
+ if (info) for (const f of planned.fixtures) info.points.set(f.global, f.point);
9138
+ return out;
9139
+ }
9140
+ return { version: ADAPTER_VERSION, household: hh, plan, createWorld, add, blockedOf, pointOf, ownSpec, registries: { typeMap, contentMap, contentByGroup, chairTables, fixturesOfPoint, substitutes, preference, ownTypes } };
9141
+ }
9142
+ var FloorplanInteractables = { version: ADAPTER_VERSION, create: create2, TYPE_MAP, CONTENT_MAP, CONTENT_BY_GROUP, CHAIR_TABLES, PREFERENCE, mergeRegistry };
9143
+
7526
9144
  // src/interactables/kit.ts
7527
9145
  function installInteractablesKit(K, shared) {
7528
9146
  const { t, THREE, DOC, cfg, Reflector } = K;
@@ -7530,12 +9148,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7530
9148
  const IVK = (() => {
7531
9149
  const o = cfg.interactives;
7532
9150
  if (!o) return null;
7533
- const GI = o.GameInteractables || null, HH = o.GameInteractablesHousehold || null, GT = o.GameInteractablesThree || null, AD = o.adapter || null;
7534
- if (!GI || !HH || !GT || !AD) {
9151
+ const GI = o.GameInteractables || null, HH = o.GameInteractablesHousehold || null, GT = o.GameInteractablesThree || null, AD = o.adapter || FloorplanInteractables;
9152
+ if (!GI || !HH || !GT) {
7535
9153
  console.warn(t("warn.interactablesIncomplete"));
7536
9154
  return null;
7537
9155
  }
7538
- const A = AD.plan ? AD : AD.create({ GameInteractables: GI, GameInteractablesHousehold: HH, locale: o.locale, region: o.region });
9156
+ const A = AD.plan ? AD : AD.create({ ...o.adapterOptions || {}, GameInteractables: GI, GameInteractablesHousehold: HH, locale: o.locale || cfg.locale, region: o.region, ...cfg.seedKey ? { seedKey: cfg.seedKey } : {} });
7539
9157
  return { GI, HH, GT, A, gfx: GT.createThreeAdapter(THREE, { document: DOC, Reflector }), items: o.items !== false, effects: o.effects !== false, camera: o.camera || null, onEvent: o.onEvent || null, onSeat: o.onSeat || null };
7540
9158
  })();
7541
9159
  const VEG = (() => {
@@ -7636,13 +9254,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7636
9254
  }
7637
9255
  for (const g of by.values()) {
7638
9256
  const ls = g.ls, n = ls.length;
7639
- let cx = 0, cy = 0, cz = 0, range = 0;
9257
+ let cx = 0, cy = 0, cz = 0, range2 = 0;
7640
9258
  for (const l of ls) {
7641
9259
  _p.set(l.x, l.y, l.z).applyMatrix4(M);
7642
9260
  cx += _p.x;
7643
9261
  cy += _p.y;
7644
9262
  cz += _p.z;
7645
- range = Math.max(range, l.range || 5);
9263
+ range2 = Math.max(range2, l.range || 5);
7646
9264
  }
7647
9265
  cx /= n;
7648
9266
  cy /= n;
@@ -7650,7 +9268,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
7650
9268
  g.pos = [cx, cy, cz];
7651
9269
  g.color = ls[0].color;
7652
9270
  g.n = n;
7653
- g.range = range;
9271
+ g.range = range2;
7654
9272
  if (g.exterior) {
7655
9273
  g.rects = [[cx - 7, cz - 7, cx + 7, cz + 7]];
7656
9274
  g.y = [cy - 3.2, cy + 4];
@@ -8923,8 +10541,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
8923
10541
  const resting = /* @__PURE__ */ new Map();
8924
10542
  const carrying = /* @__PURE__ */ new Map();
8925
10543
  const push = (map, key, value) => {
8926
- const list = map.get(key);
8927
- if (list) list.push(value);
10544
+ const list2 = map.get(key);
10545
+ if (list2) list2.push(value);
8928
10546
  else map.set(key, [value]);
8929
10547
  };
8930
10548
  for (const support of supports) {
@@ -8980,7 +10598,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
8980
10598
  if (!splits.size) return input;
8981
10599
  const boxes = new Map(input.parts.map((part) => [part.id, part.aabb]));
8982
10600
  const pieceBox = /* @__PURE__ */ new Map();
8983
- 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);
8984
10602
  const parts = input.parts.flatMap((part) => splits.get(part.id)?.pieces ?? [part]);
8985
10603
  const supports = [];
8986
10604
  for (const support of input.supports) {
@@ -9028,12 +10646,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
9028
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 });
9029
10647
  }
9030
10648
  const total = cells.reduce((sum, cell) => sum + (cell.to - cell.from) * (cell.y1 - cell.y0), 0);
9031
- 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];
9032
10650
  const pieces = cells.map((cell, index) => ({
9033
10651
  id: `${wall.id}_${spec.unitLength ? "u" : "log"}${cell.row}_${index}`,
9034
10652
  role: wall.role,
9035
10653
  material: wall.material,
9036
- aabb: box(cell),
10654
+ aabb: box2(cell),
9037
10655
  y0: cell.y0,
9038
10656
  y1: cell.y1,
9039
10657
  floor: wall.floor,
@@ -9159,9 +10777,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
9159
10777
  const capacity = input.capacities.get(id);
9160
10778
  capacities.delete(id);
9161
10779
  if (capacity === void 0) continue;
9162
- 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]);
9163
10781
  const length = along(input.parts.find((part) => part.id === id).aabb);
9164
- 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));
9165
10783
  }
9166
10784
  return { ...next, capacities };
9167
10785
  }
@@ -9438,7 +11056,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
9438
11056
  const per = Math.max(1, Math.round(len / ul));
9439
11057
  const w = len / per;
9440
11058
  const edge = fragmentMaterial(part.material).color.getHex();
9441
- const list = [];
11059
+ const list2 = [];
9442
11060
  for (let r = 0; r < rows; r++) {
9443
11061
  const shift = units.bond === "running" && r & 1 ? w / 2 : 0;
9444
11062
  const cells = per + (shift ? 1 : 0);
@@ -9453,10 +11071,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
9453
11071
  const y = part.y0 + (r + 0.5) * rowH;
9454
11072
  const d = Math.hypot(x - opening.center[0], y - opening.center[1], z - opening.center[2]);
9455
11073
  if (d < opening.radius) continue;
9456
- 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 });
9457
11075
  }
9458
11076
  }
9459
- return list;
11077
+ return list2;
9460
11078
  }
9461
11079
  function open(event) {
9462
11080
  if (lod !== 0 || views.has(event.part) || !event.opening) return false;
@@ -9465,27 +11083,27 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
9465
11083
  if (!part || !spec || !spec.units) return false;
9466
11084
  const items = structure.meshesOf(event.part).filter((it) => it.mesh);
9467
11085
  if (!items.length) return false;
9468
- const list = courses(part, spec.units, event.opening, wallColour(items));
9469
- 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));
9470
11088
  mesh.name = "breach:" + event.part;
9471
- list.forEach((u, i) => {
11089
+ list2.forEach((u, i) => {
9472
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));
9473
11091
  mesh.setMatrixAt(i, tmp.m);
9474
11092
  mesh.setColorAt(i, tmp.c.setHex(u.colour));
9475
11093
  });
9476
- mesh.count = list.length;
11094
+ mesh.count = list2.length;
9477
11095
  mesh.instanceMatrix.needsUpdate = true;
9478
11096
  if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true;
9479
11097
  mesh.castShadow = true;
9480
11098
  mesh.receiveShadow = true;
9481
11099
  house.add(mesh);
9482
11100
  const saved = items.map((it) => ({ it, v0: it.v0, data: collapseRange(it.mesh, it.v0, it.v1) }));
9483
- 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 });
9484
11102
  invalidate();
9485
11103
  invalidateShadow();
9486
11104
  return true;
9487
11105
  }
9488
- function plain(view, shown) {
11106
+ function plain2(view, shown) {
9489
11107
  for (const s of view.saved) {
9490
11108
  if (shown) restoreRange(s.it.mesh, s.v0, s.data);
9491
11109
  else s.data = collapseRange(s.it.mesh, s.v0, s.it.v1);
@@ -9511,7 +11129,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
9511
11129
  if (was === 0 === (level === 0)) return;
9512
11130
  for (const v of views.values()) {
9513
11131
  v.mesh.visible = level === 0;
9514
- plain(v, level !== 0);
11132
+ plain2(v, level !== 0);
9515
11133
  }
9516
11134
  invalidate();
9517
11135
  invalidateShadow();
@@ -9521,7 +11139,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
9521
11139
  for (const v of views.values()) {
9522
11140
  v.mesh.removeFromParent();
9523
11141
  v.mesh.dispose();
9524
- if (lod === 0) plain(v, true);
11142
+ if (lod === 0) plain2(v, true);
9525
11143
  }
9526
11144
  views.clear();
9527
11145
  },
@@ -9628,7 +11246,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
9628
11246
  };
9629
11247
  D.dropPiece = (id) => {
9630
11248
  if (hiddenPieces.has(id) || bodies.has(id)) return;
9631
- const list = [], rr = rngString(id);
11249
+ const list2 = [], rr = rngString(id);
9632
11250
  for (const it of structure.meshesOf(id)) {
9633
11251
  if (it.obj) {
9634
11252
  hide(it);
@@ -9637,10 +11255,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
9637
11255
  const m = extract(it);
9638
11256
  hide(it);
9639
11257
  const hy = (m.geometry.boundingBox.max.y - m.geometry.boundingBox.min.y) / 2;
9640
- 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 });
9641
11259
  }
9642
11260
  hiddenPieces.add(id);
9643
- if (list.length) bodies.set(id, list);
11261
+ if (list2.length) bodies.set(id, list2);
9644
11262
  invalidate();
9645
11263
  invalidateShadow();
9646
11264
  };
@@ -9812,8 +11430,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
9812
11430
  D.animate = (dt) => {
9813
11431
  if (R) return;
9814
11432
  let moved = false;
9815
- for (const [id, list] of bodies) {
9816
- for (const b of list) {
11433
+ for (const [id, list2] of bodies) {
11434
+ for (const b of list2) {
9817
11435
  if (b.landing) continue;
9818
11436
  moved = true;
9819
11437
  b.vy -= 9.8 * dt;
@@ -9829,10 +11447,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
9829
11447
  b.landing = true;
9830
11448
  }
9831
11449
  }
9832
- if (!list.impacted && list.every((b) => b.landing)) {
9833
- list.impacted = true;
11450
+ if (!list2.impacted && list2.every((b) => b.landing)) {
11451
+ list2.impacted = true;
9834
11452
  const ps = D.active ? D.world.part(D.id, id) : null;
9835
- const b = list[0];
11453
+ const b = list2[0];
9836
11454
  if (ps && ps.status !== "broken") {
9837
11455
  const h = Math.max(0.5, b.y0 - b.hy), c = worldPoint(b.mesh.parent, b.mesh.position);
9838
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" });
@@ -10413,7 +12031,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10413
12031
 
10414
12032
  // src/create.ts
10415
12033
  var VERSION = "1.0.0";
10416
- function create2(THREE, options = {}) {
12034
+ function create3(THREE, options = {}) {
10417
12035
  const cfg = Object.assign({}, options || {});
10418
12036
  const DOC = cfg.document || (typeof document !== "undefined" ? document : null);
10419
12037
  const PROPS = cfg.props || dist_exports;
@@ -10763,20 +12381,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
10763
12381
  const g = c.grids[floor];
10764
12382
  if (!g) return 0;
10765
12383
  let x0, z0, x1, z1;
10766
- const circle = "circle" in shape ? shape.circle : null;
10767
- if (circle) {
10768
- x0 = circle[0] - circle[2];
10769
- z0 = circle[1] - circle[2];
10770
- x1 = circle[0] + circle[2];
10771
- 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];
10772
12390
  } else [x0, z0, x1, z1] = shape.rect;
10773
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));
10774
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));
10775
12393
  let n = 0;
10776
12394
  for (let j = j0; j <= j1; j++) for (let i = i0; i <= i1; i++) {
10777
- if (circle) {
10778
- const dx = c.ox + (i + 0.5) * CELL - circle[0], dz = c.oz + (j + 0.5) * CELL - circle[1];
10779
- 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;
10780
12398
  }
10781
12399
  fn(g, j * c.nx + i);
10782
12400
  n++;
@@ -11013,11 +12631,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
11013
12631
  };
11014
12632
  const role = (p) => p.structure && p.structure.role;
11015
12633
  const events = (room) => {
11016
- const list = [];
11017
- room.world.on("*", (e) => list.push(e));
11018
- return list;
12634
+ const list2 = [];
12635
+ room.world.on("*", (e) => list2.push(e));
12636
+ return list2;
11019
12637
  };
11020
- 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));
11021
12639
  const whole = (room, oid, pid) => {
11022
12640
  const p = room.world.part(oid, pid);
11023
12641
  return !!p && p.status !== "broken" && !p.stripped;
@@ -11036,14 +12654,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
11036
12654
  name: text.scenarios.house_one_pillar,
11037
12655
  run({ room, step, expect }) {
11038
12656
  const { oid, parts, centre } = spawn(room, "house_casa_portico");
11039
- const list = events(room);
12657
+ const list2 = events(room);
11040
12658
  const columns = groundColumns(parts);
11041
12659
  const laj = slabs(parts);
11042
12660
  blunt(room, oid, columns[0].id, centre(columns[0].id), 3e6);
11043
12661
  step(20);
11044
12662
  expect(!whole(room, oid, columns[0].id), fill(T2.one_pillar_broke, { id: columns[0].id }));
11045
12663
  expect(laj.length > 0 && laj.every((id) => whole(room, oid, id)), T2.slabs_whole);
11046
- 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);
11047
12665
  }
11048
12666
  },
11049
12667
  {
@@ -11051,17 +12669,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
11051
12669
  name: text.scenarios.house_two_pillars,
11052
12670
  run({ room, step, expect }) {
11053
12671
  const { oid, parts, centre } = spawn(room, "house_casa_portico");
11054
- const list = events(room);
12672
+ const list2 = events(room);
11055
12673
  const columns = groundColumns(parts);
11056
12674
  const laj = slabs(parts);
11057
12675
  blunt(room, oid, columns[0].id, centre(columns[0].id), 3e6);
11058
12676
  blunt(room, oid, columns[1].id, centre(columns[1].id), 3e6);
11059
12677
  step(90);
11060
- 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++) {
11061
12679
  blunt(room, oid, columns[next].id, centre(columns[next].id), 3e6);
11062
12680
  step(90);
11063
12681
  }
11064
- const fell = collapsed(list);
12682
+ const fell = collapsed(list2);
11065
12683
  expect(laj.some((id) => fell.includes(id)), fill(T2.two_slab_fell, { n: fell.length }));
11066
12684
  expect(parts.filter((p) => role(p) === "roof").some((p) => fell.includes(p.id)), T2.two_roof_fell);
11067
12685
  }
@@ -11071,13 +12689,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
11071
12689
  name: text.scenarios.house_partition,
11072
12690
  run({ room, step, expect }) {
11073
12691
  const { oid, parts, centre } = spawn(room, "house_casa_inteira");
11074
- const list = events(room);
12692
+ const list2 = events(room);
11075
12693
  const partition = parts.find((p) => role(p) === "partition");
11076
12694
  const laj = slabs(parts);
11077
12695
  blunt(room, oid, partition.id, centre(partition.id), 3e6);
11078
12696
  step(20);
11079
12697
  expect(!whole(room, oid, partition.id), fill(T2.partition_broke, { id: partition.id }));
11080
- 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);
11081
12699
  }
11082
12700
  },
11083
12701
  {
@@ -11116,12 +12734,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
11116
12734
  name: text.scenarios.house_gas_explodes,
11117
12735
  run({ room, step, expect }) {
11118
12736
  const { oid, parts, centre } = spawn(room, "house_casa_inteira");
11119
- const list = events(room);
12737
+ const list2 = events(room);
11120
12738
  const bottle = parts.find((p) => p.explodes);
11121
12739
  room.world.hitPart(oid, bottle.id, { type: "fire", point: centre(bottle.id), temperature: 900, radius: 0.6, duration: 8 });
11122
12740
  step(12);
11123
- expect(list.filter((e) => e.type === "explode").length > 0, T2.gas_exploded);
11124
- 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");
11125
12743
  expect(damage.length > 0, fill(T2.gas_damaged, { n: new Set(damage.map((e) => e.part)).size }));
11126
12744
  }
11127
12745
  }
@@ -11162,7 +12780,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
11162
12780
  let made = byId.get(key);
11163
12781
  if (!made) {
11164
12782
  const plan = engine.generate(def.template, { seed: def.seed ?? 1, ...def.state ? { state: def.state } : {} });
11165
- const house = create2(THREE, { ...houseOptions, destruction: void 0, destructionRenderer: void 0, interactives: void 0, vegetation: void 0, fleet: null }).build(plan, { quality: "game", terrain: false, noPerimeter: true });
12783
+ const house = create3(THREE, { ...houseOptions, destruction: void 0, destructionRenderer: void 0, interactives: void 0, vegetation: void 0, fleet: null }).build(plan, { quality: "game", terrain: false, noPerimeter: true });
11166
12784
  const spec = house.structure.spec({ wallDetail: "coarse", ...def.portico ? { portico: true } : {} });
11167
12785
  house.dispose();
11168
12786
  made = { spec, plan };
@@ -11258,7 +12876,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
11258
12876
  const key = `${settings.quality}|${locale}`;
11259
12877
  if (!houseRenderer || houseRendererKey !== key) {
11260
12878
  houseRenderer?.dispose?.();
11261
- houseRenderer = create2(THREE, {
12879
+ houseRenderer = create3(THREE, {
11262
12880
  locale,
11263
12881
  lod: { interior: 10, hide: 40 },
11264
12882
  ...options.house,
@@ -11588,7 +13206,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
11588
13206
  for (const group of groups) {
11589
13207
  for (const id of group.templates) {
11590
13208
  const plan = engine.generate(id, { seed: 1 });
11591
- const house = create2(THREE ?? host?.THREE, { locale, ...options.house, destruction: void 0, destructionRenderer: void 0, interactives: void 0, vegetation: void 0, fleet: null }).build(plan, { quality: "game", terrain: false, noPerimeter: true });
13209
+ const house = create3(THREE ?? host?.THREE, { locale, ...options.house, destruction: void 0, destructionRenderer: void 0, interactives: void 0, vegetation: void 0, fleet: null }).build(plan, { quality: "game", terrain: false, noPerimeter: true });
11592
13210
  const ok = house.structure.parts.length > 0 && house.floors.length >= 1 && house.colliders.length > 0;
11593
13211
  expect(ok, `${groupName(group)}: ${templateName(id)} (${house.structure.parts.length})`);
11594
13212
  house.dispose();