prefix-safe-json 0.0.1-alpha.3 → 0.1.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/LICENSE +4 -0
- package/README.md +72 -33
- package/package.json +8 -3
- package/dist/coordinator/coordinator.d.ts +0 -53
- package/dist/coordinator/coordinator.d.ts.map +0 -1
- package/dist/coordinator/coordinator.js +0 -448
- package/dist/coordinator/coordinator.js.map +0 -1
- package/dist/coordinator/diagnostic-codes.d.ts +0 -11
- package/dist/coordinator/diagnostic-codes.d.ts.map +0 -1
- package/dist/coordinator/diagnostic-codes.js +0 -22
- package/dist/coordinator/diagnostic-codes.js.map +0 -1
- package/dist/coordinator/protocol.d.ts +0 -61
- package/dist/coordinator/protocol.d.ts.map +0 -1
- package/dist/coordinator/protocol.js +0 -2
- package/dist/coordinator/protocol.js.map +0 -1
- package/dist/coordinator/types.d.ts +0 -104
- package/dist/coordinator/types.d.ts.map +0 -1
- package/dist/coordinator/types.js +0 -7
- package/dist/coordinator/types.js.map +0 -1
- package/dist/diagnostics/codes.d.ts +0 -24
- package/dist/diagnostics/codes.d.ts.map +0 -1
- package/dist/diagnostics/codes.js +0 -28
- package/dist/diagnostics/codes.js.map +0 -1
- package/dist/diagnostics/factory.d.ts +0 -8
- package/dist/diagnostics/factory.d.ts.map +0 -1
- package/dist/diagnostics/factory.js +0 -17
- package/dist/diagnostics/factory.js.map +0 -1
- package/dist/gate/decide.d.ts +0 -20
- package/dist/gate/decide.d.ts.map +0 -1
- package/dist/gate/decide.js +0 -127
- package/dist/gate/decide.js.map +0 -1
- package/dist/gate/gate.d.ts +0 -25
- package/dist/gate/gate.d.ts.map +0 -1
- package/dist/gate/gate.js +0 -80
- package/dist/gate/gate.js.map +0 -1
- package/dist/gate/types.d.ts +0 -122
- package/dist/gate/types.d.ts.map +0 -1
- package/dist/gate/types.js +0 -2
- package/dist/gate/types.js.map +0 -1
- package/dist/grammar/frame.d.ts +0 -58
- package/dist/grammar/frame.d.ts.map +0 -1
- package/dist/grammar/frame.js +0 -87
- package/dist/grammar/frame.js.map +0 -1
- package/dist/grammar/pointer.d.ts +0 -10
- package/dist/grammar/pointer.d.ts.map +0 -1
- package/dist/grammar/pointer.js +0 -20
- package/dist/grammar/pointer.js.map +0 -1
- package/dist/grammar/stack.d.ts +0 -73
- package/dist/grammar/stack.d.ts.map +0 -1
- package/dist/grammar/stack.js +0 -168
- package/dist/grammar/stack.js.map +0 -1
- package/dist/index.d.ts +0 -37
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -37
- package/dist/index.js.map +0 -1
- package/dist/lexer/scanner.d.ts +0 -108
- package/dist/lexer/scanner.d.ts.map +0 -1
- package/dist/lexer/scanner.js +0 -676
- package/dist/lexer/scanner.js.map +0 -1
- package/dist/lexer/states.d.ts +0 -35
- package/dist/lexer/states.d.ts.map +0 -1
- package/dist/lexer/states.js +0 -39
- package/dist/lexer/states.js.map +0 -1
- package/dist/lexer/tokens.d.ts +0 -22
- package/dist/lexer/tokens.d.ts.map +0 -1
- package/dist/lexer/tokens.js +0 -22
- package/dist/lexer/tokens.js.map +0 -1
- package/dist/limits.d.ts +0 -14
- package/dist/limits.d.ts.map +0 -1
- package/dist/limits.js +0 -23
- package/dist/limits.js.map +0 -1
- package/dist/parser.d.ts +0 -6
- package/dist/parser.d.ts.map +0 -1
- package/dist/parser.js +0 -949
- package/dist/parser.js.map +0 -1
- package/dist/providers/adapter.d.ts +0 -10
- package/dist/providers/adapter.d.ts.map +0 -1
- package/dist/providers/adapter.js +0 -2
- package/dist/providers/adapter.js.map +0 -1
- package/dist/providers/ai-sdk.d.ts +0 -54
- package/dist/providers/ai-sdk.d.ts.map +0 -1
- package/dist/providers/ai-sdk.js +0 -191
- package/dist/providers/ai-sdk.js.map +0 -1
- package/dist/providers/anthropic.d.ts +0 -45
- package/dist/providers/anthropic.d.ts.map +0 -1
- package/dist/providers/anthropic.js +0 -112
- package/dist/providers/anthropic.js.map +0 -1
- package/dist/providers/gemini.d.ts +0 -31
- package/dist/providers/gemini.d.ts.map +0 -1
- package/dist/providers/gemini.js +0 -94
- package/dist/providers/gemini.js.map +0 -1
- package/dist/providers/openai-compatible.d.ts +0 -33
- package/dist/providers/openai-compatible.d.ts.map +0 -1
- package/dist/providers/openai-compatible.js +0 -160
- package/dist/providers/openai-compatible.js.map +0 -1
- package/dist/providers/openai.d.ts +0 -48
- package/dist/providers/openai.d.ts.map +0 -1
- package/dist/providers/openai.js +0 -205
- package/dist/providers/openai.js.map +0 -1
- package/dist/providers/openrouter.d.ts +0 -35
- package/dist/providers/openrouter.d.ts.map +0 -1
- package/dist/providers/openrouter.js +0 -55
- package/dist/providers/openrouter.js.map +0 -1
- package/dist/semantic/builder.d.ts +0 -55
- package/dist/semantic/builder.d.ts.map +0 -1
- package/dist/semantic/builder.js +0 -140
- package/dist/semantic/builder.js.map +0 -1
- package/dist/semantic/events.d.ts +0 -2
- package/dist/semantic/events.d.ts.map +0 -1
- package/dist/semantic/events.js +0 -5
- package/dist/semantic/events.js.map +0 -1
- package/dist/semantic/snapshot.d.ts +0 -49
- package/dist/semantic/snapshot.d.ts.map +0 -1
- package/dist/semantic/snapshot.js +0 -228
- package/dist/semantic/snapshot.js.map +0 -1
- package/dist/types.d.ts +0 -156
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -5
- package/dist/types.js.map +0 -1
- package/dist/utf8/decoder.d.ts +0 -53
- package/dist/utf8/decoder.d.ts.map +0 -1
- package/dist/utf8/decoder.js +0 -323
- package/dist/utf8/decoder.js.map +0 -1
package/LICENSE
ADDED
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# prefix-safe-json
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> **v0.1** — No longer alpha. Core API (`createParser`, `createToolCallStreamCoordinator`, `createToolCallExecutionGate`, `createAiSdkExecutionGuard`) is considered stable; any breaking change will be called out in [CHANGELOG.md](CHANGELOG.md). Raw provider adapters (`OpenAIStreamAdapter` and friends) remain experimental — see [Current Status](#current-status) for what's covered.
|
|
4
4
|
|
|
5
5
|
**Don't execute incomplete AI tool calls.**
|
|
6
6
|
|
|
@@ -34,43 +34,74 @@ model output truncated
|
|
|
34
34
|
|
|
35
35
|
*(Real terminal output from [`examples/anthropic-truncation-safety.mjs`](examples/anthropic-truncation-safety.mjs) — not staged. Same script CI runs on every push.)*
|
|
36
36
|
|
|
37
|
-
##
|
|
38
|
-
|
|
39
|
-
The highest-level API answers one question per tool call — is it safe to
|
|
40
|
-
execute right now — without requiring you to know anything about parser
|
|
41
|
-
state, coordinator events, or JSON Pointers:
|
|
37
|
+
## From stream to safe execution, in about 10 lines
|
|
42
38
|
|
|
43
39
|
```typescript
|
|
44
|
-
import {
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
40
|
+
import { createAiSdkExecutionGuard } from "prefix-safe-json";
|
|
41
|
+
|
|
42
|
+
const guard = createAiSdkExecutionGuard({
|
|
43
|
+
schemas: {
|
|
44
|
+
write_file: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: { path: { type: "string" }, content: { type: "string" } },
|
|
47
|
+
required: ["path", "content"],
|
|
48
|
+
},
|
|
51
49
|
},
|
|
52
50
|
});
|
|
53
|
-
const adapter = new AnthropicStreamAdapter();
|
|
54
51
|
|
|
55
|
-
for (const
|
|
56
|
-
for (const normalized of adapter.push(rawEvent)) gate.push(normalized);
|
|
57
|
-
}
|
|
52
|
+
for await (const part of result.fullStream) guard.push(part);
|
|
58
53
|
|
|
59
|
-
for (const decision of
|
|
60
|
-
if (decision.action === "execute")
|
|
61
|
-
await tools[decision.name](decision.value);
|
|
62
|
-
} else {
|
|
63
|
-
console.warn(`${decision.name}: ${decision.action} (${decision.reason})`); // "retry" or "reject"
|
|
64
|
-
}
|
|
54
|
+
for (const decision of guard.finish().decisions) {
|
|
55
|
+
if (decision.action === "execute") await tools[decision.name](decision.value);
|
|
65
56
|
}
|
|
66
57
|
```
|
|
67
58
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
(`ai`
|
|
71
|
-
[`examples/ai-sdk-
|
|
72
|
-
|
|
73
|
-
|
|
59
|
+
`createAiSdkExecutionGuard()` is a drop-in guard for the [Vercel AI
|
|
60
|
+
SDK](https://ai-sdk.dev)'s `fullStream` — not a dependency of this library
|
|
61
|
+
(no `ai` import, no runtime version lock; see
|
|
62
|
+
[`examples/ai-sdk-guard.mjs`](examples/ai-sdk-guard.mjs)). It's a thin
|
|
63
|
+
composition over the same lower-level adapter + gate API this library has
|
|
64
|
+
always exposed — nothing about the decision logic changes based on which one
|
|
65
|
+
you call.
|
|
66
|
+
|
|
67
|
+
**What the decisions mean**
|
|
68
|
+
|
|
69
|
+
Every tool call gets exactly one verdict:
|
|
70
|
+
|
|
71
|
+
- **`execute`** — complete, unfabricated, and (if a schema is registered)
|
|
72
|
+
schema-valid. `decision.value` is safe to pass to your tool.
|
|
73
|
+
- **`retry`** — nothing is wrong with what arrived; there just isn't a
|
|
74
|
+
trustworthy complete value yet. Continue generation.
|
|
75
|
+
- **`reject`** — the data itself is the problem (malformed JSON, a schema
|
|
76
|
+
mismatch, a resource limit, a provider error, a content-policy
|
|
77
|
+
termination). Retrying the same input won't help.
|
|
78
|
+
|
|
79
|
+
**Why the model's finish reason matters as much as the JSON's shape**
|
|
80
|
+
|
|
81
|
+
A tool call cut short by a token limit, a provider error, or a content
|
|
82
|
+
filter can still contain syntactically complete, schema-valid JSON — the
|
|
83
|
+
model was simply stopped before finishing the *rest* of its response, not
|
|
84
|
+
necessarily mid-argument. Executing on JSON shape alone means trusting data
|
|
85
|
+
nobody, including the model, confirmed as final. This is exactly the failure
|
|
86
|
+
mode independently reported and reproduced in
|
|
87
|
+
[vercel/ai#19063](https://github.com/vercel/ai/issues/19063): tool calls
|
|
88
|
+
executing regardless of an unsafe finish reason, across AI SDK v5, v6, and
|
|
89
|
+
v7, with fixes landing across all three release lines (v7's in `ai@7.0.70`).
|
|
90
|
+
`prefix-safe-json` does not patch or depend on that fix — it's a
|
|
91
|
+
provider-independent guard that requires positive proof a stream ended
|
|
92
|
+
safely before treating any tool call as final, regardless of which SDK,
|
|
93
|
+
provider, or framework hands it the data. See
|
|
94
|
+
`test/guard/ai-sdk-compatibility.test.ts` for the cross-version test
|
|
95
|
+
evidence.
|
|
96
|
+
|
|
97
|
+
**Supported providers**: OpenAI (legacy `function_call` and Responses API),
|
|
98
|
+
Anthropic, Gemini, OpenRouter, generic OpenAI-compatible endpoints, and the
|
|
99
|
+
Vercel AI SDK. High-level guards currently ship for the AI SDK; every
|
|
100
|
+
provider has a public low-level adapter (see below) that composes with
|
|
101
|
+
`createToolCallExecutionGate()` the same way.
|
|
102
|
+
|
|
103
|
+
Full semantics, the decision table, provider finish-reason mapping, and the
|
|
104
|
+
high-level guard API: [`docs/EXECUTION_GATE.md`](docs/EXECUTION_GATE.md).
|
|
74
105
|
|
|
75
106
|
## The lower-level problem this is built on
|
|
76
107
|
|
|
@@ -181,7 +212,7 @@ It does **not**:
|
|
|
181
212
|
See [`docs/EXECUTION_GATE.md`](docs/EXECUTION_GATE.md#limitations---what-this-does-not-protect-against)
|
|
182
213
|
for the full list, including known internal limitations.
|
|
183
214
|
|
|
184
|
-
## Current Status
|
|
215
|
+
## Current Status
|
|
185
216
|
|
|
186
217
|
### Implemented
|
|
187
218
|
|
|
@@ -197,6 +228,7 @@ for the full list, including known internal limitations.
|
|
|
197
228
|
- Provider stream adapters for OpenAI (legacy `function_call` and Responses API), Anthropic, Gemini, OpenRouter, generic OpenAI-compatible endpoints, and the Vercel AI SDK, plus a coordinator for tracking multiple concurrent tool-call streams
|
|
198
229
|
- Optional per-tool JSON Schema validation on the coordinator (see below) — a value can be structurally complete and still not match what a tool declared it needs
|
|
199
230
|
- `createToolCallExecutionGate()` — a fail-closed `execute` / `retry` / `reject` decision per tool call, built on top of the coordinator (see [`docs/EXECUTION_GATE.md`](docs/EXECUTION_GATE.md))
|
|
231
|
+
- `createAiSdkExecutionGuard()` — a drop-in high-level guard for the Vercel AI SDK's `fullStream`, composing a provider adapter with the execution gate; every `ExecutionDecision` also carries an `evidence` object explaining why (see [`docs/EXECUTION_GATE.md`](docs/EXECUTION_GATE.md#high-level-guards))
|
|
200
232
|
|
|
201
233
|
### Not Yet Implemented
|
|
202
234
|
|
|
@@ -241,8 +273,11 @@ npm install prefix-safe-json
|
|
|
241
273
|
|
|
242
274
|
## Low-level API: Quick Start
|
|
243
275
|
|
|
244
|
-
The
|
|
245
|
-
|
|
276
|
+
The AI SDK guard (above) covers the common case. For other providers, or
|
|
277
|
+
when you need the adapter/gate instance directly, `createToolCallExecutionGate()`
|
|
278
|
+
and the provider adapters (`AnthropicStreamAdapter`, `OpenAIStreamAdapter`,
|
|
279
|
+
etc.) are equally public — see [`docs/EXECUTION_GATE.md`](docs/EXECUTION_GATE.md#example).
|
|
280
|
+
The `createParser()` API both are built on is also fully public, for anyone who
|
|
246
281
|
needs direct access to parser state:
|
|
247
282
|
|
|
248
283
|
```typescript
|
|
@@ -280,10 +315,14 @@ and asserts the truncated call is never reported executable while a
|
|
|
280
315
|
genuinely complete one is. This example runs in CI on every push, so it
|
|
281
316
|
can't silently rot into a stale claim.
|
|
282
317
|
|
|
283
|
-
For the same demonstration through the
|
|
318
|
+
For the same demonstration through the low-level execution gate and the
|
|
284
319
|
[Vercel AI SDK](https://ai-sdk.dev)'s `fullStream` shape instead, see
|
|
285
320
|
[`examples/ai-sdk-execution-gate.mjs`](examples/ai-sdk-execution-gate.mjs)
|
|
286
321
|
(`node examples/ai-sdk-execution-gate.mjs` after `pnpm run build`) — also
|
|
322
|
+
run in CI on every push. For the drop-in `createAiSdkExecutionGuard()` shown
|
|
323
|
+
at the top of this README, see
|
|
324
|
+
[`examples/ai-sdk-guard.mjs`](examples/ai-sdk-guard.mjs)
|
|
325
|
+
(`node examples/ai-sdk-guard.mjs`) — same scenarios, same guarantees, also
|
|
287
326
|
run in CI on every push.
|
|
288
327
|
|
|
289
328
|
## License
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prefix-safe-json",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Fail-closed execution integrity for streamed LLM tool calls — reject truncated or unconfirmed arguments before side effects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"json",
|
|
7
7
|
"streaming",
|
|
8
8
|
"incremental",
|
|
9
9
|
"llm",
|
|
10
|
+
"ai-agents",
|
|
10
11
|
"tool-calling",
|
|
12
|
+
"tool-execution",
|
|
13
|
+
"execution-safety",
|
|
11
14
|
"function-calling",
|
|
12
15
|
"json-repair",
|
|
13
16
|
"json-parser"
|
|
@@ -31,6 +34,7 @@
|
|
|
31
34
|
},
|
|
32
35
|
"files": [
|
|
33
36
|
"dist",
|
|
37
|
+
"LICENSE",
|
|
34
38
|
"LICENSE-MIT",
|
|
35
39
|
"LICENSE-APACHE",
|
|
36
40
|
"README.md"
|
|
@@ -59,7 +63,8 @@
|
|
|
59
63
|
"clean": "rimraf dist coverage .vitest",
|
|
60
64
|
"pack:check": "pnpm pack --dry-run",
|
|
61
65
|
"example:anthropic": "node examples/anthropic-truncation-safety.mjs",
|
|
62
|
-
"example:ai-sdk": "node examples/ai-sdk-execution-gate.mjs"
|
|
66
|
+
"example:ai-sdk": "node examples/ai-sdk-execution-gate.mjs",
|
|
67
|
+
"example:ai-sdk-guard": "node examples/ai-sdk-guard.mjs"
|
|
63
68
|
},
|
|
64
69
|
"devDependencies": {
|
|
65
70
|
"@eslint/js": "^9.8.0",
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { ParserOptions } from "../types.js";
|
|
2
|
-
import { NormalizedToolStreamEvent, StreamEndReason } from "./protocol.js";
|
|
3
|
-
import { ToolCallStreamCoordinator, ToolCallCoordinatorSnapshot, ToolCallCoordinatorEvent, ToolCallCoordinatorFinalResult, CoordinatorPushResult, CoordinatorLimits, JsonSchemaLike } from "./types.js";
|
|
4
|
-
export declare class DefaultToolCallStreamCoordinator implements ToolCallStreamCoordinator {
|
|
5
|
-
private readonly limits;
|
|
6
|
-
private readonly parserOptions;
|
|
7
|
-
private readonly toolValidators;
|
|
8
|
-
private calls;
|
|
9
|
-
private sourceKeyToInternalId;
|
|
10
|
-
private callCounter;
|
|
11
|
-
private eventQueue;
|
|
12
|
-
private diagnostics;
|
|
13
|
-
private eventsProcessed;
|
|
14
|
-
private globalSequence;
|
|
15
|
-
private isFinished;
|
|
16
|
-
/**
|
|
17
|
-
* @param limits Coordinator-level limits (concurrent tool calls, tool name
|
|
18
|
-
* size, etc.) — distinct from `parserOptions`, which configures each
|
|
19
|
-
* underlying per-call IncrementalJsonParser (limits, repairs). Previously
|
|
20
|
-
* there was no way to pass the latter through at all; every parser the
|
|
21
|
-
* coordinator created was hardcoded to library defaults.
|
|
22
|
-
* @param toolSchemas Optional JSON Schema (draft-07) per tool name. When a
|
|
23
|
-
* call for a registered tool reaches outcome "complete", its
|
|
24
|
-
* `stableValue` is validated against the schema. Structural
|
|
25
|
-
* prefix-safety (no truncated/fabricated values) and schema validity
|
|
26
|
-
* are independent concerns — a value can be genuinely complete and
|
|
27
|
-
* still not match what the tool declared it needs (wrong type, missing
|
|
28
|
-
* required field the model never provided at all). Both must hold for
|
|
29
|
-
* `executable` to be true. Schemas are compiled eagerly here so a
|
|
30
|
-
* malformed schema fails fast at construction, not mid-stream.
|
|
31
|
-
*/
|
|
32
|
-
constructor(limits?: Partial<CoordinatorLimits>, parserOptions?: ParserOptions, toolSchemas?: Record<string, JsonSchemaLike>);
|
|
33
|
-
push(event: NormalizedToolStreamEvent): CoordinatorPushResult;
|
|
34
|
-
private handleStart;
|
|
35
|
-
private handleIdentity;
|
|
36
|
-
private handleNameDelta;
|
|
37
|
-
private handleArgumentsDelta;
|
|
38
|
-
private handleCallEnd;
|
|
39
|
-
private finishCall;
|
|
40
|
-
private hasCallConflict;
|
|
41
|
-
private handleProviderDiagnostic;
|
|
42
|
-
private handleStreamEnd;
|
|
43
|
-
private getCall;
|
|
44
|
-
private addDiagnostic;
|
|
45
|
-
snapshot(): ToolCallCoordinatorSnapshot;
|
|
46
|
-
drainEvents(): readonly ToolCallCoordinatorEvent[];
|
|
47
|
-
finish(meta?: {
|
|
48
|
-
reason?: StreamEndReason;
|
|
49
|
-
providerReason?: string;
|
|
50
|
-
}): ToolCallCoordinatorFinalResult;
|
|
51
|
-
}
|
|
52
|
-
export declare function createToolCallStreamCoordinator(limits?: Partial<CoordinatorLimits>, parserOptions?: ParserOptions, toolSchemas?: Record<string, JsonSchemaLike>): ToolCallStreamCoordinator;
|
|
53
|
-
//# sourceMappingURL=coordinator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"coordinator.d.ts","sourceRoot":"","sources":["../../src/coordinator/coordinator.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,aAAa,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,EAAE,yBAAyB,EAAgB,eAAe,EAAE,MAAM,eAAe,CAAC;AACzF,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EACxB,8BAA8B,EAC9B,qBAAqB,EACrB,iBAAiB,EAIjB,cAAc,EACf,MAAM,YAAY,CAAC;AAyBpB,qBAAa,gCAAiC,YAAW,yBAAyB;IAChF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA4B;IAC1D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgC;IAC/D,OAAO,CAAC,KAAK,CAAgD;IAC7D,OAAO,CAAC,qBAAqB,CAAkC;IAC/D,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,UAAU,CAAS;IAE3B;;;;;;;;;;;;;;;OAeG;gBAED,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,EACnC,aAAa,CAAC,EAAE,aAAa,EAC7B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC;IAa9C,IAAI,CAAC,KAAK,EAAE,yBAAyB,GAAG,qBAAqB;IAgD7D,OAAO,CAAC,WAAW;IAqDnB,OAAO,CAAC,cAAc;IAgDtB,OAAO,CAAC,eAAe;IAqCvB,OAAO,CAAC,oBAAoB;IA8B5B,OAAO,CAAC,aAAa;IA6BrB,OAAO,CAAC,UAAU;IAoElB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,wBAAwB;IAUhC,OAAO,CAAC,eAAe;IAyBvB,OAAO,CAAC,OAAO;IAcf,OAAO,CAAC,aAAa;IASrB,QAAQ,IAAI,2BAA2B;IAmBvC,WAAW,IAAI,SAAS,wBAAwB,EAAE;IAMlD,MAAM,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,eAAe,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,8BAA8B;CAcrG;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,EACnC,aAAa,CAAC,EAAE,aAAa,EAC7B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAC3C,yBAAyB,CAE3B"}
|