@zealakit/css-doctor-cli 0.0.0-stage → 1.1.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/LICENSE +21 -0
- package/README.md +393 -2
- package/README_CN.md +301 -0
- package/README_VI.md +309 -0
- package/dist/index.js +12245 -0
- package/dist/index.js.map +1 -0
- package/package.json +74 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zealamic
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,394 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# @zealakit/css-doctor-cli
|
|
4
|
+
|
|
5
|
+
**Command-line diagnostics for CSS files using the native css-doctor engine.**
|
|
6
|
+
|
|
7
|
+
[English](https://github.com/zealakit/css-doctor/blob/main/packages/cli/README.md) | [Tiếng Việt](https://github.com/zealakit/css-doctor/blob/main/packages/cli/README_VI.md) | [简体中文](https://github.com/zealakit/css-doctor/blob/main/packages/cli/README_CN.md)
|
|
8
|
+
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
## What it does
|
|
16
|
+
|
|
17
|
+
`css-doctor check` reads one or more CSS files, parses them with the native
|
|
18
|
+
LightningCSS engine, and prints a terminal report (or JSON for CI).
|
|
19
|
+
|
|
20
|
+
It is a **diagnostics** tool. It does **not** rewrite files, minify CSS, or
|
|
21
|
+
split stylesheets by page. Use the Vite / Next / Nuxt / Rsbuild / Remix adapters
|
|
22
|
+
for build-time optimization.
|
|
23
|
+
|
|
24
|
+
The CLI reports:
|
|
25
|
+
|
|
26
|
+
| Kind | Meaning |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| `syntax` | Parser / syntax warnings from LightningCSS |
|
|
29
|
+
| `empty-rule` | Rules with no declarations and no nested rules (dead-code candidates) |
|
|
30
|
+
| `duplicate-selector` | The same selector text appears in more than one rule |
|
|
31
|
+
| `threshold` | Selector count in a file exceeds `--threshold` |
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
- Node.js **≥ 18**
|
|
36
|
+
- A supported `@zealakit/css-doctor-binding` native binary (downloaded with the
|
|
37
|
+
package on macOS / Linux / Windows x64 targets)
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
### One-off run (no install)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx @zealakit/css-doctor-cli check "src/**/*.css"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Project dependency
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pnpm add -D @zealakit/css-doctor-cli
|
|
51
|
+
|
|
52
|
+
# or
|
|
53
|
+
npm install -D @zealakit/css-doctor-cli
|
|
54
|
+
yarn add -D @zealakit/css-doctor-cli
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
After install, the `css-doctor` binary is available via:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pnpm exec css-doctor --help
|
|
61
|
+
# npm
|
|
62
|
+
npx css-doctor --help
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### package.json script
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"scripts": {
|
|
70
|
+
"css:check": "css-doctor check \"src/**/*.css\"",
|
|
71
|
+
"css:check:ci": "css-doctor check \"src/**/*.css\" --json --threshold 500"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pnpm css:check
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Quick start
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Help / version
|
|
84
|
+
css-doctor --help
|
|
85
|
+
css-doctor --version
|
|
86
|
+
css-doctor check --help
|
|
87
|
+
css-doctor health --help
|
|
88
|
+
|
|
89
|
+
# Single file
|
|
90
|
+
css-doctor check src/styles/app.css
|
|
91
|
+
|
|
92
|
+
# Multiple files
|
|
93
|
+
css-doctor check src/a.css src/b.css
|
|
94
|
+
|
|
95
|
+
# Glob — quote the pattern so the shell does not expand it first
|
|
96
|
+
css-doctor check "src/**/*.css"
|
|
97
|
+
|
|
98
|
+
# Mix paths and globs
|
|
99
|
+
css-doctor check styles/global.css "components/**/*.css"
|
|
100
|
+
|
|
101
|
+
# CSS Health Score (polished report)
|
|
102
|
+
css-doctor health "src/**/*.css"
|
|
103
|
+
css-doctor health "src/**/*.css" --json
|
|
104
|
+
css-doctor health "src/**/*.css" --fail-under 80
|
|
105
|
+
css-doctor check "src/**/*.css" --fail-under 85
|
|
106
|
+
|
|
107
|
+
# Baseline + regression
|
|
108
|
+
css-doctor baseline create "src/**/*.css"
|
|
109
|
+
css-doctor baseline show
|
|
110
|
+
css-doctor diff "src/**/*.css" --fail-on-regression
|
|
111
|
+
|
|
112
|
+
# Optimization intelligence
|
|
113
|
+
css-doctor optimize "src/**/*.css" --dry-run --explain --json
|
|
114
|
+
css-doctor split "src/**/*.css" --dry-run
|
|
115
|
+
css-doctor fix --list
|
|
116
|
+
css-doctor fix "src/**/*.css" --dry-run --rule dead.empty-rule
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Command: `check`
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
css-doctor check [patterns...] [options]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
| Argument / option | Description |
|
|
126
|
+
| --- | --- |
|
|
127
|
+
| `patterns...` | One or more CSS file paths or glob patterns. **Required.** |
|
|
128
|
+
| `-j, --json` | Print a structured `CheckReport` JSON document to stdout |
|
|
129
|
+
| `--threshold <n>` | Warn when a file has more than `<n>` selectors (`n` ≥ 0 integer) |
|
|
130
|
+
| `--fail-under <n>` | Exit `1` when overall Health Score is below `<n>` (0–100) |
|
|
131
|
+
| `-v, --version` | Print CLI version (global flag) |
|
|
132
|
+
| `-h, --help` | Print help |
|
|
133
|
+
|
|
134
|
+
### Glob tips
|
|
135
|
+
|
|
136
|
+
- Quote globs: `"src/**/*.css"`. Unquoted `*` may be expanded by your shell
|
|
137
|
+
before css-doctor sees the pattern.
|
|
138
|
+
- `node_modules` and `.git` are ignored automatically.
|
|
139
|
+
- Literal paths that contain glob characters (for example `src/[slug].css`)
|
|
140
|
+
still work when passed as an existing file path.
|
|
141
|
+
|
|
142
|
+
### Example terminal output
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
css-doctor v1.0.0 · check
|
|
146
|
+
patterns src/**/*.css
|
|
147
|
+
────────────────────────────────────────────────────────────────
|
|
148
|
+
SUCCESS src/styles/app.css · 12.4 KB
|
|
149
|
+
selectors 184 · rules 132 · declarations 421
|
|
150
|
+
analysis 3.2 ms · read 0.8 ms · total 4.0 ms
|
|
151
|
+
Top selectors
|
|
152
|
+
#app .card:hover
|
|
153
|
+
.nav-link.is-active
|
|
154
|
+
…
|
|
155
|
+
|
|
156
|
+
WARNING src/legacy.css · 48.1 KB
|
|
157
|
+
selectors 612 · rules 540 · declarations 1 204
|
|
158
|
+
Diagnostics
|
|
159
|
+
• empty-rule — Rule ".unused" has no declarations…
|
|
160
|
+
• duplicate-selector — Selector ".btn" is defined in multiple rules…
|
|
161
|
+
────────────────────────────────────────────────────────────────
|
|
162
|
+
files 2 · analyzed 2 · issues 2 · …
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Status badges:
|
|
166
|
+
|
|
167
|
+
| Status | When |
|
|
168
|
+
| --- | --- |
|
|
169
|
+
| `SUCCESS` | File analyzed; no issues |
|
|
170
|
+
| `WARNING` | File analyzed; has syntax / empty-rule / duplicate / threshold issues |
|
|
171
|
+
| `ERROR` | File could not be read or analyzed, or setup failed |
|
|
172
|
+
|
|
173
|
+
## CI and JSON output
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
css-doctor check "src/**/*.css" --json
|
|
177
|
+
css-doctor check "src/**/*.css" -j --threshold 500
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
`--json` prints a stable `CheckReport` (`schemaVersion: 1`) with:
|
|
181
|
+
|
|
182
|
+
- `success` — `true` only when setup succeeded and every matched file was analyzed
|
|
183
|
+
- `errors` — fatal setup messages (no patterns, no matches, binding load failure, …)
|
|
184
|
+
- `files[]` — per-file path, size, timings, `issues`, and native `result` when `ok`
|
|
185
|
+
- `summary` — aggregated counters (files, selectors, warnings, timings, …)
|
|
186
|
+
|
|
187
|
+
Pipe or save the report:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
css-doctor check "src/**/*.css" --json > css-doctor-report.json
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Exit codes (`check`)
|
|
194
|
+
|
|
195
|
+
| Code | Meaning |
|
|
196
|
+
| --- | --- |
|
|
197
|
+
| `0` | Setup OK and every matched file was read + analyzed (warnings still allowed) |
|
|
198
|
+
| `1` | Fatal setup error, no matches, unloadable native binding, a file failed to read/analyze, or `--fail-under` failed |
|
|
199
|
+
|
|
200
|
+
Warnings and hints **do not** fail the process unless you also set
|
|
201
|
+
`--fail-under`. Use `--json` and inspect `summary.issues` / `files[].issues`
|
|
202
|
+
if you want CI gates on warnings.
|
|
203
|
+
|
|
204
|
+
`check --json` also includes an aggregated `health` field (CSS Health Score).
|
|
205
|
+
|
|
206
|
+
## Command: `health`
|
|
207
|
+
|
|
208
|
+
```text
|
|
209
|
+
css-doctor health [patterns...] [options]
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Evaluates a deterministic **CSS Health Score** (0–100) across five dimensions:
|
|
213
|
+
|
|
214
|
+
| Dimension | Weight | Measures |
|
|
215
|
+
| --- | ---: | --- |
|
|
216
|
+
| Selector Complexity | 20% | High specificity, deep combinators/nesting, long chains |
|
|
217
|
+
| Duplicate Rules | 20% | Repeated selectors / intra-rule duplicate declarations |
|
|
218
|
+
| CSS Size Efficiency | 20% | Large sheets, heavy rules, selector pressure |
|
|
219
|
+
| Dead CSS | 25% | Empty rules, recoverable syntax drops |
|
|
220
|
+
| Variable Consistency | 15% | Duplicate/`var()` usage gaps, naming mix (heuristic) |
|
|
221
|
+
|
|
222
|
+
Grades: **A** 90–100 · **B** 80–89 · **C** 70–79 · **D** 60–69 · **F** 0–59.
|
|
223
|
+
|
|
224
|
+
| Option | Description |
|
|
225
|
+
| --- | --- |
|
|
226
|
+
| `-j, --json` | Stable health JSON (`schemaVersion: 1`) |
|
|
227
|
+
| `--threshold <n>` | Maps to native `manySelectors` size pressure |
|
|
228
|
+
| `--fail-under <n>` | Exit `1` when overall score `< n` (CI gate) |
|
|
229
|
+
|
|
230
|
+
The score is **not** a guarantee of visual correctness. Unused-variable and
|
|
231
|
+
cross-file/`var()` findings are marked `heuristic` when static evidence is
|
|
232
|
+
incomplete. Page-usage dead CSS still requires adapters / `pageUsage`.
|
|
233
|
+
|
|
234
|
+
### GitHub Actions sketch
|
|
235
|
+
|
|
236
|
+
```yaml
|
|
237
|
+
- name: CSS diagnostics
|
|
238
|
+
run: pnpm exec css-doctor check "src/**/*.css" --json --threshold 800
|
|
239
|
+
|
|
240
|
+
- name: CSS health gate
|
|
241
|
+
run: pnpm exec css-doctor health "src/**/*.css" --fail-under 80
|
|
242
|
+
|
|
243
|
+
- name: CSS regression gate
|
|
244
|
+
run: pnpm exec css-doctor diff "src/**/*.css" --fail-on-regression --fail-on-new-errors
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Initialize and commit `.css-doctor/baseline.json` on the default branch before
|
|
248
|
+
enabling the regression gate.
|
|
249
|
+
|
|
250
|
+
## Command: `baseline`
|
|
251
|
+
|
|
252
|
+
```text
|
|
253
|
+
css-doctor baseline create|show|validate|remove [options]
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Creates a versioned JSON baseline (default `.css-doctor/baseline.json`) with:
|
|
257
|
+
|
|
258
|
+
- schema / tool versions and creation timestamp;
|
|
259
|
+
- overall + dimension Health Scores;
|
|
260
|
+
- aggregate size / rule / declaration counters;
|
|
261
|
+
- per-file content fingerprints (no CSS source stored);
|
|
262
|
+
- diagnostic fingerprints that ignore line-number drift.
|
|
263
|
+
|
|
264
|
+
| Subcommand | Purpose |
|
|
265
|
+
| --- | --- |
|
|
266
|
+
| `create [patterns...]` | Analyze CSS and write the baseline (`-o/--output` for custom path) |
|
|
267
|
+
| `show` | Print baseline metadata and scores |
|
|
268
|
+
| `validate` | Check schema compatibility (hard fail vs soft tool-version warning) |
|
|
269
|
+
| `remove` | Delete the baseline file |
|
|
270
|
+
|
|
271
|
+
## Command: `diff`
|
|
272
|
+
|
|
273
|
+
```text
|
|
274
|
+
css-doctor diff [patterns...] [options]
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Compares the current analysis against a stored baseline and classifies status as
|
|
278
|
+
`healthy` | `improved` | `regressed` | `mixed` | `inconclusive`.
|
|
279
|
+
|
|
280
|
+
| Option | Description |
|
|
281
|
+
| --- | --- |
|
|
282
|
+
| `-b, --baseline <path>` | Baseline path (default `.css-doctor/baseline.json`) |
|
|
283
|
+
| `--fail-on-regression` | Exit `1` when status is `regressed` or `mixed` |
|
|
284
|
+
| `--fail-on-new-errors` | Exit `1` when new error diagnostics appear |
|
|
285
|
+
| `--fail-on-new-diagnostics` | Exit `1` when any new diagnostics appear |
|
|
286
|
+
| `--max-size-increase <n%>` | Fail when total CSS bytes grow beyond the percent |
|
|
287
|
+
| `--max-new-errors <n>` | Fail when new error count exceeds `<n>` |
|
|
288
|
+
| `--max-new-warnings <n>` | Fail when new warning count exceeds `<n>` |
|
|
289
|
+
| `--min-score <n>` | Fail when current overall score is below `<n>` |
|
|
290
|
+
| `--score-tolerance <n>` | Ignore score deltas within absolute tolerance |
|
|
291
|
+
| `-v, --verbose` | Longer file / diagnostic lists |
|
|
292
|
+
| `-j, --json` | Stable regression JSON (`schemaVersion: 1`) |
|
|
293
|
+
|
|
294
|
+
Diagnostic matching uses `code|path|selector|severity` fingerprints so inserting
|
|
295
|
+
lines near the top of a file does not mark every later finding as new.
|
|
296
|
+
|
|
297
|
+
### Project config
|
|
298
|
+
|
|
299
|
+
Optional `.css-doctor/config.json`:
|
|
300
|
+
|
|
301
|
+
```json
|
|
302
|
+
{
|
|
303
|
+
"baseline": ".css-doctor/baseline.json",
|
|
304
|
+
"patterns": ["src/**/*.css"],
|
|
305
|
+
"regression": {
|
|
306
|
+
"enabled": true,
|
|
307
|
+
"scoreTolerance": 1,
|
|
308
|
+
"sizeIncreasePercent": 10,
|
|
309
|
+
"maxNewErrors": 0,
|
|
310
|
+
"maxNewWarnings": 5
|
|
311
|
+
},
|
|
312
|
+
"qualityGates": {
|
|
313
|
+
"minScore": 85,
|
|
314
|
+
"maxSizeIncreasePercent": 10,
|
|
315
|
+
"failOnRegression": true
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Precedence:** CLI flags > config file > built-in defaults.
|
|
321
|
+
|
|
322
|
+
### Exit codes (`diff` / `baseline`)
|
|
323
|
+
|
|
324
|
+
| Code | Meaning |
|
|
325
|
+
| --- | --- |
|
|
326
|
+
| `0` | Command succeeded and configured quality gates passed |
|
|
327
|
+
| `1` | Missing/invalid baseline, analysis failure, or a quality gate failed |
|
|
328
|
+
|
|
329
|
+
## Command: `optimize` / `split`
|
|
330
|
+
|
|
331
|
+
```text
|
|
332
|
+
css-doctor optimize|split [patterns...] [options]
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Runs the native two-tier pipeline (page coverage → size budget) and prints an
|
|
336
|
+
**optimization report** with structured decisions.
|
|
337
|
+
|
|
338
|
+
| Option | Description |
|
|
339
|
+
| --- | --- |
|
|
340
|
+
| `--dry-run` | Preview only (default unless `--write`) |
|
|
341
|
+
| `--write --out-dir <dir>` | Emit chunk CSS files under `<dir>` |
|
|
342
|
+
| `--explain` / `-v` | Show more decision detail |
|
|
343
|
+
| `--diff` | Concise unified diff of source vs emitted CSS |
|
|
344
|
+
| `--page-usage <json>` | Route → class map for coverage / DCE |
|
|
345
|
+
| `--min-page-ratio <n>` | Common threshold (0–1) |
|
|
346
|
+
| `--max-chunk-size <bytes>` | Size budget |
|
|
347
|
+
| `--no-page-coverage` / `--no-size-budget` / `--no-isolate-variables` / `--no-minify` | Disable stages |
|
|
348
|
+
| `-j, --json` / `--report <path>` | Stable JSON (`schemaVersion: 1`) |
|
|
349
|
+
|
|
350
|
+
**Metrics:** `bytesEliminated` is measured against a reference payload (common /
|
|
351
|
+
minified equivalent). `redistributedBytes` accounts for split duplication — chunk
|
|
352
|
+
sum vs input is **not** claimed as savings.
|
|
353
|
+
|
|
354
|
+
## Command: `fix`
|
|
355
|
+
|
|
356
|
+
```text
|
|
357
|
+
css-doctor fix [patterns...] [options]
|
|
358
|
+
css-doctor fix --list
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
| Option | Description |
|
|
362
|
+
| --- | --- |
|
|
363
|
+
| `--list` | Show fix catalog with safety levels |
|
|
364
|
+
| `--dry-run` | Preview (default unless `--write`) |
|
|
365
|
+
| `--write` | Atomically apply Safe fixes to source files |
|
|
366
|
+
| `--rule <id>` | Limit to selected rule ids (repeatable) |
|
|
367
|
+
| `--backup` | Write `.bak` before modifying |
|
|
368
|
+
| `--diff` | Unified diff preview |
|
|
369
|
+
| `-j, --json` | Stable JSON |
|
|
370
|
+
|
|
371
|
+
### Autofix safety
|
|
372
|
+
|
|
373
|
+
| Level | Default | Examples |
|
|
374
|
+
| --- | --- | --- |
|
|
375
|
+
| Safe | Applied with `--write` | `dead.empty-rule`, `duplicate.declaration` |
|
|
376
|
+
| Review | Never silent | `duplicate.selector` |
|
|
377
|
+
| Unsafe | Never applied | `variable.unused-definition` |
|
|
378
|
+
|
|
379
|
+
Safe transforms use LightningCSS AST rewrites and preserve cascade under the
|
|
380
|
+
documented conditions.
|
|
381
|
+
|
|
382
|
+
## Safety and limitations
|
|
383
|
+
|
|
384
|
+
- Binary name: `css-doctor` (package `bin` field).
|
|
385
|
+
- The CLI **analyzes** and **scores** CSS. Page-coverage splitting, size budgets,
|
|
386
|
+
and variable isolation for production bundles belong to the framework adapters.
|
|
387
|
+
- CSS Modules / dynamic class usage are out of scope for static checks; those
|
|
388
|
+
matter for build plugins.
|
|
389
|
+
- Native binding must resolve for your platform; no Rust toolchain is required
|
|
390
|
+
when a prebuilt binary is available.
|
|
391
|
+
|
|
392
|
+
## Full documentation
|
|
393
|
+
|
|
394
|
+
Project README: [English](https://github.com/zealakit/css-doctor/blob/main/README.md) | [Tiếng Việt](https://github.com/zealakit/css-doctor/blob/main/README_VI.md) | [简体中文](https://github.com/zealakit/css-doctor/blob/main/README_CN.md)
|