@almadar/ui 5.25.0 → 5.26.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 (53) hide show
  1. package/dist/avl/index.cjs +2071 -2859
  2. package/dist/avl/index.js +1020 -1808
  3. package/dist/components/core/atoms/FlipContainer.d.ts +4 -4
  4. package/dist/components/core/atoms/Icon.d.ts +4 -2
  5. package/dist/components/core/atoms/ProgressBar.d.ts +1 -1
  6. package/dist/components/core/atoms/Typography.d.ts +0 -18
  7. package/dist/components/core/atoms/index.d.ts +1 -1
  8. package/dist/components/core/atoms/types.d.ts +6 -0
  9. package/dist/components/core/molecules/ArrayEditor.d.ts +15 -0
  10. package/dist/components/core/molecules/Carousel.d.ts +8 -2
  11. package/dist/components/core/molecules/Container.d.ts +4 -4
  12. package/dist/components/core/molecules/DateRangeSelector.d.ts +3 -4
  13. package/dist/components/core/molecules/DocSidebar.d.ts +4 -4
  14. package/dist/components/core/molecules/EdgeDecoration.d.ts +3 -2
  15. package/dist/components/core/molecules/Flex.d.ts +4 -4
  16. package/dist/components/core/molecules/FlipCard.d.ts +3 -4
  17. package/dist/components/core/molecules/GradientDivider.d.ts +3 -2
  18. package/dist/components/core/molecules/MapEditor.d.ts +16 -0
  19. package/dist/components/core/molecules/ObjectEditor.d.ts +15 -0
  20. package/dist/components/core/molecules/SidePanel.d.ts +4 -4
  21. package/dist/components/core/molecules/SortableList.d.ts +4 -5
  22. package/dist/components/core/molecules/ViolationAlert.d.ts +4 -9
  23. package/dist/components/core/molecules/index.d.ts +4 -3
  24. package/dist/components/core/molecules/markdown/CodeBlock.d.ts +44 -2
  25. package/dist/components/core/organisms/ComponentPatterns.d.ts +0 -3
  26. package/dist/components/game/atoms/DialogueBubble.d.ts +2 -1
  27. package/dist/components/game/atoms/ResourceCounter.d.ts +3 -2
  28. package/dist/components/game/atoms/Sprite.d.ts +2 -2
  29. package/dist/components/game/atoms/StateIndicator.d.ts +4 -5
  30. package/dist/components/game/atoms/StatusEffect.d.ts +2 -3
  31. package/dist/components/game/molecules/ActionButtons.d.ts +6 -0
  32. package/dist/components/game/molecules/GameHud.d.ts +2 -3
  33. package/dist/components/game/molecules/StatBadge.d.ts +6 -0
  34. package/dist/components/game/organisms/puzzles/state-architect/StateJsonView.d.ts +16 -0
  35. package/dist/components/game/organisms/puzzles/state-architect/index.d.ts +2 -2
  36. package/dist/components/index.cjs +2527 -2302
  37. package/dist/components/index.js +1638 -1413
  38. package/dist/docs/index.cjs +6014 -4606
  39. package/dist/docs/index.css +1252 -0
  40. package/dist/docs/index.d.cts +108 -16
  41. package/dist/docs/index.d.ts +2 -2
  42. package/dist/docs/index.js +5970 -4567
  43. package/dist/marketing/index.cjs +36 -13
  44. package/dist/marketing/index.d.cts +30 -20
  45. package/dist/marketing/index.js +36 -13
  46. package/dist/providers/index.cjs +1891 -2679
  47. package/dist/providers/index.js +990 -1778
  48. package/dist/runtime/index.cjs +1931 -2719
  49. package/dist/runtime/index.js +994 -1782
  50. package/package.json +1 -1
  51. package/dist/components/core/molecules/CodeViewer.d.ts +0 -70
  52. package/dist/components/core/molecules/DocCodeBlock.d.ts +0 -14
  53. package/dist/components/game/organisms/puzzles/state-architect/CodeView.d.ts +0 -24
@@ -1,12 +1,12 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import * as React83 from 'react';
3
- import React83__default, { useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, lazy, createContext, useLayoutEffect, useId, useSyncExternalStore } from 'react';
2
+ import * as React79 from 'react';
3
+ import React79__default, { useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, lazy, createContext, useLayoutEffect, useId, useSyncExternalStore } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { EventBusContext, useTraitScope, TraitScopeProvider } from '@almadar/ui/providers';
7
7
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
8
8
  import * as LucideIcons2 from 'lucide-react';
9
- import { Loader2, X, List, Printer, ChevronRight, ChevronLeft, CheckCircle, XCircle, Wrench, RotateCcw, Send, Search, ChevronUp, ChevronDown, MoreHorizontal, Bug, Package, Calendar, Pencil, Eye, Image as Image$1, Upload, ZoomIn, ArrowRight, Pause, Play, SkipForward, TrendingUp, TrendingDown, Minus, AlertCircle, Circle, Clock, CheckCircle2, HelpCircle, Type, Heading1, Heading2, Heading3, ListOrdered, Quote, Code, GitBranch, Plus, Trash, ArrowLeft, Menu as Menu$1, Check, AlertTriangle, Trash2, Eraser, FileText, ZoomOut, Download, WrapText, Copy, Tag, User, DollarSign, Zap, Sword, Move, Heart, Shield } from 'lucide-react';
9
+ import { Loader2, X, List, Printer, ChevronRight, ChevronLeft, CheckCircle, XCircle, Wrench, RotateCcw, Send, Search, ChevronUp, ChevronDown, MoreHorizontal, Bug, Package, Calendar, Pencil, Eye, Image as Image$1, Upload, ZoomIn, ArrowRight, Pause, Play, SkipForward, TrendingUp, TrendingDown, Minus, AlertCircle, Circle, Clock, CheckCircle2, Code, FileText, WrapText, Check, Copy, HelpCircle, Type, Heading1, Heading2, Heading3, ListOrdered, Quote, GitBranch, Plus, Trash, ArrowLeft, Menu as Menu$1, AlertTriangle, Trash2, Eraser, ZoomOut, Download, Tag, User, DollarSign, Zap, Sword, Move, Heart, Shield } from 'lucide-react';
10
10
  import * as PhosphorIcons from '@phosphor-icons/react';
11
11
  import * as TablerIcons from '@tabler/icons-react';
12
12
  import * as FaIcons from 'react-icons/fa';
