@almadar/ui 5.134.0 → 5.136.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 (31) hide show
  1. package/dist/{TraitProvider-Ch79cUcb.d.cts → EntityBindingContext-CD9ZoXb4.d.cts} +30 -2
  2. package/dist/{TraitProvider-Ch79cUcb.d.ts → EntityBindingContext-CD9ZoXb4.d.ts} +30 -2
  3. package/dist/avl/index.cjs +819 -429
  4. package/dist/avl/index.js +820 -430
  5. package/dist/{cn-Dm0VrLRG.d.ts → cn-CCaph5o9.d.ts} +1 -1
  6. package/dist/{cn-D3H9UzCW.d.cts → cn-CL0kdshO.d.cts} +1 -1
  7. package/dist/components/index.cjs +1649 -1482
  8. package/dist/components/index.d.cts +105 -202
  9. package/dist/components/index.d.ts +105 -202
  10. package/dist/components/index.js +705 -533
  11. package/dist/lib/drawable/three/index.cjs +16 -0
  12. package/dist/lib/drawable/three/index.d.cts +1 -1
  13. package/dist/lib/drawable/three/index.d.ts +1 -1
  14. package/dist/lib/drawable/three/index.js +16 -0
  15. package/dist/lib/index.cjs +28 -0
  16. package/dist/lib/index.d.cts +21 -3
  17. package/dist/lib/index.d.ts +21 -3
  18. package/dist/lib/index.js +27 -1
  19. package/dist/marketing/index.cjs +1 -0
  20. package/dist/marketing/index.js +1 -0
  21. package/dist/{paintDispatch-BXJgISot.d.cts → paintDispatch-DXygiK7M.d.cts} +39 -10
  22. package/dist/{paintDispatch-BXJgISot.d.ts → paintDispatch-DXygiK7M.d.ts} +39 -10
  23. package/dist/providers/index.cjs +701 -323
  24. package/dist/providers/index.d.cts +3 -3
  25. package/dist/providers/index.d.ts +3 -3
  26. package/dist/providers/index.js +698 -322
  27. package/dist/runtime/index.cjs +819 -429
  28. package/dist/runtime/index.d.cts +5 -2
  29. package/dist/runtime/index.d.ts +5 -2
  30. package/dist/runtime/index.js +820 -430
  31. package/package.json +6 -5
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import * as React74 from 'react';
3
- import React74__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, useState, useLayoutEffect, Suspense, useSyncExternalStore, lazy, useId } from 'react';
2
+ import * as React75 from 'react';
3
+ import React75__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, useState, useLayoutEffect, Suspense, useSyncExternalStore, lazy, useId } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
- import { EventBusContext, useTraitScopeChain, useCurrentPagePath, useGameAudioContextOptional, useEntitySchemaOptional, TraitScopeProvider } from '@almadar/ui/providers';
6
+ import { EventBusContext, useTraitScopeChain, useCurrentPagePath, useGameAudioContextOptional, useEntitySchemaOptional, useEntityBindingSnapshot, useTraitScope, TraitScopeProvider } from '@almadar/ui/providers';
7
7
  export { GameAudioContext, GameAudioProvider, useGameAudioContext } from '@almadar/ui/providers';
8
8
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
9
9
  import * as LucideIcons2 from 'lucide-react';
