@almadar/ui 6.5.0 → 6.7.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/{EntityBindingContext-0Evn_LcT.d.cts → EntityBindingContext-Bn3ePJQC.d.cts} +1 -1
- package/dist/{EntityBindingContext-0Evn_LcT.d.ts → EntityBindingContext-Bn3ePJQC.d.ts} +1 -1
- package/dist/{GameAudioProvider-B48iXwz3.d.ts → GameAudioProvider-Ctceau1s.d.ts} +6 -18
- package/dist/{GameAudioProvider-CQAdPreB.d.cts → GameAudioProvider-Dk_Y3LN3.d.cts} +6 -18
- package/dist/avl/index.cjs +1268 -220
- package/dist/avl/index.js +1269 -221
- package/dist/{avl-schema-parser-dvJKXn-o.d.ts → avl-schema-parser-DncJLEn9.d.ts} +18 -0
- package/dist/{avl-schema-parser-Bt4NzAam.d.cts → avl-schema-parser-FQ1474v8.d.cts} +18 -0
- package/dist/{cn-DJSBBm5W.d.cts → cn-CCjFspAo.d.cts} +25 -1
- package/dist/{cn-BbhJq_nr.d.ts → cn-sgpqpN0U.d.ts} +25 -1
- package/dist/components/index.cjs +1092 -249
- package/dist/components/index.d.cts +193 -23
- package/dist/components/index.d.ts +193 -23
- package/dist/components/index.js +1089 -250
- package/dist/context/index.cjs +10 -13
- package/dist/context/index.js +10 -13
- package/dist/hooks/index.cjs +63 -13
- package/dist/hooks/index.d.cts +2 -2
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.js +64 -15
- package/dist/lib/drawable/three/index.cjs +126 -13
- package/dist/lib/drawable/three/index.d.cts +2 -2
- package/dist/lib/drawable/three/index.d.ts +2 -2
- package/dist/lib/drawable/three/index.js +127 -14
- package/dist/lib/index.cjs +180 -0
- package/dist/lib/index.d.cts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +178 -1
- package/dist/locales/index.cjs +6 -3
- package/dist/locales/index.js +6 -3
- package/dist/providers/index.cjs +974 -202
- package/dist/providers/index.d.cts +2 -2
- package/dist/providers/index.d.ts +2 -2
- package/dist/providers/index.js +974 -202
- package/dist/runtime/index.cjs +1594 -196
- package/dist/runtime/index.d.cts +79 -6
- package/dist/runtime/index.d.ts +79 -6
- package/dist/runtime/index.js +1592 -198
- package/dist/slot-host-Czc2JAxo.d.cts +47 -0
- package/dist/slot-host-Czc2JAxo.d.ts +47 -0
- package/dist/{useEventBus-CQWyAWpK.d.ts → useKeyboardRouter-D84cNWmA.d.ts} +31 -1
- package/dist/{useEventBus-Ckr4wqW3.d.cts → useKeyboardRouter-DQEE_9mq.d.cts} +31 -1
- package/locales/ar.json +2 -1
- package/locales/en.json +2 -1
- package/locales/sl.json +2 -1
- package/package.json +4 -4
- package/themes/comic.css +437 -0
- package/themes/index.css +1 -0
package/dist/providers/index.cjs
CHANGED
|
@@ -10045,7 +10045,7 @@ function collectDrawnItems(nodes) {
|
|
|
10045
10045
|
for (const n of nodes) {
|
|
10046
10046
|
switch (n.type) {
|
|
10047
10047
|
case "draw-sprite":
|
|
10048
|
-
if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id, anchor: n.anchor, width: n.width, height: n.height });
|
|
10048
|
+
if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id, anchor: n.anchor, width: n.width, height: n.height, rotation: n.rotation });
|
|
10049
10049
|
break;
|
|
10050
10050
|
case "draw-shape":
|
|
10051
10051
|
case "draw-text":
|
|
@@ -10055,7 +10055,7 @@ function collectDrawnItems(nodes) {
|
|
|
10055
10055
|
break;
|
|
10056
10056
|
case "draw-sprite-layer":
|
|
10057
10057
|
for (const it of n.items) {
|
|
10058
|
-
if (isValidScenePos(it.position)) out.push({ pos: it.position, id: it.id, anchor: it.anchor, width: it.width, height: it.height });
|
|
10058
|
+
if (isValidScenePos(it.position)) out.push({ pos: it.position, id: it.id, anchor: it.anchor, width: it.width, height: it.height, rotation: it.rotation });
|
|
10059
10059
|
}
|
|
10060
10060
|
break;
|
|
10061
10061
|
case "draw-shape-layer":
|
|
@@ -10075,15 +10075,39 @@ function buildHitIndex(items) {
|
|
|
10075
10075
|
}
|
|
10076
10076
|
return m;
|
|
10077
10077
|
}
|
|
10078
|
+
function withPreviewPosition(nodes, id, pos) {
|
|
10079
|
+
return nodes.map((n) => {
|
|
10080
|
+
if (n.type === "draw-sprite-layer" || n.type === "draw-shape-layer" || n.type === "draw-text-layer") {
|
|
10081
|
+
if (!n.items.some((it) => it.id === id)) return n;
|
|
10082
|
+
return { ...n, items: n.items.map((it) => it.id === id ? { ...it, position: pos } : it) };
|
|
10083
|
+
}
|
|
10084
|
+
if (n.type === "draw-group") {
|
|
10085
|
+
if (!Array.isArray(n.items)) return n;
|
|
10086
|
+
return { ...n, items: withPreviewPosition(n.items, id, pos) };
|
|
10087
|
+
}
|
|
10088
|
+
if (n.id === id && "position" in n) {
|
|
10089
|
+
return { ...n, position: pos };
|
|
10090
|
+
}
|
|
10091
|
+
return n;
|
|
10092
|
+
});
|
|
10093
|
+
}
|
|
10078
10094
|
function hitTestSprites(items, projector, point) {
|
|
10079
10095
|
for (let i = items.length - 1; i >= 0; i--) {
|
|
10080
10096
|
const it = items[i];
|
|
10081
10097
|
if (it.id === void 0) continue;
|
|
10082
10098
|
const r = spriteRect(projector, { position: it.pos, anchor: it.anchor, width: it.width, height: it.height });
|
|
10083
|
-
|
|
10099
|
+
const test = it.rotation ? rotatePoint(point, { x: r.x + r.w / 2, y: r.y + r.h / 2 }, -it.rotation) : point;
|
|
10100
|
+
if (test.x >= r.x && test.x <= r.x + r.w && test.y >= r.y && test.y <= r.y + r.h) return it.id;
|
|
10084
10101
|
}
|
|
10085
10102
|
return void 0;
|
|
10086
10103
|
}
|
|
10104
|
+
function rotatePoint(p, center, radians) {
|
|
10105
|
+
const cos = Math.cos(radians);
|
|
10106
|
+
const sin = Math.sin(radians);
|
|
10107
|
+
const dx = p.x - center.x;
|
|
10108
|
+
const dy = p.y - center.y;
|
|
10109
|
+
return { x: center.x + dx * cos - dy * sin, y: center.y + dx * sin + dy * cos };
|
|
10110
|
+
}
|
|
10087
10111
|
var init_hitTest = __esm({
|
|
10088
10112
|
"lib/drawable/hitTest.ts"() {
|
|
10089
10113
|
init_contract();
|
|
@@ -10092,6 +10116,41 @@ var init_hitTest = __esm({
|
|
|
10092
10116
|
function normalizeBackdrop(bg) {
|
|
10093
10117
|
return typeof bg === "string" ? { url: bg, role: "decoration", category: "background" } : bg;
|
|
10094
10118
|
}
|
|
10119
|
+
function selectionOverlayNodes(projector, item) {
|
|
10120
|
+
const r = spriteRect(projector, { position: item.pos, anchor: item.anchor, width: item.width, height: item.height });
|
|
10121
|
+
const tw = projector.tileWidth;
|
|
10122
|
+
const cellTopLeft = projector.anchorPoint(item.pos, "top-left");
|
|
10123
|
+
const offsetX = (r.x - cellTopLeft.x) / tw;
|
|
10124
|
+
const offsetY = (r.y - cellTopLeft.y) / tw;
|
|
10125
|
+
const width = r.w / tw;
|
|
10126
|
+
const height = r.h / tw;
|
|
10127
|
+
const handle = EDIT_HANDLE_SIZE_PX / tw;
|
|
10128
|
+
const ring = {
|
|
10129
|
+
type: "draw-shape",
|
|
10130
|
+
shape: "rect",
|
|
10131
|
+
position: item.pos,
|
|
10132
|
+
anchor: "top-left",
|
|
10133
|
+
offsetX,
|
|
10134
|
+
offsetY,
|
|
10135
|
+
width,
|
|
10136
|
+
height,
|
|
10137
|
+
stroke: EDIT_SELECTION_COLOR,
|
|
10138
|
+
strokeWidth: 2,
|
|
10139
|
+
fill: "none"
|
|
10140
|
+
};
|
|
10141
|
+
const handles = EDIT_SELECTION_CORNERS.map(([cx, cy]) => ({
|
|
10142
|
+
type: "draw-shape",
|
|
10143
|
+
shape: "rect",
|
|
10144
|
+
position: item.pos,
|
|
10145
|
+
anchor: "top-left",
|
|
10146
|
+
offsetX: offsetX + cx * width - handle / 2,
|
|
10147
|
+
offsetY: offsetY + cy * height - handle / 2,
|
|
10148
|
+
width: handle,
|
|
10149
|
+
height: handle,
|
|
10150
|
+
fill: EDIT_SELECTION_COLOR
|
|
10151
|
+
}));
|
|
10152
|
+
return [ring, ...handles];
|
|
10153
|
+
}
|
|
10095
10154
|
function Canvas2D({
|
|
10096
10155
|
className,
|
|
10097
10156
|
isLoading = false,
|
|
@@ -10105,6 +10164,12 @@ function Canvas2D({
|
|
|
10105
10164
|
tileLeaveEvent,
|
|
10106
10165
|
keyMap,
|
|
10107
10166
|
keyUpMap,
|
|
10167
|
+
editable = false,
|
|
10168
|
+
selectedId = null,
|
|
10169
|
+
onSelect,
|
|
10170
|
+
onMove,
|
|
10171
|
+
selectEvent,
|
|
10172
|
+
moveEvent,
|
|
10108
10173
|
camera = "pan-zoom",
|
|
10109
10174
|
scale = 0.4,
|
|
10110
10175
|
tileWidth,
|
|
@@ -10362,10 +10427,22 @@ function Canvas2D({
|
|
|
10362
10427
|
painter.scale(cam.zoom, cam.zoom);
|
|
10363
10428
|
painter.translate(-viewportSize.width / 2 - cam.x, -viewportSize.height / 2 - cam.y);
|
|
10364
10429
|
const dctx = { projector, time: timeMs, invalidate: bumpAtlas };
|
|
10365
|
-
|
|
10430
|
+
let paintNodes = drawables;
|
|
10431
|
+
if (editable) {
|
|
10432
|
+
const drag = editDragRef.current;
|
|
10433
|
+
if (drag && drag.moved) {
|
|
10434
|
+
paintNodes = withPreviewPosition(paintNodes, drag.id, { x: drag.previewX, y: drag.previewY });
|
|
10435
|
+
}
|
|
10436
|
+
const selectedItem = selectedId != null ? drawnItems.find((it) => it.id === selectedId) : void 0;
|
|
10437
|
+
if (selectedItem) {
|
|
10438
|
+
const overlaySource = drag && drag.moved && drag.id === selectedId ? { ...selectedItem, pos: { x: drag.previewX, y: drag.previewY } } : selectedItem;
|
|
10439
|
+
paintNodes = [...paintNodes, ...selectionOverlayNodes(projector, overlaySource)];
|
|
10440
|
+
}
|
|
10441
|
+
}
|
|
10442
|
+
for (const node of paintNodes) paintDrawable(painter, node, dctx);
|
|
10366
10443
|
painter.restore();
|
|
10367
|
-
scheduleAnimation(
|
|
10368
|
-
}, [viewportSize, backgroundImage, bgColor, drawables, projector, cameraRef, bumpAtlas, getImage, cameraPos, defaultGridFocus, camera, dragDistance]);
|
|
10444
|
+
scheduleAnimation(paintNodes);
|
|
10445
|
+
}, [viewportSize, backgroundImage, bgColor, drawables, projector, cameraRef, bumpAtlas, getImage, cameraPos, defaultGridFocus, camera, dragDistance, editable, selectedId, drawnItems]);
|
|
10369
10446
|
React89.useEffect(() => {
|
|
10370
10447
|
drawTimeRef.current = draw;
|
|
10371
10448
|
}, [draw]);
|
|
@@ -10410,23 +10487,83 @@ function Canvas2D({
|
|
|
10410
10487
|
};
|
|
10411
10488
|
}, [camera, followTarget, lerpToTarget, draw]);
|
|
10412
10489
|
const singlePointerActiveRef = React89.useRef(false);
|
|
10490
|
+
const editDragRef = React89.useRef(null);
|
|
10491
|
+
const pointerToScene = React89.useCallback((clientX, clientY) => {
|
|
10492
|
+
const canvas = canvasRef.current;
|
|
10493
|
+
if (!canvas) return { x: 0, y: 0 };
|
|
10494
|
+
const world = screenToWorld(clientX, clientY, canvas, viewportSize);
|
|
10495
|
+
const adjustedX = world.x - scaledTileWidth / 2;
|
|
10496
|
+
const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
|
|
10497
|
+
return unproject(adjustedX, adjustedY);
|
|
10498
|
+
}, [screenToWorld, viewportSize, scaledTileWidth, squareGrid, scaledDiamondTopY, scaledFloorHeight, unproject]);
|
|
10413
10499
|
const handleCanvasPointerDown = React89.useCallback((e) => {
|
|
10414
10500
|
singlePointerActiveRef.current = true;
|
|
10501
|
+
if (editable) {
|
|
10502
|
+
if (!canvasRef.current) return;
|
|
10503
|
+
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
10504
|
+
const hitId = hitTestSprites(drawnItems, projector, world);
|
|
10505
|
+
if (hitId === void 0) return;
|
|
10506
|
+
const item = [...drawnItems].reverse().find((it) => it.id === hitId);
|
|
10507
|
+
if (!item) return;
|
|
10508
|
+
editDragRef.current = {
|
|
10509
|
+
id: hitId,
|
|
10510
|
+
pointerId: e.pointerId,
|
|
10511
|
+
startClientX: e.clientX,
|
|
10512
|
+
startClientY: e.clientY,
|
|
10513
|
+
startSceneX: item.pos.x,
|
|
10514
|
+
startSceneY: item.pos.y,
|
|
10515
|
+
moved: false,
|
|
10516
|
+
previewX: item.pos.x,
|
|
10517
|
+
previewY: item.pos.y
|
|
10518
|
+
};
|
|
10519
|
+
return;
|
|
10520
|
+
}
|
|
10415
10521
|
if (enableCamera) handlePointerDown(e);
|
|
10416
|
-
}, [enableCamera, handlePointerDown]);
|
|
10522
|
+
}, [editable, screenToWorld, viewportSize, drawnItems, projector, enableCamera, handlePointerDown]);
|
|
10417
10523
|
const handleCanvasPointerMove = React89.useCallback((e) => {
|
|
10524
|
+
if (editable) {
|
|
10525
|
+
const drag = editDragRef.current;
|
|
10526
|
+
if (!drag || drag.pointerId !== e.pointerId) return;
|
|
10527
|
+
const dxPx = e.clientX - drag.startClientX;
|
|
10528
|
+
const dyPx = e.clientY - drag.startClientY;
|
|
10529
|
+
if (!drag.moved && Math.abs(dxPx) + Math.abs(dyPx) <= 5) return;
|
|
10530
|
+
drag.moved = true;
|
|
10531
|
+
const nowScene = pointerToScene(e.clientX, e.clientY);
|
|
10532
|
+
const startScene = pointerToScene(drag.startClientX, drag.startClientY);
|
|
10533
|
+
drag.previewX = drag.startSceneX + (nowScene.x - startScene.x);
|
|
10534
|
+
drag.previewY = drag.startSceneY + (nowScene.y - startScene.y);
|
|
10535
|
+
draw();
|
|
10536
|
+
return;
|
|
10537
|
+
}
|
|
10418
10538
|
if (enableCamera) handlePointerMove(e, () => draw());
|
|
10419
|
-
}, [
|
|
10539
|
+
}, [editable, pointerToScene, draw, enableCamera, handlePointerMove]);
|
|
10420
10540
|
const handleCanvasHover = React89.useCallback((e) => {
|
|
10421
10541
|
if (singlePointerActiveRef.current) return;
|
|
10422
10542
|
if (!tileHoverEvent || !canvasRef.current) return;
|
|
10423
|
-
const
|
|
10424
|
-
const adjustedX = world.x - scaledTileWidth / 2;
|
|
10425
|
-
const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
|
|
10426
|
-
const isoPos = unproject(adjustedX, adjustedY);
|
|
10543
|
+
const isoPos = pointerToScene(e.clientX, e.clientY);
|
|
10427
10544
|
eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
|
|
10428
|
-
}, [
|
|
10545
|
+
}, [pointerToScene, tileHoverEvent, eventBus]);
|
|
10429
10546
|
const handleCanvasPointerUp = React89.useCallback((e) => {
|
|
10547
|
+
if (editable) {
|
|
10548
|
+
singlePointerActiveRef.current = false;
|
|
10549
|
+
const drag = editDragRef.current;
|
|
10550
|
+
if (drag && drag.pointerId === e.pointerId) {
|
|
10551
|
+
editDragRef.current = null;
|
|
10552
|
+
if (drag.moved) {
|
|
10553
|
+
onMove?.(drag.id, drag.previewX, drag.previewY);
|
|
10554
|
+
if (moveEvent) eventBus.emit(`UI:${moveEvent}`, { id: drag.id, x: drag.previewX, y: drag.previewY });
|
|
10555
|
+
draw();
|
|
10556
|
+
return;
|
|
10557
|
+
}
|
|
10558
|
+
const next = selectedId === drag.id ? null : drag.id;
|
|
10559
|
+
onSelect?.(next);
|
|
10560
|
+
if (selectEvent) eventBus.emit(`UI:${selectEvent}`, { id: next });
|
|
10561
|
+
return;
|
|
10562
|
+
}
|
|
10563
|
+
onSelect?.(null);
|
|
10564
|
+
if (selectEvent) eventBus.emit(`UI:${selectEvent}`, { id: null });
|
|
10565
|
+
return;
|
|
10566
|
+
}
|
|
10430
10567
|
singlePointerActiveRef.current = false;
|
|
10431
10568
|
if (enableCamera) handlePointerUp();
|
|
10432
10569
|
if (dragDistance() > 5) return;
|
|
@@ -10437,16 +10574,14 @@ function Canvas2D({
|
|
|
10437
10574
|
eventBus.emit(`UI:${unitClickEvent}`, { unitId: spriteHit });
|
|
10438
10575
|
return;
|
|
10439
10576
|
}
|
|
10440
|
-
const
|
|
10441
|
-
const adjustedY = squareGrid ? world.y - scaledTileWidth / 2 : world.y - scaledDiamondTopY - scaledFloorHeight / 2;
|
|
10442
|
-
const isoPos = unproject(adjustedX, adjustedY);
|
|
10577
|
+
const isoPos = pointerToScene(e.clientX, e.clientY);
|
|
10443
10578
|
const hitId = hitIndex.get(`${isoPos.x},${isoPos.y}`);
|
|
10444
10579
|
if (hitId !== void 0 && unitClickEvent) {
|
|
10445
10580
|
eventBus.emit(`UI:${unitClickEvent}`, { unitId: hitId });
|
|
10446
10581
|
} else if (tileClickEvent) {
|
|
10447
10582
|
eventBus.emit(`UI:${tileClickEvent}`, { x: isoPos.x, y: isoPos.y });
|
|
10448
10583
|
}
|
|
10449
|
-
}, [
|
|
10584
|
+
}, [editable, selectedId, onMove, moveEvent, onSelect, selectEvent, eventBus, draw, enableCamera, handlePointerUp, dragDistance, screenToWorld, viewportSize, drawnItems, projector, tileClickEvent, unitClickEvent, hitIndex, pointerToScene]);
|
|
10450
10585
|
const handleCanvasPointerLeave = React89.useCallback(() => {
|
|
10451
10586
|
handleMouseLeave();
|
|
10452
10587
|
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
@@ -10465,7 +10600,7 @@ function Canvas2D({
|
|
|
10465
10600
|
}, [enableCamera, handlePointerUp]);
|
|
10466
10601
|
const gestureHandlers = useCanvasGestures({
|
|
10467
10602
|
canvasRef,
|
|
10468
|
-
enabled: enableCamera || !!tileHoverEvent || !!tileClickEvent || !!unitClickEvent,
|
|
10603
|
+
enabled: enableCamera || !!tileHoverEvent || !!tileClickEvent || !!unitClickEvent || editable,
|
|
10469
10604
|
onPointerDown: handleCanvasPointerDown,
|
|
10470
10605
|
onPointerMove: handleCanvasPointerMove,
|
|
10471
10606
|
onPointerUp: handleCanvasPointerUp,
|
|
@@ -10597,7 +10732,7 @@ function Canvas2D({
|
|
|
10597
10732
|
}
|
|
10598
10733
|
) });
|
|
10599
10734
|
}
|
|
10600
|
-
var canvas2DLog;
|
|
10735
|
+
var canvas2DLog, EDIT_SELECTION_COLOR, EDIT_HANDLE_SIZE_PX, EDIT_SELECTION_CORNERS;
|
|
10601
10736
|
var init_Canvas2D = __esm({
|
|
10602
10737
|
"components/game/molecules/Canvas2D.tsx"() {
|
|
10603
10738
|
"use client";
|
|
@@ -10622,8 +10757,12 @@ var init_Canvas2D = __esm({
|
|
|
10622
10757
|
init_DrawGroup();
|
|
10623
10758
|
init_registry();
|
|
10624
10759
|
init_hitTest();
|
|
10760
|
+
init_contract();
|
|
10625
10761
|
init_isometric();
|
|
10626
10762
|
canvas2DLog = logger.createLogger("almadar:ui:game-canvas");
|
|
10763
|
+
EDIT_SELECTION_COLOR = "#3b82f6";
|
|
10764
|
+
EDIT_HANDLE_SIZE_PX = 8;
|
|
10765
|
+
EDIT_SELECTION_CORNERS = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
|
10627
10766
|
Canvas2D.displayName = "Canvas2D";
|
|
10628
10767
|
}
|
|
10629
10768
|
});
|
|
@@ -10665,6 +10804,12 @@ function Canvas({
|
|
|
10665
10804
|
featureClickEvent,
|
|
10666
10805
|
keyMap,
|
|
10667
10806
|
keyUpMap,
|
|
10807
|
+
editable,
|
|
10808
|
+
selectedId,
|
|
10809
|
+
onSelect,
|
|
10810
|
+
onMove,
|
|
10811
|
+
selectEvent,
|
|
10812
|
+
moveEvent,
|
|
10668
10813
|
children
|
|
10669
10814
|
}) {
|
|
10670
10815
|
canvasLog.debug("Canvas render", { mode, drawablesCount: drawables?.length, projection, camera: camera ? JSON.stringify(camera) : void 0 });
|
|
@@ -10742,6 +10887,12 @@ function Canvas({
|
|
|
10742
10887
|
tileLeaveEvent,
|
|
10743
10888
|
keyMap,
|
|
10744
10889
|
keyUpMap,
|
|
10890
|
+
editable,
|
|
10891
|
+
selectedId,
|
|
10892
|
+
onSelect,
|
|
10893
|
+
onMove,
|
|
10894
|
+
selectEvent,
|
|
10895
|
+
moveEvent,
|
|
10745
10896
|
...children !== void 0 ? { children } : {}
|
|
10746
10897
|
}
|
|
10747
10898
|
);
|
|
@@ -10763,15 +10914,19 @@ function GameAudioToggle({
|
|
|
10763
10914
|
size = "sm",
|
|
10764
10915
|
className,
|
|
10765
10916
|
onAsset,
|
|
10766
|
-
offAsset
|
|
10917
|
+
offAsset,
|
|
10918
|
+
toggleEvent
|
|
10767
10919
|
}) {
|
|
10768
10920
|
const ctx = providers.useGameAudioContextOptional();
|
|
10769
10921
|
const [localMuted, setLocalMuted] = React89.useState(false);
|
|
10770
10922
|
const muted = ctx ? ctx.muted : localMuted;
|
|
10771
10923
|
const setMuted = ctx ? ctx.setMuted : setLocalMuted;
|
|
10924
|
+
const eventBus = useEventBus();
|
|
10772
10925
|
const handleToggle = React89.useCallback(() => {
|
|
10773
|
-
|
|
10774
|
-
|
|
10926
|
+
const next = !muted;
|
|
10927
|
+
setMuted(next);
|
|
10928
|
+
if (toggleEvent) eventBus.emit(`UI:${toggleEvent}`, { muted: next });
|
|
10929
|
+
}, [muted, setMuted, toggleEvent, eventBus]);
|
|
10775
10930
|
const activeAsset = muted ? offAsset : onAsset;
|
|
10776
10931
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10777
10932
|
Button,
|
|
@@ -10790,6 +10945,7 @@ var init_GameAudioToggle = __esm({
|
|
|
10790
10945
|
"use client";
|
|
10791
10946
|
init_atoms();
|
|
10792
10947
|
init_cn();
|
|
10948
|
+
init_useEventBus();
|
|
10793
10949
|
init_GameIcon();
|
|
10794
10950
|
GameAudioToggle.displayName = "GameAudioToggle";
|
|
10795
10951
|
}
|
|
@@ -11061,6 +11217,47 @@ var init_useGameAudio = __esm({
|
|
|
11061
11217
|
useGameAudio.displayName = "useGameAudio";
|
|
11062
11218
|
}
|
|
11063
11219
|
});
|
|
11220
|
+
function GameAudioCue({
|
|
11221
|
+
cue,
|
|
11222
|
+
cueSeq,
|
|
11223
|
+
music,
|
|
11224
|
+
muted,
|
|
11225
|
+
volume,
|
|
11226
|
+
manifest,
|
|
11227
|
+
baseUrl
|
|
11228
|
+
}) {
|
|
11229
|
+
const { play, playMusic, stopMusic, setMuted, setMasterVolume } = useGameAudio({
|
|
11230
|
+
manifest,
|
|
11231
|
+
baseUrl,
|
|
11232
|
+
initialMuted: muted,
|
|
11233
|
+
initialVolume: volume
|
|
11234
|
+
});
|
|
11235
|
+
const prevCueSeqRef = React89.useRef(cueSeq);
|
|
11236
|
+
React89.useEffect(() => {
|
|
11237
|
+
if (cue && cueSeq !== void 0 && cueSeq !== prevCueSeqRef.current) {
|
|
11238
|
+
play(cue);
|
|
11239
|
+
}
|
|
11240
|
+
prevCueSeqRef.current = cueSeq;
|
|
11241
|
+
}, [cue, cueSeq, play]);
|
|
11242
|
+
React89.useEffect(() => {
|
|
11243
|
+
if (music) playMusic(music);
|
|
11244
|
+
else stopMusic();
|
|
11245
|
+
}, [music, playMusic, stopMusic]);
|
|
11246
|
+
React89.useEffect(() => {
|
|
11247
|
+
if (muted !== void 0) setMuted(muted);
|
|
11248
|
+
}, [muted, setMuted]);
|
|
11249
|
+
React89.useEffect(() => {
|
|
11250
|
+
if (volume !== void 0) setMasterVolume(volume);
|
|
11251
|
+
}, [volume, setMasterVolume]);
|
|
11252
|
+
return null;
|
|
11253
|
+
}
|
|
11254
|
+
var init_GameAudioCue = __esm({
|
|
11255
|
+
"components/game/atoms/GameAudioCue.tsx"() {
|
|
11256
|
+
"use client";
|
|
11257
|
+
init_useGameAudio();
|
|
11258
|
+
GameAudioCue.displayName = "GameAudioCue";
|
|
11259
|
+
}
|
|
11260
|
+
});
|
|
11064
11261
|
function isKnownState(s) {
|
|
11065
11262
|
return s in DEFAULT_STATE_STYLES;
|
|
11066
11263
|
}
|
|
@@ -11759,15 +11956,18 @@ var init_StateJsonView = __esm({
|
|
|
11759
11956
|
StateJsonView.displayName = "StateJsonView";
|
|
11760
11957
|
}
|
|
11761
11958
|
});
|
|
11762
|
-
|
|
11763
|
-
|
|
11764
|
-
|
|
11765
|
-
|
|
11766
|
-
|
|
11767
|
-
|
|
11768
|
-
|
|
11769
|
-
|
|
11770
|
-
|
|
11959
|
+
|
|
11960
|
+
// lib/gameFonts.ts
|
|
11961
|
+
function resolveGameFontFamily(input) {
|
|
11962
|
+
if (!input) return void 0;
|
|
11963
|
+
const resolved = GAME_FONT_KEYS[input];
|
|
11964
|
+
if (resolved) return `'${resolved}', ui-sans-serif, system-ui, sans-serif`;
|
|
11965
|
+
return input;
|
|
11966
|
+
}
|
|
11967
|
+
var GAME_FONT_KEYS;
|
|
11968
|
+
var init_gameFonts = __esm({
|
|
11969
|
+
"lib/gameFonts.ts"() {
|
|
11970
|
+
GAME_FONT_KEYS = {
|
|
11771
11971
|
fredoka: "Fredoka",
|
|
11772
11972
|
future: "Kenney Future",
|
|
11773
11973
|
"future-narrow": "Kenney Future Narrow",
|
|
@@ -11775,6 +11975,17 @@ var init_GameShell = __esm({
|
|
|
11775
11975
|
blocks: "Kenney Blocks",
|
|
11776
11976
|
mini: "Kenney Mini"
|
|
11777
11977
|
};
|
|
11978
|
+
}
|
|
11979
|
+
});
|
|
11980
|
+
var GameShell;
|
|
11981
|
+
var init_GameShell = __esm({
|
|
11982
|
+
"components/game/templates/GameShell.tsx"() {
|
|
11983
|
+
init_cn();
|
|
11984
|
+
init_gameFonts();
|
|
11985
|
+
init_Box();
|
|
11986
|
+
init_Card();
|
|
11987
|
+
init_Typography();
|
|
11988
|
+
init_AtlasImage();
|
|
11778
11989
|
GameShell = ({
|
|
11779
11990
|
appName = "Game",
|
|
11780
11991
|
hud,
|
|
@@ -11788,7 +11999,7 @@ var init_GameShell = __esm({
|
|
|
11788
11999
|
fontFamily,
|
|
11789
12000
|
"data-theme": dataTheme
|
|
11790
12001
|
}) => {
|
|
11791
|
-
const
|
|
12002
|
+
const displayFont = resolveGameFontFamily(fontFamily);
|
|
11792
12003
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11793
12004
|
Box,
|
|
11794
12005
|
{
|
|
@@ -11807,7 +12018,7 @@ var init_GameShell = __esm({
|
|
|
11807
12018
|
// passed — an always-on inline stamp would shadow the orbital's
|
|
11808
12019
|
// inline-theme font-family-display token (inline style beats the
|
|
11809
12020
|
// theme provider's vars for the whole shell subtree).
|
|
11810
|
-
...
|
|
12021
|
+
...displayFont ? { "--font-family-display": displayFont } : {}
|
|
11811
12022
|
},
|
|
11812
12023
|
children: [
|
|
11813
12024
|
backgroundAsset && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -12009,14 +12220,15 @@ function drawArrowHead(ctx, x1, y1, x2, y2, size) {
|
|
|
12009
12220
|
ctx.closePath();
|
|
12010
12221
|
ctx.fill();
|
|
12011
12222
|
}
|
|
12012
|
-
function drawShape(ctx, shape, width, height, allShapes) {
|
|
12223
|
+
function drawShape(ctx, shape, width, height, allShapes, fontFamily) {
|
|
12013
12224
|
ctx.save();
|
|
12014
12225
|
const opacity = shape.opacity ?? 1;
|
|
12015
12226
|
ctx.globalAlpha = opacity;
|
|
12016
12227
|
const stroke = resolveColor2(shape.color, ctx, "#333333");
|
|
12017
12228
|
const fill = shape.fill ? resolveColor2(shape.fill, ctx, "#cccccc") : void 0;
|
|
12018
12229
|
ctx.lineWidth = shape.lineWidth ?? 2;
|
|
12019
|
-
|
|
12230
|
+
const dashPattern = shape.dash ? DASH_PATTERNS[shape.dash] : void 0;
|
|
12231
|
+
if (dashPattern) ctx.setLineDash([...dashPattern]);
|
|
12020
12232
|
switch (shape.type) {
|
|
12021
12233
|
case "grid": {
|
|
12022
12234
|
const step = shape.step ?? 40;
|
|
@@ -12138,7 +12350,7 @@ function drawShape(ctx, shape, width, height, allShapes) {
|
|
|
12138
12350
|
case "text": {
|
|
12139
12351
|
if (shape.x == null || shape.y == null || !shape.text) break;
|
|
12140
12352
|
ctx.fillStyle = stroke;
|
|
12141
|
-
ctx.font = `${shape.fontSize ?? 14}px ${themeBodyFont(ctx.canvas)}`;
|
|
12353
|
+
ctx.font = `${shape.fontSize ?? 14}px ${shape.fontFamily ?? fontFamily ?? themeBodyFont(ctx.canvas)}`;
|
|
12142
12354
|
ctx.textAlign = shape.align ?? "left";
|
|
12143
12355
|
ctx.textBaseline = "middle";
|
|
12144
12356
|
ctx.fillText(shape.text, shape.x, shape.y);
|
|
@@ -12180,7 +12392,7 @@ function drawShape(ctx, shape, width, height, allShapes) {
|
|
|
12180
12392
|
}
|
|
12181
12393
|
ctx.restore();
|
|
12182
12394
|
}
|
|
12183
|
-
function readoutShapes(readouts, width) {
|
|
12395
|
+
function readoutShapes(readouts, width, fontFamily) {
|
|
12184
12396
|
const out = [];
|
|
12185
12397
|
const chipH = 18;
|
|
12186
12398
|
const gap = 6;
|
|
@@ -12204,13 +12416,14 @@ function readoutShapes(readouts, width) {
|
|
|
12204
12416
|
text,
|
|
12205
12417
|
color: "#ffffff",
|
|
12206
12418
|
fontSize: 10,
|
|
12207
|
-
align: "center"
|
|
12419
|
+
align: "center",
|
|
12420
|
+
fontFamily
|
|
12208
12421
|
});
|
|
12209
12422
|
rightEdge = chipX - gap;
|
|
12210
12423
|
}
|
|
12211
12424
|
return out;
|
|
12212
12425
|
}
|
|
12213
|
-
function traceShapes(panel, k, width, height) {
|
|
12426
|
+
function traceShapes(panel, k, width, height, fontFamily) {
|
|
12214
12427
|
const w = panel.width ?? Math.round(width * 0.32);
|
|
12215
12428
|
const h = panel.height ?? Math.round(height * 0.28);
|
|
12216
12429
|
const x = panel.x ?? width - w - 8;
|
|
@@ -12264,14 +12477,14 @@ function traceShapes(panel, k, width, height) {
|
|
|
12264
12477
|
out.push({ type: "circle", x: last.x, y: last.y, radius: 2, color, fill: color });
|
|
12265
12478
|
}
|
|
12266
12479
|
if (series.label) {
|
|
12267
|
-
out.push({ type: "text", x: x + 6, y: y + 10 + 11 * j, text: series.label, color, fontSize: 9 });
|
|
12480
|
+
out.push({ type: "text", x: x + 6, y: y + 10 + 11 * j, text: series.label, color, fontSize: 9, fontFamily });
|
|
12268
12481
|
}
|
|
12269
12482
|
});
|
|
12270
12483
|
if (panel.yLabel) {
|
|
12271
|
-
out.push({ type: "text", x: x + w - 6, y: y + 10, text: panel.yLabel, color: "#6b7280", fontSize: 9, align: "right" });
|
|
12484
|
+
out.push({ type: "text", x: x + w - 6, y: y + 10, text: panel.yLabel, color: "#6b7280", fontSize: 9, align: "right", fontFamily });
|
|
12272
12485
|
}
|
|
12273
12486
|
if (panel.xLabel) {
|
|
12274
|
-
out.push({ type: "text", x: x + w - 6, y: y + h - 6, text: panel.xLabel, color: "#6b7280", fontSize: 9, align: "right" });
|
|
12487
|
+
out.push({ type: "text", x: x + w - 6, y: y + h - 6, text: panel.xLabel, color: "#6b7280", fontSize: 9, align: "right", fontFamily });
|
|
12275
12488
|
}
|
|
12276
12489
|
return out;
|
|
12277
12490
|
}
|
|
@@ -12294,13 +12507,14 @@ var init_LearningCanvas = __esm({
|
|
|
12294
12507
|
init_useEventBus();
|
|
12295
12508
|
init_webPainter2d();
|
|
12296
12509
|
init_paintDispatch();
|
|
12297
|
-
DASH_PATTERNS = { dashed: [6, 4], dotted: [2, 3] };
|
|
12510
|
+
DASH_PATTERNS = { solid: [], dashed: [6, 4], dotted: [2, 3] };
|
|
12298
12511
|
TRACE_SERIES_COLORS = ["#2563eb", "#dc2626", "#16a34a", "#f59e0b"];
|
|
12299
12512
|
LearningCanvas = ({
|
|
12300
12513
|
className,
|
|
12301
12514
|
width = 600,
|
|
12302
12515
|
height = 400,
|
|
12303
12516
|
backgroundColor,
|
|
12517
|
+
fontFamily,
|
|
12304
12518
|
shapes = [],
|
|
12305
12519
|
drawables,
|
|
12306
12520
|
projector,
|
|
@@ -12336,10 +12550,10 @@ var init_LearningCanvas = __esm({
|
|
|
12336
12550
|
}, [shapes]);
|
|
12337
12551
|
const derivedShapes = React89.useMemo(() => {
|
|
12338
12552
|
if (!traces?.length && !readouts?.length) return shapes;
|
|
12339
|
-
const traceOut = (traces ?? []).flatMap((panel, k) => traceShapes(panel, k, width, height));
|
|
12340
|
-
const readoutOut = readouts?.length ? readoutShapes(readouts, width) : [];
|
|
12553
|
+
const traceOut = (traces ?? []).flatMap((panel, k) => traceShapes(panel, k, width, height, fontFamily));
|
|
12554
|
+
const readoutOut = readouts?.length ? readoutShapes(readouts, width, fontFamily) : [];
|
|
12341
12555
|
return [...shapes, ...traceOut, ...readoutOut];
|
|
12342
|
-
}, [shapes, traces, readouts, width, height]);
|
|
12556
|
+
}, [shapes, traces, readouts, width, height, fontFamily]);
|
|
12343
12557
|
const draw = React89.useCallback(() => {
|
|
12344
12558
|
const _perfT = ui.perfStart("learningcanvas:paint");
|
|
12345
12559
|
const canvas = canvasRef.current;
|
|
@@ -12358,15 +12572,15 @@ var init_LearningCanvas = __esm({
|
|
|
12358
12572
|
ctx.fillRect(0, 0, width, height);
|
|
12359
12573
|
}
|
|
12360
12574
|
for (const shape of derivedShapes) {
|
|
12361
|
-
if (shape.type !== "text") drawShape(ctx, shape, width, height, derivedShapes);
|
|
12575
|
+
if (shape.type !== "text") drawShape(ctx, shape, width, height, derivedShapes, fontFamily);
|
|
12362
12576
|
}
|
|
12363
12577
|
for (const shape of derivedShapes) {
|
|
12364
|
-
if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes);
|
|
12578
|
+
if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes, fontFamily);
|
|
12365
12579
|
}
|
|
12366
12580
|
if (drawables?.length && projector) {
|
|
12367
12581
|
const painter = createWebPainter(ctx, invalidateRef.current);
|
|
12368
12582
|
const timeMs = needsAnim && typeof performance !== "undefined" ? performance.now() : 0;
|
|
12369
|
-
const dctx = { projector, time: timeMs, invalidate: invalidateRef.current, fontFamily: themeBodyFont(canvas) };
|
|
12583
|
+
const dctx = { projector, time: timeMs, invalidate: invalidateRef.current, fontFamily: fontFamily || themeBodyFont(canvas) };
|
|
12370
12584
|
for (const node of drawables) {
|
|
12371
12585
|
paintDrawable(painter, node, dctx);
|
|
12372
12586
|
}
|
|
@@ -17348,6 +17562,250 @@ var init_EmptyState = __esm({
|
|
|
17348
17562
|
EmptyState.displayName = "EmptyState";
|
|
17349
17563
|
}
|
|
17350
17564
|
});
|
|
17565
|
+
|
|
17566
|
+
// lib/editorMotions.ts
|
|
17567
|
+
function clamp(value, min, max) {
|
|
17568
|
+
return Math.max(min, Math.min(max, value));
|
|
17569
|
+
}
|
|
17570
|
+
function computeLines(text) {
|
|
17571
|
+
const lines = [];
|
|
17572
|
+
let start = 0;
|
|
17573
|
+
for (let i = 0; i <= text.length; i++) {
|
|
17574
|
+
if (i === text.length || text[i] === "\n") {
|
|
17575
|
+
lines.push({ start, end: i });
|
|
17576
|
+
start = i + 1;
|
|
17577
|
+
}
|
|
17578
|
+
}
|
|
17579
|
+
return lines;
|
|
17580
|
+
}
|
|
17581
|
+
function lineIndexAt(lines, pos) {
|
|
17582
|
+
for (let i = 0; i < lines.length; i++) {
|
|
17583
|
+
if (pos <= lines[i].end) return i;
|
|
17584
|
+
}
|
|
17585
|
+
return lines.length - 1;
|
|
17586
|
+
}
|
|
17587
|
+
function findWords(text) {
|
|
17588
|
+
const words = [];
|
|
17589
|
+
const re = /\w+|\S+/g;
|
|
17590
|
+
let m;
|
|
17591
|
+
while ((m = re.exec(text)) !== null) {
|
|
17592
|
+
words.push({ start: m.index, end: m.index + m[0].length });
|
|
17593
|
+
}
|
|
17594
|
+
return words;
|
|
17595
|
+
}
|
|
17596
|
+
function nextWordStart(text, pos) {
|
|
17597
|
+
for (const w of findWords(text)) {
|
|
17598
|
+
if (w.start > pos) return w.start;
|
|
17599
|
+
}
|
|
17600
|
+
return text.length;
|
|
17601
|
+
}
|
|
17602
|
+
function prevWordStart(text, pos) {
|
|
17603
|
+
let result = 0;
|
|
17604
|
+
for (const w of findWords(text)) {
|
|
17605
|
+
if (w.start < pos) result = w.start;
|
|
17606
|
+
else break;
|
|
17607
|
+
}
|
|
17608
|
+
return result;
|
|
17609
|
+
}
|
|
17610
|
+
function nextWordEnd(text, pos) {
|
|
17611
|
+
for (const w of findWords(text)) {
|
|
17612
|
+
const lastChar = w.end - 1;
|
|
17613
|
+
if (lastChar > pos) return lastChar;
|
|
17614
|
+
}
|
|
17615
|
+
return text.length > 0 ? text.length - 1 : 0;
|
|
17616
|
+
}
|
|
17617
|
+
function firstNonBlank(text, line) {
|
|
17618
|
+
let i = line.start;
|
|
17619
|
+
while (i < line.end && (text[i] === " " || text[i] === " ")) i++;
|
|
17620
|
+
return i;
|
|
17621
|
+
}
|
|
17622
|
+
function nextParagraphBoundary(lines, fromLineIdx, textLength) {
|
|
17623
|
+
for (let i = fromLineIdx + 1; i < lines.length; i++) {
|
|
17624
|
+
if (lines[i].start === lines[i].end) return lines[i].start;
|
|
17625
|
+
}
|
|
17626
|
+
return textLength;
|
|
17627
|
+
}
|
|
17628
|
+
function prevParagraphBoundary(lines, fromLineIdx) {
|
|
17629
|
+
for (let i = fromLineIdx - 1; i >= 0; i--) {
|
|
17630
|
+
if (lines[i].start === lines[i].end) return lines[i].start;
|
|
17631
|
+
}
|
|
17632
|
+
return 0;
|
|
17633
|
+
}
|
|
17634
|
+
function applyMotion(text, caret, motion, count) {
|
|
17635
|
+
const n = Math.max(1, count);
|
|
17636
|
+
const lines = computeLines(text);
|
|
17637
|
+
const lineIdx = lineIndexAt(lines, caret);
|
|
17638
|
+
const line = lines[lineIdx];
|
|
17639
|
+
switch (motion) {
|
|
17640
|
+
case "left":
|
|
17641
|
+
return clamp(caret - n, line.start, line.end);
|
|
17642
|
+
case "right":
|
|
17643
|
+
return clamp(caret + n, line.start, line.end);
|
|
17644
|
+
case "up": {
|
|
17645
|
+
const col = caret - line.start;
|
|
17646
|
+
const targetIdx = clamp(lineIdx - n, 0, lines.length - 1);
|
|
17647
|
+
const target = lines[targetIdx];
|
|
17648
|
+
return clamp(target.start + col, target.start, target.end);
|
|
17649
|
+
}
|
|
17650
|
+
case "down": {
|
|
17651
|
+
const col = caret - line.start;
|
|
17652
|
+
const targetIdx = clamp(lineIdx + n, 0, lines.length - 1);
|
|
17653
|
+
const target = lines[targetIdx];
|
|
17654
|
+
return clamp(target.start + col, target.start, target.end);
|
|
17655
|
+
}
|
|
17656
|
+
case "word-forward": {
|
|
17657
|
+
let pos = caret;
|
|
17658
|
+
for (let i = 0; i < n; i++) pos = nextWordStart(text, pos);
|
|
17659
|
+
return pos;
|
|
17660
|
+
}
|
|
17661
|
+
case "word-back": {
|
|
17662
|
+
let pos = caret;
|
|
17663
|
+
for (let i = 0; i < n; i++) pos = prevWordStart(text, pos);
|
|
17664
|
+
return pos;
|
|
17665
|
+
}
|
|
17666
|
+
case "word-end": {
|
|
17667
|
+
let pos = caret;
|
|
17668
|
+
for (let i = 0; i < n; i++) pos = nextWordEnd(text, pos);
|
|
17669
|
+
return pos;
|
|
17670
|
+
}
|
|
17671
|
+
case "line-start":
|
|
17672
|
+
return line.start;
|
|
17673
|
+
case "line-end":
|
|
17674
|
+
return line.end > line.start ? line.end - 1 : line.start;
|
|
17675
|
+
case "first-nonblank":
|
|
17676
|
+
return firstNonBlank(text, line);
|
|
17677
|
+
case "doc-start":
|
|
17678
|
+
return 0;
|
|
17679
|
+
case "doc-end":
|
|
17680
|
+
return text.length;
|
|
17681
|
+
case "paragraph-forward": {
|
|
17682
|
+
let pos = caret;
|
|
17683
|
+
for (let i = 0; i < n; i++) {
|
|
17684
|
+
pos = nextParagraphBoundary(lines, lineIndexAt(lines, pos), text.length);
|
|
17685
|
+
}
|
|
17686
|
+
return pos;
|
|
17687
|
+
}
|
|
17688
|
+
case "paragraph-back": {
|
|
17689
|
+
let pos = caret;
|
|
17690
|
+
for (let i = 0; i < n; i++) {
|
|
17691
|
+
pos = prevParagraphBoundary(lines, lineIndexAt(lines, pos));
|
|
17692
|
+
}
|
|
17693
|
+
return pos;
|
|
17694
|
+
}
|
|
17695
|
+
case "line":
|
|
17696
|
+
case "selection":
|
|
17697
|
+
return caret;
|
|
17698
|
+
default: {
|
|
17699
|
+
const _exhaustive = motion;
|
|
17700
|
+
return _exhaustive;
|
|
17701
|
+
}
|
|
17702
|
+
}
|
|
17703
|
+
}
|
|
17704
|
+
function motionRange(text, caret, motion, count, selection) {
|
|
17705
|
+
if (motion === "selection") {
|
|
17706
|
+
if (!selection) return [caret, caret];
|
|
17707
|
+
return [Math.min(selection[0], selection[1]), Math.max(selection[0], selection[1])];
|
|
17708
|
+
}
|
|
17709
|
+
const lines = computeLines(text);
|
|
17710
|
+
if (motion === "line") {
|
|
17711
|
+
const n = Math.max(1, count);
|
|
17712
|
+
const startIdx = lineIndexAt(lines, caret);
|
|
17713
|
+
const endIdx = clamp(startIdx + n - 1, 0, lines.length - 1);
|
|
17714
|
+
const start2 = lines[startIdx].start;
|
|
17715
|
+
const rawEnd = lines[endIdx].end;
|
|
17716
|
+
const end2 = rawEnd < text.length ? rawEnd + 1 : rawEnd;
|
|
17717
|
+
return [start2, end2];
|
|
17718
|
+
}
|
|
17719
|
+
const newCaret = applyMotion(text, caret, motion, count);
|
|
17720
|
+
let start = Math.min(caret, newCaret);
|
|
17721
|
+
let end = Math.max(caret, newCaret);
|
|
17722
|
+
if (motion === "word-end" || motion === "line-end") {
|
|
17723
|
+
end = Math.min(Math.max(start, newCaret) + 1, text.length);
|
|
17724
|
+
} else if (motion === "word-forward" && newCaret > caret) {
|
|
17725
|
+
const startLine = lineIndexAt(lines, caret);
|
|
17726
|
+
const endLine = lineIndexAt(lines, newCaret);
|
|
17727
|
+
if (endLine !== startLine) {
|
|
17728
|
+
end = lines[startLine].end;
|
|
17729
|
+
}
|
|
17730
|
+
}
|
|
17731
|
+
return [start, end];
|
|
17732
|
+
}
|
|
17733
|
+
function applyOperator(text, range, operator, register) {
|
|
17734
|
+
const start = clamp(range[0], 0, text.length);
|
|
17735
|
+
const end = clamp(range[1], start, text.length);
|
|
17736
|
+
const removed = text.slice(start, end);
|
|
17737
|
+
if (operator === "yank") {
|
|
17738
|
+
return { text, caret: start, register: removed };
|
|
17739
|
+
}
|
|
17740
|
+
return { text: text.slice(0, start) + text.slice(end), caret: start, register: removed };
|
|
17741
|
+
}
|
|
17742
|
+
var init_editorMotions = __esm({
|
|
17743
|
+
"lib/editorMotions.ts"() {
|
|
17744
|
+
}
|
|
17745
|
+
});
|
|
17746
|
+
function isMotionPayload(payload) {
|
|
17747
|
+
return !!payload && typeof payload.editorId === "string" && typeof payload.motion === "string" && typeof payload.count === "number";
|
|
17748
|
+
}
|
|
17749
|
+
function isOperatePayload(payload) {
|
|
17750
|
+
return !!payload && typeof payload.editorId === "string" && typeof payload.operator === "string" && typeof payload.motion === "string" && typeof payload.count === "number";
|
|
17751
|
+
}
|
|
17752
|
+
function isInsertTextPayload(payload) {
|
|
17753
|
+
return !!payload && typeof payload.editorId === "string" && typeof payload.text === "string";
|
|
17754
|
+
}
|
|
17755
|
+
function isSetModePayload(payload) {
|
|
17756
|
+
return !!payload && typeof payload.editorId === "string" && typeof payload.mode === "string" && typeof payload.caret === "string";
|
|
17757
|
+
}
|
|
17758
|
+
function useEditorCapabilities(args) {
|
|
17759
|
+
const [caretMode, setCaretMode] = React89.useState("bar");
|
|
17760
|
+
const registerRef = React89.useRef("");
|
|
17761
|
+
useEventListener(`UI:${args.events.onMotion}`, (evt) => {
|
|
17762
|
+
if (!args.editorId || !isMotionPayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
|
|
17763
|
+
const ta = args.textareaRef.current;
|
|
17764
|
+
if (!ta) return;
|
|
17765
|
+
const { motion, count } = evt.payload;
|
|
17766
|
+
const newCaret = applyMotion(ta.value, ta.selectionStart, motion, count);
|
|
17767
|
+
if (ta.selectionStart !== ta.selectionEnd) {
|
|
17768
|
+
ta.setSelectionRange(ta.selectionStart, newCaret);
|
|
17769
|
+
} else {
|
|
17770
|
+
ta.setSelectionRange(newCaret, newCaret);
|
|
17771
|
+
}
|
|
17772
|
+
});
|
|
17773
|
+
useEventListener(`UI:${args.events.onOperate}`, (evt) => {
|
|
17774
|
+
if (!args.editorId || !isOperatePayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
|
|
17775
|
+
const ta = args.textareaRef.current;
|
|
17776
|
+
if (!ta) return;
|
|
17777
|
+
const { operator, motion, count } = evt.payload;
|
|
17778
|
+
const selection = motion === "selection" ? [ta.selectionStart, ta.selectionEnd] : void 0;
|
|
17779
|
+
const range = motionRange(ta.value, ta.selectionStart, motion, count, selection);
|
|
17780
|
+
const result = applyOperator(ta.value, range, operator, registerRef.current);
|
|
17781
|
+
registerRef.current = result.register;
|
|
17782
|
+
if (operator === "yank") {
|
|
17783
|
+
ta.setSelectionRange(range[0], range[0]);
|
|
17784
|
+
} else {
|
|
17785
|
+
ta.setRangeText("", range[0], range[1], "end");
|
|
17786
|
+
}
|
|
17787
|
+
args.applyChange(ta.value);
|
|
17788
|
+
});
|
|
17789
|
+
useEventListener(`UI:${args.events.onInsertText}`, (evt) => {
|
|
17790
|
+
if (!args.editorId || !isInsertTextPayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
|
|
17791
|
+
const ta = args.textareaRef.current;
|
|
17792
|
+
if (!ta) return;
|
|
17793
|
+
ta.setRangeText(evt.payload.text, ta.selectionStart, ta.selectionEnd, "end");
|
|
17794
|
+
args.applyChange(ta.value);
|
|
17795
|
+
});
|
|
17796
|
+
useEventListener(`UI:${args.events.onSetMode}`, (evt) => {
|
|
17797
|
+
if (!args.editorId || !isSetModePayload(evt.payload) || evt.payload.editorId !== args.editorId) return;
|
|
17798
|
+
setCaretMode(evt.payload.caret);
|
|
17799
|
+
});
|
|
17800
|
+
return { caretMode };
|
|
17801
|
+
}
|
|
17802
|
+
var init_useEditorCapabilities = __esm({
|
|
17803
|
+
"components/core/molecules/markdown/useEditorCapabilities.ts"() {
|
|
17804
|
+
"use client";
|
|
17805
|
+
init_useEventBus();
|
|
17806
|
+
init_editorMotions();
|
|
17807
|
+
}
|
|
17808
|
+
});
|
|
17351
17809
|
function isLanguageRegistered(lang) {
|
|
17352
17810
|
return CODE_LANGUAGE_SET.has(lang) || dynamicallyLoaded.has(lang);
|
|
17353
17811
|
}
|
|
@@ -17433,7 +17891,36 @@ function useLanguageReady(language) {
|
|
|
17433
17891
|
}, [language]);
|
|
17434
17892
|
return ready;
|
|
17435
17893
|
}
|
|
17436
|
-
|
|
17894
|
+
function resolveHighlightStyle(lang) {
|
|
17895
|
+
if (lang === "orb") return orbStyle;
|
|
17896
|
+
if (lang === "lolo") return loloStyle;
|
|
17897
|
+
return dark__default.default;
|
|
17898
|
+
}
|
|
17899
|
+
function plainCodeColorOf(style) {
|
|
17900
|
+
return style['code[class*="language-"]']?.color ?? "#d4d4d4";
|
|
17901
|
+
}
|
|
17902
|
+
function buildLineProps(errorLines, extraClassName) {
|
|
17903
|
+
return (lineNumber) => {
|
|
17904
|
+
const base = {
|
|
17905
|
+
"data-line": String(lineNumber - 1),
|
|
17906
|
+
...extraClassName ? { className: extraClassName } : {}
|
|
17907
|
+
};
|
|
17908
|
+
const severity = errorLines?.get(lineNumber);
|
|
17909
|
+
if (!severity) return base;
|
|
17910
|
+
return {
|
|
17911
|
+
...base,
|
|
17912
|
+
style: {
|
|
17913
|
+
display: "block",
|
|
17914
|
+
backgroundColor: severity === "error" ? "rgba(248, 113, 113, 0.18)" : "rgba(251, 191, 36, 0.18)",
|
|
17915
|
+
// amber-400 @ 18%
|
|
17916
|
+
borderLeft: `3px solid ${severity === "error" ? "#ef4444" : "#f59e0b"}`,
|
|
17917
|
+
paddingLeft: "0.5rem",
|
|
17918
|
+
marginLeft: "-0.5rem"
|
|
17919
|
+
}
|
|
17920
|
+
};
|
|
17921
|
+
};
|
|
17922
|
+
}
|
|
17923
|
+
var dynamicallyLoaded, codeLanguageLoader, orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log7, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, DIFF_STYLE_FALLBACK, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, HIGHLIGHT_CAPACITY_BYTES, MONO_FONT_FAMILY, VIEWER_LINE_NUMBER_STYLE, CodeBlock;
|
|
17437
17924
|
var init_CodeBlock = __esm({
|
|
17438
17925
|
"components/core/molecules/markdown/CodeBlock.tsx"() {
|
|
17439
17926
|
init_cn();
|
|
@@ -17449,6 +17936,7 @@ var init_CodeBlock = __esm({
|
|
|
17449
17936
|
init_Textarea();
|
|
17450
17937
|
init_Icon();
|
|
17451
17938
|
init_useEventBus();
|
|
17939
|
+
init_useEditorCapabilities();
|
|
17452
17940
|
SyntaxHighlighter__default.default.registerLanguage("json", langJson__default.default);
|
|
17453
17941
|
SyntaxHighlighter__default.default.registerLanguage("javascript", langJavascript__default.default);
|
|
17454
17942
|
SyntaxHighlighter__default.default.registerLanguage("js", langJavascript__default.default);
|
|
@@ -17667,6 +18155,15 @@ var init_CodeBlock = __esm({
|
|
|
17667
18155
|
LINE_PROPS_FN = (n) => ({ "data-line": String(n - 1) });
|
|
17668
18156
|
HIDDEN_LINE_NUMBERS = { display: "none" };
|
|
17669
18157
|
HIGHLIGHT_CAPACITY_BYTES = 512 * 1024;
|
|
18158
|
+
MONO_FONT_FAMILY = 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace';
|
|
18159
|
+
VIEWER_LINE_NUMBER_STYLE = {
|
|
18160
|
+
minWidth: "2.5em",
|
|
18161
|
+
paddingRight: "1rem",
|
|
18162
|
+
textAlign: "right",
|
|
18163
|
+
userSelect: "none",
|
|
18164
|
+
opacity: 0.5,
|
|
18165
|
+
fontVariantNumeric: "tabular-nums"
|
|
18166
|
+
};
|
|
17670
18167
|
CodeBlock = React89__namespace.default.memo(
|
|
17671
18168
|
({
|
|
17672
18169
|
code: rawCode,
|
|
@@ -17691,15 +18188,39 @@ var init_CodeBlock = __esm({
|
|
|
17691
18188
|
actions,
|
|
17692
18189
|
isLoading = false,
|
|
17693
18190
|
error,
|
|
17694
|
-
showCopy
|
|
18191
|
+
showCopy,
|
|
18192
|
+
// editor capability surface — P1 wires these
|
|
18193
|
+
editorId,
|
|
18194
|
+
onEditorFocus = "EDITOR_FOCUS",
|
|
18195
|
+
onEditorBlur = "EDITOR_BLUR",
|
|
18196
|
+
onMotion = "MOTION",
|
|
18197
|
+
onOperate = "OPERATE",
|
|
18198
|
+
onInsertText = "INSERT_TEXT",
|
|
18199
|
+
onSetMode = "SET_MODE",
|
|
18200
|
+
motions = [
|
|
18201
|
+
"left",
|
|
18202
|
+
"right",
|
|
18203
|
+
"up",
|
|
18204
|
+
"down",
|
|
18205
|
+
"word-forward",
|
|
18206
|
+
"word-back",
|
|
18207
|
+
"word-end",
|
|
18208
|
+
"line-start",
|
|
18209
|
+
"line-end",
|
|
18210
|
+
"first-nonblank",
|
|
18211
|
+
"doc-start",
|
|
18212
|
+
"doc-end",
|
|
18213
|
+
"paragraph-forward",
|
|
18214
|
+
"paragraph-back",
|
|
18215
|
+
"line",
|
|
18216
|
+
"selection"
|
|
18217
|
+
],
|
|
18218
|
+
operators = ["delete", "yank", "change"]
|
|
17695
18219
|
}) => {
|
|
17696
18220
|
const code = typeof rawCode === "string" ? rawCode : String(rawCode ?? "");
|
|
17697
|
-
const
|
|
17698
|
-
const isLolo = language === "lolo";
|
|
17699
|
-
const activeStyle = isOrb ? orbStyle : isLolo ? loloStyle : dark__default.default;
|
|
18221
|
+
const activeStyle = resolveHighlightStyle(language);
|
|
17700
18222
|
const overCapacity = code.length > HIGHLIGHT_CAPACITY_BYTES;
|
|
17701
|
-
const plainCodeColor = activeStyle
|
|
17702
|
-
const languageReady = useLanguageReady(language);
|
|
18223
|
+
const plainCodeColor = plainCodeColorOf(activeStyle);
|
|
17703
18224
|
const eventBus = useEventBus();
|
|
17704
18225
|
const { t } = hooks.useTranslate();
|
|
17705
18226
|
const scrollRef = React89.useRef(null);
|
|
@@ -17711,6 +18232,9 @@ var init_CodeBlock = __esm({
|
|
|
17711
18232
|
const activeFile = files?.[activeFileIndex];
|
|
17712
18233
|
const activeCode = activeFile?.code ?? code;
|
|
17713
18234
|
const activeLanguage = activeFile?.language ?? language;
|
|
18235
|
+
const languageReady = useLanguageReady(activeLanguage);
|
|
18236
|
+
const viewerStyle = resolveHighlightStyle(activeLanguage);
|
|
18237
|
+
const viewerPlainCodeColor = plainCodeColorOf(viewerStyle);
|
|
17714
18238
|
const diffLines = React89.useMemo(() => {
|
|
17715
18239
|
if (propDiff) return propDiff;
|
|
17716
18240
|
if (mode === "diff" && oldValue !== void 0 && newValue !== void 0) {
|
|
@@ -17740,28 +18264,28 @@ var init_CodeBlock = __esm({
|
|
|
17740
18264
|
ov.scrollLeft = ta.scrollLeft;
|
|
17741
18265
|
}
|
|
17742
18266
|
}, []);
|
|
17743
|
-
const
|
|
17744
|
-
|
|
17745
|
-
|
|
17746
|
-
|
|
17747
|
-
|
|
17748
|
-
|
|
17749
|
-
|
|
17750
|
-
|
|
17751
|
-
|
|
17752
|
-
|
|
17753
|
-
|
|
17754
|
-
|
|
17755
|
-
|
|
17756
|
-
|
|
17757
|
-
|
|
17758
|
-
|
|
17759
|
-
|
|
17760
|
-
|
|
17761
|
-
|
|
17762
|
-
|
|
17763
|
-
|
|
17764
|
-
|
|
18267
|
+
const handleEditableChange = React89.useCallback((v) => {
|
|
18268
|
+
lastPropCodeRef.current = v;
|
|
18269
|
+
setEditableValue(v);
|
|
18270
|
+
onChange?.(v);
|
|
18271
|
+
}, [onChange]);
|
|
18272
|
+
const { caretMode } = useEditorCapabilities({
|
|
18273
|
+
editorId: editable ? editorId : void 0,
|
|
18274
|
+
textareaRef: editableTextareaRef,
|
|
18275
|
+
events: { onMotion, onOperate, onInsertText, onSetMode },
|
|
18276
|
+
applyChange: handleEditableChange
|
|
18277
|
+
});
|
|
18278
|
+
const [caretIndex, setCaretIndex] = React89.useState(0);
|
|
18279
|
+
const caretRowCol = React89.useMemo(() => {
|
|
18280
|
+
const before = editableValue.slice(0, Math.min(caretIndex, editableValue.length));
|
|
18281
|
+
const lines = before.split("\n");
|
|
18282
|
+
return { row: lines.length - 1, col: lines[lines.length - 1].length };
|
|
18283
|
+
}, [editableValue, caretIndex]);
|
|
18284
|
+
const errorLineProps = React89.useMemo(() => buildLineProps(errorLines), [errorLines]);
|
|
18285
|
+
const viewerLineProps = React89.useMemo(
|
|
18286
|
+
() => buildLineProps(errorLines, "px-4 py-0.5 hover:bg-muted/50"),
|
|
18287
|
+
[errorLines]
|
|
18288
|
+
);
|
|
17765
18289
|
const isFoldable = foldableProp ?? true;
|
|
17766
18290
|
const [collapsed, setCollapsed] = React89.useState(() => /* @__PURE__ */ new Set());
|
|
17767
18291
|
const foldRegions = React89.useMemo(
|
|
@@ -17884,6 +18408,110 @@ var init_CodeBlock = __esm({
|
|
|
17884
18408
|
),
|
|
17885
18409
|
[code, overCapacity, plainCodeColor, language, activeStyle, languageReady]
|
|
17886
18410
|
);
|
|
18411
|
+
const viewerOverCapacity = activeCode.length > HIGHLIGHT_CAPACITY_BYTES;
|
|
18412
|
+
const viewerHighlightedElement = React89.useMemo(
|
|
18413
|
+
() => viewerOverCapacity ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
18414
|
+
"div",
|
|
18415
|
+
{
|
|
18416
|
+
className: "px-4 py-0.5",
|
|
18417
|
+
style: {
|
|
18418
|
+
margin: 0,
|
|
18419
|
+
whiteSpace: wrap ? "pre-wrap" : "pre",
|
|
18420
|
+
wordBreak: wrap ? "break-all" : "normal",
|
|
18421
|
+
color: viewerPlainCodeColor,
|
|
18422
|
+
fontFamily: MONO_FONT_FAMILY,
|
|
18423
|
+
fontSize: "12px",
|
|
18424
|
+
lineHeight: "1.6"
|
|
18425
|
+
},
|
|
18426
|
+
children: activeCode
|
|
18427
|
+
}
|
|
18428
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
18429
|
+
SyntaxHighlighter__default.default,
|
|
18430
|
+
{
|
|
18431
|
+
PreTag: "div",
|
|
18432
|
+
language: activeLanguage,
|
|
18433
|
+
style: viewerStyle,
|
|
18434
|
+
wrapLines: true,
|
|
18435
|
+
wrapLongLines: wrap,
|
|
18436
|
+
showLineNumbers,
|
|
18437
|
+
lineNumberStyle: VIEWER_LINE_NUMBER_STYLE,
|
|
18438
|
+
lineProps: viewerLineProps,
|
|
18439
|
+
customStyle: {
|
|
18440
|
+
backgroundColor: "transparent",
|
|
18441
|
+
borderRadius: 0,
|
|
18442
|
+
padding: "0.25rem 0",
|
|
18443
|
+
margin: 0,
|
|
18444
|
+
whiteSpace: wrap ? "pre-wrap" : "pre",
|
|
18445
|
+
wordBreak: wrap ? "break-all" : "normal",
|
|
18446
|
+
fontFamily: MONO_FONT_FAMILY,
|
|
18447
|
+
fontSize: "12px",
|
|
18448
|
+
lineHeight: "1.6"
|
|
18449
|
+
},
|
|
18450
|
+
codeTagProps: { style: { fontFamily: MONO_FONT_FAMILY, fontSize: "12px", lineHeight: "1.6" } },
|
|
18451
|
+
children: activeCode
|
|
18452
|
+
}
|
|
18453
|
+
),
|
|
18454
|
+
[activeCode, viewerOverCapacity, viewerPlainCodeColor, activeLanguage, viewerStyle, wrap, showLineNumbers, viewerLineProps, languageReady]
|
|
18455
|
+
);
|
|
18456
|
+
const diffOverCapacity = React89.useMemo(
|
|
18457
|
+
() => !!diffLines && diffLines.reduce((n, l) => n + l.content.length + 1, 0) > HIGHLIGHT_CAPACITY_BYTES,
|
|
18458
|
+
[diffLines]
|
|
18459
|
+
);
|
|
18460
|
+
const diffRowElements = React89.useMemo(() => {
|
|
18461
|
+
if (!diffLines) return null;
|
|
18462
|
+
return diffLines.map((line, idx) => {
|
|
18463
|
+
const style = DIFF_STYLES[line.type] ?? DIFF_STYLE_FALLBACK;
|
|
18464
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "none", align: "start", className: cn(style.bg, "px-4 py-0.5"), children: [
|
|
18465
|
+
showLineNumbers && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18466
|
+
Typography,
|
|
18467
|
+
{
|
|
18468
|
+
variant: "caption",
|
|
18469
|
+
color: "secondary",
|
|
18470
|
+
className: "w-8 text-right mr-3 select-none tabular-nums flex-shrink-0",
|
|
18471
|
+
children: line.lineNumber ?? ""
|
|
18472
|
+
}
|
|
18473
|
+
),
|
|
18474
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18475
|
+
Typography,
|
|
18476
|
+
{
|
|
18477
|
+
variant: "caption",
|
|
18478
|
+
className: cn("font-mono flex-1 min-w-0", style.text, wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"),
|
|
18479
|
+
children: [
|
|
18480
|
+
/* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", className: "select-none opacity-50 mr-2", children: style.prefix }),
|
|
18481
|
+
diffOverCapacity ? line.content || " " : /* @__PURE__ */ jsxRuntime.jsx(
|
|
18482
|
+
SyntaxHighlighter__default.default,
|
|
18483
|
+
{
|
|
18484
|
+
PreTag: "span",
|
|
18485
|
+
CodeTag: "span",
|
|
18486
|
+
language: activeLanguage,
|
|
18487
|
+
style: viewerStyle,
|
|
18488
|
+
customStyle: {
|
|
18489
|
+
display: "inline",
|
|
18490
|
+
background: "transparent",
|
|
18491
|
+
padding: 0,
|
|
18492
|
+
margin: 0,
|
|
18493
|
+
whiteSpace: wrap ? "pre-wrap" : "pre",
|
|
18494
|
+
wordBreak: wrap ? "break-all" : "normal",
|
|
18495
|
+
fontFamily: "inherit",
|
|
18496
|
+
fontSize: "inherit",
|
|
18497
|
+
lineHeight: "inherit"
|
|
18498
|
+
},
|
|
18499
|
+
codeTagProps: {
|
|
18500
|
+
style: {
|
|
18501
|
+
whiteSpace: wrap ? "pre-wrap" : "pre",
|
|
18502
|
+
fontFamily: "inherit",
|
|
18503
|
+
fontSize: "inherit"
|
|
18504
|
+
}
|
|
18505
|
+
},
|
|
18506
|
+
children: line.content || " "
|
|
18507
|
+
}
|
|
18508
|
+
)
|
|
18509
|
+
]
|
|
18510
|
+
}
|
|
18511
|
+
)
|
|
18512
|
+
] }, idx);
|
|
18513
|
+
});
|
|
18514
|
+
}, [diffLines, showLineNumbers, wrap, diffOverCapacity, activeLanguage, viewerStyle, languageReady]);
|
|
17887
18515
|
React89.useLayoutEffect(() => {
|
|
17888
18516
|
const container = codeRef.current;
|
|
17889
18517
|
if (!container) return;
|
|
@@ -18027,7 +18655,6 @@ var init_CodeBlock = __esm({
|
|
|
18027
18655
|
label: file.label,
|
|
18028
18656
|
content: null
|
|
18029
18657
|
}));
|
|
18030
|
-
const lines = activeCode.split("\n");
|
|
18031
18658
|
return /* @__PURE__ */ jsxRuntime.jsx(Card, { className: cn("overflow-hidden", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
|
|
18032
18659
|
tabItems && tabItems.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
18033
18660
|
Tabs,
|
|
@@ -18090,49 +18717,7 @@ var init_CodeBlock = __esm({
|
|
|
18090
18717
|
]
|
|
18091
18718
|
}
|
|
18092
18719
|
),
|
|
18093
|
-
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "overflow-auto bg-muted/20", style: { maxHeight }, children: diffLines ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children:
|
|
18094
|
-
const style = DIFF_STYLES[line.type] ?? DIFF_STYLE_FALLBACK;
|
|
18095
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "none", align: "start", className: cn(style.bg, "px-4 py-0.5"), children: [
|
|
18096
|
-
showLineNumbers && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18097
|
-
Typography,
|
|
18098
|
-
{
|
|
18099
|
-
variant: "caption",
|
|
18100
|
-
color: "secondary",
|
|
18101
|
-
className: "w-8 text-right mr-3 select-none tabular-nums flex-shrink-0",
|
|
18102
|
-
children: line.lineNumber ?? ""
|
|
18103
|
-
}
|
|
18104
|
-
),
|
|
18105
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
18106
|
-
Typography,
|
|
18107
|
-
{
|
|
18108
|
-
variant: "caption",
|
|
18109
|
-
className: cn("font-mono flex-1 min-w-0", style.text, wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"),
|
|
18110
|
-
children: [
|
|
18111
|
-
/* @__PURE__ */ jsxRuntime.jsx(Box, { as: "span", className: "select-none opacity-50 mr-2", children: style.prefix }),
|
|
18112
|
-
line.content
|
|
18113
|
-
]
|
|
18114
|
-
}
|
|
18115
|
-
)
|
|
18116
|
-
] }, idx);
|
|
18117
|
-
}) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children: lines.map((line, idx) => /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "none", align: "start", className: "px-4 py-0.5 hover:bg-muted/50", children: [
|
|
18118
|
-
showLineNumbers && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18119
|
-
Typography,
|
|
18120
|
-
{
|
|
18121
|
-
variant: "caption",
|
|
18122
|
-
color: "secondary",
|
|
18123
|
-
className: "w-8 text-right mr-4 select-none tabular-nums flex-shrink-0",
|
|
18124
|
-
children: idx + 1
|
|
18125
|
-
}
|
|
18126
|
-
),
|
|
18127
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18128
|
-
Typography,
|
|
18129
|
-
{
|
|
18130
|
-
variant: "caption",
|
|
18131
|
-
className: cn("font-mono flex-1 min-w-0", wrap ? "whitespace-pre-wrap break-all" : "whitespace-pre"),
|
|
18132
|
-
children: line || " "
|
|
18133
|
-
}
|
|
18134
|
-
)
|
|
18135
|
-
] }, idx)) }) })
|
|
18720
|
+
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "overflow-auto bg-muted/20", style: { maxHeight }, children: diffLines ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, className: "font-mono text-xs", children: diffRowElements }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-xs", children: viewerHighlightedElement }) })
|
|
18136
18721
|
] }) });
|
|
18137
18722
|
}
|
|
18138
18723
|
const hasHeader = showLanguageBadge || effectiveCopy;
|
|
@@ -18219,13 +18804,11 @@ var init_CodeBlock = __esm({
|
|
|
18219
18804
|
{
|
|
18220
18805
|
ref: editableTextareaRef,
|
|
18221
18806
|
defaultValue: code,
|
|
18222
|
-
onChange: (e) =>
|
|
18223
|
-
const v = e.target.value;
|
|
18224
|
-
lastPropCodeRef.current = v;
|
|
18225
|
-
setEditableValue(v);
|
|
18226
|
-
onChange?.(v);
|
|
18227
|
-
},
|
|
18807
|
+
onChange: (e) => handleEditableChange(e.target.value),
|
|
18228
18808
|
onScroll: handleEditableScroll,
|
|
18809
|
+
onSelect: (e) => setCaretIndex(e.currentTarget.selectionStart),
|
|
18810
|
+
onFocus: editorId ? () => eventBus.emit(`UI:${onEditorFocus}`, { editorId }) : void 0,
|
|
18811
|
+
onBlur: editorId ? () => eventBus.emit(`UI:${onEditorBlur}`, { editorId }) : void 0,
|
|
18229
18812
|
spellCheck: false,
|
|
18230
18813
|
style: {
|
|
18231
18814
|
position: "absolute",
|
|
@@ -18240,7 +18823,7 @@ var init_CodeBlock = __esm({
|
|
|
18240
18823
|
resize: "none",
|
|
18241
18824
|
backgroundColor: "transparent",
|
|
18242
18825
|
color: "transparent",
|
|
18243
|
-
caretColor: "#e6e6e6",
|
|
18826
|
+
caretColor: caretMode === "block" ? "transparent" : "#e6e6e6",
|
|
18244
18827
|
WebkitTextFillColor: "transparent",
|
|
18245
18828
|
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
|
|
18246
18829
|
fontSize: "13px",
|
|
@@ -18251,6 +18834,22 @@ var init_CodeBlock = __esm({
|
|
|
18251
18834
|
}
|
|
18252
18835
|
},
|
|
18253
18836
|
editableTextareaKey
|
|
18837
|
+
),
|
|
18838
|
+
caretMode !== "bar" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18839
|
+
"span",
|
|
18840
|
+
{
|
|
18841
|
+
"aria-hidden": true,
|
|
18842
|
+
style: {
|
|
18843
|
+
position: "absolute",
|
|
18844
|
+
top: `calc(1rem + ${caretRowCol.row * 19.5}px)`,
|
|
18845
|
+
left: `calc(1rem + ${caretRowCol.col}ch)`,
|
|
18846
|
+
width: "1ch",
|
|
18847
|
+
height: caretMode === "block" ? "19.5px" : "2px",
|
|
18848
|
+
backgroundColor: caretMode === "block" ? "rgba(230, 230, 230, 0.5)" : void 0,
|
|
18849
|
+
borderBottom: caretMode === "underline" ? "2px solid #e6e6e6" : void 0,
|
|
18850
|
+
pointerEvents: "none"
|
|
18851
|
+
}
|
|
18852
|
+
}
|
|
18254
18853
|
)
|
|
18255
18854
|
]
|
|
18256
18855
|
}
|
|
@@ -18278,55 +18877,175 @@ var init_CodeBlock = __esm({
|
|
|
18278
18877
|
)
|
|
18279
18878
|
] });
|
|
18280
18879
|
},
|
|
18281
|
-
(prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.showCopy === next.showCopy && prev.maxHeight === next.maxHeight && prev.foldable === next.foldable && prev.editable === next.editable && prev.onChange === next.onChange && prev.errorLines === next.errorLines && prev.mode === next.mode && prev.title === next.title && prev.diff === next.diff && prev.files === next.files && prev.actions === next.actions && prev.isLoading === next.isLoading && prev.error === next.error
|
|
18880
|
+
(prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.showCopy === next.showCopy && prev.maxHeight === next.maxHeight && prev.foldable === next.foldable && prev.editable === next.editable && prev.onChange === next.onChange && prev.errorLines === next.errorLines && prev.mode === next.mode && prev.title === next.title && prev.diff === next.diff && prev.files === next.files && prev.actions === next.actions && prev.isLoading === next.isLoading && prev.error === next.error && prev.editorId === next.editorId && prev.onEditorFocus === next.onEditorFocus && prev.onEditorBlur === next.onEditorBlur && prev.onMotion === next.onMotion && prev.onOperate === next.onOperate && prev.onInsertText === next.onInsertText && prev.onSetMode === next.onSetMode && prev.motions === next.motions && prev.operators === next.operators
|
|
18282
18881
|
);
|
|
18283
18882
|
CodeBlock.displayName = "CodeBlock";
|
|
18284
18883
|
}
|
|
18285
18884
|
});
|
|
18885
|
+
|
|
18886
|
+
// components/core/molecules/markdown/mermaidSource.ts
|
|
18887
|
+
function isQuoted(label) {
|
|
18888
|
+
const trimmed = label.trim();
|
|
18889
|
+
return trimmed.length === 0 || trimmed.startsWith('"') && trimmed.endsWith('"') && trimmed.length > 1;
|
|
18890
|
+
}
|
|
18891
|
+
function quote(label) {
|
|
18892
|
+
return `"${label.replace(/"/g, "#quot;")}"`;
|
|
18893
|
+
}
|
|
18894
|
+
function isIdentifierChar(ch) {
|
|
18895
|
+
return /[A-Za-z0-9_\-.]/.test(ch);
|
|
18896
|
+
}
|
|
18897
|
+
function declaredType(code) {
|
|
18898
|
+
for (const line of code.split("\n")) {
|
|
18899
|
+
const trimmed = line.trim();
|
|
18900
|
+
if (trimmed.length === 0 || trimmed.startsWith("%%")) continue;
|
|
18901
|
+
return trimmed;
|
|
18902
|
+
}
|
|
18903
|
+
return "";
|
|
18904
|
+
}
|
|
18905
|
+
function isFlowchart(code) {
|
|
18906
|
+
return FLOWCHART_DIRECTIVE.test(declaredType(code));
|
|
18907
|
+
}
|
|
18908
|
+
function quoteNodeLabels(code) {
|
|
18909
|
+
let out = "";
|
|
18910
|
+
let i = 0;
|
|
18911
|
+
while (i < code.length) {
|
|
18912
|
+
const shape = NODE_SHAPES.find(([open2]) => code.startsWith(open2, i));
|
|
18913
|
+
const precededByIdentifier = i > 0 && isIdentifierChar(code[i - 1] ?? "");
|
|
18914
|
+
if (shape === void 0 || !precededByIdentifier) {
|
|
18915
|
+
out += code[i];
|
|
18916
|
+
i += 1;
|
|
18917
|
+
continue;
|
|
18918
|
+
}
|
|
18919
|
+
const [open, close] = shape;
|
|
18920
|
+
const contentStart = i + open.length;
|
|
18921
|
+
const closeAt = code.indexOf(close, contentStart);
|
|
18922
|
+
const newlineAt = code.indexOf("\n", contentStart);
|
|
18923
|
+
if (closeAt === -1 || newlineAt !== -1 && newlineAt < closeAt) {
|
|
18924
|
+
out += code[i];
|
|
18925
|
+
i += 1;
|
|
18926
|
+
continue;
|
|
18927
|
+
}
|
|
18928
|
+
const label = code.slice(contentStart, closeAt);
|
|
18929
|
+
out += open + (isQuoted(label) ? label : quote(label)) + close;
|
|
18930
|
+
i = closeAt + close.length;
|
|
18931
|
+
}
|
|
18932
|
+
return out;
|
|
18933
|
+
}
|
|
18934
|
+
function quoteEdgeLabels(code) {
|
|
18935
|
+
return code.split("\n").map((line) => {
|
|
18936
|
+
let out = "";
|
|
18937
|
+
let rest = line;
|
|
18938
|
+
for (; ; ) {
|
|
18939
|
+
const open = rest.indexOf("|");
|
|
18940
|
+
if (open === -1) break;
|
|
18941
|
+
const close = rest.indexOf("|", open + 1);
|
|
18942
|
+
if (close === -1) break;
|
|
18943
|
+
const label = rest.slice(open + 1, close);
|
|
18944
|
+
out += rest.slice(0, open + 1) + (isQuoted(label) ? label : quote(label)) + "|";
|
|
18945
|
+
rest = rest.slice(close + 1);
|
|
18946
|
+
}
|
|
18947
|
+
return out + rest;
|
|
18948
|
+
}).join("\n");
|
|
18949
|
+
}
|
|
18950
|
+
function quoteSubgraphTitles(code) {
|
|
18951
|
+
return code.split("\n").map((line) => {
|
|
18952
|
+
const match = /^(\s*subgraph\s+)(.+?)(\s*)$/.exec(line);
|
|
18953
|
+
if (match === null) return line;
|
|
18954
|
+
const [, prefix, title, trailing] = match;
|
|
18955
|
+
if (title === void 0 || prefix === void 0) return line;
|
|
18956
|
+
if (isQuoted(title) || title.includes("[")) return line;
|
|
18957
|
+
return prefix + quote(title) + (trailing ?? "");
|
|
18958
|
+
}).join("\n");
|
|
18959
|
+
}
|
|
18960
|
+
function mermaidRepairCandidates(code) {
|
|
18961
|
+
if (!isFlowchart(code)) return [];
|
|
18962
|
+
const nodes = quoteNodeLabels(code);
|
|
18963
|
+
const nodesAndEdges = quoteEdgeLabels(nodes);
|
|
18964
|
+
const all = quoteSubgraphTitles(nodesAndEdges);
|
|
18965
|
+
const ordered2 = [nodes, nodesAndEdges, all];
|
|
18966
|
+
const seen = /* @__PURE__ */ new Set([code]);
|
|
18967
|
+
const candidates = [];
|
|
18968
|
+
for (const candidate of ordered2) {
|
|
18969
|
+
if (seen.has(candidate)) continue;
|
|
18970
|
+
seen.add(candidate);
|
|
18971
|
+
candidates.push(candidate);
|
|
18972
|
+
}
|
|
18973
|
+
return candidates;
|
|
18974
|
+
}
|
|
18975
|
+
var NODE_SHAPES, FLOWCHART_DIRECTIVE;
|
|
18976
|
+
var init_mermaidSource = __esm({
|
|
18977
|
+
"components/core/molecules/markdown/mermaidSource.ts"() {
|
|
18978
|
+
NODE_SHAPES = [
|
|
18979
|
+
["[[", "]]"],
|
|
18980
|
+
["[(", ")]"],
|
|
18981
|
+
["([", "])"],
|
|
18982
|
+
["((", "))"],
|
|
18983
|
+
["{{", "}}"],
|
|
18984
|
+
["[", "]"],
|
|
18985
|
+
["(", ")"],
|
|
18986
|
+
["{", "}"]
|
|
18987
|
+
];
|
|
18988
|
+
FLOWCHART_DIRECTIVE = /^(?:graph|flowchart)\b/;
|
|
18989
|
+
}
|
|
18990
|
+
});
|
|
18286
18991
|
function loadMermaid() {
|
|
18287
18992
|
mermaidModule ?? (mermaidModule = import('mermaid').then((m) => m.default));
|
|
18288
18993
|
return mermaidModule;
|
|
18289
18994
|
}
|
|
18290
|
-
var mermaidModule, MermaidDiagram;
|
|
18995
|
+
var log8, mermaidModule, MermaidDiagram;
|
|
18291
18996
|
var init_MermaidDiagram = __esm({
|
|
18292
18997
|
"components/core/molecules/markdown/MermaidDiagram.tsx"() {
|
|
18293
18998
|
init_Box();
|
|
18294
18999
|
init_Typography();
|
|
18295
19000
|
init_CodeBlock();
|
|
19001
|
+
init_mermaidSource();
|
|
18296
19002
|
init_cn();
|
|
19003
|
+
log8 = logger.createLogger("almadar:ui:mermaid-diagram");
|
|
18297
19004
|
mermaidModule = null;
|
|
18298
19005
|
MermaidDiagram = React89__namespace.default.memo(
|
|
18299
19006
|
({ code, className }) => {
|
|
18300
19007
|
const { resolvedMode } = context.useTheme();
|
|
19008
|
+
const { t } = hooks.useTranslate();
|
|
18301
19009
|
const containerRef = React89.useRef(null);
|
|
18302
|
-
const [
|
|
19010
|
+
const [unrenderable, setUnrenderable] = React89.useState(false);
|
|
18303
19011
|
const reactId = React89.useId();
|
|
18304
19012
|
React89.useEffect(() => {
|
|
18305
19013
|
let active = true;
|
|
18306
19014
|
void (async () => {
|
|
18307
|
-
|
|
18308
|
-
|
|
18309
|
-
|
|
18310
|
-
|
|
18311
|
-
|
|
18312
|
-
|
|
18313
|
-
|
|
18314
|
-
|
|
18315
|
-
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18320
|
-
|
|
19015
|
+
const mermaid = await loadMermaid();
|
|
19016
|
+
mermaid.initialize({
|
|
19017
|
+
startOnLoad: false,
|
|
19018
|
+
securityLevel: "strict",
|
|
19019
|
+
theme: resolvedMode === "dark" ? "dark" : "default"
|
|
19020
|
+
});
|
|
19021
|
+
const domId = `mermaid-${reactId.replace(/[^a-zA-Z0-9]/g, "")}`;
|
|
19022
|
+
let firstError = null;
|
|
19023
|
+
for (const [index, source] of [code, ...mermaidRepairCandidates(code)].entries()) {
|
|
19024
|
+
try {
|
|
19025
|
+
const { svg } = await mermaid.render(domId, source);
|
|
19026
|
+
if (!active) return;
|
|
19027
|
+
const container = containerRef.current;
|
|
19028
|
+
if (container === null) return;
|
|
19029
|
+
container.innerHTML = svg;
|
|
19030
|
+
container.dataset.mermaidRepaired = String(index > 0);
|
|
19031
|
+
setUnrenderable(false);
|
|
19032
|
+
if (index > 0) log8.debug("mermaid:repaired", { candidate: index });
|
|
19033
|
+
return;
|
|
19034
|
+
} catch (err) {
|
|
19035
|
+
firstError ?? (firstError = err instanceof Error ? err : new Error(String(err)));
|
|
19036
|
+
}
|
|
18321
19037
|
}
|
|
19038
|
+
if (!active) return;
|
|
19039
|
+
log8.warn("mermaid:unrenderable", { error: firstError?.message ?? "", code });
|
|
19040
|
+
setUnrenderable(true);
|
|
18322
19041
|
})();
|
|
18323
19042
|
return () => {
|
|
18324
19043
|
active = false;
|
|
18325
19044
|
};
|
|
18326
19045
|
}, [code, resolvedMode, reactId]);
|
|
18327
19046
|
return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: cn("not-prose my-4", className), children: [
|
|
18328
|
-
|
|
18329
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-
|
|
19047
|
+
unrenderable && /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "space-y-2 mb-2", "data-testid": "mermaid-unrenderable", children: [
|
|
19048
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("mermaid.unrenderable") }),
|
|
18330
19049
|
/* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { code, language: "mermaid" })
|
|
18331
19050
|
] }),
|
|
18332
19051
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -18335,7 +19054,7 @@ var init_MermaidDiagram = __esm({
|
|
|
18335
19054
|
ref: containerRef,
|
|
18336
19055
|
"data-testid": "mermaid-diagram",
|
|
18337
19056
|
className: "overflow-x-auto",
|
|
18338
|
-
style:
|
|
19057
|
+
style: unrenderable ? { display: "none" } : void 0
|
|
18339
19058
|
}
|
|
18340
19059
|
)
|
|
18341
19060
|
] });
|
|
@@ -21740,14 +22459,14 @@ function useSafeEventBus2() {
|
|
|
21740
22459
|
} };
|
|
21741
22460
|
}
|
|
21742
22461
|
}
|
|
21743
|
-
var
|
|
22462
|
+
var log9, lookStyles4, ButtonGroup;
|
|
21744
22463
|
var init_ButtonGroup = __esm({
|
|
21745
22464
|
"components/core/molecules/ButtonGroup.tsx"() {
|
|
21746
22465
|
"use client";
|
|
21747
22466
|
init_cn();
|
|
21748
22467
|
init_atoms();
|
|
21749
22468
|
init_useEventBus();
|
|
21750
|
-
|
|
22469
|
+
log9 = logger.createLogger("almadar:ui:button-group");
|
|
21751
22470
|
lookStyles4 = {
|
|
21752
22471
|
"right-aligned-buttons": "",
|
|
21753
22472
|
"floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
|
|
@@ -21828,7 +22547,7 @@ var init_ButtonGroup = __esm({
|
|
|
21828
22547
|
{
|
|
21829
22548
|
variant: "ghost",
|
|
21830
22549
|
onClick: () => {
|
|
21831
|
-
|
|
22550
|
+
log9.debug("Filter clicked", { field: filter.field });
|
|
21832
22551
|
},
|
|
21833
22552
|
children: filter.label
|
|
21834
22553
|
},
|
|
@@ -24612,6 +25331,12 @@ function commandMatches(command, query) {
|
|
|
24612
25331
|
if (matchesQuery(query, command.label)) return true;
|
|
24613
25332
|
return (command.keywords ?? []).some((keyword) => matchesQuery(query, keyword));
|
|
24614
25333
|
}
|
|
25334
|
+
function dispatchCommandPaletteCommand(command, deps) {
|
|
25335
|
+
if (command.disabled) return;
|
|
25336
|
+
if (command.event) deps.emit(`UI:${command.event}`, { commandId: command.id });
|
|
25337
|
+
if (command.action) deps.emit(`UI:${command.action}`, command.actionPayload ?? {});
|
|
25338
|
+
deps.onSelect?.(command);
|
|
25339
|
+
}
|
|
24615
25340
|
var UNGROUPED, CommandPalette;
|
|
24616
25341
|
var init_CommandPalette = __esm({
|
|
24617
25342
|
"components/core/molecules/CommandPalette.tsx"() {
|
|
@@ -24666,9 +25391,7 @@ var init_CommandPalette = __esm({
|
|
|
24666
25391
|
const handleSelect = React89.useCallback(
|
|
24667
25392
|
(command) => {
|
|
24668
25393
|
if (command.disabled) return;
|
|
24669
|
-
|
|
24670
|
-
if (command.action) eventBus.emit(`UI:${command.action}`, command.actionPayload ?? {});
|
|
24671
|
-
onSelect?.(command);
|
|
25394
|
+
dispatchCommandPaletteCommand(command, { emit: eventBus.emit, onSelect });
|
|
24672
25395
|
handleClose();
|
|
24673
25396
|
},
|
|
24674
25397
|
[eventBus, onSelect, handleClose]
|
|
@@ -29647,9 +30370,9 @@ function debug(...args) {
|
|
|
29647
30370
|
const [first, ...rest] = args;
|
|
29648
30371
|
const message = typeof first === "string" ? first : "<debug>";
|
|
29649
30372
|
if (rest.length === 0 && typeof first === "string") {
|
|
29650
|
-
|
|
30373
|
+
log10.debug(message);
|
|
29651
30374
|
} else {
|
|
29652
|
-
|
|
30375
|
+
log10.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
|
|
29653
30376
|
}
|
|
29654
30377
|
}
|
|
29655
30378
|
function debugGroup(label) {
|
|
@@ -29677,11 +30400,11 @@ function toLogMetaValue(v) {
|
|
|
29677
30400
|
}
|
|
29678
30401
|
return String(v);
|
|
29679
30402
|
}
|
|
29680
|
-
var NAMESPACE,
|
|
30403
|
+
var NAMESPACE, log10;
|
|
29681
30404
|
var init_debug = __esm({
|
|
29682
30405
|
"lib/debug.ts"() {
|
|
29683
30406
|
NAMESPACE = "almadar:ui:debug";
|
|
29684
|
-
|
|
30407
|
+
log10 = logger.createLogger(NAMESPACE);
|
|
29685
30408
|
logger.createLogger("almadar:ui:debug:input");
|
|
29686
30409
|
logger.createLogger("almadar:ui:debug:collision");
|
|
29687
30410
|
logger.createLogger("almadar:ui:debug:physics");
|
|
@@ -31334,6 +32057,7 @@ var init_MathCanvas = __esm({
|
|
|
31334
32057
|
init_perf();
|
|
31335
32058
|
init_atoms();
|
|
31336
32059
|
init_Stack();
|
|
32060
|
+
init_gameFonts();
|
|
31337
32061
|
init_LearningCanvas();
|
|
31338
32062
|
MathCanvas = ({
|
|
31339
32063
|
className,
|
|
@@ -31353,6 +32077,7 @@ var init_MathCanvas = __esm({
|
|
|
31353
32077
|
showTickLabels = false,
|
|
31354
32078
|
tickLabelFontSize = 10,
|
|
31355
32079
|
labelFontSize = 12,
|
|
32080
|
+
fontFamily: fontFamilyProp,
|
|
31356
32081
|
showCurveLabels = false,
|
|
31357
32082
|
curves = [],
|
|
31358
32083
|
points = [],
|
|
@@ -31375,6 +32100,7 @@ var init_MathCanvas = __esm({
|
|
|
31375
32100
|
error
|
|
31376
32101
|
}) => {
|
|
31377
32102
|
const eventBus = useEventBus();
|
|
32103
|
+
const fontFamily = resolveGameFontFamily(fontFamilyProp);
|
|
31378
32104
|
const keyMapKey = keyMap ? JSON.stringify(keyMap) : null;
|
|
31379
32105
|
const keyUpMapKey = keyUpMap ? JSON.stringify(keyUpMap) : null;
|
|
31380
32106
|
const stableKeyMap = React89.useMemo(() => keyMap, [keyMapKey]);
|
|
@@ -31424,18 +32150,18 @@ var init_MathCanvas = __esm({
|
|
|
31424
32150
|
let kx = 0;
|
|
31425
32151
|
for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep, kx++) {
|
|
31426
32152
|
if (kx % labelEveryX === 0 && x !== 0) {
|
|
31427
|
-
out.push({ type: "text", x: mapX(x), y: xAxisY + 12, text: formatTick(x), color: "#6b7280", fontSize: tickLabelFontSize, align: "center" });
|
|
32153
|
+
out.push({ type: "text", fontFamily, x: mapX(x), y: xAxisY + 12, text: formatTick(x), color: "#6b7280", fontSize: tickLabelFontSize, align: "center" });
|
|
31428
32154
|
}
|
|
31429
32155
|
}
|
|
31430
32156
|
const labelEveryY = Math.max(1, Math.ceil((yMax - yMin) / gridStep / Math.floor(plotH / 28)));
|
|
31431
32157
|
let ky = 0;
|
|
31432
32158
|
for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep, ky++) {
|
|
31433
32159
|
if (ky % labelEveryY === 0 && y !== 0) {
|
|
31434
|
-
out.push({ type: "text", x: yAxisX - 6, y: mapY(y), text: formatTick(y), color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
|
|
32160
|
+
out.push({ type: "text", fontFamily, x: yAxisX - 6, y: mapY(y), text: formatTick(y), color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
|
|
31435
32161
|
}
|
|
31436
32162
|
}
|
|
31437
32163
|
if (xMin <= 0 && xMax >= 0 && yMin <= 0 && yMax >= 0) {
|
|
31438
|
-
out.push({ type: "text", x: yAxisX - 6, y: xAxisY + 12, text: "0", color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
|
|
32164
|
+
out.push({ type: "text", fontFamily, x: yAxisX - 6, y: xAxisY + 12, text: "0", color: "#6b7280", fontSize: tickLabelFontSize, align: "right" });
|
|
31439
32165
|
}
|
|
31440
32166
|
}
|
|
31441
32167
|
for (const region of regions) {
|
|
@@ -31462,6 +32188,7 @@ var init_MathCanvas = __esm({
|
|
|
31462
32188
|
const mid = Math.floor(region.samples.length / 2);
|
|
31463
32189
|
out.push({
|
|
31464
32190
|
type: "text",
|
|
32191
|
+
fontFamily,
|
|
31465
32192
|
x: mapX((first.x + last.x) / 2),
|
|
31466
32193
|
y: (mapY(region.samples[mid].y) + mapY(baseline)) / 2,
|
|
31467
32194
|
text: region.label,
|
|
@@ -31498,14 +32225,14 @@ var init_MathCanvas = __esm({
|
|
|
31498
32225
|
const px = mapX(guide.at);
|
|
31499
32226
|
out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color, dash });
|
|
31500
32227
|
if (guide.label) {
|
|
31501
|
-
out.push({ type: "text", x: px + 4, y: margin + 10, text: guide.label, color, fontSize: 11 });
|
|
32228
|
+
out.push({ type: "text", fontFamily, x: px + 4, y: margin + 10, text: guide.label, color, fontSize: 11 });
|
|
31502
32229
|
}
|
|
31503
32230
|
} else {
|
|
31504
32231
|
if (guide.at < yMin || guide.at > yMax) continue;
|
|
31505
32232
|
const py = mapY(guide.at);
|
|
31506
32233
|
out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color, dash });
|
|
31507
32234
|
if (guide.label) {
|
|
31508
|
-
out.push({ type: "text", x: width - margin - 4, y: py - 8, text: guide.label, color, fontSize: labelFontSize, align: "right" });
|
|
32235
|
+
out.push({ type: "text", fontFamily, x: width - margin - 4, y: py - 8, text: guide.label, color, fontSize: labelFontSize, align: "right" });
|
|
31509
32236
|
}
|
|
31510
32237
|
}
|
|
31511
32238
|
}
|
|
@@ -31544,6 +32271,7 @@ var init_MathCanvas = __esm({
|
|
|
31544
32271
|
if (showCurveLabels && curve.label && lastInRange) {
|
|
31545
32272
|
out.push({
|
|
31546
32273
|
type: "text",
|
|
32274
|
+
fontFamily,
|
|
31547
32275
|
x: mapX(lastInRange.x) + 6,
|
|
31548
32276
|
y: mapY(lastInRange.y) - 6,
|
|
31549
32277
|
text: curve.label,
|
|
@@ -31581,6 +32309,7 @@ var init_MathCanvas = __esm({
|
|
|
31581
32309
|
if (hop.label) {
|
|
31582
32310
|
out.push({
|
|
31583
32311
|
type: "text",
|
|
32312
|
+
fontFamily,
|
|
31584
32313
|
x: (x1 + x2) / 2,
|
|
31585
32314
|
y: xAxisY - peak - 8,
|
|
31586
32315
|
text: hop.label,
|
|
@@ -31608,6 +32337,7 @@ var init_MathCanvas = __esm({
|
|
|
31608
32337
|
const rad = mid * Math.PI / 180;
|
|
31609
32338
|
out.push({
|
|
31610
32339
|
type: "text",
|
|
32340
|
+
fontFamily,
|
|
31611
32341
|
x: mapX(angle.x + 1.35 * radius * Math.cos(rad)),
|
|
31612
32342
|
y: mapY(angle.y + 1.35 * radius * Math.sin(rad)),
|
|
31613
32343
|
text: angle.label,
|
|
@@ -31629,7 +32359,7 @@ var init_MathCanvas = __esm({
|
|
|
31629
32359
|
fill: isOpen ? "#ffffff" : p.color ?? "#dc2626"
|
|
31630
32360
|
});
|
|
31631
32361
|
if (p.label) {
|
|
31632
|
-
out.push({ type: "text", x: mapX(p.x) + 8, y: mapY(p.y) - 8, text: p.label, color: p.color ?? "#111827", fontSize: labelFontSize });
|
|
32362
|
+
out.push({ type: "text", fontFamily, x: mapX(p.x) + 8, y: mapY(p.y) - 8, text: p.label, color: p.color ?? "#111827", fontSize: labelFontSize });
|
|
31633
32363
|
}
|
|
31634
32364
|
}
|
|
31635
32365
|
for (const v of vectors) {
|
|
@@ -31640,7 +32370,7 @@ var init_MathCanvas = __esm({
|
|
|
31640
32370
|
const y2 = mapY(v.y + v.vy);
|
|
31641
32371
|
out.push({ type: "arrow", x1, y1, x2, y2, color: v.color ?? "#7c3aed", lineWidth: 2 });
|
|
31642
32372
|
if (v.label) {
|
|
31643
|
-
out.push({ type: "text", x: x2 + 6, y: y2 - 6, text: v.label, color: v.color ?? "#7c3aed", fontSize: labelFontSize });
|
|
32373
|
+
out.push({ type: "text", fontFamily, x: x2 + 6, y: y2 - 6, text: v.label, color: v.color ?? "#7c3aed", fontSize: labelFontSize });
|
|
31644
32374
|
}
|
|
31645
32375
|
}
|
|
31646
32376
|
out.push(...shapes);
|
|
@@ -31661,6 +32391,7 @@ var init_MathCanvas = __esm({
|
|
|
31661
32391
|
showTickLabels,
|
|
31662
32392
|
tickLabelFontSize,
|
|
31663
32393
|
labelFontSize,
|
|
32394
|
+
fontFamily,
|
|
31664
32395
|
showCurveLabels,
|
|
31665
32396
|
curves,
|
|
31666
32397
|
points,
|
|
@@ -31716,6 +32447,7 @@ var init_MathCanvas = __esm({
|
|
|
31716
32447
|
width,
|
|
31717
32448
|
height,
|
|
31718
32449
|
backgroundColor,
|
|
32450
|
+
fontFamily,
|
|
31719
32451
|
shapes: derivedShapes,
|
|
31720
32452
|
drawables,
|
|
31721
32453
|
projector,
|
|
@@ -32948,13 +33680,13 @@ var init_MapView = __esm({
|
|
|
32948
33680
|
shadowSize: [41, 41]
|
|
32949
33681
|
});
|
|
32950
33682
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
32951
|
-
const { useEffect:
|
|
33683
|
+
const { useEffect: useEffect69, useRef: useRef69, useCallback: useCallback100, useState: useState103 } = React89__namespace.default;
|
|
32952
33684
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
32953
33685
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
32954
33686
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
32955
33687
|
const map = useMap();
|
|
32956
|
-
const prevRef =
|
|
32957
|
-
|
|
33688
|
+
const prevRef = useRef69({ centerLat, centerLng, zoom });
|
|
33689
|
+
useEffect69(() => {
|
|
32958
33690
|
const prev = prevRef.current;
|
|
32959
33691
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
32960
33692
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -32965,7 +33697,7 @@ var init_MapView = __esm({
|
|
|
32965
33697
|
}
|
|
32966
33698
|
function MapClickHandler({ onMapClick }) {
|
|
32967
33699
|
const map = useMap();
|
|
32968
|
-
|
|
33700
|
+
useEffect69(() => {
|
|
32969
33701
|
if (!onMapClick) return;
|
|
32970
33702
|
const handler = (e) => {
|
|
32971
33703
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -32993,7 +33725,7 @@ var init_MapView = __esm({
|
|
|
32993
33725
|
showAttribution = true
|
|
32994
33726
|
}) {
|
|
32995
33727
|
const eventBus = useEventBus2();
|
|
32996
|
-
const [clickedPosition, setClickedPosition] =
|
|
33728
|
+
const [clickedPosition, setClickedPosition] = useState103(null);
|
|
32997
33729
|
const handleMapClick = useCallback100((lat, lng) => {
|
|
32998
33730
|
if (showClickedPin) {
|
|
32999
33731
|
setClickedPosition({ lat, lng });
|
|
@@ -47702,7 +48434,7 @@ function getAllEvents(traits2) {
|
|
|
47702
48434
|
function EventDispatcherTab({ traits: traits2, schema }) {
|
|
47703
48435
|
const eventBus = useEventBus();
|
|
47704
48436
|
const { t } = hooks.useTranslate();
|
|
47705
|
-
const [
|
|
48437
|
+
const [log14, setLog] = React89__namespace.useState([]);
|
|
47706
48438
|
const prevStatesRef = React89__namespace.useRef(/* @__PURE__ */ new Map());
|
|
47707
48439
|
React89__namespace.useEffect(() => {
|
|
47708
48440
|
for (const trait of traits2) {
|
|
@@ -47766,9 +48498,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
|
|
|
47766
48498
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "medium", className: "text-muted-foreground mb-1", children: t("debug.otherEvents") }),
|
|
47767
48499
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: unavailableEvents.map((event) => /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", className: "opacity-50", children: event }, event)) })
|
|
47768
48500
|
] }),
|
|
47769
|
-
|
|
48501
|
+
log14.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
47770
48502
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "medium", className: "text-muted-foreground mb-1", children: t("debug.recentTransitions") }),
|
|
47771
|
-
/* @__PURE__ */ jsxRuntime.jsx(Stack, { gap: "xs", children:
|
|
48503
|
+
/* @__PURE__ */ jsxRuntime.jsx(Stack, { gap: "xs", children: log14.map((entry, i) => /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
|
|
47772
48504
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: entry.traitName }),
|
|
47773
48505
|
" ",
|
|
47774
48506
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: entry.from }),
|
|
@@ -49959,6 +50691,7 @@ var init_component_registry_generated = __esm({
|
|
|
49959
50691
|
init_FormSection();
|
|
49960
50692
|
init_FormSectionHeader();
|
|
49961
50693
|
init_FxOverlay();
|
|
50694
|
+
init_GameAudioCue();
|
|
49962
50695
|
init_GameAudioToggle();
|
|
49963
50696
|
init_GameHud();
|
|
49964
50697
|
init_GameIcon();
|
|
@@ -50236,6 +50969,7 @@ var init_component_registry_generated = __esm({
|
|
|
50236
50969
|
"FormLayout": FormLayout,
|
|
50237
50970
|
"FormSectionHeader": FormSectionHeader,
|
|
50238
50971
|
"FxOverlay": FxOverlay,
|
|
50972
|
+
"GameAudioCue": GameAudioCue,
|
|
50239
50973
|
"GameAudioToggle": GameAudioToggle,
|
|
50240
50974
|
"GameHud": GameHud,
|
|
50241
50975
|
"GameIcon": GameIcon,
|
|
@@ -50684,7 +51418,9 @@ function UISlotComponentInner({
|
|
|
50684
51418
|
className,
|
|
50685
51419
|
children,
|
|
50686
51420
|
pattern,
|
|
50687
|
-
sourceTrait
|
|
51421
|
+
sourceTrait,
|
|
51422
|
+
fallback,
|
|
51423
|
+
mode = "replace"
|
|
50688
51424
|
}) {
|
|
50689
51425
|
const { slots, clear } = context.useUISlots();
|
|
50690
51426
|
const eventBus = useEventBus();
|
|
@@ -50736,12 +51472,26 @@ function UISlotComponentInner({
|
|
|
50736
51472
|
);
|
|
50737
51473
|
}
|
|
50738
51474
|
if (!content) {
|
|
51475
|
+
if (fallback !== void 0) {
|
|
51476
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
51477
|
+
Box,
|
|
51478
|
+
{
|
|
51479
|
+
id: `slot-${slot}`,
|
|
51480
|
+
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
51481
|
+
"data-testid": `ui-slot-${slot}`,
|
|
51482
|
+
"data-slot-mode": "fallback",
|
|
51483
|
+
children: fallback
|
|
51484
|
+
}
|
|
51485
|
+
);
|
|
51486
|
+
}
|
|
50739
51487
|
if (!portal) {
|
|
50740
51488
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
50741
51489
|
Box,
|
|
50742
51490
|
{
|
|
50743
51491
|
id: `slot-${slot}`,
|
|
50744
|
-
className: cn("ui-slot", `ui-slot-${slot}`, className)
|
|
51492
|
+
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
51493
|
+
"data-testid": `ui-slot-${slot}`,
|
|
51494
|
+
"data-slot-mode": "empty"
|
|
50745
51495
|
}
|
|
50746
51496
|
);
|
|
50747
51497
|
}
|
|
@@ -50758,29 +51508,51 @@ function UISlotComponentInner({
|
|
|
50758
51508
|
clear(slot);
|
|
50759
51509
|
};
|
|
50760
51510
|
if (portal) {
|
|
50761
|
-
|
|
50762
|
-
|
|
50763
|
-
}
|
|
50764
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
50765
|
-
SlotPortal,
|
|
51511
|
+
const inlineFallback = mode === "append" && fallback !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
51512
|
+
Box,
|
|
50766
51513
|
{
|
|
50767
|
-
slot
|
|
50768
|
-
|
|
50769
|
-
|
|
50770
|
-
|
|
51514
|
+
id: `slot-${slot}-fallback`,
|
|
51515
|
+
className: cn("ui-slot", `ui-slot-${slot}-fallback`, className),
|
|
51516
|
+
"data-testid": `ui-slot-${slot}-fallback`,
|
|
51517
|
+
"data-slot-mode": "append",
|
|
51518
|
+
children: fallback
|
|
50771
51519
|
}
|
|
50772
|
-
);
|
|
51520
|
+
) : null;
|
|
51521
|
+
if (contained) {
|
|
51522
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
51523
|
+
inlineFallback,
|
|
51524
|
+
renderContainedPortal(t, slot, content, handleDismiss)
|
|
51525
|
+
] });
|
|
51526
|
+
}
|
|
51527
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
51528
|
+
inlineFallback,
|
|
51529
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
51530
|
+
SlotPortal,
|
|
51531
|
+
{
|
|
51532
|
+
slot,
|
|
51533
|
+
content,
|
|
51534
|
+
position,
|
|
51535
|
+
onDismiss: handleDismiss
|
|
51536
|
+
}
|
|
51537
|
+
)
|
|
51538
|
+
] });
|
|
50773
51539
|
}
|
|
50774
51540
|
const slotContent = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content, onDismiss: handleDismiss });
|
|
50775
51541
|
const wrappedContent = suspenseConfig.enabled ? /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(React89.Suspense, { fallback: getSlotFallback(slot, suspenseConfig), children: slotContent }) }) : /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: slotContent });
|
|
50776
|
-
|
|
51542
|
+
const showFallback = mode === "append" && fallback !== void 0;
|
|
51543
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
50777
51544
|
Box,
|
|
50778
51545
|
{
|
|
50779
51546
|
id: `slot-${slot}`,
|
|
50780
51547
|
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
50781
51548
|
"data-pattern": content.pattern,
|
|
50782
51549
|
"data-source-trait": content.sourceTrait,
|
|
50783
|
-
|
|
51550
|
+
"data-testid": `ui-slot-${slot}`,
|
|
51551
|
+
"data-slot-mode": showFallback ? "append" : "content",
|
|
51552
|
+
children: [
|
|
51553
|
+
showFallback ? fallback : null,
|
|
51554
|
+
/* @__PURE__ */ jsxRuntime.jsx(MaybeTraitScope, { sourceTrait: content.sourceTrait, children: wrappedContent })
|
|
51555
|
+
]
|
|
50784
51556
|
}
|
|
50785
51557
|
);
|
|
50786
51558
|
}
|
|
@@ -51731,7 +52503,7 @@ init_UISlotRenderer();
|
|
|
51731
52503
|
// providers/VerificationProvider.tsx
|
|
51732
52504
|
init_useEventBus();
|
|
51733
52505
|
init_verificationRegistry();
|
|
51734
|
-
var
|
|
52506
|
+
var log11 = logger.createLogger("almadar:verify");
|
|
51735
52507
|
var DISPATCH_SUFFIX = ":DISPATCH";
|
|
51736
52508
|
var SUCCESS_SUFFIX = ":SUCCESS";
|
|
51737
52509
|
var ERROR_SUFFIX = ":ERROR";
|
|
@@ -51778,7 +52550,7 @@ function VerificationProvider({
|
|
|
51778
52550
|
const verificationProviderLifecycleListener = (evt) => {
|
|
51779
52551
|
const parsed = parseLifecycleEvent(evt.type);
|
|
51780
52552
|
if (!parsed) return;
|
|
51781
|
-
|
|
52553
|
+
log11.debug("lifecycle:event", { kind: parsed.kind, traitName: parsed.traitName, event: parsed.event, type: evt.type });
|
|
51782
52554
|
const payload = evt.payload ?? {};
|
|
51783
52555
|
if (parsed.kind === "dispatch") {
|
|
51784
52556
|
const key = `${parsed.traitName}:${String(payload["event"] ?? "")}`;
|
|
@@ -51834,7 +52606,7 @@ function VerificationProvider({
|
|
|
51834
52606
|
},
|
|
51835
52607
|
timestamp: Date.now()
|
|
51836
52608
|
});
|
|
51837
|
-
|
|
52609
|
+
log11.debug("transition:success", { trait: parsed.traitName, event: parsed.event, from: pending?.from, to: newState, effectCount: effects.length });
|
|
51838
52610
|
} else if (parsed.kind === "error" && parsed.event) {
|
|
51839
52611
|
const key = `${parsed.traitName}:${parsed.event}`;
|
|
51840
52612
|
const pending = pendingRef.current.get(key);
|
|
@@ -51864,7 +52636,7 @@ function VerificationProvider({
|
|
|
51864
52636
|
},
|
|
51865
52637
|
timestamp: Date.now()
|
|
51866
52638
|
});
|
|
51867
|
-
|
|
52639
|
+
log11.warn("transition:error", { trait: parsed.traitName, event: parsed.event, from: fromState, error: errorMsg });
|
|
51868
52640
|
}
|
|
51869
52641
|
};
|
|
51870
52642
|
Object.defineProperty(verificationProviderLifecycleListener, "name", {
|
|
@@ -52326,7 +53098,7 @@ function useEntitySchema() {
|
|
|
52326
53098
|
function useEntitySchemaOptional6() {
|
|
52327
53099
|
return React89.useContext(EntitySchemaContext);
|
|
52328
53100
|
}
|
|
52329
|
-
var
|
|
53101
|
+
var log12 = logger.createLogger("almadar:ui:navigation");
|
|
52330
53102
|
function matchPath2(pattern, path) {
|
|
52331
53103
|
const normalizeSegment = (p) => {
|
|
52332
53104
|
let normalized = p.trim();
|
|
@@ -52487,12 +53259,12 @@ function NavigationProvider2({
|
|
|
52487
53259
|
const navigateTo = React89.useCallback((path, payload) => {
|
|
52488
53260
|
const result = findPageByPath2(schema, path);
|
|
52489
53261
|
if (!result) {
|
|
52490
|
-
|
|
53262
|
+
log12.error("No page found for path", { path });
|
|
52491
53263
|
return;
|
|
52492
53264
|
}
|
|
52493
53265
|
const { page, params } = result;
|
|
52494
53266
|
const finalPayload = { ...params, ...payload };
|
|
52495
|
-
|
|
53267
|
+
log12.debug("Navigating to", () => ({
|
|
52496
53268
|
path,
|
|
52497
53269
|
page: page.name,
|
|
52498
53270
|
params,
|
|
@@ -52509,7 +53281,7 @@ function NavigationProvider2({
|
|
|
52509
53281
|
try {
|
|
52510
53282
|
window.history.pushState(finalPayload, "", path);
|
|
52511
53283
|
} catch (e) {
|
|
52512
|
-
|
|
53284
|
+
log12.warn("Could not update URL", { error: e instanceof Error ? e : String(e) });
|
|
52513
53285
|
}
|
|
52514
53286
|
}
|
|
52515
53287
|
if (onNavigate) {
|
|
@@ -52519,12 +53291,12 @@ function NavigationProvider2({
|
|
|
52519
53291
|
const navigateToPage = React89.useCallback((pageName, payload) => {
|
|
52520
53292
|
const result = findPageByName2(schema, pageName);
|
|
52521
53293
|
if (!result) {
|
|
52522
|
-
|
|
53294
|
+
log12.error("No page found with name", { pageName });
|
|
52523
53295
|
return;
|
|
52524
53296
|
}
|
|
52525
53297
|
const { page } = result;
|
|
52526
53298
|
const path = page.path || `/${pageName.toLowerCase()}`;
|
|
52527
|
-
|
|
53299
|
+
log12.debug("Navigating to page", () => ({
|
|
52528
53300
|
pageName,
|
|
52529
53301
|
path,
|
|
52530
53302
|
payload: JSON.stringify(payload)
|
|
@@ -52539,7 +53311,7 @@ function NavigationProvider2({
|
|
|
52539
53311
|
try {
|
|
52540
53312
|
window.history.pushState(payload || {}, "", path);
|
|
52541
53313
|
} catch (e) {
|
|
52542
|
-
|
|
53314
|
+
log12.warn("Could not update URL", { error: e instanceof Error ? e : String(e) });
|
|
52543
53315
|
}
|
|
52544
53316
|
}
|
|
52545
53317
|
if (onNavigate) {
|
|
@@ -52561,7 +53333,7 @@ function useNavigation2() {
|
|
|
52561
53333
|
function useNavigateTo2() {
|
|
52562
53334
|
const context = React89.useContext(NavigationContext);
|
|
52563
53335
|
const noOp = React89.useCallback((path, _payload) => {
|
|
52564
|
-
|
|
53336
|
+
log12.warn("navigateTo called outside NavigationProvider", { path });
|
|
52565
53337
|
}, []);
|
|
52566
53338
|
return context?.navigateTo || noOp;
|
|
52567
53339
|
}
|
|
@@ -52904,7 +53676,7 @@ function ServerBridgeProvider({
|
|
|
52904
53676
|
}, [serverUrl, eventBus]);
|
|
52905
53677
|
return /* @__PURE__ */ jsxRuntime.jsx(ServerBridgeContext.Provider, { value: { connected, sendEvent }, children });
|
|
52906
53678
|
}
|
|
52907
|
-
var
|
|
53679
|
+
var log13 = logger.createLogger("almadar:ui:trait-provider");
|
|
52908
53680
|
var TraitContext = React89.createContext(null);
|
|
52909
53681
|
function TraitProvider({
|
|
52910
53682
|
traits: traitBindings,
|
|
@@ -52921,7 +53693,7 @@ function TraitProvider({
|
|
|
52921
53693
|
currentState: stateName,
|
|
52922
53694
|
availableEvents: trait.transitions.filter((t) => t.from === stateName).map((t) => t.event),
|
|
52923
53695
|
dispatch: (eventKey, payload) => {
|
|
52924
|
-
|
|
53696
|
+
log13.debug("Dispatch", () => ({
|
|
52925
53697
|
trait: trait.name,
|
|
52926
53698
|
event: eventKey,
|
|
52927
53699
|
payloadKeys: payload ? Object.keys(payload) : []
|