@isolated-vm/experimental 0.0.7 → 0.0.9
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/addon/resolve.js +2 -2
- package/backend/backend.cts +7 -0
- package/backend/backend.d.cts +87 -0
- package/backend/host.cts +41 -0
- package/backend/require.cts +17 -0
- package/dist/backend/backend.cjs +9 -0
- package/dist/backend/backend.cjs.map +1 -0
- package/dist/backend/backend.d.cts +2 -0
- package/dist/backend/backend.d.cts.map +1 -0
- package/dist/backend/host.cjs +41 -0
- package/dist/backend/host.cjs.map +1 -0
- package/dist/backend/host.d.cts +2 -0
- package/dist/backend/host.d.cts.map +1 -0
- package/dist/backend/require.cjs +19 -0
- package/dist/backend/require.cjs.map +1 -0
- package/dist/backend/require.d.cts +2 -0
- package/dist/backend/require.d.cts.map +1 -0
- package/dist/frontend/agent.d.ts +1 -2
- package/dist/frontend/agent.d.ts.map +1 -1
- package/dist/frontend/agent.js +2 -7
- package/dist/frontend/agent.js.map +1 -1
- package/dist/frontend/module.d.ts +1 -1
- package/dist/frontend/module.d.ts.map +1 -1
- package/dist/frontend/module.js +1 -1
- package/dist/frontend/module.js.map +1 -1
- package/dist/frontend/realm.d.ts +2 -2
- package/dist/frontend/realm.d.ts.map +1 -1
- package/dist/frontend/realm.js +2 -2
- package/dist/frontend/realm.js.map +1 -1
- package/dist/frontend/reference.d.ts +1 -1
- package/dist/frontend/reference.d.ts.map +1 -1
- package/dist/frontend/script.d.ts +1 -1
- package/dist/frontend/script.d.ts.map +1 -1
- package/dist/frontend/script.js +1 -1
- package/dist/frontend/script.js.map +1 -1
- package/dist/isolated-vm.d.ts +1 -1
- package/dist/isolated-vm.d.ts.map +1 -1
- package/dist/isolated-vm.js +1 -1
- package/dist/isolated-vm.js.map +1 -1
- package/dist/test/00.transfer.js +58 -26
- package/dist/test/00.transfer.js.map +1 -1
- package/dist/test/20.array_buffer.js +191 -81
- package/dist/test/20.array_buffer.js.map +1 -1
- package/dist/test/90.isolation/00.dispose.d.ts +2 -0
- package/dist/test/90.isolation/00.dispose.d.ts.map +1 -0
- package/dist/test/90.isolation/00.dispose.js +28 -0
- package/dist/test/90.isolation/00.dispose.js.map +1 -0
- package/dist/test/fixtures.js +0 -1
- package/dist/test/fixtures.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utility/linker.js +1 -1
- package/dist/utility/linker.js.map +1 -1
- package/frontend/agent.ts +3 -9
- package/frontend/module.ts +1 -1
- package/frontend/realm.ts +2 -2
- package/frontend/reference.ts +1 -1
- package/frontend/script.ts +1 -1
- package/isolated-vm.ts +1 -1
- package/package.json +29 -15
- package/test/00.random.ts +1 -1
- package/test/00.transfer.ts +30 -22
- package/test/20.array_buffer.ts +43 -29
- package/test/90.isolation/00.dispose.ts +15 -0
- package/test/fixtures.ts +1 -1
- package/utility/linker.ts +1 -1
- package/backend/backend_v8.d.ts +0 -88
- package/backend/backend_v8.js +0 -18
- package/backend/specifier.ts +0 -20
- package/dist/backend/specifier.d.ts +0 -3
- package/dist/backend/specifier.d.ts.map +0 -1
- package/dist/backend/specifier.js +0 -21
- package/dist/backend/specifier.js.map +0 -1
package/test/20.array_buffer.ts
CHANGED
|
@@ -3,12 +3,13 @@ import { describe, test } from "node:test";
|
|
|
3
3
|
import * as ivm from "@isolated-vm/experimental";
|
|
4
4
|
import { injectAssert, unsafeEvalAsString, unsafeEvalAsStringInRealm } from "./fixtures.js";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
const hostSupportsSharedArraySupport =
|
|
7
|
+
// @ts-expect-error
|
|
8
|
+
process.isBun === undefined && process.versions.deno === undefined;
|
|
8
9
|
|
|
9
10
|
await describe("array buffer", async () => {
|
|
10
|
-
await using agent = await ivm.Agent.create();
|
|
11
11
|
await describe("transfer out", async () => {
|
|
12
|
+
await using agent = await ivm.Agent.create();
|
|
12
13
|
const ab = await unsafeEvalAsString(agent, () => {
|
|
13
14
|
const uint8 = new Uint8Array([ 1, 2, 3 ]);
|
|
14
15
|
return uint8.buffer;
|
|
@@ -19,6 +20,7 @@ await describe("array buffer", async () => {
|
|
|
19
20
|
|
|
20
21
|
if (hostSupportsSharedArraySupport) {
|
|
21
22
|
await test("transfer out same reference", async () => {
|
|
23
|
+
await using agent = await ivm.Agent.create();
|
|
22
24
|
const ab = await unsafeEvalAsString(agent, () => {
|
|
23
25
|
// nb: also tests zero-length buffer
|
|
24
26
|
const ab = new ArrayBuffer(0);
|
|
@@ -29,6 +31,7 @@ await describe("array buffer", async () => {
|
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
await test("transfer in", async () => {
|
|
34
|
+
await using agent = await ivm.Agent.create();
|
|
32
35
|
const realm = await agent.createRealm();
|
|
33
36
|
await injectAssert(agent, realm);
|
|
34
37
|
const global = await realm.acquireGlobalObject();
|
|
@@ -41,6 +44,7 @@ await describe("array buffer", async () => {
|
|
|
41
44
|
});
|
|
42
45
|
|
|
43
46
|
await test("transfer in same reference", async () => {
|
|
47
|
+
await using agent = await ivm.Agent.create();
|
|
44
48
|
const realm = await agent.createRealm();
|
|
45
49
|
await injectAssert(agent, realm);
|
|
46
50
|
const global = await realm.acquireGlobalObject();
|
|
@@ -55,9 +59,9 @@ await describe("array buffer", async () => {
|
|
|
55
59
|
});
|
|
56
60
|
|
|
57
61
|
await describe("shared array buffer", async () => {
|
|
58
|
-
await using agent = await ivm.Agent.create();
|
|
59
62
|
if (hostSupportsSharedArraySupport) {
|
|
60
63
|
await describe("transfer out", async () => {
|
|
64
|
+
await using agent = await ivm.Agent.create();
|
|
61
65
|
const realm = await agent.createRealm();
|
|
62
66
|
const sab = await unsafeEvalAsStringInRealm(agent, realm, () => {
|
|
63
67
|
const sab = new SharedArrayBuffer(3);
|
|
@@ -81,6 +85,7 @@ await describe("shared array buffer", async () => {
|
|
|
81
85
|
});
|
|
82
86
|
|
|
83
87
|
await test("transfer out same reference", async () => {
|
|
88
|
+
await using agent = await ivm.Agent.create();
|
|
84
89
|
const ab = await unsafeEvalAsString(agent, () => {
|
|
85
90
|
// nb: also tests zero-length buffer
|
|
86
91
|
const sab = new SharedArrayBuffer(0);
|
|
@@ -88,49 +93,57 @@ await describe("shared array buffer", async () => {
|
|
|
88
93
|
});
|
|
89
94
|
assert.strictEqual(ab[0], ab[1]);
|
|
90
95
|
});
|
|
91
|
-
}
|
|
92
96
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
97
|
+
await test("transfer in", async () => {
|
|
98
|
+
await using agent = await ivm.Agent.create();
|
|
99
|
+
const realm = await agent.createRealm();
|
|
100
|
+
await injectAssert(agent, realm);
|
|
101
|
+
const global = await realm.acquireGlobalObject();
|
|
102
|
+
const sab = new SharedArrayBuffer(3);
|
|
103
|
+
const uint8 = new Uint8Array(sab);
|
|
104
|
+
uint8.set([ 1, 2, 3 ]);
|
|
105
|
+
await global.set("sab", sab);
|
|
106
|
+
await unsafeEvalAsStringInRealm(agent, realm, () => {
|
|
107
|
+
// @ts-expect-error
|
|
108
|
+
const uint8 = new Uint8Array(globalThis.sab);
|
|
109
|
+
assert.ok(uint8.buffer instanceof SharedArrayBuffer);
|
|
110
|
+
assert.deepStrictEqual([ ...uint8 ], [ 1, 2, 3 ]);
|
|
111
|
+
});
|
|
105
112
|
});
|
|
106
|
-
}
|
|
113
|
+
}
|
|
107
114
|
|
|
108
115
|
await test("transfer in same reference", async () => {
|
|
116
|
+
await using agent = await ivm.Agent.create();
|
|
109
117
|
const realm = await agent.createRealm();
|
|
110
118
|
await injectAssert(agent, realm);
|
|
111
119
|
const global = await realm.acquireGlobalObject();
|
|
112
|
-
const
|
|
113
|
-
await global.set("
|
|
120
|
+
const ab = new ArrayBuffer(0);
|
|
121
|
+
await global.set("abs", [ ab, ab ]);
|
|
114
122
|
await unsafeEvalAsStringInRealm(agent, realm, () => {
|
|
115
123
|
// @ts-expect-error
|
|
116
124
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
117
|
-
assert.strictEqual(
|
|
125
|
+
assert.strictEqual(`${abs[0]}`, "[object ArrayBuffer]");
|
|
126
|
+
// @ts-expect-error
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
128
|
+
assert.strictEqual(abs[0], abs[1]);
|
|
118
129
|
});
|
|
119
130
|
});
|
|
120
131
|
});
|
|
121
132
|
|
|
122
|
-
|
|
133
|
+
// TODO: deno fails when this is in the `describe` (??)
|
|
134
|
+
await test("transfer out", async () => {
|
|
123
135
|
await using agent = await ivm.Agent.create();
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
return [ uint8, new Uint8Array(uint8.buffer) ];
|
|
128
|
-
});
|
|
129
|
-
assert.deepStrictEqual(uint8, new Uint8Array([ 1, 2, 3 ]));
|
|
130
|
-
assert.strictEqual(uint8.buffer, uint8_copy.buffer);
|
|
136
|
+
const [ uint8, uint8_copy ] = await unsafeEvalAsString(agent, () => {
|
|
137
|
+
const uint8 = new Uint8Array([ 1, 2, 3 ]);
|
|
138
|
+
return [ uint8, new Uint8Array(uint8.buffer) ];
|
|
131
139
|
});
|
|
140
|
+
assert.deepStrictEqual(uint8, new Uint8Array([ 1, 2, 3 ]));
|
|
141
|
+
assert.strictEqual(uint8.buffer, uint8_copy.buffer);
|
|
142
|
+
});
|
|
132
143
|
|
|
144
|
+
await describe("typed array", async () => {
|
|
133
145
|
await test("transfer in", async () => {
|
|
146
|
+
await using agent = await ivm.Agent.create();
|
|
134
147
|
const realm = await agent.createRealm();
|
|
135
148
|
await injectAssert(agent, realm);
|
|
136
149
|
const global = await realm.acquireGlobalObject();
|
|
@@ -146,6 +159,7 @@ await describe("typed array", async () => {
|
|
|
146
159
|
|
|
147
160
|
if (hostSupportsSharedArraySupport) {
|
|
148
161
|
await test("shared transfer out", async () => {
|
|
162
|
+
await using agent = await ivm.Agent.create();
|
|
149
163
|
const [ shared_uint8, shared_uint8_copy ] = await unsafeEvalAsString(agent, () => {
|
|
150
164
|
const sab = new SharedArrayBuffer(3);
|
|
151
165
|
const uint8 = new Uint8Array(sab);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import * as ivm from "@isolated-vm/experimental";
|
|
4
|
+
import {} from "@isolated-vm/experimental/test/fixtures";
|
|
5
|
+
|
|
6
|
+
await test("dispose while running", async () => {
|
|
7
|
+
const result = async function() {
|
|
8
|
+
await using agent = await ivm.Agent.create();
|
|
9
|
+
const realm = await agent.createRealm();
|
|
10
|
+
const script = ivm.expectComplete(await agent.compileScript("for(;;);"));
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/return-await
|
|
12
|
+
return script.run(realm);
|
|
13
|
+
}();
|
|
14
|
+
assert.strictEqual(await result, undefined);
|
|
15
|
+
});
|
package/test/fixtures.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { Agent, Realm } from "@isolated-vm/experimental";
|
|
1
2
|
import { afterEach } from "node:test";
|
|
2
|
-
import { Agent, Realm } from "@isolated-vm/experimental";
|
|
3
3
|
import { expectComplete } from "@isolated-vm/experimental/utility/completion";
|
|
4
4
|
|
|
5
5
|
export { expectComplete, expectThrow } from "@isolated-vm/experimental/utility/completion";
|
package/utility/linker.ts
CHANGED
|
@@ -44,7 +44,7 @@ export function makeDirectResolver(): ResolverSync<string> {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export function makeLocalResolver(meta: ImportMeta): ResolverSync<string> {
|
|
47
|
-
return
|
|
47
|
+
return specifier => meta.resolve(specifier);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
export function makeCachedLoader<Type extends AbstractModule | undefined>(loader: LoaderAsync<Type>): LoaderAsync<Type> {
|
package/backend/backend_v8.d.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
declare module "#backend_v8" {
|
|
2
|
-
type CapabilityMake = import("@isolated-vm/experimental/frontend/realm").Realm.CapabilityMake;
|
|
3
|
-
type _Agent = import("@isolated-vm/experimental/frontend/agent").Agent;
|
|
4
|
-
type _Module = import("@isolated-vm/experimental/frontend/module").Module;
|
|
5
|
-
type _Reference<T> = import("@isolated-vm/experimental/frontend/reference").Reference<T>;
|
|
6
|
-
type CompileModuleOptions = import("@isolated-vm/experimental/frontend/agent").Agent.CompileModuleOptions;
|
|
7
|
-
type CompileScriptOptions = import("@isolated-vm/experimental/frontend/agent").Agent.CompileScriptOptions;
|
|
8
|
-
type CreateAgentOptions = import("@isolated-vm/experimental/frontend/agent").Agent.CreateOptions;
|
|
9
|
-
type CreateCapabilityOptions = import("@isolated-vm/experimental/frontend/realm").Realm.CreateCapabilityOptions;
|
|
10
|
-
type CreateNativeModuleOptions = import("@isolated-vm/experimental/frontend/native_module").NativeModule.CreateOptions;
|
|
11
|
-
type MaybeCompletionOf<T> = import("@isolated-vm/experimental/utility/completion").MaybeCompletionOf<T>;
|
|
12
|
-
type ModuleLinkRecord = import("@isolated-vm/experimental/frontend/module").Module.LinkRecord;
|
|
13
|
-
type RunScriptOptions = import("@isolated-vm/experimental/frontend/script").Script.RunScriptOptions;
|
|
14
|
-
|
|
15
|
-
interface InheritedClasses {
|
|
16
|
-
Agent: object;
|
|
17
|
-
Module: object;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const initialize: (inherited: InheritedClasses) => void;
|
|
21
|
-
|
|
22
|
-
const Secret: unique symbol;
|
|
23
|
-
/** @internal */
|
|
24
|
-
export type Secret = typeof Secret;
|
|
25
|
-
|
|
26
|
-
export class Agent {
|
|
27
|
-
readonly #private;
|
|
28
|
-
protected constructor(secret: Secret, ...args: unknown[]);
|
|
29
|
-
compileModule(code: string, options?: CompileModuleOptions | undefined): Promise<MaybeCompletionOf<_Module>>;
|
|
30
|
-
compileScript(code: string, options?: CompileScriptOptions | undefined): Promise<MaybeCompletionOf<Script>>;
|
|
31
|
-
createRealm(): Promise<Realm>;
|
|
32
|
-
static create(options?: CreateAgentOptions | undefined): Promise<_Agent>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export class Module {
|
|
36
|
-
readonly #private;
|
|
37
|
-
protected constructor(secret: Secret, ...args: unknown[]);
|
|
38
|
-
/** @internal */ _link(realm: Realm, linker: ModuleLinkRecord): Promise<void>;
|
|
39
|
-
evaluate(realm: Realm): Promise<MaybeCompletionOf<unknown>>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export class NativeModule {
|
|
43
|
-
readonly #private;
|
|
44
|
-
protected constructor(secret: Secret, ...args: unknown[]);
|
|
45
|
-
instantiate(realm: Realm): Promise<Module>;
|
|
46
|
-
static create(filename: string, options: CreateNativeModuleOptions): Promise<NativeModule>;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export class Realm {
|
|
50
|
-
readonly #private;
|
|
51
|
-
protected constructor(secret: Secret, ...args: unknown[]);
|
|
52
|
-
acquireGlobalObject(): Promise<_Reference<Record<string, unknown>>>;
|
|
53
|
-
createCapability(make: CapabilityMake, options: CreateCapabilityOptions): Promise<Module>;
|
|
54
|
-
instantiateRuntime(): Promise<Module>;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export class Reference {
|
|
58
|
-
readonly #private;
|
|
59
|
-
protected constructor(secret: Secret, ...args: unknown[]);
|
|
60
|
-
copy(): Promise<unknown>;
|
|
61
|
-
get(property: string): Promise<Reference>;
|
|
62
|
-
set(property: string, value: unknown): Promise<void>;
|
|
63
|
-
invoke(args: unknown[]): Promise<MaybeCompletionOf<unknown>>;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export class Script {
|
|
67
|
-
readonly #private;
|
|
68
|
-
protected constructor(secret: Secret, ...args: unknown[]);
|
|
69
|
-
run(realm: Realm, options?: RunScriptOptions | undefined): Promise<MaybeCompletionOf<unknown>>;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export class SubscriberCapability {
|
|
73
|
-
readonly #private;
|
|
74
|
-
protected constructor(secret: Secret, ...args: unknown[]);
|
|
75
|
-
send(message: unknown): Promise<boolean>;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** @internal */
|
|
79
|
-
const exports: {
|
|
80
|
-
initialize: typeof initialize;
|
|
81
|
-
Agent: typeof Agent;
|
|
82
|
-
Module: typeof Module;
|
|
83
|
-
NativeModule: typeof NativeModule;
|
|
84
|
-
Realm: typeof Realm;
|
|
85
|
-
Script: typeof Script;
|
|
86
|
-
};
|
|
87
|
-
export default exports;
|
|
88
|
-
}
|
package/backend/backend_v8.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
|
-
import path from "@isolated-vm/experimental/backend/specifier";
|
|
4
|
-
|
|
5
|
-
// Import compiled module
|
|
6
|
-
const require = createRequire(import.meta.url);
|
|
7
|
-
|
|
8
|
-
/** @type {typeof import("#backend_v8")} */
|
|
9
|
-
const cjs = require(path);
|
|
10
|
-
|
|
11
|
-
// Exports must be enumerated because this imports from the native module which cannot declare ESM
|
|
12
|
-
// exports.
|
|
13
|
-
export const initialize = cjs.initialize;
|
|
14
|
-
export const Agent = cjs.Agent;
|
|
15
|
-
export const Module = cjs.Module;
|
|
16
|
-
export const NativeModule = cjs.NativeModule;
|
|
17
|
-
export const Realm = cjs.Realm;
|
|
18
|
-
export const Script = cjs.Script;
|
package/backend/specifier.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import * as fs from "node:fs";
|
|
2
|
-
import { arch, platform } from "node:process";
|
|
3
|
-
|
|
4
|
-
// Detect libc version
|
|
5
|
-
const backendPlatform = function() {
|
|
6
|
-
if (platform === "linux") {
|
|
7
|
-
try {
|
|
8
|
-
if (fs.readFileSync("/usr/bin/ldd", "latin1").includes("ld-musl-")) {
|
|
9
|
-
return `linux-${arch}-musl`;
|
|
10
|
-
}
|
|
11
|
-
} catch {}
|
|
12
|
-
return `linux-${arch}-gnu`;
|
|
13
|
-
} else {
|
|
14
|
-
return `${platform}-${arch}`;
|
|
15
|
-
}
|
|
16
|
-
}();
|
|
17
|
-
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/no-inferrable-types
|
|
19
|
-
const path: string = `@isolated-vm/experimental-${backendPlatform}`;
|
|
20
|
-
export default path;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"specifier.d.ts","sourceRoot":"","sources":["../../backend/specifier.ts"],"names":[],"mappings":"AAkBA,QAAA,MAAM,IAAI,EAAE,MAAuD,CAAC;AACpE,eAAe,IAAI,CAAC"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as fs from "node:fs";
|
|
2
|
-
import { arch, platform } from "node:process";
|
|
3
|
-
// Detect libc version
|
|
4
|
-
const backendPlatform = function () {
|
|
5
|
-
if (platform === "linux") {
|
|
6
|
-
try {
|
|
7
|
-
if (fs.readFileSync("/usr/bin/ldd", "latin1").includes("ld-musl-")) {
|
|
8
|
-
return `linux-${arch}-musl`;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
catch { }
|
|
12
|
-
return `linux-${arch}-gnu`;
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
return `${platform}-${arch}`;
|
|
16
|
-
}
|
|
17
|
-
}();
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/no-inferrable-types
|
|
19
|
-
const path = `@isolated-vm/experimental-${backendPlatform}`;
|
|
20
|
-
export default path;
|
|
21
|
-
//# sourceMappingURL=specifier.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"specifier.js","sourceRoot":"","sources":["../../backend/specifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE9C,sBAAsB;AACtB,MAAM,eAAe,GAAG;IACvB,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC;YACJ,IAAI,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBACpE,OAAO,SAAS,IAAI,OAAO,CAAC;YAC7B,CAAC;QACF,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,OAAO,SAAS,IAAI,MAAM,CAAC;IAC5B,CAAC;SAAM,CAAC;QACP,OAAO,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC;IAC9B,CAAC;AACF,CAAC,EAAE,CAAC;AAEJ,kEAAkE;AAClE,MAAM,IAAI,GAAW,6BAA6B,eAAe,EAAE,CAAC;AACpE,eAAe,IAAI,CAAC"}
|