@minicode-dev/chat 0.1.15 → 0.1.17

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.
Files changed (58) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +2 -0
  3. package/dist/chunks/{BattleshipGameCard-8H-sBCsv.js → BattleshipGameCard-DwNzgH5G.js} +199 -199
  4. package/dist/chunks/{BattleshipGameCard-8H-sBCsv.js.map → BattleshipGameCard-DwNzgH5G.js.map} +1 -1
  5. package/dist/chunks/{BattleshipPrototype-CmQd5AUO.js → BattleshipPrototype-CSQxQJt5.js} +52 -52
  6. package/dist/chunks/{BattleshipPrototype-CmQd5AUO.js.map → BattleshipPrototype-CSQxQJt5.js.map} +1 -1
  7. package/dist/chunks/{ChatContext-CVW58bzC.js → ChatContext-D5rqvt5D.js} +2 -2
  8. package/dist/chunks/{ChatContext-CVW58bzC.js.map → ChatContext-D5rqvt5D.js.map} +1 -1
  9. package/dist/chunks/RacingLiveGameCard-_wvhDRlG.js +1873 -0
  10. package/dist/chunks/RacingLiveGameCard-_wvhDRlG.js.map +1 -0
  11. package/dist/chunks/{TanksGameCard-DnCufSH6.js → TanksGameCard-B-gtDYYg.js} +137 -137
  12. package/dist/chunks/{TanksGameCard-DnCufSH6.js.map → TanksGameCard-B-gtDYYg.js.map} +1 -1
  13. package/dist/chunks/{TanksLiveGameCard-D_27Jomp.js → TanksLiveGameCard-DXgd1J2Y.js} +392 -392
  14. package/dist/chunks/{TanksLiveGameCard-D_27Jomp.js.map → TanksLiveGameCard-DXgd1J2Y.js.map} +1 -1
  15. package/dist/chunks/{avalancheScene3d-CIE2WKQn.js → avalancheScene3d-CNbQyGUd.js} +2 -2
  16. package/dist/chunks/{avalancheScene3d-CIE2WKQn.js.map → avalancheScene3d-CNbQyGUd.js.map} +1 -1
  17. package/dist/chunks/{connect4Sounds-BqEHULjv.js → connect4Sounds-3a6h7gUC.js} +8 -8
  18. package/dist/chunks/{connect4Sounds-BqEHULjv.js.map → connect4Sounds-3a6h7gUC.js.map} +1 -1
  19. package/dist/chunks/createLiveScene-jrzyQogh.js +756 -0
  20. package/dist/chunks/{createLiveScene-MTGRv8rx.js.map → createLiveScene-jrzyQogh.js.map} +1 -1
  21. package/dist/chunks/createRaceScene-C-aw0dlX.js +291 -0
  22. package/dist/chunks/createRaceScene-C-aw0dlX.js.map +1 -0
  23. package/dist/chunks/{createTankScene-yhX6la27.js → createTankScene-6asWHKFf.js} +123 -125
  24. package/dist/chunks/{createTankScene-yhX6la27.js.map → createTankScene-6asWHKFf.js.map} +1 -1
  25. package/dist/chunks/fx-BNJvJYOu.js +871 -0
  26. package/dist/chunks/fx-BNJvJYOu.js.map +1 -0
  27. package/dist/chunks/{games-Bl_8raG6.js → games-D_9SiSBT.js} +708 -697
  28. package/dist/chunks/games-D_9SiSBT.js.map +1 -0
  29. package/dist/chunks/tank-DIn6Jyt8.js +605 -0
  30. package/dist/chunks/tank-DIn6Jyt8.js.map +1 -0
  31. package/dist/chunks/{tanks-live-BcKmrhnV.js → tanks-live-BRhYW4MG.js} +36 -36
  32. package/dist/chunks/{tanks-live-BcKmrhnV.js.map → tanks-live-BRhYW4MG.js.map} +1 -1
  33. package/dist/chunks/{tanksSounds-DTnidbiq.js → tanksSounds-tYPzje61.js} +4 -4
  34. package/dist/chunks/{tanksSounds-DTnidbiq.js.map → tanksSounds-tYPzje61.js.map} +1 -1
  35. package/dist/chunks/track-C1TWWT19.js +557 -0
  36. package/dist/chunks/track-C1TWWT19.js.map +1 -0
  37. package/dist/index.js +4236 -4020
  38. package/dist/index.js.map +1 -1
  39. package/dist/styles.css +1 -1
  40. package/index.d.ts +3 -1
  41. package/package.json +1 -1
  42. package/dist/chunks/RacingLiveGameCard-8j9QLnxW.js +0 -1654
  43. package/dist/chunks/RacingLiveGameCard-8j9QLnxW.js.map +0 -1
  44. package/dist/chunks/createLiveScene-MTGRv8rx.js +0 -758
  45. package/dist/chunks/createRaceScene-BiEtQsVs.js +0 -306
  46. package/dist/chunks/createRaceScene-BiEtQsVs.js.map +0 -1
  47. package/dist/chunks/decor-CyyCnmct.js +0 -418
  48. package/dist/chunks/decor-CyyCnmct.js.map +0 -1
  49. package/dist/chunks/fx-1ZwzmPWj.js +0 -458
  50. package/dist/chunks/fx-1ZwzmPWj.js.map +0 -1
  51. package/dist/chunks/games-Bl_8raG6.js.map +0 -1
  52. package/dist/chunks/rolldown-runtime-CGnMp29N.js +0 -10
  53. package/dist/chunks/tank-DjEQ4FXF.js +0 -553
  54. package/dist/chunks/tank-DjEQ4FXF.js.map +0 -1
  55. package/dist/chunks/track-BcnnpnAm.js +0 -259
  56. package/dist/chunks/track-BcnnpnAm.js.map +0 -1
  57. package/dist/chunks/util-DwI9bfS7.js +0 -57
  58. package/dist/chunks/util-DwI9bfS7.js.map +0 -1
