@almadar/ui 6.53.0 → 6.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/Typography-CFI7JUVE.js +5 -0
  2. package/dist/{UISlotRenderer-JT34I3O7.js → UISlotRenderer-QUEG6WFM.js} +5 -5
  3. package/dist/avl/index.cjs +578 -262
  4. package/dist/avl/index.js +28 -19
  5. package/dist/{avl-3d-context-MAt_NuU9.d.ts → avl-3d-context-BpBKZIbc.d.ts} +1 -0
  6. package/dist/{chunk-DQTV6QVS.js → chunk-4HC5HRHB.js} +53 -2
  7. package/dist/{chunk-GMDMOYXD.js → chunk-4UP6BZ4R.js} +1 -1
  8. package/dist/{chunk-CBIJP5PL.js → chunk-FJDS4SVD.js} +3 -3
  9. package/dist/{chunk-4OZDHCZV.js → chunk-MCKFWPT2.js} +1 -1
  10. package/dist/{chunk-UGHAADU5.js → chunk-N2V4LHFQ.js} +4 -1
  11. package/dist/{chunk-3EF5SDIJ.js → chunk-U2FGMHQP.js} +306 -174
  12. package/dist/{chunk-IKULQIDX.js → chunk-U3CGKPOK.js} +252 -91
  13. package/dist/{chunk-7LM6I3NA.js → chunk-Z5IYJU44.js} +1 -0
  14. package/dist/{chunk-WPNM2KC6.js → chunk-Z7JWXIRE.js} +2 -2
  15. package/dist/components/index.cjs +312 -170
  16. package/dist/components/index.d.ts +5 -1
  17. package/dist/components/index.js +11 -12
  18. package/dist/context/index.cjs +2 -0
  19. package/dist/context/index.js +2 -0
  20. package/dist/hooks/index.cjs +9 -1
  21. package/dist/hooks/index.d.ts +10 -1
  22. package/dist/hooks/index.js +3 -4
  23. package/dist/lib/drawable/three/index.cjs +5 -1
  24. package/dist/lib/drawable/three/index.d.ts +2 -2
  25. package/dist/lib/drawable/three/index.js +6 -6
  26. package/dist/lib/index.cjs +4 -1
  27. package/dist/lib/index.js +2 -2
  28. package/dist/locales/index.cjs +12 -3
  29. package/dist/locales/index.js +9 -3
  30. package/dist/providers/index.cjs +307 -170
  31. package/dist/providers/index.d.ts +1 -1
  32. package/dist/providers/index.js +5 -5
  33. package/dist/runtime/index.cjs +3850 -3523
  34. package/dist/runtime/index.d.ts +22 -4
  35. package/dist/runtime/index.js +13 -10
  36. package/dist/ssr/index.cjs +5 -2
  37. package/dist/ssr/index.js +5 -2
  38. package/locales/ar.json +4 -1
  39. package/locales/en.json +4 -1
  40. package/locales/sl.json +4 -1
  41. package/package.json +7 -6
  42. package/scripts/audit-tailwind-safelist.ts +21 -1
  43. package/tailwind-preset.cjs +15 -6
  44. package/themes/_fonts.css +6 -4
  45. package/themes/_presets.css +2 -0
  46. package/themes/almadar-heritage.css +373 -0
  47. package/themes/orb.css +373 -0
  48. package/dist/Typography-JGSDH4JP.js +0 -5
  49. package/dist/chunk-GODZKHAL.js +0 -51
@@ -17,6 +17,7 @@ var ui = require('@almadar/runtime/ui');
17
17
  var SyntaxHighlighter = require('react-syntax-highlighter/dist/esm/prism-light.js');
18
18
  var createHighlightElement = require('react-syntax-highlighter/dist/esm/create-element.js');
19
19
  var dark = require('react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus.js');
20
+ var light = require('react-syntax-highlighter/dist/esm/styles/prism/vs.js');
20
21
  var syntax = require('@almadar/syntax');
21
22
  var i18n = require('@almadar/core/i18n');
22
23
  var langJson = require('react-syntax-highlighter/dist/esm/languages/prism/json.js');
@@ -103,6 +104,7 @@ var LucideIcons2__namespace = /*#__PURE__*/_interopNamespace(LucideIcons2);
103
104
  var SyntaxHighlighter__default = /*#__PURE__*/_interopDefault(SyntaxHighlighter);
104
105
  var createHighlightElement__default = /*#__PURE__*/_interopDefault(createHighlightElement);
105
106
  var dark__default = /*#__PURE__*/_interopDefault(dark);
107
+ var light__default = /*#__PURE__*/_interopDefault(light);
106
108
  var langJson__default = /*#__PURE__*/_interopDefault(langJson);
107
109
  var langJavascript__default = /*#__PURE__*/_interopDefault(langJavascript);
108
110
  var langTypescript__default = /*#__PURE__*/_interopDefault(langTypescript);
@@ -480,6 +482,7 @@ var init_avl_theme = __esm({
480
482
  "std-json": avlBlend("var(--color-success)", 60, "var(--color-foreground)"),
481
483
  "std-time": avlBlend("var(--color-info)", 50, "var(--color-success)"),
482
484
  "std-format": avlBlend("var(--color-success)", 60, "var(--color-background)"),
485
+ "std-i18n": avlBlend("var(--color-info)", 60, "var(--color-background)"),
483
486
  "std-async": avlBlend("var(--color-accent)", 50, "var(--color-error)"),
484
487
  "std-nn": avlBlend("var(--color-primary)", 60, "var(--color-accent)"),
485
488
  "std-tensor": avlBlend("var(--color-primary)", 60, "var(--color-info)"),
@@ -3632,6 +3635,7 @@ var init_en = __esm({
3632
3635
  "status.draft": "Draft",
3633
3636
  "status.archived": "Archived",
3634
3637
  "error.generic": "Something went wrong",
3638
+ "error.traitMountFailed": "{{trait}} failed to start",
3635
3639
  "error.retry": "Try again",
3636
3640
  "error.notFound": "Not found",
3637
3641
  "error.loadFailed": "Failed to load: {{message}}",
@@ -4800,7 +4804,9 @@ var init_en = __esm({
4800
4804
  "agentActivity.llmToolCalls": "Tool calls",
4801
4805
  "agentActivity.showRawLlm": "Raw LLM",
4802
4806
  "agentActivity.earlierConversations": "Earlier conversations ({{count}})",
4803
- "agentActivity.earlierActivity": "Earlier activity"
4807
+ "agentActivity.earlierActivity": "Earlier activity",
4808
+ "tabs.scrollStart": "Scroll tabs back",
4809
+ "tabs.scrollEnd": "Scroll tabs forward"
4804
4810
  };
4805
4811
  }
4806
4812
  });
@@ -7344,7 +7350,7 @@ var init_Button = __esm({
7344
7350
  const testId = dataTestId ?? (action ? `action-${action}` : void 0);
7345
7351
  const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7346
7352
  busy && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "almadar-busy-indicator absolute inset-0 flex items-center justify-center", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.Loader2, { className: "h-icon-default w-icon-default animate-spin" }) }),
7347
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("inline-flex items-center justify-center gap-2", busy && "almadar-busy-content"), children: [
7353
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("inline-flex flex-1 min-w-0 items-center [justify-content:inherit] gap-2", busy && "almadar-busy-content"), children: [
7348
7354
  resolvedLeftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
7349
7355
  (Array.isArray(children) ? children.length > 0 : Boolean(children)) ? children : label ? /* @__PURE__ */ jsxRuntime.jsx("span", { ...{ [INLINE_TEXT_ATTR]: "label" }, children: label }) : label,
7350
7356
  resolvedRightIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: resolvedRightIcon })
@@ -13356,12 +13362,13 @@ var init_Skeleton = __esm({
13356
13362
  Skeleton.displayName = "Skeleton";
13357
13363
  }
13358
13364
  });
