stitchkit 0.70.0 → 0.70.2
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/dist/agent-runtime/coding-tool-files.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-paths.d.ts +0 -1
- package/dist/agent-runtime/coding-tool-paths.d.ts.map +1 -1
- package/dist/agent-runtime/coding-tool-search-patch.d.ts.map +1 -1
- package/dist/agent-runtime/contained-files.d.ts +30 -7
- package/dist/agent-runtime/contained-files.d.ts.map +1 -1
- package/dist/agent-runtime/harness-control.d.ts +2 -0
- package/dist/agent-runtime/harness-control.d.ts.map +1 -1
- package/dist/agent-runtime/history-chronology.d.ts +19 -0
- package/dist/agent-runtime/history-chronology.d.ts.map +1 -0
- package/dist/agent-runtime/history.d.ts.map +1 -1
- package/dist/agent-runtime/run-execution.d.ts.map +1 -1
- package/dist/agent-runtime/terminal-status.d.ts.map +1 -1
- package/dist/agent-runtime-browser.js +51 -51
- package/dist/agent-runtime-coding-tools.js +31 -34
- package/dist/agent-runtime-harness.js +61 -17
- package/dist/agent-runtime-openrouter.js +2 -2
- package/dist/agent-runtime-sqlite-bun.js +5 -5
- package/dist/agent-runtime-sqlite-node.js +5 -5
- package/dist/agent-runtime.js +110 -110
- package/dist/application/server-resource.d.ts +1 -0
- package/dist/application/server-resource.d.ts.map +1 -1
- package/dist/application-grammy.js +2 -2
- package/dist/application.js +68 -65
- package/dist/browser/live-state.d.ts +126 -0
- package/dist/browser/live-state.d.ts.map +1 -0
- package/dist/cli.js +5 -5
- package/dist/contract/index.js +20 -20
- package/dist/declaration.d.ts +4 -0
- package/dist/declaration.d.ts.map +1 -1
- package/dist/declaration.js +22 -22
- package/dist/files.js +3 -3
- package/dist/index-1z5xxfst.js +397 -0
- package/dist/{index-vy5bjy07.js → index-4qfqy0m6.js} +21 -31
- package/dist/{index-dk6e56g0.js → index-7wpgrqa8.js} +37 -2
- package/dist/{index-10gbbbaa.js → index-9sx8tbz2.js} +1 -1
- package/dist/{index-38hs3a58.js → index-a01jky8m.js} +73 -8
- package/dist/{index-hsabxjz0.js → index-jw81xr75.js} +1 -1
- package/dist/{index-6wzr93cg.js → index-w0445741.js} +1 -1
- package/dist/index-y2s6h5bf.js +83 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +667 -56
- package/dist/node.js +47 -27
- package/dist/observability/index.js +22 -22
- package/dist/react.js +2 -2
- package/dist/realtime/contract.d.ts +30 -11
- package/dist/realtime/contract.d.ts.map +1 -1
- package/dist/realtime/index.d.ts +1 -1
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/server/bun.d.ts.map +1 -1
- package/dist/server/index.js +88 -80
- package/dist/server/multipart.d.ts.map +1 -1
- package/dist/server/node.d.ts.map +1 -1
- package/dist/server/process-signals.d.ts.map +1 -1
- package/dist/server/shutdown.d.ts +2 -0
- package/dist/server/shutdown.d.ts.map +1 -1
- package/dist/testing/surface-conformance.d.ts +4 -2
- package/dist/testing/surface-conformance.d.ts.map +1 -1
- package/dist/testing.js +124 -113
- package/dist/tools.js +57 -57
- package/llms-full.txt +246 -17
- package/native/darwin-arm64.node +0 -0
- package/native/darwin-x64.node +0 -0
- package/package.json +3 -1
- package/dist/index-es0h4w26.js +0 -63
- package/dist/index-xbtcszs7.js +0 -202
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from "./index-ktsps64f.js";
|
|
22
22
|
import {
|
|
23
23
|
ShutdownOptionsSchema
|
|
24
|
-
} from "./index-
|
|
24
|
+
} from "./index-7wpgrqa8.js";
|
|
25
25
|
import {
|
|
26
26
|
errorCode,
|
|
27
27
|
normalizeError,
|
|
@@ -54,7 +54,20 @@ var DEFAULT_MAX_PARTS = 1000;
|
|
|
54
54
|
var CRLF = new Uint8Array([13, 10]);
|
|
55
55
|
var HEADER_END = new Uint8Array([13, 10, 13, 10]);
|
|
56
56
|
var decoder = new TextDecoder;
|
|
57
|
+
var headerDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
57
58
|
var encoder = new TextEncoder;
|
|
59
|
+
var TOKEN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
60
|
+
function hasControl(value, allowTab = false) {
|
|
61
|
+
for (let index = 0;index < value.length; index++) {
|
|
62
|
+
const code = value.charCodeAt(index);
|
|
63
|
+
if (code < 32 && !(allowTab && code === 9) || code === 127)
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
function trimWhitespace(value) {
|
|
69
|
+
return value.replace(/^[ \t]+|[ \t]+$/g, "");
|
|
70
|
+
}
|
|
58
71
|
function indexOfBytes(haystack, needle) {
|
|
59
72
|
outer:
|
|
60
73
|
for (let index = 0;index <= haystack.length - needle.length; index += 1) {
|
|
@@ -97,10 +110,49 @@ function parseBoundary(req) {
|
|
|
97
110
|
return boundary;
|
|
98
111
|
}
|
|
99
112
|
function parseDisposition(value) {
|
|
100
|
-
if (!value
|
|
113
|
+
if (!value)
|
|
114
|
+
badRequest("Invalid multipart disposition");
|
|
115
|
+
const separator = value.indexOf(";");
|
|
116
|
+
const kind = separator < 0 ? value : value.slice(0, separator);
|
|
117
|
+
if (trimWhitespace(kind).toLowerCase() !== "form-data") {
|
|
101
118
|
badRequest("Invalid multipart disposition");
|
|
102
|
-
|
|
103
|
-
const
|
|
119
|
+
}
|
|
120
|
+
const parameters = new Map;
|
|
121
|
+
let rest = separator < 0 ? "" : value.slice(separator);
|
|
122
|
+
while (rest.length > 0) {
|
|
123
|
+
const match = /^;[ \t]*([^=; \t]+)[ \t]*=[ \t]*(?:"((?:[^"\\]|\\.)*)"|([^; \t]+))[ \t]*/.exec(rest);
|
|
124
|
+
if (!match?.[1])
|
|
125
|
+
badRequest("Invalid multipart disposition parameter");
|
|
126
|
+
const key = match[1].toLowerCase();
|
|
127
|
+
if (!TOKEN.test(key) || parameters.has(key)) {
|
|
128
|
+
badRequest("Invalid or duplicate multipart disposition parameter");
|
|
129
|
+
}
|
|
130
|
+
const quoted = match[2];
|
|
131
|
+
const raw = match[3] ?? "";
|
|
132
|
+
if (quoted === undefined && !TOKEN.test(raw)) {
|
|
133
|
+
badRequest("Invalid multipart disposition parameter");
|
|
134
|
+
}
|
|
135
|
+
const decoded = quoted === undefined ? raw : quoted.replace(/\\(.)/g, "$1");
|
|
136
|
+
if (hasControl(decoded))
|
|
137
|
+
badRequest("Invalid multipart disposition parameter");
|
|
138
|
+
parameters.set(key, decoded);
|
|
139
|
+
rest = rest.slice(match[0].length);
|
|
140
|
+
}
|
|
141
|
+
const name = parameters.get("name");
|
|
142
|
+
let filename = parameters.get("filename");
|
|
143
|
+
const extended = parameters.get("filename*");
|
|
144
|
+
if (extended !== undefined) {
|
|
145
|
+
const match = /^utf-8'[A-Za-z0-9-]*'((?:[!#$&+.^_`|~0-9A-Za-z-]|%[0-9A-Fa-f]{2})*)$/i.exec(extended);
|
|
146
|
+
if (!match)
|
|
147
|
+
badRequest("Invalid multipart extended filename");
|
|
148
|
+
try {
|
|
149
|
+
filename = decodeURIComponent(match[1] ?? "");
|
|
150
|
+
} catch {
|
|
151
|
+
badRequest("Invalid multipart extended filename");
|
|
152
|
+
}
|
|
153
|
+
if (hasControl(filename))
|
|
154
|
+
badRequest("Invalid multipart extended filename");
|
|
155
|
+
}
|
|
104
156
|
if (!name || isUnsafeKey(name))
|
|
105
157
|
badRequest("Invalid multipart field name");
|
|
106
158
|
return filename === undefined ? { name } : { name, filename };
|
|
@@ -108,23 +160,33 @@ function parseDisposition(value) {
|
|
|
108
160
|
function parsePartHeaders(bytes) {
|
|
109
161
|
let text;
|
|
110
162
|
try {
|
|
111
|
-
text =
|
|
163
|
+
text = headerDecoder.decode(bytes);
|
|
112
164
|
} catch {
|
|
113
165
|
badRequest("Invalid multipart headers");
|
|
114
166
|
}
|
|
115
|
-
const headers = new
|
|
167
|
+
const headers = new Map;
|
|
116
168
|
for (const line of text.split(`\r
|
|
117
169
|
`)) {
|
|
118
170
|
const separator = line.indexOf(":");
|
|
119
171
|
if (separator <= 0)
|
|
120
172
|
badRequest("Invalid multipart header");
|
|
121
|
-
|
|
173
|
+
const name = line.slice(0, separator).toLowerCase();
|
|
174
|
+
const value = trimWhitespace(line.slice(separator + 1));
|
|
175
|
+
if (!TOKEN.test(name) || hasControl(value, true)) {
|
|
176
|
+
badRequest("Invalid multipart header");
|
|
177
|
+
}
|
|
178
|
+
if (headers.has(name))
|
|
179
|
+
badRequest("Duplicate multipart header");
|
|
180
|
+
headers.set(name, value);
|
|
122
181
|
}
|
|
123
182
|
const disposition = parseDisposition(headers.get("content-disposition") ?? undefined);
|
|
124
183
|
const rawContentType = headers.get("content-type");
|
|
125
184
|
const contentType = rawContentType?.split(";", 1)[0]?.trim().toLowerCase();
|
|
126
185
|
const rawSize = headers.get("content-length");
|
|
127
|
-
|
|
186
|
+
if (rawSize !== undefined && !/^[0-9]+$/.test(rawSize)) {
|
|
187
|
+
badRequest("Invalid multipart part content-length");
|
|
188
|
+
}
|
|
189
|
+
const declaredSize = rawSize === undefined ? undefined : Number(rawSize);
|
|
128
190
|
if (declaredSize !== undefined && (!Number.isSafeInteger(declaredSize) || declaredSize < 0)) {
|
|
129
191
|
badRequest("Invalid multipart part content-length");
|
|
130
192
|
}
|
|
@@ -1790,6 +1852,9 @@ function bindProcessSignals(handle, options = {}) {
|
|
|
1790
1852
|
...requested.forceTimeoutMs !== undefined && {
|
|
1791
1853
|
forceTimeoutMs: validated.forceTimeoutMs
|
|
1792
1854
|
},
|
|
1855
|
+
...requested.realtimeCloseTimeoutMs !== undefined && {
|
|
1856
|
+
realtimeCloseTimeoutMs: validated.realtimeCloseTimeoutMs
|
|
1857
|
+
},
|
|
1793
1858
|
...requested.retryAfterSeconds !== undefined && {
|
|
1794
1859
|
retryAfterSeconds: validated.retryAfterSeconds
|
|
1795
1860
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// src/agent-runtime/history-chronology.ts
|
|
2
|
+
function createToolChronology() {
|
|
3
|
+
return { calls: new Map, approvals: new Map, pending: 0, resultsStarted: false };
|
|
4
|
+
}
|
|
5
|
+
function advanceToolChronology(previous, parts) {
|
|
6
|
+
const calls = new Map(previous.calls);
|
|
7
|
+
const approvals = new Map(previous.approvals);
|
|
8
|
+
let { pending, resultsStarted } = previous;
|
|
9
|
+
for (const part of parts) {
|
|
10
|
+
if (part.type === "tool-call") {
|
|
11
|
+
if (calls.has(part.callId) || resultsStarted && pending > 0)
|
|
12
|
+
return;
|
|
13
|
+
if (pending === 0)
|
|
14
|
+
resultsStarted = false;
|
|
15
|
+
calls.set(part.callId, { toolName: part.toolName, phase: "called" });
|
|
16
|
+
pending += 1;
|
|
17
|
+
} else if (part.type === "tool-approval-request") {
|
|
18
|
+
const call = calls.get(part.callId);
|
|
19
|
+
if (call?.phase !== "called" || approvals.has(part.approvalId))
|
|
20
|
+
return;
|
|
21
|
+
approvals.set(part.approvalId, part.callId);
|
|
22
|
+
calls.set(part.callId, { ...call, phase: "requested" });
|
|
23
|
+
} else if (part.type === "tool-approval-response") {
|
|
24
|
+
const callId = approvals.get(part.approvalId);
|
|
25
|
+
const call = callId === undefined ? undefined : calls.get(callId);
|
|
26
|
+
if (callId === undefined || !call || call.phase !== "requested")
|
|
27
|
+
return;
|
|
28
|
+
calls.set(callId, { ...call, phase: part.approved ? "approved" : "denied" });
|
|
29
|
+
} else if (part.type === "tool-result") {
|
|
30
|
+
const call = calls.get(part.callId);
|
|
31
|
+
if (!call || call.toolName !== part.toolName || call.phase === "result" || call.phase === "requested" || call.phase === "denied" && part.outcome === "success")
|
|
32
|
+
return;
|
|
33
|
+
calls.set(part.callId, { ...call, phase: "result" });
|
|
34
|
+
pending -= 1;
|
|
35
|
+
resultsStarted = true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { calls, approvals, pending, resultsStarted };
|
|
39
|
+
}
|
|
40
|
+
function canProjectToolChronology(state) {
|
|
41
|
+
return [...state.calls.values()].every(({ phase }) => phase !== "called");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/agent-runtime/terminal-status.ts
|
|
45
|
+
function isSpeakableAssistantStatus(status) {
|
|
46
|
+
return status === "completed" || status === "interrupted" || status === "committed";
|
|
47
|
+
}
|
|
48
|
+
function isAssistantHistoryEvidence(status, policy) {
|
|
49
|
+
return isSpeakableAssistantStatus(status) || status === "failed" && policy?.failedAssistant === "assistant-marked";
|
|
50
|
+
}
|
|
51
|
+
function isCompleteAgentHistoryTurn(messages, policy) {
|
|
52
|
+
if (messages[0]?.role !== "user")
|
|
53
|
+
return false;
|
|
54
|
+
let chronology = createToolChronology();
|
|
55
|
+
let assistantCount = 0;
|
|
56
|
+
for (const message of messages) {
|
|
57
|
+
if (message.role === "assistant") {
|
|
58
|
+
if (!isAssistantHistoryEvidence(message.status, policy))
|
|
59
|
+
return false;
|
|
60
|
+
assistantCount += 1;
|
|
61
|
+
}
|
|
62
|
+
const next = advanceToolChronology(chronology, message.parts);
|
|
63
|
+
if (!next)
|
|
64
|
+
return false;
|
|
65
|
+
chronology = next;
|
|
66
|
+
}
|
|
67
|
+
return assistantCount > 0 && chronology.pending === 0;
|
|
68
|
+
}
|
|
69
|
+
function assistantStatus(reason) {
|
|
70
|
+
if (reason === "success" || reason === "policy_stop" || reason === "provider_stop") {
|
|
71
|
+
return "completed";
|
|
72
|
+
}
|
|
73
|
+
if (reason === "superseded")
|
|
74
|
+
return "superseded";
|
|
75
|
+
if (reason === "absorbed")
|
|
76
|
+
return "superseded";
|
|
77
|
+
if (reason === "interrupted" || reason === "cancelled" || reason === "shutdown") {
|
|
78
|
+
return "interrupted";
|
|
79
|
+
}
|
|
80
|
+
return "failed";
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export { createToolChronology, advanceToolChronology, canProjectToolChronology, isAssistantHistoryEvidence, isCompleteAgentHistoryTurn, assistantStatus };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { type ClientConfig, type ClientContract, type ClientFetch, type ClientRegistryValue, type ContractClientConfig, contractEndpointMatchers, createClient, createClients, createScopedClients, createScopedUrlBuilders, createUrlBuilder, createUrlBuilders, type PathPrefixArgs, type RegistryScope, type ScopeClientConfigs, type ScopedClientRegistry, type ScopedUrlBuilderRegistry, type UrlBuilderConfig, } from './browser/client.js';
|
|
2
2
|
export { ApiError, type ApiEvent, type ApiEventListener, type ConfiguredHttpClient, createHttpClient, type HeaderProvider, type HttpClient, type HttpClientConfig, type RequestOptions, type UnauthorizedMatcher, } from './browser/http.js';
|
|
3
|
+
export { createLiveStateController, type LiveStateController, type LiveStateControllerConfig, type LiveStateControllerError, type LiveStateControllerSnapshot, type LiveStateControllerStatus, LiveStateControllerStatusSchema, type LiveStateEventDecision, type LiveStatePhase, LiveStatePhaseSchema, type LiveStateSource, type LiveStateSourceOpenInput, type LiveStateSourceOpenResult, type LiveStateStopReason, LiveStateStopReasonSchema, type LiveStateSubscriberError, } from './browser/live-state.js';
|
|
3
4
|
export type { BindRealtimeClientOptions, BoundRealtimeClient, RealtimeClient, RealtimeClientOptions, RealtimeClientTransport, SocketEventMap, SocketIOClient, SocketIOClientConfig, SocketIOClientPeerLoaders, } from './browser/socket-io.js';
|
|
4
5
|
export { bindRealtimeClient, createRealtimeClient, createSocketIOClient, } from './browser/socket-io.js';
|
|
5
6
|
export { type ParseNDJSONOptions, type ParseSSEOptions, parseNDJSON, parseSSE, } from './browser/stream.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,wBAAwB,EACxB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,QAAQ,EACR,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,mBAAmB,GACzB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,WAAW,EACX,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,wBAAwB,EACxB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,QAAQ,EACR,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,mBAAmB,GACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,EAC9B,+BAA+B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,yBAAyB,EACzB,KAAK,wBAAwB,GAC9B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,WAAW,EACX,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC"}
|