@@ -0,0 +1,1873 @@
1
+ import { a as e, t } from "./games-D_9SiSBT.js";
2
+ import { a as n, d as r, f as i, n as a, o, t as s, u as c } from "./track-C1TWWT19.js";
3
+ import { n as l, o as u, s as d } from "./createPeerLink-DBVs_yvQ.js";
4
+ import { i as f, o as p, t as m } from "./ChatContext-D5rqvt5D.js";
5
+ import { c as h, l as g } from "./gameStatus-BChd29yI.js";
6
+ import { n as _, r as v, t as y } from "./tanks-live-BRhYW4MG.js";
7
+ import { memo as b, useContext as x, useEffect as S, useRef as C, useState as w } from "react";
8
+ import { Fragment as ee, jsx as T, jsxs as E } from "react/jsx-runtime";
9
+ import { AlertTriangle as D, Link2 as te, Loader2 as O, Settings2 as k, Volume2 as A, VolumeX as j } from "lucide-react";
10
+ // \0rolldown/runtime.js
11
+ var M = Object.defineProperty, N = (e, t) => {
12
+ let n = {};
13
+ for (var r in e) M(n, r, {
14
+ get: e[r],
15
+ enumerable: !0
16
+ });
17
+ return t || M(n, Symbol.toStringTag, { value: "Module" }), n;
18
+ }, ne = 1 / 60, P = 1.2, F = Object.freeze({
19
+ maxSpeed: 35,
20
+ reverseSpeed: 10,
21
+ acceleration: 14,
22
+ braking: 24,
23
+ rollingDrag: .7,
24
+ airDrag: .009,
25
+ lateralGrip: 10,
26
+ driftGrip: 2.5,
27
+ steeringRate: 1.65,
28
+ grassDrag: 4,
29
+ barrierMargin: 3,
30
+ barrierBounce: .22
31
+ }), I = (e, t, n) => Math.max(t, Math.min(n, e)), L = (e, t = 0) => Number.isFinite(e) ? e : t, R = (e) => Math.atan2(Math.sin(e), Math.cos(e));
32
+ function z(e, t, n, r) {
33
+ for (let i of n || []) {
34
+ if (!i || ![
35
+ i.x,
36
+ i.z,
37
+ i.radius
38
+ ].every(Number.isFinite) || i.radius <= 0) continue;
39
+ let n = i.radius + P, a = t.x - i.x, o = t.z - i.z, s = e.x - t.x, c = e.z - t.z, l = a * a + o * o - n * n, u = null;
40
+ if (l < 0) u = 0;
41
+ else {
42
+ let e = s * s + c * c, t = 2 * (a * s + o * c), n = t * t - 4 * e * l;
43
+ if (e > 1e-12 && t < 0 && n >= 0) {
44
+ let r = (-t - Math.sqrt(n)) / (2 * e);
45
+ r >= 0 && r <= 1 && (u = r);
46
+ }
47
+ }
48
+ if (u === null) continue;
49
+ let d = t.x + s * u - i.x, f = t.z + c * u - i.z, p = Math.hypot(d, f);
50
+ p < 1e-9 && (d = -e.vx, f = -e.vz, p = Math.hypot(d, f), p < 1e-9 && (d = 1, f = 0, p = 1)), d /= p, f /= p, e.x = i.x + d * (n + .001), e.z = i.z + f * (n + .001);
51
+ let m = e.vx * d + e.vz * f;
52
+ m < 0 && (e.vx -= (1 + r) * m * d, e.vz -= (1 + r) * m * f);
53
+ }
54
+ }
55
+ function re({ x: e = 0, z: t = 0, heading: n = 0 } = {}) {
56
+ return {
57
+ x: L(e),
58
+ z: L(t),
59
+ heading: R(L(n)),
60
+ vx: 0,
61
+ vz: 0,
62
+ speed: 0
63
+ };
64
+ }
65
+ function ie(e, t = {}, n = ne, r, i = F) {
66
+ let o = i || F;
67
+ if (!Number.isFinite(n) || n <= 0 || n > .1) throw RangeError("Car dt must be in (0, 0.1] seconds");
68
+ if (!e || ![
69
+ "x",
70
+ "z",
71
+ "heading",
72
+ "vx",
73
+ "vz"
74
+ ].every((t) => Number.isFinite(e[t]))) throw TypeError("Car state requires finite x, z, heading, vx and vz");
75
+ let s = I(L(t.throttle, +!!t.accelerate), -1, 1), c = I(L(t.brake), 0, 1), l = I(L(t.steer), -1, 1), u = !!t.handbrake, d = { ...e }, f = Math.ceil(n / (1 / 120)), p = n / f;
76
+ for (let e = 0; e < f; e++) {
77
+ let e = Math.sin(d.heading), t = Math.cos(d.heading), n = d.vx * e + d.vz * t, i = Math.min(Math.abs(n) / 8, 1), f = o.steerFalloffSpeed > 0 ? 1 / (1 + (n / o.steerFalloffSpeed) ** 2) : 1;
78
+ d.heading = R(d.heading + l * o.steeringRate * i * f * Math.sign(n) * p), e = Math.sin(d.heading), t = Math.cos(d.heading), n = d.vx * e + d.vz * t;
79
+ let m = d.vx * t - d.vz * e, h = s * o.acceleration;
80
+ c > 0 && (h -= c * (n > .2 ? o.braking : o.acceleration * .7));
81
+ let g = r ? a(r, d) : null, _ = g ? g.distance > r.width / 2 : !1, v = o.rollingDrag + (_ ? o.grassDrag : 0) + (u ? 1.7 : 0);
82
+ n += h * p, n /= 1 + (v + o.airDrag * Math.abs(n)) * p, n = I(n, -o.reverseSpeed, o.maxSpeed), m *= Math.exp(-(u ? o.driftGrip : o.lateralGrip) * p), d.vx = e * n + t * m, d.vz = t * n - e * m;
83
+ let y = {
84
+ x: d.x,
85
+ z: d.z
86
+ };
87
+ if (d.x += d.vx * p, d.z += d.vz * p, r) {
88
+ z(d, y, r.obstacles, o.barrierBounce);
89
+ let e = a(r, d), t = r.width / 2 + L(r.barrierMargin, o.barrierMargin);
90
+ if (e.distance > t) {
91
+ let n = (d.x - e.point.x) / e.distance, r = (d.z - e.point.z) / e.distance;
92
+ d.x = e.point.x + n * t, d.z = e.point.z + r * t;
93
+ let i = d.vx * n + d.vz * r;
94
+ i > 0 && (d.vx -= (1 + o.barrierBounce) * i * n, d.vz -= (1 + o.barrierBounce) * i * r);
95
+ }
96
+ }
97
+ }
98
+ return d.speed = d.vx * Math.sin(d.heading) + d.vz * Math.cos(d.heading), d;
99
+ }
100
+ function ae(e, t, n, { maxLag: r = .25, positionTolerance: i = 1, accelerationTolerance: a = 3, rules: o = F } = {}) {
101
+ let s = o || F;
102
+ if (!e || !t || !Number.isFinite(n) || n <= 0 || n > 1 || ![e, t].every((e) => [
103
+ "x",
104
+ "z",
105
+ "heading",
106
+ "vx",
107
+ "vz",
108
+ "seq"
109
+ ].every((t) => Number.isFinite(e[t]))) || !Number.isSafeInteger(t.seq) || !Number.isSafeInteger(e.seq) || t.seq <= e.seq || t.seq < 0) return !1;
110
+ let c = I(L(r), 0, .25), l = I(L(i), 0, 2), u = I(L(a), 0, 5), d = Math.hypot(t.vx, t.vz);
111
+ if (d > s.maxSpeed + 1) return !1;
112
+ let f = n + c;
113
+ if (Math.hypot(t.x - e.x, t.z - e.z) > s.maxSpeed * f + l) return !1;
114
+ let p = Math.hypot(e.vx, e.vz);
115
+ return !(p > s.maxSpeed + 1 || Math.hypot(t.x - e.x, t.z - e.z) > Math.max(p, d) * f + .5 * s.acceleration * f * f + l || t.vx * Math.sin(t.heading) + t.vz * Math.cos(t.heading) < -s.reverseSpeed - 1 || d - p > s.acceleration * f + u);
116
+ }
117
+ // src/games/racing-live/logic/progress.js
118
+ function oe({ laps: e = 3, startTimeMs: t = 0 } = {}) {
119
+ if (!Number.isInteger(e) || e < 1 || e > 99 || !Number.isFinite(t) || t < 0) throw RangeError("Invalid race progress configuration");
120
+ return {
121
+ laps: e,
122
+ completedLaps: 0,
123
+ nextCheckpoint: 1,
124
+ startedAtMs: t,
125
+ lastSampleAtMs: t,
126
+ lapStartedAtMs: t,
127
+ lapTimesMs: [],
128
+ finishedAtMs: null
129
+ };
130
+ }
131
+ var B = (e) => Number.isFinite(e?.x) && Number.isFinite(e?.z);
132
+ function V(e, t, n) {
133
+ if (!B(e) || !B(t) || !B(n?.center) || !B(n?.normal) || !Number.isFinite(n.halfWidth) || n.halfWidth <= 0) return null;
134
+ let { center: r, normal: i, halfWidth: a } = n, o = Math.hypot(i.x, i.z);
135
+ if (o < 1e-4) return null;
136
+ let s = i.x / o, c = i.z / o, l = (e.x - r.x) * s + (e.z - r.z) * c, u = (t.x - r.x) * s + (t.z - r.z) * c;
137
+ if (l >= 0 || u < 0) return null;
138
+ let d = -l / (u - l), f = e.x + (t.x - e.x) * d - r.x, p = e.z + (t.z - e.z) * d - r.z;
139
+ return Math.abs(-f * c + p * s) <= a ? d : null;
140
+ }
141
+ function se(e, t, n, r, { nowMs: i, maxSegmentDistance: a = 12 } = {}) {
142
+ let o = (t) => ({
143
+ progress: e,
144
+ event: null,
145
+ accepted: !1,
146
+ reason: t
147
+ });
148
+ if (e.finishedAtMs !== null) return o("finished");
149
+ if (!B(t) || !B(n) || !Number.isFinite(i) || i <= e.lastSampleAtMs) return o("invalid_sample");
150
+ if (!Number.isFinite(a) || a <= 0 || Math.hypot(n.x - t.x, n.z - t.z) > a) return o("segment_too_long");
151
+ let s = r?.checkpoints;
152
+ if (!Array.isArray(s) || s.length !== 4) return o("invalid_track");
153
+ let c = e.nextCheckpoint, l = V(t, n, s[c]), u = {
154
+ ...e,
155
+ lastSampleAtMs: i
156
+ };
157
+ if (l === null) return {
158
+ progress: u,
159
+ event: null,
160
+ accepted: !0,
161
+ reason: null
162
+ };
163
+ let d = e.lastSampleAtMs + l * (i - e.lastSampleAtMs);
164
+ return c === 0 ? (u.completedLaps += 1, u.nextCheckpoint = 1, u.lapTimesMs = [...e.lapTimesMs, d - e.lapStartedAtMs], u.lapStartedAtMs = d, u.completedLaps === u.laps && (u.finishedAtMs = d), {
165
+ progress: u,
166
+ event: {
167
+ type: u.finishedAtMs === null ? "lap" : "finish",
168
+ lap: u.completedLaps,
169
+ atMs: d
170
+ },
171
+ accepted: !0,
172
+ reason: null
173
+ }) : (u.nextCheckpoint = (c + 1) % s.length, {
174
+ progress: u,
175
+ event: {
176
+ type: "checkpoint",
177
+ checkpoint: c,
178
+ atMs: d
179
+ },
180
+ accepted: !0,
181
+ reason: null
182
+ });
183
+ }
184
+ // src/games/racing-live/net/raceInterpolation.js
185
+ var ce = (e) => Math.atan2(Math.sin(e), Math.cos(e));
186
+ function le(e = 32) {
187
+ let t = [];
188
+ return {
189
+ push(n, r) {
190
+ t.push({
191
+ time: n,
192
+ pose: r
193
+ }), t.length > e && t.shift();
194
+ },
195
+ clear() {
196
+ t = [];
197
+ },
198
+ get size() {
199
+ return t.length;
200
+ },
201
+ sample(e, n = 100) {
202
+ if (!t.length) return null;
203
+ let r = e - n;
204
+ for (; t.length > 2 && t[1].time <= r;) t.shift();
205
+ let i = t[0], a = t[1];
206
+ if (!a || r >= a.time) {
207
+ let e = a || i, t = Math.min(Math.max(0, r - e.time), 150) / 1e3, n = e.pose;
208
+ return {
209
+ ...n,
210
+ x: n.x + (n.vx || 0) * t,
211
+ z: n.z + (n.vz || 0) * t
212
+ };
213
+ }
214
+ if (r <= i.time) return { ...i.pose };
215
+ let o = (r - i.time) / (a.time - i.time);
216
+ return {
217
+ ...a.pose,
218
+ x: i.pose.x + (a.pose.x - i.pose.x) * o,
219
+ z: i.pose.z + (a.pose.z - i.pose.z) * o,
220
+ heading: ce(i.pose.heading + ce(a.pose.heading - i.pose.heading) * o),
221
+ speed: i.pose.speed + (a.pose.speed - i.pose.speed) * o
222
+ };
223
+ }
224
+ };
225
+ }
226
+ // src/games/racing-live/net/createRaceMatch.js
227
+ var H = 3e3, ue = 3e3, de = Object.freeze(["#ff3b5c", "#2fb7ff"]), fe = 1.2, pe = 5, U = (e) => typeof e == "number" && Number.isFinite(e), me = (e, t, n) => Number.isInteger(e) && e >= t && e <= n, he = ["countdown", "racing"];
228
+ function W(e) {
229
+ if (!e || typeof e != "object") return null;
230
+ let { x: t, z: n, heading: r, vx: i, vz: a, speed: o, seq: s } = e;
231
+ return ![
232
+ t,
233
+ n,
234
+ r,
235
+ i,
236
+ a,
237
+ o
238
+ ].every(U) || !Number.isSafeInteger(s) || s < 0 || Math.abs(t) > 1e4 || Math.abs(n) > 1e4 || Math.abs(r) > 100 ? null : {
239
+ x: t,
240
+ z: n,
241
+ heading: r,
242
+ vx: i,
243
+ vz: a,
244
+ speed: o,
245
+ seq: s
246
+ };
247
+ }
248
+ function ge({ game: e, selfId: t, isHost: n = String(t) === String(e.hostId), signaling: r, onChange: o = () => {}, peerFactory: f = l, iceServers: p, iceTransportPolicy: m, RTCPeerConnectionImpl: h } = {}) {
249
+ t = String(t);
250
+ let g = [String(e.hostId), String(e.guestId)];
251
+ if (!g.includes(t) || g[0] === g[1]) throw Error("Invalid race match players");
252
+ let _ = g.find((e) => e !== t), v = e.raceConfig || {}, y = i(v.speedClass), b = y ? y.rules : F, x = me(v.laps, 1, 99) ? v.laps : y ? y.laps : c.laps, S = s(v.mapId || "neon_city", v.seed ?? 0, {
253
+ speedClass: y?.id,
254
+ trackId: v.trackId
255
+ }), C = y ? y.topKmh / 3.6 : 16.5, w = v.trackHash && v.trackHash !== S.trackHash ? "track_mismatch" : null, ee = (p || []).some((e) => [e.urls].flat().some((e) => /^turns?:/i.test(String(e)))), T = (e) => S.grid[g.indexOf(e)], E = "connecting", D = null, te = null, O = null, k = null, A = 0, j = 0, M = 0, N = 0, I = 0, L = {}, R = re(T(t)), z = { ...re(T(_)) }, B = {}, V = null, ce = null, ge = [], G = !1, K = {
256
+ phase: "idle",
257
+ rtt: null,
258
+ route: null
259
+ }, _e = !1, ve = -Infinity, q = null, J = null, ye = 0, be = 0, xe = {
260
+ accepted: 0,
261
+ rejected: 0
262
+ }, Se = le(), Y = () => {
263
+ G || o({
264
+ status: E,
265
+ phase: E,
266
+ winner: V,
267
+ net: K
268
+ });
269
+ }, X = (e) => {
270
+ ge.push(e), ge.length > 200 && ge.shift();
271
+ }, Z = (t) => Q.sendEvent({
272
+ ...t,
273
+ g: e.gameId
274
+ }), Ce = () => Math.min(250, Math.max(0, (Number(K.rtt) || 0) / 2)), we = () => {
275
+ B = Object.fromEntries(g.map((e) => [e, oe({
276
+ laps: x,
277
+ startTimeMs: 0
278
+ })]));
279
+ }, Te = () => Object.fromEntries(g.map((e) => {
280
+ let t = B[e];
281
+ return [e, t ? {
282
+ lap: t.completedLaps,
283
+ cp: t.nextCheckpoint,
284
+ lapTimes: t.lapTimesMs,
285
+ fin: t.finishedAtMs
286
+ } : null];
287
+ }));
288
+ we();
289
+ function Ee() {
290
+ R = re(T(t)), z = re(T(_)), Se.clear(), q = {
291
+ ...re(T(_)),
292
+ seq: -1
293
+ }, J = null, ye = 0, be = 0, j = 0, M = 0, we();
294
+ }
295
+ function De(e) {
296
+ Ee(), E = "countdown", te = A + Math.max(0, e), k = null, D = null, O = null, Y();
297
+ }
298
+ function Oe() {
299
+ he.includes(E) && (D = E, E = "paused", O = null, M = 0, X({ type: "pause" }), Y());
300
+ }
301
+ function ke(e, n) {
302
+ E !== "finished" && (E = "finished", V = e, ce = n, Q.clearManualTurn?.(), X({
303
+ type: "result",
304
+ winner: V,
305
+ reason: n,
306
+ self: V === t
307
+ }), Y());
308
+ }
309
+ function Ae(e, n) {
310
+ let r = n.event;
311
+ if (!r) return;
312
+ let i = e === t;
313
+ X({
314
+ type: r.type,
315
+ id: e,
316
+ self: i,
317
+ lap: r.lap,
318
+ checkpoint: r.checkpoint,
319
+ atMs: r.atMs
320
+ }), r.type === "lap" && r.lap === x - 1 && X({
321
+ type: "final_lap",
322
+ id: e,
323
+ self: i
324
+ });
325
+ }
326
+ function je(e, t) {
327
+ if (B[e] = t.progress, !t.event) return;
328
+ Ae(e, t);
329
+ let n = t.progress;
330
+ Z({
331
+ k: "progress",
332
+ id: e,
333
+ lap: n.completedLaps,
334
+ cp: n.nextCheckpoint,
335
+ lapTimes: n.lapTimesMs,
336
+ fin: n.finishedAtMs,
337
+ t: j,
338
+ ev: t.event
339
+ }), t.event.type === "finish" && !V && (Z({
340
+ k: "result",
341
+ winner: e,
342
+ reason: "finish",
343
+ times: Object.fromEntries(g.map((e) => [e, B[e].finishedAtMs]))
344
+ }), ke(e, "finish"));
345
+ }
346
+ function Me() {
347
+ E === "finished" ? Z({
348
+ k: "result",
349
+ winner: V,
350
+ reason: ce
351
+ }) : E !== "connecting" && E !== "ready" && (E === "countdown" || D === "countdown" ? (De(H), Z({
352
+ k: "start",
353
+ inMs: H
354
+ })) : (E === "racing" && Oe(), O = A + ue, Z({
355
+ k: "resume",
356
+ inMs: ue,
357
+ t: j,
358
+ progress: Te(),
359
+ pose: q && {
360
+ x: q.x,
361
+ z: q.z,
362
+ heading: q.heading
363
+ }
364
+ }), Y()));
365
+ }
366
+ function Ne(t) {
367
+ if (G || t?.g !== e.gameId) return;
368
+ let r = W(t);
369
+ if (!r) return;
370
+ if (!n) {
371
+ E !== "paused" && Se.push(A, r);
372
+ return;
373
+ }
374
+ if (!he.includes(E) || r.seq <= q.seq) return;
375
+ let i = J === null ? .1 : (A - J) / 1e3, a = Math.hypot(r.x - q.x, r.z - q.z), o;
376
+ if (E === "countdown") {
377
+ let e = T(_);
378
+ o = Math.hypot(r.x - e.x, r.z - e.z) <= 1.5 && Math.hypot(r.vx, r.vz) < 1;
379
+ } else o = i > .9 ? a <= b.maxSpeed * i + 2 && Math.hypot(r.vx, r.vz) <= b.maxSpeed + 1 : ae(q, r, Math.max(i, .01), { rules: b });
380
+ if (o && E === "racing") {
381
+ let e = r.x - q.x, t = r.z - q.z, n = e * e + t * t;
382
+ for (let i of S.obstacles || []) {
383
+ let a = Math.max(0, i.radius + P - .25), s = Math.hypot(q.x - i.x, q.z - i.z), c = Math.hypot(r.x - i.x, r.z - i.z);
384
+ if (s < a && c > s) continue;
385
+ let l = n ? Math.max(0, Math.min(1, ((i.x - q.x) * e + (i.z - q.z) * t) / n)) : 0;
386
+ if (Math.hypot(q.x + e * l - i.x, q.z + t * l - i.z) < a) {
387
+ o = !1;
388
+ break;
389
+ }
390
+ }
391
+ }
392
+ if (o && E === "racing" && (o = ye + a <= b.maxSpeed * (j / 1e3 + 1) + 10), o && E === "racing") {
393
+ let e = Math.max(j, B[_].lastSampleAtMs + .01), t = se(B[_], q, r, S, {
394
+ nowMs: e,
395
+ maxSegmentDistance: Math.max(12, b.maxSpeed * i + 2)
396
+ });
397
+ !t.accepted && t.reason !== "finished" ? o = !1 : je(_, t);
398
+ }
399
+ o ? (E === "racing" && (ye += a), be = 0, xe.accepted++, q = r, J = A, Se.push(A, r)) : (xe.rejected++, ++be >= pe && (be = 0, Z({
400
+ k: "correct",
401
+ x: q.x,
402
+ z: q.z,
403
+ heading: q.heading
404
+ })));
405
+ }
406
+ function Pe(r) {
407
+ if (!G && r && r.g === e.gameId && typeof r.k == "string") {
408
+ if (r.k === "resign") {
409
+ if (E === "finished") return;
410
+ ke(t, "resigned"), n && Z({
411
+ k: "result",
412
+ winner: t,
413
+ reason: "resigned"
414
+ });
415
+ } else if (n) {
416
+ if (r.k === "ready") {
417
+ if (r.hash !== S.trackHash || w) {
418
+ K = {
419
+ ...K,
420
+ error: "track_mismatch"
421
+ }, Y();
422
+ return;
423
+ }
424
+ (E === "connecting" || E === "ready") && (De(H), Z({
425
+ k: "start",
426
+ inMs: H,
427
+ hash: S.trackHash
428
+ }));
429
+ return;
430
+ }
431
+ r.k === "sync" && Me();
432
+ } else if (r.k === "start" && me(r.inMs, 0, 1e4) && E !== "finished") De(r.inMs - Ce());
433
+ else if (r.k === "result" && g.includes(r.winner) && ["finish", "resigned"].includes(r.reason)) ke(r.winner, r.reason);
434
+ else if (E !== "finished") {
435
+ if (r.k === "pause") Oe();
436
+ else if (r.k === "resume" && me(r.inMs, 0, 1e4) && U(r.t) && r.t >= 0) {
437
+ if ((E === "racing" || E === "countdown") && Oe(), E !== "paused") return;
438
+ D = "racing", j = r.t, O = A + Math.max(0, r.inMs - Ce()), Fe(r.progress), r.pose && [
439
+ r.pose.x,
440
+ r.pose.z,
441
+ r.pose.heading
442
+ ].every(U) && Math.hypot(r.pose.x - R.x, r.pose.z - R.z) > 3 && (R = re(r.pose)), Y();
443
+ } else if (r.k === "correct" && [
444
+ r.x,
445
+ r.z,
446
+ r.heading
447
+ ].every(U)) R = re(r), X({ type: "correct" });
448
+ else if (r.k === "progress" && g.includes(r.id) && me(r.lap, 0, x) && me(r.cp, 0, 3) && Array.isArray(r.lapTimes) && r.lapTimes.length === r.lap && r.lapTimes.every(U)) {
449
+ let e = B[r.id];
450
+ B[r.id] = {
451
+ ...e,
452
+ completedLaps: r.lap,
453
+ nextCheckpoint: r.cp,
454
+ lapTimesMs: r.lapTimes,
455
+ finishedAtMs: U(r.fin) ? r.fin : null
456
+ }, r.ev && [
457
+ "checkpoint",
458
+ "lap",
459
+ "finish"
460
+ ].includes(r.ev.type) && Ae(r.id, { event: r.ev }), U(r.t) && E === "racing" && Math.abs(r.t + Ce() - j) > 250 && (j = r.t + Ce());
461
+ }
462
+ }
463
+ }
464
+ }
465
+ function Fe(e) {
466
+ if (e && typeof e == "object") for (let t of g) {
467
+ let n = e[t];
468
+ n && me(n.lap, 0, x) && me(n.cp, 0, 3) && Array.isArray(n.lapTimes) && n.lapTimes.every(U) && (B[t] = {
469
+ ...B[t],
470
+ completedLaps: n.lap,
471
+ nextCheckpoint: n.cp,
472
+ lapTimesMs: n.lapTimes,
473
+ finishedAtMs: U(n.fin) ? n.fin : null
474
+ });
475
+ }
476
+ }
477
+ let Q = f({
478
+ configurationAuthority: n,
479
+ signaling: r && {
480
+ send(t) {
481
+ let n = u(t);
482
+ if (!n) return Promise.reject(/* @__PURE__ */ Error("Invalid live signal"));
483
+ let i = d({
484
+ ...n,
485
+ liveGame: e.gameId
486
+ });
487
+ return i ? r.send(i) : Promise.reject(/* @__PURE__ */ Error("Live signal too large"));
488
+ },
489
+ subscribe(t) {
490
+ return r.subscribe((n) => {
491
+ u(n?.text)?.liveGame === e.gameId && t(n);
492
+ });
493
+ }
494
+ },
495
+ selfId: t,
496
+ peerId: _,
497
+ roomId: e.roomId,
498
+ iceServers: p,
499
+ iceTransportPolicy: m,
500
+ RTCPeerConnectionImpl: h,
501
+ onMove: Ne,
502
+ onEvent: Pe,
503
+ onChange(e) {
504
+ let t = K.phase;
505
+ K = e, e.phase === "connected" ? (E === "connecting" && (E = "ready"), t !== "connected" && queueMicrotask(() => {
506
+ G || (_e && Z({ k: "resign" }), n || (Z({
507
+ k: "ready",
508
+ hash: S.trackHash
509
+ }), Z({ k: "sync" })));
510
+ })) : he.includes(E) ? Oe() : E === "ready" && (E = "connecting"), Y();
511
+ }
512
+ });
513
+ n ? Q.connect() : Q.setListening(!0);
514
+ function Ie(e, t) {
515
+ let n = B[e];
516
+ if (n.finishedAtMs !== null) return 1e9 - n.finishedAtMs;
517
+ let r = a(S, t).s;
518
+ return n.nextCheckpoint === 1 && r > S.length * .75 && (r -= S.length), n.completedLaps * S.length + r;
519
+ }
520
+ function Le() {
521
+ let e = R.x - z.x, t = R.z - z.z, n = Math.hypot(e, t);
522
+ if (n >= fe * 2 || n < 1e-6) return;
523
+ let r = e / n, i = t / n, a = (fe * 2 - n) / 2, o = (R.vx - (z.vx || 0)) * r + (R.vz - (z.vz || 0)) * i;
524
+ R = {
525
+ ...R,
526
+ x: R.x + r * a,
527
+ z: R.z + i * a
528
+ }, o < 0 && (R.vx -= .6 * o * r, R.vz -= .6 * o * i, R.speed = R.vx * Math.sin(R.heading) + R.vz * Math.cos(R.heading)), A - ve > 600 && (ve = A, X({
529
+ type: "collision",
530
+ x: (R.x + z.x) / 2,
531
+ z: (R.z + z.z) / 2,
532
+ strength: Math.min(1, Math.abs(o) / 15)
533
+ }));
534
+ }
535
+ return {
536
+ setInput(e) {
537
+ L = { ...e };
538
+ },
539
+ step(r) {
540
+ if (G) return;
541
+ let i = Math.max(0, Math.min(Number(r) || 0, 100));
542
+ if (A += i, E === "countdown") {
543
+ let e = Math.max(0, Math.ceil((te - A) / 1e3));
544
+ e !== k && e > 0 && X({
545
+ type: "countdown",
546
+ value: e
547
+ }), k = e, A >= te && (E = "racing", j = 0, M = 0, n && (J = A), X({ type: "go" }), Y());
548
+ } else E === "paused" && O !== null && A >= O && (E = "racing", O = null, D = null, M = 0, n && (J = A, Se.clear()), X({ type: "resume" }), Y());
549
+ let a = Se.sample(A);
550
+ if (a && (z = a), E === "racing") {
551
+ for (M += i / 1e3; M >= .016666666666666666 && E === "racing";) {
552
+ M -= ne;
553
+ let e = R;
554
+ if (R = ie(R, L, ne, S, b), j += ne * 1e3, n) {
555
+ let n = se(B[t], e, R, S, {
556
+ nowMs: j,
557
+ maxSegmentDistance: Math.max(12, b.maxSpeed * ne * 2 + 2)
558
+ });
559
+ n.accepted && je(t, n);
560
+ }
561
+ }
562
+ Le();
563
+ }
564
+ if (K.phase === "connected" && E !== "finished") {
565
+ let t = K.rtt > 250 || K.move?.lossPct > 15 ? 10 : K.rtt > 100 ? 15 : 20;
566
+ A >= N && (N = A + 1e3 / t, Q.sendMove({
567
+ g: e.gameId,
568
+ x: R.x,
569
+ z: R.z,
570
+ heading: R.heading,
571
+ vx: R.vx,
572
+ vz: R.vz,
573
+ speed: R.speed,
574
+ seq: ++I,
575
+ t: Math.round(A)
576
+ }));
577
+ }
578
+ },
579
+ getRender() {
580
+ let e = B[t], r = {
581
+ [t]: R,
582
+ [_]: z
583
+ }, i = g.map((e, n) => ({
584
+ id: e,
585
+ x: r[e].x,
586
+ z: r[e].z,
587
+ heading: r[e].heading,
588
+ speed: r[e].speed || 0,
589
+ color: de[n],
590
+ self: e === t,
591
+ lap: Math.min(B[e].completedLaps + 1, x),
592
+ finished: B[e].finishedAtMs !== null
593
+ })), a = E === "countdown" ? Math.max(0, Math.ceil((te - A) / 1e3)) : E === "paused" && O !== null ? Math.max(0, Math.ceil((O - A) / 1e3)) : 0, o = E === "finished" && V ? V === t ? 1 : 2 : Ie(t, R) >= Ie(_, z) ? 1 : 2, s = {
594
+ track: S,
595
+ speedClass: y?.id ?? null,
596
+ topSpeed: C,
597
+ cars: i,
598
+ phase: E,
599
+ countdown: a,
600
+ raceTimeMs: Math.round(j),
601
+ laps: x,
602
+ lap: Math.min(e.completedLaps + 1, x),
603
+ position: o,
604
+ lapTimes: [...e.lapTimesMs],
605
+ winner: V,
606
+ reason: ce,
607
+ events: ge,
608
+ validation: n ? { ...xe } : null,
609
+ net: {
610
+ ...K,
611
+ rtt: K.rtt ?? null,
612
+ route: K.route ?? null,
613
+ error: w || K.error || null,
614
+ turnConfigured: K.turnConfigured ?? ee
615
+ }
616
+ };
617
+ return ge = [], s;
618
+ },
619
+ configureTurn(e, t) {
620
+ return G || E === "finished" ? Promise.reject(/* @__PURE__ */ Error("La carrera ya terminó.")) : Q.configureTurn(e, t);
621
+ },
622
+ reconnect() {
623
+ !G && E !== "finished" && (Q.requestReconnect ? Q.requestReconnect() : Q.connect());
624
+ },
625
+ resign() {
626
+ !G && E !== "finished" && (_e = !0, Z({ k: "resign" }), ke(_, "resigned"));
627
+ },
628
+ destroy() {
629
+ G || (G = !0, Q.destroy(), Se.clear(), ge = []);
630
+ }
631
+ };
632
+ }
633
+ // src/games/racing-live/scene/trackView.js
634
+ var G = Object.freeze(["#ff2b3d", "#2f6bff"]), K = Object.freeze(["car-racer", "car"]);
635
+ function _e(e) {
636
+ let t = e >>> 0 || 1;
637
+ return () => (t ^= t << 13, t ^= t >>> 17, t ^= t << 5, (t >>> 0) / 4294967296);
638
+ }
639
+ function ve(e) {
640
+ let t = e.points, n = t.length - 1;
641
+ return t.map((e, r) => {
642
+ let i = t[(r - 1 + n) % n], a = t[(r + 1) % n], o = a.x - i.x, s = a.z - i.z, c = Math.hypot(o, s) || 1, l = o / c, u = s / c;
643
+ return {
644
+ x: e.x,
645
+ z: e.z,
646
+ tx: l,
647
+ tz: u,
648
+ sx: -u,
649
+ sz: l
650
+ };
651
+ });
652
+ }
653
+ var q = (e, t) => e.map((e) => ({
654
+ x: e.x + e.sx * t,
655
+ z: e.z + e.sz * t
656
+ }));
657
+ function J(e, t = 0) {
658
+ let n = Infinity, r = -Infinity, i = Infinity, a = -Infinity;
659
+ for (let t of e.points) n = Math.min(n, t.x), r = Math.max(r, t.x), i = Math.min(i, t.z), a = Math.max(a, t.z);
660
+ return {
661
+ minX: n - t,
662
+ maxX: r + t,
663
+ minZ: i - t,
664
+ maxZ: a + t,
665
+ width: r - n + t * 2,
666
+ depth: a - i + t * 2
667
+ };
668
+ }
669
+ function ye(e, { count: t = 140, seed: n = e.seed, clearance: r = 4 } = {}) {
670
+ let i = _e((n ^ 1540483477) >>> 0), o = J(e, 45), s = e.width / 2 + (e.barrierMargin ?? 3) + r, c = [];
671
+ for (let n = 0; c.length < t && n < t * 4; n += 1) {
672
+ let t = o.minX + i() * o.width, n = o.minZ + i() * o.depth;
673
+ if (a(e, {
674
+ x: t,
675
+ z: n
676
+ }).distance < s) continue;
677
+ let r = i() < .72;
678
+ c.push({
679
+ kind: r ? "tree" : "rock",
680
+ x: t,
681
+ z: n,
682
+ scale: r ? .9 + i() * .8 : .6 + i() * .9
683
+ });
684
+ }
685
+ return c;
686
+ }
687
+ var be = (e, t) => e?.color || G[t % G.length];
688
+ function xe(e) {
689
+ if (!Number.isFinite(e) || e < 0) return "0:00.0";
690
+ let t = Math.floor(e / 100), n = t % 10, r = Math.floor(t / 10) % 60;
691
+ return `${Math.floor(t / 600)}:${String(r).padStart(2, "0")}.${n}`;
692
+ }
693
+ var Se = (e) => typeof e == "string" ? e : e?.type ?? e?.k ?? null;
694
+ // src/games/racing-live/scene/themes/buildEnvironment.js
695
+ function Y(e, t, n, r, { lowPower: i = !1 } = {}) {
696
+ let a = new e.Group(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = (e, t) => (o.has(e) || o.set(e, t()), o.get(e)), l = (t) => (s.has(t) || s.set(t, new e.MeshLambertMaterial({ color: t })), s.get(t)), u = (t, n, r, o, s, c = 1, u = 1, d = 1) => {
697
+ let f = new e.Mesh(t, l(n));
698
+ return f.position.set(r, o, s), f.scale.set(c, u, d), f.castShadow = !i, f.receiveShadow = !i, a.add(f), f;
699
+ }, d = c("box", () => new e.BoxGeometry(1, 1, 1)), f = c("cone", () => new e.ConeGeometry(1, 1, 7)), p = c("cylinder", () => new e.CylinderGeometry(1, 1, 1, 8)), m = c("rock", () => new e.DodecahedronGeometry(1, 0)), h = J(n, 650), g = c("ground", () => new e.PlaneGeometry(h.width, h.depth));
700
+ g.rotateX(-Math.PI / 2);
701
+ let _ = u(g, r.ground, (h.minX + h.maxX) / 2, -.03, (h.minZ + h.maxZ) / 2);
702
+ _.castShadow = !1, t.background = new e.Color(r.sky), t.fog = new e.Fog(r.sky, 120, Math.max(430, Math.min(850, n.length * .6)));
703
+ let v = ye(n, {
704
+ count: i ? 45 : 95,
705
+ clearance: 10
706
+ });
707
+ for (let e = 0; e < v.length; e++) {
708
+ let { x: t, z: n, scale: i } = v[e];
709
+ if (r.decor === "building") {
710
+ let a = (8 + e % 6 * 4) * i;
711
+ u(d, e % 2 ? "#4f6078" : "#37465e", t, a / 2, n, 5, a, 5), u(d, r.accent, t, a * .7, n - 2.55, 3.5, .7, .1);
712
+ } else if (r.decor === "mesa") u(m, r.accent, t, 3 * i, n, 4 * i, 5 * i, 3 * i), e % 3 == 0 && u(p, "#608455", t + 4, 2, n, .5, 4, .5);
713
+ else if (r.decor === "palm") {
714
+ if (e % 9 == 0) u(p, "#f0e5cb", t, 5, n, 1.7, 10, 1.7), u(f, "#e76d5e", t, 10.7, n, 2.3, 2, 2.3), u(p, "#ffe8a5", t, 9, n, 1.9, .8, 1.9);
715
+ else {
716
+ u(p, "#8c7650", t, 3 * i, n, .4, 6 * i, .4);
717
+ for (let e = 0; e < 3; e++) {
718
+ let r = u(d, "#3c9370", t, 6 * i, n, 6 * i, .25, 1.1 * i);
719
+ r.rotation.y = e * Math.PI / 3;
720
+ }
721
+ }
722
+ } else u(p, "#775940", t, 1.5 * i, n, .4, 3 * i, .4), u(f, r.decor === "snowpine" ? "#d5eef2" : r.accent, t, 4 * i, n, 2.8 * i, 6 * i, 2.8 * i), r.decor === "snowpine" && u(f, "#5a8f95", t, 2.2 * i, n, 3 * i, 1.5 * i, 3 * i);
723
+ }
724
+ for (let e of n.obstacles || []) {
725
+ let { x: t, z: n, radius: i } = e, a = e.kind === "cone" ? "#ff873b" : r.obstacle;
726
+ u(p, a, t, .08, n, i, .16, i), e.kind === "cone" || e.kind === "buoy" ? (u(f, a, t, i, n, i * .8, i * 2, i * .8), u(p, "#fff8e8", t, i * .8, n, i * .5, i * .25, i * .5)) : e.kind === "log" ? u(d, "#8b6144", t, i * .6, n, i * 1.6, i * 1.2, i * 1.1) : e.kind === "snowman" ? (u(m, "#fffafa", t, i, n, i * .9, i, i * .9), u(m, "#fffafa", t, i * 2, n, i * .55, i * .65, i * .55)) : e.kind === "barrier" || e.kind === "ice" ? u(d, a, t, i * .65, n, i * 1.4, i * 1.3, i * 1.4) : u(m, a, t, i * .65, n, i * .95, i, i * .95);
727
+ }
728
+ t.add(a);
729
+ let y = !1;
730
+ return {
731
+ update() {},
732
+ dispose() {
733
+ y || (y = !0, a.removeFromParent(), o.forEach((e) => e.dispose()), s.forEach((e) => e.dispose()), a.clear());
734
+ }
735
+ };
736
+ }
737
+ // src/games/racing-live/scene/themes/city.js
738
+ var X = /* @__PURE__ */ N({
739
+ buildTheme3d: () => Ce,
740
+ theme2d: () => Z
741
+ }), Z = Object.freeze({
742
+ ground: "#273142",
743
+ asphalt: "#373d48",
744
+ edge: "#a4b0c4",
745
+ sky: "#7486a8",
746
+ accent: "#f4ad43",
747
+ decor: "building",
748
+ obstacle: "#ff873b"
749
+ });
750
+ function Ce(e, t, n, r) {
751
+ return Y(e, t, n, Z, r);
752
+ }
753
+ // src/games/racing-live/scene/themes/canyon.js
754
+ var we = /* @__PURE__ */ N({
755
+ buildTheme3d: () => Ee,
756
+ theme2d: () => Te
757
+ }), Te = Object.freeze({
758
+ ground: "#d69c64",
759
+ asphalt: "#755c50",
760
+ edge: "#f3c687",
761
+ sky: "#f2c68d",
762
+ accent: "#ad5d39",
763
+ decor: "mesa",
764
+ obstacle: "#995e40"
765
+ });
766
+ function Ee(e, t, n, r) {
767
+ return Y(e, t, n, Te, r);
768
+ }
769
+ // src/games/racing-live/scene/themes/forest.js
770
+ var De = /* @__PURE__ */ N({
771
+ buildTheme3d: () => ke,
772
+ theme2d: () => Oe
773
+ }), Oe = Object.freeze({
774
+ ground: "#3e7447",
775
+ asphalt: "#424d47",
776
+ edge: "#aeb980",
777
+ sky: "#a6d3b6",
778
+ accent: "#2c583c",
779
+ decor: "pine",
780
+ obstacle: "#96643b"
781
+ });
782
+ function ke(e, t, n, r) {
783
+ return Y(e, t, n, Oe, r);
784
+ }
785
+ // src/games/racing-live/scene/themes/snow.js
786
+ var Ae = /* @__PURE__ */ N({
787
+ buildTheme3d: () => Me,
788
+ theme2d: () => je
789
+ }), je = Object.freeze({
790
+ ground: "#e4f1f7",
791
+ asphalt: "#8299af",
792
+ edge: "#ffffff",
793
+ sky: "#b5cddd",
794
+ accent: "#7fcbe7",
795
+ decor: "snowpine",
796
+ obstacle: "#75cde9"
797
+ });
798
+ function Me(e, t, n, r) {
799
+ return Y(e, t, n, je, r);
800
+ }
801
+ // src/games/racing-live/scene/themes/coast.js
802
+ var Ne = /* @__PURE__ */ N({
803
+ buildTheme3d: () => Fe,
804
+ theme2d: () => Pe
805
+ }), Pe = Object.freeze({
806
+ ground: "#b6a588",
807
+ asphalt: "#303b55",
808
+ edge: "#b2c4d7",
809
+ sky: "#172c4b",
810
+ accent: "#2c9dba",
811
+ decor: "palm",
812
+ obstacle: "#f7a04a"
813
+ });
814
+ function Fe(e, t, n, r) {
815
+ return Y(e, t, n, Pe, r);
816
+ }
817
+ // src/games/racing-live/scene/themes/oval.js
818
+ var Q = /* @__PURE__ */ N({
819
+ buildTheme3d: () => Le,
820
+ theme2d: () => Ie
821
+ }), Ie = Object.freeze({
822
+ ground: "#4f7d3b",
823
+ asphalt: "#383b42",
824
+ edge: "#bba981",
825
+ sky: "#b8d3df",
826
+ accent: "#d6303a",
827
+ decor: "pine",
828
+ obstacle: "#ff873b"
829
+ });
830
+ function Le(e, t, n, r) {
831
+ return Y(e, t, n, Ie, r);
832
+ }
833
+ // src/games/racing-live/scene/themes/index.js
834
+ var Re = {
835
+ city: X,
836
+ canyon: we,
837
+ forest: De,
838
+ snow: Ae,
839
+ coast: Ne,
840
+ oval: Q
841
+ }, ze = (e) => Re[e.trackId] || Q;
842
+ // src/games/racing-live/scene/createRaceScene2d.js
843
+ function Be(e, { track: t } = {}) {
844
+ if (!e || !t) throw Error("createRaceScene2d: container and track required");
845
+ let n = document.createElement("canvas");
846
+ n.style.cssText = "width:100%;height:100%;display:block", e.appendChild(n);
847
+ let r = n.getContext("2d");
848
+ if (!r) throw n.remove(), Error("Canvas 2D unavailable");
849
+ let i = ve(t), a = ze(t).theme2d, o = ye(t, {
850
+ count: 80,
851
+ clearance: 10
852
+ }), s = !1, c = t.width / 2, l = t.barrierMargin ?? 3, u = i.map((e) => ({
853
+ x: e.x,
854
+ z: e.z
855
+ })), d = [q(i, c + .45), q(i, -c - .45)], f = J(t, l + 18), p = t.startFinish || t.checkpoints?.[0], m = 1, h = 1, g = 1, _ = 0, v = 0;
856
+ function y() {
857
+ if (s) return;
858
+ m = Math.max(1, e.clientWidth), h = Math.max(1, e.clientHeight);
859
+ let t = Math.min(window.devicePixelRatio || 1, 2);
860
+ n.width = m * t, n.height = h * t, r.setTransform(t, 0, 0, t, 0, 0), g = Math.min(m / f.width, h / f.depth), _ = (m - f.width * g) / 2, v = (h - f.depth * g) / 2;
861
+ }
862
+ y();
863
+ let b = typeof ResizeObserver == "function" ? new ResizeObserver(y) : null;
864
+ b?.observe(e), b || window.addEventListener("resize", y);
865
+ let x = (e) => {
866
+ r.beginPath(), e.forEach((e, t) => t ? r.lineTo(e.x, e.z) : r.moveTo(e.x, e.z));
867
+ };
868
+ return {
869
+ kind: "2d",
870
+ resize: y,
871
+ render(e) {
872
+ if (s) return;
873
+ r.fillStyle = a.ground, r.fillRect(0, 0, m, h), r.save(), r.translate(_, v), r.scale(g, g), r.translate(-f.minX, -f.minZ), r.lineJoin = "round";
874
+ for (let e of o) {
875
+ r.fillStyle = a.accent;
876
+ let t = 3 * e.scale;
877
+ if (a.decor === "building") r.fillRect(e.x - t, e.z - t, t * 2, t * 2), r.fillStyle = "#75859b", r.fillRect(e.x - t * .7, e.z - t * .7, t, t);
878
+ else if (a.decor === "palm") {
879
+ r.lineWidth = 1.2, r.strokeStyle = "#397d69";
880
+ for (let n = 0; n < 3; n++) {
881
+ let i = n * Math.PI / 3;
882
+ r.beginPath(), r.moveTo(e.x - Math.cos(i) * t, e.z - Math.sin(i) * t), r.lineTo(e.x + Math.cos(i) * t, e.z + Math.sin(i) * t), r.stroke();
883
+ }
884
+ } else r.beginPath(), r.arc(e.x, e.z, t, 0, Math.PI * 2), r.fill(), a.decor === "snowpine" && (r.fillStyle = "#f3ffff", r.beginPath(), r.arc(e.x, e.z, t * .65, 0, Math.PI * 2), r.fill());
885
+ }
886
+ x(u), r.strokeStyle = a.edge, r.lineWidth = (c + l) * 2, r.stroke(), x(u), r.strokeStyle = a.asphalt, r.lineWidth = t.width, r.stroke();
887
+ for (let e of d) x(e), r.lineWidth = .9, r.strokeStyle = "#f4f4f6", r.setLineDash([]), r.stroke(), r.strokeStyle = "#e0303a", r.setLineDash([2.5, 2.5]), r.stroke();
888
+ r.setLineDash([]);
889
+ for (let e of t.obstacles || []) r.fillStyle = e.kind === "cone" ? "#ff873b" : a.obstacle, r.beginPath(), r.arc(e.x, e.z, e.radius, 0, Math.PI * 2), r.fill(), r.lineWidth = .22, r.strokeStyle = "#fff9e8", r.stroke();
890
+ p?.a && p?.b && (r.strokeStyle = "#fff", r.lineWidth = 1.6, r.beginPath(), r.moveTo(p.a.x, p.a.z), r.lineTo(p.b.x, p.b.z), r.stroke());
891
+ let n = 7 / g;
892
+ (e?.cars || []).forEach((e, t) => {
893
+ if (!Number.isFinite(e.x) || !Number.isFinite(e.z)) return;
894
+ let i = Math.max(4.2, n * 1.6), a = Math.max(2, n * .8);
895
+ r.save(), r.translate(e.x, e.z), r.rotate(Math.atan2(Math.cos(e.heading || 0), Math.sin(e.heading || 0))), r.fillStyle = be(e, t), r.fillRect(-i / 2, -a / 2, i, a), r.fillStyle = "#111", r.fillRect(i * .1, -a / 2, i * .18, a), r.restore(), e.self && (r.strokeStyle = "#fff", r.lineWidth = .6, r.beginPath(), r.arc(e.x, e.z, i * .9, 0, Math.PI * 2), r.stroke());
896
+ }), r.restore();
897
+ },
898
+ dispose() {
899
+ s || (s = !0, b?.disconnect(), b || window.removeEventListener("resize", y), n.remove());
900
+ }
901
+ };
902
+ }
903
+ // src/games/racing-live/audio/raceAudioSynthesis.js
904
+ var Ve = Object.freeze([
905
+ "circuit",
906
+ "turbo",
907
+ "final_lap"
908
+ ]), He = Object.freeze([
909
+ "engine_start",
910
+ "drift",
911
+ "turbo",
912
+ "collision",
913
+ "countdown",
914
+ "go",
915
+ "lap",
916
+ "pickup",
917
+ "confetti",
918
+ "foam",
919
+ "foam_hit",
920
+ "shield",
921
+ "final_lap",
922
+ "victory",
923
+ "defeat",
924
+ "finish"
925
+ ]), Ue = (e, t, n) => Math.min(n, Math.max(t, Number.isFinite(e) ? e : t)), We = (e) => 440 * 2 ** ((e - 69) / 12), $ = (e, t = 0, n = .15, r = .12, i = "sine", a = e) => ({
926
+ frequency: e,
927
+ offset: t,
928
+ duration: n,
929
+ gain: r,
930
+ type: i,
931
+ endFrequency: a
932
+ });
933
+ function Ge(e) {
934
+ switch (e) {
935
+ case "engine_start": return [$(90, 0, .65, .16, "triangle", 220), $(180, .12, .5, .05, "sawtooth", 440)];
936
+ case "drift": return [$(1600, 0, .18, .035, "sawtooth", 750), $(1740, .03, .14, .025, "triangle", 940)];
937
+ case "turbo": return [$(180, 0, .48, .1, "triangle", 1500), $(360, .04, .4, .045, "sine", 2100)];
938
+ case "collision": return [$(170, 0, .16, .18, "triangle", 55), $(660, 0, .08, .055, "square", 290)];
939
+ case "countdown": return [$(660, 0, .12, .16)];
940
+ case "go": return [$(990, 0, .28, .14), $(1320, 0, .28, .08)];
941
+ case "lap": return [$(880), $(1320, .1, .23)];
942
+ case "pickup": return [
943
+ $(660),
944
+ $(990, .055),
945
+ $(1320, .11, .22)
946
+ ];
947
+ case "confetti": return [$(440, 0, .07, .13, "triangle", 80), ...[
948
+ 1300,
949
+ 1700,
950
+ 2100
951
+ ].map((e, t) => $(e, .045 + t * .035, .07, .025, "triangle", e / 2))];
952
+ case "foam": return [$(1100, 0, .22, .12, "sine", 180)];
953
+ case "foam_hit": return [$(150, 0, .3, .13, "triangle", 450)];
954
+ case "shield": return [
955
+ $(523, 0, .45, .07),
956
+ $(659, .04, .45, .06),
957
+ $(784, .08, .45, .06)
958
+ ];
959
+ case "final_lap": return [
960
+ $(784),
961
+ $(988, .12),
962
+ $(1568, .24, .35)
963
+ ];
964
+ case "victory": return [
965
+ 72,
966
+ 76,
967
+ 79,
968
+ 84,
969
+ 79,
970
+ 84
971
+ ].map((e, t) => $(We(e), t * .13, t === 5 ? .6 : .18, .12, "triangle"));
972
+ case "defeat": return [
973
+ 76,
974
+ 72,
975
+ 74,
976
+ 79
977
+ ].map((e, t) => $(We(e), t * .16, .23, .1, "triangle"));
978
+ case "finish": return [
979
+ 0,
980
+ 1,
981
+ 2,
982
+ 3,
983
+ 4,
984
+ 5,
985
+ 6,
986
+ 7
987
+ ].map((e) => $(We(84 + [
988
+ 0,
989
+ 4,
990
+ 7,
991
+ 12
992
+ ][e % 4]), e * .055, .18, .05));
993
+ default: return [];
994
+ }
995
+ }
996
+ function Ke(e = "circuit", t = 0, n = 0) {
997
+ let r = Ve.includes(e) ? e : "circuit", i = 60 / (r === "circuit" ? 128 : r === "turbo" ? 144 : 152), a = Math.abs(Math.trunc(Number.isFinite(t) ? t : 0)), o = Math.abs(Math.trunc(Number.isFinite(n) ? n : 0)) % 4, s = [
998
+ 48,
999
+ 53,
1000
+ 55,
1001
+ 53
1002
+ ][a % 4], c = [
1003
+ 0,
1004
+ 7,
1005
+ 12,
1006
+ 4,
1007
+ 7,
1008
+ 14,
1009
+ 12,
1010
+ 7
1011
+ ], l = [];
1012
+ for (let e = 0; e < 8; e += 1) l.push($(We(s + 12 + c[(e + o) % 8]), e * i / 2, i * .3, .045, "triangle")), (e % 2 == 0 || r !== "circuit") && l.push($(We(s - 12), e * i / 2, i * .32, .085, "sine")), e % 2 == 0 && l.push($(130, e * i / 2, .09, .11, "sine", 42)), e % 4 == 2 && l.push($(260, e * i / 2, .06, .035, "triangle", 110)), l.push($(4100 + e * 71, e * i / 2, .025, .009, "square", 2400));
1013
+ return {
1014
+ duration: i * 4,
1015
+ notes: l
1016
+ };
1017
+ }
1018
+ function qe(e, t, n) {
1019
+ let r = Math.max(e.currentTime, n.when ?? e.currentTime), i = Ue(n.duration ?? .15, .025, 4), a = e.createOscillator(), o = e.createGain();
1020
+ a.type = n.type ?? "sine", a.frequency.setValueAtTime(Ue(n.frequency, 20, 16e3), r), a.frequency.exponentialRampToValueAtTime(Ue(n.endFrequency ?? n.frequency, 20, 16e3), r + i), o.gain.setValueAtTime(0, r), o.gain.linearRampToValueAtTime(Ue(n.gain ?? .1, 0, .3), r + Math.min(.008, i / 4)), o.gain.exponentialRampToValueAtTime(1e-4, r + i), a.connect(o), o.connect(t);
1021
+ let s = !1, c = () => {
1022
+ a.disconnect(), o.disconnect();
1023
+ };
1024
+ return a.onended = c, a.start(r), a.stop(r + i + .01), {
1025
+ endTime: r + i + .01,
1026
+ stop() {
1027
+ if (!s) {
1028
+ s = !0;
1029
+ try {
1030
+ a.stop();
1031
+ } catch {}
1032
+ c();
1033
+ }
1034
+ }
1035
+ };
1036
+ }
1037
+ function Je(e, t, n, r, i = 1) {
1038
+ let a = Math.max(e.currentTime, r ?? e.currentTime), o = n.map((n) => qe(e, t, {
1039
+ ...n,
1040
+ when: a + n.offset,
1041
+ gain: n.gain * Ue(i, 0, 1)
1042
+ }));
1043
+ return {
1044
+ endTime: Math.max(a, ...o.map((e) => e.endTime)),
1045
+ stop() {
1046
+ o.forEach((e) => e.stop());
1047
+ }
1048
+ };
1049
+ }
1050
+ function Ye(e, t, n, { when: r, intensity: i = 1 } = {}) {
1051
+ return Je(e, t, Ge(n), r, i);
1052
+ }
1053
+ function Xe(e, t, n, { when: r, bar: i = 0, seed: a = 0 } = {}) {
1054
+ let o = Ke(n, i, a);
1055
+ return {
1056
+ ...Je(e, t, o.notes, r),
1057
+ duration: o.duration
1058
+ };
1059
+ }
1060
+ function Ze(e, t) {
1061
+ let n = [e.createOscillator(), e.createOscillator()], r = e.createGain();
1062
+ r.gain.setValueAtTime(0, e.currentTime), r.connect(t), n.forEach((t, n) => {
1063
+ t.type = n ? "sine" : "triangle", t.frequency.setValueAtTime(n ? 180 : 90, e.currentTime), t.connect(r), t.start();
1064
+ });
1065
+ let i = !1;
1066
+ return {
1067
+ update({ speed: t = 0, rpm: a, throttle: o = 0, drifting: s = !1 } = {}) {
1068
+ if (i) return;
1069
+ let c = Ue(Number.isFinite(a) ? a : Math.abs(t) / 45, 0, 1), l = Ue(o, 0, 1);
1070
+ n.forEach((t, n) => t.frequency.setTargetAtTime((90 + c * 310 + l * 35) * (n ? 2.005 : 1), e.currentTime, .06)), r.gain.setTargetAtTime(.035 + c * .045 + l * .025 + (s ? .008 : 0), e.currentTime, .08);
1071
+ },
1072
+ stop() {
1073
+ i || (i = !0, n.forEach((e) => {
1074
+ try {
1075
+ e.stop();
1076
+ } catch {}
1077
+ e.disconnect();
1078
+ }), r.disconnect());
1079
+ }
1080
+ };
1081
+ }
1082
+ // src/games/racing-live/audio/raceAudioFiles.js
1083
+ var Qe = Object.freeze({
1084
+ engine_start: "car_engine_start",
1085
+ turbo: "car_boost",
1086
+ collision: "car_bump",
1087
+ countdown: "countdown_beep",
1088
+ go: "countdown_go",
1089
+ lap: "lap_complete",
1090
+ final_lap: "final_lap",
1091
+ finish: "finish_line",
1092
+ victory: "race_victory",
1093
+ defeat: "race_defeat"
1094
+ }), $e = Object.freeze({
1095
+ circuit: "music_circuit",
1096
+ final_lap: "music_final_lap"
1097
+ }), et = Object.freeze({
1098
+ engine: "car_engine_loop",
1099
+ drift: "car_drift_loop"
1100
+ }), tt = Object.freeze([.../* @__PURE__ */ new Set([
1101
+ ...Object.values(Qe),
1102
+ ...Object.values(et),
1103
+ ...Object.values($e)
1104
+ ])]), nt = Object.freeze({
1105
+ ...Object.fromEntries(Object.entries({
1106
+ car_engine_start: -20,
1107
+ car_boost: -18,
1108
+ car_bump: -17,
1109
+ countdown_beep: -18,
1110
+ countdown_go: -16,
1111
+ lap_complete: -19,
1112
+ final_lap: -18,
1113
+ finish_line: -17,
1114
+ race_victory: -18,
1115
+ race_defeat: -19
1116
+ }).map(([e, t]) => [e, Math.min(1, 10 ** ((-21 - t) / 20))])),
1117
+ car_engine_loop: .6,
1118
+ car_drift_loop: .7,
1119
+ music_circuit: .8,
1120
+ music_final_lap: .75
1121
+ }), rt = .03;
1122
+ function it() {
1123
+ try {
1124
+ return typeof Audio < "u" && new Audio().canPlayType("audio/ogg; codecs=\"vorbis\"") !== "" ? "ogg" : "mp3";
1125
+ } catch {
1126
+ return "mp3";
1127
+ }
1128
+ }
1129
+ var at = (e, n) => t(`racing/${e}.${n}`), ot = (e, t) => new Promise((n, r) => {
1130
+ e.decodeAudioData(t, n, r)?.then?.(n, r);
1131
+ });
1132
+ function st({ context: e, format: t, fetch: n, url: r = at, onLoad: i }) {
1133
+ let a = /* @__PURE__ */ new Map(), o = !1;
1134
+ if (typeof n == "function" && typeof e?.decodeAudioData == "function") for (let s of tt) Promise.resolve().then(() => n(r(s, t))).then((e) => {
1135
+ if (!e?.ok) throw Error(`missing ${s}`);
1136
+ return e.arrayBuffer();
1137
+ }).then((t) => ot(e, t)).then((e) => {
1138
+ !o && e && (a.set(s, e), i?.(s));
1139
+ }).catch(() => {});
1140
+ return {
1141
+ get: (e) => a.get(e) || null,
1142
+ close() {
1143
+ o = !0, a.clear();
1144
+ }
1145
+ };
1146
+ }
1147
+ function ct(e, t, n, { when: r, gain: i = 1, loop: a = !1, trim: o = 0, offset: s = 0, fadeIn: c = 0 } = {}) {
1148
+ let l = Math.max(e.currentTime, r ?? e.currentTime), u = e.createBufferSource(), d = e.createGain();
1149
+ u.buffer = n, a && (u.loop = !0, o > 0 && n.duration > o * 4 && (u.loopStart = o, u.loopEnd = n.duration - o)), c > 0 ? (d.gain.setValueAtTime(0, l), d.gain.linearRampToValueAtTime(i, l + c)) : d.gain.value = i, u.connect(d), d.connect(t);
1150
+ let f = !1, p = () => {
1151
+ u.disconnect(), d.disconnect();
1152
+ };
1153
+ return u.onended = p, u.start(l, s), {
1154
+ source: u,
1155
+ gain: d.gain,
1156
+ startTime: l - s,
1157
+ endTime: a ? Infinity : l + n.duration + .02,
1158
+ fadeOut(t) {
1159
+ if (f) return;
1160
+ let n = e.currentTime;
1161
+ d.gain.cancelScheduledValues(n), d.gain.setValueAtTime(d.gain.value, n), d.gain.linearRampToValueAtTime(0, n + t), this.endTime = n + t + .05;
1162
+ try {
1163
+ u.stop(this.endTime);
1164
+ } catch {}
1165
+ },
1166
+ stop() {
1167
+ if (!f) {
1168
+ f = !0;
1169
+ try {
1170
+ u.stop();
1171
+ } catch {}
1172
+ p();
1173
+ }
1174
+ }
1175
+ };
1176
+ }
1177
+ var lt = Object.freeze({
1178
+ music: .24,
1179
+ engine: .32,
1180
+ effects: .65,
1181
+ ui: .7
1182
+ }), ut = /* @__PURE__ */ new Set([
1183
+ "countdown",
1184
+ "go",
1185
+ "lap",
1186
+ "final_lap",
1187
+ "victory",
1188
+ "defeat",
1189
+ "finish"
1190
+ ]), dt = 100, ft = .6, pt = 1.6, mt = (e) => Number.isFinite(e) ? Math.max(0, Math.min(1, e)) : 0, ht = () => {
1191
+ let e = globalThis.AudioContext || globalThis.webkitAudioContext;
1192
+ return e ? new e() : null;
1193
+ };
1194
+ function gt({ contextFactory: e = ht, document: t = globalThis.document, volumes: n = {}, setInterval: r = globalThis.setInterval, clearInterval: i = globalThis.clearInterval, fetch: a = globalThis.fetch?.bind(globalThis), format: o = null, now: s = () => globalThis.performance?.now?.() ?? Date.now() } = {}) {
1195
+ let c = null, l = null, u = null, d = null, f = null, p = !1, m = !1, h = !1, g = "off", _ = 0, v = 0, y = null, b = null, x = "mp3", S = null, C = -Infinity, w = /* @__PURE__ */ new Set(), ee = /* @__PURE__ */ new Map(), T = { ...lt }, E = {}, D = /* @__PURE__ */ new Set();
1196
+ for (let e of Object.keys(T)) Object.hasOwn(n, e) && (T[e] = mt(n[e]));
1197
+ let te = () => !p && !m && !h && !t?.hidden && c?.state === "running", O = (e, t, n = .04) => {
1198
+ let r = c.currentTime;
1199
+ e.cancelScheduledValues(r), e.setTargetAtTime(t, r, n);
1200
+ }, k = (e) => b?.get(e) || null, A = () => x === "mp3" ? rt : 0, j = () => {
1201
+ for (let e of D) e.stop();
1202
+ D.clear();
1203
+ for (let e of w) e.stop();
1204
+ w.clear(), S?.stop(), S = null, d?.stop(), d = null, f !== null && i(f), f = null, _ = 0;
1205
+ }, M = () => {
1206
+ for (let e of [D, w]) for (let t of e) t.endTime <= c.currentTime && (t.stop(), e.delete(t));
1207
+ }, N = (e) => e === "off" ? null : k($e[e]), ne = () => {
1208
+ let e = N(g);
1209
+ if (S && S.mood === g && e) return;
1210
+ let t = 0;
1211
+ if (S) {
1212
+ let n = S;
1213
+ S = null;
1214
+ let r = A();
1215
+ e && (t = r + Math.max(0, c.currentTime - n.startTime) % Math.max(.1, e.duration - 2 * r)), n.fadeOut(e ? ft : .3), D.add(n);
1216
+ }
1217
+ if (e) {
1218
+ for (let e of w) e.stop();
1219
+ w.clear(), _ = 0, S = ct(c, E.music, e, {
1220
+ loop: !0,
1221
+ trim: A(),
1222
+ offset: t,
1223
+ gain: nt[$e[g]] ?? .8,
1224
+ fadeIn: t ? ft : .05
1225
+ }), S.mood = g;
1226
+ }
1227
+ }, P = () => {
1228
+ let e = k(et.engine);
1229
+ if (!e) return null;
1230
+ let t = A(), n = ct(c, E.engine, e, {
1231
+ loop: !0,
1232
+ trim: t,
1233
+ gain: 0
1234
+ }), r = k(et.drift), i = r ? ct(c, E.engine, r, {
1235
+ loop: !0,
1236
+ trim: t,
1237
+ gain: 0
1238
+ }) : null, a = nt[et.engine];
1239
+ return {
1240
+ recorded: !0,
1241
+ update({ speed: e = 0, rpm: t, throttle: r = 0, drifting: o = !1 } = {}) {
1242
+ let s = mt(Number.isFinite(t) ? t : Math.abs(e) / 45), l = c.currentTime;
1243
+ n.source.playbackRate.setTargetAtTime(.6 + s * 1.6, l, .08), n.gain.setTargetAtTime(a * (.5 + s * .35 + mt(r) * .15), l, .08), i?.gain.setTargetAtTime(o ? nt[et.drift] : 0, l, o ? .05 : .12);
1244
+ },
1245
+ stop() {
1246
+ n.stop(), i?.stop();
1247
+ }
1248
+ };
1249
+ }, F = () => {
1250
+ if (te() && (M(), g !== "off" && !S && _ < c.currentTime + .2)) {
1251
+ _ = Math.max(_, c.currentTime + .02);
1252
+ let e = Xe(c, E.music, g, {
1253
+ when: _,
1254
+ bar: v++
1255
+ });
1256
+ w.add(e), _ += e.duration;
1257
+ }
1258
+ }, I = () => {
1259
+ c && !p && (te() ? (O(l.gain, .8), ne(), y && (!d || !d.recorded && k(et.engine)) && (d?.stop(), d = P() || Ze(c, E.engine)), d?.update(y), f === null && (f = r(F, 100)), F()) : (j(), O(l.gain, 0)));
1260
+ }, L = () => {
1261
+ I();
1262
+ };
1263
+ async function R() {
1264
+ if (p) return !1;
1265
+ try {
1266
+ if (!c) {
1267
+ if (c = e(), !c) return !1;
1268
+ l = c.createGain(), l.gain.value = 0, u = c.createDynamicsCompressor(), u.threshold.value = -8, u.knee.value = 12, u.ratio.value = 8, u.attack.value = .003, u.release.value = .15, l.connect(u), u.connect(c.destination);
1269
+ for (let e of Object.keys(T)) E[e] = c.createGain(), E[e].gain.value = T[e], E[e].connect(l);
1270
+ t?.addEventListener("visibilitychange", L), x = o || it(), b = st({
1271
+ context: c,
1272
+ format: x,
1273
+ fetch: a,
1274
+ onLoad: () => I()
1275
+ });
1276
+ }
1277
+ return c.state === "suspended" && await c.resume(), !p && (I(), c.state === "running");
1278
+ } catch {
1279
+ return !1;
1280
+ }
1281
+ }
1282
+ function z() {
1283
+ m = !0, I();
1284
+ }
1285
+ async function re() {
1286
+ return m = !1, R();
1287
+ }
1288
+ function ie(e, t) {
1289
+ return !Object.hasOwn(T, e) || p ? !1 : (T[e] = mt(t), E[e] && O(E[e].gain, e === "music" && g === "off" ? 0 : T[e]), !0);
1290
+ }
1291
+ function ae(e) {
1292
+ h = !!e, I();
1293
+ }
1294
+ function oe(e) {
1295
+ y = e ? { ...e } : null, e || (d?.stop(), d = null), I();
1296
+ }
1297
+ function B(e) {
1298
+ return p || e !== "off" && !Ve.includes(e) ? !1 : (g = e, E.music && O(E.music.gain, e === "off" ? 0 : T.music), I(), !0);
1299
+ }
1300
+ function V(e, t = {}) {
1301
+ if (!te() || !He.includes(e)) return !1;
1302
+ let n = s();
1303
+ if (n - (ee.get(e) ?? -Infinity) < dt || (M(), D.size >= 32)) return !1;
1304
+ ee.set(e, n);
1305
+ let r = t.when;
1306
+ e === "finish" ? C = c.currentTime : (e === "victory" || e === "defeat") && c.currentTime - C < pt && (r = Math.max(r ?? 0, C + pt));
1307
+ let i = E[ut.has(e) ? "ui" : "effects"], a = Qe[e], o = a ? k(a) : null;
1308
+ if (D.add(o ? ct(c, i, o, {
1309
+ when: r,
1310
+ gain: (nt[a] ?? .7) * mt(t.intensity ?? 1)
1311
+ }) : Ye(c, i, e, {
1312
+ ...t,
1313
+ when: r
1314
+ })), [
1315
+ "collision",
1316
+ "countdown",
1317
+ "go",
1318
+ "finish",
1319
+ "victory"
1320
+ ].includes(e)) {
1321
+ let e = c.currentTime;
1322
+ E.music.gain.cancelScheduledValues(e), E.music.gain.setTargetAtTime(g === "off" ? 0 : T.music * .35, e, .02), E.music.gain.setTargetAtTime(g === "off" ? 0 : T.music, e + .35, .12);
1323
+ }
1324
+ return !0;
1325
+ }
1326
+ async function se() {
1327
+ if (!p) {
1328
+ p = !0, j(), b?.close(), t?.removeEventListener("visibilitychange", L);
1329
+ for (let e of Object.values(E)) e.disconnect();
1330
+ if (l?.disconnect(), u?.disconnect(), c && c.state !== "closed") try {
1331
+ await c.close();
1332
+ } catch {}
1333
+ }
1334
+ }
1335
+ return {
1336
+ unlock: R,
1337
+ pause: z,
1338
+ resume: re,
1339
+ setVolume: ie,
1340
+ setMuted: ae,
1341
+ setEngine: oe,
1342
+ setMusic: B,
1343
+ playCue: V,
1344
+ dispose: se,
1345
+ getState: () => ({
1346
+ supported: !!(c || globalThis.AudioContext || globalThis.webkitAudioContext),
1347
+ contextState: c?.state || "locked",
1348
+ active: !!te(),
1349
+ paused: m,
1350
+ muted: h,
1351
+ disposed: p,
1352
+ music: g,
1353
+ volumes: { ...T },
1354
+ engine: !!y,
1355
+ recordedMusic: S?.mood ?? null,
1356
+ recordedEngine: !!d?.recorded
1357
+ })
1358
+ };
1359
+ }
1360
+ // src/games/racing-live/RacingLiveGameCard.jsx
1361
+ var _t = /* @__PURE__ */ N({ default: () => Tt }), vt = [
1362
+ "KeyW",
1363
+ "KeyA",
1364
+ "KeyS",
1365
+ "KeyD",
1366
+ "ArrowUp",
1367
+ "ArrowDown",
1368
+ "ArrowLeft",
1369
+ "ArrowRight",
1370
+ "Space"
1371
+ ], yt = (e) => Math.max(-1, Math.min(1, e)), bt = (t, n) => {
1372
+ e.getState().act(t, n).catch(() => {});
1373
+ }, xt = { neon_city: "Óvalo clásico 🏁" }, St = Object.fromEntries(Object.values(r).map((e) => [e.id, `~${e.topKmh} km/h · ${(e.trackLength / 1e3).toLocaleString("es")} km`]));
1374
+ function Ct(e) {
1375
+ let t = e?.manualTurn;
1376
+ return t?.status === "applying" ? "Aplicando configuración…" : t?.status === "sharing" ? "Sincronizando con el otro jugador…" : t?.status === "waiting_peer" ? "Esperando al otro jugador…" : e?.phase === "connected" ? "Conectado" : e?.phase === "failed" || e?.ice === "failed" ? "No pudimos conectar" : e?.phase === "restarting" || e?.phase === "reconnecting" ? "Reconectando…" : e?.phase === "listening" ? "Esperando al otro jugador…" : "Conectando…";
1377
+ }
1378
+ function wt({ gameKey: t, currentUserId: r, onMinimize: i, onDismiss: a, suspended: s = !1 }) {
1379
+ let c = x(m)?.config?.webrtc, l = e((e) => e.games[t]), u = C(s);
1380
+ u.current = s;
1381
+ let d = C(null), b = C(null), M = C(null), N = C(null), ne = C(/* @__PURE__ */ new Set()), P = C({
1382
+ steer: 0,
1383
+ accel: !1,
1384
+ brake: !1,
1385
+ handbrake: !1
1386
+ }), [F, I] = w(null), [L, R] = w(""), [z, re] = w(!1), [ie, ae] = w("loading"), [oe, B] = w(null), [V, se] = w(!1), [ce, le] = w(0), [H, ue] = w(!1), [de, fe] = w(f), [pe, U] = w(0), [me, he] = w(!1), W = l?.status === "active", G = F?.net?.phase === "connected";
1387
+ if (S(() => p(() => fe(f())), []), S(() => {
1388
+ N.current?.setMuted(H || !de || s);
1389
+ }, [
1390
+ H,
1391
+ de,
1392
+ s
1393
+ ]), S(() => {
1394
+ if (!W || G) {
1395
+ le(0);
1396
+ return;
1397
+ }
1398
+ let e = Date.now(), t = setInterval(() => le(Date.now() - e), 1e3);
1399
+ return () => clearInterval(t);
1400
+ }, [
1401
+ t,
1402
+ W,
1403
+ G
1404
+ ]), S(() => {
1405
+ se(!1);
1406
+ }, [t, l?.status]), S(() => {
1407
+ s ? (ne.current.clear(), P.current = {
1408
+ steer: 0,
1409
+ accel: !1,
1410
+ brake: !1,
1411
+ handbrake: !1
1412
+ }, U(0)) : M.current?.resize();
1413
+ }, [s]), S(() => {
1414
+ if (!W || !oe || !d.current) return;
1415
+ let e = !1, t = null, n = {
1416
+ track: oe,
1417
+ lowPower: matchMedia("(pointer: coarse)").matches,
1418
+ reducedMotion: matchMedia("(prefers-reduced-motion: reduce)").matches,
1419
+ onEvent: (e) => {
1420
+ e.type === "context_lost" && re(!0);
1421
+ }
1422
+ }, r = () => {
1423
+ if (!e) try {
1424
+ t = Be(d.current, n), M.current = t, ae("2d");
1425
+ } catch {
1426
+ ae("none");
1427
+ }
1428
+ };
1429
+ return z ? r() : import("./createRaceScene-C-aw0dlX.js").then(({ createRaceScene: i }) => {
1430
+ if (!e) try {
1431
+ t = i(d.current, n), M.current = t, ae("3d");
1432
+ } catch {
1433
+ r();
1434
+ }
1435
+ }).catch(r), () => {
1436
+ e = !0, t?.dispose(), M.current === t && (M.current = null);
1437
+ };
1438
+ }, [
1439
+ W,
1440
+ oe,
1441
+ z
1442
+ ]), S(() => {
1443
+ if (!W || !d.current) return;
1444
+ let n = !1, i = 0, a = performance.now(), o = 0, s = !1, p = !1, m;
1445
+ try {
1446
+ let n = e.getState(), i = (n.createRaceSignaling ?? n.createLiveSignaling)(t);
1447
+ m = ge({
1448
+ game: l,
1449
+ selfId: String(r),
1450
+ isHost: String(l.hostId) === String(r),
1451
+ signaling: i,
1452
+ iceServers: c?.iceServers,
1453
+ iceTransportPolicy: c?.iceTransportPolicy
1454
+ }), b.current = m;
1455
+ } catch (e) {
1456
+ R(e.message || "No se pudo iniciar WebRTC");
1457
+ return;
1458
+ }
1459
+ R(""), B(m.getRender().track);
1460
+ let h = gt();
1461
+ N.current = h, h.setMuted(H || !f() || u.current);
1462
+ let g = ne.current, _ = () => {
1463
+ g.clear();
1464
+ }, v = (e, t) => {
1465
+ !/^(INPUT|TEXTAREA|SELECT)$/.test(e.target?.tagName) && vt.includes(e.code) && (e.preventDefault(), t ? g.add(e.code) : g.delete(e.code));
1466
+ }, y = (e) => v(e, !0), x = (e) => v(e, !1), S = d.current;
1467
+ S.addEventListener("keydown", y), S.addEventListener("keyup", x), S.addEventListener("blur", _);
1468
+ let C = () => {
1469
+ document.hidden && _();
1470
+ };
1471
+ document.addEventListener("visibilitychange", C);
1472
+ let w = (e) => h.playCue(e);
1473
+ function ee(e) {
1474
+ if (n) return;
1475
+ let t = Math.min(80, e - a);
1476
+ a = e;
1477
+ let r = u.current || document.hidden, c = P.current, l = (...e) => e.some((e) => g.has(e)), d = r ? {
1478
+ throttle: 0,
1479
+ brake: 0,
1480
+ steer: 0,
1481
+ handbrake: !1
1482
+ } : {
1483
+ throttle: l("KeyW", "ArrowUp") || c.accel ? 1 : 0,
1484
+ brake: l("KeyS", "ArrowDown") || c.brake ? 1 : 0,
1485
+ steer: yt(Number(l("KeyA", "ArrowLeft")) - Number(l("KeyD", "ArrowRight")) - c.steer),
1486
+ handbrake: l("Space") || c.handbrake
1487
+ };
1488
+ m.setInput(d), m.step(t);
1489
+ let f = m.getRender();
1490
+ r || M.current?.render(f, t);
1491
+ let _ = f.cars?.find((e) => e.self);
1492
+ if (f.phase === "racing" || f.phase === "countdown") {
1493
+ let e = Math.abs(_?.speed || 0);
1494
+ h.setEngine({
1495
+ speed: e,
1496
+ rpm: Math.min(1, e / (f.topSpeed || 16.5)),
1497
+ throttle: d.throttle,
1498
+ drifting: d.handbrake && e > 8
1499
+ });
1500
+ } else h.setEngine(null);
1501
+ for (let e of f.events || []) {
1502
+ let t = Se(e);
1503
+ t === "countdown" ? (p || (p = !0, w("engine_start")), w("countdown")) : t === "go" ? (w("go"), h.setMusic(s ? "final_lap" : "circuit")) : t === "collision" ? w("collision") : (t === "boost" || t === "turbo") && e.self !== !1 ? w("turbo") : t === "lap" && e.self ? w("lap") : t === "final_lap" && e.self ? (s = !0, w("final_lap"), h.setMusic("final_lap")) : t === "finish" && e.self ? w("finish") : t === "result" ? (p = !1, h.setMusic("off"), h.setEngine(null), w(e.self ? "victory" : "defeat")) : t === "pause" ? h.setMusic("off") : t === "resume" && h.setMusic(s ? "final_lap" : "circuit");
1504
+ }
1505
+ (e - o > 100 || f.phase === "finished") && (o = e, I(f)), i = requestAnimationFrame(ee);
1506
+ }
1507
+ return i = requestAnimationFrame(ee), () => {
1508
+ n = !0, cancelAnimationFrame(i), _(), m.destroy(), b.current = null, h.dispose(), N.current === h && (N.current = null), S.removeEventListener("keydown", y), S.removeEventListener("keyup", x), S.removeEventListener("blur", _), document.removeEventListener("visibilitychange", C);
1509
+ };
1510
+ }, [
1511
+ W,
1512
+ t,
1513
+ r
1514
+ ]), !l) return null;
1515
+ let K = g(r, l.guestId), _e = K || g(r, l.hostId), ve = h(l), q = l.raceConfig, J = F?.net, ye = J?.manualTurn, be = F?.phase || "connecting", Y = be === "finished", X = [
1516
+ "waiting_peer",
1517
+ "sharing",
1518
+ "applying"
1519
+ ].includes(ye?.status), Z = !G && (ce >= 12e3 || J?.phase === "failed" || J?.ice === "failed" || ye?.status === "failed" || !!L), Ce = G ? J?.route?.relay === !0 ? "TURN" : J?.route?.relay === !1 ? "Directo" : "Conectado" : Ct(J), we = F?.cars?.find((e) => e.self), Te = Y && String(F?.winner) === String(r), Ee = F?.lapTimes?.length ? Math.min(...F.lapTimes) : null, De = () => {
1520
+ N.current?.unlock();
1521
+ }, Oe = async (e, t) => {
1522
+ if (!b.current?.configureTurn) throw Error("La carrera aún no está preparada. Espera un momento.");
1523
+ await b.current.configureTurn(e, t);
1524
+ }, ke = async () => {
1525
+ if (!me) {
1526
+ he(!0);
1527
+ try {
1528
+ let n = e.getState();
1529
+ if (n.raceRematch) await n.raceRematch(t);
1530
+ else {
1531
+ h(n.games[t]) || await n.act(t, "game_end");
1532
+ let e = g(r, l.hostId) ? l.guestId : l.hostId;
1533
+ await n.invite({
1534
+ roomId: l.roomId,
1535
+ opponentId: e,
1536
+ gameType: "racing_live",
1537
+ rematchOf: l.gameId,
1538
+ speedClass: l.raceConfig?.speedClass ?? null,
1539
+ ...l.raceConfig?.trackId ? { trackId: l.raceConfig.trackId } : {}
1540
+ });
1541
+ }
1542
+ } catch (e) {
1543
+ R(e.message || "No se pudo enviar la revancha");
1544
+ } finally {
1545
+ he(!1);
1546
+ }
1547
+ }
1548
+ }, Ae = (e) => {
1549
+ let t = e.currentTarget.getBoundingClientRect(), n = yt((e.clientX - t.left - t.width / 2) / (t.width / 2 * .8));
1550
+ P.current.steer = n, U(n);
1551
+ }, je = () => {
1552
+ P.current.steer = 0, U(0);
1553
+ }, Me = (e) => ({
1554
+ onPointerDown: (t) => {
1555
+ t.preventDefault(), De(), t.currentTarget.setPointerCapture(t.pointerId), P.current[e] = !0;
1556
+ },
1557
+ onPointerUp: () => {
1558
+ P.current[e] = !1;
1559
+ },
1560
+ onPointerCancel: () => {
1561
+ P.current[e] = !1;
1562
+ },
1563
+ onLostPointerCapture: () => {
1564
+ P.current[e] = !1;
1565
+ },
1566
+ onContextMenu: (e) => e.preventDefault()
1567
+ });
1568
+ return /* @__PURE__ */ E("section", {
1569
+ className: `chat-game-card tl-card rl-card${W ? " tl-card--active" : ""}`,
1570
+ "aria-label": "Carreras LIVE",
1571
+ onPointerDownCapture: De,
1572
+ onKeyDownCapture: De,
1573
+ children: [
1574
+ /* @__PURE__ */ E("header", {
1575
+ className: "tl-header",
1576
+ children: [/* @__PURE__ */ T("strong", { children: "Carreras LIVE 🏎️" }), /* @__PURE__ */ E("div", {
1577
+ className: "tl-header-actions",
1578
+ children: [
1579
+ W && /* @__PURE__ */ T("button", {
1580
+ type: "button",
1581
+ onClick: () => ue((e) => !e),
1582
+ "aria-pressed": H,
1583
+ "aria-label": H ? "Activar sonido de la carrera" : "Silenciar carrera",
1584
+ children: T(H || !de ? j : A, { size: 16 })
1585
+ }),
1586
+ i && /* @__PURE__ */ T("button", {
1587
+ type: "button",
1588
+ onClick: i,
1589
+ "aria-label": "Minimizar",
1590
+ children: "−"
1591
+ }),
1592
+ a && /* @__PURE__ */ T("button", {
1593
+ type: "button",
1594
+ onClick: a,
1595
+ "aria-label": "Ocultar",
1596
+ children: "×"
1597
+ })
1598
+ ]
1599
+ })]
1600
+ }),
1601
+ l.status === "invited" && /* @__PURE__ */ E("div", {
1602
+ className: "tl-invite",
1603
+ children: [
1604
+ /* @__PURE__ */ T("span", {
1605
+ className: "tl-invite-icon",
1606
+ "aria-hidden": "true",
1607
+ children: "🏎️"
1608
+ }),
1609
+ /* @__PURE__ */ T("strong", { children: K ? "¿Listo para correr?" : "Invitación enviada" }),
1610
+ q?.speedClass && /* @__PURE__ */ T("span", {
1611
+ className: "rl-class-badge rl-class-badge--large",
1612
+ children: q.speedClass
1613
+ }),
1614
+ /* @__PURE__ */ T("p", { children: q ? `Carrera Clásica · ${q.trackId ? `${o[q.trackId] || q.trackId} ${n[q.trackId] || ""}` : xt[q.mapId] || q.mapId} · ${q.laps} vueltas${q.speedClass ? ` · ${St[q.speedClass] || ""}` : ""}` : "" }),
1615
+ /* @__PURE__ */ T("p", { children: K ? "Te retaron a una carrera en tiempo real." : "Esperando que el rival acepte…" }),
1616
+ K && /* @__PURE__ */ E("div", {
1617
+ className: "tl-invite-actions",
1618
+ children: [/* @__PURE__ */ T("button", {
1619
+ className: "tl-button-primary",
1620
+ disabled: l.pending,
1621
+ onClick: () => bt(t, "game_accept"),
1622
+ children: "Aceptar carrera"
1623
+ }), /* @__PURE__ */ T("button", {
1624
+ disabled: l.pending,
1625
+ onClick: () => bt(t, "game_decline"),
1626
+ children: "Rechazar"
1627
+ })]
1628
+ })
1629
+ ]
1630
+ }),
1631
+ W && !Y && !G && /* @__PURE__ */ E("div", {
1632
+ className: `tl-connection tl-connection--${Z ? "problem" : "pending"}`,
1633
+ children: [
1634
+ /* @__PURE__ */ E("div", {
1635
+ className: "tl-connection-heading",
1636
+ children: [Z ? /* @__PURE__ */ T(D, {
1637
+ size: 18,
1638
+ "aria-hidden": "true"
1639
+ }) : /* @__PURE__ */ T(O, {
1640
+ size: 18,
1641
+ className: "tl-connection-spinner",
1642
+ "aria-hidden": "true"
1643
+ }), /* @__PURE__ */ T("div", { children: /* @__PURE__ */ T("strong", { children: Z ? "Problemas de conexión" : Ct(J) }) })]
1644
+ }),
1645
+ /* @__PURE__ */ T("p", {
1646
+ className: "tl-connection-message",
1647
+ role: "status",
1648
+ children: J?.error === "track_mismatch" ? "El circuito no coincide entre los dos jugadores. Cierra y vuelve a invitar." : _(J)
1649
+ }),
1650
+ /* @__PURE__ */ E("div", {
1651
+ className: "tl-connection-actions",
1652
+ children: [/* @__PURE__ */ E("button", {
1653
+ type: "button",
1654
+ className: Z ? "tl-button-primary" : "",
1655
+ onClick: () => se(!0),
1656
+ children: [/* @__PURE__ */ T(k, {
1657
+ size: 15,
1658
+ "aria-hidden": "true"
1659
+ }), "Usar TURN"]
1660
+ }), /* @__PURE__ */ E("button", {
1661
+ type: "button",
1662
+ disabled: X,
1663
+ onClick: () => b.current?.reconnect(),
1664
+ children: [/* @__PURE__ */ T(te, {
1665
+ size: 15,
1666
+ "aria-hidden": "true"
1667
+ }), "Reintentar"]
1668
+ })]
1669
+ })
1670
+ ]
1671
+ }),
1672
+ /* @__PURE__ */ T(v, {
1673
+ open: V && W && !Y,
1674
+ onClose: () => se(!1),
1675
+ onApply: Oe,
1676
+ manualTurn: ye
1677
+ }),
1678
+ W && /* @__PURE__ */ E(ee, { children: [
1679
+ /* @__PURE__ */ E("div", {
1680
+ className: "rl-stage-wrap",
1681
+ children: [
1682
+ /* @__PURE__ */ T("div", {
1683
+ className: "tl-stage rl-stage",
1684
+ ref: d,
1685
+ tabIndex: 0,
1686
+ "aria-label": "Circuito. W/flecha arriba acelera, S/flecha abajo frena, A/D o flechas giran, espacio freno de mano",
1687
+ onPointerDown: (e) => {
1688
+ e.pointerType === "mouse" && e.currentTarget.focus();
1689
+ }
1690
+ }),
1691
+ /* @__PURE__ */ E("div", {
1692
+ className: "rl-hud",
1693
+ "aria-live": "off",
1694
+ children: [
1695
+ (F?.speedClass ?? q?.speedClass) && /* @__PURE__ */ T("span", {
1696
+ className: "rl-class-badge",
1697
+ children: F?.speedClass ?? q?.speedClass
1698
+ }),
1699
+ /* @__PURE__ */ E("span", { children: [
1700
+ /* @__PURE__ */ T("b", { children: "Vuelta" }),
1701
+ " ",
1702
+ F?.lap ?? 1,
1703
+ "/",
1704
+ F?.laps ?? q?.laps ?? 3
1705
+ ] }),
1706
+ /* @__PURE__ */ E("span", { children: [
1707
+ /* @__PURE__ */ T("b", { children: "Pos." }),
1708
+ " ",
1709
+ F?.position === 1 ? "1.º" : F?.position === 2 ? "2.º" : "–"
1710
+ ] }),
1711
+ /* @__PURE__ */ E("span", { children: [/* @__PURE__ */ T("b", { children: Math.round(Math.abs(we?.speed || 0) * 3.6) }), " km/h"] }),
1712
+ /* @__PURE__ */ T("span", { children: xe(F?.raceTimeMs) }),
1713
+ /* @__PURE__ */ E("span", {
1714
+ className: "rl-net",
1715
+ children: [Ce, Number.isFinite(J?.rtt) ? ` · ${Math.round(J.rtt)} ms` : ""]
1716
+ })
1717
+ ]
1718
+ }),
1719
+ be === "countdown" && /* @__PURE__ */ T("div", {
1720
+ className: "rl-overlay rl-countdown",
1721
+ role: "status",
1722
+ children: F.countdown > 0 ? F.countdown : "¡YA!"
1723
+ }),
1724
+ be === "ready" && /* @__PURE__ */ T("div", {
1725
+ className: "rl-overlay rl-banner",
1726
+ role: "status",
1727
+ children: "¿Listos?"
1728
+ }),
1729
+ be === "paused" && /* @__PURE__ */ E("div", {
1730
+ className: "rl-overlay rl-banner",
1731
+ role: "status",
1732
+ children: ["Pausa", F?.countdown > 0 ? ` · ${F.countdown}` : ""]
1733
+ }),
1734
+ Y && /* @__PURE__ */ E("div", {
1735
+ className: "rl-overlay rl-finish",
1736
+ role: "status",
1737
+ children: [
1738
+ /* @__PURE__ */ T("strong", { children: Te ? "🏆 ¡Ganaste!" : "🏁 Ganó el rival" }),
1739
+ F?.reason === "resigned" && /* @__PURE__ */ T("p", { children: Te ? "El rival abandonó." : "Abandonaste la carrera." }),
1740
+ /* @__PURE__ */ E("dl", { children: [
1741
+ /* @__PURE__ */ T("dt", { children: "Tiempo" }),
1742
+ /* @__PURE__ */ T("dd", { children: xe(F?.lapTimes?.length === F?.laps ? F.lapTimes.reduce((e, t) => e + t, 0) : F?.raceTimeMs) }),
1743
+ Ee != null && /* @__PURE__ */ E(ee, { children: [/* @__PURE__ */ T("dt", { children: "Mejor vuelta" }), /* @__PURE__ */ T("dd", { children: xe(Ee) })] })
1744
+ ] }),
1745
+ /* @__PURE__ */ E("div", {
1746
+ className: "rl-finish-actions",
1747
+ children: [/* @__PURE__ */ T("button", {
1748
+ type: "button",
1749
+ className: "tl-button-primary",
1750
+ disabled: me || !_e,
1751
+ onClick: ke,
1752
+ children: "Revancha"
1753
+ }), /* @__PURE__ */ T("button", {
1754
+ type: "button",
1755
+ onClick: () => bt(t, "game_end"),
1756
+ children: "Cerrar"
1757
+ })]
1758
+ })
1759
+ ]
1760
+ })
1761
+ ]
1762
+ }),
1763
+ /* @__PURE__ */ E("div", {
1764
+ className: "rl-controls",
1765
+ "aria-label": "Controles táctiles",
1766
+ children: [/* @__PURE__ */ T("div", {
1767
+ className: "rl-stick",
1768
+ role: "slider",
1769
+ "aria-label": "Volante",
1770
+ "aria-valuemin": -1,
1771
+ "aria-valuemax": 1,
1772
+ "aria-valuenow": Math.round(pe * 10) / 10,
1773
+ onPointerDown: (e) => {
1774
+ e.preventDefault(), De(), e.currentTarget.setPointerCapture(e.pointerId), Ae(e);
1775
+ },
1776
+ onPointerMove: (e) => {
1777
+ e.currentTarget.hasPointerCapture(e.pointerId) && Ae(e);
1778
+ },
1779
+ onPointerUp: je,
1780
+ onPointerCancel: je,
1781
+ onLostPointerCapture: je,
1782
+ children: /* @__PURE__ */ T("span", {
1783
+ className: "rl-stick-knob",
1784
+ style: { transform: `translateX(${pe * 34}px)` }
1785
+ })
1786
+ }), /* @__PURE__ */ E("div", {
1787
+ className: "rl-pedals",
1788
+ children: [
1789
+ /* @__PURE__ */ T("button", {
1790
+ type: "button",
1791
+ className: "rl-drift",
1792
+ "aria-label": "Freno de mano",
1793
+ ...Me("handbrake"),
1794
+ children: "Derrape"
1795
+ }),
1796
+ /* @__PURE__ */ T("button", {
1797
+ type: "button",
1798
+ className: "rl-brake",
1799
+ "aria-label": "Frenar",
1800
+ ...Me("brake"),
1801
+ children: "Freno"
1802
+ }),
1803
+ /* @__PURE__ */ T("button", {
1804
+ type: "button",
1805
+ className: "rl-accel",
1806
+ "aria-label": "Acelerar",
1807
+ ...Me("accel"),
1808
+ children: "Gas"
1809
+ })
1810
+ ]
1811
+ })]
1812
+ }),
1813
+ /* @__PURE__ */ T("small", { children: "WASD / flechas para conducir · espacio: freno de mano · toca el circuito para usar el teclado" }),
1814
+ /* @__PURE__ */ E("div", {
1815
+ className: "rl-tools",
1816
+ children: [
1817
+ /* @__PURE__ */ T("button", {
1818
+ type: "button",
1819
+ onClick: () => re((e) => !e),
1820
+ children: ie === "2d" ? "Probar 3D" : "Vista 2D"
1821
+ }),
1822
+ G && !Y && /* @__PURE__ */ E("button", {
1823
+ type: "button",
1824
+ onClick: () => se(!0),
1825
+ children: [/* @__PURE__ */ T(k, {
1826
+ size: 15,
1827
+ "aria-hidden": "true"
1828
+ }), "Usar TURN"]
1829
+ }),
1830
+ !Y && /* @__PURE__ */ T("button", {
1831
+ type: "button",
1832
+ onClick: () => b.current?.resign(),
1833
+ children: "Abandonar"
1834
+ })
1835
+ ]
1836
+ }),
1837
+ /* @__PURE__ */ E("details", {
1838
+ className: "tl-diagnostics",
1839
+ children: [/* @__PURE__ */ T("summary", { children: "Diagnóstico de conexión" }), /* @__PURE__ */ T("pre", { children: JSON.stringify(y(J), null, 2) })]
1840
+ })
1841
+ ] }),
1842
+ l.pending && /* @__PURE__ */ T("p", {
1843
+ role: "status",
1844
+ children: "Enviando…"
1845
+ }),
1846
+ l.pendingEvent && l.error && /* @__PURE__ */ T("button", {
1847
+ onClick: () => {
1848
+ e.getState().retry(t).catch(() => {});
1849
+ },
1850
+ children: "Reintentar envío"
1851
+ }),
1852
+ L && /* @__PURE__ */ T("p", {
1853
+ role: "alert",
1854
+ children: L
1855
+ }),
1856
+ l.error && /* @__PURE__ */ T("p", {
1857
+ role: "alert",
1858
+ children: l.error
1859
+ }),
1860
+ !ve && _e && /* @__PURE__ */ T("footer", {
1861
+ className: "tl-footer",
1862
+ children: /* @__PURE__ */ T("button", {
1863
+ onClick: () => bt(t, "game_end"),
1864
+ children: l.status === "invited" ? "Cerrar invitación" : "Cerrar carrera"
1865
+ })
1866
+ })
1867
+ ]
1868
+ });
1869
+ }
1870
+ var Tt = b(wt);
1871
+ export { q as a, N as c, Tt as default, be as i, ze as n, Se as o, K as r, ve as s, _t as t };
1872
+
1873
+ //# sourceMappingURL=RacingLiveGameCard-_wvhDRlG.js.map