@gamebob/axon-surge 0.15.0 → 0.16.0

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.
@@ -1,4 +1,4 @@
1
- class F {
1
+ class W {
2
2
  listeners = /* @__PURE__ */ new Map();
3
3
  on(t, e) {
4
4
  return this.listeners.has(t) || this.listeners.set(t, /* @__PURE__ */ new Set()), this.listeners.get(t).add(e), () => this.off(t, e);
@@ -15,28 +15,41 @@ class F {
15
15
  this.listeners.clear();
16
16
  }
17
17
  }
18
- class W {
18
+ class Y {
19
19
  animationFrameId = null;
20
20
  lastTime = 0;
21
+ nextFrameTime = 0;
21
22
  isRunning = !1;
23
+ fpsLimit = 60;
22
24
  updateCallback;
23
25
  renderCallback;
24
26
  constructor(t, e) {
25
27
  this.updateCallback = t, this.renderCallback = e;
26
28
  }
27
29
  start() {
28
- this.isRunning || (this.isRunning = !0, this.lastTime = performance.now(), this.tick = this.tick.bind(this), this.animationFrameId = requestAnimationFrame(this.tick));
30
+ this.isRunning || (this.isRunning = !0, this.lastTime = performance.now(), this.nextFrameTime = this.lastTime, this.tick = this.tick.bind(this), this.animationFrameId = requestAnimationFrame(this.tick));
29
31
  }
30
32
  stop() {
31
33
  this.isRunning = !1, this.animationFrameId !== null && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null);
32
34
  }
35
+ setFpsLimit(t) {
36
+ this.fpsLimit = t, this.lastTime = performance.now(), this.nextFrameTime = this.lastTime;
37
+ }
38
+ getFpsLimit() {
39
+ return this.fpsLimit;
40
+ }
33
41
  tick(t) {
34
42
  if (!this.isRunning) return;
35
- const e = Math.min((t - this.lastTime) / 1e3, 0.1);
36
- this.lastTime = t, this.updateCallback(e), this.renderCallback(), this.animationFrameId = requestAnimationFrame(this.tick);
43
+ const e = 1e3 / this.fpsLimit;
44
+ if (t + 0.25 < this.nextFrameTime) {
45
+ this.animationFrameId = requestAnimationFrame(this.tick);
46
+ return;
47
+ }
48
+ const i = Math.min((t - this.lastTime) / 1e3, 0.1);
49
+ this.lastTime = t, this.nextFrameTime += e, this.nextFrameTime < t - e && (this.nextFrameTime = t + e), this.updateCallback(i), this.renderCallback(), this.animationFrameId = requestAnimationFrame(this.tick);
37
50
  }
38
51
  }
39
- const U = {
52
+ const G = {
40
53
  core: {
41
54
  maxIntegrity: 3,
42
55
  invulnerabilityDuration: 1.5,
@@ -85,14 +98,14 @@ const U = {
85
98
  absorptionSpeed: 680
86
99
  }
87
100
  };
88
- class E {
101
+ class A {
89
102
  static instance;
90
103
  config;
91
104
  constructor() {
92
- this.config = JSON.parse(JSON.stringify(U));
105
+ this.config = JSON.parse(JSON.stringify(G));
93
106
  }
94
107
  static getInstance() {
95
- return E.instance || (E.instance = new E()), E.instance;
108
+ return A.instance || (A.instance = new A()), A.instance;
96
109
  }
97
110
  getConfig() {
98
111
  return this.config;
@@ -110,10 +123,10 @@ class E {
110
123
  this.config.core.maxIntegrity += t;
111
124
  }
112
125
  resetToDefault() {
113
- this.config = JSON.parse(JSON.stringify(U));
126
+ this.config = JSON.parse(JSON.stringify(G));
114
127
  }
115
128
  }
116
- class Y {
129
+ class Z {
117
130
  position;
118
131
  radius;
119
132
  integrity;
@@ -126,7 +139,7 @@ class Y {
126
139
  powerUpCount = 0;
127
140
  collectedPowerUpColors = [];
128
141
  constructor(t, e) {
129
- const i = E.getInstance().getConfig().core;
142
+ const i = A.getInstance().getConfig().core;
130
143
  this.position = { x: t, y: e }, this.radius = i.radius, this.integrity = i.maxIntegrity, this.maxIntegrity = i.maxIntegrity, this.maxInvulnerabilityDuration = i.invulnerabilityDuration, this.organicSeed = Math.random() * 100;
131
144
  }
132
145
  absorbPowerUpColor(t, e = 0.35) {
@@ -153,7 +166,7 @@ class Y {
153
166
  }
154
167
  repairProgress = 0;
155
168
  addKillRepair() {
156
- const t = E.getInstance().getConfig().core.vampirismHealProgressRate;
169
+ const t = A.getInstance().getConfig().core.vampirismHealProgressRate;
157
170
  return t <= 0 ? !1 : (this.repairProgress += t, this.repairProgress >= 1 ? (this.integrity += 1, this.integrity > this.maxIntegrity && (this.maxIntegrity = this.integrity), this.repairProgress = 0, !0) : !1);
158
171
  }
159
172
  heal(t = 1) {
@@ -166,11 +179,11 @@ class Y {
166
179
  return this.invulnerabilityTimer > 0 ? !1 : this.integrity > 0 ? (this.integrity -= 1, this.invulnerabilityTimer = this.maxInvulnerabilityDuration, !0) : !1;
167
180
  }
168
181
  reset(t, e) {
169
- const i = E.getInstance().getConfig().core;
182
+ const i = A.getInstance().getConfig().core;
170
183
  this.position = { x: t, y: e }, this.radius = i.radius, this.maxIntegrity = i.maxIntegrity, this.integrity = this.maxIntegrity, this.maxInvulnerabilityDuration = i.invulnerabilityDuration, this.pulsePhase = 0, this.invulnerabilityTimer = 0, this.repairProgress = 0, this.powerUpCount = 0, this.collectedPowerUpColors = [], this.customColor = { r: 0, g: 240, b: 255 };
171
184
  }
172
185
  }
173
- class w {
186
+ class U {
174
187
  id;
175
188
  position = { x: 0, y: 0 };
176
189
  velocity = { x: 0, y: 0 };
@@ -229,7 +242,7 @@ class w {
229
242
  this.active = !1, this.isGrabbed = !1, this.isThrown = !1, this.wasManipulated = !1, this.isDying = !1, this.deathType = "none", this.deathTimer = 0, this.sliceAngle = 0, this.isStationaryShield = !1, this.shieldAngle = 0, this.launchDelay = 0, this.experienceDropPending = !1, this.position = { x: 0, y: 0 }, this.velocity = { x: 0, y: 0 }, this.rotation = 0, this.strategy = null, this.maxSpeed = 200;
230
243
  }
231
244
  }
232
- class G {
245
+ class H {
233
246
  id;
234
247
  definition;
235
248
  position = { x: 0, y: 0 };
@@ -246,7 +259,7 @@ class G {
246
259
  this.active && !this.isGrabbed && !this.isHovered && (this.orbitAngle += t * 0.25, this.position.x = e.x + Math.cos(this.orbitAngle) * this.orbitDistance, this.position.y = e.y + Math.sin(this.orbitAngle) * this.orbitDistance);
247
260
  }
248
261
  }
249
- class Z {
262
+ class $ {
250
263
  pointerPosition = { x: 0, y: 0 };
251
264
  isPointerDown = !1;
252
265
  grabbedEnemy = null;
@@ -345,10 +358,10 @@ class Z {
345
358
  } else if (this.dragStart) {
346
359
  const o = t.position.x - this.dragStart.x, r = t.position.y - this.dragStart.y, c = Math.hypot(o, r);
347
360
  if (c > 5) {
348
- const h = Math.atan2(r, o), u = Math.min(c * 4, 600);
361
+ const h = Math.atan2(r, o), p = Math.min(c * 4, 600);
349
362
  t.velocity = {
350
- x: Math.cos(h) * u,
351
- y: Math.sin(h) * u
363
+ x: Math.cos(h) * p,
364
+ y: Math.sin(h) * p
352
365
  };
353
366
  } else
354
367
  t.velocity = { x: 0, y: 0 }, t.isThrown = !1;
@@ -356,7 +369,7 @@ class Z {
356
369
  if (t.type === "heavy")
357
370
  t.shieldAngle = t.rotation, t.velocity = { x: 0, y: 0 }, t.isStationaryShield = !0, t.isThrown = !1;
358
371
  else if (t.type === "piercer") {
359
- const o = E.getInstance().getConfig().piercer;
372
+ const o = A.getInstance().getConfig().piercer;
360
373
  o.hasHoming && (t.remainingHomingKills = o.homingTargets);
361
374
  }
362
375
  return this.grabbedEnemy = null, this.dragStart = null, this.pointerHistory = [], t;
@@ -390,20 +403,18 @@ class z {
390
403
  for (let o = s; o <= a; o++)
391
404
  for (let r = l; r <= n; r++) {
392
405
  const c = `${o}:${r}`, h = this.grid.get(c);
393
- h && h.forEach((u) => i.add(u));
406
+ h && h.forEach((p) => i.add(p));
394
407
  }
395
408
  return i;
396
409
  }
397
410
  }
398
411
  class J {
399
- hitstopTime = 0;
400
412
  shakeTime = 0;
401
413
  shakeDuration = 0.14;
402
414
  shakeIntensity = 0;
403
415
  shakeVector = { x: 0, y: 0 };
404
416
  flashAlpha = 0;
405
417
  triggerHitstop(t = 0.06) {
406
- this.hitstopTime = 0;
407
418
  }
408
419
  triggerFlash(t = 0.4) {
409
420
  this.flashAlpha = t;
@@ -416,7 +427,7 @@ class J {
416
427
  }, this.shakeIntensity = s, this.shakeTime = this.shakeDuration;
417
428
  }
418
429
  update(t, e, i) {
419
- this.hitstopTime > 0 && (this.hitstopTime -= t), this.shakeTime > 0 && (this.shakeTime -= t), this.flashAlpha > 0 && (this.flashAlpha = Math.max(0, this.flashAlpha - t * 4)), e.length > 25 && e.splice(0, e.length - 25), i.length > 120 && i.splice(0, i.length - 120);
430
+ this.shakeTime > 0 && (this.shakeTime -= t), this.flashAlpha > 0 && (this.flashAlpha = Math.max(0, this.flashAlpha - t * 4)), e.length > 25 && e.splice(0, e.length - 25), i.length > 120 && i.splice(0, i.length - 120);
420
431
  for (let s = e.length - 1; s >= 0; s--) {
421
432
  const a = e[s];
422
433
  a && (a.lifetime += t, a.position.x += a.velocity.x * t, a.position.y += a.velocity.y * t, a.alpha = 1 - a.lifetime / a.maxLifetime, a.lifetime >= a.maxLifetime && e.splice(s, 1));
@@ -435,7 +446,7 @@ class J {
435
446
  };
436
447
  }
437
448
  }
438
- const O = {
449
+ const D = {
439
450
  es: {
440
451
  title: "AXON SURGE",
441
452
  startButton: "INICIAR ENLACE",
@@ -445,6 +456,7 @@ const O = {
445
456
  languageLabel: "IDIOMA",
446
457
  themeLabel: "TEMA VISUAL",
447
458
  hapticsLabel: "VIBRACIÓN / HÁPTICOS",
459
+ fpsLimitLabel: "LÍMITE DE FPS",
448
460
  hapticsOn: "ACTIVADO",
449
461
  hapticsOff: "DESACTIVADO",
450
462
  creditsJam: "Desarrollado para Mini Jam 216: Axon Surge",
@@ -510,6 +522,7 @@ const O = {
510
522
  languageLabel: "LANGUAGE",
511
523
  themeLabel: "VISUAL THEME",
512
524
  hapticsLabel: "HAPTICS / VIBRATION",
525
+ fpsLimitLabel: "FPS LIMIT",
513
526
  hapticsOn: "ENABLED",
514
527
  hapticsOff: "DISABLED",
515
528
  creditsJam: "Developed for Mini Jam 216: Axon Surge",
@@ -1298,29 +1311,29 @@ const O = {
1298
1311
  "ko",
1299
1312
  "zh"
1300
1313
  ];
1301
- function N(A) {
1302
- return V.includes(A);
1314
+ function w(E) {
1315
+ return V.includes(E);
1303
1316
  }
1304
- const H = "axon_surge_language";
1305
- class $ {
1317
+ const B = "axon_surge_language";
1318
+ class X {
1306
1319
  currentLanguage;
1307
1320
  constructor(t) {
1308
1321
  this.currentLanguage = this.detectLanguage(t);
1309
1322
  }
1310
1323
  detectLanguage(t) {
1311
1324
  try {
1312
- const e = localStorage.getItem(H);
1313
- if (e && N(e))
1325
+ const e = localStorage.getItem(B);
1326
+ if (e && w(e))
1314
1327
  return e;
1315
1328
  } catch {
1316
1329
  }
1317
- if (t && N(t))
1330
+ if (t && w(t))
1318
1331
  return t;
1319
1332
  try {
1320
1333
  const e = (document.documentElement.lang || document.body?.getAttribute("lang") || document.documentElement.getAttribute("data-lang") || "").toLowerCase();
1321
1334
  if (e) {
1322
1335
  const i = e.split("-")[0];
1323
- if (i && N(i))
1336
+ if (i && w(i))
1324
1337
  return i;
1325
1338
  }
1326
1339
  } catch {
@@ -1329,7 +1342,7 @@ class $ {
1329
1342
  const e = (navigator.language || navigator.languages && navigator.languages[0] || "").toLowerCase();
1330
1343
  if (e) {
1331
1344
  const i = e.split("-")[0];
1332
- if (i && N(i))
1345
+ if (i && w(i))
1333
1346
  return i;
1334
1347
  }
1335
1348
  } catch {
@@ -1337,10 +1350,10 @@ class $ {
1337
1350
  return "en";
1338
1351
  }
1339
1352
  setLanguage(t) {
1340
- if (O[t]) {
1353
+ if (D[t]) {
1341
1354
  this.currentLanguage = t;
1342
1355
  try {
1343
- localStorage.setItem(H, t);
1356
+ localStorage.setItem(B, t);
1344
1357
  } catch {
1345
1358
  }
1346
1359
  }
@@ -1349,15 +1362,15 @@ class $ {
1349
1362
  return this.currentLanguage;
1350
1363
  }
1351
1364
  translate(t, e) {
1352
- let s = (O[this.currentLanguage] || O.en)[t] || O.en[t] || String(t);
1365
+ let s = (D[this.currentLanguage] || D.en)[t] || D.en[t] || String(t);
1353
1366
  return e && Object.entries(e).forEach(([a, l]) => {
1354
1367
  s = s.replace(`{${a}}`, String(l));
1355
1368
  }), s;
1356
1369
  }
1357
1370
  }
1358
- class X {
1371
+ class j {
1359
1372
  static update(t, e, i) {
1360
- const s = E.getInstance().getConfig();
1373
+ const s = A.getInstance().getConfig();
1361
1374
  for (let a = t.length - 1; a >= 0; a--) {
1362
1375
  const l = t[a];
1363
1376
  if (l) {
@@ -1366,7 +1379,7 @@ class X {
1366
1379
  if (!n.active || n.isGrabbed || n.isDying || n.isStationaryShield || n.launchDelay > 0 || n.isThrown && n.type === "piercer") continue;
1367
1380
  const o = l.position.x - n.position.x, r = l.position.y - n.position.y, c = o * o + r * r, h = Math.sqrt(c);
1368
1381
  if (h > 2 && c <= l.radius * l.radius) {
1369
- const u = Math.pow(1 - h / l.radius, 0.7), d = l.pullForce * u, _ = Math.atan2(r, o);
1382
+ const p = Math.pow(1 - h / l.radius, 0.7), d = l.pullForce * p, _ = Math.atan2(r, o);
1370
1383
  n.velocity.x += Math.cos(_) * d * i, n.velocity.y += Math.sin(_) * d * i, n.position.x += Math.cos(_) * d * i * 0.8, n.position.y += Math.sin(_) * d * i * 0.8;
1371
1384
  }
1372
1385
  }
@@ -1376,10 +1389,10 @@ class X {
1376
1389
  if (!n.active || n.isDying) continue;
1377
1390
  const o = n.position.x - l.position.x, r = n.position.y - l.position.y;
1378
1391
  if (o * o + r * r <= l.radius * l.radius) {
1379
- const h = Math.atan2(r, o), u = 1200;
1392
+ const h = Math.atan2(r, o), p = 1200;
1380
1393
  n.isThrown = !0, n.wasManipulated = !0, n.velocity = {
1381
- x: Math.cos(h) * u,
1382
- y: Math.sin(h) * u
1394
+ x: Math.cos(h) * p,
1395
+ y: Math.sin(h) * p
1383
1396
  };
1384
1397
  }
1385
1398
  }
@@ -1389,12 +1402,12 @@ class X {
1389
1402
  }
1390
1403
  }
1391
1404
  }
1392
- class j {
1405
+ class q {
1393
1406
  static update(t, e, i, s, a, l, n, o, r, c) {
1394
1407
  for (const h of e) {
1395
1408
  if (!h.active || h.isGrabbed || h.isDying || h.launchDelay > 0) continue;
1396
- const u = t.position.x - h.position.x, d = t.position.y - h.position.y;
1397
- if (Math.hypot(u, d) <= t.getHitboxRadius() + h.radius) {
1409
+ const p = t.position.x - h.position.x, d = t.position.y - h.position.y;
1410
+ if (Math.hypot(p, d) <= t.getHitboxRadius() + h.radius) {
1398
1411
  if (h.active = !1, t.takeDamage()) {
1399
1412
  n.emit("onCoreDamaged", { currentIntegrity: t.integrity }), i.push({
1400
1413
  id: Math.random().toString(),
@@ -1405,16 +1418,16 @@ class j {
1405
1418
  alpha: 1,
1406
1419
  lifetime: 0,
1407
1420
  maxLifetime: 0.8
1408
- }), l.triggerScreenShake({ x: u, y: d }, 25), l.triggerHitstop(0.15), l.triggerFlash(0.6);
1409
- for (const p of e)
1410
- if (p.active && !p.isGrabbed && p.launchDelay <= 0) {
1411
- p.triggerDissolveDeath();
1421
+ }), l.triggerScreenShake({ x: p, y: d }, 25), l.triggerHitstop(0.15), l.triggerFlash(0.6);
1422
+ for (const u of e)
1423
+ if (u.active && !u.isGrabbed && u.launchDelay <= 0) {
1424
+ u.triggerDissolveDeath();
1412
1425
  for (let g = 0; g < 8; g++) {
1413
- const m = Math.random() * Math.PI * 2, y = 100 + Math.random() * 200;
1426
+ const f = Math.random() * Math.PI * 2, b = 100 + Math.random() * 200;
1414
1427
  s.push({
1415
1428
  id: Math.random().toString(),
1416
- position: { ...p.position },
1417
- velocity: { x: Math.cos(m) * y, y: Math.sin(m) * y },
1429
+ position: { ...u.position },
1430
+ velocity: { x: Math.cos(f) * b, y: Math.sin(f) * b },
1418
1431
  color: "#00f0ff",
1419
1432
  radius: 3 + Math.random() * 3,
1420
1433
  alpha: 1,
@@ -1440,7 +1453,7 @@ class j {
1440
1453
  }
1441
1454
  }
1442
1455
  }
1443
- class q {
1456
+ class Q {
1444
1457
  execute(t) {
1445
1458
  const { thrownEnemy: e, targetEnemy: i, shockwaves: s, particles: a, floatingTexts: l } = t;
1446
1459
  i.experienceDropPending = !0, i.active = !1, s.push({
@@ -1479,9 +1492,9 @@ class q {
1479
1492
  });
1480
1493
  }
1481
1494
  }
1482
- class Q {
1495
+ class tt {
1483
1496
  execute(t) {
1484
- const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: l, eventBus: n } = t, o = e.position, r = E.getInstance().getConfig();
1497
+ const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: l, eventBus: n } = t, o = e.position, r = A.getInstance().getConfig();
1485
1498
  i.push({
1486
1499
  id: Math.random().toString(),
1487
1500
  position: { ...o },
@@ -1500,11 +1513,11 @@ class Q {
1500
1513
  maxLifetime: 0.6
1501
1514
  });
1502
1515
  for (let c = 0; c < 45; c++) {
1503
- const h = Math.random() * Math.PI * 2, u = 120 + Math.random() * 260;
1516
+ const h = Math.random() * Math.PI * 2, p = 120 + Math.random() * 260;
1504
1517
  a.push({
1505
1518
  id: Math.random().toString(),
1506
1519
  position: { ...o },
1507
- velocity: { x: Math.cos(h) * u, y: Math.sin(h) * u },
1520
+ velocity: { x: Math.cos(h) * p, y: Math.sin(h) * p },
1508
1521
  color: "#39ff14",
1509
1522
  radius: 4 + Math.random() * 5,
1510
1523
  alpha: 1,
@@ -1525,7 +1538,7 @@ class Q {
1525
1538
  }), e.experienceDropPending = !0, e.active = !1, n.emit("onPoolCreated", { position: o });
1526
1539
  }
1527
1540
  }
1528
- class tt {
1541
+ class et {
1529
1542
  execute(t) {
1530
1543
  const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: n } = t, o = i.position;
1531
1544
  e.experienceDropPending = !0, i.experienceDropPending = !0, e.active = !1, i.active = !1, a.push({
@@ -1538,32 +1551,32 @@ class tt {
1538
1551
  lifetime: 0,
1539
1552
  maxLifetime: 0.6
1540
1553
  });
1541
- const r = E.getInstance().getConfig(), c = r.cluster.fragmentCount, h = r.cluster.hasHoming;
1542
- for (let u = 0; u < c; u++) {
1543
- const d = u * Math.PI * 2 / c, _ = 800 + Math.random() * 300, f = {
1554
+ const r = A.getInstance().getConfig(), c = r.cluster.fragmentCount, h = r.cluster.hasHoming;
1555
+ for (let p = 0; p < c; p++) {
1556
+ const d = p * Math.PI * 2 / c, _ = 800 + Math.random() * 300, m = {
1544
1557
  x: o.x + Math.cos(d) * 45,
1545
1558
  y: o.y + Math.sin(d) * 45
1546
1559
  };
1547
- let p = d;
1560
+ let u = d;
1548
1561
  if (h) {
1549
- let m = null, y = 1 / 0;
1550
- for (const b of s) {
1551
- if (b === e || b === i || !b.active || b.isGrabbed || b.isDying) continue;
1552
- const I = Math.hypot(b.position.x - f.x, b.position.y - f.y);
1553
- I < y && (y = I, m = b);
1562
+ let f = null, b = 1 / 0;
1563
+ for (const y of s) {
1564
+ if (y === e || y === i || !y.active || y.isGrabbed || y.isDying) continue;
1565
+ const v = Math.hypot(y.position.x - m.x, y.position.y - m.y);
1566
+ v < b && (b = v, f = y);
1554
1567
  }
1555
- m && (p = Math.atan2(m.position.y - f.y, m.position.x - f.x));
1568
+ f && (u = Math.atan2(f.position.y - m.y, f.position.x - m.x));
1556
1569
  }
1557
- const g = M.createEnemy("micro", f, {
1558
- x: f.x + Math.cos(p) * 500,
1559
- y: f.y + Math.sin(p) * 500
1570
+ const g = C.createEnemy("micro", m, {
1571
+ x: m.x + Math.cos(u) * 500,
1572
+ y: m.y + Math.sin(u) * 500
1560
1573
  });
1561
1574
  g.isThrown = !0, g.wasManipulated = !0, g.velocity = {
1562
- x: Math.cos(p) * _,
1563
- y: Math.sin(p) * _
1575
+ x: Math.cos(u) * _,
1576
+ y: Math.sin(u) * _
1564
1577
  }, s.push(g);
1565
1578
  }
1566
- for (let u = 0; u < 35; u++) {
1579
+ for (let p = 0; p < 35; p++) {
1567
1580
  const d = Math.random() * Math.PI * 2, _ = 200 + Math.random() * 300;
1568
1581
  l.push({
1569
1582
  id: Math.random().toString(),
@@ -1589,9 +1602,9 @@ class tt {
1589
1602
  });
1590
1603
  }
1591
1604
  }
1592
- class et {
1605
+ class it {
1593
1606
  execute(t) {
1594
- const { thrownEnemy: e, targetEnemy: i, vortices: s, shockwaves: a } = t, l = E.getInstance().getConfig(), n = {
1607
+ const { thrownEnemy: e, targetEnemy: i, vortices: s, shockwaves: a } = t, l = A.getInstance().getConfig(), n = {
1595
1608
  x: (e.position.x + i.position.x) / 2,
1596
1609
  y: (e.position.y + i.position.y) / 2
1597
1610
  };
@@ -1614,21 +1627,21 @@ class et {
1614
1627
  }), e.triggerDissolveDeath(!0), i.triggerDissolveDeath(!0);
1615
1628
  }
1616
1629
  }
1617
- class it {
1630
+ class st {
1618
1631
  execute(t) {
1619
- const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: n } = t, o = i.position.x - e.position.x, r = i.position.y - e.position.y, c = Math.atan2(r, o), h = E.getInstance().getConfig().shield, u = h.blastSpeed || 1400, d = h.isFanBlast ? [0, -h.fanBlastAngle, h.fanBlastAngle] : [0];
1620
- for (const [_, f] of d.entries()) {
1621
- const p = c + f, g = _ === 0 ? e : M.createEnemy(
1632
+ const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: n } = t, o = i.position.x - e.position.x, r = i.position.y - e.position.y, c = Math.atan2(r, o), h = A.getInstance().getConfig().shield, p = h.blastSpeed || 1400, d = h.isFanBlast ? [0, -h.fanBlastAngle, h.fanBlastAngle] : [0];
1633
+ for (const [_, m] of d.entries()) {
1634
+ const u = c + m, g = _ === 0 ? e : C.createEnemy(
1622
1635
  "heavy",
1623
1636
  {
1624
- x: e.position.x + Math.cos(p) * 30,
1625
- y: e.position.y + Math.sin(p) * 30
1637
+ x: e.position.x + Math.cos(u) * 30,
1638
+ y: e.position.y + Math.sin(u) * 30
1626
1639
  },
1627
1640
  { x: 0, y: 0 }
1628
1641
  );
1629
- g.isStationaryShield = !1, g.isThrown = !0, g.wasManipulated = !0, g.shieldAngle = p, g.rotation = p, g.launchDelay = h.isFanBlast ? _ * h.fanBlastInterval : 0, g.velocity = {
1630
- x: Math.cos(p) * u,
1631
- y: Math.sin(p) * u
1642
+ g.isStationaryShield = !1, g.isThrown = !0, g.wasManipulated = !0, g.shieldAngle = u, g.rotation = u, g.launchDelay = h.isFanBlast ? _ * h.fanBlastInterval : 0, g.velocity = {
1643
+ x: Math.cos(u) * p,
1644
+ y: Math.sin(u) * p
1632
1645
  }, g !== e && s.push(g);
1633
1646
  }
1634
1647
  i.active = !1, i.triggerDissolveDeath(!0), n.push({
@@ -1643,11 +1656,11 @@ class it {
1643
1656
  size: 24
1644
1657
  });
1645
1658
  for (let _ = 0; _ < 50; _++) {
1646
- const f = (Math.random() - 0.5) * 1.5, p = c + f, g = 300 + Math.random() * 500;
1659
+ const m = (Math.random() - 0.5) * 1.5, u = c + m, g = 300 + Math.random() * 500;
1647
1660
  l.push({
1648
1661
  id: Math.random().toString(),
1649
1662
  position: { ...e.position },
1650
- velocity: { x: Math.cos(p) * g, y: Math.sin(p) * g },
1663
+ velocity: { x: Math.cos(u) * g, y: Math.sin(u) * g },
1651
1664
  color: "#00f5ff",
1652
1665
  radius: 4 + Math.random() * 6,
1653
1666
  alpha: 1,
@@ -1668,25 +1681,25 @@ class it {
1668
1681
  });
1669
1682
  }
1670
1683
  }
1671
- class M {
1684
+ class C {
1672
1685
  static createEnemy(t, e, i) {
1673
- const s = `enemy_${Date.now()}_${Math.random()}`, a = new w(s);
1686
+ const s = `enemy_${Date.now()}_${Math.random()}`, a = new U(s);
1674
1687
  return this.configureEnemy(a, t, e, i), a;
1675
1688
  }
1676
1689
  static configureEnemy(t, e, i, s) {
1677
1690
  t.type = e, t.position = { ...i }, t.active = !0, t.isGrabbed = !1, t.isThrown = !1;
1678
1691
  const a = s.x - i.x, l = s.y - i.y, n = Math.atan2(l, a);
1679
- let o = 70, r = 100, c = 20, h = "#ff2a5f", u = null;
1680
- e === "piercer" ? (o = 95, r = 140, c = 18, h = "#ff2a5f", u = new q()) : e === "spore" ? (o = 65, r = 90, c = 24, h = "#39ff14", u = new Q()) : e === "cluster" ? (o = 50, r = 75, c = 26, h = "#ffd700", u = new tt()) : e === "parasite" ? (o = 80, r = 110, c = 22, h = "#9d4edd", u = new et()) : e === "heavy" ? (o = 35, r = 50, c = 34, h = "#00f5ff", u = new it(), t.rotation = Math.random() * Math.PI * 2) : e === "micro" && (o = 130, r = 160, c = 12, h = "#ffd700"), t.radius = c, t.color = h, t.strategy = u, t.maxSpeed = r, t.velocity = {
1692
+ let o = 70, r = 100, c = 20, h = "#ff2a5f", p = null;
1693
+ e === "piercer" ? (o = 95, r = 140, c = 18, h = "#ff2a5f", p = new Q()) : e === "spore" ? (o = 65, r = 90, c = 24, h = "#39ff14", p = new tt()) : e === "cluster" ? (o = 50, r = 75, c = 26, h = "#ffd700", p = new et()) : e === "parasite" ? (o = 80, r = 110, c = 22, h = "#9d4edd", p = new it()) : e === "heavy" ? (o = 35, r = 50, c = 34, h = "#00f5ff", p = new st(), t.rotation = Math.random() * Math.PI * 2) : e === "micro" && (o = 130, r = 160, c = 12, h = "#ffd700"), t.radius = c, t.color = h, t.strategy = p, t.maxSpeed = r, t.velocity = {
1681
1694
  x: Math.cos(n) * o,
1682
1695
  y: Math.sin(n) * o
1683
1696
  };
1684
1697
  }
1685
1698
  }
1686
- class L {
1699
+ class P {
1687
1700
  static killEnemy(t, e, i, s, a, l) {
1688
1701
  if (!t.active || t.isDying) return;
1689
- const n = E.getInstance().getConfig();
1702
+ const n = A.getInstance().getConfig();
1690
1703
  if (t.experienceDropPending = !0, a.push({
1691
1704
  id: Math.random().toString(),
1692
1705
  position: { ...t.position },
@@ -1709,28 +1722,28 @@ class L {
1709
1722
  t.triggerDissolveDeath(!0);
1710
1723
  const o = n.cluster.fragmentCount, r = n.cluster.hasHoming;
1711
1724
  for (let c = 0; c < o; c++) {
1712
- const h = c * Math.PI * 2 / o, u = 750 + Math.random() * 250, d = {
1725
+ const h = c * Math.PI * 2 / o, p = 750 + Math.random() * 250, d = {
1713
1726
  x: t.position.x + Math.cos(h) * 40,
1714
1727
  y: t.position.y + Math.sin(h) * 40
1715
1728
  };
1716
1729
  let _ = h;
1717
1730
  if (r) {
1718
- let p = null, g = 1 / 0;
1719
- for (const m of l) {
1720
- if (m === t || !m.active || m.isGrabbed || m.isDying) continue;
1721
- const y = Math.hypot(m.position.x - d.x, m.position.y - d.y);
1722
- y < g && (g = y, p = m);
1731
+ let u = null, g = 1 / 0;
1732
+ for (const f of l) {
1733
+ if (f === t || !f.active || f.isGrabbed || f.isDying) continue;
1734
+ const b = Math.hypot(f.position.x - d.x, f.position.y - d.y);
1735
+ b < g && (g = b, u = f);
1723
1736
  }
1724
- p && (_ = Math.atan2(p.position.y - d.y, p.position.x - d.x));
1737
+ u && (_ = Math.atan2(u.position.y - d.y, u.position.x - d.x));
1725
1738
  }
1726
- const f = M.createEnemy("micro", d, {
1739
+ const m = C.createEnemy("micro", d, {
1727
1740
  x: d.x + Math.cos(_) * 500,
1728
1741
  y: d.y + Math.sin(_) * 500
1729
1742
  });
1730
- f.isThrown = !0, f.wasManipulated = !0, f.velocity = {
1731
- x: Math.cos(_) * u,
1732
- y: Math.sin(_) * u
1733
- }, l.push(f);
1743
+ m.isThrown = !0, m.wasManipulated = !0, m.velocity = {
1744
+ x: Math.cos(_) * p,
1745
+ y: Math.sin(_) * p
1746
+ }, l.push(m);
1734
1747
  }
1735
1748
  } else t.type === "parasite" ? (t.triggerDissolveDeath(!0), s.push({
1736
1749
  id: Math.random().toString(),
@@ -1742,16 +1755,16 @@ class L {
1742
1755
  })) : t.type === "piercer" ? t.triggerSliceDeath(e, !0) : t.triggerDissolveDeath(!0);
1743
1756
  }
1744
1757
  }
1745
- class st {
1746
- static update(t, e, i, s, a, l, n, o, r, c, h, u, d, _) {
1747
- let f = !1;
1748
- for (const p of t)
1749
- if (!(!p.active || !p.isThrown || p.isDying || p.launchDelay > 0)) {
1750
- if (f = !0, p.position.x < -120 || p.position.x > c + 120 || p.position.y < -120 || p.position.y > h + 120) {
1751
- if (p.type === "heavy") {
1758
+ class at {
1759
+ static update(t, e, i, s, a, l, n, o, r, c, h, p, d, _) {
1760
+ let m = !1;
1761
+ for (const u of t)
1762
+ if (!(!u.active || !u.isThrown || u.isDying || u.launchDelay > 0)) {
1763
+ if (m = !0, u.position.x < -120 || u.position.x > c + 120 || u.position.y < -120 || u.position.y > h + 120) {
1764
+ if (u.type === "heavy") {
1752
1765
  s.push({
1753
1766
  id: Math.random().toString(),
1754
- position: { ...p.position },
1767
+ position: { ...u.position },
1755
1768
  radius: 20,
1756
1769
  maxRadius: 350,
1757
1770
  color: "#00f5ff",
@@ -1760,11 +1773,11 @@ class st {
1760
1773
  maxLifetime: 0.6
1761
1774
  });
1762
1775
  for (let g = 0; g < 40; g++) {
1763
- const m = Math.random() * Math.PI * 2, y = 250 + Math.random() * 450;
1776
+ const f = Math.random() * Math.PI * 2, b = 250 + Math.random() * 450;
1764
1777
  a.push({
1765
1778
  id: Math.random().toString(),
1766
- position: { ...p.position },
1767
- velocity: { x: Math.cos(m) * y, y: Math.sin(m) * y },
1779
+ position: { ...u.position },
1780
+ velocity: { x: Math.cos(f) * b, y: Math.sin(f) * b },
1768
1781
  color: "#00f5ff",
1769
1782
  radius: 4 + Math.random() * 5,
1770
1783
  alpha: 1,
@@ -1772,44 +1785,44 @@ class st {
1772
1785
  maxLifetime: 0.6
1773
1786
  });
1774
1787
  }
1775
- } else if (p.type === "piercer") {
1776
- const g = E.getInstance().getConfig().piercer;
1788
+ } else if (u.type === "piercer") {
1789
+ const g = A.getInstance().getConfig().piercer;
1777
1790
  if (g.terminalAoERadius > 0) {
1778
- const m = g.terminalAoERadius;
1791
+ const f = g.terminalAoERadius;
1779
1792
  s.push({
1780
1793
  id: Math.random().toString(),
1781
- position: { ...p.position },
1794
+ position: { ...u.position },
1782
1795
  radius: 20,
1783
- maxRadius: m,
1796
+ maxRadius: f,
1784
1797
  color: "#ff2a5f",
1785
1798
  alpha: 1,
1786
1799
  lifetime: 0,
1787
1800
  maxLifetime: 0.6
1788
1801
  });
1789
- for (const y of d.getNearby(p.position, m)) {
1790
- if (!y.active || y.isGrabbed || y.isDying) continue;
1791
- const b = y.position.x - p.position.x, I = y.position.y - p.position.y;
1792
- b * b + I * I <= m * m && L.killEnemy(y, Math.atan2(I, b), e, i, s, t);
1802
+ for (const b of d.getNearby(u.position, f)) {
1803
+ if (!b.active || b.isGrabbed || b.isDying) continue;
1804
+ const y = b.position.x - u.position.x, v = b.position.y - u.position.y;
1805
+ y * y + v * v <= f * f && P.killEnemy(b, Math.atan2(v, y), e, i, s, t);
1793
1806
  }
1794
1807
  }
1795
1808
  }
1796
- p.active = !1, p.isThrown = !1;
1809
+ u.active = !1, u.isThrown = !1;
1797
1810
  continue;
1798
1811
  }
1799
- for (const g of d.getNearby(p.position, p.getHitRadius() + 80)) {
1800
- if (g === p || !g.active || g.isGrabbed || g.isDying || g.launchDelay > 0) continue;
1801
- const m = g.position.x - p.position.x, y = g.position.y - p.position.y, b = p.getHitRadius() + g.getHitRadius();
1802
- if (m * m + y * y <= b * b) {
1803
- u.pos = { x: p.position.x, y: p.position.y };
1804
- const I = Math.atan2(p.velocity.y, p.velocity.x);
1805
- if (p.type === "heavy") {
1806
- u.kills++, L.killEnemy(g, p.rotation, e, i, s, t), n.triggerHitstop(0.04), n.triggerScreenShake({ x: m, y }, 8);
1807
- for (let S = 0; S < 8; S++) {
1808
- const v = p.rotation + (Math.random() - 0.5), x = 200 + Math.random() * 350;
1812
+ for (const g of d.getNearby(u.position, u.getHitRadius() + 80)) {
1813
+ if (g === u || !g.active || g.isGrabbed || g.isDying || g.launchDelay > 0) continue;
1814
+ const f = g.position.x - u.position.x, b = g.position.y - u.position.y, y = u.getHitRadius() + g.getHitRadius();
1815
+ if (f * f + b * b <= y * y) {
1816
+ p.pos = { x: u.position.x, y: u.position.y };
1817
+ const v = Math.atan2(u.velocity.y, u.velocity.x);
1818
+ if (u.type === "heavy") {
1819
+ p.kills++, P.killEnemy(g, u.rotation, e, i, s, t), n.triggerHitstop(0.04), n.triggerScreenShake({ x: f, y: b }, 8);
1820
+ for (let M = 0; M < 8; M++) {
1821
+ const T = u.rotation + (Math.random() - 0.5), x = 200 + Math.random() * 350;
1809
1822
  a.push({
1810
1823
  id: Math.random().toString(),
1811
1824
  position: { ...g.position },
1812
- velocity: { x: Math.cos(v) * x, y: Math.sin(v) * x },
1825
+ velocity: { x: Math.cos(T) * x, y: Math.sin(T) * x },
1813
1826
  color: "#00f5ff",
1814
1827
  radius: 3 + Math.random() * 4,
1815
1828
  alpha: 1,
@@ -1818,8 +1831,8 @@ class st {
1818
1831
  });
1819
1832
  }
1820
1833
  _ && _();
1821
- } else if (p.type === "piercer") {
1822
- u.kills++, L.killEnemy(g, I, e, i, s, t), n.triggerHitstop(0.05), n.triggerScreenShake({ x: m, y }, 7), s.push({
1834
+ } else if (u.type === "piercer") {
1835
+ p.kills++, P.killEnemy(g, v, e, i, s, t), n.triggerHitstop(0.05), n.triggerScreenShake({ x: f, y: b }, 7), s.push({
1823
1836
  id: Math.random().toString(),
1824
1837
  position: { ...g.position },
1825
1838
  radius: 10,
@@ -1829,12 +1842,12 @@ class st {
1829
1842
  lifetime: 0,
1830
1843
  maxLifetime: 0.45
1831
1844
  });
1832
- for (let S = 0; S < 16; S++) {
1833
- const v = Math.random() * Math.PI * 2, x = 150 + Math.random() * 300;
1845
+ for (let M = 0; M < 16; M++) {
1846
+ const T = Math.random() * Math.PI * 2, x = 150 + Math.random() * 300;
1834
1847
  a.push({
1835
1848
  id: Math.random().toString(),
1836
1849
  position: { ...g.position },
1837
- velocity: { x: Math.cos(v) * x, y: Math.sin(v) * x },
1850
+ velocity: { x: Math.cos(T) * x, y: Math.sin(T) * x },
1838
1851
  color: "#ff2a5f",
1839
1852
  radius: 3 + Math.random() * 3,
1840
1853
  alpha: 1,
@@ -1842,51 +1855,51 @@ class st {
1842
1855
  maxLifetime: 0.4
1843
1856
  });
1844
1857
  }
1845
- if (p.remainingHomingKills > 0) {
1846
- p.remainingHomingKills--;
1847
- let S = null, v = 1 / 0;
1858
+ if (u.remainingHomingKills > 0) {
1859
+ u.remainingHomingKills--;
1860
+ let M = null, T = 1 / 0;
1848
1861
  for (const x of t) {
1849
- if (x === p || x === g || !x.active || x.isGrabbed || x.isDying) continue;
1850
- const T = x.position.x - p.position.x, R = x.position.y - p.position.y, k = Math.hypot(T, R);
1851
- k < v && (v = k, S = x);
1862
+ if (x === u || x === g || !x.active || x.isGrabbed || x.isDying) continue;
1863
+ const L = x.position.x - u.position.x, R = x.position.y - u.position.y, I = Math.hypot(L, R);
1864
+ I < T && (T = I, M = x);
1852
1865
  }
1853
- if (S) {
1854
- const x = Math.atan2(S.position.y - p.position.y, S.position.x - p.position.x), T = Math.hypot(p.velocity.x, p.velocity.y) || 1200;
1855
- p.rotation = x, p.velocity = {
1856
- x: Math.cos(x) * T,
1857
- y: Math.sin(x) * T
1866
+ if (M) {
1867
+ const x = Math.atan2(M.position.y - u.position.y, M.position.x - u.position.x), L = Math.hypot(u.velocity.x, u.velocity.y) || 1200;
1868
+ u.rotation = x, u.velocity = {
1869
+ x: Math.cos(x) * L,
1870
+ y: Math.sin(x) * L
1858
1871
  };
1859
1872
  }
1860
1873
  }
1861
1874
  _ && _();
1862
1875
  } else {
1863
- const S = p.type === g.type, v = S ? 360 : 250;
1876
+ const M = u.type === g.type, T = M ? 360 : 250;
1864
1877
  s.push({
1865
1878
  id: Math.random().toString(),
1866
- position: { ...u.pos },
1879
+ position: { ...p.pos },
1867
1880
  radius: 15,
1868
- maxRadius: v,
1869
- color: p.color,
1881
+ maxRadius: T,
1882
+ color: u.color,
1870
1883
  alpha: 1,
1871
1884
  lifetime: 0,
1872
1885
  maxLifetime: 0.55
1873
1886
  });
1874
1887
  for (let x = 0; x < 45; x++) {
1875
- const T = Math.random() * Math.PI * 2, R = 200 + Math.random() * 450;
1888
+ const L = Math.random() * Math.PI * 2, R = 200 + Math.random() * 450;
1876
1889
  a.push({
1877
1890
  id: Math.random().toString(),
1878
- position: { ...u.pos },
1879
- velocity: { x: Math.cos(T) * R, y: Math.sin(T) * R },
1880
- color: p.color,
1891
+ position: { ...p.pos },
1892
+ velocity: { x: Math.cos(L) * R, y: Math.sin(L) * R },
1893
+ color: u.color,
1881
1894
  radius: 4 + Math.random() * 6,
1882
1895
  alpha: 1,
1883
1896
  lifetime: 0,
1884
1897
  maxLifetime: 0.7
1885
1898
  });
1886
1899
  }
1887
- if (p.strategy) {
1888
- p.strategy.execute({
1889
- thrownEnemy: p,
1900
+ if (u.strategy) {
1901
+ u.strategy.execute({
1902
+ thrownEnemy: u,
1890
1903
  targetEnemy: g,
1891
1904
  allEnemies: t,
1892
1905
  pools: e,
@@ -1897,43 +1910,43 @@ class st {
1897
1910
  eventBus: o,
1898
1911
  width: c,
1899
1912
  height: h
1900
- }), u.kills += 2, _ && _();
1913
+ }), p.kills += 2, _ && _();
1901
1914
  break;
1902
1915
  }
1903
- if (S) {
1904
- u.kills += 2, n.triggerHitstop(0.14), n.triggerFlash(0.5), n.triggerScreenShake({ x: m, y }, 16), l.push({
1916
+ if (M) {
1917
+ p.kills += 2, n.triggerHitstop(0.14), n.triggerFlash(0.5), n.triggerScreenShake({ x: f, y: b }, 16), l.push({
1905
1918
  id: Math.random().toString(),
1906
1919
  text: "COLOR SYNERGY!",
1907
- position: { ...u.pos },
1920
+ position: { ...p.pos },
1908
1921
  velocity: { x: 0, y: -80 },
1909
- color: p.color,
1922
+ color: u.color,
1910
1923
  alpha: 1,
1911
1924
  lifetime: 0,
1912
1925
  maxLifetime: 1.2,
1913
1926
  size: 26
1914
1927
  });
1915
- const x = E.getInstance().getConfig();
1916
- p.type === "spore" ? e.push({
1928
+ const x = A.getInstance().getConfig();
1929
+ u.type === "spore" ? e.push({
1917
1930
  id: Math.random().toString(),
1918
- position: { ...u.pos },
1931
+ position: { ...p.pos },
1919
1932
  radius: Math.round(x.toxicPool.baseRadius * 2),
1920
1933
  duration: 0,
1921
1934
  maxDuration: x.toxicPool.synergyDuration,
1922
1935
  damage: x.toxicPool.damage * 2
1923
- }) : p.type === "parasite" && i.push({
1936
+ }) : u.type === "parasite" && i.push({
1924
1937
  id: Math.random().toString(),
1925
- position: { ...u.pos },
1938
+ position: { ...p.pos },
1926
1939
  radius: Math.round(x.gravityVortex.baseRadius * 1.8),
1927
1940
  duration: 0,
1928
1941
  maxDuration: x.gravityVortex.synergyDuration,
1929
1942
  pullForce: x.gravityVortex.synergyPullForce
1930
- }), L.killEnemy(p, I, e, i, s, t), L.killEnemy(g, I, e, i, s, t);
1943
+ }), P.killEnemy(u, v, e, i, s, t), P.killEnemy(g, v, e, i, s, t);
1931
1944
  } else
1932
- u.kills += 2, n.triggerHitstop(0.08), n.triggerFlash(0.35), n.triggerScreenShake({ x: m, y }, 10), L.killEnemy(p, I, e, i, s, t), L.killEnemy(g, I, e, i, s, t);
1945
+ p.kills += 2, n.triggerHitstop(0.08), n.triggerFlash(0.35), n.triggerScreenShake({ x: f, y: b }, 10), P.killEnemy(u, v, e, i, s, t), P.killEnemy(g, v, e, i, s, t);
1933
1946
  for (const x of t) {
1934
- if (x === p || x === g || !x.active || x.isGrabbed || x.isDying) continue;
1935
- const T = x.position.x - u.pos.x, R = x.position.y - u.pos.y;
1936
- Math.hypot(T, R) <= v && x.type !== "micro" && (L.killEnemy(x, I, e, i, s, t), u.kills++);
1947
+ if (x === u || x === g || !x.active || x.isGrabbed || x.isDying) continue;
1948
+ const L = x.position.x - p.pos.x, R = x.position.y - p.pos.y;
1949
+ Math.hypot(L, R) <= T && x.type !== "micro" && (P.killEnemy(x, v, e, i, s, t), p.kills++);
1937
1950
  }
1938
1951
  _ && _();
1939
1952
  break;
@@ -1941,20 +1954,20 @@ class st {
1941
1954
  }
1942
1955
  }
1943
1956
  }
1944
- r.value = u.kills, !f && u.kills > 0 && (u.kills >= 2 && u.pos && l.push({
1957
+ r.value = p.kills, !m && p.kills > 0 && (p.kills >= 2 && p.pos && l.push({
1945
1958
  id: Math.random().toString(),
1946
- text: `MULTIKILL x${u.kills}!`,
1947
- position: { ...u.pos },
1959
+ text: `MULTIKILL x${p.kills}!`,
1960
+ position: { ...p.pos },
1948
1961
  velocity: { x: 0, y: -90 },
1949
1962
  color: "#ff00dd",
1950
1963
  alpha: 1,
1951
1964
  lifetime: 0,
1952
1965
  maxLifetime: 1.4,
1953
1966
  size: 32
1954
- }), o.emit("onComboUpdated", { combo: r.value }), u.kills = 0, u.pos = null);
1967
+ }), o.emit("onComboUpdated", { combo: r.value }), p.kills = 0, p.pos = null);
1955
1968
  }
1956
1969
  }
1957
- class at {
1970
+ class ot {
1958
1971
  static update(t, e, i, s, a, l, n, o) {
1959
1972
  for (let r = t.length - 1; r >= 0; r--) {
1960
1973
  const c = t[r];
@@ -1962,31 +1975,31 @@ class at {
1962
1975
  c.duration += l;
1963
1976
  for (const h of e) {
1964
1977
  if (!h.active || h.isGrabbed || h.isDying || h.launchDelay > 0 || h.isThrown && h.type === "piercer") continue;
1965
- const u = h.position.x - c.position.x, d = h.position.y - c.position.y;
1966
- u * u + d * d <= c.radius * c.radius && (L.killEnemy(h, 0, t, i, s, e), n.kills++, o && o());
1978
+ const p = h.position.x - c.position.x, d = h.position.y - c.position.y;
1979
+ p * p + d * d <= c.radius * c.radius && (P.killEnemy(h, 0, t, i, s, e), n.kills++, o && o());
1967
1980
  }
1968
1981
  c.duration >= c.maxDuration && t.splice(r, 1);
1969
1982
  }
1970
1983
  }
1971
1984
  }
1972
1985
  }
1973
- class ot {
1974
- static update(t, e, i, s, a, l, n, o, r, c, h, u, d) {
1975
- const _ = E.getInstance().getConfig().shield.protectionArc;
1976
- for (const f of t)
1977
- if (!(!f.active || !f.isStationaryShield || f.isDying))
1978
- for (const p of u.getNearby(f.position, f.getHitRadius() + 80)) {
1979
- if (p === f || !p.active || p.isGrabbed || p.isDying || p.launchDelay > 0) continue;
1980
- const g = p.position.x - f.position.x, m = p.position.y - f.position.y;
1981
- let y = Math.atan2(m, g) - f.rotation;
1982
- for (; y < -Math.PI; ) y += Math.PI * 2;
1983
- for (; y > Math.PI; ) y -= Math.PI * 2;
1984
- if (Math.abs(y) > _ / 2) continue;
1985
- const b = f.getHitRadius() + p.getHitRadius();
1986
- if (g * g + m * m <= b * b) {
1987
- f.isStationaryShield = !1, f.strategy && f.strategy.execute({
1988
- thrownEnemy: f,
1989
- targetEnemy: p,
1986
+ class nt {
1987
+ static update(t, e, i, s, a, l, n, o, r, c, h, p, d) {
1988
+ const _ = A.getInstance().getConfig().shield.protectionArc;
1989
+ for (const m of t)
1990
+ if (!(!m.active || !m.isStationaryShield || m.isDying))
1991
+ for (const u of p.getNearby(m.position, m.getHitRadius() + 80)) {
1992
+ if (u === m || !u.active || u.isGrabbed || u.isDying || u.launchDelay > 0) continue;
1993
+ const g = u.position.x - m.position.x, f = u.position.y - m.position.y;
1994
+ let b = Math.atan2(f, g) - m.rotation;
1995
+ for (; b < -Math.PI; ) b += Math.PI * 2;
1996
+ for (; b > Math.PI; ) b -= Math.PI * 2;
1997
+ if (Math.abs(b) > _ / 2) continue;
1998
+ const y = m.getHitRadius() + u.getHitRadius();
1999
+ if (g * g + f * f <= y * y) {
2000
+ m.isStationaryShield = !1, m.strategy && m.strategy.execute({
2001
+ thrownEnemy: m,
2002
+ targetEnemy: u,
1990
2003
  allEnemies: t,
1991
2004
  pools: e,
1992
2005
  vortices: i,
@@ -1996,13 +2009,13 @@ class ot {
1996
2009
  eventBus: o,
1997
2010
  width: c,
1998
2011
  height: h
1999
- }), r.kills += 2, n.triggerHitstop(0.12), n.triggerScreenShake({ x: g, y: m }, 18), d && d();
2012
+ }), r.kills += 2, n.triggerHitstop(0.12), n.triggerScreenShake({ x: g, y: f }, 18), d && d();
2000
2013
  break;
2001
2014
  }
2002
2015
  }
2003
2016
  }
2004
2017
  }
2005
- class nt {
2018
+ class rt {
2006
2019
  spatialHash;
2007
2020
  eventBus;
2008
2021
  i18n;
@@ -2010,57 +2023,57 @@ class nt {
2010
2023
  constructor(t, e) {
2011
2024
  this.spatialHash = new z(100), this.eventBus = t, this.i18n = e;
2012
2025
  }
2013
- update(t, e, i, s, a, l, n, o, r, c, h, u, d, _) {
2014
- const f = E.getInstance().getConfig().piercer;
2026
+ update(t, e, i, s, a, l, n, o, r, c, h, p, d, _) {
2027
+ const m = A.getInstance().getConfig().piercer;
2015
2028
  for (const g of i)
2016
2029
  if (g.active && !g.isDying) {
2017
- if (g.isThrown && g.type === "piercer" && f.hasHoming && g.remainingHomingKills > 0) {
2018
- let m = null, y = 1 / 0;
2019
- for (const b of i) {
2020
- if (b === g || !b.active || b.isGrabbed || b.isDying) continue;
2021
- const I = b.position.x - g.position.x, S = b.position.y - g.position.y, v = I * I + S * S;
2022
- v < y && (y = v, m = b);
2030
+ if (g.isThrown && g.type === "piercer" && m.hasHoming && g.remainingHomingKills > 0) {
2031
+ let f = null, b = 1 / 0;
2032
+ for (const y of i) {
2033
+ if (y === g || !y.active || y.isGrabbed || y.isDying) continue;
2034
+ const v = y.position.x - g.position.x, M = y.position.y - g.position.y, T = v * v + M * M;
2035
+ T < b && (b = T, f = y);
2023
2036
  }
2024
- if (m) {
2025
- const b = Math.atan2(m.position.y - g.position.y, m.position.x - g.position.x), I = Math.max(Math.hypot(g.velocity.x, g.velocity.y), 1e3), S = 25 * t, v = Math.atan2(g.velocity.y, g.velocity.x);
2026
- let x = b - v;
2037
+ if (f) {
2038
+ const y = Math.atan2(f.position.y - g.position.y, f.position.x - g.position.x), v = Math.max(Math.hypot(g.velocity.x, g.velocity.y), 1e3), M = 25 * t, T = Math.atan2(g.velocity.y, g.velocity.x);
2039
+ let x = y - T;
2027
2040
  for (; x < -Math.PI; ) x += Math.PI * 2;
2028
2041
  for (; x > Math.PI; ) x -= Math.PI * 2;
2029
- const T = v + Math.sign(x) * Math.min(Math.abs(x), S);
2030
- g.rotation = T, g.velocity = {
2031
- x: Math.cos(T) * I,
2032
- y: Math.sin(T) * I
2042
+ const L = T + Math.sign(x) * Math.min(Math.abs(x), M);
2043
+ g.rotation = L, g.velocity = {
2044
+ x: Math.cos(L) * v,
2045
+ y: Math.sin(L) * v
2033
2046
  };
2034
2047
  }
2035
2048
  }
2036
2049
  if (g.isStationaryShield) {
2037
- let m = null, y = 1 / 0;
2038
- for (const b of i) {
2039
- if (b === g || !b.active || b.isGrabbed || b.isDying || b.isStationaryShield) continue;
2040
- const I = b.position.x - g.position.x, S = b.position.y - g.position.y, v = I * I + S * S;
2041
- v < y && (y = v, m = b);
2050
+ let f = null, b = 1 / 0;
2051
+ for (const y of i) {
2052
+ if (y === g || !y.active || y.isGrabbed || y.isDying || y.isStationaryShield) continue;
2053
+ const v = y.position.x - g.position.x, M = y.position.y - g.position.y, T = v * v + M * M;
2054
+ T < b && (b = T, f = y);
2042
2055
  }
2043
- if (m) {
2044
- let I = Math.atan2(m.position.y - g.position.y, m.position.x - g.position.x) - g.rotation;
2045
- for (; I < -Math.PI; ) I += Math.PI * 2;
2046
- for (; I > Math.PI; ) I -= Math.PI * 2;
2047
- const S = 5 * t;
2048
- g.rotation += Math.sign(I) * Math.min(Math.abs(I), S);
2056
+ if (f) {
2057
+ let v = Math.atan2(f.position.y - g.position.y, f.position.x - g.position.x) - g.rotation;
2058
+ for (; v < -Math.PI; ) v += Math.PI * 2;
2059
+ for (; v > Math.PI; ) v -= Math.PI * 2;
2060
+ const M = 5 * t;
2061
+ g.rotation += Math.sign(v) * Math.min(Math.abs(v), M);
2049
2062
  }
2050
2063
  }
2051
2064
  g.update(t);
2052
2065
  } else g.active && g.isDying && g.update(t);
2053
2066
  for (let g = l.length - 1; g >= 0; g--) {
2054
- const m = l[g];
2055
- if (!m) continue;
2056
- m.lifetime += t;
2057
- const y = m.lifetime / m.maxLifetime;
2058
- m.radius = m.maxRadius * y, m.alpha = Math.max(0, 1 - y), m.lifetime >= m.maxLifetime && l.splice(g, 1);
2067
+ const f = l[g];
2068
+ if (!f) continue;
2069
+ f.lifetime += t;
2070
+ const b = f.lifetime / f.maxLifetime;
2071
+ f.radius = f.maxRadius * b, f.alpha = Math.max(0, 1 - b), f.lifetime >= f.maxLifetime && l.splice(g, 1);
2059
2072
  }
2060
- X.update(a, i, t), this.spatialHash.clear();
2073
+ j.update(a, i, t), this.spatialHash.clear();
2061
2074
  for (const g of i)
2062
2075
  g.active && !g.isDying && g.launchDelay <= 0 && this.spatialHash.insert(g);
2063
- j.update(
2076
+ q.update(
2064
2077
  e,
2065
2078
  i,
2066
2079
  l,
@@ -2069,9 +2082,9 @@ class nt {
2069
2082
  r,
2070
2083
  this.eventBus,
2071
2084
  h,
2072
- u,
2085
+ p,
2073
2086
  d
2074
- ), st.update(
2087
+ ), at.update(
2075
2088
  i,
2076
2089
  s,
2077
2090
  a,
@@ -2081,12 +2094,12 @@ class nt {
2081
2094
  r,
2082
2095
  this.eventBus,
2083
2096
  c,
2084
- u,
2097
+ p,
2085
2098
  d,
2086
2099
  this.throwState,
2087
2100
  this.spatialHash,
2088
2101
  _
2089
- ), at.update(
2102
+ ), ot.update(
2090
2103
  s,
2091
2104
  i,
2092
2105
  a,
@@ -2095,7 +2108,7 @@ class nt {
2095
2108
  t,
2096
2109
  this.throwState,
2097
2110
  _
2098
- ), ot.update(
2111
+ ), nt.update(
2099
2112
  i,
2100
2113
  s,
2101
2114
  a,
@@ -2105,20 +2118,20 @@ class nt {
2105
2118
  r,
2106
2119
  this.eventBus,
2107
2120
  this.throwState,
2108
- u,
2121
+ p,
2109
2122
  d,
2110
2123
  this.spatialHash,
2111
2124
  _
2112
2125
  );
2113
- const p = 32;
2114
- l.length > p && l.splice(0, l.length - p);
2126
+ const u = 32;
2127
+ l.length > u && l.splice(0, l.length - u);
2115
2128
  }
2116
2129
  }
2117
- class rt {
2130
+ class lt {
2118
2131
  pool = [];
2119
2132
  constructor(t = 500) {
2120
2133
  for (let e = 0; e < t; e++) {
2121
- const i = new w(`pool_enemy_${e}`);
2134
+ const i = new U(`pool_enemy_${e}`);
2122
2135
  this.pool.push(i);
2123
2136
  }
2124
2137
  }
@@ -2126,7 +2139,7 @@ class rt {
2126
2139
  for (const e of this.pool)
2127
2140
  if (!e.active)
2128
2141
  return e.reset(), e;
2129
- const t = new w(`fallback_enemy_${Date.now()}_${Math.random()}`);
2142
+ const t = new U(`fallback_enemy_${Date.now()}_${Math.random()}`);
2130
2143
  return this.pool.push(t), t;
2131
2144
  }
2132
2145
  resetAll() {
@@ -2134,7 +2147,7 @@ class rt {
2134
2147
  t.reset();
2135
2148
  }
2136
2149
  }
2137
- class C {
2150
+ class O {
2138
2151
  static getOffscreenPosition(t, e) {
2139
2152
  const i = Math.floor(Math.random() * 4), s = 70;
2140
2153
  return i === 0 ? { x: Math.random() * t, y: -s } : i === 1 ? { x: t + s, y: Math.random() * e } : i === 2 ? { x: Math.random() * t, y: e + s } : { x: -s, y: Math.random() * e };
@@ -2145,8 +2158,8 @@ class C {
2145
2158
  const r = o * Math.PI * 2 / 18, c = {
2146
2159
  x: e.x + Math.cos(r) * n,
2147
2160
  y: e.y + Math.sin(r) * n
2148
- }, h = t.get(), u = ["piercer", "spore", "cluster", "parasite"], d = u[o % u.length];
2149
- M.configureEnemy(h, d, c, e), h.velocity = {
2161
+ }, h = t.get(), p = ["piercer", "spore", "cluster", "parasite"], d = p[o % p.length];
2162
+ C.configureEnemy(h, d, c, e), h.velocity = {
2150
2163
  x: Math.cos(r + Math.PI) * 55,
2151
2164
  y: Math.sin(r + Math.PI) * 55
2152
2165
  }, a.push(h);
@@ -2161,13 +2174,13 @@ class C {
2161
2174
  const c = {
2162
2175
  x: (Math.random() - 0.5) * 60,
2163
2176
  y: (Math.random() - 0.5) * 60
2164
- }, h = { x: o.x + c.x, y: o.y + c.y }, u = t.get();
2165
- M.configureEnemy(u, "spore", h, s);
2166
- const d = s.x - h.x, _ = s.y - h.y, f = Math.atan2(_, d);
2167
- u.velocity = {
2168
- x: Math.cos(f) * (50 + Math.random() * 20),
2169
- y: Math.sin(f) * (50 + Math.random() * 20)
2170
- }, a.push(u);
2177
+ }, h = { x: o.x + c.x, y: o.y + c.y }, p = t.get();
2178
+ C.configureEnemy(p, "spore", h, s);
2179
+ const d = s.x - h.x, _ = s.y - h.y, m = Math.atan2(_, d);
2180
+ p.velocity = {
2181
+ x: Math.cos(m) * (50 + Math.random() * 20),
2182
+ y: Math.sin(m) * (50 + Math.random() * 20)
2183
+ }, a.push(p);
2171
2184
  }
2172
2185
  return a;
2173
2186
  }
@@ -2178,7 +2191,7 @@ class C {
2178
2191
  x: -60 - o * 40,
2179
2192
  y: n + Math.sin(o * 0.45) * 70
2180
2193
  }, c = t.get();
2181
- M.configureEnemy(c, "cluster", r, s), c.velocity = { x: 75, y: Math.cos(o * 0.45) * 30 }, a.push(c);
2194
+ C.configureEnemy(c, "cluster", r, s), c.velocity = { x: 75, y: Math.cos(o * 0.45) * 30 }, a.push(c);
2182
2195
  }
2183
2196
  return a;
2184
2197
  }
@@ -2188,8 +2201,8 @@ class C {
2188
2201
  const o = n / 14, r = o * Math.PI * 4, c = 120 + o * 450, h = {
2189
2202
  x: e + Math.cos(r) * c,
2190
2203
  y: -60 + Math.sin(r) * c
2191
- }, u = t.get();
2192
- M.configureEnemy(u, "parasite", h, s), a.push(u);
2204
+ }, p = t.get();
2205
+ C.configureEnemy(p, "parasite", h, s), a.push(p);
2193
2206
  }
2194
2207
  return a;
2195
2208
  }
@@ -2200,7 +2213,7 @@ class C {
2200
2213
  x: n ? -60 : e + 60,
2201
2214
  y: r
2202
2215
  }, h = t.get();
2203
- M.configureEnemy(h, "piercer", c, s), h.velocity = {
2216
+ C.configureEnemy(h, "piercer", c, s), h.velocity = {
2204
2217
  x: n ? 70 : -70,
2205
2218
  y: 0
2206
2219
  }, a.push(h);
@@ -2211,14 +2224,14 @@ class C {
2211
2224
  const a = [];
2212
2225
  for (let n = 0; n < 10; n++) {
2213
2226
  const o = { x: -50 - n * 35, y: -50 - n * 35 }, r = t.get();
2214
- M.configureEnemy(r, "spore", o, s), a.push(r);
2227
+ C.configureEnemy(r, "spore", o, s), a.push(r);
2215
2228
  const c = { x: e + 50 + n * 35, y: i + 50 + n * 35 }, h = t.get();
2216
- M.configureEnemy(h, "cluster", c, s), a.push(h);
2229
+ C.configureEnemy(h, "cluster", c, s), a.push(h);
2217
2230
  }
2218
2231
  return a;
2219
2232
  }
2220
2233
  }
2221
- class lt {
2234
+ class ct {
2222
2235
  wave = 1;
2223
2236
  pool;
2224
2237
  spawnTimer = 0;
@@ -2226,7 +2239,7 @@ class lt {
2226
2239
  patternCooldown = 0;
2227
2240
  initialGracePeriod = 6;
2228
2241
  constructor() {
2229
- this.pool = new rt(500);
2242
+ this.pool = new lt(500);
2230
2243
  }
2231
2244
  reset() {
2232
2245
  this.wave = 1, this.spawnTimer = 0, this.waveTimer = 0, this.patternCooldown = 0;
@@ -2244,15 +2257,15 @@ class lt {
2244
2257
  return this.spawnTimer >= n && l < o ? (this.spawnTimer = 0, this.spawnSingleEnemy(i, s, a)) : null;
2245
2258
  }
2246
2259
  spawnSingleEnemy(t, e, i) {
2247
- const s = C.getOffscreenPosition(t, e), a = Math.random();
2260
+ const s = O.getOffscreenPosition(t, e), a = Math.random();
2248
2261
  let l = "piercer";
2249
2262
  a > 0.75 ? l = "heavy" : a > 0.55 ? l = "parasite" : a > 0.35 ? l = "cluster" : a > 0.15 && (l = "spore");
2250
2263
  const n = this.pool.get();
2251
- return M.configureEnemy(n, l, s, i), n;
2264
+ return C.configureEnemy(n, l, s, i), n;
2252
2265
  }
2253
2266
  spawnPatternFormation(t, e, i) {
2254
2267
  const s = Math.random();
2255
- return s < 0.25 ? C.spawnCircleOfDeath(this.pool, i, t, e) : s < 0.5 ? C.spawnDenseCluster(this.pool, t, e, i) : s < 0.75 ? C.spawnSineSnake(this.pool, t, e, i) : C.spawnMarchingWall(this.pool, t, e, i);
2268
+ return s < 0.25 ? O.spawnCircleOfDeath(this.pool, i, t, e) : s < 0.5 ? O.spawnDenseCluster(this.pool, t, e, i) : s < 0.75 ? O.spawnSineSnake(this.pool, t, e, i) : O.spawnMarchingWall(this.pool, t, e, i);
2256
2269
  }
2257
2270
  applyFlockingBehaviors(t, e, i) {
2258
2271
  for (let a = 0; a < t.length; a++) {
@@ -2263,14 +2276,14 @@ class lt {
2263
2276
  if (a === d) continue;
2264
2277
  const _ = t[d];
2265
2278
  if (!_.active || _.isGrabbed || _.isDying) continue;
2266
- const f = l.position.x - _.position.x, p = l.position.y - _.position.y, g = Math.hypot(f, p);
2267
- g > 0 && g < 70 && (n += f / g, o += p / g, r++);
2279
+ const m = l.position.x - _.position.x, u = l.position.y - _.position.y, g = Math.hypot(m, u);
2280
+ g > 0 && g < 70 && (n += m / g, o += u / g, r++);
2268
2281
  }
2269
2282
  r > 0 && (n /= r, o /= r, l.velocity.x += n * 60 * e, l.velocity.y += o * 60 * e);
2270
- const c = i.x - l.position.x, h = i.y - l.position.y, u = Math.hypot(c, h);
2271
- if (u > 0) {
2283
+ const c = i.x - l.position.x, h = i.y - l.position.y, p = Math.hypot(c, h);
2284
+ if (p > 0) {
2272
2285
  const d = 80 + Math.min(this.wave * 4, 40);
2273
- l.velocity.x += c / u * d * e, l.velocity.y += h / u * d * e;
2286
+ l.velocity.x += c / p * d * e, l.velocity.y += h / p * d * e;
2274
2287
  }
2275
2288
  if (l.maxSpeed > 0) {
2276
2289
  const d = Math.hypot(l.velocity.x, l.velocity.y);
@@ -2282,7 +2295,7 @@ class lt {
2282
2295
  }
2283
2296
  }
2284
2297
  }
2285
- class ct {
2298
+ class ht {
2286
2299
  id;
2287
2300
  position;
2288
2301
  velocity;
@@ -2322,7 +2335,7 @@ class ct {
2322
2335
  }
2323
2336
  }
2324
2337
  }
2325
- const P = {
2338
+ const N = {
2326
2339
  bioluminescent: {
2327
2340
  bgInner: "#081220",
2328
2341
  bgMid: "#050b16",
@@ -2389,22 +2402,22 @@ const P = {
2389
2402
  vortexCore: "#274760",
2390
2403
  vortexMid: "#577c9e"
2391
2404
  }
2392
- }, D = "axon_surge_theme";
2393
- class ht {
2405
+ }, k = "axon_surge_theme";
2406
+ class pt {
2394
2407
  currentTheme = "dark";
2395
2408
  isExplicit = !1;
2396
2409
  targetElement;
2397
2410
  constructor(t, e) {
2398
2411
  e !== void 0 && (this.targetElement = e);
2399
2412
  try {
2400
- const i = localStorage.getItem(D);
2401
- if (i && P[i]) {
2413
+ const i = localStorage.getItem(k);
2414
+ if (i && N[i]) {
2402
2415
  this.currentTheme = i, this.isExplicit = !0, this.applyThemeToDOM();
2403
2416
  return;
2404
2417
  }
2405
2418
  } catch {
2406
2419
  }
2407
- if (t && P[t]) {
2420
+ if (t && N[t]) {
2408
2421
  this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
2409
2422
  return;
2410
2423
  }
@@ -2414,10 +2427,10 @@ class ht {
2414
2427
  this.targetElement = t, this.isExplicit ? this.applyThemeToDOM() : this.currentTheme = this.detectParentOrSystemTheme();
2415
2428
  }
2416
2429
  setTheme(t) {
2417
- if (P[t]) {
2430
+ if (N[t]) {
2418
2431
  this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
2419
2432
  try {
2420
- localStorage.setItem(D, t);
2433
+ localStorage.setItem(k, t);
2421
2434
  } catch {
2422
2435
  }
2423
2436
  }
@@ -2425,7 +2438,7 @@ class ht {
2425
2438
  clearExplicitTheme() {
2426
2439
  this.isExplicit = !1;
2427
2440
  try {
2428
- localStorage.removeItem(D);
2441
+ localStorage.removeItem(k);
2429
2442
  } catch {
2430
2443
  }
2431
2444
  this.removeThemeClasses(), this.currentTheme = this.detectParentOrSystemTheme();
@@ -2434,7 +2447,7 @@ class ht {
2434
2447
  return this.isExplicit || (this.currentTheme = this.detectParentOrSystemTheme()), this.currentTheme;
2435
2448
  }
2436
2449
  getPalette() {
2437
- return P[this.getTheme()] || P.dark;
2450
+ return N[this.getTheme()] || N.dark;
2438
2451
  }
2439
2452
  detectParentOrSystemTheme() {
2440
2453
  try {
@@ -2485,22 +2498,22 @@ class ut {
2485
2498
  if (n >= 0 && n <= i && o >= 0 && o <= s) continue;
2486
2499
  const r = Math.min(i, Math.max(0, n)), c = Math.min(s, Math.max(0, o)), h = Math.hypot(n - r, o - c);
2487
2500
  if (h <= 0 || h > this.maxDistance) continue;
2488
- const u = Math.min(1, Math.max(0, h / this.maxDistance)), d = this.minThickness + (this.maxThickness - this.minThickness) * (1 - u), _ = this.minLength + (this.maxLength - this.minLength) * (1 - u), f = 0.55 + (1 - u) * 0.35;
2489
- if (t.save(), t.globalAlpha = f, t.shadowColor = l.color, t.shadowBlur = 14, t.strokeStyle = l.color, t.lineWidth = d, t.lineCap = "round", t.beginPath(), r === 0 || r === i) {
2490
- const p = Math.max(0, c - _ / 2), g = Math.min(s, c + _ / 2);
2491
- t.moveTo(r, p), t.lineTo(r, g);
2501
+ const p = Math.min(1, Math.max(0, h / this.maxDistance)), d = this.minThickness + (this.maxThickness - this.minThickness) * (1 - p), _ = this.minLength + (this.maxLength - this.minLength) * (1 - p), m = 0.55 + (1 - p) * 0.35;
2502
+ if (t.save(), t.globalAlpha = m, t.shadowColor = l.color, t.shadowBlur = 14, t.strokeStyle = l.color, t.lineWidth = d, t.lineCap = "round", t.beginPath(), r === 0 || r === i) {
2503
+ const u = Math.max(0, c - _ / 2), g = Math.min(s, c + _ / 2);
2504
+ t.moveTo(r, u), t.lineTo(r, g);
2492
2505
  } else {
2493
- const p = Math.max(0, r - _ / 2), g = Math.min(i, r + _ / 2);
2494
- t.moveTo(p, c), t.lineTo(g, c);
2506
+ const u = Math.max(0, r - _ / 2), g = Math.min(i, r + _ / 2);
2507
+ t.moveTo(u, c), t.lineTo(g, c);
2495
2508
  }
2496
- t.stroke(), t.strokeStyle = a.effectHighlight, t.lineWidth = Math.max(1.8, d * 0.28), t.globalAlpha = f * 0.9, t.stroke(), t.restore();
2509
+ t.stroke(), t.strokeStyle = a.effectHighlight, t.lineWidth = Math.max(1.8, d * 0.28), t.globalAlpha = m * 0.9, t.stroke(), t.restore();
2497
2510
  }
2498
2511
  }
2499
2512
  }
2500
- class pt {
2513
+ class dt {
2501
2514
  render(t, e, i, s, a, l, n = !1) {
2502
- const o = Math.max(1, a), r = Math.min(1, (o - 1) / 8), c = this.wrapHue(190 + (o - 1) * 34 + Math.sin(s * 0.1) * 5), h = this.wrapHue(c + 42), u = this.wrapHue(c + 150), d = e / 2, _ = i / 2, f = Math.max(e, i) * 0.82, p = t.createRadialGradient(d, _, 20, d, _, f);
2503
- n ? (p.addColorStop(0, `hsl(${c}, 42%, 91%)`), p.addColorStop(0.42, `hsl(${h}, 42%, 86%)`), p.addColorStop(0.78, `hsl(${u}, 38%, 81%)`), p.addColorStop(1, l.bgOuter)) : (p.addColorStop(0, `hsl(${c}, 42%, 11%)`), p.addColorStop(0.42, `hsl(${h}, 48%, 8%)`), p.addColorStop(0.78, `hsl(${u}, 42%, 5%)`), p.addColorStop(1, `hsl(${u}, 48%, 2.5%)`)), t.fillStyle = p, t.fillRect(0, 0, e, i);
2515
+ const o = Math.max(1, a), r = Math.min(1, (o - 1) / 8), c = this.wrapHue(190 + (o - 1) * 34 + Math.sin(s * 0.1) * 5), h = this.wrapHue(c + 42), p = this.wrapHue(c + 150), d = e / 2, _ = i / 2, m = Math.max(e, i) * 0.82, u = t.createRadialGradient(d, _, 20, d, _, m);
2516
+ n ? (u.addColorStop(0, `hsl(${c}, 42%, 91%)`), u.addColorStop(0.42, `hsl(${h}, 42%, 86%)`), u.addColorStop(0.78, `hsl(${p}, 38%, 81%)`), u.addColorStop(1, l.bgOuter)) : (u.addColorStop(0, `hsl(${c}, 42%, 11%)`), u.addColorStop(0.42, `hsl(${h}, 48%, 8%)`), u.addColorStop(0.78, `hsl(${p}, 42%, 5%)`), u.addColorStop(1, `hsl(${p}, 48%, 2.5%)`)), t.fillStyle = u, t.fillRect(0, 0, e, i);
2504
2517
  const g = Math.min(e, i) * 0.055;
2505
2518
  this.drawNebula(
2506
2519
  t,
@@ -2523,12 +2536,12 @@ class pt {
2523
2536
  e * 0.86 + Math.sin(s * 0.11) * g * 0.7,
2524
2537
  i * 0.16 + Math.cos(s * 0.13) * g * 0.7,
2525
2538
  Math.max(e, i) * 0.3,
2526
- u,
2539
+ p,
2527
2540
  n ? 0.17 : 0.14,
2528
2541
  n
2529
2542
  ), this.drawSoftFlows(t, e, i, s, c, r, n), this.drawParticleField(t, e, i, s, c, h, o, n);
2530
- const m = t.createRadialGradient(d, _, Math.min(e, i) * 0.28, d, _, f);
2531
- m.addColorStop(0, "rgba(0, 0, 0, 0)"), m.addColorStop(1, n ? "rgba(40, 60, 90, 0.09)" : "rgba(0, 0, 0, 0.2)"), t.fillStyle = m, t.fillRect(0, 0, e, i);
2543
+ const f = t.createRadialGradient(d, _, Math.min(e, i) * 0.28, d, _, m);
2544
+ f.addColorStop(0, "rgba(0, 0, 0, 0)"), f.addColorStop(1, n ? "rgba(40, 60, 90, 0.09)" : "rgba(0, 0, 0, 0.2)"), t.fillStyle = f, t.fillRect(0, 0, e, i);
2532
2545
  }
2533
2546
  drawNebula(t, e, i, s, a, l, n) {
2534
2547
  const o = t.createRadialGradient(e, i, 0, e, i, s), r = n ? 52 : 60;
@@ -2539,16 +2552,16 @@ class pt {
2539
2552
  const o = Math.min(e, i), r = o * 0.035;
2540
2553
  t.globalAlpha = n ? 0.15 : 0.12, t.lineWidth = Math.max(1.3, o * 17e-4), t.lineCap = "round", t.shadowBlur = o * 0.02, t.shadowColor = `hsla(${a}, 85%, ${n ? 52 : 62}%, 0.28)`;
2541
2554
  for (let c = 0; c < 3; c++) {
2542
- const h = (c - 1) * o * 0.075 + Math.sin(s * 0.06 + c) * r, u = c * 28 + l * 18;
2543
- t.strokeStyle = `hsla(${this.wrapHue(a + u)}, ${n ? 78 : 74}%, ${n ? 47 : 62}%, ${0.52 - c * 0.08})`, t.beginPath(), t.moveTo(-o * 0.12, i * 0.2 + h), t.bezierCurveTo(e * 0.2, i * 0.02 + h, e * 0.47, i * 0.2 - h, e * 0.73, i * 0.07 + h), t.bezierCurveTo(e * 0.94, -o * 0.02 + h, e * 1.04, i * 0.16 + h, e * 1.1, i * 0.36 + h), t.stroke(), t.beginPath(), t.moveTo(-o * 0.1, i * 0.8 - h), t.bezierCurveTo(e * 0.2, i * 0.98 - h, e * 0.48, i * 0.8 + h, e * 0.75, i * 0.93 - h), t.bezierCurveTo(e * 0.94, i * 1.02 - h, e * 1.04, i * 0.84 - h, e * 1.1, i * 0.65 - h), t.stroke();
2555
+ const h = (c - 1) * o * 0.075 + Math.sin(s * 0.06 + c) * r, p = c * 28 + l * 18;
2556
+ t.strokeStyle = `hsla(${this.wrapHue(a + p)}, ${n ? 78 : 74}%, ${n ? 47 : 62}%, ${0.52 - c * 0.08})`, t.beginPath(), t.moveTo(-o * 0.12, i * 0.2 + h), t.bezierCurveTo(e * 0.2, i * 0.02 + h, e * 0.47, i * 0.2 - h, e * 0.73, i * 0.07 + h), t.bezierCurveTo(e * 0.94, -o * 0.02 + h, e * 1.04, i * 0.16 + h, e * 1.1, i * 0.36 + h), t.stroke(), t.beginPath(), t.moveTo(-o * 0.1, i * 0.8 - h), t.bezierCurveTo(e * 0.2, i * 0.98 - h, e * 0.48, i * 0.8 + h, e * 0.75, i * 0.93 - h), t.bezierCurveTo(e * 0.94, i * 1.02 - h, e * 1.04, i * 0.84 - h, e * 1.1, i * 0.65 - h), t.stroke();
2544
2557
  }
2545
2558
  t.restore();
2546
2559
  }
2547
2560
  drawParticleField(t, e, i, s, a, l, n, o) {
2548
- const r = 44 + Math.min(24, n * 2), c = e / 2, h = i / 2, u = Math.min(e, i) * 0.17;
2561
+ const r = 44 + Math.min(24, n * 2), c = e / 2, h = i / 2, p = Math.min(e, i) * 0.17;
2549
2562
  for (let d = 0; d < r; d++) {
2550
- const _ = d + n * 17, f = this.unitNoise(_ * 1.7) * e, p = this.unitNoise(_ * 2.9 + 13) * i, g = Math.hypot(f - c, p - h), m = Math.min(1, Math.max(0, (g - u) / (Math.min(e, i) * 0.28))), y = 0.7 + Math.sin(s * (0.6 + d % 4 * 0.08) + _) * 0.3, b = (o ? 0.34 : 0.3) * m * y, I = 0.65 + d % 3 * 0.45;
2551
- t.fillStyle = `hsla(${d % 3 === 0 ? l : a}, ${o ? 82 : 78}%, ${o ? 40 : 70}%, ${b})`, t.beginPath(), t.arc(f, p, I, 0, Math.PI * 2), t.fill();
2563
+ const _ = d + n * 17, m = this.unitNoise(_ * 1.7) * e, u = this.unitNoise(_ * 2.9 + 13) * i, g = Math.hypot(m - c, u - h), f = Math.min(1, Math.max(0, (g - p) / (Math.min(e, i) * 0.28))), b = 0.7 + Math.sin(s * (0.6 + d % 4 * 0.08) + _) * 0.3, y = (o ? 0.34 : 0.3) * f * b, v = 0.65 + d % 3 * 0.45;
2564
+ t.fillStyle = `hsla(${d % 3 === 0 ? l : a}, ${o ? 82 : 78}%, ${o ? 40 : 70}%, ${y})`, t.beginPath(), t.arc(m, u, v, 0, Math.PI * 2), t.fill();
2552
2565
  }
2553
2566
  }
2554
2567
  unitNoise(t) {
@@ -2558,7 +2571,7 @@ class pt {
2558
2571
  return (t % 360 + 360) % 360;
2559
2572
  }
2560
2573
  }
2561
- class dt {
2574
+ class gt {
2562
2575
  render(t, e, i) {
2563
2576
  if (!e.isActive) return;
2564
2577
  const s = e.getLauncher(), a = e.getTarget();
@@ -2574,8 +2587,8 @@ class dt {
2574
2587
  if (Math.hypot(n, o) > 10) {
2575
2588
  const c = Math.atan2(o, n);
2576
2589
  t.shadowColor = "#ff00dd", t.shadowBlur = 22, t.strokeStyle = "#ff00dd", t.lineWidth = 4, t.setLineDash([12, 8]), t.beginPath(), t.moveTo(s.position.x, s.position.y), t.lineTo(a.position.x, a.position.y), t.stroke(), t.setLineDash([]);
2577
- const h = a.position.x - Math.cos(c) * (a.radius + 10), u = a.position.y - Math.sin(c) * (a.radius + 10);
2578
- t.fillStyle = "#ff00dd", t.beginPath(), t.moveTo(h, u), t.lineTo(h - Math.cos(c - 0.4) * 24, u - Math.sin(c - 0.4) * 24), t.lineTo(h - Math.cos(c + 0.4) * 24, u - Math.sin(c + 0.4) * 24), t.closePath(), t.fill();
2590
+ const h = a.position.x - Math.cos(c) * (a.radius + 10), p = a.position.y - Math.sin(c) * (a.radius + 10);
2591
+ t.fillStyle = "#ff00dd", t.beginPath(), t.moveTo(h, p), t.lineTo(h - Math.cos(c - 0.4) * 24, p - Math.sin(c - 0.4) * 24), t.lineTo(h - Math.cos(c + 0.4) * 24, p - Math.sin(c + 0.4) * 24), t.closePath(), t.fill();
2579
2592
  const d = a.radius * (1.8 + Math.cos(i * 10) * 0.3);
2580
2593
  t.strokeStyle = "rgba(255, 0, 221, 0.9)", t.lineWidth = 3.5, t.beginPath(), t.arc(a.position.x, a.position.y, d, 0, Math.PI * 2), t.stroke();
2581
2594
  }
@@ -2583,7 +2596,7 @@ class dt {
2583
2596
  t.restore();
2584
2597
  }
2585
2598
  }
2586
- class gt {
2599
+ class _t {
2587
2600
  canvas;
2588
2601
  ctx;
2589
2602
  themeManager;
@@ -2591,20 +2604,20 @@ class gt {
2591
2604
  bgRenderer;
2592
2605
  tutorialArrowRenderer;
2593
2606
  constructor(t, e) {
2594
- this.canvas = t, this.ctx = t.getContext("2d"), this.themeManager = e, this.indicatorRenderer = new ut(), this.bgRenderer = new pt(), this.tutorialArrowRenderer = new dt();
2607
+ this.canvas = t, this.ctx = t.getContext("2d"), this.themeManager = e, this.indicatorRenderer = new ut(), this.bgRenderer = new dt(), this.tutorialArrowRenderer = new gt();
2595
2608
  }
2596
- render(t, e, i, s, a, l, n, o, r, c, h, u = 1, d) {
2609
+ render(t, e, i, s, a, l, n, o, r, c, h, p = 1, d) {
2597
2610
  if (!this.ctx) return;
2598
- const _ = this.themeManager.getPalette(), { width: f, height: p } = this.canvas, g = r.getShakeOffset();
2611
+ const _ = this.themeManager.getPalette(), { width: m, height: u } = this.canvas, g = r.getShakeOffset();
2599
2612
  this.ctx.save(), this.ctx.translate(g.x, g.y), this.bgRenderer.render(
2600
2613
  this.ctx,
2601
- f,
2602
- p,
2603
- t.pulsePhase,
2614
+ m,
2604
2615
  u,
2616
+ t.pulsePhase,
2617
+ p,
2605
2618
  _,
2606
2619
  this.themeManager.getTheme() === "light"
2607
- ), this.drawExperienceOrbs(i, t.position, t.pulsePhase, _), this.drawToxicPools(s, t.pulsePhase), this.drawGravityVortices(a, t.pulsePhase), this.drawShockwaves(l), this.drawCoreFilaments(t, _), this.drawParticles(n), E.getInstance().getConfig().core.hasOffscreenIndicators && this.indicatorRenderer.render(this.ctx, e, f, p, _), this.drawOrganicEnemies(e, t.pulsePhase, _), d && this.tutorialArrowRenderer.render(this.ctx, d, t.pulsePhase), c ? this.drawPsionicTendril(t.position, c.position, _) : t && this.drawHoverTendril(t.position, h, e, _), this.drawOrganicConsciousnessCore(t, _), this.drawFloatingTexts(o), r.flashAlpha > 0 && (this.ctx.fillStyle = `rgba(255, 255, 255, ${r.flashAlpha})`, this.ctx.fillRect(0, 0, f, p)), this.ctx.restore();
2620
+ ), this.drawExperienceOrbs(i, t.position, t.pulsePhase, _), this.drawToxicPools(s, t.pulsePhase), this.drawGravityVortices(a, t.pulsePhase), this.drawShockwaves(l), this.drawCoreFilaments(t, _), this.drawParticles(n), A.getInstance().getConfig().core.hasOffscreenIndicators && this.indicatorRenderer.render(this.ctx, e, m, u, _), this.drawOrganicEnemies(e, t.pulsePhase, _), d && this.tutorialArrowRenderer.render(this.ctx, d, t.pulsePhase), c ? this.drawPsionicTendril(t.position, c.position, _) : t && this.drawHoverTendril(t.position, h, e, _), this.drawOrganicConsciousnessCore(t, _), this.drawFloatingTexts(o), r.flashAlpha > 0 && (this.ctx.fillStyle = `rgba(255, 255, 255, ${r.flashAlpha})`, this.ctx.fillRect(0, 0, m, u)), this.ctx.restore();
2608
2621
  }
2609
2622
  drawExperienceOrbs(t, e, i, s) {
2610
2623
  if (this.ctx)
@@ -2625,18 +2638,18 @@ class gt {
2625
2638
  o.addColorStop(0, `rgba(57, 255, 20, ${a * 0.9})`), o.addColorStop(0.4, `rgba(16, 185, 129, ${a * 0.65})`), o.addColorStop(0.8, `rgba(5, 80, 45, ${a * 0.35})`), o.addColorStop(1, "rgba(2, 35, 15, 0)"), this.ctx.fillStyle = o, this.ctx.shadowColor = "#39ff14", this.ctx.shadowBlur = 30, this.ctx.beginPath();
2626
2639
  const r = 70;
2627
2640
  for (let c = 0; c <= r; c++) {
2628
- const h = c * Math.PI * 2 / r, u = Math.sin(h * 5 + e * 3) * 14, d = Math.cos(h * 3 - e * 2) * 9, _ = i.radius + u + d, f = l + Math.cos(h) * _, p = n + Math.sin(h) * _;
2629
- c === 0 ? this.ctx.moveTo(f, p) : this.ctx.lineTo(f, p);
2641
+ const h = c * Math.PI * 2 / r, p = Math.sin(h * 5 + e * 3) * 14, d = Math.cos(h * 3 - e * 2) * 9, _ = i.radius + p + d, m = l + Math.cos(h) * _, u = n + Math.sin(h) * _;
2642
+ c === 0 ? this.ctx.moveTo(m, u) : this.ctx.lineTo(m, u);
2630
2643
  }
2631
2644
  this.ctx.closePath(), this.ctx.fill(), this.ctx.strokeStyle = `rgba(57, 255, 20, ${a * 0.8})`, this.ctx.lineWidth = 2.5, this.ctx.beginPath();
2632
2645
  for (let c = 0; c <= r; c++) {
2633
- const h = c * Math.PI * 2 / r, u = Math.sin(h * 6 + e * 4) * 8, d = i.radius * 0.75 + u, _ = l + Math.cos(h) * d, f = n + Math.sin(h) * d;
2634
- c === 0 ? this.ctx.moveTo(_, f) : this.ctx.lineTo(_, f);
2646
+ const h = c * Math.PI * 2 / r, p = Math.sin(h * 6 + e * 4) * 8, d = i.radius * 0.75 + p, _ = l + Math.cos(h) * d, m = n + Math.sin(h) * d;
2647
+ c === 0 ? this.ctx.moveTo(_, m) : this.ctx.lineTo(_, m);
2635
2648
  }
2636
2649
  this.ctx.closePath(), this.ctx.stroke();
2637
2650
  for (let c = 0; c < 6; c++) {
2638
- const h = c * Math.PI * 0.33 + e * 1.5, u = i.radius * 0.5 * (0.3 + Math.sin(e * 2 + c) * 0.3), d = l + Math.cos(h) * u, _ = n + Math.sin(h) * u, f = 3 + Math.sin(e * 3 + c) * 2;
2639
- this.ctx.fillStyle = `rgba(255, 255, 255, ${a * 0.8})`, this.ctx.beginPath(), this.ctx.arc(d, _, Math.max(1, f), 0, Math.PI * 2), this.ctx.fill();
2651
+ const h = c * Math.PI * 0.33 + e * 1.5, p = i.radius * 0.5 * (0.3 + Math.sin(e * 2 + c) * 0.3), d = l + Math.cos(h) * p, _ = n + Math.sin(h) * p, m = 3 + Math.sin(e * 3 + c) * 2;
2652
+ this.ctx.fillStyle = `rgba(255, 255, 255, ${a * 0.8})`, this.ctx.beginPath(), this.ctx.arc(d, _, Math.max(1, m), 0, Math.PI * 2), this.ctx.fill();
2640
2653
  }
2641
2654
  this.ctx.restore();
2642
2655
  }
@@ -2668,8 +2681,8 @@ class gt {
2668
2681
  const r = this.ctx.createRadialGradient(n, o, 0, n, o, 60);
2669
2682
  r.addColorStop(0, this.colorWithAlpha(i.vortexCore, a)), r.addColorStop(0.7, this.colorWithAlpha(i.vortexMid, a)), r.addColorStop(1, `rgba(157, 78, 221, ${a * 0.5})`), this.ctx.fillStyle = r, this.ctx.beginPath(), this.ctx.arc(n, o, 60, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = i.parasiteColor, this.ctx.lineWidth = 5, this.ctx.shadowColor = i.parasiteColor, this.ctx.shadowBlur = 32;
2670
2683
  for (let c = 1; c <= 5; c++) {
2671
- const h = l * c / 5, u = e * c * 2.2;
2672
- this.ctx.beginPath(), this.ctx.arc(n, o, h, u, u + Math.PI * 1.5), this.ctx.stroke();
2684
+ const h = l * c / 5, p = e * c * 2.2;
2685
+ this.ctx.beginPath(), this.ctx.arc(n, o, h, p, p + Math.PI * 1.5), this.ctx.stroke();
2673
2686
  }
2674
2687
  this.ctx.restore();
2675
2688
  }
@@ -2706,9 +2719,9 @@ class gt {
2706
2719
  const c = t.radius + 16 + r * 12;
2707
2720
  this.ctx.strokeStyle = a, this.ctx.lineWidth = 2.2, this.ctx.shadowColor = a, this.ctx.shadowBlur = 12, this.ctx.beginPath();
2708
2721
  const h = 60;
2709
- for (let u = 0; u <= h; u++) {
2710
- const d = u * Math.PI * 2 / h, _ = c + Math.sin(d * 4 + t.pulsePhase * 2 + r) * 3, f = i + Math.cos(d) * _, p = s + Math.sin(d) * _;
2711
- u === 0 ? this.ctx.moveTo(f, p) : this.ctx.lineTo(f, p);
2722
+ for (let p = 0; p <= h; p++) {
2723
+ const d = p * Math.PI * 2 / h, _ = c + Math.sin(d * 4 + t.pulsePhase * 2 + r) * 3, m = i + Math.cos(d) * _, u = s + Math.sin(d) * _;
2724
+ p === 0 ? this.ctx.moveTo(m, u) : this.ctx.lineTo(m, u);
2712
2725
  }
2713
2726
  this.ctx.closePath(), this.ctx.stroke();
2714
2727
  }
@@ -2716,9 +2729,9 @@ class gt {
2716
2729
  const r = t.integrity, c = t.radius + 16 + r * 12;
2717
2730
  this.ctx.save(), this.ctx.globalAlpha = Math.max(0.15, t.repairProgress), this.ctx.strokeStyle = a, this.ctx.lineWidth = 2, this.ctx.shadowColor = a, this.ctx.shadowBlur = 8, this.ctx.setLineDash([6, 4]), this.ctx.beginPath();
2718
2731
  const h = 60;
2719
- for (let u = 0; u <= h; u++) {
2720
- const d = u * Math.PI * 2 / h, _ = c + Math.sin(d * 4 + t.pulsePhase * 2 + r) * 3, f = i + Math.cos(d) * _, p = s + Math.sin(d) * _;
2721
- u === 0 ? this.ctx.moveTo(f, p) : this.ctx.lineTo(f, p);
2732
+ for (let p = 0; p <= h; p++) {
2733
+ const d = p * Math.PI * 2 / h, _ = c + Math.sin(d * 4 + t.pulsePhase * 2 + r) * 3, m = i + Math.cos(d) * _, u = s + Math.sin(d) * _;
2734
+ p === 0 ? this.ctx.moveTo(m, u) : this.ctx.lineTo(m, u);
2722
2735
  }
2723
2736
  this.ctx.closePath(), this.ctx.stroke(), this.ctx.restore();
2724
2737
  }
@@ -2726,8 +2739,8 @@ class gt {
2726
2739
  l.addColorStop(0, a), l.addColorStop(0.5, e.nebulaMagenta), l.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = l, this.ctx.beginPath(), this.ctx.arc(i, s, t.radius * 2.2, 0, Math.PI * 2), this.ctx.fill(), this.ctx.save(), this.ctx.translate(i, s), this.ctx.strokeStyle = a, this.ctx.lineWidth = 3, this.ctx.fillStyle = a, this.ctx.shadowColor = a, this.ctx.shadowBlur = 20, this.ctx.beginPath();
2727
2740
  const n = 80;
2728
2741
  for (let r = 0; r <= n; r++) {
2729
- const c = r * Math.PI * 2 / n, h = t.getMembraneRadius(c), u = Math.cos(c) * h, d = Math.sin(c) * h;
2730
- r === 0 ? this.ctx.moveTo(u, d) : this.ctx.lineTo(u, d);
2742
+ const c = r * Math.PI * 2 / n, h = t.getMembraneRadius(c), p = Math.cos(c) * h, d = Math.sin(c) * h;
2743
+ r === 0 ? this.ctx.moveTo(p, d) : this.ctx.lineTo(p, d);
2731
2744
  }
2732
2745
  this.ctx.closePath(), this.ctx.fill(), this.ctx.stroke();
2733
2746
  const o = t.powerUpCount;
@@ -2736,8 +2749,8 @@ class gt {
2736
2749
  for (let r = 0; r < o; r++) {
2737
2750
  const c = r * Math.PI * 2 / o + t.pulsePhase * 0.4, h = t.radius * (0.45 + Math.sin(t.pulsePhase * 2 + r) * 0.15);
2738
2751
  this.ctx.beginPath(), this.ctx.moveTo(0, 0);
2739
- const u = Math.cos(c + Math.sin(t.pulsePhase + r) * 0.4) * (h * 0.6), d = Math.sin(c + Math.cos(t.pulsePhase + r) * 0.4) * (h * 0.6), _ = Math.cos(c) * h, f = Math.sin(c) * h;
2740
- this.ctx.quadraticCurveTo(u, d, _, f), this.ctx.stroke(), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(_, f, 2.5, 0, Math.PI * 2), this.ctx.fill();
2752
+ const p = Math.cos(c + Math.sin(t.pulsePhase + r) * 0.4) * (h * 0.6), d = Math.sin(c + Math.cos(t.pulsePhase + r) * 0.4) * (h * 0.6), _ = Math.cos(c) * h, m = Math.sin(c) * h;
2753
+ this.ctx.quadraticCurveTo(p, d, _, m), this.ctx.stroke(), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(_, m, 2.5, 0, Math.PI * 2), this.ctx.fill();
2741
2754
  }
2742
2755
  }
2743
2756
  this.ctx.fillStyle = e.effectHighlight, this.ctx.beginPath(), this.ctx.arc(0, 0, t.radius * 0.3, 0, Math.PI * 2), this.ctx.fill(), this.ctx.restore(), this.ctx.restore();
@@ -2785,14 +2798,14 @@ class gt {
2785
2798
  const c = s.radius * (1 - o * 0.7);
2786
2799
  this.ctx.fillStyle = i.sporeColor, this.ctx.shadowColor = i.sporeColor, this.ctx.shadowBlur = 20, this.ctx.beginPath(), this.ctx.arc(0, 0, c, 0, Math.PI * 2), this.ctx.fill();
2787
2800
  for (let h = 0; h < 4; h++) {
2788
- const u = h * Math.PI * 0.5 + o * 4, d = c * 0.8 * o;
2789
- this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(Math.cos(u) * d, Math.sin(u) * d, 3, 0, Math.PI * 2), this.ctx.fill();
2801
+ const p = h * Math.PI * 0.5 + o * 4, d = c * 0.8 * o;
2802
+ this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(Math.cos(p) * d, Math.sin(p) * d, 3, 0, Math.PI * 2), this.ctx.fill();
2790
2803
  }
2791
2804
  this.ctx.restore();
2792
2805
  continue;
2793
2806
  } else if (s.deathType === "sliced") {
2794
- const c = o * 24, h = s.sliceAngle + Math.PI / 2, u = Math.cos(h) * c, d = Math.sin(h) * c;
2795
- this.ctx.shadowColor = "#ff2a5f", this.ctx.shadowBlur = 22, this.ctx.fillStyle = a, this.ctx.save(), this.ctx.translate(u, d), this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.8, 0, Math.PI), this.ctx.fill(), this.ctx.restore(), this.ctx.save(), this.ctx.translate(-u, -d), this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.8, Math.PI, Math.PI * 2), this.ctx.fill(), this.ctx.restore(), this.ctx.restore();
2807
+ const c = o * 24, h = s.sliceAngle + Math.PI / 2, p = Math.cos(h) * c, d = Math.sin(h) * c;
2808
+ this.ctx.shadowColor = "#ff2a5f", this.ctx.shadowBlur = 22, this.ctx.fillStyle = a, this.ctx.save(), this.ctx.translate(p, d), this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.8, 0, Math.PI), this.ctx.fill(), this.ctx.restore(), this.ctx.save(), this.ctx.translate(-p, -d), this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.8, Math.PI, Math.PI * 2), this.ctx.fill(), this.ctx.restore(), this.ctx.restore();
2796
2809
  continue;
2797
2810
  }
2798
2811
  }
@@ -2800,7 +2813,7 @@ class gt {
2800
2813
  this.ctx.rotate(s.rotation), this.ctx.beginPath();
2801
2814
  const o = 12;
2802
2815
  for (let r = 0; r <= o; r++) {
2803
- const c = r * Math.PI * 2 / o, h = s.radius * 1.6 + Math.sin(c * 3 + e * 4) * 3, u = s.radius * 0.6 + Math.cos(c * 2 + e * 3) * 2, d = Math.cos(c) * h, _ = Math.sin(c) * u;
2816
+ const c = r * Math.PI * 2 / o, h = s.radius * 1.6 + Math.sin(c * 3 + e * 4) * 3, p = s.radius * 0.6 + Math.cos(c * 2 + e * 3) * 2, d = Math.cos(c) * h, _ = Math.sin(c) * p;
2804
2817
  r === 0 ? this.ctx.moveTo(d, _) : this.ctx.lineTo(d, _);
2805
2818
  }
2806
2819
  this.ctx.closePath(), this.ctx.fill(), this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(4, 0, 4, 0, Math.PI * 2), this.ctx.fill();
@@ -2808,8 +2821,8 @@ class gt {
2808
2821
  this.ctx.beginPath();
2809
2822
  const o = 8;
2810
2823
  for (let r = 0; r < o; r++) {
2811
- const c = r * Math.PI * 2 / o, h = s.radius + Math.sin(c * 4 + e * 3 + s.position.x) * 4, u = Math.cos(c) * h, d = Math.sin(c) * h;
2812
- r === 0 ? this.ctx.moveTo(u, d) : this.ctx.lineTo(u, d);
2824
+ const c = r * Math.PI * 2 / o, h = s.radius + Math.sin(c * 4 + e * 3 + s.position.x) * 4, p = Math.cos(c) * h, d = Math.sin(c) * h;
2825
+ r === 0 ? this.ctx.moveTo(p, d) : this.ctx.lineTo(p, d);
2813
2826
  }
2814
2827
  this.ctx.closePath(), this.ctx.fill(), this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(-4, -4, 5, 0, Math.PI * 2), this.ctx.arc(5, 3, 4, 0, Math.PI * 2), this.ctx.fill();
2815
2828
  } else if (s.type === "cluster") {
@@ -2820,19 +2833,19 @@ class gt {
2820
2833
  this.ctx.beginPath();
2821
2834
  const o = 14;
2822
2835
  for (let r = 0; r <= o; r++) {
2823
- const c = r * Math.PI * 2 / o, h = s.radius + Math.sin(c * 5 - e * 5) * 3, u = Math.cos(c) * h, d = Math.sin(c) * h;
2824
- r === 0 ? this.ctx.moveTo(u, d) : this.ctx.lineTo(u, d);
2836
+ const c = r * Math.PI * 2 / o, h = s.radius + Math.sin(c * 5 - e * 5) * 3, p = Math.cos(c) * h, d = Math.sin(c) * h;
2837
+ r === 0 ? this.ctx.moveTo(p, d) : this.ctx.lineTo(p, d);
2825
2838
  }
2826
2839
  this.ctx.closePath(), this.ctx.fill(), this.ctx.fillStyle = i.bgOuter, this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.45, 0, Math.PI * 2), this.ctx.fill();
2827
2840
  } else if (s.type === "heavy") {
2828
2841
  this.ctx.rotate(s.rotation);
2829
- const o = E.getInstance().getConfig().shield.protectionArc, r = s.radius * 1.35, c = s.radius * 0.75;
2842
+ const o = A.getInstance().getConfig().shield.protectionArc, r = s.radius * 1.35, c = s.radius * 0.75;
2830
2843
  this.ctx.beginPath(), this.ctx.arc(0, 0, r, -o / 2, o / 2, !1);
2831
- const h = Math.cos(o / 2) * c, u = Math.sin(o / 2) * c;
2832
- this.ctx.lineTo(h, u), this.ctx.arc(0, 0, c, o / 2, -o / 2, !0), this.ctx.closePath(), this.ctx.fillStyle = s.isStationaryShield ? i.corePrimary : a, this.ctx.shadowColor = i.corePrimary, this.ctx.shadowBlur = s.isStationaryShield ? 28 : 16, this.ctx.fill(), this.ctx.strokeStyle = i.effectHighlight, this.ctx.lineWidth = 3, this.ctx.beginPath(), this.ctx.arc(0, 0, r + Math.sin(e * 4) * 2, -o / 2 + 0.1, o / 2 - 0.1), this.ctx.stroke();
2844
+ const h = Math.cos(o / 2) * c, p = Math.sin(o / 2) * c;
2845
+ this.ctx.lineTo(h, p), this.ctx.arc(0, 0, c, o / 2, -o / 2, !0), this.ctx.closePath(), this.ctx.fillStyle = s.isStationaryShield ? i.corePrimary : a, this.ctx.shadowColor = i.corePrimary, this.ctx.shadowBlur = s.isStationaryShield ? 28 : 16, this.ctx.fill(), this.ctx.strokeStyle = i.effectHighlight, this.ctx.lineWidth = 3, this.ctx.beginPath(), this.ctx.arc(0, 0, r + Math.sin(e * 4) * 2, -o / 2 + 0.1, o / 2 - 0.1), this.ctx.stroke();
2833
2846
  for (let d = -2; d <= 2; d++) {
2834
- const _ = d * o / 6, f = Math.cos(_) * (c + 6), p = Math.sin(_) * (c + 6);
2835
- this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(f, p, 3, 0, Math.PI * 2), this.ctx.fill();
2847
+ const _ = d * o / 6, m = Math.cos(_) * (c + 6), u = Math.sin(_) * (c + 6);
2848
+ this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(m, u, 3, 0, Math.PI * 2), this.ctx.fill();
2836
2849
  }
2837
2850
  } else
2838
2851
  this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius, 0, Math.PI * 2), this.ctx.fill();
@@ -2857,15 +2870,15 @@ class gt {
2857
2870
  const l = this.themeManager.getPalette(), n = this.themeManager.getTheme() === "light";
2858
2871
  for (const o of t) {
2859
2872
  if (!o.active) continue;
2860
- const { x: r, y: c } = o.position, h = o.definition.color, u = o.definition.rarity, d = u === "legendary" ? "#ff00ff" : u === "epic" ? "#ffd700" : u === "rare" ? "#9d4edd" : "#00f5ff", _ = o.radius + Math.sin(e * 6 + o.orbitAngle) * 3;
2861
- if (this.ctx.save(), this.ctx.shadowColor = d, this.ctx.shadowBlur = o.isGrabbed ? 36 : u === "legendary" ? 28 : 16, u === "legendary" || u === "epic") {
2862
- const g = _ + 12, m = this.ctx.createRadialGradient(r, c, _, r, c, g);
2863
- m.addColorStop(0, d), m.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = m, this.ctx.beginPath(), this.ctx.arc(r, c, g, 0, Math.PI * 2), this.ctx.fill();
2873
+ const { x: r, y: c } = o.position, h = o.definition.color, p = o.definition.rarity, d = p === "legendary" ? "#ff00ff" : p === "epic" ? "#ffd700" : p === "rare" ? "#9d4edd" : "#00f5ff", _ = o.radius + Math.sin(e * 6 + o.orbitAngle) * 3;
2874
+ if (this.ctx.save(), this.ctx.shadowColor = d, this.ctx.shadowBlur = o.isGrabbed ? 36 : p === "legendary" ? 28 : 16, p === "legendary" || p === "epic") {
2875
+ const g = _ + 12, f = this.ctx.createRadialGradient(r, c, _, r, c, g);
2876
+ f.addColorStop(0, d), f.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = f, this.ctx.beginPath(), this.ctx.arc(r, c, g, 0, Math.PI * 2), this.ctx.fill();
2864
2877
  }
2865
- const f = this.ctx.createRadialGradient(r, c, 2, r, c, _ * 1.4);
2866
- f.addColorStop(0, l.effectHighlight), f.addColorStop(0.4, h), f.addColorStop(1, n ? "rgba(23, 50, 77, 0.24)" : "rgba(0, 0, 0, 0.5)"), this.ctx.fillStyle = f, this.ctx.beginPath(), this.ctx.arc(r, c, _, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = d, this.ctx.lineWidth = u === "legendary" ? 3.5 : 2.5, this.ctx.beginPath(), this.ctx.arc(r, c, _ + 4, e * 3, e * 3 + Math.PI * 1.2), this.ctx.stroke(), (u === "legendary" || u === "epic") && (this.ctx.strokeStyle = n ? d : l.effectHighlight, this.ctx.lineWidth = 1.5, this.ctx.beginPath(), this.ctx.arc(r, c, _ + 8, -e * 2, -e * 2 + Math.PI * 0.9), this.ctx.stroke()), this.ctx.font = "900 14px Orbitron, sans-serif", this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.fillStyle = l.effectInk, this.ctx.shadowColor = l.effectShadow, this.ctx.shadowBlur = 6, this.ctx.fillText(o.definition.badge, r, c);
2867
- const p = i ? i.translate(o.definition.titleKey) : o.definition.badge;
2868
- this.ctx.textBaseline = "alphabetic", this.ctx.font = "900 16px Orbitron, sans-serif", this.ctx.fillStyle = l.effectInk, this.ctx.shadowColor = d, this.ctx.shadowBlur = 14, this.ctx.fillText(p, r, c - _ - 14), this.ctx.restore();
2878
+ const m = this.ctx.createRadialGradient(r, c, 2, r, c, _ * 1.4);
2879
+ m.addColorStop(0, l.effectHighlight), m.addColorStop(0.4, h), m.addColorStop(1, n ? "rgba(23, 50, 77, 0.24)" : "rgba(0, 0, 0, 0.5)"), this.ctx.fillStyle = m, this.ctx.beginPath(), this.ctx.arc(r, c, _, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = d, this.ctx.lineWidth = p === "legendary" ? 3.5 : 2.5, this.ctx.beginPath(), this.ctx.arc(r, c, _ + 4, e * 3, e * 3 + Math.PI * 1.2), this.ctx.stroke(), (p === "legendary" || p === "epic") && (this.ctx.strokeStyle = n ? d : l.effectHighlight, this.ctx.lineWidth = 1.5, this.ctx.beginPath(), this.ctx.arc(r, c, _ + 8, -e * 2, -e * 2 + Math.PI * 0.9), this.ctx.stroke()), this.ctx.font = "900 14px Orbitron, sans-serif", this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.fillStyle = l.effectInk, this.ctx.shadowColor = l.effectShadow, this.ctx.shadowBlur = 6, this.ctx.fillText(o.definition.badge, r, c);
2880
+ const u = i ? i.translate(o.definition.titleKey) : o.definition.badge;
2881
+ this.ctx.textBaseline = "alphabetic", this.ctx.font = "900 16px Orbitron, sans-serif", this.ctx.fillStyle = l.effectInk, this.ctx.shadowColor = d, this.ctx.shadowBlur = 14, this.ctx.fillText(u, r, c - _ - 14), this.ctx.restore();
2869
2882
  }
2870
2883
  if (i && s) {
2871
2884
  const o = this.canvas.width / 2, r = this.canvas.height / 2 + 210, c = i.translate("rerollButton", { count: a });
@@ -2881,7 +2894,7 @@ class gt {
2881
2894
  return `rgba(${s}, ${a}, ${l}, ${e})`;
2882
2895
  }
2883
2896
  }
2884
- class _t {
2897
+ class mt {
2885
2898
  container;
2886
2899
  i18n;
2887
2900
  waveLabelElement;
@@ -2939,7 +2952,7 @@ class ft {
2939
2952
  this.container.style.display = "none";
2940
2953
  }
2941
2954
  }
2942
- class mt {
2955
+ class xt {
2943
2956
  modal;
2944
2957
  card;
2945
2958
  i18n;
@@ -2948,10 +2961,14 @@ class mt {
2948
2961
  onLanguageChangedCallback;
2949
2962
  onCloseCallback;
2950
2963
  hapticsEnabled = !0;
2951
- constructor(t, e, i, s, a, l) {
2952
- this.i18n = e, this.themeManager = i, this.platform = s, this.onLanguageChangedCallback = a, this.onCloseCallback = l;
2953
- const n = localStorage.getItem("axon_surge_haptics");
2954
- n !== null && (this.hapticsEnabled = n === "true"), this.modal = document.createElement("dialog"), this.modal.className = "axon-settings-modal", this.card = document.createElement("div"), this.card.className = "axon-settings-card", this.modal.appendChild(this.card), t.appendChild(this.modal), this.modal.addEventListener("close", () => {
2964
+ fpsLimit = 60;
2965
+ onFpsLimitChangedCallback;
2966
+ constructor(t, e, i, s, a, l, n) {
2967
+ this.i18n = e, this.themeManager = i, this.platform = s, this.onLanguageChangedCallback = a, this.onCloseCallback = l, this.onFpsLimitChangedCallback = n;
2968
+ const o = localStorage.getItem("axon_surge_haptics");
2969
+ o !== null && (this.hapticsEnabled = o === "true");
2970
+ const r = Number(localStorage.getItem("axon_surge_fps_limit"));
2971
+ (r === 30 || r === 60 || r === 120) && (this.fpsLimit = r), this.modal = document.createElement("dialog"), this.modal.className = "axon-settings-modal", this.card = document.createElement("div"), this.card.className = "axon-settings-card", this.modal.appendChild(this.card), t.appendChild(this.modal), this.modal.addEventListener("close", () => {
2955
2972
  this.onCloseCallback && this.onCloseCallback();
2956
2973
  }), this.renderContent();
2957
2974
  }
@@ -2984,13 +3001,13 @@ class mt {
2984
3001
  ko: "한국어 (KO)",
2985
3002
  zh: "中文 (ZH)"
2986
3003
  };
2987
- for (const v of V) {
2988
- const x = document.createElement("option");
2989
- x.value = v, x.textContent = l[v], this.i18n.getLanguage() === v && (x.selected = !0), a.appendChild(x);
3004
+ for (const I of V) {
3005
+ const S = document.createElement("option");
3006
+ S.value = I, S.textContent = l[I], this.i18n.getLanguage() === I && (S.selected = !0), a.appendChild(S);
2990
3007
  }
2991
3008
  a.addEventListener("change", () => {
2992
- const v = a.value;
2993
- this.i18n.setLanguage(v), this.onLanguageChangedCallback && this.onLanguageChangedCallback(v), this.renderContent();
3009
+ const I = a.value;
3010
+ this.i18n.setLanguage(I), this.onLanguageChangedCallback && this.onLanguageChangedCallback(I), this.renderContent();
2994
3011
  });
2995
3012
  const n = document.createElement("span");
2996
3013
  n.className = "axon-select-arrow", n.textContent = "▼", s.appendChild(a), s.appendChild(n), e.appendChild(i), e.appendChild(s);
@@ -3005,57 +3022,78 @@ class mt {
3005
3022
  { id: "dark", label: "DARK" },
3006
3023
  { id: "light", label: "LIGHT" }
3007
3024
  ];
3008
- for (const v of h) {
3009
- const x = document.createElement("button");
3010
- x.type = "button", x.className = `axon-toggle-btn ${this.themeManager.getTheme() === v.id ? "active" : ""}`, x.textContent = v.label, x.addEventListener("click", () => {
3011
- this.themeManager.setTheme(v.id), this.renderContent();
3012
- }), c.appendChild(x);
3025
+ for (const I of h) {
3026
+ const S = document.createElement("button");
3027
+ S.type = "button", S.className = `axon-toggle-btn ${this.themeManager.getTheme() === I.id ? "active" : ""}`, S.textContent = I.label, S.addEventListener("click", () => {
3028
+ this.themeManager.setTheme(I.id), this.renderContent();
3029
+ }), c.appendChild(S);
3013
3030
  }
3014
3031
  o.appendChild(r), o.appendChild(c);
3015
- const u = document.createElement("div");
3016
- u.className = "axon-setting-row";
3032
+ const p = document.createElement("div");
3033
+ p.className = "axon-setting-row";
3017
3034
  const d = document.createElement("span");
3018
- d.textContent = this.i18n.translate("hapticsLabel");
3035
+ d.textContent = this.i18n.translate("fpsLimitLabel");
3019
3036
  const _ = document.createElement("div");
3020
3037
  _.className = "axon-toggle-group";
3021
- const f = [
3038
+ const m = [
3039
+ { limit: 30, label: "30 FPS" },
3040
+ { limit: 60, label: "60 FPS" },
3041
+ { limit: 120, label: "120 FPS" }
3042
+ ];
3043
+ for (const I of m) {
3044
+ const S = document.createElement("button");
3045
+ S.type = "button", S.className = `axon-toggle-btn ${this.fpsLimit === I.limit ? "active" : ""}`, S.textContent = I.label, S.addEventListener("click", () => {
3046
+ this.fpsLimit = I.limit, localStorage.setItem("axon_surge_fps_limit", String(I.limit)), this.onFpsLimitChangedCallback?.(I.limit), this.renderContent();
3047
+ }), _.appendChild(S);
3048
+ }
3049
+ p.appendChild(d), p.appendChild(_);
3050
+ const u = document.createElement("div");
3051
+ u.className = "axon-setting-row";
3052
+ const g = document.createElement("span");
3053
+ g.textContent = this.i18n.translate("hapticsLabel");
3054
+ const f = document.createElement("div");
3055
+ f.className = "axon-toggle-group";
3056
+ const b = [
3022
3057
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
3023
3058
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
3024
3059
  ];
3025
- for (const v of f) {
3026
- const x = document.createElement("button");
3027
- x.type = "button", x.className = `axon-toggle-btn ${this.hapticsEnabled === v.enabled ? "active" : ""}`, x.textContent = v.label, x.addEventListener("click", () => {
3028
- this.hapticsEnabled = v.enabled, localStorage.setItem("axon_surge_haptics", String(v.enabled)), this.hapticsEnabled && this.platform.haptics.selectionChanged(), this.renderContent();
3029
- }), _.appendChild(x);
3060
+ for (const I of b) {
3061
+ const S = document.createElement("button");
3062
+ S.type = "button", S.className = `axon-toggle-btn ${this.hapticsEnabled === I.enabled ? "active" : ""}`, S.textContent = I.label, S.addEventListener("click", () => {
3063
+ this.hapticsEnabled = I.enabled, localStorage.setItem("axon_surge_haptics", String(I.enabled)), this.hapticsEnabled && this.platform.haptics.selectionChanged(), this.renderContent();
3064
+ }), f.appendChild(S);
3030
3065
  }
3031
- u.appendChild(d), u.appendChild(_);
3032
- const p = document.createElement("div");
3033
- p.className = "axon-setting-row";
3034
- const g = document.createElement("span");
3035
- g.textContent = this.i18n.translate("tutorialSettingLabel");
3036
- const m = document.createElement("div");
3037
- m.className = "axon-toggle-group";
3038
- const y = localStorage.getItem("axon_surge_show_tutorial") !== "false", b = [
3066
+ u.appendChild(g), u.appendChild(f);
3067
+ const y = document.createElement("div");
3068
+ y.className = "axon-setting-row";
3069
+ const v = document.createElement("span");
3070
+ v.textContent = this.i18n.translate("tutorialSettingLabel");
3071
+ const M = document.createElement("div");
3072
+ M.className = "axon-toggle-group";
3073
+ const T = localStorage.getItem("axon_surge_show_tutorial") !== "false", x = [
3039
3074
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
3040
3075
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
3041
3076
  ];
3042
- for (const v of b) {
3043
- const x = document.createElement("button");
3044
- x.type = "button", x.className = `axon-toggle-btn ${y === v.enabled ? "active" : ""}`, x.textContent = v.label, x.addEventListener("click", () => {
3045
- localStorage.setItem("axon_surge_show_tutorial", String(v.enabled)), this.renderContent();
3046
- }), m.appendChild(x);
3047
- }
3048
- p.appendChild(g), p.appendChild(m);
3049
- const I = document.createElement("div");
3050
- I.className = "axon-settings-credits", I.textContent = this.i18n.translate("creditsJam");
3051
- const S = document.createElement("button");
3052
- S.type = "button", S.className = "axon-start-button", S.style.padding = "12px 36px", S.style.fontSize = "14px", S.textContent = this.i18n.translate("closeButton"), S.addEventListener("click", () => {
3077
+ for (const I of x) {
3078
+ const S = document.createElement("button");
3079
+ S.type = "button", S.className = `axon-toggle-btn ${T === I.enabled ? "active" : ""}`, S.textContent = I.label, S.addEventListener("click", () => {
3080
+ localStorage.setItem("axon_surge_show_tutorial", String(I.enabled)), this.renderContent();
3081
+ }), M.appendChild(S);
3082
+ }
3083
+ y.appendChild(v), y.appendChild(M);
3084
+ const L = document.createElement("div");
3085
+ L.className = "axon-settings-credits", L.textContent = this.i18n.translate("creditsJam");
3086
+ const R = document.createElement("button");
3087
+ R.type = "button", R.className = "axon-start-button", R.style.padding = "12px 36px", R.style.fontSize = "14px", R.textContent = this.i18n.translate("closeButton"), R.addEventListener("click", () => {
3053
3088
  this.modal.close();
3054
- }), this.card.appendChild(t), this.card.appendChild(e), this.card.appendChild(o), this.card.appendChild(u), this.card.appendChild(p), this.card.appendChild(I), this.card.appendChild(S);
3089
+ }), this.card.appendChild(t), this.card.appendChild(e), this.card.appendChild(o), this.card.appendChild(p), this.card.appendChild(u), this.card.appendChild(y), this.card.appendChild(L), this.card.appendChild(R);
3055
3090
  }
3056
3091
  isHapticsEnabled() {
3057
3092
  return this.hapticsEnabled;
3058
3093
  }
3094
+ getFpsLimit() {
3095
+ return this.fpsLimit;
3096
+ }
3059
3097
  show() {
3060
3098
  this.renderContent(), this.modal.showModal();
3061
3099
  }
@@ -3063,8 +3101,8 @@ class mt {
3063
3101
  this.modal.close();
3064
3102
  }
3065
3103
  }
3066
- const B = "axon_surge_show_tutorial";
3067
- class xt {
3104
+ const K = "axon_surge_show_tutorial";
3105
+ class yt {
3068
3106
  isActive = !1;
3069
3107
  showWarning = !1;
3070
3108
  dummyLauncher = null;
@@ -3073,14 +3111,14 @@ class xt {
3073
3111
  initialTargetPos = { x: 0, y: 0 };
3074
3112
  isTutorialEnabled() {
3075
3113
  try {
3076
- return localStorage.getItem(B) !== "false";
3114
+ return localStorage.getItem(K) !== "false";
3077
3115
  } catch {
3078
3116
  return !0;
3079
3117
  }
3080
3118
  }
3081
3119
  setTutorialEnabled(t) {
3082
3120
  try {
3083
- localStorage.setItem(B, String(t));
3121
+ localStorage.setItem(K, String(t));
3084
3122
  } catch {
3085
3123
  }
3086
3124
  }
@@ -3098,11 +3136,11 @@ class xt {
3098
3136
  this.isActive = !1;
3099
3137
  return;
3100
3138
  }
3101
- this.isActive = !0, this.showWarning = !1, i.length = 0, this.initialLauncherPos = { x: t * 0.28, y: e * 0.28 }, this.initialTargetPos = { x: t * 0.72, y: e * 0.28 }, this.dummyLauncher = M.createEnemy(
3139
+ this.isActive = !0, this.showWarning = !1, i.length = 0, this.initialLauncherPos = { x: t * 0.28, y: e * 0.28 }, this.initialTargetPos = { x: t * 0.72, y: e * 0.28 }, this.dummyLauncher = C.createEnemy(
3102
3140
  "piercer",
3103
3141
  this.initialLauncherPos,
3104
3142
  this.initialTargetPos
3105
- ), this.dummyLauncher.velocity = { x: 0, y: 0 }, this.dummyTarget = M.createEnemy(
3143
+ ), this.dummyLauncher.velocity = { x: 0, y: 0 }, this.dummyTarget = C.createEnemy(
3106
3144
  "spore",
3107
3145
  this.initialTargetPos,
3108
3146
  this.initialLauncherPos
@@ -3121,8 +3159,8 @@ class xt {
3121
3159
  return;
3122
3160
  }
3123
3161
  if (n.wasManipulated) {
3124
- const u = Math.hypot(n.velocity.x, n.velocity.y);
3125
- if (!n.isThrown || u < 70) {
3162
+ const p = Math.hypot(n.velocity.x, n.velocity.y);
3163
+ if (!n.isThrown || p < 70) {
3126
3164
  l && l(), this.showWarning = !0, this.resetDummies(n, o);
3127
3165
  return;
3128
3166
  }
@@ -3130,7 +3168,7 @@ class xt {
3130
3168
  n.triggerDissolveDeath(!0), o.triggerDissolveDeath(!0), this.showWarning = !1, this.isActive = !1, a();
3131
3169
  return;
3132
3170
  }
3133
- (n.position.x < -60 || n.position.x > i + 60 || n.position.y < -60 || n.position.y > s + 60 || u < 40) && (l && l(), this.showWarning = !0, this.resetDummies(n, o));
3171
+ (n.position.x < -60 || n.position.x > i + 60 || n.position.y < -60 || n.position.y > s + 60 || p < 40) && (l && l(), this.showWarning = !0, this.resetDummies(n, o));
3134
3172
  }
3135
3173
  }
3136
3174
  resetDummies(t, e) {
@@ -3140,7 +3178,7 @@ class xt {
3140
3178
  this.isActive = !1, this.showWarning = !1;
3141
3179
  }
3142
3180
  }
3143
- class yt {
3181
+ class Et {
3144
3182
  container;
3145
3183
  i18n;
3146
3184
  tutorialManager;
@@ -3176,7 +3214,7 @@ class yt {
3176
3214
  this.container.style.display = "none";
3177
3215
  }
3178
3216
  }
3179
- class Et {
3217
+ class bt {
3180
3218
  fillElement;
3181
3219
  experienceCount = 0;
3182
3220
  currentLevel = 1;
@@ -3213,7 +3251,7 @@ class Et {
3213
3251
  this.fillElement && this.fillElement.parentElement && (this.fillElement.parentElement.style.display = "none");
3214
3252
  }
3215
3253
  }
3216
- class K {
3254
+ class F {
3217
3255
  static powerUps = [
3218
3256
  {
3219
3257
  id: "spore_radius",
@@ -3225,7 +3263,7 @@ class K {
3225
3263
  rarityWeight: 35,
3226
3264
  color: "#39ff14",
3227
3265
  apply: () => {
3228
- const t = E.getInstance(), e = t.getConfig().toxicPool;
3266
+ const t = A.getInstance(), e = t.getConfig().toxicPool;
3229
3267
  t.updateConfig({
3230
3268
  toxicPool: {
3231
3269
  ...e,
@@ -3245,7 +3283,7 @@ class K {
3245
3283
  rarityWeight: 35,
3246
3284
  color: "#39ff14",
3247
3285
  apply: () => {
3248
- const t = E.getInstance(), e = t.getConfig().toxicPool;
3286
+ const t = A.getInstance(), e = t.getConfig().toxicPool;
3249
3287
  t.updateConfig({
3250
3288
  toxicPool: {
3251
3289
  ...e,
@@ -3265,7 +3303,7 @@ class K {
3265
3303
  rarityWeight: 35,
3266
3304
  color: "#9d4edd",
3267
3305
  apply: () => {
3268
- const t = E.getInstance(), e = t.getConfig().gravityVortex;
3306
+ const t = A.getInstance(), e = t.getConfig().gravityVortex;
3269
3307
  t.updateConfig({
3270
3308
  gravityVortex: {
3271
3309
  ...e,
@@ -3285,7 +3323,7 @@ class K {
3285
3323
  rarityWeight: 35,
3286
3324
  color: "#9d4edd",
3287
3325
  apply: () => {
3288
- const t = E.getInstance(), e = t.getConfig().gravityVortex;
3326
+ const t = A.getInstance(), e = t.getConfig().gravityVortex;
3289
3327
  t.updateConfig({
3290
3328
  gravityVortex: {
3291
3329
  ...e,
@@ -3305,7 +3343,7 @@ class K {
3305
3343
  rarityWeight: 25,
3306
3344
  color: "#9d4edd",
3307
3345
  apply: () => {
3308
- const t = E.getInstance(), e = t.getConfig().gravityVortex;
3346
+ const t = A.getInstance(), e = t.getConfig().gravityVortex;
3309
3347
  t.updateConfig({
3310
3348
  gravityVortex: {
3311
3349
  ...e,
@@ -3325,7 +3363,7 @@ class K {
3325
3363
  rarityWeight: 5,
3326
3364
  color: "#9d4edd",
3327
3365
  apply: () => {
3328
- const t = E.getInstance(), e = t.getConfig().gravityVortex;
3366
+ const t = A.getInstance(), e = t.getConfig().gravityVortex;
3329
3367
  t.updateConfig({
3330
3368
  gravityVortex: {
3331
3369
  ...e,
@@ -3344,7 +3382,7 @@ class K {
3344
3382
  rarityWeight: 5,
3345
3383
  color: "#00f5ff",
3346
3384
  apply: () => {
3347
- const t = E.getInstance(), e = t.getConfig().shield;
3385
+ const t = A.getInstance(), e = t.getConfig().shield;
3348
3386
  t.updateConfig({
3349
3387
  shield: {
3350
3388
  ...e,
@@ -3363,7 +3401,7 @@ class K {
3363
3401
  rarityWeight: 15,
3364
3402
  color: "#00f5ff",
3365
3403
  apply: () => {
3366
- const t = E.getInstance(), e = t.getConfig().shield;
3404
+ const t = A.getInstance(), e = t.getConfig().shield;
3367
3405
  t.updateConfig({
3368
3406
  shield: {
3369
3407
  ...e,
@@ -3384,7 +3422,7 @@ class K {
3384
3422
  rarityWeight: 35,
3385
3423
  color: "#00f5ff",
3386
3424
  apply: () => {
3387
- const t = E.getInstance(), e = t.getConfig().shield;
3425
+ const t = A.getInstance(), e = t.getConfig().shield;
3388
3426
  t.updateConfig({
3389
3427
  shield: {
3390
3428
  ...e,
@@ -3403,7 +3441,7 @@ class K {
3403
3441
  rarityWeight: 25,
3404
3442
  color: "#ffcc00",
3405
3443
  apply: () => {
3406
- const t = E.getInstance(), e = t.getConfig().cluster;
3444
+ const t = A.getInstance(), e = t.getConfig().cluster;
3407
3445
  t.updateConfig({
3408
3446
  cluster: {
3409
3447
  ...e,
@@ -3422,7 +3460,7 @@ class K {
3422
3460
  rarityWeight: 5,
3423
3461
  color: "#ffcc00",
3424
3462
  apply: () => {
3425
- const t = E.getInstance(), e = t.getConfig().cluster;
3463
+ const t = A.getInstance(), e = t.getConfig().cluster;
3426
3464
  t.updateConfig({
3427
3465
  cluster: {
3428
3466
  ...e,
@@ -3441,7 +3479,7 @@ class K {
3441
3479
  rarityWeight: 15,
3442
3480
  color: "#ff3366",
3443
3481
  apply: () => {
3444
- const t = E.getInstance(), e = t.getConfig().piercer;
3482
+ const t = A.getInstance(), e = t.getConfig().piercer;
3445
3483
  t.updateConfig({
3446
3484
  piercer: {
3447
3485
  ...e,
@@ -3460,7 +3498,7 @@ class K {
3460
3498
  rarityWeight: 5,
3461
3499
  color: "#ff2a5f",
3462
3500
  apply: () => {
3463
- const t = E.getInstance(), e = t.getConfig().piercer;
3501
+ const t = A.getInstance(), e = t.getConfig().piercer;
3464
3502
  t.updateConfig({
3465
3503
  piercer: {
3466
3504
  ...e,
@@ -3479,7 +3517,7 @@ class K {
3479
3517
  rarityWeight: 5,
3480
3518
  color: "#00f0ff",
3481
3519
  apply: () => {
3482
- const t = E.getInstance(), e = t.getConfig().core;
3520
+ const t = A.getInstance(), e = t.getConfig().core;
3483
3521
  t.updateConfig({
3484
3522
  core: {
3485
3523
  ...e,
@@ -3498,7 +3536,7 @@ class K {
3498
3536
  rarityWeight: 15,
3499
3537
  color: "#ff2a5f",
3500
3538
  apply: () => {
3501
- const t = E.getInstance(), e = t.getConfig().piercer;
3539
+ const t = A.getInstance(), e = t.getConfig().piercer;
3502
3540
  t.updateConfig({
3503
3541
  piercer: {
3504
3542
  ...e,
@@ -3517,7 +3555,7 @@ class K {
3517
3555
  rarityWeight: 15,
3518
3556
  color: "#00f5ff",
3519
3557
  apply: () => {
3520
- const t = E.getInstance(), e = t.getConfig().core;
3558
+ const t = A.getInstance(), e = t.getConfig().core;
3521
3559
  t.updateConfig({
3522
3560
  core: {
3523
3561
  ...e,
@@ -3536,7 +3574,7 @@ class K {
3536
3574
  rarityWeight: 25,
3537
3575
  color: "#00f5ff",
3538
3576
  apply: () => {
3539
- const t = E.getInstance(), e = t.getConfig().core;
3577
+ const t = A.getInstance(), e = t.getConfig().core;
3540
3578
  t.updateConfig({
3541
3579
  core: {
3542
3580
  ...e,
@@ -3555,7 +3593,7 @@ class K {
3555
3593
  rarityWeight: 20,
3556
3594
  color: "#00f5ff",
3557
3595
  apply: (t) => {
3558
- E.getInstance().addCoreRing(1), t && t.addMaxRing(1);
3596
+ A.getInstance().addCoreRing(1), t && t.addMaxRing(1);
3559
3597
  }
3560
3598
  },
3561
3599
  {
@@ -3568,7 +3606,7 @@ class K {
3568
3606
  rarityWeight: 35,
3569
3607
  color: "#00f5ff",
3570
3608
  apply: () => {
3571
- const t = E.getInstance(), e = t.getConfig().magnet;
3609
+ const t = A.getInstance(), e = t.getConfig().magnet;
3572
3610
  t.updateConfig({
3573
3611
  magnet: {
3574
3612
  ...e,
@@ -3587,7 +3625,7 @@ class K {
3587
3625
  rarityWeight: 25,
3588
3626
  color: "#00f5ff",
3589
3627
  apply: () => {
3590
- const t = E.getInstance(), e = t.getConfig().magnet;
3628
+ const t = A.getInstance(), e = t.getConfig().magnet;
3591
3629
  t.updateConfig({
3592
3630
  magnet: {
3593
3631
  ...e,
@@ -3598,7 +3636,7 @@ class K {
3598
3636
  }
3599
3637
  ];
3600
3638
  static getRandomOptions(t = 3) {
3601
- const e = E.getInstance().getConfig(), i = this.powerUps.filter((a) => !(a.id === "vampirism_unlock" && e.core.vampirismHealProgressRate > 0 || a.id === "vampirism_boost" && e.core.vampirismHealProgressRate <= 0 || a.id === "piercer_homing" && e.piercer.hasHoming || a.id === "piercer_homing_target" && !e.piercer.hasHoming || a.id === "vortex_pocket" && e.gravityVortex.hasImplosionLaunch || a.id === "shield_fan" && e.shield.isFanBlast || a.id === "shield_fan_upgrade" && (!e.shield.isFanBlast || e.shield.hasFanBlastUpgrade) || a.id === "cluster_homing" && e.cluster.hasHoming || a.id === "offscreen_radar" && e.core.hasOffscreenIndicators)), s = [];
3639
+ const e = A.getInstance().getConfig(), i = this.powerUps.filter((a) => !(a.id === "vampirism_unlock" && e.core.vampirismHealProgressRate > 0 || a.id === "vampirism_boost" && e.core.vampirismHealProgressRate <= 0 || a.id === "piercer_homing" && e.piercer.hasHoming || a.id === "piercer_homing_target" && !e.piercer.hasHoming || a.id === "vortex_pocket" && e.gravityVortex.hasImplosionLaunch || a.id === "shield_fan" && e.shield.isFanBlast || a.id === "shield_fan_upgrade" && (!e.shield.isFanBlast || e.shield.hasFanBlastUpgrade) || a.id === "cluster_homing" && e.cluster.hasHoming || a.id === "offscreen_radar" && e.core.hasOffscreenIndicators)), s = [];
3602
3640
  for (let a = 0; a < t && i.length > 0; a++) {
3603
3641
  const l = i.reduce((o, r) => o + r.rarityWeight, 0);
3604
3642
  let n = Math.random() * l;
@@ -3656,7 +3694,125 @@ class At {
3656
3694
  }
3657
3695
  };
3658
3696
  }
3659
- class bt {
3697
+ class vt {
3698
+ enabled;
3699
+ overlay;
3700
+ copyButton;
3701
+ frameStart = 0;
3702
+ lastFrameEnd = 0;
3703
+ updateMs = 0;
3704
+ physicsMs = 0;
3705
+ renderMs = 0;
3706
+ frameMs = 0;
3707
+ fps = 0;
3708
+ fpsLimit = 60;
3709
+ state = "MENU";
3710
+ lastReport = "";
3711
+ slowFrames = 0;
3712
+ lastReportAt = 0;
3713
+ counts = {
3714
+ enemies: 0,
3715
+ particles: 0,
3716
+ shockwaves: 0,
3717
+ pools: 0,
3718
+ vortices: 0,
3719
+ floatingTexts: 0
3720
+ };
3721
+ constructor(t, e) {
3722
+ if (this.enabled = e, !e) {
3723
+ this.overlay = null, this.copyButton = null;
3724
+ return;
3725
+ }
3726
+ const i = document.createElement("pre");
3727
+ i.setAttribute("aria-label", "Performance audit"), i.style.cssText = [
3728
+ "position:fixed",
3729
+ "top:10px",
3730
+ "left:10px",
3731
+ "z-index:10000",
3732
+ "margin:0",
3733
+ "padding:8px 10px",
3734
+ "min-width:220px",
3735
+ "border:1px solid rgba(0,245,255,.55)",
3736
+ "border-radius:6px",
3737
+ "background:rgba(3,8,18,.88)",
3738
+ "color:#b8fbff",
3739
+ "font:12px/1.35 monospace",
3740
+ "pointer-events:none",
3741
+ "white-space:pre"
3742
+ ].join(";"), i.textContent = `PERF AUDIT
3743
+ starting…`, t.appendChild(i), this.overlay = i;
3744
+ const s = document.createElement("button");
3745
+ s.type = "button", s.textContent = "COPY AUDIT", s.style.cssText = [
3746
+ "position:fixed",
3747
+ "top:185px",
3748
+ "left:10px",
3749
+ "z-index:10001",
3750
+ "padding:4px 7px",
3751
+ "border:1px solid rgba(0,245,255,.55)",
3752
+ "border-radius:4px",
3753
+ "background:rgba(3,8,18,.94)",
3754
+ "color:#b8fbff",
3755
+ "font:11px monospace",
3756
+ "cursor:pointer"
3757
+ ].join(";"), s.addEventListener("click", () => {
3758
+ this.copyReport();
3759
+ }), t.appendChild(s), this.copyButton = s;
3760
+ }
3761
+ beginFrame() {
3762
+ this.enabled && (this.frameStart = performance.now());
3763
+ }
3764
+ setFpsLimit(t) {
3765
+ (t === 30 || t === 60 || t === 120) && (this.fpsLimit = t);
3766
+ }
3767
+ setState(t) {
3768
+ this.state = t;
3769
+ }
3770
+ finishUpdate(t, e) {
3771
+ !this.enabled || this.frameStart <= 0 || (this.updateMs = performance.now() - this.frameStart, this.physicsMs = t, this.counts = e);
3772
+ }
3773
+ finishRender(t) {
3774
+ if (!this.enabled || this.frameStart <= 0) return;
3775
+ const e = performance.now();
3776
+ this.renderMs = e - t, this.frameMs = this.lastFrameEnd > 0 ? e - this.lastFrameEnd : e - this.frameStart, this.lastFrameEnd = e;
3777
+ const i = this.frameMs > 0 ? 1e3 / this.frameMs : 0;
3778
+ this.fps = this.fps === 0 ? i : this.fps * 0.9 + i * 0.1, this.frameMs > 20 && this.slowFrames++, e - this.lastReportAt >= 250 && (this.lastReportAt = e, this.renderOverlay());
3779
+ }
3780
+ destroy() {
3781
+ this.overlay?.remove(), this.copyButton?.remove();
3782
+ }
3783
+ async copyReport() {
3784
+ const t = this.lastReport || this.overlay?.textContent || "";
3785
+ try {
3786
+ await navigator.clipboard.writeText(t);
3787
+ } catch {
3788
+ const e = document.createElement("textarea");
3789
+ e.value = t, document.body.appendChild(e), e.select(), document.execCommand("copy"), e.remove();
3790
+ }
3791
+ this.copyButton && (this.copyButton.textContent = "COPIED", window.setTimeout(() => {
3792
+ this.copyButton && (this.copyButton.textContent = "COPY AUDIT");
3793
+ }, 900));
3794
+ }
3795
+ renderOverlay() {
3796
+ if (!this.overlay) return;
3797
+ const t = performance.memory, e = t ? `
3798
+ HEAP ${(t.usedJSHeapSize / 1024 / 1024).toFixed(1)} MB` : "";
3799
+ this.lastReport = [
3800
+ "PERF AUDIT (?debug)",
3801
+ `STATE ${this.state}`,
3802
+ `FPS ${this.fps.toFixed(1)} / CAP ${this.fpsLimit} slow ${this.slowFrames}`,
3803
+ `FRAME ${this.frameMs.toFixed(1)} ms`,
3804
+ `UPDATE ${this.updateMs.toFixed(1)} ms`,
3805
+ `PHYS ${this.physicsMs.toFixed(1)} ms`,
3806
+ `RENDER ${this.renderMs.toFixed(1)} ms`,
3807
+ `ENEMY ${this.counts.enemies}`,
3808
+ `PART ${this.counts.particles} SW ${this.counts.shockwaves}`,
3809
+ `POOL ${this.counts.pools} VTX ${this.counts.vortices}`,
3810
+ `TEXT ${this.counts.floatingTexts}${e}`
3811
+ ].join(`
3812
+ `), this.overlay.textContent = this.lastReport;
3813
+ }
3814
+ }
3815
+ class It {
3660
3816
  container;
3661
3817
  canvas;
3662
3818
  i18n;
@@ -3675,6 +3831,7 @@ class bt {
3675
3831
  interactiveTutorial;
3676
3832
  tutorialOverlay;
3677
3833
  progressBar;
3834
+ performanceAudit;
3678
3835
  core;
3679
3836
  enemies = [];
3680
3837
  ambientEnemies = [];
@@ -3688,13 +3845,14 @@ class bt {
3688
3845
  isLevelUpActive = !1;
3689
3846
  pendingLevelUps = [];
3690
3847
  debugRerollsEnabled = typeof window < "u" && window.location.hostname === "localhost" && new URLSearchParams(window.location.search).has("debug");
3848
+ debugPerformanceEnabled = typeof window < "u" && new URLSearchParams(window.location.search).has("debug");
3691
3849
  rerollsRemaining = 1;
3692
3850
  score = { value: 0 };
3693
3851
  combo = { value: 0 };
3694
3852
  isRunning = !1;
3695
3853
  isPaused = !1;
3696
3854
  constructor(t) {
3697
- this.container = t.root, this.container.classList.add("axon-game-root"), this.i18n = new $(t.language), this.themeManager = new ht(t.theme, this.container), this.platform = t.platform || new At(), this.canvas = document.createElement("canvas"), this.canvas.className = "axon-canvas", this.container.appendChild(this.canvas), this.resizeCanvas(), window.addEventListener("resize", () => this.resizeCanvas()), this.eventBus = new F(), this.core = new Y(this.canvas.width / 2, this.canvas.height / 2), this.inputManager = new Z(this.canvas), this.physicsEngine = new nt(this.eventBus, this.i18n), this.waveDirector = new lt(), this.renderer = new gt(this.canvas, this.themeManager), this.juice = new J(), this.settingsModal = new mt(
3855
+ this.container = t.root, this.container.classList.add("axon-game-root"), this.i18n = new X(t.language), this.themeManager = new pt(t.theme, this.container), this.platform = t.platform || new At(), this.canvas = document.createElement("canvas"), this.canvas.className = "axon-canvas", this.container.appendChild(this.canvas), this.resizeCanvas(), window.addEventListener("resize", () => this.resizeCanvas()), this.eventBus = new W(), this.core = new Z(this.canvas.width / 2, this.canvas.height / 2), this.inputManager = new $(this.canvas), this.physicsEngine = new rt(this.eventBus, this.i18n), this.waveDirector = new ct(), this.renderer = new _t(this.canvas, this.themeManager), this.juice = new J(), this.settingsModal = new xt(
3698
3856
  this.container,
3699
3857
  this.i18n,
3700
3858
  this.themeManager,
@@ -3702,15 +3860,18 @@ class bt {
3702
3860
  (e) => this.onLanguageChanged(e),
3703
3861
  () => {
3704
3862
  this.isPaused = !1;
3863
+ },
3864
+ (e) => {
3865
+ this.gameLoop.setFpsLimit(e), this.performanceAudit.setFpsLimit(e);
3705
3866
  }
3706
- ), this.interactiveTutorial = new xt(), this.tutorialOverlay = new yt(this.container, this.i18n, this.interactiveTutorial), this.hud = new _t(this.container, this.i18n, () => {
3867
+ ), this.interactiveTutorial = new yt(), this.tutorialOverlay = new Et(this.container, this.i18n, this.interactiveTutorial), this.hud = new mt(this.container, this.i18n, () => {
3707
3868
  this.isPaused = !0, this.settingsModal.show();
3708
- }), this.hud.show(), this.progressBar = new Et(this.hud.progressSlot, (e) => {
3869
+ }), this.hud.show(), this.progressBar = new bt(this.hud.progressSlot, (e) => {
3709
3870
  this.waveDirector.wave = e, this.triggerLevelUp(e);
3710
- }), this.startMenu = new ft(this.container, this.i18n, () => this.startGame()), this.initAmbientArena(), this.gameLoop = new W(
3871
+ }), this.performanceAudit = new vt(this.container, this.debugPerformanceEnabled), this.startMenu = new ft(this.container, this.i18n, () => this.startGame()), this.initAmbientArena(), this.gameLoop = new Y(
3711
3872
  (e) => this.update(e),
3712
3873
  () => this.render()
3713
- ), this.setupEvents(), this.gameLoop.start();
3874
+ ), this.gameLoop.setFpsLimit(this.settingsModal.getFpsLimit()), this.performanceAudit.setFpsLimit(this.settingsModal.getFpsLimit()), this.setupEvents(), this.gameLoop.start();
3714
3875
  }
3715
3876
  setLanguage(t) {
3716
3877
  this.i18n.setLanguage(t), this.onLanguageChanged(t);
@@ -3734,7 +3895,7 @@ class bt {
3734
3895
  const i = t[e % t.length], s = e * Math.PI * 2 / 16, a = 180 + Math.random() * 220, l = {
3735
3896
  x: this.canvas.width / 2 + Math.cos(s) * a,
3736
3897
  y: this.canvas.height / 2 + Math.sin(s) * a
3737
- }, n = M.createEnemy(i, l, {
3898
+ }, n = C.createEnemy(i, l, {
3738
3899
  x: l.x + Math.sin(s) * 100,
3739
3900
  y: l.y - Math.cos(s) * 100
3740
3901
  });
@@ -3765,12 +3926,20 @@ class bt {
3765
3926
  }), this.canvas.addEventListener("touchstart", () => t(!0), { passive: !0 }), this.canvas.addEventListener("touchend", e, { passive: !0 }), this.canvas.addEventListener("touchcancel", e, { passive: !0 });
3766
3927
  }
3767
3928
  startGame() {
3768
- E.getInstance().resetToDefault(), this.score.value = 0, this.combo.value = 0, this.enemies = [], this.ambientEnemies = [], this.pools = [], this.vortices = [], this.shockwaves = [], this.particles = [], this.floatingTexts = [], this.experienceOrbs = [], this.orbitingOrbs = [], this.isLevelUpActive = !1, this.pendingLevelUps = [], this.rerollsRemaining = this.getRerollLimit(), this.core.reset(this.canvas.width / 2, this.canvas.height / 2), this.waveDirector.reset(), this.inputManager.reset(), this.hud.show(), this.hud.update(1, 0), this.progressBar.reset(), this.progressBar.show(), this.isPaused = !1, this.isRunning = !0, this.interactiveTutorial.isTutorialEnabled() ? (this.interactiveTutorial.start(this.canvas.width, this.canvas.height, this.enemies), this.tutorialOverlay.show()) : (this.interactiveTutorial.isActive = !1, this.tutorialOverlay.hide());
3929
+ A.getInstance().resetToDefault(), this.score.value = 0, this.combo.value = 0, this.enemies = [], this.ambientEnemies = [], this.pools = [], this.vortices = [], this.shockwaves = [], this.particles = [], this.floatingTexts = [], this.experienceOrbs = [], this.orbitingOrbs = [], this.isLevelUpActive = !1, this.pendingLevelUps = [], this.rerollsRemaining = this.getRerollLimit(), this.core.reset(this.canvas.width / 2, this.canvas.height / 2), this.waveDirector.reset(), this.inputManager.reset(), this.hud.show(), this.hud.update(1, 0), this.progressBar.reset(), this.progressBar.show(), this.isPaused = !1, this.isRunning = !0, this.interactiveTutorial.isTutorialEnabled() ? (this.interactiveTutorial.start(this.canvas.width, this.canvas.height, this.enemies), this.tutorialOverlay.show()) : (this.interactiveTutorial.isActive = !1, this.tutorialOverlay.hide());
3769
3930
  }
3770
3931
  update(t) {
3771
- if (this.core.update(t), !this.isRunning || this.isPaused) {
3772
- for (const e of this.ambientEnemies)
3773
- e.update(t), e.position.x < -40 && (e.position.x = this.canvas.width + 40), e.position.x > this.canvas.width + 40 && (e.position.x = -40), e.position.y < -40 && (e.position.y = this.canvas.height + 40), e.position.y > this.canvas.height + 40 && (e.position.y = -40);
3932
+ if (this.performanceAudit.beginFrame(), this.performanceAudit.setState(this.isRunning ? this.isPaused ? "PAUSED" : "GAME" : "MENU"), this.core.update(t), !this.isRunning || this.isPaused) {
3933
+ for (const i of this.ambientEnemies)
3934
+ i.update(t), i.position.x < -40 && (i.position.x = this.canvas.width + 40), i.position.x > this.canvas.width + 40 && (i.position.x = -40), i.position.y < -40 && (i.position.y = this.canvas.height + 40), i.position.y > this.canvas.height + 40 && (i.position.y = -40);
3935
+ this.performanceAudit.finishUpdate(0, {
3936
+ enemies: this.ambientEnemies.length,
3937
+ particles: this.particles.length,
3938
+ shockwaves: this.shockwaves.length,
3939
+ pools: this.pools.length,
3940
+ vortices: this.vortices.length,
3941
+ floatingTexts: this.floatingTexts.length
3942
+ });
3774
3943
  return;
3775
3944
  }
3776
3945
  if (this.interactiveTutorial.isActive)
@@ -3785,50 +3954,50 @@ class bt {
3785
3954
  () => this.inputManager.forceRelease()
3786
3955
  ), this.tutorialOverlay.updateStep(this.interactiveTutorial.getStep());
3787
3956
  else if (!this.isLevelUpActive) {
3788
- const e = this.waveDirector.update(
3957
+ const i = this.waveDirector.update(
3789
3958
  t,
3790
3959
  this.enemies,
3791
3960
  this.canvas.width,
3792
3961
  this.canvas.height,
3793
3962
  this.core.position
3794
3963
  );
3795
- e && this.enemies.push(e);
3964
+ i && this.enemies.push(i);
3796
3965
  }
3797
3966
  if (this.isLevelUpActive) {
3798
3967
  this.inputManager.tryGrabOrb(this.orbitingOrbs);
3799
- const e = this.inputManager.grabbedOrb;
3800
- !this.inputManager.isPointerDown && e && (e.isGrabbed = !1, this.inputManager.grabbedOrb = null);
3801
- const i = this.inputManager.pointerPosition;
3968
+ const i = this.inputManager.grabbedOrb;
3969
+ !this.inputManager.isPointerDown && i && (i.isGrabbed = !1, this.inputManager.grabbedOrb = null);
3970
+ const s = this.inputManager.pointerPosition;
3802
3971
  if (this.inputManager.isPointerDown && !this.inputManager.grabbedOrb && this.rerollsRemaining > 0) {
3803
- const s = this.canvas.width / 2, a = this.canvas.height / 2 + 210;
3804
- Math.hypot(i.x - s, i.y - a) <= 80 && (this.triggerReroll(), this.inputManager.isPointerDown = !1);
3972
+ const a = this.canvas.width / 2, l = this.canvas.height / 2 + 210;
3973
+ Math.hypot(s.x - a, s.y - l) <= 80 && (this.triggerReroll(), this.inputManager.isPointerDown = !1);
3805
3974
  }
3806
- for (const s of this.orbitingOrbs) {
3807
- const a = i.x - s.position.x, l = i.y - s.position.y;
3808
- if (s.isHovered = Math.hypot(a, l) <= s.radius * 1.5, s === e && this.inputManager.isPointerDown) {
3809
- s.position = { ...this.inputManager.pointerPosition };
3810
- const n = this.core.position.x - s.position.x, o = this.core.position.y - s.position.y;
3811
- if (Math.hypot(n, o) <= this.core.radius + s.radius) {
3812
- s.definition.apply(this.core), this.core.absorbPowerUpColor(s.definition.color, 0.4), this.juice.triggerFlash(0.8), this.juice.triggerScreenShake({ x: n, y: o }, 24);
3813
- const c = this.i18n.translate(s.definition.titleKey);
3975
+ for (const a of this.orbitingOrbs) {
3976
+ const l = s.x - a.position.x, n = s.y - a.position.y;
3977
+ if (a.isHovered = Math.hypot(l, n) <= a.radius * 1.5, a === i && this.inputManager.isPointerDown) {
3978
+ a.position = { ...this.inputManager.pointerPosition };
3979
+ const o = this.core.position.x - a.position.x, r = this.core.position.y - a.position.y;
3980
+ if (Math.hypot(o, r) <= this.core.radius + a.radius) {
3981
+ a.definition.apply(this.core), this.core.absorbPowerUpColor(a.definition.color, 0.4), this.juice.triggerFlash(0.8), this.juice.triggerScreenShake({ x: o, y: r }, 24);
3982
+ const h = this.i18n.translate(a.definition.titleKey);
3814
3983
  this.floatingTexts.push({
3815
3984
  id: Math.random().toString(),
3816
- text: `+ ${c}`,
3985
+ text: `+ ${h}`,
3817
3986
  position: { ...this.core.position },
3818
3987
  velocity: { x: 0, y: -80 },
3819
- color: s.definition.color,
3988
+ color: a.definition.color,
3820
3989
  alpha: 1,
3821
3990
  lifetime: 0,
3822
3991
  maxLifetime: 1.6,
3823
3992
  size: 26
3824
3993
  });
3825
- for (let h = 0; h < 45; h++) {
3826
- const u = Math.random() * Math.PI * 2, d = 200 + Math.random() * 400;
3994
+ for (let p = 0; p < 45; p++) {
3995
+ const d = Math.random() * Math.PI * 2, _ = 200 + Math.random() * 400;
3827
3996
  this.particles.push({
3828
3997
  id: Math.random().toString(),
3829
3998
  position: { ...this.core.position },
3830
- velocity: { x: Math.cos(u) * d, y: Math.sin(u) * d },
3831
- color: s.definition.color,
3999
+ velocity: { x: Math.cos(d) * _, y: Math.sin(d) * _ },
4000
+ color: a.definition.color,
3832
4001
  radius: 4 + Math.random() * 5,
3833
4002
  alpha: 1,
3834
4003
  lifetime: 0,
@@ -3838,37 +4007,49 @@ class bt {
3838
4007
  this.inputManager.forceRelease(), this.orbitingOrbs = [], this.presentNextLevelUp();
3839
4008
  }
3840
4009
  } else
3841
- s.update(t, this.core.position);
4010
+ a.update(t, this.core.position);
3842
4011
  }
3843
4012
  }
3844
- !this.isLevelUpActive && this.juice.hitstopTime <= 0 && this.physicsEngine.update(
3845
- t,
3846
- this.core,
3847
- this.enemies,
3848
- this.pools,
3849
- this.vortices,
3850
- this.shockwaves,
3851
- this.particles,
3852
- this.floatingTexts,
3853
- this.juice,
3854
- this.combo,
3855
- this.score,
3856
- this.canvas.width,
3857
- this.canvas.height,
3858
- () => {
3859
- this.core.addKillRepair() && (this.juice.triggerFlash(0.4), this.floatingTexts.push({
3860
- id: Math.random().toString(),
3861
- text: "RING RESTORED!",
3862
- position: { ...this.core.position },
3863
- velocity: { x: 0, y: -60 },
3864
- color: "#00f5ff",
3865
- alpha: 1,
3866
- lifetime: 0,
3867
- maxLifetime: 1.2,
3868
- size: 22
3869
- }));
3870
- }
3871
- ), this.spawnExperienceDrops(), this.isLevelUpActive || this.updateExperienceOrbs(t), this.hud.update(this.progressBar.getLevel(), this.combo.value), this.juice.update(t, this.floatingTexts, this.particles), this.enemies = this.enemies.filter((e) => e.active);
4013
+ let e = 0;
4014
+ if (!this.isLevelUpActive) {
4015
+ const i = this.debugPerformanceEnabled ? performance.now() : 0;
4016
+ this.physicsEngine.update(
4017
+ t,
4018
+ this.core,
4019
+ this.enemies,
4020
+ this.pools,
4021
+ this.vortices,
4022
+ this.shockwaves,
4023
+ this.particles,
4024
+ this.floatingTexts,
4025
+ this.juice,
4026
+ this.combo,
4027
+ this.score,
4028
+ this.canvas.width,
4029
+ this.canvas.height,
4030
+ () => {
4031
+ this.core.addKillRepair() && (this.juice.triggerFlash(0.4), this.floatingTexts.push({
4032
+ id: Math.random().toString(),
4033
+ text: "RING RESTORED!",
4034
+ position: { ...this.core.position },
4035
+ velocity: { x: 0, y: -60 },
4036
+ color: "#00f5ff",
4037
+ alpha: 1,
4038
+ lifetime: 0,
4039
+ maxLifetime: 1.2,
4040
+ size: 22
4041
+ }));
4042
+ }
4043
+ ), e = this.debugPerformanceEnabled ? performance.now() - i : 0;
4044
+ }
4045
+ this.spawnExperienceDrops(), this.isLevelUpActive || this.updateExperienceOrbs(t), this.hud.update(this.progressBar.getLevel(), this.combo.value), this.juice.update(t, this.floatingTexts, this.particles), this.enemies = this.enemies.filter((i) => i.active), this.performanceAudit.finishUpdate(e, {
4046
+ enemies: this.enemies.length,
4047
+ particles: this.particles.length,
4048
+ shockwaves: this.shockwaves.length,
4049
+ pools: this.pools.length,
4050
+ vortices: this.vortices.length,
4051
+ floatingTexts: this.floatingTexts.length
4052
+ });
3872
4053
  }
3873
4054
  triggerLevelUp(t) {
3874
4055
  this.pendingLevelUps.push(t), this.isLevelUpActive || this.presentNextLevelUp();
@@ -3903,18 +4084,18 @@ class bt {
3903
4084
  maxLifetime: 0.7
3904
4085
  });
3905
4086
  }
3906
- const e = K.getRandomOptions(3);
4087
+ const e = F.getRandomOptions(3);
3907
4088
  this.orbitingOrbs = e.map((i, s) => {
3908
4089
  const a = s * Math.PI * 2 / e.length;
3909
- return new G(`orb_${Date.now()}_${s}`, i, a);
4090
+ return new H(`orb_${Date.now()}_${s}`, i, a);
3910
4091
  }), this.rerollsRemaining = this.getRerollLimit();
3911
4092
  }
3912
4093
  spawnExperienceDrops() {
3913
4094
  for (const t of this.enemies)
3914
- t.experienceDropPending && (t.experienceDropPending = !1, this.experienceOrbs.push(new ct(t.position)));
4095
+ t.experienceDropPending && (t.experienceDropPending = !1, this.experienceOrbs.push(new ht(t.position)));
3915
4096
  }
3916
4097
  updateExperienceOrbs(t) {
3917
- const e = E.getInstance().getConfig().magnet;
4098
+ const e = A.getInstance().getConfig().magnet;
3918
4099
  for (const i of this.experienceOrbs)
3919
4100
  if (i.active) {
3920
4101
  if (i.isAbsorbing || Math.hypot(
@@ -3941,17 +4122,17 @@ class bt {
3941
4122
  triggerReroll() {
3942
4123
  if (this.rerollsRemaining <= 0) return;
3943
4124
  this.rerollsRemaining -= 1, this.juice.triggerFlash(0.4);
3944
- const t = K.getRandomOptions(3);
4125
+ const t = F.getRandomOptions(3);
3945
4126
  this.orbitingOrbs = t.map((e, i) => {
3946
4127
  const s = i * Math.PI * 2 / t.length;
3947
- return new G(`orb_${Date.now()}_${i}`, e, s);
4128
+ return new H(`orb_${Date.now()}_${i}`, e, s);
3948
4129
  });
3949
4130
  }
3950
4131
  render() {
3951
- const t = this.isRunning ? this.enemies : this.ambientEnemies;
4132
+ const t = this.debugPerformanceEnabled ? performance.now() : 0, e = this.isRunning ? this.enemies : this.ambientEnemies;
3952
4133
  this.renderer.render(
3953
4134
  this.core,
3954
- t,
4135
+ e,
3955
4136
  this.experienceOrbs,
3956
4137
  this.pools,
3957
4138
  this.vortices,
@@ -3969,23 +4150,23 @@ class bt {
3969
4150
  this.i18n,
3970
4151
  this.rerollsRemaining > 0,
3971
4152
  this.rerollsRemaining
3972
- );
4153
+ ), this.performanceAudit.finishRender(t);
3973
4154
  }
3974
4155
  getRerollLimit() {
3975
4156
  return this.debugRerollsEnabled ? 99 : 1;
3976
4157
  }
3977
4158
  destroy() {
3978
- this.gameLoop.stop(), this.canvas.remove();
4159
+ this.gameLoop.stop(), this.performanceAudit.destroy(), this.canvas.remove();
3979
4160
  }
3980
4161
  }
3981
- function vt(A) {
3982
- return new bt(A);
4162
+ function St(E) {
4163
+ return new It(E);
3983
4164
  }
3984
4165
  export {
3985
4166
  At as BrowserPlatform,
3986
- bt as GameEngine,
4167
+ It as GameEngine,
3987
4168
  V as LANGUAGES,
3988
- ht as ThemeManager,
3989
- vt as createAxonSurge,
3990
- N as isLanguage
4169
+ pt as ThemeManager,
4170
+ St as createAxonSurge,
4171
+ w as isLanguage
3991
4172
  };