@namzu/sandbox 13.0.0 → 15.0.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/CHANGELOG.md +1147 -0
- package/README.md +447 -0
- package/dist/backends/aci-standby-pool/index.d.ts.map +1 -1
- package/dist/backends/aci-standby-pool/index.js +13 -1
- package/dist/backends/aci-standby-pool/index.js.map +1 -1
- package/dist/backends/docker/index.d.ts.map +1 -1
- package/dist/backends/docker/index.js +19 -1
- package/dist/backends/docker/index.js.map +1 -1
- package/dist/backends/firecracker/index.d.ts.map +1 -1
- package/dist/backends/firecracker/index.js +12 -2
- package/dist/backends/firecracker/index.js.map +1 -1
- package/dist/backends/firecracker/protocol.d.ts +481 -8
- package/dist/backends/firecracker/protocol.d.ts.map +1 -1
- package/dist/backends/firecracker/protocol.js +136 -0
- package/dist/backends/firecracker/protocol.js.map +1 -1
- package/dist/backends/firecracker/transport.d.ts +642 -14
- package/dist/backends/firecracker/transport.d.ts.map +1 -1
- package/dist/backends/firecracker/transport.js +1307 -34
- package/dist/backends/firecracker/transport.js.map +1 -1
- package/dist/backends/kubernetes/egress-policy.d.ts +1296 -0
- package/dist/backends/kubernetes/egress-policy.d.ts.map +1 -0
- package/dist/backends/kubernetes/egress-policy.js +2458 -0
- package/dist/backends/kubernetes/egress-policy.js.map +1 -0
- package/dist/backends/kubernetes/identity.d.ts +193 -0
- package/dist/backends/kubernetes/identity.d.ts.map +1 -0
- package/dist/backends/kubernetes/identity.js +147 -0
- package/dist/backends/kubernetes/identity.js.map +1 -0
- package/dist/backends/kubernetes/index.d.ts +1019 -0
- package/dist/backends/kubernetes/index.d.ts.map +1 -0
- package/dist/backends/kubernetes/index.js +1756 -0
- package/dist/backends/kubernetes/index.js.map +1 -0
- package/dist/backends/kubernetes/ingress-policy.d.ts +375 -0
- package/dist/backends/kubernetes/ingress-policy.d.ts.map +1 -0
- package/dist/backends/kubernetes/ingress-policy.js +1050 -0
- package/dist/backends/kubernetes/ingress-policy.js.map +1 -0
- package/dist/backends/kubernetes/k8s-client.d.ts +334 -0
- package/dist/backends/kubernetes/k8s-client.d.ts.map +1 -0
- package/dist/backends/kubernetes/k8s-client.js +553 -0
- package/dist/backends/kubernetes/k8s-client.js.map +1 -0
- package/dist/backends/kubernetes/lease.d.ts +145 -0
- package/dist/backends/kubernetes/lease.d.ts.map +1 -0
- package/dist/backends/kubernetes/lease.js +201 -0
- package/dist/backends/kubernetes/lease.js.map +1 -0
- package/dist/backends/kubernetes/objects.d.ts +702 -0
- package/dist/backends/kubernetes/objects.d.ts.map +1 -0
- package/dist/backends/kubernetes/objects.js +518 -0
- package/dist/backends/kubernetes/objects.js.map +1 -0
- package/dist/backends/kubernetes/per-sandbox-policy.d.ts +219 -0
- package/dist/backends/kubernetes/per-sandbox-policy.d.ts.map +1 -0
- package/dist/backends/kubernetes/per-sandbox-policy.js +407 -0
- package/dist/backends/kubernetes/per-sandbox-policy.js.map +1 -0
- package/dist/backends/kubernetes/privilege-probe.d.ts +136 -0
- package/dist/backends/kubernetes/privilege-probe.d.ts.map +1 -0
- package/dist/backends/kubernetes/privilege-probe.js +185 -0
- package/dist/backends/kubernetes/privilege-probe.js.map +1 -0
- package/dist/backends/kubernetes/rbac.d.ts +153 -0
- package/dist/backends/kubernetes/rbac.d.ts.map +1 -0
- package/dist/backends/kubernetes/rbac.js +177 -0
- package/dist/backends/kubernetes/rbac.js.map +1 -0
- package/dist/backends/kubernetes/sandbox.d.ts +190 -0
- package/dist/backends/kubernetes/sandbox.d.ts.map +1 -0
- package/dist/backends/kubernetes/sandbox.js +433 -0
- package/dist/backends/kubernetes/sandbox.js.map +1 -0
- package/dist/backends/kubernetes/transport.d.ts +1048 -0
- package/dist/backends/kubernetes/transport.d.ts.map +1 -0
- package/dist/backends/kubernetes/transport.js +2093 -0
- package/dist/backends/kubernetes/transport.js.map +1 -0
- package/dist/backends/kubernetes/workspace.d.ts +1512 -0
- package/dist/backends/kubernetes/workspace.d.ts.map +1 -0
- package/dist/backends/kubernetes/workspace.js +3703 -0
- package/dist/backends/kubernetes/workspace.js.map +1 -0
- package/dist/backends/remote-execution-controller.d.ts +14 -0
- package/dist/backends/remote-execution-controller.d.ts.map +1 -1
- package/dist/backends/remote-execution-controller.js.map +1 -1
- package/dist/index.d.ts +350 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +344 -34
- package/dist/index.js.map +1 -1
- package/dist/testing/sandbox-conformance.d.ts +227 -0
- package/dist/testing/sandbox-conformance.d.ts.map +1 -0
- package/dist/testing/sandbox-conformance.js +896 -0
- package/dist/testing/sandbox-conformance.js.map +1 -0
- package/package.json +5 -4
- package/src/backends/aci-standby-pool/index.ts +16 -1
- package/src/backends/docker/index.ts +22 -1
- package/src/backends/firecracker/index.ts +14 -2
- package/src/backends/firecracker/protocol.ts +541 -6
- package/src/backends/firecracker/transport.ts +1687 -64
- package/src/backends/kubernetes/egress-policy.ts +3448 -0
- package/src/backends/kubernetes/identity.ts +261 -0
- package/src/backends/kubernetes/index.ts +2670 -0
- package/src/backends/kubernetes/ingress-policy.ts +1344 -0
- package/src/backends/kubernetes/k8s-client.ts +742 -0
- package/src/backends/kubernetes/lease.ts +254 -0
- package/src/backends/kubernetes/objects.ts +983 -0
- package/src/backends/kubernetes/per-sandbox-policy.ts +542 -0
- package/src/backends/kubernetes/privilege-probe.ts +261 -0
- package/src/backends/kubernetes/rbac.ts +192 -0
- package/src/backends/kubernetes/sandbox.ts +593 -0
- package/src/backends/kubernetes/transport.ts +2895 -0
- package/src/backends/kubernetes/workspace.ts +5640 -0
- package/src/backends/remote-execution-controller.ts +14 -0
- package/src/index.ts +838 -35
- package/src/testing/sandbox-conformance.ts +1202 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The {@link Sandbox} contract, as a suite a backend author runs against
|
|
3
|
+
* their own implementation.
|
|
4
|
+
*
|
|
5
|
+
* ## Why this exists
|
|
6
|
+
*
|
|
7
|
+
* `@namzu/sdk`'s `Sandbox` interface is the one thing every backend in this
|
|
8
|
+
* package promises to implement the same way — `exec`'s exit codes, the
|
|
9
|
+
* `AbortSignal` contract, a `writeFile`/`readFile` round trip, terminal
|
|
10
|
+
* ownership on `destroy()` — and until now nothing PROVED that two backends
|
|
11
|
+
* agreed on any of it. Each backend carried its own bespoke test file
|
|
12
|
+
* (`sandbox-surface.test.ts`, `backend.test.ts`, …), written by whoever
|
|
13
|
+
* built that backend, checking whatever that author thought to check. A
|
|
14
|
+
* shared contract can be silently narrower than either file: this suite is
|
|
15
|
+
* the thing that would have caught it.
|
|
16
|
+
*
|
|
17
|
+
* ## Why it takes its runner as an argument
|
|
18
|
+
*
|
|
19
|
+
* The same shape as `@namzu/sdk/testing`'s checkpoint-store and provider
|
|
20
|
+
* driver suites, and for the same two reasons: `@namzu/sandbox` gains no
|
|
21
|
+
* test dependency from publishing it, and a caller can pass a RECORDING
|
|
22
|
+
* `describe`/`it` and run the whole contract as ordinary code — which is
|
|
23
|
+
* how `testing/__tests__/conformance-fails-a-broken-sandbox.test.ts`
|
|
24
|
+
* proves a deliberately wrong `Sandbox` fails it.
|
|
25
|
+
*
|
|
26
|
+
* ## What is asserted, and what deliberately is not
|
|
27
|
+
*
|
|
28
|
+
* Contract behaviour only — never a backend-specific object, field or
|
|
29
|
+
* error string. A case never inspects `sandbox.constructor.name`, never
|
|
30
|
+
* matches an error message, and never assumes a particular
|
|
31
|
+
* {@link SandboxEnvironment}. `openTerminal`, `openTcpConnection` and
|
|
32
|
+
* `walkFiles` are OPTIONAL on {@link Sandbox} by the SDK's own contract — a
|
|
33
|
+
* backend that cannot honour one must omit it rather than accept and ignore
|
|
34
|
+
* it — so a factory whose sandbox omits any of them skips that section rather
|
|
35
|
+
* than failing it. Every other section runs against every sandbox.
|
|
36
|
+
*
|
|
37
|
+
* ## Where it runs today
|
|
38
|
+
*
|
|
39
|
+
* Both `backends/kubernetes/__tests__/conformance.test.ts` and
|
|
40
|
+
* `backends/firecracker/__tests__/conformance.test.ts` call this against a
|
|
41
|
+
* real `agent/agent.cjs` on a loopback socket — proving the suite is
|
|
42
|
+
* backend-agnostic rather than one backend's tests wearing a new name.
|
|
43
|
+
* `packages/sandbox/k8s/scripts/contract-suite.mjs` runs it a third time,
|
|
44
|
+
* against a live cluster.
|
|
45
|
+
*
|
|
46
|
+
* ## Not published from `@namzu/sandbox`'s entry point
|
|
47
|
+
*
|
|
48
|
+
* The package has no `testing` subpath today (unlike `@namzu/sdk`), and
|
|
49
|
+
* this batch does not add one — promoting this to a public import path is
|
|
50
|
+
* a deliberate, separate decision. Within the monorepo a caller imports it
|
|
51
|
+
* by relative path, exactly as the two files above do:
|
|
52
|
+
*
|
|
53
|
+
* ```ts sketch
|
|
54
|
+
* import { defineSandboxConformance } from '../../../testing/sandbox-conformance.js'
|
|
55
|
+
*
|
|
56
|
+
* defineSandboxConformance({
|
|
57
|
+
* describe, it, expect,
|
|
58
|
+
* label: 'my-backend',
|
|
59
|
+
* makeSandbox: async () => ({ sandbox: await myBackend.create(), dispose: async () => {} }),
|
|
60
|
+
* })
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
import type { OpenTerminalOptions, Sandbox, TerminalSession } from '@namzu/sdk';
|
|
64
|
+
import type { ConformanceAssertion, ConformanceDescribe, ConformanceExpect, ConformanceIt } from '@namzu/sdk/testing';
|
|
65
|
+
/**
|
|
66
|
+
* The contract revision these assertions express. Carried on the describe
|
|
67
|
+
* label so a failure is legible on sight as "the sandbox contract", the
|
|
68
|
+
* same convention `PROVIDER_DRIVER_CONTRACT_VERSION` uses — raised only
|
|
69
|
+
* when a case is ADDED or TIGHTENED, never on a rewording.
|
|
70
|
+
*
|
|
71
|
+
* 3 is the `walkFiles`, concurrent-`exec` and `exec`-timeout sections, none
|
|
72
|
+
* of which needs a guest feature that did not already exist.
|
|
73
|
+
*
|
|
74
|
+
* **The ranged and streamed read cases deliberately did NOT raise it
|
|
75
|
+
* further.** Raising it for them would assert that every backend this suite
|
|
76
|
+
* runs against implements them, and one does not: the Firecracker tier's
|
|
77
|
+
* guest lives in a golden rootfs image that is NOT built from this
|
|
78
|
+
* repository — nothing here builds one, `packages/sandbox/package.json#files`
|
|
79
|
+
* does not even ship `agent/`, and `README.md` documents the image as
|
|
80
|
+
* something the operator builds and canaries on their own schedule. A
|
|
81
|
+
* deployment therefore runs whatever agent its last image build baked in,
|
|
82
|
+
* and a contract version that claimed otherwise would be a claim about
|
|
83
|
+
* images this repository cannot see. Those two cases are gated on
|
|
84
|
+
* {@link SandboxConformanceOptions.supportsRangedAndStreamedReads}
|
|
85
|
+
* instead, and skip by name when a backend does not declare them.
|
|
86
|
+
*/
|
|
87
|
+
export declare const SANDBOX_CONTRACT_VERSION = 3;
|
|
88
|
+
/** A sandbox to test, plus whatever teardown building it required. */
|
|
89
|
+
export interface SandboxConformanceHandle {
|
|
90
|
+
readonly sandbox: Sandbox;
|
|
91
|
+
/**
|
|
92
|
+
* Called after each case, pass or fail — closes fixture servers, restores
|
|
93
|
+
* environment variables, removes temp directories. Distinct from
|
|
94
|
+
* `sandbox.destroy()`, which the suite calls itself (idempotently) as
|
|
95
|
+
* part of every case's teardown; `dispose` is for what `makeSandbox`
|
|
96
|
+
* itself stood up, not for the sandbox's own lifecycle.
|
|
97
|
+
*/
|
|
98
|
+
dispose?(): void | Promise<void>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Build one fresh {@link Sandbox}. Called once per case, so no case can be
|
|
102
|
+
* affected by another's writes, aborts or destroys — the suite never
|
|
103
|
+
* assumes a shared instance and never reuses one across cases.
|
|
104
|
+
*/
|
|
105
|
+
export type MakeSandbox = () => SandboxConformanceHandle | Promise<SandboxConformanceHandle>;
|
|
106
|
+
export interface SandboxConformanceOptions {
|
|
107
|
+
readonly describe: ConformanceDescribe;
|
|
108
|
+
readonly it: ConformanceIt;
|
|
109
|
+
readonly expect: ConformanceExpect;
|
|
110
|
+
readonly makeSandbox: MakeSandbox;
|
|
111
|
+
/** Names the backend in test output. Defaults to `sandbox`. */
|
|
112
|
+
readonly label?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Whether this backend's guest can run the `openTcpConnection` positive
|
|
115
|
+
* case's listener at all — by default {@link nodeGuestListener}, `node
|
|
116
|
+
* -e`. Defaults to `true`: every backend this suite ships against runs
|
|
117
|
+
* `agent/agent.cjs` in the guest, and that agent IS node, so node on the
|
|
118
|
+
* guest's own `PATH` is a precondition of the agent existing rather than
|
|
119
|
+
* an extra capability this suite demands.
|
|
120
|
+
*
|
|
121
|
+
* Set `false` for a guest that cannot run a listener this way at all
|
|
122
|
+
* (no `openTerminal`, or an image with neither node nor a substitute) —
|
|
123
|
+
* the case then SKIPS, its own title stating why, rather than failing a
|
|
124
|
+
* backend for a capability its contract never promised. A backend that
|
|
125
|
+
* can run *some* listener, just not node, keeps this `true` (or omits
|
|
126
|
+
* it) and supplies {@link SandboxConformanceOptions.guestListenerCommand}
|
|
127
|
+
* instead.
|
|
128
|
+
*/
|
|
129
|
+
readonly guestCanRunNode?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Overrides the program the `openTcpConnection` positive case starts
|
|
132
|
+
* inside the guest. Defaults to {@link nodeGuestListener}. A guest
|
|
133
|
+
* without node but with, say, busybox `nc` can supply its own command as
|
|
134
|
+
* long as it reports the bound port the way
|
|
135
|
+
* {@link GuestListenerCommand.parsePort} expects.
|
|
136
|
+
*/
|
|
137
|
+
readonly guestListenerCommand?: () => GuestListenerCommand;
|
|
138
|
+
/**
|
|
139
|
+
* Whether this backend's guest honours `readFile`'s `offset`/`length`
|
|
140
|
+
* and implements {@link Sandbox.readFileStream}.
|
|
141
|
+
*
|
|
142
|
+
* **Defaults to `false`, and the default is the honest one.** These
|
|
143
|
+
* cases are not in {@link SANDBOX_CONTRACT_VERSION} — see the comment
|
|
144
|
+
* on that constant for why — so the suite cannot assume a backend has
|
|
145
|
+
* them. A backend whose guest is built from this repository sets it
|
|
146
|
+
* `true`; every other backend gets the cases as named skips, counted in
|
|
147
|
+
* the runner's own totals and titled with the reason, rather than as
|
|
148
|
+
* failures for a contract it never agreed to.
|
|
149
|
+
*
|
|
150
|
+
* A backend that sets this `true` while its guest ignores
|
|
151
|
+
* `offset`/`length` FAILS, and that is the point: returning the whole
|
|
152
|
+
* file where a slice was asked for is a wrong answer, not a missing
|
|
153
|
+
* capability.
|
|
154
|
+
*/
|
|
155
|
+
readonly supportsRangedAndStreamedReads?: boolean;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* A program the `openTcpConnection` positive case can start INSIDE a guest
|
|
159
|
+
* through {@link Sandbox.openTerminal}, and dial back into over
|
|
160
|
+
* `openTcpConnection` itself.
|
|
161
|
+
*
|
|
162
|
+
* Starting the listener in the guest — rather than in the orchestrator/test
|
|
163
|
+
* process, which is what this case used to do — is the whole point: a
|
|
164
|
+
* listener on the HOST'S loopback only ever proves anything for a backend
|
|
165
|
+
* whose "guest" happens to share that loopback (a Firecracker fixture over a
|
|
166
|
+
* local socket, a fake-agent-in-this-process kubernetes test). It never
|
|
167
|
+
* proves anything for a real remote guest, which cannot dial the
|
|
168
|
+
* orchestrator's loopback at all — that gap is exactly what let the case
|
|
169
|
+
* pass in every colocated fixture and fail the one time it ran against a
|
|
170
|
+
* live cluster.
|
|
171
|
+
*/
|
|
172
|
+
export interface GuestListenerCommand {
|
|
173
|
+
/** The program `openTerminal` runs as the session's top-level process. */
|
|
174
|
+
readonly command: string;
|
|
175
|
+
readonly args: readonly string[];
|
|
176
|
+
/**
|
|
177
|
+
* Reads the port the listener bound out of everything it has printed to
|
|
178
|
+
* its terminal so far. Returns `undefined` until the listener has
|
|
179
|
+
* reported one — the suite polls this as output arrives rather than
|
|
180
|
+
* parsing a single chunk, because a pty may deliver the report split
|
|
181
|
+
* across reads.
|
|
182
|
+
*/
|
|
183
|
+
parsePort(output: string): number | undefined;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* The default {@link GuestListenerCommand}: `node -e` binding an ephemeral
|
|
187
|
+
* port on the GUEST's own loopback, echoing `conformance-reply:<payload>`
|
|
188
|
+
* back for the first chunk of the one connection it accepts, then reporting
|
|
189
|
+
* the bound port on its own stdout — the only way the host, which cannot
|
|
190
|
+
* inspect a real remote guest's open ports any other way, learns which port
|
|
191
|
+
* to dial.
|
|
192
|
+
*
|
|
193
|
+
* Every backend this suite ships against runs `agent/agent.cjs` in the
|
|
194
|
+
* guest, which is itself node — so node on the guest's `PATH` is not an
|
|
195
|
+
* extra requirement this suite invents, it is a precondition of the agent
|
|
196
|
+
* existing at all. A backend whose guest genuinely cannot run node (or
|
|
197
|
+
* cannot run `openTerminal`) declares that through
|
|
198
|
+
* {@link SandboxConformanceOptions.guestCanRunNode} or supplies its own
|
|
199
|
+
* command via {@link SandboxConformanceOptions.guestListenerCommand}.
|
|
200
|
+
*/
|
|
201
|
+
export declare function nodeGuestListener(): GuestListenerCommand;
|
|
202
|
+
/**
|
|
203
|
+
* Start `listener` through `openTerminal`, and resolve once it has reported
|
|
204
|
+
* the port it bound.
|
|
205
|
+
*
|
|
206
|
+
* The returned `stop()` kills the terminal's owned process tree — the exact
|
|
207
|
+
* ownership guarantee the `openTerminal` section above already proves
|
|
208
|
+
* `destroy()` gets for free, used here to tear the listener down without
|
|
209
|
+
* waiting for the whole sandbox to go away.
|
|
210
|
+
*
|
|
211
|
+
* Takes `openTerminal` as a plain function rather than a `Sandbox`, so a
|
|
212
|
+
* unit test can exercise the port-parsing and exit-races above without a
|
|
213
|
+
* `Sandbox` fixture — see `__tests__/guest-listener.test.ts`.
|
|
214
|
+
*/
|
|
215
|
+
export declare function startGuestListener(openTerminal: (options: OpenTerminalOptions) => Promise<TerminalSession>, listener: GuestListenerCommand): Promise<{
|
|
216
|
+
readonly port: number;
|
|
217
|
+
stop(): Promise<void>;
|
|
218
|
+
}>;
|
|
219
|
+
/**
|
|
220
|
+
* Register the {@link Sandbox} contract against one backend.
|
|
221
|
+
*
|
|
222
|
+
* Call it once per backend. It registers cases through the supplied
|
|
223
|
+
* `describe`/`it`; it does not run them.
|
|
224
|
+
*/
|
|
225
|
+
export declare function defineSandboxConformance(options: SandboxConformanceOptions): void;
|
|
226
|
+
export type { ConformanceAssertion, ConformanceDescribe, ConformanceExpect, ConformanceIt };
|
|
227
|
+
//# sourceMappingURL=sandbox-conformance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-conformance.d.ts","sourceRoot":"","sources":["../../src/testing/sandbox-conformance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAGH,OAAO,KAAK,EACX,mBAAmB,EACnB,OAAO,EAIP,eAAe,EACf,MAAM,YAAY,CAAA;AAEnB,OAAO,KAAK,EACX,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,MAAM,oBAAoB,CAAA;AAE3B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAEzC,sEAAsE;AACtE,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAChC;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAA;AAE5F,MAAM,WAAW,yBAAyB;IACzC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAA;IACtC,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;IAClC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,oBAAoB,CAAA;IAC1D;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,8BAA8B,CAAC,EAAE,OAAO,CAAA;CACjD;AAgED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,oBAAoB;IACpC,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC;;;;;;OAMG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAC7C;AAKD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,IAAI,oBAAoB,CAsBxD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CACvC,YAAY,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,eAAe,CAAC,EACxE,QAAQ,EAAE,oBAAoB,GAC5B,OAAO,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CA0C3D;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,IAAI,CAozBjF;AAKD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,aAAa,EAAE,CAAA"}
|