@johnmorrisdotca/kumimoji 1.2.2 → 1.3.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 +21 -1
- package/README.md +80 -39
- package/dist/check.d.ts +26 -1
- package/dist/check.js +26 -1
- package/dist/computer.types.d.ts +24 -2
- package/dist/computerPlay.d.ts +45 -2
- package/dist/computerPlay.js +45 -2
- package/dist/computerTurn.d.ts +42 -3
- package/dist/computerTurn.js +42 -3
- package/dist/daily.d.ts +22 -2
- package/dist/daily.js +22 -2
- package/dist/element-define.d.ts +1 -1
- package/dist/element-define.js +3 -13
- package/dist/element.d.ts +85 -4
- package/dist/element.js +176 -45
- package/dist/embed-day.d.ts +4 -0
- package/dist/embed-day.js +23 -0
- package/dist/export.d.ts +123 -6
- package/dist/export.js +91 -4
- package/dist/generate.d.ts +14 -0
- package/dist/generate.js +14 -0
- package/dist/grid.d.ts +181 -10
- package/dist/grid.js +122 -7
- package/dist/help.d.ts +36 -3
- package/dist/help.js +36 -3
- package/dist/judge.d.ts +14 -0
- package/dist/judge.js +14 -0
- package/dist/kana.d.ts +23 -1
- package/dist/kana.js +23 -1
- package/dist/kumimoji.types.d.ts +70 -5
- package/dist/party.d.ts +268 -14
- package/dist/party.js +268 -14
- package/dist/party.types.d.ts +50 -2
- package/dist/partyKept.d.ts +74 -4
- package/dist/partyKept.js +74 -4
- package/dist/partySeats.d.ts +92 -6
- package/dist/partySeats.js +72 -4
- package/dist/partyTurns.d.ts +171 -5
- package/dist/partyTurns.js +171 -5
- package/dist/placement.d.ts +50 -2
- package/dist/placement.js +30 -0
- package/dist/play.d.ts +247 -15
- package/dist/play.js +237 -15
- package/dist/random.d.ts +34 -3
- package/dist/random.js +23 -2
- package/dist/react.d.ts +42 -4
- package/dist/react.js +22 -5
- package/dist/showcase.d.ts +83 -7
- package/dist/showcase.js +49 -4
- package/dist/strings.d.ts +54 -5
- package/dist/strings.js +34 -3
- package/dist/tableView.d.ts +151 -8
- package/dist/tableView.js +129 -6
- package/dist/tileFace.d.ts +59 -5
- package/dist/tileFace.js +48 -4
- package/dist/tileFamily.d.ts +9 -0
- package/dist/tileFamily.js +9 -0
- package/dist/tileWords.d.ts +93 -6
- package/dist/tileWords.js +83 -6
- package/dist/tileWordsModule.d.ts +11 -1
- package/dist/tileWordsModule.js +11 -1
- package/dist/tiles.constants.d.ts +99 -5
- package/dist/tiles.constants.js +99 -5
- package/dist/turn.d.ts +82 -4
- package/dist/turn.js +82 -4
- package/dist/ui/board.d.ts +60 -5
- package/dist/ui/board.js +28 -2
- package/dist/ui/mount.d.ts +41 -2
- package/dist/ui/mount.js +38 -1
- package/dist/ui/style.d.ts +6 -1
- package/dist/ui/style.js +6 -0
- package/dist/version.d.ts +9 -2
- package/dist/version.js +9 -2
- package/dist/wilds.d.ts +22 -1
- package/dist/wilds.js +22 -1
- package/package.json +64 -56
package/dist/daily.d.ts
CHANGED
|
@@ -8,7 +8,27 @@
|
|
|
8
8
|
* hand, level, length) gets the same bag, in the same order. The race against
|
|
9
9
|
* the clock is then theirs.
|
|
10
10
|
*/
|
|
11
|
-
/** The day a moment falls on, in UTC, written `YYYY-MM-DD`. Throws a `RangeError` for an invalid `Date`.
|
|
11
|
+
/** The day a moment falls on, in UTC, written `YYYY-MM-DD`. Throws a `RangeError` for an invalid `Date`.
|
|
12
|
+
*
|
|
13
|
+
* @param at - The word offset, seat index or date specified by this signature.
|
|
14
|
+
* @returns The day a moment falls on, in UTC, written `YYYY-MM-DD`. Throws a `RangeError` for an invalid `Date`.
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { kumimojiDay } from "@johnmorrisdotca/kumimoji";
|
|
18
|
+
*
|
|
19
|
+
* console.log(kumimojiDay(new Date("2026-10-12T12:00:00Z")));
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
12
22
|
export declare function kumimojiDay(at: Date): string;
|
|
13
|
-
/** Today's seed, the date as a number: 2026-10-01 is 20261001. The day is UTC, so it is one seed worldwide.
|
|
23
|
+
/** Today's seed, the date as a number: 2026-10-01 is 20261001. The day is UTC, so it is one seed worldwide.
|
|
24
|
+
*
|
|
25
|
+
* @param at - The word offset, seat index or date specified by this signature.
|
|
26
|
+
* @returns Today's seed, the date as a number: 2026-10-01 is 20261001. The day is UTC, so it is one seed worldwide.
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { kumimojiDailySeed } from "@johnmorrisdotca/kumimoji";
|
|
30
|
+
*
|
|
31
|
+
* console.log(kumimojiDailySeed(new Date("2026-10-12T12:00:00Z")));
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
14
34
|
export declare function kumimojiDailySeed(at: Date): number;
|
package/dist/daily.js
CHANGED
|
@@ -9,13 +9,33 @@
|
|
|
9
9
|
* the clock is then theirs.
|
|
10
10
|
*/
|
|
11
11
|
const pad = (value, width) => String(value).padStart(width, "0");
|
|
12
|
-
/** The day a moment falls on, in UTC, written `YYYY-MM-DD`. Throws a `RangeError` for an invalid `Date`.
|
|
12
|
+
/** The day a moment falls on, in UTC, written `YYYY-MM-DD`. Throws a `RangeError` for an invalid `Date`.
|
|
13
|
+
*
|
|
14
|
+
* @param at - The word offset, seat index or date specified by this signature.
|
|
15
|
+
* @returns The day a moment falls on, in UTC, written `YYYY-MM-DD`. Throws a `RangeError` for an invalid `Date`.
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { kumimojiDay } from "@johnmorrisdotca/kumimoji";
|
|
19
|
+
*
|
|
20
|
+
* console.log(kumimojiDay(new Date("2026-10-12T12:00:00Z")));
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
13
23
|
export function kumimojiDay(at) {
|
|
14
24
|
if (Number.isNaN(at.getTime()))
|
|
15
25
|
throw new RangeError("kumimoji: an invalid Date has no day");
|
|
16
26
|
return `${pad(at.getUTCFullYear(), 4)}-${pad(at.getUTCMonth() + 1, 2)}-${pad(at.getUTCDate(), 2)}`;
|
|
17
27
|
}
|
|
18
|
-
/** Today's seed, the date as a number: 2026-10-01 is 20261001. The day is UTC, so it is one seed worldwide.
|
|
28
|
+
/** Today's seed, the date as a number: 2026-10-01 is 20261001. The day is UTC, so it is one seed worldwide.
|
|
29
|
+
*
|
|
30
|
+
* @param at - The word offset, seat index or date specified by this signature.
|
|
31
|
+
* @returns Today's seed, the date as a number: 2026-10-01 is 20261001. The day is UTC, so it is one seed worldwide.
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { kumimojiDailySeed } from "@johnmorrisdotca/kumimoji";
|
|
35
|
+
*
|
|
36
|
+
* console.log(kumimojiDailySeed(new Date("2026-10-12T12:00:00Z")));
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
19
39
|
export function kumimojiDailySeed(at) {
|
|
20
40
|
const [year, month, day] = kumimojiDay(at).split("-").map(Number);
|
|
21
41
|
return year * 10000 + month * 100 + day;
|
package/dist/element-define.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from "./element.ts";
|
package/dist/element-define.js
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* ```html
|
|
5
|
-
* <script type="module" src="https://cdn.jsdelivr.net/npm/@johnmorrisdotca/kumimoji@1/dist/element-define.js"></script>
|
|
6
|
-
* <kumimoji-table language="english" hand="7"></kumimoji-table>
|
|
7
|
-
* ```
|
|
8
|
-
*
|
|
9
|
-
* A tag already defined is left as it is, and on a server, where there is no page, nothing happens.
|
|
10
|
-
*/
|
|
11
|
-
import { KumimojiTable } from "./element.js";
|
|
12
|
-
if (typeof customElements !== "undefined" && customElements.get("kumimoji-table") === undefined)
|
|
13
|
-
customElements.define("kumimoji-table", KumimojiTable);
|
|
1
|
+
import { defineTable } from "./element.js";
|
|
2
|
+
defineTable();
|
|
3
|
+
export * from "./element.js";
|
package/dist/element.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type KumimojiTableHandle } from "./ui/mount.ts";
|
|
1
|
+
import { type KumimojiTableHandle, type KumimojiTableOptions } from "./ui/mount.ts";
|
|
2
2
|
import type { KumimojiSaved } from "./export.ts";
|
|
3
3
|
declare const ElementBase: typeof HTMLElement;
|
|
4
4
|
/**
|
|
@@ -12,8 +12,7 @@ declare const ElementBase: typeof HTMLElement;
|
|
|
12
12
|
* <kumimoji-table language="japanese" level="easy" seed="daily"></kumimoji-table>
|
|
13
13
|
* ```
|
|
14
14
|
*
|
|
15
|
-
* Attributes
|
|
16
|
-
* deals a new game):
|
|
15
|
+
* Attributes configure the starting game; display, language and control changes preserve play:
|
|
17
16
|
* - `language`: the tiles, `english` (default) or `japanese` kana.
|
|
18
17
|
* - `hand`: the opening hand, 3, 7 (default) or 11.
|
|
19
18
|
* - `level`: how many tiles are wild, `easy` (most), `medium` (default) or `hard` (none).
|
|
@@ -25,11 +24,41 @@ declare const ElementBase: typeof HTMLElement;
|
|
|
25
24
|
* It fires `kumimoji-change` after every change to the game, with the game as it would
|
|
26
25
|
* be saved as `event.detail.saved`, and `kumimoji-finish` when the last tile is laid and every run
|
|
27
26
|
* is a word, with `event.detail` the deal, the play and the time it took. It has the methods
|
|
28
|
-
* `newGame()` and `setGame()`.
|
|
27
|
+
* `newGame()` and `setGame()`. Invalid input shows a status and a plain error event.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Native table options, checked alongside builder coverage.
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { KUMIMOJI_EMBED_OPTION_KEYS } from "@johnmorrisdotca/kumimoji/element";
|
|
34
|
+
* console.log(KUMIMOJI_EMBED_OPTION_KEYS.includes("saved"));
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare const KUMIMOJI_EMBED_OPTION_KEYS: string[];
|
|
38
|
+
/**
|
|
39
|
+
* Full native host options, including saved state, private words and callbacks.
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* import type { KumimojiElementOptions } from "@johnmorrisdotca/kumimoji/element";
|
|
43
|
+
* const options: KumimojiElementOptions = { keep: false, locale: "ja" };
|
|
44
|
+
* console.log(options.locale);
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export type KumimojiElementOptions = KumimojiTableOptions;
|
|
48
|
+
/**
|
|
49
|
+
* A reflected crossword table with the native table handle and saved-state getter.
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { KumimojiTable } from "@johnmorrisdotca/kumimoji/element";
|
|
53
|
+
* console.log(KumimojiTable.observedAttributes.includes("daily"));
|
|
54
|
+
* ```
|
|
29
55
|
*/
|
|
30
56
|
export declare class KumimojiTable extends ElementBase {
|
|
31
57
|
#private;
|
|
32
58
|
static observedAttributes: string[];
|
|
59
|
+
/** Native host options. Callback/presentation changes preserve the current game. */
|
|
60
|
+
get options(): KumimojiElementOptions;
|
|
61
|
+
set options(value: KumimojiElementOptions);
|
|
33
62
|
connectedCallback(): void;
|
|
34
63
|
disconnectedCallback(): void;
|
|
35
64
|
attributeChangedCallback(): void;
|
|
@@ -41,5 +70,57 @@ export declare class KumimojiTable extends ElementBase {
|
|
|
41
70
|
newGame(options?: Parameters<KumimojiTableHandle["newGame"]>[0]): Promise<void>;
|
|
42
71
|
/** Put a game on the table: see `KumimojiTableHandle.setGame`. */
|
|
43
72
|
setGame(saved: KumimojiSaved): Promise<void>;
|
|
73
|
+
/** The `language` attribute, reflected. */
|
|
74
|
+
get language(): string | null;
|
|
75
|
+
set language(value: string | number | boolean | null | undefined);
|
|
76
|
+
/** The `hand` attribute, reflected. */
|
|
77
|
+
get hand(): string | null;
|
|
78
|
+
set hand(value: string | number | boolean | null | undefined);
|
|
79
|
+
/** The `level` attribute, reflected. */
|
|
80
|
+
get level(): string | null;
|
|
81
|
+
set level(value: string | number | boolean | null | undefined);
|
|
82
|
+
/** The `length` attribute, reflected. */
|
|
83
|
+
get length(): string | null;
|
|
84
|
+
set length(value: string | number | boolean | null | undefined);
|
|
85
|
+
/** The `diagonals` attribute, reflected. */
|
|
86
|
+
get diagonals(): string | null;
|
|
87
|
+
set diagonals(value: string | number | boolean | null | undefined);
|
|
88
|
+
/** The `seed` attribute, reflected. */
|
|
89
|
+
get seed(): string | null;
|
|
90
|
+
set seed(value: string | number | boolean | null | undefined);
|
|
91
|
+
/** The `keep` attribute, reflected. */
|
|
92
|
+
get keep(): string | null;
|
|
93
|
+
set keep(value: string | number | boolean | null | undefined);
|
|
94
|
+
/** The `daily` attribute, reflected. */
|
|
95
|
+
get daily(): string | null;
|
|
96
|
+
set daily(value: string | number | boolean | null | undefined);
|
|
97
|
+
/** The `controls` attribute, reflected. */
|
|
98
|
+
get controls(): string | null;
|
|
99
|
+
set controls(value: string | number | boolean | null | undefined);
|
|
100
|
+
/** The `theme` attribute, reflected. */
|
|
101
|
+
get theme(): string | null;
|
|
102
|
+
set theme(value: string | number | boolean | null | undefined);
|
|
103
|
+
/** The `size` attribute, reflected. */
|
|
104
|
+
get size(): string | null;
|
|
105
|
+
set size(value: string | number | boolean | null | undefined);
|
|
106
|
+
/** The `width` attribute, reflected. */
|
|
107
|
+
get width(): string | null;
|
|
108
|
+
set width(value: string | number | boolean | null | undefined);
|
|
109
|
+
/** The `label` attribute, reflected. */
|
|
110
|
+
get label(): string | null;
|
|
111
|
+
set label(value: string | number | boolean | null | undefined);
|
|
44
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Defines the table or a subclass under a custom tag. Server-safe and idempotent.
|
|
115
|
+
* @param tagName - The tag name; kumimoji-table by default.
|
|
116
|
+
* @param registry - The page registry, or undefined on a server.
|
|
117
|
+
* @returns Nothing; existing definitions are left alone.
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* import { defineTable } from "@johnmorrisdotca/kumimoji/element";
|
|
121
|
+
* defineTable();
|
|
122
|
+
* console.log(typeof defineTable);
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export declare function defineTable(tagName?: string, registry?: CustomElementRegistry | undefined): void;
|
|
45
126
|
export {};
|
package/dist/element.js
CHANGED
|
@@ -9,14 +9,16 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
10
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
11
|
};
|
|
12
|
-
var _KumimojiTable_instances, _KumimojiTable_table, _KumimojiTable_key, _KumimojiTable_queued, _KumimojiTable_seed, _KumimojiTable_refresh;
|
|
12
|
+
var _KumimojiTable_instances, _KumimojiTable_table, _KumimojiTable_key, _KumimojiTable_queued, _KumimojiTable_seed, _KumimojiTable_options, _KumimojiTable_revision, _KumimojiTable_widthBefore, _KumimojiTable_widthOwned, _KumimojiTable_labelBefore, _KumimojiTable_write, _KumimojiTable_frame, _KumimojiTable_refresh;
|
|
13
|
+
import { embedDay } from "./embed-day.js";
|
|
14
|
+
import { KUMIMOJI_STYLE } from "./ui/style.js";
|
|
13
15
|
import { kumimojiDailySeed } from "./daily.js";
|
|
14
16
|
import { KUMIMOJI_HANDS } from "./tiles.constants.js";
|
|
15
17
|
import { mountKumimoji } from "./ui/mount.js";
|
|
16
18
|
const ElementBase = typeof HTMLElement === "undefined" ? class {
|
|
17
19
|
} : HTMLElement;
|
|
18
20
|
const oneOf = (value, allowed) => (allowed.includes(value) ? value : undefined);
|
|
19
|
-
const isOn = (value) => value
|
|
21
|
+
const isOn = (value, fallback = false) => value === null ? fallback : !["false", "off", "no", "0"].includes(value.trim().toLowerCase());
|
|
20
22
|
const HANDS = Object.values(KUMIMOJI_HANDS);
|
|
21
23
|
/**
|
|
22
24
|
* THE `<kumimoji-table>` ELEMENT: a game of Kumimoji alone in a tag, with no
|
|
@@ -29,8 +31,7 @@ const HANDS = Object.values(KUMIMOJI_HANDS);
|
|
|
29
31
|
* <kumimoji-table language="japanese" level="easy" seed="daily"></kumimoji-table>
|
|
30
32
|
* ```
|
|
31
33
|
*
|
|
32
|
-
* Attributes
|
|
33
|
-
* deals a new game):
|
|
34
|
+
* Attributes configure the starting game; display, language and control changes preserve play:
|
|
34
35
|
* - `language`: the tiles, `english` (default) or `japanese` kana.
|
|
35
36
|
* - `hand`: the opening hand, 3, 7 (default) or 11.
|
|
36
37
|
* - `level`: how many tiles are wild, `easy` (most), `medium` (default) or `hard` (none).
|
|
@@ -42,7 +43,24 @@ const HANDS = Object.values(KUMIMOJI_HANDS);
|
|
|
42
43
|
* It fires `kumimoji-change` after every change to the game, with the game as it would
|
|
43
44
|
* be saved as `event.detail.saved`, and `kumimoji-finish` when the last tile is laid and every run
|
|
44
45
|
* is a word, with `event.detail` the deal, the play and the time it took. It has the methods
|
|
45
|
-
* `newGame()` and `setGame()`.
|
|
46
|
+
* `newGame()` and `setGame()`. Invalid input shows a status and a plain error event.
|
|
47
|
+
*/
|
|
48
|
+
/**
|
|
49
|
+
* Native table options, checked alongside builder coverage.
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { KUMIMOJI_EMBED_OPTION_KEYS } from "@johnmorrisdotca/kumimoji/element";
|
|
53
|
+
* console.log(KUMIMOJI_EMBED_OPTION_KEYS.includes("saved"));
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export const KUMIMOJI_EMBED_OPTION_KEYS = Object.keys({ language: true, hand: true, level: true, gameLength: true, diagonals: true, seed: true, onFinish: true, onChange: true, locale: true, strings: true, theme: true, keep: true, controls: true, saved: true, onError: true });
|
|
57
|
+
/**
|
|
58
|
+
* A reflected crossword table with the native table handle and saved-state getter.
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import { KumimojiTable } from "@johnmorrisdotca/kumimoji/element";
|
|
62
|
+
* console.log(KumimojiTable.observedAttributes.includes("daily"));
|
|
63
|
+
* ```
|
|
46
64
|
*/
|
|
47
65
|
export class KumimojiTable extends ElementBase {
|
|
48
66
|
constructor() {
|
|
@@ -52,11 +70,22 @@ export class KumimojiTable extends ElementBase {
|
|
|
52
70
|
_KumimojiTable_key.set(this, "");
|
|
53
71
|
_KumimojiTable_queued.set(this, false);
|
|
54
72
|
_KumimojiTable_seed.set(this, null);
|
|
73
|
+
_KumimojiTable_options.set(this, {});
|
|
74
|
+
_KumimojiTable_revision.set(this, 0);
|
|
75
|
+
_KumimojiTable_widthBefore.set(this, null);
|
|
76
|
+
_KumimojiTable_widthOwned.set(this, false);
|
|
77
|
+
_KumimojiTable_labelBefore.set(this, null);
|
|
55
78
|
}
|
|
79
|
+
/** Native host options. Callback/presentation changes preserve the current game. */
|
|
80
|
+
get options() { return __classPrivateFieldGet(this, _KumimojiTable_options, "f"); }
|
|
81
|
+
set options(value) { __classPrivateFieldSet(this, _KumimojiTable_options, value ?? {}, "f"); if (this.isConnected)
|
|
82
|
+
__classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_refresh).call(this); }
|
|
56
83
|
connectedCallback() {
|
|
57
84
|
__classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_refresh).call(this);
|
|
58
85
|
}
|
|
59
86
|
disconnectedCallback() {
|
|
87
|
+
var _a;
|
|
88
|
+
__classPrivateFieldSet(this, _KumimojiTable_revision, (_a = __classPrivateFieldGet(this, _KumimojiTable_revision, "f"), ++_a), "f");
|
|
60
89
|
__classPrivateFieldGet(this, _KumimojiTable_table, "f")?.destroy();
|
|
61
90
|
__classPrivateFieldSet(this, _KumimojiTable_table, null, "f");
|
|
62
91
|
__classPrivateFieldSet(this, _KumimojiTable_key, "", "f");
|
|
@@ -67,7 +96,8 @@ export class KumimojiTable extends ElementBase {
|
|
|
67
96
|
__classPrivateFieldSet(this, _KumimojiTable_queued, true, "f");
|
|
68
97
|
queueMicrotask(() => {
|
|
69
98
|
__classPrivateFieldSet(this, _KumimojiTable_queued, false, "f");
|
|
70
|
-
|
|
99
|
+
if (this.isConnected)
|
|
100
|
+
__classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_refresh).call(this);
|
|
71
101
|
});
|
|
72
102
|
}
|
|
73
103
|
/** The mounted table's handle (`mountKumimoji`), or null while the attributes name no table the rules offer. */
|
|
@@ -86,45 +116,146 @@ export class KumimojiTable extends ElementBase {
|
|
|
86
116
|
setGame(saved) {
|
|
87
117
|
return __classPrivateFieldGet(this, _KumimojiTable_table, "f")?.setGame(saved) ?? Promise.resolve();
|
|
88
118
|
}
|
|
119
|
+
/** The `language` attribute, reflected. */
|
|
120
|
+
get language() { return this.getAttribute("language"); }
|
|
121
|
+
set language(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "language", value); }
|
|
122
|
+
/** The `hand` attribute, reflected. */
|
|
123
|
+
get hand() { return this.getAttribute("hand"); }
|
|
124
|
+
set hand(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "hand", value); }
|
|
125
|
+
/** The `level` attribute, reflected. */
|
|
126
|
+
get level() { return this.getAttribute("level"); }
|
|
127
|
+
set level(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "level", value); }
|
|
128
|
+
/** The `length` attribute, reflected. */
|
|
129
|
+
get length() { return this.getAttribute("length"); }
|
|
130
|
+
set length(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "length", value); }
|
|
131
|
+
/** The `diagonals` attribute, reflected. */
|
|
132
|
+
get diagonals() { return this.getAttribute("diagonals"); }
|
|
133
|
+
set diagonals(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "diagonals", value); }
|
|
134
|
+
/** The `seed` attribute, reflected. */
|
|
135
|
+
get seed() { return this.getAttribute("seed"); }
|
|
136
|
+
set seed(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "seed", value); }
|
|
137
|
+
/** The `keep` attribute, reflected. */
|
|
138
|
+
get keep() { return this.getAttribute("keep"); }
|
|
139
|
+
set keep(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "keep", value); }
|
|
140
|
+
/** The `daily` attribute, reflected. */
|
|
141
|
+
get daily() { return this.getAttribute("daily"); }
|
|
142
|
+
set daily(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "daily", value); }
|
|
143
|
+
/** The `controls` attribute, reflected. */
|
|
144
|
+
get controls() { return this.getAttribute("controls"); }
|
|
145
|
+
set controls(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "controls", value); }
|
|
146
|
+
/** The `theme` attribute, reflected. */
|
|
147
|
+
get theme() { return this.getAttribute("theme"); }
|
|
148
|
+
set theme(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "theme", value); }
|
|
149
|
+
/** The `size` attribute, reflected. */
|
|
150
|
+
get size() { return this.getAttribute("size"); }
|
|
151
|
+
set size(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "size", value); }
|
|
152
|
+
/** The `width` attribute, reflected. */
|
|
153
|
+
get width() { return this.getAttribute("width"); }
|
|
154
|
+
set width(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "width", value); }
|
|
155
|
+
/** The `label` attribute, reflected. */
|
|
156
|
+
get label() { return this.getAttribute("label"); }
|
|
157
|
+
set label(value) { __classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_write).call(this, "label", value); }
|
|
89
158
|
}
|
|
90
|
-
_KumimojiTable_table = new WeakMap(), _KumimojiTable_key = new WeakMap(), _KumimojiTable_queued = new WeakMap(), _KumimojiTable_seed = new WeakMap(), _KumimojiTable_instances = new WeakSet(),
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
159
|
+
_KumimojiTable_table = new WeakMap(), _KumimojiTable_key = new WeakMap(), _KumimojiTable_queued = new WeakMap(), _KumimojiTable_seed = new WeakMap(), _KumimojiTable_options = new WeakMap(), _KumimojiTable_revision = new WeakMap(), _KumimojiTable_widthBefore = new WeakMap(), _KumimojiTable_widthOwned = new WeakMap(), _KumimojiTable_labelBefore = new WeakMap(), _KumimojiTable_instances = new WeakSet(), _KumimojiTable_write = function _KumimojiTable_write(name, value) { if (value === null || value === undefined)
|
|
160
|
+
this.removeAttribute(name);
|
|
161
|
+
else
|
|
162
|
+
this.setAttribute(name, String(value)); }, _KumimojiTable_frame = function _KumimojiTable_frame() {
|
|
163
|
+
this.style.display = "block";
|
|
164
|
+
this.style.maxWidth = "100%";
|
|
165
|
+
const width = Number(this.getAttribute("width")), size = this.getAttribute("size");
|
|
166
|
+
const pixels = this.hasAttribute("width") && width > 0 && Number.isFinite(width) ? Math.min(width, 2000) : size === "small" ? 320 : size === "medium" ? 480 : size === "large" ? 640 : null;
|
|
167
|
+
if (pixels !== null) {
|
|
168
|
+
if (!__classPrivateFieldGet(this, _KumimojiTable_widthOwned, "f"))
|
|
169
|
+
__classPrivateFieldSet(this, _KumimojiTable_widthBefore, this.style.width, "f");
|
|
170
|
+
__classPrivateFieldSet(this, _KumimojiTable_widthOwned, true, "f");
|
|
171
|
+
this.style.width = `${pixels}px`;
|
|
172
|
+
}
|
|
173
|
+
else if (__classPrivateFieldGet(this, _KumimojiTable_widthOwned, "f")) {
|
|
174
|
+
this.style.width = __classPrivateFieldGet(this, _KumimojiTable_widthBefore, "f") ?? "";
|
|
175
|
+
__classPrivateFieldSet(this, _KumimojiTable_widthOwned, false, "f");
|
|
176
|
+
}
|
|
177
|
+
const theme = this.getAttribute("theme");
|
|
178
|
+
this.style.colorScheme = theme === "light" || theme === "dark" ? theme : "light dark";
|
|
179
|
+
this.setAttribute("data-kumimoji-embed", "");
|
|
180
|
+
const root = this.getRootNode(), target = typeof ShadowRoot !== "undefined" && root instanceof ShadowRoot ? root : this.ownerDocument.head;
|
|
181
|
+
if (target.querySelector("style[data-kumimoji-embed-style]") === null) {
|
|
182
|
+
const style = this.ownerDocument.createElement("style");
|
|
183
|
+
style.setAttribute("data-kumimoji-embed-style", "");
|
|
184
|
+
const light = KUMIMOJI_STYLE.match(/\.km-root \{([^}]+)\}/)?.[1] ?? "";
|
|
185
|
+
const dark = KUMIMOJI_STYLE.match(/@media \(prefers-color-scheme: dark\) \{\s*\.km-root \{([^}]+)\}/)?.[1] ?? "";
|
|
186
|
+
style.textContent = `[data-kumimoji-embed][theme="light"] .km-root{${light}}[data-kumimoji-embed][theme="dark"] .km-root{${dark}}[data-kumimoji-embed]>.km-root{background:var(--km-panel);padding:12px;border-radius:12px}[data-kumimoji-embed] .km-controls[hidden]{display:none}`;
|
|
187
|
+
target.append(style);
|
|
188
|
+
}
|
|
189
|
+
if (this.hasAttribute("label")) {
|
|
190
|
+
__classPrivateFieldSet(this, _KumimojiTable_labelBefore, __classPrivateFieldGet(this, _KumimojiTable_labelBefore, "f") ?? { role: this.getAttribute("role"), label: this.getAttribute("aria-label") }, "f");
|
|
191
|
+
this.setAttribute("role", "group");
|
|
192
|
+
this.setAttribute("aria-label", this.getAttribute("label"));
|
|
193
|
+
}
|
|
194
|
+
else if (__classPrivateFieldGet(this, _KumimojiTable_labelBefore, "f") !== null) {
|
|
195
|
+
for (const [name, value] of [["role", __classPrivateFieldGet(this, _KumimojiTable_labelBefore, "f").role], ["aria-label", __classPrivateFieldGet(this, _KumimojiTable_labelBefore, "f").label]]) {
|
|
196
|
+
if (value === null)
|
|
197
|
+
this.removeAttribute(name);
|
|
198
|
+
else
|
|
199
|
+
this.setAttribute(name, value);
|
|
200
|
+
}
|
|
201
|
+
__classPrivateFieldSet(this, _KumimojiTable_labelBefore, null, "f");
|
|
202
|
+
}
|
|
203
|
+
}, _KumimojiTable_refresh = function _KumimojiTable_refresh() {
|
|
204
|
+
var _a;
|
|
205
|
+
__classPrivateFieldGet(this, _KumimojiTable_instances, "m", _KumimojiTable_frame).call(this);
|
|
206
|
+
try {
|
|
207
|
+
const language = oneOf(this.getAttribute("language"), ["english", "japanese"]) ?? __classPrivateFieldGet(this, _KumimojiTable_options, "f").language;
|
|
208
|
+
const hand = this.hasAttribute("hand") ? Number(this.getAttribute("hand")) : __classPrivateFieldGet(this, _KumimojiTable_options, "f").hand;
|
|
209
|
+
const level = oneOf(this.getAttribute("level"), ["easy", "medium", "hard"]) ?? __classPrivateFieldGet(this, _KumimojiTable_options, "f").level;
|
|
210
|
+
const gameLength = oneOf(this.getAttribute("length"), ["short", "medium", "full"]) ?? __classPrivateFieldGet(this, _KumimojiTable_options, "f").gameLength;
|
|
211
|
+
const diagonals = isOn(this.getAttribute("diagonals"), __classPrivateFieldGet(this, _KumimojiTable_options, "f").diagonals ?? false);
|
|
212
|
+
const seedAttribute = this.getAttribute("seed"), asked = Number(seedAttribute);
|
|
213
|
+
const day = embedDay(this.hasAttribute("daily") ? this.getAttribute("daily") : seedAttribute === "daily" ? "today" : null);
|
|
214
|
+
const seed = day !== null ? kumimojiDailySeed(new Date(`${day}T00:00:00Z`)) : seedAttribute !== null && Number.isInteger(asked) && asked >= 0 && asked <= 0xffffffff ? asked : __classPrivateFieldGet(this, _KumimojiTable_options, "f").seed ?? (__classPrivateFieldSet(this, _KumimojiTable_seed, __classPrivateFieldGet(this, _KumimojiTable_seed, "f") ?? Math.floor(Math.random() * 2 ** 31), "f"));
|
|
215
|
+
const lang = this.getAttribute("lang"), locale = lang === "en" || lang === "ja" ? lang : __classPrivateFieldGet(this, _KumimojiTable_options, "f").locale ?? (this.ownerDocument.documentElement.lang.toLowerCase().startsWith("ja") ? "ja" : "en");
|
|
216
|
+
const keep = isOn(this.getAttribute("keep"), __classPrivateFieldGet(this, _KumimojiTable_options, "f").keep ?? true), controls = isOn(this.getAttribute("controls"), __classPrivateFieldGet(this, _KumimojiTable_options, "f").controls ?? true);
|
|
217
|
+
const key = JSON.stringify([language, hand, level, gameLength, diagonals, seed, day, __classPrivateFieldGet(this, _KumimojiTable_options, "f").saved]);
|
|
218
|
+
if (key === __classPrivateFieldGet(this, _KumimojiTable_key, "f") && __classPrivateFieldGet(this, _KumimojiTable_table, "f") !== null) {
|
|
219
|
+
__classPrivateFieldGet(this, _KumimojiTable_table, "f").set({ locale, strings: __classPrivateFieldGet(this, _KumimojiTable_options, "f").strings, theme: __classPrivateFieldGet(this, _KumimojiTable_options, "f").theme ?? {}, keep, controls });
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (hand !== undefined && !HANDS.includes(hand))
|
|
223
|
+
throw new RangeError("Choose a hand of 3, 7 or 11 tiles.");
|
|
224
|
+
__classPrivateFieldGet(this, _KumimojiTable_table, "f")?.destroy();
|
|
225
|
+
__classPrivateFieldSet(this, _KumimojiTable_table, null, "f");
|
|
226
|
+
__classPrivateFieldSet(this, _KumimojiTable_key, "", "f");
|
|
227
|
+
this.replaceChildren();
|
|
228
|
+
const revision = __classPrivateFieldSet(this, _KumimojiTable_revision, (_a = __classPrivateFieldGet(this, _KumimojiTable_revision, "f"), ++_a), "f");
|
|
229
|
+
const table = mountKumimoji(this, { ...__classPrivateFieldGet(this, _KumimojiTable_options, "f"), language, hand, level, gameLength, diagonals, seed, locale, keep, controls, onChange: saved => { this.dispatchEvent(new CustomEvent("kumimoji-change", { detail: JSON.parse(JSON.stringify({ saved })), bubbles: true, composed: true })); __classPrivateFieldGet(this, _KumimojiTable_options, "f").onChange?.(saved); }, onFinish: result => { this.dispatchEvent(new CustomEvent("kumimoji-finish", { detail: JSON.parse(JSON.stringify(result)), bubbles: true, composed: true })); __classPrivateFieldGet(this, _KumimojiTable_options, "f").onFinish?.(result); }, onError: error => { this.dispatchEvent(new CustomEvent("kumimoji-error", { detail: { message: error.message }, bubbles: true, composed: true })); __classPrivateFieldGet(this, _KumimojiTable_options, "f").onError?.(error); } });
|
|
230
|
+
__classPrivateFieldSet(this, _KumimojiTable_table, table, "f");
|
|
231
|
+
__classPrivateFieldSet(this, _KumimojiTable_key, key, "f");
|
|
232
|
+
void table.ready.then(() => { if (this.isConnected && revision === __classPrivateFieldGet(this, _KumimojiTable_revision, "f") && table.saved() !== null)
|
|
233
|
+
this.dispatchEvent(new CustomEvent("kumimoji-load", { bubbles: true, composed: true, detail: { seed: table.saved().deal.seed, day } })); }).catch(() => { });
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
__classPrivateFieldGet(this, _KumimojiTable_table, "f")?.destroy();
|
|
237
|
+
__classPrivateFieldSet(this, _KumimojiTable_table, null, "f");
|
|
238
|
+
__classPrivateFieldSet(this, _KumimojiTable_key, "", "f");
|
|
239
|
+
const message = error instanceof Error ? error.message : String(error), status = this.ownerDocument.createElement("p");
|
|
240
|
+
status.setAttribute("role", "status");
|
|
241
|
+
status.textContent = message;
|
|
242
|
+
this.replaceChildren(status);
|
|
243
|
+
this.dispatchEvent(new CustomEvent("kumimoji-error", { detail: { message }, bubbles: true, composed: true }));
|
|
111
244
|
}
|
|
112
|
-
__classPrivateFieldGet(this, _KumimojiTable_table, "f")?.destroy();
|
|
113
|
-
__classPrivateFieldSet(this, _KumimojiTable_table, null, "f");
|
|
114
|
-
__classPrivateFieldSet(this, _KumimojiTable_key, key, "f");
|
|
115
|
-
if (hand !== undefined && !HANDS.includes(hand))
|
|
116
|
-
return;
|
|
117
|
-
__classPrivateFieldSet(this, _KumimojiTable_table, mountKumimoji(this, {
|
|
118
|
-
language,
|
|
119
|
-
hand,
|
|
120
|
-
level,
|
|
121
|
-
gameLength,
|
|
122
|
-
diagonals,
|
|
123
|
-
seed,
|
|
124
|
-
locale,
|
|
125
|
-
keep,
|
|
126
|
-
onChange: (saved) => this.dispatchEvent(new CustomEvent("kumimoji-change", { detail: { saved }, bubbles: true })),
|
|
127
|
-
onFinish: (result) => this.dispatchEvent(new CustomEvent("kumimoji-finish", { detail: result, bubbles: true })),
|
|
128
|
-
}), "f");
|
|
129
245
|
};
|
|
130
|
-
KumimojiTable.observedAttributes = ["language", "hand", "level", "length", "diagonals", "seed", "lang", "keep"];
|
|
246
|
+
KumimojiTable.observedAttributes = ["language", "hand", "level", "length", "diagonals", "seed", "lang", "keep", "daily", "controls", "theme", "size", "width", "label"];
|
|
247
|
+
/**
|
|
248
|
+
* Defines the table or a subclass under a custom tag. Server-safe and idempotent.
|
|
249
|
+
* @param tagName - The tag name; kumimoji-table by default.
|
|
250
|
+
* @param registry - The page registry, or undefined on a server.
|
|
251
|
+
* @returns Nothing; existing definitions are left alone.
|
|
252
|
+
* @example
|
|
253
|
+
* ```ts
|
|
254
|
+
* import { defineTable } from "@johnmorrisdotca/kumimoji/element";
|
|
255
|
+
* defineTable();
|
|
256
|
+
* console.log(typeof defineTable);
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
export function defineTable(tagName = "kumimoji-table", registry = typeof customElements === "undefined" ? undefined : customElements) { if (registry !== undefined && registry.get(tagName) === undefined)
|
|
260
|
+
registry.define(tagName, tagName === "kumimoji-table" ? KumimojiTable : class extends KumimojiTable {
|
|
261
|
+
}); }
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Shared UTC day parsing for the family's daily embeds. No storage, service or rollover timer. */
|
|
2
|
+
export declare function embedDay(value: string | null | undefined, now?: Date): string | null;
|
|
3
|
+
/** The same day and namespace give the same nonzero 32-bit seed on every machine. */
|
|
4
|
+
export declare function dailySeed(day: string, namespace: string): number;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Shared UTC day parsing for the family's daily embeds. No storage, service or rollover timer. */
|
|
2
|
+
export function embedDay(value, now = new Date()) {
|
|
3
|
+
if (value === null || value === undefined || ["off", "false", "no", "0"].includes(value.trim().toLowerCase()))
|
|
4
|
+
return null;
|
|
5
|
+
const asked = value.trim().toLowerCase();
|
|
6
|
+
const day = ["", "today", "on", "true", "1"].includes(asked) ? Number.isNaN(now.getTime()) ? "" : now.toISOString().slice(0, 10) : value.trim();
|
|
7
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(day))
|
|
8
|
+
throw new RangeError("Use a real UTC date written YYYY-MM-DD.");
|
|
9
|
+
const time = Date.parse(`${day}T00:00:00Z`);
|
|
10
|
+
if (!Number.isFinite(time) || new Date(time).toISOString().slice(0, 10) !== day)
|
|
11
|
+
throw new RangeError("Use a real UTC date written YYYY-MM-DD.");
|
|
12
|
+
return day;
|
|
13
|
+
}
|
|
14
|
+
/** The same day and namespace give the same nonzero 32-bit seed on every machine. */
|
|
15
|
+
export function dailySeed(day, namespace) {
|
|
16
|
+
const parsed = embedDay(day);
|
|
17
|
+
if (parsed === null)
|
|
18
|
+
throw new RangeError("A daily seed needs a UTC date.");
|
|
19
|
+
let hash = 2166136261;
|
|
20
|
+
for (const letter of `${parsed}/${namespace}`)
|
|
21
|
+
hash = Math.imul(hash ^ letter.charCodeAt(0), 16777619) >>> 0;
|
|
22
|
+
return hash || 1;
|
|
23
|
+
}
|