@almadar/ui 5.135.0 → 5.136.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,10 @@
1
- import * as React84 from 'react';
2
- import React84__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useLayoutEffect, lazy, useId, useSyncExternalStore } from 'react';
3
- import { EventBusContext, useTraitScopeChain, useEntitySchemaOptional, TraitScopeProvider, useCurrentPagePath, useGameAudioContextOptional } from '@almadar/ui/providers';
1
+ import * as React85 from 'react';
2
+ import React85__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState, useSyncExternalStore, useLayoutEffect, lazy, useId } from 'react';
3
+ import { EventBusContext, useTraitScopeChain, useEntitySchemaOptional, useEntityBindingSnapshot, useTraitScope, TraitScopeProvider, useCurrentPagePath, useGameAudioContextOptional } from '@almadar/ui/providers';
4
4
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
5
+ import { createContextFromBindings, interpolateValue } from '@almadar/runtime';
6
+ import { ANONYMOUS_USER, isRenderBindingMarker, isInlineTrait } from '@almadar/core';
7
+ export { ANONYMOUS_USER } from '@almadar/core';
5
8
  import { clsx } from 'clsx';
6
9
  import { twMerge } from 'tailwind-merge';
7
10
  import * as LucideIcons2 from 'lucide-react';
@@ -68,11 +71,10 @@ import ReactMarkdown from 'react-markdown';
68
71
  import remarkGfm from 'remark-gfm';
69
72
  import remarkMath from 'remark-math';
70
73
  import rehypeKatex from 'rehype-katex';
71
- import { ANONYMOUS_USER, isInlineTrait } from '@almadar/core';
72
- export { ANONYMOUS_USER } from '@almadar/core';
73
74
  import { DndContext, pointerWithin, rectIntersection, closestCorners, useSensors, useSensor, PointerSensor, KeyboardSensor, useDroppable } from '@dnd-kit/core';
74
75
  import { useSortable, arrayMove, sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
75
76
  import { CSS } from '@dnd-kit/utilities';
77
+ import { ordered, lib } from 'emojilib';
76
78
  import { useNodeId, ReactFlowProvider, Handle, Position } from '@xyflow/react';
77
79
  import { forceSimulation, forceLink, forceManyBody, forceCollide, forceX, forceY } from 'd3-force';
78
80
  import { isDrawHostPattern, getPatternDefinition, getComponentForPattern as getComponentForPattern$1 } from '@almadar/core/patterns';
@@ -267,6 +269,75 @@ var init_useEventBus = __esm({
267
269
  useEventBus_default = useEventBus;
268
270
  }
269
271
  });
272
+ function resolveMarkerExpression(expression, entity, config, state) {
273
+ const ctx = createContextFromBindings({
274
+ entity,
275
+ payload: {},
276
+ state,
277
+ ...config !== void 0 ? { config } : {}
278
+ });
279
+ return interpolateValue(expression, ctx);
280
+ }
281
+ function isPlainObject(value) {
282
+ if (value === null || value === void 0 || typeof value !== "object") return false;
283
+ if (Array.isArray(value)) return false;
284
+ if (React85__default.isValidElement(value)) return false;
285
+ if (value instanceof Date) return false;
286
+ if (typeof value === "function") return false;
287
+ return true;
288
+ }
289
+ function walkValue(value, scopeTrait, entity, config, state) {
290
+ if (isRenderBindingMarker(value)) {
291
+ return { resolved: resolveMarkerExpression(value.expression, entity, config, state), changed: true };
292
+ }
293
+ if (Array.isArray(value)) {
294
+ const out = [];
295
+ let changed = false;
296
+ for (const item of value) {
297
+ const element = item;
298
+ const wasMarker = isRenderBindingMarker(element);
299
+ const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state);
300
+ if (wasMarker && Array.isArray(resolved)) {
301
+ out.push(...resolved);
302
+ changed = true;
303
+ continue;
304
+ }
305
+ out.push(resolved);
306
+ if (itemChanged) changed = true;
307
+ }
308
+ return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
309
+ }
310
+ if (isPlainObject(value)) {
311
+ const sourceTrait = value._sourceTrait;
312
+ if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
313
+ return { resolved: value, changed: false };
314
+ }
315
+ const out = {};
316
+ let changed = false;
317
+ for (const [key, item] of Object.entries(value)) {
318
+ const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state);
319
+ out[key] = resolved;
320
+ if (itemChanged) changed = true;
321
+ }
322
+ return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
323
+ }
324
+ return { resolved: value, changed: false };
325
+ }
326
+ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
327
+ const out = {};
328
+ let changed = false;
329
+ for (const [key, value] of Object.entries(props)) {
330
+ const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state);
331
+ out[key] = resolved;
332
+ if (propChanged) changed = true;
333
+ }
334
+ return changed ? out : props;
335
+ }
336
+ var init_resolve_render_bindings = __esm({
337
+ "lib/resolve-render-bindings.ts"() {
338
+ "use client";
339
+ }
340
+ });
270
341
  function cn(...inputs) {
271
342
  return twMerge(clsx(inputs));
272
343
  }
