@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/runtime/index.js
CHANGED
|
@@ -10142,6 +10142,76 @@ var init_StateGraph = __esm({
|
|
|
10142
10142
|
init_TransitionArrow();
|
|
10143
10143
|
}
|
|
10144
10144
|
});
|
|
10145
|
+
|
|
10146
|
+
// components/game/shared/atlasSlice.ts
|
|
10147
|
+
function isTilesheet(a) {
|
|
10148
|
+
return typeof a.tileWidth === "number";
|
|
10149
|
+
}
|
|
10150
|
+
function getAtlas(url, onReady) {
|
|
10151
|
+
if (atlasCache.has(url)) return atlasCache.get(url) ?? void 0;
|
|
10152
|
+
atlasCache.set(url, void 0);
|
|
10153
|
+
fetch(url).then((r) => r.json()).then((json) => {
|
|
10154
|
+
atlasCache.set(url, json);
|
|
10155
|
+
onReady();
|
|
10156
|
+
}).catch(() => {
|
|
10157
|
+
atlasCache.set(url, null);
|
|
10158
|
+
});
|
|
10159
|
+
return void 0;
|
|
10160
|
+
}
|
|
10161
|
+
function subRectFor(atlas, sprite) {
|
|
10162
|
+
if (isTilesheet(atlas)) {
|
|
10163
|
+
let col;
|
|
10164
|
+
let row;
|
|
10165
|
+
if (sprite.includes(",")) {
|
|
10166
|
+
const [c, r] = sprite.split(",").map((n) => Number(n.trim()));
|
|
10167
|
+
col = c;
|
|
10168
|
+
row = r;
|
|
10169
|
+
} else {
|
|
10170
|
+
const i = Number(sprite);
|
|
10171
|
+
if (!Number.isFinite(i)) return null;
|
|
10172
|
+
col = i % atlas.columns;
|
|
10173
|
+
row = Math.floor(i / atlas.columns);
|
|
10174
|
+
}
|
|
10175
|
+
if (!Number.isFinite(col) || !Number.isFinite(row) || col < 0 || row < 0 || col >= atlas.columns || row >= atlas.rows) return null;
|
|
10176
|
+
const margin = atlas.margin ?? 0;
|
|
10177
|
+
const spacing = atlas.spacing ?? 0;
|
|
10178
|
+
return {
|
|
10179
|
+
sx: margin + col * (atlas.tileWidth + spacing),
|
|
10180
|
+
sy: margin + row * (atlas.tileHeight + spacing),
|
|
10181
|
+
sw: atlas.tileWidth,
|
|
10182
|
+
sh: atlas.tileHeight
|
|
10183
|
+
};
|
|
10184
|
+
}
|
|
10185
|
+
const st = atlas.subTextures[sprite];
|
|
10186
|
+
if (!st) return null;
|
|
10187
|
+
return { sx: st.x, sy: st.y, sw: st.width, sh: st.height };
|
|
10188
|
+
}
|
|
10189
|
+
function isAtlasAsset(asset) {
|
|
10190
|
+
return !!asset && typeof asset.atlas === "string" && typeof asset.sprite === "string";
|
|
10191
|
+
}
|
|
10192
|
+
function resolveAssetSource(img, asset, onReady) {
|
|
10193
|
+
if (isAtlasAsset(asset)) {
|
|
10194
|
+
const atlas = getAtlas(asset.atlas, onReady);
|
|
10195
|
+
if (!atlas) return null;
|
|
10196
|
+
const rect = subRectFor(atlas, asset.sprite);
|
|
10197
|
+
if (!rect) return null;
|
|
10198
|
+
return { img, rect, aspect: rect.sw / rect.sh };
|
|
10199
|
+
}
|
|
10200
|
+
const natW = img.naturalWidth || 1;
|
|
10201
|
+
const natH = img.naturalHeight || 1;
|
|
10202
|
+
return { img, rect: null, aspect: natW / natH };
|
|
10203
|
+
}
|
|
10204
|
+
function blit(ctx, src, dx, dy, dw, dh) {
|
|
10205
|
+
if (src.rect) ctx.drawImage(src.img, src.rect.sx, src.rect.sy, src.rect.sw, src.rect.sh, dx, dy, dw, dh);
|
|
10206
|
+
else ctx.drawImage(src.img, dx, dy, dw, dh);
|
|
10207
|
+
}
|
|
10208
|
+
var atlasCache;
|
|
10209
|
+
var init_atlasSlice = __esm({
|
|
10210
|
+
"components/game/shared/atlasSlice.ts"() {
|
|
10211
|
+
"use client";
|
|
10212
|
+
atlasCache = /* @__PURE__ */ new Map();
|
|
10213
|
+
}
|
|
10214
|
+
});
|
|
10145
10215
|
function useCamera() {
|
|
10146
10216
|
const cameraRef = useRef({ x: 0, y: 0, zoom: 1 });
|
|
10147
10217
|
const targetCameraRef = useRef(null);
|
|
@@ -10534,15 +10604,18 @@ function SideView({
|
|
|
10534
10604
|
const platType = plat.type ?? "ground";
|
|
10535
10605
|
const spriteAsset = tSprites?.[platType];
|
|
10536
10606
|
const tileImg = spriteAsset ? loadImage(spriteAsset.url) : null;
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
const
|
|
10607
|
+
const tileSrc = tileImg ? resolveAssetSource(tileImg, spriteAsset, NOOP) : null;
|
|
10608
|
+
if (tileSrc) {
|
|
10609
|
+
const originX = tileSrc.rect ? tileSrc.rect.sx : 0;
|
|
10610
|
+
const originY = tileSrc.rect ? tileSrc.rect.sy : 0;
|
|
10611
|
+
const tileW = tileSrc.rect ? tileSrc.rect.sw : tileImg.naturalWidth;
|
|
10612
|
+
const tileH = tileSrc.rect ? tileSrc.rect.sh : tileImg.naturalHeight;
|
|
10540
10613
|
const scaleH = plat.height / tileH;
|
|
10541
10614
|
const scaledW = tileW * scaleH;
|
|
10542
10615
|
for (let tx = 0; tx < plat.width; tx += scaledW) {
|
|
10543
10616
|
const drawW = Math.min(scaledW, plat.width - tx);
|
|
10544
10617
|
const srcW = drawW / scaleH;
|
|
10545
|
-
ctx.drawImage(tileImg,
|
|
10618
|
+
ctx.drawImage(tileImg, originX, originY, srcW, tileH, platX + tx, platY, drawW, plat.height);
|
|
10546
10619
|
}
|
|
10547
10620
|
} else {
|
|
10548
10621
|
const color = PLATFORM_COLORS[platType] ?? PLATFORM_COLORS.ground;
|
|
@@ -10576,14 +10649,15 @@ function SideView({
|
|
|
10576
10649
|
const ppy = py - camY;
|
|
10577
10650
|
const facingRight = auth.facingRight ?? true;
|
|
10578
10651
|
const playerImg = pSprite ? loadImage(pSprite.url) : null;
|
|
10579
|
-
|
|
10652
|
+
const playerSrc = playerImg ? resolveAssetSource(playerImg, pSprite, NOOP) : null;
|
|
10653
|
+
if (playerSrc) {
|
|
10580
10654
|
ctx.save();
|
|
10581
10655
|
if (!facingRight) {
|
|
10582
10656
|
ctx.translate(ppx + pw, ppy);
|
|
10583
10657
|
ctx.scale(-1, 1);
|
|
10584
|
-
ctx
|
|
10658
|
+
blit(ctx, playerSrc, 0, 0, pw, ph);
|
|
10585
10659
|
} else {
|
|
10586
|
-
ctx
|
|
10660
|
+
blit(ctx, playerSrc, ppx, ppy, pw, ph);
|
|
10587
10661
|
}
|
|
10588
10662
|
ctx.restore();
|
|
10589
10663
|
} else {
|
|
@@ -10784,10 +10858,11 @@ function Canvas2D({
|
|
|
10784
10858
|
const attackTargetSet = useMemo(() => new Set(attackTargets.map((p) => `${p.x},${p.y}`)), [attackTargets]);
|
|
10785
10859
|
const spriteUrls = useMemo(() => {
|
|
10786
10860
|
const urls = [];
|
|
10861
|
+
const toUrl = (x) => typeof x === "string" ? x : x?.url;
|
|
10787
10862
|
for (const tile of sortedTiles) {
|
|
10788
10863
|
if (tile.terrainSprite) urls.push(tile.terrainSprite.url);
|
|
10789
10864
|
else if (getTerrainSprite) {
|
|
10790
|
-
const url = getTerrainSprite(tile.terrain ?? "");
|
|
10865
|
+
const url = toUrl(getTerrainSprite(tile.terrain ?? ""));
|
|
10791
10866
|
if (url) urls.push(url);
|
|
10792
10867
|
} else {
|
|
10793
10868
|
const url = assetManifest?.terrains?.[tile.terrain ?? ""]?.url;
|
|
@@ -10797,7 +10872,7 @@ function Canvas2D({
|
|
|
10797
10872
|
for (const feature of features) {
|
|
10798
10873
|
if (feature.sprite) urls.push(feature.sprite.url);
|
|
10799
10874
|
else if (getFeatureSprite) {
|
|
10800
|
-
const url = getFeatureSprite(feature.type);
|
|
10875
|
+
const url = toUrl(getFeatureSprite(feature.type));
|
|
10801
10876
|
if (url) urls.push(url);
|
|
10802
10877
|
} else {
|
|
10803
10878
|
const url = assetManifest?.features?.[feature.type]?.url;
|
|
@@ -10807,7 +10882,7 @@ function Canvas2D({
|
|
|
10807
10882
|
for (const unit of units) {
|
|
10808
10883
|
if (unit.sprite) urls.push(unit.sprite.url);
|
|
10809
10884
|
else if (getUnitSprite) {
|
|
10810
|
-
const url = getUnitSprite(unit);
|
|
10885
|
+
const url = toUrl(getUnitSprite(unit));
|
|
10811
10886
|
if (url) urls.push(url);
|
|
10812
10887
|
} else if (unit.unitType) {
|
|
10813
10888
|
const url = assetManifest?.units?.[unit.unitType]?.url;
|
|
@@ -10848,14 +10923,25 @@ function Canvas2D({
|
|
|
10848
10923
|
screenToWorld,
|
|
10849
10924
|
lerpToTarget
|
|
10850
10925
|
} = useCamera();
|
|
10851
|
-
const
|
|
10852
|
-
|
|
10926
|
+
const [, setAtlasVersion] = useState(0);
|
|
10927
|
+
const bumpAtlas = useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
10928
|
+
const resolveTerrainAsset = useCallback((tile) => {
|
|
10929
|
+
if (tile.terrainSprite) return tile.terrainSprite;
|
|
10930
|
+
const s = getTerrainSprite?.(tile.terrain ?? "");
|
|
10931
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
10932
|
+
return assetManifest?.terrains?.[tile.terrain ?? ""];
|
|
10853
10933
|
}, [getTerrainSprite, assetManifest]);
|
|
10854
|
-
const
|
|
10855
|
-
|
|
10934
|
+
const resolveFeatureAsset = useCallback((feature) => {
|
|
10935
|
+
if (feature.sprite) return feature.sprite;
|
|
10936
|
+
const s = getFeatureSprite?.(feature.type);
|
|
10937
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
10938
|
+
return assetManifest?.features?.[feature.type];
|
|
10856
10939
|
}, [getFeatureSprite, assetManifest]);
|
|
10857
|
-
const
|
|
10858
|
-
|
|
10940
|
+
const resolveUnitAsset = useCallback((unit) => {
|
|
10941
|
+
if (unit.sprite) return unit.sprite;
|
|
10942
|
+
const s = getUnitSprite?.(unit);
|
|
10943
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
10944
|
+
return unit.unitType ? assetManifest?.units?.[unit.unitType] : void 0;
|
|
10859
10945
|
}, [getUnitSprite, assetManifest]);
|
|
10860
10946
|
const miniMapTiles = useMemo(() => {
|
|
10861
10947
|
if (!showMinimap) return [];
|
|
@@ -10919,18 +11005,17 @@ function Canvas2D({
|
|
|
10919
11005
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
10920
11006
|
continue;
|
|
10921
11007
|
}
|
|
10922
|
-
const
|
|
10923
|
-
const img =
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
|
|
10927
|
-
|
|
10928
|
-
|
|
10929
|
-
|
|
10930
|
-
|
|
10931
|
-
|
|
10932
|
-
|
|
10933
|
-
}
|
|
11008
|
+
const terrainAsset = resolveTerrainAsset(tile);
|
|
11009
|
+
const img = terrainAsset?.url ? getImage(terrainAsset.url) : null;
|
|
11010
|
+
const src = img ? resolveAssetSource(img, terrainAsset, bumpAtlas) : null;
|
|
11011
|
+
if (src) {
|
|
11012
|
+
const drawW = scaledTileWidth;
|
|
11013
|
+
const drawH = scaledTileWidth / src.aspect;
|
|
11014
|
+
const drawX = pos.x;
|
|
11015
|
+
const drawY = flatLike ? pos.y : pos.y + scaledTileHeight - drawH;
|
|
11016
|
+
blit(ctx, src, drawX, drawY, drawW, drawH);
|
|
11017
|
+
} else if (img && img.naturalWidth === 0) {
|
|
11018
|
+
ctx.drawImage(img, pos.x, pos.y, scaledTileWidth, scaledTileHeight);
|
|
10934
11019
|
} else {
|
|
10935
11020
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
10936
11021
|
const topY = pos.y + scaledDiamondTopY;
|
|
@@ -10984,15 +11069,16 @@ function Canvas2D({
|
|
|
10984
11069
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
10985
11070
|
continue;
|
|
10986
11071
|
}
|
|
10987
|
-
const
|
|
10988
|
-
const img =
|
|
11072
|
+
const featureAsset = resolveFeatureAsset(feature);
|
|
11073
|
+
const img = featureAsset?.url ? getImage(featureAsset.url) : null;
|
|
11074
|
+
const src = img ? resolveAssetSource(img, featureAsset, bumpAtlas) : null;
|
|
10989
11075
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
10990
11076
|
const featureGroundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
10991
11077
|
const isCastle = feature.type === "castle";
|
|
10992
11078
|
const featureDrawH = isCastle ? scaledFloorHeight * 3.5 : scaledFloorHeight * 1.6;
|
|
10993
11079
|
const maxFeatureW = isCastle ? scaledTileWidth * 1.8 : scaledTileWidth * 0.7;
|
|
10994
|
-
if (
|
|
10995
|
-
const ar =
|
|
11080
|
+
if (src) {
|
|
11081
|
+
const ar = src.aspect;
|
|
10996
11082
|
let drawH = featureDrawH;
|
|
10997
11083
|
let drawW = featureDrawH * ar;
|
|
10998
11084
|
if (drawW > maxFeatureW) {
|
|
@@ -11001,7 +11087,7 @@ function Canvas2D({
|
|
|
11001
11087
|
}
|
|
11002
11088
|
const drawX = centerX - drawW / 2;
|
|
11003
11089
|
const drawY = featureGroundY - drawH;
|
|
11004
|
-
ctx
|
|
11090
|
+
blit(ctx, src, drawX, drawY, drawW, drawH);
|
|
11005
11091
|
} else {
|
|
11006
11092
|
const color = FEATURE_COLORS[feature.type] || FEATURE_COLORS.default;
|
|
11007
11093
|
ctx.beginPath();
|
|
@@ -11030,17 +11116,18 @@ function Canvas2D({
|
|
|
11030
11116
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
11031
11117
|
const groundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
11032
11118
|
const breatheOffset = 0;
|
|
11033
|
-
const
|
|
11034
|
-
const img =
|
|
11119
|
+
const unitAsset = resolveUnitAsset(unit);
|
|
11120
|
+
const img = unitAsset?.url ? getImage(unitAsset.url) : null;
|
|
11035
11121
|
const unitDrawH = scaledFloorHeight * spriteHeightRatio * unitScale;
|
|
11036
11122
|
const maxUnitW = scaledTileWidth * spriteMaxWidthRatio * unitScale;
|
|
11037
11123
|
const unitIsSheet = unit.spriteSheet?.url !== void 0;
|
|
11124
|
+
const unitSrc = img && !unitIsSheet ? resolveAssetSource(img, unitAsset, bumpAtlas) : null;
|
|
11038
11125
|
const SHEET_ROWS = 5;
|
|
11039
11126
|
const sheetFrameW = img ? img.naturalWidth / SHEET_COLUMNS : 0;
|
|
11040
11127
|
const sheetFrameH = img ? img.naturalHeight / SHEET_ROWS : 0;
|
|
11041
11128
|
const frameW = unitIsSheet ? sheetFrameW : img?.naturalWidth ?? 1;
|
|
11042
11129
|
const frameH = unitIsSheet ? sheetFrameH : img?.naturalHeight ?? 1;
|
|
11043
|
-
const ar = frameW / (frameH || 1);
|
|
11130
|
+
const ar = unitIsSheet ? sheetFrameW / (sheetFrameH || 1) : unitSrc ? unitSrc.aspect : frameW / (frameH || 1);
|
|
11044
11131
|
let drawH = unitDrawH;
|
|
11045
11132
|
let drawW = unitDrawH * ar;
|
|
11046
11133
|
if (drawW > maxUnitW) {
|
|
@@ -11056,6 +11143,8 @@ function Canvas2D({
|
|
|
11056
11143
|
if (img) {
|
|
11057
11144
|
if (unitIsSheet) {
|
|
11058
11145
|
ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
11146
|
+
} else if (unitSrc) {
|
|
11147
|
+
blit(ctx, unitSrc, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
11059
11148
|
} else {
|
|
11060
11149
|
ctx.drawImage(img, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
11061
11150
|
}
|
|
@@ -11104,6 +11193,8 @@ function Canvas2D({
|
|
|
11104
11193
|
const drawUnit = (x) => {
|
|
11105
11194
|
if (unitIsSheet) {
|
|
11106
11195
|
ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, x, spriteY, drawW, drawH);
|
|
11196
|
+
} else if (unitSrc) {
|
|
11197
|
+
blit(ctx, unitSrc, x, spriteY, drawW, drawH);
|
|
11107
11198
|
} else {
|
|
11108
11199
|
ctx.drawImage(img, x, spriteY, drawW, drawH);
|
|
11109
11200
|
}
|
|
@@ -11154,11 +11245,12 @@ function Canvas2D({
|
|
|
11154
11245
|
flatLike,
|
|
11155
11246
|
scale,
|
|
11156
11247
|
debug2,
|
|
11157
|
-
|
|
11158
|
-
|
|
11159
|
-
|
|
11248
|
+
resolveTerrainAsset,
|
|
11249
|
+
resolveFeatureAsset,
|
|
11250
|
+
resolveUnitAsset,
|
|
11160
11251
|
resolveFrameForUnit,
|
|
11161
11252
|
getImage,
|
|
11253
|
+
bumpAtlas,
|
|
11162
11254
|
baseOffsetX,
|
|
11163
11255
|
scaledTileWidth,
|
|
11164
11256
|
scaledTileHeight,
|
|
@@ -11472,7 +11564,7 @@ function Canvas2D({
|
|
|
11472
11564
|
}
|
|
11473
11565
|
);
|
|
11474
11566
|
}
|
|
11475
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
|
|
11567
|
+
var PLATFORM_COLORS, NOOP, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
|
|
11476
11568
|
var init_Canvas2D = __esm({
|
|
11477
11569
|
"components/game/2d/molecules/Canvas2D.tsx"() {
|
|
11478
11570
|
"use client";
|
|
@@ -11486,6 +11578,7 @@ var init_Canvas2D = __esm({
|
|
|
11486
11578
|
init_MiniMap();
|
|
11487
11579
|
init_HealthBar();
|
|
11488
11580
|
init_useImageCache();
|
|
11581
|
+
init_atlasSlice();
|
|
11489
11582
|
init_useCamera();
|
|
11490
11583
|
init_useCanvasGestures();
|
|
11491
11584
|
init_useRenderInterpolation();
|
|
@@ -11499,6 +11592,8 @@ var init_Canvas2D = __esm({
|
|
|
11499
11592
|
hazard: "#c0392b",
|
|
11500
11593
|
goal: "#f1c40f"
|
|
11501
11594
|
};
|
|
11595
|
+
NOOP = () => {
|
|
11596
|
+
};
|
|
11502
11597
|
PLAYER_COLOR = "#3498db";
|
|
11503
11598
|
PLAYER_EYE_COLOR = "#ffffff";
|
|
11504
11599
|
SKY_GRADIENT_TOP = "#1a1a2e";
|
|
@@ -16157,6 +16252,153 @@ var init_ComponentPatterns = __esm({
|
|
|
16157
16252
|
AlertPattern.displayName = "AlertPattern";
|
|
16158
16253
|
}
|
|
16159
16254
|
});
|
|
16255
|
+
var DEFAULT_BAR_COLOR, DEFAULT_CELL_COLOR, DEFAULT_POINTER_COLOR, POINTER_BAND, TOP_PAD, AlgorithmCanvas;
|
|
16256
|
+
var init_AlgorithmCanvas = __esm({
|
|
16257
|
+
"components/learning/molecules/AlgorithmCanvas.tsx"() {
|
|
16258
|
+
"use client";
|
|
16259
|
+
init_atoms();
|
|
16260
|
+
init_Stack();
|
|
16261
|
+
init_LearningCanvas();
|
|
16262
|
+
DEFAULT_BAR_COLOR = "#3b82f6";
|
|
16263
|
+
DEFAULT_CELL_COLOR = "#e5e7eb";
|
|
16264
|
+
DEFAULT_POINTER_COLOR = "#dc2626";
|
|
16265
|
+
POINTER_BAND = 34;
|
|
16266
|
+
TOP_PAD = 12;
|
|
16267
|
+
AlgorithmCanvas = ({
|
|
16268
|
+
className,
|
|
16269
|
+
width = 600,
|
|
16270
|
+
height = 400,
|
|
16271
|
+
title,
|
|
16272
|
+
backgroundColor,
|
|
16273
|
+
bars = [],
|
|
16274
|
+
cells = [],
|
|
16275
|
+
pointers = [],
|
|
16276
|
+
shapes = [],
|
|
16277
|
+
interactive = false,
|
|
16278
|
+
animate = false,
|
|
16279
|
+
onShapeClick,
|
|
16280
|
+
isLoading,
|
|
16281
|
+
error
|
|
16282
|
+
}) => {
|
|
16283
|
+
const derivedShapes = useMemo(() => {
|
|
16284
|
+
const out = [];
|
|
16285
|
+
if (bars.length > 0) {
|
|
16286
|
+
const slot = width / bars.length;
|
|
16287
|
+
const barW = slot * 0.8;
|
|
16288
|
+
const gap = slot * 0.1;
|
|
16289
|
+
const baseline = height - POINTER_BAND;
|
|
16290
|
+
const usableH = baseline - TOP_PAD;
|
|
16291
|
+
const maxV = Math.max(1, ...bars.map((b) => Number.isFinite(b.value) ? b.value : 0));
|
|
16292
|
+
bars.forEach((bar, i) => {
|
|
16293
|
+
const v = Number.isFinite(bar.value) ? bar.value : 0;
|
|
16294
|
+
const bh = Math.max(0, v / maxV * usableH);
|
|
16295
|
+
const x = i * slot + gap;
|
|
16296
|
+
const color = bar.color ?? DEFAULT_BAR_COLOR;
|
|
16297
|
+
out.push({
|
|
16298
|
+
type: "rect",
|
|
16299
|
+
id: `bar-${i}`,
|
|
16300
|
+
x,
|
|
16301
|
+
y: baseline - bh,
|
|
16302
|
+
width: barW,
|
|
16303
|
+
height: bh,
|
|
16304
|
+
color,
|
|
16305
|
+
fill: color
|
|
16306
|
+
});
|
|
16307
|
+
const label = bar.label ?? (bars.length <= 24 ? String(v) : void 0);
|
|
16308
|
+
if (label) {
|
|
16309
|
+
out.push({
|
|
16310
|
+
type: "text",
|
|
16311
|
+
x: x + barW / 2,
|
|
16312
|
+
y: baseline - bh - 8,
|
|
16313
|
+
text: label,
|
|
16314
|
+
color: "#374151",
|
|
16315
|
+
fontSize: 11,
|
|
16316
|
+
align: "center"
|
|
16317
|
+
});
|
|
16318
|
+
}
|
|
16319
|
+
});
|
|
16320
|
+
pointers.forEach((p) => {
|
|
16321
|
+
if (p.index < 0 || p.index >= bars.length) return;
|
|
16322
|
+
const cx = p.index * slot + slot / 2;
|
|
16323
|
+
const color = p.color ?? DEFAULT_POINTER_COLOR;
|
|
16324
|
+
out.push({
|
|
16325
|
+
type: "arrow",
|
|
16326
|
+
x1: cx,
|
|
16327
|
+
y1: height - 6,
|
|
16328
|
+
x2: cx,
|
|
16329
|
+
y2: baseline + 4,
|
|
16330
|
+
color,
|
|
16331
|
+
lineWidth: 2
|
|
16332
|
+
});
|
|
16333
|
+
if (p.label) {
|
|
16334
|
+
out.push({
|
|
16335
|
+
type: "text",
|
|
16336
|
+
x: cx,
|
|
16337
|
+
y: height - 22,
|
|
16338
|
+
text: p.label,
|
|
16339
|
+
color,
|
|
16340
|
+
fontSize: 11,
|
|
16341
|
+
align: "center"
|
|
16342
|
+
});
|
|
16343
|
+
}
|
|
16344
|
+
});
|
|
16345
|
+
}
|
|
16346
|
+
if (cells.length > 0) {
|
|
16347
|
+
const maxCol = Math.max(0, ...cells.map((c) => c.col)) + 1;
|
|
16348
|
+
const maxRow = Math.max(0, ...cells.map((c) => c.row)) + 1;
|
|
16349
|
+
const cw = width / maxCol;
|
|
16350
|
+
const ch = height / maxRow;
|
|
16351
|
+
cells.forEach((c, i) => {
|
|
16352
|
+
const x = c.col * cw;
|
|
16353
|
+
const y = c.row * ch;
|
|
16354
|
+
const color = c.color ?? DEFAULT_CELL_COLOR;
|
|
16355
|
+
out.push({
|
|
16356
|
+
type: "rect",
|
|
16357
|
+
id: `cell-${i}`,
|
|
16358
|
+
x: x + 1,
|
|
16359
|
+
y: y + 1,
|
|
16360
|
+
width: cw - 2,
|
|
16361
|
+
height: ch - 2,
|
|
16362
|
+
color: "#9ca3af",
|
|
16363
|
+
fill: color
|
|
16364
|
+
});
|
|
16365
|
+
const label = c.label ?? (c.value != null ? String(c.value) : void 0);
|
|
16366
|
+
if (label && cw >= 18 && ch >= 14) {
|
|
16367
|
+
out.push({
|
|
16368
|
+
type: "text",
|
|
16369
|
+
x: x + cw / 2,
|
|
16370
|
+
y: y + ch / 2,
|
|
16371
|
+
text: label,
|
|
16372
|
+
color: "#111827",
|
|
16373
|
+
fontSize: 12,
|
|
16374
|
+
align: "center"
|
|
16375
|
+
});
|
|
16376
|
+
}
|
|
16377
|
+
});
|
|
16378
|
+
}
|
|
16379
|
+
out.push(...shapes);
|
|
16380
|
+
return out;
|
|
16381
|
+
}, [bars, cells, pointers, shapes, width, height]);
|
|
16382
|
+
return /* @__PURE__ */ jsx(Card, { className, children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
16383
|
+
title ? /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title }) : null,
|
|
16384
|
+
/* @__PURE__ */ jsx(
|
|
16385
|
+
LearningCanvas,
|
|
16386
|
+
{
|
|
16387
|
+
width,
|
|
16388
|
+
height,
|
|
16389
|
+
backgroundColor,
|
|
16390
|
+
shapes: derivedShapes,
|
|
16391
|
+
interactive,
|
|
16392
|
+
animate,
|
|
16393
|
+
onShapeClick,
|
|
16394
|
+
isLoading,
|
|
16395
|
+
error
|
|
16396
|
+
}
|
|
16397
|
+
)
|
|
16398
|
+
] }) });
|
|
16399
|
+
};
|
|
16400
|
+
}
|
|
16401
|
+
});
|
|
16160
16402
|
var AuthLayout;
|
|
16161
16403
|
var init_AuthLayout = __esm({
|
|
16162
16404
|
"components/marketing/templates/AuthLayout.tsx"() {
|
|
@@ -45515,6 +45757,7 @@ var init_component_registry_generated = __esm({
|
|
|
45515
45757
|
init_ActionTile();
|
|
45516
45758
|
init_ActivationBlock();
|
|
45517
45759
|
init_ComponentPatterns();
|
|
45760
|
+
init_AlgorithmCanvas();
|
|
45518
45761
|
init_AnimatedCounter();
|
|
45519
45762
|
init_AnimatedGraphic();
|
|
45520
45763
|
init_AnimatedReveal();
|
|
@@ -45813,6 +46056,7 @@ var init_component_registry_generated = __esm({
|
|
|
45813
46056
|
"ActivationBlock": ActivationBlock,
|
|
45814
46057
|
"Alert": AlertPattern,
|
|
45815
46058
|
"AlertPattern": AlertPattern,
|
|
46059
|
+
"AlgorithmCanvas": AlgorithmCanvas,
|
|
45816
46060
|
"AnimatedCounter": AnimatedCounter,
|
|
45817
46061
|
"AnimatedGraphic": AnimatedGraphic,
|
|
45818
46062
|
"AnimatedReveal": AnimatedReveal,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.95.0",
|
|
4
4
|
"description": "React UI components, hooks, and providers for Almadar",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"lint": "eslint --no-warn-ignored --max-warnings 0 ."
|
|
124
124
|
},
|
|
125
125
|
"dependencies": {
|
|
126
|
-
"@almadar/core": "^10.
|
|
126
|
+
"@almadar/core": "^10.14.0",
|
|
127
127
|
"@almadar/evaluator": ">=2.9.2",
|
|
128
128
|
"@almadar/logger": "^1.3.0",
|
|
129
129
|
"@almadar/patterns": ">=2.35.0",
|