@gamebob/axon-surge 0.15.0 → 0.17.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.
Files changed (33) hide show
  1. package/dist/axon-surge.js +1203 -983
  2. package/dist/core/GameEngine.d.ts +2 -0
  3. package/dist/core/GameEngine.d.ts.map +1 -1
  4. package/dist/core/GameLoop.d.ts +5 -0
  5. package/dist/core/GameLoop.d.ts.map +1 -1
  6. package/dist/core/PerformanceAudit.d.ts +36 -0
  7. package/dist/core/PerformanceAudit.d.ts.map +1 -0
  8. package/dist/entities/EnemyEntity.d.ts.map +1 -1
  9. package/dist/factory/EntityFactory.d.ts.map +1 -1
  10. package/dist/i18n/locales.d.ts +1 -0
  11. package/dist/i18n/locales.d.ts.map +1 -1
  12. package/dist/physics/handlers/CoreCollisionHandler.d.ts.map +1 -1
  13. package/dist/physics/handlers/ThrownCollisionHandler.d.ts.map +1 -1
  14. package/dist/powerups/PowerUpRegistry.d.ts.map +1 -1
  15. package/dist/powerups/PowerUpTypes.d.ts.map +1 -1
  16. package/dist/render/CanvasRenderer.d.ts +1 -0
  17. package/dist/render/CanvasRenderer.d.ts.map +1 -1
  18. package/dist/render/EnemyShapeRenderer.d.ts +12 -0
  19. package/dist/render/EnemyShapeRenderer.d.ts.map +1 -0
  20. package/dist/render/JuiceEffects.d.ts +1 -2
  21. package/dist/render/JuiceEffects.d.ts.map +1 -1
  22. package/dist/render/TutorialArrowRenderer.d.ts.map +1 -1
  23. package/dist/strategies/FragmentClusterStrategy.d.ts.map +1 -1
  24. package/dist/strategies/GravityParasiteStrategy.d.ts.map +1 -1
  25. package/dist/strategies/HeavyShieldStrategy.d.ts.map +1 -1
  26. package/dist/strategies/PiercingCellStrategy.d.ts.map +1 -1
  27. package/dist/strategies/ToxicSporeStrategy.d.ts.map +1 -1
  28. package/dist/theme/GameColors.d.ts +16 -0
  29. package/dist/theme/GameColors.d.ts.map +1 -0
  30. package/dist/theme/ThemeManager.d.ts.map +1 -1
  31. package/dist/ui/SettingsModal.d.ts +5 -1
  32. package/dist/ui/SettingsModal.d.ts.map +1 -1
  33. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- class F {
1
+ class Y {
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 Z {
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 H = {
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 v {
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(H));
93
106
  }
94
107
  static getInstance() {
95
- return E.instance || (E.instance = new E()), E.instance;
108
+ return v.instance || (v.instance = new v()), v.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(H));
114
127
  }
115
128
  }
116
- class Y {
129
+ class $ {
117
130
  position;
118
131
  radius;
119
132
  integrity;
@@ -126,15 +139,15 @@ class Y {
126
139
  powerUpCount = 0;
127
140
  collectedPowerUpColors = [];
128
141
  constructor(t, e) {
129
- const i = E.getInstance().getConfig().core;
142
+ const i = v.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) {
133
146
  this.powerUpCount++, this.collectedPowerUpColors.push(t);
134
147
  const i = t.replace("#", "");
135
148
  if (i.length === 6) {
136
- const s = parseInt(i.substring(0, 2), 16), a = parseInt(i.substring(2, 4), 16), l = parseInt(i.substring(4, 6), 16);
137
- this.customColor.r = Math.round(this.customColor.r * (1 - e) + s * e), this.customColor.g = Math.round(this.customColor.g * (1 - e) + a * e), this.customColor.b = Math.round(this.customColor.b * (1 - e) + l * e);
149
+ const s = parseInt(i.substring(0, 2), 16), a = parseInt(i.substring(2, 4), 16), r = parseInt(i.substring(4, 6), 16);
150
+ this.customColor.r = Math.round(this.customColor.r * (1 - e) + s * e), this.customColor.g = Math.round(this.customColor.g * (1 - e) + a * e), this.customColor.b = Math.round(this.customColor.b * (1 - e) + r * e);
138
151
  }
139
152
  }
140
153
  getHitboxRadius() {
@@ -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 = v.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,25 @@ 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 = v.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
+ const f = {
187
+ piercer: "#ff2a5f",
188
+ spore: "#39ff14",
189
+ cluster: "#ffd700",
190
+ parasite: "#9d4edd",
191
+ heavy: "#c8d0d8",
192
+ heavyAccent: "#7d8994",
193
+ micro: "#ffd700",
194
+ core: "#00f0ff",
195
+ coreGlow: "rgba(0, 240, 255, 0.85)",
196
+ coreAccent: "#ff00dd",
197
+ shieldEye: "#ffd447",
198
+ experience: "#fbbf24"
199
+ };
200
+ class G {
174
201
  id;
175
202
  position = { x: 0, y: 0 };
176
203
  velocity = { x: 0, y: 0 };
@@ -181,7 +208,7 @@ class w {
181
208
  isThrown = !1;
182
209
  wasManipulated = !1;
183
210
  rotation = 0;
184
- color = "#ff2a5f";
211
+ color = f.piercer;
185
212
  strategy = null;
186
213
  hitRadiusPadding = 1.2;
187
214
  maxSpeed = 200;
@@ -229,7 +256,7 @@ class w {
229
256
  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
257
  }
231
258
  }
232
- class G {
259
+ class B {
233
260
  id;
234
261
  definition;
235
262
  position = { x: 0, y: 0 };
@@ -246,7 +273,7 @@ class G {
246
273
  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
274
  }
248
275
  }
249
- class Z {
276
+ class z {
250
277
  pointerPosition = { x: 0, y: 0 };
251
278
  isPointerDown = !1;
252
279
  grabbedEnemy = null;
@@ -258,17 +285,17 @@ class Z {
258
285
  this.canvas = t, this.bindEvents();
259
286
  }
260
287
  updatePointerPos(t, e) {
261
- const i = this.canvas.getBoundingClientRect(), s = i.width > 0 ? this.canvas.width / i.width : 1, a = i.height > 0 ? this.canvas.height / i.height : 1, l = performance.now() / 1e3;
288
+ const i = this.canvas.getBoundingClientRect(), s = i.width > 0 ? this.canvas.width / i.width : 1, a = i.height > 0 ? this.canvas.height / i.height : 1, r = performance.now() / 1e3;
262
289
  this.pointerPosition = {
263
290
  x: (t - i.left) * s,
264
291
  y: (e - i.top) * a
265
292
  }, this.pointerHistory.push({
266
293
  x: this.pointerPosition.x,
267
294
  y: this.pointerPosition.y,
268
- time: l
295
+ time: r
269
296
  });
270
- const n = l - 0.08;
271
- this.pointerHistory = this.pointerHistory.filter((o) => o.time >= n), this.grabbedEnemy && (this.grabbedEnemy.position = { ...this.pointerPosition });
297
+ const o = r - 0.08;
298
+ this.pointerHistory = this.pointerHistory.filter((n) => n.time >= o), this.grabbedEnemy && (this.grabbedEnemy.position = { ...this.pointerPosition });
272
299
  }
273
300
  bindEvents() {
274
301
  this.canvas.addEventListener("mousemove", (t) => {
@@ -308,8 +335,8 @@ class Z {
308
335
  const i = e ? 50 : 20;
309
336
  for (const s of t) {
310
337
  if (!s.active || s.isGrabbed || s.isThrown || s.wasManipulated || s.launchDelay > 0) continue;
311
- const a = this.pointerPosition.x - s.position.x, l = this.pointerPosition.y - s.position.y;
312
- if (Math.hypot(a, l) <= s.getHitRadius() + i)
338
+ const a = this.pointerPosition.x - s.position.x, r = this.pointerPosition.y - s.position.y;
339
+ if (Math.hypot(a, r) <= s.getHitRadius() + i)
313
340
  return s.isGrabbed = !0, this.grabbedEnemy = s, this.dragStart = { ...this.pointerPosition }, this.pointerHistory = [], s;
314
341
  }
315
342
  return null;
@@ -319,8 +346,8 @@ class Z {
319
346
  const i = e ? 50 : 20;
320
347
  for (const s of t) {
321
348
  if (!s.active || s.isGrabbed) continue;
322
- const a = this.pointerPosition.x - s.position.x, l = this.pointerPosition.y - s.position.y;
323
- if (Math.hypot(a, l) <= s.radius * 1.5 + i)
349
+ const a = this.pointerPosition.x - s.position.x, r = this.pointerPosition.y - s.position.y;
350
+ if (Math.hypot(a, r) <= s.radius * 1.5 + i)
324
351
  return s.isGrabbed = !0, this.grabbedOrb = s, s;
325
352
  }
326
353
  return null;
@@ -329,26 +356,26 @@ class Z {
329
356
  if (!this.grabbedEnemy) return null;
330
357
  const t = this.grabbedEnemy;
331
358
  t.isGrabbed = !1, t.isThrown = !0, t.wasManipulated = !0;
332
- const i = performance.now() / 1e3 - 0.08, s = this.pointerHistory.filter((o) => o.time >= i);
333
- let a = 0, l = 0;
359
+ const i = performance.now() / 1e3 - 0.08, s = this.pointerHistory.filter((n) => n.time >= i);
360
+ let a = 0, r = 0;
334
361
  if (s.length >= 2) {
335
- const o = s[0], r = s[s.length - 1], c = Math.max(0.01, r.time - o.time);
336
- a = (r.x - o.x) / c, l = (r.y - o.y) / c;
362
+ const n = s[0], l = s[s.length - 1], h = Math.max(0.01, l.time - n.time);
363
+ a = (l.x - n.x) / h, r = (l.y - n.y) / h;
337
364
  }
338
- const n = Math.hypot(a, l);
339
- if (n > 30) {
340
- const r = Math.min(n * 1.15, 2500), c = Math.atan2(l, a);
365
+ const o = Math.hypot(a, r);
366
+ if (o > 30) {
367
+ const l = Math.min(o * 1.15, 2500), h = Math.atan2(r, a);
341
368
  t.velocity = {
342
- x: Math.cos(c) * r,
343
- y: Math.sin(c) * r
369
+ x: Math.cos(h) * l,
370
+ y: Math.sin(h) * l
344
371
  };
345
372
  } else if (this.dragStart) {
346
- const o = t.position.x - this.dragStart.x, r = t.position.y - this.dragStart.y, c = Math.hypot(o, r);
347
- if (c > 5) {
348
- const h = Math.atan2(r, o), u = Math.min(c * 4, 600);
373
+ const n = t.position.x - this.dragStart.x, l = t.position.y - this.dragStart.y, h = Math.hypot(n, l);
374
+ if (h > 5) {
375
+ const c = Math.atan2(l, n), p = Math.min(h * 4, 600);
349
376
  t.velocity = {
350
- x: Math.cos(h) * u,
351
- y: Math.sin(h) * u
377
+ x: Math.cos(c) * p,
378
+ y: Math.sin(c) * p
352
379
  };
353
380
  } else
354
381
  t.velocity = { x: 0, y: 0 }, t.isThrown = !1;
@@ -356,8 +383,8 @@ class Z {
356
383
  if (t.type === "heavy")
357
384
  t.shieldAngle = t.rotation, t.velocity = { x: 0, y: 0 }, t.isStationaryShield = !0, t.isThrown = !1;
358
385
  else if (t.type === "piercer") {
359
- const o = E.getInstance().getConfig().piercer;
360
- o.hasHoming && (t.remainingHomingKills = o.homingTargets);
386
+ const n = v.getInstance().getConfig().piercer;
387
+ n.hasHoming && (t.remainingHomingKills = n.homingTargets);
361
388
  }
362
389
  return this.grabbedEnemy = null, this.dragStart = null, this.pointerHistory = [], t;
363
390
  }
@@ -368,7 +395,7 @@ class Z {
368
395
  this.grabbedEnemy = null, this.grabbedOrb = null, this.dragStart = null, this.pointerHistory = [], this.isPointerDown = !1;
369
396
  }
370
397
  }
371
- class z {
398
+ class J {
372
399
  cellSize;
373
400
  grid = /* @__PURE__ */ new Map();
374
401
  constructor(t = 100) {
@@ -379,31 +406,29 @@ class z {
379
406
  }
380
407
  insert(t) {
381
408
  const e = Math.floor((t.position.x - t.radius) / this.cellSize), i = Math.floor((t.position.x + t.radius) / this.cellSize), s = Math.floor((t.position.y - t.radius) / this.cellSize), a = Math.floor((t.position.y + t.radius) / this.cellSize);
382
- for (let l = e; l <= i; l++)
383
- for (let n = s; n <= a; n++) {
384
- const o = `${l}:${n}`;
385
- this.grid.has(o) || this.grid.set(o, /* @__PURE__ */ new Set()), this.grid.get(o).add(t);
409
+ for (let r = e; r <= i; r++)
410
+ for (let o = s; o <= a; o++) {
411
+ const n = `${r}:${o}`;
412
+ this.grid.has(n) || this.grid.set(n, /* @__PURE__ */ new Set()), this.grid.get(n).add(t);
386
413
  }
387
414
  }
388
415
  getNearby(t, e) {
389
- const i = /* @__PURE__ */ new Set(), s = Math.floor((t.x - e) / this.cellSize), a = Math.floor((t.x + e) / this.cellSize), l = Math.floor((t.y - e) / this.cellSize), n = Math.floor((t.y + e) / this.cellSize);
390
- for (let o = s; o <= a; o++)
391
- for (let r = l; r <= n; r++) {
392
- const c = `${o}:${r}`, h = this.grid.get(c);
393
- h && h.forEach((u) => i.add(u));
416
+ const i = /* @__PURE__ */ new Set(), s = Math.floor((t.x - e) / this.cellSize), a = Math.floor((t.x + e) / this.cellSize), r = Math.floor((t.y - e) / this.cellSize), o = Math.floor((t.y + e) / this.cellSize);
417
+ for (let n = s; n <= a; n++)
418
+ for (let l = r; l <= o; l++) {
419
+ const h = `${n}:${l}`, c = this.grid.get(h);
420
+ c && c.forEach((p) => i.add(p));
394
421
  }
395
422
  return i;
396
423
  }
397
424
  }
398
- class J {
399
- hitstopTime = 0;
425
+ class X {
400
426
  shakeTime = 0;
401
427
  shakeDuration = 0.14;
402
428
  shakeIntensity = 0;
403
429
  shakeVector = { x: 0, y: 0 };
404
430
  flashAlpha = 0;
405
431
  triggerHitstop(t = 0.06) {
406
- this.hitstopTime = 0;
407
432
  }
408
433
  triggerFlash(t = 0.4) {
409
434
  this.flashAlpha = t;
@@ -416,7 +441,7 @@ class J {
416
441
  }, this.shakeIntensity = s, this.shakeTime = this.shakeDuration;
417
442
  }
418
443
  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);
444
+ 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
445
  for (let s = e.length - 1; s >= 0; s--) {
421
446
  const a = e[s];
422
447
  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 +460,7 @@ class J {
435
460
  };
436
461
  }
437
462
  }
438
- const O = {
463
+ const D = {
439
464
  es: {
440
465
  title: "AXON SURGE",
441
466
  startButton: "INICIAR ENLACE",
@@ -445,6 +470,7 @@ const O = {
445
470
  languageLabel: "IDIOMA",
446
471
  themeLabel: "TEMA VISUAL",
447
472
  hapticsLabel: "VIBRACIÓN / HÁPTICOS",
473
+ fpsLimitLabel: "LÍMITE DE FPS",
448
474
  hapticsOn: "ACTIVADO",
449
475
  hapticsOff: "DESACTIVADO",
450
476
  creditsJam: "Desarrollado para Mini Jam 216: Axon Surge",
@@ -510,6 +536,7 @@ const O = {
510
536
  languageLabel: "LANGUAGE",
511
537
  themeLabel: "VISUAL THEME",
512
538
  hapticsLabel: "HAPTICS / VIBRATION",
539
+ fpsLimitLabel: "FPS LIMIT",
513
540
  hapticsOn: "ENABLED",
514
541
  hapticsOff: "DISABLED",
515
542
  creditsJam: "Developed for Mini Jam 216: Axon Surge",
@@ -1281,7 +1308,7 @@ const O = {
1281
1308
  pu_core_ring_title: "核心过载",
1282
1309
  pu_core_ring_desc: "+1 生命环"
1283
1310
  }
1284
- }, V = [
1311
+ }, W = [
1285
1312
  "es",
1286
1313
  "en",
1287
1314
  "fr",
@@ -1298,29 +1325,29 @@ const O = {
1298
1325
  "ko",
1299
1326
  "zh"
1300
1327
  ];
1301
- function N(A) {
1302
- return V.includes(A);
1328
+ function k(b) {
1329
+ return W.includes(b);
1303
1330
  }
1304
- const H = "axon_surge_language";
1305
- class $ {
1331
+ const K = "axon_surge_language";
1332
+ class j {
1306
1333
  currentLanguage;
1307
1334
  constructor(t) {
1308
1335
  this.currentLanguage = this.detectLanguage(t);
1309
1336
  }
1310
1337
  detectLanguage(t) {
1311
1338
  try {
1312
- const e = localStorage.getItem(H);
1313
- if (e && N(e))
1339
+ const e = localStorage.getItem(K);
1340
+ if (e && k(e))
1314
1341
  return e;
1315
1342
  } catch {
1316
1343
  }
1317
- if (t && N(t))
1344
+ if (t && k(t))
1318
1345
  return t;
1319
1346
  try {
1320
1347
  const e = (document.documentElement.lang || document.body?.getAttribute("lang") || document.documentElement.getAttribute("data-lang") || "").toLowerCase();
1321
1348
  if (e) {
1322
1349
  const i = e.split("-")[0];
1323
- if (i && N(i))
1350
+ if (i && k(i))
1324
1351
  return i;
1325
1352
  }
1326
1353
  } catch {
@@ -1329,7 +1356,7 @@ class $ {
1329
1356
  const e = (navigator.language || navigator.languages && navigator.languages[0] || "").toLowerCase();
1330
1357
  if (e) {
1331
1358
  const i = e.split("-")[0];
1332
- if (i && N(i))
1359
+ if (i && k(i))
1333
1360
  return i;
1334
1361
  }
1335
1362
  } catch {
@@ -1337,10 +1364,10 @@ class $ {
1337
1364
  return "en";
1338
1365
  }
1339
1366
  setLanguage(t) {
1340
- if (O[t]) {
1367
+ if (D[t]) {
1341
1368
  this.currentLanguage = t;
1342
1369
  try {
1343
- localStorage.setItem(H, t);
1370
+ localStorage.setItem(K, t);
1344
1371
  } catch {
1345
1372
  }
1346
1373
  }
@@ -1349,37 +1376,37 @@ class $ {
1349
1376
  return this.currentLanguage;
1350
1377
  }
1351
1378
  translate(t, e) {
1352
- let s = (O[this.currentLanguage] || O.en)[t] || O.en[t] || String(t);
1353
- return e && Object.entries(e).forEach(([a, l]) => {
1354
- s = s.replace(`{${a}}`, String(l));
1379
+ let s = (D[this.currentLanguage] || D.en)[t] || D.en[t] || String(t);
1380
+ return e && Object.entries(e).forEach(([a, r]) => {
1381
+ s = s.replace(`{${a}}`, String(r));
1355
1382
  }), s;
1356
1383
  }
1357
1384
  }
1358
- class X {
1385
+ class q {
1359
1386
  static update(t, e, i) {
1360
- const s = E.getInstance().getConfig();
1387
+ const s = v.getInstance().getConfig();
1361
1388
  for (let a = t.length - 1; a >= 0; a--) {
1362
- const l = t[a];
1363
- if (l) {
1364
- l.duration += i;
1365
- for (const n of e) {
1366
- if (!n.active || n.isGrabbed || n.isDying || n.isStationaryShield || n.launchDelay > 0 || n.isThrown && n.type === "piercer") continue;
1367
- 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
- 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);
1370
- 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;
1389
+ const r = t[a];
1390
+ if (r) {
1391
+ r.duration += i;
1392
+ for (const o of e) {
1393
+ if (!o.active || o.isGrabbed || o.isDying || o.isStationaryShield || o.launchDelay > 0 || o.isThrown && o.type === "piercer") continue;
1394
+ const n = r.position.x - o.position.x, l = r.position.y - o.position.y, h = n * n + l * l, c = Math.sqrt(h);
1395
+ if (c > 2 && h <= r.radius * r.radius) {
1396
+ const p = Math.pow(1 - c / r.radius, 0.7), g = r.pullForce * p, _ = Math.atan2(l, n);
1397
+ o.velocity.x += Math.cos(_) * g * i, o.velocity.y += Math.sin(_) * g * i, o.position.x += Math.cos(_) * g * i * 0.8, o.position.y += Math.sin(_) * g * i * 0.8;
1371
1398
  }
1372
1399
  }
1373
- if (l.duration >= l.maxDuration) {
1400
+ if (r.duration >= r.maxDuration) {
1374
1401
  if (s.gravityVortex.hasImplosionLaunch)
1375
- for (const n of e) {
1376
- if (!n.active || n.isDying) continue;
1377
- const o = n.position.x - l.position.x, r = n.position.y - l.position.y;
1378
- if (o * o + r * r <= l.radius * l.radius) {
1379
- const h = Math.atan2(r, o), u = 1200;
1380
- n.isThrown = !0, n.wasManipulated = !0, n.velocity = {
1381
- x: Math.cos(h) * u,
1382
- y: Math.sin(h) * u
1402
+ for (const o of e) {
1403
+ if (!o.active || o.isDying) continue;
1404
+ const n = o.position.x - r.position.x, l = o.position.y - r.position.y;
1405
+ if (n * n + l * l <= r.radius * r.radius) {
1406
+ const c = Math.atan2(l, n), p = 1200;
1407
+ o.isThrown = !0, o.wasManipulated = !0, o.velocity = {
1408
+ x: Math.cos(c) * p,
1409
+ y: Math.sin(c) * p
1383
1410
  };
1384
1411
  }
1385
1412
  }
@@ -1389,33 +1416,33 @@ class X {
1389
1416
  }
1390
1417
  }
1391
1418
  }
1392
- class j {
1393
- static update(t, e, i, s, a, l, n, o, r, c) {
1394
- for (const h of e) {
1395
- 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) {
1398
- if (h.active = !1, t.takeDamage()) {
1399
- n.emit("onCoreDamaged", { currentIntegrity: t.integrity }), i.push({
1419
+ class Q {
1420
+ static update(t, e, i, s, a, r, o, n, l, h) {
1421
+ for (const c of e) {
1422
+ if (!c.active || c.isGrabbed || c.isDying || c.launchDelay > 0) continue;
1423
+ const p = t.position.x - c.position.x, g = t.position.y - c.position.y;
1424
+ if (Math.hypot(p, g) <= t.getHitboxRadius() + c.radius) {
1425
+ if (c.active = !1, t.takeDamage()) {
1426
+ o.emit("onCoreDamaged", { currentIntegrity: t.integrity }), i.push({
1400
1427
  id: Math.random().toString(),
1401
1428
  position: { ...t.position },
1402
1429
  radius: 20,
1403
- maxRadius: Math.max(r, c) * 1.3,
1404
- color: "#00f0ff",
1430
+ maxRadius: Math.max(l, h) * 1.3,
1431
+ color: f.core,
1405
1432
  alpha: 1,
1406
1433
  lifetime: 0,
1407
1434
  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();
1412
- for (let g = 0; g < 8; g++) {
1413
- const m = Math.random() * Math.PI * 2, y = 100 + Math.random() * 200;
1435
+ }), r.triggerScreenShake({ x: p, y: g }, 25), r.triggerHitstop(0.15), r.triggerFlash(0.6);
1436
+ for (const u of e)
1437
+ if (u.active && !u.isGrabbed && u.launchDelay <= 0) {
1438
+ u.triggerDissolveDeath();
1439
+ for (let d = 0; d < 8; d++) {
1440
+ const x = Math.random() * Math.PI * 2, y = 100 + Math.random() * 200;
1414
1441
  s.push({
1415
1442
  id: Math.random().toString(),
1416
- position: { ...p.position },
1417
- velocity: { x: Math.cos(m) * y, y: Math.sin(m) * y },
1418
- color: "#00f0ff",
1443
+ position: { ...u.position },
1444
+ velocity: { x: Math.cos(x) * y, y: Math.sin(x) * y },
1445
+ color: f.core,
1419
1446
  radius: 3 + Math.random() * 3,
1420
1447
  alpha: 1,
1421
1448
  lifetime: 0,
@@ -1428,50 +1455,50 @@ class j {
1428
1455
  text: "CORE OVERLOAD PULSE!",
1429
1456
  position: { ...t.position },
1430
1457
  velocity: { x: 0, y: -90 },
1431
- color: "#00f0ff",
1458
+ color: f.core,
1432
1459
  alpha: 1,
1433
1460
  lifetime: 0,
1434
1461
  maxLifetime: 1.5,
1435
1462
  size: 32
1436
- }), t.integrity <= 0 && n.emit("onGameOver", { score: o.value, wave: 1 });
1463
+ }), t.integrity <= 0 && o.emit("onGameOver", { score: n.value, wave: 1 });
1437
1464
  }
1438
1465
  break;
1439
1466
  }
1440
1467
  }
1441
1468
  }
1442
1469
  }
1443
- class q {
1470
+ class tt {
1444
1471
  execute(t) {
1445
- const { thrownEnemy: e, targetEnemy: i, shockwaves: s, particles: a, floatingTexts: l } = t;
1472
+ const { thrownEnemy: e, targetEnemy: i, shockwaves: s, particles: a, floatingTexts: r } = t;
1446
1473
  i.experienceDropPending = !0, i.active = !1, s.push({
1447
1474
  id: Math.random().toString(),
1448
1475
  position: { ...i.position },
1449
1476
  radius: 10,
1450
1477
  maxRadius: 180,
1451
- color: "#ff2a5f",
1478
+ color: f.piercer,
1452
1479
  alpha: 1,
1453
1480
  lifetime: 0,
1454
1481
  maxLifetime: 0.5
1455
1482
  });
1456
- for (let n = 0; n < 30; n++) {
1457
- const o = Math.random() * Math.PI * 2, r = 180 + Math.random() * 320;
1483
+ for (let o = 0; o < 30; o++) {
1484
+ const n = Math.random() * Math.PI * 2, l = 180 + Math.random() * 320;
1458
1485
  a.push({
1459
1486
  id: Math.random().toString(),
1460
1487
  position: { ...i.position },
1461
- velocity: { x: Math.cos(o) * r, y: Math.sin(o) * r },
1462
- color: "#ff2a5f",
1488
+ velocity: { x: Math.cos(n) * l, y: Math.sin(n) * l },
1489
+ color: f.piercer,
1463
1490
  radius: 3 + Math.random() * 4,
1464
1491
  alpha: 1,
1465
1492
  lifetime: 0,
1466
1493
  maxLifetime: 0.5
1467
1494
  });
1468
1495
  }
1469
- l.push({
1496
+ r.push({
1470
1497
  id: Math.random().toString(),
1471
1498
  text: "PIERCING SLICE",
1472
1499
  position: { ...i.position },
1473
1500
  velocity: { x: 0, y: -50 },
1474
- color: "#ff2a5f",
1501
+ color: f.piercer,
1475
1502
  alpha: 1,
1476
1503
  lifetime: 0,
1477
1504
  maxLifetime: 0.8,
@@ -1479,109 +1506,109 @@ class q {
1479
1506
  });
1480
1507
  }
1481
1508
  }
1482
- class Q {
1509
+ class et {
1483
1510
  execute(t) {
1484
- const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: l, eventBus: n } = t, o = e.position, r = E.getInstance().getConfig();
1511
+ const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: r, eventBus: o } = t, n = e.position, l = v.getInstance().getConfig();
1485
1512
  i.push({
1486
1513
  id: Math.random().toString(),
1487
- position: { ...o },
1488
- radius: Math.round(r.toxicPool.baseRadius * 2),
1514
+ position: { ...n },
1515
+ radius: Math.round(l.toxicPool.baseRadius * 2),
1489
1516
  duration: 0,
1490
- maxDuration: r.toxicPool.baseDuration * 1.5,
1491
- damage: r.toxicPool.damage
1517
+ maxDuration: l.toxicPool.baseDuration * 1.5,
1518
+ damage: l.toxicPool.damage
1492
1519
  }), s.push({
1493
1520
  id: Math.random().toString(),
1494
- position: { ...o },
1521
+ position: { ...n },
1495
1522
  radius: 10,
1496
- maxRadius: Math.round(r.toxicPool.baseRadius * 2.2),
1497
- color: "#39ff14",
1523
+ maxRadius: Math.round(l.toxicPool.baseRadius * 2.2),
1524
+ color: f.spore,
1498
1525
  alpha: 1,
1499
1526
  lifetime: 0,
1500
1527
  maxLifetime: 0.6
1501
1528
  });
1502
- for (let c = 0; c < 45; c++) {
1503
- const h = Math.random() * Math.PI * 2, u = 120 + Math.random() * 260;
1529
+ for (let h = 0; h < 45; h++) {
1530
+ const c = Math.random() * Math.PI * 2, p = 120 + Math.random() * 260;
1504
1531
  a.push({
1505
1532
  id: Math.random().toString(),
1506
- position: { ...o },
1507
- velocity: { x: Math.cos(h) * u, y: Math.sin(h) * u },
1508
- color: "#39ff14",
1533
+ position: { ...n },
1534
+ velocity: { x: Math.cos(c) * p, y: Math.sin(c) * p },
1535
+ color: f.spore,
1509
1536
  radius: 4 + Math.random() * 5,
1510
1537
  alpha: 1,
1511
1538
  lifetime: 0,
1512
1539
  maxLifetime: 0.9
1513
1540
  });
1514
1541
  }
1515
- l.push({
1542
+ r.push({
1516
1543
  id: Math.random().toString(),
1517
1544
  text: "MASSIVE SPORE NEBULA",
1518
- position: { ...o },
1545
+ position: { ...n },
1519
1546
  velocity: { x: 0, y: -60 },
1520
- color: "#39ff14",
1547
+ color: f.spore,
1521
1548
  alpha: 1,
1522
1549
  lifetime: 0,
1523
1550
  maxLifetime: 1.2,
1524
1551
  size: 26
1525
- }), e.experienceDropPending = !0, e.active = !1, n.emit("onPoolCreated", { position: o });
1552
+ }), e.experienceDropPending = !0, e.active = !1, o.emit("onPoolCreated", { position: n });
1526
1553
  }
1527
1554
  }
1528
- class tt {
1555
+ class it {
1529
1556
  execute(t) {
1530
- const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: n } = t, o = i.position;
1557
+ const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: r, floatingTexts: o } = t, n = i.position;
1531
1558
  e.experienceDropPending = !0, i.experienceDropPending = !0, e.active = !1, i.active = !1, a.push({
1532
1559
  id: Math.random().toString(),
1533
- position: { ...o },
1560
+ position: { ...n },
1534
1561
  radius: 15,
1535
1562
  maxRadius: 280,
1536
- color: "#ffd700",
1563
+ color: f.cluster,
1537
1564
  alpha: 1,
1538
1565
  lifetime: 0,
1539
1566
  maxLifetime: 0.6
1540
1567
  });
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 = {
1544
- x: o.x + Math.cos(d) * 45,
1545
- y: o.y + Math.sin(d) * 45
1568
+ const l = v.getInstance().getConfig(), h = l.cluster.fragmentCount, c = l.cluster.hasHoming;
1569
+ for (let p = 0; p < h; p++) {
1570
+ const g = p * Math.PI * 2 / h, _ = 800 + Math.random() * 300, m = {
1571
+ x: n.x + Math.cos(g) * 45,
1572
+ y: n.y + Math.sin(g) * 45
1546
1573
  };
1547
- let p = d;
1548
- 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);
1574
+ let u = g;
1575
+ if (c) {
1576
+ let x = null, y = 1 / 0;
1577
+ for (const E of s) {
1578
+ if (E === e || E === i || !E.active || E.isGrabbed || E.isDying) continue;
1579
+ const I = Math.hypot(E.position.x - m.x, E.position.y - m.y);
1580
+ I < y && (y = I, x = E);
1554
1581
  }
1555
- m && (p = Math.atan2(m.position.y - f.y, m.position.x - f.x));
1582
+ x && (u = Math.atan2(x.position.y - m.y, x.position.x - m.x));
1556
1583
  }
1557
- const g = M.createEnemy("micro", f, {
1558
- x: f.x + Math.cos(p) * 500,
1559
- y: f.y + Math.sin(p) * 500
1584
+ const d = P.createEnemy("micro", m, {
1585
+ x: m.x + Math.cos(u) * 500,
1586
+ y: m.y + Math.sin(u) * 500
1560
1587
  });
1561
- g.isThrown = !0, g.wasManipulated = !0, g.velocity = {
1562
- x: Math.cos(p) * _,
1563
- y: Math.sin(p) * _
1564
- }, s.push(g);
1565
- }
1566
- for (let u = 0; u < 35; u++) {
1567
- const d = Math.random() * Math.PI * 2, _ = 200 + Math.random() * 300;
1568
- l.push({
1588
+ d.isThrown = !0, d.wasManipulated = !0, d.velocity = {
1589
+ x: Math.cos(u) * _,
1590
+ y: Math.sin(u) * _
1591
+ }, s.push(d);
1592
+ }
1593
+ for (let p = 0; p < 35; p++) {
1594
+ const g = Math.random() * Math.PI * 2, _ = 200 + Math.random() * 300;
1595
+ r.push({
1569
1596
  id: Math.random().toString(),
1570
- position: { ...o },
1571
- velocity: { x: Math.cos(d) * _, y: Math.sin(d) * _ },
1572
- color: "#ffd700",
1597
+ position: { ...n },
1598
+ velocity: { x: Math.cos(g) * _, y: Math.sin(g) * _ },
1599
+ color: f.cluster,
1573
1600
  radius: 4 + Math.random() * 4,
1574
1601
  alpha: 1,
1575
1602
  lifetime: 0,
1576
1603
  maxLifetime: 0.6
1577
1604
  });
1578
1605
  }
1579
- n.push({
1606
+ o.push({
1580
1607
  id: Math.random().toString(),
1581
1608
  text: "CLUSTER DETONATION",
1582
- position: { ...o },
1609
+ position: { ...n },
1583
1610
  velocity: { x: 0, y: -60 },
1584
- color: "#ffd700",
1611
+ color: f.cluster,
1585
1612
  alpha: 1,
1586
1613
  lifetime: 0,
1587
1614
  maxLifetime: 1,
@@ -1589,78 +1616,78 @@ class tt {
1589
1616
  });
1590
1617
  }
1591
1618
  }
1592
- class et {
1619
+ class st {
1593
1620
  execute(t) {
1594
- const { thrownEnemy: e, targetEnemy: i, vortices: s, shockwaves: a } = t, l = E.getInstance().getConfig(), n = {
1621
+ const { thrownEnemy: e, targetEnemy: i, vortices: s, shockwaves: a } = t, r = v.getInstance().getConfig(), o = {
1595
1622
  x: (e.position.x + i.position.x) / 2,
1596
1623
  y: (e.position.y + i.position.y) / 2
1597
1624
  };
1598
1625
  s.push({
1599
1626
  id: Math.random().toString(),
1600
- position: n,
1601
- radius: Math.round(l.gravityVortex.baseRadius * 2.2),
1627
+ position: o,
1628
+ radius: Math.round(r.gravityVortex.baseRadius * 2.2),
1602
1629
  duration: 0,
1603
- maxDuration: l.gravityVortex.baseDuration * 1.5,
1604
- pullForce: l.gravityVortex.basePullForce * 1.6
1630
+ maxDuration: r.gravityVortex.baseDuration * 1.5,
1631
+ pullForce: r.gravityVortex.basePullForce * 1.6
1605
1632
  }), a.push({
1606
1633
  id: Math.random().toString(),
1607
- position: n,
1634
+ position: o,
1608
1635
  radius: 20,
1609
- maxRadius: Math.round(l.gravityVortex.baseRadius * 2.2),
1610
- color: "#9d4edd",
1636
+ maxRadius: Math.round(r.gravityVortex.baseRadius * 2.2),
1637
+ color: f.parasite,
1611
1638
  alpha: 1,
1612
1639
  lifetime: 0,
1613
1640
  maxLifetime: 0.65
1614
1641
  }), e.triggerDissolveDeath(!0), i.triggerDissolveDeath(!0);
1615
1642
  }
1616
1643
  }
1617
- class it {
1644
+ class at {
1618
1645
  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(
1646
+ const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: r, floatingTexts: o } = t, n = i.position.x - e.position.x, l = i.position.y - e.position.y, h = Math.atan2(l, n), c = v.getInstance().getConfig().shield, p = c.blastSpeed || 1400, g = c.isFanBlast ? [0, -c.fanBlastAngle, c.fanBlastAngle] : [0];
1647
+ for (const [_, m] of g.entries()) {
1648
+ const u = h + m, d = _ === 0 ? e : P.createEnemy(
1622
1649
  "heavy",
1623
1650
  {
1624
- x: e.position.x + Math.cos(p) * 30,
1625
- y: e.position.y + Math.sin(p) * 30
1651
+ x: e.position.x + Math.cos(u) * 30,
1652
+ y: e.position.y + Math.sin(u) * 30
1626
1653
  },
1627
1654
  { x: 0, y: 0 }
1628
1655
  );
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
1632
- }, g !== e && s.push(g);
1656
+ d.isStationaryShield = !1, d.isThrown = !0, d.wasManipulated = !0, d.shieldAngle = u, d.rotation = u, d.launchDelay = c.isFanBlast ? _ * c.fanBlastInterval : 0, d.velocity = {
1657
+ x: Math.cos(u) * p,
1658
+ y: Math.sin(u) * p
1659
+ }, d !== e && s.push(d);
1633
1660
  }
1634
- i.active = !1, i.triggerDissolveDeath(!0), n.push({
1661
+ i.active = !1, i.triggerDissolveDeath(!0), o.push({
1635
1662
  id: Math.random().toString(),
1636
1663
  text: "ARC BLAST!",
1637
1664
  position: { ...e.position },
1638
1665
  velocity: { x: 0, y: -50 },
1639
- color: "#00f5ff",
1666
+ color: f.heavy,
1640
1667
  alpha: 1,
1641
1668
  lifetime: 0,
1642
1669
  maxLifetime: 0.9,
1643
1670
  size: 24
1644
1671
  });
1645
1672
  for (let _ = 0; _ < 50; _++) {
1646
- const f = (Math.random() - 0.5) * 1.5, p = c + f, g = 300 + Math.random() * 500;
1647
- l.push({
1673
+ const m = (Math.random() - 0.5) * 1.5, u = h + m, d = 300 + Math.random() * 500;
1674
+ r.push({
1648
1675
  id: Math.random().toString(),
1649
1676
  position: { ...e.position },
1650
- velocity: { x: Math.cos(p) * g, y: Math.sin(p) * g },
1651
- color: "#00f5ff",
1677
+ velocity: { x: Math.cos(u) * d, y: Math.sin(u) * d },
1678
+ color: f.heavy,
1652
1679
  radius: 4 + Math.random() * 6,
1653
1680
  alpha: 1,
1654
1681
  lifetime: 0,
1655
1682
  maxLifetime: 0.7
1656
1683
  });
1657
1684
  }
1658
- n.push({
1685
+ o.push({
1659
1686
  id: Math.random().toString(),
1660
1687
  text: "ARC BLAST!",
1661
1688
  position: { ...e.position },
1662
1689
  velocity: { x: 0, y: -50 },
1663
- color: "#00f5ff",
1690
+ color: f.heavy,
1664
1691
  alpha: 1,
1665
1692
  lifetime: 0,
1666
1693
  maxLifetime: 0.9,
@@ -1668,25 +1695,25 @@ class it {
1668
1695
  });
1669
1696
  }
1670
1697
  }
1671
- class M {
1698
+ class P {
1672
1699
  static createEnemy(t, e, i) {
1673
- const s = `enemy_${Date.now()}_${Math.random()}`, a = new w(s);
1700
+ const s = `enemy_${Date.now()}_${Math.random()}`, a = new G(s);
1674
1701
  return this.configureEnemy(a, t, e, i), a;
1675
1702
  }
1676
1703
  static configureEnemy(t, e, i, s) {
1677
1704
  t.type = e, t.position = { ...i }, t.active = !0, t.isGrabbed = !1, t.isThrown = !1;
1678
- 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 = {
1681
- x: Math.cos(n) * o,
1682
- y: Math.sin(n) * o
1705
+ const a = s.x - i.x, r = s.y - i.y, o = Math.atan2(r, a);
1706
+ let n = 70, l = 100, h = 20, c = f.piercer, p = null;
1707
+ e === "piercer" ? (n = 95, l = 140, h = 18, c = f.piercer, p = new tt()) : e === "spore" ? (n = 65, l = 90, h = 24, c = f.spore, p = new et()) : e === "cluster" ? (n = 50, l = 75, h = 26, c = f.cluster, p = new it()) : e === "parasite" ? (n = 80, l = 110, h = 22, c = f.parasite, p = new st()) : e === "heavy" ? (n = 35, l = 50, h = 34, c = f.heavy, p = new at(), t.rotation = Math.random() * Math.PI * 2) : e === "micro" && (n = 130, l = 160, h = 12, c = f.micro), t.radius = h, t.color = c, t.strategy = p, t.maxSpeed = l, t.velocity = {
1708
+ x: Math.cos(o) * n,
1709
+ y: Math.sin(o) * n
1683
1710
  };
1684
1711
  }
1685
1712
  }
1686
- class L {
1687
- static killEnemy(t, e, i, s, a, l) {
1713
+ class O {
1714
+ static killEnemy(t, e, i, s, a, r) {
1688
1715
  if (!t.active || t.isDying) return;
1689
- const n = E.getInstance().getConfig();
1716
+ const o = v.getInstance().getConfig();
1690
1717
  if (t.experienceDropPending = !0, a.push({
1691
1718
  id: Math.random().toString(),
1692
1719
  position: { ...t.position },
@@ -1700,117 +1727,117 @@ class L {
1700
1727
  t.triggerDissolveDeath(!0), i.push({
1701
1728
  id: Math.random().toString(),
1702
1729
  position: { ...t.position },
1703
- radius: n.toxicPool.baseRadius,
1730
+ radius: o.toxicPool.baseRadius,
1704
1731
  duration: 0,
1705
- maxDuration: n.toxicPool.baseDuration,
1706
- damage: n.toxicPool.damage
1732
+ maxDuration: o.toxicPool.baseDuration,
1733
+ damage: o.toxicPool.damage
1707
1734
  });
1708
1735
  else if (t.type === "cluster") {
1709
1736
  t.triggerDissolveDeath(!0);
1710
- const o = n.cluster.fragmentCount, r = n.cluster.hasHoming;
1711
- for (let c = 0; c < o; c++) {
1712
- const h = c * Math.PI * 2 / o, u = 750 + Math.random() * 250, d = {
1713
- x: t.position.x + Math.cos(h) * 40,
1714
- y: t.position.y + Math.sin(h) * 40
1737
+ const n = o.cluster.fragmentCount, l = o.cluster.hasHoming;
1738
+ for (let h = 0; h < n; h++) {
1739
+ const c = h * Math.PI * 2 / n, p = 750 + Math.random() * 250, g = {
1740
+ x: t.position.x + Math.cos(c) * 40,
1741
+ y: t.position.y + Math.sin(c) * 40
1715
1742
  };
1716
- let _ = h;
1717
- 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);
1743
+ let _ = c;
1744
+ if (l) {
1745
+ let u = null, d = 1 / 0;
1746
+ for (const x of r) {
1747
+ if (x === t || !x.active || x.isGrabbed || x.isDying) continue;
1748
+ const y = Math.hypot(x.position.x - g.x, x.position.y - g.y);
1749
+ y < d && (d = y, u = x);
1723
1750
  }
1724
- p && (_ = Math.atan2(p.position.y - d.y, p.position.x - d.x));
1751
+ u && (_ = Math.atan2(u.position.y - g.y, u.position.x - g.x));
1725
1752
  }
1726
- const f = M.createEnemy("micro", d, {
1727
- x: d.x + Math.cos(_) * 500,
1728
- y: d.y + Math.sin(_) * 500
1753
+ const m = P.createEnemy("micro", g, {
1754
+ x: g.x + Math.cos(_) * 500,
1755
+ y: g.y + Math.sin(_) * 500
1729
1756
  });
1730
- f.isThrown = !0, f.wasManipulated = !0, f.velocity = {
1731
- x: Math.cos(_) * u,
1732
- y: Math.sin(_) * u
1733
- }, l.push(f);
1757
+ m.isThrown = !0, m.wasManipulated = !0, m.velocity = {
1758
+ x: Math.cos(_) * p,
1759
+ y: Math.sin(_) * p
1760
+ }, r.push(m);
1734
1761
  }
1735
1762
  } else t.type === "parasite" ? (t.triggerDissolveDeath(!0), s.push({
1736
1763
  id: Math.random().toString(),
1737
1764
  position: { ...t.position },
1738
- radius: n.gravityVortex.baseRadius,
1765
+ radius: o.gravityVortex.baseRadius,
1739
1766
  duration: 0,
1740
- maxDuration: n.gravityVortex.baseDuration,
1741
- pullForce: n.gravityVortex.basePullForce
1767
+ maxDuration: o.gravityVortex.baseDuration,
1768
+ pullForce: o.gravityVortex.basePullForce
1742
1769
  })) : t.type === "piercer" ? t.triggerSliceDeath(e, !0) : t.triggerDissolveDeath(!0);
1743
1770
  }
1744
1771
  }
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") {
1772
+ class ot {
1773
+ static update(t, e, i, s, a, r, o, n, l, h, c, p, g, _) {
1774
+ let m = !1;
1775
+ for (const u of t)
1776
+ if (!(!u.active || !u.isThrown || u.isDying || u.launchDelay > 0)) {
1777
+ if (m = !0, u.position.x < -120 || u.position.x > h + 120 || u.position.y < -120 || u.position.y > c + 120) {
1778
+ if (u.type === "heavy") {
1752
1779
  s.push({
1753
1780
  id: Math.random().toString(),
1754
- position: { ...p.position },
1781
+ position: { ...u.position },
1755
1782
  radius: 20,
1756
1783
  maxRadius: 350,
1757
- color: "#00f5ff",
1784
+ color: f.core,
1758
1785
  alpha: 1,
1759
1786
  lifetime: 0,
1760
1787
  maxLifetime: 0.6
1761
1788
  });
1762
- for (let g = 0; g < 40; g++) {
1763
- const m = Math.random() * Math.PI * 2, y = 250 + Math.random() * 450;
1789
+ for (let d = 0; d < 40; d++) {
1790
+ const x = Math.random() * Math.PI * 2, y = 250 + Math.random() * 450;
1764
1791
  a.push({
1765
1792
  id: Math.random().toString(),
1766
- position: { ...p.position },
1767
- velocity: { x: Math.cos(m) * y, y: Math.sin(m) * y },
1768
- color: "#00f5ff",
1793
+ position: { ...u.position },
1794
+ velocity: { x: Math.cos(x) * y, y: Math.sin(x) * y },
1795
+ color: f.core,
1769
1796
  radius: 4 + Math.random() * 5,
1770
1797
  alpha: 1,
1771
1798
  lifetime: 0,
1772
1799
  maxLifetime: 0.6
1773
1800
  });
1774
1801
  }
1775
- } else if (p.type === "piercer") {
1776
- const g = E.getInstance().getConfig().piercer;
1777
- if (g.terminalAoERadius > 0) {
1778
- const m = g.terminalAoERadius;
1802
+ } else if (u.type === "piercer") {
1803
+ const d = v.getInstance().getConfig().piercer;
1804
+ if (d.terminalAoERadius > 0) {
1805
+ const x = d.terminalAoERadius;
1779
1806
  s.push({
1780
1807
  id: Math.random().toString(),
1781
- position: { ...p.position },
1808
+ position: { ...u.position },
1782
1809
  radius: 20,
1783
- maxRadius: m,
1784
- color: "#ff2a5f",
1810
+ maxRadius: x,
1811
+ color: f.piercer,
1785
1812
  alpha: 1,
1786
1813
  lifetime: 0,
1787
1814
  maxLifetime: 0.6
1788
1815
  });
1789
- for (const y of d.getNearby(p.position, m)) {
1816
+ for (const y of g.getNearby(u.position, x)) {
1790
1817
  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);
1818
+ const E = y.position.x - u.position.x, I = y.position.y - u.position.y;
1819
+ E * E + I * I <= x * x && O.killEnemy(y, Math.atan2(I, E), e, i, s, t);
1793
1820
  }
1794
1821
  }
1795
1822
  }
1796
- p.active = !1, p.isThrown = !1;
1823
+ u.active = !1, u.isThrown = !1;
1797
1824
  continue;
1798
1825
  }
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;
1826
+ for (const d of g.getNearby(u.position, u.getHitRadius() + 80)) {
1827
+ if (d === u || !d.active || d.isGrabbed || d.isDying || d.launchDelay > 0) continue;
1828
+ const x = d.position.x - u.position.x, y = d.position.y - u.position.y, E = u.getHitRadius() + d.getHitRadius();
1829
+ if (x * x + y * y <= E * E) {
1830
+ p.pos = { x: u.position.x, y: u.position.y };
1831
+ const I = Math.atan2(u.velocity.y, u.velocity.x);
1832
+ if (u.type === "heavy") {
1833
+ p.kills++, O.killEnemy(d, u.rotation, e, i, s, t), o.triggerHitstop(0.04), o.triggerScreenShake({ x, y }, 8);
1834
+ for (let T = 0; T < 8; T++) {
1835
+ const L = u.rotation + (Math.random() - 0.5), A = 200 + Math.random() * 350;
1809
1836
  a.push({
1810
1837
  id: Math.random().toString(),
1811
- position: { ...g.position },
1812
- velocity: { x: Math.cos(v) * x, y: Math.sin(v) * x },
1813
- color: "#00f5ff",
1838
+ position: { ...d.position },
1839
+ velocity: { x: Math.cos(L) * A, y: Math.sin(L) * A },
1840
+ color: f.core,
1814
1841
  radius: 3 + Math.random() * 4,
1815
1842
  alpha: 1,
1816
1843
  lifetime: 0,
@@ -1818,122 +1845,122 @@ class st {
1818
1845
  });
1819
1846
  }
1820
1847
  _ && _();
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({
1848
+ } else if (u.type === "piercer") {
1849
+ p.kills++, O.killEnemy(d, I, e, i, s, t), o.triggerHitstop(0.05), o.triggerScreenShake({ x, y }, 7), s.push({
1823
1850
  id: Math.random().toString(),
1824
- position: { ...g.position },
1851
+ position: { ...d.position },
1825
1852
  radius: 10,
1826
1853
  maxRadius: 180,
1827
- color: "#ff2a5f",
1854
+ color: f.piercer,
1828
1855
  alpha: 1,
1829
1856
  lifetime: 0,
1830
1857
  maxLifetime: 0.45
1831
1858
  });
1832
- for (let S = 0; S < 16; S++) {
1833
- const v = Math.random() * Math.PI * 2, x = 150 + Math.random() * 300;
1859
+ for (let T = 0; T < 16; T++) {
1860
+ const L = Math.random() * Math.PI * 2, A = 150 + Math.random() * 300;
1834
1861
  a.push({
1835
1862
  id: Math.random().toString(),
1836
- position: { ...g.position },
1837
- velocity: { x: Math.cos(v) * x, y: Math.sin(v) * x },
1838
- color: "#ff2a5f",
1863
+ position: { ...d.position },
1864
+ velocity: { x: Math.cos(L) * A, y: Math.sin(L) * A },
1865
+ color: f.piercer,
1839
1866
  radius: 3 + Math.random() * 3,
1840
1867
  alpha: 1,
1841
1868
  lifetime: 0,
1842
1869
  maxLifetime: 0.4
1843
1870
  });
1844
1871
  }
1845
- if (p.remainingHomingKills > 0) {
1846
- p.remainingHomingKills--;
1847
- let S = null, v = 1 / 0;
1848
- 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);
1872
+ if (u.remainingHomingKills > 0) {
1873
+ u.remainingHomingKills--;
1874
+ let T = null, L = 1 / 0;
1875
+ for (const A of t) {
1876
+ if (A === u || A === d || !A.active || A.isGrabbed || A.isDying) continue;
1877
+ const R = A.position.x - u.position.x, C = A.position.y - u.position.y, S = Math.hypot(R, C);
1878
+ S < L && (L = S, T = A);
1852
1879
  }
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
1880
+ if (T) {
1881
+ const A = Math.atan2(T.position.y - u.position.y, T.position.x - u.position.x), R = Math.hypot(u.velocity.x, u.velocity.y) || 1200;
1882
+ u.rotation = A, u.velocity = {
1883
+ x: Math.cos(A) * R,
1884
+ y: Math.sin(A) * R
1858
1885
  };
1859
1886
  }
1860
1887
  }
1861
1888
  _ && _();
1862
1889
  } else {
1863
- const S = p.type === g.type, v = S ? 360 : 250;
1890
+ const T = u.type === d.type, L = T ? 360 : 250;
1864
1891
  s.push({
1865
1892
  id: Math.random().toString(),
1866
- position: { ...u.pos },
1893
+ position: { ...p.pos },
1867
1894
  radius: 15,
1868
- maxRadius: v,
1869
- color: p.color,
1895
+ maxRadius: L,
1896
+ color: u.color,
1870
1897
  alpha: 1,
1871
1898
  lifetime: 0,
1872
1899
  maxLifetime: 0.55
1873
1900
  });
1874
- for (let x = 0; x < 45; x++) {
1875
- const T = Math.random() * Math.PI * 2, R = 200 + Math.random() * 450;
1901
+ for (let A = 0; A < 45; A++) {
1902
+ const R = Math.random() * Math.PI * 2, C = 200 + Math.random() * 450;
1876
1903
  a.push({
1877
1904
  id: Math.random().toString(),
1878
- position: { ...u.pos },
1879
- velocity: { x: Math.cos(T) * R, y: Math.sin(T) * R },
1880
- color: p.color,
1905
+ position: { ...p.pos },
1906
+ velocity: { x: Math.cos(R) * C, y: Math.sin(R) * C },
1907
+ color: u.color,
1881
1908
  radius: 4 + Math.random() * 6,
1882
1909
  alpha: 1,
1883
1910
  lifetime: 0,
1884
1911
  maxLifetime: 0.7
1885
1912
  });
1886
1913
  }
1887
- if (p.strategy) {
1888
- p.strategy.execute({
1889
- thrownEnemy: p,
1890
- targetEnemy: g,
1914
+ if (u.strategy) {
1915
+ u.strategy.execute({
1916
+ thrownEnemy: u,
1917
+ targetEnemy: d,
1891
1918
  allEnemies: t,
1892
1919
  pools: e,
1893
1920
  vortices: i,
1894
1921
  shockwaves: s,
1895
1922
  particles: a,
1896
- floatingTexts: l,
1897
- eventBus: o,
1898
- width: c,
1899
- height: h
1900
- }), u.kills += 2, _ && _();
1923
+ floatingTexts: r,
1924
+ eventBus: n,
1925
+ width: h,
1926
+ height: c
1927
+ }), p.kills += 2, _ && _();
1901
1928
  break;
1902
1929
  }
1903
- if (S) {
1904
- u.kills += 2, n.triggerHitstop(0.14), n.triggerFlash(0.5), n.triggerScreenShake({ x: m, y }, 16), l.push({
1930
+ if (T) {
1931
+ p.kills += 2, o.triggerHitstop(0.14), o.triggerFlash(0.5), o.triggerScreenShake({ x, y }, 16), r.push({
1905
1932
  id: Math.random().toString(),
1906
1933
  text: "COLOR SYNERGY!",
1907
- position: { ...u.pos },
1934
+ position: { ...p.pos },
1908
1935
  velocity: { x: 0, y: -80 },
1909
- color: p.color,
1936
+ color: u.color,
1910
1937
  alpha: 1,
1911
1938
  lifetime: 0,
1912
1939
  maxLifetime: 1.2,
1913
1940
  size: 26
1914
1941
  });
1915
- const x = E.getInstance().getConfig();
1916
- p.type === "spore" ? e.push({
1942
+ const A = v.getInstance().getConfig();
1943
+ u.type === "spore" ? e.push({
1917
1944
  id: Math.random().toString(),
1918
- position: { ...u.pos },
1919
- radius: Math.round(x.toxicPool.baseRadius * 2),
1945
+ position: { ...p.pos },
1946
+ radius: Math.round(A.toxicPool.baseRadius * 2),
1920
1947
  duration: 0,
1921
- maxDuration: x.toxicPool.synergyDuration,
1922
- damage: x.toxicPool.damage * 2
1923
- }) : p.type === "parasite" && i.push({
1948
+ maxDuration: A.toxicPool.synergyDuration,
1949
+ damage: A.toxicPool.damage * 2
1950
+ }) : u.type === "parasite" && i.push({
1924
1951
  id: Math.random().toString(),
1925
- position: { ...u.pos },
1926
- radius: Math.round(x.gravityVortex.baseRadius * 1.8),
1952
+ position: { ...p.pos },
1953
+ radius: Math.round(A.gravityVortex.baseRadius * 1.8),
1927
1954
  duration: 0,
1928
- maxDuration: x.gravityVortex.synergyDuration,
1929
- pullForce: x.gravityVortex.synergyPullForce
1930
- }), L.killEnemy(p, I, e, i, s, t), L.killEnemy(g, I, e, i, s, t);
1955
+ maxDuration: A.gravityVortex.synergyDuration,
1956
+ pullForce: A.gravityVortex.synergyPullForce
1957
+ }), O.killEnemy(u, I, e, i, s, t), O.killEnemy(d, I, e, i, s, t);
1931
1958
  } 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);
1933
- 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++);
1959
+ p.kills += 2, o.triggerHitstop(0.08), o.triggerFlash(0.35), o.triggerScreenShake({ x, y }, 10), O.killEnemy(u, I, e, i, s, t), O.killEnemy(d, I, e, i, s, t);
1960
+ for (const A of t) {
1961
+ if (A === u || A === d || !A.active || A.isGrabbed || A.isDying) continue;
1962
+ const R = A.position.x - p.pos.x, C = A.position.y - p.pos.y;
1963
+ Math.hypot(R, C) <= L && A.type !== "micro" && (O.killEnemy(A, I, e, i, s, t), p.kills++);
1937
1964
  }
1938
1965
  _ && _();
1939
1966
  break;
@@ -1941,184 +1968,184 @@ class st {
1941
1968
  }
1942
1969
  }
1943
1970
  }
1944
- r.value = u.kills, !f && u.kills > 0 && (u.kills >= 2 && u.pos && l.push({
1971
+ l.value = p.kills, !m && p.kills > 0 && (p.kills >= 2 && p.pos && r.push({
1945
1972
  id: Math.random().toString(),
1946
- text: `MULTIKILL x${u.kills}!`,
1947
- position: { ...u.pos },
1973
+ text: `MULTIKILL x${p.kills}!`,
1974
+ position: { ...p.pos },
1948
1975
  velocity: { x: 0, y: -90 },
1949
- color: "#ff00dd",
1976
+ color: f.coreAccent,
1950
1977
  alpha: 1,
1951
1978
  lifetime: 0,
1952
1979
  maxLifetime: 1.4,
1953
1980
  size: 32
1954
- }), o.emit("onComboUpdated", { combo: r.value }), u.kills = 0, u.pos = null);
1981
+ }), n.emit("onComboUpdated", { combo: l.value }), p.kills = 0, p.pos = null);
1955
1982
  }
1956
1983
  }
1957
- class at {
1958
- static update(t, e, i, s, a, l, n, o) {
1959
- for (let r = t.length - 1; r >= 0; r--) {
1960
- const c = t[r];
1961
- if (c) {
1962
- c.duration += l;
1963
- for (const h of e) {
1964
- 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());
1984
+ class nt {
1985
+ static update(t, e, i, s, a, r, o, n) {
1986
+ for (let l = t.length - 1; l >= 0; l--) {
1987
+ const h = t[l];
1988
+ if (h) {
1989
+ h.duration += r;
1990
+ for (const c of e) {
1991
+ if (!c.active || c.isGrabbed || c.isDying || c.launchDelay > 0 || c.isThrown && c.type === "piercer") continue;
1992
+ const p = c.position.x - h.position.x, g = c.position.y - h.position.y;
1993
+ p * p + g * g <= h.radius * h.radius && (O.killEnemy(c, 0, t, i, s, e), o.kills++, n && n());
1967
1994
  }
1968
- c.duration >= c.maxDuration && t.splice(r, 1);
1995
+ h.duration >= h.maxDuration && t.splice(l, 1);
1969
1996
  }
1970
1997
  }
1971
1998
  }
1972
1999
  }
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;
2000
+ class rt {
2001
+ static update(t, e, i, s, a, r, o, n, l, h, c, p, g) {
2002
+ const _ = v.getInstance().getConfig().shield.protectionArc;
2003
+ for (const m of t)
2004
+ if (!(!m.active || !m.isStationaryShield || m.isDying))
2005
+ for (const u of p.getNearby(m.position, m.getHitRadius() + 80)) {
2006
+ if (u === m || !u.active || u.isGrabbed || u.isDying || u.launchDelay > 0) continue;
2007
+ const d = u.position.x - m.position.x, x = u.position.y - m.position.y;
2008
+ let y = Math.atan2(x, d) - m.rotation;
1982
2009
  for (; y < -Math.PI; ) y += Math.PI * 2;
1983
2010
  for (; y > Math.PI; ) y -= Math.PI * 2;
1984
2011
  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,
2012
+ const E = m.getHitRadius() + u.getHitRadius();
2013
+ if (d * d + x * x <= E * E) {
2014
+ m.isStationaryShield = !1, m.strategy && m.strategy.execute({
2015
+ thrownEnemy: m,
2016
+ targetEnemy: u,
1990
2017
  allEnemies: t,
1991
2018
  pools: e,
1992
2019
  vortices: i,
1993
2020
  shockwaves: s,
1994
2021
  particles: a,
1995
- floatingTexts: l,
1996
- eventBus: o,
1997
- width: c,
1998
- height: h
1999
- }), r.kills += 2, n.triggerHitstop(0.12), n.triggerScreenShake({ x: g, y: m }, 18), d && d();
2022
+ floatingTexts: r,
2023
+ eventBus: n,
2024
+ width: h,
2025
+ height: c
2026
+ }), l.kills += 2, o.triggerHitstop(0.12), o.triggerScreenShake({ x: d, y: x }, 18), g && g();
2000
2027
  break;
2001
2028
  }
2002
2029
  }
2003
2030
  }
2004
2031
  }
2005
- class nt {
2032
+ class lt {
2006
2033
  spatialHash;
2007
2034
  eventBus;
2008
2035
  i18n;
2009
2036
  throwState = { kills: 0, pos: null };
2010
2037
  constructor(t, e) {
2011
- this.spatialHash = new z(100), this.eventBus = t, this.i18n = e;
2012
- }
2013
- update(t, e, i, s, a, l, n, o, r, c, h, u, d, _) {
2014
- const f = E.getInstance().getConfig().piercer;
2015
- for (const g of i)
2016
- 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);
2038
+ this.spatialHash = new J(100), this.eventBus = t, this.i18n = e;
2039
+ }
2040
+ update(t, e, i, s, a, r, o, n, l, h, c, p, g, _) {
2041
+ const m = v.getInstance().getConfig().piercer;
2042
+ for (const d of i)
2043
+ if (d.active && !d.isDying) {
2044
+ if (d.isThrown && d.type === "piercer" && m.hasHoming && d.remainingHomingKills > 0) {
2045
+ let x = null, y = 1 / 0;
2046
+ for (const E of i) {
2047
+ if (E === d || !E.active || E.isGrabbed || E.isDying) continue;
2048
+ const I = E.position.x - d.position.x, T = E.position.y - d.position.y, L = I * I + T * T;
2049
+ L < y && (y = L, x = E);
2023
2050
  }
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;
2027
- for (; x < -Math.PI; ) x += Math.PI * 2;
2028
- 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
2051
+ if (x) {
2052
+ const E = Math.atan2(x.position.y - d.position.y, x.position.x - d.position.x), I = Math.max(Math.hypot(d.velocity.x, d.velocity.y), 1e3), T = 25 * t, L = Math.atan2(d.velocity.y, d.velocity.x);
2053
+ let A = E - L;
2054
+ for (; A < -Math.PI; ) A += Math.PI * 2;
2055
+ for (; A > Math.PI; ) A -= Math.PI * 2;
2056
+ const R = L + Math.sign(A) * Math.min(Math.abs(A), T);
2057
+ d.rotation = R, d.velocity = {
2058
+ x: Math.cos(R) * I,
2059
+ y: Math.sin(R) * I
2033
2060
  };
2034
2061
  }
2035
2062
  }
2036
- 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);
2063
+ if (d.isStationaryShield) {
2064
+ let x = null, y = 1 / 0;
2065
+ for (const E of i) {
2066
+ if (E === d || !E.active || E.isGrabbed || E.isDying || E.isStationaryShield) continue;
2067
+ const I = E.position.x - d.position.x, T = E.position.y - d.position.y, L = I * I + T * T;
2068
+ L < y && (y = L, x = E);
2042
2069
  }
2043
- if (m) {
2044
- let I = Math.atan2(m.position.y - g.position.y, m.position.x - g.position.x) - g.rotation;
2070
+ if (x) {
2071
+ let I = Math.atan2(x.position.y - d.position.y, x.position.x - d.position.x) - d.rotation;
2045
2072
  for (; I < -Math.PI; ) I += Math.PI * 2;
2046
2073
  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);
2074
+ const T = 5 * t;
2075
+ d.rotation += Math.sign(I) * Math.min(Math.abs(I), T);
2049
2076
  }
2050
2077
  }
2051
- g.update(t);
2052
- } else g.active && g.isDying && g.update(t);
2053
- 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);
2059
- }
2060
- X.update(a, i, t), this.spatialHash.clear();
2061
- for (const g of i)
2062
- g.active && !g.isDying && g.launchDelay <= 0 && this.spatialHash.insert(g);
2063
- j.update(
2078
+ d.update(t);
2079
+ } else d.active && d.isDying && d.update(t);
2080
+ for (let d = r.length - 1; d >= 0; d--) {
2081
+ const x = r[d];
2082
+ if (!x) continue;
2083
+ x.lifetime += t;
2084
+ const y = x.lifetime / x.maxLifetime;
2085
+ x.radius = x.maxRadius * y, x.alpha = Math.max(0, 1 - y), x.lifetime >= x.maxLifetime && r.splice(d, 1);
2086
+ }
2087
+ q.update(a, i, t), this.spatialHash.clear();
2088
+ for (const d of i)
2089
+ d.active && !d.isDying && d.launchDelay <= 0 && this.spatialHash.insert(d);
2090
+ Q.update(
2064
2091
  e,
2065
2092
  i,
2066
- l,
2067
- n,
2068
- o,
2069
2093
  r,
2094
+ o,
2095
+ n,
2096
+ l,
2070
2097
  this.eventBus,
2071
- h,
2072
- u,
2073
- d
2074
- ), st.update(
2098
+ c,
2099
+ p,
2100
+ g
2101
+ ), ot.update(
2075
2102
  i,
2076
2103
  s,
2077
2104
  a,
2078
- l,
2079
- n,
2080
- o,
2081
2105
  r,
2106
+ o,
2107
+ n,
2108
+ l,
2082
2109
  this.eventBus,
2083
- c,
2084
- u,
2085
- d,
2110
+ h,
2111
+ p,
2112
+ g,
2086
2113
  this.throwState,
2087
2114
  this.spatialHash,
2088
2115
  _
2089
- ), at.update(
2116
+ ), nt.update(
2090
2117
  s,
2091
2118
  i,
2092
2119
  a,
2093
- l,
2094
- n,
2120
+ r,
2121
+ o,
2095
2122
  t,
2096
2123
  this.throwState,
2097
2124
  _
2098
- ), ot.update(
2125
+ ), rt.update(
2099
2126
  i,
2100
2127
  s,
2101
2128
  a,
2102
- l,
2103
- n,
2104
- o,
2105
2129
  r,
2130
+ o,
2131
+ n,
2132
+ l,
2106
2133
  this.eventBus,
2107
2134
  this.throwState,
2108
- u,
2109
- d,
2135
+ p,
2136
+ g,
2110
2137
  this.spatialHash,
2111
2138
  _
2112
2139
  );
2113
- const p = 32;
2114
- l.length > p && l.splice(0, l.length - p);
2140
+ const u = 32;
2141
+ r.length > u && r.splice(0, r.length - u);
2115
2142
  }
2116
2143
  }
2117
- class rt {
2144
+ class ct {
2118
2145
  pool = [];
2119
2146
  constructor(t = 500) {
2120
2147
  for (let e = 0; e < t; e++) {
2121
- const i = new w(`pool_enemy_${e}`);
2148
+ const i = new G(`pool_enemy_${e}`);
2122
2149
  this.pool.push(i);
2123
2150
  }
2124
2151
  }
@@ -2126,7 +2153,7 @@ class rt {
2126
2153
  for (const e of this.pool)
2127
2154
  if (!e.active)
2128
2155
  return e.reset(), e;
2129
- const t = new w(`fallback_enemy_${Date.now()}_${Math.random()}`);
2156
+ const t = new G(`fallback_enemy_${Date.now()}_${Math.random()}`);
2130
2157
  return this.pool.push(t), t;
2131
2158
  }
2132
2159
  resetAll() {
@@ -2134,91 +2161,91 @@ class rt {
2134
2161
  t.reset();
2135
2162
  }
2136
2163
  }
2137
- class C {
2164
+ class N {
2138
2165
  static getOffscreenPosition(t, e) {
2139
2166
  const i = Math.floor(Math.random() * 4), s = 70;
2140
2167
  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 };
2141
2168
  }
2142
2169
  static spawnCircleOfDeath(t, e, i, s) {
2143
- const a = [], n = Math.max(i, s) * 0.55 + 80;
2144
- for (let o = 0; o < 18; o++) {
2145
- const r = o * Math.PI * 2 / 18, c = {
2146
- x: e.x + Math.cos(r) * n,
2147
- 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 = {
2150
- x: Math.cos(r + Math.PI) * 55,
2151
- y: Math.sin(r + Math.PI) * 55
2152
- }, a.push(h);
2170
+ const a = [], o = Math.max(i, s) * 0.55 + 80;
2171
+ for (let n = 0; n < 18; n++) {
2172
+ const l = n * Math.PI * 2 / 18, h = {
2173
+ x: e.x + Math.cos(l) * o,
2174
+ y: e.y + Math.sin(l) * o
2175
+ }, c = t.get(), p = ["piercer", "spore", "cluster", "parasite"], g = p[n % p.length];
2176
+ P.configureEnemy(c, g, h, e), c.velocity = {
2177
+ x: Math.cos(l + Math.PI) * 55,
2178
+ y: Math.sin(l + Math.PI) * 55
2179
+ }, a.push(c);
2153
2180
  }
2154
2181
  return a;
2155
2182
  }
2156
2183
  static spawnDenseCluster(t, e, i, s) {
2157
- const a = [], n = Math.floor(Math.random() * 4);
2158
- let o = { x: -60, y: -60 };
2159
- n === 0 ? o = { x: Math.random() * e, y: -80 } : n === 1 ? o = { x: e + 80, y: Math.random() * i } : n === 2 ? o = { x: Math.random() * e, y: i + 80 } : o = { x: -80, y: Math.random() * i };
2160
- for (let r = 0; r < 14; r++) {
2161
- const c = {
2184
+ const a = [], o = Math.floor(Math.random() * 4);
2185
+ let n = { x: -60, y: -60 };
2186
+ o === 0 ? n = { x: Math.random() * e, y: -80 } : o === 1 ? n = { x: e + 80, y: Math.random() * i } : o === 2 ? n = { x: Math.random() * e, y: i + 80 } : n = { x: -80, y: Math.random() * i };
2187
+ for (let l = 0; l < 14; l++) {
2188
+ const h = {
2162
2189
  x: (Math.random() - 0.5) * 60,
2163
2190
  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);
2191
+ }, c = { x: n.x + h.x, y: n.y + h.y }, p = t.get();
2192
+ P.configureEnemy(p, "spore", c, s);
2193
+ const g = s.x - c.x, _ = s.y - c.y, m = Math.atan2(_, g);
2194
+ p.velocity = {
2195
+ x: Math.cos(m) * (50 + Math.random() * 20),
2196
+ y: Math.sin(m) * (50 + Math.random() * 20)
2197
+ }, a.push(p);
2171
2198
  }
2172
2199
  return a;
2173
2200
  }
2174
2201
  static spawnSineSnake(t, e, i, s) {
2175
- const a = [], n = i * 0.2 + Math.random() * i * 0.6;
2176
- for (let o = 0; o < 12; o++) {
2177
- const r = {
2178
- x: -60 - o * 40,
2179
- y: n + Math.sin(o * 0.45) * 70
2180
- }, c = t.get();
2181
- M.configureEnemy(c, "cluster", r, s), c.velocity = { x: 75, y: Math.cos(o * 0.45) * 30 }, a.push(c);
2202
+ const a = [], o = i * 0.2 + Math.random() * i * 0.6;
2203
+ for (let n = 0; n < 12; n++) {
2204
+ const l = {
2205
+ x: -60 - n * 40,
2206
+ y: o + Math.sin(n * 0.45) * 70
2207
+ }, h = t.get();
2208
+ P.configureEnemy(h, "cluster", l, s), h.velocity = { x: 75, y: Math.cos(n * 0.45) * 30 }, a.push(h);
2182
2209
  }
2183
2210
  return a;
2184
2211
  }
2185
2212
  static spawnDoubleSpiral(t, e, i, s) {
2186
2213
  const a = [];
2187
- for (let n = 0; n < 14; n++) {
2188
- const o = n / 14, r = o * Math.PI * 4, c = 120 + o * 450, h = {
2189
- x: e + Math.cos(r) * c,
2190
- y: -60 + Math.sin(r) * c
2191
- }, u = t.get();
2192
- M.configureEnemy(u, "parasite", h, s), a.push(u);
2214
+ for (let o = 0; o < 14; o++) {
2215
+ const n = o / 14, l = n * Math.PI * 4, h = 120 + n * 450, c = {
2216
+ x: e + Math.cos(l) * h,
2217
+ y: -60 + Math.sin(l) * h
2218
+ }, p = t.get();
2219
+ P.configureEnemy(p, "parasite", c, s), a.push(p);
2193
2220
  }
2194
2221
  return a;
2195
2222
  }
2196
2223
  static spawnMarchingWall(t, e, i, s) {
2197
- const a = [], n = Math.random() > 0.5;
2198
- for (let o = 0; o < 12; o++) {
2199
- const r = o / 11 * i, c = {
2200
- x: n ? -60 : e + 60,
2201
- y: r
2202
- }, h = t.get();
2203
- M.configureEnemy(h, "piercer", c, s), h.velocity = {
2204
- x: n ? 70 : -70,
2224
+ const a = [], o = Math.random() > 0.5;
2225
+ for (let n = 0; n < 12; n++) {
2226
+ const l = n / 11 * i, h = {
2227
+ x: o ? -60 : e + 60,
2228
+ y: l
2229
+ }, c = t.get();
2230
+ P.configureEnemy(c, "piercer", h, s), c.velocity = {
2231
+ x: o ? 70 : -70,
2205
2232
  y: 0
2206
- }, a.push(h);
2233
+ }, a.push(c);
2207
2234
  }
2208
2235
  return a;
2209
2236
  }
2210
2237
  static spawnCrossfireStreams(t, e, i, s) {
2211
2238
  const a = [];
2212
- for (let n = 0; n < 10; n++) {
2213
- const o = { x: -50 - n * 35, y: -50 - n * 35 }, r = t.get();
2214
- M.configureEnemy(r, "spore", o, s), a.push(r);
2215
- 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);
2239
+ for (let o = 0; o < 10; o++) {
2240
+ const n = { x: -50 - o * 35, y: -50 - o * 35 }, l = t.get();
2241
+ P.configureEnemy(l, "spore", n, s), a.push(l);
2242
+ const h = { x: e + 50 + o * 35, y: i + 50 + o * 35 }, c = t.get();
2243
+ P.configureEnemy(c, "cluster", h, s), a.push(c);
2217
2244
  }
2218
2245
  return a;
2219
2246
  }
2220
2247
  }
2221
- class lt {
2248
+ class ht {
2222
2249
  wave = 1;
2223
2250
  pool;
2224
2251
  spawnTimer = 0;
@@ -2226,63 +2253,63 @@ class lt {
2226
2253
  patternCooldown = 0;
2227
2254
  initialGracePeriod = 6;
2228
2255
  constructor() {
2229
- this.pool = new rt(500);
2256
+ this.pool = new ct(500);
2230
2257
  }
2231
2258
  reset() {
2232
2259
  this.wave = 1, this.spawnTimer = 0, this.waveTimer = 0, this.patternCooldown = 0;
2233
2260
  }
2234
2261
  update(t, e, i, s, a) {
2235
2262
  this.waveTimer += t, this.spawnTimer += t, this.patternCooldown += t, this.applyFlockingBehaviors(e, t, a);
2236
- const l = e.filter((r) => r.active).length, n = Math.max(0.9, 2.2 - (this.wave - 1) * 0.18);
2237
- if (this.waveTimer > this.initialGracePeriod && this.patternCooldown > Math.max(12 - this.wave, 6) && l < 35) {
2263
+ const r = e.filter((l) => l.active).length, o = Math.max(0.9, 2.2 - (this.wave - 1) * 0.18);
2264
+ if (this.waveTimer > this.initialGracePeriod && this.patternCooldown > Math.max(12 - this.wave, 6) && r < 35) {
2238
2265
  this.patternCooldown = 0;
2239
- const r = this.spawnPatternFormation(i, s, a);
2240
- for (const c of r)
2241
- e.push(c);
2266
+ const l = this.spawnPatternFormation(i, s, a);
2267
+ for (const h of l)
2268
+ e.push(h);
2242
2269
  }
2243
- const o = Math.min(18 + this.wave * 4, 80);
2244
- return this.spawnTimer >= n && l < o ? (this.spawnTimer = 0, this.spawnSingleEnemy(i, s, a)) : null;
2270
+ const n = Math.min(18 + this.wave * 4, 80);
2271
+ return this.spawnTimer >= o && r < n ? (this.spawnTimer = 0, this.spawnSingleEnemy(i, s, a)) : null;
2245
2272
  }
2246
2273
  spawnSingleEnemy(t, e, i) {
2247
- const s = C.getOffscreenPosition(t, e), a = Math.random();
2248
- let l = "piercer";
2249
- a > 0.75 ? l = "heavy" : a > 0.55 ? l = "parasite" : a > 0.35 ? l = "cluster" : a > 0.15 && (l = "spore");
2250
- const n = this.pool.get();
2251
- return M.configureEnemy(n, l, s, i), n;
2274
+ const s = N.getOffscreenPosition(t, e), a = Math.random();
2275
+ let r = "piercer";
2276
+ a > 0.75 ? r = "heavy" : a > 0.55 ? r = "parasite" : a > 0.35 ? r = "cluster" : a > 0.15 && (r = "spore");
2277
+ const o = this.pool.get();
2278
+ return P.configureEnemy(o, r, s, i), o;
2252
2279
  }
2253
2280
  spawnPatternFormation(t, e, i) {
2254
2281
  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);
2282
+ return s < 0.25 ? N.spawnCircleOfDeath(this.pool, i, t, e) : s < 0.5 ? N.spawnDenseCluster(this.pool, t, e, i) : s < 0.75 ? N.spawnSineSnake(this.pool, t, e, i) : N.spawnMarchingWall(this.pool, t, e, i);
2256
2283
  }
2257
2284
  applyFlockingBehaviors(t, e, i) {
2258
2285
  for (let a = 0; a < t.length; a++) {
2259
- const l = t[a];
2260
- if (!l.active || l.isGrabbed || l.isThrown || l.isDying) continue;
2261
- let n = 0, o = 0, r = 0;
2262
- for (let d = 0; d < t.length; d++) {
2263
- if (a === d) continue;
2264
- const _ = t[d];
2286
+ const r = t[a];
2287
+ if (!r.active || r.isGrabbed || r.isThrown || r.isDying) continue;
2288
+ let o = 0, n = 0, l = 0;
2289
+ for (let g = 0; g < t.length; g++) {
2290
+ if (a === g) continue;
2291
+ const _ = t[g];
2265
2292
  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++);
2293
+ const m = r.position.x - _.position.x, u = r.position.y - _.position.y, d = Math.hypot(m, u);
2294
+ d > 0 && d < 70 && (o += m / d, n += u / d, l++);
2268
2295
  }
2269
- 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) {
2272
- const d = 80 + Math.min(this.wave * 4, 40);
2273
- l.velocity.x += c / u * d * e, l.velocity.y += h / u * d * e;
2296
+ l > 0 && (o /= l, n /= l, r.velocity.x += o * 60 * e, r.velocity.y += n * 60 * e);
2297
+ const h = i.x - r.position.x, c = i.y - r.position.y, p = Math.hypot(h, c);
2298
+ if (p > 0) {
2299
+ const g = 80 + Math.min(this.wave * 4, 40);
2300
+ r.velocity.x += h / p * g * e, r.velocity.y += c / p * g * e;
2274
2301
  }
2275
- if (l.maxSpeed > 0) {
2276
- const d = Math.hypot(l.velocity.x, l.velocity.y);
2277
- if (d > l.maxSpeed) {
2278
- const _ = l.maxSpeed / d;
2279
- l.velocity.x *= _, l.velocity.y *= _;
2302
+ if (r.maxSpeed > 0) {
2303
+ const g = Math.hypot(r.velocity.x, r.velocity.y);
2304
+ if (g > r.maxSpeed) {
2305
+ const _ = r.maxSpeed / g;
2306
+ r.velocity.x *= _, r.velocity.y *= _;
2280
2307
  }
2281
2308
  }
2282
2309
  }
2283
2310
  }
2284
2311
  }
2285
- class ct {
2312
+ class pt {
2286
2313
  id;
2287
2314
  position;
2288
2315
  velocity;
@@ -2304,15 +2331,15 @@ class ct {
2304
2331
  update(t, e, i, s) {
2305
2332
  if (this.active) {
2306
2333
  if (this.isAbsorbing) {
2307
- const a = e.x - this.position.x, l = e.y - this.position.y, n = Math.hypot(a, l);
2308
- if (n <= i + this.radius) {
2334
+ const a = e.x - this.position.x, r = e.y - this.position.y, o = Math.hypot(a, r);
2335
+ if (o <= i + this.radius) {
2309
2336
  this.position = { ...e }, this.active = !1;
2310
2337
  return;
2311
2338
  }
2312
- const o = Math.min(s + n * 0.7, 1600);
2339
+ const n = Math.min(s + o * 0.7, 1600);
2313
2340
  this.velocity = {
2314
- x: a / n * o,
2315
- y: l / n * o
2341
+ x: a / o * n,
2342
+ y: r / o * n
2316
2343
  };
2317
2344
  } else {
2318
2345
  const a = Math.pow(0.04, t);
@@ -2322,21 +2349,21 @@ class ct {
2322
2349
  }
2323
2350
  }
2324
2351
  }
2325
- const P = {
2352
+ const w = {
2326
2353
  bioluminescent: {
2327
2354
  bgInner: "#081220",
2328
2355
  bgMid: "#050b16",
2329
2356
  bgOuter: "#020408",
2330
2357
  nebulaCyan: "rgba(0, 240, 255, 0.08)",
2331
2358
  nebulaMagenta: "rgba(255, 0, 221, 0.07)",
2332
- piercerColor: "#ff2a5f",
2333
- sporeColor: "#39ff14",
2334
- clusterColor: "#ffd700",
2335
- parasiteColor: "#9d4edd",
2336
- microColor: "#ffd700",
2337
- corePrimary: "#00f0ff",
2338
- coreGlow: "rgba(0, 240, 255, 0.85)",
2339
- tendrilMagenta: "#ff00dd",
2359
+ piercerColor: f.piercer,
2360
+ sporeColor: f.spore,
2361
+ clusterColor: f.cluster,
2362
+ parasiteColor: f.parasite,
2363
+ microColor: f.micro,
2364
+ corePrimary: f.core,
2365
+ coreGlow: f.coreGlow,
2366
+ tendrilMagenta: f.coreAccent,
2340
2367
  tendrilCyan: "#00ffff",
2341
2368
  effectHighlight: "#ffffff",
2342
2369
  effectInk: "#ffffff",
@@ -2389,22 +2416,22 @@ const P = {
2389
2416
  vortexCore: "#274760",
2390
2417
  vortexMid: "#577c9e"
2391
2418
  }
2392
- }, D = "axon_surge_theme";
2393
- class ht {
2419
+ }, U = "axon_surge_theme";
2420
+ class ut {
2394
2421
  currentTheme = "dark";
2395
2422
  isExplicit = !1;
2396
2423
  targetElement;
2397
2424
  constructor(t, e) {
2398
2425
  e !== void 0 && (this.targetElement = e);
2399
2426
  try {
2400
- const i = localStorage.getItem(D);
2401
- if (i && P[i]) {
2427
+ const i = localStorage.getItem(U);
2428
+ if (i && w[i]) {
2402
2429
  this.currentTheme = i, this.isExplicit = !0, this.applyThemeToDOM();
2403
2430
  return;
2404
2431
  }
2405
2432
  } catch {
2406
2433
  }
2407
- if (t && P[t]) {
2434
+ if (t && w[t]) {
2408
2435
  this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
2409
2436
  return;
2410
2437
  }
@@ -2414,10 +2441,10 @@ class ht {
2414
2441
  this.targetElement = t, this.isExplicit ? this.applyThemeToDOM() : this.currentTheme = this.detectParentOrSystemTheme();
2415
2442
  }
2416
2443
  setTheme(t) {
2417
- if (P[t]) {
2444
+ if (w[t]) {
2418
2445
  this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
2419
2446
  try {
2420
- localStorage.setItem(D, t);
2447
+ localStorage.setItem(U, t);
2421
2448
  } catch {
2422
2449
  }
2423
2450
  }
@@ -2425,7 +2452,7 @@ class ht {
2425
2452
  clearExplicitTheme() {
2426
2453
  this.isExplicit = !1;
2427
2454
  try {
2428
- localStorage.removeItem(D);
2455
+ localStorage.removeItem(U);
2429
2456
  } catch {
2430
2457
  }
2431
2458
  this.removeThemeClasses(), this.currentTheme = this.detectParentOrSystemTheme();
@@ -2434,7 +2461,7 @@ class ht {
2434
2461
  return this.isExplicit || (this.currentTheme = this.detectParentOrSystemTheme()), this.currentTheme;
2435
2462
  }
2436
2463
  getPalette() {
2437
- return P[this.getTheme()] || P.dark;
2464
+ return w[this.getTheme()] || w.dark;
2438
2465
  }
2439
2466
  detectParentOrSystemTheme() {
2440
2467
  try {
@@ -2472,83 +2499,83 @@ class ht {
2472
2499
  this.targetElement.classList.add(t);
2473
2500
  }
2474
2501
  }
2475
- class ut {
2502
+ class dt {
2476
2503
  maxDistance = 800;
2477
2504
  maxThickness = 18;
2478
2505
  minThickness = 5;
2479
2506
  maxLength = 110;
2480
2507
  minLength = 50;
2481
2508
  render(t, e, i, s, a) {
2482
- for (const l of e) {
2483
- if (!l.active || l.isGrabbed || l.isDying) continue;
2484
- const n = l.position.x, o = l.position.y;
2485
- if (n >= 0 && n <= i && o >= 0 && o <= s) continue;
2486
- 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
- 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);
2509
+ for (const r of e) {
2510
+ if (!r.active || r.isGrabbed || r.isDying) continue;
2511
+ const o = r.position.x, n = r.position.y;
2512
+ if (o >= 0 && o <= i && n >= 0 && n <= s) continue;
2513
+ const l = Math.min(i, Math.max(0, o)), h = Math.min(s, Math.max(0, n)), c = Math.hypot(o - l, n - h);
2514
+ if (c <= 0 || c > this.maxDistance) continue;
2515
+ const p = Math.min(1, Math.max(0, c / this.maxDistance)), g = this.minThickness + (this.maxThickness - this.minThickness) * (1 - p), _ = this.minLength + (this.maxLength - this.minLength) * (1 - p), m = 0.55 + (1 - p) * 0.35;
2516
+ if (t.save(), t.globalAlpha = m, t.shadowColor = r.color, t.shadowBlur = 14, t.strokeStyle = r.color, t.lineWidth = g, t.lineCap = "round", t.beginPath(), l === 0 || l === i) {
2517
+ const u = Math.max(0, h - _ / 2), d = Math.min(s, h + _ / 2);
2518
+ t.moveTo(l, u), t.lineTo(l, d);
2492
2519
  } else {
2493
- const p = Math.max(0, r - _ / 2), g = Math.min(i, r + _ / 2);
2494
- t.moveTo(p, c), t.lineTo(g, c);
2520
+ const u = Math.max(0, l - _ / 2), d = Math.min(i, l + _ / 2);
2521
+ t.moveTo(u, h), t.lineTo(d, h);
2495
2522
  }
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();
2523
+ t.stroke(), t.strokeStyle = a.effectHighlight, t.lineWidth = Math.max(1.8, g * 0.28), t.globalAlpha = m * 0.9, t.stroke(), t.restore();
2497
2524
  }
2498
2525
  }
2499
2526
  }
2500
- class pt {
2501
- 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);
2504
- const g = Math.min(e, i) * 0.055;
2527
+ class gt {
2528
+ render(t, e, i, s, a, r, o = !1) {
2529
+ const n = Math.max(1, a), l = Math.min(1, (n - 1) / 8), h = this.wrapHue(190 + (n - 1) * 34 + Math.sin(s * 0.1) * 5), c = this.wrapHue(h + 42), p = this.wrapHue(h + 150), g = e / 2, _ = i / 2, m = Math.max(e, i) * 0.82, u = t.createRadialGradient(g, _, 20, g, _, m);
2530
+ o ? (u.addColorStop(0, `hsl(${h}, 42%, 91%)`), u.addColorStop(0.42, `hsl(${c}, 42%, 86%)`), u.addColorStop(0.78, `hsl(${p}, 38%, 81%)`), u.addColorStop(1, r.bgOuter)) : (u.addColorStop(0, `hsl(${h}, 42%, 11%)`), u.addColorStop(0.42, `hsl(${c}, 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);
2531
+ const d = Math.min(e, i) * 0.055;
2505
2532
  this.drawNebula(
2506
2533
  t,
2507
- e * 0.22 + Math.sin(s * 0.18) * g,
2508
- i * 0.28 + Math.cos(s * 0.15) * g,
2534
+ e * 0.22 + Math.sin(s * 0.18) * d,
2535
+ i * 0.28 + Math.cos(s * 0.15) * d,
2509
2536
  Math.max(e, i) * 0.42,
2510
- c,
2511
- n ? 0.27 : 0.23,
2512
- n
2537
+ h,
2538
+ o ? 0.27 : 0.23,
2539
+ o
2513
2540
  ), this.drawNebula(
2514
2541
  t,
2515
- e * 0.8 + Math.cos(s * 0.14) * g,
2516
- i * 0.7 + Math.sin(s * 0.17) * g,
2542
+ e * 0.8 + Math.cos(s * 0.14) * d,
2543
+ i * 0.7 + Math.sin(s * 0.17) * d,
2517
2544
  Math.max(e, i) * 0.48,
2518
- h,
2519
- n ? 0.23 : 0.2,
2520
- n
2545
+ c,
2546
+ o ? 0.23 : 0.2,
2547
+ o
2521
2548
  ), this.drawNebula(
2522
2549
  t,
2523
- e * 0.86 + Math.sin(s * 0.11) * g * 0.7,
2524
- i * 0.16 + Math.cos(s * 0.13) * g * 0.7,
2550
+ e * 0.86 + Math.sin(s * 0.11) * d * 0.7,
2551
+ i * 0.16 + Math.cos(s * 0.13) * d * 0.7,
2525
2552
  Math.max(e, i) * 0.3,
2526
- u,
2527
- n ? 0.17 : 0.14,
2528
- n
2529
- ), 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);
2553
+ p,
2554
+ o ? 0.17 : 0.14,
2555
+ o
2556
+ ), this.drawSoftFlows(t, e, i, s, h, l, o), this.drawParticleField(t, e, i, s, h, c, n, o);
2557
+ const x = t.createRadialGradient(g, _, Math.min(e, i) * 0.28, g, _, m);
2558
+ x.addColorStop(0, "rgba(0, 0, 0, 0)"), x.addColorStop(1, o ? "rgba(40, 60, 90, 0.09)" : "rgba(0, 0, 0, 0.2)"), t.fillStyle = x, t.fillRect(0, 0, e, i);
2532
2559
  }
2533
- drawNebula(t, e, i, s, a, l, n) {
2534
- const o = t.createRadialGradient(e, i, 0, e, i, s), r = n ? 52 : 60;
2535
- o.addColorStop(0, `hsla(${a}, ${n ? 88 : 80}%, ${r}%, ${l})`), o.addColorStop(0.38, `hsla(${a}, ${n ? 82 : 75}%, ${r - (n ? 7 : 12)}%, ${l * 0.5})`), o.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = o, t.beginPath(), t.arc(e, i, s, 0, Math.PI * 2), t.fill();
2560
+ drawNebula(t, e, i, s, a, r, o) {
2561
+ const n = t.createRadialGradient(e, i, 0, e, i, s), l = o ? 52 : 60;
2562
+ n.addColorStop(0, `hsla(${a}, ${o ? 88 : 80}%, ${l}%, ${r})`), n.addColorStop(0.38, `hsla(${a}, ${o ? 82 : 75}%, ${l - (o ? 7 : 12)}%, ${r * 0.5})`), n.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = n, t.beginPath(), t.arc(e, i, s, 0, Math.PI * 2), t.fill();
2536
2563
  }
2537
- drawSoftFlows(t, e, i, s, a, l, n) {
2564
+ drawSoftFlows(t, e, i, s, a, r, o) {
2538
2565
  t.save();
2539
- const o = Math.min(e, i), r = o * 0.035;
2540
- 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
- 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();
2566
+ const n = Math.min(e, i), l = n * 0.035;
2567
+ t.globalAlpha = o ? 0.15 : 0.12, t.lineWidth = Math.max(1.3, n * 17e-4), t.lineCap = "round", t.shadowBlur = n * 0.02, t.shadowColor = `hsla(${a}, 85%, ${o ? 52 : 62}%, 0.28)`;
2568
+ for (let h = 0; h < 3; h++) {
2569
+ const c = (h - 1) * n * 0.075 + Math.sin(s * 0.06 + h) * l, p = h * 28 + r * 18;
2570
+ t.strokeStyle = `hsla(${this.wrapHue(a + p)}, ${o ? 78 : 74}%, ${o ? 47 : 62}%, ${0.52 - h * 0.08})`, t.beginPath(), t.moveTo(-n * 0.12, i * 0.2 + c), t.bezierCurveTo(e * 0.2, i * 0.02 + c, e * 0.47, i * 0.2 - c, e * 0.73, i * 0.07 + c), t.bezierCurveTo(e * 0.94, -n * 0.02 + c, e * 1.04, i * 0.16 + c, e * 1.1, i * 0.36 + c), t.stroke(), t.beginPath(), t.moveTo(-n * 0.1, i * 0.8 - c), t.bezierCurveTo(e * 0.2, i * 0.98 - c, e * 0.48, i * 0.8 + c, e * 0.75, i * 0.93 - c), t.bezierCurveTo(e * 0.94, i * 1.02 - c, e * 1.04, i * 0.84 - c, e * 1.1, i * 0.65 - c), t.stroke();
2544
2571
  }
2545
2572
  t.restore();
2546
2573
  }
2547
- 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;
2549
- 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();
2574
+ drawParticleField(t, e, i, s, a, r, o, n) {
2575
+ const l = 44 + Math.min(24, o * 2), h = e / 2, c = i / 2, p = Math.min(e, i) * 0.17;
2576
+ for (let g = 0; g < l; g++) {
2577
+ const _ = g + o * 17, m = this.unitNoise(_ * 1.7) * e, u = this.unitNoise(_ * 2.9 + 13) * i, d = Math.hypot(m - h, u - c), x = Math.min(1, Math.max(0, (d - p) / (Math.min(e, i) * 0.28))), y = 0.7 + Math.sin(s * (0.6 + g % 4 * 0.08) + _) * 0.3, E = (n ? 0.34 : 0.3) * x * y, I = 0.65 + g % 3 * 0.45;
2578
+ t.fillStyle = `hsla(${g % 3 === 0 ? r : a}, ${n ? 82 : 78}%, ${n ? 40 : 70}%, ${E})`, t.beginPath(), t.arc(m, u, I, 0, Math.PI * 2), t.fill();
2552
2579
  }
2553
2580
  }
2554
2581
  unitNoise(t) {
@@ -2558,88 +2585,153 @@ class pt {
2558
2585
  return (t % 360 + 360) % 360;
2559
2586
  }
2560
2587
  }
2561
- class dt {
2588
+ class _t {
2562
2589
  render(t, e, i) {
2563
2590
  if (!e.isActive) return;
2564
2591
  const s = e.getLauncher(), a = e.getTarget();
2565
2592
  if (!s || !a || !s.active || !a.active) return;
2566
- const l = e.getStep();
2567
- if (t.save(), l === 1) {
2568
- const n = Math.sin(i * 6) * 10, o = s.position.x, r = s.position.y - 65 + n;
2569
- t.shadowColor = "#00f0ff", t.shadowBlur = 20, t.fillStyle = "#00f0ff", t.beginPath(), t.moveTo(o, r + 20), t.lineTo(o - 16, r - 12), t.lineTo(o - 6, r - 12), t.lineTo(o - 6, r - 32), t.lineTo(o + 6, r - 32), t.lineTo(o + 6, r - 12), t.lineTo(o + 16, r - 12), t.closePath(), t.fill();
2570
- const c = s.radius * (1.6 + Math.sin(i * 8) * 0.3);
2571
- t.strokeStyle = "rgba(0, 240, 255, 0.8)", t.lineWidth = 3, t.beginPath(), t.arc(s.position.x, s.position.y, c, 0, Math.PI * 2), t.stroke();
2572
- } else if (l === 2) {
2573
- const n = a.position.x - s.position.x, o = a.position.y - s.position.y;
2574
- if (Math.hypot(n, o) > 10) {
2575
- const c = Math.atan2(o, n);
2576
- 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();
2579
- const d = a.radius * (1.8 + Math.cos(i * 10) * 0.3);
2580
- 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();
2593
+ const r = e.getStep();
2594
+ if (t.save(), r === 1) {
2595
+ const o = Math.sin(i * 6) * 10, n = s.position.x, l = s.position.y - 65 + o;
2596
+ t.shadowColor = f.core, t.shadowBlur = 20, t.fillStyle = f.core, t.beginPath(), t.moveTo(n, l + 20), t.lineTo(n - 16, l - 12), t.lineTo(n - 6, l - 12), t.lineTo(n - 6, l - 32), t.lineTo(n + 6, l - 32), t.lineTo(n + 6, l - 12), t.lineTo(n + 16, l - 12), t.closePath(), t.fill();
2597
+ const h = s.radius * (1.6 + Math.sin(i * 8) * 0.3);
2598
+ t.strokeStyle = "rgba(0, 240, 255, 0.8)", t.lineWidth = 3, t.beginPath(), t.arc(s.position.x, s.position.y, h, 0, Math.PI * 2), t.stroke();
2599
+ } else if (r === 2) {
2600
+ const o = a.position.x - s.position.x, n = a.position.y - s.position.y;
2601
+ if (Math.hypot(o, n) > 10) {
2602
+ const h = Math.atan2(n, o);
2603
+ t.shadowColor = f.coreAccent, t.shadowBlur = 22, t.strokeStyle = f.coreAccent, 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([]);
2604
+ const c = a.position.x - Math.cos(h) * (a.radius + 10), p = a.position.y - Math.sin(h) * (a.radius + 10);
2605
+ t.fillStyle = f.coreAccent, t.beginPath(), t.moveTo(c, p), t.lineTo(c - Math.cos(h - 0.4) * 24, p - Math.sin(h - 0.4) * 24), t.lineTo(c - Math.cos(h + 0.4) * 24, p - Math.sin(h + 0.4) * 24), t.closePath(), t.fill();
2606
+ const g = a.radius * (1.8 + Math.cos(i * 10) * 0.3);
2607
+ t.strokeStyle = "rgba(255, 0, 221, 0.9)", t.lineWidth = 3.5, t.beginPath(), t.arc(a.position.x, a.position.y, g, 0, Math.PI * 2), t.stroke();
2581
2608
  }
2582
2609
  }
2583
2610
  t.restore();
2584
2611
  }
2585
2612
  }
2586
- class gt {
2613
+ class mt {
2614
+ draw(t, e, i, s, a) {
2615
+ t.shadowColor = a, t.shadowBlur = 16, t.fillStyle = a, e.type === "piercer" ? this.drawPiercer(t, e, i, s) : e.type === "spore" ? this.drawSpore(t, e, i, s) : e.type === "cluster" ? this.drawCluster(t, e, i) : e.type === "parasite" ? this.drawParasite(t, e, i, s) : e.type === "heavy" ? this.drawHeavy(t, e, i, s) : (t.beginPath(), t.arc(0, 0, e.radius, 0, Math.PI * 2), t.fill());
2616
+ }
2617
+ drawPiercer(t, e, i, s) {
2618
+ t.rotate(e.rotation), t.beginPath();
2619
+ const a = 12;
2620
+ for (let r = 0; r <= a; r++) {
2621
+ const o = r * Math.PI * 2 / a, n = e.radius * 1.6 + Math.sin(o * 3 + i * 4) * 3, l = e.radius * 0.6 + Math.cos(o * 2 + i * 3) * 2, h = Math.cos(o) * n, c = Math.sin(o) * l;
2622
+ r === 0 ? t.moveTo(h, c) : t.lineTo(h, c);
2623
+ }
2624
+ t.closePath(), t.fill(), t.fillStyle = s.effectHighlight, t.beginPath(), t.arc(4, 0, 4, 0, Math.PI * 2), t.fill();
2625
+ }
2626
+ drawSpore(t, e, i, s) {
2627
+ t.beginPath();
2628
+ const a = 8;
2629
+ for (let r = 0; r < a; r++) {
2630
+ const o = r * Math.PI * 2 / a, n = e.radius + Math.sin(o * 4 + i * 3 + e.position.x) * 4, l = Math.cos(o) * n, h = Math.sin(o) * n;
2631
+ r === 0 ? t.moveTo(l, h) : t.lineTo(l, h);
2632
+ }
2633
+ t.closePath(), t.fill(), t.fillStyle = s.effectHighlight, t.beginPath(), t.arc(-4, -4, 5, 0, Math.PI * 2), t.arc(5, 3, 4, 0, Math.PI * 2), t.fill();
2634
+ }
2635
+ drawCluster(t, e, i) {
2636
+ t.beginPath();
2637
+ const s = Math.sin(i * 3) * 2;
2638
+ t.arc(0, 0, e.radius * 0.55, 0, Math.PI * 2), t.arc(-9 + s, -7, e.radius * 0.42, 0, Math.PI * 2), t.arc(9 - s, -7, e.radius * 0.42, 0, Math.PI * 2), t.arc(0, 9 + s, e.radius * 0.45, 0, Math.PI * 2), t.fill();
2639
+ }
2640
+ drawParasite(t, e, i, s) {
2641
+ t.beginPath();
2642
+ const a = 14;
2643
+ for (let r = 0; r <= a; r++) {
2644
+ const o = r * Math.PI * 2 / a, n = e.radius + Math.sin(o * 5 - i * 5) * 3, l = Math.cos(o) * n, h = Math.sin(o) * n;
2645
+ r === 0 ? t.moveTo(l, h) : t.lineTo(l, h);
2646
+ }
2647
+ t.closePath(), t.fill(), t.fillStyle = s.bgOuter, t.beginPath(), t.arc(0, 0, e.radius * 0.45, 0, Math.PI * 2), t.fill();
2648
+ }
2649
+ drawHeavy(t, e, i, s) {
2650
+ t.rotate(e.rotation);
2651
+ const a = e.radius, r = a * 0.88, o = Math.sin(i * 3 + e.position.x * 0.01) * 1.5, n = f.heavy;
2652
+ t.save(), t.translate(-a * 0.12, o), t.fillStyle = n, t.shadowColor = n, t.shadowBlur = 20, t.beginPath();
2653
+ const l = 10;
2654
+ for (let u = 0; u <= l; u++) {
2655
+ const d = u * Math.PI * 2 / l, x = 1 + Math.sin(d * 3 + i * 2.4) * 0.08, y = Math.cos(d) * r * x, E = Math.sin(d) * r * x * 0.9;
2656
+ u === 0 ? t.moveTo(y, E) : t.lineTo(y, E);
2657
+ }
2658
+ t.closePath(), t.fill(), t.fillStyle = f.shieldEye, t.shadowColor = f.shieldEye, t.shadowBlur = 7, t.beginPath(), t.arc(-a * 0.28, -a * 0.2, a * 0.11, 0, Math.PI * 2), t.arc(a * 0.02, a * 0.18, a * 0.08, 0, Math.PI * 2), t.fill(), t.restore();
2659
+ const h = a * 0.22, c = v.getInstance().getConfig().shield.protectionArc, p = a * 0.72, g = a * 0.38;
2660
+ t.save(), t.translate(h, 0), t.beginPath(), t.arc(0, 0, p, -c / 2, c / 2, !1);
2661
+ const _ = Math.cos(c / 2) * g, m = Math.sin(c / 2) * g;
2662
+ t.lineTo(_, m), t.arc(0, 0, g, c / 2, -c / 2, !0), t.closePath(), t.fillStyle = f.heavy, t.shadowColor = f.heavy, t.shadowBlur = e.isStationaryShield ? 28 : 16, t.fill(), t.strokeStyle = s.effectHighlight, t.lineWidth = 2.5, t.beginPath(), t.arc(0, 0, p + Math.sin(i * 4) * 2, -c / 2 + 0.1, c / 2 - 0.1), t.stroke(), t.strokeStyle = f.heavyAccent, t.lineWidth = 1.5, t.shadowColor = f.heavyAccent, t.shadowBlur = 8, t.beginPath(), t.arc(0, 0, g * 0.72, -c * 0.42, c * 0.42), t.stroke();
2663
+ for (let u = -2; u <= 2; u++) {
2664
+ const d = u * c / 6, x = Math.cos(d) * (g + 6), y = Math.sin(d) * (g + 6);
2665
+ t.fillStyle = s.effectHighlight, t.beginPath(), t.arc(x, y, 3, 0, Math.PI * 2), t.fill();
2666
+ }
2667
+ t.restore();
2668
+ }
2669
+ }
2670
+ const ft = {
2671
+ common: f.spore,
2672
+ rare: f.parasite,
2673
+ epic: f.cluster,
2674
+ legendary: f.core
2675
+ };
2676
+ class xt {
2587
2677
  canvas;
2588
2678
  ctx;
2589
2679
  themeManager;
2590
2680
  indicatorRenderer;
2591
2681
  bgRenderer;
2592
2682
  tutorialArrowRenderer;
2683
+ enemyShapeRenderer;
2593
2684
  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();
2685
+ this.canvas = t, this.ctx = t.getContext("2d"), this.themeManager = e, this.indicatorRenderer = new dt(), this.bgRenderer = new gt(), this.tutorialArrowRenderer = new _t(), this.enemyShapeRenderer = new mt();
2595
2686
  }
2596
- render(t, e, i, s, a, l, n, o, r, c, h, u = 1, d) {
2687
+ render(t, e, i, s, a, r, o, n, l, h, c, p = 1, g) {
2597
2688
  if (!this.ctx) return;
2598
- const _ = this.themeManager.getPalette(), { width: f, height: p } = this.canvas, g = r.getShakeOffset();
2599
- this.ctx.save(), this.ctx.translate(g.x, g.y), this.bgRenderer.render(
2689
+ const _ = this.themeManager.getPalette(), { width: m, height: u } = this.canvas, d = l.getShakeOffset();
2690
+ this.ctx.save(), this.ctx.translate(d.x, d.y), this.bgRenderer.render(
2600
2691
  this.ctx,
2601
- f,
2602
- p,
2603
- t.pulsePhase,
2692
+ m,
2604
2693
  u,
2694
+ t.pulsePhase,
2695
+ p,
2605
2696
  _,
2606
2697
  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();
2698
+ ), this.drawExperienceOrbs(i, t.position, t.pulsePhase, _), this.drawToxicPools(s, t.pulsePhase), this.drawGravityVortices(a, t.pulsePhase), this.drawShockwaves(r), this.drawCoreFilaments(t, _), this.drawParticles(o), v.getInstance().getConfig().core.hasOffscreenIndicators && this.indicatorRenderer.render(this.ctx, e, m, u, _), this.drawOrganicEnemies(e, t.pulsePhase, _), g && this.tutorialArrowRenderer.render(this.ctx, g, t.pulsePhase), h ? this.drawPsionicTendril(t.position, h.position, _) : t && this.drawHoverTendril(t.position, c, e, _), this.drawOrganicConsciousnessCore(t, _), this.drawFloatingTexts(n), l.flashAlpha > 0 && (this.ctx.fillStyle = `rgba(255, 255, 255, ${l.flashAlpha})`, this.ctx.fillRect(0, 0, m, u)), this.ctx.restore();
2608
2699
  }
2609
2700
  drawExperienceOrbs(t, e, i, s) {
2610
2701
  if (this.ctx)
2611
2702
  for (const a of t) {
2612
2703
  if (!a.active) continue;
2613
- const l = a.radius + Math.sin(i * 7 + a.position.x * 0.01) * 0.8, { x: n, y: o } = a.position;
2614
- this.ctx.save(), this.ctx.shadowColor = s.corePrimary, this.ctx.shadowBlur = a.isAbsorbing ? 18 : 10, a.isAbsorbing && (this.ctx.globalAlpha = 0.35, this.ctx.strokeStyle = s.tendrilCyan, this.ctx.lineWidth = 1, this.ctx.setLineDash([4, 7]), this.ctx.beginPath(), this.ctx.moveTo(n, o), this.ctx.lineTo(e.x, e.y), this.ctx.stroke(), this.ctx.setLineDash([]), this.ctx.globalAlpha = 1);
2615
- const r = this.ctx.createRadialGradient(n - 1, o - 1, 1, n, o, l * 1.6);
2616
- r.addColorStop(0, s.effectHighlight), r.addColorStop(0.4, s.corePrimary), r.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = r, this.ctx.beginPath(), this.ctx.arc(n, o, l * 1.6, 0, Math.PI * 2), this.ctx.fill(), this.ctx.fillStyle = s.effectHighlight, this.ctx.beginPath(), this.ctx.arc(n, o, l * 0.65, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = s.tendrilCyan, this.ctx.lineWidth = 1, this.ctx.beginPath(), this.ctx.arc(n, o, l + 3, -i * 2, -i * 2 + Math.PI * 1.4), this.ctx.stroke(), this.ctx.restore();
2704
+ const r = a.radius + Math.sin(i * 7 + a.position.x * 0.01) * 0.8, { x: o, y: n } = a.position;
2705
+ this.ctx.save(), this.ctx.shadowColor = s.corePrimary, this.ctx.shadowBlur = a.isAbsorbing ? 18 : 10, a.isAbsorbing && (this.ctx.globalAlpha = 0.35, this.ctx.strokeStyle = s.tendrilCyan, this.ctx.lineWidth = 1, this.ctx.setLineDash([4, 7]), this.ctx.beginPath(), this.ctx.moveTo(o, n), this.ctx.lineTo(e.x, e.y), this.ctx.stroke(), this.ctx.setLineDash([]), this.ctx.globalAlpha = 1);
2706
+ const l = this.ctx.createRadialGradient(o - 1, n - 1, 1, o, n, r * 1.6);
2707
+ l.addColorStop(0, s.effectHighlight), l.addColorStop(0.4, s.corePrimary), l.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = l, this.ctx.beginPath(), this.ctx.arc(o, n, r * 1.6, 0, Math.PI * 2), this.ctx.fill(), this.ctx.fillStyle = s.effectHighlight, this.ctx.beginPath(), this.ctx.arc(o, n, r * 0.65, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = s.tendrilCyan, this.ctx.lineWidth = 1, this.ctx.beginPath(), this.ctx.arc(o, n, r + 3, -i * 2, -i * 2 + Math.PI * 1.4), this.ctx.stroke(), this.ctx.restore();
2617
2708
  }
2618
2709
  }
2619
2710
  drawToxicPools(t, e) {
2620
- if (this.ctx)
2621
- for (const i of t) {
2622
- const s = i.duration / i.maxDuration, a = Math.min(0.7, (1 - s) * 0.7), { x: l, y: n } = i.position;
2623
- this.ctx.save();
2624
- const o = this.ctx.createRadialGradient(l, n, 10, l, n, i.radius * 1.2);
2625
- 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
- const r = 70;
2627
- 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);
2630
- }
2631
- 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
- 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);
2635
- }
2636
- this.ctx.closePath(), this.ctx.stroke();
2637
- 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();
2640
- }
2641
- this.ctx.restore();
2711
+ if (!this.ctx) return;
2712
+ const i = this.themeManager.getPalette();
2713
+ for (const s of t) {
2714
+ const a = s.duration / s.maxDuration, r = Math.min(0.7, (1 - a) * 0.7), { x: o, y: n } = s.position;
2715
+ this.ctx.save();
2716
+ const l = this.ctx.createRadialGradient(o, n, 10, o, n, s.radius * 1.2);
2717
+ l.addColorStop(0, this.colorWithAlpha(i.sporeColor, r * 0.9)), l.addColorStop(0.4, `rgba(16, 185, 129, ${r * 0.65})`), l.addColorStop(0.8, `rgba(5, 80, 45, ${r * 0.35})`), l.addColorStop(1, "rgba(2, 35, 15, 0)"), this.ctx.fillStyle = l, this.ctx.shadowColor = i.sporeColor, this.ctx.shadowBlur = 30, this.ctx.beginPath();
2718
+ const h = 70;
2719
+ for (let c = 0; c <= h; c++) {
2720
+ const p = c * Math.PI * 2 / h, g = Math.sin(p * 5 + e * 3) * 14, _ = Math.cos(p * 3 - e * 2) * 9, m = s.radius + g + _, u = o + Math.cos(p) * m, d = n + Math.sin(p) * m;
2721
+ c === 0 ? this.ctx.moveTo(u, d) : this.ctx.lineTo(u, d);
2722
+ }
2723
+ this.ctx.closePath(), this.ctx.fill(), this.ctx.strokeStyle = this.colorWithAlpha(i.sporeColor, r * 0.8), this.ctx.lineWidth = 2.5, this.ctx.beginPath();
2724
+ for (let c = 0; c <= h; c++) {
2725
+ const p = c * Math.PI * 2 / h, g = Math.sin(p * 6 + e * 4) * 8, _ = s.radius * 0.75 + g, m = o + Math.cos(p) * _, u = n + Math.sin(p) * _;
2726
+ c === 0 ? this.ctx.moveTo(m, u) : this.ctx.lineTo(m, u);
2642
2727
  }
2728
+ this.ctx.closePath(), this.ctx.stroke();
2729
+ for (let c = 0; c < 6; c++) {
2730
+ const p = c * Math.PI * 0.33 + e * 1.5, g = s.radius * 0.5 * (0.3 + Math.sin(e * 2 + c) * 0.3), _ = o + Math.cos(p) * g, m = n + Math.sin(p) * g, u = 3 + Math.sin(e * 3 + c) * 2;
2731
+ this.ctx.fillStyle = `rgba(255, 255, 255, ${r * 0.8})`, this.ctx.beginPath(), this.ctx.arc(_, m, Math.max(1, u), 0, Math.PI * 2), this.ctx.fill();
2732
+ }
2733
+ this.ctx.restore();
2734
+ }
2643
2735
  }
2644
2736
  drawShockwaves(t) {
2645
2737
  if (!this.ctx) return;
@@ -2663,13 +2755,13 @@ class gt {
2663
2755
  if (!this.ctx) return;
2664
2756
  const i = this.themeManager.getPalette();
2665
2757
  for (const s of t) {
2666
- const a = Math.min(0.85, (1 - s.duration / s.maxDuration) * 0.85), l = s.radius * (1 - s.duration / s.maxDuration * 0.1), { x: n, y: o } = s.position;
2758
+ const a = Math.min(0.85, (1 - s.duration / s.maxDuration) * 0.85), r = s.radius * (1 - s.duration / s.maxDuration * 0.1), { x: o, y: n } = s.position;
2667
2759
  this.ctx.save();
2668
- const r = this.ctx.createRadialGradient(n, o, 0, n, o, 60);
2669
- 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
- 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();
2760
+ const l = this.ctx.createRadialGradient(o, n, 0, o, n, 60);
2761
+ l.addColorStop(0, this.colorWithAlpha(i.vortexCore, a)), l.addColorStop(0.7, this.colorWithAlpha(i.vortexMid, a)), l.addColorStop(1, this.colorWithAlpha(i.parasiteColor, a * 0.5)), this.ctx.fillStyle = l, this.ctx.beginPath(), this.ctx.arc(o, n, 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;
2762
+ for (let h = 1; h <= 5; h++) {
2763
+ const c = r * h / 5, p = e * h * 2.2;
2764
+ this.ctx.beginPath(), this.ctx.arc(o, n, c, p, p + Math.PI * 1.5), this.ctx.stroke();
2673
2765
  }
2674
2766
  this.ctx.restore();
2675
2767
  }
@@ -2678,10 +2770,10 @@ class gt {
2678
2770
  if (!this.ctx) return;
2679
2771
  const a = this.ctx.createRadialGradient(t / 2, e / 2, 40, t / 2, e / 2, Math.max(t, e));
2680
2772
  a.addColorStop(0, s.bgInner), a.addColorStop(0.5, s.bgMid), a.addColorStop(1, s.bgOuter), this.ctx.fillStyle = a, this.ctx.fillRect(0, 0, t, e);
2681
- const l = t * 0.35 + Math.sin(i * 0.3) * 60, n = e * 0.45 + Math.cos(i * 0.25) * 50, o = this.ctx.createRadialGradient(l, n, 20, l, n, 380);
2682
- o.addColorStop(0, s.nebulaCyan), o.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = o, this.ctx.beginPath(), this.ctx.arc(l, n, 380, 0, Math.PI * 2), this.ctx.fill();
2683
- const r = t * 0.68 + Math.cos(i * 0.35) * 50, c = e * 0.55 + Math.sin(i * 0.3) * 45, h = this.ctx.createRadialGradient(r, c, 20, r, c, 420);
2684
- h.addColorStop(0, s.nebulaMagenta), h.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = h, this.ctx.beginPath(), this.ctx.arc(r, c, 420, 0, Math.PI * 2), this.ctx.fill();
2773
+ const r = t * 0.35 + Math.sin(i * 0.3) * 60, o = e * 0.45 + Math.cos(i * 0.25) * 50, n = this.ctx.createRadialGradient(r, o, 20, r, o, 380);
2774
+ n.addColorStop(0, s.nebulaCyan), n.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = n, this.ctx.beginPath(), this.ctx.arc(r, o, 380, 0, Math.PI * 2), this.ctx.fill();
2775
+ const l = t * 0.68 + Math.cos(i * 0.35) * 50, h = e * 0.55 + Math.sin(i * 0.3) * 45, c = this.ctx.createRadialGradient(l, h, 20, l, h, 420);
2776
+ c.addColorStop(0, s.nebulaMagenta), c.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = c, this.ctx.beginPath(), this.ctx.arc(l, h, 420, 0, Math.PI * 2), this.ctx.fill();
2685
2777
  }
2686
2778
  drawCoreFilaments(t, e) {
2687
2779
  if (!this.ctx) return;
@@ -2690,54 +2782,54 @@ class gt {
2690
2782
  for (let s = 0; s < i; s++) {
2691
2783
  const a = t.collectedPowerUpColors[s] || e.nebulaCyan;
2692
2784
  this.ctx.strokeStyle = a;
2693
- const l = s * Math.PI * 2 / i + t.pulsePhase * 0.12, n = 85 + Math.sin(t.pulsePhase * 1.5 + s) * 25, o = t.position.x + Math.cos(l) * n, r = t.position.y + Math.sin(l) * n, c = t.position.x + Math.cos(l + 0.4) * 48, h = t.position.y + Math.sin(l + 0.4) * 48;
2694
- this.ctx.beginPath(), this.ctx.moveTo(t.position.x, t.position.y), this.ctx.quadraticCurveTo(c, h, o, r), this.ctx.stroke(), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(o, r, 3.5, 0, Math.PI * 2), this.ctx.fill();
2785
+ const r = s * Math.PI * 2 / i + t.pulsePhase * 0.12, o = 85 + Math.sin(t.pulsePhase * 1.5 + s) * 25, n = t.position.x + Math.cos(r) * o, l = t.position.y + Math.sin(r) * o, h = t.position.x + Math.cos(r + 0.4) * 48, c = t.position.y + Math.sin(r + 0.4) * 48;
2786
+ this.ctx.beginPath(), this.ctx.moveTo(t.position.x, t.position.y), this.ctx.quadraticCurveTo(h, c, n, l), this.ctx.stroke(), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(n, l, 3.5, 0, Math.PI * 2), this.ctx.fill();
2695
2787
  }
2696
2788
  }
2697
2789
  drawOrganicConsciousnessCore(t, e) {
2698
2790
  if (!this.ctx) return;
2699
2791
  const { x: i, y: s } = t.position;
2700
2792
  if (this.ctx.save(), t.invulnerabilityTimer > 0) {
2701
- const r = Math.floor(t.invulnerabilityTimer * 20) % 2 === 0;
2702
- this.ctx.globalAlpha = r ? 0.3 : 0.9;
2793
+ const l = Math.floor(t.invulnerabilityTimer * 20) % 2 === 0;
2794
+ this.ctx.globalAlpha = l ? 0.3 : 0.9;
2703
2795
  }
2704
2796
  const a = t.getColorHex();
2705
- for (let r = 0; r < t.integrity; r++) {
2706
- const c = t.radius + 16 + r * 12;
2797
+ for (let l = 0; l < t.integrity; l++) {
2798
+ const h = t.radius + 16 + l * 12;
2707
2799
  this.ctx.strokeStyle = a, this.ctx.lineWidth = 2.2, this.ctx.shadowColor = a, this.ctx.shadowBlur = 12, this.ctx.beginPath();
2708
- 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);
2800
+ const c = 60;
2801
+ for (let p = 0; p <= c; p++) {
2802
+ const g = p * Math.PI * 2 / c, _ = h + Math.sin(g * 4 + t.pulsePhase * 2 + l) * 3, m = i + Math.cos(g) * _, u = s + Math.sin(g) * _;
2803
+ p === 0 ? this.ctx.moveTo(m, u) : this.ctx.lineTo(m, u);
2712
2804
  }
2713
2805
  this.ctx.closePath(), this.ctx.stroke();
2714
2806
  }
2715
2807
  if (t.repairProgress > 0) {
2716
- const r = t.integrity, c = t.radius + 16 + r * 12;
2808
+ const l = t.integrity, h = t.radius + 16 + l * 12;
2717
2809
  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
- 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);
2810
+ const c = 60;
2811
+ for (let p = 0; p <= c; p++) {
2812
+ const g = p * Math.PI * 2 / c, _ = h + Math.sin(g * 4 + t.pulsePhase * 2 + l) * 3, m = i + Math.cos(g) * _, u = s + Math.sin(g) * _;
2813
+ p === 0 ? this.ctx.moveTo(m, u) : this.ctx.lineTo(m, u);
2722
2814
  }
2723
2815
  this.ctx.closePath(), this.ctx.stroke(), this.ctx.restore();
2724
2816
  }
2725
- const l = this.ctx.createRadialGradient(i, s, 5, i, s, t.radius * 2.2);
2726
- 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
- const n = 80;
2728
- 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);
2817
+ const r = this.ctx.createRadialGradient(i, s, 5, i, s, t.radius * 2.2);
2818
+ r.addColorStop(0, a), r.addColorStop(0.5, e.nebulaMagenta), r.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = r, 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();
2819
+ const o = 80;
2820
+ for (let l = 0; l <= o; l++) {
2821
+ const h = l * Math.PI * 2 / o, c = t.getMembraneRadius(h), p = Math.cos(h) * c, g = Math.sin(h) * c;
2822
+ l === 0 ? this.ctx.moveTo(p, g) : this.ctx.lineTo(p, g);
2731
2823
  }
2732
2824
  this.ctx.closePath(), this.ctx.fill(), this.ctx.stroke();
2733
- const o = t.powerUpCount;
2734
- if (o > 0) {
2825
+ const n = t.powerUpCount;
2826
+ if (n > 0) {
2735
2827
  this.ctx.strokeStyle = e.effectHighlight, this.ctx.lineWidth = 1.8, this.ctx.shadowColor = a, this.ctx.shadowBlur = 10;
2736
- for (let r = 0; r < o; r++) {
2737
- const c = r * Math.PI * 2 / o + t.pulsePhase * 0.4, h = t.radius * (0.45 + Math.sin(t.pulsePhase * 2 + r) * 0.15);
2828
+ for (let l = 0; l < n; l++) {
2829
+ const h = l * Math.PI * 2 / n + t.pulsePhase * 0.4, c = t.radius * (0.45 + Math.sin(t.pulsePhase * 2 + l) * 0.15);
2738
2830
  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();
2831
+ const p = Math.cos(h + Math.sin(t.pulsePhase + l) * 0.4) * (c * 0.6), g = Math.sin(h + Math.cos(t.pulsePhase + l) * 0.4) * (c * 0.6), _ = Math.cos(h) * c, m = Math.sin(h) * c;
2832
+ this.ctx.quadraticCurveTo(p, g, _, 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
2833
  }
2742
2834
  }
2743
2835
  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();
@@ -2747,11 +2839,11 @@ class gt {
2747
2839
  this.ctx.save();
2748
2840
  const s = e.x - t.x, a = e.y - t.y;
2749
2841
  this.ctx.strokeStyle = i.tendrilMagenta, this.ctx.lineWidth = 9, this.ctx.shadowColor = i.tendrilMagenta, this.ctx.shadowBlur = 20, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y);
2750
- const l = (t.x + e.x) / 2 + Math.sin(Date.now() * 0.02) * 16, n = (t.y + e.y) / 2 + Math.cos(Date.now() * 0.02) * 16;
2751
- this.ctx.quadraticCurveTo(l, n, e.x, e.y), this.ctx.stroke(), this.ctx.strokeStyle = i.tendrilCyan, this.ctx.lineWidth = 3.5, this.ctx.shadowColor = i.tendrilCyan, this.ctx.shadowBlur = 12, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y), this.ctx.lineTo(e.x, e.y), this.ctx.stroke();
2752
- for (let o = 0; o < 6; o++) {
2753
- const r = Math.random(), c = t.x + s * r + (Math.random() - 0.5) * 24, h = t.y + a * r + (Math.random() - 0.5) * 24;
2754
- this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(c, h, 2.5 + Math.random() * 2.5, 0, Math.PI * 2), this.ctx.fill();
2842
+ const r = (t.x + e.x) / 2 + Math.sin(Date.now() * 0.02) * 16, o = (t.y + e.y) / 2 + Math.cos(Date.now() * 0.02) * 16;
2843
+ this.ctx.quadraticCurveTo(r, o, e.x, e.y), this.ctx.stroke(), this.ctx.strokeStyle = i.tendrilCyan, this.ctx.lineWidth = 3.5, this.ctx.shadowColor = i.tendrilCyan, this.ctx.shadowBlur = 12, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y), this.ctx.lineTo(e.x, e.y), this.ctx.stroke();
2844
+ for (let n = 0; n < 6; n++) {
2845
+ const l = Math.random(), h = t.x + s * l + (Math.random() - 0.5) * 24, c = t.y + a * l + (Math.random() - 0.5) * 24;
2846
+ this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(h, c, 2.5 + Math.random() * 2.5, 0, Math.PI * 2), this.ctx.fill();
2755
2847
  }
2756
2848
  this.ctx.restore();
2757
2849
  }
@@ -2759,8 +2851,8 @@ class gt {
2759
2851
  if (this.ctx)
2760
2852
  for (const a of i) {
2761
2853
  if (!a.active || a.isGrabbed || a.isThrown || a.wasManipulated || a.isDying) continue;
2762
- const l = e.x - a.position.x, n = e.y - a.position.y;
2763
- if (Math.hypot(l, n) <= a.getHitRadius()) {
2854
+ const r = e.x - a.position.x, o = e.y - a.position.y;
2855
+ if (Math.hypot(r, o) <= a.getHitRadius()) {
2764
2856
  this.ctx.strokeStyle = s.tendrilMagenta, this.ctx.lineWidth = 2.5, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y), this.ctx.lineTo(a.position.x, a.position.y), this.ctx.stroke();
2765
2857
  break;
2766
2858
  }
@@ -2772,71 +2864,31 @@ class gt {
2772
2864
  if (!s.active) continue;
2773
2865
  let a = s.color;
2774
2866
  s.type === "piercer" ? a = i.piercerColor : s.type === "spore" ? a = i.sporeColor : s.type === "cluster" ? a = i.clusterColor : s.type === "parasite" ? a = i.parasiteColor : s.type === "micro" && (a = i.microColor);
2775
- const { x: l, y: n } = s.position;
2776
- if (this.ctx.save(), this.ctx.translate(l, n), s.wasManipulated && !s.isDying) {
2777
- const o = s.radius * 1.5 + Math.sin(e * 6) * 4;
2778
- this.ctx.strokeStyle = i.tendrilMagenta, this.ctx.lineWidth = 2.5, this.ctx.shadowColor = i.tendrilMagenta, this.ctx.shadowBlur = 18, this.ctx.beginPath(), this.ctx.arc(0, 0, o, 0, Math.PI * 2), this.ctx.stroke();
2779
- const r = s.radius * 1.8 + Math.cos(e * 8) * 3;
2780
- this.ctx.strokeStyle = i.tendrilCyan, this.ctx.lineWidth = 1.5, this.ctx.beginPath(), this.ctx.arc(0, 0, r, 0, Math.PI * 2), this.ctx.stroke();
2867
+ const { x: r, y: o } = s.position;
2868
+ if (this.ctx.save(), this.ctx.translate(r, o), s.wasManipulated && !s.isDying) {
2869
+ const n = s.radius * 1.5 + Math.sin(e * 6) * 4;
2870
+ this.ctx.strokeStyle = i.tendrilMagenta, this.ctx.lineWidth = 2.5, this.ctx.shadowColor = i.tendrilMagenta, this.ctx.shadowBlur = 18, this.ctx.beginPath(), this.ctx.arc(0, 0, n, 0, Math.PI * 2), this.ctx.stroke();
2871
+ const l = s.radius * 1.8 + Math.cos(e * 8) * 3;
2872
+ this.ctx.strokeStyle = i.tendrilCyan, this.ctx.lineWidth = 1.5, this.ctx.beginPath(), this.ctx.arc(0, 0, l, 0, Math.PI * 2), this.ctx.stroke();
2781
2873
  }
2782
2874
  if (s.isDying) {
2783
- const o = s.deathTimer / s.maxDeathTimer, r = Math.max(0, 1 - o);
2784
- if (this.ctx.globalAlpha = r, s.deathType === "dissolve") {
2785
- const c = s.radius * (1 - o * 0.7);
2786
- 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
- 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();
2875
+ const n = s.deathTimer / s.maxDeathTimer, l = Math.max(0, 1 - n);
2876
+ if (this.ctx.globalAlpha = l, s.deathType === "dissolve") {
2877
+ const h = s.radius * (1 - n * 0.7);
2878
+ this.ctx.fillStyle = i.sporeColor, this.ctx.shadowColor = i.sporeColor, this.ctx.shadowBlur = 20, this.ctx.beginPath(), this.ctx.arc(0, 0, h, 0, Math.PI * 2), this.ctx.fill();
2879
+ for (let c = 0; c < 4; c++) {
2880
+ const p = c * Math.PI * 0.5 + n * 4, g = h * 0.8 * n;
2881
+ this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(Math.cos(p) * g, Math.sin(p) * g, 3, 0, Math.PI * 2), this.ctx.fill();
2790
2882
  }
2791
2883
  this.ctx.restore();
2792
2884
  continue;
2793
2885
  } 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();
2886
+ const h = n * 24, c = s.sliceAngle + Math.PI / 2, p = Math.cos(c) * h, g = Math.sin(c) * h;
2887
+ this.ctx.shadowColor = i.piercerColor, this.ctx.shadowBlur = 22, this.ctx.fillStyle = a, this.ctx.save(), this.ctx.translate(p, g), 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, -g), 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
2888
  continue;
2797
2889
  }
2798
2890
  }
2799
- if (this.ctx.shadowColor = a, this.ctx.shadowBlur = 16, this.ctx.fillStyle = a, s.type === "piercer") {
2800
- this.ctx.rotate(s.rotation), this.ctx.beginPath();
2801
- const o = 12;
2802
- 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;
2804
- r === 0 ? this.ctx.moveTo(d, _) : this.ctx.lineTo(d, _);
2805
- }
2806
- 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();
2807
- } else if (s.type === "spore") {
2808
- this.ctx.beginPath();
2809
- const o = 8;
2810
- 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);
2813
- }
2814
- 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
- } else if (s.type === "cluster") {
2816
- this.ctx.beginPath();
2817
- const o = Math.sin(e * 3) * 2;
2818
- this.ctx.arc(0, 0, s.radius * 0.55, 0, Math.PI * 2), this.ctx.arc(-9 + o, -7, s.radius * 0.42, 0, Math.PI * 2), this.ctx.arc(9 - o, -7, s.radius * 0.42, 0, Math.PI * 2), this.ctx.arc(0, 9 + o, s.radius * 0.45, 0, Math.PI * 2), this.ctx.fill();
2819
- } else if (s.type === "parasite") {
2820
- this.ctx.beginPath();
2821
- const o = 14;
2822
- 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);
2825
- }
2826
- 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
- } else if (s.type === "heavy") {
2828
- this.ctx.rotate(s.rotation);
2829
- const o = E.getInstance().getConfig().shield.protectionArc, r = s.radius * 1.35, c = s.radius * 0.75;
2830
- 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();
2833
- 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();
2836
- }
2837
- } else
2838
- this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius, 0, Math.PI * 2), this.ctx.fill();
2839
- this.ctx.restore();
2891
+ this.enemyShapeRenderer.draw(this.ctx, s, e, i, a), this.ctx.restore();
2840
2892
  }
2841
2893
  }
2842
2894
  drawParticles(t) {
@@ -2854,34 +2906,34 @@ class gt {
2854
2906
  }
2855
2907
  drawOrbitingModifierOrbs(t, e, i, s = !0, a = 1) {
2856
2908
  if (!this.ctx) return;
2857
- const l = this.themeManager.getPalette(), n = this.themeManager.getTheme() === "light";
2858
- for (const o of t) {
2859
- 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();
2909
+ const r = this.themeManager.getPalette(), o = this.themeManager.getTheme() === "light";
2910
+ for (const n of t) {
2911
+ if (!n.active) continue;
2912
+ const { x: l, y: h } = n.position, c = n.definition.color, p = n.definition.rarity, g = ft[p], _ = n.radius + Math.sin(e * 6 + n.orbitAngle) * 3;
2913
+ if (this.ctx.save(), this.ctx.shadowColor = g, this.ctx.shadowBlur = n.isGrabbed ? 36 : p === "legendary" ? 28 : 16, p === "legendary" || p === "epic") {
2914
+ const d = _ + 12, x = this.ctx.createRadialGradient(l, h, _, l, h, d);
2915
+ x.addColorStop(0, g), x.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = x, this.ctx.beginPath(), this.ctx.arc(l, h, d, 0, Math.PI * 2), this.ctx.fill();
2864
2916
  }
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();
2917
+ const m = this.ctx.createRadialGradient(l, h, 2, l, h, _ * 1.4);
2918
+ m.addColorStop(0, r.effectHighlight), m.addColorStop(0.4, c), m.addColorStop(1, o ? "rgba(23, 50, 77, 0.24)" : "rgba(0, 0, 0, 0.5)"), this.ctx.fillStyle = m, this.ctx.beginPath(), this.ctx.arc(l, h, _, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = g, this.ctx.lineWidth = p === "legendary" ? 3.5 : 2.5, this.ctx.beginPath(), this.ctx.arc(l, h, _ + 4, e * 3, e * 3 + Math.PI * 1.2), this.ctx.stroke(), (p === "legendary" || p === "epic") && (this.ctx.strokeStyle = o ? g : r.effectHighlight, this.ctx.lineWidth = 1.5, this.ctx.beginPath(), this.ctx.arc(l, h, _ + 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 = r.effectInk, this.ctx.shadowColor = r.effectShadow, this.ctx.shadowBlur = 6, this.ctx.fillText(n.definition.badge, l, h);
2919
+ const u = i ? i.translate(n.definition.titleKey) : n.definition.badge;
2920
+ this.ctx.textBaseline = "alphabetic", this.ctx.font = "900 16px Orbitron, sans-serif", this.ctx.fillStyle = r.effectInk, this.ctx.shadowColor = g, this.ctx.shadowBlur = 14, this.ctx.fillText(u, l, h - _ - 14), this.ctx.restore();
2869
2921
  }
2870
2922
  if (i && s) {
2871
- const o = this.canvas.width / 2, r = this.canvas.height / 2 + 210, c = i.translate("rerollButton", { count: a });
2872
- this.ctx.save(), this.ctx.font = "900 14px Orbitron, sans-serif", this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.fillStyle = l.effectPanel, this.ctx.strokeStyle = l.tendrilCyan, this.ctx.lineWidth = 2, this.ctx.shadowColor = l.tendrilCyan, this.ctx.shadowBlur = 12;
2873
- const d = this.ctx.measureText(c).width + 20 * 2, _ = 38;
2874
- this.ctx.beginPath(), this.ctx.roundRect(o - d / 2, r - _ / 2, d, _, 8), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = l.effectInk, this.ctx.shadowColor = l.effectShadow, this.ctx.shadowBlur = 4, this.ctx.fillText(c, o, r), this.ctx.restore();
2923
+ const n = this.canvas.width / 2, l = this.canvas.height / 2 + 210, h = i.translate("rerollButton", { count: a });
2924
+ this.ctx.save(), this.ctx.font = "900 14px Orbitron, sans-serif", this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.fillStyle = r.effectPanel, this.ctx.strokeStyle = r.tendrilCyan, this.ctx.lineWidth = 2, this.ctx.shadowColor = r.tendrilCyan, this.ctx.shadowBlur = 12;
2925
+ const g = this.ctx.measureText(h).width + 20 * 2, _ = 38;
2926
+ this.ctx.beginPath(), this.ctx.roundRect(n - g / 2, l - _ / 2, g, _, 8), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = r.effectInk, this.ctx.shadowColor = r.effectShadow, this.ctx.shadowBlur = 4, this.ctx.fillText(h, n, l), this.ctx.restore();
2875
2927
  }
2876
2928
  }
2877
2929
  colorWithAlpha(t, e) {
2878
2930
  const i = t.replace("#", "");
2879
2931
  if (i.length !== 6) return t;
2880
- const s = Number.parseInt(i.slice(0, 2), 16), a = Number.parseInt(i.slice(2, 4), 16), l = Number.parseInt(i.slice(4, 6), 16);
2881
- return `rgba(${s}, ${a}, ${l}, ${e})`;
2932
+ const s = Number.parseInt(i.slice(0, 2), 16), a = Number.parseInt(i.slice(2, 4), 16), r = Number.parseInt(i.slice(4, 6), 16);
2933
+ return `rgba(${s}, ${a}, ${r}, ${e})`;
2882
2934
  }
2883
2935
  }
2884
- class _t {
2936
+ class yt {
2885
2937
  container;
2886
2938
  i18n;
2887
2939
  waveLabelElement;
@@ -2913,7 +2965,7 @@ class _t {
2913
2965
  this.container.style.display = "none";
2914
2966
  }
2915
2967
  }
2916
- class ft {
2968
+ class Et {
2917
2969
  container;
2918
2970
  i18n;
2919
2971
  onStartCallback;
@@ -2939,7 +2991,7 @@ class ft {
2939
2991
  this.container.style.display = "none";
2940
2992
  }
2941
2993
  }
2942
- class mt {
2994
+ class At {
2943
2995
  modal;
2944
2996
  card;
2945
2997
  i18n;
@@ -2948,10 +3000,14 @@ class mt {
2948
3000
  onLanguageChangedCallback;
2949
3001
  onCloseCallback;
2950
3002
  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;
3003
+ fpsLimit = 60;
3004
+ onFpsLimitChangedCallback;
3005
+ constructor(t, e, i, s, a, r, o) {
3006
+ this.i18n = e, this.themeManager = i, this.platform = s, this.onLanguageChangedCallback = a, this.onCloseCallback = r, this.onFpsLimitChangedCallback = o;
2953
3007
  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", () => {
3008
+ n !== null && (this.hapticsEnabled = n === "true");
3009
+ const l = Number(localStorage.getItem("axon_surge_fps_limit"));
3010
+ (l === 30 || l === 60 || l === 120) && (this.fpsLimit = l), 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
3011
  this.onCloseCallback && this.onCloseCallback();
2956
3012
  }), this.renderContent();
2957
3013
  }
@@ -2967,7 +3023,7 @@ class mt {
2967
3023
  s.className = "axon-select-wrapper";
2968
3024
  const a = document.createElement("select");
2969
3025
  a.className = "axon-select";
2970
- const l = {
3026
+ const r = {
2971
3027
  es: "ESPAÑOL (ES)",
2972
3028
  en: "ENGLISH (EN)",
2973
3029
  fr: "FRANÇAIS (FR)",
@@ -2984,78 +3040,99 @@ class mt {
2984
3040
  ko: "한국어 (KO)",
2985
3041
  zh: "中文 (ZH)"
2986
3042
  };
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);
3043
+ for (const S of W) {
3044
+ const M = document.createElement("option");
3045
+ M.value = S, M.textContent = r[S], this.i18n.getLanguage() === S && (M.selected = !0), a.appendChild(M);
2990
3046
  }
2991
3047
  a.addEventListener("change", () => {
2992
- const v = a.value;
2993
- this.i18n.setLanguage(v), this.onLanguageChangedCallback && this.onLanguageChangedCallback(v), this.renderContent();
3048
+ const S = a.value;
3049
+ this.i18n.setLanguage(S), this.onLanguageChangedCallback && this.onLanguageChangedCallback(S), this.renderContent();
2994
3050
  });
2995
- const n = document.createElement("span");
2996
- n.className = "axon-select-arrow", n.textContent = "▼", s.appendChild(a), s.appendChild(n), e.appendChild(i), e.appendChild(s);
2997
- const o = document.createElement("div");
2998
- o.className = "axon-setting-row";
2999
- const r = document.createElement("span");
3000
- r.textContent = this.i18n.translate("themeLabel");
3001
- const c = document.createElement("div");
3002
- c.className = "axon-toggle-group";
3003
- const h = [
3051
+ const o = document.createElement("span");
3052
+ o.className = "axon-select-arrow", o.textContent = "▼", s.appendChild(a), s.appendChild(o), e.appendChild(i), e.appendChild(s);
3053
+ const n = document.createElement("div");
3054
+ n.className = "axon-setting-row";
3055
+ const l = document.createElement("span");
3056
+ l.textContent = this.i18n.translate("themeLabel");
3057
+ const h = document.createElement("div");
3058
+ h.className = "axon-toggle-group";
3059
+ const c = [
3004
3060
  { id: "bioluminescent", label: "BIO" },
3005
3061
  { id: "dark", label: "DARK" },
3006
3062
  { id: "light", label: "LIGHT" }
3007
3063
  ];
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);
3064
+ for (const S of c) {
3065
+ const M = document.createElement("button");
3066
+ M.type = "button", M.className = `axon-toggle-btn ${this.themeManager.getTheme() === S.id ? "active" : ""}`, M.textContent = S.label, M.addEventListener("click", () => {
3067
+ this.themeManager.setTheme(S.id), this.renderContent();
3068
+ }), h.appendChild(M);
3013
3069
  }
3014
- o.appendChild(r), o.appendChild(c);
3070
+ n.appendChild(l), n.appendChild(h);
3071
+ const p = document.createElement("div");
3072
+ p.className = "axon-setting-row";
3073
+ const g = document.createElement("span");
3074
+ g.textContent = this.i18n.translate("fpsLimitLabel");
3075
+ const _ = document.createElement("div");
3076
+ _.className = "axon-toggle-group";
3077
+ const m = [
3078
+ { limit: 30, label: "30 FPS" },
3079
+ { limit: 60, label: "60 FPS" },
3080
+ { limit: 120, label: "120 FPS" }
3081
+ ];
3082
+ for (const S of m) {
3083
+ const M = document.createElement("button");
3084
+ M.type = "button", M.className = `axon-toggle-btn ${this.fpsLimit === S.limit ? "active" : ""}`, M.textContent = S.label, M.addEventListener("click", () => {
3085
+ this.fpsLimit = S.limit, localStorage.setItem("axon_surge_fps_limit", String(S.limit)), this.onFpsLimitChangedCallback?.(S.limit), this.renderContent();
3086
+ }), _.appendChild(M);
3087
+ }
3088
+ p.appendChild(g), p.appendChild(_);
3015
3089
  const u = document.createElement("div");
3016
3090
  u.className = "axon-setting-row";
3017
3091
  const d = document.createElement("span");
3018
3092
  d.textContent = this.i18n.translate("hapticsLabel");
3019
- const _ = document.createElement("div");
3020
- _.className = "axon-toggle-group";
3021
- const f = [
3093
+ const x = document.createElement("div");
3094
+ x.className = "axon-toggle-group";
3095
+ const y = [
3022
3096
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
3023
3097
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
3024
3098
  ];
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);
3099
+ for (const S of y) {
3100
+ const M = document.createElement("button");
3101
+ M.type = "button", M.className = `axon-toggle-btn ${this.hapticsEnabled === S.enabled ? "active" : ""}`, M.textContent = S.label, M.addEventListener("click", () => {
3102
+ this.hapticsEnabled = S.enabled, localStorage.setItem("axon_surge_haptics", String(S.enabled)), this.hapticsEnabled && this.platform.haptics.selectionChanged(), this.renderContent();
3103
+ }), x.appendChild(M);
3030
3104
  }
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 = [
3105
+ u.appendChild(d), u.appendChild(x);
3106
+ const E = document.createElement("div");
3107
+ E.className = "axon-setting-row";
3108
+ const I = document.createElement("span");
3109
+ I.textContent = this.i18n.translate("tutorialSettingLabel");
3110
+ const T = document.createElement("div");
3111
+ T.className = "axon-toggle-group";
3112
+ const L = localStorage.getItem("axon_surge_show_tutorial") !== "false", A = [
3039
3113
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
3040
3114
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
3041
3115
  ];
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", () => {
3116
+ for (const S of A) {
3117
+ const M = document.createElement("button");
3118
+ M.type = "button", M.className = `axon-toggle-btn ${L === S.enabled ? "active" : ""}`, M.textContent = S.label, M.addEventListener("click", () => {
3119
+ localStorage.setItem("axon_surge_show_tutorial", String(S.enabled)), this.renderContent();
3120
+ }), T.appendChild(M);
3121
+ }
3122
+ E.appendChild(I), E.appendChild(T);
3123
+ const R = document.createElement("div");
3124
+ R.className = "axon-settings-credits", R.textContent = this.i18n.translate("creditsJam");
3125
+ const C = document.createElement("button");
3126
+ C.type = "button", C.className = "axon-start-button", C.style.padding = "12px 36px", C.style.fontSize = "14px", C.textContent = this.i18n.translate("closeButton"), C.addEventListener("click", () => {
3053
3127
  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);
3128
+ }), this.card.appendChild(t), this.card.appendChild(e), this.card.appendChild(n), this.card.appendChild(p), this.card.appendChild(u), this.card.appendChild(E), this.card.appendChild(R), this.card.appendChild(C);
3055
3129
  }
3056
3130
  isHapticsEnabled() {
3057
3131
  return this.hapticsEnabled;
3058
3132
  }
3133
+ getFpsLimit() {
3134
+ return this.fpsLimit;
3135
+ }
3059
3136
  show() {
3060
3137
  this.renderContent(), this.modal.showModal();
3061
3138
  }
@@ -3063,8 +3140,8 @@ class mt {
3063
3140
  this.modal.close();
3064
3141
  }
3065
3142
  }
3066
- const B = "axon_surge_show_tutorial";
3067
- class xt {
3143
+ const F = "axon_surge_show_tutorial";
3144
+ class bt {
3068
3145
  isActive = !1;
3069
3146
  showWarning = !1;
3070
3147
  dummyLauncher = null;
@@ -3073,14 +3150,14 @@ class xt {
3073
3150
  initialTargetPos = { x: 0, y: 0 };
3074
3151
  isTutorialEnabled() {
3075
3152
  try {
3076
- return localStorage.getItem(B) !== "false";
3153
+ return localStorage.getItem(F) !== "false";
3077
3154
  } catch {
3078
3155
  return !0;
3079
3156
  }
3080
3157
  }
3081
3158
  setTutorialEnabled(t) {
3082
3159
  try {
3083
- localStorage.setItem(B, String(t));
3160
+ localStorage.setItem(F, String(t));
3084
3161
  } catch {
3085
3162
  }
3086
3163
  }
@@ -3098,39 +3175,39 @@ class xt {
3098
3175
  this.isActive = !1;
3099
3176
  return;
3100
3177
  }
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(
3178
+ 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 = P.createEnemy(
3102
3179
  "piercer",
3103
3180
  this.initialLauncherPos,
3104
3181
  this.initialTargetPos
3105
- ), this.dummyLauncher.velocity = { x: 0, y: 0 }, this.dummyTarget = M.createEnemy(
3182
+ ), this.dummyLauncher.velocity = { x: 0, y: 0 }, this.dummyTarget = P.createEnemy(
3106
3183
  "spore",
3107
3184
  this.initialTargetPos,
3108
3185
  this.initialLauncherPos
3109
3186
  ), this.dummyTarget.velocity = { x: 0, y: 0 }, i.push(this.dummyLauncher), i.push(this.dummyTarget);
3110
3187
  }
3111
- update(t, e, i, s, a, l) {
3188
+ update(t, e, i, s, a, r) {
3112
3189
  if (!this.isActive || !this.dummyLauncher || !this.dummyTarget) return;
3113
- const n = this.dummyLauncher, o = this.dummyTarget;
3114
- e.includes(n) || e.push(n), e.includes(o) || e.push(o);
3115
- const r = o.position.x - n.position.x, c = o.position.y - n.position.y, h = Math.hypot(r, c);
3116
- if (n.isGrabbed) {
3117
- if (this.showWarning = !1, h <= n.radius + o.radius + 60) {
3118
- l && l(), n.isGrabbed = !1, this.showWarning = !0, this.resetDummies(n, o);
3190
+ const o = this.dummyLauncher, n = this.dummyTarget;
3191
+ e.includes(o) || e.push(o), e.includes(n) || e.push(n);
3192
+ const l = n.position.x - o.position.x, h = n.position.y - o.position.y, c = Math.hypot(l, h);
3193
+ if (o.isGrabbed) {
3194
+ if (this.showWarning = !1, c <= o.radius + n.radius + 60) {
3195
+ r && r(), o.isGrabbed = !1, this.showWarning = !0, this.resetDummies(o, n);
3119
3196
  return;
3120
3197
  }
3121
3198
  return;
3122
3199
  }
3123
- if (n.wasManipulated) {
3124
- const u = Math.hypot(n.velocity.x, n.velocity.y);
3125
- if (!n.isThrown || u < 70) {
3126
- l && l(), this.showWarning = !0, this.resetDummies(n, o);
3200
+ if (o.wasManipulated) {
3201
+ const p = Math.hypot(o.velocity.x, o.velocity.y);
3202
+ if (!o.isThrown || p < 70) {
3203
+ r && r(), this.showWarning = !0, this.resetDummies(o, n);
3127
3204
  return;
3128
3205
  }
3129
- if (h <= n.getHitRadius() + o.getHitRadius()) {
3130
- n.triggerDissolveDeath(!0), o.triggerDissolveDeath(!0), this.showWarning = !1, this.isActive = !1, a();
3206
+ if (c <= o.getHitRadius() + n.getHitRadius()) {
3207
+ o.triggerDissolveDeath(!0), n.triggerDissolveDeath(!0), this.showWarning = !1, this.isActive = !1, a();
3131
3208
  return;
3132
3209
  }
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));
3210
+ (o.position.x < -60 || o.position.x > i + 60 || o.position.y < -60 || o.position.y > s + 60 || p < 40) && (r && r(), this.showWarning = !0, this.resetDummies(o, n));
3134
3211
  }
3135
3212
  }
3136
3213
  resetDummies(t, e) {
@@ -3140,7 +3217,7 @@ class xt {
3140
3217
  this.isActive = !1, this.showWarning = !1;
3141
3218
  }
3142
3219
  }
3143
- class yt {
3220
+ class vt {
3144
3221
  container;
3145
3222
  i18n;
3146
3223
  tutorialManager;
@@ -3176,7 +3253,7 @@ class yt {
3176
3253
  this.container.style.display = "none";
3177
3254
  }
3178
3255
  }
3179
- class Et {
3256
+ class It {
3180
3257
  fillElement;
3181
3258
  experienceCount = 0;
3182
3259
  currentLevel = 1;
@@ -3213,7 +3290,7 @@ class Et {
3213
3290
  this.fillElement && this.fillElement.parentElement && (this.fillElement.parentElement.style.display = "none");
3214
3291
  }
3215
3292
  }
3216
- class K {
3293
+ class V {
3217
3294
  static powerUps = [
3218
3295
  {
3219
3296
  id: "spore_radius",
@@ -3223,9 +3300,9 @@ class K {
3223
3300
  category: "radius",
3224
3301
  rarity: "common",
3225
3302
  rarityWeight: 35,
3226
- color: "#39ff14",
3303
+ color: f.spore,
3227
3304
  apply: () => {
3228
- const t = E.getInstance(), e = t.getConfig().toxicPool;
3305
+ const t = v.getInstance(), e = t.getConfig().toxicPool;
3229
3306
  t.updateConfig({
3230
3307
  toxicPool: {
3231
3308
  ...e,
@@ -3243,9 +3320,9 @@ class K {
3243
3320
  category: "duration",
3244
3321
  rarity: "common",
3245
3322
  rarityWeight: 35,
3246
- color: "#39ff14",
3323
+ color: f.spore,
3247
3324
  apply: () => {
3248
- const t = E.getInstance(), e = t.getConfig().toxicPool;
3325
+ const t = v.getInstance(), e = t.getConfig().toxicPool;
3249
3326
  t.updateConfig({
3250
3327
  toxicPool: {
3251
3328
  ...e,
@@ -3263,9 +3340,9 @@ class K {
3263
3340
  category: "radius",
3264
3341
  rarity: "common",
3265
3342
  rarityWeight: 35,
3266
- color: "#9d4edd",
3343
+ color: f.parasite,
3267
3344
  apply: () => {
3268
- const t = E.getInstance(), e = t.getConfig().gravityVortex;
3345
+ const t = v.getInstance(), e = t.getConfig().gravityVortex;
3269
3346
  t.updateConfig({
3270
3347
  gravityVortex: {
3271
3348
  ...e,
@@ -3283,9 +3360,9 @@ class K {
3283
3360
  category: "duration",
3284
3361
  rarity: "common",
3285
3362
  rarityWeight: 35,
3286
- color: "#9d4edd",
3363
+ color: f.parasite,
3287
3364
  apply: () => {
3288
- const t = E.getInstance(), e = t.getConfig().gravityVortex;
3365
+ const t = v.getInstance(), e = t.getConfig().gravityVortex;
3289
3366
  t.updateConfig({
3290
3367
  gravityVortex: {
3291
3368
  ...e,
@@ -3303,9 +3380,9 @@ class K {
3303
3380
  category: "power",
3304
3381
  rarity: "rare",
3305
3382
  rarityWeight: 25,
3306
- color: "#9d4edd",
3383
+ color: f.parasite,
3307
3384
  apply: () => {
3308
- const t = E.getInstance(), e = t.getConfig().gravityVortex;
3385
+ const t = v.getInstance(), e = t.getConfig().gravityVortex;
3309
3386
  t.updateConfig({
3310
3387
  gravityVortex: {
3311
3388
  ...e,
@@ -3323,9 +3400,9 @@ class K {
3323
3400
  category: "power",
3324
3401
  rarity: "legendary",
3325
3402
  rarityWeight: 5,
3326
- color: "#9d4edd",
3403
+ color: f.parasite,
3327
3404
  apply: () => {
3328
- const t = E.getInstance(), e = t.getConfig().gravityVortex;
3405
+ const t = v.getInstance(), e = t.getConfig().gravityVortex;
3329
3406
  t.updateConfig({
3330
3407
  gravityVortex: {
3331
3408
  ...e,
@@ -3342,9 +3419,9 @@ class K {
3342
3419
  category: "power",
3343
3420
  rarity: "legendary",
3344
3421
  rarityWeight: 5,
3345
- color: "#00f5ff",
3422
+ color: f.heavy,
3346
3423
  apply: () => {
3347
- const t = E.getInstance(), e = t.getConfig().shield;
3424
+ const t = v.getInstance(), e = t.getConfig().shield;
3348
3425
  t.updateConfig({
3349
3426
  shield: {
3350
3427
  ...e,
@@ -3361,9 +3438,9 @@ class K {
3361
3438
  category: "power",
3362
3439
  rarity: "epic",
3363
3440
  rarityWeight: 15,
3364
- color: "#00f5ff",
3441
+ color: f.heavy,
3365
3442
  apply: () => {
3366
- const t = E.getInstance(), e = t.getConfig().shield;
3443
+ const t = v.getInstance(), e = t.getConfig().shield;
3367
3444
  t.updateConfig({
3368
3445
  shield: {
3369
3446
  ...e,
@@ -3382,9 +3459,9 @@ class K {
3382
3459
  category: "defense",
3383
3460
  rarity: "common",
3384
3461
  rarityWeight: 35,
3385
- color: "#00f5ff",
3462
+ color: f.heavy,
3386
3463
  apply: () => {
3387
- const t = E.getInstance(), e = t.getConfig().shield;
3464
+ const t = v.getInstance(), e = t.getConfig().shield;
3388
3465
  t.updateConfig({
3389
3466
  shield: {
3390
3467
  ...e,
@@ -3401,9 +3478,9 @@ class K {
3401
3478
  category: "power",
3402
3479
  rarity: "rare",
3403
3480
  rarityWeight: 25,
3404
- color: "#ffcc00",
3481
+ color: f.cluster,
3405
3482
  apply: () => {
3406
- const t = E.getInstance(), e = t.getConfig().cluster;
3483
+ const t = v.getInstance(), e = t.getConfig().cluster;
3407
3484
  t.updateConfig({
3408
3485
  cluster: {
3409
3486
  ...e,
@@ -3420,9 +3497,9 @@ class K {
3420
3497
  category: "power",
3421
3498
  rarity: "legendary",
3422
3499
  rarityWeight: 5,
3423
- color: "#ffcc00",
3500
+ color: f.cluster,
3424
3501
  apply: () => {
3425
- const t = E.getInstance(), e = t.getConfig().cluster;
3502
+ const t = v.getInstance(), e = t.getConfig().cluster;
3426
3503
  t.updateConfig({
3427
3504
  cluster: {
3428
3505
  ...e,
@@ -3439,9 +3516,9 @@ class K {
3439
3516
  category: "power",
3440
3517
  rarity: "epic",
3441
3518
  rarityWeight: 15,
3442
- color: "#ff3366",
3519
+ color: f.piercer,
3443
3520
  apply: () => {
3444
- const t = E.getInstance(), e = t.getConfig().piercer;
3521
+ const t = v.getInstance(), e = t.getConfig().piercer;
3445
3522
  t.updateConfig({
3446
3523
  piercer: {
3447
3524
  ...e,
@@ -3458,9 +3535,9 @@ class K {
3458
3535
  category: "power",
3459
3536
  rarity: "legendary",
3460
3537
  rarityWeight: 5,
3461
- color: "#ff2a5f",
3538
+ color: f.piercer,
3462
3539
  apply: () => {
3463
- const t = E.getInstance(), e = t.getConfig().piercer;
3540
+ const t = v.getInstance(), e = t.getConfig().piercer;
3464
3541
  t.updateConfig({
3465
3542
  piercer: {
3466
3543
  ...e,
@@ -3477,9 +3554,9 @@ class K {
3477
3554
  category: "defense",
3478
3555
  rarity: "legendary",
3479
3556
  rarityWeight: 5,
3480
- color: "#00f0ff",
3557
+ color: f.core,
3481
3558
  apply: () => {
3482
- const t = E.getInstance(), e = t.getConfig().core;
3559
+ const t = v.getInstance(), e = t.getConfig().core;
3483
3560
  t.updateConfig({
3484
3561
  core: {
3485
3562
  ...e,
@@ -3496,9 +3573,9 @@ class K {
3496
3573
  category: "power",
3497
3574
  rarity: "epic",
3498
3575
  rarityWeight: 15,
3499
- color: "#ff2a5f",
3576
+ color: f.piercer,
3500
3577
  apply: () => {
3501
- const t = E.getInstance(), e = t.getConfig().piercer;
3578
+ const t = v.getInstance(), e = t.getConfig().piercer;
3502
3579
  t.updateConfig({
3503
3580
  piercer: {
3504
3581
  ...e,
@@ -3515,9 +3592,9 @@ class K {
3515
3592
  category: "defense",
3516
3593
  rarity: "epic",
3517
3594
  rarityWeight: 15,
3518
- color: "#00f5ff",
3595
+ color: f.core,
3519
3596
  apply: () => {
3520
- const t = E.getInstance(), e = t.getConfig().core;
3597
+ const t = v.getInstance(), e = t.getConfig().core;
3521
3598
  t.updateConfig({
3522
3599
  core: {
3523
3600
  ...e,
@@ -3534,9 +3611,9 @@ class K {
3534
3611
  category: "defense",
3535
3612
  rarity: "rare",
3536
3613
  rarityWeight: 25,
3537
- color: "#00f5ff",
3614
+ color: f.core,
3538
3615
  apply: () => {
3539
- const t = E.getInstance(), e = t.getConfig().core;
3616
+ const t = v.getInstance(), e = t.getConfig().core;
3540
3617
  t.updateConfig({
3541
3618
  core: {
3542
3619
  ...e,
@@ -3553,9 +3630,9 @@ class K {
3553
3630
  category: "defense",
3554
3631
  rarity: "rare",
3555
3632
  rarityWeight: 20,
3556
- color: "#00f5ff",
3633
+ color: f.core,
3557
3634
  apply: (t) => {
3558
- E.getInstance().addCoreRing(1), t && t.addMaxRing(1);
3635
+ v.getInstance().addCoreRing(1), t && t.addMaxRing(1);
3559
3636
  }
3560
3637
  },
3561
3638
  {
@@ -3566,9 +3643,9 @@ class K {
3566
3643
  category: "magnet",
3567
3644
  rarity: "common",
3568
3645
  rarityWeight: 35,
3569
- color: "#00f5ff",
3646
+ color: f.core,
3570
3647
  apply: () => {
3571
- const t = E.getInstance(), e = t.getConfig().magnet;
3648
+ const t = v.getInstance(), e = t.getConfig().magnet;
3572
3649
  t.updateConfig({
3573
3650
  magnet: {
3574
3651
  ...e,
@@ -3585,9 +3662,9 @@ class K {
3585
3662
  category: "magnet",
3586
3663
  rarity: "rare",
3587
3664
  rarityWeight: 25,
3588
- color: "#00f5ff",
3665
+ color: f.core,
3589
3666
  apply: () => {
3590
- const t = E.getInstance(), e = t.getConfig().magnet;
3667
+ const t = v.getInstance(), e = t.getConfig().magnet;
3591
3668
  t.updateConfig({
3592
3669
  magnet: {
3593
3670
  ...e,
@@ -3598,14 +3675,14 @@ class K {
3598
3675
  }
3599
3676
  ];
3600
3677
  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 = [];
3678
+ const e = v.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
3679
  for (let a = 0; a < t && i.length > 0; a++) {
3603
- const l = i.reduce((o, r) => o + r.rarityWeight, 0);
3604
- let n = Math.random() * l;
3605
- for (let o = 0; o < i.length; o++) {
3606
- const r = i[o];
3607
- if (n -= r.rarityWeight, n <= 0) {
3608
- s.push(r), i.splice(o, 1);
3680
+ const r = i.reduce((n, l) => n + l.rarityWeight, 0);
3681
+ let o = Math.random() * r;
3682
+ for (let n = 0; n < i.length; n++) {
3683
+ const l = i[n];
3684
+ if (o -= l.rarityWeight, o <= 0) {
3685
+ s.push(l), i.splice(n, 1);
3609
3686
  break;
3610
3687
  }
3611
3688
  }
@@ -3616,7 +3693,7 @@ class K {
3616
3693
  this.powerUps.push(t);
3617
3694
  }
3618
3695
  }
3619
- class At {
3696
+ class St {
3620
3697
  haptics = {
3621
3698
  impact: async (t) => {
3622
3699
  if ("vibrate" in navigator) {
@@ -3656,7 +3733,125 @@ class At {
3656
3733
  }
3657
3734
  };
3658
3735
  }
3659
- class bt {
3736
+ class Mt {
3737
+ enabled;
3738
+ overlay;
3739
+ copyButton;
3740
+ frameStart = 0;
3741
+ lastFrameEnd = 0;
3742
+ updateMs = 0;
3743
+ physicsMs = 0;
3744
+ renderMs = 0;
3745
+ frameMs = 0;
3746
+ fps = 0;
3747
+ fpsLimit = 60;
3748
+ state = "MENU";
3749
+ lastReport = "";
3750
+ slowFrames = 0;
3751
+ lastReportAt = 0;
3752
+ counts = {
3753
+ enemies: 0,
3754
+ particles: 0,
3755
+ shockwaves: 0,
3756
+ pools: 0,
3757
+ vortices: 0,
3758
+ floatingTexts: 0
3759
+ };
3760
+ constructor(t, e) {
3761
+ if (this.enabled = e, !e) {
3762
+ this.overlay = null, this.copyButton = null;
3763
+ return;
3764
+ }
3765
+ const i = document.createElement("pre");
3766
+ i.setAttribute("aria-label", "Performance audit"), i.style.cssText = [
3767
+ "position:fixed",
3768
+ "top:10px",
3769
+ "left:10px",
3770
+ "z-index:10000",
3771
+ "margin:0",
3772
+ "padding:8px 10px",
3773
+ "min-width:220px",
3774
+ "border:1px solid rgba(0,245,255,.55)",
3775
+ "border-radius:6px",
3776
+ "background:rgba(3,8,18,.88)",
3777
+ "color:#b8fbff",
3778
+ "font:12px/1.35 monospace",
3779
+ "pointer-events:none",
3780
+ "white-space:pre"
3781
+ ].join(";"), i.textContent = `PERF AUDIT
3782
+ starting…`, t.appendChild(i), this.overlay = i;
3783
+ const s = document.createElement("button");
3784
+ s.type = "button", s.textContent = "COPY AUDIT", s.style.cssText = [
3785
+ "position:fixed",
3786
+ "top:185px",
3787
+ "left:10px",
3788
+ "z-index:10001",
3789
+ "padding:4px 7px",
3790
+ "border:1px solid rgba(0,245,255,.55)",
3791
+ "border-radius:4px",
3792
+ "background:rgba(3,8,18,.94)",
3793
+ "color:#b8fbff",
3794
+ "font:11px monospace",
3795
+ "cursor:pointer"
3796
+ ].join(";"), s.addEventListener("click", () => {
3797
+ this.copyReport();
3798
+ }), t.appendChild(s), this.copyButton = s;
3799
+ }
3800
+ beginFrame() {
3801
+ this.enabled && (this.frameStart = performance.now());
3802
+ }
3803
+ setFpsLimit(t) {
3804
+ (t === 30 || t === 60 || t === 120) && (this.fpsLimit = t);
3805
+ }
3806
+ setState(t) {
3807
+ this.state = t;
3808
+ }
3809
+ finishUpdate(t, e) {
3810
+ !this.enabled || this.frameStart <= 0 || (this.updateMs = performance.now() - this.frameStart, this.physicsMs = t, this.counts = e);
3811
+ }
3812
+ finishRender(t) {
3813
+ if (!this.enabled || this.frameStart <= 0) return;
3814
+ const e = performance.now();
3815
+ this.renderMs = e - t, this.frameMs = this.lastFrameEnd > 0 ? e - this.lastFrameEnd : e - this.frameStart, this.lastFrameEnd = e;
3816
+ const i = this.frameMs > 0 ? 1e3 / this.frameMs : 0;
3817
+ 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());
3818
+ }
3819
+ destroy() {
3820
+ this.overlay?.remove(), this.copyButton?.remove();
3821
+ }
3822
+ async copyReport() {
3823
+ const t = this.lastReport || this.overlay?.textContent || "";
3824
+ try {
3825
+ await navigator.clipboard.writeText(t);
3826
+ } catch {
3827
+ const e = document.createElement("textarea");
3828
+ e.value = t, document.body.appendChild(e), e.select(), document.execCommand("copy"), e.remove();
3829
+ }
3830
+ this.copyButton && (this.copyButton.textContent = "COPIED", window.setTimeout(() => {
3831
+ this.copyButton && (this.copyButton.textContent = "COPY AUDIT");
3832
+ }, 900));
3833
+ }
3834
+ renderOverlay() {
3835
+ if (!this.overlay) return;
3836
+ const t = performance.memory, e = t ? `
3837
+ HEAP ${(t.usedJSHeapSize / 1024 / 1024).toFixed(1)} MB` : "";
3838
+ this.lastReport = [
3839
+ "PERF AUDIT (?debug)",
3840
+ `STATE ${this.state}`,
3841
+ `FPS ${this.fps.toFixed(1)} / CAP ${this.fpsLimit} slow ${this.slowFrames}`,
3842
+ `FRAME ${this.frameMs.toFixed(1)} ms`,
3843
+ `UPDATE ${this.updateMs.toFixed(1)} ms`,
3844
+ `PHYS ${this.physicsMs.toFixed(1)} ms`,
3845
+ `RENDER ${this.renderMs.toFixed(1)} ms`,
3846
+ `ENEMY ${this.counts.enemies}`,
3847
+ `PART ${this.counts.particles} SW ${this.counts.shockwaves}`,
3848
+ `POOL ${this.counts.pools} VTX ${this.counts.vortices}`,
3849
+ `TEXT ${this.counts.floatingTexts}${e}`
3850
+ ].join(`
3851
+ `), this.overlay.textContent = this.lastReport;
3852
+ }
3853
+ }
3854
+ class Tt {
3660
3855
  container;
3661
3856
  canvas;
3662
3857
  i18n;
@@ -3675,6 +3870,7 @@ class bt {
3675
3870
  interactiveTutorial;
3676
3871
  tutorialOverlay;
3677
3872
  progressBar;
3873
+ performanceAudit;
3678
3874
  core;
3679
3875
  enemies = [];
3680
3876
  ambientEnemies = [];
@@ -3688,13 +3884,14 @@ class bt {
3688
3884
  isLevelUpActive = !1;
3689
3885
  pendingLevelUps = [];
3690
3886
  debugRerollsEnabled = typeof window < "u" && window.location.hostname === "localhost" && new URLSearchParams(window.location.search).has("debug");
3887
+ debugPerformanceEnabled = typeof window < "u" && new URLSearchParams(window.location.search).has("debug");
3691
3888
  rerollsRemaining = 1;
3692
3889
  score = { value: 0 };
3693
3890
  combo = { value: 0 };
3694
3891
  isRunning = !1;
3695
3892
  isPaused = !1;
3696
3893
  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(
3894
+ this.container = t.root, this.container.classList.add("axon-game-root"), this.i18n = new j(t.language), this.themeManager = new ut(t.theme, this.container), this.platform = t.platform || new St(), 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 Y(), this.core = new $(this.canvas.width / 2, this.canvas.height / 2), this.inputManager = new z(this.canvas), this.physicsEngine = new lt(this.eventBus, this.i18n), this.waveDirector = new ht(), this.renderer = new xt(this.canvas, this.themeManager), this.juice = new X(), this.settingsModal = new At(
3698
3895
  this.container,
3699
3896
  this.i18n,
3700
3897
  this.themeManager,
@@ -3702,15 +3899,18 @@ class bt {
3702
3899
  (e) => this.onLanguageChanged(e),
3703
3900
  () => {
3704
3901
  this.isPaused = !1;
3902
+ },
3903
+ (e) => {
3904
+ this.gameLoop.setFpsLimit(e), this.performanceAudit.setFpsLimit(e);
3705
3905
  }
3706
- ), this.interactiveTutorial = new xt(), this.tutorialOverlay = new yt(this.container, this.i18n, this.interactiveTutorial), this.hud = new _t(this.container, this.i18n, () => {
3906
+ ), this.interactiveTutorial = new bt(), this.tutorialOverlay = new vt(this.container, this.i18n, this.interactiveTutorial), this.hud = new yt(this.container, this.i18n, () => {
3707
3907
  this.isPaused = !0, this.settingsModal.show();
3708
- }), this.hud.show(), this.progressBar = new Et(this.hud.progressSlot, (e) => {
3908
+ }), this.hud.show(), this.progressBar = new It(this.hud.progressSlot, (e) => {
3709
3909
  this.waveDirector.wave = e, this.triggerLevelUp(e);
3710
- }), this.startMenu = new ft(this.container, this.i18n, () => this.startGame()), this.initAmbientArena(), this.gameLoop = new W(
3910
+ }), this.performanceAudit = new Mt(this.container, this.debugPerformanceEnabled), this.startMenu = new Et(this.container, this.i18n, () => this.startGame()), this.initAmbientArena(), this.gameLoop = new Z(
3711
3911
  (e) => this.update(e),
3712
3912
  () => this.render()
3713
- ), this.setupEvents(), this.gameLoop.start();
3913
+ ), this.gameLoop.setFpsLimit(this.settingsModal.getFpsLimit()), this.performanceAudit.setFpsLimit(this.settingsModal.getFpsLimit()), this.setupEvents(), this.gameLoop.start();
3714
3914
  }
3715
3915
  setLanguage(t) {
3716
3916
  this.i18n.setLanguage(t), this.onLanguageChanged(t);
@@ -3731,14 +3931,14 @@ class bt {
3731
3931
  this.ambientEnemies = [];
3732
3932
  const t = ["piercer", "spore", "cluster", "parasite"];
3733
3933
  for (let e = 0; e < 16; e++) {
3734
- const i = t[e % t.length], s = e * Math.PI * 2 / 16, a = 180 + Math.random() * 220, l = {
3934
+ const i = e === 0 ? "heavy" : t[(e - 1) % t.length], s = e * Math.PI * 2 / 16, a = 180 + Math.random() * 220, r = {
3735
3935
  x: this.canvas.width / 2 + Math.cos(s) * a,
3736
3936
  y: this.canvas.height / 2 + Math.sin(s) * a
3737
- }, n = M.createEnemy(i, l, {
3738
- x: l.x + Math.sin(s) * 100,
3739
- y: l.y - Math.cos(s) * 100
3937
+ }, o = P.createEnemy(i, r, {
3938
+ x: r.x + Math.sin(s) * 100,
3939
+ y: r.y - Math.cos(s) * 100
3740
3940
  });
3741
- this.ambientEnemies.push(n);
3941
+ this.ambientEnemies.push(o);
3742
3942
  }
3743
3943
  }
3744
3944
  resizeCanvas() {
@@ -3765,12 +3965,20 @@ class bt {
3765
3965
  }), this.canvas.addEventListener("touchstart", () => t(!0), { passive: !0 }), this.canvas.addEventListener("touchend", e, { passive: !0 }), this.canvas.addEventListener("touchcancel", e, { passive: !0 });
3766
3966
  }
3767
3967
  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());
3968
+ v.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
3969
  }
3770
3970
  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);
3971
+ if (this.performanceAudit.beginFrame(), this.performanceAudit.setState(this.isRunning ? this.isPaused ? "PAUSED" : "GAME" : "MENU"), this.core.update(t), !this.isRunning || this.isPaused) {
3972
+ for (const i of this.ambientEnemies)
3973
+ 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);
3974
+ this.performanceAudit.finishUpdate(0, {
3975
+ enemies: this.ambientEnemies.length,
3976
+ particles: this.particles.length,
3977
+ shockwaves: this.shockwaves.length,
3978
+ pools: this.pools.length,
3979
+ vortices: this.vortices.length,
3980
+ floatingTexts: this.floatingTexts.length
3981
+ });
3774
3982
  return;
3775
3983
  }
3776
3984
  if (this.interactiveTutorial.isActive)
@@ -3785,50 +3993,50 @@ class bt {
3785
3993
  () => this.inputManager.forceRelease()
3786
3994
  ), this.tutorialOverlay.updateStep(this.interactiveTutorial.getStep());
3787
3995
  else if (!this.isLevelUpActive) {
3788
- const e = this.waveDirector.update(
3996
+ const i = this.waveDirector.update(
3789
3997
  t,
3790
3998
  this.enemies,
3791
3999
  this.canvas.width,
3792
4000
  this.canvas.height,
3793
4001
  this.core.position
3794
4002
  );
3795
- e && this.enemies.push(e);
4003
+ i && this.enemies.push(i);
3796
4004
  }
3797
4005
  if (this.isLevelUpActive) {
3798
4006
  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;
4007
+ const i = this.inputManager.grabbedOrb;
4008
+ !this.inputManager.isPointerDown && i && (i.isGrabbed = !1, this.inputManager.grabbedOrb = null);
4009
+ const s = this.inputManager.pointerPosition;
3802
4010
  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);
4011
+ const a = this.canvas.width / 2, r = this.canvas.height / 2 + 210;
4012
+ Math.hypot(s.x - a, s.y - r) <= 80 && (this.triggerReroll(), this.inputManager.isPointerDown = !1);
3805
4013
  }
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);
4014
+ for (const a of this.orbitingOrbs) {
4015
+ const r = s.x - a.position.x, o = s.y - a.position.y;
4016
+ if (a.isHovered = Math.hypot(r, o) <= a.radius * 1.5, a === i && this.inputManager.isPointerDown) {
4017
+ a.position = { ...this.inputManager.pointerPosition };
4018
+ const n = this.core.position.x - a.position.x, l = this.core.position.y - a.position.y;
4019
+ if (Math.hypot(n, l) <= this.core.radius + a.radius) {
4020
+ a.definition.apply(this.core), this.core.absorbPowerUpColor(a.definition.color, 0.4), this.juice.triggerFlash(0.8), this.juice.triggerScreenShake({ x: n, y: l }, 24);
4021
+ const c = this.i18n.translate(a.definition.titleKey);
3814
4022
  this.floatingTexts.push({
3815
4023
  id: Math.random().toString(),
3816
4024
  text: `+ ${c}`,
3817
4025
  position: { ...this.core.position },
3818
4026
  velocity: { x: 0, y: -80 },
3819
- color: s.definition.color,
4027
+ color: a.definition.color,
3820
4028
  alpha: 1,
3821
4029
  lifetime: 0,
3822
4030
  maxLifetime: 1.6,
3823
4031
  size: 26
3824
4032
  });
3825
- for (let h = 0; h < 45; h++) {
3826
- const u = Math.random() * Math.PI * 2, d = 200 + Math.random() * 400;
4033
+ for (let p = 0; p < 45; p++) {
4034
+ const g = Math.random() * Math.PI * 2, _ = 200 + Math.random() * 400;
3827
4035
  this.particles.push({
3828
4036
  id: Math.random().toString(),
3829
4037
  position: { ...this.core.position },
3830
- velocity: { x: Math.cos(u) * d, y: Math.sin(u) * d },
3831
- color: s.definition.color,
4038
+ velocity: { x: Math.cos(g) * _, y: Math.sin(g) * _ },
4039
+ color: a.definition.color,
3832
4040
  radius: 4 + Math.random() * 5,
3833
4041
  alpha: 1,
3834
4042
  lifetime: 0,
@@ -3838,37 +4046,49 @@ class bt {
3838
4046
  this.inputManager.forceRelease(), this.orbitingOrbs = [], this.presentNextLevelUp();
3839
4047
  }
3840
4048
  } else
3841
- s.update(t, this.core.position);
4049
+ a.update(t, this.core.position);
3842
4050
  }
3843
4051
  }
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);
4052
+ let e = 0;
4053
+ if (!this.isLevelUpActive) {
4054
+ const i = this.debugPerformanceEnabled ? performance.now() : 0;
4055
+ this.physicsEngine.update(
4056
+ t,
4057
+ this.core,
4058
+ this.enemies,
4059
+ this.pools,
4060
+ this.vortices,
4061
+ this.shockwaves,
4062
+ this.particles,
4063
+ this.floatingTexts,
4064
+ this.juice,
4065
+ this.combo,
4066
+ this.score,
4067
+ this.canvas.width,
4068
+ this.canvas.height,
4069
+ () => {
4070
+ this.core.addKillRepair() && (this.juice.triggerFlash(0.4), this.floatingTexts.push({
4071
+ id: Math.random().toString(),
4072
+ text: "RING RESTORED!",
4073
+ position: { ...this.core.position },
4074
+ velocity: { x: 0, y: -60 },
4075
+ color: f.core,
4076
+ alpha: 1,
4077
+ lifetime: 0,
4078
+ maxLifetime: 1.2,
4079
+ size: 22
4080
+ }));
4081
+ }
4082
+ ), e = this.debugPerformanceEnabled ? performance.now() - i : 0;
4083
+ }
4084
+ 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, {
4085
+ enemies: this.enemies.length,
4086
+ particles: this.particles.length,
4087
+ shockwaves: this.shockwaves.length,
4088
+ pools: this.pools.length,
4089
+ vortices: this.vortices.length,
4090
+ floatingTexts: this.floatingTexts.length
4091
+ });
3872
4092
  }
3873
4093
  triggerLevelUp(t) {
3874
4094
  this.pendingLevelUps.push(t), this.isLevelUpActive || this.presentNextLevelUp();
@@ -3884,7 +4104,7 @@ class bt {
3884
4104
  text: this.i18n.translate("levelUpChoose", { level: t }),
3885
4105
  position: { ...this.core.position },
3886
4106
  velocity: { x: 0, y: -100 },
3887
- color: "#00f0ff",
4107
+ color: f.core,
3888
4108
  alpha: 1,
3889
4109
  lifetime: 0,
3890
4110
  maxLifetime: 2,
@@ -3896,40 +4116,40 @@ class bt {
3896
4116
  id: Math.random().toString(),
3897
4117
  position: { ...this.core.position },
3898
4118
  velocity: { x: Math.cos(s) * a, y: Math.sin(s) * a },
3899
- color: "#00f0ff",
4119
+ color: f.core,
3900
4120
  radius: 2 + Math.random() * 3,
3901
4121
  alpha: 1,
3902
4122
  lifetime: 0,
3903
4123
  maxLifetime: 0.7
3904
4124
  });
3905
4125
  }
3906
- const e = K.getRandomOptions(3);
4126
+ const e = V.getRandomOptions(3);
3907
4127
  this.orbitingOrbs = e.map((i, s) => {
3908
4128
  const a = s * Math.PI * 2 / e.length;
3909
- return new G(`orb_${Date.now()}_${s}`, i, a);
4129
+ return new B(`orb_${Date.now()}_${s}`, i, a);
3910
4130
  }), this.rerollsRemaining = this.getRerollLimit();
3911
4131
  }
3912
4132
  spawnExperienceDrops() {
3913
4133
  for (const t of this.enemies)
3914
- t.experienceDropPending && (t.experienceDropPending = !1, this.experienceOrbs.push(new ct(t.position)));
4134
+ t.experienceDropPending && (t.experienceDropPending = !1, this.experienceOrbs.push(new pt(t.position)));
3915
4135
  }
3916
4136
  updateExperienceOrbs(t) {
3917
- const e = E.getInstance().getConfig().magnet;
4137
+ const e = v.getInstance().getConfig().magnet;
3918
4138
  for (const i of this.experienceOrbs)
3919
4139
  if (i.active) {
3920
4140
  if (i.isAbsorbing || Math.hypot(
3921
4141
  this.core.position.x - i.position.x,
3922
4142
  this.core.position.y - i.position.y
3923
4143
  ) <= this.core.getHitboxRadius() + e.corePickupRadius && i.beginAbsorption(), !i.isAbsorbing) {
3924
- const s = this.inputManager.pointerPosition.x - i.position.x, a = this.inputManager.pointerPosition.y - i.position.y, l = e.psionicRadius + e.pickupRadius + i.radius;
3925
- Math.hypot(s, a) <= l && i.beginAbsorption();
4144
+ const s = this.inputManager.pointerPosition.x - i.position.x, a = this.inputManager.pointerPosition.y - i.position.y, r = e.psionicRadius + e.pickupRadius + i.radius;
4145
+ Math.hypot(s, a) <= r && i.beginAbsorption();
3926
4146
  }
3927
4147
  i.update(t, this.core.position, this.core.getHitboxRadius(), e.absorptionSpeed), i.active || (this.progressBar.addExperience(i.value), this.juice.triggerFlash(0.12), this.floatingTexts.push({
3928
4148
  id: Math.random().toString(),
3929
4149
  text: `+${i.value} XP`,
3930
4150
  position: { ...this.core.position },
3931
4151
  velocity: { x: 0, y: -55 },
3932
- color: "#fbbf24",
4152
+ color: f.experience,
3933
4153
  alpha: 1,
3934
4154
  lifetime: 0,
3935
4155
  maxLifetime: 0.8,
@@ -3941,17 +4161,17 @@ class bt {
3941
4161
  triggerReroll() {
3942
4162
  if (this.rerollsRemaining <= 0) return;
3943
4163
  this.rerollsRemaining -= 1, this.juice.triggerFlash(0.4);
3944
- const t = K.getRandomOptions(3);
4164
+ const t = V.getRandomOptions(3);
3945
4165
  this.orbitingOrbs = t.map((e, i) => {
3946
4166
  const s = i * Math.PI * 2 / t.length;
3947
- return new G(`orb_${Date.now()}_${i}`, e, s);
4167
+ return new B(`orb_${Date.now()}_${i}`, e, s);
3948
4168
  });
3949
4169
  }
3950
4170
  render() {
3951
- const t = this.isRunning ? this.enemies : this.ambientEnemies;
4171
+ const t = this.debugPerformanceEnabled ? performance.now() : 0, e = this.isRunning ? this.enemies : this.ambientEnemies;
3952
4172
  this.renderer.render(
3953
4173
  this.core,
3954
- t,
4174
+ e,
3955
4175
  this.experienceOrbs,
3956
4176
  this.pools,
3957
4177
  this.vortices,
@@ -3969,23 +4189,23 @@ class bt {
3969
4189
  this.i18n,
3970
4190
  this.rerollsRemaining > 0,
3971
4191
  this.rerollsRemaining
3972
- );
4192
+ ), this.performanceAudit.finishRender(t);
3973
4193
  }
3974
4194
  getRerollLimit() {
3975
4195
  return this.debugRerollsEnabled ? 99 : 1;
3976
4196
  }
3977
4197
  destroy() {
3978
- this.gameLoop.stop(), this.canvas.remove();
4198
+ this.gameLoop.stop(), this.performanceAudit.destroy(), this.canvas.remove();
3979
4199
  }
3980
4200
  }
3981
- function vt(A) {
3982
- return new bt(A);
4201
+ function Lt(b) {
4202
+ return new Tt(b);
3983
4203
  }
3984
4204
  export {
3985
- At as BrowserPlatform,
3986
- bt as GameEngine,
3987
- V as LANGUAGES,
3988
- ht as ThemeManager,
3989
- vt as createAxonSurge,
3990
- N as isLanguage
4205
+ St as BrowserPlatform,
4206
+ Tt as GameEngine,
4207
+ W as LANGUAGES,
4208
+ ut as ThemeManager,
4209
+ Lt as createAxonSurge,
4210
+ k as isLanguage
3991
4211
  };