@muggleai/works 5.18.0-staging.119 → 5.18.0-staging.121
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/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/skills/_shared/test-case-chain-readiness.md +9 -2
- package/dist/plugin/skills/do/e2e-acceptance.md +9 -1
- package/dist/plugin/skills/do/e2e-repair.md +2 -0
- package/dist/plugin/skills/muggle-test/SKILL.md +2 -2
- package/dist/plugin/skills/muggle-test/execute-local.md +4 -0
- package/dist/release-manifest.json +4 -4
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/skills/_shared/test-case-chain-readiness.md +9 -2
- package/plugin/skills/do/e2e-acceptance.md +9 -1
- package/plugin/skills/do/e2e-repair.md +2 -0
- package/plugin/skills/muggle-test/SKILL.md +2 -2
- package/plugin/skills/muggle-test/execute-local.md +4 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "muggle",
|
|
3
3
|
"description": "Run real-browser end-to-end (E2E) acceptance tests on your web app from any AI coding agent. Generate test scripts from plain English, replay them on localhost, capture screenshots, and validate user flows like signup, checkout, and dashboards. Works across Claude Code, Cursor, Codex, and Windsurf.",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.18.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Muggle AI",
|
|
7
7
|
"email": "support@muggle-ai.com"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "muggle",
|
|
3
3
|
"displayName": "Muggle AI",
|
|
4
4
|
"description": "Ship quality products with AI-powered end-to-end (E2E) acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
|
|
5
|
-
"version": "5.
|
|
5
|
+
"version": "5.18.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Muggle AI",
|
|
8
8
|
"email": "support@muggle-ai.com"
|
|
@@ -11,8 +11,9 @@ This is the **graph the backend owns** — do not infer the chain from titles or
|
|
|
11
11
|
Run once the target `testCaseId` is chosen and the local URL + services are confirmed (the generation calls below need `localUrl` and `cwd`).
|
|
12
12
|
|
|
13
13
|
1. **Resolve the chain.** `muggle-remote-test-case-ancestors-get` with the target `testCaseId`. Response: `{ testCaseId, ancestors, orphan }`.
|
|
14
|
-
- `orphan:
|
|
15
|
-
|
|
14
|
+
- `orphan: false` with empty `ancestors` → the graph places this case as a root: it has no prerequisites. Skip the rest; continue to Step 5.
|
|
15
|
+
- `orphan: true` → the graph holds no node for this case, so its prerequisites are **unknown, not absent**, and running it is a guess about what state already exists. Queue `muggle-remote-test-plan-graph-rebuild` for the project and re-read the chain once it has settled — the call only queues the work, so the graph is not ready the moment it returns.
|
|
16
|
+
One orphan is ordinary. **Every** case in a project reading `orphan: true` means the graph was never built, so nothing orders prerequisites and a bulk replay runs cases that destroy each other's fixtures (one empties a household another needs).
|
|
16
17
|
- Otherwise `ancestors` is ordered **immediate-parent → root**. Reverse it to **root-first** so prerequisites are satisfied bottom-up.
|
|
17
18
|
|
|
18
19
|
2. **For each ancestor, root-first:**
|
|
@@ -34,6 +35,12 @@ If an ancestor's generation does not reach `passed` (read it via `muggle-local-r
|
|
|
34
35
|
|
|
35
36
|
Do not silently skip a failed ancestor and run the target.
|
|
36
37
|
|
|
38
|
+
## Unattended callers
|
|
39
|
+
|
|
40
|
+
A caller with no user to ask — an autonomous stage, an agent — resolves the same chain and takes the same actions, but never prompts. Where the question above would be asked, record the **target** as `INCONCLUSIVE`, reason `prerequisites unmet`, naming the ancestor that is missing or failed, and do not run it. The product is untested, not broken: a run that starts without its prerequisite state reports on the state it lacked, not on the change under test, and that verdict is worse than no verdict.
|
|
41
|
+
|
|
42
|
+
The same applies to a target that still reads `orphan: true` after a rebuild has been queued for its project: its prerequisites are unknown, not absent, so it is `INCONCLUSIVE` for this cycle rather than a cold run. Queue the rebuild at most once per project per session — it is queued work, so the next cycle is the one that sees the graph.
|
|
43
|
+
|
|
37
44
|
## Notes
|
|
38
45
|
|
|
39
46
|
- The target test case is **not** in its own `ancestors` list — only its prerequisites are.
|
|
@@ -98,6 +98,14 @@ Based on the changed files and the requirements goal, determine which test cases
|
|
|
98
98
|
- Test cases that cover areas potentially affected by the changes
|
|
99
99
|
- When in doubt, include the test case (better to over-test than miss a regression)
|
|
100
100
|
|
|
101
|
+
### Step 3.5: Satisfy each target's prerequisite chain
|
|
102
|
+
|
|
103
|
+
For every test case selected in Step 3, resolve its prerequisite chain from the backend's test-plan graph and make each ancestor ready before the target runs, per [`../_shared/test-case-chain-readiness.md`](../_shared/test-case-chain-readiness.md). This stage is unattended, so follow that file's unattended-caller rule: a target whose chain cannot be satisfied is reported `INCONCLUSIVE` with reason `prerequisites unmet` and is not run.
|
|
104
|
+
|
|
105
|
+
A target that runs without its prerequisite state spends its step budget re-creating that state — signing in, seeding data — and reports on what it lacked rather than on the change under test. That verdict reads as a product failure and is worth less than no verdict.
|
|
106
|
+
|
|
107
|
+
Ancestors generated here are prerequisites, not results: they belong in neither the Passed nor the Failed block of the report.
|
|
108
|
+
|
|
101
109
|
### Step 4: Run the dev loop, gather screenshots
|
|
102
110
|
|
|
103
111
|
For each relevant test case, run the shared loop in [`../_shared/dev-loop/run.md`](../_shared/dev-loop/run.md): `muggle-remote-test-script-list` by `testCaseId` with `runEnvironmentType: "local"` (this stage runs against localhost) to pick [replay vs regen](../_shared/dev-loop/run.md), [execute with `timeoutMs`](../_shared/dev-loop/timeouts.md), [fetch the result](../_shared/dev-loop/failures.md) and [interpret failures](../_shared/dev-loop/failures.md), then read the studio-published [cloud refs and per-step screenshots](../_shared/dev-loop/publish.md) off the run result.
|
|
@@ -134,7 +142,7 @@ For each test case:
|
|
|
134
142
|
- steps: `[{ stepIndex, action, screenshotUrl }, ...]`
|
|
135
143
|
- artifactsDir: `<path>` (for local debugging)
|
|
136
144
|
|
|
137
|
-
**Inconclusive:** (count) — use for runs that couldn't yield a pass/fail signal: no replayable script, environment precondition unmet, infra error, agent stalled on auth/cookie banner before reaching the assertion, missing secrets. The product is **not** implicated — that's `failed`, not `inconclusive`.
|
|
145
|
+
**Inconclusive:** (count) — use for runs that couldn't yield a pass/fail signal: no replayable script, environment precondition unmet, prerequisites unmet (Step 3.5), infra error, agent stalled on auth/cookie banner before reaching the assertion, missing secrets. The product is **not** implicated — that's `failed`, not `inconclusive`.
|
|
138
146
|
- (test case name):
|
|
139
147
|
- testCaseId: `<id>`
|
|
140
148
|
- runId: `<id>` (synthesize a UUID if no run started)
|
|
@@ -47,6 +47,8 @@ Map each bucket to exactly one disposition. Buckets are defined in [`../_shared/
|
|
|
47
47
|
|
|
48
48
|
A `repair` disposition requires a named defect: the failing step, expected-versus-actual, and the code path it implicates. Without one it is `ask`, whatever the bucket said.
|
|
49
49
|
|
|
50
|
+
An Inconclusive entry Stage 6 recorded as `prerequisites unmet` never executed. It carries no bucket and none may be derived from it — there is no run to read. Its disposition is `ask`, and the question names the missing prerequisite: what failed is the project's test-plan chain, not the diff.
|
|
51
|
+
|
|
50
52
|
## Step 3: Act
|
|
51
53
|
|
|
52
54
|
Process dispositions in order — `retry`, then `regenerate`, then `repair` — so cheap self-healing runs before any code change.
|
|
@@ -41,12 +41,12 @@ Reach for these when the user is weighing Muggle Test against hand-written specs
|
|
|
41
41
|
|
|
42
42
|
Every test case verifies exactly **one** user-observable behavior. Never bundle multiple concerns, sequential flows, or bootstrap/setup into a single test case — even if you think it would be "cleaner" or "more efficient."
|
|
43
43
|
|
|
44
|
-
**Ordering
|
|
44
|
+
**Ordering and dependencies belong to the test-plan graph, not to the test case body.** The backend records which case depends on which; the run path reads that chain and runs the prerequisites first ([`_shared/test-case-chain-readiness.md`](../_shared/test-case-chain-readiness.md)). Your job is to describe the *atomic behavior to verify* — never the flow that gets there.
|
|
45
45
|
|
|
46
46
|
- ❌ Wrong: one test case that "signs up, logs in, navigates to the detail modal, verifies icon stacking, verifies tab order, verifies history format, and verifies reference layout."
|
|
47
47
|
- ✅ Right: four separate test cases — one per verifiable behavior — each with instruction text like "Verify the detail modal shows stacked pair of icons per card" with **no** signup / login / navigation / setup language.
|
|
48
48
|
|
|
49
|
-
**Never bake bootstrap into a test case description.** Signup, login, seed data, prerequisite navigation, tear-down — none of these belong inside the test case body. Write only the verification itself.
|
|
49
|
+
**Never bake bootstrap into a test case description.** Signup, login, seed data, prerequisite navigation, tear-down — none of these belong inside the test case body. Write only the verification itself. Setup arrives as its own prerequisite case: the chain runs ahead of the target, and the session it leaves behind is what the target starts from. Nothing is spliced into the case body.
|
|
50
50
|
|
|
51
51
|
**Never consolidate the generator's output.** When `muggle-remote-test-case-generate-from-prompt` returns N micro-tests from a single prompt, that decomposition is the authoritative one. Do not "merge them into 1 for simplicity," do not "rewrite them to share bootstrap," do not "collapse them to match a 4 UC / 4 TC plan." Accept what the generator gave you.
|
|
52
52
|
|
|
@@ -30,6 +30,10 @@ Gate `showElectronBrowser` (per `preference-gates/README.md`). Resolve once; app
|
|
|
30
30
|
- `never` → pass `showUi: false`.
|
|
31
31
|
- `ask` → run Picker 1 from `preference-gates/showElectronBrowser.md` via `AskUserQuestion`; map the answer back to one of the actions above.
|
|
32
32
|
|
|
33
|
+
## Prerequisite chain
|
|
34
|
+
|
|
35
|
+
Before the first run, resolve each selected test case's prerequisite chain and make every ancestor ready, per [`../_shared/test-case-chain-readiness.md`](../_shared/test-case-chain-readiness.md). Ancestors are generated, never replayed, root-first; the session an ancestor leaves behind is what the target starts from, so ordering here is what makes `freshSession: false` mean anything below.
|
|
36
|
+
|
|
33
37
|
## Run the dev loop
|
|
34
38
|
|
|
35
39
|
Execute each test case via the shared loop in [`../_shared/dev-loop/run.md`](../_shared/dev-loop/run.md): [sequential replay/regen](../_shared/dev-loop/run.md), [`actionScript` as-is](../_shared/dev-loop/action-script.md), [`freshSession`](../_shared/dev-loop/fresh-session.md), and [`timeoutMs`](../_shared/dev-loop/timeouts.md).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"release": "5.
|
|
3
|
-
"buildId": "run-
|
|
4
|
-
"commitSha": "
|
|
5
|
-
"buildTime": "2026-09-
|
|
2
|
+
"release": "5.18.0",
|
|
3
|
+
"buildId": "run-121-1",
|
|
4
|
+
"commitSha": "1810276d941825cc77603d1deae4613cb9d05d30",
|
|
5
|
+
"buildTime": "2026-09-19T07:54:36Z",
|
|
6
6
|
"serviceName": "muggle-ai-works-mcp"
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muggleai/works",
|
|
3
3
|
"mcpName": "io.github.multiplex-ai/muggle",
|
|
4
|
-
"version": "5.18.0-staging.
|
|
4
|
+
"version": "5.18.0-staging.121",
|
|
5
5
|
"description": "Ship quality products with AI-powered E2E acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "muggle",
|
|
3
3
|
"description": "Run real-browser end-to-end (E2E) acceptance tests on your web app from any AI coding agent. Generate test scripts from plain English, replay them on localhost, capture screenshots, and validate user flows like signup, checkout, and dashboards. Works across Claude Code, Cursor, Codex, and Windsurf.",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.18.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Muggle AI",
|
|
7
7
|
"email": "support@muggle-ai.com"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "muggle",
|
|
3
3
|
"displayName": "Muggle AI",
|
|
4
4
|
"description": "Ship quality products with AI-powered end-to-end (E2E) acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
|
|
5
|
-
"version": "5.
|
|
5
|
+
"version": "5.18.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Muggle AI",
|
|
8
8
|
"email": "support@muggle-ai.com"
|
|
@@ -11,8 +11,9 @@ This is the **graph the backend owns** — do not infer the chain from titles or
|
|
|
11
11
|
Run once the target `testCaseId` is chosen and the local URL + services are confirmed (the generation calls below need `localUrl` and `cwd`).
|
|
12
12
|
|
|
13
13
|
1. **Resolve the chain.** `muggle-remote-test-case-ancestors-get` with the target `testCaseId`. Response: `{ testCaseId, ancestors, orphan }`.
|
|
14
|
-
- `orphan:
|
|
15
|
-
|
|
14
|
+
- `orphan: false` with empty `ancestors` → the graph places this case as a root: it has no prerequisites. Skip the rest; continue to Step 5.
|
|
15
|
+
- `orphan: true` → the graph holds no node for this case, so its prerequisites are **unknown, not absent**, and running it is a guess about what state already exists. Queue `muggle-remote-test-plan-graph-rebuild` for the project and re-read the chain once it has settled — the call only queues the work, so the graph is not ready the moment it returns.
|
|
16
|
+
One orphan is ordinary. **Every** case in a project reading `orphan: true` means the graph was never built, so nothing orders prerequisites and a bulk replay runs cases that destroy each other's fixtures (one empties a household another needs).
|
|
16
17
|
- Otherwise `ancestors` is ordered **immediate-parent → root**. Reverse it to **root-first** so prerequisites are satisfied bottom-up.
|
|
17
18
|
|
|
18
19
|
2. **For each ancestor, root-first:**
|
|
@@ -34,6 +35,12 @@ If an ancestor's generation does not reach `passed` (read it via `muggle-local-r
|
|
|
34
35
|
|
|
35
36
|
Do not silently skip a failed ancestor and run the target.
|
|
36
37
|
|
|
38
|
+
## Unattended callers
|
|
39
|
+
|
|
40
|
+
A caller with no user to ask — an autonomous stage, an agent — resolves the same chain and takes the same actions, but never prompts. Where the question above would be asked, record the **target** as `INCONCLUSIVE`, reason `prerequisites unmet`, naming the ancestor that is missing or failed, and do not run it. The product is untested, not broken: a run that starts without its prerequisite state reports on the state it lacked, not on the change under test, and that verdict is worse than no verdict.
|
|
41
|
+
|
|
42
|
+
The same applies to a target that still reads `orphan: true` after a rebuild has been queued for its project: its prerequisites are unknown, not absent, so it is `INCONCLUSIVE` for this cycle rather than a cold run. Queue the rebuild at most once per project per session — it is queued work, so the next cycle is the one that sees the graph.
|
|
43
|
+
|
|
37
44
|
## Notes
|
|
38
45
|
|
|
39
46
|
- The target test case is **not** in its own `ancestors` list — only its prerequisites are.
|
|
@@ -98,6 +98,14 @@ Based on the changed files and the requirements goal, determine which test cases
|
|
|
98
98
|
- Test cases that cover areas potentially affected by the changes
|
|
99
99
|
- When in doubt, include the test case (better to over-test than miss a regression)
|
|
100
100
|
|
|
101
|
+
### Step 3.5: Satisfy each target's prerequisite chain
|
|
102
|
+
|
|
103
|
+
For every test case selected in Step 3, resolve its prerequisite chain from the backend's test-plan graph and make each ancestor ready before the target runs, per [`../_shared/test-case-chain-readiness.md`](../_shared/test-case-chain-readiness.md). This stage is unattended, so follow that file's unattended-caller rule: a target whose chain cannot be satisfied is reported `INCONCLUSIVE` with reason `prerequisites unmet` and is not run.
|
|
104
|
+
|
|
105
|
+
A target that runs without its prerequisite state spends its step budget re-creating that state — signing in, seeding data — and reports on what it lacked rather than on the change under test. That verdict reads as a product failure and is worth less than no verdict.
|
|
106
|
+
|
|
107
|
+
Ancestors generated here are prerequisites, not results: they belong in neither the Passed nor the Failed block of the report.
|
|
108
|
+
|
|
101
109
|
### Step 4: Run the dev loop, gather screenshots
|
|
102
110
|
|
|
103
111
|
For each relevant test case, run the shared loop in [`../_shared/dev-loop/run.md`](../_shared/dev-loop/run.md): `muggle-remote-test-script-list` by `testCaseId` with `runEnvironmentType: "local"` (this stage runs against localhost) to pick [replay vs regen](../_shared/dev-loop/run.md), [execute with `timeoutMs`](../_shared/dev-loop/timeouts.md), [fetch the result](../_shared/dev-loop/failures.md) and [interpret failures](../_shared/dev-loop/failures.md), then read the studio-published [cloud refs and per-step screenshots](../_shared/dev-loop/publish.md) off the run result.
|
|
@@ -134,7 +142,7 @@ For each test case:
|
|
|
134
142
|
- steps: `[{ stepIndex, action, screenshotUrl }, ...]`
|
|
135
143
|
- artifactsDir: `<path>` (for local debugging)
|
|
136
144
|
|
|
137
|
-
**Inconclusive:** (count) — use for runs that couldn't yield a pass/fail signal: no replayable script, environment precondition unmet, infra error, agent stalled on auth/cookie banner before reaching the assertion, missing secrets. The product is **not** implicated — that's `failed`, not `inconclusive`.
|
|
145
|
+
**Inconclusive:** (count) — use for runs that couldn't yield a pass/fail signal: no replayable script, environment precondition unmet, prerequisites unmet (Step 3.5), infra error, agent stalled on auth/cookie banner before reaching the assertion, missing secrets. The product is **not** implicated — that's `failed`, not `inconclusive`.
|
|
138
146
|
- (test case name):
|
|
139
147
|
- testCaseId: `<id>`
|
|
140
148
|
- runId: `<id>` (synthesize a UUID if no run started)
|
|
@@ -47,6 +47,8 @@ Map each bucket to exactly one disposition. Buckets are defined in [`../_shared/
|
|
|
47
47
|
|
|
48
48
|
A `repair` disposition requires a named defect: the failing step, expected-versus-actual, and the code path it implicates. Without one it is `ask`, whatever the bucket said.
|
|
49
49
|
|
|
50
|
+
An Inconclusive entry Stage 6 recorded as `prerequisites unmet` never executed. It carries no bucket and none may be derived from it — there is no run to read. Its disposition is `ask`, and the question names the missing prerequisite: what failed is the project's test-plan chain, not the diff.
|
|
51
|
+
|
|
50
52
|
## Step 3: Act
|
|
51
53
|
|
|
52
54
|
Process dispositions in order — `retry`, then `regenerate`, then `repair` — so cheap self-healing runs before any code change.
|
|
@@ -41,12 +41,12 @@ Reach for these when the user is weighing Muggle Test against hand-written specs
|
|
|
41
41
|
|
|
42
42
|
Every test case verifies exactly **one** user-observable behavior. Never bundle multiple concerns, sequential flows, or bootstrap/setup into a single test case — even if you think it would be "cleaner" or "more efficient."
|
|
43
43
|
|
|
44
|
-
**Ordering
|
|
44
|
+
**Ordering and dependencies belong to the test-plan graph, not to the test case body.** The backend records which case depends on which; the run path reads that chain and runs the prerequisites first ([`_shared/test-case-chain-readiness.md`](../_shared/test-case-chain-readiness.md)). Your job is to describe the *atomic behavior to verify* — never the flow that gets there.
|
|
45
45
|
|
|
46
46
|
- ❌ Wrong: one test case that "signs up, logs in, navigates to the detail modal, verifies icon stacking, verifies tab order, verifies history format, and verifies reference layout."
|
|
47
47
|
- ✅ Right: four separate test cases — one per verifiable behavior — each with instruction text like "Verify the detail modal shows stacked pair of icons per card" with **no** signup / login / navigation / setup language.
|
|
48
48
|
|
|
49
|
-
**Never bake bootstrap into a test case description.** Signup, login, seed data, prerequisite navigation, tear-down — none of these belong inside the test case body. Write only the verification itself.
|
|
49
|
+
**Never bake bootstrap into a test case description.** Signup, login, seed data, prerequisite navigation, tear-down — none of these belong inside the test case body. Write only the verification itself. Setup arrives as its own prerequisite case: the chain runs ahead of the target, and the session it leaves behind is what the target starts from. Nothing is spliced into the case body.
|
|
50
50
|
|
|
51
51
|
**Never consolidate the generator's output.** When `muggle-remote-test-case-generate-from-prompt` returns N micro-tests from a single prompt, that decomposition is the authoritative one. Do not "merge them into 1 for simplicity," do not "rewrite them to share bootstrap," do not "collapse them to match a 4 UC / 4 TC plan." Accept what the generator gave you.
|
|
52
52
|
|
|
@@ -30,6 +30,10 @@ Gate `showElectronBrowser` (per `preference-gates/README.md`). Resolve once; app
|
|
|
30
30
|
- `never` → pass `showUi: false`.
|
|
31
31
|
- `ask` → run Picker 1 from `preference-gates/showElectronBrowser.md` via `AskUserQuestion`; map the answer back to one of the actions above.
|
|
32
32
|
|
|
33
|
+
## Prerequisite chain
|
|
34
|
+
|
|
35
|
+
Before the first run, resolve each selected test case's prerequisite chain and make every ancestor ready, per [`../_shared/test-case-chain-readiness.md`](../_shared/test-case-chain-readiness.md). Ancestors are generated, never replayed, root-first; the session an ancestor leaves behind is what the target starts from, so ordering here is what makes `freshSession: false` mean anything below.
|
|
36
|
+
|
|
33
37
|
## Run the dev loop
|
|
34
38
|
|
|
35
39
|
Execute each test case via the shared loop in [`../_shared/dev-loop/run.md`](../_shared/dev-loop/run.md): [sequential replay/regen](../_shared/dev-loop/run.md), [`actionScript` as-is](../_shared/dev-loop/action-script.md), [`freshSession`](../_shared/dev-loop/fresh-session.md), and [`timeoutMs`](../_shared/dev-loop/timeouts.md).
|