@gamebob/axon-surge 0.12.0 → 0.14.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 (36) hide show
  1. package/dist/axon-surge.js +797 -534
  2. package/dist/config/GameConfig.d.ts +8 -0
  3. package/dist/config/GameConfig.d.ts.map +1 -1
  4. package/dist/core/GameEngine.d.ts +8 -1
  5. package/dist/core/GameEngine.d.ts.map +1 -1
  6. package/dist/entities/CoreEntity.d.ts +2 -0
  7. package/dist/entities/CoreEntity.d.ts.map +1 -1
  8. package/dist/entities/EnemyEntity.d.ts +3 -2
  9. package/dist/entities/EnemyEntity.d.ts.map +1 -1
  10. package/dist/entities/ExperienceOrb.d.ts +14 -0
  11. package/dist/entities/ExperienceOrb.d.ts.map +1 -0
  12. package/dist/i18n/locales.d.ts +6 -0
  13. package/dist/i18n/locales.d.ts.map +1 -1
  14. package/dist/physics/PhysicsEngine.d.ts.map +1 -1
  15. package/dist/physics/handlers/ChainReactionHelper.d.ts.map +1 -1
  16. package/dist/powerups/PowerUpRegistry.d.ts.map +1 -1
  17. package/dist/powerups/PowerUpTypes.d.ts +1 -1
  18. package/dist/powerups/PowerUpTypes.d.ts.map +1 -1
  19. package/dist/render/CanvasRenderer.d.ts +5 -2
  20. package/dist/render/CanvasRenderer.d.ts.map +1 -1
  21. package/dist/render/CosmosBackgroundRenderer.d.ts +7 -1
  22. package/dist/render/CosmosBackgroundRenderer.d.ts.map +1 -1
  23. package/dist/render/JuiceEffects.d.ts.map +1 -1
  24. package/dist/render/OffscreenIndicatorRenderer.d.ts +2 -1
  25. package/dist/render/OffscreenIndicatorRenderer.d.ts.map +1 -1
  26. package/dist/strategies/FragmentClusterStrategy.d.ts.map +1 -1
  27. package/dist/strategies/GravityParasiteStrategy.d.ts.map +1 -1
  28. package/dist/strategies/HeavyShieldStrategy.d.ts.map +1 -1
  29. package/dist/strategies/PiercingCellStrategy.d.ts.map +1 -1
  30. package/dist/strategies/ToxicSporeStrategy.d.ts.map +1 -1
  31. package/dist/styles.css +1 -1
  32. package/dist/theme/ThemeManager.d.ts +6 -0
  33. package/dist/theme/ThemeManager.d.ts.map +1 -1
  34. package/dist/ui/ProgressBar.d.ts +3 -2
  35. package/dist/ui/ProgressBar.d.ts.map +1 -1
  36. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- class J {
1
+ class V {
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,7 +15,7 @@ class J {
15
15
  this.listeners.clear();
16
16
  }
17
17
  }
18
- class X {
18
+ class W {
19
19
  animationFrameId = null;
20
20
  lastTime = 0;
21
21
  isRunning = !1;
@@ -36,23 +36,24 @@ class X {
36
36
  this.lastTime = t, this.updateCallback(e), this.renderCallback(), this.animationFrameId = requestAnimationFrame(this.tick);
37
37
  }
38
38
  }
39
- const B = {
39
+ const k = {
40
40
  core: {
41
41
  maxIntegrity: 3,
42
42
  invulnerabilityDuration: 1.5,
43
43
  radius: 32,
44
- vampirismHealProgressRate: 0
44
+ vampirismHealProgressRate: 0,
45
+ hasOffscreenIndicators: !1
45
46
  },
46
47
  toxicPool: {
47
- baseRadius: 110,
48
- synergyRadius: 210,
48
+ baseRadius: 40,
49
+ synergyRadius: 80,
49
50
  baseDuration: 4.5,
50
51
  synergyDuration: 8,
51
52
  damage: 50
52
53
  },
53
54
  gravityVortex: {
54
- baseRadius: 220,
55
- synergyRadius: 360,
55
+ baseRadius: 75,
56
+ synergyRadius: 130,
56
57
  baseDuration: 4,
57
58
  synergyDuration: 6,
58
59
  basePullForce: 2200,
@@ -72,16 +73,22 @@ const B = {
72
73
  terminalAoERadius: 0,
73
74
  hasHoming: !1,
74
75
  homingTargets: 1
76
+ },
77
+ magnet: {
78
+ pickupRadius: 0,
79
+ psionicRadius: 70,
80
+ corePickupRadius: 120,
81
+ absorptionSpeed: 680
75
82
  }
76
83
  };
77
- class A {
84
+ class E {
78
85
  static instance;
79
86
  config;
80
87
  constructor() {
81
- this.config = JSON.parse(JSON.stringify(B));
88
+ this.config = JSON.parse(JSON.stringify(k));
82
89
  }
83
90
  static getInstance() {
84
- return A.instance || (A.instance = new A()), A.instance;
91
+ return E.instance || (E.instance = new E()), E.instance;
85
92
  }
86
93
  getConfig() {
87
94
  return this.config;
@@ -99,10 +106,10 @@ class A {
99
106
  this.config.core.maxIntegrity += t;
100
107
  }
101
108
  resetToDefault() {
102
- this.config = JSON.parse(JSON.stringify(B));
109
+ this.config = JSON.parse(JSON.stringify(k));
103
110
  }
104
111
  }
105
- class z {
112
+ class F {
106
113
  position;
107
114
  radius;
108
115
  integrity;
@@ -113,18 +120,22 @@ class z {
113
120
  maxInvulnerabilityDuration;
114
121
  customColor = { r: 0, g: 240, b: 255 };
115
122
  powerUpCount = 0;
123
+ collectedPowerUpColors = [];
116
124
  constructor(t, e) {
117
- const i = A.getInstance().getConfig().core;
125
+ const i = E.getInstance().getConfig().core;
118
126
  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;
119
127
  }
120
128
  absorbPowerUpColor(t, e = 0.35) {
121
- this.powerUpCount++;
129
+ this.powerUpCount++, this.collectedPowerUpColors.push(t);
122
130
  const i = t.replace("#", "");
123
131
  if (i.length === 6) {
124
132
  const s = parseInt(i.substring(0, 2), 16), a = parseInt(i.substring(2, 4), 16), l = parseInt(i.substring(4, 6), 16);
125
133
  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);
126
134
  }
127
135
  }
136
+ getHitboxRadius() {
137
+ return this.integrity > 0 ? this.radius + 16 + (this.integrity - 1) * 12 : this.radius;
138
+ }
128
139
  getColorHex() {
129
140
  const t = this.customColor.r.toString(16).padStart(2, "0"), e = this.customColor.g.toString(16).padStart(2, "0"), i = this.customColor.b.toString(16).padStart(2, "0");
130
141
  return `#${t}${e}${i}`;
@@ -138,7 +149,7 @@ class z {
138
149
  }
139
150
  repairProgress = 0;
140
151
  addKillRepair() {
141
- const t = A.getInstance().getConfig().core.vampirismHealProgressRate;
152
+ const t = E.getInstance().getConfig().core.vampirismHealProgressRate;
142
153
  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);
143
154
  }
144
155
  heal(t = 1) {
@@ -151,11 +162,11 @@ class z {
151
162
  return this.invulnerabilityTimer > 0 ? !1 : this.integrity > 0 ? (this.integrity -= 1, this.invulnerabilityTimer = this.maxInvulnerabilityDuration, !0) : !1;
152
163
  }
153
164
  reset(t, e) {
154
- const i = A.getInstance().getConfig().core;
155
- 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.customColor = { r: 0, g: 240, b: 255 };
165
+ const i = E.getInstance().getConfig().core;
166
+ 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 };
156
167
  }
157
168
  }
158
- class H {
169
+ class D {
159
170
  id;
160
171
  position = { x: 0, y: 0 };
161
172
  velocity = { x: 0, y: 0 };
@@ -173,6 +184,7 @@ class H {
173
184
  isStationaryShield = !1;
174
185
  shieldAngle = 0;
175
186
  remainingHomingKills = 0;
187
+ experienceDropPending = !1;
176
188
  isDying = !1;
177
189
  deathType = "none";
178
190
  deathTimer = 0;
@@ -184,11 +196,11 @@ class H {
184
196
  getHitRadius() {
185
197
  return this.radius * (1 + this.hitRadiusPadding);
186
198
  }
187
- triggerDissolveDeath() {
188
- this.isDying || (this.isDying = !0, this.deathType = "dissolve", this.deathTimer = 0, this.maxDeathTimer = 0.45, this.velocity = { x: 0, y: 0 });
199
+ triggerDissolveDeath(t = !1) {
200
+ t && (this.experienceDropPending = !0), !this.isDying && (this.isDying = !0, this.deathType = "dissolve", this.deathTimer = 0, this.maxDeathTimer = 0.45, this.velocity = { x: 0, y: 0 });
189
201
  }
190
- triggerSliceDeath(t) {
191
- this.isDying || (this.isDying = !0, this.deathType = "sliced", this.deathTimer = 0, this.maxDeathTimer = 0.35, this.sliceAngle = t, this.velocity = { x: 0, y: 0 });
202
+ triggerSliceDeath(t, e = !1) {
203
+ e && (this.experienceDropPending = !0), !this.isDying && (this.isDying = !0, this.deathType = "sliced", this.deathTimer = 0, this.maxDeathTimer = 0.35, this.sliceAngle = t, this.velocity = { x: 0, y: 0 });
192
204
  }
193
205
  update(t) {
194
206
  if (this.active) {
@@ -209,10 +221,10 @@ class H {
209
221
  }
210
222
  }
211
223
  reset() {
212
- 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.position = { x: 0, y: 0 }, this.velocity = { x: 0, y: 0 }, this.rotation = 0, this.strategy = null, this.maxSpeed = 200;
224
+ 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.experienceDropPending = !1, this.position = { x: 0, y: 0 }, this.velocity = { x: 0, y: 0 }, this.rotation = 0, this.strategy = null, this.maxSpeed = 200;
213
225
  }
214
226
  }
215
- class K {
227
+ class G {
216
228
  id;
217
229
  definition;
218
230
  position = { x: 0, y: 0 };
@@ -229,7 +241,7 @@ class K {
229
241
  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);
230
242
  }
231
243
  }
232
- class $ {
244
+ class Y {
233
245
  pointerPosition = { x: 0, y: 0 };
234
246
  isPointerDown = !1;
235
247
  grabbedEnemy = null;
@@ -339,7 +351,7 @@ class $ {
339
351
  if (t.type === "heavy")
340
352
  t.shieldAngle = t.rotation, t.velocity = { x: 0, y: 0 }, t.isStationaryShield = !0, t.isThrown = !1;
341
353
  else if (t.type === "piercer") {
342
- const o = A.getInstance().getConfig().piercer;
354
+ const o = E.getInstance().getConfig().piercer;
343
355
  o.hasHoming && (t.remainingHomingKills = o.homingTargets);
344
356
  }
345
357
  return this.grabbedEnemy = null, this.dragStart = null, this.pointerHistory = [], t;
@@ -351,7 +363,7 @@ class $ {
351
363
  this.grabbedEnemy = null, this.grabbedOrb = null, this.dragStart = null, this.pointerHistory = [], this.isPointerDown = !1;
352
364
  }
353
365
  }
354
- class j {
366
+ class Z {
355
367
  cellSize;
356
368
  grid = /* @__PURE__ */ new Map();
357
369
  constructor(t = 100) {
@@ -378,7 +390,7 @@ class j {
378
390
  return i;
379
391
  }
380
392
  }
381
- class q {
393
+ class z {
382
394
  hitstopTime = 0;
383
395
  shakeTime = 0;
384
396
  shakeDuration = 0.14;
@@ -386,7 +398,7 @@ class q {
386
398
  shakeVector = { x: 0, y: 0 };
387
399
  flashAlpha = 0;
388
400
  triggerHitstop(t = 0.06) {
389
- this.hitstopTime = t;
401
+ this.hitstopTime = 0;
390
402
  }
391
403
  triggerFlash(t = 0.4) {
392
404
  this.flashAlpha = t;
@@ -399,7 +411,7 @@ class q {
399
411
  }, this.shakeIntensity = s, this.shakeTime = this.shakeDuration;
400
412
  }
401
413
  update(t, e, i) {
402
- this.hitstopTime > 0 && (this.hitstopTime -= t), this.shakeTime > 0 && (this.shakeTime -= t), this.flashAlpha > 0 && (this.flashAlpha = Math.max(0, this.flashAlpha - t * 4));
414
+ 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);
403
415
  for (let s = e.length - 1; s >= 0; s--) {
404
416
  const a = e[s];
405
417
  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));
@@ -418,7 +430,7 @@ class q {
418
430
  };
419
431
  }
420
432
  }
421
- const N = {
433
+ const P = {
422
434
  es: {
423
435
  title: "AXON SURGE",
424
436
  startButton: "INICIAR ENLACE",
@@ -442,13 +454,13 @@ const N = {
442
454
  tutorialStep2Text: "PASO 2: LÁNZALO CON IMPULSO HACIA EL OBJETIVO",
443
455
  tutorialDragWarning: "¡LA MEJOR ESTRATEGIA ES LANZARLOS! LÁNZALO CON IMPULSO",
444
456
  levelUpChoose: "¡NIVEL {level}! ELIGE UN MODIFICADOR",
445
- rerollButton: "🎲 REROLL (1 DISPONIBLE)",
457
+ rerollButton: "🎲 REROLL ({count} DISPONIBLE)",
446
458
  pu_spore_radius_title: "EXPANSIÓN ÁCIDA",
447
- pu_spore_radius_desc: "+30% Radio Ácido",
459
+ pu_spore_radius_desc: "+12% Radio Ácido",
448
460
  pu_spore_duration_title: "LONGEVIDAD ÁCIDA",
449
461
  pu_spore_duration_desc: "+3.0s Duración Ácido",
450
462
  pu_vortex_radius_title: "EXPANSIÓN DE SINGULARIDAD",
451
- pu_vortex_radius_desc: "+25% Radio Vórtice",
463
+ pu_vortex_radius_desc: "+12% Radio Vórtice",
452
464
  pu_vortex_duration_title: "LONGEVIDAD GRAVITATORIA",
453
465
  pu_vortex_duration_desc: "+2.5s Duración Vórtice",
454
466
  pu_vortex_power_title: "SOBRECARGA GRAVITATORIA",
@@ -472,7 +484,13 @@ const N = {
472
484
  pu_vampirism_boost_title: "IMPULSO VAMPÍRICO",
473
485
  pu_vampirism_boost_desc: "+0.3% Curación por baja",
474
486
  pu_core_ring_title: "SOBRECARGA DE NÚCLEO",
475
- pu_core_ring_desc: "+1 Anillo de Vida"
487
+ pu_core_ring_desc: "+1 Anillo de Vida",
488
+ pu_magnet_radius_title: "CAMPO MAGNÉTICO",
489
+ pu_magnet_radius_desc: "+60 Radio de recogida de experiencia",
490
+ pu_magnet_strength_title: "ATRACCIÓN MAGNÉTICA",
491
+ pu_magnet_strength_desc: "+25% Velocidad de absorción de experiencia",
492
+ pu_offscreen_radar_title: "RADAR PSÍONICO",
493
+ pu_offscreen_radar_desc: "Detecta enemigos fuera de pantalla"
476
494
  },
477
495
  en: {
478
496
  title: "AXON SURGE",
@@ -497,13 +515,13 @@ const N = {
497
515
  tutorialStep2Text: "STEP 2: FLICK TOWARD TARGET WITH SWIPE SPEED",
498
516
  tutorialDragWarning: "THE BEST STRATEGY IS TO FLICK THEM! THROW WITH SWIPE SPEED",
499
517
  levelUpChoose: "LEVEL {level}! CHOOSE MODIFIER",
500
- rerollButton: "🎲 REROLL (1 AVAILABLE)",
518
+ rerollButton: "🎲 REROLL ({count} AVAILABLE)",
501
519
  pu_spore_radius_title: "ACID EXPANSION",
502
- pu_spore_radius_desc: "+30% Acid Radius",
520
+ pu_spore_radius_desc: "+12% Acid Radius",
503
521
  pu_spore_duration_title: "ACID LINGER",
504
522
  pu_spore_duration_desc: "+3.0s Acid Duration",
505
523
  pu_vortex_radius_title: "SINGULARITY EXPANSION",
506
- pu_vortex_radius_desc: "+25% Vortex Radius",
524
+ pu_vortex_radius_desc: "+12% Vortex Radius",
507
525
  pu_vortex_duration_title: "GRAVITY LINGER",
508
526
  pu_vortex_duration_desc: "+2.5s Vortex Duration",
509
527
  pu_vortex_power_title: "GRAVITY SURGE",
@@ -527,7 +545,13 @@ const N = {
527
545
  pu_vampirism_boost_title: "VAMPIRIC SURGE",
528
546
  pu_vampirism_boost_desc: "+0.3% Heal per kill",
529
547
  pu_core_ring_title: "NUCLEUS OVERCHARGE",
530
- pu_core_ring_desc: "+1 Life Ring"
548
+ pu_core_ring_desc: "+1 Life Ring",
549
+ pu_magnet_radius_title: "MAGNETIC FIELD",
550
+ pu_magnet_radius_desc: "+60 Experience pickup range",
551
+ pu_magnet_strength_title: "MAGNETIC PULL",
552
+ pu_magnet_strength_desc: "+25% Experience absorption speed",
553
+ pu_offscreen_radar_title: "PSIONIC RADAR",
554
+ pu_offscreen_radar_desc: "Detect off-screen enemies"
531
555
  },
532
556
  fr: {
533
557
  title: "AXON SURGE",
@@ -552,7 +576,7 @@ const N = {
552
576
  tutorialStep2Text: "ETAPE 2: LANCEZ AVEC VITESSE VERS LA CIBLE",
553
577
  tutorialDragWarning: "LA MEILLEURE STRATEGIE EST DE LES LANCER !",
554
578
  levelUpChoose: "NIVEAU {level} ! CHOISISSEZ UN MODIFICATEUR",
555
- rerollButton: "🎲 RELANCER (1 DISPONIBLE)",
579
+ rerollButton: "🎲 RELANCER ({count} DISPONIBLE)",
556
580
  pu_spore_radius_title: "EXPANSION ACIDE",
557
581
  pu_spore_radius_desc: "+30% Rayon d'acide",
558
582
  pu_spore_duration_title: "LONGEVITE ACIDE",
@@ -607,7 +631,7 @@ const N = {
607
631
  tutorialStep2Text: "SCHRITT 2: SCHLEUDERE MIT SCHWUNG AUF DAS ZIEL",
608
632
  tutorialDragWarning: "DIE BESTE STRATEGIE IST ES SIE ZU SCHLEUDERN!",
609
633
  levelUpChoose: "LEVEL {level}! MODIFIKATOR WÄHLEN",
610
- rerollButton: "🎲 NEU WÜRFELN (1 VERFÜGBAR)",
634
+ rerollButton: "🎲 NEU WÜRFELN ({count} VERFÜGBAR)",
611
635
  pu_spore_radius_title: "SÄURE-EXPANSION",
612
636
  pu_spore_radius_desc: "+30% Säureradius",
613
637
  pu_spore_duration_title: "SÄURE-DAUER",
@@ -662,7 +686,7 @@ const N = {
662
686
  tutorialStep2Text: "PASSO 2: LANCIA CON VELOCITA VERSO IL BERSAGLIO",
663
687
  tutorialDragWarning: "LA STRATEGIA MIGLIORE E LANCIARLI!",
664
688
  levelUpChoose: "LIVELLO {level}! SCEGLI UN MODIFICATORE",
665
- rerollButton: "🎲 RILANCIA (1 DISPONIBILE)",
689
+ rerollButton: "🎲 RILANCIA ({count} DISPONIBILE)",
666
690
  pu_spore_radius_title: "ESPANSIONE ACIDA",
667
691
  pu_spore_radius_desc: "+30% Raggio Acido",
668
692
  pu_spore_duration_title: "DURATA ACIDA",
@@ -717,7 +741,7 @@ const N = {
717
741
  tutorialStep2Text: "PASSO 2: LANCE COM IMPULSO EM DIRECAO AO ALVO",
718
742
  tutorialDragWarning: "A MELHOR ESTRATEGIA E LANCA-LOS!",
719
743
  levelUpChoose: "NÍVEL {level}! ESCOLHA UM MODIFICADOR",
720
- rerollButton: "🎲 REROLAR (1 DISPONÍVEL)",
744
+ rerollButton: "🎲 REROLAR ({count} DISPONÍVEL)",
721
745
  pu_spore_radius_title: "EXPANSÃO ÁCIDA",
722
746
  pu_spore_radius_desc: "+30% Raio Ácido",
723
747
  pu_spore_duration_title: "LONGEVIDADE ÁCIDA",
@@ -772,7 +796,7 @@ const N = {
772
796
  tutorialStep2Text: "STAP 2: GOOI MET SNELHEID NAAR HET DOEL",
773
797
  tutorialDragWarning: "DE BESTE STRATEGIE IS OM ZE TE GOOIEN!",
774
798
  levelUpChoose: "NIVEAU {level}! KIES EEN MODIFICATOR",
775
- rerollButton: "🎲 HERROL (1 BESCHIKBAAR)",
799
+ rerollButton: "🎲 HERROL ({count} BESCHIKBAAR)",
776
800
  pu_spore_radius_title: "ZURE EXPANSIE",
777
801
  pu_spore_radius_desc: "+30% Zuurstraal",
778
802
  pu_spore_duration_title: "ZURE DUUR",
@@ -827,7 +851,7 @@ const N = {
827
851
  tutorialStep2Text: "STEG 2: KASTA MED HASTIGHET MOT MÅLET",
828
852
  tutorialDragWarning: "DEN BÄSTA STRATEGIN ÄR ATT KASTA DEM!",
829
853
  levelUpChoose: "NIVÅ {level}! VÄLJ MODIFIERARE",
830
- rerollButton: "🎲 SLÅ OM (1 TILLGÄNGLIG)",
854
+ rerollButton: "🎲 SLÅ OM ({count} TILLGÄNGLIG)",
831
855
  pu_spore_radius_title: "SYRA-EXPANSION",
832
856
  pu_spore_radius_desc: "+30% Syraradie",
833
857
  pu_spore_duration_title: "SYRA-VARAKTIGHET",
@@ -882,7 +906,7 @@ const N = {
882
906
  tutorialStep2Text: "KROK 2: RZUĆ Z PRĘDKOŚCIĄ W STRONĘ CELU",
883
907
  tutorialDragWarning: "NAJLEPSZA STRATEGIA TO RZUCANIE NIMI!",
884
908
  levelUpChoose: "POZIOM {level}! WYBIERZ MODYFIKATOR",
885
- rerollButton: "🎲 PRZEROSZADA (1 DOSTĘPNA)",
909
+ rerollButton: "🎲 PRZEROSZADA ({count} DOSTĘPNA)",
886
910
  pu_spore_radius_title: "EKSPANSJA KWASOWA",
887
911
  pu_spore_radius_desc: "+30% Promień kwasu",
888
912
  pu_spore_duration_title: "TRWAŁOŚĆ KWASOWA",
@@ -937,7 +961,7 @@ const N = {
937
961
  tutorialStep2Text: "LANGKAH 2: LEMPAR DENGAN KECEPATAN KE TARGET",
938
962
  tutorialDragWarning: "STRATEGI TERBAIK ADALAH MELEMPAR MEREKA!",
939
963
  levelUpChoose: "TINGKAT {level}! PILIH MODIFIKASI",
940
- rerollButton: "🎲 ACAK ULANG (1 TERSEDIA)",
964
+ rerollButton: "🎲 ACAK ULANG ({count} TERSEDIA)",
941
965
  pu_spore_radius_title: "EKSPANSI ASAM",
942
966
  pu_spore_radius_desc: "+30% Radius Asam",
943
967
  pu_spore_duration_title: "DURASI ASAM",
@@ -992,7 +1016,7 @@ const N = {
992
1016
  tutorialStep2Text: "ADIM 2: HEDEFE HIZLA FIRLATIN",
993
1017
  tutorialDragWarning: "EN İYİ STRATEJİ ONLARI FIRLATMAKTIR!",
994
1018
  levelUpChoose: "SEVİYE {level}! GÜÇLENDİRME SEÇ",
995
- rerollButton: "🎲 YENİDEN ZAR AT (1 HAKK)",
1019
+ rerollButton: "🎲 YENİDEN ZAR AT ({count} HAKK)",
996
1020
  pu_spore_radius_title: "ASİT GENİŞLEMESİ",
997
1021
  pu_spore_radius_desc: "+30% Asit Yarıçapı",
998
1022
  pu_spore_duration_title: "ASİT SÜRESİ",
@@ -1047,7 +1071,7 @@ const N = {
1047
1071
  tutorialStep2Text: "ШАГ 2: БРОСАЙТЕ С ИМПУЛЬСОМ В ЦЕЛЬ",
1048
1072
  tutorialDragWarning: "ЛУЧШАЯ СТРАТЕГИЯ - БРОСАТЬ ИХ С ИМПУЛЬСОМ!",
1049
1073
  levelUpChoose: "УРОВЕНЬ {level}! ВЫБЕРИТЕ МОДИФИКАТОР",
1050
- rerollButton: "🎲 ПЕРЕБРОСИТЬ (1 ДОСТУПЕН)",
1074
+ rerollButton: "🎲 ПЕРЕБРОСИТЬ ({count} ДОСТУПЕН)",
1051
1075
  pu_spore_radius_title: "КИСЛОТНОЕ РАСШИРЕНИЕ",
1052
1076
  pu_spore_radius_desc: "+30% Радиус кислоты",
1053
1077
  pu_spore_duration_title: "КИСЛОТНАЯ ДЛИТЕЛЬНОСТЬ",
@@ -1102,7 +1126,7 @@ const N = {
1102
1126
  tutorialStep2Text: "ステップ2: ターゲットに向けて勢いよくフリック",
1103
1127
  tutorialDragWarning: "最高の戦略は勢いよく投げることです!",
1104
1128
  levelUpChoose: "レベル {level}! 強化を選択",
1105
- rerollButton: "🎲 リロール (残り1回)",
1129
+ rerollButton: "🎲 リロール (残り{count}回)",
1106
1130
  pu_spore_radius_title: "アシッド拡大",
1107
1131
  pu_spore_radius_desc: "+30% アシッド範囲",
1108
1132
  pu_spore_duration_title: "アシッド持続",
@@ -1157,7 +1181,7 @@ const N = {
1157
1181
  tutorialStep2Text: "2단계: 표적을 향해 빠르게 튕기세요",
1158
1182
  tutorialDragWarning: "최선의 전략은 적을 튕겨 던지는 것입니다!",
1159
1183
  levelUpChoose: "레벨 {level}! 강화 선택",
1160
- rerollButton: "🎲 리롤 (1회 가능)",
1184
+ rerollButton: "🎲 리롤 ({count}회 가능)",
1161
1185
  pu_spore_radius_title: "산성 확장",
1162
1186
  pu_spore_radius_desc: "+30% 산성 범주",
1163
1187
  pu_spore_duration_title: "산성 지속",
@@ -1212,7 +1236,7 @@ const N = {
1212
1236
  tutorialStep2Text: "步骤 2: 朝目标快速挥动抛投",
1213
1237
  tutorialDragWarning: "最佳策略是快速挥动抛投!",
1214
1238
  levelUpChoose: "等级 {level}! 选择强化",
1215
- rerollButton: "🎲 重刷 (剩余1次)",
1239
+ rerollButton: "🎲 重刷 (剩余{count}次)",
1216
1240
  pu_spore_radius_title: "酸液扩张",
1217
1241
  pu_spore_radius_desc: "+30% 酸液范围",
1218
1242
  pu_spore_duration_title: "酸液持久",
@@ -1244,7 +1268,7 @@ const N = {
1244
1268
  pu_core_ring_title: "核心过载",
1245
1269
  pu_core_ring_desc: "+1 生命环"
1246
1270
  }
1247
- }, Y = [
1271
+ }, K = [
1248
1272
  "es",
1249
1273
  "en",
1250
1274
  "fr",
@@ -1261,29 +1285,29 @@ const N = {
1261
1285
  "ko",
1262
1286
  "zh"
1263
1287
  ];
1264
- function P(E) {
1265
- return Y.includes(E);
1288
+ function O(y) {
1289
+ return K.includes(y);
1266
1290
  }
1267
- const V = "axon_surge_language";
1268
- class Q {
1291
+ const U = "axon_surge_language";
1292
+ class J {
1269
1293
  currentLanguage;
1270
1294
  constructor(t) {
1271
1295
  this.currentLanguage = this.detectLanguage(t);
1272
1296
  }
1273
1297
  detectLanguage(t) {
1274
1298
  try {
1275
- const e = localStorage.getItem(V);
1276
- if (e && P(e))
1299
+ const e = localStorage.getItem(U);
1300
+ if (e && O(e))
1277
1301
  return e;
1278
1302
  } catch {
1279
1303
  }
1280
- if (t && P(t))
1304
+ if (t && O(t))
1281
1305
  return t;
1282
1306
  try {
1283
1307
  const e = (document.documentElement.lang || document.body?.getAttribute("lang") || document.documentElement.getAttribute("data-lang") || "").toLowerCase();
1284
1308
  if (e) {
1285
1309
  const i = e.split("-")[0];
1286
- if (i && P(i))
1310
+ if (i && O(i))
1287
1311
  return i;
1288
1312
  }
1289
1313
  } catch {
@@ -1292,7 +1316,7 @@ class Q {
1292
1316
  const e = (navigator.language || navigator.languages && navigator.languages[0] || "").toLowerCase();
1293
1317
  if (e) {
1294
1318
  const i = e.split("-")[0];
1295
- if (i && P(i))
1319
+ if (i && O(i))
1296
1320
  return i;
1297
1321
  }
1298
1322
  } catch {
@@ -1300,10 +1324,10 @@ class Q {
1300
1324
  return "en";
1301
1325
  }
1302
1326
  setLanguage(t) {
1303
- if (N[t]) {
1327
+ if (P[t]) {
1304
1328
  this.currentLanguage = t;
1305
1329
  try {
1306
- localStorage.setItem(V, t);
1330
+ localStorage.setItem(U, t);
1307
1331
  } catch {
1308
1332
  }
1309
1333
  }
@@ -1312,15 +1336,15 @@ class Q {
1312
1336
  return this.currentLanguage;
1313
1337
  }
1314
1338
  translate(t, e) {
1315
- let s = (N[this.currentLanguage] || N.en)[t] || N.en[t] || String(t);
1339
+ let s = (P[this.currentLanguage] || P.en)[t] || P.en[t] || String(t);
1316
1340
  return e && Object.entries(e).forEach(([a, l]) => {
1317
1341
  s = s.replace(`{${a}}`, String(l));
1318
1342
  }), s;
1319
1343
  }
1320
1344
  }
1321
- class tt {
1345
+ class $ {
1322
1346
  static update(t, e, i) {
1323
- const s = A.getInstance().getConfig();
1347
+ const s = E.getInstance().getConfig();
1324
1348
  for (let a = t.length - 1; a >= 0; a--) {
1325
1349
  const l = t[a];
1326
1350
  if (l) {
@@ -1352,12 +1376,12 @@ class tt {
1352
1376
  }
1353
1377
  }
1354
1378
  }
1355
- class et {
1379
+ class X {
1356
1380
  static update(t, e, i, s, a, l, n, o, r, c) {
1357
1381
  for (const h of e) {
1358
1382
  if (!h.active || h.isGrabbed || h.isDying) continue;
1359
1383
  const u = t.position.x - h.position.x, p = t.position.y - h.position.y;
1360
- if (Math.hypot(u, p) <= t.radius + h.radius) {
1384
+ if (Math.hypot(u, p) <= t.getHitboxRadius() + h.radius) {
1361
1385
  if (h.active = !1, t.takeDamage()) {
1362
1386
  n.emit("onCoreDamaged", { currentIntegrity: t.integrity }), i.push({
1363
1387
  id: Math.random().toString(),
@@ -1369,15 +1393,15 @@ class et {
1369
1393
  lifetime: 0,
1370
1394
  maxLifetime: 0.8
1371
1395
  }), l.triggerScreenShake({ x: u, y: p }, 25), l.triggerHitstop(0.15), l.triggerFlash(0.6);
1372
- for (const g of e)
1373
- if (g.active && !g.isGrabbed) {
1374
- g.triggerDissolveDeath();
1375
- for (let f = 0; f < 8; f++) {
1376
- const x = Math.random() * Math.PI * 2, b = 100 + Math.random() * 200;
1396
+ for (const d of e)
1397
+ if (d.active && !d.isGrabbed) {
1398
+ d.triggerDissolveDeath();
1399
+ for (let m = 0; m < 8; m++) {
1400
+ const x = Math.random() * Math.PI * 2, A = 100 + Math.random() * 200;
1377
1401
  s.push({
1378
1402
  id: Math.random().toString(),
1379
- position: { ...g.position },
1380
- velocity: { x: Math.cos(x) * b, y: Math.sin(x) * b },
1403
+ position: { ...d.position },
1404
+ velocity: { x: Math.cos(x) * A, y: Math.sin(x) * A },
1381
1405
  color: "#00f0ff",
1382
1406
  radius: 3 + Math.random() * 3,
1383
1407
  alpha: 1,
@@ -1403,10 +1427,10 @@ class et {
1403
1427
  }
1404
1428
  }
1405
1429
  }
1406
- class it {
1430
+ class j {
1407
1431
  execute(t) {
1408
1432
  const { thrownEnemy: e, targetEnemy: i, shockwaves: s, particles: a, floatingTexts: l } = t;
1409
- i.active = !1, s.push({
1433
+ i.experienceDropPending = !0, i.active = !1, s.push({
1410
1434
  id: Math.random().toString(),
1411
1435
  position: { ...i.position },
1412
1436
  radius: 10,
@@ -1442,32 +1466,32 @@ class it {
1442
1466
  });
1443
1467
  }
1444
1468
  }
1445
- class st {
1469
+ class q {
1446
1470
  execute(t) {
1447
- const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: l, eventBus: n } = t, o = e.position;
1471
+ const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: l, eventBus: n } = t, o = e.position, r = E.getInstance().getConfig();
1448
1472
  i.push({
1449
1473
  id: Math.random().toString(),
1450
1474
  position: { ...o },
1451
- radius: 220,
1475
+ radius: Math.round(r.toxicPool.baseRadius * 2),
1452
1476
  duration: 0,
1453
- maxDuration: 7,
1454
- damage: 50
1477
+ maxDuration: r.toxicPool.baseDuration * 1.5,
1478
+ damage: r.toxicPool.damage
1455
1479
  }), s.push({
1456
1480
  id: Math.random().toString(),
1457
1481
  position: { ...o },
1458
1482
  radius: 10,
1459
- maxRadius: 240,
1483
+ maxRadius: Math.round(r.toxicPool.baseRadius * 2.2),
1460
1484
  color: "#39ff14",
1461
1485
  alpha: 1,
1462
1486
  lifetime: 0,
1463
1487
  maxLifetime: 0.6
1464
1488
  });
1465
- for (let r = 0; r < 45; r++) {
1466
- const c = Math.random() * Math.PI * 2, h = 120 + Math.random() * 260;
1489
+ for (let c = 0; c < 45; c++) {
1490
+ const h = Math.random() * Math.PI * 2, u = 120 + Math.random() * 260;
1467
1491
  a.push({
1468
1492
  id: Math.random().toString(),
1469
1493
  position: { ...o },
1470
- velocity: { x: Math.cos(c) * h, y: Math.sin(c) * h },
1494
+ velocity: { x: Math.cos(h) * u, y: Math.sin(h) * u },
1471
1495
  color: "#39ff14",
1472
1496
  radius: 4 + Math.random() * 5,
1473
1497
  alpha: 1,
@@ -1485,13 +1509,13 @@ class st {
1485
1509
  lifetime: 0,
1486
1510
  maxLifetime: 1.2,
1487
1511
  size: 26
1488
- }), e.active = !1, n.emit("onPoolCreated", { position: o });
1512
+ }), e.experienceDropPending = !0, e.active = !1, n.emit("onPoolCreated", { position: o });
1489
1513
  }
1490
1514
  }
1491
- class at {
1515
+ class Q {
1492
1516
  execute(t) {
1493
1517
  const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: n } = t, o = i.position;
1494
- e.active = !1, i.active = !1, a.push({
1518
+ e.experienceDropPending = !0, i.experienceDropPending = !0, e.active = !1, i.active = !1, a.push({
1495
1519
  id: Math.random().toString(),
1496
1520
  position: { ...o },
1497
1521
  radius: 15,
@@ -1501,30 +1525,30 @@ class at {
1501
1525
  lifetime: 0,
1502
1526
  maxLifetime: 0.6
1503
1527
  });
1504
- const r = A.getInstance().getConfig(), c = r.cluster.fragmentCount, h = r.cluster.hasHoming;
1528
+ const r = E.getInstance().getConfig(), c = r.cluster.fragmentCount, h = r.cluster.hasHoming;
1505
1529
  for (let u = 0; u < c; u++) {
1506
- const p = u * Math.PI * 2 / c, _ = 800 + Math.random() * 300, d = {
1530
+ const p = u * Math.PI * 2 / c, _ = 800 + Math.random() * 300, g = {
1507
1531
  x: o.x + Math.cos(p) * 45,
1508
1532
  y: o.y + Math.sin(p) * 45
1509
1533
  };
1510
- let g = p;
1534
+ let d = p;
1511
1535
  if (h) {
1512
- let x = null, b = 1 / 0;
1513
- for (const S of s) {
1514
- if (S === e || S === i || !S.active || S.isGrabbed || S.isDying) continue;
1515
- const I = Math.hypot(S.position.x - d.x, S.position.y - d.y);
1516
- I < b && (b = I, x = S);
1536
+ let x = null, A = 1 / 0;
1537
+ for (const b of s) {
1538
+ if (b === e || b === i || !b.active || b.isGrabbed || b.isDying) continue;
1539
+ const I = Math.hypot(b.position.x - g.x, b.position.y - g.y);
1540
+ I < A && (A = I, x = b);
1517
1541
  }
1518
- x && (g = Math.atan2(x.position.y - d.y, x.position.x - d.x));
1542
+ x && (d = Math.atan2(x.position.y - g.y, x.position.x - g.x));
1519
1543
  }
1520
- const f = M.createEnemy("micro", d, {
1521
- x: d.x + Math.cos(g) * 500,
1522
- y: d.y + Math.sin(g) * 500
1544
+ const m = M.createEnemy("micro", g, {
1545
+ x: g.x + Math.cos(d) * 500,
1546
+ y: g.y + Math.sin(d) * 500
1523
1547
  });
1524
- f.isThrown = !0, f.wasManipulated = !0, f.velocity = {
1525
- x: Math.cos(g) * _,
1526
- y: Math.sin(g) * _
1527
- }, s.push(f);
1548
+ m.isThrown = !0, m.wasManipulated = !0, m.velocity = {
1549
+ x: Math.cos(d) * _,
1550
+ y: Math.sin(d) * _
1551
+ }, s.push(m);
1528
1552
  }
1529
1553
  for (let u = 0; u < 35; u++) {
1530
1554
  const p = Math.random() * Math.PI * 2, _ = 200 + Math.random() * 300;
@@ -1552,51 +1576,49 @@ class at {
1552
1576
  });
1553
1577
  }
1554
1578
  }
1555
- class ot {
1579
+ class tt {
1556
1580
  execute(t) {
1557
- const { thrownEnemy: e, targetEnemy: i, vortices: s, shockwaves: a } = t, l = {
1581
+ const { thrownEnemy: e, targetEnemy: i, vortices: s, shockwaves: a } = t, l = E.getInstance().getConfig(), n = {
1558
1582
  x: (e.position.x + i.position.x) / 2,
1559
1583
  y: (e.position.y + i.position.y) / 2
1560
1584
  };
1561
1585
  s.push({
1562
1586
  id: Math.random().toString(),
1563
- position: l,
1564
- radius: 480,
1587
+ position: n,
1588
+ radius: Math.round(l.gravityVortex.baseRadius * 2.2),
1565
1589
  duration: 0,
1566
- maxDuration: 6,
1567
- pullForce: 3500
1590
+ maxDuration: l.gravityVortex.baseDuration * 1.5,
1591
+ pullForce: l.gravityVortex.basePullForce * 1.6
1568
1592
  }), a.push({
1569
1593
  id: Math.random().toString(),
1570
- position: l,
1594
+ position: n,
1571
1595
  radius: 20,
1572
- maxRadius: 480,
1596
+ maxRadius: Math.round(l.gravityVortex.baseRadius * 2.2),
1573
1597
  color: "#9d4edd",
1574
1598
  alpha: 1,
1575
1599
  lifetime: 0,
1576
1600
  maxLifetime: 0.65
1577
- }), e.triggerDissolveDeath(), i.triggerDissolveDeath();
1601
+ }), e.triggerDissolveDeath(!0), i.triggerDissolveDeath(!0);
1578
1602
  }
1579
1603
  }
1580
- class nt {
1604
+ class et {
1581
1605
  execute(t) {
1582
- const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: n } = t, o = i.position.x - e.position.x, r = i.position.y - e.position.y, c = Math.atan2(r, o), h = A.getInstance().getConfig().shield, u = h.blastSpeed || 1400;
1583
- if (e.isStationaryShield = !1, e.isThrown = !0, e.wasManipulated = !0, e.rotation = c, e.velocity = {
1584
- x: Math.cos(c) * u,
1585
- y: Math.sin(c) * u
1586
- }, h.isFanBlast) {
1587
- const p = [-Math.PI / 4, Math.PI / 4];
1588
- for (const _ of p) {
1589
- const d = c + _, g = M.createEnemy("heavy", {
1590
- x: e.position.x + Math.cos(d) * 30,
1591
- y: e.position.y + Math.sin(d) * 30
1592
- }, { x: 0, y: 0 });
1593
- g.isStationaryShield = !1, g.isThrown = !0, g.wasManipulated = !0, g.shieldAngle = d, g.rotation = d, g.velocity = {
1594
- x: Math.cos(d) * u,
1595
- y: Math.sin(d) * u
1596
- }, s.push(g);
1597
- }
1606
+ 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, p = h.isFanBlast ? [-Math.PI / 4, 0, Math.PI / 4] : [0];
1607
+ for (const _ of p) {
1608
+ const g = c + _, d = _ === 0 ? e : M.createEnemy(
1609
+ "heavy",
1610
+ {
1611
+ x: e.position.x + Math.cos(g) * 30,
1612
+ y: e.position.y + Math.sin(g) * 30
1613
+ },
1614
+ { x: 0, y: 0 }
1615
+ );
1616
+ d.isStationaryShield = !1, d.isThrown = !0, d.wasManipulated = !0, d.shieldAngle = g, d.rotation = g, d.velocity = {
1617
+ x: Math.cos(g) * u,
1618
+ y: Math.sin(g) * u
1619
+ }, d !== e && s.push(d);
1598
1620
  }
1599
- i.active = !1, i.triggerDissolveDeath(), n.push({
1621
+ i.active = !1, i.triggerDissolveDeath(!0), n.push({
1600
1622
  id: Math.random().toString(),
1601
1623
  text: "ARC BLAST!",
1602
1624
  position: { ...e.position },
@@ -1607,12 +1629,12 @@ class nt {
1607
1629
  maxLifetime: 0.9,
1608
1630
  size: 24
1609
1631
  });
1610
- for (let p = 0; p < 50; p++) {
1611
- const _ = (Math.random() - 0.5) * 1.5, d = c + _, g = 300 + Math.random() * 500;
1632
+ for (let _ = 0; _ < 50; _++) {
1633
+ const g = (Math.random() - 0.5) * 1.5, d = c + g, m = 300 + Math.random() * 500;
1612
1634
  l.push({
1613
1635
  id: Math.random().toString(),
1614
1636
  position: { ...e.position },
1615
- velocity: { x: Math.cos(d) * g, y: Math.sin(d) * g },
1637
+ velocity: { x: Math.cos(d) * m, y: Math.sin(d) * m },
1616
1638
  color: "#00f5ff",
1617
1639
  radius: 4 + Math.random() * 6,
1618
1640
  alpha: 1,
@@ -1635,24 +1657,24 @@ class nt {
1635
1657
  }
1636
1658
  class M {
1637
1659
  static createEnemy(t, e, i) {
1638
- const s = `enemy_${Date.now()}_${Math.random()}`, a = new H(s);
1660
+ const s = `enemy_${Date.now()}_${Math.random()}`, a = new D(s);
1639
1661
  return this.configureEnemy(a, t, e, i), a;
1640
1662
  }
1641
1663
  static configureEnemy(t, e, i, s) {
1642
1664
  t.type = e, t.position = { ...i }, t.active = !0, t.isGrabbed = !1, t.isThrown = !1;
1643
1665
  const a = s.x - i.x, l = s.y - i.y, n = Math.atan2(l, a);
1644
1666
  let o = 70, r = 100, c = 20, h = "#ff2a5f", u = null;
1645
- e === "piercer" ? (o = 95, r = 140, c = 18, h = "#ff2a5f", u = new it()) : e === "spore" ? (o = 65, r = 90, c = 24, h = "#39ff14", u = new st()) : e === "cluster" ? (o = 50, r = 75, c = 26, h = "#ffd700", u = new at()) : e === "parasite" ? (o = 80, r = 110, c = 22, h = "#9d4edd", u = new ot()) : e === "heavy" ? (o = 35, r = 50, c = 34, h = "#00f5ff", u = new nt(), 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 = {
1667
+ e === "piercer" ? (o = 95, r = 140, c = 18, h = "#ff2a5f", u = new j()) : 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 Q()) : e === "parasite" ? (o = 80, r = 110, c = 22, h = "#9d4edd", u = new tt()) : e === "heavy" ? (o = 35, r = 50, c = 34, h = "#00f5ff", u = new et(), 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 = {
1646
1668
  x: Math.cos(n) * o,
1647
1669
  y: Math.sin(n) * o
1648
1670
  };
1649
1671
  }
1650
1672
  }
1651
- class L {
1673
+ class T {
1652
1674
  static killEnemy(t, e, i, s, a, l) {
1653
1675
  if (!t.active || t.isDying) return;
1654
- const n = A.getInstance().getConfig();
1655
- if (a.push({
1676
+ const n = E.getInstance().getConfig();
1677
+ if (t.experienceDropPending = !0, a.push({
1656
1678
  id: Math.random().toString(),
1657
1679
  position: { ...t.position },
1658
1680
  radius: 10,
@@ -1662,7 +1684,7 @@ class L {
1662
1684
  lifetime: 0,
1663
1685
  maxLifetime: 0.5
1664
1686
  }), t.type === "spore")
1665
- t.triggerDissolveDeath(), i.push({
1687
+ t.triggerDissolveDeath(!0), i.push({
1666
1688
  id: Math.random().toString(),
1667
1689
  position: { ...t.position },
1668
1690
  radius: n.toxicPool.baseRadius,
@@ -1671,7 +1693,7 @@ class L {
1671
1693
  damage: n.toxicPool.damage
1672
1694
  });
1673
1695
  else if (t.type === "cluster") {
1674
- t.triggerDissolveDeath();
1696
+ t.triggerDissolveDeath(!0);
1675
1697
  const o = n.cluster.fragmentCount, r = n.cluster.hasHoming;
1676
1698
  for (let c = 0; c < o; c++) {
1677
1699
  const h = c * Math.PI * 2 / o, u = 750 + Math.random() * 250, p = {
@@ -1680,43 +1702,43 @@ class L {
1680
1702
  };
1681
1703
  let _ = h;
1682
1704
  if (r) {
1683
- let g = null, f = 1 / 0;
1705
+ let d = null, m = 1 / 0;
1684
1706
  for (const x of l) {
1685
1707
  if (x === t || !x.active || x.isGrabbed || x.isDying) continue;
1686
- const b = Math.hypot(x.position.x - p.x, x.position.y - p.y);
1687
- b < f && (f = b, g = x);
1708
+ const A = Math.hypot(x.position.x - p.x, x.position.y - p.y);
1709
+ A < m && (m = A, d = x);
1688
1710
  }
1689
- g && (_ = Math.atan2(g.position.y - p.y, g.position.x - p.x));
1711
+ d && (_ = Math.atan2(d.position.y - p.y, d.position.x - p.x));
1690
1712
  }
1691
- const d = M.createEnemy("micro", p, {
1713
+ const g = M.createEnemy("micro", p, {
1692
1714
  x: p.x + Math.cos(_) * 500,
1693
1715
  y: p.y + Math.sin(_) * 500
1694
1716
  });
1695
- d.isThrown = !0, d.wasManipulated = !0, d.velocity = {
1717
+ g.isThrown = !0, g.wasManipulated = !0, g.velocity = {
1696
1718
  x: Math.cos(_) * u,
1697
1719
  y: Math.sin(_) * u
1698
- }, l.push(d);
1720
+ }, l.push(g);
1699
1721
  }
1700
- } else t.type === "parasite" ? (t.triggerDissolveDeath(), s.push({
1722
+ } else t.type === "parasite" ? (t.triggerDissolveDeath(!0), s.push({
1701
1723
  id: Math.random().toString(),
1702
1724
  position: { ...t.position },
1703
1725
  radius: n.gravityVortex.baseRadius,
1704
1726
  duration: 0,
1705
1727
  maxDuration: n.gravityVortex.baseDuration,
1706
1728
  pullForce: n.gravityVortex.basePullForce
1707
- })) : t.type === "piercer" ? t.triggerSliceDeath(e) : t.triggerDissolveDeath();
1729
+ })) : t.type === "piercer" ? t.triggerSliceDeath(e, !0) : t.triggerDissolveDeath(!0);
1708
1730
  }
1709
1731
  }
1710
- class rt {
1732
+ class it {
1711
1733
  static update(t, e, i, s, a, l, n, o, r, c, h, u, p) {
1712
1734
  let _ = !1;
1713
- for (const d of t)
1714
- if (!(!d.active || !d.isThrown || d.isDying)) {
1715
- if (_ = !0, d.position.x < -120 || d.position.x > c + 120 || d.position.y < -120 || d.position.y > h + 120) {
1716
- if (d.type === "heavy") {
1735
+ for (const g of t)
1736
+ if (!(!g.active || !g.isThrown || g.isDying)) {
1737
+ if (_ = !0, g.position.x < -120 || g.position.x > c + 120 || g.position.y < -120 || g.position.y > h + 120) {
1738
+ if (g.type === "heavy") {
1717
1739
  s.push({
1718
1740
  id: Math.random().toString(),
1719
- position: { ...d.position },
1741
+ position: { ...g.position },
1720
1742
  radius: 20,
1721
1743
  maxRadius: 350,
1722
1744
  color: "#00f5ff",
@@ -1724,12 +1746,12 @@ class rt {
1724
1746
  lifetime: 0,
1725
1747
  maxLifetime: 0.6
1726
1748
  });
1727
- for (let g = 0; g < 40; g++) {
1728
- const f = Math.random() * Math.PI * 2, x = 250 + Math.random() * 450;
1749
+ for (let d = 0; d < 40; d++) {
1750
+ const m = Math.random() * Math.PI * 2, x = 250 + Math.random() * 450;
1729
1751
  a.push({
1730
1752
  id: Math.random().toString(),
1731
- position: { ...d.position },
1732
- velocity: { x: Math.cos(f) * x, y: Math.sin(f) * x },
1753
+ position: { ...g.position },
1754
+ velocity: { x: Math.cos(m) * x, y: Math.sin(m) * x },
1733
1755
  color: "#00f5ff",
1734
1756
  radius: 4 + Math.random() * 5,
1735
1757
  alpha: 1,
@@ -1737,15 +1759,15 @@ class rt {
1737
1759
  maxLifetime: 0.6
1738
1760
  });
1739
1761
  }
1740
- } else if (d.type === "piercer") {
1741
- const g = A.getInstance().getConfig().piercer;
1742
- if (g.terminalAoERadius > 0) {
1743
- const f = g.terminalAoERadius;
1762
+ } else if (g.type === "piercer") {
1763
+ const d = E.getInstance().getConfig().piercer;
1764
+ if (d.terminalAoERadius > 0) {
1765
+ const m = d.terminalAoERadius;
1744
1766
  s.push({
1745
1767
  id: Math.random().toString(),
1746
- position: { ...d.position },
1768
+ position: { ...g.position },
1747
1769
  radius: 20,
1748
- maxRadius: f,
1770
+ maxRadius: m,
1749
1771
  color: "#ff2a5f",
1750
1772
  alpha: 1,
1751
1773
  lifetime: 0,
@@ -1753,28 +1775,28 @@ class rt {
1753
1775
  });
1754
1776
  for (const x of t) {
1755
1777
  if (!x.active || x.isGrabbed || x.isDying) continue;
1756
- const b = x.position.x - d.position.x, S = x.position.y - d.position.y;
1757
- Math.hypot(b, S) <= f && L.killEnemy(x, Math.atan2(S, b), e, i, s, t);
1778
+ const A = x.position.x - g.position.x, b = x.position.y - g.position.y;
1779
+ Math.hypot(A, b) <= m && T.killEnemy(x, Math.atan2(b, A), e, i, s, t);
1758
1780
  }
1759
1781
  }
1760
1782
  }
1761
- d.active = !1, d.isThrown = !1;
1783
+ g.active = !1, g.isThrown = !1;
1762
1784
  continue;
1763
1785
  }
1764
- for (const g of t) {
1765
- if (g === d || !g.active || g.isGrabbed || g.isDying) continue;
1766
- const f = g.position.x - d.position.x, x = g.position.y - d.position.y;
1767
- if (Math.hypot(f, x) <= d.getHitRadius() + g.getHitRadius()) {
1768
- u.pos = { x: d.position.x, y: d.position.y };
1769
- const S = Math.atan2(d.velocity.y, d.velocity.x);
1770
- if (d.type === "heavy") {
1771
- u.kills++, L.killEnemy(g, d.rotation, e, i, s, t), n.triggerHitstop(0.04), n.triggerScreenShake({ x: f, y: x }, 8);
1786
+ for (const d of t) {
1787
+ if (d === g || !d.active || d.isGrabbed || d.isDying) continue;
1788
+ const m = d.position.x - g.position.x, x = d.position.y - g.position.y;
1789
+ if (Math.hypot(m, x) <= g.getHitRadius() + d.getHitRadius()) {
1790
+ u.pos = { x: g.position.x, y: g.position.y };
1791
+ const b = Math.atan2(g.velocity.y, g.velocity.x);
1792
+ if (g.type === "heavy") {
1793
+ u.kills++, T.killEnemy(d, g.rotation, e, i, s, t), n.triggerHitstop(0.04), n.triggerScreenShake({ x: m, y: x }, 8);
1772
1794
  for (let I = 0; I < 8; I++) {
1773
- const v = d.rotation + (Math.random() - 0.5), m = 200 + Math.random() * 350;
1795
+ const S = g.rotation + (Math.random() - 0.5), f = 200 + Math.random() * 350;
1774
1796
  a.push({
1775
1797
  id: Math.random().toString(),
1776
- position: { ...g.position },
1777
- velocity: { x: Math.cos(v) * m, y: Math.sin(v) * m },
1798
+ position: { ...d.position },
1799
+ velocity: { x: Math.cos(S) * f, y: Math.sin(S) * f },
1778
1800
  color: "#00f5ff",
1779
1801
  radius: 3 + Math.random() * 4,
1780
1802
  alpha: 1,
@@ -1783,10 +1805,10 @@ class rt {
1783
1805
  });
1784
1806
  }
1785
1807
  p && p();
1786
- } else if (d.type === "piercer") {
1787
- u.kills++, L.killEnemy(g, S, e, i, s, t), n.triggerHitstop(0.05), n.triggerScreenShake({ x: f, y: x }, 7), s.push({
1808
+ } else if (g.type === "piercer") {
1809
+ u.kills++, T.killEnemy(d, b, e, i, s, t), n.triggerHitstop(0.05), n.triggerScreenShake({ x: m, y: x }, 7), s.push({
1788
1810
  id: Math.random().toString(),
1789
- position: { ...g.position },
1811
+ position: { ...d.position },
1790
1812
  radius: 10,
1791
1813
  maxRadius: 180,
1792
1814
  color: "#ff2a5f",
@@ -1795,11 +1817,11 @@ class rt {
1795
1817
  maxLifetime: 0.45
1796
1818
  });
1797
1819
  for (let I = 0; I < 16; I++) {
1798
- const v = Math.random() * Math.PI * 2, m = 150 + Math.random() * 300;
1820
+ const S = Math.random() * Math.PI * 2, f = 150 + Math.random() * 300;
1799
1821
  a.push({
1800
1822
  id: Math.random().toString(),
1801
- position: { ...g.position },
1802
- velocity: { x: Math.cos(v) * m, y: Math.sin(v) * m },
1823
+ position: { ...d.position },
1824
+ velocity: { x: Math.cos(S) * f, y: Math.sin(S) * f },
1803
1825
  color: "#ff2a5f",
1804
1826
  radius: 3 + Math.random() * 3,
1805
1827
  alpha: 1,
@@ -1807,52 +1829,52 @@ class rt {
1807
1829
  maxLifetime: 0.4
1808
1830
  });
1809
1831
  }
1810
- if (d.remainingHomingKills > 0) {
1811
- d.remainingHomingKills--;
1812
- let I = null, v = 1 / 0;
1813
- for (const m of t) {
1814
- if (m === d || m === g || !m.active || m.isGrabbed || m.isDying) continue;
1815
- const y = m.position.x - d.position.x, T = m.position.y - d.position.y, R = Math.hypot(y, T);
1816
- R < v && (v = R, I = m);
1832
+ if (g.remainingHomingKills > 0) {
1833
+ g.remainingHomingKills--;
1834
+ let I = null, S = 1 / 0;
1835
+ for (const f of t) {
1836
+ if (f === g || f === d || !f.active || f.isGrabbed || f.isDying) continue;
1837
+ const v = f.position.x - g.position.x, L = f.position.y - g.position.y, w = Math.hypot(v, L);
1838
+ w < S && (S = w, I = f);
1817
1839
  }
1818
1840
  if (I) {
1819
- const m = Math.atan2(I.position.y - d.position.y, I.position.x - d.position.x), y = Math.hypot(d.velocity.x, d.velocity.y) || 1200;
1820
- d.rotation = m, d.velocity = {
1821
- x: Math.cos(m) * y,
1822
- y: Math.sin(m) * y
1841
+ const f = Math.atan2(I.position.y - g.position.y, I.position.x - g.position.x), v = Math.hypot(g.velocity.x, g.velocity.y) || 1200;
1842
+ g.rotation = f, g.velocity = {
1843
+ x: Math.cos(f) * v,
1844
+ y: Math.sin(f) * v
1823
1845
  };
1824
1846
  }
1825
1847
  }
1826
1848
  p && p();
1827
1849
  } else {
1828
- const I = d.type === g.type, v = I ? 360 : 250;
1850
+ const I = g.type === d.type, S = I ? 360 : 250;
1829
1851
  s.push({
1830
1852
  id: Math.random().toString(),
1831
1853
  position: { ...u.pos },
1832
1854
  radius: 15,
1833
- maxRadius: v,
1834
- color: d.color,
1855
+ maxRadius: S,
1856
+ color: g.color,
1835
1857
  alpha: 1,
1836
1858
  lifetime: 0,
1837
1859
  maxLifetime: 0.55
1838
1860
  });
1839
- for (let m = 0; m < 45; m++) {
1840
- const y = Math.random() * Math.PI * 2, T = 200 + Math.random() * 450;
1861
+ for (let f = 0; f < 45; f++) {
1862
+ const v = Math.random() * Math.PI * 2, L = 200 + Math.random() * 450;
1841
1863
  a.push({
1842
1864
  id: Math.random().toString(),
1843
1865
  position: { ...u.pos },
1844
- velocity: { x: Math.cos(y) * T, y: Math.sin(y) * T },
1845
- color: d.color,
1866
+ velocity: { x: Math.cos(v) * L, y: Math.sin(v) * L },
1867
+ color: g.color,
1846
1868
  radius: 4 + Math.random() * 6,
1847
1869
  alpha: 1,
1848
1870
  lifetime: 0,
1849
1871
  maxLifetime: 0.7
1850
1872
  });
1851
1873
  }
1852
- if (d.strategy) {
1853
- d.strategy.execute({
1854
- thrownEnemy: d,
1855
- targetEnemy: g,
1874
+ if (g.strategy) {
1875
+ g.strategy.execute({
1876
+ thrownEnemy: g,
1877
+ targetEnemy: d,
1856
1878
  allEnemies: t,
1857
1879
  pools: e,
1858
1880
  vortices: i,
@@ -1866,39 +1888,39 @@ class rt {
1866
1888
  break;
1867
1889
  }
1868
1890
  if (I) {
1869
- u.kills += 2, n.triggerHitstop(0.14), n.triggerFlash(0.5), n.triggerScreenShake({ x: f, y: x }, 16), l.push({
1891
+ u.kills += 2, n.triggerHitstop(0.14), n.triggerFlash(0.5), n.triggerScreenShake({ x: m, y: x }, 16), l.push({
1870
1892
  id: Math.random().toString(),
1871
1893
  text: "COLOR SYNERGY!",
1872
1894
  position: { ...u.pos },
1873
1895
  velocity: { x: 0, y: -80 },
1874
- color: d.color,
1896
+ color: g.color,
1875
1897
  alpha: 1,
1876
1898
  lifetime: 0,
1877
1899
  maxLifetime: 1.2,
1878
1900
  size: 26
1879
1901
  });
1880
- const m = A.getInstance().getConfig();
1881
- d.type === "spore" ? e.push({
1902
+ const f = E.getInstance().getConfig();
1903
+ g.type === "spore" ? e.push({
1882
1904
  id: Math.random().toString(),
1883
1905
  position: { ...u.pos },
1884
- radius: m.toxicPool.synergyRadius,
1906
+ radius: Math.round(f.toxicPool.baseRadius * 2),
1885
1907
  duration: 0,
1886
- maxDuration: m.toxicPool.synergyDuration,
1887
- damage: m.toxicPool.damage * 2
1888
- }) : d.type === "parasite" && i.push({
1908
+ maxDuration: f.toxicPool.synergyDuration,
1909
+ damage: f.toxicPool.damage * 2
1910
+ }) : g.type === "parasite" && i.push({
1889
1911
  id: Math.random().toString(),
1890
1912
  position: { ...u.pos },
1891
- radius: m.gravityVortex.synergyRadius,
1913
+ radius: Math.round(f.gravityVortex.baseRadius * 1.8),
1892
1914
  duration: 0,
1893
- maxDuration: m.gravityVortex.synergyDuration,
1894
- pullForce: m.gravityVortex.synergyPullForce
1895
- }), L.killEnemy(d, S, e, i, s, t), L.killEnemy(g, S, e, i, s, t);
1915
+ maxDuration: f.gravityVortex.synergyDuration,
1916
+ pullForce: f.gravityVortex.synergyPullForce
1917
+ }), T.killEnemy(g, b, e, i, s, t), T.killEnemy(d, b, e, i, s, t);
1896
1918
  } else
1897
- u.kills += 2, n.triggerHitstop(0.08), n.triggerFlash(0.35), n.triggerScreenShake({ x: f, y: x }, 10), L.killEnemy(d, S, e, i, s, t), L.killEnemy(g, S, e, i, s, t);
1898
- for (const m of t) {
1899
- if (m === d || m === g || !m.active || m.isGrabbed || m.isDying) continue;
1900
- const y = m.position.x - u.pos.x, T = m.position.y - u.pos.y;
1901
- Math.hypot(y, T) <= v && m.type !== "micro" && (L.killEnemy(m, S, e, i, s, t), u.kills++);
1919
+ u.kills += 2, n.triggerHitstop(0.08), n.triggerFlash(0.35), n.triggerScreenShake({ x: m, y: x }, 10), T.killEnemy(g, b, e, i, s, t), T.killEnemy(d, b, e, i, s, t);
1920
+ for (const f of t) {
1921
+ if (f === g || f === d || !f.active || f.isGrabbed || f.isDying) continue;
1922
+ const v = f.position.x - u.pos.x, L = f.position.y - u.pos.y;
1923
+ Math.hypot(v, L) <= S && f.type !== "micro" && (T.killEnemy(f, b, e, i, s, t), u.kills++);
1902
1924
  }
1903
1925
  p && p();
1904
1926
  break;
@@ -1919,7 +1941,7 @@ class rt {
1919
1941
  }), o.emit("onComboUpdated", { combo: r.value }), u.kills = 0, u.pos = null);
1920
1942
  }
1921
1943
  }
1922
- class lt {
1944
+ class st {
1923
1945
  static update(t, e, i, s, a, l, n, o) {
1924
1946
  for (let r = t.length - 1; r >= 0; r--) {
1925
1947
  const c = t[r];
@@ -1928,21 +1950,21 @@ class lt {
1928
1950
  for (const h of e) {
1929
1951
  if (!h.active || h.isGrabbed || h.isDying || h.isThrown && h.type === "piercer") continue;
1930
1952
  const u = h.position.x - c.position.x, p = h.position.y - c.position.y;
1931
- Math.hypot(u, p) <= c.radius && (L.killEnemy(h, 0, t, i, s, e), n.kills++, o && o());
1953
+ Math.hypot(u, p) <= c.radius && (T.killEnemy(h, 0, t, i, s, e), n.kills++, o && o());
1932
1954
  }
1933
1955
  c.duration >= c.maxDuration && t.splice(r, 1);
1934
1956
  }
1935
1957
  }
1936
1958
  }
1937
1959
  }
1938
- class ct {
1960
+ class at {
1939
1961
  static update(t, e, i, s, a, l, n, o, r, c, h, u) {
1940
1962
  for (const p of t)
1941
1963
  if (!(!p.active || !p.isStationaryShield || p.isDying))
1942
1964
  for (const _ of t) {
1943
1965
  if (_ === p || !_.active || _.isGrabbed || _.isDying) continue;
1944
- const d = _.position.x - p.position.x, g = _.position.y - p.position.y;
1945
- if (Math.hypot(d, g) <= p.getHitRadius() + _.getHitRadius()) {
1966
+ const g = _.position.x - p.position.x, d = _.position.y - p.position.y;
1967
+ if (Math.hypot(g, d) <= p.getHitRadius() + _.getHitRadius()) {
1946
1968
  p.isStationaryShield = !1, p.strategy && p.strategy.execute({
1947
1969
  thrownEnemy: p,
1948
1970
  targetEnemy: _,
@@ -1955,54 +1977,69 @@ class ct {
1955
1977
  eventBus: o,
1956
1978
  width: c,
1957
1979
  height: h
1958
- }), r.kills += 2, n.triggerHitstop(0.12), n.triggerScreenShake({ x: d, y: g }, 18), u && u();
1980
+ }), r.kills += 2, n.triggerHitstop(0.12), n.triggerScreenShake({ x: g, y: d }, 18), u && u();
1959
1981
  break;
1960
1982
  }
1961
1983
  }
1962
1984
  }
1963
1985
  }
1964
- class ht {
1986
+ class ot {
1965
1987
  spatialHash;
1966
1988
  eventBus;
1967
1989
  i18n;
1968
1990
  throwState = { kills: 0, pos: null };
1969
1991
  constructor(t, e) {
1970
- this.spatialHash = new j(100), this.eventBus = t, this.i18n = e;
1992
+ this.spatialHash = new Z(100), this.eventBus = t, this.i18n = e;
1971
1993
  }
1972
1994
  update(t, e, i, s, a, l, n, o, r, c, h, u, p, _) {
1973
1995
  this.spatialHash.clear();
1974
- const d = A.getInstance().getConfig().piercer;
1975
- for (const g of i)
1976
- if (g.active && !g.isDying) {
1977
- if (g.isThrown && g.type === "piercer" && d.hasHoming && g.remainingHomingKills > 0) {
1978
- let f = null, x = 1 / 0;
1979
- for (const b of i) {
1980
- if (b === g || !b.active || b.isGrabbed || b.isDying) continue;
1981
- const S = b.position.x - g.position.x, I = b.position.y - g.position.y, v = Math.hypot(S, I);
1982
- v < x && (x = v, f = b);
1996
+ const g = E.getInstance().getConfig().piercer;
1997
+ for (const d of i)
1998
+ if (d.active && !d.isDying) {
1999
+ if (d.isThrown && d.type === "piercer" && g.hasHoming && d.remainingHomingKills > 0) {
2000
+ let m = null, x = 1 / 0;
2001
+ for (const A of i) {
2002
+ if (A === d || !A.active || A.isGrabbed || A.isDying) continue;
2003
+ const b = A.position.x - d.position.x, I = A.position.y - d.position.y, S = Math.hypot(b, I);
2004
+ S < x && (x = S, m = A);
1983
2005
  }
1984
- if (f) {
1985
- const b = Math.atan2(f.position.y - g.position.y, f.position.x - g.position.x), S = Math.max(Math.hypot(g.velocity.x, g.velocity.y), 1e3), I = 25 * t, v = Math.atan2(g.velocity.y, g.velocity.x);
1986
- let m = b - v;
1987
- for (; m < -Math.PI; ) m += Math.PI * 2;
1988
- for (; m > Math.PI; ) m -= Math.PI * 2;
1989
- const y = v + Math.sign(m) * Math.min(Math.abs(m), I);
1990
- g.rotation = y, g.velocity = {
1991
- x: Math.cos(y) * S,
1992
- y: Math.sin(y) * S
2006
+ if (m) {
2007
+ const A = Math.atan2(m.position.y - d.position.y, m.position.x - d.position.x), b = Math.max(Math.hypot(d.velocity.x, d.velocity.y), 1e3), I = 25 * t, S = Math.atan2(d.velocity.y, d.velocity.x);
2008
+ let f = A - S;
2009
+ for (; f < -Math.PI; ) f += Math.PI * 2;
2010
+ for (; f > Math.PI; ) f -= Math.PI * 2;
2011
+ const v = S + Math.sign(f) * Math.min(Math.abs(f), I);
2012
+ d.rotation = v, d.velocity = {
2013
+ x: Math.cos(v) * b,
2014
+ y: Math.sin(v) * b
1993
2015
  };
1994
2016
  }
1995
2017
  }
1996
- g.update(t), this.spatialHash.insert(g);
1997
- } else g.active && g.isDying && g.update(t);
1998
- for (let g = l.length - 1; g >= 0; g--) {
1999
- const f = l[g];
2000
- if (!f) continue;
2001
- f.lifetime += t;
2002
- const x = f.lifetime / f.maxLifetime;
2003
- f.radius = f.maxRadius * x, f.alpha = Math.max(0, 1 - x), f.lifetime >= f.maxLifetime && l.splice(g, 1);
2004
- }
2005
- tt.update(a, i, t), et.update(
2018
+ if (d.isStationaryShield) {
2019
+ let m = null, x = 1 / 0;
2020
+ for (const A of i) {
2021
+ if (A === d || !A.active || A.isGrabbed || A.isDying || A.isStationaryShield) continue;
2022
+ const b = A.position.x - d.position.x, I = A.position.y - d.position.y, S = Math.hypot(b, I);
2023
+ S < x && (x = S, m = A);
2024
+ }
2025
+ if (m) {
2026
+ let b = Math.atan2(m.position.y - d.position.y, m.position.x - d.position.x) - d.rotation;
2027
+ for (; b < -Math.PI; ) b += Math.PI * 2;
2028
+ for (; b > Math.PI; ) b -= Math.PI * 2;
2029
+ const I = 5 * t;
2030
+ d.rotation += Math.sign(b) * Math.min(Math.abs(b), I);
2031
+ }
2032
+ }
2033
+ d.update(t), this.spatialHash.insert(d);
2034
+ } else d.active && d.isDying && d.update(t);
2035
+ for (let d = l.length - 1; d >= 0; d--) {
2036
+ const m = l[d];
2037
+ if (!m) continue;
2038
+ m.lifetime += t;
2039
+ const x = m.lifetime / m.maxLifetime;
2040
+ m.radius = m.maxRadius * x, m.alpha = Math.max(0, 1 - x), m.lifetime >= m.maxLifetime && l.splice(d, 1);
2041
+ }
2042
+ $.update(a, i, t), X.update(
2006
2043
  e,
2007
2044
  i,
2008
2045
  l,
@@ -2013,7 +2050,7 @@ class ht {
2013
2050
  h,
2014
2051
  u,
2015
2052
  p
2016
- ), rt.update(
2053
+ ), it.update(
2017
2054
  i,
2018
2055
  s,
2019
2056
  a,
@@ -2027,7 +2064,7 @@ class ht {
2027
2064
  p,
2028
2065
  this.throwState,
2029
2066
  _
2030
- ), lt.update(
2067
+ ), st.update(
2031
2068
  s,
2032
2069
  i,
2033
2070
  a,
@@ -2036,7 +2073,7 @@ class ht {
2036
2073
  t,
2037
2074
  this.throwState,
2038
2075
  _
2039
- ), ct.update(
2076
+ ), at.update(
2040
2077
  i,
2041
2078
  s,
2042
2079
  a,
@@ -2052,11 +2089,11 @@ class ht {
2052
2089
  );
2053
2090
  }
2054
2091
  }
2055
- class ut {
2092
+ class nt {
2056
2093
  pool = [];
2057
2094
  constructor(t = 500) {
2058
2095
  for (let e = 0; e < t; e++) {
2059
- const i = new H(`pool_enemy_${e}`);
2096
+ const i = new D(`pool_enemy_${e}`);
2060
2097
  this.pool.push(i);
2061
2098
  }
2062
2099
  }
@@ -2064,7 +2101,7 @@ class ut {
2064
2101
  for (const e of this.pool)
2065
2102
  if (!e.active)
2066
2103
  return e.reset(), e;
2067
- const t = new H(`fallback_enemy_${Date.now()}_${Math.random()}`);
2104
+ const t = new D(`fallback_enemy_${Date.now()}_${Math.random()}`);
2068
2105
  return this.pool.push(t), t;
2069
2106
  }
2070
2107
  resetAll() {
@@ -2072,7 +2109,7 @@ class ut {
2072
2109
  t.reset();
2073
2110
  }
2074
2111
  }
2075
- class C {
2112
+ class R {
2076
2113
  static getOffscreenPosition(t, e) {
2077
2114
  const i = Math.floor(Math.random() * 4), s = 70;
2078
2115
  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 };
@@ -2101,10 +2138,10 @@ class C {
2101
2138
  y: (Math.random() - 0.5) * 60
2102
2139
  }, h = { x: o.x + c.x, y: o.y + c.y }, u = t.get();
2103
2140
  M.configureEnemy(u, "spore", h, s);
2104
- const p = s.x - h.x, _ = s.y - h.y, d = Math.atan2(_, p);
2141
+ const p = s.x - h.x, _ = s.y - h.y, g = Math.atan2(_, p);
2105
2142
  u.velocity = {
2106
- x: Math.cos(d) * (50 + Math.random() * 20),
2107
- y: Math.sin(d) * (50 + Math.random() * 20)
2143
+ x: Math.cos(g) * (50 + Math.random() * 20),
2144
+ y: Math.sin(g) * (50 + Math.random() * 20)
2108
2145
  }, a.push(u);
2109
2146
  }
2110
2147
  return a;
@@ -2156,7 +2193,7 @@ class C {
2156
2193
  return a;
2157
2194
  }
2158
2195
  }
2159
- class pt {
2196
+ class rt {
2160
2197
  wave = 1;
2161
2198
  pool;
2162
2199
  spawnTimer = 0;
@@ -2164,7 +2201,7 @@ class pt {
2164
2201
  patternCooldown = 0;
2165
2202
  initialGracePeriod = 6;
2166
2203
  constructor() {
2167
- this.pool = new ut(500);
2204
+ this.pool = new nt(500);
2168
2205
  }
2169
2206
  reset() {
2170
2207
  this.wave = 1, this.spawnTimer = 0, this.waveTimer = 0, this.patternCooldown = 0;
@@ -2182,7 +2219,7 @@ class pt {
2182
2219
  return this.spawnTimer >= n && l < o ? (this.spawnTimer = 0, this.spawnSingleEnemy(i, s, a)) : null;
2183
2220
  }
2184
2221
  spawnSingleEnemy(t, e, i) {
2185
- const s = C.getOffscreenPosition(t, e), a = Math.random();
2222
+ const s = R.getOffscreenPosition(t, e), a = Math.random();
2186
2223
  let l = "piercer";
2187
2224
  a > 0.75 ? l = "heavy" : a > 0.55 ? l = "parasite" : a > 0.35 ? l = "cluster" : a > 0.15 && (l = "spore");
2188
2225
  const n = this.pool.get();
@@ -2190,7 +2227,7 @@ class pt {
2190
2227
  }
2191
2228
  spawnPatternFormation(t, e, i) {
2192
2229
  const s = Math.random();
2193
- 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);
2230
+ return s < 0.25 ? R.spawnCircleOfDeath(this.pool, i, t, e) : s < 0.5 ? R.spawnDenseCluster(this.pool, t, e, i) : s < 0.75 ? R.spawnSineSnake(this.pool, t, e, i) : R.spawnMarchingWall(this.pool, t, e, i);
2194
2231
  }
2195
2232
  applyFlockingBehaviors(t, e, i) {
2196
2233
  for (let a = 0; a < t.length; a++) {
@@ -2201,8 +2238,8 @@ class pt {
2201
2238
  if (a === p) continue;
2202
2239
  const _ = t[p];
2203
2240
  if (!_.active || _.isGrabbed || _.isDying) continue;
2204
- const d = l.position.x - _.position.x, g = l.position.y - _.position.y, f = Math.hypot(d, g);
2205
- f > 0 && f < 70 && (n += d / f, o += g / f, r++);
2241
+ const g = l.position.x - _.position.x, d = l.position.y - _.position.y, m = Math.hypot(g, d);
2242
+ m > 0 && m < 70 && (n += g / m, o += d / m, r++);
2206
2243
  }
2207
2244
  r > 0 && (n /= r, o /= r, l.velocity.x += n * 60 * e, l.velocity.y += o * 60 * e);
2208
2245
  const c = i.x - l.position.x, h = i.y - l.position.y, u = Math.hypot(c, h);
@@ -2220,7 +2257,47 @@ class pt {
2220
2257
  }
2221
2258
  }
2222
2259
  }
2223
- const O = {
2260
+ class lt {
2261
+ id;
2262
+ position;
2263
+ velocity;
2264
+ value;
2265
+ radius = 5;
2266
+ active = !0;
2267
+ isAbsorbing = !1;
2268
+ constructor(t, e = 1) {
2269
+ this.id = `xp_${Date.now()}_${Math.random()}`, this.position = { ...t }, this.value = e;
2270
+ const i = Math.random() * Math.PI * 2, s = 25 + Math.random() * 45;
2271
+ this.velocity = {
2272
+ x: Math.cos(i) * s,
2273
+ y: Math.sin(i) * s
2274
+ };
2275
+ }
2276
+ beginAbsorption() {
2277
+ this.active && (this.isAbsorbing = !0);
2278
+ }
2279
+ update(t, e, i, s) {
2280
+ if (this.active) {
2281
+ if (this.isAbsorbing) {
2282
+ const a = e.x - this.position.x, l = e.y - this.position.y, n = Math.hypot(a, l);
2283
+ if (n <= i + this.radius) {
2284
+ this.position = { ...e }, this.active = !1;
2285
+ return;
2286
+ }
2287
+ const o = Math.min(s + n * 0.7, 1600);
2288
+ this.velocity = {
2289
+ x: a / n * o,
2290
+ y: l / n * o
2291
+ };
2292
+ } else {
2293
+ const a = Math.pow(0.04, t);
2294
+ this.velocity.x *= a, this.velocity.y *= a;
2295
+ }
2296
+ this.position.x += this.velocity.x * t, this.position.y += this.velocity.y * t;
2297
+ }
2298
+ }
2299
+ }
2300
+ const C = {
2224
2301
  bioluminescent: {
2225
2302
  bgInner: "#081220",
2226
2303
  bgMid: "#050b16",
@@ -2235,7 +2312,13 @@ const O = {
2235
2312
  corePrimary: "#00f0ff",
2236
2313
  coreGlow: "rgba(0, 240, 255, 0.85)",
2237
2314
  tendrilMagenta: "#ff00dd",
2238
- tendrilCyan: "#00ffff"
2315
+ tendrilCyan: "#00ffff",
2316
+ effectHighlight: "#ffffff",
2317
+ effectInk: "#ffffff",
2318
+ effectShadow: "#000000",
2319
+ effectPanel: "rgba(0, 0, 0, 0.65)",
2320
+ vortexCore: "#000000",
2321
+ vortexMid: "#140028"
2239
2322
  },
2240
2323
  dark: {
2241
2324
  bgInner: "#0d0f17",
@@ -2251,7 +2334,13 @@ const O = {
2251
2334
  corePrimary: "#00b4d8",
2252
2335
  coreGlow: "rgba(0, 180, 216, 0.85)",
2253
2336
  tendrilMagenta: "#d800a6",
2254
- tendrilCyan: "#00b4d8"
2337
+ tendrilCyan: "#00b4d8",
2338
+ effectHighlight: "#ffffff",
2339
+ effectInk: "#ffffff",
2340
+ effectShadow: "#000000",
2341
+ effectPanel: "rgba(0, 0, 0, 0.65)",
2342
+ vortexCore: "#000000",
2343
+ vortexMid: "#140028"
2255
2344
  },
2256
2345
  light: {
2257
2346
  bgInner: "#f1f5f9",
@@ -2267,24 +2356,30 @@ const O = {
2267
2356
  corePrimary: "#0077b6",
2268
2357
  coreGlow: "rgba(0, 119, 182, 0.85)",
2269
2358
  tendrilMagenta: "#b5008c",
2270
- tendrilCyan: "#0077b6"
2271
- }
2272
- }, U = "axon_surge_theme";
2273
- class dt {
2359
+ tendrilCyan: "#0077b6",
2360
+ effectHighlight: "#fffaf2",
2361
+ effectInk: "#17324d",
2362
+ effectShadow: "#18334c",
2363
+ effectPanel: "rgba(255, 255, 255, 0.82)",
2364
+ vortexCore: "#274760",
2365
+ vortexMid: "#577c9e"
2366
+ }
2367
+ }, N = "axon_surge_theme";
2368
+ class ct {
2274
2369
  currentTheme = "dark";
2275
2370
  isExplicit = !1;
2276
2371
  targetElement;
2277
2372
  constructor(t, e) {
2278
2373
  e !== void 0 && (this.targetElement = e);
2279
2374
  try {
2280
- const i = localStorage.getItem(U);
2281
- if (i && O[i]) {
2375
+ const i = localStorage.getItem(N);
2376
+ if (i && C[i]) {
2282
2377
  this.currentTheme = i, this.isExplicit = !0, this.applyThemeToDOM();
2283
2378
  return;
2284
2379
  }
2285
2380
  } catch {
2286
2381
  }
2287
- if (t && O[t]) {
2382
+ if (t && C[t]) {
2288
2383
  this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
2289
2384
  return;
2290
2385
  }
@@ -2294,10 +2389,10 @@ class dt {
2294
2389
  this.targetElement = t, this.isExplicit ? this.applyThemeToDOM() : this.currentTheme = this.detectParentOrSystemTheme();
2295
2390
  }
2296
2391
  setTheme(t) {
2297
- if (O[t]) {
2392
+ if (C[t]) {
2298
2393
  this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
2299
2394
  try {
2300
- localStorage.setItem(U, t);
2395
+ localStorage.setItem(N, t);
2301
2396
  } catch {
2302
2397
  }
2303
2398
  }
@@ -2305,7 +2400,7 @@ class dt {
2305
2400
  clearExplicitTheme() {
2306
2401
  this.isExplicit = !1;
2307
2402
  try {
2308
- localStorage.removeItem(U);
2403
+ localStorage.removeItem(N);
2309
2404
  } catch {
2310
2405
  }
2311
2406
  this.removeThemeClasses(), this.currentTheme = this.detectParentOrSystemTheme();
@@ -2314,7 +2409,7 @@ class dt {
2314
2409
  return this.isExplicit || (this.currentTheme = this.detectParentOrSystemTheme()), this.currentTheme;
2315
2410
  }
2316
2411
  getPalette() {
2317
- return O[this.getTheme()] || O.dark;
2412
+ return C[this.getTheme()] || C.dark;
2318
2413
  }
2319
2414
  detectParentOrSystemTheme() {
2320
2415
  try {
@@ -2352,52 +2447,93 @@ class dt {
2352
2447
  this.targetElement.classList.add(t);
2353
2448
  }
2354
2449
  }
2355
- class gt {
2356
- maxDistance = 450;
2357
- maxThickness = 28;
2358
- minThickness = 4;
2359
- maxLength = 140;
2360
- minLength = 40;
2361
- render(t, e, i, s) {
2362
- for (const a of e) {
2363
- if (!a.active || a.isGrabbed || a.isDying) continue;
2364
- const l = a.position.x, n = a.position.y;
2365
- if (l >= 0 && l <= i && n >= 0 && n <= s) continue;
2366
- const o = Math.min(i, Math.max(0, l)), r = Math.min(s, Math.max(0, n)), c = Math.hypot(l - o, n - r);
2367
- if (c <= 0 || c > this.maxDistance) continue;
2368
- const h = Math.min(1, Math.max(0, c / this.maxDistance)), u = this.minThickness + (this.maxThickness - this.minThickness) * h, p = this.minLength + (this.maxLength - this.minLength) * h, _ = 0.35 + (1 - h) * 0.55;
2369
- if (t.save(), t.globalAlpha = _, t.shadowColor = a.color, t.shadowBlur = 12 + (1 - h) * 16, t.strokeStyle = a.color, t.lineWidth = u, t.lineCap = "round", t.beginPath(), o === 0 || o === i) {
2370
- const d = Math.max(0, r - p / 2), g = Math.min(s, r + p / 2);
2371
- t.moveTo(o, d), t.lineTo(o, g);
2450
+ class ht {
2451
+ maxDistance = 800;
2452
+ maxThickness = 18;
2453
+ minThickness = 5;
2454
+ maxLength = 110;
2455
+ minLength = 50;
2456
+ render(t, e, i, s, a) {
2457
+ for (const l of e) {
2458
+ if (!l.active || l.isGrabbed || l.isDying) continue;
2459
+ const n = l.position.x, o = l.position.y;
2460
+ if (n >= 0 && n <= i && o >= 0 && o <= s) continue;
2461
+ const r = Math.min(i, Math.max(0, n)), c = Math.min(s, Math.max(0, o)), h = Math.hypot(n - r, o - c);
2462
+ if (h <= 0 || h > this.maxDistance) continue;
2463
+ const u = Math.min(1, Math.max(0, h / this.maxDistance)), p = this.minThickness + (this.maxThickness - this.minThickness) * (1 - u), _ = this.minLength + (this.maxLength - this.minLength) * (1 - u), g = 0.55 + (1 - u) * 0.35;
2464
+ if (t.save(), t.globalAlpha = g, t.shadowColor = l.color, t.shadowBlur = 14, t.strokeStyle = l.color, t.lineWidth = p, t.lineCap = "round", t.beginPath(), r === 0 || r === i) {
2465
+ const d = Math.max(0, c - _ / 2), m = Math.min(s, c + _ / 2);
2466
+ t.moveTo(r, d), t.lineTo(r, m);
2372
2467
  } else {
2373
- const d = Math.max(0, o - p / 2), g = Math.min(i, o + p / 2);
2374
- t.moveTo(d, r), t.lineTo(g, r);
2468
+ const d = Math.max(0, r - _ / 2), m = Math.min(i, r + _ / 2);
2469
+ t.moveTo(d, c), t.lineTo(m, c);
2375
2470
  }
2376
- t.stroke(), t.strokeStyle = "#ffffff", t.lineWidth = Math.max(1.5, u * 0.25), t.globalAlpha = _ * 0.8, t.stroke(), t.restore();
2471
+ t.stroke(), t.strokeStyle = a.effectHighlight, t.lineWidth = Math.max(1.8, p * 0.28), t.globalAlpha = g * 0.9, t.stroke(), t.restore();
2377
2472
  }
2378
2473
  }
2379
2474
  }
2380
- class _t {
2381
- render(t, e, i, s, a, l = !1) {
2382
- const n = (210 + (a - 1) * 38 + Math.sin(s * 0.12) * 15) % 360;
2383
- if (l) {
2384
- const S = `hsl(${n}, 50%, 94%)`, I = `hsl(${(n + 25) % 360}, 45%, 89%)`, v = `hsl(${(n + 50) % 360}, 40%, 82%)`, m = t.createRadialGradient(e / 2, i / 2, 40, e / 2, i / 2, Math.max(e, i));
2385
- m.addColorStop(0, S), m.addColorStop(0.55, I), m.addColorStop(1, v), t.fillStyle = m, t.fillRect(0, 0, e, i);
2386
- const y = (n + 75) % 360, T = e * 0.35 + Math.sin(s * 0.25) * 70, R = i * 0.45 + Math.cos(s * 0.2) * 60, D = t.createRadialGradient(T, R, 20, T, R, 400);
2387
- D.addColorStop(0, `hsla(${y}, 65%, 78%, 0.35)`), D.addColorStop(1, "rgba(255, 255, 255, 0)"), t.fillStyle = D, t.beginPath(), t.arc(T, R, 400, 0, Math.PI * 2), t.fill();
2388
- const Z = (n + 160) % 360, w = e * 0.68 + Math.cos(s * 0.28) * 60, k = i * 0.55 + Math.sin(s * 0.22) * 55, G = t.createRadialGradient(w, k, 20, w, k, 440);
2389
- G.addColorStop(0, `hsla(${Z}, 60%, 75%, 0.3)`), G.addColorStop(1, "rgba(255, 255, 255, 0)"), t.fillStyle = G, t.beginPath(), t.arc(w, k, 440, 0, Math.PI * 2), t.fill();
2390
- return;
2475
+ class ut {
2476
+ render(t, e, i, s, a, l, n = !1) {
2477
+ 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), p = e / 2, _ = i / 2, g = Math.max(e, i) * 0.82, d = t.createRadialGradient(p, _, 20, p, _, g);
2478
+ n ? (d.addColorStop(0, `hsl(${c}, 42%, 91%)`), d.addColorStop(0.42, `hsl(${h}, 42%, 86%)`), d.addColorStop(0.78, `hsl(${u}, 38%, 81%)`), d.addColorStop(1, l.bgOuter)) : (d.addColorStop(0, `hsl(${c}, 42%, 11%)`), d.addColorStop(0.42, `hsl(${h}, 48%, 8%)`), d.addColorStop(0.78, `hsl(${u}, 42%, 5%)`), d.addColorStop(1, `hsl(${u}, 48%, 2.5%)`)), t.fillStyle = d, t.fillRect(0, 0, e, i);
2479
+ const m = Math.min(e, i) * 0.055;
2480
+ this.drawNebula(
2481
+ t,
2482
+ e * 0.22 + Math.sin(s * 0.18) * m,
2483
+ i * 0.28 + Math.cos(s * 0.15) * m,
2484
+ Math.max(e, i) * 0.42,
2485
+ c,
2486
+ n ? 0.27 : 0.23,
2487
+ n
2488
+ ), this.drawNebula(
2489
+ t,
2490
+ e * 0.8 + Math.cos(s * 0.14) * m,
2491
+ i * 0.7 + Math.sin(s * 0.17) * m,
2492
+ Math.max(e, i) * 0.48,
2493
+ h,
2494
+ n ? 0.23 : 0.2,
2495
+ n
2496
+ ), this.drawNebula(
2497
+ t,
2498
+ e * 0.86 + Math.sin(s * 0.11) * m * 0.7,
2499
+ i * 0.16 + Math.cos(s * 0.13) * m * 0.7,
2500
+ Math.max(e, i) * 0.3,
2501
+ u,
2502
+ n ? 0.17 : 0.14,
2503
+ n
2504
+ ), this.drawSoftFlows(t, e, i, s, c, r, n), this.drawParticleField(t, e, i, s, c, h, o, n);
2505
+ const x = t.createRadialGradient(p, _, Math.min(e, i) * 0.28, p, _, g);
2506
+ x.addColorStop(0, "rgba(0, 0, 0, 0)"), x.addColorStop(1, n ? "rgba(40, 60, 90, 0.09)" : "rgba(0, 0, 0, 0.2)"), t.fillStyle = x, t.fillRect(0, 0, e, i);
2507
+ }
2508
+ drawNebula(t, e, i, s, a, l, n) {
2509
+ const o = t.createRadialGradient(e, i, 0, e, i, s), r = n ? 52 : 60;
2510
+ 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();
2511
+ }
2512
+ drawSoftFlows(t, e, i, s, a, l, n) {
2513
+ t.save();
2514
+ const o = Math.min(e, i), r = o * 0.035;
2515
+ 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)`;
2516
+ for (let c = 0; c < 3; c++) {
2517
+ const h = (c - 1) * o * 0.075 + Math.sin(s * 0.06 + c) * r, u = c * 28 + l * 18;
2518
+ 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();
2391
2519
  }
2392
- const o = `hsl(${n}, 45%, 8%)`, r = `hsl(${(n + 30) % 360}, 40%, 4%)`, c = `hsl(${(n + 60) % 360}, 50%, 2%)`, h = t.createRadialGradient(e / 2, i / 2, 40, e / 2, i / 2, Math.max(e, i));
2393
- h.addColorStop(0, o), h.addColorStop(0.55, r), h.addColorStop(1, c), t.fillStyle = h, t.fillRect(0, 0, e, i);
2394
- const u = (n + 75) % 360, p = e * 0.35 + Math.sin(s * 0.25) * 70, _ = i * 0.45 + Math.cos(s * 0.2) * 60, d = t.createRadialGradient(p, _, 20, p, _, 400);
2395
- d.addColorStop(0, `hsla(${u}, 65%, 12%, 0.35)`), d.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = d, t.beginPath(), t.arc(p, _, 400, 0, Math.PI * 2), t.fill();
2396
- const g = (n + 160) % 360, f = e * 0.68 + Math.cos(s * 0.28) * 60, x = i * 0.55 + Math.sin(s * 0.22) * 55, b = t.createRadialGradient(f, x, 20, f, x, 440);
2397
- b.addColorStop(0, `hsla(${g}, 60%, 10%, 0.3)`), b.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = b, t.beginPath(), t.arc(f, x, 440, 0, Math.PI * 2), t.fill();
2520
+ t.restore();
2521
+ }
2522
+ drawParticleField(t, e, i, s, a, l, n, o) {
2523
+ const r = 44 + Math.min(24, n * 2), c = e / 2, h = i / 2, u = Math.min(e, i) * 0.17;
2524
+ for (let p = 0; p < r; p++) {
2525
+ const _ = p + n * 17, g = this.unitNoise(_ * 1.7) * e, d = this.unitNoise(_ * 2.9 + 13) * i, m = Math.hypot(g - c, d - h), x = Math.min(1, Math.max(0, (m - u) / (Math.min(e, i) * 0.28))), A = 0.7 + Math.sin(s * (0.6 + p % 4 * 0.08) + _) * 0.3, b = (o ? 0.34 : 0.3) * x * A, I = 0.65 + p % 3 * 0.45;
2526
+ t.fillStyle = `hsla(${p % 3 === 0 ? l : a}, ${o ? 82 : 78}%, ${o ? 40 : 70}%, ${b})`, t.beginPath(), t.arc(g, d, I, 0, Math.PI * 2), t.fill();
2527
+ }
2528
+ }
2529
+ unitNoise(t) {
2530
+ return (Math.sin(t * 12.9898) * 43758.5453 % 1 + 1) % 1;
2531
+ }
2532
+ wrapHue(t) {
2533
+ return (t % 360 + 360) % 360;
2398
2534
  }
2399
2535
  }
2400
- class mt {
2536
+ class pt {
2401
2537
  render(t, e, i) {
2402
2538
  if (!e.isActive) return;
2403
2539
  const s = e.getLauncher(), a = e.getTarget();
@@ -2422,7 +2558,7 @@ class mt {
2422
2558
  t.restore();
2423
2559
  }
2424
2560
  }
2425
- class ft {
2561
+ class dt {
2426
2562
  canvas;
2427
2563
  ctx;
2428
2564
  themeManager;
@@ -2430,12 +2566,30 @@ class ft {
2430
2566
  bgRenderer;
2431
2567
  tutorialArrowRenderer;
2432
2568
  constructor(t, e) {
2433
- this.canvas = t, this.ctx = t.getContext("2d"), this.themeManager = e, this.indicatorRenderer = new gt(), this.bgRenderer = new _t(), this.tutorialArrowRenderer = new mt();
2569
+ this.canvas = t, this.ctx = t.getContext("2d"), this.themeManager = e, this.indicatorRenderer = new ht(), this.bgRenderer = new ut(), this.tutorialArrowRenderer = new pt();
2434
2570
  }
2435
- render(t, e, i, s, a, l, n, o, r, c, h = 1, u) {
2571
+ render(t, e, i, s, a, l, n, o, r, c, h, u = 1, p) {
2436
2572
  if (!this.ctx) return;
2437
- const p = this.themeManager.getPalette(), { width: _, height: d } = this.canvas, g = o.getShakeOffset();
2438
- this.ctx.save(), this.ctx.translate(g.x, g.y), this.bgRenderer.render(this.ctx, _, d, t.pulsePhase, h, this.themeManager.getTheme() === "light"), this.drawToxicPools(i, t.pulsePhase), this.drawGravityVortices(s, t.pulsePhase), this.drawShockwaves(a), this.drawCoreFilaments(t, p), this.drawParticles(l), this.indicatorRenderer.render(this.ctx, e, _, d), this.drawOrganicEnemies(e, t.pulsePhase, p), u && this.tutorialArrowRenderer.render(this.ctx, u, t.pulsePhase), r ? this.drawPsionicTendril(t.position, r.position, p) : t && this.drawHoverTendril(t.position, c, e, p), this.drawOrganicConsciousnessCore(t, p), this.drawFloatingTexts(n), o.flashAlpha > 0 && (this.ctx.fillStyle = `rgba(255, 255, 255, ${o.flashAlpha})`, this.ctx.fillRect(0, 0, _, d)), this.ctx.restore();
2573
+ const _ = this.themeManager.getPalette(), { width: g, height: d } = this.canvas, m = r.getShakeOffset();
2574
+ this.ctx.save(), this.ctx.translate(m.x, m.y), this.bgRenderer.render(
2575
+ this.ctx,
2576
+ g,
2577
+ d,
2578
+ t.pulsePhase,
2579
+ u,
2580
+ _,
2581
+ this.themeManager.getTheme() === "light"
2582
+ ), 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, g, d, _), this.drawOrganicEnemies(e, t.pulsePhase, _), p && this.tutorialArrowRenderer.render(this.ctx, p, 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, g, d)), this.ctx.restore();
2583
+ }
2584
+ drawExperienceOrbs(t, e, i, s) {
2585
+ if (this.ctx)
2586
+ for (const a of t) {
2587
+ if (!a.active) continue;
2588
+ const l = a.radius + Math.sin(i * 7 + a.position.x * 0.01) * 0.8, { x: n, y: o } = a.position;
2589
+ 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);
2590
+ const r = this.ctx.createRadialGradient(n - 1, o - 1, 1, n, o, l * 1.6);
2591
+ 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();
2592
+ }
2439
2593
  }
2440
2594
  drawToxicPools(t, e) {
2441
2595
  if (this.ctx)
@@ -2446,50 +2600,52 @@ class ft {
2446
2600
  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();
2447
2601
  const r = 70;
2448
2602
  for (let c = 0; c <= r; c++) {
2449
- const h = c * Math.PI * 2 / r, u = Math.sin(h * 5 + e * 3) * 14, p = Math.cos(h * 3 - e * 2) * 9, _ = i.radius + u + p, d = l + Math.cos(h) * _, g = n + Math.sin(h) * _;
2450
- c === 0 ? this.ctx.moveTo(d, g) : this.ctx.lineTo(d, g);
2603
+ const h = c * Math.PI * 2 / r, u = Math.sin(h * 5 + e * 3) * 14, p = Math.cos(h * 3 - e * 2) * 9, _ = i.radius + u + p, g = l + Math.cos(h) * _, d = n + Math.sin(h) * _;
2604
+ c === 0 ? this.ctx.moveTo(g, d) : this.ctx.lineTo(g, d);
2451
2605
  }
2452
2606
  this.ctx.closePath(), this.ctx.fill(), this.ctx.strokeStyle = `rgba(57, 255, 20, ${a * 0.8})`, this.ctx.lineWidth = 2.5, this.ctx.beginPath();
2453
2607
  for (let c = 0; c <= r; c++) {
2454
- const h = c * Math.PI * 2 / r, u = Math.sin(h * 6 + e * 4) * 8, p = i.radius * 0.75 + u, _ = l + Math.cos(h) * p, d = n + Math.sin(h) * p;
2455
- c === 0 ? this.ctx.moveTo(_, d) : this.ctx.lineTo(_, d);
2608
+ const h = c * Math.PI * 2 / r, u = Math.sin(h * 6 + e * 4) * 8, p = i.radius * 0.75 + u, _ = l + Math.cos(h) * p, g = n + Math.sin(h) * p;
2609
+ c === 0 ? this.ctx.moveTo(_, g) : this.ctx.lineTo(_, g);
2456
2610
  }
2457
2611
  this.ctx.closePath(), this.ctx.stroke();
2458
2612
  for (let c = 0; c < 6; c++) {
2459
- const h = c * Math.PI * 0.33 + e * 1.5, u = i.radius * 0.5 * (0.3 + Math.sin(e * 2 + c) * 0.3), p = l + Math.cos(h) * u, _ = n + Math.sin(h) * u, d = 3 + Math.sin(e * 3 + c) * 2;
2460
- this.ctx.fillStyle = `rgba(255, 255, 255, ${a * 0.8})`, this.ctx.beginPath(), this.ctx.arc(p, _, Math.max(1, d), 0, Math.PI * 2), this.ctx.fill();
2613
+ const h = c * Math.PI * 0.33 + e * 1.5, u = i.radius * 0.5 * (0.3 + Math.sin(e * 2 + c) * 0.3), p = l + Math.cos(h) * u, _ = n + Math.sin(h) * u, g = 3 + Math.sin(e * 3 + c) * 2;
2614
+ this.ctx.fillStyle = `rgba(255, 255, 255, ${a * 0.8})`, this.ctx.beginPath(), this.ctx.arc(p, _, Math.max(1, g), 0, Math.PI * 2), this.ctx.fill();
2461
2615
  }
2462
2616
  this.ctx.restore();
2463
2617
  }
2464
2618
  }
2465
2619
  drawShockwaves(t) {
2466
- if (this.ctx)
2467
- for (const e of t) {
2468
- this.ctx.save(), this.ctx.globalAlpha = e.alpha;
2469
- const i = this.ctx.createRadialGradient(
2470
- e.position.x,
2471
- e.position.y,
2472
- 0,
2473
- e.position.x,
2474
- e.position.y,
2475
- e.radius
2476
- );
2477
- i.addColorStop(0, "rgba(255, 255, 255, 0.4)"), i.addColorStop(0.7, e.color), i.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = i, this.ctx.beginPath(), this.ctx.arc(e.position.x, e.position.y, e.radius, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = "#ffffff", this.ctx.lineWidth = 4, this.ctx.shadowColor = e.color, this.ctx.shadowBlur = 24, this.ctx.beginPath(), this.ctx.arc(e.position.x, e.position.y, e.radius, 0, Math.PI * 2), this.ctx.stroke(), this.ctx.restore();
2478
- }
2620
+ if (!this.ctx) return;
2621
+ const e = this.themeManager.getTheme() === "light";
2622
+ for (const i of t) {
2623
+ this.ctx.save(), this.ctx.globalAlpha = i.alpha;
2624
+ const s = this.ctx.createRadialGradient(
2625
+ i.position.x,
2626
+ i.position.y,
2627
+ 0,
2628
+ i.position.x,
2629
+ i.position.y,
2630
+ i.radius
2631
+ );
2632
+ s.addColorStop(0, e ? "rgba(255, 255, 255, 0.72)" : "rgba(255, 255, 255, 0.4)"), s.addColorStop(0.7, i.color), s.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = s, this.ctx.beginPath(), this.ctx.arc(i.position.x, i.position.y, i.radius, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = e ? i.color : "#ffffff", this.ctx.lineWidth = 4, this.ctx.shadowColor = i.color, this.ctx.shadowBlur = 24, this.ctx.beginPath(), this.ctx.arc(i.position.x, i.position.y, i.radius, 0, Math.PI * 2), this.ctx.stroke(), this.ctx.restore();
2633
+ }
2479
2634
  }
2480
2635
  drawGravityVortices(t, e) {
2481
- if (this.ctx)
2482
- for (const i of t) {
2483
- const s = Math.min(0.85, (1 - i.duration / i.maxDuration) * 0.85), a = i.radius * (1 - i.duration / i.maxDuration * 0.1), { x: l, y: n } = i.position;
2484
- this.ctx.save();
2485
- const o = this.ctx.createRadialGradient(l, n, 0, l, n, 60);
2486
- o.addColorStop(0, `rgba(0, 0, 0, ${s})`), o.addColorStop(0.7, `rgba(20, 0, 40, ${s})`), o.addColorStop(1, `rgba(157, 78, 221, ${s * 0.5})`), this.ctx.fillStyle = o, this.ctx.beginPath(), this.ctx.arc(l, n, 60, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = `rgba(157, 78, 221, ${s})`, this.ctx.lineWidth = 5, this.ctx.shadowColor = "#9d4edd", this.ctx.shadowBlur = 32;
2487
- for (let r = 1; r <= 5; r++) {
2488
- const c = a * r / 5, h = e * r * 2.2;
2489
- this.ctx.beginPath(), this.ctx.arc(l, n, c, h, h + Math.PI * 1.5), this.ctx.stroke();
2490
- }
2491
- this.ctx.restore();
2636
+ if (!this.ctx) return;
2637
+ const i = this.themeManager.getPalette();
2638
+ for (const s of t) {
2639
+ 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;
2640
+ this.ctx.save();
2641
+ const r = this.ctx.createRadialGradient(n, o, 0, n, o, 60);
2642
+ 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;
2643
+ for (let c = 1; c <= 5; c++) {
2644
+ const h = l * c / 5, u = e * c * 2.2;
2645
+ this.ctx.beginPath(), this.ctx.arc(n, o, h, u, u + Math.PI * 1.5), this.ctx.stroke();
2492
2646
  }
2647
+ this.ctx.restore();
2648
+ }
2493
2649
  }
2494
2650
  drawFluidCosmosBackground(t, e, i, s) {
2495
2651
  if (!this.ctx) return;
@@ -2502,11 +2658,13 @@ class ft {
2502
2658
  }
2503
2659
  drawCoreFilaments(t, e) {
2504
2660
  if (!this.ctx) return;
2505
- const i = 12;
2506
- this.ctx.lineWidth = 1.5, this.ctx.strokeStyle = e.nebulaCyan;
2661
+ const i = t.powerUpCount;
2662
+ this.ctx.lineWidth = 1.5;
2507
2663
  for (let s = 0; s < i; s++) {
2508
- const a = s * Math.PI * 2 / i + t.pulsePhase * 0.12, l = 85 + Math.sin(t.pulsePhase * 1.5 + s) * 25, n = t.position.x + Math.cos(a) * l, o = t.position.y + Math.sin(a) * l, r = t.position.x + Math.cos(a + 0.4) * 48, c = t.position.y + Math.sin(a + 0.4) * 48;
2509
- this.ctx.beginPath(), this.ctx.moveTo(t.position.x, t.position.y), this.ctx.quadraticCurveTo(r, c, n, o), this.ctx.stroke(), this.ctx.fillStyle = e.sporeColor, this.ctx.beginPath(), this.ctx.arc(n, o, 3.5, 0, Math.PI * 2), this.ctx.fill();
2664
+ const a = t.collectedPowerUpColors[s] || e.nebulaCyan;
2665
+ this.ctx.strokeStyle = a;
2666
+ 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;
2667
+ 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();
2510
2668
  }
2511
2669
  }
2512
2670
  drawOrganicConsciousnessCore(t, e) {
@@ -2522,8 +2680,8 @@ class ft {
2522
2680
  this.ctx.strokeStyle = a, this.ctx.lineWidth = 2.2, this.ctx.shadowColor = a, this.ctx.shadowBlur = 12, this.ctx.beginPath();
2523
2681
  const h = 60;
2524
2682
  for (let u = 0; u <= h; u++) {
2525
- const p = u * Math.PI * 2 / h, _ = c + Math.sin(p * 4 + t.pulsePhase * 2 + r) * 3, d = i + Math.cos(p) * _, g = s + Math.sin(p) * _;
2526
- u === 0 ? this.ctx.moveTo(d, g) : this.ctx.lineTo(d, g);
2683
+ const p = u * Math.PI * 2 / h, _ = c + Math.sin(p * 4 + t.pulsePhase * 2 + r) * 3, g = i + Math.cos(p) * _, d = s + Math.sin(p) * _;
2684
+ u === 0 ? this.ctx.moveTo(g, d) : this.ctx.lineTo(g, d);
2527
2685
  }
2528
2686
  this.ctx.closePath(), this.ctx.stroke();
2529
2687
  }
@@ -2532,8 +2690,8 @@ class ft {
2532
2690
  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();
2533
2691
  const h = 60;
2534
2692
  for (let u = 0; u <= h; u++) {
2535
- const p = u * Math.PI * 2 / h, _ = c + Math.sin(p * 4 + t.pulsePhase * 2 + r) * 3, d = i + Math.cos(p) * _, g = s + Math.sin(p) * _;
2536
- u === 0 ? this.ctx.moveTo(d, g) : this.ctx.lineTo(d, g);
2693
+ const p = u * Math.PI * 2 / h, _ = c + Math.sin(p * 4 + t.pulsePhase * 2 + r) * 3, g = i + Math.cos(p) * _, d = s + Math.sin(p) * _;
2694
+ u === 0 ? this.ctx.moveTo(g, d) : this.ctx.lineTo(g, d);
2537
2695
  }
2538
2696
  this.ctx.closePath(), this.ctx.stroke(), this.ctx.restore();
2539
2697
  }
@@ -2547,15 +2705,15 @@ class ft {
2547
2705
  this.ctx.closePath(), this.ctx.fill(), this.ctx.stroke();
2548
2706
  const o = t.powerUpCount;
2549
2707
  if (o > 0) {
2550
- this.ctx.strokeStyle = "#ffffff", this.ctx.lineWidth = 1.8, this.ctx.shadowColor = a, this.ctx.shadowBlur = 10;
2708
+ this.ctx.strokeStyle = e.effectHighlight, this.ctx.lineWidth = 1.8, this.ctx.shadowColor = a, this.ctx.shadowBlur = 10;
2551
2709
  for (let r = 0; r < o; r++) {
2552
2710
  const c = r * Math.PI * 2 / o + t.pulsePhase * 0.4, h = t.radius * (0.45 + Math.sin(t.pulsePhase * 2 + r) * 0.15);
2553
2711
  this.ctx.beginPath(), this.ctx.moveTo(0, 0);
2554
- const u = Math.cos(c + Math.sin(t.pulsePhase + r) * 0.4) * (h * 0.6), p = Math.sin(c + Math.cos(t.pulsePhase + r) * 0.4) * (h * 0.6), _ = Math.cos(c) * h, d = Math.sin(c) * h;
2555
- this.ctx.quadraticCurveTo(u, p, _, d), this.ctx.stroke(), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(_, d, 2.5, 0, Math.PI * 2), this.ctx.fill();
2712
+ const u = Math.cos(c + Math.sin(t.pulsePhase + r) * 0.4) * (h * 0.6), p = Math.sin(c + Math.cos(t.pulsePhase + r) * 0.4) * (h * 0.6), _ = Math.cos(c) * h, g = Math.sin(c) * h;
2713
+ this.ctx.quadraticCurveTo(u, p, _, g), this.ctx.stroke(), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(_, g, 2.5, 0, Math.PI * 2), this.ctx.fill();
2556
2714
  }
2557
2715
  }
2558
- this.ctx.fillStyle = "#ffffff", 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();
2716
+ 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();
2559
2717
  }
2560
2718
  drawPsionicTendril(t, e, i) {
2561
2719
  if (!this.ctx) return;
@@ -2566,7 +2724,7 @@ class ft {
2566
2724
  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();
2567
2725
  for (let o = 0; o < 6; o++) {
2568
2726
  const r = Math.random(), c = t.x + s * r + (Math.random() - 0.5) * 24, h = t.y + a * r + (Math.random() - 0.5) * 24;
2569
- this.ctx.fillStyle = "#ffffff", this.ctx.beginPath(), this.ctx.arc(c, h, 2.5 + Math.random() * 2.5, 0, Math.PI * 2), this.ctx.fill();
2727
+ 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();
2570
2728
  }
2571
2729
  this.ctx.restore();
2572
2730
  }
@@ -2601,7 +2759,7 @@ class ft {
2601
2759
  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();
2602
2760
  for (let h = 0; h < 4; h++) {
2603
2761
  const u = h * Math.PI * 0.5 + o * 4, p = c * 0.8 * o;
2604
- this.ctx.fillStyle = "#ffffff", this.ctx.beginPath(), this.ctx.arc(Math.cos(u) * p, Math.sin(u) * p, 3, 0, Math.PI * 2), this.ctx.fill();
2762
+ this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(Math.cos(u) * p, Math.sin(u) * p, 3, 0, Math.PI * 2), this.ctx.fill();
2605
2763
  }
2606
2764
  this.ctx.restore();
2607
2765
  continue;
@@ -2618,7 +2776,7 @@ class ft {
2618
2776
  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, p = Math.cos(c) * h, _ = Math.sin(c) * u;
2619
2777
  r === 0 ? this.ctx.moveTo(p, _) : this.ctx.lineTo(p, _);
2620
2778
  }
2621
- this.ctx.closePath(), this.ctx.fill(), this.ctx.fillStyle = "#ffffff", this.ctx.beginPath(), this.ctx.arc(4, 0, 4, 0, Math.PI * 2), this.ctx.fill();
2779
+ 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();
2622
2780
  } else if (s.type === "spore") {
2623
2781
  this.ctx.beginPath();
2624
2782
  const o = 8;
@@ -2626,7 +2784,7 @@ class ft {
2626
2784
  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, p = Math.sin(c) * h;
2627
2785
  r === 0 ? this.ctx.moveTo(u, p) : this.ctx.lineTo(u, p);
2628
2786
  }
2629
- this.ctx.closePath(), this.ctx.fill(), this.ctx.fillStyle = "rgba(255, 255, 255, 0.7)", 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();
2787
+ 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();
2630
2788
  } else if (s.type === "cluster") {
2631
2789
  this.ctx.beginPath();
2632
2790
  const o = Math.sin(e * 3) * 2;
@@ -2644,10 +2802,10 @@ class ft {
2644
2802
  const o = Math.PI * 0.75, r = s.radius * 1.35, c = s.radius * 0.75;
2645
2803
  this.ctx.beginPath(), this.ctx.arc(0, 0, r, -o / 2, o / 2, !1);
2646
2804
  const h = Math.cos(o / 2) * c, u = Math.sin(o / 2) * c;
2647
- this.ctx.lineTo(h, u), this.ctx.arc(0, 0, c, o / 2, -o / 2, !0), this.ctx.closePath(), this.ctx.fillStyle = s.isStationaryShield ? "#00f5ff" : a, this.ctx.shadowColor = "#00f5ff", this.ctx.shadowBlur = s.isStationaryShield ? 28 : 16, this.ctx.fill(), this.ctx.strokeStyle = "#ffffff", 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();
2805
+ 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();
2648
2806
  for (let p = -2; p <= 2; p++) {
2649
- const _ = p * o / 6, d = Math.cos(_) * (c + 6), g = Math.sin(_) * (c + 6);
2650
- this.ctx.fillStyle = "#ffffff", this.ctx.beginPath(), this.ctx.arc(d, g, 3, 0, Math.PI * 2), this.ctx.fill();
2807
+ const _ = p * o / 6, g = Math.cos(_) * (c + 6), d = Math.sin(_) * (c + 6);
2808
+ this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(g, d, 3, 0, Math.PI * 2), this.ctx.fill();
2651
2809
  }
2652
2810
  } else
2653
2811
  this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius, 0, Math.PI * 2), this.ctx.fill();
@@ -2664,30 +2822,36 @@ class ft {
2664
2822
  for (const e of t)
2665
2823
  this.ctx.save(), this.ctx.globalAlpha = e.alpha, this.ctx.fillStyle = e.color, this.ctx.font = `900 ${e.size}px Orbitron, sans-serif`, this.ctx.textAlign = "center", this.ctx.shadowColor = e.color, this.ctx.shadowBlur = 12, this.ctx.fillText(e.text, e.position.x, e.position.y), this.ctx.restore();
2666
2824
  }
2667
- drawOrbitingModifierOrbs(t, e, i, s = !0) {
2668
- if (this.ctx) {
2669
- for (const a of t) {
2670
- if (!a.active) continue;
2671
- const { x: l, y: n } = a.position, o = a.definition.color, r = a.definition.rarity, c = r === "legendary" ? "#ff00ff" : r === "epic" ? "#ffd700" : r === "rare" ? "#9d4edd" : "#00f5ff", h = a.radius + Math.sin(e * 6 + a.orbitAngle) * 3;
2672
- if (this.ctx.save(), this.ctx.shadowColor = c, this.ctx.shadowBlur = a.isGrabbed ? 36 : r === "legendary" ? 28 : 16, r === "legendary" || r === "epic") {
2673
- const _ = h + 12, d = this.ctx.createRadialGradient(l, n, h, l, n, _);
2674
- d.addColorStop(0, c), d.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = d, this.ctx.beginPath(), this.ctx.arc(l, n, _, 0, Math.PI * 2), this.ctx.fill();
2675
- }
2676
- const u = this.ctx.createRadialGradient(l, n, 2, l, n, h * 1.4);
2677
- u.addColorStop(0, "#ffffff"), u.addColorStop(0.4, o), u.addColorStop(1, "rgba(0, 0, 0, 0.5)"), this.ctx.fillStyle = u, this.ctx.beginPath(), this.ctx.arc(l, n, h, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = c, this.ctx.lineWidth = r === "legendary" ? 3.5 : 2.5, this.ctx.beginPath(), this.ctx.arc(l, n, h + 4, e * 3, e * 3 + Math.PI * 1.2), this.ctx.stroke(), (r === "legendary" || r === "epic") && (this.ctx.strokeStyle = "#ffffff", this.ctx.lineWidth = 1.5, this.ctx.beginPath(), this.ctx.arc(l, n, 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 = "#ffffff", this.ctx.shadowColor = "#000000", this.ctx.shadowBlur = 6, this.ctx.fillText(a.definition.badge, l, n);
2678
- const p = i ? i.translate(a.definition.titleKey) : a.definition.badge;
2679
- this.ctx.textBaseline = "alphabetic", this.ctx.font = "900 16px Orbitron, sans-serif", this.ctx.fillStyle = "#ffffff", this.ctx.shadowColor = c, this.ctx.shadowBlur = 14, this.ctx.fillText(p, l, n - h - 14), this.ctx.restore();
2680
- }
2681
- if (i && s) {
2682
- const a = this.canvas.width / 2, l = this.canvas.height / 2 + 210, n = i.translate("rerollButton");
2683
- this.ctx.save(), this.ctx.font = "900 14px Orbitron, sans-serif", this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.fillStyle = "rgba(0, 0, 0, 0.65)", this.ctx.strokeStyle = "#00f0ff", this.ctx.lineWidth = 2, this.ctx.shadowColor = "#00f0ff", this.ctx.shadowBlur = 12;
2684
- const c = this.ctx.measureText(n).width + 20 * 2, h = 38;
2685
- this.ctx.beginPath(), this.ctx.roundRect(a - c / 2, l - h / 2, c, h, 8), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = "#ffffff", this.ctx.shadowColor = "#000000", this.ctx.shadowBlur = 4, this.ctx.fillText(n, a, l), this.ctx.restore();
2825
+ drawOrbitingModifierOrbs(t, e, i, s = !0, a = 1) {
2826
+ if (!this.ctx) return;
2827
+ const l = this.themeManager.getPalette(), n = this.themeManager.getTheme() === "light";
2828
+ for (const o of t) {
2829
+ if (!o.active) continue;
2830
+ const { x: r, y: c } = o.position, h = o.definition.color, u = o.definition.rarity, p = u === "legendary" ? "#ff00ff" : u === "epic" ? "#ffd700" : u === "rare" ? "#9d4edd" : "#00f5ff", _ = o.radius + Math.sin(e * 6 + o.orbitAngle) * 3;
2831
+ if (this.ctx.save(), this.ctx.shadowColor = p, this.ctx.shadowBlur = o.isGrabbed ? 36 : u === "legendary" ? 28 : 16, u === "legendary" || u === "epic") {
2832
+ const m = _ + 12, x = this.ctx.createRadialGradient(r, c, _, r, c, m);
2833
+ x.addColorStop(0, p), x.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = x, this.ctx.beginPath(), this.ctx.arc(r, c, m, 0, Math.PI * 2), this.ctx.fill();
2686
2834
  }
2835
+ const g = this.ctx.createRadialGradient(r, c, 2, r, c, _ * 1.4);
2836
+ g.addColorStop(0, l.effectHighlight), g.addColorStop(0.4, h), g.addColorStop(1, n ? "rgba(23, 50, 77, 0.24)" : "rgba(0, 0, 0, 0.5)"), this.ctx.fillStyle = g, this.ctx.beginPath(), this.ctx.arc(r, c, _, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = p, 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 ? p : 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);
2837
+ const d = i ? i.translate(o.definition.titleKey) : o.definition.badge;
2838
+ this.ctx.textBaseline = "alphabetic", this.ctx.font = "900 16px Orbitron, sans-serif", this.ctx.fillStyle = l.effectInk, this.ctx.shadowColor = p, this.ctx.shadowBlur = 14, this.ctx.fillText(d, r, c - _ - 14), this.ctx.restore();
2687
2839
  }
2840
+ if (i && s) {
2841
+ const o = this.canvas.width / 2, r = this.canvas.height / 2 + 210, c = i.translate("rerollButton", { count: a });
2842
+ 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;
2843
+ const p = this.ctx.measureText(c).width + 20 * 2, _ = 38;
2844
+ this.ctx.beginPath(), this.ctx.roundRect(o - p / 2, r - _ / 2, p, _, 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();
2845
+ }
2846
+ }
2847
+ colorWithAlpha(t, e) {
2848
+ const i = t.replace("#", "");
2849
+ if (i.length !== 6) return t;
2850
+ 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);
2851
+ return `rgba(${s}, ${a}, ${l}, ${e})`;
2688
2852
  }
2689
2853
  }
2690
- class xt {
2854
+ class gt {
2691
2855
  container;
2692
2856
  i18n;
2693
2857
  waveLabelElement;
@@ -2719,7 +2883,7 @@ class xt {
2719
2883
  this.container.style.display = "none";
2720
2884
  }
2721
2885
  }
2722
- class Et {
2886
+ class _t {
2723
2887
  container;
2724
2888
  i18n;
2725
2889
  onStartCallback;
@@ -2745,7 +2909,7 @@ class Et {
2745
2909
  this.container.style.display = "none";
2746
2910
  }
2747
2911
  }
2748
- class yt {
2912
+ class mt {
2749
2913
  modal;
2750
2914
  card;
2751
2915
  i18n;
@@ -2790,13 +2954,13 @@ class yt {
2790
2954
  ko: "한국어 (KO)",
2791
2955
  zh: "中文 (ZH)"
2792
2956
  };
2793
- for (const m of Y) {
2794
- const y = document.createElement("option");
2795
- y.value = m, y.textContent = l[m], this.i18n.getLanguage() === m && (y.selected = !0), a.appendChild(y);
2957
+ for (const f of K) {
2958
+ const v = document.createElement("option");
2959
+ v.value = f, v.textContent = l[f], this.i18n.getLanguage() === f && (v.selected = !0), a.appendChild(v);
2796
2960
  }
2797
2961
  a.addEventListener("change", () => {
2798
- const m = a.value;
2799
- this.i18n.setLanguage(m), this.onLanguageChangedCallback && this.onLanguageChangedCallback(m), this.renderContent();
2962
+ const f = a.value;
2963
+ this.i18n.setLanguage(f), this.onLanguageChangedCallback && this.onLanguageChangedCallback(f), this.renderContent();
2800
2964
  });
2801
2965
  const n = document.createElement("span");
2802
2966
  n.className = "axon-select-arrow", n.textContent = "▼", s.appendChild(a), s.appendChild(n), e.appendChild(i), e.appendChild(s);
@@ -2811,11 +2975,11 @@ class yt {
2811
2975
  { id: "dark", label: "DARK" },
2812
2976
  { id: "light", label: "LIGHT" }
2813
2977
  ];
2814
- for (const m of h) {
2815
- const y = document.createElement("button");
2816
- y.type = "button", y.className = `axon-toggle-btn ${this.themeManager.getTheme() === m.id ? "active" : ""}`, y.textContent = m.label, y.addEventListener("click", () => {
2817
- this.themeManager.setTheme(m.id), this.renderContent();
2818
- }), c.appendChild(y);
2978
+ for (const f of h) {
2979
+ const v = document.createElement("button");
2980
+ v.type = "button", v.className = `axon-toggle-btn ${this.themeManager.getTheme() === f.id ? "active" : ""}`, v.textContent = f.label, v.addEventListener("click", () => {
2981
+ this.themeManager.setTheme(f.id), this.renderContent();
2982
+ }), c.appendChild(v);
2819
2983
  }
2820
2984
  o.appendChild(r), o.appendChild(c);
2821
2985
  const u = document.createElement("div");
@@ -2824,40 +2988,40 @@ class yt {
2824
2988
  p.textContent = this.i18n.translate("hapticsLabel");
2825
2989
  const _ = document.createElement("div");
2826
2990
  _.className = "axon-toggle-group";
2827
- const d = [
2991
+ const g = [
2828
2992
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
2829
2993
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
2830
2994
  ];
2831
- for (const m of d) {
2832
- const y = document.createElement("button");
2833
- y.type = "button", y.className = `axon-toggle-btn ${this.hapticsEnabled === m.enabled ? "active" : ""}`, y.textContent = m.label, y.addEventListener("click", () => {
2834
- this.hapticsEnabled = m.enabled, localStorage.setItem("axon_surge_haptics", String(m.enabled)), this.hapticsEnabled && this.platform.haptics.selectionChanged(), this.renderContent();
2835
- }), _.appendChild(y);
2995
+ for (const f of g) {
2996
+ const v = document.createElement("button");
2997
+ v.type = "button", v.className = `axon-toggle-btn ${this.hapticsEnabled === f.enabled ? "active" : ""}`, v.textContent = f.label, v.addEventListener("click", () => {
2998
+ this.hapticsEnabled = f.enabled, localStorage.setItem("axon_surge_haptics", String(f.enabled)), this.hapticsEnabled && this.platform.haptics.selectionChanged(), this.renderContent();
2999
+ }), _.appendChild(v);
2836
3000
  }
2837
3001
  u.appendChild(p), u.appendChild(_);
2838
- const g = document.createElement("div");
2839
- g.className = "axon-setting-row";
2840
- const f = document.createElement("span");
2841
- f.textContent = this.i18n.translate("tutorialSettingLabel");
3002
+ const d = document.createElement("div");
3003
+ d.className = "axon-setting-row";
3004
+ const m = document.createElement("span");
3005
+ m.textContent = this.i18n.translate("tutorialSettingLabel");
2842
3006
  const x = document.createElement("div");
2843
3007
  x.className = "axon-toggle-group";
2844
- const b = localStorage.getItem("axon_surge_show_tutorial") !== "false", S = [
3008
+ const A = localStorage.getItem("axon_surge_show_tutorial") !== "false", b = [
2845
3009
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
2846
3010
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
2847
3011
  ];
2848
- for (const m of S) {
2849
- const y = document.createElement("button");
2850
- y.type = "button", y.className = `axon-toggle-btn ${b === m.enabled ? "active" : ""}`, y.textContent = m.label, y.addEventListener("click", () => {
2851
- localStorage.setItem("axon_surge_show_tutorial", String(m.enabled)), this.renderContent();
2852
- }), x.appendChild(y);
3012
+ for (const f of b) {
3013
+ const v = document.createElement("button");
3014
+ v.type = "button", v.className = `axon-toggle-btn ${A === f.enabled ? "active" : ""}`, v.textContent = f.label, v.addEventListener("click", () => {
3015
+ localStorage.setItem("axon_surge_show_tutorial", String(f.enabled)), this.renderContent();
3016
+ }), x.appendChild(v);
2853
3017
  }
2854
- g.appendChild(f), g.appendChild(x);
3018
+ d.appendChild(m), d.appendChild(x);
2855
3019
  const I = document.createElement("div");
2856
3020
  I.className = "axon-settings-credits", I.textContent = this.i18n.translate("creditsJam");
2857
- const v = document.createElement("button");
2858
- v.type = "button", v.className = "axon-start-button", v.style.padding = "12px 36px", v.style.fontSize = "14px", v.textContent = this.i18n.translate("closeButton"), v.addEventListener("click", () => {
3021
+ const S = document.createElement("button");
3022
+ 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", () => {
2859
3023
  this.modal.close();
2860
- }), this.card.appendChild(t), this.card.appendChild(e), this.card.appendChild(o), this.card.appendChild(u), this.card.appendChild(g), this.card.appendChild(I), this.card.appendChild(v);
3024
+ }), this.card.appendChild(t), this.card.appendChild(e), this.card.appendChild(o), this.card.appendChild(u), this.card.appendChild(d), this.card.appendChild(I), this.card.appendChild(S);
2861
3025
  }
2862
3026
  isHapticsEnabled() {
2863
3027
  return this.hapticsEnabled;
@@ -2869,8 +3033,8 @@ class yt {
2869
3033
  this.modal.close();
2870
3034
  }
2871
3035
  }
2872
- const W = "axon_surge_show_tutorial";
2873
- class At {
3036
+ const H = "axon_surge_show_tutorial";
3037
+ class ft {
2874
3038
  isActive = !1;
2875
3039
  showWarning = !1;
2876
3040
  dummyLauncher = null;
@@ -2879,14 +3043,14 @@ class At {
2879
3043
  initialTargetPos = { x: 0, y: 0 };
2880
3044
  isTutorialEnabled() {
2881
3045
  try {
2882
- return localStorage.getItem(W) !== "false";
3046
+ return localStorage.getItem(H) !== "false";
2883
3047
  } catch {
2884
3048
  return !0;
2885
3049
  }
2886
3050
  }
2887
3051
  setTutorialEnabled(t) {
2888
3052
  try {
2889
- localStorage.setItem(W, String(t));
3053
+ localStorage.setItem(H, String(t));
2890
3054
  } catch {
2891
3055
  }
2892
3056
  }
@@ -2933,7 +3097,7 @@ class At {
2933
3097
  return;
2934
3098
  }
2935
3099
  if (h <= n.getHitRadius() + o.getHitRadius()) {
2936
- n.triggerDissolveDeath(), o.triggerDissolveDeath(), this.showWarning = !1, this.isActive = !1, a();
3100
+ n.triggerDissolveDeath(!0), o.triggerDissolveDeath(!0), this.showWarning = !1, this.isActive = !1, a();
2937
3101
  return;
2938
3102
  }
2939
3103
  (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));
@@ -2946,7 +3110,7 @@ class At {
2946
3110
  this.isActive = !1, this.showWarning = !1;
2947
3111
  }
2948
3112
  }
2949
- class bt {
3113
+ class xt {
2950
3114
  container;
2951
3115
  i18n;
2952
3116
  tutorialManager;
@@ -2982,9 +3146,9 @@ class bt {
2982
3146
  this.container.style.display = "none";
2983
3147
  }
2984
3148
  }
2985
- class St {
3149
+ class yt {
2986
3150
  fillElement;
2987
- killsCount = 0;
3151
+ experienceCount = 0;
2988
3152
  currentLevel = 1;
2989
3153
  onLevelUpCallback;
2990
3154
  constructor(t, e) {
@@ -2992,19 +3156,25 @@ class St {
2992
3156
  const i = document.createElement("div");
2993
3157
  i.className = "axon-hud-level-track", this.fillElement = document.createElement("div"), this.fillElement.className = "axon-hud-level-fill", i.appendChild(this.fillElement), t.appendChild(i);
2994
3158
  }
2995
- getKillsRequiredForLevel(t) {
3159
+ getExperienceRequiredForLevel(t) {
2996
3160
  return t === 1 ? 3 : t === 2 ? 6 : t === 3 ? 10 : 10 + (t - 3) * 6;
2997
3161
  }
3162
+ addExperience(t = 1) {
3163
+ this.experienceCount += Math.max(0, t);
3164
+ let e = this.getExperienceRequiredForLevel(this.currentLevel);
3165
+ for (; this.experienceCount >= e; )
3166
+ this.experienceCount -= e, this.currentLevel++, this.onLevelUpCallback && this.onLevelUpCallback(this.currentLevel), e = this.getExperienceRequiredForLevel(this.currentLevel);
3167
+ const i = Math.min(100, this.experienceCount / e * 100);
3168
+ this.fillElement.style.width = `${i}%`;
3169
+ }
2998
3170
  addKill() {
2999
- this.killsCount++;
3000
- const t = this.getKillsRequiredForLevel(this.currentLevel), e = Math.min(100, this.killsCount / t * 100);
3001
- this.fillElement.style.width = `${e}%`, this.killsCount >= t && (this.currentLevel++, this.killsCount = 0, this.fillElement.style.width = "0%", this.onLevelUpCallback && this.onLevelUpCallback(this.currentLevel));
3171
+ this.addExperience(1);
3002
3172
  }
3003
3173
  getLevel() {
3004
3174
  return this.currentLevel;
3005
3175
  }
3006
3176
  reset() {
3007
- this.killsCount = 0, this.currentLevel = 1, this.fillElement.style.width = "0%";
3177
+ this.experienceCount = 0, this.currentLevel = 1, this.fillElement.style.width = "0%";
3008
3178
  }
3009
3179
  show() {
3010
3180
  this.fillElement && this.fillElement.parentElement && (this.fillElement.parentElement.style.display = "block");
@@ -3013,24 +3183,24 @@ class St {
3013
3183
  this.fillElement && this.fillElement.parentElement && (this.fillElement.parentElement.style.display = "none");
3014
3184
  }
3015
3185
  }
3016
- class F {
3186
+ class B {
3017
3187
  static powerUps = [
3018
3188
  {
3019
3189
  id: "spore_radius",
3020
3190
  titleKey: "pu_spore_radius_title",
3021
3191
  descKey: "pu_spore_radius_desc",
3022
- badge: "+30% RAD",
3192
+ badge: "+12% RAD",
3023
3193
  category: "radius",
3024
3194
  rarity: "common",
3025
3195
  rarityWeight: 35,
3026
3196
  color: "#39ff14",
3027
3197
  apply: () => {
3028
- const t = A.getInstance(), e = t.getConfig().toxicPool;
3198
+ const t = E.getInstance(), e = t.getConfig().toxicPool;
3029
3199
  t.updateConfig({
3030
3200
  toxicPool: {
3031
3201
  ...e,
3032
- baseRadius: Math.round(e.baseRadius * 1.3),
3033
- synergyRadius: Math.round(e.synergyRadius * 1.3)
3202
+ baseRadius: Math.round(e.baseRadius * 1.12),
3203
+ synergyRadius: Math.round(e.synergyRadius * 1.12)
3034
3204
  }
3035
3205
  });
3036
3206
  }
@@ -3045,7 +3215,7 @@ class F {
3045
3215
  rarityWeight: 35,
3046
3216
  color: "#39ff14",
3047
3217
  apply: () => {
3048
- const t = A.getInstance(), e = t.getConfig().toxicPool;
3218
+ const t = E.getInstance(), e = t.getConfig().toxicPool;
3049
3219
  t.updateConfig({
3050
3220
  toxicPool: {
3051
3221
  ...e,
@@ -3059,18 +3229,18 @@ class F {
3059
3229
  id: "vortex_radius",
3060
3230
  titleKey: "pu_vortex_radius_title",
3061
3231
  descKey: "pu_vortex_radius_desc",
3062
- badge: "+25% RAD",
3232
+ badge: "+12% RAD",
3063
3233
  category: "radius",
3064
3234
  rarity: "common",
3065
3235
  rarityWeight: 35,
3066
3236
  color: "#9d4edd",
3067
3237
  apply: () => {
3068
- const t = A.getInstance(), e = t.getConfig().gravityVortex;
3238
+ const t = E.getInstance(), e = t.getConfig().gravityVortex;
3069
3239
  t.updateConfig({
3070
3240
  gravityVortex: {
3071
3241
  ...e,
3072
- baseRadius: Math.round(e.baseRadius * 1.25),
3073
- synergyRadius: Math.round(e.synergyRadius * 1.25)
3242
+ baseRadius: Math.round(e.baseRadius * 1.12),
3243
+ synergyRadius: Math.round(e.synergyRadius * 1.12)
3074
3244
  }
3075
3245
  });
3076
3246
  }
@@ -3085,7 +3255,7 @@ class F {
3085
3255
  rarityWeight: 35,
3086
3256
  color: "#9d4edd",
3087
3257
  apply: () => {
3088
- const t = A.getInstance(), e = t.getConfig().gravityVortex;
3258
+ const t = E.getInstance(), e = t.getConfig().gravityVortex;
3089
3259
  t.updateConfig({
3090
3260
  gravityVortex: {
3091
3261
  ...e,
@@ -3105,7 +3275,7 @@ class F {
3105
3275
  rarityWeight: 25,
3106
3276
  color: "#9d4edd",
3107
3277
  apply: () => {
3108
- const t = A.getInstance(), e = t.getConfig().gravityVortex;
3278
+ const t = E.getInstance(), e = t.getConfig().gravityVortex;
3109
3279
  t.updateConfig({
3110
3280
  gravityVortex: {
3111
3281
  ...e,
@@ -3125,7 +3295,7 @@ class F {
3125
3295
  rarityWeight: 5,
3126
3296
  color: "#9d4edd",
3127
3297
  apply: () => {
3128
- const t = A.getInstance(), e = t.getConfig().gravityVortex;
3298
+ const t = E.getInstance(), e = t.getConfig().gravityVortex;
3129
3299
  t.updateConfig({
3130
3300
  gravityVortex: {
3131
3301
  ...e,
@@ -3144,7 +3314,7 @@ class F {
3144
3314
  rarityWeight: 5,
3145
3315
  color: "#00f5ff",
3146
3316
  apply: () => {
3147
- const t = A.getInstance(), e = t.getConfig().shield;
3317
+ const t = E.getInstance(), e = t.getConfig().shield;
3148
3318
  t.updateConfig({
3149
3319
  shield: {
3150
3320
  ...e,
@@ -3163,7 +3333,7 @@ class F {
3163
3333
  rarityWeight: 25,
3164
3334
  color: "#ffcc00",
3165
3335
  apply: () => {
3166
- const t = A.getInstance(), e = t.getConfig().cluster;
3336
+ const t = E.getInstance(), e = t.getConfig().cluster;
3167
3337
  t.updateConfig({
3168
3338
  cluster: {
3169
3339
  ...e,
@@ -3182,7 +3352,7 @@ class F {
3182
3352
  rarityWeight: 5,
3183
3353
  color: "#ffcc00",
3184
3354
  apply: () => {
3185
- const t = A.getInstance(), e = t.getConfig().cluster;
3355
+ const t = E.getInstance(), e = t.getConfig().cluster;
3186
3356
  t.updateConfig({
3187
3357
  cluster: {
3188
3358
  ...e,
@@ -3201,7 +3371,7 @@ class F {
3201
3371
  rarityWeight: 15,
3202
3372
  color: "#ff3366",
3203
3373
  apply: () => {
3204
- const t = A.getInstance(), e = t.getConfig().piercer;
3374
+ const t = E.getInstance(), e = t.getConfig().piercer;
3205
3375
  t.updateConfig({
3206
3376
  piercer: {
3207
3377
  ...e,
@@ -3220,7 +3390,7 @@ class F {
3220
3390
  rarityWeight: 5,
3221
3391
  color: "#ff2a5f",
3222
3392
  apply: () => {
3223
- const t = A.getInstance(), e = t.getConfig().piercer;
3393
+ const t = E.getInstance(), e = t.getConfig().piercer;
3224
3394
  t.updateConfig({
3225
3395
  piercer: {
3226
3396
  ...e,
@@ -3229,6 +3399,25 @@ class F {
3229
3399
  });
3230
3400
  }
3231
3401
  },
3402
+ {
3403
+ id: "offscreen_radar",
3404
+ titleKey: "pu_offscreen_radar_title",
3405
+ descKey: "pu_offscreen_radar_desc",
3406
+ badge: "RADAR",
3407
+ category: "defense",
3408
+ rarity: "legendary",
3409
+ rarityWeight: 5,
3410
+ color: "#00f0ff",
3411
+ apply: () => {
3412
+ const t = E.getInstance(), e = t.getConfig().core;
3413
+ t.updateConfig({
3414
+ core: {
3415
+ ...e,
3416
+ hasOffscreenIndicators: !0
3417
+ }
3418
+ });
3419
+ }
3420
+ },
3232
3421
  {
3233
3422
  id: "piercer_homing_target",
3234
3423
  titleKey: "pu_piercer_homing_target_title",
@@ -3239,7 +3428,7 @@ class F {
3239
3428
  rarityWeight: 15,
3240
3429
  color: "#ff2a5f",
3241
3430
  apply: () => {
3242
- const t = A.getInstance(), e = t.getConfig().piercer;
3431
+ const t = E.getInstance(), e = t.getConfig().piercer;
3243
3432
  t.updateConfig({
3244
3433
  piercer: {
3245
3434
  ...e,
@@ -3258,7 +3447,7 @@ class F {
3258
3447
  rarityWeight: 15,
3259
3448
  color: "#00f5ff",
3260
3449
  apply: () => {
3261
- const t = A.getInstance(), e = t.getConfig().core;
3450
+ const t = E.getInstance(), e = t.getConfig().core;
3262
3451
  t.updateConfig({
3263
3452
  core: {
3264
3453
  ...e,
@@ -3277,7 +3466,7 @@ class F {
3277
3466
  rarityWeight: 25,
3278
3467
  color: "#00f5ff",
3279
3468
  apply: () => {
3280
- const t = A.getInstance(), e = t.getConfig().core;
3469
+ const t = E.getInstance(), e = t.getConfig().core;
3281
3470
  t.updateConfig({
3282
3471
  core: {
3283
3472
  ...e,
@@ -3296,12 +3485,50 @@ class F {
3296
3485
  rarityWeight: 20,
3297
3486
  color: "#00f5ff",
3298
3487
  apply: (t) => {
3299
- A.getInstance().addCoreRing(1), t && t.addMaxRing(1);
3488
+ E.getInstance().addCoreRing(1), t && t.addMaxRing(1);
3489
+ }
3490
+ },
3491
+ {
3492
+ id: "magnet_radius",
3493
+ titleKey: "pu_magnet_radius_title",
3494
+ descKey: "pu_magnet_radius_desc",
3495
+ badge: "+60 MAGNET",
3496
+ category: "magnet",
3497
+ rarity: "common",
3498
+ rarityWeight: 35,
3499
+ color: "#00f5ff",
3500
+ apply: () => {
3501
+ const t = E.getInstance(), e = t.getConfig().magnet;
3502
+ t.updateConfig({
3503
+ magnet: {
3504
+ ...e,
3505
+ pickupRadius: e.pickupRadius + 60
3506
+ }
3507
+ });
3508
+ }
3509
+ },
3510
+ {
3511
+ id: "magnet_strength",
3512
+ titleKey: "pu_magnet_strength_title",
3513
+ descKey: "pu_magnet_strength_desc",
3514
+ badge: "+25% PULL",
3515
+ category: "magnet",
3516
+ rarity: "rare",
3517
+ rarityWeight: 25,
3518
+ color: "#00f5ff",
3519
+ apply: () => {
3520
+ const t = E.getInstance(), e = t.getConfig().magnet;
3521
+ t.updateConfig({
3522
+ magnet: {
3523
+ ...e,
3524
+ absorptionSpeed: Math.round(e.absorptionSpeed * 1.25)
3525
+ }
3526
+ });
3300
3527
  }
3301
3528
  }
3302
3529
  ];
3303
3530
  static getRandomOptions(t = 3) {
3304
- const e = A.getInstance().getConfig(), i = this.powerUps.filter((a) => !(a.id === "vampirism_unlock" && e.core.vampirismHealProgressRate > 0 || a.id === "vampirism_boost" && e.core.vampirismHealProgressRate <= 0 || a.id === "piercer_homing" && e.piercer.hasHoming || a.id === "piercer_homing_target" && !e.piercer.hasHoming || a.id === "vortex_pocket" && e.gravityVortex.hasImplosionLaunch || a.id === "shield_fan" && e.shield.isFanBlast || a.id === "cluster_homing" && e.cluster.hasHoming)), s = [];
3531
+ 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 === "cluster_homing" && e.cluster.hasHoming || a.id === "offscreen_radar" && e.core.hasOffscreenIndicators)), s = [];
3305
3532
  for (let a = 0; a < t && i.length > 0; a++) {
3306
3533
  const l = i.reduce((o, r) => o + r.rarityWeight, 0);
3307
3534
  let n = Math.random() * l;
@@ -3319,7 +3546,7 @@ class F {
3319
3546
  this.powerUps.push(t);
3320
3547
  }
3321
3548
  }
3322
- class vt {
3549
+ class Et {
3323
3550
  haptics = {
3324
3551
  impact: async (t) => {
3325
3552
  if ("vibrate" in navigator) {
@@ -3359,7 +3586,7 @@ class vt {
3359
3586
  }
3360
3587
  };
3361
3588
  }
3362
- class It {
3589
+ class At {
3363
3590
  container;
3364
3591
  canvas;
3365
3592
  i18n;
@@ -3386,15 +3613,18 @@ class It {
3386
3613
  shockwaves = [];
3387
3614
  particles = [];
3388
3615
  floatingTexts = [];
3616
+ experienceOrbs = [];
3389
3617
  orbitingOrbs = [];
3390
3618
  isLevelUpActive = !1;
3391
- hasRerolledThisLevel = !1;
3619
+ pendingLevelUps = [];
3620
+ debugRerollsEnabled = typeof window < "u" && window.location.hostname === "localhost" && new URLSearchParams(window.location.search).has("debug");
3621
+ rerollsRemaining = 1;
3392
3622
  score = { value: 0 };
3393
3623
  combo = { value: 0 };
3394
3624
  isRunning = !1;
3395
3625
  isPaused = !1;
3396
3626
  constructor(t) {
3397
- this.container = t.root, this.container.classList.add("axon-game-root"), this.i18n = new Q(t.language), this.themeManager = new dt(t.theme, this.container), this.platform = t.platform || new vt(), 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 J(), this.core = new z(this.canvas.width / 2, this.canvas.height / 2), this.inputManager = new $(this.canvas), this.physicsEngine = new ht(this.eventBus, this.i18n), this.waveDirector = new pt(), this.renderer = new ft(this.canvas, this.themeManager), this.juice = new q(), this.settingsModal = new yt(
3627
+ this.container = t.root, this.container.classList.add("axon-game-root"), this.i18n = new J(t.language), this.themeManager = new ct(t.theme, this.container), this.platform = t.platform || new Et(), 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 V(), this.core = new F(this.canvas.width / 2, this.canvas.height / 2), this.inputManager = new Y(this.canvas), this.physicsEngine = new ot(this.eventBus, this.i18n), this.waveDirector = new rt(), this.renderer = new dt(this.canvas, this.themeManager), this.juice = new z(), this.settingsModal = new mt(
3398
3628
  this.container,
3399
3629
  this.i18n,
3400
3630
  this.themeManager,
@@ -3403,11 +3633,11 @@ class It {
3403
3633
  () => {
3404
3634
  this.isPaused = !1;
3405
3635
  }
3406
- ), this.interactiveTutorial = new At(), this.tutorialOverlay = new bt(this.container, this.i18n, this.interactiveTutorial), this.hud = new xt(this.container, this.i18n, () => {
3636
+ ), this.interactiveTutorial = new ft(), this.tutorialOverlay = new xt(this.container, this.i18n, this.interactiveTutorial), this.hud = new gt(this.container, this.i18n, () => {
3407
3637
  this.isPaused = !0, this.settingsModal.show();
3408
- }), this.hud.show(), this.progressBar = new St(this.hud.progressSlot, (e) => {
3638
+ }), this.hud.show(), this.progressBar = new yt(this.hud.progressSlot, (e) => {
3409
3639
  this.waveDirector.wave = e, this.triggerLevelUp(e);
3410
- }), this.startMenu = new Et(this.container, this.i18n, () => this.startGame()), this.initAmbientArena(), this.gameLoop = new X(
3640
+ }), this.startMenu = new _t(this.container, this.i18n, () => this.startGame()), this.initAmbientArena(), this.gameLoop = new W(
3411
3641
  (e) => this.update(e),
3412
3642
  () => this.render()
3413
3643
  ), this.setupEvents(), this.gameLoop.start();
@@ -3449,13 +3679,13 @@ class It {
3449
3679
  this.eventBus.on("onCoreDamaged", () => {
3450
3680
  this.settingsModal.isHapticsEnabled() && this.platform.haptics.notification("error");
3451
3681
  }), this.eventBus.on("onGameOver", () => {
3452
- this.isRunning = !1, this.tutorialOverlay.hide(), this.progressBar.hide(), this.initAmbientArena(), this.startMenu.show();
3682
+ this.isRunning = !1, this.experienceOrbs = [], this.pendingLevelUps = [], this.tutorialOverlay.hide(), this.progressBar.hide(), this.initAmbientArena(), this.startMenu.show();
3453
3683
  });
3454
3684
  const t = (i = !1) => {
3455
- if (!this.isRunning || this.isPaused) return;
3685
+ if (!this.isRunning || this.isPaused || this.isLevelUpActive) return;
3456
3686
  this.inputManager.tryGrab(this.enemies, i) && this.settingsModal.isHapticsEnabled() && this.platform.haptics.impact("light");
3457
3687
  }, e = () => {
3458
- if (!this.isRunning || this.isPaused) return;
3688
+ if (!this.isRunning || this.isPaused || this.isLevelUpActive) return;
3459
3689
  this.inputManager.releaseAndThrow() && this.settingsModal.isHapticsEnabled() && this.platform.haptics.impact("medium");
3460
3690
  };
3461
3691
  this.canvas.addEventListener("mousedown", (i) => {
@@ -3465,7 +3695,7 @@ class It {
3465
3695
  }), this.canvas.addEventListener("touchstart", () => t(!0), { passive: !0 }), this.canvas.addEventListener("touchend", e, { passive: !0 }), this.canvas.addEventListener("touchcancel", e, { passive: !0 });
3466
3696
  }
3467
3697
  startGame() {
3468
- this.score.value = 0, this.combo.value = 0, this.enemies = [], this.ambientEnemies = [], this.pools = [], this.vortices = [], this.shockwaves = [], this.particles = [], this.floatingTexts = [], 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());
3698
+ 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());
3469
3699
  }
3470
3700
  update(t) {
3471
3701
  if (this.core.update(t), !this.isRunning || this.isPaused) {
@@ -3499,7 +3729,7 @@ class It {
3499
3729
  const e = this.inputManager.grabbedOrb;
3500
3730
  !this.inputManager.isPointerDown && e && (e.isGrabbed = !1, this.inputManager.grabbedOrb = null);
3501
3731
  const i = this.inputManager.pointerPosition;
3502
- if (this.inputManager.isPointerDown && !this.inputManager.grabbedOrb && !this.hasRerolledThisLevel) {
3732
+ if (this.inputManager.isPointerDown && !this.inputManager.grabbedOrb && this.rerollsRemaining > 0) {
3503
3733
  const s = this.canvas.width / 2, a = this.canvas.height / 2 + 210;
3504
3734
  Math.hypot(i.x - s, i.y - a) <= 80 && (this.triggerReroll(), this.inputManager.isPointerDown = !1);
3505
3735
  }
@@ -3535,13 +3765,13 @@ class It {
3535
3765
  maxLifetime: 0.7
3536
3766
  });
3537
3767
  }
3538
- this.inputManager.forceRelease(), this.orbitingOrbs = [], this.isLevelUpActive = !1;
3768
+ this.inputManager.forceRelease(), this.orbitingOrbs = [], this.presentNextLevelUp();
3539
3769
  }
3540
3770
  } else
3541
3771
  s.update(t, this.core.position);
3542
3772
  }
3543
3773
  }
3544
- this.juice.hitstopTime <= 0 && this.physicsEngine.update(
3774
+ !this.isLevelUpActive && this.juice.hitstopTime <= 0 && this.physicsEngine.update(
3545
3775
  t,
3546
3776
  this.core,
3547
3777
  this.enemies,
@@ -3556,7 +3786,7 @@ class It {
3556
3786
  this.canvas.width,
3557
3787
  this.canvas.height,
3558
3788
  () => {
3559
- this.progressBar.addKill(), this.core.addKillRepair() && (this.juice.triggerFlash(0.4), this.floatingTexts.push({
3789
+ this.core.addKillRepair() && (this.juice.triggerFlash(0.4), this.floatingTexts.push({
3560
3790
  id: Math.random().toString(),
3561
3791
  text: "RING RESTORED!",
3562
3792
  position: { ...this.core.position },
@@ -3568,37 +3798,18 @@ class It {
3568
3798
  size: 22
3569
3799
  }));
3570
3800
  }
3571
- ), 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);
3801
+ ), 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);
3572
3802
  }
3573
3803
  triggerLevelUp(t) {
3574
- this.isLevelUpActive = !0;
3575
- for (const i of this.enemies)
3576
- if (i.active) {
3577
- i.triggerDissolveDeath();
3578
- for (let s = 0; s < 6; s++) {
3579
- const a = Math.random() * Math.PI * 2, l = 100 + Math.random() * 200;
3580
- this.particles.push({
3581
- id: Math.random().toString(),
3582
- position: { ...i.position },
3583
- velocity: { x: Math.cos(a) * l, y: Math.sin(a) * l },
3584
- color: "#00f0ff",
3585
- radius: 3 + Math.random() * 3,
3586
- alpha: 1,
3587
- lifetime: 0,
3588
- maxLifetime: 0.5
3589
- });
3590
- }
3591
- }
3592
- this.shockwaves.push({
3593
- id: Math.random().toString(),
3594
- position: { ...this.core.position },
3595
- radius: 20,
3596
- maxRadius: Math.max(this.canvas.width, this.canvas.height) * 1.4,
3597
- color: "#00f0ff",
3598
- alpha: 1,
3599
- lifetime: 0,
3600
- maxLifetime: 0.8
3601
- }), this.juice.triggerFlash(0.6), this.juice.triggerScreenShake({ x: 0, y: 1 }, 20), this.floatingTexts.push({
3804
+ this.pendingLevelUps.push(t), this.isLevelUpActive || this.presentNextLevelUp();
3805
+ }
3806
+ presentNextLevelUp() {
3807
+ const t = this.pendingLevelUps.shift();
3808
+ if (t === void 0) {
3809
+ this.isLevelUpActive = !1;
3810
+ return;
3811
+ }
3812
+ this.isLevelUpActive = !0, this.inputManager.forceRelease(), this.juice.triggerFlash(0.3), this.juice.triggerScreenShake({ x: 0, y: 1 }, 8), this.floatingTexts.push({
3602
3813
  id: Math.random().toString(),
3603
3814
  text: this.i18n.translate("levelUpChoose", { level: t }),
3604
3815
  position: { ...this.core.position },
@@ -3609,19 +3820,61 @@ class It {
3609
3820
  maxLifetime: 2,
3610
3821
  size: 30
3611
3822
  });
3612
- const e = F.getRandomOptions(3);
3823
+ for (let i = 0; i < 18; i++) {
3824
+ const s = Math.random() * Math.PI * 2, a = 80 + Math.random() * 160;
3825
+ this.particles.push({
3826
+ id: Math.random().toString(),
3827
+ position: { ...this.core.position },
3828
+ velocity: { x: Math.cos(s) * a, y: Math.sin(s) * a },
3829
+ color: "#00f0ff",
3830
+ radius: 2 + Math.random() * 3,
3831
+ alpha: 1,
3832
+ lifetime: 0,
3833
+ maxLifetime: 0.7
3834
+ });
3835
+ }
3836
+ const e = B.getRandomOptions(3);
3613
3837
  this.orbitingOrbs = e.map((i, s) => {
3614
3838
  const a = s * Math.PI * 2 / e.length;
3615
- return new K(`orb_${Date.now()}_${s}`, i, a);
3616
- }), this.hasRerolledThisLevel = !1;
3839
+ return new G(`orb_${Date.now()}_${s}`, i, a);
3840
+ }), this.rerollsRemaining = this.getRerollLimit();
3841
+ }
3842
+ spawnExperienceDrops() {
3843
+ for (const t of this.enemies)
3844
+ t.experienceDropPending && (t.experienceDropPending = !1, this.experienceOrbs.push(new lt(t.position)));
3845
+ }
3846
+ updateExperienceOrbs(t) {
3847
+ const e = E.getInstance().getConfig().magnet;
3848
+ for (const i of this.experienceOrbs)
3849
+ if (i.active) {
3850
+ if (i.isAbsorbing || Math.hypot(
3851
+ this.core.position.x - i.position.x,
3852
+ this.core.position.y - i.position.y
3853
+ ) <= this.core.getHitboxRadius() + e.corePickupRadius && i.beginAbsorption(), !i.isAbsorbing) {
3854
+ const s = this.inputManager.pointerPosition.x - i.position.x, a = this.inputManager.pointerPosition.y - i.position.y, l = e.psionicRadius + e.pickupRadius + i.radius;
3855
+ Math.hypot(s, a) <= l && i.beginAbsorption();
3856
+ }
3857
+ 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({
3858
+ id: Math.random().toString(),
3859
+ text: `+${i.value} XP`,
3860
+ position: { ...this.core.position },
3861
+ velocity: { x: 0, y: -55 },
3862
+ color: "#fbbf24",
3863
+ alpha: 1,
3864
+ lifetime: 0,
3865
+ maxLifetime: 0.8,
3866
+ size: 18
3867
+ }));
3868
+ }
3869
+ this.experienceOrbs = this.experienceOrbs.filter((i) => i.active);
3617
3870
  }
3618
3871
  triggerReroll() {
3619
- if (this.hasRerolledThisLevel) return;
3620
- this.hasRerolledThisLevel = !0, this.juice.triggerFlash(0.4);
3621
- const t = F.getRandomOptions(3);
3872
+ if (this.rerollsRemaining <= 0) return;
3873
+ this.rerollsRemaining -= 1, this.juice.triggerFlash(0.4);
3874
+ const t = B.getRandomOptions(3);
3622
3875
  this.orbitingOrbs = t.map((e, i) => {
3623
3876
  const s = i * Math.PI * 2 / t.length;
3624
- return new K(`orb_${Date.now()}_${i}`, e, s);
3877
+ return new G(`orb_${Date.now()}_${i}`, e, s);
3625
3878
  });
3626
3879
  }
3627
3880
  render() {
@@ -3629,6 +3882,7 @@ class It {
3629
3882
  this.renderer.render(
3630
3883
  this.core,
3631
3884
  t,
3885
+ this.experienceOrbs,
3632
3886
  this.pools,
3633
3887
  this.vortices,
3634
3888
  this.shockwaves,
@@ -3639,20 +3893,29 @@ class It {
3639
3893
  this.inputManager.pointerPosition,
3640
3894
  this.progressBar.getLevel(),
3641
3895
  this.interactiveTutorial.isActive ? this.interactiveTutorial : void 0
3642
- ), this.isLevelUpActive && this.orbitingOrbs.length > 0 && this.renderer.drawOrbitingModifierOrbs(this.orbitingOrbs, this.core.pulsePhase, this.i18n, !this.hasRerolledThisLevel);
3896
+ ), this.isLevelUpActive && this.orbitingOrbs.length > 0 && this.renderer.drawOrbitingModifierOrbs(
3897
+ this.orbitingOrbs,
3898
+ this.core.pulsePhase,
3899
+ this.i18n,
3900
+ this.rerollsRemaining > 0,
3901
+ this.rerollsRemaining
3902
+ );
3903
+ }
3904
+ getRerollLimit() {
3905
+ return this.debugRerollsEnabled ? 99 : 1;
3643
3906
  }
3644
3907
  destroy() {
3645
3908
  this.gameLoop.stop(), this.canvas.remove();
3646
3909
  }
3647
3910
  }
3648
- function Mt(E) {
3649
- return new It(E);
3911
+ function bt(y) {
3912
+ return new At(y);
3650
3913
  }
3651
3914
  export {
3652
- vt as BrowserPlatform,
3653
- It as GameEngine,
3654
- Y as LANGUAGES,
3655
- dt as ThemeManager,
3656
- Mt as createAxonSurge,
3657
- P as isLanguage
3915
+ Et as BrowserPlatform,
3916
+ At as GameEngine,
3917
+ K as LANGUAGES,
3918
+ ct as ThemeManager,
3919
+ bt as createAxonSurge,
3920
+ O as isLanguage
3658
3921
  };