@loomwork/llm 0.0.0-stage → 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 +202 -0
- package/NOTICE +8 -0
- package/README.md +80 -2
- package/dist/assembleStream.d.ts +95 -0
- package/dist/assembleStream.d.ts.map +1 -0
- package/dist/assembleStream.js +180 -0
- package/dist/assembleStream.js.map +1 -0
- package/dist/capabilities.d.ts +43 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +77 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/createLlmEffect.d.ts +110 -0
- package/dist/createLlmEffect.d.ts.map +1 -0
- package/dist/createLlmEffect.js +177 -0
- package/dist/createLlmEffect.js.map +1 -0
- package/dist/errors.d.ts +96 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +280 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/parts.d.ts +220 -0
- package/dist/parts.d.ts.map +1 -0
- package/dist/parts.js +231 -0
- package/dist/parts.js.map +1 -0
- package/dist/providers/AnthropicProvider.d.ts +53 -0
- package/dist/providers/AnthropicProvider.d.ts.map +1 -0
- package/dist/providers/AnthropicProvider.js +443 -0
- package/dist/providers/AnthropicProvider.js.map +1 -0
- package/dist/providers/GeminiProvider.d.ts +66 -0
- package/dist/providers/GeminiProvider.d.ts.map +1 -0
- package/dist/providers/GeminiProvider.js +281 -0
- package/dist/providers/GeminiProvider.js.map +1 -0
- package/dist/providers/OpenAiProvider.d.ts +56 -0
- package/dist/providers/OpenAiProvider.d.ts.map +1 -0
- package/dist/providers/OpenAiProvider.js +402 -0
- package/dist/providers/OpenAiProvider.js.map +1 -0
- package/dist/providers/extraHeaders.d.ts +7 -0
- package/dist/providers/extraHeaders.d.ts.map +1 -0
- package/dist/providers/extraHeaders.js +40 -0
- package/dist/providers/extraHeaders.js.map +1 -0
- package/dist/providers/systemPrompt.d.ts +10 -0
- package/dist/providers/systemPrompt.d.ts.map +1 -0
- package/dist/providers/systemPrompt.js +22 -0
- package/dist/providers/systemPrompt.js.map +1 -0
- package/dist/reasoning.d.ts +154 -0
- package/dist/reasoning.d.ts.map +1 -0
- package/dist/reasoning.js +256 -0
- package/dist/reasoning.js.map +1 -0
- package/dist/resolveContent.d.ts +74 -0
- package/dist/resolveContent.d.ts.map +1 -0
- package/dist/resolveContent.js +335 -0
- package/dist/resolveContent.js.map +1 -0
- package/dist/types.d.ts +152 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/untrusted.d.ts +91 -0
- package/dist/untrusted.d.ts.map +1 -0
- package/dist/untrusted.js +385 -0
- package/dist/untrusted.js.map +1 -0
- package/package.json +54 -3
- package/src/assembleStream.ts +219 -0
- package/src/capabilities.ts +96 -0
- package/src/createLlmEffect.ts +287 -0
- package/src/errors.ts +269 -0
- package/src/index.ts +137 -0
- package/src/parts.ts +409 -0
- package/src/providers/AnthropicProvider.ts +550 -0
- package/src/providers/GeminiProvider.ts +380 -0
- package/src/providers/OpenAiProvider.ts +511 -0
- package/src/providers/extraHeaders.ts +41 -0
- package/src/providers/systemPrompt.ts +19 -0
- package/src/reasoning.ts +386 -0
- package/src/resolveContent.ts +425 -0
- package/src/types.ts +175 -0
- package/src/untrusted.ts +440 -0
package/dist/parts.js
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TaintedContentError = void 0;
|
|
4
|
+
exports.toParts = toParts;
|
|
5
|
+
exports.textOf = textOf;
|
|
6
|
+
exports.hasStructuredParts = hasStructuredParts;
|
|
7
|
+
exports.layoutOf = layoutOf;
|
|
8
|
+
exports.assistantMessageOf = assistantMessageOf;
|
|
9
|
+
exports.withoutReasoningParts = withoutReasoningParts;
|
|
10
|
+
exports.hasReasoningParts = hasReasoningParts;
|
|
11
|
+
exports.base64ByteLength = base64ByteLength;
|
|
12
|
+
const classify_1 = require("@loomwork/classify");
|
|
13
|
+
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
14
|
+
/** Normalise message content to its parts form (a string becomes one text part). */
|
|
15
|
+
function toParts(content) {
|
|
16
|
+
return typeof content === "string" ? [{ type: "text", text: content }] : content;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Thrown by {@link textOf} when handed a `tainted()` wrapper (`{ __loomTainted, value }`) instead
|
|
20
|
+
* of message content. A wrapper is neither a string nor parts; reading it as text would either
|
|
21
|
+
* crash obscurely or, worse, silently drop the provenance. The message never echoes the content.
|
|
22
|
+
*/
|
|
23
|
+
class TaintedContentError extends Error {
|
|
24
|
+
/** The `origin` recorded when the content was tainted. */
|
|
25
|
+
origin;
|
|
26
|
+
constructor(origin) {
|
|
27
|
+
super(`textOf() was given tainted content from "${origin}": untrusted data wrapped by tainted(), not message text. Unwrap it deliberately with unwrapTainted() (or, in a conversation summarizer, summarizerText() from @loomwork/conversation) and treat the result as DATA - never place it in an instruction position.`);
|
|
28
|
+
this.name = "TaintedContentError";
|
|
29
|
+
this.origin = origin;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.TaintedContentError = TaintedContentError;
|
|
33
|
+
/**
|
|
34
|
+
* The text of a message: the string itself, or its text parts joined (including text
|
|
35
|
+
* inside `tool_result`s, which is what a text-only consumer wants to read). Media and
|
|
36
|
+
* `tool_use` parts contribute nothing.
|
|
37
|
+
*
|
|
38
|
+
* Throws {@link TaintedContentError} on a `tainted()` wrapper - at the top level, in a text part's
|
|
39
|
+
* `text`, or in a `tool_result`'s `content` (or its text parts): unwrap it on purpose first.
|
|
40
|
+
*/
|
|
41
|
+
function textOf(content) {
|
|
42
|
+
if (typeof content === "string")
|
|
43
|
+
return content;
|
|
44
|
+
if ((0, classify_1.isTainted)(content))
|
|
45
|
+
throw new TaintedContentError(content.__loomTainted.origin);
|
|
46
|
+
let out = "";
|
|
47
|
+
for (const p of content) {
|
|
48
|
+
if ((0, classify_1.isTainted)(p))
|
|
49
|
+
throw new TaintedContentError(p.__loomTainted.origin); // off-type: a wrapper as a part
|
|
50
|
+
if (p.type === "text")
|
|
51
|
+
out += plainText(p.text);
|
|
52
|
+
else if (p.type === "tool_result") {
|
|
53
|
+
const c = p.content;
|
|
54
|
+
if ((0, classify_1.isTainted)(c))
|
|
55
|
+
throw new TaintedContentError(c.__loomTainted.origin);
|
|
56
|
+
if (typeof c === "string")
|
|
57
|
+
out += c;
|
|
58
|
+
else
|
|
59
|
+
for (const r of c) {
|
|
60
|
+
// an off-type wrapper used as an element of the parts is refused like any other
|
|
61
|
+
if ((0, classify_1.isTainted)(r))
|
|
62
|
+
throw new TaintedContentError(r.__loomTainted.origin);
|
|
63
|
+
if (r.type === "text")
|
|
64
|
+
out += plainText(r.text);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
/** A text slot's string; a `tainted()` wrapper nested in a part is refused like a top-level one. */
|
|
71
|
+
function plainText(text) {
|
|
72
|
+
if ((0, classify_1.isTainted)(text))
|
|
73
|
+
throw new TaintedContentError(text.__loomTainted.origin);
|
|
74
|
+
return text;
|
|
75
|
+
}
|
|
76
|
+
/** Whether a message carries any non-text part. */
|
|
77
|
+
function hasStructuredParts(content) {
|
|
78
|
+
return typeof content !== "string" && content.some((p) => p.type !== "text");
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The layout to record for a response, or `undefined` when none is needed: no reasoning (the shape
|
|
82
|
+
* stays exactly today's, G2) or the canonical order. Zero-length text blocks are dropped (a provider
|
|
83
|
+
* rejects an empty text block, so there is nothing to reproduce).
|
|
84
|
+
*/
|
|
85
|
+
function layoutOf(entries) {
|
|
86
|
+
const kept = entries.filter((e) => typeof e !== "object" || !("text" in e) || e.text > 0);
|
|
87
|
+
if (!kept.includes("reasoning"))
|
|
88
|
+
return undefined;
|
|
89
|
+
// canonical: "reasoning"*, at most one text, calls*. Phase 0 = reasoning, 1 = after the text, 2 = calls.
|
|
90
|
+
let phase = 0;
|
|
91
|
+
let canonical = true;
|
|
92
|
+
for (const e of kept) {
|
|
93
|
+
if (e === "reasoning") {
|
|
94
|
+
if (phase !== 0)
|
|
95
|
+
canonical = false;
|
|
96
|
+
}
|
|
97
|
+
else if ("text" in e) {
|
|
98
|
+
if (phase !== 0)
|
|
99
|
+
canonical = false;
|
|
100
|
+
phase = 1;
|
|
101
|
+
}
|
|
102
|
+
else
|
|
103
|
+
phase = 2;
|
|
104
|
+
}
|
|
105
|
+
return canonical ? undefined : kept.map((e) => (typeof e === "object" ? { ...e } : e));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The `assistant` message that records a model response — text (when any) then one
|
|
109
|
+
* `tool_use` part per call — so the next turn's `tool_result`s have something to
|
|
110
|
+
* answer. A response with neither text nor calls yields an empty text part rather than
|
|
111
|
+
* an empty array (providers reject empty content).
|
|
112
|
+
*
|
|
113
|
+
* With a `layout` (ADR 0133 D5) the parts come back in the vendor's own order, text blocks at their
|
|
114
|
+
* positions. A layout that does not fit the response (malformed, text lengths not summing to `content`,
|
|
115
|
+
* or a reasoning count that differs) drops every reasoning part rather than reorder them; a named call
|
|
116
|
+
* that is missing drops the reasoning parts after it; calls it does not name go at the end.
|
|
117
|
+
*/
|
|
118
|
+
function assistantMessageOf(response) {
|
|
119
|
+
const recorded = [];
|
|
120
|
+
for (const r of response.reasoning ?? []) {
|
|
121
|
+
if (r.type === "reasoning")
|
|
122
|
+
recorded.push(r);
|
|
123
|
+
}
|
|
124
|
+
const parts = laidOut(response, recorded) ?? canonicalParts(response, recorded);
|
|
125
|
+
if (!parts.some((p) => p.type === "text" || p.type === "tool_use")) {
|
|
126
|
+
parts.push({ type: "text", text: "" });
|
|
127
|
+
}
|
|
128
|
+
return { role: "assistant", content: parts };
|
|
129
|
+
}
|
|
130
|
+
function toolUse(c) {
|
|
131
|
+
return {
|
|
132
|
+
type: "tool_use",
|
|
133
|
+
id: c.id,
|
|
134
|
+
name: c.name,
|
|
135
|
+
input: c.input,
|
|
136
|
+
...(c.signature !== undefined && { signature: c.signature }),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function canonicalParts(response, recorded) {
|
|
140
|
+
const parts = [...recorded];
|
|
141
|
+
if (response.content !== "")
|
|
142
|
+
parts.push({ type: "text", text: response.content });
|
|
143
|
+
for (const c of response.toolCalls ?? [])
|
|
144
|
+
parts.push(toolUse(c));
|
|
145
|
+
return parts;
|
|
146
|
+
}
|
|
147
|
+
function laidOut(response, recorded) {
|
|
148
|
+
const layout = response.layout;
|
|
149
|
+
if (layout === undefined || layout.length === 0)
|
|
150
|
+
return undefined;
|
|
151
|
+
// A thinking block is valid only while everything before it is unchanged, so a layout that cannot be
|
|
152
|
+
// replayed exactly must never be "repaired" by moving blocks (a 400 on a preserved-thinking account).
|
|
153
|
+
// When it does not fit at all, every reasoning part is dropped instead: stripping is always valid.
|
|
154
|
+
let total = 0;
|
|
155
|
+
let reasoningEntries = 0;
|
|
156
|
+
for (const e of layout) {
|
|
157
|
+
if (e === "reasoning")
|
|
158
|
+
reasoningEntries++;
|
|
159
|
+
else if (typeof e === "object" &&
|
|
160
|
+
e !== null &&
|
|
161
|
+
typeof e.text === "number") {
|
|
162
|
+
total += e.text;
|
|
163
|
+
}
|
|
164
|
+
else if (typeof e !== "object" ||
|
|
165
|
+
e === null ||
|
|
166
|
+
typeof e.call !== "string") {
|
|
167
|
+
return canonicalParts(response, []);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (total !== response.content.length || reasoningEntries !== recorded.length) {
|
|
171
|
+
return canonicalParts(response, []);
|
|
172
|
+
}
|
|
173
|
+
const calls = new Map((response.toolCalls ?? []).map((c) => [c.id, c]));
|
|
174
|
+
const used = new Set();
|
|
175
|
+
const parts = [];
|
|
176
|
+
let nextReasoning = 0;
|
|
177
|
+
let offset = 0;
|
|
178
|
+
// Once a named call is missing (screened out by the loop), every later block's prefix has changed:
|
|
179
|
+
// drop the reasoning parts from there on (a suffix drop), keep the earlier ones.
|
|
180
|
+
let prefixChanged = false;
|
|
181
|
+
for (const e of layout) {
|
|
182
|
+
if (e === "reasoning") {
|
|
183
|
+
const r = recorded[nextReasoning++];
|
|
184
|
+
if (!prefixChanged)
|
|
185
|
+
parts.push(r);
|
|
186
|
+
}
|
|
187
|
+
else if ("text" in e) {
|
|
188
|
+
parts.push({ type: "text", text: response.content.slice(offset, offset + e.text) });
|
|
189
|
+
offset += e.text;
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
const c = calls.get(e.call);
|
|
193
|
+
if (c !== undefined && !used.has(e.call)) {
|
|
194
|
+
used.add(e.call);
|
|
195
|
+
parts.push(toolUse(c));
|
|
196
|
+
}
|
|
197
|
+
else
|
|
198
|
+
prefixChanged = true;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// A call the layout did not name goes after every block, so it changes no block's prefix.
|
|
202
|
+
for (const c of response.toolCalls ?? [])
|
|
203
|
+
if (!used.has(c.id))
|
|
204
|
+
parts.push(toolUse(c));
|
|
205
|
+
return parts;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* ADR 0133 D5 - the same message without its `reasoning` parts (the edit-point drop). Returns the
|
|
209
|
+
* SAME object when it holds none, so callers can compare by identity; tool-call signatures are never
|
|
210
|
+
* touched. A message left empty keeps the shape `assistantMessageOf` gives an empty turn.
|
|
211
|
+
*/
|
|
212
|
+
function withoutReasoningParts(message) {
|
|
213
|
+
const content = message.content;
|
|
214
|
+
if (!Array.isArray(content) || !content.some((p) => p?.type === "reasoning"))
|
|
215
|
+
return message;
|
|
216
|
+
const kept = content.filter((p) => p?.type !== "reasoning");
|
|
217
|
+
return { ...message, content: kept.length > 0 ? kept : [{ type: "text", text: "" }] };
|
|
218
|
+
}
|
|
219
|
+
/** Whether a message holds a `reasoning` part. */
|
|
220
|
+
function hasReasoningParts(message) {
|
|
221
|
+
return Array.isArray(message.content) && message.content.some((p) => p?.type === "reasoning");
|
|
222
|
+
}
|
|
223
|
+
const BASE64 = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
224
|
+
/** Decoded byte length of a base64 string, or `undefined` if it is not valid base64. */
|
|
225
|
+
function base64ByteLength(data) {
|
|
226
|
+
if (data.length % 4 !== 0 || !BASE64.test(data))
|
|
227
|
+
return undefined;
|
|
228
|
+
const pad = data.endsWith("==") ? 2 : data.endsWith("=") ? 1 : 0;
|
|
229
|
+
return (data.length / 4) * 3 - pad;
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=parts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.js","sourceRoot":"","sources":["../src/parts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type LlmCapabilities } from "../capabilities";
|
|
2
|
+
import { type LlmContentPart } from "../parts";
|
|
3
|
+
import type { LlmProvider, LlmRequest, LlmResponse, LlmStreamChunk } from "../types";
|
|
4
|
+
export interface AnthropicProviderConfig {
|
|
5
|
+
/**
|
|
6
|
+
* Extra request headers sent on every request (for example `anthropic-workspace-id`). Header
|
|
7
|
+
* names and values must be strings without CR/LF; a header the provider sets itself (auth,
|
|
8
|
+
* protocol, content type) cannot be overridden and throws at construction. Unset, the request
|
|
9
|
+
* is unchanged.
|
|
10
|
+
*/
|
|
11
|
+
headers?: Readonly<Record<string, string>>;
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
baseUrl?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Cap on a complete response body, in bytes after decompression (default 8 MiB). Over it the
|
|
17
|
+
* body is cancelled and `LlmResponseLimitError` (provider and reason only) is thrown.
|
|
18
|
+
*/
|
|
19
|
+
maxResponseBytes?: number;
|
|
20
|
+
/** Cap on the total bytes read from a stream (default 128 MiB); same error. */
|
|
21
|
+
maxStreamBytes?: number;
|
|
22
|
+
/** Cap on one line of a stream, in UTF-8 bytes (default 1 MiB); same error. */
|
|
23
|
+
maxLineBytes?: number;
|
|
24
|
+
/** Override the declared modalities (e.g. a model without vision). */
|
|
25
|
+
capabilities?: LlmCapabilities;
|
|
26
|
+
/**
|
|
27
|
+
* Extended thinking, passed through as the request's `thinking` (ADR 0133). `display: "summarized"`
|
|
28
|
+
* asks for a readable summary; the default is the API's (omitted on current models, where only the
|
|
29
|
+
* signature is returned). Unset, no `thinking` is sent.
|
|
30
|
+
*/
|
|
31
|
+
thinking?: {
|
|
32
|
+
type: "adaptive";
|
|
33
|
+
display?: "summarized" | "omitted";
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** SPI part → Anthropic content block. Exported for tests. */
|
|
37
|
+
export declare function mapPart(p: LlmContentPart): Record<string, unknown>;
|
|
38
|
+
export declare class AnthropicProvider implements LlmProvider {
|
|
39
|
+
private readonly apiKey;
|
|
40
|
+
private readonly model;
|
|
41
|
+
private readonly baseUrl;
|
|
42
|
+
private readonly maxResponseBytes;
|
|
43
|
+
private readonly maxStreamBytes;
|
|
44
|
+
private readonly maxLineBytes;
|
|
45
|
+
private readonly thinking;
|
|
46
|
+
private readonly extraHeaders;
|
|
47
|
+
readonly capabilities: LlmCapabilities;
|
|
48
|
+
constructor(config?: AnthropicProviderConfig);
|
|
49
|
+
private buildBody;
|
|
50
|
+
complete(request: LlmRequest): Promise<LlmResponse>;
|
|
51
|
+
stream(request: LlmRequest): AsyncIterable<LlmStreamChunk>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=AnthropicProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnthropicProvider.d.ts","sourceRoot":"","sources":["../../src/providers/AnthropicProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EAGrB,MAAM,iBAAiB,CAAC;AAYzB,OAAO,EACL,KAAK,cAAc,EAMpB,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAEV,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EAEf,MAAM,UAAU,CAAC;AAelB,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,OAAO,CAAC,EAAE,YAAY,GAAG,SAAS,CAAA;KAAE,CAAC;CACrE;AAmBD,8DAA8D;AAC9D,wBAAgB,OAAO,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgClE;AAiFD,qBAAa,iBAAkB,YAAW,WAAW;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;IAC/D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmC;IAChE,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;gBAE3B,MAAM,GAAE,uBAA4B;IA+BhD,OAAO,CAAC,SAAS;IA4BX,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IA6DlD,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,aAAa,CAAC,cAAc,CAAC;CAkNlE"}
|