@awcp/transport-sshfs 0.0.0-dev-202601300724 → 0.0.0-dev-202601301521
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/cli/setup.d.ts +13 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +286 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/delegator/credential-manager.d.ts +15 -52
- package/dist/delegator/credential-manager.d.ts.map +1 -1
- package/dist/delegator/credential-manager.js +82 -106
- package/dist/delegator/credential-manager.js.map +1 -1
- package/dist/delegator/index.d.ts +1 -1
- package/dist/delegator/index.d.ts.map +1 -1
- package/dist/delegator/index.js.map +1 -1
- package/dist/executor/index.d.ts +1 -1
- package/dist/executor/index.d.ts.map +1 -1
- package/dist/executor/index.js +1 -1
- package/dist/executor/index.js.map +1 -1
- package/dist/executor/sshfs-client.d.ts +20 -23
- package/dist/executor/sshfs-client.d.ts.map +1 -1
- package/dist/executor/sshfs-client.js +60 -32
- package/dist/executor/sshfs-client.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/sshfs-transport.d.ts +24 -0
- package/dist/sshfs-transport.d.ts.map +1 -0
- package/dist/sshfs-transport.js +93 -0
- package/dist/sshfs-transport.js.map +1 -0
- package/dist/types.d.ts +114 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +6 -2
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AWCP SSHFS Transport Setup CLI
|
|
4
|
+
*
|
|
5
|
+
* Configures SSH certificate authentication for AWCP.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx @awcp/transport-sshfs setup # Check and guide
|
|
9
|
+
* npx @awcp/transport-sshfs setup --auto # Auto-configure (needs sudo)
|
|
10
|
+
* npx @awcp/transport-sshfs setup --check # Check only
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AWCP SSHFS Transport Setup CLI
|
|
4
|
+
*
|
|
5
|
+
* Configures SSH certificate authentication for AWCP.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx @awcp/transport-sshfs setup # Check and guide
|
|
9
|
+
* npx @awcp/transport-sshfs setup --auto # Auto-configure (needs sudo)
|
|
10
|
+
* npx @awcp/transport-sshfs setup --check # Check only
|
|
11
|
+
*/
|
|
12
|
+
import { spawn, execSync } from 'node:child_process';
|
|
13
|
+
import { access, mkdir, readFile, constants } from 'node:fs/promises';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import { homedir, platform } from 'node:os';
|
|
16
|
+
import * as net from 'node:net';
|
|
17
|
+
const CA_KEY_PATH = join(homedir(), '.awcp', 'ca');
|
|
18
|
+
const SSHD_CONFIG_PATH = '/etc/ssh/sshd_config';
|
|
19
|
+
/**
|
|
20
|
+
* Print colored output
|
|
21
|
+
*/
|
|
22
|
+
function print(message) {
|
|
23
|
+
console.log(message);
|
|
24
|
+
}
|
|
25
|
+
function printStatus(name, status, message) {
|
|
26
|
+
const icon = status === 'ok' ? '✓' : status === 'missing' ? '✗' : '!';
|
|
27
|
+
const color = status === 'ok' ? '\x1b[32m' : status === 'missing' ? '\x1b[31m' : '\x1b[33m';
|
|
28
|
+
console.log(` ${color}[${icon}]\x1b[0m ${name.padEnd(20)} ${message}`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if a command exists
|
|
32
|
+
*/
|
|
33
|
+
async function commandExists(cmd) {
|
|
34
|
+
try {
|
|
35
|
+
execSync(`which ${cmd}`, { stdio: 'ignore' });
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Check if sshd is running
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* Check if sshd is running by trying to connect to port 22
|
|
47
|
+
*/
|
|
48
|
+
async function isSshdRunning() {
|
|
49
|
+
return new Promise((resolve) => {
|
|
50
|
+
const socket = new net.Socket();
|
|
51
|
+
socket.setTimeout(2000);
|
|
52
|
+
socket.on('connect', () => {
|
|
53
|
+
socket.destroy();
|
|
54
|
+
resolve(true);
|
|
55
|
+
});
|
|
56
|
+
socket.on('timeout', () => {
|
|
57
|
+
socket.destroy();
|
|
58
|
+
resolve(false);
|
|
59
|
+
});
|
|
60
|
+
socket.on('error', () => {
|
|
61
|
+
resolve(false);
|
|
62
|
+
});
|
|
63
|
+
socket.connect(22, 'localhost');
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check if sshd_config has TrustedUserCAKeys configured
|
|
68
|
+
*/
|
|
69
|
+
async function isSshdConfigured() {
|
|
70
|
+
try {
|
|
71
|
+
const content = await readFile(SSHD_CONFIG_PATH, 'utf-8');
|
|
72
|
+
const caKeyPub = `${CA_KEY_PATH}.pub`;
|
|
73
|
+
return content.includes(`TrustedUserCAKeys`) && content.includes(caKeyPub);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if CA key exists
|
|
81
|
+
*/
|
|
82
|
+
async function caKeyExists() {
|
|
83
|
+
try {
|
|
84
|
+
await access(CA_KEY_PATH, constants.R_OK);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Generate CA key pair
|
|
93
|
+
*/
|
|
94
|
+
async function generateCaKey() {
|
|
95
|
+
const caDir = join(CA_KEY_PATH, '..');
|
|
96
|
+
await mkdir(caDir, { recursive: true, mode: 0o700 });
|
|
97
|
+
return new Promise((resolve, reject) => {
|
|
98
|
+
const proc = spawn('ssh-keygen', [
|
|
99
|
+
'-t', 'ed25519',
|
|
100
|
+
'-f', CA_KEY_PATH,
|
|
101
|
+
'-N', '',
|
|
102
|
+
'-C', 'awcp-ca',
|
|
103
|
+
], { stdio: 'inherit' });
|
|
104
|
+
proc.on('close', (code) => {
|
|
105
|
+
if (code === 0)
|
|
106
|
+
resolve();
|
|
107
|
+
else
|
|
108
|
+
reject(new Error(`ssh-keygen failed with code ${code}`));
|
|
109
|
+
});
|
|
110
|
+
proc.on('error', reject);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Configure sshd (requires sudo)
|
|
115
|
+
*/
|
|
116
|
+
async function configureSshd() {
|
|
117
|
+
const caKeyPub = `${CA_KEY_PATH}.pub`;
|
|
118
|
+
print('\n Configuring sshd (requires sudo)...');
|
|
119
|
+
// Add TrustedUserCAKeys to sshd_config
|
|
120
|
+
execSync(`echo "TrustedUserCAKeys ${caKeyPub}" | sudo tee -a ${SSHD_CONFIG_PATH}`, {
|
|
121
|
+
stdio: 'inherit',
|
|
122
|
+
});
|
|
123
|
+
// Restart sshd
|
|
124
|
+
if (platform() === 'darwin') {
|
|
125
|
+
execSync('sudo launchctl stop com.openssh.sshd', { stdio: 'inherit' });
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
execSync('sudo systemctl restart sshd || sudo systemctl restart ssh', { stdio: 'inherit' });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Run all checks
|
|
133
|
+
*/
|
|
134
|
+
async function runChecks() {
|
|
135
|
+
const results = [];
|
|
136
|
+
// Check ssh-keygen
|
|
137
|
+
const hasSshKeygen = await commandExists('ssh-keygen');
|
|
138
|
+
results.push({
|
|
139
|
+
name: 'ssh-keygen',
|
|
140
|
+
status: hasSshKeygen ? 'ok' : 'missing',
|
|
141
|
+
message: hasSshKeygen ? 'found' : 'not found',
|
|
142
|
+
hint: 'Install OpenSSH client',
|
|
143
|
+
});
|
|
144
|
+
// Check sshfs
|
|
145
|
+
const hasSshfs = await commandExists('sshfs');
|
|
146
|
+
results.push({
|
|
147
|
+
name: 'sshfs',
|
|
148
|
+
status: hasSshfs ? 'ok' : 'missing',
|
|
149
|
+
message: hasSshfs ? 'found' : 'not found',
|
|
150
|
+
hint: platform() === 'darwin'
|
|
151
|
+
? 'Install: brew install macfuse && brew install sshfs'
|
|
152
|
+
: 'Install: sudo apt install sshfs',
|
|
153
|
+
});
|
|
154
|
+
// Check sshd
|
|
155
|
+
const sshdRunning = await isSshdRunning();
|
|
156
|
+
results.push({
|
|
157
|
+
name: 'sshd',
|
|
158
|
+
status: sshdRunning ? 'ok' : 'missing',
|
|
159
|
+
message: sshdRunning ? 'running' : 'not running',
|
|
160
|
+
hint: platform() === 'darwin'
|
|
161
|
+
? 'Enable: System Settings → General → Sharing → Remote Login'
|
|
162
|
+
: 'Install & start: sudo apt install openssh-server && sudo systemctl start sshd',
|
|
163
|
+
});
|
|
164
|
+
// Check CA key
|
|
165
|
+
const hasCaKey = await caKeyExists();
|
|
166
|
+
results.push({
|
|
167
|
+
name: 'CA key',
|
|
168
|
+
status: hasCaKey ? 'ok' : 'missing',
|
|
169
|
+
message: hasCaKey ? `exists at ${CA_KEY_PATH}` : 'not found',
|
|
170
|
+
hint: 'Will be auto-generated',
|
|
171
|
+
});
|
|
172
|
+
// Check sshd config (only if CA key exists)
|
|
173
|
+
if (hasCaKey) {
|
|
174
|
+
const sshdConfigured = await isSshdConfigured();
|
|
175
|
+
results.push({
|
|
176
|
+
name: 'sshd TrustedUserCAKeys',
|
|
177
|
+
status: sshdConfigured ? 'ok' : 'missing',
|
|
178
|
+
message: sshdConfigured ? 'configured' : 'not configured',
|
|
179
|
+
hint: `Add to ${SSHD_CONFIG_PATH}: TrustedUserCAKeys ${CA_KEY_PATH}.pub`,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
return results;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Print setup instructions
|
|
186
|
+
*/
|
|
187
|
+
function printInstructions(results) {
|
|
188
|
+
const missing = results.filter(r => r.status === 'missing');
|
|
189
|
+
if (missing.length === 0) {
|
|
190
|
+
print('\n \x1b[32m✓ All checks passed! AWCP is ready to use.\x1b[0m\n');
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
print('\n \x1b[33mSetup required:\x1b[0m\n');
|
|
194
|
+
for (const result of missing) {
|
|
195
|
+
if (result.hint) {
|
|
196
|
+
print(` • ${result.name}: ${result.hint}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Print auto command hint
|
|
200
|
+
const needsSshdConfig = missing.some(r => r.name === 'sshd TrustedUserCAKeys');
|
|
201
|
+
const needsCaKey = missing.some(r => r.name === 'CA key');
|
|
202
|
+
if (needsCaKey || needsSshdConfig) {
|
|
203
|
+
print('\n Or run with --auto to configure automatically:');
|
|
204
|
+
print(' npx @awcp/transport-sshfs setup --auto\n');
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Main setup function
|
|
209
|
+
*/
|
|
210
|
+
async function setup(options) {
|
|
211
|
+
print('');
|
|
212
|
+
print('╔════════════════════════════════════════════════════════════╗');
|
|
213
|
+
print('║ AWCP SSHFS Transport Setup ║');
|
|
214
|
+
print('╚════════════════════════════════════════════════════════════╝');
|
|
215
|
+
print('');
|
|
216
|
+
print(' Checking dependencies...');
|
|
217
|
+
print('');
|
|
218
|
+
const results = await runChecks();
|
|
219
|
+
for (const result of results) {
|
|
220
|
+
printStatus(result.name, result.status, result.message);
|
|
221
|
+
}
|
|
222
|
+
if (options.check) {
|
|
223
|
+
const allOk = results.every(r => r.status === 'ok');
|
|
224
|
+
process.exit(allOk ? 0 : 1);
|
|
225
|
+
}
|
|
226
|
+
if (options.auto) {
|
|
227
|
+
// Auto-configure
|
|
228
|
+
const needsCaKey = results.some(r => r.name === 'CA key' && r.status === 'missing');
|
|
229
|
+
const needsSshdConfig = results.some(r => r.name === 'sshd TrustedUserCAKeys' && r.status === 'missing');
|
|
230
|
+
if (needsCaKey) {
|
|
231
|
+
print('\n Generating CA key pair...');
|
|
232
|
+
await generateCaKey();
|
|
233
|
+
printStatus('CA key', 'ok', `generated at ${CA_KEY_PATH}`);
|
|
234
|
+
}
|
|
235
|
+
if (needsSshdConfig || needsCaKey) {
|
|
236
|
+
// Re-check if sshd config is needed after CA key generation
|
|
237
|
+
const sshdConfigured = await isSshdConfigured();
|
|
238
|
+
if (!sshdConfigured) {
|
|
239
|
+
await configureSshd();
|
|
240
|
+
printStatus('sshd TrustedUserCAKeys', 'ok', 'configured');
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
print('\n \x1b[32m✓ Setup complete! AWCP is ready to use.\x1b[0m\n');
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
printInstructions(results);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Parse CLI arguments and run
|
|
251
|
+
*/
|
|
252
|
+
async function main() {
|
|
253
|
+
const args = process.argv.slice(2);
|
|
254
|
+
// Handle help
|
|
255
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
256
|
+
print(`
|
|
257
|
+
AWCP SSHFS Transport Setup
|
|
258
|
+
|
|
259
|
+
Usage:
|
|
260
|
+
npx @awcp/transport-sshfs setup [options]
|
|
261
|
+
|
|
262
|
+
Options:
|
|
263
|
+
--auto Auto-configure everything (requires sudo for sshd config)
|
|
264
|
+
--check Check only, don't print setup instructions
|
|
265
|
+
--help Show this help message
|
|
266
|
+
|
|
267
|
+
Examples:
|
|
268
|
+
npx @awcp/transport-sshfs setup # Check and show instructions
|
|
269
|
+
npx @awcp/transport-sshfs setup --auto # Auto-configure
|
|
270
|
+
`);
|
|
271
|
+
process.exit(0);
|
|
272
|
+
}
|
|
273
|
+
const options = {
|
|
274
|
+
auto: args.includes('--auto'),
|
|
275
|
+
check: args.includes('--check'),
|
|
276
|
+
};
|
|
277
|
+
try {
|
|
278
|
+
await setup(options);
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
console.error('\n \x1b[31mError:\x1b[0m', error instanceof Error ? error.message : error);
|
|
282
|
+
process.exit(1);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
main();
|
|
286
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,53 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
export interface CredentialManagerConfig {
|
|
5
|
-
/** Directory to store temporary keys (default: ~/.awcp/keys) */
|
|
6
|
-
keyDir?: string;
|
|
7
|
-
/** SSH server port (default: 22) */
|
|
8
|
-
sshPort?: number;
|
|
9
|
-
/** SSH server host (default: localhost) */
|
|
10
|
-
sshHost?: string;
|
|
11
|
-
/** SSH user for connections */
|
|
12
|
-
sshUser?: string;
|
|
13
|
-
/** Path to authorized_keys file (default: ~/.ssh/authorized_keys) */
|
|
14
|
-
authorizedKeysPath?: string;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Generated credential
|
|
18
|
-
*/
|
|
19
|
-
export interface GeneratedCredential {
|
|
20
|
-
/** The private key content */
|
|
21
|
-
privateKey: string;
|
|
22
|
-
/** The public key content */
|
|
23
|
-
publicKey: string;
|
|
24
|
-
/** Path to the private key file */
|
|
25
|
-
privateKeyPath: string;
|
|
26
|
-
/** Path to the public key file */
|
|
27
|
-
publicKeyPath: string;
|
|
28
|
-
/** Delegation ID for tracking */
|
|
29
|
-
delegationId: string;
|
|
30
|
-
}
|
|
1
|
+
import type { SshCredential } from '@awcp/core';
|
|
2
|
+
import type { CredentialManagerConfig, GeneratedCredential } from '../types.js';
|
|
31
3
|
/**
|
|
32
4
|
* SSH Credential Manager
|
|
33
5
|
*
|
|
34
|
-
* Manages temporary SSH
|
|
35
|
-
*
|
|
36
|
-
* TODO [Security]: Consider SSH certificates with built-in expiry for production.
|
|
6
|
+
* Manages temporary SSH certificates for AWCP delegations.
|
|
7
|
+
* Uses SSH certificates with built-in expiry for automatic TTL enforcement.
|
|
37
8
|
*/
|
|
38
9
|
export declare class CredentialManager {
|
|
39
10
|
private config;
|
|
40
11
|
private activeCredentials;
|
|
41
|
-
constructor(config
|
|
12
|
+
constructor(config: CredentialManagerConfig);
|
|
42
13
|
/**
|
|
43
|
-
*
|
|
14
|
+
* Generate a temporary SSH key pair and sign certificate with TTL
|
|
44
15
|
*/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
* Generate a temporary SSH key pair for a delegation
|
|
48
|
-
*/
|
|
49
|
-
generateCredential(delegationId: string, _ttlSeconds: number): Promise<{
|
|
50
|
-
credential: string;
|
|
16
|
+
generateCredential(delegationId: string, ttlSeconds: number): Promise<{
|
|
17
|
+
credential: SshCredential;
|
|
51
18
|
endpoint: {
|
|
52
19
|
host: string;
|
|
53
20
|
port: number;
|
|
@@ -55,7 +22,11 @@ export declare class CredentialManager {
|
|
|
55
22
|
};
|
|
56
23
|
}>;
|
|
57
24
|
/**
|
|
58
|
-
*
|
|
25
|
+
* Ensure CA key exists, auto-generate if not present
|
|
26
|
+
*/
|
|
27
|
+
private ensureCaKey;
|
|
28
|
+
/**
|
|
29
|
+
* Revoke a credential (delete key files, certificate expires automatically)
|
|
59
30
|
*/
|
|
60
31
|
revokeCredential(delegationId: string): Promise<void>;
|
|
61
32
|
/**
|
|
@@ -66,22 +37,14 @@ export declare class CredentialManager {
|
|
|
66
37
|
* Revoke all credentials
|
|
67
38
|
*/
|
|
68
39
|
revokeAll(): Promise<void>;
|
|
69
|
-
/**
|
|
70
|
-
* Clean up stale AWCP keys from authorized_keys (call on startup)
|
|
71
|
-
*/
|
|
72
|
-
cleanupStaleKeys(): Promise<number>;
|
|
73
40
|
/**
|
|
74
41
|
* Clean up stale key files from key directory (call on startup)
|
|
75
42
|
*/
|
|
76
43
|
cleanupStaleKeyFiles(): Promise<number>;
|
|
77
44
|
/**
|
|
78
|
-
*
|
|
79
|
-
*/
|
|
80
|
-
private addToAuthorizedKeys;
|
|
81
|
-
/**
|
|
82
|
-
* Remove a public key from authorized_keys by delegation ID
|
|
45
|
+
* Sign public key with CA to create certificate with TTL
|
|
83
46
|
*/
|
|
84
|
-
private
|
|
47
|
+
private signCertificate;
|
|
85
48
|
/**
|
|
86
49
|
* Execute ssh-keygen to generate a key pair
|
|
87
50
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-manager.d.ts","sourceRoot":"","sources":["../../src/delegator/credential-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"credential-manager.d.ts","sourceRoot":"","sources":["../../src/delegator/credential-manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAIhF;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,iBAAiB,CAA0C;gBAEvD,MAAM,EAAE,uBAAuB;IAI3C;;OAEG;IACG,kBAAkB,CACtB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;QACT,UAAU,EAAE,aAAa,CAAC;QAC1B,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;KACxD,CAAC;IA4CF;;OAEG;YACW,WAAW;IA0BzB;;OAEG;IACG,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3D;;OAEG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAIpE;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAMhC;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IA8B7C;;OAEG;IACH,OAAO,CAAC,eAAe;IAgCvB;;OAEG;IACH,OAAO,CAAC,aAAa;CAyBtB"}
|