@hackersheet/next-document-content-kifu 0.1.0-alpha.15 → 0.1.0-alpha.17

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.
Files changed (46) hide show
  1. package/dist/cjs/components/kifu/kifu.js +2 -2
  2. package/dist/cjs/components/shogi-player/adapters/kifu-adapter.d.ts +11 -0
  3. package/dist/cjs/components/shogi-player/adapters/kifu-adapter.js +104 -0
  4. package/dist/cjs/components/shogi-player/board-renderer.d.ts +60 -0
  5. package/dist/cjs/components/shogi-player/board-renderer.js +137 -0
  6. package/dist/cjs/components/shogi-player/button.d.ts +22 -1
  7. package/dist/cjs/components/shogi-player/button.js +2 -1
  8. package/dist/cjs/components/shogi-player/canvas-utils.d.ts +29 -0
  9. package/dist/cjs/components/shogi-player/{index.js → canvas-utils.js} +26 -16
  10. package/dist/cjs/components/shogi-player/hands-renderer.d.ts +42 -0
  11. package/dist/cjs/components/shogi-player/hands-renderer.js +86 -0
  12. package/dist/cjs/components/shogi-player/moves-area.d.ts +24 -3
  13. package/dist/cjs/components/shogi-player/moves-area.js +15 -20
  14. package/dist/cjs/components/shogi-player/shogi-board-canvas.d.ts +20 -13
  15. package/dist/cjs/components/shogi-player/shogi-board-canvas.js +9 -119
  16. package/dist/cjs/components/shogi-player/shogi-hands-canvas.d.ts +20 -12
  17. package/dist/cjs/components/shogi-player/shogi-hands-canvas.js +7 -79
  18. package/dist/cjs/components/shogi-player/shogi-player.d.ts +22 -0
  19. package/dist/cjs/components/shogi-player/shogi-player.js +51 -41
  20. package/dist/cjs/components/shogi-player/types.d.ts +169 -0
  21. package/dist/cjs/components/shogi-player/types.js +16 -0
  22. package/dist/esm/components/kifu/kifu.mjs +1 -1
  23. package/dist/esm/components/shogi-player/adapters/kifu-adapter.d.mts +11 -0
  24. package/dist/esm/components/shogi-player/adapters/kifu-adapter.mjs +80 -0
  25. package/dist/esm/components/shogi-player/board-renderer.d.mts +60 -0
  26. package/dist/esm/components/shogi-player/board-renderer.mjs +109 -0
  27. package/dist/esm/components/shogi-player/button.d.mts +22 -1
  28. package/dist/esm/components/shogi-player/button.mjs +2 -1
  29. package/dist/esm/components/shogi-player/canvas-utils.d.mts +29 -0
  30. package/dist/esm/components/shogi-player/canvas-utils.mjs +22 -0
  31. package/dist/esm/components/shogi-player/hands-renderer.d.mts +42 -0
  32. package/dist/esm/components/shogi-player/hands-renderer.mjs +60 -0
  33. package/dist/esm/components/shogi-player/moves-area.d.mts +24 -3
  34. package/dist/esm/components/shogi-player/moves-area.mjs +16 -17
  35. package/dist/esm/components/shogi-player/shogi-board-canvas.d.mts +20 -13
  36. package/dist/esm/components/shogi-player/shogi-board-canvas.mjs +12 -116
  37. package/dist/esm/components/shogi-player/shogi-hands-canvas.d.mts +20 -12
  38. package/dist/esm/components/shogi-player/shogi-hands-canvas.mjs +4 -76
  39. package/dist/esm/components/shogi-player/shogi-player.d.mts +22 -0
  40. package/dist/esm/components/shogi-player/shogi-player.mjs +52 -42
  41. package/dist/esm/components/shogi-player/types.d.mts +169 -0
  42. package/dist/esm/components/shogi-player/types.mjs +0 -0
  43. package/package.json +3 -3
  44. package/dist/cjs/components/shogi-player/index.d.ts +0 -2
  45. package/dist/esm/components/shogi-player/index.d.mts +0 -2
  46. package/dist/esm/components/shogi-player/index.mjs +0 -4
