@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.
@@ -9254,7 +9254,7 @@ function IsometricCanvas({
9254
9254
  // Rendering options
9255
9255
  scale = 0.4,
9256
9256
  debug: debug2 = false,
9257
- backgroundImage,
9257
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/court.png",
9258
9258
  showMinimap = true,
9259
9259
  enableCamera = true,
9260
9260
  unitScale = 1,
@@ -9269,7 +9269,7 @@ function IsometricCanvas({
9269
9269
  // Tuning
9270
9270
  diamondTopY: diamondTopYProp,
9271
9271
  // Remote asset loading
9272
- assetBaseUrl,
9272
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/",
9273
9273
  assetManifest
9274
9274
  }) {
9275
9275
  const tilesProp = Array.isArray(_tilesPropRaw) ? _tilesPropRaw : [];
@@ -10029,6 +10029,10 @@ var init_boardEntity = __esm({
10029
10029
  });
10030
10030
  function BattleBoard({
10031
10031
  entity,
10032
+ tiles: propTiles,
10033
+ units: propUnits,
10034
+ features: propFeatures,
10035
+ assetManifest: propAssetManifest,
10032
10036
  scale = 0.45,
10033
10037
  unitScale = 1,
10034
10038
  header,
@@ -10054,11 +10058,11 @@ function BattleBoard({
10054
10058
  className
10055
10059
  }) {
10056
10060
  const board = boardEntity(entity) ?? {};
10057
- const tiles = Array.isArray(board.tiles) ? board.tiles : [];
10058
- const features = Array.isArray(board.features) ? board.features : [];
10061
+ const tiles = propTiles ?? (Array.isArray(board.tiles) ? board.tiles : []);
10062
+ const features = propFeatures ?? (Array.isArray(board.features) ? board.features : []);
10059
10063
  const boardWidth = num(board.boardWidth, 8);
10060
10064
  const boardHeight = num(board.boardHeight, 6);
10061
- const assetManifest = board.assetManifest;
10065
+ const assetManifest = propAssetManifest ?? board.assetManifest;
10062
10066
  const backgroundImage = board.backgroundImage;
10063
10067
  const units = rows(board.units);
10064
10068
  const selectedUnitId = board.selectedUnitId ?? null;
@@ -10150,7 +10154,7 @@ function BattleBoard({
10150
10154
  }, 16);
10151
10155
  return () => clearInterval(interval);
10152
10156
  }, []);
10153
- const isoUnits = useMemo(() => {
10157
+ const derivedIsoUnits = useMemo(() => {
10154
10158
  return units.filter((u) => unitHealth(u) > 0).map((unit) => {
10155
10159
  const id = str(unit.id);
10156
10160
  const pos = movingPositions.get(id) ?? unitPosition(unit);
@@ -10174,6 +10178,7 @@ function BattleBoard({
10174
10178
  };
10175
10179
  });
10176
10180
  }, [units, movingPositions]);
10181
+ const isoUnits = propUnits ?? derivedIsoUnits;
10177
10182
  const maxY = Math.max(...tiles.map((t2) => t2.y), 0);
10178
10183
  const baseOffsetX = (maxY + 1) * (TILE_WIDTH * scale / 2);
10179
10184
  const tileToScreen = useCallback(
@@ -10395,14 +10400,22 @@ function BattleTemplate({
10395
10400
  entity,
10396
10401
  scale = 0.45,
10397
10402
  unitScale = 1,
10403
+ tiles,
10404
+ units,
10405
+ features,
10406
+ assetManifest,
10398
10407
  className
10399
10408
  }) {
10400
10409
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
10401
- if (!resolved) return null;
10410
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
10402
10411
  return /* @__PURE__ */ jsx(
10403
10412
  BattleBoard,
10404
10413
  {
10405
10414
  entity: resolved,
10415
+ tiles,
10416
+ units,
10417
+ features,
10418
+ assetManifest,
10406
10419
  scale,
10407
10420
  unitScale,
10408
10421
  tileClickEvent: "TILE_CLICK",
@@ -17377,16 +17390,21 @@ function EmojiEffect({
17377
17390
  }
17378
17391
  );
17379
17392
  }
17380
- function CanvasEffect(props) {
17393
+ function CanvasEffect({
17394
+ effectSpriteUrl = "https://almadar-kflow-assets.web.app/shared/effects/gas/gas00.png",
17395
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/effects/",
17396
+ ...props
17397
+ }) {
17381
17398
  const eventBus = useEventBus();
17382
- const { completeEvent, onComplete, ...rest } = props;
17399
+ const mergedProps = { effectSpriteUrl, assetBaseUrl, ...props };
17400
+ const { completeEvent, onComplete, ...rest } = mergedProps;
17383
17401
  const handleComplete = useCallback(() => {
17384
17402
  if (completeEvent) eventBus.emit(`UI:${completeEvent}`, {});
17385
17403
  onComplete?.();
17386
17404
  }, [completeEvent, eventBus, onComplete]);
17387
17405
  const enhancedProps = { ...rest, onComplete: handleComplete };
17388
- if (props.assetManifest) {
17389
- return /* @__PURE__ */ jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: props.assetManifest });
17406
+ if (rest.assetManifest) {
17407
+ return /* @__PURE__ */ jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: rest.assetManifest });
17390
17408
  }
17391
17409
  return /* @__PURE__ */ jsx(EmojiEffect, { ...enhancedProps });
17392
17410
  }
@@ -18171,6 +18189,10 @@ var init_CaseStudyOrganism = __esm({
18171
18189
  });
18172
18190
  function CastleBoard({
18173
18191
  entity,
18192
+ tiles: propTiles,
18193
+ units: propUnits,
18194
+ features: propFeatures,
18195
+ assetManifest: propAssetManifest,
18174
18196
  scale = 0.45,
18175
18197
  header,
18176
18198
  sidePanel,
@@ -18186,10 +18208,10 @@ function CastleBoard({
18186
18208
  }) {
18187
18209
  const eventBus = useEventBus();
18188
18210
  const resolved = boardEntity(entity);
18189
- const tiles = Array.isArray(resolved?.tiles) ? resolved.tiles : [];
18190
- const features = Array.isArray(resolved?.features) ? resolved.features : [];
18191
- const units = Array.isArray(resolved?.units) ? resolved.units : [];
18192
- const assetManifest = resolved?.assetManifest;
18211
+ const tiles = propTiles ?? (Array.isArray(resolved?.tiles) ? resolved.tiles : []);
18212
+ const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
18213
+ const units = propUnits ?? (Array.isArray(resolved?.units) ? resolved.units : []);
18214
+ const assetManifest = propAssetManifest ?? resolved?.assetManifest;
18193
18215
  const backgroundImage = resolved?.backgroundImage;
18194
18216
  const [hoveredTile, setHoveredTile] = useState(null);
18195
18217
  const [selectedFeature, setSelectedFeature] = useState(null);
@@ -18292,14 +18314,22 @@ var init_CastleBoard = __esm({
18292
18314
  function CastleTemplate({
18293
18315
  entity,
18294
18316
  scale = 0.45,
18317
+ tiles,
18318
+ units,
18319
+ features,
18320
+ assetManifest,
18295
18321
  className
18296
18322
  }) {
18297
18323
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
18298
- if (!resolved) return null;
18324
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
18299
18325
  return /* @__PURE__ */ jsx(
18300
18326
  CastleBoard,
18301
18327
  {
18302
18328
  entity: resolved,
18329
+ tiles,
18330
+ units,
18331
+ features,
18332
+ assetManifest,
18303
18333
  scale,
18304
18334
  featureClickEvent: "FEATURE_CLICK",
18305
18335
  unitClickEvent: "UNIT_CLICK",
@@ -26186,8 +26216,8 @@ function GameCanvas2D({
26186
26216
  tickEvent,
26187
26217
  drawEvent,
26188
26218
  fps = 60,
26189
- backgroundImage,
26190
- assetBaseUrl = "",
26219
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/resonators.jpeg",
26220
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/",
26191
26221
  className
26192
26222
  }) {
26193
26223
  const canvasRef = React74.useRef(null);
@@ -26251,6 +26281,9 @@ function GameCanvas2D({
26251
26281
  const bgImg = loadImage(backgroundImageRef.current);
26252
26282
  if (bgImg) {
26253
26283
  ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
26284
+ } else {
26285
+ ctx.fillStyle = "#0f1420";
26286
+ ctx.fillRect(0, 0, widthRef.current, heightRef.current);
26254
26287
  }
26255
26288
  }
26256
26289
  onDrawRef.current?.(ctx, frame);
@@ -27447,10 +27480,10 @@ function PlatformerCanvas({
27447
27480
  canvasHeight = 400,
27448
27481
  followCamera = true,
27449
27482
  bgColor,
27450
- playerSprite,
27483
+ playerSprite = "https://almadar-kflow-assets.web.app/shared/platformer/characters/platformChar_idle.png",
27451
27484
  tileSprites,
27452
- backgroundImage,
27453
- assetBaseUrl = "",
27485
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/court.png",
27486
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/platformer/",
27454
27487
  leftEvent = "MOVE_LEFT",
27455
27488
  rightEvent = "MOVE_RIGHT",
27456
27489
  jumpEvent = "JUMP",
@@ -38333,7 +38366,7 @@ var init_DetailPanel = __esm({
38333
38366
  function DialogueBubble({
38334
38367
  speaker,
38335
38368
  text,
38336
- portrait = "https://almadar-kflow-assets.web.app/shared/characters/archetypes/00_base_model.png",
38369
+ portrait = "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
38337
38370
  position = "bottom",
38338
38371
  className
38339
38372
  }) {
@@ -46563,7 +46596,14 @@ var init_useBattleState = __esm({
46563
46596
  init_boardEntity();
46564
46597
  }
46565
46598
  });
46566
- function UncontrolledBattleBoard({ entity, ...rest }) {
46599
+ function UncontrolledBattleBoard({
46600
+ entity,
46601
+ tiles,
46602
+ units,
46603
+ features,
46604
+ assetManifest,
46605
+ ...rest
46606
+ }) {
46567
46607
  const resolved = boardEntity(entity);
46568
46608
  const battleState = useBattleState(
46569
46609
  rows(resolved?.initialUnits),
@@ -46583,19 +46623,23 @@ function UncontrolledBattleBoard({ entity, ...rest }) {
46583
46623
  calculateDamage: rest.calculateDamage
46584
46624
  }
46585
46625
  );
46586
- if (!resolved) return null;
46626
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
46587
46627
  return /* @__PURE__ */ jsx(
46588
46628
  BattleBoard,
46589
46629
  {
46590
46630
  ...rest,
46591
- entity: {
46631
+ tiles,
46632
+ units,
46633
+ features,
46634
+ assetManifest,
46635
+ entity: resolved ? {
46592
46636
  ...resolved,
46593
46637
  units: battleState.units,
46594
46638
  phase: battleState.phase,
46595
46639
  turn: battleState.turn,
46596
46640
  gameResult: battleState.gameResult,
46597
46641
  selectedUnitId: battleState.selectedUnitId
46598
- }
46642
+ } : void 0
46599
46643
  }
46600
46644
  );
46601
46645
  }
@@ -46624,6 +46668,10 @@ function defaultIsInRange(from, to, range) {
46624
46668
  }
46625
46669
  function WorldMapBoard({
46626
46670
  entity,
46671
+ tiles: propTiles,
46672
+ units: propUnits,
46673
+ features: propFeatures,
46674
+ assetManifest: propAssetManifest,
46627
46675
  isLoading,
46628
46676
  scale = 0.4,
46629
46677
  unitScale = 2.5,
@@ -46652,16 +46700,16 @@ function WorldMapBoard({
46652
46700
  const resolved = boardEntity(entity);
46653
46701
  const hexes = rows(resolved?.hexes);
46654
46702
  const heroes = rows(resolved?.heroes);
46655
- const features = Array.isArray(resolved?.features) ? resolved.features : [];
46703
+ const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
46656
46704
  const selectedHeroId = resolved?.selectedHeroId ?? null;
46657
- const assetManifest = resolved?.assetManifest;
46705
+ const assetManifest = propAssetManifest ?? resolved?.assetManifest;
46658
46706
  const backgroundImage = resolved?.backgroundImage;
46659
46707
  const [hoveredTile, setHoveredTile] = useState(null);
46660
46708
  const selectedHero = useMemo(
46661
46709
  () => heroes.find((h) => str(h.id) === selectedHeroId) ?? null,
46662
46710
  [heroes, selectedHeroId]
46663
46711
  );
46664
- const tiles = useMemo(
46712
+ const derivedTiles = useMemo(
46665
46713
  () => hexes.map((hex) => ({
46666
46714
  x: num(hex.x),
46667
46715
  y: num(hex.y),
@@ -46670,8 +46718,9 @@ function WorldMapBoard({
46670
46718
  })),
46671
46719
  [hexes]
46672
46720
  );
46721
+ const tiles = propTiles ?? derivedTiles;
46673
46722
  const baseUnits = useMemo(
46674
- () => heroes.map((hero) => ({
46723
+ () => propUnits ?? heroes.map((hero) => ({
46675
46724
  id: str(hero.id),
46676
46725
  position: heroPosition(hero),
46677
46726
  name: str(hero.name),
@@ -46680,7 +46729,7 @@ function WorldMapBoard({
46680
46729
  maxHealth: 100,
46681
46730
  sprite: hero.sprite == null ? void 0 : str(hero.sprite)
46682
46731
  })),
46683
- [heroes]
46732
+ [heroes, propUnits]
46684
46733
  );
46685
46734
  const MOVE_SPEED_MS_PER_TILE = 300;
46686
46735
  const movementAnimRef = useRef(null);
@@ -46890,12 +46939,20 @@ function WorldMapTemplate({
46890
46939
  unitScale = 2.5,
46891
46940
  diamondTopY,
46892
46941
  allowMoveAllHeroes = false,
46942
+ tiles,
46943
+ units,
46944
+ features,
46945
+ assetManifest,
46893
46946
  className
46894
46947
  }) {
46895
46948
  return /* @__PURE__ */ jsx(
46896
46949
  WorldMapBoard,
46897
46950
  {
46898
46951
  entity,
46952
+ tiles,
46953
+ units,
46954
+ features,
46955
+ assetManifest,
46899
46956
  scale,
46900
46957
  unitScale,
46901
46958
  diamondTopY,
@@ -48197,6 +48254,24 @@ function renderPatternProps(props, onDismiss) {
48197
48254
  priority: 0
48198
48255
  };
48199
48256
  rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
48257
+ } else if (Array.isArray(value)) {
48258
+ rendered[key] = value.map((item, i) => {
48259
+ const el = item;
48260
+ if (isPatternConfig(el)) {
48261
+ const nestedProps = {};
48262
+ for (const [k, v] of Object.entries(el)) {
48263
+ if (k !== "type") nestedProps[k] = v;
48264
+ }
48265
+ const childContent = {
48266
+ id: `prop-${key}-${i}`,
48267
+ pattern: el.type,
48268
+ props: nestedProps,
48269
+ priority: 0
48270
+ };
48271
+ return /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss }, i);
48272
+ }
48273
+ return substituteTraitRefsDeep(el, `prop:${key}[${i}]`);
48274
+ });
48200
48275
  } else {
48201
48276
  rendered[key] = substituteTraitRefsDeep(value, `prop:${key}`);
48202
48277
  }
@@ -7806,7 +7806,7 @@ var init_DamageNumber = __esm({
7806
7806
  function DialogueBubble({
7807
7807
  speaker,
7808
7808
  text,
7809
- portrait = "https://almadar-kflow-assets.web.app/shared/characters/archetypes/00_base_model.png",
7809
+ portrait = "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
7810
7810
  position = "bottom",
7811
7811
  className
7812
7812
  }) {
@@ -10760,7 +10760,7 @@ function IsometricCanvas({
10760
10760
  // Rendering options
10761
10761
  scale = 0.4,
10762
10762
  debug: debug2 = false,
10763
- backgroundImage,
10763
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/court.png",
10764
10764
  showMinimap = true,
10765
10765
  enableCamera = true,
10766
10766
  unitScale = 1,
@@ -10775,7 +10775,7 @@ function IsometricCanvas({
10775
10775
  // Tuning
10776
10776
  diamondTopY: diamondTopYProp,
10777
10777
  // Remote asset loading
10778
- assetBaseUrl,
10778
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/",
10779
10779
  assetManifest
10780
10780
  }) {
10781
10781
  const tilesProp = Array.isArray(_tilesPropRaw) ? _tilesPropRaw : [];
@@ -11534,6 +11534,10 @@ var init_boardEntity = __esm({
11534
11534
  });
11535
11535
  function BattleBoard({
11536
11536
  entity,
11537
+ tiles: propTiles,
11538
+ units: propUnits,
11539
+ features: propFeatures,
11540
+ assetManifest: propAssetManifest,
11537
11541
  scale = 0.45,
11538
11542
  unitScale = 1,
11539
11543
  header,
@@ -11559,11 +11563,11 @@ function BattleBoard({
11559
11563
  className
11560
11564
  }) {
11561
11565
  const board = boardEntity(entity) ?? {};
11562
- const tiles = Array.isArray(board.tiles) ? board.tiles : [];
11563
- const features = Array.isArray(board.features) ? board.features : [];
11566
+ const tiles = propTiles ?? (Array.isArray(board.tiles) ? board.tiles : []);
11567
+ const features = propFeatures ?? (Array.isArray(board.features) ? board.features : []);
11564
11568
  const boardWidth = num(board.boardWidth, 8);
11565
11569
  const boardHeight = num(board.boardHeight, 6);
11566
- const assetManifest = board.assetManifest;
11570
+ const assetManifest = propAssetManifest ?? board.assetManifest;
11567
11571
  const backgroundImage = board.backgroundImage;
11568
11572
  const units = rows(board.units);
11569
11573
  const selectedUnitId = board.selectedUnitId ?? null;
@@ -11655,7 +11659,7 @@ function BattleBoard({
11655
11659
  }, 16);
11656
11660
  return () => clearInterval(interval);
11657
11661
  }, []);
11658
- const isoUnits = React80.useMemo(() => {
11662
+ const derivedIsoUnits = React80.useMemo(() => {
11659
11663
  return units.filter((u) => unitHealth(u) > 0).map((unit) => {
11660
11664
  const id = str(unit.id);
11661
11665
  const pos = movingPositions.get(id) ?? unitPosition(unit);
@@ -11679,6 +11683,7 @@ function BattleBoard({
11679
11683
  };
11680
11684
  });
11681
11685
  }, [units, movingPositions]);
11686
+ const isoUnits = propUnits ?? derivedIsoUnits;
11682
11687
  const maxY = Math.max(...tiles.map((t2) => t2.y), 0);
11683
11688
  const baseOffsetX = (maxY + 1) * (TILE_WIDTH * scale / 2);
11684
11689
  const tileToScreen = React80.useCallback(
@@ -11900,14 +11905,22 @@ function BattleTemplate({
11900
11905
  entity,
11901
11906
  scale = 0.45,
11902
11907
  unitScale = 1,
11908
+ tiles,
11909
+ units,
11910
+ features,
11911
+ assetManifest,
11903
11912
  className
11904
11913
  }) {
11905
11914
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
11906
- if (!resolved) return null;
11915
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
11907
11916
  return /* @__PURE__ */ jsxRuntime.jsx(
11908
11917
  BattleBoard,
11909
11918
  {
11910
11919
  entity: resolved,
11920
+ tiles,
11921
+ units,
11922
+ features,
11923
+ assetManifest,
11911
11924
  scale,
11912
11925
  unitScale,
11913
11926
  tileClickEvent: "TILE_CLICK",
@@ -18882,16 +18895,21 @@ function EmojiEffect({
18882
18895
  }
18883
18896
  );
18884
18897
  }
18885
- function CanvasEffect(props) {
18898
+ function CanvasEffect({
18899
+ effectSpriteUrl = "https://almadar-kflow-assets.web.app/shared/effects/gas/gas00.png",
18900
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/effects/",
18901
+ ...props
18902
+ }) {
18886
18903
  const eventBus = useEventBus();
18887
- const { completeEvent, onComplete, ...rest } = props;
18904
+ const mergedProps = { effectSpriteUrl, assetBaseUrl, ...props };
18905
+ const { completeEvent, onComplete, ...rest } = mergedProps;
18888
18906
  const handleComplete = React80.useCallback(() => {
18889
18907
  if (completeEvent) eventBus.emit(`UI:${completeEvent}`, {});
18890
18908
  onComplete?.();
18891
18909
  }, [completeEvent, eventBus, onComplete]);
18892
18910
  const enhancedProps = { ...rest, onComplete: handleComplete };
18893
- if (props.assetManifest) {
18894
- return /* @__PURE__ */ jsxRuntime.jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: props.assetManifest });
18911
+ if (rest.assetManifest) {
18912
+ return /* @__PURE__ */ jsxRuntime.jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: rest.assetManifest });
18895
18913
  }
18896
18914
  return /* @__PURE__ */ jsxRuntime.jsx(EmojiEffect, { ...enhancedProps });
18897
18915
  }
@@ -19676,6 +19694,10 @@ var init_CaseStudyOrganism = __esm({
19676
19694
  });
19677
19695
  function CastleBoard({
19678
19696
  entity,
19697
+ tiles: propTiles,
19698
+ units: propUnits,
19699
+ features: propFeatures,
19700
+ assetManifest: propAssetManifest,
19679
19701
  scale = 0.45,
19680
19702
  header,
19681
19703
  sidePanel,
@@ -19691,10 +19713,10 @@ function CastleBoard({
19691
19713
  }) {
19692
19714
  const eventBus = useEventBus();
19693
19715
  const resolved = boardEntity(entity);
19694
- const tiles = Array.isArray(resolved?.tiles) ? resolved.tiles : [];
19695
- const features = Array.isArray(resolved?.features) ? resolved.features : [];
19696
- const units = Array.isArray(resolved?.units) ? resolved.units : [];
19697
- const assetManifest = resolved?.assetManifest;
19716
+ const tiles = propTiles ?? (Array.isArray(resolved?.tiles) ? resolved.tiles : []);
19717
+ const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
19718
+ const units = propUnits ?? (Array.isArray(resolved?.units) ? resolved.units : []);
19719
+ const assetManifest = propAssetManifest ?? resolved?.assetManifest;
19698
19720
  const backgroundImage = resolved?.backgroundImage;
19699
19721
  const [hoveredTile, setHoveredTile] = React80.useState(null);
19700
19722
  const [selectedFeature, setSelectedFeature] = React80.useState(null);
@@ -19797,14 +19819,22 @@ var init_CastleBoard = __esm({
19797
19819
  function CastleTemplate({
19798
19820
  entity,
19799
19821
  scale = 0.45,
19822
+ tiles,
19823
+ units,
19824
+ features,
19825
+ assetManifest,
19800
19826
  className
19801
19827
  }) {
19802
19828
  const resolved = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
19803
- if (!resolved) return null;
19829
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
19804
19830
  return /* @__PURE__ */ jsxRuntime.jsx(
19805
19831
  CastleBoard,
19806
19832
  {
19807
19833
  entity: resolved,
19834
+ tiles,
19835
+ units,
19836
+ features,
19837
+ assetManifest,
19808
19838
  scale,
19809
19839
  featureClickEvent: "FEATURE_CLICK",
19810
19840
  unitClickEvent: "UNIT_CLICK",
@@ -26437,8 +26467,8 @@ function GameCanvas2D({
26437
26467
  tickEvent,
26438
26468
  drawEvent,
26439
26469
  fps = 60,
26440
- backgroundImage,
26441
- assetBaseUrl = "",
26470
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/resonators.jpeg",
26471
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/",
26442
26472
  className
26443
26473
  }) {
26444
26474
  const canvasRef = React80__namespace.useRef(null);
@@ -26502,6 +26532,9 @@ function GameCanvas2D({
26502
26532
  const bgImg = loadImage(backgroundImageRef.current);
26503
26533
  if (bgImg) {
26504
26534
  ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
26535
+ } else {
26536
+ ctx.fillStyle = "#0f1420";
26537
+ ctx.fillRect(0, 0, widthRef.current, heightRef.current);
26505
26538
  }
26506
26539
  }
26507
26540
  onDrawRef.current?.(ctx, frame);
@@ -27646,10 +27679,10 @@ function PlatformerCanvas({
27646
27679
  canvasHeight = 400,
27647
27680
  followCamera = true,
27648
27681
  bgColor,
27649
- playerSprite,
27682
+ playerSprite = "https://almadar-kflow-assets.web.app/shared/platformer/characters/platformChar_idle.png",
27650
27683
  tileSprites,
27651
- backgroundImage,
27652
- assetBaseUrl = "",
27684
+ backgroundImage = "https://almadar-kflow-assets.web.app/shared/scenes/court.png",
27685
+ assetBaseUrl = "https://almadar-kflow-assets.web.app/shared/platformer/",
27653
27686
  leftEvent = "MOVE_LEFT",
27654
27687
  rightEvent = "MOVE_RIGHT",
27655
27688
  jumpEvent = "JUMP",
@@ -45857,7 +45890,14 @@ var init_useBattleState = __esm({
45857
45890
  init_boardEntity();
45858
45891
  }
45859
45892
  });
45860
- function UncontrolledBattleBoard({ entity, ...rest }) {
45893
+ function UncontrolledBattleBoard({
45894
+ entity,
45895
+ tiles,
45896
+ units,
45897
+ features,
45898
+ assetManifest,
45899
+ ...rest
45900
+ }) {
45861
45901
  const resolved = boardEntity(entity);
45862
45902
  const battleState = useBattleState(
45863
45903
  rows(resolved?.initialUnits),
@@ -45877,19 +45917,23 @@ function UncontrolledBattleBoard({ entity, ...rest }) {
45877
45917
  calculateDamage: rest.calculateDamage
45878
45918
  }
45879
45919
  );
45880
- if (!resolved) return null;
45920
+ if (!resolved && !tiles && !units && !features && !assetManifest) return null;
45881
45921
  return /* @__PURE__ */ jsxRuntime.jsx(
45882
45922
  BattleBoard,
45883
45923
  {
45884
45924
  ...rest,
45885
- entity: {
45925
+ tiles,
45926
+ units,
45927
+ features,
45928
+ assetManifest,
45929
+ entity: resolved ? {
45886
45930
  ...resolved,
45887
45931
  units: battleState.units,
45888
45932
  phase: battleState.phase,
45889
45933
  turn: battleState.turn,
45890
45934
  gameResult: battleState.gameResult,
45891
45935
  selectedUnitId: battleState.selectedUnitId
45892
- }
45936
+ } : void 0
45893
45937
  }
45894
45938
  );
45895
45939
  }
@@ -45918,6 +45962,10 @@ function defaultIsInRange(from, to, range) {
45918
45962
  }
45919
45963
  function WorldMapBoard({
45920
45964
  entity,
45965
+ tiles: propTiles,
45966
+ units: propUnits,
45967
+ features: propFeatures,
45968
+ assetManifest: propAssetManifest,
45921
45969
  isLoading,
45922
45970
  scale = 0.4,
45923
45971
  unitScale = 2.5,
@@ -45946,16 +45994,16 @@ function WorldMapBoard({
45946
45994
  const resolved = boardEntity(entity);
45947
45995
  const hexes = rows(resolved?.hexes);
45948
45996
  const heroes = rows(resolved?.heroes);
45949
- const features = Array.isArray(resolved?.features) ? resolved.features : [];
45997
+ const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
45950
45998
  const selectedHeroId = resolved?.selectedHeroId ?? null;
45951
- const assetManifest = resolved?.assetManifest;
45999
+ const assetManifest = propAssetManifest ?? resolved?.assetManifest;
45952
46000
  const backgroundImage = resolved?.backgroundImage;
45953
46001
  const [hoveredTile, setHoveredTile] = React80.useState(null);
45954
46002
  const selectedHero = React80.useMemo(
45955
46003
  () => heroes.find((h) => str(h.id) === selectedHeroId) ?? null,
45956
46004
  [heroes, selectedHeroId]
45957
46005
  );
45958
- const tiles = React80.useMemo(
46006
+ const derivedTiles = React80.useMemo(
45959
46007
  () => hexes.map((hex) => ({
45960
46008
  x: num(hex.x),
45961
46009
  y: num(hex.y),
@@ -45964,8 +46012,9 @@ function WorldMapBoard({
45964
46012
  })),
45965
46013
  [hexes]
45966
46014
  );
46015
+ const tiles = propTiles ?? derivedTiles;
45967
46016
  const baseUnits = React80.useMemo(
45968
- () => heroes.map((hero) => ({
46017
+ () => propUnits ?? heroes.map((hero) => ({
45969
46018
  id: str(hero.id),
45970
46019
  position: heroPosition(hero),
45971
46020
  name: str(hero.name),
@@ -45974,7 +46023,7 @@ function WorldMapBoard({
45974
46023
  maxHealth: 100,
45975
46024
  sprite: hero.sprite == null ? void 0 : str(hero.sprite)
45976
46025
  })),
45977
- [heroes]
46026
+ [heroes, propUnits]
45978
46027
  );
45979
46028
  const MOVE_SPEED_MS_PER_TILE = 300;
45980
46029
  const movementAnimRef = React80.useRef(null);
@@ -46184,12 +46233,20 @@ function WorldMapTemplate({
46184
46233
  unitScale = 2.5,
46185
46234
  diamondTopY,
46186
46235
  allowMoveAllHeroes = false,
46236
+ tiles,
46237
+ units,
46238
+ features,
46239
+ assetManifest,
46187
46240
  className
46188
46241
  }) {
46189
46242
  return /* @__PURE__ */ jsxRuntime.jsx(
46190
46243
  WorldMapBoard,
46191
46244
  {
46192
46245
  entity,
46246
+ tiles,
46247
+ units,
46248
+ features,
46249
+ assetManifest,
46193
46250
  scale,
46194
46251
  unitScale,
46195
46252
  diamondTopY,
@@ -47407,6 +47464,24 @@ function renderPatternProps(props, onDismiss) {
47407
47464
  priority: 0
47408
47465
  };
47409
47466
  rendered[key] = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss });
47467
+ } else if (Array.isArray(value)) {
47468
+ rendered[key] = value.map((item, i) => {
47469
+ const el = item;
47470
+ if (isPatternConfig(el)) {
47471
+ const nestedProps = {};
47472
+ for (const [k, v] of Object.entries(el)) {
47473
+ if (k !== "type") nestedProps[k] = v;
47474
+ }
47475
+ const childContent = {
47476
+ id: `prop-${key}-${i}`,
47477
+ pattern: el.type,
47478
+ props: nestedProps,
47479
+ priority: 0
47480
+ };
47481
+ return /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss }, i);
47482
+ }
47483
+ return substituteTraitRefsDeep(el, `prop:${key}[${i}]`);
47484
+ });
47410
47485
  } else {
47411
47486
  rendered[key] = substituteTraitRefsDeep(value, `prop:${key}`);
47412
47487
  }