@instawp/cli 0.0.1-beta.1
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 +129 -0
- package/dist/commands/exec.d.ts +3 -0
- package/dist/commands/exec.js +126 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +63 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/sites.d.ts +3 -0
- package/dist/commands/sites.js +343 -0
- package/dist/commands/sites.js.map +1 -0
- package/dist/commands/ssh.d.ts +2 -0
- package/dist/commands/ssh.js +41 -0
- package/dist/commands/ssh.js.map +1 -0
- package/dist/commands/sync.d.ts +2 -0
- package/dist/commands/sync.js +131 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/teams.d.ts +2 -0
- package/dist/commands/teams.js +122 -0
- package/dist/commands/teams.js.map +1 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.js +60 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +101 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +4 -0
- package/dist/lib/api.js +45 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/auth.d.ts +1 -0
- package/dist/lib/auth.js +75 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/config.d.ts +11 -0
- package/dist/lib/config.js +66 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/output.d.ts +14 -0
- package/dist/lib/output.js +63 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/site-resolver.d.ts +2 -0
- package/dist/lib/site-resolver.js +78 -0
- package/dist/lib/site-resolver.js.map +1 -0
- package/dist/lib/ssh-connection.d.ts +8 -0
- package/dist/lib/ssh-connection.js +70 -0
- package/dist/lib/ssh-connection.js.map +1 -0
- package/dist/lib/ssh-keys.d.ts +2 -0
- package/dist/lib/ssh-keys.js +232 -0
- package/dist/lib/ssh-keys.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 InstaWP
|
|
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
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# InstaWP CLI
|
|
2
|
+
|
|
3
|
+
Create and manage WordPress sites from the terminal.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
npm install -g @instawp/cli
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
> **Beta** - This is an early release. Report issues at [github.com/InstaWP/cli/issues](https://github.com/InstaWP/cli/issues).
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Authenticate (opens browser)
|
|
15
|
+
instawp login
|
|
16
|
+
|
|
17
|
+
# Or use an API token (for CI/CD)
|
|
18
|
+
instawp login --token <your-api-token>
|
|
19
|
+
|
|
20
|
+
# Check your session
|
|
21
|
+
instawp whoami
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Commands
|
|
25
|
+
|
|
26
|
+
### Sites
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# List all sites
|
|
30
|
+
instawp sites list
|
|
31
|
+
|
|
32
|
+
# Create a new site (waits for provisioning by default)
|
|
33
|
+
instawp create --name my-site
|
|
34
|
+
instawp create --name my-site --php 8.3
|
|
35
|
+
|
|
36
|
+
# Delete a site
|
|
37
|
+
instawp sites delete <site>
|
|
38
|
+
instawp sites delete <site> --force
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Run Commands
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Run any command on a site (via SSH, default)
|
|
45
|
+
instawp exec <site> ls -la
|
|
46
|
+
instawp exec <site> php -v
|
|
47
|
+
instawp exec <site> cat wp-config.php
|
|
48
|
+
|
|
49
|
+
# Run via API instead of SSH (no SSH setup needed)
|
|
50
|
+
instawp exec <site> ls -la --api
|
|
51
|
+
|
|
52
|
+
# WP-CLI shorthand (prepends `wp` automatically)
|
|
53
|
+
instawp wp <site> plugin list
|
|
54
|
+
instawp wp <site> option get siteurl
|
|
55
|
+
instawp wp <site> user list --api
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`<site>` can be a site **ID**, **name**, or **domain** — the CLI resolves it automatically.
|
|
59
|
+
|
|
60
|
+
### SSH
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Open an interactive SSH session
|
|
64
|
+
instawp ssh <site>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The CLI manages SSH keys automatically — it generates a key, uploads it, and caches the connection.
|
|
68
|
+
|
|
69
|
+
### Sync (rsync)
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Push local wp-content to remote
|
|
73
|
+
instawp sync push <site> --path ./wp-content/
|
|
74
|
+
|
|
75
|
+
# Pull remote wp-content to local
|
|
76
|
+
instawp sync pull <site>
|
|
77
|
+
|
|
78
|
+
# Dry run first
|
|
79
|
+
instawp sync push <site> --dry-run
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Teams
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
instawp teams list
|
|
86
|
+
instawp teams members <team>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## JSON Output
|
|
90
|
+
|
|
91
|
+
Add `--json` to any command for machine-readable output:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
instawp sites list --json
|
|
95
|
+
instawp create --name test-site --json
|
|
96
|
+
instawp exec <site> wp option get siteurl --json
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Environment Variables
|
|
100
|
+
|
|
101
|
+
| Variable | Description |
|
|
102
|
+
|----------|-------------|
|
|
103
|
+
| `INSTAWP_TOKEN` | API token — skips `instawp login` |
|
|
104
|
+
| `INSTAWP_API_URL` | Custom API base URL |
|
|
105
|
+
|
|
106
|
+
### CI/CD Example
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
export INSTAWP_TOKEN=${{ secrets.INSTAWP_TOKEN }}
|
|
110
|
+
|
|
111
|
+
# Create a preview site for a PR
|
|
112
|
+
instawp create --name "pr-$PR_NUMBER" --json
|
|
113
|
+
|
|
114
|
+
# Run a smoke test
|
|
115
|
+
instawp wp "pr-$PR_NUMBER" option get siteurl
|
|
116
|
+
|
|
117
|
+
# Clean up
|
|
118
|
+
instawp sites delete "pr-$PR_NUMBER" --force
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Requirements
|
|
122
|
+
|
|
123
|
+
- Node.js 18+
|
|
124
|
+
- `ssh` and `ssh-keygen` (for SSH/exec commands)
|
|
125
|
+
- `rsync` (for sync commands)
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
MIT
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { requireAuth, getClient } from '../lib/api.js';
|
|
2
|
+
import { resolveSite } from '../lib/site-resolver.js';
|
|
3
|
+
import { ensureSshAccess } from '../lib/ssh-keys.js';
|
|
4
|
+
import { execViaSsh } from '../lib/ssh-connection.js';
|
|
5
|
+
import { error, spinner, isJsonMode } from '../lib/output.js';
|
|
6
|
+
async function execAction(siteIdentifier, args, opts) {
|
|
7
|
+
requireAuth();
|
|
8
|
+
if (args.length === 0) {
|
|
9
|
+
error('No command specified. Usage: instawp exec <site> <command...>');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
const spin = spinner('Resolving site...');
|
|
13
|
+
spin.start();
|
|
14
|
+
let site;
|
|
15
|
+
try {
|
|
16
|
+
site = await resolveSite(siteIdentifier);
|
|
17
|
+
spin.stop();
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
spin.fail('Site resolution failed');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
const command = args.join(' ');
|
|
24
|
+
if (opts.api) {
|
|
25
|
+
await execViaApi(site, command, opts);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
await execViaSshTransport(site, command);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function execViaApi(site, command, opts) {
|
|
32
|
+
const spin2 = spinner(`Running: ${command}`);
|
|
33
|
+
spin2.start();
|
|
34
|
+
try {
|
|
35
|
+
const client = getClient();
|
|
36
|
+
const res = await client.post(`/sites/${site.id}/run-cmd`, {
|
|
37
|
+
commands: [command],
|
|
38
|
+
timeout_seconds: parseInt(opts.timeout || '30'),
|
|
39
|
+
});
|
|
40
|
+
spin2.stop();
|
|
41
|
+
const data = res.data?.data;
|
|
42
|
+
if (isJsonMode()) {
|
|
43
|
+
console.log(JSON.stringify({ success: true, data }));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const stripEcho = (s) => {
|
|
47
|
+
const lines = s.split('\n');
|
|
48
|
+
if (lines[0] && /^\d{4}-\d{2}-\d{2}\s/.test(lines[0])) {
|
|
49
|
+
return lines.slice(1).join('\n').trim();
|
|
50
|
+
}
|
|
51
|
+
return s.trim();
|
|
52
|
+
};
|
|
53
|
+
if (Array.isArray(data)) {
|
|
54
|
+
for (const result of data) {
|
|
55
|
+
const output = result.output || result;
|
|
56
|
+
console.log(typeof output === 'string' ? stripEcho(output) : JSON.stringify(output));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (typeof data === 'string') {
|
|
60
|
+
console.log(stripEcho(data));
|
|
61
|
+
}
|
|
62
|
+
else if (data?.output) {
|
|
63
|
+
console.log(typeof data.output === 'string' ? stripEcho(data.output) : JSON.stringify(data.output));
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.log(JSON.stringify(data, null, 2));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
spin2.fail('Command failed');
|
|
72
|
+
error('Failed to run command', err.response?.data?.message || err.message);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function execViaSshTransport(site, command) {
|
|
77
|
+
const conn = await ensureSshAccess(site.id);
|
|
78
|
+
// Auto-cd into WordPress root so wp-cli and other tools work out of the box
|
|
79
|
+
const wpRoot = conn.domain
|
|
80
|
+
? `/home/${conn.username}/web/${conn.domain}/public_html`
|
|
81
|
+
: '';
|
|
82
|
+
const fullCmd = wpRoot ? `cd ${wpRoot} && ${command}` : command;
|
|
83
|
+
const result = execViaSsh(conn, fullCmd);
|
|
84
|
+
if (isJsonMode()) {
|
|
85
|
+
console.log(JSON.stringify({
|
|
86
|
+
success: result.exitCode === 0,
|
|
87
|
+
data: {
|
|
88
|
+
stdout: result.stdout,
|
|
89
|
+
stderr: result.stderr,
|
|
90
|
+
exit_code: result.exitCode,
|
|
91
|
+
},
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
if (result.stdout)
|
|
96
|
+
process.stdout.write(result.stdout);
|
|
97
|
+
if (result.stderr)
|
|
98
|
+
process.stderr.write(result.stderr);
|
|
99
|
+
}
|
|
100
|
+
process.exit(result.exitCode);
|
|
101
|
+
}
|
|
102
|
+
export function registerExecCommand(program) {
|
|
103
|
+
program
|
|
104
|
+
.command('exec <site> [args...]')
|
|
105
|
+
.description('Run a command on a remote site (SSH by default, or --api)')
|
|
106
|
+
.passThroughOptions()
|
|
107
|
+
.allowUnknownOption()
|
|
108
|
+
.option('--api', 'Use API transport instead of SSH')
|
|
109
|
+
.option('--timeout <seconds>', 'Command timeout in seconds (API mode only)', '30')
|
|
110
|
+
.action(async (siteIdentifier, args, opts) => {
|
|
111
|
+
await execAction(siteIdentifier, args, opts);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
export function registerWpCommand(program) {
|
|
115
|
+
program
|
|
116
|
+
.command('wp <site> [args...]')
|
|
117
|
+
.description('Run WP-CLI commands on a remote site (shorthand for exec <site> wp ...)')
|
|
118
|
+
.passThroughOptions()
|
|
119
|
+
.allowUnknownOption()
|
|
120
|
+
.option('--api', 'Use API transport instead of SSH')
|
|
121
|
+
.option('--timeout <seconds>', 'Command timeout in seconds (API mode only)', '30')
|
|
122
|
+
.action(async (siteIdentifier, args, opts) => {
|
|
123
|
+
await execAction(siteIdentifier, ['wp', ...args], opts);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/commands/exec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { startOAuthFlow } from '../lib/auth.js';
|
|
2
|
+
import { setToken, setApiUrl, getApiUrl } from '../lib/config.js';
|
|
3
|
+
import { getClient, resetClient } from '../lib/api.js';
|
|
4
|
+
import { success, error, spinner, info } from '../lib/output.js';
|
|
5
|
+
export function registerLoginCommand(program) {
|
|
6
|
+
program
|
|
7
|
+
.command('login')
|
|
8
|
+
.description('Authenticate with InstaWP')
|
|
9
|
+
.option('--token <token>', 'API token (skip browser login)')
|
|
10
|
+
.option('--api-url <url>', 'API base URL')
|
|
11
|
+
.action(async (opts) => {
|
|
12
|
+
try {
|
|
13
|
+
if (opts.apiUrl) {
|
|
14
|
+
setApiUrl(opts.apiUrl);
|
|
15
|
+
resetClient();
|
|
16
|
+
}
|
|
17
|
+
let token;
|
|
18
|
+
if (opts.token) {
|
|
19
|
+
token = opts.token;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
info(`Opening browser for authentication at ${getApiUrl()}...`);
|
|
23
|
+
const spin = spinner('Waiting for browser authentication...');
|
|
24
|
+
spin.start();
|
|
25
|
+
try {
|
|
26
|
+
token = await startOAuthFlow();
|
|
27
|
+
spin.succeed('Browser authentication successful');
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
spin.fail('Browser authentication failed');
|
|
31
|
+
error(err.message);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
setToken(token);
|
|
36
|
+
resetClient();
|
|
37
|
+
// Validate token
|
|
38
|
+
const spin2 = spinner('Validating token...');
|
|
39
|
+
spin2.start();
|
|
40
|
+
try {
|
|
41
|
+
const client = getClient();
|
|
42
|
+
const res = await client.get('/sites', { params: { per_page: 1 } });
|
|
43
|
+
spin2.succeed('Token validated');
|
|
44
|
+
// Try to extract user info from response if available
|
|
45
|
+
// The sites endpoint may return user info in the meta/auth context
|
|
46
|
+
// If not, we at least know the token is valid
|
|
47
|
+
success('Logged in successfully', {
|
|
48
|
+
api_url: getApiUrl(),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
spin2.fail('Token validation failed');
|
|
53
|
+
error('Invalid token. Please check and try again.');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
error('Login failed', err.message);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAW,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEjE,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,2BAA2B,CAAC;SACxC,MAAM,CAAC,iBAAiB,EAAE,gCAAgC,CAAC;SAC3D,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACvB,WAAW,EAAE,CAAC;YAChB,CAAC;YAED,IAAI,KAAa,CAAC;YAElB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,yCAAyC,SAAS,EAAE,KAAK,CAAC,CAAC;gBAChE,MAAM,IAAI,GAAG,OAAO,CAAC,uCAAuC,CAAC,CAAC;gBAC9D,IAAI,CAAC,KAAK,EAAE,CAAC;gBACb,IAAI,CAAC;oBACH,KAAK,GAAG,MAAM,cAAc,EAAE,CAAC;oBAC/B,IAAI,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;gBACpD,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,IAAI,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;oBAC3C,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;YACH,CAAC;YAED,QAAQ,CAAC,KAAK,CAAC,CAAC;YAChB,WAAW,EAAE,CAAC;YAEd,iBAAiB;YACjB,MAAM,KAAK,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;YAC7C,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBACpE,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;gBAEjC,sDAAsD;gBACtD,mEAAmE;gBACnE,8CAA8C;gBAC9C,OAAO,CAAC,wBAAwB,EAAE;oBAChC,OAAO,EAAE,SAAS,EAAE;iBACrB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;gBACtC,KAAK,CAAC,4CAA4C,CAAC,CAAC;gBACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|