@almadar/ui 5.70.0 → 5.72.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 (63) hide show
  1. package/dist/avl/index.cjs +2198 -2218
  2. package/dist/avl/index.d.cts +93 -56
  3. package/dist/avl/index.js +931 -951
  4. package/dist/components/avl/molecules/AvlEventWireEdge.d.ts +2 -1
  5. package/dist/components/avl/molecules/AvlTransitionEdge.d.ts +2 -1
  6. package/dist/components/avl/molecules/avl-behavior-compose-converter.d.ts +7 -5
  7. package/dist/components/avl/molecules/avl-behavior-compose-types.d.ts +41 -21
  8. package/dist/components/avl/molecules/avl-canvas-types.d.ts +10 -7
  9. package/dist/components/avl/molecules/avl-preview-converter.d.ts +5 -5
  10. package/dist/components/avl/molecules/avl-preview-types.d.ts +15 -4
  11. package/dist/components/avl/organisms/FlowCanvas.d.ts +2 -2
  12. package/dist/components/avl/organisms/avl-schema-parser.d.ts +18 -16
  13. package/dist/components/core/atoms/Button.d.ts +2 -0
  14. package/dist/components/core/atoms/ConditionalWrapper.d.ts +5 -4
  15. package/dist/components/core/molecules/Carousel.d.ts +2 -2
  16. package/dist/components/core/molecules/OrbitalVisualization.d.ts +4 -3
  17. package/dist/components/core/molecules/PageHeader.d.ts +3 -3
  18. package/dist/components/core/molecules/RepeatableFormSection.d.ts +4 -3
  19. package/dist/components/core/molecules/ViolationAlert.d.ts +2 -0
  20. package/dist/components/core/molecules/WizardContainer.d.ts +23 -22
  21. package/dist/components/core/organisms/CardGrid.d.ts +2 -2
  22. package/dist/components/core/organisms/CustomPattern.d.ts +3 -4
  23. package/dist/components/core/organisms/DataTable.d.ts +2 -2
  24. package/dist/components/core/organisms/DetailPanel.d.ts +1 -1
  25. package/dist/components/core/organisms/Form.d.ts +11 -11
  26. package/dist/components/core/organisms/List.d.ts +3 -5
  27. package/dist/components/core/organisms/StatCard.d.ts +2 -2
  28. package/dist/components/core/organisms/book/types.d.ts +1 -1
  29. package/dist/components/core/organisms/debug/RuntimeDebugger.d.ts +2 -1
  30. package/dist/components/core/organisms/debug/tabs/EventDispatcherTab.d.ts +2 -1
  31. package/dist/components/core/organisms/layout/DashboardGrid.d.ts +0 -2
  32. package/dist/components/core/organisms/types.d.ts +3 -2
  33. package/dist/components/game/atoms/ScoreDisplay.d.ts +3 -3
  34. package/dist/components/game/atoms/Sprite.d.ts +6 -1
  35. package/dist/components/game/atoms/XPBar.d.ts +1 -1
  36. package/dist/components/game/molecules/GameCanvas3D.d.ts +0 -2
  37. package/dist/components/game/molecules/IsometricCanvas.d.ts +4 -2
  38. package/dist/components/game/molecules/PlatformerCanvas.d.ts +4 -1
  39. package/dist/components/game/molecules/StatBadge.d.ts +3 -1
  40. package/dist/components/game/molecules/three/hooks/useSceneGraph.d.ts +2 -1
  41. package/dist/components/game/molecules/three/index.cjs +41 -105
  42. package/dist/components/game/molecules/three/index.js +41 -105
  43. package/dist/components/game/molecules/useUnitSpriteAtlas.d.ts +3 -2
  44. package/dist/components/game/organisms/PinballBoard.d.ts +4 -4
  45. package/dist/components/game/organisms/boardEntity.d.ts +6 -6
  46. package/dist/components/game/organisms/puzzles/debugger/DebuggerBoard.d.ts +16 -2
  47. package/dist/components/game/organisms/puzzles/event-handler/puzzleObject.d.ts +21 -10
  48. package/dist/components/game/organisms/puzzles/state-architect/StateJsonView.d.ts +2 -1
  49. package/dist/components/game/organisms/types/isometric.d.ts +16 -0
  50. package/dist/components/index.cjs +2228 -2251
  51. package/dist/components/index.js +1116 -1139
  52. package/dist/docs/index.cjs +107 -104
  53. package/dist/docs/index.d.cts +2 -0
  54. package/dist/docs/index.js +38 -35
  55. package/dist/lib/getNestedValue.d.ts +2 -13
  56. package/dist/marketing/index.cjs +97 -98
  57. package/dist/marketing/index.d.cts +2 -0
  58. package/dist/marketing/index.js +54 -55
  59. package/dist/providers/index.cjs +1908 -1951
  60. package/dist/providers/index.js +808 -851
  61. package/dist/runtime/index.cjs +1966 -2009
  62. package/dist/runtime/index.js +814 -857
  63. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
- import * as React86 from 'react';
2
- import React86__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useLayoutEffect, lazy, useId, useSyncExternalStore, forwardRef, useImperativeHandle, Component } from 'react';
1
+ import * as React88 from 'react';
2
+ import React88__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useLayoutEffect, lazy, useId, useSyncExternalStore, forwardRef, useImperativeHandle, Component } from 'react';
3
3
  import { EventBusContext, useTraitScope, TraitScopeProvider } from '@almadar/ui/providers';
