@adatechnology/game-characters-three 0.6.0 → 0.7.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.
@@ -1687,6 +1687,90 @@ var GameCharactersThree = (() => {
1687
1687
  shims.add(result);
1688
1688
  return result;
1689
1689
  }
1690
+ var isTexture = (v) => !!v && typeof v === "object" && v.isTexture === true;
1691
+ function texturesOf(material, out) {
1692
+ for (const value of Object.values(material)) if (isTexture(value)) out.add(value);
1693
+ const uniforms = material.uniforms;
1694
+ if (uniforms) {
1695
+ for (const u of Object.values(uniforms)) if (isTexture(u?.value)) out.add(u.value);
1696
+ }
1697
+ }
1698
+ function collect(roots) {
1699
+ const geometries = /* @__PURE__ */ new Set();
1700
+ const materials = /* @__PURE__ */ new Set();
1701
+ const textures = /* @__PURE__ */ new Set();
1702
+ const skeletons = /* @__PURE__ */ new Set();
1703
+ for (const root of roots) {
1704
+ root.traverse((object2) => {
1705
+ const o = object2;
1706
+ if (o.geometry && typeof o.geometry.dispose === "function") geometries.add(o.geometry);
1707
+ if (o.skeleton && typeof o.skeleton.dispose === "function") skeletons.add(o.skeleton);
1708
+ const list2 = Array.isArray(o.material) ? o.material : o.material ? [o.material] : [];
1709
+ for (const m of list2) {
1710
+ if (!m || typeof m.dispose !== "function") continue;
1711
+ materials.add(m);
1712
+ texturesOf(m, textures);
1713
+ }
1714
+ });
1715
+ }
1716
+ return { geometries, materials, textures, skeletons };
1717
+ }
1718
+ var marked = /* @__PURE__ */ new WeakSet();
1719
+ var shared = (r) => r.userData?.shared === true || marked.has(r);
1720
+ function releaseObject3D(roots, options = {}) {
1721
+ const list2 = Array.isArray(roots) ? roots : [roots];
1722
+ const report2 = { geometries: 0, materials: 0, textures: 0 };
1723
+ if (list2.length === 0) return report2;
1724
+ const found = collect(list2);
1725
+ const keepRoots = options.keep === void 0 ? [] : Array.isArray(options.keep) ? options.keep : [options.keep];
1726
+ const releasing = new Set(list2);
1727
+ for (const keep of keepRoots) {
1728
+ const walk = (o) => {
1729
+ if (releasing.has(o)) return;
1730
+ const owner = o;
1731
+ if (owner.geometry) found.geometries.delete(owner.geometry);
1732
+ if (owner.skeleton) found.skeletons.delete(owner.skeleton);
1733
+ const mats = Array.isArray(owner.material) ? owner.material : owner.material ? [owner.material] : [];
1734
+ for (const m of mats) {
1735
+ if (!m) continue;
1736
+ found.materials.delete(m);
1737
+ const t = /* @__PURE__ */ new Set();
1738
+ texturesOf(m, t);
1739
+ for (const x of t) found.textures.delete(x);
1740
+ }
1741
+ for (const c of o.children) walk(c);
1742
+ };
1743
+ walk(keep);
1744
+ }
1745
+ for (const g of found.geometries) {
1746
+ if (shared(g)) continue;
1747
+ g.dispose();
1748
+ report2.geometries++;
1749
+ }
1750
+ for (const m of found.materials) {
1751
+ if (shared(m)) continue;
1752
+ m.dispose();
1753
+ report2.materials++;
1754
+ }
1755
+ for (const t of found.textures) {
1756
+ if (shared(t)) continue;
1757
+ t.dispose();
1758
+ report2.textures++;
1759
+ }
1760
+ for (const s of found.skeletons) s.dispose();
1761
+ return report2;
1762
+ }
1763
+ function discardObject3D(objects, options = {}) {
1764
+ const list2 = Array.isArray(objects) ? objects : [objects];
1765
+ const keep = options.keep === void 0 ? [] : Array.isArray(options.keep) ? [...options.keep] : [options.keep];
1766
+ for (const object2 of list2) {
1767
+ let top = object2;
1768
+ while (top.parent) top = top.parent;
1769
+ object2.removeFromParent();
1770
+ if (top !== object2 && !keep.includes(top)) keep.push(top);
1771
+ }
1772
+ return releaseObject3D(list2, { keep });
1773
+ }
1690
1774
 
1691
1775
  // ../game-contracts/dist/index.js
1692
1776
  var DEFAULT_BLAST_SHOVE = { coupling: 0.02, maxSpeed: 20, lift: 0.3, minSpeed: 0.3, falloffPower: 2 };
@@ -5221,7 +5305,7 @@ var GameCharactersThree = (() => {
5221
5305
  });
5222
5306
  }
5223
5307
  const neckLen = 0.14 + Math.max(0, P.neck);
5224
- if (!cut.head) add(U, CYL(0.058, 0.068, neckLen, SEG), skinM, 0, 1.63 + Math.max(0, P.neck) / 2, 0);
5308
+ const neck = cut.head ? void 0 : add(U, CYL(0.058, 0.068, neckLen, SEG), skinM, 0, 1.63 + Math.max(0, P.neck) / 2, 0);
5225
5309
  const headG = new THREE.Group();
5226
5310
  headG.position.set(0, 1.64 + P.neck, P.headFwd || 0);
5227
5311
  headG.rotation.x = P.headX;
@@ -5428,6 +5512,7 @@ var GameCharactersThree = (() => {
5428
5512
  if (o.userData.flap) flaps.push(o);
5429
5513
  });
5430
5514
  const rig = { flaps, dangles: arms.filter((a) => a.el.userData.dangle), type: spec.type || "Lento", fig, upper, headG, arms, legs, P, ph: spec.phase ?? options.random() * 6, dropBase: fig.position.y, leanBase: P.lean, hxBase: P.headX };
