@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.
package/dist/avl/index.js CHANGED
@@ -4304,10 +4304,10 @@ var init_ModuleCard = __esm({
4304
4304
  ] })
4305
4305
  ] }, trait.name);
4306
4306
  }),
4307
- pages.length > 0 && /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 flex items-center gap-2 flex-wrap", children: pages.map((p2) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
4307
+ pages.length > 0 && /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 flex items-center gap-2 flex-wrap", children: pages.map((p) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
4308
4308
  /* @__PURE__ */ jsx("svg", { width: 10, height: 10, viewBox: "0 0 12 12", children: /* @__PURE__ */ jsx(AvlPage, { x: 6, y: 6, size: 5 }) }),
4309
- /* @__PURE__ */ jsx("span", { className: "text-xs font-mono text-[var(--color-muted-foreground)]", children: p2.route })
4310
- ] }, p2.name)) })
4309
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-mono text-[var(--color-muted-foreground)]", children: p.route })
4310
+ ] }, p.name)) })
4311
4311
  ]
4312
4312
  }
4313
4313
  );
@@ -4486,12 +4486,12 @@ function kebabToPascal(name) {
4486
4486
  }).join("");
4487
4487
  }
4488
4488
  function loadLib(key, importer) {
4489
- let p2 = libPromises.get(key);
4490
- if (!p2) {
4491
- p2 = importer();
4492
- libPromises.set(key, p2);
4489
+ let p = libPromises.get(key);
4490
+ if (!p) {
4491
+ p = importer();
4492
+ libPromises.set(key, p);
4493
4493
  }
4494
- return p2;
4494
+ return p;
4495
4495
  }
4496
4496
  function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
4497
4497
  const Lazy = React104__default.lazy(async () => {
@@ -9577,28 +9577,28 @@ var init_ConfettiEffect = __esm({
9577
9577
  ),
9578
9578
  "aria-hidden": "true",
9579
9579
  children: [
9580
- particles.map((p2) => {
9581
- const rad = p2.angle * Math.PI / 180;
9582
- const tx = Math.cos(rad) * p2.distance;
9583
- const ty = Math.sin(rad) * p2.distance - 20;
9580
+ particles.map((p) => {
9581
+ const rad = p.angle * Math.PI / 180;
9582
+ const tx = Math.cos(rad) * p.distance;
9583
+ const ty = Math.sin(rad) * p.distance - 20;
9584
9584
  return /* @__PURE__ */ jsx(
9585
9585
  Box,
9586
9586
  {
9587
9587
  className: "absolute rounded-sm",
9588
9588
  style: {
9589
- left: `${p2.left}%`,
9589
+ left: `${p.left}%`,
9590
9590
  top: "50%",
9591
- width: p2.size,
9592
- height: p2.size,
9593
- backgroundColor: p2.color,
9594
- animation: `confetti-burst ${duration - p2.delay}ms ease-out ${p2.delay}ms forwards`,
9591
+ width: p.size,
9592
+ height: p.size,
9593
+ backgroundColor: p.color,
9594
+ animation: `confetti-burst ${duration - p.delay}ms ease-out ${p.delay}ms forwards`,
9595
9595
  opacity: 0,
9596
9596
  "--confetti-tx": `${tx}px`,
9597
9597
  "--confetti-ty": `${ty}px`,
9598
- "--confetti-rotate": `${p2.rotation}deg`
9598
+ "--confetti-rotate": `${p.rotation}deg`
9599
9599
  }
9600
9600
  },
9601
- p2.id
9601
+ p.id
9602
9602
  );
9603
9603
  }),
9604
9604
  /* @__PURE__ */ jsx("style", { children: `
@@ -10509,8 +10509,8 @@ var init_AnimatedGraphic = __esm({
10509
10509
  const el = containerRef.current;
10510
10510
  if (!el || !strokeColor) return;
10511
10511
  const paths = el.querySelectorAll("path, line, polyline, polygon, circle, ellipse, rect");
10512
- paths.forEach((p2) => {
10513
- p2.style.stroke = strokeColor;
10512
+ paths.forEach((p) => {
10513
+ p.style.stroke = strokeColor;
10514
10514
  });
10515
10515
  }, [resolvedSvg, strokeColor]);
10516
10516
  useEffect(() => {
@@ -10518,23 +10518,23 @@ var init_AnimatedGraphic = __esm({
10518
10518
  if (!el || !resolvedSvg) return;
10519
10519
  if (animation === "draw" || animation === "fill") {
10520
10520
  const paths = el.querySelectorAll("path, line, polyline, polygon, circle, ellipse, rect");
10521
- paths.forEach((p2) => {
10522
- if ("getTotalLength" in p2 && typeof p2.getTotalLength === "function") {
10523
- const len = p2.getTotalLength();
10524
- p2.style.strokeDasharray = `${len}`;
10525
- p2.style.strokeDashoffset = `${len}`;
10521
+ paths.forEach((p) => {
10522
+ if ("getTotalLength" in p && typeof p.getTotalLength === "function") {
10523
+ const len = p.getTotalLength();
10524
+ p.style.strokeDasharray = `${len}`;
10525
+ p.style.strokeDashoffset = `${len}`;
10526
10526
  }
10527
10527
  if (animation === "fill") {
10528
- p2.style.fillOpacity = "0";
10528
+ p.style.fillOpacity = "0";
10529
10529
  }
10530
10530
  });
10531
10531
  }
10532
10532
  if (animation === "morph") {
10533
10533
  const paths = el.querySelectorAll("path, circle, ellipse, rect, polygon");
10534
- paths.forEach((p2) => {
10535
- p2.style.transform = "scale(0)";
10536
- p2.style.transformOrigin = "center";
10537
- p2.style.opacity = "0";
10534
+ paths.forEach((p) => {
10535
+ p.style.transform = "scale(0)";
10536
+ p.style.transformOrigin = "center";
10537
+ p.style.opacity = "0";
10538
10538
  });
10539
10539
  }
10540
10540
  }, [resolvedSvg, animation]);
@@ -10639,14 +10639,8 @@ var init_TraitFrame = __esm({
10639
10639
  });
10640
10640
 
10641
10641
  // components/game/shared/effects.ts
10642
- var EMPTY_EFFECT_STATE;
10643
10642
  var init_effects = __esm({
10644
10643
  "components/game/shared/effects.ts"() {
10645
- EMPTY_EFFECT_STATE = {
10646
- particles: [],
10647
- sequences: [],
10648
- overlays: []
10649
- };
10650
10644
  }
10651
10645
  });
10652
10646
 
@@ -11054,1021 +11048,12 @@ var init_spriteAnimation = __esm({
11054
11048
  }
11055
11049
  });
11056
11050
 
11057
- // components/game/shared/combatPresets.ts
11058
- function p(manifest, key) {
11059
- const particles = manifest.particles;
11060
- if (!particles) return [];
11061
- const val = particles[key];
11062
- if (Array.isArray(val)) return val.map((v) => `${manifest.baseUrl}/${v}`);
11063
- if (typeof val === "string") return [`${manifest.baseUrl}/${val}`];
11064
- return [];
11065
- }
11066
- function anim(manifest, key) {
11067
- const animations = manifest.animations;
11068
- if (!animations) return [];
11069
- const val = animations[key];
11070
- if (Array.isArray(val)) return val.map((v) => `${manifest.baseUrl}/${v}`);
11071
- return [];
11072
- }
11073
- function createCombatPresets(manifest) {
11074
- return {
11075
- // =====================================================================
11076
- // MELEE — slash (red) + dirt + scratch + flash sequence
11077
- // =====================================================================
11078
- melee: (originX, originY) => {
11079
- const particles = [
11080
- {
11081
- spriteUrls: p(manifest, "slash"),
11082
- count: 6,
11083
- originX,
11084
- originY,
11085
- spread: 8,
11086
- velocityMin: 40,
11087
- velocityMax: 120,
11088
- angleMin: -PI2 * 0.8,
11089
- angleMax: -PI2 * 0.2,
11090
- gravity: 0,
11091
- tint: { r: 255, g: 60, b: 40 },
11092
- scaleMin: 0.3,
11093
- scaleMax: 0.6,
11094
- lifetimeMin: 300,
11095
- lifetimeMax: 500,
11096
- fadeRate: -2.5
11097
- },
11098
- {
11099
- spriteUrls: p(manifest, "dirt"),
11100
- count: 4,
11101
- originX,
11102
- originY: originY + 10,
11103
- spread: 12,
11104
- velocityMin: 20,
11105
- velocityMax: 60,
11106
- angleMin: -PI2 * 0.9,
11107
- angleMax: -PI2 * 0.1,
11108
- gravity: 120,
11109
- tint: { r: 180, g: 140, b: 90 },
11110
- scaleMin: 0.15,
11111
- scaleMax: 0.3,
11112
- lifetimeMin: 400,
11113
- lifetimeMax: 700,
11114
- fadeRate: -1.8
11115
- },
11116
- {
11117
- spriteUrls: p(manifest, "scratch"),
11118
- count: 2,
11119
- originX,
11120
- originY,
11121
- spread: 5,
11122
- velocityMin: 10,
11123
- velocityMax: 30,
11124
- angleMin: -PI2 * 0.7,
11125
- angleMax: -PI2 * 0.3,
11126
- gravity: 0,
11127
- tint: { r: 255, g: 200, b: 150 },
11128
- scaleMin: 0.25,
11129
- scaleMax: 0.4,
11130
- lifetimeMin: 200,
11131
- lifetimeMax: 400,
11132
- fadeRate: -3
11133
- }
11134
- ];
11135
- const sequences = [];
11136
- const flashFrames = anim(manifest, "flash");
11137
- if (flashFrames.length > 0) {
11138
- sequences.push({
11139
- frameUrls: flashFrames,
11140
- originX,
11141
- originY,
11142
- frameDuration: 35,
11143
- scale: 0.4
11144
- });
11145
- }
11146
- return {
11147
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11148
- sequences,
11149
- overlays: [],
11150
- screenShake: 4,
11151
- screenFlash: null
11152
- };
11153
- },
11154
- // =====================================================================
11155
- // RANGED — muzzle + trace + smoke + explosion sequence
11156
- // =====================================================================
11157
- ranged: (originX, originY) => {
11158
- const particles = [
11159
- {
11160
- spriteUrls: p(manifest, "muzzle"),
11161
- count: 3,
11162
- originX,
11163
- originY,
11164
- spread: 4,
11165
- velocityMin: 60,
11166
- velocityMax: 150,
11167
- angleMin: -PI2 * 0.6,
11168
- angleMax: -PI2 * 0.4,
11169
- gravity: 0,
11170
- tint: { r: 255, g: 220, b: 100 },
11171
- scaleMin: 0.2,
11172
- scaleMax: 0.4,
11173
- lifetimeMin: 200,
11174
- lifetimeMax: 400,
11175
- fadeRate: -3
11176
- },
11177
- {
11178
- spriteUrls: p(manifest, "trace"),
11179
- count: 5,
11180
- originX,
11181
- originY,
11182
- spread: 3,
11183
- velocityMin: 100,
11184
- velocityMax: 200,
11185
- angleMin: -PI2 * 0.55,
11186
- angleMax: -PI2 * 0.45,
11187
- gravity: 0,
11188
- tint: { r: 255, g: 200, b: 80 },
11189
- scaleMin: 0.15,
11190
- scaleMax: 0.3,
11191
- lifetimeMin: 150,
11192
- lifetimeMax: 300,
11193
- fadeRate: -4
11194
- },
11195
- {
11196
- spriteUrls: p(manifest, "smoke").slice(0, 3),
11197
- count: 3,
11198
- originX,
11199
- originY: originY + 5,
11200
- spread: 6,
11201
- velocityMin: 10,
11202
- velocityMax: 30,
11203
- angleMin: -PI2 * 0.8,
11204
- angleMax: -PI2 * 0.2,
11205
- gravity: -20,
11206
- tint: { r: 200, g: 200, b: 200 },
11207
- scaleMin: 0.2,
11208
- scaleMax: 0.35,
11209
- lifetimeMin: 500,
11210
- lifetimeMax: 800,
11211
- fadeRate: -1.5
11212
- }
11213
- ];
11214
- const sequences = [];
11215
- const explosionFrames = anim(manifest, "smokeExplosion");
11216
- if (explosionFrames.length > 0) {
11217
- sequences.push({
11218
- frameUrls: explosionFrames,
11219
- originX,
11220
- originY,
11221
- frameDuration: 50,
11222
- scale: 0.35
11223
- });
11224
- }
11225
- return {
11226
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11227
- sequences,
11228
- overlays: [],
11229
- screenShake: 2,
11230
- screenFlash: null
11231
- };
11232
- },
11233
- // =====================================================================
11234
- // MAGIC — twirl (purple) + spark (purple) + star
11235
- // =====================================================================
11236
- magic: (originX, originY) => {
11237
- const particles = [
11238
- {
11239
- spriteUrls: p(manifest, "twirl"),
11240
- count: 5,
11241
- originX,
11242
- originY,
11243
- spread: 15,
11244
- velocityMin: 20,
11245
- velocityMax: 80,
11246
- angleMin: 0,
11247
- angleMax: PI2 * 2,
11248
- gravity: -30,
11249
- tint: { r: 180, g: 80, b: 255 },
11250
- scaleMin: 0.2,
11251
- scaleMax: 0.5,
11252
- lifetimeMin: 500,
11253
- lifetimeMax: 900,
11254
- fadeRate: -1.2,
11255
- blendMode: "lighter",
11256
- rotationSpeedMin: -4,
11257
- rotationSpeedMax: 4
11258
- },
11259
- {
11260
- spriteUrls: p(manifest, "spark"),
11261
- count: 8,
11262
- originX,
11263
- originY,
11264
- spread: 20,
11265
- velocityMin: 30,
11266
- velocityMax: 100,
11267
- angleMin: 0,
11268
- angleMax: PI2 * 2,
11269
- gravity: -15,
11270
- tint: { r: 200, g: 120, b: 255 },
11271
- scaleMin: 0.1,
11272
- scaleMax: 0.25,
11273
- lifetimeMin: 300,
11274
- lifetimeMax: 600,
11275
- fadeRate: -2,
11276
- blendMode: "lighter"
11277
- },
11278
- {
11279
- spriteUrls: p(manifest, "star"),
11280
- count: 4,
11281
- originX,
11282
- originY,
11283
- spread: 10,
11284
- velocityMin: 15,
11285
- velocityMax: 50,
11286
- angleMin: -PI2,
11287
- angleMax: 0,
11288
- gravity: -40,
11289
- tint: { r: 220, g: 180, b: 255 },
11290
- scaleMin: 0.15,
11291
- scaleMax: 0.3,
11292
- lifetimeMin: 600,
11293
- lifetimeMax: 1e3,
11294
- fadeRate: -1,
11295
- blendMode: "lighter"
11296
- }
11297
- ];
11298
- const overlays = [];
11299
- const circleUrls = p(manifest, "circle");
11300
- if (circleUrls.length > 0) {
11301
- overlays.push({
11302
- spriteUrl: circleUrls[0],
11303
- originX,
11304
- originY,
11305
- alpha: 0.5,
11306
- fadeRate: -0.6,
11307
- pulseAmplitude: 0.2,
11308
- pulseFrequency: 3,
11309
- scale: 0.5,
11310
- blendMode: "lighter",
11311
- lifetime: 1200
11312
- });
11313
- }
11314
- return {
11315
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11316
- sequences: [],
11317
- overlays,
11318
- screenShake: 0,
11319
- screenFlash: null
11320
- };
11321
- },
11322
- // =====================================================================
11323
- // HEAL — circle (green) + star (green) + light (green, pulse)
11324
- // =====================================================================
11325
- heal: (originX, originY) => {
11326
- const particles = [
11327
- {
11328
- spriteUrls: p(manifest, "circle"),
11329
- count: 6,
11330
- originX,
11331
- originY,
11332
- spread: 15,
11333
- velocityMin: 10,
11334
- velocityMax: 40,
11335
- angleMin: -PI2,
11336
- angleMax: -PI2 * 0.3,
11337
- gravity: -50,
11338
- tint: { r: 80, g: 255, b: 120 },
11339
- scaleMin: 0.15,
11340
- scaleMax: 0.35,
11341
- lifetimeMin: 600,
11342
- lifetimeMax: 1e3,
11343
- fadeRate: -0.8,
11344
- blendMode: "lighter"
11345
- },
11346
- {
11347
- spriteUrls: p(manifest, "star"),
11348
- count: 5,
11349
- originX,
11350
- originY,
11351
- spread: 12,
11352
- velocityMin: 15,
11353
- velocityMax: 50,
11354
- angleMin: -PI2 * 0.9,
11355
- angleMax: -PI2 * 0.1,
11356
- gravity: -60,
11357
- tint: { r: 100, g: 255, b: 140 },
11358
- scaleMin: 0.1,
11359
- scaleMax: 0.2,
11360
- lifetimeMin: 500,
11361
- lifetimeMax: 800,
11362
- fadeRate: -1.2,
11363
- blendMode: "lighter"
11364
- }
11365
- ];
11366
- const overlays = [];
11367
- const lightUrls = p(manifest, "light");
11368
- if (lightUrls.length > 0) {
11369
- overlays.push({
11370
- spriteUrl: lightUrls[0],
11371
- originX,
11372
- originY,
11373
- alpha: 0.6,
11374
- fadeRate: -0.4,
11375
- pulseAmplitude: 0.25,
11376
- pulseFrequency: 2.5,
11377
- scale: 0.6,
11378
- blendMode: "lighter",
11379
- lifetime: 1500
11380
- });
11381
- }
11382
- return {
11383
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11384
- sequences: [],
11385
- overlays,
11386
- screenShake: 0,
11387
- screenFlash: null
11388
- };
11389
- },
11390
- // =====================================================================
11391
- // DEFEND / SHIELD — star (blue) + circle (blue, pulse)
11392
- // =====================================================================
11393
- defend: (originX, originY) => {
11394
- const particles = [
11395
- {
11396
- spriteUrls: p(manifest, "star"),
11397
- count: 8,
11398
- originX,
11399
- originY,
11400
- spread: 18,
11401
- velocityMin: 10,
11402
- velocityMax: 35,
11403
- angleMin: 0,
11404
- angleMax: PI2 * 2,
11405
- gravity: 0,
11406
- tint: { r: 80, g: 160, b: 255 },
11407
- scaleMin: 0.12,
11408
- scaleMax: 0.25,
11409
- lifetimeMin: 600,
11410
- lifetimeMax: 1e3,
11411
- fadeRate: -0.8,
11412
- blendMode: "lighter",
11413
- rotationSpeedMin: -1,
11414
- rotationSpeedMax: 1
11415
- }
11416
- ];
11417
- const overlays = [];
11418
- const circleUrls = p(manifest, "circle");
11419
- if (circleUrls.length > 0) {
11420
- overlays.push({
11421
- spriteUrl: circleUrls[0],
11422
- originX,
11423
- originY,
11424
- alpha: 0.6,
11425
- fadeRate: -0.3,
11426
- pulseAmplitude: 0.2,
11427
- pulseFrequency: 2,
11428
- scale: 0.6,
11429
- blendMode: "lighter",
11430
- lifetime: 1500
11431
- });
11432
- }
11433
- return {
11434
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11435
- sequences: [],
11436
- overlays,
11437
- screenShake: 0,
11438
- screenFlash: null
11439
- };
11440
- },
11441
- // shield aliases to defend
11442
- shield: (originX, originY) => {
11443
- const particles = [
11444
- {
11445
- spriteUrls: p(manifest, "star"),
11446
- count: 10,
11447
- originX,
11448
- originY,
11449
- spread: 20,
11450
- velocityMin: 8,
11451
- velocityMax: 30,
11452
- angleMin: 0,
11453
- angleMax: PI2 * 2,
11454
- gravity: 0,
11455
- tint: { r: 60, g: 180, b: 255 },
11456
- scaleMin: 0.1,
11457
- scaleMax: 0.22,
11458
- lifetimeMin: 700,
11459
- lifetimeMax: 1200,
11460
- fadeRate: -0.7,
11461
- blendMode: "lighter",
11462
- rotationSpeedMin: -0.8,
11463
- rotationSpeedMax: 0.8
11464
- }
11465
- ];
11466
- const overlays = [];
11467
- const circleUrls = p(manifest, "circle");
11468
- if (circleUrls.length > 0) {
11469
- overlays.push({
11470
- spriteUrl: circleUrls[0],
11471
- originX,
11472
- originY,
11473
- alpha: 0.7,
11474
- fadeRate: -0.25,
11475
- pulseAmplitude: 0.25,
11476
- pulseFrequency: 1.8,
11477
- scale: 0.7,
11478
- blendMode: "lighter",
11479
- lifetime: 1800
11480
- });
11481
- }
11482
- return {
11483
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11484
- sequences: [],
11485
- overlays,
11486
- screenShake: 0,
11487
- screenFlash: null
11488
- };
11489
- },
11490
- // =====================================================================
11491
- // HIT — spark (orange) + flash (5 frames) + screen shake/flash
11492
- // =====================================================================
11493
- hit: (originX, originY) => {
11494
- const particles = [
11495
- {
11496
- spriteUrls: p(manifest, "spark"),
11497
- count: 10,
11498
- originX,
11499
- originY,
11500
- spread: 8,
11501
- velocityMin: 50,
11502
- velocityMax: 150,
11503
- angleMin: 0,
11504
- angleMax: PI2 * 2,
11505
- gravity: 80,
11506
- tint: { r: 255, g: 180, b: 50 },
11507
- scaleMin: 0.08,
11508
- scaleMax: 0.2,
11509
- lifetimeMin: 200,
11510
- lifetimeMax: 500,
11511
- fadeRate: -2.5
11512
- }
11513
- ];
11514
- const sequences = [];
11515
- const flashFrames = anim(manifest, "flash");
11516
- if (flashFrames.length > 0) {
11517
- sequences.push({
11518
- frameUrls: flashFrames.slice(0, 5),
11519
- originX,
11520
- originY,
11521
- frameDuration: 40,
11522
- scale: 0.3
11523
- });
11524
- }
11525
- return {
11526
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11527
- sequences,
11528
- overlays: [],
11529
- screenShake: 3,
11530
- screenFlash: { r: 255, g: 50, b: 50, duration: 150 }
11531
- };
11532
- },
11533
- // critical aliases to hit with bigger shake
11534
- critical: (originX, originY) => {
11535
- const particles = [
11536
- {
11537
- spriteUrls: p(manifest, "flame"),
11538
- count: 8,
11539
- originX,
11540
- originY,
11541
- spread: 12,
11542
- velocityMin: 60,
11543
- velocityMax: 180,
11544
- angleMin: 0,
11545
- angleMax: PI2 * 2,
11546
- gravity: 60,
11547
- tint: { r: 255, g: 120, b: 30 },
11548
- scaleMin: 0.15,
11549
- scaleMax: 0.4,
11550
- lifetimeMin: 300,
11551
- lifetimeMax: 600,
11552
- fadeRate: -2
11553
- },
11554
- {
11555
- spriteUrls: p(manifest, "spark"),
11556
- count: 12,
11557
- originX,
11558
- originY,
11559
- spread: 10,
11560
- velocityMin: 80,
11561
- velocityMax: 200,
11562
- angleMin: 0,
11563
- angleMax: PI2 * 2,
11564
- gravity: 100,
11565
- tint: { r: 255, g: 200, b: 60 },
11566
- scaleMin: 0.06,
11567
- scaleMax: 0.18,
11568
- lifetimeMin: 200,
11569
- lifetimeMax: 400,
11570
- fadeRate: -3
11571
- }
11572
- ];
11573
- const sequences = [];
11574
- const flashFrames = anim(manifest, "flash");
11575
- if (flashFrames.length > 0) {
11576
- sequences.push({
11577
- frameUrls: flashFrames,
11578
- originX,
11579
- originY,
11580
- frameDuration: 30,
11581
- scale: 0.5
11582
- });
11583
- }
11584
- return {
11585
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11586
- sequences,
11587
- overlays: [],
11588
- screenShake: 6,
11589
- screenFlash: { r: 255, g: 80, b: 0, duration: 200 }
11590
- };
11591
- },
11592
- // =====================================================================
11593
- // DEATH — dirt (gray) + explosion + black smoke + scorch (ground)
11594
- // =====================================================================
11595
- death: (originX, originY) => {
11596
- const particles = [
11597
- {
11598
- spriteUrls: p(manifest, "dirt"),
11599
- count: 8,
11600
- originX,
11601
- originY,
11602
- spread: 10,
11603
- velocityMin: 30,
11604
- velocityMax: 100,
11605
- angleMin: 0,
11606
- angleMax: PI2 * 2,
11607
- gravity: 100,
11608
- tint: { r: 140, g: 140, b: 140 },
11609
- scaleMin: 0.15,
11610
- scaleMax: 0.35,
11611
- lifetimeMin: 500,
11612
- lifetimeMax: 900,
11613
- fadeRate: -1.2
11614
- }
11615
- ];
11616
- const sequences = [];
11617
- const explosionFrames = anim(manifest, "explosion");
11618
- if (explosionFrames.length > 0) {
11619
- sequences.push({
11620
- frameUrls: explosionFrames,
11621
- originX,
11622
- originY,
11623
- frameDuration: 60,
11624
- scale: 0.5
11625
- });
11626
- }
11627
- const blackSmokeFrames = anim(manifest, "blackSmoke");
11628
- if (blackSmokeFrames.length > 0) {
11629
- sequences.push({
11630
- frameUrls: blackSmokeFrames,
11631
- originX,
11632
- originY: originY - 10,
11633
- frameDuration: 50,
11634
- scale: 0.4,
11635
- alpha: 0.7
11636
- });
11637
- }
11638
- const overlays = [];
11639
- const scorchUrls = p(manifest, "scorch");
11640
- if (scorchUrls.length > 0) {
11641
- overlays.push({
11642
- spriteUrl: scorchUrls[0],
11643
- originX,
11644
- originY: originY + 10,
11645
- alpha: 0.6,
11646
- fadeRate: -0.15,
11647
- scale: 0.4,
11648
- lifetime: 4e3
11649
- });
11650
- }
11651
- return {
11652
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11653
- sequences,
11654
- overlays,
11655
- screenShake: 0,
11656
- screenFlash: null
11657
- };
11658
- },
11659
- // =====================================================================
11660
- // BUFF — star (gold) + symbol + flare (gold, pulse)
11661
- // =====================================================================
11662
- buff: (originX, originY) => {
11663
- const particles = [
11664
- {
11665
- spriteUrls: p(manifest, "star"),
11666
- count: 6,
11667
- originX,
11668
- originY,
11669
- spread: 15,
11670
- velocityMin: 15,
11671
- velocityMax: 50,
11672
- angleMin: -PI2,
11673
- angleMax: 0,
11674
- gravity: -30,
11675
- tint: { r: 255, g: 215, b: 50 },
11676
- scaleMin: 0.12,
11677
- scaleMax: 0.25,
11678
- lifetimeMin: 600,
11679
- lifetimeMax: 1e3,
11680
- fadeRate: -0.8,
11681
- blendMode: "lighter"
11682
- },
11683
- {
11684
- spriteUrls: p(manifest, "symbol"),
11685
- count: 2,
11686
- originX,
11687
- originY: originY - 10,
11688
- spread: 8,
11689
- velocityMin: 5,
11690
- velocityMax: 20,
11691
- angleMin: -PI2 * 0.7,
11692
- angleMax: -PI2 * 0.3,
11693
- gravity: -20,
11694
- tint: { r: 255, g: 230, b: 100 },
11695
- scaleMin: 0.2,
11696
- scaleMax: 0.35,
11697
- lifetimeMin: 800,
11698
- lifetimeMax: 1200,
11699
- fadeRate: -0.6,
11700
- blendMode: "lighter"
11701
- }
11702
- ];
11703
- const overlays = [];
11704
- const flareUrls = p(manifest, "flare");
11705
- if (flareUrls.length > 0) {
11706
- overlays.push({
11707
- spriteUrl: flareUrls[0],
11708
- originX,
11709
- originY,
11710
- alpha: 0.5,
11711
- fadeRate: -0.3,
11712
- pulseAmplitude: 0.3,
11713
- pulseFrequency: 2,
11714
- scale: 0.5,
11715
- blendMode: "lighter",
11716
- lifetime: 1500
11717
- });
11718
- }
11719
- return {
11720
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11721
- sequences: [],
11722
- overlays,
11723
- screenShake: 0,
11724
- screenFlash: null
11725
- };
11726
- },
11727
- // =====================================================================
11728
- // DEBUFF — scorch (dark) + smoke (purple tint)
11729
- // =====================================================================
11730
- debuff: (originX, originY) => {
11731
- const particles = [
11732
- {
11733
- spriteUrls: p(manifest, "scorch"),
11734
- count: 4,
11735
- originX,
11736
- originY,
11737
- spread: 12,
11738
- velocityMin: 15,
11739
- velocityMax: 40,
11740
- angleMin: -PI2,
11741
- angleMax: 0,
11742
- gravity: -20,
11743
- tint: { r: 120, g: 40, b: 160 },
11744
- scaleMin: 0.15,
11745
- scaleMax: 0.3,
11746
- lifetimeMin: 500,
11747
- lifetimeMax: 800,
11748
- fadeRate: -1
11749
- },
11750
- {
11751
- spriteUrls: p(manifest, "smoke").slice(0, 3),
11752
- count: 3,
11753
- originX,
11754
- originY,
11755
- spread: 10,
11756
- velocityMin: 8,
11757
- velocityMax: 25,
11758
- angleMin: -PI2 * 0.8,
11759
- angleMax: -PI2 * 0.2,
11760
- gravity: -15,
11761
- tint: { r: 100, g: 50, b: 140 },
11762
- scaleMin: 0.2,
11763
- scaleMax: 0.35,
11764
- lifetimeMin: 600,
11765
- lifetimeMax: 1e3,
11766
- fadeRate: -0.8
11767
- }
11768
- ];
11769
- const overlays = [];
11770
- const circleUrls = p(manifest, "circle");
11771
- if (circleUrls.length > 0) {
11772
- overlays.push({
11773
- spriteUrl: circleUrls[0],
11774
- originX,
11775
- originY,
11776
- alpha: 0.4,
11777
- fadeRate: -0.4,
11778
- pulseAmplitude: 0.15,
11779
- pulseFrequency: 2,
11780
- scale: 0.45,
11781
- lifetime: 1200
11782
- });
11783
- }
11784
- return {
11785
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11786
- sequences: [],
11787
- overlays,
11788
- screenShake: 0,
11789
- screenFlash: null
11790
- };
11791
- },
11792
- // =====================================================================
11793
- // AOE — explosion (large) + flame + spark (radial) + screen shake
11794
- // =====================================================================
11795
- aoe: (originX, originY) => {
11796
- const particles = [
11797
- {
11798
- spriteUrls: p(manifest, "flame"),
11799
- count: 10,
11800
- originX,
11801
- originY,
11802
- spread: 20,
11803
- velocityMin: 40,
11804
- velocityMax: 140,
11805
- angleMin: 0,
11806
- angleMax: PI2 * 2,
11807
- gravity: 40,
11808
- tint: { r: 255, g: 140, b: 30 },
11809
- scaleMin: 0.2,
11810
- scaleMax: 0.5,
11811
- lifetimeMin: 400,
11812
- lifetimeMax: 800,
11813
- fadeRate: -1.5
11814
- },
11815
- {
11816
- spriteUrls: p(manifest, "spark"),
11817
- count: 15,
11818
- originX,
11819
- originY,
11820
- spread: 15,
11821
- velocityMin: 60,
11822
- velocityMax: 200,
11823
- angleMin: 0,
11824
- angleMax: PI2 * 2,
11825
- gravity: 60,
11826
- tint: { r: 255, g: 180, b: 60 },
11827
- scaleMin: 0.06,
11828
- scaleMax: 0.15,
11829
- lifetimeMin: 200,
11830
- lifetimeMax: 500,
11831
- fadeRate: -2.5
11832
- }
11833
- ];
11834
- const sequences = [];
11835
- const explosionFrames = anim(manifest, "explosion");
11836
- if (explosionFrames.length > 0) {
11837
- sequences.push({
11838
- frameUrls: explosionFrames,
11839
- originX,
11840
- originY,
11841
- frameDuration: 50,
11842
- scale: 0.6
11843
- });
11844
- }
11845
- return {
11846
- particles: particles.filter((pc) => pc.spriteUrls.length > 0),
11847
- sequences,
11848
- overlays: [],
11849
- screenShake: 5,
11850
- screenFlash: { r: 255, g: 160, b: 0, duration: 180 }
11851
- };
11852
- }
11853
- };
11854
- }
11855
- var PI2;
11856
- var init_combatPresets = __esm({
11857
- "components/game/shared/combatPresets.ts"() {
11858
- PI2 = Math.PI;
11859
- }
11860
- });
11861
-
11862
- // components/game/shared/canvasEffects.ts
11863
- function getOffscreenCtx(w, h) {
11864
- if (!_offscreen) {
11865
- if (typeof OffscreenCanvas !== "undefined") {
11866
- _offscreen = new OffscreenCanvas(w, h);
11867
- } else {
11868
- _offscreen = document.createElement("canvas");
11869
- }
11870
- }
11871
- if (_offscreen.width < w) _offscreen.width = w;
11872
- if (_offscreen.height < h) _offscreen.height = h;
11873
- if (!_offCtx) {
11874
- _offCtx = _offscreen.getContext("2d");
11875
- }
11876
- return _offCtx;
11877
- }
11878
- function drawTintedImage(ctx, img, x, y, w, h, tint, alpha, blendMode = "source-over") {
11879
- if (w <= 0 || h <= 0) return;
11880
- const oc = getOffscreenCtx(w, h);
11881
- oc.clearRect(0, 0, w, h);
11882
- oc.globalCompositeOperation = "source-over";
11883
- oc.drawImage(img, 0, 0, w, h);
11884
- oc.globalCompositeOperation = "source-atop";
11885
- oc.fillStyle = `rgb(${tint.r}, ${tint.g}, ${tint.b})`;
11886
- oc.fillRect(0, 0, w, h);
11887
- const prevAlpha = ctx.globalAlpha;
11888
- const prevBlend = ctx.globalCompositeOperation;
11889
- ctx.globalAlpha = alpha;
11890
- ctx.globalCompositeOperation = blendMode;
11891
- ctx.drawImage(_offscreen, 0, 0, w, h, x, y, w, h);
11892
- ctx.globalAlpha = prevAlpha;
11893
- ctx.globalCompositeOperation = prevBlend;
11894
- }
11895
- function randRange(min, max) {
11896
- return min + Math.random() * (max - min);
11897
- }
11898
- function spawnParticles(config, animTime) {
11899
- const particles = [];
11900
- for (let i = 0; i < config.count; i++) {
11901
- const angle = randRange(config.angleMin, config.angleMax);
11902
- const speed = randRange(config.velocityMin, config.velocityMax);
11903
- const spriteUrl = config.spriteUrls[Math.floor(Math.random() * config.spriteUrls.length)];
11904
- particles.push({
11905
- spriteUrl,
11906
- x: config.originX + randRange(-config.spread, config.spread),
11907
- y: config.originY + randRange(-config.spread, config.spread),
11908
- vx: Math.cos(angle) * speed,
11909
- vy: Math.sin(angle) * speed,
11910
- gravity: config.gravity,
11911
- rotation: Math.random() * Math.PI * 2,
11912
- rotationSpeed: randRange(config.rotationSpeedMin ?? -2, config.rotationSpeedMax ?? 2),
11913
- scale: randRange(config.scaleMin, config.scaleMax),
11914
- scaleSpeed: config.scaleSpeed ?? 0,
11915
- alpha: config.alpha ?? 1,
11916
- fadeRate: config.fadeRate ?? -1.5,
11917
- tint: { ...config.tint },
11918
- blendMode: config.blendMode ?? "source-over",
11919
- spawnTime: animTime,
11920
- lifetime: randRange(config.lifetimeMin, config.lifetimeMax)
11921
- });
11922
- }
11923
- return particles;
11924
- }
11925
- function spawnSequence(config, animTime) {
11926
- return {
11927
- frameUrls: config.frameUrls,
11928
- x: config.originX,
11929
- y: config.originY,
11930
- frameDuration: config.frameDuration,
11931
- startTime: animTime,
11932
- loop: config.loop ?? false,
11933
- scale: config.scale ?? 1,
11934
- tint: config.tint ?? null,
11935
- alpha: config.alpha ?? 1,
11936
- blendMode: config.blendMode ?? "source-over"
11937
- };
11938
- }
11939
- function spawnOverlay(config, animTime) {
11940
- return {
11941
- spriteUrl: config.spriteUrl,
11942
- x: config.originX,
11943
- y: config.originY,
11944
- alpha: config.alpha ?? 0.8,
11945
- fadeRate: config.fadeRate ?? -0.5,
11946
- pulseAmplitude: config.pulseAmplitude ?? 0,
11947
- pulseFrequency: config.pulseFrequency ?? 2,
11948
- scale: config.scale ?? 1,
11949
- blendMode: config.blendMode ?? "source-over",
11950
- spawnTime: animTime,
11951
- lifetime: config.lifetime ?? 2e3
11952
- };
11953
- }
11954
- function updateEffectState(state, animTime, deltaMs) {
11955
- const dt = deltaMs / 1e3;
11956
- const particles = state.particles.map((p2) => ({
11957
- ...p2,
11958
- x: p2.x + p2.vx * dt,
11959
- y: p2.y + p2.vy * dt,
11960
- vy: p2.vy + p2.gravity * dt,
11961
- rotation: p2.rotation + p2.rotationSpeed * dt,
11962
- scale: Math.max(0, p2.scale + p2.scaleSpeed * dt),
11963
- alpha: Math.max(0, p2.alpha + p2.fadeRate * dt)
11964
- })).filter((p2) => p2.alpha > 0.01 && animTime - p2.spawnTime < p2.lifetime);
11965
- const sequences = state.sequences.filter((s) => {
11966
- const elapsed = animTime - s.startTime;
11967
- const totalDuration = s.frameUrls.length * s.frameDuration;
11968
- return s.loop || elapsed < totalDuration;
11969
- });
11970
- const overlays = state.overlays.map((o) => ({
11971
- ...o,
11972
- alpha: Math.max(0, o.alpha + o.fadeRate * dt)
11973
- })).filter((o) => o.alpha > 0.01 && animTime - o.spawnTime < o.lifetime);
11974
- return { particles, sequences, overlays };
11975
- }
11976
- function drawEffectState(ctx, state, animTime, getImage) {
11977
- for (const o of state.overlays) {
11978
- const img = getImage(o.spriteUrl);
11979
- if (!img) continue;
11980
- let alpha = o.alpha;
11981
- if (o.pulseAmplitude > 0) {
11982
- const elapsed = (animTime - o.spawnTime) / 1e3;
11983
- alpha += Math.sin(elapsed * o.pulseFrequency * Math.PI * 2) * o.pulseAmplitude;
11984
- alpha = Math.max(0, Math.min(1, alpha));
11985
- }
11986
- const w = img.naturalWidth * o.scale;
11987
- const h = img.naturalHeight * o.scale;
11988
- const prevAlpha = ctx.globalAlpha;
11989
- const prevBlend = ctx.globalCompositeOperation;
11990
- ctx.globalAlpha = alpha;
11991
- ctx.globalCompositeOperation = o.blendMode;
11992
- ctx.drawImage(img, o.x - w / 2, o.y - h / 2, w, h);
11993
- ctx.globalAlpha = prevAlpha;
11994
- ctx.globalCompositeOperation = prevBlend;
11995
- }
11996
- for (const s of state.sequences) {
11997
- const elapsed = animTime - s.startTime;
11998
- let frameIndex = Math.floor(elapsed / s.frameDuration);
11999
- if (s.loop) {
12000
- frameIndex = frameIndex % s.frameUrls.length;
12001
- } else if (frameIndex >= s.frameUrls.length) {
12002
- continue;
12003
- }
12004
- const img = getImage(s.frameUrls[frameIndex]);
12005
- if (!img) continue;
12006
- const w = img.naturalWidth * s.scale;
12007
- const h = img.naturalHeight * s.scale;
12008
- if (s.tint) {
12009
- drawTintedImage(ctx, img, s.x - w / 2, s.y - h / 2, w, h, s.tint, s.alpha, s.blendMode);
12010
- } else {
12011
- const prevAlpha = ctx.globalAlpha;
12012
- const prevBlend = ctx.globalCompositeOperation;
12013
- ctx.globalAlpha = s.alpha;
12014
- ctx.globalCompositeOperation = s.blendMode;
12015
- ctx.drawImage(img, s.x - w / 2, s.y - h / 2, w, h);
12016
- ctx.globalAlpha = prevAlpha;
12017
- ctx.globalCompositeOperation = prevBlend;
12018
- }
12019
- }
12020
- for (const p2 of state.particles) {
12021
- const img = getImage(p2.spriteUrl);
12022
- if (!img) continue;
12023
- const w = img.naturalWidth * p2.scale;
12024
- const h = img.naturalHeight * p2.scale;
12025
- ctx.save();
12026
- ctx.translate(p2.x, p2.y);
12027
- ctx.rotate(p2.rotation);
12028
- drawTintedImage(ctx, img, -w / 2, -h / 2, w, h, p2.tint, p2.alpha, p2.blendMode);
12029
- ctx.restore();
12030
- }
12031
- }
12032
- function hasActiveEffects(state) {
12033
- return state.particles.length > 0 || state.sequences.length > 0 || state.overlays.length > 0;
12034
- }
12035
- function getAllEffectSpriteUrls(manifest) {
12036
- const urls = [];
12037
- const base = manifest.baseUrl;
12038
- if (manifest.particles) {
12039
- for (const value of Object.values(manifest.particles)) {
12040
- if (Array.isArray(value)) {
12041
- value.forEach((v) => urls.push(`${base}/${v}`));
12042
- } else if (typeof value === "string") {
12043
- urls.push(`${base}/${value}`);
12044
- }
12045
- }
12046
- }
12047
- if (manifest.animations) {
12048
- for (const frames of Object.values(manifest.animations)) {
12049
- if (Array.isArray(frames)) {
12050
- frames.forEach((f3) => urls.push(`${base}/${f3}`));
12051
- }
12052
- }
12053
- }
12054
- return urls;
12055
- }
12056
- var _offscreen, _offCtx;
12057
- var init_canvasEffects = __esm({
12058
- "components/game/shared/canvasEffects.ts"() {
12059
- _offscreen = null;
12060
- _offCtx = null;
12061
- }
12062
- });
12063
-
12064
11051
  // components/game/shared/index.ts
12065
11052
  var init_shared = __esm({
12066
11053
  "components/game/shared/index.ts"() {
12067
11054
  init_effects();
12068
11055
  init_boardEntity();
12069
11056
  init_makeAsset();
12070
- init_combatPresets();
12071
- init_canvasEffects();
12072
11057
  }
12073
11058
  });
12074
11059
  function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
@@ -14403,13 +13388,13 @@ function useRenderInterpolation(options = {}) {
14403
13388
  const prevMap = /* @__PURE__ */ new Map();
14404
13389
  for (const e of prev.entities) prevMap.set(e.id, e);
14405
13390
  for (const c of curr.entities) {
14406
- const p2 = prevMap.get(c.id);
14407
- if (!p2) {
13391
+ const p = prevMap.get(c.id);
13392
+ if (!p) {
14408
13393
  out.set(c.id, { x: c.x, y: c.y });
14409
13394
  } else {
14410
13395
  out.set(c.id, {
14411
- x: p2.x + (c.x - p2.x) * alpha,
14412
- y: p2.y + (c.y - p2.y) * alpha
13396
+ x: p.x + (c.x - p.x) * alpha,
13397
+ y: p.y + (c.y - p.y) * alpha
14413
13398
  });
14414
13399
  }
14415
13400
  }
@@ -14974,8 +13959,8 @@ function Canvas2D({
14974
13959
  if (isFree) return 0;
14975
13960
  return (gridHeight - 1) * (scaledTileWidth / 2);
14976
13961
  }, [isFree, gridHeight, scaledTileWidth]);
14977
- const validMoveSet = useMemo(() => new Set(validMoves.map((p2) => `${p2.x},${p2.y}`)), [validMoves]);
14978
- const attackTargetSet = useMemo(() => new Set(attackTargets.map((p2) => `${p2.x},${p2.y}`)), [attackTargets]);
13962
+ const validMoveSet = useMemo(() => new Set(validMoves.map((p) => `${p.x},${p.y}`)), [validMoves]);
13963
+ const attackTargetSet = useMemo(() => new Set(attackTargets.map((p) => `${p.x},${p.y}`)), [attackTargets]);
14979
13964
  const spriteUrls = useMemo(() => {
14980
13965
  const urls = [];
14981
13966
  for (const tile of sortedTiles) {
@@ -15692,264 +14677,6 @@ var init_Canvas2D = __esm({
15692
14677
  Canvas2D.displayName = "Canvas2D";
15693
14678
  }
15694
14679
  });
15695
- function CanvasEffectEngine({
15696
- actionType,
15697
- x,
15698
- y,
15699
- duration = 2e3,
15700
- intensity = 1,
15701
- onComplete,
15702
- className,
15703
- assetManifest,
15704
- width = 400,
15705
- height = 300
15706
- }) {
15707
- const canvasRef = useRef(null);
15708
- const stateRef = useRef({ ...EMPTY_EFFECT_STATE });
15709
- const lastTimeRef = useRef(0);
15710
- const rafRef = useRef(0);
15711
- const imageCacheRef = useRef(/* @__PURE__ */ new Map());
15712
- const [shakeOffset, setShakeOffset] = useState({ x: 0, y: 0 });
15713
- const [flash, setFlash] = useState(null);
15714
- const shakeRef = useRef({ x: 0, y: 0, intensity: 0 });
15715
- const presets = useMemo(() => createCombatPresets(assetManifest), [assetManifest]);
15716
- const spriteUrls = useMemo(() => getAllEffectSpriteUrls(assetManifest), [assetManifest]);
15717
- useEffect(() => {
15718
- const cache = imageCacheRef.current;
15719
- for (const url of spriteUrls) {
15720
- if (!cache.has(url)) {
15721
- const img = new Image();
15722
- img.crossOrigin = "anonymous";
15723
- img.src = url;
15724
- cache.set(url, img);
15725
- }
15726
- }
15727
- }, [spriteUrls]);
15728
- const getImage = useCallback((url) => {
15729
- const img = imageCacheRef.current.get(url);
15730
- return img?.complete ? img : void 0;
15731
- }, []);
15732
- useEffect(() => {
15733
- const now2 = performance.now();
15734
- const effectX = x || width / 2;
15735
- const effectY = y || height / 2;
15736
- const preset = presets[actionType](effectX, effectY);
15737
- const state = stateRef.current;
15738
- for (const emitter of preset.particles) {
15739
- const scaledEmitter = { ...emitter, count: Math.round(emitter.count * intensity) };
15740
- state.particles.push(...spawnParticles(scaledEmitter, now2));
15741
- }
15742
- for (const seqConfig of preset.sequences) {
15743
- state.sequences.push(spawnSequence(seqConfig, now2));
15744
- }
15745
- for (const ovConfig of preset.overlays) {
15746
- state.overlays.push(spawnOverlay(ovConfig, now2));
15747
- }
15748
- if (preset.screenShake > 0) {
15749
- shakeRef.current.intensity = preset.screenShake * intensity;
15750
- }
15751
- if (preset.screenFlash) {
15752
- const { r: r2, g, b, duration: flashDur } = preset.screenFlash;
15753
- setFlash({ color: `rgb(${r2}, ${g}, ${b})`, alpha: 0.3 });
15754
- setTimeout(() => setFlash(null), flashDur);
15755
- }
15756
- const timer = setTimeout(() => {
15757
- onComplete?.();
15758
- }, duration);
15759
- return () => clearTimeout(timer);
15760
- }, []);
15761
- useEffect(() => {
15762
- const canvas = canvasRef.current;
15763
- if (!canvas) return;
15764
- const ctx = canvas.getContext("2d");
15765
- if (!ctx) return;
15766
- function loop(animTime) {
15767
- const delta = lastTimeRef.current > 0 ? animTime - lastTimeRef.current : 16;
15768
- lastTimeRef.current = animTime;
15769
- stateRef.current = updateEffectState(stateRef.current, animTime, delta);
15770
- if (shakeRef.current.intensity > 0.2) {
15771
- const i = shakeRef.current.intensity;
15772
- shakeRef.current.x = (Math.random() - 0.5) * i * 2;
15773
- shakeRef.current.y = (Math.random() - 0.5) * i * 2;
15774
- shakeRef.current.intensity *= 0.85;
15775
- setShakeOffset({ x: shakeRef.current.x, y: shakeRef.current.y });
15776
- } else if (shakeRef.current.intensity > 0) {
15777
- shakeRef.current = { x: 0, y: 0, intensity: 0 };
15778
- setShakeOffset({ x: 0, y: 0 });
15779
- }
15780
- ctx.clearRect(0, 0, width, height);
15781
- drawEffectState(ctx, stateRef.current, animTime, getImage);
15782
- if (hasActiveEffects(stateRef.current)) {
15783
- rafRef.current = requestAnimationFrame(loop);
15784
- }
15785
- }
15786
- rafRef.current = requestAnimationFrame(loop);
15787
- return () => cancelAnimationFrame(rafRef.current);
15788
- }, [width, height, getImage]);
15789
- const shakeStyle = shakeOffset.x !== 0 || shakeOffset.y !== 0 ? { transform: `translate(${shakeOffset.x}px, ${shakeOffset.y}px)` } : {};
15790
- return /* @__PURE__ */ jsxs(
15791
- Box,
15792
- {
15793
- className: cn("absolute inset-0 pointer-events-none z-10", className),
15794
- style: shakeStyle,
15795
- children: [
15796
- flash && /* @__PURE__ */ jsx(
15797
- Box,
15798
- {
15799
- className: "absolute inset-0 z-20 pointer-events-none rounded-container",
15800
- style: { backgroundColor: flash.color, opacity: flash.alpha }
15801
- }
15802
- ),
15803
- /* @__PURE__ */ jsx(
15804
- "canvas",
15805
- {
15806
- ref: canvasRef,
15807
- width,
15808
- height,
15809
- className: "absolute inset-0 w-full h-full",
15810
- style: { imageRendering: "pixelated" }
15811
- }
15812
- )
15813
- ]
15814
- }
15815
- );
15816
- }
15817
- function EmojiEffect({
15818
- actionType,
15819
- x,
15820
- y,
15821
- duration = 800,
15822
- intensity = 1,
15823
- onComplete,
15824
- className,
15825
- effectSpriteUrl,
15826
- assetBaseUrl
15827
- }) {
15828
- const [visible, setVisible] = useState(true);
15829
- const [phase, setPhase] = useState("enter");
15830
- useEffect(() => {
15831
- const enterTimer = setTimeout(() => setPhase("active"), 100);
15832
- const exitTimer = setTimeout(() => setPhase("exit"), duration * 0.7);
15833
- const doneTimer = setTimeout(() => {
15834
- setVisible(false);
15835
- onComplete?.();
15836
- }, duration);
15837
- return () => {
15838
- clearTimeout(enterTimer);
15839
- clearTimeout(exitTimer);
15840
- clearTimeout(doneTimer);
15841
- };
15842
- }, [duration, onComplete]);
15843
- if (!visible) return null;
15844
- const config = ACTION_EMOJI[actionType] ?? ACTION_EMOJI.melee;
15845
- const scaleVal = phase === "enter" ? 0.3 : phase === "active" ? intensity : 0.5;
15846
- const opacity = phase === "exit" ? 0 : 1;
15847
- const resolvedSpriteUrl = effectSpriteUrl ? effectSpriteUrl.startsWith("http") || effectSpriteUrl.startsWith("/") ? effectSpriteUrl : assetBaseUrl ? `${assetBaseUrl.replace(/\/$/, "")}/${effectSpriteUrl}` : effectSpriteUrl : void 0;
15848
- return /* @__PURE__ */ jsxs(
15849
- Box,
15850
- {
15851
- className: cn(
15852
- "fixed pointer-events-none z-50 flex items-center justify-center",
15853
- "transition-all ease-out",
15854
- className
15855
- ),
15856
- style: {
15857
- left: x,
15858
- top: y,
15859
- transform: `translate(-50%, -50%) scale(${scaleVal})`,
15860
- opacity,
15861
- transitionDuration: phase === "enter" ? "100ms" : "300ms"
15862
- },
15863
- children: [
15864
- /* @__PURE__ */ jsx(
15865
- Box,
15866
- {
15867
- className: "absolute rounded-pill animate-ping",
15868
- style: {
15869
- width: 48 * intensity,
15870
- height: 48 * intensity,
15871
- backgroundColor: config.color,
15872
- opacity: 0.25
15873
- }
15874
- }
15875
- ),
15876
- resolvedSpriteUrl ? /* @__PURE__ */ jsx(
15877
- "img",
15878
- {
15879
- src: resolvedSpriteUrl,
15880
- alt: config.label,
15881
- className: "relative drop-shadow-lg",
15882
- style: {
15883
- width: `${3 * intensity}rem`,
15884
- height: `${3 * intensity}rem`,
15885
- objectFit: "contain",
15886
- imageRendering: "pixelated"
15887
- }
15888
- }
15889
- ) : /* @__PURE__ */ jsx(
15890
- "span",
15891
- {
15892
- className: "relative text-3xl drop-shadow-lg",
15893
- style: { fontSize: `${2 * intensity}rem` },
15894
- role: "img",
15895
- "aria-label": config.label,
15896
- children: config.emoji
15897
- }
15898
- )
15899
- ]
15900
- }
15901
- );
15902
- }
15903
- function CanvasEffect({
15904
- effectSpriteUrl,
15905
- assetBaseUrl,
15906
- ...props
15907
- }) {
15908
- const eventBus = useEventBus();
15909
- const mergedProps = { effectSpriteUrl, assetBaseUrl, ...props };
15910
- const { completeEvent, onComplete, ...rest } = mergedProps;
15911
- const handleComplete = useCallback(() => {
15912
- if (completeEvent) eventBus.emit(`UI:${completeEvent}`, {});
15913
- onComplete?.();
15914
- }, [completeEvent, eventBus, onComplete]);
15915
- const enhancedProps = { ...rest, onComplete: handleComplete };
15916
- if (rest.assetManifest) {
15917
- return /* @__PURE__ */ jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: rest.assetManifest });
15918
- }
15919
- return /* @__PURE__ */ jsx(EmojiEffect, { ...enhancedProps });
15920
- }
15921
- var ACTION_EMOJI;
15922
- var init_CanvasEffect = __esm({
15923
- "components/game/2d/organisms/CanvasEffect.tsx"() {
15924
- "use client";
15925
- init_cn();
15926
- init_useEventBus();
15927
- init_Box();
15928
- init_effects();
15929
- init_canvasEffects();
15930
- init_combatPresets();
15931
- ACTION_EMOJI = {
15932
- melee: { emoji: "\u2694\uFE0F", color: "var(--color-error)", label: "Slash" },
15933
- ranged: { emoji: "\u{1F3F9}", color: "var(--color-warning)", label: "Arrow" },
15934
- magic: { emoji: "\u2728", color: "var(--color-primary)", label: "Spell" },
15935
- heal: { emoji: "\u{1F49A}", color: "var(--color-success)", label: "Heal" },
15936
- buff: { emoji: "\u2B06\uFE0F", color: "var(--color-info)", label: "Buff" },
15937
- debuff: { emoji: "\u2B07\uFE0F", color: "var(--color-warning)", label: "Debuff" },
15938
- shield: { emoji: "\u{1F6E1}\uFE0F", color: "var(--color-info)", label: "Shield" },
15939
- aoe: { emoji: "\u{1F4A5}", color: "var(--color-error)", label: "Explosion" },
15940
- critical: { emoji: "\u{1F525}", color: "var(--color-error)", label: "Critical" },
15941
- defend: { emoji: "\u{1F6E1}\uFE0F", color: "var(--color-info)", label: "Defend" },
15942
- hit: { emoji: "\u{1F4A5}", color: "var(--color-error)", label: "Hit" },
15943
- death: { emoji: "\u{1F480}", color: "var(--color-error)", label: "Death" }
15944
- };
15945
- CanvasEffect.displayName = "CanvasEffect";
15946
- }
15947
- });
15948
- var init_useCanvasEffects = __esm({
15949
- "components/game/shared/hooks/useCanvasEffects.ts"() {
15950
- "use client";
15951
- }
15952
- });
15953
14680
  var init_useGameAudio = __esm({
15954
14681
  "components/game/shared/hooks/useGameAudio.ts"() {
15955
14682
  "use client";
@@ -18569,7 +17296,7 @@ function NegotiatorBoard({
18569
17296
  useEffect(() => {
18570
17297
  if (currentRound > prevRoundRef.current && lastPlayerAction) {
18571
17298
  const opponentPayoffEntry = payoffMatrix.find(
18572
- (p2) => p2.playerAction === lastPlayerAction && p2.opponentAction === lastOpponentAction
17299
+ (p) => p.playerAction === lastPlayerAction && p.opponentAction === lastOpponentAction
18573
17300
  );
18574
17301
  setHistory((prev) => [
18575
17302
  ...prev,
@@ -18855,14 +17582,14 @@ function SimulationCanvas({
18855
17582
  const ctx = canvas.getContext("2d");
18856
17583
  if (!ctx) return;
18857
17584
  const bodies = bodiesRef.current;
18858
- const p2 = presetRef.current;
17585
+ const p = presetRef.current;
18859
17586
  const w = widthRef.current;
18860
17587
  const h = heightRef.current;
18861
17588
  ctx.clearRect(0, 0, w, h);
18862
- ctx.fillStyle = p2.backgroundColor ?? "#1a1a2e";
17589
+ ctx.fillStyle = p.backgroundColor ?? "#1a1a2e";
18863
17590
  ctx.fillRect(0, 0, w, h);
18864
- if (p2.constraints) {
18865
- for (const c of p2.constraints) {
17591
+ if (p.constraints) {
17592
+ for (const c of p.constraints) {
18866
17593
  const a = bodies[c.bodyA];
18867
17594
  const b = bodies[c.bodyB];
18868
17595
  if (a && b) {
@@ -18885,7 +17612,7 @@ function SimulationCanvas({
18885
17612
  ctx.arc(pos.x, pos.y, body.radius, 0, Math.PI * 2);
18886
17613
  ctx.fillStyle = body.color ?? "#e94560";
18887
17614
  ctx.fill();
18888
- if (p2.showVelocity) {
17615
+ if (p.showVelocity) {
18889
17616
  ctx.beginPath();
18890
17617
  ctx.moveTo(pos.x, pos.y);
18891
17618
  ctx.lineTo(pos.x + body.vx * 0.1, pos.y + body.vy * 0.1);
@@ -19144,7 +17871,6 @@ var init_GameShell = __esm({
19144
17871
  var init_molecules = __esm({
19145
17872
  "components/game/2d/molecules/index.ts"() {
19146
17873
  init_shared();
19147
- init_useCanvasEffects();
19148
17874
  init_puzzleObject();
19149
17875
  }
19150
17876
  });
@@ -19185,8 +17911,8 @@ function shapeBounds(shape) {
19185
17911
  case "polygon":
19186
17912
  if (!shape.points || shape.points.length === 0) return null;
19187
17913
  {
19188
- const xs = shape.points.map((p2) => p2.x);
19189
- const ys = shape.points.map((p2) => p2.y);
17914
+ const xs = shape.points.map((p) => p.x);
17915
+ const ys = shape.points.map((p) => p.y);
19190
17916
  const minX = Math.min(...xs);
19191
17917
  const minY = Math.min(...ys);
19192
17918
  return {
@@ -19312,13 +18038,13 @@ function drawShape(ctx, shape, width, height) {
19312
18038
  }
19313
18039
  case "path": {
19314
18040
  if (!shape.path) break;
19315
- const p2 = new Path2D(shape.path);
18041
+ const p = new Path2D(shape.path);
19316
18042
  if (fill) {
19317
18043
  ctx.fillStyle = fill;
19318
- ctx.fill(p2);
18044
+ ctx.fill(p);
19319
18045
  }
19320
18046
  ctx.strokeStyle = stroke;
19321
- ctx.stroke(p2);
18047
+ ctx.stroke(p);
19322
18048
  break;
19323
18049
  }
19324
18050
  case "text": {
@@ -24001,7 +22727,7 @@ function renderStateMachineToDomData(stateMachine, options = {}, config = DEFAUL
24001
22727
  }
24002
22728
  let domOutputs;
24003
22729
  if (outputs.length > 0) {
24004
- const maxX = Math.max(...Object.values(positions).map((p2) => p2.x));
22730
+ const maxX = Math.max(...Object.values(positions).map((p) => p.x));
24005
22731
  const maxOutputLength = Math.max(...outputs.map((o) => o.length));
24006
22732
  const boxWidth = Math.max(200, maxOutputLength * 7 + 30);
24007
22733
  const lineHeight = 22;
@@ -24983,7 +23709,7 @@ var init_BookViewer = __esm({
24983
23709
  }
24984
23710
  });
24985
23711
  function BoxPattern({
24986
- p: p2,
23712
+ p,
24987
23713
  m,
24988
23714
  bg = "transparent",
24989
23715
  border = false,
@@ -24996,7 +23722,7 @@ function BoxPattern({
24996
23722
  return /* @__PURE__ */ jsx(
24997
23723
  Box,
24998
23724
  {
24999
- padding: p2,
23725
+ padding: p,
25000
23726
  margin: m,
25001
23727
  bg,
25002
23728
  border,
@@ -26765,10 +25491,10 @@ var init_Chart = __esm({
26765
25491
  const set = [];
26766
25492
  const seen = /* @__PURE__ */ new Set();
26767
25493
  for (const s of series) {
26768
- for (const p2 of s.data) {
26769
- if (!seen.has(p2.label)) {
26770
- seen.add(p2.label);
26771
- set.push(p2.label);
25494
+ for (const p of s.data) {
25495
+ if (!seen.has(p.label)) {
25496
+ seen.add(p.label);
25497
+ set.push(p.label);
26772
25498
  }
26773
25499
  }
26774
25500
  }
@@ -26776,8 +25502,8 @@ var init_Chart = __esm({
26776
25502
  }, [series]);
26777
25503
  const valueAt = useCallback(
26778
25504
  (s, label) => {
26779
- const p2 = s.data.find((d) => d.label === label);
26780
- return p2 ? p2.value : 0;
25505
+ const p = s.data.find((d) => d.label === label);
25506
+ return p ? p.value : 0;
26781
25507
  },
26782
25508
  []
26783
25509
  );
@@ -26794,7 +25520,7 @@ var init_Chart = __esm({
26794
25520
  }
26795
25521
  let m = 1;
26796
25522
  for (const s of series) {
26797
- for (const p2 of s.data) if (p2.value > m) m = p2.value;
25523
+ for (const p of s.data) if (p.value > m) m = p.value;
26798
25524
  }
26799
25525
  return m;
26800
25526
  }, [series, stack, columnTotals]);
@@ -27054,10 +25780,10 @@ var init_Chart = __esm({
27054
25780
  const seen = /* @__PURE__ */ new Set();
27055
25781
  const out = [];
27056
25782
  for (const s of series) {
27057
- for (const p2 of s.data) {
27058
- if (!seen.has(p2.label)) {
27059
- seen.add(p2.label);
27060
- out.push(p2.label);
25783
+ for (const p of s.data) {
25784
+ if (!seen.has(p.label)) {
25785
+ seen.add(p.label);
25786
+ out.push(p.label);
27061
25787
  }
27062
25788
  }
27063
25789
  }
@@ -27066,7 +25792,7 @@ var init_Chart = __esm({
27066
25792
  const maxValue = useMemo(() => {
27067
25793
  let m = 1;
27068
25794
  for (const s of series) {
27069
- for (const p2 of s.data) if (p2.value > m) m = p2.value;
25795
+ for (const p of s.data) if (p.value > m) m = p.value;
27070
25796
  }
27071
25797
  return m;
27072
25798
  }, [series]);
@@ -27113,7 +25839,7 @@ var init_Chart = __esm({
27113
25839
  label
27114
25840
  };
27115
25841
  });
27116
- const linePath = points.map((p2, i) => `${i === 0 ? "M" : "L"} ${p2.x} ${p2.y}`).join(" ");
25842
+ const linePath = points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
27117
25843
  const areaPath = `${linePath} L ${points[points.length - 1]?.x ?? 0} ${padding.top + chartHeight} L ${padding.left} ${padding.top + chartHeight} Z`;
27118
25844
  return /* @__PURE__ */ jsxs("g", { children: [
27119
25845
  fill && /* @__PURE__ */ jsx(
@@ -27136,19 +25862,19 @@ var init_Chart = __esm({
27136
25862
  strokeDasharray: s.dashed ? "6 4" : void 0
27137
25863
  }
27138
25864
  ),
27139
- points.map((p2, idx) => /* @__PURE__ */ jsxs("g", { children: [
25865
+ points.map((p, idx) => /* @__PURE__ */ jsxs("g", { children: [
27140
25866
  /* @__PURE__ */ jsx(
27141
25867
  "circle",
27142
25868
  {
27143
- cx: p2.x,
27144
- cy: p2.y,
25869
+ cx: p.x,
25870
+ cy: p.y,
27145
25871
  r: "4",
27146
25872
  fill: "var(--color-card)",
27147
25873
  stroke: color,
27148
25874
  strokeWidth: "2",
27149
25875
  className: "cursor-pointer",
27150
25876
  onClick: () => onPointClick?.(
27151
- { label: p2.label, value: p2.value, color },
25877
+ { label: p.label, value: p.value, color },
27152
25878
  s.name
27153
25879
  )
27154
25880
  }
@@ -27156,13 +25882,13 @@ var init_Chart = __esm({
27156
25882
  showValues && series.length === 1 && /* @__PURE__ */ jsx(
27157
25883
  "text",
27158
25884
  {
27159
- x: p2.x,
27160
- y: p2.y - 10,
25885
+ x: p.x,
25886
+ y: p.y - 10,
27161
25887
  textAnchor: "middle",
27162
25888
  fill: "var(--color-foreground)",
27163
25889
  fontSize: "10",
27164
25890
  fontWeight: "500",
27165
- children: p2.value
25891
+ children: p.value
27166
25892
  }
27167
25893
  )
27168
25894
  ] }, idx))
@@ -27197,11 +25923,11 @@ var init_Chart = __esm({
27197
25923
  let mxX = data[0].x;
27198
25924
  let mnY = data[0].y;
27199
25925
  let mxY = data[0].y;
27200
- for (const p2 of data) {
27201
- if (p2.x < mnX) mnX = p2.x;
27202
- if (p2.x > mxX) mxX = p2.x;
27203
- if (p2.y < mnY) mnY = p2.y;
27204
- if (p2.y > mxY) mxY = p2.y;
25926
+ for (const p of data) {
25927
+ if (p.x < mnX) mnX = p.x;
25928
+ if (p.x > mxX) mxX = p.x;
25929
+ if (p.y < mnY) mnY = p.y;
25930
+ if (p.y > mxY) mxY = p.y;
27205
25931
  }
27206
25932
  return { minX: mnX, maxX: mxX, minY: mnY, maxY: mxY };
27207
25933
  }, [data]);
@@ -27231,11 +25957,11 @@ var init_Chart = __esm({
27231
25957
  frac
27232
25958
  );
27233
25959
  }),
27234
- data.map((p2, idx) => {
27235
- const cx = padding.left + (p2.x - minX) / rangeX * chartWidth;
27236
- const cy = padding.top + chartHeight - (p2.y - minY) / rangeY * chartHeight;
27237
- const r2 = p2.size ?? 5;
27238
- const color = p2.color ?? CHART_COLORS[idx % CHART_COLORS.length];
25960
+ data.map((p, idx) => {
25961
+ const cx = padding.left + (p.x - minX) / rangeX * chartWidth;
25962
+ const cy = padding.top + chartHeight - (p.y - minY) / rangeY * chartHeight;
25963
+ const r2 = p.size ?? 5;
25964
+ const color = p.color ?? CHART_COLORS[idx % CHART_COLORS.length];
27239
25965
  return /* @__PURE__ */ jsx(
27240
25966
  "circle",
27241
25967
  {
@@ -27247,13 +25973,13 @@ var init_Chart = __esm({
27247
25973
  className: "cursor-pointer hover:opacity-100",
27248
25974
  onClick: () => onPointClick?.(
27249
25975
  {
27250
- label: p2.label ?? `(${p2.x}, ${p2.y})`,
27251
- value: p2.y,
25976
+ label: p.label ?? `(${p.x}, ${p.y})`,
25977
+ value: p.y,
27252
25978
  color
27253
25979
  },
27254
25980
  "default"
27255
25981
  ),
27256
- children: /* @__PURE__ */ jsx("title", { children: p2.label ?? `(${p2.x}, ${p2.y})` })
25982
+ children: /* @__PURE__ */ jsx("title", { children: p.label ?? `(${p.x}, ${p.y})` })
27257
25983
  },
27258
25984
  idx
27259
25985
  );
@@ -33411,7 +32137,7 @@ var init_LineChart = __esm({
33411
32137
  }, [sortedData, width, height]);
33412
32138
  const linePath = useMemo(() => {
33413
32139
  if (points.length === 0) return "";
33414
- return points.map((p2, i) => `${i === 0 ? "M" : "L"} ${p2.x} ${p2.y}`).join(" ");
32140
+ return points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
33415
32141
  }, [points]);
33416
32142
  const areaPath = useMemo(() => {
33417
32143
  if (points.length === 0 || !showArea) return "";
@@ -33611,18 +32337,18 @@ var init_MathCanvas = __esm({
33611
32337
  });
33612
32338
  }
33613
32339
  }
33614
- for (const p2 of points) {
33615
- if (p2.x < xMin || p2.x > xMax || p2.y < yMin || p2.y > yMax) continue;
32340
+ for (const p of points) {
32341
+ if (p.x < xMin || p.x > xMax || p.y < yMin || p.y > yMax) continue;
33616
32342
  out.push({
33617
32343
  type: "circle",
33618
- x: mapX(p2.x),
33619
- y: mapY(p2.y),
33620
- radius: p2.radius ?? 4,
33621
- color: p2.color ?? "#dc2626",
33622
- fill: p2.color ?? "#dc2626"
32344
+ x: mapX(p.x),
32345
+ y: mapY(p.y),
32346
+ radius: p.radius ?? 4,
32347
+ color: p.color ?? "#dc2626",
32348
+ fill: p.color ?? "#dc2626"
33623
32349
  });
33624
- if (p2.label) {
33625
- out.push({ type: "text", x: mapX(p2.x) + 8, y: mapY(p2.y) - 8, text: p2.label, color: "#111827", fontSize: 12 });
32350
+ if (p.label) {
32351
+ out.push({ type: "text", x: mapX(p.x) + 8, y: mapY(p.y) - 8, text: p.label, color: "#111827", fontSize: 12 });
33626
32352
  }
33627
32353
  }
33628
32354
  for (const v of vectors) {
@@ -34141,13 +32867,13 @@ var init_MapView = __esm({
34141
32867
  shadowSize: [41, 41]
34142
32868
  });
34143
32869
  L.Marker.prototype.options.icon = defaultIcon;
34144
- const { useEffect: useEffect72, useRef: useRef69, useCallback: useCallback107, useState: useState107 } = React104__default;
32870
+ const { useEffect: useEffect71, useRef: useRef67, useCallback: useCallback105, useState: useState105 } = React104__default;
34145
32871
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
34146
32872
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
34147
32873
  function MapUpdater({ centerLat, centerLng, zoom }) {
34148
32874
  const map = useMap();
34149
- const prevRef = useRef69({ centerLat, centerLng, zoom });
34150
- useEffect72(() => {
32875
+ const prevRef = useRef67({ centerLat, centerLng, zoom });
32876
+ useEffect71(() => {
34151
32877
  const prev = prevRef.current;
34152
32878
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
34153
32879
  map.setView([centerLat, centerLng], zoom);
@@ -34158,7 +32884,7 @@ var init_MapView = __esm({
34158
32884
  }
34159
32885
  function MapClickHandler({ onMapClick }) {
34160
32886
  const map = useMap();
34161
- useEffect72(() => {
32887
+ useEffect71(() => {
34162
32888
  if (!onMapClick) return;
34163
32889
  const handler = (e) => {
34164
32890
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -34186,8 +32912,8 @@ var init_MapView = __esm({
34186
32912
  showAttribution = true
34187
32913
  }) {
34188
32914
  const eventBus = useEventBus2();
34189
- const [clickedPosition, setClickedPosition] = useState107(null);
34190
- const handleMapClick = useCallback107((lat, lng) => {
32915
+ const [clickedPosition, setClickedPosition] = useState105(null);
32916
+ const handleMapClick = useCallback105((lat, lng) => {
34191
32917
  if (showClickedPin) {
34192
32918
  setClickedPosition({ lat, lng });
34193
32919
  }
@@ -34196,7 +32922,7 @@ var init_MapView = __esm({
34196
32922
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
34197
32923
  }
34198
32924
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
34199
- const handleMarkerClick = useCallback107((marker) => {
32925
+ const handleMarkerClick = useCallback105((marker) => {
34200
32926
  onMarkerClick?.(marker);
34201
32927
  if (markerClickEvent) {
34202
32928
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -35269,7 +33995,7 @@ function TableView({
35269
33995
  children: [
35270
33996
  header,
35271
33997
  dnd.wrapContainer(body),
35272
- hasMore && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setVisibleCount((p2) => p2 + (pageSize || 5)), children: [
33998
+ hasMore && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setVisibleCount((p) => p + (pageSize || 5)), children: [
35273
33999
  /* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
35274
34000
  t("common.showMore"),
35275
34001
  " (",
@@ -37991,7 +36717,7 @@ var init_QrScanner = __esm({
37991
36717
  setCurrentFacing((f3) => f3 === "environment" ? "user" : "environment");
37992
36718
  }, []);
37993
36719
  const togglePause = useCallback(() => {
37994
- setIsPaused((p2) => !p2);
36720
+ setIsPaused((p) => !p);
37995
36721
  }, []);
37996
36722
  const handleMockScan = useCallback(() => {
37997
36723
  const result = {
@@ -42043,12 +40769,12 @@ var init_DocumentViewer = __esm({
42043
40769
  const handleZoomIn = useCallback(() => setZoom((z) => Math.min(z + 25, 200)), []);
42044
40770
  const handleZoomOut = useCallback(() => setZoom((z) => Math.max(z - 25, 50)), []);
42045
40771
  const handlePagePrev = useCallback(() => {
42046
- setCurrentPage((p2) => Math.max(p2 - 1, 1));
40772
+ setCurrentPage((p) => Math.max(p - 1, 1));
42047
40773
  eventBus.emit("UI:DOCUMENT_PAGE_CHANGE", { page: currentPage - 1 });
42048
40774
  }, [eventBus, currentPage]);
42049
40775
  const handlePageNext = useCallback(() => {
42050
40776
  if (totalPages) {
42051
- setCurrentPage((p2) => Math.min(p2 + 1, totalPages));
40777
+ setCurrentPage((p) => Math.min(p + 1, totalPages));
42052
40778
  eventBus.emit("UI:DOCUMENT_PAGE_CHANGE", { page: currentPage + 1 });
42053
40779
  }
42054
40780
  }, [totalPages, eventBus, currentPage]);
@@ -46150,7 +44876,7 @@ function WalkMinimap() {
46150
44876
  const graphH = 120;
46151
44877
  const nodeR = 10;
46152
44878
  const positions = activeTrait ? layoutGraph(activeTrait.states, activeTrait.transitions, activeTrait.initialState, graphW, graphH) : [];
46153
- const posMap = new Map(positions.map((p2) => [p2.state, p2]));
44879
+ const posMap = new Map(positions.map((p) => [p.state, p]));
46154
44880
  const visitedStates = new Set(
46155
44881
  coveredEdges.filter((e) => e.trait === walkStep.traitName).flatMap((e) => [e.from, e.to])
46156
44882
  );
@@ -49420,7 +48146,6 @@ var init_component_registry_generated = __esm({
49420
48146
  init_CTABanner();
49421
48147
  init_CalendarGrid();
49422
48148
  init_Canvas2D();
49423
- init_CanvasEffect();
49424
48149
  init_Card();
49425
48150
  init_CardGrid();
49426
48151
  init_Carousel();
@@ -49719,7 +48444,6 @@ var init_component_registry_generated = __esm({
49719
48444
  "CTABanner": CTABanner,
49720
48445
  "CalendarGrid": CalendarGrid,
49721
48446
  "Canvas2D": Canvas2D,
49722
- "CanvasEffect": CanvasEffect,
49723
48447
  "Card": Card,
49724
48448
  "CardGrid": CardGrid,
49725
48449
  "Carousel": Carousel,
@@ -52900,10 +51624,10 @@ function getTraits(orbital) {
52900
51624
  }
52901
51625
  function getPages(orbital) {
52902
51626
  if (!orbital.pages) return [];
52903
- return orbital.pages.map((p2) => {
52904
- if (typeof p2 === "string") return { name: p2, path: `/${p2.toLowerCase()}` };
52905
- if ("ref" in p2 && !("path" in p2)) return { name: p2.ref, path: `/${p2.ref.toLowerCase()}` };
52906
- return p2;
51627
+ return orbital.pages.map((p) => {
51628
+ if (typeof p === "string") return { name: p, path: `/${p.toLowerCase()}` };
51629
+ if ("ref" in p && !("path" in p)) return { name: p.ref, path: `/${p.ref.toLowerCase()}` };
51630
+ return p;
52907
51631
  });
52908
51632
  }
52909
51633
  function getStateMachine(trait) {
@@ -52979,7 +51703,7 @@ function parseApplicationLevel(schema) {
52979
51703
  fieldCount: entity.fields.length,
52980
51704
  persistence: entity.persistence,
52981
51705
  traitNames: traits2.map((t) => t.name ?? ""),
52982
- pageNames: pages.map((p2) => p2.name ?? ""),
51706
+ pageNames: pages.map((p) => p.name ?? ""),
52983
51707
  position: {
52984
51708
  x: originX + i % cols * spacing,
52985
51709
  y: originY + Math.floor(i / cols) * spacing
@@ -53041,9 +51765,9 @@ function parseOrbitalLevel(schema, orbitalName) {
53041
51765
  listens: getListens(t)
53042
51766
  };
53043
51767
  });
53044
- const pageInfos = pages.map((p2) => ({
53045
- name: p2.name ?? "",
53046
- route: p2.path ?? `/${(p2.name ?? "").toLowerCase()}`
51768
+ const pageInfos = pages.map((p) => ({
51769
+ name: p.name ?? "",
51770
+ route: p.path ?? `/${(p.name ?? "").toLowerCase()}`
53047
51771
  }));
53048
51772
  const externalLinks = [];
53049
51773
  const thisTraitEmits = traits2.flatMap((t) => getEmits(t).map((e) => ({ trait: t.name ?? "", event: e })));
@@ -53250,7 +51974,7 @@ var SystemNode = ({ data }) => {
53250
51974
  i < stateChain.length - 1 && /* @__PURE__ */ jsx("line", { x1: i * 14 + 12, y1: 5, x2: i * 14 + 15, y2: 5, stroke: "var(--color-border)", strokeWidth: 0.5 })
53251
51975
  ] }, s.name);
53252
51976
  }) }),
53253
- pageDots.length > 0 && /* @__PURE__ */ jsx("svg", { width: pageDots.length * 10, height: 10, viewBox: `0 0 ${pageDots.length * 10} 10`, children: pageDots.map((p2, i) => /* @__PURE__ */ jsx(AvlPage, { x: i * 10 + 4, y: 4, size: 5 }, p2.name)) })
51977
+ pageDots.length > 0 && /* @__PURE__ */ jsx("svg", { width: pageDots.length * 10, height: 10, viewBox: `0 0 ${pageDots.length * 10} 10`, children: pageDots.map((p, i) => /* @__PURE__ */ jsx(AvlPage, { x: i * 10 + 4, y: 4, size: 5 }, p.name)) })
53254
51978
  ] })
53255
51979
  ]
53256
51980
  }
@@ -53653,10 +52377,10 @@ function getEntityInfo(orbital) {
53653
52377
  }
53654
52378
  function getPages2(orbital) {
53655
52379
  if (!orbital.pages) return [];
53656
- return orbital.pages.map((p2) => {
53657
- if (typeof p2 === "string") return `/${p2.toLowerCase()}`;
53658
- if ("ref" in p2) return p2.path ?? `/${p2.ref}`.toLowerCase();
53659
- return p2.path ?? `/${p2.name}`.toLowerCase();
52380
+ return orbital.pages.map((p) => {
52381
+ if (typeof p === "string") return `/${p.toLowerCase()}`;
52382
+ if ("ref" in p) return p.path ?? `/${p.ref}`.toLowerCase();
52383
+ return p.path ?? `/${p.name}`.toLowerCase();
53660
52384
  });
53661
52385
  }
53662
52386
  function getEmits2(trait) {
@@ -53857,10 +52581,10 @@ function schemaToOverviewGraph(schema, mockData, behaviorMeta, layoutHint, orbit
53857
52581
  const smEvents = trait.stateMachine?.events ?? [];
53858
52582
  const matchingEvent = smEvents.find((ev) => ev.key === source.event);
53859
52583
  if (matchingEvent?.payloadSchema && Array.isArray(matchingEvent.payloadSchema)) {
53860
- source.payloadFields = matchingEvent.payloadSchema.map((p2) => ({
53861
- name: p2.name ?? "",
53862
- type: p2.type ?? "string",
53863
- ...p2.required ? { required: true } : {}
52584
+ source.payloadFields = matchingEvent.payloadSchema.map((p) => ({
52585
+ name: p.name ?? "",
52586
+ type: p.type ?? "string",
52587
+ ...p.required ? { required: true } : {}
53864
52588
  }));
53865
52589
  break;
53866
52590
  }
@@ -54356,12 +53080,12 @@ function isFnFormLambda(value) {
54356
53080
  return false;
54357
53081
  }
54358
53082
  const params = arr[1];
54359
- return typeof params === "string" || Array.isArray(params) && params.length > 0 && params.every((p2) => typeof p2 === "string");
53083
+ return typeof params === "string" || Array.isArray(params) && params.length > 0 && params.every((p) => typeof p === "string");
54360
53084
  }
54361
53085
  function fnFormParams(value) {
54362
- const p2 = value[1];
54363
- if (typeof p2 === "string") return [p2];
54364
- if (Array.isArray(p2)) return p2.filter((x) => typeof x === "string");
53086
+ const p = value[1];
53087
+ if (typeof p === "string") return [p];
53088
+ if (Array.isArray(p)) return p.filter((x) => typeof x === "string");
54365
53089
  return [];
54366
53090
  }
54367
53091
  function resolveLambdaBindings(body, params, item, index) {
@@ -55704,9 +54428,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
55704
54428
  const orbitalsByTrait = useMemo(
55705
54429
  () => buildOrbitalsByTrait(
55706
54430
  schema,
55707
- ir ? Array.from(ir.pages.values()).map((p2) => ({
55708
- path: p2.path,
55709
- traitNames: p2.traits.map((b) => b.trait.name)
54431
+ ir ? Array.from(ir.pages.values()).map((p) => ({
54432
+ path: p.path,
54433
+ traitNames: p.traits.map((b) => b.trait.name)
55710
54434
  })) : []
55711
54435
  ),
55712
54436
  [schema, ir]
@@ -55895,7 +54619,7 @@ function OrbPreview({
55895
54619
  navLog.debug("handleNavigate", () => ({
55896
54620
  path,
55897
54621
  matched: match?.page.name ?? null,
55898
- availablePaths: pages.map((p2) => p2.page.path)
54622
+ availablePaths: pages.map((p) => p.page.path)
55899
54623
  }));
55900
54624
  if (match) {
55901
54625
  setCurrentPage(match.page.name);
@@ -55939,7 +54663,7 @@ function OrbPreview({
55939
54663
  handleNavigate(href);
55940
54664
  };
55941
54665
  el.addEventListener("click", handler, true);
55942
- navLog.info("interceptor:installed", { pageCount: pages.length, paths: pages.map((p2) => p2.page.path) });
54666
+ navLog.info("interceptor:installed", { pageCount: pages.length, paths: pages.map((p) => p.page.path) });
55943
54667
  return () => el.removeEventListener("click", handler, true);
55944
54668
  }, [pages, handleNavigate]);
55945
54669
  return /* @__PURE__ */ jsxs(
@@ -58281,9 +57005,9 @@ function FlowCanvasInner({
58281
57005
  const [selectedPattern, setSelectedPattern] = useState(null);
58282
57006
  const patternSelectionValue = useMemo(() => ({
58283
57007
  selected: selectedPattern,
58284
- select: (p2) => {
58285
- setSelectedPattern(p2);
58286
- if (p2) setSelectedNode(p2.nodeData);
57008
+ select: (p) => {
57009
+ setSelectedPattern(p);
57010
+ if (p) setSelectedNode(p.nodeData);
58287
57011
  }
58288
57012
  }), [selectedPattern]);
58289
57013
  const [atBehaviorLevel, setAtBehaviorLevel] = useState(composeLevel === "behavior");
@@ -58555,7 +57279,7 @@ function FlowCanvasInner({
58555
57279
  /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-muted-foreground", children: level === "overview" ? t("canvas.modulesCount", { count: nodes.length }) : t("canvas.screensCount", { count: nodes.length }) })
58556
57280
  ] }),
58557
57281
  /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1 px-2 py-1 rounded-md bg-card/80 border border-border/40 backdrop-blur-sm", children: screenSizeKeys.map((size) => {
58558
- const p2 = SCREEN_SIZE_PRESETS[size];
57282
+ const p = SCREEN_SIZE_PRESETS[size];
58559
57283
  const active = screenSize === size;
58560
57284
  return /* @__PURE__ */ jsx(
58561
57285
  "button",
@@ -58567,9 +57291,9 @@ function FlowCanvasInner({
58567
57291
  });
58568
57292
  },
58569
57293
  className: `px-2 py-1 text-xs font-medium rounded cursor-pointer border-none transition-colors ${active ? "bg-primary text-primary-foreground" : "bg-transparent text-muted-foreground hover:text-foreground hover:bg-muted/50"}`,
58570
- title: `${p2.label} (${p2.width}px)`,
58571
- "aria-label": t("canvas.switchToView", { label: p2.label }),
58572
- children: p2.label
57294
+ title: `${p.label} (${p.width}px)`,
57295
+ "aria-label": t("canvas.switchToView", { label: p.label }),
57296
+ children: p.label
58573
57297
  },
58574
57298
  size
58575
57299
  );