@almadar/ui 5.138.0 → 5.140.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.
@@ -1,5 +1,5 @@
1
- import * as React85 from 'react';
2
- import React85__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useSyncExternalStore, useLayoutEffect, lazy, useId } from 'react';
1
+ import * as React86 from 'react';
2
+ import React86__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useSyncExternalStore, useLayoutEffect, lazy, useId } from 'react';
3
3
  import { EventBusContext, useTraitScopeChain, useEntitySchemaOptional, useEntityBindingSnapshot, useTraitScope, TraitScopeProvider, useCurrentPagePath, useGameAudioContextOptional } from '@almadar/ui/providers';
4
4
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
5
5
  import { createContextFromBindings, interpolateValue } from '@almadar/runtime';
@@ -281,7 +281,7 @@ function resolveMarkerExpression(expression, entity, config, state) {
281
281
  function isPlainObject(value) {
282
282
  if (value === null || value === void 0 || typeof value !== "object") return false;
283
283
  if (Array.isArray(value)) return false;
284
- if (React85__default.isValidElement(value)) return false;
284
+ if (React86__default.isValidElement(value)) return false;
285
285
  if (value instanceof Date) return false;
286
286
  if (typeof value === "function") return false;
287
287
  return true;
@@ -501,7 +501,7 @@ var init_Box = __esm({
501
501
  fixed: "fixed",
502
502
  sticky: "sticky"
503
503
  };
504
- Box = React85__default.forwardRef(
504
+ Box = React86__default.forwardRef(
505
505
  ({
506
506
  padding,
507
507
  paddingX,
@@ -566,7 +566,7 @@ var init_Box = __esm({
566
566
  onPointerDown?.(e);
567
567
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
568
568
  const isClickable = action || onClick;
569
- return React85__default.createElement(
569
+ return React86__default.createElement(
570
570
  Component,
571
571
  {
572
572
  ref,
@@ -783,7 +783,7 @@ var init_Icon = __esm({
783
783
  const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
784
784
  const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
785
785
  const family = useIconFamily();
786
- const RenderedComponent = React85__default.useMemo(() => {
786
+ const RenderedComponent = React86__default.useMemo(() => {
787
787
  if (directIcon) return null;
788
788
  return effectiveName ? resolveIconForFamily(effectiveName) : null;
789
789
  }, [directIcon, effectiveName, family]);
@@ -907,7 +907,7 @@ var init_atlasSlice = __esm({
907
907
  }
908
908
  });
909
909
  function useAtlasSliceDataUrl(asset) {
910
- const [, bump] = React85.useReducer((x) => x + 1, 0);
910
+ const [, bump] = React86.useReducer((x) => x + 1, 0);
911
911
  if (!isAtlasAsset(asset)) return void 0;
912
912
  const key = `${asset.atlas}#${asset.sprite}`;
913
913
  const cached = sliceDataUrlCache.get(key);
@@ -970,13 +970,13 @@ function AtlasImage({
970
970
  style,
971
971
  "aria-hidden": ariaHidden
972
972
  }) {
973
- const [, bump] = React85.useReducer((x) => x + 1, 0);
974
- const canvasRef = React85.useRef(null);
973
+ const [, bump] = React86.useReducer((x) => x + 1, 0);
974
+ const canvasRef = React86.useRef(null);
975
975
  const sliced = isAtlasAsset(asset);
976
976
  const atlas = sliced ? getAtlas(asset.atlas, bump) : void 0;
977
977
  const img = sliced && asset?.url ? getSheetImage(asset.url, bump) : null;
978
978
  const rect = sliced && atlas ? subRectFor(atlas, asset.sprite) : null;
979
- React85.useEffect(() => {
979
+ React86.useEffect(() => {
980
980
  const canvas = canvasRef.current;
981
981
  if (!canvas || !img || !rect) return;
982
982
  canvas.width = rect.sw;
@@ -1052,7 +1052,7 @@ function resolveIconProp(value, sizeClass) {
1052
1052
  const IconComp = value;
1053
1053
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
1054
1054
  }
1055
- if (React85__default.isValidElement(value)) {
1055
+ if (React86__default.isValidElement(value)) {
1056
1056
  return value;
1057
1057
  }
1058
1058
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -1129,7 +1129,7 @@ var init_Button = __esm({
1129
1129
  md: "h-icon-default w-icon-default",
1130
1130
  lg: "h-icon-default w-icon-default"
1131
1131
  };
1132
- Button = React85__default.forwardRef(
1132
+ Button = React86__default.forwardRef(
1133
1133
  ({
1134
1134
  className,
1135
1135
  variant = "primary",
@@ -1199,7 +1199,7 @@ var Dialog;
1199
1199
  var init_Dialog = __esm({
1200
1200
  "components/core/atoms/Dialog.tsx"() {
1201
1201
  init_cn();
1202
- Dialog = React85__default.forwardRef(
1202
+ Dialog = React86__default.forwardRef(
1203
1203
  ({
1204
1204
  role = "dialog",
1205
1205
  "aria-modal": ariaModal = true,
@@ -1410,7 +1410,7 @@ var init_Typography = __esm({
1410
1410
  if (format !== void 0 && format !== "none" && (typeof body === "string" || typeof body === "number" || body instanceof Date)) {
1411
1411
  body = formatValue(body, format);
1412
1412
  }
1413
- return React85__default.createElement(
1413
+ return React86__default.createElement(
1414
1414
  Component,
1415
1415
  {
1416
1416
  id,
@@ -1973,7 +1973,7 @@ var init_Badge = __esm({
1973
1973
  md: "px-2.5 py-1 text-sm",
1974
1974
  lg: "px-3 py-1.5 text-base"
1975
1975
  };
1976
- Badge = React85__default.forwardRef(
1976
+ Badge = React86__default.forwardRef(
1977
1977
  ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
1978
1978
  const iconSizes3 = {
1979
1979
  sm: "h-icon-default w-icon-default",
@@ -2323,7 +2323,7 @@ var init_SvgFlow = __esm({
2323
2323
  width = 100,
2324
2324
  height = 100
2325
2325
  }) => {
2326
- const markerId = React85__default.useMemo(() => {
2326
+ const markerId = React86__default.useMemo(() => {
2327
2327
  flowIdCounter += 1;
2328
2328
  return `almadar-flow-arrow-${flowIdCounter}`;
2329
2329
  }, []);
@@ -2916,7 +2916,7 @@ var init_SvgRing = __esm({
2916
2916
  width = 100,
2917
2917
  height = 100
2918
2918
  }) => {
2919
- const gradientId = React85__default.useMemo(() => {
2919
+ const gradientId = React86__default.useMemo(() => {
2920
2920
  ringIdCounter += 1;
2921
2921
  return `almadar-ring-glow-${ringIdCounter}`;
2922
2922
  }, []);
@@ -3097,7 +3097,7 @@ var init_Input = __esm({
3097
3097
  init_cn();
3098
3098
  init_Icon();
3099
3099
  init_useEventBus();
3100
- Input = React85__default.forwardRef(
3100
+ Input = React86__default.forwardRef(
3101
3101
  ({
3102
3102
  className,
3103
3103
  inputType,
@@ -3121,9 +3121,9 @@ var init_Input = __esm({
3121
3121
  const eventBus = useEventBus();
3122
3122
  const type = inputType || htmlType || "text";
3123
3123
  const isDeclarative = typeof onChange === "string";
3124
- const [localValue, setLocalValue] = React85__default.useState(value);
3125
- const pendingEchoRef = React85__default.useRef(/* @__PURE__ */ new Set());
3126
- React85__default.useEffect(() => {
3124
+ const [localValue, setLocalValue] = React86__default.useState(value);
3125
+ const pendingEchoRef = React86__default.useRef(/* @__PURE__ */ new Set());
3126
+ React86__default.useEffect(() => {
3127
3127
  if (!isDeclarative) return;
3128
3128
  const incoming = value == null ? "" : String(value);
3129
3129
  if (pendingEchoRef.current.has(incoming)) {
@@ -3283,7 +3283,7 @@ var Label;
3283
3283
  var init_Label = __esm({
3284
3284
  "components/core/atoms/Label.tsx"() {
3285
3285
  init_cn();
3286
- Label = React85__default.forwardRef(
3286
+ Label = React86__default.forwardRef(
3287
3287
  ({ className, required, children, ...props }, ref) => {
3288
3288
  return /* @__PURE__ */ jsxs(
3289
3289
  "label",
@@ -3310,7 +3310,7 @@ var init_Textarea = __esm({
3310
3310
  "components/core/atoms/Textarea.tsx"() {
3311
3311
  init_cn();
3312
3312
  init_useEventBus();
3313
- Textarea = React85__default.forwardRef(
3313
+ Textarea = React86__default.forwardRef(
3314
3314
  ({ className, error, onChange, ...props }, ref) => {
3315
3315
  const eventBus = useEventBus();
3316
3316
  const handleChange = (e) => {
@@ -3549,7 +3549,7 @@ var init_Select = __esm({
3549
3549
  init_cn();
3550
3550
  init_Icon();
3551
3551
  init_useEventBus();
3552
- Select = React85__default.forwardRef(
3552
+ Select = React86__default.forwardRef(
3553
3553
  (props, _ref) => {
3554
3554
  const { multiple, searchable, clearable } = props;
3555
3555
  if (multiple || searchable || clearable) {
@@ -3566,7 +3566,7 @@ var init_Checkbox = __esm({
3566
3566
  "components/core/atoms/Checkbox.tsx"() {
3567
3567
  init_cn();
3568
3568
  init_useEventBus();
3569
- Checkbox = React85__default.forwardRef(
3569
+ Checkbox = React86__default.forwardRef(
3570
3570
  ({ className, label, id, onChange, ...props }, ref) => {
3571
3571
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
3572
3572
  const eventBus = useEventBus();
@@ -3620,7 +3620,7 @@ var init_Spinner = __esm({
3620
3620
  md: "h-6 w-6",
3621
3621
  lg: "h-8 w-8"
3622
3622
  };
3623
- Spinner = React85__default.forwardRef(
3623
+ Spinner = React86__default.forwardRef(
3624
3624
  ({ className, size = "md", overlay, ...props }, ref) => {
3625
3625
  if (overlay) {
3626
3626
  return /* @__PURE__ */ jsx(
@@ -3710,7 +3710,7 @@ var init_Card = __esm({
3710
3710
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
3711
3711
  "tile-image-first": "p-0 overflow-hidden"
3712
3712
  };
3713
- Card = React85__default.forwardRef(
3713
+ Card = React86__default.forwardRef(
3714
3714
  ({
3715
3715
  className,
3716
3716
  variant = "bordered",
@@ -3759,9 +3759,9 @@ var init_Card = __esm({
3759
3759
  }
3760
3760
  );
3761
3761
  Card.displayName = "Card";
3762
- CardHeader = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3762
+ CardHeader = React86__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3763
3763
  CardHeader.displayName = "CardHeader";
3764
- CardTitle = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3764
+ CardTitle = React86__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3765
3765
  "h3",
3766
3766
  {
3767
3767
  ref,
@@ -3774,11 +3774,11 @@ var init_Card = __esm({
3774
3774
  }
3775
3775
  ));
3776
3776
  CardTitle.displayName = "CardTitle";
3777
- CardContent = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3777
+ CardContent = React86__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3778
3778
  CardContent.displayName = "CardContent";
3779
3779
  CardBody = CardContent;
3780
3780
  CardBody.displayName = "CardBody";
3781
- CardFooter = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3781
+ CardFooter = React86__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3782
3782
  "div",
3783
3783
  {
3784
3784
  ref,
@@ -3865,7 +3865,7 @@ var init_FilterPill = __esm({
3865
3865
  md: "w-3.5 h-3.5",
3866
3866
  lg: "w-4 h-4"
3867
3867
  };
3868
- FilterPill = React85__default.forwardRef(
3868
+ FilterPill = React86__default.forwardRef(
3869
3869
  ({
3870
3870
  className,
3871
3871
  variant = "default",
@@ -3994,8 +3994,8 @@ var init_Avatar = __esm({
3994
3994
  actionPayload
3995
3995
  }) => {
3996
3996
  const eventBus = useEventBus();
3997
- const [imgFailed, setImgFailed] = React85__default.useState(false);
3998
- React85__default.useEffect(() => {
3997
+ const [imgFailed, setImgFailed] = React86__default.useState(false);
3998
+ React86__default.useEffect(() => {
3999
3999
  setImgFailed(false);
4000
4000
  }, [src]);
4001
4001
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -4108,7 +4108,7 @@ var init_Center = __esm({
4108
4108
  as: Component = "div"
4109
4109
  }) => {
4110
4110
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
4111
- return React85__default.createElement(Component, {
4111
+ return React86__default.createElement(Component, {
4112
4112
  className: cn(
4113
4113
  inline ? "inline-flex" : "flex",
4114
4114
  horizontal && "justify-center",
@@ -4376,7 +4376,7 @@ var init_Radio = __esm({
4376
4376
  md: "w-2.5 h-2.5",
4377
4377
  lg: "w-3 h-3"
4378
4378
  };
4379
- Radio = React85__default.forwardRef(
4379
+ Radio = React86__default.forwardRef(
4380
4380
  ({
4381
4381
  label,
4382
4382
  helperText,
@@ -4393,12 +4393,12 @@ var init_Radio = __esm({
4393
4393
  onChange,
4394
4394
  ...props
4395
4395
  }, ref) => {
4396
- const reactId = React85__default.useId();
4396
+ const reactId = React86__default.useId();
4397
4397
  const baseId = id || `radio-${reactId}`;
4398
4398
  const hasError = !!error;
4399
4399
  const eventBus = useEventBus();
4400
- const [selected, setSelected] = React85__default.useState(value);
4401
- React85__default.useEffect(() => {
4400
+ const [selected, setSelected] = React86__default.useState(value);
4401
+ React86__default.useEffect(() => {
4402
4402
  if (value !== void 0) setSelected(value);
4403
4403
  }, [value]);
4404
4404
  const pick = (next, e) => {
@@ -4580,7 +4580,7 @@ var init_Switch = __esm({
4580
4580
  "components/core/atoms/Switch.tsx"() {
4581
4581
  "use client";
4582
4582
  init_cn();
4583
- Switch = React85.forwardRef(
4583
+ Switch = React86.forwardRef(
4584
4584
  ({
4585
4585
  checked,
4586
4586
  defaultChecked = false,
@@ -4591,10 +4591,10 @@ var init_Switch = __esm({
4591
4591
  name,
4592
4592
  className
4593
4593
  }, ref) => {
4594
- const [isChecked, setIsChecked] = React85.useState(
4594
+ const [isChecked, setIsChecked] = React86.useState(
4595
4595
  checked !== void 0 ? checked : defaultChecked
4596
4596
  );
4597
- React85.useEffect(() => {
4597
+ React86.useEffect(() => {
4598
4598
  if (checked !== void 0) {
4599
4599
  setIsChecked(checked);
4600
4600
  }
@@ -4757,7 +4757,7 @@ var init_Stack = __esm({
4757
4757
  };
4758
4758
  const isHorizontal = direction === "horizontal";
4759
4759
  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";
4760
- return React85__default.createElement(
4760
+ return React86__default.createElement(
4761
4761
  Component,
4762
4762
  {
4763
4763
  className: cn(
@@ -4957,7 +4957,7 @@ var Aside;
4957
4957
  var init_Aside = __esm({
4958
4958
  "components/core/atoms/Aside.tsx"() {
4959
4959
  init_cn();
4960
- Aside = React85__default.forwardRef(
4960
+ Aside = React86__default.forwardRef(
4961
4961
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
4962
4962
  );
4963
4963
  Aside.displayName = "Aside";
@@ -5036,9 +5036,9 @@ var init_LawReferenceTooltip = __esm({
5036
5036
  className
5037
5037
  }) => {
5038
5038
  const { t } = useTranslate();
5039
- const [isVisible, setIsVisible] = React85__default.useState(false);
5040
- const timeoutRef = React85__default.useRef(null);
5041
- const triggerRef = React85__default.useRef(null);
5039
+ const [isVisible, setIsVisible] = React86__default.useState(false);
5040
+ const timeoutRef = React86__default.useRef(null);
5041
+ const triggerRef = React86__default.useRef(null);
5042
5042
  const handleMouseEnter = () => {
5043
5043
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5044
5044
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -5049,7 +5049,7 @@ var init_LawReferenceTooltip = __esm({
5049
5049
  };
5050
5050
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
5051
5051
  const open = isVisible || revealed;
5052
- React85__default.useEffect(() => {
5052
+ React86__default.useEffect(() => {
5053
5053
  return () => {
5054
5054
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5055
5055
  };
@@ -5259,7 +5259,7 @@ var init_StatusDot = __esm({
5259
5259
  md: "w-2.5 h-2.5",
5260
5260
  lg: "w-3 h-3"
5261
5261
  };
5262
- StatusDot = React85__default.forwardRef(
5262
+ StatusDot = React86__default.forwardRef(
5263
5263
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
5264
5264
  return /* @__PURE__ */ jsx(
5265
5265
  "span",
@@ -5313,7 +5313,7 @@ var init_TrendIndicator = __esm({
5313
5313
  down: "trending-down",
5314
5314
  flat: "arrow-right"
5315
5315
  };
5316
- TrendIndicator = React85__default.forwardRef(
5316
+ TrendIndicator = React86__default.forwardRef(
5317
5317
  ({
5318
5318
  className,
5319
5319
  value,
@@ -5382,7 +5382,7 @@ var init_RangeSlider = __esm({
5382
5382
  md: "w-4 h-4",
5383
5383
  lg: "w-5 h-5"
5384
5384
  };
5385
- RangeSlider = React85__default.forwardRef(
5385
+ RangeSlider = React86__default.forwardRef(
5386
5386
  ({
5387
5387
  className,
5388
5388
  min = 0,
@@ -5993,7 +5993,7 @@ var init_ContentSection = __esm({
5993
5993
  md: "py-16",
5994
5994
  lg: "py-24"
5995
5995
  };
5996
- ContentSection = React85__default.forwardRef(
5996
+ ContentSection = React86__default.forwardRef(
5997
5997
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
5998
5998
  return /* @__PURE__ */ jsx(
5999
5999
  Box,
@@ -6527,7 +6527,7 @@ var init_AnimatedReveal = __esm({
6527
6527
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
6528
6528
  "none": {}
6529
6529
  };
6530
- AnimatedReveal = React85__default.forwardRef(
6530
+ AnimatedReveal = React86__default.forwardRef(
6531
6531
  ({
6532
6532
  trigger = "scroll",
6533
6533
  animation = "fade-up",
@@ -6687,7 +6687,7 @@ var init_AnimatedGraphic = __esm({
6687
6687
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
6688
6688
  "use client";
6689
6689
  init_cn();
6690
- AnimatedGraphic = React85__default.forwardRef(
6690
+ AnimatedGraphic = React86__default.forwardRef(
6691
6691
  ({
6692
6692
  src,
6693
6693
  svgContent,
@@ -6710,7 +6710,7 @@ var init_AnimatedGraphic = __esm({
6710
6710
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
6711
6711
  const resolvedSvg = svgContent ?? fetchedSvg;
6712
6712
  const prevAnimateRef = useRef(animate);
6713
- const setRef = React85__default.useCallback(
6713
+ const setRef = React86__default.useCallback(
6714
6714
  (node) => {
6715
6715
  containerRef.current = node;
6716
6716
  if (typeof ref === "function") ref(node);
@@ -7438,9 +7438,9 @@ function ControlButton({
7438
7438
  className
7439
7439
  }) {
7440
7440
  const eventBus = useEventBus();
7441
- const [isPressed, setIsPressed] = React85.useState(false);
7441
+ const [isPressed, setIsPressed] = React86.useState(false);
7442
7442
  const actualPressed = pressed ?? isPressed;
7443
- const handlePointerDown = React85.useCallback(
7443
+ const handlePointerDown = React86.useCallback(
7444
7444
  (e) => {
7445
7445
  e.preventDefault();
7446
7446
  if (disabled) return;
@@ -7450,7 +7450,7 @@ function ControlButton({
7450
7450
  },
7451
7451
  [disabled, pressEvent, eventBus, onPress]
7452
7452
  );
7453
- const handlePointerUp = React85.useCallback(
7453
+ const handlePointerUp = React86.useCallback(
7454
7454
  (e) => {
7455
7455
  e.preventDefault();
7456
7456
  if (disabled) return;
@@ -7460,7 +7460,7 @@ function ControlButton({
7460
7460
  },
7461
7461
  [disabled, releaseEvent, eventBus, onRelease]
7462
7462
  );
7463
- const handlePointerLeave = React85.useCallback(
7463
+ const handlePointerLeave = React86.useCallback(
7464
7464
  (e) => {
7465
7465
  if (isPressed) {
7466
7466
  setIsPressed(false);
@@ -7718,8 +7718,8 @@ function ControlGrid({
7718
7718
  className
7719
7719
  }) {
7720
7720
  const eventBus = useEventBus();
7721
- const [active, setActive] = React85.useState(/* @__PURE__ */ new Set());
7722
- const handlePress = React85.useCallback(
7721
+ const [active, setActive] = React86.useState(/* @__PURE__ */ new Set());
7722
+ const handlePress = React86.useCallback(
7723
7723
  (id) => {
7724
7724
  setActive((prev) => new Set(prev).add(id));
7725
7725
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -7733,7 +7733,7 @@ function ControlGrid({
7733
7733
  },
7734
7734
  [kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
7735
7735
  );
7736
- const handleRelease = React85.useCallback(
7736
+ const handleRelease = React86.useCallback(
7737
7737
  (id) => {
7738
7738
  setActive((prev) => {
7739
7739
  const next = new Set(prev);
@@ -8091,7 +8091,7 @@ function GameMenu({
8091
8091
  }) {
8092
8092
  const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
8093
8093
  const eventBus = useEventBus();
8094
- const handleOptionClick = React85.useCallback(
8094
+ const handleOptionClick = React86.useCallback(
8095
8095
  (option) => {
8096
8096
  if (option.event) {
8097
8097
  eventBus.emit(`UI:${option.event}`, { option });
@@ -8327,7 +8327,7 @@ function StateGraph({
8327
8327
  }) {
8328
8328
  const eventBus = useEventBus();
8329
8329
  const nodes = states ?? [];
8330
- const positions = React85.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
8330
+ const positions = React86.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
8331
8331
  return /* @__PURE__ */ jsxs(
8332
8332
  Box,
8333
8333
  {
@@ -8398,8 +8398,8 @@ function MiniMap({
8398
8398
  tileAssets,
8399
8399
  unitAssets
8400
8400
  }) {
8401
- const canvasRef = React85.useRef(null);
8402
- const imgCacheRef = React85.useRef(/* @__PURE__ */ new Map());
8401
+ const canvasRef = React86.useRef(null);
8402
+ const imgCacheRef = React86.useRef(/* @__PURE__ */ new Map());
8403
8403
  function loadImg(url) {
8404
8404
  const cached = imgCacheRef.current.get(url);
8405
8405
  if (cached) return cached.complete ? cached : null;
@@ -8415,7 +8415,7 @@ function MiniMap({
8415
8415
  imgCacheRef.current.set(url, img);
8416
8416
  return null;
8417
8417
  }
8418
- React85.useEffect(() => {
8418
+ React86.useEffect(() => {
8419
8419
  const canvas = canvasRef.current;
8420
8420
  if (!canvas) return;
8421
8421
  const ctx = canvas.getContext("2d");
@@ -8823,6 +8823,12 @@ function createWebPainter(ctx, onAssetLoad) {
8823
8823
  for (let i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y);
8824
8824
  if (closed) ctx.closePath();
8825
8825
  };
8826
+ const toCanvasStyle = (style) => {
8827
+ if (typeof style === "string") return style;
8828
+ const g = style.kind === "linear" ? ctx.createLinearGradient(style.x1, style.y1, style.x2, style.y2) : ctx.createRadialGradient(style.cx, style.cy, 0, style.cx, style.cy, style.r);
8829
+ for (const stop of style.stops) g.addColorStop(stop.offset, stop.color);
8830
+ return g;
8831
+ };
8826
8832
  return {
8827
8833
  setViewport(width, height, dpr) {
8828
8834
  vw = width;
@@ -8876,47 +8882,47 @@ function createWebPainter(ctx, onAssetLoad) {
8876
8882
  ctx.drawImage(img, dest.x, dest.y, dw, dh);
8877
8883
  }
8878
8884
  },
8879
- fillRect(x, y, w, h, color) {
8880
- ctx.fillStyle = color;
8885
+ fillRect(x, y, w, h, style) {
8886
+ ctx.fillStyle = toCanvasStyle(style);
8881
8887
  ctx.fillRect(x, y, w, h);
8882
8888
  },
8883
- strokeRect(x, y, w, h, color, lineWidth = 1) {
8884
- ctx.strokeStyle = color;
8889
+ strokeRect(x, y, w, h, style, lineWidth = 1) {
8890
+ ctx.strokeStyle = toCanvasStyle(style);
8885
8891
  ctx.lineWidth = lineWidth;
8886
8892
  ctx.strokeRect(x, y, w, h);
8887
8893
  },
8888
- fillPoly(points, color) {
8894
+ fillPoly(points, style) {
8889
8895
  if (points.length === 0) return;
8890
8896
  tracePoly(points, true);
8891
- ctx.fillStyle = color;
8897
+ ctx.fillStyle = toCanvasStyle(style);
8892
8898
  ctx.fill();
8893
8899
  },
8894
- strokePoly(points, color, lineWidth = 1, closed = false) {
8900
+ strokePoly(points, style, lineWidth = 1, closed = false) {
8895
8901
  if (points.length === 0) return;
8896
8902
  tracePoly(points, closed);
8897
- ctx.strokeStyle = color;
8903
+ ctx.strokeStyle = toCanvasStyle(style);
8898
8904
  ctx.lineWidth = lineWidth;
8899
8905
  ctx.stroke();
8900
8906
  },
8901
- fillEllipse(cx, cy, rx, ry, color) {
8907
+ fillEllipse(cx, cy, rx, ry, style) {
8902
8908
  ctx.beginPath();
8903
8909
  ctx.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2);
8904
- ctx.fillStyle = color;
8910
+ ctx.fillStyle = toCanvasStyle(style);
8905
8911
  ctx.fill();
8906
8912
  },
8907
- strokeEllipse(cx, cy, rx, ry, color, lineWidth = 1) {
8913
+ strokeEllipse(cx, cy, rx, ry, style, lineWidth = 1) {
8908
8914
  ctx.beginPath();
8909
8915
  ctx.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2);
8910
- ctx.strokeStyle = color;
8916
+ ctx.strokeStyle = toCanvasStyle(style);
8911
8917
  ctx.lineWidth = lineWidth;
8912
8918
  ctx.stroke();
8913
8919
  },
8914
- fillPath(d, color) {
8915
- ctx.fillStyle = color;
8920
+ fillPath(d, style) {
8921
+ ctx.fillStyle = toCanvasStyle(style);
8916
8922
  ctx.fill(new Path2D(d));
8917
8923
  },
8918
- strokePath(d, color, lineWidth = 1) {
8919
- ctx.strokeStyle = color;
8924
+ strokePath(d, style, lineWidth = 1) {
8925
+ ctx.strokeStyle = toCanvasStyle(style);
8920
8926
  ctx.lineWidth = lineWidth;
8921
8927
  ctx.stroke(new Path2D(d));
8922
8928
  },
@@ -8990,6 +8996,21 @@ var init_projector = __esm({
8990
8996
  function isValidScenePos(pos) {
8991
8997
  return Number.isFinite(pos?.x) && Number.isFinite(pos?.y);
8992
8998
  }
8999
+ function spriteRect(projector, node, natural) {
9000
+ const tw = projector.tileWidth;
9001
+ const fallbackW = projector.worldPixelDirect ? natural?.w ?? 0 : tw;
9002
+ const fallbackH = projector.worldPixelDirect ? natural?.h ?? 0 : tw;
9003
+ const w = node.width !== void 0 ? node.width * tw : fallbackW;
9004
+ const h = node.height !== void 0 ? node.height * tw : fallbackH;
9005
+ const anchor = node.anchor ?? "top-left";
9006
+ const p = projector.anchorPoint(node.position, anchor);
9007
+ return {
9008
+ x: anchor === "top-left" ? p.x : p.x - w / 2,
9009
+ y: anchor === "ground" ? p.y - h : anchor === "center" ? p.y - h / 2 : p.y,
9010
+ w,
9011
+ h
9012
+ };
9013
+ }
8993
9014
  var init_contract = __esm({
8994
9015
  "lib/drawable/contract.ts"() {
8995
9016
  }
@@ -9004,16 +9025,11 @@ function paintFallbackSquare(painter, node, dctx, reason) {
9004
9025
  warnMissingOnce(reason, node);
9005
9026
  const tw = dctx.projector.tileWidth;
9006
9027
  const natural = dctx.projector.worldPixelDirect ? FALLBACK_WORLD_PX : tw;
9007
- const w = node.width !== void 0 ? node.width * tw : natural;
9008
- const h = node.height !== void 0 ? node.height * tw : natural;
9009
- const anchor = node.anchor ?? "top-left";
9010
- const p = dctx.projector.anchorPoint(node.position, anchor);
9011
- const dx = anchor === "top-left" ? p.x : p.x - w / 2;
9012
- const dy = anchor === "ground" ? p.y - h : anchor === "center" ? p.y - h / 2 : p.y;
9028
+ const rect = spriteRect(dctx.projector, node, { w: natural, h: natural });
9013
9029
  painter.save();
9014
9030
  if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
9015
- painter.fillRect(dx, dy, w, h, "#9b8f7f");
9016
- painter.strokeRect(dx, dy, w, h, "#5e564b", Math.max(1, tw / 32));
9031
+ painter.fillRect(rect.x, rect.y, rect.w, rect.h, "#9b8f7f");
9032
+ painter.strokeRect(rect.x, rect.y, rect.w, rect.h, "#5e564b", Math.max(1, tw / 32));
9017
9033
  painter.restore();
9018
9034
  }
9019
9035
  function DrawSprite(_props) {
@@ -9050,15 +9066,10 @@ var init_DrawSprite = __esm({
9050
9066
  }
9051
9067
  src = { x: r.sx, y: r.sy, w: r.sw, h: r.sh };
9052
9068
  }
9053
- const tw = dctx.projector.tileWidth;
9054
- const fallbackW = dctx.projector.worldPixelDirect ? src ? src.w : tex.width : tw;
9055
- const fallbackH = dctx.projector.worldPixelDirect ? src ? src.h : tex.height : tw;
9056
- const w = node.width !== void 0 ? node.width * tw : fallbackW;
9057
- const h = node.height !== void 0 ? node.height * tw : fallbackH;
9058
- const anchor = node.anchor ?? "top-left";
9059
- const p = dctx.projector.anchorPoint(node.position, anchor);
9060
- const dx = anchor === "top-left" ? p.x : p.x - w / 2;
9061
- const dy = anchor === "ground" ? p.y - h : anchor === "center" ? p.y - h / 2 : p.y;
9069
+ const rect = spriteRect(dctx.projector, node, src ? { w: src.w, h: src.h } : { w: tex.width, h: tex.height });
9070
+ const { w, h } = rect;
9071
+ const dx = rect.x;
9072
+ const dy = rect.y;
9062
9073
  painter.save();
9063
9074
  if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
9064
9075
  if (node.shadow) painter.setShadow(node.shadow);
@@ -9080,25 +9091,145 @@ var init_DrawSprite = __esm({
9080
9091
  };
9081
9092
  }
9082
9093
  });
9083
-
9084
- // components/game/atoms/DrawShape.tsx
9085
- function DrawShape(_props) {
9094
+ var DrawableRegistryContext;
9095
+ var init_registry = __esm({
9096
+ "lib/drawable/registry.ts"() {
9097
+ DrawableRegistryContext = createContext(null);
9098
+ }
9099
+ });
9100
+ function isAnimatedShape(node) {
9101
+ return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
9102
+ }
9103
+ function applyShapeAnimation(node, timeMs) {
9104
+ const anim = node.animation;
9105
+ if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return node;
9106
+ const frames = [...anim.keyframes].sort((a, b) => a.at - b.at);
9107
+ const cycle = timeMs / anim.durationMs;
9108
+ const t = anim.loop === false ? Math.min(cycle, 1) : cycle - Math.floor(cycle);
9109
+ const out = { ...node };
9110
+ const trackValue = (key) => {
9111
+ const defined = frames.filter((f3) => f3[key] !== void 0);
9112
+ if (defined.length === 0) return void 0;
9113
+ let prev;
9114
+ let next;
9115
+ for (const f3 of defined) {
9116
+ if (f3.at <= t) prev = f3;
9117
+ else if (!next) next = f3;
9118
+ }
9119
+ if (!prev) return defined[0][key];
9120
+ if (!next) return prev[key];
9121
+ const span = next.at - prev.at;
9122
+ const k = span > 0 ? (t - prev.at) / span : 1;
9123
+ const a = prev[key];
9124
+ const b = next[key];
9125
+ if (typeof a === "number" && typeof b === "number") return lerp(a, b, k);
9126
+ return a;
9127
+ };
9128
+ for (const key of NUMERIC_TRACKS) {
9129
+ const v = trackValue(key);
9130
+ if (v !== void 0) out[key] = v;
9131
+ }
9132
+ const fill = trackValue("fill");
9133
+ if (fill !== void 0) out.fill = fill;
9134
+ const stroke = trackValue("stroke");
9135
+ if (stroke !== void 0) out.stroke = stroke;
9136
+ const shadowFrames = frames.filter((f3) => f3.shadow !== void 0);
9137
+ if (shadowFrames.length > 0) {
9138
+ const sh = trackValue("shadow");
9139
+ if (sh !== void 0) {
9140
+ let prevSh;
9141
+ let nextSh;
9142
+ for (const f3 of shadowFrames) {
9143
+ if (f3.at <= t) prevSh = f3;
9144
+ else if (!nextSh) nextSh = f3;
9145
+ }
9146
+ if (prevSh?.shadow && nextSh?.shadow) {
9147
+ const span = nextSh.at - prevSh.at;
9148
+ const k = span > 0 ? (t - prevSh.at) / span : 1;
9149
+ out.shadow = { color: prevSh.shadow.color, blur: lerp(prevSh.shadow.blur, nextSh.shadow.blur, k) };
9150
+ } else {
9151
+ out.shadow = sh;
9152
+ }
9153
+ }
9154
+ }
9155
+ return out;
9156
+ }
9157
+ function gradientStyle(g, ox, oy, scale) {
9158
+ if (g.kind === "linear") {
9159
+ if (!g.from || !g.to) return void 0;
9160
+ return {
9161
+ kind: "linear",
9162
+ x1: ox + g.from.x * scale,
9163
+ y1: oy + g.from.y * scale,
9164
+ x2: ox + g.to.x * scale,
9165
+ y2: oy + g.to.y * scale,
9166
+ stops: g.stops
9167
+ };
9168
+ }
9169
+ if (!g.center || g.radius === void 0) return void 0;
9170
+ return {
9171
+ kind: "radial",
9172
+ cx: ox + g.center.x * scale,
9173
+ cy: oy + g.center.y * scale,
9174
+ r: g.radius * scale,
9175
+ stops: g.stops
9176
+ };
9177
+ }
9178
+ function DrawShape(props) {
9179
+ const register = useContext(DrawableRegistryContext);
9180
+ if (register) {
9181
+ const { opacity, ...rest } = props;
9182
+ const node = {
9183
+ ...rest,
9184
+ type: "draw-shape",
9185
+ ...opacity !== void 0 && opacity > 0 ? { opacity } : {}
9186
+ };
9187
+ register(node);
9188
+ }
9086
9189
  return null;
9087
9190
  }
9088
- var paintShape;
9191
+ var NUMERIC_TRACKS, lerp, paintShape;
9089
9192
  var init_DrawShape = __esm({
9090
9193
  "components/game/atoms/DrawShape.tsx"() {
9091
9194
  "use client";
9092
9195
  init_contract();
9093
- paintShape = (painter, node, dctx) => {
9196
+ init_registry();
9197
+ NUMERIC_TRACKS = [
9198
+ "offsetX",
9199
+ "offsetY",
9200
+ "rotate",
9201
+ "opacity",
9202
+ "radiusX",
9203
+ "radiusY",
9204
+ "width",
9205
+ "height",
9206
+ "strokeWidth"
9207
+ ];
9208
+ lerp = (a, b, k) => a + (b - a) * k;
9209
+ paintShape = (painter, rawNode, dctx) => {
9210
+ const node = dctx.time > 0 ? applyShapeAnimation(rawNode, dctx.time) : rawNode;
9094
9211
  if (!isValidScenePos(node.position)) return;
9095
9212
  painter.save();
9096
9213
  if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
9214
+ const origin = dctx.projector.project(node.position);
9215
+ const tileWidth = dctx.projector.tileWidth;
9216
+ if (node.rotate) {
9217
+ const pivot = node.pivot ?? { x: 0.5, y: 0.5 };
9218
+ const px = origin.x + pivot.x * tileWidth;
9219
+ const py = origin.y + pivot.y * tileWidth;
9220
+ painter.translate(px, py);
9221
+ painter.rotate(node.rotate);
9222
+ painter.translate(-px, -py);
9223
+ }
9224
+ if (node.shadow) painter.setShadow({ color: node.shadow.color, blur: node.shadow.blur * tileWidth });
9225
+ const fill = node.fill === "none" ? void 0 : node.fill;
9226
+ const stroke = node.stroke === "none" ? void 0 : node.stroke;
9227
+ const pxFill = node.gradient ? gradientStyle(node.gradient, origin.x, origin.y, tileWidth) ?? fill : fill;
9097
9228
  switch (node.shape) {
9098
9229
  case "cell": {
9099
9230
  const pts = dctx.projector.cellPath(node.position);
9100
- if (node.fill) painter.fillPoly(pts, node.fill);
9101
- if (node.stroke) painter.strokePoly(pts, node.stroke, node.strokeWidth ?? 1, true);
9231
+ if (pxFill) painter.fillPoly(pts, pxFill);
9232
+ if (stroke) painter.strokePoly(pts, stroke, node.strokeWidth ?? 1, true);
9102
9233
  break;
9103
9234
  }
9104
9235
  case "rect": {
@@ -9108,8 +9239,8 @@ var init_DrawShape = __esm({
9108
9239
  const y = p.y + (node.offsetY ?? 0) * tw;
9109
9240
  const w = (node.width ?? 0) * tw;
9110
9241
  const h = (node.height ?? 0) * tw;
9111
- if (node.fill) painter.fillRect(x, y, w, h, node.fill);
9112
- if (node.stroke) painter.strokeRect(x, y, w, h, node.stroke, node.strokeWidth ?? 1);
9242
+ if (pxFill) painter.fillRect(x, y, w, h, pxFill);
9243
+ if (stroke) painter.strokeRect(x, y, w, h, stroke, node.strokeWidth ?? 1);
9113
9244
  break;
9114
9245
  }
9115
9246
  case "ellipse": {
@@ -9119,26 +9250,26 @@ var init_DrawShape = __esm({
9119
9250
  const cy = p.y + (node.offsetY ?? 0) * tw;
9120
9251
  const rx = (node.radiusX ?? 0) * tw;
9121
9252
  const ry = (node.radiusY ?? rx) * tw;
9122
- if (node.fill) painter.fillEllipse(cx, cy, rx, ry, node.fill);
9123
- if (node.stroke) painter.strokeEllipse(cx, cy, rx, ry, node.stroke, node.strokeWidth ?? 1);
9253
+ if (pxFill) painter.fillEllipse(cx, cy, rx, ry, pxFill);
9254
+ if (stroke) painter.strokeEllipse(cx, cy, rx, ry, stroke, node.strokeWidth ?? 1);
9124
9255
  break;
9125
9256
  }
9126
9257
  case "poly": {
9127
- const base = dctx.projector.project(node.position);
9128
- const tw = dctx.projector.tileWidth;
9129
- const pts = (node.points ?? []).map((pt) => ({ x: base.x + pt.x * tw, y: base.y + pt.y * tw }));
9130
- if (node.fill) painter.fillPoly(pts, node.fill);
9131
- if (node.stroke) painter.strokePoly(pts, node.stroke, node.strokeWidth ?? 1, true);
9258
+ const pts = (node.points ?? []).map((pt) => ({
9259
+ x: origin.x + ((node.offsetX ?? 0) + pt.x) * tileWidth,
9260
+ y: origin.y + ((node.offsetY ?? 0) + pt.y) * tileWidth
9261
+ }));
9262
+ if (pxFill) painter.fillPoly(pts, pxFill);
9263
+ if (stroke) painter.strokePoly(pts, stroke, node.strokeWidth ?? 1, true);
9132
9264
  break;
9133
9265
  }
9134
9266
  case "path": {
9135
9267
  if (!node.d) break;
9136
- const base = dctx.projector.project(node.position);
9137
- const tw = dctx.projector.tileWidth;
9138
- painter.translate(base.x, base.y);
9139
- painter.scale(tw, tw);
9140
- if (node.fill) painter.fillPath(node.d, node.fill);
9141
- if (node.stroke) painter.strokePath(node.d, node.stroke, (node.strokeWidth ?? 1) / tw);
9268
+ painter.translate(origin.x + (node.offsetX ?? 0) * tileWidth, origin.y + (node.offsetY ?? 0) * tileWidth);
9269
+ painter.scale(tileWidth, tileWidth);
9270
+ const localFill = node.gradient ? gradientStyle(node.gradient, 0, 0, 1) ?? fill : fill;
9271
+ if (localFill) painter.fillPath(node.d, localFill);
9272
+ if (stroke) painter.strokePath(node.d, stroke, (node.strokeWidth ?? 1) / tileWidth);
9142
9273
  break;
9143
9274
  }
9144
9275
  }
@@ -9274,12 +9405,18 @@ function collectDrawnItems(nodes) {
9274
9405
  for (const n of nodes) {
9275
9406
  switch (n.type) {
9276
9407
  case "draw-sprite":
9408
+ if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id, anchor: n.anchor, width: n.width, height: n.height });
9409
+ break;
9277
9410
  case "draw-shape":
9278
9411
  case "draw-text":
9279
9412
  case "draw-group":
9280
9413
  if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id });
9281
9414
  break;
9282
9415
  case "draw-sprite-layer":
9416
+ for (const it of n.items) {
9417
+ if (isValidScenePos(it.position)) out.push({ pos: it.position, id: it.id, anchor: it.anchor, width: it.width, height: it.height });
9418
+ }
9419
+ break;
9283
9420
  case "draw-shape-layer":
9284
9421
  case "draw-text-layer":
9285
9422
  for (const it of n.items) {
@@ -9297,6 +9434,15 @@ function buildHitIndex(items) {
9297
9434
  }
9298
9435
  return m;
9299
9436
  }
9437
+ function hitTestSprites(items, projector, point) {
9438
+ for (let i = items.length - 1; i >= 0; i--) {
9439
+ const it = items[i];
9440
+ if (it.id === void 0) continue;
9441
+ const r = spriteRect(projector, { position: it.pos, anchor: it.anchor, width: it.width, height: it.height });
9442
+ if (point.x >= r.x && point.x <= r.x + r.w && point.y >= r.y && point.y <= r.y + r.h) return it.id;
9443
+ }
9444
+ return void 0;
9445
+ }
9300
9446
  var init_hitTest = __esm({
9301
9447
  "lib/drawable/hitTest.ts"() {
9302
9448
  init_contract();
@@ -9325,9 +9471,16 @@ function Canvas2D({
9325
9471
  showMinimap = true,
9326
9472
  followTarget,
9327
9473
  cameraPos,
9328
- bgColor
9474
+ bgColor,
9475
+ children
9329
9476
  }) {
9330
9477
  const instanceId = useMemo(() => Math.random().toString(36).slice(2, 8), []);
9478
+ const childDrawablesRef = useRef([]);
9479
+ childDrawablesRef.current = [];
9480
+ const registerChildDrawable = useCallback((node) => {
9481
+ childDrawablesRef.current.push(node);
9482
+ }, []);
9483
+ const hasJsxChildren = React86.Children.count(children) > 0;
9331
9484
  function isDrawableLayer(node) {
9332
9485
  return node.type === "draw-sprite-layer" || node.type === "draw-shape-layer" || node.type === "draw-text-layer";
9333
9486
  }
@@ -9476,11 +9629,24 @@ function Canvas2D({
9476
9629
  }, [showMinimap, scenePositions]);
9477
9630
  const miniMapWidth = gridExtent.width || 10;
9478
9631
  const miniMapHeight = gridExtent.height || 10;
9479
- const draw = useCallback(() => {
9632
+ const drawableIsAnimated = (node) => {
9633
+ if (node.type === "draw-shape") return isAnimatedShape(node);
9634
+ if (node.type === "draw-group") return Array.isArray(node.items) && node.items.some(drawableIsAnimated);
9635
+ if (node.type === "draw-shape-layer") return Array.isArray(node.items) && node.items.some(isAnimatedShape);
9636
+ return false;
9637
+ };
9638
+ const animRafRef = useRef(0);
9639
+ const drawTimeRef = useRef(() => void 0);
9640
+ const draw = useCallback((timeMs = 0) => {
9480
9641
  const canvas = canvasRef.current;
9481
9642
  if (!canvas) return;
9482
9643
  const ctx = canvas.getContext("2d");
9483
9644
  if (!ctx) return;
9645
+ const scheduleAnimation = (nodes) => {
9646
+ if (!nodes.some(drawableIsAnimated)) return;
9647
+ cancelAnimationFrame(animRafRef.current);
9648
+ animRafRef.current = requestAnimationFrame(() => drawTimeRef.current(performance.now()));
9649
+ };
9484
9650
  const dpr = window.devicePixelRatio || 1;
9485
9651
  canvas.width = viewportSize.width * dpr;
9486
9652
  canvas.height = viewportSize.height * dpr;
@@ -9510,7 +9676,29 @@ function Canvas2D({
9510
9676
  ctx.fillStyle = bgColor ?? BACKGROUND_FALLBACK_COLOR;
9511
9677
  ctx.fillRect(0, 0, viewportSize.width, viewportSize.height);
9512
9678
  }
9513
- if (!drawables || drawables.length === 0) return;
9679
+ if (!drawables || drawables.length === 0) {
9680
+ const childDrawables = childDrawablesRef.current;
9681
+ if (childDrawables.length === 0) return;
9682
+ const cam0 = cameraRef.current;
9683
+ if (camera !== "follow" && dragDistance() === 0) {
9684
+ const focus = cameraPos ?? defaultGridFocus;
9685
+ if (focus) {
9686
+ const p = projector.anchorPoint(focus, "center");
9687
+ cam0.x = p.x - viewportSize.width / 2;
9688
+ cam0.y = p.y - viewportSize.height / 2;
9689
+ }
9690
+ }
9691
+ const painter0 = createWebPainter(ctx, bumpAtlas);
9692
+ painter0.save();
9693
+ painter0.translate(viewportSize.width / 2, viewportSize.height / 2);
9694
+ painter0.scale(cam0.zoom, cam0.zoom);
9695
+ painter0.translate(-viewportSize.width / 2 - cam0.x, -viewportSize.height / 2 - cam0.y);
9696
+ const dctx0 = { projector, time: timeMs, invalidate: bumpAtlas };
9697
+ for (const node of childDrawables) paintDrawable(painter0, node, dctx0);
9698
+ painter0.restore();
9699
+ scheduleAnimation(childDrawables);
9700
+ return;
9701
+ }
9514
9702
  const cam = cameraRef.current;
9515
9703
  if (camera !== "follow" && dragDistance() === 0) {
9516
9704
  const focus = cameraPos ?? defaultGridFocus;
@@ -9528,10 +9716,15 @@ function Canvas2D({
9528
9716
  painter.translate(viewportSize.width / 2, viewportSize.height / 2);
9529
9717
  painter.scale(cam.zoom, cam.zoom);
9530
9718
  painter.translate(-viewportSize.width / 2 - cam.x, -viewportSize.height / 2 - cam.y);
9531
- const dctx = { projector, time: 0, invalidate: bumpAtlas };
9719
+ const dctx = { projector, time: timeMs, invalidate: bumpAtlas };
9532
9720
  for (const node of drawables) paintDrawable(painter, node, dctx);
9533
9721
  painter.restore();
9722
+ scheduleAnimation(drawables);
9534
9723
  }, [viewportSize, backgroundImage, bgColor, drawables, projector, cameraRef, bumpAtlas, getImage, cameraPos, defaultGridFocus, camera, dragDistance]);
9724
+ useEffect(() => {
9725
+ drawTimeRef.current = draw;
9726
+ }, [draw]);
9727
+ useEffect(() => () => cancelAnimationFrame(animRafRef.current), []);
9535
9728
  useEffect(() => {
9536
9729
  if (camera !== "follow" || !followTarget) return;
9537
9730
  const p = projector.anchorPoint(followTarget, "center");
@@ -9594,6 +9787,11 @@ function Canvas2D({
9594
9787
  if (dragDistance() > 5) return;
9595
9788
  if (!canvasRef.current || !tileClickEvent && !unitClickEvent) return;
9596
9789
  const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
9790
+ const spriteHit = unitClickEvent ? hitTestSprites(drawnItems, projector, world) : void 0;
9791
+ if (spriteHit !== void 0 && unitClickEvent) {
9792
+ eventBus.emit(`UI:${unitClickEvent}`, { unitId: spriteHit });
9793
+ return;
9794
+ }
9597
9795
  const adjustedX = world.x - scaledTileWidth / 2;
9598
9796
  const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
9599
9797
  const isoPos = unproject(adjustedX, adjustedY);
@@ -9603,7 +9801,7 @@ function Canvas2D({
9603
9801
  } else if (tileClickEvent) {
9604
9802
  eventBus.emit(`UI:${tileClickEvent}`, { x: isoPos.x, y: isoPos.y });
9605
9803
  }
9606
- }, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject, hitIndex, tileClickEvent, unitClickEvent, eventBus]);
9804
+ }, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject, hitIndex, drawnItems, projector, tileClickEvent, unitClickEvent, eventBus]);
9607
9805
  const handleCanvasPointerLeave = useCallback(() => {
9608
9806
  handleMouseLeave();
9609
9807
  if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
@@ -9673,7 +9871,7 @@ function Canvas2D({
9673
9871
  /* @__PURE__ */ jsx(Typography, { variant: "body", className: "text-muted-foreground", children: t("canvas.loadingMessage") || "Loading\u2026" })
9674
9872
  ] }) });
9675
9873
  }
9676
- if (!drawables || drawables.length === 0) {
9874
+ if ((!drawables || drawables.length === 0) && !hasJsxChildren) {
9677
9875
  return /* @__PURE__ */ jsx(
9678
9876
  Box,
9679
9877
  {
@@ -9687,7 +9885,7 @@ function Canvas2D({
9687
9885
  }
9688
9886
  );
9689
9887
  }
9690
- return /* @__PURE__ */ jsxs(
9888
+ return /* @__PURE__ */ jsx(DrawableRegistryContext.Provider, { value: registerChildDrawable, children: /* @__PURE__ */ jsxs(
9691
9889
  Box,
9692
9890
  {
9693
9891
  ref: containerRef,
@@ -9748,10 +9946,11 @@ function Canvas2D({
9748
9946
  mapWidth: miniMapWidth,
9749
9947
  mapHeight: miniMapHeight
9750
9948
  }
9751
- ) })
9949
+ ) }),
9950
+ hasJsxChildren && /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: { position: "absolute", width: 0, height: 0, overflow: "hidden" }, children })
9752
9951
  ]
9753
9952
  }
9754
- );
9953
+ ) });
9755
9954
  }
9756
9955
  var canvas2DLog;
9757
9956
  var init_Canvas2D = __esm({
@@ -9773,6 +9972,8 @@ var init_Canvas2D = __esm({
9773
9972
  init_webPainter2d();
9774
9973
  init_projector();
9775
9974
  init_paintDispatch();
9975
+ init_DrawShape();
9976
+ init_registry();
9776
9977
  init_hitTest();
9777
9978
  init_isometric();
9778
9979
  canvas2DLog = createLogger("almadar:ui:game-canvas");
@@ -9814,7 +10015,8 @@ function Canvas({
9814
10015
  tileLeaveEvent,
9815
10016
  featureClickEvent,
9816
10017
  keyMap,
9817
- keyUpMap
10018
+ keyUpMap,
10019
+ children
9818
10020
  }) {
9819
10021
  canvasLog.debug("Canvas render", { mode, drawablesCount: drawables?.length, projection, camera: camera ? JSON.stringify(camera) : void 0 });
9820
10022
  const zoom = camera?.zoom;
@@ -9867,7 +10069,8 @@ function Canvas({
9867
10069
  tileHoverEvent,
9868
10070
  tileLeaveEvent,
9869
10071
  keyMap,
9870
- keyUpMap
10072
+ keyUpMap,
10073
+ ...children !== void 0 ? { children } : {}
9871
10074
  }
9872
10075
  );
9873
10076
  }
@@ -10266,7 +10469,7 @@ function LinearView({
10266
10469
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
10267
10470
  const isDone = i < currentIdx;
10268
10471
  const isCurrent = i === currentIdx;
10269
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
10472
+ return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
10270
10473
  i > 0 && /* @__PURE__ */ jsx(
10271
10474
  Typography,
10272
10475
  {
@@ -10801,7 +11004,7 @@ function SequenceBar({
10801
11004
  else onSlotRemove?.(index);
10802
11005
  }, [emit, slotRemoveEvent, onSlotRemove, playing]);
10803
11006
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
10804
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
11007
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
10805
11008
  i > 0 && /* @__PURE__ */ jsx(
10806
11009
  Typography,
10807
11010
  {
@@ -11450,7 +11653,7 @@ var init_ErrorBoundary = __esm({
11450
11653
  }
11451
11654
  );
11452
11655
  };
11453
- ErrorBoundary = class extends React85__default.Component {
11656
+ ErrorBoundary = class extends React86__default.Component {
11454
11657
  constructor(props) {
11455
11658
  super(props);
11456
11659
  __publicField(this, "reset", () => {
@@ -12102,7 +12305,7 @@ var init_Container = __esm({
12102
12305
  as: Component = "div"
12103
12306
  }) => {
12104
12307
  const resolvedSize = maxWidth ?? size ?? "lg";
12105
- return React85__default.createElement(
12308
+ return React86__default.createElement(
12106
12309
  Component,
12107
12310
  {
12108
12311
  className: cn(
@@ -15067,7 +15270,7 @@ var init_CodeBlock = __esm({
15067
15270
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
15068
15271
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
15069
15272
  HIDDEN_LINE_NUMBERS = { display: "none" };
15070
- CodeBlock = React85__default.memo(
15273
+ CodeBlock = React86__default.memo(
15071
15274
  ({
15072
15275
  code: rawCode,
15073
15276
  language = "text",
@@ -15655,7 +15858,7 @@ var init_MarkdownContent = __esm({
15655
15858
  init_Box();
15656
15859
  init_CodeBlock();
15657
15860
  init_cn();
15658
- MarkdownContent = React85__default.memo(
15861
+ MarkdownContent = React86__default.memo(
15659
15862
  ({ content, direction = "ltr", className }) => {
15660
15863
  const { t: _t } = useTranslate();
15661
15864
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -16982,7 +17185,7 @@ var init_StateMachineView = __esm({
16982
17185
  style: { top: title ? 30 : 0 },
16983
17186
  children: [
16984
17187
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
16985
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React85__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
17188
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React86__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
16986
17189
  StateNode2,
16987
17190
  {
16988
17191
  state,
@@ -22804,8 +23007,8 @@ var init_Menu = __esm({
22804
23007
  "bottom-end": "bottom-start"
22805
23008
  };
22806
23009
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
22807
- const triggerChild = React85__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
22808
- const triggerElement = React85__default.cloneElement(
23010
+ const triggerChild = React86__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
23011
+ const triggerElement = React86__default.cloneElement(
22809
23012
  triggerChild,
22810
23013
  {
22811
23014
  ref: triggerRef,
@@ -22900,14 +23103,14 @@ function useDataDnd(args) {
22900
23103
  const isZone = Boolean(dragGroup || accepts || sortable);
22901
23104
  const enabled = isZone || Boolean(dndRoot);
22902
23105
  const eventBus = useEventBus();
22903
- const parentRoot = React85__default.useContext(RootCtx);
23106
+ const parentRoot = React86__default.useContext(RootCtx);
22904
23107
  const isRoot = enabled && parentRoot === null;
22905
- const zoneId = React85__default.useId();
23108
+ const zoneId = React86__default.useId();
22906
23109
  const ownGroup = dragGroup ?? accepts ?? zoneId;
22907
- const [optimisticOrders, setOptimisticOrders] = React85__default.useState(() => /* @__PURE__ */ new Map());
22908
- const optimisticOrdersRef = React85__default.useRef(optimisticOrders);
23110
+ const [optimisticOrders, setOptimisticOrders] = React86__default.useState(() => /* @__PURE__ */ new Map());
23111
+ const optimisticOrdersRef = React86__default.useRef(optimisticOrders);
22909
23112
  optimisticOrdersRef.current = optimisticOrders;
22910
- const clearOptimisticOrder = React85__default.useCallback((group) => {
23113
+ const clearOptimisticOrder = React86__default.useCallback((group) => {
22911
23114
  setOptimisticOrders((prev) => {
22912
23115
  if (!prev.has(group)) return prev;
22913
23116
  const next = new Map(prev);
@@ -22932,7 +23135,7 @@ function useDataDnd(args) {
22932
23135
  const raw = it[dndItemIdField];
22933
23136
  return raw != null ? String(raw) : `__idx_${idx}`;
22934
23137
  }).join("|");
22935
- const itemIds = React85__default.useMemo(
23138
+ const itemIds = React86__default.useMemo(
22936
23139
  () => orderedItems.map((it, idx) => {
22937
23140
  const raw = it[dndItemIdField];
22938
23141
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -22943,7 +23146,7 @@ function useDataDnd(args) {
22943
23146
  const raw = it[dndItemIdField];
22944
23147
  return raw != null ? String(raw) : `__${idx}`;
22945
23148
  }).join("|");
22946
- React85__default.useEffect(() => {
23149
+ React86__default.useEffect(() => {
22947
23150
  const root = isRoot ? null : parentRoot;
22948
23151
  if (root) {
22949
23152
  root.clearOptimisticOrder(ownGroup);
@@ -22951,20 +23154,20 @@ function useDataDnd(args) {
22951
23154
  clearOptimisticOrder(ownGroup);
22952
23155
  }
22953
23156
  }, [itemsContentSig, ownGroup]);
22954
- const zonesRef = React85__default.useRef(/* @__PURE__ */ new Map());
22955
- const registerZone = React85__default.useCallback((zoneId2, meta2) => {
23157
+ const zonesRef = React86__default.useRef(/* @__PURE__ */ new Map());
23158
+ const registerZone = React86__default.useCallback((zoneId2, meta2) => {
22956
23159
  zonesRef.current.set(zoneId2, meta2);
22957
23160
  }, []);
22958
- const unregisterZone = React85__default.useCallback((zoneId2) => {
23161
+ const unregisterZone = React86__default.useCallback((zoneId2) => {
22959
23162
  zonesRef.current.delete(zoneId2);
22960
23163
  }, []);
22961
- const [activeDrag, setActiveDrag] = React85__default.useState(null);
22962
- const [overZoneGroup, setOverZoneGroup] = React85__default.useState(null);
22963
- const meta = React85__default.useMemo(
23164
+ const [activeDrag, setActiveDrag] = React86__default.useState(null);
23165
+ const [overZoneGroup, setOverZoneGroup] = React86__default.useState(null);
23166
+ const meta = React86__default.useMemo(
22964
23167
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
22965
23168
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
22966
23169
  );
22967
- React85__default.useEffect(() => {
23170
+ React86__default.useEffect(() => {
22968
23171
  const target = isRoot ? null : parentRoot;
22969
23172
  if (!target) {
22970
23173
  zonesRef.current.set(zoneId, meta);
@@ -22983,7 +23186,7 @@ function useDataDnd(args) {
22983
23186
  }, [parentRoot, isRoot, zoneId, meta]);
22984
23187
  const sensors = useAlmadarDndSensors(true);
22985
23188
  const collisionDetection = almadarDndCollisionDetection;
22986
- const findZoneByItem = React85__default.useCallback(
23189
+ const findZoneByItem = React86__default.useCallback(
22987
23190
  (id) => {
22988
23191
  for (const z of zonesRef.current.values()) {
22989
23192
  if (z.itemIds.includes(id)) return z;
@@ -22992,7 +23195,7 @@ function useDataDnd(args) {
22992
23195
  },
22993
23196
  []
22994
23197
  );
22995
- React85__default.useCallback(
23198
+ React86__default.useCallback(
22996
23199
  (group) => {
22997
23200
  for (const z of zonesRef.current.values()) {
22998
23201
  if (z.group === group) return z;
@@ -23001,7 +23204,7 @@ function useDataDnd(args) {
23001
23204
  },
23002
23205
  []
23003
23206
  );
23004
- const handleDragEnd = React85__default.useCallback(
23207
+ const handleDragEnd = React86__default.useCallback(
23005
23208
  (event) => {
23006
23209
  const { active, over } = event;
23007
23210
  const activeIdStr = String(active.id);
@@ -23092,8 +23295,8 @@ function useDataDnd(args) {
23092
23295
  },
23093
23296
  [eventBus]
23094
23297
  );
23095
- const sortableData = React85__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
23096
- const SortableItem = React85__default.useCallback(
23298
+ const sortableData = React86__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
23299
+ const SortableItem = React86__default.useCallback(
23097
23300
  ({ id, children }) => {
23098
23301
  const {
23099
23302
  attributes,
@@ -23133,7 +23336,7 @@ function useDataDnd(args) {
23133
23336
  id: droppableId,
23134
23337
  data: sortableData
23135
23338
  });
23136
- const ctx = React85__default.useContext(RootCtx);
23339
+ const ctx = React86__default.useContext(RootCtx);
23137
23340
  const activeDrag2 = ctx?.activeDrag ?? null;
23138
23341
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
23139
23342
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -23148,7 +23351,7 @@ function useDataDnd(args) {
23148
23351
  showForeignPlaceholder,
23149
23352
  ctxAvailable: ctx != null
23150
23353
  });
23151
- React85__default.useEffect(() => {
23354
+ React86__default.useEffect(() => {
23152
23355
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
23153
23356
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
23154
23357
  return /* @__PURE__ */ jsx(
@@ -23162,11 +23365,11 @@ function useDataDnd(args) {
23162
23365
  }
23163
23366
  );
23164
23367
  };
23165
- const rootContextValue = React85__default.useMemo(
23368
+ const rootContextValue = React86__default.useMemo(
23166
23369
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
23167
23370
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
23168
23371
  );
23169
- const handleDragStart = React85__default.useCallback((event) => {
23372
+ const handleDragStart = React86__default.useCallback((event) => {
23170
23373
  const sourceZone = findZoneByItem(event.active.id);
23171
23374
  const rect = event.active.rect.current.initial;
23172
23375
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -23185,7 +23388,7 @@ function useDataDnd(args) {
23185
23388
  isRoot
23186
23389
  });
23187
23390
  }, [findZoneByItem, isRoot, zoneId]);
23188
- const handleDragOver = React85__default.useCallback((event) => {
23391
+ const handleDragOver = React86__default.useCallback((event) => {
23189
23392
  const { active, over } = event;
23190
23393
  const overData = over?.data?.current;
23191
23394
  const overGroup = overData?.dndGroup ?? null;
@@ -23255,7 +23458,7 @@ function useDataDnd(args) {
23255
23458
  return next;
23256
23459
  });
23257
23460
  }, []);
23258
- const handleDragCancel = React85__default.useCallback((event) => {
23461
+ const handleDragCancel = React86__default.useCallback((event) => {
23259
23462
  setActiveDrag(null);
23260
23463
  setOverZoneGroup(null);
23261
23464
  dndLog.warn("dragCancel", {
@@ -23263,12 +23466,12 @@ function useDataDnd(args) {
23263
23466
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
23264
23467
  });
23265
23468
  }, []);
23266
- const handleDragEndWithCleanup = React85__default.useCallback((event) => {
23469
+ const handleDragEndWithCleanup = React86__default.useCallback((event) => {
23267
23470
  handleDragEnd(event);
23268
23471
  setActiveDrag(null);
23269
23472
  setOverZoneGroup(null);
23270
23473
  }, [handleDragEnd]);
23271
- const wrapContainer = React85__default.useCallback(
23474
+ const wrapContainer = React86__default.useCallback(
23272
23475
  (children) => {
23273
23476
  if (!enabled) return children;
23274
23477
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -23322,7 +23525,7 @@ var init_useDataDnd = __esm({
23322
23525
  init_useAlmadarDndCollision();
23323
23526
  init_Box();
23324
23527
  dndLog = createLogger("almadar:ui:dnd");
23325
- RootCtx = React85__default.createContext(null);
23528
+ RootCtx = React86__default.createContext(null);
23326
23529
  }
23327
23530
  });
23328
23531
  function renderIconInput(icon, props) {
@@ -23864,7 +24067,7 @@ function DataList({
23864
24067
  }) {
23865
24068
  const eventBus = useEventBus();
23866
24069
  const { t } = useTranslate();
23867
- const [visibleCount, setVisibleCount] = React85__default.useState(pageSize || Infinity);
24070
+ const [visibleCount, setVisibleCount] = React86__default.useState(pageSize || Infinity);
23868
24071
  const fieldDefs = fields ?? columns ?? [];
23869
24072
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
23870
24073
  const dnd = useDataDnd({
@@ -23880,14 +24083,14 @@ function DataList({
23880
24083
  dndRoot
23881
24084
  });
23882
24085
  const orderedData = dnd.orderedItems;
23883
- const allData = React85__default.useMemo(
24086
+ const allData = React86__default.useMemo(
23884
24087
  () => sortRows(orderedData, sortBy, sortDirection),
23885
24088
  [orderedData, sortBy, sortDirection]
23886
24089
  );
23887
24090
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
23888
24091
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
23889
24092
  const hasRenderProp = typeof children === "function";
23890
- React85__default.useEffect(() => {
24093
+ React86__default.useEffect(() => {
23891
24094
  const renderItemTypeOf = typeof schemaRenderItem;
23892
24095
  const childrenTypeOf = typeof children;
23893
24096
  if (data.length > 0 && !hasRenderProp) {
@@ -24002,7 +24205,7 @@ function DataList({
24002
24205
  return v === void 0 || v === null || v === "" ? raw : String(v);
24003
24206
  };
24004
24207
  return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn("py-2", className), children: [
24005
- groups2.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
24208
+ groups2.map((group, gi) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
24006
24209
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
24007
24210
  group.items.map((itemData, index) => {
24008
24211
  const id = itemData.id || `${gi}-${index}`;
@@ -24201,7 +24404,7 @@ function DataList({
24201
24404
  className
24202
24405
  ),
24203
24406
  children: [
24204
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
24407
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
24205
24408
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
24206
24409
  group.items.map(
24207
24410
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -24288,7 +24491,7 @@ var init_FormSection = __esm({
24288
24491
  columns = 1,
24289
24492
  className
24290
24493
  }) => {
24291
- const [collapsed, setCollapsed] = React85__default.useState(defaultCollapsed);
24494
+ const [collapsed, setCollapsed] = React86__default.useState(defaultCollapsed);
24292
24495
  const { t } = useTranslate();
24293
24496
  const eventBus = useEventBus();
24294
24497
  const gridClass = {
@@ -24296,7 +24499,7 @@ var init_FormSection = __esm({
24296
24499
  2: "grid-cols-1 md:grid-cols-2",
24297
24500
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
24298
24501
  }[columns];
24299
- React85__default.useCallback(() => {
24502
+ React86__default.useCallback(() => {
24300
24503
  if (collapsible) {
24301
24504
  setCollapsed((prev) => !prev);
24302
24505
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -25341,7 +25544,7 @@ var init_Flex = __esm({
25341
25544
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
25342
25545
  }
25343
25546
  }
25344
- return React85__default.createElement(Component, {
25547
+ return React86__default.createElement(Component, {
25345
25548
  className: cn(
25346
25549
  inline ? "inline-flex" : "flex",
25347
25550
  directionStyles[direction],
@@ -25460,7 +25663,7 @@ var init_Grid = __esm({
25460
25663
  as: Component = "div"
25461
25664
  }) => {
25462
25665
  const mergedStyle = rows ? { gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`, ...style } : style;
25463
- return React85__default.createElement(
25666
+ return React86__default.createElement(
25464
25667
  Component,
25465
25668
  {
25466
25669
  className: cn(
@@ -25692,9 +25895,9 @@ var init_Popover = __esm({
25692
25895
  onMouseLeave: handleClose,
25693
25896
  onPointerDown: tapTriggerProps.onPointerDown
25694
25897
  };
25695
- const childElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
25898
+ const childElement = React86__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
25696
25899
  const childPointerDown = childElement.props.onPointerDown;
25697
- const triggerElement = React85__default.cloneElement(
25900
+ const triggerElement = React86__default.cloneElement(
25698
25901
  childElement,
25699
25902
  {
25700
25903
  ref: triggerRef,
@@ -26303,9 +26506,9 @@ var init_Tooltip = __esm({
26303
26506
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
26304
26507
  };
26305
26508
  }, []);
26306
- const triggerElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
26509
+ const triggerElement = React86__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
26307
26510
  const childPointerDown = triggerElement.props.onPointerDown;
26308
- const trigger = React85__default.cloneElement(triggerElement, {
26511
+ const trigger = React86__default.cloneElement(triggerElement, {
26309
26512
  ref: triggerRef,
26310
26513
  onMouseEnter: handleMouseEnter,
26311
26514
  onMouseLeave: handleMouseLeave,
@@ -26395,7 +26598,7 @@ var init_WizardProgress = __esm({
26395
26598
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
26396
26599
  const isActive = index === currentStep;
26397
26600
  const isCompleted = index < currentStep;
26398
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
26601
+ return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
26399
26602
  /* @__PURE__ */ jsx(
26400
26603
  "button",
26401
26604
  {
@@ -28030,7 +28233,7 @@ var init_MapView = __esm({
28030
28233
  shadowSize: [41, 41]
28031
28234
  });
28032
28235
  L.Marker.prototype.options.icon = defaultIcon;
28033
- const { useEffect: useEffect62, useRef: useRef61, useCallback: useCallback95, useState: useState93 } = React85__default;
28236
+ const { useEffect: useEffect62, useRef: useRef61, useCallback: useCallback95, useState: useState93 } = React86__default;
28034
28237
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
28035
28238
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
28036
28239
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -28948,8 +29151,8 @@ function TableView({
28948
29151
  }) {
28949
29152
  const eventBus = useEventBus();
28950
29153
  const { t } = useTranslate();
28951
- const [visibleCount, setVisibleCount] = React85__default.useState(pageSize > 0 ? pageSize : Infinity);
28952
- const [localSelected, setLocalSelected] = React85__default.useState(/* @__PURE__ */ new Set());
29154
+ const [visibleCount, setVisibleCount] = React86__default.useState(pageSize > 0 ? pageSize : Infinity);
29155
+ const [localSelected, setLocalSelected] = React86__default.useState(/* @__PURE__ */ new Set());
28953
29156
  const colDefs = (Array.isArray(columns) ? columns : void 0) ?? (Array.isArray(fields) ? fields : void 0) ?? [];
28954
29157
  const actionDefs = Array.isArray(itemActions) ? itemActions : [];
28955
29158
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
@@ -28971,7 +29174,7 @@ function TableView({
28971
29174
  const hasRenderProp = typeof children === "function";
28972
29175
  const idField = dndItemIdField ?? "id";
28973
29176
  const isCoarsePointer = useMediaQuery("(pointer: coarse)");
28974
- React85__default.useEffect(() => {
29177
+ React86__default.useEffect(() => {
28975
29178
  tableViewLog.debug("render", {
28976
29179
  rowCount: data.length,
28977
29180
  colCount: colDefs.length,
@@ -29028,7 +29231,7 @@ function TableView({
29028
29231
  };
29029
29232
  eventBus.emit(`UI:${itemClickEvent}`, payload);
29030
29233
  };
29031
- const colFloors = React85__default.useMemo(
29234
+ const colFloors = React86__default.useMemo(
29032
29235
  () => colDefs.map((col) => {
29033
29236
  const longest = data.reduce((widest, row) => {
29034
29237
  const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
@@ -29190,12 +29393,12 @@ function TableView({
29190
29393
  ]
29191
29394
  }
29192
29395
  );
29193
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React85__default.Fragment, { children: rowInner }, id);
29396
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React86__default.Fragment, { children: rowInner }, id);
29194
29397
  };
29195
29398
  const items = Array.from(data);
29196
29399
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
29197
29400
  let runningIndex = 0;
29198
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
29401
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
29199
29402
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
29200
29403
  group.items.map((row) => renderRow(row, runningIndex++))
29201
29404
  ] }, gi)) });
@@ -30558,7 +30761,7 @@ var init_StepFlow = __esm({
30558
30761
  className
30559
30762
  }) => {
30560
30763
  if (orientation === "vertical") {
30561
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React85__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
30764
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React86__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
30562
30765
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
30563
30766
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
30564
30767
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -30569,7 +30772,7 @@ var init_StepFlow = __esm({
30569
30772
  ] })
30570
30773
  ] }) }, index)) });
30571
30774
  }
30572
- 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(React85__default.Fragment, { children: [
30775
+ return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
30573
30776
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
30574
30777
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
30575
30778
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -31559,7 +31762,7 @@ var init_LikertScale = __esm({
31559
31762
  md: "text-base",
31560
31763
  lg: "text-lg"
31561
31764
  };
31562
- LikertScale = React85__default.forwardRef(
31765
+ LikertScale = React86__default.forwardRef(
31563
31766
  ({
31564
31767
  question,
31565
31768
  options = DEFAULT_LIKERT_OPTIONS,
@@ -31571,7 +31774,7 @@ var init_LikertScale = __esm({
31571
31774
  variant = "radios",
31572
31775
  className
31573
31776
  }, ref) => {
31574
- const groupId = React85__default.useId();
31777
+ const groupId = React86__default.useId();
31575
31778
  const eventBus = useEventBus();
31576
31779
  const handleSelect = useCallback(
31577
31780
  (next) => {
@@ -33860,7 +34063,7 @@ var init_DocBreadcrumb = __esm({
33860
34063
  "aria-label": t("aria.breadcrumb"),
33861
34064
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
33862
34065
  const isLast = idx === items.length - 1;
33863
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
34066
+ return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
33864
34067
  idx > 0 && /* @__PURE__ */ jsx(
33865
34068
  Icon,
33866
34069
  {
@@ -34729,7 +34932,7 @@ var init_MiniStateMachine = __esm({
34729
34932
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
34730
34933
  const tc = transitionCounts[s.name] ?? 0;
34731
34934
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
34732
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
34935
+ return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
34733
34936
  /* @__PURE__ */ jsx(
34734
34937
  AvlState,
34735
34938
  {
@@ -34933,7 +35136,7 @@ var init_PageHeader = __esm({
34933
35136
  info: "bg-info/10 text-info"
34934
35137
  };
34935
35138
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
34936
- 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(React85__default.Fragment, { children: [
35139
+ breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
34937
35140
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
34938
35141
  crumb.href ? /* @__PURE__ */ jsx(
34939
35142
  "a",
@@ -35291,7 +35494,7 @@ var init_Section = __esm({
35291
35494
  as: Component = "section"
35292
35495
  }) => {
35293
35496
  const hasHeader = title || description || action;
35294
- return React85__default.createElement(
35497
+ return React86__default.createElement(
35295
35498
  Component,
35296
35499
  {
35297
35500
  className: cn(
@@ -35665,7 +35868,7 @@ var init_WizardContainer = __esm({
35665
35868
  const isCompleted = index < currentStep;
35666
35869
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
35667
35870
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
35668
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
35871
+ return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
35669
35872
  /* @__PURE__ */ jsx(
35670
35873
  Button,
35671
35874
  {
@@ -37452,7 +37655,7 @@ var init_ImportPreviewTree = __esm({
37452
37655
  const renderUnit = (unit, childrenByParent, depth) => {
37453
37656
  const summary = fieldSummary(unit);
37454
37657
  const children = childrenByParent.get(unit.ref) ?? [];
37455
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
37658
+ return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
37456
37659
  /* @__PURE__ */ jsxs(
37457
37660
  Box,
37458
37661
  {
@@ -37549,7 +37752,7 @@ var init_ImportProgress = __esm({
37549
37752
  PIPELINE.map((key, index) => {
37550
37753
  const isComplete = index < currentIndex;
37551
37754
  const isActive = index === currentIndex;
37552
- return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
37755
+ return /* @__PURE__ */ jsxs(React86__default.Fragment, { children: [
37553
37756
  index > 0 ? /* @__PURE__ */ jsx(Box, { className: "h-px w-4 bg-border" }) : null,
37554
37757
  /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-1", "data-testid": `import-progress-step-${key}`, children: [
37555
37758
  /* @__PURE__ */ jsx(
@@ -38662,7 +38865,7 @@ var init_DrawGroup = __esm({
38662
38865
  }
38663
38866
  });
38664
38867
  function extractTitle(children) {
38665
- if (!React85__default.isValidElement(children)) return void 0;
38868
+ if (!React86__default.isValidElement(children)) return void 0;
38666
38869
  const props = children.props;
38667
38870
  if (typeof props.title === "string") {
38668
38871
  return props.title;
@@ -39012,12 +39215,12 @@ var init_Form = __esm({
39012
39215
  const isSchemaEntity = isOrbitalEntitySchema(entity);
39013
39216
  const resolvedEntity = isSchemaEntity ? entity : void 0;
39014
39217
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
39015
- const normalizedInitialData = React85__default.useMemo(() => {
39218
+ const normalizedInitialData = React86__default.useMemo(() => {
39016
39219
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
39017
39220
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
39018
39221
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
39019
39222
  }, [entity, initialData]);
39020
- const entityDerivedFields = React85__default.useMemo(() => {
39223
+ const entityDerivedFields = React86__default.useMemo(() => {
39021
39224
  if (fields && fields.length > 0) return void 0;
39022
39225
  if (!resolvedEntity) return void 0;
39023
39226
  return resolvedEntity.fields.map(
@@ -39038,16 +39241,16 @@ var init_Form = __esm({
39038
39241
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
39039
39242
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
39040
39243
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
39041
- const [formData, setFormData] = React85__default.useState(
39244
+ const [formData, setFormData] = React86__default.useState(
39042
39245
  normalizedInitialData
39043
39246
  );
39044
- const [collapsedSections, setCollapsedSections] = React85__default.useState(
39247
+ const [collapsedSections, setCollapsedSections] = React86__default.useState(
39045
39248
  /* @__PURE__ */ new Set()
39046
39249
  );
39047
- const [submitError, setSubmitError] = React85__default.useState(null);
39048
- const formRef = React85__default.useRef(null);
39250
+ const [submitError, setSubmitError] = React86__default.useState(null);
39251
+ const formRef = React86__default.useRef(null);
39049
39252
  const formMode = props.mode;
39050
- const mountedRef = React85__default.useRef(false);
39253
+ const mountedRef = React86__default.useRef(false);
39051
39254
  if (!mountedRef.current) {
39052
39255
  mountedRef.current = true;
39053
39256
  debug("forms", "mount", {
@@ -39060,7 +39263,7 @@ var init_Form = __esm({
39060
39263
  });
39061
39264
  }
39062
39265
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
39063
- const evalContext = React85__default.useMemo(
39266
+ const evalContext = React86__default.useMemo(
39064
39267
  () => ({
39065
39268
  formValues: formData,
39066
39269
  globalVariables: externalContext?.globalVariables ?? {},
@@ -39069,7 +39272,7 @@ var init_Form = __esm({
39069
39272
  }),
39070
39273
  [formData, externalContext]
39071
39274
  );
39072
- React85__default.useEffect(() => {
39275
+ React86__default.useEffect(() => {
39073
39276
  debug("forms", "initialData-sync", {
39074
39277
  mode: formMode,
39075
39278
  normalizedInitialData,
@@ -39080,7 +39283,7 @@ var init_Form = __esm({
39080
39283
  setFormData(normalizedInitialData);
39081
39284
  }
39082
39285
  }, [normalizedInitialData]);
39083
- const processCalculations = React85__default.useCallback(
39286
+ const processCalculations = React86__default.useCallback(
39084
39287
  (changedFieldId, newFormData) => {
39085
39288
  if (!hiddenCalculations.length) return;
39086
39289
  const context = {
@@ -39105,7 +39308,7 @@ var init_Form = __esm({
39105
39308
  },
39106
39309
  [hiddenCalculations, externalContext, eventBus]
39107
39310
  );
39108
- const checkViolations = React85__default.useCallback(
39311
+ const checkViolations = React86__default.useCallback(
39109
39312
  (changedFieldId, newFormData) => {
39110
39313
  if (!violationTriggers.length) return;
39111
39314
  const context = {
@@ -39143,7 +39346,7 @@ var init_Form = __esm({
39143
39346
  processCalculations(name, newFormData);
39144
39347
  checkViolations(name, newFormData);
39145
39348
  };
39146
- const isFieldVisible = React85__default.useCallback(
39349
+ const isFieldVisible = React86__default.useCallback(
39147
39350
  (fieldName) => {
39148
39351
  const condition = conditionalFields[fieldName];
39149
39352
  if (!condition) return true;
@@ -39151,7 +39354,7 @@ var init_Form = __esm({
39151
39354
  },
39152
39355
  [conditionalFields, evalContext]
39153
39356
  );
39154
- const isSectionVisible = React85__default.useCallback(
39357
+ const isSectionVisible = React86__default.useCallback(
39155
39358
  (section) => {
39156
39359
  if (!section.condition) return true;
39157
39360
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -39227,7 +39430,7 @@ var init_Form = __esm({
39227
39430
  eventBus.emit(`UI:${onCancel}`);
39228
39431
  }
39229
39432
  };
39230
- const renderField = React85__default.useCallback(
39433
+ const renderField = React86__default.useCallback(
39231
39434
  (field) => {
39232
39435
  const fieldName = field.name || field.field;
39233
39436
  if (!fieldName) return null;
@@ -39248,7 +39451,7 @@ var init_Form = __esm({
39248
39451
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
39249
39452
  );
39250
39453
  const effectiveFields = entityDerivedFields ?? fields;
39251
- const normalizedFields = React85__default.useMemo(() => {
39454
+ const normalizedFields = React86__default.useMemo(() => {
39252
39455
  if (!effectiveFields || effectiveFields.length === 0) return [];
39253
39456
  return effectiveFields.map((field) => {
39254
39457
  if (typeof field === "string") {
@@ -39272,7 +39475,7 @@ var init_Form = __esm({
39272
39475
  return field;
39273
39476
  });
39274
39477
  }, [effectiveFields, resolvedEntity]);
39275
- const schemaFields = React85__default.useMemo(() => {
39478
+ const schemaFields = React86__default.useMemo(() => {
39276
39479
  if (normalizedFields.length === 0) return null;
39277
39480
  if (isDebugEnabled()) {
39278
39481
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -39282,7 +39485,7 @@ var init_Form = __esm({
39282
39485
  }
39283
39486
  return normalizedFields.map(renderField).filter(Boolean);
39284
39487
  }, [normalizedFields, renderField, entityName, conditionalFields]);
39285
- const sectionElements = React85__default.useMemo(() => {
39488
+ const sectionElements = React86__default.useMemo(() => {
39286
39489
  if (!sections || sections.length === 0) return null;
39287
39490
  return sections.map((section) => {
39288
39491
  if (!isSectionVisible(section)) {
@@ -40008,7 +40211,7 @@ var init_List = __esm({
40008
40211
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
40009
40212
  return [];
40010
40213
  }, [entity]);
40011
- const getItemActions = React85__default.useCallback(
40214
+ const getItemActions = React86__default.useCallback(
40012
40215
  (item) => {
40013
40216
  if (!itemActions) return [];
40014
40217
  if (typeof itemActions === "function") {
@@ -40489,7 +40692,7 @@ var init_MediaGallery = __esm({
40489
40692
  [selectable, selectedItems, selectionEvent, eventBus]
40490
40693
  );
40491
40694
  const entityData = Array.isArray(entity) ? entity : [];
40492
- const items = React85__default.useMemo(() => {
40695
+ const items = React86__default.useMemo(() => {
40493
40696
  if (propItems && propItems.length > 0) return propItems;
40494
40697
  if (entityData.length === 0) return [];
40495
40698
  return entityData.map((record, idx) => {
@@ -40654,7 +40857,7 @@ var init_MediaGallery = __esm({
40654
40857
  }
40655
40858
  });
40656
40859
  function extractTitle2(children) {
40657
- if (!React85__default.isValidElement(children)) return void 0;
40860
+ if (!React86__default.isValidElement(children)) return void 0;
40658
40861
  const props = children.props;
40659
40862
  if (typeof props.title === "string") {
40660
40863
  return props.title;
@@ -40909,7 +41112,7 @@ var init_debugRegistry = __esm({
40909
41112
  }
40910
41113
  });
40911
41114
  function useDebugData() {
40912
- const [data, setData] = React85.useState(() => ({
41115
+ const [data, setData] = React86.useState(() => ({
40913
41116
  traits: [],
40914
41117
  ticks: [],
40915
41118
  guards: [],
@@ -40923,7 +41126,7 @@ function useDebugData() {
40923
41126
  },
40924
41127
  lastUpdate: Date.now()
40925
41128
  }));
40926
- React85.useEffect(() => {
41129
+ React86.useEffect(() => {
40927
41130
  const updateData = () => {
40928
41131
  setData({
40929
41132
  traits: getAllTraits(),
@@ -41032,12 +41235,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
41032
41235
  return positions;
41033
41236
  }
41034
41237
  function WalkMinimap() {
41035
- const [walkStep, setWalkStep] = React85.useState(null);
41036
- const [traits2, setTraits] = React85.useState([]);
41037
- const [coveredEdges, setCoveredEdges] = React85.useState([]);
41038
- const [completedTraits, setCompletedTraits] = React85.useState(/* @__PURE__ */ new Set());
41039
- const prevTraitRef = React85.useRef(null);
41040
- React85.useEffect(() => {
41238
+ const [walkStep, setWalkStep] = React86.useState(null);
41239
+ const [traits2, setTraits] = React86.useState([]);
41240
+ const [coveredEdges, setCoveredEdges] = React86.useState([]);
41241
+ const [completedTraits, setCompletedTraits] = React86.useState(/* @__PURE__ */ new Set());
41242
+ const prevTraitRef = React86.useRef(null);
41243
+ React86.useEffect(() => {
41041
41244
  const interval = setInterval(() => {
41042
41245
  const w = window;
41043
41246
  const step = w.__orbitalWalkStep;
@@ -41473,15 +41676,15 @@ var init_EntitiesTab = __esm({
41473
41676
  });
41474
41677
  function EventFlowTab({ events: events2 }) {
41475
41678
  const { t } = useTranslate();
41476
- const [filter, setFilter] = React85.useState("all");
41477
- const containerRef = React85.useRef(null);
41478
- const [autoScroll, setAutoScroll] = React85.useState(true);
41479
- React85.useEffect(() => {
41679
+ const [filter, setFilter] = React86.useState("all");
41680
+ const containerRef = React86.useRef(null);
41681
+ const [autoScroll, setAutoScroll] = React86.useState(true);
41682
+ React86.useEffect(() => {
41480
41683
  if (autoScroll && containerRef.current) {
41481
41684
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
41482
41685
  }
41483
41686
  }, [events2.length, autoScroll]);
41484
- const filteredEvents = React85.useMemo(() => {
41687
+ const filteredEvents = React86.useMemo(() => {
41485
41688
  if (filter === "all") return events2;
41486
41689
  return events2.filter((e) => e.type === filter);
41487
41690
  }, [events2, filter]);
@@ -41597,7 +41800,7 @@ var init_EventFlowTab = __esm({
41597
41800
  });
41598
41801
  function GuardsPanel({ guards }) {
41599
41802
  const { t } = useTranslate();
41600
- const [filter, setFilter] = React85.useState("all");
41803
+ const [filter, setFilter] = React86.useState("all");
41601
41804
  if (guards.length === 0) {
41602
41805
  return /* @__PURE__ */ jsx(
41603
41806
  EmptyState,
@@ -41610,7 +41813,7 @@ function GuardsPanel({ guards }) {
41610
41813
  }
41611
41814
  const passedCount = guards.filter((g) => g.result).length;
41612
41815
  const failedCount = guards.length - passedCount;
41613
- const filteredGuards = React85.useMemo(() => {
41816
+ const filteredGuards = React86.useMemo(() => {
41614
41817
  if (filter === "all") return guards;
41615
41818
  if (filter === "passed") return guards.filter((g) => g.result);
41616
41819
  return guards.filter((g) => !g.result);
@@ -41773,10 +41976,10 @@ function EffectBadge({ effect }) {
41773
41976
  }
41774
41977
  function TransitionTimeline({ transitions }) {
41775
41978
  const { t } = useTranslate();
41776
- const containerRef = React85.useRef(null);
41777
- const [autoScroll, setAutoScroll] = React85.useState(true);
41778
- const [expandedId, setExpandedId] = React85.useState(null);
41779
- React85.useEffect(() => {
41979
+ const containerRef = React86.useRef(null);
41980
+ const [autoScroll, setAutoScroll] = React86.useState(true);
41981
+ const [expandedId, setExpandedId] = React86.useState(null);
41982
+ React86.useEffect(() => {
41780
41983
  if (autoScroll && containerRef.current) {
41781
41984
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
41782
41985
  }
@@ -42056,9 +42259,9 @@ function getAllEvents(traits2) {
42056
42259
  function EventDispatcherTab({ traits: traits2, schema }) {
42057
42260
  const eventBus = useEventBus();
42058
42261
  const { t } = useTranslate();
42059
- const [log13, setLog] = React85.useState([]);
42060
- const prevStatesRef = React85.useRef(/* @__PURE__ */ new Map());
42061
- React85.useEffect(() => {
42262
+ const [log13, setLog] = React86.useState([]);
42263
+ const prevStatesRef = React86.useRef(/* @__PURE__ */ new Map());
42264
+ React86.useEffect(() => {
42062
42265
  for (const trait of traits2) {
42063
42266
  const prev = prevStatesRef.current.get(trait.id);
42064
42267
  if (prev && prev !== trait.currentState) {
@@ -42227,10 +42430,10 @@ function VerifyModePanel({
42227
42430
  localCount
42228
42431
  }) {
42229
42432
  const { t } = useTranslate();
42230
- const [expanded, setExpanded] = React85.useState(true);
42231
- const scrollRef = React85.useRef(null);
42232
- const prevCountRef = React85.useRef(0);
42233
- React85.useEffect(() => {
42433
+ const [expanded, setExpanded] = React86.useState(true);
42434
+ const scrollRef = React86.useRef(null);
42435
+ const prevCountRef = React86.useRef(0);
42436
+ React86.useEffect(() => {
42234
42437
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
42235
42438
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
42236
42439
  }
@@ -42287,10 +42490,10 @@ function RuntimeDebugger({
42287
42490
  schema
42288
42491
  }) {
42289
42492
  const { t } = useTranslate();
42290
- const [isCollapsed, setIsCollapsed] = React85.useState(mode === "verify" ? true : defaultCollapsed);
42291
- const [isVisible, setIsVisible] = React85.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
42493
+ const [isCollapsed, setIsCollapsed] = React86.useState(mode === "verify" ? true : defaultCollapsed);
42494
+ const [isVisible, setIsVisible] = React86.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
42292
42495
  const debugData = useDebugData();
42293
- React85.useEffect(() => {
42496
+ React86.useEffect(() => {
42294
42497
  if (mode === "inline") return;
42295
42498
  return onDebugToggle((enabled) => {
42296
42499
  setIsVisible(enabled);
@@ -42299,7 +42502,7 @@ function RuntimeDebugger({
42299
42502
  }
42300
42503
  });
42301
42504
  }, [mode]);
42302
- React85.useEffect(() => {
42505
+ React86.useEffect(() => {
42303
42506
  if (mode === "inline") return;
42304
42507
  const handleKeyDown = (e) => {
42305
42508
  if (e.key === "`" && isVisible) {
@@ -42819,7 +43022,7 @@ var init_StatCard = __esm({
42819
43022
  const labelToUse = propLabel ?? propTitle;
42820
43023
  const eventBus = useEventBus();
42821
43024
  const { t } = useTranslate();
42822
- const handleActionClick = React85__default.useCallback(() => {
43025
+ const handleActionClick = React86__default.useCallback(() => {
42823
43026
  if (action?.event) {
42824
43027
  eventBus.emit(`UI:${action.event}`, {});
42825
43028
  }
@@ -42830,7 +43033,7 @@ var init_StatCard = __esm({
42830
43033
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
42831
43034
  const isLoading = externalLoading ?? false;
42832
43035
  const error = externalError;
42833
- const computeMetricValue = React85__default.useCallback(
43036
+ const computeMetricValue = React86__default.useCallback(
42834
43037
  (metric, items) => {
42835
43038
  if (metric.value !== void 0) {
42836
43039
  return metric.value;
@@ -42869,7 +43072,7 @@ var init_StatCard = __esm({
42869
43072
  },
42870
43073
  []
42871
43074
  );
42872
- const schemaStats = React85__default.useMemo(() => {
43075
+ const schemaStats = React86__default.useMemo(() => {
42873
43076
  if (!metrics || metrics.length === 0) return null;
42874
43077
  return metrics.map((metric) => ({
42875
43078
  label: metric.label,
@@ -42877,7 +43080,7 @@ var init_StatCard = __esm({
42877
43080
  format: metric.format
42878
43081
  }));
42879
43082
  }, [metrics, data, computeMetricValue]);
42880
- const calculatedTrend = React85__default.useMemo(() => {
43083
+ const calculatedTrend = React86__default.useMemo(() => {
42881
43084
  if (manualTrend !== void 0) return manualTrend;
42882
43085
  if (previousValue === void 0 || currentValue === void 0)
42883
43086
  return void 0;
@@ -43517,8 +43720,8 @@ var init_SubagentTracePanel = __esm({
43517
43720
  ] });
43518
43721
  };
43519
43722
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
43520
- const endRef = React85__default.useRef(null);
43521
- React85__default.useEffect(() => {
43723
+ const endRef = React86__default.useRef(null);
43724
+ React86__default.useEffect(() => {
43522
43725
  if (!autoScroll) return;
43523
43726
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
43524
43727
  }, [activities.length, autoScroll]);
@@ -43612,7 +43815,7 @@ var init_SubagentTracePanel = __esm({
43612
43815
  };
43613
43816
  SubagentRichCard = ({ subagent }) => {
43614
43817
  const { t } = useTranslate();
43615
- const activities = React85__default.useMemo(
43818
+ const activities = React86__default.useMemo(
43616
43819
  () => subagentMessagesToActivities(subagent.messages),
43617
43820
  [subagent.messages]
43618
43821
  );
@@ -43689,8 +43892,8 @@ var init_SubagentTracePanel = __esm({
43689
43892
  ] });
43690
43893
  };
43691
43894
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
43692
- const endRef = React85__default.useRef(null);
43693
- React85__default.useEffect(() => {
43895
+ const endRef = React86__default.useRef(null);
43896
+ React86__default.useEffect(() => {
43694
43897
  if (!autoScroll) return;
43695
43898
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
43696
43899
  }, [messages.length, autoScroll]);
@@ -44125,7 +44328,7 @@ var init_Timeline = __esm({
44125
44328
  }) => {
44126
44329
  const { t } = useTranslate();
44127
44330
  const entityData = entity ?? [];
44128
- const items = React85__default.useMemo(() => {
44331
+ const items = React86__default.useMemo(() => {
44129
44332
  if (propItems) return propItems;
44130
44333
  if (entityData.length === 0) return [];
44131
44334
  return entityData.map((record, idx) => {
@@ -44227,7 +44430,7 @@ var init_Timeline = __esm({
44227
44430
  }
44228
44431
  });
44229
44432
  function extractToastProps(children) {
44230
- if (!React85__default.isValidElement(children)) {
44433
+ if (!React86__default.isValidElement(children)) {
44231
44434
  if (typeof children === "string") {
44232
44435
  return { message: children };
44233
44436
  }
@@ -44269,7 +44472,7 @@ var init_ToastSlot = __esm({
44269
44472
  eventBus.emit(`${prefix}CLOSE`);
44270
44473
  };
44271
44474
  if (!isVisible) return null;
44272
- const isCustomContent = React85__default.isValidElement(children) && !message;
44475
+ const isCustomContent = React86__default.isValidElement(children) && !message;
44273
44476
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
44274
44477
  Toast,
44275
44478
  {
@@ -44842,7 +45045,7 @@ function SuspenseConfigProvider({
44842
45045
  config,
44843
45046
  children
44844
45047
  }) {
44845
- return React85__default.createElement(
45048
+ return React86__default.createElement(
44846
45049
  SuspenseConfigContext.Provider,
44847
45050
  { value: config },
44848
45051
  children
@@ -44884,7 +45087,7 @@ function enrichFormFields(fields, entityDef) {
44884
45087
  }
44885
45088
  return { name: field, label: humanizeFieldName(field) };
44886
45089
  }
44887
- if (field && typeof field === "object" && !Array.isArray(field) && !React85__default.isValidElement(field) && !(field instanceof Date)) {
45090
+ if (field && typeof field === "object" && !Array.isArray(field) && !React86__default.isValidElement(field) && !(field instanceof Date)) {
44888
45091
  const obj = field;
44889
45092
  const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
44890
45093
  if (!fieldName) return field;
@@ -45356,7 +45559,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
45356
45559
  const key = `${parentId}-${index}-trait:${traitName}`;
45357
45560
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
45358
45561
  }
45359
- return /* @__PURE__ */ jsx(React85__default.Fragment, { children: child }, `${parentId}-${index}`);
45562
+ return /* @__PURE__ */ jsx(React86__default.Fragment, { children: child }, `${parentId}-${index}`);
45360
45563
  }
45361
45564
  if (!child || typeof child !== "object") return null;
45362
45565
  const childId = `${parentId}-${index}`;
@@ -45413,14 +45616,14 @@ function isPatternConfig(value) {
45413
45616
  if (value === null || value === void 0) return false;
45414
45617
  if (typeof value !== "object") return false;
45415
45618
  if (Array.isArray(value)) return false;
45416
- if (React85__default.isValidElement(value)) return false;
45619
+ if (React86__default.isValidElement(value)) return false;
45417
45620
  if (value instanceof Date) return false;
45418
45621
  if (typeof value === "function") return false;
45419
45622
  const record = value;
45420
45623
  return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
45421
45624
  }
45422
45625
  function isPlainConfigObject(value) {
45423
- if (React85__default.isValidElement(value)) return false;
45626
+ if (React86__default.isValidElement(value)) return false;
45424
45627
  if (value instanceof Date) return false;
45425
45628
  const proto = Object.getPrototypeOf(value);
45426
45629
  return proto === Object.prototype || proto === null;
@@ -45541,8 +45744,13 @@ function SlotContentRenderer({
45541
45744
  const isSingleChild = typeof childrenConfig === "string" || typeof childrenConfig === "object" && childrenConfig !== null && !Array.isArray(childrenConfig) && "type" in childrenConfig;
45542
45745
  const hasChildren = PATTERNS_WITH_CHILDREN.has(content.pattern) || Array.isArray(childrenConfig) && childrenConfig.length > 0 || isSingleChild;
45543
45746
  const isDrawHost = isDrawHostPattern(content.pattern);
45747
+ const arr = Array.isArray(childrenConfig) ? childrenConfig : childrenConfig ? [childrenConfig] : [];
45748
+ const hasTraitChildren = arr.some(
45749
+ (c) => typeof c === "string" && TRAIT_BINDING_RE.test(c)
45750
+ );
45751
+ const drawHostUsesReactChildren = isDrawHost && hasTraitChildren;
45544
45752
  const myPath = patternPath ?? "root";
45545
- const renderedChildren = hasChildren && !isDrawHost ? renderPatternChildren(childrenConfig, onDismiss, content.id, myPath, content.sourceTrait, {
45753
+ const renderedChildren = hasChildren && (!isDrawHost || drawHostUsesReactChildren) ? renderPatternChildren(childrenConfig, onDismiss, content.id, myPath, content.sourceTrait, {
45546
45754
  slot: content.slot,
45547
45755
  transitionEvent: content.transitionEvent,
45548
45756
  fromState: content.fromState,
@@ -45556,7 +45764,7 @@ function SlotContentRenderer({
45556
45764
  for (const slotKey of CONTENT_NODE_SLOTS) {
45557
45765
  const slotVal = restProps[slotKey];
45558
45766
  if (slotVal === void 0 || slotVal === null) continue;
45559
- if (React85__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
45767
+ if (React86__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
45560
45768
  const typelessChildren = !Array.isArray(slotVal) && typeof slotVal === "object" && !("type" in slotVal) && Array.isArray(slotVal.children) ? slotVal.children : void 0;
45561
45769
  if (typelessChildren !== void 0 || Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
45562
45770
  nodeSlotOverrides[slotKey] = renderPatternChildren(
@@ -45603,14 +45811,14 @@ function SlotContentRenderer({
45603
45811
  for (const [k, v] of Object.entries(nodeSlotOverrides)) {
45604
45812
  finalProps[k] = v;
45605
45813
  }
45606
- if (isDrawHost && Array.isArray(childrenConfig) && childrenConfig.length > 0) {
45814
+ if (isDrawHost && !drawHostUsesReactChildren && Array.isArray(childrenConfig) && childrenConfig.length > 0) {
45607
45815
  finalProps.drawables = toDrawableNodes(childrenConfig);
45608
45816
  }
45609
45817
  const entityVal = finalProps.entity;
45610
45818
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
45611
45819
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
45612
45820
  const sample = resolvedItems[0];
45613
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React85__default.isValidElement(sample) && !(sample instanceof Date)) {
45821
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React86__default.isValidElement(sample) && !(sample instanceof Date)) {
45614
45822
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
45615
45823
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
45616
45824
  }
@@ -45782,6 +45990,8 @@ var init_UISlotRenderer = __esm({
45782
45990
  "vstack",
45783
45991
  "hstack",
45784
45992
  "box",
45993
+ "canvas",
45994
+ "canvas-2d",
45785
45995
  "grid",
45786
45996
  "center",
45787
45997
  "card",