@almadar/ui 5.40.0 → 5.42.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.
@@ -11225,6 +11225,7 @@ var init_ResourceCounter = __esm({
11225
11225
  }
11226
11226
  });
11227
11227
  function ItemSlot({
11228
+ assetUrl = DEFAULT_ASSET_URL,
11228
11229
  icon = "sword",
11229
11230
  label = "Iron Sword",
11230
11231
  quantity,
@@ -11236,6 +11237,7 @@ function ItemSlot({
11236
11237
  className
11237
11238
  }) {
11238
11239
  const isClickable = onClick != null;
11240
+ const px = assetSizeMap[size];
11239
11241
  return /* @__PURE__ */ jsxRuntime.jsx(
11240
11242
  "button",
11241
11243
  {
@@ -11256,7 +11258,17 @@ function ItemSlot({
11256
11258
  className
11257
11259
  ),
11258
11260
  children: empty ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11259
- icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }),
11261
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
11262
+ "img",
11263
+ {
11264
+ src: assetUrl,
11265
+ alt: label,
11266
+ width: px,
11267
+ height: px,
11268
+ style: { imageRendering: "pixelated", objectFit: "contain" },
11269
+ className: "flex-shrink-0"
11270
+ }
11271
+ ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }) : null,
11260
11272
  quantity != null && quantity > 1 && /* @__PURE__ */ jsxRuntime.jsx(
11261
11273
  "span",
11262
11274
  {
@@ -11272,7 +11284,7 @@ function ItemSlot({
11272
11284
  }
11273
11285
  );
11274
11286
  }
11275
- var sizeMap6, rarityBorderMap, rarityGlowMap;
11287
+ var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL, assetSizeMap;
11276
11288
  var init_ItemSlot = __esm({
11277
11289
  "components/game/atoms/ItemSlot.tsx"() {
11278
11290
  "use client";
@@ -11297,6 +11309,12 @@ var init_ItemSlot = __esm({
11297
11309
  epic: "shadow-lg",
11298
11310
  legendary: "shadow-lg"
11299
11311
  };
11312
+ DEFAULT_ASSET_URL = "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png";
11313
+ assetSizeMap = {
11314
+ sm: 28,
11315
+ md: 40,
11316
+ lg: 56
11317
+ };
11300
11318
  ItemSlot.displayName = "ItemSlot";
11301
11319
  }
11302
11320
  });
@@ -46853,6 +46871,10 @@ function SequencerBoard({
46853
46871
  stepDurationMs = 1e3,
46854
46872
  playEvent,
46855
46873
  completeEvent,
46874
+ placeEvent,
46875
+ removeEvent,
46876
+ checkEvent,
46877
+ playAgainEvent,
46856
46878
  className
46857
46879
  }) {
46858
46880
  const { emit } = useEventBus();
@@ -46888,7 +46910,8 @@ function SequencerBoard({
46888
46910
  return next;
46889
46911
  });
46890
46912
  emit("UI:PLAY_SOUND", { key: "drop_slot" });
46891
- }, [emit]);
46913
+ if (placeEvent) emit(`UI:${placeEvent}`, { slotIndex: index, actionId: item.id });
46914
+ }, [emit, placeEvent]);
46892
46915
  const handleSlotRemove = React91.useCallback((index) => {
46893
46916
  setSlots((prev) => {
46894
46917
  const next = [...prev];
@@ -46901,7 +46924,8 @@ function SequencerBoard({
46901
46924
  return next;
46902
46925
  });
46903
46926
  emit("UI:PLAY_SOUND", { key: "back" });
46904
- }, [emit]);
46927
+ if (removeEvent) emit(`UI:${removeEvent}`, { slotIndex: index });
46928
+ }, [emit, removeEvent]);
46905
46929
  const handleReset = React91.useCallback(() => {
46906
46930
  if (timerRef.current) clearTimeout(timerRef.current);
46907
46931
  setSlots(Array.from({ length: maxSlots }, () => void 0));
@@ -46909,7 +46933,8 @@ function SequencerBoard({
46909
46933
  setCurrentStep(-1);
46910
46934
  setAttempts(0);
46911
46935
  setSlotFeedback(Array.from({ length: maxSlots }, () => null));
46912
- }, [maxSlots]);
46936
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
46937
+ }, [maxSlots, playAgainEvent, emit]);
46913
46938
  const filledSlots = slots.filter((s) => !!s);
46914
46939
  const canPlay = filledSlots.length > 0 && playState === "idle";
46915
46940
  const handlePlay = React91.useCallback(() => {
@@ -46931,6 +46956,7 @@ function SequencerBoard({
46931
46956
  const success = solutions.some(
46932
46957
  (sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
46933
46958
  );
46959
+ if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
46934
46960
  if (success) {
46935
46961
  setPlayState("success");
46936
46962
  setCurrentStep(-1);
@@ -46958,7 +46984,7 @@ function SequencerBoard({
46958
46984
  }
46959
46985
  };
46960
46986
  timerRef.current = setTimeout(advance, stepDurationMs);
46961
- }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, emit]);
46987
+ }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, checkEvent, emit]);
46962
46988
  const machine = {
46963
46989
  name: str(resolved?.title),
46964
46990
  description: str(resolved?.description),
package/dist/avl/index.js CHANGED
@@ -11179,6 +11179,7 @@ var init_ResourceCounter = __esm({
11179
11179
  }
11180
11180
  });
11181
11181
  function ItemSlot({
11182
+ assetUrl = DEFAULT_ASSET_URL,
11182
11183
  icon = "sword",
11183
11184
  label = "Iron Sword",
11184
11185
  quantity,
@@ -11190,6 +11191,7 @@ function ItemSlot({
11190
11191
  className
11191
11192
  }) {
11192
11193
  const isClickable = onClick != null;
11194
+ const px = assetSizeMap[size];
11193
11195
  return /* @__PURE__ */ jsx(
11194
11196
  "button",
11195
11197
  {
@@ -11210,7 +11212,17 @@ function ItemSlot({
11210
11212
  className
11211
11213
  ),
11212
11214
  children: empty ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
11213
- icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }),
11215
+ assetUrl ? /* @__PURE__ */ jsx(
11216
+ "img",
11217
+ {
11218
+ src: assetUrl,
11219
+ alt: label,
11220
+ width: px,
11221
+ height: px,
11222
+ style: { imageRendering: "pixelated", objectFit: "contain" },
11223
+ className: "flex-shrink-0"
11224
+ }
11225
+ ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
11214
11226
  quantity != null && quantity > 1 && /* @__PURE__ */ jsx(
11215
11227
  "span",
11216
11228
  {
@@ -11226,7 +11238,7 @@ function ItemSlot({
11226
11238
  }
11227
11239
  );
11228
11240
  }
11229
- var sizeMap6, rarityBorderMap, rarityGlowMap;
11241
+ var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL, assetSizeMap;
11230
11242
  var init_ItemSlot = __esm({
11231
11243
  "components/game/atoms/ItemSlot.tsx"() {
11232
11244
  "use client";
@@ -11251,6 +11263,12 @@ var init_ItemSlot = __esm({
11251
11263
  epic: "shadow-lg",
11252
11264
  legendary: "shadow-lg"
11253
11265
  };
11266
+ DEFAULT_ASSET_URL = "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png";
11267
+ assetSizeMap = {
11268
+ sm: 28,
11269
+ md: 40,
11270
+ lg: 56
11271
+ };
11254
11272
  ItemSlot.displayName = "ItemSlot";
11255
11273
  }
11256
11274
  });
@@ -46807,6 +46825,10 @@ function SequencerBoard({
46807
46825
  stepDurationMs = 1e3,
46808
46826
  playEvent,
46809
46827
  completeEvent,
46828
+ placeEvent,
46829
+ removeEvent,
46830
+ checkEvent,
46831
+ playAgainEvent,
46810
46832
  className
46811
46833
  }) {
46812
46834
  const { emit } = useEventBus();
@@ -46842,7 +46864,8 @@ function SequencerBoard({
46842
46864
  return next;
46843
46865
  });
46844
46866
  emit("UI:PLAY_SOUND", { key: "drop_slot" });
46845
- }, [emit]);
46867
+ if (placeEvent) emit(`UI:${placeEvent}`, { slotIndex: index, actionId: item.id });
46868
+ }, [emit, placeEvent]);
46846
46869
  const handleSlotRemove = useCallback((index) => {
46847
46870
  setSlots((prev) => {
46848
46871
  const next = [...prev];
@@ -46855,7 +46878,8 @@ function SequencerBoard({
46855
46878
  return next;
46856
46879
  });
46857
46880
  emit("UI:PLAY_SOUND", { key: "back" });
46858
- }, [emit]);
46881
+ if (removeEvent) emit(`UI:${removeEvent}`, { slotIndex: index });
46882
+ }, [emit, removeEvent]);
46859
46883
  const handleReset = useCallback(() => {
46860
46884
  if (timerRef.current) clearTimeout(timerRef.current);
46861
46885
  setSlots(Array.from({ length: maxSlots }, () => void 0));
@@ -46863,7 +46887,8 @@ function SequencerBoard({
46863
46887
  setCurrentStep(-1);
46864
46888
  setAttempts(0);
46865
46889
  setSlotFeedback(Array.from({ length: maxSlots }, () => null));
46866
- }, [maxSlots]);
46890
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
46891
+ }, [maxSlots, playAgainEvent, emit]);
46867
46892
  const filledSlots = slots.filter((s) => !!s);
46868
46893
  const canPlay = filledSlots.length > 0 && playState === "idle";
46869
46894
  const handlePlay = useCallback(() => {
@@ -46885,6 +46910,7 @@ function SequencerBoard({
46885
46910
  const success = solutions.some(
46886
46911
  (sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
46887
46912
  );
46913
+ if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
46888
46914
  if (success) {
46889
46915
  setPlayState("success");
46890
46916
  setCurrentStep(-1);
@@ -46912,7 +46938,7 @@ function SequencerBoard({
46912
46938
  }
46913
46939
  };
46914
46940
  timerRef.current = setTimeout(advance, stepDurationMs);
46915
- }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, emit]);
46941
+ }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, checkEvent, emit]);
46916
46942
  const machine = {
46917
46943
  name: str(resolved?.title),
46918
46944
  description: str(resolved?.description),
@@ -1,6 +1,9 @@
1
1
  import { type IconInput } from '../../core/atoms/Icon';
2
+ import type { AssetUrl } from '@almadar/core';
2
3
  export interface ItemSlotProps {
3
- /** Icon component or emoji */
4
+ /** Sprite image URL takes precedence over icon when provided */
5
+ assetUrl?: AssetUrl;
6
+ /** Icon component or emoji — shown only when assetUrl is absent */
4
7
  icon?: IconInput;
5
8
  /** Item label */
6
9
  label?: string;
@@ -19,7 +22,7 @@ export interface ItemSlotProps {
19
22
  /** Additional CSS classes */
20
23
  className?: string;
21
24
  }
22
- export declare function ItemSlot({ icon, label, quantity, rarity, empty, size, selected, onClick, className, }: ItemSlotProps): import("react/jsx-runtime").JSX.Element;
25
+ export declare function ItemSlot({ assetUrl, icon, label, quantity, rarity, empty, size, selected, onClick, className, }: ItemSlotProps): import("react/jsx-runtime").JSX.Element;
23
26
  export declare namespace ItemSlot {
24
27
  var displayName: string;
25
28
  }
@@ -14,7 +14,7 @@
14
14
  * @packageDocumentation
15
15
  */
16
16
  import * as React from 'react';
17
- import type { EntityRow } from '@almadar/core';
17
+ import type { EntityRow, EventEmit } from '@almadar/core';
18
18
  import { type BattleBoardProps } from './BattleBoard';
19
19
  import type { IsometricTile, IsometricUnit, IsometricFeature } from './types/isometric';
20
20
  export interface UncontrolledBattleBoardProps extends Omit<BattleBoardProps, 'entity'> {
@@ -27,6 +27,14 @@ export interface UncontrolledBattleBoardProps extends Omit<BattleBoardProps, 'en
27
27
  features?: IsometricFeature[];
28
28
  /** Direct asset manifest — takes priority over entity-derived manifest. */
29
29
  assetManifest?: BattleBoardProps['assetManifest'];
30
+ /** Emits UI:{stepEvent} with { attackerId, targetId, damage } each battle round */
31
+ stepEvent?: EventEmit<{
32
+ attackerId: string;
33
+ targetId: string;
34
+ damage: number;
35
+ }>;
36
+ /** Emits UI:{playAgainEvent} with {} on restart */
37
+ playAgainEvent?: EventEmit<Record<string, never>>;
30
38
  }
31
39
  export declare function UncontrolledBattleBoard({ entity, tiles, units, features, assetManifest, ...rest }: UncontrolledBattleBoardProps): React.JSX.Element | null;
32
40
  export declare namespace UncontrolledBattleBoard {
@@ -42,8 +42,23 @@ export interface SequencerBoardProps extends DisplayStateProps {
42
42
  success: boolean;
43
43
  sequence: string[];
44
44
  }>;
45
+ /** Emits UI:{placeEvent} with { slotIndex, actionId } when an action is dropped into a slot */
46
+ placeEvent?: EventEmit<{
47
+ slotIndex: number;
48
+ actionId: string;
49
+ }>;
50
+ /** Emits UI:{removeEvent} with { slotIndex } when an action is removed from a slot */
51
+ removeEvent?: EventEmit<{
52
+ slotIndex: number;
53
+ }>;
54
+ /** Emits UI:{checkEvent} with { sequence } when the player submits the sequence */
55
+ checkEvent?: EventEmit<{
56
+ sequence: string[];
57
+ }>;
58
+ /** Emits UI:{playAgainEvent} with {} on reset */
59
+ playAgainEvent?: EventEmit<Record<string, never>>;
45
60
  }
46
- export declare function SequencerBoard({ entity, categoryColors, stepDurationMs, playEvent, completeEvent, className, }: SequencerBoardProps): React.JSX.Element | null;
61
+ export declare function SequencerBoard({ entity, categoryColors, stepDurationMs, playEvent, completeEvent, placeEvent, removeEvent, checkEvent, playAgainEvent, className, }: SequencerBoardProps): React.JSX.Element | null;
47
62
  export declare namespace SequencerBoard {
48
63
  var displayName: string;
49
64
  }
@@ -20649,6 +20649,7 @@ var init_CounterTemplate = __esm({
20649
20649
  }
20650
20650
  });
20651
20651
  function ItemSlot({
20652
+ assetUrl = DEFAULT_ASSET_URL,
20652
20653
  icon = "sword",
20653
20654
  label = "Iron Sword",
20654
20655
  quantity,
@@ -20660,6 +20661,7 @@ function ItemSlot({
20660
20661
  className
20661
20662
  }) {
20662
20663
  const isClickable = onClick != null;
20664
+ const px = assetSizeMap[size];
20663
20665
  return /* @__PURE__ */ jsxRuntime.jsx(
20664
20666
  "button",
20665
20667
  {
@@ -20680,7 +20682,17 @@ function ItemSlot({
20680
20682
  className
20681
20683
  ),
20682
20684
  children: empty ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
20683
- icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon }) }),
20685
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
20686
+ "img",
20687
+ {
20688
+ src: assetUrl,
20689
+ alt: label,
20690
+ width: px,
20691
+ height: px,
20692
+ style: { imageRendering: "pixelated", objectFit: "contain" },
20693
+ className: "flex-shrink-0"
20694
+ }
20695
+ ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon }) }) : null,
20684
20696
  quantity != null && quantity > 1 && /* @__PURE__ */ jsxRuntime.jsx(
20685
20697
  "span",
20686
20698
  {
@@ -20696,7 +20708,7 @@ function ItemSlot({
20696
20708
  }
20697
20709
  );
20698
20710
  }
20699
- var sizeMap5, rarityBorderMap, rarityGlowMap;
20711
+ var sizeMap5, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL, assetSizeMap;
20700
20712
  var init_ItemSlot = __esm({
20701
20713
  "components/game/atoms/ItemSlot.tsx"() {
20702
20714
  "use client";
@@ -20721,6 +20733,12 @@ var init_ItemSlot = __esm({
20721
20733
  epic: "shadow-lg",
20722
20734
  legendary: "shadow-lg"
20723
20735
  };
20736
+ DEFAULT_ASSET_URL = "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png";
20737
+ assetSizeMap = {
20738
+ sm: 28,
20739
+ md: 40,
20740
+ lg: 56
20741
+ };
20724
20742
  ItemSlot.displayName = "ItemSlot";
20725
20743
  }
20726
20744
  });
@@ -45490,6 +45508,10 @@ function SequencerBoard({
45490
45508
  stepDurationMs = 1e3,
45491
45509
  playEvent,
45492
45510
  completeEvent,
45511
+ placeEvent,
45512
+ removeEvent,
45513
+ checkEvent,
45514
+ playAgainEvent,
45493
45515
  className
45494
45516
  }) {
45495
45517
  const { emit } = useEventBus();
@@ -45525,7 +45547,8 @@ function SequencerBoard({
45525
45547
  return next;
45526
45548
  });
45527
45549
  emit("UI:PLAY_SOUND", { key: "drop_slot" });
45528
- }, [emit]);
45550
+ if (placeEvent) emit(`UI:${placeEvent}`, { slotIndex: index, actionId: item.id });
45551
+ }, [emit, placeEvent]);
45529
45552
  const handleSlotRemove = React77.useCallback((index) => {
45530
45553
  setSlots((prev) => {
45531
45554
  const next = [...prev];
@@ -45538,7 +45561,8 @@ function SequencerBoard({
45538
45561
  return next;
45539
45562
  });
45540
45563
  emit("UI:PLAY_SOUND", { key: "back" });
45541
- }, [emit]);
45564
+ if (removeEvent) emit(`UI:${removeEvent}`, { slotIndex: index });
45565
+ }, [emit, removeEvent]);
45542
45566
  const handleReset = React77.useCallback(() => {
45543
45567
  if (timerRef.current) clearTimeout(timerRef.current);
45544
45568
  setSlots(Array.from({ length: maxSlots }, () => void 0));
@@ -45546,7 +45570,8 @@ function SequencerBoard({
45546
45570
  setCurrentStep(-1);
45547
45571
  setAttempts(0);
45548
45572
  setSlotFeedback(Array.from({ length: maxSlots }, () => null));
45549
- }, [maxSlots]);
45573
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
45574
+ }, [maxSlots, playAgainEvent, emit]);
45550
45575
  const filledSlots = slots.filter((s) => !!s);
45551
45576
  const canPlay = filledSlots.length > 0 && playState === "idle";
45552
45577
  const handlePlay = React77.useCallback(() => {
@@ -45568,6 +45593,7 @@ function SequencerBoard({
45568
45593
  const success = solutions.some(
45569
45594
  (sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
45570
45595
  );
45596
+ if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
45571
45597
  if (success) {
45572
45598
  setPlayState("success");
45573
45599
  setCurrentStep(-1);
@@ -45595,7 +45621,7 @@ function SequencerBoard({
45595
45621
  }
45596
45622
  };
45597
45623
  timerRef.current = setTimeout(advance, stepDurationMs);
45598
- }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, emit]);
45624
+ }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, checkEvent, emit]);
45599
45625
  const machine = {
45600
45626
  name: str(resolved?.title),
45601
45627
  description: str(resolved?.description),
@@ -20604,6 +20604,7 @@ var init_CounterTemplate = __esm({
20604
20604
  }
20605
20605
  });
20606
20606
  function ItemSlot({
20607
+ assetUrl = DEFAULT_ASSET_URL,
20607
20608
  icon = "sword",
20608
20609
  label = "Iron Sword",
20609
20610
  quantity,
@@ -20615,6 +20616,7 @@ function ItemSlot({
20615
20616
  className
20616
20617
  }) {
20617
20618
  const isClickable = onClick != null;
20619
+ const px = assetSizeMap[size];
20618
20620
  return /* @__PURE__ */ jsx(
20619
20621
  "button",
20620
20622
  {
@@ -20635,7 +20637,17 @@ function ItemSlot({
20635
20637
  className
20636
20638
  ),
20637
20639
  children: empty ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
20638
- icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }),
20640
+ assetUrl ? /* @__PURE__ */ jsx(
20641
+ "img",
20642
+ {
20643
+ src: assetUrl,
20644
+ alt: label,
20645
+ width: px,
20646
+ height: px,
20647
+ style: { imageRendering: "pixelated", objectFit: "contain" },
20648
+ className: "flex-shrink-0"
20649
+ }
20650
+ ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
20639
20651
  quantity != null && quantity > 1 && /* @__PURE__ */ jsx(
20640
20652
  "span",
20641
20653
  {
@@ -20651,7 +20663,7 @@ function ItemSlot({
20651
20663
  }
20652
20664
  );
20653
20665
  }
20654
- var sizeMap5, rarityBorderMap, rarityGlowMap;
20666
+ var sizeMap5, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL, assetSizeMap;
20655
20667
  var init_ItemSlot = __esm({
20656
20668
  "components/game/atoms/ItemSlot.tsx"() {
20657
20669
  "use client";
@@ -20676,6 +20688,12 @@ var init_ItemSlot = __esm({
20676
20688
  epic: "shadow-lg",
20677
20689
  legendary: "shadow-lg"
20678
20690
  };
20691
+ DEFAULT_ASSET_URL = "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png";
20692
+ assetSizeMap = {
20693
+ sm: 28,
20694
+ md: 40,
20695
+ lg: 56
20696
+ };
20679
20697
  ItemSlot.displayName = "ItemSlot";
20680
20698
  }
20681
20699
  });
@@ -45445,6 +45463,10 @@ function SequencerBoard({
45445
45463
  stepDurationMs = 1e3,
45446
45464
  playEvent,
45447
45465
  completeEvent,
45466
+ placeEvent,
45467
+ removeEvent,
45468
+ checkEvent,
45469
+ playAgainEvent,
45448
45470
  className
45449
45471
  }) {
45450
45472
  const { emit } = useEventBus();
@@ -45480,7 +45502,8 @@ function SequencerBoard({
45480
45502
  return next;
45481
45503
  });
45482
45504
  emit("UI:PLAY_SOUND", { key: "drop_slot" });
45483
- }, [emit]);
45505
+ if (placeEvent) emit(`UI:${placeEvent}`, { slotIndex: index, actionId: item.id });
45506
+ }, [emit, placeEvent]);
45484
45507
  const handleSlotRemove = useCallback((index) => {
45485
45508
  setSlots((prev) => {
45486
45509
  const next = [...prev];
@@ -45493,7 +45516,8 @@ function SequencerBoard({
45493
45516
  return next;
45494
45517
  });
45495
45518
  emit("UI:PLAY_SOUND", { key: "back" });
45496
- }, [emit]);
45519
+ if (removeEvent) emit(`UI:${removeEvent}`, { slotIndex: index });
45520
+ }, [emit, removeEvent]);
45497
45521
  const handleReset = useCallback(() => {
45498
45522
  if (timerRef.current) clearTimeout(timerRef.current);
45499
45523
  setSlots(Array.from({ length: maxSlots }, () => void 0));
@@ -45501,7 +45525,8 @@ function SequencerBoard({
45501
45525
  setCurrentStep(-1);
45502
45526
  setAttempts(0);
45503
45527
  setSlotFeedback(Array.from({ length: maxSlots }, () => null));
45504
- }, [maxSlots]);
45528
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
45529
+ }, [maxSlots, playAgainEvent, emit]);
45505
45530
  const filledSlots = slots.filter((s) => !!s);
45506
45531
  const canPlay = filledSlots.length > 0 && playState === "idle";
45507
45532
  const handlePlay = useCallback(() => {
@@ -45523,6 +45548,7 @@ function SequencerBoard({
45523
45548
  const success = solutions.some(
45524
45549
  (sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
45525
45550
  );
45551
+ if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
45526
45552
  if (success) {
45527
45553
  setPlayState("success");
45528
45554
  setCurrentStep(-1);
@@ -45550,7 +45576,7 @@ function SequencerBoard({
45550
45576
  }
45551
45577
  };
45552
45578
  timerRef.current = setTimeout(advance, stepDurationMs);
45553
- }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, emit]);
45579
+ }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, checkEvent, emit]);
45554
45580
  const machine = {
45555
45581
  name: str(resolved?.title),
45556
45582
  description: str(resolved?.description),
@@ -7575,6 +7575,7 @@ var init_ResourceCounter = __esm({
7575
7575
  }
7576
7576
  });
7577
7577
  function ItemSlot({
7578
+ assetUrl = DEFAULT_ASSET_URL,
7578
7579
  icon = "sword",
7579
7580
  label = "Iron Sword",
7580
7581
  quantity,
@@ -7586,6 +7587,7 @@ function ItemSlot({
7586
7587
  className
7587
7588
  }) {
7588
7589
  const isClickable = onClick != null;
7590
+ const px = assetSizeMap[size];
7589
7591
  return /* @__PURE__ */ jsxRuntime.jsx(
7590
7592
  "button",
7591
7593
  {
@@ -7606,7 +7608,17 @@ function ItemSlot({
7606
7608
  className
7607
7609
  ),
7608
7610
  children: empty ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7609
- icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }),
7611
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
7612
+ "img",
7613
+ {
7614
+ src: assetUrl,
7615
+ alt: label,
7616
+ width: px,
7617
+ height: px,
7618
+ style: { imageRendering: "pixelated", objectFit: "contain" },
7619
+ className: "flex-shrink-0"
7620
+ }
7621
+ ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }) : null,
7610
7622
  quantity != null && quantity > 1 && /* @__PURE__ */ jsxRuntime.jsx(
7611
7623
  "span",
7612
7624
  {
@@ -7622,7 +7634,7 @@ function ItemSlot({
7622
7634
  }
7623
7635
  );
7624
7636
  }
7625
- var sizeMap6, rarityBorderMap, rarityGlowMap;
7637
+ var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL, assetSizeMap;
7626
7638
  var init_ItemSlot = __esm({
7627
7639
  "components/game/atoms/ItemSlot.tsx"() {
7628
7640
  "use client";
@@ -7647,6 +7659,12 @@ var init_ItemSlot = __esm({
7647
7659
  epic: "shadow-lg",
7648
7660
  legendary: "shadow-lg"
7649
7661
  };
7662
+ DEFAULT_ASSET_URL = "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png";
7663
+ assetSizeMap = {
7664
+ sm: 28,
7665
+ md: 40,
7666
+ lg: 56
7667
+ };
7650
7668
  ItemSlot.displayName = "ItemSlot";
7651
7669
  }
7652
7670
  });
@@ -44766,6 +44784,10 @@ function SequencerBoard({
44766
44784
  stepDurationMs = 1e3,
44767
44785
  playEvent,
44768
44786
  completeEvent,
44787
+ placeEvent,
44788
+ removeEvent,
44789
+ checkEvent,
44790
+ playAgainEvent,
44769
44791
  className
44770
44792
  }) {
44771
44793
  const { emit } = useEventBus();
@@ -44801,7 +44823,8 @@ function SequencerBoard({
44801
44823
  return next;
44802
44824
  });
44803
44825
  emit("UI:PLAY_SOUND", { key: "drop_slot" });
44804
- }, [emit]);
44826
+ if (placeEvent) emit(`UI:${placeEvent}`, { slotIndex: index, actionId: item.id });
44827
+ }, [emit, placeEvent]);
44805
44828
  const handleSlotRemove = React83.useCallback((index) => {
44806
44829
  setSlots((prev) => {
44807
44830
  const next = [...prev];
@@ -44814,7 +44837,8 @@ function SequencerBoard({
44814
44837
  return next;
44815
44838
  });
44816
44839
  emit("UI:PLAY_SOUND", { key: "back" });
44817
- }, [emit]);
44840
+ if (removeEvent) emit(`UI:${removeEvent}`, { slotIndex: index });
44841
+ }, [emit, removeEvent]);
44818
44842
  const handleReset = React83.useCallback(() => {
44819
44843
  if (timerRef.current) clearTimeout(timerRef.current);
44820
44844
  setSlots(Array.from({ length: maxSlots }, () => void 0));
@@ -44822,7 +44846,8 @@ function SequencerBoard({
44822
44846
  setCurrentStep(-1);
44823
44847
  setAttempts(0);
44824
44848
  setSlotFeedback(Array.from({ length: maxSlots }, () => null));
44825
- }, [maxSlots]);
44849
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
44850
+ }, [maxSlots, playAgainEvent, emit]);
44826
44851
  const filledSlots = slots.filter((s) => !!s);
44827
44852
  const canPlay = filledSlots.length > 0 && playState === "idle";
44828
44853
  const handlePlay = React83.useCallback(() => {
@@ -44844,6 +44869,7 @@ function SequencerBoard({
44844
44869
  const success = solutions.some(
44845
44870
  (sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
44846
44871
  );
44872
+ if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
44847
44873
  if (success) {
44848
44874
  setPlayState("success");
44849
44875
  setCurrentStep(-1);
@@ -44871,7 +44897,7 @@ function SequencerBoard({
44871
44897
  }
44872
44898
  };
44873
44899
  timerRef.current = setTimeout(advance, stepDurationMs);
44874
- }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, emit]);
44900
+ }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, checkEvent, emit]);
44875
44901
  const machine = {
44876
44902
  name: str(resolved?.title),
44877
44903
  description: str(resolved?.description),
@@ -7529,6 +7529,7 @@ var init_ResourceCounter = __esm({
7529
7529
  }
7530
7530
  });
7531
7531
  function ItemSlot({
7532
+ assetUrl = DEFAULT_ASSET_URL,
7532
7533
  icon = "sword",
7533
7534
  label = "Iron Sword",
7534
7535
  quantity,
@@ -7540,6 +7541,7 @@ function ItemSlot({
7540
7541
  className
7541
7542
  }) {
7542
7543
  const isClickable = onClick != null;
7544
+ const px = assetSizeMap[size];
7543
7545
  return /* @__PURE__ */ jsx(
7544
7546
  "button",
7545
7547
  {
@@ -7560,7 +7562,17 @@ function ItemSlot({
7560
7562
  className
7561
7563
  ),
7562
7564
  children: empty ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7563
- icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }),
7565
+ assetUrl ? /* @__PURE__ */ jsx(
7566
+ "img",
7567
+ {
7568
+ src: assetUrl,
7569
+ alt: label,
7570
+ width: px,
7571
+ height: px,
7572
+ style: { imageRendering: "pixelated", objectFit: "contain" },
7573
+ className: "flex-shrink-0"
7574
+ }
7575
+ ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
7564
7576
  quantity != null && quantity > 1 && /* @__PURE__ */ jsx(
7565
7577
  "span",
7566
7578
  {
@@ -7576,7 +7588,7 @@ function ItemSlot({
7576
7588
  }
7577
7589
  );
7578
7590
  }
7579
- var sizeMap6, rarityBorderMap, rarityGlowMap;
7591
+ var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL, assetSizeMap;
7580
7592
  var init_ItemSlot = __esm({
7581
7593
  "components/game/atoms/ItemSlot.tsx"() {
7582
7594
  "use client";
@@ -7601,6 +7613,12 @@ var init_ItemSlot = __esm({
7601
7613
  epic: "shadow-lg",
7602
7614
  legendary: "shadow-lg"
7603
7615
  };
7616
+ DEFAULT_ASSET_URL = "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png";
7617
+ assetSizeMap = {
7618
+ sm: 28,
7619
+ md: 40,
7620
+ lg: 56
7621
+ };
7604
7622
  ItemSlot.displayName = "ItemSlot";
7605
7623
  }
7606
7624
  });
@@ -44720,6 +44738,10 @@ function SequencerBoard({
44720
44738
  stepDurationMs = 1e3,
44721
44739
  playEvent,
44722
44740
  completeEvent,
44741
+ placeEvent,
44742
+ removeEvent,
44743
+ checkEvent,
44744
+ playAgainEvent,
44723
44745
  className
44724
44746
  }) {
44725
44747
  const { emit } = useEventBus();
@@ -44755,7 +44777,8 @@ function SequencerBoard({
44755
44777
  return next;
44756
44778
  });
44757
44779
  emit("UI:PLAY_SOUND", { key: "drop_slot" });
44758
- }, [emit]);
44780
+ if (placeEvent) emit(`UI:${placeEvent}`, { slotIndex: index, actionId: item.id });
44781
+ }, [emit, placeEvent]);
44759
44782
  const handleSlotRemove = useCallback((index) => {
44760
44783
  setSlots((prev) => {
44761
44784
  const next = [...prev];
@@ -44768,7 +44791,8 @@ function SequencerBoard({
44768
44791
  return next;
44769
44792
  });
44770
44793
  emit("UI:PLAY_SOUND", { key: "back" });
44771
- }, [emit]);
44794
+ if (removeEvent) emit(`UI:${removeEvent}`, { slotIndex: index });
44795
+ }, [emit, removeEvent]);
44772
44796
  const handleReset = useCallback(() => {
44773
44797
  if (timerRef.current) clearTimeout(timerRef.current);
44774
44798
  setSlots(Array.from({ length: maxSlots }, () => void 0));
@@ -44776,7 +44800,8 @@ function SequencerBoard({
44776
44800
  setCurrentStep(-1);
44777
44801
  setAttempts(0);
44778
44802
  setSlotFeedback(Array.from({ length: maxSlots }, () => null));
44779
- }, [maxSlots]);
44803
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
44804
+ }, [maxSlots, playAgainEvent, emit]);
44780
44805
  const filledSlots = slots.filter((s) => !!s);
44781
44806
  const canPlay = filledSlots.length > 0 && playState === "idle";
44782
44807
  const handlePlay = useCallback(() => {
@@ -44798,6 +44823,7 @@ function SequencerBoard({
44798
44823
  const success = solutions.some(
44799
44824
  (sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
44800
44825
  );
44826
+ if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
44801
44827
  if (success) {
44802
44828
  setPlayState("success");
44803
44829
  setCurrentStep(-1);
@@ -44825,7 +44851,7 @@ function SequencerBoard({
44825
44851
  }
44826
44852
  };
44827
44853
  timerRef.current = setTimeout(advance, stepDurationMs);
44828
- }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, emit]);
44854
+ }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, checkEvent, emit]);
44829
44855
  const machine = {
44830
44856
  name: str(resolved?.title),
44831
44857
  description: str(resolved?.description),
@@ -7486,6 +7486,7 @@ var init_ResourceCounter = __esm({
7486
7486
  }
7487
7487
  });
7488
7488
  function ItemSlot({
7489
+ assetUrl = DEFAULT_ASSET_URL,
7489
7490
  icon = "sword",
7490
7491
  label = "Iron Sword",
7491
7492
  quantity,
@@ -7497,6 +7498,7 @@ function ItemSlot({
7497
7498
  className
7498
7499
  }) {
7499
7500
  const isClickable = onClick != null;
7501
+ const px = assetSizeMap[size];
7500
7502
  return /* @__PURE__ */ jsxRuntime.jsx(
7501
7503
  "button",
7502
7504
  {
@@ -7517,7 +7519,17 @@ function ItemSlot({
7517
7519
  className
7518
7520
  ),
7519
7521
  children: empty ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7520
- icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }),
7522
+ assetUrl ? /* @__PURE__ */ jsxRuntime.jsx(
7523
+ "img",
7524
+ {
7525
+ src: assetUrl,
7526
+ alt: label,
7527
+ width: px,
7528
+ height: px,
7529
+ style: { imageRendering: "pixelated", objectFit: "contain" },
7530
+ className: "flex-shrink-0"
7531
+ }
7532
+ ) : icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon }) }) : null,
7521
7533
  quantity != null && quantity > 1 && /* @__PURE__ */ jsxRuntime.jsx(
7522
7534
  "span",
7523
7535
  {
@@ -7533,7 +7545,7 @@ function ItemSlot({
7533
7545
  }
7534
7546
  );
7535
7547
  }
7536
- var sizeMap6, rarityBorderMap, rarityGlowMap;
7548
+ var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL, assetSizeMap;
7537
7549
  var init_ItemSlot = __esm({
7538
7550
  "components/game/atoms/ItemSlot.tsx"() {
7539
7551
  "use client";
@@ -7558,6 +7570,12 @@ var init_ItemSlot = __esm({
7558
7570
  epic: "shadow-lg",
7559
7571
  legendary: "shadow-lg"
7560
7572
  };
7573
+ DEFAULT_ASSET_URL = "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png";
7574
+ assetSizeMap = {
7575
+ sm: 28,
7576
+ md: 40,
7577
+ lg: 56
7578
+ };
7561
7579
  ItemSlot.displayName = "ItemSlot";
7562
7580
  }
7563
7581
  });
@@ -44352,6 +44370,10 @@ function SequencerBoard({
44352
44370
  stepDurationMs = 1e3,
44353
44371
  playEvent,
44354
44372
  completeEvent,
44373
+ placeEvent,
44374
+ removeEvent,
44375
+ checkEvent,
44376
+ playAgainEvent,
44355
44377
  className
44356
44378
  }) {
44357
44379
  const { emit } = useEventBus();
@@ -44387,7 +44409,8 @@ function SequencerBoard({
44387
44409
  return next;
44388
44410
  });
44389
44411
  emit("UI:PLAY_SOUND", { key: "drop_slot" });
44390
- }, [emit]);
44412
+ if (placeEvent) emit(`UI:${placeEvent}`, { slotIndex: index, actionId: item.id });
44413
+ }, [emit, placeEvent]);
44391
44414
  const handleSlotRemove = React82.useCallback((index) => {
44392
44415
  setSlots((prev) => {
44393
44416
  const next = [...prev];
@@ -44400,7 +44423,8 @@ function SequencerBoard({
44400
44423
  return next;
44401
44424
  });
44402
44425
  emit("UI:PLAY_SOUND", { key: "back" });
44403
- }, [emit]);
44426
+ if (removeEvent) emit(`UI:${removeEvent}`, { slotIndex: index });
44427
+ }, [emit, removeEvent]);
44404
44428
  const handleReset = React82.useCallback(() => {
44405
44429
  if (timerRef.current) clearTimeout(timerRef.current);
44406
44430
  setSlots(Array.from({ length: maxSlots }, () => void 0));
@@ -44408,7 +44432,8 @@ function SequencerBoard({
44408
44432
  setCurrentStep(-1);
44409
44433
  setAttempts(0);
44410
44434
  setSlotFeedback(Array.from({ length: maxSlots }, () => null));
44411
- }, [maxSlots]);
44435
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
44436
+ }, [maxSlots, playAgainEvent, emit]);
44412
44437
  const filledSlots = slots.filter((s) => !!s);
44413
44438
  const canPlay = filledSlots.length > 0 && playState === "idle";
44414
44439
  const handlePlay = React82.useCallback(() => {
@@ -44430,6 +44455,7 @@ function SequencerBoard({
44430
44455
  const success = solutions.some(
44431
44456
  (sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
44432
44457
  );
44458
+ if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
44433
44459
  if (success) {
44434
44460
  setPlayState("success");
44435
44461
  setCurrentStep(-1);
@@ -44457,7 +44483,7 @@ function SequencerBoard({
44457
44483
  }
44458
44484
  };
44459
44485
  timerRef.current = setTimeout(advance, stepDurationMs);
44460
- }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, emit]);
44486
+ }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, checkEvent, emit]);
44461
44487
  const machine = {
44462
44488
  name: str(resolved?.title),
44463
44489
  description: str(resolved?.description),
@@ -7440,6 +7440,7 @@ var init_ResourceCounter = __esm({
7440
7440
  }
7441
7441
  });
7442
7442
  function ItemSlot({
7443
+ assetUrl = DEFAULT_ASSET_URL,
7443
7444
  icon = "sword",
7444
7445
  label = "Iron Sword",
7445
7446
  quantity,
@@ -7451,6 +7452,7 @@ function ItemSlot({
7451
7452
  className
7452
7453
  }) {
7453
7454
  const isClickable = onClick != null;
7455
+ const px = assetSizeMap[size];
7454
7456
  return /* @__PURE__ */ jsx(
7455
7457
  "button",
7456
7458
  {
@@ -7471,7 +7473,17 @@ function ItemSlot({
7471
7473
  className
7472
7474
  ),
7473
7475
  children: empty ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-base", children: "+" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7474
- icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }),
7476
+ assetUrl ? /* @__PURE__ */ jsx(
7477
+ "img",
7478
+ {
7479
+ src: assetUrl,
7480
+ alt: label,
7481
+ width: px,
7482
+ height: px,
7483
+ style: { imageRendering: "pixelated", objectFit: "contain" },
7484
+ className: "flex-shrink-0"
7485
+ }
7486
+ ) : icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon }) : /* @__PURE__ */ jsx(Icon, { icon }) }) : null,
7475
7487
  quantity != null && quantity > 1 && /* @__PURE__ */ jsx(
7476
7488
  "span",
7477
7489
  {
@@ -7487,7 +7499,7 @@ function ItemSlot({
7487
7499
  }
7488
7500
  );
7489
7501
  }
7490
- var sizeMap6, rarityBorderMap, rarityGlowMap;
7502
+ var sizeMap6, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL, assetSizeMap;
7491
7503
  var init_ItemSlot = __esm({
7492
7504
  "components/game/atoms/ItemSlot.tsx"() {
7493
7505
  "use client";
@@ -7512,6 +7524,12 @@ var init_ItemSlot = __esm({
7512
7524
  epic: "shadow-lg",
7513
7525
  legendary: "shadow-lg"
7514
7526
  };
7527
+ DEFAULT_ASSET_URL = "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png";
7528
+ assetSizeMap = {
7529
+ sm: 28,
7530
+ md: 40,
7531
+ lg: 56
7532
+ };
7515
7533
  ItemSlot.displayName = "ItemSlot";
7516
7534
  }
7517
7535
  });
@@ -44306,6 +44324,10 @@ function SequencerBoard({
44306
44324
  stepDurationMs = 1e3,
44307
44325
  playEvent,
44308
44326
  completeEvent,
44327
+ placeEvent,
44328
+ removeEvent,
44329
+ checkEvent,
44330
+ playAgainEvent,
44309
44331
  className
44310
44332
  }) {
44311
44333
  const { emit } = useEventBus();
@@ -44341,7 +44363,8 @@ function SequencerBoard({
44341
44363
  return next;
44342
44364
  });
44343
44365
  emit("UI:PLAY_SOUND", { key: "drop_slot" });
44344
- }, [emit]);
44366
+ if (placeEvent) emit(`UI:${placeEvent}`, { slotIndex: index, actionId: item.id });
44367
+ }, [emit, placeEvent]);
44345
44368
  const handleSlotRemove = useCallback((index) => {
44346
44369
  setSlots((prev) => {
44347
44370
  const next = [...prev];
@@ -44354,7 +44377,8 @@ function SequencerBoard({
44354
44377
  return next;
44355
44378
  });
44356
44379
  emit("UI:PLAY_SOUND", { key: "back" });
44357
- }, [emit]);
44380
+ if (removeEvent) emit(`UI:${removeEvent}`, { slotIndex: index });
44381
+ }, [emit, removeEvent]);
44358
44382
  const handleReset = useCallback(() => {
44359
44383
  if (timerRef.current) clearTimeout(timerRef.current);
44360
44384
  setSlots(Array.from({ length: maxSlots }, () => void 0));
@@ -44362,7 +44386,8 @@ function SequencerBoard({
44362
44386
  setCurrentStep(-1);
44363
44387
  setAttempts(0);
44364
44388
  setSlotFeedback(Array.from({ length: maxSlots }, () => null));
44365
- }, [maxSlots]);
44389
+ if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
44390
+ }, [maxSlots, playAgainEvent, emit]);
44366
44391
  const filledSlots = slots.filter((s) => !!s);
44367
44392
  const canPlay = filledSlots.length > 0 && playState === "idle";
44368
44393
  const handlePlay = useCallback(() => {
@@ -44384,6 +44409,7 @@ function SequencerBoard({
44384
44409
  const success = solutions.some(
44385
44410
  (sol) => sol.length === playerIds.length && sol.every((id, i) => id === playerIds[i])
44386
44411
  );
44412
+ if (checkEvent) emit(`UI:${checkEvent}`, { sequence: playerIds });
44387
44413
  if (success) {
44388
44414
  setPlayState("success");
44389
44415
  setCurrentStep(-1);
@@ -44411,7 +44437,7 @@ function SequencerBoard({
44411
44437
  }
44412
44438
  };
44413
44439
  timerRef.current = setTimeout(advance, stepDurationMs);
44414
- }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, emit]);
44440
+ }, [canPlay, slots, maxSlots, solutions, stepDurationMs, playEvent, completeEvent, checkEvent, emit]);
44415
44441
  const machine = {
44416
44442
  name: str(resolved?.title),
44417
44443
  description: str(resolved?.description),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.40.0",
3
+ "version": "5.42.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [