@almadar/ui 5.28.2 → 5.28.4

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.
@@ -7757,7 +7757,7 @@ var init_DamageNumber = __esm({
7757
7757
  function DialogueBubble({
7758
7758
  speaker,
7759
7759
  text,
7760
- portrait = "https://almadar-kflow-assets.web.app/shared/characters/archetypes/00_base_model.png",
7760
+ portrait = "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
7761
7761
  position = "bottom",
7762
7762
  className
7763
7763
  }) {
@@ -10711,7 +10711,7 @@ function IsometricCanvas({
10711
10711
  // Rendering options
10712
10712
  scale = 0.4,
10713
10713
  debug: debug2 = false,
10714
- backgroundImage,
10714
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/court.png",
10715
10715
  showMinimap = true,
10716
10716
  enableCamera = true,
10717
10717
  unitScale = 1,
@@ -10726,7 +10726,7 @@ function IsometricCanvas({
10726
10726
  // Tuning
10727
10727
  diamondTopY: diamondTopYProp,
10728
10728
  // Remote asset loading
10729
- assetBaseUrl,
10729
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/",
10730
10730
  assetManifest
10731
10731
  }) {
10732
10732
  const tilesProp = Array.isArray(_tilesPropRaw) ? _tilesPropRaw : [];
@@ -11485,6 +11485,10 @@ var init_boardEntity = __esm({
11485
11485
  });
11486
11486
  function BattleBoard({
11487
11487
  entity,
11488
+ tiles: propTiles,
11489
+ units: propUnits,
11490
+ features: propFeatures,
11491
+ assetManifest: propAssetManifest,
11488
11492
  scale = 0.45,
11489
11493
  unitScale = 1,
11490
11494
  header,
@@ -11510,11 +11514,11 @@ function BattleBoard({
11510
11514
  className
11511
11515
  }) {
11512
11516
  const board = boardEntity(entity) ?? {};
11513
- const tiles = Array.isArray(board.tiles) ? board.tiles : [];
11514
- const features = Array.isArray(board.features) ? board.features : [];
11517
+ const tiles = propTiles ?? (Array.isArray(board.tiles) ? board.tiles : []);
11518
+ const features = propFeatures ?? (Array.isArray(board.features) ? board.features : []);
11515
11519
  const boardWidth = num(board.boardWidth, 8);
11516
11520
  const boardHeight = num(board.boardHeight, 6);
11517
- const assetManifest = board.assetManifest;
11521
+ const assetManifest = propAssetManifest ?? board.assetManifest;
11518
11522
  const backgroundImage = board.backgroundImage;
11519
11523
  const units = rows(board.units);
11520
11524
  const selectedUnitId = board.selectedUnitId ?? null;
@@ -11606,7 +11610,7 @@ function BattleBoard({
11606
11610
  }, 16);
11607
11611
  return () => clearInterval(interval);
11608
11612
  }, []);
11609
- const isoUnits = useMemo(() => {
11613
+ const derivedIsoUnits = useMemo(() => {
11610
11614
  return units.filter((u) => unitHealth(u) > 0).map((unit) => {
11611
11615
  const id = str(unit.id);
11612
11616
  const pos = movingPositions.get(id) ?? unitPosition(unit);
@@ -11630,6 +11634,7 @@ function BattleBoard({
11630
11634
  };
11631
11635
  });
11632
11636
  }, [units, movingPositions]);
11637
+ const isoUnits = propUnits ?? derivedIsoUnits;
11633
11638
  const maxY = Math.max(...tiles.map((t2) => t2.y), 0);
11634
11639
  const baseOffsetX = (maxY + 1) * (TILE_WIDTH * scale / 2);
11635
11640
  const tileToScreen = useCallback(
@@ -11851,14 +11856,22 @@ function BattleTemplate({
11851
11856
  entity,
11852
11857
  scale = 0.45,
11853
11858
  unitScale = 1,
11859
+ tiles,
11860
+ units,
11861
+ features,
11862
+ assetManifest,
11854
11863
  className
11855
11864
  }) {
11856
11865
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
11857
- if (!resolved) return null;
11866
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
11858
11867
  return /* @__PURE__ */ jsx(
11859
11868
  BattleBoard,
11860
11869
  {
11861
11870
  entity: resolved,
11871
+ tiles,
11872
+ units,
11873
+ features,
11874
+ assetManifest,
11862
11875
  scale,
11863
11876
  unitScale,
11864
11877
  tileClickEvent: "TILE_CLICK",
@@ -18833,16 +18846,21 @@ function EmojiEffect({
18833
18846
  }
18834
18847
  );
18835
18848
  }
18836
- function CanvasEffect(props) {
18849
+ function CanvasEffect({
18850
+ effectSpriteUrl = "https://almadar-kflow-assets.web.app/shared/effects/gas/gas00.png",
18851
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/effects/",
18852
+ ...props
18853
+ }) {
18837
18854
  const eventBus = useEventBus();
18838
- const { completeEvent, onComplete, ...rest } = props;
18855
+ const mergedProps = { effectSpriteUrl, assetBaseUrl, ...props };
18856
+ const { completeEvent, onComplete, ...rest } = mergedProps;
18839
18857
  const handleComplete = useCallback(() => {
18840
18858
  if (completeEvent) eventBus.emit(`UI:${completeEvent}`, {});
18841
18859
  onComplete?.();
18842
18860
  }, [completeEvent, eventBus, onComplete]);
18843
18861
  const enhancedProps = { ...rest, onComplete: handleComplete };
18844
- if (props.assetManifest) {
18845
- return /* @__PURE__ */ jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: props.assetManifest });
18862
+ if (rest.assetManifest) {
18863
+ return /* @__PURE__ */ jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: rest.assetManifest });
18846
18864
  }
18847
18865
  return /* @__PURE__ */ jsx(EmojiEffect, { ...enhancedProps });
18848
18866
  }
@@ -19627,6 +19645,10 @@ var init_CaseStudyOrganism = __esm({
19627
19645
  });
19628
19646
  function CastleBoard({
19629
19647
  entity,
19648
+ tiles: propTiles,
19649
+ units: propUnits,
19650
+ features: propFeatures,
19651
+ assetManifest: propAssetManifest,
19630
19652
  scale = 0.45,
19631
19653
  header,
19632
19654
  sidePanel,
@@ -19642,10 +19664,10 @@ function CastleBoard({
19642
19664
  }) {
19643
19665
  const eventBus = useEventBus();
19644
19666
  const resolved = boardEntity(entity);
19645
- const tiles = Array.isArray(resolved?.tiles) ? resolved.tiles : [];
19646
- const features = Array.isArray(resolved?.features) ? resolved.features : [];
19647
- const units = Array.isArray(resolved?.units) ? resolved.units : [];
19648
- const assetManifest = resolved?.assetManifest;
19667
+ const tiles = propTiles ?? (Array.isArray(resolved?.tiles) ? resolved.tiles : []);
19668
+ const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
19669
+ const units = propUnits ?? (Array.isArray(resolved?.units) ? resolved.units : []);
19670
+ const assetManifest = propAssetManifest ?? resolved?.assetManifest;
19649
19671
  const backgroundImage = resolved?.backgroundImage;
19650
19672
  const [hoveredTile, setHoveredTile] = useState(null);
19651
19673
  const [selectedFeature, setSelectedFeature] = useState(null);
@@ -19748,14 +19770,22 @@ var init_CastleBoard = __esm({
19748
19770
  function CastleTemplate({
19749
19771
  entity,
19750
19772
  scale = 0.45,
19773
+ tiles,
19774
+ units,
19775
+ features,
19776
+ assetManifest,
19751
19777
  className
19752
19778
  }) {
19753
19779
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
19754
- if (!resolved) return null;
19780
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
19755
19781
  return /* @__PURE__ */ jsx(
19756
19782
  CastleBoard,
19757
19783
  {
19758
19784
  entity: resolved,
19785
+ tiles,
19786
+ units,
19787
+ features,
19788
+ assetManifest,
19759
19789
  scale,
19760
19790
  featureClickEvent: "FEATURE_CLICK",
19761
19791
  unitClickEvent: "UNIT_CLICK",
@@ -26388,8 +26418,8 @@ function GameCanvas2D({
26388
26418
  tickEvent,
26389
26419
  drawEvent,
26390
26420
  fps = 60,
26391
- backgroundImage,
26392
- assetBaseUrl = "",
26421
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/resonators.jpeg",
26422
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/",
26393
26423
  className
26394
26424
  }) {
26395
26425
  const canvasRef = React80.useRef(null);
@@ -26453,6 +26483,9 @@ function GameCanvas2D({
26453
26483
  const bgImg = loadImage(backgroundImageRef.current);
26454
26484
  if (bgImg) {
26455
26485
  ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
26486
+ } else {
26487
+ ctx.fillStyle = "#0f1420";
26488
+ ctx.fillRect(0, 0, widthRef.current, heightRef.current);
26456
26489
  }
26457
26490
  }
26458
26491
  onDrawRef.current?.(ctx, frame);
@@ -27597,10 +27630,10 @@ function PlatformerCanvas({
27597
27630
  canvasHeight = 400,
27598
27631
  followCamera = true,
27599
27632
  bgColor,
27600
- playerSprite,
27633
+ playerSprite = "https://almadar-kflow-assets.web.app/shared/platformer/characters/platformChar_idle.png",
27601
27634
  tileSprites,
27602
- backgroundImage,
27603
- assetBaseUrl = "",
27635
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/court.png",
27636
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/platformer/",
27604
27637
  leftEvent = "MOVE_LEFT",
27605
27638
  rightEvent = "MOVE_RIGHT",
27606
27639
  jumpEvent = "JUMP",
@@ -45808,7 +45841,14 @@ var init_useBattleState = __esm({
45808
45841
  init_boardEntity();
45809
45842
  }
45810
45843
  });
45811
- function UncontrolledBattleBoard({ entity, ...rest }) {
45844
+ function UncontrolledBattleBoard({
45845
+ entity,
45846
+ tiles,
45847
+ units,
45848
+ features,
45849
+ assetManifest,
45850
+ ...rest
45851
+ }) {
45812
45852
  const resolved = boardEntity(entity);
45813
45853
  const battleState = useBattleState(
45814
45854
  rows(resolved?.initialUnits),
@@ -45828,19 +45868,23 @@ function UncontrolledBattleBoard({ entity, ...rest }) {
45828
45868
  calculateDamage: rest.calculateDamage
45829
45869
  }
45830
45870
  );
45831
- if (!resolved) return null;
45871
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
45832
45872
  return /* @__PURE__ */ jsx(
45833
45873
  BattleBoard,
45834
45874
  {
45835
45875
  ...rest,
45836
- entity: {
45876
+ tiles,
45877
+ units,
45878
+ features,
45879
+ assetManifest,
45880
+ entity: resolved ? {
45837
45881
  ...resolved,
45838
45882
  units: battleState.units,
45839
45883
  phase: battleState.phase,
45840
45884
  turn: battleState.turn,
45841
45885
  gameResult: battleState.gameResult,
45842
45886
  selectedUnitId: battleState.selectedUnitId
45843
- }
45887
+ } : void 0
45844
45888
  }
45845
45889
  );
45846
45890
  }
@@ -45869,6 +45913,10 @@ function defaultIsInRange(from, to, range) {
45869
45913
  }
45870
45914
  function WorldMapBoard({
45871
45915
  entity,
45916
+ tiles: propTiles,
45917
+ units: propUnits,
45918
+ features: propFeatures,
45919
+ assetManifest: propAssetManifest,
45872
45920
  isLoading,
45873
45921
  scale = 0.4,
45874
45922
  unitScale = 2.5,
@@ -45897,16 +45945,16 @@ function WorldMapBoard({
45897
45945
  const resolved = boardEntity(entity);
45898
45946
  const hexes = rows(resolved?.hexes);
45899
45947
  const heroes = rows(resolved?.heroes);
45900
- const features = Array.isArray(resolved?.features) ? resolved.features : [];
45948
+ const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
45901
45949
  const selectedHeroId = resolved?.selectedHeroId ?? null;
45902
- const assetManifest = resolved?.assetManifest;
45950
+ const assetManifest = propAssetManifest ?? resolved?.assetManifest;
45903
45951
  const backgroundImage = resolved?.backgroundImage;
45904
45952
  const [hoveredTile, setHoveredTile] = useState(null);
45905
45953
  const selectedHero = useMemo(
45906
45954
  () => heroes.find((h) => str(h.id) === selectedHeroId) ?? null,
45907
45955
  [heroes, selectedHeroId]
45908
45956
  );
45909
- const tiles = useMemo(
45957
+ const derivedTiles = useMemo(
45910
45958
  () => hexes.map((hex) => ({
45911
45959
  x: num(hex.x),
45912
45960
  y: num(hex.y),
@@ -45915,8 +45963,9 @@ function WorldMapBoard({
45915
45963
  })),
45916
45964
  [hexes]
45917
45965
  );
45966
+ const tiles = propTiles ?? derivedTiles;
45918
45967
  const baseUnits = useMemo(
45919
- () => heroes.map((hero) => ({
45968
+ () => propUnits ?? heroes.map((hero) => ({
45920
45969
  id: str(hero.id),
45921
45970
  position: heroPosition(hero),
45922
45971
  name: str(hero.name),
@@ -45925,7 +45974,7 @@ function WorldMapBoard({
45925
45974
  maxHealth: 100,
45926
45975
  sprite: hero.sprite == null ? void 0 : str(hero.sprite)
45927
45976
  })),
45928
- [heroes]
45977
+ [heroes, propUnits]
45929
45978
  );
45930
45979
  const MOVE_SPEED_MS_PER_TILE = 300;
45931
45980
  const movementAnimRef = useRef(null);
@@ -46135,12 +46184,20 @@ function WorldMapTemplate({
46135
46184
  unitScale = 2.5,
46136
46185
  diamondTopY,
46137
46186
  allowMoveAllHeroes = false,
46187
+ tiles,
46188
+ units,
46189
+ features,
46190
+ assetManifest,
46138
46191
  className
46139
46192
  }) {
46140
46193
  return /* @__PURE__ */ jsx(
46141
46194
  WorldMapBoard,
46142
46195
  {
46143
46196
  entity,
46197
+ tiles,
46198
+ units,
46199
+ features,
46200
+ assetManifest,
46144
46201
  scale,
46145
46202
  unitScale,
46146
46203
  diamondTopY,
@@ -47358,6 +47415,24 @@ function renderPatternProps(props, onDismiss) {
47358
47415
  priority: 0
47359
47416
  };
47360
47417
  rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
47418
+ } else if (Array.isArray(value)) {
47419
+ rendered[key] = value.map((item, i) => {
47420
+ const el = item;
47421
+ if (isPatternConfig(el)) {
47422
+ const nestedProps = {};
47423
+ for (const [k, v] of Object.entries(el)) {
47424
+ if (k !== "type") nestedProps[k] = v;
47425
+ }
47426
+ const childContent = {
47427
+ id: `prop-${key}-${i}`,
47428
+ pattern: el.type,
47429
+ props: nestedProps,
47430
+ priority: 0
47431
+ };
47432
+ return /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss }, i);
47433
+ }
47434
+ return substituteTraitRefsDeep(el, `prop:${key}[${i}]`);
47435
+ });
47361
47436
  } else {
47362
47437
  rendered[key] = substituteTraitRefsDeep(value, `prop:${key}`);
47363
47438
  }
@@ -7717,7 +7717,7 @@ var init_DamageNumber = __esm({
7717
7717
  function DialogueBubble({
7718
7718
  speaker,
7719
7719
  text,
7720
- portrait = "https://almadar-kflow-assets.web.app/shared/characters/archetypes/00_base_model.png",
7720
+ portrait = "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
7721
7721
  position = "bottom",
7722
7722
  className
7723
7723
  }) {
@@ -10327,7 +10327,7 @@ function IsometricCanvas({
10327
10327
  // Rendering options
10328
10328
  scale = 0.4,
10329
10329
  debug: debug2 = false,
10330
- backgroundImage,
10330
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/court.png",
10331
10331
  showMinimap = true,
10332
10332
  enableCamera = true,
10333
10333
  unitScale = 1,
@@ -10342,7 +10342,7 @@ function IsometricCanvas({
10342
10342
  // Tuning
10343
10343
  diamondTopY: diamondTopYProp,
10344
10344
  // Remote asset loading
10345
- assetBaseUrl,
10345
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/",
10346
10346
  assetManifest
10347
10347
  }) {
10348
10348
  const tilesProp = Array.isArray(_tilesPropRaw) ? _tilesPropRaw : [];
@@ -11101,6 +11101,10 @@ var init_boardEntity = __esm({
11101
11101
  });
11102
11102
  function BattleBoard({
11103
11103
  entity,
11104
+ tiles: propTiles,
11105
+ units: propUnits,
11106
+ features: propFeatures,
11107
+ assetManifest: propAssetManifest,
11104
11108
  scale = 0.45,
11105
11109
  unitScale = 1,
11106
11110
  header,
@@ -11126,11 +11130,11 @@ function BattleBoard({
11126
11130
  className
11127
11131
  }) {
11128
11132
  const board = boardEntity(entity) ?? {};
11129
- const tiles = Array.isArray(board.tiles) ? board.tiles : [];
11130
- const features = Array.isArray(board.features) ? board.features : [];
11133
+ const tiles = propTiles ?? (Array.isArray(board.tiles) ? board.tiles : []);
11134
+ const features = propFeatures ?? (Array.isArray(board.features) ? board.features : []);
11131
11135
  const boardWidth = num(board.boardWidth, 8);
11132
11136
  const boardHeight = num(board.boardHeight, 6);
11133
- const assetManifest = board.assetManifest;
11137
+ const assetManifest = propAssetManifest ?? board.assetManifest;
11134
11138
  const backgroundImage = board.backgroundImage;
11135
11139
  const units = rows(board.units);
11136
11140
  const selectedUnitId = board.selectedUnitId ?? null;
@@ -11222,7 +11226,7 @@ function BattleBoard({
11222
11226
  }, 16);
11223
11227
  return () => clearInterval(interval);
11224
11228
  }, []);
11225
- const isoUnits = React79.useMemo(() => {
11229
+ const derivedIsoUnits = React79.useMemo(() => {
11226
11230
  return units.filter((u) => unitHealth(u) > 0).map((unit) => {
11227
11231
  const id = str(unit.id);
11228
11232
  const pos = movingPositions.get(id) ?? unitPosition(unit);
@@ -11246,6 +11250,7 @@ function BattleBoard({
11246
11250
  };
11247
11251
  });
11248
11252
  }, [units, movingPositions]);
11253
+ const isoUnits = propUnits ?? derivedIsoUnits;
11249
11254
  const maxY = Math.max(...tiles.map((t2) => t2.y), 0);
11250
11255
  const baseOffsetX = (maxY + 1) * (TILE_WIDTH * scale / 2);
11251
11256
  const tileToScreen = React79.useCallback(
@@ -11467,14 +11472,22 @@ function BattleTemplate({
11467
11472
  entity,
11468
11473
  scale = 0.45,
11469
11474
  unitScale = 1,
11475
+ tiles,
11476
+ units,
11477
+ features,
11478
+ assetManifest,
11470
11479
  className
11471
11480
  }) {
11472
11481
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
11473
- if (!resolved) return null;
11482
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
11474
11483
  return /* @__PURE__ */ jsxRuntime.jsx(
11475
11484
  BattleBoard,
11476
11485
  {
11477
11486
  entity: resolved,
11487
+ tiles,
11488
+ units,
11489
+ features,
11490
+ assetManifest,
11478
11491
  scale,
11479
11492
  unitScale,
11480
11493
  tileClickEvent: "TILE_CLICK",
@@ -18449,16 +18462,21 @@ function EmojiEffect({
18449
18462
  }
18450
18463
  );
18451
18464
  }
18452
- function CanvasEffect(props) {
18465
+ function CanvasEffect({
18466
+ effectSpriteUrl = "https://almadar-kflow-assets.web.app/shared/effects/gas/gas00.png",
18467
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/effects/",
18468
+ ...props
18469
+ }) {
18453
18470
  const eventBus = useEventBus();
18454
- const { completeEvent, onComplete, ...rest } = props;
18471
+ const mergedProps = { effectSpriteUrl, assetBaseUrl, ...props };
18472
+ const { completeEvent, onComplete, ...rest } = mergedProps;
18455
18473
  const handleComplete = React79.useCallback(() => {
18456
18474
  if (completeEvent) eventBus.emit(`UI:${completeEvent}`, {});
18457
18475
  onComplete?.();
18458
18476
  }, [completeEvent, eventBus, onComplete]);
18459
18477
  const enhancedProps = { ...rest, onComplete: handleComplete };
18460
- if (props.assetManifest) {
18461
- return /* @__PURE__ */ jsxRuntime.jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: props.assetManifest });
18478
+ if (rest.assetManifest) {
18479
+ return /* @__PURE__ */ jsxRuntime.jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: rest.assetManifest });
18462
18480
  }
18463
18481
  return /* @__PURE__ */ jsxRuntime.jsx(EmojiEffect, { ...enhancedProps });
18464
18482
  }
@@ -19243,6 +19261,10 @@ var init_CaseStudyOrganism = __esm({
19243
19261
  });
19244
19262
  function CastleBoard({
19245
19263
  entity,
19264
+ tiles: propTiles,
19265
+ units: propUnits,
19266
+ features: propFeatures,
19267
+ assetManifest: propAssetManifest,
19246
19268
  scale = 0.45,
19247
19269
  header,
19248
19270
  sidePanel,
@@ -19258,10 +19280,10 @@ function CastleBoard({
19258
19280
  }) {
19259
19281
  const eventBus = useEventBus();
19260
19282
  const resolved = boardEntity(entity);
19261
- const tiles = Array.isArray(resolved?.tiles) ? resolved.tiles : [];
19262
- const features = Array.isArray(resolved?.features) ? resolved.features : [];
19263
- const units = Array.isArray(resolved?.units) ? resolved.units : [];
19264
- const assetManifest = resolved?.assetManifest;
19283
+ const tiles = propTiles ?? (Array.isArray(resolved?.tiles) ? resolved.tiles : []);
19284
+ const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
19285
+ const units = propUnits ?? (Array.isArray(resolved?.units) ? resolved.units : []);
19286
+ const assetManifest = propAssetManifest ?? resolved?.assetManifest;
19265
19287
  const backgroundImage = resolved?.backgroundImage;
19266
19288
  const [hoveredTile, setHoveredTile] = React79.useState(null);
19267
19289
  const [selectedFeature, setSelectedFeature] = React79.useState(null);
@@ -19364,14 +19386,22 @@ var init_CastleBoard = __esm({
19364
19386
  function CastleTemplate({
19365
19387
  entity,
19366
19388
  scale = 0.45,
19389
+ tiles,
19390
+ units,
19391
+ features,
19392
+ assetManifest,
19367
19393
  className
19368
19394
  }) {
19369
19395
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
19370
- if (!resolved) return null;
19396
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
19371
19397
  return /* @__PURE__ */ jsxRuntime.jsx(
19372
19398
  CastleBoard,
19373
19399
  {
19374
19400
  entity: resolved,
19401
+ tiles,
19402
+ units,
19403
+ features,
19404
+ assetManifest,
19375
19405
  scale,
19376
19406
  featureClickEvent: "FEATURE_CLICK",
19377
19407
  unitClickEvent: "UNIT_CLICK",
@@ -26004,8 +26034,8 @@ function GameCanvas2D({
26004
26034
  tickEvent,
26005
26035
  drawEvent,
26006
26036
  fps = 60,
26007
- backgroundImage,
26008
- assetBaseUrl = "",
26037
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/resonators.jpeg",
26038
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/",
26009
26039
  className
26010
26040
  }) {
26011
26041
  const canvasRef = React79__namespace.useRef(null);
@@ -26069,6 +26099,9 @@ function GameCanvas2D({
26069
26099
  const bgImg = loadImage(backgroundImageRef.current);
26070
26100
  if (bgImg) {
26071
26101
  ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
26102
+ } else {
26103
+ ctx.fillStyle = "#0f1420";
26104
+ ctx.fillRect(0, 0, widthRef.current, heightRef.current);
26072
26105
  }
26073
26106
  }
26074
26107
  onDrawRef.current?.(ctx, frame);
@@ -27213,10 +27246,10 @@ function PlatformerCanvas({
27213
27246
  canvasHeight = 400,
27214
27247
  followCamera = true,
27215
27248
  bgColor,
27216
- playerSprite,
27249
+ playerSprite = "https://almadar-kflow-assets.web.app/shared/platformer/characters/platformChar_idle.png",
27217
27250
  tileSprites,
27218
- backgroundImage,
27219
- assetBaseUrl = "",
27251
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/court.png",
27252
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/platformer/",
27220
27253
  leftEvent = "MOVE_LEFT",
27221
27254
  rightEvent = "MOVE_RIGHT",
27222
27255
  jumpEvent = "JUMP",
@@ -45443,7 +45476,14 @@ var init_useBattleState = __esm({
45443
45476
  init_boardEntity();
45444
45477
  }
45445
45478
  });
45446
- function UncontrolledBattleBoard({ entity, ...rest }) {
45479
+ function UncontrolledBattleBoard({
45480
+ entity,
45481
+ tiles,
45482
+ units,
45483
+ features,
45484
+ assetManifest,
45485
+ ...rest
45486
+ }) {
45447
45487
  const resolved = boardEntity(entity);
45448
45488
  const battleState = useBattleState(
45449
45489
  rows(resolved?.initialUnits),
@@ -45463,19 +45503,23 @@ function UncontrolledBattleBoard({ entity, ...rest }) {
45463
45503
  calculateDamage: rest.calculateDamage
45464
45504
  }
45465
45505
  );
45466
- if (!resolved) return null;
45506
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
45467
45507
  return /* @__PURE__ */ jsxRuntime.jsx(
45468
45508
  BattleBoard,
45469
45509
  {
45470
45510
  ...rest,
45471
- entity: {
45511
+ tiles,
45512
+ units,
45513
+ features,
45514
+ assetManifest,
45515
+ entity: resolved ? {
45472
45516
  ...resolved,
45473
45517
  units: battleState.units,
45474
45518
  phase: battleState.phase,
45475
45519
  turn: battleState.turn,
45476
45520
  gameResult: battleState.gameResult,
45477
45521
  selectedUnitId: battleState.selectedUnitId
45478
- }
45522
+ } : void 0
45479
45523
  }
45480
45524
  );
45481
45525
  }
@@ -45504,6 +45548,10 @@ function defaultIsInRange(from, to, range) {
45504
45548
  }
45505
45549
  function WorldMapBoard({
45506
45550
  entity,
45551
+ tiles: propTiles,
45552
+ units: propUnits,
45553
+ features: propFeatures,
45554
+ assetManifest: propAssetManifest,
45507
45555
  isLoading,
45508
45556
  scale = 0.4,
45509
45557
  unitScale = 2.5,
@@ -45532,16 +45580,16 @@ function WorldMapBoard({
45532
45580
  const resolved = boardEntity(entity);
45533
45581
  const hexes = rows(resolved?.hexes);
45534
45582
  const heroes = rows(resolved?.heroes);
45535
- const features = Array.isArray(resolved?.features) ? resolved.features : [];
45583
+ const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
45536
45584
  const selectedHeroId = resolved?.selectedHeroId ?? null;
45537
- const assetManifest = resolved?.assetManifest;
45585
+ const assetManifest = propAssetManifest ?? resolved?.assetManifest;
45538
45586
  const backgroundImage = resolved?.backgroundImage;
45539
45587
  const [hoveredTile, setHoveredTile] = React79.useState(null);
45540
45588
  const selectedHero = React79.useMemo(
45541
45589
  () => heroes.find((h) => str(h.id) === selectedHeroId) ?? null,
45542
45590
  [heroes, selectedHeroId]
45543
45591
  );
45544
- const tiles = React79.useMemo(
45592
+ const derivedTiles = React79.useMemo(
45545
45593
  () => hexes.map((hex) => ({
45546
45594
  x: num(hex.x),
45547
45595
  y: num(hex.y),
@@ -45550,8 +45598,9 @@ function WorldMapBoard({
45550
45598
  })),
45551
45599
  [hexes]
45552
45600
  );
45601
+ const tiles = propTiles ?? derivedTiles;
45553
45602
  const baseUnits = React79.useMemo(
45554
- () => heroes.map((hero) => ({
45603
+ () => propUnits ?? heroes.map((hero) => ({
45555
45604
  id: str(hero.id),
45556
45605
  position: heroPosition(hero),
45557
45606
  name: str(hero.name),
@@ -45560,7 +45609,7 @@ function WorldMapBoard({
45560
45609
  maxHealth: 100,
45561
45610
  sprite: hero.sprite == null ? void 0 : str(hero.sprite)
45562
45611
  })),
45563
- [heroes]
45612
+ [heroes, propUnits]
45564
45613
  );
45565
45614
  const MOVE_SPEED_MS_PER_TILE = 300;
45566
45615
  const movementAnimRef = React79.useRef(null);
@@ -45770,12 +45819,20 @@ function WorldMapTemplate({
45770
45819
  unitScale = 2.5,
45771
45820
  diamondTopY,
45772
45821
  allowMoveAllHeroes = false,
45822
+ tiles,
45823
+ units,
45824
+ features,
45825
+ assetManifest,
45773
45826
  className
45774
45827
  }) {
45775
45828
  return /* @__PURE__ */ jsxRuntime.jsx(
45776
45829
  WorldMapBoard,
45777
45830
  {
45778
45831
  entity,
45832
+ tiles,
45833
+ units,
45834
+ features,
45835
+ assetManifest,
45779
45836
  scale,
45780
45837
  unitScale,
45781
45838
  diamondTopY,
@@ -46993,6 +47050,24 @@ function renderPatternProps(props, onDismiss) {
46993
47050
  priority: 0
46994
47051
  };
46995
47052
  rendered[key] = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss });
47053
+ } else if (Array.isArray(value)) {
47054
+ rendered[key] = value.map((item, i) => {
47055
+ const el = item;
47056
+ if (isPatternConfig(el)) {
47057
+ const nestedProps = {};
47058
+ for (const [k, v] of Object.entries(el)) {
47059
+ if (k !== "type") nestedProps[k] = v;
47060
+ }
47061
+ const childContent = {
47062
+ id: `prop-${key}-${i}`,
47063
+ pattern: el.type,
47064
+ props: nestedProps,
47065
+ priority: 0
47066
+ };
47067
+ return /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss }, i);
47068
+ }
47069
+ return substituteTraitRefsDeep(el, `prop:${key}[${i}]`);
47070
+ });
46996
47071
  } else {
46997
47072
  rendered[key] = substituteTraitRefsDeep(value, `prop:${key}`);
46998
47073
  }