@almadar/ui 5.59.0 → 5.61.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.
@@ -8379,16 +8379,6 @@ var init_Skeleton = __esm({
8379
8379
  Skeleton.displayName = "Skeleton";
8380
8380
  }
8381
8381
  });
8382
- function isKnownPattern(type) {
8383
- return type in componentMapping;
8384
- }
8385
- var componentMapping;
8386
- var init_pattern_resolver = __esm({
8387
- "renderer/pattern-resolver.ts"() {
8388
- createLogger("almadar:ui:pattern-resolver");
8389
- componentMapping = {};
8390
- }
8391
- });
8392
8382
  function executeClientEffects(effects, config) {
8393
8383
  if (!effects || effects.length === 0) {
8394
8384
  return;
@@ -8397,7 +8387,7 @@ function executeClientEffects(effects, config) {
8397
8387
  try {
8398
8388
  executeEffect(effect, config);
8399
8389
  } catch (error) {
8400
- log4.error("Error executing effect", () => ({
8390
+ log3.error("Error executing effect", () => ({
8401
8391
  effect: JSON.stringify(effect),
8402
8392
  error: error instanceof Error ? error : String(error)
8403
8393
  }));
@@ -8429,7 +8419,7 @@ function executeEffect(effect, config) {
8429
8419
  break;
8430
8420
  }
8431
8421
  default:
8432
- log4.warn("Unknown effect type", { effectType: String(effectType) });
8422
+ log3.warn("Unknown effect type", { effectType: String(effectType) });
8433
8423
  }
8434
8424
  }
8435
8425
  function executeRenderUI(slot, patternConfig, config) {
@@ -8444,10 +8434,10 @@ function executeNotify(message, options, config) {
8444
8434
  function executeEmit(event, payload, config) {
8445
8435
  config.eventBus.emit(event, payload);
8446
8436
  }
8447
- var log4;
8437
+ var log3;
8448
8438
  var init_client_effect_executor = __esm({
8449
8439
  "renderer/client-effect-executor.ts"() {
8450
- log4 = createLogger("almadar:ui:effects:client");
8440
+ log3 = createLogger("almadar:ui:effects:client");
8451
8441
  }
8452
8442
  });
8453
8443
 
@@ -8608,12 +8598,12 @@ function useOfflineExecutor(options) {
8608
8598
  clearQueue
8609
8599
  };
8610
8600
  }
8611
- var log5, effectIdCounter, OfflineExecutor;
8601
+ var log4, effectIdCounter, OfflineExecutor;
8612
8602
  var init_offline_executor = __esm({
8613
8603
  "renderer/offline-executor.ts"() {
8614
8604
  "use client";
8615
8605
  init_client_effect_executor();
8616
- log5 = createLogger("almadar:ui:effects:offline");
8606
+ log4 = createLogger("almadar:ui:effects:offline");
8617
8607
  effectIdCounter = 0;
8618
8608
  OfflineExecutor = class {
8619
8609
  constructor(config) {
@@ -8667,7 +8657,7 @@ var init_offline_executor = __esm({
8667
8657
  this.state.syncQueue = JSON.parse(stored);
8668
8658
  }
8669
8659
  } catch (error) {
8670
- log5.warn("Failed to load sync queue", { error: error instanceof Error ? error : String(error) });
8660
+ log4.warn("Failed to load sync queue", { error: error instanceof Error ? error : String(error) });
8671
8661
  }
8672
8662
  }
8673
8663
  /**
@@ -8678,7 +8668,7 @@ var init_offline_executor = __esm({
8678
8668
  try {
8679
8669
  this.storage.setItem("orbital-offline-queue", JSON.stringify(this.state.syncQueue));
8680
8670
  } catch (error) {
8681
- log5.warn("Failed to save sync queue", { error: error instanceof Error ? error : String(error) });
8671
+ log4.warn("Failed to save sync queue", { error: error instanceof Error ? error : String(error) });
8682
8672
  }
8683
8673
  }
8684
8674
  /**
@@ -8748,7 +8738,7 @@ var init_offline_executor = __esm({
8748
8738
  this.queueForSync(type, { args, event, payload });
8749
8739
  break;
8750
8740
  default:
8751
- log5.warn("Unknown effect type", { type });
8741
+ log4.warn("Unknown effect type", { type });
8752
8742
  }
8753
8743
  }
8754
8744
  }
@@ -8853,7 +8843,6 @@ var init_offline_executor = __esm({
8853
8843
  // renderer/index.ts
8854
8844
  var init_renderer = __esm({
8855
8845
  "renderer/index.ts"() {
8856
- init_pattern_resolver();
8857
8846
  init_slot_definitions();
8858
8847
  }
8859
8848
  });
@@ -10557,7 +10546,7 @@ function recordTransition(trace) {
10557
10546
  ...trace,
10558
10547
  id: `t-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
10559
10548
  };
10560
- log6.debug("transition:recorded", { trait: trace.traitName, from: trace.from, to: trace.to, event: trace.event, effectCount: trace.effects.length });
10549
+ log5.debug("transition:recorded", { trait: trace.traitName, from: trace.from, to: trace.to, event: trace.event, effectCount: trace.effects.length });
10561
10550
  getState().transitions.push(entry);
10562
10551
  if (getState().transitions.length > MAX_TRANSITIONS) {
10563
10552
  getState().transitions.shift();
@@ -10626,7 +10615,7 @@ function getTraitSnapshots() {
10626
10615
  try {
10627
10616
  snapshots.push(getter());
10628
10617
  } catch (err) {
10629
- log6.error("traitSnapshot getter failed", { trait: traitName, err: String(err) });
10618
+ log5.error("traitSnapshot getter failed", { trait: traitName, err: String(err) });
10630
10619
  }
10631
10620
  }
10632
10621
  return snapshots;
@@ -10689,12 +10678,12 @@ function waitForTransition(event, timeoutMs = 1e4) {
10689
10678
  }
10690
10679
  function bindEventBus(eventBus) {
10691
10680
  if (typeof window === "undefined") return;
10692
- log6.info("bindEventBus", { hasOnAny: !!eventBus.onAny });
10681
+ log5.info("bindEventBus", { hasOnAny: !!eventBus.onAny });
10693
10682
  exposeOnWindow();
10694
10683
  if (window.__orbitalVerification) {
10695
10684
  window.__orbitalVerification.sendEvent = (event, payload, traitScope) => {
10696
10685
  const prefixed = event.startsWith("UI:") ? event : traitScope ? `UI:${traitScope}.${event}` : `UI:${event}`;
10697
- log6.debug("sendEvent", { event: prefixed, traitScope, payloadKeys: payload ? Object.keys(payload) : [] });
10686
+ log5.debug("sendEvent", { event: prefixed, traitScope, payloadKeys: payload ? Object.keys(payload) : [] });
10698
10687
  eventBus.emit(prefixed, payload);
10699
10688
  };
10700
10689
  const eventLog = [];
@@ -10743,10 +10732,10 @@ function updateAssetStatus(url, status) {
10743
10732
  window.__orbitalVerification.assetStatus[url] = status;
10744
10733
  }
10745
10734
  }
10746
- var log6, MAX_TRANSITIONS;
10735
+ var log5, MAX_TRANSITIONS;
10747
10736
  var init_verificationRegistry = __esm({
10748
10737
  "lib/verificationRegistry.ts"() {
10749
- log6 = createLogger("almadar:bridge");
10738
+ log5 = createLogger("almadar:bridge");
10750
10739
  MAX_TRANSITIONS = 500;
10751
10740
  exposeOnWindow();
10752
10741
  }
@@ -13075,7 +13064,7 @@ var init_avl_elk_layout = __esm({
13075
13064
  elk = new ELK();
13076
13065
  }
13077
13066
  });
13078
- var log7, SWIM_GUTTER, CENTER_W, BehaviorView;
13067
+ var log6, SWIM_GUTTER, CENTER_W, BehaviorView;
13079
13068
  var init_BehaviorView = __esm({
13080
13069
  "components/avl/molecules/BehaviorView.tsx"() {
13081
13070
  "use client";
@@ -13084,7 +13073,7 @@ var init_BehaviorView = __esm({
13084
13073
  init_AvlSwimLane();
13085
13074
  init_types();
13086
13075
  init_avl_elk_layout();
13087
- log7 = createLogger("almadar:ui:avl:behavior-view");
13076
+ log6 = createLogger("almadar:ui:avl:behavior-view");
13088
13077
  SWIM_GUTTER = 120;
13089
13078
  CENTER_W = 360;
13090
13079
  BehaviorView = ({ data }) => {
@@ -13095,7 +13084,7 @@ var init_BehaviorView = __esm({
13095
13084
  const dataKey = useMemo(() => JSON.stringify(traitData), [traitData]);
13096
13085
  useEffect(() => {
13097
13086
  if (!traitData) return;
13098
- computeTraitLayout(traitData).then(setLayout).catch((err) => log7.error("compute-trait-layout-failed", { error: err instanceof Error ? err : String(err) }));
13087
+ computeTraitLayout(traitData).then(setLayout).catch((err) => log6.error("compute-trait-layout-failed", { error: err instanceof Error ? err : String(err) }));
13099
13088
  }, [dataKey]);
13100
13089
  if (!traitData) {
13101
13090
  return /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] p-4 text-center text-[var(--color-muted-foreground)] text-sm", children: t("avl.noTraitData") });
@@ -13506,7 +13495,7 @@ function generateDiff(oldVal, newVal) {
13506
13495
  }
13507
13496
  return diff;
13508
13497
  }
13509
- var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log8, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
13498
+ var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log7, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
13510
13499
  var init_CodeBlock = __esm({
13511
13500
  "components/core/molecules/markdown/CodeBlock.tsx"() {
13512
13501
  init_cn();
@@ -13589,7 +13578,7 @@ var init_CodeBlock = __esm({
13589
13578
  "lolo-op-async": { color: ORB_COLORS.dark.async }
13590
13579
  };
13591
13580
  loloStyle = { ...dark, ...loloStyleOverrides };
13592
- log8 = createLogger("almadar:ui:markdown-code");
13581
+ log7 = createLogger("almadar:ui:markdown-code");
13593
13582
  CODE_LANGUAGES = [
13594
13583
  "text",
13595
13584
  "json",
@@ -13853,7 +13842,7 @@ var init_CodeBlock = __esm({
13853
13842
  eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: true });
13854
13843
  setTimeout(() => setCopied(false), 2e3);
13855
13844
  } catch (err) {
13856
- log8.error("Failed to copy code", { error: err instanceof Error ? err : String(err) });
13845
+ log7.error("Failed to copy code", { error: err instanceof Error ? err : String(err) });
13857
13846
  eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: false });
13858
13847
  }
13859
13848
  };
@@ -17734,14 +17723,14 @@ function useSafeEventBus2() {
17734
17723
  } };
17735
17724
  }
17736
17725
  }
17737
- var log9, lookStyles4, ButtonGroup;
17726
+ var log8, lookStyles4, ButtonGroup;
17738
17727
  var init_ButtonGroup = __esm({
17739
17728
  "components/core/molecules/ButtonGroup.tsx"() {
17740
17729
  "use client";
17741
17730
  init_cn();
17742
17731
  init_atoms2();
17743
17732
  init_useEventBus();
17744
- log9 = createLogger("almadar:ui:button-group");
17733
+ log8 = createLogger("almadar:ui:button-group");
17745
17734
  lookStyles4 = {
17746
17735
  "right-aligned-buttons": "",
17747
17736
  "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
@@ -17822,7 +17811,7 @@ var init_ButtonGroup = __esm({
17822
17811
  {
17823
17812
  variant: "ghost",
17824
17813
  onClick: () => {
17825
- log9.debug("Filter clicked", { field: filter.field });
17814
+ log8.debug("Filter clicked", { field: filter.field });
17826
17815
  },
17827
17816
  children: filter.label
17828
17817
  },
@@ -25484,9 +25473,9 @@ function debug(...args) {
25484
25473
  const [first, ...rest] = args;
25485
25474
  const message = typeof first === "string" ? first : "<debug>";
25486
25475
  if (rest.length === 0 && typeof first === "string") {
25487
- log10.debug(message);
25476
+ log9.debug(message);
25488
25477
  } else {
25489
- log10.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
25478
+ log9.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
25490
25479
  }
25491
25480
  }
25492
25481
  function debugGroup(label) {
@@ -25514,11 +25503,11 @@ function toLogMetaValue(v) {
25514
25503
  }
25515
25504
  return String(v);
25516
25505
  }
25517
- var NAMESPACE, log10;
25506
+ var NAMESPACE, log9;
25518
25507
  var init_debug = __esm({
25519
25508
  "lib/debug.ts"() {
25520
25509
  NAMESPACE = "almadar:ui:debug";
25521
- log10 = createLogger(NAMESPACE);
25510
+ log9 = createLogger(NAMESPACE);
25522
25511
  createLogger("almadar:ui:debug:input");
25523
25512
  createLogger("almadar:ui:debug:collision");
25524
25513
  createLogger("almadar:ui:debug:physics");
@@ -37923,6 +37912,12 @@ function getGroupColor(group, groups) {
37923
37912
  const idx = groups.indexOf(group);
37924
37913
  return GROUP_COLORS2[idx % GROUP_COLORS2.length];
37925
37914
  }
37915
+ function resolveColor2(color, el) {
37916
+ const m = /^var\((--[^,)]+)(?:,\s*([^)]+))?\)$/.exec(color.trim());
37917
+ if (!m) return color;
37918
+ const resolved = getComputedStyle(el).getPropertyValue(m[1]).trim();
37919
+ return resolved || (m[2]?.trim() ?? "#888888");
37920
+ }
37926
37921
  var GROUP_COLORS2, GraphCanvas;
37927
37922
  var init_GraphCanvas = __esm({
37928
37923
  "components/core/molecules/GraphCanvas.tsx"() {
@@ -37952,6 +37947,7 @@ var init_GraphCanvas = __esm({
37952
37947
  draggable = true,
37953
37948
  actions,
37954
37949
  onNodeClick,
37950
+ onNodeDoubleClick,
37955
37951
  nodeClickEvent,
37956
37952
  selectedNodeId,
37957
37953
  repulsion = 800,
@@ -37971,6 +37967,19 @@ var init_GraphCanvas = __esm({
37971
37967
  const [hoveredNode, setHoveredNode] = useState(null);
37972
37968
  const nodesRef = useRef([]);
37973
37969
  const [, forceUpdate] = useState(0);
37970
+ const [logicalW, setLogicalW] = useState(800);
37971
+ useEffect(() => {
37972
+ const canvas = canvasRef.current;
37973
+ if (!canvas || typeof ResizeObserver === "undefined") return;
37974
+ const measure = () => {
37975
+ const width = Math.round(canvas.clientWidth);
37976
+ if (width > 0) setLogicalW(width);
37977
+ };
37978
+ measure();
37979
+ const ro = new ResizeObserver(measure);
37980
+ ro.observe(canvas);
37981
+ return () => ro.disconnect();
37982
+ }, []);
37974
37983
  const interactionRef = useRef({
37975
37984
  mode: "none",
37976
37985
  dragNodeId: null,
@@ -38024,8 +38033,8 @@ var init_GraphCanvas = __esm({
38024
38033
  useEffect(() => {
38025
38034
  const canvas = canvasRef.current;
38026
38035
  if (!canvas || propNodes.length === 0) return;
38027
- const w = canvas.width;
38028
- const h = canvas.height;
38036
+ const w = logicalW;
38037
+ const h = height;
38029
38038
  const simNodes = propNodes.map((n, idx) => {
38030
38039
  let x = n.x ?? 0;
38031
38040
  let y = n.y ?? 0;
@@ -38115,28 +38124,41 @@ var init_GraphCanvas = __esm({
38115
38124
  return () => {
38116
38125
  cancelAnimationFrame(animRef.current);
38117
38126
  };
38118
- }, [propNodes, propEdges, layout, repulsion, linkDistance]);
38127
+ }, [propNodes, propEdges, layout, repulsion, linkDistance, logicalW, height]);
38119
38128
  useEffect(() => {
38120
38129
  const canvas = canvasRef.current;
38121
38130
  if (!canvas) return;
38122
38131
  const ctx = canvas.getContext("2d");
38123
38132
  if (!ctx) return;
38124
- const w = canvas.width;
38125
- const h = canvas.height;
38133
+ const w = logicalW;
38134
+ const h = height;
38126
38135
  const nodes = nodesRef.current;
38136
+ const accentColor = resolveColor2("var(--color-accent)", canvas);
38137
+ const dpr = typeof window !== "undefined" && window.devicePixelRatio || 1;
38138
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
38127
38139
  ctx.clearRect(0, 0, w, h);
38128
38140
  ctx.save();
38129
38141
  ctx.translate(offset.x, offset.y);
38130
38142
  ctx.scale(zoom, zoom);
38143
+ const neighbors = /* @__PURE__ */ new Set();
38144
+ if (hoveredNode) {
38145
+ neighbors.add(hoveredNode);
38146
+ for (const edge of propEdges) {
38147
+ if (edge.source === hoveredNode) neighbors.add(String(edge.target));
38148
+ else if (edge.target === hoveredNode) neighbors.add(String(edge.source));
38149
+ }
38150
+ }
38131
38151
  for (const edge of propEdges) {
38132
38152
  const source = nodes.find((n) => n.id === edge.source);
38133
38153
  const target = nodes.find((n) => n.id === edge.target);
38134
38154
  if (!source || !target) continue;
38155
+ const incident = !!hoveredNode && (edge.source === hoveredNode || edge.target === hoveredNode);
38156
+ ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.12 : 1;
38135
38157
  ctx.beginPath();
38136
38158
  ctx.moveTo(source.x, source.y);
38137
38159
  ctx.lineTo(target.x, target.y);
38138
- ctx.strokeStyle = edge.color || "#88888866";
38139
- ctx.lineWidth = edge.weight ? Math.max(1, edge.weight) : 1;
38160
+ ctx.strokeStyle = incident ? accentColor : edge.color || "#88888866";
38161
+ ctx.lineWidth = incident ? 2 : edge.weight ? Math.max(1, edge.weight) : 1;
38140
38162
  ctx.stroke();
38141
38163
  if (edge.label && showLabels) {
38142
38164
  const mx = (source.x + target.x) / 2;
@@ -38147,18 +38169,20 @@ var init_GraphCanvas = __esm({
38147
38169
  ctx.fillText(edge.label, mx, my - 4);
38148
38170
  }
38149
38171
  }
38172
+ ctx.globalAlpha = 1;
38150
38173
  for (const node of nodes) {
38151
38174
  const size = node.size || 8;
38152
- const color = node.color || getGroupColor(node.group, groups);
38175
+ const color = resolveColor2(node.color || getGroupColor(node.group, groups), canvas);
38153
38176
  const isHovered = hoveredNode === node.id;
38154
38177
  const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
38178
+ ctx.globalAlpha = hoveredNode && !neighbors.has(node.id) ? 0.2 : 1;
38155
38179
  const radius = isSelected ? size + 4 : isHovered ? size + 2 : size;
38156
38180
  ctx.beginPath();
38157
38181
  ctx.arc(node.x, node.y, radius, 0, Math.PI * 2);
38158
38182
  ctx.fillStyle = color;
38159
38183
  ctx.fill();
38160
38184
  if (isSelected) {
38161
- ctx.strokeStyle = "var(--color-accent)";
38185
+ ctx.strokeStyle = accentColor;
38162
38186
  ctx.lineWidth = 3;
38163
38187
  } else {
38164
38188
  ctx.strokeStyle = isHovered ? "#ffffff" : "#00000020";
@@ -38271,6 +38295,15 @@ var init_GraphCanvas = __esm({
38271
38295
  interactionRef.current.dragNodeId = null;
38272
38296
  setHoveredNode(null);
38273
38297
  }, []);
38298
+ const handleDoubleClick = useCallback(
38299
+ (e) => {
38300
+ const coords = toCoords(e);
38301
+ if (!coords) return;
38302
+ const node = nodeAt(coords.graphX, coords.graphY);
38303
+ if (node) onNodeDoubleClick?.(node);
38304
+ },
38305
+ [toCoords, nodeAt, onNodeDoubleClick]
38306
+ );
38274
38307
  if (isLoading) {
38275
38308
  return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
38276
38309
  }
@@ -38328,15 +38361,16 @@ var init_GraphCanvas = __esm({
38328
38361
  "canvas",
38329
38362
  {
38330
38363
  ref: canvasRef,
38331
- width: 800,
38332
- height,
38364
+ width: Math.round(logicalW * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
38365
+ height: Math.round(height * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
38333
38366
  className: "w-full cursor-grab active:cursor-grabbing",
38334
38367
  style: { height },
38335
38368
  onWheel: handleWheel,
38336
38369
  onMouseDown: handleMouseDown,
38337
38370
  onMouseMove: handleMouseMove,
38338
38371
  onMouseUp: handleMouseUp,
38339
- onMouseLeave: handleMouseLeave
38372
+ onMouseLeave: handleMouseLeave,
38373
+ onDoubleClick: handleDoubleClick
38340
38374
  }
38341
38375
  ) }),
38342
38376
  groups.length > 1 && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "px-4 py-2 border-t border-border", wrap: true, children: groups.map((group, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
@@ -41930,11 +41964,11 @@ var init_Canvas3DErrorBoundary = __esm({
41930
41964
  "components/game/molecules/three/components/Canvas3DErrorBoundary.css"() {
41931
41965
  }
41932
41966
  });
41933
- var log11, Canvas3DErrorBoundary;
41967
+ var log10, Canvas3DErrorBoundary;
41934
41968
  var init_Canvas3DErrorBoundary2 = __esm({
41935
41969
  "components/game/molecules/three/components/Canvas3DErrorBoundary.tsx"() {
41936
41970
  init_Canvas3DErrorBoundary();
41937
- log11 = createLogger("almadar:ui:game:canvas3d:error-boundary");
41971
+ log10 = createLogger("almadar:ui:game:canvas3d:error-boundary");
41938
41972
  Canvas3DErrorBoundary = class extends Component {
41939
41973
  constructor(props) {
41940
41974
  super(props);
@@ -41962,8 +41996,8 @@ var init_Canvas3DErrorBoundary2 = __esm({
41962
41996
  componentDidCatch(error, errorInfo) {
41963
41997
  this.setState({ errorInfo });
41964
41998
  this.props.onError?.(error, errorInfo);
41965
- log11.error("Error caught", { error });
41966
- log11.error("Component stack", { componentStack: errorInfo.componentStack ?? "<none>" });
41999
+ log10.error("Error caught", { error });
42000
+ log10.error("Component stack", { componentStack: errorInfo.componentStack ?? "<none>" });
41967
42001
  }
41968
42002
  render() {
41969
42003
  if (this.state.hasError) {
@@ -42026,7 +42060,7 @@ function useGLTFModel(url, resourceBasePath) {
42026
42060
  setState({ model: null, isLoading: false, error: null });
42027
42061
  return;
42028
42062
  }
42029
- log12.debug("Loading", { url });
42063
+ log11.debug("Loading", { url });
42030
42064
  setState((prev) => ({ ...prev, isLoading: true, error: null }));
42031
42065
  const assetRoot = resourceBasePath || detectAssetRoot2(url);
42032
42066
  const loader = new GLTFLoader$1();
@@ -42034,7 +42068,7 @@ function useGLTFModel(url, resourceBasePath) {
42034
42068
  loader.load(
42035
42069
  url,
42036
42070
  (gltf) => {
42037
- log12.debug("Loaded", { url });
42071
+ log11.debug("Loaded", { url });
42038
42072
  setState({
42039
42073
  model: gltf.scene,
42040
42074
  isLoading: false,
@@ -42043,7 +42077,7 @@ function useGLTFModel(url, resourceBasePath) {
42043
42077
  },
42044
42078
  void 0,
42045
42079
  (err) => {
42046
- log12.warn("Failed", { url, error: err instanceof Error ? err : String(err) });
42080
+ log11.warn("Failed", { url, error: err instanceof Error ? err : String(err) });
42047
42081
  setState({
42048
42082
  model: null,
42049
42083
  isLoading: false,
@@ -42159,11 +42193,11 @@ function ModelLoader({
42159
42193
  }
42160
42194
  );
42161
42195
  }
42162
- var log12;
42196
+ var log11;
42163
42197
  var init_ModelLoader = __esm({
42164
42198
  "components/game/molecules/three/components/ModelLoader.tsx"() {
42165
42199
  "use client";
42166
- log12 = createLogger("almadar:ui:game:model-loader");
42200
+ log11 = createLogger("almadar:ui:game:model-loader");
42167
42201
  }
42168
42202
  });
42169
42203
 
@@ -42424,24 +42458,28 @@ var init_GameCanvas3D2 = __esm({
42424
42458
  const cameraConfig = useMemo(() => {
42425
42459
  const size = Math.max(
42426
42460
  gridBounds.maxX - gridBounds.minX,
42427
- gridBounds.maxZ - gridBounds.minZ
42461
+ gridBounds.maxZ - gridBounds.minZ,
42462
+ 4
42463
+ // minimum framing distance so a tiny board isn't zoomed in
42428
42464
  );
42429
- const distance = size * 1.5;
42465
+ const cx = (gridBounds.minX + gridBounds.maxX) / 2;
42466
+ const cz = (gridBounds.minZ + gridBounds.maxZ) / 2;
42467
+ const d = size * 1.5;
42430
42468
  switch (cameraMode) {
42431
42469
  case "isometric":
42432
42470
  return {
42433
- position: [distance, distance * 0.8, distance],
42471
+ position: [cx + d, d * 0.8, cz + d],
42434
42472
  fov: 45
42435
42473
  };
42436
42474
  case "top-down":
42437
42475
  return {
42438
- position: [0, distance * 2, 0],
42476
+ position: [cx, d * 2, cz],
42439
42477
  fov: 45
42440
42478
  };
42441
42479
  case "perspective":
42442
42480
  default:
42443
42481
  return {
42444
- position: [distance, distance, distance],
42482
+ position: [cx + d, d, cz + d],
42445
42483
  fov: 45
42446
42484
  };
42447
42485
  }
@@ -42680,7 +42718,8 @@ var init_GameCanvas3D2 = __esm({
42680
42718
  "div",
42681
42719
  {
42682
42720
  ref: containerRef,
42683
- className: cn("game-canvas-3d relative w-full h-full min-h-[85vh] overflow-hidden", className),
42721
+ className: cn("game-canvas-3d relative w-full overflow-hidden", className),
42722
+ style: { minHeight: "85vh" },
42684
42723
  "data-orientation": orientation,
42685
42724
  "data-camera-mode": cameraMode,
42686
42725
  "data-overlay": overlay,
@@ -42695,7 +42734,7 @@ var init_GameCanvas3D2 = __esm({
42695
42734
  near: 0.1,
42696
42735
  far: 1e3
42697
42736
  },
42698
- style: { background: backgroundColor },
42737
+ style: { background: backgroundColor, height: "85vh", width: "100%" },
42699
42738
  onClick: (e) => {
42700
42739
  if (e.target === e.currentTarget) {
42701
42740
  eventHandlers.handleCanvasClick(e);
@@ -46478,7 +46517,7 @@ function getAllEvents(traits2) {
46478
46517
  function EventDispatcherTab({ traits: traits2, schema }) {
46479
46518
  const eventBus = useEventBus();
46480
46519
  const { t } = useTranslate();
46481
- const [log14, setLog] = React82.useState([]);
46520
+ const [log13, setLog] = React82.useState([]);
46482
46521
  const prevStatesRef = React82.useRef(/* @__PURE__ */ new Map());
46483
46522
  React82.useEffect(() => {
46484
46523
  for (const trait of traits2) {
@@ -46542,9 +46581,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
46542
46581
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.otherEvents") }),
46543
46582
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: unavailableEvents.map((event) => /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", className: "opacity-50", children: event }, event)) })
46544
46583
  ] }),
46545
- log14.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
46584
+ log13.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
46546
46585
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.recentTransitions") }),
46547
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log14.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
46586
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log13.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
46548
46587
  /* @__PURE__ */ jsx("span", { className: "text-purple-400", children: entry.traitName }),
46549
46588
  " ",
46550
46589
  /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: entry.from }),
@@ -51559,7 +51598,7 @@ function isPatternConfig(value) {
51559
51598
  if (value instanceof Date) return false;
51560
51599
  if (typeof value === "function") return false;
51561
51600
  const record = value;
51562
- return "type" in record && typeof record.type === "string" && isKnownPattern(record.type);
51601
+ return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
51563
51602
  }
51564
51603
  function isPlainConfigObject(value) {
51565
51604
  if (React82__default.isValidElement(value)) return false;
@@ -52153,7 +52192,7 @@ init_UISlotRenderer();
52153
52192
  // providers/VerificationProvider.tsx
52154
52193
  init_useEventBus();
52155
52194
  init_verificationRegistry();
52156
- var log13 = createLogger("almadar:verify");
52195
+ var log12 = createLogger("almadar:verify");
52157
52196
  var DISPATCH_SUFFIX = ":DISPATCH";
52158
52197
  var SUCCESS_SUFFIX = ":SUCCESS";
52159
52198
  var ERROR_SUFFIX = ":ERROR";
@@ -52200,7 +52239,7 @@ function VerificationProvider({
52200
52239
  const verificationProviderLifecycleListener = (evt) => {
52201
52240
  const parsed = parseLifecycleEvent(evt.type);
52202
52241
  if (!parsed) return;
52203
- log13.debug("lifecycle:event", { kind: parsed.kind, traitName: parsed.traitName, event: parsed.event, type: evt.type });
52242
+ log12.debug("lifecycle:event", { kind: parsed.kind, traitName: parsed.traitName, event: parsed.event, type: evt.type });
52204
52243
  const payload = evt.payload ?? {};
52205
52244
  if (parsed.kind === "dispatch") {
52206
52245
  const key = `${parsed.traitName}:${String(payload["event"] ?? "")}`;
@@ -52255,7 +52294,7 @@ function VerificationProvider({
52255
52294
  },
52256
52295
  timestamp: Date.now()
52257
52296
  });
52258
- log13.debug("transition:success", { trait: parsed.traitName, event: parsed.event, from: pending?.from, to: newState, effectCount: effects.length });
52297
+ log12.debug("transition:success", { trait: parsed.traitName, event: parsed.event, from: pending?.from, to: newState, effectCount: effects.length });
52259
52298
  } else if (parsed.kind === "error" && parsed.event) {
52260
52299
  const key = `${parsed.traitName}:${parsed.event}`;
52261
52300
  const pending = pendingRef.current.get(key);
@@ -52285,7 +52324,7 @@ function VerificationProvider({
52285
52324
  },
52286
52325
  timestamp: Date.now()
52287
52326
  });
52288
- log13.warn("transition:error", { trait: parsed.traitName, event: parsed.event, from: fromState, error: errorMsg });
52327
+ log12.warn("transition:error", { trait: parsed.traitName, event: parsed.event, from: fromState, error: errorMsg });
52289
52328
  }
52290
52329
  };
52291
52330
  Object.defineProperty(verificationProviderLifecycleListener, "name", {