@almadar/ui 5.121.3 → 5.121.4

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.
@@ -3,7 +3,7 @@ import * as React73 from 'react';
3
3
  import React73__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, useState, Suspense, lazy, useSyncExternalStore, useLayoutEffect, useId } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
- import { EventBusContext, useTraitScope, useCurrentPagePath, useGameAudioContextOptional, useEntitySchemaOptional, TraitScopeProvider } from '@almadar/ui/providers';
6
+ import { EventBusContext, useTraitScopeChain, useCurrentPagePath, useGameAudioContextOptional, useEntitySchemaOptional, TraitScopeProvider } from '@almadar/ui/providers';
7
7
  export { GameAudioContext, GameAudioProvider, useGameAudioContext } from '@almadar/ui/providers';
8
8
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
9
9
  import * as LucideIcons2 from 'lucide-react';
@@ -1043,9 +1043,9 @@ function getGlobalEventBus() {
1043
1043
  function useEventBus() {
1044
1044
  const context = useContext(EventBusContext);
1045
1045
  const baseBus = context ?? getGlobalEventBus() ?? fallbackEventBus;
1046
- const scope = useTraitScope();
1046
+ const chain = useTraitScopeChain();
1047
1047
  return useMemo(() => {
1048
- if (!scope) {
1048
+ if (chain.length === 0) {
1049
1049
  return {
1050
1050
  ...baseBus,
1051
1051
  emit: (type, payload, source) => {
@@ -1061,22 +1061,31 @@ function useEventBus() {
1061
1061
  emit: (type, payload, source) => {
1062
1062
  if (typeof type === "string" && type.startsWith("UI:")) {
1063
1063
  const tail = type.slice(3);
1064
- const qualified = tail.includes(".") ? type : `UI:${scope.orbital}.${scope.trait}.${tail}`;
1065
- if (qualified !== type) {
1066
- scopeLog.info("emit:qualified", {
1064
+ const isQualified = tail.includes(".");
1065
+ const event = isQualified ? tail.split(".").slice(2).join(".") : tail;
1066
+ if (!event) {
1067
+ baseBus.emit(type, payload, source);
1068
+ return;
1069
+ }
1070
+ const keys = /* @__PURE__ */ new Set();
1071
+ if (isQualified) keys.add(type);
1072
+ for (const sc of chain) {
1073
+ keys.add(`UI:${sc.orbital}.${sc.trait}.${event}`);
1074
+ }
1075
+ if (keys.size > 1) {
1076
+ scopeLog.info("emit:fan-out", {
1067
1077
  from: type,
1068
- to: qualified,
1069
- scopeOrbital: scope.orbital,
1070
- scopeTrait: scope.trait
1078
+ keys: Array.from(keys),
1079
+ chainDepth: chain.length
1071
1080
  });
1072
1081
  }
1073
- baseBus.emit(qualified, payload, source);
1082
+ for (const key of keys) baseBus.emit(key, payload, source);
1074
1083
  return;
1075
1084
  }
1076
1085
  baseBus.emit(type, payload, source);
1077
1086
  }
1078
1087
  };
1079
- }, [baseBus, scope]);
1088
+ }, [baseBus, chain]);
1080
1089
  }
1081
1090
  function useEventListener(event, handler) {
1082
1091
  const eventBus = useEventBus();
@@ -1353,13 +1362,13 @@ var init_Icon = __esm({
1353
1362
  style
1354
1363
  }) => {
1355
1364
  const directIcon = typeof icon === "string" ? void 0 : icon;
1356
- const effectiveName = typeof icon === "string" ? icon : name;
1365
+ const effectiveName = typeof icon === "string" && icon !== "" ? icon : name;
1366
+ const effectiveStrokeWidth = strokeWidth != null && strokeWidth > 0 ? strokeWidth : void 0;
1357
1367
  const family = useIconFamily();
1358
1368
  const RenderedComponent = React73__default.useMemo(() => {
1359
1369
  if (directIcon) return null;
1360
1370
  return effectiveName ? resolveIconForFamily(effectiveName) : null;
1361
1371
  }, [directIcon, effectiveName, family]);
1362
- const effectiveStrokeWidth = strokeWidth ?? void 0;
1363
1372
  const inlineStyle = {
1364
1373
  ...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
1365
1374
  ...style
@@ -1836,7 +1845,7 @@ var init_Input = __esm({
1836
1845
  eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
1837
1846
  }
1838
1847
  };
1839
- const wrapField = (field) => /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
1848
+ const wrapField = (field, fullWidth = true) => /* @__PURE__ */ jsxs("div", { className: fullWidth ? "w-full" : "w-fit", children: [
1840
1849
  label && /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
1841
1850
  field,
1842
1851
  (helperText || error) && /* @__PURE__ */ jsx("p", { className: cn("mt-1 text-xs", error ? "text-error" : "text-muted-foreground"), children: error ?? helperText })
@@ -1896,7 +1905,8 @@ var init_Input = __esm({
1896
1905
  ),
1897
1906
  ...props
1898
1907
  }
1899
- )
1908
+ ),
1909
+ false
1900
1910
  );
1901
1911
  }
1902
1912
  return wrapField(
@@ -4065,6 +4075,7 @@ var init_Overlay = __esm({
4065
4075
  className: cn(
4066
4076
  "fixed inset-0 z-40",
4067
4077
  blur && "backdrop-blur-sm",
4078
+ "animate-overlay-in",
4068
4079
  className
4069
4080
  ),
4070
4081
  style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
@@ -4756,6 +4767,18 @@ var init_RangeSlider = __esm({
4756
4767
  function easeOut(t) {
4757
4768
  return t * (2 - t);
4758
4769
  }
4770
+ function formatDisplay(value, format, decimals) {
4771
+ switch (format) {
4772
+ case "currency":
4773
+ return `$${value.toFixed(2)}`;
4774
+ case "percent":
4775
+ return `${Math.round(value)}%`;
4776
+ case "number":
4777
+ return value.toLocaleString();
4778
+ default:
4779
+ return value.toFixed(decimals);
4780
+ }
4781
+ }
4759
4782
  var AnimatedCounter;
4760
4783
  var init_AnimatedCounter = __esm({
4761
4784
  "components/marketing/atoms/AnimatedCounter.tsx"() {
@@ -4767,6 +4790,7 @@ var init_AnimatedCounter = __esm({
4767
4790
  duration = 600,
4768
4791
  prefix,
4769
4792
  suffix,
4793
+ format,
4770
4794
  className
4771
4795
  }) => {
4772
4796
  const numericRaw = typeof rawValue === "number" ? rawValue : Number.parseFloat(String(rawValue ?? ""));
@@ -4782,6 +4806,10 @@ var init_AnimatedCounter = __esm({
4782
4806
  setDisplayValue(to);
4783
4807
  return;
4784
4808
  }
4809
+ if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
4810
+ setDisplayValue(to);
4811
+ return;
4812
+ }
4785
4813
  const startTime = performance.now();
4786
4814
  const diff = to - from;
4787
4815
  function animate(currentTime) {
@@ -4803,7 +4831,7 @@ var init_AnimatedCounter = __esm({
4803
4831
  };
4804
4832
  }, [value, duration]);
4805
4833
  const decimalPlaces = Number.isInteger(value) ? 0 : String(value).split(".")[1]?.length ?? 0;
4806
- const formattedValue = displayValue.toFixed(decimalPlaces);
4834
+ const formattedValue = formatDisplay(displayValue, format, decimalPlaces);
4807
4835
  return /* @__PURE__ */ jsxs(Typography, { variant: "h3", className: cn("tabular-nums", className), children: [
4808
4836
  prefix,
4809
4837
  formattedValue,
@@ -6016,6 +6044,15 @@ var init_Modal = __esm({
6016
6044
  const [dragY, setDragY] = useState(0);
6017
6045
  const dragStartY = useRef(0);
6018
6046
  const isDragging = useRef(false);
6047
+ const [closing, setClosing] = useState(false);
6048
+ const wasOpenRef = useRef(isOpen);
6049
+ useEffect(() => {
6050
+ if (wasOpenRef.current && !isOpen) setClosing(true);
6051
+ wasOpenRef.current = isOpen;
6052
+ }, [isOpen]);
6053
+ const handleAnimEnd = (e) => {
6054
+ if (closing && e.target === e.currentTarget) setClosing(false);
6055
+ };
6019
6056
  useEffect(() => {
6020
6057
  if (isOpen) {
6021
6058
  previousActiveElement.current = document.activeElement;
@@ -6049,7 +6086,11 @@ var init_Modal = __esm({
6049
6086
  document.body.style.overflow = "";
6050
6087
  };
6051
6088
  }, [isOpen]);
6052
- if (!isOpen || typeof document === "undefined") return null;
6089
+ if (typeof document === "undefined") return null;
6090
+ const renderOpen = isOpen || closing;
6091
+ if (!renderOpen) return null;
6092
+ const dialogAnim = closing ? "animate-modal-out" : "animate-modal-in";
6093
+ const overlayAnim = closing ? "animate-overlay-out" : "animate-overlay-in";
6053
6094
  const handleClose = () => {
6054
6095
  if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
6055
6096
  onClose();
@@ -6066,7 +6107,8 @@ var init_Modal = __esm({
6066
6107
  className: cn(
6067
6108
  "fixed inset-0 z-[1000]",
6068
6109
  "flex items-start justify-center px-4 pb-4 pt-[10vh]",
6069
- "max-sm:items-stretch max-sm:p-0 max-sm:pt-0"
6110
+ "max-sm:items-stretch max-sm:p-0 max-sm:pt-0",
6111
+ overlayAnim
6070
6112
  ),
6071
6113
  style: { backgroundColor: "rgba(0, 0, 0, 0.6)" },
6072
6114
  onClick: handleOverlayClick,
@@ -6094,8 +6136,10 @@ var init_Modal = __esm({
6094
6136
  // full height, no rounded corners, no min-width.
6095
6137
  "max-sm:max-w-none max-sm:max-h-none max-sm:w-full max-sm:h-full max-sm:rounded-none",
6096
6138
  lookStyles2[look],
6097
- className
6139
+ className,
6140
+ dialogAnim
6098
6141
  ),
6142
+ onAnimationEnd: handleAnimEnd,
6099
6143
  style: dragY > 0 ? {
6100
6144
  transform: `translateY(${dragY}px)`,
6101
6145
  transition: isDragging.current ? "none" : "transform 200ms ease-out"
@@ -9732,7 +9776,8 @@ var init_LoadingState = __esm({
9732
9776
  LoadingState = ({
9733
9777
  title,
9734
9778
  message,
9735
- className
9779
+ className,
9780
+ fullPage = false
9736
9781
  }) => {
9737
9782
  const { t } = useTranslate();
9738
9783
  const displayMessage = message ?? t("common.loading");
@@ -9741,7 +9786,8 @@ var init_LoadingState = __esm({
9741
9786
  {
9742
9787
  align: "center",
9743
9788
  className: cn(
9744
- "justify-center py-12",
9789
+ "justify-center",
9790
+ fullPage ? "fixed inset-0 z-[1000] py-12 bg-background/80 backdrop-blur-sm animate-overlay-in" : "py-12",
9745
9791
  className
9746
9792
  ),
9747
9793
  children: [
@@ -12943,7 +12989,7 @@ var init_BookCoverPage = __esm({
12943
12989
  size: "lg",
12944
12990
  action: "BOOK_START",
12945
12991
  className: "mt-8",
12946
- children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: t("book.startReading") })
12992
+ children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "inherit", children: t("book.startReading") })
12947
12993
  }
12948
12994
  )
12949
12995
  ]
@@ -15726,6 +15772,10 @@ function Canvas2D({
15726
15772
  window.removeEventListener("keyup", onUp);
15727
15773
  };
15728
15774
  }, [keyMap, keyUpMap, eventBus]);
15775
+ useEffect(() => {
15776
+ if (!keyMap && !keyUpMap) return;
15777
+ canvasRef.current?.focus();
15778
+ }, [keyMap, keyUpMap]);
15729
15779
  if (error) {
15730
15780
  return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center w-full h-full bg-[var(--color-card)] rounded-container", className), children: /* @__PURE__ */ jsxs(Stack, { direction: "vertical", gap: "md", align: "center", children: [
15731
15781
  /* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: "xl" }),
@@ -15774,7 +15824,7 @@ function Canvas2D({
15774
15824
  onWheel: gestureHandlers.onWheel,
15775
15825
  onContextMenu: (e) => e.preventDefault(),
15776
15826
  className: "cursor-pointer touch-none",
15777
- tabIndex: isFree ? 0 : void 0,
15827
+ tabIndex: isFree || keyMap || keyUpMap ? 0 : void 0,
15778
15828
  style: {
15779
15829
  width: viewportSize.width,
15780
15830
  height: viewportSize.height
@@ -16840,8 +16890,9 @@ var init_Chart = __esm({
16840
16890
  align: "center",
16841
16891
  flex: true,
16842
16892
  className: "min-w-0",
16893
+ style: { height: "100%" },
16843
16894
  children: [
16844
- /* @__PURE__ */ jsx(HStack, { gap: histogram ? "none" : "xs", align: "end", className: "w-full", style: { height: "100%" }, children: series.map((s, sIdx) => {
16895
+ /* @__PURE__ */ jsx(HStack, { gap: histogram ? "none" : "xs", align: "end", justify: histogram ? void 0 : "center", className: "w-full flex-1 min-h-0", children: series.map((s, sIdx) => {
16845
16896
  const value = valueAt(s, label);
16846
16897
  const barHeight = value / maxValue * 100;
16847
16898
  const color = seriesColor(s, sIdx);
@@ -16854,6 +16905,8 @@ var init_Chart = __esm({
16854
16905
  ),
16855
16906
  style: {
16856
16907
  height: `${barHeight}%`,
16908
+ // Cap width so a lone category doesn't paint the whole plot as one solid block; narrow columns are unaffected (flex-1 binds first).
16909
+ ...!histogram && { maxWidth: 72 },
16857
16910
  backgroundColor: color
16858
16911
  },
16859
16912
  onClick: () => onPointClick?.(
@@ -16888,8 +16941,9 @@ var init_Chart = __esm({
16888
16941
  align: "center",
16889
16942
  flex: true,
16890
16943
  className: "min-w-0",
16944
+ style: { height: "100%" },
16891
16945
  children: [
16892
- /* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full", style: { height: "100%" }, justify: "end", children: series.map((s, sIdx) => {
16946
+ /* @__PURE__ */ jsx(VStack, { gap: "none", className: "w-full flex-1 min-h-0", justify: "end", children: series.map((s, sIdx) => {
16893
16947
  const value = valueAt(s, label);
16894
16948
  const ratio = stack === "normalize" ? total === 0 ? 0 : value / total * 100 : value / maxValue * 100;
16895
16949
  const color = seriesColor(s, sIdx);
@@ -16934,6 +16988,7 @@ var init_Chart = __esm({
16934
16988
  const innerRadius = donut ? radius * 0.6 : 0;
16935
16989
  const center = size / 2;
16936
16990
  const segments = useMemo(() => {
16991
+ if (!Number.isFinite(total) || total <= 0) return [];
16937
16992
  let currentAngle = -Math.PI / 2;
16938
16993
  return data.map((point, idx) => {
16939
16994
  const angle = point.value / total * 2 * Math.PI;
@@ -16945,13 +17000,25 @@ var init_Chart = __esm({
16945
17000
  const y1 = center + radius * Math.sin(startAngle);
16946
17001
  const x2 = center + radius * Math.cos(endAngle);
16947
17002
  const y2 = center + radius * Math.sin(endAngle);
17003
+ const fullCircle = angle >= 2 * Math.PI - 1e-9;
17004
+ const midAngle = startAngle + angle / 2;
17005
+ const xm = center + radius * Math.cos(midAngle);
17006
+ const ym = center + radius * Math.sin(midAngle);
16948
17007
  let d;
16949
17008
  if (innerRadius > 0) {
16950
17009
  const ix1 = center + innerRadius * Math.cos(startAngle);
16951
17010
  const iy1 = center + innerRadius * Math.sin(startAngle);
16952
17011
  const ix2 = center + innerRadius * Math.cos(endAngle);
16953
17012
  const iy2 = center + innerRadius * Math.sin(endAngle);
16954
- d = `M ${ix1} ${iy1} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} L ${ix2} ${iy2} A ${innerRadius} ${innerRadius} 0 ${largeArc} 0 ${ix1} ${iy1} Z`;
17013
+ if (fullCircle) {
17014
+ const ixm = center + innerRadius * Math.cos(midAngle);
17015
+ const iym = center + innerRadius * Math.sin(midAngle);
17016
+ d = `M ${ix1} ${iy1} L ${x1} ${y1} A ${radius} ${radius} 0 1 1 ${xm} ${ym} A ${radius} ${radius} 0 1 1 ${x2} ${y2} L ${ix2} ${iy2} A ${innerRadius} ${innerRadius} 0 1 0 ${ixm} ${iym} A ${innerRadius} ${innerRadius} 0 1 0 ${ix1} ${iy1} Z`;
17017
+ } else {
17018
+ d = `M ${ix1} ${iy1} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} L ${ix2} ${iy2} A ${innerRadius} ${innerRadius} 0 ${largeArc} 0 ${ix1} ${iy1} Z`;
17019
+ }
17020
+ } else if (fullCircle) {
17021
+ d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 1 1 ${xm} ${ym} A ${radius} ${radius} 0 1 1 ${x2} ${y2} Z`;
16955
17022
  } else {
16956
17023
  d = `M ${center} ${center} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`;
16957
17024
  }
@@ -20351,10 +20418,10 @@ function DataGrid({
20351
20418
  ] }),
20352
20419
  badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
20353
20420
  const val = getNestedValue(itemData, field.name);
20354
- if (val === void 0 || val === null) return null;
20421
+ if (val === void 0 || val === null || val === "") return null;
20355
20422
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
20356
20423
  field.icon && renderIconInput(field.icon, { size: "xs" }),
20357
- /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: String(val) })
20424
+ /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: formatValue(val, field.format) })
20358
20425
  ] }, field.name);
20359
20426
  }) })
20360
20427
  ] }),
@@ -25745,7 +25812,7 @@ function GameMenu({
25745
25812
  logo,
25746
25813
  className
25747
25814
  }) {
25748
- const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
25815
+ const resolvedOptions = (options?.length ? options : void 0) ?? (menuItems?.length ? menuItems : void 0) ?? DEFAULT_MENU_OPTIONS;
25749
25816
  const eventBus = useEventBus();
25750
25817
  const handleOptionClick = React73.useCallback(
25751
25818
  (option) => {
@@ -31489,6 +31556,11 @@ var init_VoteStack = __esm({
31489
31556
  {
31490
31557
  className: cn(
31491
31558
  "inline-flex items-center justify-center",
31559
+ // Shrink-wrap in stretch contexts (slot/sidecar wrappers are
31560
+ // flex-column with stretch alignment): without this the root spans
31561
+ // the full wrapper width and the count row's `w-full` turns the
31562
+ // compact pill into a page-wide band.
31563
+ "w-fit",
31492
31564
  variant === "vertical" ? "flex-col" : "flex-row",
31493
31565
  "rounded-sm",
31494
31566
  "border-[length:var(--border-width)] border-border",
@@ -35394,7 +35466,7 @@ var init_Sidebar = __esm({
35394
35466
  isActive ? [
35395
35467
  "bg-primary text-primary-foreground",
35396
35468
  "font-medium shadow-sm",
35397
- "border-primary translate-x-1 -translate-y-0.5"
35469
+ "border-primary translate-x-1 rtl:-translate-x-1 -translate-y-0.5"
35398
35470
  ].join(" ") : [
35399
35471
  "text-foreground",
35400
35472
  "hover:bg-muted hover:border-border",
@@ -35404,10 +35476,10 @@ var init_Sidebar = __esm({
35404
35476
  title: collapsed ? item.label : void 0,
35405
35477
  children: [
35406
35478
  item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm", className: cn("min-w-[20px] flex-shrink-0", isActive && "text-primary-foreground") }) : /* @__PURE__ */ jsx(Icon, { icon: item.icon, size: "sm", className: cn("min-w-[20px] flex-shrink-0", isActive && "text-primary-foreground") })),
35407
- !collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-left", children: item.label }),
35479
+ !collapsed && /* @__PURE__ */ jsx(Typography, { variant: "body", color: isActive ? "inherit" : "primary", className: "font-medium truncate flex-1 text-start", children: item.label }),
35408
35480
  !collapsed && item.badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "danger", size: "sm", children: item.badge }),
35409
35481
  collapsed && /* @__PURE__ */ jsx(Box, { className: cn(
35410
- "absolute left-full ml-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
35482
+ "absolute start-full ms-2 px-2 py-1 text-xs opacity-0 group-hover:opacity-100",
35411
35483
  "pointer-events-none whitespace-nowrap z-50 transition-opacity",
35412
35484
  "bg-primary text-primary-foreground",
35413
35485
  "border-[length:var(--border-width-thin)] border-border",
@@ -35462,7 +35534,7 @@ var init_Sidebar = __esm({
35462
35534
  as: "aside",
35463
35535
  className: cn(
35464
35536
  "flex flex-col h-full",
35465
- "bg-card border-r border-border",
35537
+ "bg-card border-e border-border",
35466
35538
  "transition-all duration-300 ease-in-out",
35467
35539
  collapsed ? "w-20" : "w-64",
35468
35540
  className
@@ -36623,7 +36695,7 @@ function resolveColor3(color, el) {
36623
36695
  function truncateLabel(label) {
36624
36696
  return label.length > MAX_LABEL_CHARS ? label.slice(0, MAX_LABEL_CHARS - 1) + "\u2026" : label;
36625
36697
  }
36626
- var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, GraphCanvas;
36698
+ var GROUP_COLORS2, GROUP_GRAVITY, UNGROUPED_GRAVITY, labelMeasureCtx, MAX_LABEL_CHARS, NO_NODES, NO_EDGES, NO_SIM, GraphCanvas;
36627
36699
  var init_GraphCanvas = __esm({
36628
36700
  "components/core/molecules/GraphCanvas.tsx"() {
36629
36701
  "use client";
@@ -36647,11 +36719,14 @@ var init_GraphCanvas = __esm({
36647
36719
  UNGROUPED_GRAVITY = 0.02;
36648
36720
  labelMeasureCtx = null;
36649
36721
  MAX_LABEL_CHARS = 22;
36722
+ NO_NODES = [];
36723
+ NO_EDGES = [];
36724
+ NO_SIM = [];
36650
36725
  GraphCanvas = ({
36651
36726
  title,
36652
- nodes: propNodes = [],
36653
- edges: propEdges = [],
36654
- similarity: propSimilarity = [],
36727
+ nodes: propNodes = NO_NODES,
36728
+ edges: propEdges = NO_EDGES,
36729
+ similarity: propSimilarity = NO_SIM,
36655
36730
  height = 400,
36656
36731
  showLabels = true,
36657
36732
  interactive = true,
@@ -36701,6 +36776,7 @@ var init_GraphCanvas = __esm({
36701
36776
  const interactionRef = useRef({
36702
36777
  mode: "none",
36703
36778
  dragNodeId: null,
36779
+ pressedNodeId: null,
36704
36780
  startMouse: { x: 0, y: 0 },
36705
36781
  startOffset: { x: 0, y: 0 },
36706
36782
  downPos: { x: 0, y: 0 }
@@ -36748,6 +36824,11 @@ var init_GraphCanvas = __esm({
36748
36824
  () => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
36749
36825
  [propNodes]
36750
36826
  );
36827
+ const nodesKey = useMemo(() => propNodes.map((n) => n.id).join(""), [propNodes]);
36828
+ const edgesKey = useMemo(
36829
+ () => propEdges.map((e) => `${e.source}${e.target}`).join(""),
36830
+ [propEdges]
36831
+ );
36751
36832
  useEffect(() => {
36752
36833
  const canvas = canvasRef.current;
36753
36834
  if (!canvas || propNodes.length === 0) return;
@@ -36928,7 +37009,7 @@ var init_GraphCanvas = __esm({
36928
37009
  return () => {
36929
37010
  cancelAnimationFrame(animRef.current);
36930
37011
  };
36931
- }, [propNodes, propEdges, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
37012
+ }, [nodesKey, edgesKey, propSimilarity, layout, repulsion, linkDistance, nodeSpacing, showLabels]);
36932
37013
  useEffect(() => {
36933
37014
  const canvas = canvasRef.current;
36934
37015
  if (!canvas) return;
@@ -37058,6 +37139,7 @@ var init_GraphCanvas = __esm({
37058
37139
  const cancelSinglePointer = useCallback(() => {
37059
37140
  interactionRef.current.mode = "none";
37060
37141
  interactionRef.current.dragNodeId = null;
37142
+ interactionRef.current.pressedNodeId = null;
37061
37143
  }, []);
37062
37144
  const handlePointerDown = useCallback(
37063
37145
  (e) => {
@@ -37068,6 +37150,7 @@ var init_GraphCanvas = __esm({
37068
37150
  state.downPos = { x: e.clientX, y: e.clientY };
37069
37151
  state.startMouse = { x: e.clientX, y: e.clientY };
37070
37152
  state.startOffset = { ...offset };
37153
+ state.pressedNodeId = node?.id ?? null;
37071
37154
  if (draggable && node) {
37072
37155
  state.mode = "dragging";
37073
37156
  state.dragNodeId = node.id;
@@ -37119,7 +37202,8 @@ var init_GraphCanvas = __esm({
37119
37202
  if (moved < 4) {
37120
37203
  const coords = toCoords(e);
37121
37204
  if (!coords) return;
37122
- const node = nodeAt(coords.graphX, coords.graphY);
37205
+ const node = (state.pressedNodeId ? nodesRef.current.find((n) => n.id === state.pressedNodeId) : void 0) ?? nodeAt(coords.graphX, coords.graphY);
37206
+ state.pressedNodeId = null;
37123
37207
  if (node) {
37124
37208
  if (node.badge && node.badge > 1 && onBadgeClick) {
37125
37209
  const r = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
@@ -37139,6 +37223,7 @@ var init_GraphCanvas = __esm({
37139
37223
  );
37140
37224
  const handlePointerLeave = useCallback(() => {
37141
37225
  setHoveredNode(null);
37226
+ interactionRef.current.pressedNodeId = null;
37142
37227
  }, []);
37143
37228
  const gestureHandlers = useCanvasGestures({
37144
37229
  canvasRef,
@@ -40307,8 +40392,17 @@ var init_MediaGallery = __esm({
40307
40392
  const eventBus = useEventBus();
40308
40393
  const { t } = useTranslate();
40309
40394
  const [lightboxItem, setLightboxItem] = useState(null);
40395
+ const [failedIds, setFailedIds] = useState(/* @__PURE__ */ new Set());
40310
40396
  const closeLightbox = useCallback(() => setLightboxItem(null), []);
40311
40397
  useEventListener("UI:LIGHTBOX_CLOSE", closeLightbox);
40398
+ const handleImageError = useCallback((id) => {
40399
+ setFailedIds((prev) => {
40400
+ if (prev.has(id)) return prev;
40401
+ const next = new Set(prev);
40402
+ next.add(id);
40403
+ return next;
40404
+ });
40405
+ }, []);
40312
40406
  const handleItemClick = useCallback(
40313
40407
  (item) => {
40314
40408
  if (selectable) {
@@ -40324,7 +40418,7 @@ var init_MediaGallery = __esm({
40324
40418
  );
40325
40419
  const entityData = Array.isArray(entity) ? entity : [];
40326
40420
  const items = React73__default.useMemo(() => {
40327
- if (propItems) return propItems;
40421
+ if (propItems && propItems.length > 0) return propItems;
40328
40422
  if (entityData.length === 0) return [];
40329
40423
  return entityData.map((record, idx) => {
40330
40424
  return {
@@ -40407,13 +40501,14 @@ var init_MediaGallery = __esm({
40407
40501
  ),
40408
40502
  onClick: () => handleItemClick(item),
40409
40503
  children: [
40410
- /* @__PURE__ */ jsx(
40504
+ failedIds.has(item.id) ? /* @__PURE__ */ jsx(Box, { className: "w-full h-full flex items-center justify-center bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx(Icon, { icon: Image$1, size: "lg" }) }) : /* @__PURE__ */ jsx(
40411
40505
  "img",
40412
40506
  {
40413
40507
  src: item.thumbnail || item.src,
40414
40508
  alt: item.alt || item.caption || "",
40415
40509
  className: "w-full h-full object-cover",
40416
- loading: "lazy"
40510
+ loading: "lazy",
40511
+ onError: () => handleImageError(item.id)
40417
40512
  }
40418
40513
  ),
40419
40514
  /* @__PURE__ */ jsx(
@@ -43901,6 +43996,11 @@ var init_TeamOrganism = __esm({
43901
43996
  TeamOrganism.displayName = "TeamOrganism";
43902
43997
  }
43903
43998
  });
43999
+ function formatDate4(value) {
44000
+ const d = new Date(value);
44001
+ if (isNaN(d.getTime())) return value;
44002
+ return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
44003
+ }
43904
44004
  var lookStyles10, STATUS_STYLES2, Timeline;
43905
44005
  var init_Timeline = __esm({
43906
44006
  "components/core/organisms/Timeline.tsx"() {
@@ -44028,7 +44128,7 @@ var init_Timeline = __esm({
44028
44128
  /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("flex-1 min-w-0", !isLast && "pb-6"), children: [
44029
44129
  /* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", wrap: true, children: [
44030
44130
  /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "semibold", children: item.title }),
44031
- item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: item.date })
44131
+ item.date && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "flex-shrink-0", children: formatDate4(item.date) })
44032
44132
  ] }),
44033
44133
  item.description && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
44034
44134
  item.tags && item.tags.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, children: item.tags.map((tag, tagIdx) => /* @__PURE__ */ jsx(Badge, { variant: "default", children: tag }, tagIdx)) }),
@@ -45240,7 +45340,7 @@ function substituteTraitRefsDeep(value, pathKey) {
45240
45340
  }
45241
45341
  return value;
45242
45342
  }
45243
- function renderPatternProps(props, onDismiss) {
45343
+ function renderPatternProps(props, onDismiss, propsSchema) {
45244
45344
  const rendered = {};
45245
45345
  for (const [key, value] of Object.entries(props)) {
45246
45346
  if (key === "children") {
@@ -45258,9 +45358,10 @@ function renderPatternProps(props, onDismiss) {
45258
45358
  };
45259
45359
  rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
45260
45360
  } else if (Array.isArray(value)) {
45361
+ const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
45261
45362
  rendered[key] = value.map((item, i) => {
45262
45363
  const el = item;
45263
- if (isPatternConfig(el)) {
45364
+ if (!isDataArray && isPatternConfig(el)) {
45264
45365
  const nestedProps = {};
45265
45366
  for (const [k, v] of Object.entries(el)) {
45266
45367
  if (k !== "type") nestedProps[k] = v;
@@ -45348,14 +45449,15 @@ function SlotContentRenderer({
45348
45449
  );
45349
45450
  }
45350
45451
  }
45351
- const renderedProps = renderPatternProps(restProps, onDismiss);
45352
45452
  const patternDef = getPatternDefinition$1(content.pattern);
45353
45453
  const propsSchema = patternDef?.propsSchema;
45454
+ const renderedProps = renderPatternProps(restProps, onDismiss, propsSchema);
45354
45455
  if (propsSchema) {
45355
45456
  for (const [propKey, propValue] of Object.entries(renderedProps)) {
45356
45457
  if (typeof propValue !== "string") continue;
45357
45458
  const propDef = propsSchema[propKey];
45358
45459
  if (!propDef || propDef.kind !== "callback") continue;
45460
+ if (propValue === "") continue;
45359
45461
  renderedProps[propKey] = wrapCallbackForEvent(
45360
45462
  `UI:${propValue}`,
45361
45463
  propDef.callbackArgs,
@@ -47144,6 +47246,16 @@ function useSharedEntityStore() {
47144
47246
  }
47145
47247
  return storeRef.current;
47146
47248
  }
47249
+ var SharedEntityStoreContext = createContext(null);
47250
+ function useSharedEntityStoreContext() {
47251
+ const store = useContext(SharedEntityStoreContext);
47252
+ if (!store) {
47253
+ throw new Error(
47254
+ "useSharedEntityStoreContext: no SharedEntityStoreContext.Provider found in the component tree"
47255
+ );
47256
+ }
47257
+ return store;
47258
+ }
47147
47259
  function useSharedEntitySnapshot(store, entityId) {
47148
47260
  return useSyncExternalStore(
47149
47261
  (onStoreChange) => store.subscribe(entityId, onStoreChange),
@@ -48023,4 +48135,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
48023
48135
  });
48024
48136
  }
48025
48137
 
48026
- export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AtlasImage, AtlasPanel, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioToggle, GameHud, GameIcon, GameMenu, GameShell, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, Modal, ModalSlot, ModuleCard, Navigation, NodeSlotEditor, NotifyListener, NumberStepper, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, RichBlockEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateGraph, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VersionDiff, ViolationAlert, VoteStack, WizardContainer, WizardNavigation, WizardProgress, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createSharedEntityStore, createTranslate, createUnitAnimationState, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, runTickFrame, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAtlasSliceDataUrl, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSwipeGesture, useTapReveal, useTraitListens, useTranslate115 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
48138
+ export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AtlasImage, AtlasPanel, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioToggle, GameHud, GameIcon, GameMenu, GameShell, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, Modal, ModalSlot, ModuleCard, Navigation, NodeSlotEditor, NotifyListener, NumberStepper, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, RichBlockEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, ServiceCatalog, SharedEntityStoreContext, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateGraph, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VersionDiff, ViolationAlert, VoteStack, WizardContainer, WizardNavigation, WizardProgress, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createSharedEntityStore, createTranslate, createUnitAnimationState, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, runTickFrame, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAtlasSliceDataUrl, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSharedEntityStoreContext, useSwipeGesture, useTapReveal, useTraitListens, useTranslate115 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };