@almadar/ui 5.94.0 → 5.95.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.cjs +284 -40
- package/dist/avl/index.js +284 -40
- package/dist/components/core/molecules/index.d.ts +1 -0
- package/dist/components/game/2d/molecules/Canvas2D.d.ts +6 -6
- package/dist/components/game/shared/atlasSlice.d.ts +58 -0
- package/dist/components/index.cjs +594 -349
- package/dist/components/index.js +595 -350
- package/dist/components/learning/molecules/AlgorithmCanvas.d.ts +58 -0
- package/dist/providers/index.cjs +284 -40
- package/dist/providers/index.js +284 -40
- package/dist/runtime/index.cjs +284 -40
- package/dist/runtime/index.js +284 -40
- package/package.json +2 -2
package/dist/providers/index.js
CHANGED
|
@@ -9616,6 +9616,76 @@ var init_StateGraph = __esm({
|
|
|
9616
9616
|
init_TransitionArrow();
|
|
9617
9617
|
}
|
|
9618
9618
|
});
|
|
9619
|
+
|
|
9620
|
+
// components/game/shared/atlasSlice.ts
|
|
9621
|
+
function isTilesheet(a) {
|
|
9622
|
+
return typeof a.tileWidth === "number";
|
|
9623
|
+
}
|
|
9624
|
+
function getAtlas(url, onReady) {
|
|
9625
|
+
if (atlasCache.has(url)) return atlasCache.get(url) ?? void 0;
|
|
9626
|
+
atlasCache.set(url, void 0);
|
|
9627
|
+
fetch(url).then((r) => r.json()).then((json) => {
|
|
9628
|
+
atlasCache.set(url, json);
|
|
9629
|
+
onReady();
|
|
9630
|
+
}).catch(() => {
|
|
9631
|
+
atlasCache.set(url, null);
|
|
9632
|
+
});
|
|
9633
|
+
return void 0;
|
|
9634
|
+
}
|
|
9635
|
+
function subRectFor(atlas, sprite) {
|
|
9636
|
+
if (isTilesheet(atlas)) {
|
|
9637
|
+
let col;
|
|
9638
|
+
let row;
|
|
9639
|
+
if (sprite.includes(",")) {
|
|
9640
|
+
const [c, r] = sprite.split(",").map((n) => Number(n.trim()));
|
|
9641
|
+
col = c;
|
|
9642
|
+
row = r;
|
|
9643
|
+
} else {
|
|
9644
|
+
const i = Number(sprite);
|
|
9645
|
+
if (!Number.isFinite(i)) return null;
|
|
9646
|
+
col = i % atlas.columns;
|
|
9647
|
+
row = Math.floor(i / atlas.columns);
|
|
9648
|
+
}
|
|
9649
|
+
if (!Number.isFinite(col) || !Number.isFinite(row) || col < 0 || row < 0 || col >= atlas.columns || row >= atlas.rows) return null;
|
|
9650
|
+
const margin = atlas.margin ?? 0;
|
|
9651
|
+
const spacing = atlas.spacing ?? 0;
|
|
9652
|
+
return {
|
|
9653
|
+
sx: margin + col * (atlas.tileWidth + spacing),
|
|
9654
|
+
sy: margin + row * (atlas.tileHeight + spacing),
|
|
9655
|
+
sw: atlas.tileWidth,
|
|
9656
|
+
sh: atlas.tileHeight
|
|
9657
|
+
};
|
|
9658
|
+
}
|
|
9659
|
+
const st = atlas.subTextures[sprite];
|
|
9660
|
+
if (!st) return null;
|
|
9661
|
+
return { sx: st.x, sy: st.y, sw: st.width, sh: st.height };
|
|
9662
|
+
}
|
|
9663
|
+
function isAtlasAsset(asset) {
|
|
9664
|
+
return !!asset && typeof asset.atlas === "string" && typeof asset.sprite === "string";
|
|
9665
|
+
}
|
|
9666
|
+
function resolveAssetSource(img, asset, onReady) {
|
|
9667
|
+
if (isAtlasAsset(asset)) {
|
|
9668
|
+
const atlas = getAtlas(asset.atlas, onReady);
|
|
9669
|
+
if (!atlas) return null;
|
|
9670
|
+
const rect = subRectFor(atlas, asset.sprite);
|
|
9671
|
+
if (!rect) return null;
|
|
9672
|
+
return { img, rect, aspect: rect.sw / rect.sh };
|
|
9673
|
+
}
|
|
9674
|
+
const natW = img.naturalWidth || 1;
|
|
9675
|
+
const natH = img.naturalHeight || 1;
|
|
9676
|
+
return { img, rect: null, aspect: natW / natH };
|
|
9677
|
+
}
|
|
9678
|
+
function blit(ctx, src, dx, dy, dw, dh) {
|
|
9679
|
+
if (src.rect) ctx.drawImage(src.img, src.rect.sx, src.rect.sy, src.rect.sw, src.rect.sh, dx, dy, dw, dh);
|
|
9680
|
+
else ctx.drawImage(src.img, dx, dy, dw, dh);
|
|
9681
|
+
}
|
|
9682
|
+
var atlasCache;
|
|
9683
|
+
var init_atlasSlice = __esm({
|
|
9684
|
+
"components/game/shared/atlasSlice.ts"() {
|
|
9685
|
+
"use client";
|
|
9686
|
+
atlasCache = /* @__PURE__ */ new Map();
|
|
9687
|
+
}
|
|
9688
|
+
});
|
|
9619
9689
|
function useCamera() {
|
|
9620
9690
|
const cameraRef = useRef({ x: 0, y: 0, zoom: 1 });
|
|
9621
9691
|
const targetCameraRef = useRef(null);
|
|
@@ -10187,15 +10257,18 @@ function SideView({
|
|
|
10187
10257
|
const platType = plat.type ?? "ground";
|
|
10188
10258
|
const spriteAsset = tSprites?.[platType];
|
|
10189
10259
|
const tileImg = spriteAsset ? loadImage(spriteAsset.url) : null;
|
|
10190
|
-
|
|
10191
|
-
|
|
10192
|
-
const
|
|
10260
|
+
const tileSrc = tileImg ? resolveAssetSource(tileImg, spriteAsset, NOOP) : null;
|
|
10261
|
+
if (tileSrc) {
|
|
10262
|
+
const originX = tileSrc.rect ? tileSrc.rect.sx : 0;
|
|
10263
|
+
const originY = tileSrc.rect ? tileSrc.rect.sy : 0;
|
|
10264
|
+
const tileW = tileSrc.rect ? tileSrc.rect.sw : tileImg.naturalWidth;
|
|
10265
|
+
const tileH = tileSrc.rect ? tileSrc.rect.sh : tileImg.naturalHeight;
|
|
10193
10266
|
const scaleH = plat.height / tileH;
|
|
10194
10267
|
const scaledW = tileW * scaleH;
|
|
10195
10268
|
for (let tx = 0; tx < plat.width; tx += scaledW) {
|
|
10196
10269
|
const drawW = Math.min(scaledW, plat.width - tx);
|
|
10197
10270
|
const srcW = drawW / scaleH;
|
|
10198
|
-
ctx.drawImage(tileImg,
|
|
10271
|
+
ctx.drawImage(tileImg, originX, originY, srcW, tileH, platX + tx, platY, drawW, plat.height);
|
|
10199
10272
|
}
|
|
10200
10273
|
} else {
|
|
10201
10274
|
const color = PLATFORM_COLORS[platType] ?? PLATFORM_COLORS.ground;
|
|
@@ -10229,14 +10302,15 @@ function SideView({
|
|
|
10229
10302
|
const ppy = py - camY;
|
|
10230
10303
|
const facingRight = auth.facingRight ?? true;
|
|
10231
10304
|
const playerImg = pSprite ? loadImage(pSprite.url) : null;
|
|
10232
|
-
|
|
10305
|
+
const playerSrc = playerImg ? resolveAssetSource(playerImg, pSprite, NOOP) : null;
|
|
10306
|
+
if (playerSrc) {
|
|
10233
10307
|
ctx.save();
|
|
10234
10308
|
if (!facingRight) {
|
|
10235
10309
|
ctx.translate(ppx + pw, ppy);
|
|
10236
10310
|
ctx.scale(-1, 1);
|
|
10237
|
-
ctx
|
|
10311
|
+
blit(ctx, playerSrc, 0, 0, pw, ph);
|
|
10238
10312
|
} else {
|
|
10239
|
-
ctx
|
|
10313
|
+
blit(ctx, playerSrc, ppx, ppy, pw, ph);
|
|
10240
10314
|
}
|
|
10241
10315
|
ctx.restore();
|
|
10242
10316
|
} else {
|
|
@@ -10437,10 +10511,11 @@ function Canvas2D({
|
|
|
10437
10511
|
const attackTargetSet = useMemo(() => new Set(attackTargets.map((p) => `${p.x},${p.y}`)), [attackTargets]);
|
|
10438
10512
|
const spriteUrls = useMemo(() => {
|
|
10439
10513
|
const urls = [];
|
|
10514
|
+
const toUrl = (x) => typeof x === "string" ? x : x?.url;
|
|
10440
10515
|
for (const tile of sortedTiles) {
|
|
10441
10516
|
if (tile.terrainSprite) urls.push(tile.terrainSprite.url);
|
|
10442
10517
|
else if (getTerrainSprite) {
|
|
10443
|
-
const url = getTerrainSprite(tile.terrain ?? "");
|
|
10518
|
+
const url = toUrl(getTerrainSprite(tile.terrain ?? ""));
|
|
10444
10519
|
if (url) urls.push(url);
|
|
10445
10520
|
} else {
|
|
10446
10521
|
const url = assetManifest?.terrains?.[tile.terrain ?? ""]?.url;
|
|
@@ -10450,7 +10525,7 @@ function Canvas2D({
|
|
|
10450
10525
|
for (const feature of features) {
|
|
10451
10526
|
if (feature.sprite) urls.push(feature.sprite.url);
|
|
10452
10527
|
else if (getFeatureSprite) {
|
|
10453
|
-
const url = getFeatureSprite(feature.type);
|
|
10528
|
+
const url = toUrl(getFeatureSprite(feature.type));
|
|
10454
10529
|
if (url) urls.push(url);
|
|
10455
10530
|
} else {
|
|
10456
10531
|
const url = assetManifest?.features?.[feature.type]?.url;
|
|
@@ -10460,7 +10535,7 @@ function Canvas2D({
|
|
|
10460
10535
|
for (const unit of units) {
|
|
10461
10536
|
if (unit.sprite) urls.push(unit.sprite.url);
|
|
10462
10537
|
else if (getUnitSprite) {
|
|
10463
|
-
const url = getUnitSprite(unit);
|
|
10538
|
+
const url = toUrl(getUnitSprite(unit));
|
|
10464
10539
|
if (url) urls.push(url);
|
|
10465
10540
|
} else if (unit.unitType) {
|
|
10466
10541
|
const url = assetManifest?.units?.[unit.unitType]?.url;
|
|
@@ -10501,14 +10576,25 @@ function Canvas2D({
|
|
|
10501
10576
|
screenToWorld,
|
|
10502
10577
|
lerpToTarget
|
|
10503
10578
|
} = useCamera();
|
|
10504
|
-
const
|
|
10505
|
-
|
|
10579
|
+
const [, setAtlasVersion] = useState(0);
|
|
10580
|
+
const bumpAtlas = useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
10581
|
+
const resolveTerrainAsset = useCallback((tile) => {
|
|
10582
|
+
if (tile.terrainSprite) return tile.terrainSprite;
|
|
10583
|
+
const s = getTerrainSprite?.(tile.terrain ?? "");
|
|
10584
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
10585
|
+
return assetManifest?.terrains?.[tile.terrain ?? ""];
|
|
10506
10586
|
}, [getTerrainSprite, assetManifest]);
|
|
10507
|
-
const
|
|
10508
|
-
|
|
10587
|
+
const resolveFeatureAsset = useCallback((feature) => {
|
|
10588
|
+
if (feature.sprite) return feature.sprite;
|
|
10589
|
+
const s = getFeatureSprite?.(feature.type);
|
|
10590
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
10591
|
+
return assetManifest?.features?.[feature.type];
|
|
10509
10592
|
}, [getFeatureSprite, assetManifest]);
|
|
10510
|
-
const
|
|
10511
|
-
|
|
10593
|
+
const resolveUnitAsset = useCallback((unit) => {
|
|
10594
|
+
if (unit.sprite) return unit.sprite;
|
|
10595
|
+
const s = getUnitSprite?.(unit);
|
|
10596
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
10597
|
+
return unit.unitType ? assetManifest?.units?.[unit.unitType] : void 0;
|
|
10512
10598
|
}, [getUnitSprite, assetManifest]);
|
|
10513
10599
|
const miniMapTiles = useMemo(() => {
|
|
10514
10600
|
if (!showMinimap) return [];
|
|
@@ -10572,18 +10658,17 @@ function Canvas2D({
|
|
|
10572
10658
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
10573
10659
|
continue;
|
|
10574
10660
|
}
|
|
10575
|
-
const
|
|
10576
|
-
const img =
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
|
|
10582
|
-
|
|
10583
|
-
|
|
10584
|
-
|
|
10585
|
-
|
|
10586
|
-
}
|
|
10661
|
+
const terrainAsset = resolveTerrainAsset(tile);
|
|
10662
|
+
const img = terrainAsset?.url ? getImage(terrainAsset.url) : null;
|
|
10663
|
+
const src = img ? resolveAssetSource(img, terrainAsset, bumpAtlas) : null;
|
|
10664
|
+
if (src) {
|
|
10665
|
+
const drawW = scaledTileWidth;
|
|
10666
|
+
const drawH = scaledTileWidth / src.aspect;
|
|
10667
|
+
const drawX = pos.x;
|
|
10668
|
+
const drawY = flatLike ? pos.y : pos.y + scaledTileHeight - drawH;
|
|
10669
|
+
blit(ctx, src, drawX, drawY, drawW, drawH);
|
|
10670
|
+
} else if (img && img.naturalWidth === 0) {
|
|
10671
|
+
ctx.drawImage(img, pos.x, pos.y, scaledTileWidth, scaledTileHeight);
|
|
10587
10672
|
} else {
|
|
10588
10673
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
10589
10674
|
const topY = pos.y + scaledDiamondTopY;
|
|
@@ -10637,15 +10722,16 @@ function Canvas2D({
|
|
|
10637
10722
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
10638
10723
|
continue;
|
|
10639
10724
|
}
|
|
10640
|
-
const
|
|
10641
|
-
const img =
|
|
10725
|
+
const featureAsset = resolveFeatureAsset(feature);
|
|
10726
|
+
const img = featureAsset?.url ? getImage(featureAsset.url) : null;
|
|
10727
|
+
const src = img ? resolveAssetSource(img, featureAsset, bumpAtlas) : null;
|
|
10642
10728
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
10643
10729
|
const featureGroundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
10644
10730
|
const isCastle = feature.type === "castle";
|
|
10645
10731
|
const featureDrawH = isCastle ? scaledFloorHeight * 3.5 : scaledFloorHeight * 1.6;
|
|
10646
10732
|
const maxFeatureW = isCastle ? scaledTileWidth * 1.8 : scaledTileWidth * 0.7;
|
|
10647
|
-
if (
|
|
10648
|
-
const ar =
|
|
10733
|
+
if (src) {
|
|
10734
|
+
const ar = src.aspect;
|
|
10649
10735
|
let drawH = featureDrawH;
|
|
10650
10736
|
let drawW = featureDrawH * ar;
|
|
10651
10737
|
if (drawW > maxFeatureW) {
|
|
@@ -10654,7 +10740,7 @@ function Canvas2D({
|
|
|
10654
10740
|
}
|
|
10655
10741
|
const drawX = centerX - drawW / 2;
|
|
10656
10742
|
const drawY = featureGroundY - drawH;
|
|
10657
|
-
ctx
|
|
10743
|
+
blit(ctx, src, drawX, drawY, drawW, drawH);
|
|
10658
10744
|
} else {
|
|
10659
10745
|
const color = FEATURE_COLORS[feature.type] || FEATURE_COLORS.default;
|
|
10660
10746
|
ctx.beginPath();
|
|
@@ -10683,17 +10769,18 @@ function Canvas2D({
|
|
|
10683
10769
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
10684
10770
|
const groundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
10685
10771
|
const breatheOffset = 0;
|
|
10686
|
-
const
|
|
10687
|
-
const img =
|
|
10772
|
+
const unitAsset = resolveUnitAsset(unit);
|
|
10773
|
+
const img = unitAsset?.url ? getImage(unitAsset.url) : null;
|
|
10688
10774
|
const unitDrawH = scaledFloorHeight * spriteHeightRatio * unitScale;
|
|
10689
10775
|
const maxUnitW = scaledTileWidth * spriteMaxWidthRatio * unitScale;
|
|
10690
10776
|
const unitIsSheet = unit.spriteSheet?.url !== void 0;
|
|
10777
|
+
const unitSrc = img && !unitIsSheet ? resolveAssetSource(img, unitAsset, bumpAtlas) : null;
|
|
10691
10778
|
const SHEET_ROWS = 5;
|
|
10692
10779
|
const sheetFrameW = img ? img.naturalWidth / SHEET_COLUMNS : 0;
|
|
10693
10780
|
const sheetFrameH = img ? img.naturalHeight / SHEET_ROWS : 0;
|
|
10694
10781
|
const frameW = unitIsSheet ? sheetFrameW : img?.naturalWidth ?? 1;
|
|
10695
10782
|
const frameH = unitIsSheet ? sheetFrameH : img?.naturalHeight ?? 1;
|
|
10696
|
-
const ar = frameW / (frameH || 1);
|
|
10783
|
+
const ar = unitIsSheet ? sheetFrameW / (sheetFrameH || 1) : unitSrc ? unitSrc.aspect : frameW / (frameH || 1);
|
|
10697
10784
|
let drawH = unitDrawH;
|
|
10698
10785
|
let drawW = unitDrawH * ar;
|
|
10699
10786
|
if (drawW > maxUnitW) {
|
|
@@ -10709,6 +10796,8 @@ function Canvas2D({
|
|
|
10709
10796
|
if (img) {
|
|
10710
10797
|
if (unitIsSheet) {
|
|
10711
10798
|
ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
10799
|
+
} else if (unitSrc) {
|
|
10800
|
+
blit(ctx, unitSrc, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
10712
10801
|
} else {
|
|
10713
10802
|
ctx.drawImage(img, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
10714
10803
|
}
|
|
@@ -10757,6 +10846,8 @@ function Canvas2D({
|
|
|
10757
10846
|
const drawUnit = (x) => {
|
|
10758
10847
|
if (unitIsSheet) {
|
|
10759
10848
|
ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, x, spriteY, drawW, drawH);
|
|
10849
|
+
} else if (unitSrc) {
|
|
10850
|
+
blit(ctx, unitSrc, x, spriteY, drawW, drawH);
|
|
10760
10851
|
} else {
|
|
10761
10852
|
ctx.drawImage(img, x, spriteY, drawW, drawH);
|
|
10762
10853
|
}
|
|
@@ -10807,11 +10898,12 @@ function Canvas2D({
|
|
|
10807
10898
|
flatLike,
|
|
10808
10899
|
scale,
|
|
10809
10900
|
debug2,
|
|
10810
|
-
|
|
10811
|
-
|
|
10812
|
-
|
|
10901
|
+
resolveTerrainAsset,
|
|
10902
|
+
resolveFeatureAsset,
|
|
10903
|
+
resolveUnitAsset,
|
|
10813
10904
|
resolveFrameForUnit,
|
|
10814
10905
|
getImage,
|
|
10906
|
+
bumpAtlas,
|
|
10815
10907
|
baseOffsetX,
|
|
10816
10908
|
scaledTileWidth,
|
|
10817
10909
|
scaledTileHeight,
|
|
@@ -11125,7 +11217,7 @@ function Canvas2D({
|
|
|
11125
11217
|
}
|
|
11126
11218
|
);
|
|
11127
11219
|
}
|
|
11128
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
|
|
11220
|
+
var PLATFORM_COLORS, NOOP, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
|
|
11129
11221
|
var init_Canvas2D = __esm({
|
|
11130
11222
|
"components/game/2d/molecules/Canvas2D.tsx"() {
|
|
11131
11223
|
"use client";
|
|
@@ -11139,6 +11231,7 @@ var init_Canvas2D = __esm({
|
|
|
11139
11231
|
init_MiniMap();
|
|
11140
11232
|
init_HealthBar();
|
|
11141
11233
|
init_useImageCache();
|
|
11234
|
+
init_atlasSlice();
|
|
11142
11235
|
init_useCamera();
|
|
11143
11236
|
init_useCanvasGestures();
|
|
11144
11237
|
init_useRenderInterpolation();
|
|
@@ -11152,6 +11245,8 @@ var init_Canvas2D = __esm({
|
|
|
11152
11245
|
hazard: "#c0392b",
|
|
11153
11246
|
goal: "#f1c40f"
|
|
11154
11247
|
};
|
|
11248
|
+
NOOP = () => {
|
|
11249
|
+
};
|
|
11155
11250
|
PLAYER_COLOR = "#3498db";
|
|
11156
11251
|
PLAYER_EYE_COLOR = "#ffffff";
|
|
11157
11252
|
SKY_GRADIENT_TOP = "#1a1a2e";
|
|
@@ -16193,6 +16288,153 @@ var init_ComponentPatterns = __esm({
|
|
|
16193
16288
|
AlertPattern.displayName = "AlertPattern";
|
|
16194
16289
|
}
|
|
16195
16290
|
});
|
|
16291
|
+
var DEFAULT_BAR_COLOR, DEFAULT_CELL_COLOR, DEFAULT_POINTER_COLOR, POINTER_BAND, TOP_PAD, AlgorithmCanvas;
|
|
16292
|
+
var init_AlgorithmCanvas = __esm({
|
|
16293
|
+
"components/learning/molecules/AlgorithmCanvas.tsx"() {
|
|
16294
|
+
"use client";
|
|
16295
|
+
init_atoms();
|
|
16296
|
+
init_Stack();
|
|
16297
|
+
init_LearningCanvas();
|
|
16298
|
+
DEFAULT_BAR_COLOR = "#3b82f6";
|
|
16299
|
+
DEFAULT_CELL_COLOR = "#e5e7eb";
|
|
16300
|
+
DEFAULT_POINTER_COLOR = "#dc2626";
|
|
16301
|
+
POINTER_BAND = 34;
|
|
16302
|
+
TOP_PAD = 12;
|
|
16303
|
+
AlgorithmCanvas = ({
|
|
16304
|
+
className,
|
|
16305
|
+
width = 600,
|
|
16306
|
+
height = 400,
|
|
16307
|
+
title,
|
|
16308
|
+
backgroundColor,
|
|
16309
|
+
bars = [],
|
|
16310
|
+
cells = [],
|
|
16311
|
+
pointers = [],
|
|
16312
|
+
shapes = [],
|
|
16313
|
+
interactive = false,
|
|
16314
|
+
animate = false,
|
|
16315
|
+
onShapeClick,
|
|
16316
|
+
isLoading,
|
|
16317
|
+
error
|
|
16318
|
+
}) => {
|
|
16319
|
+
const derivedShapes = useMemo(() => {
|
|
16320
|
+
const out = [];
|
|
16321
|
+
if (bars.length > 0) {
|
|
16322
|
+
const slot = width / bars.length;
|
|
16323
|
+
const barW = slot * 0.8;
|
|
16324
|
+
const gap = slot * 0.1;
|
|
16325
|
+
const baseline = height - POINTER_BAND;
|
|
16326
|
+
const usableH = baseline - TOP_PAD;
|
|
16327
|
+
const maxV = Math.max(1, ...bars.map((b) => Number.isFinite(b.value) ? b.value : 0));
|
|
16328
|
+
bars.forEach((bar, i) => {
|
|
16329
|
+
const v = Number.isFinite(bar.value) ? bar.value : 0;
|
|
16330
|
+
const bh = Math.max(0, v / maxV * usableH);
|
|
16331
|
+
const x = i * slot + gap;
|
|
16332
|
+
const color = bar.color ?? DEFAULT_BAR_COLOR;
|
|
16333
|
+
out.push({
|
|
16334
|
+
type: "rect",
|
|
16335
|
+
id: `bar-${i}`,
|
|
16336
|
+
x,
|
|
16337
|
+
y: baseline - bh,
|
|
16338
|
+
width: barW,
|
|
16339
|
+
height: bh,
|
|
16340
|
+
color,
|
|
16341
|
+
fill: color
|
|
16342
|
+
});
|
|
16343
|
+
const label = bar.label ?? (bars.length <= 24 ? String(v) : void 0);
|
|
16344
|
+
if (label) {
|
|
16345
|
+
out.push({
|
|
16346
|
+
type: "text",
|
|
16347
|
+
x: x + barW / 2,
|
|
16348
|
+
y: baseline - bh - 8,
|
|
16349
|
+
text: label,
|
|
16350
|
+
color: "#374151",
|
|
16351
|
+
fontSize: 11,
|
|
16352
|
+
align: "center"
|
|
16353
|
+
});
|
|
16354
|
+
}
|
|
16355
|
+
});
|
|
16356
|
+
pointers.forEach((p) => {
|
|
16357
|
+
if (p.index < 0 || p.index >= bars.length) return;
|
|
16358
|
+
const cx = p.index * slot + slot / 2;
|
|
16359
|
+
const color = p.color ?? DEFAULT_POINTER_COLOR;
|
|
16360
|
+
out.push({
|
|
16361
|
+
type: "arrow",
|
|
16362
|
+
x1: cx,
|
|
16363
|
+
y1: height - 6,
|
|
16364
|
+
x2: cx,
|
|
16365
|
+
y2: baseline + 4,
|
|
16366
|
+
color,
|
|
16367
|
+
lineWidth: 2
|
|
16368
|
+
});
|
|
16369
|
+
if (p.label) {
|
|
16370
|
+
out.push({
|
|
16371
|
+
type: "text",
|
|
16372
|
+
x: cx,
|
|
16373
|
+
y: height - 22,
|
|
16374
|
+
text: p.label,
|
|
16375
|
+
color,
|
|
16376
|
+
fontSize: 11,
|
|
16377
|
+
align: "center"
|
|
16378
|
+
});
|
|
16379
|
+
}
|
|
16380
|
+
});
|
|
16381
|
+
}
|
|
16382
|
+
if (cells.length > 0) {
|
|
16383
|
+
const maxCol = Math.max(0, ...cells.map((c) => c.col)) + 1;
|
|
16384
|
+
const maxRow = Math.max(0, ...cells.map((c) => c.row)) + 1;
|
|
16385
|
+
const cw = width / maxCol;
|
|
16386
|
+
const ch = height / maxRow;
|
|
16387
|
+
cells.forEach((c, i) => {
|
|
16388
|
+
const x = c.col * cw;
|
|
16389
|
+
const y = c.row * ch;
|
|
16390
|
+
const color = c.color ?? DEFAULT_CELL_COLOR;
|
|
16391
|
+
out.push({
|
|
16392
|
+
type: "rect",
|
|
16393
|
+
id: `cell-${i}`,
|
|
16394
|
+
x: x + 1,
|
|
16395
|
+
y: y + 1,
|
|
16396
|
+
width: cw - 2,
|
|
16397
|
+
height: ch - 2,
|
|
16398
|
+
color: "#9ca3af",
|
|
16399
|
+
fill: color
|
|
16400
|
+
});
|
|
16401
|
+
const label = c.label ?? (c.value != null ? String(c.value) : void 0);
|
|
16402
|
+
if (label && cw >= 18 && ch >= 14) {
|
|
16403
|
+
out.push({
|
|
16404
|
+
type: "text",
|
|
16405
|
+
x: x + cw / 2,
|
|
16406
|
+
y: y + ch / 2,
|
|
16407
|
+
text: label,
|
|
16408
|
+
color: "#111827",
|
|
16409
|
+
fontSize: 12,
|
|
16410
|
+
align: "center"
|
|
16411
|
+
});
|
|
16412
|
+
}
|
|
16413
|
+
});
|
|
16414
|
+
}
|
|
16415
|
+
out.push(...shapes);
|
|
16416
|
+
return out;
|
|
16417
|
+
}, [bars, cells, pointers, shapes, width, height]);
|
|
16418
|
+
return /* @__PURE__ */ jsx(Card, { className, children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
16419
|
+
title ? /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title }) : null,
|
|
16420
|
+
/* @__PURE__ */ jsx(
|
|
16421
|
+
LearningCanvas,
|
|
16422
|
+
{
|
|
16423
|
+
width,
|
|
16424
|
+
height,
|
|
16425
|
+
backgroundColor,
|
|
16426
|
+
shapes: derivedShapes,
|
|
16427
|
+
interactive,
|
|
16428
|
+
animate,
|
|
16429
|
+
onShapeClick,
|
|
16430
|
+
isLoading,
|
|
16431
|
+
error
|
|
16432
|
+
}
|
|
16433
|
+
)
|
|
16434
|
+
] }) });
|
|
16435
|
+
};
|
|
16436
|
+
}
|
|
16437
|
+
});
|
|
16196
16438
|
var AuthLayout;
|
|
16197
16439
|
var init_AuthLayout = __esm({
|
|
16198
16440
|
"components/marketing/templates/AuthLayout.tsx"() {
|
|
@@ -45865,6 +46107,7 @@ var init_component_registry_generated = __esm({
|
|
|
45865
46107
|
init_ActionTile();
|
|
45866
46108
|
init_ActivationBlock();
|
|
45867
46109
|
init_ComponentPatterns();
|
|
46110
|
+
init_AlgorithmCanvas();
|
|
45868
46111
|
init_AnimatedCounter();
|
|
45869
46112
|
init_AnimatedGraphic();
|
|
45870
46113
|
init_AnimatedReveal();
|
|
@@ -46163,6 +46406,7 @@ var init_component_registry_generated = __esm({
|
|
|
46163
46406
|
"ActivationBlock": ActivationBlock,
|
|
46164
46407
|
"Alert": AlertPattern,
|
|
46165
46408
|
"AlertPattern": AlertPattern,
|
|
46409
|
+
"AlgorithmCanvas": AlgorithmCanvas,
|
|
46166
46410
|
"AnimatedCounter": AnimatedCounter,
|
|
46167
46411
|
"AnimatedGraphic": AnimatedGraphic,
|
|
46168
46412
|
"AnimatedReveal": AnimatedReveal,
|