4
4
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -403,7 +403,7 @@ var init_Box = __esm({
403
403
  fixed: "fixed",
404
404
  sticky: "sticky"
405
405
  };
406
- Box = React86__default.forwardRef(
406
+ Box = React88__default.forwardRef(
407
407
  ({
408
408
  padding,
409
409
  paddingX,
@@ -468,7 +468,7 @@ var init_Box = __esm({
468
468
  onPointerDown?.(e);
469
469
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
470
470
  const isClickable = action || onClick;
471
- return React86__default.createElement(
471
+ return React88__default.createElement(
472
472
  Component2,
473
473
  {
474
474
  ref,
@@ -564,7 +564,7 @@ function loadLib(key, importer) {
564
564
  return p2;
565
565
  }
566
566
  function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
567
- const Lazy = React86__default.lazy(async () => {
567
+ const Lazy = React88__default.lazy(async () => {
568
568
  const lib = await loadLib(libKey, importer);
569
569
  const Comp = pick(lib);
570
570
  if (!Comp) {
@@ -574,7 +574,7 @@ function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
574
574
  return { default: Comp };
575
575
  });
576
576
  const Wrapped = (props) => /* @__PURE__ */ jsx(
577
- React86__default.Suspense,
577
+ React88__default.Suspense,
578
578
  {
579
579
  fallback: /* @__PURE__ */ jsx(
580
580
  "span",
@@ -1242,9 +1242,10 @@ function resolveIcon(name) {
1242
1242
  function doResolve(name) {
1243
1243
  if (iconAliases[name]) return iconAliases[name];
1244
1244
  const pascalName = kebabToPascal2(name);
1245
- const directLookup = LucideIcons2[pascalName];
1245
+ const lucideMap = LucideIcons2;
1246
+ const directLookup = lucideMap[pascalName];
1246
1247
  if (directLookup && typeof directLookup === "object") return directLookup;
1247
- const asIs = LucideIcons2[name];
1248
+ const asIs = lucideMap[name];
1248
1249
  if (asIs && typeof asIs === "object") return asIs;
1249
1250
  return LucideIcons2.HelpCircle;
1250
1251
  }
@@ -1300,7 +1301,7 @@ var init_Icon = __esm({
1300
1301
  const directIcon = typeof icon === "string" ? void 0 : icon;
1301
1302
  const effectiveName = typeof icon === "string" ? icon : name;
1302
1303
  const family = useIconFamily();
1303
- const RenderedComponent = React86__default.useMemo(() => {
1304
+ const RenderedComponent = React88__default.useMemo(() => {
1304
1305
  if (directIcon) return null;
1305
1306
  return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
1306
1307
  }, [directIcon, effectiveName, family]);
@@ -1350,6 +1351,9 @@ var init_Icon = __esm({
1350
1351
  Icon.displayName = "Icon";
1351
1352
  }
1352
1353
  });
1354
+ function isIconLike(v) {
1355
+ return typeof v.render === "function";
1356
+ }
1353
1357
  function resolveIconProp(value, sizeClass) {
1354
1358
  if (!value) return null;
1355
1359
  if (typeof value === "string") {
@@ -1359,10 +1363,10 @@ function resolveIconProp(value, sizeClass) {
1359
1363
  const IconComp = value;
1360
1364
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1361
1365
  }
1362
- if (React86__default.isValidElement(value)) {
1366
+ if (React88__default.isValidElement(value)) {
1363
1367
  return value;
1364
1368
  }
1365
- if (typeof value === "object" && value !== null && "render" in value) {
1369
+ if (typeof value === "object" && value !== null && isIconLike(value)) {
1366
1370
  const IconComp = value;
1367
1371
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1368
1372
  }
@@ -1435,7 +1439,7 @@ var init_Button = __esm({
1435
1439
  md: "h-icon-default w-icon-default",
1436
1440
  lg: "h-icon-default w-icon-default"
1437
1441
  };
1438
- Button = React86__default.forwardRef(
1442
+ Button = React88__default.forwardRef(
1439
1443
  ({
1440
1444
  className,
1441
1445
  variant = "primary",
@@ -1451,6 +1455,7 @@ var init_Button = __esm({
1451
1455
  label,
1452
1456
  children,
1453
1457
  onClick,
1458
+ "data-testid": dataTestId,
1454
1459
  ...props
1455
1460
  }, ref) => {
1456
1461
  const eventBus = useEventBus();
@@ -1483,7 +1488,7 @@ var init_Button = __esm({
1483
1488
  ),
1484
1489
  onClick: handleClick,
1485
1490
  ...props,
1486
- "data-testid": props["data-testid"] ?? (action ? `action-${action}` : void 0),
1491
+ "data-testid": dataTestId ?? (action ? `action-${action}` : void 0),
1487
1492
  children: [
1488
1493
  isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-icon-default w-icon-default animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
1489
1494
  children || label,
@@ -1500,7 +1505,7 @@ var Dialog;
1500
1505
  var init_Dialog = __esm({
1501
1506
  "components/core/atoms/Dialog.tsx"() {
1502
1507
  init_cn();
1503
- Dialog = React86__default.forwardRef(
1508
+ Dialog = React88__default.forwardRef(
1504
1509
  ({
1505
1510
  role = "dialog",
1506
1511
  "aria-modal": ariaModal = true,
@@ -1618,9 +1623,8 @@ var init_Typography = __esm({
1618
1623
  }) => {
1619
1624
  const variant = variantProp ?? (level ? `h${level}` : "body1");
1620
1625
  const Component2 = as || defaultElements[variant];
1621
- const Comp = Component2;
1622
- return /* @__PURE__ */ jsx(
1623
- Comp,
1626
+ return React88__default.createElement(
1627
+ Component2,
1624
1628
  {
1625
1629
  id,
1626
1630
  className: cn(
@@ -1633,9 +1637,9 @@ var init_Typography = __esm({
1633
1637
  overflow && overflowStyles2[overflow],
1634
1638
  className
1635
1639
  ),
1636
- style,
1637
- children: children ?? content
1638
- }
1640
+ style
1641
+ },
1642
+ children ?? content
1639
1643
  );
1640
1644
  };
1641
1645
  Typography.displayName = "Typography";
@@ -2114,7 +2118,7 @@ var init_Badge = __esm({
2114
2118
  md: "px-2.5 py-1 text-sm",
2115
2119
  lg: "px-3 py-1.5 text-base"
2116
2120
  };
2117
- Badge = React86__default.forwardRef(
2121
+ Badge = React88__default.forwardRef(
2118
2122
  ({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
2119
2123
  const iconSizes3 = {
2120
2124
  sm: "h-icon-default w-icon-default",
@@ -2450,7 +2454,7 @@ var init_SvgFlow = __esm({
2450
2454
  width = 100,
2451
2455
  height = 100
2452
2456
  }) => {
2453
- const markerId = React86__default.useMemo(() => {
2457
+ const markerId = React88__default.useMemo(() => {
2454
2458
  flowIdCounter += 1;
2455
2459
  return `almadar-flow-arrow-${flowIdCounter}`;
2456
2460
  }, []);
@@ -3043,7 +3047,7 @@ var init_SvgRing = __esm({
3043
3047
  width = 100,
3044
3048
  height = 100
3045
3049
  }) => {
3046
- const gradientId = React86__default.useMemo(() => {
3050
+ const gradientId = React88__default.useMemo(() => {
3047
3051
  ringIdCounter += 1;
3048
3052
  return `almadar-ring-glow-${ringIdCounter}`;
3049
3053
  }, []);
@@ -3224,7 +3228,7 @@ var init_Input = __esm({
3224
3228
  init_cn();
3225
3229
  init_Icon();
3226
3230
  init_useEventBus();
3227
- Input = React86__default.forwardRef(
3231
+ Input = React88__default.forwardRef(
3228
3232
  ({
3229
3233
  className,
3230
3234
  inputType,
@@ -3384,7 +3388,7 @@ var Label;
3384
3388
  var init_Label = __esm({
3385
3389
  "components/core/atoms/Label.tsx"() {
3386
3390
  init_cn();
3387
- Label = React86__default.forwardRef(
3391
+ Label = React88__default.forwardRef(
3388
3392
  ({ className, required, children, ...props }, ref) => {
3389
3393
  return /* @__PURE__ */ jsxs(
3390
3394
  "label",
@@ -3411,7 +3415,7 @@ var init_Textarea = __esm({
3411
3415
  "components/core/atoms/Textarea.tsx"() {
3412
3416
  init_cn();
3413
3417
  init_useEventBus();
3414
- Textarea = React86__default.forwardRef(
3418
+ Textarea = React88__default.forwardRef(
3415
3419
  ({ className, error, onChange, ...props }, ref) => {
3416
3420
  const eventBus = useEventBus();
3417
3421
  const handleChange = (e) => {
@@ -3650,7 +3654,7 @@ var init_Select = __esm({
3650
3654
  init_cn();
3651
3655
  init_Icon();
3652
3656
  init_useEventBus();
3653
- Select = React86__default.forwardRef(
3657
+ Select = React88__default.forwardRef(
3654
3658
  (props, _ref) => {
3655
3659
  const { multiple, searchable, clearable } = props;
3656
3660
  if (multiple || searchable || clearable) {
@@ -3667,7 +3671,7 @@ var init_Checkbox = __esm({
3667
3671
  "components/core/atoms/Checkbox.tsx"() {
3668
3672
  init_cn();
3669
3673
  init_useEventBus();
3670
- Checkbox = React86__default.forwardRef(
3674
+ Checkbox = React88__default.forwardRef(
3671
3675
  ({ className, label, id, onChange, ...props }, ref) => {
3672
3676
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
3673
3677
  const eventBus = useEventBus();
@@ -3721,7 +3725,7 @@ var init_Spinner = __esm({
3721
3725
  md: "h-6 w-6",
3722
3726
  lg: "h-8 w-8"
3723
3727
  };
3724
- Spinner = React86__default.forwardRef(
3728
+ Spinner = React88__default.forwardRef(
3725
3729
  ({ className, size = "md", overlay, ...props }, ref) => {
3726
3730
  if (overlay) {
3727
3731
  return /* @__PURE__ */ jsx(
@@ -3811,7 +3815,7 @@ var init_Card = __esm({
3811
3815
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
3812
3816
  "tile-image-first": "p-0 overflow-hidden"
3813
3817
  };
3814
- Card = React86__default.forwardRef(
3818
+ Card = React88__default.forwardRef(
3815
3819
  ({
3816
3820
  className,
3817
3821
  variant = "bordered",
@@ -3859,9 +3863,9 @@ var init_Card = __esm({
3859
3863
  }
3860
3864
  );
3861
3865
  Card.displayName = "Card";
3862
- CardHeader = React86__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3866
+ CardHeader = React88__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3863
3867
  CardHeader.displayName = "CardHeader";
3864
- CardTitle = React86__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3868
+ CardTitle = React88__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3865
3869
  "h3",
3866
3870
  {
3867
3871
  ref,
@@ -3874,11 +3878,11 @@ var init_Card = __esm({
3874
3878
  }
3875
3879
  ));
3876
3880
  CardTitle.displayName = "CardTitle";
3877
- CardContent = React86__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3881
+ CardContent = React88__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3878
3882
  CardContent.displayName = "CardContent";
3879
3883
  CardBody = CardContent;
3880
3884
  CardBody.displayName = "CardBody";
3881
- CardFooter = React86__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3885
+ CardFooter = React88__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3882
3886
  "div",
3883
3887
  {
3884
3888
  ref,
@@ -3933,7 +3937,7 @@ var init_FilterPill = __esm({
3933
3937
  md: "w-3.5 h-3.5",
3934
3938
  lg: "w-4 h-4"
3935
3939
  };
3936
- FilterPill = React86__default.forwardRef(
3940
+ FilterPill = React88__default.forwardRef(
3937
3941
  ({
3938
3942
  className,
3939
3943
  variant = "default",
@@ -4062,8 +4066,8 @@ var init_Avatar = __esm({
4062
4066
  actionPayload
4063
4067
  }) => {
4064
4068
  const eventBus = useEventBus();
4065
- const [imgFailed, setImgFailed] = React86__default.useState(false);
4066
- React86__default.useEffect(() => {
4069
+ const [imgFailed, setImgFailed] = React88__default.useState(false);
4070
+ React88__default.useEffect(() => {
4067
4071
  setImgFailed(false);
4068
4072
  }, [src]);
4069
4073
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -4176,22 +4180,18 @@ var init_Center = __esm({
4176
4180
  as: Component2 = "div"
4177
4181
  }) => {
4178
4182
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
4179
- const Comp = Component2;
4180
- return /* @__PURE__ */ jsx(
4181
- Comp,
4182
- {
4183
- className: cn(
4184
- inline ? "inline-flex" : "flex",
4185
- horizontal && "justify-center",
4186
- vertical && "items-center",
4187
- fullHeight && "h-full",
4188
- fullWidth && "w-full",
4189
- className
4190
- ),
4191
- style: mergedStyle,
4192
- children
4193
- }
4194
- );
4183
+ return React88__default.createElement(Component2, {
4184
+ className: cn(
4185
+ inline ? "inline-flex" : "flex",
4186
+ horizontal && "justify-center",
4187
+ vertical && "items-center",
4188
+ fullHeight && "h-full",
4189
+ fullWidth && "w-full",
4190
+ className
4191
+ ),
4192
+ style: mergedStyle,
4193
+ children
4194
+ });
4195
4195
  };
4196
4196
  }
4197
4197
  });
@@ -4448,7 +4448,7 @@ var init_Radio = __esm({
4448
4448
  md: "w-2.5 h-2.5",
4449
4449
  lg: "w-3 h-3"
4450
4450
  };
4451
- Radio = React86__default.forwardRef(
4451
+ Radio = React88__default.forwardRef(
4452
4452
  ({
4453
4453
  label,
4454
4454
  helperText,
@@ -4465,12 +4465,12 @@ var init_Radio = __esm({
4465
4465
  onChange,
4466
4466
  ...props
4467
4467
  }, ref) => {
4468
- const reactId = React86__default.useId();
4468
+ const reactId = React88__default.useId();
4469
4469
  const baseId = id || `radio-${reactId}`;
4470
4470
  const hasError = !!error;
4471
4471
  const eventBus = useEventBus();
4472
- const [selected, setSelected] = React86__default.useState(value);
4473
- React86__default.useEffect(() => {
4472
+ const [selected, setSelected] = React88__default.useState(value);
4473
+ React88__default.useEffect(() => {
4474
4474
  if (value !== void 0) setSelected(value);
4475
4475
  }, [value]);
4476
4476
  const pick = (next, e) => {
@@ -4652,7 +4652,7 @@ var init_Switch = __esm({
4652
4652
  "components/core/atoms/Switch.tsx"() {
4653
4653
  "use client";
4654
4654
  init_cn();
4655
- Switch = React86.forwardRef(
4655
+ Switch = React88.forwardRef(
4656
4656
  ({
4657
4657
  checked,
4658
4658
  defaultChecked = false,
@@ -4663,10 +4663,10 @@ var init_Switch = __esm({
4663
4663
  name,
4664
4664
  className
4665
4665
  }, ref) => {
4666
- const [isChecked, setIsChecked] = React86.useState(
4666
+ const [isChecked, setIsChecked] = React88.useState(
4667
4667
  checked !== void 0 ? checked : defaultChecked
4668
4668
  );
4669
- React86.useEffect(() => {
4669
+ React88.useEffect(() => {
4670
4670
  if (checked !== void 0) {
4671
4671
  setIsChecked(checked);
4672
4672
  }
@@ -4825,9 +4825,8 @@ var init_Stack = __esm({
4825
4825
  };
4826
4826
  const isHorizontal = direction === "horizontal";
4827
4827
  const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
4828
- const Comp = Component2;
4829
- return /* @__PURE__ */ jsx(
4830
- Comp,
4828
+ return React88__default.createElement(
4829
+ Component2,
4831
4830
  {
4832
4831
  className: cn(
4833
4832
  "flex",
@@ -4843,9 +4842,9 @@ var init_Stack = __esm({
4843
4842
  onClick: action || onClick ? handleClick : void 0,
4844
4843
  onKeyDown,
4845
4844
  role,
4846
- tabIndex,
4847
- children
4848
- }
4845
+ tabIndex
4846
+ },
4847
+ children
4849
4848
  );
4850
4849
  };
4851
4850
  VStack = (props) => /* @__PURE__ */ jsx(Stack, { direction: "vertical", ...props });
@@ -5026,7 +5025,7 @@ var Aside;
5026
5025
  var init_Aside = __esm({
5027
5026
  "components/core/atoms/Aside.tsx"() {
5028
5027
  init_cn();
5029
- Aside = React86__default.forwardRef(
5028
+ Aside = React88__default.forwardRef(
5030
5029
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
5031
5030
  );
5032
5031
  Aside.displayName = "Aside";
@@ -5105,9 +5104,9 @@ var init_LawReferenceTooltip = __esm({
5105
5104
  className
5106
5105
  }) => {
5107
5106
  const { t } = useTranslate();
5108
- const [isVisible, setIsVisible] = React86__default.useState(false);
5109
- const timeoutRef = React86__default.useRef(null);
5110
- const triggerRef = React86__default.useRef(null);
5107
+ const [isVisible, setIsVisible] = React88__default.useState(false);
5108
+ const timeoutRef = React88__default.useRef(null);
5109
+ const triggerRef = React88__default.useRef(null);
5111
5110
  const handleMouseEnter = () => {
5112
5111
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5113
5112
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -5118,7 +5117,7 @@ var init_LawReferenceTooltip = __esm({
5118
5117
  };
5119
5118
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
5120
5119
  const open = isVisible || revealed;
5121
- React86__default.useEffect(() => {
5120
+ React88__default.useEffect(() => {
5122
5121
  return () => {
5123
5122
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5124
5123
  };
@@ -5330,7 +5329,7 @@ var init_StatusDot = __esm({
5330
5329
  md: "w-2.5 h-2.5",
5331
5330
  lg: "w-3 h-3"
5332
5331
  };
5333
- StatusDot = React86__default.forwardRef(
5332
+ StatusDot = React88__default.forwardRef(
5334
5333
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
5335
5334
  return /* @__PURE__ */ jsx(
5336
5335
  "span",
@@ -5384,7 +5383,7 @@ var init_TrendIndicator = __esm({
5384
5383
  down: "trending-down",
5385
5384
  flat: "arrow-right"
5386
5385
  };
5387
- TrendIndicator = React86__default.forwardRef(
5386
+ TrendIndicator = React88__default.forwardRef(
5388
5387
  ({
5389
5388
  className,
5390
5389
  value,
@@ -5451,7 +5450,7 @@ var init_RangeSlider = __esm({
5451
5450
  md: "w-4 h-4",
5452
5451
  lg: "w-5 h-5"
5453
5452
  };
5454
- RangeSlider = React86__default.forwardRef(
5453
+ RangeSlider = React88__default.forwardRef(
5455
5454
  ({
5456
5455
  className,
5457
5456
  min = 0,
@@ -5959,7 +5958,7 @@ var init_ContentSection = __esm({
5959
5958
  md: "py-16",
5960
5959
  lg: "py-24"
5961
5960
  };
5962
- ContentSection = React86__default.forwardRef(
5961
+ ContentSection = React88__default.forwardRef(
5963
5962
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
5964
5963
  return /* @__PURE__ */ jsx(
5965
5964
  Box,
@@ -6493,7 +6492,7 @@ var init_AnimatedReveal = __esm({
6493
6492
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
6494
6493
  "none": {}
6495
6494
  };
6496
- AnimatedReveal = React86__default.forwardRef(
6495
+ AnimatedReveal = React88__default.forwardRef(
6497
6496
  ({
6498
6497
  trigger = "scroll",
6499
6498
  animation = "fade-up",
@@ -6653,7 +6652,7 @@ var init_AnimatedGraphic = __esm({
6653
6652
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
6654
6653
  "use client";
6655
6654
  init_cn();
6656
- AnimatedGraphic = React86__default.forwardRef(
6655
+ AnimatedGraphic = React88__default.forwardRef(
6657
6656
  ({
6658
6657
  src,
6659
6658
  svgContent,
@@ -6676,7 +6675,7 @@ var init_AnimatedGraphic = __esm({
6676
6675
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
6677
6676
  const resolvedSvg = svgContent ?? fetchedSvg;
6678
6677
  const prevAnimateRef = useRef(animate);
6679
- const setRef = React86__default.useCallback(
6678
+ const setRef = React88__default.useCallback(
6680
6679
  (node) => {
6681
6680
  containerRef.current = node;
6682
6681
  if (typeof ref === "function") ref(node);
@@ -6893,48 +6892,21 @@ var init_HealthBar = __esm({
6893
6892
  function ScoreDisplay({
6894
6893
  assetUrl = DEFAULT_ASSET_URL,
6895
6894
  value,
6895
+ score,
6896
6896
  label,
6897
6897
  icon,
6898
6898
  size = "md",
6899
6899
  className,
6900
- animated = true,
6901
- locale = "en-US",
6902
- ...rest
6900
+ locale = "en-US"
6903
6901
  }) {
6904
- const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof rest.score === "number" && !Number.isNaN(rest.score) ? rest.score : 0;
6905
- const [displayValue, setDisplayValue] = React86.useState(resolvedValue);
6906
- const [isAnimating, setIsAnimating] = React86.useState(false);
6907
- React86.useEffect(() => {
6908
- if (!animated || displayValue === resolvedValue) {
6909
- setDisplayValue(resolvedValue);
6910
- return;
6911
- }
6912
- setIsAnimating(true);
6913
- const diff = resolvedValue - displayValue;
6914
- const steps = Math.min(Math.abs(diff), 20);
6915
- const increment = diff / steps;
6916
- let current = displayValue;
6917
- let step = 0;
6918
- const timer = setInterval(() => {
6919
- step++;
6920
- current += increment;
6921
- setDisplayValue(Math.round(current));
6922
- if (step >= steps) {
6923
- clearInterval(timer);
6924
- setDisplayValue(resolvedValue);
6925
- setIsAnimating(false);
6926
- }
6927
- }, 50);
6928
- return () => clearInterval(timer);
6929
- }, [resolvedValue, animated]);
6930
- const formattedValue = new Intl.NumberFormat(locale).format(displayValue);
6902
+ const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof score === "number" && !Number.isNaN(score) ? score : 0;
6903
+ const formattedValue = new Intl.NumberFormat(locale).format(resolvedValue);
6931
6904
  return /* @__PURE__ */ jsxs(
6932
6905
  "div",
6933
6906
  {
6934
6907
  className: cn(
6935
6908
  "flex items-center gap-2 font-bold",
6936
6909
  sizeMap2[size],
6937
- isAnimating && "animate-pulse",
6938
6910
  className
6939
6911
  ),
6940
6912
  children: [
@@ -6958,7 +6930,6 @@ function ScoreDisplay({
6958
6930
  var sizeMap2, DEFAULT_ASSET_URL;
6959
6931
  var init_ScoreDisplay = __esm({
6960
6932
  "components/game/atoms/ScoreDisplay.tsx"() {
6961
- "use client";
6962
6933
  init_cn();
6963
6934
  init_Icon();
6964
6935
  sizeMap2 = {
@@ -6987,9 +6958,9 @@ function ControlButton({
6987
6958
  className
6988
6959
  }) {
6989
6960
  const eventBus = useEventBus();
6990
- const [isPressed, setIsPressed] = React86.useState(false);
6961
+ const [isPressed, setIsPressed] = React88.useState(false);
6991
6962
  const actualPressed = pressed ?? isPressed;
6992
- const handlePointerDown = React86.useCallback(
6963
+ const handlePointerDown = React88.useCallback(
6993
6964
  (e) => {
6994
6965
  e.preventDefault();
6995
6966
  if (disabled) return;
@@ -6999,7 +6970,7 @@ function ControlButton({
6999
6970
  },
7000
6971
  [disabled, pressEvent, eventBus, onPress]
7001
6972
  );
7002
- const handlePointerUp = React86.useCallback(
6973
+ const handlePointerUp = React88.useCallback(
7003
6974
  (e) => {
7004
6975
  e.preventDefault();
7005
6976
  if (disabled) return;
@@ -7009,7 +6980,7 @@ function ControlButton({
7009
6980
  },
7010
6981
  [disabled, releaseEvent, eventBus, onRelease]
7011
6982
  );
7012
- const handlePointerLeave = React86.useCallback(
6983
+ const handlePointerLeave = React88.useCallback(
7013
6984
  (e) => {
7014
6985
  if (isPressed) {
7015
6986
  setIsPressed(false);
@@ -7097,13 +7068,6 @@ var init_spriteSheetConstants = __esm({
7097
7068
  });
7098
7069
 
7099
7070
  // components/game/organisms/utils/spriteAnimation.ts
7100
- function inferDirection(dx, dy) {
7101
- if (dx === 0 && dy === 0) return "se";
7102
- if (dx >= 0 && dy >= 0) return "se";
7103
- if (dx <= 0 && dy >= 0) return "sw";
7104
- if (dx >= 0 && dy <= 0) return "ne";
7105
- return "nw";
7106
- }
7107
7071
  function resolveSheetDirection(facing) {
7108
7072
  switch (facing) {
7109
7073
  case "se":
@@ -7124,19 +7088,6 @@ function frameRect(frame, row, columns, frameWidth, frameHeight) {
7124
7088
  sh: frameHeight
7125
7089
  };
7126
7090
  }
7127
- function getCurrentFrameFromDef(def, elapsed) {
7128
- const frameDuration = 1e3 / def.frameRate;
7129
- const totalDuration = def.frames * frameDuration;
7130
- if (def.loop) {
7131
- const frame2 = Math.floor(elapsed % totalDuration / frameDuration);
7132
- return { frame: frame2, finished: false };
7133
- }
7134
- if (elapsed >= totalDuration) {
7135
- return { frame: def.frames - 1, finished: true };
7136
- }
7137
- const frame = Math.floor(elapsed / frameDuration);
7138
- return { frame, finished: false };
7139
- }
7140
7091
  var init_spriteAnimation = __esm({
7141
7092
  "components/game/organisms/utils/spriteAnimation.ts"() {
7142
7093
  }
@@ -7155,6 +7106,8 @@ function Sprite({
7155
7106
  opacity = 1,
7156
7107
  zIndex = 0,
7157
7108
  columns = 16,
7109
+ animState: _animState,
7110
+ frameRate: _frameRate,
7158
7111
  className,
7159
7112
  onClick,
7160
7113
  action
@@ -7638,21 +7591,6 @@ function XPBar({
7638
7591
  }) {
7639
7592
  const sizes = sizeMap9[size];
7640
7593
  const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
7641
- const [fillWidth, setFillWidth] = React86.useState(animated ? 0 : percentage);
7642
- React86.useEffect(() => {
7643
- if (!animated) {
7644
- setFillWidth(percentage);
7645
- return;
7646
- }
7647
- let frame2;
7648
- const frame1 = requestAnimationFrame(() => {
7649
- frame2 = requestAnimationFrame(() => setFillWidth(percentage));
7650
- });
7651
- return () => {
7652
- cancelAnimationFrame(frame1);
7653
- cancelAnimationFrame(frame2);
7654
- };
7655
- }, [animated, percentage]);
7656
7594
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
7657
7595
  level != null && /* @__PURE__ */ jsxs(
7658
7596
  "span",
@@ -7684,7 +7622,7 @@ function XPBar({
7684
7622
  "bg-gradient-to-r from-accent to-info",
7685
7623
  animated && "transition-all duration-500 ease-out"
7686
7624
  ),
7687
- style: { width: `${fillWidth}%` }
7625
+ style: { width: `${percentage}%` }
7688
7626
  }
7689
7627
  )
7690
7628
  }
@@ -7701,7 +7639,6 @@ function XPBar({
7701
7639
  var sizeMap9;
7702
7640
  var init_XPBar = __esm({
7703
7641
  "components/game/atoms/XPBar.tsx"() {
7704
- "use client";
7705
7642
  init_cn();
7706
7643
  sizeMap9 = {
7707
7644
  sm: { bar: "h-2", text: "text-xs", badge: "text-xs px-1.5 py-0.5" },
@@ -8147,9 +8084,9 @@ function MiniMap({
8147
8084
  viewportRect = DEFAULT_VIEWPORT,
8148
8085
  className
8149
8086
  }) {
8150
- const canvasRef = React86.useRef(null);
8151
- const frameRef = React86.useRef(0);
8152
- React86.useEffect(() => {
8087
+ const canvasRef = React88.useRef(null);
8088
+ const frameRef = React88.useRef(0);
8089
+ React88.useEffect(() => {
8153
8090
  const canvas = canvasRef.current;
8154
8091
  if (!canvas) return;
8155
8092
  const ctx = canvas.getContext("2d");
@@ -8338,7 +8275,7 @@ var init_ErrorBoundary = __esm({
8338
8275
  }
8339
8276
  );
8340
8277
  };
8341
- ErrorBoundary = class extends React86__default.Component {
8278
+ ErrorBoundary = class extends React88__default.Component {
8342
8279
  constructor(props) {
8343
8280
  super(props);
8344
8281
  __publicField(this, "reset", () => {
@@ -9005,9 +8942,8 @@ var init_Container = __esm({
9005
8942
  as: Component2 = "div"
9006
8943
  }) => {
9007
8944
  const resolvedSize = maxWidth ?? size ?? "lg";
9008
- const Comp = Component2;
9009
- return /* @__PURE__ */ jsx(
9010
- Comp,
8945
+ return React88__default.createElement(
8946
+ Component2,
9011
8947
  {
9012
8948
  className: cn(
9013
8949
  "w-full",
@@ -9015,9 +8951,9 @@ var init_Container = __esm({
9015
8951
  paddingStyles3[padding],
9016
8952
  center && "mx-auto",
9017
8953
  className
9018
- ),
9019
- children
9020
- }
8954
+ )
8955
+ },
8956
+ children
9021
8957
  );
9022
8958
  };
9023
8959
  Container.displayName = "Container";
@@ -9729,8 +9665,8 @@ function ActionButtons({
9729
9665
  disabled
9730
9666
  }) {
9731
9667
  const eventBus = useEventBus();
9732
- const [activeButtons, setActiveButtons] = React86.useState(/* @__PURE__ */ new Set());
9733
- const handlePress = React86.useCallback(
9668
+ const [activeButtons, setActiveButtons] = React88.useState(/* @__PURE__ */ new Set());
9669
+ const handlePress = React88.useCallback(
9734
9670
  (id) => {
9735
9671
  setActiveButtons((prev) => new Set(prev).add(id));
9736
9672
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -9738,7 +9674,7 @@ function ActionButtons({
9738
9674
  },
9739
9675
  [actionEvent, eventBus, onAction]
9740
9676
  );
9741
- const handleRelease = React86.useCallback(
9677
+ const handleRelease = React88.useCallback(
9742
9678
  (id) => {
9743
9679
  setActiveButtons((prev) => {
9744
9680
  const next = new Set(prev);
@@ -10568,50 +10504,6 @@ var init_AuthLayout = __esm({
10568
10504
  AuthLayout.displayName = "AuthLayout";
10569
10505
  }
10570
10506
  });
10571
- var LoadingState;
10572
- var init_LoadingState = __esm({
10573
- "components/core/molecules/LoadingState.tsx"() {
10574
- "use client";
10575
- init_cn();
10576
- init_atoms2();
10577
- init_Stack();
10578
- init_Typography();
10579
- LoadingState = ({
10580
- title,
10581
- message,
10582
- className
10583
- }) => {
10584
- const { t } = useTranslate();
10585
- const displayMessage = message ?? t("common.loading");
10586
- return /* @__PURE__ */ jsxs(
10587
- VStack,
10588
- {
10589
- align: "center",
10590
- className: cn(
10591
- "justify-center py-12",
10592
- className
10593
- ),
10594
- children: [
10595
- /* @__PURE__ */ jsx(Spinner, { size: "lg" }),
10596
- title && /* @__PURE__ */ jsx(Typography, { variant: "h3", className: "mt-4 text-lg font-semibold text-foreground", children: title }),
10597
- /* @__PURE__ */ jsx(
10598
- Typography,
10599
- {
10600
- variant: "small",
10601
- className: cn(
10602
- "text-muted-foreground",
10603
- title ? "mt-2" : "mt-4"
10604
- ),
10605
- children: displayMessage
10606
- }
10607
- )
10608
- ]
10609
- }
10610
- );
10611
- };
10612
- LoadingState.displayName = "LoadingState";
10613
- }
10614
- });
10615
10507
  function getState() {
10616
10508
  if (typeof window !== "undefined") {
10617
10509
  const w = window;
@@ -11129,9 +11021,6 @@ function useUnitSpriteAtlas(units) {
11129
11021
  const loadingRef = useRef(/* @__PURE__ */ new Set());
11130
11022
  const [pendingCount, setPendingCount] = useState(0);
11131
11023
  const [, forceTick] = useState(0);
11132
- const animStatesRef = useRef(/* @__PURE__ */ new Map());
11133
- const lastTickRef = useRef(0);
11134
- const rafRef = useRef(0);
11135
11024
  const atlasUrls = useMemo(() => {
11136
11025
  const set = /* @__PURE__ */ new Set();
11137
11026
  for (const unit of units) {
@@ -11177,54 +11066,6 @@ function useUnitSpriteAtlas(units) {
11177
11066
  }
11178
11067
  return [...urls];
11179
11068
  }, [units, pendingCount]);
11180
- useEffect(() => {
11181
- const hasAtlasUnits = units.some((u) => unitAtlasUrl(u) !== null);
11182
- if (!hasAtlasUnits) return;
11183
- let running = true;
11184
- const tick = (ts) => {
11185
- if (!running) return;
11186
- const last = lastTickRef.current || ts;
11187
- const delta = ts - last;
11188
- lastTickRef.current = ts;
11189
- const states = animStatesRef.current;
11190
- const currentIds = /* @__PURE__ */ new Set();
11191
- for (const unit of units) {
11192
- if (unitAtlasUrl(unit) === null) continue;
11193
- currentIds.add(unit.id);
11194
- let state = states.get(unit.id);
11195
- if (!state) {
11196
- state = { animation: "idle", direction: "se", elapsed: 0, walkHold: 0, prev: null };
11197
- states.set(unit.id, state);
11198
- }
11199
- const posX = unit.position?.x ?? unit.x ?? 0;
11200
- const posY = unit.position?.y ?? unit.y ?? 0;
11201
- if (state.prev) {
11202
- const dx = posX - state.prev.x;
11203
- const dy = posY - state.prev.y;
11204
- if (dx !== 0 || dy !== 0) {
11205
- state.animation = "walk";
11206
- state.direction = inferDirection(dx, dy);
11207
- state.walkHold = WALK_HOLD_MS;
11208
- } else if (state.animation === "walk") {
11209
- state.walkHold -= delta;
11210
- if (state.walkHold <= 0) state.animation = "idle";
11211
- }
11212
- }
11213
- state.prev = { x: posX, y: posY };
11214
- state.elapsed += delta;
11215
- }
11216
- for (const id of states.keys()) {
11217
- if (!currentIds.has(id)) states.delete(id);
11218
- }
11219
- rafRef.current = requestAnimationFrame(tick);
11220
- };
11221
- rafRef.current = requestAnimationFrame(tick);
11222
- return () => {
11223
- running = false;
11224
- cancelAnimationFrame(rafRef.current);
11225
- lastTickRef.current = 0;
11226
- };
11227
- }, [units]);
11228
11069
  const resolveUnitFrame = useCallback((unitId) => {
11229
11070
  const unit = units.find((u) => u.id === unitId);
11230
11071
  if (!unit) return null;
@@ -11232,18 +11073,14 @@ function useUnitSpriteAtlas(units) {
11232
11073
  if (!atlasUrl) return null;
11233
11074
  const atlas = atlasCacheRef.current.get(atlasUrl);
11234
11075
  if (!atlas) return null;
11235
- const state = animStatesRef.current.get(unitId);
11236
- const animation = state?.animation ?? "idle";
11237
- const direction = state?.direction ?? "se";
11238
- const elapsed = state?.elapsed ?? 0;
11076
+ const animation = unit.animation ?? "idle";
11077
+ const frame = unit.frame ?? 0;
11239
11078
  const def = atlas.animations[animation] ?? atlas.animations.idle;
11240
11079
  if (!def) return null;
11241
- const { sheetDir, flipX } = resolveSheetDirection(direction);
11080
+ const { sheetDir, flipX } = resolveSheetDirection("se");
11242
11081
  const rel = atlas.sheets[sheetDir] ?? atlas.sheets.se ?? atlas.sheets.sw;
11243
11082
  if (!rel) return null;
11244
11083
  const sheetUrl = resolveSheetUrl(atlasUrl, rel);
11245
- const isIdle = animation === "idle";
11246
- const frame = isIdle ? 0 : getCurrentFrameFromDef(def, elapsed).frame;
11247
11084
  const rect = frameRect(frame, def.row, atlas.columns, atlas.frameWidth, atlas.frameHeight);
11248
11085
  return {
11249
11086
  sheetUrl,
@@ -11252,17 +11089,15 @@ function useUnitSpriteAtlas(units) {
11252
11089
  sw: rect.sw,
11253
11090
  sh: rect.sh,
11254
11091
  flipX,
11255
- applyBreathing: isIdle
11092
+ applyBreathing: animation === "idle"
11256
11093
  };
11257
11094
  }, [units]);
11258
11095
  return { sheetUrls, resolveUnitFrame, pendingCount };
11259
11096
  }
11260
- var WALK_HOLD_MS;
11261
11097
  var init_useUnitSpriteAtlas = __esm({
11262
11098
  "components/game/molecules/useUnitSpriteAtlas.ts"() {
11263
11099
  "use client";
11264
11100
  init_spriteAnimation();
11265
- WALK_HOLD_MS = 600;
11266
11101
  }
11267
11102
  });
11268
11103
 
@@ -11330,6 +11165,7 @@ function IsometricCanvas({
11330
11165
  tiles: _tilesPropRaw = [],
11331
11166
  units: _unitsPropRaw = [],
11332
11167
  features: _featuresPropRaw = [],
11168
+ effects: _effectsPropRaw = [],
11333
11169
  // Interaction state
11334
11170
  selectedUnitId = null,
11335
11171
  validMoves = [],
@@ -11362,7 +11198,7 @@ function IsometricCanvas({
11362
11198
  resolveUnitFrame,
11363
11199
  effectSpriteUrls = [],
11364
11200
  onDrawEffects,
11365
- hasActiveEffects: hasActiveEffects2 = false,
11201
+ hasActiveEffects: _hasActiveEffects = false,
11366
11202
  // Tuning
11367
11203
  diamondTopY: diamondTopYProp,
11368
11204
  // Remote asset loading
@@ -11372,13 +11208,12 @@ function IsometricCanvas({
11372
11208
  const tilesProp = Array.isArray(_tilesPropRaw) ? _tilesPropRaw : [];
11373
11209
  const unitsProp = Array.isArray(_unitsPropRaw) ? _unitsPropRaw : [];
11374
11210
  const featuresProp = Array.isArray(_featuresPropRaw) ? _featuresPropRaw : [];
11211
+ const effects = Array.isArray(_effectsPropRaw) ? _effectsPropRaw : [];
11375
11212
  const eventBus = useEventBus();
11376
11213
  const { t } = useTranslate();
11377
11214
  const canvasRef = useRef(null);
11378
11215
  const containerRef = useRef(null);
11379
- const minimapRef = useRef(null);
11380
- const animTimeRef = useRef(0);
11381
- const rafIdRef = useRef(0);
11216
+ const lerpRafRef = useRef(0);
11382
11217
  const [viewportSize, setViewportSize] = useState({ width: 800, height: 600 });
11383
11218
  useEffect(() => {
11384
11219
  const el = containerRef.current;
@@ -11402,7 +11237,7 @@ function IsometricCanvas({
11402
11237
  () => unitsProp.map((u) => u.position ? u : { ...u, position: { x: u.x ?? 0, y: u.y ?? 0 } }),
11403
11238
  [unitsProp]
11404
11239
  );
11405
- const { sheetUrls: atlasSheetUrls, resolveUnitFrame: resolveUnitFrameInternal, pendingCount: atlasPending } = useUnitSpriteAtlas(units);
11240
+ const { sheetUrls: atlasSheetUrls, resolveUnitFrame: resolveUnitFrameInternal } = useUnitSpriteAtlas(units);
11406
11241
  const resolveFrameForUnit = useCallback((unitId) => {
11407
11242
  return resolveUnitFrame?.(unitId) ?? resolveUnitFrameInternal(unitId);
11408
11243
  }, [resolveUnitFrame, resolveUnitFrameInternal]);
@@ -11497,7 +11332,7 @@ function IsometricCanvas({
11497
11332
  if (backgroundImage) urls.push(backgroundImage);
11498
11333
  return [...new Set(urls.filter(Boolean))];
11499
11334
  }, [sortedTiles, features, units, getTerrainSprite, getFeatureSprite, getUnitSprite, effectSpriteUrls, atlasSheetUrls, backgroundImage, assetManifest, resolveManifestUrl7]);
11500
- const { getImage, pendingCount } = useImageCache(spriteUrls);
11335
+ const { getImage, pendingCount: _imagePendingCount } = useImageCache(spriteUrls);
11501
11336
  useEffect(() => {
11502
11337
  if (typeof window === "undefined") return;
11503
11338
  const canvas = canvasRef.current;
@@ -11529,63 +11364,26 @@ function IsometricCanvas({
11529
11364
  const resolveUnitSpriteUrl = useCallback((unit) => {
11530
11365
  return unit.sprite || getUnitSprite?.(unit) || (unit.unitType ? resolveManifestUrl7(assetManifest?.units?.[unit.unitType]) : void 0);
11531
11366
  }, [getUnitSprite, assetManifest, resolveManifestUrl7]);
11532
- const drawMinimap = useCallback(() => {
11533
- if (!showMinimap) return;
11534
- const miniCanvas = minimapRef.current;
11535
- if (!miniCanvas || sortedTiles.length === 0) return;
11536
- const mCtx = miniCanvas.getContext("2d");
11537
- if (!mCtx) return;
11538
- const mW = 150;
11539
- const mH = 100;
11540
- miniCanvas.width = mW;
11541
- miniCanvas.height = mH;
11542
- mCtx.clearRect(0, 0, mW, mH);
11543
- const allScreenPos = sortedTiles.map((t2) => isoToScreen(t2.x, t2.y, scale, baseOffsetX, tileLayout));
11544
- const minX = Math.min(...allScreenPos.map((p2) => p2.x));
11545
- const maxX = Math.max(...allScreenPos.map((p2) => p2.x + scaledTileWidth));
11546
- const minY = Math.min(...allScreenPos.map((p2) => p2.y));
11547
- const tileBottomExtent = tileLayout === "hex" || tileLayout === "flat" ? scaledTileWidth : scaledTileHeight;
11548
- const maxY = Math.max(...allScreenPos.map((p2) => p2.y + tileBottomExtent));
11549
- const worldW = maxX - minX;
11550
- const worldH = maxY - minY;
11551
- const scaleM = Math.min(mW / worldW, mH / worldH) * 0.9;
11552
- const offsetMx = (mW - worldW * scaleM) / 2;
11553
- const offsetMy = (mH - worldH * scaleM) / 2;
11554
- for (const tile of sortedTiles) {
11555
- const pos = isoToScreen(tile.x, tile.y, scale, baseOffsetX, tileLayout);
11556
- const mx = (pos.x - minX) * scaleM + offsetMx;
11557
- const my = (pos.y - minY) * scaleM + offsetMy;
11558
- const mTileW = scaledTileWidth * scaleM;
11559
- const mFloorH = scaledFloorHeight * scaleM;
11560
- mCtx.fillStyle = tile.terrain === "water" ? "#3b82f6" : tile.terrain === "mountain" ? "#78716c" : "#4ade80";
11561
- mCtx.beginPath();
11562
- mCtx.moveTo(mx + mTileW / 2, my);
11563
- mCtx.lineTo(mx + mTileW, my + mFloorH / 2);
11564
- mCtx.lineTo(mx + mTileW / 2, my + mFloorH);
11565
- mCtx.lineTo(mx, my + mFloorH / 2);
11566
- mCtx.closePath();
11567
- mCtx.fill();
11568
- }
11569
- for (const unit of units) {
11570
- if (!unit.position) continue;
11571
- const pos = isoToScreen(unit.position.x, unit.position.y, scale, baseOffsetX, tileLayout);
11572
- const mx = (pos.x + scaledTileWidth / 2 - minX) * scaleM + offsetMx;
11573
- const my = (pos.y + scaledTileHeight / 2 - minY) * scaleM + offsetMy;
11574
- mCtx.fillStyle = unit.team === "player" ? "#60a5fa" : unit.team === "enemy" ? "#f87171" : "#9ca3af";
11575
- mCtx.beginPath();
11576
- mCtx.arc(mx, my, 3, 0, Math.PI * 2);
11577
- mCtx.fill();
11578
- }
11579
- const cam = cameraRef.current;
11580
- const vLeft = (cam.x - minX) * scaleM + offsetMx;
11581
- const vTop = (cam.y - minY) * scaleM + offsetMy;
11582
- const vW = viewportSize.width / cam.zoom * scaleM;
11583
- const vH = viewportSize.height / cam.zoom * scaleM;
11584
- mCtx.strokeStyle = "rgba(255, 255, 255, 0.8)";
11585
- mCtx.lineWidth = 1;
11586
- mCtx.strokeRect(vLeft, vTop, vW, vH);
11587
- }, [showMinimap, sortedTiles, units, tileLayout, scale, baseOffsetX, scaledTileWidth, scaledTileHeight, scaledFloorHeight, viewportSize, cameraRef]);
11588
- const draw = useCallback((animTime) => {
11367
+ const miniMapTiles = useMemo(() => {
11368
+ if (!showMinimap) return [];
11369
+ return sortedTiles.map((t2) => ({
11370
+ x: t2.x,
11371
+ y: t2.y,
11372
+ color: t2.terrain === "water" ? "#3b82f6" : t2.terrain === "mountain" ? "#78716c" : "#4ade80"
11373
+ }));
11374
+ }, [showMinimap, sortedTiles]);
11375
+ const miniMapUnits = useMemo(() => {
11376
+ if (!showMinimap) return [];
11377
+ return units.filter((u) => u.position).map((u) => ({
11378
+ x: u.position.x,
11379
+ y: u.position.y,
11380
+ color: u.team === "player" ? "#60a5fa" : u.team === "enemy" ? "#f87171" : "#9ca3af",
11381
+ isPlayer: u.team === "player"
11382
+ }));
11383
+ }, [showMinimap, units]);
11384
+ const miniMapWidth = gridWidth || 10;
11385
+ const miniMapHeight = gridHeight || 10;
11386
+ const draw = useCallback(() => {
11589
11387
  const canvas = canvasRef.current;
11590
11388
  if (!canvas) return;
11591
11389
  const ctx = canvas.getContext("2d");
@@ -11671,8 +11469,7 @@ function IsometricCanvas({
11671
11469
  if (validMoveSet.has(tileKey)) {
11672
11470
  const centerX = pos.x + scaledTileWidth / 2;
11673
11471
  const topY = pos.y + scaledDiamondTopY;
11674
- const pulse = 0.15 + 0.1 * Math.sin(animTime * 4e-3);
11675
- ctx.fillStyle = `rgba(74, 222, 128, ${pulse})`;
11472
+ ctx.fillStyle = "rgba(74, 222, 128, 0.25)";
11676
11473
  ctx.beginPath();
11677
11474
  ctx.moveTo(centerX, topY);
11678
11475
  ctx.lineTo(pos.x + scaledTileWidth, topY + scaledFloorHeight / 2);
@@ -11684,8 +11481,7 @@ function IsometricCanvas({
11684
11481
  if (attackTargetSet.has(tileKey)) {
11685
11482
  const centerX = pos.x + scaledTileWidth / 2;
11686
11483
  const topY = pos.y + scaledDiamondTopY;
11687
- const pulse = 0.2 + 0.15 * Math.sin(animTime * 5e-3);
11688
- ctx.fillStyle = `rgba(239, 68, 68, ${pulse})`;
11484
+ ctx.fillStyle = "rgba(239, 68, 68, 0.35)";
11689
11485
  ctx.beginPath();
11690
11486
  ctx.moveTo(centerX, topY);
11691
11487
  ctx.lineTo(pos.x + scaledTileWidth, topY + scaledFloorHeight / 2);
@@ -11758,7 +11554,7 @@ function IsometricCanvas({
11758
11554
  const isSelected = unit.id === selectedUnitId;
11759
11555
  const centerX = pos.x + scaledTileWidth / 2;
11760
11556
  const groundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
11761
- const breatheOffset = 0.8 * scale * (1 + Math.sin(animTime * 2e-3 + (unit.position.x * 3.7 + unit.position.y * 5.3)));
11557
+ const breatheOffset = 0;
11762
11558
  const unitSpriteUrl = resolveUnitSpriteUrl(unit);
11763
11559
  const img = unitSpriteUrl ? getImage(unitSpriteUrl) : null;
11764
11560
  const unitDrawH = scaledFloorHeight * spriteHeightRatio * unitScale;
@@ -11798,10 +11594,9 @@ function IsometricCanvas({
11798
11594
  ctx.restore();
11799
11595
  }
11800
11596
  if (isSelected) {
11801
- const ringAlpha = 0.6 + 0.3 * Math.sin(animTime * 4e-3);
11802
11597
  ctx.beginPath();
11803
11598
  ctx.ellipse(centerX, groundY, drawW / 2 + 4 * scale, 12 * scale, 0, 0, Math.PI * 2);
11804
- ctx.strokeStyle = `rgba(0, 200, 255, ${ringAlpha})`;
11599
+ ctx.strokeStyle = "rgba(0, 200, 255, 0.8)";
11805
11600
  ctx.lineWidth = 3;
11806
11601
  ctx.stroke();
11807
11602
  }
@@ -11857,66 +11652,29 @@ function IsometricCanvas({
11857
11652
  ctx.lineWidth = 2;
11858
11653
  ctx.stroke();
11859
11654
  }
11860
- if (unit.name) {
11861
- const labelBg = unit.team === "player" ? "rgba(59, 130, 246, 0.9)" : unit.team === "enemy" ? "rgba(239, 68, 68, 0.9)" : "rgba(107, 114, 128, 0.9)";
11862
- ctx.font = `bold ${10 * scale * 2.5}px system-ui`;
11863
- ctx.textAlign = "center";
11864
- const textWidth = ctx.measureText(unit.name).width;
11865
- const labelY = groundY + 14 * scale - breatheOffset;
11866
- ctx.fillStyle = labelBg;
11867
- ctx.beginPath();
11868
- ctx.roundRect(centerX - textWidth / 2 - 6 * scale, labelY - 8 * scale, textWidth + 12 * scale, 16 * scale, 4 * scale);
11869
- ctx.fill();
11870
- ctx.fillStyle = "white";
11871
- ctx.fillText(unit.name, centerX, labelY + 4 * scale);
11872
- }
11873
- if (unit.health !== void 0 && unit.maxHealth !== void 0) {
11874
- const barWidth = 40 * scale;
11875
- const barHeight = 6 * scale;
11876
- const barX = centerX - barWidth / 2;
11877
- const barY = groundY - drawH - 2 * scale - breatheOffset;
11878
- const healthRatio = unit.health / unit.maxHealth;
11879
- const barRadius = barHeight / 2;
11880
- ctx.fillStyle = "rgba(0, 0, 0, 0.7)";
11881
- ctx.beginPath();
11882
- ctx.roundRect(barX, barY, barWidth, barHeight, barRadius);
11883
- ctx.fill();
11884
- if (healthRatio > 0) {
11885
- const fillWidth = barWidth * healthRatio;
11886
- const gradient = ctx.createLinearGradient(barX, barY, barX, barY + barHeight);
11887
- if (healthRatio > 0.6) {
11888
- gradient.addColorStop(0, "#4ade80");
11889
- gradient.addColorStop(1, "#22c55e");
11890
- } else if (healthRatio > 0.3) {
11891
- gradient.addColorStop(0, "#fde047");
11892
- gradient.addColorStop(1, "#eab308");
11893
- } else {
11894
- gradient.addColorStop(0, "#f87171");
11895
- gradient.addColorStop(1, "#ef4444");
11896
- }
11897
- ctx.fillStyle = gradient;
11898
- ctx.save();
11899
- ctx.beginPath();
11900
- ctx.roundRect(barX, barY, fillWidth, barHeight, barRadius);
11901
- ctx.clip();
11902
- ctx.fillRect(barX, barY, fillWidth, barHeight);
11903
- ctx.restore();
11904
- }
11905
- ctx.strokeStyle = "rgba(255, 255, 255, 0.3)";
11906
- ctx.lineWidth = 1;
11907
- ctx.beginPath();
11908
- ctx.roundRect(barX, barY, barWidth, barHeight, barRadius);
11909
- ctx.stroke();
11910
- }
11911
11655
  }
11912
- onDrawEffects?.(ctx, animTime, getImage);
11656
+ for (const fx of effects) {
11657
+ const spriteUrl = resolveManifestUrl7(assetManifest?.effects?.[fx.key]);
11658
+ if (!spriteUrl) continue;
11659
+ const img = getImage(spriteUrl);
11660
+ if (!img) continue;
11661
+ const pos = isoToScreen(fx.x, fx.y, scale, baseOffsetX, tileLayout);
11662
+ const cx = pos.x + scaledTileWidth / 2;
11663
+ const cy = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
11664
+ const alpha = Math.min(1, fx.ttl / 4);
11665
+ const prev = ctx.globalAlpha;
11666
+ ctx.globalAlpha = alpha;
11667
+ ctx.drawImage(img, cx - img.naturalWidth / 2, cy - img.naturalHeight / 2);
11668
+ ctx.globalAlpha = prev;
11669
+ }
11670
+ onDrawEffects?.(ctx, 0, getImage);
11913
11671
  ctx.restore();
11914
- drawMinimap();
11915
11672
  }, [
11916
11673
  sortedTiles,
11917
11674
  units,
11918
11675
  features,
11919
11676
  selectedUnitId,
11677
+ effects,
11920
11678
  tileLayout,
11921
11679
  scale,
11922
11680
  debug2,
@@ -11936,11 +11694,12 @@ function IsometricCanvas({
11936
11694
  attackTargetSet,
11937
11695
  hoveredTile,
11938
11696
  viewportSize,
11939
- drawMinimap,
11940
11697
  onDrawEffects,
11941
11698
  backgroundImage,
11942
11699
  cameraRef,
11943
- unitScale
11700
+ unitScale,
11701
+ resolveManifestUrl7,
11702
+ assetManifest
11944
11703
  ]);
11945
11704
  useEffect(() => {
11946
11705
  if (!selectedUnitId) return;
@@ -11955,30 +11714,33 @@ function IsometricCanvas({
11955
11714
  };
11956
11715
  }, [selectedUnitId, units, tileLayout, scale, baseOffsetX, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, targetCameraRef]);
11957
11716
  useEffect(() => {
11958
- const hasAnimations = units.length > 0 || validMoves.length > 0 || attackTargets.length > 0 || selectedUnitId != null || targetCameraRef.current != null || hasActiveEffects2 || pendingCount > 0 || atlasPending > 0;
11959
- draw(animTimeRef.current);
11960
- if (!hasAnimations) return;
11717
+ draw();
11718
+ }, [draw]);
11719
+ useEffect(() => {
11720
+ draw();
11721
+ }, [_imagePendingCount]);
11722
+ useEffect(() => {
11723
+ if (selectedUnitId == null) return;
11961
11724
  let running = true;
11962
- const animate = (timestamp) => {
11725
+ const tick = () => {
11963
11726
  if (!running) return;
11964
- animTimeRef.current = timestamp;
11965
- lerpToTarget();
11966
- draw(timestamp);
11967
- rafIdRef.current = requestAnimationFrame(animate);
11727
+ const stillLerping = lerpToTarget();
11728
+ draw();
11729
+ if (stillLerping) lerpRafRef.current = requestAnimationFrame(tick);
11968
11730
  };
11969
- rafIdRef.current = requestAnimationFrame(animate);
11731
+ lerpRafRef.current = requestAnimationFrame(tick);
11970
11732
  return () => {
11971
11733
  running = false;
11972
- cancelAnimationFrame(rafIdRef.current);
11734
+ cancelAnimationFrame(lerpRafRef.current);
11973
11735
  };
11974
- }, [draw, units.length, validMoves.length, attackTargets.length, selectedUnitId, hasActiveEffects2, pendingCount, atlasPending, lerpToTarget, targetCameraRef]);
11736
+ }, [selectedUnitId, lerpToTarget, draw]);
11975
11737
  const singlePointerActiveRef = useRef(false);
11976
11738
  const handleCanvasPointerDown = useCallback((e) => {
11977
11739
  singlePointerActiveRef.current = true;
11978
11740
  if (enableCamera) handlePointerDown(e);
11979
11741
  }, [enableCamera, handlePointerDown]);
11980
11742
  const handleCanvasPointerMove = useCallback((e) => {
11981
- if (enableCamera) handlePointerMove(e, () => draw(animTimeRef.current));
11743
+ if (enableCamera) handlePointerMove(e, () => draw());
11982
11744
  }, [enableCamera, handlePointerMove, draw]);
11983
11745
  const handleCanvasHover = useCallback((e) => {
11984
11746
  if (singlePointerActiveRef.current) return;
@@ -12020,10 +11782,10 @@ function IsometricCanvas({
12020
11782
  onTileLeave?.();
12021
11783
  }, [handleMouseLeave, onTileLeave, tileLeaveEvent, eventBus]);
12022
11784
  const applyZoom = useCallback((factor, centerX, centerY) => {
12023
- if (enableCamera) zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw(animTimeRef.current));
11785
+ if (enableCamera) zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw());
12024
11786
  }, [enableCamera, zoomAtPoint, viewportSize, draw]);
12025
11787
  const applyPanDelta = useCallback((dx, dy) => {
12026
- if (enableCamera) panBy(dx, dy, () => draw(animTimeRef.current));
11788
+ if (enableCamera) panBy(dx, dy, () => draw());
12027
11789
  }, [enableCamera, panBy, draw]);
12028
11790
  const cancelSinglePointer = useCallback(() => {
12029
11791
  singlePointerActiveRef.current = false;
@@ -12039,11 +11801,27 @@ function IsometricCanvas({
12039
11801
  onPanDelta: applyPanDelta,
12040
11802
  onMultiTouchStart: cancelSinglePointer
12041
11803
  });
11804
+ const unitOverlays = useMemo(() => {
11805
+ if (sortedTiles.length === 0) return [];
11806
+ return units.filter((u) => !!u.position).map((u) => {
11807
+ const pos = isoToScreen(u.position.x, u.position.y, scale, baseOffsetX, tileLayout);
11808
+ const cam = cameraRef.current;
11809
+ const screenX = (pos.x + scaledTileWidth / 2 - (cam.x + viewportSize.width / 2)) * cam.zoom + viewportSize.width / 2;
11810
+ const screenY = (pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5 - (cam.y + viewportSize.height / 2)) * cam.zoom + viewportSize.height / 2;
11811
+ return { unit: u, screenX, screenY };
11812
+ });
11813
+ }, [units, sortedTiles.length, scale, baseOffsetX, tileLayout, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, cameraRef]);
12042
11814
  if (error) {
12043
- return /* @__PURE__ */ jsx(ErrorState, { title: t("canvas.errorTitle"), message: error.message, className });
11815
+ return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center w-full h-full bg-[var(--color-card)] rounded-container", className), children: /* @__PURE__ */ jsxs(Stack, { direction: "vertical", gap: "md", align: "center", children: [
11816
+ /* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: "xl" }),
11817
+ /* @__PURE__ */ jsx(Typography, { variant: "body", className: "text-error", children: error.message })
11818
+ ] }) });
12044
11819
  }
12045
11820
  if (isLoading) {
12046
- return /* @__PURE__ */ jsx(LoadingState, { className });
11821
+ return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center w-full h-full bg-[var(--color-card)] rounded-container", className), children: /* @__PURE__ */ jsxs(Stack, { direction: "vertical", gap: "md", align: "center", children: [
11822
+ /* @__PURE__ */ jsx(Icon, { name: "loader", size: "xl", className: "animate-spin" }),
11823
+ /* @__PURE__ */ jsx(Typography, { variant: "body", className: "text-muted-foreground", children: t("canvas.loadingMessage") || "Loading\u2026" })
11824
+ ] }) });
12047
11825
  }
12048
11826
  if (sortedTiles.length === 0) {
12049
11827
  return /* @__PURE__ */ jsx(
@@ -12108,14 +11886,36 @@ function IsometricCanvas({
12108
11886
  }
12109
11887
  )
12110
11888
  ] }),
12111
- showMinimap && /* @__PURE__ */ jsx(
12112
- "canvas",
11889
+ unitOverlays.map(({ unit, screenX, screenY }) => /* @__PURE__ */ jsxs(
11890
+ "div",
11891
+ {
11892
+ className: "absolute pointer-events-none",
11893
+ style: { left: Math.round(screenX), top: Math.round(screenY), transform: "translate(-50%, 0)", zIndex: 5 },
11894
+ children: [
11895
+ unit.name && /* @__PURE__ */ jsx(
11896
+ "div",
11897
+ {
11898
+ className: "text-white text-xs font-bold px-1.5 py-0.5 rounded mb-0.5 whitespace-nowrap",
11899
+ style: { background: unit.team === "player" ? "rgba(59,130,246,0.9)" : unit.team === "enemy" ? "rgba(239,68,68,0.9)" : "rgba(107,114,128,0.9)" },
11900
+ children: unit.name
11901
+ }
11902
+ ),
11903
+ unit.health !== void 0 && unit.maxHealth !== void 0 && unit.maxHealth > 0 && /* @__PURE__ */ jsx(HealthBar, { current: unit.health, max: unit.maxHealth, format: "bar", size: "sm" })
11904
+ ]
11905
+ },
11906
+ unit.id
11907
+ )),
11908
+ showMinimap && /* @__PURE__ */ jsx("div", { className: "absolute bottom-2 right-2 pointer-events-none", style: { zIndex: 10 }, children: /* @__PURE__ */ jsx(
11909
+ MiniMap,
12113
11910
  {
12114
- ref: minimapRef,
12115
- className: "absolute bottom-2 right-2 border border-border rounded bg-background/80 pointer-events-none",
12116
- style: { width: 150, height: 100, zIndex: 10 }
11911
+ tiles: miniMapTiles,
11912
+ units: miniMapUnits,
11913
+ width: 150,
11914
+ height: 100,
11915
+ mapWidth: miniMapWidth,
11916
+ mapHeight: miniMapHeight
12117
11917
  }
12118
- )
11918
+ ) })
12119
11919
  ]
12120
11920
  }
12121
11921
  );
@@ -12130,8 +11930,8 @@ var init_IsometricCanvas = __esm({
12130
11930
  init_Stack();
12131
11931
  init_Icon();
12132
11932
  init_Typography();
12133
- init_LoadingState();
12134
- init_ErrorState();
11933
+ init_MiniMap();
11934
+ init_HealthBar();
12135
11935
  init_useImageCache();
12136
11936
  init_useCamera();
12137
11937
  init_useCanvasGestures();
@@ -12225,9 +12025,37 @@ function BattleBoard({
12225
12025
  className
12226
12026
  }) {
12227
12027
  const board = boardEntity(entity) ?? {};
12228
- const rawTiles = propTiles ?? (Array.isArray(board.tiles) ? board.tiles : []);
12028
+ function asFieldObj(v) {
12029
+ if (v === null || typeof v !== "object" || Array.isArray(v) || v instanceof Date) return null;
12030
+ return v;
12031
+ }
12032
+ const rawTiles = propTiles ?? (Array.isArray(board.tiles) ? board.tiles.flatMap((v) => {
12033
+ const o = asFieldObj(v);
12034
+ if (o === null || typeof o.x !== "number" || typeof o.y !== "number") return [];
12035
+ const tile = { x: o.x, y: o.y };
12036
+ if (typeof o.terrain === "string") tile.terrain = o.terrain;
12037
+ if (typeof o.terrainSprite === "string") tile.terrainSprite = o.terrainSprite;
12038
+ if (typeof o.passable === "boolean") tile.passable = o.passable;
12039
+ if (typeof o.movementCost === "number") tile.movementCost = o.movementCost;
12040
+ if (typeof o.elevation === "number") tile.elevation = o.elevation;
12041
+ if (typeof o.type === "string") tile.type = o.type;
12042
+ if (typeof o.tileType === "string") tile.tileType = o.tileType;
12043
+ if (typeof o.id === "string") tile.id = o.id;
12044
+ if (typeof o.modelUrl === "string") tile.modelUrl = o.modelUrl;
12045
+ return [tile];
12046
+ }) : []);
12229
12047
  const tiles = rawTiles.length === 0 ? DEFAULT_BATTLE_TILES : rawTiles;
12230
- const features = propFeatures ?? (Array.isArray(board.features) ? board.features : []);
12048
+ const features = propFeatures ?? (Array.isArray(board.features) ? board.features.flatMap((v) => {
12049
+ const o = asFieldObj(v);
12050
+ if (o === null || typeof o.type !== "string" || typeof o.x !== "number" || typeof o.y !== "number") return [];
12051
+ const feat = { type: o.type, x: o.x, y: o.y };
12052
+ if (typeof o.id === "string") feat.id = o.id;
12053
+ if (typeof o.sprite === "string") feat.sprite = o.sprite;
12054
+ if (typeof o.color === "string") feat.color = o.color;
12055
+ if (typeof o.elevation === "number") feat.elevation = o.elevation;
12056
+ if (typeof o.assetUrl === "string") feat.assetUrl = o.assetUrl;
12057
+ return [feat];
12058
+ }) : []);
12231
12059
  const boardWidth = num(board.gridWidth ?? board.boardWidth, BATTLE_GRID_W);
12232
12060
  const boardHeight = num(board.gridHeight ?? board.boardHeight, BATTLE_GRID_H);
12233
12061
  const assetManifest = propAssetManifest ?? board.assetManifest;
@@ -12326,7 +12154,12 @@ function BattleBoard({
12326
12154
  return units.filter((u) => unitHealth(u) > 0).map((unit) => {
12327
12155
  const id = str(unit.id);
12328
12156
  const pos = movingPositions.get(id) ?? unitPosition(unit);
12329
- const unitTraits = Array.isArray(unit.traits) ? unit.traits : void 0;
12157
+ const unitTraits = Array.isArray(unit.traits) ? unit.traits.flatMap((v) => {
12158
+ const o = asFieldObj(v);
12159
+ if (o === null || typeof o.name !== "string" || typeof o.currentState !== "string" || !Array.isArray(o.states)) return [];
12160
+ const stateNames = Array.from(o.states).flatMap((s) => typeof s === "string" ? [s] : []);
12161
+ return [{ name: o.name, currentState: o.currentState, states: stateNames, cooldown: typeof o.cooldown === "number" ? o.cooldown : void 0 }];
12162
+ }) : void 0;
12330
12163
  return {
12331
12164
  id,
12332
12165
  position: pos,
@@ -13322,9 +13155,9 @@ async function computeTraitLayout(data) {
13322
13155
  y: n.y ?? 0,
13323
13156
  width: n.width ?? 110,
13324
13157
  height: n.height ?? STATE_H,
13325
- isInitial: stateInfo?.isInitial,
13326
- isTerminal: stateInfo?.isTerminal,
13327
- role: getStateRole(name, stateInfo?.isInitial, stateInfo?.isTerminal, tc, maxTC),
13158
+ isInitial: stateInfo?.isInitial ?? void 0,
13159
+ isTerminal: stateInfo?.isTerminal ?? void 0,
13160
+ role: getStateRole(name, stateInfo?.isInitial ?? void 0, stateInfo?.isTerminal ?? void 0, tc, maxTC),
13328
13161
  transitionCount: tc
13329
13162
  };
13330
13163
  });
@@ -13335,12 +13168,10 @@ async function computeTraitLayout(data) {
13335
13168
  const sections = e.sections ?? [];
13336
13169
  const points = [];
13337
13170
  for (const section of sections) {
13338
- const startPoint = section.startPoint;
13339
- const endPoint = section.endPoint;
13340
13171
  const bendPoints = section.bendPoints ?? [];
13341
- points.push({ x: startPoint.x, y: startPoint.y });
13172
+ points.push({ x: section.startPoint.x, y: section.startPoint.y });
13342
13173
  for (const bp of bendPoints) points.push({ x: bp.x, y: bp.y });
13343
- points.push({ x: endPoint.x, y: endPoint.y });
13174
+ points.push({ x: section.endPoint.x, y: section.endPoint.y });
13344
13175
  }
13345
13176
  const isSelf = t.from === t.to;
13346
13177
  const isBackward = !isSelf && (nodeXMap[t.to] ?? 0) <= (nodeXMap[t.from] ?? 0);
@@ -13658,6 +13489,50 @@ var init_Tabs = __esm({
13658
13489
  Tabs.displayName = "Tabs";
13659
13490
  }
13660
13491
  });
13492
+ var LoadingState;
13493
+ var init_LoadingState = __esm({
13494
+ "components/core/molecules/LoadingState.tsx"() {
13495
+ "use client";
13496
+ init_cn();
13497
+ init_atoms2();
13498
+ init_Stack();
13499
+ init_Typography();
13500
+ LoadingState = ({
13501
+ title,
13502
+ message,
13503
+ className
13504
+ }) => {
13505
+ const { t } = useTranslate();
13506
+ const displayMessage = message ?? t("common.loading");
13507
+ return /* @__PURE__ */ jsxs(
13508
+ VStack,
13509
+ {
13510
+ align: "center",
13511
+ className: cn(
13512
+ "justify-center py-12",
13513
+ className
13514
+ ),
13515
+ children: [
13516
+ /* @__PURE__ */ jsx(Spinner, { size: "lg" }),
13517
+ title && /* @__PURE__ */ jsx(Typography, { variant: "h3", className: "mt-4 text-lg font-semibold text-foreground", children: title }),
13518
+ /* @__PURE__ */ jsx(
13519
+ Typography,
13520
+ {
13521
+ variant: "small",
13522
+ className: cn(
13523
+ "text-muted-foreground",
13524
+ title ? "mt-2" : "mt-4"
13525
+ ),
13526
+ children: displayMessage
13527
+ }
13528
+ )
13529
+ ]
13530
+ }
13531
+ );
13532
+ };
13533
+ LoadingState.displayName = "LoadingState";
13534
+ }
13535
+ });
13661
13536
  var ICON_NAME_ALIASES, lookStyles3, EmptyState;
13662
13537
  var init_EmptyState = __esm({
13663
13538
  "components/core/molecules/EmptyState.tsx"() {
@@ -13938,7 +13813,7 @@ var init_CodeBlock = __esm({
13938
13813
  };
13939
13814
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
13940
13815
  HIDDEN_LINE_NUMBERS = { display: "none" };
13941
- CodeBlock = React86__default.memo(
13816
+ CodeBlock = React88__default.memo(
13942
13817
  ({
13943
13818
  code: rawCode,
13944
13819
  language = "text",
@@ -14525,7 +14400,7 @@ var init_MarkdownContent = __esm({
14525
14400
  init_Box();
14526
14401
  init_CodeBlock();
14527
14402
  init_cn();
14528
- MarkdownContent = React86__default.memo(
14403
+ MarkdownContent = React88__default.memo(
14529
14404
  ({ content, direction = "ltr", className }) => {
14530
14405
  const { t: _t } = useTranslate();
14531
14406
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -15894,7 +15769,7 @@ var init_StateMachineView = __esm({
15894
15769
  style: { top: title ? 30 : 0 },
15895
15770
  children: [
15896
15771
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
15897
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React86__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
15772
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React88__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
15898
15773
  StateNode,
15899
15774
  {
15900
15775
  state,
@@ -16713,12 +16588,13 @@ var init_ContentRenderer = __esm({
16713
16588
  );
16714
16589
  case "orbital": {
16715
16590
  const parsed = segment.schema;
16591
+ const isFullSchema = (v) => Array.isArray(v.orbitals);
16716
16592
  const inlineTrait = {
16717
16593
  name: "inline",
16718
16594
  scope: "instance",
16719
16595
  stateMachine: parsed
16720
16596
  };
16721
- const schema = Array.isArray(parsed.orbitals) ? parsed : {
16597
+ const schema = isFullSchema(parsed) ? parsed : {
16722
16598
  name: "inline",
16723
16599
  orbitals: [{
16724
16600
  name: "inline",
@@ -17944,8 +17820,21 @@ function BuilderBoard({
17944
17820
  const resolved = boardEntity(entity);
17945
17821
  const [headerError, setHeaderError] = useState(false);
17946
17822
  const [selectedComponent, setSelectedComponent] = useState(null);
17947
- const components = Array.isArray(resolved?.components) ? resolved.components : [];
17948
- const slots = Array.isArray(resolved?.slots) ? resolved.slots : [];
17823
+ const components = rows(resolved?.components).map((r) => ({
17824
+ id: str(r.id),
17825
+ label: str(r.label),
17826
+ description: str(r.description) || void 0,
17827
+ iconEmoji: str(r.iconEmoji) || void 0,
17828
+ iconUrl: str(r.iconUrl) || void 0,
17829
+ category: str(r.category) || void 0
17830
+ }));
17831
+ const slots = rows(resolved?.slots).map((r) => ({
17832
+ id: str(r.id),
17833
+ label: str(r.label) || void 0,
17834
+ description: str(r.description) || void 0,
17835
+ requiredComponentId: str(r.requiredComponentId),
17836
+ placedComponentId: str(r.placedComponentId) || void 0
17837
+ }));
17949
17838
  const placements = {};
17950
17839
  for (const slot of slots) {
17951
17840
  if (slot.placedComponentId) placements[slot.id] = slot.placedComponentId;
@@ -19849,7 +19738,7 @@ function CardHand({
19849
19738
  className
19850
19739
  }) {
19851
19740
  const eventBus = useEventBus();
19852
- const handleClick = React86.useCallback(
19741
+ const handleClick = React88.useCallback(
19853
19742
  (card) => {
19854
19743
  if (card.disabled) return;
19855
19744
  onCardClick?.(card.id);
@@ -20596,14 +20485,15 @@ var init_CardGrid = __esm({
20596
20485
  bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
20597
20486
  const value = getNestedValue(itemData, field);
20598
20487
  if (value === void 0 || value === null || value === "") return null;
20599
- const boolVal = asBooleanValue(value);
20488
+ const fieldValue = value;
20489
+ const boolVal = asBooleanValue(fieldValue);
20600
20490
  if (boolVal !== null) {
20601
20491
  return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between", children: [
20602
20492
  /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: fieldLabel(field) }),
20603
20493
  boolVal ? /* @__PURE__ */ jsx(Badge, { variant: "success", children: t("common.yes") || "Yes" }) : /* @__PURE__ */ jsx(Badge, { variant: "neutral", children: t("common.no") || "No" })
20604
20494
  ] }, field);
20605
20495
  }
20606
- const displayValue = isDateField(field) ? formatDate(value) : STATUS_FIELDS.has(field.toLowerCase()) ? void 0 : String(value);
20496
+ const displayValue = isDateField(field) ? formatDate(fieldValue) : STATUS_FIELDS.has(field.toLowerCase()) ? void 0 : String(value);
20607
20497
  if (!displayValue) return null;
20608
20498
  return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between", children: [
20609
20499
  /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: fieldLabel(field) }),
@@ -20988,9 +20878,9 @@ function CastleBoard({
20988
20878
  const eventBus = useEventBus();
20989
20879
  const { t } = useTranslate();
20990
20880
  const resolved = boardEntity(entity);
20991
- const tiles = propTiles ?? (Array.isArray(resolved?.tiles) ? resolved.tiles : []);
20992
- const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
20993
- const units = propUnits ?? (Array.isArray(resolved?.units) ? resolved.units : []);
20881
+ const tiles = propTiles ?? (resolved?.tiles ?? []);
20882
+ const features = propFeatures ?? (resolved?.features ?? []);
20883
+ const units = propUnits ?? (resolved?.units ?? []);
20994
20884
  const assetManifest = propAssetManifest ?? resolved?.assetManifest;
20995
20885
  const backgroundImage = resolved?.backgroundImage;
20996
20886
  const gold = num(resolved?.gold);
@@ -22525,8 +22415,8 @@ function ClassifierBoard({
22525
22415
  const { t } = useTranslate();
22526
22416
  const resolved = boardEntity(entity);
22527
22417
  const [headerError, setHeaderError] = useState(false);
22528
- const items = Array.isArray(resolved?.items) ? resolved.items : [];
22529
- const categories = Array.isArray(resolved?.categories) ? resolved.categories : [];
22418
+ const items = rows(resolved?.items);
22419
+ const categories = rows(resolved?.categories);
22530
22420
  const result = str(resolved?.result);
22531
22421
  const submitted = result === "win";
22532
22422
  const attempts = num(resolved?.attempts);
@@ -22837,10 +22727,10 @@ function CombatLog({
22837
22727
  }, [events2, autoScroll]);
22838
22728
  const safeEvents = events2 ?? [];
22839
22729
  const visibleEvents = safeEvents.slice(-maxVisible);
22840
- return /* @__PURE__ */ jsxs(Card, { variant: "default", className: cn("flex flex-col", className), children: [
22730
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col rounded-container border border-border bg-card shadow-elevation-card", className), children: [
22841
22731
  /* @__PURE__ */ jsx(Box, { padding: "sm", border: true, className: "border-b-2 border-x-0 border-t-0 border-border", children: /* @__PURE__ */ jsxs(Box, { display: "flex", className: "items-center justify-between", children: [
22842
22732
  /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "font-bold", children: title }),
22843
- /* @__PURE__ */ jsxs(Badge, { variant: "neutral", size: "sm", children: [
22733
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground bg-muted/60 rounded px-1.5 py-0.5 border border-border/50 font-mono", children: [
22844
22734
  safeEvents.length,
22845
22735
  " events"
22846
22736
  ] })
@@ -22860,7 +22750,7 @@ function CombatLog({
22860
22750
  /* @__PURE__ */ jsx(Box, { className: cn("flex-shrink-0 mt-0.5", colorClass), children: /* @__PURE__ */ jsx(EventIcon, { className: "h-4 w-4" }) }),
22861
22751
  /* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
22862
22752
  /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "block", children: event.message }),
22863
- event.value !== void 0 && /* @__PURE__ */ jsxs(Badge, { variant: eventBadgeVariants[eventType], size: "sm", className: "mt-1", children: [
22753
+ event.value !== void 0 && /* @__PURE__ */ jsxs("span", { className: cn("inline-block mt-1 text-xs font-bold rounded px-1.5 py-0.5 border", eventValueColors[eventType]), children: [
22864
22754
  eventType === "heal" ? "+" : eventType === "attack" ? "-" : "",
22865
22755
  event.value
22866
22756
  ] })
@@ -22873,7 +22763,7 @@ function CombatLog({
22873
22763
  }) }) })
22874
22764
  ] });
22875
22765
  }
22876
- var eventIcons, eventColors, eventBadgeVariants, DEFAULT_COMBAT_EVENTS;
22766
+ var eventIcons, eventColors, eventValueColors, DEFAULT_COMBAT_EVENTS;
22877
22767
  var init_CombatLog = __esm({
22878
22768
  "components/game/molecules/CombatLog.tsx"() {
22879
22769
  init_atoms2();
@@ -22896,14 +22786,14 @@ var init_CombatLog = __esm({
22896
22786
  death: "text-muted-foreground",
22897
22787
  spawn: "text-accent"
22898
22788
  };
22899
- eventBadgeVariants = {
22900
- attack: "danger",
22901
- defend: "primary",
22902
- heal: "success",
22903
- move: "warning",
22904
- special: "secondary",
22905
- death: "secondary",
22906
- spawn: "secondary"
22789
+ eventValueColors = {
22790
+ attack: "text-error bg-error/10 border-error/30",
22791
+ defend: "text-info bg-info/10 border-info/30",
22792
+ heal: "text-success bg-success/10 border-success/30",
22793
+ move: "text-warning bg-warning/10 border-warning/30",
22794
+ special: "text-accent bg-accent/10 border-accent/30",
22795
+ death: "text-muted-foreground bg-muted/30 border-border",
22796
+ spawn: "text-accent bg-accent/10 border-accent/30"
22907
22797
  };
22908
22798
  DEFAULT_COMBAT_EVENTS = [
22909
22799
  { id: "e1", type: "spawn", message: "Shadow Guard entered the field.", timestamp: 0, turn: 1 },
@@ -23327,7 +23217,7 @@ function CraftingRecipe({
23327
23217
  className
23328
23218
  }) {
23329
23219
  const eventBus = useEventBus();
23330
- const handleCraft = React86.useCallback(() => {
23220
+ const handleCraft = React88.useCallback(() => {
23331
23221
  onCraft?.();
23332
23222
  if (craftEvent) {
23333
23223
  eventBus.emit(craftEvent, { output: output.label });
@@ -23344,7 +23234,7 @@ function CraftingRecipe({
23344
23234
  children: [
23345
23235
  /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap items-center", children: inputs.map((ingredient, index) => {
23346
23236
  const hasSufficient = ingredient.available >= ingredient.required;
23347
- return /* @__PURE__ */ jsxs(React86.Fragment, { children: [
23237
+ return /* @__PURE__ */ jsxs(React88.Fragment, { children: [
23348
23238
  /* @__PURE__ */ jsx(Box, { className: "relative", children: /* @__PURE__ */ jsx(
23349
23239
  ItemSlot,
23350
23240
  {
@@ -23369,13 +23259,13 @@ function CraftingRecipe({
23369
23259
  }
23370
23260
  ),
23371
23261
  /* @__PURE__ */ jsx(
23372
- Button,
23262
+ ActionButton,
23373
23263
  {
23264
+ label: "Craft",
23374
23265
  onClick: handleCraft,
23375
23266
  disabled: !canCraft,
23376
23267
  variant: canCraft ? "primary" : "secondary",
23377
- size: "sm",
23378
- children: "Craft"
23268
+ size: "sm"
23379
23269
  }
23380
23270
  )
23381
23271
  ]
@@ -23389,7 +23279,7 @@ var init_CraftingRecipe = __esm({
23389
23279
  init_cn();
23390
23280
  init_useEventBus();
23391
23281
  init_ItemSlot();
23392
- init_Button();
23282
+ init_ActionButton();
23393
23283
  init_Box();
23394
23284
  init_Stack();
23395
23285
  init_Icon();
@@ -23416,8 +23306,8 @@ function DPad({
23416
23306
  }) {
23417
23307
  const eventBus = useEventBus();
23418
23308
  const sizes = sizeMap15[size];
23419
- const [activeDirections, setActiveDirections] = React86.useState(/* @__PURE__ */ new Set());
23420
- const handlePress = React86.useCallback(
23309
+ const [activeDirections, setActiveDirections] = React88.useState(/* @__PURE__ */ new Set());
23310
+ const handlePress = React88.useCallback(
23421
23311
  (direction) => {
23422
23312
  setActiveDirections((prev) => new Set(prev).add(direction));
23423
23313
  if (directionEvent) eventBus.emit(`UI:${directionEvent}`, { direction, pressed: true });
@@ -23425,7 +23315,7 @@ function DPad({
23425
23315
  },
23426
23316
  [directionEvent, eventBus, onDirection]
23427
23317
  );
23428
- const handleRelease = React86.useCallback(
23318
+ const handleRelease = React88.useCallback(
23429
23319
  (direction) => {
23430
23320
  setActiveDirections((prev) => {
23431
23321
  const next = new Set(prev);
@@ -24310,8 +24200,8 @@ var init_Menu = __esm({
24310
24200
  "bottom-end": "bottom-start"
24311
24201
  };
24312
24202
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
24313
- const triggerChild = React86__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
24314
- const triggerElement = React86__default.cloneElement(
24203
+ const triggerChild = React88__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
24204
+ const triggerElement = React88__default.cloneElement(
24315
24205
  triggerChild,
24316
24206
  {
24317
24207
  ref: triggerRef,
@@ -24406,14 +24296,14 @@ function useDataDnd(args) {
24406
24296
  const isZone = Boolean(dragGroup || accepts || sortable);
24407
24297
  const enabled = isZone || Boolean(dndRoot);
24408
24298
  const eventBus = useEventBus();
24409
- const parentRoot = React86__default.useContext(RootCtx);
24299
+ const parentRoot = React88__default.useContext(RootCtx);
24410
24300
  const isRoot = enabled && parentRoot === null;
24411
- const zoneId = React86__default.useId();
24301
+ const zoneId = React88__default.useId();
24412
24302
  const ownGroup = dragGroup ?? accepts ?? zoneId;
24413
- const [optimisticOrders, setOptimisticOrders] = React86__default.useState(() => /* @__PURE__ */ new Map());
24414
- const optimisticOrdersRef = React86__default.useRef(optimisticOrders);
24303
+ const [optimisticOrders, setOptimisticOrders] = React88__default.useState(() => /* @__PURE__ */ new Map());
24304
+ const optimisticOrdersRef = React88__default.useRef(optimisticOrders);
24415
24305
  optimisticOrdersRef.current = optimisticOrders;
24416
- const clearOptimisticOrder = React86__default.useCallback((group) => {
24306
+ const clearOptimisticOrder = React88__default.useCallback((group) => {
24417
24307
  setOptimisticOrders((prev) => {
24418
24308
  if (!prev.has(group)) return prev;
24419
24309
  const next = new Map(prev);
@@ -24436,17 +24326,20 @@ function useDataDnd(args) {
24436
24326
  }
24437
24327
  const itemIdsSignature = orderedItems.map((it, idx) => {
24438
24328
  const raw = it[dndItemIdField];
24439
- return String(raw ?? `__idx_${idx}`);
24329
+ return raw != null ? String(raw) : `__idx_${idx}`;
24440
24330
  }).join("|");
24441
- const itemIds = React86__default.useMemo(
24331
+ const itemIds = React88__default.useMemo(
24442
24332
  () => orderedItems.map((it, idx) => {
24443
24333
  const raw = it[dndItemIdField];
24444
- return raw ?? `__idx_${idx}`;
24334
+ return raw != null ? String(raw) : `__idx_${idx}`;
24445
24335
  }),
24446
24336
  [itemIdsSignature]
24447
24337
  );
24448
- const itemsContentSig = items.map((it, idx) => String(it[dndItemIdField] ?? `__${idx}`)).join("|");
24449
- React86__default.useEffect(() => {
24338
+ const itemsContentSig = items.map((it, idx) => {
24339
+ const raw = it[dndItemIdField];
24340
+ return raw != null ? String(raw) : `__${idx}`;
24341
+ }).join("|");
24342
+ React88__default.useEffect(() => {
24450
24343
  const root = isRoot ? null : parentRoot;
24451
24344
  if (root) {
24452
24345
  root.clearOptimisticOrder(ownGroup);
@@ -24454,20 +24347,20 @@ function useDataDnd(args) {
24454
24347
  clearOptimisticOrder(ownGroup);
24455
24348
  }
24456
24349
  }, [itemsContentSig, ownGroup]);
24457
- const zonesRef = React86__default.useRef(/* @__PURE__ */ new Map());
24458
- const registerZone = React86__default.useCallback((zoneId2, meta2) => {
24350
+ const zonesRef = React88__default.useRef(/* @__PURE__ */ new Map());
24351
+ const registerZone = React88__default.useCallback((zoneId2, meta2) => {
24459
24352
  zonesRef.current.set(zoneId2, meta2);
24460
24353
  }, []);
24461
- const unregisterZone = React86__default.useCallback((zoneId2) => {
24354
+ const unregisterZone = React88__default.useCallback((zoneId2) => {
24462
24355
  zonesRef.current.delete(zoneId2);
24463
24356
  }, []);
24464
- const [activeDrag, setActiveDrag] = React86__default.useState(null);
24465
- const [overZoneGroup, setOverZoneGroup] = React86__default.useState(null);
24466
- const meta = React86__default.useMemo(
24357
+ const [activeDrag, setActiveDrag] = React88__default.useState(null);
24358
+ const [overZoneGroup, setOverZoneGroup] = React88__default.useState(null);
24359
+ const meta = React88__default.useMemo(
24467
24360
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
24468
24361
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
24469
24362
  );
24470
- React86__default.useEffect(() => {
24363
+ React88__default.useEffect(() => {
24471
24364
  const target = isRoot ? null : parentRoot;
24472
24365
  if (!target) {
24473
24366
  zonesRef.current.set(zoneId, meta);
@@ -24486,7 +24379,7 @@ function useDataDnd(args) {
24486
24379
  }, [parentRoot, isRoot, zoneId, meta]);
24487
24380
  const sensors = useAlmadarDndSensors(true);
24488
24381
  const collisionDetection = almadarDndCollisionDetection;
24489
- const findZoneByItem = React86__default.useCallback(
24382
+ const findZoneByItem = React88__default.useCallback(
24490
24383
  (id) => {
24491
24384
  for (const z of zonesRef.current.values()) {
24492
24385
  if (z.itemIds.includes(id)) return z;
@@ -24495,7 +24388,7 @@ function useDataDnd(args) {
24495
24388
  },
24496
24389
  []
24497
24390
  );
24498
- React86__default.useCallback(
24391
+ React88__default.useCallback(
24499
24392
  (group) => {
24500
24393
  for (const z of zonesRef.current.values()) {
24501
24394
  if (z.group === group) return z;
@@ -24504,7 +24397,7 @@ function useDataDnd(args) {
24504
24397
  },
24505
24398
  []
24506
24399
  );
24507
- const handleDragEnd = React86__default.useCallback(
24400
+ const handleDragEnd = React88__default.useCallback(
24508
24401
  (event) => {
24509
24402
  const { active, over } = event;
24510
24403
  const activeIdStr = String(active.id);
@@ -24595,8 +24488,8 @@ function useDataDnd(args) {
24595
24488
  },
24596
24489
  [eventBus]
24597
24490
  );
24598
- const sortableData = React86__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
24599
- const SortableItem = React86__default.useCallback(
24491
+ const sortableData = React88__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
24492
+ const SortableItem = React88__default.useCallback(
24600
24493
  ({ id, children }) => {
24601
24494
  const {
24602
24495
  attributes,
@@ -24636,7 +24529,7 @@ function useDataDnd(args) {
24636
24529
  id: droppableId,
24637
24530
  data: sortableData
24638
24531
  });
24639
- const ctx = React86__default.useContext(RootCtx);
24532
+ const ctx = React88__default.useContext(RootCtx);
24640
24533
  const activeDrag2 = ctx?.activeDrag ?? null;
24641
24534
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
24642
24535
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -24651,7 +24544,7 @@ function useDataDnd(args) {
24651
24544
  showForeignPlaceholder,
24652
24545
  ctxAvailable: ctx != null
24653
24546
  });
24654
- React86__default.useEffect(() => {
24547
+ React88__default.useEffect(() => {
24655
24548
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
24656
24549
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
24657
24550
  return /* @__PURE__ */ jsx(
@@ -24665,11 +24558,11 @@ function useDataDnd(args) {
24665
24558
  }
24666
24559
  );
24667
24560
  };
24668
- const rootContextValue = React86__default.useMemo(
24561
+ const rootContextValue = React88__default.useMemo(
24669
24562
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
24670
24563
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
24671
24564
  );
24672
- const handleDragStart = React86__default.useCallback((event) => {
24565
+ const handleDragStart = React88__default.useCallback((event) => {
24673
24566
  const sourceZone = findZoneByItem(event.active.id);
24674
24567
  const rect = event.active.rect.current.initial;
24675
24568
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -24688,7 +24581,7 @@ function useDataDnd(args) {
24688
24581
  isRoot
24689
24582
  });
24690
24583
  }, [findZoneByItem, isRoot, zoneId]);
24691
- const handleDragOver = React86__default.useCallback((event) => {
24584
+ const handleDragOver = React88__default.useCallback((event) => {
24692
24585
  const { active, over } = event;
24693
24586
  const overData = over?.data?.current;
24694
24587
  const overGroup = overData?.dndGroup ?? null;
@@ -24758,7 +24651,7 @@ function useDataDnd(args) {
24758
24651
  return next;
24759
24652
  });
24760
24653
  }, []);
24761
- const handleDragCancel = React86__default.useCallback((event) => {
24654
+ const handleDragCancel = React88__default.useCallback((event) => {
24762
24655
  setActiveDrag(null);
24763
24656
  setOverZoneGroup(null);
24764
24657
  dndLog.warn("dragCancel", {
@@ -24766,12 +24659,12 @@ function useDataDnd(args) {
24766
24659
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
24767
24660
  });
24768
24661
  }, []);
24769
- const handleDragEndWithCleanup = React86__default.useCallback((event) => {
24662
+ const handleDragEndWithCleanup = React88__default.useCallback((event) => {
24770
24663
  handleDragEnd(event);
24771
24664
  setActiveDrag(null);
24772
24665
  setOverZoneGroup(null);
24773
24666
  }, [handleDragEnd]);
24774
- const wrapContainer = React86__default.useCallback(
24667
+ const wrapContainer = React88__default.useCallback(
24775
24668
  (children) => {
24776
24669
  if (!enabled) return children;
24777
24670
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -24825,7 +24718,7 @@ var init_useDataDnd = __esm({
24825
24718
  init_useAlmadarDndCollision();
24826
24719
  init_Box();
24827
24720
  dndLog = createLogger("almadar:ui:dnd");
24828
- RootCtx = React86__default.createContext(null);
24721
+ RootCtx = React88__default.createContext(null);
24829
24722
  }
24830
24723
  });
24831
24724
  function renderIconInput(icon, props) {
@@ -24968,8 +24861,8 @@ function DataGrid({
24968
24861
  const hasRenderProp = typeof children === "function";
24969
24862
  useEffect(() => {
24970
24863
  if (data.length > 0 && !hasRenderProp && fieldDefs.length === 0) {
24971
- const renderItemRaw = schemaRenderItem;
24972
- const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
24864
+ const schemaArr = Array.isArray(schemaRenderItem) ? schemaRenderItem : null;
24865
+ const isFnLambda = schemaArr !== null && schemaArr.length >= 3 && (schemaArr[0] === "fn" || schemaArr[0] === "lambda");
24973
24866
  dataGridLog.warn("renderItem-unresolved", {
24974
24867
  rowCount: data.length,
24975
24868
  renderItemIsFnLambda: isFnLambda
@@ -25351,7 +25244,7 @@ function DataList({
25351
25244
  }) {
25352
25245
  const eventBus = useEventBus();
25353
25246
  const { t } = useTranslate();
25354
- const [visibleCount, setVisibleCount] = React86__default.useState(pageSize || Infinity);
25247
+ const [visibleCount, setVisibleCount] = React88__default.useState(pageSize || Infinity);
25355
25248
  const fieldDefs = fields ?? columns ?? [];
25356
25249
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
25357
25250
  const dnd = useDataDnd({
@@ -25370,21 +25263,20 @@ function DataList({
25370
25263
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
25371
25264
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
25372
25265
  const hasRenderProp = typeof children === "function";
25373
- React86__default.useEffect(() => {
25266
+ React88__default.useEffect(() => {
25374
25267
  const renderItemTypeOf = typeof schemaRenderItem;
25375
25268
  const childrenTypeOf = typeof children;
25376
25269
  if (data.length > 0 && !hasRenderProp) {
25377
25270
  const firstRow = data[0];
25378
25271
  const sampleKeys = firstRow ? Object.keys(firstRow).slice(0, 6) : [];
25379
- const renderItemRaw = schemaRenderItem;
25380
- const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
25272
+ const isFnLambda = Array.isArray(schemaRenderItem) && schemaRenderItem.length >= 3 && (schemaRenderItem[0] === "fn" || schemaRenderItem[0] === "lambda");
25381
25273
  dataListLog.warn("renderItem-unresolved", {
25382
25274
  rowCount: data.length,
25383
25275
  fieldsCount: fieldDefs.length,
25384
25276
  renderItemTypeOf,
25385
- renderItemIsArray: Array.isArray(renderItemRaw),
25277
+ renderItemIsArray: Array.isArray(schemaRenderItem),
25386
25278
  renderItemIsFnLambda: isFnLambda,
25387
- renderItemHead: Array.isArray(renderItemRaw) ? String(renderItemRaw[0]) : void 0,
25279
+ renderItemHead: Array.isArray(schemaRenderItem) ? String(schemaRenderItem[0]) : void 0,
25388
25280
  childrenTypeOf,
25389
25281
  sampleRowKeys: sampleKeys
25390
25282
  });
@@ -25472,10 +25364,10 @@ function DataList({
25472
25364
  const isCompact = variant === "compact";
25473
25365
  const isMessage = variant === "message";
25474
25366
  if (isMessage) {
25475
- const items2 = data.map((item) => item);
25367
+ const items2 = [...data];
25476
25368
  const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
25477
25369
  const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
25478
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
25370
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
25479
25371
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
25480
25372
  group.items.map((itemData, index) => {
25481
25373
  const id = itemData.id || `${gi}-${index}`;
@@ -25521,7 +25413,7 @@ function DataList({
25521
25413
  })
25522
25414
  ] }, gi)) });
25523
25415
  }
25524
- const items = data.map((item) => item);
25416
+ const items = [...data];
25525
25417
  const groups = groupBy ? groupData(items, groupBy) : [{ label: "", items }];
25526
25418
  const idFieldName = dndItemIdField ?? "id";
25527
25419
  const renderItem = (itemData, index, isLast) => {
@@ -25616,7 +25508,7 @@ function DataList({
25616
25508
  className
25617
25509
  ),
25618
25510
  children: [
25619
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
25511
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
25620
25512
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
25621
25513
  group.items.map(
25622
25514
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -26409,23 +26301,19 @@ var init_Flex = __esm({
26409
26301
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
26410
26302
  }
26411
26303
  }
26412
- const Comp = Component2;
26413
- return /* @__PURE__ */ jsx(
26414
- Comp,
26415
- {
26416
- className: cn(
26417
- inline ? "inline-flex" : "flex",
26418
- directionStyles[direction],
26419
- wrapStyles[wrap],
26420
- alignStyles3[align],
26421
- justifyStyles2[justify],
26422
- gapStyles6[gap],
26423
- className
26424
- ),
26425
- style: Object.keys(flexStyle).length > 0 ? flexStyle : void 0,
26426
- children
26427
- }
26428
- );
26304
+ return React88__default.createElement(Component2, {
26305
+ className: cn(
26306
+ inline ? "inline-flex" : "flex",
26307
+ directionStyles[direction],
26308
+ wrapStyles[wrap],
26309
+ alignStyles3[align],
26310
+ justifyStyles2[justify],
26311
+ gapStyles6[gap],
26312
+ className
26313
+ ),
26314
+ style: Object.keys(flexStyle).length > 0 ? flexStyle : void 0,
26315
+ children
26316
+ });
26429
26317
  };
26430
26318
  Flex.displayName = "Flex";
26431
26319
  }
@@ -26532,7 +26420,7 @@ var init_Grid = __esm({
26532
26420
  as: Component2 = "div"
26533
26421
  }) => {
26534
26422
  const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
26535
- return React86__default.createElement(
26423
+ return React88__default.createElement(
26536
26424
  Component2,
26537
26425
  {
26538
26426
  className: cn(
@@ -26728,9 +26616,9 @@ var init_Popover = __esm({
26728
26616
  onMouseLeave: handleClose,
26729
26617
  onPointerDown: tapTriggerProps.onPointerDown
26730
26618
  };
26731
- const childElement = React86__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
26619
+ const childElement = React88__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
26732
26620
  const childPointerDown = childElement.props.onPointerDown;
26733
- const triggerElement = React86__default.cloneElement(
26621
+ const triggerElement = React88__default.cloneElement(
26734
26622
  childElement,
26735
26623
  {
26736
26624
  ref: triggerRef,
@@ -27332,9 +27220,9 @@ var init_Tooltip = __esm({
27332
27220
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
27333
27221
  };
27334
27222
  }, []);
27335
- const triggerElement = React86__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
27223
+ const triggerElement = React88__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
27336
27224
  const childPointerDown = triggerElement.props.onPointerDown;
27337
- const trigger = React86__default.cloneElement(triggerElement, {
27225
+ const trigger = React88__default.cloneElement(triggerElement, {
27338
27226
  ref: triggerRef,
27339
27227
  onMouseEnter: handleMouseEnter,
27340
27228
  onMouseLeave: handleMouseLeave,
@@ -27424,7 +27312,7 @@ var init_WizardProgress = __esm({
27424
27312
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
27425
27313
  const isActive = index === currentStep;
27426
27314
  const isCompleted = index < currentStep;
27427
- return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
27315
+ return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
27428
27316
  /* @__PURE__ */ jsx(
27429
27317
  "button",
27430
27318
  {
@@ -27736,13 +27624,14 @@ var init_ViolationAlert = __esm({
27736
27624
  onNavigateToField,
27737
27625
  compact = false,
27738
27626
  className,
27739
- ...flatProps
27627
+ message
27740
27628
  }) => {
27741
27629
  const { t } = useTranslate();
27630
+ const fallbackMessage = message ?? t("violationAlert.fallbackMessage");
27742
27631
  const resolvedViolation = violation ?? {
27743
27632
  law: "",
27744
27633
  article: "",
27745
- message: flatProps.message ?? t("violationAlert.fallbackMessage"),
27634
+ message: fallbackMessage,
27746
27635
  actionType: "measure"
27747
27636
  };
27748
27637
  const effectiveSeverity = severity ?? (resolvedViolation.actionType === "measure" ? "warning" : "error");
@@ -28386,6 +28275,7 @@ var init_ProgressDots = __esm({
28386
28275
  });
28387
28276
  function StatBadge({
28388
28277
  assetUrl,
28278
+ iconUrl,
28389
28279
  label,
28390
28280
  value = 0,
28391
28281
  max,
@@ -28399,6 +28289,7 @@ function StatBadge({
28399
28289
  field: _field
28400
28290
  }) {
28401
28291
  const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
28292
+ const resolvedAsset = iconUrl ?? assetUrl;
28402
28293
  return /* @__PURE__ */ jsxs(
28403
28294
  "div",
28404
28295
  {
@@ -28409,10 +28300,10 @@ function StatBadge({
28409
28300
  className
28410
28301
  ),
28411
28302
  children: [
28412
- assetUrl ? /* @__PURE__ */ jsx(
28303
+ resolvedAsset ? /* @__PURE__ */ jsx(
28413
28304
  "img",
28414
28305
  {
28415
- src: assetUrl,
28306
+ src: resolvedAsset,
28416
28307
  alt: "",
28417
28308
  width: 16,
28418
28309
  height: 16,
@@ -28443,8 +28334,7 @@ function StatBadge({
28443
28334
  ScoreDisplay,
28444
28335
  {
28445
28336
  value: numValue,
28446
- size: size === "lg" ? "md" : "sm",
28447
- animated: true
28337
+ size: size === "lg" ? "md" : "sm"
28448
28338
  }
28449
28339
  ),
28450
28340
  format === "text" && /* @__PURE__ */ jsx("span", { className: "font-bold text-foreground", children: value })
@@ -28487,7 +28377,7 @@ function InventoryGrid({
28487
28377
  const eventBus = useEventBus();
28488
28378
  const slotCount = totalSlots ?? items.length;
28489
28379
  const emptySlotCount = Math.max(0, slotCount - items.length);
28490
- const handleSelect = React86.useCallback(
28380
+ const handleSelect = React88.useCallback(
28491
28381
  (id) => {
28492
28382
  onSelect?.(id);
28493
28383
  if (selectEvent) {
@@ -28594,12 +28484,14 @@ function QuestTracker({
28594
28484
  }
28595
28485
  ),
28596
28486
  /* @__PURE__ */ jsx(Box, { className: "mt-1.5", children: /* @__PURE__ */ jsx(
28597
- ProgressBar,
28487
+ HealthBar,
28598
28488
  {
28599
- value: quest.progress,
28489
+ current: quest.progress,
28600
28490
  max: quest.maxProgress,
28601
- variant: isCompleted ? "success" : isActive ? "primary" : "default",
28602
- size: "sm"
28491
+ format: "bar",
28492
+ size: "sm",
28493
+ animated: true,
28494
+ className: isCompleted ? "[--health-color:var(--color-success)]" : isActive ? "" : "opacity-60"
28603
28495
  }
28604
28496
  ) }),
28605
28497
  /* @__PURE__ */ jsxs(
@@ -28627,7 +28519,7 @@ var init_QuestTracker = __esm({
28627
28519
  "use client";
28628
28520
  init_cn();
28629
28521
  init_WaypointMarker();
28630
- init_ProgressBar();
28522
+ init_HealthBar();
28631
28523
  init_Typography();
28632
28524
  init_Box();
28633
28525
  init_Stack();
@@ -28722,31 +28614,31 @@ function GameCanvas2D({
28722
28614
  assetBaseUrl,
28723
28615
  className
28724
28616
  }) {
28725
- const canvasRef = React86.useRef(null);
28726
- const rafRef = React86.useRef(0);
28727
- const frameRef = React86.useRef(0);
28728
- const lastTimeRef = React86.useRef(0);
28729
- const imageCache = React86.useRef(/* @__PURE__ */ new Map());
28617
+ const canvasRef = React88.useRef(null);
28618
+ const rafRef = React88.useRef(0);
28619
+ const frameRef = React88.useRef(0);
28620
+ const lastTimeRef = React88.useRef(0);
28621
+ const imageCache = React88.useRef(/* @__PURE__ */ new Map());
28730
28622
  const emit = useEmitEvent();
28731
- const onDrawRef = React86.useRef(onDraw);
28623
+ const onDrawRef = React88.useRef(onDraw);
28732
28624
  onDrawRef.current = onDraw;
28733
- const onTickRef = React86.useRef(onTick);
28625
+ const onTickRef = React88.useRef(onTick);
28734
28626
  onTickRef.current = onTick;
28735
- const tickEventRef = React86.useRef(tickEvent);
28627
+ const tickEventRef = React88.useRef(tickEvent);
28736
28628
  tickEventRef.current = tickEvent;
28737
- const drawEventRef = React86.useRef(drawEvent);
28629
+ const drawEventRef = React88.useRef(drawEvent);
28738
28630
  drawEventRef.current = drawEvent;
28739
- const emitRef = React86.useRef(emit);
28631
+ const emitRef = React88.useRef(emit);
28740
28632
  emitRef.current = emit;
28741
- const assetBaseUrlRef = React86.useRef(assetBaseUrl);
28633
+ const assetBaseUrlRef = React88.useRef(assetBaseUrl);
28742
28634
  assetBaseUrlRef.current = assetBaseUrl;
28743
- const backgroundImageRef = React86.useRef(backgroundImage);
28635
+ const backgroundImageRef = React88.useRef(backgroundImage);
28744
28636
  backgroundImageRef.current = backgroundImage;
28745
- const widthRef = React86.useRef(width);
28637
+ const widthRef = React88.useRef(width);
28746
28638
  widthRef.current = width;
28747
- const heightRef = React86.useRef(height);
28639
+ const heightRef = React88.useRef(height);
28748
28640
  heightRef.current = height;
28749
- const loadImage = React86.useCallback((url) => {
28641
+ const loadImage = React88.useCallback((url) => {
28750
28642
  const base = assetBaseUrlRef.current;
28751
28643
  if (!url.startsWith("http") && !base) return null;
28752
28644
  const fullUrl = url.startsWith("http") ? url : `${base}${url}`;
@@ -28760,7 +28652,7 @@ function GameCanvas2D({
28760
28652
  }
28761
28653
  return null;
28762
28654
  }, []);
28763
- React86.useEffect(() => {
28655
+ React88.useEffect(() => {
28764
28656
  const canvas = canvasRef.current;
28765
28657
  if (!canvas) return;
28766
28658
  const ctx = canvas.getContext("2d");
@@ -28908,26 +28800,14 @@ function HealthPanel({
28908
28800
  )
28909
28801
  }
28910
28802
  ),
28911
- effects && effects.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1 flex-wrap", children: effects.map((effect, i) => /* @__PURE__ */ jsxs(
28912
- Badge,
28803
+ effects && effects.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1 flex-wrap", children: effects.map((effect, i) => /* @__PURE__ */ jsx(
28804
+ StatusEffect,
28913
28805
  {
28806
+ assetUrl: effect.assetUrl,
28807
+ icon: effect.icon,
28808
+ label: effect.label,
28914
28809
  variant: effectVariantMap[effect.variant ?? "neutral"],
28915
- size: "sm",
28916
- icon: effect.assetUrl ? void 0 : effect.icon,
28917
- children: [
28918
- effect.assetUrl && /* @__PURE__ */ jsx(
28919
- "img",
28920
- {
28921
- src: effect.assetUrl,
28922
- alt: "",
28923
- width: 12,
28924
- height: 12,
28925
- style: { imageRendering: "pixelated", objectFit: "contain" },
28926
- className: "flex-shrink-0 inline-block"
28927
- }
28928
- ),
28929
- effect.label
28930
- ]
28810
+ size: "sm"
28931
28811
  },
28932
28812
  i
28933
28813
  )) })
@@ -28941,17 +28821,17 @@ var init_HealthPanel = __esm({
28941
28821
  "use client";
28942
28822
  init_cn();
28943
28823
  init_HealthBar();
28824
+ init_StatusEffect();
28944
28825
  init_Box();
28945
28826
  init_Typography();
28946
- init_Badge();
28947
28827
  sizeMap18 = {
28948
28828
  sm: { gap: "gap-1", padding: "px-2 py-1.5", text: "text-xs", barSize: "sm" },
28949
28829
  md: { gap: "gap-1.5", padding: "px-3 py-2", text: "text-sm", barSize: "md" },
28950
28830
  lg: { gap: "gap-2", padding: "px-4 py-3", text: "text-base", barSize: "lg" }
28951
28831
  };
28952
28832
  effectVariantMap = {
28953
- buff: "success",
28954
- debuff: "danger",
28833
+ buff: "buff",
28834
+ debuff: "debuff",
28955
28835
  neutral: "neutral"
28956
28836
  };
28957
28837
  HealthPanel.displayName = "HealthPanel";
@@ -28971,13 +28851,13 @@ function ScoreBoard({
28971
28851
  const multiplier = rawMultiplier ?? 1;
28972
28852
  const level = rawLevel ?? 1;
28973
28853
  return /* @__PURE__ */ jsx(
28974
- Card,
28854
+ Box,
28975
28855
  {
28976
28856
  className: cn(
28977
- "bg-[var(--color-card)]/90 border-border backdrop-blur-sm",
28857
+ "rounded-container border border-border bg-[var(--color-card)]/90 backdrop-blur-sm p-3",
28978
28858
  className
28979
28859
  ),
28980
- children: /* @__PURE__ */ jsx(CardContent, { className: "p-3", children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-wrap", children: [
28860
+ children: /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-3 flex-wrap", children: [
28981
28861
  /* @__PURE__ */ jsx(
28982
28862
  StatBadge,
28983
28863
  {
@@ -29019,7 +28899,7 @@ function ScoreBoard({
29019
28899
  }
29020
28900
  ),
29021
28901
  combo != null && combo > 0 && /* @__PURE__ */ jsx(ComboCounter, { combo, multiplier, size: "sm" })
29022
- ] }) })
28902
+ ] })
29023
28903
  }
29024
28904
  );
29025
28905
  }
@@ -29029,7 +28909,6 @@ var init_ScoreBoard = __esm({
29029
28909
  init_cn();
29030
28910
  init_ComboCounter();
29031
28911
  init_StatBadge();
29032
- init_Card();
29033
28912
  init_Box();
29034
28913
  ScoreBoard.displayName = "ScoreBoard";
29035
28914
  }
@@ -29085,7 +28964,7 @@ function TurnPanel({
29085
28964
  className
29086
28965
  }) {
29087
28966
  const eventBus = useEventBus();
29088
- const handleAction = React86.useCallback(
28967
+ const handleAction = React88.useCallback(
29089
28968
  (event) => {
29090
28969
  if (event) {
29091
28970
  eventBus.emit(event, { turn: currentTurn, phase, activeTeam });
@@ -29110,28 +28989,16 @@ function TurnPanel({
29110
28989
  activeTeam
29111
28990
  }
29112
28991
  ),
29113
- actions && actions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1.5 ml-auto", children: actions.map((action, i) => /* @__PURE__ */ jsxs(
29114
- Button,
28992
+ actions && actions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1.5 ml-auto", children: actions.map((action, i) => /* @__PURE__ */ jsx(
28993
+ ActionButton,
29115
28994
  {
29116
- variant: "ghost",
29117
- size: "sm",
28995
+ label: action.label,
28996
+ icon: action.assetUrl ? void 0 : action.icon,
28997
+ assetUrl: action.assetUrl,
29118
28998
  disabled: action.disabled,
29119
- leftIcon: action.assetUrl ? void 0 : action.icon,
29120
- onClick: () => handleAction(action.event),
29121
- children: [
29122
- action.assetUrl && /* @__PURE__ */ jsx(
29123
- "img",
29124
- {
29125
- src: action.assetUrl,
29126
- alt: "",
29127
- width: 14,
29128
- height: 14,
29129
- style: { imageRendering: "pixelated", objectFit: "contain" },
29130
- className: "flex-shrink-0"
29131
- }
29132
- ),
29133
- action.label
29134
- ]
28999
+ variant: "secondary",
29000
+ size: "sm",
29001
+ onClick: () => handleAction(action.event)
29135
29002
  },
29136
29003
  i
29137
29004
  )) })
@@ -29145,7 +29012,7 @@ var init_TurnPanel = __esm({
29145
29012
  "use client";
29146
29013
  init_cn();
29147
29014
  init_TurnIndicator();
29148
- init_Button();
29015
+ init_ActionButton();
29149
29016
  init_Box();
29150
29017
  init_useEventBus();
29151
29018
  DEFAULT_TURN_ACTIONS = [
@@ -29196,7 +29063,7 @@ function EnemyPlate({
29196
29063
  }
29197
29064
  )
29198
29065
  ] }),
29199
- level != null && /* @__PURE__ */ jsxs(Badge, { variant: "neutral", size: "sm", children: [
29066
+ level != null && /* @__PURE__ */ jsxs("span", { className: "text-xs font-bold text-muted-foreground bg-muted/60 rounded px-1.5 py-0.5 border border-border/50 shrink-0", children: [
29200
29067
  "Lv.",
29201
29068
  level
29202
29069
  ] })
@@ -29227,12 +29094,12 @@ function EnemyPlate({
29227
29094
  )
29228
29095
  ] }),
29229
29096
  effects && effects.length > 0 && /* @__PURE__ */ jsx(Box, { className: "flex items-center gap-1 flex-wrap", children: effects.map((effect, i) => /* @__PURE__ */ jsx(
29230
- Badge,
29097
+ StatusEffect,
29231
29098
  {
29232
- variant: effectVariantMap2[effect.variant ?? "neutral"],
29233
- size: "sm",
29234
29099
  icon: effect.icon,
29235
- children: effect.label
29100
+ label: effect.label,
29101
+ variant: effectVariantMap2[effect.variant ?? "neutral"],
29102
+ size: "sm"
29236
29103
  },
29237
29104
  i
29238
29105
  )) })
@@ -29246,12 +29113,12 @@ var init_EnemyPlate = __esm({
29246
29113
  "use client";
29247
29114
  init_cn();
29248
29115
  init_HealthBar();
29116
+ init_StatusEffect();
29249
29117
  init_Box();
29250
29118
  init_Typography();
29251
- init_Badge();
29252
29119
  effectVariantMap2 = {
29253
- buff: "success",
29254
- debuff: "danger",
29120
+ buff: "buff",
29121
+ debuff: "debuff",
29255
29122
  neutral: "neutral"
29256
29123
  };
29257
29124
  DEFAULT_ENEMY_EFFECTS = [
@@ -29266,7 +29133,7 @@ function UnitCommandBar({
29266
29133
  className
29267
29134
  }) {
29268
29135
  const eventBus = useEventBus();
29269
- const handleCommand = React86.useCallback(
29136
+ const handleCommand = React88.useCallback(
29270
29137
  (event) => {
29271
29138
  if (event) {
29272
29139
  eventBus.emit(event, { unitId: selectedUnitId });
@@ -29281,27 +29148,18 @@ function UnitCommandBar({
29281
29148
  "flex items-center gap-1.5 rounded-container bg-[var(--color-card)]/90 border border-border backdrop-blur-sm px-2 py-1.5",
29282
29149
  className
29283
29150
  ),
29284
- children: commands.map((command, i) => /* @__PURE__ */ jsxs(Box, { className: "flex flex-col items-center gap-0.5", children: [
29285
- /* @__PURE__ */ jsx(
29286
- Button,
29287
- {
29288
- variant: "ghost",
29289
- size: "sm",
29290
- disabled: command.disabled,
29291
- leftIcon: command.icon,
29292
- onClick: () => handleCommand(command.event),
29293
- children: command.label
29294
- }
29295
- ),
29296
- command.hotkey && /* @__PURE__ */ jsx(
29297
- Typography,
29298
- {
29299
- variant: "caption",
29300
- className: "text-muted-foreground text-xs font-mono",
29301
- children: command.hotkey
29302
- }
29303
- )
29304
- ] }, i))
29151
+ children: commands.map((command, i) => /* @__PURE__ */ jsx(Box, { className: "flex flex-col items-center gap-0.5", children: /* @__PURE__ */ jsx(
29152
+ ActionButton,
29153
+ {
29154
+ label: command.label,
29155
+ icon: command.icon,
29156
+ disabled: command.disabled,
29157
+ hotkey: command.hotkey,
29158
+ variant: "secondary",
29159
+ size: "sm",
29160
+ onClick: () => handleCommand(command.event)
29161
+ }
29162
+ ) }, i))
29305
29163
  }
29306
29164
  );
29307
29165
  }
@@ -29310,9 +29168,8 @@ var init_UnitCommandBar = __esm({
29310
29168
  "components/game/molecules/UnitCommandBar.tsx"() {
29311
29169
  "use client";
29312
29170
  init_cn();
29313
- init_Button();
29171
+ init_ActionButton();
29314
29172
  init_Box();
29315
- init_Typography();
29316
29173
  init_useEventBus();
29317
29174
  DEFAULT_COMMANDS = [
29318
29175
  { label: "Move", icon: "move", event: "MOVE", hotkey: "M" },
@@ -29817,7 +29674,7 @@ function GameMenu({
29817
29674
  } catch {
29818
29675
  }
29819
29676
  const eventBus = eventBusProp || eventBusFromHook;
29820
- const handleOptionClick = React86.useCallback(
29677
+ const handleOptionClick = React88.useCallback(
29821
29678
  (option) => {
29822
29679
  if (option.event && eventBus) {
29823
29680
  eventBus.emit(`UI:${option.event}`, { option });
@@ -29936,7 +29793,7 @@ function GameOverScreen({
29936
29793
  } catch {
29937
29794
  }
29938
29795
  const eventBus = eventBusProp || eventBusFromHook;
29939
- const handleActionClick = React86.useCallback(
29796
+ const handleActionClick = React88.useCallback(
29940
29797
  (action) => {
29941
29798
  if (action.event && eventBus) {
29942
29799
  eventBus.emit(`UI:${action.event}`, { action });
@@ -30151,6 +30008,7 @@ function PlatformerCanvas({
30151
30008
  rightEvent = "MOVE_RIGHT",
30152
30009
  jumpEvent = "JUMP",
30153
30010
  stopEvent = "STOP",
30011
+ effects = [],
30154
30012
  className
30155
30013
  }) {
30156
30014
  const canvasRef = useRef(null);
@@ -30221,7 +30079,8 @@ function PlatformerCanvas({
30221
30079
  playerSprite,
30222
30080
  tileSprites,
30223
30081
  backgroundImage,
30224
- assetBaseUrl
30082
+ assetBaseUrl,
30083
+ effects
30225
30084
  });
30226
30085
  propsRef.current = {
30227
30086
  platforms,
@@ -30234,7 +30093,8 @@ function PlatformerCanvas({
30234
30093
  playerSprite,
30235
30094
  tileSprites,
30236
30095
  backgroundImage,
30237
- assetBaseUrl
30096
+ assetBaseUrl,
30097
+ effects
30238
30098
  };
30239
30099
  const handleKeyDown = useCallback((e) => {
30240
30100
  if (keysRef.current.has(e.code)) return;
@@ -30301,7 +30161,8 @@ function PlatformerCanvas({
30301
30161
  bgColor: bg,
30302
30162
  playerSprite: pSprite,
30303
30163
  tileSprites: tSprites,
30304
- backgroundImage: bgImg
30164
+ backgroundImage: bgImg,
30165
+ effects: fxList
30305
30166
  } = propsRef.current;
30306
30167
  const auth = playerRef.current;
30307
30168
  const interped = positions.get("player");
@@ -30455,6 +30316,18 @@ function PlatformerCanvas({
30455
30316
  ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
30456
30317
  ctx.fill();
30457
30318
  }
30319
+ for (const fx of fxList) {
30320
+ const fxScreenX = fx.x - camX;
30321
+ const fxScreenY = fx.y - camY;
30322
+ const alpha = Math.min(1, fx.ttl / 4);
30323
+ const prev = ctx.globalAlpha;
30324
+ ctx.globalAlpha = alpha;
30325
+ ctx.fillStyle = "#ffe066";
30326
+ ctx.beginPath();
30327
+ ctx.arc(fxScreenX, fxScreenY, 12, 0, Math.PI * 2);
30328
+ ctx.fill();
30329
+ ctx.globalAlpha = prev;
30330
+ }
30458
30331
  };
30459
30332
  return interp.startLoop(drawFrame);
30460
30333
  }, [interp.startLoop, loadImage]);
@@ -30868,13 +30741,13 @@ var init_MapView = __esm({
30868
30741
  shadowSize: [41, 41]
30869
30742
  });
30870
30743
  L.Marker.prototype.options.icon = defaultIcon;
30871
- const { useEffect: useEffect83, useRef: useRef80, useCallback: useCallback126, useState: useState113 } = React86__default;
30744
+ const { useEffect: useEffect81, useRef: useRef80, useCallback: useCallback126, useState: useState111 } = React88__default;
30872
30745
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
30873
30746
  const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
30874
30747
  function MapUpdater({ centerLat, centerLng, zoom }) {
30875
30748
  const map = useMap();
30876
30749
  const prevRef = useRef80({ centerLat, centerLng, zoom });
30877
- useEffect83(() => {
30750
+ useEffect81(() => {
30878
30751
  const prev = prevRef.current;
30879
30752
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
30880
30753
  map.setView([centerLat, centerLng], zoom);
@@ -30885,7 +30758,7 @@ var init_MapView = __esm({
30885
30758
  }
30886
30759
  function MapClickHandler({ onMapClick }) {
30887
30760
  const map = useMap();
30888
- useEffect83(() => {
30761
+ useEffect81(() => {
30889
30762
  if (!onMapClick) return;
30890
30763
  const handler = (e) => {
30891
30764
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -30913,7 +30786,7 @@ var init_MapView = __esm({
30913
30786
  showAttribution = true
30914
30787
  }) {
30915
30788
  const eventBus = useEventBus3();
30916
- const [clickedPosition, setClickedPosition] = useState113(null);
30789
+ const [clickedPosition, setClickedPosition] = useState111(null);
30917
30790
  const handleMapClick = useCallback126((lat, lng) => {
30918
30791
  if (showClickedPin) {
30919
30792
  setClickedPosition({ lat, lng });
@@ -31704,6 +31577,15 @@ function renderIconInput3(icon, props) {
31704
31577
  function columnLabel(col) {
31705
31578
  return col.header ?? col.label ?? col.key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
31706
31579
  }
31580
+ function asFieldValue(v) {
31581
+ if (v === void 0 || v === null) return v;
31582
+ const t = typeof v;
31583
+ if (t === "string" || t === "number" || t === "boolean") return v;
31584
+ if (v instanceof Date) return v;
31585
+ if (Array.isArray(v)) return v;
31586
+ if (t === "object") return v;
31587
+ return void 0;
31588
+ }
31707
31589
  function statusVariant4(value) {
31708
31590
  const v = value.toLowerCase();
31709
31591
  if (["active", "completed", "done", "approved", "published", "resolved", "open", "online", "ok"].includes(v)) return "success";
@@ -31774,8 +31656,8 @@ function TableView({
31774
31656
  }) {
31775
31657
  const eventBus = useEventBus();
31776
31658
  const { t } = useTranslate();
31777
- const [visibleCount, setVisibleCount] = React86__default.useState(pageSize > 0 ? pageSize : Infinity);
31778
- const [localSelected, setLocalSelected] = React86__default.useState(/* @__PURE__ */ new Set());
31659
+ const [visibleCount, setVisibleCount] = React88__default.useState(pageSize > 0 ? pageSize : Infinity);
31660
+ const [localSelected, setLocalSelected] = React88__default.useState(/* @__PURE__ */ new Set());
31779
31661
  const colDefs = columns ?? fields ?? [];
31780
31662
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
31781
31663
  const dnd = useDataDnd({
@@ -31920,7 +31802,7 @@ function TableView({
31920
31802
  }
31921
31803
  ) }),
31922
31804
  hasRenderProp ? /* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: children(row, index) }) : colDefs.map((col) => {
31923
- const raw = getNestedValue(row, col.field ?? col.key);
31805
+ const raw = asFieldValue(getNestedValue(row, col.field ?? col.key));
31924
31806
  const cellBase = cn(
31925
31807
  "flex items-center min-w-0",
31926
31808
  alignClass[col.align ?? "left"],
@@ -31970,12 +31852,12 @@ function TableView({
31970
31852
  ]
31971
31853
  }
31972
31854
  );
31973
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React86__default.Fragment, { children: rowInner }, id);
31855
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React88__default.Fragment, { children: rowInner }, id);
31974
31856
  };
31975
- const items = data.map((row) => row);
31857
+ const items = Array.from(data);
31976
31858
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
31977
31859
  let runningIndex = 0;
31978
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
31860
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
31979
31861
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
31980
31862
  group.items.map((row) => renderRow(row, runningIndex++))
31981
31863
  ] }, gi)) });
@@ -33332,7 +33214,7 @@ var init_StepFlow = __esm({
33332
33214
  className
33333
33215
  }) => {
33334
33216
  if (orientation === "vertical") {
33335
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React86__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
33217
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React88__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
33336
33218
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
33337
33219
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
33338
33220
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -33343,7 +33225,7 @@ var init_StepFlow = __esm({
33343
33225
  ] })
33344
33226
  ] }) }, index)) });
33345
33227
  }
33346
- return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
33228
+ return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
33347
33229
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
33348
33230
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
33349
33231
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -34328,7 +34210,7 @@ var init_LikertScale = __esm({
34328
34210
  md: "text-base",
34329
34211
  lg: "text-lg"
34330
34212
  };
34331
- LikertScale = React86__default.forwardRef(
34213
+ LikertScale = React88__default.forwardRef(
34332
34214
  ({
34333
34215
  question,
34334
34216
  options = DEFAULT_LIKERT_OPTIONS,
@@ -34340,7 +34222,7 @@ var init_LikertScale = __esm({
34340
34222
  variant = "radios",
34341
34223
  className
34342
34224
  }, ref) => {
34343
- const groupId = React86__default.useId();
34225
+ const groupId = React88__default.useId();
34344
34226
  const eventBus = useEventBus();
34345
34227
  const handleSelect = useCallback(
34346
34228
  (next) => {
@@ -35235,11 +35117,11 @@ function nextBlockId(prefix = "blk") {
35235
35117
  function normalizeBlocks(raw) {
35236
35118
  if (!Array.isArray(raw) || raw.length === 0) return [createBlock("paragraph")];
35237
35119
  return raw.map((row) => {
35238
- const r = row;
35239
- const rawType = r.type;
35120
+ const entity = row;
35121
+ const rawType = entity.type;
35240
35122
  const type = typeof rawType === "string" && BLOCK_TYPES.has(rawType) ? rawType : "paragraph";
35241
- const id = typeof r.id === "string" && r.id ? r.id : nextBlockId(type);
35242
- return { ...r, id, type };
35123
+ const id = typeof entity.id === "string" && entity.id ? entity.id : nextBlockId(type);
35124
+ return { ...entity, id, type };
35243
35125
  });
35244
35126
  }
35245
35127
  function createBlock(type) {
@@ -36622,7 +36504,7 @@ var init_DocBreadcrumb = __esm({
36622
36504
  "aria-label": t("aria.breadcrumb"),
36623
36505
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
36624
36506
  const isLast = idx === items.length - 1;
36625
- return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
36507
+ return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
36626
36508
  idx > 0 && /* @__PURE__ */ jsx(
36627
36509
  Icon,
36628
36510
  {
@@ -37490,8 +37372,8 @@ var init_MiniStateMachine = __esm({
37490
37372
  states.map((s, i) => {
37491
37373
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
37492
37374
  const tc = transitionCounts[s.name] ?? 0;
37493
- const role = getStateRole(s.name, s.isInitial, s.isTerminal, tc, maxTC);
37494
- return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
37375
+ const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
37376
+ return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
37495
37377
  /* @__PURE__ */ jsx(
37496
37378
  AvlState,
37497
37379
  {
@@ -37501,8 +37383,8 @@ var init_MiniStateMachine = __esm({
37501
37383
  height: NODE_H,
37502
37384
  name: "",
37503
37385
  role,
37504
- isInitial: s.isInitial,
37505
- isTerminal: s.isTerminal
37386
+ isInitial: s.isInitial ?? void 0,
37387
+ isTerminal: s.isTerminal ?? void 0
37506
37388
  }
37507
37389
  ),
37508
37390
  i < states.length - 1 && /* @__PURE__ */ jsxs("g", { children: [
@@ -37695,7 +37577,7 @@ var init_PageHeader = __esm({
37695
37577
  info: "bg-info/10 text-info"
37696
37578
  };
37697
37579
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
37698
- breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
37580
+ breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
37699
37581
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
37700
37582
  crumb.href ? /* @__PURE__ */ jsx(
37701
37583
  "a",
@@ -38053,52 +37935,49 @@ var init_Section = __esm({
38053
37935
  as: Component2 = "section"
38054
37936
  }) => {
38055
37937
  const hasHeader = title || description || action;
38056
- const Comp = Component2;
38057
- return /* @__PURE__ */ jsxs(
38058
- Comp,
37938
+ return React88__default.createElement(
37939
+ Component2,
38059
37940
  {
38060
37941
  className: cn(
38061
37942
  paddingStyles4[padding],
38062
37943
  variantStyles9[variant],
38063
37944
  className
38064
- ),
38065
- children: [
38066
- hasHeader && /* @__PURE__ */ jsxs(
38067
- Box,
38068
- {
38069
- className: cn(
38070
- "flex flex-col sm:flex-row sm:items-start sm:justify-between gap-2 sm:gap-4",
38071
- divider && "pb-4 mb-4 border-b-[length:var(--border-width)] border-border",
38072
- !divider && "mb-4",
38073
- headerClassName
38074
- ),
38075
- children: [
38076
- /* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
38077
- title && /* @__PURE__ */ jsx(
38078
- Typography,
38079
- {
38080
- variant: "h4",
38081
- className: "text-foreground font-semibold",
38082
- children: title
38083
- }
38084
- ),
38085
- description && /* @__PURE__ */ jsx(
38086
- Typography,
38087
- {
38088
- variant: "body",
38089
- color: "muted",
38090
- className: "mt-1",
38091
- children: description
38092
- }
38093
- )
38094
- ] }),
38095
- action && /* @__PURE__ */ jsx(Box, { className: "flex-shrink-0 flex items-center gap-2", children: action })
38096
- ]
38097
- }
37945
+ )
37946
+ },
37947
+ hasHeader && /* @__PURE__ */ jsxs(
37948
+ Box,
37949
+ {
37950
+ className: cn(
37951
+ "flex flex-col sm:flex-row sm:items-start sm:justify-between gap-2 sm:gap-4",
37952
+ divider && "pb-4 mb-4 border-b-[length:var(--border-width)] border-border",
37953
+ !divider && "mb-4",
37954
+ headerClassName
38098
37955
  ),
38099
- /* @__PURE__ */ jsx(Box, { className: contentClassName, children })
38100
- ]
38101
- }
37956
+ children: [
37957
+ /* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
37958
+ title && /* @__PURE__ */ jsx(
37959
+ Typography,
37960
+ {
37961
+ variant: "h4",
37962
+ className: "text-foreground font-semibold",
37963
+ children: title
37964
+ }
37965
+ ),
37966
+ description && /* @__PURE__ */ jsx(
37967
+ Typography,
37968
+ {
37969
+ variant: "body",
37970
+ color: "muted",
37971
+ className: "mt-1",
37972
+ children: description
37973
+ }
37974
+ )
37975
+ ] }),
37976
+ action && /* @__PURE__ */ jsx(Box, { className: "flex-shrink-0 flex items-center gap-2", children: action })
37977
+ ]
37978
+ }
37979
+ ),
37980
+ /* @__PURE__ */ jsx(Box, { className: contentClassName, children })
38102
37981
  );
38103
37982
  };
38104
37983
  Section.displayName = "Section";
@@ -38424,7 +38303,7 @@ var init_WizardContainer = __esm({
38424
38303
  const isCompleted = index < currentStep;
38425
38304
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
38426
38305
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
38427
- return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
38306
+ return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
38428
38307
  /* @__PURE__ */ jsx(
38429
38308
  Button,
38430
38309
  {
@@ -40367,6 +40246,22 @@ var init_DataTable = __esm({
40367
40246
  DataTable.displayName = "DataTable";
40368
40247
  }
40369
40248
  });
40249
+ function toDebuggerLine(v) {
40250
+ if (v === null || typeof v !== "object" || Array.isArray(v) || v instanceof Date) return null;
40251
+ const id = v["id"];
40252
+ const content = v["content"];
40253
+ const isBug = v["isBug"];
40254
+ if (typeof id !== "string" || typeof content !== "string" || typeof isBug !== "boolean") return null;
40255
+ const isFlagged = v["isFlagged"];
40256
+ const explanation = v["explanation"];
40257
+ return {
40258
+ id,
40259
+ content,
40260
+ isBug,
40261
+ isFlagged: typeof isFlagged === "boolean" ? isFlagged : void 0,
40262
+ explanation: typeof explanation === "string" ? explanation : void 0
40263
+ };
40264
+ }
40370
40265
  function DebuggerBoard({
40371
40266
  entity,
40372
40267
  completeEvent = "PUZZLE_COMPLETE",
@@ -40379,7 +40274,10 @@ function DebuggerBoard({
40379
40274
  const { t } = useTranslate();
40380
40275
  const resolved = boardEntity(entity);
40381
40276
  const [headerError, setHeaderError] = useState(false);
40382
- const lines = Array.isArray(resolved?.lines) ? resolved.lines : [];
40277
+ const lines = Array.isArray(resolved?.lines) ? resolved.lines.flatMap((v) => {
40278
+ const l = toDebuggerLine(v);
40279
+ return l ? [l] : [];
40280
+ }) : [];
40383
40281
  const result = str(resolved?.result) || "none";
40384
40282
  const attempts = num(resolved?.attempts);
40385
40283
  const submitted = result === "win";
@@ -40984,7 +40882,7 @@ var init_DetailPanel = __esm({
40984
40882
  }
40985
40883
  });
40986
40884
  function extractTitle(children) {
40987
- if (!React86__default.isValidElement(children)) return void 0;
40885
+ if (!React88__default.isValidElement(children)) return void 0;
40988
40886
  const props = children.props;
40989
40887
  if (typeof props.title === "string") {
40990
40888
  return props.title;
@@ -41039,7 +40937,7 @@ function LinearView({
41039
40937
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
41040
40938
  const isDone = i < currentIdx;
41041
40939
  const isCurrent = i === currentIdx;
41042
- return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
40940
+ return /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
41043
40941
  i > 0 && /* @__PURE__ */ jsx(
41044
40942
  Typography,
41045
40943
  {
@@ -41861,12 +41759,12 @@ function evaluateFormExpression(expr, formCtx) {
41861
41759
  return evaluate(expr, ctx);
41862
41760
  }
41863
41761
  function isOrbitalEntitySchema(value) {
41864
- if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
41762
+ if (value === null || value === void 0 || typeof value !== "object" || Array.isArray(value)) return false;
41865
41763
  const fields = value.fields;
41866
41764
  return Array.isArray(fields);
41867
41765
  }
41868
41766
  function isPlainEntityRow(value) {
41869
- if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
41767
+ if (value === null || value === void 0 || typeof value !== "object" || Array.isArray(value)) return false;
41870
41768
  const fields = value.fields;
41871
41769
  return !Array.isArray(fields);
41872
41770
  }
@@ -42025,12 +41923,12 @@ var init_Form = __esm({
42025
41923
  const isSchemaEntity = isOrbitalEntitySchema(entity);
42026
41924
  const resolvedEntity = isSchemaEntity ? entity : void 0;
42027
41925
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
42028
- const normalizedInitialData = React86__default.useMemo(() => {
41926
+ const normalizedInitialData = React88__default.useMemo(() => {
42029
41927
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
42030
41928
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
42031
41929
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
42032
41930
  }, [entity, initialData]);
42033
- const entityDerivedFields = React86__default.useMemo(() => {
41931
+ const entityDerivedFields = React88__default.useMemo(() => {
42034
41932
  if (fields && fields.length > 0) return void 0;
42035
41933
  if (!resolvedEntity) return void 0;
42036
41934
  return resolvedEntity.fields.map(
@@ -42038,6 +41936,7 @@ var init_Form = __esm({
42038
41936
  name: f3.name,
42039
41937
  type: f3.type,
42040
41938
  required: f3.required,
41939
+ // EntityField.default is typed `unknown` upstream — safe cast: schema defaults are always FieldValues.
42041
41940
  defaultValue: f3.default,
42042
41941
  // EntityField is a discriminated union — `values` lives on Scalar/Enum, `relation` lives on Relation.
42043
41942
  values: "values" in f3 ? f3.values : void 0,
@@ -42050,16 +41949,16 @@ var init_Form = __esm({
42050
41949
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
42051
41950
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
42052
41951
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
42053
- const [formData, setFormData] = React86__default.useState(
41952
+ const [formData, setFormData] = React88__default.useState(
42054
41953
  normalizedInitialData
42055
41954
  );
42056
- const [collapsedSections, setCollapsedSections] = React86__default.useState(
41955
+ const [collapsedSections, setCollapsedSections] = React88__default.useState(
42057
41956
  /* @__PURE__ */ new Set()
42058
41957
  );
42059
- const [submitError, setSubmitError] = React86__default.useState(null);
42060
- const formRef = React86__default.useRef(null);
41958
+ const [submitError, setSubmitError] = React88__default.useState(null);
41959
+ const formRef = React88__default.useRef(null);
42061
41960
  const formMode = props.mode;
42062
- const mountedRef = React86__default.useRef(false);
41961
+ const mountedRef = React88__default.useRef(false);
42063
41962
  if (!mountedRef.current) {
42064
41963
  mountedRef.current = true;
42065
41964
  debug("forms", "mount", {
@@ -42072,7 +41971,7 @@ var init_Form = __esm({
42072
41971
  });
42073
41972
  }
42074
41973
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
42075
- const evalContext = React86__default.useMemo(
41974
+ const evalContext = React88__default.useMemo(
42076
41975
  () => ({
42077
41976
  formValues: formData,
42078
41977
  globalVariables: externalContext?.globalVariables ?? {},
@@ -42081,7 +41980,7 @@ var init_Form = __esm({
42081
41980
  }),
42082
41981
  [formData, externalContext]
42083
41982
  );
42084
- React86__default.useEffect(() => {
41983
+ React88__default.useEffect(() => {
42085
41984
  debug("forms", "initialData-sync", {
42086
41985
  mode: formMode,
42087
41986
  normalizedInitialData,
@@ -42092,7 +41991,7 @@ var init_Form = __esm({
42092
41991
  setFormData(normalizedInitialData);
42093
41992
  }
42094
41993
  }, [normalizedInitialData]);
42095
- const processCalculations = React86__default.useCallback(
41994
+ const processCalculations = React88__default.useCallback(
42096
41995
  (changedFieldId, newFormData) => {
42097
41996
  if (!hiddenCalculations.length) return;
42098
41997
  const context = {
@@ -42117,7 +42016,7 @@ var init_Form = __esm({
42117
42016
  },
42118
42017
  [hiddenCalculations, externalContext, eventBus]
42119
42018
  );
42120
- const checkViolations = React86__default.useCallback(
42019
+ const checkViolations = React88__default.useCallback(
42121
42020
  (changedFieldId, newFormData) => {
42122
42021
  if (!violationTriggers.length) return;
42123
42022
  const context = {
@@ -42155,7 +42054,7 @@ var init_Form = __esm({
42155
42054
  processCalculations(name, newFormData);
42156
42055
  checkViolations(name, newFormData);
42157
42056
  };
42158
- const isFieldVisible = React86__default.useCallback(
42057
+ const isFieldVisible = React88__default.useCallback(
42159
42058
  (fieldName) => {
42160
42059
  const condition = conditionalFields[fieldName];
42161
42060
  if (!condition) return true;
@@ -42163,7 +42062,7 @@ var init_Form = __esm({
42163
42062
  },
42164
42063
  [conditionalFields, evalContext]
42165
42064
  );
42166
- const isSectionVisible = React86__default.useCallback(
42065
+ const isSectionVisible = React88__default.useCallback(
42167
42066
  (section) => {
42168
42067
  if (!section.condition) return true;
42169
42068
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -42239,7 +42138,7 @@ var init_Form = __esm({
42239
42138
  eventBus.emit(`UI:${onCancel}`);
42240
42139
  }
42241
42140
  };
42242
- const renderField = React86__default.useCallback(
42141
+ const renderField = React88__default.useCallback(
42243
42142
  (field) => {
42244
42143
  const fieldName = field.name || field.field;
42245
42144
  if (!fieldName) return null;
@@ -42260,7 +42159,7 @@ var init_Form = __esm({
42260
42159
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
42261
42160
  );
42262
42161
  const effectiveFields = entityDerivedFields ?? fields;
42263
- const normalizedFields = React86__default.useMemo(() => {
42162
+ const normalizedFields = React88__default.useMemo(() => {
42264
42163
  if (!effectiveFields || effectiveFields.length === 0) return [];
42265
42164
  return effectiveFields.map((field) => {
42266
42165
  if (typeof field === "string") {
@@ -42270,6 +42169,7 @@ var init_Form = __esm({
42270
42169
  name: field,
42271
42170
  type: entityField.type,
42272
42171
  required: entityField.required,
42172
+ // EntityField.default is typed `unknown` upstream — safe cast: schema defaults are always FieldValues.
42273
42173
  defaultValue: entityField.default,
42274
42174
  // EntityField is a discriminated union — `values` lives on Scalar/Enum, `relation` lives on Relation.
42275
42175
  values: "values" in entityField ? entityField.values : void 0,
@@ -42283,7 +42183,7 @@ var init_Form = __esm({
42283
42183
  return field;
42284
42184
  });
42285
42185
  }, [effectiveFields, resolvedEntity]);
42286
- const schemaFields = React86__default.useMemo(() => {
42186
+ const schemaFields = React88__default.useMemo(() => {
42287
42187
  if (normalizedFields.length === 0) return null;
42288
42188
  if (isDebugEnabled()) {
42289
42189
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -42293,7 +42193,7 @@ var init_Form = __esm({
42293
42193
  }
42294
42194
  return normalizedFields.map(renderField).filter(Boolean);
42295
42195
  }, [normalizedFields, renderField, entityName, conditionalFields]);
42296
- const sectionElements = React86__default.useMemo(() => {
42196
+ const sectionElements = React88__default.useMemo(() => {
42297
42197
  if (!sections || sections.length === 0) return null;
42298
42198
  return sections.map((section) => {
42299
42199
  if (!isSectionVisible(section)) {
@@ -43814,7 +43714,6 @@ var init_GameCanvas3D2 = __esm({
43814
43714
  className,
43815
43715
  isLoading: externalLoading,
43816
43716
  error: externalError,
43817
- entity,
43818
43717
  preloadAssets = [],
43819
43718
  tileClickEvent,
43820
43719
  unitClickEvent,
@@ -44549,6 +44448,14 @@ var init_GameBoard3D = __esm({
44549
44448
  GameBoard3D.displayName = "GameBoard3D";
44550
44449
  }
44551
44450
  });
44451
+ function asDescriptor(v) {
44452
+ if (Array.isArray(v) || React88__default.isValidElement(v)) return null;
44453
+ const o = v;
44454
+ if (typeof o.type !== "string") return null;
44455
+ const props = o.props !== void 0 && typeof o.props === "object" && !Array.isArray(o.props) && o.props !== null ? o.props : void 0;
44456
+ const _id = typeof o._id === "string" ? o._id : void 0;
44457
+ return { type: o.type, props, _id };
44458
+ }
44552
44459
  function getSlotContentRenderer2() {
44553
44460
  if (_scr) return _scr;
44554
44461
  const mod = (init_UISlotRenderer(), __toCommonJS(UISlotRenderer_exports));
@@ -44557,17 +44464,16 @@ function getSlotContentRenderer2() {
44557
44464
  }
44558
44465
  function resolveDescriptor(value, idPrefix) {
44559
44466
  if (value === null || value === void 0) return value;
44560
- if (React86__default.isValidElement(value)) return value;
44467
+ if (React88__default.isValidElement(value)) return value;
44561
44468
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
44562
44469
  if (Array.isArray(value)) {
44563
- return value.map((item, i) => /* @__PURE__ */ jsx(React86__default.Fragment, { children: resolveDescriptor(item, `${idPrefix}-${i}`) }, i));
44470
+ return value.map((item, i) => /* @__PURE__ */ jsx(React88__default.Fragment, { children: resolveDescriptor(item, `${idPrefix}-${i}`) }, i));
44564
44471
  }
44565
- if (typeof value === "object") {
44566
- const rec = value;
44567
- if (typeof rec.type === "string" && getComponentForPattern(rec.type) !== null) {
44568
- const { type, props: nestedProps, _id, ...flatProps } = rec;
44569
- const resolvedProps = nestedProps !== void 0 ? nestedProps : flatProps;
44570
- const content = { id: _id ?? idPrefix, pattern: type, props: resolvedProps, priority: 0 };
44472
+ if (typeof value === "object" && value !== null) {
44473
+ const desc = asDescriptor(value);
44474
+ if (desc !== null && getComponentForPattern(desc.type) !== null) {
44475
+ const resolvedProps = desc.props ?? {};
44476
+ const content = { id: desc._id ?? idPrefix, pattern: desc.type, props: resolvedProps, priority: 0 };
44571
44477
  const SCR = getSlotContentRenderer2();
44572
44478
  return /* @__PURE__ */ jsx(SCR, { content, onDismiss: () => void 0 });
44573
44479
  }
@@ -44661,16 +44567,19 @@ function getSlotContentRenderer3() {
44661
44567
  }
44662
44568
  function resolveDescriptor2(value, idPrefix) {
44663
44569
  if (value === null || value === void 0) return value;
44664
- if (React86__default.isValidElement(value)) return value;
44570
+ if (React88__default.isValidElement(value)) return value;
44665
44571
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
44666
44572
  if (Array.isArray(value)) {
44667
- return value.map((item, i) => /* @__PURE__ */ jsx(React86__default.Fragment, { children: resolveDescriptor2(item, `${idPrefix}-${i}`) }, i));
44573
+ return value.map((item, i) => /* @__PURE__ */ jsx(React88__default.Fragment, { children: resolveDescriptor2(item, `${idPrefix}-${i}`) }, i));
44668
44574
  }
44669
44575
  if (typeof value === "object") {
44670
44576
  const rec = value;
44671
44577
  if (typeof rec.type === "string" && getComponentForPattern(rec.type) !== null) {
44672
- const { type, props: nestedProps, _id, ...flatProps } = rec;
44673
- const resolvedProps = nestedProps !== void 0 ? nestedProps : flatProps;
44578
+ const type = rec.type;
44579
+ const _id = typeof rec._id === "string" ? rec._id : void 0;
44580
+ const nestedProps = rec.props !== void 0 && typeof rec.props === "object" && !Array.isArray(rec.props) && rec.props !== null ? rec.props : void 0;
44581
+ const { type: _t, props: _p, _id: _d, ...flatRest } = rec;
44582
+ const resolvedProps = nestedProps !== void 0 ? nestedProps : flatRest;
44674
44583
  const content = { id: _id ?? idPrefix, pattern: type, props: resolvedProps, priority: 0 };
44675
44584
  const SCR = getSlotContentRenderer3();
44676
44585
  return /* @__PURE__ */ jsx(SCR, { content, onDismiss: () => void 0 });
@@ -45374,7 +45283,7 @@ var init_List = __esm({
45374
45283
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
45375
45284
  return [];
45376
45285
  }, [entity]);
45377
- const getItemActions = React86__default.useCallback(
45286
+ const getItemActions = React88__default.useCallback(
45378
45287
  (item) => {
45379
45288
  if (!itemActions) return [];
45380
45289
  if (typeof itemActions === "function") {
@@ -45431,15 +45340,14 @@ var init_List = __esm({
45431
45340
  };
45432
45341
  if (effectiveFieldNames && effectiveFieldNames.length > 0) {
45433
45342
  const firstField = effectiveFieldNames[0];
45434
- const itemRecord = item;
45435
- if (!normalizedItem.title && getNestedValue(itemRecord, firstField)) {
45343
+ if (!normalizedItem.title && getNestedValue(item, firstField)) {
45436
45344
  normalizedItem.title = String(
45437
- getNestedValue(itemRecord, firstField)
45345
+ getNestedValue(item, firstField)
45438
45346
  );
45439
45347
  }
45440
45348
  normalizedItem._fields = effectiveFieldNames.reduce(
45441
45349
  (acc, field) => {
45442
- const value = getNestedValue(itemRecord, field);
45350
+ const value = getNestedValue(item, field);
45443
45351
  if (value !== void 0 && value !== null) {
45444
45352
  acc[field] = value;
45445
45353
  }
@@ -45892,16 +45800,18 @@ var init_MediaGallery = __esm({
45892
45800
  [selectable, selectedItems, selectionEvent, eventBus]
45893
45801
  );
45894
45802
  const entityData = Array.isArray(entity) ? entity : [];
45895
- const items = React86__default.useMemo(() => {
45803
+ const items = React88__default.useMemo(() => {
45896
45804
  if (propItems) return propItems;
45897
45805
  if (entityData.length === 0) return [];
45898
- return entityData.map((record, idx) => ({
45899
- id: String(record.id ?? idx),
45900
- src: String(record.src ?? record.url ?? record.image ?? ""),
45901
- alt: record.alt ? String(record.alt) : void 0,
45902
- thumbnail: record.thumbnail ? String(record.thumbnail) : void 0,
45903
- caption: record.caption ? String(record.caption) : record.title ? String(record.title) : void 0
45904
- }));
45806
+ return entityData.map((record, idx) => {
45807
+ return {
45808
+ id: String(record.id ?? idx),
45809
+ src: String(record.src ?? ("url" in record ? record.url : "") ?? ("image" in record ? record.image : "") ?? ""),
45810
+ alt: record.alt ? String(record.alt) : void 0,
45811
+ thumbnail: record.thumbnail ? String(record.thumbnail) : void 0,
45812
+ caption: record.caption ? String(record.caption) : "title" in record ? String(record.title) : void 0
45813
+ };
45814
+ });
45905
45815
  }, [propItems, entityData]);
45906
45816
  if (isLoading) {
45907
45817
  return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
@@ -46095,7 +46005,7 @@ var init_MinigolfBoard = __esm({
46095
46005
  }
46096
46006
  });
46097
46007
  function extractTitle2(children) {
46098
- if (!React86__default.isValidElement(children)) return void 0;
46008
+ if (!React88__default.isValidElement(children)) return void 0;
46099
46009
  const props = children.props;
46100
46010
  if (typeof props.title === "string") {
46101
46011
  return props.title;
@@ -46161,8 +46071,16 @@ function NegotiatorBoard({
46161
46071
  const lastPlayerAction = str(resolved?.lastPlayerAction);
46162
46072
  const lastOpponentAction = str(resolved?.lastOpponentAction);
46163
46073
  const lastPayoff = num(resolved?.lastPayoff);
46164
- const actions = Array.isArray(resolved?.actions) ? resolved.actions : [];
46165
- const payoffMatrix = Array.isArray(resolved?.payoffMatrix) ? resolved.payoffMatrix : [];
46074
+ const actions = Array.isArray(resolved?.actions) ? resolved.actions.flatMap((item) => {
46075
+ if (item !== null && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && typeof item.id === "string" && typeof item.label === "string")
46076
+ return [{ id: item.id, label: item.label, description: typeof item.description === "string" ? item.description : void 0 }];
46077
+ return [];
46078
+ }) : [];
46079
+ const payoffMatrix = Array.isArray(resolved?.payoffMatrix) ? resolved.payoffMatrix.flatMap((item) => {
46080
+ if (item !== null && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && typeof item.playerAction === "string" && typeof item.opponentAction === "string")
46081
+ return [{ playerAction: item.playerAction, opponentAction: item.opponentAction, playerPayoff: typeof item.playerPayoff === "number" ? item.playerPayoff : 0, opponentPayoff: typeof item.opponentPayoff === "number" ? item.opponentPayoff : 0 }];
46082
+ return [];
46083
+ }) : [];
46166
46084
  const prevRoundRef = useRef(currentRound);
46167
46085
  useEffect(() => {
46168
46086
  if (currentRound > prevRoundRef.current && lastPlayerAction) {
@@ -47269,7 +47187,7 @@ var init_debugRegistry = __esm({
47269
47187
  }
47270
47188
  });
47271
47189
  function useDebugData() {
47272
- const [data, setData] = React86.useState(() => ({
47190
+ const [data, setData] = React88.useState(() => ({
47273
47191
  traits: [],
47274
47192
  ticks: [],
47275
47193
  guards: [],
@@ -47283,7 +47201,7 @@ function useDebugData() {
47283
47201
  },
47284
47202
  lastUpdate: Date.now()
47285
47203
  }));
47286
- React86.useEffect(() => {
47204
+ React88.useEffect(() => {
47287
47205
  const updateData = () => {
47288
47206
  setData({
47289
47207
  traits: getAllTraits(),
@@ -47392,12 +47310,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
47392
47310
  return positions;
47393
47311
  }
47394
47312
  function WalkMinimap() {
47395
- const [walkStep, setWalkStep] = React86.useState(null);
47396
- const [traits2, setTraits] = React86.useState([]);
47397
- const [coveredEdges, setCoveredEdges] = React86.useState([]);
47398
- const [completedTraits, setCompletedTraits] = React86.useState(/* @__PURE__ */ new Set());
47399
- const prevTraitRef = React86.useRef(null);
47400
- React86.useEffect(() => {
47313
+ const [walkStep, setWalkStep] = React88.useState(null);
47314
+ const [traits2, setTraits] = React88.useState([]);
47315
+ const [coveredEdges, setCoveredEdges] = React88.useState([]);
47316
+ const [completedTraits, setCompletedTraits] = React88.useState(/* @__PURE__ */ new Set());
47317
+ const prevTraitRef = React88.useRef(null);
47318
+ React88.useEffect(() => {
47401
47319
  const interval = setInterval(() => {
47402
47320
  const w = window;
47403
47321
  const step = w.__orbitalWalkStep;
@@ -47833,15 +47751,15 @@ var init_EntitiesTab = __esm({
47833
47751
  });
47834
47752
  function EventFlowTab({ events: events2 }) {
47835
47753
  const { t } = useTranslate();
47836
- const [filter, setFilter] = React86.useState("all");
47837
- const containerRef = React86.useRef(null);
47838
- const [autoScroll, setAutoScroll] = React86.useState(true);
47839
- React86.useEffect(() => {
47754
+ const [filter, setFilter] = React88.useState("all");
47755
+ const containerRef = React88.useRef(null);
47756
+ const [autoScroll, setAutoScroll] = React88.useState(true);
47757
+ React88.useEffect(() => {
47840
47758
  if (autoScroll && containerRef.current) {
47841
47759
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
47842
47760
  }
47843
47761
  }, [events2.length, autoScroll]);
47844
- const filteredEvents = React86.useMemo(() => {
47762
+ const filteredEvents = React88.useMemo(() => {
47845
47763
  if (filter === "all") return events2;
47846
47764
  return events2.filter((e) => e.type === filter);
47847
47765
  }, [events2, filter]);
@@ -47957,7 +47875,7 @@ var init_EventFlowTab = __esm({
47957
47875
  });
47958
47876
  function GuardsPanel({ guards }) {
47959
47877
  const { t } = useTranslate();
47960
- const [filter, setFilter] = React86.useState("all");
47878
+ const [filter, setFilter] = React88.useState("all");
47961
47879
  if (guards.length === 0) {
47962
47880
  return /* @__PURE__ */ jsx(
47963
47881
  EmptyState,
@@ -47970,7 +47888,7 @@ function GuardsPanel({ guards }) {
47970
47888
  }
47971
47889
  const passedCount = guards.filter((g) => g.result).length;
47972
47890
  const failedCount = guards.length - passedCount;
47973
- const filteredGuards = React86.useMemo(() => {
47891
+ const filteredGuards = React88.useMemo(() => {
47974
47892
  if (filter === "all") return guards;
47975
47893
  if (filter === "passed") return guards.filter((g) => g.result);
47976
47894
  return guards.filter((g) => !g.result);
@@ -48133,10 +48051,10 @@ function EffectBadge({ effect }) {
48133
48051
  }
48134
48052
  function TransitionTimeline({ transitions }) {
48135
48053
  const { t } = useTranslate();
48136
- const containerRef = React86.useRef(null);
48137
- const [autoScroll, setAutoScroll] = React86.useState(true);
48138
- const [expandedId, setExpandedId] = React86.useState(null);
48139
- React86.useEffect(() => {
48054
+ const containerRef = React88.useRef(null);
48055
+ const [autoScroll, setAutoScroll] = React88.useState(true);
48056
+ const [expandedId, setExpandedId] = React88.useState(null);
48057
+ React88.useEffect(() => {
48140
48058
  if (autoScroll && containerRef.current) {
48141
48059
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
48142
48060
  }
@@ -48342,18 +48260,18 @@ var init_ServerBridgeTab = __esm({
48342
48260
  });
48343
48261
  function extractPayloadFields(schema, eventName) {
48344
48262
  if (!schema) return [];
48345
- const orbitals = schema.orbitals;
48346
- if (!orbitals) return [];
48347
- for (const orbital of orbitals) {
48348
- const traits2 = orbital.traits ?? [];
48349
- for (const trait of traits2) {
48350
- const sm = trait.stateMachine;
48263
+ for (const orbital of schema.orbitals) {
48264
+ const traitRefs = orbital.traits ?? [];
48265
+ for (const traitRef of traitRefs) {
48266
+ if (!isInlineTrait(traitRef)) continue;
48267
+ const inlineTrait = traitRef;
48268
+ const sm = inlineTrait.stateMachine;
48351
48269
  if (!sm) continue;
48352
48270
  const events2 = sm.events ?? [];
48353
48271
  for (const evt of events2) {
48354
48272
  if (evt.name !== eventName) continue;
48355
- const payload = evt.payload ?? [];
48356
- return payload.map((f3) => ({
48273
+ const payloadFields = evt.payloadSchema ?? [];
48274
+ return payloadFields.map((f3) => ({
48357
48275
  name: f3.name,
48358
48276
  type: f3.type ?? "string"
48359
48277
  }));
@@ -48416,9 +48334,9 @@ function getAllEvents(traits2) {
48416
48334
  function EventDispatcherTab({ traits: traits2, schema }) {
48417
48335
  const eventBus = useEventBus();
48418
48336
  const { t } = useTranslate();
48419
- const [log13, setLog] = React86.useState([]);
48420
- const prevStatesRef = React86.useRef(/* @__PURE__ */ new Map());
48421
- React86.useEffect(() => {
48337
+ const [log13, setLog] = React88.useState([]);
48338
+ const prevStatesRef = React88.useRef(/* @__PURE__ */ new Map());
48339
+ React88.useEffect(() => {
48422
48340
  for (const trait of traits2) {
48423
48341
  const prev = prevStatesRef.current.get(trait.id);
48424
48342
  if (prev && prev !== trait.currentState) {
@@ -48587,10 +48505,10 @@ function VerifyModePanel({
48587
48505
  localCount
48588
48506
  }) {
48589
48507
  const { t } = useTranslate();
48590
- const [expanded, setExpanded] = React86.useState(true);
48591
- const scrollRef = React86.useRef(null);
48592
- const prevCountRef = React86.useRef(0);
48593
- React86.useEffect(() => {
48508
+ const [expanded, setExpanded] = React88.useState(true);
48509
+ const scrollRef = React88.useRef(null);
48510
+ const prevCountRef = React88.useRef(0);
48511
+ React88.useEffect(() => {
48594
48512
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
48595
48513
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
48596
48514
  }
@@ -48647,10 +48565,10 @@ function RuntimeDebugger({
48647
48565
  schema
48648
48566
  }) {
48649
48567
  const { t } = useTranslate();
48650
- const [isCollapsed, setIsCollapsed] = React86.useState(mode === "verify" ? true : defaultCollapsed);
48651
- const [isVisible, setIsVisible] = React86.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
48568
+ const [isCollapsed, setIsCollapsed] = React88.useState(mode === "verify" ? true : defaultCollapsed);
48569
+ const [isVisible, setIsVisible] = React88.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
48652
48570
  const debugData = useDebugData();
48653
- React86.useEffect(() => {
48571
+ React88.useEffect(() => {
48654
48572
  if (mode === "inline") return;
48655
48573
  return onDebugToggle((enabled) => {
48656
48574
  setIsVisible(enabled);
@@ -48659,7 +48577,7 @@ function RuntimeDebugger({
48659
48577
  }
48660
48578
  });
48661
48579
  }, [mode]);
48662
- React86.useEffect(() => {
48580
+ React88.useEffect(() => {
48663
48581
  if (mode === "inline") return;
48664
48582
  const handleKeyDown = (e) => {
48665
48583
  if (e.key === "`" && isVisible) {
@@ -49219,7 +49137,7 @@ function SequenceBar({
49219
49137
  onSlotRemove(index);
49220
49138
  }, [onSlotRemove, playing]);
49221
49139
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
49222
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
49140
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React88__default.Fragment, { children: [
49223
49141
  i > 0 && /* @__PURE__ */ jsx(
49224
49142
  Typography,
49225
49143
  {
@@ -49834,6 +49752,29 @@ var init_SimulationCanvas = __esm({
49834
49752
  SimulationCanvas.displayName = "SimulationCanvas";
49835
49753
  }
49836
49754
  });
49755
+ function readSimulatorParameters(v) {
49756
+ if (!Array.isArray(v)) return [];
49757
+ const result = [];
49758
+ for (const item of v) {
49759
+ if (typeof item === "object" && item !== null && !Array.isArray(item) && !(item instanceof Date)) {
49760
+ const param = item;
49761
+ if ("id" in item && "label" in item && "unit" in item && "min" in item && "max" in item && "step" in item) {
49762
+ result.push({
49763
+ id: str(param.id),
49764
+ label: str(param.label),
49765
+ unit: str(param.unit),
49766
+ min: num(param.min),
49767
+ max: num(param.max),
49768
+ step: num(param.step),
49769
+ initial: num(param.initial),
49770
+ correct: num(param.correct),
49771
+ tolerance: num(param.tolerance)
49772
+ });
49773
+ }
49774
+ }
49775
+ }
49776
+ return result;
49777
+ }
49837
49778
  function SimulatorBoard({
49838
49779
  entity,
49839
49780
  completeEvent = "PUZZLE_COMPLETE",
@@ -49846,7 +49787,7 @@ function SimulatorBoard({
49846
49787
  const { emit } = useEventBus();
49847
49788
  const { t } = useTranslate();
49848
49789
  const resolved = boardEntity(entity);
49849
- const parameters = Array.isArray(resolved?.parameters) ? resolved.parameters : [];
49790
+ const parameters = readSimulatorParameters(resolved?.parameters);
49850
49791
  const [headerError, setHeaderError] = useState(false);
49851
49792
  if (!resolved) return null;
49852
49793
  const paramA = num(resolved.paramA);
@@ -49873,8 +49814,14 @@ function SimulatorBoard({
49873
49814
  const handlePlayAgain = () => {
49874
49815
  if (playAgainEvent) emit(`UI:${playAgainEvent}`, {});
49875
49816
  };
49876
- const theme = resolved.theme ?? void 0;
49877
- const themeBackground = theme?.background;
49817
+ const themeBackground = (() => {
49818
+ const t2 = resolved.theme;
49819
+ if (typeof t2 === "object" && t2 !== null && !Array.isArray(t2) && !(t2 instanceof Date)) {
49820
+ const bg = t2.background;
49821
+ return str(bg);
49822
+ }
49823
+ return "";
49824
+ })();
49878
49825
  const headerImage = str(resolved.headerImage);
49879
49826
  const hint = str(resolved.hint);
49880
49827
  const showHint = isComplete && !isWin && attempts >= 2 && Boolean(hint);
@@ -50279,7 +50226,7 @@ var init_StatCard = __esm({
50279
50226
  const labelToUse = propLabel ?? propTitle;
50280
50227
  const eventBus = useEventBus();
50281
50228
  const { t } = useTranslate();
50282
- const handleActionClick = React86__default.useCallback(() => {
50229
+ const handleActionClick = React88__default.useCallback(() => {
50283
50230
  if (action?.event) {
50284
50231
  eventBus.emit(`UI:${action.event}`, {});
50285
50232
  }
@@ -50290,7 +50237,7 @@ var init_StatCard = __esm({
50290
50237
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
50291
50238
  const isLoading = externalLoading ?? false;
50292
50239
  const error = externalError;
50293
- const computeMetricValue = React86__default.useCallback(
50240
+ const computeMetricValue = React88__default.useCallback(
50294
50241
  (metric, items) => {
50295
50242
  if (metric.value !== void 0) {
50296
50243
  return metric.value;
@@ -50329,7 +50276,7 @@ var init_StatCard = __esm({
50329
50276
  },
50330
50277
  []
50331
50278
  );
50332
- const schemaStats = React86__default.useMemo(() => {
50279
+ const schemaStats = React88__default.useMemo(() => {
50333
50280
  if (!metrics || metrics.length === 0) return null;
50334
50281
  return metrics.map((metric) => ({
50335
50282
  label: metric.label,
@@ -50337,7 +50284,7 @@ var init_StatCard = __esm({
50337
50284
  format: metric.format
50338
50285
  }));
50339
50286
  }, [metrics, data, computeMetricValue]);
50340
- const calculatedTrend = React86__default.useMemo(() => {
50287
+ const calculatedTrend = React88__default.useMemo(() => {
50341
50288
  if (manualTrend !== void 0) return manualTrend;
50342
50289
  if (previousValue === void 0 || currentValue === void 0)
50343
50290
  return void 0;
@@ -50680,8 +50627,25 @@ function StateArchitectBoard({
50680
50627
  const initialState = str(resolved?.initialState);
50681
50628
  const entityName = str(resolved?.entityName);
50682
50629
  const availableEvents = Array.isArray(resolved?.availableEvents) ? resolved.availableEvents : [];
50683
- const testCases = Array.isArray(resolved?.testCases) ? resolved.testCases : [];
50684
- const entityTransitions = Array.isArray(resolved?.transitions) ? resolved.transitions : [];
50630
+ const testCases = (Array.isArray(resolved?.testCases) ? resolved.testCases : []).map((item) => {
50631
+ const o = typeof item === "object" && item !== null && !Array.isArray(item) ? item : {};
50632
+ const eventsField = o["events"];
50633
+ return {
50634
+ events: Array.isArray(eventsField) ? eventsField : [],
50635
+ expectedState: str(o["expectedState"]),
50636
+ label: str(o["label"])
50637
+ };
50638
+ });
50639
+ const entityTransitions = (Array.isArray(resolved?.transitions) ? resolved.transitions : []).map((item) => {
50640
+ const o = typeof item === "object" && item !== null && !Array.isArray(item) ? item : {};
50641
+ return {
50642
+ id: str(o["id"]),
50643
+ from: str(o["from"]),
50644
+ to: str(o["to"]),
50645
+ event: str(o["event"]),
50646
+ ...o["guardHint"] ? { guardHint: str(o["guardHint"]) } : {}
50647
+ };
50648
+ });
50685
50649
  const entityVariables = rows(resolved?.variables);
50686
50650
  const transitions = entityTransitions;
50687
50651
  const attempts = typeof resolved?.attempts === "number" ? resolved.attempts : 0;
@@ -51526,8 +51490,8 @@ var init_SubagentTracePanel = __esm({
51526
51490
  ] });
51527
51491
  };
51528
51492
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
51529
- const endRef = React86__default.useRef(null);
51530
- React86__default.useEffect(() => {
51493
+ const endRef = React88__default.useRef(null);
51494
+ React88__default.useEffect(() => {
51531
51495
  if (!autoScroll) return;
51532
51496
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
51533
51497
  }, [activities.length, autoScroll]);
@@ -51621,7 +51585,7 @@ var init_SubagentTracePanel = __esm({
51621
51585
  };
51622
51586
  SubagentRichCard = ({ subagent }) => {
51623
51587
  const { t } = useTranslate();
51624
- const activities = React86__default.useMemo(
51588
+ const activities = React88__default.useMemo(
51625
51589
  () => subagentMessagesToActivities(subagent.messages),
51626
51590
  [subagent.messages]
51627
51591
  );
@@ -51698,8 +51662,8 @@ var init_SubagentTracePanel = __esm({
51698
51662
  ] });
51699
51663
  };
51700
51664
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
51701
- const endRef = React86__default.useRef(null);
51702
- React86__default.useEffect(() => {
51665
+ const endRef = React88__default.useRef(null);
51666
+ React88__default.useEffect(() => {
51703
51667
  if (!autoScroll) return;
51704
51668
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
51705
51669
  }, [messages.length, autoScroll]);
@@ -52170,17 +52134,12 @@ var init_Timeline = __esm({
52170
52134
  look = "vertical-spacious"
52171
52135
  }) => {
52172
52136
  const { t } = useTranslate();
52173
- const entityData = Array.isArray(entity) ? entity : [];
52174
- const items = React86__default.useMemo(() => {
52137
+ const entityData = entity ?? [];
52138
+ const items = React88__default.useMemo(() => {
52175
52139
  if (propItems) return propItems;
52176
52140
  if (entityData.length === 0) return [];
52177
52141
  return entityData.map((record, idx) => {
52178
- const resolveField = (f3) => {
52179
- if (typeof f3 === "string") return f3;
52180
- if (f3 && typeof f3 === "object" && "name" in f3) return String(f3.name);
52181
- return "";
52182
- };
52183
- const resolvedFields = fields?.map(resolveField) ?? [];
52142
+ const resolvedFields = fields ?? [];
52184
52143
  const titleField = resolvedFields[0] || "title";
52185
52144
  const descField = resolvedFields[1] || "description";
52186
52145
  const dateField = resolvedFields.find(
@@ -52278,7 +52237,7 @@ var init_Timeline = __esm({
52278
52237
  }
52279
52238
  });
52280
52239
  function extractToastProps(children) {
52281
- if (!React86__default.isValidElement(children)) {
52240
+ if (!React88__default.isValidElement(children)) {
52282
52241
  if (typeof children === "string") {
52283
52242
  return { message: children };
52284
52243
  }
@@ -52316,7 +52275,7 @@ var init_ToastSlot = __esm({
52316
52275
  eventBus.emit("UI:CLOSE");
52317
52276
  };
52318
52277
  if (!isVisible) return null;
52319
- const isCustomContent = React86__default.isValidElement(children) && !message;
52278
+ const isCustomContent = React88__default.isValidElement(children) && !message;
52320
52279
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
52321
52280
  Toast,
52322
52281
  {
@@ -53588,7 +53547,7 @@ function WorldMapBoard({
53588
53547
  const resolved = boardEntity(entity);
53589
53548
  const entityUnits = rows(resolved?.units);
53590
53549
  const entityTiles = rows(resolved?.tiles);
53591
- const features = propFeatures ?? (Array.isArray(resolved?.features) ? resolved.features : []);
53550
+ const features = propFeatures ?? rows(resolved?.features);
53592
53551
  const selectedHeroId = resolved?.selectedHeroId ?? null;
53593
53552
  const assetManifest = propAssetManifest ?? resolved?.assetManifest;
53594
53553
  const backgroundImage = resolved?.backgroundImage;
@@ -53721,7 +53680,8 @@ function WorldMapBoard({
53721
53680
  if (heroMoveEvent) {
53722
53681
  eventBus.emit(`UI:${heroMoveEvent}`, { heroId, toX: x, toY: y });
53723
53682
  }
53724
- const feature = tile ? str(tile.feature) : "";
53683
+ const tileWithFeature = tile;
53684
+ const feature = tileWithFeature ? str(tileWithFeature.feature) : "";
53725
53685
  if (feature && feature !== "none") {
53726
53686
  const tileRow = tile;
53727
53687
  onFeatureEnter?.(heroId, tileRow);
@@ -53932,7 +53892,7 @@ var init_WorldMapTemplate = __esm({
53932
53892
  }
53933
53893
  });
53934
53894
  function lazyThree(name, loader) {
53935
- const Lazy = React86__default.lazy(
53895
+ const Lazy = React88__default.lazy(
53936
53896
  () => loader().then((m) => {
53937
53897
  const Resolved = m[name];
53938
53898
  if (!Resolved) {
@@ -53944,13 +53904,13 @@ function lazyThree(name, loader) {
53944
53904
  })
53945
53905
  );
53946
53906
  function ThreeWrapper(props) {
53947
- return React86__default.createElement(
53907
+ return React88__default.createElement(
53948
53908
  ThreeBoundary,
53949
53909
  { name },
53950
- React86__default.createElement(
53951
- React86__default.Suspense,
53910
+ React88__default.createElement(
53911
+ React88__default.Suspense,
53952
53912
  { fallback: null },
53953
- React86__default.createElement(Lazy, props)
53913
+ React88__default.createElement(Lazy, props)
53954
53914
  )
53955
53915
  );
53956
53916
  }
@@ -54273,7 +54233,7 @@ var init_component_registry_generated = __esm({
54273
54233
  init_WorldMapBoard();
54274
54234
  init_WorldMapTemplate();
54275
54235
  init_XPBar();
54276
- ThreeBoundary = class extends React86__default.Component {
54236
+ ThreeBoundary = class extends React88__default.Component {
54277
54237
  constructor() {
54278
54238
  super(...arguments);
54279
54239
  __publicField(this, "state", { failed: false });
@@ -54283,7 +54243,7 @@ var init_component_registry_generated = __esm({
54283
54243
  }
54284
54244
  render() {
54285
54245
  if (this.state.failed) {
54286
- return React86__default.createElement(
54246
+ return React88__default.createElement(
54287
54247
  "div",
54288
54248
  {
54289
54249
  "data-testid": "three-unavailable",
@@ -54649,7 +54609,7 @@ function SuspenseConfigProvider({
54649
54609
  config,
54650
54610
  children
54651
54611
  }) {
54652
- return React86__default.createElement(
54612
+ return React88__default.createElement(
54653
54613
  SuspenseConfigContext.Provider,
54654
54614
  { value: config },
54655
54615
  children
@@ -54665,9 +54625,7 @@ function getComponentForPattern3(patternType) {
54665
54625
  if (!mapping) {
54666
54626
  return null;
54667
54627
  }
54668
- const name = typeof mapping === "string" ? mapping : mapping.component;
54669
- if (!name) return null;
54670
- return COMPONENT_REGISTRY[name] ?? null;
54628
+ return COMPONENT_REGISTRY[mapping] ?? null;
54671
54629
  }
54672
54630
  function enrichFormFields(fields, entityDef) {
54673
54631
  const fieldMap = new Map(entityDef.fields.map((f3) => [f3.name, f3]));
@@ -54679,7 +54637,7 @@ function enrichFormFields(fields, entityDef) {
54679
54637
  name: field,
54680
54638
  label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()),
54681
54639
  type: entityField.type,
54682
- required: entityField.required
54640
+ required: entityField.required ?? false
54683
54641
  };
54684
54642
  if (entityField.values && entityField.values.length > 0) {
54685
54643
  enriched.values = entityField.values;
@@ -54687,15 +54645,15 @@ function enrichFormFields(fields, entityDef) {
54687
54645
  enriched.values = entityField.enumValues;
54688
54646
  }
54689
54647
  if (entityField.relation) {
54690
- enriched.relation = entityField.relation;
54648
+ enriched.relation = entityField.relation.entity;
54691
54649
  }
54692
54650
  return enriched;
54693
54651
  }
54694
54652
  return { name: field, label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()) };
54695
54653
  }
54696
- if (field && typeof field === "object" && !Array.isArray(field)) {
54654
+ if (field && typeof field === "object" && !Array.isArray(field) && !React88__default.isValidElement(field) && !(field instanceof Date)) {
54697
54655
  const obj = field;
54698
- const fieldName = obj.name ?? obj.field;
54656
+ const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
54699
54657
  if (!fieldName) return field;
54700
54658
  if (obj.type || obj.inputType) return field;
54701
54659
  const entityField = fieldMap.get(fieldName);
@@ -54712,7 +54670,7 @@ function enrichFormFields(fields, entityDef) {
54712
54670
  }
54713
54671
  }
54714
54672
  if (!obj.relation && entityField.relation) {
54715
- enriched.relation = entityField.relation;
54673
+ enriched.relation = entityField.relation.entity;
54716
54674
  }
54717
54675
  return enriched;
54718
54676
  }
@@ -55139,7 +55097,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
55139
55097
  const key = `${parentId}-${index}-trait:${traitName}`;
55140
55098
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
55141
55099
  }
55142
- return /* @__PURE__ */ jsx(React86__default.Fragment, { children: child }, `${parentId}-${index}`);
55100
+ return /* @__PURE__ */ jsx(React88__default.Fragment, { children: child }, `${parentId}-${index}`);
55143
55101
  }
55144
55102
  if (!child || typeof child !== "object") return null;
55145
55103
  const childId = `${parentId}-${index}`;
@@ -55179,14 +55137,14 @@ function isPatternConfig(value) {
55179
55137
  if (value === null || value === void 0) return false;
55180
55138
  if (typeof value !== "object") return false;
55181
55139
  if (Array.isArray(value)) return false;
55182
- if (React86__default.isValidElement(value)) return false;
55140
+ if (React88__default.isValidElement(value)) return false;
55183
55141
  if (value instanceof Date) return false;
55184
55142
  if (typeof value === "function") return false;
55185
55143
  const record = value;
55186
55144
  return "type" in record && typeof record.type === "string" && getComponentForPattern(record.type) !== null;
55187
55145
  }
55188
55146
  function isPlainConfigObject(value) {
55189
- if (React86__default.isValidElement(value)) return false;
55147
+ if (React88__default.isValidElement(value)) return false;
55190
55148
  if (value instanceof Date) return false;
55191
55149
  const proto = Object.getPrototypeOf(value);
55192
55150
  return proto === Object.prototype || proto === null;
@@ -55312,7 +55270,7 @@ function SlotContentRenderer({
55312
55270
  for (const slotKey of CONTENT_NODE_SLOTS) {
55313
55271
  const slotVal = restProps[slotKey];
55314
55272
  if (slotVal === void 0 || slotVal === null) continue;
55315
- if (React86__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
55273
+ if (React88__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
55316
55274
  if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
55317
55275
  nodeSlotOverrides[slotKey] = renderPatternChildren(
55318
55276
  slotVal,
@@ -55357,19 +55315,18 @@ function SlotContentRenderer({
55357
55315
  for (const [k, v] of Object.entries(nodeSlotOverrides)) {
55358
55316
  finalProps[k] = v;
55359
55317
  }
55360
- const resolvedItems = Array.isArray(
55361
- finalProps.entity
55362
- ) ? finalProps.entity : null;
55318
+ const entityVal = finalProps.entity;
55319
+ const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
55363
55320
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
55364
55321
  const sample = resolvedItems[0];
55365
- if (sample && typeof sample === "object") {
55322
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React88__default.isValidElement(sample) && !(sample instanceof Date)) {
55366
55323
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
55367
55324
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
55368
55325
  }
55369
55326
  }
55370
55327
  const isFormPattern = FORM_PATTERNS.has(content.pattern) || content.pattern.includes("form");
55371
- if (isFormPattern && entityDef && Array.isArray(finalProps.fields)) {
55372
- finalProps.fields = enrichFormFields(finalProps.fields, entityDef);
55328
+ if (isFormPattern && entityDef && Array.isArray(finalProps.fields) && finalProps.fields[0] !== "fn") {
55329
+ finalProps.fields = enrichFormFields([...finalProps.fields], entityDef);
55373
55330
  }
55374
55331
  const acceptsChildren = PATTERNS_WITH_CHILDREN.has(content.pattern);
55375
55332
  return /* @__PURE__ */ jsx(