@@ -34,7 +34,7 @@ __export(kifu_exports, {
34
34
  module.exports = __toCommonJS(kifu_exports);
35
35
  var import_navigation = require("next/navigation");
36
36
  var import_react = __toESM(require("react"));
37
- var import_shogi_player = require("../shogi-player");
37
+ var import_shogi_player = __toESM(require("../shogi-player/shogi-player"));
38
38
  function Kifu({ code, language }) {
39
39
  const [ply, setPly] = (0, import_react.useState)(0);
40
40
  const [, filename] = language.split(":");
@@ -47,5 +47,5 @@ function Kifu({ code, language }) {
47
47
  setPly(newPly);
48
48
  }
49
49
  }, [searchParams, id]);
50
- return /* @__PURE__ */ import_react.default.createElement("div", { className: "kifu-block", id }, /* @__PURE__ */ import_react.default.createElement(import_shogi_player.ShogiPlayer, { kifuText: code, tesuu: ply, size: 320 }));
50
+ return /* @__PURE__ */ import_react.default.createElement("div", { className: "kifu-block", id }, /* @__PURE__ */ import_react.default.createElement(import_shogi_player.default, { kifuText: code, tesuu: ply, size: 320 }));
51
51
  }
@@ -0,0 +1,11 @@
1
+ import { KifuAdapter } from '../types.js';
2
+ import 'shogi.js';
3
+
4
+ /**
5
+ * Factory function to create a KifuAdapter from KIF text
6
+ * @param kifuText - KIF format game record text
7
+ * @returns KifuAdapter instance
8
+ */
9
+ declare function createKifuAdapter(kifuText: string): KifuAdapter;
10
+
11
+ export { createKifuAdapter };
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var kifu_adapter_exports = {};
20
+ __export(kifu_adapter_exports, {
21
+ createKifuAdapter: () => createKifuAdapter
22
+ });
23
+ module.exports = __toCommonJS(kifu_adapter_exports);
24
+ var import_json_kifu_format = require("json-kifu-format");
25
+ function convertToMove(move) {
26
+ if (!move?.move) {
27
+ return void 0;
28
+ }
29
+ const m = move.move;
30
+ return {
31
+ from: m.from ? { x: m.from.x, y: m.from.y } : void 0,
32
+ to: m.to ? { x: m.to.x, y: m.to.y } : void 0,
33
+ color: m.color,
34
+ piece: m.piece,
35
+ same: m.same,
36
+ promote: m.promote,
37
+ capture: m.capture,
38
+ relative: m.relative
39
+ };
40
+ }
41
+ class JKFPlayerAdapter {
42
+ player;
43
+ readableMoves;
44
+ constructor(kifuText) {
45
+ this.player = import_json_kifu_format.JKFPlayer.parse(kifuText.trim());
46
+ this.readableMoves = this.buildReadableMoves();
47
+ }
48
+ /**
49
+ * Pre-compute readable move strings for all moves
50
+ */
51
+ buildReadableMoves() {
52
+ const moves = this.player.kifu.moves;
53
+ return moves.map((move, index) => {
54
+ if (index === 0) {
55
+ return "\u958B\u59CB\u5C40\u9762";
56
+ }
57
+ return import_json_kifu_format.JKFPlayer.moveToReadableKifu(move);
58
+ });
59
+ }
60
+ /**
61
+ * Extract current game state from JKFPlayer
62
+ */
63
+ extractState() {
64
+ const header = this.player.kifu.header;
65
+ return {
66
+ board: [...this.player.shogi.board],
67
+ hands: [...this.player.shogi.hands],
68
+ currentMoveIndex: this.player.tesuu,
69
+ maxMoveIndex: this.player.getMaxTesuu(),
70
+ currentMove: convertToMove(this.player.kifu.moves[this.player.tesuu]),
71
+ header: {
72
+ senteName: header["\u5148\u624B"] || header["\u4E0B\u624B"] || "",
73
+ goteName: header["\u5F8C\u624B"] || header["\u4E0A\u624B"] || "",
74
+ ...header
75
+ },
76
+ comments: this.player.getComments(),
77
+ readableMoves: this.readableMoves
78
+ };
79
+ }
80
+ forward() {
81
+ this.player.forward();
82
+ return this.extractState();
83
+ }
84
+ backward() {
85
+ this.player.backward();
86
+ return this.extractState();
87
+ }
88
+ goto(moveIndex) {
89
+ this.player.goto(moveIndex);
90
+ return this.extractState();
91
+ }
92
+ getState() {
93
+ return this.extractState();
94
+ }
95
+ dispose() {
96
+ }
97
+ }
98
+ function createKifuAdapter(kifuText) {
99
+ return new JKFPlayerAdapter(kifuText);
100
+ }
101
+ // Annotate the CommonJS export names for ESM import in node:
102
+ 0 && (module.exports = {
103
+ createKifuAdapter
104
+ });
@@ -0,0 +1,60 @@
1
+ import { Piece } from 'shogi.js';
2
+ import { Move } from './types.js';
3
+
4
+ /**
5
+ * Draw the board background
6
+ * Fills the entire canvas with the board color
7
+ *
8
+ * @param ctx - Canvas rendering context
9
+ * @param size - Canvas size in CSS pixels
10
+ * @param boardColor - Background color hex code
11
+ */
12
+ declare function drawBoardBackground(ctx: CanvasRenderingContext2D, size: number, boardColor: string): void;
13
+ /**
14
+ * Draw the board grid (lines and outer frame)
15
+ * Creates the 9x9 grid structure with outer border
16
+ *
17
+ * @param ctx - Canvas rendering context
18
+ * @param margin - Margin from canvas edge
19
+ * @param boardSize - Total size of the board area
20
+ * @param lineColor - Color of the lines
21
+ */
22
+ declare function drawBoardGrid(ctx: CanvasRenderingContext2D, margin: number, boardSize: number, lineColor: string): void;
23
+ /**
24
+ * Draw all pieces on the board
25
+ * Renders pieces with proper rotation based on perspective
26
+ *
27
+ * @param ctx - Canvas rendering context
28
+ * @param pieces - 2D array of pieces on the board
29
+ * @param margin - Margin from canvas edge
30
+ * @param cell - Size of a single cell
31
+ * @param fontFamily - Font family for piece characters
32
+ * @param fontSizeRatio - Font size ratio relative to cell size
33
+ * @param isSente - Whether rendering from black player's perspective
34
+ */
35
+ declare function drawBoardPieces(ctx: CanvasRenderingContext2D, pieces: (Piece | null)[][], margin: number, cell: number, fontFamily: string, fontSizeRatio: number, isSente: boolean): void;
36
+ /**
37
+ * Draw board coordinates (row and column labels)
38
+ * Displays numbers and kanji labels around the board
39
+ *
40
+ * @param ctx - Canvas rendering context
41
+ * @param margin - Margin from canvas edge
42
+ * @param boardSize - Total size of the board area
43
+ * @param cell - Size of a single cell
44
+ * @param fontFamily - Font family for labels
45
+ * @param isSente - Whether rendering from black player's perspective
46
+ */
47
+ declare function drawBoardCoordinates(ctx: CanvasRenderingContext2D, margin: number, boardSize: number, cell: number, fontFamily: string, isSente: boolean): void;
48
+ /**
49
+ * Highlight the destination and source cells of the current move
50
+ * Uses red semi-transparent rectangles to indicate move locations
51
+ *
52
+ * @param ctx - Canvas rendering context
53
+ * @param margin - Margin from canvas edge
54
+ * @param cell - Size of a single cell
55
+ * @param isSente - Whether rendering from black player's perspective
56
+ * @param currentMove - Current move data, undefined means no highlight
57
+ */
58
+ declare function drawHighlightedCell(ctx: CanvasRenderingContext2D, margin: number, cell: number, isSente: boolean, currentMove?: Move): void;
59
+
60
+ export { drawBoardBackground, drawBoardCoordinates, drawBoardGrid, drawBoardPieces, drawHighlightedCell };
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var board_renderer_exports = {};
20
+ __export(board_renderer_exports, {
21
+ drawBoardBackground: () => drawBoardBackground,
22
+ drawBoardCoordinates: () => drawBoardCoordinates,
23
+ drawBoardGrid: () => drawBoardGrid,
24
+ drawBoardPieces: () => drawBoardPieces,
25
+ drawHighlightedCell: () => drawHighlightedCell
26
+ });
27
+ module.exports = __toCommonJS(board_renderer_exports);
28
+ var import_json_kifu_format = require("json-kifu-format");
29
+ var import_shogi = require("shogi.js");
30
+ function drawBoardBackground(ctx, size, boardColor) {
31
+ ctx.fillStyle = boardColor;
32
+ ctx.fillRect(0, 0, size, size);
33
+ }
34
+ function drawBoardGrid(ctx, margin, boardSize, lineColor) {
35
+ ctx.strokeStyle = lineColor;
36
+ ctx.lineWidth = 2;
37
+ ctx.strokeRect(margin, margin, boardSize, boardSize);
38
+ ctx.lineWidth = 1;
39
+ Array.from({ length: 8 }).forEach((_, i) => {
40
+ const offset = (i + 1) * (boardSize / 9);
41
+ ctx.beginPath();
42
+ ctx.moveTo(margin + offset, margin);
43
+ ctx.lineTo(margin + offset, margin + boardSize);
44
+ ctx.stroke();
45
+ ctx.beginPath();
46
+ ctx.moveTo(margin, margin + offset);
47
+ ctx.lineTo(margin + boardSize, margin + offset);
48
+ ctx.stroke();
49
+ });
50
+ }
51
+ function drawBoardPieces(ctx, pieces, margin, cell, fontFamily, fontSizeRatio, isSente) {
52
+ ctx.textAlign = "center";
53
+ ctx.textBaseline = "middle";
54
+ pieces.forEach((row, rowIndex) => {
55
+ row.forEach((piece, colIndex) => {
56
+ if (!piece) return;
57
+ const x = isSente ? 8 - rowIndex : rowIndex;
58
+ const y = isSente ? colIndex : 8 - colIndex;
59
+ const px = margin + x * cell + cell / 2;
60
+ const py = margin + y * cell + cell / 2;
61
+ ctx.save();
62
+ ctx.translate(px, py);
63
+ if (isSente && piece.color === import_shogi.Color.White) {
64
+ ctx.rotate(Math.PI);
65
+ } else if (!isSente && piece.color === import_shogi.Color.Black) {
66
+ ctx.rotate(Math.PI);
67
+ }
68
+ const kan = import_json_kifu_format.JKFPlayer.kindToKan(piece.kind);
69
+ ctx.fillStyle = "#000";
70
+ if (kan.length === 2) {
71
+ const baseFontSize = cell * fontSizeRatio * 0.5;
72
+ ctx.font = `${baseFontSize}px ${fontFamily}`;
73
+ const scaleX = 2;
74
+ const scaleY = 1;
75
+ const offsetY = cell * 0.18;
76
+ ctx.save();
77
+ ctx.scale(scaleX, scaleY);
78
+ ctx.fillText(kan[0], 0 / scaleX, -offsetY / scaleY);
79
+ ctx.restore();
80
+ ctx.save();
81
+ ctx.scale(scaleX, scaleY);
82
+ ctx.fillText(kan[1], 0 / scaleX, offsetY / scaleY);
83
+ ctx.restore();
84
+ } else {
85
+ const fontSize = cell * fontSizeRatio;
86
+ ctx.font = `${fontSize}px ${fontFamily}`;
87
+ ctx.fillText(kan, 0, 0);
88
+ }
89
+ ctx.restore();
90
+ });
91
+ });
92
+ }
93
+ function drawBoardCoordinates(ctx, margin, boardSize, cell, fontFamily, isSente) {
94
+ ctx.fillStyle = "#000";
95
+ ctx.font = `${cell * 0.35}px ${fontFamily}`;
96
+ ctx.textAlign = "center";
97
+ ctx.textBaseline = "middle";
98
+ Array.from({ length: 9 }).forEach((_, i) => {
99
+ const x = margin + i * cell + cell / 2;
100
+ const y = margin / 2;
101
+ const label = isSente ? import_json_kifu_format.JKFPlayer.numToZen(9 - i) : import_json_kifu_format.JKFPlayer.numToZen(i + 1);
102
+ ctx.fillText(label, x, y);
103
+ });
104
+ Array.from({ length: 9 }).forEach((_, i) => {
105
+ const x = margin + boardSize + margin / 2;
106
+ const y = margin + i * cell + cell / 2;
107
+ const label = isSente ? import_json_kifu_format.JKFPlayer.numToKan(i + 1) : import_json_kifu_format.JKFPlayer.numToKan(9 - i);
108
+ ctx.fillText(label, x, y);
109
+ });
110
+ }
111
+ function drawHighlightedCell(ctx, margin, cell, isSente, currentMove) {
112
+ if (!currentMove) return;
113
+ if (currentMove.to) {
114
+ const toRow = currentMove.to.x - 1;
115
+ const toCol = currentMove.to.y - 1;
116
+ const toX = isSente ? 8 - toRow : toRow;
117
+ const toY = isSente ? toCol : 8 - toCol;
118
+ ctx.fillStyle = "rgba(255,0,0,0.1)";
119
+ ctx.fillRect(margin + toX * cell, margin + toY * cell, cell, cell);
120
+ }
121
+ if (currentMove.from) {
122
+ const fromRow = currentMove.from.x - 1;
123
+ const fromCol = currentMove.from.y - 1;
124
+ const fromX = isSente ? 8 - fromRow : fromRow;
125
+ const fromY = isSente ? fromCol : 8 - fromCol;
126
+ ctx.fillStyle = "rgba(255,0,0,0.1)";
127
+ ctx.fillRect(margin + fromX * cell, margin + fromY * cell, cell, cell);
128
+ }
129
+ }
130
+ // Annotate the CommonJS export names for ESM import in node:
131
+ 0 && (module.exports = {
132
+ drawBoardBackground,
133
+ drawBoardCoordinates,
134
+ drawBoardGrid,
135
+ drawBoardPieces,
136
+ drawHighlightedCell
137
+ });
@@ -1,8 +1,29 @@
1
1
  import React, { MouseEventHandler, PropsWithChildren } from 'react';
