@vibe-agent-toolkit/utils 0.1.0-rc.10
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/README.md +34 -0
- package/dist/file-crawler.d.ts +54 -0
- package/dist/file-crawler.d.ts.map +1 -0
- package/dist/file-crawler.js +177 -0
- package/dist/file-crawler.js.map +1 -0
- package/dist/fs-utils.d.ts +14 -0
- package/dist/fs-utils.d.ts.map +1 -0
- package/dist/fs-utils.js +31 -0
- package/dist/fs-utils.js.map +1 -0
- package/dist/git-utils.d.ts +11 -0
- package/dist/git-utils.d.ts.map +1 -0
- package/dist/git-utils.js +30 -0
- package/dist/git-utils.js.map +1 -0
- package/dist/gitignore-checker.d.ts +30 -0
- package/dist/gitignore-checker.d.ts.map +1 -0
- package/dist/gitignore-checker.js +95 -0
- package/dist/gitignore-checker.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/path-utils.d.ts +87 -0
- package/dist/path-utils.d.ts.map +1 -0
- package/dist/path-utils.js +112 -0
- package/dist/path-utils.js.map +1 -0
- package/dist/safe-exec.d.ts +206 -0
- package/dist/safe-exec.d.ts.map +1 -0
- package/dist/safe-exec.js +393 -0
- package/dist/safe-exec.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
/**
|
|
3
|
+
* Normalize a path for cross-platform comparison
|
|
4
|
+
*
|
|
5
|
+
* - Converts to absolute path (if baseDir provided)
|
|
6
|
+
* - Normalizes separators (/ vs \)
|
|
7
|
+
* - Resolves . and ..
|
|
8
|
+
* - Removes trailing slashes
|
|
9
|
+
*
|
|
10
|
+
* @param p - Path to normalize
|
|
11
|
+
* @param baseDir - Optional base directory for relative path resolution
|
|
12
|
+
* @returns Normalized absolute path
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* normalizePath('./docs/../README.md', '/project')
|
|
16
|
+
* // Returns: '/project/README.md'
|
|
17
|
+
*/
|
|
18
|
+
export function normalizePath(p, baseDir) {
|
|
19
|
+
// Resolve to absolute if baseDir provided, otherwise just normalize
|
|
20
|
+
const resolved = baseDir ? path.resolve(baseDir, p) : path.normalize(p);
|
|
21
|
+
// Normalize path separators and remove trailing slashes
|
|
22
|
+
// Use simple non-backtracking pattern
|
|
23
|
+
let normalized = resolved;
|
|
24
|
+
while (normalized.endsWith('/') || normalized.endsWith('\\')) {
|
|
25
|
+
normalized = normalized.slice(0, -1);
|
|
26
|
+
}
|
|
27
|
+
return normalized;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if a path is absolute
|
|
31
|
+
*
|
|
32
|
+
* Cross-platform detection of absolute paths:
|
|
33
|
+
* - Unix: /path/to/file
|
|
34
|
+
* - Windows: C:\path\to\file or C:/path/to/file
|
|
35
|
+
*
|
|
36
|
+
* @param p - Path to check
|
|
37
|
+
* @returns True if path is absolute
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* isAbsolutePath('/path/to/file') // true
|
|
41
|
+
* isAbsolutePath('./relative') // false
|
|
42
|
+
* isAbsolutePath('C:/Windows') // true (Windows)
|
|
43
|
+
*/
|
|
44
|
+
export function isAbsolutePath(p) {
|
|
45
|
+
return path.isAbsolute(p);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Convert a relative path to absolute
|
|
49
|
+
*
|
|
50
|
+
* If path is already absolute, returns it normalized.
|
|
51
|
+
* Otherwise resolves relative to baseDir.
|
|
52
|
+
*
|
|
53
|
+
* @param p - Path to convert
|
|
54
|
+
* @param baseDir - Base directory for resolution
|
|
55
|
+
* @returns Absolute path
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* toAbsolutePath('./docs/README.md', '/project')
|
|
59
|
+
* // Returns: '/project/docs/README.md'
|
|
60
|
+
*
|
|
61
|
+
* toAbsolutePath('/absolute/path.md', '/project')
|
|
62
|
+
* // Returns: '/absolute/path.md'
|
|
63
|
+
*/
|
|
64
|
+
export function toAbsolutePath(p, baseDir) {
|
|
65
|
+
if (path.isAbsolute(p)) {
|
|
66
|
+
return path.normalize(p);
|
|
67
|
+
}
|
|
68
|
+
return path.resolve(baseDir, p);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get the relative path from one file to another
|
|
72
|
+
*
|
|
73
|
+
* Useful for generating relative links between markdown files.
|
|
74
|
+
*
|
|
75
|
+
* @param from - Source file path (absolute)
|
|
76
|
+
* @param to - Target file path (absolute)
|
|
77
|
+
* @returns Relative path from source to target
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* getRelativePath('/project/docs/guide.md', '/project/README.md')
|
|
81
|
+
* // Returns: '../README.md'
|
|
82
|
+
*
|
|
83
|
+
* getRelativePath('/project/README.md', '/project/docs/api.md')
|
|
84
|
+
* // Returns: 'docs/api.md'
|
|
85
|
+
*/
|
|
86
|
+
export function getRelativePath(from, to) {
|
|
87
|
+
// Get directory of source file (not the file itself)
|
|
88
|
+
const fromDir = path.dirname(from);
|
|
89
|
+
// Calculate relative path from source directory to target file
|
|
90
|
+
return path.relative(fromDir, to);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Convert a path to Unix-style forward slashes
|
|
94
|
+
*
|
|
95
|
+
* Useful for glob pattern matching, which expects forward slashes.
|
|
96
|
+
* On Windows, path.resolve() and path.normalize() return backslashes,
|
|
97
|
+
* but glob matchers like picomatch expect forward slashes by default.
|
|
98
|
+
*
|
|
99
|
+
* @param p - Path to convert
|
|
100
|
+
* @returns Path with forward slashes
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* toUnixPath('C:\\Users\\docs\\README.md')
|
|
104
|
+
* // Returns: 'C:/Users/docs/README.md'
|
|
105
|
+
*
|
|
106
|
+
* toUnixPath('/project/docs/README.md')
|
|
107
|
+
* // Returns: '/project/docs/README.md' (unchanged on Unix)
|
|
108
|
+
*/
|
|
109
|
+
export function toUnixPath(p) {
|
|
110
|
+
return p.replaceAll('\\', '/');
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=path-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-utils.js","sourceRoot":"","sources":["../src/path-utils.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa,CAAC,CAAS,EAAE,OAAgB;IACvD,oEAAoE;IACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAExE,wDAAwD;IACxD,sCAAsC;IACtC,IAAI,UAAU,GAAG,QAAQ,CAAC;IAC1B,OAAO,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,cAAc,CAAC,CAAS,EAAE,OAAe;IACvD,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,EAAU;IACtD,qDAAqD;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC,+DAA+D;IAC/D,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for safe command execution
|
|
3
|
+
*/
|
|
4
|
+
export interface SafeExecOptions {
|
|
5
|
+
/** Character encoding for output (default: undefined = Buffer) */
|
|
6
|
+
encoding?: BufferEncoding;
|
|
7
|
+
/** Standard I/O configuration */
|
|
8
|
+
stdio?: 'pipe' | 'ignore' | Array<'pipe' | 'ignore' | 'inherit'>;
|
|
9
|
+
/** Environment variables (merged with process.env if not fully specified) */
|
|
10
|
+
env?: NodeJS.ProcessEnv;
|
|
11
|
+
/** Working directory */
|
|
12
|
+
cwd?: string;
|
|
13
|
+
/** Maximum output buffer size in bytes */
|
|
14
|
+
maxBuffer?: number;
|
|
15
|
+
/** Timeout in milliseconds */
|
|
16
|
+
timeout?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Result of a safe command execution
|
|
20
|
+
*/
|
|
21
|
+
export interface SafeExecResult {
|
|
22
|
+
/** Exit code (0 = success) */
|
|
23
|
+
status: number;
|
|
24
|
+
/** Standard output */
|
|
25
|
+
stdout: Buffer | string;
|
|
26
|
+
/** Standard error */
|
|
27
|
+
stderr: Buffer | string;
|
|
28
|
+
/** Error object if command failed to spawn */
|
|
29
|
+
error?: Error;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Error thrown when command execution fails
|
|
33
|
+
*/
|
|
34
|
+
export declare class CommandExecutionError extends Error {
|
|
35
|
+
readonly status: number;
|
|
36
|
+
readonly stdout: Buffer | string;
|
|
37
|
+
readonly stderr: Buffer | string;
|
|
38
|
+
constructor(message: string, status: number, stdout: Buffer | string, stderr: Buffer | string);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Safe command execution using spawnSync + which pattern
|
|
42
|
+
*
|
|
43
|
+
* More secure than execSync:
|
|
44
|
+
* - Resolves PATH once using pure Node.js (which package)
|
|
45
|
+
* - Executes with absolute path and shell: false
|
|
46
|
+
* - No shell interpreter = no command injection risk
|
|
47
|
+
* - Supports custom env vars (e.g., GIT_INDEX_FILE)
|
|
48
|
+
*
|
|
49
|
+
* @param command - Command name (e.g., 'git', 'gitleaks', 'node')
|
|
50
|
+
* @param args - Array of arguments
|
|
51
|
+
* @param options - Execution options
|
|
52
|
+
* @returns Buffer or string output
|
|
53
|
+
* @throws Error if command not found or execution fails
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* // Tool detection
|
|
57
|
+
* safeExecSync('gitleaks', ['--version'], { stdio: 'ignore' });
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* // Git with custom env
|
|
61
|
+
* safeExecSync('git', ['add', '--all'], {
|
|
62
|
+
* env: { ...process.env, GIT_INDEX_FILE: tempFile }
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* // Get output as string
|
|
67
|
+
* const version = safeExecSync('node', ['--version'], { encoding: 'utf8' });
|
|
68
|
+
*/
|
|
69
|
+
export declare function safeExecSync(command: string, args?: string[], options?: SafeExecOptions): Buffer | string;
|
|
70
|
+
/**
|
|
71
|
+
* Safe command execution that returns detailed result (doesn't throw)
|
|
72
|
+
*
|
|
73
|
+
* Use this when you need to handle errors programmatically
|
|
74
|
+
* instead of catching exceptions.
|
|
75
|
+
*
|
|
76
|
+
* @param command - Command name (e.g., 'git', 'node')
|
|
77
|
+
* @param args - Array of arguments
|
|
78
|
+
* @param options - Execution options
|
|
79
|
+
* @returns Detailed execution result
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* const result = safeExecResult('git', ['status']);
|
|
83
|
+
* if (result.status === 0) {
|
|
84
|
+
* console.log(result.stdout.toString());
|
|
85
|
+
* } else {
|
|
86
|
+
* console.error(`Failed: ${result.stderr.toString()}`);
|
|
87
|
+
* }
|
|
88
|
+
*/
|
|
89
|
+
export declare function safeExecResult(command: string, args?: string[], options?: SafeExecOptions): SafeExecResult;
|
|
90
|
+
/**
|
|
91
|
+
* Check if a command-line tool is available
|
|
92
|
+
*
|
|
93
|
+
* @param toolName - Name of tool to check (e.g., 'gh', 'gitleaks', 'node')
|
|
94
|
+
* @returns true if tool is available, false otherwise
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* if (isToolAvailable('gh')) {
|
|
98
|
+
* console.log('GitHub CLI is installed');
|
|
99
|
+
* }
|
|
100
|
+
*/
|
|
101
|
+
export declare function isToolAvailable(toolName: string): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Get tool version if available
|
|
104
|
+
*
|
|
105
|
+
* @param toolName - Name of tool (e.g., 'node', 'pnpm')
|
|
106
|
+
* @param versionArg - Argument to get version (default: '--version')
|
|
107
|
+
* @returns Version string or null if not available
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* const nodeVersion = getToolVersion('node');
|
|
111
|
+
* console.log(nodeVersion); // "v20.11.0"
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* const gitVersion = getToolVersion('git', 'version');
|
|
115
|
+
* console.log(gitVersion); // "git version 2.39.2"
|
|
116
|
+
*/
|
|
117
|
+
export declare function getToolVersion(toolName: string, versionArg?: string): string | null;
|
|
118
|
+
/**
|
|
119
|
+
* Check if a command string contains shell-specific syntax
|
|
120
|
+
*
|
|
121
|
+
* Detects patterns that require shell interpretation:
|
|
122
|
+
* - Quotes (", ', `)
|
|
123
|
+
* - Glob patterns (*, ?, [])
|
|
124
|
+
* - Variable expansion ($)
|
|
125
|
+
* - Pipes/redirects/operators (|, >, <, &, ;, &&, ||)
|
|
126
|
+
*
|
|
127
|
+
* Performance: Single-pass O(n) algorithm with O(1) Set lookups.
|
|
128
|
+
* Short-circuits on first match (no backtracking, no regex overhead).
|
|
129
|
+
*
|
|
130
|
+
* @param commandString - Command string to check
|
|
131
|
+
* @returns Object with detection result and details
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* const check1 = hasShellSyntax('npm test');
|
|
136
|
+
* console.log(check1); // { hasShellSyntax: false }
|
|
137
|
+
*
|
|
138
|
+
* const check2 = hasShellSyntax('npm test && npm run build');
|
|
139
|
+
* console.log(check2);
|
|
140
|
+
* // {
|
|
141
|
+
* // hasShellSyntax: true,
|
|
142
|
+
* // pattern: 'pipes/redirects/operators',
|
|
143
|
+
* // example: 'cat file | grep text'
|
|
144
|
+
* // }
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export declare function hasShellSyntax(commandString: string): {
|
|
148
|
+
hasShellSyntax: boolean;
|
|
149
|
+
pattern?: string;
|
|
150
|
+
example?: string;
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Execute a command from a simple command string (convenience wrapper)
|
|
154
|
+
*
|
|
155
|
+
* **IMPORTANT: Shift-Left Validation** - This function actively rejects shell syntax
|
|
156
|
+
* to prevent subtle bugs where shell features are expected but not executed.
|
|
157
|
+
*
|
|
158
|
+
* **Supported:**
|
|
159
|
+
* - Simple commands: `git status`, `pnpm test`, `node --version`
|
|
160
|
+
* - Commands with flags: `git log --oneline --max-count 10`
|
|
161
|
+
* - Multiple unquoted arguments: `gh pr view 123`
|
|
162
|
+
*
|
|
163
|
+
* **NOT Supported (will throw error):**
|
|
164
|
+
* - Quotes: `echo "hello world"` ❌
|
|
165
|
+
* - Glob patterns: `ls *.txt` ❌
|
|
166
|
+
* - Variable expansion: `echo $HOME` ❌
|
|
167
|
+
* - Pipes/redirects: `cat file | grep text` ❌
|
|
168
|
+
* - Command chaining: `build && test` ❌
|
|
169
|
+
*
|
|
170
|
+
* **Why these restrictions?**
|
|
171
|
+
* We don't use a shell interpreter (for security), so shell features like
|
|
172
|
+
* glob expansion, variable substitution, and pipes don't work. By detecting
|
|
173
|
+
* and rejecting these patterns, we force you to use the safer `safeExecSync()`
|
|
174
|
+
* API with explicit argument arrays.
|
|
175
|
+
*
|
|
176
|
+
* @param commandString - Simple command string (no shell syntax)
|
|
177
|
+
* @param options - Execution options
|
|
178
|
+
* @returns Command output (Buffer or string depending on encoding option)
|
|
179
|
+
* @throws Error if command contains shell-specific syntax
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```typescript
|
|
183
|
+
* // ✅ Simple commands (these work)
|
|
184
|
+
* safeExecFromString('git status');
|
|
185
|
+
* safeExecFromString('pnpm test --watch');
|
|
186
|
+
* safeExecFromString('gh pr view 123');
|
|
187
|
+
* ```
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* // ❌ Shell syntax (these throw errors)
|
|
192
|
+
* safeExecFromString('echo "hello"'); // Quotes
|
|
193
|
+
* safeExecFromString('ls *.txt'); // Glob pattern
|
|
194
|
+
* safeExecFromString('cat file | grep text'); // Pipe
|
|
195
|
+
* safeExecFromString('echo $HOME'); // Variable expansion
|
|
196
|
+
*
|
|
197
|
+
* // ✅ Use safeExecSync() instead with explicit arguments
|
|
198
|
+
* safeExecSync('echo', ['hello']);
|
|
199
|
+
* safeExecSync('ls', ['file1.txt', 'file2.txt']); // Or use glob library
|
|
200
|
+
* safeExecSync('grep', ['text', 'file']);
|
|
201
|
+
* safeExecSync('echo', [process.env.HOME || '']);
|
|
202
|
+
* ```
|
|
203
|
+
*
|
|
204
|
+
*/
|
|
205
|
+
export declare function safeExecFromString(commandString: string, options?: SafeExecOptions): Buffer | string;
|
|
206
|
+
//# sourceMappingURL=safe-exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-exec.d.ts","sourceRoot":"","sources":["../src/safe-exec.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;IACjE,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,qBAAqB;IACrB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxC,SAAgB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;gBAGtC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,MAAM,EAAE,MAAM,GAAG,MAAM;CAQ1B;AA4DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,eAAoB,GAC5B,MAAM,GAAG,MAAM,CAsCjB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,eAAoB,GAC5B,cAAc,CA0ChB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOzD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAAoB,GAC/B,MAAM,GAAG,IAAI,CAUf;AAuBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG;IACrD,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CA0CA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,eAAoB,GAC5B,MAAM,GAAG,MAAM,CAyBjB"}
|