13359
- function resolveMarkerExpression(expression, entity, config, state) {
13365
+ function resolveMarkerExpression(expression, entity, config, state, i18n) {
13360
13366
  const ctx = runtime.createContextFromBindings({
13361
13367
  entity,
13362
13368
  payload: {},
13363
13369
  state,
13364
- ...config !== void 0 ? { config } : {}
13370
+ ...config !== void 0 ? { config } : {},
13371
+ ...i18n !== void 0 ? { locale: i18n.locale, messages: i18n.messages } : {}
13365
13372
  });
13366
13373
  return runtime.interpolateValue(expression, ctx);
13367
13374
  }
@@ -13373,9 +13380,9 @@ function isPlainObject(value) {
13373
13380
  if (typeof value === "function") return false;
13374
13381
  return true;
13375
13382
  }
13376
- function cachedContainer(value, scopeTrait, entity, config, state) {
13383
+ function cachedContainer(value, scopeTrait, entity, config, state, i18n) {
13377
13384
  const hit = containerResolutionCache.get(value);
13378
- return hit !== void 0 && hit.entity === entity && hit.config === config && hit.state === state && hit.scopeTrait === scopeTrait ? hit.resolved : void 0;
13385
+ return hit !== void 0 && hit.entity === entity && hit.config === config && hit.state === state && hit.i18n === i18n && hit.scopeTrait === scopeTrait ? hit.resolved : void 0;
13379
13386
  }
13380
13387
  function isEvaluatorResolvedData(value) {
13381
13388
  return evaluatorResolvedData.has(value);
@@ -13406,14 +13413,14 @@ function subtreeHasMarker(value) {
13406
13413
  markerPresenceCache.set(value, found);
13407
13414
  return found;
13408
13415
  }
13409
- function walkValue(value, scopeTrait, entity, config, state) {
13416
+ function walkValue(value, scopeTrait, entity, config, state, i18n) {
13410
13417
  if (core.isRenderBindingMarker(value)) {
13411
13418
  const cached = markerResolutionCache.get(value);
13412
- if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state) {
13419
+ if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state && cached.i18n === i18n) {
13413
13420
  return { resolved: cached.resolved, changed: true };
13414
13421
  }
13415
- const resolved = resolveMarkerExpression(value.expression, entity, config, state);
13416
- markerResolutionCache.set(value, { entity, config, state, resolved });
13422
+ const resolved = resolveMarkerExpression(value.expression, entity, config, state, i18n);
13423
+ markerResolutionCache.set(value, { entity, config, state, i18n, resolved });
13417
13424
  if (resolved !== null && typeof resolved === "object" && !React93__namespace.default.isValidElement(resolved) && !(resolved instanceof Date)) {
13418
13425
  resolvedMarkerFree.add(resolved);
13419
13426
  evaluatorResolvedData.add(resolved);
@@ -13425,14 +13432,14 @@ function walkValue(value, scopeTrait, entity, config, state) {
13425
13432
  brandResolved(value);
13426
13433
  return { resolved: value, changed: false };
13427
13434
  }
13428
- const cachedArray = cachedContainer(value, scopeTrait, entity, config, state);
13435
+ const cachedArray = cachedContainer(value, scopeTrait, entity, config, state, i18n);
13429
13436
  if (cachedArray !== void 0) return { resolved: cachedArray, changed: true };
13430
13437
  const out = [];
13431
13438
  let changed = false;
13432
13439
  for (const item of value) {
13433
13440
  const element = item;
13434
13441
  const wasMarker = core.isRenderBindingMarker(element);
13435
- const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state);
13442
+ const { resolved, changed: itemChanged } = walkValue(element, scopeTrait, entity, config, state, i18n);
13436
13443
  if (wasMarker && Array.isArray(resolved)) {
13437
13444
  out.push(...resolved);
13438
13445
  changed = true;
@@ -13443,7 +13450,7 @@ function walkValue(value, scopeTrait, entity, config, state) {
13443
13450
  }
13444
13451
  brandResolved(out);
13445
13452
  if (!changed) return { resolved: value, changed: false };
13446
- containerResolutionCache.set(value, { entity, config, state, scopeTrait, resolved: out });
13453
+ containerResolutionCache.set(value, { entity, config, state, i18n, scopeTrait, resolved: out });
13447
13454
  return { resolved: out, changed: true };
13448
13455
  }
13449
13456
  if (isPlainObject(value)) {
@@ -13455,37 +13462,37 @@ function walkValue(value, scopeTrait, entity, config, state) {
13455
13462
  if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
13456
13463
  return { resolved: value, changed: false };
13457
13464
  }
13458
- const cachedObject = cachedContainer(value, scopeTrait, entity, config, state);
13465
+ const cachedObject = cachedContainer(value, scopeTrait, entity, config, state, i18n);
13459
13466
  if (cachedObject !== void 0) return { resolved: cachedObject, changed: true };
13460
13467
  const out = {};
13461
13468
  let changed = false;
13462
13469
  for (const [key, item] of Object.entries(value)) {
13463
- const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state);
13470
+ const { resolved, changed: itemChanged } = walkValue(item, scopeTrait, entity, config, state, i18n);
13464
13471
  out[key] = resolved;
13465
13472
  if (itemChanged) changed = true;
13466
13473
  }
13467
13474
  brandResolved(out);
13468
13475
  if (!changed) return { resolved: value, changed: false };
13469
- containerResolutionCache.set(value, { entity, config, state, scopeTrait, resolved: out });
13476
+ containerResolutionCache.set(value, { entity, config, state, i18n, scopeTrait, resolved: out });
13470
13477
  return { resolved: out, changed: true };
13471
13478
  }
13472
13479
  return { resolved: value, changed: false };
13473
13480
  }
13474
- function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
13481
+ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state, i18n) {
13475
13482
  if (props === null || typeof props !== "object") return props;
13476
13483
  if (resolvedMarkerFree.has(props)) return props;
13477
- const cached = cachedContainer(props, scopeTrait, entity, config, state);
13484
+ const cached = cachedContainer(props, scopeTrait, entity, config, state, i18n);
13478
13485
  if (cached !== void 0) return cached;
13479
13486
  const out = {};
13480
13487
  let changed = false;
13481
13488
  for (const [key, value] of Object.entries(props)) {
13482
- const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state);
13489
+ const { resolved, changed: propChanged } = walkValue(value, scopeTrait, entity, config, state, i18n);
13483
13490
  out[key] = resolved;
13484
13491
  if (propChanged) changed = true;
13485
13492
  }
13486
13493
  brandResolved(out);
13487
13494
  if (!changed) return props;
13488
- containerResolutionCache.set(props, { entity, config, state, scopeTrait, resolved: out });
13495
+ containerResolutionCache.set(props, { entity, config, state, i18n, scopeTrait, resolved: out });
13489
13496
  return out;
13490
13497
  }
13491
13498
  var markerPresenceCache, markerResolutionCache, containerResolutionCache, resolvedMarkerFree, evaluatorResolvedData;
@@ -15282,6 +15289,7 @@ var init_Tabs = __esm({
15282
15289
  init_Badge();
15283
15290
  init_Typography();
15284
15291
  init_Box();
15292
+ init_Button();
15285
15293
  init_cn();
15286
15294
  init_useEventBus();
15287
15295
  init_domPassthrough();
@@ -15313,6 +15321,28 @@ var init_Tabs = __esm({
15313
15321
  const uid = React93.useId();
15314
15322
  const tabId = (id) => `${uid}-tab-${id}`;
15315
15323
  const panelId = (id) => `${uid}-panel-${id}`;
15324
+ const laneRef = React93.useRef(null);
15325
+ const [hidden, setHidden] = React93.useState({ start: false, end: false });
15326
+ const measure = React93.useCallback(() => {
15327
+ const lane = laneRef.current;
15328
+ if (!lane || orientation !== "horizontal") return;
15329
+ const max = lane.scrollWidth - lane.clientWidth;
15330
+ const start = max > 1 && lane.scrollLeft > 1;
15331
+ const end = max > 1 && lane.scrollLeft < max - 1;
15332
+ setHidden((prev) => prev.start === start && prev.end === end ? prev : { start, end });
15333
+ }, [orientation]);
15334
+ React93.useLayoutEffect(() => {
15335
+ measure();
15336
+ const lane = laneRef.current;
15337
+ if (!lane || typeof ResizeObserver === "undefined") return void 0;
15338
+ const observer2 = new ResizeObserver(measure);
15339
+ observer2.observe(lane);
15340
+ return () => observer2.disconnect();
15341
+ }, [measure, rawItems.length]);
15342
+ const scrollLane = (direction) => {
15343
+ const lane = laneRef.current;
15344
+ if (lane) lane.scrollBy({ left: direction * lane.clientWidth * 0.8, behavior: "smooth" });
15345
+ };
15316
15346
  const handleTabChange = (tabId2, tabEvent) => {
15317
15347
  if (controlledActiveTab === void 0) {
15318
15348
  setInternalActiveTab(tabId2);
@@ -15369,62 +15399,97 @@ var init_Tabs = __esm({
15369
15399
  "data-[active=true]:border-primary"
15370
15400
  ].join(" ")
15371
15401
  };
15372
- return /* @__PURE__ */ jsxRuntime.jsxs(Box, { ...domPassthrough(rest), className: cn("w-full", orientation === "vertical" && "flex flex-row", className), children: [
15373
- /* @__PURE__ */ jsxRuntime.jsx(
15374
- Box,
15375
- {
15376
- role: "tablist",
15377
- "aria-orientation": orientation,
15378
- className: cn(
15379
- "flex",
15380
- // Horizontal tab strip becomes a horizontally-scrollable lane
15381
- // below its container width — phones with many tabs scroll
15382
- // instead of clipping. `snap-x` snaps to each tab; the
15383
- // scrollbar is hidden for a cleaner affordance (the swipe
15384
- // gesture is the discoverability cue).
15385
- orientation === "horizontal" ? "flex-row border-b-[length:var(--border-width)] border-border overflow-x-auto snap-x snap-mandatory [&::-webkit-scrollbar]:hidden" : "flex-col border-r-[length:var(--border-width)] border-border",
15386
- variant === "pills" && "gap-1 p-1 bg-muted border-0 rounded-interactive",
15387
- variant === "underline" && orientation === "vertical" && "border-b-0"
15388
- ),
15389
- children: safeItems.map((item, index) => {
15390
- const isActive = item.id === activeTab;
15391
- const isDisabled = item.disabled;
15392
- return /* @__PURE__ */ jsxRuntime.jsxs(
15393
- Box,
15394
- {
15395
- as: "button",
15396
- ref: (el) => {
15397
- tabRefs.current[item.id] = el;
15398
- },
15399
- id: tabId(item.id),
15400
- role: "tab",
15401
- "aria-selected": isActive,
15402
- "aria-controls": isActive ? panelId(item.id) : void 0,
15403
- "aria-disabled": isDisabled,
15404
- tabIndex: isActive ? 0 : -1,
15405
- onClick: () => !isDisabled && handleTabChange(item.id, item.event),
15406
- onKeyDown: (e) => handleKeyDown(e, index),
15407
- "data-active": isActive,
15408
- "data-testid": `tab-${item.id}`,
15409
- className: cn(
15410
- "flex items-center gap-2 px-4 py-2 text-sm font-medium transition-colors whitespace-nowrap",
15411
- orientation === "horizontal" && "snap-start shrink-0",
15412
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
15413
- isDisabled && "opacity-50 cursor-not-allowed",
15414
- variantClasses2[variant],
15415
- isActive ? variant === "pills" ? "text-primary-foreground" : "text-foreground" : "text-muted-foreground hover:text-foreground"
15416
- ),
15417
- children: [
15418
- item.iconAsset?.url ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.iconAsset.url, alt: item.iconAsset.name ?? item.iconAsset.category ?? "", width: 16, height: 16, style: { imageRendering: "pixelated", objectFit: "contain", width: 16, height: 16 }, className: "flex-shrink-0" }) : item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: item.icon, size: "sm" })),
15419
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "medium", className: "!text-inherit", children: item.label }),
15420
- item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: item.badge })
15421
- ]
15402
+ const tablist = /* @__PURE__ */ jsxRuntime.jsx(
15403
+ Box,
15404
+ {
15405
+ ref: laneRef,
15406
+ role: "tablist",
15407
+ "aria-orientation": orientation,
15408
+ onScroll: measure,
15409
+ "data-scroll-affordance": hidden.start || hidden.end ? "true" : void 0,
15410
+ className: cn(
15411
+ "flex",
15412
+ // Horizontal tab strip becomes a horizontally-scrollable lane
15413
+ // below its container width — phones with many tabs scroll
15414
+ // instead of clipping. `snap-x` snaps to each tab; the
15415
+ // scrollbar is hidden — the edge chevrons are the affordance.
15416
+ orientation === "horizontal" ? "flex-row border-b-[length:var(--border-width)] border-border overflow-x-auto snap-x snap-mandatory [&::-webkit-scrollbar]:hidden" : "flex-col border-r-[length:var(--border-width)] border-border",
15417
+ variant === "pills" && "gap-1 p-1 bg-muted border-0 rounded-interactive",
15418
+ variant === "underline" && orientation === "vertical" && "border-b-0"
15419
+ ),
15420
+ children: safeItems.map((item, index) => {
15421
+ const isActive = item.id === activeTab;
15422
+ const isDisabled = item.disabled;
15423
+ return /* @__PURE__ */ jsxRuntime.jsxs(
15424
+ Box,
15425
+ {
15426
+ as: "button",
15427
+ ref: (el) => {
15428
+ tabRefs.current[item.id] = el;
15422
15429
  },
15423
- item.id
15424
- );
15425
- })
15426
- }
15427
- ),
15430
+ id: tabId(item.id),
15431
+ role: "tab",
15432
+ "aria-selected": isActive,
15433
+ "aria-controls": isActive ? panelId(item.id) : void 0,
15434
+ "aria-disabled": isDisabled,
15435
+ tabIndex: isActive ? 0 : -1,
15436
+ onClick: () => !isDisabled && handleTabChange(item.id, item.event),
15437
+ onKeyDown: (e) => handleKeyDown(e, index),
15438
+ "data-active": isActive,
15439
+ "data-testid": `tab-${item.id}`,
15440
+ className: cn(
15441
+ "flex items-center gap-2 px-4 py-2 text-sm font-medium transition-colors whitespace-nowrap",
15442
+ orientation === "horizontal" && "snap-start shrink-0",
15443
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
15444
+ isDisabled && "opacity-50 cursor-not-allowed",
15445
+ variantClasses2[variant],
15446
+ isActive ? variant === "pills" ? "text-primary-foreground" : "text-foreground" : "text-muted-foreground hover:text-foreground"
15447
+ ),
15448
+ children: [
15449
+ item.iconAsset?.url ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.iconAsset.url, alt: item.iconAsset.name ?? item.iconAsset.category ?? "", width: 16, height: 16, style: { imageRendering: "pixelated", objectFit: "contain", width: 16, height: 16 }, className: "flex-shrink-0" }) : item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, size: "sm" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: item.icon, size: "sm" })),
15450
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "medium", className: "!text-inherit", children: item.label }),
15451
+ item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: item.badge })
15452
+ ]
15453
+ },
15454
+ item.id
15455
+ );
15456
+ })
15457
+ }
15458
+ );
15459
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { ...domPassthrough(rest), className: cn("w-full", orientation === "vertical" && "flex flex-row", className), children: [
15460
+ orientation === "horizontal" ? /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative", children: [
15461
+ tablist,
15462
+ hidden.start && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15463
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "pointer-events-none absolute inset-y-0 start-0 w-10 bg-gradient-to-r from-[var(--color-background)] to-transparent rtl:bg-gradient-to-l" }),
15464
+ /* @__PURE__ */ jsxRuntime.jsx(
15465
+ Button,
15466
+ {
15467
+ variant: "ghost",
15468
+ size: "sm",
15469
+ leftIcon: "chevron-left",
15470
+ "aria-label": t("tabs.scrollStart"),
15471
+ "data-testid": "tabs-scroll-start",
15472
+ className: "absolute start-0 top-1/2 -translate-y-1/2 px-1 rtl:rotate-180",
15473
+ onClick: () => scrollLane(-1)
15474
+ }
15475
+ )
15476
+ ] }),
15477
+ hidden.end && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15478
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "pointer-events-none absolute inset-y-0 end-0 w-10 bg-gradient-to-l from-[var(--color-background)] to-transparent rtl:bg-gradient-to-r" }),
15479
+ /* @__PURE__ */ jsxRuntime.jsx(
15480
+ Button,
15481
+ {
15482
+ variant: "ghost",
15483
+ size: "sm",
15484
+ leftIcon: "chevron-right",
15485
+ "aria-label": t("tabs.scrollEnd"),
15486
+ "data-testid": "tabs-scroll-end",
15487
+ className: "absolute end-0 top-1/2 -translate-y-1/2 px-1 rtl:rotate-180",
15488
+ onClick: () => scrollLane(1)
15489
+ }
15490
+ )
15491
+ ] })
15492
+ ] }) : tablist,
15428
15493
  activeTabContent !== void 0 && activeTabContent !== null && /* @__PURE__ */ jsxRuntime.jsx(
15429
15494
  Box,
15430
15495
  {
@@ -16635,6 +16700,35 @@ function withTokenTypes(node) {
16635
16700
  function renderWithTokenTypes({ rows, stylesheet, useInlineStyles }) {
16636
16701
  return rows.map((node, i) => createHighlightElement__default.default({ node: withTokenTypes(node), stylesheet, useInlineStyles, key: `code-segment-${i}` }));
16637
16702
  }
16703
+ function island(value, style) {
16704
+ return { type: "element", tagName: "span", properties: { className: [], "data-bidi-island": "", style }, children: [{ type: "text", value }] };
16705
+ }
16706
+ function splitLtrWords(value) {
16707
+ const out = [];
16708
+ let last = 0;
16709
+ for (const match of value.matchAll(LTR_WORD)) {
16710
+ const start = match.index ?? 0;
16711
+ if (start > last) out.push({ type: "text", value: value.slice(last, start) });
16712
+ out.push(island(match[0], LTR_ISLAND_STYLE));
16713
+ last = start + match[0].length;
16714
+ }
16715
+ if (last < value.length) out.push({ type: "text", value: value.slice(last) });
16716
+ return out;
16717
+ }
16718
+ function withBidiIslands(node) {
16719
+ if (node.type === "text") return splitLtrWords(String(node.value ?? ""));
16720
+ if (node.type !== "element") return [node];
16721
+ const classes = node.properties?.className;
16722
+ if (Array.isArray(classes) && classes.includes("string")) {
16723
+ return [{ ...node, properties: { ...node.properties, className: classes, "data-bidi-island": "", style: STRING_ISLAND_STYLE } }];
16724
+ }
16725
+ return [{ ...node, ...node.children ? { children: node.children.flatMap(withBidiIslands) } : {} }];
16726
+ }
16727
+ function renderRtlCode({ rows, stylesheet, useInlineStyles }) {
16728
+ return rows.map(
16729
+ (node, i) => withBidiIslands(node).map((n, j) => createHighlightElement__default.default({ node: n, stylesheet, useInlineStyles, key: `code-rtl-${i}-${j}` }))
16730
+ );
16731
+ }
16638
16732
  function tokenClassAt(layer, offset) {
16639
16733
  const walker = document.createTreeWalker(layer, NodeFilter.SHOW_TEXT);
16640
16734
  let pos = 0;
@@ -16691,10 +16785,9 @@ function useLanguageReady(language) {
16691
16785
  }, [language]);
16692
16786
  return ready;
16693
16787
  }
16694
- function resolveHighlightStyle(lang) {
16695
- if (lang === "orb") return orbStyle;
16696
- if (lang === "lolo") return loloStyle;
16697
- return dark__default.default;
16788
+ function resolveHighlightStyle(lang, scheme) {
16789
+ if (lang === "orb" || lang === "lolo") return HIGHLIGHT_STYLES[scheme][lang];
16790
+ return SCHEME_BASE[scheme];
16698
16791
  }
16699
16792
  function plainCodeColorOf(style) {
16700
16793
  return style['code[class*="language-"]']?.color ?? "#d4d4d4";
@@ -16729,7 +16822,7 @@ function translateProgram(source, language, lang) {
16729
16822
  }
16730
16823
  return source;
16731
16824
  }
16732
- var dynamicallyLoaded, codeLanguageLoader, orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, MONO_EDITOR_FONT, GHOST_COLOR, GUTTER_COLOR, caretOf, DIAGNOSTIC_ERROR_COLOR, DIAGNOSTIC_WARNING_COLOR, EDITOR_LINE_PX, log5, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, DIFF_STYLE_FALLBACK, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, HIGHLIGHT_CAPACITY_BYTES, MONO_FONT_FAMILY, VIEWER_LINE_NUMBER_STYLE, CodeBlock;
16825
+ var dynamicallyLoaded, codeLanguageLoader, orbStyleOverrides, loloStyleOverrides, SCHEME_BASE, HIGHLIGHT_STYLES, MONO_EDITOR_FONT, GHOST_COLOR, GUTTER_COLOR, caretOf, LTR_WORD, LTR_ISLAND_STYLE, STRING_ISLAND_STYLE, DIAGNOSTIC_ERROR_COLOR, DIAGNOSTIC_WARNING_COLOR, EDITOR_LINE_PX, log5, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, DIFF_STYLE_FALLBACK, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, HIGHLIGHT_CAPACITY_BYTES, MONO_FONT_FAMILY, VIEWER_LINE_NUMBER_STYLE, VIEWER_LINE_NUMBER_STYLE_RTL, CodeBlock;
16733
16826
  var init_CodeBlock = __esm({
16734
16827
  "components/core/molecules/markdown/CodeBlock.tsx"() {
16735
16828
  init_cn();
@@ -16832,52 +16925,64 @@ var init_CodeBlock = __esm({
16832
16925
  SyntaxHighlighter__default.default.registerLanguage("lolo", syntax.loloLanguage);
16833
16926
  dynamicallyLoaded = /* @__PURE__ */ new Set();
16834
16927
  codeLanguageLoader = null;
16835
- orbStyleOverrides = {
16836
- "orb-binding": { color: syntax.ORB_COLORS.dark.binding, fontWeight: "bold" },
16837
- "orb-effect": { color: syntax.ORB_COLORS.dark.effect, fontWeight: "bold" },
16838
- "orb-event": { color: syntax.ORB_COLORS.dark.event },
16839
- "orb-slot": { color: syntax.ORB_COLORS.dark.uiSlot },
16840
- "orb-structural": { color: syntax.ORB_COLORS.dark.structural },
16841
- "orb-field-type": { color: syntax.ORB_COLORS.dark.fieldType },
16842
- "orb-persistence": { color: syntax.ORB_COLORS.dark.persistence },
16843
- "orb-pattern": { color: syntax.ORB_COLORS.dark.pattern },
16844
- "orb-behavior": { color: syntax.ORB_COLORS.dark.behavior },
16845
- "orb-unknown-op": { color: syntax.ORB_COLORS.dark.error, textDecoration: "wavy underline" },
16846
- "orb-op-arithmetic": { color: syntax.ORB_COLORS.dark.arithmetic, fontWeight: "bold" },
16847
- "orb-op-comparison": { color: syntax.ORB_COLORS.dark.comparison },
16848
- "orb-op-logic": { color: syntax.ORB_COLORS.dark.logic },
16849
- "orb-op-string": { color: syntax.ORB_COLORS.dark.string },
16850
- "orb-op-collection": { color: syntax.ORB_COLORS.dark.collection },
16851
- "orb-op-time": { color: syntax.ORB_COLORS.dark.time },
16852
- "orb-op-control": { color: syntax.ORB_COLORS.dark.control },
16853
- "orb-op-async": { color: syntax.ORB_COLORS.dark.async }
16854
- };
16855
- orbStyle = { ...dark__default.default, ...orbStyleOverrides };
16856
- loloStyleOverrides = {
16857
- "lolo-binding": { color: syntax.ORB_COLORS.dark.binding, fontWeight: "bold" },
16858
- "lolo-event": { color: syntax.ORB_COLORS.dark.event },
16859
- "lolo-effect": { color: syntax.ORB_COLORS.dark.effect, fontWeight: "bold" },
16860
- "keyword": { color: syntax.ORB_COLORS.dark.loloKeyword },
16861
- "lolo-constructor": { color: syntax.ORB_COLORS.dark.loloConstructor },
16862
- "lolo-arrow": { color: syntax.ORB_COLORS.dark.loloArrow },
16863
- "lolo-reference": { color: syntax.ORB_COLORS.dark.loloReference },
16864
- "lolo-type": { color: syntax.ORB_COLORS.dark.fieldType },
16865
- "lolo-persistence": { color: syntax.ORB_COLORS.dark.persistence },
16866
- "lolo-unknown-op": { color: syntax.ORB_COLORS.dark.error },
16867
- "lolo-op-arithmetic": { color: syntax.ORB_COLORS.dark.arithmetic, fontWeight: "bold" },
16868
- "lolo-op-comparison": { color: syntax.ORB_COLORS.dark.comparison },
16869
- "lolo-op-logic": { color: syntax.ORB_COLORS.dark.logic },
16870
- "lolo-op-string": { color: syntax.ORB_COLORS.dark.string },
16871
- "lolo-op-collection": { color: syntax.ORB_COLORS.dark.collection },
16872
- "lolo-op-time": { color: syntax.ORB_COLORS.dark.time },
16873
- "lolo-op-control": { color: syntax.ORB_COLORS.dark.control },
16874
- "lolo-op-async": { color: syntax.ORB_COLORS.dark.async }
16875
- };
16876
- loloStyle = { ...dark__default.default, ...loloStyleOverrides };
16928
+ orbStyleOverrides = (c) => ({
16929
+ "orb-binding": { color: c.binding, fontWeight: "bold" },
16930
+ "orb-effect": { color: c.effect, fontWeight: "bold" },
16931
+ "orb-event": { color: c.event },
16932
+ "orb-slot": { color: c.uiSlot },
16933
+ "orb-structural": { color: c.structural },
16934
+ "orb-field-type": { color: c.fieldType },
16935
+ "orb-persistence": { color: c.persistence },
16936
+ "orb-pattern": { color: c.pattern },
16937
+ "orb-behavior": { color: c.behavior },
16938
+ "orb-unknown-op": { color: c.error, textDecoration: "wavy underline" },
16939
+ "orb-op-arithmetic": { color: c.arithmetic, fontWeight: "bold" },
16940
+ "orb-op-comparison": { color: c.comparison },
16941
+ "orb-op-logic": { color: c.logic },
16942
+ "orb-op-string": { color: c.string },
16943
+ "orb-op-collection": { color: c.collection },
16944
+ "orb-op-time": { color: c.time },
16945
+ "orb-op-control": { color: c.control },
16946
+ "orb-op-async": { color: c.async }
16947
+ });
16948
+ loloStyleOverrides = (c) => ({
16949
+ "lolo-binding": { color: c.binding, fontWeight: "bold" },
16950
+ "lolo-event": { color: c.event },
16951
+ "lolo-effect": { color: c.effect, fontWeight: "bold" },
16952
+ "keyword": { color: c.loloKeyword },
16953
+ "lolo-constructor": { color: c.loloConstructor },
16954
+ "lolo-arrow": { color: c.loloArrow },
16955
+ "lolo-reference": { color: c.loloReference },
16956
+ "lolo-type": { color: c.fieldType },
16957
+ "lolo-persistence": { color: c.persistence },
16958
+ "lolo-unknown-op": { color: c.error },
16959
+ "lolo-op-arithmetic": { color: c.arithmetic, fontWeight: "bold" },
16960
+ "lolo-op-comparison": { color: c.comparison },
16961
+ "lolo-op-logic": { color: c.logic },
16962
+ "lolo-op-string": { color: c.string },
16963
+ "lolo-op-collection": { color: c.collection },
16964
+ "lolo-op-time": { color: c.time },
16965
+ "lolo-op-control": { color: c.control },
16966
+ "lolo-op-async": { color: c.async }
16967
+ });
16968
+ SCHEME_BASE = { dark: dark__default.default, light: light__default.default };
16969
+ HIGHLIGHT_STYLES = {
16970
+ dark: {
16971
+ orb: { ...dark__default.default, ...orbStyleOverrides(syntax.ORB_COLORS.dark) },
16972
+ lolo: { ...dark__default.default, ...loloStyleOverrides(syntax.ORB_COLORS.dark) }
16973
+ },
16974
+ light: {
16975
+ orb: { ...light__default.default, ...orbStyleOverrides(syntax.ORB_COLORS.light) },
16976
+ lolo: { ...light__default.default, ...loloStyleOverrides(syntax.ORB_COLORS.light) }
16977
+ }
16978
+ };
16877
16979
  MONO_EDITOR_FONT = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace';
16878
16980
  GHOST_COLOR = "#7f848e";
16879
16981
  GUTTER_COLOR = "#858585";
16880
16982
  caretOf = (ta) => ta.selectionDirection === "backward" ? ta.selectionStart : ta.selectionEnd;
16983
+ LTR_WORD = /[A-Za-z0-9_$@?][A-Za-z0-9_$@?.!-]*/g;
16984
+ LTR_ISLAND_STYLE = { unicodeBidi: "isolate", direction: "ltr" };
16985
+ STRING_ISLAND_STYLE = { unicodeBidi: "plaintext" };
16881
16986
  DIAGNOSTIC_ERROR_COLOR = "#f14c4c";
16882
16987
  DIAGNOSTIC_WARNING_COLOR = "#cca700";
16883
16988
  EDITOR_LINE_PX = 19.5;
@@ -16977,7 +17082,7 @@ var init_CodeBlock = __esm({
16977
17082
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
16978
17083
  HIDDEN_LINE_NUMBERS = { display: "none" };
16979
17084
  HIGHLIGHT_CAPACITY_BYTES = 512 * 1024;
16980
- MONO_FONT_FAMILY = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace';
17085
+ MONO_FONT_FAMILY = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", "IBM Plex Sans Arabic", "Noto Sans Arabic", monospace';
16981
17086
  VIEWER_LINE_NUMBER_STYLE = {
16982
17087
  minWidth: "2.5em",
16983
17088
  paddingRight: "1rem",
@@ -16986,6 +17091,15 @@ var init_CodeBlock = __esm({
16986
17091
  opacity: 0.5,
16987
17092
  fontVariantNumeric: "tabular-nums"
16988
17093
  };
17094
+ VIEWER_LINE_NUMBER_STYLE_RTL = {
17095
+ minWidth: "2.5em",
17096
+ paddingRight: 0,
17097
+ paddingLeft: "1rem",
17098
+ textAlign: "left",
17099
+ userSelect: "none",
17100
+ opacity: 0.5,
17101
+ fontVariantNumeric: "tabular-nums"
17102
+ };
16989
17103
  CodeBlock = React93__namespace.default.memo(
16990
17104
  ({
16991
17105
  code: rawCode,
@@ -17065,8 +17179,12 @@ var init_CodeBlock = __esm({
17065
17179
  }) => {
17066
17180
  const englishCode = typeof rawCode === "string" ? rawCode : String(rawCode ?? "");
17067
17181
  const naturalTabs = !editable && naturalLanguages && naturalLanguages.length > 1 ? naturalLanguages : void 0;
17068
- const [naturalLanguage, setNaturalLanguage] = React93.useState(() => naturalTabs?.[0] ?? "en");
17182
+ const { locale: pageLocale } = hooks.useTranslate();
17183
+ const [naturalLanguage, setNaturalLanguage] = React93.useState(
17184
+ () => naturalTabs?.find((lang) => lang === pageLocale) ?? naturalTabs?.[0] ?? "en"
17185
+ );
17069
17186
  const activeNaturalLanguage = naturalTabs?.includes(naturalLanguage) === true ? naturalLanguage : naturalTabs?.[0] ?? "en";
17187
+ const codeDir = naturalTabs && i18n.coreTables[activeNaturalLanguage].meta.rtl ? "rtl" : "ltr";
17070
17188
  const translationCache = React93.useMemo(() => /* @__PURE__ */ new Map(), [englishCode, files]);
17071
17189
  const translateFor = React93.useCallback(
17072
17190
  (source, sourceLanguage, cacheKey) => {
@@ -17105,11 +17223,12 @@ var init_CodeBlock = __esm({
17105
17223
  )
17106
17224
  }
17107
17225
  ) : null;
17108
- const activeStyle = resolveHighlightStyle(language);
17226
+ const activeStyle = resolveHighlightStyle(language, "dark");
17109
17227
  const overCapacity = code.length > HIGHLIGHT_CAPACITY_BYTES;
17110
17228
  const plainCodeColor = plainCodeColorOf(activeStyle);
17111
17229
  const eventBus = useEventBus();
17112
17230
  const { t } = hooks.useTranslate();
17231
+ const { resolvedMode } = context.useTheme();
17113
17232
  const scrollRef = React93.useRef(null);
17114
17233
  const codeRef = React93.useRef(null);
17115
17234
  const savedScrollLeftRef = React93.useRef(0);
@@ -17120,7 +17239,7 @@ var init_CodeBlock = __esm({
17120
17239
  const activeLanguage = activeFile?.language ?? language;
17121
17240
  const activeCode = activeFile ? translateFor(activeFile.code, activeLanguage, `file-${activeFileIndex}`) : code;
17122
17241
  const languageReady = useLanguageReady(activeLanguage);
17123
- const viewerStyle = resolveHighlightStyle(activeLanguage);
17242
+ const viewerStyle = resolveHighlightStyle(activeLanguage, resolvedMode);
17124
17243
  const viewerPlainCodeColor = plainCodeColorOf(viewerStyle);
17125
17244
  const diffLines = React93.useMemo(() => {
17126
17245
  if (propDiff && propDiff.length > 0) return propDiff;
@@ -17458,8 +17577,9 @@ var init_CodeBlock = __esm({
17458
17577
  wrapLines: true,
17459
17578
  wrapLongLines: wrap,
17460
17579
  showLineNumbers,
17461
- lineNumberStyle: VIEWER_LINE_NUMBER_STYLE,
17580
+ lineNumberStyle: codeDir === "rtl" ? VIEWER_LINE_NUMBER_STYLE_RTL : VIEWER_LINE_NUMBER_STYLE,
17462
17581
  lineProps: viewerLineProps,
17582
+ renderer: codeDir === "rtl" ? renderRtlCode : void 0,
17463
17583
  customStyle: {
17464
17584
  backgroundColor: "transparent",
17465
17585
  borderRadius: 0,
@@ -17469,13 +17589,15 @@ var init_CodeBlock = __esm({
17469
17589
  wordBreak: wrap ? "break-all" : "normal",
17470
17590
  fontFamily: MONO_FONT_FAMILY,
17471
17591
  fontSize: "12px",
17472
- lineHeight: "1.6"
17592
+ lineHeight: "1.6",
17593
+ direction: codeDir,
17594
+ textAlign: "start"
17473
17595
  },
17474
- codeTagProps: { style: { fontFamily: MONO_FONT_FAMILY, fontSize: "12px", lineHeight: "1.6" } },
17596
+ codeTagProps: { style: { fontFamily: MONO_FONT_FAMILY, fontSize: "12px", lineHeight: "1.6", direction: codeDir, textAlign: "start" } },
17475
17597
  children: activeCode
17476
17598
  }
17477
17599
  ),
17478
- [activeCode, viewerOverCapacity, viewerPlainCodeColor, activeLanguage, viewerStyle, wrap, showLineNumbers, viewerLineProps, languageReady]
17600
+ [activeCode, viewerOverCapacity, viewerPlainCodeColor, activeLanguage, viewerStyle, wrap, showLineNumbers, viewerLineProps, languageReady, codeDir]
17479
17601
  );
17480
17602
  const diffOverCapacity = React93.useMemo(
17481
17603
  () => !!diffLines && diffLines.reduce((n, l) => n + l.content.length + 1, 0) > HIGHLIGHT_CAPACITY_BYTES,
@@ -17745,33 +17867,35 @@ var init_CodeBlock = __esm({
17745
17867
  ]
17746
17868
  }
17747
17869
  ),
17748
- /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "overflow-auto bg-muted/20", style: { maxHeight }, dir: "ltr", children: diffLines ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children: diffRowElements }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-xs", children: viewerHighlightedElement }) })
17870
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "overflow-auto bg-muted/20", style: { maxHeight }, dir: codeDir, children: diffLines ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children: diffRowElements }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-xs", children: viewerHighlightedElement }) })
17749
17871
  ] }) });
17750
17872
  }
17751
- const hasHeader = showLanguageBadge || effectiveCopy;
17873
+ const hasHeader = showLanguageBadge;
17874
+ const copyButton = effectiveCopy ? /* @__PURE__ */ jsxRuntime.jsx(
17875
+ Button,
17876
+ {
17877
+ variant: "ghost",
17878
+ size: "sm",
17879
+ onClick: handleCopy,
17880
+ className: `opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity text-muted-foreground hover:text-foreground${hasHeader ? "" : " absolute top-2 end-2 z-10"}`,
17881
+ "aria-label": t("common.copy"),
17882
+ children: copied ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "check", className: "w-4 h-4 text-success" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "copy", className: "w-4 h-4" })
17883
+ }
17884
+ ) : null;
17752
17885
  return /* @__PURE__ */ jsxRuntime.jsxs(Box, { ...domPassthrough(a11yRest), className: `relative group not-prose ${className || ""}`, style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
17753
- hasHeader && /* @__PURE__ */ jsxRuntime.jsxs(
17886
+ hasHeader ? /* @__PURE__ */ jsxRuntime.jsxs(
17754
17887
  HStack,
17755
17888
  {
17756
17889
  justify: "between",
17757
17890
  align: "center",
17758
17891
  className: "px-3 py-2 bg-[var(--color-card)] rounded-t-container border-b border-border",
17892
+ "data-testid": "code-block-header",
17759
17893
  children: [
17760
- showLanguageBadge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: language }),
17761
- effectiveCopy && /* @__PURE__ */ jsxRuntime.jsx(
17762
- Button,
17763
- {
17764
- variant: "ghost",
17765
- size: "sm",
17766
- onClick: handleCopy,
17767
- className: "opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity text-muted-foreground hover:text-foreground",
17768
- "aria-label": t("common.copy"),
17769
- children: copied ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "check", className: "w-4 h-4 text-success" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "copy", className: "w-4 h-4" })
17770
- }
17771
- )
17894
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: language }),
17895
+ copyButton
17772
17896
  ]
17773
17897
  }
17774
- ),
17898
+ ) : copyButton,
17775
17899
  naturalTabStrip,
17776
17900
  editable ? (
17777
17901
  /* GAP-77 / GAP-82 / GAP-83: editable mode = transparent textarea on
@@ -32428,7 +32552,7 @@ function DataList({
32428
32552
  return f3.variant === "badge" ? (
32429
32553
  // `format` applies here too — a boolean field badged
32430
32554
  // without it renders the raw "false" instead of "No".
32431
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: badgeVariantFor(String(v), f3.colorMap), children: formatValue2(v, f3.format, fmt2, relationsData?.[f3.name]) }, f3.name)
32555
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: badgeVariantFor(String(v), f3.colorMap), children: valueLabelFor(formatValue2(v, f3.format, fmt2, relationsData?.[f3.name]), f3.labels) }, f3.name)
32432
32556
  ) : /* @__PURE__ */ jsxRuntime.jsx(
32433
32557
  Typography,
32434
32558
  {
@@ -32591,7 +32715,7 @@ function DataList({
32591
32715
  if (val === void 0 || val === null || val === "") return null;
32592
32716
  return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
32593
32717
  field.icon && renderIconInput2(field.icon, { size: "xs" }),
32594
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: badgeVariantFor(String(val), field.colorMap), children: formatValue2(val, field.format, fmt2, relationsData?.[field.name]) })
32718
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: badgeVariantFor(String(val), field.colorMap), children: valueLabelFor(formatValue2(val, field.format, fmt2, relationsData?.[field.name]), field.labels) })
32595
32719
  ] }, field.name);
32596
32720
  })
32597
32721
  ] }),
@@ -33140,13 +33264,13 @@ var init_MapView = __esm({
33140
33264
  shadowSize: [41, 41]
33141
33265
  });
33142
33266
  L.Marker.prototype.options.icon = defaultIcon;
33143
- const { useEffect: useEffect81, useRef: useRef85, useCallback: useCallback106, useState: useState117 } = React93__namespace.default;
33267
+ const { useEffect: useEffect82, useRef: useRef85, useCallback: useCallback107, useState: useState118 } = React93__namespace.default;
33144
33268
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
33145
33269
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
33146
33270
  function MapUpdater({ centerLat, centerLng, zoom }) {
33147
33271
  const map = useMap();
33148
33272
  const prevRef = useRef85({ centerLat, centerLng, zoom });
33149
- useEffect81(() => {
33273
+ useEffect82(() => {
33150
33274
  const prev = prevRef.current;
33151
33275
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
33152
33276
  map.setView([centerLat, centerLng], zoom);
@@ -33157,7 +33281,7 @@ var init_MapView = __esm({
33157
33281
  }
33158
33282
  function MapClickHandler({ onMapClick }) {
33159
33283
  const map = useMap();
33160
- useEffect81(() => {
33284
+ useEffect82(() => {
33161
33285
  if (!onMapClick) return;
33162
33286
  const handler = (e) => {
33163
33287
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -33188,8 +33312,8 @@ var init_MapView = __esm({
33188
33312
  }) {
33189
33313
  const contentSurface = providers.useContentSurface(surface);
33190
33314
  const eventBus = useEventBus2();
33191
- const [clickedPosition, setClickedPosition] = useState117(null);
33192
- const handleMapClick = useCallback106((lat, lng) => {
33315
+ const [clickedPosition, setClickedPosition] = useState118(null);
33316
+ const handleMapClick = useCallback107((lat, lng) => {
33193
33317
  if (showClickedPin) {
33194
33318
  setClickedPosition({ lat, lng });
33195
33319
  }
@@ -33198,7 +33322,7 @@ var init_MapView = __esm({
33198
33322
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
33199
33323
  }
33200
33324
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
33201
- const handleMarkerClick = useCallback106((marker) => {
33325
+ const handleMarkerClick = useCallback107((marker) => {
33202
33326
  onMarkerClick?.(marker);
33203
33327
  if (markerClickEvent) {
33204
33328
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -35830,7 +35954,7 @@ var init_DocSidebar = __esm({
35830
35954
  className: cn(
35831
35955
  "h-auto w-full justify-start rounded-interactive px-3 py-1.5 text-sm font-normal",
35832
35956
  depth > 0 && "ml-2",
35833
- item.active ? "bg-primary/8 text-foreground font-semibold" : "text-muted-foreground"
35957
+ item.active ? "bg-primary/[0.08] text-foreground font-semibold" : "text-muted-foreground"
35834
35958
  ),
35835
35959
  children: label
35836
35960
  }
@@ -44198,11 +44322,23 @@ var init_Header = __esm({
44198
44322
  variant = "mobile",
44199
44323
  look = "compact-bar",
44200
44324
  onLogoClick,
44325
+ brandHref,
44201
44326
  className,
44202
44327
  ...rest
44203
44328
  }) => {
44204
44329
  const { t } = hooks.useTranslate();
44205
44330
  const resolvedSearchPlaceholder = searchPlaceholder ?? t("common.search");
44331
+ const brandContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
44332
+ logo ? typeof logo === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: logo, alt: brandName, size: "sm" }) : logo : logoSrc ? /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: logoSrc, alt: brandName, size: "sm" }) : null,
44333
+ brandName && /* @__PURE__ */ jsxRuntime.jsx(
44334
+ Typography,
44335
+ {
44336
+ variant: "h5",
44337
+ className: "text-lg text-foreground",
44338
+ children: brandName
44339
+ }
44340
+ )
44341
+ ] });
44206
44342
  const userInitials = userAvatar?.initials || userName?.[0]?.toUpperCase() || "U";
44207
44343
  return /* @__PURE__ */ jsxRuntime.jsxs(
44208
44344
  Box,
@@ -44229,7 +44365,16 @@ var init_Header = __esm({
44229
44365
  children: isMenuOpen ? /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.X, { size: 24 }) : /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.Menu, { size: 24 })
44230
44366
  }
44231
44367
  ),
44232
- /* @__PURE__ */ jsxRuntime.jsxs(
44368
+ brandHref ? /* @__PURE__ */ jsxRuntime.jsx(
44369
+ Button,
44370
+ {
44371
+ variant: "ghost",
44372
+ href: brandHref,
44373
+ "aria-label": brandName,
44374
+ className: "gap-2 px-0 hover:bg-transparent",
44375
+ children: brandContent
44376
+ }
44377
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
44233
44378
  HStack,
44234
44379
  {
44235
44380
  gap: "none",
@@ -44240,17 +44385,7 @@ var init_Header = __esm({
44240
44385
  ),
44241
44386
  ...pressableProps(onLogoClick),
44242
44387
  "aria-label": onLogoClick ? brandName : void 0,
44243
- children: [
44244
- logo ? typeof logo === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: logo, alt: brandName, size: "sm" }) : logo : logoSrc ? /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: logoSrc, alt: brandName, size: "sm" }) : null,
44245
- brandName && /* @__PURE__ */ jsxRuntime.jsx(
44246
- Typography,
44247
- {
44248
- variant: "h5",
44249
- className: "text-lg text-foreground",
44250
- children: brandName
44251
- }
44252
- )
44253
- ]
44388
+ children: brandContent
44254
44389
  }
44255
44390
  )
44256
44391
  ] }),
@@ -54243,8 +54378,8 @@ var init_VersionDiff = __esm({
54243
54378
  }
54244
54379
  ),
54245
54380
  /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "overflow-auto bg-muted/20", style: { maxHeight: 600 }, children: isEmpty ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "py-8", "data-testid": "version-diff-empty", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", color: "muted", align: "center", children: t("versionDiff.noChanges") }) }) : activeView === "side-by-side" ? /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "grid grid-cols-1 md:grid-cols-2", children: [
54246
- /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "border-b md:border-b-0 md:border-r border-border", "data-testid": "version-diff-before", children: renderColumn("before") }),
54247
- /* @__PURE__ */ jsxRuntime.jsx(Box, { "data-testid": "version-diff-after", children: renderColumn("after") })
54381
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "min-w-0 overflow-x-auto border-b md:border-b-0 md:border-r border-border", "data-testid": "version-diff-before", children: renderColumn("before") }),
54382
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "min-w-0 overflow-x-auto", "data-testid": "version-diff-after", children: renderColumn("after") })
54248
54383
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(VStack, { gap: "none", className: "font-mono text-xs", children: shown.map((row, idx) => {
54249
54384
  if (row.kind === "header") return renderHeader(row.header, `i-h-${idx}`);
54250
54385
  if (row.kind === "gap") return renderGap(row, `i-g-${row.id}`);
@@ -55395,6 +55530,7 @@ function UISlotComponentInner({
55395
55530
  const awaiting = isPortalSlot(slot) ? void 0 : awaitingSkeleton ?? runtimeAwaiting;
55396
55531
  const regionClassName = fallback !== void 0 ? cn("contents", className) : className;
55397
55532
  const binding = providers.useEntityBindingSnapshot(rawContent?.sourceTrait);
55533
+ const i18n = hooks.useRenderI18n();
55398
55534
  const content = React93.useMemo(() => {
55399
55535
  if (!rawContent) return rawContent;
55400
55536
  const resolvedProps = resolveRenderBindingMarkers(
@@ -55402,10 +55538,11 @@ function UISlotComponentInner({
55402
55538
  rawContent.sourceTrait,
55403
55539
  binding.entity,
55404
55540
  binding.config,
55405
- binding.state
55541
+ binding.state,
55542
+ i18n
55406
55543
  );
55407
55544
  return resolvedProps === rawContent.props ? rawContent : { ...rawContent, props: resolvedProps };
55408
- }, [rawContent, binding.entity, binding.config, binding.state]);
55545
+ }, [rawContent, binding.entity, binding.config, binding.state, i18n]);
55409
55546
  const animatedPortal = isAnimatedPortalSlot(slot);
55410
55547
  const holdForPending = useScopeHasPending(React93.useContext(PendingScopeContext));
55411
55548
  const runtimePresence = useSlotPresence(portal && animatedPortal ? content ?? null : null, holdForPending);
@@ -56043,9 +56180,10 @@ function SlotContentRenderer({
56043
56180
  const ambientScope = providers.useTraitScope();
56044
56181
  const bindingTrait = content.sourceTrait ?? ambientScope?.trait;
56045
56182
  const binding = providers.useEntityBindingSnapshot(bindingTrait);
56183
+ const i18n = hooks.useRenderI18n();
56046
56184
  const liveProps = React93.useMemo(
56047
- () => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state),
56048
- [content.props, bindingTrait, binding.entity, binding.config, binding.state]
56185
+ () => resolveRenderBindingMarkers(content.props, bindingTrait, binding.entity, binding.config, binding.state, i18n),
56186
+ [content.props, bindingTrait, binding.entity, binding.config, binding.state, i18n]
56049
56187
  );
56050
56188
  const propsObj = typeof liveProps === "string" ? {} : liveProps;
56051
56189
  const entityProp = propsObj.entity;
@@ -60174,13 +60312,18 @@ function stateOptionsFor(schema, orbitalName, entityName, transitions, view, moc
60174
60312
  const key = `${s.entry.traitName}|${s.entry.transition.to}`;
60175
60313
  stateUses.set(key, (stateUses.get(key) ?? 0) + 1);
60176
60314
  }
60315
+ const armsSeen = /* @__PURE__ */ new Map();
60177
60316
  return screens.map(({ entry, enteredBy }) => {
60178
60317
  const t = entry.transition;
60179
60318
  const from = String(t.from);
60180
60319
  const state = view === "screens" ? (stateUses.get(`${entry.traitName}|${t.to}`) ?? 0) > 1 ? `${t.to} \xB7 ${t.event}` : t.to : `${t.event}: ${from} \u2192 ${t.to}`;
60181
- const label = manyTraits ? `${entry.traitName} \xB7 ${state}` : state;
60320
+ const baseId = `${entry.traitName}:${t.event}:${from}:${t.to}`;
60321
+ const arm = (armsSeen.get(baseId) ?? 0) + 1;
60322
+ armsSeen.set(baseId, arm);
60323
+ const named = manyTraits ? `${entry.traitName} \xB7 ${state}` : state;
60324
+ const label = arm > 1 ? `${named} (guard ${arm})` : named;
60182
60325
  return {
60183
- id: `${entry.traitName}:${t.event}:${from}:${t.to}`,
60326
+ id: arm > 1 ? `${baseId}#${arm}` : baseId,
60184
60327
  label,
60185
60328
  hint: view === "screens" ? enteredBy.join(" \xB7 ") : entry.traitName,
60186
60329
  data: {
@@ -60587,6 +60730,10 @@ I18nContext.displayName = "I18nContext";
60587
60730
  function useTranslate157() {
60588
60731
  return React93.useContext(I18nContext);
60589
60732
  }
60733
+ function useRenderI18n2() {
60734
+ const { locale, messages } = React93.useContext(I18nContext);
60735
+ return React93.useMemo(() => messages !== void 0 ? { locale, messages } : void 0, [locale, messages]);
60736
+ }
60590
60737
 
60591
60738
  // hooks/useInlineTextEdit.ts
60592
60739
  init_inlineText();
@@ -61154,11 +61301,11 @@ function marqueeHits(marquee, boxes) {
61154
61301
  );
61155
61302
  }
61156
61303
  function axisPositionFrom(axis, constraint, offset) {
61157
- const start = offset ? axis === "x" ? offset.left : offset.top : 0;
61158
- const end = offset ? axis === "x" ? offset.right : offset.bottom : 0;
61304
+ const start = axis === "x" ? offset.left : offset.top;
61305
+ const end = axis === "x" ? offset.right : offset.bottom;
61159
61306
  if (constraint === "center") return { constraint, start: (start - end) / 2, end: 0 };
61160
61307
  if (constraint !== "scale") return { constraint, start, end };
61161
- const size2 = offset ? axis === "x" ? offset.parentWidth : offset.parentHeight : 0;
61308
+ const size2 = axis === "x" ? offset.parentWidth : offset.parentHeight;
61162
61309
  return size2 > 0 ? { constraint, start: start / size2 * 100, end: end / size2 * 100 } : { constraint, start: 0, end: 0 };
61163
61310
  }
61164
61311
  var edgesX = (r2) => [r2.left, r2.left + r2.width / 2, r2.left + r2.width];
@@ -61739,9 +61886,9 @@ function getTabClientId() {
61739
61886
  return tabClientId;
61740
61887
  }
61741
61888
  var log11 = logger.createLogger("almadar:ui:circuit-kernel");
61742
- function postUnmounts(transport, traits2) {
61889
+ function postUnmounts(transport, traits2, locale) {
61743
61890
  for (const [traitName, orbitalName] of traits2) {
61744
- transport.send(orbitalName, { event: runtime.UNMOUNT_EVENT, targetTrait: traitName, clientId: getTabClientId() }).catch((err) => log11.warn("unmount-post-failed", { trait: traitName, orbital: orbitalName, error: String(err) }));
61891
+ transport.send(orbitalName, { event: runtime.UNMOUNT_EVENT, targetTrait: traitName, clientId: getTabClientId(), locale }).catch((err) => log11.warn("unmount-post-failed", { trait: traitName, orbital: orbitalName, error: String(err) }));
61745
61892
  }
61746
61893
  }
61747
61894
  function restrictTraitIndex(full, activeNames) {
@@ -61762,6 +61909,10 @@ function useCircuitKernel(traitBindings, options) {
61762
61909
  [activeTraitKey, fullTraitIndex]
61763
61910
  );
61764
61911
  const mountedRef = React93.useRef(/* @__PURE__ */ new Map());
61912
+ const { locale } = useTranslate157();
61913
+ const i18n = useRenderI18n2();
61914
+ const localeRef = React93.useRef(locale);
61915
+ localeRef.current = locale;
61765
61916
  const transport = options.transport;
61766
61917
  const topologyPending = options.awaitTopology === true;
61767
61918
  React93.useEffect(() => {
@@ -61770,12 +61921,12 @@ function useCircuitKernel(traitBindings, options) {
61770
61921
  const dropped = [...mounted].filter(([name]) => !traitIndex.byName.has(name));
61771
61922
  mounted.clear();
61772
61923
  for (const [name, entry] of traitIndex.byName) mounted.set(name, entry.orbitalName);
61773
- postUnmounts(transport, dropped);
61924
+ postUnmounts(transport, dropped, localeRef.current);
61774
61925
  }, [traitIndex, transport, topologyPending]);
61775
61926
  React93.useEffect(() => {
61776
61927
  if (transport === void 0) return;
61777
61928
  const mounted = mountedRef.current;
61778
- return () => postUnmounts(transport, [...mounted]);
61929
+ return () => postUnmounts(transport, [...mounted], localeRef.current);
61779
61930
  }, [transport]);
61780
61931
  const store = React93.useMemo(() => {
61781
61932
  const traitDefs = Array.from(traitIndex.byName.values(), (entry) => entry.traitDef);
@@ -61786,42 +61937,43 @@ function useCircuitKernel(traitBindings, options) {
61786
61937
  };
61787
61938
  return runtime.createMemoryCircuitStore(traitDefs, config, options.observer);
61788
61939
  }, [traitIndex, options.guardMode, options.strictBindings, options.contextExtensions, options.observer]);
61789
- const offlineTransport = React93.useMemo(() => {
61790
- if (options.transport !== void 0 || options.persistence === void 0) return void 0;
61791
- const persistence = options.persistence;
61792
- return runtime.createInProcessTransport(
61793
- async (_orbitalName, request) => {
61794
- const runEffects = runtime.createIndexStageRunner({
61795
- traitIndex,
61796
- persistence,
61797
- frames: store.frames,
61798
- manager: store.manager,
61799
- ...options.callService !== void 0 ? { extraEffectHandlers: { callService: options.callService } } : {},
61800
- ...options.debug !== void 0 ? { debug: options.debug } : {}
61801
- });
61802
- return runtime.evaluateOrbitalEvent(
61803
- {
61804
- traitIndex,
61805
- manager: store.manager,
61806
- persistence,
61807
- frames: store.frames,
61808
- runEffects,
61809
- ...options.user !== void 0 ? { user: options.user } : {},
61810
- ...options.guardMode !== void 0 ? { guardMode: options.guardMode } : {},
61811
- ...options.strictBindings !== void 0 ? { strictBindings: options.strictBindings } : {},
61812
- ...options.contextExtensions !== void 0 ? { contextExtensions: options.contextExtensions } : {},
61813
- ...options.debug !== void 0 ? { debug: options.debug } : {},
61814
- ...options.logContext !== void 0 ? { logContext: options.logContext } : {}
61815
- },
61816
- request
61817
- );
61818
- },
61819
- { carriesCircuitState: false }
61820
- );
61940
+ const localTransportOptions = {
61941
+ traitIndex,
61942
+ store,
61943
+ ...options.callService !== void 0 ? { callService: options.callService } : {},
61944
+ ...options.user !== void 0 ? { user: options.user } : {},
61945
+ ...options.guardMode !== void 0 ? { guardMode: options.guardMode } : {},
61946
+ ...options.strictBindings !== void 0 ? { strictBindings: options.strictBindings } : {},
61947
+ ...options.contextExtensions !== void 0 ? { contextExtensions: options.contextExtensions } : {},
61948
+ ...options.debug !== void 0 ? { debug: options.debug } : {},
61949
+ ...options.logContext !== void 0 ? { logContext: options.logContext } : {}
61950
+ };
61951
+ const offlineTransport = React93.useMemo(
61952
+ () => options.transport !== void 0 || options.persistence === void 0 ? void 0 : runtime.createLocalStoreTransport({ ...localTransportOptions, persistence: options.persistence }),
61953
+ [
61954
+ options.transport,
61955
+ options.persistence,
61956
+ traitIndex,
61957
+ store,
61958
+ options.callService,
61959
+ options.user,
61960
+ options.guardMode,
61961
+ options.strictBindings,
61962
+ options.contextExtensions,
61963
+ options.debug,
61964
+ options.logContext
61965
+ ]
61966
+ );
61967
+ const routedTransport = React93.useMemo(() => {
61968
+ if (options.browserStore === void 0) return void 0;
61969
+ const local = runtime.createLocalStoreTransport({ ...localTransportOptions, traitIndex: fullTraitIndex, persistence: options.browserStore, clientRelays: true });
61970
+ const remote = options.transport ?? offlineTransport;
61971
+ return runtime.createResidenceTransport({ local, ...remote !== void 0 ? { remote } : {}, traitIndex: fullTraitIndex });
61821
61972
  }, [
61973
+ options.browserStore,
61822
61974
  options.transport,
61823
- options.persistence,
61824
- traitIndex,
61975
+ offlineTransport,
61976
+ fullTraitIndex,
61825
61977
  store,
61826
61978
  options.callService,
61827
61979
  options.user,
@@ -61831,7 +61983,7 @@ function useCircuitKernel(traitBindings, options) {
61831
61983
  options.debug,
61832
61984
  options.logContext
61833
61985
  ]);
61834
- const baseTransport = options.transport ?? offlineTransport;
61986
+ const baseTransport = routedTransport ?? options.transport ?? offlineTransport;
61835
61987
  const effectiveTransport = React93.useMemo(
61836
61988
  () => baseTransport === void 0 ? void 0 : recordingTransport(baseTransport),
61837
61989
  [baseTransport]
@@ -61856,6 +62008,8 @@ function useCircuitKernel(traitBindings, options) {
61856
62008
  store,
61857
62009
  ...options.persistence !== void 0 ? { persistence: options.persistence } : {},
61858
62010
  ...options.user !== void 0 ? { user: options.user } : {},
62011
+ locale,
62012
+ ...i18n !== void 0 ? { messages: { [i18n.locale]: i18n.messages } } : {},
61859
62013
  ...options.guardMode !== void 0 ? { guardMode: options.guardMode } : {},
61860
62014
  ...options.strictBindings !== void 0 ? { strictBindings: options.strictBindings } : {},
61861
62015
  ...options.contextExtensions !== void 0 ? { contextExtensions: options.contextExtensions } : {},
@@ -61871,6 +62025,8 @@ function useCircuitKernel(traitBindings, options) {
61871
62025
  store,
61872
62026
  options.persistence,
61873
62027
  options.user,
62028
+ locale,
62029
+ i18n,
61874
62030
  options.guardMode,
61875
62031
  options.strictBindings,
61876
62032
  options.contextExtensions,
@@ -61879,12 +62035,19 @@ function useCircuitKernel(traitBindings, options) {
61879
62035
  topology,
61880
62036
  effectiveTransport
61881
62037
  ]);
61882
- const kernel = React93.useMemo(() => ({
61883
- store: rawKernel.store,
61884
- dispatch: (request, hooks) => rawKernel.dispatch(request.clientId !== void 0 ? request : { ...request, clientId: getTabClientId() }, hooks),
61885
- dispatchMount: (seeds, hooks, base = {}) => rawKernel.dispatchMount(seeds, hooks, base.clientId !== void 0 ? base : { ...base, clientId: getTabClientId() }),
61886
- dispatchProgress: (request) => rawKernel.dispatchProgress(request.clientId !== void 0 ? request : { ...request, clientId: getTabClientId() })
61887
- }), [rawKernel]);
62038
+ const kernel = React93.useMemo(() => {
62039
+ const stamp = (request) => ({
62040
+ ...request,
62041
+ clientId: request.clientId ?? getTabClientId(),
62042
+ locale: request.locale ?? locale
62043
+ });
62044
+ return {
62045
+ store: rawKernel.store,
62046
+ dispatch: (request, hooks) => rawKernel.dispatch(stamp(request), hooks),
62047
+ dispatchMount: (seeds, hooks, base = {}) => rawKernel.dispatchMount(seeds, hooks, stamp(base)),
62048
+ dispatchProgress: (request) => rawKernel.dispatchProgress(stamp(request))
62049
+ };
62050
+ }, [rawKernel, locale]);
61888
62051
  return { kernel, store, traitIndex, transport: effectiveTransport };
61889
62052
  }
61890
62053
 
@@ -62368,11 +62531,12 @@ async function runCircuitEffects(params) {
62368
62531
  // hooks/circuit/useCallsiteCapture.ts
62369
62532
  var log14 = logger.createLogger("almadar:ui:circuit:callsite-capture");
62370
62533
  function useCallsiteCapture(traitBindings, store, traitIndex, slotFlush, options) {
62371
- return React93.useCallback(async function reRender(traitName, callsitePayload, entityByTrait, visited = /* @__PURE__ */ new Set(), serverComposed = /* @__PURE__ */ new Set(), keepComposed = false) {
62534
+ return React93.useCallback(async function reRender(traitName, callsitePayload, entityByTrait, visited = /* @__PURE__ */ new Set(), serverComposed = /* @__PURE__ */ new Set(), keepComposed = false, composedBy) {
62372
62535
  const children = options.callsiteCaptureChildrenByTrait?.get(traitName);
62373
62536
  if (!children || children.size === 0) return;
62374
62537
  const bindingMap = new Map(traitBindings.map((b) => [b.trait.name, b]));
62375
62538
  for (const childName of children) {
62539
+ if (composedBy !== void 0 && !composedBy.has(childName)) continue;
62376
62540
  if (visited.has(childName)) continue;
62377
62541
  visited.add(childName);
62378
62542
  const childBinding = bindingMap.get(childName);
@@ -62426,7 +62590,7 @@ function useCallsiteCapture(traitBindings, store, traitIndex, slotFlush, options
62426
62590
  { event: lifecycleEvent, state: entry.result.previousState, entity: childBinding.linkedEntity }
62427
62591
  );
62428
62592
  }
62429
- await reRender(childName, composedWith, entityByTrait, visited, serverComposed, keepComposed);
62593
+ await reRender(childName, composedWith, entityByTrait, visited, serverComposed, keepComposed, core.traitsEmbeddedByEffects(indexed.irTrait, entry.result.effects));
62430
62594
  }
62431
62595
  }, [traitBindings, store, traitIndex, slotFlush, options.callsiteCaptureChildrenByTrait, options.eventBus, options.navigate, options.navigateBack, options.user]);
62432
62596
  }
@@ -62720,6 +62884,7 @@ function useAwaitingSkeletonSource(store, traitIndex, embeddedTraits) {
62720
62884
  }
62721
62885
 
62722
62886
  // hooks/useTraitStateMachine.ts
62887
+ var MOUNT_ERROR_SOURCE = "$mount";
62723
62888
  var stateLog = logger.createLogger("almadar:ui:state-transitions");
62724
62889
  function diffDroppedTraitNames(prev, next) {
62725
62890
  const dropped = [];
@@ -62734,6 +62899,7 @@ function normalizeEventKey(eventKey) {
62734
62899
  function useTraitStateMachine(traitBindings, uiSlots, options) {
62735
62900
  const eventBus = useEventBus();
62736
62901
  const { user: contextViewer } = providers.useUser();
62902
+ const { t } = useTranslate157();
62737
62903
  const userContext = options.user ?? contextViewer ?? void 0;
62738
62904
  const observer2 = React93.useMemo(() => createCircuitVerificationObserver(), []);
62739
62905
  const { kernel, store, traitIndex, transport } = useCircuitKernel(traitBindings, {
@@ -62743,6 +62909,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
62743
62909
  ...options.carriesCircuitState !== void 0 ? { carriesCircuitState: options.carriesCircuitState } : {},
62744
62910
  ...options.awaitTopology !== void 0 ? { awaitTopology: options.awaitTopology } : {},
62745
62911
  ...options.persistence !== void 0 ? { persistence: options.persistence } : {},
62912
+ ...options.browserStore !== void 0 ? { browserStore: options.browserStore } : {},
62746
62913
  ...options.callService !== void 0 ? { callService: options.callService } : {},
62747
62914
  ...userContext !== void 0 ? { user: userContext } : {},
62748
62915
  ...options.debug !== void 0 ? { debug: options.debug } : {},
@@ -62781,11 +62948,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
62781
62948
  name: trait.name,
62782
62949
  currentState: state?.currentState ?? trait.states[0]?.name ?? "unknown",
62783
62950
  states: trait.states.map((s) => s.name),
62784
- transitions: trait.transitions.flatMap((t) => {
62785
- const froms = Array.isArray(t.from) ? t.from : [t.from];
62786
- return froms.map((f3) => ({ from: f3, to: t.to, event: t.event, guard: t.guard ? String(t.guard) : void 0 }));
62951
+ transitions: trait.transitions.flatMap((t2) => {
62952
+ const froms = Array.isArray(t2.from) ? t2.from : [t2.from];
62953
+ return froms.map((f3) => ({ from: f3, to: t2.to, event: t2.event, guard: t2.guard ? String(t2.guard) : void 0 }));
62787
62954
  }),
62788
- guards: trait.transitions.filter((t) => t.guard).map((t) => ({ name: String(t.guard) })),
62955
+ guards: trait.transitions.filter((t2) => t2.guard).map((t2) => ({ name: String(t2.guard) })),
62789
62956
  transitionCount: 0
62790
62957
  };
62791
62958
  registerTrait(info);
@@ -62823,7 +62990,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
62823
62990
  }
62824
62991
  const repainted = new Set(repaints.map((e) => e.traitName));
62825
62992
  const serverComposed = new Set([...store.callsitePayloads].filter(([child, composed]) => composedBefore.get(child) !== composed).map(([child]) => child));
62826
- await reRenderCallsiteCaptureChildren(traitName, payload ?? {}, entityByTrait, repainted, serverComposed);
62993
+ const irTrait = traitIndex.byName.get(traitName)?.irTrait;
62994
+ const composedBy = irTrait !== void 0 ? core.traitsEmbeddedByEvent(irTrait, eventKey) : void 0;
62995
+ await reRenderCallsiteCaptureChildren(traitName, payload ?? {}, entityByTrait, repainted, serverComposed, false, composedBy);
62827
62996
  }
62828
62997
  options.onEventProcessed?.(eventKey, payload);
62829
62998
  }, [traitIndex, store, reRenderCallsiteCaptureChildren, options.onEventProcessed]);
@@ -62892,8 +63061,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
62892
63061
  React93.useEffect(() => {
62893
63062
  if (!transport?.subscribe) return;
62894
63063
  return transport.subscribe((emitted, target) => {
62895
- for (const t of runtime.collectListenerTargets(traitIndex, emitted.source, emitted.event, emitted.payload)) {
62896
- void (target === "origin" ? progressAndSettle(t.listenerTrait, t.triggers, t.payload) : dispatchAndSettle(t.listenerTrait, t.triggers, t.payload));
63064
+ for (const t2 of runtime.collectListenerTargets(traitIndex, emitted.source, emitted.event, emitted.payload)) {
63065
+ void (target === "origin" ? progressAndSettle(t2.listenerTrait, t2.triggers, t2.payload) : dispatchAndSettle(t2.listenerTrait, t2.triggers, t2.payload));
62897
63066
  }
62898
63067
  }, { clientId: getTabClientId() });
62899
63068
  }, [transport, traitIndex, progressAndSettle, dispatchAndSettle]);
@@ -62965,26 +63134,75 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
62965
63134
  for (const traitName of left) mount.initialized.delete(traitName);
62966
63135
  store.mount.unmounted(left);
62967
63136
  const entering = [];
63137
+ const embeddedChildren = new Set([...options.callsiteCaptureChildrenByTrait?.values() ?? []].flatMap((c) => [...c]));
62968
63138
  for (const binding of traitBindings) {
62969
63139
  const traitName = binding.trait.name;
62970
63140
  if (mount.initialized.has(traitName)) continue;
62971
63141
  mount.initialized.add(traitName);
63142
+ const indexed = traitIndex.byName.get(traitName);
63143
+ if (embeddedChildren.has(traitName) && indexed !== void 0 && (core.traitReferencesCallsitePayload(indexed.irTrait) || core.configReferencesCallsitePayload(indexed.config)) && store.manager.repaintLifecycleEvent(traitName) !== void 0 && !store.callsitePayloads.has(traitName)) {
63144
+ continue;
63145
+ }
62972
63146
  const lifecycleEvent = runtime.LIFECYCLE_EVENTS.find((evt) => store.manager.canHandleEvent(traitName, evt));
62973
63147
  if (lifecycleEvent !== void 0) entering.push({ trait: traitName, event: lifecycleEvent });
62974
63148
  }
62975
63149
  store.mount.mounting(entering.map((e) => e.trait));
62976
63150
  if (entering.length > 0) {
63151
+ uiSlots.clearBySource("main", MOUNT_ERROR_SOURCE);
62977
63152
  void mountAndSettle(entering, { ...options.initPayload ?? {} }).catch((err) => {
62978
- stateLog.warn("mount:failed", { traits: entering.map((e) => e.trait), error: String(err) });
63153
+ const traits2 = entering.map((e) => e.trait);
63154
+ const message = err instanceof Error ? err.message : String(err);
63155
+ const failed = err instanceof runtime.TraitMountError ? err.trait : traits2.join(", ");
63156
+ const cause = err instanceof runtime.TraitMountError ? err.original : err;
63157
+ stateLog.warn("mount:failed", { traits: traits2, failed, error: message, stack: cause instanceof Error ? cause.stack : void 0 });
63158
+ uiSlots.render({
63159
+ target: "main",
63160
+ pattern: "error-state",
63161
+ props: { title: t("error.traitMountFailed", { trait: failed }), message, "data-testid": core.TRAIT_MOUNT_ERROR_TESTID },
63162
+ sourceTrait: MOUNT_ERROR_SOURCE
63163
+ });
62979
63164
  });
62980
63165
  }
62981
63166
  mountedRef.current = mount;
62982
- }, [traitBindings, store, mountAndSettle, mountKey]);
63167
+ }, [traitBindings, store, mountAndSettle, mountKey, uiSlots, traitIndex, options.callsiteCaptureChildrenByTrait, t]);
62983
63168
  React93.useSyncExternalStore(store.subscribe, store.getVersion, store.getVersion);
62984
63169
  const traitStates = React93.useMemo(() => store.manager.getAllStates(), [store, store.getVersion()]);
62985
63170
  return { traitStates, sendEvent, getTraitState, canHandleEvent, entityBindingSource, awaitingSkeletonSource };
62986
63171
  }
62987
63172
 
63173
+ // runtime/OrbPreview.tsx
63174
+ init_LoadingState();
63175
+ init_ErrorState();
63176
+ function useBrowserStore(appName, orbitals, locale) {
63177
+ const entities = React93.useMemo(() => orbitals.flatMap(core.orbitalInlineEntities).filter(core.storesRowsInBrowser), [orbitals]);
63178
+ const [state, setState] = React93.useState(() => entities.length === 0 ? { status: "none" } : { status: "opening" });
63179
+ React93.useEffect(() => {
63180
+ if (entities.length === 0) {
63181
+ setState({ status: "none" });
63182
+ return;
63183
+ }
63184
+ let cancelled = false;
63185
+ let opened;
63186
+ setState({ status: "opening" });
63187
+ const open = async () => {
63188
+ try {
63189
+ const store = await runtime.openBrowserStore(runtime.browserStoreName(appName, locale), orbitals, void 0, locale);
63190
+ if (store === null) return;
63191
+ opened = store;
63192
+ if (!cancelled) setState({ status: "ready", store });
63193
+ } catch (err) {
63194
+ if (!cancelled) setState({ status: "failed", error: err instanceof Error ? err : new Error(String(err)) });
63195
+ }
63196
+ };
63197
+ void open();
63198
+ return () => {
63199
+ cancelled = true;
63200
+ opened?.close();
63201
+ };
63202
+ }, [appName, locale, entities, orbitals]);
63203
+ return state;
63204
+ }
63205
+
62988
63206
  // runtime/fitContent.ts
62989
63207
  var IDENTITY2 = { scale: 1, x: 0, y: 0 };
62990
63208
  function fitContentTransform(box, content) {
@@ -63043,7 +63261,7 @@ function appPathFromHref(href, hostHrefBase) {
63043
63261
  if (!href.startsWith(`${root}/`)) return null;
63044
63262
  return href.slice(root.length);
63045
63263
  }
63046
- function TraitInitializer({ traits: traits2, routeParams, mountKey, orbitals, onNavigate, onNavigateBack, onLocalFallback, localFallbackTimeoutMs, persistence, traitConfigsByName, embeddedTraits, callsiteCaptureChildrenByTrait, hasBridge, children }) {
63264
+ function TraitInitializer({ traits: traits2, routeParams, mountKey, orbitals, onNavigate, onNavigateBack, onLocalFallback, localFallbackTimeoutMs, persistence, browserStore, traitConfigsByName, embeddedTraits, callsiteCaptureChildrenByTrait, hasBridge, children }) {
63047
63265
  const bridge = providers.useServerBridge();
63048
63266
  const uiSlots = context.useUISlots();
63049
63267
  React93.useEffect(() => {
@@ -63062,7 +63280,8 @@ function TraitInitializer({ traits: traits2, routeParams, mountKey, orbitals, on
63062
63280
  ...callsiteCaptureChildrenByTrait !== void 0 ? { callsiteCaptureChildrenByTrait } : {},
63063
63281
  initPayload: routeParams,
63064
63282
  ...mountKey !== void 0 ? { mountKey } : {},
63065
- ...hasBridge ? { transport: bridge.transport, carriesCircuitState: bridge.carriesCircuitState, awaitTopology: !bridge.topologyKnown } : { persistence }
63283
+ ...hasBridge ? { transport: bridge.transport, carriesCircuitState: bridge.carriesCircuitState, awaitTopology: !bridge.topologyKnown } : { persistence },
63284
+ ...browserStore !== void 0 ? { browserStore } : {}
63066
63285
  });
63067
63286
  return /* @__PURE__ */ jsxRuntime.jsx(providers.EntityBindingContext.Provider, { value: entityBindingSource, children: /* @__PURE__ */ jsxRuntime.jsx(providers.AwaitingSkeletonContext.Provider, { value: awaitingSkeletonSource, children }) });
63068
63287
  }
@@ -63248,6 +63467,8 @@ function SchemaRunner({ schema, serverUrl, transport, getAccessToken, mockData,
63248
63467
  return set;
63249
63468
  }, [schema, pageName]);
63250
63469
  const activeOrbitalTheme = React93.useMemo(() => resolvePreviewTheme(schema, pageName), [schema, pageName]);
63470
+ const { locale } = hooks.useTranslate();
63471
+ const browserStore = useBrowserStore(schema.name ?? "app", schema.orbitals, locale);
63251
63472
  const inner = /* @__PURE__ */ jsxRuntime.jsx(providers.VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(
63252
63473
  providers.EntitySchemaProvider,
63253
63474
  {
@@ -63270,11 +63491,16 @@ function SchemaRunner({ schema, serverUrl, transport, getAccessToken, mockData,
63270
63491
  onLocalFallback,
63271
63492
  localFallbackTimeoutMs,
63272
63493
  persistence,
63494
+ ...browserStore.status === "ready" ? { browserStore: browserStore.store } : {},
63273
63495
  children: /* @__PURE__ */ jsxRuntime.jsx(providers.OrbitalThemeProvider, { theme: activeOrbitalTheme, override: themeOverride, children: /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "h-full min-h-full overflow-auto p-4", children: /* @__PURE__ */ jsxRuntime.jsx(UISlotRenderer, { includeHud: true, hudMode: "inline", includeFloating: true, pageKey: pageName }) }) })
63274
63496
  }
63275
63497
  )
63276
63498
  }
63277
63499
  ) });
63500
+ if (browserStore.status === "opening") return /* @__PURE__ */ jsxRuntime.jsx(LoadingState, {});
63501
+ if (browserStore.status === "failed") {
63502
+ return /* @__PURE__ */ jsxRuntime.jsx(ErrorState, { "data-testid": "browser-store-error", message: browserStore.error.message });
63503
+ }
63278
63504
  if (serverUrl || transport) {
63279
63505
  return /* @__PURE__ */ jsxRuntime.jsx(providers.ServerBridgeProvider, { schema, serverUrl, transport, getAccessToken, children: inner });
63280
63506
  }
@@ -63307,7 +63533,10 @@ function OrbPreview({
63307
63533
  onPageChange,
63308
63534
  user = null,
63309
63535
  localFallbackTimeoutMs,
63310
- themeOverride
63536
+ themeOverride,
63537
+ lazyLoader,
63538
+ schemaPath,
63539
+ onUnmatchedNavigate
63311
63540
  }) {
63312
63541
  if (serverUrl && transport) {
63313
63542
  throw new Error("OrbPreview accepts serverUrl OR transport, not both");
@@ -63356,12 +63585,44 @@ function OrbPreview({
63356
63585
  return [];
63357
63586
  }
63358
63587
  }, [parsedSchema]);
63588
+ const lazyPages = React93.useMemo(() => parsedSchema?.lazyPages ?? [], [parsedSchema]);
63589
+ const matchRoute = React93.useCallback((path) => {
63590
+ const candidates = [
63591
+ ...pages.map((entry) => ({ kind: "page", entry, path: entry.page.path })),
63592
+ ...lazyPages.map((page) => ({ kind: "lazy", page, path: page.path }))
63593
+ ];
63594
+ const hit = providers.matchPathAmong(candidates, path, (c) => c.path);
63595
+ if (!hit) return null;
63596
+ return hit.candidate.kind === "page" ? { kind: "page", entry: hit.candidate.entry, params: hit.params } : { kind: "lazy", page: hit.candidate.page, params: hit.params };
63597
+ }, [pages, lazyPages]);
63598
+ const initialRoute = React93.useMemo(
63599
+ () => initialPagePath ? matchRoute(initialPagePath) : null,
63600
+ [matchRoute, initialPagePath]
63601
+ );
63359
63602
  const initialPageMatch = React93.useMemo(() => {
63360
- if (!initialPagePath) return void 0;
63361
- const hit = providers.matchPathAmong(pages, initialPagePath, (entry) => entry.page.path);
63362
- if (!hit) return void 0;
63363
- return { name: hit.candidate.page.name, params: hit.params };
63364
- }, [pages, initialPagePath]);
63603
+ if (initialRoute?.kind !== "page" || !initialRoute.entry.page.name) return void 0;
63604
+ return { name: initialRoute.entry.page.name, params: initialRoute.params };
63605
+ }, [initialRoute]);
63606
+ const [lazyRoute, setLazyRoute] = React93.useState(
63607
+ initialRoute?.kind === "lazy" && initialPagePath ? { page: initialRoute.page, path: initialPagePath } : null
63608
+ );
63609
+ const [lazyLoad, setLazyLoad] = React93.useState({ status: "loading" });
63610
+ React93.useEffect(() => {
63611
+ if (!lazyRoute) return;
63612
+ if (!lazyLoader) {
63613
+ setLazyLoad({ status: "error", error: `No loader for lazy page ${lazyRoute.page.path} (${lazyRoute.page.orbRef})` });
63614
+ return;
63615
+ }
63616
+ let cancelled = false;
63617
+ setLazyLoad({ status: "loading" });
63618
+ void runtime.loadLazyPage(lazyLoader, lazyRoute.page, schemaPath).then((result) => {
63619
+ if (cancelled) return;
63620
+ setLazyLoad(result.success ? { status: "ready", schema: result.data } : { status: "error", error: result.error });
63621
+ });
63622
+ return () => {
63623
+ cancelled = true;
63624
+ };
63625
+ }, [lazyRoute?.page, lazyLoader, schemaPath]);
63365
63626
  const initialPageName = initialPageMatch?.name;
63366
63627
  const [currentPage, setCurrentPage] = React93.useState(initialPageName);
63367
63628
  const [routeParams, setRouteParams] = React93.useState(initialPageMatch?.params ?? {});
@@ -63371,8 +63632,9 @@ function OrbPreview({
63371
63632
  prevInitialPagePathRef.current = initialPagePath;
63372
63633
  setCurrentPage(initialPageName);
63373
63634
  setRouteParams(initialPageMatch?.params ?? {});
63635
+ setLazyRoute(initialRoute?.kind === "lazy" && initialPagePath ? { page: initialRoute.page, path: initialPagePath } : null);
63374
63636
  }
63375
- }, [initialPagePath, initialPageName, initialPageMatch]);
63637
+ }, [initialPagePath, initialPageName, initialPageMatch, initialRoute]);
63376
63638
  const currentPagePath = React93.useMemo(() => {
63377
63639
  const activePageName = currentPage ?? pages[0]?.page.name;
63378
63640
  const resolved = pages.find((p) => p.page.name === activePageName)?.page.path;
@@ -63387,10 +63649,30 @@ function OrbPreview({
63387
63649
  return pattern.replace(/:([A-Za-z0-9_]+)/g, (whole, key) => routeParams[key] ?? whole);
63388
63650
  }, [currentPagePath, routeParams]);
63389
63651
  const navStackRef = React93.useRef(null);
63652
+ const announcePage = React93.useCallback((path) => {
63653
+ if (onPageChange) {
63654
+ onPageChange(path);
63655
+ } else if (!isolated && typeof window !== "undefined") {
63656
+ const url = new URL(window.location.href);
63657
+ url.searchParams.set("page", path);
63658
+ window.history.pushState({}, "", url.toString());
63659
+ window.dispatchEvent(new PopStateEvent("popstate"));
63660
+ }
63661
+ }, [isolated, onPageChange]);
63390
63662
  const handleNavigate = React93.useCallback((path, navState) => {
63391
- const hit = providers.matchPathAmong(pages, path, (entry) => entry.page.path);
63392
- const match = hit?.candidate;
63393
- const params = { ...hit?.params ?? {}, ...navState ?? {} };
63663
+ const route = matchRoute(path);
63664
+ if (!route) {
63665
+ onUnmatchedNavigate?.(path);
63666
+ return;
63667
+ }
63668
+ if (route.kind === "lazy") {
63669
+ setLazyRoute({ page: route.page, path });
63670
+ announcePage(path);
63671
+ return;
63672
+ }
63673
+ setLazyRoute(null);
63674
+ const match = route.entry;
63675
+ const params = { ...route.params, ...navState ?? {} };
63394
63676
  navLog.debug("handleNavigate", () => ({
63395
63677
  path,
63396
63678
  matched: match?.page.name ?? null,
@@ -63398,19 +63680,12 @@ function OrbPreview({
63398
63680
  navState: navState ? JSON.stringify(navState) : void 0,
63399
63681
  availablePaths: pages.map((p) => p.page.path)
63400
63682
  }));
63401
- if (match?.page.name) {
63683
+ if (match.page.name) {
63402
63684
  setRouteParams(params);
63403
63685
  setCurrentPage(match.page.name);
63404
- if (onPageChange) {
63405
- onPageChange(path);
63406
- } else if (!isolated && typeof window !== "undefined") {
63407
- const url = new URL(window.location.href);
63408
- url.searchParams.set("page", path);
63409
- window.history.pushState({}, "", url.toString());
63410
- window.dispatchEvent(new PopStateEvent("popstate"));
63411
- }
63686
+ announcePage(path);
63412
63687
  }
63413
- }, [pages, isolated, onPageChange]);
63688
+ }, [pages, matchRoute, announcePage, onUnmatchedNavigate]);
63414
63689
  const handleNavigateEffect = React93.useCallback(
63415
63690
  (path, params, crumb) => {
63416
63691
  navStackRef.current?.beginNavigate(path, crumb);
@@ -63475,6 +63750,33 @@ function OrbPreview({
63475
63750
  navLog.info("interceptor:installed", { pageCount: pages.length, paths: pages.map((p) => p.page.path) });
63476
63751
  return () => el.removeEventListener("click", handler, true);
63477
63752
  }, [pages, handleNavigate, isolated, hostHrefBase]);
63753
+ if (lazyRoute) {
63754
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { ref: containerRef, className: `overflow-auto ${className ?? ""}`, style: { height }, children: [
63755
+ lazyLoad.status === "loading" && /* @__PURE__ */ jsxRuntime.jsx(LoadingState, {}),
63756
+ lazyLoad.status === "error" && /* @__PURE__ */ jsxRuntime.jsx(ErrorState, { "data-testid": "lazy-page-error", message: lazyLoad.error }),
63757
+ lazyLoad.status === "ready" && /* @__PURE__ */ jsxRuntime.jsx(
63758
+ OrbPreview,
63759
+ {
63760
+ schema: lazyLoad.schema,
63761
+ autoMock,
63762
+ height: "100%",
63763
+ className: "border-0",
63764
+ serverUrl,
63765
+ transport,
63766
+ getAccessToken,
63767
+ initialPagePath: lazyRoute.path,
63768
+ user,
63769
+ isolated,
63770
+ fit,
63771
+ onPageChange: announcePage,
63772
+ themeOverride,
63773
+ lazyLoader,
63774
+ onUnmatchedNavigate: handleNavigate
63775
+ },
63776
+ lazyRoute.page.orbRef
63777
+ )
63778
+ ] });
63779
+ }
63478
63780
  return /* @__PURE__ */ jsxRuntime.jsxs(
63479
63781
  Box,
63480
63782
  {
@@ -63546,7 +63848,9 @@ function BrowserPlayground({
63546
63848
  paused,
63547
63849
  fit,
63548
63850
  onPageChange,
63549
- viewer
63851
+ viewer,
63852
+ messages,
63853
+ locale
63550
63854
  }) {
63551
63855
  const [runtime$1] = React93.useState(
63552
63856
  () => new OrbitalServerRuntime.OrbitalServerRuntime({ mode, debug: false, ...viewer !== void 0 ? { defaultUser: viewer } : {} })
@@ -63562,10 +63866,10 @@ function BrowserPlayground({
63562
63866
  const registrationReady = React93.useMemo(() => {
63563
63867
  const orbitalNames = schema.orbitals.map((o) => o.name);
63564
63868
  playgroundLog.debug("register:start", { schema: schema.name, orbitalNames });
63565
- return runtime$1.register(schema).then(() => {
63869
+ return runtime$1.register(schema, messages !== void 0 ? { messages } : {}).then(() => {
63566
63870
  playgroundLog.debug("register:done", { schema: schema.name, orbitalNames });
63567
63871
  });
63568
- }, [runtime$1, schema]);
63872
+ }, [runtime$1, schema, messages]);
63569
63873
  const teardownTimerRef = React93.useRef(null);
63570
63874
  React93.useEffect(() => {
63571
63875
  if (teardownTimerRef.current !== null) {
@@ -63595,7 +63899,13 @@ function BrowserPlayground({
63595
63899
  ),
63596
63900
  [runtime$1, registrationReady]
63597
63901
  );
63598
- return /* @__PURE__ */ jsxRuntime.jsx(
63902
+ const viewerLocale = locale ?? schema.locales?.[0];
63903
+ const i18n$1 = React93.useMemo(() => {
63904
+ if (viewerLocale === void 0 || messages === void 0) return void 0;
63905
+ const catalog = messages[viewerLocale] ?? {};
63906
+ return { locale: viewerLocale, direction: i18n.localeDirection(viewerLocale), t: hooks.createTranslate(catalog), messages: catalog };
63907
+ }, [viewerLocale, messages]);
63908
+ const preview = /* @__PURE__ */ jsxRuntime.jsx(
63599
63909
  OrbPreview,
63600
63910
  {
63601
63911
  schema,
@@ -63609,6 +63919,7 @@ function BrowserPlayground({
63609
63919
  isolated: true
63610
63920
  }
63611
63921
  );
63922
+ return i18n$1 !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(hooks.I18nProvider, { value: i18n$1, children: preview }) : preview;
63612
63923
  }
63613
63924
 
63614
63925
  // components/avl/molecules/OrbPreviewNode.tsx
@@ -66883,7 +67194,11 @@ function AppearanceSection({ patternConfig, themeManifest, onPropChange, onToken
66883
67194
  {
66884
67195
  checked: position.absolute,
66885
67196
  label: t("orbInspector.absolute"),
66886
- onChange: (on) => write(on ? { absolute: true, x: axisPositionFrom("x", "start", offsetInParent), y: axisPositionFrom("y", "start", offsetInParent) } : { ...position, absolute: false })
67197
+ disabled: !offsetInParent && !position.absolute,
67198
+ onChange: (on) => {
67199
+ if (!on) write({ ...position, absolute: false });
67200
+ else if (offsetInParent) write({ absolute: true, x: axisPositionFrom("x", "start", offsetInParent), y: axisPositionFrom("y", "start", offsetInParent) });
67201
+ }
66887
67202
  }
66888
67203
  ),
66889
67204
  position.absolute && ["x", "y"].map((axis) => /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "flex items-center gap-2", "data-testid": `inspector-constraint-${axis}`, children: [
@@ -66894,9 +67209,10 @@ function AppearanceSection({ patternConfig, themeManifest, onPropChange, onToken
66894
67209
  value: position[axis].constraint,
66895
67210
  "aria-label": t(axis === "x" ? "orbInspector.constraintHorizontal" : "orbInspector.constraintVertical"),
66896
67211
  options: CONSTRAINTS.map((c) => ({ value: c, label: t(CONSTRAINT_LABELS[axis][c]) })),
67212
+ disabled: !offsetInParent,
66897
67213
  onValueChange: (v) => {
66898
67214
  const constraint = CONSTRAINTS.find((c) => c === v);
66899
- if (constraint) write({ ...position, [axis]: axisPositionFrom(axis, constraint, offsetInParent) });
67215
+ if (constraint && offsetInParent) write({ ...position, [axis]: axisPositionFrom(axis, constraint, offsetInParent) });
66900
67216
  },
66901
67217
  className: "flex-1 text-xs h-6"
66902
67218
  }