@kubuild/ai 0.3.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 +21 -0
- package/dist/chunk-27AY2KBI.js +500 -0
- package/dist/chunk-27AY2KBI.js.map +1 -0
- package/dist/chunk-JY4NHD3Q.js +227 -0
- package/dist/chunk-JY4NHD3Q.js.map +1 -0
- package/dist/chunk-UH24LHRY.js +443 -0
- package/dist/chunk-UH24LHRY.js.map +1 -0
- package/dist/client/ai-client.d.ts +59 -0
- package/dist/client/ai-client.d.ts.map +1 -0
- package/dist/client/index.cjs +254 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +9 -0
- package/dist/client/index.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/normalizer.d.ts +9 -0
- package/dist/core/normalizer.d.ts.map +1 -0
- package/dist/core/prompt-compiler.d.ts +10 -0
- package/dist/core/prompt-compiler.d.ts.map +1 -0
- package/dist/index.cjs +468 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.cjs +584 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +336 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/use-ai-chat.d.ts +63 -0
- package/dist/react/use-ai-chat.d.ts.map +1 -0
- package/dist/react/use-ai-generator.d.ts +19 -0
- package/dist/react/use-ai-generator.d.ts.map +1 -0
- package/dist/server/adapters/anthropic.d.ts +30 -0
- package/dist/server/adapters/anthropic.d.ts.map +1 -0
- package/dist/server/adapters/base.d.ts +2 -0
- package/dist/server/adapters/base.d.ts.map +1 -0
- package/dist/server/adapters/custom.d.ts +18 -0
- package/dist/server/adapters/custom.d.ts.map +1 -0
- package/dist/server/adapters/gemini.d.ts +22 -0
- package/dist/server/adapters/gemini.d.ts.map +1 -0
- package/dist/server/adapters/index.cjs +529 -0
- package/dist/server/adapters/index.cjs.map +1 -0
- package/dist/server/adapters/index.d.ts +6 -0
- package/dist/server/adapters/index.d.ts.map +1 -0
- package/dist/server/adapters/index.js +13 -0
- package/dist/server/adapters/index.js.map +1 -0
- package/dist/server/adapters/openai.d.ts +26 -0
- package/dist/server/adapters/openai.d.ts.map +1 -0
- package/dist/server/adapters/stream-utils.d.ts +12 -0
- package/dist/server/adapters/stream-utils.d.ts.map +1 -0
- package/dist/server/engine.d.ts +59 -0
- package/dist/server/engine.d.ts.map +1 -0
- package/dist/server/handler.d.ts +66 -0
- package/dist/server/handler.d.ts.map +1 -0
- package/dist/server/index.cjs +1824 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +890 -0
- package/dist/server/index.js.map +1 -0
- package/dist/types.d.ts +184 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// src/client/ai-client.ts
|
|
2
|
+
var KubuildAiClient = class {
|
|
3
|
+
endpoint;
|
|
4
|
+
headers;
|
|
5
|
+
fetchFn;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
if (!options.endpoint) {
|
|
8
|
+
throw new Error("KubuildAiClient requires an endpoint URL");
|
|
9
|
+
}
|
|
10
|
+
this.endpoint = options.endpoint;
|
|
11
|
+
this.headers = options.headers;
|
|
12
|
+
this.fetchFn = options.fetch || globalThis.fetch.bind(globalThis);
|
|
13
|
+
}
|
|
14
|
+
async resolveHeaders() {
|
|
15
|
+
if (!this.headers) return {};
|
|
16
|
+
if (typeof this.headers === "function") {
|
|
17
|
+
return await this.headers();
|
|
18
|
+
}
|
|
19
|
+
return this.headers;
|
|
20
|
+
}
|
|
21
|
+
async sendRequest(body, signal) {
|
|
22
|
+
const dynamicHeaders = await this.resolveHeaders();
|
|
23
|
+
const res = await this.fetchFn(this.endpoint, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: {
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
...dynamicHeaders
|
|
28
|
+
},
|
|
29
|
+
body: JSON.stringify(body),
|
|
30
|
+
signal
|
|
31
|
+
});
|
|
32
|
+
const json = await res.json();
|
|
33
|
+
if (!res.ok || !json.success || !json.data) {
|
|
34
|
+
const errMessage = json?.error?.message || `HTTP ${res.status}: ${res.statusText}`;
|
|
35
|
+
const error = new Error(errMessage);
|
|
36
|
+
error.code = json?.error?.code;
|
|
37
|
+
error.details = json?.error?.details;
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
return json.data;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Standard single-pass full page generator (non-streaming).
|
|
44
|
+
*/
|
|
45
|
+
async generatePage(params, options) {
|
|
46
|
+
return this.sendRequest(
|
|
47
|
+
{
|
|
48
|
+
mode: "full-page",
|
|
49
|
+
...params
|
|
50
|
+
},
|
|
51
|
+
options?.signal
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Low-level SSE frame consumer shared by every streaming method on this client
|
|
56
|
+
* (`streamPage`, `chatStream`) — one transport implementation, reused rather than
|
|
57
|
+
* duplicated per stream "flavor" (STORA-515).
|
|
58
|
+
*
|
|
59
|
+
* Reads `res.body`, decodes `data: <json>\n\n` frames into `AiStreamEvent`s, and
|
|
60
|
+
* invokes `onEvent` for each one in arrival order. If `onEvent` throws (the
|
|
61
|
+
* conventional way callers signal a fatal `error` event), the throw propagates out of
|
|
62
|
+
* this method after the reader lock is released.
|
|
63
|
+
*/
|
|
64
|
+
async consumeSse(res, onEvent) {
|
|
65
|
+
if (!res.body) {
|
|
66
|
+
throw new Error("Response body is null, cannot stream");
|
|
67
|
+
}
|
|
68
|
+
const reader = res.body.getReader();
|
|
69
|
+
const decoder = new TextDecoder();
|
|
70
|
+
let buffer = "";
|
|
71
|
+
try {
|
|
72
|
+
while (true) {
|
|
73
|
+
const { done, value } = await reader.read();
|
|
74
|
+
if (done) break;
|
|
75
|
+
buffer += decoder.decode(value, { stream: true });
|
|
76
|
+
const parts = buffer.split("\n\n");
|
|
77
|
+
buffer = parts.pop() || "";
|
|
78
|
+
for (const part of parts) {
|
|
79
|
+
const lines = part.split("\n");
|
|
80
|
+
for (const line of lines) {
|
|
81
|
+
if (line.startsWith("data: ")) {
|
|
82
|
+
let event;
|
|
83
|
+
try {
|
|
84
|
+
event = JSON.parse(line.slice(6).trim());
|
|
85
|
+
} catch {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
onEvent(event);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
} finally {
|
|
94
|
+
reader.releaseLock();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Progressive section streamer (SSE).
|
|
99
|
+
* Calls callbacks on each event (status, metadata, section, complete).
|
|
100
|
+
*/
|
|
101
|
+
async streamPage(params, callbacks, options) {
|
|
102
|
+
const dynamicHeaders = await this.resolveHeaders();
|
|
103
|
+
const res = await this.fetchFn(this.endpoint, {
|
|
104
|
+
method: "POST",
|
|
105
|
+
headers: {
|
|
106
|
+
"Content-Type": "application/json",
|
|
107
|
+
...dynamicHeaders
|
|
108
|
+
},
|
|
109
|
+
body: JSON.stringify({
|
|
110
|
+
mode: "full-page",
|
|
111
|
+
stream: true,
|
|
112
|
+
...params
|
|
113
|
+
}),
|
|
114
|
+
signal: options?.signal
|
|
115
|
+
});
|
|
116
|
+
if (!res.ok) {
|
|
117
|
+
const errText = await res.text().catch(() => "");
|
|
118
|
+
const err = new Error(`Streaming failed [${res.status} ${res.statusText}]: ${errText}`);
|
|
119
|
+
callbacks?.onError?.(err);
|
|
120
|
+
throw err;
|
|
121
|
+
}
|
|
122
|
+
let finalDoc = null;
|
|
123
|
+
await this.consumeSse(res, (event) => {
|
|
124
|
+
if (event.type === "status") {
|
|
125
|
+
callbacks?.onStatus?.(event.message);
|
|
126
|
+
} else if (event.type === "metadata") {
|
|
127
|
+
callbacks?.onMetadata?.(event.metadata, event.rootPageNode);
|
|
128
|
+
} else if (event.type === "section") {
|
|
129
|
+
callbacks?.onSection?.(event.section, event.index, event.total);
|
|
130
|
+
} else if (event.type === "complete") {
|
|
131
|
+
finalDoc = event.document;
|
|
132
|
+
callbacks?.onComplete?.(event.document);
|
|
133
|
+
} else if (event.type === "error") {
|
|
134
|
+
const err = new Error(event.error.message || "Stream error");
|
|
135
|
+
err.code = event.error.code;
|
|
136
|
+
callbacks?.onError?.(err);
|
|
137
|
+
throw err;
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
if (!finalDoc) {
|
|
141
|
+
throw new Error("Stream ended without receiving complete document");
|
|
142
|
+
}
|
|
143
|
+
return finalDoc;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Token-level streaming chat (STORA-515). Calls `onChatChunk` for every partial chunk
|
|
147
|
+
* as it arrives and resolves with the fully assembled assistant `AiChatMessage` once
|
|
148
|
+
* the stream's terminal `chat-complete` event is received. Reuses the exact same SSE
|
|
149
|
+
* transport as `streamPage` via `consumeSse` — no separate parsing path.
|
|
150
|
+
*/
|
|
151
|
+
async chatStream(params, callbacks, options) {
|
|
152
|
+
const dynamicHeaders = await this.resolveHeaders();
|
|
153
|
+
const res = await this.fetchFn(this.endpoint, {
|
|
154
|
+
method: "POST",
|
|
155
|
+
headers: {
|
|
156
|
+
"Content-Type": "application/json",
|
|
157
|
+
...dynamicHeaders
|
|
158
|
+
},
|
|
159
|
+
body: JSON.stringify({
|
|
160
|
+
mode: "chat",
|
|
161
|
+
stream: true,
|
|
162
|
+
...params
|
|
163
|
+
}),
|
|
164
|
+
signal: options?.signal
|
|
165
|
+
});
|
|
166
|
+
if (!res.ok) {
|
|
167
|
+
const errText = await res.text().catch(() => "");
|
|
168
|
+
const err = new Error(`Chat streaming failed [${res.status} ${res.statusText}]: ${errText}`);
|
|
169
|
+
callbacks?.onError?.(err);
|
|
170
|
+
throw err;
|
|
171
|
+
}
|
|
172
|
+
let finalMessage = null;
|
|
173
|
+
await this.consumeSse(res, (event) => {
|
|
174
|
+
if (event.type === "chat-chunk") {
|
|
175
|
+
callbacks?.onChatChunk?.(event.delta, event.content);
|
|
176
|
+
} else if (event.type === "chat-complete") {
|
|
177
|
+
finalMessage = event.message;
|
|
178
|
+
callbacks?.onChatComplete?.(event.message);
|
|
179
|
+
} else if (event.type === "error") {
|
|
180
|
+
const err = new Error(event.error.message || "Stream error");
|
|
181
|
+
err.code = event.error.code;
|
|
182
|
+
callbacks?.onError?.(err);
|
|
183
|
+
throw err;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
if (!finalMessage) {
|
|
187
|
+
throw new Error("Chat stream ended without receiving a complete message");
|
|
188
|
+
}
|
|
189
|
+
return finalMessage;
|
|
190
|
+
}
|
|
191
|
+
async generateSection(params, options) {
|
|
192
|
+
return this.sendRequest(
|
|
193
|
+
{
|
|
194
|
+
mode: "section",
|
|
195
|
+
...params
|
|
196
|
+
},
|
|
197
|
+
options?.signal
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
async refactorNode(params, options) {
|
|
201
|
+
return this.sendRequest(
|
|
202
|
+
{
|
|
203
|
+
mode: "refactor",
|
|
204
|
+
...params
|
|
205
|
+
},
|
|
206
|
+
options?.signal
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
async chat(params, options) {
|
|
210
|
+
return this.sendRequest(
|
|
211
|
+
{
|
|
212
|
+
mode: "chat",
|
|
213
|
+
...params
|
|
214
|
+
},
|
|
215
|
+
options?.signal
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
function createAiClient(options) {
|
|
220
|
+
return new KubuildAiClient(options);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export {
|
|
224
|
+
KubuildAiClient,
|
|
225
|
+
createAiClient
|
|
226
|
+
};
|
|
227
|
+
//# sourceMappingURL=chunk-JY4NHD3Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/ai-client.ts"],"sourcesContent":["import type { PageDocument, Node } from '@kubuild/schema';\nimport type {\n AiGeneratePageRequest,\n AiGenerateSectionRequest,\n AiRefactorNodeRequest,\n AiChatRequest,\n AiChatResponse,\n AiChatMessage,\n AiGenerateResponse,\n AiStreamCallbacks,\n AiStreamEvent,\n} from '../types';\n\nexport interface AiClientOptions {\n endpoint: string;\n headers?:\n | Record<string, string>\n | (() => Promise<Record<string, string>> | Record<string, string>);\n fetch?: typeof fetch;\n}\n\nexport class KubuildAiClient {\n private endpoint: string;\n private headers?: AiClientOptions['headers'];\n private fetchFn: typeof fetch;\n\n constructor(options: AiClientOptions) {\n if (!options.endpoint) {\n throw new Error('KubuildAiClient requires an endpoint URL');\n }\n this.endpoint = options.endpoint;\n this.headers = options.headers;\n this.fetchFn = options.fetch || globalThis.fetch.bind(globalThis);\n }\n\n private async resolveHeaders(): Promise<Record<string, string>> {\n if (!this.headers) return {};\n if (typeof this.headers === 'function') {\n return await this.headers();\n }\n return this.headers;\n }\n\n private async sendRequest<T>(\n body: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<T> {\n const dynamicHeaders = await this.resolveHeaders();\n\n const res = await this.fetchFn(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...dynamicHeaders,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n const json = (await res.json()) as AiGenerateResponse<T>;\n\n if (!res.ok || !json.success || !json.data) {\n const errMessage = json?.error?.message || `HTTP ${res.status}: ${res.statusText}`;\n const error = new Error(errMessage);\n (error as unknown as { code?: string; details?: unknown }).code = json?.error?.code;\n (error as unknown as { code?: string; details?: unknown }).details = json?.error?.details;\n throw error;\n }\n\n return json.data;\n }\n\n /**\n * Standard single-pass full page generator (non-streaming).\n */\n async generatePage(\n params: AiGeneratePageRequest,\n options?: { signal?: AbortSignal },\n ): Promise<PageDocument> {\n return this.sendRequest<PageDocument>(\n {\n mode: 'full-page',\n ...params,\n },\n options?.signal,\n );\n }\n\n /**\n * Low-level SSE frame consumer shared by every streaming method on this client\n * (`streamPage`, `chatStream`) — one transport implementation, reused rather than\n * duplicated per stream \"flavor\" (STORA-515).\n *\n * Reads `res.body`, decodes `data: <json>\\n\\n` frames into `AiStreamEvent`s, and\n * invokes `onEvent` for each one in arrival order. If `onEvent` throws (the\n * conventional way callers signal a fatal `error` event), the throw propagates out of\n * this method after the reader lock is released.\n */\n private async consumeSse(\n res: Response,\n onEvent: (event: AiStreamEvent) => void,\n ): Promise<void> {\n if (!res.body) {\n throw new Error('Response body is null, cannot stream');\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split('\\n\\n');\n buffer = parts.pop() || '';\n\n for (const part of parts) {\n const lines = part.split('\\n');\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n let event: AiStreamEvent;\n try {\n event = JSON.parse(line.slice(6).trim()) as AiStreamEvent;\n } catch {\n // Ignore incomplete or non-JSON data frames\n continue;\n }\n onEvent(event);\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Progressive section streamer (SSE).\n * Calls callbacks on each event (status, metadata, section, complete).\n */\n async streamPage(\n params: AiGeneratePageRequest,\n callbacks?: AiStreamCallbacks,\n options?: { signal?: AbortSignal },\n ): Promise<PageDocument> {\n const dynamicHeaders = await this.resolveHeaders();\n\n const res = await this.fetchFn(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...dynamicHeaders,\n },\n body: JSON.stringify({\n mode: 'full-page',\n stream: true,\n ...params,\n }),\n signal: options?.signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n const err = new Error(`Streaming failed [${res.status} ${res.statusText}]: ${errText}`);\n callbacks?.onError?.(err);\n throw err;\n }\n\n let finalDoc: PageDocument | null = null;\n\n await this.consumeSse(res, (event) => {\n if (event.type === 'status') {\n callbacks?.onStatus?.(event.message);\n } else if (event.type === 'metadata') {\n callbacks?.onMetadata?.(event.metadata, event.rootPageNode);\n } else if (event.type === 'section') {\n callbacks?.onSection?.(event.section, event.index, event.total);\n } else if (event.type === 'complete') {\n finalDoc = event.document;\n callbacks?.onComplete?.(event.document);\n } else if (event.type === 'error') {\n const err = new Error(event.error.message || 'Stream error');\n (err as unknown as { code?: string }).code = event.error.code;\n callbacks?.onError?.(err);\n throw err;\n }\n });\n\n if (!finalDoc) {\n throw new Error('Stream ended without receiving complete document');\n }\n\n return finalDoc;\n }\n\n /**\n * Token-level streaming chat (STORA-515). Calls `onChatChunk` for every partial chunk\n * as it arrives and resolves with the fully assembled assistant `AiChatMessage` once\n * the stream's terminal `chat-complete` event is received. Reuses the exact same SSE\n * transport as `streamPage` via `consumeSse` — no separate parsing path.\n */\n async chatStream(\n params: AiChatRequest,\n callbacks?: Pick<AiStreamCallbacks, 'onChatChunk' | 'onChatComplete' | 'onError'>,\n options?: { signal?: AbortSignal },\n ): Promise<AiChatMessage> {\n const dynamicHeaders = await this.resolveHeaders();\n\n const res = await this.fetchFn(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...dynamicHeaders,\n },\n body: JSON.stringify({\n mode: 'chat',\n stream: true,\n ...params,\n }),\n signal: options?.signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n const err = new Error(`Chat streaming failed [${res.status} ${res.statusText}]: ${errText}`);\n callbacks?.onError?.(err);\n throw err;\n }\n\n let finalMessage: AiChatMessage | null = null;\n\n await this.consumeSse(res, (event) => {\n if (event.type === 'chat-chunk') {\n callbacks?.onChatChunk?.(event.delta, event.content);\n } else if (event.type === 'chat-complete') {\n finalMessage = event.message;\n callbacks?.onChatComplete?.(event.message);\n } else if (event.type === 'error') {\n const err = new Error(event.error.message || 'Stream error');\n (err as unknown as { code?: string }).code = event.error.code;\n callbacks?.onError?.(err);\n throw err;\n }\n });\n\n if (!finalMessage) {\n throw new Error('Chat stream ended without receiving a complete message');\n }\n\n return finalMessage;\n }\n\n async generateSection(\n params: AiGenerateSectionRequest,\n options?: { signal?: AbortSignal },\n ): Promise<Node> {\n return this.sendRequest<Node>(\n {\n mode: 'section',\n ...params,\n },\n options?.signal,\n );\n }\n\n async refactorNode(\n params: AiRefactorNodeRequest,\n options?: { signal?: AbortSignal },\n ): Promise<Node> {\n return this.sendRequest<Node>(\n {\n mode: 'refactor',\n ...params,\n },\n options?.signal,\n );\n }\n\n async chat(\n params: AiChatRequest,\n options?: { signal?: AbortSignal },\n ): Promise<AiChatResponse> {\n return this.sendRequest<AiChatResponse>(\n {\n mode: 'chat',\n ...params,\n },\n options?.signal,\n );\n }\n}\n\nexport function createAiClient(options: AiClientOptions): KubuildAiClient {\n return new KubuildAiClient(options);\n}\n"],"mappings":";AAqBO,IAAM,kBAAN,MAAsB;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAA0B;AACpC,QAAI,CAAC,QAAQ,UAAU;AACrB,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AACA,SAAK,WAAW,QAAQ;AACxB,SAAK,UAAU,QAAQ;AACvB,SAAK,UAAU,QAAQ,SAAS,WAAW,MAAM,KAAK,UAAU;AAAA,EAClE;AAAA,EAEA,MAAc,iBAAkD;AAC9D,QAAI,CAAC,KAAK,QAAS,QAAO,CAAC;AAC3B,QAAI,OAAO,KAAK,YAAY,YAAY;AACtC,aAAO,MAAM,KAAK,QAAQ;AAAA,IAC5B;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,YACZ,MACA,QACY;AACZ,UAAM,iBAAiB,MAAM,KAAK,eAAe;AAEjD,UAAM,MAAM,MAAM,KAAK,QAAQ,KAAK,UAAU;AAAA,MAC5C,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG;AAAA,MACL;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,MACzB;AAAA,IACF,CAAC;AAED,UAAM,OAAQ,MAAM,IAAI,KAAK;AAE7B,QAAI,CAAC,IAAI,MAAM,CAAC,KAAK,WAAW,CAAC,KAAK,MAAM;AAC1C,YAAM,aAAa,MAAM,OAAO,WAAW,QAAQ,IAAI,MAAM,KAAK,IAAI,UAAU;AAChF,YAAM,QAAQ,IAAI,MAAM,UAAU;AAClC,MAAC,MAA0D,OAAO,MAAM,OAAO;AAC/E,MAAC,MAA0D,UAAU,MAAM,OAAO;AAClF,YAAM;AAAA,IACR;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aACJ,QACA,SACuB;AACvB,WAAO,KAAK;AAAA,MACV;AAAA,QACE,MAAM;AAAA,QACN,GAAG;AAAA,MACL;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAc,WACZ,KACA,SACe;AACf,QAAI,CAAC,IAAI,MAAM;AACb,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AAEA,UAAM,SAAS,IAAI,KAAK,UAAU;AAClC,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,SAAS;AAEb,QAAI;AACF,aAAO,MAAM;AACX,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,KAAM;AAEV,kBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,cAAM,QAAQ,OAAO,MAAM,MAAM;AACjC,iBAAS,MAAM,IAAI,KAAK;AAExB,mBAAW,QAAQ,OAAO;AACxB,gBAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,qBAAW,QAAQ,OAAO;AACxB,gBAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,kBAAI;AACJ,kBAAI;AACF,wBAAQ,KAAK,MAAM,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC;AAAA,cACzC,QAAQ;AAEN;AAAA,cACF;AACA,sBAAQ,KAAK;AAAA,YACf;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,UAAE;AACA,aAAO,YAAY;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WACJ,QACA,WACA,SACuB;AACvB,UAAM,iBAAiB,MAAM,KAAK,eAAe;AAEjD,UAAM,MAAM,MAAM,KAAK,QAAQ,KAAK,UAAU;AAAA,MAC5C,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG;AAAA,MACL;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,GAAG;AAAA,MACL,CAAC;AAAA,MACD,QAAQ,SAAS;AAAA,IACnB,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,UAAU,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE;AAC/C,YAAM,MAAM,IAAI,MAAM,qBAAqB,IAAI,MAAM,IAAI,IAAI,UAAU,MAAM,OAAO,EAAE;AACtF,iBAAW,UAAU,GAAG;AACxB,YAAM;AAAA,IACR;AAEA,QAAI,WAAgC;AAEpC,UAAM,KAAK,WAAW,KAAK,CAAC,UAAU;AACpC,UAAI,MAAM,SAAS,UAAU;AAC3B,mBAAW,WAAW,MAAM,OAAO;AAAA,MACrC,WAAW,MAAM,SAAS,YAAY;AACpC,mBAAW,aAAa,MAAM,UAAU,MAAM,YAAY;AAAA,MAC5D,WAAW,MAAM,SAAS,WAAW;AACnC,mBAAW,YAAY,MAAM,SAAS,MAAM,OAAO,MAAM,KAAK;AAAA,MAChE,WAAW,MAAM,SAAS,YAAY;AACpC,mBAAW,MAAM;AACjB,mBAAW,aAAa,MAAM,QAAQ;AAAA,MACxC,WAAW,MAAM,SAAS,SAAS;AACjC,cAAM,MAAM,IAAI,MAAM,MAAM,MAAM,WAAW,cAAc;AAC3D,QAAC,IAAqC,OAAO,MAAM,MAAM;AACzD,mBAAW,UAAU,GAAG;AACxB,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAED,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,kDAAkD;AAAA,IACpE;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WACJ,QACA,WACA,SACwB;AACxB,UAAM,iBAAiB,MAAM,KAAK,eAAe;AAEjD,UAAM,MAAM,MAAM,KAAK,QAAQ,KAAK,UAAU;AAAA,MAC5C,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG;AAAA,MACL;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,GAAG;AAAA,MACL,CAAC;AAAA,MACD,QAAQ,SAAS;AAAA,IACnB,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,UAAU,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE;AAC/C,YAAM,MAAM,IAAI,MAAM,0BAA0B,IAAI,MAAM,IAAI,IAAI,UAAU,MAAM,OAAO,EAAE;AAC3F,iBAAW,UAAU,GAAG;AACxB,YAAM;AAAA,IACR;AAEA,QAAI,eAAqC;AAEzC,UAAM,KAAK,WAAW,KAAK,CAAC,UAAU;AACpC,UAAI,MAAM,SAAS,cAAc;AAC/B,mBAAW,cAAc,MAAM,OAAO,MAAM,OAAO;AAAA,MACrD,WAAW,MAAM,SAAS,iBAAiB;AACzC,uBAAe,MAAM;AACrB,mBAAW,iBAAiB,MAAM,OAAO;AAAA,MAC3C,WAAW,MAAM,SAAS,SAAS;AACjC,cAAM,MAAM,IAAI,MAAM,MAAM,MAAM,WAAW,cAAc;AAC3D,QAAC,IAAqC,OAAO,MAAM,MAAM;AACzD,mBAAW,UAAU,GAAG;AACxB,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAED,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBACJ,QACA,SACe;AACf,WAAO,KAAK;AAAA,MACV;AAAA,QACE,MAAM;AAAA,QACN,GAAG;AAAA,MACL;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,MAAM,aACJ,QACA,SACe;AACf,WAAO,KAAK;AAAA,MACV;AAAA,QACE,MAAM;AAAA,QACN,GAAG;AAAA,MACL;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,MAAM,KACJ,QACA,SACyB;AACzB,WAAO,KAAK;AAAA,MACV;AAAA,QACE,MAAM;AAAA,QACN,GAAG;AAAA,MACL;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAEO,SAAS,eAAe,SAA2C;AACxE,SAAO,IAAI,gBAAgB,OAAO;AACpC;","names":[]}
|