@cardenelabs/cdl 0.41.1 → 0.43.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 +93 -1
- package/dist/index.cjs +30 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +30 -54
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +29 -51
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +29 -51
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/src/layout/lanes.ts +48 -11
- package/src/layout/spec.ts +8 -3
- package/src/visual-validate.ts +55 -81
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardenelabs/cdl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.43.0",
|
|
4
4
|
"description": "CDL (Chainome Diagram Language). Mermaid-like declarative DSL that compiles to animated SVG diagrams. Built for blockchain / Solidity flows, generic enough for sequence / flow / state / ER / topology diagrams.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "cardene777",
|
package/src/layout/lanes.ts
CHANGED
|
@@ -219,7 +219,20 @@ export function expandLaneGapsForEdgeLabels(
|
|
|
219
219
|
// 修正 = edge が跨ぐ全ての隣接 lane 対に対して、 その edge の labelBoxW を要求する。
|
|
220
220
|
// label が span 内のどの対に置かれても収まることを保証する (routing 前なので
|
|
221
221
|
// 実際の label x は未定、 保守的に全対へ課す)。
|
|
222
|
-
|
|
222
|
+
//
|
|
223
|
+
// **要求は 2 種類に分ける** (`#789`)。 起点にできる位置が違うため。
|
|
224
|
+
//
|
|
225
|
+
// | 辺の形 | label が入りうる場所 | 起点 |
|
|
226
|
+
// |---|---|---|
|
|
227
|
+
// | 隣り合う 2 lane を発着 | 発着の 2 lane の内側と その間 | node の縁 |
|
|
228
|
+
// | 2 対以上を跨ぐ | 途中の lane の内側にも入りうる | lane の縁 |
|
|
229
|
+
//
|
|
230
|
+
// Axis 64 (`lane-border-clearance`) は **発着以外の lane** の border を貫くことだけを見る
|
|
231
|
+
// (`allowedLanes`)。 隣り合う辺の label が入るのは発着の 2 lane に閉じるので判定の対象外に
|
|
232
|
+
// なり、 node の縁を起点にしても新しい違反にならない。 跨ぐ辺は途中の lane を貫きうるので
|
|
233
|
+
// lane の縁のまま残す。
|
|
234
|
+
const requiredBoxWAdjacent = new Array<number>(Math.max(0, sortedByX.length - 1)).fill(0);
|
|
235
|
+
const requiredBoxWSpanning = new Array<number>(Math.max(0, sortedByX.length - 1)).fill(0);
|
|
223
236
|
for (const edge of edges) {
|
|
224
237
|
const fromLane = nodeById.get(edge.from)?.lane;
|
|
225
238
|
const toLane = nodeById.get(edge.to)?.lane;
|
|
@@ -231,11 +244,27 @@ export function expandLaneGapsForEdgeLabels(
|
|
|
231
244
|
if (labelBoxW === 0) continue;
|
|
232
245
|
const lo = Math.min(fi, ti);
|
|
233
246
|
const hi = Math.max(fi, ti);
|
|
247
|
+
const 要求 = hi - lo === 1 ? requiredBoxWAdjacent : requiredBoxWSpanning;
|
|
234
248
|
for (let pair = lo; pair < hi; pair++) {
|
|
235
|
-
if (labelBoxW >
|
|
249
|
+
if (labelBoxW > 要求[pair]!) 要求[pair] = labelBoxW;
|
|
236
250
|
}
|
|
237
251
|
}
|
|
238
252
|
|
|
253
|
+
/**
|
|
254
|
+
* lane の中で最も広い node の半幅。 node を 1 つも持たない lane は 0。
|
|
255
|
+
*
|
|
256
|
+
* 最大で取るのは、 一番広い node の縁から数えないと label がその node に被るため。
|
|
257
|
+
*
|
|
258
|
+
* **0 になる lane は `requiredBoxWAdjacent` の分岐に入らない**。 隣り合う要求が立つのは
|
|
259
|
+
* 発着の node が両 lane に居る edge がある時だけで、 その時どちらの lane も node を持つ。
|
|
260
|
+
* 使う側で 0 を除ける必要はない。
|
|
261
|
+
*/
|
|
262
|
+
const 箱の半幅 = new Map<string, number>();
|
|
263
|
+
for (const n of nodes) {
|
|
264
|
+
const 今 = 箱の半幅.get(n.lane) ?? 0;
|
|
265
|
+
if (n.w / 2 > 今) 箱の半幅.set(n.lane, n.w / 2);
|
|
266
|
+
}
|
|
267
|
+
|
|
239
268
|
// 各 隣接対が必要とする pitch (lane 中心間距離) を求め、 その最大値に全対を揃える。
|
|
240
269
|
//
|
|
241
270
|
// pitch を対ごとではなく全体で揃える理由 (Issue #202)。
|
|
@@ -250,26 +279,34 @@ export function expandLaneGapsForEdgeLabels(
|
|
|
250
279
|
for (let i = 0; i < sortedByX.length - 1; i++) {
|
|
251
280
|
const lane = sortedByX[i]!;
|
|
252
281
|
const rightLane = sortedByX[i + 1]!;
|
|
253
|
-
const
|
|
282
|
+
const laneHalfSum = lane.width / 2 + rightLane.width / 2;
|
|
283
|
+
const nodeHalfSum = (箱の半幅.get(lane.id) ?? 0) + (箱の半幅.get(rightLane.id) ?? 0);
|
|
254
284
|
const currentPitch = rightLane.x + rightLane.width / 2 - (lane.x + lane.width / 2);
|
|
255
|
-
const
|
|
285
|
+
const 隣 = requiredBoxWAdjacent[i]!;
|
|
286
|
+
const 跨 = requiredBoxWSpanning[i]!;
|
|
256
287
|
// edge が跨がない対は label 収納の要求がない。 下限を課さず現状の pitch を維持する。
|
|
257
288
|
// author が意図的に lane を重ねた図 (resolveOverlaps が y 軸 shift で解消する edge case) を
|
|
258
289
|
// engine が勝手に引き離さないため。
|
|
259
|
-
if (
|
|
290
|
+
if (隣 === 0 && 跨 === 0) {
|
|
260
291
|
requiredPitchByPair.push(currentPitch);
|
|
261
292
|
continue;
|
|
262
293
|
}
|
|
263
|
-
|
|
264
|
-
|
|
294
|
+
// 上乗せ (node と label の余白 + 経路の突き出し) は どちらの起点でも同じ。
|
|
295
|
+
const 上乗せ = CLEARANCE_NODE_LABEL * 2 + EDGE_STUB_OUT * 2;
|
|
296
|
+
const 隣の要求 = 隣 === 0 ? 0 : 隣 + 上乗せ + nodeHalfSum;
|
|
297
|
+
const 跨の要求 = 跨 === 0 ? 0 : 跨 + 上乗せ + laneHalfSum;
|
|
298
|
+
requiredPitchByPair.push(Math.max(currentPitch, 隣の要求, 跨の要求));
|
|
265
299
|
}
|
|
266
300
|
// 整数に切り上げる。 pitch は label 幅から決まり、 label 幅は 1 文字あたりの送り幅
|
|
267
301
|
// (1.08 em 等) × font size で出すため小数になる。 その小数がそのまま lane の x に乗り、
|
|
268
|
-
// node 中心 → edge label の x へ順に伝わって、
|
|
269
|
-
//
|
|
302
|
+
// node 中心 → edge label の x へ順に伝わって、 図全体の座標が非整数になる。
|
|
303
|
+
//
|
|
304
|
+
// 元の根拠は「非整数座標は SVG が subpixel で描くので輪郭がにじむ」 だったが、 にじみは
|
|
305
|
+
// device pixel で起きるのに world 座標を見ていたため、 それを測っていた軸 33 は `#783` で
|
|
306
|
+
// 畳んだ。 切り上げ自体は残す = 座標が整数に揃うと図全体の値が読みやすく、 外すと 444 枚
|
|
307
|
+
// すべての lane の x が動く一方で得るものが無い。
|
|
270
308
|
//
|
|
271
|
-
//
|
|
272
|
-
// label 収納に必要な幅は必ず確保される (切り捨てると label がはみ出す)。
|
|
309
|
+
// 切り上げなので label 収納に必要な幅は必ず確保される (切り捨てると label がはみ出す)。
|
|
273
310
|
const targetPitch = Math.ceil(Math.max(...requiredPitchByPair));
|
|
274
311
|
|
|
275
312
|
// 先頭 lane の x を固定し (viewBox 原点維持)、 以降を targetPitch 間隔で再配置する。
|
package/src/layout/spec.ts
CHANGED
|
@@ -581,9 +581,14 @@ export function requiredVerticalLabelGap(pillHs: readonly number[]): number {
|
|
|
581
581
|
* `computeLabelBBoxWorld` は本 helper を呼出、 layout/edges.ts routePathL は labelX / labelY
|
|
582
582
|
* 未確定の段階で幅だけ必要なので本 helper を単独で呼ぶ。
|
|
583
583
|
*
|
|
584
|
-
* 返す値は **偶数に切り上げる**。 label 位置は `経路の端 + 余白 + 幅 / 2`
|
|
585
|
-
*
|
|
586
|
-
*
|
|
584
|
+
* 返す値は **偶数に切り上げる**。 label 位置は `経路の端 + 余白 + 幅 / 2` で決まるので、
|
|
585
|
+
* 幅を偶数にすると `幅 / 2` が整数になり、 端と余白が整数である限り位置も 0.5 刻みに乗る。
|
|
586
|
+
*
|
|
587
|
+
* 元の根拠は「半端な小数が乗ると輪郭がにじむ」 だったが、 にじみは device pixel で起きる
|
|
588
|
+
* のに世界座標を見ていたため、 それを測っていた軸 33 は `#783` で畳んだ。 丸め自体は残す =
|
|
589
|
+
* 外すと全ての label が動く一方、 動かして良くなるものが無いため。 固定するのは
|
|
590
|
+
* 「座標が 0.5 刻みに乗る」 という性質で、 画面上のにじみは主張しない
|
|
591
|
+
* (`test/label-coord-half-grid.test.ts`)。
|
|
587
592
|
*
|
|
588
593
|
* 切り下げでなく切り上げるのは、 幅を狭める向きの丸めが節や他の label との間隔を
|
|
589
594
|
* 減らすため。 広げる向きなら間隔は増える一方で、 増分は 2 world 未満に収まる
|
package/src/visual-validate.ts
CHANGED
|
@@ -316,8 +316,8 @@ export type VisualAxis =
|
|
|
316
316
|
// CAR-Z5 (PR #84) 追加 = SVG filter / marker / gradient integrity 4 領域。
|
|
317
317
|
| "color-blind-safety"
|
|
318
318
|
| "marker-gradient-def-integrity"
|
|
319
|
-
// CAR-Z6 (PR #85) 追加 =
|
|
320
|
-
|
|
319
|
+
// CAR-Z6 (PR #85) 追加 = DOM complexity / motion / touch 3 領域
|
|
320
|
+
// (subpixel は #783 で削除)。
|
|
321
321
|
| "dom-complexity-budget"
|
|
322
322
|
| "reduced-motion-compat"
|
|
323
323
|
| "touch-target-size"
|
|
@@ -471,7 +471,6 @@ function emptyCounts(): Record<VisualAxis, number> {
|
|
|
471
471
|
"print-media-compat": 0,
|
|
472
472
|
"color-blind-safety": 0,
|
|
473
473
|
"marker-gradient-def-integrity": 0,
|
|
474
|
-
"subpixel-precision": 0,
|
|
475
474
|
"dom-complexity-budget": 0,
|
|
476
475
|
"reduced-motion-compat": 0,
|
|
477
476
|
"touch-target-size": 0,
|
|
@@ -3049,27 +3048,54 @@ function runAxes(
|
|
|
3049
3048
|
}
|
|
3050
3049
|
|
|
3051
3050
|
// ───────────────────────────────────────────────────────────
|
|
3052
|
-
// Axis 23: responsive-viewport (
|
|
3051
|
+
// Axis 23: responsive-viewport (親幅に収めた時に文字が小さくなりすぎないか)
|
|
3053
3052
|
//
|
|
3054
|
-
//
|
|
3055
|
-
//
|
|
3056
|
-
// 親幅に収めた時に帯状に潰れて中身が読めなくなる。
|
|
3057
|
-
//
|
|
3058
|
-
// viewBox width の下限は見ない。 render は `w-full` + `preserveAspectRatio="xMidYMid meet"`
|
|
3059
|
-
// で親要素の幅いっぱいに伸ばすため (`render/stage.tsx`)、 画面上の文字サイズは
|
|
3053
|
+
// render は `w-full` + `preserveAspectRatio="xMidYMid meet"` で親要素の幅いっぱいに伸ばす
|
|
3054
|
+
// (`render/stage.tsx`)。 したがって画面上の文字サイズは
|
|
3060
3055
|
//
|
|
3061
3056
|
// 画面上の文字サイズ = 文字の world 寸法 × (親要素の幅 px ÷ viewBox width)
|
|
3062
3057
|
//
|
|
3063
|
-
// で決まる。 viewBox width
|
|
3064
|
-
//
|
|
3058
|
+
// で決まる。 **この式に縦横比は出てこない**。 判定は viewBox width の上限で行う。
|
|
3059
|
+
//
|
|
3060
|
+
// 以前は縦横比 6:1 を超えると warn にしていたが、 下流の見本帳 444 枚の実測で順位が
|
|
3061
|
+
// 一致しなかった。 画面上の文字が最も小さい図 (幅 3353 world、 器 1100px で 7.2px) は
|
|
3062
|
+
// 縦横比 1.4 なので 1 度も拾われず、 縦横比が最大の図 (比 8.0、 幅 1535 world) は 15.8px で
|
|
3063
|
+
// 十分読めた。 文字が小さい上位 20 枚のうち縦横比が拾ったのは 5 枚だけ (`#785`)。
|
|
3064
|
+
//
|
|
3065
|
+
// 幅の **下限** は見ない。 viewBox width が小さいほど倍率が上がって読みやすくなるので、
|
|
3066
|
+
// 「幅が小さい = 識別不能」 は成り立たない。 以前 400 world 未満を warn にしていた頃に
|
|
3065
3067
|
// 発火した 17 件は全て単体部品の図 (271-390 world) で、 幅 375px の携帯では 1.0-1.38 倍に
|
|
3066
|
-
// 拡大される最も読みやすい部類だった。
|
|
3067
|
-
// 判定ごと外している。
|
|
3068
|
+
// 拡大される最も読みやすい部類だった。
|
|
3068
3069
|
//
|
|
3069
|
-
//
|
|
3070
|
-
//
|
|
3070
|
+
// 描画不能な寸法 (0 / 負値 / 非有限) は別に拾う。 倍率は 0 幅で無限大になり、 負値で
|
|
3071
|
+
// 符号が反転して比較が素通りするため、 割る前に弾く。
|
|
3071
3072
|
// ───────────────────────────────────────────────────────────
|
|
3072
|
-
|
|
3073
|
+
//
|
|
3074
|
+
/**
|
|
3075
|
+
* 判定に使う親要素の幅 (px)。 書き出しの窓 1600px から左右の余白を引いた実測の見当。
|
|
3076
|
+
*
|
|
3077
|
+
* **実際の親幅は呼び出し側が決める**。 engine はそれを知らないので、 判定の基準として
|
|
3078
|
+
* 1 つ選ぶ。 選んだ値そのものが閾値の意味を決めるため、 定数として出す。
|
|
3079
|
+
*/
|
|
3080
|
+
const RESPONSIVE_REF_CONTAINER_PX = 1100;
|
|
3081
|
+
/**
|
|
3082
|
+
* 画面上で読めると見なす文字の下限 (px)。
|
|
3083
|
+
*
|
|
3084
|
+
* 12px は WCAG が数値で定める下限ではない (WCAG は寸法でなく拡大できることを求める)。
|
|
3085
|
+
* 下流の見本帳で実際に読み取れるかを見て決めた運用上の下限で、 これを下回る図は
|
|
3086
|
+
* 器 1100px の画面で拡大しないと読めない。
|
|
3087
|
+
*/
|
|
3088
|
+
const RESPONSIVE_MIN_ON_SCREEN_FONT_PX = 12;
|
|
3089
|
+
/**
|
|
3090
|
+
* 判定の基準にする文字の world 寸法。 箱の題の大きさ (`kinds/storage.tsx` の fontSize 22)。
|
|
3091
|
+
*
|
|
3092
|
+
* 図の中には これより小さい文字 (辺の名札等) もあるが、 基準を最小の文字に取ると
|
|
3093
|
+
* ほぼ全ての図が境を割る。 最も多く出る文字で見る。
|
|
3094
|
+
*/
|
|
3095
|
+
const RESPONSIVE_BASE_FONT_WORLD = 22;
|
|
3096
|
+
/** 上の 3 つから導く viewBox width の上限。 数を直接書かない。 */
|
|
3097
|
+
const RESPONSIVE_MAX_VIEWBOX_W =
|
|
3098
|
+
(RESPONSIVE_BASE_FONT_WORLD * RESPONSIVE_REF_CONTAINER_PX) / RESPONSIVE_MIN_ON_SCREEN_FONT_PX;
|
|
3073
3099
|
const vbResp = laid.viewBox;
|
|
3074
3100
|
if (
|
|
3075
3101
|
!(vbResp.w > 0) ||
|
|
@@ -3082,17 +3108,15 @@ function runAxes(
|
|
|
3082
3108
|
`viewBox 寸法 ${vbResp.w}×${vbResp.h} が描画不能 (正の有限値である必要がある)`,
|
|
3083
3109
|
"warn",
|
|
3084
3110
|
);
|
|
3085
|
-
} else {
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
);
|
|
3095
|
-
}
|
|
3111
|
+
} else if (vbResp.w > RESPONSIVE_MAX_VIEWBOX_W) {
|
|
3112
|
+
const 画面上の字 = (RESPONSIVE_BASE_FONT_WORLD * RESPONSIVE_REF_CONTAINER_PX) / vbResp.w;
|
|
3113
|
+
push(
|
|
3114
|
+
"responsive-viewport",
|
|
3115
|
+
`viewBox width ${vbResp.w} が上限 ${RESPONSIVE_MAX_VIEWBOX_W.toFixed(0)} 超え ` +
|
|
3116
|
+
`(親幅 ${RESPONSIVE_REF_CONTAINER_PX}px で箱の題が ${画面上の字.toFixed(1)}px、 ` +
|
|
3117
|
+
`下限 ${RESPONSIVE_MIN_ON_SCREEN_FONT_PX}px)`,
|
|
3118
|
+
"warn",
|
|
3119
|
+
);
|
|
3096
3120
|
}
|
|
3097
3121
|
|
|
3098
3122
|
// ───────────────────────────────────────────────────────────
|
|
@@ -3367,55 +3391,6 @@ function runAxes(
|
|
|
3367
3391
|
}
|
|
3368
3392
|
}
|
|
3369
3393
|
|
|
3370
|
-
// ───────────────────────────────────────────────────────────
|
|
3371
|
-
// Axis 33: subpixel-precision (node / edge label 座標の subpixel drift 検知)
|
|
3372
|
-
//
|
|
3373
|
-
// 判定 = node cx / cy / edge labelX / labelY / lane x / y が SUBPIXEL_TOL (0.5 world) を
|
|
3374
|
-
// 超えて小数点を持つ (e.g. 100.7) と subpixel render 時に SVG 描画が blur を生む。
|
|
3375
|
-
// 整数化 or 0.5 刻みが理想。 label は shift 経路の結果として非整数が出やすい。
|
|
3376
|
-
// ───────────────────────────────────────────────────────────
|
|
3377
|
-
const SUBPIXEL_TOL = 0.5;
|
|
3378
|
-
function isSubpixel(v: number): boolean {
|
|
3379
|
-
// 整数と 0.5 刻みの両方を許容する。
|
|
3380
|
-
//
|
|
3381
|
-
// 0.5 は SVG では「にじむ座標」 ではない。 幅 1 の線は中心を .5 に置くと 1 pixel に
|
|
3382
|
-
// ちょうど収まって輪郭が立つ (逆に整数に置くと 2 pixel に半分ずつ跨いでぼやける)。
|
|
3383
|
-
// 本 axis の説明も「整数化 or 0.5 刻みが理想」 としており、 判定側だけが 0.5 を
|
|
3384
|
-
// 弾いていた。 説明に合わせる。
|
|
3385
|
-
//
|
|
3386
|
-
// 判定は「最も近い 0.5 の倍数からの距離」 で見る。 0.05 以下は float 演算の誤差として許容。
|
|
3387
|
-
const nearestHalf = Math.round(v * 2) / 2;
|
|
3388
|
-
return Math.abs(v - nearestHalf) > SUBPIXEL_TOL / 10;
|
|
3389
|
-
}
|
|
3390
|
-
for (const n of laid.nodes) {
|
|
3391
|
-
if (n.id.endsWith("-spacer") || /^s\d+-/.test(n.id)) continue;
|
|
3392
|
-
if (isSubpixel(n.cx) || isSubpixel(n.cy)) {
|
|
3393
|
-
push(
|
|
3394
|
-
"subpixel-precision",
|
|
3395
|
-
`node "${n.id}" 座標 (${n.cx.toFixed(2)}, ${n.cy.toFixed(2)}) が非整数、 subpixel blur リスク`,
|
|
3396
|
-
"warn",
|
|
3397
|
-
);
|
|
3398
|
-
}
|
|
3399
|
-
}
|
|
3400
|
-
for (const e of laid.edges) {
|
|
3401
|
-
if (isSubpixel(e.labelX) || isSubpixel(e.labelY)) {
|
|
3402
|
-
push(
|
|
3403
|
-
"subpixel-precision",
|
|
3404
|
-
`edge "${e.id}" label 座標 (${e.labelX.toFixed(2)}, ${e.labelY.toFixed(2)}) が非整数、 subpixel blur リスク`,
|
|
3405
|
-
"warn",
|
|
3406
|
-
);
|
|
3407
|
-
}
|
|
3408
|
-
}
|
|
3409
|
-
for (const l of laid.lanes) {
|
|
3410
|
-
if (isSubpixel(l.x) || isSubpixel(l.y)) {
|
|
3411
|
-
push(
|
|
3412
|
-
"subpixel-precision",
|
|
3413
|
-
`lane "${l.id}" 座標 (${l.x.toFixed(2)}, ${l.y.toFixed(2)}) が非整数、 subpixel blur リスク`,
|
|
3414
|
-
"warn",
|
|
3415
|
-
);
|
|
3416
|
-
}
|
|
3417
|
-
}
|
|
3418
|
-
|
|
3419
3394
|
// ───────────────────────────────────────────────────────────
|
|
3420
3395
|
// Axis 34: dom-complexity-budget (1 diagram あたりの element 総数)
|
|
3421
3396
|
//
|
|
@@ -4481,7 +4456,6 @@ function validateMetaAxes(
|
|
|
4481
4456
|
"print-media-compat",
|
|
4482
4457
|
"color-blind-safety",
|
|
4483
4458
|
"marker-gradient-def-integrity",
|
|
4484
|
-
"subpixel-precision",
|
|
4485
4459
|
"dom-complexity-budget",
|
|
4486
4460
|
"reduced-motion-compat",
|
|
4487
4461
|
"touch-target-size",
|
|
@@ -4550,7 +4524,6 @@ function validateMetaAxes(
|
|
|
4550
4524
|
"print-media-compat",
|
|
4551
4525
|
"color-blind-safety",
|
|
4552
4526
|
"marker-gradient-def-integrity",
|
|
4553
|
-
"subpixel-precision",
|
|
4554
4527
|
"dom-complexity-budget",
|
|
4555
4528
|
"reduced-motion-compat",
|
|
4556
4529
|
"touch-target-size",
|
|
@@ -4607,8 +4580,9 @@ function validateMetaAxes(
|
|
|
4607
4580
|
//
|
|
4608
4581
|
// 削除済 = engine-meta 51 (mermaid-parity、 #366) / 軸 29 (svg-filter-integrity) /
|
|
4609
4582
|
// 軸 30 (neumorphism-shadow-budget、 どちらも #426 で主題の廃止に伴い削除) /
|
|
4610
|
-
// 軸 40 (memory-budget、 #775 で軸 34 に一本化)
|
|
4611
|
-
|
|
4583
|
+
// 軸 40 (memory-budget、 #775 で軸 34 に一本化) /
|
|
4584
|
+
// 軸 33 (subpixel-precision、 #783 で削除)。
|
|
4585
|
+
const EXPECTED_AXIS_COUNT = 66;
|
|
4612
4586
|
if (allAxes.length !== EXPECTED_AXIS_COUNT) {
|
|
4613
4587
|
out.push({
|
|
4614
4588
|
axis: "axis-documentation-completeness",
|