@johnmorrisdotca/kumimoji 1.2.2 → 1.3.1

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 (83) hide show
  1. package/CHANGELOG.md +33 -1
  2. package/CONTRIBUTING.md +11 -2
  3. package/README.md +80 -39
  4. package/dist/check.d.ts +26 -1
  5. package/dist/check.js +30 -3
  6. package/dist/computer.types.d.ts +24 -2
  7. package/dist/computerPlay.d.ts +45 -2
  8. package/dist/computerPlay.js +56 -6
  9. package/dist/computerTurn.d.ts +42 -3
  10. package/dist/computerTurn.js +47 -5
  11. package/dist/daily.d.ts +22 -2
  12. package/dist/daily.js +23 -3
  13. package/dist/element-define.d.ts +1 -1
  14. package/dist/element-define.js +3 -13
  15. package/dist/element.d.ts +85 -4
  16. package/dist/element.js +359 -77
  17. package/dist/embed-day.d.ts +4 -0
  18. package/dist/embed-day.js +23 -0
  19. package/dist/export.d.ts +123 -6
  20. package/dist/export.js +109 -9
  21. package/dist/generate.d.ts +14 -0
  22. package/dist/generate.js +32 -5
  23. package/dist/grid.d.ts +181 -10
  24. package/dist/grid.js +148 -11
  25. package/dist/help.d.ts +36 -3
  26. package/dist/help.js +36 -3
  27. package/dist/index.d.ts +22 -22
  28. package/dist/index.js +22 -22
  29. package/dist/judge.d.ts +14 -0
  30. package/dist/judge.js +14 -0
  31. package/dist/kana.d.ts +23 -1
  32. package/dist/kana.js +62 -7
  33. package/dist/kumimoji.types.d.ts +70 -5
  34. package/dist/party.d.ts +268 -14
  35. package/dist/party.js +296 -19
  36. package/dist/party.types.d.ts +50 -2
  37. package/dist/partyKept.d.ts +74 -4
  38. package/dist/partyKept.js +127 -12
  39. package/dist/partySeats.d.ts +92 -6
  40. package/dist/partySeats.js +83 -8
  41. package/dist/partyTurns.d.ts +171 -5
  42. package/dist/partyTurns.js +187 -8
  43. package/dist/placement.d.ts +50 -2
  44. package/dist/placement.js +35 -2
  45. package/dist/play.d.ts +247 -15
  46. package/dist/play.js +251 -18
  47. package/dist/random.d.ts +34 -3
  48. package/dist/random.js +23 -2
  49. package/dist/react.d.ts +42 -4
  50. package/dist/react.js +54 -7
  51. package/dist/showcase.d.ts +83 -7
  52. package/dist/showcase.js +61 -7
  53. package/dist/strings.d.ts +54 -5
  54. package/dist/strings.js +34 -3
  55. package/dist/tableView.d.ts +151 -8
  56. package/dist/tableView.js +129 -6
  57. package/dist/tileFace.d.ts +59 -5
  58. package/dist/tileFace.js +48 -4
  59. package/dist/tileFamily.d.ts +9 -0
  60. package/dist/tileFamily.js +9 -0
  61. package/dist/tileWords.d.ts +93 -6
  62. package/dist/tileWords.js +94 -12
  63. package/dist/tileWordsModule.d.ts +12 -2
  64. package/dist/tileWordsModule.js +14 -2
  65. package/dist/tiles.constants.d.ts +99 -5
  66. package/dist/tiles.constants.js +171 -13
  67. package/dist/turn.d.ts +82 -4
  68. package/dist/turn.js +88 -5
  69. package/dist/ui/board.d.ts +60 -5
  70. package/dist/ui/board.js +44 -4
  71. package/dist/ui/draw.d.ts +62 -0
  72. package/dist/ui/draw.js +229 -0
  73. package/dist/ui/mount.d.ts +41 -2
  74. package/dist/ui/mount.js +190 -265
  75. package/dist/ui/style.d.ts +6 -1
  76. package/dist/ui/style.js +6 -0
  77. package/dist/ui.d.ts +3 -3
  78. package/dist/ui.js +2 -2
  79. package/dist/version.d.ts +9 -2
  80. package/dist/version.js +9 -2
  81. package/dist/wilds.d.ts +22 -1
  82. package/dist/wilds.js +25 -3
  83. package/package.json +68 -61