@@ -211,7 +211,7 @@ var init_SvgFlow = __esm({
211
211
  opacity = 1,
212
212
  className
213
213
  }) => {
214
- const markerId = React83__default.useMemo(() => {
214
+ const markerId = React79__default.useMemo(() => {
215
215
  flowIdCounter += 1;
216
216
  return `almadar-flow-arrow-${flowIdCounter}`;
217
217
  }, []);
@@ -754,7 +754,7 @@ var init_SvgRing = __esm({
754
754
  className,
755
755
  label
756
756
  }) => {
757
- const gradientId = React83__default.useMemo(() => {
757
+ const gradientId = React79__default.useMemo(() => {
758
758
  ringIdCounter += 1;
759
759
  return `almadar-ring-glow-${ringIdCounter}`;
760
760
  }, []);
@@ -1792,12 +1792,20 @@ function doResolve(name) {
1792
1792
  if (asIs && typeof asIs === "object") return asIs;
1793
1793
  return LucideIcons2.HelpCircle;
1794
1794
  }
1795
- var iconAliases, resolvedCache, sizeClasses, animationClasses, Icon;
1795
+ var colorTokenClasses, iconAliases, resolvedCache, sizeClasses, animationClasses, Icon;
1796
1796
  var init_Icon = __esm({
1797
1797
  "components/core/atoms/Icon.tsx"() {
1798
1798
  "use client";
1799
1799
  init_cn();
1800
1800
  init_iconFamily();
1801
+ colorTokenClasses = {
1802
+ primary: "text-primary",
1803
+ secondary: "text-secondary",
1804
+ success: "text-success",
1805
+ warning: "text-warning",
1806
+ error: "text-error",
1807
+ muted: "text-muted-foreground"
1808
+ };
1801
1809
  iconAliases = {
1802
1810
  "close": LucideIcons2.X,
1803
1811
  "trash": LucideIcons2.Trash2,
@@ -1836,7 +1844,7 @@ var init_Icon = __esm({
1836
1844
  const directIcon = typeof icon === "string" ? void 0 : icon;
1837
1845
  const effectiveName = typeof icon === "string" ? icon : name;
1838
1846
  const family = useIconFamily();
1839
- const RenderedComponent = React83__default.useMemo(() => {
1847
+ const RenderedComponent = React79__default.useMemo(() => {
1840
1848
  if (directIcon) return null;
1841
1849
  return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
1842
1850
  }, [directIcon, effectiveName, family]);
@@ -1845,10 +1853,11 @@ var init_Icon = __esm({
1845
1853
  ...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
1846
1854
  ...style
1847
1855
  };
1856
+ const resolvedColor = color ? color in colorTokenClasses ? colorTokenClasses[color] : color : "text-current";
1848
1857
  const composedClassName = cn(
1849
1858
  sizeClasses[size],
1850
1859
  animationClasses[animation],
1851
- color ? color : "text-current",
1860
+ resolvedColor,
1852
1861
  className
1853
1862
  );
1854
1863
  if (directIcon) {
@@ -1894,7 +1903,7 @@ function resolveIconProp(value, sizeClass) {
1894
1903
  const IconComp = value;
1895
1904
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1896
1905
  }
1897
- if (React83__default.isValidElement(value)) {
1906
+ if (React79__default.isValidElement(value)) {
1898
1907
  return value;
1899
1908
  }
1900
1909
  if (typeof value === "object" && value !== null && "render" in value) {
@@ -1970,7 +1979,7 @@ var init_Button = __esm({
1970
1979
  md: "h-icon-default w-icon-default",
1971
1980
  lg: "h-icon-default w-icon-default"
1972
1981
  };
1973
- Button = React83__default.forwardRef(
1982
+ Button = React79__default.forwardRef(
1974
1983
  ({
1975
1984
  className,
1976
1985
  variant = "primary",
@@ -2036,7 +2045,7 @@ var init_Input = __esm({
2036
2045
  "components/core/atoms/Input.tsx"() {
2037
2046
  init_cn();
2038
2047
  init_Icon();
2039
- Input = React83__default.forwardRef(
2048
+ Input = React79__default.forwardRef(
2040
2049
  ({
2041
2050
  className,
2042
2051
  inputType,
@@ -2157,7 +2166,7 @@ var Label;
2157
2166
  var init_Label = __esm({
2158
2167
  "components/core/atoms/Label.tsx"() {
2159
2168
  init_cn();
2160
- Label = React83__default.forwardRef(
2169
+ Label = React79__default.forwardRef(
2161
2170
  ({ className, required, children, ...props }, ref) => {
2162
2171
  return /* @__PURE__ */ jsxs(
2163
2172
  "label",
@@ -2183,7 +2192,7 @@ var Textarea;
2183
2192
  var init_Textarea = __esm({
2184
2193
  "components/core/atoms/Textarea.tsx"() {
2185
2194
  init_cn();
2186
- Textarea = React83__default.forwardRef(
2195
+ Textarea = React79__default.forwardRef(
2187
2196
  ({ className, error, ...props }, ref) => {
2188
2197
  return /* @__PURE__ */ jsx(
2189
2198
  "textarea",
@@ -2213,7 +2222,7 @@ var init_Select = __esm({
2213
2222
  "components/core/atoms/Select.tsx"() {
2214
2223
  init_cn();
2215
2224
  init_Icon();
2216
- Select = React83__default.forwardRef(
2225
+ Select = React79__default.forwardRef(
2217
2226
  ({ className, options, placeholder, error, ...props }, ref) => {
2218
2227
  return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
2219
2228
  /* @__PURE__ */ jsxs(
@@ -2255,7 +2264,7 @@ var Checkbox;
2255
2264
  var init_Checkbox = __esm({
2256
2265
  "components/core/atoms/Checkbox.tsx"() {
2257
2266
  init_cn();
2258
- Checkbox = React83__default.forwardRef(
2267
+ Checkbox = React79__default.forwardRef(
2259
2268
  ({ className, label, id, ...props }, ref) => {
2260
2269
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
2261
2270
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
@@ -2346,7 +2355,7 @@ var init_Card = __esm({
2346
2355
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
2347
2356
  "tile-image-first": "p-0 overflow-hidden"
2348
2357
  };
2349
- Card = React83__default.forwardRef(
2358
+ Card = React79__default.forwardRef(
2350
2359
  ({
2351
2360
  className,
2352
2361
  variant = "bordered",
@@ -2384,9 +2393,9 @@ var init_Card = __esm({
2384
2393
  }
2385
2394
  );
2386
2395
  Card.displayName = "Card";
2387
- CardHeader = React83__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
2396
+ CardHeader = React79__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
2388
2397
  CardHeader.displayName = "CardHeader";
2389
- CardTitle = React83__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2398
+ CardTitle = React79__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2390
2399
  "h3",
2391
2400
  {
2392
2401
  ref,
@@ -2399,11 +2408,11 @@ var init_Card = __esm({
2399
2408
  }
2400
2409
  ));
2401
2410
  CardTitle.displayName = "CardTitle";
2402
- CardContent = React83__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
2411
+ CardContent = React79__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
2403
2412
  CardContent.displayName = "CardContent";
2404
2413
  CardBody = CardContent;
2405
2414
  CardBody.displayName = "CardBody";
2406
- CardFooter = React83__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2415
+ CardFooter = React79__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2407
2416
  "div",
2408
2417
  {
2409
2418
  ref,
@@ -2456,7 +2465,7 @@ var init_Badge = __esm({
2456
2465
  md: "px-2.5 py-1 text-sm",
2457
2466
  lg: "px-3 py-1.5 text-base"
2458
2467
  };
2459
- Badge = React83__default.forwardRef(
2468
+ Badge = React79__default.forwardRef(
2460
2469
  ({ className, variant = "default", size = "sm", amount, label, icon, children, onRemove, removeLabel, ...props }, ref) => {
2461
2470
  const iconSizes3 = {
2462
2471
  sm: "h-icon-default w-icon-default",
@@ -2549,7 +2558,7 @@ var init_FilterPill = __esm({
2549
2558
  md: "w-3.5 h-3.5",
2550
2559
  lg: "w-4 h-4"
2551
2560
  };
2552
- FilterPill = React83__default.forwardRef(
2561
+ FilterPill = React79__default.forwardRef(
2553
2562
  ({
2554
2563
  className,
2555
2564
  variant = "default",
@@ -2626,7 +2635,7 @@ var init_Spinner = __esm({
2626
2635
  md: "h-6 w-6",
2627
2636
  lg: "h-8 w-8"
2628
2637
  };
2629
- Spinner = React83__default.forwardRef(
2638
+ Spinner = React79__default.forwardRef(
2630
2639
  ({ className, size = "md", ...props }, ref) => {
2631
2640
  return /* @__PURE__ */ jsx(
2632
2641
  "div",
@@ -2705,13 +2714,12 @@ var init_Avatar = __esm({
2705
2714
  actionPayload
2706
2715
  }) => {
2707
2716
  const eventBus = useEventBus();
2708
- const [imgFailed, setImgFailed] = React83__default.useState(false);
2709
- React83__default.useEffect(() => {
2717
+ const [imgFailed, setImgFailed] = React79__default.useState(false);
2718
+ React79__default.useEffect(() => {
2710
2719
  setImgFailed(false);
2711
2720
  }, [src]);
2712
2721
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
2713
2722
  const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
2714
- const hasImage = !!src && !imgFailed;
2715
2723
  const hasIcon = !!IconComponent;
2716
2724
  const hasInitials = !!initials && !(hasIcon && !providedInitials);
2717
2725
  const getInitialsBackground = () => "bg-primary text-primary-foreground";
@@ -2737,15 +2745,13 @@ var init_Avatar = __esm({
2737
2745
  onClick: isClickable ? handleClick : void 0,
2738
2746
  role: isClickable ? "button" : void 0,
2739
2747
  tabIndex: isClickable ? 0 : void 0,
2740
- children: hasImage ? /* @__PURE__ */ jsx(
2748
+ children: src && !imgFailed ? /* @__PURE__ */ jsx(
2741
2749
  "img",
2742
2750
  {
2743
2751
  src,
2744
2752
  alt: alt || "Avatar",
2745
2753
  className: "w-full h-full object-cover",
2746
- onError: () => {
2747
- setImgFailed(true);
2748
- }
2754
+ onError: () => setImgFailed(true)
2749
2755
  }
2750
2756
  ) : hasInitials ? /* @__PURE__ */ jsx(
2751
2757
  "div",
@@ -2913,7 +2919,7 @@ var init_Box = __esm({
2913
2919
  fixed: "fixed",
2914
2920
  sticky: "sticky"
2915
2921
  };
2916
- Box = React83__default.forwardRef(
2922
+ Box = React79__default.forwardRef(
2917
2923
  ({
2918
2924
  padding,
2919
2925
  paddingX,
@@ -2963,7 +2969,7 @@ var init_Box = __esm({
2963
2969
  onMouseLeave?.(e);
2964
2970
  }, [hoverEvent, eventBus, onMouseLeave]);
2965
2971
  const isClickable = action || onClick;
2966
- return React83__default.createElement(
2972
+ return React79__default.createElement(
2967
2973
  Component,
2968
2974
  {
2969
2975
  ref,
@@ -3120,6 +3126,7 @@ var init_ProgressBar = __esm({
3120
3126
  primary: "bg-primary",
3121
3127
  success: "bg-success",
3122
3128
  warning: "bg-warning",
3129
+ error: "bg-error",
3123
3130
  danger: "bg-error"
3124
3131
  };
3125
3132
  circularSizeClasses = {
@@ -3285,7 +3292,7 @@ var init_Radio = __esm({
3285
3292
  md: "w-2.5 h-2.5",
3286
3293
  lg: "w-3 h-3"
3287
3294
  };
3288
- Radio = React83__default.forwardRef(
3295
+ Radio = React79__default.forwardRef(
3289
3296
  ({
3290
3297
  label,
3291
3298
  helperText,
@@ -3302,12 +3309,12 @@ var init_Radio = __esm({
3302
3309
  onChange,
3303
3310
  ...props
3304
3311
  }, ref) => {
3305
- const reactId = React83__default.useId();
3312
+ const reactId = React79__default.useId();
3306
3313
  const baseId = id || `radio-${reactId}`;
3307
3314
  const hasError = !!error;
3308
3315
  const eventBus = useEventBus();
3309
- const [selected, setSelected] = React83__default.useState(value);
3310
- React83__default.useEffect(() => {
3316
+ const [selected, setSelected] = React79__default.useState(value);
3317
+ React79__default.useEffect(() => {
3311
3318
  if (value !== void 0) setSelected(value);
3312
3319
  }, [value]);
3313
3320
  const pick = (next, e) => {
@@ -3489,7 +3496,7 @@ var init_Switch = __esm({
3489
3496
  "components/core/atoms/Switch.tsx"() {
3490
3497
  "use client";
3491
3498
  init_cn();
3492
- Switch = React83.forwardRef(
3499
+ Switch = React79.forwardRef(
3493
3500
  ({
3494
3501
  checked,
3495
3502
  defaultChecked = false,
@@ -3500,10 +3507,10 @@ var init_Switch = __esm({
3500
3507
  name,
3501
3508
  className
3502
3509
  }, ref) => {
3503
- const [isChecked, setIsChecked] = React83.useState(
3510
+ const [isChecked, setIsChecked] = React79.useState(
3504
3511
  checked !== void 0 ? checked : defaultChecked
3505
3512
  );
3506
- React83.useEffect(() => {
3513
+ React79.useEffect(() => {
3507
3514
  if (checked !== void 0) {
3508
3515
  setIsChecked(checked);
3509
3516
  }
@@ -3762,11 +3769,9 @@ var init_TextHighlight = __esm({
3762
3769
  // components/core/atoms/Typography.tsx
3763
3770
  var Typography_exports = {};
3764
3771
  __export(Typography_exports, {
3765
- Heading: () => Heading,
3766
- Text: () => Text,
3767
3772
  Typography: () => Typography
3768
3773
  });
3769
- var variantStyles6, colorStyles, weightStyles, defaultElements, typographySizeStyles, overflowStyles2, Typography, sizeStyles5, Heading, Text;
3774
+ var variantStyles6, colorStyles, weightStyles, defaultElements, typographySizeStyles, overflowStyles2, Typography;
3770
3775
  var init_Typography = __esm({
3771
3776
  "components/core/atoms/Typography.tsx"() {
3772
3777
  init_cn();
@@ -3877,46 +3882,6 @@ var init_Typography = __esm({
3877
3882
  );
3878
3883
  };
3879
3884
  Typography.displayName = "Typography";
3880
- sizeStyles5 = {
3881
- xs: "text-xs",
3882
- sm: "text-sm",
3883
- md: "text-base",
3884
- lg: "text-lg",
3885
- xl: "text-xl",
3886
- "2xl": "text-2xl",
3887
- "3xl": "text-3xl"
3888
- };
3889
- Heading = ({
3890
- level = 2,
3891
- size,
3892
- className,
3893
- ...props
3894
- }) => {
3895
- const variant = `h${level}`;
3896
- const sizeClass = size ? sizeStyles5[size] : void 0;
3897
- return /* @__PURE__ */ jsx(
3898
- Typography,
3899
- {
3900
- variant,
3901
- className: cn(sizeClass, className),
3902
- ...props
3903
- }
3904
- );
3905
- };
3906
- Heading.displayName = "Heading";
3907
- Text = ({
3908
- variant = "body",
3909
- ...props
3910
- }) => {
3911
- return /* @__PURE__ */ jsx(
3912
- Typography,
3913
- {
3914
- variant,
3915
- ...props
3916
- }
3917
- );
3918
- };
3919
- Text.displayName = "Text";
3920
3885
  }
3921
3886
  });
3922
3887
  function useTheme() {
@@ -4374,7 +4339,7 @@ var Dialog;
4374
4339
  var init_Dialog = __esm({
4375
4340
  "components/core/atoms/Dialog.tsx"() {
4376
4341
  init_cn();
4377
- Dialog = React83__default.forwardRef(
4342
+ Dialog = React79__default.forwardRef(
4378
4343
  ({
4379
4344
  role = "dialog",
4380
4345
  "aria-modal": ariaModal = true,
@@ -4400,7 +4365,7 @@ var Aside;
4400
4365
  var init_Aside = __esm({
4401
4366
  "components/core/atoms/Aside.tsx"() {
4402
4367
  init_cn();
4403
- Aside = React83__default.forwardRef(
4368
+ Aside = React79__default.forwardRef(
4404
4369
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
4405
4370
  );
4406
4371
  Aside.displayName = "Aside";
@@ -4478,8 +4443,8 @@ var init_LawReferenceTooltip = __esm({
4478
4443
  className
4479
4444
  }) => {
4480
4445
  const { t } = useTranslate();
4481
- const [isVisible, setIsVisible] = React83__default.useState(false);
4482
- const timeoutRef = React83__default.useRef(null);
4446
+ const [isVisible, setIsVisible] = React79__default.useState(false);
4447
+ const timeoutRef = React79__default.useRef(null);
4483
4448
  const handleMouseEnter = () => {
4484
4449
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4485
4450
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -4488,7 +4453,7 @@ var init_LawReferenceTooltip = __esm({
4488
4453
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4489
4454
  setIsVisible(false);
4490
4455
  };
4491
- React83__default.useEffect(() => {
4456
+ React79__default.useEffect(() => {
4492
4457
  return () => {
4493
4458
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4494
4459
  };
@@ -4673,7 +4638,7 @@ var init_TimeSlotCell = __esm({
4673
4638
  TimeSlotCell.displayName = "TimeSlotCell";
4674
4639
  }
4675
4640
  });
4676
- var statusColors, pulseRingColors, sizeStyles6, StatusDot;
4641
+ var statusColors, pulseRingColors, sizeStyles5, StatusDot;
4677
4642
  var init_StatusDot = __esm({
4678
4643
  "components/core/atoms/StatusDot.tsx"() {
4679
4644
  init_cn();
@@ -4693,12 +4658,12 @@ var init_StatusDot = __esm({
4693
4658
  warning: "ring-warning",
4694
4659
  critical: "ring-error"
4695
4660
  };
4696
- sizeStyles6 = {
4661
+ sizeStyles5 = {
4697
4662
  sm: "w-2 h-2",
4698
4663
  md: "w-2.5 h-2.5",
4699
4664
  lg: "w-3 h-3"
4700
4665
  };
4701
- StatusDot = React83__default.forwardRef(
4666
+ StatusDot = React79__default.forwardRef(
4702
4667
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
4703
4668
  return /* @__PURE__ */ jsx(
4704
4669
  "span",
@@ -4707,7 +4672,7 @@ var init_StatusDot = __esm({
4707
4672
  className: cn(
4708
4673
  "inline-block rounded-full flex-shrink-0",
4709
4674
  statusColors[status],
4710
- sizeStyles6[size],
4675
+ sizeStyles5[size],
4711
4676
  pulse && [
4712
4677
  "animate-pulse",
4713
4678
  "ring-2 ring-offset-1",
@@ -4737,12 +4702,12 @@ function resolveColor(dir, invert) {
4737
4702
  const isGood = invert ? !isPositive : isPositive;
4738
4703
  return isGood ? "text-success" : "text-error";
4739
4704
  }
4740
- var sizeStyles7, iconNameMap, TrendIndicator;
4705
+ var sizeStyles6, iconNameMap, TrendIndicator;
4741
4706
  var init_TrendIndicator = __esm({
4742
4707
  "components/core/atoms/TrendIndicator.tsx"() {
4743
4708
  init_Icon();
4744
4709
  init_cn();
4745
- sizeStyles7 = {
4710
+ sizeStyles6 = {
4746
4711
  sm: { icon: "w-3 h-3", text: "text-xs" },
4747
4712
  md: { icon: "w-4 h-4", text: "text-sm" },
4748
4713
  lg: { icon: "w-5 h-5", text: "text-base" }
@@ -4752,7 +4717,7 @@ var init_TrendIndicator = __esm({
4752
4717
  down: "trending-down",
4753
4718
  flat: "arrow-right"
4754
4719
  };
4755
- TrendIndicator = React83__default.forwardRef(
4720
+ TrendIndicator = React79__default.forwardRef(
4756
4721
  ({
4757
4722
  className,
4758
4723
  value,
@@ -4766,7 +4731,7 @@ var init_TrendIndicator = __esm({
4766
4731
  const dir = resolveDirection(value, direction);
4767
4732
  const colorClass = resolveColor(dir, invert);
4768
4733
  const iconName = iconNameMap[dir];
4769
- const styles = sizeStyles7[size];
4734
+ const styles = sizeStyles6[size];
4770
4735
  const formattedValue = value !== void 0 ? `${value > 0 ? "+" : ""}${value}%` : void 0;
4771
4736
  const ariaLabel = label ?? (formattedValue ? `${dir} ${formattedValue}` : dir);
4772
4737
  return /* @__PURE__ */ jsxs(
@@ -4819,7 +4784,7 @@ var init_RangeSlider = __esm({
4819
4784
  md: "w-4 h-4",
4820
4785
  lg: "w-5 h-5"
4821
4786
  };
4822
- RangeSlider = React83__default.forwardRef(
4787
+ RangeSlider = React79__default.forwardRef(
4823
4788
  ({
4824
4789
  className,
4825
4790
  min = 0,
@@ -5415,7 +5380,7 @@ var init_ContentSection = __esm({
5415
5380
  md: "py-16",
5416
5381
  lg: "py-24"
5417
5382
  };
5418
- ContentSection = React83__default.forwardRef(
5383
+ ContentSection = React79__default.forwardRef(
5419
5384
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
5420
5385
  return /* @__PURE__ */ jsx(
5421
5386
  Box,
@@ -5949,7 +5914,7 @@ var init_AnimatedReveal = __esm({
5949
5914
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
5950
5915
  "none": {}
5951
5916
  };
5952
- AnimatedReveal = React83__default.forwardRef(
5917
+ AnimatedReveal = React79__default.forwardRef(
5953
5918
  ({
5954
5919
  trigger = "scroll",
5955
5920
  animation = "fade-up",
@@ -6109,7 +6074,7 @@ var init_AnimatedGraphic = __esm({
6109
6074
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
6110
6075
  "use client";
6111
6076
  init_cn();
6112
- AnimatedGraphic = React83__default.forwardRef(
6077
+ AnimatedGraphic = React79__default.forwardRef(
6113
6078
  ({
6114
6079
  src,
6115
6080
  svgContent,
@@ -6132,7 +6097,7 @@ var init_AnimatedGraphic = __esm({
6132
6097
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
6133
6098
  const resolvedSvg = svgContent ?? fetchedSvg;
6134
6099
  const prevAnimateRef = useRef(animate);
6135
- const setRef = React83__default.useCallback(
6100
+ const setRef = React79__default.useCallback(
6136
6101
  (node) => {
6137
6102
  containerRef.current = node;
6138
6103
  if (typeof ref === "function") ref(node);
@@ -6238,7 +6203,6 @@ var init_Modal = __esm({
6238
6203
  init_Button();
6239
6204
  init_Dialog();
6240
6205
  init_Typography();
6241
- init_Overlay();
6242
6206
  init_cn();
6243
6207
  init_useEventBus();
6244
6208
  sizeClasses6 = {
@@ -6328,124 +6292,117 @@ var init_Modal = __esm({
6328
6292
  }
6329
6293
  };
6330
6294
  return createPortal(
6331
- /* @__PURE__ */ jsxs(Fragment, { children: [
6332
- /* @__PURE__ */ jsx(
6333
- Overlay,
6334
- {
6335
- isVisible: isOpen,
6336
- onClick: handleOverlayClick,
6337
- className: "z-[1000]"
6338
- }
6339
- ),
6340
- /* @__PURE__ */ jsx(
6341
- Box,
6342
- {
6343
- className: cn(
6344
- "fixed inset-0 z-[1001] pointer-events-none",
6345
- "flex items-start justify-center px-4 pb-4 pt-[10vh]",
6346
- "max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
6347
- ),
6348
- children: /* @__PURE__ */ jsxs(
6349
- Dialog,
6350
- {
6351
- ref: modalRef,
6352
- open: true,
6353
- className: cn(
6354
- // Reset browser-default dialog chrome — we own styling. `static`
6355
- // overrides the user-agent `position: absolute` so the parent
6356
- // flex container's `justify-center` actually centers the dialog
6357
- // (without this, the dialog drops out of flex flow and `m-0`
6358
- // kills the user-agent's `margin: auto` centering, pinning the
6359
- // dialog to top-left).
6360
- "static m-0 p-0 border-0 bg-transparent",
6361
- // Pre-existing dialog frame
6362
- "pointer-events-auto w-full flex flex-col bg-surface border shadow-elevation-dialog rounded-container",
6363
- // Desktop sizing + viewport-aware floor.
6364
- sizeClasses6[size],
6365
- minWidthClasses[size],
6366
- "max-h-[80vh]",
6367
- // Mobile: take the entire screen. Override desktop max-w cap,
6368
- // full height, no rounded corners, no min-width.
6369
- "max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
6370
- lookStyles2[look],
6371
- className
6295
+ /* @__PURE__ */ jsx(
6296
+ "div",
6297
+ {
6298
+ className: cn(
6299
+ "fixed inset-0 z-[1000]",
6300
+ "flex items-start justify-center px-4 pb-4 pt-[10vh]",
6301
+ "max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
6302
+ ),
6303
+ style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
6304
+ onClick: handleOverlayClick,
6305
+ "aria-hidden": "true",
6306
+ children: /* @__PURE__ */ jsxs(
6307
+ Dialog,
6308
+ {
6309
+ ref: modalRef,
6310
+ open: true,
6311
+ className: cn(
6312
+ // Reset browser-default dialog chrome — we own styling. `static`
6313
+ // overrides the user-agent `position: absolute` so the parent
6314
+ // flex container's `justify-center` actually centers the dialog
6315
+ // (without this, the dialog drops out of flex flow and `m-0`
6316
+ // kills the user-agent's `margin: auto` centering, pinning the
6317
+ // dialog to top-left).
6318
+ "static m-0 p-0 border-0 bg-transparent",
6319
+ // Pre-existing dialog frame
6320
+ "pointer-events-auto w-full flex flex-col bg-surface border shadow-elevation-dialog rounded-container",
6321
+ // Desktop sizing + viewport-aware floor.
6322
+ sizeClasses6[size],
6323
+ minWidthClasses[size],
6324
+ "max-h-[80vh]",
6325
+ // Mobile: take the entire screen. Override desktop max-w cap,
6326
+ // full height, no rounded corners, no min-width.
6327
+ "max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
6328
+ lookStyles2[look],
6329
+ className
6330
+ ),
6331
+ style: dragY > 0 ? {
6332
+ transform: `translateY(${dragY}px)`,
6333
+ transition: isDragging.current ? "none" : "transform 200ms ease-out"
6334
+ } : void 0,
6335
+ ...title && { "aria-labelledby": "modal-title" },
6336
+ children: [
6337
+ /* @__PURE__ */ jsx(
6338
+ Box,
6339
+ {
6340
+ className: "hidden max-sm:flex justify-center py-2 cursor-grab active:cursor-grabbing touch-none",
6341
+ onPointerDown: (e) => {
6342
+ if (!swipeDownToClose) return;
6343
+ dragStartY.current = e.clientY;
6344
+ isDragging.current = true;
6345
+ e.target.setPointerCapture(e.pointerId);
6346
+ },
6347
+ onPointerMove: (e) => {
6348
+ if (!isDragging.current) return;
6349
+ const dy = Math.max(0, e.clientY - dragStartY.current);
6350
+ setDragY(dy);
6351
+ },
6352
+ onPointerUp: () => {
6353
+ if (!isDragging.current) return;
6354
+ isDragging.current = false;
6355
+ if (dragY > 100) {
6356
+ handleClose();
6357
+ }
6358
+ setDragY(0);
6359
+ },
6360
+ onPointerCancel: () => {
6361
+ isDragging.current = false;
6362
+ setDragY(0);
6363
+ },
6364
+ children: /* @__PURE__ */ jsx(Box, { className: "w-10 h-1 rounded-full bg-border" })
6365
+ }
6372
6366
  ),
6373
- style: dragY > 0 ? {
6374
- transform: `translateY(${dragY}px)`,
6375
- transition: isDragging.current ? "none" : "transform 200ms ease-out"
6376
- } : void 0,
6377
- ...title && { "aria-labelledby": "modal-title" },
6378
- children: [
6379
- /* @__PURE__ */ jsx(
6380
- Box,
6381
- {
6382
- className: "hidden max-sm:flex justify-center py-2 cursor-grab active:cursor-grabbing touch-none",
6383
- onPointerDown: (e) => {
6384
- if (!swipeDownToClose) return;
6385
- dragStartY.current = e.clientY;
6386
- isDragging.current = true;
6387
- e.target.setPointerCapture(e.pointerId);
6388
- },
6389
- onPointerMove: (e) => {
6390
- if (!isDragging.current) return;
6391
- const dy = Math.max(0, e.clientY - dragStartY.current);
6392
- setDragY(dy);
6393
- },
6394
- onPointerUp: () => {
6395
- if (!isDragging.current) return;
6396
- isDragging.current = false;
6397
- if (dragY > 100) {
6398
- handleClose();
6367
+ (title || showCloseButton) && /* @__PURE__ */ jsxs(
6368
+ Box,
6369
+ {
6370
+ className: cn(
6371
+ "px-6 py-4 flex items-center justify-between",
6372
+ "border-b-[length:var(--border-width)] border-border"
6373
+ ),
6374
+ children: [
6375
+ title && /* @__PURE__ */ jsx(Typography, { variant: "h4", as: "h2", id: "modal-title", children: title }),
6376
+ showCloseButton && /* @__PURE__ */ jsx(
6377
+ Button,
6378
+ {
6379
+ variant: "ghost",
6380
+ size: "sm",
6381
+ icon: "x",
6382
+ onClick: handleClose,
6383
+ "data-event": "CLOSE",
6384
+ "aria-label": t("aria.closeModal")
6399
6385
  }
6400
- setDragY(0);
6401
- },
6402
- onPointerCancel: () => {
6403
- isDragging.current = false;
6404
- setDragY(0);
6405
- },
6406
- children: /* @__PURE__ */ jsx(Box, { className: "w-10 h-1 rounded-full bg-border" })
6407
- }
6408
- ),
6409
- (title || showCloseButton) && /* @__PURE__ */ jsxs(
6410
- Box,
6411
- {
6412
- className: cn(
6413
- "px-6 py-4 flex items-center justify-between",
6414
- "border-b-[length:var(--border-width)] border-border"
6415
- ),
6416
- children: [
6417
- title && /* @__PURE__ */ jsx(Typography, { variant: "h4", as: "h2", id: "modal-title", children: title }),
6418
- showCloseButton && /* @__PURE__ */ jsx(
6419
- Button,
6420
- {
6421
- variant: "ghost",
6422
- size: "sm",
6423
- icon: "x",
6424
- onClick: handleClose,
6425
- "data-event": "CLOSE",
6426
- "aria-label": t("aria.closeModal")
6427
- }
6428
- )
6429
- ]
6430
- }
6431
- ),
6432
- /* @__PURE__ */ jsx(Box, { className: "flex-1 overflow-y-auto p-6", children }),
6433
- footer && /* @__PURE__ */ jsx(
6434
- Box,
6435
- {
6436
- className: cn(
6437
- "px-6 py-4 bg-muted",
6438
- "border-t-[length:var(--border-width)] border-border"
6439
- ),
6440
- children: footer
6441
- }
6442
- )
6443
- ]
6444
- }
6445
- )
6446
- }
6447
- )
6448
- ] }),
6386
+ )
6387
+ ]
6388
+ }
6389
+ ),
6390
+ /* @__PURE__ */ jsx(Box, { className: "flex-1 overflow-y-auto p-6", children }),
6391
+ footer && /* @__PURE__ */ jsx(
6392
+ Box,
6393
+ {
6394
+ className: cn(
6395
+ "px-6 py-4 bg-muted",
6396
+ "border-t-[length:var(--border-width)] border-border"
6397
+ ),
6398
+ children: footer
6399
+ }
6400
+ )
6401
+ ]
6402
+ }
6403
+ )
6404
+ }
6405
+ ),
6449
6406
  document.body
6450
6407
  );
6451
6408
  };
@@ -6822,7 +6779,7 @@ var init_ErrorBoundary = __esm({
6822
6779
  }
6823
6780
  );
6824
6781
  };
6825
- ErrorBoundary = class extends React83__default.Component {
6782
+ ErrorBoundary = class extends React79__default.Component {
6826
6783
  constructor(props) {
6827
6784
  super(props);
6828
6785
  __publicField(this, "reset", () => {
@@ -7070,11 +7027,11 @@ var init_wrapCallbackForEvent = __esm({
7070
7027
  "runtime/wrapCallbackForEvent.ts"() {
7071
7028
  }
7072
7029
  });
7073
- var sizeStyles8, paddingStyles3, Container;
7030
+ var sizeStyles7, paddingStyles3, Container;
7074
7031
  var init_Container = __esm({
7075
7032
  "components/core/molecules/Container.tsx"() {
7076
7033
  init_cn();
7077
- sizeStyles8 = {
7034
+ sizeStyles7 = {
7078
7035
  xs: "max-w-xs",
7079
7036
  // 320px
7080
7037
  sm: "max-w-screen-sm",
@@ -7112,7 +7069,7 @@ var init_Container = __esm({
7112
7069
  {
7113
7070
  className: cn(
7114
7071
  "w-full",
7115
- sizeStyles8[resolvedSize],
7072
+ sizeStyles7[resolvedSize],
7116
7073
  paddingStyles3[padding],
7117
7074
  center && "mx-auto",
7118
7075
  className
@@ -7874,7 +7831,7 @@ var init_Tooltip = __esm({
7874
7831
  setIsVisible(false);
7875
7832
  }, hideDelay);
7876
7833
  };
7877
- useEffect(() => {
7834
+ useLayoutEffect(() => {
7878
7835
  if (isVisible) {
7879
7836
  updatePosition();
7880
7837
  }
@@ -7885,8 +7842,8 @@ var init_Tooltip = __esm({
7885
7842
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
7886
7843
  };
7887
7844
  }, []);
7888
- const triggerElement = React83__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
7889
- const trigger = React83__default.cloneElement(triggerElement, {
7845
+ const triggerElement = React79__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
7846
+ const trigger = React79__default.cloneElement(triggerElement, {
7890
7847
  ref: triggerRef,
7891
7848
  onMouseEnter: handleMouseEnter,
7892
7849
  onMouseLeave: handleMouseLeave,
@@ -8033,8 +7990,8 @@ var init_Popover = __esm({
8033
7990
  onMouseEnter: handleOpen,
8034
7991
  onMouseLeave: handleClose
8035
7992
  };
8036
- const childElement = React83__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
8037
- const triggerElement = React83__default.cloneElement(
7993
+ const childElement = React79__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
7994
+ const triggerElement = React79__default.cloneElement(
8038
7995
  childElement,
8039
7996
  {
8040
7997
  ref: triggerRef,
@@ -8050,7 +8007,10 @@ var init_Popover = __esm({
8050
8007
  "bg-card border-2 border-border shadow-elevation-popover",
8051
8008
  className
8052
8009
  ),
8053
- style: computePopoverStyle(position, triggerRect, popoverWidth),
8010
+ style: {
8011
+ ...computePopoverStyle(position, triggerRect, popoverWidth),
8012
+ ...popoverWidth === 0 ? { visibility: "hidden" } : void 0
8013
+ },
8054
8014
  role: "dialog",
8055
8015
  onMouseEnter: trigger === "hover" ? handleOpen : void 0,
8056
8016
  onMouseLeave: trigger === "hover" ? handleClose : void 0,
@@ -8160,8 +8120,8 @@ var init_Menu = __esm({
8160
8120
  };
8161
8121
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
8162
8122
  const subMenuSideClass = direction === "rtl" ? "right-full mr-2" : "left-full ml-2";
8163
- const triggerChild = React83__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
8164
- const triggerElement = React83__default.cloneElement(
8123
+ const triggerChild = React79__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
8124
+ const triggerElement = React79__default.cloneElement(
8165
8125
  triggerChild,
8166
8126
  {
8167
8127
  ref: triggerRef,
@@ -8568,7 +8528,7 @@ var init_MapView = __esm({
8568
8528
  shadowSize: [41, 41]
8569
8529
  });
8570
8530
  L.Marker.prototype.options.icon = defaultIcon;
8571
- const { useEffect: useEffect71, useRef: useRef68, useCallback: useCallback116, useState: useState102 } = React83__default;
8531
+ const { useEffect: useEffect71, useRef: useRef68, useCallback: useCallback114, useState: useState100 } = React79__default;
8572
8532
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
8573
8533
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
8574
8534
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -8613,8 +8573,8 @@ var init_MapView = __esm({
8613
8573
  showAttribution = true
8614
8574
  }) {
8615
8575
  const eventBus = useEventBus2();
8616
- const [clickedPosition, setClickedPosition] = useState102(null);
8617
- const handleMapClick = useCallback116((lat, lng) => {
8576
+ const [clickedPosition, setClickedPosition] = useState100(null);
8577
+ const handleMapClick = useCallback114((lat, lng) => {
8618
8578
  if (showClickedPin) {
8619
8579
  setClickedPosition({ lat, lng });
8620
8580
  }
@@ -8623,7 +8583,7 @@ var init_MapView = __esm({
8623
8583
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
8624
8584
  }
8625
8585
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
8626
- const handleMarkerClick = useCallback116((marker) => {
8586
+ const handleMarkerClick = useCallback114((marker) => {
8627
8587
  onMarkerClick?.(marker);
8628
8588
  if (markerClickEvent) {
8629
8589
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -8632,7 +8592,7 @@ var init_MapView = __esm({
8632
8592
  return /* @__PURE__ */ jsx(
8633
8593
  Box,
8634
8594
  {
8635
- className: cn("relative isolate w-full overflow-hidden rounded-lg", className),
8595
+ className: cn("relative isolate z-0 w-full overflow-hidden rounded-lg", className),
8636
8596
  style: { height },
8637
8597
  "data-testid": "map-view",
8638
8598
  children: /* @__PURE__ */ jsxs(
@@ -8814,7 +8774,7 @@ function InputPattern({
8814
8774
  fieldName
8815
8775
  }) {
8816
8776
  const { emit } = useEventBus();
8817
- const [localValue, setLocalValue] = React83__default.useState(value);
8777
+ const [localValue, setLocalValue] = React79__default.useState(value);
8818
8778
  const handleChange = (e) => {
8819
8779
  setLocalValue(e.target.value);
8820
8780
  if (onChange) {
@@ -8852,7 +8812,7 @@ function TextareaPattern({
8852
8812
  fieldName
8853
8813
  }) {
8854
8814
  const { emit } = useEventBus();
8855
- const [localValue, setLocalValue] = React83__default.useState(value);
8815
+ const [localValue, setLocalValue] = React79__default.useState(value);
8856
8816
  const handleChange = (e) => {
8857
8817
  setLocalValue(e.target.value);
8858
8818
  if (onChange) {
@@ -8884,7 +8844,7 @@ function SelectPattern({
8884
8844
  fieldName
8885
8845
  }) {
8886
8846
  const { emit } = useEventBus();
8887
- const [localValue, setLocalValue] = React83__default.useState(value);
8847
+ const [localValue, setLocalValue] = React79__default.useState(value);
8888
8848
  const handleChange = (e) => {
8889
8849
  setLocalValue(e.target.value);
8890
8850
  if (onChange) {
@@ -8913,7 +8873,7 @@ function CheckboxPattern({
8913
8873
  className
8914
8874
  }) {
8915
8875
  const { emit } = useEventBus();
8916
- const [localChecked, setLocalChecked] = React83__default.useState(checked);
8876
+ const [localChecked, setLocalChecked] = React79__default.useState(checked);
8917
8877
  const handleChange = (e) => {
8918
8878
  setLocalChecked(e.target.checked);
8919
8879
  if (onChange) {
@@ -9101,6 +9061,7 @@ var init_ComponentPatterns = __esm({
9101
9061
  init_ProgressBar();
9102
9062
  init_Card();
9103
9063
  init_Typography();
9064
+ init_cn();
9104
9065
  init_Alert();
9105
9066
  init_Tooltip();
9106
9067
  init_Popover();
@@ -9226,9 +9187,9 @@ function ControlButton({
9226
9187
  className
9227
9188
  }) {
9228
9189
  const eventBus = useEventBus();
9229
- const [isPressed, setIsPressed] = React83.useState(false);
9190
+ const [isPressed, setIsPressed] = React79.useState(false);
9230
9191
  const actualPressed = pressed ?? isPressed;
9231
- const handlePointerDown = React83.useCallback(
9192
+ const handlePointerDown = React79.useCallback(
9232
9193
  (e) => {
9233
9194
  e.preventDefault();
9234
9195
  if (disabled) return;
@@ -9238,7 +9199,7 @@ function ControlButton({
9238
9199
  },
9239
9200
  [disabled, pressEvent, eventBus, onPress]
9240
9201
  );
9241
- const handlePointerUp = React83.useCallback(
9202
+ const handlePointerUp = React79.useCallback(
9242
9203
  (e) => {
9243
9204
  e.preventDefault();
9244
9205
  if (disabled) return;
@@ -9248,7 +9209,7 @@ function ControlButton({
9248
9209
  },
9249
9210
  [disabled, releaseEvent, eventBus, onRelease]
9250
9211
  );
9251
- const handlePointerLeave = React83.useCallback(
9212
+ const handlePointerLeave = React79.useCallback(
9252
9213
  (e) => {
9253
9214
  if (isPressed) {
9254
9215
  setIsPressed(false);
@@ -9325,8 +9286,8 @@ function ActionButtons({
9325
9286
  disabled
9326
9287
  }) {
9327
9288
  const eventBus = useEventBus();
9328
- const [activeButtons, setActiveButtons] = React83.useState(/* @__PURE__ */ new Set());
9329
- const handlePress = React83.useCallback(
9289
+ const [activeButtons, setActiveButtons] = React79.useState(/* @__PURE__ */ new Set());
9290
+ const handlePress = React79.useCallback(
9330
9291
  (id) => {
9331
9292
  setActiveButtons((prev) => new Set(prev).add(id));
9332
9293
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -9334,7 +9295,7 @@ function ActionButtons({
9334
9295
  },
9335
9296
  [actionEvent, eventBus, onAction]
9336
9297
  );
9337
- const handleRelease = React83.useCallback(
9298
+ const handleRelease = React79.useCallback(
9338
9299
  (id) => {
9339
9300
  setActiveButtons((prev) => {
9340
9301
  const next = new Set(prev);
@@ -9615,259 +9576,6 @@ var init_AnimatedCounter2 = __esm({
9615
9576
  AnimatedCounter2.displayName = "AnimatedCounter";
9616
9577
  }
9617
9578
  });
9618
- var ALL_CATEGORY, GridPicker;
9619
- var init_GridPicker = __esm({
9620
- "components/core/molecules/GridPicker.tsx"() {
9621
- "use client";
9622
- init_cn();
9623
- init_Input();
9624
- init_Badge();
9625
- init_Stack();
9626
- ALL_CATEGORY = "__all__";
9627
- GridPicker = ({
9628
- items,
9629
- value,
9630
- onChange,
9631
- categories,
9632
- searchPlaceholder,
9633
- renderThumbnail,
9634
- cellSize = 32,
9635
- className
9636
- }) => {
9637
- const [search, setSearch] = useState("");
9638
- const [activeCategory, setActiveCategory] = useState(ALL_CATEGORY);
9639
- const gridRef = useRef(null);
9640
- const categoryChips = useMemo(() => {
9641
- if (categories !== void 0) return categories;
9642
- const seen = [];
9643
- for (const item of items) {
9644
- if (!seen.includes(item.category)) seen.push(item.category);
9645
- }
9646
- return seen;
9647
- }, [categories, items]);
9648
- const filtered = useMemo(() => {
9649
- const needle = search.trim().toLowerCase();
9650
- return items.filter((item) => {
9651
- const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
9652
- const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle);
9653
- return matchesCategory && matchesSearch;
9654
- });
9655
- }, [items, search, activeCategory]);
9656
- const select = useCallback(
9657
- (item) => {
9658
- onChange(item.id);
9659
- },
9660
- [onChange]
9661
- );
9662
- const handleKeyDown = useCallback(
9663
- (e, index) => {
9664
- const cells = gridRef.current?.querySelectorAll(
9665
- "[data-gridpicker-cell]"
9666
- );
9667
- if (cells === void 0 || cells.length === 0) return;
9668
- const columns = (() => {
9669
- const grid = gridRef.current;
9670
- if (grid === null) return 1;
9671
- const style = window.getComputedStyle(grid);
9672
- const cols = style.gridTemplateColumns.split(" ").filter(Boolean).length;
9673
- return cols > 0 ? cols : 1;
9674
- })();
9675
- let next = -1;
9676
- if (e.key === "ArrowRight") next = index + 1;
9677
- else if (e.key === "ArrowLeft") next = index - 1;
9678
- else if (e.key === "ArrowDown") next = index + columns;
9679
- else if (e.key === "ArrowUp") next = index - columns;
9680
- else if (e.key === "Enter" || e.key === " ") {
9681
- e.preventDefault();
9682
- select(filtered[index]);
9683
- return;
9684
- } else {
9685
- return;
9686
- }
9687
- e.preventDefault();
9688
- if (next >= 0 && next < cells.length) {
9689
- cells[next].focus();
9690
- }
9691
- },
9692
- [filtered, select]
9693
- );
9694
- return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn("w-full", className), children: [
9695
- /* @__PURE__ */ jsx(
9696
- Input,
9697
- {
9698
- type: "search",
9699
- icon: "search",
9700
- value: search,
9701
- placeholder: searchPlaceholder,
9702
- clearable: true,
9703
- onClear: () => setSearch(""),
9704
- onChange: (e) => setSearch(e.target.value)
9705
- }
9706
- ),
9707
- categoryChips.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", wrap: true, children: [
9708
- /* @__PURE__ */ jsx(
9709
- Badge,
9710
- {
9711
- variant: activeCategory === ALL_CATEGORY ? "primary" : "neutral",
9712
- size: "sm",
9713
- role: "button",
9714
- tabIndex: 0,
9715
- "aria-pressed": activeCategory === ALL_CATEGORY,
9716
- className: "cursor-pointer",
9717
- onClick: () => setActiveCategory(ALL_CATEGORY),
9718
- onKeyDown: (e) => {
9719
- if (e.key === "Enter" || e.key === " ") {
9720
- e.preventDefault();
9721
- setActiveCategory(ALL_CATEGORY);
9722
- }
9723
- },
9724
- children: "All"
9725
- }
9726
- ),
9727
- categoryChips.map((category) => /* @__PURE__ */ jsx(
9728
- Badge,
9729
- {
9730
- variant: activeCategory === category ? "primary" : "neutral",
9731
- size: "sm",
9732
- role: "button",
9733
- tabIndex: 0,
9734
- "aria-pressed": activeCategory === category,
9735
- className: "cursor-pointer",
9736
- onClick: () => setActiveCategory(category),
9737
- onKeyDown: (e) => {
9738
- if (e.key === "Enter" || e.key === " ") {
9739
- e.preventDefault();
9740
- setActiveCategory(category);
9741
- }
9742
- },
9743
- children: category
9744
- },
9745
- category
9746
- ))
9747
- ] }),
9748
- /* @__PURE__ */ jsx(
9749
- "div",
9750
- {
9751
- ref: gridRef,
9752
- role: "listbox",
9753
- className: "grid gap-1 overflow-y-auto max-h-64 p-1",
9754
- style: {
9755
- gridTemplateColumns: `repeat(auto-fill, minmax(${cellSize}px, 1fr))`
9756
- },
9757
- children: filtered.map((item, index) => {
9758
- const selected = item.id === value;
9759
- return /* @__PURE__ */ jsx(
9760
- "button",
9761
- {
9762
- type: "button",
9763
- role: "option",
9764
- "aria-selected": selected,
9765
- "aria-label": item.label,
9766
- title: item.label,
9767
- "data-gridpicker-cell": true,
9768
- tabIndex: selected || value === void 0 && index === 0 ? 0 : -1,
9769
- onClick: () => select(item),
9770
- onKeyDown: (e) => handleKeyDown(e, index),
9771
- className: cn(
9772
- "flex items-center justify-center rounded-sm",
9773
- "transition-colors hover:bg-muted",
9774
- "focus:outline-none focus:ring-1 focus:ring-ring",
9775
- selected && "bg-primary/10 ring-1 ring-primary"
9776
- ),
9777
- style: { width: cellSize, height: cellSize },
9778
- children: renderThumbnail(item)
9779
- },
9780
- item.id
9781
- );
9782
- })
9783
- }
9784
- )
9785
- ] });
9786
- };
9787
- GridPicker.displayName = "GridPicker";
9788
- }
9789
- });
9790
- function iconForKind(kind) {
9791
- if (kind === "audio") return "music";
9792
- if (kind === "model") return "box";
9793
- return "file";
9794
- }
9795
- var THUMB_PX, IMAGE_KINDS, AssetPicker;
9796
- var init_AssetPicker = __esm({
9797
- "components/core/molecules/AssetPicker.tsx"() {
9798
- "use client";
9799
- init_GridPicker();
9800
- init_Icon();
9801
- THUMB_PX = 32;
9802
- IMAGE_KINDS = /* @__PURE__ */ new Set([
9803
- "image",
9804
- "spritesheet",
9805
- "scene",
9806
- "portrait"
9807
- ]);
9808
- AssetPicker = ({
9809
- assets,
9810
- value,
9811
- onChange,
9812
- className
9813
- }) => {
9814
- const byUrl = useMemo(() => {
9815
- const map = /* @__PURE__ */ new Map();
9816
- for (const entry of assets) map.set(entry.url, entry);
9817
- return map;
9818
- }, [assets]);
9819
- const items = useMemo(
9820
- () => assets.map((entry) => ({
9821
- id: entry.url,
9822
- label: entry.name,
9823
- category: entry.category
9824
- })),
9825
- [assets]
9826
- );
9827
- const categories = useMemo(() => {
9828
- const seen = [];
9829
- for (const entry of assets) {
9830
- if (!seen.includes(entry.category)) seen.push(entry.category);
9831
- }
9832
- return seen;
9833
- }, [assets]);
9834
- const renderThumbnail = useCallback(
9835
- (item) => {
9836
- const entry = byUrl.get(item.id);
9837
- if (entry === void 0) return null;
9838
- if (IMAGE_KINDS.has(entry.kind)) {
9839
- return /* @__PURE__ */ jsx(
9840
- "img",
9841
- {
9842
- src: entry.thumbnailUrl ?? entry.url,
9843
- alt: entry.name,
9844
- loading: "lazy",
9845
- width: THUMB_PX,
9846
- height: THUMB_PX,
9847
- style: { width: THUMB_PX, height: THUMB_PX, objectFit: "cover" }
9848
- }
9849
- );
9850
- }
9851
- return /* @__PURE__ */ jsx(Icon, { name: iconForKind(entry.kind), size: "sm" });
9852
- },
9853
- [byUrl]
9854
- );
9855
- return /* @__PURE__ */ jsx(
9856
- GridPicker,
9857
- {
9858
- items,
9859
- value,
9860
- onChange,
9861
- categories,
9862
- renderThumbnail,
9863
- cellSize: THUMB_PX,
9864
- className
9865
- }
9866
- );
9867
- };
9868
- AssetPicker.displayName = "AssetPicker";
9869
- }
9870
- });
9871
9579
  var AuthLayout;
9872
9580
  var init_AuthLayout = __esm({
9873
9581
  "components/marketing/templates/AuthLayout.tsx"() {
@@ -12479,6 +12187,263 @@ var init_katex_min = __esm({
12479
12187
  "node_modules/katex/dist/katex.min.css"() {
12480
12188
  }
12481
12189
  });
12190
+ var Tabs;
12191
+ var init_Tabs = __esm({
12192
+ "components/core/molecules/Tabs.tsx"() {
12193
+ "use client";
12194
+ init_Icon();
12195
+ init_Badge();
12196
+ init_Typography();
12197
+ init_Box();
12198
+ init_cn();
12199
+ init_useEventBus();
12200
+ Tabs = ({
12201
+ items,
12202
+ tabs,
12203
+ defaultActiveTab,
12204
+ activeTab: controlledActiveTab,
12205
+ onTabChange,
12206
+ tabChangeEvent,
12207
+ variant = "default",
12208
+ orientation = "horizontal",
12209
+ className
12210
+ }) => {
12211
+ const rawItems = items ?? tabs ?? [];
12212
+ const safeItems = rawItems.map(({ id, value, ...rest }) => ({
12213
+ ...rest,
12214
+ id: id || value || ""
12215
+ }));
12216
+ const eventBus = useEventBus();
12217
+ const { t } = useTranslate();
12218
+ const initialActive = safeItems.find((item) => item.active)?.id;
12219
+ const [internalActiveTab, setInternalActiveTab] = useState(
12220
+ defaultActiveTab || initialActive || safeItems[0]?.id || ""
12221
+ );
12222
+ const activeTab = controlledActiveTab !== void 0 ? controlledActiveTab : internalActiveTab;
12223
+ const tabRefs = useRef({});
12224
+ const handleTabChange = (tabId, tabEvent) => {
12225
+ if (controlledActiveTab === void 0) {
12226
+ setInternalActiveTab(tabId);
12227
+ }
12228
+ onTabChange?.(tabId);
12229
+ if (tabChangeEvent) {
12230
+ eventBus.emit(`UI:${tabChangeEvent}`, { tabId });
12231
+ }
12232
+ if (tabEvent) {
12233
+ eventBus.emit(`UI:${tabEvent}`, { tabId });
12234
+ }
12235
+ };
12236
+ const handleKeyDown = (e, index) => {
12237
+ if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
12238
+ e.preventDefault();
12239
+ const direction = e.key === "ArrowLeft" ? -1 : 1;
12240
+ const nextIndex = (index + direction + safeItems.length) % safeItems.length;
12241
+ const nextTab = safeItems[nextIndex];
12242
+ if (nextTab && !nextTab.disabled) {
12243
+ handleTabChange(nextTab.id);
12244
+ tabRefs.current[nextTab.id]?.focus();
12245
+ }
12246
+ } else if (e.key === "Home" || e.key === "End") {
12247
+ e.preventDefault();
12248
+ const targetIndex = e.key === "Home" ? 0 : safeItems.length - 1;
12249
+ const targetTab = safeItems[targetIndex];
12250
+ if (targetTab && !targetTab.disabled) {
12251
+ handleTabChange(targetTab.id);
12252
+ tabRefs.current[targetTab.id]?.focus();
12253
+ }
12254
+ }
12255
+ };
12256
+ const activeTabContent = safeItems.find((item) => item.id === activeTab)?.content;
12257
+ if (safeItems.length === 0) {
12258
+ return /* @__PURE__ */ jsx(Box, { className: cn("w-full", className), children: /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", className: "py-4", children: t("empty.noItems") }) });
12259
+ }
12260
+ const variantClasses2 = {
12261
+ default: [
12262
+ "border-b-[length:var(--border-width)] border-transparent",
12263
+ "hover:border-muted-foreground",
12264
+ "data-[active=true]:border-primary"
12265
+ ].join(" "),
12266
+ pills: [
12267
+ "rounded-sm",
12268
+ "data-[active=true]:bg-primary",
12269
+ "data-[active=true]:text-primary-foreground"
12270
+ ].join(" "),
12271
+ underline: [
12272
+ "border-b-[length:var(--border-width)] border-transparent",
12273
+ "data-[active=true]:border-primary"
12274
+ ].join(" ")
12275
+ };
12276
+ return /* @__PURE__ */ jsxs(Box, { className: cn("w-full", className), children: [
12277
+ /* @__PURE__ */ jsx(
12278
+ Box,
12279
+ {
12280
+ role: "tablist",
12281
+ className: cn(
12282
+ "flex",
12283
+ // Horizontal tab strip becomes a horizontally-scrollable lane
12284
+ // below its container width — phones with many tabs scroll
12285
+ // instead of clipping. `snap-x` snaps to each tab; the
12286
+ // scrollbar is hidden for a cleaner affordance (the swipe
12287
+ // gesture is the discoverability cue).
12288
+ orientation === "horizontal" ? "flex-row border-b-[length:var(--border-width)] border-border overflow-x-auto snap-x snap-mandatory [&::-webkit-scrollbar]:hidden" : "flex-col border-r-[length:var(--border-width)] border-border",
12289
+ variant === "pills" && "gap-1 p-1 bg-muted border-0 rounded-md",
12290
+ variant === "underline" && orientation === "vertical" && "border-b-0"
12291
+ ),
12292
+ children: safeItems.map((item, index) => {
12293
+ const isActive = item.id === activeTab;
12294
+ const isDisabled = item.disabled;
12295
+ return /* @__PURE__ */ jsxs(
12296
+ Box,
12297
+ {
12298
+ as: "button",
12299
+ ref: (el) => {
12300
+ tabRefs.current[item.id] = el;
12301
+ },
12302
+ role: "tab",
12303
+ "aria-selected": isActive,
12304
+ "aria-controls": `tabpanel-${item.id}`,
12305
+ "aria-disabled": isDisabled,
12306
+ onClick: () => !isDisabled && handleTabChange(item.id, item.event),
12307
+ onKeyDown: (e) => handleKeyDown(e, index),
12308
+ "data-active": isActive,
12309
+ className: cn(
12310
+ "flex items-center gap-2 px-4 py-2 text-sm font-medium transition-all whitespace-nowrap",
12311
+ orientation === "horizontal" && "snap-start shrink-0",
12312
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
12313
+ isDisabled && "opacity-50 cursor-not-allowed",
12314
+ variantClasses2[variant],
12315
+ isActive ? variant === "pills" ? "text-primary-foreground font-bold" : "text-foreground font-bold" : "text-muted-foreground hover:text-foreground"
12316
+ ),
12317
+ children: [
12318
+ item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm" })),
12319
+ /* @__PURE__ */ jsx(Typography, { variant: "small", weight: isActive ? "semibold" : "normal", className: "!text-inherit", children: item.label }),
12320
+ item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge })
12321
+ ]
12322
+ },
12323
+ item.id
12324
+ );
12325
+ })
12326
+ }
12327
+ ),
12328
+ activeTabContent !== void 0 && activeTabContent !== null && /* @__PURE__ */ jsx(
12329
+ Box,
12330
+ {
12331
+ role: "tabpanel",
12332
+ id: `tabpanel-${activeTab}`,
12333
+ "aria-labelledby": `tab-${activeTab}`,
12334
+ className: "mt-4",
12335
+ children: activeTabContent
12336
+ }
12337
+ )
12338
+ ] });
12339
+ };
12340
+ Tabs.displayName = "Tabs";
12341
+ }
12342
+ });
12343
+ var ICON_NAME_ALIASES, lookStyles3, EmptyState;
12344
+ var init_EmptyState = __esm({
12345
+ "components/core/molecules/EmptyState.tsx"() {
12346
+ "use client";
12347
+ init_cn();
12348
+ init_atoms2();
12349
+ init_Box();
12350
+ init_Icon();
12351
+ init_Stack();
12352
+ init_Typography();
12353
+ init_useEventBus();
12354
+ ICON_NAME_ALIASES = {
12355
+ check: "check-circle",
12356
+ error: "x-circle",
12357
+ warning: "alert-circle"
12358
+ };
12359
+ lookStyles3 = {
12360
+ "icon-only": "",
12361
+ illustrated: "[&_svg]:w-32 [&_svg]:h-32",
12362
+ "text-only": "[&_svg]:hidden",
12363
+ mascot: "[&_svg]:w-24 [&_svg]:h-24 [&_svg]:rounded-pill"
12364
+ };
12365
+ EmptyState = ({
12366
+ icon,
12367
+ title,
12368
+ message,
12369
+ description,
12370
+ actionLabel,
12371
+ onAction,
12372
+ className,
12373
+ destructive,
12374
+ variant,
12375
+ actionEvent,
12376
+ look = "icon-only"
12377
+ }) => {
12378
+ const eventBus = useEventBus();
12379
+ const { t } = useTranslate();
12380
+ const handleAction = () => {
12381
+ if (actionEvent) eventBus.emit(`UI:${actionEvent}`, {});
12382
+ onAction?.();
12383
+ };
12384
+ const iconName = typeof icon === "string" ? ICON_NAME_ALIASES[icon] ?? icon : void 0;
12385
+ const iconComponent = typeof icon === "function" ? icon : void 0;
12386
+ const hasIcon = Boolean(iconName || iconComponent);
12387
+ const isDestructive = destructive || variant === "error";
12388
+ const isSuccess = variant === "success";
12389
+ const displayText = title || message || t("empty.noItems");
12390
+ return /* @__PURE__ */ jsxs(
12391
+ VStack,
12392
+ {
12393
+ align: "center",
12394
+ className: cn(
12395
+ "justify-center py-12 text-center",
12396
+ lookStyles3[look],
12397
+ className
12398
+ ),
12399
+ children: [
12400
+ hasIcon && /* @__PURE__ */ jsx(
12401
+ Box,
12402
+ {
12403
+ className: cn(
12404
+ "mb-4 rounded-full p-3",
12405
+ isDestructive ? "bg-error/10" : isSuccess ? "bg-success/10" : "bg-muted"
12406
+ ),
12407
+ children: /* @__PURE__ */ jsx(
12408
+ Icon,
12409
+ {
12410
+ ...iconName ? { name: iconName } : { icon: iconComponent },
12411
+ className: cn(
12412
+ "h-8 w-8",
12413
+ isDestructive ? "text-error" : isSuccess ? "text-success" : "text-muted-foreground"
12414
+ )
12415
+ }
12416
+ )
12417
+ }
12418
+ ),
12419
+ /* @__PURE__ */ jsx(
12420
+ Typography,
12421
+ {
12422
+ variant: "h3",
12423
+ className: cn(
12424
+ "text-lg font-medium",
12425
+ isDestructive ? "text-error" : isSuccess ? "text-success" : "text-foreground"
12426
+ ),
12427
+ children: displayText
12428
+ }
12429
+ ),
12430
+ description && /* @__PURE__ */ jsx(Typography, { variant: "small", className: "mt-1 text-muted-foreground max-w-sm", children: description }),
12431
+ actionLabel && (onAction || actionEvent) && /* @__PURE__ */ jsx(
12432
+ Button,
12433
+ {
12434
+ className: "mt-4",
12435
+ variant: isDestructive ? "danger" : "primary",
12436
+ onClick: handleAction,
12437
+ children: actionLabel
12438
+ }
12439
+ )
12440
+ ]
12441
+ }
12442
+ );
12443
+ };
12444
+ EmptyState.displayName = "EmptyState";
12445
+ }
12446
+ });
12482
12447
  function computeFoldRegions(code) {
12483
12448
  const lines = code.split("\n");
12484
12449
  const regions = [];
@@ -12516,9 +12481,32 @@ function computeFoldRegions(code) {
12516
12481
  function toCodeLanguage(value) {
12517
12482
  return value && CODE_LANGUAGE_SET.has(value) ? value : "text";
12518
12483
  }
12519
- var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log5, CODE_LANGUAGES, CODE_LANGUAGE_SET, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
12484
+ function generateDiff(oldVal, newVal) {
12485
+ const oldLines = oldVal.split("\n");
12486
+ const newLines = newVal.split("\n");
12487
+ const diff = [];
12488
+ const maxLen = Math.max(oldLines.length, newLines.length);
12489
+ for (let i = 0; i < maxLen; i++) {
12490
+ const oldLine = oldLines[i];
12491
+ const newLine = newLines[i];
12492
+ if (oldLine === newLine) {
12493
+ diff.push({ type: "context", content: oldLine ?? "", lineNumber: i + 1 });
12494
+ } else {
12495
+ if (oldLine !== void 0) diff.push({ type: "remove", content: oldLine, lineNumber: i + 1 });
12496
+ if (newLine !== void 0) diff.push({ type: "add", content: newLine, lineNumber: i + 1 });
12497
+ }
12498
+ }
12499
+ return diff;
12500
+ }
12501
+ var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log5, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
12520
12502
  var init_CodeBlock = __esm({
12521
12503
  "components/core/molecules/markdown/CodeBlock.tsx"() {
12504
+ init_cn();
12505
+ init_atoms2();
12506
+ init_Tabs();
12507
+ init_LoadingState();
12508
+ init_ErrorState();
12509
+ init_EmptyState();
12522
12510
  init_Box();
12523
12511
  init_Button();
12524
12512
  init_Badge();
@@ -12625,9 +12613,14 @@ var init_CodeBlock = __esm({
12625
12613
  "lolo"
12626
12614
  ];
12627
12615
  CODE_LANGUAGE_SET = new Set(CODE_LANGUAGES);
12616
+ DIFF_STYLES = {
12617
+ add: { bg: "bg-success/10", prefix: "+", text: "text-success" },
12618
+ remove: { bg: "bg-error/10", prefix: "-", text: "text-error" },
12619
+ context: { bg: "", prefix: " ", text: "text-foreground" }
12620
+ };
12628
12621
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
12629
12622
  HIDDEN_LINE_NUMBERS = { display: "none" };
12630
- CodeBlock = React83__default.memo(
12623
+ CodeBlock = React79__default.memo(
12631
12624
  ({
12632
12625
  code: rawCode,
12633
12626
  language = "text",
@@ -12638,7 +12631,20 @@ var init_CodeBlock = __esm({
12638
12631
  className,
12639
12632
  editable = false,
12640
12633
  onChange,
12641
- errorLines
12634
+ errorLines,
12635
+ // viewer props
12636
+ title,
12637
+ mode = "code",
12638
+ diff: propDiff,
12639
+ oldValue,
12640
+ newValue,
12641
+ showLineNumbers = false,
12642
+ wordWrap = false,
12643
+ files,
12644
+ actions,
12645
+ isLoading = false,
12646
+ error,
12647
+ showCopy
12642
12648
  }) => {
12643
12649
  const code = typeof rawCode === "string" ? rawCode : String(rawCode ?? "");
12644
12650
  const isOrb = language === "orb";
@@ -12650,6 +12656,20 @@ var init_CodeBlock = __esm({
12650
12656
  const codeRef = useRef(null);
12651
12657
  const savedScrollLeftRef = useRef(0);
12652
12658
  const [copied, setCopied] = useState(false);
12659
+ const [wrap, setWrap] = useState(wordWrap);
12660
+ const [activeFileIndex, setActiveFileIndex] = useState(0);
12661
+ const activeFile = files?.[activeFileIndex];
12662
+ const activeCode = activeFile?.code ?? code;
12663
+ const activeLanguage = activeFile?.language ?? language;
12664
+ const diffLines = useMemo(() => {
12665
+ if (propDiff) return propDiff;
12666
+ if (mode === "diff" && oldValue !== void 0 && newValue !== void 0) {
12667
+ return generateDiff(oldValue, newValue);
12668
+ }
12669
+ return null;
12670
+ }, [propDiff, mode, oldValue, newValue]);
12671
+ const isViewerMode = !!(title || files || showLineNumbers || diffLines || mode === "diff" || actions);
12672
+ const effectiveCopy = showCopy ?? showCopyButton;
12653
12673
  const [editableValue, setEditableValue] = useState(code);
12654
12674
  const [editableTextareaKey, setEditableTextareaKey] = useState(0);
12655
12675
  const lastPropCodeRef = useRef(code);
@@ -12820,13 +12840,13 @@ var init_CodeBlock = __esm({
12820
12840
  }, [language, code]);
12821
12841
  const handleCopy = async () => {
12822
12842
  try {
12823
- await navigator.clipboard.writeText(code);
12843
+ await navigator.clipboard.writeText(activeCode);
12824
12844
  setCopied(true);
12825
- eventBus.emit("UI:COPY_CODE", { language, success: true });
12845
+ eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: true });
12826
12846
  setTimeout(() => setCopied(false), 2e3);
12827
12847
  } catch (err) {
12828
12848
  log5.error("Failed to copy code", { error: err instanceof Error ? err : String(err) });
12829
- eventBus.emit("UI:COPY_CODE", { language, success: false });
12849
+ eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: false });
12830
12850
  }
12831
12851
  };
12832
12852
  const handleSelectionCopy = useCallback((e) => {
@@ -12879,11 +12899,134 @@ var init_CodeBlock = __esm({
12879
12899
  }
12880
12900
  });
12881
12901
  }
12882
- const full = code.split("\n").slice(a, endLine + 1).join("\n");
12902
+ const full = activeCode.split("\n").slice(a, endLine + 1).join("\n");
12883
12903
  e.clipboardData.setData("text/plain", full);
12884
12904
  e.preventDefault();
12885
12905
  }, [code]);
12886
- const hasHeader = showLanguageBadge || showCopyButton;
12906
+ if (isLoading) {
12907
+ return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
12908
+ }
12909
+ if (error) {
12910
+ return /* @__PURE__ */ jsx(ErrorState, { title: t("display.codeViewerError"), message: error.message, className });
12911
+ }
12912
+ if (isViewerMode && !activeCode && !diffLines) {
12913
+ return /* @__PURE__ */ jsx(EmptyState, { icon: Code, title: t("display.noCode"), description: "No code to display.", className });
12914
+ }
12915
+ if (isViewerMode) {
12916
+ const tabItems = files?.map((file, idx) => ({
12917
+ id: `file-${idx}`,
12918
+ label: file.label,
12919
+ content: null
12920
+ }));
12921
+ const lines = activeCode.split("\n");
12922
+ return /* @__PURE__ */ jsx(Card, { className: cn("overflow-hidden", className), children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
12923
+ tabItems && tabItems.length > 1 && /* @__PURE__ */ jsx(Box, { className: "border-b border-border", children: /* @__PURE__ */ jsx(
12924
+ Tabs,
12925
+ {
12926
+ tabs: tabItems,
12927
+ activeTab: `file-${activeFileIndex}`,
12928
+ onTabChange: (id) => {
12929
+ const idx = parseInt(id.replace("file-", ""), 10);
12930
+ setActiveFileIndex(idx);
12931
+ }
12932
+ }
12933
+ ) }),
12934
+ /* @__PURE__ */ jsxs(
12935
+ HStack,
12936
+ {
12937
+ gap: "sm",
12938
+ align: "center",
12939
+ justify: "between",
12940
+ className: "px-4 py-2 border-b border-border bg-muted/30",
12941
+ children: [
12942
+ /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", children: [
12943
+ /* @__PURE__ */ jsx(Icon, { icon: mode === "diff" ? FileText : Code, size: "sm", className: "text-muted-foreground" }),
12944
+ title && /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "truncate", children: title }),
12945
+ activeLanguage && activeLanguage !== "text" && /* @__PURE__ */ jsx(Badge, { variant: "default", children: activeLanguage })
12946
+ ] }),
12947
+ /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
12948
+ /* @__PURE__ */ jsx(
12949
+ Button,
12950
+ {
12951
+ variant: "ghost",
12952
+ size: "sm",
12953
+ icon: WrapText,
12954
+ onClick: () => setWrap(!wrap),
12955
+ className: cn(wrap && "text-primary")
12956
+ }
12957
+ ),
12958
+ effectiveCopy && /* @__PURE__ */ jsx(
12959
+ Button,
12960
+ {
12961
+ variant: "ghost",
12962
+ size: "sm",
12963
+ icon: copied ? Check : Copy,
12964
+ onClick: handleCopy,
12965
+ className: cn(copied && "text-success")
12966
+ }
12967
+ ),
12968
+ actions?.map((action, idx) => /* @__PURE__ */ jsx(
12969
+ Badge,
12970
+ {
12971
+ variant: "default",
12972
+ className: "cursor-pointer hover:opacity-80 transition-opacity",
12973
+ onClick: () => {
12974
+ if (action.event) eventBus.emit(`UI:${action.event}`, {});
12975
+ },
12976
+ children: action.label
12977
+ },
12978
+ idx
12979
+ ))
12980
+ ] })
12981
+ ]
12982
+ }
12983
+ ),
12984
+ /* @__PURE__ */ jsx(Box, { className: "overflow-auto bg-muted/20", style: { maxHeight }, children: diffLines ? /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children: diffLines.map((line, idx) => {
12985
+ const style = DIFF_STYLES[line.type];
12986
+ return /* @__PURE__ */ jsxs(HStack, { gap: "none", align: "start", className: cn(style.bg, "px-4 py-0.5"), children: [
12987
+ showLineNumbers && /* @__PURE__ */ jsx(
12988
+ Typography,
12989
+ {
12990
+ variant: "caption",
12991
+ color: "secondary",
12992
+ className: "w-8 text-right mr-3 select-none tabular-nums flex-shrink-0",
12993
+ children: line.lineNumber ?? ""
12994
+ }
12995
+ ),
12996
+ /* @__PURE__ */ jsxs(
12997
+ Typography,
12998
+ {
12999
+ variant: "caption",
13000
+ className: cn("font-mono flex-1 min-w-0", style.text, wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"),
13001
+ children: [
13002
+ /* @__PURE__ */ jsx(Box, { as: "span", className: "select-none opacity-50 mr-2", children: style.prefix }),
13003
+ line.content
13004
+ ]
13005
+ }
13006
+ )
13007
+ ] }, idx);
13008
+ }) }) : /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children: lines.map((line, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "none", align: "start", className: "px-4 py-0.5 hover:bg-muted/50", children: [
13009
+ showLineNumbers && /* @__PURE__ */ jsx(
13010
+ Typography,
13011
+ {
13012
+ variant: "caption",
13013
+ color: "secondary",
13014
+ className: "w-8 text-right mr-4 select-none tabular-nums flex-shrink-0",
13015
+ children: idx + 1
13016
+ }
13017
+ ),
13018
+ /* @__PURE__ */ jsx(
13019
+ Typography,
13020
+ {
13021
+ variant: "caption",
13022
+ className: cn("font-mono flex-1 min-w-0", wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"),
13023
+ children: line || " "
13024
+ }
13025
+ )
13026
+ ] }, idx)) }) })
13027
+ ] }) });
13028
+ }
13029
+ const hasHeader = showLanguageBadge || effectiveCopy;
12887
13030
  return /* @__PURE__ */ jsxs(Box, { className: `relative group ${className || ""}`, style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
12888
13031
  hasHeader && /* @__PURE__ */ jsxs(
12889
13032
  HStack,
@@ -12893,7 +13036,7 @@ var init_CodeBlock = __esm({
12893
13036
  className: "px-3 py-2 bg-[var(--color-card)] rounded-t-lg border-b border-gray-700",
12894
13037
  children: [
12895
13038
  showLanguageBadge && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: language }),
12896
- showCopyButton && /* @__PURE__ */ jsx(
13039
+ effectiveCopy && /* @__PURE__ */ jsx(
12897
13040
  Button,
12898
13041
  {
12899
13042
  variant: "ghost",
@@ -13052,7 +13195,7 @@ var init_CodeBlock = __esm({
13052
13195
  )
13053
13196
  ] });
13054
13197
  },
13055
- (prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.maxHeight === next.maxHeight && prev.foldable === next.foldable && prev.editable === next.editable && prev.onChange === next.onChange && prev.errorLines === next.errorLines
13198
+ (prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.showCopy === next.showCopy && prev.maxHeight === next.maxHeight && prev.foldable === next.foldable && prev.editable === next.editable && prev.onChange === next.onChange && prev.errorLines === next.errorLines && prev.mode === next.mode && prev.title === next.title && prev.diff === next.diff && prev.files === next.files && prev.actions === next.actions && prev.isLoading === next.isLoading && prev.error === next.error
13056
13199
  );
13057
13200
  CodeBlock.displayName = "CodeBlock";
13058
13201
  }
@@ -13064,7 +13207,7 @@ var init_MarkdownContent = __esm({
13064
13207
  init_Box();
13065
13208
  init_CodeBlock();
13066
13209
  init_cn();
13067
- MarkdownContent = React83__default.memo(
13210
+ MarkdownContent = React79__default.memo(
13068
13211
  ({ content, direction, className }) => {
13069
13212
  const { t: _t } = useTranslate();
13070
13213
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -14160,7 +14303,7 @@ var init_StateMachineView = __esm({
14160
14303
  style: { top: title ? 30 : 0 },
14161
14304
  children: [
14162
14305
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
14163
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React83__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
14306
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React79__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
14164
14307
  StateNode,
14165
14308
  {
14166
14309
  state,
@@ -15309,110 +15452,6 @@ var init_BookTableOfContents = __esm({
15309
15452
  BookTableOfContents.displayName = "BookTableOfContents";
15310
15453
  }
15311
15454
  });
15312
- var ICON_NAME_ALIASES, lookStyles3, EmptyState;
15313
- var init_EmptyState = __esm({
15314
- "components/core/molecules/EmptyState.tsx"() {
15315
- "use client";
15316
- init_cn();
15317
- init_atoms2();
15318
- init_Box();
15319
- init_Icon();
15320
- init_Stack();
15321
- init_Typography();
15322
- init_useEventBus();
15323
- ICON_NAME_ALIASES = {
15324
- check: "check-circle",
15325
- error: "x-circle",
15326
- warning: "alert-circle"
15327
- };
15328
- lookStyles3 = {
15329
- "icon-only": "",
15330
- illustrated: "[&_svg]:w-32 [&_svg]:h-32",
15331
- "text-only": "[&_svg]:hidden",
15332
- mascot: "[&_svg]:w-24 [&_svg]:h-24 [&_svg]:rounded-pill"
15333
- };
15334
- EmptyState = ({
15335
- icon,
15336
- title,
15337
- message,
15338
- description,
15339
- actionLabel,
15340
- onAction,
15341
- className,
15342
- destructive,
15343
- variant,
15344
- actionEvent,
15345
- look = "icon-only"
15346
- }) => {
15347
- const eventBus = useEventBus();
15348
- const { t } = useTranslate();
15349
- const handleAction = () => {
15350
- if (actionEvent) eventBus.emit(`UI:${actionEvent}`, {});
15351
- onAction?.();
15352
- };
15353
- const iconName = typeof icon === "string" ? ICON_NAME_ALIASES[icon] ?? icon : void 0;
15354
- const iconComponent = typeof icon === "function" ? icon : void 0;
15355
- const hasIcon = Boolean(iconName || iconComponent);
15356
- const isDestructive = destructive || variant === "error";
15357
- const isSuccess = variant === "success";
15358
- const displayText = title || message || t("empty.noItems");
15359
- return /* @__PURE__ */ jsxs(
15360
- VStack,
15361
- {
15362
- align: "center",
15363
- className: cn(
15364
- "justify-center py-12 text-center",
15365
- lookStyles3[look],
15366
- className
15367
- ),
15368
- children: [
15369
- hasIcon && /* @__PURE__ */ jsx(
15370
- Box,
15371
- {
15372
- className: cn(
15373
- "mb-4 rounded-full p-3",
15374
- isDestructive ? "bg-error/10" : isSuccess ? "bg-success/10" : "bg-muted"
15375
- ),
15376
- children: /* @__PURE__ */ jsx(
15377
- Icon,
15378
- {
15379
- ...iconName ? { name: iconName } : { icon: iconComponent },
15380
- className: cn(
15381
- "h-8 w-8",
15382
- isDestructive ? "text-error" : isSuccess ? "text-success" : "text-muted-foreground"
15383
- )
15384
- }
15385
- )
15386
- }
15387
- ),
15388
- /* @__PURE__ */ jsx(
15389
- Typography,
15390
- {
15391
- variant: "h3",
15392
- className: cn(
15393
- "text-lg font-medium",
15394
- isDestructive ? "text-error" : isSuccess ? "text-success" : "text-foreground"
15395
- ),
15396
- children: displayText
15397
- }
15398
- ),
15399
- description && /* @__PURE__ */ jsx(Typography, { variant: "small", className: "mt-1 text-muted-foreground max-w-sm", children: description }),
15400
- actionLabel && (onAction || actionEvent) && /* @__PURE__ */ jsx(
15401
- Button,
15402
- {
15403
- className: "mt-4",
15404
- variant: isDestructive ? "danger" : "primary",
15405
- onClick: handleAction,
15406
- children: actionLabel
15407
- }
15408
- )
15409
- ]
15410
- }
15411
- );
15412
- };
15413
- EmptyState.displayName = "EmptyState";
15414
- }
15415
- });
15416
15455
 
15417
15456
  // components/core/organisms/book/types.ts
15418
15457
  function resolveFieldMap(fieldMap) {
@@ -15765,7 +15804,7 @@ var init_Grid = __esm({
15765
15804
  as: Component = "div"
15766
15805
  }) => {
15767
15806
  const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
15768
- return React83__default.createElement(
15807
+ return React79__default.createElement(
15769
15808
  Component,
15770
15809
  {
15771
15810
  className: cn(
@@ -20254,449 +20293,6 @@ var init_ClassifierBoard = __esm({
20254
20293
  ClassifierBoard.displayName = "ClassifierBoard";
20255
20294
  }
20256
20295
  });
20257
- function CodeView({
20258
- data,
20259
- label,
20260
- defaultExpanded = false,
20261
- className
20262
- }) {
20263
- const { t } = useTranslate();
20264
- const [expanded, setExpanded] = useState(defaultExpanded);
20265
- const jsonString = JSON.stringify(data, null, 2);
20266
- return /* @__PURE__ */ jsxs(VStack, { className: cn("rounded-lg border border-border overflow-hidden", className), gap: "none", children: [
20267
- /* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between p-2 bg-muted", gap: "sm", children: [
20268
- /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground font-medium", children: label ?? t("stateArchitect.viewCode") }),
20269
- /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: () => setExpanded(!expanded), className: "text-xs", children: expanded ? t("stateArchitect.hideJson") : t("stateArchitect.showJson") })
20270
- ] }),
20271
- expanded && /* @__PURE__ */ jsx(Box, { className: "p-3 bg-background overflow-x-auto", children: /* @__PURE__ */ jsx(
20272
- Typography,
20273
- {
20274
- variant: "caption",
20275
- className: "text-foreground font-mono whitespace-pre text-xs leading-relaxed block",
20276
- children: jsonString
20277
- }
20278
- ) })
20279
- ] });
20280
- }
20281
- var init_CodeView = __esm({
20282
- "components/game/organisms/puzzles/state-architect/CodeView.tsx"() {
20283
- init_atoms2();
20284
- init_cn();
20285
- CodeView.displayName = "CodeView";
20286
- }
20287
- });
20288
- var Tabs;
20289
- var init_Tabs = __esm({
20290
- "components/core/molecules/Tabs.tsx"() {
20291
- "use client";
20292
- init_Icon();
20293
- init_Badge();
20294
- init_Typography();
20295
- init_Box();
20296
- init_cn();
20297
- init_useEventBus();
20298
- Tabs = ({
20299
- items,
20300
- tabs,
20301
- defaultActiveTab,
20302
- activeTab: controlledActiveTab,
20303
- onTabChange,
20304
- tabChangeEvent,
20305
- variant = "default",
20306
- orientation = "horizontal",
20307
- className
20308
- }) => {
20309
- const rawItems = items ?? tabs ?? [];
20310
- const safeItems = rawItems.map(({ id, value, ...rest }) => ({
20311
- ...rest,
20312
- id: id || value || ""
20313
- }));
20314
- const eventBus = useEventBus();
20315
- const { t } = useTranslate();
20316
- const initialActive = safeItems.find((item) => item.active)?.id;
20317
- const [internalActiveTab, setInternalActiveTab] = useState(
20318
- defaultActiveTab || initialActive || safeItems[0]?.id || ""
20319
- );
20320
- const activeTab = controlledActiveTab !== void 0 ? controlledActiveTab : internalActiveTab;
20321
- const tabRefs = useRef({});
20322
- const handleTabChange = (tabId, tabEvent) => {
20323
- if (controlledActiveTab === void 0) {
20324
- setInternalActiveTab(tabId);
20325
- }
20326
- onTabChange?.(tabId);
20327
- if (tabChangeEvent) {
20328
- eventBus.emit(`UI:${tabChangeEvent}`, { tabId });
20329
- }
20330
- if (tabEvent) {
20331
- eventBus.emit(`UI:${tabEvent}`, { tabId });
20332
- }
20333
- };
20334
- const handleKeyDown = (e, index) => {
20335
- if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
20336
- e.preventDefault();
20337
- const direction = e.key === "ArrowLeft" ? -1 : 1;
20338
- const nextIndex = (index + direction + safeItems.length) % safeItems.length;
20339
- const nextTab = safeItems[nextIndex];
20340
- if (nextTab && !nextTab.disabled) {
20341
- handleTabChange(nextTab.id);
20342
- tabRefs.current[nextTab.id]?.focus();
20343
- }
20344
- } else if (e.key === "Home" || e.key === "End") {
20345
- e.preventDefault();
20346
- const targetIndex = e.key === "Home" ? 0 : safeItems.length - 1;
20347
- const targetTab = safeItems[targetIndex];
20348
- if (targetTab && !targetTab.disabled) {
20349
- handleTabChange(targetTab.id);
20350
- tabRefs.current[targetTab.id]?.focus();
20351
- }
20352
- }
20353
- };
20354
- const activeTabContent = safeItems.find((item) => item.id === activeTab)?.content;
20355
- if (safeItems.length === 0) {
20356
- return /* @__PURE__ */ jsx(Box, { className: cn("w-full", className), children: /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", className: "py-4", children: t("empty.noItems") }) });
20357
- }
20358
- const variantClasses2 = {
20359
- default: [
20360
- "border-b-[length:var(--border-width)] border-transparent",
20361
- "hover:border-muted-foreground",
20362
- "data-[active=true]:border-primary"
20363
- ].join(" "),
20364
- pills: [
20365
- "rounded-sm",
20366
- "data-[active=true]:bg-primary",
20367
- "data-[active=true]:text-primary-foreground"
20368
- ].join(" "),
20369
- underline: [
20370
- "border-b-[length:var(--border-width)] border-transparent",
20371
- "data-[active=true]:border-primary"
20372
- ].join(" ")
20373
- };
20374
- return /* @__PURE__ */ jsxs(Box, { className: cn("w-full", className), children: [
20375
- /* @__PURE__ */ jsx(
20376
- Box,
20377
- {
20378
- role: "tablist",
20379
- className: cn(
20380
- "flex",
20381
- // Horizontal tab strip becomes a horizontally-scrollable lane
20382
- // below its container width — phones with many tabs scroll
20383
- // instead of clipping. `snap-x` snaps to each tab; the
20384
- // scrollbar is hidden for a cleaner affordance (the swipe
20385
- // gesture is the discoverability cue).
20386
- orientation === "horizontal" ? "flex-row border-b-[length:var(--border-width)] border-border overflow-x-auto snap-x snap-mandatory [&::-webkit-scrollbar]:hidden" : "flex-col border-r-[length:var(--border-width)] border-border",
20387
- variant === "pills" && "gap-1 p-1 bg-muted border-0 rounded-md",
20388
- variant === "underline" && orientation === "vertical" && "border-b-0"
20389
- ),
20390
- children: safeItems.map((item, index) => {
20391
- const isActive = item.id === activeTab;
20392
- const isDisabled = item.disabled;
20393
- return /* @__PURE__ */ jsxs(
20394
- Box,
20395
- {
20396
- as: "button",
20397
- ref: (el) => {
20398
- tabRefs.current[item.id] = el;
20399
- },
20400
- role: "tab",
20401
- "aria-selected": isActive,
20402
- "aria-controls": `tabpanel-${item.id}`,
20403
- "aria-disabled": isDisabled,
20404
- onClick: () => !isDisabled && handleTabChange(item.id, item.event),
20405
- onKeyDown: (e) => handleKeyDown(e, index),
20406
- "data-active": isActive,
20407
- className: cn(
20408
- "flex items-center gap-2 px-4 py-2 text-sm font-medium transition-all whitespace-nowrap",
20409
- orientation === "horizontal" && "snap-start shrink-0",
20410
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
20411
- isDisabled && "opacity-50 cursor-not-allowed",
20412
- variantClasses2[variant],
20413
- isActive ? variant === "pills" ? "text-primary-foreground font-bold" : "text-foreground font-bold" : "text-muted-foreground hover:text-foreground"
20414
- ),
20415
- children: [
20416
- item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm" })),
20417
- /* @__PURE__ */ jsx(Typography, { variant: "small", weight: isActive ? "semibold" : "normal", className: "!text-inherit", children: item.label }),
20418
- item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: item.badge })
20419
- ]
20420
- },
20421
- item.id
20422
- );
20423
- })
20424
- }
20425
- ),
20426
- activeTabContent !== void 0 && activeTabContent !== null && /* @__PURE__ */ jsx(
20427
- Box,
20428
- {
20429
- role: "tabpanel",
20430
- id: `tabpanel-${activeTab}`,
20431
- "aria-labelledby": `tab-${activeTab}`,
20432
- className: "mt-4",
20433
- children: activeTabContent
20434
- }
20435
- )
20436
- ] });
20437
- };
20438
- Tabs.displayName = "Tabs";
20439
- }
20440
- });
20441
- function generateDiff(oldVal, newVal) {
20442
- const oldLines = oldVal.split("\n");
20443
- const newLines = newVal.split("\n");
20444
- const diff = [];
20445
- const maxLen = Math.max(oldLines.length, newLines.length);
20446
- for (let i = 0; i < maxLen; i++) {
20447
- const oldLine = oldLines[i];
20448
- const newLine = newLines[i];
20449
- if (oldLine === newLine) {
20450
- diff.push({ type: "context", content: oldLine ?? "", lineNumber: i + 1 });
20451
- } else {
20452
- if (oldLine !== void 0) {
20453
- diff.push({ type: "remove", content: oldLine, lineNumber: i + 1 });
20454
- }
20455
- if (newLine !== void 0) {
20456
- diff.push({ type: "add", content: newLine, lineNumber: i + 1 });
20457
- }
20458
- }
20459
- }
20460
- return diff;
20461
- }
20462
- var DIFF_STYLES, CodeViewer;
20463
- var init_CodeViewer = __esm({
20464
- "components/core/molecules/CodeViewer.tsx"() {
20465
- "use client";
20466
- init_cn();
20467
- init_atoms2();
20468
- init_Stack();
20469
- init_LoadingState();
20470
- init_ErrorState();
20471
- init_EmptyState();
20472
- init_Tabs();
20473
- init_useEventBus();
20474
- DIFF_STYLES = {
20475
- add: {
20476
- bg: "bg-success/10",
20477
- prefix: "+",
20478
- text: "text-success"
20479
- },
20480
- remove: {
20481
- bg: "bg-error/10",
20482
- prefix: "-",
20483
- text: "text-error"
20484
- },
20485
- context: {
20486
- bg: "",
20487
- prefix: " ",
20488
- text: "text-foreground"
20489
- }
20490
- };
20491
- CodeViewer = ({
20492
- title,
20493
- code,
20494
- language,
20495
- diff: propDiff,
20496
- oldValue,
20497
- newValue,
20498
- mode = "code",
20499
- showLineNumbers = true,
20500
- showCopy = true,
20501
- wordWrap = false,
20502
- maxHeight = 500,
20503
- files,
20504
- actions,
20505
- entity,
20506
- isLoading = false,
20507
- error,
20508
- className
20509
- }) => {
20510
- const eventBus = useEventBus();
20511
- const { t } = useTranslate();
20512
- const [copied, setCopied] = useState(false);
20513
- const [wrap, setWrap] = useState(wordWrap);
20514
- const [activeFileIndex, setActiveFileIndex] = useState(0);
20515
- const handleAction = useCallback(
20516
- (action) => {
20517
- if (action.event) {
20518
- eventBus.emit(`UI:${action.event}`, {});
20519
- }
20520
- },
20521
- [eventBus]
20522
- );
20523
- const activeFile = files?.[activeFileIndex];
20524
- const activeCode = activeFile?.code ?? code ?? "";
20525
- const activeLanguage = activeFile?.language ?? language ?? "text";
20526
- const lines = useMemo(() => activeCode.split("\n"), [activeCode]);
20527
- const diffLines = useMemo(() => {
20528
- if (propDiff) return propDiff;
20529
- if (mode === "diff" && oldValue !== void 0 && newValue !== void 0) {
20530
- return generateDiff(oldValue, newValue);
20531
- }
20532
- return null;
20533
- }, [propDiff, mode, oldValue, newValue]);
20534
- const handleCopy = useCallback(async () => {
20535
- try {
20536
- await navigator.clipboard.writeText(activeCode);
20537
- setCopied(true);
20538
- eventBus.emit("UI:CODE_COPY", { language: activeLanguage });
20539
- setTimeout(() => setCopied(false), 2e3);
20540
- } catch {
20541
- }
20542
- }, [activeCode, eventBus, activeLanguage]);
20543
- const tabItems = files?.map((file, idx) => ({
20544
- id: `file-${idx}`,
20545
- label: file.label,
20546
- content: null
20547
- }));
20548
- if (isLoading) {
20549
- return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
20550
- }
20551
- if (error) {
20552
- return /* @__PURE__ */ jsx(
20553
- ErrorState,
20554
- {
20555
- title: t("display.codeViewerError"),
20556
- message: error.message,
20557
- className
20558
- }
20559
- );
20560
- }
20561
- if (!activeCode && !diffLines) {
20562
- return /* @__PURE__ */ jsx(
20563
- EmptyState,
20564
- {
20565
- icon: Code,
20566
- title: t("display.noCode"),
20567
- description: "No code to display.",
20568
- className
20569
- }
20570
- );
20571
- }
20572
- return /* @__PURE__ */ jsx(Card, { className: cn("overflow-hidden", className), children: /* @__PURE__ */ jsxs(VStack, { gap: "none", children: [
20573
- tabItems && tabItems.length > 1 && /* @__PURE__ */ jsx(Box, { className: "border-b border-border", children: /* @__PURE__ */ jsx(
20574
- Tabs,
20575
- {
20576
- tabs: tabItems,
20577
- activeTab: `file-${activeFileIndex}`,
20578
- onTabChange: (id) => {
20579
- const idx = parseInt(id.replace("file-", ""), 10);
20580
- setActiveFileIndex(idx);
20581
- }
20582
- }
20583
- ) }),
20584
- /* @__PURE__ */ jsxs(
20585
- HStack,
20586
- {
20587
- gap: "sm",
20588
- align: "center",
20589
- justify: "between",
20590
- className: "px-4 py-2 border-b border-border bg-muted/30",
20591
- children: [
20592
- /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", children: [
20593
- /* @__PURE__ */ jsx(Icon, { icon: mode === "diff" ? FileText : Code, size: "sm", className: "text-muted-foreground" }),
20594
- title && /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "truncate", children: title }),
20595
- activeLanguage && activeLanguage !== "text" && /* @__PURE__ */ jsx(Badge, { variant: "default", children: activeLanguage })
20596
- ] }),
20597
- /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
20598
- /* @__PURE__ */ jsx(
20599
- Button,
20600
- {
20601
- variant: "ghost",
20602
- size: "sm",
20603
- icon: WrapText,
20604
- onClick: () => setWrap(!wrap),
20605
- className: cn(wrap && "text-primary")
20606
- }
20607
- ),
20608
- showCopy && /* @__PURE__ */ jsx(
20609
- Button,
20610
- {
20611
- variant: "ghost",
20612
- size: "sm",
20613
- icon: copied ? Check : Copy,
20614
- onClick: handleCopy,
20615
- className: cn(copied && "text-success")
20616
- }
20617
- ),
20618
- actions?.map((action, idx) => /* @__PURE__ */ jsx(
20619
- Badge,
20620
- {
20621
- variant: "default",
20622
- className: "cursor-pointer hover:opacity-80 transition-opacity",
20623
- onClick: () => handleAction(action),
20624
- children: action.label
20625
- },
20626
- idx
20627
- ))
20628
- ] })
20629
- ]
20630
- }
20631
- ),
20632
- /* @__PURE__ */ jsx(
20633
- Box,
20634
- {
20635
- className: "overflow-auto bg-muted/20",
20636
- style: { maxHeight },
20637
- children: diffLines ? (
20638
- /* Diff mode */
20639
- /* @__PURE__ */ jsx(VStack, { gap: "none", className: "font-mono text-xs", children: diffLines.map((line, idx) => {
20640
- const style = DIFF_STYLES[line.type];
20641
- return /* @__PURE__ */ jsxs(HStack, { gap: "none", align: "start", className: cn(style.bg, "px-4 py-0.5"), children: [
20642
- showLineNumbers && /* @__PURE__ */ jsx(
20643
- Typography,
20644
- {
20645
- variant: "caption",
20646
- color: "secondary",
20647
- className: "w-8 text-right mr-3 select-none tabular-nums flex-shrink-0",
20648
- children: line.lineNumber ?? ""
20649
- }
20650
- ),
20651
- /* @__PURE__ */ jsxs(
20652
- Typography,
20653
- {
20654
- variant: "caption",
20655
- className: cn(
20656
- "font-mono flex-1 min-w-0",
20657
- style.text,
20658
- wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"
20659
- ),
20660
- children: [
20661
- /* @__PURE__ */ jsx(Box, { as: "span", className: "select-none opacity-50 mr-2", children: style.prefix }),
20662
- line.content
20663
- ]
20664
- }
20665
- )
20666
- ] }, idx);
20667
- }) })
20668
- ) : (
20669
- /* Code mode */
20670
- /* @__PURE__ */ jsx(VStack, { gap: "none", className: "font-mono text-xs", children: lines.map((line, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "none", align: "start", className: "px-4 py-0.5 hover:bg-muted/50", children: [
20671
- showLineNumbers && /* @__PURE__ */ jsx(
20672
- Typography,
20673
- {
20674
- variant: "caption",
20675
- color: "secondary",
20676
- className: "w-8 text-right mr-4 select-none tabular-nums flex-shrink-0",
20677
- children: idx + 1
20678
- }
20679
- ),
20680
- /* @__PURE__ */ jsx(
20681
- Typography,
20682
- {
20683
- variant: "caption",
20684
- className: cn(
20685
- "font-mono flex-1 min-w-0",
20686
- wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"
20687
- ),
20688
- children: line || " "
20689
- }
20690
- )
20691
- ] }, idx)) })
20692
- )
20693
- }
20694
- )
20695
- ] }) });
20696
- };
20697
- CodeViewer.displayName = "CodeViewer";
20698
- }
20699
- });
20700
20296
  function CombatLog({
20701
20297
  events: events2,
20702
20298
  maxVisible = 50,
@@ -21018,7 +20614,7 @@ function CounterMinimal({
21018
20614
  Button,
21019
20615
  {
21020
20616
  variant: "secondary",
21021
- size: sizeStyles9[size].button,
20617
+ size: sizeStyles8[size].button,
21022
20618
  onClick: onDecrement,
21023
20619
  disabled: resolved.decrementDisabled,
21024
20620
  icon: "minus",
@@ -21030,7 +20626,7 @@ function CounterMinimal({
21030
20626
  {
21031
20627
  variant: "h1",
21032
20628
  className: cn(
21033
- sizeStyles9[size].display,
20629
+ sizeStyles8[size].display,
21034
20630
  "font-bold tabular-nums min-w-[3ch] text-center"
21035
20631
  ),
21036
20632
  children: resolved.count
@@ -21040,7 +20636,7 @@ function CounterMinimal({
21040
20636
  Button,
21041
20637
  {
21042
20638
  variant: "secondary",
21043
- size: sizeStyles9[size].button,
20639
+ size: sizeStyles8[size].button,
21044
20640
  onClick: onIncrement,
21045
20641
  disabled: resolved.incrementDisabled,
21046
20642
  icon: "plus",
@@ -21075,7 +20671,7 @@ function CounterStandard({
21075
20671
  {
21076
20672
  variant: "h1",
21077
20673
  className: cn(
21078
- sizeStyles9[size].display,
20674
+ sizeStyles8[size].display,
21079
20675
  "font-bold tabular-nums text-primary-600"
21080
20676
  ),
21081
20677
  children: resolved.count
@@ -21086,7 +20682,7 @@ function CounterStandard({
21086
20682
  Button,
21087
20683
  {
21088
20684
  variant: "secondary",
21089
- size: sizeStyles9[size].button,
20685
+ size: sizeStyles8[size].button,
21090
20686
  onClick: onDecrement,
21091
20687
  disabled: resolved.decrementDisabled,
21092
20688
  icon: "minus"
@@ -21096,7 +20692,7 @@ function CounterStandard({
21096
20692
  Button,
21097
20693
  {
21098
20694
  variant: "primary",
21099
- size: sizeStyles9[size].button,
20695
+ size: sizeStyles8[size].button,
21100
20696
  onClick: onIncrement,
21101
20697
  disabled: resolved.incrementDisabled,
21102
20698
  icon: "plus"
@@ -21142,7 +20738,7 @@ function CounterFull({
21142
20738
  {
21143
20739
  variant: "h1",
21144
20740
  className: cn(
21145
- sizeStyles9[size].display,
20741
+ sizeStyles8[size].display,
21146
20742
  "font-bold tabular-nums text-primary-600"
21147
20743
  ),
21148
20744
  children: resolved.count
@@ -21155,7 +20751,7 @@ function CounterFull({
21155
20751
  Button,
21156
20752
  {
21157
20753
  variant: "secondary",
21158
- size: sizeStyles9[size].button,
20754
+ size: sizeStyles8[size].button,
21159
20755
  onClick: onDecrement,
21160
20756
  disabled: resolved.decrementDisabled,
21161
20757
  icon: "minus",
@@ -21166,7 +20762,7 @@ function CounterFull({
21166
20762
  Button,
21167
20763
  {
21168
20764
  variant: "primary",
21169
- size: sizeStyles9[size].button,
20765
+ size: sizeStyles8[size].button,
21170
20766
  onClick: onIncrement,
21171
20767
  disabled: resolved.incrementDisabled,
21172
20768
  icon: "plus",
@@ -21186,7 +20782,7 @@ function CounterFull({
21186
20782
  )
21187
20783
  ] }) });
21188
20784
  }
21189
- var sizeStyles9, CounterTemplate;
20785
+ var sizeStyles8, CounterTemplate;
21190
20786
  var init_CounterTemplate = __esm({
21191
20787
  "components/core/templates/CounterTemplate.tsx"() {
21192
20788
  init_cn();
@@ -21194,7 +20790,7 @@ var init_CounterTemplate = __esm({
21194
20790
  init_Stack();
21195
20791
  init_Typography();
21196
20792
  init_Button();
21197
- sizeStyles9 = {
20793
+ sizeStyles8 = {
21198
20794
  sm: { display: "text-4xl", button: "sm" },
21199
20795
  md: { display: "text-6xl", button: "md" },
21200
20796
  lg: { display: "text-8xl", button: "lg" }
@@ -21303,7 +20899,7 @@ function CraftingRecipe({
21303
20899
  className
21304
20900
  }) {
21305
20901
  const eventBus = useEventBus();
21306
- const handleCraft = React83.useCallback(() => {
20902
+ const handleCraft = React79.useCallback(() => {
21307
20903
  onCraft?.();
21308
20904
  if (craftEvent) {
21309
20905
  eventBus.emit(craftEvent, { output: output.label });
@@ -21320,7 +20916,7 @@ function CraftingRecipe({
21320
20916
  children: [
21321
20917
  /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap items-center", children: inputs.map((ingredient, index) => {
21322
20918
  const hasSufficient = ingredient.available >= ingredient.required;
21323
- return /* @__PURE__ */ jsxs(React83.Fragment, { children: [
20919
+ return /* @__PURE__ */ jsxs(React79.Fragment, { children: [
21324
20920
  /* @__PURE__ */ jsx(Box, { className: "relative", children: /* @__PURE__ */ jsx(
21325
20921
  ItemSlot,
21326
20922
  {
@@ -21383,8 +20979,8 @@ function DPad({
21383
20979
  }) {
21384
20980
  const eventBus = useEventBus();
21385
20981
  const sizes = sizeMap6[size];
21386
- const [activeDirections, setActiveDirections] = React83.useState(/* @__PURE__ */ new Set());
21387
- const handlePress = React83.useCallback(
20982
+ const [activeDirections, setActiveDirections] = React79.useState(/* @__PURE__ */ new Set());
20983
+ const handlePress = React79.useCallback(
21388
20984
  (direction) => {
21389
20985
  setActiveDirections((prev) => new Set(prev).add(direction));
21390
20986
  if (directionEvent) eventBus.emit(`UI:${directionEvent}`, { direction, pressed: true });
@@ -21392,7 +20988,7 @@ function DPad({
21392
20988
  },
21393
20989
  [directionEvent, eventBus, onDirection]
21394
20990
  );
21395
- const handleRelease = React83.useCallback(
20991
+ const handleRelease = React79.useCallback(
21396
20992
  (direction) => {
21397
20993
  setActiveDirections((prev) => {
21398
20994
  const next = new Set(prev);
@@ -22127,14 +21723,14 @@ function useDataDnd(args) {
22127
21723
  const isZone = Boolean(dragGroup || accepts || sortable);
22128
21724
  const enabled = isZone || Boolean(dndRoot);
22129
21725
  const eventBus = useEventBus();
22130
- const parentRoot = React83__default.useContext(RootCtx);
21726
+ const parentRoot = React79__default.useContext(RootCtx);
22131
21727
  const isRoot = enabled && parentRoot === null;
22132
- const zoneId = React83__default.useId();
21728
+ const zoneId = React79__default.useId();
22133
21729
  const ownGroup = dragGroup ?? accepts ?? zoneId;
22134
- const [optimisticOrders, setOptimisticOrders] = React83__default.useState(() => /* @__PURE__ */ new Map());
22135
- const optimisticOrdersRef = React83__default.useRef(optimisticOrders);
21730
+ const [optimisticOrders, setOptimisticOrders] = React79__default.useState(() => /* @__PURE__ */ new Map());
21731
+ const optimisticOrdersRef = React79__default.useRef(optimisticOrders);
22136
21732
  optimisticOrdersRef.current = optimisticOrders;
22137
- const clearOptimisticOrder = React83__default.useCallback((group) => {
21733
+ const clearOptimisticOrder = React79__default.useCallback((group) => {
22138
21734
  setOptimisticOrders((prev) => {
22139
21735
  if (!prev.has(group)) return prev;
22140
21736
  const next = new Map(prev);
@@ -22159,7 +21755,7 @@ function useDataDnd(args) {
22159
21755
  const raw = it[dndItemIdField];
22160
21756
  return String(raw ?? `__idx_${idx}`);
22161
21757
  }).join("|");
22162
- const itemIds = React83__default.useMemo(
21758
+ const itemIds = React79__default.useMemo(
22163
21759
  () => orderedItems.map((it, idx) => {
22164
21760
  const raw = it[dndItemIdField];
22165
21761
  return raw ?? `__idx_${idx}`;
@@ -22167,7 +21763,7 @@ function useDataDnd(args) {
22167
21763
  [itemIdsSignature]
22168
21764
  );
22169
21765
  const itemsContentSig = items.map((it, idx) => String(it[dndItemIdField] ?? `__${idx}`)).join("|");
22170
- React83__default.useEffect(() => {
21766
+ React79__default.useEffect(() => {
22171
21767
  const root = isRoot ? null : parentRoot;
22172
21768
  if (root) {
22173
21769
  root.clearOptimisticOrder(ownGroup);
@@ -22175,20 +21771,20 @@ function useDataDnd(args) {
22175
21771
  clearOptimisticOrder(ownGroup);
22176
21772
  }
22177
21773
  }, [itemsContentSig, ownGroup]);
22178
- const zonesRef = React83__default.useRef(/* @__PURE__ */ new Map());
22179
- const registerZone = React83__default.useCallback((zoneId2, meta2) => {
21774
+ const zonesRef = React79__default.useRef(/* @__PURE__ */ new Map());
21775
+ const registerZone = React79__default.useCallback((zoneId2, meta2) => {
22180
21776
  zonesRef.current.set(zoneId2, meta2);
22181
21777
  }, []);
22182
- const unregisterZone = React83__default.useCallback((zoneId2) => {
21778
+ const unregisterZone = React79__default.useCallback((zoneId2) => {
22183
21779
  zonesRef.current.delete(zoneId2);
22184
21780
  }, []);
22185
- const [activeDrag, setActiveDrag] = React83__default.useState(null);
22186
- const [overZoneGroup, setOverZoneGroup] = React83__default.useState(null);
22187
- const meta = React83__default.useMemo(
21781
+ const [activeDrag, setActiveDrag] = React79__default.useState(null);
21782
+ const [overZoneGroup, setOverZoneGroup] = React79__default.useState(null);
21783
+ const meta = React79__default.useMemo(
22188
21784
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
22189
21785
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
22190
21786
  );
22191
- React83__default.useEffect(() => {
21787
+ React79__default.useEffect(() => {
22192
21788
  const target = isRoot ? null : parentRoot;
22193
21789
  if (!target) {
22194
21790
  zonesRef.current.set(zoneId, meta);
@@ -22207,7 +21803,7 @@ function useDataDnd(args) {
22207
21803
  }, [parentRoot, isRoot, zoneId, meta]);
22208
21804
  const sensors = useAlmadarDndSensors(true);
22209
21805
  const collisionDetection = almadarDndCollisionDetection;
22210
- const findZoneByItem = React83__default.useCallback(
21806
+ const findZoneByItem = React79__default.useCallback(
22211
21807
  (id) => {
22212
21808
  for (const z of zonesRef.current.values()) {
22213
21809
  if (z.itemIds.includes(id)) return z;
@@ -22216,7 +21812,7 @@ function useDataDnd(args) {
22216
21812
  },
22217
21813
  []
22218
21814
  );
22219
- React83__default.useCallback(
21815
+ React79__default.useCallback(
22220
21816
  (group) => {
22221
21817
  for (const z of zonesRef.current.values()) {
22222
21818
  if (z.group === group) return z;
@@ -22225,7 +21821,7 @@ function useDataDnd(args) {
22225
21821
  },
22226
21822
  []
22227
21823
  );
22228
- const handleDragEnd = React83__default.useCallback(
21824
+ const handleDragEnd = React79__default.useCallback(
22229
21825
  (event) => {
22230
21826
  const { active, over } = event;
22231
21827
  const activeIdStr = String(active.id);
@@ -22316,8 +21912,8 @@ function useDataDnd(args) {
22316
21912
  },
22317
21913
  [eventBus]
22318
21914
  );
22319
- const sortableData = React83__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
22320
- const SortableItem = React83__default.useCallback(
21915
+ const sortableData = React79__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
21916
+ const SortableItem = React79__default.useCallback(
22321
21917
  ({ id, children }) => {
22322
21918
  const {
22323
21919
  attributes,
@@ -22357,7 +21953,7 @@ function useDataDnd(args) {
22357
21953
  id: droppableId,
22358
21954
  data: sortableData
22359
21955
  });
22360
- const ctx = React83__default.useContext(RootCtx);
21956
+ const ctx = React79__default.useContext(RootCtx);
22361
21957
  const activeDrag2 = ctx?.activeDrag ?? null;
22362
21958
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
22363
21959
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -22372,7 +21968,7 @@ function useDataDnd(args) {
22372
21968
  showForeignPlaceholder,
22373
21969
  ctxAvailable: ctx != null
22374
21970
  });
22375
- React83__default.useEffect(() => {
21971
+ React79__default.useEffect(() => {
22376
21972
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
22377
21973
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
22378
21974
  return /* @__PURE__ */ jsx(
@@ -22386,11 +21982,11 @@ function useDataDnd(args) {
22386
21982
  }
22387
21983
  );
22388
21984
  };
22389
- const rootContextValue = React83__default.useMemo(
21985
+ const rootContextValue = React79__default.useMemo(
22390
21986
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
22391
21987
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
22392
21988
  );
22393
- const handleDragStart = React83__default.useCallback((event) => {
21989
+ const handleDragStart = React79__default.useCallback((event) => {
22394
21990
  const sourceZone = findZoneByItem(event.active.id);
22395
21991
  const rect = event.active.rect.current.initial;
22396
21992
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -22409,7 +22005,7 @@ function useDataDnd(args) {
22409
22005
  isRoot
22410
22006
  });
22411
22007
  }, [findZoneByItem, isRoot, zoneId]);
22412
- const handleDragOver = React83__default.useCallback((event) => {
22008
+ const handleDragOver = React79__default.useCallback((event) => {
22413
22009
  const { active, over } = event;
22414
22010
  const overData = over?.data?.current;
22415
22011
  const overGroup = overData?.dndGroup ?? null;
@@ -22479,7 +22075,7 @@ function useDataDnd(args) {
22479
22075
  return next;
22480
22076
  });
22481
22077
  }, []);
22482
- const handleDragCancel = React83__default.useCallback((event) => {
22078
+ const handleDragCancel = React79__default.useCallback((event) => {
22483
22079
  setActiveDrag(null);
22484
22080
  setOverZoneGroup(null);
22485
22081
  dndLog.warn("dragCancel", {
@@ -22487,12 +22083,12 @@ function useDataDnd(args) {
22487
22083
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
22488
22084
  });
22489
22085
  }, []);
22490
- const handleDragEndWithCleanup = React83__default.useCallback((event) => {
22086
+ const handleDragEndWithCleanup = React79__default.useCallback((event) => {
22491
22087
  handleDragEnd(event);
22492
22088
  setActiveDrag(null);
22493
22089
  setOverZoneGroup(null);
22494
22090
  }, [handleDragEnd]);
22495
- const wrapContainer = React83__default.useCallback(
22091
+ const wrapContainer = React79__default.useCallback(
22496
22092
  (children) => {
22497
22093
  if (!enabled) return children;
22498
22094
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -22546,7 +22142,7 @@ var init_useDataDnd = __esm({
22546
22142
  init_useAlmadarDndCollision();
22547
22143
  init_Box();
22548
22144
  dndLog = createLogger("almadar:ui:dnd");
22549
- RootCtx = React83__default.createContext(null);
22145
+ RootCtx = React79__default.createContext(null);
22550
22146
  }
22551
22147
  });
22552
22148
  function fieldLabel2(key) {
@@ -23066,7 +22662,7 @@ function DataList({
23066
22662
  }) {
23067
22663
  const eventBus = useEventBus();
23068
22664
  const { t } = useTranslate();
23069
- const [visibleCount, setVisibleCount] = React83__default.useState(pageSize || Infinity);
22665
+ const [visibleCount, setVisibleCount] = React79__default.useState(pageSize || Infinity);
23070
22666
  const fieldDefs = fields ?? columns ?? [];
23071
22667
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
23072
22668
  const dnd = useDataDnd({
@@ -23085,7 +22681,7 @@ function DataList({
23085
22681
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
23086
22682
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
23087
22683
  const hasRenderProp = typeof children === "function";
23088
- React83__default.useEffect(() => {
22684
+ React79__default.useEffect(() => {
23089
22685
  const renderItemTypeOf = typeof schemaRenderItem;
23090
22686
  const childrenTypeOf = typeof children;
23091
22687
  if (data.length > 0 && !hasRenderProp) {
@@ -23190,7 +22786,7 @@ function DataList({
23190
22786
  const items2 = data.map((item) => item);
23191
22787
  const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
23192
22788
  const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
23193
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
22789
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React79__default.Fragment, { children: [
23194
22790
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
23195
22791
  group.items.map((itemData, index) => {
23196
22792
  const id = itemData.id || `${gi}-${index}`;
@@ -23338,7 +22934,7 @@ function DataList({
23338
22934
  className
23339
22935
  ),
23340
22936
  children: [
23341
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
22937
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React79__default.Fragment, { children: [
23342
22938
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
23343
22939
  group.items.map(
23344
22940
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -23401,6 +22997,422 @@ var init_DataList = __esm({
23401
22997
  DataList.displayName = "DataList";
23402
22998
  }
23403
22999
  });
23000
+ function isTraitConfigObject(v) {
23001
+ return v !== null && typeof v === "object" && !Array.isArray(v);
23002
+ }
23003
+ function LeafControl({
23004
+ value,
23005
+ onChange
23006
+ }) {
23007
+ if (typeof value === "boolean") {
23008
+ return /* @__PURE__ */ jsx(Switch, { checked: value, onChange: (c) => onChange(c) });
23009
+ }
23010
+ if (typeof value === "number") {
23011
+ const [draft2, setDraft2] = React79__default.useState(String(value));
23012
+ React79__default.useEffect(() => setDraft2(String(value)), [value]);
23013
+ const commit2 = () => {
23014
+ const n = draft2.trim() === "" ? 0 : Number(draft2);
23015
+ onChange(Number.isNaN(n) ? 0 : n);
23016
+ };
23017
+ return /* @__PURE__ */ jsx(
23018
+ Input,
23019
+ {
23020
+ inputType: "number",
23021
+ value: draft2,
23022
+ onChange: (e) => setDraft2(e.target.value),
23023
+ onBlur: commit2,
23024
+ onKeyDown: (e) => {
23025
+ if (e.key === "Enter") commit2();
23026
+ }
23027
+ }
23028
+ );
23029
+ }
23030
+ if (isTraitConfigObject(value)) {
23031
+ const [draft2, setDraft2] = React79__default.useState(JSON.stringify(value));
23032
+ React79__default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
23033
+ const commit2 = () => {
23034
+ try {
23035
+ const parsed = JSON.parse(draft2);
23036
+ onChange(parsed);
23037
+ } catch {
23038
+ }
23039
+ };
23040
+ return /* @__PURE__ */ jsx(
23041
+ Input,
23042
+ {
23043
+ inputType: "text",
23044
+ value: draft2,
23045
+ onChange: (e) => setDraft2(e.target.value),
23046
+ onBlur: commit2,
23047
+ onKeyDown: (e) => {
23048
+ if (e.key === "Enter") commit2();
23049
+ }
23050
+ }
23051
+ );
23052
+ }
23053
+ if (Array.isArray(value)) {
23054
+ const [draft2, setDraft2] = React79__default.useState(JSON.stringify(value));
23055
+ React79__default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
23056
+ const commit2 = () => {
23057
+ try {
23058
+ const parsed = JSON.parse(draft2);
23059
+ onChange(parsed);
23060
+ } catch {
23061
+ }
23062
+ };
23063
+ return /* @__PURE__ */ jsx(
23064
+ Input,
23065
+ {
23066
+ inputType: "text",
23067
+ value: draft2,
23068
+ onChange: (e) => setDraft2(e.target.value),
23069
+ onBlur: commit2,
23070
+ onKeyDown: (e) => {
23071
+ if (e.key === "Enter") commit2();
23072
+ }
23073
+ }
23074
+ );
23075
+ }
23076
+ const strVal = value === null ? "" : String(value);
23077
+ const [draft, setDraft] = React79__default.useState(strVal);
23078
+ React79__default.useEffect(() => setDraft(value === null ? "" : String(value)), [value]);
23079
+ const commit = () => {
23080
+ onChange(draft);
23081
+ };
23082
+ return /* @__PURE__ */ jsx(
23083
+ Input,
23084
+ {
23085
+ inputType: "text",
23086
+ value: draft,
23087
+ onChange: (e) => setDraft(e.target.value),
23088
+ onBlur: commit,
23089
+ onKeyDown: (e) => {
23090
+ if (e.key === "Enter") commit();
23091
+ }
23092
+ }
23093
+ );
23094
+ }
23095
+ function cloneElement(template) {
23096
+ if (isTraitConfigObject(template)) {
23097
+ const blank = {};
23098
+ for (const k of Object.keys(template)) blank[k] = null;
23099
+ return blank;
23100
+ }
23101
+ if (Array.isArray(template)) return [];
23102
+ if (typeof template === "boolean") return false;
23103
+ if (typeof template === "number") return 0;
23104
+ return "";
23105
+ }
23106
+ var ArrayEditor;
23107
+ var init_ArrayEditor = __esm({
23108
+ "components/core/molecules/ArrayEditor.tsx"() {
23109
+ "use client";
23110
+ init_Stack();
23111
+ init_Button();
23112
+ init_Switch();
23113
+ init_Input();
23114
+ init_cn();
23115
+ ArrayEditor = ({ value, onChange, className }) => {
23116
+ const arr = value;
23117
+ const update = (idx, next) => {
23118
+ const copy = [...arr];
23119
+ copy[idx] = next;
23120
+ onChange(copy);
23121
+ };
23122
+ const remove = (idx) => {
23123
+ onChange(arr.filter((_, i) => i !== idx));
23124
+ };
23125
+ const add = () => {
23126
+ const template = arr.length > 0 ? arr[0] : "";
23127
+ onChange([...arr, cloneElement(template)]);
23128
+ };
23129
+ return /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("w-full", className), children: [
23130
+ arr.map((elem, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
23131
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(LeafControl, { value: elem, onChange: (next) => update(idx, next) }) }),
23132
+ /* @__PURE__ */ jsx(
23133
+ Button,
23134
+ {
23135
+ variant: "ghost",
23136
+ size: "sm",
23137
+ icon: "trash-2",
23138
+ onClick: () => remove(idx),
23139
+ "aria-label": "Remove item"
23140
+ }
23141
+ )
23142
+ ] }, idx)),
23143
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", icon: "plus", label: "Add item", onClick: add })
23144
+ ] });
23145
+ };
23146
+ }
23147
+ });
23148
+ function isTraitConfigObject2(v) {
23149
+ return v !== null && typeof v === "object" && !Array.isArray(v);
23150
+ }
23151
+ function ScalarControl({
23152
+ fieldKey,
23153
+ value,
23154
+ onFieldChange
23155
+ }) {
23156
+ if (typeof value === "boolean") {
23157
+ return /* @__PURE__ */ jsx(Switch, { checked: value, onChange: (c) => onFieldChange(fieldKey, c) });
23158
+ }
23159
+ if (typeof value === "number") {
23160
+ const [draft2, setDraft2] = React79__default.useState(String(value));
23161
+ React79__default.useEffect(() => setDraft2(String(value)), [value]);
23162
+ const commit2 = () => {
23163
+ const n = draft2.trim() === "" ? 0 : Number(draft2);
23164
+ onFieldChange(fieldKey, Number.isNaN(n) ? 0 : n);
23165
+ };
23166
+ return /* @__PURE__ */ jsx(
23167
+ Input,
23168
+ {
23169
+ inputType: "number",
23170
+ value: draft2,
23171
+ onChange: (e) => setDraft2(e.target.value),
23172
+ onBlur: commit2,
23173
+ onKeyDown: (e) => {
23174
+ if (e.key === "Enter") commit2();
23175
+ }
23176
+ }
23177
+ );
23178
+ }
23179
+ if (isTraitConfigObject2(value)) {
23180
+ const [draft2, setDraft2] = React79__default.useState(JSON.stringify(value));
23181
+ React79__default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
23182
+ const commit2 = () => {
23183
+ try {
23184
+ onFieldChange(fieldKey, JSON.parse(draft2));
23185
+ } catch {
23186
+ }
23187
+ };
23188
+ return /* @__PURE__ */ jsx(
23189
+ Input,
23190
+ {
23191
+ inputType: "text",
23192
+ value: draft2,
23193
+ onChange: (e) => setDraft2(e.target.value),
23194
+ onBlur: commit2,
23195
+ onKeyDown: (e) => {
23196
+ if (e.key === "Enter") commit2();
23197
+ }
23198
+ }
23199
+ );
23200
+ }
23201
+ if (Array.isArray(value)) {
23202
+ const [draft2, setDraft2] = React79__default.useState(JSON.stringify(value));
23203
+ React79__default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
23204
+ const commit2 = () => {
23205
+ try {
23206
+ onFieldChange(fieldKey, JSON.parse(draft2));
23207
+ } catch {
23208
+ }
23209
+ };
23210
+ return /* @__PURE__ */ jsx(
23211
+ Input,
23212
+ {
23213
+ inputType: "text",
23214
+ value: draft2,
23215
+ onChange: (e) => setDraft2(e.target.value),
23216
+ onBlur: commit2,
23217
+ onKeyDown: (e) => {
23218
+ if (e.key === "Enter") commit2();
23219
+ }
23220
+ }
23221
+ );
23222
+ }
23223
+ const [draft, setDraft] = React79__default.useState(value === null ? "" : String(value));
23224
+ React79__default.useEffect(() => setDraft(value === null ? "" : String(value)), [value]);
23225
+ const commit = () => {
23226
+ onFieldChange(fieldKey, draft);
23227
+ };
23228
+ return /* @__PURE__ */ jsx(
23229
+ Input,
23230
+ {
23231
+ inputType: "text",
23232
+ value: draft,
23233
+ onChange: (e) => setDraft(e.target.value),
23234
+ onBlur: commit,
23235
+ onKeyDown: (e) => {
23236
+ if (e.key === "Enter") commit();
23237
+ }
23238
+ }
23239
+ );
23240
+ }
23241
+ var ObjectEditor;
23242
+ var init_ObjectEditor = __esm({
23243
+ "components/core/molecules/ObjectEditor.tsx"() {
23244
+ "use client";
23245
+ init_Stack();
23246
+ init_Typography();
23247
+ init_Switch();
23248
+ init_Input();
23249
+ init_cn();
23250
+ ObjectEditor = ({ value, onChange, className }) => {
23251
+ const entries = Object.entries(value);
23252
+ const handleFieldChange = (k, next) => {
23253
+ onChange({ ...value, [k]: next });
23254
+ };
23255
+ if (entries.length === 0) {
23256
+ return /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: "Empty object" });
23257
+ }
23258
+ return /* @__PURE__ */ jsx(VStack, { gap: "xs", className: cn("w-full", className), children: entries.map(([k, v]) => /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", children: [
23259
+ /* @__PURE__ */ jsx("span", { className: "w-24 shrink-0 truncate", title: k, children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: k }) }),
23260
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(ScalarControl, { fieldKey: k, value: v, onFieldChange: handleFieldChange }) })
23261
+ ] }, k)) });
23262
+ };
23263
+ }
23264
+ });
23265
+ function isTraitConfigObject3(v) {
23266
+ return v !== null && typeof v === "object" && !Array.isArray(v);
23267
+ }
23268
+ function ValueControl({
23269
+ value,
23270
+ onChange
23271
+ }) {
23272
+ if (typeof value === "boolean") {
23273
+ return /* @__PURE__ */ jsx(Switch, { checked: value, onChange: (c) => onChange(c) });
23274
+ }
23275
+ if (typeof value === "number") {
23276
+ const [draft2, setDraft2] = React79__default.useState(String(value));
23277
+ React79__default.useEffect(() => setDraft2(String(value)), [value]);
23278
+ const commit2 = () => {
23279
+ const n = draft2.trim() === "" ? 0 : Number(draft2);
23280
+ onChange(Number.isNaN(n) ? 0 : n);
23281
+ };
23282
+ return /* @__PURE__ */ jsx(
23283
+ Input,
23284
+ {
23285
+ inputType: "number",
23286
+ value: draft2,
23287
+ onChange: (e) => setDraft2(e.target.value),
23288
+ onBlur: commit2,
23289
+ onKeyDown: (e) => {
23290
+ if (e.key === "Enter") commit2();
23291
+ }
23292
+ }
23293
+ );
23294
+ }
23295
+ if (isTraitConfigObject3(value) || Array.isArray(value)) {
23296
+ const [draft2, setDraft2] = React79__default.useState(JSON.stringify(value));
23297
+ React79__default.useEffect(() => setDraft2(JSON.stringify(value)), [value]);
23298
+ const commit2 = () => {
23299
+ try {
23300
+ onChange(JSON.parse(draft2));
23301
+ } catch {
23302
+ }
23303
+ };
23304
+ return /* @__PURE__ */ jsx(
23305
+ Input,
23306
+ {
23307
+ inputType: "text",
23308
+ value: draft2,
23309
+ onChange: (e) => setDraft2(e.target.value),
23310
+ onBlur: commit2,
23311
+ onKeyDown: (e) => {
23312
+ if (e.key === "Enter") commit2();
23313
+ }
23314
+ }
23315
+ );
23316
+ }
23317
+ const [draft, setDraft] = React79__default.useState(value === null ? "" : String(value));
23318
+ React79__default.useEffect(() => setDraft(value === null ? "" : String(value)), [value]);
23319
+ const commit = () => {
23320
+ onChange(draft);
23321
+ };
23322
+ return /* @__PURE__ */ jsx(
23323
+ Input,
23324
+ {
23325
+ inputType: "text",
23326
+ value: draft,
23327
+ onChange: (e) => setDraft(e.target.value),
23328
+ onBlur: commit,
23329
+ onKeyDown: (e) => {
23330
+ if (e.key === "Enter") commit();
23331
+ }
23332
+ }
23333
+ );
23334
+ }
23335
+ function KeyInput({
23336
+ currentKey,
23337
+ onRename
23338
+ }) {
23339
+ const [draft, setDraft] = React79__default.useState(currentKey);
23340
+ React79__default.useEffect(() => setDraft(currentKey), [currentKey]);
23341
+ const commit = () => {
23342
+ const trimmed = draft.trim();
23343
+ if (trimmed !== "" && trimmed !== currentKey) onRename(trimmed);
23344
+ else setDraft(currentKey);
23345
+ };
23346
+ return /* @__PURE__ */ jsx(
23347
+ Input,
23348
+ {
23349
+ inputType: "text",
23350
+ value: draft,
23351
+ onChange: (e) => setDraft(e.target.value),
23352
+ onBlur: commit,
23353
+ onKeyDown: (e) => {
23354
+ if (e.key === "Enter") commit();
23355
+ },
23356
+ className: "w-24 shrink-0 font-mono text-xs",
23357
+ placeholder: "key"
23358
+ }
23359
+ );
23360
+ }
23361
+ var MapEditor;
23362
+ var init_MapEditor = __esm({
23363
+ "components/core/molecules/MapEditor.tsx"() {
23364
+ "use client";
23365
+ init_Stack();
23366
+ init_Button();
23367
+ init_Input();
23368
+ init_Switch();
23369
+ init_cn();
23370
+ MapEditor = ({ value, onChange, className }) => {
23371
+ const entries = Object.entries(value);
23372
+ const updateKey = (oldKey, newKey) => {
23373
+ const next = {};
23374
+ for (const [k, v] of Object.entries(value)) {
23375
+ next[k === oldKey ? newKey : k] = v;
23376
+ }
23377
+ onChange(next);
23378
+ };
23379
+ const updateValue = (k, next) => {
23380
+ onChange({ ...value, [k]: next });
23381
+ };
23382
+ const remove = (k) => {
23383
+ const next = { ...value };
23384
+ delete next[k];
23385
+ onChange(next);
23386
+ };
23387
+ const add = () => {
23388
+ let key = "key";
23389
+ let i = 1;
23390
+ while (key in value) {
23391
+ key = `key${i}`;
23392
+ i++;
23393
+ }
23394
+ onChange({ ...value, [key]: "" });
23395
+ };
23396
+ return /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("w-full", className), children: [
23397
+ entries.map(([k, v]) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
23398
+ /* @__PURE__ */ jsx(KeyInput, { currentKey: k, onRename: (newKey) => updateKey(k, newKey) }),
23399
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(ValueControl, { value: v, onChange: (next) => updateValue(k, next) }) }),
23400
+ /* @__PURE__ */ jsx(
23401
+ Button,
23402
+ {
23403
+ variant: "ghost",
23404
+ size: "sm",
23405
+ icon: "trash-2",
23406
+ onClick: () => remove(k),
23407
+ "aria-label": "Remove entry"
23408
+ }
23409
+ )
23410
+ ] }, k)),
23411
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", icon: "plus", label: "Add entry", onClick: add })
23412
+ ] });
23413
+ };
23414
+ }
23415
+ });
23404
23416
  function fileIcon(name) {
23405
23417
  const ext = name.split(".").pop()?.toLowerCase() ?? "";
23406
23418
  switch (ext) {
@@ -24962,7 +24974,7 @@ var init_WizardProgress = __esm({
24962
24974
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
24963
24975
  const isActive = index === currentStep;
24964
24976
  const isCompleted = index < currentStep;
24965
- return /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
24977
+ return /* @__PURE__ */ jsxs(React79__default.Fragment, { children: [
24966
24978
  /* @__PURE__ */ jsx(
24967
24979
  "button",
24968
24980
  {
@@ -25479,8 +25491,9 @@ var init_FormSectionHeader = __esm({
25479
25491
  Box,
25480
25492
  {
25481
25493
  className: cn(
25482
- "px-4 py-3 bg-muted rounded-t-lg border-b-2 border-border border-l-4 border-l-primary",
25483
- isClickable && "cursor-pointer hover:bg-[var(--color-surface-hover)] transition-colors",
25494
+ "px-5 py-4 bg-muted/60 rounded-lg",
25495
+ "border border-border border-l-4 border-l-primary",
25496
+ isClickable && "cursor-pointer hover:bg-muted transition-colors",
25484
25497
  className
25485
25498
  ),
25486
25499
  onClick: isClickable ? onToggle : void 0,
@@ -25491,7 +25504,7 @@ var init_FormSectionHeader = __esm({
25491
25504
  {
25492
25505
  name: icon,
25493
25506
  size: "md",
25494
- className: "text-primary"
25507
+ className: "text-primary shrink-0"
25495
25508
  }
25496
25509
  ),
25497
25510
  statusIcon && /* @__PURE__ */ jsx(
@@ -25499,12 +25512,15 @@ var init_FormSectionHeader = __esm({
25499
25512
  {
25500
25513
  name: statusIcon,
25501
25514
  size: "md",
25502
- className: hasErrors ? "text-error" : "text-success"
25515
+ className: cn(
25516
+ "shrink-0",
25517
+ hasErrors ? "text-error" : "text-success"
25518
+ )
25503
25519
  }
25504
25520
  ),
25505
25521
  /* @__PURE__ */ jsxs(Box, { className: "space-y-0.5", children: [
25506
- /* @__PURE__ */ jsx(Typography, { variant: "subheading", weight: "semibold", children: title }),
25507
- subtitle && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: subtitle })
25522
+ /* @__PURE__ */ jsx(Typography, { variant: "subheading", weight: "semibold", className: "text-foreground", children: title }),
25523
+ subtitle && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", className: "leading-snug", children: subtitle })
25508
25524
  ] })
25509
25525
  ] }),
25510
25526
  /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", children: [
@@ -25513,9 +25529,9 @@ var init_FormSectionHeader = __esm({
25513
25529
  Icon,
25514
25530
  {
25515
25531
  name: "chevron-down",
25516
- size: "md",
25532
+ size: "sm",
25517
25533
  className: cn(
25518
- "text-muted-foreground transition-transform",
25534
+ "text-muted-foreground transition-transform duration-200 shrink-0",
25519
25535
  isCollapsed && "-rotate-90"
25520
25536
  )
25521
25537
  }
@@ -25573,6 +25589,259 @@ var init_FlipCard = __esm({
25573
25589
  FlipCard.displayName = "FlipCard";
25574
25590
  }
25575
25591
  });
25592
+ var ALL_CATEGORY, GridPicker;
25593
+ var init_GridPicker = __esm({
25594
+ "components/core/molecules/GridPicker.tsx"() {
25595
+ "use client";
25596
+ init_cn();
25597
+ init_Input();
25598
+ init_Badge();
25599
+ init_Stack();
25600
+ ALL_CATEGORY = "__all__";
25601
+ GridPicker = ({
25602
+ items,
25603
+ value,
25604
+ onChange,
25605
+ categories,
25606
+ searchPlaceholder,
25607
+ renderThumbnail,
25608
+ cellSize = 32,
25609
+ className
25610
+ }) => {
25611
+ const [search, setSearch] = useState("");
25612
+ const [activeCategory, setActiveCategory] = useState(ALL_CATEGORY);
25613
+ const gridRef = useRef(null);
25614
+ const categoryChips = useMemo(() => {
25615
+ if (categories !== void 0) return categories;
25616
+ const seen = [];
25617
+ for (const item of items) {
25618
+ if (!seen.includes(item.category)) seen.push(item.category);
25619
+ }
25620
+ return seen;
25621
+ }, [categories, items]);
25622
+ const filtered = useMemo(() => {
25623
+ const needle = search.trim().toLowerCase();
25624
+ return items.filter((item) => {
25625
+ const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
25626
+ const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle);
25627
+ return matchesCategory && matchesSearch;
25628
+ });
25629
+ }, [items, search, activeCategory]);
25630
+ const select = useCallback(
25631
+ (item) => {
25632
+ onChange(item.id);
25633
+ },
25634
+ [onChange]
25635
+ );
25636
+ const handleKeyDown = useCallback(
25637
+ (e, index) => {
25638
+ const cells = gridRef.current?.querySelectorAll(
25639
+ "[data-gridpicker-cell]"
25640
+ );
25641
+ if (cells === void 0 || cells.length === 0) return;
25642
+ const columns = (() => {
25643
+ const grid = gridRef.current;
25644
+ if (grid === null) return 1;
25645
+ const style = window.getComputedStyle(grid);
25646
+ const cols = style.gridTemplateColumns.split(" ").filter(Boolean).length;
25647
+ return cols > 0 ? cols : 1;
25648
+ })();
25649
+ let next = -1;
25650
+ if (e.key === "ArrowRight") next = index + 1;
25651
+ else if (e.key === "ArrowLeft") next = index - 1;
25652
+ else if (e.key === "ArrowDown") next = index + columns;
25653
+ else if (e.key === "ArrowUp") next = index - columns;
25654
+ else if (e.key === "Enter" || e.key === " ") {
25655
+ e.preventDefault();
25656
+ select(filtered[index]);
25657
+ return;
25658
+ } else {
25659
+ return;
25660
+ }
25661
+ e.preventDefault();
25662
+ if (next >= 0 && next < cells.length) {
25663
+ cells[next].focus();
25664
+ }
25665
+ },
25666
+ [filtered, select]
25667
+ );
25668
+ return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn("w-full", className), children: [
25669
+ /* @__PURE__ */ jsx(
25670
+ Input,
25671
+ {
25672
+ type: "search",
25673
+ icon: "search",
25674
+ value: search,
25675
+ placeholder: searchPlaceholder,
25676
+ clearable: true,
25677
+ onClear: () => setSearch(""),
25678
+ onChange: (e) => setSearch(e.target.value)
25679
+ }
25680
+ ),
25681
+ categoryChips.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", wrap: true, children: [
25682
+ /* @__PURE__ */ jsx(
25683
+ Badge,
25684
+ {
25685
+ variant: activeCategory === ALL_CATEGORY ? "primary" : "neutral",
25686
+ size: "sm",
25687
+ role: "button",
25688
+ tabIndex: 0,
25689
+ "aria-pressed": activeCategory === ALL_CATEGORY,
25690
+ className: "cursor-pointer",
25691
+ onClick: () => setActiveCategory(ALL_CATEGORY),
25692
+ onKeyDown: (e) => {
25693
+ if (e.key === "Enter" || e.key === " ") {
25694
+ e.preventDefault();
25695
+ setActiveCategory(ALL_CATEGORY);
25696
+ }
25697
+ },
25698
+ children: "All"
25699
+ }
25700
+ ),
25701
+ categoryChips.map((category) => /* @__PURE__ */ jsx(
25702
+ Badge,
25703
+ {
25704
+ variant: activeCategory === category ? "primary" : "neutral",
25705
+ size: "sm",
25706
+ role: "button",
25707
+ tabIndex: 0,
25708
+ "aria-pressed": activeCategory === category,
25709
+ className: "cursor-pointer",
25710
+ onClick: () => setActiveCategory(category),
25711
+ onKeyDown: (e) => {
25712
+ if (e.key === "Enter" || e.key === " ") {
25713
+ e.preventDefault();
25714
+ setActiveCategory(category);
25715
+ }
25716
+ },
25717
+ children: category
25718
+ },
25719
+ category
25720
+ ))
25721
+ ] }),
25722
+ /* @__PURE__ */ jsx(
25723
+ "div",
25724
+ {
25725
+ ref: gridRef,
25726
+ role: "listbox",
25727
+ className: "grid gap-1 overflow-y-auto max-h-64 p-1",
25728
+ style: {
25729
+ gridTemplateColumns: `repeat(auto-fill, minmax(${cellSize}px, 1fr))`
25730
+ },
25731
+ children: filtered.map((item, index) => {
25732
+ const selected = item.id === value;
25733
+ return /* @__PURE__ */ jsx(
25734
+ "button",
25735
+ {
25736
+ type: "button",
25737
+ role: "option",
25738
+ "aria-selected": selected,
25739
+ "aria-label": item.label,
25740
+ title: item.label,
25741
+ "data-gridpicker-cell": true,
25742
+ tabIndex: selected || value === void 0 && index === 0 ? 0 : -1,
25743
+ onClick: () => select(item),
25744
+ onKeyDown: (e) => handleKeyDown(e, index),
25745
+ className: cn(
25746
+ "flex items-center justify-center rounded-sm",
25747
+ "transition-colors hover:bg-muted",
25748
+ "focus:outline-none focus:ring-1 focus:ring-ring",
25749
+ selected && "bg-primary/10 ring-1 ring-primary"
25750
+ ),
25751
+ style: { width: cellSize, height: cellSize },
25752
+ children: renderThumbnail(item)
25753
+ },
25754
+ item.id
25755
+ );
25756
+ })
25757
+ }
25758
+ )
25759
+ ] });
25760
+ };
25761
+ GridPicker.displayName = "GridPicker";
25762
+ }
25763
+ });
25764
+ function iconForKind(kind) {
25765
+ if (kind === "audio") return "music";
25766
+ if (kind === "model") return "box";
25767
+ return "file";
25768
+ }
25769
+ var THUMB_PX, IMAGE_KINDS, AssetPicker;
25770
+ var init_AssetPicker = __esm({
25771
+ "components/core/molecules/AssetPicker.tsx"() {
25772
+ "use client";
25773
+ init_GridPicker();
25774
+ init_Icon();
25775
+ THUMB_PX = 32;
25776
+ IMAGE_KINDS = /* @__PURE__ */ new Set([
25777
+ "image",
25778
+ "spritesheet",
25779
+ "scene",
25780
+ "portrait"
25781
+ ]);
25782
+ AssetPicker = ({
25783
+ assets,
25784
+ value,
25785
+ onChange,
25786
+ className
25787
+ }) => {
25788
+ const byUrl = useMemo(() => {
25789
+ const map = /* @__PURE__ */ new Map();
25790
+ for (const entry of assets) map.set(entry.url, entry);
25791
+ return map;
25792
+ }, [assets]);
25793
+ const items = useMemo(
25794
+ () => assets.map((entry) => ({
25795
+ id: entry.url,
25796
+ label: entry.name,
25797
+ category: entry.category
25798
+ })),
25799
+ [assets]
25800
+ );
25801
+ const categories = useMemo(() => {
25802
+ const seen = [];
25803
+ for (const entry of assets) {
25804
+ if (!seen.includes(entry.category)) seen.push(entry.category);
25805
+ }
25806
+ return seen;
25807
+ }, [assets]);
25808
+ const renderThumbnail = useCallback(
25809
+ (item) => {
25810
+ const entry = byUrl.get(item.id);
25811
+ if (entry === void 0) return null;
25812
+ if (IMAGE_KINDS.has(entry.kind)) {
25813
+ return /* @__PURE__ */ jsx(
25814
+ "img",
25815
+ {
25816
+ src: entry.thumbnailUrl ?? entry.url,
25817
+ alt: entry.name,
25818
+ loading: "lazy",
25819
+ width: THUMB_PX,
25820
+ height: THUMB_PX,
25821
+ style: { width: THUMB_PX, height: THUMB_PX, objectFit: "cover" }
25822
+ }
25823
+ );
25824
+ }
25825
+ return /* @__PURE__ */ jsx(Icon, { name: iconForKind(entry.kind), size: "sm" });
25826
+ },
25827
+ [byUrl]
25828
+ );
25829
+ return /* @__PURE__ */ jsx(
25830
+ GridPicker,
25831
+ {
25832
+ items,
25833
+ value,
25834
+ onChange,
25835
+ categories,
25836
+ renderThumbnail,
25837
+ cellSize: THUMB_PX,
25838
+ className
25839
+ }
25840
+ );
25841
+ };
25842
+ AssetPicker.displayName = "AssetPicker";
25843
+ }
25844
+ });
25576
25845
  function pascalToKebab(name) {
25577
25846
  return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
25578
25847
  }
@@ -26053,9 +26322,9 @@ function ScoreDisplay({
26053
26322
  ...rest
26054
26323
  }) {
26055
26324
  const resolvedValue = typeof value === "number" && !Number.isNaN(value) ? value : typeof rest.score === "number" && !Number.isNaN(rest.score) ? rest.score : 0;
26056
- const [displayValue, setDisplayValue] = React83.useState(resolvedValue);
26057
- const [isAnimating, setIsAnimating] = React83.useState(false);
26058
- React83.useEffect(() => {
26325
+ const [displayValue, setDisplayValue] = React79.useState(resolvedValue);
26326
+ const [isAnimating, setIsAnimating] = React79.useState(false);
26327
+ React79.useEffect(() => {
26059
26328
  if (!animated || displayValue === resolvedValue) {
26060
26329
  setDisplayValue(resolvedValue);
26061
26330
  return;
@@ -26202,7 +26471,7 @@ function InventoryGrid({
26202
26471
  const eventBus = useEventBus();
26203
26472
  const slotCount = totalSlots ?? items.length;
26204
26473
  const emptySlotCount = Math.max(0, slotCount - items.length);
26205
- const handleSelect = React83.useCallback(
26474
+ const handleSelect = React79.useCallback(
26206
26475
  (id) => {
26207
26476
  onSelect?.(id);
26208
26477
  if (selectEvent) {
@@ -26488,31 +26757,31 @@ function GameCanvas2D({
26488
26757
  assetBaseUrl = "",
26489
26758
  className
26490
26759
  }) {
26491
- const canvasRef = React83.useRef(null);
26492
- const rafRef = React83.useRef(0);
26493
- const frameRef = React83.useRef(0);
26494
- const lastTimeRef = React83.useRef(0);
26495
- const imageCache = React83.useRef(/* @__PURE__ */ new Map());
26760
+ const canvasRef = React79.useRef(null);
26761
+ const rafRef = React79.useRef(0);
26762
+ const frameRef = React79.useRef(0);
26763
+ const lastTimeRef = React79.useRef(0);
26764
+ const imageCache = React79.useRef(/* @__PURE__ */ new Map());
26496
26765
  const emit = useEmitEvent();
26497
- const onDrawRef = React83.useRef(onDraw);
26766
+ const onDrawRef = React79.useRef(onDraw);
26498
26767
  onDrawRef.current = onDraw;
26499
- const onTickRef = React83.useRef(onTick);
26768
+ const onTickRef = React79.useRef(onTick);
26500
26769
  onTickRef.current = onTick;
26501
- const tickEventRef = React83.useRef(tickEvent);
26770
+ const tickEventRef = React79.useRef(tickEvent);
26502
26771
  tickEventRef.current = tickEvent;
26503
- const drawEventRef = React83.useRef(drawEvent);
26772
+ const drawEventRef = React79.useRef(drawEvent);
26504
26773
  drawEventRef.current = drawEvent;
26505
- const emitRef = React83.useRef(emit);
26774
+ const emitRef = React79.useRef(emit);
26506
26775
  emitRef.current = emit;
26507
- const assetBaseUrlRef = React83.useRef(assetBaseUrl);
26776
+ const assetBaseUrlRef = React79.useRef(assetBaseUrl);
26508
26777
  assetBaseUrlRef.current = assetBaseUrl;
26509
- const backgroundImageRef = React83.useRef(backgroundImage);
26778
+ const backgroundImageRef = React79.useRef(backgroundImage);
26510
26779
  backgroundImageRef.current = backgroundImage;
26511
- const widthRef = React83.useRef(width);
26780
+ const widthRef = React79.useRef(width);
26512
26781
  widthRef.current = width;
26513
- const heightRef = React83.useRef(height);
26782
+ const heightRef = React79.useRef(height);
26514
26783
  heightRef.current = height;
26515
- const loadImage = React83.useCallback((url) => {
26784
+ const loadImage = React79.useCallback((url) => {
26516
26785
  const fullUrl = url.startsWith("http") ? url : `${assetBaseUrlRef.current}${url}`;
26517
26786
  const cached = imageCache.current.get(fullUrl);
26518
26787
  if (cached?.complete && cached.naturalWidth > 0) return cached;
@@ -26524,7 +26793,7 @@ function GameCanvas2D({
26524
26793
  }
26525
26794
  return null;
26526
26795
  }, []);
26527
- React83.useEffect(() => {
26796
+ React79.useEffect(() => {
26528
26797
  const canvas = canvasRef.current;
26529
26798
  if (!canvas) return;
26530
26799
  const ctx = canvas.getContext("2d");
@@ -26879,7 +27148,7 @@ function TurnPanel({
26879
27148
  className
26880
27149
  }) {
26881
27150
  const eventBus = useEventBus();
26882
- const handleAction = React83.useCallback(
27151
+ const handleAction = React79.useCallback(
26883
27152
  (event) => {
26884
27153
  if (event) {
26885
27154
  eventBus.emit(event, { turn: currentTurn, phase, activeTeam });
@@ -27025,7 +27294,7 @@ function UnitCommandBar({
27025
27294
  className
27026
27295
  }) {
27027
27296
  const eventBus = useEventBus();
27028
- const handleCommand = React83.useCallback(
27297
+ const handleCommand = React79.useCallback(
27029
27298
  (event) => {
27030
27299
  if (event) {
27031
27300
  eventBus.emit(event, { unitId: selectedUnitId });
@@ -27510,7 +27779,7 @@ function GameMenu({
27510
27779
  } catch {
27511
27780
  }
27512
27781
  const eventBus = eventBusProp || eventBusFromHook;
27513
- const handleOptionClick = React83.useCallback(
27782
+ const handleOptionClick = React79.useCallback(
27514
27783
  (option) => {
27515
27784
  if (option.event && eventBus) {
27516
27785
  eventBus.emit(`UI:${option.event}`, { option });
@@ -27624,7 +27893,7 @@ function GameOverScreen({
27624
27893
  } catch {
27625
27894
  }
27626
27895
  const eventBus = eventBusProp || eventBusFromHook;
27627
- const handleActionClick = React83.useCallback(
27896
+ const handleActionClick = React79.useCallback(
27628
27897
  (action) => {
27629
27898
  if (action.event && eventBus) {
27630
27899
  eventBus.emit(`UI:${action.event}`, { action });
@@ -28357,14 +28626,14 @@ function useSafeEventBus5() {
28357
28626
  } };
28358
28627
  }
28359
28628
  }
28360
- var sizeStyles10, LONG_PRESS_DELAY, LONG_PRESS_INTERVAL, NumberStepper;
28629
+ var sizeStyles9, LONG_PRESS_DELAY, LONG_PRESS_INTERVAL, NumberStepper;
28361
28630
  var init_NumberStepper = __esm({
28362
28631
  "components/core/molecules/NumberStepper.tsx"() {
28363
28632
  "use client";
28364
28633
  init_cn();
28365
28634
  init_Icon();
28366
28635
  init_useEventBus();
28367
- sizeStyles10 = {
28636
+ sizeStyles9 = {
28368
28637
  sm: {
28369
28638
  button: "w-7 h-7",
28370
28639
  text: "text-sm min-w-[2rem]",
@@ -28402,7 +28671,7 @@ var init_NumberStepper = __esm({
28402
28671
  const timeoutRef = useRef(null);
28403
28672
  const isAtMin = min !== void 0 && value <= min;
28404
28673
  const isAtMax = max !== void 0 && value >= max;
28405
- const styles = sizeStyles10[size];
28674
+ const styles = sizeStyles9[size];
28406
28675
  const emitChange = useCallback(
28407
28676
  (newValue) => {
28408
28677
  const clamped = Math.round(newValue / step) * step;
@@ -28543,14 +28812,14 @@ function useSafeEventBus6() {
28543
28812
  } };
28544
28813
  }
28545
28814
  }
28546
- var sizeStyles11, StarRating;
28815
+ var sizeStyles10, StarRating;
28547
28816
  var init_StarRating = __esm({
28548
28817
  "components/core/molecules/StarRating.tsx"() {
28549
28818
  "use client";
28550
28819
  init_cn();
28551
28820
  init_Icon();
28552
28821
  init_useEventBus();
28553
- sizeStyles11 = {
28822
+ sizeStyles10 = {
28554
28823
  sm: { star: "w-4 h-4", gap: "gap-0.5" },
28555
28824
  md: { star: "w-6 h-6", gap: "gap-1" },
28556
28825
  lg: { star: "w-8 h-8", gap: "gap-1.5" }
@@ -28569,7 +28838,7 @@ var init_StarRating = __esm({
28569
28838
  }) => {
28570
28839
  const [hoverValue, setHoverValue] = useState(null);
28571
28840
  const eventBus = useSafeEventBus6();
28572
- const styles = sizeStyles11[size];
28841
+ const styles = sizeStyles10[size];
28573
28842
  const displayValue = hoverValue ?? value;
28574
28843
  const emitChange = useCallback(
28575
28844
  (newValue) => {
@@ -28640,7 +28909,7 @@ var init_StarRating = __esm({
28640
28909
  name: "star",
28641
28910
  className: cn(
28642
28911
  styles.star,
28643
- "text-muted-foreground",
28912
+ "text-foreground/30",
28644
28913
  "transition-colors duration-100"
28645
28914
  ),
28646
28915
  strokeWidth: 1.5
@@ -29123,8 +29392,8 @@ function TableView({
29123
29392
  }) {
29124
29393
  const eventBus = useEventBus();
29125
29394
  const { t } = useTranslate();
29126
- const [visibleCount, setVisibleCount] = React83__default.useState(pageSize > 0 ? pageSize : Infinity);
29127
- const [localSelected, setLocalSelected] = React83__default.useState(/* @__PURE__ */ new Set());
29395
+ const [visibleCount, setVisibleCount] = React79__default.useState(pageSize > 0 ? pageSize : Infinity);
29396
+ const [localSelected, setLocalSelected] = React79__default.useState(/* @__PURE__ */ new Set());
29128
29397
  const colDefs = columns ?? fields ?? [];
29129
29398
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
29130
29399
  const dnd = useDataDnd({
@@ -29319,12 +29588,12 @@ function TableView({
29319
29588
  ]
29320
29589
  }
29321
29590
  );
29322
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React83__default.Fragment, { children: rowInner }, id);
29591
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React79__default.Fragment, { children: rowInner }, id);
29323
29592
  };
29324
29593
  const items = data.map((row) => row);
29325
29594
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
29326
29595
  let runningIndex = 0;
29327
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
29596
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React79__default.Fragment, { children: [
29328
29597
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
29329
29598
  group.items.map((row) => renderRow(row, runningIndex++))
29330
29599
  ] }, gi)) });
@@ -30676,7 +30945,7 @@ var init_StepFlow = __esm({
30676
30945
  className
30677
30946
  }) => {
30678
30947
  if (orientation === "vertical") {
30679
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React83__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
30948
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React79__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
30680
30949
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
30681
30950
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
30682
30951
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -30687,7 +30956,7 @@ var init_StepFlow = __esm({
30687
30956
  ] })
30688
30957
  ] }) }, index)) });
30689
30958
  }
30690
- 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(React83__default.Fragment, { children: [
30959
+ 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(React79__default.Fragment, { children: [
30691
30960
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
30692
30961
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
30693
30962
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -31442,11 +31711,19 @@ function LatticeSVG({
31442
31711
  function f2(n) {
31443
31712
  return n.toFixed(2);
31444
31713
  }
31445
- var VARIANT_MAP2, EdgeDecoration;
31714
+ var colorTokenVars, VARIANT_MAP2, EdgeDecoration;
31446
31715
  var init_EdgeDecoration = __esm({
31447
31716
  "components/core/molecules/EdgeDecoration.tsx"() {
31448
31717
  "use client";
31449
31718
  init_cn();
31719
+ colorTokenVars = {
31720
+ primary: "var(--color-primary)",
31721
+ secondary: "var(--color-secondary)",
31722
+ success: "var(--color-success)",
31723
+ warning: "var(--color-warning)",
31724
+ error: "var(--color-error)",
31725
+ muted: "var(--color-muted)"
31726
+ };
31450
31727
  VARIANT_MAP2 = {
31451
31728
  arch: ArchSVG,
31452
31729
  vine: VineSVG,
@@ -31456,13 +31733,14 @@ var init_EdgeDecoration = __esm({
31456
31733
  variant = "arch",
31457
31734
  side = "both",
31458
31735
  opacity = 0.15,
31459
- color = "var(--color-primary)",
31736
+ color = "primary",
31460
31737
  strokeWidth = 0.5,
31461
31738
  width = 15,
31462
31739
  className
31463
31740
  }) => {
31464
31741
  const id = useId();
31465
31742
  const Variant = VARIANT_MAP2[variant];
31743
+ const resolvedColor = color in colorTokenVars ? colorTokenVars[color] : color;
31466
31744
  const sides = side === "both" ? ["left", "right"] : [side];
31467
31745
  return /* @__PURE__ */ jsx(Fragment, { children: sides.map((s) => /* @__PURE__ */ jsx(
31468
31746
  "svg",
@@ -31485,7 +31763,7 @@ var init_EdgeDecoration = __esm({
31485
31763
  facing: s,
31486
31764
  w: 200,
31487
31765
  h: 600,
31488
- color,
31766
+ color: resolvedColor,
31489
31767
  strokeWidth
31490
31768
  }
31491
31769
  )
@@ -31496,14 +31774,14 @@ var init_EdgeDecoration = __esm({
31496
31774
  EdgeDecoration.displayName = "EdgeDecoration";
31497
31775
  }
31498
31776
  });
31499
- var sizeStyles12, VoteStack;
31777
+ var sizeStyles11, VoteStack;
31500
31778
  var init_VoteStack = __esm({
31501
31779
  "components/core/molecules/VoteStack.tsx"() {
31502
31780
  "use client";
31503
31781
  init_cn();
31504
31782
  init_Icon();
31505
31783
  init_useEventBus();
31506
- sizeStyles12 = {
31784
+ sizeStyles11 = {
31507
31785
  sm: {
31508
31786
  button: "w-7 h-7",
31509
31787
  text: "text-sm min-w-[2rem]",
@@ -31531,7 +31809,7 @@ var init_VoteStack = __esm({
31531
31809
  className,
31532
31810
  label
31533
31811
  }) => {
31534
- const styles = sizeStyles12[size];
31812
+ const styles = sizeStyles11[size];
31535
31813
  const isUp = userVote === "up";
31536
31814
  const isDown = userVote === "down";
31537
31815
  const eventBus = useEventBus();
@@ -31663,7 +31941,7 @@ var init_LikertScale = __esm({
31663
31941
  md: "text-base",
31664
31942
  lg: "text-lg"
31665
31943
  };
31666
- LikertScale = React83__default.forwardRef(
31944
+ LikertScale = React79__default.forwardRef(
31667
31945
  ({
31668
31946
  question,
31669
31947
  options = DEFAULT_LIKERT_OPTIONS,
@@ -31675,7 +31953,7 @@ var init_LikertScale = __esm({
31675
31953
  variant = "radios",
31676
31954
  className
31677
31955
  }, ref) => {
31678
- const groupId = React83__default.useId();
31956
+ const groupId = React79__default.useId();
31679
31957
  const eventBus = useEventBus();
31680
31958
  const handleSelect = useCallback(
31681
31959
  (next) => {
@@ -31799,7 +32077,7 @@ var init_LikertScale = __esm({
31799
32077
  LikertScale.displayName = "LikertScale";
31800
32078
  }
31801
32079
  });
31802
- var DEFAULT_MATRIX_COLUMNS, sizeStyles13, MatrixQuestion;
32080
+ var DEFAULT_MATRIX_COLUMNS, sizeStyles12, MatrixQuestion;
31803
32081
  var init_MatrixQuestion = __esm({
31804
32082
  "components/core/molecules/MatrixQuestion.tsx"() {
31805
32083
  "use client";
@@ -31815,7 +32093,7 @@ var init_MatrixQuestion = __esm({
31815
32093
  { value: 4, label: "Agree" },
31816
32094
  { value: 5, label: "Strongly Agree" }
31817
32095
  ];
31818
- sizeStyles13 = {
32096
+ sizeStyles12 = {
31819
32097
  sm: {
31820
32098
  cell: "px-2 py-1.5 text-xs",
31821
32099
  radio: "sm",
@@ -31838,7 +32116,7 @@ var init_MatrixQuestion = __esm({
31838
32116
  size = "md",
31839
32117
  className
31840
32118
  }) => {
31841
- const styles = sizeStyles13[size];
32119
+ const styles = sizeStyles12[size];
31842
32120
  const safeRows = rows2 ?? [];
31843
32121
  const safeValues = values ?? {};
31844
32122
  const eventBus = useEventBus();
@@ -32825,7 +33103,6 @@ function BlockRow({
32825
33103
  onUpdate,
32826
33104
  onDelete,
32827
33105
  onDuplicate,
32828
- onInsertAfter,
32829
33106
  onChangeType
32830
33107
  }) {
32831
33108
  const { t } = useTranslate();
@@ -33101,34 +33378,16 @@ function BlockRow({
33101
33378
  "data-block-id": block.id,
33102
33379
  "data-block-type": block.type,
33103
33380
  children: [
33104
- !readOnly && showAffordances && /* @__PURE__ */ jsxs(Box, { className: "flex w-12 shrink-0 items-center gap-0.5 pt-1", children: [
33105
- /* @__PURE__ */ jsx(
33106
- Button,
33107
- {
33108
- type: "button",
33109
- variant: "ghost",
33110
- "aria-label": t("richBlockEditor.insertParagraphBelow"),
33111
- className: cn(
33112
- "inline-flex h-6 w-6 items-center justify-center rounded-sm p-0 gap-0",
33113
- "text-muted-foreground hover:bg-muted hover:text-foreground",
33114
- "opacity-0 group-hover:opacity-100 focus-visible:opacity-100",
33115
- "transition-opacity"
33116
- ),
33117
- onClick: () => onInsertAfter("paragraph"),
33118
- children: /* @__PURE__ */ jsx(Icon, { name: "plus", className: "w-3.5 h-3.5" })
33119
- }
33120
- ),
33121
- /* @__PURE__ */ jsx(
33122
- BlockMenu,
33123
- {
33124
- block,
33125
- readOnly,
33126
- onDelete,
33127
- onDuplicate,
33128
- onChangeType
33129
- }
33130
- )
33131
- ] }),
33381
+ !readOnly && showAffordances && /* @__PURE__ */ jsx(Box, { className: "flex w-8 shrink-0 items-center pt-1", children: /* @__PURE__ */ jsx(
33382
+ BlockMenu,
33383
+ {
33384
+ block,
33385
+ readOnly,
33386
+ onDelete,
33387
+ onDuplicate,
33388
+ onChangeType
33389
+ }
33390
+ ) }),
33132
33391
  /* @__PURE__ */ jsx(Box, { className: "min-w-0 flex-1", children: renderBody() })
33133
33392
  ]
33134
33393
  }
@@ -33251,12 +33510,6 @@ var init_RichBlockEditor = __esm({
33251
33510
  },
33252
33511
  [blocks, commit]
33253
33512
  );
33254
- const handleInsertAfter = useCallback(
33255
- (id, type) => {
33256
- commit(insertAfter(blocks, id, createBlock(type)));
33257
- },
33258
- [blocks, commit]
33259
- );
33260
33513
  const handleChangeType = useCallback(
33261
33514
  (id, type) => {
33262
33515
  commit(
@@ -33313,7 +33566,6 @@ var init_RichBlockEditor = __esm({
33313
33566
  onUpdate: (updater) => handleUpdate(block.id, updater),
33314
33567
  onDelete: () => handleDelete(block.id),
33315
33568
  onDuplicate: () => handleDuplicate(block.id),
33316
- onInsertAfter: (type) => handleInsertAfter(block.id, type),
33317
33569
  onChangeType: (type) => handleChangeType(block.id, type)
33318
33570
  },
33319
33571
  block.id
@@ -33983,7 +34235,7 @@ var init_DocBreadcrumb = __esm({
33983
34235
  "aria-label": t("aria.breadcrumb"),
33984
34236
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
33985
34237
  const isLast = idx === items.length - 1;
33986
- return /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
34238
+ return /* @__PURE__ */ jsxs(React79__default.Fragment, { children: [
33987
34239
  idx > 0 && /* @__PURE__ */ jsx(
33988
34240
  Icon,
33989
34241
  {
@@ -34030,108 +34282,6 @@ var init_DocBreadcrumb = __esm({
34030
34282
  DocBreadcrumb.displayName = "DocBreadcrumb";
34031
34283
  }
34032
34284
  });
34033
- function DocCodeBlock({
34034
- code,
34035
- language,
34036
- title,
34037
- showLineNumbers = false,
34038
- className
34039
- }) {
34040
- const [copied, setCopied] = useState(false);
34041
- const handleCopy = useCallback(() => {
34042
- void navigator.clipboard.writeText(code).then(() => {
34043
- setCopied(true);
34044
- setTimeout(() => setCopied(false), 2e3);
34045
- });
34046
- }, [code]);
34047
- const lines = code.split("\n");
34048
- return /* @__PURE__ */ jsxs(
34049
- Box,
34050
- {
34051
- className: cn(
34052
- "rounded-container border border-border overflow-hidden",
34053
- className
34054
- ),
34055
- position: "relative",
34056
- children: [
34057
- title ? /* @__PURE__ */ jsxs(
34058
- HStack,
34059
- {
34060
- align: "center",
34061
- justify: "between",
34062
- className: "bg-muted px-4 py-2 border-b border-border",
34063
- children: [
34064
- /* @__PURE__ */ jsxs(HStack, { align: "center", gap: "sm", children: [
34065
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: title }),
34066
- language ? /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: language }) : null
34067
- ] }),
34068
- /* @__PURE__ */ jsx(
34069
- Button,
34070
- {
34071
- variant: "ghost",
34072
- size: "sm",
34073
- onClick: handleCopy,
34074
- leftIcon: copied ? "check" : "copy",
34075
- children: copied ? "Copied!" : "Copy"
34076
- }
34077
- )
34078
- ]
34079
- }
34080
- ) : null,
34081
- !title ? /* @__PURE__ */ jsx(Box, { position: "absolute", className: "top-2 right-2 z-10", children: /* @__PURE__ */ jsx(
34082
- Button,
34083
- {
34084
- variant: "ghost",
34085
- size: "sm",
34086
- onClick: handleCopy,
34087
- leftIcon: copied ? "check" : "copy",
34088
- children: copied ? "Copied!" : "Copy"
34089
- }
34090
- ) }) : null,
34091
- /* @__PURE__ */ jsxs(HStack, { gap: "none", className: "bg-foreground overflow-x-auto", children: [
34092
- showLineNumbers ? /* @__PURE__ */ jsx(
34093
- Box,
34094
- {
34095
- className: "py-4 pl-4 pr-3 select-none border-r border-border flex-shrink-0",
34096
- children: lines.map((_, i) => /* @__PURE__ */ jsx(
34097
- Typography,
34098
- {
34099
- variant: "caption",
34100
- color: "muted",
34101
- className: "block font-mono text-right leading-6",
34102
- as: "span",
34103
- children: i + 1
34104
- },
34105
- i
34106
- ))
34107
- }
34108
- ) : null,
34109
- /* @__PURE__ */ jsx(
34110
- Box,
34111
- {
34112
- as: "pre",
34113
- className: cn(
34114
- "p-4 font-mono text-sm text-background leading-6 flex-1 min-w-0",
34115
- !title && "pr-24"
34116
- ),
34117
- children: /* @__PURE__ */ jsx(Box, { as: "code", className: "whitespace-pre", children: code })
34118
- }
34119
- )
34120
- ] })
34121
- ]
34122
- }
34123
- );
34124
- }
34125
- var init_DocCodeBlock = __esm({
34126
- "components/core/molecules/DocCodeBlock.tsx"() {
34127
- "use client";
34128
- init_cn();
34129
- init_Box();
34130
- init_Stack();
34131
- init_Typography();
34132
- init_Button();
34133
- }
34134
- });
34135
34285
  function DocPagination({ prev, next, className }) {
34136
34286
  if (!prev && !next) return null;
34137
34287
  return /* @__PURE__ */ jsxs(
@@ -34568,17 +34718,25 @@ var init_DocTOC = __esm({
34568
34718
  DocTOC.displayName = "DocTOC";
34569
34719
  }
34570
34720
  });
34571
- var GradientDivider;
34721
+ var colorTokenVars2, GradientDivider;
34572
34722
  var init_GradientDivider = __esm({
34573
34723
  "components/core/molecules/GradientDivider.tsx"() {
34574
34724
  "use client";
34575
34725
  init_cn();
34576
34726
  init_Box();
34727
+ colorTokenVars2 = {
34728
+ primary: "var(--color-primary)",
34729
+ secondary: "var(--color-secondary)",
34730
+ success: "var(--color-success)",
34731
+ warning: "var(--color-warning)",
34732
+ error: "var(--color-error)",
34733
+ muted: "var(--color-muted)"
34734
+ };
34577
34735
  GradientDivider = ({
34578
34736
  color,
34579
34737
  className
34580
34738
  }) => {
34581
- const centerColor = color ?? "var(--color-primary)";
34739
+ const centerColor = color ? color in colorTokenVars2 ? colorTokenVars2[color] : color : "var(--color-primary)";
34582
34740
  return /* @__PURE__ */ jsx(
34583
34741
  Box,
34584
34742
  {
@@ -34947,7 +35105,7 @@ var init_MiniStateMachine = __esm({
34947
35105
  const x = 2 + i * (NODE_W + GAP2 + ARROW_W + GAP2);
34948
35106
  const tc = transitionCounts[s.name] ?? 0;
34949
35107
  const role = getStateRole(s.name, s.isInitial, s.isTerminal, tc, maxTC);
34950
- return /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
35108
+ return /* @__PURE__ */ jsxs(React79__default.Fragment, { children: [
34951
35109
  /* @__PURE__ */ jsx(
34952
35110
  AvlState,
34953
35111
  {
@@ -35151,7 +35309,7 @@ var init_PageHeader = __esm({
35151
35309
  info: "bg-info/10 text-info"
35152
35310
  };
35153
35311
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
35154
- 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(React83__default.Fragment, { children: [
35312
+ 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(React79__default.Fragment, { children: [
35155
35313
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
35156
35314
  crumb.href ? /* @__PURE__ */ jsx(
35157
35315
  "a",
@@ -35260,7 +35418,7 @@ var init_FormSection = __esm({
35260
35418
  columns = 1,
35261
35419
  className
35262
35420
  }) => {
35263
- const [collapsed, setCollapsed] = React83__default.useState(defaultCollapsed);
35421
+ const [collapsed, setCollapsed] = React79__default.useState(defaultCollapsed);
35264
35422
  const { t } = useTranslate();
35265
35423
  const eventBus = useEventBus();
35266
35424
  const gridClass = {
@@ -35268,7 +35426,7 @@ var init_FormSection = __esm({
35268
35426
  2: "grid-cols-1 md:grid-cols-2",
35269
35427
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
35270
35428
  }[columns];
35271
- React83__default.useCallback(() => {
35429
+ React79__default.useCallback(() => {
35272
35430
  if (collapsible) {
35273
35431
  setCollapsed((prev) => !prev);
35274
35432
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -35375,8 +35533,8 @@ function TextLikeControl({
35375
35533
  onCommit
35376
35534
  }) {
35377
35535
  const initial = value === void 0 || value === null ? "" : String(value);
35378
- const [draft, setDraft] = React83__default.useState(initial);
35379
- React83__default.useEffect(() => setDraft(initial), [initial]);
35536
+ const [draft, setDraft] = React79__default.useState(initial);
35537
+ React79__default.useEffect(() => setDraft(initial), [initial]);
35380
35538
  const commit = () => {
35381
35539
  if (numeric) {
35382
35540
  const n = draft.trim() === "" ? 0 : Number(draft);
@@ -35398,6 +35556,9 @@ function TextLikeControl({
35398
35556
  }
35399
35557
  );
35400
35558
  }
35559
+ function isTraitConfigObject4(v) {
35560
+ return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
35561
+ }
35401
35562
  function FieldControl({
35402
35563
  name,
35403
35564
  decl,
@@ -35407,6 +35568,7 @@ function FieldControl({
35407
35568
  }) {
35408
35569
  let control;
35409
35570
  const stringValue = typeof value === "string" ? value : void 0;
35571
+ const effectiveValue = value ?? decl.default;
35410
35572
  if (decl.type === "icon") {
35411
35573
  control = /* @__PURE__ */ jsx(IconPicker, { value: stringValue, onChange: (icon) => onChange(name, icon) });
35412
35574
  } else if (decl.type === "asset") {
@@ -35433,6 +35595,32 @@ function FieldControl({
35433
35595
  control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: true, value, onCommit: onChange });
35434
35596
  } else if (decl.type === "string") {
35435
35597
  control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
35598
+ } else if (decl.type.startsWith("[") || Array.isArray(effectiveValue)) {
35599
+ const arr = Array.isArray(effectiveValue) ? effectiveValue : [];
35600
+ control = /* @__PURE__ */ jsx(
35601
+ ArrayEditor,
35602
+ {
35603
+ value: arr,
35604
+ onChange: (next) => onChange(name, next)
35605
+ }
35606
+ );
35607
+ } else if (decl.type === "object" && isTraitConfigObject4(effectiveValue)) {
35608
+ control = /* @__PURE__ */ jsx(
35609
+ ObjectEditor,
35610
+ {
35611
+ value: effectiveValue,
35612
+ onChange: (next) => onChange(name, next)
35613
+ }
35614
+ );
35615
+ } else if (decl.type.startsWith("Map ") || !SCALAR_TYPES.has(decl.type) && isTraitConfigObject4(effectiveValue)) {
35616
+ const obj = isTraitConfigObject4(effectiveValue) ? effectiveValue : {};
35617
+ control = /* @__PURE__ */ jsx(
35618
+ MapEditor,
35619
+ {
35620
+ value: obj,
35621
+ onChange: (next) => onChange(name, next)
35622
+ }
35623
+ );
35436
35624
  } else {
35437
35625
  control = /* @__PURE__ */ jsxs(Typography, { variant: "caption", color: "muted", children: [
35438
35626
  decl.type,
@@ -35445,7 +35633,7 @@ function FieldControl({
35445
35633
  decl.description !== void 0 && decl.description !== "" && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: decl.description })
35446
35634
  ] });
35447
35635
  }
35448
- var TIER_ORDER, PropertyInspector;
35636
+ var TIER_ORDER, SCALAR_TYPES, PropertyInspector;
35449
35637
  var init_PropertyInspector = __esm({
35450
35638
  "components/core/molecules/PropertyInspector.tsx"() {
35451
35639
  "use client";
@@ -35459,7 +35647,11 @@ var init_PropertyInspector = __esm({
35459
35647
  init_FormSection();
35460
35648
  init_IconPicker();
35461
35649
  init_AssetPicker();
35650
+ init_ArrayEditor();
35651
+ init_ObjectEditor();
35652
+ init_MapEditor();
35462
35653
  TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
35654
+ SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset"]);
35463
35655
  PropertyInspector = ({
35464
35656
  config,
35465
35657
  values,
@@ -36153,7 +36345,7 @@ var init_WizardContainer = __esm({
36153
36345
  const isCompleted = index < currentStep;
36154
36346
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
36155
36347
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
36156
- return /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
36348
+ return /* @__PURE__ */ jsxs(React79__default.Fragment, { children: [
36157
36349
  /* @__PURE__ */ jsx(
36158
36350
  Button,
36159
36351
  {
@@ -37361,6 +37553,9 @@ var init_GraphCanvas = __esm({
37361
37553
  var init_molecules2 = __esm({
37362
37554
  "components/core/molecules/index.ts"() {
37363
37555
  init_ErrorBoundary();
37556
+ init_ArrayEditor();
37557
+ init_ObjectEditor();
37558
+ init_MapEditor();
37364
37559
  init_FileTree();
37365
37560
  init_FormField();
37366
37561
  init_EmptyState();
@@ -37459,7 +37654,6 @@ var init_molecules2 = __esm({
37459
37654
  init_BranchingLogicBuilder();
37460
37655
  init_VersionDiff();
37461
37656
  init_DocBreadcrumb();
37462
- init_DocCodeBlock();
37463
37657
  init_DocPagination();
37464
37658
  init_DocSearch();
37465
37659
  init_DocSidebar();
@@ -37486,7 +37680,6 @@ var init_molecules2 = __esm({
37486
37680
  init_SignaturePad();
37487
37681
  init_DocumentViewer();
37488
37682
  init_GraphCanvas();
37489
- init_CodeViewer();
37490
37683
  }
37491
37684
  });
37492
37685
 
@@ -38564,7 +38757,7 @@ var init_DetailPanel = __esm({
38564
38757
  function DialogueBubble({
38565
38758
  speaker,
38566
38759
  text,
38567
- portrait,
38760
+ portrait = "https://almadar-kflow-assets.web.app/shared/characters/archetypes/00_base_model.png",
38568
38761
  position = "bottom",
38569
38762
  className
38570
38763
  }) {
@@ -38600,7 +38793,7 @@ var init_DialogueBubble = __esm({
38600
38793
  }
38601
38794
  });
38602
38795
  function extractTitle(children) {
38603
- if (!React83__default.isValidElement(children)) return void 0;
38796
+ if (!React79__default.isValidElement(children)) return void 0;
38604
38797
  const props = children.props;
38605
38798
  if (typeof props.title === "string") {
38606
38799
  return props.title;
@@ -38712,7 +38905,7 @@ function LinearView({
38712
38905
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
38713
38906
  const isDone = i < currentIdx;
38714
38907
  const isCurrent = i === currentIdx;
38715
- return /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
38908
+ return /* @__PURE__ */ jsxs(React79__default.Fragment, { children: [
38716
38909
  i > 0 && /* @__PURE__ */ jsx(
38717
38910
  Typography,
38718
38911
  {
@@ -39670,12 +39863,12 @@ var init_Form = __esm({
39670
39863
  const isSchemaEntity = isOrbitalEntitySchema(entity);
39671
39864
  const resolvedEntity = isSchemaEntity ? entity : void 0;
39672
39865
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
39673
- const normalizedInitialData = React83__default.useMemo(() => {
39866
+ const normalizedInitialData = React79__default.useMemo(() => {
39674
39867
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
39675
39868
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
39676
39869
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
39677
39870
  }, [entity, initialData]);
39678
- const entityDerivedFields = React83__default.useMemo(() => {
39871
+ const entityDerivedFields = React79__default.useMemo(() => {
39679
39872
  if (fields && fields.length > 0) return void 0;
39680
39873
  if (!resolvedEntity) return void 0;
39681
39874
  return resolvedEntity.fields.map(
@@ -39695,16 +39888,16 @@ var init_Form = __esm({
39695
39888
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
39696
39889
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
39697
39890
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
39698
- const [formData, setFormData] = React83__default.useState(
39891
+ const [formData, setFormData] = React79__default.useState(
39699
39892
  normalizedInitialData
39700
39893
  );
39701
- const [collapsedSections, setCollapsedSections] = React83__default.useState(
39894
+ const [collapsedSections, setCollapsedSections] = React79__default.useState(
39702
39895
  /* @__PURE__ */ new Set()
39703
39896
  );
39704
- const [submitError, setSubmitError] = React83__default.useState(null);
39705
- const formRef = React83__default.useRef(null);
39897
+ const [submitError, setSubmitError] = React79__default.useState(null);
39898
+ const formRef = React79__default.useRef(null);
39706
39899
  const formMode = props.mode;
39707
- const mountedRef = React83__default.useRef(false);
39900
+ const mountedRef = React79__default.useRef(false);
39708
39901
  if (!mountedRef.current) {
39709
39902
  mountedRef.current = true;
39710
39903
  debug("forms", "mount", {
@@ -39717,7 +39910,7 @@ var init_Form = __esm({
39717
39910
  });
39718
39911
  }
39719
39912
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
39720
- const evalContext = React83__default.useMemo(
39913
+ const evalContext = React79__default.useMemo(
39721
39914
  () => ({
39722
39915
  formValues: formData,
39723
39916
  globalVariables: externalContext?.globalVariables ?? {},
@@ -39726,7 +39919,7 @@ var init_Form = __esm({
39726
39919
  }),
39727
39920
  [formData, externalContext]
39728
39921
  );
39729
- React83__default.useEffect(() => {
39922
+ React79__default.useEffect(() => {
39730
39923
  debug("forms", "initialData-sync", {
39731
39924
  mode: formMode,
39732
39925
  normalizedInitialData,
@@ -39737,7 +39930,7 @@ var init_Form = __esm({
39737
39930
  setFormData(normalizedInitialData);
39738
39931
  }
39739
39932
  }, [normalizedInitialData]);
39740
- const processCalculations = React83__default.useCallback(
39933
+ const processCalculations = React79__default.useCallback(
39741
39934
  (changedFieldId, newFormData) => {
39742
39935
  if (!hiddenCalculations.length) return;
39743
39936
  const context = {
@@ -39762,7 +39955,7 @@ var init_Form = __esm({
39762
39955
  },
39763
39956
  [hiddenCalculations, externalContext, eventBus]
39764
39957
  );
39765
- const checkViolations = React83__default.useCallback(
39958
+ const checkViolations = React79__default.useCallback(
39766
39959
  (changedFieldId, newFormData) => {
39767
39960
  if (!violationTriggers.length) return;
39768
39961
  const context = {
@@ -39800,7 +39993,7 @@ var init_Form = __esm({
39800
39993
  processCalculations(name, newFormData);
39801
39994
  checkViolations(name, newFormData);
39802
39995
  };
39803
- const isFieldVisible = React83__default.useCallback(
39996
+ const isFieldVisible = React79__default.useCallback(
39804
39997
  (fieldName) => {
39805
39998
  const condition = conditionalFields[fieldName];
39806
39999
  if (!condition) return true;
@@ -39808,7 +40001,7 @@ var init_Form = __esm({
39808
40001
  },
39809
40002
  [conditionalFields, evalContext]
39810
40003
  );
39811
- const isSectionVisible = React83__default.useCallback(
40004
+ const isSectionVisible = React79__default.useCallback(
39812
40005
  (section) => {
39813
40006
  if (!section.condition) return true;
39814
40007
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -39884,7 +40077,7 @@ var init_Form = __esm({
39884
40077
  eventBus.emit(`UI:${onCancel}`);
39885
40078
  }
39886
40079
  };
39887
- const renderField = React83__default.useCallback(
40080
+ const renderField = React79__default.useCallback(
39888
40081
  (field) => {
39889
40082
  const fieldName = field.name || field.field;
39890
40083
  if (!fieldName) return null;
@@ -39905,7 +40098,7 @@ var init_Form = __esm({
39905
40098
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
39906
40099
  );
39907
40100
  const effectiveFields = entityDerivedFields ?? fields;
39908
- const normalizedFields = React83__default.useMemo(() => {
40101
+ const normalizedFields = React79__default.useMemo(() => {
39909
40102
  if (!effectiveFields || effectiveFields.length === 0) return [];
39910
40103
  return effectiveFields.map((field) => {
39911
40104
  if (typeof field === "string") {
@@ -39928,7 +40121,7 @@ var init_Form = __esm({
39928
40121
  return field;
39929
40122
  });
39930
40123
  }, [effectiveFields, resolvedEntity]);
39931
- const schemaFields = React83__default.useMemo(() => {
40124
+ const schemaFields = React79__default.useMemo(() => {
39932
40125
  if (normalizedFields.length === 0) return null;
39933
40126
  if (isDebugEnabled()) {
39934
40127
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -39938,7 +40131,7 @@ var init_Form = __esm({
39938
40131
  }
39939
40132
  return normalizedFields.map(renderField).filter(Boolean);
39940
40133
  }, [normalizedFields, renderField, entityName, conditionalFields]);
39941
- const sectionElements = React83__default.useMemo(() => {
40134
+ const sectionElements = React79__default.useMemo(() => {
39942
40135
  if (!sections || sections.length === 0) return null;
39943
40136
  return sections.map((section) => {
39944
40137
  if (!isSectionVisible(section)) {
@@ -41220,7 +41413,7 @@ var init_List = __esm({
41220
41413
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
41221
41414
  return [];
41222
41415
  }, [entity]);
41223
- const getItemActions = React83__default.useCallback(
41416
+ const getItemActions = React79__default.useCallback(
41224
41417
  (item) => {
41225
41418
  if (!itemActions) return [];
41226
41419
  if (typeof itemActions === "function") {
@@ -41696,7 +41889,7 @@ var init_MediaGallery = __esm({
41696
41889
  [selectable, selectedItems, selectionEvent, eventBus]
41697
41890
  );
41698
41891
  const entityData = Array.isArray(entity) ? entity : [];
41699
- const items = React83__default.useMemo(() => {
41892
+ const items = React79__default.useMemo(() => {
41700
41893
  if (propItems) return propItems;
41701
41894
  if (entityData.length === 0) return [];
41702
41895
  return entityData.map((record, idx) => ({
@@ -41866,9 +42059,9 @@ function MiniMap({
41866
42059
  viewportRect,
41867
42060
  className
41868
42061
  }) {
41869
- const canvasRef = React83.useRef(null);
41870
- const frameRef = React83.useRef(0);
41871
- React83.useEffect(() => {
42062
+ const canvasRef = React79.useRef(null);
42063
+ const frameRef = React79.useRef(0);
42064
+ React79.useEffect(() => {
41872
42065
  const canvas = canvasRef.current;
41873
42066
  if (!canvas) return;
41874
42067
  const ctx = canvas.getContext("2d");
@@ -41950,7 +42143,7 @@ var init_MiniMap = __esm({
41950
42143
  }
41951
42144
  });
41952
42145
  function extractTitle2(children) {
41953
- if (!React83__default.isValidElement(children)) return void 0;
42146
+ if (!React79__default.isValidElement(children)) return void 0;
41954
42147
  const props = children.props;
41955
42148
  if (typeof props.title === "string") {
41956
42149
  return props.title;
@@ -42297,7 +42490,7 @@ function ResourceCounter({
42297
42490
  children: [
42298
42491
  icon && /* @__PURE__ */ jsx("span", { className: cn("flex-shrink-0", sizes.icon), children: icon }),
42299
42492
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
42300
- /* @__PURE__ */ jsxs("span", { className: cn("font-bold tabular-nums", color), children: [
42493
+ /* @__PURE__ */ jsxs("span", { className: cn("font-bold tabular-nums", color && (color in colorTokenClasses2 ? colorTokenClasses2[color] : color)), children: [
42301
42494
  value,
42302
42495
  max != null && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
42303
42496
  "/",
@@ -42308,10 +42501,18 @@ function ResourceCounter({
42308
42501
  }
42309
42502
  );
42310
42503
  }
42311
- var sizeMap15;
42504
+ var colorTokenClasses2, sizeMap15;
42312
42505
  var init_ResourceCounter = __esm({
42313
42506
  "components/game/atoms/ResourceCounter.tsx"() {
42314
42507
  init_cn();
42508
+ colorTokenClasses2 = {
42509
+ primary: "text-primary",
42510
+ secondary: "text-secondary",
42511
+ success: "text-success",
42512
+ warning: "text-warning",
42513
+ error: "text-error",
42514
+ muted: "text-muted-foreground"
42515
+ };
42315
42516
  sizeMap15 = {
42316
42517
  sm: { wrapper: "text-xs gap-1 px-1.5 py-0.5", icon: "text-sm" },
42317
42518
  md: { wrapper: "text-sm gap-1.5 px-2 py-1", icon: "text-base" },
@@ -42407,7 +42608,7 @@ var init_debugRegistry = __esm({
42407
42608
  }
42408
42609
  });
42409
42610
  function useDebugData() {
42410
- const [data, setData] = React83.useState(() => ({
42611
+ const [data, setData] = React79.useState(() => ({
42411
42612
  traits: [],
42412
42613
  ticks: [],
42413
42614
  guards: [],
@@ -42421,7 +42622,7 @@ function useDebugData() {
42421
42622
  },
42422
42623
  lastUpdate: Date.now()
42423
42624
  }));
42424
- React83.useEffect(() => {
42625
+ React79.useEffect(() => {
42425
42626
  const updateData = () => {
42426
42627
  setData({
42427
42628
  traits: getAllTraits(),
@@ -42530,12 +42731,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
42530
42731
  return positions;
42531
42732
  }
42532
42733
  function WalkMinimap() {
42533
- const [walkStep, setWalkStep] = React83.useState(null);
42534
- const [traits2, setTraits] = React83.useState([]);
42535
- const [coveredEdges, setCoveredEdges] = React83.useState([]);
42536
- const [completedTraits, setCompletedTraits] = React83.useState(/* @__PURE__ */ new Set());
42537
- const prevTraitRef = React83.useRef(null);
42538
- React83.useEffect(() => {
42734
+ const [walkStep, setWalkStep] = React79.useState(null);
42735
+ const [traits2, setTraits] = React79.useState([]);
42736
+ const [coveredEdges, setCoveredEdges] = React79.useState([]);
42737
+ const [completedTraits, setCompletedTraits] = React79.useState(/* @__PURE__ */ new Set());
42738
+ const prevTraitRef = React79.useRef(null);
42739
+ React79.useEffect(() => {
42539
42740
  const interval = setInterval(() => {
42540
42741
  const w = window;
42541
42742
  const step = w.__orbitalWalkStep;
@@ -42971,15 +43172,15 @@ var init_EntitiesTab = __esm({
42971
43172
  });
42972
43173
  function EventFlowTab({ events: events2 }) {
42973
43174
  const { t } = useTranslate();
42974
- const [filter, setFilter] = React83.useState("all");
42975
- const containerRef = React83.useRef(null);
42976
- const [autoScroll, setAutoScroll] = React83.useState(true);
42977
- React83.useEffect(() => {
43175
+ const [filter, setFilter] = React79.useState("all");
43176
+ const containerRef = React79.useRef(null);
43177
+ const [autoScroll, setAutoScroll] = React79.useState(true);
43178
+ React79.useEffect(() => {
42978
43179
  if (autoScroll && containerRef.current) {
42979
43180
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
42980
43181
  }
42981
43182
  }, [events2.length, autoScroll]);
42982
- const filteredEvents = React83.useMemo(() => {
43183
+ const filteredEvents = React79.useMemo(() => {
42983
43184
  if (filter === "all") return events2;
42984
43185
  return events2.filter((e) => e.type === filter);
42985
43186
  }, [events2, filter]);
@@ -43095,7 +43296,7 @@ var init_EventFlowTab = __esm({
43095
43296
  });
43096
43297
  function GuardsPanel({ guards }) {
43097
43298
  const { t } = useTranslate();
43098
- const [filter, setFilter] = React83.useState("all");
43299
+ const [filter, setFilter] = React79.useState("all");
43099
43300
  if (guards.length === 0) {
43100
43301
  return /* @__PURE__ */ jsx(
43101
43302
  EmptyState,
@@ -43108,7 +43309,7 @@ function GuardsPanel({ guards }) {
43108
43309
  }
43109
43310
  const passedCount = guards.filter((g) => g.result).length;
43110
43311
  const failedCount = guards.length - passedCount;
43111
- const filteredGuards = React83.useMemo(() => {
43312
+ const filteredGuards = React79.useMemo(() => {
43112
43313
  if (filter === "all") return guards;
43113
43314
  if (filter === "passed") return guards.filter((g) => g.result);
43114
43315
  return guards.filter((g) => !g.result);
@@ -43271,10 +43472,10 @@ function EffectBadge({ effect }) {
43271
43472
  }
43272
43473
  function TransitionTimeline({ transitions }) {
43273
43474
  const { t } = useTranslate();
43274
- const containerRef = React83.useRef(null);
43275
- const [autoScroll, setAutoScroll] = React83.useState(true);
43276
- const [expandedId, setExpandedId] = React83.useState(null);
43277
- React83.useEffect(() => {
43475
+ const containerRef = React79.useRef(null);
43476
+ const [autoScroll, setAutoScroll] = React79.useState(true);
43477
+ const [expandedId, setExpandedId] = React79.useState(null);
43478
+ React79.useEffect(() => {
43278
43479
  if (autoScroll && containerRef.current) {
43279
43480
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
43280
43481
  }
@@ -43554,9 +43755,9 @@ function getAllEvents(traits2) {
43554
43755
  function EventDispatcherTab({ traits: traits2, schema }) {
43555
43756
  const eventBus = useEventBus();
43556
43757
  const { t } = useTranslate();
43557
- const [log8, setLog] = React83.useState([]);
43558
- const prevStatesRef = React83.useRef(/* @__PURE__ */ new Map());
43559
- React83.useEffect(() => {
43758
+ const [log8, setLog] = React79.useState([]);
43759
+ const prevStatesRef = React79.useRef(/* @__PURE__ */ new Map());
43760
+ React79.useEffect(() => {
43560
43761
  for (const trait of traits2) {
43561
43762
  const prev = prevStatesRef.current.get(trait.id);
43562
43763
  if (prev && prev !== trait.currentState) {
@@ -43725,10 +43926,10 @@ function VerifyModePanel({
43725
43926
  localCount
43726
43927
  }) {
43727
43928
  const { t } = useTranslate();
43728
- const [expanded, setExpanded] = React83.useState(true);
43729
- const scrollRef = React83.useRef(null);
43730
- const prevCountRef = React83.useRef(0);
43731
- React83.useEffect(() => {
43929
+ const [expanded, setExpanded] = React79.useState(true);
43930
+ const scrollRef = React79.useRef(null);
43931
+ const prevCountRef = React79.useRef(0);
43932
+ React79.useEffect(() => {
43732
43933
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
43733
43934
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
43734
43935
  }
@@ -43785,10 +43986,10 @@ function RuntimeDebugger({
43785
43986
  schema
43786
43987
  }) {
43787
43988
  const { t } = useTranslate();
43788
- const [isCollapsed, setIsCollapsed] = React83.useState(mode === "verify" ? true : defaultCollapsed);
43789
- const [isVisible, setIsVisible] = React83.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
43989
+ const [isCollapsed, setIsCollapsed] = React79.useState(mode === "verify" ? true : defaultCollapsed);
43990
+ const [isVisible, setIsVisible] = React79.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
43790
43991
  const debugData = useDebugData();
43791
- React83.useEffect(() => {
43992
+ React79.useEffect(() => {
43792
43993
  if (mode === "inline") return;
43793
43994
  return onDebugToggle((enabled) => {
43794
43995
  setIsVisible(enabled);
@@ -43797,7 +43998,7 @@ function RuntimeDebugger({
43797
43998
  }
43798
43999
  });
43799
44000
  }, [mode]);
43800
- React83.useEffect(() => {
44001
+ React79.useEffect(() => {
43801
44002
  if (mode === "inline") return;
43802
44003
  const handleKeyDown = (e) => {
43803
44004
  if (e.key === "`" && isVisible) {
@@ -44246,7 +44447,7 @@ function SequenceBar({
44246
44447
  onSlotRemove(index);
44247
44448
  }, [onSlotRemove, playing]);
44248
44449
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
44249
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React83__default.Fragment, { children: [
44450
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React79__default.Fragment, { children: [
44250
44451
  i > 0 && /* @__PURE__ */ jsx(
44251
44452
  Typography,
44252
44453
  {
@@ -45188,7 +45389,7 @@ var init_SplitPane = __esm({
45188
45389
  }
45189
45390
  });
45190
45391
  function Sprite({
45191
- spritesheet,
45392
+ spritesheet = "https://almadar-kflow-assets.web.app/shared/isometric-blocks/Spritesheet/allTiles_sheet.png",
45192
45393
  frameWidth,
45193
45394
  frameHeight,
45194
45395
  frame,
@@ -45336,7 +45537,7 @@ var init_StatCard = __esm({
45336
45537
  const labelToUse = propLabel ?? propTitle;
45337
45538
  const eventBus = useEventBus();
45338
45539
  const { t } = useTranslate();
45339
- const handleActionClick = React83__default.useCallback(() => {
45540
+ const handleActionClick = React79__default.useCallback(() => {
45340
45541
  if (action?.event) {
45341
45542
  eventBus.emit(`UI:${action.event}`, {});
45342
45543
  }
@@ -45347,7 +45548,7 @@ var init_StatCard = __esm({
45347
45548
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
45348
45549
  const isLoading = externalLoading ?? false;
45349
45550
  const error = externalError;
45350
- const computeMetricValue = React83__default.useCallback(
45551
+ const computeMetricValue = React79__default.useCallback(
45351
45552
  (metric, items) => {
45352
45553
  if (metric.value !== void 0) {
45353
45554
  return metric.value;
@@ -45386,7 +45587,7 @@ var init_StatCard = __esm({
45386
45587
  },
45387
45588
  []
45388
45589
  );
45389
- const schemaStats = React83__default.useMemo(() => {
45590
+ const schemaStats = React79__default.useMemo(() => {
45390
45591
  if (!metrics || metrics.length === 0) return null;
45391
45592
  return metrics.map((metric) => ({
45392
45593
  label: metric.label,
@@ -45394,7 +45595,7 @@ var init_StatCard = __esm({
45394
45595
  format: metric.format
45395
45596
  }));
45396
45597
  }, [metrics, data, computeMetricValue]);
45397
- const calculatedTrend = React83__default.useMemo(() => {
45598
+ const calculatedTrend = React79__default.useMemo(() => {
45398
45599
  if (manualTrend !== void 0) return manualTrend;
45399
45600
  if (previousValue === void 0 || currentValue2 === void 0)
45400
45601
  return void 0;
@@ -45675,6 +45876,37 @@ var init_VariablePanel = __esm({
45675
45876
  VariablePanel.displayName = "VariablePanel";
45676
45877
  }
45677
45878
  });
45879
+ function StateJsonView({
45880
+ data,
45881
+ label,
45882
+ defaultExpanded = false,
45883
+ className
45884
+ }) {
45885
+ const { t } = useTranslate();
45886
+ const [expanded, setExpanded] = useState(defaultExpanded);
45887
+ const jsonString = JSON.stringify(data, null, 2);
45888
+ return /* @__PURE__ */ jsxs(VStack, { className: cn("rounded-lg border border-border overflow-hidden", className), gap: "none", children: [
45889
+ /* @__PURE__ */ jsxs(HStack, { className: "items-center justify-between p-2 bg-muted", gap: "sm", children: [
45890
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground font-medium", children: label ?? t("stateArchitect.viewCode") }),
45891
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: () => setExpanded(!expanded), className: "text-xs", children: expanded ? t("stateArchitect.hideJson") : t("stateArchitect.showJson") })
45892
+ ] }),
45893
+ expanded && /* @__PURE__ */ jsx(Box, { className: "p-3 bg-background overflow-x-auto", children: /* @__PURE__ */ jsx(
45894
+ Typography,
45895
+ {
45896
+ variant: "caption",
45897
+ className: "text-foreground font-mono whitespace-pre text-xs leading-relaxed block",
45898
+ children: jsonString
45899
+ }
45900
+ ) })
45901
+ ] });
45902
+ }
45903
+ var init_StateJsonView = __esm({
45904
+ "components/game/organisms/puzzles/state-architect/StateJsonView.tsx"() {
45905
+ init_atoms2();
45906
+ init_cn();
45907
+ StateJsonView.displayName = "StateJsonView";
45908
+ }
45909
+ });
45678
45910
  function layoutStates(states, width, height) {
45679
45911
  const cx = width / 2;
45680
45912
  const cy = height / 2;
@@ -45966,7 +46198,7 @@ function StateArchitectBoard({
45966
46198
  !r.passed && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-error", children: t("stateArchitect.gotState", { state: r.actualState }) })
45967
46199
  ] }, i))
45968
46200
  ] }),
45969
- resolved.showCodeView !== false && /* @__PURE__ */ jsx(CodeView, { data: codeData, label: "View Code" })
46201
+ resolved.showCodeView !== false && /* @__PURE__ */ jsx(StateJsonView, { data: codeData, label: "View Code" })
45970
46202
  ] })
45971
46203
  ] }),
45972
46204
  playState === "success" && /* @__PURE__ */ jsx(Box, { className: "p-4 rounded-container bg-success/20 border border-success text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "text-success", children: str(resolved.successMessage) || t("stateArchitect.allPassed") }) }),
@@ -46003,7 +46235,7 @@ var init_StateArchitectBoard = __esm({
46003
46235
  init_StateNode();
46004
46236
  init_TransitionArrow();
46005
46237
  init_VariablePanel();
46006
- init_CodeView();
46238
+ init_StateJsonView();
46007
46239
  init_boardEntity();
46008
46240
  ENCOURAGEMENT_KEYS3 = [
46009
46241
  "puzzle.tryAgain1",
@@ -46083,7 +46315,7 @@ function StatusEffect({
46083
46315
  ),
46084
46316
  title: label,
46085
46317
  children: [
46086
- /* @__PURE__ */ jsx("span", { className: cn("flex items-center justify-center", sizes.icon), children: icon }),
46318
+ /* @__PURE__ */ jsx("span", { className: cn("flex items-center justify-center", sizes.icon), children: /* @__PURE__ */ jsx(Icon, { name: icon, size: "sm" }) }),
46087
46319
  duration !== void 0 && /* @__PURE__ */ jsx(
46088
46320
  "span",
46089
46321
  {
@@ -46114,6 +46346,7 @@ var sizeMap16, variantStyles9;
46114
46346
  var init_StatusEffect = __esm({
46115
46347
  "components/game/atoms/StatusEffect.tsx"() {
46116
46348
  init_cn();
46349
+ init_Icon();
46117
46350
  sizeMap16 = {
46118
46351
  sm: { container: "w-8 h-8", icon: "text-sm", badge: "text-xs -top-1 -right-1 w-4 h-4", timer: "text-[9px]" },
46119
46352
  md: { container: "w-10 h-10", icon: "text-base", badge: "text-xs -top-1 -right-1 w-5 h-5", timer: "text-xs" },
@@ -46399,7 +46632,7 @@ var init_Timeline = __esm({
46399
46632
  }) => {
46400
46633
  const { t } = useTranslate();
46401
46634
  const entityData = Array.isArray(entity) ? entity : [];
46402
- const items = React83__default.useMemo(() => {
46635
+ const items = React79__default.useMemo(() => {
46403
46636
  if (propItems) return propItems;
46404
46637
  if (entityData.length === 0) return [];
46405
46638
  return entityData.map((record, idx) => {
@@ -46556,7 +46789,7 @@ var init_TimerDisplay = __esm({
46556
46789
  }
46557
46790
  });
46558
46791
  function extractToastProps(children) {
46559
- if (!React83__default.isValidElement(children)) {
46792
+ if (!React79__default.isValidElement(children)) {
46560
46793
  if (typeof children === "string") {
46561
46794
  return { message: children };
46562
46795
  }
@@ -46594,7 +46827,7 @@ var init_ToastSlot = __esm({
46594
46827
  eventBus.emit("UI:CLOSE");
46595
46828
  };
46596
46829
  if (!isVisible) return null;
46597
- const isCustomContent = React83__default.isValidElement(children) && !message;
46830
+ const isCustomContent = React79__default.isValidElement(children) && !message;
46598
46831
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
46599
46832
  Toast,
46600
46833
  {
@@ -47114,14 +47347,20 @@ function XPBar({
47114
47347
  }) {
47115
47348
  const sizes = sizeMap18[size];
47116
47349
  const percentage = max > 0 ? Math.max(0, Math.min(100, current / max * 100)) : 0;
47117
- const [fillWidth, setFillWidth] = React83.useState(animated ? 0 : percentage);
47118
- React83.useEffect(() => {
47350
+ const [fillWidth, setFillWidth] = React79.useState(animated ? 0 : percentage);
47351
+ React79.useEffect(() => {
47119
47352
  if (!animated) {
47120
47353
  setFillWidth(percentage);
47121
47354
  return;
47122
47355
  }
47123
- const frame = requestAnimationFrame(() => setFillWidth(percentage));
47124
- return () => cancelAnimationFrame(frame);
47356
+ let frame2;
47357
+ const frame1 = requestAnimationFrame(() => {
47358
+ frame2 = requestAnimationFrame(() => setFillWidth(percentage));
47359
+ });
47360
+ return () => {
47361
+ cancelAnimationFrame(frame1);
47362
+ cancelAnimationFrame(frame2);
47363
+ };
47125
47364
  }, [animated, percentage]);
47126
47365
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
47127
47366
  level != null && /* @__PURE__ */ jsxs(
@@ -47159,7 +47398,7 @@ function XPBar({
47159
47398
  )
47160
47399
  }
47161
47400
  ),
47162
- showLabel && /* @__PURE__ */ jsxs("span", { className: cn("text-muted-foreground tabular-nums", sizes.text), children: [
47401
+ showLabel && /* @__PURE__ */ jsxs("span", { className: cn("text-foreground/70 tabular-nums", sizes.text), children: [
47163
47402
  current,
47164
47403
  " / ",
47165
47404
  max,
@@ -47182,12 +47421,12 @@ var init_XPBar = __esm({
47182
47421
  }
47183
47422
  });
47184
47423
  function lazyThree(name, loader) {
47185
- const Lazy = React83__default.lazy(() => loader().then((m) => ({ default: m[name] })));
47424
+ const Lazy = React79__default.lazy(() => loader().then((m) => ({ default: m[name] })));
47186
47425
  function ThreeWrapper(props) {
47187
- return React83__default.createElement(
47188
- React83__default.Suspense,
47426
+ return React79__default.createElement(
47427
+ React79__default.Suspense,
47189
47428
  { fallback: null },
47190
- React83__default.createElement(Lazy, props)
47429
+ React79__default.createElement(Lazy, props)
47191
47430
  );
47192
47431
  }
47193
47432
  ThreeWrapper.displayName = `Lazy(${name})`;
@@ -47207,7 +47446,6 @@ var init_component_registry_generated = __esm({
47207
47446
  init_AnimatedReveal();
47208
47447
  init_ArticleSection();
47209
47448
  init_Aside();
47210
- init_AssetPicker();
47211
47449
  init_AuthLayout();
47212
47450
  init_BattleBoard();
47213
47451
  init_BattleTemplate();
@@ -47236,8 +47474,6 @@ var init_component_registry_generated = __esm({
47236
47474
  init_ChoiceButton();
47237
47475
  init_ClassifierBoard();
47238
47476
  init_CodeBlock();
47239
- init_CodeView();
47240
- init_CodeViewer();
47241
47477
  init_CombatLog();
47242
47478
  init_ComboCounter();
47243
47479
  init_CommunityLinks();
@@ -47265,7 +47501,6 @@ var init_component_registry_generated = __esm({
47265
47501
  init_DialogueBox();
47266
47502
  init_DialogueBubble();
47267
47503
  init_DocBreadcrumb();
47268
- init_DocCodeBlock();
47269
47504
  init_DocPagination();
47270
47505
  init_DocSearch();
47271
47506
  init_DocSidebar();
@@ -47307,13 +47542,11 @@ var init_component_registry_generated = __esm({
47307
47542
  init_GradientDivider();
47308
47543
  init_GraphCanvas();
47309
47544
  init_GraphView();
47310
- init_GridPicker();
47311
47545
  init_Header();
47312
47546
  init_HealthBar();
47313
47547
  init_HealthPanel();
47314
47548
  init_HeroOrganism();
47315
47549
  init_HeroSection();
47316
- init_IconPicker();
47317
47550
  init_InfiniteScrollSentinel();
47318
47551
  init_InputGroup();
47319
47552
  init_InstallBox();
@@ -47358,7 +47591,6 @@ var init_component_registry_generated = __esm({
47358
47591
  init_PricingOrganism();
47359
47592
  init_PricingPageTemplate();
47360
47593
  init_ProgressDots();
47361
- init_PropertyInspector();
47362
47594
  init_PullQuote();
47363
47595
  init_PullToRefresh();
47364
47596
  init_QrScanner();
@@ -47482,7 +47714,6 @@ var init_component_registry_generated = __esm({
47482
47714
  "AnimatedReveal": AnimatedReveal,
47483
47715
  "ArticleSection": ArticleSection,
47484
47716
  "Aside": Aside,
47485
- "AssetPicker": AssetPicker,
47486
47717
  "AuthLayout": AuthLayout,
47487
47718
  "Avatar": AvatarPattern,
47488
47719
  "AvatarPattern": AvatarPattern,
@@ -47524,8 +47755,6 @@ var init_component_registry_generated = __esm({
47524
47755
  "ChoiceButton": ChoiceButton,
47525
47756
  "ClassifierBoard": ClassifierBoard,
47526
47757
  "CodeBlock": CodeBlock,
47527
- "CodeView": CodeView,
47528
- "CodeViewer": CodeViewer,
47529
47758
  "CombatLog": CombatLog,
47530
47759
  "ComboCounter": ComboCounter,
47531
47760
  "CommunityLinks": CommunityLinks,
@@ -47557,7 +47786,6 @@ var init_component_registry_generated = __esm({
47557
47786
  "Divider": DividerPattern,
47558
47787
  "DividerPattern": DividerPattern,
47559
47788
  "DocBreadcrumb": DocBreadcrumb,
47560
- "DocCodeBlock": DocCodeBlock,
47561
47789
  "DocPagination": DocPagination,
47562
47790
  "DocSearch": DocSearch,
47563
47791
  "DocSidebar": DocSidebar,
@@ -47602,7 +47830,6 @@ var init_component_registry_generated = __esm({
47602
47830
  "GraphView": GraphView,
47603
47831
  "Grid": GridPattern,
47604
47832
  "GridPattern": GridPattern,
47605
- "GridPicker": GridPicker,
47606
47833
  "HStack": HStackPattern,
47607
47834
  "HStackPattern": HStackPattern,
47608
47835
  "Header": Header,
@@ -47612,7 +47839,6 @@ var init_component_registry_generated = __esm({
47612
47839
  "HeroSection": HeroSection,
47613
47840
  "Icon": IconPattern,
47614
47841
  "IconPattern": IconPattern,
47615
- "IconPicker": IconPicker,
47616
47842
  "InfiniteScrollSentinel": InfiniteScrollSentinel,
47617
47843
  "Input": InputPattern,
47618
47844
  "InputGroup": InputGroup,
@@ -47669,7 +47895,6 @@ var init_component_registry_generated = __esm({
47669
47895
  "ProgressBar": ProgressBarPattern,
47670
47896
  "ProgressBarPattern": ProgressBarPattern,
47671
47897
  "ProgressDots": ProgressDots,
47672
- "PropertyInspector": PropertyInspector,
47673
47898
  "PullQuote": PullQuote,
47674
47899
  "PullToRefresh": PullToRefresh,
47675
47900
  "QrScanner": QrScanner,
@@ -47811,7 +48036,7 @@ function SuspenseConfigProvider({
47811
48036
  config,
47812
48037
  children
47813
48038
  }) {
47814
- return React83__default.createElement(
48039
+ return React79__default.createElement(
47815
48040
  SuspenseConfigContext.Provider,
47816
48041
  { value: config },
47817
48042
  children
@@ -48301,7 +48526,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
48301
48526
  const key = `${parentId}-${index}-trait:${traitName}`;
48302
48527
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
48303
48528
  }
48304
- return /* @__PURE__ */ jsx(React83__default.Fragment, { children: child }, `${parentId}-${index}`);
48529
+ return /* @__PURE__ */ jsx(React79__default.Fragment, { children: child }, `${parentId}-${index}`);
48305
48530
  }
48306
48531
  if (!child || typeof child !== "object") return null;
48307
48532
  const childId = `${parentId}-${index}`;
@@ -48341,14 +48566,14 @@ function isPatternConfig(value) {
48341
48566
  if (value === null || value === void 0) return false;
48342
48567
  if (typeof value !== "object") return false;
48343
48568
  if (Array.isArray(value)) return false;
48344
- if (React83__default.isValidElement(value)) return false;
48569
+ if (React79__default.isValidElement(value)) return false;
48345
48570
  if (value instanceof Date) return false;
48346
48571
  if (typeof value === "function") return false;
48347
48572
  const record = value;
48348
48573
  return "type" in record && typeof record.type === "string";
48349
48574
  }
48350
48575
  function isPlainConfigObject(value) {
48351
- if (React83__default.isValidElement(value)) return false;
48576
+ if (React79__default.isValidElement(value)) return false;
48352
48577
  if (value instanceof Date) return false;
48353
48578
  const proto = Object.getPrototypeOf(value);
48354
48579
  return proto === Object.prototype || proto === null;
@@ -49508,7 +49733,7 @@ init_EventHandlerBoard();
49508
49733
  init_StateNode();
49509
49734
  init_TransitionArrow();
49510
49735
  init_VariablePanel();
49511
- init_CodeView();
49736
+ init_StateJsonView();
49512
49737
  init_StateArchitectBoard();
49513
49738
 
49514
49739
  // components/game/organisms/puzzles/simulator/index.ts
@@ -49959,4 +50184,4 @@ init_AboutPageTemplate();
49959
50184
  // components/index.ts
49960
50185
  init_cn();
49961
50186
 
49962
- export { ALL_PRESETS, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, ActionButtons, Card2 as ActionCard, ActionPalette, ActionTile, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AuthLayout, Avatar, Badge, BattleBoard, BattleTemplate, BehaviorView, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, CanvasEffect, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, CastleBoard, CastleTemplate, Center, Chart, ChartLegend, Checkbox, ChoiceButton, ClassifierBoard, Coachmark, CodeBlock, CodeView, CodeViewer, CollapsibleSection, CombatLog, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, Container, ContentRenderer, ContentSection, ControlButton, CounterTemplate, CraftingRecipe, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DIAMOND_TOP_Y, DPad, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBox, DialogueBubble, Divider, DocBreadcrumb, DocCodeBlock, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EnemyPlate, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FeatureRenderer2 as FeatureRenderer, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCanvas2D, GameHud, GameMenu, GameOverScreen, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, Heading, HealthBar, HealthPanel, HeroOrganism, HeroSection, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, InventoryPanel, IsometricCanvas, ItemSlot, JazariStateMachine, Label, LandingPageTemplate, LawReferenceTooltip, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NotifyListener, NumberStepper, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsManager, PlatformerCanvas, Popover, PositionedCanvas, PowerupSlots, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuestTracker, QuizBlock, Radio, RangeSlider, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreBoard, ScoreDisplay, SearchInput, Section, SectionHeader, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateIndicator, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, Text, TextHighlight, Textarea, ThemeSelector, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TurnPanel, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UncontrolledBattleBoard, UnitCommandBar, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, WorldMapBoard, WorldMapTemplate, XPBar, applyTemporaryEffect, calculateAttackTargets, calculateDamage, calculateValidMoves, cn, combatAnimations, combatClasses, combatEffects, createInitialGameState, createUnitAnimationState, drawSprite, generateCombatMessage, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, mapBookData, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, screenToIso, springOscillator, tickAnimationState, transitionAnimation, useAnchorRect, useBattleState, useCamera, useGameAudio, useGameAudioContext, useImageCache, usePhysics2D, useSpriteAnimations };
50187
+ export { ALL_PRESETS, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, ActionButtons, Card2 as ActionCard, ActionPalette, ActionTile, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArrayEditor, ArticleSection, Aside, AssetPicker, AuthLayout, Avatar, Badge, BattleBoard, BattleTemplate, BehaviorView, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, CanvasEffect, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, CastleBoard, CastleTemplate, Center, Chart, ChartLegend, Checkbox, ChoiceButton, ClassifierBoard, Coachmark, CodeBlock, CollapsibleSection, CombatLog, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, Container, ContentRenderer, ContentSection, ControlButton, CounterTemplate, CraftingRecipe, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DIAMOND_TOP_Y, DPad, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBox, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EnemyPlate, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FeatureRenderer2 as FeatureRenderer, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCanvas2D, GameHud, GameMenu, GameOverScreen, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HealthPanel, HeroOrganism, HeroSection, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, InventoryPanel, IsometricCanvas, ItemSlot, JazariStateMachine, Label, LandingPageTemplate, LawReferenceTooltip, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapEditor, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NotifyListener, NumberStepper, ObjectEditor, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsManager, PlatformerCanvas, Popover, PositionedCanvas, PowerupSlots, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuestTracker, QuizBlock, Radio, RangeSlider, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreBoard, ScoreDisplay, SearchInput, Section, SectionHeader, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateIndicator, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeSelector, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TurnPanel, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UncontrolledBattleBoard, UnitCommandBar, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, WorldMapBoard, WorldMapTemplate, XPBar, applyTemporaryEffect, calculateAttackTargets, calculateDamage, calculateValidMoves, cn, combatAnimations, combatClasses, combatEffects, createInitialGameState, createUnitAnimationState, drawSprite, generateCombatMessage, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, mapBookData, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, screenToIso, springOscillator, tickAnimationState, toCodeLanguage, transitionAnimation, useAnchorRect, useBattleState, useCamera, useGameAudio, useGameAudioContext, useImageCache, usePhysics2D, useSpriteAnimations };