@adatechnology/game-crowd-three 0.2.0 → 0.3.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.
@@ -989,6 +989,379 @@ var GameCrowdThree = (() => {
989
989
  var RED = 8000012;
990
990
  var BLOOD_COLORS = [10361618, 7214096, 4860440, 1840658];
991
991
  var OLD_HAIR = 9078656;
992
+ var pose_clips_default = {
993
+ clips: [
994
+ {
995
+ id: "grabbed_bitten_human",
996
+ source: {
997
+ file: "site/pages/zumbis-personagens/bestiario.html",
998
+ scene: "ataque (Agarr\xE3o e mordida)",
999
+ variable: "HK"
1000
+ },
1001
+ duration: 8,
1002
+ loop: false,
1003
+ channels: "full",
1004
+ keys: [
1005
+ {
1006
+ t: 0,
1007
+ pose: {
1008
+ lean: 0,
1009
+ headY: 0,
1010
+ armL: -0.1,
1011
+ armR: 0.05,
1012
+ elbL: -0.2,
1013
+ elbR: -0.2,
1014
+ drop: 0,
1015
+ kneeL: 0.05,
1016
+ kneeR: 0.05,
1017
+ legL: -0.05,
1018
+ legR: 0.05,
1019
+ headX: 0
1020
+ }
1021
+ },
1022
+ {
1023
+ t: 1.5,
1024
+ pose: {
1025
+ lean: -0.1,
1026
+ headY: -0.6,
1027
+ armL: -0.1,
1028
+ armR: 0.05,
1029
+ elbL: -0.2,
1030
+ elbR: -0.2,
1031
+ drop: 0,
1032
+ kneeL: 0.05,
1033
+ kneeR: 0.05,
1034
+ legL: -0.05,
1035
+ legR: 0.05,
1036
+ headX: -0.1
1037
+ }
1038
+ },
1039
+ {
1040
+ t: 2.1,
1041
+ pose: {
1042
+ lean: -0.3,
1043
+ headY: -0.2,
1044
+ armL: -1.3,
1045
+ armR: -1.2,
1046
+ elbL: -1.4,
1047
+ elbR: -1.5,
1048
+ drop: -0.04,
1049
+ kneeL: 0.25,
1050
+ kneeR: 0.2,
1051
+ legL: -0.3,
1052
+ legR: 0.25,
1053
+ headX: -0.25
1054
+ }
1055
+ },
1056
+ {
1057
+ t: 3.6,
1058
+ pose: {
1059
+ lean: -0.35,
1060
+ headY: 0.3,
1061
+ armL: -1.5,
1062
+ armR: -1,
1063
+ elbL: -0.6,
1064
+ elbR: -1.8,
1065
+ drop: -0.05,
1066
+ kneeL: 0.3,
1067
+ kneeR: 0.2,
1068
+ legL: -0.4,
1069
+ legR: 0.35,
1070
+ headX: -0.2
1071
+ }
1072
+ },
1073
+ {
1074
+ t: 4.3,
1075
+ pose: {
1076
+ lean: -0.2,
1077
+ headY: 0.7,
1078
+ headZ: -0.5,
1079
+ armL: -0.6,
1080
+ armR: -1.9,
1081
+ elbL: -0.4,
1082
+ elbR: -1.2,
1083
+ drop: -0.06,
1084
+ kneeL: 0.3,
1085
+ kneeR: 0.3,
1086
+ legL: -0.3,
1087
+ legR: 0.3,
1088
+ headX: -0.3
1089
+ }
1090
+ },
1091
+ {
1092
+ t: 5.6,
1093
+ pose: {
1094
+ lean: 0.55,
1095
+ headY: 0.4,
1096
+ headZ: -0.3,
1097
+ armL: -0.3,
1098
+ armR: -0.5,
1099
+ elbL: -0.6,
1100
+ elbR: -0.8,
1101
+ drop: -0.5,
1102
+ kneeL: 1.9,
1103
+ kneeR: 1.7,
1104
+ legL: -1.1,
1105
+ legR: -0.9,
1106
+ headX: 0.3
1107
+ }
1108
+ },
1109
+ {
1110
+ t: 8,
1111
+ pose: {
1112
+ lean: 0.6,
1113
+ headY: 0.4,
1114
+ headZ: -0.3,
1115
+ armL: -0.25,
1116
+ armR: -0.45,
1117
+ elbL: -0.6,
1118
+ elbR: -0.8,
1119
+ drop: -0.52,
1120
+ kneeL: 1.95,
1121
+ kneeR: 1.75,
1122
+ legL: -1.1,
1123
+ legR: -0.95,
1124
+ headX: 0.4
1125
+ }
1126
+ }
1127
+ ],
1128
+ events: [
1129
+ {
1130
+ t: 0,
1131
+ type: "phase",
1132
+ data: {
1133
+ label: "pose_clip.grab_bite.phase.approach"
1134
+ }
1135
+ },
1136
+ {
1137
+ t: 1.7,
1138
+ type: "phase",
1139
+ data: {
1140
+ label: "pose_clip.grab_bite.phase.pounce"
1141
+ }
1142
+ },
1143
+ {
1144
+ t: 2.1,
1145
+ type: "phase",
1146
+ data: {
1147
+ label: "pose_clip.grab_bite.phase.grab"
1148
+ }
1149
+ },
1150
+ {
1151
+ t: 4.3,
1152
+ type: "phase",
1153
+ data: {
1154
+ label: "pose_clip.grab_bite.phase.bite"
1155
+ }
1156
+ },
1157
+ {
1158
+ t: 5.6,
1159
+ type: "phase",
1160
+ data: {
1161
+ label: "pose_clip.grab_bite.phase.fall"
1162
+ }
1163
+ },
1164
+ {
1165
+ t: 4.4,
1166
+ type: "impact",
1167
+ data: {
1168
+ kind: "bite",
1169
+ source: "bite.visible=T>4.4 in the scene's step()"
1170
+ }
1171
+ }
1172
+ ]
1173
+ },
1174
+ {
1175
+ id: "grab_bite_zombie",
1176
+ source: {
1177
+ file: "site/pages/zumbis-personagens/bestiario.html",
1178
+ scene: "ataque (Agarr\xE3o e mordida)",
1179
+ variable: "ZK"
1180
+ },
1181
+ duration: 8,
1182
+ loop: false,
1183
+ channels: "full",
1184
+ keys: [
1185
+ {
1186
+ t: 0,
1187
+ pose: {
1188
+ x: -6,
1189
+ lean: 0.75,
1190
+ armL: -1.35,
1191
+ armR: -1.05,
1192
+ elbL: -0.08,
1193
+ elbR: -0.12,
1194
+ headX: -0.55,
1195
+ drop: -0.1,
1196
+ run: 1
1197
+ }
1198
+ },
1199
+ {
1200
+ t: 1.7,
1201
+ pose: {
1202
+ x: -0.9,
1203
+ lean: 0.75,
1204
+ armL: -1.35,
1205
+ armR: -1.05,
1206
+ elbL: -0.08,
1207
+ elbR: -0.12,
1208
+ headX: -0.55,
1209
+ drop: -0.1,
1210
+ run: 1
1211
+ }
1212
+ },
1213
+ {
1214
+ t: 2.1,
1215
+ pose: {
1216
+ x: -0.32,
1217
+ lean: 0.45,
1218
+ armL: -1.65,
1219
+ armR: -1.6,
1220
+ elbL: -0.25,
1221
+ elbR: -0.3,
1222
+ headX: -0.3,
1223
+ drop: -0.08,
1224
+ legL: -0.6,
1225
+ legR: 0.4,
1226
+ kneeL: 0.5,
1227
+ kneeR: 0.6,
1228
+ run: 0
1229
+ }
1230
+ },
1231
+ {
1232
+ t: 3.6,
1233
+ pose: {
1234
+ x: -0.2,
1235
+ lean: 0.35,
1236
+ armL: -1.5,
1237
+ armR: -1.45,
1238
+ elbL: -1.1,
1239
+ elbR: -1.2,
1240
+ headX: -0.2,
1241
+ drop: -0.06,
1242
+ legL: -0.4,
1243
+ legR: 0.3,
1244
+ kneeL: 0.4,
1245
+ kneeR: 0.4,
1246
+ run: 0
1247
+ }
1248
+ },
1249
+ {
1250
+ t: 4.3,
1251
+ pose: {
1252
+ x: -0.1,
1253
+ lean: 0.5,
1254
+ armL: -1.4,
1255
+ armR: -1.3,
1256
+ elbL: -1.5,
1257
+ elbR: -1.5,
1258
+ headX: 0.35,
1259
+ headY: 0.35,
1260
+ drop: -0.08,
1261
+ legL: -0.35,
1262
+ legR: 0.3,
1263
+ kneeL: 0.4,
1264
+ kneeR: 0.4,
1265
+ run: 0
1266
+ }
1267
+ },
1268
+ {
1269
+ t: 5.6,
1270
+ pose: {
1271
+ x: 0,
1272
+ lean: 0.95,
1273
+ armL: -1.2,
1274
+ armR: -1,
1275
+ elbL: -1.4,
1276
+ elbR: -1.3,
1277
+ headX: 0.5,
1278
+ headY: 0.3,
1279
+ drop: -0.45,
1280
+ legL: -1.2,
1281
+ legR: -0.8,
1282
+ kneeL: 1.8,
1283
+ kneeR: 1.5,
1284
+ run: 0
1285
+ }
1286
+ },
1287
+ {
1288
+ t: 8,
1289
+ pose: {
1290
+ x: 0,
1291
+ lean: 1,
1292
+ armL: -1.15,
1293
+ armR: -0.95,
1294
+ elbL: -1.4,
1295
+ elbR: -1.3,
1296
+ headX: 0.55,
1297
+ headY: 0.3,
1298
+ drop: -0.47,
1299
+ legL: -1.2,
1300
+ legR: -0.8,
1301
+ kneeL: 1.85,
1302
+ kneeR: 1.5,
1303
+ run: 0
1304
+ }
1305
+ }
1306
+ ],
1307
+ events: [
1308
+ {
1309
+ t: 0,
1310
+ type: "phase",
1311
+ data: {
1312
+ label: "pose_clip.grab_bite.phase.approach"
1313
+ }
1314
+ },
1315
+ {
1316
+ t: 1.7,
1317
+ type: "phase",
1318
+ data: {
1319
+ label: "pose_clip.grab_bite.phase.pounce"
1320
+ }
1321
+ },
1322
+ {
1323
+ t: 2.1,
1324
+ type: "phase",
1325
+ data: {
1326
+ label: "pose_clip.grab_bite.phase.grab"
1327
+ }
1328
+ },
1329
+ {
1330
+ t: 4.3,
1331
+ type: "phase",
1332
+ data: {
1333
+ label: "pose_clip.grab_bite.phase.bite"
1334
+ }
1335
+ },
1336
+ {
1337
+ t: 5.6,
1338
+ type: "phase",
1339
+ data: {
1340
+ label: "pose_clip.grab_bite.phase.fall"
1341
+ }
1342
+ }
1343
+ ]
1344
+ }
1345
+ ],
1346
+ locales: {
1347
+ "pt-BR": {
1348
+ "pose_clip.grab_bite.phase.approach": "1. Aproxima\xE7\xE3o",
1349
+ "pose_clip.grab_bite.phase.pounce": "2. O bote",
1350
+ "pose_clip.grab_bite.phase.grab": "3. Agarr\xE3o: 3 s para se soltar",
1351
+ "pose_clip.grab_bite.phase.bite": "4. Mordida: infec\xE7\xE3o 100%",
1352
+ "pose_clip.grab_bite.phase.fall": "5. Queda"
1353
+ },
1354
+ en: {
1355
+ "pose_clip.grab_bite.phase.approach": "1. Approach",
1356
+ "pose_clip.grab_bite.phase.pounce": "2. The pounce",
1357
+ "pose_clip.grab_bite.phase.grab": "3. Grab: 3 s to break free",
1358
+ "pose_clip.grab_bite.phase.bite": "4. Bite: 100% infection",
1359
+ "pose_clip.grab_bite.phase.fall": "5. The fall"
1360
+ }
1361
+ }
1362
+ };
1363
+ var POSE_CLIPS = pose_clips_default.clips;
1364
+ var POSE_CLIP_LOCALES = pose_clips_default.locales;
992
1365
 
993
1366
  // ../game-crowd/dist/index.js
994
1367
  var defaults_default = {
@@ -1082,29 +1455,29 @@ var GameCrowdThree = (() => {
1082
1455
  function createDoors(grid, options) {
1083
1456
  const N = { ...DOOR_DEFAULTS, ...options.numbers };
1084
1457
  const random = options.random;
1085
- const list = [];
1458
+ const list2 = [];
1086
1459
  const doorAt = new Int16Array(grid.n * grid.n).fill(-1);
1087
1460
  const listeners = /* @__PURE__ */ new Map();
1088
1461
  const emit = (event, payload) => {
1089
1462
  for (const listener of listeners.get(event) ?? []) listener(payload);
1090
1463
  };
1091
1464
  const set = (index, open) => {
1092
- const d = list[index];
1465
+ const d = list2[index];
1093
1466
  if (!d) return;
1094
1467
  d.open = open;
1095
1468
  grid.fillRect(...d.rect, open || d.broken ? 3 : 5, N.height);
1096
1469
  };
1097
1470
  return {
1098
- list,
1471
+ list: list2,
1099
1472
  at: (cell) => cell < 0 ? -1 : doorAt[cell],
1100
1473
  add(x, z, axis, width, data) {
1101
- const i = list.length;
1474
+ const i = list2.length;
1102
1475
  const t = N.thickness;
1103
1476
  const x0 = axis === "x" ? x - width / 2 : x - t;
1104
1477
  const x1 = axis === "x" ? x + width / 2 : x + t;
1105
1478
  const z0 = axis === "x" ? z - t : z - width / 2;
1106
1479
  const z1 = axis === "x" ? z + t : z + width / 2;
1107
- list.push({ x, z, axis, width, hp: N.doorHp, hpMax: N.doorHp, open: false, broken: false, planks: 0, rect: [x0, z0, x1, z1], data });
1480
+ list2.push({ x, z, axis, width, hp: N.doorHp, hpMax: N.doorHp, open: false, broken: false, planks: 0, rect: [x0, z0, x1, z1], data });
1108
1481
  grid.fillRect(x0, z0, x1, z1, 5, N.height);
1109
1482
  const a = Math.floor((x0 + grid.half) / grid.cell);
1110
1483
  const b = Math.ceil((x1 + grid.half) / grid.cell);
@@ -1115,7 +1488,7 @@ var GameCrowdThree = (() => {
1115
1488
  },
1116
1489
  set,
1117
1490
  hit(index, damage) {
1118
- const d = list[index];
1491
+ const d = list2[index];
1119
1492
  if (!d || d.open || d.broken) return;
1120
1493
  d.hp -= damage;
1121
1494
  if (random() < N.soundChance) emit("sound", { sound: "wood", volume: N.soundVolume, position: [d.x, 1, d.z] });
@@ -1131,7 +1504,7 @@ var GameCrowdThree = (() => {
1131
1504
  }
1132
1505
  },
1133
1506
  plank(index) {
1134
- const d = list[index];
1507
+ const d = list2[index];
1135
1508
  if (!d) return;
1136
1509
  d.planks += 1;
1137
1510
  d.hp += N.plankHp;
@@ -1366,8 +1739,8 @@ var GameCrowdThree = (() => {
1366
1739
  function createCrowd(options) {
1367
1740
  const random = options.random ?? createRng(options.seed ?? 1);
1368
1741
  const R = random;
1369
- const pack = options.pack;
1370
- const types = pack.types;
1742
+ const pack2 = options.pack;
1743
+ const types = pack2.types;
1371
1744
  const N = { ...CROWD_DEFAULTS.numbers, ...options.numbers };
1372
1745
  const BANDS = options.bands ?? CROWD_DEFAULTS.bands;
1373
1746
  const HYST = N.hysteresis;
@@ -1411,14 +1784,14 @@ var GameCrowdThree = (() => {
1411
1784
  {
1412
1785
  let next = 0;
1413
1786
  types.forEach((type) => {
1414
- const list = [];
1415
- for (let v = 0; v < (type.variants ?? 1); v++) list.push(next++);
1416
- variantsOf.push(list);
1787
+ const list2 = [];
1788
+ for (let v = 0; v < (type.variants ?? 1); v++) list2.push(next++);
1789
+ variantsOf.push(list2);
1417
1790
  });
1418
1791
  }
1419
1792
  const typeIndexById = new Map(types.map((type, index) => [type.id, index]));
1420
1793
  const noises = [];
1421
- const stats = { bands: [0, 0, 0, 0], slots: 0, kills: 0, heads: 0 };
1794
+ const stats2 = { bands: [0, 0, 0, 0], slots: 0, kills: 0, heads: 0 };
1422
1795
  const corpses = createCorpseLedger({ max: N.corpsesMax, seconds: N.corpseSeconds });
1423
1796
  const trail = [];
1424
1797
  let trailLast = { x: 1e9, z: 1e9 };
@@ -1443,14 +1816,14 @@ var GameCrowdThree = (() => {
1443
1816
  if (target && Math.hypot(d.x - target.state.x, d.z - target.state.z) < N.doorMessageDistance) emit("message", { id: "door_broken", seconds: 2 });
1444
1817
  });
1445
1818
  const sound = (id, volume, x, y, z, d) => emit("sound", { sound: id, volume, position: [x, y, z], distance: d });
1446
- const pick = (list) => {
1819
+ const pick = (list2) => {
1447
1820
  const r = R();
1448
1821
  let acc = 0;
1449
- for (const it of list) {
1822
+ for (const it of list2) {
1450
1823
  acc += it.p;
1451
1824
  if (r < acc) return it;
1452
1825
  }
1453
- return list[0];
1826
+ return list2[0];
1454
1827
  };
1455
1828
  const T = (i) => types[Z.type[i]];
1456
1829
  const traits = (i) => T(i).traits ?? {};
@@ -1486,16 +1859,16 @@ var GameCrowdThree = (() => {
1486
1859
  const i = Z.n++;
1487
1860
  const c = catForce >= 0 ? catForce : catTable[Math.floor(R() * catTable.length)];
1488
1861
  const C = types[c];
1489
- const ai = pack.ages.indexOf(pick(pack.ages));
1862
+ const ai = pack2.ages.indexOf(pick(pack2.ages));
1490
1863
  const maxAge = C.traits?.maxAge;
1491
- const A = pack.ages[maxAge !== void 0 ? Math.min(ai, maxAge) : ai];
1492
- const ri = pack.outfits.indexOf(pick(pack.outfits));
1493
- const RO = pack.outfits[ri];
1864
+ const A = pack2.ages[maxAge !== void 0 ? Math.min(ai, maxAge) : ai];
1865
+ const ri = pack2.outfits.indexOf(pick(pack2.outfits));
1866
+ const RO = pack2.outfits[ri];
1494
1867
  Z.x[i] = x;
1495
1868
  Z.z[i] = z;
1496
1869
  Z.vx[i] = Z.vz[i] = 0;
1497
1870
  Z.type[i] = c;
1498
- Z.age[i] = pack.ages.indexOf(A);
1871
+ Z.age[i] = pack2.ages.indexOf(A);
1499
1872
  Z.outfit[i] = ri;
1500
1873
  const g = (R() + R() + R() - 1.5) * 0.09;
1501
1874
  Z.height[i] = clamp(1 + g, 0.9, 1.1) * (C.scale || 1);
@@ -1506,9 +1879,9 @@ var GameCrowdThree = (() => {
1506
1879
  Z.chaseSpeed[i] = C.speed.chase * A.speed * (thin ? 1.05 : heavy ? 0.9 : 1) * (0.92 + R() * 0.16);
1507
1880
  Z.wanderSpeed[i] = C.speed.wander * A.speed * (0.8 + R() * 0.4);
1508
1881
  Z.hpMax[i] = Z.hp[i] = C.health * A.health * (thin ? 0.9 : heavy ? 1.15 : 1);
1509
- Z.headHp[i] = pack.segments.head;
1510
- Z.armHp[i * 2] = Z.armHp[i * 2 + 1] = pack.segments.arm;
1511
- Z.legHp[i * 2] = Z.legHp[i * 2 + 1] = pack.segments.leg;
1882
+ Z.headHp[i] = pack2.segments.head;
1883
+ Z.armHp[i * 2] = Z.armHp[i * 2 + 1] = pack2.segments.arm;
1884
+ Z.legHp[i * 2] = Z.legHp[i * 2 + 1] = pack2.segments.leg;
1512
1885
  Z.missing[i] = 0;
1513
1886
  Z.helmet[i] = RO.helmet ? 1 : 0;
1514
1887
  Z.crawl[i] = C.crawls ? 1 : 0;
@@ -1534,7 +1907,7 @@ var GameCrowdThree = (() => {
1534
1907
  Z.next[i] = R() * 0.05;
1535
1908
  Z.wx[i] = x;
1536
1909
  Z.wz[i] = z;
1537
- Z.color[i] = RO.color || pack.palette[Math.floor(R() * pack.palette.length)];
1910
+ Z.color[i] = RO.color || pack2.palette[Math.floor(R() * pack2.palette.length)];
1538
1911
  Z.skin[i] = R();
1539
1912
  special(i);
1540
1913
  emit("spawn", { agent: i, type: C.id });
@@ -1769,8 +2142,8 @@ var GameCrowdThree = (() => {
1769
2142
  const blood = (x, y, z, age, amount, died, agent) => effect({ effect: "blood", point: [x, y, z], age, amount, died, ...agent === void 0 ? {} : { agent } });
1770
2143
  const damage = (i, hit) => {
1771
2144
  const C = T(i);
1772
- const A = pack.ages[Z.age[i]];
1773
- const RO = pack.outfits[Z.outfit[i]];
2145
+ const A = pack2.ages[Z.age[i]];
2146
+ const RO = pack2.outfits[Z.outfit[i]];
1774
2147
  const cal = hit.caliber ?? null;
1775
2148
  const proj = !!cal;
1776
2149
  const dano = hit.amount;
@@ -1808,7 +2181,7 @@ var GameCrowdThree = (() => {
1808
2181
  const k = i * 2 + (perna ? lado : regiao === 3 ? 1 : 0);
1809
2182
  segArr[k] -= dano * mm;
1810
2183
  Z.hp[i] -= dano * mm * 0.5;
1811
- const max = perna ? pack.segments.leg : pack.segments.arm;
2184
+ const max = perna ? pack2.segments.leg : pack2.segments.arm;
1812
2185
  if (perna && segArr[k] <= max * 0.5) Z.limp[i] = 1;
1813
2186
  if (segArr[k] <= 0) {
1814
2187
  const arranca = corte >= 0.5 || dano * mm > max * 0.9;
@@ -1842,8 +2215,8 @@ var GameCrowdThree = (() => {
1842
2215
  return { died: morreu };
1843
2216
  };
1844
2217
  function kill(i, headshot = false) {
1845
- stats.kills++;
1846
- if (headshot) stats.heads++;
2218
+ stats2.kills++;
2219
+ if (headshot) stats2.heads++;
1847
2220
  const tr = traits(i);
1848
2221
  if (tr.burst) burstAt(i, Z.x[i], Z.z[i]);
1849
2222
  const C = T(i);
@@ -1946,9 +2319,9 @@ var GameCrowdThree = (() => {
1946
2319
  if (Z.stateTimer[i] <= 0) {
1947
2320
  let best = -1;
1948
2321
  let bd = ec2.grabRange;
1949
- const list = corpses.entries;
1950
- for (let k = 0; k < list.length; k++) {
1951
- const e = Math.hypot(list[k].data.x - Z.x[i], list[k].data.z - Z.z[i]);
2322
+ const list2 = corpses.entries;
2323
+ for (let k = 0; k < list2.length; k++) {
2324
+ const e = Math.hypot(list2[k].data.x - Z.x[i], list2[k].data.z - Z.z[i]);
1952
2325
  if (e < bd) {
1953
2326
  bd = e;
1954
2327
  best = k;
@@ -2032,9 +2405,9 @@ var GameCrowdThree = (() => {
2032
2405
  if (ec && st === 0 && Z.eaten[i] < ec.max && Z.abilityTimer[i] <= 0 && corpses.count) {
2033
2406
  let best = -1;
2034
2407
  let bd = ec.search;
2035
- const list = corpses.entries;
2036
- for (let k = 0; k < list.length; k++) {
2037
- const e = Math.hypot(list[k].data.x - Z.x[i], list[k].data.z - Z.z[i]);
2408
+ const list2 = corpses.entries;
2409
+ for (let k = 0; k < list2.length; k++) {
2410
+ const e = Math.hypot(list2[k].data.x - Z.x[i], list2[k].data.z - Z.z[i]);
2038
2411
  if (e < bd) {
2039
2412
  bd = e;
2040
2413
  best = k;
@@ -2047,7 +2420,7 @@ var GameCrowdThree = (() => {
2047
2420
  Z.vx[i] = Z.vz[i] = 0;
2048
2421
  return true;
2049
2422
  }
2050
- const cp = list[best].data;
2423
+ const cp = list2[best].data;
2051
2424
  const ex = cp.x - Z.x[i];
2052
2425
  const ez = cp.z - Z.z[i];
2053
2426
  const sp = Z.wanderSpeed[i] * ec.approach;
@@ -2179,7 +2552,7 @@ var GameCrowdThree = (() => {
2179
2552
  hNext[i] = hHead[h];
2180
2553
  hHead[h] = i;
2181
2554
  }
2182
- const B = stats.bands;
2555
+ const B = stats2.bands;
2183
2556
  B[0] = B[1] = B[2] = B[3] = 0;
2184
2557
  let slots = 0;
2185
2558
  const F = flow.dir;
@@ -2223,13 +2596,13 @@ var GameCrowdThree = (() => {
2223
2596
  Z.next[i] += tdt;
2224
2597
  if (alive && b <= 1 && Z.state[i] <= 1) {
2225
2598
  let sees = false;
2226
- const A = pack.ages[Z.age[i]];
2599
+ const A = pack2.ages[Z.age[i]];
2227
2600
  const vis = C.perception.sight * (1 - N.nightSight * nightF) * (P.state.crouch ? N.crouchSight : 1) * A.sight;
2228
2601
  if (d < vis) {
2229
2602
  const fx = Math.sin(Z.yaw[i]);
2230
2603
  const fz = Math.cos(Z.yaw[i]);
2231
- const cone = (-dx * fx - dz * fz) / (d || 1);
2232
- if ((cone > N.sightCone || d < N.sightNear) && (Z.floor[i] === P.state.floor || d < 5) && (Z.floor[i] || P.state.floor || losClear(Z.x[i], Z.z[i], px, pz))) sees = true;
2604
+ const cone2 = (-dx * fx - dz * fz) / (d || 1);
2605
+ if ((cone2 > N.sightCone || d < N.sightNear) && (Z.floor[i] === P.state.floor || d < 5) && (Z.floor[i] || P.state.floor || losClear(Z.x[i], Z.z[i], px, pz))) sees = true;
2233
2606
  }
2234
2607
  if (C.perception.smell && d < C.perception.smell * (P.state.bleeding || P.state.scentTimer > 0 ? 2 : 1)) sees = true;
2235
2608
  if (sees) {
@@ -2247,7 +2620,7 @@ var GameCrowdThree = (() => {
2247
2620
  }
2248
2621
  for (let k = 0; k < noises.length && (Z.state[i] === 0 || Z.state[i] === STATE.SEEKING_SOUND); k++) {
2249
2622
  const Nz = noises[k];
2250
- const hear = Nz.r * (C.perception.hearing / N.hearingBase) * pack.ages[Z.age[i]].hearing;
2623
+ const hear = Nz.r * (C.perception.hearing / N.hearingBase) * pack2.ages[Z.age[i]].hearing;
2251
2624
  if ((Z.x[i] - Nz.x) ** 2 + (Z.z[i] - Nz.z) ** 2 < hear * hear) {
2252
2625
  if (tr.soundSeeker) {
2253
2626
  Z.state[i] = STATE.SEEKING_SOUND;
@@ -2415,7 +2788,7 @@ var GameCrowdThree = (() => {
2415
2788
  }
2416
2789
  killQFlush();
2417
2790
  noises.length = 0;
2418
- stats.slots = slots;
2791
+ stats2.slots = slots;
2419
2792
  };
2420
2793
  const updateTrail = (dt, who = target) => {
2421
2794
  for (const p2 of trail) p2.t += dt;
@@ -2478,12 +2851,12 @@ var GameCrowdThree = (() => {
2478
2851
  };
2479
2852
  const crowd = {
2480
2853
  store: Z,
2481
- pack,
2854
+ pack: pack2,
2482
2855
  grid,
2483
2856
  doors,
2484
2857
  corpses,
2485
2858
  numbers: N,
2486
- stats,
2859
+ stats: stats2,
2487
2860
  pile,
2488
2861
  pileCount: () => pileN,
2489
2862
  trail,
@@ -2629,7 +3002,7 @@ var GameCrowdThree = (() => {
2629
3002
  if (Math.sign(a[a.length - 1][1]) !== Math.sign(b[0][1])) out.push([a[a.length - 1][0], b[0][1]]);
2630
3003
  return out.concat(b);
2631
3004
  };
2632
- const list = options.people.map((spec, k) => {
3005
+ const list2 = options.people.map((spec, k) => {
2633
3006
  const b = casaDe(spec.home);
2634
3007
  const p2 = pontos(b)[0];
2635
3008
  return {
@@ -2654,7 +3027,7 @@ var GameCrowdThree = (() => {
2654
3027
  agent: -1
2655
3028
  };
2656
3029
  });
2657
- const byId = new Map(list.map((c) => [c.id, c]));
3030
+ const byId = new Map(list2.map((c) => [c.id, c]));
2658
3031
  const exposed = (n) => n.state !== "dead" && n.state !== "undead" && n.state !== "gone";
2659
3032
  const target = () => crowd.target?.state ?? null;
2660
3033
  const distToTarget = (x, z) => {
@@ -2701,7 +3074,7 @@ var GameCrowdThree = (() => {
2701
3074
  if (Z.band[i] > 1) continue;
2702
3075
  const k = Z.hunts[i];
2703
3076
  if (k >= 0) {
2704
- const n = list[k];
3077
+ const n = list2[k];
2705
3078
  if (!exposed(n)) {
2706
3079
  Z.hunts[i] = -1;
2707
3080
  continue;
@@ -2730,7 +3103,7 @@ var GameCrowdThree = (() => {
2730
3103
  }
2731
3104
  }
2732
3105
  } else if (Z.state[i] <= 1) {
2733
- for (const n of list) {
3106
+ for (const n of list2) {
2734
3107
  if (!exposed(n) || n.state === "home") continue;
2735
3108
  const dx = n.x - Z.x[i];
2736
3109
  const dz = n.z - Z.z[i];
@@ -2746,7 +3119,7 @@ var GameCrowdThree = (() => {
2746
3119
  }
2747
3120
  };
2748
3121
  crowd.setHunt((i) => {
2749
- const n = list[Z.hunts[i]];
3122
+ const n = list2[Z.hunts[i]];
2750
3123
  if (!n) return false;
2751
3124
  const dx = n.x - Z.x[i];
2752
3125
  const dz = n.z - Z.z[i];
@@ -2800,7 +3173,7 @@ var GameCrowdThree = (() => {
2800
3173
  agentsAgainst(dt);
2801
3174
  const h = hourNow();
2802
3175
  const t = target();
2803
- for (const n of list) {
3176
+ for (const n of list2) {
2804
3177
  if (n.state === "dead" || n.state === "undead" || n.state === "gone") continue;
2805
3178
  if (n.biteTimer > 0) {
2806
3179
  n.biteTimer -= dt;
@@ -2873,7 +3246,7 @@ var GameCrowdThree = (() => {
2873
3246
  }
2874
3247
  for (let i = 0; i < Z.n; i++)
2875
3248
  if (Z.named[i] >= 0 && Z.state[i] === STATE.WANDER && R() < dt * N.patrolChance) {
2876
- const n = list[Z.named[i]];
3249
+ const n = list2[Z.named[i]];
2877
3250
  if (!n) continue;
2878
3251
  const p2 = pontos(casaDe(n.spec.home));
2879
3252
  const q = p2[Math.floor(R() * p2.length)];
@@ -2882,7 +3255,7 @@ var GameCrowdThree = (() => {
2882
3255
  }
2883
3256
  };
2884
3257
  return {
2885
- list,
3258
+ list: list2,
2886
3259
  get: (id) => byId.get(id),
2887
3260
  update,
2888
3261
  join(id) {
@@ -2949,7 +3322,7 @@ var GameCrowdThree = (() => {
2949
3322
  const R = crowd.random;
2950
3323
  const Z = crowd.store;
2951
3324
  const grid = crowd.grid;
2952
- const list = [];
3325
+ const list2 = [];
2953
3326
  let time = 0;
2954
3327
  const listeners = /* @__PURE__ */ new Map();
2955
3328
  const emit = (event, payload) => {
@@ -2992,7 +3365,7 @@ var GameCrowdThree = (() => {
2992
3365
  const px = t?.x ?? 0;
2993
3366
  const pz = t?.z ?? 0;
2994
3367
  const v = view();
2995
- for (const E of list) {
3368
+ for (const E of list2) {
2996
3369
  if (E.spec.sky) continue;
2997
3370
  const dc = Math.hypot(E.x - v.x, E.z - v.z);
2998
3371
  if (dc >= N.activeDistance || E.dead) continue;
@@ -3093,10 +3466,10 @@ var GameCrowdThree = (() => {
3093
3466
  }
3094
3467
  };
3095
3468
  return {
3096
- list,
3469
+ list: list2,
3097
3470
  add(spec) {
3098
3471
  const E = {
3099
- index: list.length,
3472
+ index: list2.length,
3100
3473
  spec,
3101
3474
  x: spec.x,
3102
3475
  z: spec.z,
@@ -3117,7 +3490,7 @@ var GameCrowdThree = (() => {
3117
3490
  dead: !!spec.dead,
3118
3491
  near: void 0
3119
3492
  };
3120
- list.push(E);
3493
+ list2.push(E);
3121
3494
  return E;
3122
3495
  },
3123
3496
  free,
@@ -3126,7 +3499,7 @@ var GameCrowdThree = (() => {
3126
3499
  return time;
3127
3500
  },
3128
3501
  setCompanion(index, on) {
3129
- const E = list[index];
3502
+ const E = list2[index];
3130
3503
  if (!E) return;
3131
3504
  E.companion = on;
3132
3505
  E.homeX = E.x;
@@ -3230,16 +3603,16 @@ var GameCrowdThree = (() => {
3230
3603
  const entry = tracked.get(i);
3231
3604
  if (!entry || region !== void 0 && entry.region !== region) continue;
3232
3605
  if (!opts.all && crowd.store.band[i] < band) continue;
3233
- let list = byRegion.get(entry.region);
3234
- if (!list) byRegion.set(entry.region, list = []);
3235
- list.push({ state: entry.state, seed: entry.seed });
3606
+ let list2 = byRegion.get(entry.region);
3607
+ if (!list2) byRegion.set(entry.region, list2 = []);
3608
+ list2.push({ state: entry.state, seed: entry.seed });
3236
3609
  tracked.delete(i);
3237
3610
  crowd.remove(i);
3238
3611
  }
3239
3612
  let count = 0;
3240
- for (const [r, list] of byRegion) {
3241
- model.giveBack(r, list);
3242
- count += list.length;
3613
+ for (const [r, list2] of byRegion) {
3614
+ model.giveBack(r, list2);
3615
+ count += list2.length;
3243
3616
  }
3244
3617
  return count;
3245
3618
  },
@@ -3398,8 +3771,8 @@ var GameCrowdThree = (() => {
3398
3771
  plain({ a: [C.x, C.z, C.yaw, C.seed], b: [C.height * fade, C.build, Math.min(1, t * N.corpseRise), pose.corpse], c, color: C.color, shade, eye: null, y: 0 });
3399
3772
  }
3400
3773
  },
3401
- civilians(list, colorOf, sink) {
3402
- for (const n of list) {
3774
+ civilians(list2, colorOf, sink) {
3775
+ for (const n of list2) {
3403
3776
  if (n.state === "undead" || n.state === "gone" || n.state === "dead") continue;
3404
3777
  const sp = Math.hypot(n.vx, n.vz);
3405
3778
  const child = !!n.spec.child;
@@ -3417,6 +3790,1523 @@ var GameCrowdThree = (() => {
3417
3790
  };
3418
3791
  }
3419
3792
 
3793
+ // ../game-shapes/dist/chunk-R4RY23RH.js
3794
+ function canonicalJson(value) {
3795
+ if (value === null) return "null";
3796
+ if (typeof value === "number") return Object.is(value, -0) ? "-0" : Number.isFinite(value) ? String(value) : JSON.stringify(String(value));
3797
+ if (typeof value === "string") return JSON.stringify(value);
3798
+ if (typeof value === "boolean") return value ? "true" : "false";
3799
+ if (typeof value === "function") throw new Error("game-shapes: a function cannot be part of a shape (register it as a generator)");
3800
+ if (ArrayBuffer.isView(value)) return canonicalJson(Array.from(value));
3801
+ if (Array.isArray(value)) return `[${value.map((item) => item === void 0 ? "null" : canonicalJson(item)).join(",")}]`;
3802
+ if (typeof value === "object") {
3803
+ const record = value;
3804
+ const keys = Object.keys(record).filter((key) => record[key] !== void 0).sort();
3805
+ return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(",")}}`;
3806
+ }
3807
+ return "null";
3808
+ }
3809
+ function needsUint32(array) {
3810
+ for (let i = array.length - 1; i >= 0; --i) if (array[i] >= 65535) return true;
3811
+ return false;
3812
+ }
3813
+ var indexArray = (indices) => needsUint32(indices) ? new Uint32Array(indices) : new Uint16Array(indices);
3814
+ function pack(type, parameters, a) {
3815
+ return {
3816
+ type,
3817
+ parameters,
3818
+ positions: new Float32Array(a.vertices),
3819
+ normals: new Float32Array(a.normals),
3820
+ uvs: new Float32Array(a.uvs),
3821
+ ...a.indices ? { indices: indexArray(a.indices) } : {},
3822
+ groups: a.groups
3823
+ };
3824
+ }
3825
+ var normalize3 = (x, y, z) => {
3826
+ const length = Math.sqrt(x * x + y * y + z * z);
3827
+ const s = 1 / (length || 1);
3828
+ return [x * s, y * s, z * s];
3829
+ };
3830
+ function box(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) {
3831
+ const parameters = { width, height, depth, widthSegments, heightSegments, depthSegments };
3832
+ widthSegments = Math.floor(widthSegments);
3833
+ heightSegments = Math.floor(heightSegments);
3834
+ depthSegments = Math.floor(depthSegments);
3835
+ const indices = [];
3836
+ const vertices = [];
3837
+ const normals = [];
3838
+ const uvs = [];
3839
+ const groups = [];
3840
+ let numberOfVertices = 0;
3841
+ let groupStart = 0;
3842
+ const buildPlane = (u, v, w, udir, vdir, width2, height2, depth2, gridX, gridY, materialIndex) => {
3843
+ const segmentWidth = width2 / gridX;
3844
+ const segmentHeight = height2 / gridY;
3845
+ const widthHalf = width2 / 2;
3846
+ const heightHalf = height2 / 2;
3847
+ const depthHalf = depth2 / 2;
3848
+ const gridX1 = gridX + 1;
3849
+ const gridY1 = gridY + 1;
3850
+ let vertexCounter = 0;
3851
+ let groupCount = 0;
3852
+ const vector = { x: 0, y: 0, z: 0 };
3853
+ for (let iy = 0; iy < gridY1; iy++) {
3854
+ const y = iy * segmentHeight - heightHalf;
3855
+ for (let ix = 0; ix < gridX1; ix++) {
3856
+ const x = ix * segmentWidth - widthHalf;
3857
+ vector[u] = x * udir;
3858
+ vector[v] = y * vdir;
3859
+ vector[w] = depthHalf;
3860
+ vertices.push(vector.x, vector.y, vector.z);
3861
+ vector[u] = 0;
3862
+ vector[v] = 0;
3863
+ vector[w] = depth2 > 0 ? 1 : -1;
3864
+ normals.push(vector.x, vector.y, vector.z);
3865
+ uvs.push(ix / gridX);
3866
+ uvs.push(1 - iy / gridY);
3867
+ vertexCounter += 1;
3868
+ }
3869
+ }
3870
+ for (let iy = 0; iy < gridY; iy++) {
3871
+ for (let ix = 0; ix < gridX; ix++) {
3872
+ const a = numberOfVertices + ix + gridX1 * iy;
3873
+ const b = numberOfVertices + ix + gridX1 * (iy + 1);
3874
+ const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1);
3875
+ const d = numberOfVertices + (ix + 1) + gridX1 * iy;
3876
+ indices.push(a, b, d);
3877
+ indices.push(b, c, d);
3878
+ groupCount += 6;
3879
+ }
3880
+ }
3881
+ groups.push({ start: groupStart, count: groupCount, materialIndex });
3882
+ groupStart += groupCount;
3883
+ numberOfVertices += vertexCounter;
3884
+ };
3885
+ buildPlane("z", "y", "x", -1, -1, depth, height, width, depthSegments, heightSegments, 0);
3886
+ buildPlane("z", "y", "x", 1, -1, depth, height, -width, depthSegments, heightSegments, 1);
3887
+ buildPlane("x", "z", "y", 1, 1, width, depth, height, widthSegments, depthSegments, 2);
3888
+ buildPlane("x", "z", "y", 1, -1, width, depth, -height, widthSegments, depthSegments, 3);
3889
+ buildPlane("x", "y", "z", 1, -1, width, height, depth, widthSegments, heightSegments, 4);
3890
+ buildPlane("x", "y", "z", -1, -1, width, height, -depth, widthSegments, heightSegments, 5);
3891
+ return pack("BoxGeometry", parameters, { vertices, normals, uvs, indices, groups });
3892
+ }
3893
+ function cylinderArrays(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) {
3894
+ radialSegments = Math.floor(radialSegments);
3895
+ heightSegments = Math.floor(heightSegments);
3896
+ const indices = [];
3897
+ const vertices = [];
3898
+ const normals = [];
3899
+ const uvs = [];
3900
+ const groups = [];
3901
+ let index = 0;
3902
+ const indexArray2 = [];
3903
+ const halfHeight = height / 2;
3904
+ let groupStart = 0;
3905
+ const generateTorso = () => {
3906
+ let groupCount = 0;
3907
+ const slope = (radiusBottom - radiusTop) / height;
3908
+ for (let y = 0; y <= heightSegments; y++) {
3909
+ const indexRow = [];
3910
+ const v = y / heightSegments;
3911
+ const radius = v * (radiusBottom - radiusTop) + radiusTop;
3912
+ for (let x = 0; x <= radialSegments; x++) {
3913
+ const u = x / radialSegments;
3914
+ const theta = u * thetaLength + thetaStart;
3915
+ const sinTheta = Math.sin(theta);
3916
+ const cosTheta = Math.cos(theta);
3917
+ vertices.push(radius * sinTheta, -v * height + halfHeight, radius * cosTheta);
3918
+ const n = normalize3(sinTheta, slope, cosTheta);
3919
+ normals.push(n[0], n[1], n[2]);
3920
+ uvs.push(u, 1 - v);
3921
+ indexRow.push(index++);
3922
+ }
3923
+ indexArray2.push(indexRow);
3924
+ }
3925
+ for (let x = 0; x < radialSegments; x++) {
3926
+ for (let y = 0; y < heightSegments; y++) {
3927
+ const a = indexArray2[y][x];
3928
+ const b = indexArray2[y + 1][x];
3929
+ const c = indexArray2[y + 1][x + 1];
3930
+ const d = indexArray2[y][x + 1];
3931
+ indices.push(a, b, d);
3932
+ indices.push(b, c, d);
3933
+ groupCount += 6;
3934
+ }
3935
+ }
3936
+ groups.push({ start: groupStart, count: groupCount, materialIndex: 0 });
3937
+ groupStart += groupCount;
3938
+ };
3939
+ const generateCap = (top) => {
3940
+ const centerIndexStart = index;
3941
+ let groupCount = 0;
3942
+ const radius = top === true ? radiusTop : radiusBottom;
3943
+ const sign2 = top === true ? 1 : -1;
3944
+ for (let x = 1; x <= radialSegments; x++) {
3945
+ vertices.push(0, halfHeight * sign2, 0);
3946
+ normals.push(0, sign2, 0);
3947
+ uvs.push(0.5, 0.5);
3948
+ index++;
3949
+ }
3950
+ const centerIndexEnd = index;
3951
+ for (let x = 0; x <= radialSegments; x++) {
3952
+ const u = x / radialSegments;
3953
+ const theta = u * thetaLength + thetaStart;
3954
+ const cosTheta = Math.cos(theta);
3955
+ const sinTheta = Math.sin(theta);
3956
+ vertices.push(radius * sinTheta, halfHeight * sign2, radius * cosTheta);
3957
+ normals.push(0, sign2, 0);
3958
+ uvs.push(cosTheta * 0.5 + 0.5, sinTheta * 0.5 * sign2 + 0.5);
3959
+ index++;
3960
+ }
3961
+ for (let x = 0; x < radialSegments; x++) {
3962
+ const c = centerIndexStart + x;
3963
+ const i = centerIndexEnd + x;
3964
+ if (top === true) indices.push(i, i + 1, c);
3965
+ else indices.push(i + 1, i, c);
3966
+ groupCount += 3;
3967
+ }
3968
+ groups.push({ start: groupStart, count: groupCount, materialIndex: top === true ? 1 : 2 });
3969
+ groupStart += groupCount;
3970
+ };
3971
+ generateTorso();
3972
+ if (openEnded === false) {
3973
+ if (radiusTop > 0) generateCap(true);
3974
+ if (radiusBottom > 0) generateCap(false);
3975
+ }
3976
+ return { vertices, normals, uvs, indices, groups };
3977
+ }
3978
+ function cylinder(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) {
3979
+ const parameters = { radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength };
3980
+ return pack("CylinderGeometry", parameters, cylinderArrays(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength));
3981
+ }
3982
+ function cone(radius = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) {
3983
+ const parameters = { radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength };
3984
+ return pack("ConeGeometry", parameters, cylinderArrays(0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength));
3985
+ }
3986
+ function sphere(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI) {
3987
+ const parameters = { radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength };
3988
+ widthSegments = Math.max(3, Math.floor(widthSegments));
3989
+ heightSegments = Math.max(2, Math.floor(heightSegments));
3990
+ const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI);
3991
+ let index = 0;
3992
+ const grid = [];
3993
+ const indices = [];
3994
+ const vertices = [];
3995
+ const normals = [];
3996
+ const uvs = [];
3997
+ for (let iy = 0; iy <= heightSegments; iy++) {
3998
+ const verticesRow = [];
3999
+ const v = iy / heightSegments;
4000
+ let uOffset = 0;
4001
+ if (iy === 0 && thetaStart === 0) uOffset = 0.5 / widthSegments;
4002
+ else if (iy === heightSegments && thetaEnd === Math.PI) uOffset = -0.5 / widthSegments;
4003
+ for (let ix = 0; ix <= widthSegments; ix++) {
4004
+ const u = ix / widthSegments;
4005
+ const x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
4006
+ const y = radius * Math.cos(thetaStart + v * thetaLength);
4007
+ const z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
4008
+ vertices.push(x, y, z);
4009
+ const n = normalize3(x, y, z);
4010
+ normals.push(n[0], n[1], n[2]);
4011
+ uvs.push(u + uOffset, 1 - v);
4012
+ verticesRow.push(index++);
4013
+ }
4014
+ grid.push(verticesRow);
4015
+ }
4016
+ for (let iy = 0; iy < heightSegments; iy++) {
4017
+ for (let ix = 0; ix < widthSegments; ix++) {
4018
+ const a = grid[iy][ix + 1];
4019
+ const b = grid[iy][ix];
4020
+ const c = grid[iy + 1][ix];
4021
+ const d = grid[iy + 1][ix + 1];
4022
+ if (iy !== 0 || thetaStart > 0) indices.push(a, b, d);
4023
+ if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d);
4024
+ }
4025
+ }
4026
+ return pack("SphereGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
4027
+ }
4028
+ function plane(width = 1, height = 1, widthSegments = 1, heightSegments = 1) {
4029
+ const parameters = { width, height, widthSegments, heightSegments };
4030
+ const widthHalf = width / 2;
4031
+ const heightHalf = height / 2;
4032
+ const gridX = Math.floor(widthSegments);
4033
+ const gridY = Math.floor(heightSegments);
4034
+ const gridX1 = gridX + 1;
4035
+ const gridY1 = gridY + 1;
4036
+ const segmentWidth = width / gridX;
4037
+ const segmentHeight = height / gridY;
4038
+ const indices = [];
4039
+ const vertices = [];
4040
+ const normals = [];
4041
+ const uvs = [];
4042
+ for (let iy = 0; iy < gridY1; iy++) {
4043
+ const y = iy * segmentHeight - heightHalf;
4044
+ for (let ix = 0; ix < gridX1; ix++) {
4045
+ const x = ix * segmentWidth - widthHalf;
4046
+ vertices.push(x, -y, 0);
4047
+ normals.push(0, 0, 1);
4048
+ uvs.push(ix / gridX);
4049
+ uvs.push(1 - iy / gridY);
4050
+ }
4051
+ }
4052
+ for (let iy = 0; iy < gridY; iy++) {
4053
+ for (let ix = 0; ix < gridX; ix++) {
4054
+ const a = ix + gridX1 * iy;
4055
+ const b = ix + gridX1 * (iy + 1);
4056
+ const c = ix + 1 + gridX1 * (iy + 1);
4057
+ const d = ix + 1 + gridX1 * iy;
4058
+ indices.push(a, b, d);
4059
+ indices.push(b, c, d);
4060
+ }
4061
+ }
4062
+ return pack("PlaneGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
4063
+ }
4064
+ function circle(radius = 1, segments = 32, thetaStart = 0, thetaLength = Math.PI * 2) {
4065
+ const parameters = { radius, segments, thetaStart, thetaLength };
4066
+ segments = Math.max(3, segments);
4067
+ const indices = [];
4068
+ const vertices = [];
4069
+ const normals = [];
4070
+ const uvs = [];
4071
+ vertices.push(0, 0, 0);
4072
+ normals.push(0, 0, 1);
4073
+ uvs.push(0.5, 0.5);
4074
+ for (let s = 0, i = 3; s <= segments; s++, i += 3) {
4075
+ const segment = thetaStart + s / segments * thetaLength;
4076
+ vertices.push(radius * Math.cos(segment), radius * Math.sin(segment), 0);
4077
+ normals.push(0, 0, 1);
4078
+ uvs.push((vertices[i] / radius + 1) / 2, (vertices[i + 1] / radius + 1) / 2);
4079
+ }
4080
+ for (let i = 1; i <= segments; i++) indices.push(i, i + 1, 0);
4081
+ return pack("CircleGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
4082
+ }
4083
+ function ring(innerRadius = 0.5, outerRadius = 1, thetaSegments = 32, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2) {
4084
+ const parameters = { innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength };
4085
+ thetaSegments = Math.max(3, thetaSegments);
4086
+ phiSegments = Math.max(1, phiSegments);
4087
+ const indices = [];
4088
+ const vertices = [];
4089
+ const normals = [];
4090
+ const uvs = [];
4091
+ let radius = innerRadius;
4092
+ const radiusStep = (outerRadius - innerRadius) / phiSegments;
4093
+ for (let j = 0; j <= phiSegments; j++) {
4094
+ for (let i = 0; i <= thetaSegments; i++) {
4095
+ const segment = thetaStart + i / thetaSegments * thetaLength;
4096
+ const x = radius * Math.cos(segment);
4097
+ const y = radius * Math.sin(segment);
4098
+ vertices.push(x, y, 0);
4099
+ normals.push(0, 0, 1);
4100
+ uvs.push((x / outerRadius + 1) / 2, (y / outerRadius + 1) / 2);
4101
+ }
4102
+ radius += radiusStep;
4103
+ }
4104
+ for (let j = 0; j < phiSegments; j++) {
4105
+ const thetaSegmentLevel = j * (thetaSegments + 1);
4106
+ for (let i = 0; i < thetaSegments; i++) {
4107
+ const segment = i + thetaSegmentLevel;
4108
+ const a = segment;
4109
+ const b = segment + thetaSegments + 1;
4110
+ const c = segment + thetaSegments + 2;
4111
+ const d = segment + 1;
4112
+ indices.push(a, b, d);
4113
+ indices.push(b, c, d);
4114
+ }
4115
+ }
4116
+ return pack("RingGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
4117
+ }
4118
+ function lathe(points, segments = 12, phiStart = 0, phiLength = Math.PI * 2) {
4119
+ const parameters = { points: points.map(([x, y]) => ({ x, y })), segments, phiStart, phiLength };
4120
+ segments = Math.floor(segments);
4121
+ phiLength = Math.max(0, Math.min(Math.PI * 2, phiLength));
4122
+ const indices = [];
4123
+ const vertices = [];
4124
+ const uvs = [];
4125
+ const initNormals = [];
4126
+ const normals = [];
4127
+ const inverseSegments = 1 / segments;
4128
+ const normal = { x: 0, y: 0, z: 0 };
4129
+ const curNormal = { x: 0, y: 0, z: 0 };
4130
+ const prevNormal = { x: 0, y: 0, z: 0 };
4131
+ let dx = 0;
4132
+ let dy = 0;
4133
+ const last = points.length - 1;
4134
+ const px = (j) => points[j][0];
4135
+ const py = (j) => points[j][1];
4136
+ const setNormalized = () => {
4137
+ const n = normalize3(normal.x, normal.y, normal.z);
4138
+ normal.x = n[0];
4139
+ normal.y = n[1];
4140
+ normal.z = n[2];
4141
+ };
4142
+ for (let j = 0; j <= last; j++) {
4143
+ if (j === 0) {
4144
+ dx = px(j + 1) - px(j);
4145
+ dy = py(j + 1) - py(j);
4146
+ normal.x = dy * 1;
4147
+ normal.y = -dx;
4148
+ normal.z = dy * 0;
4149
+ prevNormal.x = normal.x;
4150
+ prevNormal.y = normal.y;
4151
+ prevNormal.z = normal.z;
4152
+ setNormalized();
4153
+ initNormals.push(normal.x, normal.y, normal.z);
4154
+ } else if (j === last) {
4155
+ initNormals.push(prevNormal.x, prevNormal.y, prevNormal.z);
4156
+ } else {
4157
+ dx = px(j + 1) - px(j);
4158
+ dy = py(j + 1) - py(j);
4159
+ normal.x = dy * 1;
4160
+ normal.y = -dx;
4161
+ normal.z = dy * 0;
4162
+ curNormal.x = normal.x;
4163
+ curNormal.y = normal.y;
4164
+ curNormal.z = normal.z;
4165
+ normal.x += prevNormal.x;
4166
+ normal.y += prevNormal.y;
4167
+ normal.z += prevNormal.z;
4168
+ setNormalized();
4169
+ initNormals.push(normal.x, normal.y, normal.z);
4170
+ prevNormal.x = curNormal.x;
4171
+ prevNormal.y = curNormal.y;
4172
+ prevNormal.z = curNormal.z;
4173
+ }
4174
+ }
4175
+ for (let i = 0; i <= segments; i++) {
4176
+ const phi = phiStart + i * inverseSegments * phiLength;
4177
+ const sin = Math.sin(phi);
4178
+ const cos = Math.cos(phi);
4179
+ for (let j = 0; j <= last; j++) {
4180
+ vertices.push(px(j) * sin, py(j), px(j) * cos);
4181
+ uvs.push(i / segments, j / (points.length - 1));
4182
+ const x = initNormals[3 * j + 0] * sin;
4183
+ const y = initNormals[3 * j + 1];
4184
+ const z = initNormals[3 * j + 0] * cos;
4185
+ normals.push(x, y, z);
4186
+ }
4187
+ }
4188
+ for (let i = 0; i < segments; i++) {
4189
+ for (let j = 0; j < points.length - 1; j++) {
4190
+ const base = j + i * points.length;
4191
+ const a = base;
4192
+ const b = base + points.length;
4193
+ const c = base + points.length + 1;
4194
+ const d = base + 1;
4195
+ indices.push(a, b, d);
4196
+ indices.push(c, d, b);
4197
+ }
4198
+ }
4199
+ return pack("LatheGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
4200
+ }
4201
+ function torus(radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48, arc = Math.PI * 2) {
4202
+ const parameters = { radius, tube, radialSegments, tubularSegments, arc };
4203
+ radialSegments = Math.floor(radialSegments);
4204
+ tubularSegments = Math.floor(tubularSegments);
4205
+ const indices = [];
4206
+ const vertices = [];
4207
+ const normals = [];
4208
+ const uvs = [];
4209
+ for (let j = 0; j <= radialSegments; j++) {
4210
+ for (let i = 0; i <= tubularSegments; i++) {
4211
+ const u = i / tubularSegments * arc;
4212
+ const v = j / radialSegments * Math.PI * 2;
4213
+ const x = (radius + tube * Math.cos(v)) * Math.cos(u);
4214
+ const y = (radius + tube * Math.cos(v)) * Math.sin(u);
4215
+ const z = tube * Math.sin(v);
4216
+ vertices.push(x, y, z);
4217
+ const cx = radius * Math.cos(u);
4218
+ const cy = radius * Math.sin(u);
4219
+ const n = normalize3(x - cx, y - cy, z - 0);
4220
+ normals.push(n[0], n[1], n[2]);
4221
+ uvs.push(i / tubularSegments);
4222
+ uvs.push(j / radialSegments);
4223
+ }
4224
+ }
4225
+ for (let j = 1; j <= radialSegments; j++) {
4226
+ for (let i = 1; i <= tubularSegments; i++) {
4227
+ const a = (tubularSegments + 1) * j + i - 1;
4228
+ const b = (tubularSegments + 1) * (j - 1) + i - 1;
4229
+ const c = (tubularSegments + 1) * (j - 1) + i;
4230
+ const d = (tubularSegments + 1) * j + i;
4231
+ indices.push(a, b, d);
4232
+ indices.push(b, c, d);
4233
+ }
4234
+ }
4235
+ return pack("TorusGeometry", parameters, { vertices, normals, uvs, indices, groups: [] });
4236
+ }
4237
+ function difference(size, subtract) {
4238
+ const [w, h, d] = size;
4239
+ const hw = w / 2;
4240
+ const hh = h / 2;
4241
+ const hd = d / 2;
4242
+ const holes = subtract.map((hole) => ({ x0: Math.max(-hw, Math.min(hole.min[0], hole.max[0])), x1: Math.min(hw, Math.max(hole.min[0], hole.max[0])), y0: Math.max(-hh, Math.min(hole.min[1], hole.max[1])), y1: Math.min(hh, Math.max(hole.min[1], hole.max[1])) })).filter((hole) => hole.x1 > hole.x0 && hole.y1 > hole.y0);
4243
+ const cuts = (lo, hi, values) => [.../* @__PURE__ */ new Set([lo, hi, ...values.filter((v) => v > lo && v < hi)])].sort((a, b) => a - b);
4244
+ const xs = cuts(-hw, hw, holes.flatMap((hole) => [hole.x0, hole.x1]));
4245
+ const ys = cuts(-hh, hh, holes.flatMap((hole) => [hole.y0, hole.y1]));
4246
+ const nx = xs.length - 1;
4247
+ const ny = ys.length - 1;
4248
+ const solid = (i, j) => {
4249
+ if (i < 0 || j < 0 || i >= nx || j >= ny) return false;
4250
+ const cx = (xs[i] + xs[i + 1]) / 2;
4251
+ const cy = (ys[j] + ys[j + 1]) / 2;
4252
+ return !holes.some((hole) => cx > hole.x0 && cx < hole.x1 && cy > hole.y0 && cy < hole.y1);
4253
+ };
4254
+ const positions = [];
4255
+ const normals = [];
4256
+ const uvs = [];
4257
+ const indices = [];
4258
+ const quad = (corners, normal, uv) => {
4259
+ const base = positions.length / 3;
4260
+ for (let k = 0; k < 4; k++) {
4261
+ positions.push(...corners[k]);
4262
+ normals.push(...normal);
4263
+ uvs.push(...uv[k]);
4264
+ }
4265
+ indices.push(base, base + 1, base + 2, base, base + 2, base + 3);
4266
+ };
4267
+ const fu = (x) => (x + hw) / w;
4268
+ const fv = (y) => (y + hh) / h;
4269
+ for (let j = 0; j < ny; j++) {
4270
+ for (let i = 0; i < nx; i++) {
4271
+ if (!solid(i, j)) continue;
4272
+ const x0 = xs[i];
4273
+ const x1 = xs[i + 1];
4274
+ const y0 = ys[j];
4275
+ const y1 = ys[j + 1];
4276
+ quad([[x0, y0, hd], [x1, y0, hd], [x1, y1, hd], [x0, y1, hd]], [0, 0, 1], [[fu(x0), fv(y0)], [fu(x1), fv(y0)], [fu(x1), fv(y1)], [fu(x0), fv(y1)]]);
4277
+ quad([[x1, y0, -hd], [x0, y0, -hd], [x0, y1, -hd], [x1, y1, -hd]], [0, 0, -1], [[1 - fu(x1), fv(y0)], [1 - fu(x0), fv(y0)], [1 - fu(x0), fv(y1)], [1 - fu(x1), fv(y1)]]);
4278
+ const zu = (z) => (z + hd) / d;
4279
+ if (!solid(i - 1, j)) quad([[x0, y0, -hd], [x0, y0, hd], [x0, y1, hd], [x0, y1, -hd]], [-1, 0, 0], [[zu(-hd), fv(y0)], [zu(hd), fv(y0)], [zu(hd), fv(y1)], [zu(-hd), fv(y1)]]);
4280
+ if (!solid(i + 1, j)) quad([[x1, y0, hd], [x1, y0, -hd], [x1, y1, -hd], [x1, y1, hd]], [1, 0, 0], [[zu(hd), fv(y0)], [zu(-hd), fv(y0)], [zu(-hd), fv(y1)], [zu(hd), fv(y1)]]);
4281
+ if (!solid(i, j - 1)) quad([[x0, y0, -hd], [x1, y0, -hd], [x1, y0, hd], [x0, y0, hd]], [0, -1, 0], [[fu(x0), zu(-hd)], [fu(x1), zu(-hd)], [fu(x1), zu(hd)], [fu(x0), zu(hd)]]);
4282
+ if (!solid(i, j + 1)) quad([[x0, y1, hd], [x1, y1, hd], [x1, y1, -hd], [x0, y1, -hd]], [0, 1, 0], [[fu(x0), zu(hd)], [fu(x1), zu(hd)], [fu(x1), zu(-hd)], [fu(x0), zu(-hd)]]);
4283
+ }
4284
+ }
4285
+ return {
4286
+ type: "BufferGeometry",
4287
+ parameters: { size: [w, h, d], subtract: holes.map((hole) => ({ min: [hole.x0, hole.y0], max: [hole.x1, hole.y1] })) },
4288
+ positions: new Float32Array(positions),
4289
+ normals: new Float32Array(normals),
4290
+ uvs: new Float32Array(uvs),
4291
+ indices: indexArray(indices),
4292
+ groups: []
4293
+ };
4294
+ }
4295
+ var Earcut = {
4296
+ triangulate: function(data, holeIndices, dim = 2) {
4297
+ const hasHoles = holeIndices && holeIndices.length;
4298
+ const outerLen = hasHoles ? holeIndices[0] * dim : data.length;
4299
+ let outerNode = linkedList(data, 0, outerLen, dim, true);
4300
+ const triangles = [];
4301
+ if (!outerNode || outerNode.next === outerNode.prev) return triangles;
4302
+ let minX, minY, maxX, maxY, x, y, invSize;
4303
+ if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
4304
+ if (data.length > 80 * dim) {
4305
+ minX = maxX = data[0];
4306
+ minY = maxY = data[1];
4307
+ for (let i = dim; i < outerLen; i += dim) {
4308
+ x = data[i];
4309
+ y = data[i + 1];
4310
+ if (x < minX) minX = x;
4311
+ if (y < minY) minY = y;
4312
+ if (x > maxX) maxX = x;
4313
+ if (y > maxY) maxY = y;
4314
+ }
4315
+ invSize = Math.max(maxX - minX, maxY - minY);
4316
+ invSize = invSize !== 0 ? 32767 / invSize : 0;
4317
+ }
4318
+ earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
4319
+ return triangles;
4320
+ }
4321
+ };
4322
+ function linkedList(data, start, end, dim, clockwise) {
4323
+ let i, last;
4324
+ if (clockwise === signedArea(data, start, end, dim) > 0) {
4325
+ for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
4326
+ } else {
4327
+ for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
4328
+ }
4329
+ if (last && equals(last, last.next)) {
4330
+ removeNode(last);
4331
+ last = last.next;
4332
+ }
4333
+ return last;
4334
+ }
4335
+ function filterPoints(start, end) {
4336
+ if (!start) return start;
4337
+ if (!end) end = start;
4338
+ let p2 = start, again;
4339
+ do {
4340
+ again = false;
4341
+ if (!p2.steiner && (equals(p2, p2.next) || area(p2.prev, p2, p2.next) === 0)) {
4342
+ removeNode(p2);
4343
+ p2 = end = p2.prev;
4344
+ if (p2 === p2.next) break;
4345
+ again = true;
4346
+ } else {
4347
+ p2 = p2.next;
4348
+ }
4349
+ } while (again || p2 !== end);
4350
+ return end;
4351
+ }
4352
+ function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
4353
+ if (!ear) return;
4354
+ if (!pass && invSize) indexCurve(ear, minX, minY, invSize);
4355
+ let stop = ear, prev, next;
4356
+ while (ear.prev !== ear.next) {
4357
+ prev = ear.prev;
4358
+ next = ear.next;
4359
+ if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
4360
+ triangles.push(prev.i / dim | 0);
4361
+ triangles.push(ear.i / dim | 0);
4362
+ triangles.push(next.i / dim | 0);
4363
+ removeNode(ear);
4364
+ ear = next.next;
4365
+ stop = next.next;
4366
+ continue;
4367
+ }
4368
+ ear = next;
4369
+ if (ear === stop) {
4370
+ if (!pass) {
4371
+ earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);
4372
+ } else if (pass === 1) {
4373
+ ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
4374
+ earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
4375
+ } else if (pass === 2) {
4376
+ splitEarcut(ear, triangles, dim, minX, minY, invSize);
4377
+ }
4378
+ break;
4379
+ }
4380
+ }
4381
+ }
4382
+ function isEar(ear) {
4383
+ const a = ear.prev, b = ear, c = ear.next;
4384
+ if (area(a, b, c) >= 0) return false;
4385
+ const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
4386
+ const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
4387
+ let p2 = c.next;
4388
+ while (p2 !== a) {
4389
+ if (p2.x >= x0 && p2.x <= x1 && p2.y >= y0 && p2.y <= y1 && pointInTriangle(ax, ay, bx, by, cx, cy, p2.x, p2.y) && area(p2.prev, p2, p2.next) >= 0) return false;
4390
+ p2 = p2.next;
4391
+ }
4392
+ return true;
4393
+ }
4394
+ function isEarHashed(ear, minX, minY, invSize) {
4395
+ const a = ear.prev, b = ear, c = ear.next;
4396
+ if (area(a, b, c) >= 0) return false;
4397
+ const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
4398
+ const x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
4399
+ const minZ = zOrder(x0, y0, minX, minY, invSize), maxZ = zOrder(x1, y1, minX, minY, invSize);
4400
+ let p2 = ear.prevZ, n = ear.nextZ;
4401
+ while (p2 && p2.z >= minZ && n && n.z <= maxZ) {
4402
+ if (p2.x >= x0 && p2.x <= x1 && p2.y >= y0 && p2.y <= y1 && p2 !== a && p2 !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p2.x, p2.y) && area(p2.prev, p2, p2.next) >= 0) return false;
4403
+ p2 = p2.prevZ;
4404
+ if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
4405
+ n = n.nextZ;
4406
+ }
4407
+ while (p2 && p2.z >= minZ) {
4408
+ if (p2.x >= x0 && p2.x <= x1 && p2.y >= y0 && p2.y <= y1 && p2 !== a && p2 !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p2.x, p2.y) && area(p2.prev, p2, p2.next) >= 0) return false;
4409
+ p2 = p2.prevZ;
4410
+ }
4411
+ while (n && n.z <= maxZ) {
4412
+ if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
4413
+ n = n.nextZ;
4414
+ }
4415
+ return true;
4416
+ }
4417
+ function cureLocalIntersections(start, triangles, dim) {
4418
+ let p2 = start;
4419
+ do {
4420
+ const a = p2.prev, b = p2.next.next;
4421
+ if (!equals(a, b) && intersects(a, p2, p2.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
4422
+ triangles.push(a.i / dim | 0);
4423
+ triangles.push(p2.i / dim | 0);
4424
+ triangles.push(b.i / dim | 0);
4425
+ removeNode(p2);
4426
+ removeNode(p2.next);
4427
+ p2 = start = b;
4428
+ }
4429
+ p2 = p2.next;
4430
+ } while (p2 !== start);
4431
+ return filterPoints(p2);
4432
+ }
4433
+ function splitEarcut(start, triangles, dim, minX, minY, invSize) {
4434
+ let a = start;
4435
+ do {
4436
+ let b = a.next.next;
4437
+ while (b !== a.prev) {
4438
+ if (a.i !== b.i && isValidDiagonal(a, b)) {
4439
+ let c = splitPolygon(a, b);
4440
+ a = filterPoints(a, a.next);
4441
+ c = filterPoints(c, c.next);
4442
+ earcutLinked(a, triangles, dim, minX, minY, invSize, 0);
4443
+ earcutLinked(c, triangles, dim, minX, minY, invSize, 0);
4444
+ return;
4445
+ }
4446
+ b = b.next;
4447
+ }
4448
+ a = a.next;
4449
+ } while (a !== start);
4450
+ }
4451
+ function eliminateHoles(data, holeIndices, outerNode, dim) {
4452
+ const queue = [];
4453
+ let i, len, start, end, list2;
4454
+ for (i = 0, len = holeIndices.length; i < len; i++) {
4455
+ start = holeIndices[i] * dim;
4456
+ end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
4457
+ list2 = linkedList(data, start, end, dim, false);
4458
+ if (list2 === list2.next) list2.steiner = true;
4459
+ queue.push(getLeftmost(list2));
4460
+ }
4461
+ queue.sort(compareX);
4462
+ for (i = 0; i < queue.length; i++) {
4463
+ outerNode = eliminateHole(queue[i], outerNode);
4464
+ }
4465
+ return outerNode;
4466
+ }
4467
+ function compareX(a, b) {
4468
+ return a.x - b.x;
4469
+ }
4470
+ function eliminateHole(hole, outerNode) {
4471
+ const bridge = findHoleBridge(hole, outerNode);
4472
+ if (!bridge) {
4473
+ return outerNode;
4474
+ }
4475
+ const bridgeReverse = splitPolygon(bridge, hole);
4476
+ filterPoints(bridgeReverse, bridgeReverse.next);
4477
+ return filterPoints(bridge, bridge.next);
4478
+ }
4479
+ function findHoleBridge(hole, outerNode) {
4480
+ let p2 = outerNode, qx = -Infinity, m;
4481
+ const hx = hole.x, hy = hole.y;
4482
+ do {
4483
+ if (hy <= p2.y && hy >= p2.next.y && p2.next.y !== p2.y) {
4484
+ const x = p2.x + (hy - p2.y) * (p2.next.x - p2.x) / (p2.next.y - p2.y);
4485
+ if (x <= hx && x > qx) {
4486
+ qx = x;
4487
+ m = p2.x < p2.next.x ? p2 : p2.next;
4488
+ if (x === hx) return m;
4489
+ }
4490
+ }
4491
+ p2 = p2.next;
4492
+ } while (p2 !== outerNode);
4493
+ if (!m) return null;
4494
+ const stop = m, mx = m.x, my = m.y;
4495
+ let tanMin = Infinity, tan;
4496
+ p2 = m;
4497
+ do {
4498
+ if (hx >= p2.x && p2.x >= mx && hx !== p2.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p2.x, p2.y)) {
4499
+ tan = Math.abs(hy - p2.y) / (hx - p2.x);
4500
+ if (locallyInside(p2, hole) && (tan < tanMin || tan === tanMin && (p2.x > m.x || p2.x === m.x && sectorContainsSector(m, p2)))) {
4501
+ m = p2;
4502
+ tanMin = tan;
4503
+ }
4504
+ }
4505
+ p2 = p2.next;
4506
+ } while (p2 !== stop);
4507
+ return m;
4508
+ }
4509
+ function sectorContainsSector(m, p2) {
4510
+ return area(m.prev, m, p2.prev) < 0 && area(p2.next, m, m.next) < 0;
4511
+ }
4512
+ function indexCurve(start, minX, minY, invSize) {
4513
+ let p2 = start;
4514
+ do {
4515
+ if (p2.z === 0) p2.z = zOrder(p2.x, p2.y, minX, minY, invSize);
4516
+ p2.prevZ = p2.prev;
4517
+ p2.nextZ = p2.next;
4518
+ p2 = p2.next;
4519
+ } while (p2 !== start);
4520
+ p2.prevZ.nextZ = null;
4521
+ p2.prevZ = null;
4522
+ sortLinked(p2);
4523
+ }
4524
+ function sortLinked(list2) {
4525
+ let i, p2, q, e, tail, numMerges, pSize, qSize, inSize = 1;
4526
+ do {
4527
+ p2 = list2;
4528
+ list2 = null;
4529
+ tail = null;
4530
+ numMerges = 0;
4531
+ while (p2) {
4532
+ numMerges++;
4533
+ q = p2;
4534
+ pSize = 0;
4535
+ for (i = 0; i < inSize; i++) {
4536
+ pSize++;
4537
+ q = q.nextZ;
4538
+ if (!q) break;
4539
+ }
4540
+ qSize = inSize;
4541
+ while (pSize > 0 || qSize > 0 && q) {
4542
+ if (pSize !== 0 && (qSize === 0 || !q || p2.z <= q.z)) {
4543
+ e = p2;
4544
+ p2 = p2.nextZ;
4545
+ pSize--;
4546
+ } else {
4547
+ e = q;
4548
+ q = q.nextZ;
4549
+ qSize--;
4550
+ }
4551
+ if (tail) tail.nextZ = e;
4552
+ else list2 = e;
4553
+ e.prevZ = tail;
4554
+ tail = e;
4555
+ }
4556
+ p2 = q;
4557
+ }
4558
+ tail.nextZ = null;
4559
+ inSize *= 2;
4560
+ } while (numMerges > 1);
4561
+ return list2;
4562
+ }
4563
+ function zOrder(x, y, minX, minY, invSize) {
4564
+ x = (x - minX) * invSize | 0;
4565
+ y = (y - minY) * invSize | 0;
4566
+ x = (x | x << 8) & 16711935;
4567
+ x = (x | x << 4) & 252645135;
4568
+ x = (x | x << 2) & 858993459;
4569
+ x = (x | x << 1) & 1431655765;
4570
+ y = (y | y << 8) & 16711935;
4571
+ y = (y | y << 4) & 252645135;
4572
+ y = (y | y << 2) & 858993459;
4573
+ y = (y | y << 1) & 1431655765;
4574
+ return x | y << 1;
4575
+ }
4576
+ function getLeftmost(start) {
4577
+ let p2 = start, leftmost = start;
4578
+ do {
4579
+ if (p2.x < leftmost.x || p2.x === leftmost.x && p2.y < leftmost.y) leftmost = p2;
4580
+ p2 = p2.next;
4581
+ } while (p2 !== start);
4582
+ return leftmost;
4583
+ }
4584
+ function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
4585
+ return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
4586
+ }
4587
+ function isValidDiagonal(a, b) {
4588
+ return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges
4589
+ (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible
4590
+ (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
4591
+ equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0);
4592
+ }
4593
+ function area(p2, q, r) {
4594
+ return (q.y - p2.y) * (r.x - q.x) - (q.x - p2.x) * (r.y - q.y);
4595
+ }
4596
+ function equals(p1, p2) {
4597
+ return p1.x === p2.x && p1.y === p2.y;
4598
+ }
4599
+ function intersects(p1, q1, p2, q2) {
4600
+ const o1 = sign(area(p1, q1, p2));
4601
+ const o2 = sign(area(p1, q1, q2));
4602
+ const o3 = sign(area(p2, q2, p1));
4603
+ const o4 = sign(area(p2, q2, q1));
4604
+ if (o1 !== o2 && o3 !== o4) return true;
4605
+ if (o1 === 0 && onSegment(p1, p2, q1)) return true;
4606
+ if (o2 === 0 && onSegment(p1, q2, q1)) return true;
4607
+ if (o3 === 0 && onSegment(p2, p1, q2)) return true;
4608
+ if (o4 === 0 && onSegment(p2, q1, q2)) return true;
4609
+ return false;
4610
+ }
4611
+ function onSegment(p2, q, r) {
4612
+ return q.x <= Math.max(p2.x, r.x) && q.x >= Math.min(p2.x, r.x) && q.y <= Math.max(p2.y, r.y) && q.y >= Math.min(p2.y, r.y);
4613
+ }
4614
+ function sign(num2) {
4615
+ return num2 > 0 ? 1 : num2 < 0 ? -1 : 0;
4616
+ }
4617
+ function intersectsPolygon(a, b) {
4618
+ let p2 = a;
4619
+ do {
4620
+ if (p2.i !== a.i && p2.next.i !== a.i && p2.i !== b.i && p2.next.i !== b.i && intersects(p2, p2.next, a, b)) return true;
4621
+ p2 = p2.next;
4622
+ } while (p2 !== a);
4623
+ return false;
4624
+ }
4625
+ function locallyInside(a, b) {
4626
+ return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
4627
+ }
4628
+ function middleInside(a, b) {
4629
+ let p2 = a, inside = false;
4630
+ const px = (a.x + b.x) / 2, py = (a.y + b.y) / 2;
4631
+ do {
4632
+ if (p2.y > py !== p2.next.y > py && p2.next.y !== p2.y && px < (p2.next.x - p2.x) * (py - p2.y) / (p2.next.y - p2.y) + p2.x)
4633
+ inside = !inside;
4634
+ p2 = p2.next;
4635
+ } while (p2 !== a);
4636
+ return inside;
4637
+ }
4638
+ function splitPolygon(a, b) {
4639
+ const a2 = new Node(a.i, a.x, a.y), b2 = new Node(b.i, b.x, b.y), an = a.next, bp = b.prev;
4640
+ a.next = b;
4641
+ b.prev = a;
4642
+ a2.next = an;
4643
+ an.prev = a2;
4644
+ b2.next = a2;
4645
+ a2.prev = b2;
4646
+ bp.next = b2;
4647
+ b2.prev = bp;
4648
+ return b2;
4649
+ }
4650
+ function insertNode(i, x, y, last) {
4651
+ const p2 = new Node(i, x, y);
4652
+ if (!last) {
4653
+ p2.prev = p2;
4654
+ p2.next = p2;
4655
+ } else {
4656
+ p2.next = last.next;
4657
+ p2.prev = last;
4658
+ last.next.prev = p2;
4659
+ last.next = p2;
4660
+ }
4661
+ return p2;
4662
+ }
4663
+ function removeNode(p2) {
4664
+ p2.next.prev = p2.prev;
4665
+ p2.prev.next = p2.next;
4666
+ if (p2.prevZ) p2.prevZ.nextZ = p2.nextZ;
4667
+ if (p2.nextZ) p2.nextZ.prevZ = p2.prevZ;
4668
+ }
4669
+ function Node(i, x, y) {
4670
+ this.i = i;
4671
+ this.x = x;
4672
+ this.y = y;
4673
+ this.prev = null;
4674
+ this.next = null;
4675
+ this.z = 0;
4676
+ this.prevZ = null;
4677
+ this.nextZ = null;
4678
+ this.steiner = false;
4679
+ }
4680
+ function signedArea(data, start, end, dim) {
4681
+ let sum = 0;
4682
+ for (let i = start, j = end - dim; i < end; i += dim) {
4683
+ sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
4684
+ j = i;
4685
+ }
4686
+ return sum;
4687
+ }
4688
+ var equals2 = (a, b) => a.x === b.x && a.y === b.y;
4689
+ var linePoint = (v1, v2, t) => t === 1 ? { x: v2.x, y: v2.y } : { x: (v2.x - v1.x) * t + v1.x, y: (v2.y - v1.y) * t + v1.y };
4690
+ function pathPoints(points) {
4691
+ const out = [];
4692
+ let last;
4693
+ for (let i = 1; i < points.length; i++) {
4694
+ const v1 = { x: points[i - 1][0], y: points[i - 1][1] };
4695
+ const v2 = { x: points[i][0], y: points[i][1] };
4696
+ for (let d = 0; d <= 1; d++) {
4697
+ const point = linePoint(v1, v2, d / 1);
4698
+ if (last && equals2(last, point)) continue;
4699
+ out.push(point);
4700
+ last = point;
4701
+ }
4702
+ }
4703
+ return out;
4704
+ }
4705
+ function area2(contour) {
4706
+ const n = contour.length;
4707
+ let a = 0;
4708
+ for (let p2 = n - 1, q = 0; q < n; p2 = q++) a += contour[p2].x * contour[q].y - contour[q].x * contour[p2].y;
4709
+ return a * 0.5;
4710
+ }
4711
+ var isClockWise = (pts) => area2(pts) < 0;
4712
+ function removeDupEndPts(points) {
4713
+ const l = points.length;
4714
+ if (l > 2 && equals2(points[l - 1], points[0])) points.pop();
4715
+ }
4716
+ function triangulateShape(contour, holes) {
4717
+ const vertices = [];
4718
+ const holeIndices = [];
4719
+ const faces = [];
4720
+ removeDupEndPts(contour);
4721
+ for (const p2 of contour) vertices.push(p2.x, p2.y);
4722
+ let holeIndex = contour.length;
4723
+ holes.forEach(removeDupEndPts);
4724
+ for (let i = 0; i < holes.length; i++) {
4725
+ holeIndices.push(holeIndex);
4726
+ holeIndex += holes[i].length;
4727
+ for (const p2 of holes[i]) vertices.push(p2.x, p2.y);
4728
+ }
4729
+ const triangles = Earcut.triangulate(vertices, holeIndices);
4730
+ for (let i = 0; i < triangles.length; i += 3) faces.push(triangles.slice(i, i + 3));
4731
+ return faces;
4732
+ }
4733
+ function computeVertexNormals(positions, indices) {
4734
+ const normals = new Float32Array(positions.length);
4735
+ const get = (array, i) => [array[i * 3], array[i * 3 + 1], array[i * 3 + 2]];
4736
+ const face = (vA, vB, vC) => {
4737
+ const pA = get(positions, vA);
4738
+ const pB = get(positions, vB);
4739
+ const pC = get(positions, vC);
4740
+ const cb = [pC[0] - pB[0], pC[1] - pB[1], pC[2] - pB[2]];
4741
+ const ab = [pA[0] - pB[0], pA[1] - pB[1], pA[2] - pB[2]];
4742
+ return [cb[1] * ab[2] - cb[2] * ab[1], cb[2] * ab[0] - cb[0] * ab[2], cb[0] * ab[1] - cb[1] * ab[0]];
4743
+ };
4744
+ const set = (i, x, y, z) => {
4745
+ normals[i * 3] = x;
4746
+ normals[i * 3 + 1] = y;
4747
+ normals[i * 3 + 2] = z;
4748
+ };
4749
+ if (indices) {
4750
+ for (let i = 0; i < indices.length; i += 3) {
4751
+ const vA = indices[i];
4752
+ const vB = indices[i + 1];
4753
+ const vC = indices[i + 2];
4754
+ const cb = face(vA, vB, vC);
4755
+ for (const v of [vA, vB, vC]) {
4756
+ const n = get(normals, v);
4757
+ set(v, n[0] + cb[0], n[1] + cb[1], n[2] + cb[2]);
4758
+ }
4759
+ }
4760
+ } else {
4761
+ for (let i = 0; i < positions.length / 3; i += 3) {
4762
+ const cb = face(i, i + 1, i + 2);
4763
+ set(i, cb[0], cb[1], cb[2]);
4764
+ set(i + 1, cb[0], cb[1], cb[2]);
4765
+ set(i + 2, cb[0], cb[1], cb[2]);
4766
+ }
4767
+ }
4768
+ for (let i = 0; i < normals.length / 3; i++) {
4769
+ const [x, y, z] = get(normals, i);
4770
+ const s = 1 / (Math.sqrt(x * x + y * y + z * z) || 1);
4771
+ set(i, x * s, y * s, z * s);
4772
+ }
4773
+ return normals;
4774
+ }
4775
+ function extrude(outline, depth = 1, steps = 1, bevel = void 0) {
4776
+ const parameters = { shape: outline, depth, steps, bevel: bevel ?? {} };
4777
+ const verticesArray = [];
4778
+ const uvArray = [];
4779
+ const groups = [];
4780
+ const placeholder = [];
4781
+ const bevelEnabled = bevel !== false;
4782
+ const spec = bevel === false || bevel === void 0 ? {} : bevel;
4783
+ let bevelThickness = spec.thickness !== void 0 ? spec.thickness : 0.2;
4784
+ let bevelSize = spec.size !== void 0 ? spec.size : bevelThickness - 0.1;
4785
+ let bevelOffset = spec.offset !== void 0 ? spec.offset : 0;
4786
+ let bevelSegments = spec.segments !== void 0 ? spec.segments : 3;
4787
+ if (!bevelEnabled) {
4788
+ bevelSegments = 0;
4789
+ bevelThickness = 0;
4790
+ bevelSize = 0;
4791
+ bevelOffset = 0;
4792
+ }
4793
+ let vertices = pathPoints(outline.outer);
4794
+ const holes = (outline.holes ?? []).map(pathPoints);
4795
+ const reverse = !isClockWise(vertices);
4796
+ if (reverse) {
4797
+ vertices = vertices.reverse();
4798
+ for (let h = 0; h < holes.length; h++) {
4799
+ const ahole = holes[h];
4800
+ if (isClockWise(ahole)) holes[h] = ahole.reverse();
4801
+ }
4802
+ }
4803
+ const faces = triangulateShape(vertices, holes);
4804
+ const contour = vertices;
4805
+ for (const ahole of holes) vertices = vertices.concat(ahole);
4806
+ const scalePt2 = (pt, vec, size) => ({ x: pt.x + vec.x * size, y: pt.y + vec.y * size });
4807
+ const vlen = vertices.length;
4808
+ const flen = faces.length;
4809
+ const getBevelVec = (inPt, inPrev, inNext) => {
4810
+ let vTransX;
4811
+ let vTransY;
4812
+ let shrinkBy;
4813
+ const vPrevX = inPt.x - inPrev.x;
4814
+ const vPrevY = inPt.y - inPrev.y;
4815
+ const vNextX = inNext.x - inPt.x;
4816
+ const vNextY = inNext.y - inPt.y;
4817
+ const vPrevLensq = vPrevX * vPrevX + vPrevY * vPrevY;
4818
+ const collinear0 = vPrevX * vNextY - vPrevY * vNextX;
4819
+ if (Math.abs(collinear0) > Number.EPSILON) {
4820
+ const vPrevLen = Math.sqrt(vPrevLensq);
4821
+ const vNextLen = Math.sqrt(vNextX * vNextX + vNextY * vNextY);
4822
+ const ptPrevShiftX = inPrev.x - vPrevY / vPrevLen;
4823
+ const ptPrevShiftY = inPrev.y + vPrevX / vPrevLen;
4824
+ const ptNextShiftX = inNext.x - vNextY / vNextLen;
4825
+ const ptNextShiftY = inNext.y + vNextX / vNextLen;
4826
+ const sf = ((ptNextShiftX - ptPrevShiftX) * vNextY - (ptNextShiftY - ptPrevShiftY) * vNextX) / (vPrevX * vNextY - vPrevY * vNextX);
4827
+ vTransX = ptPrevShiftX + vPrevX * sf - inPt.x;
4828
+ vTransY = ptPrevShiftY + vPrevY * sf - inPt.y;
4829
+ const vTransLensq = vTransX * vTransX + vTransY * vTransY;
4830
+ if (vTransLensq <= 2) return { x: vTransX, y: vTransY };
4831
+ shrinkBy = Math.sqrt(vTransLensq / 2);
4832
+ } else {
4833
+ let directionEq = false;
4834
+ if (vPrevX > Number.EPSILON) {
4835
+ if (vNextX > Number.EPSILON) directionEq = true;
4836
+ } else if (vPrevX < -Number.EPSILON) {
4837
+ if (vNextX < -Number.EPSILON) directionEq = true;
4838
+ } else if (Math.sign(vPrevY) === Math.sign(vNextY)) {
4839
+ directionEq = true;
4840
+ }
4841
+ if (directionEq) {
4842
+ vTransX = -vPrevY;
4843
+ vTransY = vPrevX;
4844
+ shrinkBy = Math.sqrt(vPrevLensq);
4845
+ } else {
4846
+ vTransX = vPrevX;
4847
+ vTransY = vPrevY;
4848
+ shrinkBy = Math.sqrt(vPrevLensq / 2);
4849
+ }
4850
+ }
4851
+ return { x: vTransX / shrinkBy, y: vTransY / shrinkBy };
4852
+ };
4853
+ const movements = (ring2) => {
4854
+ const out = [];
4855
+ for (let i = 0, il = ring2.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) {
4856
+ if (j === il) j = 0;
4857
+ if (k === il) k = 0;
4858
+ out[i] = getBevelVec(ring2[i], ring2[j], ring2[k]);
4859
+ }
4860
+ return out;
4861
+ };
4862
+ const contourMovements = movements(contour);
4863
+ const holesMovements = [];
4864
+ let verticesMovements = contourMovements.concat();
4865
+ for (const ahole of holes) {
4866
+ const oneHoleMovements = movements(ahole);
4867
+ holesMovements.push(oneHoleMovements);
4868
+ verticesMovements = verticesMovements.concat(oneHoleMovements);
4869
+ }
4870
+ const v = (x, y, z) => {
4871
+ placeholder.push(x);
4872
+ placeholder.push(y);
4873
+ placeholder.push(z);
4874
+ };
4875
+ const bevelLayer = (b, zOf) => {
4876
+ const t = b / bevelSegments;
4877
+ const z = bevelThickness * Math.cos(t * Math.PI / 2);
4878
+ const bs2 = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset;
4879
+ for (let i = 0; i < contour.length; i++) {
4880
+ const vert = scalePt2(contour[i], contourMovements[i], bs2);
4881
+ v(vert.x, vert.y, zOf(z));
4882
+ }
4883
+ for (let h = 0; h < holes.length; h++) {
4884
+ const ahole = holes[h];
4885
+ const oneHoleMovements = holesMovements[h];
4886
+ for (let i = 0; i < ahole.length; i++) {
4887
+ const vert = scalePt2(ahole[i], oneHoleMovements[i], bs2);
4888
+ v(vert.x, vert.y, zOf(z));
4889
+ }
4890
+ }
4891
+ };
4892
+ for (let b = 0; b < bevelSegments; b++) bevelLayer(b, (z) => -z);
4893
+ const bs = bevelSize + bevelOffset;
4894
+ for (let i = 0; i < vlen; i++) {
4895
+ const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i];
4896
+ v(vert.x, vert.y, 0);
4897
+ }
4898
+ for (let s = 1; s <= steps; s++) {
4899
+ for (let i = 0; i < vlen; i++) {
4900
+ const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i];
4901
+ v(vert.x, vert.y, depth / steps * s);
4902
+ }
4903
+ }
4904
+ for (let b = bevelSegments - 1; b >= 0; b--) bevelLayer(b, (z) => depth + z);
4905
+ const addVertex = (index) => {
4906
+ verticesArray.push(placeholder[index * 3 + 0]);
4907
+ verticesArray.push(placeholder[index * 3 + 1]);
4908
+ verticesArray.push(placeholder[index * 3 + 2]);
4909
+ };
4910
+ const addUV = (x, y) => {
4911
+ uvArray.push(x);
4912
+ uvArray.push(y);
4913
+ };
4914
+ const at = (index, axis) => verticesArray[index * 3 + axis];
4915
+ const f3 = (a, b, c) => {
4916
+ addVertex(a);
4917
+ addVertex(b);
4918
+ addVertex(c);
4919
+ const nextIndex = verticesArray.length / 3;
4920
+ for (const index of [nextIndex - 3, nextIndex - 2, nextIndex - 1]) addUV(at(index, 0), at(index, 1));
4921
+ };
4922
+ const f4 = (a, b, c, d) => {
4923
+ addVertex(a);
4924
+ addVertex(b);
4925
+ addVertex(d);
4926
+ addVertex(b);
4927
+ addVertex(c);
4928
+ addVertex(d);
4929
+ const nextIndex = verticesArray.length / 3;
4930
+ const iA = nextIndex - 6;
4931
+ const iB = nextIndex - 3;
4932
+ const iC = nextIndex - 2;
4933
+ const iD = nextIndex - 1;
4934
+ const byX = Math.abs(at(iA, 1) - at(iB, 1)) < Math.abs(at(iA, 0) - at(iB, 0));
4935
+ const uv = (index) => [byX ? at(index, 0) : at(index, 1), 1 - at(index, 2)];
4936
+ const uvs = [uv(iA), uv(iB), uv(iC), uv(iD)];
4937
+ for (const k of [0, 1, 3, 1, 2, 3]) addUV(...uvs[k]);
4938
+ };
4939
+ let start = verticesArray.length / 3;
4940
+ if (bevelEnabled) {
4941
+ let offset = 0;
4942
+ for (let i = 0; i < flen; i++) {
4943
+ const face = faces[i];
4944
+ f3(face[2] + offset, face[1] + offset, face[0] + offset);
4945
+ }
4946
+ const layer = steps + bevelSegments * 2;
4947
+ offset = vlen * layer;
4948
+ for (let i = 0; i < flen; i++) {
4949
+ const face = faces[i];
4950
+ f3(face[0] + offset, face[1] + offset, face[2] + offset);
4951
+ }
4952
+ } else {
4953
+ for (let i = 0; i < flen; i++) {
4954
+ const face = faces[i];
4955
+ f3(face[2], face[1], face[0]);
4956
+ }
4957
+ for (let i = 0; i < flen; i++) {
4958
+ const face = faces[i];
4959
+ f3(face[0] + vlen * steps, face[1] + vlen * steps, face[2] + vlen * steps);
4960
+ }
4961
+ }
4962
+ groups.push({ start, count: verticesArray.length / 3 - start, materialIndex: 0 });
4963
+ start = verticesArray.length / 3;
4964
+ const sidewalls = (ring2, layeroffset2) => {
4965
+ let i = ring2.length;
4966
+ while (--i >= 0) {
4967
+ const j = i;
4968
+ let k = i - 1;
4969
+ if (k < 0) k = ring2.length - 1;
4970
+ for (let s = 0, sl = steps + bevelSegments * 2; s < sl; s++) {
4971
+ const slen1 = vlen * s;
4972
+ const slen2 = vlen * (s + 1);
4973
+ f4(layeroffset2 + j + slen1, layeroffset2 + k + slen1, layeroffset2 + k + slen2, layeroffset2 + j + slen2);
4974
+ }
4975
+ }
4976
+ };
4977
+ let layeroffset = 0;
4978
+ sidewalls(contour, layeroffset);
4979
+ layeroffset += contour.length;
4980
+ for (const ahole of holes) {
4981
+ sidewalls(ahole, layeroffset);
4982
+ layeroffset += ahole.length;
4983
+ }
4984
+ groups.push({ start, count: verticesArray.length / 3 - start, materialIndex: 1 });
4985
+ const positions = new Float32Array(verticesArray);
4986
+ return { type: "ExtrudeGeometry", parameters, positions, normals: computeVertexNormals(positions), uvs: new Float32Array(uvArray), groups };
4987
+ }
4988
+ var PARAMETER_KEYS = {
4989
+ box: ["size", "segments"],
4990
+ cylinder: ["radiusTop", "radiusBottom", "height", "radialSegments", "heightSegments", "openEnded", "thetaStart", "thetaLength"],
4991
+ cone: ["radius", "height", "radialSegments", "heightSegments", "openEnded", "thetaStart", "thetaLength"],
4992
+ sphere: ["radius", "widthSegments", "heightSegments", "phiStart", "phiLength", "thetaStart", "thetaLength"],
4993
+ plane: ["width", "height", "widthSegments", "heightSegments"],
4994
+ circle: ["radius", "segments", "thetaStart", "thetaLength"],
4995
+ ring: ["innerRadius", "outerRadius", "thetaSegments", "phiSegments", "thetaStart", "thetaLength"],
4996
+ lathe: ["points", "segments", "phiStart", "phiLength"],
4997
+ torus: ["radius", "tube", "radialSegments", "tubularSegments", "arc"],
4998
+ extrude: ["shape", "depth", "steps", "bevel"],
4999
+ difference: ["size", "subtract"],
5000
+ mesh: ["positions", "normals", "uvs", "indices"]
5001
+ };
5002
+ var SEGMENT_KEYS = {
5003
+ cylinder: ["radialSegments"],
5004
+ cone: ["radialSegments"],
5005
+ sphere: ["widthSegments", "heightSegments"],
5006
+ circle: ["segments"],
5007
+ ring: ["thetaSegments"],
5008
+ lathe: ["segments"],
5009
+ torus: ["radialSegments", "tubularSegments"]
5010
+ };
5011
+ var SEGMENT_DEFAULTS = { radialSegments: 32, widthSegments: 32, heightSegments: 16, segments: 12, thetaSegments: 32, tubularSegments: 48 };
5012
+ var segmentDefault = (kind, key) => kind === "circle" && key === "segments" ? 32 : kind === "torus" && key === "radialSegments" ? 12 : SEGMENT_DEFAULTS[key];
5013
+ function primitiveParameters(node, options = {}) {
5014
+ const out = {};
5015
+ const source = node;
5016
+ for (const key of PARAMETER_KEYS[node.kind]) if (source[key] !== void 0) out[key] = source[key];
5017
+ const detail = options.detail ?? 1;
5018
+ if (detail !== 1) {
5019
+ const floor = options.minSegments ?? 3;
5020
+ for (const key of SEGMENT_KEYS[node.kind] ?? []) {
5021
+ const given = out[key] ?? segmentDefault(node.kind, key);
5022
+ out[key] = Math.max(floor, Math.round(given * detail));
5023
+ }
5024
+ }
5025
+ return out;
5026
+ }
5027
+ function mesh(p2) {
5028
+ const positions = new Float32Array(p2.positions);
5029
+ const indices = p2.indices ? indexArray(p2.indices) : void 0;
5030
+ return {
5031
+ type: "BufferGeometry",
5032
+ parameters: {},
5033
+ positions,
5034
+ normals: p2.normals ? new Float32Array(p2.normals) : computeVertexNormals(positions, indices),
5035
+ uvs: p2.uvs ? new Float32Array(p2.uvs) : new Float32Array(positions.length / 3 * 2),
5036
+ ...indices ? { indices } : {},
5037
+ groups: []
5038
+ };
5039
+ }
5040
+ function make(kind, p2) {
5041
+ switch (kind) {
5042
+ case "box": {
5043
+ const size = p2.size ?? [1, 1, 1];
5044
+ const segments = p2.segments ?? [1, 1, 1];
5045
+ return box(size[0], size[1], size[2], segments[0], segments[1], segments[2]);
5046
+ }
5047
+ case "cylinder":
5048
+ return cylinder(p2.radiusTop, p2.radiusBottom, p2.height, p2.radialSegments, p2.heightSegments, p2.openEnded, p2.thetaStart, p2.thetaLength);
5049
+ case "cone":
5050
+ return cone(p2.radius, p2.height, p2.radialSegments, p2.heightSegments, p2.openEnded, p2.thetaStart, p2.thetaLength);
5051
+ case "sphere":
5052
+ return sphere(p2.radius, p2.widthSegments, p2.heightSegments, p2.phiStart, p2.phiLength, p2.thetaStart, p2.thetaLength);
5053
+ case "plane":
5054
+ return plane(p2.width, p2.height, p2.widthSegments, p2.heightSegments);
5055
+ case "circle":
5056
+ return circle(p2.radius, p2.segments, p2.thetaStart, p2.thetaLength);
5057
+ case "ring":
5058
+ return ring(p2.innerRadius, p2.outerRadius, p2.thetaSegments, p2.phiSegments, p2.thetaStart, p2.thetaLength);
5059
+ case "lathe":
5060
+ return lathe(p2.points, p2.segments, p2.phiStart, p2.phiLength);
5061
+ case "torus":
5062
+ return torus(p2.radius, p2.tube, p2.radialSegments, p2.tubularSegments, p2.arc);
5063
+ case "extrude":
5064
+ return extrude(p2.shape, p2.depth, p2.steps, p2.bevel);
5065
+ case "difference":
5066
+ return difference(p2.size, p2.subtract ?? []);
5067
+ case "mesh":
5068
+ return mesh(p2);
5069
+ default:
5070
+ throw new Error(`game-shapes: unknown primitive kind "${String(kind)}"`);
5071
+ }
5072
+ }
5073
+ var templates = /* @__PURE__ */ new Map();
5074
+ var templateLimit = 4096;
5075
+ var stats = { hits: 0, misses: 0 };
5076
+ function buildPrimitive(node, options = {}) {
5077
+ const parameters = primitiveParameters(node, options);
5078
+ if (node.kind === "mesh" || templateLimit === 0) return make(node.kind, parameters);
5079
+ const key = `${node.kind}:${canonicalJson(parameters)}`;
5080
+ const cached = templates.get(key);
5081
+ if (cached) {
5082
+ stats.hits++;
5083
+ templates.delete(key);
5084
+ templates.set(key, cached);
5085
+ return cached;
5086
+ }
5087
+ stats.misses++;
5088
+ const built = make(node.kind, parameters);
5089
+ templates.set(key, built);
5090
+ if (templates.size > templateLimit) templates.delete(templates.keys().next().value);
5091
+ return built;
5092
+ }
5093
+ var num = (v) => typeof v === "number" && Number.isFinite(v) ? null : "expected a finite number";
5094
+ var bool = (v) => typeof v === "boolean" ? null : "expected a boolean";
5095
+ var str = (v) => typeof v === "string" ? null : "expected a string";
5096
+ var int = (min) => (v) => typeof v === "number" && Number.isInteger(v) && v >= min ? null : `expected an integer >= ${min}`;
5097
+ 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}]`;
5098
+ var tuple = (n, item = num) => (v) => {
5099
+ if (!Array.isArray(v) || v.length !== n) return `expected an array of ${n}`;
5100
+ for (const x of v) if (item(x)) return `expected an array of ${n} numbers`;
5101
+ return null;
5102
+ };
5103
+ var list = (item, min = 0) => (v) => {
5104
+ if (!Array.isArray(v)) return "expected an array";
5105
+ if (v.length < min) return `expected at least ${min} items`;
5106
+ for (let i = 0; i < v.length; i++) {
5107
+ const e = item(v[i]);
5108
+ if (e) return `[${i}]: ${e}`;
5109
+ }
5110
+ return null;
5111
+ };
5112
+ 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"';
5113
+ var oneOf = (values) => (v) => values.includes(v) ? null : `expected one of ${values.map((x) => JSON.stringify(x)).join(", ")}`;
5114
+ var object = (fields, required = []) => (v) => {
5115
+ if (!v || typeof v !== "object" || Array.isArray(v)) return "expected an object";
5116
+ const record = v;
5117
+ for (const key of required) if (record[key] === void 0) return `${key}: required`;
5118
+ for (const key of Object.keys(record)) {
5119
+ if (record[key] === void 0) continue;
5120
+ const check = fields[key];
5121
+ if (!check) return `${key}: unknown field`;
5122
+ const e = check(record[key]);
5123
+ if (e) return `${key}: ${e}`;
5124
+ }
5125
+ return null;
5126
+ };
5127
+ var ORDERS = ["XYZ", "YXZ", "ZXY", "ZYX", "YZX", "XZY"];
5128
+ var TRANSFORM = {
5129
+ position: tuple(3),
5130
+ rotation: tuple(3),
5131
+ rotationOrder: oneOf(ORDERS),
5132
+ scale: (v) => typeof v === "number" ? num(v) : tuple(3)(v),
5133
+ heading: num,
5134
+ matrix: tuple(16)
5135
+ };
5136
+ var UV = object({ u0: num, v0: num, u1: num, v1: num }, ["u0", "v0", "u1", "v1"]);
5137
+ var INSTANCE = object({ ...TRANSFORM, color });
5138
+ var COMMON = {
5139
+ ...TRANSFORM,
5140
+ kind: str,
5141
+ name: str,
5142
+ part: str,
5143
+ material: str,
5144
+ color,
5145
+ uv: UV,
5146
+ instances: list(INSTANCE),
5147
+ minDetail: range(0, 1, true),
5148
+ tags: list(str)
5149
+ };
5150
+ var vec2 = tuple(2);
5151
+ var BEVEL = (v) => v === false ? null : object({ thickness: num, size: num, offset: num, segments: int(1) })(v);
5152
+ var KINDS = {
5153
+ group: { fields: {} },
5154
+ box: { fields: { size: tuple(3), segments: tuple(3, int(1)) } },
5155
+ cylinder: { fields: { radiusTop: num, radiusBottom: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },
5156
+ cone: { fields: { radius: num, height: num, radialSegments: int(1), heightSegments: int(1), openEnded: bool, thetaStart: num, thetaLength: num } },
5157
+ sphere: { fields: { radius: num, widthSegments: int(3), heightSegments: int(2), phiStart: num, phiLength: num, thetaStart: num, thetaLength: num } },
5158
+ plane: { fields: { width: num, height: num, widthSegments: int(1), heightSegments: int(1) } },
5159
+ circle: { fields: { radius: num, segments: int(3), thetaStart: num, thetaLength: num } },
5160
+ ring: { fields: { innerRadius: num, outerRadius: num, thetaSegments: int(3), phiSegments: int(1), thetaStart: num, thetaLength: num } },
5161
+ lathe: { fields: { points: list(vec2, 2), segments: int(1), phiStart: num, phiLength: num }, required: ["points"] },
5162
+ torus: { fields: { radius: num, tube: num, radialSegments: int(1), tubularSegments: int(1), arc: num } },
5163
+ extrude: {
5164
+ fields: { shape: object({ outer: list(vec2, 3), holes: list(list(vec2, 3)) }, ["outer"]), depth: num, steps: int(1), bevel: BEVEL },
5165
+ required: ["shape"]
5166
+ },
5167
+ difference: { fields: { size: tuple(3), subtract: list(object({ min: vec2, max: vec2 }, ["min", "max"])) }, required: ["size", "subtract"] },
5168
+ mesh: {
5169
+ fields: {
5170
+ positions: (v) => list(num)(v) ?? (v.length % 3 === 0 ? null : "expected a multiple of 3 numbers"),
5171
+ normals: list(num),
5172
+ uvs: list(num),
5173
+ indices: list(int(0))
5174
+ },
5175
+ required: ["positions"]
5176
+ },
5177
+ point: { fields: { data: () => null } },
5178
+ custom: { fields: { generator: str, params: () => null }, required: ["generator"] }
5179
+ };
5180
+
5181
+ // ../game-shapes-three/dist/index.js
5182
+ var UV_BEFORE_NORMAL = /* @__PURE__ */ new Set(["LatheGeometry", "ExtrudeGeometry"]);
5183
+ var INDEX_FIRST = /* @__PURE__ */ new Set(["BoxGeometry", "CylinderGeometry", "ConeGeometry", "SphereGeometry", "PlaneGeometry", "CircleGeometry", "RingGeometry", "LatheGeometry", "TorusGeometry"]);
5184
+ var isPrimitive = (value) => typeof value.type === "string";
5185
+ function threeParameters(THREE, p2) {
5186
+ if (p2.type === "LatheGeometry") {
5187
+ const points = p2.parameters.points.map(({ x, y }) => new THREE.Vector2(x, y));
5188
+ return { ...p2.parameters, points };
5189
+ }
5190
+ return { ...p2.parameters };
5191
+ }
5192
+ function toGeometry(THREE, source, options = {}) {
5193
+ const copy = options.copy !== false;
5194
+ const primitive = isPrimitive(source) ? source : null;
5195
+ const ThreeClass = primitive && primitive.type !== "BufferGeometry" ? THREE[primitive.type] : void 0;
5196
+ const geometry = ThreeClass ? Reflect.construct(THREE.BufferGeometry, [], ThreeClass) : new THREE.BufferGeometry();
5197
+ if (primitive && ThreeClass) {
5198
+ Object.assign(geometry, { type: primitive.type, parameters: threeParameters(THREE, primitive) });
5199
+ }
5200
+ const attribute = (array, size) => copy ? new THREE.Float32BufferAttribute(array, size) : new THREE.BufferAttribute(array, size);
5201
+ const index = source.indices;
5202
+ const setIndex = () => {
5203
+ if (!index) return;
5204
+ geometry.setIndex(copy ? index instanceof Uint32Array ? new THREE.Uint32BufferAttribute(index, 1) : new THREE.Uint16BufferAttribute(index, 1) : new THREE.BufferAttribute(index, 1));
5205
+ };
5206
+ const type = primitive?.type ?? "BufferGeometry";
5207
+ if (INDEX_FIRST.has(type)) setIndex();
5208
+ geometry.setAttribute("position", attribute(source.positions, 3));
5209
+ if (UV_BEFORE_NORMAL.has(type)) {
5210
+ geometry.setAttribute("uv", attribute(source.uvs, 2));
5211
+ geometry.setAttribute("normal", attribute(source.normals, 3));
5212
+ } else {
5213
+ geometry.setAttribute("normal", attribute(source.normals, 3));
5214
+ geometry.setAttribute("uv", attribute(source.uvs, 2));
5215
+ }
5216
+ if (!primitive && source.colors) geometry.setAttribute("color", attribute(source.colors, 3));
5217
+ if (!INDEX_FIRST.has(type)) setIndex();
5218
+ if (primitive) for (const group of primitive.groups) geometry.addGroup(group.start, group.count, group.materialIndex);
5219
+ return geometry;
5220
+ }
5221
+ var SHAPE_GEOMETRY_TYPES = ["BoxGeometry", "CylinderGeometry", "ConeGeometry", "SphereGeometry", "PlaneGeometry", "CircleGeometry", "RingGeometry", "LatheGeometry", "TorusGeometry", "ExtrudeGeometry"];
5222
+ function linePoints(path) {
5223
+ if (path.autoClose || path.curves.length === 0) return null;
5224
+ const points = [];
5225
+ for (const [index, curve] of path.curves.entries()) {
5226
+ if (!curve.isLineCurve || !curve.v1 || !curve.v2) return null;
5227
+ if (index === 0) points.push([curve.v1.x, curve.v1.y]);
5228
+ else {
5229
+ const last = points[points.length - 1];
5230
+ if (last[0] !== curve.v1.x || last[1] !== curve.v1.y) return null;
5231
+ }
5232
+ points.push([curve.v2.x, curve.v2.y]);
5233
+ }
5234
+ return points;
5235
+ }
5236
+ function extrudeOf(shapes, options = {}) {
5237
+ if (Array.isArray(shapes) || !shapes || options.extrudePath !== void 0 || options.UVGenerator !== void 0) return null;
5238
+ const shape = shapes;
5239
+ const outer = linePoints(shape);
5240
+ if (!outer) return null;
5241
+ const holes = [];
5242
+ for (const hole of shape.holes ?? []) {
5243
+ const points = linePoints(hole);
5244
+ if (!points) return null;
5245
+ holes.push(points);
5246
+ }
5247
+ const outline = holes.length ? { outer, holes } : { outer };
5248
+ const bevel = options.bevelEnabled === false ? false : {
5249
+ ...options.bevelThickness !== void 0 ? { thickness: options.bevelThickness } : {},
5250
+ ...options.bevelSize !== void 0 ? { size: options.bevelSize } : {},
5251
+ ...options.bevelOffset !== void 0 ? { offset: options.bevelOffset } : {},
5252
+ ...options.bevelSegments !== void 0 ? { segments: options.bevelSegments } : {}
5253
+ };
5254
+ return extrude(outline, options.depth, options.steps, bevel);
5255
+ }
5256
+ var namespaces = /* @__PURE__ */ new WeakMap();
5257
+ var shims = /* @__PURE__ */ new WeakSet();
5258
+ function shapeGeometries(THREE, options = {}) {
5259
+ if (shims.has(THREE)) return THREE;
5260
+ const cache = options.cache !== false;
5261
+ const key = cache ? "cache" : "nocache";
5262
+ let byKey = namespaces.get(THREE);
5263
+ if (!byKey) {
5264
+ byKey = /* @__PURE__ */ new Map();
5265
+ namespaces.set(THREE, byKey);
5266
+ }
5267
+ const existing = byKey.get(key);
5268
+ if (existing) return existing;
5269
+ const made = (p2) => toGeometry(THREE, p2);
5270
+ const viaCache = (node, direct) => cache ? buildPrimitive(node) : direct();
5271
+ const defined = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
5272
+ const constructors = {
5273
+ BoxGeometry: (width, height, depth, ws = 1, hs = 1, ds = 1) => made(viaCache({ kind: "box", size: [width ?? 1, height ?? 1, depth ?? 1], segments: [ws, hs, ds] }, () => box(width, height, depth, ws, hs, ds))),
5274
+ CylinderGeometry: (radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) => made(viaCache({ kind: "cylinder", ...defined({ radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }) }, () => cylinder(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))),
5275
+ ConeGeometry: (radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) => made(viaCache({ kind: "cone", ...defined({ radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }) }, () => cone(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength))),
5276
+ SphereGeometry: (radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength) => made(viaCache({ kind: "sphere", ...defined({ radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength }) }, () => sphere(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength))),
5277
+ PlaneGeometry: (width, height, widthSegments, heightSegments) => made(viaCache({ kind: "plane", ...defined({ width, height, widthSegments, heightSegments }) }, () => plane(width, height, widthSegments, heightSegments))),
5278
+ CircleGeometry: (radius, segments, thetaStart, thetaLength) => made(viaCache({ kind: "circle", ...defined({ radius, segments, thetaStart, thetaLength }) }, () => circle(radius, segments, thetaStart, thetaLength))),
5279
+ RingGeometry: (innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength) => made(viaCache({ kind: "ring", ...defined({ innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength }) }, () => ring(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength))),
5280
+ LatheGeometry: (points, segments, phiStart, phiLength) => {
5281
+ if (!points) return new THREE.LatheGeometry(void 0, segments, phiStart, phiLength);
5282
+ const profile = points.map((p2) => [p2.x, p2.y]);
5283
+ return made(viaCache({ kind: "lathe", points: profile, ...defined({ segments, phiStart, phiLength }) }, () => lathe(profile, segments, phiStart, phiLength)));
5284
+ },
5285
+ TorusGeometry: (radius, tube, radialSegments, tubularSegments, arc) => made(viaCache({ kind: "torus", ...defined({ radius, tube, radialSegments, tubularSegments, arc }) }, () => torus(radius, tube, radialSegments, tubularSegments, arc))),
5286
+ ExtrudeGeometry: (shapes, extrudeOptions) => {
5287
+ const buffers = shapes === void 0 ? null : extrudeOf(shapes, extrudeOptions);
5288
+ if (!buffers) return new THREE.ExtrudeGeometry(shapes, extrudeOptions);
5289
+ const geometry = toGeometry(THREE, buffers);
5290
+ geometry.parameters = { shapes, options: extrudeOptions ?? {} };
5291
+ return geometry;
5292
+ }
5293
+ };
5294
+ const namespace = { ...THREE };
5295
+ for (const type of SHAPE_GEOMETRY_TYPES) {
5296
+ const make2 = constructors[type];
5297
+ const Constructor = function(...args) {
5298
+ return make2(...args);
5299
+ };
5300
+ Constructor.prototype = THREE[type].prototype;
5301
+ Object.defineProperty(Constructor, "name", { value: type });
5302
+ namespace[type] = Constructor;
5303
+ }
5304
+ const result = namespace;
5305
+ byKey.set(key, result);
5306
+ shims.add(result);
5307
+ return result;
5308
+ }
5309
+
3420
5310
  // ../game-audio/dist/index.js
3421
5311
  var DISTANCE_CURVES = {
3422
5312
  /** The game's `sfx`: `vol / (1 + d² × 0.004)`, cutoff `/ (1 + d × 0.01)`, silent below 0.01 (jogo L62091–62092, L62101). */
@@ -3728,13 +5618,13 @@ var GameCrowdThree = (() => {
3728
5618
  return source;
3729
5619
  };
3730
5620
  var MERGED_ATTRIBUTES = [["position", 3], ["normal", 3], ["bone", 1], ["vcol", 4], ["pivot", 3], ["ppivot", 3]];
3731
- var mergeBody = (list, three) => {
3732
- const total = list.reduce((sum, geometry) => sum + geometry.attributes.position.count, 0);
5621
+ var mergeBody = (list2, three) => {
5622
+ const total = list2.reduce((sum, geometry) => sum + geometry.attributes.position.count, 0);
3733
5623
  const merged = new three.BufferGeometry();
3734
5624
  for (const [name, size] of MERGED_ATTRIBUTES) {
3735
5625
  const array = new Float32Array(total * size);
3736
5626
  let offset = 0;
3737
- for (const geometry of list) {
5627
+ for (const geometry of list2) {
3738
5628
  const part = geometry.attributes[name].array;
3739
5629
  array.set(part, offset);
3740
5630
  offset += part.length;
@@ -3744,7 +5634,8 @@ var GameCrowdThree = (() => {
3744
5634
  merged.computeBoundingSphere();
3745
5635
  return merged;
3746
5636
  };
3747
- var buildInstancedBody = (three, { segments, body = TEAM_GAME }) => {
5637
+ var buildInstancedBody = (host, { segments, body = TEAM_GAME }) => {
5638
+ const three = shapeGeometries(host);
3748
5639
  const joints = jointsOf(body);
3749
5640
  const parts = [];
3750
5641
  const half = Math.max(4, segments >> 1);
@@ -3868,15 +5759,15 @@ var GameCrowdThree = (() => {
3868
5759
  copy.setAttribute(name, attribute);
3869
5760
  attributes[name] = attribute;
3870
5761
  }
3871
- const mesh = new three.InstancedMesh(copy, createBodyMaterial(three, { time }), max);
3872
- mesh.customDepthMaterial = createBodyMaterial(three, { depth: true, time });
3873
- mesh.frustumCulled = false;
3874
- mesh.castShadow = castShadow;
3875
- mesh.receiveShadow = true;
3876
- mesh.count = 0;
5762
+ const mesh2 = new three.InstancedMesh(copy, createBodyMaterial(three, { time }), max);
5763
+ mesh2.customDepthMaterial = createBodyMaterial(three, { depth: true, time });
5764
+ mesh2.frustumCulled = false;
5765
+ mesh2.castShadow = castShadow;
5766
+ mesh2.receiveShadow = true;
5767
+ mesh2.count = 0;
3877
5768
  let count = 0;
3878
5769
  return {
3879
- mesh,
5770
+ mesh: mesh2,
3880
5771
  max,
3881
5772
  get count() {
3882
5773
  return count;
@@ -3884,7 +5775,7 @@ var GameCrowdThree = (() => {
3884
5775
  begin() {
3885
5776
  count = 0;
3886
5777
  },
3887
- push({ a, b, c, color, eye, y = 0 }) {
5778
+ push({ a, b, c, color: color2, eye, y = 0 }) {
3888
5779
  if (count >= max) return;
3889
5780
  const index = count++;
3890
5781
  const fourOffset = index * 4;
@@ -3892,11 +5783,11 @@ var GameCrowdThree = (() => {
3892
5783
  attributes.iA.array.set(a, fourOffset);
3893
5784
  attributes.iB.array.set([b[0], b[1], b[2], b[3] + POSE_SLOTS * Math.round((Math.min(MAX_HEIGHT, Math.max(MIN_HEIGHT, y)) - MIN_HEIGHT) * HEIGHT_STEPS)], fourOffset);
3894
5785
  attributes.iC.array.set(c, fourOffset);
3895
- attributes.iCol.array.set([color.r, color.g, color.b], threeOffset);
5786
+ attributes.iCol.array.set([color2.r, color2.g, color2.b], threeOffset);
3896
5787
  attributes.iEye.array.set(eye ? [eye.r, eye.g, eye.b] : [0, 0, 0], threeOffset);
3897
5788
  },
3898
5789
  end() {
3899
- mesh.count = count;
5790
+ mesh2.count = count;
3900
5791
  for (const attribute of Object.values(attributes)) {
3901
5792
  attribute.clearUpdateRanges();
3902
5793
  attribute.addUpdateRange(0, count * attribute.itemSize);
@@ -3915,7 +5806,8 @@ var GameCrowdThree = (() => {
3915
5806
  var FAR_LOD = 0.6;
3916
5807
  var EYE_SCALE = 2.2;
3917
5808
  var EYE_DEPTH_SCALE = 1.4;
3918
- var bakeBody = (three, builders, spec, lod) => {
5809
+ var bakeBody = (host, builders, spec, lod) => {
5810
+ const three = shapeGeometries(host);
3919
5811
  const root = spec.retrato && builders.buildPortrait ? builders.buildPortrait(spec.retrato, lod) : builders.buildBest({ ...spec, pose: { ...BAKE_NEUTRAL_POSE, ...spec.pose ?? {} } }, lod);
3920
5812
  const rig = root.userData.rig;
3921
5813
  const P = rig.P;
@@ -3931,7 +5823,7 @@ var GameCrowdThree = (() => {
3931
5823
  leg.kn.rotation.set(0, 0, 0);
3932
5824
  }
3933
5825
  root.updateMatrixWorld(true);
3934
- const worldPosition2 = (object) => object.getWorldPosition(new three.Vector3()).toArray();
5826
+ const worldPosition2 = (object2) => object2.getWorldPosition(new three.Vector3()).toArray();
3935
5827
  const bones = /* @__PURE__ */ new Map();
3936
5828
  bones.set(rig.headG, [1, worldPosition2(rig.headG), [0, 0, 0]]);
3937
5829
  for (const arm of rig.arms) {
@@ -3947,13 +5839,13 @@ var GameCrowdThree = (() => {
3947
5839
  const trunk = [0, [0, 0.9 * P.s, 0], [0, 0, 0]];
3948
5840
  const parts = [];
3949
5841
  const topMaterial = spec.retrato ? null : builders.topMaterial();
3950
- root.traverse((object) => {
3951
- const mesh = object;
3952
- const material = mesh.material;
3953
- if (!mesh.isMesh || !mesh.geometry || material.transparent) return;
3954
- for (let ancestor = object; ancestor; ancestor = ancestor.parent) if (!ancestor.visible) return;
5842
+ root.traverse((object2) => {
5843
+ const mesh2 = object2;
5844
+ const material = mesh2.material;
5845
+ if (!mesh2.isMesh || !mesh2.geometry || material.transparent) return;
5846
+ for (let ancestor = object2; ancestor; ancestor = ancestor.parent) if (!ancestor.visible) return;
3955
5847
  let tag = trunk;
3956
- for (let ancestor = object.parent; ancestor; ancestor = ancestor.parent) {
5848
+ for (let ancestor = object2.parent; ancestor; ancestor = ancestor.parent) {
3957
5849
  const found = bones.get(ancestor);
3958
5850
  if (found) {
3959
5851
  tag = found;
@@ -3961,21 +5853,21 @@ var GameCrowdThree = (() => {
3961
5853
  }
3962
5854
  }
3963
5855
  let [bone, pivot, parentPivot] = tag;
3964
- if (object.userData.bone === 11) {
5856
+ if (object2.userData.bone === 11) {
3965
5857
  bone = 11;
3966
5858
  pivot = bones.get(rig.headG)[1];
3967
5859
  parentPivot = [0, 0, 0];
3968
5860
  }
3969
- const isEye2 = !!object.userData.eye;
3970
- const color = material.color;
5861
+ const isEye2 = !!object2.userData.eye;
5862
+ const color2 = material.color;
3971
5863
  const materialId = isEye2 ? 3 : material === topMaterial ? 1 : 6;
3972
5864
  if (isEye2 && bone === 1) bone = 6;
3973
- const geometry = mesh.geometry.clone();
3974
- geometry.applyMatrix4(mesh.matrixWorld);
5865
+ const geometry = mesh2.geometry.clone();
5866
+ geometry.applyMatrix4(mesh2.matrixWorld);
3975
5867
  const isBlood = material.polygonOffset && material.isMeshStandardMaterial;
3976
5868
  if (isBlood) liftAlongNormals(geometry, lod < FAR_LOD ? BLOOD_LIFT_FAR : BLOOD_LIFT_NEAR);
3977
5869
  if (isEye2) enlargeEye(three, geometry, lod < FAR_LOD ? 1 : 0.68);
3978
- const colors = isBlood ? [Math.max(color.r * 1.7, 0.3), Math.min(color.g * 1.7, 0.04), Math.min(color.b * 1.7, 0.04), materialId] : [color.r, color.g, color.b, materialId];
5870
+ const colors = isBlood ? [Math.max(color2.r * 1.7, 0.3), Math.min(color2.g * 1.7, 0.04), Math.min(color2.b * 1.7, 0.04), materialId] : [color2.r, color2.g, color2.b, materialId];
3979
5871
  parts.push({ g: geometry, bone, pv: pivot, pp: parentPivot, col: colors });
3980
5872
  });
3981
5873
  return { geo: mergeBaked(three, parts), s: P.s, bulk: P.bulk, verts: parts.reduce((sum, part) => sum + part.g.attributes.position.count, 0) };
@@ -4001,7 +5893,7 @@ var GameCrowdThree = (() => {
4001
5893
  }
4002
5894
  const position = new Float32Array(vertexTotal * 3);
4003
5895
  const normal = new Float32Array(vertexTotal * 3);
4004
- const color = new Float32Array(vertexTotal * 4);
5896
+ const color2 = new Float32Array(vertexTotal * 4);
4005
5897
  const bone = new Float32Array(vertexTotal);
4006
5898
  const pivot = new Float32Array(vertexTotal * 3);
4007
5899
  const parentPivot = new Float32Array(vertexTotal * 3);
@@ -4013,7 +5905,7 @@ var GameCrowdThree = (() => {
4013
5905
  position.set(part.g.attributes.position.array, vertexOffset * 3);
4014
5906
  normal.set(part.g.attributes.normal.array, vertexOffset * 3);
4015
5907
  for (let vertex = 0; vertex < count; vertex++) {
4016
- color.set(part.col, (vertexOffset + vertex) * 4);
5908
+ color2.set(part.col, (vertexOffset + vertex) * 4);
4017
5909
  bone[vertexOffset + vertex] = part.bone;
4018
5910
  pivot.set(part.pv, (vertexOffset + vertex) * 3);
4019
5911
  parentPivot.set(part.pp, (vertexOffset + vertex) * 3);
@@ -4028,7 +5920,7 @@ var GameCrowdThree = (() => {
4028
5920
  const out = new three.BufferGeometry();
4029
5921
  out.setAttribute("position", new three.BufferAttribute(position, 3));
4030
5922
  out.setAttribute("normal", new three.BufferAttribute(normal, 3));
4031
- out.setAttribute("vcol", new three.BufferAttribute(color, 4));
5923
+ out.setAttribute("vcol", new three.BufferAttribute(color2, 4));
4032
5924
  out.setAttribute("bone", new three.BufferAttribute(bone, 1));
4033
5925
  out.setAttribute("pivot", new three.BufferAttribute(pivot, 3));
4034
5926
  out.setAttribute("ppivot", new three.BufferAttribute(parentPivot, 3));
@@ -4061,8 +5953,8 @@ var GameCrowdThree = (() => {
4061
5953
  add(U, Bx(0.1, 0.12, 0.09), m, -0.17, 0.95, -0.15);
4062
5954
  return;
4063
5955
  },
4064
- belt: ({ U, m, ring }) => {
4065
- ring(U, 0.212, 0.07, m, 0.95, 1.12, 0.72);
5956
+ belt: ({ U, m, ring: ring2 }) => {
5957
+ ring2(U, 0.212, 0.07, m, 0.95, 1.12, 0.72);
4066
5958
  return;
4067
5959
  },
4068
5960
  holster: ({ Bx, add, cmat, legs }) => {
@@ -4074,9 +5966,9 @@ var GameCrowdThree = (() => {
4074
5966
  add(U, Bx(0.012, 0.1, 0.012), cmat(1710618), 0.17, 1.52, 0.18);
4075
5967
  return;
4076
5968
  },
4077
- stripes: ({ THREE, U, add, arms, m, ring }) => {
4078
- ring(U, 0.205, 0.05, m, 1.03, 1.13, 0.68);
4079
- ring(U, 0.268, 0.05, m, 1.42, 1.13, 0.67);
5969
+ stripes: ({ THREE, U, add, arms, m, ring: ring2 }) => {
5970
+ ring2(U, 0.205, 0.05, m, 1.03, 1.13, 0.68);
5971
+ ring2(U, 0.268, 0.05, m, 1.42, 1.13, 0.67);
4080
5972
  arms.forEach((a) => {
4081
5973
  const r = add(a.el, new THREE.CylinderGeometry(0.058, 0.054, 0.05, 18), m, 0, -0.17, 0);
4082
5974
  });
@@ -4186,17 +6078,17 @@ var GameCrowdThree = (() => {
4186
6078
  add(arms[1].g, new THREE.CylinderGeometry(0.08, 0.078, 0.08, 18), m, 0, -0.12, 0);
4187
6079
  return;
4188
6080
  },
4189
- tiedsleeves: ({ Bx, U, add, legs, m, ring }) => {
4190
- ring(U, 0.215, 0.1, m, 0.95, 1.12, 0.74);
6081
+ tiedsleeves: ({ Bx, U, add, legs, m, ring: ring2 }) => {
6082
+ ring2(U, 0.215, 0.1, m, 0.95, 1.12, 0.74);
4191
6083
  legs.forEach((l) => add(l.g, Bx(0.1, 0.26, 0.05), m, l.s * 0.02, -0.1, 0.105));
4192
6084
  return;
4193
6085
  },
4194
- labcoat: ({ Bx, THREE, U, add, arms, cmat, fem, legs, m, ring, torsoGeo }) => {
6086
+ labcoat: ({ Bx, THREE, U, add, arms, cmat, fem, legs, m, ring: ring2, torsoGeo }) => {
4195
6087
  {
4196
6088
  const g = torsoGeo(fem);
4197
6089
  g.scale(1.06, 1, 1.12);
4198
6090
  add(U, g, m, 0, 0, 0);
4199
- ring(U, 0.22, 0.14, m, 0.9, 1.12, 0.76);
6091
+ ring2(U, 0.22, 0.14, m, 0.9, 1.12, 0.76);
4200
6092
  legs.forEach((l) => add(l.g, new THREE.CylinderGeometry(0.145, 0.165, 0.46, 20, 1, true).translate(0, -0.21, 0), m, 0, 0, 0));
4201
6093
  add(U, Bx(0.025, 0.62, 0.012), cmat(10132114), 0, 1.2, 0.19);
4202
6094
  arms.forEach((a) => {
@@ -4286,8 +6178,8 @@ var GameCrowdThree = (() => {
4286
6178
  add(U, Bx(0.05, 0.75, 0.02), cmat(4864546), 0, 1.22, 0.195, 0, 0, -0.75);
4287
6179
  return;
4288
6180
  },
4289
- scarf: ({ PI, THREE, U, add, m, ring }) => {
4290
- ring(U, 0.1, 0.08, m, 1.57, 1.3, 1.2);
6181
+ scarf: ({ PI, THREE, U, add, m, ring: ring2 }) => {
6182
+ ring2(U, 0.1, 0.08, m, 1.57, 1.3, 1.2);
4291
6183
  add(U, new THREE.ConeGeometry(0.08, 0.14, 3), m, 0, 1.47, 0.15, PI, 0, 0);
4292
6184
  return;
4293
6185
  },
@@ -4330,12 +6222,12 @@ var GameCrowdThree = (() => {
4330
6222
  return;
4331
6223
  }
4332
6224
  },
4333
- refl: ({ Bx, THREE, U, add, cmat, m, ring }) => {
6225
+ refl: ({ Bx, THREE, U, add, cmat, m, ring: ring2 }) => {
4334
6226
  {
4335
6227
  const v = add(U, new THREE.CylinderGeometry(0.287, 0.252, 0.46, 20), m, 0, 1.3, 0);
4336
6228
  v.scale.set(1.13, 1, 0.72);
4337
- ring(U, 0.29, 0.035, cmat(13159632, { metalness: 0.3, roughness: 0.4 }), 1.2, 1.13, 0.73);
4338
- ring(U, 0.3, 0.035, cmat(13159632, { metalness: 0.3, roughness: 0.4 }), 1.37, 1.13, 0.73);
6229
+ ring2(U, 0.29, 0.035, cmat(13159632, { metalness: 0.3, roughness: 0.4 }), 1.2, 1.13, 0.73);
6230
+ ring2(U, 0.3, 0.035, cmat(13159632, { metalness: 0.3, roughness: 0.4 }), 1.37, 1.13, 0.73);
4339
6231
  add(U, Bx(0.17, 0.055, 0.02), cmat(1714794), 0, 1.47, 0.205);
4340
6232
  return;
4341
6233
  }
@@ -4583,6 +6475,84 @@ var GameCrowdThree = (() => {
4583
6475
  var DATA = voices_default;
4584
6476
  var UNDEAD_VOICES = DATA.types;
4585
6477
  var UNDEAD_VOICE_SOURCES = DATA.sources;
6478
+ var player_avatar_default = {
6479
+ source: {
6480
+ file: "site/pages/jogo/zombiada-modo-livre.html",
6481
+ variable: "PB specs[0] ('voc\xEA') and PLAYER_COR",
6482
+ note: "The team game's player body: the Besti\xE1rio/Elenco human body. Overridable by `createPlayerAvatar(THREE, { spec, shirtColor })`."
6483
+ },
6484
+ spec: {
6485
+ type: "Lento",
6486
+ human: true,
6487
+ decay: 0,
6488
+ seed: 4242,
6489
+ skin: "b07a52",
6490
+ fem: false,
6491
+ life: 1,
6492
+ hs: "short",
6493
+ hair: "2a1e16",
6494
+ pose: {
6495
+ armL: 0,
6496
+ armR: 0,
6497
+ elbL: -0.12,
6498
+ elbR: -0.12,
6499
+ armOut: 0.11,
6500
+ lean: 0.04,
6501
+ headX: 0,
6502
+ headZ: 0
6503
+ }
6504
+ },
6505
+ shirtColor: "3d5a73"
6506
+ };
6507
+ var TWO_PI2 = Math.PI * 2;
6508
+ var first_person_arms_default = {
6509
+ source: {
6510
+ note: "Authored in the kit: no team delivered first-person arms. The rig is in metres in the camera's space (x right, y up, the view looks down -z); rest poses use the hand frame of HandPose in game-contracts, Euler [roll, yaw, pitch] in the order YZX (yaw pi/2 points the fingers forward)."
6511
+ },
6512
+ rig: {
6513
+ shoulder: [0.16, -0.36, 0.18],
6514
+ upper: 0.32,
6515
+ fore: 0.3,
6516
+ reachShift: 0.35,
6517
+ wrist: 0.07,
6518
+ elbowPole: [0.45, -1, 0.2],
6519
+ shoulderLeft: [-0.07, -0.46, 0.18],
6520
+ elbowPoleLeft: [-0.1, -1, 0.2],
6521
+ radius: { shoulder: 0.04, elbow: 0.034, wrist: 0.028, cuff: 0.031 },
6522
+ hip: [0.12, -0.82, 0.04],
6523
+ thigh: 0.46,
6524
+ shin: 0.46,
6525
+ kneePole: [0.1, 0.5, -1],
6526
+ foot: { p: [0.13, -0.85, -0.05], r: [0, 1.5708, 0] }
6527
+ },
6528
+ stances: {
6529
+ relaxed: {
6530
+ R: { p: [0.2, -0.22, -0.36], r: [0.05, 1.57, -0.05], grip: 0.2 },
6531
+ L: "mirror"
6532
+ },
6533
+ fists: {
6534
+ R: { p: [0.15, -0.12, -0.4], r: [0, 1.5, 0.15], grip: 1 },
6535
+ L: "mirror"
6536
+ },
6537
+ hold: { follow: true, fallback: "relaxed" }
6538
+ },
6539
+ bob: { frequency: 2.3, x: 6e-3, y: 8e-3, run: 1.5, fullSpeed: 4, crouch: 0.02 }
6540
+ };
6541
+ var FIRST_PERSON_STANCES = first_person_arms_default.stances;
6542
+ var FIRST_PERSON_RIG = first_person_arms_default.rig;
6543
+ var FIRST_PERSON_BOB = first_person_arms_default.bob;
6544
+ var hexOf2 = (value) => typeof value === "string" ? Number.parseInt(value, 16) : value;
6545
+ var scaleHex = (hex2, factor) => {
6546
+ const channel = (shift) => Math.round((hex2 >> shift & 255) * factor);
6547
+ return channel(16) << 16 | channel(8) << 8 | channel(0);
6548
+ };
6549
+ var FIRST_PERSON_COLORS = {
6550
+ skin: hexOf2(player_avatar_default.spec.skin),
6551
+ sleeve: hexOf2(player_avatar_default.shirtColor),
6552
+ cuff: scaleHex(hexOf2(player_avatar_default.shirtColor), 0.72),
6553
+ trouser: 2962496,
6554
+ shoe: 1841690
6555
+ };
4586
6556
 
4587
6557
  // src/renderer.ts
4588
6558
  var now = () => typeof performance === "undefined" ? Date.now() : performance.now();
@@ -4603,9 +6573,9 @@ var GameCrowdThree = (() => {
4603
6573
  const shirt = new three.Color();
4604
6574
  const eyeColors = /* @__PURE__ */ new Map();
4605
6575
  const eyeOf = (hex) => {
4606
- let color = eyeColors.get(hex);
4607
- if (!color) eyeColors.set(hex, color = new three.Color(hex));
4608
- return color;
6576
+ let color2 = eyeColors.get(hex);
6577
+ if (!color2) eyeColors.set(hex, color2 = new three.Color(hex));
6578
+ return color2;
4609
6579
  };
4610
6580
  const push = (batch, instance) => {
4611
6581
  if (!batch) return;
@@ -4613,7 +6583,7 @@ var GameCrowdThree = (() => {
4613
6583
  batch.push({ a: instance.a, b: instance.b, c: instance.c, color: shirt, ...instance.eye !== null ? { eye: eyeOf(instance.eye) } : {}, y: instance.y });
4614
6584
  };
4615
6585
  const typeOfVariant = [];
4616
- crowd.variantsOf.forEach((list, c) => list.forEach((g) => typeOfVariant[g] = c));
6586
+ crowd.variantsOf.forEach((list2, c) => list2.forEach((g) => typeOfVariant[g] = c));
4617
6587
  const baked = /* @__PURE__ */ new Set();
4618
6588
  const ensurePlain = () => {
4619
6589
  if (!plain) {
@@ -4667,8 +6637,8 @@ var GameCrowdThree = (() => {
4667
6637
  instances.agents(crowd.store, variants, frame, (v, l, instance) => push(batches[v]?.[l], instance));
4668
6638
  if (options.drawCorpses?.() !== false) instances.corpses(crowd.corpses.entries, variants, frame, crowd.numbers.corpseSeconds, (v, l, instance) => push(batches[v]?.[l], instance), (instance) => push(ensurePlain(), instance));
4669
6639
  for (let l = 0; l < 3; l++) lodCounts[l] = batches.reduce((sum, set) => sum + (set?.[l]?.count ?? 0), 0);
4670
- const list = options.civilians?.list();
4671
- if (list) instances.civilians(list, options.civilians?.color ?? ((n) => n.spec.color ?? 8421504), (n, instance) => push(personBatch(n), instance));
6640
+ const list2 = options.civilians?.list();
6641
+ if (list2) instances.civilians(list2, options.civilians?.color ?? ((n) => n.spec.color ?? 8421504), (n, instance) => push(personBatch(n), instance));
4672
6642
  for (const batch of all()) batch.end();
4673
6643
  },
4674
6644
  get lodCounts() {
@@ -5133,7 +7103,7 @@ var GameCrowdThree = (() => {
5133
7103
  sound("flesh", numbers.grabVolume);
5134
7104
  emit("grabbed", { by, noJaw, drown });
5135
7105
  };
5136
- const front = (range, cosMin, yaw, crowd = world.crowd) => {
7106
+ const front = (range2, cosMin, yaw, crowd = world.crowd) => {
5137
7107
  const out = [];
5138
7108
  if (!crowd) return out;
5139
7109
  const fx = -Math.sin(yaw);
@@ -5144,7 +7114,7 @@ var GameCrowdThree = (() => {
5144
7114
  const ex = crowd.x(i) - P.x;
5145
7115
  const ez = crowd.z(i) - P.z;
5146
7116
  const d = Math.hypot(ex, ez);
5147
- if (d < range && (ex * fx + ez * fz) / (d || 1) > cosMin) out.push([d, i]);
7117
+ if (d < range2 && (ex * fx + ez * fz) / (d || 1) > cosMin) out.push([d, i]);
5148
7118
  }
5149
7119
  return out.sort((a, b) => a[0] - b[0]);
5150
7120
  };
@@ -5846,7 +7816,7 @@ var GameCrowdThree = (() => {
5846
7816
  { kind: "choice", id: "type", name: text.controls.type, hint: text.hints.type, options: typeOptions(), default: "mix" },
5847
7817
  { kind: "boolean", id: "night", name: text.controls.night, hint: text.hints.night, default: false },
5848
7818
  { kind: "number", id: "seed", name: text.controls.seed, min: 1, max: 9999, step: 1, default: settings.seed },
5849
- { kind: "action", id: "spawn", name: text.controls.spawn },
7819
+ { kind: "action", id: "spawn", name: text.controls.spawn, slow: true },
5850
7820
  { kind: "action", id: "noise", name: text.controls.noise, hint: text.hints.noise },
5851
7821
  { kind: "action", id: "hit", name: text.controls.hit, hint: text.hints.hit },
5852
7822
  { kind: "action", id: "kill_all", name: text.controls.kill_all },
@@ -5855,7 +7825,7 @@ var GameCrowdThree = (() => {
5855
7825
  ...options.animals ? [{ kind: "action", id: "herd", name: text.controls.herd, hint: text.hints.herd }] : [],
5856
7826
  ...options.infection ? [{ kind: "action", id: "materialize", name: text.controls.materialize, hint: text.hints.materialize }] : [],
5857
7827
  { kind: "action", id: "push", name: text.controls.push, hint: text.hints.push },
5858
- { kind: "action", id: "reset", name: text.controls.reset }
7828
+ { kind: "action", id: "reset", name: text.controls.reset, slow: true }
5859
7829
  ];
5860
7830
  const benchLayers = () => [
5861
7831
  { id: "corpses", name: text.layers.corpses },