@ankhorage/zora 25.11.0 → 26.0.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/CHANGELOG.md +12 -0
- package/README.md +1 -4
- package/dist/capabilities/index.js +65 -41
- package/dist/capabilities/index.js.map +3 -3
- package/dist/features/chess/adapters/inbound/ChessBoard.d.ts +1 -1
- package/dist/features/chess/adapters/inbound/ChessBoard.d.ts.map +1 -1
- package/dist/features/chess/adapters/inbound/ChessBoard.js +130 -83
- package/dist/features/chess/adapters/inbound/ChessBoard.js.map +1 -1
- package/dist/features/chess/meta.d.ts +97 -72
- package/dist/features/chess/meta.d.ts.map +1 -1
- package/dist/features/chess/meta.js +64 -40
- package/dist/features/chess/meta.js.map +1 -1
- package/dist/features/chess/public.d.ts +1 -7
- package/dist/features/chess/public.d.ts.map +1 -1
- package/dist/features/chess/public.js +0 -6
- package/dist/features/chess/public.js.map +1 -1
- package/dist/features/chess/utils/createChessBoardCellPressHandler.d.ts +6 -0
- package/dist/features/chess/utils/createChessBoardCellPressHandler.d.ts.map +1 -0
- package/dist/features/chess/utils/createChessBoardCellPressHandler.js +17 -0
- package/dist/features/chess/utils/createChessBoardCellPressHandler.js.map +1 -0
- package/dist/features/chess/utils/createChessBoardCells.d.ts +12 -0
- package/dist/features/chess/utils/createChessBoardCells.d.ts.map +1 -0
- package/dist/features/chess/utils/createChessBoardCells.js +28 -0
- package/dist/features/chess/utils/createChessBoardCells.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.d.ts +2 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.js +68 -4
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.d.ts +3 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.js +41 -8
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.js +6 -2
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.d.ts +2 -2
- package/dist/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.js +3 -3
- package/dist/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.js.map +1 -1
- package/dist/readerFree.d.ts +2 -2
- package/dist/readerFree.d.ts.map +1 -1
- package/dist/readerFree.js +1 -1
- package/dist/readerFree.js.map +1 -1
- package/dist/types/authoring.d.ts +2 -1
- package/dist/types/authoring.d.ts.map +1 -1
- package/dist/types/authoring.js.map +1 -1
- package/dist/types/chess.d.ts +27 -20
- package/dist/types/chess.d.ts.map +1 -1
- package/dist/types/chess.js.map +1 -1
- package/package.json +31 -92
- package/src/features/chess/adapters/inbound/ChessBoard.tsx +263 -112
- package/src/features/chess/meta.ts +64 -40
- package/src/features/chess/public.test.tsx +77 -228
- package/src/features/chess/public.ts +2 -9
- package/src/features/chess/utils/createChessBoardCellPressHandler.ts +30 -0
- package/src/features/chess/utils/createChessBoardCells.ts +54 -0
- package/src/features/chessTabletopOwnership.test.ts +3 -7
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphController.test.ts +145 -1
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphController.ts +86 -5
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.test.ts +163 -6
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.ts +57 -8
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.test.ts +42 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.ts +7 -1
- package/src/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.test.ts +7 -3
- package/src/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.ts +7 -3
- package/src/features/registry/componentMeta.test.ts +12 -1
- package/src/readerFree.ts +3 -15
- package/src/types/authoring.ts +2 -1
- package/src/types/chess.ts +28 -21
- package/web-dist/chunks/Accordion-91sjb3zh.js +453 -0
- package/web-dist/components/chess-board/ChessBoard.js +2 -1
- package/web-dist/components/graph-view/GraphView.js +107 -17
- package/web-dist/components/opening-book/OpeningBook.js +2 -1
- package/web-dist/manifest.json +8 -4
- package/dist/features/chess/utils/chessEngine.d.ts +0 -8
- package/dist/features/chess/utils/chessEngine.d.ts.map +0 -1
- package/dist/features/chess/utils/chessEngine.js +0 -71
- package/dist/features/chess/utils/chessEngine.js.map +0 -1
- package/dist/features/chess/utils/chessSquares.d.ts +0 -4
- package/dist/features/chess/utils/chessSquares.d.ts.map +0 -1
- package/dist/features/chess/utils/chessSquares.js +0 -3
- package/dist/features/chess/utils/chessSquares.js.map +0 -1
- package/dist/features/chess/utils/createBoardSquares.d.ts +0 -4
- package/dist/features/chess/utils/createBoardSquares.d.ts.map +0 -1
- package/dist/features/chess/utils/createBoardSquares.js +0 -9
- package/dist/features/chess/utils/createBoardSquares.js.map +0 -1
- package/dist/features/chess/utils/getSquareFile.d.ts +0 -4
- package/dist/features/chess/utils/getSquareFile.d.ts.map +0 -1
- package/dist/features/chess/utils/getSquareFile.js +0 -5
- package/dist/features/chess/utils/getSquareFile.js.map +0 -1
- package/dist/features/chess/utils/getSquareRank.d.ts +0 -4
- package/dist/features/chess/utils/getSquareRank.d.ts.map +0 -1
- package/dist/features/chess/utils/getSquareRank.js +0 -5
- package/dist/features/chess/utils/getSquareRank.js.map +0 -1
- package/dist/features/chess/utils/isLightSquare.d.ts +0 -4
- package/dist/features/chess/utils/isLightSquare.d.ts.map +0 -1
- package/dist/features/chess/utils/isLightSquare.js +0 -6
- package/dist/features/chess/utils/isLightSquare.js.map +0 -1
- package/src/features/chess/utils/chessEngine.test.ts +0 -35
- package/src/features/chess/utils/chessEngine.ts +0 -83
- package/src/features/chess/utils/chessSquares.ts +0 -6
- package/src/features/chess/utils/createBoardSquares.ts +0 -13
- package/src/features/chess/utils/getSquareFile.ts +0 -6
- package/src/features/chess/utils/getSquareRank.ts +0 -6
- package/src/features/chess/utils/isLightSquare.ts +0 -8
- package/web-dist/chunks/Accordion-xcm1qc39.js +0 -3813
|
@@ -122736,7 +122736,8 @@ function createGraphController(cy, fitPaddingRef, optimizeFit) {
|
|
|
122736
122736
|
readableSize: 0,
|
|
122737
122737
|
fitSize: Infinity,
|
|
122738
122738
|
readableZoom: 0,
|
|
122739
|
-
fitZoom: Infinity
|
|
122739
|
+
fitZoom: Infinity,
|
|
122740
|
+
resizeSnapshot: null
|
|
122740
122741
|
};
|
|
122741
122742
|
const controller = {
|
|
122742
122743
|
fit(options) {
|
|
@@ -122786,6 +122787,9 @@ function createGraphController(cy, fitPaddingRef, optimizeFit) {
|
|
|
122786
122787
|
getReadableZoomTarget() {
|
|
122787
122788
|
return state.readableZoom;
|
|
122788
122789
|
},
|
|
122790
|
+
beginResize() {
|
|
122791
|
+
state.resizeSnapshot = captureResizeSnapshot(cy);
|
|
122792
|
+
},
|
|
122789
122793
|
settle(fit) {
|
|
122790
122794
|
const logicalZoom = cy.zoom() / state.scale;
|
|
122791
122795
|
const fonts = cy.nodes().filter((node) => !node.isParent() && Boolean(node.style("label"))).map((node) => Number.parseFloat(String(node.style("font-size")))).filter((size) => Number.isFinite(size) && size > 0);
|
|
@@ -122793,15 +122797,66 @@ function createGraphController(cy, fitPaddingRef, optimizeFit) {
|
|
|
122793
122797
|
state.fitZoom = fonts.length ? state.fitSize / fonts.reduce((maximum, size) => Math.max(maximum, size), 0) : Infinity;
|
|
122794
122798
|
state.scale = state.relative ? Math.min(getNodeFitZoom(cy, fitPaddingRef.current), state.fitZoom) : 1;
|
|
122795
122799
|
applyZoomLimits(cy, state);
|
|
122796
|
-
if (fit)
|
|
122800
|
+
if (fit) {
|
|
122801
|
+
state.resizeSnapshot = null;
|
|
122802
|
+
controller.fit();
|
|
122803
|
+
} else if (settlePreservedViewport(cy, state, logicalZoom))
|
|
122797
122804
|
controller.fit();
|
|
122798
|
-
else if (state.relative) {
|
|
122799
|
-
setCenteredZoom(cy, logicalZoom * state.scale);
|
|
122800
|
-
cy.center(cy.nodes());
|
|
122801
|
-
}
|
|
122802
122805
|
}
|
|
122803
122806
|
};
|
|
122804
122807
|
}
|
|
122808
|
+
function captureResizeSnapshot(cy) {
|
|
122809
|
+
const viewport = { width: cy.width(), height: cy.height() };
|
|
122810
|
+
const zoom = cy.zoom();
|
|
122811
|
+
if (!isUsableViewport(viewport) || !Number.isFinite(zoom) || zoom <= 0)
|
|
122812
|
+
return null;
|
|
122813
|
+
const pan = cy.pan();
|
|
122814
|
+
const renderedCenter = { x: viewport.width / 2, y: viewport.height / 2 };
|
|
122815
|
+
return {
|
|
122816
|
+
center: {
|
|
122817
|
+
x: (renderedCenter.x - pan.x) / zoom,
|
|
122818
|
+
y: (renderedCenter.y - pan.y) / zoom
|
|
122819
|
+
},
|
|
122820
|
+
nodeBounds: getNodeBoundsStatus(cy, viewport)
|
|
122821
|
+
};
|
|
122822
|
+
}
|
|
122823
|
+
function settlePreservedViewport(cy, state, logicalZoom) {
|
|
122824
|
+
const snapshot = state.resizeSnapshot;
|
|
122825
|
+
state.resizeSnapshot = null;
|
|
122826
|
+
const zoom = state.relative ? logicalZoom * state.scale : cy.zoom();
|
|
122827
|
+
if (snapshot === null) {
|
|
122828
|
+
if (state.relative)
|
|
122829
|
+
setCenteredZoom(cy, zoom);
|
|
122830
|
+
return false;
|
|
122831
|
+
}
|
|
122832
|
+
const viewport = { width: cy.width(), height: cy.height() };
|
|
122833
|
+
if (!isUsableViewport(viewport))
|
|
122834
|
+
return false;
|
|
122835
|
+
cy.viewport({
|
|
122836
|
+
zoom,
|
|
122837
|
+
pan: {
|
|
122838
|
+
x: viewport.width / 2 - snapshot.center.x * zoom,
|
|
122839
|
+
y: viewport.height / 2 - snapshot.center.y * zoom
|
|
122840
|
+
}
|
|
122841
|
+
});
|
|
122842
|
+
const nodeBounds = getNodeBoundsStatus(cy, viewport);
|
|
122843
|
+
return nodeBounds === "unusable" || snapshot.nodeBounds === "fit" && nodeBounds === "clipped";
|
|
122844
|
+
}
|
|
122845
|
+
function getNodeBoundsStatus(cy, viewport) {
|
|
122846
|
+
if (cy.nodes().empty())
|
|
122847
|
+
return "empty";
|
|
122848
|
+
if (!isUsableViewport(viewport))
|
|
122849
|
+
return "unusable";
|
|
122850
|
+
const bounds = cy.nodes().renderedBoundingBox();
|
|
122851
|
+
if (![bounds.x1, bounds.x2, bounds.y1, bounds.y2].every(Number.isFinite))
|
|
122852
|
+
return "unusable";
|
|
122853
|
+
const fitsHorizontally = bounds.x1 >= 0 && bounds.x2 <= viewport.width;
|
|
122854
|
+
const fitsVertically = bounds.y1 >= 0 && bounds.y2 <= viewport.height;
|
|
122855
|
+
return fitsHorizontally && fitsVertically ? "fit" : "clipped";
|
|
122856
|
+
}
|
|
122857
|
+
function isUsableViewport(viewport) {
|
|
122858
|
+
return Number.isFinite(viewport.width) && Number.isFinite(viewport.height) && viewport.width > 0 && viewport.height > 0;
|
|
122859
|
+
}
|
|
122805
122860
|
function measureRenderedNodes(cy, nodeIds) {
|
|
122806
122861
|
const viewport = { width: cy.width(), height: cy.height() };
|
|
122807
122862
|
if (viewport.width <= 0 || viewport.height <= 0 || nodeIds.length === 0)
|
|
@@ -122900,31 +122955,62 @@ function createGraphResizeObserver(input) {
|
|
|
122900
122955
|
if (Observer === null)
|
|
122901
122956
|
return null;
|
|
122902
122957
|
const sizeRef = { height: -1, width: -1 };
|
|
122958
|
+
const pendingLayoutResizeRef = { current: false };
|
|
122959
|
+
const pendingResizeSnapshotRef = { current: false };
|
|
122960
|
+
const resizeScheduledRef = { current: false };
|
|
122903
122961
|
const observer = new Observer((entries) => {
|
|
122904
122962
|
const entry = entries.at(0);
|
|
122905
122963
|
if (entry === undefined || !hasSizeChanged(sizeRef, entry.contentRect))
|
|
122906
122964
|
return;
|
|
122907
122965
|
sizeRef.height = entry.contentRect.height;
|
|
122908
122966
|
sizeRef.width = entry.contentRect.width;
|
|
122909
|
-
if (input.layoutRunningRef.current)
|
|
122910
|
-
return;
|
|
122911
122967
|
if (!input.readyRef.current && !input.pendingInitialFitRef.current)
|
|
122912
122968
|
return;
|
|
122913
|
-
|
|
122969
|
+
captureResizeSnapshot2(input, pendingResizeSnapshotRef);
|
|
122970
|
+
if (input.layoutRunningRef.current) {
|
|
122971
|
+
pendingLayoutResizeRef.current = true;
|
|
122972
|
+
return;
|
|
122973
|
+
}
|
|
122974
|
+
scheduleResizeFit(input, pendingLayoutResizeRef, pendingResizeSnapshotRef, resizeScheduledRef);
|
|
122914
122975
|
});
|
|
122915
122976
|
observer.observe(input.container);
|
|
122916
|
-
return
|
|
122977
|
+
return {
|
|
122978
|
+
disconnect: () => observer.disconnect(),
|
|
122979
|
+
flushAfterLayout: () => flushAfterLayout(input, pendingLayoutResizeRef, pendingResizeSnapshotRef)
|
|
122980
|
+
};
|
|
122981
|
+
}
|
|
122982
|
+
function captureResizeSnapshot2(input, pendingResizeSnapshotRef) {
|
|
122983
|
+
if (pendingResizeSnapshotRef.current)
|
|
122984
|
+
return;
|
|
122985
|
+
input.beginViewportResize();
|
|
122986
|
+
pendingResizeSnapshotRef.current = true;
|
|
122987
|
+
}
|
|
122988
|
+
function flushAfterLayout(input, pendingLayoutResizeRef, pendingResizeSnapshotRef) {
|
|
122989
|
+
if (!pendingLayoutResizeRef.current || input.cy.destroyed() || input.layoutRunningRef.current)
|
|
122990
|
+
return;
|
|
122991
|
+
pendingLayoutResizeRef.current = false;
|
|
122992
|
+
pendingResizeSnapshotRef.current = false;
|
|
122993
|
+
input.cy.resize();
|
|
122917
122994
|
}
|
|
122918
|
-
function scheduleResizeFit(input) {
|
|
122995
|
+
function scheduleResizeFit(input, pendingLayoutResizeRef, pendingResizeSnapshotRef, resizeScheduledRef) {
|
|
122996
|
+
if (resizeScheduledRef.current)
|
|
122997
|
+
return;
|
|
122998
|
+
resizeScheduledRef.current = true;
|
|
122919
122999
|
scheduleGraphFrame(() => {
|
|
122920
|
-
|
|
123000
|
+
resizeScheduledRef.current = false;
|
|
123001
|
+
if (input.cy.destroyed())
|
|
122921
123002
|
return;
|
|
123003
|
+
if (input.layoutRunningRef.current) {
|
|
123004
|
+
pendingLayoutResizeRef.current = true;
|
|
123005
|
+
return;
|
|
123006
|
+
}
|
|
122922
123007
|
input.cy.resize();
|
|
122923
123008
|
if (input.cy.width() <= 0 || input.cy.height() <= 0)
|
|
122924
123009
|
return;
|
|
123010
|
+
pendingResizeSnapshotRef.current = false;
|
|
122925
123011
|
const completedPendingInitialFit = input.pendingInitialFitRef.current;
|
|
122926
123012
|
input.pendingInitialFitRef.current = false;
|
|
122927
|
-
input.settleViewport();
|
|
123013
|
+
input.settleViewport(completedPendingInitialFit);
|
|
122928
123014
|
input.onViewportSettled(completedPendingInitialFit);
|
|
122929
123015
|
});
|
|
122930
123016
|
}
|
|
@@ -123233,8 +123319,8 @@ function stopGraphLayout(layout, handleStop) {
|
|
|
123233
123319
|
}
|
|
123234
123320
|
|
|
123235
123321
|
// src/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.ts
|
|
123236
|
-
function shouldFitGraphAfterLayout(ready, topologyChanged) {
|
|
123237
|
-
return !ready || topologyChanged;
|
|
123322
|
+
function shouldFitGraphAfterLayout(ready, topologyChanged, layoutChanged) {
|
|
123323
|
+
return !ready || topologyChanged || layoutChanged;
|
|
123238
123324
|
}
|
|
123239
123325
|
|
|
123240
123326
|
// src/features/graph-view/adapters/inbound/web-artifact/sizeGraphNodesToLabels.ts
|
|
@@ -123384,6 +123470,7 @@ function createRuntimeState(cy, container, callbacksRef) {
|
|
|
123384
123470
|
loopSizer: createGraphLoopSizer(cy),
|
|
123385
123471
|
pendingInitialFitRef: { current: false },
|
|
123386
123472
|
readyRef,
|
|
123473
|
+
settledLayoutRef: { current: null },
|
|
123387
123474
|
settledTopologyRef: { current: null },
|
|
123388
123475
|
relayoutScheduledRef: { current: false },
|
|
123389
123476
|
renderedNodeListeners
|
|
@@ -123392,7 +123479,8 @@ function createRuntimeState(cy, container, callbacksRef) {
|
|
|
123392
123479
|
const resizeObserver = createGraphResizeObserver({
|
|
123393
123480
|
container,
|
|
123394
123481
|
cy,
|
|
123395
|
-
|
|
123482
|
+
beginViewportResize: () => viewport.beginResize(),
|
|
123483
|
+
settleViewport: (fit) => viewport.settle(fit),
|
|
123396
123484
|
layoutRunningRef,
|
|
123397
123485
|
pendingInitialFitRef: stateBase.pendingInitialFitRef,
|
|
123398
123486
|
onViewportSettled: (completedPendingInitialFit) => {
|
|
@@ -123468,6 +123556,7 @@ function completeCurrentLayout(state, generation) {
|
|
|
123468
123556
|
state.layoutRef.current = null;
|
|
123469
123557
|
state.cy.resize();
|
|
123470
123558
|
state.layoutRunningRef.current = false;
|
|
123559
|
+
state.resizeObserver?.flushAfterLayout();
|
|
123471
123560
|
if (!hasUsableViewport(state.cy)) {
|
|
123472
123561
|
if (!state.readyRef.current)
|
|
123473
123562
|
state.pendingInitialFitRef.current = true;
|
|
@@ -123478,8 +123567,9 @@ function completeCurrentLayout(state, generation) {
|
|
|
123478
123567
|
if (input === null)
|
|
123479
123568
|
return;
|
|
123480
123569
|
const topology = getGraphTopologyKey(input.nodes, input.edges);
|
|
123481
|
-
const shouldFit = shouldFitGraphAfterLayout(state.readyRef.current, topology !== state.settledTopologyRef.current);
|
|
123570
|
+
const shouldFit = shouldFitGraphAfterLayout(state.readyRef.current, topology !== state.settledTopologyRef.current, input.layout !== state.settledLayoutRef.current);
|
|
123482
123571
|
state.viewport.settle(shouldFit);
|
|
123572
|
+
state.settledLayoutRef.current = input.layout;
|
|
123483
123573
|
state.settledTopologyRef.current = topology;
|
|
123484
123574
|
const fitRequest = state.fitRequestRef.current;
|
|
123485
123575
|
state.fitRequestRef.current = null;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import"../../chunks/Accordion-t0k1cjca.js";
|
|
2
3
|
import"../../chunks/Accordion-6wrr910w.js";
|
|
3
4
|
import"../../chunks/Accordion-vj1m2wck.js";
|
|
4
5
|
import {
|
|
5
6
|
ChessBoard2,
|
|
6
7
|
OpeningBook2
|
|
7
|
-
} from "../../chunks/Accordion-
|
|
8
|
+
} from "../../chunks/Accordion-91sjb3zh.js";
|
|
8
9
|
import"../../chunks/Accordion-srjya6dz.js";
|
|
9
10
|
import"../../chunks/Accordion-xgpzh4wq.js";
|
|
10
11
|
export {
|
package/web-dist/manifest.json
CHANGED
|
@@ -870,12 +870,14 @@
|
|
|
870
870
|
"components/chess-board/index.js",
|
|
871
871
|
"components/chess-board/index.d.ts",
|
|
872
872
|
"chunks/Accordion-6wrr910w.js",
|
|
873
|
+
"chunks/Accordion-91sjb3zh.js",
|
|
873
874
|
"chunks/Accordion-fcczvwgg.js",
|
|
874
875
|
"chunks/Accordion-nh0cs9hq.js",
|
|
875
876
|
"chunks/Accordion-srjya6dz.js",
|
|
877
|
+
"chunks/Accordion-t0k1cjca.js",
|
|
876
878
|
"chunks/Accordion-vj1m2wck.js",
|
|
877
|
-
"chunks/Accordion-
|
|
878
|
-
"chunks/Accordion-
|
|
879
|
+
"chunks/Accordion-xgpzh4wq.js",
|
|
880
|
+
"chunks/Accordion-zypyr9xw.js"
|
|
879
881
|
],
|
|
880
882
|
"sourceKind": "public"
|
|
881
883
|
},
|
|
@@ -2372,12 +2374,14 @@
|
|
|
2372
2374
|
"components/opening-book/index.js",
|
|
2373
2375
|
"components/opening-book/index.d.ts",
|
|
2374
2376
|
"chunks/Accordion-6wrr910w.js",
|
|
2377
|
+
"chunks/Accordion-91sjb3zh.js",
|
|
2375
2378
|
"chunks/Accordion-fcczvwgg.js",
|
|
2376
2379
|
"chunks/Accordion-nh0cs9hq.js",
|
|
2377
2380
|
"chunks/Accordion-srjya6dz.js",
|
|
2381
|
+
"chunks/Accordion-t0k1cjca.js",
|
|
2378
2382
|
"chunks/Accordion-vj1m2wck.js",
|
|
2379
|
-
"chunks/Accordion-
|
|
2380
|
-
"chunks/Accordion-
|
|
2383
|
+
"chunks/Accordion-xgpzh4wq.js",
|
|
2384
|
+
"chunks/Accordion-zypyr9xw.js"
|
|
2381
2385
|
],
|
|
2382
2386
|
"sourceKind": "public"
|
|
2383
2387
|
},
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ChessMoveAttempt, ChessMoveResult, ChessPieceState, ChessSquareId } from '../../../types/chess';
|
|
2
|
-
/*** Read all pieces from a FEN-backed position. Invalid FEN produces an empty position. */
|
|
3
|
-
export declare function readChessPieces(fen: string): ReadonlyMap<ChessSquareId, ChessPieceState>;
|
|
4
|
-
/*** Resolve legal destination squares from one FEN position and source square. */
|
|
5
|
-
export declare function getLegalTargets(fen: string, from: ChessSquareId): readonly ChessSquareId[];
|
|
6
|
-
/*** Attempt one legal chess move against FEN and return the resulting position/move notation. */
|
|
7
|
-
export declare function tryMove(fen: string, attempt: ChessMoveAttempt): ChessMoveResult | null;
|
|
8
|
-
//# sourceMappingURL=chessEngine.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chessEngine.d.ts","sourceRoot":"","sources":["../../../../src/features/chess/utils/chessEngine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EAEf,eAAe,EAEf,aAAa,EACd,MAAM,sBAAsB,CAAC;AAiC9B,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC,aAAa,EAAE,eAAe,CAAC,CAgBxF;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,SAAS,aAAa,EAAE,CAG1F;AAED,iGAAiG;AACjG,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,eAAe,GAAG,IAAI,CActF"}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { Chess } from 'chess.js';
|
|
2
|
-
/*** Create a chess.js position from FEN without leaking invalid-position exceptions. */
|
|
3
|
-
function createChess(fen) {
|
|
4
|
-
try {
|
|
5
|
-
return new Chess(fen);
|
|
6
|
-
}
|
|
7
|
-
catch {
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
/*** Convert a chess.js piece into the public ZORA piece code. */
|
|
12
|
-
function toPieceCode(piece) {
|
|
13
|
-
return piece.color === 'w' ? piece.type.toUpperCase() : piece.type.toLowerCase();
|
|
14
|
-
}
|
|
15
|
-
/*** Normalize a chess.js promotion marker into the public promotion union. */
|
|
16
|
-
function toPromotionPiece(piece) {
|
|
17
|
-
return piece === 'q' || piece === 'r' || piece === 'b' || piece === 'n' ? piece : undefined;
|
|
18
|
-
}
|
|
19
|
-
/*** Convert one successful chess.js move into the public result contract. */
|
|
20
|
-
function toMoveResult(move, fen) {
|
|
21
|
-
return {
|
|
22
|
-
fen,
|
|
23
|
-
from: move.from,
|
|
24
|
-
lan: move.lan,
|
|
25
|
-
promotion: toPromotionPiece(move.promotion),
|
|
26
|
-
san: move.san,
|
|
27
|
-
to: move.to,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
/*** Read all pieces from a FEN-backed position. Invalid FEN produces an empty position. */
|
|
31
|
-
export function readChessPieces(fen) {
|
|
32
|
-
const chess = createChess(fen);
|
|
33
|
-
const pieces = new Map();
|
|
34
|
-
if (!chess)
|
|
35
|
-
return pieces;
|
|
36
|
-
for (const rank of chess.board()) {
|
|
37
|
-
for (const piece of rank) {
|
|
38
|
-
if (!piece)
|
|
39
|
-
continue;
|
|
40
|
-
pieces.set(piece.square, {
|
|
41
|
-
color: piece.color === 'w' ? 'white' : 'black',
|
|
42
|
-
piece: toPieceCode(piece),
|
|
43
|
-
square: piece.square,
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return pieces;
|
|
48
|
-
}
|
|
49
|
-
/*** Resolve legal destination squares from one FEN position and source square. */
|
|
50
|
-
export function getLegalTargets(fen, from) {
|
|
51
|
-
const chess = createChess(fen);
|
|
52
|
-
return chess ? chess.moves({ square: from, verbose: true }).map((move) => move.to) : [];
|
|
53
|
-
}
|
|
54
|
-
/*** Attempt one legal chess move against FEN and return the resulting position/move notation. */
|
|
55
|
-
export function tryMove(fen, attempt) {
|
|
56
|
-
const chess = createChess(fen);
|
|
57
|
-
if (!chess)
|
|
58
|
-
return null;
|
|
59
|
-
try {
|
|
60
|
-
const move = chess.move({
|
|
61
|
-
from: attempt.from,
|
|
62
|
-
promotion: attempt.promotion,
|
|
63
|
-
to: attempt.to,
|
|
64
|
-
});
|
|
65
|
-
return toMoveResult(move, chess.fen());
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
//# sourceMappingURL=chessEngine.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chessEngine.js","sourceRoot":"","sources":["../../../../src/features/chess/utils/chessEngine.ts"],"names":[],"mappings":"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","sourcesContent":["import { Chess, type Move } from 'chess.js';\n\nimport type {\n ChessMoveAttempt,\n ChessMoveResult,\n ChessPieceCode,\n ChessPieceState,\n ChessPromotionPiece,\n ChessSquareId,\n} from '../../../types/chess';\n\n/*** Create a chess.js position from FEN without leaking invalid-position exceptions. */\nfunction createChess(fen: string): Chess | null {\n try {\n return new Chess(fen);\n } catch {\n return null;\n }\n}\n\n/*** Convert a chess.js piece into the public ZORA piece code. */\nfunction toPieceCode(piece: { readonly color: 'b' | 'w'; readonly type: string }): ChessPieceCode {\n return piece.color === 'w' ? piece.type.toUpperCase() : piece.type.toLowerCase();\n}\n\n/*** Normalize a chess.js promotion marker into the public promotion union. */\nfunction toPromotionPiece(piece: string | undefined): ChessPromotionPiece | undefined {\n return piece === 'q' || piece === 'r' || piece === 'b' || piece === 'n' ? piece : undefined;\n}\n\n/*** Convert one successful chess.js move into the public result contract. */\nfunction toMoveResult(move: Move, fen: string): ChessMoveResult {\n return {\n fen,\n from: move.from,\n lan: move.lan,\n promotion: toPromotionPiece(move.promotion),\n san: move.san,\n to: move.to,\n };\n}\n\n/*** Read all pieces from a FEN-backed position. Invalid FEN produces an empty position. */\nexport function readChessPieces(fen: string): ReadonlyMap<ChessSquareId, ChessPieceState> {\n const chess = createChess(fen);\n const pieces = new Map<ChessSquareId, ChessPieceState>();\n if (!chess) return pieces;\n\n for (const rank of chess.board()) {\n for (const piece of rank) {\n if (!piece) continue;\n pieces.set(piece.square, {\n color: piece.color === 'w' ? 'white' : 'black',\n piece: toPieceCode(piece),\n square: piece.square,\n });\n }\n }\n return pieces;\n}\n\n/*** Resolve legal destination squares from one FEN position and source square. */\nexport function getLegalTargets(fen: string, from: ChessSquareId): readonly ChessSquareId[] {\n const chess = createChess(fen);\n return chess ? chess.moves({ square: from, verbose: true }).map((move) => move.to) : [];\n}\n\n/*** Attempt one legal chess move against FEN and return the resulting position/move notation. */\nexport function tryMove(fen: string, attempt: ChessMoveAttempt): ChessMoveResult | null {\n const chess = createChess(fen);\n if (!chess) return null;\n\n try {\n const move = chess.move({\n from: attempt.from,\n promotion: attempt.promotion,\n to: attempt.to,\n });\n return toMoveResult(move, chess.fen());\n } catch {\n return null;\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chessSquares.d.ts","sourceRoot":"","sources":["../../../../src/features/chess/utils/chessSquares.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,kEAAkE;AAClE,eAAO,MAAM,YAAY,EAAE,SAAS,aAAa,EAEhD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chessSquares.js","sourceRoot":"","sources":["../../../../src/features/chess/utils/chessSquares.ts"],"names":[],"mappings":"AAEA,kEAAkE;AAClE,MAAM,CAAC,MAAM,YAAY,GAA6B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC9F,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,EAAmB,CAAC,CACjE,CAAC","sourcesContent":["import type { ChessSquareId } from '../../../types/chess';\n\n/*** Lists every board square in ascending rank and file order. */\nexport const chessSquares: readonly ChessSquareId[] = [1, 2, 3, 4, 5, 6, 7, 8].flatMap((rank) =>\n [...'abcdefgh'].map((file) => `${file}${rank}` as ChessSquareId),\n);\n"]}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { ChessBoardOrientation, ChessSquareId } from '../../../types/chess';
|
|
2
|
-
/*** Orders the 64 displayed squares for the selected player orientation. */
|
|
3
|
-
export declare function createBoardSquares(orientation: ChessBoardOrientation): readonly ChessSquareId[];
|
|
4
|
-
//# sourceMappingURL=createBoardSquares.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createBoardSquares.d.ts","sourceRoot":"","sources":["../../../../src/features/chess/utils/createBoardSquares.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAKjF,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,qBAAqB,GAAG,SAAS,aAAa,EAAE,CAM/F"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
const files = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
|
|
2
|
-
const ranks = ['1', '2', '3', '4', '5', '6', '7', '8'];
|
|
3
|
-
/*** Orders the 64 displayed squares for the selected player orientation. */
|
|
4
|
-
export function createBoardSquares(orientation) {
|
|
5
|
-
const displayedRanks = orientation === 'white' ? [...ranks].reverse() : [...ranks];
|
|
6
|
-
const displayedFiles = orientation === 'white' ? [...files] : [...files].reverse();
|
|
7
|
-
return displayedRanks.flatMap((rank) => displayedFiles.map((file) => `${file}${rank}`));
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=createBoardSquares.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createBoardSquares.js","sourceRoot":"","sources":["../../../../src/features/chess/utils/createBoardSquares.ts"],"names":[],"mappings":"AAEA,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC;AAChE,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC;AAEhE,4EAA4E;AAC5E,MAAM,UAAU,kBAAkB,CAAC,WAAkC;IACnE,MAAM,cAAc,GAAG,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;IACnF,MAAM,cAAc,GAAG,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;IACnF,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACrC,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAiB,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAC9D,CAAC;AACJ,CAAC","sourcesContent":["import type { ChessBoardOrientation, ChessSquareId } from '../../../types/chess';\n\nconst files = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] as const;\nconst ranks = ['1', '2', '3', '4', '5', '6', '7', '8'] as const;\n\n/*** Orders the 64 displayed squares for the selected player orientation. */\nexport function createBoardSquares(orientation: ChessBoardOrientation): readonly ChessSquareId[] {\n const displayedRanks = orientation === 'white' ? [...ranks].reverse() : [...ranks];\n const displayedFiles = orientation === 'white' ? [...files] : [...files].reverse();\n return displayedRanks.flatMap((rank) =>\n displayedFiles.map((file): ChessSquareId => `${file}${rank}`),\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getSquareFile.d.ts","sourceRoot":"","sources":["../../../../src/features/chess/utils/getSquareFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,kDAAkD;AAClD,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAE3D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getSquareFile.js","sourceRoot":"","sources":["../../../../src/features/chess/utils/getSquareFile.ts"],"names":[],"mappings":"AAEA,kDAAkD;AAClD,MAAM,UAAU,aAAa,CAAC,MAAqB;IACjD,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC","sourcesContent":["import type { ChessSquareId } from '../../../types/chess';\n\n/*** Returns the file letter of a chess square. */\nexport function getSquareFile(square: ChessSquareId): string {\n return square[0] ?? '';\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getSquareRank.d.ts","sourceRoot":"","sources":["../../../../src/features/chess/utils/getSquareRank.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,kDAAkD;AAClD,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAE3D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getSquareRank.js","sourceRoot":"","sources":["../../../../src/features/chess/utils/getSquareRank.ts"],"names":[],"mappings":"AAEA,kDAAkD;AAClD,MAAM,UAAU,aAAa,CAAC,MAAqB;IACjD,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC","sourcesContent":["import type { ChessSquareId } from '../../../types/chess';\n\n/*** Returns the rank number of a chess square. */\nexport function getSquareRank(square: ChessSquareId): string {\n return square[1] ?? '';\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isLightSquare.d.ts","sourceRoot":"","sources":["../../../../src/features/chess/utils/isLightSquare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI1D,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAE5D"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
const files = 'abcdefgh';
|
|
2
|
-
/*** Determines whether a chess square uses the light presentation color. */
|
|
3
|
-
export function isLightSquare(square) {
|
|
4
|
-
return (files.indexOf(square[0] ?? '') + Number(square[1]) - 1) % 2 === 1;
|
|
5
|
-
}
|
|
6
|
-
//# sourceMappingURL=isLightSquare.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isLightSquare.js","sourceRoot":"","sources":["../../../../src/features/chess/utils/isLightSquare.ts"],"names":[],"mappings":"AAEA,MAAM,KAAK,GAAG,UAAU,CAAC;AAEzB,4EAA4E;AAC5E,MAAM,UAAU,aAAa,CAAC,MAAqB;IACjD,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC5E,CAAC","sourcesContent":["import type { ChessSquareId } from '../../../types/chess';\n\nconst files = 'abcdefgh';\n\n/*** Determines whether a chess square uses the light presentation color. */\nexport function isLightSquare(square: ChessSquareId): boolean {\n return (files.indexOf(square[0] ?? '') + Number(square[1]) - 1) % 2 === 1;\n}\n"]}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test';
|
|
2
|
-
|
|
3
|
-
import { getLegalTargets, readChessPieces, tryMove } from './chessEngine';
|
|
4
|
-
|
|
5
|
-
const START_FEN = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';
|
|
6
|
-
|
|
7
|
-
describe('core chess engine', () => {
|
|
8
|
-
it('reads pieces from FEN and preserves piece codes', () => {
|
|
9
|
-
const pieces = readChessPieces(START_FEN);
|
|
10
|
-
|
|
11
|
-
expect(pieces.size).toBe(32);
|
|
12
|
-
expect(pieces.get('e1')?.piece).toBe('K');
|
|
13
|
-
expect(pieces.get('e8')?.piece).toBe('k');
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('returns an empty map for invalid FEN', () => {
|
|
17
|
-
expect(readChessPieces('invalid').size).toBe(0);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('returns legal target squares', () => {
|
|
21
|
-
expect(getLegalTargets(START_FEN, 'e2')).toEqual(['e3', 'e4']);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('returns resulting move details for legal moves', () => {
|
|
25
|
-
const result = tryMove(START_FEN, { from: 'e2', to: 'e4' });
|
|
26
|
-
|
|
27
|
-
expect(result?.san).toBe('e4');
|
|
28
|
-
expect(result?.lan).toBe('e2e4');
|
|
29
|
-
expect(result?.fen).toContain(' b ');
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('returns null for invalid moves', () => {
|
|
33
|
-
expect(tryMove(START_FEN, { from: 'e2', to: 'e5' })).toBeNull();
|
|
34
|
-
});
|
|
35
|
-
});
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { Chess, type Move } from 'chess.js';
|
|
2
|
-
|
|
3
|
-
import type {
|
|
4
|
-
ChessMoveAttempt,
|
|
5
|
-
ChessMoveResult,
|
|
6
|
-
ChessPieceCode,
|
|
7
|
-
ChessPieceState,
|
|
8
|
-
ChessPromotionPiece,
|
|
9
|
-
ChessSquareId,
|
|
10
|
-
} from '../../../types/chess';
|
|
11
|
-
|
|
12
|
-
/*** Create a chess.js position from FEN without leaking invalid-position exceptions. */
|
|
13
|
-
function createChess(fen: string): Chess | null {
|
|
14
|
-
try {
|
|
15
|
-
return new Chess(fen);
|
|
16
|
-
} catch {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/*** Convert a chess.js piece into the public ZORA piece code. */
|
|
22
|
-
function toPieceCode(piece: { readonly color: 'b' | 'w'; readonly type: string }): ChessPieceCode {
|
|
23
|
-
return piece.color === 'w' ? piece.type.toUpperCase() : piece.type.toLowerCase();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/*** Normalize a chess.js promotion marker into the public promotion union. */
|
|
27
|
-
function toPromotionPiece(piece: string | undefined): ChessPromotionPiece | undefined {
|
|
28
|
-
return piece === 'q' || piece === 'r' || piece === 'b' || piece === 'n' ? piece : undefined;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/*** Convert one successful chess.js move into the public result contract. */
|
|
32
|
-
function toMoveResult(move: Move, fen: string): ChessMoveResult {
|
|
33
|
-
return {
|
|
34
|
-
fen,
|
|
35
|
-
from: move.from,
|
|
36
|
-
lan: move.lan,
|
|
37
|
-
promotion: toPromotionPiece(move.promotion),
|
|
38
|
-
san: move.san,
|
|
39
|
-
to: move.to,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/*** Read all pieces from a FEN-backed position. Invalid FEN produces an empty position. */
|
|
44
|
-
export function readChessPieces(fen: string): ReadonlyMap<ChessSquareId, ChessPieceState> {
|
|
45
|
-
const chess = createChess(fen);
|
|
46
|
-
const pieces = new Map<ChessSquareId, ChessPieceState>();
|
|
47
|
-
if (!chess) return pieces;
|
|
48
|
-
|
|
49
|
-
for (const rank of chess.board()) {
|
|
50
|
-
for (const piece of rank) {
|
|
51
|
-
if (!piece) continue;
|
|
52
|
-
pieces.set(piece.square, {
|
|
53
|
-
color: piece.color === 'w' ? 'white' : 'black',
|
|
54
|
-
piece: toPieceCode(piece),
|
|
55
|
-
square: piece.square,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return pieces;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/*** Resolve legal destination squares from one FEN position and source square. */
|
|
63
|
-
export function getLegalTargets(fen: string, from: ChessSquareId): readonly ChessSquareId[] {
|
|
64
|
-
const chess = createChess(fen);
|
|
65
|
-
return chess ? chess.moves({ square: from, verbose: true }).map((move) => move.to) : [];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/*** Attempt one legal chess move against FEN and return the resulting position/move notation. */
|
|
69
|
-
export function tryMove(fen: string, attempt: ChessMoveAttempt): ChessMoveResult | null {
|
|
70
|
-
const chess = createChess(fen);
|
|
71
|
-
if (!chess) return null;
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
const move = chess.move({
|
|
75
|
-
from: attempt.from,
|
|
76
|
-
promotion: attempt.promotion,
|
|
77
|
-
to: attempt.to,
|
|
78
|
-
});
|
|
79
|
-
return toMoveResult(move, chess.fen());
|
|
80
|
-
} catch {
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { ChessSquareId } from '../../../types/chess';
|
|
2
|
-
|
|
3
|
-
/*** Lists every board square in ascending rank and file order. */
|
|
4
|
-
export const chessSquares: readonly ChessSquareId[] = [1, 2, 3, 4, 5, 6, 7, 8].flatMap((rank) =>
|
|
5
|
-
[...'abcdefgh'].map((file) => `${file}${rank}` as ChessSquareId),
|
|
6
|
-
);
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { ChessBoardOrientation, ChessSquareId } from '../../../types/chess';
|
|
2
|
-
|
|
3
|
-
const files = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] as const;
|
|
4
|
-
const ranks = ['1', '2', '3', '4', '5', '6', '7', '8'] as const;
|
|
5
|
-
|
|
6
|
-
/*** Orders the 64 displayed squares for the selected player orientation. */
|
|
7
|
-
export function createBoardSquares(orientation: ChessBoardOrientation): readonly ChessSquareId[] {
|
|
8
|
-
const displayedRanks = orientation === 'white' ? [...ranks].reverse() : [...ranks];
|
|
9
|
-
const displayedFiles = orientation === 'white' ? [...files] : [...files].reverse();
|
|
10
|
-
return displayedRanks.flatMap((rank) =>
|
|
11
|
-
displayedFiles.map((file): ChessSquareId => `${file}${rank}`),
|
|
12
|
-
);
|
|
13
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ChessSquareId } from '../../../types/chess';
|
|
2
|
-
|
|
3
|
-
const files = 'abcdefgh';
|
|
4
|
-
|
|
5
|
-
/*** Determines whether a chess square uses the light presentation color. */
|
|
6
|
-
export function isLightSquare(square: ChessSquareId): boolean {
|
|
7
|
-
return (files.indexOf(square[0] ?? '') + Number(square[1]) - 1) % 2 === 1;
|
|
8
|
-
}
|