@@ -430,7 +501,7 @@ var init_Box = __esm({
430
501
  fixed: "fixed",
431
502
  sticky: "sticky"
432
503
  };
433
- Box = React84__default.forwardRef(
504
+ Box = React85__default.forwardRef(
434
505
  ({
435
506
  padding,
436
507
  paddingX,
@@ -495,7 +566,7 @@ var init_Box = __esm({
495
566
  onPointerDown?.(e);
496
567
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
497
568
  const isClickable = action || onClick;
498
- return React84__default.createElement(
569
+ return React85__default.createElement(
499
570
  Component,
500
571
  {
501
572
  ref,
@@ -712,7 +783,7 @@ var init_Icon = __esm({
712
783
  const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
713
784
  const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
714
785
  const family = useIconFamily();
715
- const RenderedComponent = React84__default.useMemo(() => {
786
+ const RenderedComponent = React85__default.useMemo(() => {
716
787
  if (directIcon) return null;
717
788
  return effectiveName ? resolveIconForFamily(effectiveName) : null;
718
789
  }, [directIcon, effectiveName, family]);
@@ -774,9 +845,13 @@ function getAtlas(url, onReady) {
774
845
  onReady();
775
846
  }).catch(() => {
776
847
  atlasCache.set(url, null);
848
+ onReady();
777
849
  });
778
850
  return void 0;
779
851
  }
852
+ function atlasFailed(url) {
853
+ return atlasCache.get(url) === null;
854
+ }
780
855
  function subRectFor(atlas, sprite) {
781
856
  if (isTilesheet(atlas)) {
782
857
  let col;
@@ -832,7 +907,7 @@ var init_atlasSlice = __esm({
832
907
  }
833
908
  });
834
909
  function useAtlasSliceDataUrl(asset) {
835
- const [, bump] = React84.useReducer((x) => x + 1, 0);
910
+ const [, bump] = React85.useReducer((x) => x + 1, 0);
836
911
  if (!isAtlasAsset(asset)) return void 0;
837
912
  const key = `${asset.atlas}#${asset.sprite}`;
838
913
  const cached = sliceDataUrlCache.get(key);
@@ -895,13 +970,13 @@ function AtlasImage({
895
970
  style,
896
971
  "aria-hidden": ariaHidden
897
972
  }) {
898
- const [, bump] = React84.useReducer((x) => x + 1, 0);
899
- const canvasRef = React84.useRef(null);
973
+ const [, bump] = React85.useReducer((x) => x + 1, 0);
974
+ const canvasRef = React85.useRef(null);
900
975
  const sliced = isAtlasAsset(asset);
901
976
  const atlas = sliced ? getAtlas(asset.atlas, bump) : void 0;
902
977
  const img = sliced && asset?.url ? getSheetImage(asset.url, bump) : null;
903
978
  const rect = sliced && atlas ? subRectFor(atlas, asset.sprite) : null;
904
- React84.useEffect(() => {
979
+ React85.useEffect(() => {
905
980
  const canvas = canvasRef.current;
906
981
  if (!canvas || !img || !rect) return;
907
982
  canvas.width = rect.sw;
@@ -977,7 +1052,7 @@ function resolveIconProp(value, sizeClass) {
977
1052
  const IconComp = value;
978
1053
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
979
1054
  }
980
- if (React84__default.isValidElement(value)) {
1055
+ if (React85__default.isValidElement(value)) {
981
1056
  return value;
982
1057
  }
983
1058
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -1054,7 +1129,7 @@ var init_Button = __esm({
1054
1129
  md: "h-icon-default w-icon-default",
1055
1130
  lg: "h-icon-default w-icon-default"
1056
1131
  };
1057
- Button = React84__default.forwardRef(
1132
+ Button = React85__default.forwardRef(
1058
1133
  ({
1059
1134
  className,
1060
1135
  variant = "primary",
@@ -1124,7 +1199,7 @@ var Dialog;
1124
1199
  var init_Dialog = __esm({
1125
1200
  "components/core/atoms/Dialog.tsx"() {
1126
1201
  init_cn();
1127
- Dialog = React84__default.forwardRef(
1202
+ Dialog = React85__default.forwardRef(
1128
1203
  ({
1129
1204
  role = "dialog",
1130
1205
  "aria-modal": ariaModal = true,
@@ -1335,7 +1410,7 @@ var init_Typography = __esm({
1335
1410
  if (format !== void 0 && format !== "none" && (typeof body === "string" || typeof body === "number" || body instanceof Date)) {
1336
1411
  body = formatValue(body, format);
1337
1412
  }
1338
- return React84__default.createElement(
1413
+ return React85__default.createElement(
1339
1414
  Component,
1340
1415
  {
1341
1416
  id,
@@ -1898,7 +1973,7 @@ var init_Badge = __esm({
1898
1973
  md: "px-2.5 py-1 text-sm",
1899
1974
  lg: "px-3 py-1.5 text-base"
1900
1975
  };
1901
- Badge = React84__default.forwardRef(
1976
+ Badge = React85__default.forwardRef(
1902
1977
  ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
1903
1978
  const iconSizes3 = {
1904
1979
  sm: "h-icon-default w-icon-default",
@@ -2248,7 +2323,7 @@ var init_SvgFlow = __esm({
2248
2323
  width = 100,
2249
2324
  height = 100
2250
2325
  }) => {
2251
- const markerId = React84__default.useMemo(() => {
2326
+ const markerId = React85__default.useMemo(() => {
2252
2327
  flowIdCounter += 1;
2253
2328
  return `almadar-flow-arrow-${flowIdCounter}`;
2254
2329
  }, []);
@@ -2841,7 +2916,7 @@ var init_SvgRing = __esm({
2841
2916
  width = 100,
2842
2917
  height = 100
2843
2918
  }) => {
2844
- const gradientId = React84__default.useMemo(() => {
2919
+ const gradientId = React85__default.useMemo(() => {
2845
2920
  ringIdCounter += 1;
2846
2921
  return `almadar-ring-glow-${ringIdCounter}`;
2847
2922
  }, []);
@@ -3022,7 +3097,7 @@ var init_Input = __esm({
3022
3097
  init_cn();
3023
3098
  init_Icon();
3024
3099
  init_useEventBus();
3025
- Input = React84__default.forwardRef(
3100
+ Input = React85__default.forwardRef(
3026
3101
  ({
3027
3102
  className,
3028
3103
  inputType,
@@ -3045,6 +3120,20 @@ var init_Input = __esm({
3045
3120
  const { t } = useTranslate();
3046
3121
  const eventBus = useEventBus();
3047
3122
  const type = inputType || htmlType || "text";
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(() => {
3127
+ if (!isDeclarative) return;
3128
+ const incoming = value == null ? "" : String(value);
3129
+ if (pendingEchoRef.current.has(incoming)) {
3130
+ pendingEchoRef.current.delete(incoming);
3131
+ return;
3132
+ }
3133
+ pendingEchoRef.current.clear();
3134
+ setLocalValue(value);
3135
+ }, [value, isDeclarative]);
3136
+ const displayValue = isDeclarative ? localValue : value;
3048
3137
  const resolveIconNode = (i, cls) => {
3049
3138
  if (!i) return null;
3050
3139
  if (typeof i === "string") return /* @__PURE__ */ jsx(Icon, { name: i, className: cls });
@@ -3054,7 +3143,7 @@ var init_Input = __esm({
3054
3143
  const iconCls = "h-icon-default w-icon-default";
3055
3144
  const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
3056
3145
  const resolvedLeftIcon = (leftIcon ? resolveIconNode(leftIcon, iconCls) : null) || IconComponent && /* @__PURE__ */ jsx(IconComponent, { className: iconCls });
3057
- const showClearButton = clearable && value && String(value).length > 0;
3146
+ const showClearButton = clearable && displayValue && String(displayValue).length > 0;
3058
3147
  const isMultiline = type === "textarea";
3059
3148
  const baseClassName = cn(
3060
3149
  "block w-full rounded-sm transition-all duration-fast",
@@ -3073,6 +3162,10 @@ var init_Input = __esm({
3073
3162
  if (typeof onChange === "string") {
3074
3163
  const target = e.target;
3075
3164
  const payload = type === "checkbox" ? { checked: target.checked } : { value: target.value };
3165
+ if (type !== "checkbox") {
3166
+ pendingEchoRef.current.add(target.value);
3167
+ setLocalValue(target.value);
3168
+ }
3076
3169
  eventBus.emit(`UI:${onChange}`, payload);
3077
3170
  } else {
3078
3171
  onChange?.(e);
@@ -3103,7 +3196,7 @@ var init_Input = __esm({
3103
3196
  "select",
3104
3197
  {
3105
3198
  ref,
3106
- value,
3199
+ value: displayValue,
3107
3200
  onChange: handleChange,
3108
3201
  className: cn(baseClassName, "appearance-none pr-10", className),
3109
3202
  ...props,
@@ -3123,7 +3216,7 @@ var init_Input = __esm({
3123
3216
  "textarea",
3124
3217
  {
3125
3218
  ref,
3126
- value,
3219
+ value: displayValue,
3127
3220
  onChange: handleChange,
3128
3221
  rows,
3129
3222
  className: baseClassName,
@@ -3162,7 +3255,7 @@ var init_Input = __esm({
3162
3255
  {
3163
3256
  ref,
3164
3257
  type,
3165
- value,
3258
+ value: displayValue,
3166
3259
  onChange: handleChange,
3167
3260
  onKeyDown: handleKeyDown,
3168
3261
  className: baseClassName,
@@ -3190,7 +3283,7 @@ var Label;
3190
3283
  var init_Label = __esm({
3191
3284
  "components/core/atoms/Label.tsx"() {
3192
3285
  init_cn();
3193
- Label = React84__default.forwardRef(
3286
+ Label = React85__default.forwardRef(
3194
3287
  ({ className, required, children, ...props }, ref) => {
3195
3288
  return /* @__PURE__ */ jsxs(
3196
3289
  "label",
@@ -3217,7 +3310,7 @@ var init_Textarea = __esm({
3217
3310
  "components/core/atoms/Textarea.tsx"() {
3218
3311
  init_cn();
3219
3312
  init_useEventBus();
3220
- Textarea = React84__default.forwardRef(
3313
+ Textarea = React85__default.forwardRef(
3221
3314
  ({ className, error, onChange, ...props }, ref) => {
3222
3315
  const eventBus = useEventBus();
3223
3316
  const handleChange = (e) => {
@@ -3456,7 +3549,7 @@ var init_Select = __esm({
3456
3549
  init_cn();
3457
3550
  init_Icon();
3458
3551
  init_useEventBus();
3459
- Select = React84__default.forwardRef(
3552
+ Select = React85__default.forwardRef(
3460
3553
  (props, _ref) => {
3461
3554
  const { multiple, searchable, clearable } = props;
3462
3555
  if (multiple || searchable || clearable) {
@@ -3473,7 +3566,7 @@ var init_Checkbox = __esm({
3473
3566
  "components/core/atoms/Checkbox.tsx"() {
3474
3567
  init_cn();
3475
3568
  init_useEventBus();
3476
- Checkbox = React84__default.forwardRef(
3569
+ Checkbox = React85__default.forwardRef(
3477
3570
  ({ className, label, id, onChange, ...props }, ref) => {
3478
3571
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
3479
3572
  const eventBus = useEventBus();
@@ -3527,7 +3620,7 @@ var init_Spinner = __esm({
3527
3620
  md: "h-6 w-6",
3528
3621
  lg: "h-8 w-8"
3529
3622
  };
3530
- Spinner = React84__default.forwardRef(
3623
+ Spinner = React85__default.forwardRef(
3531
3624
  ({ className, size = "md", overlay, ...props }, ref) => {
3532
3625
  if (overlay) {
3533
3626
  return /* @__PURE__ */ jsx(
@@ -3617,7 +3710,7 @@ var init_Card = __esm({
3617
3710
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
3618
3711
  "tile-image-first": "p-0 overflow-hidden"
3619
3712
  };
3620
- Card = React84__default.forwardRef(
3713
+ Card = React85__default.forwardRef(
3621
3714
  ({
3622
3715
  className,
3623
3716
  variant = "bordered",
@@ -3666,9 +3759,9 @@ var init_Card = __esm({
3666
3759
  }
3667
3760
  );
3668
3761
  Card.displayName = "Card";
3669
- CardHeader = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3762
+ CardHeader = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
3670
3763
  CardHeader.displayName = "CardHeader";
3671
- CardTitle = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3764
+ CardTitle = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3672
3765
  "h3",
3673
3766
  {
3674
3767
  ref,
@@ -3681,11 +3774,11 @@ var init_Card = __esm({
3681
3774
  }
3682
3775
  ));
3683
3776
  CardTitle.displayName = "CardTitle";
3684
- CardContent = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3777
+ CardContent = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
3685
3778
  CardContent.displayName = "CardContent";
3686
3779
  CardBody = CardContent;
3687
3780
  CardBody.displayName = "CardBody";
3688
- CardFooter = React84__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3781
+ CardFooter = React85__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
3689
3782
  "div",
3690
3783
  {
3691
3784
  ref,
@@ -3772,7 +3865,7 @@ var init_FilterPill = __esm({
3772
3865
  md: "w-3.5 h-3.5",
3773
3866
  lg: "w-4 h-4"
3774
3867
  };
3775
- FilterPill = React84__default.forwardRef(
3868
+ FilterPill = React85__default.forwardRef(
3776
3869
  ({
3777
3870
  className,
3778
3871
  variant = "default",
@@ -3901,8 +3994,8 @@ var init_Avatar = __esm({
3901
3994
  actionPayload
3902
3995
  }) => {
3903
3996
  const eventBus = useEventBus();
3904
- const [imgFailed, setImgFailed] = React84__default.useState(false);
3905
- React84__default.useEffect(() => {
3997
+ const [imgFailed, setImgFailed] = React85__default.useState(false);
3998
+ React85__default.useEffect(() => {
3906
3999
  setImgFailed(false);
3907
4000
  }, [src]);
3908
4001
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -4015,7 +4108,7 @@ var init_Center = __esm({
4015
4108
  as: Component = "div"
4016
4109
  }) => {
4017
4110
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
4018
- return React84__default.createElement(Component, {
4111
+ return React85__default.createElement(Component, {
4019
4112
  className: cn(
4020
4113
  inline ? "inline-flex" : "flex",
4021
4114
  horizontal && "justify-center",
@@ -4283,7 +4376,7 @@ var init_Radio = __esm({
4283
4376
  md: "w-2.5 h-2.5",
4284
4377
  lg: "w-3 h-3"
4285
4378
  };
4286
- Radio = React84__default.forwardRef(
4379
+ Radio = React85__default.forwardRef(
4287
4380
  ({
4288
4381
  label,
4289
4382
  helperText,
@@ -4300,12 +4393,12 @@ var init_Radio = __esm({
4300
4393
  onChange,
4301
4394
  ...props
4302
4395
  }, ref) => {
4303
- const reactId = React84__default.useId();
4396
+ const reactId = React85__default.useId();
4304
4397
  const baseId = id || `radio-${reactId}`;
4305
4398
  const hasError = !!error;
4306
4399
  const eventBus = useEventBus();
4307
- const [selected, setSelected] = React84__default.useState(value);
4308
- React84__default.useEffect(() => {
4400
+ const [selected, setSelected] = React85__default.useState(value);
4401
+ React85__default.useEffect(() => {
4309
4402
  if (value !== void 0) setSelected(value);
4310
4403
  }, [value]);
4311
4404
  const pick = (next, e) => {
@@ -4487,7 +4580,7 @@ var init_Switch = __esm({
4487
4580
  "components/core/atoms/Switch.tsx"() {
4488
4581
  "use client";
4489
4582
  init_cn();
4490
- Switch = React84.forwardRef(
4583
+ Switch = React85.forwardRef(
4491
4584
  ({
4492
4585
  checked,
4493
4586
  defaultChecked = false,
@@ -4498,10 +4591,10 @@ var init_Switch = __esm({
4498
4591
  name,
4499
4592
  className
4500
4593
  }, ref) => {
4501
- const [isChecked, setIsChecked] = React84.useState(
4594
+ const [isChecked, setIsChecked] = React85.useState(
4502
4595
  checked !== void 0 ? checked : defaultChecked
4503
4596
  );
4504
- React84.useEffect(() => {
4597
+ React85.useEffect(() => {
4505
4598
  if (checked !== void 0) {
4506
4599
  setIsChecked(checked);
4507
4600
  }
@@ -4664,7 +4757,7 @@ var init_Stack = __esm({
4664
4757
  };
4665
4758
  const isHorizontal = direction === "horizontal";
4666
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";
4667
- return React84__default.createElement(
4760
+ return React85__default.createElement(
4668
4761
  Component,
4669
4762
  {
4670
4763
  className: cn(
@@ -4864,7 +4957,7 @@ var Aside;
4864
4957
  var init_Aside = __esm({
4865
4958
  "components/core/atoms/Aside.tsx"() {
4866
4959
  init_cn();
4867
- Aside = React84__default.forwardRef(
4960
+ Aside = React85__default.forwardRef(
4868
4961
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
4869
4962
  );
4870
4963
  Aside.displayName = "Aside";
@@ -4943,9 +5036,9 @@ var init_LawReferenceTooltip = __esm({
4943
5036
  className
4944
5037
  }) => {
4945
5038
  const { t } = useTranslate();
4946
- const [isVisible, setIsVisible] = React84__default.useState(false);
4947
- const timeoutRef = React84__default.useRef(null);
4948
- const triggerRef = React84__default.useRef(null);
5039
+ const [isVisible, setIsVisible] = React85__default.useState(false);
5040
+ const timeoutRef = React85__default.useRef(null);
5041
+ const triggerRef = React85__default.useRef(null);
4949
5042
  const handleMouseEnter = () => {
4950
5043
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4951
5044
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -4956,7 +5049,7 @@ var init_LawReferenceTooltip = __esm({
4956
5049
  };
4957
5050
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
4958
5051
  const open = isVisible || revealed;
4959
- React84__default.useEffect(() => {
5052
+ React85__default.useEffect(() => {
4960
5053
  return () => {
4961
5054
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
4962
5055
  };
@@ -5166,7 +5259,7 @@ var init_StatusDot = __esm({
5166
5259
  md: "w-2.5 h-2.5",
5167
5260
  lg: "w-3 h-3"
5168
5261
  };
5169
- StatusDot = React84__default.forwardRef(
5262
+ StatusDot = React85__default.forwardRef(
5170
5263
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
5171
5264
  return /* @__PURE__ */ jsx(
5172
5265
  "span",
@@ -5220,7 +5313,7 @@ var init_TrendIndicator = __esm({
5220
5313
  down: "trending-down",
5221
5314
  flat: "arrow-right"
5222
5315
  };
5223
- TrendIndicator = React84__default.forwardRef(
5316
+ TrendIndicator = React85__default.forwardRef(
5224
5317
  ({
5225
5318
  className,
5226
5319
  value,
@@ -5289,7 +5382,7 @@ var init_RangeSlider = __esm({
5289
5382
  md: "w-4 h-4",
5290
5383
  lg: "w-5 h-5"
5291
5384
  };
5292
- RangeSlider = React84__default.forwardRef(
5385
+ RangeSlider = React85__default.forwardRef(
5293
5386
  ({
5294
5387
  className,
5295
5388
  min = 0,
@@ -5900,7 +5993,7 @@ var init_ContentSection = __esm({
5900
5993
  md: "py-16",
5901
5994
  lg: "py-24"
5902
5995
  };
5903
- ContentSection = React84__default.forwardRef(
5996
+ ContentSection = React85__default.forwardRef(
5904
5997
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
5905
5998
  return /* @__PURE__ */ jsx(
5906
5999
  Box,
@@ -6434,7 +6527,7 @@ var init_AnimatedReveal = __esm({
6434
6527
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
6435
6528
  "none": {}
6436
6529
  };
6437
- AnimatedReveal = React84__default.forwardRef(
6530
+ AnimatedReveal = React85__default.forwardRef(
6438
6531
  ({
6439
6532
  trigger = "scroll",
6440
6533
  animation = "fade-up",
@@ -6594,7 +6687,7 @@ var init_AnimatedGraphic = __esm({
6594
6687
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
6595
6688
  "use client";
6596
6689
  init_cn();
6597
- AnimatedGraphic = React84__default.forwardRef(
6690
+ AnimatedGraphic = React85__default.forwardRef(
6598
6691
  ({
6599
6692
  src,
6600
6693
  svgContent,
@@ -6617,7 +6710,7 @@ var init_AnimatedGraphic = __esm({
6617
6710
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
6618
6711
  const resolvedSvg = svgContent ?? fetchedSvg;
6619
6712
  const prevAnimateRef = useRef(animate);
6620
- const setRef = React84__default.useCallback(
6713
+ const setRef = React85__default.useCallback(
6621
6714
  (node) => {
6622
6715
  containerRef.current = node;
6623
6716
  if (typeof ref === "function") ref(node);
@@ -7085,46 +7178,45 @@ var init_useImageCache = __esm({
7085
7178
  });
7086
7179
 
7087
7180
  // lib/isometric.ts
7088
- function isoToScreen(tileX, tileY, scale, baseOffsetX, layout = "isometric") {
7089
- const scaledTileWidth = TILE_WIDTH * scale;
7090
- const scaledFloorHeight = FLOOR_HEIGHT * scale;
7181
+ function isoToScreen(tileX, tileY, cellWidth, baseOffsetX, layout = "isometric") {
7182
+ const w = cellWidth;
7183
+ const fh = cellWidth / 2;
7091
7184
  if (layout === "hex") {
7092
- const screenX2 = tileX * scaledTileWidth + (tileY & 1) * (scaledTileWidth / 2) + baseOffsetX;
7093
- const screenY2 = tileY * (scaledFloorHeight * 0.75);
7185
+ const screenX2 = tileX * w + (tileY & 1) * (w / 2) + baseOffsetX;
7186
+ const screenY2 = tileY * (fh * 0.75);
7094
7187
  return { x: screenX2, y: screenY2 };
7095
7188
  }
7096
7189
  if (layout === "flat") {
7097
- const screenX2 = tileX * scaledTileWidth + baseOffsetX;
7098
- const screenY2 = tileY * scaledTileWidth;
7190
+ const screenX2 = tileX * w + baseOffsetX;
7191
+ const screenY2 = tileY * w;
7099
7192
  return { x: screenX2, y: screenY2 };
7100
7193
  }
7101
- const screenX = (tileX - tileY) * (scaledTileWidth / 2) + baseOffsetX;
7102
- const screenY = (tileX + tileY) * (scaledFloorHeight / 2);
7194
+ const screenX = (tileX - tileY) * (w / 2) + baseOffsetX;
7195
+ const screenY = (tileX + tileY) * (fh / 2);
7103
7196
  return { x: screenX, y: screenY };
7104
7197
  }
7105
- function screenToIso(screenX, screenY, scale, baseOffsetX, layout = "isometric") {
7106
- const scaledTileWidth = TILE_WIDTH * scale;
7107
- const scaledFloorHeight = FLOOR_HEIGHT * scale;
7198
+ function screenToIso(screenX, screenY, cellWidth, baseOffsetX, layout = "isometric") {
7199
+ const w = cellWidth;
7200
+ const fh = cellWidth / 2;
7108
7201
  if (layout === "hex") {
7109
- const row = Math.round(screenY / (scaledFloorHeight * 0.75));
7110
- const col = Math.round((screenX - (row & 1) * (scaledTileWidth / 2) - baseOffsetX) / scaledTileWidth);
7202
+ const row = Math.round(screenY / (fh * 0.75));
7203
+ const col = Math.round((screenX - (row & 1) * (w / 2) - baseOffsetX) / w);
7111
7204
  return { x: col, y: row };
7112
7205
  }
7113
7206
  if (layout === "flat") {
7114
- const col = Math.round((screenX - baseOffsetX) / scaledTileWidth);
7115
- const row = Math.round(screenY / scaledTileWidth);
7207
+ const col = Math.round((screenX - baseOffsetX) / w);
7208
+ const row = Math.round(screenY / w);
7116
7209
  return { x: col, y: row };
7117
7210
  }
7118
7211
  const adjustedX = screenX - baseOffsetX;
7119
- const tileX = (adjustedX / (scaledTileWidth / 2) + screenY / (scaledFloorHeight / 2)) / 2;
7120
- const tileY = (screenY / (scaledFloorHeight / 2) - adjustedX / (scaledTileWidth / 2)) / 2;
7212
+ const tileX = (adjustedX / (w / 2) + screenY / (fh / 2)) / 2;
7213
+ const tileY = (screenY / (fh / 2) - adjustedX / (w / 2)) / 2;
7121
7214
  return { x: Math.round(tileX), y: Math.round(tileY) };
7122
7215
  }
7123
- var TILE_WIDTH, FLOOR_HEIGHT, DIAMOND_TOP_Y, BACKGROUND_FALLBACK_COLOR, MINIMAP_TERRAIN_COLORS;
7216
+ var TILE_WIDTH, DIAMOND_TOP_Y, BACKGROUND_FALLBACK_COLOR, MINIMAP_TERRAIN_COLORS;
7124
7217
  var init_isometric = __esm({
7125
7218
  "lib/isometric.ts"() {
7126
7219
  TILE_WIDTH = 256;
7127
- FLOOR_HEIGHT = 128;
7128
7220
  DIAMOND_TOP_Y = 374;
7129
7221
  BACKGROUND_FALLBACK_COLOR = "#1a1a2e";
7130
7222
  MINIMAP_TERRAIN_COLORS = {
@@ -7346,9 +7438,9 @@ function ControlButton({
7346
7438
  className
7347
7439
  }) {
7348
7440
  const eventBus = useEventBus();
7349
- const [isPressed, setIsPressed] = React84.useState(false);
7441
+ const [isPressed, setIsPressed] = React85.useState(false);
7350
7442
  const actualPressed = pressed ?? isPressed;
7351
- const handlePointerDown = React84.useCallback(
7443
+ const handlePointerDown = React85.useCallback(
7352
7444
  (e) => {
7353
7445
  e.preventDefault();
7354
7446
  if (disabled) return;
@@ -7358,7 +7450,7 @@ function ControlButton({
7358
7450
  },
7359
7451
  [disabled, pressEvent, eventBus, onPress]
7360
7452
  );
7361
- const handlePointerUp = React84.useCallback(
7453
+ const handlePointerUp = React85.useCallback(
7362
7454
  (e) => {
7363
7455
  e.preventDefault();
7364
7456
  if (disabled) return;
@@ -7368,7 +7460,7 @@ function ControlButton({
7368
7460
  },
7369
7461
  [disabled, releaseEvent, eventBus, onRelease]
7370
7462
  );
7371
- const handlePointerLeave = React84.useCallback(
7463
+ const handlePointerLeave = React85.useCallback(
7372
7464
  (e) => {
7373
7465
  if (isPressed) {
7374
7466
  setIsPressed(false);
@@ -7626,8 +7718,8 @@ function ControlGrid({
7626
7718
  className
7627
7719
  }) {
7628
7720
  const eventBus = useEventBus();
7629
- const [active, setActive] = React84.useState(/* @__PURE__ */ new Set());
7630
- const handlePress = React84.useCallback(
7721
+ const [active, setActive] = React85.useState(/* @__PURE__ */ new Set());
7722
+ const handlePress = React85.useCallback(
7631
7723
  (id) => {
7632
7724
  setActive((prev) => new Set(prev).add(id));
7633
7725
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -7641,7 +7733,7 @@ function ControlGrid({
7641
7733
  },
7642
7734
  [kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
7643
7735
  );
7644
- const handleRelease = React84.useCallback(
7736
+ const handleRelease = React85.useCallback(
7645
7737
  (id) => {
7646
7738
  setActive((prev) => {
7647
7739
  const next = new Set(prev);
@@ -7999,7 +8091,7 @@ function GameMenu({
7999
8091
  }) {
8000
8092
  const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
8001
8093
  const eventBus = useEventBus();
8002
- const handleOptionClick = React84.useCallback(
8094
+ const handleOptionClick = React85.useCallback(
8003
8095
  (option) => {
8004
8096
  if (option.event) {
8005
8097
  eventBus.emit(`UI:${option.event}`, { option });
@@ -8235,7 +8327,7 @@ function StateGraph({
8235
8327
  }) {
8236
8328
  const eventBus = useEventBus();
8237
8329
  const nodes = states ?? [];
8238
- const positions = React84.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
8330
+ const positions = React85.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
8239
8331
  return /* @__PURE__ */ jsxs(
8240
8332
  Box,
8241
8333
  {
@@ -8306,12 +8398,13 @@ function MiniMap({
8306
8398
  tileAssets,
8307
8399
  unitAssets
8308
8400
  }) {
8309
- const canvasRef = React84.useRef(null);
8310
- const imgCacheRef = React84.useRef(/* @__PURE__ */ new Map());
8401
+ const canvasRef = React85.useRef(null);
8402
+ const imgCacheRef = React85.useRef(/* @__PURE__ */ new Map());
8311
8403
  function loadImg(url) {
8312
8404
  const cached = imgCacheRef.current.get(url);
8313
8405
  if (cached) return cached.complete ? cached : null;
8314
8406
  const img = new Image();
8407
+ img.crossOrigin = "anonymous";
8315
8408
  img.src = url;
8316
8409
  img.onload = () => {
8317
8410
  const canvas = canvasRef.current;
@@ -8322,7 +8415,7 @@ function MiniMap({
8322
8415
  imgCacheRef.current.set(url, img);
8323
8416
  return null;
8324
8417
  }
8325
- React84.useEffect(() => {
8418
+ React85.useEffect(() => {
8326
8419
  const canvas = canvasRef.current;
8327
8420
  if (!canvas) return;
8328
8421
  const ctx = canvas.getContext("2d");
@@ -8479,7 +8572,7 @@ function useCamera(initial) {
8479
8572
  const handleWheel = useCallback((e, drawFn) => {
8480
8573
  e.preventDefault();
8481
8574
  const zoomDelta = e.deltaY > 0 ? 0.9 : 1.1;
8482
- cameraRef.current.zoom = Math.max(0.5, Math.min(3, cameraRef.current.zoom * zoomDelta));
8575
+ cameraRef.current.zoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, cameraRef.current.zoom * zoomDelta));
8483
8576
  drawFn?.();
8484
8577
  }, []);
8485
8578
  const handlePointerDown = useCallback((e) => {
@@ -8500,7 +8593,7 @@ function useCamera(initial) {
8500
8593
  const zoomAtPoint = useCallback((factor, centerX, centerY, viewportSize, drawFn) => {
8501
8594
  const cam = cameraRef.current;
8502
8595
  const oldZoom = cam.zoom;
8503
- const newZoom = Math.max(0.5, Math.min(3, oldZoom * factor));
8596
+ const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, oldZoom * factor));
8504
8597
  if (newZoom === oldZoom) {
8505
8598
  drawFn?.();
8506
8599
  return;
@@ -8552,9 +8645,12 @@ function useCamera(initial) {
8552
8645
  lerpToTarget
8553
8646
  };
8554
8647
  }
8648
+ var MIN_ZOOM, MAX_ZOOM;
8555
8649
  var init_useCamera = __esm({
8556
8650
  "hooks/useCamera.ts"() {
8557
8651
  "use client";
8652
+ MIN_ZOOM = 0.05;
8653
+ MAX_ZOOM = 10;
8558
8654
  }
8559
8655
  });
8560
8656
  function localPoint(canvas, clientX, clientY) {
@@ -8675,6 +8771,7 @@ function getOrLoadImage(url, onReady) {
8675
8771
  return null;
8676
8772
  }
8677
8773
  const img = new Image();
8774
+ img.crossOrigin = "anonymous";
8678
8775
  const entry = { img, status: "pending", onReady };
8679
8776
  cache.set(url, entry);
8680
8777
  updateAssetStatus(url, "pending");
@@ -8686,10 +8783,14 @@ function getOrLoadImage(url, onReady) {
8686
8783
  img.onerror = () => {
8687
8784
  entry.status = "failed";
8688
8785
  updateAssetStatus(url, "failed");
8786
+ entry.onReady?.();
8689
8787
  };
8690
8788
  img.src = url;
8691
8789
  return null;
8692
8790
  }
8791
+ function getImageStatus(url) {
8792
+ return cache.get(url)?.status;
8793
+ }
8693
8794
  var cache;
8694
8795
  var init_imageCache = __esm({
8695
8796
  "lib/imageCache.ts"() {
@@ -8828,12 +8929,13 @@ var init_webPainter2d = __esm({
8828
8929
 
8829
8930
  // lib/drawable/projector.ts
8830
8931
  function create2DProjector(opts) {
8831
- const { scale, baseOffsetX, layout } = opts;
8832
- const tileWidth = layout === "free" ? 1 : TILE_WIDTH * scale;
8833
- const floorHeight = layout === "free" ? 1 : FLOOR_HEIGHT * scale;
8834
- const diamondTopY = layout === "free" ? 0 : (opts.diamondTopY ?? DIAMOND_TOP_Y) * scale;
8932
+ const { baseOffsetX, layout } = opts;
8933
+ const tw = opts.tileWidth ?? TILE_WIDTH;
8934
+ const tileWidth = layout === "free" ? 1 : tw;
8935
+ const floorHeight = layout === "free" ? 1 : tw / 2;
8936
+ const diamondTopY = layout === "free" ? 0 : opts.diamondTopY ?? tw * (DIAMOND_TOP_Y / TILE_WIDTH);
8835
8937
  const squareGrid = layout === "flat" || layout === "free";
8836
- const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y, scale, baseOffsetX, layout);
8938
+ const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y, tw, baseOffsetX, layout);
8837
8939
  const anchorPoint = (pos, anchor) => {
8838
8940
  const base = project(pos);
8839
8941
  if (anchor === "top-left") return base;
@@ -8864,7 +8966,7 @@ function create2DProjector(opts) {
8864
8966
  { x: base.x, y: topY + floorHeight / 2 }
8865
8967
  ];
8866
8968
  };
8867
- return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY, scale, squareGrid };
8969
+ return { project, anchorPoint, cellPath, tileWidth, floorHeight, diamondTopY, squareGrid, worldPixelDirect: layout === "free" };
8868
8970
  }
8869
8971
  var init_projector = __esm({
8870
8972
  "lib/drawable/projector.ts"() {
@@ -8880,32 +8982,67 @@ var init_contract = __esm({
8880
8982
  "lib/drawable/contract.ts"() {
8881
8983
  }
8882
8984
  });
8883
-
8884
- // components/game/atoms/DrawSprite.tsx
8985
+ function warnMissingOnce(reason, node) {
8986
+ const key = `${reason}:${node.asset.url}:${String(node.asset.atlas)}:${String(node.asset.sprite)}`;
8987
+ if (loggedMissing.has(key)) return;
8988
+ loggedMissing.add(key);
8989
+ spriteLog.warn("draw-sprite asset unresolvable \u2014 painting fallback square", { reason, url: node.asset.url, atlas: node.asset.atlas, sprite: node.asset.sprite });
8990
+ }
8991
+ function paintFallbackSquare(painter, node, dctx, reason) {
8992
+ warnMissingOnce(reason, node);
8993
+ const tw = dctx.projector.tileWidth;
8994
+ const natural = dctx.projector.worldPixelDirect ? FALLBACK_WORLD_PX : tw;
8995
+ const w = node.width !== void 0 ? node.width * tw : natural;
8996
+ const h = node.height !== void 0 ? node.height * tw : natural;
8997
+ const anchor = node.anchor ?? "top-left";
8998
+ const p = dctx.projector.anchorPoint(node.position, anchor);
8999
+ const dx = anchor === "top-left" ? p.x : p.x - w / 2;
9000
+ const dy = anchor === "ground" ? p.y - h : anchor === "center" ? p.y - h / 2 : p.y;
9001
+ painter.save();
9002
+ if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
9003
+ painter.fillRect(dx, dy, w, h, "#9b8f7f");
9004
+ painter.strokeRect(dx, dy, w, h, "#5e564b", Math.max(1, tw / 32));
9005
+ painter.restore();
9006
+ }
8885
9007
  function DrawSprite(_props) {
8886
9008
  return null;
8887
9009
  }
8888
- var paintSprite;
9010
+ var spriteLog, loggedMissing, FALLBACK_WORLD_PX, paintSprite;
8889
9011
  var init_DrawSprite = __esm({
8890
9012
  "components/game/atoms/DrawSprite.tsx"() {
8891
9013
  "use client";
8892
9014
  init_atlasSlice();
9015
+ init_imageCache();
8893
9016
  init_contract();
9017
+ spriteLog = createLogger("almadar:ui:draw-sprite");
9018
+ loggedMissing = /* @__PURE__ */ new Set();
9019
+ FALLBACK_WORLD_PX = 32;
8894
9020
  paintSprite = (painter, node, dctx) => {
8895
9021
  if (!node.asset?.url || !isValidScenePos(node.position)) return;
8896
9022
  const tex = painter.resolveTexture(node.asset.url);
8897
- if (!tex) return;
9023
+ if (!tex) {
9024
+ if (getImageStatus(node.asset.url) === "failed") paintFallbackSquare(painter, node, dctx, "texture-failed");
9025
+ return;
9026
+ }
8898
9027
  let src = typeof node.frame === "object" ? node.frame : void 0;
8899
9028
  if (!src && isAtlasAsset(node.asset)) {
8900
9029
  const atlas = getAtlas(node.asset.atlas, dctx.invalidate);
8901
- if (!atlas) return;
9030
+ if (!atlas) {
9031
+ if (atlasFailed(node.asset.atlas)) paintFallbackSquare(painter, node, dctx, "atlas-failed");
9032
+ return;
9033
+ }
8902
9034
  const r = subRectFor(atlas, node.asset.sprite);
8903
- if (!r) return;
9035
+ if (!r) {
9036
+ paintFallbackSquare(painter, node, dctx, "sprite-missing");
9037
+ return;
9038
+ }
8904
9039
  src = { x: r.sx, y: r.sy, w: r.sw, h: r.sh };
8905
9040
  }
8906
9041
  const tw = dctx.projector.tileWidth;
8907
- const w = node.width !== void 0 ? node.width * tw : src ? src.w : tex.width;
8908
- const h = node.height !== void 0 ? node.height * tw : src ? src.h : tex.height;
9042
+ const fallbackW = dctx.projector.worldPixelDirect ? src ? src.w : tex.width : tw;
9043
+ const fallbackH = dctx.projector.worldPixelDirect ? src ? src.h : tex.height : tw;
9044
+ const w = node.width !== void 0 ? node.width * tw : fallbackW;
9045
+ const h = node.height !== void 0 ? node.height * tw : fallbackH;
8909
9046
  const anchor = node.anchor ?? "top-left";
8910
9047
  const p = dctx.projector.anchorPoint(node.position, anchor);
8911
9048
  const dx = anchor === "top-left" ? p.x : p.x - w / 2;
@@ -9171,6 +9308,8 @@ function Canvas2D({
9171
9308
  keyUpMap,
9172
9309
  camera = "pan-zoom",
9173
9310
  scale = 0.4,
9311
+ tileWidth,
9312
+ fit = false,
9174
9313
  showMinimap = true,
9175
9314
  followTarget,
9176
9315
  cameraPos,
@@ -9213,9 +9352,32 @@ function Canvas2D({
9213
9352
  observer2.observe(el);
9214
9353
  return () => observer2.disconnect();
9215
9354
  }, []);
9216
- const scaledTileWidth = TILE_WIDTH * scale;
9217
- const scaledFloorHeight = FLOOR_HEIGHT * scale;
9218
- const scaledDiamondTopY = DIAMOND_TOP_Y * scale;
9355
+ const [atlasVersion, setAtlasVersion] = useState(0);
9356
+ const bumpAtlas = useCallback(() => setAtlasVersion((v) => v + 1), []);
9357
+ const detectedTileWidth = useMemo(() => {
9358
+ for (const n of drawables ?? []) {
9359
+ const refs = [];
9360
+ if (n.type === "draw-sprite") refs.push(n.asset);
9361
+ else if (n.type === "draw-sprite-layer") for (const it of n.items) refs.push(it.asset);
9362
+ for (const a of refs) {
9363
+ if (a && isAtlasAsset(a) && a.atlas) {
9364
+ const atlas = getAtlas(a.atlas, bumpAtlas);
9365
+ if (atlas) {
9366
+ if ("tileWidth" in atlas) return atlas.tileWidth;
9367
+ if ("subTextures" in atlas) {
9368
+ const first = Object.values(atlas.subTextures)[0];
9369
+ if (first && typeof first.width === "number") return first.width;
9370
+ }
9371
+ }
9372
+ }
9373
+ }
9374
+ }
9375
+ return void 0;
9376
+ }, [drawables, atlasVersion]);
9377
+ const nativeTileW = tileWidth ?? detectedTileWidth ?? TILE_WIDTH;
9378
+ const scaledTileWidth = nativeTileW;
9379
+ const scaledFloorHeight = nativeTileW / 2;
9380
+ const scaledDiamondTopY = nativeTileW * (DIAMOND_TOP_Y / TILE_WIDTH);
9219
9381
  const drawnItems = useMemo(() => collectDrawnItems(drawables ?? []), [drawables]);
9220
9382
  const scenePositions = useMemo(() => drawnItems.map((i) => i.pos), [drawnItems]);
9221
9383
  const hitIndex = useMemo(() => buildHitIndex(drawnItems), [drawnItems]);
@@ -9233,14 +9395,36 @@ function Canvas2D({
9233
9395
  if (isFree || projection === "flat" || projection === "side") return 0;
9234
9396
  return (gridExtent.height - 1) * (scaledTileWidth / 2);
9235
9397
  }, [isFree, projection, gridExtent.height, scaledTileWidth]);
9398
+ const effectiveZoom = useMemo(() => {
9399
+ if (isFree || projection === "side") return scale;
9400
+ if (!fit) {
9401
+ const z2 = TILE_WIDTH * scale * scale / nativeTileW;
9402
+ return Number.isFinite(z2) && z2 > 0 ? z2 : scale;
9403
+ }
9404
+ if (!viewportSize.width || gridExtent.width < 2 || gridExtent.height < 2) return scale;
9405
+ let boardW;
9406
+ let boardH;
9407
+ if (projection === "flat") {
9408
+ boardW = gridExtent.width * nativeTileW;
9409
+ boardH = gridExtent.height * nativeTileW;
9410
+ } else if (projection === "hex") {
9411
+ boardW = (gridExtent.width + 0.5) * nativeTileW;
9412
+ boardH = gridExtent.height * (nativeTileW / 2) * 0.75 + nativeTileW / 2;
9413
+ } else {
9414
+ boardW = (gridExtent.width + gridExtent.height) * (nativeTileW / 2);
9415
+ boardH = (gridExtent.width + gridExtent.height) * (nativeTileW / 4);
9416
+ }
9417
+ const z = Math.min(viewportSize.width * 0.85 / boardW, viewportSize.height * 0.85 / boardH);
9418
+ return Number.isFinite(z) && z > 0 ? z : scale;
9419
+ }, [isFree, projection, fit, viewportSize, gridExtent, nativeTileW, scale]);
9236
9420
  const projector = useMemo(
9237
- () => create2DProjector({ scale, baseOffsetX, layout }),
9238
- [scale, baseOffsetX, layout]
9421
+ () => create2DProjector({ tileWidth: nativeTileW, baseOffsetX, layout }),
9422
+ [nativeTileW, baseOffsetX, layout]
9239
9423
  );
9240
9424
  const unproject = useCallback((screenX, screenY) => {
9241
9425
  if (projection === "free" || projection === "side") return { x: Math.round(screenX), y: Math.round(screenY) };
9242
- return screenToIso(screenX, screenY, scale, baseOffsetX, projection);
9243
- }, [projection, scale, baseOffsetX]);
9426
+ return screenToIso(screenX, screenY, nativeTileW, baseOffsetX, projection);
9427
+ }, [projection, nativeTileW, baseOffsetX]);
9244
9428
  const bgUrls = useMemo(() => backgroundImage ? [backgroundImage.url] : [], [backgroundImage]);
9245
9429
  const { getImage, pendingCount: _imagePendingCount } = useImageCache(bgUrls);
9246
9430
  useEffect(() => {
@@ -9267,9 +9451,7 @@ function Canvas2D({
9267
9451
  zoomAtPoint,
9268
9452
  screenToWorld,
9269
9453
  lerpToTarget
9270
- } = useCamera({ zoom: scale });
9271
- const [atlasVersion, setAtlasVersion] = useState(0);
9272
- const bumpAtlas = useCallback(() => setAtlasVersion((v) => v + 1), []);
9454
+ } = useCamera({ zoom: effectiveZoom });
9273
9455
  const miniMapTiles = useMemo(() => {
9274
9456
  if (!showMinimap) return [];
9275
9457
  const color = MINIMAP_TERRAIN_COLORS.default;
@@ -9344,6 +9526,13 @@ function Canvas2D({
9344
9526
  useEffect(() => {
9345
9527
  draw();
9346
9528
  }, [_imagePendingCount, draw]);
9529
+ const userZoomedRef = useRef(false);
9530
+ useEffect(() => {
9531
+ if (userZoomedRef.current) return;
9532
+ if (cameraRef.current.zoom === effectiveZoom) return;
9533
+ cameraRef.current.zoom = effectiveZoom;
9534
+ draw();
9535
+ }, [effectiveZoom, cameraRef, draw]);
9347
9536
  useEffect(() => {
9348
9537
  draw();
9349
9538
  }, [atlasVersion, draw]);
@@ -9400,7 +9589,9 @@ function Canvas2D({
9400
9589
  if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
9401
9590
  }, [handleMouseLeave, tileLeaveEvent, eventBus]);
9402
9591
  const applyZoom = useCallback((factor, centerX, centerY) => {
9403
- if (enableCamera) zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw());
9592
+ if (!enableCamera) return;
9593
+ userZoomedRef.current = true;
9594
+ zoomAtPoint(factor, centerX, centerY, viewportSize, () => draw());
9404
9595
  }, [enableCamera, zoomAtPoint, viewportSize, draw]);
9405
9596
  const applyPanDelta = useCallback((dx, dy) => {
9406
9597
  if (enableCamera) panBy(dx, dy, () => draw());
@@ -9585,6 +9776,8 @@ function Canvas({
9585
9776
  isLoading,
9586
9777
  unitScale,
9587
9778
  showMinimap,
9779
+ fit,
9780
+ tileWidth,
9588
9781
  backgroundImage,
9589
9782
  backgroundColor,
9590
9783
  worldWidth,
@@ -9642,6 +9835,8 @@ function Canvas({
9642
9835
  projection,
9643
9836
  camera: to2DCamera(camera?.mode),
9644
9837
  ...zoom !== void 0 ? { scale: zoom } : {},
9838
+ ...fit !== void 0 ? { fit } : {},
9839
+ ...tileWidth !== void 0 ? { tileWidth } : {},
9645
9840
  ...camera?.target !== void 0 ? { followTarget: camera.target } : {},
9646
9841
  ...camera?.pos !== void 0 ? { cameraPos: camera.pos } : {},
9647
9842
  showMinimap,
@@ -10051,7 +10246,7 @@ function LinearView({
10051
10246
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
10052
10247
  const isDone = i < currentIdx;
10053
10248
  const isCurrent = i === currentIdx;
10054
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
10249
+ return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
10055
10250
  i > 0 && /* @__PURE__ */ jsx(
10056
10251
  Typography,
10057
10252
  {
@@ -10586,7 +10781,7 @@ function SequenceBar({
10586
10781
  else onSlotRemove?.(index);
10587
10782
  }, [emit, slotRemoveEvent, onSlotRemove, playing]);
10588
10783
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
10589
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
10784
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
10590
10785
  i > 0 && /* @__PURE__ */ jsx(
10591
10786
  Typography,
10592
10787
  {
@@ -11235,7 +11430,7 @@ var init_ErrorBoundary = __esm({
11235
11430
  }
11236
11431
  );
11237
11432
  };
11238
- ErrorBoundary = class extends React84__default.Component {
11433
+ ErrorBoundary = class extends React85__default.Component {
11239
11434
  constructor(props) {
11240
11435
  super(props);
11241
11436
  __publicField(this, "reset", () => {
@@ -11887,7 +12082,7 @@ var init_Container = __esm({
11887
12082
  as: Component = "div"
11888
12083
  }) => {
11889
12084
  const resolvedSize = maxWidth ?? size ?? "lg";
11890
- return React84__default.createElement(
12085
+ return React85__default.createElement(
11891
12086
  Component,
11892
12087
  {
11893
12088
  className: cn(
@@ -14852,7 +15047,7 @@ var init_CodeBlock = __esm({
14852
15047
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
14853
15048
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
14854
15049
  HIDDEN_LINE_NUMBERS = { display: "none" };
14855
- CodeBlock = React84__default.memo(
15050
+ CodeBlock = React85__default.memo(
14856
15051
  ({
14857
15052
  code: rawCode,
14858
15053
  language = "text",
@@ -15440,7 +15635,7 @@ var init_MarkdownContent = __esm({
15440
15635
  init_Box();
15441
15636
  init_CodeBlock();
15442
15637
  init_cn();
15443
- MarkdownContent = React84__default.memo(
15638
+ MarkdownContent = React85__default.memo(
15444
15639
  ({ content, direction = "ltr", className }) => {
15445
15640
  const { t: _t } = useTranslate();
15446
15641
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -16767,7 +16962,7 @@ var init_StateMachineView = __esm({
16767
16962
  style: { top: title ? 30 : 0 },
16768
16963
  children: [
16769
16964
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
16770
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React84__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
16965
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React85__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
16771
16966
  StateNode2,
16772
16967
  {
16773
16968
  state,
@@ -22589,8 +22784,8 @@ var init_Menu = __esm({
22589
22784
  "bottom-end": "bottom-start"
22590
22785
  };
22591
22786
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
22592
- const triggerChild = React84__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
22593
- const triggerElement = React84__default.cloneElement(
22787
+ const triggerChild = React85__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
22788
+ const triggerElement = React85__default.cloneElement(
22594
22789
  triggerChild,
22595
22790
  {
22596
22791
  ref: triggerRef,
@@ -22685,14 +22880,14 @@ function useDataDnd(args) {
22685
22880
  const isZone = Boolean(dragGroup || accepts || sortable);
22686
22881
  const enabled = isZone || Boolean(dndRoot);
22687
22882
  const eventBus = useEventBus();
22688
- const parentRoot = React84__default.useContext(RootCtx);
22883
+ const parentRoot = React85__default.useContext(RootCtx);
22689
22884
  const isRoot = enabled && parentRoot === null;
22690
- const zoneId = React84__default.useId();
22885
+ const zoneId = React85__default.useId();
22691
22886
  const ownGroup = dragGroup ?? accepts ?? zoneId;
22692
- const [optimisticOrders, setOptimisticOrders] = React84__default.useState(() => /* @__PURE__ */ new Map());
22693
- const optimisticOrdersRef = React84__default.useRef(optimisticOrders);
22887
+ const [optimisticOrders, setOptimisticOrders] = React85__default.useState(() => /* @__PURE__ */ new Map());
22888
+ const optimisticOrdersRef = React85__default.useRef(optimisticOrders);
22694
22889
  optimisticOrdersRef.current = optimisticOrders;
22695
- const clearOptimisticOrder = React84__default.useCallback((group) => {
22890
+ const clearOptimisticOrder = React85__default.useCallback((group) => {
22696
22891
  setOptimisticOrders((prev) => {
22697
22892
  if (!prev.has(group)) return prev;
22698
22893
  const next = new Map(prev);
@@ -22717,7 +22912,7 @@ function useDataDnd(args) {
22717
22912
  const raw = it[dndItemIdField];
22718
22913
  return raw != null ? String(raw) : `__idx_${idx}`;
22719
22914
  }).join("|");
22720
- const itemIds = React84__default.useMemo(
22915
+ const itemIds = React85__default.useMemo(
22721
22916
  () => orderedItems.map((it, idx) => {
22722
22917
  const raw = it[dndItemIdField];
22723
22918
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -22728,7 +22923,7 @@ function useDataDnd(args) {
22728
22923
  const raw = it[dndItemIdField];
22729
22924
  return raw != null ? String(raw) : `__${idx}`;
22730
22925
  }).join("|");
22731
- React84__default.useEffect(() => {
22926
+ React85__default.useEffect(() => {
22732
22927
  const root = isRoot ? null : parentRoot;
22733
22928
  if (root) {
22734
22929
  root.clearOptimisticOrder(ownGroup);
@@ -22736,20 +22931,20 @@ function useDataDnd(args) {
22736
22931
  clearOptimisticOrder(ownGroup);
22737
22932
  }
22738
22933
  }, [itemsContentSig, ownGroup]);
22739
- const zonesRef = React84__default.useRef(/* @__PURE__ */ new Map());
22740
- const registerZone = React84__default.useCallback((zoneId2, meta2) => {
22934
+ const zonesRef = React85__default.useRef(/* @__PURE__ */ new Map());
22935
+ const registerZone = React85__default.useCallback((zoneId2, meta2) => {
22741
22936
  zonesRef.current.set(zoneId2, meta2);
22742
22937
  }, []);
22743
- const unregisterZone = React84__default.useCallback((zoneId2) => {
22938
+ const unregisterZone = React85__default.useCallback((zoneId2) => {
22744
22939
  zonesRef.current.delete(zoneId2);
22745
22940
  }, []);
22746
- const [activeDrag, setActiveDrag] = React84__default.useState(null);
22747
- const [overZoneGroup, setOverZoneGroup] = React84__default.useState(null);
22748
- const meta = React84__default.useMemo(
22941
+ const [activeDrag, setActiveDrag] = React85__default.useState(null);
22942
+ const [overZoneGroup, setOverZoneGroup] = React85__default.useState(null);
22943
+ const meta = React85__default.useMemo(
22749
22944
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
22750
22945
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
22751
22946
  );
22752
- React84__default.useEffect(() => {
22947
+ React85__default.useEffect(() => {
22753
22948
  const target = isRoot ? null : parentRoot;
22754
22949
  if (!target) {
22755
22950
  zonesRef.current.set(zoneId, meta);
@@ -22768,7 +22963,7 @@ function useDataDnd(args) {
22768
22963
  }, [parentRoot, isRoot, zoneId, meta]);
22769
22964
  const sensors = useAlmadarDndSensors(true);
22770
22965
  const collisionDetection = almadarDndCollisionDetection;
22771
- const findZoneByItem = React84__default.useCallback(
22966
+ const findZoneByItem = React85__default.useCallback(
22772
22967
  (id) => {
22773
22968
  for (const z of zonesRef.current.values()) {
22774
22969
  if (z.itemIds.includes(id)) return z;
@@ -22777,7 +22972,7 @@ function useDataDnd(args) {
22777
22972
  },
22778
22973
  []
22779
22974
  );
22780
- React84__default.useCallback(
22975
+ React85__default.useCallback(
22781
22976
  (group) => {
22782
22977
  for (const z of zonesRef.current.values()) {
22783
22978
  if (z.group === group) return z;
@@ -22786,7 +22981,7 @@ function useDataDnd(args) {
22786
22981
  },
22787
22982
  []
22788
22983
  );
22789
- const handleDragEnd = React84__default.useCallback(
22984
+ const handleDragEnd = React85__default.useCallback(
22790
22985
  (event) => {
22791
22986
  const { active, over } = event;
22792
22987
  const activeIdStr = String(active.id);
@@ -22877,8 +23072,8 @@ function useDataDnd(args) {
22877
23072
  },
22878
23073
  [eventBus]
22879
23074
  );
22880
- const sortableData = React84__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
22881
- const SortableItem = React84__default.useCallback(
23075
+ const sortableData = React85__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
23076
+ const SortableItem = React85__default.useCallback(
22882
23077
  ({ id, children }) => {
22883
23078
  const {
22884
23079
  attributes,
@@ -22918,7 +23113,7 @@ function useDataDnd(args) {
22918
23113
  id: droppableId,
22919
23114
  data: sortableData
22920
23115
  });
22921
- const ctx = React84__default.useContext(RootCtx);
23116
+ const ctx = React85__default.useContext(RootCtx);
22922
23117
  const activeDrag2 = ctx?.activeDrag ?? null;
22923
23118
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
22924
23119
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -22933,7 +23128,7 @@ function useDataDnd(args) {
22933
23128
  showForeignPlaceholder,
22934
23129
  ctxAvailable: ctx != null
22935
23130
  });
22936
- React84__default.useEffect(() => {
23131
+ React85__default.useEffect(() => {
22937
23132
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
22938
23133
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
22939
23134
  return /* @__PURE__ */ jsx(
@@ -22947,11 +23142,11 @@ function useDataDnd(args) {
22947
23142
  }
22948
23143
  );
22949
23144
  };
22950
- const rootContextValue = React84__default.useMemo(
23145
+ const rootContextValue = React85__default.useMemo(
22951
23146
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
22952
23147
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
22953
23148
  );
22954
- const handleDragStart = React84__default.useCallback((event) => {
23149
+ const handleDragStart = React85__default.useCallback((event) => {
22955
23150
  const sourceZone = findZoneByItem(event.active.id);
22956
23151
  const rect = event.active.rect.current.initial;
22957
23152
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -22970,7 +23165,7 @@ function useDataDnd(args) {
22970
23165
  isRoot
22971
23166
  });
22972
23167
  }, [findZoneByItem, isRoot, zoneId]);
22973
- const handleDragOver = React84__default.useCallback((event) => {
23168
+ const handleDragOver = React85__default.useCallback((event) => {
22974
23169
  const { active, over } = event;
22975
23170
  const overData = over?.data?.current;
22976
23171
  const overGroup = overData?.dndGroup ?? null;
@@ -23040,7 +23235,7 @@ function useDataDnd(args) {
23040
23235
  return next;
23041
23236
  });
23042
23237
  }, []);
23043
- const handleDragCancel = React84__default.useCallback((event) => {
23238
+ const handleDragCancel = React85__default.useCallback((event) => {
23044
23239
  setActiveDrag(null);
23045
23240
  setOverZoneGroup(null);
23046
23241
  dndLog.warn("dragCancel", {
@@ -23048,12 +23243,12 @@ function useDataDnd(args) {
23048
23243
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
23049
23244
  });
23050
23245
  }, []);
23051
- const handleDragEndWithCleanup = React84__default.useCallback((event) => {
23246
+ const handleDragEndWithCleanup = React85__default.useCallback((event) => {
23052
23247
  handleDragEnd(event);
23053
23248
  setActiveDrag(null);
23054
23249
  setOverZoneGroup(null);
23055
23250
  }, [handleDragEnd]);
23056
- const wrapContainer = React84__default.useCallback(
23251
+ const wrapContainer = React85__default.useCallback(
23057
23252
  (children) => {
23058
23253
  if (!enabled) return children;
23059
23254
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -23107,7 +23302,7 @@ var init_useDataDnd = __esm({
23107
23302
  init_useAlmadarDndCollision();
23108
23303
  init_Box();
23109
23304
  dndLog = createLogger("almadar:ui:dnd");
23110
- RootCtx = React84__default.createContext(null);
23305
+ RootCtx = React85__default.createContext(null);
23111
23306
  }
23112
23307
  });
23113
23308
  function renderIconInput(icon, props) {
@@ -23649,7 +23844,7 @@ function DataList({
23649
23844
  }) {
23650
23845
  const eventBus = useEventBus();
23651
23846
  const { t } = useTranslate();
23652
- const [visibleCount, setVisibleCount] = React84__default.useState(pageSize || Infinity);
23847
+ const [visibleCount, setVisibleCount] = React85__default.useState(pageSize || Infinity);
23653
23848
  const fieldDefs = fields ?? columns ?? [];
23654
23849
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
23655
23850
  const dnd = useDataDnd({
@@ -23665,14 +23860,14 @@ function DataList({
23665
23860
  dndRoot
23666
23861
  });
23667
23862
  const orderedData = dnd.orderedItems;
23668
- const allData = React84__default.useMemo(
23863
+ const allData = React85__default.useMemo(
23669
23864
  () => sortRows(orderedData, sortBy, sortDirection),
23670
23865
  [orderedData, sortBy, sortDirection]
23671
23866
  );
23672
23867
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
23673
23868
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
23674
23869
  const hasRenderProp = typeof children === "function";
23675
- React84__default.useEffect(() => {
23870
+ React85__default.useEffect(() => {
23676
23871
  const renderItemTypeOf = typeof schemaRenderItem;
23677
23872
  const childrenTypeOf = typeof children;
23678
23873
  if (data.length > 0 && !hasRenderProp) {
@@ -23787,7 +23982,7 @@ function DataList({
23787
23982
  return v === void 0 || v === null || v === "" ? raw : String(v);
23788
23983
  };
23789
23984
  return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn("py-2", className), children: [
23790
- groups2.map((group, gi) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
23985
+ groups2.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
23791
23986
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
23792
23987
  group.items.map((itemData, index) => {
23793
23988
  const id = itemData.id || `${gi}-${index}`;
@@ -23823,7 +24018,11 @@ function DataList({
23823
24018
  metaFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "mt-1 flex-wrap", children: metaFields.map((f3) => {
23824
24019
  const v = getNestedValue(itemData, f3.name);
23825
24020
  if (v === void 0 || v === null || v === "") return null;
23826
- return f3.variant === "badge" ? /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(v)), children: String(v) }, f3.name) : /* @__PURE__ */ jsx(
24021
+ return f3.variant === "badge" ? (
24022
+ // `format` applies here too — a boolean field badged
24023
+ // without it renders the raw "false" instead of "No".
24024
+ /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format) }, f3.name)
24025
+ ) : /* @__PURE__ */ jsx(
23827
24026
  Typography,
23828
24027
  {
23829
24028
  variant: "caption",
@@ -23935,7 +24134,7 @@ function DataList({
23935
24134
  if (val === void 0 || val === null) return null;
23936
24135
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
23937
24136
  field.icon && renderIconInput2(field.icon, { size: "xs" }),
23938
- /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children: String(val) })
24137
+ /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format) })
23939
24138
  ] }, field.name);
23940
24139
  })
23941
24140
  ] }),
@@ -23982,7 +24181,7 @@ function DataList({
23982
24181
  className
23983
24182
  ),
23984
24183
  children: [
23985
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
24184
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
23986
24185
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
23987
24186
  group.items.map(
23988
24187
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -24069,7 +24268,7 @@ var init_FormSection = __esm({
24069
24268
  columns = 1,
24070
24269
  className
24071
24270
  }) => {
24072
- const [collapsed, setCollapsed] = React84__default.useState(defaultCollapsed);
24271
+ const [collapsed, setCollapsed] = React85__default.useState(defaultCollapsed);
24073
24272
  const { t } = useTranslate();
24074
24273
  const eventBus = useEventBus();
24075
24274
  const gridClass = {
@@ -24077,7 +24276,7 @@ var init_FormSection = __esm({
24077
24276
  2: "grid-cols-1 md:grid-cols-2",
24078
24277
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
24079
24278
  }[columns];
24080
- React84__default.useCallback(() => {
24279
+ React85__default.useCallback(() => {
24081
24280
  if (collapsible) {
24082
24281
  setCollapsed((prev) => !prev);
24083
24282
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -24174,6 +24373,182 @@ var init_FormSection = __esm({
24174
24373
  FormActions.displayName = "FormActions";
24175
24374
  }
24176
24375
  });
24376
+ var ALL_CATEGORY, MAX_RENDERED, GridPicker;
24377
+ var init_GridPicker = __esm({
24378
+ "components/core/molecules/GridPicker.tsx"() {
24379
+ "use client";
24380
+ init_cn();
24381
+ init_Input();
24382
+ init_Badge();
24383
+ init_Stack();
24384
+ ALL_CATEGORY = "__all__";
24385
+ MAX_RENDERED = 300;
24386
+ GridPicker = ({
24387
+ items,
24388
+ value,
24389
+ onChange,
24390
+ categories,
24391
+ searchPlaceholder,
24392
+ renderThumbnail,
24393
+ cellSize = 32,
24394
+ className
24395
+ }) => {
24396
+ const [search, setSearch] = useState("");
24397
+ const [activeCategory, setActiveCategory] = useState(ALL_CATEGORY);
24398
+ const gridRef = useRef(null);
24399
+ const categoryChips = useMemo(() => {
24400
+ if (categories !== void 0) return categories;
24401
+ const seen = [];
24402
+ for (const item of items) {
24403
+ if (!seen.includes(item.category)) seen.push(item.category);
24404
+ }
24405
+ return seen;
24406
+ }, [categories, items]);
24407
+ const filtered = useMemo(() => {
24408
+ const needle = search.trim().toLowerCase();
24409
+ return items.filter((item) => {
24410
+ const matchesCategory = activeCategory === ALL_CATEGORY || item.category === activeCategory;
24411
+ const matchesSearch = needle === "" || item.label.toLowerCase().includes(needle) || item.keywords !== void 0 && item.keywords.some((k) => k.toLowerCase().includes(needle));
24412
+ return matchesCategory && matchesSearch;
24413
+ });
24414
+ }, [items, search, activeCategory]);
24415
+ const visible = useMemo(() => filtered.slice(0, MAX_RENDERED), [filtered]);
24416
+ const truncated = filtered.length - visible.length;
24417
+ const select = useCallback(
24418
+ (item) => {
24419
+ onChange(item.id);
24420
+ },
24421
+ [onChange]
24422
+ );
24423
+ const handleKeyDown = useCallback(
24424
+ (e, index) => {
24425
+ const cells = gridRef.current?.querySelectorAll(
24426
+ "[data-gridpicker-cell]"
24427
+ );
24428
+ if (cells === void 0 || cells.length === 0) return;
24429
+ const columns = (() => {
24430
+ const grid = gridRef.current;
24431
+ if (grid === null) return 1;
24432
+ const style = window.getComputedStyle(grid);
24433
+ const cols = style.gridTemplateColumns.split(" ").filter(Boolean).length;
24434
+ return cols > 0 ? cols : 1;
24435
+ })();
24436
+ let next = -1;
24437
+ if (e.key === "ArrowRight") next = index + 1;
24438
+ else if (e.key === "ArrowLeft") next = index - 1;
24439
+ else if (e.key === "ArrowDown") next = index + columns;
24440
+ else if (e.key === "ArrowUp") next = index - columns;
24441
+ else if (e.key === "Enter" || e.key === " ") {
24442
+ e.preventDefault();
24443
+ select(filtered[index]);
24444
+ return;
24445
+ } else {
24446
+ return;
24447
+ }
24448
+ e.preventDefault();
24449
+ if (next >= 0 && next < cells.length) {
24450
+ cells[next].focus();
24451
+ }
24452
+ },
24453
+ [filtered, select]
24454
+ );
24455
+ return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn("w-full", className), children: [
24456
+ /* @__PURE__ */ jsx(
24457
+ Input,
24458
+ {
24459
+ type: "search",
24460
+ icon: "search",
24461
+ value: search,
24462
+ placeholder: searchPlaceholder,
24463
+ clearable: true,
24464
+ onClear: () => setSearch(""),
24465
+ onChange: (e) => setSearch(e.target.value)
24466
+ }
24467
+ ),
24468
+ categoryChips.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", wrap: true, children: [
24469
+ /* @__PURE__ */ jsx(
24470
+ Badge,
24471
+ {
24472
+ variant: activeCategory === ALL_CATEGORY ? "primary" : "neutral",
24473
+ size: "sm",
24474
+ role: "button",
24475
+ tabIndex: 0,
24476
+ "aria-pressed": activeCategory === ALL_CATEGORY,
24477
+ className: "cursor-pointer",
24478
+ onClick: () => setActiveCategory(ALL_CATEGORY),
24479
+ onKeyDown: (e) => {
24480
+ if (e.key === "Enter" || e.key === " ") {
24481
+ e.preventDefault();
24482
+ setActiveCategory(ALL_CATEGORY);
24483
+ }
24484
+ },
24485
+ children: "All"
24486
+ }
24487
+ ),
24488
+ categoryChips.map((category) => /* @__PURE__ */ jsx(
24489
+ Badge,
24490
+ {
24491
+ variant: activeCategory === category ? "primary" : "neutral",
24492
+ size: "sm",
24493
+ role: "button",
24494
+ tabIndex: 0,
24495
+ "aria-pressed": activeCategory === category,
24496
+ className: "cursor-pointer",
24497
+ onClick: () => setActiveCategory(category),
24498
+ onKeyDown: (e) => {
24499
+ if (e.key === "Enter" || e.key === " ") {
24500
+ e.preventDefault();
24501
+ setActiveCategory(category);
24502
+ }
24503
+ },
24504
+ children: category
24505
+ },
24506
+ category
24507
+ ))
24508
+ ] }),
24509
+ /* @__PURE__ */ jsx(
24510
+ "div",
24511
+ {
24512
+ ref: gridRef,
24513
+ role: "listbox",
24514
+ className: "grid gap-1 overflow-y-auto max-h-64 p-1",
24515
+ style: {
24516
+ gridTemplateColumns: `repeat(auto-fill, minmax(${cellSize}px, 1fr))`
24517
+ },
24518
+ children: visible.map((item, index) => {
24519
+ const selected = item.id === value;
24520
+ return /* @__PURE__ */ jsx(
24521
+ "button",
24522
+ {
24523
+ type: "button",
24524
+ role: "option",
24525
+ "aria-selected": selected,
24526
+ "aria-label": item.label,
24527
+ title: item.label,
24528
+ "data-gridpicker-cell": true,
24529
+ tabIndex: selected || value === void 0 && index === 0 ? 0 : -1,
24530
+ onClick: () => select(item),
24531
+ onKeyDown: (e) => handleKeyDown(e, index),
24532
+ className: cn(
24533
+ "flex items-center justify-center rounded-sm",
24534
+ "transition-colors hover:bg-muted",
24535
+ "focus:outline-none focus:ring-1 focus:ring-ring",
24536
+ selected && "bg-primary/10 ring-1 ring-primary"
24537
+ ),
24538
+ style: { width: cellSize, height: cellSize },
24539
+ children: renderThumbnail(item)
24540
+ },
24541
+ item.id
24542
+ );
24543
+ })
24544
+ }
24545
+ ),
24546
+ truncated > 0 && /* @__PURE__ */ jsx("div", { className: "px-1 text-xs text-muted-foreground", children: `+${truncated} more \u2014 refine your search` })
24547
+ ] });
24548
+ };
24549
+ GridPicker.displayName = "GridPicker";
24550
+ }
24551
+ });
24177
24552
  function fileIcon(name) {
24178
24553
  const ext = name.split(".").pop()?.toLowerCase() ?? "";
24179
24554
  switch (ext) {
@@ -24946,7 +25321,7 @@ var init_Flex = __esm({
24946
25321
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
24947
25322
  }
24948
25323
  }
24949
- return React84__default.createElement(Component, {
25324
+ return React85__default.createElement(Component, {
24950
25325
  className: cn(
24951
25326
  inline ? "inline-flex" : "flex",
24952
25327
  directionStyles[direction],
@@ -25065,7 +25440,7 @@ var init_Grid = __esm({
25065
25440
  as: Component = "div"
25066
25441
  }) => {
25067
25442
  const mergedStyle = rows ? { gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`, ...style } : style;
25068
- return React84__default.createElement(
25443
+ return React85__default.createElement(
25069
25444
  Component,
25070
25445
  {
25071
25446
  className: cn(
@@ -25202,9 +25577,16 @@ var init_Popover = __esm({
25202
25577
  position = "bottom",
25203
25578
  trigger = "click",
25204
25579
  showArrow = true,
25580
+ open,
25581
+ onOpenChange,
25205
25582
  className
25206
25583
  }) => {
25207
- const [isOpen, setIsOpen] = useState(false);
25584
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
25585
+ const isOpen = open !== void 0 ? open : uncontrolledOpen;
25586
+ const setIsOpen = (next) => {
25587
+ if (open === void 0) setUncontrolledOpen(next);
25588
+ onOpenChange?.(next);
25589
+ };
25208
25590
  const [triggerRect, setTriggerRect] = useState(null);
25209
25591
  const [popoverWidth, setPopoverWidth] = useState(0);
25210
25592
  const triggerRef = useRef(null);
@@ -25237,6 +25619,23 @@ var init_Popover = __esm({
25237
25619
  updatePosition();
25238
25620
  }
25239
25621
  }, [isOpen]);
25622
+ useEffect(() => {
25623
+ if (!isOpen) return;
25624
+ let raf = 0;
25625
+ let lastTop = Number.NaN;
25626
+ let lastLeft = Number.NaN;
25627
+ const track = () => {
25628
+ const rect = triggerRef.current?.getBoundingClientRect();
25629
+ if (rect && (rect.top !== lastTop || rect.left !== lastLeft)) {
25630
+ lastTop = rect.top;
25631
+ lastLeft = rect.left;
25632
+ updatePosition();
25633
+ }
25634
+ raf = requestAnimationFrame(track);
25635
+ };
25636
+ raf = requestAnimationFrame(track);
25637
+ return () => cancelAnimationFrame(raf);
25638
+ }, [isOpen]);
25240
25639
  useEffect(() => {
25241
25640
  if (!mounted) setPopoverWidth(0);
25242
25641
  }, [mounted]);
@@ -25273,9 +25672,9 @@ var init_Popover = __esm({
25273
25672
  onMouseLeave: handleClose,
25274
25673
  onPointerDown: tapTriggerProps.onPointerDown
25275
25674
  };
25276
- const childElement = React84__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
25675
+ const childElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
25277
25676
  const childPointerDown = childElement.props.onPointerDown;
25278
- const triggerElement = React84__default.cloneElement(
25677
+ const triggerElement = React85__default.cloneElement(
25279
25678
  childElement,
25280
25679
  {
25281
25680
  ref: triggerRef,
@@ -25884,9 +26283,9 @@ var init_Tooltip = __esm({
25884
26283
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
25885
26284
  };
25886
26285
  }, []);
25887
- const triggerElement = React84__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
26286
+ const triggerElement = React85__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
25888
26287
  const childPointerDown = triggerElement.props.onPointerDown;
25889
- const trigger = React84__default.cloneElement(triggerElement, {
26288
+ const trigger = React85__default.cloneElement(triggerElement, {
25890
26289
  ref: triggerRef,
25891
26290
  onMouseEnter: handleMouseEnter,
25892
26291
  onMouseLeave: handleMouseLeave,
@@ -25976,7 +26375,7 @@ var init_WizardProgress = __esm({
25976
26375
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
25977
26376
  const isActive = index === currentStep;
25978
26377
  const isCompleted = index < currentStep;
25979
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
26378
+ return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
25980
26379
  /* @__PURE__ */ jsx(
25981
26380
  "button",
25982
26381
  {
@@ -26585,6 +26984,80 @@ var init_FlipCard = __esm({
26585
26984
  FlipCard.displayName = "FlipCard";
26586
26985
  }
26587
26986
  });
26987
+ var EMOJI_ITEMS, EmojiPicker;
26988
+ var init_EmojiPicker = __esm({
26989
+ "components/core/molecules/EmojiPicker.tsx"() {
26990
+ "use client";
26991
+ init_useEventBus();
26992
+ init_Button();
26993
+ init_GridPicker();
26994
+ init_Popover();
26995
+ EMOJI_ITEMS = (() => {
26996
+ const items = [];
26997
+ for (const name of ordered) {
26998
+ const entry = lib[name];
26999
+ if (entry === void 0 || entry.char === null || entry.char === "") continue;
27000
+ items.push({
27001
+ id: entry.char,
27002
+ label: name.replace(/_/g, " "),
27003
+ category: entry.category.replace(/_/g, " "),
27004
+ keywords: entry.keywords
27005
+ });
27006
+ }
27007
+ return items;
27008
+ })();
27009
+ EmojiPicker = ({
27010
+ pickEvent,
27011
+ position = "top",
27012
+ triggerIcon = "smile",
27013
+ triggerLabel = "Add emoji",
27014
+ className
27015
+ }) => {
27016
+ const eventBus = useEventBus();
27017
+ const [open, setOpen] = useState(false);
27018
+ const handlePick = (glyph) => {
27019
+ if (pickEvent !== void 0) {
27020
+ const payload = { emoji: glyph };
27021
+ eventBus.emit(`UI:${pickEvent}`, payload);
27022
+ }
27023
+ setOpen(false);
27024
+ };
27025
+ return /* @__PURE__ */ jsx(
27026
+ Popover,
27027
+ {
27028
+ position,
27029
+ trigger: "click",
27030
+ showArrow: false,
27031
+ open,
27032
+ onOpenChange: setOpen,
27033
+ content: /* @__PURE__ */ jsx(
27034
+ GridPicker,
27035
+ {
27036
+ items: EMOJI_ITEMS,
27037
+ onChange: handlePick,
27038
+ searchPlaceholder: "Search emoji\u2026",
27039
+ renderThumbnail: (item) => /* @__PURE__ */ jsx("span", { className: "text-xl leading-none", "aria-hidden": "true", children: item.id }),
27040
+ cellSize: 32,
27041
+ className: "w-80"
27042
+ }
27043
+ ),
27044
+ children: /* @__PURE__ */ jsx(
27045
+ Button,
27046
+ {
27047
+ variant: "ghost",
27048
+ icon: triggerIcon,
27049
+ "aria-label": triggerLabel,
27050
+ title: triggerLabel,
27051
+ className,
27052
+ "data-testid": "emoji-picker-trigger"
27053
+ }
27054
+ )
27055
+ }
27056
+ );
27057
+ };
27058
+ EmojiPicker.displayName = "EmojiPicker";
27059
+ }
27060
+ });
26588
27061
  function toISODate(d) {
26589
27062
  return d.toISOString().slice(0, 10);
26590
27063
  }
@@ -27537,12 +28010,12 @@ var init_MapView = __esm({
27537
28010
  shadowSize: [41, 41]
27538
28011
  });
27539
28012
  L.Marker.prototype.options.icon = defaultIcon;
27540
- const { useEffect: useEffect62, useRef: useRef60, useCallback: useCallback94, useState: useState91 } = React84__default;
28013
+ const { useEffect: useEffect62, useRef: useRef61, useCallback: useCallback95, useState: useState93 } = React85__default;
27541
28014
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
27542
28015
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
27543
28016
  function MapUpdater({ centerLat, centerLng, zoom }) {
27544
28017
  const map = useMap();
27545
- const prevRef = useRef60({ centerLat, centerLng, zoom });
28018
+ const prevRef = useRef61({ centerLat, centerLng, zoom });
27546
28019
  useEffect62(() => {
27547
28020
  const prev = prevRef.current;
27548
28021
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
@@ -27582,8 +28055,8 @@ var init_MapView = __esm({
27582
28055
  showAttribution = true
27583
28056
  }) {
27584
28057
  const eventBus = useEventBus2();
27585
- const [clickedPosition, setClickedPosition] = useState91(null);
27586
- const handleMapClick = useCallback94((lat, lng) => {
28058
+ const [clickedPosition, setClickedPosition] = useState93(null);
28059
+ const handleMapClick = useCallback95((lat, lng) => {
27587
28060
  if (showClickedPin) {
27588
28061
  setClickedPosition({ lat, lng });
27589
28062
  }
@@ -27592,7 +28065,7 @@ var init_MapView = __esm({
27592
28065
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
27593
28066
  }
27594
28067
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
27595
- const handleMarkerClick = useCallback94((marker) => {
28068
+ const handleMarkerClick = useCallback95((marker) => {
27596
28069
  onMarkerClick?.(marker);
27597
28070
  if (markerClickEvent) {
27598
28071
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -28427,6 +28900,7 @@ function TableView({
28427
28900
  fields,
28428
28901
  itemActions,
28429
28902
  maxInlineActions,
28903
+ itemClickEvent,
28430
28904
  selectable = false,
28431
28905
  selectEvent,
28432
28906
  selectedIds,
@@ -28454,8 +28928,8 @@ function TableView({
28454
28928
  }) {
28455
28929
  const eventBus = useEventBus();
28456
28930
  const { t } = useTranslate();
28457
- const [visibleCount, setVisibleCount] = React84__default.useState(pageSize > 0 ? pageSize : Infinity);
28458
- const [localSelected, setLocalSelected] = React84__default.useState(/* @__PURE__ */ new Set());
28931
+ const [visibleCount, setVisibleCount] = React85__default.useState(pageSize > 0 ? pageSize : Infinity);
28932
+ const [localSelected, setLocalSelected] = React85__default.useState(/* @__PURE__ */ new Set());
28459
28933
  const colDefs = (Array.isArray(columns) ? columns : void 0) ?? (Array.isArray(fields) ? fields : void 0) ?? [];
28460
28934
  const actionDefs = Array.isArray(itemActions) ? itemActions : [];
28461
28935
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
@@ -28471,13 +28945,13 @@ function TableView({
28471
28945
  dndItemIdField,
28472
28946
  dndRoot
28473
28947
  });
28474
- const ordered = dnd.orderedItems;
28475
- const data = pageSize > 0 ? ordered.slice(0, visibleCount) : ordered;
28476
- const hasMore = pageSize > 0 && visibleCount < ordered.length;
28948
+ const ordered2 = dnd.orderedItems;
28949
+ const data = pageSize > 0 ? ordered2.slice(0, visibleCount) : ordered2;
28950
+ const hasMore = pageSize > 0 && visibleCount < ordered2.length;
28477
28951
  const hasRenderProp = typeof children === "function";
28478
28952
  const idField = dndItemIdField ?? "id";
28479
28953
  const isCoarsePointer = useMediaQuery("(pointer: coarse)");
28480
- React84__default.useEffect(() => {
28954
+ React85__default.useEffect(() => {
28481
28955
  tableViewLog.debug("render", {
28482
28956
  rowCount: data.length,
28483
28957
  colCount: colDefs.length,
@@ -28526,7 +29000,15 @@ function TableView({
28526
29000
  };
28527
29001
  eventBus.emit(`UI:${action.event}`, payload);
28528
29002
  };
28529
- const colFloors = React84__default.useMemo(
29003
+ const handleRowClick = (row) => () => {
29004
+ if (!itemClickEvent) return;
29005
+ const payload = {
29006
+ id: row.id,
29007
+ row
29008
+ };
29009
+ eventBus.emit(`UI:${itemClickEvent}`, payload);
29010
+ };
29011
+ const colFloors = React85__default.useMemo(
28530
29012
  () => colDefs.map((col) => {
28531
29013
  const longest = data.reduce((widest, row) => {
28532
29014
  const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
@@ -28602,10 +29084,12 @@ function TableView({
28602
29084
  role: "row",
28603
29085
  "data-entity-row": true,
28604
29086
  "data-entity-id": id,
29087
+ onClick: itemClickEvent ? handleRowClick(row) : void 0,
28605
29088
  style: !hasRenderProp ? { gridTemplateColumns } : void 0,
28606
29089
  className: cn(
28607
29090
  "group items-center gap-3 transition-colors duration-fast",
28608
29091
  hasRenderProp ? "flex" : "grid",
29092
+ itemClickEvent && "cursor-pointer",
28609
29093
  lk.rowPad,
28610
29094
  lk.divider && "border-b border-[var(--color-border)]",
28611
29095
  lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
@@ -28613,7 +29097,7 @@ function TableView({
28613
29097
  look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
28614
29098
  ),
28615
29099
  children: [
28616
- selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", children: /* @__PURE__ */ jsx(
29100
+ selectable && /* @__PURE__ */ jsx(Box, { className: "flex items-center", onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0, children: /* @__PURE__ */ jsx(
28617
29101
  Checkbox,
28618
29102
  {
28619
29103
  checked: selected.has(id),
@@ -28638,6 +29122,7 @@ function TableView({
28638
29122
  HStack,
28639
29123
  {
28640
29124
  gap: "xs",
29125
+ onClick: itemClickEvent ? (e) => e.stopPropagation() : void 0,
28641
29126
  className: cn(
28642
29127
  // Pinned: the fixed column tracks routinely overflow the caller's
28643
29128
  // scroll container, which used to leave the actions off-screen.
@@ -28685,12 +29170,12 @@ function TableView({
28685
29170
  ]
28686
29171
  }
28687
29172
  );
28688
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React84__default.Fragment, { children: rowInner }, id);
29173
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React85__default.Fragment, { children: rowInner }, id);
28689
29174
  };
28690
29175
  const items = Array.from(data);
28691
29176
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
28692
29177
  let runningIndex = 0;
28693
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
29178
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
28694
29179
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
28695
29180
  group.items.map((row) => renderRow(row, runningIndex++))
28696
29181
  ] }, gi)) });
@@ -28707,7 +29192,7 @@ function TableView({
28707
29192
  /* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
28708
29193
  t("common.showMore"),
28709
29194
  " (",
28710
- t("common.remaining", { count: ordered.length - visibleCount }),
29195
+ t("common.remaining", { count: ordered2.length - visibleCount }),
28711
29196
  ")"
28712
29197
  ] }) })
28713
29198
  ]
@@ -30053,7 +30538,7 @@ var init_StepFlow = __esm({
30053
30538
  className
30054
30539
  }) => {
30055
30540
  if (orientation === "vertical") {
30056
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React84__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
30541
+ 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: [
30057
30542
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
30058
30543
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
30059
30544
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -30064,7 +30549,7 @@ var init_StepFlow = __esm({
30064
30549
  ] })
30065
30550
  ] }) }, index)) });
30066
30551
  }
30067
- 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(React84__default.Fragment, { children: [
30552
+ 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: [
30068
30553
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
30069
30554
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
30070
30555
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -31054,7 +31539,7 @@ var init_LikertScale = __esm({
31054
31539
  md: "text-base",
31055
31540
  lg: "text-lg"
31056
31541
  };
31057
- LikertScale = React84__default.forwardRef(
31542
+ LikertScale = React85__default.forwardRef(
31058
31543
  ({
31059
31544
  question,
31060
31545
  options = DEFAULT_LIKERT_OPTIONS,
@@ -31066,7 +31551,7 @@ var init_LikertScale = __esm({
31066
31551
  variant = "radios",
31067
31552
  className
31068
31553
  }, ref) => {
31069
- const groupId = React84__default.useId();
31554
+ const groupId = React85__default.useId();
31070
31555
  const eventBus = useEventBus();
31071
31556
  const handleSelect = useCallback(
31072
31557
  (next) => {
@@ -33355,7 +33840,7 @@ var init_DocBreadcrumb = __esm({
33355
33840
  "aria-label": t("aria.breadcrumb"),
33356
33841
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
33357
33842
  const isLast = idx === items.length - 1;
33358
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
33843
+ return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
33359
33844
  idx > 0 && /* @__PURE__ */ jsx(
33360
33845
  Icon,
33361
33846
  {
@@ -34224,7 +34709,7 @@ var init_MiniStateMachine = __esm({
34224
34709
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
34225
34710
  const tc = transitionCounts[s.name] ?? 0;
34226
34711
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
34227
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
34712
+ return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
34228
34713
  /* @__PURE__ */ jsx(
34229
34714
  AvlState,
34230
34715
  {
@@ -34428,7 +34913,7 @@ var init_PageHeader = __esm({
34428
34913
  info: "bg-info/10 text-info"
34429
34914
  };
34430
34915
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
34431
- 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(React84__default.Fragment, { children: [
34916
+ 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: [
34432
34917
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
34433
34918
  crumb.href ? /* @__PURE__ */ jsx(
34434
34919
  "a",
@@ -34786,7 +35271,7 @@ var init_Section = __esm({
34786
35271
  as: Component = "section"
34787
35272
  }) => {
34788
35273
  const hasHeader = title || description || action;
34789
- return React84__default.createElement(
35274
+ return React85__default.createElement(
34790
35275
  Component,
34791
35276
  {
34792
35277
  className: cn(
@@ -35160,7 +35645,7 @@ var init_WizardContainer = __esm({
35160
35645
  const isCompleted = index < currentStep;
35161
35646
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
35162
35647
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
35163
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
35648
+ return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
35164
35649
  /* @__PURE__ */ jsx(
35165
35650
  Button,
35166
35651
  {
@@ -36947,7 +37432,7 @@ var init_ImportPreviewTree = __esm({
36947
37432
  const renderUnit = (unit, childrenByParent, depth) => {
36948
37433
  const summary = fieldSummary(unit);
36949
37434
  const children = childrenByParent.get(unit.ref) ?? [];
36950
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
37435
+ return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
36951
37436
  /* @__PURE__ */ jsxs(
36952
37437
  Box,
36953
37438
  {
@@ -37044,7 +37529,7 @@ var init_ImportProgress = __esm({
37044
37529
  PIPELINE.map((key, index) => {
37045
37530
  const isComplete = index < currentIndex;
37046
37531
  const isActive = index === currentIndex;
37047
- return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
37532
+ return /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
37048
37533
  index > 0 ? /* @__PURE__ */ jsx(Box, { className: "h-px w-4 bg-border" }) : null,
37049
37534
  /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-1", "data-testid": `import-progress-step-${key}`, children: [
37050
37535
  /* @__PURE__ */ jsx(
@@ -38157,7 +38642,7 @@ var init_DrawGroup = __esm({
38157
38642
  }
38158
38643
  });
38159
38644
  function extractTitle(children) {
38160
- if (!React84__default.isValidElement(children)) return void 0;
38645
+ if (!React85__default.isValidElement(children)) return void 0;
38161
38646
  const props = children.props;
38162
38647
  if (typeof props.title === "string") {
38163
38648
  return props.title;
@@ -38507,12 +38992,12 @@ var init_Form = __esm({
38507
38992
  const isSchemaEntity = isOrbitalEntitySchema(entity);
38508
38993
  const resolvedEntity = isSchemaEntity ? entity : void 0;
38509
38994
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
38510
- const normalizedInitialData = React84__default.useMemo(() => {
38995
+ const normalizedInitialData = React85__default.useMemo(() => {
38511
38996
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
38512
38997
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
38513
38998
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
38514
38999
  }, [entity, initialData]);
38515
- const entityDerivedFields = React84__default.useMemo(() => {
39000
+ const entityDerivedFields = React85__default.useMemo(() => {
38516
39001
  if (fields && fields.length > 0) return void 0;
38517
39002
  if (!resolvedEntity) return void 0;
38518
39003
  return resolvedEntity.fields.map(
@@ -38533,16 +39018,16 @@ var init_Form = __esm({
38533
39018
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
38534
39019
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
38535
39020
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
38536
- const [formData, setFormData] = React84__default.useState(
39021
+ const [formData, setFormData] = React85__default.useState(
38537
39022
  normalizedInitialData
38538
39023
  );
38539
- const [collapsedSections, setCollapsedSections] = React84__default.useState(
39024
+ const [collapsedSections, setCollapsedSections] = React85__default.useState(
38540
39025
  /* @__PURE__ */ new Set()
38541
39026
  );
38542
- const [submitError, setSubmitError] = React84__default.useState(null);
38543
- const formRef = React84__default.useRef(null);
39027
+ const [submitError, setSubmitError] = React85__default.useState(null);
39028
+ const formRef = React85__default.useRef(null);
38544
39029
  const formMode = props.mode;
38545
- const mountedRef = React84__default.useRef(false);
39030
+ const mountedRef = React85__default.useRef(false);
38546
39031
  if (!mountedRef.current) {
38547
39032
  mountedRef.current = true;
38548
39033
  debug("forms", "mount", {
@@ -38555,7 +39040,7 @@ var init_Form = __esm({
38555
39040
  });
38556
39041
  }
38557
39042
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
38558
- const evalContext = React84__default.useMemo(
39043
+ const evalContext = React85__default.useMemo(
38559
39044
  () => ({
38560
39045
  formValues: formData,
38561
39046
  globalVariables: externalContext?.globalVariables ?? {},
@@ -38564,7 +39049,7 @@ var init_Form = __esm({
38564
39049
  }),
38565
39050
  [formData, externalContext]
38566
39051
  );
38567
- React84__default.useEffect(() => {
39052
+ React85__default.useEffect(() => {
38568
39053
  debug("forms", "initialData-sync", {
38569
39054
  mode: formMode,
38570
39055
  normalizedInitialData,
@@ -38575,7 +39060,7 @@ var init_Form = __esm({
38575
39060
  setFormData(normalizedInitialData);
38576
39061
  }
38577
39062
  }, [normalizedInitialData]);
38578
- const processCalculations = React84__default.useCallback(
39063
+ const processCalculations = React85__default.useCallback(
38579
39064
  (changedFieldId, newFormData) => {
38580
39065
  if (!hiddenCalculations.length) return;
38581
39066
  const context = {
@@ -38600,7 +39085,7 @@ var init_Form = __esm({
38600
39085
  },
38601
39086
  [hiddenCalculations, externalContext, eventBus]
38602
39087
  );
38603
- const checkViolations = React84__default.useCallback(
39088
+ const checkViolations = React85__default.useCallback(
38604
39089
  (changedFieldId, newFormData) => {
38605
39090
  if (!violationTriggers.length) return;
38606
39091
  const context = {
@@ -38638,7 +39123,7 @@ var init_Form = __esm({
38638
39123
  processCalculations(name, newFormData);
38639
39124
  checkViolations(name, newFormData);
38640
39125
  };
38641
- const isFieldVisible = React84__default.useCallback(
39126
+ const isFieldVisible = React85__default.useCallback(
38642
39127
  (fieldName) => {
38643
39128
  const condition = conditionalFields[fieldName];
38644
39129
  if (!condition) return true;
@@ -38646,7 +39131,7 @@ var init_Form = __esm({
38646
39131
  },
38647
39132
  [conditionalFields, evalContext]
38648
39133
  );
38649
- const isSectionVisible = React84__default.useCallback(
39134
+ const isSectionVisible = React85__default.useCallback(
38650
39135
  (section) => {
38651
39136
  if (!section.condition) return true;
38652
39137
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -38722,7 +39207,7 @@ var init_Form = __esm({
38722
39207
  eventBus.emit(`UI:${onCancel}`);
38723
39208
  }
38724
39209
  };
38725
- const renderField = React84__default.useCallback(
39210
+ const renderField = React85__default.useCallback(
38726
39211
  (field) => {
38727
39212
  const fieldName = field.name || field.field;
38728
39213
  if (!fieldName) return null;
@@ -38743,7 +39228,7 @@ var init_Form = __esm({
38743
39228
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
38744
39229
  );
38745
39230
  const effectiveFields = entityDerivedFields ?? fields;
38746
- const normalizedFields = React84__default.useMemo(() => {
39231
+ const normalizedFields = React85__default.useMemo(() => {
38747
39232
  if (!effectiveFields || effectiveFields.length === 0) return [];
38748
39233
  return effectiveFields.map((field) => {
38749
39234
  if (typeof field === "string") {
@@ -38767,7 +39252,7 @@ var init_Form = __esm({
38767
39252
  return field;
38768
39253
  });
38769
39254
  }, [effectiveFields, resolvedEntity]);
38770
- const schemaFields = React84__default.useMemo(() => {
39255
+ const schemaFields = React85__default.useMemo(() => {
38771
39256
  if (normalizedFields.length === 0) return null;
38772
39257
  if (isDebugEnabled()) {
38773
39258
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -38777,7 +39262,7 @@ var init_Form = __esm({
38777
39262
  }
38778
39263
  return normalizedFields.map(renderField).filter(Boolean);
38779
39264
  }, [normalizedFields, renderField, entityName, conditionalFields]);
38780
- const sectionElements = React84__default.useMemo(() => {
39265
+ const sectionElements = React85__default.useMemo(() => {
38781
39266
  if (!sections || sections.length === 0) return null;
38782
39267
  return sections.map((section) => {
38783
39268
  if (!isSectionVisible(section)) {
@@ -39503,7 +39988,7 @@ var init_List = __esm({
39503
39988
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
39504
39989
  return [];
39505
39990
  }, [entity]);
39506
- const getItemActions = React84__default.useCallback(
39991
+ const getItemActions = React85__default.useCallback(
39507
39992
  (item) => {
39508
39993
  if (!itemActions) return [];
39509
39994
  if (typeof itemActions === "function") {
@@ -39984,7 +40469,7 @@ var init_MediaGallery = __esm({
39984
40469
  [selectable, selectedItems, selectionEvent, eventBus]
39985
40470
  );
39986
40471
  const entityData = Array.isArray(entity) ? entity : [];
39987
- const items = React84__default.useMemo(() => {
40472
+ const items = React85__default.useMemo(() => {
39988
40473
  if (propItems && propItems.length > 0) return propItems;
39989
40474
  if (entityData.length === 0) return [];
39990
40475
  return entityData.map((record, idx) => {
@@ -40149,7 +40634,7 @@ var init_MediaGallery = __esm({
40149
40634
  }
40150
40635
  });
40151
40636
  function extractTitle2(children) {
40152
- if (!React84__default.isValidElement(children)) return void 0;
40637
+ if (!React85__default.isValidElement(children)) return void 0;
40153
40638
  const props = children.props;
40154
40639
  if (typeof props.title === "string") {
40155
40640
  return props.title;
@@ -40404,7 +40889,7 @@ var init_debugRegistry = __esm({
40404
40889
  }
40405
40890
  });
40406
40891
  function useDebugData() {
40407
- const [data, setData] = React84.useState(() => ({
40892
+ const [data, setData] = React85.useState(() => ({
40408
40893
  traits: [],
40409
40894
  ticks: [],
40410
40895
  guards: [],
@@ -40418,7 +40903,7 @@ function useDebugData() {
40418
40903
  },
40419
40904
  lastUpdate: Date.now()
40420
40905
  }));
40421
- React84.useEffect(() => {
40906
+ React85.useEffect(() => {
40422
40907
  const updateData = () => {
40423
40908
  setData({
40424
40909
  traits: getAllTraits(),
@@ -40527,12 +41012,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
40527
41012
  return positions;
40528
41013
  }
40529
41014
  function WalkMinimap() {
40530
- const [walkStep, setWalkStep] = React84.useState(null);
40531
- const [traits2, setTraits] = React84.useState([]);
40532
- const [coveredEdges, setCoveredEdges] = React84.useState([]);
40533
- const [completedTraits, setCompletedTraits] = React84.useState(/* @__PURE__ */ new Set());
40534
- const prevTraitRef = React84.useRef(null);
40535
- React84.useEffect(() => {
41015
+ const [walkStep, setWalkStep] = React85.useState(null);
41016
+ const [traits2, setTraits] = React85.useState([]);
41017
+ const [coveredEdges, setCoveredEdges] = React85.useState([]);
41018
+ const [completedTraits, setCompletedTraits] = React85.useState(/* @__PURE__ */ new Set());
41019
+ const prevTraitRef = React85.useRef(null);
41020
+ React85.useEffect(() => {
40536
41021
  const interval = setInterval(() => {
40537
41022
  const w = window;
40538
41023
  const step = w.__orbitalWalkStep;
@@ -40968,15 +41453,15 @@ var init_EntitiesTab = __esm({
40968
41453
  });
40969
41454
  function EventFlowTab({ events: events2 }) {
40970
41455
  const { t } = useTranslate();
40971
- const [filter, setFilter] = React84.useState("all");
40972
- const containerRef = React84.useRef(null);
40973
- const [autoScroll, setAutoScroll] = React84.useState(true);
40974
- React84.useEffect(() => {
41456
+ const [filter, setFilter] = React85.useState("all");
41457
+ const containerRef = React85.useRef(null);
41458
+ const [autoScroll, setAutoScroll] = React85.useState(true);
41459
+ React85.useEffect(() => {
40975
41460
  if (autoScroll && containerRef.current) {
40976
41461
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
40977
41462
  }
40978
41463
  }, [events2.length, autoScroll]);
40979
- const filteredEvents = React84.useMemo(() => {
41464
+ const filteredEvents = React85.useMemo(() => {
40980
41465
  if (filter === "all") return events2;
40981
41466
  return events2.filter((e) => e.type === filter);
40982
41467
  }, [events2, filter]);
@@ -41092,7 +41577,7 @@ var init_EventFlowTab = __esm({
41092
41577
  });
41093
41578
  function GuardsPanel({ guards }) {
41094
41579
  const { t } = useTranslate();
41095
- const [filter, setFilter] = React84.useState("all");
41580
+ const [filter, setFilter] = React85.useState("all");
41096
41581
  if (guards.length === 0) {
41097
41582
  return /* @__PURE__ */ jsx(
41098
41583
  EmptyState,
@@ -41105,7 +41590,7 @@ function GuardsPanel({ guards }) {
41105
41590
  }
41106
41591
  const passedCount = guards.filter((g) => g.result).length;
41107
41592
  const failedCount = guards.length - passedCount;
41108
- const filteredGuards = React84.useMemo(() => {
41593
+ const filteredGuards = React85.useMemo(() => {
41109
41594
  if (filter === "all") return guards;
41110
41595
  if (filter === "passed") return guards.filter((g) => g.result);
41111
41596
  return guards.filter((g) => !g.result);
@@ -41268,10 +41753,10 @@ function EffectBadge({ effect }) {
41268
41753
  }
41269
41754
  function TransitionTimeline({ transitions }) {
41270
41755
  const { t } = useTranslate();
41271
- const containerRef = React84.useRef(null);
41272
- const [autoScroll, setAutoScroll] = React84.useState(true);
41273
- const [expandedId, setExpandedId] = React84.useState(null);
41274
- React84.useEffect(() => {
41756
+ const containerRef = React85.useRef(null);
41757
+ const [autoScroll, setAutoScroll] = React85.useState(true);
41758
+ const [expandedId, setExpandedId] = React85.useState(null);
41759
+ React85.useEffect(() => {
41275
41760
  if (autoScroll && containerRef.current) {
41276
41761
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
41277
41762
  }
@@ -41551,9 +42036,9 @@ function getAllEvents(traits2) {
41551
42036
  function EventDispatcherTab({ traits: traits2, schema }) {
41552
42037
  const eventBus = useEventBus();
41553
42038
  const { t } = useTranslate();
41554
- const [log13, setLog] = React84.useState([]);
41555
- const prevStatesRef = React84.useRef(/* @__PURE__ */ new Map());
41556
- React84.useEffect(() => {
42039
+ const [log13, setLog] = React85.useState([]);
42040
+ const prevStatesRef = React85.useRef(/* @__PURE__ */ new Map());
42041
+ React85.useEffect(() => {
41557
42042
  for (const trait of traits2) {
41558
42043
  const prev = prevStatesRef.current.get(trait.id);
41559
42044
  if (prev && prev !== trait.currentState) {
@@ -41722,10 +42207,10 @@ function VerifyModePanel({
41722
42207
  localCount
41723
42208
  }) {
41724
42209
  const { t } = useTranslate();
41725
- const [expanded, setExpanded] = React84.useState(true);
41726
- const scrollRef = React84.useRef(null);
41727
- const prevCountRef = React84.useRef(0);
41728
- React84.useEffect(() => {
42210
+ const [expanded, setExpanded] = React85.useState(true);
42211
+ const scrollRef = React85.useRef(null);
42212
+ const prevCountRef = React85.useRef(0);
42213
+ React85.useEffect(() => {
41729
42214
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
41730
42215
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
41731
42216
  }
@@ -41782,10 +42267,10 @@ function RuntimeDebugger({
41782
42267
  schema
41783
42268
  }) {
41784
42269
  const { t } = useTranslate();
41785
- const [isCollapsed, setIsCollapsed] = React84.useState(mode === "verify" ? true : defaultCollapsed);
41786
- const [isVisible, setIsVisible] = React84.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
42270
+ const [isCollapsed, setIsCollapsed] = React85.useState(mode === "verify" ? true : defaultCollapsed);
42271
+ const [isVisible, setIsVisible] = React85.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
41787
42272
  const debugData = useDebugData();
41788
- React84.useEffect(() => {
42273
+ React85.useEffect(() => {
41789
42274
  if (mode === "inline") return;
41790
42275
  return onDebugToggle((enabled) => {
41791
42276
  setIsVisible(enabled);
@@ -41794,7 +42279,7 @@ function RuntimeDebugger({
41794
42279
  }
41795
42280
  });
41796
42281
  }, [mode]);
41797
- React84.useEffect(() => {
42282
+ React85.useEffect(() => {
41798
42283
  if (mode === "inline") return;
41799
42284
  const handleKeyDown = (e) => {
41800
42285
  if (e.key === "`" && isVisible) {
@@ -42314,7 +42799,7 @@ var init_StatCard = __esm({
42314
42799
  const labelToUse = propLabel ?? propTitle;
42315
42800
  const eventBus = useEventBus();
42316
42801
  const { t } = useTranslate();
42317
- const handleActionClick = React84__default.useCallback(() => {
42802
+ const handleActionClick = React85__default.useCallback(() => {
42318
42803
  if (action?.event) {
42319
42804
  eventBus.emit(`UI:${action.event}`, {});
42320
42805
  }
@@ -42325,7 +42810,7 @@ var init_StatCard = __esm({
42325
42810
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
42326
42811
  const isLoading = externalLoading ?? false;
42327
42812
  const error = externalError;
42328
- const computeMetricValue = React84__default.useCallback(
42813
+ const computeMetricValue = React85__default.useCallback(
42329
42814
  (metric, items) => {
42330
42815
  if (metric.value !== void 0) {
42331
42816
  return metric.value;
@@ -42364,7 +42849,7 @@ var init_StatCard = __esm({
42364
42849
  },
42365
42850
  []
42366
42851
  );
42367
- const schemaStats = React84__default.useMemo(() => {
42852
+ const schemaStats = React85__default.useMemo(() => {
42368
42853
  if (!metrics || metrics.length === 0) return null;
42369
42854
  return metrics.map((metric) => ({
42370
42855
  label: metric.label,
@@ -42372,7 +42857,7 @@ var init_StatCard = __esm({
42372
42857
  format: metric.format
42373
42858
  }));
42374
42859
  }, [metrics, data, computeMetricValue]);
42375
- const calculatedTrend = React84__default.useMemo(() => {
42860
+ const calculatedTrend = React85__default.useMemo(() => {
42376
42861
  if (manualTrend !== void 0) return manualTrend;
42377
42862
  if (previousValue === void 0 || currentValue === void 0)
42378
42863
  return void 0;
@@ -43012,8 +43497,8 @@ var init_SubagentTracePanel = __esm({
43012
43497
  ] });
43013
43498
  };
43014
43499
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
43015
- const endRef = React84__default.useRef(null);
43016
- React84__default.useEffect(() => {
43500
+ const endRef = React85__default.useRef(null);
43501
+ React85__default.useEffect(() => {
43017
43502
  if (!autoScroll) return;
43018
43503
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
43019
43504
  }, [activities.length, autoScroll]);
@@ -43107,7 +43592,7 @@ var init_SubagentTracePanel = __esm({
43107
43592
  };
43108
43593
  SubagentRichCard = ({ subagent }) => {
43109
43594
  const { t } = useTranslate();
43110
- const activities = React84__default.useMemo(
43595
+ const activities = React85__default.useMemo(
43111
43596
  () => subagentMessagesToActivities(subagent.messages),
43112
43597
  [subagent.messages]
43113
43598
  );
@@ -43184,8 +43669,8 @@ var init_SubagentTracePanel = __esm({
43184
43669
  ] });
43185
43670
  };
43186
43671
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
43187
- const endRef = React84__default.useRef(null);
43188
- React84__default.useEffect(() => {
43672
+ const endRef = React85__default.useRef(null);
43673
+ React85__default.useEffect(() => {
43189
43674
  if (!autoScroll) return;
43190
43675
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
43191
43676
  }, [messages.length, autoScroll]);
@@ -43620,7 +44105,7 @@ var init_Timeline = __esm({
43620
44105
  }) => {
43621
44106
  const { t } = useTranslate();
43622
44107
  const entityData = entity ?? [];
43623
- const items = React84__default.useMemo(() => {
44108
+ const items = React85__default.useMemo(() => {
43624
44109
  if (propItems) return propItems;
43625
44110
  if (entityData.length === 0) return [];
43626
44111
  return entityData.map((record, idx) => {
@@ -43722,7 +44207,7 @@ var init_Timeline = __esm({
43722
44207
  }
43723
44208
  });
43724
44209
  function extractToastProps(children) {
43725
- if (!React84__default.isValidElement(children)) {
44210
+ if (!React85__default.isValidElement(children)) {
43726
44211
  if (typeof children === "string") {
43727
44212
  return { message: children };
43728
44213
  }
@@ -43764,7 +44249,7 @@ var init_ToastSlot = __esm({
43764
44249
  eventBus.emit(`${prefix}CLOSE`);
43765
44250
  };
43766
44251
  if (!isVisible) return null;
43767
- const isCustomContent = React84__default.isValidElement(children) && !message;
44252
+ const isCustomContent = React85__default.isValidElement(children) && !message;
43768
44253
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
43769
44254
  Toast,
43770
44255
  {
@@ -43869,6 +44354,7 @@ var init_component_registry_generated = __esm({
43869
44354
  init_Drawer();
43870
44355
  init_DrawerSlot();
43871
44356
  init_EdgeDecoration();
44357
+ init_EmojiPicker();
43872
44358
  init_EmptyState();
43873
44359
  init_ErrorBoundary();
43874
44360
  init_ErrorState();
@@ -44136,6 +44622,7 @@ var init_component_registry_generated = __esm({
44136
44622
  "Drawer": Drawer,
44137
44623
  "DrawerSlot": DrawerSlot,
44138
44624
  "EdgeDecoration": EdgeDecoration,
44625
+ "EmojiPicker": EmojiPicker,
44139
44626
  "EmptyState": EmptyState,
44140
44627
  "ErrorBoundary": ErrorBoundary,
44141
44628
  "ErrorState": ErrorState,
@@ -44335,7 +44822,7 @@ function SuspenseConfigProvider({
44335
44822
  config,
44336
44823
  children
44337
44824
  }) {
44338
- return React84__default.createElement(
44825
+ return React85__default.createElement(
44339
44826
  SuspenseConfigContext.Provider,
44340
44827
  { value: config },
44341
44828
  children
@@ -44377,7 +44864,7 @@ function enrichFormFields(fields, entityDef) {
44377
44864
  }
44378
44865
  return { name: field, label: humanizeFieldName(field) };
44379
44866
  }
44380
- if (field && typeof field === "object" && !Array.isArray(field) && !React84__default.isValidElement(field) && !(field instanceof Date)) {
44867
+ if (field && typeof field === "object" && !Array.isArray(field) && !React85__default.isValidElement(field) && !(field instanceof Date)) {
44381
44868
  const obj = field;
44382
44869
  const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
44383
44870
  if (!fieldName) return field;
@@ -44563,7 +45050,19 @@ function UISlotComponent({
44563
45050
  const suspenseConfig = useContext(SuspenseConfigContext);
44564
45051
  const contained = useContext(SlotContainedContext);
44565
45052
  const schemaCtx = useEntitySchemaOptional();
44566
- const content = slots[slot];
45053
+ const rawContent = slots[slot];
45054
+ const binding = useEntityBindingSnapshot(rawContent?.sourceTrait);
45055
+ const content = useMemo(() => {
45056
+ if (!rawContent) return rawContent;
45057
+ const resolvedProps = resolveRenderBindingMarkers(
45058
+ rawContent.props,
45059
+ rawContent.sourceTrait,
45060
+ binding.entity,
45061
+ binding.config,
45062
+ binding.state
45063
+ );
45064
+ return resolvedProps === rawContent.props ? rawContent : { ...rawContent, props: resolvedProps };
45065
+ }, [rawContent, binding.entity, binding.config, binding.state]);
44567
45066
  if (children !== void 0) {
44568
45067
  if (pattern === "clear") {
44569
45068
  return null;
@@ -44837,7 +45336,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
44837
45336
  const key = `${parentId}-${index}-trait:${traitName}`;
44838
45337
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
44839
45338
  }
44840
- return /* @__PURE__ */ jsx(React84__default.Fragment, { children: child }, `${parentId}-${index}`);
45339
+ return /* @__PURE__ */ jsx(React85__default.Fragment, { children: child }, `${parentId}-${index}`);
44841
45340
  }
44842
45341
  if (!child || typeof child !== "object") return null;
44843
45342
  const childId = `${parentId}-${index}`;
@@ -44894,19 +45393,20 @@ function isPatternConfig(value) {
44894
45393
  if (value === null || value === void 0) return false;
44895
45394
  if (typeof value !== "object") return false;
44896
45395
  if (Array.isArray(value)) return false;
44897
- if (React84__default.isValidElement(value)) return false;
45396
+ if (React85__default.isValidElement(value)) return false;
44898
45397
  if (value instanceof Date) return false;
44899
45398
  if (typeof value === "function") return false;
44900
45399
  const record = value;
44901
45400
  return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
44902
45401
  }
44903
45402
  function isPlainConfigObject(value) {
44904
- if (React84__default.isValidElement(value)) return false;
45403
+ if (React85__default.isValidElement(value)) return false;
44905
45404
  if (value instanceof Date) return false;
44906
45405
  const proto = Object.getPrototypeOf(value);
44907
45406
  return proto === Object.prototype || proto === null;
44908
45407
  }
44909
45408
  function substituteTraitRefsDeep(value, pathKey) {
45409
+ if (isRenderBindingMarker(value)) return value;
44910
45410
  if (typeof value === "string") {
44911
45411
  const match = TRAIT_BINDING_RE.exec(value);
44912
45412
  if (match) {
@@ -44979,7 +45479,14 @@ function SlotContentRenderer({
44979
45479
  onDismiss,
44980
45480
  patternPath
44981
45481
  }) {
44982
- const entityProp = content.props.entity;
45482
+ const ambientScope = useTraitScope();
45483
+ const bindingTrait = content.sourceTrait ?? ambientScope?.trait;
45484
+ const binding = useEntityBindingSnapshot(bindingTrait);
45485
+ const liveProps = useMemo(
45486
+ () => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state),
45487
+ [content.props, bindingTrait, binding.entity, binding.config, binding.state]
45488
+ );
45489
+ const entityProp = liveProps.entity;
44983
45490
  if (content.pattern === "form-section") {
44984
45491
  slotLog.debug("SlotContentRenderer:form-section-render", {
44985
45492
  contentId: content.id,
@@ -45010,7 +45517,7 @@ function SlotContentRenderer({
45010
45517
  const orbitalName = schemaCtx && content.sourceTrait !== void 0 ? schemaCtx.orbitalsByTrait.get(content.sourceTrait) : void 0;
45011
45518
  const PatternComponent = getComponentForPattern(content.pattern);
45012
45519
  if (PatternComponent) {
45013
- const childrenConfig = content.props.children;
45520
+ const childrenConfig = liveProps.children;
45014
45521
  const isSingleChild = typeof childrenConfig === "string" || typeof childrenConfig === "object" && childrenConfig !== null && !Array.isArray(childrenConfig) && "type" in childrenConfig;
45015
45522
  const hasChildren = PATTERNS_WITH_CHILDREN.has(content.pattern) || Array.isArray(childrenConfig) && childrenConfig.length > 0 || isSingleChild;
45016
45523
  const isDrawHost = isDrawHostPattern(content.pattern);
@@ -45021,15 +45528,15 @@ function SlotContentRenderer({
45021
45528
  fromState: content.fromState,
45022
45529
  entity: content.entity
45023
45530
  }) : void 0;
45024
- const incomingChildren = content.props.children;
45531
+ const incomingChildren = liveProps.children;
45025
45532
  const childrenIsRenderFn = typeof incomingChildren === "function";
45026
- const { children: _childrenConfig, ...restPropsNoChildren } = content.props;
45533
+ const { children: _childrenConfig, ...restPropsNoChildren } = liveProps;
45027
45534
  const restProps = childrenIsRenderFn ? { ...restPropsNoChildren, children: incomingChildren } : restPropsNoChildren;
45028
45535
  const nodeSlotOverrides = {};
45029
45536
  for (const slotKey of CONTENT_NODE_SLOTS) {
45030
45537
  const slotVal = restProps[slotKey];
45031
45538
  if (slotVal === void 0 || slotVal === null) continue;
45032
- if (React84__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
45539
+ if (React85__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
45033
45540
  const typelessChildren = !Array.isArray(slotVal) && typeof slotVal === "object" && !("type" in slotVal) && Array.isArray(slotVal.children) ? slotVal.children : void 0;
45034
45541
  if (typelessChildren !== void 0 || Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
45035
45542
  nodeSlotOverrides[slotKey] = renderPatternChildren(
@@ -45083,7 +45590,7 @@ function SlotContentRenderer({
45083
45590
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
45084
45591
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
45085
45592
  const sample = resolvedItems[0];
45086
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React84__default.isValidElement(sample) && !(sample instanceof Date)) {
45593
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React85__default.isValidElement(sample) && !(sample instanceof Date)) {
45087
45594
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
45088
45595
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
45089
45596
  }
@@ -45132,7 +45639,7 @@ function SlotContentRenderer({
45132
45639
  "data-orb-path": patternPath ?? "root",
45133
45640
  "data-orb-pattern": content.pattern,
45134
45641
  "data-orb-orbital": orbitalName,
45135
- children: content.props.children ?? /* @__PURE__ */ jsxs(Box, { className: "p-4 text-sm text-muted-foreground border border-dashed border-border rounded", children: [
45642
+ children: liveProps.children ?? /* @__PURE__ */ jsxs(Box, { className: "p-4 text-sm text-muted-foreground border border-dashed border-border rounded", children: [
45136
45643
  "Unknown pattern: ",
45137
45644
  content.pattern,
45138
45645
  content.sourceTrait && /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "ml-2", children: [
@@ -45204,6 +45711,7 @@ var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext,
45204
45711
  var init_UISlotRenderer = __esm({
45205
45712
  "components/core/organisms/UISlotRenderer.tsx"() {
45206
45713
  "use client";
45714
+ init_resolve_render_bindings();
45207
45715
  init_Modal();
45208
45716
  init_Drawer();
45209
45717
  init_Toast();
@@ -45598,9 +46106,10 @@ function VerificationProvider({
45598
46106
  }));
45599
46107
  const effectResults = Array.isArray(payload["effectResults"]) ? payload["effectResults"] : [];
45600
46108
  for (const er of effectResults) {
46109
+ const target = er["entity"] ?? er["service"];
45601
46110
  effects.push({
45602
46111
  type: String(er["type"] ?? er["effect"] ?? "server-effect"),
45603
- args: [er["entity"] ?? er["service"] ?? ""].filter(Boolean),
46112
+ args: typeof target === "string" && target !== "" ? [target] : [],
45604
46113
  status: er["error"] ? "failed" : "executed",
45605
46114
  error: er["error"]
45606
46115
  });
@@ -46389,7 +46898,7 @@ function reEmitServerEvent(eventBus, emitted, origin) {
46389
46898
  sourceTrait: evTrait,
46390
46899
  origin
46391
46900
  });
46392
- eventBus.emit(key, emitted.payload);
46901
+ eventBus.emit(key, emitted.payload, emitted.source);
46393
46902
  }
46394
46903
  function isBusPushEnvelope(value) {
46395
46904
  return value.type === "bus" && typeof value.event === "string";
@@ -46557,7 +47066,12 @@ function ServerBridgeProvider({
46557
47066
  }
46558
47067
  if (result.emittedEvents) {
46559
47068
  for (const emitted of result.emittedEvents) {
46560
- reEmitServerEvent(eventBus, emitted, orbitalName);
47069
+ if (emitted.event === event) continue;
47070
+ reEmitServerEvent(
47071
+ eventBus,
47072
+ { ...emitted, source: { ...emitted.source, dispatched: true } },
47073
+ orbitalName
47074
+ );
46561
47075
  }
46562
47076
  }
46563
47077
  } else if (result.error) {
@@ -46695,10 +47209,29 @@ function useTraitScopeChain2() {
46695
47209
  const chain = useContext(TraitScopeContext);
46696
47210
  return chain ?? EMPTY_CHAIN;
46697
47211
  }
46698
- function useTraitScope() {
47212
+ function useTraitScope2() {
46699
47213
  const chain = useContext(TraitScopeContext);
46700
47214
  return chain && chain.length > 0 ? chain[0] : null;
46701
47215
  }
47216
+ var EntityBindingContext = createContext(null);
47217
+ var EMPTY_ENTITY = {};
47218
+ var NOOP_SUBSCRIBE = () => () => void 0;
47219
+ function useEntityBindingSnapshot2(traitName) {
47220
+ const source = useContext(EntityBindingContext);
47221
+ const entity = useSyncExternalStore(
47222
+ source !== null && traitName !== void 0 ? (onStoreChange) => source.subscribe(traitName, onStoreChange) : NOOP_SUBSCRIBE,
47223
+ () => source !== null && traitName !== void 0 ? source.getEntitySnapshot(traitName) : EMPTY_ENTITY
47224
+ );
47225
+ const config = useMemo(
47226
+ () => source !== null && traitName !== void 0 ? source.getConfig(traitName) : void 0,
47227
+ [source, traitName]
47228
+ );
47229
+ return {
47230
+ entity,
47231
+ config,
47232
+ state: source !== null && traitName !== void 0 ? source.getState(traitName) : ""
47233
+ };
47234
+ }
46702
47235
 
46703
47236
  // providers/OfflineModeProvider.tsx
46704
47237
  init_offline_executor();
@@ -46791,4 +47324,4 @@ function GameAudioProvider2({
46791
47324
  }
46792
47325
  GameAudioProvider2.displayName = "GameAudioProvider";
46793
47326
 
46794
- export { CurrentPagePathContext, CurrentPagePathProvider, EntitySchemaProvider, EventBusContext2 as EventBusContext, EventBusProvider, GameAudioContext2 as GameAudioContext, GameAudioProvider2 as GameAudioProvider, NavigationProvider2 as NavigationProvider, OfflineModeProvider, OrbitalProvider, OrbitalThemeProvider, SelectionContext, SelectionProvider, ServerBridgeProvider, TraitContext, TraitProvider, TraitScopeProvider3 as TraitScopeProvider, UserContext, UserProvider, VerificationProvider, comparePathSpecificity2 as comparePathSpecificity, extractRouteParams2 as extractRouteParams, findPageByName2 as findPageByName, findPageByPath2 as findPageByPath, getAllPages2 as getAllPages, getDefaultPage2 as getDefaultPage, matchPath2 as matchPath, matchPathAmong2 as matchPathAmong, pathMatches2 as pathMatches, useActivePage2 as useActivePage, useCurrentPagePath2 as useCurrentPagePath, useEntitySchema, useEntitySchemaOptional6 as useEntitySchemaOptional, useGameAudioContext2 as useGameAudioContext, useGameAudioContextOptional2 as useGameAudioContextOptional, useHasPermission, useHasRole, useInitPayload2 as useInitPayload, useNavigateTo2 as useNavigateTo, useNavigation2 as useNavigation, useNavigationId2 as useNavigationId, useNavigationState2 as useNavigationState, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useServerBridge, useTrait, useTraitContext, useTraitScope, useTraitScopeChain2 as useTraitScopeChain, useUser, useUserForEvaluation };
47327
+ export { CurrentPagePathContext, CurrentPagePathProvider, EntityBindingContext, EntitySchemaProvider, EventBusContext2 as EventBusContext, EventBusProvider, GameAudioContext2 as GameAudioContext, GameAudioProvider2 as GameAudioProvider, NavigationProvider2 as NavigationProvider, OfflineModeProvider, OrbitalProvider, OrbitalThemeProvider, SelectionContext, SelectionProvider, ServerBridgeProvider, TraitContext, TraitProvider, TraitScopeProvider3 as TraitScopeProvider, UserContext, UserProvider, VerificationProvider, comparePathSpecificity2 as comparePathSpecificity, extractRouteParams2 as extractRouteParams, findPageByName2 as findPageByName, findPageByPath2 as findPageByPath, getAllPages2 as getAllPages, getDefaultPage2 as getDefaultPage, matchPath2 as matchPath, matchPathAmong2 as matchPathAmong, pathMatches2 as pathMatches, useActivePage2 as useActivePage, useCurrentPagePath2 as useCurrentPagePath, useEntityBindingSnapshot2 as useEntityBindingSnapshot, useEntitySchema, useEntitySchemaOptional6 as useEntitySchemaOptional, useGameAudioContext2 as useGameAudioContext, useGameAudioContextOptional2 as useGameAudioContextOptional, useHasPermission, useHasRole, useInitPayload2 as useInitPayload, useNavigateTo2 as useNavigateTo, useNavigation2 as useNavigation, useNavigationId2 as useNavigationId, useNavigationState2 as useNavigationState, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useServerBridge, useTrait, useTraitContext, useTraitScope2 as useTraitScope, useTraitScopeChain2 as useTraitScopeChain, useUser, useUserForEvaluation };