@almadar/ui 5.85.0 → 5.87.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.
@@ -586,12 +586,12 @@ function kebabToPascal(name) {
586
586
  }).join("");
587
587
  }
588
588
  function loadLib(key, importer) {
589
- let p2 = libPromises.get(key);
590
- if (!p2) {
591
- p2 = importer();
592
- libPromises.set(key, p2);
589
+ let p = libPromises.get(key);
590
+ if (!p) {
591
+ p = importer();
592
+ libPromises.set(key, p);
593
593
  }
594
- return p2;
594
+ return p;
595
595
  }
596
596
  function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
597
597
  const Lazy = React97__namespace.default.lazy(async () => {
@@ -5880,28 +5880,28 @@ var init_ConfettiEffect = __esm({
5880
5880
  ),
5881
5881
  "aria-hidden": "true",
5882
5882
  children: [
5883
- particles.map((p2) => {
5884
- const rad = p2.angle * Math.PI / 180;
5885
- const tx = Math.cos(rad) * p2.distance;
5886
- const ty = Math.sin(rad) * p2.distance - 20;
5883
+ particles.map((p) => {
5884
+ const rad = p.angle * Math.PI / 180;
5885
+ const tx = Math.cos(rad) * p.distance;
5886
+ const ty = Math.sin(rad) * p.distance - 20;
5887
5887
  return /* @__PURE__ */ jsxRuntime.jsx(
5888
5888
  Box,
5889
5889
  {
5890
5890
  className: "absolute rounded-sm",
5891
5891
  style: {
5892
- left: `${p2.left}%`,
5892
+ left: `${p.left}%`,
5893
5893
  top: "50%",
5894
- width: p2.size,
5895
- height: p2.size,
5896
- backgroundColor: p2.color,
5897
- animation: `confetti-burst ${duration - p2.delay}ms ease-out ${p2.delay}ms forwards`,
5894
+ width: p.size,
5895
+ height: p.size,
5896
+ backgroundColor: p.color,
5897
+ animation: `confetti-burst ${duration - p.delay}ms ease-out ${p.delay}ms forwards`,
5898
5898
  opacity: 0,
5899
5899
  "--confetti-tx": `${tx}px`,
5900
5900
  "--confetti-ty": `${ty}px`,
5901
- "--confetti-rotate": `${p2.rotation}deg`
5901
+ "--confetti-rotate": `${p.rotation}deg`
5902
5902
  }
5903
5903
  },
5904
- p2.id
5904
+ p.id
5905
5905
  );
5906
5906
  }),
5907
5907
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
@@ -6812,8 +6812,8 @@ var init_AnimatedGraphic = __esm({
6812
6812
  const el = containerRef.current;
6813
6813
  if (!el || !strokeColor) return;
6814
6814
  const paths = el.querySelectorAll("path, line, polyline, polygon, circle, ellipse, rect");
6815
- paths.forEach((p2) => {
6816
- p2.style.stroke = strokeColor;
6815
+ paths.forEach((p) => {
6816
+ p.style.stroke = strokeColor;
6817
6817
  });
6818
6818
  }, [resolvedSvg, strokeColor]);
6819
6819
  React97.useEffect(() => {
@@ -6821,23 +6821,23 @@ var init_AnimatedGraphic = __esm({
6821
6821
  if (!el || !resolvedSvg) return;
6822
6822
  if (animation === "draw" || animation === "fill") {
6823
6823
  const paths = el.querySelectorAll("path, line, polyline, polygon, circle, ellipse, rect");
6824
- paths.forEach((p2) => {
6825
- if ("getTotalLength" in p2 && typeof p2.getTotalLength === "function") {
6826
- const len = p2.getTotalLength();
6827
- p2.style.strokeDasharray = `${len}`;
6828
- p2.style.strokeDashoffset = `${len}`;
6824
+ paths.forEach((p) => {
6825
+ if ("getTotalLength" in p && typeof p.getTotalLength === "function") {
6826
+ const len = p.getTotalLength();
6827
+ p.style.strokeDasharray = `${len}`;
6828
+ p.style.strokeDashoffset = `${len}`;
6829
6829
  }
6830
6830
  if (animation === "fill") {
6831
- p2.style.fillOpacity = "0";
6831
+ p.style.fillOpacity = "0";
6832
6832
  }
6833
6833
  });
6834
6834
  }
6835
6835
  if (animation === "morph") {
6836
6836
  const paths = el.querySelectorAll("path, circle, ellipse, rect, polygon");
6837
- paths.forEach((p2) => {
6838
- p2.style.transform = "scale(0)";
6839
- p2.style.transformOrigin = "center";
6840
- p2.style.opacity = "0";
6837
+ paths.forEach((p) => {
6838
+ p.style.transform = "scale(0)";
6839
+ p.style.transformOrigin = "center";
6840
+ p.style.opacity = "0";
6841
6841
  });
6842
6842
  }
6843
6843
  }, [resolvedSvg, animation]);
@@ -6942,14 +6942,8 @@ var init_TraitFrame = __esm({
6942
6942
  });
6943
6943
 
6944
6944
  // components/game/shared/effects.ts
6945
- var EMPTY_EFFECT_STATE;
6946
6945
  var init_effects = __esm({
6947
6946
  "components/game/shared/effects.ts"() {
6948
- EMPTY_EFFECT_STATE = {
6949
- particles: [],
6950
- sequences: [],
6951
- overlays: []
6952
- };
6953
6947
  }
6954
6948
  });
6955
6949
 
@@ -7345,1021 +7339,12 @@ var init_spriteAnimation = __esm({
7345
7339
  }
7346
7340
  });
7347
7341
 
7348
- // components/game/shared/combatPresets.ts
7349
- function p(manifest, key) {
7350
- const particles = manifest.particles;
7351
- if (!particles) return [];
7352
- const val = particles[key];
7353
- if (Array.isArray(val)) return val.map((v) => `${manifest.baseUrl}/${v}`);
7354
- if (typeof val === "string") return [`${manifest.baseUrl}/${val}`];
7355
- return [];
7356
- }
7357
- function anim(manifest, key) {
7358
- const animations = manifest.animations;
7359
- if (!animations) return [];
7360
- const val = animations[key];
7361
- if (Array.isArray(val)) return val.map((v) => `${manifest.baseUrl}/${v}`);
7362
- return [];
7363
- }
7364
- function createCombatPresets(manifest) {
7365
- return {
7366
- // =====================================================================
7367
- // MELEE — slash (red) + dirt + scratch + flash sequence
7368
- // =====================================================================
7369
- melee: (originX, originY) => {
7370
- const particles = [
7371
- {
7372
- spriteUrls: p(manifest, "slash"),
7373
- count: 6,
7374
- originX,
7375
- originY,
7376
- spread: 8,
7377
- velocityMin: 40,
7378
- velocityMax: 120,
7379
- angleMin: -PI2 * 0.8,
7380
- angleMax: -PI2 * 0.2,
7381
- gravity: 0,
7382
- tint: { r: 255, g: 60, b: 40 },
7383
- scaleMin: 0.3,
7384
- scaleMax: 0.6,
7385
- lifetimeMin: 300,
7386
- lifetimeMax: 500,
7387
- fadeRate: -2.5
7388
- },
7389
- {
7390
- spriteUrls: p(manifest, "dirt"),
7391
- count: 4,
7392
- originX,
7393
- originY: originY + 10,
7394
- spread: 12,
7395
- velocityMin: 20,
7396
- velocityMax: 60,
7397
- angleMin: -PI2 * 0.9,
7398
- angleMax: -PI2 * 0.1,
7399
- gravity: 120,
7400
- tint: { r: 180, g: 140, b: 90 },
7401
- scaleMin: 0.15,
7402
- scaleMax: 0.3,
7403
- lifetimeMin: 400,
7404
- lifetimeMax: 700,
7405
- fadeRate: -1.8
7406
- },
7407
- {
7408
- spriteUrls: p(manifest, "scratch"),
7409
- count: 2,
7410
- originX,
7411
- originY,
7412
- spread: 5,
7413
- velocityMin: 10,
7414
- velocityMax: 30,
7415
- angleMin: -PI2 * 0.7,
7416
- angleMax: -PI2 * 0.3,
7417
- gravity: 0,
7418
- tint: { r: 255, g: 200, b: 150 },
7419
- scaleMin: 0.25,
7420
- scaleMax: 0.4,
7421
- lifetimeMin: 200,
7422
- lifetimeMax: 400,
7423
- fadeRate: -3
7424
- }
7425
- ];
7426
- const sequences = [];
7427
- const flashFrames = anim(manifest, "flash");
7428
- if (flashFrames.length > 0) {
7429
- sequences.push({
7430
- frameUrls: flashFrames,
7431
- originX,
7432
- originY,
7433
- frameDuration: 35,
7434
- scale: 0.4
7435
- });
7436
- }
7437
- return {
7438
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
7439
- sequences,
7440
- overlays: [],
7441
- screenShake: 4,
7442
- screenFlash: null
7443
- };
7444
- },
7445
- // =====================================================================
7446
- // RANGED — muzzle + trace + smoke + explosion sequence
7447
- // =====================================================================
7448
- ranged: (originX, originY) => {
7449
- const particles = [
7450
- {
7451
- spriteUrls: p(manifest, "muzzle"),
7452
- count: 3,
7453
- originX,
7454
- originY,
7455
- spread: 4,
7456
- velocityMin: 60,
7457
- velocityMax: 150,
7458
- angleMin: -PI2 * 0.6,
7459
- angleMax: -PI2 * 0.4,
7460
- gravity: 0,
7461
- tint: { r: 255, g: 220, b: 100 },
7462
- scaleMin: 0.2,
7463
- scaleMax: 0.4,
7464
- lifetimeMin: 200,
7465
- lifetimeMax: 400,
7466
- fadeRate: -3
7467
- },
7468
- {
7469
- spriteUrls: p(manifest, "trace"),
7470
- count: 5,
7471
- originX,
7472
- originY,
7473
- spread: 3,
7474
- velocityMin: 100,
7475
- velocityMax: 200,
7476
- angleMin: -PI2 * 0.55,
7477
- angleMax: -PI2 * 0.45,
7478
- gravity: 0,
7479
- tint: { r: 255, g: 200, b: 80 },
7480
- scaleMin: 0.15,
7481
- scaleMax: 0.3,
7482
- lifetimeMin: 150,
7483
- lifetimeMax: 300,
7484
- fadeRate: -4
7485
- },
7486
- {
7487
- spriteUrls: p(manifest, "smoke").slice(0, 3),
7488
- count: 3,
7489
- originX,
7490
- originY: originY + 5,
7491
- spread: 6,
7492
- velocityMin: 10,
7493
- velocityMax: 30,
7494
- angleMin: -PI2 * 0.8,
7495
- angleMax: -PI2 * 0.2,
7496
- gravity: -20,
7497
- tint: { r: 200, g: 200, b: 200 },
7498
- scaleMin: 0.2,
7499
- scaleMax: 0.35,
7500
- lifetimeMin: 500,
7501
- lifetimeMax: 800,
7502
- fadeRate: -1.5
7503
- }
7504
- ];
7505
- const sequences = [];
7506
- const explosionFrames = anim(manifest, "smokeExplosion");
7507
- if (explosionFrames.length > 0) {
7508
- sequences.push({
7509
- frameUrls: explosionFrames,
7510
- originX,
7511
- originY,
7512
- frameDuration: 50,
7513
- scale: 0.35
7514
- });
7515
- }
7516
- return {
7517
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
7518
- sequences,
7519
- overlays: [],
7520
- screenShake: 2,
7521
- screenFlash: null
7522
- };
7523
- },
7524
- // =====================================================================
7525
- // MAGIC — twirl (purple) + spark (purple) + star
7526
- // =====================================================================
7527
- magic: (originX, originY) => {
7528
- const particles = [
7529
- {
7530
- spriteUrls: p(manifest, "twirl"),
7531
- count: 5,
7532
- originX,
7533
- originY,
7534
- spread: 15,
7535
- velocityMin: 20,
7536
- velocityMax: 80,
7537
- angleMin: 0,
7538
- angleMax: PI2 * 2,
7539
- gravity: -30,
7540
- tint: { r: 180, g: 80, b: 255 },
7541
- scaleMin: 0.2,
7542
- scaleMax: 0.5,
7543
- lifetimeMin: 500,
7544
- lifetimeMax: 900,
7545
- fadeRate: -1.2,
7546
- blendMode: "lighter",
7547
- rotationSpeedMin: -4,
7548
- rotationSpeedMax: 4
7549
- },
7550
- {
7551
- spriteUrls: p(manifest, "spark"),
7552
- count: 8,
7553
- originX,
7554
- originY,
7555
- spread: 20,
7556
- velocityMin: 30,
7557
- velocityMax: 100,
7558
- angleMin: 0,
7559
- angleMax: PI2 * 2,
7560
- gravity: -15,
7561
- tint: { r: 200, g: 120, b: 255 },
7562
- scaleMin: 0.1,
7563
- scaleMax: 0.25,
7564
- lifetimeMin: 300,
7565
- lifetimeMax: 600,
7566
- fadeRate: -2,
7567
- blendMode: "lighter"
7568
- },
7569
- {
7570
- spriteUrls: p(manifest, "star"),
7571
- count: 4,
7572
- originX,
7573
- originY,
7574
- spread: 10,
7575
- velocityMin: 15,
7576
- velocityMax: 50,
7577
- angleMin: -PI2,
7578
- angleMax: 0,
7579
- gravity: -40,
7580
- tint: { r: 220, g: 180, b: 255 },
7581
- scaleMin: 0.15,
7582
- scaleMax: 0.3,
7583
- lifetimeMin: 600,
7584
- lifetimeMax: 1e3,
7585
- fadeRate: -1,
7586
- blendMode: "lighter"
7587
- }
7588
- ];
7589
- const overlays = [];
7590
- const circleUrls = p(manifest, "circle");
7591
- if (circleUrls.length > 0) {
7592
- overlays.push({
7593
- spriteUrl: circleUrls[0],
7594
- originX,
7595
- originY,
7596
- alpha: 0.5,
7597
- fadeRate: -0.6,
7598
- pulseAmplitude: 0.2,
7599
- pulseFrequency: 3,
7600
- scale: 0.5,
7601
- blendMode: "lighter",
7602
- lifetime: 1200
7603
- });
7604
- }
7605
- return {
7606
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
7607
- sequences: [],
7608
- overlays,
7609
- screenShake: 0,
7610
- screenFlash: null
7611
- };
7612
- },
7613
- // =====================================================================
7614
- // HEAL — circle (green) + star (green) + light (green, pulse)
7615
- // =====================================================================
7616
- heal: (originX, originY) => {
7617
- const particles = [
7618
- {
7619
- spriteUrls: p(manifest, "circle"),
7620
- count: 6,
7621
- originX,
7622
- originY,
7623
- spread: 15,
7624
- velocityMin: 10,
7625
- velocityMax: 40,
7626
- angleMin: -PI2,
7627
- angleMax: -PI2 * 0.3,
7628
- gravity: -50,
7629
- tint: { r: 80, g: 255, b: 120 },
7630
- scaleMin: 0.15,
7631
- scaleMax: 0.35,
7632
- lifetimeMin: 600,
7633
- lifetimeMax: 1e3,
7634
- fadeRate: -0.8,
7635
- blendMode: "lighter"
7636
- },
7637
- {
7638
- spriteUrls: p(manifest, "star"),
7639
- count: 5,
7640
- originX,
7641
- originY,
7642
- spread: 12,
7643
- velocityMin: 15,
7644
- velocityMax: 50,
7645
- angleMin: -PI2 * 0.9,
7646
- angleMax: -PI2 * 0.1,
7647
- gravity: -60,
7648
- tint: { r: 100, g: 255, b: 140 },
7649
- scaleMin: 0.1,
7650
- scaleMax: 0.2,
7651
- lifetimeMin: 500,
7652
- lifetimeMax: 800,
7653
- fadeRate: -1.2,
7654
- blendMode: "lighter"
7655
- }
7656
- ];
7657
- const overlays = [];
7658
- const lightUrls = p(manifest, "light");
7659
- if (lightUrls.length > 0) {
7660
- overlays.push({
7661
- spriteUrl: lightUrls[0],
7662
- originX,
7663
- originY,
7664
- alpha: 0.6,
7665
- fadeRate: -0.4,
7666
- pulseAmplitude: 0.25,
7667
- pulseFrequency: 2.5,
7668
- scale: 0.6,
7669
- blendMode: "lighter",
7670
- lifetime: 1500
7671
- });
7672
- }
7673
- return {
7674
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
7675
- sequences: [],
7676
- overlays,
7677
- screenShake: 0,
7678
- screenFlash: null
7679
- };
7680
- },
7681
- // =====================================================================
7682
- // DEFEND / SHIELD — star (blue) + circle (blue, pulse)
7683
- // =====================================================================
7684
- defend: (originX, originY) => {
7685
- const particles = [
7686
- {
7687
- spriteUrls: p(manifest, "star"),
7688
- count: 8,
7689
- originX,
7690
- originY,
7691
- spread: 18,
7692
- velocityMin: 10,
7693
- velocityMax: 35,
7694
- angleMin: 0,
7695
- angleMax: PI2 * 2,
7696
- gravity: 0,
7697
- tint: { r: 80, g: 160, b: 255 },
7698
- scaleMin: 0.12,
7699
- scaleMax: 0.25,
7700
- lifetimeMin: 600,
7701
- lifetimeMax: 1e3,
7702
- fadeRate: -0.8,
7703
- blendMode: "lighter",
7704
- rotationSpeedMin: -1,
7705
- rotationSpeedMax: 1
7706
- }
7707
- ];
7708
- const overlays = [];
7709
- const circleUrls = p(manifest, "circle");
7710
- if (circleUrls.length > 0) {
7711
- overlays.push({
7712
- spriteUrl: circleUrls[0],
7713
- originX,
7714
- originY,
7715
- alpha: 0.6,
7716
- fadeRate: -0.3,
7717
- pulseAmplitude: 0.2,
7718
- pulseFrequency: 2,
7719
- scale: 0.6,
7720
- blendMode: "lighter",
7721
- lifetime: 1500
7722
- });
7723
- }
7724
- return {
7725
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
7726
- sequences: [],
7727
- overlays,
7728
- screenShake: 0,
7729
- screenFlash: null
7730
- };
7731
- },
7732
- // shield aliases to defend
7733
- shield: (originX, originY) => {
7734
- const particles = [
7735
- {
7736
- spriteUrls: p(manifest, "star"),
7737
- count: 10,
7738
- originX,
7739
- originY,
7740
- spread: 20,
7741
- velocityMin: 8,
7742
- velocityMax: 30,
7743
- angleMin: 0,
7744
- angleMax: PI2 * 2,
7745
- gravity: 0,
7746
- tint: { r: 60, g: 180, b: 255 },
7747
- scaleMin: 0.1,
7748
- scaleMax: 0.22,
7749
- lifetimeMin: 700,
7750
- lifetimeMax: 1200,
7751
- fadeRate: -0.7,
7752
- blendMode: "lighter",
7753
- rotationSpeedMin: -0.8,
7754
- rotationSpeedMax: 0.8
7755
- }
7756
- ];
7757
- const overlays = [];
7758
- const circleUrls = p(manifest, "circle");
7759
- if (circleUrls.length > 0) {
7760
- overlays.push({
7761
- spriteUrl: circleUrls[0],
7762
- originX,
7763
- originY,
7764
- alpha: 0.7,
7765
- fadeRate: -0.25,
7766
- pulseAmplitude: 0.25,
7767
- pulseFrequency: 1.8,
7768
- scale: 0.7,
7769
- blendMode: "lighter",
7770
- lifetime: 1800
7771
- });
7772
- }
7773
- return {
7774
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
7775
- sequences: [],
7776
- overlays,
7777
- screenShake: 0,
7778
- screenFlash: null
7779
- };
7780
- },
7781
- // =====================================================================
7782
- // HIT — spark (orange) + flash (5 frames) + screen shake/flash
7783
- // =====================================================================
7784
- hit: (originX, originY) => {
7785
- const particles = [
7786
- {
7787
- spriteUrls: p(manifest, "spark"),
7788
- count: 10,
7789
- originX,
7790
- originY,
7791
- spread: 8,
7792
- velocityMin: 50,
7793
- velocityMax: 150,
7794
- angleMin: 0,
7795
- angleMax: PI2 * 2,
7796
- gravity: 80,
7797
- tint: { r: 255, g: 180, b: 50 },
7798
- scaleMin: 0.08,
7799
- scaleMax: 0.2,
7800
- lifetimeMin: 200,
7801
- lifetimeMax: 500,
7802
- fadeRate: -2.5
7803
- }
7804
- ];
7805
- const sequences = [];
7806
- const flashFrames = anim(manifest, "flash");
7807
- if (flashFrames.length > 0) {
7808
- sequences.push({
7809
- frameUrls: flashFrames.slice(0, 5),
7810
- originX,
7811
- originY,
7812
- frameDuration: 40,
7813
- scale: 0.3
7814
- });
7815
- }
7816
- return {
7817
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
7818
- sequences,
7819
- overlays: [],
7820
- screenShake: 3,
7821
- screenFlash: { r: 255, g: 50, b: 50, duration: 150 }
7822
- };
7823
- },
7824
- // critical aliases to hit with bigger shake
7825
- critical: (originX, originY) => {
7826
- const particles = [
7827
- {
7828
- spriteUrls: p(manifest, "flame"),
7829
- count: 8,
7830
- originX,
7831
- originY,
7832
- spread: 12,
7833
- velocityMin: 60,
7834
- velocityMax: 180,
7835
- angleMin: 0,
7836
- angleMax: PI2 * 2,
7837
- gravity: 60,
7838
- tint: { r: 255, g: 120, b: 30 },
7839
- scaleMin: 0.15,
7840
- scaleMax: 0.4,
7841
- lifetimeMin: 300,
7842
- lifetimeMax: 600,
7843
- fadeRate: -2
7844
- },
7845
- {
7846
- spriteUrls: p(manifest, "spark"),
7847
- count: 12,
7848
- originX,
7849
- originY,
7850
- spread: 10,
7851
- velocityMin: 80,
7852
- velocityMax: 200,
7853
- angleMin: 0,
7854
- angleMax: PI2 * 2,
7855
- gravity: 100,
7856
- tint: { r: 255, g: 200, b: 60 },
7857
- scaleMin: 0.06,
7858
- scaleMax: 0.18,
7859
- lifetimeMin: 200,
7860
- lifetimeMax: 400,
7861
- fadeRate: -3
7862
- }
7863
- ];
7864
- const sequences = [];
7865
- const flashFrames = anim(manifest, "flash");
7866
- if (flashFrames.length > 0) {
7867
- sequences.push({
7868
- frameUrls: flashFrames,
7869
- originX,
7870
- originY,
7871
- frameDuration: 30,
7872
- scale: 0.5
7873
- });
7874
- }
7875
- return {
7876
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
7877
- sequences,
7878
- overlays: [],
7879
- screenShake: 6,
7880
- screenFlash: { r: 255, g: 80, b: 0, duration: 200 }
7881
- };
7882
- },
7883
- // =====================================================================
7884
- // DEATH — dirt (gray) + explosion + black smoke + scorch (ground)
7885
- // =====================================================================
7886
- death: (originX, originY) => {
7887
- const particles = [
7888
- {
7889
- spriteUrls: p(manifest, "dirt"),
7890
- count: 8,
7891
- originX,
7892
- originY,
7893
- spread: 10,
7894
- velocityMin: 30,
7895
- velocityMax: 100,
7896
- angleMin: 0,
7897
- angleMax: PI2 * 2,
7898
- gravity: 100,
7899
- tint: { r: 140, g: 140, b: 140 },
7900
- scaleMin: 0.15,
7901
- scaleMax: 0.35,
7902
- lifetimeMin: 500,
7903
- lifetimeMax: 900,
7904
- fadeRate: -1.2
7905
- }
7906
- ];
7907
- const sequences = [];
7908
- const explosionFrames = anim(manifest, "explosion");
7909
- if (explosionFrames.length > 0) {
7910
- sequences.push({
7911
- frameUrls: explosionFrames,
7912
- originX,
7913
- originY,
7914
- frameDuration: 60,
7915
- scale: 0.5
7916
- });
7917
- }
7918
- const blackSmokeFrames = anim(manifest, "blackSmoke");
7919
- if (blackSmokeFrames.length > 0) {
7920
- sequences.push({
7921
- frameUrls: blackSmokeFrames,
7922
- originX,
7923
- originY: originY - 10,
7924
- frameDuration: 50,
7925
- scale: 0.4,
7926
- alpha: 0.7
7927
- });
7928
- }
7929
- const overlays = [];
7930
- const scorchUrls = p(manifest, "scorch");
7931
- if (scorchUrls.length > 0) {
7932
- overlays.push({
7933
- spriteUrl: scorchUrls[0],
7934
- originX,
7935
- originY: originY + 10,
7936
- alpha: 0.6,
7937
- fadeRate: -0.15,
7938
- scale: 0.4,
7939
- lifetime: 4e3
7940
- });
7941
- }
7942
- return {
7943
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
7944
- sequences,
7945
- overlays,
7946
- screenShake: 0,
7947
- screenFlash: null
7948
- };
7949
- },
7950
- // =====================================================================
7951
- // BUFF — star (gold) + symbol + flare (gold, pulse)
7952
- // =====================================================================
7953
- buff: (originX, originY) => {
7954
- const particles = [
7955
- {
7956
- spriteUrls: p(manifest, "star"),
7957
- count: 6,
7958
- originX,
7959
- originY,
7960
- spread: 15,
7961
- velocityMin: 15,
7962
- velocityMax: 50,
7963
- angleMin: -PI2,
7964
- angleMax: 0,
7965
- gravity: -30,
7966
- tint: { r: 255, g: 215, b: 50 },
7967
- scaleMin: 0.12,
7968
- scaleMax: 0.25,
7969
- lifetimeMin: 600,
7970
- lifetimeMax: 1e3,
7971
- fadeRate: -0.8,
7972
- blendMode: "lighter"
7973
- },
7974
- {
7975
- spriteUrls: p(manifest, "symbol"),
7976
- count: 2,
7977
- originX,
7978
- originY: originY - 10,
7979
- spread: 8,
7980
- velocityMin: 5,
7981
- velocityMax: 20,
7982
- angleMin: -PI2 * 0.7,
7983
- angleMax: -PI2 * 0.3,
7984
- gravity: -20,
7985
- tint: { r: 255, g: 230, b: 100 },
7986
- scaleMin: 0.2,
7987
- scaleMax: 0.35,
7988
- lifetimeMin: 800,
7989
- lifetimeMax: 1200,
7990
- fadeRate: -0.6,
7991
- blendMode: "lighter"
7992
- }
7993
- ];
7994
- const overlays = [];
7995
- const flareUrls = p(manifest, "flare");
7996
- if (flareUrls.length > 0) {
7997
- overlays.push({
7998
- spriteUrl: flareUrls[0],
7999
- originX,
8000
- originY,
8001
- alpha: 0.5,
8002
- fadeRate: -0.3,
8003
- pulseAmplitude: 0.3,
8004
- pulseFrequency: 2,
8005
- scale: 0.5,
8006
- blendMode: "lighter",
8007
- lifetime: 1500
8008
- });
8009
- }
8010
- return {
8011
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
8012
- sequences: [],
8013
- overlays,
8014
- screenShake: 0,
8015
- screenFlash: null
8016
- };
8017
- },
8018
- // =====================================================================
8019
- // DEBUFF — scorch (dark) + smoke (purple tint)
8020
- // =====================================================================
8021
- debuff: (originX, originY) => {
8022
- const particles = [
8023
- {
8024
- spriteUrls: p(manifest, "scorch"),
8025
- count: 4,
8026
- originX,
8027
- originY,
8028
- spread: 12,
8029
- velocityMin: 15,
8030
- velocityMax: 40,
8031
- angleMin: -PI2,
8032
- angleMax: 0,
8033
- gravity: -20,
8034
- tint: { r: 120, g: 40, b: 160 },
8035
- scaleMin: 0.15,
8036
- scaleMax: 0.3,
8037
- lifetimeMin: 500,
8038
- lifetimeMax: 800,
8039
- fadeRate: -1
8040
- },
8041
- {
8042
- spriteUrls: p(manifest, "smoke").slice(0, 3),
8043
- count: 3,
8044
- originX,
8045
- originY,
8046
- spread: 10,
8047
- velocityMin: 8,
8048
- velocityMax: 25,
8049
- angleMin: -PI2 * 0.8,
8050
- angleMax: -PI2 * 0.2,
8051
- gravity: -15,
8052
- tint: { r: 100, g: 50, b: 140 },
8053
- scaleMin: 0.2,
8054
- scaleMax: 0.35,
8055
- lifetimeMin: 600,
8056
- lifetimeMax: 1e3,
8057
- fadeRate: -0.8
8058
- }
8059
- ];
8060
- const overlays = [];
8061
- const circleUrls = p(manifest, "circle");
8062
- if (circleUrls.length > 0) {
8063
- overlays.push({
8064
- spriteUrl: circleUrls[0],
8065
- originX,
8066
- originY,
8067
- alpha: 0.4,
8068
- fadeRate: -0.4,
8069
- pulseAmplitude: 0.15,
8070
- pulseFrequency: 2,
8071
- scale: 0.45,
8072
- lifetime: 1200
8073
- });
8074
- }
8075
- return {
8076
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
8077
- sequences: [],
8078
- overlays,
8079
- screenShake: 0,
8080
- screenFlash: null
8081
- };
8082
- },
8083
- // =====================================================================
8084
- // AOE — explosion (large) + flame + spark (radial) + screen shake
8085
- // =====================================================================
8086
- aoe: (originX, originY) => {
8087
- const particles = [
8088
- {
8089
- spriteUrls: p(manifest, "flame"),
8090
- count: 10,
8091
- originX,
8092
- originY,
8093
- spread: 20,
8094
- velocityMin: 40,
8095
- velocityMax: 140,
8096
- angleMin: 0,
8097
- angleMax: PI2 * 2,
8098
- gravity: 40,
8099
- tint: { r: 255, g: 140, b: 30 },
8100
- scaleMin: 0.2,
8101
- scaleMax: 0.5,
8102
- lifetimeMin: 400,
8103
- lifetimeMax: 800,
8104
- fadeRate: -1.5
8105
- },
8106
- {
8107
- spriteUrls: p(manifest, "spark"),
8108
- count: 15,
8109
- originX,
8110
- originY,
8111
- spread: 15,
8112
- velocityMin: 60,
8113
- velocityMax: 200,
8114
- angleMin: 0,
8115
- angleMax: PI2 * 2,
8116
- gravity: 60,
8117
- tint: { r: 255, g: 180, b: 60 },
8118
- scaleMin: 0.06,
8119
- scaleMax: 0.15,
8120
- lifetimeMin: 200,
8121
- lifetimeMax: 500,
8122
- fadeRate: -2.5
8123
- }
8124
- ];
8125
- const sequences = [];
8126
- const explosionFrames = anim(manifest, "explosion");
8127
- if (explosionFrames.length > 0) {
8128
- sequences.push({
8129
- frameUrls: explosionFrames,
8130
- originX,
8131
- originY,
8132
- frameDuration: 50,
8133
- scale: 0.6
8134
- });
8135
- }
8136
- return {
8137
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
8138
- sequences,
8139
- overlays: [],
8140
- screenShake: 5,
8141
- screenFlash: { r: 255, g: 160, b: 0, duration: 180 }
8142
- };
8143
- }
8144
- };
8145
- }
8146
- var PI2;
8147
- var init_combatPresets = __esm({
8148
- "components/game/shared/combatPresets.ts"() {
8149
- PI2 = Math.PI;
8150
- }
8151
- });
8152
-
8153
- // components/game/shared/canvasEffects.ts
8154
- function getOffscreenCtx(w, h) {
8155
- if (!_offscreen) {
8156
- if (typeof OffscreenCanvas !== "undefined") {
8157
- _offscreen = new OffscreenCanvas(w, h);
8158
- } else {
8159
- _offscreen = document.createElement("canvas");
8160
- }
8161
- }
8162
- if (_offscreen.width < w) _offscreen.width = w;
8163
- if (_offscreen.height < h) _offscreen.height = h;
8164
- if (!_offCtx) {
8165
- _offCtx = _offscreen.getContext("2d");
8166
- }
8167
- return _offCtx;
8168
- }
8169
- function drawTintedImage(ctx, img, x, y, w, h, tint, alpha, blendMode = "source-over") {
8170
- if (w <= 0 || h <= 0) return;
8171
- const oc = getOffscreenCtx(w, h);
8172
- oc.clearRect(0, 0, w, h);
8173
- oc.globalCompositeOperation = "source-over";
8174
- oc.drawImage(img, 0, 0, w, h);
8175
- oc.globalCompositeOperation = "source-atop";
8176
- oc.fillStyle = `rgb(${tint.r}, ${tint.g}, ${tint.b})`;
8177
- oc.fillRect(0, 0, w, h);
8178
- const prevAlpha = ctx.globalAlpha;
8179
- const prevBlend = ctx.globalCompositeOperation;
8180
- ctx.globalAlpha = alpha;
8181
- ctx.globalCompositeOperation = blendMode;
8182
- ctx.drawImage(_offscreen, 0, 0, w, h, x, y, w, h);
8183
- ctx.globalAlpha = prevAlpha;
8184
- ctx.globalCompositeOperation = prevBlend;
8185
- }
8186
- function randRange(min, max) {
8187
- return min + Math.random() * (max - min);
8188
- }
8189
- function spawnParticles(config, animTime) {
8190
- const particles = [];
8191
- for (let i = 0; i < config.count; i++) {
8192
- const angle = randRange(config.angleMin, config.angleMax);
8193
- const speed = randRange(config.velocityMin, config.velocityMax);
8194
- const spriteUrl = config.spriteUrls[Math.floor(Math.random() * config.spriteUrls.length)];
8195
- particles.push({
8196
- spriteUrl,
8197
- x: config.originX + randRange(-config.spread, config.spread),
8198
- y: config.originY + randRange(-config.spread, config.spread),
8199
- vx: Math.cos(angle) * speed,
8200
- vy: Math.sin(angle) * speed,
8201
- gravity: config.gravity,
8202
- rotation: Math.random() * Math.PI * 2,
8203
- rotationSpeed: randRange(config.rotationSpeedMin ?? -2, config.rotationSpeedMax ?? 2),
8204
- scale: randRange(config.scaleMin, config.scaleMax),
8205
- scaleSpeed: config.scaleSpeed ?? 0,
8206
- alpha: config.alpha ?? 1,
8207
- fadeRate: config.fadeRate ?? -1.5,
8208
- tint: { ...config.tint },
8209
- blendMode: config.blendMode ?? "source-over",
8210
- spawnTime: animTime,
8211
- lifetime: randRange(config.lifetimeMin, config.lifetimeMax)
8212
- });
8213
- }
8214
- return particles;
8215
- }
8216
- function spawnSequence(config, animTime) {
8217
- return {
8218
- frameUrls: config.frameUrls,
8219
- x: config.originX,
8220
- y: config.originY,
8221
- frameDuration: config.frameDuration,
8222
- startTime: animTime,
8223
- loop: config.loop ?? false,
8224
- scale: config.scale ?? 1,
8225
- tint: config.tint ?? null,
8226
- alpha: config.alpha ?? 1,
8227
- blendMode: config.blendMode ?? "source-over"
8228
- };
8229
- }
8230
- function spawnOverlay(config, animTime) {
8231
- return {
8232
- spriteUrl: config.spriteUrl,
8233
- x: config.originX,
8234
- y: config.originY,
8235
- alpha: config.alpha ?? 0.8,
8236
- fadeRate: config.fadeRate ?? -0.5,
8237
- pulseAmplitude: config.pulseAmplitude ?? 0,
8238
- pulseFrequency: config.pulseFrequency ?? 2,
8239
- scale: config.scale ?? 1,
8240
- blendMode: config.blendMode ?? "source-over",
8241
- spawnTime: animTime,
8242
- lifetime: config.lifetime ?? 2e3
8243
- };
8244
- }
8245
- function updateEffectState(state, animTime, deltaMs) {
8246
- const dt = deltaMs / 1e3;
8247
- const particles = state.particles.map((p2) => ({
8248
- ...p2,
8249
- x: p2.x + p2.vx * dt,
8250
- y: p2.y + p2.vy * dt,
8251
- vy: p2.vy + p2.gravity * dt,
8252
- rotation: p2.rotation + p2.rotationSpeed * dt,
8253
- scale: Math.max(0, p2.scale + p2.scaleSpeed * dt),
8254
- alpha: Math.max(0, p2.alpha + p2.fadeRate * dt)
8255
- })).filter((p2) => p2.alpha > 0.01 && animTime - p2.spawnTime < p2.lifetime);
8256
- const sequences = state.sequences.filter((s) => {
8257
- const elapsed = animTime - s.startTime;
8258
- const totalDuration = s.frameUrls.length * s.frameDuration;
8259
- return s.loop || elapsed < totalDuration;
8260
- });
8261
- const overlays = state.overlays.map((o) => ({
8262
- ...o,
8263
- alpha: Math.max(0, o.alpha + o.fadeRate * dt)
8264
- })).filter((o) => o.alpha > 0.01 && animTime - o.spawnTime < o.lifetime);
8265
- return { particles, sequences, overlays };
8266
- }
8267
- function drawEffectState(ctx, state, animTime, getImage) {
8268
- for (const o of state.overlays) {
8269
- const img = getImage(o.spriteUrl);
8270
- if (!img) continue;
8271
- let alpha = o.alpha;
8272
- if (o.pulseAmplitude > 0) {
8273
- const elapsed = (animTime - o.spawnTime) / 1e3;
8274
- alpha += Math.sin(elapsed * o.pulseFrequency * Math.PI * 2) * o.pulseAmplitude;
8275
- alpha = Math.max(0, Math.min(1, alpha));
8276
- }
8277
- const w = img.naturalWidth * o.scale;
8278
- const h = img.naturalHeight * o.scale;
8279
- const prevAlpha = ctx.globalAlpha;
8280
- const prevBlend = ctx.globalCompositeOperation;
8281
- ctx.globalAlpha = alpha;
8282
- ctx.globalCompositeOperation = o.blendMode;
8283
- ctx.drawImage(img, o.x - w / 2, o.y - h / 2, w, h);
8284
- ctx.globalAlpha = prevAlpha;
8285
- ctx.globalCompositeOperation = prevBlend;
8286
- }
8287
- for (const s of state.sequences) {
8288
- const elapsed = animTime - s.startTime;
8289
- let frameIndex = Math.floor(elapsed / s.frameDuration);
8290
- if (s.loop) {
8291
- frameIndex = frameIndex % s.frameUrls.length;
8292
- } else if (frameIndex >= s.frameUrls.length) {
8293
- continue;
8294
- }
8295
- const img = getImage(s.frameUrls[frameIndex]);
8296
- if (!img) continue;
8297
- const w = img.naturalWidth * s.scale;
8298
- const h = img.naturalHeight * s.scale;
8299
- if (s.tint) {
8300
- drawTintedImage(ctx, img, s.x - w / 2, s.y - h / 2, w, h, s.tint, s.alpha, s.blendMode);
8301
- } else {
8302
- const prevAlpha = ctx.globalAlpha;
8303
- const prevBlend = ctx.globalCompositeOperation;
8304
- ctx.globalAlpha = s.alpha;
8305
- ctx.globalCompositeOperation = s.blendMode;
8306
- ctx.drawImage(img, s.x - w / 2, s.y - h / 2, w, h);
8307
- ctx.globalAlpha = prevAlpha;
8308
- ctx.globalCompositeOperation = prevBlend;
8309
- }
8310
- }
8311
- for (const p2 of state.particles) {
8312
- const img = getImage(p2.spriteUrl);
8313
- if (!img) continue;
8314
- const w = img.naturalWidth * p2.scale;
8315
- const h = img.naturalHeight * p2.scale;
8316
- ctx.save();
8317
- ctx.translate(p2.x, p2.y);
8318
- ctx.rotate(p2.rotation);
8319
- drawTintedImage(ctx, img, -w / 2, -h / 2, w, h, p2.tint, p2.alpha, p2.blendMode);
8320
- ctx.restore();
8321
- }
8322
- }
8323
- function hasActiveEffects(state) {
8324
- return state.particles.length > 0 || state.sequences.length > 0 || state.overlays.length > 0;
8325
- }
8326
- function getAllEffectSpriteUrls(manifest) {
8327
- const urls = [];
8328
- const base = manifest.baseUrl;
8329
- if (manifest.particles) {
8330
- for (const value of Object.values(manifest.particles)) {
8331
- if (Array.isArray(value)) {
8332
- value.forEach((v) => urls.push(`${base}/${v}`));
8333
- } else if (typeof value === "string") {
8334
- urls.push(`${base}/${value}`);
8335
- }
8336
- }
8337
- }
8338
- if (manifest.animations) {
8339
- for (const frames of Object.values(manifest.animations)) {
8340
- if (Array.isArray(frames)) {
8341
- frames.forEach((f3) => urls.push(`${base}/${f3}`));
8342
- }
8343
- }
8344
- }
8345
- return urls;
8346
- }
8347
- var _offscreen, _offCtx;
8348
- var init_canvasEffects = __esm({
8349
- "components/game/shared/canvasEffects.ts"() {
8350
- _offscreen = null;
8351
- _offCtx = null;
8352
- }
8353
- });
8354
-
8355
7342
  // components/game/shared/index.ts
8356
7343
  var init_shared = __esm({
8357
7344
  "components/game/shared/index.ts"() {
8358
7345
  init_effects();
8359
7346
  init_boardEntity();
8360
7347
  init_makeAsset();
8361
- init_combatPresets();
8362
- init_canvasEffects();
8363
7348
  }
8364
7349
  });
8365
7350
  function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
@@ -10694,13 +9679,13 @@ function useRenderInterpolation(options = {}) {
10694
9679
  const prevMap = /* @__PURE__ */ new Map();
10695
9680
  for (const e of prev.entities) prevMap.set(e.id, e);
10696
9681
  for (const c of curr.entities) {
10697
- const p2 = prevMap.get(c.id);
10698
- if (!p2) {
9682
+ const p = prevMap.get(c.id);
9683
+ if (!p) {
10699
9684
  out.set(c.id, { x: c.x, y: c.y });
10700
9685
  } else {
10701
9686
  out.set(c.id, {
10702
- x: p2.x + (c.x - p2.x) * alpha,
10703
- y: p2.y + (c.y - p2.y) * alpha
9687
+ x: p.x + (c.x - p.x) * alpha,
9688
+ y: p.y + (c.y - p.y) * alpha
10704
9689
  });
10705
9690
  }
10706
9691
  }
@@ -11265,8 +10250,8 @@ function Canvas2D({
11265
10250
  if (isFree) return 0;
11266
10251
  return (gridHeight - 1) * (scaledTileWidth / 2);
11267
10252
  }, [isFree, gridHeight, scaledTileWidth]);
11268
- const validMoveSet = React97.useMemo(() => new Set(validMoves.map((p2) => `${p2.x},${p2.y}`)), [validMoves]);
11269
- const attackTargetSet = React97.useMemo(() => new Set(attackTargets.map((p2) => `${p2.x},${p2.y}`)), [attackTargets]);
10253
+ const validMoveSet = React97.useMemo(() => new Set(validMoves.map((p) => `${p.x},${p.y}`)), [validMoves]);
10254
+ const attackTargetSet = React97.useMemo(() => new Set(attackTargets.map((p) => `${p.x},${p.y}`)), [attackTargets]);
11270
10255
  const spriteUrls = React97.useMemo(() => {
11271
10256
  const urls = [];
11272
10257
  for (const tile of sortedTiles) {
@@ -11983,264 +10968,6 @@ var init_Canvas2D = __esm({
11983
10968
  Canvas2D.displayName = "Canvas2D";
11984
10969
  }
11985
10970
  });
11986
- function CanvasEffectEngine({
11987
- actionType,
11988
- x,
11989
- y,
11990
- duration = 2e3,
11991
- intensity = 1,
11992
- onComplete,
11993
- className,
11994
- assetManifest,
11995
- width = 400,
11996
- height = 300
11997
- }) {
11998
- const canvasRef = React97.useRef(null);
11999
- const stateRef = React97.useRef({ ...EMPTY_EFFECT_STATE });
12000
- const lastTimeRef = React97.useRef(0);
12001
- const rafRef = React97.useRef(0);
12002
- const imageCacheRef = React97.useRef(/* @__PURE__ */ new Map());
12003
- const [shakeOffset, setShakeOffset] = React97.useState({ x: 0, y: 0 });
12004
- const [flash, setFlash] = React97.useState(null);
12005
- const shakeRef = React97.useRef({ x: 0, y: 0, intensity: 0 });
12006
- const presets = React97.useMemo(() => createCombatPresets(assetManifest), [assetManifest]);
12007
- const spriteUrls = React97.useMemo(() => getAllEffectSpriteUrls(assetManifest), [assetManifest]);
12008
- React97.useEffect(() => {
12009
- const cache = imageCacheRef.current;
12010
- for (const url of spriteUrls) {
12011
- if (!cache.has(url)) {
12012
- const img = new Image();
12013
- img.crossOrigin = "anonymous";
12014
- img.src = url;
12015
- cache.set(url, img);
12016
- }
12017
- }
12018
- }, [spriteUrls]);
12019
- const getImage = React97.useCallback((url) => {
12020
- const img = imageCacheRef.current.get(url);
12021
- return img?.complete ? img : void 0;
12022
- }, []);
12023
- React97.useEffect(() => {
12024
- const now = performance.now();
12025
- const effectX = x || width / 2;
12026
- const effectY = y || height / 2;
12027
- const preset = presets[actionType](effectX, effectY);
12028
- const state = stateRef.current;
12029
- for (const emitter of preset.particles) {
12030
- const scaledEmitter = { ...emitter, count: Math.round(emitter.count * intensity) };
12031
- state.particles.push(...spawnParticles(scaledEmitter, now));
12032
- }
12033
- for (const seqConfig of preset.sequences) {
12034
- state.sequences.push(spawnSequence(seqConfig, now));
12035
- }
12036
- for (const ovConfig of preset.overlays) {
12037
- state.overlays.push(spawnOverlay(ovConfig, now));
12038
- }
12039
- if (preset.screenShake > 0) {
12040
- shakeRef.current.intensity = preset.screenShake * intensity;
12041
- }
12042
- if (preset.screenFlash) {
12043
- const { r, g, b, duration: flashDur } = preset.screenFlash;
12044
- setFlash({ color: `rgb(${r}, ${g}, ${b})`, alpha: 0.3 });
12045
- setTimeout(() => setFlash(null), flashDur);
12046
- }
12047
- const timer = setTimeout(() => {
12048
- onComplete?.();
12049
- }, duration);
12050
- return () => clearTimeout(timer);
12051
- }, []);
12052
- React97.useEffect(() => {
12053
- const canvas = canvasRef.current;
12054
- if (!canvas) return;
12055
- const ctx = canvas.getContext("2d");
12056
- if (!ctx) return;
12057
- function loop(animTime) {
12058
- const delta = lastTimeRef.current > 0 ? animTime - lastTimeRef.current : 16;
12059
- lastTimeRef.current = animTime;
12060
- stateRef.current = updateEffectState(stateRef.current, animTime, delta);
12061
- if (shakeRef.current.intensity > 0.2) {
12062
- const i = shakeRef.current.intensity;
12063
- shakeRef.current.x = (Math.random() - 0.5) * i * 2;
12064
- shakeRef.current.y = (Math.random() - 0.5) * i * 2;
12065
- shakeRef.current.intensity *= 0.85;
12066
- setShakeOffset({ x: shakeRef.current.x, y: shakeRef.current.y });
12067
- } else if (shakeRef.current.intensity > 0) {
12068
- shakeRef.current = { x: 0, y: 0, intensity: 0 };
12069
- setShakeOffset({ x: 0, y: 0 });
12070
- }
12071
- ctx.clearRect(0, 0, width, height);
12072
- drawEffectState(ctx, stateRef.current, animTime, getImage);
12073
- if (hasActiveEffects(stateRef.current)) {
12074
- rafRef.current = requestAnimationFrame(loop);
12075
- }
12076
- }
12077
- rafRef.current = requestAnimationFrame(loop);
12078
- return () => cancelAnimationFrame(rafRef.current);
12079
- }, [width, height, getImage]);
12080
- const shakeStyle = shakeOffset.x !== 0 || shakeOffset.y !== 0 ? { transform: `translate(${shakeOffset.x}px, ${shakeOffset.y}px)` } : {};
12081
- return /* @__PURE__ */ jsxRuntime.jsxs(
12082
- Box,
12083
- {
12084
- className: cn("absolute inset-0 pointer-events-none z-10", className),
12085
- style: shakeStyle,
12086
- children: [
12087
- flash && /* @__PURE__ */ jsxRuntime.jsx(
12088
- Box,
12089
- {
12090
- className: "absolute inset-0 z-20 pointer-events-none rounded-container",
12091
- style: { backgroundColor: flash.color, opacity: flash.alpha }
12092
- }
12093
- ),
12094
- /* @__PURE__ */ jsxRuntime.jsx(
12095
- "canvas",
12096
- {
12097
- ref: canvasRef,
12098
- width,
12099
- height,
12100
- className: "absolute inset-0 w-full h-full",
12101
- style: { imageRendering: "pixelated" }
12102
- }
12103
- )
12104
- ]
12105
- }
12106
- );
12107
- }
12108
- function EmojiEffect({
12109
- actionType,
12110
- x,
12111
- y,
12112
- duration = 800,
12113
- intensity = 1,
12114
- onComplete,
12115
- className,
12116
- effectSpriteUrl,
12117
- assetBaseUrl
12118
- }) {
12119
- const [visible, setVisible] = React97.useState(true);
12120
- const [phase, setPhase] = React97.useState("enter");
12121
- React97.useEffect(() => {
12122
- const enterTimer = setTimeout(() => setPhase("active"), 100);
12123
- const exitTimer = setTimeout(() => setPhase("exit"), duration * 0.7);
12124
- const doneTimer = setTimeout(() => {
12125
- setVisible(false);
12126
- onComplete?.();
12127
- }, duration);
12128
- return () => {
12129
- clearTimeout(enterTimer);
12130
- clearTimeout(exitTimer);
12131
- clearTimeout(doneTimer);
12132
- };
12133
- }, [duration, onComplete]);
12134
- if (!visible) return null;
12135
- const config = ACTION_EMOJI[actionType] ?? ACTION_EMOJI.melee;
12136
- const scaleVal = phase === "enter" ? 0.3 : phase === "active" ? intensity : 0.5;
12137
- const opacity = phase === "exit" ? 0 : 1;
12138
- const resolvedSpriteUrl = effectSpriteUrl ? effectSpriteUrl.startsWith("http") || effectSpriteUrl.startsWith("/") ? effectSpriteUrl : assetBaseUrl ? `${assetBaseUrl.replace(/\/$/, "")}/${effectSpriteUrl}` : effectSpriteUrl : void 0;
12139
- return /* @__PURE__ */ jsxRuntime.jsxs(
12140
- Box,
12141
- {
12142
- className: cn(
12143
- "fixed pointer-events-none z-50 flex items-center justify-center",
12144
- "transition-all ease-out",
12145
- className
12146
- ),
12147
- style: {
12148
- left: x,
12149
- top: y,
12150
- transform: `translate(-50%, -50%) scale(${scaleVal})`,
12151
- opacity,
12152
- transitionDuration: phase === "enter" ? "100ms" : "300ms"
12153
- },
12154
- children: [
12155
- /* @__PURE__ */ jsxRuntime.jsx(
12156
- Box,
12157
- {
12158
- className: "absolute rounded-pill animate-ping",
12159
- style: {
12160
- width: 48 * intensity,
12161
- height: 48 * intensity,
12162
- backgroundColor: config.color,
12163
- opacity: 0.25
12164
- }
12165
- }
12166
- ),
12167
- resolvedSpriteUrl ? /* @__PURE__ */ jsxRuntime.jsx(
12168
- "img",
12169
- {
12170
- src: resolvedSpriteUrl,
12171
- alt: config.label,
12172
- className: "relative drop-shadow-lg",
12173
- style: {
12174
- width: `${3 * intensity}rem`,
12175
- height: `${3 * intensity}rem`,
12176
- objectFit: "contain",
12177
- imageRendering: "pixelated"
12178
- }
12179
- }
12180
- ) : /* @__PURE__ */ jsxRuntime.jsx(
12181
- "span",
12182
- {
12183
- className: "relative text-3xl drop-shadow-lg",
12184
- style: { fontSize: `${2 * intensity}rem` },
12185
- role: "img",
12186
- "aria-label": config.label,
12187
- children: config.emoji
12188
- }
12189
- )
12190
- ]
12191
- }
12192
- );
12193
- }
12194
- function CanvasEffect({
12195
- effectSpriteUrl,
12196
- assetBaseUrl,
12197
- ...props
12198
- }) {
12199
- const eventBus = useEventBus();
12200
- const mergedProps = { effectSpriteUrl, assetBaseUrl, ...props };
12201
- const { completeEvent, onComplete, ...rest } = mergedProps;
12202
- const handleComplete = React97.useCallback(() => {
12203
- if (completeEvent) eventBus.emit(`UI:${completeEvent}`, {});
12204
- onComplete?.();
12205
- }, [completeEvent, eventBus, onComplete]);
12206
- const enhancedProps = { ...rest, onComplete: handleComplete };
12207
- if (rest.assetManifest) {
12208
- return /* @__PURE__ */ jsxRuntime.jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: rest.assetManifest });
12209
- }
12210
- return /* @__PURE__ */ jsxRuntime.jsx(EmojiEffect, { ...enhancedProps });
12211
- }
12212
- var ACTION_EMOJI;
12213
- var init_CanvasEffect = __esm({
12214
- "components/game/2d/organisms/CanvasEffect.tsx"() {
12215
- "use client";
12216
- init_cn();
12217
- init_useEventBus();
12218
- init_Box();
12219
- init_effects();
12220
- init_canvasEffects();
12221
- init_combatPresets();
12222
- ACTION_EMOJI = {
12223
- melee: { emoji: "\u2694\uFE0F", color: "var(--color-error)", label: "Slash" },
12224
- ranged: { emoji: "\u{1F3F9}", color: "var(--color-warning)", label: "Arrow" },
12225
- magic: { emoji: "\u2728", color: "var(--color-primary)", label: "Spell" },
12226
- heal: { emoji: "\u{1F49A}", color: "var(--color-success)", label: "Heal" },
12227
- buff: { emoji: "\u2B06\uFE0F", color: "var(--color-info)", label: "Buff" },
12228
- debuff: { emoji: "\u2B07\uFE0F", color: "var(--color-warning)", label: "Debuff" },
12229
- shield: { emoji: "\u{1F6E1}\uFE0F", color: "var(--color-info)", label: "Shield" },
12230
- aoe: { emoji: "\u{1F4A5}", color: "var(--color-error)", label: "Explosion" },
12231
- critical: { emoji: "\u{1F525}", color: "var(--color-error)", label: "Critical" },
12232
- defend: { emoji: "\u{1F6E1}\uFE0F", color: "var(--color-info)", label: "Defend" },
12233
- hit: { emoji: "\u{1F4A5}", color: "var(--color-error)", label: "Hit" },
12234
- death: { emoji: "\u{1F480}", color: "var(--color-error)", label: "Death" }
12235
- };
12236
- CanvasEffect.displayName = "CanvasEffect";
12237
- }
12238
- });
12239
- var init_useCanvasEffects = __esm({
12240
- "components/game/shared/hooks/useCanvasEffects.ts"() {
12241
- "use client";
12242
- }
12243
- });
12244
10971
  var init_useGameAudio = __esm({
12245
10972
  "components/game/shared/hooks/useGameAudio.ts"() {
12246
10973
  "use client";
@@ -14860,7 +13587,7 @@ function NegotiatorBoard({
14860
13587
  React97.useEffect(() => {
14861
13588
  if (currentRound > prevRoundRef.current && lastPlayerAction) {
14862
13589
  const opponentPayoffEntry = payoffMatrix.find(
14863
- (p2) => p2.playerAction === lastPlayerAction && p2.opponentAction === lastOpponentAction
13590
+ (p) => p.playerAction === lastPlayerAction && p.opponentAction === lastOpponentAction
14864
13591
  );
14865
13592
  setHistory((prev) => [
14866
13593
  ...prev,
@@ -15146,14 +13873,14 @@ function SimulationCanvas({
15146
13873
  const ctx = canvas.getContext("2d");
15147
13874
  if (!ctx) return;
15148
13875
  const bodies = bodiesRef.current;
15149
- const p2 = presetRef.current;
13876
+ const p = presetRef.current;
15150
13877
  const w = widthRef.current;
15151
13878
  const h = heightRef.current;
15152
13879
  ctx.clearRect(0, 0, w, h);
15153
- ctx.fillStyle = p2.backgroundColor ?? "#1a1a2e";
13880
+ ctx.fillStyle = p.backgroundColor ?? "#1a1a2e";
15154
13881
  ctx.fillRect(0, 0, w, h);
15155
- if (p2.constraints) {
15156
- for (const c of p2.constraints) {
13882
+ if (p.constraints) {
13883
+ for (const c of p.constraints) {
15157
13884
  const a = bodies[c.bodyA];
15158
13885
  const b = bodies[c.bodyB];
15159
13886
  if (a && b) {
@@ -15176,7 +13903,7 @@ function SimulationCanvas({
15176
13903
  ctx.arc(pos.x, pos.y, body.radius, 0, Math.PI * 2);
15177
13904
  ctx.fillStyle = body.color ?? "#e94560";
15178
13905
  ctx.fill();
15179
- if (p2.showVelocity) {
13906
+ if (p.showVelocity) {
15180
13907
  ctx.beginPath();
15181
13908
  ctx.moveTo(pos.x, pos.y);
15182
13909
  ctx.lineTo(pos.x + body.vx * 0.1, pos.y + body.vy * 0.1);
@@ -15435,7 +14162,6 @@ var init_GameShell = __esm({
15435
14162
  var init_molecules = __esm({
15436
14163
  "components/game/2d/molecules/index.ts"() {
15437
14164
  init_shared();
15438
- init_useCanvasEffects();
15439
14165
  init_puzzleObject();
15440
14166
  }
15441
14167
  });
@@ -15476,8 +14202,8 @@ function shapeBounds(shape) {
15476
14202
  case "polygon":
15477
14203
  if (!shape.points || shape.points.length === 0) return null;
15478
14204
  {
15479
- const xs = shape.points.map((p2) => p2.x);
15480
- const ys = shape.points.map((p2) => p2.y);
14205
+ const xs = shape.points.map((p) => p.x);
14206
+ const ys = shape.points.map((p) => p.y);
15481
14207
  const minX = Math.min(...xs);
15482
14208
  const minY = Math.min(...ys);
15483
14209
  return {
@@ -15603,13 +14329,13 @@ function drawShape(ctx, shape, width, height) {
15603
14329
  }
15604
14330
  case "path": {
15605
14331
  if (!shape.path) break;
15606
- const p2 = new Path2D(shape.path);
14332
+ const p = new Path2D(shape.path);
15607
14333
  if (fill) {
15608
14334
  ctx.fillStyle = fill;
15609
- ctx.fill(p2);
14335
+ ctx.fill(p);
15610
14336
  }
15611
14337
  ctx.strokeStyle = stroke;
15612
- ctx.stroke(p2);
14338
+ ctx.stroke(p);
15613
14339
  break;
15614
14340
  }
15615
14341
  case "text": {
@@ -21502,7 +20228,7 @@ function renderStateMachineToDomData(stateMachine, options = {}, config = DEFAUL
21502
20228
  }
21503
20229
  let domOutputs;
21504
20230
  if (outputs.length > 0) {
21505
- const maxX = Math.max(...Object.values(positions).map((p2) => p2.x));
20231
+ const maxX = Math.max(...Object.values(positions).map((p) => p.x));
21506
20232
  const maxOutputLength = Math.max(...outputs.map((o) => o.length));
21507
20233
  const boxWidth = Math.max(200, maxOutputLength * 7 + 30);
21508
20234
  const lineHeight = 22;
@@ -22484,7 +21210,7 @@ var init_BookViewer = __esm({
22484
21210
  }
22485
21211
  });
22486
21212
  function BoxPattern({
22487
- p: p2,
21213
+ p,
22488
21214
  m,
22489
21215
  bg = "transparent",
22490
21216
  border = false,
@@ -22497,7 +21223,7 @@ function BoxPattern({
22497
21223
  return /* @__PURE__ */ jsxRuntime.jsx(
22498
21224
  Box,
22499
21225
  {
22500
- padding: p2,
21226
+ padding: p,
22501
21227
  margin: m,
22502
21228
  bg,
22503
21229
  border,
@@ -24266,10 +22992,10 @@ var init_Chart = __esm({
24266
22992
  const set = [];
24267
22993
  const seen = /* @__PURE__ */ new Set();
24268
22994
  for (const s of series) {
24269
- for (const p2 of s.data) {
24270
- if (!seen.has(p2.label)) {
24271
- seen.add(p2.label);
24272
- set.push(p2.label);
22995
+ for (const p of s.data) {
22996
+ if (!seen.has(p.label)) {
22997
+ seen.add(p.label);
22998
+ set.push(p.label);
24273
22999
  }
24274
23000
  }
24275
23001
  }
@@ -24277,8 +23003,8 @@ var init_Chart = __esm({
24277
23003
  }, [series]);
24278
23004
  const valueAt = React97.useCallback(
24279
23005
  (s, label) => {
24280
- const p2 = s.data.find((d) => d.label === label);
24281
- return p2 ? p2.value : 0;
23006
+ const p = s.data.find((d) => d.label === label);
23007
+ return p ? p.value : 0;
24282
23008
  },
24283
23009
  []
24284
23010
  );
@@ -24295,7 +23021,7 @@ var init_Chart = __esm({
24295
23021
  }
24296
23022
  let m = 1;
24297
23023
  for (const s of series) {
24298
- for (const p2 of s.data) if (p2.value > m) m = p2.value;
23024
+ for (const p of s.data) if (p.value > m) m = p.value;
24299
23025
  }
24300
23026
  return m;
24301
23027
  }, [series, stack, columnTotals]);
@@ -24555,10 +23281,10 @@ var init_Chart = __esm({
24555
23281
  const seen = /* @__PURE__ */ new Set();
24556
23282
  const out = [];
24557
23283
  for (const s of series) {
24558
- for (const p2 of s.data) {
24559
- if (!seen.has(p2.label)) {
24560
- seen.add(p2.label);
24561
- out.push(p2.label);
23284
+ for (const p of s.data) {
23285
+ if (!seen.has(p.label)) {
23286
+ seen.add(p.label);
23287
+ out.push(p.label);
24562
23288
  }
24563
23289
  }
24564
23290
  }
@@ -24567,7 +23293,7 @@ var init_Chart = __esm({
24567
23293
  const maxValue = React97.useMemo(() => {
24568
23294
  let m = 1;
24569
23295
  for (const s of series) {
24570
- for (const p2 of s.data) if (p2.value > m) m = p2.value;
23296
+ for (const p of s.data) if (p.value > m) m = p.value;
24571
23297
  }
24572
23298
  return m;
24573
23299
  }, [series]);
@@ -24614,7 +23340,7 @@ var init_Chart = __esm({
24614
23340
  label
24615
23341
  };
24616
23342
  });
24617
- const linePath = points.map((p2, i) => `${i === 0 ? "M" : "L"} ${p2.x} ${p2.y}`).join(" ");
23343
+ const linePath = points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
24618
23344
  const areaPath = `${linePath} L ${points[points.length - 1]?.x ?? 0} ${padding.top + chartHeight} L ${padding.left} ${padding.top + chartHeight} Z`;
24619
23345
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
24620
23346
  fill && /* @__PURE__ */ jsxRuntime.jsx(
@@ -24637,19 +23363,19 @@ var init_Chart = __esm({
24637
23363
  strokeDasharray: s.dashed ? "6 4" : void 0
24638
23364
  }
24639
23365
  ),
24640
- points.map((p2, idx) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
23366
+ points.map((p, idx) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
24641
23367
  /* @__PURE__ */ jsxRuntime.jsx(
24642
23368
  "circle",
24643
23369
  {
24644
- cx: p2.x,
24645
- cy: p2.y,
23370
+ cx: p.x,
23371
+ cy: p.y,
24646
23372
  r: "4",
24647
23373
  fill: "var(--color-card)",
24648
23374
  stroke: color,
24649
23375
  strokeWidth: "2",
24650
23376
  className: "cursor-pointer",
24651
23377
  onClick: () => onPointClick?.(
24652
- { label: p2.label, value: p2.value, color },
23378
+ { label: p.label, value: p.value, color },
24653
23379
  s.name
24654
23380
  )
24655
23381
  }
@@ -24657,13 +23383,13 @@ var init_Chart = __esm({
24657
23383
  showValues && series.length === 1 && /* @__PURE__ */ jsxRuntime.jsx(
24658
23384
  "text",
24659
23385
  {
24660
- x: p2.x,
24661
- y: p2.y - 10,
23386
+ x: p.x,
23387
+ y: p.y - 10,
24662
23388
  textAnchor: "middle",
24663
23389
  fill: "var(--color-foreground)",
24664
23390
  fontSize: "10",
24665
23391
  fontWeight: "500",
24666
- children: p2.value
23392
+ children: p.value
24667
23393
  }
24668
23394
  )
24669
23395
  ] }, idx))
@@ -24698,11 +23424,11 @@ var init_Chart = __esm({
24698
23424
  let mxX = data[0].x;
24699
23425
  let mnY = data[0].y;
24700
23426
  let mxY = data[0].y;
24701
- for (const p2 of data) {
24702
- if (p2.x < mnX) mnX = p2.x;
24703
- if (p2.x > mxX) mxX = p2.x;
24704
- if (p2.y < mnY) mnY = p2.y;
24705
- if (p2.y > mxY) mxY = p2.y;
23427
+ for (const p of data) {
23428
+ if (p.x < mnX) mnX = p.x;
23429
+ if (p.x > mxX) mxX = p.x;
23430
+ if (p.y < mnY) mnY = p.y;
23431
+ if (p.y > mxY) mxY = p.y;
24706
23432
  }
24707
23433
  return { minX: mnX, maxX: mxX, minY: mnY, maxY: mxY };
24708
23434
  }, [data]);
@@ -24732,11 +23458,11 @@ var init_Chart = __esm({
24732
23458
  frac
24733
23459
  );
24734
23460
  }),
24735
- data.map((p2, idx) => {
24736
- const cx = padding.left + (p2.x - minX) / rangeX * chartWidth;
24737
- const cy = padding.top + chartHeight - (p2.y - minY) / rangeY * chartHeight;
24738
- const r = p2.size ?? 5;
24739
- const color = p2.color ?? CHART_COLORS[idx % CHART_COLORS.length];
23461
+ data.map((p, idx) => {
23462
+ const cx = padding.left + (p.x - minX) / rangeX * chartWidth;
23463
+ const cy = padding.top + chartHeight - (p.y - minY) / rangeY * chartHeight;
23464
+ const r = p.size ?? 5;
23465
+ const color = p.color ?? CHART_COLORS[idx % CHART_COLORS.length];
24740
23466
  return /* @__PURE__ */ jsxRuntime.jsx(
24741
23467
  "circle",
24742
23468
  {
@@ -24748,13 +23474,13 @@ var init_Chart = __esm({
24748
23474
  className: "cursor-pointer hover:opacity-100",
24749
23475
  onClick: () => onPointClick?.(
24750
23476
  {
24751
- label: p2.label ?? `(${p2.x}, ${p2.y})`,
24752
- value: p2.y,
23477
+ label: p.label ?? `(${p.x}, ${p.y})`,
23478
+ value: p.y,
24753
23479
  color
24754
23480
  },
24755
23481
  "default"
24756
23482
  ),
24757
- children: /* @__PURE__ */ jsxRuntime.jsx("title", { children: p2.label ?? `(${p2.x}, ${p2.y})` })
23483
+ children: /* @__PURE__ */ jsxRuntime.jsx("title", { children: p.label ?? `(${p.x}, ${p.y})` })
24758
23484
  },
24759
23485
  idx
24760
23486
  );
@@ -30912,7 +29638,7 @@ var init_LineChart = __esm({
30912
29638
  }, [sortedData, width, height]);
30913
29639
  const linePath = React97.useMemo(() => {
30914
29640
  if (points.length === 0) return "";
30915
- return points.map((p2, i) => `${i === 0 ? "M" : "L"} ${p2.x} ${p2.y}`).join(" ");
29641
+ return points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
30916
29642
  }, [points]);
30917
29643
  const areaPath = React97.useMemo(() => {
30918
29644
  if (points.length === 0 || !showArea) return "";
@@ -31112,18 +29838,18 @@ var init_MathCanvas = __esm({
31112
29838
  });
31113
29839
  }
31114
29840
  }
31115
- for (const p2 of points) {
31116
- if (p2.x < xMin || p2.x > xMax || p2.y < yMin || p2.y > yMax) continue;
29841
+ for (const p of points) {
29842
+ if (p.x < xMin || p.x > xMax || p.y < yMin || p.y > yMax) continue;
31117
29843
  out.push({
31118
29844
  type: "circle",
31119
- x: mapX(p2.x),
31120
- y: mapY(p2.y),
31121
- radius: p2.radius ?? 4,
31122
- color: p2.color ?? "#dc2626",
31123
- fill: p2.color ?? "#dc2626"
29845
+ x: mapX(p.x),
29846
+ y: mapY(p.y),
29847
+ radius: p.radius ?? 4,
29848
+ color: p.color ?? "#dc2626",
29849
+ fill: p.color ?? "#dc2626"
31124
29850
  });
31125
- if (p2.label) {
31126
- out.push({ type: "text", x: mapX(p2.x) + 8, y: mapY(p2.y) - 8, text: p2.label, color: "#111827", fontSize: 12 });
29851
+ if (p.label) {
29852
+ out.push({ type: "text", x: mapX(p.x) + 8, y: mapY(p.y) - 8, text: p.label, color: "#111827", fontSize: 12 });
31127
29853
  }
31128
29854
  }
31129
29855
  for (const v of vectors) {
@@ -31642,13 +30368,13 @@ var init_MapView = __esm({
31642
30368
  shadowSize: [41, 41]
31643
30369
  });
31644
30370
  L.Marker.prototype.options.icon = defaultIcon;
31645
- const { useEffect: useEffect69, useRef: useRef67, useCallback: useCallback106, useState: useState100 } = React97__namespace.default;
30371
+ const { useEffect: useEffect68, useRef: useRef65, useCallback: useCallback104, useState: useState98 } = React97__namespace.default;
31646
30372
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
31647
30373
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
31648
30374
  function MapUpdater({ centerLat, centerLng, zoom }) {
31649
30375
  const map = useMap();
31650
- const prevRef = useRef67({ centerLat, centerLng, zoom });
31651
- useEffect69(() => {
30376
+ const prevRef = useRef65({ centerLat, centerLng, zoom });
30377
+ useEffect68(() => {
31652
30378
  const prev = prevRef.current;
31653
30379
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
31654
30380
  map.setView([centerLat, centerLng], zoom);
@@ -31659,7 +30385,7 @@ var init_MapView = __esm({
31659
30385
  }
31660
30386
  function MapClickHandler({ onMapClick }) {
31661
30387
  const map = useMap();
31662
- useEffect69(() => {
30388
+ useEffect68(() => {
31663
30389
  if (!onMapClick) return;
31664
30390
  const handler = (e) => {
31665
30391
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -31687,8 +30413,8 @@ var init_MapView = __esm({
31687
30413
  showAttribution = true
31688
30414
  }) {
31689
30415
  const eventBus = useEventBus2();
31690
- const [clickedPosition, setClickedPosition] = useState100(null);
31691
- const handleMapClick = useCallback106((lat, lng) => {
30416
+ const [clickedPosition, setClickedPosition] = useState98(null);
30417
+ const handleMapClick = useCallback104((lat, lng) => {
31692
30418
  if (showClickedPin) {
31693
30419
  setClickedPosition({ lat, lng });
31694
30420
  }
@@ -31697,7 +30423,7 @@ var init_MapView = __esm({
31697
30423
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
31698
30424
  }
31699
30425
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
31700
- const handleMarkerClick = useCallback106((marker) => {
30426
+ const handleMarkerClick = useCallback104((marker) => {
31701
30427
  onMarkerClick?.(marker);
31702
30428
  if (markerClickEvent) {
31703
30429
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -32770,7 +31496,7 @@ function TableView({
32770
31496
  children: [
32771
31497
  header,
32772
31498
  dnd.wrapContainer(body),
32773
- hasMore && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setVisibleCount((p2) => p2 + (pageSize || 5)), children: [
31499
+ hasMore && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setVisibleCount((p) => p + (pageSize || 5)), children: [
32774
31500
  /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
32775
31501
  t("common.showMore"),
32776
31502
  " (",
@@ -35492,7 +34218,7 @@ var init_QrScanner = __esm({
35492
34218
  setCurrentFacing((f3) => f3 === "environment" ? "user" : "environment");
35493
34219
  }, []);
35494
34220
  const togglePause = React97.useCallback(() => {
35495
- setIsPaused((p2) => !p2);
34221
+ setIsPaused((p) => !p);
35496
34222
  }, []);
35497
34223
  const handleMockScan = React97.useCallback(() => {
35498
34224
  const result = {
@@ -38414,10 +37140,10 @@ var init_ModuleCard = __esm({
38414
37140
  ] })
38415
37141
  ] }, trait.name);
38416
37142
  }),
38417
- pages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1.5 flex items-center gap-2 flex-wrap", children: pages.map((p2) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
37143
+ pages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1.5 flex items-center gap-2 flex-wrap", children: pages.map((p) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
38418
37144
  /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 10, height: 10, viewBox: "0 0 12 12", children: /* @__PURE__ */ jsxRuntime.jsx(AvlPage, { x: 6, y: 6, size: 5 }) }),
38419
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-mono text-[var(--color-muted-foreground)]", children: p2.route })
38420
- ] }, p2.name)) })
37145
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-mono text-[var(--color-muted-foreground)]", children: p.route })
37146
+ ] }, p.name)) })
38421
37147
  ]
38422
37148
  }
38423
37149
  );
@@ -39953,12 +38679,12 @@ var init_DocumentViewer = __esm({
39953
38679
  const handleZoomIn = React97.useCallback(() => setZoom((z) => Math.min(z + 25, 200)), []);
39954
38680
  const handleZoomOut = React97.useCallback(() => setZoom((z) => Math.max(z - 25, 50)), []);
39955
38681
  const handlePagePrev = React97.useCallback(() => {
39956
- setCurrentPage((p2) => Math.max(p2 - 1, 1));
38682
+ setCurrentPage((p) => Math.max(p - 1, 1));
39957
38683
  eventBus.emit("UI:DOCUMENT_PAGE_CHANGE", { page: currentPage - 1 });
39958
38684
  }, [eventBus, currentPage]);
39959
38685
  const handlePageNext = React97.useCallback(() => {
39960
38686
  if (totalPages) {
39961
- setCurrentPage((p2) => Math.min(p2 + 1, totalPages));
38687
+ setCurrentPage((p) => Math.min(p + 1, totalPages));
39962
38688
  eventBus.emit("UI:DOCUMENT_PAGE_CHANGE", { page: currentPage + 1 });
39963
38689
  }
39964
38690
  }, [totalPages, eventBus, currentPage]);
@@ -44041,7 +42767,7 @@ function WalkMinimap() {
44041
42767
  const graphH = 120;
44042
42768
  const nodeR = 10;
44043
42769
  const positions = activeTrait ? layoutGraph(activeTrait.states, activeTrait.transitions, activeTrait.initialState, graphW, graphH) : [];
44044
- const posMap = new Map(positions.map((p2) => [p2.state, p2]));
42770
+ const posMap = new Map(positions.map((p) => [p.state, p]));
44045
42771
  const visitedStates = new Set(
44046
42772
  coveredEdges.filter((e) => e.trait === walkStep.traitName).flatMap((e) => [e.from, e.to])
44047
42773
  );
@@ -47311,7 +46037,6 @@ var init_component_registry_generated = __esm({
47311
46037
  init_CTABanner();
47312
46038
  init_CalendarGrid();
47313
46039
  init_Canvas2D();
47314
- init_CanvasEffect();
47315
46040
  init_Card();
47316
46041
  init_CardGrid();
47317
46042
  init_Carousel();
@@ -47610,7 +46335,6 @@ var init_component_registry_generated = __esm({
47610
46335
  "CTABanner": CTABanner,
47611
46336
  "CalendarGrid": CalendarGrid,
47612
46337
  "Canvas2D": Canvas2D,
47613
- "CanvasEffect": CanvasEffect,
47614
46338
  "Card": Card,
47615
46339
  "CardGrid": CardGrid,
47616
46340
  "Carousel": Carousel,
@@ -49529,7 +48253,7 @@ function UserProvider({
49529
48253
  const hasAllPermissions = React97.useCallback(
49530
48254
  (permissions) => {
49531
48255
  if (!user || !user.permissions) return false;
49532
- return permissions.every((p2) => user.permissions?.includes(p2));
48256
+ return permissions.every((p) => user.permissions?.includes(p));
49533
48257
  },
49534
48258
  [user]
49535
48259
  );
@@ -49635,8 +48359,8 @@ function useEntitySchemaOptional6() {
49635
48359
  }
49636
48360
  var log11 = logger.createLogger("almadar:ui:navigation");
49637
48361
  function matchPath2(pattern, path) {
49638
- const normalizeSegment = (p2) => {
49639
- let normalized = p2.trim();
48362
+ const normalizeSegment = (p) => {
48363
+ let normalized = p.trim();
49640
48364
  if (!normalized.startsWith("/")) normalized = "/" + normalized;
49641
48365
  if (normalized.length > 1 && normalized.endsWith("/")) {
49642
48366
  normalized = normalized.slice(0, -1);