veto-sdk 1.4.0 → 1.5.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/README.md +2 -2
- package/dist/cli/bin.d.ts +0 -5
- package/dist/cli/bin.d.ts.map +1 -1
- package/dist/cli/bin.js +182 -31
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/compile.d.ts +44 -0
- package/dist/cli/compile.d.ts.map +1 -0
- package/dist/cli/compile.js +330 -0
- package/dist/cli/compile.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +3 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.js +4 -4
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/learn.d.ts +63 -0
- package/dist/cli/learn.d.ts.map +1 -0
- package/dist/cli/learn.js +257 -0
- package/dist/cli/learn.js.map +1 -0
- package/dist/cli/templates.d.ts +2 -2
- package/dist/cli/templates.d.ts.map +1 -1
- package/dist/cli/templates.js +13 -9
- package/dist/cli/templates.js.map +1 -1
- package/dist/cli/test.d.ts +136 -0
- package/dist/cli/test.d.ts.map +1 -0
- package/dist/cli/test.js +619 -0
- package/dist/cli/test.js.map +1 -0
- package/dist/core/budget.d.ts +44 -0
- package/dist/core/budget.d.ts.map +1 -0
- package/dist/core/budget.js +131 -0
- package/dist/core/budget.js.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/interceptor.d.ts +4 -0
- package/dist/core/interceptor.d.ts.map +1 -1
- package/dist/core/interceptor.js +23 -1
- package/dist/core/interceptor.js.map +1 -1
- package/dist/core/veto.d.ts +71 -5
- package/dist/core/veto.d.ts.map +1 -1
- package/dist/core/veto.js +363 -21
- package/dist/core/veto.js.map +1 -1
- package/dist/deterministic/types.d.ts +2 -0
- package/dist/deterministic/types.d.ts.map +1 -1
- package/dist/deterministic/validator.js +28 -4
- package/dist/deterministic/validator.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/providers/adapters.d.ts +41 -1
- package/dist/providers/adapters.d.ts.map +1 -1
- package/dist/providers/adapters.js +96 -0
- package/dist/providers/adapters.js.map +1 -1
- package/dist/providers/types.d.ts +43 -3
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/rules/expression-validator.d.ts.map +1 -1
- package/dist/rules/expression-validator.js +9 -1
- package/dist/rules/expression-validator.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ The AI model remains unaware of the guardrail - the tool interface is preserved.
|
|
|
18
18
|
## Installation
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
npm install veto
|
|
21
|
+
npm install veto-sdk
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
## Quick Start
|
|
@@ -36,7 +36,7 @@ This creates a `veto/` directory with `veto.config.yaml` and default rules.
|
|
|
36
36
|
Veto's `wrap()` method is provider-agnostic. It works with LangChain, Vercel AI SDK, or any custom tool object.
|
|
37
37
|
|
|
38
38
|
```typescript
|
|
39
|
-
import { Veto } from 'veto';
|
|
39
|
+
import { Veto } from 'veto-sdk';
|
|
40
40
|
import { tool } from '@langchain/core/tools'; // Example with LangChain
|
|
41
41
|
|
|
42
42
|
// 1. Define your tools normally
|
package/dist/cli/bin.d.ts
CHANGED
package/dist/cli/bin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":""}
|
package/dist/cli/bin.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Veto CLI entry point.
|
|
4
|
-
*
|
|
5
|
-
* @module cli/bin
|
|
6
|
-
*/
|
|
7
2
|
import { init } from './init.js';
|
|
3
|
+
import { Observer, PolicyGenerator, parseDuration, policiesToYaml } from './learn.js';
|
|
4
|
+
import { compile } from './compile.js';
|
|
5
|
+
import { test } from './test.js';
|
|
6
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
7
|
+
import { dirname, resolve } from 'node:path';
|
|
8
8
|
const VERSION = '0.1.0';
|
|
9
|
-
|
|
10
|
-
* Print help message.
|
|
11
|
-
*/
|
|
9
|
+
const VALID_PROVIDERS = new Set(['openai', 'anthropic', 'gemini', 'openrouter']);
|
|
12
10
|
function printHelp() {
|
|
13
11
|
console.log(`
|
|
14
12
|
Veto - AI Agent Tool Call Guardrail
|
|
@@ -18,35 +16,69 @@ Usage:
|
|
|
18
16
|
|
|
19
17
|
Commands:
|
|
20
18
|
init Initialize Veto in the current directory
|
|
19
|
+
learn Observe tool calls and generate policies
|
|
20
|
+
compile Compile natural language policies to deterministic YAML rules
|
|
21
|
+
test Run adversarial policy gap analysis
|
|
21
22
|
version Show version information
|
|
22
23
|
help Show this help message
|
|
23
24
|
|
|
24
25
|
Options:
|
|
25
|
-
--force, -f
|
|
26
|
-
--quiet, -q
|
|
27
|
-
--help, -h
|
|
26
|
+
--force, -f Force overwrite existing files (init)
|
|
27
|
+
--quiet, -q Suppress output
|
|
28
|
+
--help, -h Show help
|
|
29
|
+
|
|
30
|
+
Learn Options:
|
|
31
|
+
--runs <n> Stop after n tool calls
|
|
32
|
+
--duration <time> Stop after duration (e.g., 30s, 10m, 1h)
|
|
33
|
+
--output <path> Output YAML file path (default: ./veto/rules/learned.yaml)
|
|
34
|
+
--margin <n> Numeric range margin as decimal (default: 0.1)
|
|
35
|
+
|
|
36
|
+
Compile Options:
|
|
37
|
+
--input <text> Policy description as inline text
|
|
38
|
+
--file <path> Path to a text file containing policy descriptions
|
|
39
|
+
--output <path> Output file (.yaml) or directory for generated rules
|
|
40
|
+
--provider <name> LLM provider: openai, anthropic, gemini, openrouter
|
|
41
|
+
--model <name> Model identifier (e.g. gpt-4o, claude-sonnet-4-5-20250929)
|
|
42
|
+
|
|
43
|
+
Test Options:
|
|
44
|
+
--policy <path> Policy directory (default: ./veto/rules/)
|
|
45
|
+
--output <file> Write JSON report to file
|
|
46
|
+
--format <fmt> Output format: text or json (default: text)
|
|
28
47
|
|
|
29
48
|
Examples:
|
|
30
|
-
veto init
|
|
31
|
-
veto init --force
|
|
49
|
+
veto init Initialize Veto in current directory
|
|
50
|
+
veto init --force Reinitialize, overwriting existing files
|
|
51
|
+
veto learn --runs 10 Observe 10 tool calls then generate policies
|
|
52
|
+
veto learn --duration 30m Observe for 30 minutes
|
|
53
|
+
veto compile --input 'Block emails outside company domain' --output ./veto/rules/email.yaml
|
|
54
|
+
veto compile --file policies.txt --output ./veto/rules/
|
|
55
|
+
veto test Analyze policies for gaps
|
|
56
|
+
veto test --policy ./rules Analyze specific policy directory
|
|
57
|
+
veto test --output report.json Save JSON report
|
|
32
58
|
`);
|
|
33
59
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Print version.
|
|
36
|
-
*/
|
|
37
60
|
function printVersion() {
|
|
38
61
|
console.log(`veto v${VERSION}`);
|
|
39
62
|
}
|
|
40
|
-
/**
|
|
41
|
-
* Parse command line arguments.
|
|
42
|
-
*/
|
|
43
63
|
function parseArgs(args) {
|
|
44
64
|
const flags = {};
|
|
65
|
+
const values = {};
|
|
45
66
|
let command = '';
|
|
46
|
-
|
|
67
|
+
const valueFlags = new Set([
|
|
68
|
+
'runs', 'duration', 'output', 'margin',
|
|
69
|
+
'input', 'file', 'provider', 'model',
|
|
70
|
+
'policy', 'format',
|
|
71
|
+
]);
|
|
72
|
+
for (let i = 0; i < args.length; i++) {
|
|
73
|
+
const arg = args[i];
|
|
47
74
|
if (arg.startsWith('--')) {
|
|
48
75
|
const flag = arg.slice(2);
|
|
49
|
-
|
|
76
|
+
if (valueFlags.has(flag) && i + 1 < args.length) {
|
|
77
|
+
values[flag] = args[++i];
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
flags[flag] = true;
|
|
81
|
+
}
|
|
50
82
|
}
|
|
51
83
|
else if (arg.startsWith('-')) {
|
|
52
84
|
const shortFlags = arg.slice(1).split('');
|
|
@@ -68,25 +100,111 @@ function parseArgs(args) {
|
|
|
68
100
|
command = arg;
|
|
69
101
|
}
|
|
70
102
|
}
|
|
71
|
-
return { command, flags };
|
|
103
|
+
return { command, flags, values };
|
|
104
|
+
}
|
|
105
|
+
async function runLearn(flags, values) {
|
|
106
|
+
const quiet = flags['quiet'] ?? false;
|
|
107
|
+
const stopCondition = {};
|
|
108
|
+
if (values['runs']) {
|
|
109
|
+
const runs = parseInt(values['runs'], 10);
|
|
110
|
+
if (isNaN(runs) || runs <= 0) {
|
|
111
|
+
console.error('--runs must be a positive integer');
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
stopCondition.runs = runs;
|
|
115
|
+
}
|
|
116
|
+
if (values['duration']) {
|
|
117
|
+
stopCondition.durationMs = parseDuration(values['duration']);
|
|
118
|
+
}
|
|
119
|
+
if (!stopCondition.runs && !stopCondition.durationMs) {
|
|
120
|
+
console.error('veto learn requires --runs or --duration');
|
|
121
|
+
console.error('Example: veto learn --runs 10');
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
const margin = values['margin'] ? parseFloat(values['margin']) : 0.1;
|
|
125
|
+
if (values['margin'] && (isNaN(margin) || margin < 0 || margin > 1)) {
|
|
126
|
+
console.error('--margin must be a number between 0 and 1');
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
const outputPath = resolve(values['output'] ?? './veto/rules/learned.yaml');
|
|
130
|
+
const observer = new Observer(stopCondition);
|
|
131
|
+
observer.start();
|
|
132
|
+
if (!quiet) {
|
|
133
|
+
console.log('');
|
|
134
|
+
console.log('Veto Learn - Observing tool calls...');
|
|
135
|
+
if (stopCondition.runs)
|
|
136
|
+
console.log(` Stop after: ${stopCondition.runs} calls`);
|
|
137
|
+
if (stopCondition.durationMs)
|
|
138
|
+
console.log(` Stop after: ${values['duration']}`);
|
|
139
|
+
console.log(` Output: ${outputPath}`);
|
|
140
|
+
console.log(` Margin: ${margin}`);
|
|
141
|
+
console.log('');
|
|
142
|
+
console.log('Reading tool calls from stdin (one JSON object per line)...');
|
|
143
|
+
console.log('Format: {"tool": "tool_name", "args": {...}}');
|
|
144
|
+
console.log('');
|
|
145
|
+
}
|
|
146
|
+
const readline = await import('node:readline');
|
|
147
|
+
const rl = readline.createInterface({ input: process.stdin });
|
|
148
|
+
for await (const line of rl) {
|
|
149
|
+
if (observer.stopped)
|
|
150
|
+
break;
|
|
151
|
+
const trimmed = line.trim();
|
|
152
|
+
if (!trimmed)
|
|
153
|
+
continue;
|
|
154
|
+
try {
|
|
155
|
+
const parsed = JSON.parse(trimmed);
|
|
156
|
+
const toolName = parsed.tool ?? parsed.name;
|
|
157
|
+
const args = parsed.args ?? parsed.arguments ?? {};
|
|
158
|
+
if (!toolName || typeof toolName !== 'string') {
|
|
159
|
+
if (!quiet)
|
|
160
|
+
console.error(' Skipping line: missing "tool" or "name" field');
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
observer.recordRaw(toolName, args);
|
|
164
|
+
if (!quiet)
|
|
165
|
+
console.log(` [${observer.callCount}] ${toolName}(${JSON.stringify(args).slice(0, 60)})`);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
if (!quiet)
|
|
169
|
+
console.error(` Skipping invalid JSON: ${trimmed.slice(0, 50)}`);
|
|
170
|
+
}
|
|
171
|
+
if (observer.shouldStop())
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
rl.close();
|
|
175
|
+
const observations = observer.getObservations();
|
|
176
|
+
const generator = new PolicyGenerator(margin);
|
|
177
|
+
const policies = generator.generate(observations);
|
|
178
|
+
if (policies.length === 0) {
|
|
179
|
+
if (!quiet)
|
|
180
|
+
console.log('No tool calls observed. No policies generated.');
|
|
181
|
+
process.exit(0);
|
|
182
|
+
}
|
|
183
|
+
const yaml = policiesToYaml(policies);
|
|
184
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
185
|
+
writeFileSync(outputPath, yaml, 'utf-8');
|
|
186
|
+
if (!quiet) {
|
|
187
|
+
console.log('');
|
|
188
|
+
console.log(`Generated ${policies.length} policies from ${observer.callCount} observations.`);
|
|
189
|
+
console.log(`Output: ${outputPath}`);
|
|
190
|
+
console.log('');
|
|
191
|
+
for (const p of policies) {
|
|
192
|
+
console.log(` ${p.toolName}: ${p.constraints.length} constraints`);
|
|
193
|
+
}
|
|
194
|
+
console.log('');
|
|
195
|
+
}
|
|
72
196
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Main CLI entry point.
|
|
75
|
-
*/
|
|
76
197
|
async function main() {
|
|
77
198
|
const args = process.argv.slice(2);
|
|
78
|
-
const { command, flags } = parseArgs(args);
|
|
79
|
-
// Handle help flag
|
|
199
|
+
const { command, flags, values } = parseArgs(args);
|
|
80
200
|
if (flags['help'] || command === 'help') {
|
|
81
201
|
printHelp();
|
|
82
202
|
process.exit(0);
|
|
83
203
|
}
|
|
84
|
-
// Handle version flag or command
|
|
85
204
|
if (flags['version'] || command === 'version') {
|
|
86
205
|
printVersion();
|
|
87
206
|
process.exit(0);
|
|
88
207
|
}
|
|
89
|
-
// Handle commands
|
|
90
208
|
switch (command) {
|
|
91
209
|
case 'init': {
|
|
92
210
|
const result = await init({
|
|
@@ -96,8 +214,42 @@ async function main() {
|
|
|
96
214
|
process.exit(result.success ? 0 : 1);
|
|
97
215
|
break;
|
|
98
216
|
}
|
|
217
|
+
case 'learn': {
|
|
218
|
+
await runLearn(flags, values);
|
|
219
|
+
process.exit(0);
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
case 'compile': {
|
|
223
|
+
if (!values['output']) {
|
|
224
|
+
console.error('Error: --output is required for compile command');
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
if (values['provider'] && !VALID_PROVIDERS.has(values['provider'])) {
|
|
228
|
+
console.error(`Error: Invalid provider "${values['provider']}". Must be one of: openai, anthropic, gemini, openrouter`);
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
const result = await compile({
|
|
232
|
+
input: values['input'],
|
|
233
|
+
file: values['file'],
|
|
234
|
+
output: values['output'],
|
|
235
|
+
provider: values['provider'],
|
|
236
|
+
model: values['model'],
|
|
237
|
+
quiet: flags['quiet'],
|
|
238
|
+
});
|
|
239
|
+
process.exit(result.success ? 0 : 1);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
case 'test': {
|
|
243
|
+
const testResult = await test({
|
|
244
|
+
policy: values['policy'],
|
|
245
|
+
output: values['output'],
|
|
246
|
+
quiet: flags['quiet'],
|
|
247
|
+
format: values['format'] ?? undefined,
|
|
248
|
+
});
|
|
249
|
+
process.exit(testResult.success ? 0 : 1);
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
99
252
|
case '': {
|
|
100
|
-
// No command provided
|
|
101
253
|
console.log('Veto - AI Agent Tool Call Guardrail');
|
|
102
254
|
console.log('');
|
|
103
255
|
console.log('Run "veto help" for usage information.');
|
|
@@ -112,7 +264,6 @@ async function main() {
|
|
|
112
264
|
}
|
|
113
265
|
}
|
|
114
266
|
}
|
|
115
|
-
// Run the CLI
|
|
116
267
|
main().catch((error) => {
|
|
117
268
|
console.error('Error:', error.message);
|
|
118
269
|
process.exit(1);
|
package/dist/cli/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { CustomProvider } from '../custom/types.js';
|
|
2
|
+
import { CustomError } from '../custom/types.js';
|
|
3
|
+
export interface CompileOptions {
|
|
4
|
+
input?: string;
|
|
5
|
+
file?: string;
|
|
6
|
+
output: string;
|
|
7
|
+
provider?: CustomProvider;
|
|
8
|
+
model?: string;
|
|
9
|
+
quiet?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface CompileResult {
|
|
12
|
+
success: boolean;
|
|
13
|
+
outputPath?: string;
|
|
14
|
+
yaml?: string;
|
|
15
|
+
messages: string[];
|
|
16
|
+
}
|
|
17
|
+
declare const COMPILE_SYSTEM_PROMPT = "You are a policy compiler for Veto, an AI agent tool-call guardrail system.\n\nYour task: convert a natural language policy description into deterministic YAML constraint rules.\n\nThe output MUST be a valid JSON object with two fields:\n- \"rules\": an array of rule objects (the compiled rules)\n- \"notes\": a string with any caveats or suggestions (empty string if none)\n\nEach rule object MUST have these fields:\n- \"id\": kebab-case unique identifier (e.g. \"block-external-emails\")\n- \"name\": short human-readable name\n- \"description\": what the rule does\n- \"enabled\": true\n- \"severity\": one of \"critical\", \"high\", \"medium\", \"low\", \"info\"\n- \"action\": one of \"block\", \"warn\", \"log\", \"allow\"\n- \"tools\": array of tool name strings this applies to (use general names like \"send_email\", \"transfer_funds\", \"read_file\", \"write_file\", \"execute_command\", etc.)\n- \"conditions\": array of condition objects, each with:\n - \"field\": dot-notation path (e.g. \"arguments.to\", \"arguments.amount\")\n - \"operator\": one of \"equals\", \"not_equals\", \"contains\", \"not_contains\", \"starts_with\", \"ends_with\", \"matches\", \"greater_than\", \"less_than\", \"in\", \"not_in\"\n - \"value\": the value to compare against\n\nCommon patterns:\n- Domain restrictions: use \"matches\" operator with regex (e.g. \"^[^@]+@company\\.com$\")\n- Amount limits: use \"greater_than\" or \"less_than\" with numeric values\n- Field requirements: use \"equals\" with expected values\n- Enum allowlists: use \"in\" with an array of allowed values\n- Path restrictions: use \"starts_with\" or \"matches\" with path patterns\n\nIf the policy CANNOT be fully expressed as deterministic rules, include an explanation in the \"notes\" field describing what aspects require LLM-based evaluation.\n\nRespond with ONLY a JSON object. No markdown, no explanation outside the JSON.";
|
|
18
|
+
declare function buildUserPrompt(policyText: string): string;
|
|
19
|
+
export declare class CompileError extends CustomError {
|
|
20
|
+
constructor(message: string);
|
|
21
|
+
}
|
|
22
|
+
interface CompiledRule {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
severity: string;
|
|
28
|
+
action: string;
|
|
29
|
+
tools: string[];
|
|
30
|
+
conditions: Array<{
|
|
31
|
+
field: string;
|
|
32
|
+
operator: string;
|
|
33
|
+
value: unknown;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
interface LLMOutput {
|
|
37
|
+
rules: CompiledRule[];
|
|
38
|
+
notes: string;
|
|
39
|
+
}
|
|
40
|
+
declare function parseAndValidateLLMOutput(raw: string): LLMOutput;
|
|
41
|
+
declare function toYaml(output: LLMOutput, policyText: string): string;
|
|
42
|
+
export declare function compile(options: CompileOptions): Promise<CompileResult>;
|
|
43
|
+
export { COMPILE_SYSTEM_PROMPT, buildUserPrompt, parseAndValidateLLMOutput, toYaml };
|
|
44
|
+
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/cli/compile.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAGL,WAAW,EACZ,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AASD,QAAA,MAAM,qBAAqB,w3DA8BoD,CAAC;AAEhF,iBAAS,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEnD;AA6CD,qBAAa,YAAa,SAAQ,WAAW;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAsED,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,KAAK,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC,CAAC;CACJ;AAED,UAAU,SAAS;IACjB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAcD,iBAAS,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAgEzD;AAED,iBAAS,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAQ7D;AAQD,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAsG7E;AAED,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,EAAE,CAAC"}
|