@almadar/ui 5.72.0 → 5.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/avl/index.cjs +410 -365
  2. package/dist/avl/index.js +410 -365
  3. package/dist/components/game/atoms/ActionButton.d.ts +3 -3
  4. package/dist/components/game/atoms/ChoiceButton.d.ts +3 -3
  5. package/dist/components/game/atoms/ComboCounter.d.ts +3 -3
  6. package/dist/components/game/atoms/ControlButton.d.ts +3 -3
  7. package/dist/components/game/atoms/DamageNumber.d.ts +3 -3
  8. package/dist/components/game/atoms/DialogueBubble.d.ts +3 -3
  9. package/dist/components/game/atoms/ItemSlot.d.ts +3 -3
  10. package/dist/components/game/atoms/ResourceCounter.d.ts +3 -3
  11. package/dist/components/game/atoms/ScoreDisplay.d.ts +3 -3
  12. package/dist/components/game/atoms/Sprite.d.ts +3 -20
  13. package/dist/components/game/atoms/StateIndicator.d.ts +2 -2
  14. package/dist/components/game/atoms/StatusEffect.d.ts +3 -3
  15. package/dist/components/game/atoms/TurnIndicator.d.ts +3 -3
  16. package/dist/components/game/atoms/WaypointMarker.d.ts +3 -3
  17. package/dist/components/game/molecules/CardHand.d.ts +2 -2
  18. package/dist/components/game/molecules/DialogueBox.d.ts +3 -3
  19. package/dist/components/game/molecules/EnemyPlate.d.ts +3 -3
  20. package/dist/components/game/molecules/GameCanvas2D.d.ts +3 -3
  21. package/dist/components/game/molecules/HealthPanel.d.ts +3 -3
  22. package/dist/components/game/molecules/IsometricCanvas.d.ts +8 -12
  23. package/dist/components/game/molecules/PowerupSlots.d.ts +3 -3
  24. package/dist/components/game/molecules/StatBadge.d.ts +5 -5
  25. package/dist/components/game/molecules/TurnPanel.d.ts +3 -3
  26. package/dist/components/game/molecules/three/index.cjs +51 -28
  27. package/dist/components/game/molecules/three/index.js +51 -28
  28. package/dist/components/game/molecules/useUnitSpriteAtlas.d.ts +3 -10
  29. package/dist/components/game/organisms/BattleBoard.d.ts +5 -6
  30. package/dist/components/game/organisms/CardBattlerBoard.d.ts +3 -4
  31. package/dist/components/game/organisms/CastleBoard.d.ts +5 -6
  32. package/dist/components/game/organisms/CityBuilderBoard.d.ts +6 -7
  33. package/dist/components/game/organisms/FishingBoard.d.ts +4 -6
  34. package/dist/components/game/organisms/PlatformerBoard.d.ts +5 -5
  35. package/dist/components/game/organisms/RoguelikeBoard.d.ts +4 -5
  36. package/dist/components/game/organisms/TopDownShooterBoard.d.ts +5 -6
  37. package/dist/components/game/organisms/TowerDefenseBoard.d.ts +5 -6
  38. package/dist/components/game/organisms/VisualNovelBoard.d.ts +4 -5
  39. package/dist/components/game/organisms/WorldMapBoard.d.ts +5 -6
  40. package/dist/components/game/organisms/types/effects.d.ts +7 -8
  41. package/dist/components/game/organisms/types/isometric.d.ts +8 -8
  42. package/dist/components/game/organisms/types/spriteAnimation.d.ts +3 -4
  43. package/dist/components/game/organisms/utils/makeAsset.d.ts +5 -0
  44. package/dist/components/game/templates/PlatformerTemplate.d.ts +5 -4
  45. package/dist/components/game/templates/game3dAssetManifest.d.ts +6 -8
  46. package/dist/components/index.cjs +425 -366
  47. package/dist/components/index.js +425 -366
  48. package/dist/providers/index.cjs +410 -365
  49. package/dist/providers/index.js +410 -365
  50. package/dist/runtime/index.cjs +410 -365
  51. package/dist/runtime/index.js +410 -365
  52. package/package.json +2 -2