@@ -11,6 +11,8 @@ import { X, List, Printer, ChevronRight, ChevronLeft, RotateCcw, Play, Terminal,
11
11
  import { useTranslate } from '@almadar/ui/hooks';
12
12
  import { useUISlots, useTheme } from '@almadar/ui/context';
13
13
  import { evaluate, createMinimalContext } from '@almadar/evaluator';
14
+ import { createContextFromBindings, interpolateValue } from '@almadar/runtime';
15
+ import { mergeEntityFrame, isInlineTrait, isRenderBindingMarker } from '@almadar/core';
14
16
  import { createPortal } from 'react-dom';
15
17
  import { wrapCallbackForEvent } from '@almadar/runtime/ui';
16
18
  import { Link, Outlet, useLocation } from 'react-router-dom';
@@ -68,10 +70,10 @@ import ReactMarkdown from 'react-markdown';
68
70
  import remarkGfm from 'remark-gfm';
69
71
  import remarkMath from 'remark-math';
70
72
  import rehypeKatex from 'rehype-katex';
71
- import { mergeEntityFrame, isInlineTrait } from '@almadar/core';
72
73
  import { DndContext, useSensors, useSensor, PointerSensor, KeyboardSensor, useDroppable, pointerWithin, rectIntersection, closestCorners } from '@dnd-kit/core';
73
74
  import { useSortable, arrayMove, sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
74
75
  import { CSS } from '@dnd-kit/utilities';
76
+ import { ordered, lib } from 'emojilib';
75
77
  import { useNodeId, ReactFlowProvider, Handle, Position } from '@xyflow/react';
76
78
  import { forceSimulation, forceLink, forceManyBody, forceCollide, forceX, forceY } from 'd3-force';
77
79
  import { isDrawHostPattern, getPatternDefinition as getPatternDefinition$1, getComponentForPattern as getComponentForPattern$1 } from '@almadar/core/patterns';
@@ -260,7 +262,7 @@ var init_SvgFlow = __esm({
260
262
  width = 100,
261
263
  height = 100
262
264
  }) => {
263
- const markerId = React74__default.useMemo(() => {
265
+ const markerId = React75__default.useMemo(() => {
264
266
  flowIdCounter += 1;
265
267
  return `almadar-flow-arrow-${flowIdCounter}`;
266
268
  }, []);
@@ -853,7 +855,7 @@ var init_SvgRing = __esm({
853
855
  width = 100,
854
856
  height = 100
855
857
  }) => {
856
- const gradientId = React74__default.useMemo(() => {
858
+ const gradientId = React75__default.useMemo(() => {
857
859
  ringIdCounter += 1;
858
860
  return `almadar-ring-glow-${ringIdCounter}`;
859
861
  }, []);
@@ -1395,7 +1397,7 @@ var init_Icon = __esm({
1395
1397
  const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
1396
1398
  const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
1397
1399
  const family = useIconFamily();
1398
- const RenderedComponent = React74__default.useMemo(() => {
1400
+ const RenderedComponent = React75__default.useMemo(() => {
1399
1401
  if (directIcon) return null;
1400
1402
  return effectiveName ? resolveIconForFamily(effectiveName) : null;
1401
1403
  }, [directIcon, effectiveName, family]);
@@ -1457,9 +1459,13 @@ function getAtlas(url, onReady) {
1457
1459
  onReady();
1458
1460
  }).catch(() => {
1459
1461
  atlasCache.set(url, null);
1462
+ onReady();
1460
1463
  });
1461
1464
  return void 0;
1462
1465
  }
1466
+ function atlasFailed(url) {
1467
+ return atlasCache.get(url) === null;
1468
+ }
1463
1469
  function subRectFor(atlas, sprite) {
1464
1470
  if (isTilesheet(atlas)) {
1465
1471
  let col;
@@ -1515,7 +1521,7 @@ var init_atlasSlice = __esm({
1515
1521
  }
1516
1522
  });
1517
1523
  function useAtlasSliceDataUrl(asset) {
1518
- const [, bump] = React74.useReducer((x) => x + 1, 0);
1524
+ const [, bump] = React75.useReducer((x) => x + 1, 0);
1519
1525
  if (!isAtlasAsset(asset)) return void 0;
1520
1526
  const key = `${asset.atlas}#${asset.sprite}`;
1521
1527
  const cached = sliceDataUrlCache.get(key);
@@ -1578,13 +1584,13 @@ function AtlasImage({
1578
1584
  style,
1579
1585
  "aria-hidden": ariaHidden
1580
1586
  }) {
1581
- const [, bump] = React74.useReducer((x) => x + 1, 0);
1582
- const canvasRef = React74.useRef(null);
1587
+ const [, bump] = React75.useReducer((x) => x + 1, 0);
1588
+ const canvasRef = React75.useRef(null);
1583
1589
  const sliced = isAtlasAsset(asset);
1584
1590
  const atlas = sliced ? getAtlas(asset.atlas, bump) : void 0;
1585
1591
  const img = sliced && asset?.url ? getSheetImage(asset.url, bump) : null;
1586
1592
  const rect = sliced && atlas ? subRectFor(atlas, asset.sprite) : null;
1587
- React74.useEffect(() => {
1593
+ React75.useEffect(() => {
1588
1594
  const canvas = canvasRef.current;
1589
1595
  if (!canvas || !img || !rect) return;
1590
1596
  canvas.width = rect.sw;
@@ -1660,7 +1666,7 @@ function resolveIconProp(value, sizeClass) {
1660
1666
  const IconComp = value;
1661
1667
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1662
1668
  }
1663
- if (React74__default.isValidElement(value)) {
1669
+ if (React75__default.isValidElement(value)) {
1664
1670
  return value;
1665
1671
  }
1666
1672
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -1737,7 +1743,7 @@ var init_Button = __esm({
1737
1743
  md: "h-icon-default w-icon-default",
1738
1744
  lg: "h-icon-default w-icon-default"
1739
1745
  };
1740
- Button = React74__default.forwardRef(
1746
+ Button = React75__default.forwardRef(
1741
1747
  ({
1742
1748
  className,
1743
1749
  variant = "primary",
@@ -1809,7 +1815,7 @@ var init_Input = __esm({
1809
1815
  init_cn();
1810
1816
  init_Icon();
1811
1817
  init_useEventBus();
1812
- Input = React74__default.forwardRef(
1818
+ Input = React75__default.forwardRef(
1813
1819
  ({
1814
1820
  className,
1815
1821
  inputType,
@@ -1832,6 +1838,20 @@ var init_Input = __esm({
1832
1838
  const { t } = useTranslate();
1833
1839
  const eventBus = useEventBus();
1834
1840
  const type = inputType || htmlType || "text";
1841
+ const isDeclarative = typeof onChange === "string";
1842
+ const [localValue, setLocalValue] = React75__default.useState(value);
1843
+ const pendingEchoRef = React75__default.useRef(/* @__PURE__ */ new Set());
1844
+ React75__default.useEffect(() => {
1845
+ if (!isDeclarative) return;
1846
+ const incoming = value == null ? "" : String(value);
1847
+ if (pendingEchoRef.current.has(incoming)) {
1848
+ pendingEchoRef.current.delete(incoming);
1849
+ return;
1850
+ }
1851
+ pendingEchoRef.current.clear();
1852
+ setLocalValue(value);
1853
+ }, [value, isDeclarative]);
1854
+ const displayValue = isDeclarative ? localValue : value;
1835
1855
  const resolveIconNode = (i, cls) => {
1836
1856
  if (!i) return null;
1837
1857
  if (typeof i === "string") return /* @__PURE__ */ jsx(Icon, { name: i, className: cls });
@@ -1841,7 +1861,7 @@ var init_Input = __esm({
1841
1861
  const iconCls = "h-icon-default w-icon-default";
1842
1862
  const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
1843
1863
  const resolvedLeftIcon = (leftIcon ? resolveIconNode(leftIcon, iconCls) : null) || IconComponent && /* @__PURE__ */ jsx(IconComponent, { className: iconCls });
1844
- const showClearButton = clearable && value && String(value).length > 0;
1864
+ const showClearButton = clearable && displayValue && String(displayValue).length > 0;
1845
1865
  const isMultiline = type === "textarea";
1846
1866
  const baseClassName = cn(
1847
1867
  "block w-full rounded-sm transition-all duration-fast",
@@ -1860,6 +1880,10 @@ var init_Input = __esm({
1860
1880
  if (typeof onChange === "string") {
1861
1881
  const target = e.target;
1862
1882
  const payload = type === "checkbox" ? { checked: target.checked } : { value: target.value };
1883
+ if (type !== "checkbox") {
1884
+ pendingEchoRef.current.add(target.value);
1885
+ setLocalValue(target.value);
1886
+ }
1863
1887
  eventBus.emit(`UI:${onChange}`, payload);
1864
1888
  } else {
1865
1889
  onChange?.(e);
@@ -1890,7 +1914,7 @@ var init_Input = __esm({
1890
1914
  "select",
1891
1915
  {
1892
1916
  ref,
1893
- value,
1917
+ value: displayValue,
1894
1918
  onChange: handleChange,
1895
1919
  className: cn(baseClassName, "appearance-none pr-10", className),
1896
1920
  ...props,
@@ -1910,7 +1934,7 @@ var init_Input = __esm({
1910
1934
  "textarea",
1911
1935
  {
1912
1936
  ref,
1913
- value,
1937
+ value: displayValue,
1914
1938
  onChange: handleChange,
1915
1939
  rows: rows2,
1916
1940
  className: baseClassName,
@@ -1949,7 +1973,7 @@ var init_Input = __esm({
1949
1973
  {
1950
1974
  ref,
1951
1975
  type,
1952
- value,
1976
+ value: displayValue,
1953
1977
  onChange: handleChange,
1954
1978
  onKeyDown: handleKeyDown,
1955
1979
  className: baseClassName,
@@ -1977,7 +2001,7 @@ var Label;
1977
2001
  var init_Label = __esm({
1978
2002
  "components/core/atoms/Label.tsx"() {
1979
2003
  init_cn();
1980
- Label = React74__default.forwardRef(
2004
+ Label = React75__default.forwardRef(
1981
2005
  ({ className, required, children, ...props }, ref) => {
1982
2006
  return /* @__PURE__ */ jsxs(
1983
2007
  "label",
@@ -2004,7 +2028,7 @@ var init_Textarea = __esm({
2004
2028
  "components/core/atoms/Textarea.tsx"() {
2005
2029
  init_cn();
2006
2030
  init_useEventBus();
2007
- Textarea = React74__default.forwardRef(
2031
+ Textarea = React75__default.forwardRef(
2008
2032
  ({ className, error, onChange, ...props }, ref) => {
2009
2033
  const eventBus = useEventBus();
2010
2034
  const handleChange = (e) => {
@@ -2243,7 +2267,7 @@ var init_Select = __esm({
2243
2267
  init_cn();
2244
2268
  init_Icon();
2245
2269
  init_useEventBus();
2246
- Select = React74__default.forwardRef(
2270
+ Select = React75__default.forwardRef(
2247
2271
  (props, _ref) => {
2248
2272
  const { multiple, searchable, clearable } = props;
2249
2273
  if (multiple || searchable || clearable) {
@@ -2260,7 +2284,7 @@ var init_Checkbox = __esm({
2260
2284
  "components/core/atoms/Checkbox.tsx"() {
2261
2285
  init_cn();
2262
2286
  init_useEventBus();
2263
- Checkbox = React74__default.forwardRef(
2287
+ Checkbox = React75__default.forwardRef(
2264
2288
  ({ className, label, id, onChange, ...props }, ref) => {
2265
2289
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
2266
2290
  const eventBus = useEventBus();
@@ -2314,7 +2338,7 @@ var init_Spinner = __esm({
2314
2338
  md: "h-6 w-6",
2315
2339
  lg: "h-8 w-8"
2316
2340
  };
2317
- Spinner = React74__default.forwardRef(
2341
+ Spinner = React75__default.forwardRef(
2318
2342
  ({ className, size = "md", overlay, ...props }, ref) => {
2319
2343
  if (overlay) {
2320
2344
  return /* @__PURE__ */ jsx(
@@ -2404,7 +2428,7 @@ var init_Card = __esm({
2404
2428
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
2405
2429
  "tile-image-first": "p-0 overflow-hidden"
2406
2430
  };
2407
- Card = React74__default.forwardRef(
2431
+ Card = React75__default.forwardRef(
2408
2432
  ({
2409
2433
  className,
2410
2434
  variant = "bordered",
@@ -2453,9 +2477,9 @@ var init_Card = __esm({
2453
2477
  }
2454
2478
  );
2455
2479
  Card.displayName = "Card";
2456
- CardHeader = React74__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
2480
+ CardHeader = React75__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
2457
2481
  CardHeader.displayName = "CardHeader";
2458
- CardTitle = React74__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2482
+ CardTitle = React75__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2459
2483
  "h3",
2460
2484
  {
2461
2485
  ref,
@@ -2468,11 +2492,11 @@ var init_Card = __esm({
2468
2492
  }
2469
2493
  ));
2470
2494
  CardTitle.displayName = "CardTitle";
2471
- CardContent = React74__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
2495
+ CardContent = React75__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
2472
2496
  CardContent.displayName = "CardContent";
2473
2497
  CardBody = CardContent;
2474
2498
  CardBody.displayName = "CardBody";
2475
- CardFooter = React74__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2499
+ CardFooter = React75__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2476
2500
  "div",
2477
2501
  {
2478
2502
  ref,
@@ -2526,7 +2550,7 @@ var init_Badge = __esm({
2526
2550
  md: "px-2.5 py-1 text-sm",
2527
2551
  lg: "px-3 py-1.5 text-base"
2528
2552
  };
2529
- Badge = React74__default.forwardRef(
2553
+ Badge = React75__default.forwardRef(
2530
2554
  ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
2531
2555
  const iconSizes3 = {
2532
2556
  sm: "h-icon-default w-icon-default",
@@ -2654,7 +2678,7 @@ var init_FilterPill = __esm({
2654
2678
  md: "w-3.5 h-3.5",
2655
2679
  lg: "w-4 h-4"
2656
2680
  };
2657
- FilterPill = React74__default.forwardRef(
2681
+ FilterPill = React75__default.forwardRef(
2658
2682
  ({
2659
2683
  className,
2660
2684
  variant = "default",
@@ -2783,8 +2807,8 @@ var init_Avatar = __esm({
2783
2807
  actionPayload
2784
2808
  }) => {
2785
2809
  const eventBus = useEventBus();
2786
- const [imgFailed, setImgFailed] = React74__default.useState(false);
2787
- React74__default.useEffect(() => {
2810
+ const [imgFailed, setImgFailed] = React75__default.useState(false);
2811
+ React75__default.useEffect(() => {
2788
2812
  setImgFailed(false);
2789
2813
  }, [src]);
2790
2814
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -3036,7 +3060,7 @@ var init_Box = __esm({
3036
3060
  fixed: "fixed",
3037
3061
  sticky: "sticky"
3038
3062
  };
3039
- Box = React74__default.forwardRef(
3063
+ Box = React75__default.forwardRef(
3040
3064
  ({
3041
3065
  padding,
3042
3066
  paddingX,
@@ -3101,7 +3125,7 @@ var init_Box = __esm({
3101
3125
  onPointerDown?.(e);
3102
3126
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
3103
3127
  const isClickable = action || onClick;
3104
- return React74__default.createElement(
3128
+ return React75__default.createElement(
3105
3129
  Component,
3106
3130
  {
3107
3131
  ref,
@@ -3155,7 +3179,7 @@ var init_Center = __esm({
3155
3179
  as: Component = "div"
3156
3180
  }) => {
3157
3181
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
3158
- return React74__default.createElement(Component, {
3182
+ return React75__default.createElement(Component, {
3159
3183
  className: cn(
3160
3184
  inline ? "inline-flex" : "flex",
3161
3185
  horizontal && "justify-center",
@@ -3423,7 +3447,7 @@ var init_Radio = __esm({
3423
3447
  md: "w-2.5 h-2.5",
3424
3448
  lg: "w-3 h-3"
3425
3449
  };
3426
- Radio = React74__default.forwardRef(
3450
+ Radio = React75__default.forwardRef(
3427
3451
  ({
3428
3452
  label,
3429
3453
  helperText,
@@ -3440,12 +3464,12 @@ var init_Radio = __esm({
3440
3464
  onChange,
3441
3465
  ...props
3442
3466
  }, ref) => {
3443
- const reactId = React74__default.useId();
3467
+ const reactId = React75__default.useId();
3444
3468
  const baseId = id || `radio-${reactId}`;
3445
3469
  const hasError = !!error;
3446
3470
  const eventBus = useEventBus();
3447
- const [selected, setSelected] = React74__default.useState(value);
3448
- React74__default.useEffect(() => {
3471
+ const [selected, setSelected] = React75__default.useState(value);
3472
+ React75__default.useEffect(() => {
3449
3473
  if (value !== void 0) setSelected(value);
3450
3474
  }, [value]);
3451
3475
  const pick = (next, e) => {
@@ -3627,7 +3651,7 @@ var init_Switch = __esm({
3627
3651
  "components/core/atoms/Switch.tsx"() {
3628
3652
  "use client";
3629
3653
  init_cn();
3630
- Switch = React74.forwardRef(
3654
+ Switch = React75.forwardRef(
3631
3655
  ({
3632
3656
  checked,
3633
3657
  defaultChecked = false,
@@ -3638,10 +3662,10 @@ var init_Switch = __esm({
3638
3662
  name,
3639
3663
  className
3640
3664
  }, ref) => {
3641
- const [isChecked, setIsChecked] = React74.useState(
3665
+ const [isChecked, setIsChecked] = React75.useState(
3642
3666
  checked !== void 0 ? checked : defaultChecked
3643
3667
  );
3644
- React74.useEffect(() => {
3668
+ React75.useEffect(() => {
3645
3669
  if (checked !== void 0) {
3646
3670
  setIsChecked(checked);
3647
3671
  }
@@ -3804,7 +3828,7 @@ var init_Stack = __esm({
3804
3828
  };
3805
3829
  const isHorizontal = direction === "horizontal";
3806
3830
  const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
3807
- return React74__default.createElement(
3831
+ return React75__default.createElement(
3808
3832
  Component,
3809
3833
  {
3810
3834
  className: cn(
@@ -3955,6 +3979,32 @@ function formatValue(value, format) {
3955
3979
  return String(value);
3956
3980
  }
3957
3981
  }
3982
+ function compareCellValues(a, b) {
3983
+ const aEmpty = a === null || a === void 0 || a === "";
3984
+ const bEmpty = b === null || b === void 0 || b === "";
3985
+ if (aEmpty || bEmpty) return aEmpty && bEmpty ? 0 : aEmpty ? 1 : -1;
3986
+ if (typeof a === "number" && typeof b === "number") return a - b;
3987
+ if (typeof a === "boolean" && typeof b === "boolean") return Number(a) - Number(b);
3988
+ const aNum = Number(a);
3989
+ const bNum = Number(b);
3990
+ if (Number.isFinite(aNum) && Number.isFinite(bNum)) return aNum - bNum;
3991
+ const aTime = dateLikeTime(a);
3992
+ const bTime = dateLikeTime(b);
3993
+ if (aTime !== null && bTime !== null) return aTime - bTime;
3994
+ return String(a).localeCompare(String(b));
3995
+ }
3996
+ function dateLikeTime(value) {
3997
+ if (value instanceof Date) return value.getTime();
3998
+ const text = String(value);
3999
+ if (!/\d/.test(text) || !/[-/:T]/.test(text)) return null;
4000
+ const time = Date.parse(text);
4001
+ return Number.isNaN(time) ? null : time;
4002
+ }
4003
+ function sortRows(rows2, field, direction = "asc") {
4004
+ if (!field) return rows2;
4005
+ const dir = direction === "desc" ? -1 : 1;
4006
+ return [...rows2].sort((a, b) => dir * compareCellValues(a?.[field], b?.[field]));
4007
+ }
3958
4008
  var init_format = __esm({
3959
4009
  "lib/format.ts"() {
3960
4010
  }
@@ -4067,7 +4117,7 @@ var init_Typography = __esm({
4067
4117
  if (format !== void 0 && format !== "none" && (typeof body === "string" || typeof body === "number" || body instanceof Date)) {
4068
4118
  body = formatValue(body, format);
4069
4119
  }
4070
- return React74__default.createElement(
4120
+ return React75__default.createElement(
4071
4121
  Component,
4072
4122
  {
4073
4123
  id,
@@ -4301,7 +4351,7 @@ var Dialog;
4301
4351
  var init_Dialog = __esm({
4302
4352
  "components/core/atoms/Dialog.tsx"() {
4303
4353
  init_cn();
4304
- Dialog = React74__default.forwardRef(
4354
+ Dialog = React75__default.forwardRef(
4305
4355
  ({
4306
4356
  role = "dialog",
4307
4357
  "aria-modal": ariaModal = true,
@@ -4327,7 +4377,7 @@ var Aside;
4327
4377
  var init_Aside = __esm({
4328
4378
  "components/core/atoms/Aside.tsx"() {
4329
4379
  init_cn();
4330
- Aside = React74__default.forwardRef(
4380
+ Aside = React75__default.forwardRef(
4331
4381
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
4332
4382
  );
4333
4383
  Aside.displayName = "Aside";
@@ -4406,9 +4456,9 @@ var init_LawReferenceTooltip = __esm({
4406
4456
  className
4407
4457
  }) => {
4408
4458
  const { t } = useTranslate();
4409
- const [isVisible, setIsVisible] = React74__default.useState(false);
4410
- const timeoutRef = React74__default.useRef(null);
4411
- const triggerRef = React74__default.useRef(null);
4459
+ const [isVisible, setIsVisible] = React75__default.useState(false);
4460
+ const timeoutRef = React75__default.useRef(null);
4461
+ const triggerRef = React75__default.useRef(null);
4412
4462
  const handleMouseEnter = () => {
4413
4463
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4414
4464
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -4419,7 +4469,7 @@ var init_LawReferenceTooltip = __esm({
4419
4469
  };
4420
4470
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
4421
4471
  const open = isVisible || revealed;
4422
- React74__default.useEffect(() => {
4472
+ React75__default.useEffect(() => {
4423
4473
  return () => {
4424
4474
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4425
4475
  };
@@ -4629,7 +4679,7 @@ var init_StatusDot = __esm({
4629
4679
  md: "w-2.5 h-2.5",
4630
4680
  lg: "w-3 h-3"
4631
4681
  };
4632
- StatusDot = React74__default.forwardRef(
4682
+ StatusDot = React75__default.forwardRef(
4633
4683
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
4634
4684
  return /* @__PURE__ */ jsx(
4635
4685
  "span",
@@ -4683,7 +4733,7 @@ var init_TrendIndicator = __esm({
4683
4733
  down: "trending-down",
4684
4734
  flat: "arrow-right"
4685
4735
  };
4686
- TrendIndicator = React74__default.forwardRef(
4736
+ TrendIndicator = React75__default.forwardRef(
4687
4737
  ({
4688
4738
  className,
4689
4739
  value,
@@ -4752,7 +4802,7 @@ var init_RangeSlider = __esm({
4752
4802
  md: "w-4 h-4",
4753
4803
  lg: "w-5 h-5"
4754
4804
  };
4755
- RangeSlider = React74__default.forwardRef(
4805
+ RangeSlider = React75__default.forwardRef(
4756
4806
  ({
4757
4807
  className,
4758
4808
  min = 0,
@@ -5363,7 +5413,7 @@ var init_ContentSection = __esm({
5363
5413
  md: "py-16",
5364
5414
  lg: "py-24"
5365
5415
  };
5366
- ContentSection = React74__default.forwardRef(
5416
+ ContentSection = React75__default.forwardRef(
5367
5417
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
5368
5418
  return /* @__PURE__ */ jsx(
5369
5419
  Box,
@@ -5897,7 +5947,7 @@ var init_AnimatedReveal = __esm({
5897
5947
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
5898
5948
  "none": {}
5899
5949
  };
5900
- AnimatedReveal = React74__default.forwardRef(
5950
+ AnimatedReveal = React75__default.forwardRef(
5901
5951
  ({
5902
5952
  trigger = "scroll",
5903
5953
  animation = "fade-up",
@@ -6057,7 +6107,7 @@ var init_AnimatedGraphic = __esm({
6057
6107
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
6058
6108
  "use client";
6059
6109
  init_cn();
6060
- AnimatedGraphic = React74__default.forwardRef(
6110
+ AnimatedGraphic = React75__default.forwardRef(
6061
6111
  ({
6062
6112
  src,
6063
6113
  svgContent,
@@ -6080,7 +6130,7 @@ var init_AnimatedGraphic = __esm({
6080
6130
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
6081
6131
  const resolvedSvg = svgContent ?? fetchedSvg;
6082
6132
  const prevAnimateRef = useRef(animate);
6083
- const setRef = React74__default.useCallback(
6133
+ const setRef = React75__default.useCallback(
6084
6134
  (node) => {
6085
6135
  containerRef.current = node;
6086
6136
  if (typeof ref === "function") ref(node);
@@ -6169,6 +6219,75 @@ var init_AnimatedGraphic = __esm({
6169
6219
  AnimatedGraphic.displayName = "AnimatedGraphic";
6170
6220
  }
6171
6221
  });
6222
+ function resolveMarkerExpression(expression, entity, config, state) {
6223
+ const ctx = createContextFromBindings({
6224
+ entity,
6225
+ payload: {},
6226
+ state,
6227
+ ...config !== void 0 ? { config } : {}
6228
+ });
6229
+ return interpolateValue(expression, ctx);
6230
+ }
6231
+ function isPlainObject(value) {
6232
+ if (value === null || value === void 0 || typeof value !== "object") return false;
6233
+ if (Array.isArray(value)) return false;
6234
+ if (React75__default.isValidElement(value)) return false;
6235
+ if (value instanceof Date) return false;
6236
+ if (typeof value === "function") return false;
6237
+ return true;
6238
+ }
6239
+ function walkValue(value, scopeTrait, entity, config, state) {
6240
+ if (isRenderBindingMarker(value)) {
6241
+ return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
6242
+ }
6243
+ if (Array.isArray(value)) {
6244
+ const out = [];
6245
+ let changed = false;
6246
+ for (const item of value) {
6247
+ const element = item;
6248
+ const wasMarker = isRenderBindingMarker(element);
6249
+ const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state);
6250
+ if (wasMarker && Array.isArray(resolved)) {
6251
+ out.push(...resolved);
6252
+ changed = true;
6253
+ continue;
6254
+ }
6255
+ out.push(resolved);
6256
+ if (itemChanged) changed = true;
6257
+ }
6258
+ return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
6259
+ }
6260
+ if (isPlainObject(value)) {
6261
+ const sourceTrait = value._sourceTrait;
6262
+ if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
6263
+ return { resolved: value, changed: false };
6264
+ }
6265
+ const out = {};
6266
+ let changed = false;
6267
+ for (const [key, item] of Object.entries(value)) {
6268
+ const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state);
6269
+ out[key] = resolved;
6270
+ if (itemChanged) changed = true;
6271
+ }
6272
+ return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
6273
+ }
6274
+ return { resolved: value, changed: false };
6275
+ }
6276
+ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
6277
+ const out = {};
6278
+ let changed = false;
6279
+ for (const [key, value] of Object.entries(props)) {
6280
+ const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state);
6281
+ out[key] = resolved;
6282
+ if (propChanged) changed = true;
6283
+ }
6284
+ return changed ? out : props;
6285
+ }
6286
+ var init_resolve_render_bindings = __esm({
6287
+ "lib/resolve-render-bindings.ts"() {
6288
+ "use client";
6289
+ }
6290
+ });
6172
6291
  var sizeClasses6, minWidthClasses, lookStyles2, Modal;
6173
6292
  var init_Modal = __esm({
6174
6293
  "components/core/molecules/Modal.tsx"() {
@@ -6756,7 +6875,7 @@ var init_ErrorBoundary = __esm({
6756
6875
  }
6757
6876
  );
6758
6877
  };
6759
- ErrorBoundary = class extends React74__default.Component {
6878
+ ErrorBoundary = class extends React75__default.Component {
6760
6879
  constructor(props) {
6761
6880
  super(props);
6762
6881
  __publicField(this, "reset", () => {
@@ -7039,7 +7158,7 @@ var init_Container = __esm({
7039
7158
  as: Component = "div"
7040
7159
  }) => {
7041
7160
  const resolvedSize = maxWidth ?? size ?? "lg";
7042
- return React74__default.createElement(
7161
+ return React75__default.createElement(
7043
7162
  Component,
7044
7163
  {
7045
7164
  className: cn(
@@ -10403,7 +10522,7 @@ var init_CodeBlock = __esm({
10403
10522
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
10404
10523
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
10405
10524
  HIDDEN_LINE_NUMBERS = { display: "none" };
10406
- CodeBlock = React74__default.memo(
10525
+ CodeBlock = React75__default.memo(
10407
10526
  ({
10408
10527
  code: rawCode,
10409
10528
  language = "text",
@@ -10991,7 +11110,7 @@ var init_MarkdownContent = __esm({
10991
11110
  init_Box();
10992
11111
  init_CodeBlock();
10993
11112
  init_cn();
10994
- MarkdownContent = React74__default.memo(
11113
+ MarkdownContent = React75__default.memo(
10995
11114
  ({ content, direction = "ltr", className }) => {
10996
11115
  const { t: _t } = useTranslate();
10997
11116
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -12318,7 +12437,7 @@ var init_StateMachineView = __esm({
12318
12437
  style: { top: title ? 30 : 0 },
12319
12438
  children: [
12320
12439
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
12321
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React74__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
12440
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React75__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
12322
12441
  StateNode,
12323
12442
  {
12324
12443
  state,
@@ -14895,12 +15014,13 @@ function MiniMap({
14895
15014
  tileAssets,
14896
15015
  unitAssets
14897
15016
  }) {
14898
- const canvasRef = React74.useRef(null);
14899
- const imgCacheRef = React74.useRef(/* @__PURE__ */ new Map());
15017
+ const canvasRef = React75.useRef(null);
15018
+ const imgCacheRef = React75.useRef(/* @__PURE__ */ new Map());
14900
15019
  function loadImg(url) {
14901
15020
  const cached = imgCacheRef.current.get(url);
14902
15021
  if (cached) return cached.complete ? cached : null;
14903
15022
  const img = new Image();
15023
+ img.crossOrigin = "anonymous";
14904
15024
  img.src = url;
14905
15025
  img.onload = () => {
14906
15026
  const canvas = canvasRef.current;
@@ -14911,7 +15031,7 @@ function MiniMap({
14911
15031
  imgCacheRef.current.set(url, img);
14912
15032
  return null;
14913
15033
  }
14914
- React74.useEffect(() => {
15034
+ React75.useEffect(() => {
14915
15035
  const canvas = canvasRef.current;
14916
15036
  if (!canvas) return;
14917
15037
  const ctx = canvas.getContext("2d");
@@ -15261,7 +15381,7 @@ function useCamera(initial) {
15261
15381
  const handleWheel = useCallback((e, drawFn) => {
15262
15382
  e.preventDefault();
15263
15383
  const zoomDelta = e.deltaY > 0 ? 0.9 : 1.1;
15264
- cameraRef.current.zoom = Math.max(0.5, Math.min(3, cameraRef.current.zoom * zoomDelta));
15384
+ cameraRef.current.zoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, cameraRef.current.zoom * zoomDelta));
15265
15385
  drawFn?.();
15266
15386
  }, []);
15267
15387
  const handlePointerDown = useCallback((e) => {
@@ -15282,7 +15402,7 @@ function useCamera(initial) {
15282
15402
  const zoomAtPoint = useCallback((factor, centerX, centerY, viewportSize, drawFn) => {
15283
15403
  const cam = cameraRef.current;
15284
15404
  const oldZoom = cam.zoom;
15285
- const newZoom = Math.max(0.5, Math.min(3, oldZoom * factor));
15405
+ const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, oldZoom * factor));
15286
15406
  if (newZoom === oldZoom) {
15287
15407
  drawFn?.();
15288
15408
  return;
@@ -15334,9 +15454,12 @@ function useCamera(initial) {
15334
15454
  lerpToTarget
15335
15455
  };
15336
15456
  }
15457
+ var MIN_ZOOM, MAX_ZOOM;
15337
15458
  var init_useCamera = __esm({
15338
15459
  "hooks/useCamera.ts"() {
15339
15460
  "use client";
15461
+ MIN_ZOOM = 0.05;
15462
+ MAX_ZOOM = 10;
15340
15463
  }
15341
15464
  });
15342
15465
  function localPoint(canvas, clientX, clientY) {
@@ -15457,6 +15580,7 @@ function getOrLoadImage(url, onReady) {
15457
15580
  return null;
15458
15581
  }
15459
15582
  const img = new Image();
15583
+ img.crossOrigin = "anonymous";
15460
15584
  const entry = { img, status: "pending", onReady };
15461
15585
  cache.set(url, entry);
15462
15586
  updateAssetStatus(url, "pending");
@@ -15468,10 +15592,14 @@ function getOrLoadImage(url, onReady) {
15468
15592
  img.onerror = () => {
15469
15593
  entry.status = "failed";
15470
15594
  updateAssetStatus(url, "failed");
15595
+ entry.onReady?.();
15471
15596
  };
15472
15597
  img.src = url;
15473
15598
  return null;
15474
15599
  }
15600
+ function getImageStatus(url) {
15601
+ return cache.get(url)?.status;
15602
+ }
15475
15603
  var cache;
15476
15604
  var init_imageCache = __esm({
15477
15605
  "lib/imageCache.ts"() {
@@ -15580,6 +15708,15 @@ function createWebPainter(ctx, onAssetLoad) {
15580
15708
  ctx.lineWidth = lineWidth;
15581
15709
  ctx.stroke();
15582
15710
  },
15711
+ fillPath(d, color) {
15712
+ ctx.fillStyle = color;
15713
+ ctx.fill(new Path2D(d));
15714
+ },
15715
+ strokePath(d, color, lineWidth = 1) {
15716
+ ctx.strokeStyle = color;
15717
+ ctx.lineWidth = lineWidth;
15718
+ ctx.stroke(new Path2D(d));
15719
+ },
15583
15720
  text(str2, x, y, style) {
15584
15721
  if (style.font) ctx.font = style.font;
15585
15722
  ctx.fillStyle = style.color;
@@ -15600,39 +15737,39 @@ var init_webPainter2d = __esm({
15600
15737
  });
15601
15738
 
15602
15739
  // lib/isometric.ts
15603
- function isoToScreen(tileX, tileY, scale, baseOffsetX, layout = "isometric") {
15604
- const scaledTileWidth = TILE_WIDTH * scale;
15605
- const scaledFloorHeight = FLOOR_HEIGHT * scale;
15740
+ function isoToScreen(tileX, tileY, cellWidth, baseOffsetX, layout = "isometric") {
15741
+ const w = cellWidth;
15742
+ const fh = cellWidth / 2;
15606
15743
  if (layout === "hex") {
15607
- const screenX2 = tileX * scaledTileWidth + (tileY & 1) * (scaledTileWidth / 2) + baseOffsetX;
15608
- const screenY2 = tileY * (scaledFloorHeight * 0.75);
15744
+ const screenX2 = tileX * w + (tileY & 1) * (w / 2) + baseOffsetX;
15745
+ const screenY2 = tileY * (fh * 0.75);
15609
15746
  return { x: screenX2, y: screenY2 };
15610
15747
  }
15611
15748
  if (layout === "flat") {
15612
- const screenX2 = tileX * scaledTileWidth + baseOffsetX;
15613
- const screenY2 = tileY * scaledTileWidth;
15749
+ const screenX2 = tileX * w + baseOffsetX;
15750
+ const screenY2 = tileY * w;
15614
15751
  return { x: screenX2, y: screenY2 };
15615
15752
  }
15616
- const screenX = (tileX - tileY) * (scaledTileWidth / 2) + baseOffsetX;
15617
- const screenY = (tileX + tileY) * (scaledFloorHeight / 2);
15753
+ const screenX = (tileX - tileY) * (w / 2) + baseOffsetX;
15754
+ const screenY = (tileX + tileY) * (fh / 2);
15618
15755
  return { x: screenX, y: screenY };
15619
15756
  }
15620
- function screenToIso(screenX, screenY, scale, baseOffsetX, layout = "isometric") {
15621
- const scaledTileWidth = TILE_WIDTH * scale;
15622
- const scaledFloorHeight = FLOOR_HEIGHT * scale;
15757
+ function screenToIso(screenX, screenY, cellWidth, baseOffsetX, layout = "isometric") {
15758
+ const w = cellWidth;
15759
+ const fh = cellWidth / 2;
15623
15760
  if (layout === "hex") {
15624
- const row = Math.round(screenY / (scaledFloorHeight * 0.75));
15625
- const col = Math.round((screenX - (row & 1) * (scaledTileWidth / 2) - baseOffsetX) / scaledTileWidth);
15761
+ const row = Math.round(screenY / (fh * 0.75));
15762
+ const col = Math.round((screenX - (row & 1) * (w / 2) - baseOffsetX) / w);
15626
15763
  return { x: col, y: row };
15627
15764
  }
15628
15765
  if (layout === "flat") {
15629
- const col = Math.round((screenX - baseOffsetX) / scaledTileWidth);
15630
- const row = Math.round(screenY / scaledTileWidth);
15766
+ const col = Math.round((screenX - baseOffsetX) / w);
15767
+ const row = Math.round(screenY / w);
15631
15768
  return { x: col, y: row };
15632
15769
  }
15633
15770
  const adjustedX = screenX - baseOffsetX;
15634
- const tileX = (adjustedX / (scaledTileWidth / 2) + screenY / (scaledFloorHeight / 2)) / 2;
15635
- const tileY = (screenY / (scaledFloorHeight / 2) - adjustedX / (scaledTileWidth / 2)) / 2;
15771
+ const tileX = (adjustedX / (w / 2) + screenY / (fh / 2)) / 2;
15772
+ const tileY = (screenY / (fh / 2) - adjustedX / (w / 2)) / 2;
15636
15773
  return { x: Math.round(tileX), y: Math.round(tileY) };
15637
15774
  }
15638
15775
  var TILE_WIDTH, TILE_HEIGHT, FLOOR_HEIGHT, DIAMOND_TOP_Y, FEATURE_COLORS, BACKGROUND_FALLBACK_COLOR, MINIMAP_TERRAIN_COLORS;
@@ -15663,12 +15800,13 @@ var init_isometric = __esm({
15663
15800
 
15664
15801
  // lib/drawable/projector.ts
15665
15802
  function create2DProjector(opts) {
15666
- const { scale, baseOffsetX, layout } = opts;
15667
- const tileWidth = layout === "free" ? 1 : TILE_WIDTH * scale;
15668
- const floorHeight = layout === "free" ? 1 : FLOOR_HEIGHT * scale;
15669
- const diamondTopY = layout === "free" ? 0 : (opts.diamondTopY ?? DIAMOND_TOP_Y) * scale;
15803
+ const { baseOffsetX, layout } = opts;
15804
+ const tw = opts.tileWidth ?? TILE_WIDTH;
15805
+ const tileWidth = layout === "free" ? 1 : tw;
15806
+ const floorHeight = layout === "free" ? 1 : tw / 2;
15807
+ const diamondTopY = layout === "free" ? 0 : opts.diamondTopY ?? tw * (DIAMOND_TOP_Y / TILE_WIDTH);
15670
15808
  const squareGrid = layout === "flat" || layout === "free";
15671
- const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y, scale, baseOffsetX, layout);
15809
+ const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y, tw, baseOffsetX, layout);
15672
15810
  const anchorPoint = (pos, anchor) => {
15673
15811
  const base = project(pos);
15674
15812
  if (anchor === "top-left") return base;
@@ -15699,7 +15837,7 @@ function create2DProjector(opts) {
15699
15837
  { x: base.x, y: topY + floorHeight / 2 }
15700
15838
  ];
15701
15839
  };
15702
- return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY, scale, squareGrid };
15840
+ return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY, squareGrid, worldPixelDirect: layout === "free" };
15703
15841
  }
15704
15842
  var init_projector = __esm({
15705
15843
  "lib/drawable/projector.ts"() {
@@ -15715,32 +15853,67 @@ var init_contract = __esm({
15715
15853
  "lib/drawable/contract.ts"() {
15716
15854
  }
15717
15855
  });
15718
-
15719
- // components/game/atoms/DrawSprite.tsx
15856
+ function warnMissingOnce(reason, node) {
15857
+ const key = `${reason}:${node.asset.url}:${String(node.asset.atlas)}:${String(node.asset.sprite)}`;
15858
+ if (loggedMissing.has(key)) return;
15859
+ loggedMissing.add(key);
15860
+ spriteLog.warn("draw-sprite asset unresolvable \u2014 painting fallback square", { reason, url: node.asset.url, atlas: node.asset.atlas, sprite: node.asset.sprite });
15861
+ }
15862
+ function paintFallbackSquare(painter, node, dctx, reason) {
15863
+ warnMissingOnce(reason, node);
15864
+ const tw = dctx.projector.tileWidth;
15865
+ const natural = dctx.projector.worldPixelDirect ? FALLBACK_WORLD_PX : tw;
15866
+ const w = node.width !== void 0 ? node.width * tw : natural;
15867
+ const h = node.height !== void 0 ? node.height * tw : natural;
15868
+ const anchor = node.anchor ?? "top-left";
15869
+ const p = dctx.projector.anchorPoint(node.position, anchor);
15870
+ const dx = anchor === "top-left" ? p.x : p.x - w / 2;
15871
+ const dy = anchor === "ground" ? p.y - h : anchor === "center" ? p.y - h / 2 : p.y;
15872
+ painter.save();
15873
+ if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
15874
+ painter.fillRect(dx, dy, w, h, "#9b8f7f");
15875
+ painter.strokeRect(dx, dy, w, h, "#5e564b", Math.max(1, tw / 32));
15876
+ painter.restore();
15877
+ }
15720
15878
  function DrawSprite(_props) {
15721
15879
  return null;
15722
15880
  }
15723
- var paintSprite;
15881
+ var spriteLog, loggedMissing, FALLBACK_WORLD_PX, paintSprite;
15724
15882
  var init_DrawSprite = __esm({
15725
15883
  "components/game/atoms/DrawSprite.tsx"() {
15726
15884
  "use client";
15727
15885
  init_atlasSlice();
15886
+ init_imageCache();
15728
15887
  init_contract();
15888
+ spriteLog = createLogger("almadar:ui:draw-sprite");
15889
+ loggedMissing = /* @__PURE__ */ new Set();
15890
+ FALLBACK_WORLD_PX = 32;
15729
15891
  paintSprite = (painter, node, dctx) => {
15730
15892
  if (!node.asset?.url || !isValidScenePos(node.position)) return;
15731
15893
  const tex = painter.resolveTexture(node.asset.url);
15732
- if (!tex) return;
15894
+ if (!tex) {
15895
+ if (getImageStatus(node.asset.url) === "failed") paintFallbackSquare(painter, node, dctx, "texture-failed");
15896
+ return;
15897
+ }
15733
15898
  let src = typeof node.frame === "object" ? node.frame : void 0;
15734
15899
  if (!src && isAtlasAsset(node.asset)) {
15735
15900
  const atlas = getAtlas(node.asset.atlas, dctx.invalidate);
15736
- if (!atlas) return;
15901
+ if (!atlas) {
15902
+ if (atlasFailed(node.asset.atlas)) paintFallbackSquare(painter, node, dctx, "atlas-failed");
15903
+ return;
15904
+ }
15737
15905
  const r = subRectFor(atlas, node.asset.sprite);
15738
- if (!r) return;
15906
+ if (!r) {
15907
+ paintFallbackSquare(painter, node, dctx, "sprite-missing");
15908
+ return;
15909
+ }
15739
15910
  src = { x: r.sx, y: r.sy, w: r.sw, h: r.sh };
15740
15911
  }
15741
15912
  const tw = dctx.projector.tileWidth;
15742
- const w = node.width !== void 0 ? node.width * tw : src ? src.w : tex.width;
15743
- const h = node.height !== void 0 ? node.height * tw : src ? src.h : tex.height;
15913
+ const fallbackW = dctx.projector.worldPixelDirect ? src ? src.w : tex.width : tw;
15914
+ const fallbackH = dctx.projector.worldPixelDirect ? src ? src.h : tex.height : tw;
15915
+ const w = node.width !== void 0 ? node.width * tw : fallbackW;
15916
+ const h = node.height !== void 0 ? node.height * tw : fallbackH;
15744
15917
  const anchor = node.anchor ?? "top-left";
15745
15918
  const p = dctx.projector.anchorPoint(node.position, anchor);
15746
15919
  const dx = anchor === "top-left" ? p.x : p.x - w / 2;
@@ -15817,6 +15990,16 @@ var init_DrawShape = __esm({
15817
15990
  if (node.stroke) painter.strokePoly(pts, node.stroke, node.strokeWidth ?? 1, true);
15818
15991
  break;
15819
15992
  }
15993
+ case "path": {
15994
+ if (!node.d) break;
15995
+ const base = dctx.projector.project(node.position);
15996
+ const tw = dctx.projector.tileWidth;
15997
+ painter.translate(base.x, base.y);
15998
+ painter.scale(tw, tw);
15999
+ if (node.fill) painter.fillPath(node.d, node.fill);
16000
+ if (node.stroke) painter.strokePath(node.d, node.stroke, (node.strokeWidth ?? 1) / tw);
16001
+ break;
16002
+ }
15820
16003
  }
15821
16004
  painter.restore();
15822
16005
  };
@@ -15908,6 +16091,19 @@ function paintDrawable(painter, node, dctx) {
15908
16091
  case "draw-text":
15909
16092
  paintText(painter, node, dctx);
15910
16093
  break;
16094
+ case "draw-group": {
16095
+ if (!isValidScenePos(node.position)) break;
16096
+ if (!Array.isArray(node.items)) break;
16097
+ const p = dctx.projector.project(node.position);
16098
+ painter.save();
16099
+ painter.translate(p.x, p.y);
16100
+ if (node.scale !== void 0) painter.scale(node.scale, node.scale);
16101
+ if (node.rotate !== void 0) painter.rotate(node.rotate);
16102
+ if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
16103
+ for (const item of node.items) paintDrawable(painter, item, dctx);
16104
+ painter.restore();
16105
+ break;
16106
+ }
15911
16107
  case "draw-sprite-layer":
15912
16108
  paintSpriteLayer(painter, node, dctx);
15913
16109
  break;
@@ -15921,6 +16117,7 @@ function paintDrawable(painter, node, dctx) {
15921
16117
  }
15922
16118
  var init_paintDispatch = __esm({
15923
16119
  "lib/drawable/paintDispatch.ts"() {
16120
+ init_contract();
15924
16121
  init_DrawSprite();
15925
16122
  init_DrawShape();
15926
16123
  init_DrawText();
@@ -15938,6 +16135,7 @@ function collectDrawnItems(nodes) {
15938
16135
  case "draw-sprite":
15939
16136
  case "draw-shape":
15940
16137
  case "draw-text":
16138
+ case "draw-group":
15941
16139
  if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id });
15942
16140
  break;
15943
16141
  case "draw-sprite-layer":
@@ -15981,6 +16179,8 @@ function Canvas2D({
15981
16179
  keyUpMap,
15982
16180
  camera = "pan-zoom",
15983
16181
  scale = 0.4,
16182
+ tileWidth,
16183
+ fit = false,
15984
16184
  showMinimap = true,
15985
16185
  followTarget,
15986
16186
  cameraPos,
@@ -16023,9 +16223,32 @@ function Canvas2D({
16023
16223
  observer2.observe(el);
16024
16224
  return () => observer2.disconnect();
16025
16225
  }, []);
16026
- const scaledTileWidth = TILE_WIDTH * scale;
16027
- const scaledFloorHeight = FLOOR_HEIGHT * scale;
16028
- const scaledDiamondTopY = DIAMOND_TOP_Y * scale;
16226
+ const [atlasVersion, setAtlasVersion] = useState(0);
16227
+ const bumpAtlas = useCallback(() => setAtlasVersion((v) => v + 1), []);
16228
+ const detectedTileWidth = useMemo(() => {
16229
+ for (const n of drawables ?? []) {
16230
+ const refs = [];
16231
+ if (n.type === "draw-sprite") refs.push(n.asset);
16232
+ else if (n.type === "draw-sprite-layer") for (const it of n.items) refs.push(it.asset);
16233
+ for (const a of refs) {
16234
+ if (a && isAtlasAsset(a) && a.atlas) {
16235
+ const atlas = getAtlas(a.atlas, bumpAtlas);
16236
+ if (atlas) {
16237
+ if ("tileWidth" in atlas) return atlas.tileWidth;
16238
+ if ("subTextures" in atlas) {
16239
+ const first = Object.values(atlas.subTextures)[0];
16240
+ if (first && typeof first.width === "number") return first.width;
16241
+ }
16242
+ }
16243
+ }
16244
+ }
16245
+ }
16246
+ return void 0;
16247
+ }, [drawables, atlasVersion]);
16248
+ const nativeTileW = tileWidth ?? detectedTileWidth ?? TILE_WIDTH;
16249
+ const scaledTileWidth = nativeTileW;
16250
+ const scaledFloorHeight = nativeTileW / 2;
16251
+ const scaledDiamondTopY = nativeTileW * (DIAMOND_TOP_Y / TILE_WIDTH);
16029
16252
  const drawnItems = useMemo(() => collectDrawnItems(drawables ?? []), [drawables]);
16030
16253
  const scenePositions = useMemo(() => drawnItems.map((i) => i.pos), [drawnItems]);
16031
16254
  const hitIndex = useMemo(() => buildHitIndex(drawnItems), [drawnItems]);
@@ -16043,14 +16266,36 @@ function Canvas2D({
16043
16266
  if (isFree || projection === "flat" || projection === "side") return 0;
16044
16267
  return (gridExtent.height - 1) * (scaledTileWidth / 2);
16045
16268
  }, [isFree, projection, gridExtent.height, scaledTileWidth]);
16269
+ const effectiveZoom = useMemo(() => {
16270
+ if (isFree || projection === "side") return scale;
16271
+ if (!fit) {
16272
+ const z2 = TILE_WIDTH * scale * scale / nativeTileW;
16273
+ return Number.isFinite(z2) && z2 > 0 ? z2 : scale;
16274
+ }
16275
+ if (!viewportSize.width || gridExtent.width < 2 || gridExtent.height < 2) return scale;
16276
+ let boardW;
16277
+ let boardH;
16278
+ if (projection === "flat") {
16279
+ boardW = gridExtent.width * nativeTileW;
16280
+ boardH = gridExtent.height * nativeTileW;
16281
+ } else if (projection === "hex") {
16282
+ boardW = (gridExtent.width + 0.5) * nativeTileW;
16283
+ boardH = gridExtent.height * (nativeTileW / 2) * 0.75 + nativeTileW / 2;
16284
+ } else {
16285
+ boardW = (gridExtent.width + gridExtent.height) * (nativeTileW / 2);
16286
+ boardH = (gridExtent.width + gridExtent.height) * (nativeTileW / 4);
16287
+ }
16288
+ const z = Math.min(viewportSize.width * 0.85 / boardW, viewportSize.height * 0.85 / boardH);
16289
+ return Number.isFinite(z) && z > 0 ? z : scale;
16290
+ }, [isFree, projection, fit, viewportSize, gridExtent, nativeTileW, scale]);
16046
16291
  const projector = useMemo(
16047
- () => create2DProjector({ scale, baseOffsetX, layout }),
16048
- [scale, baseOffsetX, layout]
16292
+ () => create2DProjector({ tileWidth: nativeTileW, baseOffsetX, layout }),
16293
+ [nativeTileW, baseOffsetX, layout]
16049
16294
  );
16050
16295
  const unproject = useCallback((screenX, screenY) => {
16051
16296
  if (projection === "free" || projection === "side") return { x: Math.round(screenX), y: Math.round(screenY) };
16052
- return screenToIso(screenX, screenY, scale, baseOffsetX, projection);
16053
- }, [projection, scale, baseOffsetX]);
16297
+ return screenToIso(screenX, screenY, nativeTileW, baseOffsetX, projection);
16298
+ }, [projection, nativeTileW, baseOffsetX]);
16054
16299
  const bgUrls = useMemo(() => backgroundImage ? [backgroundImage.url] : [], [backgroundImage]);
16055
16300
  const { getImage, pendingCount: _imagePendingCount } = useImageCache(bgUrls);
16056
16301
  useEffect(() => {
@@ -16077,9 +16322,7 @@ function Canvas2D({
16077
16322
  zoomAtPoint,
16078
16323
  screenToWorld,
16079
16324
  lerpToTarget
16080
- } = useCamera({ zoom: scale });
16081
- const [atlasVersion, setAtlasVersion] = useState(0);
16082
- const bumpAtlas = useCallback(() => setAtlasVersion((v) => v + 1), []);
16325
+ } = useCamera({ zoom: effectiveZoom });
16083
16326
  const miniMapTiles = useMemo(() => {
16084
16327
  if (!showMinimap) return [];
16085
16328
  const color = MINIMAP_TERRAIN_COLORS.default;
@@ -16154,6 +16397,13 @@ function Canvas2D({
16154
16397
  useEffect(() => {
16155
16398
  draw();
16156
16399
  }, [_imagePendingCount, draw]);
16400
+ const userZoomedRef = useRef(false);
16401
+ useEffect(() => {
16402
+ if (userZoomedRef.current) return;
16403
+ if (cameraRef.current.zoom === effectiveZoom) return;
16404
+ cameraRef.current.zoom = effectiveZoom;
16405
+ draw();
16406
+ }, [effectiveZoom, cameraRef, draw]);
16157
16407
  useEffect(() => {
16158
16408
  draw();
16159
16409
  }, [atlasVersion, draw]);
@@ -16210,7 +16460,9 @@ function Canvas2D({
16210
16460
  if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
16211
16461
  }, [handleMouseLeave, tileLeaveEvent, eventBus]);
16212
16462
  const applyZoom = useCallback((factor, centerX, centerY) => {
16213
- if (enableCamera) zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw());
16463
+ if (!enableCamera) return;
16464
+ userZoomedRef.current = true;
16465
+ zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw());
16214
16466
  }, [enableCamera, zoomAtPoint, viewportSize, draw]);
16215
16467
  const applyPanDelta = useCallback((dx, dy) => {
16216
16468
  if (enableCamera) panBy(dx, dy, () => draw());
@@ -16395,6 +16647,8 @@ function Canvas({
16395
16647
  isLoading,
16396
16648
  unitScale,
16397
16649
  showMinimap,
16650
+ fit,
16651
+ tileWidth,
16398
16652
  backgroundImage,
16399
16653
  backgroundColor,
16400
16654
  worldWidth,
@@ -16452,6 +16706,8 @@ function Canvas({
16452
16706
  projection,
16453
16707
  camera: to2DCamera(camera?.mode),
16454
16708
  ...zoom !== void 0 ? { scale: zoom } : {},
16709
+ ...fit !== void 0 ? { fit } : {},
16710
+ ...tileWidth !== void 0 ? { tileWidth } : {},
16455
16711
  ...camera?.target !== void 0 ? { followTarget: camera.target } : {},
16456
16712
  ...camera?.pos !== void 0 ? { cameraPos: camera.pos } : {},
16457
16713
  showMinimap,
@@ -18745,9 +19001,9 @@ function ControlButton({
18745
19001
  className
18746
19002
  }) {
18747
19003
  const eventBus = useEventBus();
18748
- const [isPressed, setIsPressed] = React74.useState(false);
19004
+ const [isPressed, setIsPressed] = React75.useState(false);
18749
19005
  const actualPressed = pressed ?? isPressed;
18750
- const handlePointerDown = React74.useCallback(
19006
+ const handlePointerDown = React75.useCallback(
18751
19007
  (e) => {
18752
19008
  e.preventDefault();
18753
19009
  if (disabled) return;
@@ -18757,7 +19013,7 @@ function ControlButton({
18757
19013
  },
18758
19014
  [disabled, pressEvent, eventBus, onPress]
18759
19015
  );
18760
- const handlePointerUp = React74.useCallback(
19016
+ const handlePointerUp = React75.useCallback(
18761
19017
  (e) => {
18762
19018
  e.preventDefault();
18763
19019
  if (disabled) return;
@@ -18767,7 +19023,7 @@ function ControlButton({
18767
19023
  },
18768
19024
  [disabled, releaseEvent, eventBus, onRelease]
18769
19025
  );
18770
- const handlePointerLeave = React74.useCallback(
19026
+ const handlePointerLeave = React75.useCallback(
18771
19027
  (e) => {
18772
19028
  if (isPressed) {
18773
19029
  setIsPressed(false);
@@ -18855,8 +19111,8 @@ function ControlGrid({
18855
19111
  className
18856
19112
  }) {
18857
19113
  const eventBus = useEventBus();
18858
- const [active, setActive] = React74.useState(/* @__PURE__ */ new Set());
18859
- const handlePress = React74.useCallback(
19114
+ const [active, setActive] = React75.useState(/* @__PURE__ */ new Set());
19115
+ const handlePress = React75.useCallback(
18860
19116
  (id) => {
18861
19117
  setActive((prev) => new Set(prev).add(id));
18862
19118
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -18870,7 +19126,7 @@ function ControlGrid({
18870
19126
  },
18871
19127
  [kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
18872
19128
  );
18873
- const handleRelease = React74.useCallback(
19129
+ const handleRelease = React75.useCallback(
18874
19130
  (id) => {
18875
19131
  setActive((prev) => {
18876
19132
  const next = new Set(prev);
@@ -20108,8 +20364,8 @@ var init_Menu = __esm({
20108
20364
  "bottom-end": "bottom-start"
20109
20365
  };
20110
20366
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
20111
- const triggerChild = React74__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
20112
- const triggerElement = React74__default.cloneElement(
20367
+ const triggerChild = React75__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
20368
+ const triggerElement = React75__default.cloneElement(
20113
20369
  triggerChild,
20114
20370
  {
20115
20371
  ref: triggerRef,
@@ -20204,14 +20460,14 @@ function useDataDnd(args) {
20204
20460
  const isZone = Boolean(dragGroup || accepts || sortable);
20205
20461
  const enabled = isZone || Boolean(dndRoot);
20206
20462
  const eventBus = useEventBus();
20207
- const parentRoot = React74__default.useContext(RootCtx);
20463
+ const parentRoot = React75__default.useContext(RootCtx);
20208
20464
  const isRoot = enabled && parentRoot === null;
20209
- const zoneId = React74__default.useId();
20465
+ const zoneId = React75__default.useId();
20210
20466
  const ownGroup = dragGroup ?? accepts ?? zoneId;
20211
- const [optimisticOrders, setOptimisticOrders] = React74__default.useState(() => /* @__PURE__ */ new Map());
20212
- const optimisticOrdersRef = React74__default.useRef(optimisticOrders);
20467
+ const [optimisticOrders, setOptimisticOrders] = React75__default.useState(() => /* @__PURE__ */ new Map());
20468
+ const optimisticOrdersRef = React75__default.useRef(optimisticOrders);
20213
20469
  optimisticOrdersRef.current = optimisticOrders;
20214
- const clearOptimisticOrder = React74__default.useCallback((group) => {
20470
+ const clearOptimisticOrder = React75__default.useCallback((group) => {
20215
20471
  setOptimisticOrders((prev) => {
20216
20472
  if (!prev.has(group)) return prev;
20217
20473
  const next = new Map(prev);
@@ -20236,7 +20492,7 @@ function useDataDnd(args) {
20236
20492
  const raw = it[dndItemIdField];
20237
20493
  return raw != null ? String(raw) : `__idx_${idx}`;
20238
20494
  }).join("|");
20239
- const itemIds = React74__default.useMemo(
20495
+ const itemIds = React75__default.useMemo(
20240
20496
  () => orderedItems.map((it, idx) => {
20241
20497
  const raw = it[dndItemIdField];
20242
20498
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -20247,7 +20503,7 @@ function useDataDnd(args) {
20247
20503
  const raw = it[dndItemIdField];
20248
20504
  return raw != null ? String(raw) : `__${idx}`;
20249
20505
  }).join("|");
20250
- React74__default.useEffect(() => {
20506
+ React75__default.useEffect(() => {
20251
20507
  const root = isRoot ? null : parentRoot;
20252
20508
  if (root) {
20253
20509
  root.clearOptimisticOrder(ownGroup);
@@ -20255,20 +20511,20 @@ function useDataDnd(args) {
20255
20511
  clearOptimisticOrder(ownGroup);
20256
20512
  }
20257
20513
  }, [itemsContentSig, ownGroup]);
20258
- const zonesRef = React74__default.useRef(/* @__PURE__ */ new Map());
20259
- const registerZone = React74__default.useCallback((zoneId2, meta2) => {
20514
+ const zonesRef = React75__default.useRef(/* @__PURE__ */ new Map());
20515
+ const registerZone = React75__default.useCallback((zoneId2, meta2) => {
20260
20516
  zonesRef.current.set(zoneId2, meta2);
20261
20517
  }, []);
20262
- const unregisterZone = React74__default.useCallback((zoneId2) => {
20518
+ const unregisterZone = React75__default.useCallback((zoneId2) => {
20263
20519
  zonesRef.current.delete(zoneId2);
20264
20520
  }, []);
20265
- const [activeDrag, setActiveDrag] = React74__default.useState(null);
20266
- const [overZoneGroup, setOverZoneGroup] = React74__default.useState(null);
20267
- const meta = React74__default.useMemo(
20521
+ const [activeDrag, setActiveDrag] = React75__default.useState(null);
20522
+ const [overZoneGroup, setOverZoneGroup] = React75__default.useState(null);
20523
+ const meta = React75__default.useMemo(
20268
20524
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
20269
20525
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
20270
20526
  );
20271
- React74__default.useEffect(() => {
20527
+ React75__default.useEffect(() => {
20272
20528
  const target = isRoot ? null : parentRoot;
20273
20529
  if (!target) {
20274
20530
  zonesRef.current.set(zoneId, meta);
@@ -20287,7 +20543,7 @@ function useDataDnd(args) {
20287
20543
  }, [parentRoot, isRoot, zoneId, meta]);
20288
20544
  const sensors = useAlmadarDndSensors(true);
20289
20545
  const collisionDetection = almadarDndCollisionDetection;
20290
- const findZoneByItem = React74__default.useCallback(
20546
+ const findZoneByItem = React75__default.useCallback(
20291
20547
  (id) => {
20292
20548
  for (const z of zonesRef.current.values()) {
20293
20549
  if (z.itemIds.includes(id)) return z;
@@ -20296,7 +20552,7 @@ function useDataDnd(args) {
20296
20552
  },
20297
20553
  []
20298
20554
  );
20299
- React74__default.useCallback(
20555
+ React75__default.useCallback(
20300
20556
  (group) => {
20301
20557
  for (const z of zonesRef.current.values()) {
20302
20558
  if (z.group === group) return z;
@@ -20305,7 +20561,7 @@ function useDataDnd(args) {
20305
20561
  },
20306
20562
  []
20307
20563
  );
20308
- const handleDragEnd = React74__default.useCallback(
20564
+ const handleDragEnd = React75__default.useCallback(
20309
20565
  (event) => {
20310
20566
  const { active, over } = event;
20311
20567
  const activeIdStr = String(active.id);
@@ -20396,8 +20652,8 @@ function useDataDnd(args) {
20396
20652
  },
20397
20653
  [eventBus]
20398
20654
  );
20399
- const sortableData = React74__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
20400
- const SortableItem = React74__default.useCallback(
20655
+ const sortableData = React75__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
20656
+ const SortableItem = React75__default.useCallback(
20401
20657
  ({ id, children }) => {
20402
20658
  const {
20403
20659
  attributes,
@@ -20437,7 +20693,7 @@ function useDataDnd(args) {
20437
20693
  id: droppableId,
20438
20694
  data: sortableData
20439
20695
  });
20440
- const ctx = React74__default.useContext(RootCtx);
20696
+ const ctx = React75__default.useContext(RootCtx);
20441
20697
  const activeDrag2 = ctx?.activeDrag ?? null;
20442
20698
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
20443
20699
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -20452,7 +20708,7 @@ function useDataDnd(args) {
20452
20708
  showForeignPlaceholder,
20453
20709
  ctxAvailable: ctx != null
20454
20710
  });
20455
- React74__default.useEffect(() => {
20711
+ React75__default.useEffect(() => {
20456
20712
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
20457
20713
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
20458
20714
  return /* @__PURE__ */ jsx(
@@ -20466,11 +20722,11 @@ function useDataDnd(args) {
20466
20722
  }
20467
20723
  );
20468
20724
  };
20469
- const rootContextValue = React74__default.useMemo(
20725
+ const rootContextValue = React75__default.useMemo(
20470
20726
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
20471
20727
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
20472
20728
  );
20473
- const handleDragStart = React74__default.useCallback((event) => {
20729
+ const handleDragStart = React75__default.useCallback((event) => {
20474
20730
  const sourceZone = findZoneByItem(event.active.id);
20475
20731
  const rect = event.active.rect.current.initial;
20476
20732
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -20489,7 +20745,7 @@ function useDataDnd(args) {
20489
20745
  isRoot
20490
20746
  });
20491
20747
  }, [findZoneByItem, isRoot, zoneId]);
20492
- const handleDragOver = React74__default.useCallback((event) => {
20748
+ const handleDragOver = React75__default.useCallback((event) => {
20493
20749
  const { active, over } = event;
20494
20750
  const overData = over?.data?.current;
20495
20751
  const overGroup = overData?.dndGroup ?? null;
@@ -20559,7 +20815,7 @@ function useDataDnd(args) {
20559
20815
  return next;
20560
20816
  });
20561
20817
  }, []);
20562
- const handleDragCancel = React74__default.useCallback((event) => {
20818
+ const handleDragCancel = React75__default.useCallback((event) => {
20563
20819
  setActiveDrag(null);
20564
20820
  setOverZoneGroup(null);
20565
20821
  dndLog.warn("dragCancel", {
@@ -20567,12 +20823,12 @@ function useDataDnd(args) {
20567
20823
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
20568
20824
  });
20569
20825
  }, []);
20570
- const handleDragEndWithCleanup = React74__default.useCallback((event) => {
20826
+ const handleDragEndWithCleanup = React75__default.useCallback((event) => {
20571
20827
  handleDragEnd(event);
20572
20828
  setActiveDrag(null);
20573
20829
  setOverZoneGroup(null);
20574
20830
  }, [handleDragEnd]);
20575
- const wrapContainer = React74__default.useCallback(
20831
+ const wrapContainer = React75__default.useCallback(
20576
20832
  (children) => {
20577
20833
  if (!enabled) return children;
20578
20834
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -20626,7 +20882,7 @@ var init_useDataDnd = __esm({
20626
20882
  init_useAlmadarDndCollision();
20627
20883
  init_Box();
20628
20884
  dndLog = createLogger("almadar:ui:dnd");
20629
- RootCtx = React74__default.createContext(null);
20885
+ RootCtx = React75__default.createContext(null);
20630
20886
  }
20631
20887
  });
20632
20888
  function renderIconInput(icon, props) {
@@ -21153,6 +21409,8 @@ function DataList({
21153
21409
  hasMore,
21154
21410
  children,
21155
21411
  pageSize = 5,
21412
+ sortBy,
21413
+ sortDirection,
21156
21414
  renderItem: schemaRenderItem,
21157
21415
  dragGroup,
21158
21416
  accepts,
@@ -21166,7 +21424,7 @@ function DataList({
21166
21424
  }) {
21167
21425
  const eventBus = useEventBus();
21168
21426
  const { t } = useTranslate();
21169
- const [visibleCount, setVisibleCount] = React74__default.useState(pageSize || Infinity);
21427
+ const [visibleCount, setVisibleCount] = React75__default.useState(pageSize || Infinity);
21170
21428
  const fieldDefs = fields ?? columns ?? [];
21171
21429
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
21172
21430
  const dnd = useDataDnd({
@@ -21181,11 +21439,15 @@ function DataList({
21181
21439
  dndItemIdField,
21182
21440
  dndRoot
21183
21441
  });
21184
- const allData = dnd.orderedItems;
21442
+ const orderedData = dnd.orderedItems;
21443
+ const allData = React75__default.useMemo(
21444
+ () => sortRows(orderedData, sortBy, sortDirection),
21445
+ [orderedData, sortBy, sortDirection]
21446
+ );
21185
21447
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
21186
21448
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
21187
21449
  const hasRenderProp = typeof children === "function";
21188
- React74__default.useEffect(() => {
21450
+ React75__default.useEffect(() => {
21189
21451
  const renderItemTypeOf = typeof schemaRenderItem;
21190
21452
  const childrenTypeOf = typeof children;
21191
21453
  if (data.length > 0 && !hasRenderProp) {
@@ -21218,7 +21480,7 @@ function DataList({
21218
21480
  };
21219
21481
  eventBus.emit(`UI:${action.event}`, payload);
21220
21482
  };
21221
- const renderItemActions = (itemData) => {
21483
+ const renderItemActions = (itemData, onPrimary = false) => {
21222
21484
  if (!itemActions || itemActions.length === 0) return null;
21223
21485
  const inline = maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions;
21224
21486
  const overflow = maxInlineActions != null ? itemActions.slice(maxInlineActions) : [];
@@ -21231,7 +21493,12 @@ function DataList({
21231
21493
  onClick: handleActionClick(action, itemData),
21232
21494
  "data-testid": `action-${action.event}`,
21233
21495
  "data-row-id": String(itemData.id),
21234
- className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
21496
+ className: cn(
21497
+ action.variant === "danger" && "text-error hover:bg-error/10",
21498
+ // Must sit on the Button itself: the variant's own text colour
21499
+ // beats an inherited one from the row wrapper.
21500
+ onPrimary && "!text-primary-foreground hover:bg-primary-foreground/15"
21501
+ ),
21235
21502
  children: [
21236
21503
  action.icon && renderIconInput2(action.icon, { size: "xs", className: "mr-1" }),
21237
21504
  action.label
@@ -21295,7 +21562,7 @@ function DataList({
21295
21562
  return v === void 0 || v === null || v === "" ? raw : String(v);
21296
21563
  };
21297
21564
  return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn("py-2", className), children: [
21298
- groups2.map((group, gi) => /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
21565
+ groups2.map((group, gi) => /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
21299
21566
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
21300
21567
  group.items.map((itemData, index) => {
21301
21568
  const id = itemData.id || `${gi}-${index}`;
@@ -21331,7 +21598,11 @@ function DataList({
21331
21598
  metaFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "mt-1 flex-wrap", children: metaFields.map((f3) => {
21332
21599
  const v = getNestedValue(itemData, f3.name);
21333
21600
  if (v === void 0 || v === null || v === "") return null;
21334
- return f3.variant === "badge" ? /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(v)), children: String(v) }, f3.name) : /* @__PURE__ */ jsx(
21601
+ return f3.variant === "badge" ? (
21602
+ // `format` applies here too — a boolean field badged
21603
+ // without it renders the raw "false" instead of "No".
21604
+ /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format) }, f3.name)
21605
+ ) : /* @__PURE__ */ jsx(
21335
21606
  Typography,
21336
21607
  {
21337
21608
  variant: "caption",
@@ -21350,7 +21621,7 @@ function DataList({
21350
21621
  children: formatDate(timestamp)
21351
21622
  }
21352
21623
  ) : /* @__PURE__ */ jsx("span", {}),
21353
- renderItemActions(itemData)
21624
+ renderItemActions(itemData, isSent)
21354
21625
  ] })
21355
21626
  ]
21356
21627
  }
@@ -21443,7 +21714,7 @@ function DataList({
21443
21714
  if (val === void 0 || val === null) return null;
21444
21715
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
21445
21716
  field.icon && renderIconInput2(field.icon, { size: "xs" }),
21446
- /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children: String(val) })
21717
+ /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format) })
21447
21718
  ] }, field.name);
21448
21719
  })
21449
21720
  ] }),
@@ -21490,7 +21761,7 @@ function DataList({
21490
21761
  className
21491
21762
  ),
21492
21763
  children: [
21493
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
21764
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
21494
21765
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
21495
21766
  group.items.map(
21496
21767
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -21599,8 +21870,8 @@ function ScalarControl({
21599
21870
  }
21600
21871
  const numeric = typeof value === "number";
21601
21872
  const initial = value === null ? "" : String(value);
21602
- const [draft, setDraft] = React74__default.useState(initial);
21603
- React74__default.useEffect(() => setDraft(initial), [initial]);
21873
+ const [draft, setDraft] = React75__default.useState(initial);
21874
+ React75__default.useEffect(() => setDraft(initial), [initial]);
21604
21875
  const commit = () => {
21605
21876
  if (numeric) {
21606
21877
  const n = draft.trim() === "" ? 0 : Number(draft);
@@ -21668,8 +21939,8 @@ function Row({
21668
21939
  onRemove,
21669
21940
  readonly
21670
21941
  }) {
21671
- const [keyDraft, setKeyDraft] = React74__default.useState(rowKey);
21672
- React74__default.useEffect(() => setKeyDraft(rowKey), [rowKey]);
21942
+ const [keyDraft, setKeyDraft] = React75__default.useState(rowKey);
21943
+ React75__default.useEffect(() => setKeyDraft(rowKey), [rowKey]);
21673
21944
  const container = isObj(value) || isArr(value);
21674
21945
  return /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "group w-max min-w-full", children: [
21675
21946
  /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", className: "py-0.5 w-max", children: [
@@ -21712,7 +21983,7 @@ function ContainerNode({
21712
21983
  depth,
21713
21984
  readonly
21714
21985
  }) {
21715
- const [open, setOpen] = React74__default.useState(depth < 2);
21986
+ const [open, setOpen] = React75__default.useState(depth < 2);
21716
21987
  const array = isArr(value);
21717
21988
  const entries = array ? value.map((v, i) => [String(i), v]) : Object.entries(value);
21718
21989
  const setObjValue = (key, next) => {
@@ -21854,7 +22125,7 @@ var init_FormSection = __esm({
21854
22125
  columns = 1,
21855
22126
  className
21856
22127
  }) => {
21857
- const [collapsed, setCollapsed] = React74__default.useState(defaultCollapsed);
22128
+ const [collapsed, setCollapsed] = React75__default.useState(defaultCollapsed);
21858
22129
  const { t } = useTranslate();
21859
22130
  const eventBus = useEventBus();
21860
22131
  const gridClass = {
@@ -21862,7 +22133,7 @@ var init_FormSection = __esm({
21862
22133
  2: "grid-cols-1 md:grid-cols-2",
21863
22134
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
21864
22135
  }[columns];
21865
- React74__default.useCallback(() => {
22136
+ React75__default.useCallback(() => {
21866
22137
  if (collapsible) {
21867
22138
  setCollapsed((prev) => !prev);
21868
22139
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -21994,7 +22265,7 @@ var init_GridPicker = __esm({
21994
22265
  const needle = search.trim().toLowerCase();
21995
22266
  return items.filter((item) => {
21996
22267
  const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
21997
- const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle);
22268
+ const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle) || item.keywords !== void 0 && item.keywords.some((k) => k.toLowerCase().includes(needle));
21998
22269
  return matchesCategory && matchesSearch;
21999
22270
  });
22000
22271
  }, [items, search, activeCategory]);
@@ -22270,8 +22541,8 @@ function TextLikeControl({
22270
22541
  onCommit
22271
22542
  }) {
22272
22543
  const initial = value === void 0 || value === null ? "" : String(value);
22273
- const [draft, setDraft] = React74__default.useState(initial);
22274
- React74__default.useEffect(() => setDraft(initial), [initial]);
22544
+ const [draft, setDraft] = React75__default.useState(initial);
22545
+ React75__default.useEffect(() => setDraft(initial), [initial]);
22275
22546
  const commit = () => {
22276
22547
  if (numeric) {
22277
22548
  const n = draft.trim() === "" ? 0 : Number(draft);
@@ -22456,14 +22727,14 @@ var init_NodeSlotEditor = __esm({
22456
22727
  isObj2 = (v) => v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
22457
22728
  NodeSlotEditor = ({ value, onChange, className }) => {
22458
22729
  const { type, props, wasArray } = normalize(value);
22459
- const patterns = React74__default.useMemo(() => {
22730
+ const patterns = React75__default.useMemo(() => {
22460
22731
  try {
22461
22732
  return [...getKnownPatterns()].sort();
22462
22733
  } catch {
22463
22734
  return [];
22464
22735
  }
22465
22736
  }, []);
22466
- const options = React74__default.useMemo(
22737
+ const options = React75__default.useMemo(
22467
22738
  () => [{ value: "", label: "\u2014 none \u2014" }, ...patterns.map((p) => ({ value: p, label: p }))],
22468
22739
  [patterns]
22469
22740
  );
@@ -22475,7 +22746,7 @@ var init_NodeSlotEditor = __esm({
22475
22746
  const pattern = { type: nextType, ...nextProps };
22476
22747
  onChange(wasArray || value === void 0 ? [pattern] : pattern);
22477
22748
  };
22478
- const schemaEntries = React74__default.useMemo(() => {
22749
+ const schemaEntries = React75__default.useMemo(() => {
22479
22750
  if (!type) return [];
22480
22751
  const def = getPatternDefinition(type);
22481
22752
  if (!def?.propsSchema) return [];
@@ -23296,7 +23567,7 @@ var init_Flex = __esm({
23296
23567
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
23297
23568
  }
23298
23569
  }
23299
- return React74__default.createElement(Component, {
23570
+ return React75__default.createElement(Component, {
23300
23571
  className: cn(
23301
23572
  inline ? "inline-flex" : "flex",
23302
23573
  directionStyles[direction],
@@ -23415,7 +23686,7 @@ var init_Grid = __esm({
23415
23686
  as: Component = "div"
23416
23687
  }) => {
23417
23688
  const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
23418
- return React74__default.createElement(
23689
+ return React75__default.createElement(
23419
23690
  Component,
23420
23691
  {
23421
23692
  className: cn(
@@ -23552,9 +23823,16 @@ var init_Popover = __esm({
23552
23823
  position = "bottom",
23553
23824
  trigger = "click",
23554
23825
  showArrow = true,
23826
+ open,
23827
+ onOpenChange,
23555
23828
  className
23556
23829
  }) => {
23557
- const [isOpen, setIsOpen] = useState(false);
23830
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
23831
+ const isOpen = open !== void 0 ? open : uncontrolledOpen;
23832
+ const setIsOpen = (next) => {
23833
+ if (open === void 0) setUncontrolledOpen(next);
23834
+ onOpenChange?.(next);
23835
+ };
23558
23836
  const [triggerRect, setTriggerRect] = useState(null);
23559
23837
  const [popoverWidth, setPopoverWidth] = useState(0);
23560
23838
  const triggerRef = useRef(null);
@@ -23587,6 +23865,23 @@ var init_Popover = __esm({
23587
23865
  updatePosition();
23588
23866
  }
23589
23867
  }, [isOpen]);
23868
+ useEffect(() => {
23869
+ if (!isOpen) return;
23870
+ let raf = 0;
23871
+ let lastTop = Number.NaN;
23872
+ let lastLeft = Number.NaN;
23873
+ const track = () => {
23874
+ const rect = triggerRef.current?.getBoundingClientRect();
23875
+ if (rect && (rect.top !== lastTop || rect.left !== lastLeft)) {
23876
+ lastTop = rect.top;
23877
+ lastLeft = rect.left;
23878
+ updatePosition();
23879
+ }
23880
+ raf = requestAnimationFrame(track);
23881
+ };
23882
+ raf = requestAnimationFrame(track);
23883
+ return () => cancelAnimationFrame(raf);
23884
+ }, [isOpen]);
23590
23885
  useEffect(() => {
23591
23886
  if (!mounted) setPopoverWidth(0);
23592
23887
  }, [mounted]);
@@ -23623,9 +23918,9 @@ var init_Popover = __esm({
23623
23918
  onMouseLeave: handleClose,
23624
23919
  onPointerDown: tapTriggerProps.onPointerDown
23625
23920
  };
23626
- const childElement = React74__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
23921
+ const childElement = React75__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
23627
23922
  const childPointerDown = childElement.props.onPointerDown;
23628
- const triggerElement = React74__default.cloneElement(
23923
+ const triggerElement = React75__default.cloneElement(
23629
23924
  childElement,
23630
23925
  {
23631
23926
  ref: triggerRef,
@@ -24484,9 +24779,9 @@ var init_Tooltip = __esm({
24484
24779
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
24485
24780
  };
24486
24781
  }, []);
24487
- const triggerElement = React74__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
24782
+ const triggerElement = React75__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
24488
24783
  const childPointerDown = triggerElement.props.onPointerDown;
24489
- const trigger = React74__default.cloneElement(triggerElement, {
24784
+ const trigger = React75__default.cloneElement(triggerElement, {
24490
24785
  ref: triggerRef,
24491
24786
  onMouseEnter: handleMouseEnter,
24492
24787
  onMouseLeave: handleMouseLeave,
@@ -24576,7 +24871,7 @@ var init_WizardProgress = __esm({
24576
24871
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
24577
24872
  const isActive = index === currentStep;
24578
24873
  const isCompleted = index < currentStep;
24579
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
24874
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
24580
24875
  /* @__PURE__ */ jsx(
24581
24876
  "button",
24582
24877
  {
@@ -25185,6 +25480,80 @@ var init_FlipCard = __esm({
25185
25480
  FlipCard.displayName = "FlipCard";
25186
25481
  }
25187
25482
  });
25483
+ var EMOJI_ITEMS, EmojiPicker;
25484
+ var init_EmojiPicker = __esm({
25485
+ "components/core/molecules/EmojiPicker.tsx"() {
25486
+ "use client";
25487
+ init_useEventBus();
25488
+ init_Button();
25489
+ init_GridPicker();
25490
+ init_Popover();
25491
+ EMOJI_ITEMS = (() => {
25492
+ const items = [];
25493
+ for (const name of ordered) {
25494
+ const entry = lib[name];
25495
+ if (entry === void 0 || entry.char === null || entry.char === "") continue;
25496
+ items.push({
25497
+ id: entry.char,
25498
+ label: name.replace(/_/g, " "),
25499
+ category: entry.category.replace(/_/g, " "),
25500
+ keywords: entry.keywords
25501
+ });
25502
+ }
25503
+ return items;
25504
+ })();
25505
+ EmojiPicker = ({
25506
+ pickEvent,
25507
+ position = "top",
25508
+ triggerIcon = "smile",
25509
+ triggerLabel = "Add emoji",
25510
+ className
25511
+ }) => {
25512
+ const eventBus = useEventBus();
25513
+ const [open, setOpen] = useState(false);
25514
+ const handlePick = (glyph) => {
25515
+ if (pickEvent !== void 0) {
25516
+ const payload = { emoji: glyph };
25517
+ eventBus.emit(`UI:${pickEvent}`, payload);
25518
+ }
25519
+ setOpen(false);
25520
+ };
25521
+ return /* @__PURE__ */ jsx(
25522
+ Popover,
25523
+ {
25524
+ position,
25525
+ trigger: "click",
25526
+ showArrow: false,
25527
+ open,
25528
+ onOpenChange: setOpen,
25529
+ content: /* @__PURE__ */ jsx(
25530
+ GridPicker,
25531
+ {
25532
+ items: EMOJI_ITEMS,
25533
+ onChange: handlePick,
25534
+ searchPlaceholder: "Search emoji\u2026",
25535
+ renderThumbnail: (item) => /* @__PURE__ */ jsx("span", { className: "text-xl leading-none", "aria-hidden": "true", children: item.id }),
25536
+ cellSize: 32,
25537
+ className: "w-80"
25538
+ }
25539
+ ),
25540
+ children: /* @__PURE__ */ jsx(
25541
+ Button,
25542
+ {
25543
+ variant: "ghost",
25544
+ icon: triggerIcon,
25545
+ "aria-label": triggerLabel,
25546
+ title: triggerLabel,
25547
+ className,
25548
+ "data-testid": "emoji-picker-trigger"
25549
+ }
25550
+ )
25551
+ }
25552
+ );
25553
+ };
25554
+ EmojiPicker.displayName = "EmojiPicker";
25555
+ }
25556
+ });
25188
25557
  function toISODate(d) {
25189
25558
  return d.toISOString().slice(0, 10);
25190
25559
  }
@@ -26118,210 +26487,6 @@ var init_DialogueBubble = __esm({
26118
26487
  DialogueBubble.displayName = "DialogueBubble";
26119
26488
  }
26120
26489
  });
26121
- function SvgStage({
26122
- cols,
26123
- rows: rows2,
26124
- tileSize = 32,
26125
- background = "var(--color-background)",
26126
- tileClickEvent,
26127
- tileHoverEvent,
26128
- tileLeaveEvent,
26129
- keyMap,
26130
- keyUpMap,
26131
- className,
26132
- children
26133
- }) {
26134
- const eventBus = useEventBus();
26135
- const svgRef = useRef(null);
26136
- const pointerDownRef = useRef(null);
26137
- const cellFromClient = useCallback((clientX, clientY) => {
26138
- const svg = svgRef.current;
26139
- if (!svg) return null;
26140
- const rect = svg.getBoundingClientRect();
26141
- if (rect.width === 0 || rect.height === 0) return null;
26142
- const vbW = cols * tileSize;
26143
- const vbH = rows2 * tileSize;
26144
- const meet = Math.min(rect.width / vbW, rect.height / vbH);
26145
- const offsetX = (rect.width - vbW * meet) / 2;
26146
- const offsetY = (rect.height - vbH * meet) / 2;
26147
- const svgX = (clientX - rect.left - offsetX) / meet;
26148
- const svgY = (clientY - rect.top - offsetY) / meet;
26149
- return {
26150
- x: Math.min(Math.max(Math.floor(svgX / tileSize), 0), cols - 1),
26151
- y: Math.min(Math.max(Math.floor(svgY / tileSize), 0), rows2 - 1)
26152
- };
26153
- }, [cols, rows2, tileSize]);
26154
- const handlePointerDown = useCallback((e) => {
26155
- pointerDownRef.current = { clientX: e.clientX, clientY: e.clientY };
26156
- }, []);
26157
- const handlePointerUp = useCallback((e) => {
26158
- const down = pointerDownRef.current;
26159
- pointerDownRef.current = null;
26160
- if (!tileClickEvent) return;
26161
- if (down && Math.hypot(e.clientX - down.clientX, e.clientY - down.clientY) > 5) return;
26162
- const cell = cellFromClient(e.clientX, e.clientY);
26163
- if (cell) eventBus.emit(`UI:${tileClickEvent}`, cell);
26164
- }, [cellFromClient, tileClickEvent, eventBus]);
26165
- const handlePointerMove = useCallback((e) => {
26166
- if (!tileHoverEvent) return;
26167
- const cell = cellFromClient(e.clientX, e.clientY);
26168
- if (cell) eventBus.emit(`UI:${tileHoverEvent}`, cell);
26169
- }, [cellFromClient, tileHoverEvent, eventBus]);
26170
- const handlePointerLeave = useCallback(() => {
26171
- pointerDownRef.current = null;
26172
- if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
26173
- }, [tileLeaveEvent, eventBus]);
26174
- useEffect(() => {
26175
- if (!keyMap && !keyUpMap) return;
26176
- const onDown = (e) => {
26177
- const ev = keyMap?.[e.code];
26178
- if (ev) {
26179
- eventBus.emit(`UI:${ev}`, {});
26180
- e.preventDefault();
26181
- }
26182
- };
26183
- const onUp = (e) => {
26184
- const ev = keyUpMap?.[e.code];
26185
- if (ev) eventBus.emit(`UI:${ev}`, {});
26186
- };
26187
- window.addEventListener("keydown", onDown);
26188
- window.addEventListener("keyup", onUp);
26189
- return () => {
26190
- window.removeEventListener("keydown", onDown);
26191
- window.removeEventListener("keyup", onUp);
26192
- };
26193
- }, [keyMap, keyUpMap, eventBus]);
26194
- useEffect(() => {
26195
- if (!keyMap && !keyUpMap) return;
26196
- svgRef.current?.focus();
26197
- }, [keyMap, keyUpMap]);
26198
- const stageContext = useMemo(() => ({ tileSize }), [tileSize]);
26199
- return /* @__PURE__ */ jsxs(
26200
- "svg",
26201
- {
26202
- ref: svgRef,
26203
- "data-testid": "svg-stage",
26204
- viewBox: `0 0 ${cols * tileSize} ${rows2 * tileSize}`,
26205
- preserveAspectRatio: "xMidYMid meet",
26206
- className: cn("block h-full w-full", className),
26207
- tabIndex: keyMap || keyUpMap ? 0 : void 0,
26208
- onPointerDown: handlePointerDown,
26209
- onPointerMove: handlePointerMove,
26210
- onPointerUp: handlePointerUp,
26211
- onPointerLeave: handlePointerLeave,
26212
- children: [
26213
- /* @__PURE__ */ jsx("rect", { width: cols * tileSize, height: rows2 * tileSize, fill: background }),
26214
- /* @__PURE__ */ jsx(SvgStageContext.Provider, { value: stageContext, children })
26215
- ]
26216
- }
26217
- );
26218
- }
26219
- var SvgStageContext;
26220
- var init_SvgStage = __esm({
26221
- "components/game/molecules/SvgStage.tsx"() {
26222
- "use client";
26223
- init_cn();
26224
- init_useEventBus();
26225
- SvgStageContext = React74.createContext({ tileSize: 1 });
26226
- SvgStage.displayName = "SvgStage";
26227
- }
26228
- });
26229
- function SvgDrawShape({
26230
- shape,
26231
- x,
26232
- y,
26233
- width,
26234
- height,
26235
- radius,
26236
- radiusY,
26237
- points,
26238
- d,
26239
- x2,
26240
- y2,
26241
- fill,
26242
- stroke,
26243
- strokeWidth,
26244
- opacity,
26245
- className
26246
- }) {
26247
- const { tileSize } = useContext(SvgStageContext);
26248
- const cell = (v) => v === void 0 ? void 0 : v * tileSize;
26249
- const paint = {
26250
- fill: fill ?? (stroke === void 0 ? "var(--color-primary)" : "none"),
26251
- stroke,
26252
- strokeWidth,
26253
- opacity,
26254
- className
26255
- };
26256
- return /* @__PURE__ */ jsxs("g", { transform: `translate(${x * tileSize} ${y * tileSize})`, children: [
26257
- shape === "rect" && /* @__PURE__ */ jsx("rect", { width: cell(width), height: cell(height), ...paint }),
26258
- shape === "circle" && /* @__PURE__ */ jsx("circle", { r: cell(radius), ...paint }),
26259
- shape === "ellipse" && /* @__PURE__ */ jsx("ellipse", { rx: cell(radius), ry: cell(radiusY ?? radius), ...paint }),
26260
- shape === "polygon" && /* @__PURE__ */ jsx("polygon", { points, ...paint }),
26261
- shape === "polyline" && /* @__PURE__ */ jsx("polyline", { points, ...paint }),
26262
- shape === "path" && /* @__PURE__ */ jsx("path", { d, ...paint }),
26263
- shape === "line" && /* @__PURE__ */ jsx("line", { x2: cell(x2), y2: cell(y2), ...paint })
26264
- ] });
26265
- }
26266
- var init_SvgDrawShape = __esm({
26267
- "components/game/atoms/SvgDrawShape.tsx"() {
26268
- "use client";
26269
- init_SvgStage();
26270
- SvgDrawShape.displayName = "SvgDrawShape";
26271
- }
26272
- });
26273
- function SvgDrawGroup({
26274
- x = 0,
26275
- y = 0,
26276
- scale,
26277
- rotate,
26278
- opacity,
26279
- className,
26280
- children
26281
- }) {
26282
- const { tileSize } = useContext(SvgStageContext);
26283
- const transforms = [`translate(${x * tileSize} ${y * tileSize})`];
26284
- if (rotate !== void 0) transforms.push(`rotate(${rotate})`);
26285
- if (scale !== void 0) transforms.push(`scale(${scale})`);
26286
- return /* @__PURE__ */ jsx("g", { transform: transforms.join(" "), opacity, className, children });
26287
- }
26288
- var init_SvgDrawGroup = __esm({
26289
- "components/game/atoms/SvgDrawGroup.tsx"() {
26290
- "use client";
26291
- init_SvgStage();
26292
- SvgDrawGroup.displayName = "SvgDrawGroup";
26293
- }
26294
- });
26295
- function SvgDrawText({
26296
- x,
26297
- y,
26298
- text,
26299
- size = 12,
26300
- fill = "var(--color-foreground)",
26301
- anchor = "middle",
26302
- className
26303
- }) {
26304
- const { tileSize } = useContext(SvgStageContext);
26305
- return /* @__PURE__ */ jsx(
26306
- "text",
26307
- {
26308
- x: x * tileSize,
26309
- y: y * tileSize,
26310
- fontSize: size,
26311
- fill,
26312
- textAnchor: anchor,
26313
- className,
26314
- children: text
26315
- }
26316
- );
26317
- }
26318
- var init_SvgDrawText = __esm({
26319
- "components/game/atoms/SvgDrawText.tsx"() {
26320
- "use client";
26321
- init_SvgStage();
26322
- SvgDrawText.displayName = "SvgDrawText";
26323
- }
26324
- });
26325
26490
  function StatBadge({
26326
26491
  assetUrl,
26327
26492
  iconUrl,
@@ -26517,7 +26682,7 @@ function GameMenu({
26517
26682
  }) {
26518
26683
  const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
26519
26684
  const eventBus = useEventBus();
26520
- const handleOptionClick = React74.useCallback(
26685
+ const handleOptionClick = React75.useCallback(
26521
26686
  (option) => {
26522
26687
  if (option.event) {
26523
26688
  eventBus.emit(`UI:${option.event}`, { option });
@@ -26753,7 +26918,7 @@ function StateGraph({
26753
26918
  }) {
26754
26919
  const eventBus = useEventBus();
26755
26920
  const nodes = states ?? [];
26756
- const positions = React74.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
26921
+ const positions = React75.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
26757
26922
  return /* @__PURE__ */ jsxs(
26758
26923
  Box,
26759
26924
  {
@@ -26812,32 +26977,6 @@ var init_StateGraph = __esm({
26812
26977
  init_TransitionArrow();
26813
26978
  }
26814
26979
  });
26815
- function SvgDrawShapeLayer({
26816
- items,
26817
- fill,
26818
- stroke,
26819
- strokeWidth,
26820
- opacity
26821
- }) {
26822
- return /* @__PURE__ */ jsx("g", { children: items.map(({ id, ...shape }) => /* @__PURE__ */ jsx(
26823
- SvgDrawShape,
26824
- {
26825
- ...shape,
26826
- fill: shape.fill ?? fill,
26827
- stroke: shape.stroke ?? stroke,
26828
- strokeWidth: shape.strokeWidth ?? strokeWidth,
26829
- opacity: shape.opacity ?? opacity
26830
- },
26831
- id
26832
- )) });
26833
- }
26834
- var init_SvgDrawShapeLayer = __esm({
26835
- "components/game/molecules/SvgDrawShapeLayer.tsx"() {
26836
- "use client";
26837
- init_SvgDrawShape();
26838
- SvgDrawShapeLayer.displayName = "SvgDrawShapeLayer";
26839
- }
26840
- });
26841
26980
  function unitAtlasUrl(unit) {
26842
26981
  return unit.spriteSheet?.url ?? null;
26843
26982
  }
@@ -27316,7 +27455,7 @@ function LinearView({
27316
27455
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
27317
27456
  const isDone = i < currentIdx;
27318
27457
  const isCurrent = i === currentIdx;
27319
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
27458
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
27320
27459
  i > 0 && /* @__PURE__ */ jsx(
27321
27460
  Typography,
27322
27461
  {
@@ -27949,7 +28088,7 @@ function SequenceBar({
27949
28088
  else onSlotRemove?.(index);
27950
28089
  }, [emit, slotRemoveEvent, onSlotRemove, playing]);
27951
28090
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
27952
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
28091
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
27953
28092
  i > 0 && /* @__PURE__ */ jsx(
27954
28093
  Typography,
27955
28094
  {
@@ -28305,9 +28444,6 @@ var init_molecules = __esm({
28305
28444
  init_TimerDisplay();
28306
28445
  init_DialogueBubble();
28307
28446
  init_ChoiceButton();
28308
- init_SvgDrawShape();
28309
- init_SvgDrawGroup();
28310
- init_SvgDrawText();
28311
28447
  init_ControlGrid();
28312
28448
  init_StatBadge();
28313
28449
  init_GameHud();
@@ -28315,8 +28451,6 @@ var init_molecules = __esm({
28315
28451
  init_StateGraph();
28316
28452
  init_Canvas2D();
28317
28453
  init_Canvas();
28318
- init_SvgDrawShapeLayer();
28319
- init_SvgStage();
28320
28454
  init_useUnitSpriteAtlas();
28321
28455
  init_GameAudioToggle();
28322
28456
  init_useGameAudio();
@@ -28934,13 +29068,13 @@ var init_MapView = __esm({
28934
29068
  shadowSize: [41, 41]
28935
29069
  });
28936
29070
  L.Marker.prototype.options.icon = defaultIcon;
28937
- const { useEffect: useEffect66, useRef: useRef64, useCallback: useCallback107, useState: useState102 } = React74__default;
29071
+ const { useEffect: useEffect65, useRef: useRef63, useCallback: useCallback106, useState: useState103 } = React75__default;
28938
29072
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
28939
29073
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
28940
29074
  function MapUpdater({ centerLat, centerLng, zoom }) {
28941
29075
  const map = useMap();
28942
- const prevRef = useRef64({ centerLat, centerLng, zoom });
28943
- useEffect66(() => {
29076
+ const prevRef = useRef63({ centerLat, centerLng, zoom });
29077
+ useEffect65(() => {
28944
29078
  const prev = prevRef.current;
28945
29079
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
28946
29080
  map.setView([centerLat, centerLng], zoom);
@@ -28951,7 +29085,7 @@ var init_MapView = __esm({
28951
29085
  }
28952
29086
  function MapClickHandler({ onMapClick }) {
28953
29087
  const map = useMap();
28954
- useEffect66(() => {
29088
+ useEffect65(() => {
28955
29089
  if (!onMapClick) return;
28956
29090
  const handler = (e) => {
28957
29091
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -28979,8 +29113,8 @@ var init_MapView = __esm({
28979
29113
  showAttribution = true
28980
29114
  }) {
28981
29115
  const eventBus = useEventBus2();
28982
- const [clickedPosition, setClickedPosition] = useState102(null);
28983
- const handleMapClick = useCallback107((lat, lng) => {
29116
+ const [clickedPosition, setClickedPosition] = useState103(null);
29117
+ const handleMapClick = useCallback106((lat, lng) => {
28984
29118
  if (showClickedPin) {
28985
29119
  setClickedPosition({ lat, lng });
28986
29120
  }
@@ -28989,7 +29123,7 @@ var init_MapView = __esm({
28989
29123
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
28990
29124
  }
28991
29125
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
28992
- const handleMarkerClick = useCallback107((marker) => {
29126
+ const handleMarkerClick = useCallback106((marker) => {
28993
29127
  onMarkerClick?.(marker);
28994
29128
  if (markerClickEvent) {
28995
29129
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -29824,6 +29958,7 @@ function TableView({
29824
29958
  fields,
29825
29959
  itemActions,
29826
29960
  maxInlineActions,
29961
+ itemClickEvent,
29827
29962
  selectable = false,
29828
29963
  selectEvent,
29829
29964
  selectedIds,
@@ -29851,8 +29986,8 @@ function TableView({
29851
29986
  }) {
29852
29987
  const eventBus = useEventBus();
29853
29988
  const { t } = useTranslate();
29854
- const [visibleCount, setVisibleCount] = React74__default.useState(pageSize > 0 ? pageSize : Infinity);
29855
- const [localSelected, setLocalSelected] = React74__default.useState(/* @__PURE__ */ new Set());
29989
+ const [visibleCount, setVisibleCount] = React75__default.useState(pageSize > 0 ? pageSize : Infinity);
29990
+ const [localSelected, setLocalSelected] = React75__default.useState(/* @__PURE__ */ new Set());
29856
29991
  const colDefs = (Array.isArray(columns) ? columns : void 0) ?? (Array.isArray(fields) ? fields : void 0) ?? [];
29857
29992
  const actionDefs = Array.isArray(itemActions) ? itemActions : [];
29858
29993
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
@@ -29868,13 +30003,13 @@ function TableView({
29868
30003
  dndItemIdField,
29869
30004
  dndRoot
29870
30005
  });
29871
- const ordered = dnd.orderedItems;
29872
- const data = pageSize > 0 ? ordered.slice(0, visibleCount) : ordered;
29873
- const hasMore = pageSize > 0 && visibleCount < ordered.length;
30006
+ const ordered2 = dnd.orderedItems;
30007
+ const data = pageSize > 0 ? ordered2.slice(0, visibleCount) : ordered2;
30008
+ const hasMore = pageSize > 0 && visibleCount < ordered2.length;
29874
30009
  const hasRenderProp = typeof children === "function";
29875
30010
  const idField = dndItemIdField ?? "id";
29876
30011
  const isCoarsePointer = useMediaQuery("(pointer: coarse)");
29877
- React74__default.useEffect(() => {
30012
+ React75__default.useEffect(() => {
29878
30013
  tableViewLog.debug("render", {
29879
30014
  rowCount: data.length,
29880
30015
  colCount: colDefs.length,
@@ -29923,7 +30058,15 @@ function TableView({
29923
30058
  };
29924
30059
  eventBus.emit(`UI:${action.event}`, payload);
29925
30060
  };
29926
- const colFloors = React74__default.useMemo(
30061
+ const handleRowClick = (row) => () => {
30062
+ if (!itemClickEvent) return;
30063
+ const payload = {
30064
+ id: row.id,
30065
+ row
30066
+ };
30067
+ eventBus.emit(`UI:${itemClickEvent}`, payload);
30068
+ };
30069
+ const colFloors = React75__default.useMemo(
29927
30070
  () => colDefs.map((col) => {
29928
30071
  const longest = data.reduce((widest, row) => {
29929
30072
  const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
@@ -29999,10 +30142,12 @@ function TableView({
29999
30142
  role: "row",
30000
30143
  "data-entity-row": true,
30001
30144
  "data-entity-id": id,
30145
+ onClick: itemClickEvent ? handleRowClick(row) : void 0,
30002
30146
  style: !hasRenderProp ? { gridTemplateColumns } : void 0,
30003
30147
  className: cn(
30004
30148
  "group items-center gap-3 transition-colors duration-fast",
30005
30149
  hasRenderProp ? "flex" : "grid",
30150
+ itemClickEvent && "cursor-pointer",
30006
30151
  lk.rowPad,
30007
30152
  lk.divider && "border-b border-[var(--color-border)]",
30008
30153
  lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
@@ -30010,7 +30155,7 @@ function TableView({
30010
30155
  look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
30011
30156
  ),
30012
30157
  children: [
30013
- selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsx(
30158
+ selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0, children: /* @__PURE__ */ jsx(
30014
30159
  Checkbox,
30015
30160
  {
30016
30161
  checked: selected.has(id),
@@ -30035,6 +30180,7 @@ function TableView({
30035
30180
  HStack,
30036
30181
  {
30037
30182
  gap: "xs",
30183
+ onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0,
30038
30184
  className: cn(
30039
30185
  // Pinned: the fixed column tracks routinely overflow the caller's
30040
30186
  // scroll container, which used to leave the actions off-screen.
@@ -30082,12 +30228,12 @@ function TableView({
30082
30228
  ]
30083
30229
  }
30084
30230
  );
30085
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React74__default.Fragment, { children: rowInner }, id);
30231
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React75__default.Fragment, { children: rowInner }, id);
30086
30232
  };
30087
30233
  const items = Array.from(data);
30088
30234
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
30089
30235
  let runningIndex = 0;
30090
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
30236
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
30091
30237
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
30092
30238
  group.items.map((row) => renderRow(row, runningIndex++))
30093
30239
  ] }, gi)) });
@@ -30104,7 +30250,7 @@ function TableView({
30104
30250
  /* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
30105
30251
  t("common.showMore"),
30106
30252
  " (",
30107
- t("common.remaining", { count: ordered.length - visibleCount }),
30253
+ t("common.remaining", { count: ordered2.length - visibleCount }),
30108
30254
  ")"
30109
30255
  ] }) })
30110
30256
  ]
@@ -31450,7 +31596,7 @@ var init_StepFlow = __esm({
31450
31596
  className
31451
31597
  }) => {
31452
31598
  if (orientation === "vertical") {
31453
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React74__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
31599
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React75__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
31454
31600
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
31455
31601
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
31456
31602
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -31461,7 +31607,7 @@ var init_StepFlow = __esm({
31461
31607
  ] })
31462
31608
  ] }) }, index)) });
31463
31609
  }
31464
- 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(React74__default.Fragment, { children: [
31610
+ 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(React75__default.Fragment, { children: [
31465
31611
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
31466
31612
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
31467
31613
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -32451,7 +32597,7 @@ var init_LikertScale = __esm({
32451
32597
  md: "text-base",
32452
32598
  lg: "text-lg"
32453
32599
  };
32454
- LikertScale = React74__default.forwardRef(
32600
+ LikertScale = React75__default.forwardRef(
32455
32601
  ({
32456
32602
  question,
32457
32603
  options = DEFAULT_LIKERT_OPTIONS,
@@ -32463,7 +32609,7 @@ var init_LikertScale = __esm({
32463
32609
  variant = "radios",
32464
32610
  className
32465
32611
  }, ref) => {
32466
- const groupId = React74__default.useId();
32612
+ const groupId = React75__default.useId();
32467
32613
  const eventBus = useEventBus();
32468
32614
  const handleSelect = useCallback(
32469
32615
  (next) => {
@@ -34752,7 +34898,7 @@ var init_DocBreadcrumb = __esm({
34752
34898
  "aria-label": t("aria.breadcrumb"),
34753
34899
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
34754
34900
  const isLast = idx === items.length - 1;
34755
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
34901
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
34756
34902
  idx > 0 && /* @__PURE__ */ jsx(
34757
34903
  Icon,
34758
34904
  {
@@ -35621,7 +35767,7 @@ var init_MiniStateMachine = __esm({
35621
35767
  const x = 2 + i * (NODE_W + GAP2 + ARROW_W + GAP2);
35622
35768
  const tc = transitionCounts[s.name] ?? 0;
35623
35769
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
35624
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
35770
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
35625
35771
  /* @__PURE__ */ jsx(
35626
35772
  AvlState,
35627
35773
  {
@@ -35825,7 +35971,7 @@ var init_PageHeader = __esm({
35825
35971
  info: "bg-info/10 text-info"
35826
35972
  };
35827
35973
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
35828
- 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(React74__default.Fragment, { children: [
35974
+ 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(React75__default.Fragment, { children: [
35829
35975
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
35830
35976
  crumb.href ? /* @__PURE__ */ jsx(
35831
35977
  "a",
@@ -36183,7 +36329,7 @@ var init_Section = __esm({
36183
36329
  as: Component = "section"
36184
36330
  }) => {
36185
36331
  const hasHeader = title || description || action;
36186
- return React74__default.createElement(
36332
+ return React75__default.createElement(
36187
36333
  Component,
36188
36334
  {
36189
36335
  className: cn(
@@ -36557,7 +36703,7 @@ var init_WizardContainer = __esm({
36557
36703
  const isCompleted = index < currentStep;
36558
36704
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
36559
36705
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
36560
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
36706
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
36561
36707
  /* @__PURE__ */ jsx(
36562
36708
  Button,
36563
36709
  {
@@ -38344,7 +38490,7 @@ var init_ImportPreviewTree = __esm({
38344
38490
  const renderUnit = (unit, childrenByParent, depth) => {
38345
38491
  const summary = fieldSummary(unit);
38346
38492
  const children = childrenByParent.get(unit.ref) ?? [];
38347
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
38493
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
38348
38494
  /* @__PURE__ */ jsxs(
38349
38495
  Box,
38350
38496
  {
@@ -38441,7 +38587,7 @@ var init_ImportProgress = __esm({
38441
38587
  PIPELINE.map((key, index) => {
38442
38588
  const isComplete = index < currentIndex;
38443
38589
  const isActive = index === currentIndex;
38444
- return /* @__PURE__ */ jsxs(React74__default.Fragment, { children: [
38590
+ return /* @__PURE__ */ jsxs(React75__default.Fragment, { children: [
38445
38591
  index > 0 ? /* @__PURE__ */ jsx(Box, { className: "h-px w-4 bg-border" }) : null,
38446
38592
  /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-1", "data-testid": `import-progress-step-${key}`, children: [
38447
38593
  /* @__PURE__ */ jsx(
@@ -38707,6 +38853,7 @@ var init_molecules2 = __esm({
38707
38853
  init_GridPicker();
38708
38854
  init_AssetPicker();
38709
38855
  init_IconPicker();
38856
+ init_EmojiPicker();
38710
38857
  init_DateRangePicker();
38711
38858
  init_DateRangeSelector();
38712
38859
  init_ChartLegend();
@@ -39764,8 +39911,18 @@ var init_DetailPanel = __esm({
39764
39911
  DetailPanel.displayName = "DetailPanel";
39765
39912
  }
39766
39913
  });
39914
+
39915
+ // components/game/atoms/DrawGroup.tsx
39916
+ function DrawGroup(_props) {
39917
+ return null;
39918
+ }
39919
+ var init_DrawGroup = __esm({
39920
+ "components/game/atoms/DrawGroup.tsx"() {
39921
+ "use client";
39922
+ }
39923
+ });
39767
39924
  function extractTitle(children) {
39768
- if (!React74__default.isValidElement(children)) return void 0;
39925
+ if (!React75__default.isValidElement(children)) return void 0;
39769
39926
  const props = children.props;
39770
39927
  if (typeof props.title === "string") {
39771
39928
  return props.title;
@@ -40115,12 +40272,12 @@ var init_Form = __esm({
40115
40272
  const isSchemaEntity = isOrbitalEntitySchema(entity);
40116
40273
  const resolvedEntity = isSchemaEntity ? entity : void 0;
40117
40274
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
40118
- const normalizedInitialData = React74__default.useMemo(() => {
40275
+ const normalizedInitialData = React75__default.useMemo(() => {
40119
40276
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
40120
40277
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
40121
40278
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
40122
40279
  }, [entity, initialData]);
40123
- const entityDerivedFields = React74__default.useMemo(() => {
40280
+ const entityDerivedFields = React75__default.useMemo(() => {
40124
40281
  if (fields && fields.length > 0) return void 0;
40125
40282
  if (!resolvedEntity) return void 0;
40126
40283
  return resolvedEntity.fields.map(
@@ -40141,16 +40298,16 @@ var init_Form = __esm({
40141
40298
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
40142
40299
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
40143
40300
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
40144
- const [formData, setFormData] = React74__default.useState(
40301
+ const [formData, setFormData] = React75__default.useState(
40145
40302
  normalizedInitialData
40146
40303
  );
40147
- const [collapsedSections, setCollapsedSections] = React74__default.useState(
40304
+ const [collapsedSections, setCollapsedSections] = React75__default.useState(
40148
40305
  /* @__PURE__ */ new Set()
40149
40306
  );
40150
- const [submitError, setSubmitError] = React74__default.useState(null);
40151
- const formRef = React74__default.useRef(null);
40307
+ const [submitError, setSubmitError] = React75__default.useState(null);
40308
+ const formRef = React75__default.useRef(null);
40152
40309
  const formMode = props.mode;
40153
- const mountedRef = React74__default.useRef(false);
40310
+ const mountedRef = React75__default.useRef(false);
40154
40311
  if (!mountedRef.current) {
40155
40312
  mountedRef.current = true;
40156
40313
  debug("forms", "mount", {
@@ -40163,7 +40320,7 @@ var init_Form = __esm({
40163
40320
  });
40164
40321
  }
40165
40322
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
40166
- const evalContext = React74__default.useMemo(
40323
+ const evalContext = React75__default.useMemo(
40167
40324
  () => ({
40168
40325
  formValues: formData,
40169
40326
  globalVariables: externalContext?.globalVariables ?? {},
@@ -40172,7 +40329,7 @@ var init_Form = __esm({
40172
40329
  }),
40173
40330
  [formData, externalContext]
40174
40331
  );
40175
- React74__default.useEffect(() => {
40332
+ React75__default.useEffect(() => {
40176
40333
  debug("forms", "initialData-sync", {
40177
40334
  mode: formMode,
40178
40335
  normalizedInitialData,
@@ -40183,7 +40340,7 @@ var init_Form = __esm({
40183
40340
  setFormData(normalizedInitialData);
40184
40341
  }
40185
40342
  }, [normalizedInitialData]);
40186
- const processCalculations = React74__default.useCallback(
40343
+ const processCalculations = React75__default.useCallback(
40187
40344
  (changedFieldId, newFormData) => {
40188
40345
  if (!hiddenCalculations.length) return;
40189
40346
  const context = {
@@ -40208,7 +40365,7 @@ var init_Form = __esm({
40208
40365
  },
40209
40366
  [hiddenCalculations, externalContext, eventBus]
40210
40367
  );
40211
- const checkViolations = React74__default.useCallback(
40368
+ const checkViolations = React75__default.useCallback(
40212
40369
  (changedFieldId, newFormData) => {
40213
40370
  if (!violationTriggers.length) return;
40214
40371
  const context = {
@@ -40246,7 +40403,7 @@ var init_Form = __esm({
40246
40403
  processCalculations(name, newFormData);
40247
40404
  checkViolations(name, newFormData);
40248
40405
  };
40249
- const isFieldVisible = React74__default.useCallback(
40406
+ const isFieldVisible = React75__default.useCallback(
40250
40407
  (fieldName) => {
40251
40408
  const condition = conditionalFields[fieldName];
40252
40409
  if (!condition) return true;
@@ -40254,7 +40411,7 @@ var init_Form = __esm({
40254
40411
  },
40255
40412
  [conditionalFields, evalContext]
40256
40413
  );
40257
- const isSectionVisible = React74__default.useCallback(
40414
+ const isSectionVisible = React75__default.useCallback(
40258
40415
  (section) => {
40259
40416
  if (!section.condition) return true;
40260
40417
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -40330,7 +40487,7 @@ var init_Form = __esm({
40330
40487
  eventBus.emit(`UI:${onCancel}`);
40331
40488
  }
40332
40489
  };
40333
- const renderField = React74__default.useCallback(
40490
+ const renderField = React75__default.useCallback(
40334
40491
  (field) => {
40335
40492
  const fieldName = field.name || field.field;
40336
40493
  if (!fieldName) return null;
@@ -40351,7 +40508,7 @@ var init_Form = __esm({
40351
40508
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
40352
40509
  );
40353
40510
  const effectiveFields = entityDerivedFields ?? fields;
40354
- const normalizedFields = React74__default.useMemo(() => {
40511
+ const normalizedFields = React75__default.useMemo(() => {
40355
40512
  if (!effectiveFields || effectiveFields.length === 0) return [];
40356
40513
  return effectiveFields.map((field) => {
40357
40514
  if (typeof field === "string") {
@@ -40375,7 +40532,7 @@ var init_Form = __esm({
40375
40532
  return field;
40376
40533
  });
40377
40534
  }, [effectiveFields, resolvedEntity]);
40378
- const schemaFields = React74__default.useMemo(() => {
40535
+ const schemaFields = React75__default.useMemo(() => {
40379
40536
  if (normalizedFields.length === 0) return null;
40380
40537
  if (isDebugEnabled()) {
40381
40538
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -40385,7 +40542,7 @@ var init_Form = __esm({
40385
40542
  }
40386
40543
  return normalizedFields.map(renderField).filter(Boolean);
40387
40544
  }, [normalizedFields, renderField, entityName, conditionalFields]);
40388
- const sectionElements = React74__default.useMemo(() => {
40545
+ const sectionElements = React75__default.useMemo(() => {
40389
40546
  if (!sections || sections.length === 0) return null;
40390
40547
  return sections.map((section) => {
40391
40548
  if (!isSectionVisible(section)) {
@@ -41111,7 +41268,7 @@ var init_List = __esm({
41111
41268
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
41112
41269
  return [];
41113
41270
  }, [entity]);
41114
- const getItemActions = React74__default.useCallback(
41271
+ const getItemActions = React75__default.useCallback(
41115
41272
  (item) => {
41116
41273
  if (!itemActions) return [];
41117
41274
  if (typeof itemActions === "function") {
@@ -41592,7 +41749,7 @@ var init_MediaGallery = __esm({
41592
41749
  [selectable, selectedItems, selectionEvent, eventBus]
41593
41750
  );
41594
41751
  const entityData = Array.isArray(entity) ? entity : [];
41595
- const items = React74__default.useMemo(() => {
41752
+ const items = React75__default.useMemo(() => {
41596
41753
  if (propItems && propItems.length > 0) return propItems;
41597
41754
  if (entityData.length === 0) return [];
41598
41755
  return entityData.map((record, idx) => {
@@ -41757,7 +41914,7 @@ var init_MediaGallery = __esm({
41757
41914
  }
41758
41915
  });
41759
41916
  function extractTitle2(children) {
41760
- if (!React74__default.isValidElement(children)) return void 0;
41917
+ if (!React75__default.isValidElement(children)) return void 0;
41761
41918
  const props = children.props;
41762
41919
  if (typeof props.title === "string") {
41763
41920
  return props.title;
@@ -42012,7 +42169,7 @@ var init_debugRegistry = __esm({
42012
42169
  }
42013
42170
  });
42014
42171
  function useDebugData() {
42015
- const [data, setData] = React74.useState(() => ({
42172
+ const [data, setData] = React75.useState(() => ({
42016
42173
  traits: [],
42017
42174
  ticks: [],
42018
42175
  guards: [],
@@ -42026,7 +42183,7 @@ function useDebugData() {
42026
42183
  },
42027
42184
  lastUpdate: Date.now()
42028
42185
  }));
42029
- React74.useEffect(() => {
42186
+ React75.useEffect(() => {
42030
42187
  const updateData = () => {
42031
42188
  setData({
42032
42189
  traits: getAllTraits(),
@@ -42135,12 +42292,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
42135
42292
  return positions;
42136
42293
  }
42137
42294
  function WalkMinimap() {
42138
- const [walkStep, setWalkStep] = React74.useState(null);
42139
- const [traits2, setTraits] = React74.useState([]);
42140
- const [coveredEdges, setCoveredEdges] = React74.useState([]);
42141
- const [completedTraits, setCompletedTraits] = React74.useState(/* @__PURE__ */ new Set());
42142
- const prevTraitRef = React74.useRef(null);
42143
- React74.useEffect(() => {
42295
+ const [walkStep, setWalkStep] = React75.useState(null);
42296
+ const [traits2, setTraits] = React75.useState([]);
42297
+ const [coveredEdges, setCoveredEdges] = React75.useState([]);
42298
+ const [completedTraits, setCompletedTraits] = React75.useState(/* @__PURE__ */ new Set());
42299
+ const prevTraitRef = React75.useRef(null);
42300
+ React75.useEffect(() => {
42144
42301
  const interval = setInterval(() => {
42145
42302
  const w = window;
42146
42303
  const step = w.__orbitalWalkStep;
@@ -42576,15 +42733,15 @@ var init_EntitiesTab = __esm({
42576
42733
  });
42577
42734
  function EventFlowTab({ events: events2 }) {
42578
42735
  const { t } = useTranslate();
42579
- const [filter, setFilter] = React74.useState("all");
42580
- const containerRef = React74.useRef(null);
42581
- const [autoScroll, setAutoScroll] = React74.useState(true);
42582
- React74.useEffect(() => {
42736
+ const [filter, setFilter] = React75.useState("all");
42737
+ const containerRef = React75.useRef(null);
42738
+ const [autoScroll, setAutoScroll] = React75.useState(true);
42739
+ React75.useEffect(() => {
42583
42740
  if (autoScroll && containerRef.current) {
42584
42741
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
42585
42742
  }
42586
42743
  }, [events2.length, autoScroll]);
42587
- const filteredEvents = React74.useMemo(() => {
42744
+ const filteredEvents = React75.useMemo(() => {
42588
42745
  if (filter === "all") return events2;
42589
42746
  return events2.filter((e) => e.type === filter);
42590
42747
  }, [events2, filter]);
@@ -42700,7 +42857,7 @@ var init_EventFlowTab = __esm({
42700
42857
  });
42701
42858
  function GuardsPanel({ guards }) {
42702
42859
  const { t } = useTranslate();
42703
- const [filter, setFilter] = React74.useState("all");
42860
+ const [filter, setFilter] = React75.useState("all");
42704
42861
  if (guards.length === 0) {
42705
42862
  return /* @__PURE__ */ jsx(
42706
42863
  EmptyState,
@@ -42713,7 +42870,7 @@ function GuardsPanel({ guards }) {
42713
42870
  }
42714
42871
  const passedCount = guards.filter((g) => g.result).length;
42715
42872
  const failedCount = guards.length - passedCount;
42716
- const filteredGuards = React74.useMemo(() => {
42873
+ const filteredGuards = React75.useMemo(() => {
42717
42874
  if (filter === "all") return guards;
42718
42875
  if (filter === "passed") return guards.filter((g) => g.result);
42719
42876
  return guards.filter((g) => !g.result);
@@ -42876,10 +43033,10 @@ function EffectBadge({ effect }) {
42876
43033
  }
42877
43034
  function TransitionTimeline({ transitions }) {
42878
43035
  const { t } = useTranslate();
42879
- const containerRef = React74.useRef(null);
42880
- const [autoScroll, setAutoScroll] = React74.useState(true);
42881
- const [expandedId, setExpandedId] = React74.useState(null);
42882
- React74.useEffect(() => {
43036
+ const containerRef = React75.useRef(null);
43037
+ const [autoScroll, setAutoScroll] = React75.useState(true);
43038
+ const [expandedId, setExpandedId] = React75.useState(null);
43039
+ React75.useEffect(() => {
42883
43040
  if (autoScroll && containerRef.current) {
42884
43041
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
42885
43042
  }
@@ -43159,9 +43316,9 @@ function getAllEvents(traits2) {
43159
43316
  function EventDispatcherTab({ traits: traits2, schema }) {
43160
43317
  const eventBus = useEventBus();
43161
43318
  const { t } = useTranslate();
43162
- const [log19, setLog] = React74.useState([]);
43163
- const prevStatesRef = React74.useRef(/* @__PURE__ */ new Map());
43164
- React74.useEffect(() => {
43319
+ const [log19, setLog] = React75.useState([]);
43320
+ const prevStatesRef = React75.useRef(/* @__PURE__ */ new Map());
43321
+ React75.useEffect(() => {
43165
43322
  for (const trait of traits2) {
43166
43323
  const prev = prevStatesRef.current.get(trait.id);
43167
43324
  if (prev && prev !== trait.currentState) {
@@ -43330,10 +43487,10 @@ function VerifyModePanel({
43330
43487
  localCount
43331
43488
  }) {
43332
43489
  const { t } = useTranslate();
43333
- const [expanded, setExpanded] = React74.useState(true);
43334
- const scrollRef = React74.useRef(null);
43335
- const prevCountRef = React74.useRef(0);
43336
- React74.useEffect(() => {
43490
+ const [expanded, setExpanded] = React75.useState(true);
43491
+ const scrollRef = React75.useRef(null);
43492
+ const prevCountRef = React75.useRef(0);
43493
+ React75.useEffect(() => {
43337
43494
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
43338
43495
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
43339
43496
  }
@@ -43390,10 +43547,10 @@ function RuntimeDebugger({
43390
43547
  schema
43391
43548
  }) {
43392
43549
  const { t } = useTranslate();
43393
- const [isCollapsed, setIsCollapsed] = React74.useState(mode === "verify" ? true : defaultCollapsed);
43394
- const [isVisible, setIsVisible] = React74.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
43550
+ const [isCollapsed, setIsCollapsed] = React75.useState(mode === "verify" ? true : defaultCollapsed);
43551
+ const [isVisible, setIsVisible] = React75.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
43395
43552
  const debugData = useDebugData();
43396
- React74.useEffect(() => {
43553
+ React75.useEffect(() => {
43397
43554
  if (mode === "inline") return;
43398
43555
  return onDebugToggle((enabled) => {
43399
43556
  setIsVisible(enabled);
@@ -43402,7 +43559,7 @@ function RuntimeDebugger({
43402
43559
  }
43403
43560
  });
43404
43561
  }, [mode]);
43405
- React74.useEffect(() => {
43562
+ React75.useEffect(() => {
43406
43563
  if (mode === "inline") return;
43407
43564
  const handleKeyDown = (e) => {
43408
43565
  if (e.key === "`" && isVisible) {
@@ -43922,7 +44079,7 @@ var init_StatCard = __esm({
43922
44079
  const labelToUse = propLabel ?? propTitle;
43923
44080
  const eventBus = useEventBus();
43924
44081
  const { t } = useTranslate();
43925
- const handleActionClick = React74__default.useCallback(() => {
44082
+ const handleActionClick = React75__default.useCallback(() => {
43926
44083
  if (action?.event) {
43927
44084
  eventBus.emit(`UI:${action.event}`, {});
43928
44085
  }
@@ -43933,7 +44090,7 @@ var init_StatCard = __esm({
43933
44090
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
43934
44091
  const isLoading = externalLoading ?? false;
43935
44092
  const error = externalError;
43936
- const computeMetricValue = React74__default.useCallback(
44093
+ const computeMetricValue = React75__default.useCallback(
43937
44094
  (metric, items) => {
43938
44095
  if (metric.value !== void 0) {
43939
44096
  return metric.value;
@@ -43972,7 +44129,7 @@ var init_StatCard = __esm({
43972
44129
  },
43973
44130
  []
43974
44131
  );
43975
- const schemaStats = React74__default.useMemo(() => {
44132
+ const schemaStats = React75__default.useMemo(() => {
43976
44133
  if (!metrics || metrics.length === 0) return null;
43977
44134
  return metrics.map((metric) => ({
43978
44135
  label: metric.label,
@@ -43980,7 +44137,7 @@ var init_StatCard = __esm({
43980
44137
  format: metric.format
43981
44138
  }));
43982
44139
  }, [metrics, data, computeMetricValue]);
43983
- const calculatedTrend = React74__default.useMemo(() => {
44140
+ const calculatedTrend = React75__default.useMemo(() => {
43984
44141
  if (manualTrend !== void 0) return manualTrend;
43985
44142
  if (previousValue === void 0 || currentValue2 === void 0)
43986
44143
  return void 0;
@@ -44620,8 +44777,8 @@ var init_SubagentTracePanel = __esm({
44620
44777
  ] });
44621
44778
  };
44622
44779
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
44623
- const endRef = React74__default.useRef(null);
44624
- React74__default.useEffect(() => {
44780
+ const endRef = React75__default.useRef(null);
44781
+ React75__default.useEffect(() => {
44625
44782
  if (!autoScroll) return;
44626
44783
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
44627
44784
  }, [activities.length, autoScroll]);
@@ -44715,7 +44872,7 @@ var init_SubagentTracePanel = __esm({
44715
44872
  };
44716
44873
  SubagentRichCard = ({ subagent }) => {
44717
44874
  const { t } = useTranslate();
44718
- const activities = React74__default.useMemo(
44875
+ const activities = React75__default.useMemo(
44719
44876
  () => subagentMessagesToActivities(subagent.messages),
44720
44877
  [subagent.messages]
44721
44878
  );
@@ -44792,8 +44949,8 @@ var init_SubagentTracePanel = __esm({
44792
44949
  ] });
44793
44950
  };
44794
44951
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
44795
- const endRef = React74__default.useRef(null);
44796
- React74__default.useEffect(() => {
44952
+ const endRef = React75__default.useRef(null);
44953
+ React75__default.useEffect(() => {
44797
44954
  if (!autoScroll) return;
44798
44955
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
44799
44956
  }, [messages.length, autoScroll]);
@@ -45228,7 +45385,7 @@ var init_Timeline = __esm({
45228
45385
  }) => {
45229
45386
  const { t } = useTranslate();
45230
45387
  const entityData = entity ?? [];
45231
- const items = React74__default.useMemo(() => {
45388
+ const items = React75__default.useMemo(() => {
45232
45389
  if (propItems) return propItems;
45233
45390
  if (entityData.length === 0) return [];
45234
45391
  return entityData.map((record, idx) => {
@@ -45330,7 +45487,7 @@ var init_Timeline = __esm({
45330
45487
  }
45331
45488
  });
45332
45489
  function extractToastProps(children) {
45333
- if (!React74__default.isValidElement(children)) {
45490
+ if (!React75__default.isValidElement(children)) {
45334
45491
  if (typeof children === "string") {
45335
45492
  return { message: children };
45336
45493
  }
@@ -45372,7 +45529,7 @@ var init_ToastSlot = __esm({
45372
45529
  eventBus.emit(`${prefix}CLOSE`);
45373
45530
  };
45374
45531
  if (!isVisible) return null;
45375
- const isCustomContent = React74__default.isValidElement(children) && !message;
45532
+ const isCustomContent = React75__default.isValidElement(children) && !message;
45376
45533
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
45377
45534
  Toast,
45378
45535
  {
@@ -45467,6 +45624,7 @@ var init_component_registry_generated = __esm({
45467
45624
  init_DocSidebar();
45468
45625
  init_DocTOC();
45469
45626
  init_DocumentViewer();
45627
+ init_DrawGroup();
45470
45628
  init_DrawShape();
45471
45629
  init_DrawShapeLayer();
45472
45630
  init_DrawSprite();
@@ -45476,6 +45634,7 @@ var init_component_registry_generated = __esm({
45476
45634
  init_Drawer();
45477
45635
  init_DrawerSlot();
45478
45636
  init_EdgeDecoration();
45637
+ init_EmojiPicker();
45479
45638
  init_EmptyState();
45480
45639
  init_ErrorBoundary();
45481
45640
  init_ErrorState();
@@ -45610,10 +45769,6 @@ var init_component_registry_generated = __esm({
45610
45769
  init_SubagentTracePanel();
45611
45770
  init_SvgBranch();
45612
45771
  init_SvgConnection();
45613
- init_SvgDrawGroup();
45614
- init_SvgDrawShape();
45615
- init_SvgDrawShapeLayer();
45616
- init_SvgDrawText();
45617
45772
  init_SvgFlow();
45618
45773
  init_SvgGrid();
45619
45774
  init_SvgLobe();
@@ -45624,7 +45779,6 @@ var init_component_registry_generated = __esm({
45624
45779
  init_SvgRing();
45625
45780
  init_SvgShield();
45626
45781
  init_SvgStack();
45627
- init_SvgStage();
45628
45782
  init_SwipeableRow();
45629
45783
  init_Switch();
45630
45784
  init_TabbedContainer();
@@ -45738,6 +45892,7 @@ var init_component_registry_generated = __esm({
45738
45892
  "DocSidebar": DocSidebar,
45739
45893
  "DocTOC": DocTOC,
45740
45894
  "DocumentViewer": DocumentViewer,
45895
+ "DrawGroup": DrawGroup,
45741
45896
  "DrawShape": DrawShape,
45742
45897
  "DrawShapeLayer": DrawShapeLayer,
45743
45898
  "DrawSprite": DrawSprite,
@@ -45747,6 +45902,7 @@ var init_component_registry_generated = __esm({
45747
45902
  "Drawer": Drawer,
45748
45903
  "DrawerSlot": DrawerSlot,
45749
45904
  "EdgeDecoration": EdgeDecoration,
45905
+ "EmojiPicker": EmojiPicker,
45750
45906
  "EmptyState": EmptyState,
45751
45907
  "ErrorBoundary": ErrorBoundary,
45752
45908
  "ErrorState": ErrorState,
@@ -45886,10 +46042,6 @@ var init_component_registry_generated = __esm({
45886
46042
  "SubagentTracePanel": SubagentTracePanel,
45887
46043
  "SvgBranch": SvgBranch,
45888
46044
  "SvgConnection": SvgConnection,
45889
- "SvgDrawGroup": SvgDrawGroup,
45890
- "SvgDrawShape": SvgDrawShape,
45891
- "SvgDrawShapeLayer": SvgDrawShapeLayer,
45892
- "SvgDrawText": SvgDrawText,
45893
46045
  "SvgFlow": SvgFlow,
45894
46046
  "SvgGrid": SvgGrid,
45895
46047
  "SvgLobe": SvgLobe,
@@ -45900,7 +46052,6 @@ var init_component_registry_generated = __esm({
45900
46052
  "SvgRing": SvgRing,
45901
46053
  "SvgShield": SvgShield,
45902
46054
  "SvgStack": SvgStack,
45903
- "SvgStage": SvgStage,
45904
46055
  "SwipeableRow": SwipeableRow,
45905
46056
  "Switch": Switch,
45906
46057
  "TabbedContainer": TabbedContainer,
@@ -45951,7 +46102,7 @@ function SuspenseConfigProvider({
45951
46102
  config,
45952
46103
  children
45953
46104
  }) {
45954
- return React74__default.createElement(
46105
+ return React75__default.createElement(
45955
46106
  SuspenseConfigContext.Provider,
45956
46107
  { value: config },
45957
46108
  children
@@ -45993,7 +46144,7 @@ function enrichFormFields(fields, entityDef) {
45993
46144
  }
45994
46145
  return { name: field, label: humanizeFieldName(field) };
45995
46146
  }
45996
- if (field && typeof field === "object" && !Array.isArray(field) && !React74__default.isValidElement(field) && !(field instanceof Date)) {
46147
+ if (field && typeof field === "object" && !Array.isArray(field) && !React75__default.isValidElement(field) && !(field instanceof Date)) {
45997
46148
  const obj = field;
45998
46149
  const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
45999
46150
  if (!fieldName) return field;
@@ -46179,7 +46330,19 @@ function UISlotComponent({
46179
46330
  const suspenseConfig = useContext(SuspenseConfigContext);
46180
46331
  const contained = useContext(SlotContainedContext);
46181
46332
  const schemaCtx = useEntitySchemaOptional();
46182
- const content = slots[slot];
46333
+ const rawContent = slots[slot];
46334
+ const binding = useEntityBindingSnapshot(rawContent?.sourceTrait);
46335
+ const content = useMemo(() => {
46336
+ if (!rawContent) return rawContent;
46337
+ const resolvedProps = resolveRenderBindingMarkers(
46338
+ rawContent.props,
46339
+ rawContent.sourceTrait,
46340
+ binding.entity,
46341
+ binding.config,
46342
+ binding.state
46343
+ );
46344
+ return resolvedProps === rawContent.props ? rawContent : { ...rawContent, props: resolvedProps };
46345
+ }, [rawContent, binding.entity, binding.config, binding.state]);
46183
46346
  if (children !== void 0) {
46184
46347
  if (pattern === "clear") {
46185
46348
  return null;
@@ -46453,7 +46616,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
46453
46616
  const key = `${parentId}-${index}-trait:${traitName}`;
46454
46617
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
46455
46618
  }
46456
- return /* @__PURE__ */ jsx(React74__default.Fragment, { children: child }, `${parentId}-${index}`);
46619
+ return /* @__PURE__ */ jsx(React75__default.Fragment, { children: child }, `${parentId}-${index}`);
46457
46620
  }
46458
46621
  if (!child || typeof child !== "object") return null;
46459
46622
  const childId = `${parentId}-${index}`;
@@ -46510,19 +46673,20 @@ function isPatternConfig(value) {
46510
46673
  if (value === null || value === void 0) return false;
46511
46674
  if (typeof value !== "object") return false;
46512
46675
  if (Array.isArray(value)) return false;
46513
- if (React74__default.isValidElement(value)) return false;
46676
+ if (React75__default.isValidElement(value)) return false;
46514
46677
  if (value instanceof Date) return false;
46515
46678
  if (typeof value === "function") return false;
46516
46679
  const record = value;
46517
46680
  return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
46518
46681
  }
46519
46682
  function isPlainConfigObject(value) {
46520
- if (React74__default.isValidElement(value)) return false;
46683
+ if (React75__default.isValidElement(value)) return false;
46521
46684
  if (value instanceof Date) return false;
46522
46685
  const proto = Object.getPrototypeOf(value);
46523
46686
  return proto === Object.prototype || proto === null;
46524
46687
  }
46525
46688
  function substituteTraitRefsDeep(value, pathKey) {
46689
+ if (isRenderBindingMarker(value)) return value;
46526
46690
  if (typeof value === "string") {
46527
46691
  const match = TRAIT_BINDING_RE.exec(value);
46528
46692
  if (match) {
@@ -46595,7 +46759,14 @@ function SlotContentRenderer({
46595
46759
  onDismiss,
46596
46760
  patternPath
46597
46761
  }) {
46598
- const entityProp = content.props.entity;
46762
+ const ambientScope = useTraitScope();
46763
+ const bindingTrait = content.sourceTrait ?? ambientScope?.trait;
46764
+ const binding = useEntityBindingSnapshot(bindingTrait);
46765
+ const liveProps = useMemo(
46766
+ () => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state),
46767
+ [content.props, bindingTrait, binding.entity, binding.config, binding.state]
46768
+ );
46769
+ const entityProp = liveProps.entity;
46599
46770
  if (content.pattern === "form-section") {
46600
46771
  slotLog.debug("SlotContentRenderer:form-section-render", {
46601
46772
  contentId: content.id,
@@ -46626,7 +46797,7 @@ function SlotContentRenderer({
46626
46797
  const orbitalName = schemaCtx && content.sourceTrait !== void 0 ? schemaCtx.orbitalsByTrait.get(content.sourceTrait) : void 0;
46627
46798
  const PatternComponent = getComponentForPattern(content.pattern);
46628
46799
  if (PatternComponent) {
46629
- const childrenConfig = content.props.children;
46800
+ const childrenConfig = liveProps.children;
46630
46801
  const isSingleChild = typeof childrenConfig === "string" || typeof childrenConfig === "object" && childrenConfig !== null && !Array.isArray(childrenConfig) && "type" in childrenConfig;
46631
46802
  const hasChildren = PATTERNS_WITH_CHILDREN.has(content.pattern) || Array.isArray(childrenConfig) && childrenConfig.length > 0 || isSingleChild;
46632
46803
  const isDrawHost = isDrawHostPattern(content.pattern);
@@ -46637,15 +46808,15 @@ function SlotContentRenderer({
46637
46808
  fromState: content.fromState,
46638
46809
  entity: content.entity
46639
46810
  }) : void 0;
46640
- const incomingChildren = content.props.children;
46811
+ const incomingChildren = liveProps.children;
46641
46812
  const childrenIsRenderFn = typeof incomingChildren === "function";
46642
- const { children: _childrenConfig, ...restPropsNoChildren } = content.props;
46813
+ const { children: _childrenConfig, ...restPropsNoChildren } = liveProps;
46643
46814
  const restProps = childrenIsRenderFn ? { ...restPropsNoChildren, children: incomingChildren } : restPropsNoChildren;
46644
46815
  const nodeSlotOverrides = {};
46645
46816
  for (const slotKey of CONTENT_NODE_SLOTS) {
46646
46817
  const slotVal = restProps[slotKey];
46647
46818
  if (slotVal === void 0 || slotVal === null) continue;
46648
- if (React74__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
46819
+ if (React75__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
46649
46820
  const typelessChildren = !Array.isArray(slotVal) && typeof slotVal === "object" && !("type" in slotVal) && Array.isArray(slotVal.children) ? slotVal.children : void 0;
46650
46821
  if (typelessChildren !== void 0 || Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
46651
46822
  nodeSlotOverrides[slotKey] = renderPatternChildren(
@@ -46699,7 +46870,7 @@ function SlotContentRenderer({
46699
46870
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
46700
46871
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
46701
46872
  const sample = resolvedItems[0];
46702
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React74__default.isValidElement(sample) && !(sample instanceof Date)) {
46873
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React75__default.isValidElement(sample) && !(sample instanceof Date)) {
46703
46874
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
46704
46875
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
46705
46876
  }
@@ -46748,7 +46919,7 @@ function SlotContentRenderer({
46748
46919
  "data-orb-path": patternPath ?? "root",
46749
46920
  "data-orb-pattern": content.pattern,
46750
46921
  "data-orb-orbital": orbitalName,
46751
- children: content.props.children ?? /* @__PURE__ */ jsxs(Box, { className: "p-4 text-sm text-muted-foreground border border-dashed border-border rounded", children: [
46922
+ children: liveProps.children ?? /* @__PURE__ */ jsxs(Box, { className: "p-4 text-sm text-muted-foreground border border-dashed border-border rounded", children: [
46752
46923
  "Unknown pattern: ",
46753
46924
  content.pattern,
46754
46925
  content.sourceTrait && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "ml-2", children: [
@@ -46820,6 +46991,7 @@ var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext,
46820
46991
  var init_UISlotRenderer = __esm({
46821
46992
  "components/core/organisms/UISlotRenderer.tsx"() {
46822
46993
  "use client";
46994
+ init_resolve_render_bindings();
46823
46995
  init_Modal();
46824
46996
  init_Drawer();
46825
46997
  init_Toast();
@@ -49356,4 +49528,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
49356
49528
  });
49357
49529
  }
49358
49530
 
49359
- export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AtlasImage, AtlasPanel, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioToggle, GameHud, GameIcon, GameMenu, GameShell, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, ImportPreviewTree, ImportProgress, ImportSourcePicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, Modal, ModalSlot, ModuleCard, Navigation, NodeSlotEditor, NotifyListener, NumberStepper, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, PageTransition, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, Presence, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, RichBlockEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, ServiceCatalog, SharedEntityStoreContext, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateGraph, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgDrawGroup, SvgDrawShape, SvgDrawShapeLayer, SvgDrawText, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SvgStage, SvgStageContext, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VersionDiff, ViolationAlert, VoteStack, WizardContainer, WizardNavigation, WizardProgress, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createSharedEntityStore, createTranslate, createUnitAnimationState, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, registerCodeLanguageLoader, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, runTickFrame, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAtlasSliceDataUrl, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useMediaQuery, useOrbitalHistory, usePresence, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSharedEntityStoreContext, useSwipeGesture, useTapReveal, useTraitListens, useTranslate114 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
49531
+ export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AtlasImage, AtlasPanel, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmojiPicker, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioToggle, GameHud, GameIcon, GameMenu, GameShell, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, ImportPreviewTree, ImportProgress, ImportSourcePicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, Modal, ModalSlot, ModuleCard, Navigation, NodeSlotEditor, NotifyListener, NumberStepper, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, PageTransition, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, Presence, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, RichBlockEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, ServiceCatalog, SharedEntityStoreContext, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateGraph, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StepFlow, StepFlowOrganism, SubagentTracePanel, 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, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VersionDiff, ViolationAlert, VoteStack, WizardContainer, WizardNavigation, WizardProgress, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createSharedEntityStore, createTranslate, createUnitAnimationState, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, registerCodeLanguageLoader, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, runTickFrame, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAtlasSliceDataUrl, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useMediaQuery, useOrbitalHistory, usePresence, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSharedEntityStoreContext, useSwipeGesture, useTapReveal, useTraitListens, useTranslate114 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };