@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
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AlgorithmCanvas
|
|
3
|
+
*
|
|
4
|
+
* A field-scoped learning molecule for computer-science algorithm visualizations.
|
|
5
|
+
* Projects semantic `bars` (sorting/histograms), `cells` (grids/arrays/DP tables),
|
|
6
|
+
* and `pointers` (index cursors) into pixel-space shapes on the declarative
|
|
7
|
+
* `LearningCanvas` atom, so a `.lolo` behavior never computes pixel coordinates —
|
|
8
|
+
* it just sets `bars`/`cells`/`pointers` and lets this molecule lay them out.
|
|
9
|
+
* Graph/tree algorithms reuse `BiologyCanvas` (nodes + edges); this canvas owns
|
|
10
|
+
* only the bar/cell/pointer vocabulary.
|
|
11
|
+
*
|
|
12
|
+
* @packageDocumentation
|
|
13
|
+
*/
|
|
14
|
+
import * as React from 'react';
|
|
15
|
+
import type { LearningShape } from '../atoms/LearningCanvas';
|
|
16
|
+
import type { UiError } from '../../core/atoms/types';
|
|
17
|
+
export interface AlgorithmBar {
|
|
18
|
+
value: number;
|
|
19
|
+
color?: string;
|
|
20
|
+
label?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface AlgorithmCell {
|
|
23
|
+
row: number;
|
|
24
|
+
col: number;
|
|
25
|
+
value?: number;
|
|
26
|
+
color?: string;
|
|
27
|
+
label?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface AlgorithmPointer {
|
|
30
|
+
index: number;
|
|
31
|
+
label?: string;
|
|
32
|
+
color?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface AlgorithmCanvasProps {
|
|
35
|
+
className?: string;
|
|
36
|
+
width?: number;
|
|
37
|
+
height?: number;
|
|
38
|
+
title?: string;
|
|
39
|
+
backgroundColor?: string;
|
|
40
|
+
/** Sorting/histogram bars; laid out left-to-right, height proportional to value. */
|
|
41
|
+
bars?: AlgorithmBar[];
|
|
42
|
+
/** Grid/array/DP cells; laid out on a row/col lattice sized to the extent. */
|
|
43
|
+
cells?: AlgorithmCell[];
|
|
44
|
+
/** Index cursors (i/j/lo/hi/mid); drawn as markers beneath the referenced bar/cell column. */
|
|
45
|
+
pointers?: AlgorithmPointer[];
|
|
46
|
+
/** Extra declarative shapes in canvas pixel coordinates. */
|
|
47
|
+
shapes?: LearningShape[];
|
|
48
|
+
interactive?: boolean;
|
|
49
|
+
animate?: boolean;
|
|
50
|
+
onShapeClick?: (payload: {
|
|
51
|
+
id?: string;
|
|
52
|
+
type?: string;
|
|
53
|
+
index: number;
|
|
54
|
+
}) => void;
|
|
55
|
+
isLoading?: boolean;
|
|
56
|
+
error?: UiError | null;
|
|
57
|
+
}
|
|
58
|
+
export declare const AlgorithmCanvas: React.FC<AlgorithmCanvasProps>;
|
package/dist/providers/index.cjs
CHANGED
|
@@ -9661,6 +9661,76 @@ var init_StateGraph = __esm({
|
|
|
9661
9661
|
init_TransitionArrow();
|
|
9662
9662
|
}
|
|
9663
9663
|
});
|
|
9664
|
+
|
|
9665
|
+
// components/game/shared/atlasSlice.ts
|
|
9666
|
+
function isTilesheet(a) {
|
|
9667
|
+
return typeof a.tileWidth === "number";
|
|
9668
|
+
}
|
|
9669
|
+
function getAtlas(url, onReady) {
|
|
9670
|
+
if (atlasCache.has(url)) return atlasCache.get(url) ?? void 0;
|
|
9671
|
+
atlasCache.set(url, void 0);
|
|
9672
|
+
fetch(url).then((r) => r.json()).then((json) => {
|
|
9673
|
+
atlasCache.set(url, json);
|
|
9674
|
+
onReady();
|
|
9675
|
+
}).catch(() => {
|
|
9676
|
+
atlasCache.set(url, null);
|
|
9677
|
+
});
|
|
9678
|
+
return void 0;
|
|
9679
|
+
}
|
|
9680
|
+
function subRectFor(atlas, sprite) {
|
|
9681
|
+
if (isTilesheet(atlas)) {
|
|
9682
|
+
let col;
|
|
9683
|
+
let row;
|
|
9684
|
+
if (sprite.includes(",")) {
|
|
9685
|
+
const [c, r] = sprite.split(",").map((n) => Number(n.trim()));
|
|
9686
|
+
col = c;
|
|
9687
|
+
row = r;
|
|
9688
|
+
} else {
|
|
9689
|
+
const i = Number(sprite);
|
|
9690
|
+
if (!Number.isFinite(i)) return null;
|
|
9691
|
+
col = i % atlas.columns;
|
|
9692
|
+
row = Math.floor(i / atlas.columns);
|
|
9693
|
+
}
|
|
9694
|
+
if (!Number.isFinite(col) || !Number.isFinite(row) || col < 0 || row < 0 || col >= atlas.columns || row >= atlas.rows) return null;
|
|
9695
|
+
const margin = atlas.margin ?? 0;
|
|
9696
|
+
const spacing = atlas.spacing ?? 0;
|
|
9697
|
+
return {
|
|
9698
|
+
sx: margin + col * (atlas.tileWidth + spacing),
|
|
9699
|
+
sy: margin + row * (atlas.tileHeight + spacing),
|
|
9700
|
+
sw: atlas.tileWidth,
|
|
9701
|
+
sh: atlas.tileHeight
|
|
9702
|
+
};
|
|
9703
|
+
}
|
|
9704
|
+
const st = atlas.subTextures[sprite];
|
|
9705
|
+
if (!st) return null;
|
|
9706
|
+
return { sx: st.x, sy: st.y, sw: st.width, sh: st.height };
|
|
9707
|
+
}
|
|
9708
|
+
function isAtlasAsset(asset) {
|
|
9709
|
+
return !!asset && typeof asset.atlas === "string" && typeof asset.sprite === "string";
|
|
9710
|
+
}
|
|
9711
|
+
function resolveAssetSource(img, asset, onReady) {
|
|
9712
|
+
if (isAtlasAsset(asset)) {
|
|
9713
|
+
const atlas = getAtlas(asset.atlas, onReady);
|
|
9714
|
+
if (!atlas) return null;
|
|
9715
|
+
const rect = subRectFor(atlas, asset.sprite);
|
|
9716
|
+
if (!rect) return null;
|
|
9717
|
+
return { img, rect, aspect: rect.sw / rect.sh };
|
|
9718
|
+
}
|
|
9719
|
+
const natW = img.naturalWidth || 1;
|
|
9720
|
+
const natH = img.naturalHeight || 1;
|
|
9721
|
+
return { img, rect: null, aspect: natW / natH };
|
|
9722
|
+
}
|
|
9723
|
+
function blit(ctx, src, dx, dy, dw, dh) {
|
|
9724
|
+
if (src.rect) ctx.drawImage(src.img, src.rect.sx, src.rect.sy, src.rect.sw, src.rect.sh, dx, dy, dw, dh);
|
|
9725
|
+
else ctx.drawImage(src.img, dx, dy, dw, dh);
|
|
9726
|
+
}
|
|
9727
|
+
var atlasCache;
|
|
9728
|
+
var init_atlasSlice = __esm({
|
|
9729
|
+
"components/game/shared/atlasSlice.ts"() {
|
|
9730
|
+
"use client";
|
|
9731
|
+
atlasCache = /* @__PURE__ */ new Map();
|
|
9732
|
+
}
|
|
9733
|
+
});
|
|
9664
9734
|
function useCamera() {
|
|
9665
9735
|
const cameraRef = React97.useRef({ x: 0, y: 0, zoom: 1 });
|
|
9666
9736
|
const targetCameraRef = React97.useRef(null);
|
|
@@ -10232,15 +10302,18 @@ function SideView({
|
|
|
10232
10302
|
const platType = plat.type ?? "ground";
|
|
10233
10303
|
const spriteAsset = tSprites?.[platType];
|
|
10234
10304
|
const tileImg = spriteAsset ? loadImage(spriteAsset.url) : null;
|
|
10235
|
-
|
|
10236
|
-
|
|
10237
|
-
const
|
|
10305
|
+
const tileSrc = tileImg ? resolveAssetSource(tileImg, spriteAsset, NOOP) : null;
|
|
10306
|
+
if (tileSrc) {
|
|
10307
|
+
const originX = tileSrc.rect ? tileSrc.rect.sx : 0;
|
|
10308
|
+
const originY = tileSrc.rect ? tileSrc.rect.sy : 0;
|
|
10309
|
+
const tileW = tileSrc.rect ? tileSrc.rect.sw : tileImg.naturalWidth;
|
|
10310
|
+
const tileH = tileSrc.rect ? tileSrc.rect.sh : tileImg.naturalHeight;
|
|
10238
10311
|
const scaleH = plat.height / tileH;
|
|
10239
10312
|
const scaledW = tileW * scaleH;
|
|
10240
10313
|
for (let tx = 0; tx < plat.width; tx += scaledW) {
|
|
10241
10314
|
const drawW = Math.min(scaledW, plat.width - tx);
|
|
10242
10315
|
const srcW = drawW / scaleH;
|
|
10243
|
-
ctx.drawImage(tileImg,
|
|
10316
|
+
ctx.drawImage(tileImg, originX, originY, srcW, tileH, platX + tx, platY, drawW, plat.height);
|
|
10244
10317
|
}
|
|
10245
10318
|
} else {
|
|
10246
10319
|
const color = PLATFORM_COLORS[platType] ?? PLATFORM_COLORS.ground;
|
|
@@ -10274,14 +10347,15 @@ function SideView({
|
|
|
10274
10347
|
const ppy = py - camY;
|
|
10275
10348
|
const facingRight = auth.facingRight ?? true;
|
|
10276
10349
|
const playerImg = pSprite ? loadImage(pSprite.url) : null;
|
|
10277
|
-
|
|
10350
|
+
const playerSrc = playerImg ? resolveAssetSource(playerImg, pSprite, NOOP) : null;
|
|
10351
|
+
if (playerSrc) {
|
|
10278
10352
|
ctx.save();
|
|
10279
10353
|
if (!facingRight) {
|
|
10280
10354
|
ctx.translate(ppx + pw, ppy);
|
|
10281
10355
|
ctx.scale(-1, 1);
|
|
10282
|
-
ctx
|
|
10356
|
+
blit(ctx, playerSrc, 0, 0, pw, ph);
|
|
10283
10357
|
} else {
|
|
10284
|
-
ctx
|
|
10358
|
+
blit(ctx, playerSrc, ppx, ppy, pw, ph);
|
|
10285
10359
|
}
|
|
10286
10360
|
ctx.restore();
|
|
10287
10361
|
} else {
|
|
@@ -10482,10 +10556,11 @@ function Canvas2D({
|
|
|
10482
10556
|
const attackTargetSet = React97.useMemo(() => new Set(attackTargets.map((p) => `${p.x},${p.y}`)), [attackTargets]);
|
|
10483
10557
|
const spriteUrls = React97.useMemo(() => {
|
|
10484
10558
|
const urls = [];
|
|
10559
|
+
const toUrl = (x) => typeof x === "string" ? x : x?.url;
|
|
10485
10560
|
for (const tile of sortedTiles) {
|
|
10486
10561
|
if (tile.terrainSprite) urls.push(tile.terrainSprite.url);
|
|
10487
10562
|
else if (getTerrainSprite) {
|
|
10488
|
-
const url = getTerrainSprite(tile.terrain ?? "");
|
|
10563
|
+
const url = toUrl(getTerrainSprite(tile.terrain ?? ""));
|
|
10489
10564
|
if (url) urls.push(url);
|
|
10490
10565
|
} else {
|
|
10491
10566
|
const url = assetManifest?.terrains?.[tile.terrain ?? ""]?.url;
|
|
@@ -10495,7 +10570,7 @@ function Canvas2D({
|
|
|
10495
10570
|
for (const feature of features) {
|
|
10496
10571
|
if (feature.sprite) urls.push(feature.sprite.url);
|
|
10497
10572
|
else if (getFeatureSprite) {
|
|
10498
|
-
const url = getFeatureSprite(feature.type);
|
|
10573
|
+
const url = toUrl(getFeatureSprite(feature.type));
|
|
10499
10574
|
if (url) urls.push(url);
|
|
10500
10575
|
} else {
|
|
10501
10576
|
const url = assetManifest?.features?.[feature.type]?.url;
|
|
@@ -10505,7 +10580,7 @@ function Canvas2D({
|
|
|
10505
10580
|
for (const unit of units) {
|
|
10506
10581
|
if (unit.sprite) urls.push(unit.sprite.url);
|
|
10507
10582
|
else if (getUnitSprite) {
|
|
10508
|
-
const url = getUnitSprite(unit);
|
|
10583
|
+
const url = toUrl(getUnitSprite(unit));
|
|
10509
10584
|
if (url) urls.push(url);
|
|
10510
10585
|
} else if (unit.unitType) {
|
|
10511
10586
|
const url = assetManifest?.units?.[unit.unitType]?.url;
|
|
@@ -10546,14 +10621,25 @@ function Canvas2D({
|
|
|
10546
10621
|
screenToWorld,
|
|
10547
10622
|
lerpToTarget
|
|
10548
10623
|
} = useCamera();
|
|
10549
|
-
const
|
|
10550
|
-
|
|
10624
|
+
const [, setAtlasVersion] = React97.useState(0);
|
|
10625
|
+
const bumpAtlas = React97.useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
10626
|
+
const resolveTerrainAsset = React97.useCallback((tile) => {
|
|
10627
|
+
if (tile.terrainSprite) return tile.terrainSprite;
|
|
10628
|
+
const s = getTerrainSprite?.(tile.terrain ?? "");
|
|
10629
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
10630
|
+
return assetManifest?.terrains?.[tile.terrain ?? ""];
|
|
10551
10631
|
}, [getTerrainSprite, assetManifest]);
|
|
10552
|
-
const
|
|
10553
|
-
|
|
10632
|
+
const resolveFeatureAsset = React97.useCallback((feature) => {
|
|
10633
|
+
if (feature.sprite) return feature.sprite;
|
|
10634
|
+
const s = getFeatureSprite?.(feature.type);
|
|
10635
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
10636
|
+
return assetManifest?.features?.[feature.type];
|
|
10554
10637
|
}, [getFeatureSprite, assetManifest]);
|
|
10555
|
-
const
|
|
10556
|
-
|
|
10638
|
+
const resolveUnitAsset = React97.useCallback((unit) => {
|
|
10639
|
+
if (unit.sprite) return unit.sprite;
|
|
10640
|
+
const s = getUnitSprite?.(unit);
|
|
10641
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
10642
|
+
return unit.unitType ? assetManifest?.units?.[unit.unitType] : void 0;
|
|
10557
10643
|
}, [getUnitSprite, assetManifest]);
|
|
10558
10644
|
const miniMapTiles = React97.useMemo(() => {
|
|
10559
10645
|
if (!showMinimap) return [];
|
|
@@ -10617,18 +10703,17 @@ function Canvas2D({
|
|
|
10617
10703
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
10618
10704
|
continue;
|
|
10619
10705
|
}
|
|
10620
|
-
const
|
|
10621
|
-
const img =
|
|
10622
|
-
|
|
10623
|
-
|
|
10624
|
-
|
|
10625
|
-
|
|
10626
|
-
|
|
10627
|
-
|
|
10628
|
-
|
|
10629
|
-
|
|
10630
|
-
|
|
10631
|
-
}
|
|
10706
|
+
const terrainAsset = resolveTerrainAsset(tile);
|
|
10707
|
+
const img = terrainAsset?.url ? getImage(terrainAsset.url) : null;
|
|
10708
|
+
const src = img ? resolveAssetSource(img, terrainAsset, bumpAtlas) : null;
|
|
10709
|
+
if (src) {
|
|
10710
|
+
const drawW = scaledTileWidth;
|
|
10711
|
+
const drawH = scaledTileWidth / src.aspect;
|
|
10712
|
+
const drawX = pos.x;
|
|
10713
|
+
const drawY = flatLike ? pos.y : pos.y + scaledTileHeight - drawH;
|
|
10714
|
+
blit(ctx, src, drawX, drawY, drawW, drawH);
|
|
10715
|
+
} else if (img && img.naturalWidth === 0) {
|
|
10716
|
+
ctx.drawImage(img, pos.x, pos.y, scaledTileWidth, scaledTileHeight);
|
|
10632
10717
|
} else {
|
|
10633
10718
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
10634
10719
|
const topY = pos.y + scaledDiamondTopY;
|
|
@@ -10682,15 +10767,16 @@ function Canvas2D({
|
|
|
10682
10767
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
10683
10768
|
continue;
|
|
10684
10769
|
}
|
|
10685
|
-
const
|
|
10686
|
-
const img =
|
|
10770
|
+
const featureAsset = resolveFeatureAsset(feature);
|
|
10771
|
+
const img = featureAsset?.url ? getImage(featureAsset.url) : null;
|
|
10772
|
+
const src = img ? resolveAssetSource(img, featureAsset, bumpAtlas) : null;
|
|
10687
10773
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
10688
10774
|
const featureGroundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
10689
10775
|
const isCastle = feature.type === "castle";
|
|
10690
10776
|
const featureDrawH = isCastle ? scaledFloorHeight * 3.5 : scaledFloorHeight * 1.6;
|
|
10691
10777
|
const maxFeatureW = isCastle ? scaledTileWidth * 1.8 : scaledTileWidth * 0.7;
|
|
10692
|
-
if (
|
|
10693
|
-
const ar =
|
|
10778
|
+
if (src) {
|
|
10779
|
+
const ar = src.aspect;
|
|
10694
10780
|
let drawH = featureDrawH;
|
|
10695
10781
|
let drawW = featureDrawH * ar;
|
|
10696
10782
|
if (drawW > maxFeatureW) {
|
|
@@ -10699,7 +10785,7 @@ function Canvas2D({
|
|
|
10699
10785
|
}
|
|
10700
10786
|
const drawX = centerX - drawW / 2;
|
|
10701
10787
|
const drawY = featureGroundY - drawH;
|
|
10702
|
-
ctx
|
|
10788
|
+
blit(ctx, src, drawX, drawY, drawW, drawH);
|
|
10703
10789
|
} else {
|
|
10704
10790
|
const color = FEATURE_COLORS[feature.type] || FEATURE_COLORS.default;
|
|
10705
10791
|
ctx.beginPath();
|
|
@@ -10728,17 +10814,18 @@ function Canvas2D({
|
|
|
10728
10814
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
10729
10815
|
const groundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
10730
10816
|
const breatheOffset = 0;
|
|
10731
|
-
const
|
|
10732
|
-
const img =
|
|
10817
|
+
const unitAsset = resolveUnitAsset(unit);
|
|
10818
|
+
const img = unitAsset?.url ? getImage(unitAsset.url) : null;
|
|
10733
10819
|
const unitDrawH = scaledFloorHeight * spriteHeightRatio * unitScale;
|
|
10734
10820
|
const maxUnitW = scaledTileWidth * spriteMaxWidthRatio * unitScale;
|
|
10735
10821
|
const unitIsSheet = unit.spriteSheet?.url !== void 0;
|
|
10822
|
+
const unitSrc = img && !unitIsSheet ? resolveAssetSource(img, unitAsset, bumpAtlas) : null;
|
|
10736
10823
|
const SHEET_ROWS = 5;
|
|
10737
10824
|
const sheetFrameW = img ? img.naturalWidth / SHEET_COLUMNS : 0;
|
|
10738
10825
|
const sheetFrameH = img ? img.naturalHeight / SHEET_ROWS : 0;
|
|
10739
10826
|
const frameW = unitIsSheet ? sheetFrameW : img?.naturalWidth ?? 1;
|
|
10740
10827
|
const frameH = unitIsSheet ? sheetFrameH : img?.naturalHeight ?? 1;
|
|
10741
|
-
const ar = frameW / (frameH || 1);
|
|
10828
|
+
const ar = unitIsSheet ? sheetFrameW / (sheetFrameH || 1) : unitSrc ? unitSrc.aspect : frameW / (frameH || 1);
|
|
10742
10829
|
let drawH = unitDrawH;
|
|
10743
10830
|
let drawW = unitDrawH * ar;
|
|
10744
10831
|
if (drawW > maxUnitW) {
|
|
@@ -10754,6 +10841,8 @@ function Canvas2D({
|
|
|
10754
10841
|
if (img) {
|
|
10755
10842
|
if (unitIsSheet) {
|
|
10756
10843
|
ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
10844
|
+
} else if (unitSrc) {
|
|
10845
|
+
blit(ctx, unitSrc, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
10757
10846
|
} else {
|
|
10758
10847
|
ctx.drawImage(img, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
10759
10848
|
}
|
|
@@ -10802,6 +10891,8 @@ function Canvas2D({
|
|
|
10802
10891
|
const drawUnit = (x) => {
|
|
10803
10892
|
if (unitIsSheet) {
|
|
10804
10893
|
ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, x, spriteY, drawW, drawH);
|
|
10894
|
+
} else if (unitSrc) {
|
|
10895
|
+
blit(ctx, unitSrc, x, spriteY, drawW, drawH);
|
|
10805
10896
|
} else {
|
|
10806
10897
|
ctx.drawImage(img, x, spriteY, drawW, drawH);
|
|
10807
10898
|
}
|
|
@@ -10852,11 +10943,12 @@ function Canvas2D({
|
|
|
10852
10943
|
flatLike,
|
|
10853
10944
|
scale,
|
|
10854
10945
|
debug2,
|
|
10855
|
-
|
|
10856
|
-
|
|
10857
|
-
|
|
10946
|
+
resolveTerrainAsset,
|
|
10947
|
+
resolveFeatureAsset,
|
|
10948
|
+
resolveUnitAsset,
|
|
10858
10949
|
resolveFrameForUnit,
|
|
10859
10950
|
getImage,
|
|
10951
|
+
bumpAtlas,
|
|
10860
10952
|
baseOffsetX,
|
|
10861
10953
|
scaledTileWidth,
|
|
10862
10954
|
scaledTileHeight,
|
|
@@ -11170,7 +11262,7 @@ function Canvas2D({
|
|
|
11170
11262
|
}
|
|
11171
11263
|
);
|
|
11172
11264
|
}
|
|
11173
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
|
|
11265
|
+
var PLATFORM_COLORS, NOOP, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
|
|
11174
11266
|
var init_Canvas2D = __esm({
|
|
11175
11267
|
"components/game/2d/molecules/Canvas2D.tsx"() {
|
|
11176
11268
|
"use client";
|
|
@@ -11184,6 +11276,7 @@ var init_Canvas2D = __esm({
|
|
|
11184
11276
|
init_MiniMap();
|
|
11185
11277
|
init_HealthBar();
|
|
11186
11278
|
init_useImageCache();
|
|
11279
|
+
init_atlasSlice();
|
|
11187
11280
|
init_useCamera();
|
|
11188
11281
|
init_useCanvasGestures();
|
|
11189
11282
|
init_useRenderInterpolation();
|
|
@@ -11197,6 +11290,8 @@ var init_Canvas2D = __esm({
|
|
|
11197
11290
|
hazard: "#c0392b",
|
|
11198
11291
|
goal: "#f1c40f"
|
|
11199
11292
|
};
|
|
11293
|
+
NOOP = () => {
|
|
11294
|
+
};
|
|
11200
11295
|
PLAYER_COLOR = "#3498db";
|
|
11201
11296
|
PLAYER_EYE_COLOR = "#ffffff";
|
|
11202
11297
|
SKY_GRADIENT_TOP = "#1a1a2e";
|
|
@@ -16238,6 +16333,153 @@ var init_ComponentPatterns = __esm({
|
|
|
16238
16333
|
AlertPattern.displayName = "AlertPattern";
|
|
16239
16334
|
}
|
|
16240
16335
|
});
|
|
16336
|
+
var DEFAULT_BAR_COLOR, DEFAULT_CELL_COLOR, DEFAULT_POINTER_COLOR, POINTER_BAND, TOP_PAD, AlgorithmCanvas;
|
|
16337
|
+
var init_AlgorithmCanvas = __esm({
|
|
16338
|
+
"components/learning/molecules/AlgorithmCanvas.tsx"() {
|
|
16339
|
+
"use client";
|
|
16340
|
+
init_atoms();
|
|
16341
|
+
init_Stack();
|
|
16342
|
+
init_LearningCanvas();
|
|
16343
|
+
DEFAULT_BAR_COLOR = "#3b82f6";
|
|
16344
|
+
DEFAULT_CELL_COLOR = "#e5e7eb";
|
|
16345
|
+
DEFAULT_POINTER_COLOR = "#dc2626";
|
|
16346
|
+
POINTER_BAND = 34;
|
|
16347
|
+
TOP_PAD = 12;
|
|
16348
|
+
AlgorithmCanvas = ({
|
|
16349
|
+
className,
|
|
16350
|
+
width = 600,
|
|
16351
|
+
height = 400,
|
|
16352
|
+
title,
|
|
16353
|
+
backgroundColor,
|
|
16354
|
+
bars = [],
|
|
16355
|
+
cells = [],
|
|
16356
|
+
pointers = [],
|
|
16357
|
+
shapes = [],
|
|
16358
|
+
interactive = false,
|
|
16359
|
+
animate = false,
|
|
16360
|
+
onShapeClick,
|
|
16361
|
+
isLoading,
|
|
16362
|
+
error
|
|
16363
|
+
}) => {
|
|
16364
|
+
const derivedShapes = React97.useMemo(() => {
|
|
16365
|
+
const out = [];
|
|
16366
|
+
if (bars.length > 0) {
|
|
16367
|
+
const slot = width / bars.length;
|
|
16368
|
+
const barW = slot * 0.8;
|
|
16369
|
+
const gap = slot * 0.1;
|
|
16370
|
+
const baseline = height - POINTER_BAND;
|
|
16371
|
+
const usableH = baseline - TOP_PAD;
|
|
16372
|
+
const maxV = Math.max(1, ...bars.map((b) => Number.isFinite(b.value) ? b.value : 0));
|
|
16373
|
+
bars.forEach((bar, i) => {
|
|
16374
|
+
const v = Number.isFinite(bar.value) ? bar.value : 0;
|
|
16375
|
+
const bh = Math.max(0, v / maxV * usableH);
|
|
16376
|
+
const x = i * slot + gap;
|
|
16377
|
+
const color = bar.color ?? DEFAULT_BAR_COLOR;
|
|
16378
|
+
out.push({
|
|
16379
|
+
type: "rect",
|
|
16380
|
+
id: `bar-${i}`,
|
|
16381
|
+
x,
|
|
16382
|
+
y: baseline - bh,
|
|
16383
|
+
width: barW,
|
|
16384
|
+
height: bh,
|
|
16385
|
+
color,
|
|
16386
|
+
fill: color
|
|
16387
|
+
});
|
|
16388
|
+
const label = bar.label ?? (bars.length <= 24 ? String(v) : void 0);
|
|
16389
|
+
if (label) {
|
|
16390
|
+
out.push({
|
|
16391
|
+
type: "text",
|
|
16392
|
+
x: x + barW / 2,
|
|
16393
|
+
y: baseline - bh - 8,
|
|
16394
|
+
text: label,
|
|
16395
|
+
color: "#374151",
|
|
16396
|
+
fontSize: 11,
|
|
16397
|
+
align: "center"
|
|
16398
|
+
});
|
|
16399
|
+
}
|
|
16400
|
+
});
|
|
16401
|
+
pointers.forEach((p) => {
|
|
16402
|
+
if (p.index < 0 || p.index >= bars.length) return;
|
|
16403
|
+
const cx = p.index * slot + slot / 2;
|
|
16404
|
+
const color = p.color ?? DEFAULT_POINTER_COLOR;
|
|
16405
|
+
out.push({
|
|
16406
|
+
type: "arrow",
|
|
16407
|
+
x1: cx,
|
|
16408
|
+
y1: height - 6,
|
|
16409
|
+
x2: cx,
|
|
16410
|
+
y2: baseline + 4,
|
|
16411
|
+
color,
|
|
16412
|
+
lineWidth: 2
|
|
16413
|
+
});
|
|
16414
|
+
if (p.label) {
|
|
16415
|
+
out.push({
|
|
16416
|
+
type: "text",
|
|
16417
|
+
x: cx,
|
|
16418
|
+
y: height - 22,
|
|
16419
|
+
text: p.label,
|
|
16420
|
+
color,
|
|
16421
|
+
fontSize: 11,
|
|
16422
|
+
align: "center"
|
|
16423
|
+
});
|
|
16424
|
+
}
|
|
16425
|
+
});
|
|
16426
|
+
}
|
|
16427
|
+
if (cells.length > 0) {
|
|
16428
|
+
const maxCol = Math.max(0, ...cells.map((c) => c.col)) + 1;
|
|
16429
|
+
const maxRow = Math.max(0, ...cells.map((c) => c.row)) + 1;
|
|
16430
|
+
const cw = width / maxCol;
|
|
16431
|
+
const ch = height / maxRow;
|
|
16432
|
+
cells.forEach((c, i) => {
|
|
16433
|
+
const x = c.col * cw;
|
|
16434
|
+
const y = c.row * ch;
|
|
16435
|
+
const color = c.color ?? DEFAULT_CELL_COLOR;
|
|
16436
|
+
out.push({
|
|
16437
|
+
type: "rect",
|
|
16438
|
+
id: `cell-${i}`,
|
|
16439
|
+
x: x + 1,
|
|
16440
|
+
y: y + 1,
|
|
16441
|
+
width: cw - 2,
|
|
16442
|
+
height: ch - 2,
|
|
16443
|
+
color: "#9ca3af",
|
|
16444
|
+
fill: color
|
|
16445
|
+
});
|
|
16446
|
+
const label = c.label ?? (c.value != null ? String(c.value) : void 0);
|
|
16447
|
+
if (label && cw >= 18 && ch >= 14) {
|
|
16448
|
+
out.push({
|
|
16449
|
+
type: "text",
|
|
16450
|
+
x: x + cw / 2,
|
|
16451
|
+
y: y + ch / 2,
|
|
16452
|
+
text: label,
|
|
16453
|
+
color: "#111827",
|
|
16454
|
+
fontSize: 12,
|
|
16455
|
+
align: "center"
|
|
16456
|
+
});
|
|
16457
|
+
}
|
|
16458
|
+
});
|
|
16459
|
+
}
|
|
16460
|
+
out.push(...shapes);
|
|
16461
|
+
return out;
|
|
16462
|
+
}, [bars, cells, pointers, shapes, width, height]);
|
|
16463
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
|
|
16464
|
+
title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", children: title }) : null,
|
|
16465
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16466
|
+
LearningCanvas,
|
|
16467
|
+
{
|
|
16468
|
+
width,
|
|
16469
|
+
height,
|
|
16470
|
+
backgroundColor,
|
|
16471
|
+
shapes: derivedShapes,
|
|
16472
|
+
interactive,
|
|
16473
|
+
animate,
|
|
16474
|
+
onShapeClick,
|
|
16475
|
+
isLoading,
|
|
16476
|
+
error
|
|
16477
|
+
}
|
|
16478
|
+
)
|
|
16479
|
+
] }) });
|
|
16480
|
+
};
|
|
16481
|
+
}
|
|
16482
|
+
});
|
|
16241
16483
|
var AuthLayout;
|
|
16242
16484
|
var init_AuthLayout = __esm({
|
|
16243
16485
|
"components/marketing/templates/AuthLayout.tsx"() {
|
|
@@ -45910,6 +46152,7 @@ var init_component_registry_generated = __esm({
|
|
|
45910
46152
|
init_ActionTile();
|
|
45911
46153
|
init_ActivationBlock();
|
|
45912
46154
|
init_ComponentPatterns();
|
|
46155
|
+
init_AlgorithmCanvas();
|
|
45913
46156
|
init_AnimatedCounter();
|
|
45914
46157
|
init_AnimatedGraphic();
|
|
45915
46158
|
init_AnimatedReveal();
|
|
@@ -46208,6 +46451,7 @@ var init_component_registry_generated = __esm({
|
|
|
46208
46451
|
"ActivationBlock": ActivationBlock,
|
|
46209
46452
|
"Alert": AlertPattern,
|
|
46210
46453
|
"AlertPattern": AlertPattern,
|
|
46454
|
+
"AlgorithmCanvas": AlgorithmCanvas,
|
|
46211
46455
|
"AnimatedCounter": AnimatedCounter,
|
|
46212
46456
|
"AnimatedGraphic": AnimatedGraphic,
|
|
46213
46457
|
"AnimatedReveal": AnimatedReveal,
|