@@ -8171,7 +8171,7 @@ function ActionButton({
8171
8171
  assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
8172
8172
  "img",
8173
8173
  {
8174
- src: assetUrl,
8174
+ src: assetUrl.url,
8175
8175
  alt: "",
8176
8176
  width: 16,
8177
8177
  height: 16,
@@ -8215,7 +8215,11 @@ var init_ActionButton = __esm({
8215
8215
  secondary: "bg-secondary text-secondary-foreground hover:bg-secondary-hover border-border",
8216
8216
  danger: "bg-error text-error-foreground hover:bg-error/90 border-error"
8217
8217
  };
8218
- DEFAULT_ASSET_URL = "https://almadar-kflow-assets.web.app/shared/effects/particles/slash_01.png";
8218
+ DEFAULT_ASSET_URL = {
8219
+ url: "https://almadar-kflow-assets.web.app/shared/effects/particles/slash_01.png",
8220
+ role: "effect",
8221
+ category: "effect"
8222
+ };
8219
8223
  ActionButton.displayName = "ActionButton";
8220
8224
  }
8221
8225
  });
@@ -8291,7 +8295,7 @@ function ControlButton({
8291
8295
  children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
8292
8296
  "img",
8293
8297
  {
8294
- src: assetUrl,
8298
+ src: assetUrl.url,
8295
8299
  alt: "",
8296
8300
  width: 24,
8297
8301
  height: 24,
@@ -8331,7 +8335,11 @@ var init_ControlButton = __esm({
8331
8335
  secondary: "bg-secondary text-secondary-foreground border-border hover:bg-secondary-hover",
8332
8336
  ghost: "bg-transparent text-foreground border-border hover:bg-muted"
8333
8337
  };
8334
- DEFAULT_ASSET_URL2 = "https://almadar-kflow-assets.web.app/shared/effects/particles/circle_01.png";
8338
+ DEFAULT_ASSET_URL2 = {
8339
+ url: "https://almadar-kflow-assets.web.app/shared/effects/particles/circle_01.png",
8340
+ role: "effect",
8341
+ category: "effect"
8342
+ };
8335
8343
  ControlButton.displayName = "ControlButton";
8336
8344
  }
8337
8345
  });
@@ -9900,12 +9908,7 @@ var init_spriteAnimation = __esm({
9900
9908
  }
9901
9909
  });
9902
9910
  function unitAtlasUrl(unit) {
9903
- if (unit.spriteSheet) return unit.spriteSheet;
9904
- const sprite = unit.sprite;
9905
- if (!sprite) return null;
9906
- const match = /^(.*-sprite-sheet)(?:-(?:se|sw))?(?:-v\d+)?\.png$/.exec(sprite);
9907
- if (!match) return null;
9908
- return `${match[1]}.json`;
9911
+ return unit.spriteSheet?.url ?? null;
9909
9912
  }
9910
9913
  function resolveSheetUrl(atlasUrl, relativeSheetPath) {
9911
9914
  try {
@@ -10101,7 +10104,6 @@ function IsometricCanvas({
10101
10104
  // Tuning
10102
10105
  diamondTopY: diamondTopYProp,
10103
10106
  // Remote asset loading
10104
- assetBaseUrl,
10105
10107
  assetManifest
10106
10108
  }) {
10107
10109
  const tilesProp = Array.isArray(_tilesPropRaw) ? _tilesPropRaw : [];
@@ -10183,54 +10185,48 @@ function IsometricCanvas({
10183
10185
  const attackTargetSet = React85.useMemo(() => {
10184
10186
  return new Set(attackTargets.map((p2) => `${p2.x},${p2.y}`));
10185
10187
  }, [attackTargets]);
10186
- const resolveManifestUrl7 = React85.useCallback((relativePath) => {
10187
- if (!relativePath) return void 0;
10188
- if (assetBaseUrl) return `${assetBaseUrl.replace(/\/$/, "")}${relativePath.startsWith("/") ? "" : "/"}${relativePath}`;
10189
- return relativePath;
10190
- }, [assetBaseUrl]);
10191
10188
  const spriteUrls = React85.useMemo(() => {
10192
10189
  const urls = [];
10193
10190
  for (const tile of sortedTiles) {
10194
- if (tile.terrainSprite) urls.push(tile.terrainSprite);
10191
+ if (tile.terrainSprite) urls.push(tile.terrainSprite.url);
10195
10192
  else if (getTerrainSprite) {
10196
10193
  const url = getTerrainSprite(tile.terrain ?? "");
10197
10194
  if (url) urls.push(url);
10198
10195
  } else {
10199
- const url = resolveManifestUrl7(assetManifest?.terrains?.[tile.terrain ?? ""]);
10196
+ const url = assetManifest?.terrains?.[tile.terrain ?? ""]?.url;
10200
10197
  if (url) urls.push(url);
10201
10198
  }
10202
10199
  }
10203
10200
  for (const feature of features) {
10204
- if (feature.sprite) urls.push(feature.sprite);
10201
+ if (feature.sprite) urls.push(feature.sprite.url);
10205
10202
  else if (getFeatureSprite) {
10206
10203
  const url = getFeatureSprite(feature.type);
10207
10204
  if (url) urls.push(url);
10208
10205
  } else {
10209
- const url = resolveManifestUrl7(assetManifest?.features?.[feature.type]);
10206
+ const url = assetManifest?.features?.[feature.type]?.url;
10210
10207
  if (url) urls.push(url);
10211
10208
  }
10212
10209
  }
10213
10210
  for (const unit of units) {
10214
- if (unit.sprite) urls.push(unit.sprite);
10211
+ if (unit.sprite) urls.push(unit.sprite.url);
10215
10212
  else if (getUnitSprite) {
10216
10213
  const url = getUnitSprite(unit);
10217
10214
  if (url) urls.push(url);
10218
10215
  } else if (unit.unitType) {
10219
- const url = resolveManifestUrl7(assetManifest?.units?.[unit.unitType]);
10216
+ const url = assetManifest?.units?.[unit.unitType]?.url;
10220
10217
  if (url) urls.push(url);
10221
10218
  }
10222
10219
  }
10223
10220
  if (assetManifest?.effects) {
10224
- for (const path of Object.values(assetManifest.effects)) {
10225
- const url = resolveManifestUrl7(path);
10226
- if (url) urls.push(url);
10221
+ for (const asset of Object.values(assetManifest.effects)) {
10222
+ if (asset.url) urls.push(asset.url);
10227
10223
  }
10228
10224
  }
10229
10225
  if (effectSpriteUrls) urls.push(...effectSpriteUrls);
10230
10226
  if (atlasSheetUrls.length) urls.push(...atlasSheetUrls);
10231
10227
  if (backgroundImage) urls.push(backgroundImage);
10232
10228
  return [...new Set(urls.filter(Boolean))];
10233
- }, [sortedTiles, features, units, getTerrainSprite, getFeatureSprite, getUnitSprite, effectSpriteUrls, atlasSheetUrls, backgroundImage, assetManifest, resolveManifestUrl7]);
10229
+ }, [sortedTiles, features, units, getTerrainSprite, getFeatureSprite, getUnitSprite, effectSpriteUrls, atlasSheetUrls, backgroundImage, assetManifest]);
10234
10230
  const { getImage, pendingCount: _imagePendingCount } = useImageCache(spriteUrls);
10235
10231
  React85.useEffect(() => {
10236
10232
  if (typeof window === "undefined") return;
@@ -10255,14 +10251,14 @@ function IsometricCanvas({
10255
10251
  lerpToTarget
10256
10252
  } = useCamera();
10257
10253
  const resolveTerrainSpriteUrl = React85.useCallback((tile) => {
10258
- return tile.terrainSprite || getTerrainSprite?.(tile.terrain ?? "") || resolveManifestUrl7(assetManifest?.terrains?.[tile.terrain ?? ""]);
10259
- }, [getTerrainSprite, assetManifest, resolveManifestUrl7]);
10254
+ return tile.terrainSprite?.url || getTerrainSprite?.(tile.terrain ?? "") || assetManifest?.terrains?.[tile.terrain ?? ""]?.url;
10255
+ }, [getTerrainSprite, assetManifest]);
10260
10256
  const resolveFeatureSpriteUrl = React85.useCallback((featureType) => {
10261
- return getFeatureSprite?.(featureType) || resolveManifestUrl7(assetManifest?.features?.[featureType]);
10262
- }, [getFeatureSprite, assetManifest, resolveManifestUrl7]);
10257
+ return getFeatureSprite?.(featureType) || assetManifest?.features?.[featureType]?.url;
10258
+ }, [getFeatureSprite, assetManifest]);
10263
10259
  const resolveUnitSpriteUrl = React85.useCallback((unit) => {
10264
- return unit.sprite || getUnitSprite?.(unit) || (unit.unitType ? resolveManifestUrl7(assetManifest?.units?.[unit.unitType]) : void 0);
10265
- }, [getUnitSprite, assetManifest, resolveManifestUrl7]);
10260
+ return unit.sprite?.url || getUnitSprite?.(unit) || (unit.unitType ? assetManifest?.units?.[unit.unitType]?.url : void 0);
10261
+ }, [getUnitSprite, assetManifest]);
10266
10262
  const miniMapTiles = React85.useMemo(() => {
10267
10263
  if (!showMinimap) return [];
10268
10264
  return sortedTiles.map((t2) => ({
@@ -10409,7 +10405,7 @@ function IsometricCanvas({
10409
10405
  if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
10410
10406
  continue;
10411
10407
  }
10412
- const spriteUrl = feature.sprite || resolveFeatureSpriteUrl(feature.type);
10408
+ const spriteUrl = feature.sprite?.url || resolveFeatureSpriteUrl(feature.type);
10413
10409
  const img = spriteUrl ? getImage(spriteUrl) : null;
10414
10410
  const centerX = pos.x + scaledTileWidth / 2;
10415
10411
  const featureGroundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
@@ -10458,12 +10454,12 @@ function IsometricCanvas({
10458
10454
  const img = unitSpriteUrl ? getImage(unitSpriteUrl) : null;
10459
10455
  const unitDrawH = scaledFloorHeight * spriteHeightRatio * unitScale;
10460
10456
  const maxUnitW = scaledTileWidth * spriteMaxWidthRatio * unitScale;
10457
+ const unitIsSheet = unit.sprite?.dimension === "2d" && (unit.sprite?.animations?.length ?? 0) > 0;
10461
10458
  const SHEET_ROWS = 5;
10462
10459
  const sheetFrameW = img ? img.naturalWidth / exports.SHEET_COLUMNS : 0;
10463
10460
  const sheetFrameH = img ? img.naturalHeight / SHEET_ROWS : 0;
10464
- const imgIsSheet = img ? img.naturalWidth % exports.SHEET_COLUMNS === 0 && img.naturalHeight % SHEET_ROWS === 0 && Math.abs(sheetFrameW - sheetFrameH) < 2 : false;
10465
- const frameW = imgIsSheet ? sheetFrameW : img?.naturalWidth ?? 1;
10466
- const frameH = imgIsSheet ? sheetFrameH : img?.naturalHeight ?? 1;
10461
+ const frameW = unitIsSheet ? sheetFrameW : img?.naturalWidth ?? 1;
10462
+ const frameH = unitIsSheet ? sheetFrameH : img?.naturalHeight ?? 1;
10467
10463
  const ar = frameW / (frameH || 1);
10468
10464
  let drawH = unitDrawH;
10469
10465
  let drawW = unitDrawH * ar;
@@ -10478,7 +10474,7 @@ function IsometricCanvas({
10478
10474
  ctx.save();
10479
10475
  ctx.globalAlpha = 0.25;
10480
10476
  if (img) {
10481
- if (imgIsSheet) {
10477
+ if (unitIsSheet) {
10482
10478
  ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
10483
10479
  } else {
10484
10480
  ctx.drawImage(img, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
@@ -10526,7 +10522,7 @@ function IsometricCanvas({
10526
10522
  } else if (img) {
10527
10523
  const spriteY = groundY - drawH - breatheOffset;
10528
10524
  const drawUnit = (x) => {
10529
- if (imgIsSheet) {
10525
+ if (unitIsSheet) {
10530
10526
  ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, x, spriteY, drawW, drawH);
10531
10527
  } else {
10532
10528
  ctx.drawImage(img, x, spriteY, drawW, drawH);
@@ -10553,7 +10549,7 @@ function IsometricCanvas({
10553
10549
  }
10554
10550
  }
10555
10551
  for (const fx of effects) {
10556
- const spriteUrl = resolveManifestUrl7(assetManifest?.effects?.[fx.key]);
10552
+ const spriteUrl = assetManifest?.effects?.[fx.key]?.url;
10557
10553
  if (!spriteUrl) continue;
10558
10554
  const img = getImage(spriteUrl);
10559
10555
  if (!img) continue;
@@ -10597,7 +10593,6 @@ function IsometricCanvas({
10597
10593
  backgroundImage,
10598
10594
  cameraRef,
10599
10595
  unitScale,
10600
- resolveManifestUrl7,
10601
10596
  assetManifest
10602
10597
  ]);
10603
10598
  React85.useEffect(() => {
@@ -10875,6 +10870,42 @@ var init_boardEntity = __esm({
10875
10870
  "components/game/organisms/boardEntity.ts"() {
10876
10871
  }
10877
10872
  });
10873
+
10874
+ // components/game/organisms/utils/makeAsset.ts
10875
+ function makeAsset(url, role, overrides = {}) {
10876
+ const defaults = ROLE_DEFAULTS[role] ?? { dimension: "2d", animations: ["static"], aspect: "1:1" };
10877
+ return {
10878
+ url,
10879
+ role,
10880
+ category: url.split("/").pop()?.replace(/\.[^.]+$/, "") ?? role,
10881
+ ...defaults,
10882
+ ...overrides
10883
+ };
10884
+ }
10885
+ function makeAssetMap(record, role, overrides = {}) {
10886
+ const result = {};
10887
+ for (const [key, url] of Object.entries(record)) {
10888
+ result[key] = makeAsset(url, role, overrides);
10889
+ }
10890
+ return result;
10891
+ }
10892
+ var ROLE_DEFAULTS;
10893
+ var init_makeAsset = __esm({
10894
+ "components/game/organisms/utils/makeAsset.ts"() {
10895
+ ROLE_DEFAULTS = {
10896
+ tile: { dimension: "2d", animations: ["static"], aspect: "1:1" },
10897
+ decoration: { dimension: "2d", animations: ["static"], aspect: "1:1" },
10898
+ effect: { dimension: "2d", animations: ["static"], aspect: "1:1" },
10899
+ item: { dimension: "2d", animations: ["static"], aspect: "5:7" },
10900
+ player: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
10901
+ enemy: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
10902
+ npc: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
10903
+ projectile: { dimension: "2d", animations: ["static"], aspect: "1:1" },
10904
+ vehicle: { dimension: "2d", animations: ["idle", "walk"], aspect: "1:1" },
10905
+ ui: { dimension: "2d", animations: ["static"], aspect: "1:1" }
10906
+ };
10907
+ }
10908
+ });
10878
10909
  function buildDefaultBattleTiles() {
10879
10910
  const tiles = [];
10880
10911
  for (let y = 0; y < BATTLE_GRID_H; y++) {
@@ -10933,14 +10964,14 @@ function BattleBoard({
10933
10964
  if (o === null || typeof o.x !== "number" || typeof o.y !== "number") return [];
10934
10965
  const tile = { x: o.x, y: o.y };
10935
10966
  if (typeof o.terrain === "string") tile.terrain = o.terrain;
10936
- if (typeof o.terrainSprite === "string") tile.terrainSprite = o.terrainSprite;
10967
+ if (typeof o.terrainSprite === "string") tile.terrainSprite = makeAsset(o.terrainSprite, "tile");
10937
10968
  if (typeof o.passable === "boolean") tile.passable = o.passable;
10938
10969
  if (typeof o.movementCost === "number") tile.movementCost = o.movementCost;
10939
10970
  if (typeof o.elevation === "number") tile.elevation = o.elevation;
10940
10971
  if (typeof o.type === "string") tile.type = o.type;
10941
10972
  if (typeof o.tileType === "string") tile.tileType = o.tileType;
10942
10973
  if (typeof o.id === "string") tile.id = o.id;
10943
- if (typeof o.modelUrl === "string") tile.modelUrl = o.modelUrl;
10974
+ if (typeof o.modelUrl === "string") tile.modelUrl = makeAsset(o.modelUrl, "decoration", { dimension: "3d" });
10944
10975
  return [tile];
10945
10976
  }) : []);
10946
10977
  const tiles = rawTiles.length === 0 ? DEFAULT_BATTLE_TILES : rawTiles;
@@ -10949,10 +10980,10 @@ function BattleBoard({
10949
10980
  if (o === null || typeof o.type !== "string" || typeof o.x !== "number" || typeof o.y !== "number") return [];
10950
10981
  const feat = { type: o.type, x: o.x, y: o.y };
10951
10982
  if (typeof o.id === "string") feat.id = o.id;
10952
- if (typeof o.sprite === "string") feat.sprite = o.sprite;
10983
+ if (typeof o.sprite === "string") feat.sprite = makeAsset(o.sprite, "decoration");
10953
10984
  if (typeof o.color === "string") feat.color = o.color;
10954
10985
  if (typeof o.elevation === "number") feat.elevation = o.elevation;
10955
- if (typeof o.assetUrl === "string") feat.assetUrl = o.assetUrl;
10986
+ if (typeof o.assetUrl === "string") feat.assetUrl = makeAsset(o.assetUrl, "decoration", { dimension: "3d" });
10956
10987
  return [feat];
10957
10988
  }) : []);
10958
10989
  const boardWidth = num(board.gridWidth ?? board.boardWidth, BATTLE_GRID_W);
@@ -11068,7 +11099,7 @@ function BattleBoard({
11068
11099
  maxHealth: num(unit.maxHealth),
11069
11100
  unitType: unit.unitType == null ? void 0 : str(unit.unitType),
11070
11101
  heroId: unit.heroId == null ? void 0 : str(unit.heroId),
11071
- sprite: unit.sprite == null ? void 0 : str(unit.sprite),
11102
+ sprite: unit.sprite == null ? void 0 : makeAsset(str(unit.sprite), "npc"),
11072
11103
  traits: unitTraits?.map((tr) => ({
11073
11104
  name: tr.name,
11074
11105
  currentState: tr.currentState,
@@ -11218,7 +11249,6 @@ function BattleBoard({
11218
11249
  onTileHover: (x, y) => setHoveredTile({ x, y }),
11219
11250
  onTileLeave: () => setHoveredTile(null),
11220
11251
  scale,
11221
- assetBaseUrl: assetManifest?.baseUrl,
11222
11252
  assetManifest,
11223
11253
  backgroundImage,
11224
11254
  onDrawEffects,
@@ -11296,15 +11326,16 @@ var init_BattleBoard = __esm({
11296
11326
  init_IsometricCanvas();
11297
11327
  init_boardEntity();
11298
11328
  init_isometric();
11329
+ init_makeAsset();
11299
11330
  BATTLE_CDN = "https://almadar-kflow-assets.web.app/shared";
11300
11331
  BATTLE_GRID_W = 16;
11301
11332
  BATTLE_GRID_H = 16;
11302
11333
  BATTLE_TERRAIN_SPRITES = [
11303
- `${BATTLE_CDN}/isometric-dungeon/Isometric/dirt_E.png`,
11304
- `${BATTLE_CDN}/isometric-dungeon/Isometric/dirtTiles_E.png`,
11305
- `${BATTLE_CDN}/isometric-dungeon/Isometric/planks_E.png`,
11306
- `${BATTLE_CDN}/isometric-dungeon/Isometric/stoneTile_E.png`,
11307
- `${BATTLE_CDN}/isometric-dungeon/Isometric/stoneInset_E.png`
11334
+ makeAsset(`${BATTLE_CDN}/isometric-dungeon/Isometric/dirt_E.png`, "tile"),
11335
+ makeAsset(`${BATTLE_CDN}/isometric-dungeon/Isometric/dirtTiles_E.png`, "tile"),
11336
+ makeAsset(`${BATTLE_CDN}/isometric-dungeon/Isometric/planks_E.png`, "tile"),
11337
+ makeAsset(`${BATTLE_CDN}/isometric-dungeon/Isometric/stoneTile_E.png`, "tile"),
11338
+ makeAsset(`${BATTLE_CDN}/isometric-dungeon/Isometric/stoneInset_E.png`, "tile")
11308
11339
  ];
11309
11340
  DEFAULT_BATTLE_TILES = buildDefaultBattleTiles();
11310
11341
  BattleBoard.displayName = "BattleBoard";
@@ -11343,61 +11374,64 @@ function BattleTemplate({
11343
11374
  }
11344
11375
  );
11345
11376
  }
11346
- var CDN, DEFAULT_BATTLE_TILES2, DEFAULT_BATTLE_UNITS, DEFAULT_BATTLE_FEATURES, DEFAULT_BATTLE_MANIFEST;
11377
+ var CDN, STONE, DIRT, GRASS, DEFAULT_BATTLE_TILES2, DEFAULT_BATTLE_UNITS, DEFAULT_BATTLE_FEATURES, DEFAULT_BATTLE_MANIFEST;
11347
11378
  var init_BattleTemplate = __esm({
11348
11379
  "components/game/templates/BattleTemplate.tsx"() {
11349
11380
  init_BattleBoard();
11381
+ init_makeAsset();
11350
11382
  CDN = "https://almadar-kflow-assets.web.app/shared";
11383
+ STONE = makeAsset(`${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png`, "tile");
11384
+ DIRT = makeAsset(`${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_01.png`, "tile");
11385
+ GRASS = makeAsset(`${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_13.png`, "tile");
11351
11386
  DEFAULT_BATTLE_TILES2 = [
11352
- { x: 0, y: 0, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11353
- { x: 1, y: 0, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11354
- { x: 2, y: 0, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11355
- { x: 3, y: 0, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11356
- { x: 4, y: 0, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11357
- { x: 0, y: 1, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11358
- { x: 1, y: 1, terrain: "dirt", passable: true, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_01.png` },
11359
- { x: 2, y: 1, terrain: "grass", passable: true, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_13.png` },
11360
- { x: 3, y: 1, terrain: "grass", passable: true, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_13.png` },
11361
- { x: 4, y: 1, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11362
- { x: 0, y: 2, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11363
- { x: 1, y: 2, terrain: "grass", passable: true, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_13.png` },
11364
- { x: 2, y: 2, terrain: "dirt", passable: true, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_01.png` },
11365
- { x: 3, y: 2, terrain: "grass", passable: true, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_13.png` },
11366
- { x: 4, y: 2, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11367
- { x: 0, y: 3, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11368
- { x: 1, y: 3, terrain: "grass", passable: true, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_13.png` },
11369
- { x: 2, y: 3, terrain: "grass", passable: true, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_13.png` },
11370
- { x: 3, y: 3, terrain: "dirt", passable: true, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_01.png` },
11371
- { x: 4, y: 3, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11372
- { x: 0, y: 4, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11373
- { x: 1, y: 4, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11374
- { x: 2, y: 4, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11375
- { x: 3, y: 4, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` },
11376
- { x: 4, y: 4, terrain: "stone", passable: false, terrainSprite: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png` }
11387
+ { x: 0, y: 0, terrain: "stone", passable: false, terrainSprite: STONE },
11388
+ { x: 1, y: 0, terrain: "stone", passable: false, terrainSprite: STONE },
11389
+ { x: 2, y: 0, terrain: "stone", passable: false, terrainSprite: STONE },
11390
+ { x: 3, y: 0, terrain: "stone", passable: false, terrainSprite: STONE },
11391
+ { x: 4, y: 0, terrain: "stone", passable: false, terrainSprite: STONE },
11392
+ { x: 0, y: 1, terrain: "stone", passable: false, terrainSprite: STONE },
11393
+ { x: 1, y: 1, terrain: "dirt", passable: true, terrainSprite: DIRT },
11394
+ { x: 2, y: 1, terrain: "grass", passable: true, terrainSprite: GRASS },
11395
+ { x: 3, y: 1, terrain: "grass", passable: true, terrainSprite: GRASS },
11396
+ { x: 4, y: 1, terrain: "stone", passable: false, terrainSprite: STONE },
11397
+ { x: 0, y: 2, terrain: "stone", passable: false, terrainSprite: STONE },
11398
+ { x: 1, y: 2, terrain: "grass", passable: true, terrainSprite: GRASS },
11399
+ { x: 2, y: 2, terrain: "dirt", passable: true, terrainSprite: DIRT },
11400
+ { x: 3, y: 2, terrain: "grass", passable: true, terrainSprite: GRASS },
11401
+ { x: 4, y: 2, terrain: "stone", passable: false, terrainSprite: STONE },
11402
+ { x: 0, y: 3, terrain: "stone", passable: false, terrainSprite: STONE },
11403
+ { x: 1, y: 3, terrain: "grass", passable: true, terrainSprite: GRASS },
11404
+ { x: 2, y: 3, terrain: "grass", passable: true, terrainSprite: GRASS },
11405
+ { x: 3, y: 3, terrain: "dirt", passable: true, terrainSprite: DIRT },
11406
+ { x: 4, y: 3, terrain: "stone", passable: false, terrainSprite: STONE },
11407
+ { x: 0, y: 4, terrain: "stone", passable: false, terrainSprite: STONE },
11408
+ { x: 1, y: 4, terrain: "stone", passable: false, terrainSprite: STONE },
11409
+ { x: 2, y: 4, terrain: "stone", passable: false, terrainSprite: STONE },
11410
+ { x: 3, y: 4, terrain: "stone", passable: false, terrainSprite: STONE },
11411
+ { x: 4, y: 4, terrain: "stone", passable: false, terrainSprite: STONE }
11377
11412
  ];
11378
11413
  DEFAULT_BATTLE_UNITS = [
11379
- { id: "u1", position: { x: 1, y: 1 }, unitType: "worker", name: "Worker", team: "player", health: 10, maxHealth: 10, sprite: `${CDN}/sprite-sheets/amir-sprite-sheet-se.png` },
11380
- { id: "u2", position: { x: 3, y: 3 }, unitType: "guardian", name: "Guardian", team: "enemy", health: 8, maxHealth: 10, sprite: `${CDN}/sprite-sheets/destroyer-sprite-sheet-sw.png` }
11414
+ { id: "u1", position: { x: 1, y: 1 }, unitType: "worker", name: "Worker", team: "player", health: 10, maxHealth: 10, sprite: makeAsset(`${CDN}/sprite-sheets/amir-sprite-sheet-se.png`, "player") },
11415
+ { id: "u2", position: { x: 3, y: 3 }, unitType: "guardian", name: "Guardian", team: "enemy", health: 8, maxHealth: 10, sprite: makeAsset(`${CDN}/sprite-sheets/destroyer-sprite-sheet-sw.png`, "enemy") }
11381
11416
  ];
11382
11417
  DEFAULT_BATTLE_FEATURES = [
11383
- { id: "f1", x: 2, y: 2, type: "gold_mine", sprite: `${CDN}/world-map/gold_mine.png` },
11384
- { id: "f2", x: 3, y: 1, type: "portal", sprite: `${CDN}/world-map/portal_open.png` }
11418
+ { id: "f1", x: 2, y: 2, type: "gold_mine", sprite: makeAsset(`${CDN}/world-map/gold_mine.png`, "decoration") },
11419
+ { id: "f2", x: 3, y: 1, type: "portal", sprite: makeAsset(`${CDN}/world-map/portal_open.png`, "decoration") }
11385
11420
  ];
11386
11421
  DEFAULT_BATTLE_MANIFEST = {
11387
- baseUrl: CDN,
11388
- terrains: {
11389
- stone: "/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png",
11390
- dirt: "/isometric-blocks/PNG/Abstract tiles/abstractTile_01.png",
11391
- grass: "/isometric-blocks/PNG/Abstract tiles/abstractTile_13.png"
11392
- },
11393
- units: {
11394
- worker: "/sprite-sheets/amir-sprite-sheet-se.png",
11395
- guardian: "/sprite-sheets/destroyer-sprite-sheet-sw.png"
11396
- },
11397
- features: {
11398
- gold_mine: "/world-map/gold_mine.png",
11399
- portal: "/world-map/portal_open.png"
11400
- }
11422
+ terrains: makeAssetMap({
11423
+ stone: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_07.png`,
11424
+ dirt: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_01.png`,
11425
+ grass: `${CDN}/isometric-blocks/PNG/Abstract tiles/abstractTile_13.png`
11426
+ }, "tile"),
11427
+ units: makeAssetMap({
11428
+ worker: `${CDN}/sprite-sheets/amir-sprite-sheet-se.png`,
11429
+ guardian: `${CDN}/sprite-sheets/destroyer-sprite-sheet-sw.png`
11430
+ }, "npc"),
11431
+ features: makeAssetMap({
11432
+ gold_mine: `${CDN}/world-map/gold_mine.png`,
11433
+ portal: `${CDN}/world-map/portal_open.png`
11434
+ }, "decoration")
11401
11435
  };
11402
11436
  BattleTemplate.displayName = "BattleTemplate";
11403
11437
  }
@@ -13612,7 +13646,6 @@ function BoardgameBoard({
13612
13646
  units,
13613
13647
  features,
13614
13648
  assetManifest,
13615
- assetBaseUrl,
13616
13649
  scale,
13617
13650
  showMinimap,
13618
13651
  enableCamera,
@@ -18682,7 +18715,7 @@ function CardHand({
18682
18715
  /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex-1 flex items-center justify-center w-full", children: card.iconUrl ? /* @__PURE__ */ jsxRuntime.jsx(
18683
18716
  "img",
18684
18717
  {
18685
- src: card.iconUrl,
18718
+ src: card.iconUrl.url,
18686
18719
  alt: card.title ?? card.id,
18687
18720
  width: art,
18688
18721
  height: art,
@@ -18740,15 +18773,6 @@ var init_CardHand = __esm({
18740
18773
  CardHand.displayName = "CardHand";
18741
18774
  }
18742
18775
  });
18743
- function resolveManifestUrl(manifest, relative) {
18744
- if (relative == null) return void 0;
18745
- if (/^https?:\/\//.test(relative)) return relative;
18746
- const base = manifest?.baseUrl;
18747
- if (base == null) return relative;
18748
- const cleanBase = base.replace(/\/$/, "");
18749
- const cleanRel = relative.replace(/^\//, "");
18750
- return `${cleanBase}/${cleanRel}`;
18751
- }
18752
18776
  function rowToCard(r) {
18753
18777
  return {
18754
18778
  id: str(r.id),
@@ -18762,7 +18786,7 @@ function rowToCard(r) {
18762
18786
  function toHandCards(cards, manifest, mana) {
18763
18787
  return cards.map((c) => {
18764
18788
  const key = c.iconKey ?? c.id;
18765
- const iconUrl = resolveManifestUrl(manifest, manifest?.cards?.[key]);
18789
+ const iconUrl = manifest?.cards?.[key];
18766
18790
  return {
18767
18791
  id: c.id,
18768
18792
  iconUrl,
@@ -19876,7 +19900,6 @@ function CastleBoard({
19876
19900
  onTileHover: (x, y) => setHoveredTile({ x, y }),
19877
19901
  onTileLeave: () => setHoveredTile(null),
19878
19902
  scale,
19879
- assetBaseUrl: assetManifest?.baseUrl,
19880
19903
  assetManifest,
19881
19904
  backgroundImage
19882
19905
  }
@@ -19952,60 +19975,63 @@ function CastleTemplate({
19952
19975
  }
19953
19976
  );
19954
19977
  }
19955
- var CDN2, DEFAULT_CASTLE_TILES, DEFAULT_CASTLE_UNITS, DEFAULT_CASTLE_FEATURES, DEFAULT_CASTLE_MANIFEST;
19978
+ var CDN2, WALL, FLOOR, FLOOR_CENTER, DEFAULT_CASTLE_TILES, DEFAULT_CASTLE_UNITS, DEFAULT_CASTLE_FEATURES, DEFAULT_CASTLE_MANIFEST;
19956
19979
  var init_CastleTemplate = __esm({
19957
19980
  "components/game/templates/CastleTemplate.tsx"() {
19958
19981
  init_CastleBoard();
19982
+ init_makeAsset();
19959
19983
  CDN2 = "https://almadar-kflow-assets.web.app/shared";
19984
+ WALL = makeAsset(`${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png`, "tile");
19985
+ FLOOR = makeAsset(`${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png`, "tile");
19986
+ FLOOR_CENTER = makeAsset(`${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_09.png`, "tile");
19960
19987
  DEFAULT_CASTLE_TILES = [
19961
- { x: 0, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19962
- { x: 1, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19963
- { x: 2, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19964
- { x: 3, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19965
- { x: 4, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19966
- { x: 0, y: 1, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19967
- { x: 1, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
19968
- { x: 2, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
19969
- { x: 3, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
19970
- { x: 4, y: 1, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19971
- { x: 0, y: 2, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19972
- { x: 1, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
19973
- { x: 2, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_09.png` },
19974
- { x: 3, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
19975
- { x: 4, y: 2, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19976
- { x: 0, y: 3, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19977
- { x: 1, y: 3, terrain: "floor", passable: true, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
19978
- { x: 2, y: 3, terrain: "floor", passable: true, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
19979
- { x: 3, y: 3, terrain: "floor", passable: true, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
19980
- { x: 4, y: 3, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19981
- { x: 0, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19982
- { x: 1, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19983
- { x: 2, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19984
- { x: 3, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` },
19985
- { x: 4, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png` }
19988
+ { x: 0, y: 0, terrain: "wall", passable: false, terrainSprite: WALL },
19989
+ { x: 1, y: 0, terrain: "wall", passable: false, terrainSprite: WALL },
19990
+ { x: 2, y: 0, terrain: "wall", passable: false, terrainSprite: WALL },
19991
+ { x: 3, y: 0, terrain: "wall", passable: false, terrainSprite: WALL },
19992
+ { x: 4, y: 0, terrain: "wall", passable: false, terrainSprite: WALL },
19993
+ { x: 0, y: 1, terrain: "wall", passable: false, terrainSprite: WALL },
19994
+ { x: 1, y: 1, terrain: "floor", passable: true, terrainSprite: FLOOR },
19995
+ { x: 2, y: 1, terrain: "floor", passable: true, terrainSprite: FLOOR },
19996
+ { x: 3, y: 1, terrain: "floor", passable: true, terrainSprite: FLOOR },
19997
+ { x: 4, y: 1, terrain: "wall", passable: false, terrainSprite: WALL },
19998
+ { x: 0, y: 2, terrain: "wall", passable: false, terrainSprite: WALL },
19999
+ { x: 1, y: 2, terrain: "floor", passable: true, terrainSprite: FLOOR },
20000
+ { x: 2, y: 2, terrain: "floor", passable: true, terrainSprite: FLOOR_CENTER },
20001
+ { x: 3, y: 2, terrain: "floor", passable: true, terrainSprite: FLOOR },
20002
+ { x: 4, y: 2, terrain: "wall", passable: false, terrainSprite: WALL },
20003
+ { x: 0, y: 3, terrain: "wall", passable: false, terrainSprite: WALL },
20004
+ { x: 1, y: 3, terrain: "floor", passable: true, terrainSprite: FLOOR },
20005
+ { x: 2, y: 3, terrain: "floor", passable: true, terrainSprite: FLOOR },
20006
+ { x: 3, y: 3, terrain: "floor", passable: true, terrainSprite: FLOOR },
20007
+ { x: 4, y: 3, terrain: "wall", passable: false, terrainSprite: WALL },
20008
+ { x: 0, y: 4, terrain: "wall", passable: false, terrainSprite: WALL },
20009
+ { x: 1, y: 4, terrain: "wall", passable: false, terrainSprite: WALL },
20010
+ { x: 2, y: 4, terrain: "wall", passable: false, terrainSprite: WALL },
20011
+ { x: 3, y: 4, terrain: "wall", passable: false, terrainSprite: WALL },
20012
+ { x: 4, y: 4, terrain: "wall", passable: false, terrainSprite: WALL }
19986
20013
  ];
19987
20014
  DEFAULT_CASTLE_UNITS = [
19988
- { id: "u1", position: { x: 1, y: 1 }, unitType: "worker", name: "Worker", team: "player", health: 10, maxHealth: 10, sprite: `${CDN2}/sprite-sheets/coordinator-sprite-sheet-se.png` },
19989
- { id: "u2", position: { x: 3, y: 3 }, unitType: "guardian", name: "Guardian", team: "player", health: 10, maxHealth: 10, sprite: `${CDN2}/sprite-sheets/forger-sprite-sheet-se.png` }
20015
+ { id: "u1", position: { x: 1, y: 1 }, unitType: "worker", name: "Worker", team: "player", health: 10, maxHealth: 10, sprite: makeAsset(`${CDN2}/sprite-sheets/coordinator-sprite-sheet-se.png`, "player") },
20016
+ { id: "u2", position: { x: 3, y: 3 }, unitType: "guardian", name: "Guardian", team: "player", health: 10, maxHealth: 10, sprite: makeAsset(`${CDN2}/sprite-sheets/forger-sprite-sheet-se.png`, "player") }
19990
20017
  ];
19991
20018
  DEFAULT_CASTLE_FEATURES = [
19992
- { id: "f1", x: 2, y: 2, type: "chest", sprite: `${CDN2}/world-map/treasure_chest_closed.png` },
19993
- { id: "f2", x: 3, y: 1, type: "crystal", sprite: `${CDN2}/world-map/resonance_crystal.png` }
20019
+ { id: "f1", x: 2, y: 2, type: "chest", sprite: makeAsset(`${CDN2}/world-map/treasure_chest_closed.png`, "decoration") },
20020
+ { id: "f2", x: 3, y: 1, type: "crystal", sprite: makeAsset(`${CDN2}/world-map/resonance_crystal.png`, "decoration") }
19994
20021
  ];
19995
20022
  DEFAULT_CASTLE_MANIFEST = {
19996
- baseUrl: CDN2,
19997
- terrains: {
19998
- wall: "/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png",
19999
- floor: "/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png"
20000
- },
20001
- units: {
20002
- worker: "/sprite-sheets/coordinator-sprite-sheet-se.png",
20003
- guardian: "/sprite-sheets/forger-sprite-sheet-se.png"
20004
- },
20005
- features: {
20006
- chest: "/world-map/treasure_chest_closed.png",
20007
- crystal: "/world-map/resonance_crystal.png"
20008
- }
20023
+ terrains: makeAssetMap({
20024
+ wall: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_05.png`,
20025
+ floor: `${CDN2}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png`
20026
+ }, "tile"),
20027
+ units: makeAssetMap({
20028
+ worker: `${CDN2}/sprite-sheets/coordinator-sprite-sheet-se.png`,
20029
+ guardian: `${CDN2}/sprite-sheets/forger-sprite-sheet-se.png`
20030
+ }, "player"),
20031
+ features: makeAssetMap({
20032
+ chest: `${CDN2}/world-map/treasure_chest_closed.png`,
20033
+ crystal: `${CDN2}/world-map/resonance_crystal.png`
20034
+ }, "decoration")
20009
20035
  };
20010
20036
  CastleTemplate.displayName = "CastleTemplate";
20011
20037
  }
@@ -21033,7 +21059,7 @@ function ChoiceButton({
21033
21059
  assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
21034
21060
  "img",
21035
21061
  {
21036
- src: assetUrl,
21062
+ src: assetUrl.url,
21037
21063
  alt: "",
21038
21064
  width: 16,
21039
21065
  height: 16,
@@ -21059,15 +21085,6 @@ var init_ChoiceButton = __esm({
21059
21085
  ChoiceButton.displayName = "ChoiceButton";
21060
21086
  }
21061
21087
  });
21062
- function resolveManifestUrl2(manifest, relative) {
21063
- if (relative == null) return void 0;
21064
- if (/^https?:\/\//.test(relative)) return relative;
21065
- const base = manifest?.baseUrl;
21066
- if (base == null) return relative;
21067
- const cleanBase = base.replace(/\/$/, "");
21068
- const cleanRel = relative.replace(/^\//, "");
21069
- return `${cleanBase}/${cleanRel}`;
21070
- }
21071
21088
  function buildDefaultCBTiles() {
21072
21089
  const tiles = [];
21073
21090
  for (let y = 0; y < CB_GRID_H; y++) {
@@ -21082,12 +21099,12 @@ function buildDefaultCBTiles() {
21082
21099
  function tilesToIso(tiles, manifest) {
21083
21100
  return tiles.map((t) => {
21084
21101
  const key = t.terrain ?? "grass";
21085
- const sprite = t.terrainSprite ?? resolveManifestUrl2(manifest, manifest?.terrains?.[key]) ?? resolveManifestUrl2(manifest, manifest?.terrains?.grass);
21102
+ const terrainSprite = t.terrainSprite ?? manifest?.terrains?.[key] ?? manifest?.terrains?.grass;
21086
21103
  return {
21087
21104
  x: t.x,
21088
21105
  y: t.y,
21089
21106
  terrain: t.terrain,
21090
- terrainSprite: sprite,
21107
+ terrainSprite,
21091
21108
  passable: t.passable
21092
21109
  };
21093
21110
  });
@@ -21098,7 +21115,7 @@ function buildingsToFeatures(buildings, manifest) {
21098
21115
  x: b.x,
21099
21116
  y: b.y,
21100
21117
  type: b.type,
21101
- sprite: resolveManifestUrl2(manifest, manifest?.features?.[b.type])
21118
+ sprite: manifest?.features?.[b.type]
21102
21119
  }));
21103
21120
  }
21104
21121
  function CityBuilderBoard({
@@ -21130,7 +21147,7 @@ function CityBuilderBoard({
21130
21147
  x: num(r.x),
21131
21148
  y: num(r.y),
21132
21149
  terrain: r.terrain == null ? void 0 : str(r.terrain),
21133
- terrainSprite: r.terrainSprite == null ? void 0 : str(r.terrainSprite),
21150
+ terrainSprite: r.terrainSprite == null ? void 0 : makeAsset(str(r.terrainSprite), "tile"),
21134
21151
  passable: r.passable !== false
21135
21152
  })),
21136
21153
  [board.tiles]
@@ -21239,7 +21256,6 @@ function CityBuilderBoard({
21239
21256
  {
21240
21257
  tiles: isoTiles,
21241
21258
  features: buildingFeatures,
21242
- assetBaseUrl: assetManifest?.baseUrl,
21243
21259
  assetManifest,
21244
21260
  validMoves,
21245
21261
  hoveredTile,
@@ -21274,6 +21290,7 @@ var CB_GRID_W, CB_GRID_H, DEFAULT_BUILD_TYPES, DEFAULT_CB_TILES;
21274
21290
  var init_CityBuilderBoard = __esm({
21275
21291
  "components/game/organisms/CityBuilderBoard.tsx"() {
21276
21292
  "use client";
21293
+ init_makeAsset();
21277
21294
  init_cn();
21278
21295
  init_useEventBus();
21279
21296
  init_Box();
@@ -21805,7 +21822,7 @@ function ComboCounter({
21805
21822
  assetUrl && /* @__PURE__ */ jsxRuntime.jsx(
21806
21823
  "img",
21807
21824
  {
21808
- src: assetUrl,
21825
+ src: assetUrl.url,
21809
21826
  alt: "combo",
21810
21827
  width: 24,
21811
21828
  height: 24,
@@ -21831,7 +21848,11 @@ var DEFAULT_ASSET_URL3, sizeMap5;
21831
21848
  var init_ComboCounter = __esm({
21832
21849
  "components/game/atoms/ComboCounter.tsx"() {
21833
21850
  init_cn();
21834
- DEFAULT_ASSET_URL3 = "https://almadar-kflow-assets.web.app/shared/effects/flash/flash00.png";
21851
+ DEFAULT_ASSET_URL3 = {
21852
+ url: "https://almadar-kflow-assets.web.app/shared/effects/flash/flash00.png",
21853
+ role: "effect",
21854
+ category: "effect"
21855
+ };
21835
21856
  sizeMap5 = {
21836
21857
  sm: { combo: "text-lg", label: "text-xs", multiplier: "text-xs" },
21837
21858
  md: { combo: "text-2xl", label: "text-xs", multiplier: "text-sm" },
@@ -22276,7 +22297,7 @@ function ItemSlot({
22276
22297
  assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
22277
22298
  "img",
22278
22299
  {
22279
- src: assetUrl,
22300
+ src: assetUrl?.url,
22280
22301
  alt: label,
22281
22302
  width: px,
22282
22303
  height: px,
@@ -22324,7 +22345,11 @@ var init_ItemSlot = __esm({
22324
22345
  epic: "shadow-lg",
22325
22346
  legendary: "shadow-lg"
22326
22347
  };
22327
- DEFAULT_ASSET_URL4 = "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png";
22348
+ DEFAULT_ASSET_URL4 = {
22349
+ url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
22350
+ role: "effect",
22351
+ category: "item"
22352
+ };
22328
22353
  assetSizeMap = {
22329
22354
  sm: 28,
22330
22355
  md: 40,
@@ -22526,7 +22551,7 @@ function DamageNumber({
22526
22551
  assetUrl && /* @__PURE__ */ jsxRuntime.jsx(
22527
22552
  "img",
22528
22553
  {
22529
- src: assetUrl,
22554
+ src: assetUrl.url,
22530
22555
  alt: "",
22531
22556
  width: 14,
22532
22557
  height: 14,
@@ -22562,7 +22587,11 @@ var init_DamageNumber = __esm({
22562
22587
  100% { opacity: 0; transform: translateY(-32px) scale(0.8); }
22563
22588
  }
22564
22589
  `;
22565
- DEFAULT_ASSET_URL5 = "https://almadar-kflow-assets.web.app/shared/effects/particles/spark_01.png";
22590
+ DEFAULT_ASSET_URL5 = {
22591
+ url: "https://almadar-kflow-assets.web.app/shared/effects/particles/spark_01.png",
22592
+ role: "effect",
22593
+ category: "effect"
22594
+ };
22566
22595
  DamageNumber.displayName = "DamageNumber";
22567
22596
  }
22568
22597
  });
@@ -25505,6 +25534,9 @@ function TextLikeControl({
25505
25534
  function isTraitConfigObject(v) {
25506
25535
  return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
25507
25536
  }
25537
+ function isAssetObject(v) {
25538
+ return isTraitConfigObject(v) && typeof v.url === "string";
25539
+ }
25508
25540
  function FieldControl({
25509
25541
  name,
25510
25542
  decl,
@@ -25526,6 +25558,17 @@ function FieldControl({
25526
25558
  onChange: (url) => onChange(name, url)
25527
25559
  }
25528
25560
  );
25561
+ } else if (decl.type === "Asset") {
25562
+ const assetUrl = isAssetObject(effectiveValue) ? effectiveValue.url : "";
25563
+ const baseAsset = isAssetObject(effectiveValue) ? effectiveValue : {};
25564
+ control = /* @__PURE__ */ jsxRuntime.jsx(
25565
+ exports.AssetPicker,
25566
+ {
25567
+ assets: assets ?? [],
25568
+ value: assetUrl,
25569
+ onChange: (url) => onChange(name, { ...baseAsset, url })
25570
+ }
25571
+ );
25529
25572
  } else if (decl.type === "boolean") {
25530
25573
  control = /* @__PURE__ */ jsxRuntime.jsx(exports.Switch, { checked: value === true, onChange: (c) => onChange(name, c) });
25531
25574
  } else if (decl.type === "string" && decl.values !== void 0 && decl.values.length > 0) {
@@ -25578,7 +25621,7 @@ var init_PropertyInspector = __esm({
25578
25621
  init_JsonTreeEditor();
25579
25622
  init_NodeSlotEditor();
25580
25623
  TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
25581
- SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset"]);
25624
+ SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset", "Asset"]);
25582
25625
  exports.PropertyInspector = ({
25583
25626
  config,
25584
25627
  values,
@@ -28682,7 +28725,7 @@ function ScoreDisplay({
28682
28725
  assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
28683
28726
  "img",
28684
28727
  {
28685
- src: assetUrl,
28728
+ src: assetUrl.url,
28686
28729
  alt: "",
28687
28730
  width: 20,
28688
28731
  height: 20,
@@ -28707,7 +28750,11 @@ var init_ScoreDisplay = __esm({
28707
28750
  lg: "text-2xl",
28708
28751
  xl: "text-4xl"
28709
28752
  };
28710
- DEFAULT_ASSET_URL6 = "https://almadar-kflow-assets.web.app/shared/effects/particles/star_01.png";
28753
+ DEFAULT_ASSET_URL6 = {
28754
+ url: "https://almadar-kflow-assets.web.app/shared/effects/particles/star_01.png",
28755
+ role: "effect",
28756
+ category: "effect"
28757
+ };
28711
28758
  ScoreDisplay.displayName = "ScoreDisplay";
28712
28759
  }
28713
28760
  });
@@ -28741,7 +28788,7 @@ function StatBadge({
28741
28788
  resolvedAsset ? /* @__PURE__ */ jsxRuntime.jsx(
28742
28789
  "img",
28743
28790
  {
28744
- src: resolvedAsset,
28791
+ src: resolvedAsset.url,
28745
28792
  alt: "",
28746
28793
  width: 16,
28747
28794
  height: 16,
@@ -28924,7 +28971,7 @@ function WaypointMarker({
28924
28971
  children: completed ? checkIcon : assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
28925
28972
  "img",
28926
28973
  {
28927
- src: assetUrl,
28974
+ src: assetUrl.url,
28928
28975
  alt: label,
28929
28976
  width: sizes.img,
28930
28977
  height: sizes.img,
@@ -28953,7 +29000,11 @@ var init_WaypointMarker = __esm({
28953
29000
  "components/game/atoms/WaypointMarker.tsx"() {
28954
29001
  init_cn();
28955
29002
  init_Icon();
28956
- DEFAULT_ASSET_URL7 = "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png";
29003
+ DEFAULT_ASSET_URL7 = {
29004
+ url: "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png",
29005
+ role: "effect",
29006
+ category: "world"
29007
+ };
28957
29008
  sizeMap12 = {
28958
29009
  sm: { dot: "w-4 h-4", ring: "w-6 h-6", label: "text-xs mt-1", img: 12 },
28959
29010
  md: { dot: "w-6 h-6", ring: "w-8 h-8", label: "text-sm mt-1.5", img: 18 },
@@ -29130,7 +29181,7 @@ function GameCanvas2D({
29130
29181
  tickEvent,
29131
29182
  drawEvent,
29132
29183
  fps = 60,
29133
- backgroundImage = "",
29184
+ backgroundImage,
29134
29185
  assetBaseUrl,
29135
29186
  className
29136
29187
  }) {
@@ -29194,7 +29245,7 @@ function GameCanvas2D({
29194
29245
  emitRef.current(tickEventRef.current, { dt, frame });
29195
29246
  }
29196
29247
  if (backgroundImageRef.current) {
29197
- const bgImg = loadImage(backgroundImageRef.current);
29248
+ const bgImg = loadImage(backgroundImageRef.current.url);
29198
29249
  if (bgImg) {
29199
29250
  ctx.drawImage(bgImg, 0, 0, widthRef.current, heightRef.current);
29200
29251
  } else {
@@ -29266,7 +29317,7 @@ function StatusEffect({
29266
29317
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex items-center justify-center", sizes.icon), children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
29267
29318
  "img",
29268
29319
  {
29269
- src: assetUrl,
29320
+ src: assetUrl.url,
29270
29321
  alt: label,
29271
29322
  width: sizes.img,
29272
29323
  height: sizes.img,
@@ -29305,7 +29356,11 @@ var init_StatusEffect = __esm({
29305
29356
  "components/game/atoms/StatusEffect.tsx"() {
29306
29357
  init_cn();
29307
29358
  init_Icon();
29308
- DEFAULT_ASSET_URL8 = "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png";
29359
+ DEFAULT_ASSET_URL8 = {
29360
+ url: "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png",
29361
+ role: "effect",
29362
+ category: "effect"
29363
+ };
29309
29364
  sizeMap13 = {
29310
29365
  sm: { container: "w-8 h-8", icon: "text-sm", badge: "text-xs -top-1 -right-1 w-4 h-4", timer: "text-[9px]", img: 20 },
29311
29366
  md: { container: "w-10 h-10", icon: "text-base", badge: "text-xs -top-1 -right-1 w-5 h-5", timer: "text-xs", img: 28 },
@@ -29596,7 +29651,7 @@ function TurnIndicator({
29596
29651
  assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
29597
29652
  "img",
29598
29653
  {
29599
- src: assetUrl,
29654
+ src: assetUrl.url,
29600
29655
  alt: "",
29601
29656
  width: 12,
29602
29657
  height: 12,
@@ -29619,7 +29674,11 @@ var init_TurnIndicator = __esm({
29619
29674
  md: { wrapper: "text-sm gap-2 px-3 py-1", dot: "w-2 h-2" },
29620
29675
  lg: { wrapper: "text-base gap-2.5 px-4 py-1.5", dot: "w-2.5 h-2.5" }
29621
29676
  };
29622
- DEFAULT_ASSET_URL9 = "https://almadar-kflow-assets.web.app/shared/effects/particles/symbol_01.png";
29677
+ DEFAULT_ASSET_URL9 = {
29678
+ url: "https://almadar-kflow-assets.web.app/shared/effects/particles/symbol_01.png",
29679
+ role: "effect",
29680
+ category: "effect"
29681
+ };
29623
29682
  TurnIndicator.displayName = "TurnIndicator";
29624
29683
  }
29625
29684
  });
@@ -29713,7 +29772,7 @@ function EnemyPlate({
29713
29772
  assetUrl && /* @__PURE__ */ jsxRuntime.jsx(
29714
29773
  "img",
29715
29774
  {
29716
- src: assetUrl,
29775
+ src: assetUrl.url,
29717
29776
  alt: name,
29718
29777
  width: 24,
29719
29778
  height: 24,
@@ -30055,7 +30114,7 @@ function DialogueBox({
30055
30114
  "div",
30056
30115
  {
30057
30116
  className: "fixed inset-0 z-20 bg-center bg-cover bg-no-repeat",
30058
- style: { backgroundImage: `url(${backgroundImage})` },
30117
+ style: { backgroundImage: `url(${backgroundImage?.url})` },
30059
30118
  "aria-hidden": "true"
30060
30119
  }
30061
30120
  ),
@@ -30070,7 +30129,7 @@ function DialogueBox({
30070
30129
  children: /* @__PURE__ */ jsxRuntime.jsx(
30071
30130
  "img",
30072
30131
  {
30073
- src: portraitUrl,
30132
+ src: portraitUrl?.url,
30074
30133
  alt: dialogue.speaker,
30075
30134
  className: "h-full w-auto object-contain drop-shadow-2xl"
30076
30135
  }
@@ -41787,7 +41846,7 @@ var init_DetailPanel = __esm({
41787
41846
  function DialogueBubble({
41788
41847
  speaker = "Hero",
41789
41848
  text = "The dungeon awaits. Choose your path wisely.",
41790
- portrait = "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
41849
+ portrait = DEFAULT_PORTRAIT,
41791
41850
  position = "bottom",
41792
41851
  className
41793
41852
  }) {
@@ -41803,7 +41862,7 @@ function DialogueBubble({
41803
41862
  portrait && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 w-12 h-12 rounded-full overflow-hidden border-2 border-warning/60", children: /* @__PURE__ */ jsxRuntime.jsx(
41804
41863
  "img",
41805
41864
  {
41806
- src: portrait,
41865
+ src: portrait?.url,
41807
41866
  alt: speaker ?? "speaker",
41808
41867
  className: "w-full h-full object-cover"
41809
41868
  }
@@ -41816,9 +41875,15 @@ function DialogueBubble({
41816
41875
  }
41817
41876
  );
41818
41877
  }
41878
+ var DEFAULT_PORTRAIT;
41819
41879
  var init_DialogueBubble = __esm({
41820
41880
  "components/game/atoms/DialogueBubble.tsx"() {
41821
41881
  init_cn();
41882
+ DEFAULT_PORTRAIT = {
41883
+ url: "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
41884
+ role: "effect",
41885
+ category: "character"
41886
+ };
41822
41887
  DialogueBubble.displayName = "DialogueBubble";
41823
41888
  }
41824
41889
  });
@@ -41894,7 +41959,7 @@ function StateIndicator({
41894
41959
  /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "span", children: assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
41895
41960
  "img",
41896
41961
  {
41897
- src: assetUrl,
41962
+ src: assetUrl.url,
41898
41963
  alt: displayLabel,
41899
41964
  width: 16,
41900
41965
  height: 16,
@@ -41913,7 +41978,11 @@ var init_StateIndicator = __esm({
41913
41978
  init_Box();
41914
41979
  init_Icon();
41915
41980
  init_cn();
41916
- DEFAULT_ASSET_URL10 = "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png";
41981
+ DEFAULT_ASSET_URL10 = {
41982
+ url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
41983
+ role: "effect",
41984
+ category: "item"
41985
+ };
41917
41986
  DEFAULT_STATE_STYLES = {
41918
41987
  idle: { icon: "\u23F8", bgClass: "bg-muted" },
41919
41988
  active: { icon: "\u25B6", bgClass: "bg-success" },
@@ -42719,7 +42788,6 @@ var init_FeatureGridOrganism = __esm({
42719
42788
  });
42720
42789
  function FishingBoard({
42721
42790
  backgroundImage,
42722
- assetBaseUrl,
42723
42791
  scale = 1,
42724
42792
  showMinimap = false,
42725
42793
  enableCamera = true,
@@ -42737,8 +42805,7 @@ function FishingBoard({
42737
42805
  {
42738
42806
  width,
42739
42807
  height,
42740
- backgroundImage: backgroundImage ?? "",
42741
- assetBaseUrl,
42808
+ backgroundImage,
42742
42809
  fps: 60,
42743
42810
  className: "w-full h-full"
42744
42811
  }
@@ -44964,7 +45031,7 @@ var init_GameCanvas3D2 = __esm({
44964
45031
  children: /* @__PURE__ */ jsxRuntime.jsx(
44965
45032
  ModelLoader,
44966
45033
  {
44967
- url: tile.modelUrl,
45034
+ url: tile.modelUrl.url,
44968
45035
  scale: 0.95,
44969
45036
  fallbackGeometry: "box",
44970
45037
  castShadow: true,
@@ -45029,7 +45096,7 @@ var init_GameCanvas3D2 = __esm({
45029
45096
  /* @__PURE__ */ jsxRuntime.jsx(
45030
45097
  ModelLoader,
45031
45098
  {
45032
- url: unit.modelUrl,
45099
+ url: unit.modelUrl.url,
45033
45100
  scale: modelScale,
45034
45101
  fallbackGeometry: "box",
45035
45102
  castShadow: true
@@ -45089,7 +45156,7 @@ var init_GameCanvas3D2 = __esm({
45089
45156
  return /* @__PURE__ */ jsxRuntime.jsx(
45090
45157
  ModelLoader,
45091
45158
  {
45092
- url: feature.assetUrl,
45159
+ url: feature.assetUrl.url,
45093
45160
  position,
45094
45161
  scale: 0.5,
45095
45162
  rotation: [0, feature.rotation ?? 0, 0],
@@ -45310,7 +45377,18 @@ function GameBoard3D({
45310
45377
  const row = boardEntity(entity);
45311
45378
  const eventBus = useEventBus();
45312
45379
  const entityUnits = row ? rows(row.units) : [];
45313
- const units = entityUnits;
45380
+ const units = entityUnits.map((r) => ({
45381
+ id: str(r.id),
45382
+ x: num(r.x),
45383
+ y: num(r.y),
45384
+ z: num(r.z),
45385
+ faction: str(r.faction) || "neutral",
45386
+ team: str(r.team) || str(r.faction) || "neutral",
45387
+ unitType: r.unitType == null ? void 0 : str(r.unitType),
45388
+ name: r.name == null ? void 0 : str(r.name),
45389
+ health: r.health == null ? void 0 : num(r.health),
45390
+ maxHealth: r.maxHealth == null ? void 0 : num(r.maxHealth)
45391
+ }));
45314
45392
  const selectedUnitId = row ? str(row.selectedUnitId) || null : null;
45315
45393
  const phase = row ? str(row.phase) : "observation";
45316
45394
  const result = row ? str(row.result) : "none";
@@ -45489,22 +45567,27 @@ function resolveDescriptor(value, idPrefix) {
45489
45567
  }
45490
45568
  if (typeof value === "object" && value !== null) {
45491
45569
  const desc = asDescriptor(value);
45492
- if (desc !== null && patterns.getComponentForPattern(desc.type) !== null) {
45570
+ const hasComp = desc !== null && patterns.getComponentForPattern(desc.type) !== null;
45571
+ shellLog.debug("resolve", { idPrefix, type: desc?.type ?? null, hasDesc: desc !== null, render: hasComp });
45572
+ if (hasComp) {
45493
45573
  const resolvedProps = desc.props ?? {};
45494
45574
  const content = { id: desc._id ?? idPrefix, pattern: desc.type, props: resolvedProps, priority: 0 };
45495
45575
  const SCR = getSlotContentRenderer();
45496
- return /* @__PURE__ */ jsxRuntime.jsx(SCR, { content, onDismiss: () => void 0 });
45576
+ return /* @__PURE__ */ jsxRuntime.jsx(SCR, { content, onDismiss: () => void 0 }, content.id);
45497
45577
  }
45578
+ } else {
45579
+ shellLog.debug("resolve", { idPrefix, type: null, hasDesc: false, render: false, branch: typeof value });
45498
45580
  }
45499
45581
  return null;
45500
45582
  }
45501
- var _scr; exports.GameShell = void 0;
45583
+ var shellLog, _scr; exports.GameShell = void 0;
45502
45584
  var init_GameShell = __esm({
45503
45585
  "components/game/templates/GameShell.tsx"() {
45504
45586
  init_cn();
45505
45587
  init_Box();
45506
45588
  init_Stack();
45507
45589
  init_Typography();
45590
+ shellLog = logger.createLogger("almadar:ui:game:game-shell");
45508
45591
  _scr = null;
45509
45592
  exports.GameShell = ({
45510
45593
  appName = "Game",
@@ -45905,7 +45988,6 @@ function HexStrategyBoard({
45905
45988
  units,
45906
45989
  features,
45907
45990
  assetManifest,
45908
- assetBaseUrl,
45909
45991
  scale,
45910
45992
  showMinimap,
45911
45993
  enableCamera,
@@ -45947,7 +46029,6 @@ function HolidayRunnerBoard({
45947
46029
  units,
45948
46030
  features,
45949
46031
  assetManifest,
45950
- assetBaseUrl,
45951
46032
  scale,
45952
46033
  showMinimap,
45953
46034
  enableCamera,
@@ -46742,7 +46823,6 @@ function MatchPuzzleBoard({
46742
46823
  units,
46743
46824
  features,
46744
46825
  assetManifest,
46745
- assetBaseUrl,
46746
46826
  scale,
46747
46827
  showMinimap,
46748
46828
  enableCamera,
@@ -47003,7 +47083,6 @@ function MinigolfBoard({
47003
47083
  units,
47004
47084
  features,
47005
47085
  assetManifest,
47006
- assetBaseUrl,
47007
47086
  scale,
47008
47087
  showMinimap,
47009
47088
  enableCamera,
@@ -47309,7 +47388,6 @@ function PirateBoard({
47309
47388
  units,
47310
47389
  features,
47311
47390
  assetManifest,
47312
- assetBaseUrl,
47313
47391
  scale,
47314
47392
  showMinimap,
47315
47393
  enableCamera,
@@ -47430,8 +47508,8 @@ function PlatformerBoard({
47430
47508
  canvasHeight,
47431
47509
  followCamera: true,
47432
47510
  bgColor,
47433
- playerSprite,
47434
- tileSprites,
47511
+ playerSprite: playerSprite?.url,
47512
+ tileSprites: tileSprites ? Object.fromEntries(Object.entries(tileSprites).map(([k, a]) => [k, a.url])) : void 0,
47435
47513
  leftEvent,
47436
47514
  rightEvent,
47437
47515
  jumpEvent,
@@ -47496,7 +47574,7 @@ function PlatformerTemplate({
47496
47574
  worldHeight = 400,
47497
47575
  canvasWidth = 800,
47498
47576
  canvasHeight = 400,
47499
- playerSprite = `${CDN3}/characters/platformChar_idle.png`,
47577
+ playerSprite = makeAsset(`${CDN3}/characters/platformChar_idle.png`, "player"),
47500
47578
  tileSprites = DEFAULT_TILE_SPRITES,
47501
47579
  bgColor = "#5c94fc",
47502
47580
  gameEndEvent = "GAME_END",
@@ -47549,13 +47627,14 @@ var init_PlatformerTemplate = __esm({
47549
47627
  init_PlatformerBoard();
47550
47628
  init_GameHud();
47551
47629
  init_ScoreBoard();
47630
+ init_makeAsset();
47552
47631
  CDN3 = "https://almadar-kflow-assets.web.app/shared/platformer";
47553
- DEFAULT_TILE_SPRITES = {
47632
+ DEFAULT_TILE_SPRITES = makeAssetMap({
47554
47633
  ground: `${CDN3}/tiles/platformPack_tile001.png`,
47555
47634
  platform: `${CDN3}/tiles/platformPack_tile004.png`,
47556
47635
  hazard: `${CDN3}/tiles/platformPack_tile017.png`,
47557
47636
  goal: `${CDN3}/tiles/platformPack_tile007.png`
47558
- };
47637
+ }, "tile");
47559
47638
  DEFAULT_PLATFORMS = [
47560
47639
  { x: 0, y: 368, width: 800, height: 32, type: "ground" },
47561
47640
  { x: 150, y: 280, width: 160, height: 16, type: "platform" },
@@ -47711,7 +47790,6 @@ function RacingBoard({
47711
47790
  units,
47712
47791
  features,
47713
47792
  assetManifest,
47714
- assetBaseUrl,
47715
47793
  scale,
47716
47794
  showMinimap,
47717
47795
  enableCamera,
@@ -47754,7 +47832,7 @@ function ResourceCounter({
47754
47832
  assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
47755
47833
  "img",
47756
47834
  {
47757
- src: assetUrl,
47835
+ src: assetUrl.url,
47758
47836
  alt: label,
47759
47837
  width: sizes.img,
47760
47838
  height: sizes.img,
@@ -47787,7 +47865,11 @@ var init_ResourceCounter = __esm({
47787
47865
  error: "text-error",
47788
47866
  muted: "text-muted-foreground"
47789
47867
  };
47790
- DEFAULT_ASSET_URL11 = "https://almadar-kflow-assets.web.app/shared/world-map/gold_mine.png";
47868
+ DEFAULT_ASSET_URL11 = {
47869
+ url: "https://almadar-kflow-assets.web.app/shared/world-map/gold_mine.png",
47870
+ role: "effect",
47871
+ category: "world"
47872
+ };
47791
47873
  sizeMap16 = {
47792
47874
  sm: { wrapper: "text-xs gap-1 px-1.5 py-0.5", icon: "text-sm", img: 16 },
47793
47875
  md: { wrapper: "text-sm gap-1.5 px-2 py-1", icon: "text-base", img: 20 },
@@ -47796,27 +47878,18 @@ var init_ResourceCounter = __esm({
47796
47878
  ResourceCounter.displayName = "ResourceCounter";
47797
47879
  }
47798
47880
  });
47799
- function resolveManifestUrl3(manifest, relative) {
47800
- if (relative == null) return void 0;
47801
- if (/^https?:\/\//.test(relative)) return relative;
47802
- const base = manifest?.baseUrl;
47803
- if (base == null) return relative;
47804
- const cleanBase = base.replace(/\/$/, "");
47805
- const cleanRel = relative.replace(/^\//, "");
47806
- return `${cleanBase}/${cleanRel}`;
47807
- }
47808
47881
  function dungeonTerrain(x, y, stairsX, stairsY, manifest) {
47809
47882
  const isBorder = x === 0 || y === 0 || x === DUNGEON_GRID_W - 1 || y === DUNGEON_GRID_H - 1;
47810
47883
  const isPillar = x % 4 === 0 && y % 4 === 0 && !isBorder;
47811
47884
  const isWall = isBorder || isPillar;
47812
47885
  const terrains = manifest?.terrains;
47813
47886
  if (x === stairsX && y === stairsY) {
47814
- return { terrain: "stairs", passable: true, terrainSprite: resolveManifestUrl3(manifest, terrains?.stairs) };
47887
+ return { terrain: "stairs", passable: true, terrainSprite: terrains?.stairs };
47815
47888
  }
47816
47889
  if (isWall) {
47817
- return { terrain: "wall", passable: false, terrainSprite: resolveManifestUrl3(manifest, terrains?.wall) };
47890
+ return { terrain: "wall", passable: false, terrainSprite: terrains?.wall };
47818
47891
  }
47819
- return { terrain: "floor", passable: true, terrainSprite: resolveManifestUrl3(manifest, terrains?.floor) };
47892
+ return { terrain: "floor", passable: true, terrainSprite: terrains?.floor };
47820
47893
  }
47821
47894
  function buildDefaultDungeonTiles(stairsX, stairsY, manifest) {
47822
47895
  const tiles = [];
@@ -47860,7 +47933,7 @@ function RoguelikeBoard({
47860
47933
  x: num(r.x),
47861
47934
  y: num(r.y),
47862
47935
  terrain: r.terrain == null ? void 0 : str(r.terrain),
47863
- terrainSprite: r.terrainSprite == null ? void 0 : str(r.terrainSprite),
47936
+ terrainSprite: r.terrainSprite == null ? void 0 : makeAsset(str(r.terrainSprite), "tile"),
47864
47937
  passable: r.passable !== false
47865
47938
  })),
47866
47939
  [board.tiles]
@@ -47940,7 +48013,7 @@ function RoguelikeBoard({
47940
48013
  health: playerHp,
47941
48014
  maxHealth: playerMaxHp,
47942
48015
  unitType: "player",
47943
- sprite: resolveManifestUrl3(assetManifest, assetManifest?.units?.player)
48016
+ sprite: assetManifest?.units?.player
47944
48017
  },
47945
48018
  ...liveEnemies.map((e) => ({
47946
48019
  id: e.id,
@@ -47950,7 +48023,7 @@ function RoguelikeBoard({
47950
48023
  health: e.hp,
47951
48024
  maxHealth: 6,
47952
48025
  unitType: "enemy",
47953
- sprite: resolveManifestUrl3(assetManifest, assetManifest?.units?.enemy)
48026
+ sprite: assetManifest?.units?.enemy
47954
48027
  }))
47955
48028
  ];
47956
48029
  }, [player, enemies, playerHp, playerMaxHp, assetManifest, t]);
@@ -47960,7 +48033,7 @@ function RoguelikeBoard({
47960
48033
  x: it.x,
47961
48034
  y: it.y,
47962
48035
  type: it.kind,
47963
- sprite: resolveManifestUrl3(assetManifest, assetManifest?.features?.[it.kind])
48036
+ sprite: assetManifest?.features?.[it.kind]
47964
48037
  })),
47965
48038
  [items, assetManifest]
47966
48039
  );
@@ -48021,7 +48094,6 @@ function RoguelikeBoard({
48021
48094
  onTileHover: (x, y) => setHoveredTile({ x, y }),
48022
48095
  onTileLeave: () => setHoveredTile(null),
48023
48096
  scale,
48024
- assetBaseUrl: assetManifest?.baseUrl,
48025
48097
  assetManifest,
48026
48098
  unitScale,
48027
48099
  spriteHeightRatio,
@@ -48081,6 +48153,7 @@ var init_RoguelikeBoard = __esm({
48081
48153
  init_Stack();
48082
48154
  init_IsometricCanvas();
48083
48155
  init_boardEntity();
48156
+ init_makeAsset();
48084
48157
  DUNGEON_GRID_W = 16;
48085
48158
  DUNGEON_GRID_H = 16;
48086
48159
  DEFAULT_ENEMIES = [
@@ -48131,55 +48204,59 @@ function RoguelikeTemplate({
48131
48204
  }
48132
48205
  );
48133
48206
  }
48134
- var CDN4, DEFAULT_ROGUELIKE_TILES, DEFAULT_ROGUELIKE_MANIFEST;
48207
+ var CDN4, wall, floor, tiles2, stairs, DEFAULT_ROGUELIKE_TILES, DEFAULT_ROGUELIKE_MANIFEST;
48135
48208
  var init_RoguelikeTemplate = __esm({
48136
48209
  "components/game/templates/RoguelikeTemplate.tsx"() {
48137
48210
  init_RoguelikeBoard();
48211
+ init_makeAsset();
48138
48212
  CDN4 = "https://almadar-kflow-assets.web.app/shared";
48213
+ wall = makeAsset(`${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png`, "tile");
48214
+ floor = makeAsset(`${CDN4}/isometric-dungeon/Isometric/dirt_E.png`, "tile");
48215
+ tiles2 = makeAsset(`${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png`, "tile");
48216
+ stairs = makeAsset(`${CDN4}/isometric-dungeon/Isometric/stairs_E.png`, "tile");
48139
48217
  DEFAULT_ROGUELIKE_TILES = [
48140
- { x: 0, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48141
- { x: 1, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48142
- { x: 2, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48143
- { x: 3, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48144
- { x: 4, y: 0, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48145
- { x: 0, y: 1, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48146
- { x: 1, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
48147
- { x: 2, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
48148
- { x: 3, y: 1, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
48149
- { x: 4, y: 1, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48150
- { x: 0, y: 2, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48151
- { x: 1, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png` },
48152
- { x: 2, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png` },
48153
- { x: 3, y: 2, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
48154
- { x: 4, y: 2, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48155
- { x: 0, y: 3, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48156
- { x: 1, y: 3, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png` },
48157
- { x: 2, y: 3, terrain: "floor", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/dirtTiles_E.png` },
48158
- { x: 3, y: 3, terrain: "stairs", passable: true, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stairs_E.png` },
48159
- { x: 4, y: 3, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48160
- { x: 0, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48161
- { x: 1, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48162
- { x: 2, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48163
- { x: 3, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` },
48164
- { x: 4, y: 4, terrain: "wall", passable: false, terrainSprite: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png` }
48218
+ { x: 0, y: 0, terrain: "wall", passable: false, terrainSprite: wall },
48219
+ { x: 1, y: 0, terrain: "wall", passable: false, terrainSprite: wall },
48220
+ { x: 2, y: 0, terrain: "wall", passable: false, terrainSprite: wall },
48221
+ { x: 3, y: 0, terrain: "wall", passable: false, terrainSprite: wall },
48222
+ { x: 4, y: 0, terrain: "wall", passable: false, terrainSprite: wall },
48223
+ { x: 0, y: 1, terrain: "wall", passable: false, terrainSprite: wall },
48224
+ { x: 1, y: 1, terrain: "floor", passable: true, terrainSprite: floor },
48225
+ { x: 2, y: 1, terrain: "floor", passable: true, terrainSprite: floor },
48226
+ { x: 3, y: 1, terrain: "floor", passable: true, terrainSprite: floor },
48227
+ { x: 4, y: 1, terrain: "wall", passable: false, terrainSprite: wall },
48228
+ { x: 0, y: 2, terrain: "wall", passable: false, terrainSprite: wall },
48229
+ { x: 1, y: 2, terrain: "floor", passable: true, terrainSprite: tiles2 },
48230
+ { x: 2, y: 2, terrain: "floor", passable: true, terrainSprite: tiles2 },
48231
+ { x: 3, y: 2, terrain: "floor", passable: true, terrainSprite: floor },
48232
+ { x: 4, y: 2, terrain: "wall", passable: false, terrainSprite: wall },
48233
+ { x: 0, y: 3, terrain: "wall", passable: false, terrainSprite: wall },
48234
+ { x: 1, y: 3, terrain: "floor", passable: true, terrainSprite: floor },
48235
+ { x: 2, y: 3, terrain: "floor", passable: true, terrainSprite: tiles2 },
48236
+ { x: 3, y: 3, terrain: "stairs", passable: true, terrainSprite: stairs },
48237
+ { x: 4, y: 3, terrain: "wall", passable: false, terrainSprite: wall },
48238
+ { x: 0, y: 4, terrain: "wall", passable: false, terrainSprite: wall },
48239
+ { x: 1, y: 4, terrain: "wall", passable: false, terrainSprite: wall },
48240
+ { x: 2, y: 4, terrain: "wall", passable: false, terrainSprite: wall },
48241
+ { x: 3, y: 4, terrain: "wall", passable: false, terrainSprite: wall },
48242
+ { x: 4, y: 4, terrain: "wall", passable: false, terrainSprite: wall }
48165
48243
  ];
48166
48244
  DEFAULT_ROGUELIKE_MANIFEST = {
48167
- baseUrl: CDN4,
48168
- terrains: {
48169
- floor: "/isometric-dungeon/Isometric/dirt_E.png",
48170
- wall: "/isometric-dungeon/Isometric/stoneInset_E.png",
48171
- stairs: "/isometric-dungeon/Isometric/stairs_E.png",
48172
- planks: "/isometric-dungeon/Isometric/planks_E.png"
48173
- },
48245
+ terrains: makeAssetMap({
48246
+ floor: `${CDN4}/isometric-dungeon/Isometric/dirt_E.png`,
48247
+ wall: `${CDN4}/isometric-dungeon/Isometric/stoneInset_E.png`,
48248
+ stairs: `${CDN4}/isometric-dungeon/Isometric/stairs_E.png`,
48249
+ planks: `${CDN4}/isometric-dungeon/Isometric/planks_E.png`
48250
+ }, "tile"),
48174
48251
  units: {
48175
- player: "/isometric-dungeon/Characters/Male/Male_0_Idle0.png",
48176
- enemy: "/sprite-sheets/shadow-legion-sprite-sheet-sw.png"
48252
+ player: makeAsset(`${CDN4}/isometric-dungeon/Characters/Male/Male_0_Idle0.png`, "player"),
48253
+ enemy: makeAsset(`${CDN4}/sprite-sheets/shadow-legion-sprite-sheet-sw.png`, "enemy")
48177
48254
  },
48178
- features: {
48179
- health_potion: "/isometric-dungeon/Isometric/chestClosed_E.png",
48180
- sword: "/isometric-dungeon/Isometric/barrel_E.png",
48181
- shield: "/isometric-dungeon/Isometric/barrel_E.png"
48182
- }
48255
+ features: makeAssetMap({
48256
+ health_potion: `${CDN4}/isometric-dungeon/Isometric/chestClosed_E.png`,
48257
+ sword: `${CDN4}/isometric-dungeon/Isometric/barrel_E.png`,
48258
+ shield: `${CDN4}/isometric-dungeon/Isometric/barrel_E.png`
48259
+ }, "item")
48183
48260
  };
48184
48261
  RoguelikeTemplate.displayName = "RoguelikeTemplate";
48185
48262
  }
@@ -51034,7 +51111,6 @@ function SokobanBoard({
51034
51111
  units,
51035
51112
  features,
51036
51113
  assetManifest,
51037
- assetBaseUrl,
51038
51114
  scale,
51039
51115
  showMinimap,
51040
51116
  enableCamera,
@@ -51076,7 +51152,6 @@ function SpaceShmupBoard({
51076
51152
  units,
51077
51153
  features,
51078
51154
  assetManifest,
51079
- assetBaseUrl,
51080
51155
  scale,
51081
51156
  showMinimap,
51082
51157
  enableCamera,
@@ -51118,7 +51193,6 @@ function SpaceStationBoard({
51118
51193
  units,
51119
51194
  features,
51120
51195
  assetManifest,
51121
- assetBaseUrl,
51122
51196
  scale,
51123
51197
  showMinimap,
51124
51198
  enableCamera,
@@ -51253,7 +51327,6 @@ function SportsBoard({
51253
51327
  units,
51254
51328
  features,
51255
51329
  assetManifest,
51256
- assetBaseUrl,
51257
51330
  scale,
51258
51331
  showMinimap,
51259
51332
  enableCamera,
@@ -51273,7 +51346,7 @@ var init_SportsBoard = __esm({
51273
51346
  }
51274
51347
  });
51275
51348
  function Sprite({
51276
- spritesheet = "https://almadar-kflow-assets.web.app/shared/isometric-blocks/Spritesheet/allTiles_sheet.png",
51349
+ spritesheet = DEFAULT_SPRITESHEET,
51277
51350
  frameWidth = 64,
51278
51351
  frameHeight = 64,
51279
51352
  frame = 0,
@@ -51326,7 +51399,7 @@ function Sprite({
51326
51399
  position: "absolute",
51327
51400
  width: frameWidth,
51328
51401
  height: frameHeight,
51329
- backgroundImage: `url(${spritesheet})`,
51402
+ backgroundImage: `url(${spritesheet.url})`,
51330
51403
  backgroundPosition,
51331
51404
  backgroundRepeat: "no-repeat",
51332
51405
  imageRendering: "pixelated",
@@ -51374,11 +51447,17 @@ function drawSprite(ctx, image, props) {
51374
51447
  );
51375
51448
  ctx.restore();
51376
51449
  }
51450
+ var DEFAULT_SPRITESHEET;
51377
51451
  var init_Sprite = __esm({
51378
51452
  "components/game/atoms/Sprite.tsx"() {
51379
51453
  "use client";
51380
51454
  init_useEventBus();
51381
51455
  init_spriteAnimation();
51456
+ DEFAULT_SPRITESHEET = {
51457
+ url: "https://almadar-kflow-assets.web.app/shared/isometric-blocks/Spritesheet/allTiles_sheet.png",
51458
+ role: "tile",
51459
+ category: "tile"
51460
+ };
51382
51461
  }
51383
51462
  });
51384
51463
  exports.StatCard = void 0;
@@ -53206,7 +53285,6 @@ function TanksBoard({
53206
53285
  units,
53207
53286
  features,
53208
53287
  assetManifest,
53209
- assetBaseUrl,
53210
53288
  scale,
53211
53289
  showMinimap,
53212
53290
  enableCamera,
@@ -53534,15 +53612,6 @@ var init_ToastSlot = __esm({
53534
53612
  exports.ToastSlot.displayName = "ToastSlot";
53535
53613
  }
53536
53614
  });
53537
- function resolveManifestUrl4(manifest, relative) {
53538
- if (relative == null || relative === "") return void 0;
53539
- if (/^https?:\/\//.test(relative)) return relative;
53540
- const base = manifest?.baseUrl;
53541
- if (base == null) return relative;
53542
- const cleanBase = base.replace(/\/$/, "");
53543
- const cleanRel = relative.replace(/^\//, "");
53544
- return `${cleanBase}/${cleanRel}`;
53545
- }
53546
53615
  function readPlayer(v) {
53547
53616
  if (v == null || typeof v !== "object") return void 0;
53548
53617
  const o = v;
@@ -53595,10 +53664,10 @@ function TopDownShooterBoard({
53595
53664
  const wave = propWave ?? num(board.wave, 1);
53596
53665
  const lives = propLives ?? num(board.lives, 3);
53597
53666
  const result = propResult ?? (str(board.result) || "none");
53598
- const playerSprite = resolveManifestUrl4(assetManifest, assetManifest?.units?.player);
53599
- const enemySprite = resolveManifestUrl4(assetManifest, assetManifest?.units?.enemy);
53600
- const projectileSprite = resolveManifestUrl4(assetManifest, assetManifest?.features?.projectile);
53601
- const backgroundSprite = resolveManifestUrl4(assetManifest, assetManifest?.background);
53667
+ const playerSprite = assetManifest?.units?.player?.url;
53668
+ const enemySprite = assetManifest?.units?.enemy?.url;
53669
+ const projectileSprite = assetManifest?.features?.projectile?.url;
53670
+ const backgroundSprite = assetManifest?.background;
53602
53671
  const spriteUrls = React85.useMemo(
53603
53672
  () => [playerSprite, enemySprite, projectileSprite].filter((u) => u != null),
53604
53673
  [playerSprite, enemySprite, projectileSprite]
@@ -53765,7 +53834,6 @@ function TopDownShooterBoard({
53765
53834
  width,
53766
53835
  height,
53767
53836
  backgroundImage: backgroundSprite,
53768
- assetBaseUrl: assetManifest?.baseUrl,
53769
53837
  onDraw
53770
53838
  }
53771
53839
  ),
@@ -53890,15 +53958,6 @@ var init_TopDownShooterTemplate = __esm({
53890
53958
  TopDownShooterTemplate.displayName = "TopDownShooterTemplate";
53891
53959
  }
53892
53960
  });
53893
- function resolveManifestUrl5(manifest, relative) {
53894
- if (relative == null) return void 0;
53895
- if (/^https?:\/\//.test(relative)) return relative;
53896
- const base = manifest?.baseUrl;
53897
- if (base == null) return relative;
53898
- const cleanBase = base.replace(/\/$/, "");
53899
- const cleanRel = relative.replace(/^\//, "");
53900
- return `${cleanBase}/${cleanRel}`;
53901
- }
53902
53961
  function buildDefaultTDTiles() {
53903
53962
  const pathSet = new Set(DEFAULT_TD_PATH.map((p2) => `${p2.x},${p2.y}`));
53904
53963
  const tiles = [];
@@ -53918,18 +53977,18 @@ function buildDefaultTDTiles() {
53918
53977
  function tilesToIso2(tiles, manifest) {
53919
53978
  return tiles.map((t) => {
53920
53979
  const key = t.terrain ?? "ground";
53921
- const sprite = t.terrainSprite ?? resolveManifestUrl5(manifest, manifest?.terrains?.[key]) ?? resolveManifestUrl5(manifest, manifest?.terrains?.ground);
53980
+ const terrainSprite = t.terrainSprite != null ? makeAsset(t.terrainSprite, "tile") : manifest?.terrains?.[key] ?? manifest?.terrains?.ground;
53922
53981
  return {
53923
53982
  x: t.x,
53924
53983
  y: t.y,
53925
53984
  terrain: t.terrain,
53926
- terrainSprite: sprite,
53985
+ terrainSprite,
53927
53986
  passable: t.passable
53928
53987
  };
53929
53988
  });
53930
53989
  }
53931
53990
  function creepsToUnits(creeps, manifest) {
53932
- const sprite = resolveManifestUrl5(manifest, manifest?.units?.creep);
53991
+ const sprite = manifest?.units?.creep;
53933
53992
  return creeps.map((c) => ({
53934
53993
  id: c.id,
53935
53994
  position: { x: c.x, y: c.y },
@@ -53947,14 +54006,14 @@ function heroToUnit(hero, manifest) {
53947
54006
  position: { x: hero.x, y: hero.y },
53948
54007
  name: "Hero",
53949
54008
  team: "player",
53950
- sprite: resolveManifestUrl5(manifest, manifest?.units?.hero),
54009
+ sprite: manifest?.units?.hero,
53951
54010
  unitType: "hero",
53952
54011
  health: 1,
53953
54012
  maxHealth: 1
53954
54013
  };
53955
54014
  }
53956
54015
  function towersToFeatures(towers, manifest) {
53957
- const sprite = resolveManifestUrl5(manifest, manifest?.features?.tower);
54016
+ const sprite = manifest?.features?.tower;
53958
54017
  return towers.map((t) => ({
53959
54018
  id: t.id,
53960
54019
  x: t.x,
@@ -54152,7 +54211,6 @@ function TowerDefenseBoard({
54152
54211
  tiles: isoTiles,
54153
54212
  units: isoUnits,
54154
54213
  features: towerFeatures,
54155
- assetBaseUrl: assetManifest?.baseUrl,
54156
54214
  assetManifest,
54157
54215
  validMoves,
54158
54216
  hoveredTile,
@@ -54196,6 +54254,7 @@ var TD_GRID_W, TD_GRID_H, DEFAULT_TD_PATH, DEFAULT_TD_TILES;
54196
54254
  var init_TowerDefenseBoard = __esm({
54197
54255
  "components/game/organisms/TowerDefenseBoard.tsx"() {
54198
54256
  "use client";
54257
+ init_makeAsset();
54199
54258
  init_cn();
54200
54259
  init_useEventBus();
54201
54260
  init_Box();
@@ -54525,15 +54584,6 @@ var init_UncontrolledBattleBoard = __esm({
54525
54584
  UncontrolledBattleBoard.displayName = "UncontrolledBattleBoard";
54526
54585
  }
54527
54586
  });
54528
- function resolveManifestUrl6(manifest, relative) {
54529
- if (relative == null) return void 0;
54530
- if (/^https?:\/\//.test(relative)) return relative;
54531
- const base = manifest?.baseUrl;
54532
- if (base == null) return relative;
54533
- const cleanBase = base.replace(/\/$/, "");
54534
- const cleanRel = relative.replace(/^\//, "");
54535
- return `${cleanBase}/${cleanRel}`;
54536
- }
54537
54587
  function VisualNovelBoard({
54538
54588
  entity,
54539
54589
  nodes: propNodes,
@@ -54568,11 +54618,11 @@ function VisualNovelBoard({
54568
54618
  const currentNodeId = propCurrentNodeId ?? (str(board.currentNodeId) || nodes[0]?.id);
54569
54619
  const currentNode = nodes.find((n) => n.id === currentNodeId) ?? nodes[0];
54570
54620
  const backgroundImage = React85.useMemo(
54571
- () => resolveManifestUrl6(assetManifest, assetManifest?.backgrounds?.[currentNode?.backgroundKey ?? ""]),
54621
+ () => assetManifest?.backgrounds?.[currentNode?.backgroundKey ?? ""],
54572
54622
  [assetManifest, currentNode?.backgroundKey]
54573
54623
  );
54574
54624
  const portraitUrl = React85.useMemo(
54575
- () => resolveManifestUrl6(assetManifest, assetManifest?.portraits?.[currentNode?.portraitKey ?? ""]),
54625
+ () => assetManifest?.portraits?.[currentNode?.portraitKey ?? ""],
54576
54626
  [assetManifest, currentNode?.portraitKey]
54577
54627
  );
54578
54628
  const dialogueChoices = React85.useMemo(
@@ -54746,7 +54796,7 @@ function buildDefaultWorldTiles() {
54746
54796
  for (let x = 0; x < WORLD_GRID_W; x++) {
54747
54797
  const isBorder = x === 0 || y === 0 || x === WORLD_GRID_W - 1 || y === WORLD_GRID_H - 1;
54748
54798
  const def = isBorder ? WORLD_TERRAIN_DEFS[3] : WORLD_TERRAIN_DEFS[(x * 5 + y * 3 + (x ^ y)) % (WORLD_TERRAIN_DEFS.length - 1)];
54749
- tiles.push({ x, y, terrain: def.terrain, terrainSprite: def.sprite, passable: def.passable });
54799
+ tiles.push({ x, y, terrain: def.terrain, terrainSprite: makeAsset(def.sprite, "tile"), passable: def.passable });
54750
54800
  }
54751
54801
  }
54752
54802
  return tiles;
@@ -54790,7 +54840,12 @@ function WorldMapBoard({
54790
54840
  const resolved = boardEntity(entity);
54791
54841
  const entityUnits = rows(resolved?.units);
54792
54842
  const entityTiles = rows(resolved?.tiles);
54793
- const features = propFeatures ?? rows(resolved?.features);
54843
+ const features = propFeatures ?? rows(resolved?.features).map((r) => ({
54844
+ id: r.id == null ? void 0 : str(r.id),
54845
+ x: num(r.x),
54846
+ y: num(r.y),
54847
+ type: str(r.type)
54848
+ }));
54794
54849
  const selectedHeroId = resolved?.selectedHeroId ?? null;
54795
54850
  const assetManifest = propAssetManifest ?? resolved?.assetManifest;
54796
54851
  const backgroundImage = resolved?.backgroundImage;
@@ -54800,7 +54855,7 @@ function WorldMapBoard({
54800
54855
  x: num(t.x),
54801
54856
  y: num(t.y),
54802
54857
  terrain: str(t.terrain),
54803
- terrainSprite: t.terrainSprite == null ? void 0 : str(t.terrainSprite),
54858
+ terrainSprite: t.terrainSprite == null ? void 0 : makeAsset(str(t.terrainSprite), "tile"),
54804
54859
  passable: t.passable !== false
54805
54860
  })),
54806
54861
  [entityTiles]
@@ -54816,7 +54871,7 @@ function WorldMapBoard({
54816
54871
  team: str(u.team) === "enemy" ? "enemy" : "player",
54817
54872
  health: num(u.health) || 100,
54818
54873
  maxHealth: num(u.maxHealth) || 100,
54819
- sprite: u.sprite == null ? void 0 : str(u.sprite)
54874
+ sprite: u.sprite == null ? void 0 : makeAsset(str(u.sprite), "player")
54820
54875
  })),
54821
54876
  [entityUnits, propUnits]
54822
54877
  );
@@ -54998,7 +55053,6 @@ function WorldMapBoard({
54998
55053
  onTileHover: (x, y) => setHoveredTile({ x, y }),
54999
55054
  onTileLeave: () => setHoveredTile(null),
55000
55055
  scale,
55001
- assetBaseUrl: assetManifest?.baseUrl,
55002
55056
  assetManifest,
55003
55057
  backgroundImage,
55004
55058
  effectSpriteUrls,
@@ -55021,6 +55075,7 @@ var WORLD_CDN, WORLD_GRID_W, WORLD_GRID_H, WORLD_TERRAIN_DEFS, DEFAULT_WORLD_TIL
55021
55075
  var init_WorldMapBoard = __esm({
55022
55076
  "components/game/organisms/WorldMapBoard.tsx"() {
55023
55077
  "use client";
55078
+ init_makeAsset();
55024
55079
  init_cn();
55025
55080
  init_useEventBus();
55026
55081
  init_Stack();
@@ -55074,62 +55129,66 @@ function WorldMapTemplate({
55074
55129
  }
55075
55130
  );
55076
55131
  }
55077
- var CDN5, DEFAULT_WORLDMAP_TILES, DEFAULT_WORLDMAP_UNITS, DEFAULT_WORLDMAP_FEATURES, DEFAULT_WORLDMAP_MANIFEST;
55132
+ var CDN5, mountain, water, grass, road, DEFAULT_WORLDMAP_TILES, DEFAULT_WORLDMAP_UNITS, DEFAULT_WORLDMAP_FEATURES, DEFAULT_WORLDMAP_MANIFEST;
55078
55133
  var init_WorldMapTemplate = __esm({
55079
55134
  "components/game/templates/WorldMapTemplate.tsx"() {
55080
55135
  init_WorldMapBoard();
55136
+ init_makeAsset();
55081
55137
  CDN5 = "https://almadar-kflow-assets.web.app/shared";
55138
+ mountain = makeAsset(`${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png`, "tile");
55139
+ water = makeAsset(`${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png`, "tile");
55140
+ grass = makeAsset(`${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png`, "tile");
55141
+ road = makeAsset(`${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_03.png`, "tile");
55082
55142
  DEFAULT_WORLDMAP_TILES = [
55083
- { x: 0, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
55084
- { x: 1, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
55085
- { x: 2, y: 0, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
55086
- { x: 3, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
55087
- { x: 4, y: 0, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
55088
- { x: 0, y: 1, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
55089
- { x: 1, y: 1, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
55090
- { x: 2, y: 1, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
55091
- { x: 3, y: 1, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
55092
- { x: 4, y: 1, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
55093
- { x: 0, y: 2, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
55094
- { x: 1, y: 2, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
55095
- { x: 2, y: 2, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_03.png` },
55096
- { x: 3, y: 2, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
55097
- { x: 4, y: 2, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
55098
- { x: 0, y: 3, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
55099
- { x: 1, y: 3, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
55100
- { x: 2, y: 3, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
55101
- { x: 3, y: 3, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_03.png` },
55102
- { x: 4, y: 3, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
55103
- { x: 0, y: 4, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
55104
- { x: 1, y: 4, terrain: "water", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png` },
55105
- { x: 2, y: 4, terrain: "grass", passable: true, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png` },
55106
- { x: 3, y: 4, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` },
55107
- { x: 4, y: 4, terrain: "mountain", passable: false, terrainSprite: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png` }
55143
+ { x: 0, y: 0, terrain: "mountain", passable: false, terrainSprite: mountain },
55144
+ { x: 1, y: 0, terrain: "mountain", passable: false, terrainSprite: mountain },
55145
+ { x: 2, y: 0, terrain: "water", passable: false, terrainSprite: water },
55146
+ { x: 3, y: 0, terrain: "mountain", passable: false, terrainSprite: mountain },
55147
+ { x: 4, y: 0, terrain: "mountain", passable: false, terrainSprite: mountain },
55148
+ { x: 0, y: 1, terrain: "mountain", passable: false, terrainSprite: mountain },
55149
+ { x: 1, y: 1, terrain: "grass", passable: true, terrainSprite: grass },
55150
+ { x: 2, y: 1, terrain: "grass", passable: true, terrainSprite: grass },
55151
+ { x: 3, y: 1, terrain: "grass", passable: true, terrainSprite: grass },
55152
+ { x: 4, y: 1, terrain: "water", passable: false, terrainSprite: water },
55153
+ { x: 0, y: 2, terrain: "water", passable: false, terrainSprite: water },
55154
+ { x: 1, y: 2, terrain: "grass", passable: true, terrainSprite: grass },
55155
+ { x: 2, y: 2, terrain: "grass", passable: true, terrainSprite: road },
55156
+ { x: 3, y: 2, terrain: "grass", passable: true, terrainSprite: grass },
55157
+ { x: 4, y: 2, terrain: "mountain", passable: false, terrainSprite: mountain },
55158
+ { x: 0, y: 3, terrain: "mountain", passable: false, terrainSprite: mountain },
55159
+ { x: 1, y: 3, terrain: "grass", passable: true, terrainSprite: grass },
55160
+ { x: 2, y: 3, terrain: "grass", passable: true, terrainSprite: grass },
55161
+ { x: 3, y: 3, terrain: "grass", passable: true, terrainSprite: road },
55162
+ { x: 4, y: 3, terrain: "mountain", passable: false, terrainSprite: mountain },
55163
+ { x: 0, y: 4, terrain: "mountain", passable: false, terrainSprite: mountain },
55164
+ { x: 1, y: 4, terrain: "water", passable: false, terrainSprite: water },
55165
+ { x: 2, y: 4, terrain: "grass", passable: true, terrainSprite: grass },
55166
+ { x: 3, y: 4, terrain: "mountain", passable: false, terrainSprite: mountain },
55167
+ { x: 4, y: 4, terrain: "mountain", passable: false, terrainSprite: mountain }
55108
55168
  ];
55109
55169
  DEFAULT_WORLDMAP_UNITS = [
55110
- { id: "h1", position: { x: 1, y: 1 }, unitType: "hero", name: "Amir", team: "player", health: 10, maxHealth: 10, sprite: `${CDN5}/sprite-sheets/amir-sprite-sheet-se.png` },
55111
- { id: "h2", position: { x: 3, y: 3 }, unitType: "scout", name: "Archivist", team: "player", health: 10, maxHealth: 10, sprite: `${CDN5}/sprite-sheets/archivist-sprite-sheet-se.png` }
55170
+ { id: "h1", position: { x: 1, y: 1 }, unitType: "hero", name: "Amir", team: "player", health: 10, maxHealth: 10, sprite: makeAsset(`${CDN5}/sprite-sheets/amir-sprite-sheet-se.png`, "player") },
55171
+ { id: "h2", position: { x: 3, y: 3 }, unitType: "scout", name: "Archivist", team: "player", health: 10, maxHealth: 10, sprite: makeAsset(`${CDN5}/sprite-sheets/archivist-sprite-sheet-se.png`, "npc") }
55112
55172
  ];
55113
55173
  DEFAULT_WORLDMAP_FEATURES = [
55114
- { id: "f1", x: 2, y: 2, type: "capital", sprite: `${CDN5}/scenes/world/capital.png` },
55115
- { id: "f2", x: 4, y: 2, type: "power_node", sprite: `${CDN5}/world-map/power_node.png` }
55174
+ { id: "f1", x: 2, y: 2, type: "capital", sprite: makeAsset(`${CDN5}/scenes/world/capital.png`, "decoration") },
55175
+ { id: "f2", x: 4, y: 2, type: "power_node", sprite: makeAsset(`${CDN5}/world-map/power_node.png`, "decoration") }
55116
55176
  ];
55117
55177
  DEFAULT_WORLDMAP_MANIFEST = {
55118
- baseUrl: CDN5,
55119
- terrains: {
55120
- grass: "/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png",
55121
- water: "/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png",
55122
- mountain: "/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png",
55123
- road: "/isometric-blocks/PNG/Platformer tiles/platformerTile_03.png"
55124
- },
55178
+ terrains: makeAssetMap({
55179
+ grass: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_01.png`,
55180
+ water: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_11.png`,
55181
+ mountain: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_13.png`,
55182
+ road: `${CDN5}/isometric-blocks/PNG/Platformer tiles/platformerTile_03.png`
55183
+ }, "tile"),
55125
55184
  units: {
55126
- hero: "/sprite-sheets/amir-sprite-sheet-se.png",
55127
- scout: "/sprite-sheets/archivist-sprite-sheet-se.png"
55185
+ hero: makeAsset(`${CDN5}/sprite-sheets/amir-sprite-sheet-se.png`, "player"),
55186
+ scout: makeAsset(`${CDN5}/sprite-sheets/archivist-sprite-sheet-se.png`, "npc")
55128
55187
  },
55129
- features: {
55130
- capital: "/scenes/world/capital.png",
55131
- power_node: "/world-map/power_node.png"
55132
- }
55188
+ features: makeAssetMap({
55189
+ capital: `${CDN5}/scenes/world/capital.png`,
55190
+ power_node: `${CDN5}/world-map/power_node.png`
55191
+ }, "decoration")
55133
55192
  };
55134
55193
  WorldMapTemplate.displayName = "WorldMapTemplate";
55135
55194
  }