@@ -10,6 +10,12 @@ import { type Tiles } from "./grid.ts";
10
10
  * there is always room to build outward, and it zooms to fit the crossword:
11
11
  * big tiles for a first word, smaller as the grid spreads, never smaller than
12
12
  * a thumb can press (`TABLE.tileLeast`). Past that the table pans instead.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { TABLE } from "@johnmorrisdotca/kumimoji";
17
+ * console.log(TABLE);
18
+ * ```
13
19
  */
14
20
  export declare const TABLE: {
15
21
  /** Empty squares shown beyond the tiles on every side. */
@@ -40,20 +46,52 @@ export declare const TABLE: {
40
46
  /** How long a dragged tile must stay near an edge before the table pans: crossing an edge on the way in is not asking to pan. */
41
47
  readonly edgeDwellMs: 350;
42
48
  };
43
- /** The squares shown: from `top`/`left`, `rows` by `cols`. */
49
+ /** The squares shown: from `top`/`left`, `rows` by `cols`.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * import type { Area } from "@johnmorrisdotca/kumimoji";
54
+ *
55
+ * const area = {top:0,left:0,rows:1,cols:3};
56
+ * const value: Area = area;
57
+ * console.log(value);
58
+ * ```
59
+ */
44
60
  export type Area = {
45
61
  top: number;
46
62
  left: number;
47
63
  rows: number;
48
64
  cols: number;
49
65
  };
50
- /** A view: a tile's side in pixels, and where the corner of square (0, 0) is drawn. */
66
+ /** A view: a tile's side in pixels, and where the corner of square (0, 0) is drawn.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * import type { View } from "@johnmorrisdotca/kumimoji";
71
+ *
72
+ * const view = {tile:40,x:100,y:100};
73
+ * const value: View = view;
74
+ * console.log(value);
75
+ * ```
76
+ */
51
77
  export type View = {
52
78
  tile: number;
53
79
  x: number;
54
80
  y: number;
55
81
  };
56
- /** The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in. */
82
+ /** The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in.
83
+ *
84
+ * @param tiles - The map from row,column square names to internal tile codes.
85
+ * @param also - Additional square names to include in the table bounds.
86
+ * @returns The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in.
87
+ * @example
88
+ * ```ts
89
+ * import { tableArea } from "@johnmorrisdotca/kumimoji";
90
+ *
91
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
92
+ * console.log(tableArea(tiles));
93
+ * ```
94
+ */
57
95
  export declare function tableArea(tiles: Tiles, also?: readonly string[]): Area;
58
96
  /**
59
97
  * The largest a fitted tile is drawn in a table this big. `tileMost` in any
@@ -61,32 +99,137 @@ export declare function tableArea(tiles: Tiles, also?: readonly string[]): Area;
61
99
  * the Regular desk table; past that, in proportion, so a table the player asked
62
100
  * to be Large or Full (`BoardScale`) draws bigger squares rather than only more
63
101
  * of them — never past what a hand may zoom to.
102
+ *
103
+ * @param width - The available viewport width in pixels.
104
+ * @param height - The available viewport height in pixels.
105
+ * @returns The largest a fitted tile is drawn in a table this big. `tileMost` in any table up to `growsFrom` across its shorter side, which is every phone's and the Regular desk table; past that, in proportion, so a table the player asked to be Large or Full (`BoardScale`) draws bigger squares rather than only more of them — never past what a hand may zoom to.
106
+ * @example
107
+ * ```ts
108
+ * import { fittedMost } from "@johnmorrisdotca/kumimoji";
109
+ *
110
+ * console.log(fittedMost(640,480));
111
+ * ```
64
112
  */
65
113
  export declare function fittedMost(width: number, height: number): number;