5515
+ if (neck) Object.defineProperty(rig, "neck", { value: neck });
5431
5516
  if (spec.lying) {
5432
5517
  root.rotation.x = -PI / 2;
5433
5518
  root.position.set(0, 0.16 * P.s, 0.9 * P.s);
@@ -5438,8 +5523,8 @@ var GameCharactersThree = (() => {
5438
5523
  root.userData.rig = rig;
5439
5524
  return root;
5440
5525
  }
5441
- const marked = (...args) => markKitOrigin(build(...args), { owner: "game-characters-three", kind: "person" });
5442
- return { build: marked, TYPES, setLOD(k) {
5526
+ const marked2 = (...args) => markKitOrigin(build(...args), { owner: "game-characters-three", kind: "person" });
5527
+ return { build: marked2, TYPES, setLOD(k) {
5443
5528
  LK = k;
5444
5529
  SEG = Math.max(5, Math.round(16 * k));
5445
5530
  }, topM: () => topM_ref };
@@ -6907,7 +6992,10 @@ var GameCharactersThree = (() => {
6907
6992
  const quaternion = new three.Quaternion();
6908
6993
  const euler = new three.Euler();
6909
6994
  const trim = () => {
6910
- while (pieces.length > max) pieces.shift()?.object.removeFromParent();
6995
+ while (pieces.length > max) {
6996
+ const piece = pieces.shift();
6997
+ if (piece) discardObject3D(piece.object);
6998
+ }
6911
6999
  };
6912
7000
  const add = (object2, velocity, spin, tag) => {
6913
7001
  const piece = { object: object2, velocity, spin, rest: false, ...tag ? { tag } : {} };
@@ -6956,7 +7044,7 @@ var GameCharactersThree = (() => {
6956
7044
  }
6957
7045
  },
6958
7046
  clear() {
6959
- pieces.splice(0).forEach((piece) => piece.object.removeFromParent());
7047
+ discardObject3D(pieces.splice(0).map((piece) => piece.object));
6960
7048
  }
6961
7049
  };
6962
7050
  };
@@ -8165,7 +8253,8 @@ var GameCharactersThree = (() => {
8165
8253
  const makeKit = () => options.createKit ? options.createKit({ penetration: settings.penetration, deathRule: settings.deathRule }) : createCharacters({ ...options.packs ? { packs: options.packs } : {}, penetration: settings.penetration, damage: { deathRule: settings.deathRule } });
8166
8254
  let kit = makeKit();
8167
8255
  let undead = options.createUndead ? options.createUndead(kit) : null;
8168
- const random = createRng(options.seed ?? 1);
8256
+ let stream = createRng(options.seed ?? 1);
8257
+ const random = () => stream();
8169
8258
  let seedCounter = 100;
8170
8259
  let host = null;
8171
8260
  let three = null;
@@ -8545,6 +8634,14 @@ var GameCharactersThree = (() => {
8545
8634
  wounds = createWounds(lent.THREE, { random, scene: scene2, groundAt: (x, z) => lent.groundAt(x, z), ...bridge ? { bridge } : {}, ...sound ? { sound } : {} });
8546
8635
  for (const entry of entries.values()) trackEntry(entry);
8547
8636
  const stopChange = lent.bench?.onChange(onChange);
8637
+ const stopReset = lent.onReset?.(() => {
8638
+ stream = createRng(options.seed ?? 1);
8639
+ seedCounter = 100;
8640
+ time = 0;
8641
+ selected = null;
8642
+ lastCrossed = 0;
8643
+ lastEnergy = 1;
8644
+ });
8548
8645
  const stopEvents = lent.on((event) => {
8549
8646
  if (event.type !== "explosion") return;
8550
8647
  for (const entry of entries.values()) {
@@ -8558,6 +8655,8 @@ var GameCharactersThree = (() => {
8558
8655
  time += dt;
8559
8656
  for (const [id, entry] of entries) {
8560
8657
  if (!entry.root.parent) {
8658
+ if (entry.body) wounds?.untrack(entry.body);
8659
+ if (selected === entry) selected = null;
8561
8660
  entries.delete(id);
8562
8661
  continue;
8563
8662
  }
@@ -8569,6 +8668,7 @@ var GameCharactersThree = (() => {
8569
8668
  });
8570
8669
  return () => {
8571
8670
  stopChange?.();
8671
+ stopReset?.();
8572
8672
  stopEvents();
8573
8673
  stopFrame();
8574
8674
  clearOverlays();
@@ -8678,8 +8778,22 @@ var GameCharactersThree = (() => {
8678
8778
  slack: 0.96,
8679
8779
  /** Where the elbow points: down and out from the body, a little back (body space, x outward). */
8680
8780
  elbowPole: [0.55, -1, -0.25],
8781
+ /** The support arm's elbow: under the gun, hardly out of the body (the first-person arms' `elbowPoleLeft`), so the forearm meets the handguard nearer the aim's line. */
8782
+ elbowPoleSupport: [0.1, -1, -0.2],
8681
8783
  /** From the wrist joint to the middle of the palm, metres of the body. */
8682
- palm: 0.042
8784
+ palm: 0.042,
8785
+ /** In a view the elbow keeps at least this interior bend where a hand is out of reach, right then left (the first-person arms' numbers). */
8786
+ viewBend: [1.35, 0.95],
8787
+ /** In a view a hand stays this far before a surface, metres. */
8788
+ contactMargin: 5e-3,
8789
+ /** In a view a hand is never nearer than this to the eye, metres. */
8790
+ contactNearest: 0.12,
8791
+ /** How far in front of the eye a surface is looked for, metres. */
8792
+ contactProbe: 1.4,
8793
+ /** How far a hand reaches forward of its middle at least (the thickness of the palm), and per metre of fingers pointing ahead. */
8794
+ contactPalm: 0.03,
8795
+ /** From the middle of the palm to the fingertips. */
8796
+ contactFingers: 0.085
8683
8797
  };
8684
8798
  var createArmReach = (THREE, rig, hands) => {
8685
8799
  const arms = {
@@ -8700,11 +8814,17 @@ var GameCharactersThree = (() => {
8700
8814
  const v = { shoulder: new THREE.Vector3(), elbow: new THREE.Vector3(), wrist: new THREE.Vector3(), palm: new THREE.Vector3(), target: new THREE.Vector3(), pole: new THREE.Vector3(), a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3() };
8701
8815
  const q = { hand: new THREE.Quaternion(), parent: new THREE.Quaternion(), body: new THREE.Quaternion(), local: new THREE.Quaternion(), swing: new THREE.Quaternion(), twist: new THREE.Quaternion(), rest: new THREE.Quaternion() };
8702
8816
  const basis = new THREE.Matrix4();
8817
+ const camera = { position: new THREE.Vector3(), quaternion: new THREE.Quaternion(), inverse: new THREE.Quaternion(), probe: new THREE.Vector3(), forward: new THREE.Vector3(), fingers: new THREE.Vector3(), hand: new THREE.Quaternion() };
8818
+ let bendLimit = null;
8703
8819
  const yAxis = new THREE.Vector3(0, 1, 0);
8704
8820
  const lengthsOf = (arm) => {
8705
8821
  const scale = arm.g.getWorldScale(v.a).y;
8706
8822
  return { upper: arm.el.position.length() * scale, fore: arm.hand.position.length() * scale, palm: ARM_REACH.palm * scale };
8707
8823
  };
8824
+ const limitOf = (side, upperLength, fore) => {
8825
+ if (!bendLimit) return (upperLength + fore) * ARM_REACH.slack;
8826
+ return Math.sqrt(upperLength * upperLength + fore * fore + 2 * upperLength * fore * Math.cos(bendLimit[side === "R" ? 0 : 1]));
8827
+ };
8708
8828
  const wristOf = (side, pose, palm) => {
8709
8829
  q.hand.set(...pose.quaternion).multiply(handBasis[side]);
8710
8830
  v.palm.set(...pose.position);
@@ -8713,14 +8833,14 @@ var GameCharactersThree = (() => {
8713
8833
  const turnChest = (pose) => {
8714
8834
  const { upper: up, fore, palm } = lengthsOf(arms.L);
8715
8835
  wristOf("L", pose, palm);
8716
- const excess = arms.L.g.getWorldPosition(v.shoulder).distanceTo(v.wrist) - (up + fore) * ARM_REACH.slack;
8836
+ const excess = arms.L.g.getWorldPosition(v.shoulder).distanceTo(v.wrist) - limitOf("L", up, fore);
8717
8837
  if (excess <= 0) return;
8718
8838
  const chestRadius = Math.hypot(arms.L.g.position.x, arms.L.g.position.z) * arms.L.g.getWorldScale(v.a).y;
8719
8839
  upper.rotation.y -= Math.min(ARM_REACH.chestTurn, excess / Math.max(0.05, chestRadius));
8720
8840
  upper.updateMatrixWorld(true);
8721
8841
  };
8722
- const protract = (arm, length) => {
8723
- const excess = arm.g.getWorldPosition(v.shoulder).distanceTo(v.wrist) - length * ARM_REACH.slack;
8842
+ const protract = (arm, limit) => {
8843
+ const excess = arm.g.getWorldPosition(v.shoulder).distanceTo(v.wrist) - limit;
8724
8844
  if (excess <= 0) return;
8725
8845
  const parent = arm.g.parent;
8726
8846
  v.b.copy(v.wrist).sub(v.shoulder).normalize().multiplyScalar(Math.min(excess, ARM_REACH.protraction)).add(v.shoulder);
@@ -8741,11 +8861,13 @@ var GameCharactersThree = (() => {
8741
8861
  const arm = arms[side];
8742
8862
  const { upper: up, fore, palm } = lengthsOf(arm);
8743
8863
  wristOf(side, pose, palm);
8744
- protract(arm, up + fore);
8864
+ protract(arm, limitOf(side, up, fore));
8745
8865
  arm.g.getWorldPosition(v.shoulder);
8746
8866
  upper.getWorldQuaternion(q.body);
8747
- v.pole.set(ARM_REACH.elbowPole[0] * arm.outward, ARM_REACH.elbowPole[1], ARM_REACH.elbowPole[2]).applyQuaternion(q.body);
8748
- const most = Math.sqrt(up * up + fore * fore + 2 * up * fore * Math.cos(ARM_REACH.elbowMin));
8867
+ const pole = side === "L" ? ARM_REACH.elbowPoleSupport : ARM_REACH.elbowPole;
8868
+ v.pole.set(pole[0] * arm.outward, pole[1], pole[2]).applyQuaternion(q.body);
8869
+ const lockLimit = Math.sqrt(up * up + fore * fore + 2 * up * fore * Math.cos(ARM_REACH.elbowMin));
8870
+ const most = bendLimit ? Math.min(lockLimit, limitOf(side, up, fore)) : lockLimit;
8749
8871
  const least = Math.sqrt(up * up + fore * fore + 2 * up * fore * Math.cos(ARM_REACH.elbowMax));
8750
8872
  const line = v.c.copy(v.wrist).sub(v.shoulder);
8751
8873
  const distance3 = Math.min(most, Math.max(least, line.length()));
@@ -8770,6 +8892,20 @@ var GameCharactersThree = (() => {
8770
8892
  arm.el.getWorldQuaternion(q.parent);
8771
8893
  arm.hand.quaternion.copy(limitWrist(q.local.copy(q.parent.invert()).multiply(q.hand)));
8772
8894
  };
8895
+ const keepOutside = (pose, outside) => {
8896
+ const place = v.a.set(...pose.position).sub(camera.position).applyQuaternion(camera.inverse);
8897
+ camera.probe.set(place.x, place.y, 0).applyQuaternion(camera.quaternion).add(camera.position);
8898
+ camera.forward.set(0, 0, -1).applyQuaternion(camera.quaternion);
8899
+ const distance3 = outside.contact([camera.probe.x, camera.probe.y, camera.probe.z], [camera.forward.x, camera.forward.y, camera.forward.z], ARM_REACH.contactProbe);
8900
+ if (distance3 === null) return pose;
8901
+ camera.hand.set(...pose.quaternion).premultiply(camera.inverse);
8902
+ const ahead = Math.max(ARM_REACH.contactPalm, -camera.fingers.set(1, 0, 0).applyQuaternion(camera.hand).z * ARM_REACH.contactFingers);
8903
+ const limit = Math.max(outside.nearest ?? ARM_REACH.contactNearest, distance3 - ahead - (outside.margin ?? ARM_REACH.contactMargin));
8904
+ if (-place.z <= limit) return pose;
8905
+ place.z = -limit;
8906
+ place.applyQuaternion(camera.quaternion).add(camera.position);
8907
+ return { ...pose, position: [place.x, place.y, place.z] };
8908
+ };
8773
8909
  const save = () => {
8774
8910
  saved.twist = upper.rotation.y;
8775
8911
  for (const side of ["R", "L"]) {
@@ -8782,14 +8918,24 @@ var GameCharactersThree = (() => {
8782
8918
  }
8783
8919
  };
8784
8920
  return {
8785
- apply(targets) {
8921
+ apply(targets, view) {
8786
8922
  if (!targets || !targets.R && !targets.L) return;
8787
8923
  save();
8788
8924
  applied = true;
8789
8925
  upper.updateWorldMatrix(true, true);
8790
- if (targets.L && targets.R) turnChest(targets.L);
8791
- if (targets.R) reach("R", targets.R);
8792
- if (targets.L) reach("L", targets.L);
8926
+ let { R, L } = targets;
8927
+ bendLimit = view ? view.reachBend ?? ARM_REACH.viewBend : null;
8928
+ if (view?.keepOutside) {
8929
+ view.camera.updateWorldMatrix(true, false);
8930
+ view.camera.matrixWorld.decompose(camera.position, camera.quaternion, v.a);
8931
+ camera.inverse.copy(camera.quaternion).invert();
8932
+ if (R) R = keepOutside(R, view.keepOutside);
8933
+ if (L) L = keepOutside(L, view.keepOutside);
8934
+ }
8935
+ if (L && R) turnChest(L);
8936
+ if (R) reach("R", R);
8937
+ if (L) reach("L", L);
8938
+ bendLimit = null;
8793
8939
  },
8794
8940
  restore() {
8795
8941
  if (!applied) return;
@@ -8807,12 +8953,56 @@ var GameCharactersThree = (() => {
8807
8953
  };
8808
8954
  };
8809
8955
 
8956
+ // src/player/head-hiding.ts
8957
+ var isDrawable = (object2) => {
8958
+ const flagged = object2;
8959
+ return Boolean(flagged.isMesh || flagged.isSprite || flagged.isPoints);
8960
+ };
8961
+ var createHeadHider = (roots) => {
8962
+ let isHiding = false;
8963
+ let viewCamera = null;
8964
+ const drawables = [];
8965
+ for (const root of roots) root.traverse((object2) => isDrawable(object2) && drawables.push(object2));
8966
+ for (const drawable of drawables) {
8967
+ const previousBefore = drawable.onBeforeRender;
8968
+ const previousAfter = drawable.onAfterRender;
8969
+ let saved = [];
8970
+ drawable.onBeforeRender = (renderer, scene2, camera, geometry, material, group) => {
8971
+ previousBefore.call(drawable, renderer, scene2, camera, geometry, material, group);
8972
+ if (!isHiding || camera !== viewCamera) return;
8973
+ const drawn = Array.isArray(drawable.material) ? drawable.material : [material];
8974
+ saved = drawn.map((entry) => ({ material: entry, colorWrite: entry.colorWrite, depthWrite: entry.depthWrite }));
8975
+ for (const entry of drawn) {
8976
+ entry.colorWrite = false;
8977
+ entry.depthWrite = false;
8978
+ }
8979
+ };
8980
+ drawable.onAfterRender = (renderer, scene2, camera, geometry, material, group) => {
8981
+ previousAfter.call(drawable, renderer, scene2, camera, geometry, material, group);
8982
+ for (const flags of saved) {
8983
+ flags.material.colorWrite = flags.colorWrite;
8984
+ flags.material.depthWrite = flags.depthWrite;
8985
+ }
8986
+ saved = [];
8987
+ };
8988
+ }
8989
+ return {
8990
+ setView(mode, camera) {
8991
+ isHiding = mode === "first" && camera !== null;
8992
+ viewCamera = camera;
8993
+ }
8994
+ };
8995
+ };
8996
+
8810
8997
  // src/player/avatar.ts
8811
8998
  var TWO_PI2 = Math.PI * 2;
8812
8999
  var MAX_GAIT = 1.4;
8813
9000
  var CLIP_BLEND = 0.12;
8814
9001
  var CLIP_CASCADE = 5;
8815
9002
  var FALL_SECONDS2 = 0.3;
9003
+ var BUILDER_EYE = [0, 1.815, 0.16];
9004
+ var EYE_OFFSET = [0, -0.068, 0];
9005
+ var EYE_BOB = 0.5;
8816
9006
  var HIP_HEIGHT = 0.95;
8817
9007
  var WALK_ARM = 0.28;
8818
9008
  var WALK_BOB = 0.035;
@@ -8822,7 +9012,11 @@ var GameCharactersThree = (() => {
8822
9012
  var REST_ARM_Z = 0.18;
8823
9013
  var CROUCH = { thigh: -0.95, thighWalk: 0.3, shin: 1.9, lean: 0.25, drop: -0.35 };
8824
9014
  var AIMED = { shoulder: -1.42, perAim: 0.85, swing: 0.02, zRight: -0.54, zLeft: 0.36, elbowRight: -0.04, elbowLeft: -0.12 };
9015
+ var SIT = { thigh: -1.5, lean: -0.08, arm: -0.45, armZ: 0.12, elbow: -0.75 };
9016
+ var LIE = { knee: 0.08, armZ: 0.12, elbow: -0.1 };
8825
9017
  var DOWN = { thighWalk: 0.5, shinSwing: 0.85, shinBend: 1.3, armHigh: -2.8, armLow: -0.35, armWave: 0.3, armZ: 0.5, armZWave: 0.3, tilt: 1.5, roll: 0.3, hipY: 0.16, hipZ: 0.6, hipZFlip: 1.2 };
9018
+ var DOOR_SHOULDER = 1.42;
9019
+ var DOOR_ARM = 0.62;
8826
9020
  var HAND_OFFSET = { x: 0, y: -0.33, z: 0.04 };
8827
9021
  var hexOf = (value) => typeof value === "string" ? Number.parseInt(value, 16) : value;
8828
9022
  var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
@@ -8852,6 +9046,8 @@ var GameCharactersThree = (() => {
8852
9046
  const fallSeconds = options.fallSeconds ?? FALL_SECONDS2;
8853
9047
  const smooth = options.cascade ?? true;
8854
9048
  const clipCascade = options.clipCascade ?? CLIP_CASCADE;
9049
+ const eyeBob = options.eyeBob ?? EYE_BOB;
9050
+ const eyeOffset = options.eyeOffset ?? EYE_OFFSET;
8855
9051
  const root = new THREE.Group();
8856
9052
  const tilt = new THREE.Group();
8857
9053
  tilt.add(body);
@@ -8911,7 +9107,23 @@ var GameCharactersThree = (() => {
8911
9107
  if (hand.th) hand.th.rotation.z = -hand.side * (0.32 + grip * 0.25);
8912
9108
  hand.hg.rotation.x = wristX;
8913
9109
  };
9110
+ const eyeSocket = new THREE.Object3D();
9111
+ eyeSocket.name = "eye";
9112
+ eyeSocket.position.set(BUILDER_EYE[0] + eyeOffset[0], BUILDER_EYE[1] + eyeOffset[1], BUILDER_EYE[2] + eyeOffset[2]);
9113
+ rig.headG.children[0].add(eyeSocket);
9114
+ const headHider = createHeadHider([rig.headG, ...rig.neck ? [rig.neck] : []]);
9115
+ const eyeLocal = new THREE.Vector3();
9116
+ let bob = 0;
9117
+ let hipWithoutBob = null;
8914
9118
  const legRestX = rig.legs.map((leg) => leg.g.position.x);
9119
+ const legLengths = (() => {
9120
+ const thigh = rig.legs[0].g;
9121
+ const shin = rig.legs[0].kn;
9122
+ root.updateMatrixWorld(true);
9123
+ const hipY = thigh.getWorldPosition(new THREE.Vector3()).y;
9124
+ const kneeY = shin.getWorldPosition(new THREE.Vector3()).y;
9125
+ return { hipBelowTrunk: HIP_HEIGHT - hipY, thigh: hipY - kneeY, shin: kneeY - new THREE.Box3().setFromObject(shin).min.y };
9126
+ })();
8915
9127
  const legSide = (index) => index === 0 ? 1 : -1;
8916
9128
  let cycles = 0;
8917
9129
  let time = 0;
@@ -8970,10 +9182,29 @@ var GameCharactersThree = (() => {
8970
9182
  ...strain ? { legL: -0.5, legR: 0.4, kneeL: 0.55, kneeR: 0.08, drop: -0.05 } : {}
8971
9183
  };
8972
9184
  };
9185
+ const doorPose = (door) => {
9186
+ const { phase, progress } = door;
9187
+ const on = phase === "reach" ? progress : phase === "release" ? 1 - progress : 1;
9188
+ const swing = phase === "swing" ? progress : phase === "release" ? 1 : 0;
9189
+ const shake = phase === "rattle" ? Math.sin(time * 55) * 0.06 * (1 - progress) : 0;
9190
+ const drop = clamp((DOOR_SHOULDER - door.height) / DOOR_ARM, -0.9, 1);
9191
+ const low = clamp((0.75 - door.height) / 0.5, 0, 1);
9192
+ const raise = -Math.acos(clamp(drop, -1, 1)) * on - 0.35 * low * on;
9193
+ const elbow = door.pull ? -0.35 - 0.75 * swing : -0.95 + 0.75 * swing;
9194
+ return {
9195
+ armR: raise + shake,
9196
+ armRz: REST_ARM_Z * (1 - on) + 0.05 * on,
9197
+ elbR: -0.12 + (elbow + 0.12) * on,
9198
+ armLz: -REST_ARM_Z,
9199
+ elbL: -0.12,
9200
+ lean: ((door.pull ? -0.06 : 0.1) * swing + 0.35 * low) * on,
9201
+ headX: 0.06 * on + 0.2 * low * on
9202
+ };
9203
+ };
8973
9204
  const holdingPose = (gait, itemUse) => {
8974
- const bob = Math.sin(cycles * TWO_PI2) * 0.05 * gait;
9205
+ const bob2 = Math.sin(cycles * TWO_PI2) * 0.05 * gait;
8975
9206
  if (!itemUse) {
8976
- return { armL: -0.45 + bob, armLz: 0.22, elbL: -1.05 };
9207
+ return { armL: -0.45 + bob2, armLz: 0.22, elbL: -1.05 };
8977
9208
  }
8978
9209
  const { id, position, rotation } = itemUse;
8979
9210
  if (id === "drink" || id === "sip" || id === "chug") {
@@ -8986,7 +9217,7 @@ var GameCharactersThree = (() => {
8986
9217
  headX: -0.26 * tilt3
8987
9218
  };
8988
9219
  }
8989
- if (id === "open" || id === "close") {
9220
+ if (id === "open" || id === "close" || itemUse.gripL !== void 0) {
8990
9221
  const reach = clamp((0.22 - position[0]) / 0.12, 0, 1);
8991
9222
  return {
8992
9223
  armL: -0.45 - 0.35 * reach,
@@ -9085,6 +9316,31 @@ var GameCharactersThree = (() => {
9085
9316
  drop: Math.abs(Math.sin(ph)) * WALK_BOB * gait
9086
9317
  };
9087
9318
  };
9319
+ const sitPose = (hip) => {
9320
+ const knee = hip - legLengths.hipBelowTrunk - legLengths.thigh * Math.cos(SIT.thigh);
9321
+ const shinFromVertical = Math.acos(clamp(knee / legLengths.shin, 0, 1));
9322
+ const bend = -SIT.thigh - shinFromVertical;
9323
+ return {
9324
+ legL: SIT.thigh,
9325
+ legR: SIT.thigh,
9326
+ kneeL: bend,
9327
+ kneeR: bend,
9328
+ lean: SIT.lean,
9329
+ drop: hip - HIP_HEIGHT,
9330
+ armR: SIT.arm,
9331
+ armL: SIT.arm,
9332
+ armRz: SIT.armZ,
9333
+ armLz: -SIT.armZ,
9334
+ elbR: SIT.elbow,
9335
+ elbL: SIT.elbow
9336
+ };
9337
+ };
9338
+ const liePose = () => ({ legL: 0, legR: 0, kneeL: LIE.knee, kneeR: LIE.knee, lean: 0, drop: 0, armR: 0, armL: 0, armRz: LIE.armZ, armLz: -LIE.armZ, elbR: LIE.elbow, elbL: LIE.elbow });
9339
+ const layBody = (hip) => {
9340
+ tilt.rotation.set(-Math.PI / 2, 0, 0, "XYZ");
9341
+ const pivot = new THREE.Vector3(0, HIP_HEIGHT, 0).applyEuler(tilt.rotation);
9342
+ tilt.position.set(0, hip, 0).sub(pivot);
9343
+ };
9088
9344
  const placeBody = (progress) => {
9089
9345
  const fk = progress * progress * (3 - 2 * progress);
9090
9346
  const flip = fract(cycles * 1.7) >= 0.5 ? 1 : 0;
@@ -9145,13 +9401,27 @@ var GameCharactersThree = (() => {
9145
9401
  profile.bob = (running ? RUN_BOB : WALK_BOB) * gait;
9146
9402
  time = cycles / (walkCadence(Math.max(speed, 0)) * (running ? 1.3 : 1));
9147
9403
  animator.animate(body, time, { speed });
9404
+ bob = rig.fig.position.y - rig.dropBase;
9148
9405
  fall = fallSeconds <= 0 ? down ? 1 : 0 : clamp(fall + (down ? dt : -dt) / fallSeconds, 0, 1);
9149
9406
  resetLegYaw();
9150
- if (down) animator.setPose(rig, downPose());
9151
- else {
9152
- if (running) animator.setPose(rig, runningPose(gait, Boolean(state.armed || state.holding || state.itemUse)));
9153
- if (state.crouch) animator.setPose(rig, crouchPose(gait));
9407
+ const seat = down ? null : state.seat ?? null;
9408
+ if (down) {
9409
+ animator.setPose(rig, downPose());
9410
+ bob = rig.fig.position.y - rig.dropBase;
9411
+ } else if (seat) {
9412
+ animator.setPose(rig, seat.pose === "lie" ? liePose() : sitPose(seat.hip));
9413
+ bob = 0;
9414
+ } else {
9415
+ if (running) {
9416
+ animator.setPose(rig, runningPose(gait, Boolean(state.armed || state.holding || state.itemUse)));
9417
+ bob = rig.fig.position.y - rig.dropBase;
9418
+ }
9419
+ if (state.crouch) {
9420
+ animator.setPose(rig, crouchPose(gait));
9421
+ bob = rig.fig.position.y - rig.dropBase - CROUCH.drop;
9422
+ }
9154
9423
  if (state.push) animator.setPose(rig, pushingPose(state.push));
9424
+ else if (state.door) animator.setPose(rig, doorPose(state.door));
9155
9425
  else if (state.armed) animator.setPose(rig, armed(state.pitch ?? 0, gait, state.hip ?? 0));
9156
9426
  else if (state.holding || state.itemUse) animator.setPose(rig, holdingPose(gait, state.itemUse));
9157
9427
  else if (!running) {
@@ -9163,20 +9433,33 @@ var GameCharactersThree = (() => {
9163
9433
  });
9164
9434
  }
9165
9435
  }
9166
- placeBody(fall);
9167
- stepClip(dt, down, Boolean(state.crouch));
9168
- if (smooth) animator.cascade(rig, run && !run.clip.loop ? dt * clipCascade : dt);
9436
+ if (seat?.pose === "lie") layBody(seat.hip);
9437
+ else placeBody(fall);
9438
+ stepClip(dt, down, Boolean(state.crouch || seat));
9439
+ const cascadeDt = run && !run.clip.loop ? dt * clipCascade : dt;
9440
+ const targetWithoutBob = rig.fig.position.y - bob;
9441
+ if (smooth) animator.cascade(rig, cascadeDt);
9442
+ hipWithoutBob = smooth && hipWithoutBob !== null ? stepCascade(hipWithoutBob, targetWithoutBob, cascadeDt, "hip") : targetWithoutBob;
9443
+ bob = rig.fig.position.y - hipWithoutBob;
9169
9444
  const blow = run?.clip.events?.find((event) => (event.type === "impact" || event.type === "grip") && event.data?.kind)?.data?.kind;
9170
9445
  const ph = cycles * TWO_PI2;
9171
9446
  hands.forEach((hand) => {
9172
9447
  const isRight = hand.side < 0;
9173
9448
  const holdRight = isRight && (!!state.holding || !!state.itemUse);
9174
- const holdLeft = !isRight && (state.itemUse?.id === "open" || state.itemUse?.id === "close");
9175
- const grip = blow === "punch" ? 1.4 : blow === "shove" ? 0.15 : state.armed || holdRight || holdLeft ? 1.22 : running ? 0.85 : 0.12;
9449
+ const holdLeft = !isRight && (state.itemUse?.id === "open" || state.itemUse?.id === "close" || state.itemUse?.gripL !== void 0);
9450
+ const grip = !isRight && state.itemUse?.gripL !== void 0 ? 1.22 * state.itemUse.gripL : blow === "punch" ? 1.4 : blow === "shove" ? 0.15 : state.armed || holdRight || holdLeft ? 1.22 : running ? 0.85 : 0.12;
9176
9451
  const wristSwing = holdRight || state.armed || running ? 0 : -Math.min(1, gait) * Math.sin(ph - 0.6) * 0.12 * hand.side;
9177
9452
  setHandGrip(hand, grip, wristSwing);
9178
9453
  });
9454
+ root.updateMatrixWorld(true);
9455
+ root.worldToLocal(eyeSocket.getWorldPosition(eyeLocal));
9456
+ eyeLocal.y -= (1 - eyeBob) * bob;
9457
+ },
9458
+ eye(out = new THREE.Vector3()) {
9459
+ root.updateWorldMatrix(true, false);
9460
+ return root.localToWorld(out.copy(eyeLocal));
9179
9461
  },
9462
+ setView: (mode, camera) => headHider.setView(mode, camera),
9180
9463
  play(clip, playOptions = {}) {
9181
9464
  const found = typeof clip === "string" ? clips.get(clip) : clip;
9182
9465
  if (!found) throw new Error(`Unknown pose clip: ${String(clip)}`);
@@ -9188,10 +9471,11 @@ var GameCharactersThree = (() => {
9188
9471
  if (run) run.target = 0;
9189
9472
  },
9190
9473
  hand: (side) => sockets[side],
9191
- reach(targets) {
9474
+ shoulder: (side) => armOf[side].g,
9475
+ reach(targets, view) {
9192
9476
  if (run || fall > 0) return;
9193
9477
  root.updateMatrixWorld(true);
9194
- armReach.apply(targets);
9478
+ armReach.apply(targets, view);
9195
9479
  },
9196
9480
  on(_type, listener) {
9197
9481
  listeners.add(listener);
@@ -9614,6 +9898,233 @@ var GameCharactersThree = (() => {
9614
9898
  var FIRST_PERSON_CLIPS = first_person_clips_default.clips;
9615
9899
  var NAME_POOLS = { "pt-BR": names_default["pt-BR"] };
9616
9900
 
9901
+ // src/player/room-avatar.ts
9902
+ var impactOf = (clip) => clip.events?.find((event) => event.type === "impact")?.t ?? null;
9903
+ var isPunch = (clip) => clip.events?.some((event) => event.type === "impact" && event.data?.kind === "punch") ?? false;
9904
+ var GUARD_SPEED = 0.3;
9905
+ var toRoomAvatar = (avatar, options = {}) => {
9906
+ const strikes = new Map((options.strikeClips ?? ATTACK_CLIPS).map((clip) => [clip.id, clip]));
9907
+ const mirrored = /* @__PURE__ */ new Map();
9908
+ const leftOf = (clip) => {
9909
+ let found = mirrored.get(clip.id);
9910
+ if (!found) mirrored.set(clip.id, found = mirrorPoseClip(clip, `${clip.id}_left`));
9911
+ return found;
9912
+ };
9913
+ const guard = options.guardClip === false ? void 0 : strikes.get(options.guardClip ?? "fight_guard");
9914
+ const guardHold = options.guardHold ?? 1.2;
9915
+ const punchBlend = options.punchBlend ?? 0.05;
9916
+ let strikeLeft = 0;
9917
+ let guardLeft = 0;
9918
+ let guarding = false;
9919
+ const stepGuard = (dt, state) => {
9920
+ if (!guard) return;
9921
+ const free = state.speed < GUARD_SPEED && !state.down && !state.armed && !state.holding && !state.push && !state.door && !state.itemUse && !state.running;
9922
+ if (strikeLeft > 0) {
9923
+ strikeLeft -= dt;
9924
+ if (strikeLeft <= 0 && guardLeft > 0 && free) {
9925
+ avatar.play(guard);
9926
+ guarding = true;
9927
+ }
9928
+ return;
9929
+ }
9930
+ guardLeft = Math.max(0, guardLeft - dt);
9931
+ if (guarding && (guardLeft <= 0 || !free || avatar.playing !== guard.id)) {
9932
+ if (avatar.playing === guard.id) avatar.stop();
9933
+ guarding = false;
9934
+ }
9935
+ };
9936
+ return {
9937
+ root: avatar.root,
9938
+ avatar,
9939
+ eye: (out) => avatar.eye(out),
9940
+ setView: (mode, camera) => avatar.setView(mode, camera),
9941
+ update: (dt, state) => {
9942
+ stepGuard(dt, state);
9943
+ avatar.update(dt, {
9944
+ speed: state.speed,
9945
+ running: state.running,
9946
+ crouch: state.crouch,
9947
+ down: state.down,
9948
+ armed: state.armed,
9949
+ pitch: -state.pitch,
9950
+ ...state.holding !== void 0 ? { holding: state.holding } : {},
9951
+ ...state.itemUse !== void 0 ? { itemUse: state.itemUse } : {},
9952
+ ...state.push !== void 0 ? { push: state.push } : {},
9953
+ ...state.seat !== void 0 ? { seat: state.seat } : {},
9954
+ ...state.door !== void 0 ? { door: state.door } : {}
9955
+ });
9956
+ },
9957
+ hand: (side) => avatar.hand(side),
9958
+ shoulder: (side) => avatar.shoulder(side),
9959
+ reach: (targets, view) => avatar.reach(targets, view),
9960
+ strike: (clipId, strikeOptions) => {
9961
+ const clip = strikes.get(clipId);
9962
+ if (!clip) return null;
9963
+ const left = strikeOptions?.leg === "left" || strikeOptions?.hand === "left";
9964
+ const punch = guard !== void 0 && isPunch(clip);
9965
+ avatar.play(left ? leftOf(clip) : clip, punch ? { blend: punchBlend } : void 0);
9966
+ strikeLeft = punch ? clip.duration : 0;
9967
+ guardLeft = punch ? guardHold : 0;
9968
+ guarding = false;
9969
+ return impactOf(clip);
9970
+ }
9971
+ };
9972
+ };
9973
+
9974
+ // src/player/test-text.ts
9975
+ var AVATAR_TEXT = {
9976
+ en: {
9977
+ group: "Avatar",
9978
+ name: "Player body",
9979
+ actions: {
9980
+ camera_first: "Camera: 1st person",
9981
+ camera_third: "Camera: 3rd person",
9982
+ crouch: "Crouch",
9983
+ stand: "Stand up",
9984
+ fall: "Fall down",
9985
+ get_up: "Get up",
9986
+ armed_on: "Armed: on",
9987
+ armed_off: "Armed: off",
9988
+ stop_clip: "Stop clip"
9989
+ },
9990
+ play: "Play",
9991
+ metrics: { camera: "Camera", clip: "Clip playing", last_event: "Last clip event", state: "State", joints: "Joints" },
9992
+ none: "none"
9993
+ },
9994
+ "pt-BR": {
9995
+ group: "Avatar",
9996
+ name: "Corpo do jogador",
9997
+ actions: {
9998
+ camera_first: "C\xE2mera: 1\xAA pessoa",
9999
+ camera_third: "C\xE2mera: 3\xAA pessoa",
10000
+ crouch: "Agachar",
10001
+ stand: "Levantar",
10002
+ fall: "Cair",
10003
+ get_up: "Levantar do ch\xE3o",
10004
+ armed_on: "Armado: ligado",
10005
+ armed_off: "Armado: desligado",
10006
+ stop_clip: "Parar clipe"
10007
+ },
10008
+ play: "Tocar",
10009
+ metrics: { camera: "C\xE2mera", clip: "Clipe tocando", last_event: "\xDAltimo evento do clipe", state: "Estado", joints: "Juntas" },
10010
+ none: "nenhum"
10011
+ }
10012
+ };
10013
+
10014
+ // src/player/test-module.ts
10015
+ var AVATAR_AREA_ID = "avatar_area";
10016
+ var round = (value) => (Math.round(value * 100) / 100).toString();
10017
+ function createAvatarTestModule(options) {
10018
+ const clips = options.clips ?? POSE_CLIPS;
10019
+ const textOf = (locale) => AVATAR_TEXT[locale ?? options.locale ?? "pt-BR"] ?? AVATAR_TEXT["pt-BR"];
10020
+ const phaseLabel = (label, locale) => {
10021
+ const id = locale ?? options.locale ?? "pt-BR";
10022
+ const table = { ...POSE_CLIP_LOCALES[id] ?? POSE_CLIP_LOCALES["pt-BR"], ...options.clipLocales?.[id] ?? options.clipLocales?.["pt-BR"] };
10023
+ return typeof label === "string" ? table[label] ?? label : "";
10024
+ };
10025
+ const state = { crouch: false, down: false, armed: null };
10026
+ let host = null;
10027
+ let lastEvent = "";
10028
+ const log = (action, extra = {}) => {
10029
+ const entry = { type: "avatar", action, ...extra };
10030
+ host?.log(JSON.stringify(entry), entry);
10031
+ };
10032
+ const push = (action, patch, extra = {}) => {
10033
+ Object.assign(state, patch);
10034
+ options.state?.set(patch);
10035
+ log(action, { crouch: state.crouch, down: state.down, armed: state.armed, ...extra });
10036
+ };
10037
+ const setCamera = (mode) => {
10038
+ options.camera?.set(mode);
10039
+ log(`camera_${mode}`, { mode: options.camera?.mode() ?? null });
10040
+ };
10041
+ const onChange = (change) => {
10042
+ if (change.kind !== "action") return;
10043
+ switch (change.id) {
10044
+ case "camera_first":
10045
+ return setCamera("first");
10046
+ case "camera_third":
10047
+ return setCamera("third");
10048
+ case "crouch":
10049
+ return push("crouch", { crouch: true });
10050
+ case "stand":
10051
+ return push("stand", { crouch: false });
10052
+ case "fall":
10053
+ return push("fall", { down: true });
10054
+ case "get_up":
10055
+ return push("get_up", { down: false });
10056
+ case "armed_on":
10057
+ return push("armed_on", { armed: true });
10058
+ case "armed_off":
10059
+ return push("armed_off", { armed: false });
10060
+ case "stop_clip":
10061
+ options.avatar.stop();
10062
+ return log("stop_clip", { playing: options.avatar.playing });
10063
+ default: {
10064
+ const clip = clips.find((item) => `play_${item.id}` === change.id);
10065
+ if (!clip) return;
10066
+ options.avatar.play(clip);
10067
+ log("play_clip", { clip: clip.id, duration: clip.duration, loop: clip.loop ?? false, channels: clip.channels ?? "full" });
10068
+ }
10069
+ }
10070
+ };
10071
+ const joints = () => {
10072
+ const rig = options.avatar.rig;
10073
+ const [armA, armB] = rig.arms;
10074
+ const [legA, legB] = rig.legs;
10075
+ return `arms ${round(armA.g.rotation.x)}/${round(armB.g.rotation.x)} elbows ${round(armA.el.rotation.x)}/${round(armB.el.rotation.x)} legs ${round(legA.g.rotation.x)}/${round(legB.g.rotation.x)} knees ${round(legA.kn.rotation.x)}/${round(legB.kn.rotation.x)} lean ${round(rig.upper.rotation.x)}`;
10076
+ };
10077
+ return {
10078
+ id: AVATAR_AREA_ID,
10079
+ name: textOf().name,
10080
+ ground: { surface: "concrete_slab" },
10081
+ group: textOf().group,
10082
+ state,
10083
+ items: () => [],
10084
+ area: () => ({ placements: [], view: { eye: [0, 1.7, 6], target: [0, 1.2, 0] } }),
10085
+ controls: (locale) => {
10086
+ const text = textOf(locale);
10087
+ const action = (id, name, hint) => ({ kind: "action", id, name, ...hint ? { hint } : {} });
10088
+ return [
10089
+ action("camera_first", text.actions.camera_first),
10090
+ action("camera_third", text.actions.camera_third),
10091
+ action("crouch", text.actions.crouch),
10092
+ action("stand", text.actions.stand),
10093
+ action("fall", text.actions.fall),
10094
+ action("get_up", text.actions.get_up),
10095
+ action("armed_on", text.actions.armed_on),
10096
+ action("armed_off", text.actions.armed_off),
10097
+ ...clips.map((clip) => action(`play_${clip.id}`, `${text.play}: ${clip.id}`)),
10098
+ action("stop_clip", text.actions.stop_clip)
10099
+ ];
10100
+ },
10101
+ metrics: (locale) => {
10102
+ const text = textOf(locale);
10103
+ return [
10104
+ { id: "camera", name: text.metrics.camera, read: () => options.camera?.mode() ?? text.none },
10105
+ { id: "clip", name: text.metrics.clip, read: () => options.avatar.playing ?? text.none },
10106
+ { id: "last_event", name: text.metrics.last_event, read: () => lastEvent || text.none },
10107
+ { id: "state", name: text.metrics.state, read: () => `${state.crouch ? "crouch " : ""}${state.down ? "down " : ""}${state.armed === null ? "" : state.armed ? "armed" : "unarmed"}`.trim() || text.none },
10108
+ { id: "joints", name: text.metrics.joints, read: joints }
10109
+ ];
10110
+ },
10111
+ attach(lent) {
10112
+ host = lent;
10113
+ const stopChange = lent.bench?.onChange(onChange);
10114
+ const stopEvents = options.avatar.on("event", (event) => {
10115
+ lastEvent = `${event.clip} ${event.type} ${round(event.t)}s${event.data && "label" in event.data ? ` ${phaseLabel(event.data.label)}` : ""}`;
10116
+ log("clip_event", { clip: event.clip, event: event.type, t: event.t, data: event.data ?? null });
10117
+ if (event.type === "impact") log("impact", { clip: event.clip, t: event.t, kind: event.data?.kind ?? null });
10118
+ });
10119
+ return () => {
10120
+ stopChange?.();
10121
+ stopEvents();
10122
+ host = null;
10123
+ };
10124
+ }
10125
+ };
10126
+ }
10127
+
9617
10128
  // src/presets/first-person-arms.json
9618
10129
  var first_person_arms_default = {
9619
10130
  source: {
@@ -9623,7 +10134,9 @@ var GameCharactersThree = (() => {
9623
10134
  shoulder: [0.16, -0.36, 0.18],
9624
10135
  upper: 0.32,
9625
10136
  fore: 0.3,
9626
- reachShift: 0.35,
10137
+ reachShift: 0.42,
10138
+ reachBend: [1.35, 0.95],
10139
+ elbowView: [[0.96, -0.26, -0.06], null],
9627
10140
  wrist: 0.07,
9628
10141
  elbowPole: [0.45, -1, 0.2],
9629
10142
  shoulderLeft: [-0.07, -0.46, 0.18],
@@ -9650,22 +10163,14 @@ var GameCharactersThree = (() => {
9650
10163
  };
9651
10164
 
9652
10165
  // src/first-person/hand.ts
9653
- var FINGERS = [
9654
- { z: -0.03, lengths: [0.034, 0.024, 0.02], width: 0.016 },
9655
- { z: -0.0105, lengths: [0.038, 0.027, 0.022], width: 0.0165 },
9656
- { z: 9e-3, lengths: [0.035, 0.025, 0.02], width: 0.0155 },
9657
- { z: 0.027, lengths: [0.029, 0.02, 0.018], width: 0.0135 }
9658
- ];
9659
- var PALM = { length: 0.09, thick: 0.026, width: 0.09, wristWidth: 0.066 };
9660
- var FINGER_THICK = 0.0135;
9661
- var CURL = { near: 1.05, mid: 1.25, far: 0.85, spread: 0.06 };
9662
- var THUMB = { base: [5e-3, -6e-3, -0.044], near: 0.034, far: 0.028, width: 0.019 };
10166
+ var PALM = { radius: 0.048, scale: [0.6, 1.05, 1], down: 0.035 };
10167
+ var CURL = { closed: 1.25, near: 0.9, far: 1.1 };
10168
+ var THUMB = { open: 0.32, closed: 0.25 };
9663
10169
  var createHandMesh = (THREE, skin, wristSkin = skin) => {
9664
10170
  const root = new THREE.Group();
9665
10171
  root.name = "first-person-hand";
9666
10172
  const geometries = [];
9667
- const box2 = (parent, sx, sy, sz, x, y, z, material = skin) => {
9668
- const geometry = new THREE.BoxGeometry(sx, sy, sz);
10173
+ const add = (parent, geometry, material, x = 0, y = 0, z = 0) => {
9669
10174
  geometries.push(geometry);
9670
10175
  const mesh2 = new THREE.Mesh(geometry, material);
9671
10176
  mesh2.position.set(x, y, z);
@@ -9673,64 +10178,26 @@ var GameCharactersThree = (() => {
9673
10178
  parent.add(mesh2);
9674
10179
  return mesh2;
9675
10180
  };
9676
- const palmGeometry = new THREE.BoxGeometry(PALM.length, PALM.thick, PALM.width);
9677
- const palmPosition = palmGeometry.getAttribute("position");
9678
- for (let i = 0; i < palmPosition.count; i++) {
9679
- if (palmPosition.getX(i) < 0) palmPosition.setZ(i, palmPosition.getZ(i) * PALM.wristWidth / PALM.width);
9680
- }
9681
- palmGeometry.computeVertexNormals();
9682
- geometries.push(palmGeometry);
9683
- const palm = new THREE.Mesh(palmGeometry, skin);
9684
- palm.frustumCulled = false;
9685
- root.add(palm);
9686
- const wristGeometry = new THREE.CylinderGeometry(0.03, 0.033, 0.05, 8);
10181
+ const group = new THREE.Group();
10182
+ group.quaternion.setFromRotationMatrix(new THREE.Matrix4().makeBasis(new THREE.Vector3(0, -1, 0), new THREE.Vector3(-1, 0, 0), new THREE.Vector3(0, 0, -1)));
10183
+ group.position.set(-PALM.down, 0, 0);
10184
+ root.add(group);
10185
+ add(group, new THREE.SphereGeometry(PALM.radius, 14, 10), skin, 0, -PALM.down, 0).scale.set(...PALM.scale);
10186
+ const built = buildHand({ THREE, add, hg: group, handM: skin, s: -1, detailed: true });
10187
+ const wristGeometry = new THREE.CylinderGeometry(0.03, 0.033, 0.05, 10);
9687
10188
  wristGeometry.rotateZ(Math.PI / 2);
9688
- geometries.push(wristGeometry);
9689
- const wrist = new THREE.Mesh(wristGeometry, wristSkin);
9690
- wrist.position.set(-PALM.length / 2 - 0.018, 0, 0);
9691
- wrist.frustumCulled = false;
9692
- root.add(wrist);
9693
- const joints = [];
9694
- FINGERS.forEach((finger, index) => {
9695
- const segments = [];
9696
- let parent = root;
9697
- let at = PALM.length / 2;
9698
- finger.lengths.forEach((length, k) => {
9699
- const group = new THREE.Group();
9700
- group.position.set(at, k === 0 ? 2e-3 : 0, k === 0 ? finger.z : 0);
9701
- const taper = 1 - k * 0.07;
9702
- box2(group, length, FINGER_THICK * taper, finger.width * taper, length / 2, 0, 0);
9703
- parent.add(group);
9704
- segments.push(group);
9705
- parent = group;
9706
- at = length;
9707
- });
9708
- joints.push({ segments, weight: 1 + index * (CURL.spread / CURL.near) });
9709
- });
9710
- const thumbNear = new THREE.Group();
9711
- thumbNear.rotation.order = "YZX";
9712
- thumbNear.position.set(...THUMB.base);
9713
- box2(thumbNear, THUMB.near, FINGER_THICK * 1.1, THUMB.width, THUMB.near / 2, 0, 0);
9714
- const thumbFar = new THREE.Group();
9715
- thumbFar.position.set(THUMB.near, 0, 0);
9716
- box2(thumbFar, THUMB.far, FINGER_THICK, THUMB.width * 0.9, THUMB.far / 2, 0, 0);
9717
- thumbNear.add(thumbFar);
9718
- root.add(thumbNear);
10189
+ add(root, wristGeometry, wristSkin, -PALM.down - 0.03, 0, 0);
9719
10190
  let lastGrip = 0;
9720
10191
  let indexCurl;
9721
- const curl = [CURL.near, CURL.mid, CURL.far];
9722
- const applyIndex = () => {
9723
- const finger = joints[0];
9724
- if (!finger) return;
9725
- const k = indexCurl === void 0 ? lastGrip : Math.min(1, Math.max(0, indexCurl));
9726
- finger.segments.forEach((segment, i) => segment.rotation.z = -curl[i] * k * finger.weight);
10192
+ const curlFinger = (finger, k) => {
10193
+ built.fingers[finger * 2].rotation.z = k * CURL.closed * CURL.near;
10194
+ built.fingers[finger * 2 + 1].rotation.z = k * CURL.closed * CURL.far;
9727
10195
  };
10196
+ const applyIndex = () => curlFinger(0, indexCurl === void 0 ? lastGrip : Math.min(1, Math.max(0, indexCurl)));
9728
10197
  const setGrip = (grip) => {
9729
- const k = Math.min(1, Math.max(0, grip));
9730
- lastGrip = k;
9731
- for (const joint of joints) joint.segments.forEach((segment, i) => segment.rotation.z = -curl[i] * k * joint.weight);
9732
- thumbNear.rotation.set(0, 0.55 - 1.45 * k, -0.1 - 0.75 * k);
9733
- thumbFar.rotation.z = -0.1 - 0.7 * k;
10198
+ lastGrip = Math.min(1, Math.max(0, grip));
10199
+ for (let finger = 1; finger < 4; finger++) curlFinger(finger, lastGrip);
10200
+ if (built.th) built.th.rotation.z = THUMB.open + lastGrip * THUMB.closed;
9734
10201
  applyIndex();
9735
10202
  };
9736
10203
  const setIndex = (value) => {
@@ -9752,6 +10219,8 @@ var GameCharactersThree = (() => {
9752
10219
  var DEFAULT_BLEND = 0.18;
9753
10220
  var ELBOW_SEGMENTS = 8;
9754
10221
  var REACH_SLACK = 0.97;
10222
+ var ELBOW_VIEW_MARGIN = 0.86;
10223
+ var ELBOW_VIEW_PASSES = 4;
9755
10224
  var CONTACT_PROBE = 1.4;
9756
10225
  var CONTACT_MIN = 0.12;
9757
10226
  var CONTACT_MARGIN = 5e-3;
@@ -9900,6 +10369,11 @@ var GameCharactersThree = (() => {
9900
10369
  const shoulderOf = (sign2, out) => sign2 === -1 && rig.shoulderLeft ? out.set(...rig.shoulderLeft) : out.set(rig.shoulder[0] * sign2, rig.shoulder[1], rig.shoulder[2]);
9901
10370
  const poleOf = (sign2) => sign2 === -1 && rig.elbowPoleLeft ? new THREE.Vector3(...rig.elbowPoleLeft) : new THREE.Vector3(rig.elbowPole[0] * sign2, rig.elbowPole[1], rig.elbowPole[2]);
9902
10371
  const kneePole = new THREE.Vector3(...rig.kneePole);
10372
+ const reachOf = (sign2) => {
10373
+ const bend = rig.reachBend?.[sign2 === 1 ? 0 : 1];
10374
+ if (bend === void 0) return (rig.upper + rig.fore) * REACH_SLACK;
10375
+ return Math.sqrt(rig.upper * rig.upper + rig.fore * rig.fore + 2 * rig.upper * rig.fore * Math.cos(bend));
10376
+ };
9903
10377
  const hip = new THREE.Vector3(...rig.hip);
9904
10378
  const euler = new THREE.Euler(0, 0, 0, "YZX");
9905
10379
  const quaternionOf = (r) => new THREE.Quaternion().setFromEuler(euler.set(r[0], r[1], r[2], "YZX"));
@@ -9989,15 +10463,45 @@ var GameCharactersThree = (() => {
9989
10463
  out.scale = base.scale;
9990
10464
  return out;
9991
10465
  };
9992
- const drawArm = (arm, pose) => {
10466
+ const elbowAt = new THREE.Vector3();
10467
+ const viewOf = (camera) => {
10468
+ const lens = camera;
10469
+ if (!lens.isPerspectiveCamera) return null;
10470
+ const tanV = Math.tan(lens.fov * Math.PI / 360);
10471
+ return { tanV, tanH: tanV * lens.aspect };
10472
+ };
10473
+ const placeElbowInView = (sign2, view) => {
10474
+ const way = rig.elbowView?.[sign2 === 1 ? 0 : 1];
10475
+ if (!way) return false;
10476
+ elbowAt.set(way[0], way[1], way[2]).setLength(rig.fore).add(wristAt);
10477
+ for (let pass = 0; pass < ELBOW_VIEW_PASSES; pass++) {
10478
+ const depth = Math.max(0.05, -elbowAt.z);
10479
+ const high = view.tanV * ELBOW_VIEW_MARGIN * depth;
10480
+ const wide = view.tanH * ELBOW_VIEW_MARGIN * depth;
10481
+ elbowAt.y = Math.max(elbowAt.y, -high);
10482
+ elbowAt.x = Math.min(wide, Math.max(-wide, elbowAt.x));
10483
+ elbowAt.sub(wristAt).setLength(rig.fore).add(wristAt);
10484
+ }
10485
+ shoulder.sub(elbowAt).setLength(rig.upper).add(elbowAt);
10486
+ return true;
10487
+ };
10488
+ const drawArm = (arm, pose, view) => {
9993
10489
  copyPose(arm.drawn, pose);
9994
10490
  const scale = pose.scale;
9995
10491
  fingers.set(1, 0, 0).applyQuaternion(pose.q);
9996
10492
  wristAt.copy(pose.p).addScaledVector(fingers, -rig.wrist * scale);
9997
10493
  shoulderOf(arm.sign, shoulder).add(bobOffset);
9998
- const excess = shoulder.distanceTo(wristAt) - (rig.upper + rig.fore) * REACH_SLACK;
10494
+ if (view && placeElbowInView(arm.sign, view)) {
10495
+ solveTwoBone(shoulder, wristAt, rig.upper, rig.fore, towards.copy(elbowAt).sub(shoulder).add(elbowAt).sub(wristAt), bone);
10496
+ finishArm(arm, pose, scale);
10497
+ return;
10498
+ }
10499
+ const excess = shoulder.distanceTo(wristAt) - reachOf(arm.sign);
9999
10500
  if (excess > 0 && rig.reachShift > 0) shoulder.addScaledVector(towards.subVectors(wristAt, shoulder).normalize(), Math.min(excess, rig.reachShift));
10000
10501
  solveTwoBone(shoulder, wristAt, rig.upper, rig.fore, poleOf(arm.sign), bone);
10502
+ finishArm(arm, pose, scale);
10503
+ };
10504
+ const finishArm = (arm, pose, scale) => {
10001
10505
  palmAt.copy(bone.end).addScaledVector(fingers, rig.wrist * scale);
10002
10506
  arm.drawn.p.copy(palmAt);
10003
10507
  arm.anchor.position.copy(palmAt);
@@ -10109,7 +10613,7 @@ var GameCharactersThree = (() => {
10109
10613
  dropped.p.y -= AWAY_DROP * ease2(arm.away);
10110
10614
  pose = dropped;
10111
10615
  }
10112
- drawArm(arm, pose);
10616
+ drawArm(arm, pose, mode === "target" && targets?.elbows !== "body" ? viewOf(state.camera) : null);
10113
10617
  const shown = arm.away < AWAY_HIDDEN;
10114
10618
  for (const part of [arm.anchor, arm.upper, arm.fore, arm.cuff, arm.elbow]) part.visible = shown;
10115
10619
  }
@@ -10151,237 +10655,6 @@ var GameCharactersThree = (() => {
10151
10655
  }
10152
10656
  };
10153
10657
  }
10154
-
10155
- // src/player/room-avatar.ts
10156
- var impactOf = (clip) => clip.events?.find((event) => event.type === "impact")?.t ?? null;
10157
- var isPunch = (clip) => clip.events?.some((event) => event.type === "impact" && event.data?.kind === "punch") ?? false;
10158
- var GUARD_SPEED = 0.3;
10159
- var toRoomAvatar = (avatar, options = {}) => {
10160
- const arms = options.firstPerson === false ? null : createFirstPersonArms(avatar.three, {
10161
- colors: { skin: avatar.colors.skin, sleeve: avatar.colors.longSleeves ? avatar.colors.shirt : avatar.colors.skin, trouser: avatar.colors.trousers, shoe: avatar.colors.shoes, ...options.firstPerson?.colors },
10162
- clips: options.firstPersonClips ?? FIRST_PERSON_CLIPS,
10163
- hideWhenIdle: true,
10164
- ...options.firstPerson
10165
- });
10166
- const strikes = new Map((options.strikeClips ?? ATTACK_CLIPS).map((clip) => [clip.id, clip]));
10167
- const mirrored = /* @__PURE__ */ new Map();
10168
- const leftOf = (clip) => {
10169
- let found = mirrored.get(clip.id);
10170
- if (!found) mirrored.set(clip.id, found = mirrorPoseClip(clip, `${clip.id}_left`));
10171
- return found;
10172
- };
10173
- const guard = options.guardClip === false ? void 0 : strikes.get(options.guardClip ?? "fight_guard");
10174
- const guardHold = options.guardHold ?? 1.2;
10175
- const punchBlend = options.punchBlend ?? 0.05;
10176
- let strikeLeft = 0;
10177
- let guardLeft = 0;
10178
- let guarding = false;
10179
- const stepGuard = (dt, state) => {
10180
- if (!guard) return;
10181
- const free = state.speed < GUARD_SPEED && !state.down && !state.armed && !state.holding && !state.push && !state.itemUse && !state.running;
10182
- if (strikeLeft > 0) {
10183
- strikeLeft -= dt;
10184
- if (strikeLeft <= 0 && guardLeft > 0 && free) {
10185
- avatar.play(guard);
10186
- guarding = true;
10187
- }
10188
- return;
10189
- }
10190
- guardLeft = Math.max(0, guardLeft - dt);
10191
- if (guarding && (guardLeft <= 0 || !free || avatar.playing !== guard.id)) {
10192
- if (avatar.playing === guard.id) avatar.stop();
10193
- guarding = false;
10194
- }
10195
- };
10196
- return {
10197
- root: avatar.root,
10198
- avatar,
10199
- arms,
10200
- ...arms ? { firstPerson: { root: arms.root, update: (dt, state) => arms.update(dt, state) } } : {},
10201
- update: (dt, state) => {
10202
- stepGuard(dt, state);
10203
- avatar.update(dt, {
10204
- speed: state.speed,
10205
- running: state.running,
10206
- crouch: state.crouch,
10207
- down: state.down,
10208
- armed: state.armed,
10209
- pitch: -state.pitch,
10210
- ...state.holding !== void 0 ? { holding: state.holding } : {},
10211
- ...state.itemUse !== void 0 ? { itemUse: state.itemUse } : {},
10212
- ...state.push !== void 0 ? { push: state.push } : {}
10213
- });
10214
- },
10215
- hand: (side) => avatar.hand(side),
10216
- reach: (targets) => avatar.reach(targets),
10217
- strike: (clipId, strikeOptions) => {
10218
- const clip = strikes.get(clipId);
10219
- if (!clip) return null;
10220
- const left = strikeOptions?.leg === "left" || strikeOptions?.hand === "left";
10221
- const punch = guard !== void 0 && isPunch(clip);
10222
- avatar.play(left ? leftOf(clip) : clip, punch ? { blend: punchBlend } : void 0);
10223
- strikeLeft = punch ? clip.duration : 0;
10224
- guardLeft = punch ? guardHold : 0;
10225
- guarding = false;
10226
- arms?.play(clipId, strikeOptions?.leg === "left" ? { leg: "left" } : strikeOptions?.hand === "left" ? { hand: "left" } : void 0);
10227
- return impactOf(clip);
10228
- }
10229
- };
10230
- };
10231
-
10232
- // src/player/test-text.ts
10233
- var AVATAR_TEXT = {
10234
- en: {
10235
- group: "Avatar",
10236
- name: "Player body",
10237
- actions: {
10238
- camera_first: "Camera: 1st person",
10239
- camera_third: "Camera: 3rd person",
10240
- crouch: "Crouch",
10241
- stand: "Stand up",
10242
- fall: "Fall down",
10243
- get_up: "Get up",
10244
- armed_on: "Armed: on",
10245
- armed_off: "Armed: off",
10246
- stop_clip: "Stop clip"
10247
- },
10248
- play: "Play",
10249
- metrics: { camera: "Camera", clip: "Clip playing", last_event: "Last clip event", state: "State", joints: "Joints" },
10250
- none: "none"
10251
- },
10252
- "pt-BR": {
10253
- group: "Avatar",
10254
- name: "Corpo do jogador",
10255
- actions: {
10256
- camera_first: "C\xE2mera: 1\xAA pessoa",
10257
- camera_third: "C\xE2mera: 3\xAA pessoa",
10258
- crouch: "Agachar",
10259
- stand: "Levantar",
10260
- fall: "Cair",
10261
- get_up: "Levantar do ch\xE3o",
10262
- armed_on: "Armado: ligado",
10263
- armed_off: "Armado: desligado",
10264
- stop_clip: "Parar clipe"
10265
- },
10266
- play: "Tocar",
10267
- metrics: { camera: "C\xE2mera", clip: "Clipe tocando", last_event: "\xDAltimo evento do clipe", state: "Estado", joints: "Juntas" },
10268
- none: "nenhum"
10269
- }
10270
- };
10271
-
10272
- // src/player/test-module.ts
10273
- var AVATAR_AREA_ID = "avatar_area";
10274
- var round = (value) => (Math.round(value * 100) / 100).toString();
10275
- function createAvatarTestModule(options) {
10276
- const clips = options.clips ?? POSE_CLIPS;
10277
- const textOf = (locale) => AVATAR_TEXT[locale ?? options.locale ?? "pt-BR"] ?? AVATAR_TEXT["pt-BR"];
10278
- const phaseLabel = (label, locale) => {
10279
- const id = locale ?? options.locale ?? "pt-BR";
10280
- const table = { ...POSE_CLIP_LOCALES[id] ?? POSE_CLIP_LOCALES["pt-BR"], ...options.clipLocales?.[id] ?? options.clipLocales?.["pt-BR"] };
10281
- return typeof label === "string" ? table[label] ?? label : "";
10282
- };
10283
- const state = { crouch: false, down: false, armed: null };
10284
- let host = null;
10285
- let lastEvent = "";
10286
- const log = (action, extra = {}) => {
10287
- const entry = { type: "avatar", action, ...extra };
10288
- host?.log(JSON.stringify(entry), entry);
10289
- };
10290
- const push = (action, patch, extra = {}) => {
10291
- Object.assign(state, patch);
10292
- options.state?.set(patch);
10293
- log(action, { crouch: state.crouch, down: state.down, armed: state.armed, ...extra });
10294
- };
10295
- const setCamera = (mode) => {
10296
- options.camera?.set(mode);
10297
- log(`camera_${mode}`, { mode: options.camera?.mode() ?? null });
10298
- };
10299
- const onChange = (change) => {
10300
- if (change.kind !== "action") return;
10301
- switch (change.id) {
10302
- case "camera_first":
10303
- return setCamera("first");
10304
- case "camera_third":
10305
- return setCamera("third");
10306
- case "crouch":
10307
- return push("crouch", { crouch: true });
10308
- case "stand":
10309
- return push("stand", { crouch: false });
10310
- case "fall":
10311
- return push("fall", { down: true });
10312
- case "get_up":
10313
- return push("get_up", { down: false });
10314
- case "armed_on":
10315
- return push("armed_on", { armed: true });
10316
- case "armed_off":
10317
- return push("armed_off", { armed: false });
10318
- case "stop_clip":
10319
- options.avatar.stop();
10320
- return log("stop_clip", { playing: options.avatar.playing });
10321
- default: {
10322
- const clip = clips.find((item) => `play_${item.id}` === change.id);
10323
- if (!clip) return;
10324
- options.avatar.play(clip);
10325
- log("play_clip", { clip: clip.id, duration: clip.duration, loop: clip.loop ?? false, channels: clip.channels ?? "full" });
10326
- }
10327
- }
10328
- };
10329
- const joints = () => {
10330
- const rig = options.avatar.rig;
10331
- const [armA, armB] = rig.arms;
10332
- const [legA, legB] = rig.legs;
10333
- return `arms ${round(armA.g.rotation.x)}/${round(armB.g.rotation.x)} elbows ${round(armA.el.rotation.x)}/${round(armB.el.rotation.x)} legs ${round(legA.g.rotation.x)}/${round(legB.g.rotation.x)} knees ${round(legA.kn.rotation.x)}/${round(legB.kn.rotation.x)} lean ${round(rig.upper.rotation.x)}`;
10334
- };
10335
- return {
10336
- id: AVATAR_AREA_ID,
10337
- name: textOf().name,
10338
- ground: { surface: "concrete_slab" },
10339
- group: textOf().group,
10340
- state,
10341
- items: () => [],
10342
- area: () => ({ placements: [], view: { eye: [0, 1.7, 6], target: [0, 1.2, 0] } }),
10343
- controls: (locale) => {
10344
- const text = textOf(locale);
10345
- const action = (id, name, hint) => ({ kind: "action", id, name, ...hint ? { hint } : {} });
10346
- return [
10347
- action("camera_first", text.actions.camera_first),
10348
- action("camera_third", text.actions.camera_third),
10349
- action("crouch", text.actions.crouch),
10350
- action("stand", text.actions.stand),
10351
- action("fall", text.actions.fall),
10352
- action("get_up", text.actions.get_up),
10353
- action("armed_on", text.actions.armed_on),
10354
- action("armed_off", text.actions.armed_off),
10355
- ...clips.map((clip) => action(`play_${clip.id}`, `${text.play}: ${clip.id}`)),
10356
- action("stop_clip", text.actions.stop_clip)
10357
- ];
10358
- },
10359
- metrics: (locale) => {
10360
- const text = textOf(locale);
10361
- return [
10362
- { id: "camera", name: text.metrics.camera, read: () => options.camera?.mode() ?? text.none },
10363
- { id: "clip", name: text.metrics.clip, read: () => options.avatar.playing ?? text.none },
10364
- { id: "last_event", name: text.metrics.last_event, read: () => lastEvent || text.none },
10365
- { id: "state", name: text.metrics.state, read: () => `${state.crouch ? "crouch " : ""}${state.down ? "down " : ""}${state.armed === null ? "" : state.armed ? "armed" : "unarmed"}`.trim() || text.none },
10366
- { id: "joints", name: text.metrics.joints, read: joints }
10367
- ];
10368
- },
10369
- attach(lent) {
10370
- host = lent;
10371
- const stopChange = lent.bench?.onChange(onChange);
10372
- const stopEvents = options.avatar.on("event", (event) => {
10373
- lastEvent = `${event.clip} ${event.type} ${round(event.t)}s${event.data && "label" in event.data ? ` ${phaseLabel(event.data.label)}` : ""}`;
10374
- log("clip_event", { clip: event.clip, event: event.type, t: event.t, data: event.data ?? null });
10375
- if (event.type === "impact") log("impact", { clip: event.clip, t: event.t, kind: event.data?.kind ?? null });
10376
- });
10377
- return () => {
10378
- stopChange?.();
10379
- stopEvents();
10380
- host = null;
10381
- };
10382
- }
10383
- };
10384
- }
10385
10658
  return __toCommonJS(index_exports);
10386
10659
  })();
10387
10660
  //# sourceMappingURL=index.global.js.map