@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/components/index.js
CHANGED
|
@@ -8549,6 +8549,462 @@ var init_ComponentPatterns = __esm({
|
|
|
8549
8549
|
AlertPattern.displayName = "AlertPattern";
|
|
8550
8550
|
}
|
|
8551
8551
|
});
|
|
8552
|
+
function resolveColor2(color, ctx, fallback) {
|
|
8553
|
+
if (!color) return fallback;
|
|
8554
|
+
if (color.startsWith("var(")) {
|
|
8555
|
+
ctx.canvas.style;
|
|
8556
|
+
const m = /^var\((--[^,)]+)(?:,\s*([^)]+))?\)$/.exec(color);
|
|
8557
|
+
if (m) {
|
|
8558
|
+
const computed = getComputedStyle(ctx.canvas).getPropertyValue(m[1]).trim();
|
|
8559
|
+
return computed || m[2]?.trim() || fallback;
|
|
8560
|
+
}
|
|
8561
|
+
}
|
|
8562
|
+
return color;
|
|
8563
|
+
}
|
|
8564
|
+
function shapeBounds(shape) {
|
|
8565
|
+
switch (shape.type) {
|
|
8566
|
+
case "line":
|
|
8567
|
+
case "arrow":
|
|
8568
|
+
if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) return null;
|
|
8569
|
+
return {
|
|
8570
|
+
x: Math.min(shape.x1, shape.x2) - 6,
|
|
8571
|
+
y: Math.min(shape.y1, shape.y2) - 6,
|
|
8572
|
+
w: Math.abs(shape.x2 - shape.x1) + 12,
|
|
8573
|
+
h: Math.abs(shape.y2 - shape.y1) + 12
|
|
8574
|
+
};
|
|
8575
|
+
case "circle":
|
|
8576
|
+
if (shape.x == null || shape.y == null || shape.radius == null) return null;
|
|
8577
|
+
return {
|
|
8578
|
+
x: shape.x - shape.radius - 4,
|
|
8579
|
+
y: shape.y - shape.radius - 4,
|
|
8580
|
+
w: shape.radius * 2 + 8,
|
|
8581
|
+
h: shape.radius * 2 + 8
|
|
8582
|
+
};
|
|
8583
|
+
case "rect":
|
|
8584
|
+
if (shape.x == null || shape.y == null || shape.width == null || shape.height == null) return null;
|
|
8585
|
+
return { x: shape.x - 4, y: shape.y - 4, w: shape.width + 8, h: shape.height + 8 };
|
|
8586
|
+
case "polygon":
|
|
8587
|
+
if (!shape.points || shape.points.length === 0) return null;
|
|
8588
|
+
{
|
|
8589
|
+
const xs = shape.points.map((p) => p.x);
|
|
8590
|
+
const ys = shape.points.map((p) => p.y);
|
|
8591
|
+
const minX = Math.min(...xs);
|
|
8592
|
+
const minY = Math.min(...ys);
|
|
8593
|
+
return {
|
|
8594
|
+
x: minX - 4,
|
|
8595
|
+
y: minY - 4,
|
|
8596
|
+
w: Math.max(...xs) - minX + 8,
|
|
8597
|
+
h: Math.max(...ys) - minY + 8
|
|
8598
|
+
};
|
|
8599
|
+
}
|
|
8600
|
+
case "text":
|
|
8601
|
+
if (shape.x == null || shape.y == null) return null;
|
|
8602
|
+
return { x: shape.x - 4, y: shape.y - (shape.fontSize ?? 14) - 4, w: 120, h: (shape.fontSize ?? 14) + 8 };
|
|
8603
|
+
default:
|
|
8604
|
+
return null;
|
|
8605
|
+
}
|
|
8606
|
+
}
|
|
8607
|
+
function drawArrowHead(ctx, x1, y1, x2, y2, size) {
|
|
8608
|
+
const angle = Math.atan2(y2 - y1, x2 - x1);
|
|
8609
|
+
ctx.beginPath();
|
|
8610
|
+
ctx.moveTo(x2, y2);
|
|
8611
|
+
ctx.lineTo(x2 - size * Math.cos(angle - Math.PI / 6), y2 - size * Math.sin(angle - Math.PI / 6));
|
|
8612
|
+
ctx.lineTo(x2 - size * Math.cos(angle + Math.PI / 6), y2 - size * Math.sin(angle + Math.PI / 6));
|
|
8613
|
+
ctx.closePath();
|
|
8614
|
+
ctx.fill();
|
|
8615
|
+
}
|
|
8616
|
+
function drawShape(ctx, shape, width, height) {
|
|
8617
|
+
ctx.save();
|
|
8618
|
+
const opacity = shape.opacity ?? 1;
|
|
8619
|
+
ctx.globalAlpha = opacity;
|
|
8620
|
+
const stroke = resolveColor2(shape.color, ctx, "#333333");
|
|
8621
|
+
const fill = shape.fill ? resolveColor2(shape.fill, ctx, "#cccccc") : void 0;
|
|
8622
|
+
ctx.lineWidth = shape.lineWidth ?? 2;
|
|
8623
|
+
switch (shape.type) {
|
|
8624
|
+
case "grid": {
|
|
8625
|
+
const step = shape.step ?? 40;
|
|
8626
|
+
ctx.strokeStyle = stroke;
|
|
8627
|
+
ctx.globalAlpha = opacity * 0.25;
|
|
8628
|
+
ctx.lineWidth = 1;
|
|
8629
|
+
ctx.beginPath();
|
|
8630
|
+
for (let x = 0; x <= width; x += step) {
|
|
8631
|
+
ctx.moveTo(x, 0);
|
|
8632
|
+
ctx.lineTo(x, height);
|
|
8633
|
+
}
|
|
8634
|
+
for (let y = 0; y <= height; y += step) {
|
|
8635
|
+
ctx.moveTo(0, y);
|
|
8636
|
+
ctx.lineTo(width, y);
|
|
8637
|
+
}
|
|
8638
|
+
ctx.stroke();
|
|
8639
|
+
break;
|
|
8640
|
+
}
|
|
8641
|
+
case "axis": {
|
|
8642
|
+
const axis = shape.axis ?? "x";
|
|
8643
|
+
ctx.strokeStyle = stroke;
|
|
8644
|
+
ctx.lineWidth = shape.lineWidth ?? 2;
|
|
8645
|
+
ctx.beginPath();
|
|
8646
|
+
if (axis === "x") {
|
|
8647
|
+
ctx.moveTo(0, height / 2);
|
|
8648
|
+
ctx.lineTo(width, height / 2);
|
|
8649
|
+
} else {
|
|
8650
|
+
ctx.moveTo(width / 2, 0);
|
|
8651
|
+
ctx.lineTo(width / 2, height);
|
|
8652
|
+
}
|
|
8653
|
+
ctx.stroke();
|
|
8654
|
+
break;
|
|
8655
|
+
}
|
|
8656
|
+
case "line": {
|
|
8657
|
+
if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) break;
|
|
8658
|
+
ctx.strokeStyle = stroke;
|
|
8659
|
+
ctx.beginPath();
|
|
8660
|
+
ctx.moveTo(shape.x1, shape.y1);
|
|
8661
|
+
ctx.lineTo(shape.x2, shape.y2);
|
|
8662
|
+
ctx.stroke();
|
|
8663
|
+
break;
|
|
8664
|
+
}
|
|
8665
|
+
case "arrow": {
|
|
8666
|
+
if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) break;
|
|
8667
|
+
ctx.strokeStyle = stroke;
|
|
8668
|
+
ctx.fillStyle = stroke;
|
|
8669
|
+
ctx.beginPath();
|
|
8670
|
+
ctx.moveTo(shape.x1, shape.y1);
|
|
8671
|
+
ctx.lineTo(shape.x2, shape.y2);
|
|
8672
|
+
ctx.stroke();
|
|
8673
|
+
drawArrowHead(ctx, shape.x1, shape.y1, shape.x2, shape.y2, 10);
|
|
8674
|
+
break;
|
|
8675
|
+
}
|
|
8676
|
+
case "circle": {
|
|
8677
|
+
if (shape.x == null || shape.y == null || shape.radius == null) break;
|
|
8678
|
+
ctx.beginPath();
|
|
8679
|
+
ctx.arc(shape.x, shape.y, shape.radius, 0, Math.PI * 2);
|
|
8680
|
+
if (fill) {
|
|
8681
|
+
ctx.fillStyle = fill;
|
|
8682
|
+
ctx.fill();
|
|
8683
|
+
}
|
|
8684
|
+
ctx.strokeStyle = stroke;
|
|
8685
|
+
ctx.stroke();
|
|
8686
|
+
break;
|
|
8687
|
+
}
|
|
8688
|
+
case "rect": {
|
|
8689
|
+
if (shape.x == null || shape.y == null || shape.width == null || shape.height == null) break;
|
|
8690
|
+
if (fill) {
|
|
8691
|
+
ctx.fillStyle = fill;
|
|
8692
|
+
ctx.fillRect(shape.x, shape.y, shape.width, shape.height);
|
|
8693
|
+
}
|
|
8694
|
+
ctx.strokeStyle = stroke;
|
|
8695
|
+
ctx.strokeRect(shape.x, shape.y, shape.width, shape.height);
|
|
8696
|
+
break;
|
|
8697
|
+
}
|
|
8698
|
+
case "polygon": {
|
|
8699
|
+
if (!shape.points || shape.points.length < 2) break;
|
|
8700
|
+
ctx.beginPath();
|
|
8701
|
+
ctx.moveTo(shape.points[0].x, shape.points[0].y);
|
|
8702
|
+
for (let i = 1; i < shape.points.length; i++) {
|
|
8703
|
+
ctx.lineTo(shape.points[i].x, shape.points[i].y);
|
|
8704
|
+
}
|
|
8705
|
+
ctx.closePath();
|
|
8706
|
+
if (fill) {
|
|
8707
|
+
ctx.fillStyle = fill;
|
|
8708
|
+
ctx.fill();
|
|
8709
|
+
}
|
|
8710
|
+
ctx.strokeStyle = stroke;
|
|
8711
|
+
ctx.stroke();
|
|
8712
|
+
break;
|
|
8713
|
+
}
|
|
8714
|
+
case "path": {
|
|
8715
|
+
if (!shape.path) break;
|
|
8716
|
+
const p = new Path2D(shape.path);
|
|
8717
|
+
if (fill) {
|
|
8718
|
+
ctx.fillStyle = fill;
|
|
8719
|
+
ctx.fill(p);
|
|
8720
|
+
}
|
|
8721
|
+
ctx.strokeStyle = stroke;
|
|
8722
|
+
ctx.stroke(p);
|
|
8723
|
+
break;
|
|
8724
|
+
}
|
|
8725
|
+
case "text": {
|
|
8726
|
+
if (shape.x == null || shape.y == null || !shape.text) break;
|
|
8727
|
+
ctx.fillStyle = stroke;
|
|
8728
|
+
ctx.font = `${shape.fontSize ?? 14}px system-ui, sans-serif`;
|
|
8729
|
+
ctx.textAlign = shape.align ?? "left";
|
|
8730
|
+
ctx.textBaseline = "middle";
|
|
8731
|
+
ctx.fillText(shape.text, shape.x, shape.y);
|
|
8732
|
+
break;
|
|
8733
|
+
}
|
|
8734
|
+
}
|
|
8735
|
+
ctx.restore();
|
|
8736
|
+
}
|
|
8737
|
+
var LearningCanvas;
|
|
8738
|
+
var init_LearningCanvas = __esm({
|
|
8739
|
+
"components/learning/atoms/LearningCanvas.tsx"() {
|
|
8740
|
+
"use client";
|
|
8741
|
+
init_cn();
|
|
8742
|
+
init_useEventBus();
|
|
8743
|
+
LearningCanvas = ({
|
|
8744
|
+
className,
|
|
8745
|
+
width = 600,
|
|
8746
|
+
height = 400,
|
|
8747
|
+
backgroundColor,
|
|
8748
|
+
shapes = [],
|
|
8749
|
+
interactive = false,
|
|
8750
|
+
animate = false,
|
|
8751
|
+
onShapeClick,
|
|
8752
|
+
onShapeHover,
|
|
8753
|
+
isLoading,
|
|
8754
|
+
error
|
|
8755
|
+
}) => {
|
|
8756
|
+
const canvasRef = useRef(null);
|
|
8757
|
+
const eventBus = useEventBus();
|
|
8758
|
+
const animRef = useRef(0);
|
|
8759
|
+
const hoverIndexRef = useRef(-1);
|
|
8760
|
+
const findShapeAt = useCallback((clientX, clientY) => {
|
|
8761
|
+
const canvas = canvasRef.current;
|
|
8762
|
+
if (!canvas) return -1;
|
|
8763
|
+
const rect = canvas.getBoundingClientRect();
|
|
8764
|
+
const x = clientX - rect.left;
|
|
8765
|
+
const y = clientY - rect.top;
|
|
8766
|
+
for (let i = shapes.length - 1; i >= 0; i--) {
|
|
8767
|
+
const b = shapeBounds(shapes[i]);
|
|
8768
|
+
if (b && x >= b.x && x <= b.x + b.w && y >= b.y && y <= b.y + b.h) {
|
|
8769
|
+
return i;
|
|
8770
|
+
}
|
|
8771
|
+
}
|
|
8772
|
+
return -1;
|
|
8773
|
+
}, [shapes]);
|
|
8774
|
+
const draw = useCallback(() => {
|
|
8775
|
+
const canvas = canvasRef.current;
|
|
8776
|
+
if (!canvas) return;
|
|
8777
|
+
const ctx = canvas.getContext("2d");
|
|
8778
|
+
if (!ctx) return;
|
|
8779
|
+
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
8780
|
+
canvas.width = Math.max(1, Math.floor(width * dpr));
|
|
8781
|
+
canvas.height = Math.max(1, Math.floor(height * dpr));
|
|
8782
|
+
canvas.style.width = `${width}px`;
|
|
8783
|
+
canvas.style.height = `${height}px`;
|
|
8784
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
8785
|
+
ctx.clearRect(0, 0, width, height);
|
|
8786
|
+
if (backgroundColor) {
|
|
8787
|
+
ctx.fillStyle = backgroundColor;
|
|
8788
|
+
ctx.fillRect(0, 0, width, height);
|
|
8789
|
+
}
|
|
8790
|
+
for (const shape of shapes) {
|
|
8791
|
+
drawShape(ctx, shape, width, height);
|
|
8792
|
+
}
|
|
8793
|
+
}, [width, height, backgroundColor, shapes]);
|
|
8794
|
+
useEffect(() => {
|
|
8795
|
+
draw();
|
|
8796
|
+
}, [draw]);
|
|
8797
|
+
useEffect(() => {
|
|
8798
|
+
if (!animate) return;
|
|
8799
|
+
const loop = () => {
|
|
8800
|
+
draw();
|
|
8801
|
+
animRef.current = requestAnimationFrame(loop);
|
|
8802
|
+
};
|
|
8803
|
+
animRef.current = requestAnimationFrame(loop);
|
|
8804
|
+
return () => cancelAnimationFrame(animRef.current);
|
|
8805
|
+
}, [animate, draw]);
|
|
8806
|
+
const handlePointerMove = useCallback(
|
|
8807
|
+
(e) => {
|
|
8808
|
+
if (!interactive) return;
|
|
8809
|
+
const idx = findShapeAt(e.clientX, e.clientY);
|
|
8810
|
+
if (idx !== hoverIndexRef.current) {
|
|
8811
|
+
hoverIndexRef.current = idx;
|
|
8812
|
+
if (idx >= 0) {
|
|
8813
|
+
const shape = shapes[idx];
|
|
8814
|
+
const payload = { id: shape.id, type: shape.type, index: idx };
|
|
8815
|
+
if (onShapeHover) onShapeHover(payload);
|
|
8816
|
+
else if (eventBus) eventBus.emit(`UI:SHAPE_HOVER`, payload);
|
|
8817
|
+
}
|
|
8818
|
+
}
|
|
8819
|
+
},
|
|
8820
|
+
[interactive, onShapeHover, eventBus, findShapeAt, shapes]
|
|
8821
|
+
);
|
|
8822
|
+
const handleClick = useCallback(
|
|
8823
|
+
(e) => {
|
|
8824
|
+
if (!interactive) return;
|
|
8825
|
+
const idx = findShapeAt(e.clientX, e.clientY);
|
|
8826
|
+
if (idx >= 0) {
|
|
8827
|
+
const shape = shapes[idx];
|
|
8828
|
+
const payload = { id: shape.id, type: shape.type, index: idx };
|
|
8829
|
+
if (onShapeClick) onShapeClick(payload);
|
|
8830
|
+
else if (eventBus) eventBus.emit(`UI:SHAPE_CLICK`, payload);
|
|
8831
|
+
}
|
|
8832
|
+
},
|
|
8833
|
+
[interactive, onShapeClick, eventBus, findShapeAt, shapes]
|
|
8834
|
+
);
|
|
8835
|
+
if (isLoading || error) {
|
|
8836
|
+
return /* @__PURE__ */ jsx(
|
|
8837
|
+
"div",
|
|
8838
|
+
{
|
|
8839
|
+
className: cn(
|
|
8840
|
+
"flex items-center justify-center rounded border border-border bg-surface",
|
|
8841
|
+
className
|
|
8842
|
+
),
|
|
8843
|
+
style: { width, height },
|
|
8844
|
+
children: error ? /* @__PURE__ */ jsx("span", { className: "text-sm text-destructive", children: error.message }) : /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Loading canvas\u2026" })
|
|
8845
|
+
}
|
|
8846
|
+
);
|
|
8847
|
+
}
|
|
8848
|
+
return /* @__PURE__ */ jsx(
|
|
8849
|
+
"canvas",
|
|
8850
|
+
{
|
|
8851
|
+
ref: canvasRef,
|
|
8852
|
+
className: cn("block touch-none rounded border border-border", className),
|
|
8853
|
+
style: { width, height },
|
|
8854
|
+
onClick: handleClick,
|
|
8855
|
+
onPointerMove: handlePointerMove
|
|
8856
|
+
}
|
|
8857
|
+
);
|
|
8858
|
+
};
|
|
8859
|
+
}
|
|
8860
|
+
});
|
|
8861
|
+
var DEFAULT_BAR_COLOR, DEFAULT_CELL_COLOR, DEFAULT_POINTER_COLOR, POINTER_BAND, TOP_PAD, AlgorithmCanvas;
|
|
8862
|
+
var init_AlgorithmCanvas = __esm({
|
|
8863
|
+
"components/learning/molecules/AlgorithmCanvas.tsx"() {
|
|
8864
|
+
"use client";
|
|
8865
|
+
init_atoms();
|
|
8866
|
+
init_Stack();
|
|
8867
|
+
init_LearningCanvas();
|
|
8868
|
+
DEFAULT_BAR_COLOR = "#3b82f6";
|
|
8869
|
+
DEFAULT_CELL_COLOR = "#e5e7eb";
|
|
8870
|
+
DEFAULT_POINTER_COLOR = "#dc2626";
|
|
8871
|
+
POINTER_BAND = 34;
|
|
8872
|
+
TOP_PAD = 12;
|
|
8873
|
+
AlgorithmCanvas = ({
|
|
8874
|
+
className,
|
|
8875
|
+
width = 600,
|
|
8876
|
+
height = 400,
|
|
8877
|
+
title,
|
|
8878
|
+
backgroundColor,
|
|
8879
|
+
bars = [],
|
|
8880
|
+
cells = [],
|
|
8881
|
+
pointers = [],
|
|
8882
|
+
shapes = [],
|
|
8883
|
+
interactive = false,
|
|
8884
|
+
animate = false,
|
|
8885
|
+
onShapeClick,
|
|
8886
|
+
isLoading,
|
|
8887
|
+
error
|
|
8888
|
+
}) => {
|
|
8889
|
+
const derivedShapes = useMemo(() => {
|
|
8890
|
+
const out = [];
|
|
8891
|
+
if (bars.length > 0) {
|
|
8892
|
+
const slot = width / bars.length;
|
|
8893
|
+
const barW = slot * 0.8;
|
|
8894
|
+
const gap = slot * 0.1;
|
|
8895
|
+
const baseline = height - POINTER_BAND;
|
|
8896
|
+
const usableH = baseline - TOP_PAD;
|
|
8897
|
+
const maxV = Math.max(1, ...bars.map((b) => Number.isFinite(b.value) ? b.value : 0));
|
|
8898
|
+
bars.forEach((bar, i) => {
|
|
8899
|
+
const v = Number.isFinite(bar.value) ? bar.value : 0;
|
|
8900
|
+
const bh = Math.max(0, v / maxV * usableH);
|
|
8901
|
+
const x = i * slot + gap;
|
|
8902
|
+
const color = bar.color ?? DEFAULT_BAR_COLOR;
|
|
8903
|
+
out.push({
|
|
8904
|
+
type: "rect",
|
|
8905
|
+
id: `bar-${i}`,
|
|
8906
|
+
x,
|
|
8907
|
+
y: baseline - bh,
|
|
8908
|
+
width: barW,
|
|
8909
|
+
height: bh,
|
|
8910
|
+
color,
|
|
8911
|
+
fill: color
|
|
8912
|
+
});
|
|
8913
|
+
const label = bar.label ?? (bars.length <= 24 ? String(v) : void 0);
|
|
8914
|
+
if (label) {
|
|
8915
|
+
out.push({
|
|
8916
|
+
type: "text",
|
|
8917
|
+
x: x + barW / 2,
|
|
8918
|
+
y: baseline - bh - 8,
|
|
8919
|
+
text: label,
|
|
8920
|
+
color: "#374151",
|
|
8921
|
+
fontSize: 11,
|
|
8922
|
+
align: "center"
|
|
8923
|
+
});
|
|
8924
|
+
}
|
|
8925
|
+
});
|
|
8926
|
+
pointers.forEach((p) => {
|
|
8927
|
+
if (p.index < 0 || p.index >= bars.length) return;
|
|
8928
|
+
const cx = p.index * slot + slot / 2;
|
|
8929
|
+
const color = p.color ?? DEFAULT_POINTER_COLOR;
|
|
8930
|
+
out.push({
|
|
8931
|
+
type: "arrow",
|
|
8932
|
+
x1: cx,
|
|
8933
|
+
y1: height - 6,
|
|
8934
|
+
x2: cx,
|
|
8935
|
+
y2: baseline + 4,
|
|
8936
|
+
color,
|
|
8937
|
+
lineWidth: 2
|
|
8938
|
+
});
|
|
8939
|
+
if (p.label) {
|
|
8940
|
+
out.push({
|
|
8941
|
+
type: "text",
|
|
8942
|
+
x: cx,
|
|
8943
|
+
y: height - 22,
|
|
8944
|
+
text: p.label,
|
|
8945
|
+
color,
|
|
8946
|
+
fontSize: 11,
|
|
8947
|
+
align: "center"
|
|
8948
|
+
});
|
|
8949
|
+
}
|
|
8950
|
+
});
|
|
8951
|
+
}
|
|
8952
|
+
if (cells.length > 0) {
|
|
8953
|
+
const maxCol = Math.max(0, ...cells.map((c) => c.col)) + 1;
|
|
8954
|
+
const maxRow = Math.max(0, ...cells.map((c) => c.row)) + 1;
|
|
8955
|
+
const cw = width / maxCol;
|
|
8956
|
+
const ch = height / maxRow;
|
|
8957
|
+
cells.forEach((c, i) => {
|
|
8958
|
+
const x = c.col * cw;
|
|
8959
|
+
const y = c.row * ch;
|
|
8960
|
+
const color = c.color ?? DEFAULT_CELL_COLOR;
|
|
8961
|
+
out.push({
|
|
8962
|
+
type: "rect",
|
|
8963
|
+
id: `cell-${i}`,
|
|
8964
|
+
x: x + 1,
|
|
8965
|
+
y: y + 1,
|
|
8966
|
+
width: cw - 2,
|
|
8967
|
+
height: ch - 2,
|
|
8968
|
+
color: "#9ca3af",
|
|
8969
|
+
fill: color
|
|
8970
|
+
});
|
|
8971
|
+
const label = c.label ?? (c.value != null ? String(c.value) : void 0);
|
|
8972
|
+
if (label && cw >= 18 && ch >= 14) {
|
|
8973
|
+
out.push({
|
|
8974
|
+
type: "text",
|
|
8975
|
+
x: x + cw / 2,
|
|
8976
|
+
y: y + ch / 2,
|
|
8977
|
+
text: label,
|
|
8978
|
+
color: "#111827",
|
|
8979
|
+
fontSize: 12,
|
|
8980
|
+
align: "center"
|
|
8981
|
+
});
|
|
8982
|
+
}
|
|
8983
|
+
});
|
|
8984
|
+
}
|
|
8985
|
+
out.push(...shapes);
|
|
8986
|
+
return out;
|
|
8987
|
+
}, [bars, cells, pointers, shapes, width, height]);
|
|
8988
|
+
return /* @__PURE__ */ jsx(Card, { className, children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
|
|
8989
|
+
title ? /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title }) : null,
|
|
8990
|
+
/* @__PURE__ */ jsx(
|
|
8991
|
+
LearningCanvas,
|
|
8992
|
+
{
|
|
8993
|
+
width,
|
|
8994
|
+
height,
|
|
8995
|
+
backgroundColor,
|
|
8996
|
+
shapes: derivedShapes,
|
|
8997
|
+
interactive,
|
|
8998
|
+
animate,
|
|
8999
|
+
onShapeClick,
|
|
9000
|
+
isLoading,
|
|
9001
|
+
error
|
|
9002
|
+
}
|
|
9003
|
+
)
|
|
9004
|
+
] }) });
|
|
9005
|
+
};
|
|
9006
|
+
}
|
|
9007
|
+
});
|
|
8552
9008
|
var AuthLayout;
|
|
8553
9009
|
var init_AuthLayout = __esm({
|
|
8554
9010
|
"components/marketing/templates/AuthLayout.tsx"() {
|
|
@@ -9517,315 +9973,6 @@ var init_BehaviorView = __esm({
|
|
|
9517
9973
|
BehaviorView.displayName = "BehaviorView";
|
|
9518
9974
|
}
|
|
9519
9975
|
});
|
|
9520
|
-
function resolveColor2(color, ctx, fallback) {
|
|
9521
|
-
if (!color) return fallback;
|
|
9522
|
-
if (color.startsWith("var(")) {
|
|
9523
|
-
ctx.canvas.style;
|
|
9524
|
-
const m = /^var\((--[^,)]+)(?:,\s*([^)]+))?\)$/.exec(color);
|
|
9525
|
-
if (m) {
|
|
9526
|
-
const computed = getComputedStyle(ctx.canvas).getPropertyValue(m[1]).trim();
|
|
9527
|
-
return computed || m[2]?.trim() || fallback;
|
|
9528
|
-
}
|
|
9529
|
-
}
|
|
9530
|
-
return color;
|
|
9531
|
-
}
|
|
9532
|
-
function shapeBounds(shape) {
|
|
9533
|
-
switch (shape.type) {
|
|
9534
|
-
case "line":
|
|
9535
|
-
case "arrow":
|
|
9536
|
-
if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) return null;
|
|
9537
|
-
return {
|
|
9538
|
-
x: Math.min(shape.x1, shape.x2) - 6,
|
|
9539
|
-
y: Math.min(shape.y1, shape.y2) - 6,
|
|
9540
|
-
w: Math.abs(shape.x2 - shape.x1) + 12,
|
|
9541
|
-
h: Math.abs(shape.y2 - shape.y1) + 12
|
|
9542
|
-
};
|
|
9543
|
-
case "circle":
|
|
9544
|
-
if (shape.x == null || shape.y == null || shape.radius == null) return null;
|
|
9545
|
-
return {
|
|
9546
|
-
x: shape.x - shape.radius - 4,
|
|
9547
|
-
y: shape.y - shape.radius - 4,
|
|
9548
|
-
w: shape.radius * 2 + 8,
|
|
9549
|
-
h: shape.radius * 2 + 8
|
|
9550
|
-
};
|
|
9551
|
-
case "rect":
|
|
9552
|
-
if (shape.x == null || shape.y == null || shape.width == null || shape.height == null) return null;
|
|
9553
|
-
return { x: shape.x - 4, y: shape.y - 4, w: shape.width + 8, h: shape.height + 8 };
|
|
9554
|
-
case "polygon":
|
|
9555
|
-
if (!shape.points || shape.points.length === 0) return null;
|
|
9556
|
-
{
|
|
9557
|
-
const xs = shape.points.map((p) => p.x);
|
|
9558
|
-
const ys = shape.points.map((p) => p.y);
|
|
9559
|
-
const minX = Math.min(...xs);
|
|
9560
|
-
const minY = Math.min(...ys);
|
|
9561
|
-
return {
|
|
9562
|
-
x: minX - 4,
|
|
9563
|
-
y: minY - 4,
|
|
9564
|
-
w: Math.max(...xs) - minX + 8,
|
|
9565
|
-
h: Math.max(...ys) - minY + 8
|
|
9566
|
-
};
|
|
9567
|
-
}
|
|
9568
|
-
case "text":
|
|
9569
|
-
if (shape.x == null || shape.y == null) return null;
|
|
9570
|
-
return { x: shape.x - 4, y: shape.y - (shape.fontSize ?? 14) - 4, w: 120, h: (shape.fontSize ?? 14) + 8 };
|
|
9571
|
-
default:
|
|
9572
|
-
return null;
|
|
9573
|
-
}
|
|
9574
|
-
}
|
|
9575
|
-
function drawArrowHead(ctx, x1, y1, x2, y2, size) {
|
|
9576
|
-
const angle = Math.atan2(y2 - y1, x2 - x1);
|
|
9577
|
-
ctx.beginPath();
|
|
9578
|
-
ctx.moveTo(x2, y2);
|
|
9579
|
-
ctx.lineTo(x2 - size * Math.cos(angle - Math.PI / 6), y2 - size * Math.sin(angle - Math.PI / 6));
|
|
9580
|
-
ctx.lineTo(x2 - size * Math.cos(angle + Math.PI / 6), y2 - size * Math.sin(angle + Math.PI / 6));
|
|
9581
|
-
ctx.closePath();
|
|
9582
|
-
ctx.fill();
|
|
9583
|
-
}
|
|
9584
|
-
function drawShape(ctx, shape, width, height) {
|
|
9585
|
-
ctx.save();
|
|
9586
|
-
const opacity = shape.opacity ?? 1;
|
|
9587
|
-
ctx.globalAlpha = opacity;
|
|
9588
|
-
const stroke = resolveColor2(shape.color, ctx, "#333333");
|
|
9589
|
-
const fill = shape.fill ? resolveColor2(shape.fill, ctx, "#cccccc") : void 0;
|
|
9590
|
-
ctx.lineWidth = shape.lineWidth ?? 2;
|
|
9591
|
-
switch (shape.type) {
|
|
9592
|
-
case "grid": {
|
|
9593
|
-
const step = shape.step ?? 40;
|
|
9594
|
-
ctx.strokeStyle = stroke;
|
|
9595
|
-
ctx.globalAlpha = opacity * 0.25;
|
|
9596
|
-
ctx.lineWidth = 1;
|
|
9597
|
-
ctx.beginPath();
|
|
9598
|
-
for (let x = 0; x <= width; x += step) {
|
|
9599
|
-
ctx.moveTo(x, 0);
|
|
9600
|
-
ctx.lineTo(x, height);
|
|
9601
|
-
}
|
|
9602
|
-
for (let y = 0; y <= height; y += step) {
|
|
9603
|
-
ctx.moveTo(0, y);
|
|
9604
|
-
ctx.lineTo(width, y);
|
|
9605
|
-
}
|
|
9606
|
-
ctx.stroke();
|
|
9607
|
-
break;
|
|
9608
|
-
}
|
|
9609
|
-
case "axis": {
|
|
9610
|
-
const axis = shape.axis ?? "x";
|
|
9611
|
-
ctx.strokeStyle = stroke;
|
|
9612
|
-
ctx.lineWidth = shape.lineWidth ?? 2;
|
|
9613
|
-
ctx.beginPath();
|
|
9614
|
-
if (axis === "x") {
|
|
9615
|
-
ctx.moveTo(0, height / 2);
|
|
9616
|
-
ctx.lineTo(width, height / 2);
|
|
9617
|
-
} else {
|
|
9618
|
-
ctx.moveTo(width / 2, 0);
|
|
9619
|
-
ctx.lineTo(width / 2, height);
|
|
9620
|
-
}
|
|
9621
|
-
ctx.stroke();
|
|
9622
|
-
break;
|
|
9623
|
-
}
|
|
9624
|
-
case "line": {
|
|
9625
|
-
if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) break;
|
|
9626
|
-
ctx.strokeStyle = stroke;
|
|
9627
|
-
ctx.beginPath();
|
|
9628
|
-
ctx.moveTo(shape.x1, shape.y1);
|
|
9629
|
-
ctx.lineTo(shape.x2, shape.y2);
|
|
9630
|
-
ctx.stroke();
|
|
9631
|
-
break;
|
|
9632
|
-
}
|
|
9633
|
-
case "arrow": {
|
|
9634
|
-
if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) break;
|
|
9635
|
-
ctx.strokeStyle = stroke;
|
|
9636
|
-
ctx.fillStyle = stroke;
|
|
9637
|
-
ctx.beginPath();
|
|
9638
|
-
ctx.moveTo(shape.x1, shape.y1);
|
|
9639
|
-
ctx.lineTo(shape.x2, shape.y2);
|
|
9640
|
-
ctx.stroke();
|
|
9641
|
-
drawArrowHead(ctx, shape.x1, shape.y1, shape.x2, shape.y2, 10);
|
|
9642
|
-
break;
|
|
9643
|
-
}
|
|
9644
|
-
case "circle": {
|
|
9645
|
-
if (shape.x == null || shape.y == null || shape.radius == null) break;
|
|
9646
|
-
ctx.beginPath();
|
|
9647
|
-
ctx.arc(shape.x, shape.y, shape.radius, 0, Math.PI * 2);
|
|
9648
|
-
if (fill) {
|
|
9649
|
-
ctx.fillStyle = fill;
|
|
9650
|
-
ctx.fill();
|
|
9651
|
-
}
|
|
9652
|
-
ctx.strokeStyle = stroke;
|
|
9653
|
-
ctx.stroke();
|
|
9654
|
-
break;
|
|
9655
|
-
}
|
|
9656
|
-
case "rect": {
|
|
9657
|
-
if (shape.x == null || shape.y == null || shape.width == null || shape.height == null) break;
|
|
9658
|
-
if (fill) {
|
|
9659
|
-
ctx.fillStyle = fill;
|
|
9660
|
-
ctx.fillRect(shape.x, shape.y, shape.width, shape.height);
|
|
9661
|
-
}
|
|
9662
|
-
ctx.strokeStyle = stroke;
|
|
9663
|
-
ctx.strokeRect(shape.x, shape.y, shape.width, shape.height);
|
|
9664
|
-
break;
|
|
9665
|
-
}
|
|
9666
|
-
case "polygon": {
|
|
9667
|
-
if (!shape.points || shape.points.length < 2) break;
|
|
9668
|
-
ctx.beginPath();
|
|
9669
|
-
ctx.moveTo(shape.points[0].x, shape.points[0].y);
|
|
9670
|
-
for (let i = 1; i < shape.points.length; i++) {
|
|
9671
|
-
ctx.lineTo(shape.points[i].x, shape.points[i].y);
|
|
9672
|
-
}
|
|
9673
|
-
ctx.closePath();
|
|
9674
|
-
if (fill) {
|
|
9675
|
-
ctx.fillStyle = fill;
|
|
9676
|
-
ctx.fill();
|
|
9677
|
-
}
|
|
9678
|
-
ctx.strokeStyle = stroke;
|
|
9679
|
-
ctx.stroke();
|
|
9680
|
-
break;
|
|
9681
|
-
}
|
|
9682
|
-
case "path": {
|
|
9683
|
-
if (!shape.path) break;
|
|
9684
|
-
const p = new Path2D(shape.path);
|
|
9685
|
-
if (fill) {
|
|
9686
|
-
ctx.fillStyle = fill;
|
|
9687
|
-
ctx.fill(p);
|
|
9688
|
-
}
|
|
9689
|
-
ctx.strokeStyle = stroke;
|
|
9690
|
-
ctx.stroke(p);
|
|
9691
|
-
break;
|
|
9692
|
-
}
|
|
9693
|
-
case "text": {
|
|
9694
|
-
if (shape.x == null || shape.y == null || !shape.text) break;
|
|
9695
|
-
ctx.fillStyle = stroke;
|
|
9696
|
-
ctx.font = `${shape.fontSize ?? 14}px system-ui, sans-serif`;
|
|
9697
|
-
ctx.textAlign = shape.align ?? "left";
|
|
9698
|
-
ctx.textBaseline = "middle";
|
|
9699
|
-
ctx.fillText(shape.text, shape.x, shape.y);
|
|
9700
|
-
break;
|
|
9701
|
-
}
|
|
9702
|
-
}
|
|
9703
|
-
ctx.restore();
|
|
9704
|
-
}
|
|
9705
|
-
var LearningCanvas;
|
|
9706
|
-
var init_LearningCanvas = __esm({
|
|
9707
|
-
"components/learning/atoms/LearningCanvas.tsx"() {
|
|
9708
|
-
"use client";
|
|
9709
|
-
init_cn();
|
|
9710
|
-
init_useEventBus();
|
|
9711
|
-
LearningCanvas = ({
|
|
9712
|
-
className,
|
|
9713
|
-
width = 600,
|
|
9714
|
-
height = 400,
|
|
9715
|
-
backgroundColor,
|
|
9716
|
-
shapes = [],
|
|
9717
|
-
interactive = false,
|
|
9718
|
-
animate = false,
|
|
9719
|
-
onShapeClick,
|
|
9720
|
-
onShapeHover,
|
|
9721
|
-
isLoading,
|
|
9722
|
-
error
|
|
9723
|
-
}) => {
|
|
9724
|
-
const canvasRef = useRef(null);
|
|
9725
|
-
const eventBus = useEventBus();
|
|
9726
|
-
const animRef = useRef(0);
|
|
9727
|
-
const hoverIndexRef = useRef(-1);
|
|
9728
|
-
const findShapeAt = useCallback((clientX, clientY) => {
|
|
9729
|
-
const canvas = canvasRef.current;
|
|
9730
|
-
if (!canvas) return -1;
|
|
9731
|
-
const rect = canvas.getBoundingClientRect();
|
|
9732
|
-
const x = clientX - rect.left;
|
|
9733
|
-
const y = clientY - rect.top;
|
|
9734
|
-
for (let i = shapes.length - 1; i >= 0; i--) {
|
|
9735
|
-
const b = shapeBounds(shapes[i]);
|
|
9736
|
-
if (b && x >= b.x && x <= b.x + b.w && y >= b.y && y <= b.y + b.h) {
|
|
9737
|
-
return i;
|
|
9738
|
-
}
|
|
9739
|
-
}
|
|
9740
|
-
return -1;
|
|
9741
|
-
}, [shapes]);
|
|
9742
|
-
const draw = useCallback(() => {
|
|
9743
|
-
const canvas = canvasRef.current;
|
|
9744
|
-
if (!canvas) return;
|
|
9745
|
-
const ctx = canvas.getContext("2d");
|
|
9746
|
-
if (!ctx) return;
|
|
9747
|
-
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
9748
|
-
canvas.width = Math.max(1, Math.floor(width * dpr));
|
|
9749
|
-
canvas.height = Math.max(1, Math.floor(height * dpr));
|
|
9750
|
-
canvas.style.width = `${width}px`;
|
|
9751
|
-
canvas.style.height = `${height}px`;
|
|
9752
|
-
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
9753
|
-
ctx.clearRect(0, 0, width, height);
|
|
9754
|
-
if (backgroundColor) {
|
|
9755
|
-
ctx.fillStyle = backgroundColor;
|
|
9756
|
-
ctx.fillRect(0, 0, width, height);
|
|
9757
|
-
}
|
|
9758
|
-
for (const shape of shapes) {
|
|
9759
|
-
drawShape(ctx, shape, width, height);
|
|
9760
|
-
}
|
|
9761
|
-
}, [width, height, backgroundColor, shapes]);
|
|
9762
|
-
useEffect(() => {
|
|
9763
|
-
draw();
|
|
9764
|
-
}, [draw]);
|
|
9765
|
-
useEffect(() => {
|
|
9766
|
-
if (!animate) return;
|
|
9767
|
-
const loop = () => {
|
|
9768
|
-
draw();
|
|
9769
|
-
animRef.current = requestAnimationFrame(loop);
|
|
9770
|
-
};
|
|
9771
|
-
animRef.current = requestAnimationFrame(loop);
|
|
9772
|
-
return () => cancelAnimationFrame(animRef.current);
|
|
9773
|
-
}, [animate, draw]);
|
|
9774
|
-
const handlePointerMove = useCallback(
|
|
9775
|
-
(e) => {
|
|
9776
|
-
if (!interactive) return;
|
|
9777
|
-
const idx = findShapeAt(e.clientX, e.clientY);
|
|
9778
|
-
if (idx !== hoverIndexRef.current) {
|
|
9779
|
-
hoverIndexRef.current = idx;
|
|
9780
|
-
if (idx >= 0) {
|
|
9781
|
-
const shape = shapes[idx];
|
|
9782
|
-
const payload = { id: shape.id, type: shape.type, index: idx };
|
|
9783
|
-
if (onShapeHover) onShapeHover(payload);
|
|
9784
|
-
else if (eventBus) eventBus.emit(`UI:SHAPE_HOVER`, payload);
|
|
9785
|
-
}
|
|
9786
|
-
}
|
|
9787
|
-
},
|
|
9788
|
-
[interactive, onShapeHover, eventBus, findShapeAt, shapes]
|
|
9789
|
-
);
|
|
9790
|
-
const handleClick = useCallback(
|
|
9791
|
-
(e) => {
|
|
9792
|
-
if (!interactive) return;
|
|
9793
|
-
const idx = findShapeAt(e.clientX, e.clientY);
|
|
9794
|
-
if (idx >= 0) {
|
|
9795
|
-
const shape = shapes[idx];
|
|
9796
|
-
const payload = { id: shape.id, type: shape.type, index: idx };
|
|
9797
|
-
if (onShapeClick) onShapeClick(payload);
|
|
9798
|
-
else if (eventBus) eventBus.emit(`UI:SHAPE_CLICK`, payload);
|
|
9799
|
-
}
|
|
9800
|
-
},
|
|
9801
|
-
[interactive, onShapeClick, eventBus, findShapeAt, shapes]
|
|
9802
|
-
);
|
|
9803
|
-
if (isLoading || error) {
|
|
9804
|
-
return /* @__PURE__ */ jsx(
|
|
9805
|
-
"div",
|
|
9806
|
-
{
|
|
9807
|
-
className: cn(
|
|
9808
|
-
"flex items-center justify-center rounded border border-border bg-surface",
|
|
9809
|
-
className
|
|
9810
|
-
),
|
|
9811
|
-
style: { width, height },
|
|
9812
|
-
children: error ? /* @__PURE__ */ jsx("span", { className: "text-sm text-destructive", children: error.message }) : /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Loading canvas\u2026" })
|
|
9813
|
-
}
|
|
9814
|
-
);
|
|
9815
|
-
}
|
|
9816
|
-
return /* @__PURE__ */ jsx(
|
|
9817
|
-
"canvas",
|
|
9818
|
-
{
|
|
9819
|
-
ref: canvasRef,
|
|
9820
|
-
className: cn("block touch-none rounded border border-border", className),
|
|
9821
|
-
style: { width, height },
|
|
9822
|
-
onClick: handleClick,
|
|
9823
|
-
onPointerMove: handlePointerMove
|
|
9824
|
-
}
|
|
9825
|
-
);
|
|
9826
|
-
};
|
|
9827
|
-
}
|
|
9828
|
-
});
|
|
9829
9976
|
var BiologyCanvas;
|
|
9830
9977
|
var init_BiologyCanvas = __esm({
|
|
9831
9978
|
"components/learning/molecules/BiologyCanvas.tsx"() {
|
|
@@ -15411,6 +15558,76 @@ var init_useImageCache = __esm({
|
|
|
15411
15558
|
init_verificationRegistry();
|
|
15412
15559
|
}
|
|
15413
15560
|
});
|
|
15561
|
+
|
|
15562
|
+
// components/game/shared/atlasSlice.ts
|
|
15563
|
+
function isTilesheet(a) {
|
|
15564
|
+
return typeof a.tileWidth === "number";
|
|
15565
|
+
}
|
|
15566
|
+
function getAtlas(url, onReady) {
|
|
15567
|
+
if (atlasCache.has(url)) return atlasCache.get(url) ?? void 0;
|
|
15568
|
+
atlasCache.set(url, void 0);
|
|
15569
|
+
fetch(url).then((r) => r.json()).then((json) => {
|
|
15570
|
+
atlasCache.set(url, json);
|
|
15571
|
+
onReady();
|
|
15572
|
+
}).catch(() => {
|
|
15573
|
+
atlasCache.set(url, null);
|
|
15574
|
+
});
|
|
15575
|
+
return void 0;
|
|
15576
|
+
}
|
|
15577
|
+
function subRectFor(atlas, sprite) {
|
|
15578
|
+
if (isTilesheet(atlas)) {
|
|
15579
|
+
let col;
|
|
15580
|
+
let row;
|
|
15581
|
+
if (sprite.includes(",")) {
|
|
15582
|
+
const [c, r] = sprite.split(",").map((n) => Number(n.trim()));
|
|
15583
|
+
col = c;
|
|
15584
|
+
row = r;
|
|
15585
|
+
} else {
|
|
15586
|
+
const i = Number(sprite);
|
|
15587
|
+
if (!Number.isFinite(i)) return null;
|
|
15588
|
+
col = i % atlas.columns;
|
|
15589
|
+
row = Math.floor(i / atlas.columns);
|
|
15590
|
+
}
|
|
15591
|
+
if (!Number.isFinite(col) || !Number.isFinite(row) || col < 0 || row < 0 || col >= atlas.columns || row >= atlas.rows) return null;
|
|
15592
|
+
const margin = atlas.margin ?? 0;
|
|
15593
|
+
const spacing = atlas.spacing ?? 0;
|
|
15594
|
+
return {
|
|
15595
|
+
sx: margin + col * (atlas.tileWidth + spacing),
|
|
15596
|
+
sy: margin + row * (atlas.tileHeight + spacing),
|
|
15597
|
+
sw: atlas.tileWidth,
|
|
15598
|
+
sh: atlas.tileHeight
|
|
15599
|
+
};
|
|
15600
|
+
}
|
|
15601
|
+
const st = atlas.subTextures[sprite];
|
|
15602
|
+
if (!st) return null;
|
|
15603
|
+
return { sx: st.x, sy: st.y, sw: st.width, sh: st.height };
|
|
15604
|
+
}
|
|
15605
|
+
function isAtlasAsset(asset) {
|
|
15606
|
+
return !!asset && typeof asset.atlas === "string" && typeof asset.sprite === "string";
|
|
15607
|
+
}
|
|
15608
|
+
function resolveAssetSource(img, asset, onReady) {
|
|
15609
|
+
if (isAtlasAsset(asset)) {
|
|
15610
|
+
const atlas = getAtlas(asset.atlas, onReady);
|
|
15611
|
+
if (!atlas) return null;
|
|
15612
|
+
const rect = subRectFor(atlas, asset.sprite);
|
|
15613
|
+
if (!rect) return null;
|
|
15614
|
+
return { img, rect, aspect: rect.sw / rect.sh };
|
|
15615
|
+
}
|
|
15616
|
+
const natW = img.naturalWidth || 1;
|
|
15617
|
+
const natH = img.naturalHeight || 1;
|
|
15618
|
+
return { img, rect: null, aspect: natW / natH };
|
|
15619
|
+
}
|
|
15620
|
+
function blit(ctx, src, dx, dy, dw, dh) {
|
|
15621
|
+
if (src.rect) ctx.drawImage(src.img, src.rect.sx, src.rect.sy, src.rect.sw, src.rect.sh, dx, dy, dw, dh);
|
|
15622
|
+
else ctx.drawImage(src.img, dx, dy, dw, dh);
|
|
15623
|
+
}
|
|
15624
|
+
var atlasCache;
|
|
15625
|
+
var init_atlasSlice = __esm({
|
|
15626
|
+
"components/game/shared/atlasSlice.ts"() {
|
|
15627
|
+
"use client";
|
|
15628
|
+
atlasCache = /* @__PURE__ */ new Map();
|
|
15629
|
+
}
|
|
15630
|
+
});
|
|
15414
15631
|
function useCamera() {
|
|
15415
15632
|
const cameraRef = useRef({ x: 0, y: 0, zoom: 1 });
|
|
15416
15633
|
const targetCameraRef = useRef(null);
|
|
@@ -16166,15 +16383,18 @@ function SideView({
|
|
|
16166
16383
|
const platType = plat.type ?? "ground";
|
|
16167
16384
|
const spriteAsset = tSprites?.[platType];
|
|
16168
16385
|
const tileImg = spriteAsset ? loadImage(spriteAsset.url) : null;
|
|
16169
|
-
|
|
16170
|
-
|
|
16171
|
-
const
|
|
16386
|
+
const tileSrc = tileImg ? resolveAssetSource(tileImg, spriteAsset, NOOP) : null;
|
|
16387
|
+
if (tileSrc) {
|
|
16388
|
+
const originX = tileSrc.rect ? tileSrc.rect.sx : 0;
|
|
16389
|
+
const originY = tileSrc.rect ? tileSrc.rect.sy : 0;
|
|
16390
|
+
const tileW = tileSrc.rect ? tileSrc.rect.sw : tileImg.naturalWidth;
|
|
16391
|
+
const tileH = tileSrc.rect ? tileSrc.rect.sh : tileImg.naturalHeight;
|
|
16172
16392
|
const scaleH = plat.height / tileH;
|
|
16173
16393
|
const scaledW = tileW * scaleH;
|
|
16174
16394
|
for (let tx = 0; tx < plat.width; tx += scaledW) {
|
|
16175
16395
|
const drawW = Math.min(scaledW, plat.width - tx);
|
|
16176
16396
|
const srcW = drawW / scaleH;
|
|
16177
|
-
ctx.drawImage(tileImg,
|
|
16397
|
+
ctx.drawImage(tileImg, originX, originY, srcW, tileH, platX + tx, platY, drawW, plat.height);
|
|
16178
16398
|
}
|
|
16179
16399
|
} else {
|
|
16180
16400
|
const color = PLATFORM_COLORS[platType] ?? PLATFORM_COLORS.ground;
|
|
@@ -16208,14 +16428,15 @@ function SideView({
|
|
|
16208
16428
|
const ppy = py - camY;
|
|
16209
16429
|
const facingRight = auth.facingRight ?? true;
|
|
16210
16430
|
const playerImg = pSprite ? loadImage(pSprite.url) : null;
|
|
16211
|
-
|
|
16431
|
+
const playerSrc = playerImg ? resolveAssetSource(playerImg, pSprite, NOOP) : null;
|
|
16432
|
+
if (playerSrc) {
|
|
16212
16433
|
ctx.save();
|
|
16213
16434
|
if (!facingRight) {
|
|
16214
16435
|
ctx.translate(ppx + pw, ppy);
|
|
16215
16436
|
ctx.scale(-1, 1);
|
|
16216
|
-
ctx
|
|
16437
|
+
blit(ctx, playerSrc, 0, 0, pw, ph);
|
|
16217
16438
|
} else {
|
|
16218
|
-
ctx
|
|
16439
|
+
blit(ctx, playerSrc, ppx, ppy, pw, ph);
|
|
16219
16440
|
}
|
|
16220
16441
|
ctx.restore();
|
|
16221
16442
|
} else {
|
|
@@ -16416,10 +16637,11 @@ function Canvas2D({
|
|
|
16416
16637
|
const attackTargetSet = useMemo(() => new Set(attackTargets.map((p) => `${p.x},${p.y}`)), [attackTargets]);
|
|
16417
16638
|
const spriteUrls = useMemo(() => {
|
|
16418
16639
|
const urls = [];
|
|
16640
|
+
const toUrl = (x) => typeof x === "string" ? x : x?.url;
|
|
16419
16641
|
for (const tile of sortedTiles) {
|
|
16420
16642
|
if (tile.terrainSprite) urls.push(tile.terrainSprite.url);
|
|
16421
16643
|
else if (getTerrainSprite) {
|
|
16422
|
-
const url = getTerrainSprite(tile.terrain ?? "");
|
|
16644
|
+
const url = toUrl(getTerrainSprite(tile.terrain ?? ""));
|
|
16423
16645
|
if (url) urls.push(url);
|
|
16424
16646
|
} else {
|
|
16425
16647
|
const url = assetManifest?.terrains?.[tile.terrain ?? ""]?.url;
|
|
@@ -16429,7 +16651,7 @@ function Canvas2D({
|
|
|
16429
16651
|
for (const feature of features) {
|
|
16430
16652
|
if (feature.sprite) urls.push(feature.sprite.url);
|
|
16431
16653
|
else if (getFeatureSprite) {
|
|
16432
|
-
const url = getFeatureSprite(feature.type);
|
|
16654
|
+
const url = toUrl(getFeatureSprite(feature.type));
|
|
16433
16655
|
if (url) urls.push(url);
|
|
16434
16656
|
} else {
|
|
16435
16657
|
const url = assetManifest?.features?.[feature.type]?.url;
|
|
@@ -16439,7 +16661,7 @@ function Canvas2D({
|
|
|
16439
16661
|
for (const unit of units) {
|
|
16440
16662
|
if (unit.sprite) urls.push(unit.sprite.url);
|
|
16441
16663
|
else if (getUnitSprite) {
|
|
16442
|
-
const url = getUnitSprite(unit);
|
|
16664
|
+
const url = toUrl(getUnitSprite(unit));
|
|
16443
16665
|
if (url) urls.push(url);
|
|
16444
16666
|
} else if (unit.unitType) {
|
|
16445
16667
|
const url = assetManifest?.units?.[unit.unitType]?.url;
|
|
@@ -16480,14 +16702,25 @@ function Canvas2D({
|
|
|
16480
16702
|
screenToWorld,
|
|
16481
16703
|
lerpToTarget
|
|
16482
16704
|
} = useCamera();
|
|
16483
|
-
const
|
|
16484
|
-
|
|
16705
|
+
const [, setAtlasVersion] = useState(0);
|
|
16706
|
+
const bumpAtlas = useCallback(() => setAtlasVersion((v) => v + 1), []);
|
|
16707
|
+
const resolveTerrainAsset = useCallback((tile) => {
|
|
16708
|
+
if (tile.terrainSprite) return tile.terrainSprite;
|
|
16709
|
+
const s = getTerrainSprite?.(tile.terrain ?? "");
|
|
16710
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
16711
|
+
return assetManifest?.terrains?.[tile.terrain ?? ""];
|
|
16485
16712
|
}, [getTerrainSprite, assetManifest]);
|
|
16486
|
-
const
|
|
16487
|
-
|
|
16713
|
+
const resolveFeatureAsset = useCallback((feature) => {
|
|
16714
|
+
if (feature.sprite) return feature.sprite;
|
|
16715
|
+
const s = getFeatureSprite?.(feature.type);
|
|
16716
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
16717
|
+
return assetManifest?.features?.[feature.type];
|
|
16488
16718
|
}, [getFeatureSprite, assetManifest]);
|
|
16489
|
-
const
|
|
16490
|
-
|
|
16719
|
+
const resolveUnitAsset = useCallback((unit) => {
|
|
16720
|
+
if (unit.sprite) return unit.sprite;
|
|
16721
|
+
const s = getUnitSprite?.(unit);
|
|
16722
|
+
if (s) return typeof s === "string" ? { url: s } : s;
|
|
16723
|
+
return unit.unitType ? assetManifest?.units?.[unit.unitType] : void 0;
|
|
16491
16724
|
}, [getUnitSprite, assetManifest]);
|
|
16492
16725
|
const miniMapTiles = useMemo(() => {
|
|
16493
16726
|
if (!showMinimap) return [];
|
|
@@ -16551,18 +16784,17 @@ function Canvas2D({
|
|
|
16551
16784
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
16552
16785
|
continue;
|
|
16553
16786
|
}
|
|
16554
|
-
const
|
|
16555
|
-
const img =
|
|
16556
|
-
|
|
16557
|
-
|
|
16558
|
-
|
|
16559
|
-
|
|
16560
|
-
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
|
|
16565
|
-
}
|
|
16787
|
+
const terrainAsset = resolveTerrainAsset(tile);
|
|
16788
|
+
const img = terrainAsset?.url ? getImage(terrainAsset.url) : null;
|
|
16789
|
+
const src = img ? resolveAssetSource(img, terrainAsset, bumpAtlas) : null;
|
|
16790
|
+
if (src) {
|
|
16791
|
+
const drawW = scaledTileWidth;
|
|
16792
|
+
const drawH = scaledTileWidth / src.aspect;
|
|
16793
|
+
const drawX = pos.x;
|
|
16794
|
+
const drawY = flatLike ? pos.y : pos.y + scaledTileHeight - drawH;
|
|
16795
|
+
blit(ctx, src, drawX, drawY, drawW, drawH);
|
|
16796
|
+
} else if (img && img.naturalWidth === 0) {
|
|
16797
|
+
ctx.drawImage(img, pos.x, pos.y, scaledTileWidth, scaledTileHeight);
|
|
16566
16798
|
} else {
|
|
16567
16799
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
16568
16800
|
const topY = pos.y + scaledDiamondTopY;
|
|
@@ -16616,15 +16848,16 @@ function Canvas2D({
|
|
|
16616
16848
|
if (pos.x + scaledTileWidth < visLeft || pos.x > visRight || pos.y + scaledTileHeight < visTop || pos.y > visBottom) {
|
|
16617
16849
|
continue;
|
|
16618
16850
|
}
|
|
16619
|
-
const
|
|
16620
|
-
const img =
|
|
16851
|
+
const featureAsset = resolveFeatureAsset(feature);
|
|
16852
|
+
const img = featureAsset?.url ? getImage(featureAsset.url) : null;
|
|
16853
|
+
const src = img ? resolveAssetSource(img, featureAsset, bumpAtlas) : null;
|
|
16621
16854
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
16622
16855
|
const featureGroundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
16623
16856
|
const isCastle = feature.type === "castle";
|
|
16624
16857
|
const featureDrawH = isCastle ? scaledFloorHeight * 3.5 : scaledFloorHeight * 1.6;
|
|
16625
16858
|
const maxFeatureW = isCastle ? scaledTileWidth * 1.8 : scaledTileWidth * 0.7;
|
|
16626
|
-
if (
|
|
16627
|
-
const ar =
|
|
16859
|
+
if (src) {
|
|
16860
|
+
const ar = src.aspect;
|
|
16628
16861
|
let drawH = featureDrawH;
|
|
16629
16862
|
let drawW = featureDrawH * ar;
|
|
16630
16863
|
if (drawW > maxFeatureW) {
|
|
@@ -16633,7 +16866,7 @@ function Canvas2D({
|
|
|
16633
16866
|
}
|
|
16634
16867
|
const drawX = centerX - drawW / 2;
|
|
16635
16868
|
const drawY = featureGroundY - drawH;
|
|
16636
|
-
ctx
|
|
16869
|
+
blit(ctx, src, drawX, drawY, drawW, drawH);
|
|
16637
16870
|
} else {
|
|
16638
16871
|
const color = FEATURE_COLORS[feature.type] || FEATURE_COLORS.default;
|
|
16639
16872
|
ctx.beginPath();
|
|
@@ -16662,17 +16895,18 @@ function Canvas2D({
|
|
|
16662
16895
|
const centerX = pos.x + scaledTileWidth / 2;
|
|
16663
16896
|
const groundY = pos.y + scaledDiamondTopY + scaledFloorHeight * 0.5;
|
|
16664
16897
|
const breatheOffset = 0;
|
|
16665
|
-
const
|
|
16666
|
-
const img =
|
|
16898
|
+
const unitAsset = resolveUnitAsset(unit);
|
|
16899
|
+
const img = unitAsset?.url ? getImage(unitAsset.url) : null;
|
|
16667
16900
|
const unitDrawH = scaledFloorHeight * spriteHeightRatio * unitScale;
|
|
16668
16901
|
const maxUnitW = scaledTileWidth * spriteMaxWidthRatio * unitScale;
|
|
16669
16902
|
const unitIsSheet = unit.spriteSheet?.url !== void 0;
|
|
16903
|
+
const unitSrc = img && !unitIsSheet ? resolveAssetSource(img, unitAsset, bumpAtlas) : null;
|
|
16670
16904
|
const SHEET_ROWS = 5;
|
|
16671
16905
|
const sheetFrameW = img ? img.naturalWidth / SHEET_COLUMNS : 0;
|
|
16672
16906
|
const sheetFrameH = img ? img.naturalHeight / SHEET_ROWS : 0;
|
|
16673
16907
|
const frameW = unitIsSheet ? sheetFrameW : img?.naturalWidth ?? 1;
|
|
16674
16908
|
const frameH = unitIsSheet ? sheetFrameH : img?.naturalHeight ?? 1;
|
|
16675
|
-
const ar = frameW / (frameH || 1);
|
|
16909
|
+
const ar = unitIsSheet ? sheetFrameW / (sheetFrameH || 1) : unitSrc ? unitSrc.aspect : frameW / (frameH || 1);
|
|
16676
16910
|
let drawH = unitDrawH;
|
|
16677
16911
|
let drawW = unitDrawH * ar;
|
|
16678
16912
|
if (drawW > maxUnitW) {
|
|
@@ -16688,6 +16922,8 @@ function Canvas2D({
|
|
|
16688
16922
|
if (img) {
|
|
16689
16923
|
if (unitIsSheet) {
|
|
16690
16924
|
ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
16925
|
+
} else if (unitSrc) {
|
|
16926
|
+
blit(ctx, unitSrc, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
16691
16927
|
} else {
|
|
16692
16928
|
ctx.drawImage(img, ghostCenterX - drawW / 2, ghostGroundY - drawH, drawW, drawH);
|
|
16693
16929
|
}
|
|
@@ -16736,6 +16972,8 @@ function Canvas2D({
|
|
|
16736
16972
|
const drawUnit = (x) => {
|
|
16737
16973
|
if (unitIsSheet) {
|
|
16738
16974
|
ctx.drawImage(img, 0, 0, sheetFrameW, sheetFrameH, x, spriteY, drawW, drawH);
|
|
16975
|
+
} else if (unitSrc) {
|
|
16976
|
+
blit(ctx, unitSrc, x, spriteY, drawW, drawH);
|
|
16739
16977
|
} else {
|
|
16740
16978
|
ctx.drawImage(img, x, spriteY, drawW, drawH);
|
|
16741
16979
|
}
|
|
@@ -16786,11 +17024,12 @@ function Canvas2D({
|
|
|
16786
17024
|
flatLike,
|
|
16787
17025
|
scale,
|
|
16788
17026
|
debug2,
|
|
16789
|
-
|
|
16790
|
-
|
|
16791
|
-
|
|
17027
|
+
resolveTerrainAsset,
|
|
17028
|
+
resolveFeatureAsset,
|
|
17029
|
+
resolveUnitAsset,
|
|
16792
17030
|
resolveFrameForUnit,
|
|
16793
17031
|
getImage,
|
|
17032
|
+
bumpAtlas,
|
|
16794
17033
|
baseOffsetX,
|
|
16795
17034
|
scaledTileWidth,
|
|
16796
17035
|
scaledTileHeight,
|
|
@@ -17104,7 +17343,7 @@ function Canvas2D({
|
|
|
17104
17343
|
}
|
|
17105
17344
|
);
|
|
17106
17345
|
}
|
|
17107
|
-
var PLATFORM_COLORS, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
|
|
17346
|
+
var PLATFORM_COLORS, NOOP, PLAYER_COLOR, PLAYER_EYE_COLOR, SKY_GRADIENT_TOP, SKY_GRADIENT_BOTTOM, GRID_COLOR, DEFAULT_PLATFORMS;
|
|
17108
17347
|
var init_Canvas2D = __esm({
|
|
17109
17348
|
"components/game/2d/molecules/Canvas2D.tsx"() {
|
|
17110
17349
|
"use client";
|
|
@@ -17118,6 +17357,7 @@ var init_Canvas2D = __esm({
|
|
|
17118
17357
|
init_MiniMap();
|
|
17119
17358
|
init_HealthBar();
|
|
17120
17359
|
init_useImageCache();
|
|
17360
|
+
init_atlasSlice();
|
|
17121
17361
|
init_useCamera();
|
|
17122
17362
|
init_useCanvasGestures();
|
|
17123
17363
|
init_useRenderInterpolation();
|
|
@@ -17131,6 +17371,8 @@ var init_Canvas2D = __esm({
|
|
|
17131
17371
|
hazard: "#c0392b",
|
|
17132
17372
|
goal: "#f1c40f"
|
|
17133
17373
|
};
|
|
17374
|
+
NOOP = () => {
|
|
17375
|
+
};
|
|
17134
17376
|
PLAYER_COLOR = "#3498db";
|
|
17135
17377
|
PLAYER_EYE_COLOR = "#ffffff";
|
|
17136
17378
|
SKY_GRADIENT_TOP = "#1a1a2e";
|
|
@@ -40883,6 +41125,7 @@ var init_molecules2 = __esm({
|
|
|
40883
41125
|
init_PhysicsCanvas();
|
|
40884
41126
|
init_BiologyCanvas();
|
|
40885
41127
|
init_ChemistryCanvas();
|
|
41128
|
+
init_AlgorithmCanvas();
|
|
40886
41129
|
init_GraphView();
|
|
40887
41130
|
init_MapView();
|
|
40888
41131
|
init_NumberStepper();
|
|
@@ -47541,6 +47784,7 @@ var init_component_registry_generated = __esm({
|
|
|
47541
47784
|
init_ActionTile();
|
|
47542
47785
|
init_ActivationBlock();
|
|
47543
47786
|
init_ComponentPatterns();
|
|
47787
|
+
init_AlgorithmCanvas();
|
|
47544
47788
|
init_AnimatedCounter();
|
|
47545
47789
|
init_AnimatedGraphic();
|
|
47546
47790
|
init_AnimatedReveal();
|
|
@@ -47839,6 +48083,7 @@ var init_component_registry_generated = __esm({
|
|
|
47839
48083
|
"ActivationBlock": ActivationBlock,
|
|
47840
48084
|
"Alert": AlertPattern,
|
|
47841
48085
|
"AlertPattern": AlertPattern,
|
|
48086
|
+
"AlgorithmCanvas": AlgorithmCanvas,
|
|
47842
48087
|
"AnimatedCounter": AnimatedCounter,
|
|
47843
48088
|
"AnimatedGraphic": AnimatedGraphic,
|
|
47844
48089
|
"AnimatedReveal": AnimatedReveal,
|
|
@@ -51354,4 +51599,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
|
|
|
51354
51599
|
});
|
|
51355
51600
|
}
|
|
51356
51601
|
|
|
51357
|
-
export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, ClassifierBoard, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EMPTY_EFFECT_STATE, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCard, GameHud, GameIcon, GameMenu, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, ItemSlot, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NodeSlotEditor, NotifyListener, NumberStepper, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateGraph, StateIndicator, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createTranslate, createUnitAnimationState, drawSprite, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGameAudioContext, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSwipeGesture, useTapReveal, useTraitListens, useTranslate127 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
|
|
51602
|
+
export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, ClassifierBoard, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EMPTY_EFFECT_STATE, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCard, GameHud, GameIcon, GameMenu, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, ItemSlot, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NodeSlotEditor, NotifyListener, NumberStepper, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateGraph, StateIndicator, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createTranslate, createUnitAnimationState, drawSprite, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGameAudioContext, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSwipeGesture, useTapReveal, useTraitListens, useTranslate127 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
|