66
114
  /**
67
115
  * The view that shows the whole area, centred, its tiles as big as fit between
68
116
  * the least and the most. A picture nobody presses (a finished grid, the
69
117
  * set-up preview) passes a smaller least, so a whole grid fits its box.
118
+ *
119
+ * @param area - The occupied table bounds.
120
+ * @param width - The available viewport width in pixels.
121
+ * @param height - The available viewport height in pixels.
122
+ * @param least - The minimum permitted tile size.
123
+ * @returns The view that shows the whole area, centred, its tiles as big as fit between the least and the most. A picture nobody presses (a finished grid, the set-up preview) passes a smaller least, so a whole grid fits its box.
124
+ * @example
125
+ * ```ts
126
+ * import { fitView } from "@johnmorrisdotca/kumimoji";
127
+ *
128
+ * const area = {top:0,left:0,rows:1,cols:3};
129
+ * console.log(fitView(area,640,480));
130
+ * ```
70
131
  */
71
132
  export declare function fitView(area: Area, width: number, height: number, least?: number): View;
72
- /** Whether the area, at this view's size, is bigger than the screen: then the table pans. */
133
+ /** Whether the area, at this view's size, is bigger than the screen: then the table pans.
134
+ *
135
+ * @param area - The occupied table bounds.
136
+ * @param view - The current tile size and pixel translation.
137
+ * @param width - The available viewport width in pixels.
138
+ * @param height - The available viewport height in pixels.
139
+ * @returns Whether the area, at this view's size, is bigger than the screen: then the table pans.
140
+ * @example
141
+ * ```ts
142
+ * import { overflows } from "@johnmorrisdotca/kumimoji";
143
+ *
144
+ * const area = {top:0,left:0,rows:1,cols:3};
145
+ * const view = {tile:40,x:100,y:100};
146
+ * console.log(overflows(area,view,640,480));
147
+ * ```
148
+ */
73
149
  export declare function overflows(area: Area, view: View, width: number, height: number): boolean;
74
- /** Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table. */
150
+ /** Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table.
151
+ *
152
+ * @param view - The current tile size and pixel translation.
153
+ * @param factor - The positive scale factor for zooming.
154
+ * @param px - The horizontal pointer position in pixels.
155
+ * @param py - The vertical pointer position in pixels.
156
+ * @returns Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table.
157
+ * @example
158
+ * ```ts
159
+ * import { zoomView } from "@johnmorrisdotca/kumimoji";
160
+ *
161
+ * const view = {tile:40,x:100,y:100};
162
+ * console.log(zoomView(view,1.2,320,240));
163
+ * ```
164
+ */
75
165
  export declare function zoomView(view: View, factor: number, px: number, py: number): View;
76
- /** The view moved by `dx` and `dy` screen pixels. */
166
+ /** The view moved by `dx` and `dy` screen pixels.
167
+ *
168
+ * @param view - The current tile size and pixel translation.
169
+ * @param dx - The horizontal pixel movement.
170
+ * @param dy - The vertical pixel movement.
171
+ * @returns The view moved by `dx` and `dy` screen pixels.
172
+ * @example
173
+ * ```ts
174
+ * import { panView } from "@johnmorrisdotca/kumimoji";
175
+ *
176
+ * const view = {tile:40,x:100,y:100};
177
+ * console.log(panView(view,20,10));
178
+ * ```
179
+ */
77
180
  export declare function panView(view: View, dx: number, dy: number): View;
78
181
  /**
79
182
  * Kept within reach: some of the area always on the screen, so a pan can
80
183
  * never lose the crossword. A quarter of the screen or two tiles, whichever
81
184
  * is less, stays in view on every side.
185
+ *
186
+ * @param view - The current tile size and pixel translation.
187
+ * @param area - The occupied table bounds.
188
+ * @param width - The available viewport width in pixels.
189
+ * @param height - The available viewport height in pixels.
190
+ * @returns Kept within reach: some of the area always on the screen, so a pan can never lose the crossword. A quarter of the screen or two tiles, whichever is less, stays in view on every side.
191
+ * @example
192
+ * ```ts
193
+ * import { keepInReach } from "@johnmorrisdotca/kumimoji";
194
+ *
195
+ * const area = {top:0,left:0,rows:1,cols:3};
196
+ * const view = {tile:40,x:100,y:100};
197
+ * console.log(keepInReach(view,area,640,480));
198
+ * ```
82
199
  */
