@cardenelabs/dragon 0.18.3 → 0.20.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/README.md +3 -0
- package/dist/index.cjs +706 -149
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -1
- package/dist/index.d.ts +59 -1
- package/dist/index.js +706 -149
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/compile.ts +104 -9
- package/src/json-parser.ts +41 -0
- package/src/keywords.ts +38 -0
- package/src/schemas/diagram.json +586 -140
- package/src/types.ts +15 -1
- package/src/v05/parser.ts +79 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardenelabs/dragon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Dragon — Mermaid 感覚で animated SVG を生成する Text DSL。 cdl engine を内部利用。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "cardene777",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"prepublishOnly": "pnpm run typecheck && pnpm run test && pnpm run build"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@cardenelabs/cdl": "^0.
|
|
60
|
+
"@cardenelabs/cdl": "^0.27.0"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
63
|
"react": "^19.0.0",
|
package/src/compile.ts
CHANGED
|
@@ -544,9 +544,81 @@ export function compileToCdl(doc: DslDocument, opts?: CompileToCdlOpts): CdlDiag
|
|
|
544
544
|
// 作り替えた名前を表示だけ戻す (#1220)。 **図への追加を全て終えた後**に戻す = 途中で戻すと、
|
|
545
545
|
// 後続の処理が名前で引く時に作り替え前と後が混ざる
|
|
546
546
|
restoreActorNames(merged, 分けた.元の名前, 作り替えた対象);
|
|
547
|
+
// 配色と行の縞は **図への追加を全て終えた後**に当てる (#1553)。 図種ごとの組み立ては
|
|
548
|
+
// 20 か所以上あり、そのどれに足しても残りが取り残される
|
|
549
|
+
配色と縞を当てる(merged, doc);
|
|
550
|
+
静止した図の焦点を外す(merged, doc);
|
|
547
551
|
return merged;
|
|
548
552
|
}
|
|
549
553
|
|
|
554
|
+
/**
|
|
555
|
+
* 段を書かない図では、どの箱も「いま」 にしない (#1557)。
|
|
556
|
+
*
|
|
557
|
+
* ## 何が起きていたか
|
|
558
|
+
*
|
|
559
|
+
* `animation:` を書かない図でも段は 1 つ作られる。 作るのは 2 経路あり、cdl の組み立て器
|
|
560
|
+
* (`er()` / `flow()` / `topology()` 等) が図種ごとに 1 段を作る経路と、どちらも作らない図種に
|
|
561
|
+
* dragon が 1 段を足す経路 (`injectStaticPhase`)。 どちらも **全ての箱と矢印を段に載せる**。
|
|
562
|
+
*
|
|
563
|
+
* 描画側は段に載った箱を「いま」 として描く (枠を主役色にして太くする)。 その結果、静止した図は
|
|
564
|
+
* 全ての箱が「いま」 になり、止まっている箱の枠が 1 度も出ない (実測 = ER 図 3 箱 / 流れ図 2 箱)。
|
|
565
|
+
*
|
|
566
|
+
* 全部を強調するのと何も強調しないのは、どちらも「区別が無い」 状態。 後者の方が落ち着いて読める。
|
|
567
|
+
*
|
|
568
|
+
* ## 矢印は段に載せたまま置く
|
|
569
|
+
*
|
|
570
|
+
* 描画側の既定 (`edgeReveal: "phase"`) は「段が名指しする矢印は、その段が来るまで描かない」。
|
|
571
|
+
* 矢印まで外すと、静止した図から線が 1 本も出なくなる。
|
|
572
|
+
*
|
|
573
|
+
* ## 判定は書いた内容で決める
|
|
574
|
+
*
|
|
575
|
+
* 「段に全ての箱が載っている図」 を目印にしない = 書き手が 1 段だけ書いて全部を焦点にした図と
|
|
576
|
+
* 見分けが付かない。 見るのは `animation:` を書いたかどうかで、これは書き手が段のために書く値。
|
|
577
|
+
*/
|
|
578
|
+
function 静止した図の焦点を外す(diagram: CdlDiagram, doc: DslDocument): void {
|
|
579
|
+
if ((doc.animate?.phases.length ?? 0) > 0) return;
|
|
580
|
+
const 箱 = new Set(diagram.nodes.map((n) => n.id));
|
|
581
|
+
for (const phase of diagram.phases) {
|
|
582
|
+
phase.activate = phase.activate.filter((id) => !箱.has(id));
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
const 既定の配色を持つ図種: ReadonlySet<DslDocument["type"]> = new Set(["er", "class"]);
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* 図の配色と、表の箱の行の縞を当てる (#1553)。
|
|
590
|
+
*
|
|
591
|
+
* ## 配色
|
|
592
|
+
*
|
|
593
|
+
* cdl は色を持たない。 名前だけを `data-cdl-palette` として markup に出し、消費側
|
|
594
|
+
* (`cdl-theme.css`) が名前を見て 7 つの口 (台 / 行の面 / 縞 / 枠 / 字 / 型名 / 線) に色を当てる。
|
|
595
|
+
*
|
|
596
|
+
* ER 図とクラス図は書かなくても `kinari` (生成りに茶) になる。
|
|
597
|
+
* どちらも箱の作りが同じ (行頭の印 + 左に名前 + 右に型) で、名前と型が離れて並ぶため、
|
|
598
|
+
* 行を横に追う目印 (行の縞) が要る。
|
|
599
|
+
* 縞の色は配色からしか来ないので、既定が無いと縞が箱の面と同じ色に落ちて 1 本も出ない。
|
|
600
|
+
* 書き手が `palette:` を書いた時はそちらが勝つ。
|
|
601
|
+
*
|
|
602
|
+
* クラス図の意匠は `docs/design/class/note.md` が持つ。
|
|
603
|
+
*
|
|
604
|
+
* ## 行の縞
|
|
605
|
+
*
|
|
606
|
+
* cdl の `er()` 組み立て器は縞を既定で敷くが、**動きを持つ ER 図はその経路を通らない**
|
|
607
|
+
* (`compileGenericWithAnimate` が箱を直に組む)。 同じ図が動きの有無で縞を持ったり持たなかったり
|
|
608
|
+
* しないよう、出口で揃える。
|
|
609
|
+
*
|
|
610
|
+
* 縞を描くのは表の箱 (`storage`) だけ。 他の種別の箱に書いても描画側が読まないので、
|
|
611
|
+
* ここで対象を絞って「書いたのに出ない」 欄を残さない。
|
|
612
|
+
*/
|
|
613
|
+
function 配色と縞を当てる(diagram: CdlDiagram, doc: DslDocument): void {
|
|
614
|
+
const 配色 = doc.palette ?? (既定の配色を持つ図種.has(doc.type) ? "kinari" : undefined);
|
|
615
|
+
if (配色 !== undefined) diagram.palette = 配色;
|
|
616
|
+
if (doc.type !== "er") return;
|
|
617
|
+
for (const node of diagram.nodes) {
|
|
618
|
+
if (node.kind === "storage") node.rowStripe = true;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
550
622
|
/**
|
|
551
623
|
* readout の配色配列から外部参照を落とす (#1374)。
|
|
552
624
|
*
|
|
@@ -599,11 +671,15 @@ function materializeStates(diagram: CdlDiagram, doc: DslDocument): void {
|
|
|
599
671
|
* 描画側は段が 1 件以上あることを要求する。 一方で段を作るかどうかは種類ごとにばらけており、
|
|
600
672
|
* `animation:` を書かない図は 12 種のうち 6 種だけが描かれ、 残り 6 種は弾かれていた。
|
|
601
673
|
*
|
|
602
|
-
* ##
|
|
674
|
+
* ## 空の段にはしない
|
|
603
675
|
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
676
|
+
* 描画側の既定 (`edgeReveal: "phase"`) は「段が名指しする矢印は、その段が来るまで描かない」。
|
|
677
|
+
* 空の段を入れると、静止した図から線が 1 本も出ない。
|
|
678
|
+
*
|
|
679
|
+
* **箱は段に載せた後で外す** (#1557)。 ここで載せるのは矢印を描かせるためで、箱まで
|
|
680
|
+
* 「いま」 のままにすると静止した図の全ての箱が主役色の枠になる。 外すのは出口の
|
|
681
|
+
* `静止した図の焦点を外す` が 1 か所で行う = 段を作る経路は cdl の組み立て器にもあり、
|
|
682
|
+
* ここだけ直しても図種によって残る。
|
|
607
683
|
*
|
|
608
684
|
* ## 既に段がある図には触らない
|
|
609
685
|
*
|
|
@@ -3436,6 +3512,10 @@ function 矢印へ書き写す(target: CdlEdge, s: DslStep, doc: DslDocument): v
|
|
|
3436
3512
|
if (s.tailHead !== undefined) target.tailHead = s.tailHead;
|
|
3437
3513
|
if (s.headFill !== undefined) target.headFill = s.headFill;
|
|
3438
3514
|
if (s.tailHeadFill !== undefined) target.tailHeadFill = s.tailHeadFill;
|
|
3515
|
+
// 辺の役目と名前の下地 (cdl#618)。 主となる道を朱で引き、丸い下地を外せる。
|
|
3516
|
+
// 書かない辺には値を入れない = 既存の図が変わらない
|
|
3517
|
+
if (s.role !== undefined) target.role = s.role;
|
|
3518
|
+
if (s.labelPlate !== undefined) target.labelPlate = s.labelPlate;
|
|
3439
3519
|
if (s.labelOffsetX !== undefined) target.labelOffsetX = s.labelOffsetX;
|
|
3440
3520
|
if (s.labelOffsetY !== undefined) target.labelOffsetY = s.labelOffsetY;
|
|
3441
3521
|
if (s.overlay !== undefined) target.overlay = s.overlay;
|
|
@@ -5443,9 +5523,13 @@ function 行を組み立て器が持つ(type: DslDocument["type"]): boolean {
|
|
|
5443
5523
|
/**
|
|
5444
5524
|
* 行と印を組む (#1466)。 群の分け方は図の種類が決める。
|
|
5445
5525
|
*
|
|
5446
|
-
* ER は
|
|
5447
|
-
* 記法に空の行を書かせないのは、`rows` が空の要素を捨てるため = 書いても消える。
|
|
5526
|
+
* ER は **鍵の群を上にまとめる** (組み立て器 `er()` と同じ形)。
|
|
5448
5527
|
* 状態遷移は群を分けないので、書いた並びのまま。
|
|
5528
|
+
*
|
|
5529
|
+
* **空の行では開けない** (cdl `#606`)。 群の区切りは行頭の印が持っている = ER は鍵の名前に
|
|
5530
|
+
* 下線が付く。 空の行はその 2 つ目の手掛かりで、代わりに行の間隔を不揃いにしていた
|
|
5531
|
+
* (鍵と値を持つ箱だけ境目が広がる)。 組み立て器が cdl 0.23.0 で空の行をやめたので、
|
|
5532
|
+
* こちらも同時にやめる = 片方だけ残ると記法と図の照合が落ちる。
|
|
5449
5533
|
*/
|
|
5450
5534
|
function 行と印を組む(
|
|
5451
5535
|
type: DslDocument["type"],
|
|
@@ -5460,10 +5544,10 @@ function 行と印を組む(
|
|
|
5460
5544
|
const 鍵: number[] = [];
|
|
5461
5545
|
const 値: number[] = [];
|
|
5462
5546
|
rows.forEach((_, i) => ((印[i]?.underline === true ? 鍵 : 値).push(i)));
|
|
5463
|
-
const 並び =
|
|
5547
|
+
const 並び = [...鍵, ...値];
|
|
5464
5548
|
return {
|
|
5465
|
-
rows: 並び.map((i) =>
|
|
5466
|
-
rowMarks: 並び.map((i) =>
|
|
5549
|
+
rows: 並び.map((i) => rows[i] ?? ""),
|
|
5550
|
+
rowMarks: 並び.map((i) => 印[i] ?? null),
|
|
5467
5551
|
};
|
|
5468
5552
|
}
|
|
5469
5553
|
|
|
@@ -6607,6 +6691,17 @@ const 縦列を選べる図種: ReadonlySet<PresetType> = new Set<PresetType>([
|
|
|
6607
6691
|
"swimlane",
|
|
6608
6692
|
"class",
|
|
6609
6693
|
"state",
|
|
6694
|
+
/*
|
|
6695
|
+
* ER 図 (#1571)。
|
|
6696
|
+
*
|
|
6697
|
+
* `er` の組み立て器は実体 1 つにつき帯を 1 本作り、必ず段 0 に置く = 表が横 1 列にしか
|
|
6698
|
+
* 並ばない。 関係を 4 本持つ実体があると、どう並べ替えても 2 本は隣を飛び越す
|
|
6699
|
+
* (意匠帳 `docs/design/er/note.md` § 記法の制約 が 4 通りを実測しており、1 列は縦横比 7.0 /
|
|
6700
|
+
* 最長の線 4068、格子は 3.5 / 836)。
|
|
6701
|
+
*
|
|
6702
|
+
* **全ての箱が縦列を書いた時だけ** 効くので、書かない図はいままでどおり組み立て器が並べる。
|
|
6703
|
+
*/
|
|
6704
|
+
"er",
|
|
6610
6705
|
]);
|
|
6611
6706
|
|
|
6612
6707
|
/**
|
package/src/json-parser.ts
CHANGED
|
@@ -36,6 +36,10 @@ import {
|
|
|
36
36
|
EVENT_KINDS,
|
|
37
37
|
type 図形の定義,
|
|
38
38
|
} from "./v05/parser";
|
|
39
|
+
// 図の配色 (#1553)。 記法の読み手と同じ解決を通す = 別名 (`生成り` / `青磁`) の受け方が
|
|
40
|
+
// 記法と JSON でずれない
|
|
41
|
+
import { resolvePalette } from "./keywords";
|
|
42
|
+
import type { DslPalette } from "./keywords";
|
|
39
43
|
import type { CompileToCdlOpts } from "./compile";
|
|
40
44
|
import type {
|
|
41
45
|
CdlDiagram,
|
|
@@ -189,6 +193,16 @@ export interface DragonJson {
|
|
|
189
193
|
reveal?: EdgeReveal;
|
|
190
194
|
/** 図の並ぶ向き (#1494)。 記法の最上位 `direction:` と同じ。 JSON は英語の語で書く */
|
|
191
195
|
direction?: "vertical" | "horizontal";
|
|
196
|
+
/**
|
|
197
|
+
* 図の配色 (#1553)。 記法の最上位 `palette:` と同じ。
|
|
198
|
+
*
|
|
199
|
+
* 名前だけを図に載せる = cdl は色を持たず、値は `cdl-theme.css` が決める。
|
|
200
|
+
* ER 図とクラス図は書かなくても `kinari` (生成りに茶) になる。 どちらも箱の作りが同じ
|
|
201
|
+
* (行頭の印 + 左に名前 + 右に型) で、名前と型が離れて並ぶため、行を横に追う目印
|
|
202
|
+
* (行の縞) が要る。 縞の色は配色からしか来ないので、既定が無いと縞が箱の面と同じ色に
|
|
203
|
+
* 落ちて 1 本も出ない。 書き手が `palette:` を書いた時はそちらが勝つ。
|
|
204
|
+
*/
|
|
205
|
+
palette?: DslPalette;
|
|
192
206
|
}
|
|
193
207
|
|
|
194
208
|
export interface JsonActor {
|
|
@@ -347,6 +361,14 @@ export interface JsonStep {
|
|
|
347
361
|
tailHead?: EdgeHead;
|
|
348
362
|
headFill?: EdgeHeadFill;
|
|
349
363
|
tailHeadFill?: EdgeHeadFill;
|
|
364
|
+
/**
|
|
365
|
+
* 辺の役目 (cdl#618)。 記法の `{ role: main }` と同じ。
|
|
366
|
+
*
|
|
367
|
+
* `main` を書いた辺だけ「いま」 の色で引く。 主となる 1 本 (または 1 続き) にだけ書く。
|
|
368
|
+
*/
|
|
369
|
+
role?: "main";
|
|
370
|
+
/** 名前の下地を敷くか (cdl#618)。 記法の `{ labelPlate: false }` と同じ。 既定は敷く */
|
|
371
|
+
labelPlate?: boolean;
|
|
350
372
|
/** クラス図の関係の語 (#1466)。 書くと端の形 / 塗り / 線種がまとめて決まる */
|
|
351
373
|
relation?: ClassRelationType;
|
|
352
374
|
/** 順序図の言づての種類 (#1466)。 `call` / `return` / `fire` */
|
|
@@ -491,6 +513,8 @@ export const ACCEPTED_KEYS = {
|
|
|
491
513
|
"reveal",
|
|
492
514
|
// 図の並ぶ向き (#1494)
|
|
493
515
|
"direction",
|
|
516
|
+
// 図の配色 (#1553)
|
|
517
|
+
"palette",
|
|
494
518
|
],
|
|
495
519
|
actor: [
|
|
496
520
|
"name",
|
|
@@ -548,6 +572,9 @@ export const ACCEPTED_KEYS = {
|
|
|
548
572
|
"headFill",
|
|
549
573
|
"tailHeadFill",
|
|
550
574
|
"relation",
|
|
575
|
+
// 辺の役目と名前の下地 (cdl#618)
|
|
576
|
+
"role",
|
|
577
|
+
"labelPlate",
|
|
551
578
|
"kind",
|
|
552
579
|
"tone",
|
|
553
580
|
"style",
|
|
@@ -649,6 +676,8 @@ export const 欄の型表 = {
|
|
|
649
676
|
reveal: "非空の文字列",
|
|
650
677
|
// 図の並ぶ向き (#1494)
|
|
651
678
|
direction: "非空の文字列",
|
|
679
|
+
// 図の配色 (#1553)
|
|
680
|
+
palette: "非空の文字列",
|
|
652
681
|
},
|
|
653
682
|
actor: {
|
|
654
683
|
name: "必須の非空文字列",
|
|
@@ -704,6 +733,9 @@ export const 欄の型表 = {
|
|
|
704
733
|
headFill: "非空の文字列",
|
|
705
734
|
tailHeadFill: "非空の文字列",
|
|
706
735
|
relation: "非空の文字列",
|
|
736
|
+
// 辺の役目と名前の下地 (cdl#618)
|
|
737
|
+
role: "非空の文字列",
|
|
738
|
+
labelPlate: "真偽",
|
|
707
739
|
kind: "非空の文字列",
|
|
708
740
|
tone: "色",
|
|
709
741
|
style: "線種",
|
|
@@ -2348,6 +2380,9 @@ export function jsonToDoc(json: DragonJson): DslDocument {
|
|
|
2348
2380
|
pos: p0,
|
|
2349
2381
|
};
|
|
2350
2382
|
});
|
|
2383
|
+
// 図の配色 (#1553)。 解くのは 1 度だけにする
|
|
2384
|
+
const 配色 = json.palette === undefined ? null : resolvePalette(json.palette);
|
|
2385
|
+
|
|
2351
2386
|
const flow: DslStep[] = json.flow.map((s, i) => ({
|
|
2352
2387
|
no: i + 1,
|
|
2353
2388
|
from: s.from,
|
|
@@ -2362,6 +2397,9 @@ export function jsonToDoc(json: DragonJson): DslDocument {
|
|
|
2362
2397
|
headFill: s.headFill,
|
|
2363
2398
|
tailHeadFill: s.tailHeadFill,
|
|
2364
2399
|
relation: s.relation,
|
|
2400
|
+
// 辺の役目と名前の下地 (cdl#618)
|
|
2401
|
+
role: s.role,
|
|
2402
|
+
labelPlate: s.labelPlate,
|
|
2365
2403
|
msgKind: s.kind,
|
|
2366
2404
|
// 箱と同じ読み替えを通す (#1304)。 通さないと `tone: "成功"` が色名として解決されないまま
|
|
2367
2405
|
// 図に届き、同じ値が箱では色になり矢印では色にならない
|
|
@@ -2502,6 +2540,9 @@ export function jsonToDoc(json: DragonJson): DslDocument {
|
|
|
2502
2540
|
reveal: json.reveal,
|
|
2503
2541
|
// 図の並ぶ向き (#1494)。 JSON は英語で書くので、記法と同じ語に直してから渡す
|
|
2504
2542
|
...(json.direction !== undefined ? { direction: json.direction === "horizontal" ? ("横" as const) : ("縦" as const) } : {}),
|
|
2543
|
+
// 図の配色 (#1553)。 記法と同じ解決を通す = 別名 (`生成り` / `青磁`) の受け方がずれない。
|
|
2544
|
+
// 読めない語は渡さない = 上流の型検査が語を絞っているので、ここに来るのは書き間違いだけ
|
|
2545
|
+
...(配色 !== null ? { palette: 配色 } : {}),
|
|
2505
2546
|
pos: p0,
|
|
2506
2547
|
};
|
|
2507
2548
|
}
|
package/src/keywords.ts
CHANGED
|
@@ -45,6 +45,44 @@ export function resolveDirection(s: string): DslDirection | null {
|
|
|
45
45
|
return Object.hasOwn(DIRECTION_ALIAS, k) ? DIRECTION_ALIAS[k]! : null;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* 図の配色 (`palette:`、 #1553)。
|
|
50
|
+
*
|
|
51
|
+
* cdl は色を持たない (形だけを描く)。 名前を `data-cdl-palette` として markup に出すので、
|
|
52
|
+
* dragon の `cdl-theme.css` がその名前を見て 7 つの口 (台 / 行の面 / 縞 / 枠 / 字 / 型名 / 線)
|
|
53
|
+
* に色を当てる。
|
|
54
|
+
*
|
|
55
|
+
* **名前を自由文字列にしない**。 書き間違えると既定の色みのまま出るので、書き手には
|
|
56
|
+
* 「効かない」 としか見えない。 語を絞れば読めない語をその場で知らせられる。
|
|
57
|
+
*/
|
|
58
|
+
export const PALETTES = ["kinari", "celadon"] as const;
|
|
59
|
+
export type DslPalette = (typeof PALETTES)[number];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 配色の別名。 向きと同じく日本語と英語の両方で書ける。
|
|
63
|
+
*
|
|
64
|
+
* `kinari` = 生成りに茶、 `celadon` = 青磁に墨。
|
|
65
|
+
*
|
|
66
|
+
* ER 図とクラス図は書かなくても `kinari` (生成りに茶) になる。 どちらも箱の作りが同じ
|
|
67
|
+
* (行頭の印 + 左に名前 + 右に型) で、名前と型が離れて並ぶため、行を横に追う目印
|
|
68
|
+
* (行の縞) が要る。 縞の色は配色からしか来ないので、既定が無いと縞が箱の面と同じ色に
|
|
69
|
+
* 落ちて 1 本も出ない。 書き手が `palette:` を書いた時はそちらが勝つ。
|
|
70
|
+
*/
|
|
71
|
+
export const PALETTE_ALIAS: Record<string, DslPalette> = {
|
|
72
|
+
kinari: "kinari",
|
|
73
|
+
celadon: "celadon",
|
|
74
|
+
生成り: "kinari",
|
|
75
|
+
生成りに茶: "kinari",
|
|
76
|
+
青磁: "celadon",
|
|
77
|
+
青磁に墨: "celadon",
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/** 書いた配色を正規の語に直す。 読めない語は `null`。 */
|
|
81
|
+
export function resolvePalette(s: string): DslPalette | null {
|
|
82
|
+
const k = s.trim().toLowerCase();
|
|
83
|
+
return Object.hasOwn(PALETTE_ALIAS, k) ? PALETTE_ALIAS[k]! : null;
|
|
84
|
+
}
|
|
85
|
+
|
|
48
86
|
/** NodeKind 別名 (日本語 → English) */
|
|
49
87
|
export const NODE_KIND_ALIAS: Record<string, NodeKind> = {
|
|
50
88
|
// 日本語
|