@almadar/ui 5.94.1 → 5.96.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.
package/dist/avl/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import * as React104 from 'react';
3
- import React104__default, { createContext, useState, useMemo, useRef, useEffect, useContext, useCallback, Suspense, useLayoutEffect, Profiler, useReducer, useSyncExternalStore, lazy, useId } from 'react';
2
+ import * as React105 from 'react';
3
+ import React105__default, { createContext, useState, useMemo, useRef, useEffect, useContext, useCallback, Suspense, useLayoutEffect, Profiler, useReducer, useSyncExternalStore, lazy, useId } from 'react';
4
4
  import { getAllPages, OrbitalProvider, EventBusContext, useTraitScope, ServerBridgeProvider, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge, useEntitySchema, useEntitySchemaOptional, TraitScopeProvider, useCurrentPagePath } from '@almadar/ui/providers';
5
5
  import { createLogger, isLogLevelEnabled } from '@almadar/logger';
6
6
  import ELK from 'elkjs/lib/elk.bundled.js';
@@ -3174,7 +3174,7 @@ var init_Typography = __esm({
3174
3174
  }) => {
3175
3175
  const variant = variantProp ?? (level ? `h${level}` : "body1");
3176
3176
  const Component = as || defaultElements[variant];
3177
- return React104__default.createElement(
3177
+ return React105__default.createElement(
3178
3178
  Component,
3179
3179
  {
3180
3180
  id,
@@ -3511,7 +3511,7 @@ var init_Box = __esm({
3511
3511
  fixed: "fixed",
3512
3512
  sticky: "sticky"
3513
3513
  };
3514
- Box = React104__default.forwardRef(
3514
+ Box = React105__default.forwardRef(
3515
3515
  ({
3516
3516
  padding,
3517
3517
  paddingX,
@@ -3576,7 +3576,7 @@ var init_Box = __esm({
3576
3576
  onPointerDown?.(e);
3577
3577
  }, [hoverEvent, tapReveal, triggerProps, onPointerDown]);
3578
3578
  const isClickable = action || onClick;
3579
- return React104__default.createElement(
3579
+ return React105__default.createElement(
3580
3580
  Component,
3581
3581
  {
3582
3582
  ref,
@@ -3672,7 +3672,7 @@ var init_Stack = __esm({
3672
3672
  };
3673
3673
  const isHorizontal = direction === "horizontal";
3674
3674
  const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
3675
- return React104__default.createElement(
3675
+ return React105__default.createElement(
3676
3676
  Component,
3677
3677
  {
3678
3678
  className: cn(
@@ -4164,7 +4164,7 @@ var init_MiniStateMachine = __esm({
4164
4164
  const x = 2 + i * (NODE_W + GAP + ARROW_W + GAP);
4165
4165
  const tc = transitionCounts[s.name] ?? 0;
4166
4166
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
4167
- return /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
4167
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
4168
4168
  /* @__PURE__ */ jsx(
4169
4169
  AvlState,
4170
4170
  {
@@ -4494,7 +4494,7 @@ function loadLib(key, importer) {
4494
4494
  return p;
4495
4495
  }
4496
4496
  function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
4497
- const Lazy = React104__default.lazy(async () => {
4497
+ const Lazy = React105__default.lazy(async () => {
4498
4498
  const lib = await loadLib(libKey, importer);
4499
4499
  const Comp = pick(lib);
4500
4500
  if (!Comp) {
@@ -4504,7 +4504,7 @@ function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
4504
4504
  return { default: Comp };
4505
4505
  });
4506
4506
  const Wrapped = (props) => /* @__PURE__ */ jsx(
4507
- React104__default.Suspense,
4507
+ React105__default.Suspense,
4508
4508
  {
4509
4509
  fallback: /* @__PURE__ */ jsx(
4510
4510
  "span",
@@ -5235,7 +5235,7 @@ var init_Icon = __esm({
5235
5235
  const directIcon = typeof icon === "string" ? void 0 : icon;
5236
5236
  const effectiveName = typeof icon === "string" ? icon : name;
5237
5237
  const family = useIconFamily();
5238
- const RenderedComponent = React104__default.useMemo(() => {
5238
+ const RenderedComponent = React105__default.useMemo(() => {
5239
5239
  if (directIcon) return null;
5240
5240
  return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
5241
5241
  }, [directIcon, effectiveName, family]);
@@ -5285,6 +5285,210 @@ var init_Icon = __esm({
5285
5285
  Icon.displayName = "Icon";
5286
5286
  }
5287
5287
  });
5288
+
5289
+ // lib/atlasSlice.ts
5290
+ function isTilesheet(a) {
5291
+ return typeof a.tileWidth === "number";
5292
+ }
5293
+ function getAtlas(url, onReady) {
5294
+ if (atlasCache.has(url)) return atlasCache.get(url) ?? void 0;
5295
+ atlasCache.set(url, void 0);
5296
+ fetch(url).then((r2) => r2.json()).then((json) => {
5297
+ atlasCache.set(url, json);
5298
+ onReady();
5299
+ }).catch(() => {
5300
+ atlasCache.set(url, null);
5301
+ });
5302
+ return void 0;
5303
+ }
5304
+ function subRectFor(atlas, sprite) {
5305
+ if (isTilesheet(atlas)) {
5306
+ let col;
5307
+ let row;
5308
+ if (sprite.includes(",")) {
5309
+ const [c, r2] = sprite.split(",").map((n) => Number(n.trim()));
5310
+ col = c;
5311
+ row = r2;
5312
+ } else {
5313
+ const i = Number(sprite);
5314
+ if (!Number.isFinite(i)) return null;
5315
+ col = i % atlas.columns;
5316
+ row = Math.floor(i / atlas.columns);
5317
+ }
5318
+ if (!Number.isFinite(col) || !Number.isFinite(row) || col < 0 || row < 0 || col >= atlas.columns || row >= atlas.rows) return null;
5319
+ const margin = atlas.margin ?? 0;
5320
+ const spacing = atlas.spacing ?? 0;
5321
+ return {
5322
+ sx: margin + col * (atlas.tileWidth + spacing),
5323
+ sy: margin + row * (atlas.tileHeight + spacing),
5324
+ sw: atlas.tileWidth,
5325
+ sh: atlas.tileHeight
5326
+ };
5327
+ }
5328
+ const st = atlas.subTextures[sprite];
5329
+ if (!st) return null;
5330
+ return { sx: st.x, sy: st.y, sw: st.width, sh: st.height };
5331
+ }
5332
+ function isAtlasAsset(asset) {
5333
+ return !!asset && typeof asset.atlas === "string" && typeof asset.sprite === "string";
5334
+ }
5335
+ function resolveAssetSource(img, asset, onReady) {
5336
+ if (isAtlasAsset(asset)) {
5337
+ const atlas = getAtlas(asset.atlas, onReady);
5338
+ if (!atlas) return null;
5339
+ const rect = subRectFor(atlas, asset.sprite);
5340
+ if (!rect) return null;
5341
+ return { img, rect, aspect: rect.sw / rect.sh };
5342
+ }
5343
+ const natW = img.naturalWidth || 1;
5344
+ const natH = img.naturalHeight || 1;
5345
+ return { img, rect: null, aspect: natW / natH };
5346
+ }
5347
+ function blit(ctx, src, dx, dy, dw, dh) {
5348
+ if (src.rect) ctx.drawImage(src.img, src.rect.sx, src.rect.sy, src.rect.sw, src.rect.sh, dx, dy, dw, dh);
5349
+ else ctx.drawImage(src.img, dx, dy, dw, dh);
5350
+ }
5351
+ var atlasCache;
5352
+ var init_atlasSlice = __esm({
5353
+ "lib/atlasSlice.ts"() {
5354
+ "use client";
5355
+ atlasCache = /* @__PURE__ */ new Map();
5356
+ }
5357
+ });
5358
+ function useAtlasSliceDataUrl(asset) {
5359
+ const [, bump] = React105.useReducer((x) => x + 1, 0);
5360
+ if (!isAtlasAsset(asset)) return void 0;
5361
+ const key = `${asset.atlas}#${asset.sprite}`;
5362
+ const cached = sliceDataUrlCache.get(key);
5363
+ if (cached) return cached;
5364
+ const atlas = getAtlas(asset.atlas, bump);
5365
+ const img = asset?.url ? getSheetImage(asset.url, bump) : null;
5366
+ if (!atlas || !img) return void 0;
5367
+ const rect = subRectFor(atlas, asset.sprite);
5368
+ if (!rect) return void 0;
5369
+ const canvas = document.createElement("canvas");
5370
+ canvas.width = rect.sw;
5371
+ canvas.height = rect.sh;
5372
+ const ctx = canvas.getContext("2d");
5373
+ if (!ctx) return void 0;
5374
+ ctx.imageSmoothingEnabled = false;
5375
+ ctx.drawImage(img, rect.sx, rect.sy, rect.sw, rect.sh, 0, 0, rect.sw, rect.sh);
5376
+ const url = canvas.toDataURL();
5377
+ sliceDataUrlCache.set(key, url);
5378
+ return url;
5379
+ }
5380
+ function AtlasPanel({ asset, borderSlice = 16, borderWidth = 16, mode = "nineSlice", className, style, children, "aria-hidden": ariaHidden }) {
5381
+ const dataUrl = useAtlasSliceDataUrl(asset);
5382
+ const skin = !dataUrl ? {} : mode === "repeat" ? { backgroundImage: `url(${dataUrl})`, backgroundRepeat: "repeat" } : {
5383
+ borderStyle: "solid",
5384
+ borderWidth,
5385
+ borderImageSource: `url(${dataUrl})`,
5386
+ borderImageSlice: `${borderSlice} fill`,
5387
+ borderImageWidth: borderWidth,
5388
+ borderImageRepeat: "stretch",
5389
+ imageRendering: "pixelated"
5390
+ };
5391
+ return /* @__PURE__ */ jsx("span", { "aria-hidden": ariaHidden, className: cn("inline-block", className), style: { ...skin, ...style }, children });
5392
+ }
5393
+ function getSheetImage(url, onReady) {
5394
+ const cached = imageCache.get(url);
5395
+ if (cached) return cached;
5396
+ (imageWaiters.get(url) ?? imageWaiters.set(url, /* @__PURE__ */ new Set()).get(url)).add(onReady);
5397
+ if (!imageCache.has(url)) {
5398
+ imageCache.set(url, null);
5399
+ const img = new Image();
5400
+ img.crossOrigin = "anonymous";
5401
+ img.onload = () => {
5402
+ imageCache.set(url, img);
5403
+ imageWaiters.get(url)?.forEach((fn) => fn());
5404
+ imageWaiters.delete(url);
5405
+ };
5406
+ img.src = url;
5407
+ }
5408
+ return null;
5409
+ }
5410
+ function AtlasImage({
5411
+ asset,
5412
+ size,
5413
+ width,
5414
+ height,
5415
+ fill = false,
5416
+ fit = "contain",
5417
+ alt,
5418
+ className,
5419
+ style,
5420
+ "aria-hidden": ariaHidden
5421
+ }) {
5422
+ const [, bump] = React105.useReducer((x) => x + 1, 0);
5423
+ const canvasRef = React105.useRef(null);
5424
+ const sliced = isAtlasAsset(asset);
5425
+ const atlas = sliced ? getAtlas(asset.atlas, bump) : void 0;
5426
+ const img = sliced && asset?.url ? getSheetImage(asset.url, bump) : null;
5427
+ const rect = sliced && atlas ? subRectFor(atlas, asset.sprite) : null;
5428
+ React105.useEffect(() => {
5429
+ const canvas = canvasRef.current;
5430
+ if (!canvas || !img || !rect) return;
5431
+ canvas.width = rect.sw;
5432
+ canvas.height = rect.sh;
5433
+ const ctx = canvas.getContext("2d");
5434
+ if (!ctx) return;
5435
+ ctx.imageSmoothingEnabled = false;
5436
+ ctx.clearRect(0, 0, rect.sw, rect.sh);
5437
+ ctx.drawImage(img, rect.sx, rect.sy, rect.sw, rect.sh, 0, 0, rect.sw, rect.sh);
5438
+ }, [img, rect?.sx, rect?.sy, rect?.sw, rect?.sh]);
5439
+ const w = fill ? "100%" : width ?? size;
5440
+ const h = fill ? "100%" : height ?? size;
5441
+ const boxStyle = {
5442
+ ...fill ? { position: "absolute", inset: 0 } : {},
5443
+ width: w,
5444
+ height: h,
5445
+ objectFit: fit,
5446
+ imageRendering: "pixelated",
5447
+ ...style
5448
+ };
5449
+ if (!asset?.url) return null;
5450
+ if (sliced) {
5451
+ if (!rect || !img) {
5452
+ return /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("inline-block flex-shrink-0", className), style: { ...boxStyle, objectFit: void 0 } });
5453
+ }
5454
+ return /* @__PURE__ */ jsx(
5455
+ "canvas",
5456
+ {
5457
+ ref: canvasRef,
5458
+ role: ariaHidden ? void 0 : "img",
5459
+ "aria-hidden": ariaHidden,
5460
+ "aria-label": ariaHidden ? void 0 : alt ?? asset.name ?? asset.category ?? "",
5461
+ className: cn("flex-shrink-0", className),
5462
+ style: boxStyle
5463
+ }
5464
+ );
5465
+ }
5466
+ return /* @__PURE__ */ jsx(
5467
+ "img",
5468
+ {
5469
+ src: asset.url,
5470
+ alt: alt ?? asset.name ?? asset.category ?? "",
5471
+ "aria-hidden": ariaHidden,
5472
+ ...typeof w === "number" ? { width: w } : {},
5473
+ ...typeof h === "number" ? { height: h } : {},
5474
+ className: cn("flex-shrink-0", className),
5475
+ style: boxStyle
5476
+ }
5477
+ );
5478
+ }
5479
+ var sliceDataUrlCache, imageCache, imageWaiters;
5480
+ var init_AtlasImage = __esm({
5481
+ "components/core/atoms/AtlasImage.tsx"() {
5482
+ "use client";
5483
+ init_atlasSlice();
5484
+ init_cn();
5485
+ sliceDataUrlCache = /* @__PURE__ */ new Map();
5486
+ AtlasPanel.displayName = "AtlasPanel";
5487
+ imageCache = /* @__PURE__ */ new Map();
5488
+ imageWaiters = /* @__PURE__ */ new Map();
5489
+ AtlasImage.displayName = "AtlasImage";
5490
+ }
5491
+ });
5288
5492
  function isIconLike(v) {
5289
5493
  return typeof v.render === "function";
5290
5494
  }
@@ -5297,7 +5501,7 @@ function resolveIconProp(value, sizeClass) {
5297
5501
  const IconComp = value;
5298
5502
  return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
5299
5503
  }
5300
- if (React104__default.isValidElement(value)) {
5504
+ if (React105__default.isValidElement(value)) {
5301
5505
  return value;
5302
5506
  }
5303
5507
  if (typeof value === "object" && value !== null && isIconLike(value)) {
@@ -5313,6 +5517,7 @@ var init_Button = __esm({
5313
5517
  init_cn();
5314
5518
  init_useEventBus();
5315
5519
  init_Icon();
5520
+ init_AtlasImage();
5316
5521
  variantStyles2 = {
5317
5522
  primary: [
5318
5523
  "bg-primary text-primary-foreground",
@@ -5373,7 +5578,7 @@ var init_Button = __esm({
5373
5578
  md: "h-icon-default w-icon-default",
5374
5579
  lg: "h-icon-default w-icon-default"
5375
5580
  };
5376
- Button = React104__default.forwardRef(
5581
+ Button = React105__default.forwardRef(
5377
5582
  ({
5378
5583
  className,
5379
5584
  variant = "primary",
@@ -5397,7 +5602,7 @@ var init_Button = __esm({
5397
5602
  const leftIconValue = leftIcon || iconProp;
5398
5603
  const rightIconValue = rightIcon || iconRightProp;
5399
5604
  const px = size === "sm" ? 16 : size === "lg" ? 20 : 16;
5400
- const resolvedLeftIcon = iconAsset?.url ? /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: iconAsset.name ?? iconAsset.category ?? "", width: px, height: px, style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px }, className: "flex-shrink-0" }) : resolveIconProp(leftIconValue, iconSizeStyles[size]);
5605
+ const resolvedLeftIcon = iconAsset?.url ? /* @__PURE__ */ jsx(AtlasImage, { asset: iconAsset, size: px, alt: iconAsset.name ?? iconAsset.category ?? "", className: "flex-shrink-0" }) : resolveIconProp(leftIconValue, iconSizeStyles[size]);
5401
5606
  const resolvedRightIcon = resolveIconProp(rightIconValue, iconSizeStyles[size]);
5402
5607
  const handleClick = (e) => {
5403
5608
  if (action) {
@@ -5441,7 +5646,7 @@ var Dialog;
5441
5646
  var init_Dialog = __esm({
5442
5647
  "components/core/atoms/Dialog.tsx"() {
5443
5648
  init_cn();
5444
- Dialog = React104__default.forwardRef(
5649
+ Dialog = React105__default.forwardRef(
5445
5650
  ({
5446
5651
  role = "dialog",
5447
5652
  "aria-modal": ariaModal = true,
@@ -5899,6 +6104,7 @@ var init_Badge = __esm({
5899
6104
  "components/core/atoms/Badge.tsx"() {
5900
6105
  init_cn();
5901
6106
  init_Icon();
6107
+ init_AtlasImage();
5902
6108
  variantStyles3 = {
5903
6109
  default: [
5904
6110
  "bg-muted text-foreground",
@@ -5936,7 +6142,7 @@ var init_Badge = __esm({
5936
6142
  md: "px-2.5 py-1 text-sm",
5937
6143
  lg: "px-3 py-1.5 text-base"
5938
6144
  };
5939
- Badge = React104__default.forwardRef(
6145
+ Badge = React105__default.forwardRef(
5940
6146
  ({ className, variant = "default", size = "sm", amount, label, icon, iconAsset, children, onRemove, removeLabel, ...props }, ref) => {
5941
6147
  const iconSizes3 = {
5942
6148
  sm: "h-icon-default w-icon-default",
@@ -5944,7 +6150,7 @@ var init_Badge = __esm({
5944
6150
  lg: "h-icon-default w-icon-default"
5945
6151
  };
5946
6152
  const iconPx = size === "lg" ? 20 : 16;
5947
- const resolvedIcon = iconAsset?.url ? /* @__PURE__ */ jsx("img", { src: iconAsset.url, alt: iconAsset.name ?? iconAsset.category ?? "", width: iconPx, height: iconPx, style: { imageRendering: "pixelated", objectFit: "contain", width: iconPx, height: iconPx }, className: "flex-shrink-0" }) : typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsx(Icon, { icon, className: iconSizes3[size] }) : null;
6153
+ const resolvedIcon = iconAsset?.url ? /* @__PURE__ */ jsx(AtlasImage, { asset: iconAsset, size: iconPx, alt: iconAsset.name ?? iconAsset.category ?? "", className: "flex-shrink-0" }) : typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, className: iconSizes3[size] }) : icon ? /* @__PURE__ */ jsx(Icon, { icon, className: iconSizes3[size] }) : null;
5948
6154
  return /* @__PURE__ */ jsxs(
5949
6155
  "span",
5950
6156
  {
@@ -6273,7 +6479,7 @@ var init_SvgFlow = __esm({
6273
6479
  width = 100,
6274
6480
  height = 100
6275
6481
  }) => {
6276
- const markerId = React104__default.useMemo(() => {
6482
+ const markerId = React105__default.useMemo(() => {
6277
6483
  flowIdCounter += 1;
6278
6484
  return `almadar-flow-arrow-${flowIdCounter}`;
6279
6485
  }, []);
@@ -6866,7 +7072,7 @@ var init_SvgRing = __esm({
6866
7072
  width = 100,
6867
7073
  height = 100
6868
7074
  }) => {
6869
- const gradientId = React104__default.useMemo(() => {
7075
+ const gradientId = React105__default.useMemo(() => {
6870
7076
  ringIdCounter += 1;
6871
7077
  return `almadar-ring-glow-${ringIdCounter}`;
6872
7078
  }, []);
@@ -7047,7 +7253,7 @@ var init_Input = __esm({
7047
7253
  init_cn();
7048
7254
  init_Icon();
7049
7255
  init_useEventBus();
7050
- Input = React104__default.forwardRef(
7256
+ Input = React105__default.forwardRef(
7051
7257
  ({
7052
7258
  className,
7053
7259
  inputType,
@@ -7207,7 +7413,7 @@ var Label;
7207
7413
  var init_Label = __esm({
7208
7414
  "components/core/atoms/Label.tsx"() {
7209
7415
  init_cn();
7210
- Label = React104__default.forwardRef(
7416
+ Label = React105__default.forwardRef(
7211
7417
  ({ className, required, children, ...props }, ref) => {
7212
7418
  return /* @__PURE__ */ jsxs(
7213
7419
  "label",
@@ -7234,7 +7440,7 @@ var init_Textarea = __esm({
7234
7440
  "components/core/atoms/Textarea.tsx"() {
7235
7441
  init_cn();
7236
7442
  init_useEventBus();
7237
- Textarea = React104__default.forwardRef(
7443
+ Textarea = React105__default.forwardRef(
7238
7444
  ({ className, error, onChange, ...props }, ref) => {
7239
7445
  const eventBus = useEventBus();
7240
7446
  const handleChange = (e) => {
@@ -7473,7 +7679,7 @@ var init_Select = __esm({
7473
7679
  init_cn();
7474
7680
  init_Icon();
7475
7681
  init_useEventBus();
7476
- Select = React104__default.forwardRef(
7682
+ Select = React105__default.forwardRef(
7477
7683
  (props, _ref) => {
7478
7684
  const { multiple, searchable, clearable } = props;
7479
7685
  if (multiple || searchable || clearable) {
@@ -7490,7 +7696,7 @@ var init_Checkbox = __esm({
7490
7696
  "components/core/atoms/Checkbox.tsx"() {
7491
7697
  init_cn();
7492
7698
  init_useEventBus();
7493
- Checkbox = React104__default.forwardRef(
7699
+ Checkbox = React105__default.forwardRef(
7494
7700
  ({ className, label, id, onChange, ...props }, ref) => {
7495
7701
  const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
7496
7702
  const eventBus = useEventBus();
@@ -7544,7 +7750,7 @@ var init_Spinner = __esm({
7544
7750
  md: "h-6 w-6",
7545
7751
  lg: "h-8 w-8"
7546
7752
  };
7547
- Spinner = React104__default.forwardRef(
7753
+ Spinner = React105__default.forwardRef(
7548
7754
  ({ className, size = "md", overlay, ...props }, ref) => {
7549
7755
  if (overlay) {
7550
7756
  return /* @__PURE__ */ jsx(
@@ -7634,7 +7840,7 @@ var init_Card = __esm({
7634
7840
  chip: "shadow-none rounded-pill border-[length:var(--border-width)] border-border",
7635
7841
  "tile-image-first": "p-0 overflow-hidden"
7636
7842
  };
7637
- Card = React104__default.forwardRef(
7843
+ Card = React105__default.forwardRef(
7638
7844
  ({
7639
7845
  className,
7640
7846
  variant = "bordered",
@@ -7682,9 +7888,9 @@ var init_Card = __esm({
7682
7888
  }
7683
7889
  );
7684
7890
  Card.displayName = "Card";
7685
- CardHeader = React104__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
7891
+ CardHeader = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
7686
7892
  CardHeader.displayName = "CardHeader";
7687
- CardTitle = React104__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7893
+ CardTitle = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7688
7894
  "h3",
7689
7895
  {
7690
7896
  ref,
@@ -7697,11 +7903,11 @@ var init_Card = __esm({
7697
7903
  }
7698
7904
  ));
7699
7905
  CardTitle.displayName = "CardTitle";
7700
- CardContent = React104__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
7906
+ CardContent = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
7701
7907
  CardContent.displayName = "CardContent";
7702
7908
  CardBody = CardContent;
7703
7909
  CardBody.displayName = "CardBody";
7704
- CardFooter = React104__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7910
+ CardFooter = React105__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7705
7911
  "div",
7706
7912
  {
7707
7913
  ref,
@@ -7756,7 +7962,7 @@ var init_FilterPill = __esm({
7756
7962
  md: "w-3.5 h-3.5",
7757
7963
  lg: "w-4 h-4"
7758
7964
  };
7759
- FilterPill = React104__default.forwardRef(
7965
+ FilterPill = React105__default.forwardRef(
7760
7966
  ({
7761
7967
  className,
7762
7968
  variant = "default",
@@ -7885,8 +8091,8 @@ var init_Avatar = __esm({
7885
8091
  actionPayload
7886
8092
  }) => {
7887
8093
  const eventBus = useEventBus();
7888
- const [imgFailed, setImgFailed] = React104__default.useState(false);
7889
- React104__default.useEffect(() => {
8094
+ const [imgFailed, setImgFailed] = React105__default.useState(false);
8095
+ React105__default.useEffect(() => {
7890
8096
  setImgFailed(false);
7891
8097
  }, [src]);
7892
8098
  const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
@@ -7999,7 +8205,7 @@ var init_Center = __esm({
7999
8205
  as: Component = "div"
8000
8206
  }) => {
8001
8207
  const mergedStyle = minHeight ? { minHeight, ...style } : style;
8002
- return React104__default.createElement(Component, {
8208
+ return React105__default.createElement(Component, {
8003
8209
  className: cn(
8004
8210
  inline ? "inline-flex" : "flex",
8005
8211
  horizontal && "justify-center",
@@ -8267,7 +8473,7 @@ var init_Radio = __esm({
8267
8473
  md: "w-2.5 h-2.5",
8268
8474
  lg: "w-3 h-3"
8269
8475
  };
8270
- Radio = React104__default.forwardRef(
8476
+ Radio = React105__default.forwardRef(
8271
8477
  ({
8272
8478
  label,
8273
8479
  helperText,
@@ -8284,12 +8490,12 @@ var init_Radio = __esm({
8284
8490
  onChange,
8285
8491
  ...props
8286
8492
  }, ref) => {
8287
- const reactId = React104__default.useId();
8493
+ const reactId = React105__default.useId();
8288
8494
  const baseId = id || `radio-${reactId}`;
8289
8495
  const hasError = !!error;
8290
8496
  const eventBus = useEventBus();
8291
- const [selected, setSelected] = React104__default.useState(value);
8292
- React104__default.useEffect(() => {
8497
+ const [selected, setSelected] = React105__default.useState(value);
8498
+ React105__default.useEffect(() => {
8293
8499
  if (value !== void 0) setSelected(value);
8294
8500
  }, [value]);
8295
8501
  const pick = (next, e) => {
@@ -8471,7 +8677,7 @@ var init_Switch = __esm({
8471
8677
  "components/core/atoms/Switch.tsx"() {
8472
8678
  "use client";
8473
8679
  init_cn();
8474
- Switch = React104.forwardRef(
8680
+ Switch = React105.forwardRef(
8475
8681
  ({
8476
8682
  checked,
8477
8683
  defaultChecked = false,
@@ -8482,10 +8688,10 @@ var init_Switch = __esm({
8482
8688
  name,
8483
8689
  className
8484
8690
  }, ref) => {
8485
- const [isChecked, setIsChecked] = React104.useState(
8691
+ const [isChecked, setIsChecked] = React105.useState(
8486
8692
  checked !== void 0 ? checked : defaultChecked
8487
8693
  );
8488
- React104.useEffect(() => {
8694
+ React105.useEffect(() => {
8489
8695
  if (checked !== void 0) {
8490
8696
  setIsChecked(checked);
8491
8697
  }
@@ -8763,7 +8969,7 @@ var Aside;
8763
8969
  var init_Aside = __esm({
8764
8970
  "components/core/atoms/Aside.tsx"() {
8765
8971
  init_cn();
8766
- Aside = React104__default.forwardRef(
8972
+ Aside = React105__default.forwardRef(
8767
8973
  ({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx("aside", { ref, className: cn(className), ...rest, children })
8768
8974
  );
8769
8975
  Aside.displayName = "Aside";
@@ -8842,9 +9048,9 @@ var init_LawReferenceTooltip = __esm({
8842
9048
  className
8843
9049
  }) => {
8844
9050
  const { t } = useTranslate();
8845
- const [isVisible, setIsVisible] = React104__default.useState(false);
8846
- const timeoutRef = React104__default.useRef(null);
8847
- const triggerRef = React104__default.useRef(null);
9051
+ const [isVisible, setIsVisible] = React105__default.useState(false);
9052
+ const timeoutRef = React105__default.useRef(null);
9053
+ const triggerRef = React105__default.useRef(null);
8848
9054
  const handleMouseEnter = () => {
8849
9055
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
8850
9056
  timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
@@ -8855,7 +9061,7 @@ var init_LawReferenceTooltip = __esm({
8855
9061
  };
8856
9062
  const { revealed, triggerProps } = useTapReveal({ refs: [triggerRef] });
8857
9063
  const open = isVisible || revealed;
8858
- React104__default.useEffect(() => {
9064
+ React105__default.useEffect(() => {
8859
9065
  return () => {
8860
9066
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
8861
9067
  };
@@ -9065,7 +9271,7 @@ var init_StatusDot = __esm({
9065
9271
  md: "w-2.5 h-2.5",
9066
9272
  lg: "w-3 h-3"
9067
9273
  };
9068
- StatusDot = React104__default.forwardRef(
9274
+ StatusDot = React105__default.forwardRef(
9069
9275
  ({ className, status = "offline", pulse = false, size = "md", label, ...props }, ref) => {
9070
9276
  return /* @__PURE__ */ jsx(
9071
9277
  "span",
@@ -9119,7 +9325,7 @@ var init_TrendIndicator = __esm({
9119
9325
  down: "trending-down",
9120
9326
  flat: "arrow-right"
9121
9327
  };
9122
- TrendIndicator = React104__default.forwardRef(
9328
+ TrendIndicator = React105__default.forwardRef(
9123
9329
  ({
9124
9330
  className,
9125
9331
  value,
@@ -9186,7 +9392,7 @@ var init_RangeSlider = __esm({
9186
9392
  md: "w-4 h-4",
9187
9393
  lg: "w-5 h-5"
9188
9394
  };
9189
- RangeSlider = React104__default.forwardRef(
9395
+ RangeSlider = React105__default.forwardRef(
9190
9396
  ({
9191
9397
  className,
9192
9398
  min = 0,
@@ -9780,7 +9986,7 @@ var init_ContentSection = __esm({
9780
9986
  md: "py-16",
9781
9987
  lg: "py-24"
9782
9988
  };
9783
- ContentSection = React104__default.forwardRef(
9989
+ ContentSection = React105__default.forwardRef(
9784
9990
  ({ children, background = "default", padding = "lg", id, className }, ref) => {
9785
9991
  return /* @__PURE__ */ jsx(
9786
9992
  Box,
@@ -10314,7 +10520,7 @@ var init_AnimatedReveal = __esm({
10314
10520
  "scale-up": { opacity: 1, transform: "scale(1) translateY(0)" },
10315
10521
  "none": {}
10316
10522
  };
10317
- AnimatedReveal = React104__default.forwardRef(
10523
+ AnimatedReveal = React105__default.forwardRef(
10318
10524
  ({
10319
10525
  trigger = "scroll",
10320
10526
  animation = "fade-up",
@@ -10474,7 +10680,7 @@ var init_AnimatedGraphic = __esm({
10474
10680
  "components/marketing/atoms/AnimatedGraphic.tsx"() {
10475
10681
  "use client";
10476
10682
  init_cn();
10477
- AnimatedGraphic = React104__default.forwardRef(
10683
+ AnimatedGraphic = React105__default.forwardRef(
10478
10684
  ({
10479
10685
  src,
10480
10686
  svgContent,
@@ -10497,7 +10703,7 @@ var init_AnimatedGraphic = __esm({
10497
10703
  const fetchedSvg = useFetchedSvg(svgContent ? void 0 : src);
10498
10704
  const resolvedSvg = svgContent ?? fetchedSvg;
10499
10705
  const prevAnimateRef = useRef(animate);
10500
- const setRef = React104__default.useCallback(
10706
+ const setRef = React105__default.useCallback(
10501
10707
  (node) => {
10502
10708
  containerRef.current = node;
10503
10709
  if (typeof ref === "function") ref(node);
@@ -10969,7 +11175,7 @@ function isoToScreen(tileX, tileY, scale, baseOffsetX, layout = "isometric") {
10969
11175
  }
10970
11176
  if (layout === "flat") {
10971
11177
  const screenX2 = tileX * scaledTileWidth + baseOffsetX;
10972
- const screenY2 = tileY * scaledFloorHeight;
11178
+ const screenY2 = tileY * scaledTileWidth;
10973
11179
  return { x: screenX2, y: screenY2 };
10974
11180
  }
10975
11181
  const screenX = (tileX - tileY) * (scaledTileWidth / 2) + baseOffsetX;
@@ -10986,7 +11192,7 @@ function screenToIso(screenX, screenY, scale, baseOffsetX, layout = "isometric")
10986
11192
  }
10987
11193
  if (layout === "flat") {
10988
11194
  const col = Math.round((screenX - baseOffsetX) / scaledTileWidth);
10989
- const row = Math.round(screenY / scaledFloorHeight);
11195
+ const row = Math.round(screenY / scaledTileWidth);
10990
11196
  return { x: col, y: row };
10991
11197
  }
10992
11198
  const adjustedX = screenX - baseOffsetX;
@@ -11060,13 +11266,11 @@ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
11060
11266
  const px = typeof size === "number" ? size : sizeMap[size];
11061
11267
  if (assetUrl?.url) {
11062
11268
  return /* @__PURE__ */ jsx(
11063
- "img",
11269
+ AtlasImage,
11064
11270
  {
11065
- src: assetUrl.url,
11271
+ asset: assetUrl,
11272
+ size: px,
11066
11273
  alt: alt ?? assetUrl.category ?? "",
11067
- width: px,
11068
- height: px,
11069
- style: { imageRendering: "pixelated", objectFit: "contain", width: px, height: px },
11070
11274
  className: cn("flex-shrink-0", className)
11071
11275
  }
11072
11276
  );
@@ -11080,6 +11284,7 @@ var init_GameIcon = __esm({
11080
11284
  "use client";
11081
11285
  init_cn();
11082
11286
  init_Icon();
11287
+ init_AtlasImage();
11083
11288
  sizeMap = {
11084
11289
  sm: 16,
11085
11290
  md: 24,
@@ -11105,13 +11310,12 @@ function GameCard({
11105
11310
  className
11106
11311
  }) {
11107
11312
  const eventBus = useEventBus();
11108
- const handleClick = React104.useCallback(() => {
11313
+ const handleClick = React105.useCallback(() => {
11109
11314
  if (disabled) return;
11110
11315
  onClick?.(id);
11111
11316
  if (clickEvent) eventBus.emit(`UI:${clickEvent}`, { cardId: id });
11112
11317
  }, [disabled, id, onClick, clickEvent, eventBus]);
11113
11318
  const artPx = artPxMap[size];
11114
- const frameStyle = frameAsset?.url ? { backgroundImage: `url(${frameAsset.url})`, backgroundSize: "100% 100%", backgroundRepeat: "no-repeat" } : {};
11115
11319
  return /* @__PURE__ */ jsxs(
11116
11320
  Button,
11117
11321
  {
@@ -11119,11 +11323,10 @@ function GameCard({
11119
11323
  onClick: handleClick,
11120
11324
  disabled,
11121
11325
  title: name,
11122
- style: frameStyle,
11123
11326
  className: cn(
11124
- "relative flex flex-col items-center rounded-interactive",
11125
- "bg-card/90 px-1.5 pt-1.5 pb-1 transition-all duration-150",
11126
- frameAsset?.url ? "border-0" : "border-2",
11327
+ "relative isolate flex flex-col items-center rounded-interactive",
11328
+ "px-1.5 pt-1.5 pb-1 transition-all duration-150",
11329
+ frameAsset?.url ? "border-0" : "border-2 bg-card/90",
11127
11330
  cardSizeMap[size],
11128
11331
  disabled ? "border-border opacity-50 cursor-not-allowed" : "border-accent hover:brightness-125 hover:-translate-y-1 cursor-pointer",
11129
11332
  selected && "ring-2 ring-foreground ring-offset-1 ring-offset-background -translate-y-1",
@@ -11131,6 +11334,7 @@ function GameCard({
11131
11334
  className
11132
11335
  ),
11133
11336
  children: [
11337
+ frameAsset?.url && /* @__PURE__ */ jsx(AtlasImage, { asset: frameAsset, fill: true, fit: "fill", "aria-hidden": true, style: { zIndex: -1 } }),
11134
11338
  cost != null && /* @__PURE__ */ jsx(
11135
11339
  Typography,
11136
11340
  {
@@ -11169,6 +11373,7 @@ var init_GameCard = __esm({
11169
11373
  init_Box();
11170
11374
  init_Button();
11171
11375
  init_Typography();
11376
+ init_AtlasImage();
11172
11377
  init_GameIcon();
11173
11378
  cardSizeMap = {
11174
11379
  sm: "w-16 h-24",
@@ -11329,7 +11534,7 @@ var init_HealthBar = __esm({
11329
11534
  }
11330
11535
  });
11331
11536
  function ScoreDisplay({
11332
- assetUrl = DEFAULT_ASSET_URL,
11537
+ assetUrl,
11333
11538
  value,
11334
11539
  score,
11335
11540
  label,
@@ -11356,7 +11561,7 @@ function ScoreDisplay({
11356
11561
  }
11357
11562
  );
11358
11563
  }
11359
- var sizeMap3, DEFAULT_ASSET_URL;
11564
+ var sizeMap3;
11360
11565
  var init_ScoreDisplay = __esm({
11361
11566
  "components/game/2d/atoms/ScoreDisplay.tsx"() {
11362
11567
  init_cn();
@@ -11370,16 +11575,11 @@ var init_ScoreDisplay = __esm({
11370
11575
  lg: "text-2xl",
11371
11576
  xl: "text-4xl"
11372
11577
  };
11373
- DEFAULT_ASSET_URL = {
11374
- url: "https://almadar-kflow-assets.web.app/shared/effects/particles/star_01.png",
11375
- role: "effect",
11376
- category: "effect"
11377
- };
11378
11578
  ScoreDisplay.displayName = "ScoreDisplay";
11379
11579
  }
11380
11580
  });
11381
11581
  function ControlButton({
11382
- assetUrl = DEFAULT_ASSET_URL2,
11582
+ assetUrl = DEFAULT_ASSET_URL,
11383
11583
  label,
11384
11584
  icon,
11385
11585
  size = "md",
@@ -11394,9 +11594,9 @@ function ControlButton({
11394
11594
  className
11395
11595
  }) {
11396
11596
  const eventBus = useEventBus();
11397
- const [isPressed, setIsPressed] = React104.useState(false);
11597
+ const [isPressed, setIsPressed] = React105.useState(false);
11398
11598
  const actualPressed = pressed ?? isPressed;
11399
- const handlePointerDown = React104.useCallback(
11599
+ const handlePointerDown = React105.useCallback(
11400
11600
  (e) => {
11401
11601
  e.preventDefault();
11402
11602
  if (disabled) return;
@@ -11406,7 +11606,7 @@ function ControlButton({
11406
11606
  },
11407
11607
  [disabled, pressEvent, eventBus, onPress]
11408
11608
  );
11409
- const handlePointerUp = React104.useCallback(
11609
+ const handlePointerUp = React105.useCallback(
11410
11610
  (e) => {
11411
11611
  e.preventDefault();
11412
11612
  if (disabled) return;
@@ -11416,7 +11616,7 @@ function ControlButton({
11416
11616
  },
11417
11617
  [disabled, releaseEvent, eventBus, onRelease]
11418
11618
  );
11419
- const handlePointerLeave = React104.useCallback(
11619
+ const handlePointerLeave = React105.useCallback(
11420
11620
  (e) => {
11421
11621
  if (isPressed) {
11422
11622
  setIsPressed(false);
@@ -11457,7 +11657,7 @@ function ControlButton({
11457
11657
  }
11458
11658
  );
11459
11659
  }
11460
- var sizeMap4, shapeMap, variantMap, DEFAULT_ASSET_URL2;
11660
+ var sizeMap4, shapeMap, variantMap, DEFAULT_ASSET_URL;
11461
11661
  var init_ControlButton = __esm({
11462
11662
  "components/game/2d/atoms/ControlButton.tsx"() {
11463
11663
  "use client";
@@ -11484,7 +11684,7 @@ var init_ControlButton = __esm({
11484
11684
  secondary: "bg-secondary text-secondary-foreground border-border hover:bg-secondary-hover",
11485
11685
  ghost: "bg-transparent text-foreground border-border hover:bg-muted"
11486
11686
  };
11487
- DEFAULT_ASSET_URL2 = {
11687
+ DEFAULT_ASSET_URL = {
11488
11688
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/circle_01.png",
11489
11689
  role: "ui",
11490
11690
  category: "control"
@@ -11577,7 +11777,7 @@ function isKnownState(s) {
11577
11777
  return s in DEFAULT_STATE_STYLES;
11578
11778
  }
11579
11779
  function StateIndicator({
11580
- assetUrl = DEFAULT_ASSET_URL3,
11780
+ assetUrl = DEFAULT_ASSET_URL2,
11581
11781
  state = "idle",
11582
11782
  label,
11583
11783
  size = "md",
@@ -11607,14 +11807,14 @@ function StateIndicator({
11607
11807
  }
11608
11808
  );
11609
11809
  }
11610
- var DEFAULT_ASSET_URL3, DEFAULT_STATE_STYLES, DEFAULT_STYLE, STATIC_STATES, SIZE_CLASSES;
11810
+ var DEFAULT_ASSET_URL2, DEFAULT_STATE_STYLES, DEFAULT_STYLE, STATIC_STATES, SIZE_CLASSES;
11611
11811
  var init_StateIndicator = __esm({
11612
11812
  "components/game/2d/atoms/StateIndicator.tsx"() {
11613
11813
  init_Box();
11614
11814
  init_Icon();
11615
11815
  init_cn();
11616
11816
  init_GameIcon();
11617
- DEFAULT_ASSET_URL3 = {
11817
+ DEFAULT_ASSET_URL2 = {
11618
11818
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
11619
11819
  role: "ui",
11620
11820
  category: "state"
@@ -11700,7 +11900,7 @@ var init_TimerDisplay = __esm({
11700
11900
  }
11701
11901
  });
11702
11902
  function ResourceCounter({
11703
- assetUrl = DEFAULT_ASSET_URL4,
11903
+ assetUrl = DEFAULT_ASSET_URL3,
11704
11904
  icon,
11705
11905
  label = "Gold",
11706
11906
  value = 250,
@@ -11733,7 +11933,7 @@ function ResourceCounter({
11733
11933
  }
11734
11934
  );
11735
11935
  }
11736
- var colorTokenClasses2, DEFAULT_ASSET_URL4, sizeMap6;
11936
+ var colorTokenClasses2, DEFAULT_ASSET_URL3, sizeMap6;
11737
11937
  var init_ResourceCounter = __esm({
11738
11938
  "components/game/2d/atoms/ResourceCounter.tsx"() {
11739
11939
  init_cn();
@@ -11749,7 +11949,7 @@ var init_ResourceCounter = __esm({
11749
11949
  error: "text-error",
11750
11950
  muted: "text-muted-foreground"
11751
11951
  };
11752
- DEFAULT_ASSET_URL4 = {
11952
+ DEFAULT_ASSET_URL3 = {
11753
11953
  url: "https://almadar-kflow-assets.web.app/shared/world-map/gold_mine.png",
11754
11954
  role: "ui",
11755
11955
  category: "coin"
@@ -11763,7 +11963,7 @@ var init_ResourceCounter = __esm({
11763
11963
  }
11764
11964
  });
11765
11965
  function ItemSlot({
11766
- assetUrl = DEFAULT_ASSET_URL5,
11966
+ assetUrl = DEFAULT_ASSET_URL4,
11767
11967
  icon = "sword",
11768
11968
  label = "Iron Sword",
11769
11969
  quantity,
@@ -11818,7 +12018,7 @@ function ItemSlot({
11818
12018
  }
11819
12019
  );
11820
12020
  }
11821
- var sizeMap7, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL5, assetSizeMap;
12021
+ var sizeMap7, rarityBorderMap, rarityGlowMap, DEFAULT_ASSET_URL4, assetSizeMap;
11822
12022
  var init_ItemSlot = __esm({
11823
12023
  "components/game/2d/atoms/ItemSlot.tsx"() {
11824
12024
  "use client";
@@ -11848,7 +12048,7 @@ var init_ItemSlot = __esm({
11848
12048
  epic: "shadow-lg",
11849
12049
  legendary: "shadow-lg"
11850
12050
  };
11851
- DEFAULT_ASSET_URL5 = {
12051
+ DEFAULT_ASSET_URL4 = {
11852
12052
  url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
11853
12053
  role: "item",
11854
12054
  category: "item"
@@ -11862,7 +12062,7 @@ var init_ItemSlot = __esm({
11862
12062
  }
11863
12063
  });
11864
12064
  function TurnIndicator({
11865
- assetUrl = DEFAULT_ASSET_URL6,
12065
+ assetUrl = DEFAULT_ASSET_URL5,
11866
12066
  currentTurn = 1,
11867
12067
  maxTurns,
11868
12068
  activeTeam,
@@ -11902,7 +12102,7 @@ function TurnIndicator({
11902
12102
  }
11903
12103
  );
11904
12104
  }
11905
- var sizeMap8, DEFAULT_ASSET_URL6;
12105
+ var sizeMap8, DEFAULT_ASSET_URL5;
11906
12106
  var init_TurnIndicator = __esm({
11907
12107
  "components/game/2d/atoms/TurnIndicator.tsx"() {
11908
12108
  init_cn();
@@ -11914,7 +12114,7 @@ var init_TurnIndicator = __esm({
11914
12114
  md: { wrapper: "text-sm gap-2 px-3 py-1", dot: "w-2 h-2" },
11915
12115
  lg: { wrapper: "text-base gap-2.5 px-4 py-1.5", dot: "w-2.5 h-2.5" }
11916
12116
  };
11917
- DEFAULT_ASSET_URL6 = {
12117
+ DEFAULT_ASSET_URL5 = {
11918
12118
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/symbol_01.png",
11919
12119
  role: "ui",
11920
12120
  category: "turn"
@@ -11934,7 +12134,7 @@ function getComboScale(combo) {
11934
12134
  return "";
11935
12135
  }
11936
12136
  function ComboCounter({
11937
- assetUrl = DEFAULT_ASSET_URL7,
12137
+ assetUrl = DEFAULT_ASSET_URL6,
11938
12138
  combo = 5,
11939
12139
  multiplier,
11940
12140
  streak,
@@ -11969,14 +12169,14 @@ function ComboCounter({
11969
12169
  }
11970
12170
  );
11971
12171
  }
11972
- var DEFAULT_ASSET_URL7, sizeMap9;
12172
+ var DEFAULT_ASSET_URL6, sizeMap9;
11973
12173
  var init_ComboCounter = __esm({
11974
12174
  "components/game/2d/atoms/ComboCounter.tsx"() {
11975
12175
  init_cn();
11976
12176
  init_Box();
11977
12177
  init_Typography();
11978
12178
  init_GameIcon();
11979
- DEFAULT_ASSET_URL7 = {
12179
+ DEFAULT_ASSET_URL6 = {
11980
12180
  url: "https://almadar-kflow-assets.web.app/shared/effects/flash/flash00.png",
11981
12181
  role: "effect",
11982
12182
  category: "effect"
@@ -11990,7 +12190,7 @@ var init_ComboCounter = __esm({
11990
12190
  }
11991
12191
  });
11992
12192
  function WaypointMarker({
11993
- assetUrl = DEFAULT_ASSET_URL8,
12193
+ assetUrl = DEFAULT_ASSET_URL7,
11994
12194
  label,
11995
12195
  icon,
11996
12196
  active = true,
@@ -12050,7 +12250,7 @@ function WaypointMarker({
12050
12250
  )
12051
12251
  ] });
12052
12252
  }
12053
- var DEFAULT_ASSET_URL8, sizeMap10, checkIcon;
12253
+ var DEFAULT_ASSET_URL7, sizeMap10, checkIcon;
12054
12254
  var init_WaypointMarker = __esm({
12055
12255
  "components/game/2d/atoms/WaypointMarker.tsx"() {
12056
12256
  init_cn();
@@ -12058,7 +12258,7 @@ var init_WaypointMarker = __esm({
12058
12258
  init_Box();
12059
12259
  init_Typography();
12060
12260
  init_GameIcon();
12061
- DEFAULT_ASSET_URL8 = {
12261
+ DEFAULT_ASSET_URL7 = {
12062
12262
  url: "https://almadar-kflow-assets.web.app/shared/world-map/battle_marker.png",
12063
12263
  role: "ui",
12064
12264
  category: "waypoint"
@@ -12079,7 +12279,7 @@ function formatDuration(seconds) {
12079
12279
  return `${Math.round(seconds)}s`;
12080
12280
  }
12081
12281
  function StatusEffect({
12082
- assetUrl = DEFAULT_ASSET_URL9,
12282
+ assetUrl = DEFAULT_ASSET_URL8,
12083
12283
  icon,
12084
12284
  label = "Shield",
12085
12285
  duration = 30,
@@ -12130,7 +12330,7 @@ function StatusEffect({
12130
12330
  label && /* @__PURE__ */ jsx(Typography, { as: "span", className: "text-xs text-muted-foreground mt-0.5 text-center whitespace-nowrap", children: label })
12131
12331
  ] });
12132
12332
  }
12133
- var DEFAULT_ASSET_URL9, sizeMap11, variantStyles7;
12333
+ var DEFAULT_ASSET_URL8, sizeMap11, variantStyles7;
12134
12334
  var init_StatusEffect = __esm({
12135
12335
  "components/game/2d/atoms/StatusEffect.tsx"() {
12136
12336
  init_cn();
@@ -12138,7 +12338,7 @@ var init_StatusEffect = __esm({
12138
12338
  init_Box();
12139
12339
  init_Typography();
12140
12340
  init_GameIcon();
12141
- DEFAULT_ASSET_URL9 = {
12341
+ DEFAULT_ASSET_URL8 = {
12142
12342
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/flame_01.png",
12143
12343
  role: "ui",
12144
12344
  category: "effect"
@@ -12157,7 +12357,7 @@ var init_StatusEffect = __esm({
12157
12357
  }
12158
12358
  });
12159
12359
  function DamageNumber({
12160
- assetUrl = DEFAULT_ASSET_URL10,
12360
+ assetUrl = DEFAULT_ASSET_URL9,
12161
12361
  value = 42,
12162
12362
  type = "damage",
12163
12363
  size = "md",
@@ -12185,7 +12385,7 @@ function DamageNumber({
12185
12385
  )
12186
12386
  ] });
12187
12387
  }
12188
- var sizeMap12, typeStyles, floatKeyframes, DEFAULT_ASSET_URL10;
12388
+ var sizeMap12, typeStyles, floatKeyframes, DEFAULT_ASSET_URL9;
12189
12389
  var init_DamageNumber = __esm({
12190
12390
  "components/game/2d/atoms/DamageNumber.tsx"() {
12191
12391
  init_cn();
@@ -12209,7 +12409,7 @@ var init_DamageNumber = __esm({
12209
12409
  100% { opacity: 0; transform: translateY(-32px) scale(0.8); }
12210
12410
  }
12211
12411
  `;
12212
- DEFAULT_ASSET_URL10 = {
12412
+ DEFAULT_ASSET_URL9 = {
12213
12413
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/spark_01.png",
12214
12414
  role: "effect",
12215
12415
  category: "effect"
@@ -12335,7 +12535,7 @@ var init_ChoiceButton = __esm({
12335
12535
  }
12336
12536
  });
12337
12537
  function ActionButton({
12338
- assetUrl = DEFAULT_ASSET_URL11,
12538
+ assetUrl = DEFAULT_ASSET_URL10,
12339
12539
  label = "Attack",
12340
12540
  icon,
12341
12541
  cooldown = 0,
@@ -12404,7 +12604,7 @@ function ActionButton({
12404
12604
  }
12405
12605
  );
12406
12606
  }
12407
- var sizeMap13, variantStyles8, DEFAULT_ASSET_URL11;
12607
+ var sizeMap13, variantStyles8, DEFAULT_ASSET_URL10;
12408
12608
  var init_ActionButton = __esm({
12409
12609
  "components/game/2d/atoms/ActionButton.tsx"() {
12410
12610
  init_cn();
@@ -12424,7 +12624,7 @@ var init_ActionButton = __esm({
12424
12624
  secondary: "bg-secondary text-secondary-foreground hover:bg-secondary-hover border-border",
12425
12625
  danger: "bg-error text-error-foreground hover:bg-error/90 border-error"
12426
12626
  };
12427
- DEFAULT_ASSET_URL11 = {
12627
+ DEFAULT_ASSET_URL10 = {
12428
12628
  url: "https://almadar-kflow-assets.web.app/shared/effects/particles/slash_01.png",
12429
12629
  role: "ui",
12430
12630
  category: "action"
@@ -12444,8 +12644,8 @@ function MiniMap({
12444
12644
  tileAssets,
12445
12645
  unitAssets
12446
12646
  }) {
12447
- const canvasRef = React104.useRef(null);
12448
- const imgCacheRef = React104.useRef(/* @__PURE__ */ new Map());
12647
+ const canvasRef = React105.useRef(null);
12648
+ const imgCacheRef = React105.useRef(/* @__PURE__ */ new Map());
12449
12649
  function loadImg(url) {
12450
12650
  const cached = imgCacheRef.current.get(url);
12451
12651
  if (cached) return cached.complete ? cached : null;
@@ -12460,7 +12660,7 @@ function MiniMap({
12460
12660
  imgCacheRef.current.set(url, img);
12461
12661
  return null;
12462
12662
  }
12463
- React104.useEffect(() => {
12663
+ React105.useEffect(() => {
12464
12664
  const canvas = canvasRef.current;
12465
12665
  if (!canvas) return;
12466
12666
  const ctx = canvas.getContext("2d");
@@ -12595,8 +12795,8 @@ function ControlGrid({
12595
12795
  className
12596
12796
  }) {
12597
12797
  const eventBus = useEventBus();
12598
- const [active, setActive] = React104.useState(/* @__PURE__ */ new Set());
12599
- const handlePress = React104.useCallback(
12798
+ const [active, setActive] = React105.useState(/* @__PURE__ */ new Set());
12799
+ const handlePress = React105.useCallback(
12600
12800
  (id) => {
12601
12801
  setActive((prev) => new Set(prev).add(id));
12602
12802
  if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
@@ -12610,7 +12810,7 @@ function ControlGrid({
12610
12810
  },
12611
12811
  [kind, actionEvent, directionEvent, directionEvents, eventBus, onAction, onDirection]
12612
12812
  );
12613
- const handleRelease = React104.useCallback(
12813
+ const handleRelease = React105.useCallback(
12614
12814
  (id) => {
12615
12815
  setActive((prev) => {
12616
12816
  const next = new Set(prev);
@@ -12868,7 +13068,7 @@ function InventoryGrid({
12868
13068
  const eventBus = useEventBus();
12869
13069
  const slotCount = totalSlots ?? items.length;
12870
13070
  const emptySlotCount = Math.max(0, slotCount - items.length);
12871
- const handleSelect = React104.useCallback(
13071
+ const handleSelect = React105.useCallback(
12872
13072
  (id) => {
12873
13073
  onSelect?.(id);
12874
13074
  if (selectEvent) {
@@ -13085,7 +13285,7 @@ function GameMenu({
13085
13285
  }) {
13086
13286
  const resolvedOptions = options ?? menuItems ?? DEFAULT_MENU_OPTIONS;
13087
13287
  const eventBus = useEventBus();
13088
- const handleOptionClick = React104.useCallback(
13288
+ const handleOptionClick = React105.useCallback(
13089
13289
  (option) => {
13090
13290
  if (option.event) {
13091
13291
  eventBus.emit(`UI:${option.event}`, { option });
@@ -13311,7 +13511,7 @@ function StateGraph({
13311
13511
  }) {
13312
13512
  const eventBus = useEventBus();
13313
13513
  const nodes = states ?? [];
13314
- const positions = React104.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
13514
+ const positions = React105.useMemo(() => layoutStates(nodes, width, height), [nodes, width, height]);
13315
13515
  return /* @__PURE__ */ jsxs(
13316
13516
  Box,
13317
13517
  {
@@ -13777,11 +13977,11 @@ function SideView({
13777
13977
  const canvasRef = useRef(null);
13778
13978
  const eventBus = useEventBus();
13779
13979
  const keysRef = useRef(/* @__PURE__ */ new Set());
13780
- const imageCache = useRef(/* @__PURE__ */ new Map());
13980
+ const imageCache2 = useRef(/* @__PURE__ */ new Map());
13781
13981
  const [loadedImages, setLoadedImages] = useState(/* @__PURE__ */ new Set());
13782
13982
  const loadImage = useCallback((url) => {
13783
13983
  if (!url) return null;
13784
- const cached = imageCache.current.get(url);
13984
+ const cached = imageCache2.current.get(url);
13785
13985
  if (cached?.complete && cached.naturalWidth > 0) {
13786
13986
  if (!loadedImages.has(url)) setLoadedImages((prev) => new Set(prev).add(url));
13787
13987
  return cached;
@@ -13791,7 +13991,7 @@ function SideView({
13791
13991
  img.crossOrigin = "anonymous";
13792
13992
  img.src = url;
13793
13993
  img.onload = () => setLoadedImages((prev) => new Set(prev).add(url));
13794
- imageCache.current.set(url, img);
13994
+ imageCache2.current.set(url, img);
13795
13995
  }
13796
13996
  return null;
13797
13997
  }, [loadedImages]);
@@ -13908,7 +14108,10 @@ function SideView({
13908
14108
  camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
13909
14109
  }
13910
14110
  const bgImage = bgImg ? loadImage(bgImg.url) : null;
13911
- if (bgImage) {
14111
+ const bgSrc = bgImage ? resolveAssetSource(bgImage, bgImg, NOOP) : null;
14112
+ if (bgSrc) {
14113
+ blit(ctx, bgSrc, 0, 0, cw, ch);
14114
+ } else if (bgImage) {
13912
14115
  ctx.drawImage(bgImage, 0, 0, cw, ch);
13913
14116
  } else if (bg) {
13914
14117
  ctx.fillStyle = bg;
@@ -13941,15 +14144,18 @@ function SideView({
13941
14144
  const platType = plat.type ?? "ground";
13942
14145
  const spriteAsset = tSprites?.[platType];
13943
14146
  const tileImg = spriteAsset ? loadImage(spriteAsset.url) : null;
13944
- if (tileImg) {
13945
- const tileW = tileImg.naturalWidth;
13946
- const tileH = tileImg.naturalHeight;
14147
+ const tileSrc = tileImg ? resolveAssetSource(tileImg, spriteAsset, NOOP) : null;
14148
+ if (tileSrc) {
14149
+ const originX = tileSrc.rect ? tileSrc.rect.sx : 0;
14150
+ const originY = tileSrc.rect ? tileSrc.rect.sy : 0;
14151
+ const tileW = tileSrc.rect ? tileSrc.rect.sw : tileImg.naturalWidth;
14152
+ const tileH = tileSrc.rect ? tileSrc.rect.sh : tileImg.naturalHeight;
13947
14153
  const scaleH = plat.height / tileH;
13948
14154
  const scaledW = tileW * scaleH;
13949
14155
  for (let tx = 0; tx < plat.width; tx += scaledW) {
13950
14156
  const drawW = Math.min(scaledW, plat.width - tx);
13951
14157
  const srcW = drawW / scaleH;
13952
- ctx.drawImage(tileImg, 0, 0, srcW, tileH, platX + tx, platY, drawW, plat.height);
14158
+ ctx.drawImage(tileImg, originX, originY, srcW, tileH, platX + tx, platY, drawW, plat.height);
13953
14159
  }
13954
14160
  } else {
13955
14161
  const color = PLATFORM_COLORS[platType] ?? PLATFORM_COLORS.ground;
@@ -13983,14 +14189,15 @@ function SideView({
13983
14189
  const ppy = py - camY;
13984
14190
  const facingRight = auth.facingRight ?? true;
13985
14191
  const playerImg = pSprite ? loadImage(pSprite.url) : null;
13986
- if (playerImg) {
14192
+ const playerSrc = playerImg ? resolveAssetSource(playerImg, pSprite, NOOP) : null;
14193
+ if (playerSrc) {
13987
14194
  ctx.save();
13988
14195
  if (!facingRight) {
13989
14196
  ctx.translate(ppx + pw, ppy);
13990
14197
  ctx.scale(-1, 1);
13991
- ctx.drawImage(playerImg, 0, 0, pw, ph);
14198
+ blit(ctx, playerSrc, 0, 0, pw, ph);
13992
14199
  } else {
13993
- ctx.drawImage(playerImg, ppx, ppy, pw, ph);
14200
+ blit(ctx, playerSrc, ppx, ppy, pw, ph);
13994
14201
  }
13995
14202
  ctx.restore();
13996
14203
  } else {
@@ -14102,6 +14309,7 @@ function Canvas2D({
14102
14309
  const isSide = projection === "side";
14103
14310
  const isFree = projection === "free";
14104
14311
  const flatLike = projection === "hex" || projection === "flat" || isFree;
14312
+ const squareGrid = projection === "flat";
14105
14313
  const tilesProp = Array.isArray(_tilesPropRaw) ? _tilesPropRaw : [];
14106
14314
  const unitsProp = Array.isArray(_unitsPropRaw) ? _unitsPropRaw : [];
14107
14315
  const featuresProp = Array.isArray(_featuresPropRaw) ? _featuresPropRaw : [];
@@ -14184,17 +14392,18 @@ function Canvas2D({
14184
14392
  const effectiveDiamondTopY = diamondTopYProp ?? DIAMOND_TOP_Y;
14185
14393
  const scaledDiamondTopY = effectiveDiamondTopY * scale;
14186
14394
  const baseOffsetX = useMemo(() => {
14187
- if (isFree) return 0;
14395
+ if (isFree || projection === "flat") return 0;
14188
14396
  return (gridHeight - 1) * (scaledTileWidth / 2);
14189
- }, [isFree, gridHeight, scaledTileWidth]);
14397
+ }, [isFree, projection, gridHeight, scaledTileWidth]);
14190
14398
  const validMoveSet = useMemo(() => new Set(validMoves.map((p) => `${p.x},${p.y}`)), [validMoves]);
14191
14399
  const attackTargetSet = useMemo(() => new Set(attackTargets.map((p) => `${p.x},${p.y}`)), [attackTargets]);
14192
14400
  const spriteUrls = useMemo(() => {
14193
14401
  const urls = [];
14402
+ const toUrl = (x) => typeof x === "string" ? x : x?.url;
14194
14403
  for (const tile of sortedTiles) {
14195
14404
  if (tile.terrainSprite) urls.push(tile.terrainSprite.url);
14196
14405
  else if (getTerrainSprite) {
14197
- const url = getTerrainSprite(tile.terrain ?? "");
14406
+ const url = toUrl(getTerrainSprite(tile.terrain ?? ""));
14198
14407
  if (url) urls.push(url);
14199
14408
  } else {
14200
14409
  const url = assetManifest?.terrains?.[tile.terrain ?? ""]?.url;
@@ -14204,7 +14413,7 @@ function Canvas2D({
14204
14413
  for (const feature of features) {
14205
14414
  if (feature.sprite) urls.push(feature.sprite.url);
14206
14415
  else if (getFeatureSprite) {
14207
- const url = getFeatureSprite(feature.type);
14416
+ const url = toUrl(getFeatureSprite(feature.type));
14208
14417
  if (url) urls.push(url);
14209
14418
  } else {
14210
14419
  const url = assetManifest?.features?.[feature.type]?.url;
@@ -14214,7 +14423,7 @@ function Canvas2D({
14214
14423
  for (const unit of units) {
14215
14424
  if (unit.sprite) urls.push(unit.sprite.url);
14216
14425
  else if (getUnitSprite) {
14217
- const url = getUnitSprite(unit);
14426
+ const url = toUrl(getUnitSprite(unit));
14218
14427
  if (url) urls.push(url);
14219
14428
  } else if (unit.unitType) {
14220
14429
  const url = assetManifest?.units?.[unit.unitType]?.url;
@@ -14255,14 +14464,25 @@ function Canvas2D({
14255
14464
  screenToWorld,
14256
14465
  lerpToTarget
14257
14466
  } = useCamera();
14258
- const resolveTerrainSpriteUrl = useCallback((tile) => {
14259
- return tile.terrainSprite?.url || getTerrainSprite?.(tile.terrain ?? "") || assetManifest?.terrains?.[tile.terrain ?? ""]?.url;
14467
+ const [, setAtlasVersion] = useState(0);
14468
+ const bumpAtlas = useCallback(() => setAtlasVersion((v) => v + 1), []);
14469
+ const resolveTerrainAsset = useCallback((tile) => {
14470
+ if (tile.terrainSprite) return tile.terrainSprite;
14471
+ const s = getTerrainSprite?.(tile.terrain ?? "");
14472
+ if (s) return typeof s === "string" ? { url: s } : s;
14473
+ return assetManifest?.terrains?.[tile.terrain ?? ""];
14260
14474
  }, [getTerrainSprite, assetManifest]);
14261
- const resolveFeatureSpriteUrl = useCallback((featureType) => {
14262
- return getFeatureSprite?.(featureType) || assetManifest?.features?.[featureType]?.url;
14475
+ const resolveFeatureAsset = useCallback((feature) => {
14476
+ if (feature.sprite) return feature.sprite;
14477
+ const s = getFeatureSprite?.(feature.type);
14478
+ if (s) return typeof s === "string" ? { url: s } : s;
14479
+ return assetManifest?.features?.[feature.type];
14263
14480
  }, [getFeatureSprite, assetManifest]);
14264
- const resolveUnitSpriteUrl = useCallback((unit) => {
14265
- return unit.sprite?.url || getUnitSprite?.(unit) || (unit.unitType ? assetManifest?.units?.[unit.unitType]?.url : void 0);
14481
+ const resolveUnitAsset = useCallback((unit) => {
14482
+ if (unit.sprite) return unit.sprite;
14483
+ const s = getUnitSprite?.(unit);
14484
+ if (s) return typeof s === "string" ? { url: s } : s;
14485
+ return unit.unitType ? assetManifest?.units?.[unit.unitType] : void 0;
14266
14486
  }, [getUnitSprite, assetManifest]);
14267
14487
  const miniMapTiles = useMemo(() => {
14268
14488
  if (!showMinimap) return [];
@@ -14295,7 +14515,13 @@ function Canvas2D({
14295
14515
  ctx.clearRect(0, 0, viewportSize.width, viewportSize.height);
14296
14516
  if (backgroundImage) {
14297
14517
  const bgImg = getImage(backgroundImage.url);
14298
- if (bgImg) {
14518
+ const bgSrc = bgImg ? resolveAssetSource(bgImg, backgroundImage, bumpAtlas) : null;
14519
+ if (bgSrc?.rect) {
14520
+ const k = Math.max(viewportSize.width / bgSrc.rect.sw, viewportSize.height / bgSrc.rect.sh);
14521
+ const dw = bgSrc.rect.sw * k;
14522
+ const dh = bgSrc.rect.sh * k;
14523
+ blit(ctx, bgSrc, (viewportSize.width - dw) / 2, (viewportSize.height - dh) / 2, dw, dh);
14524
+ } else if (bgImg) {
14299
14525
  const cam2 = cameraRef.current;
14300
14526
  const patW = bgImg.naturalWidth;
14301
14527
  const patH = bgImg.naturalHeight;
@@ -14326,18 +14552,23 @@ function Canvas2D({
14326
14552
  if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
14327
14553
  continue;
14328
14554
  }
14329
- const spriteUrl = resolveTerrainSpriteUrl(tile);
14330
- const img = spriteUrl ? getImage(spriteUrl) : null;
14331
- if (img) {
14332
- if (img.naturalWidth === 0) {
14333
- ctx.drawImage(img, pos.x, pos.y, scaledTileWidth, scaledTileHeight);
14334
- } else {
14335
- const drawW = scaledTileWidth;
14336
- const drawH = scaledTileWidth * (img.naturalHeight / img.naturalWidth);
14337
- const drawX = pos.x;
14338
- const drawY = flatLike ? pos.y : pos.y + scaledTileHeight - drawH;
14339
- ctx.drawImage(img, drawX, drawY, drawW, drawH);
14340
- }
14555
+ const terrainAsset = resolveTerrainAsset(tile);
14556
+ const img = terrainAsset?.url ? getImage(terrainAsset.url) : null;
14557
+ const src = img ? resolveAssetSource(img, terrainAsset, bumpAtlas) : null;
14558
+ if (src) {
14559
+ const drawW = scaledTileWidth;
14560
+ const drawH = squareGrid ? scaledTileWidth : scaledTileWidth / src.aspect;
14561
+ const drawX = pos.x;
14562
+ const drawY = flatLike ? pos.y : pos.y + scaledTileHeight - drawH;
14563
+ blit(ctx, src, drawX, drawY, drawW, drawH);
14564
+ } else if (img && img.naturalWidth === 0) {
14565
+ ctx.drawImage(img, pos.x, pos.y, scaledTileWidth, scaledTileHeight);
14566
+ } else if (squareGrid) {
14567
+ ctx.fillStyle = tile.terrain === "water" ? "#3b82f6" : tile.terrain === "mountain" ? "#78716c" : tile.terrain === "stone" ? "#9ca3af" : "#4ade80";
14568
+ ctx.fillRect(pos.x, pos.y, scaledTileWidth, scaledTileWidth);
14569
+ ctx.strokeStyle = "rgba(0,0,0,0.2)";
14570
+ ctx.lineWidth = 1;
14571
+ ctx.strokeRect(pos.x, pos.y, scaledTileWidth, scaledTileWidth);
14341
14572
  } else {
14342
14573
  const centerX = pos.x + scaledTileWidth / 2;
14343
14574
  const topY = pos.y + scaledDiamondTopY;
@@ -14354,9 +14585,13 @@ function Canvas2D({
14354
14585
  ctx.stroke();
14355
14586
  }
14356
14587
  const drawHighlight = (color) => {
14588
+ ctx.fillStyle = color;
14589
+ if (squareGrid) {
14590
+ ctx.fillRect(pos.x, pos.y, scaledTileWidth, scaledTileWidth);
14591
+ return;
14592
+ }
14357
14593
  const centerX = pos.x + scaledTileWidth / 2;
14358
14594
  const topY = pos.y + scaledDiamondTopY;
14359
- ctx.fillStyle = color;
14360
14595
  ctx.beginPath();
14361
14596
  ctx.moveTo(centerX, topY);
14362
14597
  ctx.lineTo(pos.x + scaledTileWidth, topY + scaledFloorHeight / 2);
@@ -14373,7 +14608,7 @@ function Canvas2D({
14373
14608
  if (attackTargetSet.has(tileKey)) drawHighlight("rgba(239, 68, 68, 0.35)");
14374
14609
  if (debug2) {
14375
14610
  const centerX = pos.x + scaledTileWidth / 2;
14376
- const centerY = pos.y + scaledFloorHeight / 2 + scaledDiamondTopY;
14611
+ const centerY = squareGrid ? pos.y + scaledTileWidth / 2 : pos.y + scaledFloorHeight / 2 + scaledDiamondTopY;
14377
14612
  ctx.fillStyle = "rgba(0, 0, 0, 0.7)";
14378
14613
  ctx.font = `${12 * scale * 2}px monospace`;
14379
14614
  ctx.textAlign = "center";
@@ -14391,15 +14626,16 @@ function Canvas2D({
14391
14626
  if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
14392
14627
  continue;
14393
14628
  }
14394
- const spriteUrl = feature.sprite?.url || resolveFeatureSpriteUrl(feature.type);
14395
- const img = spriteUrl ? getImage(spriteUrl) : null;
14629
+ const featureAsset = resolveFeatureAsset(feature);
14630
+ const img = featureAsset?.url ? getImage(featureAsset.url) : null;
14631
+ const src = img ? resolveAssetSource(img, featureAsset, bumpAtlas) : null;
14396
14632
  const centerX = pos.x + scaledTileWidth / 2;
14397
- const featureGroundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
14633
+ const featureGroundY = squareGrid ? pos.y + scaledTileWidth * 0.92 : pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
14398
14634
  const isCastle = feature.type === "castle";
14399
- const featureDrawH = isCastle ? scaledFloorHeight * 3.5 : scaledFloorHeight * 1.6;
14635
+ const featureDrawH = squareGrid ? isCastle ? scaledTileWidth * 1.4 : scaledTileWidth * 0.8 : isCastle ? scaledFloorHeight * 3.5 : scaledFloorHeight * 1.6;
14400
14636
  const maxFeatureW = isCastle ? scaledTileWidth * 1.8 : scaledTileWidth * 0.7;
14401
- if (img) {
14402
- const ar = img.naturalWidth / img.naturalHeight;
14637
+ if (src) {
14638
+ const ar = src.aspect;
14403
14639
  let drawH = featureDrawH;
14404
14640
  let drawW = featureDrawH * ar;
14405
14641
  if (drawW > maxFeatureW) {
@@ -14408,7 +14644,7 @@ function Canvas2D({
14408
14644
  }
14409
14645
  const drawX = centerX - drawW / 2;
14410
14646
  const drawY = featureGroundY - drawH;
14411
- ctx.drawImage(img, drawX, drawY, drawW, drawH);
14647
+ blit(ctx, src, drawX, drawY, drawW, drawH);
14412
14648
  } else {
14413
14649
  const color = FEATURE_COLORS[feature.type] || FEATURE_COLORS.default;
14414
14650
  ctx.beginPath();
@@ -14435,19 +14671,20 @@ function Canvas2D({
14435
14671
  }
14436
14672
  const isSelected = unit.id === selectedUnitId;
14437
14673
  const centerX = pos.x + scaledTileWidth / 2;
14438
- const groundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
14674
+ const groundY = squareGrid ? pos.y + scaledTileWidth * 0.92 : pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
14439
14675
  const breatheOffset = 0;
14440
- const unitSpriteUrl = resolveUnitSpriteUrl(unit);
14441
- const img = unitSpriteUrl ? getImage(unitSpriteUrl) : null;
14442
- const unitDrawH = scaledFloorHeight * spriteHeightRatio * unitScale;
14676
+ const unitAsset = resolveUnitAsset(unit);
14677
+ const img = unitAsset?.url ? getImage(unitAsset.url) : null;
14678
+ const unitDrawH = squareGrid ? scaledTileWidth * 0.55 * spriteHeightRatio * unitScale : scaledFloorHeight * spriteHeightRatio * unitScale;
14443
14679
  const maxUnitW = scaledTileWidth * spriteMaxWidthRatio * unitScale;
14444
14680
  const unitIsSheet = unit.spriteSheet?.url !== void 0;
14681
+ const unitSrc = img && !unitIsSheet ? resolveAssetSource(img, unitAsset, bumpAtlas) : null;
14445
14682
  const SHEET_ROWS = 5;
14446
14683
  const sheetFrameW = img ? img.naturalWidth / SHEET_COLUMNS : 0;
14447
14684
  const sheetFrameH = img ? img.naturalHeight / SHEET_ROWS : 0;
14448
14685
  const frameW = unitIsSheet ? sheetFrameW : img?.naturalWidth ?? 1;
14449
14686
  const frameH = unitIsSheet ? sheetFrameH : img?.naturalHeight ?? 1;
14450
- const ar = frameW / (frameH || 1);
14687
+ const ar = unitIsSheet ? sheetFrameW / (sheetFrameH || 1) : unitSrc ? unitSrc.aspect : frameW / (frameH || 1);
14451
14688
  let drawH = unitDrawH;
14452
14689
  let drawW = unitDrawH * ar;
14453
14690
  if (drawW > maxUnitW) {
@@ -14457,12 +14694,14 @@ function Canvas2D({
14457
14694
  if (unit.previousPosition && (unit.previousPosition.x !== unit.position.x || unit.previousPosition.y !== unit.position.y)) {
14458
14695
  const ghostPos = project(unit.previousPosition.x, unit.previousPosition.y, baseOffsetX);
14459
14696
  const ghostCenterX = ghostPos.x + scaledTileWidth / 2;
14460
- const ghostGroundY = ghostPos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
14697
+ const ghostGroundY = squareGrid ? ghostPos.y + scaledTileWidth * 0.92 : ghostPos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
14461
14698
  ctx.save();
14462
14699
  ctx.globalAlpha = 0.25;
14463
14700
  if (img) {
14464
14701
  if (unitIsSheet) {
14465
14702
  ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
14703
+ } else if (unitSrc) {
14704
+ blit(ctx, unitSrc, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
14466
14705
  } else {
14467
14706
  ctx.drawImage(img, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
14468
14707
  }
@@ -14511,6 +14750,8 @@ function Canvas2D({
14511
14750
  const drawUnit = (x) => {
14512
14751
  if (unitIsSheet) {
14513
14752
  ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, x, spriteY, drawW, drawH);
14753
+ } else if (unitSrc) {
14754
+ blit(ctx, unitSrc, x, spriteY, drawW, drawH);
14514
14755
  } else {
14515
14756
  ctx.drawImage(img, x, spriteY, drawW, drawH);
14516
14757
  }
@@ -14536,17 +14777,24 @@ function Canvas2D({
14536
14777
  }
14537
14778
  }
14538
14779
  for (const fx of effects) {
14539
- const spriteUrl = assetManifest?.effects?.[fx.key]?.url;
14540
- if (!spriteUrl) continue;
14541
- const img = getImage(spriteUrl);
14780
+ const fxAsset = assetManifest?.effects?.[fx.key];
14781
+ if (!fxAsset?.url) continue;
14782
+ const img = getImage(fxAsset.url);
14542
14783
  if (!img) continue;
14784
+ const src = resolveAssetSource(img, fxAsset, bumpAtlas);
14543
14785
  const pos = project(fx.x, fx.y, baseOffsetX);
14544
14786
  const cx = pos.x + scaledTileWidth / 2;
14545
- const cy = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
14787
+ const cy = squareGrid ? pos.y + scaledTileWidth / 2 : pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
14546
14788
  const alpha = Math.min(1, fx.ttl / 4);
14547
14789
  const prev = ctx.globalAlpha;
14548
14790
  ctx.globalAlpha = alpha;
14549
- ctx.drawImage(img, cx - img.naturalWidth / 2, cy - img.naturalHeight / 2);
14791
+ if (src?.rect) {
14792
+ const dw = scaledTileWidth;
14793
+ const dh = dw / src.aspect;
14794
+ blit(ctx, src, cx - dw / 2, cy - dh / 2, dw, dh);
14795
+ } else {
14796
+ ctx.drawImage(img, cx - img.naturalWidth / 2, cy - img.naturalHeight / 2);
14797
+ }
14550
14798
  ctx.globalAlpha = prev;
14551
14799
  }
14552
14800
  onDrawEffects?.(ctx, 0, getImage);
@@ -14559,13 +14807,15 @@ function Canvas2D({
14559
14807
  effects,
14560
14808
  project,
14561
14809
  flatLike,
14810
+ squareGrid,
14562
14811
  scale,
14563
14812
  debug2,
14564
- resolveTerrainSpriteUrl,
14565
- resolveFeatureSpriteUrl,
14566
- resolveUnitSpriteUrl,
14813
+ resolveTerrainAsset,
14814
+ resolveFeatureAsset,
14815
+ resolveUnitAsset,
14567
14816
  resolveFrameForUnit,
14568
14817
  getImage,
14818
+ bumpAtlas,
14569
14819
  baseOffsetX,
14570
14820
  scaledTileWidth,
14571
14821
  scaledTileHeight,
@@ -14591,12 +14841,12 @@ function Canvas2D({
14591
14841
  if (!unit?.position) return;
14592
14842
  const pos = project(unit.position.x, unit.position.y, baseOffsetX);
14593
14843
  const centerX = pos.x + scaledTileWidth / 2;
14594
- const centerY = pos.y + scaledDiamondTopY + scaledFloorHeight / 2;
14844
+ const centerY = squareGrid ? pos.y + scaledTileWidth / 2 : pos.y + scaledDiamondTopY + scaledFloorHeight / 2;
14595
14845
  targetCameraRef.current = {
14596
14846
  x: centerX - viewportSize.width / 2,
14597
14847
  y: centerY - viewportSize.height / 2
14598
14848
  };
14599
- }, [camera, selectedUnitId, units, project, baseOffsetX, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, targetCameraRef]);
14849
+ }, [camera, selectedUnitId, units, project, baseOffsetX, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, viewportSize, targetCameraRef]);
14600
14850
  useEffect(() => {
14601
14851
  if (isSide || !interpolateUnits) return;
14602
14852
  unitInterp.onSnapshot(
@@ -14667,11 +14917,11 @@ function Canvas2D({
14667
14917
  if (!tileHoverEvent || !canvasRef.current) return;
14668
14918
  const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
14669
14919
  const adjustedX = world.x - scaledTileWidth / 2;
14670
- const adjustedY = world.y - scaledDiamondTopY - scaledFloorHeight / 2;
14920
+ const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
14671
14921
  const isoPos = unproject(adjustedX, adjustedY, baseOffsetX);
14672
14922
  const tileExists = tilesProp.some((t2) => t2.x === isoPos.x && t2.y === isoPos.y);
14673
14923
  if (tileExists) eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
14674
- }, [screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, unproject, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
14924
+ }, [screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
14675
14925
  const handleCanvasPointerUp = useCallback((e) => {
14676
14926
  singlePointerActiveRef.current = false;
14677
14927
  if (enableCamera) handlePointerUp();
@@ -14679,7 +14929,7 @@ function Canvas2D({
14679
14929
  if (!canvasRef.current) return;
14680
14930
  const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
14681
14931
  const adjustedX = world.x - scaledTileWidth / 2;
14682
- const adjustedY = world.y - scaledDiamondTopY - scaledFloorHeight / 2;
14932
+ const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
14683
14933
  const isoPos = unproject(adjustedX, adjustedY, baseOffsetX);
14684
14934
  const clickedUnit = units.find((u) => u.position?.x === isoPos.x && u.position?.y === isoPos.y);
14685
14935
  if (clickedUnit && unitClickEvent) {
@@ -14688,7 +14938,7 @@ function Canvas2D({
14688
14938
  const tileExists = tilesProp.some((t2) => t2.x === isoPos.x && t2.y === isoPos.y);
14689
14939
  if (tileExists) eventBus.emit(`UI:${tileClickEvent}`, { x: isoPos.x, y: isoPos.y });
14690
14940
  }
14691
- }, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, unproject, baseOffsetX, units, tilesProp, unitClickEvent, tileClickEvent, eventBus]);
14941
+ }, [enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject, baseOffsetX, units, tilesProp, unitClickEvent, tileClickEvent, eventBus]);
14692
14942
  const handleCanvasPointerLeave = useCallback(() => {
14693
14943
  handleMouseLeave();
14694
14944
  if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
@@ -14738,11 +14988,12 @@ function Canvas2D({
14738
14988
  return units.filter((u) => !!u.position).map((u) => {
14739
14989
  const pos = project(u.position.x, u.position.y, baseOffsetX);
14740
14990
  const cam = cameraRef.current;
14991
+ const anchorY = squareGrid ? pos.y + scaledTileWidth * 0.92 : pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
14741
14992
  const screenX = (pos.x + scaledTileWidth / 2 - (cam.x + viewportSize.width / 2)) * cam.zoom + viewportSize.width / 2;
14742
- const screenY = (pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5 - (cam.y + viewportSize.height / 2)) * cam.zoom + viewportSize.height / 2;
14993
+ const screenY = (anchorY - (cam.y + viewportSize.height / 2)) * cam.zoom + viewportSize.height / 2;
14743
14994
  return { unit: u, screenX, screenY };
14744
14995
  });
14745
- }, [units, project, baseOffsetX, scaledTileWidth, scaledDiamondTopY, scaledFloorHeight, viewportSize, cameraRef]);
14996
+ }, [units, project, baseOffsetX, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, viewportSize, cameraRef]);
14746
14997
  if (error) {
14747
14998
  return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center w-full h-full bg-[var(--color-card)] rounded-container", className), children: /* @__PURE__ */ jsxs(Stack, { direction: "vertical", gap: "md", align: "center", children: [
14748
14999
  /* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: "xl" }),
@@ -14879,7 +15130,7 @@ function Canvas2D({
14879
15130
  }
14880
15131
  );
14881
15132
  }
14882
- var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
15133
+ var PLATFORM_COLORS, NOOP, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
14883
15134
  var init_Canvas2D = __esm({
14884
15135
  "components/game/2d/molecules/Canvas2D.tsx"() {
14885
15136
  "use client";
@@ -14893,6 +15144,7 @@ var init_Canvas2D = __esm({
14893
15144
  init_MiniMap();
14894
15145
  init_HealthBar();
14895
15146
  init_useImageCache();
15147
+ init_atlasSlice();
14896
15148
  init_useCamera();
14897
15149
  init_useCanvasGestures();
14898
15150
  init_useRenderInterpolation();
@@ -14906,6 +15158,8 @@ var init_Canvas2D = __esm({
14906
15158
  hazard: "#c0392b",
14907
15159
  goal: "#f1c40f"
14908
15160
  };
15161
+ NOOP = () => {
15162
+ };
14909
15163
  PLAYER_COLOR = "#3498db";
14910
15164
  PLAYER_EYE_COLOR = "#ffffff";
14911
15165
  SKY_GRADIENT_TOP = "#1a1a2e";
@@ -14985,7 +15239,7 @@ function LinearView({
14985
15239
  /* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
14986
15240
  const isDone = i < currentIdx;
14987
15241
  const isCurrent = i === currentIdx;
14988
- return /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
15242
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
14989
15243
  i > 0 && /* @__PURE__ */ jsx(
14990
15244
  Typography,
14991
15245
  {
@@ -15520,7 +15774,7 @@ function SequenceBar({
15520
15774
  else onSlotRemove?.(index);
15521
15775
  }, [emit, slotRemoveEvent, onSlotRemove, playing]);
15522
15776
  const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
15523
- return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
15777
+ return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
15524
15778
  i > 0 && /* @__PURE__ */ jsx(
15525
15779
  Typography,
15526
15780
  {
@@ -17677,82 +17931,167 @@ var init_GameTemplate = __esm({
17677
17931
  GameTemplate.displayName = "GameTemplate";
17678
17932
  }
17679
17933
  });
17680
- var GameShell;
17934
+ var FONT_BASE, GAME_FONTS, FONT_FACES, GameShell;
17681
17935
  var init_GameShell = __esm({
17682
17936
  "components/game/2d/templates/GameShell.tsx"() {
17683
17937
  init_cn();
17684
17938
  init_Box();
17685
- init_Stack();
17686
17939
  init_Typography();
17940
+ init_AtlasImage();
17941
+ FONT_BASE = "https://almadar-kflow-assets.web.app/shared/_shared/kenney-fonts/fonts";
17942
+ GAME_FONTS = {
17943
+ future: "Kenney Future",
17944
+ "future-narrow": "Kenney Future Narrow",
17945
+ pixel: "Kenney Pixel",
17946
+ blocks: "Kenney Blocks",
17947
+ mini: "Kenney Mini"
17948
+ };
17949
+ FONT_FACES = `
17950
+ @font-face { font-family: 'Kenney Future'; src: url('${FONT_BASE}/Kenney%20Future.ttf') format('truetype'); font-display: swap; }
17951
+ @font-face { font-family: 'Kenney Future Narrow'; src: url('${FONT_BASE}/Kenney%20Future%20Narrow.ttf') format('truetype'); font-display: swap; }
17952
+ @font-face { font-family: 'Kenney Pixel'; src: url('${FONT_BASE}/Kenney%20Pixel.ttf') format('truetype'); font-display: swap; }
17953
+ @font-face { font-family: 'Kenney Blocks'; src: url('${FONT_BASE}/Kenney%20Blocks.ttf') format('truetype'); font-display: swap; }
17954
+ @font-face { font-family: 'Kenney Mini'; src: url('${FONT_BASE}/Kenney%20Mini.ttf') format('truetype'); font-display: swap; }
17955
+ .game-shell, .game-shell * { font-family: inherit; }
17956
+ `;
17687
17957
  GameShell = ({
17688
17958
  appName = "Game",
17689
17959
  hud,
17960
+ addons,
17961
+ controls,
17962
+ overlay,
17690
17963
  className,
17691
17964
  showTopBar = true,
17692
17965
  children,
17693
17966
  backgroundAsset,
17694
- hudBackgroundAsset
17967
+ hudBackgroundAsset,
17968
+ fontFamily = "future"
17695
17969
  }) => {
17970
+ const font = GAME_FONTS[fontFamily] ?? fontFamily;
17696
17971
  return /* @__PURE__ */ jsxs(
17697
17972
  Box,
17698
17973
  {
17699
- display: "flex",
17700
- className: cn(
17701
- "game-shell",
17702
- "flex-col w-full h-screen overflow-hidden",
17703
- className
17704
- ),
17974
+ className: cn("game-shell", className),
17705
17975
  style: {
17976
+ position: "relative",
17706
17977
  width: "100vw",
17707
17978
  height: "100vh",
17708
17979
  overflow: "hidden",
17709
- background: backgroundAsset ? `url(${backgroundAsset.url}) center/cover no-repeat` : "var(--color-background, #0a0a0f)",
17710
- color: "var(--color-text, #e0e0e0)"
17980
+ background: "var(--color-background, #0a0a0f)",
17981
+ color: "var(--color-text, #e0e0e0)",
17982
+ fontFamily: `'${font}', system-ui, sans-serif`
17711
17983
  },
17712
17984
  children: [
17713
- showTopBar && /* @__PURE__ */ jsxs(
17985
+ /* @__PURE__ */ jsx("style", { children: FONT_FACES }),
17986
+ backgroundAsset && /* @__PURE__ */ jsx(
17987
+ AtlasPanel,
17988
+ {
17989
+ asset: backgroundAsset,
17990
+ mode: "repeat",
17991
+ "aria-hidden": true,
17992
+ className: "game-shell__bg",
17993
+ style: { position: "absolute", inset: 0, opacity: 0.18, zIndex: 0, display: "block" }
17994
+ }
17995
+ ),
17996
+ /* @__PURE__ */ jsx(Box, { className: "game-shell__content", style: { position: "absolute", inset: 0, zIndex: 1 }, children }),
17997
+ (showTopBar || hud) && /* @__PURE__ */ jsxs(
17714
17998
  Box,
17715
17999
  {
17716
- className: "game-shell__header",
18000
+ className: "game-shell__top pointer-events-none",
17717
18001
  style: {
17718
- flexShrink: 0,
17719
- background: hudBackgroundAsset ? `url(${hudBackgroundAsset.url}) center/cover no-repeat` : "var(--color-surface, #12121f)",
17720
- borderBottom: "1px solid var(--color-border, #2a2a3a)"
18002
+ position: "absolute",
18003
+ top: 12,
18004
+ left: 12,
18005
+ right: 12,
18006
+ zIndex: 2,
18007
+ display: "flex",
18008
+ alignItems: "flex-start",
18009
+ gap: 12
17721
18010
  },
17722
18011
  children: [
17723
- /* @__PURE__ */ jsx(
17724
- HStack,
18012
+ showTopBar && /* @__PURE__ */ jsx(
18013
+ AtlasPanel,
17725
18014
  {
17726
- align: "center",
17727
- justify: "between",
17728
- style: { padding: "0.375rem 1rem" },
18015
+ asset: hudBackgroundAsset,
18016
+ borderSlice: 12,
18017
+ borderWidth: 10,
18018
+ className: "game-shell__title pointer-events-auto",
18019
+ style: {
18020
+ padding: "6px 16px",
18021
+ background: hudBackgroundAsset ? void 0 : "rgba(18, 18, 31, 0.85)",
18022
+ borderRadius: hudBackgroundAsset ? void 0 : 10,
18023
+ boxShadow: "0 4px 14px rgba(0,0,0,0.45)",
18024
+ flexShrink: 0
18025
+ },
17729
18026
  children: /* @__PURE__ */ jsx(
17730
18027
  Typography,
17731
18028
  {
17732
- variant: "h6",
18029
+ as: "span",
17733
18030
  style: {
17734
18031
  fontWeight: 700,
17735
- letterSpacing: "0.02em"
18032
+ fontSize: "1.05rem",
18033
+ letterSpacing: "0.06em",
18034
+ textShadow: "0 2px 0 rgba(0,0,0,0.5)",
18035
+ whiteSpace: "nowrap"
17736
18036
  },
17737
18037
  children: appName
17738
18038
  }
17739
18039
  )
17740
18040
  }
17741
18041
  ),
17742
- hud && /* @__PURE__ */ jsx(Box, { className: "game-shell__hud", style: { width: "100%" }, children: hud })
18042
+ hud && /* @__PURE__ */ jsx(Box, { className: "game-shell__hud pointer-events-auto", style: { flex: 1, minWidth: 0 }, children: hud })
17743
18043
  ]
17744
18044
  }
17745
18045
  ),
17746
- /* @__PURE__ */ jsx(
18046
+ controls && /* @__PURE__ */ jsx(
17747
18047
  Box,
17748
18048
  {
17749
- className: "game-shell__content",
18049
+ className: "game-shell__controls pointer-events-auto",
17750
18050
  style: {
17751
- flex: 1,
17752
- overflow: "hidden",
17753
- position: "relative"
18051
+ position: "absolute",
18052
+ left: 16,
18053
+ bottom: 16,
18054
+ zIndex: 2,
18055
+ display: "flex",
18056
+ flexDirection: "column",
18057
+ alignItems: "flex-start",
18058
+ gap: 10,
18059
+ filter: "drop-shadow(0 6px 12px rgba(0,0,0,0.5))"
17754
18060
  },
17755
- children
18061
+ children: controls
18062
+ }
18063
+ ),
18064
+ addons && /* @__PURE__ */ jsx(
18065
+ Box,
18066
+ {
18067
+ className: "game-shell__actions pointer-events-auto",
18068
+ style: {
18069
+ position: "absolute",
18070
+ right: 16,
18071
+ bottom: 16,
18072
+ zIndex: 2,
18073
+ display: "flex",
18074
+ flexDirection: "column",
18075
+ alignItems: "flex-end",
18076
+ gap: 10,
18077
+ filter: "drop-shadow(0 6px 12px rgba(0,0,0,0.5))"
18078
+ },
18079
+ children: addons
18080
+ }
18081
+ ),
18082
+ overlay && /* @__PURE__ */ jsx(
18083
+ Box,
18084
+ {
18085
+ className: "game-shell__overlay pointer-events-none",
18086
+ style: {
18087
+ position: "absolute",
18088
+ inset: 0,
18089
+ zIndex: 3,
18090
+ display: "flex",
18091
+ alignItems: "center",
18092
+ justifyContent: "center"
18093
+ },
18094
+ children: /* @__PURE__ */ jsx(Box, { className: "pointer-events-auto", children: overlay })
17756
18095
  }
17757
18096
  )
17758
18097
  ]
@@ -18166,7 +18505,7 @@ var init_ErrorBoundary = __esm({
18166
18505
  }
18167
18506
  );
18168
18507
  };
18169
- ErrorBoundary = class extends React104__default.Component {
18508
+ ErrorBoundary = class extends React105__default.Component {
18170
18509
  constructor(props) {
18171
18510
  super(props);
18172
18511
  __publicField(this, "reset", () => {
@@ -18448,7 +18787,7 @@ var init_Container = __esm({
18448
18787
  as: Component = "div"
18449
18788
  }) => {
18450
18789
  const resolvedSize = maxWidth ?? size ?? "lg";
18451
- return React104__default.createElement(
18790
+ return React105__default.createElement(
18452
18791
  Component,
18453
18792
  {
18454
18793
  className: cn(
@@ -19564,6 +19903,153 @@ var init_ComponentPatterns = __esm({
19564
19903
  AlertPattern.displayName = "AlertPattern";
19565
19904
  }
19566
19905
  });
19906
+ var DEFAULT_BAR_COLOR, DEFAULT_CELL_COLOR, DEFAULT_POINTER_COLOR, POINTER_BAND, TOP_PAD, AlgorithmCanvas;
19907
+ var init_AlgorithmCanvas = __esm({
19908
+ "components/learning/molecules/AlgorithmCanvas.tsx"() {
19909
+ "use client";
19910
+ init_atoms();
19911
+ init_Stack();
19912
+ init_LearningCanvas();
19913
+ DEFAULT_BAR_COLOR = "#3b82f6";
19914
+ DEFAULT_CELL_COLOR = "#e5e7eb";
19915
+ DEFAULT_POINTER_COLOR = "#dc2626";
19916
+ POINTER_BAND = 34;
19917
+ TOP_PAD = 12;
19918
+ AlgorithmCanvas = ({
19919
+ className,
19920
+ width = 600,
19921
+ height = 400,
19922
+ title,
19923
+ backgroundColor,
19924
+ bars = [],
19925
+ cells = [],
19926
+ pointers = [],
19927
+ shapes = [],
19928
+ interactive = false,
19929
+ animate = false,
19930
+ onShapeClick,
19931
+ isLoading,
19932
+ error
19933
+ }) => {
19934
+ const derivedShapes = useMemo(() => {
19935
+ const out = [];
19936
+ if (bars.length > 0) {
19937
+ const slot = width / bars.length;
19938
+ const barW = slot * 0.8;
19939
+ const gap = slot * 0.1;
19940
+ const baseline = height - POINTER_BAND;
19941
+ const usableH = baseline - TOP_PAD;
19942
+ const maxV = Math.max(1, ...bars.map((b) => Number.isFinite(b.value) ? b.value : 0));
19943
+ bars.forEach((bar, i) => {
19944
+ const v = Number.isFinite(bar.value) ? bar.value : 0;
19945
+ const bh = Math.max(0, v / maxV * usableH);
19946
+ const x = i * slot + gap;
19947
+ const color = bar.color ?? DEFAULT_BAR_COLOR;
19948
+ out.push({
19949
+ type: "rect",
19950
+ id: `bar-${i}`,
19951
+ x,
19952
+ y: baseline - bh,
19953
+ width: barW,
19954
+ height: bh,
19955
+ color,
19956
+ fill: color
19957
+ });
19958
+ const label = bar.label ?? (bars.length <= 24 ? String(v) : void 0);
19959
+ if (label) {
19960
+ out.push({
19961
+ type: "text",
19962
+ x: x + barW / 2,
19963
+ y: baseline - bh - 8,
19964
+ text: label,
19965
+ color: "#374151",
19966
+ fontSize: 11,
19967
+ align: "center"
19968
+ });
19969
+ }
19970
+ });
19971
+ pointers.forEach((p) => {
19972
+ if (p.index < 0 || p.index >= bars.length) return;
19973
+ const cx = p.index * slot + slot / 2;
19974
+ const color = p.color ?? DEFAULT_POINTER_COLOR;
19975
+ out.push({
19976
+ type: "arrow",
19977
+ x1: cx,
19978
+ y1: height - 6,
19979
+ x2: cx,
19980
+ y2: baseline + 4,
19981
+ color,
19982
+ lineWidth: 2
19983
+ });
19984
+ if (p.label) {
19985
+ out.push({
19986
+ type: "text",
19987
+ x: cx,
19988
+ y: height - 22,
19989
+ text: p.label,
19990
+ color,
19991
+ fontSize: 11,
19992
+ align: "center"
19993
+ });
19994
+ }
19995
+ });
19996
+ }
19997
+ if (cells.length > 0) {
19998
+ const maxCol = Math.max(0, ...cells.map((c) => c.col)) + 1;
19999
+ const maxRow = Math.max(0, ...cells.map((c) => c.row)) + 1;
20000
+ const cw = width / maxCol;
20001
+ const ch = height / maxRow;
20002
+ cells.forEach((c, i) => {
20003
+ const x = c.col * cw;
20004
+ const y = c.row * ch;
20005
+ const color = c.color ?? DEFAULT_CELL_COLOR;
20006
+ out.push({
20007
+ type: "rect",
20008
+ id: `cell-${i}`,
20009
+ x: x + 1,
20010
+ y: y + 1,
20011
+ width: cw - 2,
20012
+ height: ch - 2,
20013
+ color: "#9ca3af",
20014
+ fill: color
20015
+ });
20016
+ const label = c.label ?? (c.value != null ? String(c.value) : void 0);
20017
+ if (label && cw >= 18 && ch >= 14) {
20018
+ out.push({
20019
+ type: "text",
20020
+ x: x + cw / 2,
20021
+ y: y + ch / 2,
20022
+ text: label,
20023
+ color: "#111827",
20024
+ fontSize: 12,
20025
+ align: "center"
20026
+ });
20027
+ }
20028
+ });
20029
+ }
20030
+ out.push(...shapes);
20031
+ return out;
20032
+ }, [bars, cells, pointers, shapes, width, height]);
20033
+ return /* @__PURE__ */ jsx(Card, { className, children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
20034
+ title ? /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title }) : null,
20035
+ /* @__PURE__ */ jsx(
20036
+ LearningCanvas,
20037
+ {
20038
+ width,
20039
+ height,
20040
+ backgroundColor,
20041
+ shapes: derivedShapes,
20042
+ interactive,
20043
+ animate,
20044
+ onShapeClick,
20045
+ isLoading,
20046
+ error
20047
+ }
20048
+ )
20049
+ ] }) });
20050
+ };
20051
+ }
20052
+ });
19567
20053
  var AuthLayout;
19568
20054
  var init_AuthLayout = __esm({
19569
20055
  "components/marketing/templates/AuthLayout.tsx"() {
@@ -20289,7 +20775,7 @@ var init_CodeBlock = __esm({
20289
20775
  DIFF_STYLE_FALLBACK = { bg: "", prefix: " ", text: "text-foreground" };
20290
20776
  LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
20291
20777
  HIDDEN_LINE_NUMBERS = { display: "none" };
20292
- CodeBlock = React104__default.memo(
20778
+ CodeBlock = React105__default.memo(
20293
20779
  ({
20294
20780
  code: rawCode,
20295
20781
  language = "text",
@@ -20876,7 +21362,7 @@ var init_MarkdownContent = __esm({
20876
21362
  init_Box();
20877
21363
  init_CodeBlock();
20878
21364
  init_cn();
20879
- MarkdownContent = React104__default.memo(
21365
+ MarkdownContent = React105__default.memo(
20880
21366
  ({ content, direction = "ltr", className }) => {
20881
21367
  const { t: _t } = useTranslate();
20882
21368
  const safeContent = typeof content === "string" ? content : String(content ?? "");
@@ -22203,7 +22689,7 @@ var init_StateMachineView = __esm({
22203
22689
  style: { top: title ? 30 : 0 },
22204
22690
  children: [
22205
22691
  entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
22206
- states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React104__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
22692
+ states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React105__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
22207
22693
  StateNode2,
22208
22694
  {
22209
22695
  state,
@@ -27841,8 +28327,8 @@ var init_Menu = __esm({
27841
28327
  "bottom-end": "bottom-start"
27842
28328
  };
27843
28329
  const effectivePosition = direction === "rtl" ? rtlMirror[position] ?? position : position;
27844
- const triggerChild = React104__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
27845
- const triggerElement = React104__default.cloneElement(
28330
+ const triggerChild = React105__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx(Typography, { variant: "small", as: "span", children: trigger });
28331
+ const triggerElement = React105__default.cloneElement(
27846
28332
  triggerChild,
27847
28333
  {
27848
28334
  ref: triggerRef,
@@ -27937,14 +28423,14 @@ function useDataDnd(args) {
27937
28423
  const isZone = Boolean(dragGroup || accepts || sortable);
27938
28424
  const enabled = isZone || Boolean(dndRoot);
27939
28425
  const eventBus = useEventBus();
27940
- const parentRoot = React104__default.useContext(RootCtx);
28426
+ const parentRoot = React105__default.useContext(RootCtx);
27941
28427
  const isRoot = enabled && parentRoot === null;
27942
- const zoneId = React104__default.useId();
28428
+ const zoneId = React105__default.useId();
27943
28429
  const ownGroup = dragGroup ?? accepts ?? zoneId;
27944
- const [optimisticOrders, setOptimisticOrders] = React104__default.useState(() => /* @__PURE__ */ new Map());
27945
- const optimisticOrdersRef = React104__default.useRef(optimisticOrders);
28430
+ const [optimisticOrders, setOptimisticOrders] = React105__default.useState(() => /* @__PURE__ */ new Map());
28431
+ const optimisticOrdersRef = React105__default.useRef(optimisticOrders);
27946
28432
  optimisticOrdersRef.current = optimisticOrders;
27947
- const clearOptimisticOrder = React104__default.useCallback((group) => {
28433
+ const clearOptimisticOrder = React105__default.useCallback((group) => {
27948
28434
  setOptimisticOrders((prev) => {
27949
28435
  if (!prev.has(group)) return prev;
27950
28436
  const next = new Map(prev);
@@ -27969,7 +28455,7 @@ function useDataDnd(args) {
27969
28455
  const raw = it[dndItemIdField];
27970
28456
  return raw != null ? String(raw) : `__idx_${idx}`;
27971
28457
  }).join("|");
27972
- const itemIds = React104__default.useMemo(
28458
+ const itemIds = React105__default.useMemo(
27973
28459
  () => orderedItems.map((it, idx) => {
27974
28460
  const raw = it[dndItemIdField];
27975
28461
  return raw != null ? String(raw) : `__idx_${idx}`;
@@ -27980,7 +28466,7 @@ function useDataDnd(args) {
27980
28466
  const raw = it[dndItemIdField];
27981
28467
  return raw != null ? String(raw) : `__${idx}`;
27982
28468
  }).join("|");
27983
- React104__default.useEffect(() => {
28469
+ React105__default.useEffect(() => {
27984
28470
  const root = isRoot ? null : parentRoot;
27985
28471
  if (root) {
27986
28472
  root.clearOptimisticOrder(ownGroup);
@@ -27988,20 +28474,20 @@ function useDataDnd(args) {
27988
28474
  clearOptimisticOrder(ownGroup);
27989
28475
  }
27990
28476
  }, [itemsContentSig, ownGroup]);
27991
- const zonesRef = React104__default.useRef(/* @__PURE__ */ new Map());
27992
- const registerZone = React104__default.useCallback((zoneId2, meta2) => {
28477
+ const zonesRef = React105__default.useRef(/* @__PURE__ */ new Map());
28478
+ const registerZone = React105__default.useCallback((zoneId2, meta2) => {
27993
28479
  zonesRef.current.set(zoneId2, meta2);
27994
28480
  }, []);
27995
- const unregisterZone = React104__default.useCallback((zoneId2) => {
28481
+ const unregisterZone = React105__default.useCallback((zoneId2) => {
27996
28482
  zonesRef.current.delete(zoneId2);
27997
28483
  }, []);
27998
- const [activeDrag, setActiveDrag] = React104__default.useState(null);
27999
- const [overZoneGroup, setOverZoneGroup] = React104__default.useState(null);
28000
- const meta = React104__default.useMemo(
28484
+ const [activeDrag, setActiveDrag] = React105__default.useState(null);
28485
+ const [overZoneGroup, setOverZoneGroup] = React105__default.useState(null);
28486
+ const meta = React105__default.useMemo(
28001
28487
  () => ({ group: ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, rawItems: items, idField: dndItemIdField }),
28002
28488
  [ownGroup, dropEvent, reorderEvent, positionEvent, itemIds, items, dndItemIdField]
28003
28489
  );
28004
- React104__default.useEffect(() => {
28490
+ React105__default.useEffect(() => {
28005
28491
  const target = isRoot ? null : parentRoot;
28006
28492
  if (!target) {
28007
28493
  zonesRef.current.set(zoneId, meta);
@@ -28020,7 +28506,7 @@ function useDataDnd(args) {
28020
28506
  }, [parentRoot, isRoot, zoneId, meta]);
28021
28507
  const sensors = useAlmadarDndSensors(true);
28022
28508
  const collisionDetection = almadarDndCollisionDetection;
28023
- const findZoneByItem = React104__default.useCallback(
28509
+ const findZoneByItem = React105__default.useCallback(
28024
28510
  (id) => {
28025
28511
  for (const z of zonesRef.current.values()) {
28026
28512
  if (z.itemIds.includes(id)) return z;
@@ -28029,7 +28515,7 @@ function useDataDnd(args) {
28029
28515
  },
28030
28516
  []
28031
28517
  );
28032
- React104__default.useCallback(
28518
+ React105__default.useCallback(
28033
28519
  (group) => {
28034
28520
  for (const z of zonesRef.current.values()) {
28035
28521
  if (z.group === group) return z;
@@ -28038,7 +28524,7 @@ function useDataDnd(args) {
28038
28524
  },
28039
28525
  []
28040
28526
  );
28041
- const handleDragEnd = React104__default.useCallback(
28527
+ const handleDragEnd = React105__default.useCallback(
28042
28528
  (event) => {
28043
28529
  const { active, over } = event;
28044
28530
  const activeIdStr = String(active.id);
@@ -28129,8 +28615,8 @@ function useDataDnd(args) {
28129
28615
  },
28130
28616
  [eventBus]
28131
28617
  );
28132
- const sortableData = React104__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
28133
- const SortableItem = React104__default.useCallback(
28618
+ const sortableData = React105__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
28619
+ const SortableItem = React105__default.useCallback(
28134
28620
  ({ id, children }) => {
28135
28621
  const {
28136
28622
  attributes,
@@ -28170,7 +28656,7 @@ function useDataDnd(args) {
28170
28656
  id: droppableId,
28171
28657
  data: sortableData
28172
28658
  });
28173
- const ctx = React104__default.useContext(RootCtx);
28659
+ const ctx = React105__default.useContext(RootCtx);
28174
28660
  const activeDrag2 = ctx?.activeDrag ?? null;
28175
28661
  const overZoneGroup2 = ctx?.overZoneGroup ?? null;
28176
28662
  const isThisZoneOver = overZoneGroup2 === ownGroup;
@@ -28185,7 +28671,7 @@ function useDataDnd(args) {
28185
28671
  showForeignPlaceholder,
28186
28672
  ctxAvailable: ctx != null
28187
28673
  });
28188
- React104__default.useEffect(() => {
28674
+ React105__default.useEffect(() => {
28189
28675
  dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
28190
28676
  }, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
28191
28677
  return /* @__PURE__ */ jsx(
@@ -28199,11 +28685,11 @@ function useDataDnd(args) {
28199
28685
  }
28200
28686
  );
28201
28687
  };
28202
- const rootContextValue = React104__default.useMemo(
28688
+ const rootContextValue = React105__default.useMemo(
28203
28689
  () => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
28204
28690
  [registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
28205
28691
  );
28206
- const handleDragStart = React104__default.useCallback((event) => {
28692
+ const handleDragStart = React105__default.useCallback((event) => {
28207
28693
  const sourceZone = findZoneByItem(event.active.id);
28208
28694
  const rect = event.active.rect.current.initial;
28209
28695
  const height = rect?.height && rect.height > 0 ? rect.height : 64;
@@ -28222,7 +28708,7 @@ function useDataDnd(args) {
28222
28708
  isRoot
28223
28709
  });
28224
28710
  }, [findZoneByItem, isRoot, zoneId]);
28225
- const handleDragOver = React104__default.useCallback((event) => {
28711
+ const handleDragOver = React105__default.useCallback((event) => {
28226
28712
  const { active, over } = event;
28227
28713
  const overData = over?.data?.current;
28228
28714
  const overGroup = overData?.dndGroup ?? null;
@@ -28292,7 +28778,7 @@ function useDataDnd(args) {
28292
28778
  return next;
28293
28779
  });
28294
28780
  }, []);
28295
- const handleDragCancel = React104__default.useCallback((event) => {
28781
+ const handleDragCancel = React105__default.useCallback((event) => {
28296
28782
  setActiveDrag(null);
28297
28783
  setOverZoneGroup(null);
28298
28784
  dndLog.warn("dragCancel", {
@@ -28300,12 +28786,12 @@ function useDataDnd(args) {
28300
28786
  reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
28301
28787
  });
28302
28788
  }, []);
28303
- const handleDragEndWithCleanup = React104__default.useCallback((event) => {
28789
+ const handleDragEndWithCleanup = React105__default.useCallback((event) => {
28304
28790
  handleDragEnd(event);
28305
28791
  setActiveDrag(null);
28306
28792
  setOverZoneGroup(null);
28307
28793
  }, [handleDragEnd]);
28308
- const wrapContainer = React104__default.useCallback(
28794
+ const wrapContainer = React105__default.useCallback(
28309
28795
  (children) => {
28310
28796
  if (!enabled) return children;
28311
28797
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
@@ -28359,7 +28845,7 @@ var init_useDataDnd = __esm({
28359
28845
  init_useAlmadarDndCollision();
28360
28846
  init_Box();
28361
28847
  dndLog = createLogger("almadar:ui:dnd");
28362
- RootCtx = React104__default.createContext(null);
28848
+ RootCtx = React105__default.createContext(null);
28363
28849
  }
28364
28850
  });
28365
28851
  function renderIconInput(icon, props) {
@@ -28885,7 +29371,7 @@ function DataList({
28885
29371
  }) {
28886
29372
  const eventBus = useEventBus();
28887
29373
  const { t } = useTranslate();
28888
- const [visibleCount, setVisibleCount] = React104__default.useState(pageSize || Infinity);
29374
+ const [visibleCount, setVisibleCount] = React105__default.useState(pageSize || Infinity);
28889
29375
  const fieldDefs = fields ?? columns ?? [];
28890
29376
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
28891
29377
  const dnd = useDataDnd({
@@ -28904,7 +29390,7 @@ function DataList({
28904
29390
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
28905
29391
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
28906
29392
  const hasRenderProp = typeof children === "function";
28907
- React104__default.useEffect(() => {
29393
+ React105__default.useEffect(() => {
28908
29394
  const renderItemTypeOf = typeof schemaRenderItem;
28909
29395
  const childrenTypeOf = typeof children;
28910
29396
  if (data.length > 0 && !hasRenderProp) {
@@ -29008,7 +29494,7 @@ function DataList({
29008
29494
  const items2 = [...data];
29009
29495
  const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
29010
29496
  const contentField = titleField?.name ?? fieldDefs[0]?.name ?? "";
29011
- return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
29497
+ return /* @__PURE__ */ jsx(VStack, { gap: "sm", className: cn("py-2", className), children: groups2.map((group, gi) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
29012
29498
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: "my-2" }),
29013
29499
  group.items.map((itemData, index) => {
29014
29500
  const id = itemData.id || `${gi}-${index}`;
@@ -29149,7 +29635,7 @@ function DataList({
29149
29635
  className
29150
29636
  ),
29151
29637
  children: [
29152
- groups.map((group, gi) => /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
29638
+ groups.map((group, gi) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
29153
29639
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-4" : "mt-0" }),
29154
29640
  group.items.map(
29155
29641
  (itemData, index) => renderItem(itemData, index, gi === groups.length - 1 && index === group.items.length - 1)
@@ -29234,7 +29720,7 @@ var init_FormSection = __esm({
29234
29720
  columns = 1,
29235
29721
  className
29236
29722
  }) => {
29237
- const [collapsed, setCollapsed] = React104__default.useState(defaultCollapsed);
29723
+ const [collapsed, setCollapsed] = React105__default.useState(defaultCollapsed);
29238
29724
  const { t } = useTranslate();
29239
29725
  const eventBus = useEventBus();
29240
29726
  const gridClass = {
@@ -29242,7 +29728,7 @@ var init_FormSection = __esm({
29242
29728
  2: "grid-cols-1 md:grid-cols-2",
29243
29729
  3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
29244
29730
  }[columns];
29245
- React104__default.useCallback(() => {
29731
+ React105__default.useCallback(() => {
29246
29732
  if (collapsible) {
29247
29733
  setCollapsed((prev) => !prev);
29248
29734
  eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
@@ -30192,7 +30678,7 @@ var init_Flex = __esm({
30192
30678
  flexStyle.flexBasis = typeof basis === "number" ? `${basis}px` : basis;
30193
30679
  }
30194
30680
  }
30195
- return React104__default.createElement(Component, {
30681
+ return React105__default.createElement(Component, {
30196
30682
  className: cn(
30197
30683
  inline ? "inline-flex" : "flex",
30198
30684
  directionStyles[direction],
@@ -30311,7 +30797,7 @@ var init_Grid = __esm({
30311
30797
  as: Component = "div"
30312
30798
  }) => {
30313
30799
  const mergedStyle = rows2 ? { gridTemplateRows: `repeat(${rows2}, minmax(0, 1fr))`, ...style } : style;
30314
- return React104__default.createElement(
30800
+ return React105__default.createElement(
30315
30801
  Component,
30316
30802
  {
30317
30803
  className: cn(
@@ -30507,9 +30993,9 @@ var init_Popover = __esm({
30507
30993
  onMouseLeave: handleClose,
30508
30994
  onPointerDown: tapTriggerProps.onPointerDown
30509
30995
  };
30510
- const childElement = React104__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
30996
+ const childElement = React105__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
30511
30997
  const childPointerDown = childElement.props.onPointerDown;
30512
- const triggerElement = React104__default.cloneElement(
30998
+ const triggerElement = React105__default.cloneElement(
30513
30999
  childElement,
30514
31000
  {
30515
31001
  ref: triggerRef,
@@ -31111,9 +31597,9 @@ var init_Tooltip = __esm({
31111
31597
  if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
31112
31598
  };
31113
31599
  }, []);
31114
- const triggerElement = React104__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
31600
+ const triggerElement = React105__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
31115
31601
  const childPointerDown = triggerElement.props.onPointerDown;
31116
- const trigger = React104__default.cloneElement(triggerElement, {
31602
+ const trigger = React105__default.cloneElement(triggerElement, {
31117
31603
  ref: triggerRef,
31118
31604
  onMouseEnter: handleMouseEnter,
31119
31605
  onMouseLeave: handleMouseLeave,
@@ -31203,7 +31689,7 @@ var init_WizardProgress = __esm({
31203
31689
  children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: normalizedSteps.map((step, index) => {
31204
31690
  const isActive = index === currentStep;
31205
31691
  const isCompleted = index < currentStep;
31206
- return /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
31692
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
31207
31693
  /* @__PURE__ */ jsx(
31208
31694
  "button",
31209
31695
  {
@@ -32763,13 +33249,13 @@ var init_MapView = __esm({
32763
33249
  shadowSize: [41, 41]
32764
33250
  });
32765
33251
  L.Marker.prototype.options.icon = defaultIcon;
32766
- const { useEffect: useEffect70, useRef: useRef66, useCallback: useCallback104, useState: useState105 } = React104__default;
33252
+ const { useEffect: useEffect71, useRef: useRef67, useCallback: useCallback104, useState: useState105 } = React105__default;
32767
33253
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
32768
33254
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
32769
33255
  function MapUpdater({ centerLat, centerLng, zoom }) {
32770
33256
  const map = useMap();
32771
- const prevRef = useRef66({ centerLat, centerLng, zoom });
32772
- useEffect70(() => {
33257
+ const prevRef = useRef67({ centerLat, centerLng, zoom });
33258
+ useEffect71(() => {
32773
33259
  const prev = prevRef.current;
32774
33260
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
32775
33261
  map.setView([centerLat, centerLng], zoom);
@@ -32780,7 +33266,7 @@ var init_MapView = __esm({
32780
33266
  }
32781
33267
  function MapClickHandler({ onMapClick }) {
32782
33268
  const map = useMap();
32783
- useEffect70(() => {
33269
+ useEffect71(() => {
32784
33270
  if (!onMapClick) return;
32785
33271
  const handler = (e) => {
32786
33272
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -33678,8 +34164,8 @@ function TableView({
33678
34164
  }) {
33679
34165
  const eventBus = useEventBus();
33680
34166
  const { t } = useTranslate();
33681
- const [visibleCount, setVisibleCount] = React104__default.useState(pageSize > 0 ? pageSize : Infinity);
33682
- const [localSelected, setLocalSelected] = React104__default.useState(/* @__PURE__ */ new Set());
34167
+ const [visibleCount, setVisibleCount] = React105__default.useState(pageSize > 0 ? pageSize : Infinity);
34168
+ const [localSelected, setLocalSelected] = React105__default.useState(/* @__PURE__ */ new Set());
33683
34169
  const colDefs = columns ?? fields ?? [];
33684
34170
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
33685
34171
  const dnd = useDataDnd({
@@ -33874,12 +34360,12 @@ function TableView({
33874
34360
  ]
33875
34361
  }
33876
34362
  );
33877
- return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React104__default.Fragment, { children: rowInner }, id);
34363
+ return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React105__default.Fragment, { children: rowInner }, id);
33878
34364
  };
33879
34365
  const items = Array.from(data);
33880
34366
  const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
33881
34367
  let runningIndex = 0;
33882
- const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
34368
+ const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
33883
34369
  group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
33884
34370
  group.items.map((row) => renderRow(row, runningIndex++))
33885
34371
  ] }, gi)) });
@@ -35236,7 +35722,7 @@ var init_StepFlow = __esm({
35236
35722
  className
35237
35723
  }) => {
35238
35724
  if (orientation === "vertical") {
35239
- return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React104__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
35725
+ return /* @__PURE__ */ jsx(VStack, { gap: "none", className: cn("w-full", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(React105__default.Fragment, { children: /* @__PURE__ */ jsxs(HStack, { gap: "md", align: "start", className: "w-full", children: [
35240
35726
  /* @__PURE__ */ jsxs(VStack, { gap: "none", align: "center", children: [
35241
35727
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
35242
35728
  showConnectors && index < steps.length - 1 && /* @__PURE__ */ jsx(Box, { className: "w-px h-8 bg-border" })
@@ -35247,7 +35733,7 @@ var init_StepFlow = __esm({
35247
35733
  ] })
35248
35734
  ] }) }, index)) });
35249
35735
  }
35250
- return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
35736
+ return /* @__PURE__ */ jsx(Box, { className: cn("w-full flex flex-col md:flex-row items-start gap-0", className), children: steps.map((step, index) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
35251
35737
  /* @__PURE__ */ jsxs(VStack, { gap: "sm", align: "center", className: "flex-1 w-full md:w-auto", children: [
35252
35738
  /* @__PURE__ */ jsx(StepCircle, { step, index }),
35253
35739
  /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "text-center", children: step.title }),
@@ -36232,7 +36718,7 @@ var init_LikertScale = __esm({
36232
36718
  md: "text-base",
36233
36719
  lg: "text-lg"
36234
36720
  };
36235
- LikertScale = React104__default.forwardRef(
36721
+ LikertScale = React105__default.forwardRef(
36236
36722
  ({
36237
36723
  question,
36238
36724
  options = DEFAULT_LIKERT_OPTIONS,
@@ -36244,7 +36730,7 @@ var init_LikertScale = __esm({
36244
36730
  variant = "radios",
36245
36731
  className
36246
36732
  }, ref) => {
36247
- const groupId = React104__default.useId();
36733
+ const groupId = React105__default.useId();
36248
36734
  const eventBus = useEventBus();
36249
36735
  const handleSelect = useCallback(
36250
36736
  (next) => {
@@ -38526,7 +39012,7 @@ var init_DocBreadcrumb = __esm({
38526
39012
  "aria-label": t("aria.breadcrumb"),
38527
39013
  children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", wrap: true, children: items.map((item, idx) => {
38528
39014
  const isLast = idx === items.length - 1;
38529
- return /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
39015
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
38530
39016
  idx > 0 && /* @__PURE__ */ jsx(
38531
39017
  Icon,
38532
39018
  {
@@ -39190,7 +39676,7 @@ var init_PageHeader = __esm({
39190
39676
  info: "bg-info/10 text-info"
39191
39677
  };
39192
39678
  return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
39193
- breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
39679
+ breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
39194
39680
  idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
39195
39681
  crumb.href ? /* @__PURE__ */ jsx(
39196
39682
  "a",
@@ -39548,7 +40034,7 @@ var init_Section = __esm({
39548
40034
  as: Component = "section"
39549
40035
  }) => {
39550
40036
  const hasHeader = title || description || action;
39551
- return React104__default.createElement(
40037
+ return React105__default.createElement(
39552
40038
  Component,
39553
40039
  {
39554
40040
  className: cn(
@@ -39922,7 +40408,7 @@ var init_WizardContainer = __esm({
39922
40408
  const isCompleted = index < currentStep;
39923
40409
  const stepKey = step.id ?? step.tabId ?? `step-${index}`;
39924
40410
  const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
39925
- return /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
40411
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
39926
40412
  /* @__PURE__ */ jsx(
39927
40413
  Button,
39928
40414
  {
@@ -42355,7 +42841,7 @@ var init_DetailPanel = __esm({
42355
42841
  }
42356
42842
  });
42357
42843
  function extractTitle(children) {
42358
- if (!React104__default.isValidElement(children)) return void 0;
42844
+ if (!React105__default.isValidElement(children)) return void 0;
42359
42845
  const props = children.props;
42360
42846
  if (typeof props.title === "string") {
42361
42847
  return props.title;
@@ -42705,12 +43191,12 @@ var init_Form = __esm({
42705
43191
  const isSchemaEntity = isOrbitalEntitySchema(entity);
42706
43192
  const resolvedEntity = isSchemaEntity ? entity : void 0;
42707
43193
  const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
42708
- const normalizedInitialData = React104__default.useMemo(() => {
43194
+ const normalizedInitialData = React105__default.useMemo(() => {
42709
43195
  const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
42710
43196
  const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
42711
43197
  return entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
42712
43198
  }, [entity, initialData]);
42713
- const entityDerivedFields = React104__default.useMemo(() => {
43199
+ const entityDerivedFields = React105__default.useMemo(() => {
42714
43200
  if (fields && fields.length > 0) return void 0;
42715
43201
  if (!resolvedEntity) return void 0;
42716
43202
  return resolvedEntity.fields.map(
@@ -42731,16 +43217,16 @@ var init_Form = __esm({
42731
43217
  const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
42732
43218
  const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
42733
43219
  const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
42734
- const [formData, setFormData] = React104__default.useState(
43220
+ const [formData, setFormData] = React105__default.useState(
42735
43221
  normalizedInitialData
42736
43222
  );
42737
- const [collapsedSections, setCollapsedSections] = React104__default.useState(
43223
+ const [collapsedSections, setCollapsedSections] = React105__default.useState(
42738
43224
  /* @__PURE__ */ new Set()
42739
43225
  );
42740
- const [submitError, setSubmitError] = React104__default.useState(null);
42741
- const formRef = React104__default.useRef(null);
43226
+ const [submitError, setSubmitError] = React105__default.useState(null);
43227
+ const formRef = React105__default.useRef(null);
42742
43228
  const formMode = props.mode;
42743
- const mountedRef = React104__default.useRef(false);
43229
+ const mountedRef = React105__default.useRef(false);
42744
43230
  if (!mountedRef.current) {
42745
43231
  mountedRef.current = true;
42746
43232
  debug("forms", "mount", {
@@ -42753,7 +43239,7 @@ var init_Form = __esm({
42753
43239
  });
42754
43240
  }
42755
43241
  const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
42756
- const evalContext = React104__default.useMemo(
43242
+ const evalContext = React105__default.useMemo(
42757
43243
  () => ({
42758
43244
  formValues: formData,
42759
43245
  globalVariables: externalContext?.globalVariables ?? {},
@@ -42762,7 +43248,7 @@ var init_Form = __esm({
42762
43248
  }),
42763
43249
  [formData, externalContext]
42764
43250
  );
42765
- React104__default.useEffect(() => {
43251
+ React105__default.useEffect(() => {
42766
43252
  debug("forms", "initialData-sync", {
42767
43253
  mode: formMode,
42768
43254
  normalizedInitialData,
@@ -42773,7 +43259,7 @@ var init_Form = __esm({
42773
43259
  setFormData(normalizedInitialData);
42774
43260
  }
42775
43261
  }, [normalizedInitialData]);
42776
- const processCalculations = React104__default.useCallback(
43262
+ const processCalculations = React105__default.useCallback(
42777
43263
  (changedFieldId, newFormData) => {
42778
43264
  if (!hiddenCalculations.length) return;
42779
43265
  const context = {
@@ -42798,7 +43284,7 @@ var init_Form = __esm({
42798
43284
  },
42799
43285
  [hiddenCalculations, externalContext, eventBus]
42800
43286
  );
42801
- const checkViolations = React104__default.useCallback(
43287
+ const checkViolations = React105__default.useCallback(
42802
43288
  (changedFieldId, newFormData) => {
42803
43289
  if (!violationTriggers.length) return;
42804
43290
  const context = {
@@ -42836,7 +43322,7 @@ var init_Form = __esm({
42836
43322
  processCalculations(name, newFormData);
42837
43323
  checkViolations(name, newFormData);
42838
43324
  };
42839
- const isFieldVisible = React104__default.useCallback(
43325
+ const isFieldVisible = React105__default.useCallback(
42840
43326
  (fieldName) => {
42841
43327
  const condition = conditionalFields[fieldName];
42842
43328
  if (!condition) return true;
@@ -42844,7 +43330,7 @@ var init_Form = __esm({
42844
43330
  },
42845
43331
  [conditionalFields, evalContext]
42846
43332
  );
42847
- const isSectionVisible = React104__default.useCallback(
43333
+ const isSectionVisible = React105__default.useCallback(
42848
43334
  (section) => {
42849
43335
  if (!section.condition) return true;
42850
43336
  return Boolean(evaluateFormExpression(section.condition, evalContext));
@@ -42920,7 +43406,7 @@ var init_Form = __esm({
42920
43406
  eventBus.emit(`UI:${onCancel}`);
42921
43407
  }
42922
43408
  };
42923
- const renderField = React104__default.useCallback(
43409
+ const renderField = React105__default.useCallback(
42924
43410
  (field) => {
42925
43411
  const fieldName = field.name || field.field;
42926
43412
  if (!fieldName) return null;
@@ -42941,7 +43427,7 @@ var init_Form = __esm({
42941
43427
  [formData, isFieldVisible, relationsData, relationsLoading, isLoading]
42942
43428
  );
42943
43429
  const effectiveFields = entityDerivedFields ?? fields;
42944
- const normalizedFields = React104__default.useMemo(() => {
43430
+ const normalizedFields = React105__default.useMemo(() => {
42945
43431
  if (!effectiveFields || effectiveFields.length === 0) return [];
42946
43432
  return effectiveFields.map((field) => {
42947
43433
  if (typeof field === "string") {
@@ -42965,7 +43451,7 @@ var init_Form = __esm({
42965
43451
  return field;
42966
43452
  });
42967
43453
  }, [effectiveFields, resolvedEntity]);
42968
- const schemaFields = React104__default.useMemo(() => {
43454
+ const schemaFields = React105__default.useMemo(() => {
42969
43455
  if (normalizedFields.length === 0) return null;
42970
43456
  if (isDebugEnabled()) {
42971
43457
  debugGroup(`Form: ${entityName || "unknown"}`);
@@ -42975,7 +43461,7 @@ var init_Form = __esm({
42975
43461
  }
42976
43462
  return normalizedFields.map(renderField).filter(Boolean);
42977
43463
  }, [normalizedFields, renderField, entityName, conditionalFields]);
42978
- const sectionElements = React104__default.useMemo(() => {
43464
+ const sectionElements = React105__default.useMemo(() => {
42979
43465
  if (!sections || sections.length === 0) return null;
42980
43466
  return sections.map((section) => {
42981
43467
  if (!isSectionVisible(section)) {
@@ -43700,7 +44186,7 @@ var init_List = __esm({
43700
44186
  if (entity && typeof entity === "object" && "id" in entity) return [entity];
43701
44187
  return [];
43702
44188
  }, [entity]);
43703
- const getItemActions = React104__default.useCallback(
44189
+ const getItemActions = React105__default.useCallback(
43704
44190
  (item) => {
43705
44191
  if (!itemActions) return [];
43706
44192
  if (typeof itemActions === "function") {
@@ -44175,7 +44661,7 @@ var init_MediaGallery = __esm({
44175
44661
  [selectable, selectedItems, selectionEvent, eventBus]
44176
44662
  );
44177
44663
  const entityData = Array.isArray(entity) ? entity : [];
44178
- const items = React104__default.useMemo(() => {
44664
+ const items = React105__default.useMemo(() => {
44179
44665
  if (propItems) return propItems;
44180
44666
  if (entityData.length === 0) return [];
44181
44667
  return entityData.map((record, idx) => {
@@ -44338,7 +44824,7 @@ var init_MediaGallery = __esm({
44338
44824
  }
44339
44825
  });
44340
44826
  function extractTitle2(children) {
44341
- if (!React104__default.isValidElement(children)) return void 0;
44827
+ if (!React105__default.isValidElement(children)) return void 0;
44342
44828
  const props = children.props;
44343
44829
  if (typeof props.title === "string") {
44344
44830
  return props.title;
@@ -44612,7 +45098,7 @@ var init_debugRegistry = __esm({
44612
45098
  }
44613
45099
  });
44614
45100
  function useDebugData() {
44615
- const [data, setData] = React104.useState(() => ({
45101
+ const [data, setData] = React105.useState(() => ({
44616
45102
  traits: [],
44617
45103
  ticks: [],
44618
45104
  guards: [],
@@ -44626,7 +45112,7 @@ function useDebugData() {
44626
45112
  },
44627
45113
  lastUpdate: Date.now()
44628
45114
  }));
44629
- React104.useEffect(() => {
45115
+ React105.useEffect(() => {
44630
45116
  const updateData = () => {
44631
45117
  setData({
44632
45118
  traits: getAllTraits(),
@@ -44735,12 +45221,12 @@ function layoutGraph(states, transitions, initialState, width, height) {
44735
45221
  return positions;
44736
45222
  }
44737
45223
  function WalkMinimap() {
44738
- const [walkStep, setWalkStep] = React104.useState(null);
44739
- const [traits2, setTraits] = React104.useState([]);
44740
- const [coveredEdges, setCoveredEdges] = React104.useState([]);
44741
- const [completedTraits, setCompletedTraits] = React104.useState(/* @__PURE__ */ new Set());
44742
- const prevTraitRef = React104.useRef(null);
44743
- React104.useEffect(() => {
45224
+ const [walkStep, setWalkStep] = React105.useState(null);
45225
+ const [traits2, setTraits] = React105.useState([]);
45226
+ const [coveredEdges, setCoveredEdges] = React105.useState([]);
45227
+ const [completedTraits, setCompletedTraits] = React105.useState(/* @__PURE__ */ new Set());
45228
+ const prevTraitRef = React105.useRef(null);
45229
+ React105.useEffect(() => {
44744
45230
  const interval = setInterval(() => {
44745
45231
  const w = window;
44746
45232
  const step = w.__orbitalWalkStep;
@@ -45176,15 +45662,15 @@ var init_EntitiesTab = __esm({
45176
45662
  });
45177
45663
  function EventFlowTab({ events: events2 }) {
45178
45664
  const { t } = useTranslate();
45179
- const [filter, setFilter] = React104.useState("all");
45180
- const containerRef = React104.useRef(null);
45181
- const [autoScroll, setAutoScroll] = React104.useState(true);
45182
- React104.useEffect(() => {
45665
+ const [filter, setFilter] = React105.useState("all");
45666
+ const containerRef = React105.useRef(null);
45667
+ const [autoScroll, setAutoScroll] = React105.useState(true);
45668
+ React105.useEffect(() => {
45183
45669
  if (autoScroll && containerRef.current) {
45184
45670
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
45185
45671
  }
45186
45672
  }, [events2.length, autoScroll]);
45187
- const filteredEvents = React104.useMemo(() => {
45673
+ const filteredEvents = React105.useMemo(() => {
45188
45674
  if (filter === "all") return events2;
45189
45675
  return events2.filter((e) => e.type === filter);
45190
45676
  }, [events2, filter]);
@@ -45300,7 +45786,7 @@ var init_EventFlowTab = __esm({
45300
45786
  });
45301
45787
  function GuardsPanel({ guards }) {
45302
45788
  const { t } = useTranslate();
45303
- const [filter, setFilter] = React104.useState("all");
45789
+ const [filter, setFilter] = React105.useState("all");
45304
45790
  if (guards.length === 0) {
45305
45791
  return /* @__PURE__ */ jsx(
45306
45792
  EmptyState,
@@ -45313,7 +45799,7 @@ function GuardsPanel({ guards }) {
45313
45799
  }
45314
45800
  const passedCount = guards.filter((g) => g.result).length;
45315
45801
  const failedCount = guards.length - passedCount;
45316
- const filteredGuards = React104.useMemo(() => {
45802
+ const filteredGuards = React105.useMemo(() => {
45317
45803
  if (filter === "all") return guards;
45318
45804
  if (filter === "passed") return guards.filter((g) => g.result);
45319
45805
  return guards.filter((g) => !g.result);
@@ -45476,10 +45962,10 @@ function EffectBadge({ effect }) {
45476
45962
  }
45477
45963
  function TransitionTimeline({ transitions }) {
45478
45964
  const { t } = useTranslate();
45479
- const containerRef = React104.useRef(null);
45480
- const [autoScroll, setAutoScroll] = React104.useState(true);
45481
- const [expandedId, setExpandedId] = React104.useState(null);
45482
- React104.useEffect(() => {
45965
+ const containerRef = React105.useRef(null);
45966
+ const [autoScroll, setAutoScroll] = React105.useState(true);
45967
+ const [expandedId, setExpandedId] = React105.useState(null);
45968
+ React105.useEffect(() => {
45483
45969
  if (autoScroll && containerRef.current) {
45484
45970
  containerRef.current.scrollTop = containerRef.current.scrollHeight;
45485
45971
  }
@@ -45759,9 +46245,9 @@ function getAllEvents(traits2) {
45759
46245
  function EventDispatcherTab({ traits: traits2, schema }) {
45760
46246
  const eventBus = useEventBus();
45761
46247
  const { t } = useTranslate();
45762
- const [log11, setLog] = React104.useState([]);
45763
- const prevStatesRef = React104.useRef(/* @__PURE__ */ new Map());
45764
- React104.useEffect(() => {
46248
+ const [log11, setLog] = React105.useState([]);
46249
+ const prevStatesRef = React105.useRef(/* @__PURE__ */ new Map());
46250
+ React105.useEffect(() => {
45765
46251
  for (const trait of traits2) {
45766
46252
  const prev = prevStatesRef.current.get(trait.id);
45767
46253
  if (prev && prev !== trait.currentState) {
@@ -45930,10 +46416,10 @@ function VerifyModePanel({
45930
46416
  localCount
45931
46417
  }) {
45932
46418
  const { t } = useTranslate();
45933
- const [expanded, setExpanded] = React104.useState(true);
45934
- const scrollRef = React104.useRef(null);
45935
- const prevCountRef = React104.useRef(0);
45936
- React104.useEffect(() => {
46419
+ const [expanded, setExpanded] = React105.useState(true);
46420
+ const scrollRef = React105.useRef(null);
46421
+ const prevCountRef = React105.useRef(0);
46422
+ React105.useEffect(() => {
45937
46423
  if (expanded && transitions.length > prevCountRef.current && scrollRef.current) {
45938
46424
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
45939
46425
  }
@@ -45990,10 +46476,10 @@ function RuntimeDebugger({
45990
46476
  schema
45991
46477
  }) {
45992
46478
  const { t } = useTranslate();
45993
- const [isCollapsed, setIsCollapsed] = React104.useState(mode === "verify" ? true : defaultCollapsed);
45994
- const [isVisible, setIsVisible] = React104.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
46479
+ const [isCollapsed, setIsCollapsed] = React105.useState(mode === "verify" ? true : defaultCollapsed);
46480
+ const [isVisible, setIsVisible] = React105.useState(mode === "inline" || mode === "verify" || isDebugEnabled2());
45995
46481
  const debugData = useDebugData();
45996
- React104.useEffect(() => {
46482
+ React105.useEffect(() => {
45997
46483
  if (mode === "inline") return;
45998
46484
  return onDebugToggle((enabled) => {
45999
46485
  setIsVisible(enabled);
@@ -46002,7 +46488,7 @@ function RuntimeDebugger({
46002
46488
  }
46003
46489
  });
46004
46490
  }, [mode]);
46005
- React104.useEffect(() => {
46491
+ React105.useEffect(() => {
46006
46492
  if (mode === "inline") return;
46007
46493
  const handleKeyDown = (e) => {
46008
46494
  if (e.key === "`" && isVisible) {
@@ -46522,7 +47008,7 @@ var init_StatCard = __esm({
46522
47008
  const labelToUse = propLabel ?? propTitle;
46523
47009
  const eventBus = useEventBus();
46524
47010
  const { t } = useTranslate();
46525
- const handleActionClick = React104__default.useCallback(() => {
47011
+ const handleActionClick = React105__default.useCallback(() => {
46526
47012
  if (action?.event) {
46527
47013
  eventBus.emit(`UI:${action.event}`, {});
46528
47014
  }
@@ -46533,7 +47019,7 @@ var init_StatCard = __esm({
46533
47019
  const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
46534
47020
  const isLoading = externalLoading ?? false;
46535
47021
  const error = externalError;
46536
- const computeMetricValue = React104__default.useCallback(
47022
+ const computeMetricValue = React105__default.useCallback(
46537
47023
  (metric, items) => {
46538
47024
  if (metric.value !== void 0) {
46539
47025
  return metric.value;
@@ -46572,7 +47058,7 @@ var init_StatCard = __esm({
46572
47058
  },
46573
47059
  []
46574
47060
  );
46575
- const schemaStats = React104__default.useMemo(() => {
47061
+ const schemaStats = React105__default.useMemo(() => {
46576
47062
  if (!metrics || metrics.length === 0) return null;
46577
47063
  return metrics.map((metric) => ({
46578
47064
  label: metric.label,
@@ -46580,7 +47066,7 @@ var init_StatCard = __esm({
46580
47066
  format: metric.format
46581
47067
  }));
46582
47068
  }, [metrics, data, computeMetricValue]);
46583
- const calculatedTrend = React104__default.useMemo(() => {
47069
+ const calculatedTrend = React105__default.useMemo(() => {
46584
47070
  if (manualTrend !== void 0) return manualTrend;
46585
47071
  if (previousValue === void 0 || currentValue === void 0)
46586
47072
  return void 0;
@@ -47220,8 +47706,8 @@ var init_SubagentTracePanel = __esm({
47220
47706
  ] });
47221
47707
  };
47222
47708
  InlineActivityStream = ({ activities, autoScroll = true, className }) => {
47223
- const endRef = React104__default.useRef(null);
47224
- React104__default.useEffect(() => {
47709
+ const endRef = React105__default.useRef(null);
47710
+ React105__default.useEffect(() => {
47225
47711
  if (!autoScroll) return;
47226
47712
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
47227
47713
  }, [activities.length, autoScroll]);
@@ -47315,7 +47801,7 @@ var init_SubagentTracePanel = __esm({
47315
47801
  };
47316
47802
  SubagentRichCard = ({ subagent }) => {
47317
47803
  const { t } = useTranslate();
47318
- const activities = React104__default.useMemo(
47804
+ const activities = React105__default.useMemo(
47319
47805
  () => subagentMessagesToActivities(subagent.messages),
47320
47806
  [subagent.messages]
47321
47807
  );
@@ -47392,8 +47878,8 @@ var init_SubagentTracePanel = __esm({
47392
47878
  ] });
47393
47879
  };
47394
47880
  CoordinatorConversation = ({ messages, autoScroll = true, className }) => {
47395
- const endRef = React104__default.useRef(null);
47396
- React104__default.useEffect(() => {
47881
+ const endRef = React105__default.useRef(null);
47882
+ React105__default.useEffect(() => {
47397
47883
  if (!autoScroll) return;
47398
47884
  endRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
47399
47885
  }, [messages.length, autoScroll]);
@@ -47823,7 +48309,7 @@ var init_Timeline = __esm({
47823
48309
  }) => {
47824
48310
  const { t } = useTranslate();
47825
48311
  const entityData = entity ?? [];
47826
- const items = React104__default.useMemo(() => {
48312
+ const items = React105__default.useMemo(() => {
47827
48313
  if (propItems) return propItems;
47828
48314
  if (entityData.length === 0) return [];
47829
48315
  return entityData.map((record, idx) => {
@@ -47925,7 +48411,7 @@ var init_Timeline = __esm({
47925
48411
  }
47926
48412
  });
47927
48413
  function extractToastProps(children) {
47928
- if (!React104__default.isValidElement(children)) {
48414
+ if (!React105__default.isValidElement(children)) {
47929
48415
  if (typeof children === "string") {
47930
48416
  return { message: children };
47931
48417
  }
@@ -47967,7 +48453,7 @@ var init_ToastSlot = __esm({
47967
48453
  eventBus.emit(`${prefix}CLOSE`);
47968
48454
  };
47969
48455
  if (!isVisible) return null;
47970
- const isCustomContent = React104__default.isValidElement(children) && !message;
48456
+ const isCustomContent = React105__default.isValidElement(children) && !message;
47971
48457
  return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
47972
48458
  Toast,
47973
48459
  {
@@ -47984,7 +48470,7 @@ var init_ToastSlot = __esm({
47984
48470
  }
47985
48471
  });
47986
48472
  function lazyThree(name, loader) {
47987
- const Lazy = React104__default.lazy(
48473
+ const Lazy = React105__default.lazy(
47988
48474
  () => loader().then((m) => {
47989
48475
  const Resolved = m[name];
47990
48476
  if (!Resolved) {
@@ -47996,13 +48482,13 @@ function lazyThree(name, loader) {
47996
48482
  })
47997
48483
  );
47998
48484
  function ThreeWrapper(props) {
47999
- return React104__default.createElement(
48485
+ return React105__default.createElement(
48000
48486
  ThreeBoundary,
48001
48487
  { name },
48002
- React104__default.createElement(
48003
- React104__default.Suspense,
48488
+ React105__default.createElement(
48489
+ React105__default.Suspense,
48004
48490
  { fallback: null },
48005
- React104__default.createElement(Lazy, props)
48491
+ React105__default.createElement(Lazy, props)
48006
48492
  )
48007
48493
  );
48008
48494
  }
@@ -48019,11 +48505,13 @@ var init_component_registry_generated = __esm({
48019
48505
  init_ActionTile();
48020
48506
  init_ActivationBlock();
48021
48507
  init_ComponentPatterns();
48508
+ init_AlgorithmCanvas();
48022
48509
  init_AnimatedCounter();
48023
48510
  init_AnimatedGraphic();
48024
48511
  init_AnimatedReveal();
48025
48512
  init_ArticleSection();
48026
48513
  init_Aside();
48514
+ init_AtlasImage();
48027
48515
  init_AuthLayout();
48028
48516
  init_Avatar();
48029
48517
  init_Badge();
@@ -48281,7 +48769,7 @@ var init_component_registry_generated = __esm({
48281
48769
  init_WizardContainer();
48282
48770
  init_WizardNavigation();
48283
48771
  init_WizardProgress();
48284
- ThreeBoundary = class extends React104__default.Component {
48772
+ ThreeBoundary = class extends React105__default.Component {
48285
48773
  constructor() {
48286
48774
  super(...arguments);
48287
48775
  __publicField(this, "state", { failed: false });
@@ -48291,7 +48779,7 @@ var init_component_registry_generated = __esm({
48291
48779
  }
48292
48780
  render() {
48293
48781
  if (this.state.failed) {
48294
- return React104__default.createElement(
48782
+ return React105__default.createElement(
48295
48783
  "div",
48296
48784
  {
48297
48785
  "data-testid": "three-unavailable",
@@ -48317,11 +48805,14 @@ var init_component_registry_generated = __esm({
48317
48805
  "ActivationBlock": ActivationBlock,
48318
48806
  "Alert": AlertPattern,
48319
48807
  "AlertPattern": AlertPattern,
48808
+ "AlgorithmCanvas": AlgorithmCanvas,
48320
48809
  "AnimatedCounter": AnimatedCounter,
48321
48810
  "AnimatedGraphic": AnimatedGraphic,
48322
48811
  "AnimatedReveal": AnimatedReveal,
48323
48812
  "ArticleSection": ArticleSection,
48324
48813
  "Aside": Aside,
48814
+ "AtlasImage": AtlasImage,
48815
+ "AtlasPanel": AtlasPanel,
48325
48816
  "AuthLayout": AuthLayout,
48326
48817
  "Avatar": Avatar,
48327
48818
  "Badge": Badge,
@@ -48614,7 +49105,7 @@ function SuspenseConfigProvider({
48614
49105
  config,
48615
49106
  children
48616
49107
  }) {
48617
- return React104__default.createElement(
49108
+ return React105__default.createElement(
48618
49109
  SuspenseConfigContext.Provider,
48619
49110
  { value: config },
48620
49111
  children
@@ -48656,7 +49147,7 @@ function enrichFormFields(fields, entityDef) {
48656
49147
  }
48657
49148
  return { name: field, label: field.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase()) };
48658
49149
  }
48659
- if (field && typeof field === "object" && !Array.isArray(field) && !React104__default.isValidElement(field) && !(field instanceof Date)) {
49150
+ if (field && typeof field === "object" && !Array.isArray(field) && !React105__default.isValidElement(field) && !(field instanceof Date)) {
48660
49151
  const obj = field;
48661
49152
  const fieldName = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
48662
49153
  if (!fieldName) return field;
@@ -49109,7 +49600,7 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
49109
49600
  const key = `${parentId}-${index}-trait:${traitName}`;
49110
49601
  return /* @__PURE__ */ jsx(TraitFrame, { traitName }, key);
49111
49602
  }
49112
- return /* @__PURE__ */ jsx(React104__default.Fragment, { children: child }, `${parentId}-${index}`);
49603
+ return /* @__PURE__ */ jsx(React105__default.Fragment, { children: child }, `${parentId}-${index}`);
49113
49604
  }
49114
49605
  if (!child || typeof child !== "object") return null;
49115
49606
  const childId = `${parentId}-${index}`;
@@ -49149,14 +49640,14 @@ function isPatternConfig(value) {
49149
49640
  if (value === null || value === void 0) return false;
49150
49641
  if (typeof value !== "object") return false;
49151
49642
  if (Array.isArray(value)) return false;
49152
- if (React104__default.isValidElement(value)) return false;
49643
+ if (React105__default.isValidElement(value)) return false;
49153
49644
  if (value instanceof Date) return false;
49154
49645
  if (typeof value === "function") return false;
49155
49646
  const record = value;
49156
49647
  return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
49157
49648
  }
49158
49649
  function isPlainConfigObject(value) {
49159
- if (React104__default.isValidElement(value)) return false;
49650
+ if (React105__default.isValidElement(value)) return false;
49160
49651
  if (value instanceof Date) return false;
49161
49652
  const proto = Object.getPrototypeOf(value);
49162
49653
  return proto === Object.prototype || proto === null;
@@ -49282,7 +49773,7 @@ function SlotContentRenderer({
49282
49773
  for (const slotKey of CONTENT_NODE_SLOTS) {
49283
49774
  const slotVal = restProps[slotKey];
49284
49775
  if (slotVal === void 0 || slotVal === null) continue;
49285
- if (React104__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
49776
+ if (React105__default.isValidElement(slotVal) || typeof slotVal === "string" || typeof slotVal === "number" || typeof slotVal === "boolean") continue;
49286
49777
  if (Array.isArray(slotVal) || typeof slotVal === "object" && "type" in slotVal) {
49287
49778
  nodeSlotOverrides[slotKey] = renderPatternChildren(
49288
49779
  slotVal,
@@ -49331,7 +49822,7 @@ function SlotContentRenderer({
49331
49822
  const resolvedItems = Array.isArray(entityVal) && entityVal[0] !== "fn" ? entityVal : null;
49332
49823
  if (resolvedItems && resolvedItems.length > 0 && !finalProps.fields && !finalProps.columns) {
49333
49824
  const sample = resolvedItems[0];
49334
- if (sample && typeof sample === "object" && !Array.isArray(sample) && !React104__default.isValidElement(sample) && !(sample instanceof Date)) {
49825
+ if (sample && typeof sample === "object" && !Array.isArray(sample) && !React105__default.isValidElement(sample) && !(sample instanceof Date)) {
49335
49826
  const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
49336
49827
  finalProps.fields = keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" }));
49337
49828
  }
@@ -49492,7 +49983,9 @@ var init_UISlotRenderer = __esm({
49492
49983
  "content",
49493
49984
  "addons",
49494
49985
  "hud",
49495
- "fallback"
49986
+ "fallback",
49987
+ "controls",
49988
+ "overlay"
49496
49989
  ]);
49497
49990
  PATTERNS_WITH_CHILDREN = /* @__PURE__ */ new Set([
49498
49991
  "stack",
@@ -49694,7 +50187,7 @@ var AvlTransition = ({
49694
50187
  opacity = 1,
49695
50188
  className
49696
50189
  }) => {
49697
- const ids = React104__default.useMemo(() => {
50190
+ const ids = React105__default.useMemo(() => {
49698
50191
  avlTransitionId += 1;
49699
50192
  return { arrow: `avl-tr-${avlTransitionId}-arrow` };
49700
50193
  }, []);
@@ -50255,7 +50748,7 @@ var AvlStateMachine = ({
50255
50748
  color = "var(--color-primary)",
50256
50749
  animated = false
50257
50750
  }) => {
50258
- const ids = React104__default.useMemo(() => {
50751
+ const ids = React105__default.useMemo(() => {
50259
50752
  avlSmId += 1;
50260
50753
  const base = `avl-sm-${avlSmId}`;
50261
50754
  return { glow: `${base}-glow`, grad: `${base}-grad` };
@@ -50454,7 +50947,7 @@ var AvlOrbitalUnit = ({
50454
50947
  color = "var(--color-primary)",
50455
50948
  animated = false
50456
50949
  }) => {
50457
- const ids = React104__default.useMemo(() => {
50950
+ const ids = React105__default.useMemo(() => {
50458
50951
  avlOuId += 1;
50459
50952
  const base = `avl-ou-${avlOuId}`;
50460
50953
  return { glow: `${base}-glow`, grad: `${base}-grad` };
@@ -50550,7 +51043,7 @@ var AvlClosedCircuit = ({
50550
51043
  color = "var(--color-primary)",
50551
51044
  animated = false
50552
51045
  }) => {
50553
- const ids = React104__default.useMemo(() => {
51046
+ const ids = React105__default.useMemo(() => {
50554
51047
  avlCcId += 1;
50555
51048
  const base = `avl-cc-${avlCcId}`;
50556
51049
  return { glow: `${base}-glow`, grad: `${base}-grad`, arrow: `${base}-arrow` };
@@ -50705,7 +51198,7 @@ var AvlEmitListen = ({
50705
51198
  color = "var(--color-primary)",
50706
51199
  animated = false
50707
51200
  }) => {
50708
- const ids = React104__default.useMemo(() => {
51201
+ const ids = React105__default.useMemo(() => {
50709
51202
  avlElId += 1;
50710
51203
  const base = `avl-el-${avlElId}`;
50711
51204
  return { arrow: `${base}-arrow`, grad: `${base}-grad` };
@@ -50979,7 +51472,7 @@ function renderNode(node, color, glowId) {
50979
51472
  const baseR = node.type === "operator" ? 20 : 16;
50980
51473
  const r2 = Math.max(baseR, labelLen * 3.5 + 6);
50981
51474
  const nc = nodeColor(node.type, color);
50982
- return /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
51475
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
50983
51476
  node.children.map((child, i) => {
50984
51477
  const childR = Math.max(
50985
51478
  child.type === "operator" ? 20 : 16,
@@ -51036,7 +51529,7 @@ var AvlExprTree = ({
51036
51529
  className,
51037
51530
  color = "var(--color-primary)"
51038
51531
  }) => {
51039
- const ids = React104__default.useMemo(() => {
51532
+ const ids = React105__default.useMemo(() => {
51040
51533
  avlEtId += 1;
51041
51534
  return { glow: `avl-et-${avlEtId}-glow` };
51042
51535
  }, []);
@@ -51871,7 +52364,7 @@ var SystemNode = ({ data }) => {
51871
52364
  stateChain.length > 0 && /* @__PURE__ */ jsx("svg", { width: stateChain.length * 14 + 2, height: 10, viewBox: `0 0 ${stateChain.length * 14 + 2} 10`, children: stateChain.map((s, i) => {
51872
52365
  const tc = transitionCounts[s.name] ?? 0;
51873
52366
  const role = getStateRole(s.name, s.isInitial ?? void 0, s.isTerminal ?? void 0, tc, maxTC);
51874
- return /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
52367
+ return /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
51875
52368
  /* @__PURE__ */ jsx(AvlState, { x: i * 14 + 1, y: 1, width: 10, height: 8, name: "", role, isInitial: s.isInitial ?? void 0, isTerminal: s.isTerminal ?? void 0 }),
51876
52369
  i < stateChain.length - 1 && /* @__PURE__ */ jsx("line", { x1: i * 14 + 12, y1: 5, x2: i * 14 + 15, y2: 5, stroke: "var(--color-border)", strokeWidth: 0.5 })
51877
52370
  ] }, s.name);
@@ -53016,7 +53509,7 @@ function resolveLambdaBindings(body, params, item, index) {
53016
53509
  if (Array.isArray(body)) {
53017
53510
  return body.map((b) => recur(b));
53018
53511
  }
53019
- if (body !== null && typeof body === "object" && !React104__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
53512
+ if (body !== null && typeof body === "object" && !React105__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
53020
53513
  const out = {};
53021
53514
  for (const [k, v] of Object.entries(body)) {
53022
53515
  out[k] = recur(v);
@@ -53035,7 +53528,7 @@ function getSlotContentRenderer2() {
53035
53528
  function makeLambdaFn(params, lambdaBody, callerKey) {
53036
53529
  return (item, index) => {
53037
53530
  const resolvedBody = resolveLambdaBindings(lambdaBody, params, item, index);
53038
- if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React104__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
53531
+ if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React105__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
53039
53532
  return null;
53040
53533
  }
53041
53534
  const record = resolvedBody;
@@ -53054,7 +53547,7 @@ function makeLambdaFn(params, lambdaBody, callerKey) {
53054
53547
  props: childProps,
53055
53548
  priority: 0
53056
53549
  };
53057
- return React104__default.createElement(SlotContentRenderer2, { content: childContent });
53550
+ return React105__default.createElement(SlotContentRenderer2, { content: childContent });
53058
53551
  };
53059
53552
  }
53060
53553
  function convertNode(node, callerKey) {
@@ -53073,7 +53566,7 @@ function convertNode(node, callerKey) {
53073
53566
  });
53074
53567
  return anyChanged ? mapped : node;
53075
53568
  }
53076
- if (typeof node === "object" && !React104__default.isValidElement(node) && !(node instanceof Date)) {
53569
+ if (typeof node === "object" && !React105__default.isValidElement(node) && !(node instanceof Date)) {
53077
53570
  return convertObjectProps(node);
53078
53571
  }
53079
53572
  return node;
@@ -54708,8 +55201,8 @@ function CanvasDndProvider({
54708
55201
  }) {
54709
55202
  const eventBus = useEventBus();
54710
55203
  const sensors = useAlmadarDndSensors(false);
54711
- const [activePayload, setActivePayload] = React104__default.useState(null);
54712
- const handleDragStart = React104__default.useCallback((e) => {
55204
+ const [activePayload, setActivePayload] = React105__default.useState(null);
55205
+ const handleDragStart = React105__default.useCallback((e) => {
54713
55206
  const data = e.active.data.current;
54714
55207
  const payload = data?.payload;
54715
55208
  if (payload) {
@@ -54720,7 +55213,7 @@ function CanvasDndProvider({
54720
55213
  log9.warn("dragStart:missing-payload", { id: e.active.id });
54721
55214
  }
54722
55215
  }, [eventBus]);
54723
- const handleDragEnd = React104__default.useCallback((e) => {
55216
+ const handleDragEnd = React105__default.useCallback((e) => {
54724
55217
  setActivePayload(null);
54725
55218
  const activeData = e.active.data.current;
54726
55219
  const payload = activeData?.payload;
@@ -54749,7 +55242,7 @@ function CanvasDndProvider({
54749
55242
  const suppressed = onDrop ? onDrop(drop) === true : false;
54750
55243
  if (!suppressed) defaultEmit(eventBus, drop);
54751
55244
  }, [eventBus, onDrop]);
54752
- const handleDragCancel = React104__default.useCallback(() => {
55245
+ const handleDragCancel = React105__default.useCallback(() => {
54753
55246
  setActivePayload(null);
54754
55247
  log9.info("dragCancel");
54755
55248
  }, []);
@@ -55507,7 +56000,7 @@ var OrbPreviewNodeInner = (props) => {
55507
56000
  }
55508
56001
  );
55509
56002
  };
55510
- var OrbPreviewNode = React104__default.memo(OrbPreviewNodeInner);
56003
+ var OrbPreviewNode = React105__default.memo(OrbPreviewNodeInner);
55511
56004
  OrbPreviewNode.displayName = "OrbPreviewNode";
55512
56005
  orbPreviewLog.debug("export-resolved", () => ({
55513
56006
  type: typeof OrbPreviewNode,
@@ -55612,7 +56105,7 @@ var EventFlowEdgeInner = (props) => {
55612
56105
  ) })
55613
56106
  ] });
55614
56107
  };
55615
- var EventFlowEdge = React104__default.memo(EventFlowEdgeInner);
56108
+ var EventFlowEdge = React105__default.memo(EventFlowEdgeInner);
55616
56109
  EventFlowEdge.displayName = "EventFlowEdge";
55617
56110
 
55618
56111
  // components/avl/molecules/BehaviorComposeNode.tsx
@@ -55759,7 +56252,7 @@ var BehaviorComposeNodeInner = (props) => {
55759
56252
  }
55760
56253
  );
55761
56254
  };
55762
- var BehaviorComposeNode = React104__default.memo(BehaviorComposeNodeInner);
56255
+ var BehaviorComposeNode = React105__default.memo(BehaviorComposeNodeInner);
55763
56256
  BehaviorComposeNode.displayName = "BehaviorComposeNode";
55764
56257
 
55765
56258
  // components/avl/lib/avl-behavior-compose-converter.ts
@@ -56785,7 +57278,7 @@ var TraitCardNodeInner = (props) => {
56785
57278
  }
56786
57279
  );
56787
57280
  };
56788
- var TraitCardNode = React104__default.memo(TraitCardNodeInner);
57281
+ var TraitCardNode = React105__default.memo(TraitCardNodeInner);
56789
57282
  TraitCardNode.displayName = "TraitCardNode";
56790
57283
 
56791
57284
  // components/avl/organisms/FlowCanvas.tsx
@@ -56858,7 +57351,7 @@ function FlowCanvasInner({
56858
57351
  initialOrbital
56859
57352
  );
56860
57353
  const [expandedBehaviorAlias, setExpandedBehaviorAlias] = useState(void 0);
56861
- const screenSizeUserOverrideRef = React104__default.useRef(false);
57354
+ const screenSizeUserOverrideRef = React105__default.useRef(false);
56862
57355
  const [screenSize, setScreenSize] = useState(
56863
57356
  () => typeof window === "undefined" ? "laptop" : detectScreenSize(window.innerWidth)
56864
57357
  );
@@ -57242,7 +57735,7 @@ var ZoomBreadcrumb = ({
57242
57735
  if (eventName && band === "detail") {
57243
57736
  segments.push({ icon: "\u26A1", label: eventName });
57244
57737
  }
57245
- return /* @__PURE__ */ jsx("div", { className: "absolute top-2 left-2 z-10 flex items-center gap-1 px-2 py-1 rounded-md bg-card/90 border border-border text-xs text-muted-foreground backdrop-blur-sm", children: segments.map((seg, i) => /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
57738
+ return /* @__PURE__ */ jsx("div", { className: "absolute top-2 left-2 z-10 flex items-center gap-1 px-2 py-1 rounded-md bg-card/90 border border-border text-xs text-muted-foreground backdrop-blur-sm", children: segments.map((seg, i) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
57246
57739
  i > 0 && /* @__PURE__ */ jsx("span", { className: "opacity-40", children: ">" }),
57247
57740
  /* @__PURE__ */ jsx("span", { className: "opacity-60", children: seg.icon }),
57248
57741
  /* @__PURE__ */ jsx("span", { children: seg.label })
@@ -57583,7 +58076,7 @@ var EventWireOverlay = ({
57583
58076
  containerW,
57584
58077
  containerH
57585
58078
  }) => {
57586
- const ids = React104__default.useMemo(() => {
58079
+ const ids = React105__default.useMemo(() => {
57587
58080
  avlOczWireId += 1;
57588
58081
  return { arrow: `avl-ocz-wire-${avlOczWireId}-arrow` };
57589
58082
  }, []);
@@ -57950,7 +58443,7 @@ var AvlOrbitalsCosmicZoom = ({
57950
58443
  borderRadius: 6,
57951
58444
  border: `1px solid ${color}`
57952
58445
  },
57953
- children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxs(React104__default.Fragment, { children: [
58446
+ children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxs(React105__default.Fragment, { children: [
57954
58447
  i > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", style: { opacity: 0.5, color }, children: "/" }),
57955
58448
  i < breadcrumbs.length - 1 ? /* @__PURE__ */ jsx(
57956
58449
  Box,