83
200
  export declare function keepInReach(view: View, area: Area, width: number, height: number): View;
84
- /** The square under a point on the screen. */
201
+ /** The square under a point on the screen.
202
+ *
203
+ * @param view - The current tile size and pixel translation.
204
+ * @param px - The horizontal pointer position in pixels.
205
+ * @param py - The vertical pointer position in pixels.
206
+ * @returns The square under a point on the screen.
207
+ * @example
208
+ * ```ts
209
+ * import { squareUnder } from "@johnmorrisdotca/kumimoji";
210
+ *
211
+ * const view = {tile:40,x:100,y:100};
212
+ * console.log(squareUnder(view,100,100));
213
+ * ```
214
+ */
85
215
  export declare function squareUnder(view: View, px: number, py: number): {
86
216
  row: number;
87
217
  col: number;
88
218
  };
89
- /** Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near. */
219
+ /** Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near.
220
+ *
221
+ * @param px - The horizontal pointer position in pixels.
222
+ * @param py - The vertical pointer position in pixels.
223
+ * @param width - The available viewport width in pixels.
224
+ * @param height - The available viewport height in pixels.
225
+ * @returns Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near.
226
+ * @example
227
+ * ```ts
228
+ * import { edgePan } from "@johnmorrisdotca/kumimoji";
229
+ *
230
+ * console.log(edgePan(5,240,640,480));
231
+ * ```
232
+ */
90
233
  export declare function edgePan(px: number, py: number, width: number, height: number): {
91
234
  dx: number;
92
235
  dy: number;
package/dist/tableView.js CHANGED
@@ -10,6 +10,12 @@ import { boundsOf, placeOf } from "./grid.js";
10
10
  * there is always room to build outward, and it zooms to fit the crossword:
11
11
  * big tiles for a first word, smaller as the grid spreads, never smaller than
12
12
  * a thumb can press (`TABLE.tileLeast`). Past that the table pans instead.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { TABLE } from "@johnmorrisdotca/kumimoji";
17
+ * console.log(TABLE);
18
+ * ```
13
19
  */
14
20
  export const TABLE = {
15
21
  /** Empty squares shown beyond the tiles on every side. */
@@ -40,7 +46,19 @@ export const TABLE = {
40
46
  /** How long a dragged tile must stay near an edge before the table pans: crossing an edge on the way in is not asking to pan. */
41
47
  edgeDwellMs: 350,
42
48
  };
43
- /** The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in. */
49
+ /** The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in.
50
+ *
51
+ * @param tiles - The map from row,column square names to internal tile codes.
52
+ * @param also - Additional square names to include in the table bounds.
53
+ * @returns The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in.
54
+ * @example
55
+ * ```ts
56
+ * import { tableArea } from "@johnmorrisdotca/kumimoji";
57
+ *
58
+ * const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
59
+ * console.log(tableArea(tiles));
60
+ * ```
61
+ */
44
62
  export function tableArea(tiles, also = []) {
45
63
  const bounds = boundsOf(tiles) ?? { top: 0, left: 0, bottom: 0, right: 0 };
46
64
  let { top, left, bottom, right } = bounds;
@@ -60,6 +78,16 @@ export function tableArea(tiles, also = []) {
60
78
  * the Regular desk table; past that, in proportion, so a table the player asked
61
79
  * to be Large or Full (`BoardScale`) draws bigger squares rather than only more
62
80
  * of them — never past what a hand may zoom to.
81
+ *
82
+ * @param width - The available viewport width in pixels.
83
+ * @param height - The available viewport height in pixels.
84
+ * @returns The largest a fitted tile is drawn in a table this big. `tileMost` in any table up to `growsFrom` across its shorter side, which is every phone's and the Regular desk table; past that, in proportion, so a table the player asked to be Large or Full (`BoardScale`) draws bigger squares rather than only more of them — never past what a hand may zoom to.
85
+ * @example
86
+ * ```ts
87
+ * import { fittedMost } from "@johnmorrisdotca/kumimoji";
88
+ *
89
+ * console.log(fittedMost(640,480));
90
+ * ```
63
91
  */
64
92
  export function fittedMost(width, height) {
65
93
  const side = Math.min(width, height);
@@ -71,6 +99,19 @@ export function fittedMost(width, height) {
71
99
  * The view that shows the whole area, centred, its tiles as big as fit between
72
100
  * the least and the most. A picture nobody presses (a finished grid, the
73
101
  * set-up preview) passes a smaller least, so a whole grid fits its box.
102
+ *
103
+ * @param area - The occupied table bounds.
104
+ * @param width - The available viewport width in pixels.
105
+ * @param height - The available viewport height in pixels.
106
+ * @param least - The minimum permitted tile size.
107
+ * @returns The view that shows the whole area, centred, its tiles as big as fit between the least and the most. A picture nobody presses (a finished grid, the set-up preview) passes a smaller least, so a whole grid fits its box.
108
+ * @example
109
+ * ```ts
110
+ * import { fitView } from "@johnmorrisdotca/kumimoji";
111
+ *
112
+ * const area = {top:0,left:0,rows:1,cols:3};
113
+ * console.log(fitView(area,640,480));
114
+ * ```
74
115
  */
75
116
  export function fitView(area, width, height, least = TABLE.tileLeast) {
76
117
  const fits = Math.min(width / area.cols, height / area.rows);
@@ -81,17 +122,59 @@ export function fitView(area, width, height, least = TABLE.tileLeast) {
81
122
  y: Math.round((height - area.rows * tile) / 2 - area.top * tile),
82
123
  };
83
124
  }
84
- /** Whether the area, at this view's size, is bigger than the screen: then the table pans. */
125
+ /** Whether the area, at this view's size, is bigger than the screen: then the table pans.
126
+ *
127
+ * @param area - The occupied table bounds.
128
+ * @param view - The current tile size and pixel translation.
129
+ * @param width - The available viewport width in pixels.
130
+ * @param height - The available viewport height in pixels.
131
+ * @returns Whether the area, at this view's size, is bigger than the screen: then the table pans.
132
+ * @example
133
+ * ```ts
134
+ * import { overflows } from "@johnmorrisdotca/kumimoji";
135
+ *
136
+ * const area = {top:0,left:0,rows:1,cols:3};
137
+ * const view = {tile:40,x:100,y:100};
138
+ * console.log(overflows(area,view,640,480));
139
+ * ```
140
+ */
85
141
  export function overflows(area, view, width, height) {
86
142
  return area.cols * view.tile > width + 0.5 || area.rows * view.tile > height + 0.5;
87
143
  }
88
- /** Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table. */
144
+ /** Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table.
145
+ *
146
+ * @param view - The current tile size and pixel translation.
147
+ * @param factor - The positive scale factor for zooming.
148
+ * @param px - The horizontal pointer position in pixels.
149
+ * @param py - The vertical pointer position in pixels.
150
+ * @returns Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table.
151
+ * @example
152
+ * ```ts
153
+ * import { zoomView } from "@johnmorrisdotca/kumimoji";
154
+ *
155
+ * const view = {tile:40,x:100,y:100};
156
+ * console.log(zoomView(view,1.2,320,240));
157
+ * ```
158
+ */
89
159
  export function zoomView(view, factor, px, py) {
90
160
  const tile = Math.max(TABLE.zoomLeast, Math.min(TABLE.zoomMost, view.tile * factor));
91
161
  const scale = tile / view.tile;
92
162
  return { tile, x: px - (px - view.x) * scale, y: py - (py - view.y) * scale };
93
163
  }
94
- /** The view moved by `dx` and `dy` screen pixels. */
164
+ /** The view moved by `dx` and `dy` screen pixels.
165
+ *
166
+ * @param view - The current tile size and pixel translation.
167
+ * @param dx - The horizontal pixel movement.
168
+ * @param dy - The vertical pixel movement.
169
+ * @returns The view moved by `dx` and `dy` screen pixels.
170
+ * @example
171
+ * ```ts
172
+ * import { panView } from "@johnmorrisdotca/kumimoji";
173
+ *
174
+ * const view = {tile:40,x:100,y:100};
175
+ * console.log(panView(view,20,10));
176
+ * ```
177
+ */
95
178
  export function panView(view, dx, dy) {
96
179
  return { ...view, x: view.x + dx, y: view.y + dy };
97
180
  }
@@ -99,6 +182,20 @@ export function panView(view, dx, dy) {
99
182
  * Kept within reach: some of the area always on the screen, so a pan can
100
183
  * never lose the crossword. A quarter of the screen or two tiles, whichever
101
184
  * is less, stays in view on every side.
185
+ *
186
+ * @param view - The current tile size and pixel translation.
187
+ * @param area - The occupied table bounds.
188
+ * @param width - The available viewport width in pixels.
189
+ * @param height - The available viewport height in pixels.
190
+ * @returns Kept within reach: some of the area always on the screen, so a pan can never lose the crossword. A quarter of the screen or two tiles, whichever is less, stays in view on every side.
191
+ * @example
192
+ * ```ts
193
+ * import { keepInReach } from "@johnmorrisdotca/kumimoji";
194
+ *
195
+ * const area = {top:0,left:0,rows:1,cols:3};
196
+ * const view = {tile:40,x:100,y:100};
197
+ * console.log(keepInReach(view,area,640,480));
198
+ * ```
102
199
  */
103
200
  export function keepInReach(view, area, width, height) {
104
201
  const hold = (span) => Math.min(span / 4, view.tile * 2);
@@ -117,11 +214,37 @@ export function keepInReach(view, area, width, height) {
117
214
  y -= top - (height - hold(height));
118
215
  return { ...view, x, y };
119
216
  }
120
- /** The square under a point on the screen. */
217
+ /** The square under a point on the screen.
218
+ *
219
+ * @param view - The current tile size and pixel translation.
220
+ * @param px - The horizontal pointer position in pixels.
221
+ * @param py - The vertical pointer position in pixels.
222
+ * @returns The square under a point on the screen.
223
+ * @example
224
+ * ```ts
225
+ * import { squareUnder } from "@johnmorrisdotca/kumimoji";
226
+ *
227
+ * const view = {tile:40,x:100,y:100};
228
+ * console.log(squareUnder(view,100,100));
229
+ * ```
230
+ */
121
231
  export function squareUnder(view, px, py) {
122
232
  return { row: Math.floor((py - view.y) / view.tile), col: Math.floor((px - view.x) / view.tile) };
123
233
  }
124
- /** Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near. */
234
+ /** Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near.
235
+ *
236
+ * @param px - The horizontal pointer position in pixels.
237
+ * @param py - The vertical pointer position in pixels.
238
+ * @param width - The available viewport width in pixels.
239
+ * @param height - The available viewport height in pixels.
240
+ * @returns Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near.
241
+ * @example
242
+ * ```ts
243
+ * import { edgePan } from "@johnmorrisdotca/kumimoji";
244
+ *
245
+ * console.log(edgePan(5,240,640,480));
246
+ * ```
247
+ */
125
248
  export function edgePan(px, py, width, height) {
126
249
  const step = (near) => (near < TABLE.edge ? TABLE.edgeStep * (1 - Math.max(0, near) / TABLE.edge) : 0);
127
250
  return { dx: step(px) - step(width - px), dy: step(py) - step(height - py) };
@@ -6,13 +6,47 @@
6
6
  * `KANA_TILE_START`, or above `KANA_WILD_START` for a wild given that kana.
7
7
  * So the set-up's preview and a finished game's page draw Japanese tiles
8
8
  * without fetching the dictionary, and `tileWords` reads the same codes.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { KANA_TILE_START } from "@johnmorrisdotca/kumimoji";
13
+ * console.log(KANA_TILE_START);
14
+ * ```
9
15
  */
10
16
  export declare const KANA_TILE_START = 57344;
11
- /** Where the codes of wild tiles given a kana begin: the kana's place in `BASE_KANA` above this. */
17
+ /** Where the codes of wild tiles given a kana begin: the kana's place in `BASE_KANA` above this.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { KANA_WILD_START } from "@johnmorrisdotca/kumimoji";
22
+ * console.log(KANA_WILD_START);
23
+ * ```
24
+ */
12
25
  export declare const KANA_WILD_START = 61440;
13
- /** The code of a base kana's tile, or of a wild given that kana. */
26
+ /** The code of a base kana's tile, or of a wild given that kana.
27
+ *
28
+ * @param kana - The hiragana reading to map to a base tile.
29
+ * @param wild - Whether to encode the assigned face as a wild tile.
30
+ * @returns The internal tile code, or null when the kana has no supported base tile.
31
+ * @example
32
+ * ```ts
33
+ * import { kanaTileCode } from "@johnmorrisdotca/kumimoji";
34
+ *
35
+ * console.log(kanaTileCode("は"));
36
+ * ```
37
+ */
14
38
  export declare function kanaTileCode(kana: string, wild?: boolean): string | null;
15
- /** What a tile shows: what `tileFace` answers. */
39
+ /** What a tile shows: what `tileFace` answers.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * import type { TileFaceOf } from "@johnmorrisdotca/kumimoji";
44
+ * import { tileFace } from "@johnmorrisdotca/kumimoji";
45
+ *
46
+ * const value: TileFaceOf = tileFace("A");
47
+ * console.log(value);
48
+ * ```
49
+ */
16
50
  export type TileFaceOf = {
17
51
  /** The letter or kana printed on it: 五 on a wild nobody has given one. */
18
52
  glyph: string;
@@ -23,7 +57,27 @@ export type TileFaceOf = {
23
57
  /** A wild with no letter yet. */
24
58
  blank: boolean;
25
59
  };
26
- /** What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild. */
60
+ /** What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild.
61
+ *
62
+ * @param tile - The internal tile code to describe.
63
+ * @returns What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild.
64
+ * @example
65
+ * ```ts
66
+ * import { tileFace } from "@johnmorrisdotca/kumimoji";
67
+ *
68
+ * console.log(tileFace("A"));
69
+ * ```
70
+ */
27
71
  export declare function tileFace(tile: string): TileFaceOf;
28
- /** What a screen reader says for a tile: its letter, or that it is a wild and what it stands for. */
72
+ /** What a screen reader says for a tile: its letter, or that it is a wild and what it stands for.
73
+ *
74
+ * @param tile - The internal tile code to describe.
75
+ * @returns What a screen reader says for a tile: its letter, or that it is a wild and what it stands for.
76
+ * @example
77
+ * ```ts
78
+ * import { tileDescription } from "@johnmorrisdotca/kumimoji";
79
+ *
80
+ * console.log(tileDescription("A"));
81
+ * ```
82
+ */
29
83
  export declare function tileDescription(tile: string): string;
package/dist/tileFace.js CHANGED
@@ -7,17 +7,51 @@ import { BASE_KANA, CORNER_FORMS } from "./kana.js";
7
7
  * `KANA_TILE_START`, or above `KANA_WILD_START` for a wild given that kana.
8
8
  * So the set-up's preview and a finished game's page draw Japanese tiles
9
9
  * without fetching the dictionary, and `tileWords` reads the same codes.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { KANA_TILE_START } from "@johnmorrisdotca/kumimoji";
14
+ * console.log(KANA_TILE_START);
15
+ * ```
10
16
  */
11
17
  export const KANA_TILE_START = 0xe000;
12
- /** Where the codes of wild tiles given a kana begin: the kana's place in `BASE_KANA` above this. */
18
+ /** Where the codes of wild tiles given a kana begin: the kana's place in `BASE_KANA` above this.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { KANA_WILD_START } from "@johnmorrisdotca/kumimoji";
23
+ * console.log(KANA_WILD_START);
24
+ * ```
25
+ */
13
26
  export const KANA_WILD_START = 0xf000;
14
27
  const KANA = [...BASE_KANA];
15
- /** The code of a base kana's tile, or of a wild given that kana. */
28
+ /** The code of a base kana's tile, or of a wild given that kana.
29
+ *
30
+ * @param kana - The hiragana reading to map to a base tile.
31
+ * @param wild - Whether to encode the assigned face as a wild tile.
32
+ * @returns The internal tile code, or null when the kana has no supported base tile.
33
+ * @example
34
+ * ```ts
35
+ * import { kanaTileCode } from "@johnmorrisdotca/kumimoji";
36
+ *
37
+ * console.log(kanaTileCode("は"));
38
+ * ```
39
+ */
16
40
  export function kanaTileCode(kana, wild = false) {
17
41
  const at = KANA.indexOf(kana);
18
42
  return at === -1 ? null : String.fromCodePoint((wild ? KANA_WILD_START : KANA_TILE_START) + at);
19
43
  }
20
- /** What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild. */
44
+ /** What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild.
45
+ *
46
+ * @param tile - The internal tile code to describe.
47
+ * @returns What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild.
48
+ * @example
49
+ * ```ts
50
+ * import { tileFace } from "@johnmorrisdotca/kumimoji";
51
+ *
52
+ * console.log(tileFace("A"));
53
+ * ```
54
+ */
21
55
  export function tileFace(tile) {
22
56
  if (tile === "*")
23
57
  return { glyph: "五", forms: "", wild: true, blank: true };
@@ -32,7 +66,17 @@ export function tileFace(tile) {
32
66
  return { glyph: wildKana, forms: "", wild: true, blank: false };
33
67
  return { glyph: tile, forms: "", wild: false, blank: false };
34
68
  }
35
- /** What a screen reader says for a tile: its letter, or that it is a wild and what it stands for. */
69
+ /** What a screen reader says for a tile: its letter, or that it is a wild and what it stands for.
70
+ *
71
+ * @param tile - The internal tile code to describe.
72
+ * @returns What a screen reader says for a tile: its letter, or that it is a wild and what it stands for.
73
+ * @example
74
+ * ```ts
75
+ * import { tileDescription } from "@johnmorrisdotca/kumimoji";
76
+ *
77
+ * console.log(tileDescription("A"));
78
+ * ```
79
+ */
36
80
  export function tileDescription(tile) {
37
81
  const face = tileFace(tile);
38
82
  if (face.wild)
@@ -7,5 +7,14 @@ import type { KumimojiLanguage } from "./kumimoji.types.ts";
7
7
  * several devices (docs/plans/party-online/README.md, John 2026-09-29: the
8
8
  * browser checks the words, the server only that the tiles are real).
9
9
  * `tileFamily.test.ts` holds the two to one another.
10
+ *
11
+ * @param language - The English or Japanese tile language.
12
+ * @returns A function returning the physical family of a tile, or null for an invalid code.
13
+ * @example
14
+ * ```ts
15
+ * import { familyKeyOf } from "@johnmorrisdotca/kumimoji";
16
+ *
17
+ * console.log(familyKeyOf("english")("A"));
18
+ * ```
10
19
  */
11
20
  export declare function familyKeyOf(language: KumimojiLanguage): (tile: string) => string | null;
@@ -8,6 +8,15 @@ import { KANA_TILE_START, KANA_WILD_START, tileFace } from "./tileFace.js";
8
8
  * several devices (docs/plans/party-online/README.md, John 2026-09-29: the
9
9
  * browser checks the words, the server only that the tiles are real).
10
10
  * `tileFamily.test.ts` holds the two to one another.
11
+ *
12
+ * @param language - The English or Japanese tile language.
13
+ * @returns A function returning the physical family of a tile, or null for an invalid code.
14
+ * @example
15
+ * ```ts
16
+ * import { familyKeyOf } from "@johnmorrisdotca/kumimoji";
17
+ *
18
+ * console.log(familyKeyOf("english")("A"));
19
+ * ```
11
20
  */
12
21
  export function familyKeyOf(language) {
13
22
  if (language === "english") {