2
2
 
3
+ /**
4
+ * Props for the Button component
5
+ * @property onClick - Click event handler
6
+ * @property type - HTML button type attribute
7
+ * @property children - Button content/label
8
+ */
3
9
  type ButtonProps = {
4
10
  onClick?: MouseEventHandler<HTMLButtonElement>;
11
+ type?: 'button' | 'submit' | 'reset';
5
12
  } & PropsWithChildren;
6
- declare function Button({ children, onClick }: ButtonProps): React.JSX.Element;
13
+ /**
14
+ * A styled button component for the shogi player interface
15
+ *
16
+ * @component
17
+ * @param props - Component props
18
+ * @returns A button element with consistent styling
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * <Button onClick={handleClick} type="button">
23
+ * Click me
24
+ * </Button>
25
+ * ```
26
+ */
27
+ declare function Button({ children, onClick, type }: ButtonProps): React.JSX.Element;
7
28
 
8
29
  export { type ButtonProps, Button as default };
@@ -32,10 +32,11 @@ __export(button_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(button_exports);
34
34
  var import_react = __toESM(require("react"));
35
- function Button({ children, onClick }) {
35
+ function Button({ children, onClick, type = "button" }) {
36
36
  return /* @__PURE__ */ import_react.default.createElement(
37
37
  "button",
38
38
  {
39
+ type,
39
40
  className: "border-2 text-xs text-black p-2 border-black rounded-lg hover:bg-amber-100 cursor-pointer",
40
41
  onClick
41
42
  },
@@ -0,0 +1,29 @@
1
+ import { CanvasDimensions, BoardLayout, HandsLayout } from './types.js';
2
+ import 'shogi.js';
3
+
4
+ /**
5
+ * Calculate canvas dimensions based on device pixel ratio
6
+ * Adjusts canvas resolution for crisp rendering on HiDPI displays
7
+ *
8
+ * @param size - Base size in CSS pixels
9
+ * @returns Canvas dimensions with DPR applied for high-quality rendering
10
+ */
11
+ declare function getCanvasDimensions(size: number): CanvasDimensions;
12
+ /**
13
+ * Calculate board layout dimensions
14
+ * Computes margins and cell size based on canvas size
15
+ *
16
+ * @param size - Base size in CSS pixels
17
+ * @returns Layout object containing margin, total board size, and individual cell size
18
+ */
19
+ declare function getBoardLayout(size: number): BoardLayout;
20
+ /**
21
+ * Calculate hands (captured pieces) layout dimensions
22
+ * Computes layout for the area displaying captured pieces
23
+ *
24
+ * @param size - Base size in CSS pixels
25
+ * @returns Layout object with margins, height, and cell size for the hands area
26
+ */
27
+ declare function getHandsLayout(size: number): HandsLayout;
28
+
29
+ export { getBoardLayout, getCanvasDimensions, getHandsLayout };
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,22 +15,34 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var shogi_player_exports = {};
30
- __export(shogi_player_exports, {
31
- ShogiPlayer: () => import_shogi_player.default
19
+ var canvas_utils_exports = {};
20
+ __export(canvas_utils_exports, {
21
+ getBoardLayout: () => getBoardLayout,
22
+ getCanvasDimensions: () => getCanvasDimensions,
23
+ getHandsLayout: () => getHandsLayout
32
24
  });
33
- module.exports = __toCommonJS(shogi_player_exports);
34
- var import_shogi_player = __toESM(require("./shogi-player"));
25
+ module.exports = __toCommonJS(canvas_utils_exports);
26
+ function getCanvasDimensions(size) {
27
+ const dpr = window.devicePixelRatio || 1;
28
+ return { width: size * dpr, height: size * dpr, dpr };
29
+ }
30
+ function getBoardLayout(size) {
31
+ const margin = size * 0.06;
32
+ const boardSize = size - margin * 2;
33
+ const cell = boardSize / 9;
34
+ return { margin, boardSize, cell };
35
+ }
36
+ function getHandsLayout(size) {
37
+ const margin = size * 0.06;
38
+ const boardSize = size - margin * 2;
39
+ const cellSize = boardSize / 9;
40
+ const handsHeight = cellSize + margin + 2;
41
+ return { margin, handsHeight, boardSize, cellSize };
42
+ }
35
43
  // Annotate the CommonJS export names for ESM import in node:
36
44
  0 && (module.exports = {
37
- ShogiPlayer
45
+ getBoardLayout,
46
+ getCanvasDimensions,
47
+ getHandsLayout
38
48
  });
@@ -0,0 +1,42 @@
1
+ import { Piece } from 'shogi.js';
2
+
3
+ /**
4
+ * Draw the background of the hands area
5
+ * Fills the canvas with a solid color
6
+ *
7
+ * @param ctx - Canvas rendering context
8
+ * @param width - Width of the canvas
9
+ * @param height - Height of the canvas
10
+ * @param color - Background color hex code
11
+ */
12
+ declare function drawHandsBackground(ctx: CanvasRenderingContext2D, width: number, height: number, color: string): void;
13
+ /**
14
+ * Draw the frame border for the hands area
15
+ * Creates a bordered rectangle around the hands display
16
+ *
17
+ * @param ctx - Canvas rendering context
18
+ * @param x - X coordinate of the frame
19
+ * @param y - Y coordinate of the frame
20
+ * @param width - Width of the frame
21
+ * @param height - Height of the frame
22
+ * @param lineColor - Color of the border lines
23
+ * @param isTop - Whether this is the top hands area (affects positioning)
24
+ */
25
+ declare function drawHandsFrame(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, lineColor: string, isTop: boolean): void;
26
+ /**
27
+ * Draw captured pieces (hands) on the canvas
28
+ * Displays pieces grouped by type with counts for multiple captures
29
+ *
30
+ * @param ctx - Canvas rendering context
31
+ * @param hands - 2D array of captured pieces
32
+ * @param margin - Margin from canvas edge
33
+ * @param boardSize - Width of the hands area
34
+ * @param cell - Size of a single cell
35
+ * @param fontFamily - Font family for piece names
36
+ * @param fontSizeRatio - Font size ratio relative to cell size
37
+ * @param isSente - Whether rendering from black player's perspective
38
+ * @param isTop - Whether this is the top hands area
39
+ */
40
+ declare function drawHandsPieces(ctx: CanvasRenderingContext2D, hands: Piece[][], margin: number, boardSize: number, cell: number, fontFamily: string, fontSizeRatio: number, isSente: boolean, isTop: boolean): void;
41
+
42
+ export { drawHandsBackground, drawHandsFrame, drawHandsPieces };
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var hands_renderer_exports = {};
20
+ __export(hands_renderer_exports, {
21
+ drawHandsBackground: () => drawHandsBackground,
22
+ drawHandsFrame: () => drawHandsFrame,
23
+ drawHandsPieces: () => drawHandsPieces
24
+ });
25
+ module.exports = __toCommonJS(hands_renderer_exports);
26
+ var import_json_kifu_format = require("json-kifu-format");
27
+ var import_shogi = require("shogi.js");
28
+ function drawHandsBackground(ctx, width, height, color) {
29
+ ctx.fillStyle = color;
30
+ ctx.fillRect(0, 0, width, height);
31
+ }
32
+ function drawHandsFrame(ctx, x, y, width, height, lineColor, isTop) {
33
+ ctx.strokeStyle = lineColor;
34
+ ctx.lineWidth = 2;
35
+ if (isTop) {
36
+ ctx.strokeRect(x, y, width, height);
37
+ } else {
38
+ ctx.strokeRect(x, 2, width, height);
39
+ }
40
+ }
41
+ function drawHandsPieces(ctx, hands, margin, boardSize, cell, fontFamily, fontSizeRatio, isSente, isTop) {
42
+ ctx.textAlign = "center";
43
+ ctx.textBaseline = "middle";
44
+ const pieces = isSente && isTop || !isSente && !isTop ? hands[import_shogi.Color.White] : hands[import_shogi.Color.Black];
45
+ if (!pieces || pieces.length === 0) return;
46
+ const grouped = pieces.reduce(
47
+ (acc, piece) => {
48
+ if (!piece) return acc;
49
+ const key = piece.kind;
50
+ if (!acc[key]) acc[key] = { count: 0, color: piece.color };
51
+ acc[key].count += 1;
52
+ return acc;
53
+ },
54
+ {}
55
+ );
56
+ const order = ["OU", "HI", "KA", "KI", "GI", "KE", "KY", "FU"];
57
+ const kinds = order.filter((kind) => grouped[kind]);
58
+ kinds.forEach((kind, index) => {
59
+ const { count, color } = grouped[kind];
60
+ const px = isTop ? margin + boardSize - (index * cell + cell / 2) : margin + index * cell + cell / 2;
61
+ const py = isTop ? margin + cell / 2 : cell / 2 + 2;
62
+ ctx.save();
63
+ ctx.translate(px, py);
64
+ if (isSente && color === import_shogi.Color.White) {
65
+ ctx.rotate(Math.PI);
66
+ } else if (!isSente && color === import_shogi.Color.Black) {
67
+ ctx.rotate(Math.PI);
68
+ }
69
+ const fontSize = cell * fontSizeRatio;
70
+ const kan = import_json_kifu_format.JKFPlayer.kindToKan(kind);
71
+ ctx.font = `${fontSize}px ${fontFamily}`;
72
+ ctx.fillText(kan, 0, 0);
73
+ if (count > 1) {
74
+ ctx.font = `${fontSize * 0.5}px ${fontFamily}`;
75
+ const countOffsetY = cell * 0.8;
76
+ ctx.fillText(String(count), 0, countOffsetY);
77
+ }
78
+ ctx.restore();
79
+ });
80
+ }
81
+ // Annotate the CommonJS export names for ESM import in node:
82
+ 0 && (module.exports = {
83
+ drawHandsBackground,
84
+ drawHandsFrame,
85
+ drawHandsPieces
86
+ });
@@ -1,11 +1,32 @@
1
- import { IMoveFormat } from 'json-kifu-format/dist/src/Formats';
2
1
  import React from 'react';
3
2
 
3
+ /**
4
+ * Props for the MovesArea component
5
+ * @property readableMoves - Array of human-readable move strings (e.g., "☗7六歩")
6
+ * @property tesuu - Current move number
7
+ * @property onTesuuChange - Callback when the user selects a different move
8
+ */
4
9
  type MovesAreaProps = {
5
- moves: IMoveFormat[];
10
+ readableMoves: string[];
6
11
  tesuu: number;
7
12
  onTesuuChange?: (tesuu: number) => void;
8
13
  };
14
+ /**
15
+ * Scrollable list of moves showing the game record with current position highlighting
16
+ *
17
+ * @component
18
+ * @param props - Component props
19
+ * @returns A scrollable moves list with keyboard navigation support
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <MovesArea
24
+ * readableMoves={['開始局面', '☗7六歩', '☖3四歩']}
25
+ * tesuu={1}
26
+ * onTesuuChange={(move) => setCurrentMove(move)}
27
+ * />
28
+ * ```
29
+ */
9
30
  declare function MovesArea(props: MovesAreaProps): React.JSX.Element;
10
31
 
11
- export { MovesArea, type MovesAreaProps };
32
+ export { type MovesAreaProps, MovesArea as default };