@sandboxxjs/core 0.5.0 → 2.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/.turbo/turbo-build.log +1 -0
- package/CHANGELOG.md +17 -0
- package/dist/allocator.d.ts +44 -0
- package/dist/allocator.d.ts.map +1 -0
- package/dist/allocator.js +14 -0
- package/dist/allocator.js.map +1 -0
- package/dist/client.d.ts +50 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +21 -0
- package/dist/client.js.map +1 -0
- package/dist/create-client.d.ts +11 -0
- package/dist/create-client.d.ts.map +1 -0
- package/dist/create-client.js +159 -0
- package/dist/create-client.js.map +1 -0
- package/dist/index.d.ts +25 -326
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -16858
- package/dist/index.js.map +1 -295
- package/dist/protocol.d.ts +96 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +15 -0
- package/dist/protocol.js.map +1 -0
- package/dist/provider.d.ts +54 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +14 -0
- package/dist/provider.js.map +1 -0
- package/dist/registry.d.ts +28 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +19 -0
- package/dist/registry.js.map +1 -0
- package/dist/router.d.ts +24 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +18 -0
- package/dist/router.js.map +1 -0
- package/dist/sandbox.d.ts +54 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +15 -0
- package/dist/sandbox.js.map +1 -0
- package/package.json +10 -35
- package/src/allocator.ts +48 -0
- package/src/client.ts +51 -0
- package/src/create-client.ts +187 -0
- package/src/index.ts +45 -0
- package/src/protocol.ts +133 -0
- package/src/provider.ts +54 -0
- package/src/registry.ts +29 -0
- package/src/router.ts +25 -0
- package/src/sandbox.ts +52 -0
- package/tsconfig.json +12 -0
- package/README.md +0 -60
|
@@ -0,0 +1 @@
|
|
|
1
|
+
$ tsc
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @sandboxxjs/core
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 9c7ae4c: Complete architecture rewrite: Provider-based unified sandbox lifecycle.
|
|
8
|
+
|
|
9
|
+
Breaking changes:
|
|
10
|
+
|
|
11
|
+
- Removed old Isolator + Mixin + State architecture
|
|
12
|
+
- Removed @sandboxxjs/state, @sandboxxjs/cli, @sandboxxjs/cloudflare-isolator packages
|
|
13
|
+
- New unified lifecycle: Allocate → Prepare → Register → Ready → Command
|
|
14
|
+
- New SandboxProvider interface with pluggable components (Executor, FileSystem, ProcessManager)
|
|
15
|
+
- New @sandboxxjs/node-provider for cloud containers (child_process + node:fs)
|
|
16
|
+
- New @sandboxxjs/web-provider for browser WebContainer (@webcontainer/api)
|
|
17
|
+
- createSandboxClient(provider) replaces createSandbox()
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SandboxAllocator — provisions sandbox resources.
|
|
3
|
+
*
|
|
4
|
+
* Step 1 of the lifecycle: Allocate.
|
|
5
|
+
*
|
|
6
|
+
* The allocator creates a sandbox environment and returns a SandboxContainer
|
|
7
|
+
* with status "pending". The sandbox is NOT ready for commands yet —
|
|
8
|
+
* it becomes ready only after a sandbox-client connects and registers.
|
|
9
|
+
*
|
|
10
|
+
* Lifecycle: Allocate → Prepare → Register → Ready → Command
|
|
11
|
+
* ^^^^^^^^
|
|
12
|
+
*/
|
|
13
|
+
export type SandboxContainerType = "cloud" | "web";
|
|
14
|
+
export type SandboxStatus = "pending" | "ready" | "destroyed";
|
|
15
|
+
export interface SandboxContainer {
|
|
16
|
+
id: string;
|
|
17
|
+
type: SandboxContainerType;
|
|
18
|
+
status: SandboxStatus;
|
|
19
|
+
createdAt: number;
|
|
20
|
+
source?: string;
|
|
21
|
+
/** Connection info for sandbox-client to register */
|
|
22
|
+
connection: {
|
|
23
|
+
wsUrl: string;
|
|
24
|
+
token: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export interface AllocateRequest {
|
|
28
|
+
type?: SandboxContainerType;
|
|
29
|
+
sandboxId?: string;
|
|
30
|
+
source?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface SandboxAllocator {
|
|
33
|
+
/** Allocate a sandbox — returns container with status "pending" */
|
|
34
|
+
allocate(request: AllocateRequest): Promise<SandboxContainer>;
|
|
35
|
+
/** Release sandbox resources */
|
|
36
|
+
deallocate(sandboxId: string): Promise<void>;
|
|
37
|
+
/** List all sandboxes */
|
|
38
|
+
list(): Promise<SandboxContainer[]>;
|
|
39
|
+
/** Get a single sandbox by id */
|
|
40
|
+
get(sandboxId: string): Promise<SandboxContainer | null>;
|
|
41
|
+
/** Update sandbox status (called by registry on registration) */
|
|
42
|
+
updateStatus(sandboxId: string, status: SandboxStatus): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=allocator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allocator.d.ts","sourceRoot":"","sources":["../src/allocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,KAAK,CAAC;AAEnD,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,UAAU,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC9D,gCAAgC;IAChC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,yBAAyB;IACzB,IAAI,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACpC,iCAAiC;IACjC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACzD,iEAAiE;IACjE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SandboxAllocator — provisions sandbox resources.
|
|
3
|
+
*
|
|
4
|
+
* Step 1 of the lifecycle: Allocate.
|
|
5
|
+
*
|
|
6
|
+
* The allocator creates a sandbox environment and returns a SandboxContainer
|
|
7
|
+
* with status "pending". The sandbox is NOT ready for commands yet —
|
|
8
|
+
* it becomes ready only after a sandbox-client connects and registers.
|
|
9
|
+
*
|
|
10
|
+
* Lifecycle: Allocate → Prepare → Register → Ready → Command
|
|
11
|
+
* ^^^^^^^^
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=allocator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allocator.js","sourceRoot":"","sources":["../src/allocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SandboxClient — the agent that runs inside every sandbox environment.
|
|
3
|
+
*
|
|
4
|
+
* Step 2-3 of the lifecycle: Prepare → Register.
|
|
5
|
+
*
|
|
6
|
+
* After allocation, the sandbox environment starts a SandboxClient.
|
|
7
|
+
* The client connects to the service via WebSocket, registers itself,
|
|
8
|
+
* and then listens for commands (exec, fs, process operations).
|
|
9
|
+
*
|
|
10
|
+
* The client is platform-agnostic. Platform differences are injected
|
|
11
|
+
* via SandboxProvider, which supplies Executor, FileSystem, and
|
|
12
|
+
* ProcessManager components:
|
|
13
|
+
* - node-provider: child_process + node:fs
|
|
14
|
+
* - web-provider: @webcontainer/api
|
|
15
|
+
* - Future: Docker, SSH, etc.
|
|
16
|
+
*
|
|
17
|
+
* Lifecycle: Allocate → Prepare → Register → Ready → Command
|
|
18
|
+
* ^^^^^^^^^^^^^^^^^
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Connection options for a sandbox-client.
|
|
22
|
+
*/
|
|
23
|
+
export interface SandboxClientOptions {
|
|
24
|
+
/** WebSocket URL of the sandbox service registry */
|
|
25
|
+
wsUrl: string;
|
|
26
|
+
/** Sandbox identifier */
|
|
27
|
+
sandboxId: string;
|
|
28
|
+
/** Authentication token */
|
|
29
|
+
token: string;
|
|
30
|
+
/** Heartbeat interval in milliseconds (default: 30000) */
|
|
31
|
+
heartbeatInterval?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* SandboxClient — connects to service, receives commands, executes via provider components.
|
|
35
|
+
*
|
|
36
|
+
* Usage:
|
|
37
|
+
* const provider = new NodeProvider(); // or WebContainerProvider
|
|
38
|
+
* const client = createSandboxClient(provider);
|
|
39
|
+
* await client.connect({ wsUrl, sandboxId, token });
|
|
40
|
+
* // Client is now registered and listening for commands
|
|
41
|
+
*/
|
|
42
|
+
export interface SandboxClient {
|
|
43
|
+
/** Connect to the sandbox service and register */
|
|
44
|
+
connect(options: SandboxClientOptions): Promise<void>;
|
|
45
|
+
/** Disconnect from the service */
|
|
46
|
+
disconnect(): Promise<void>;
|
|
47
|
+
/** Whether the client is connected and registered */
|
|
48
|
+
readonly connected: boolean;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,kCAAkC;IAClC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SandboxClient — the agent that runs inside every sandbox environment.
|
|
3
|
+
*
|
|
4
|
+
* Step 2-3 of the lifecycle: Prepare → Register.
|
|
5
|
+
*
|
|
6
|
+
* After allocation, the sandbox environment starts a SandboxClient.
|
|
7
|
+
* The client connects to the service via WebSocket, registers itself,
|
|
8
|
+
* and then listens for commands (exec, fs, process operations).
|
|
9
|
+
*
|
|
10
|
+
* The client is platform-agnostic. Platform differences are injected
|
|
11
|
+
* via SandboxProvider, which supplies Executor, FileSystem, and
|
|
12
|
+
* ProcessManager components:
|
|
13
|
+
* - node-provider: child_process + node:fs
|
|
14
|
+
* - web-provider: @webcontainer/api
|
|
15
|
+
* - Future: Docker, SSH, etc.
|
|
16
|
+
*
|
|
17
|
+
* Lifecycle: Allocate → Prepare → Register → Ready → Command
|
|
18
|
+
* ^^^^^^^^^^^^^^^^^
|
|
19
|
+
*/
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createSandboxClient — the runtime implementation of SandboxClient.
|
|
3
|
+
*
|
|
4
|
+
* Platform-agnostic: uses standard WebSocket API (available in Node 22+, browsers).
|
|
5
|
+
* Platform differences are injected via SandboxProvider, which supplies
|
|
6
|
+
* Executor, FileSystem, and ProcessManager components.
|
|
7
|
+
*/
|
|
8
|
+
import type { SandboxClient } from "./client";
|
|
9
|
+
import type { SandboxProvider } from "./provider";
|
|
10
|
+
export declare function createSandboxClient(provider: SandboxProvider): SandboxClient;
|
|
11
|
+
//# sourceMappingURL=create-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-client.d.ts","sourceRoot":"","sources":["../src/create-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAwB,MAAM,UAAU,CAAC;AAQpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,eAAe,GAAG,aAAa,CAwK5E"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createSandboxClient — the runtime implementation of SandboxClient.
|
|
3
|
+
*
|
|
4
|
+
* Platform-agnostic: uses standard WebSocket API (available in Node 22+, browsers).
|
|
5
|
+
* Platform differences are injected via SandboxProvider, which supplies
|
|
6
|
+
* Executor, FileSystem, and ProcessManager components.
|
|
7
|
+
*/
|
|
8
|
+
export function createSandboxClient(provider) {
|
|
9
|
+
const executor = provider.createExecutor();
|
|
10
|
+
const fs = provider.createFileSystem();
|
|
11
|
+
const pm = provider.createProcessManager();
|
|
12
|
+
let ws = null;
|
|
13
|
+
let heartbeatTimer = null;
|
|
14
|
+
let isConnected = false;
|
|
15
|
+
async function connect(options) {
|
|
16
|
+
const { wsUrl, sandboxId, token, heartbeatInterval = 30_000 } = options;
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
ws = new WebSocket(wsUrl);
|
|
19
|
+
ws.onopen = () => {
|
|
20
|
+
// Step 3: Register
|
|
21
|
+
const registerMsg = { type: "register", sandboxId, token };
|
|
22
|
+
ws.send(JSON.stringify(registerMsg));
|
|
23
|
+
};
|
|
24
|
+
ws.onmessage = (event) => {
|
|
25
|
+
const data = typeof event.data === "string" ? event.data : "";
|
|
26
|
+
let msg;
|
|
27
|
+
try {
|
|
28
|
+
msg = JSON.parse(data);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (msg.type === "registered") {
|
|
34
|
+
// Step 4: Ready
|
|
35
|
+
isConnected = true;
|
|
36
|
+
heartbeatTimer = setInterval(() => {
|
|
37
|
+
if (ws?.readyState === WebSocket.OPEN) {
|
|
38
|
+
const hb = { type: "heartbeat" };
|
|
39
|
+
ws.send(JSON.stringify(hb));
|
|
40
|
+
}
|
|
41
|
+
}, heartbeatInterval);
|
|
42
|
+
resolve();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Step 5: Command — handle and respond
|
|
46
|
+
handleCommand(msg);
|
|
47
|
+
};
|
|
48
|
+
ws.onerror = () => {
|
|
49
|
+
if (!isConnected)
|
|
50
|
+
reject(new Error("WebSocket connection failed"));
|
|
51
|
+
};
|
|
52
|
+
ws.onclose = () => {
|
|
53
|
+
cleanup();
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async function handleCommand(msg) {
|
|
58
|
+
if (!ws || ws.readyState !== WebSocket.OPEN)
|
|
59
|
+
return;
|
|
60
|
+
try {
|
|
61
|
+
switch (msg.type) {
|
|
62
|
+
// Executor
|
|
63
|
+
case "exec": {
|
|
64
|
+
const result = await executor.exec(msg.command, {
|
|
65
|
+
cwd: msg.cwd,
|
|
66
|
+
timeout: msg.timeout,
|
|
67
|
+
});
|
|
68
|
+
const reply = {
|
|
69
|
+
type: "result",
|
|
70
|
+
id: msg.id,
|
|
71
|
+
stdout: result.stdout,
|
|
72
|
+
stderr: result.stderr,
|
|
73
|
+
exitCode: result.exitCode,
|
|
74
|
+
};
|
|
75
|
+
ws.send(JSON.stringify(reply));
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
// FileSystem
|
|
79
|
+
case "fs.read": {
|
|
80
|
+
const content = await fs.readFile(msg.path);
|
|
81
|
+
sendFsResult(msg.id, { content });
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case "fs.write": {
|
|
85
|
+
await fs.writeFile(msg.path, msg.content);
|
|
86
|
+
sendFsResult(msg.id, { written: true });
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case "fs.list": {
|
|
90
|
+
const files = await fs.listFiles(msg.path);
|
|
91
|
+
sendFsResult(msg.id, files);
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
case "fs.mkdir": {
|
|
95
|
+
await fs.mkdir(msg.path, { recursive: msg.recursive });
|
|
96
|
+
sendFsResult(msg.id, { created: true });
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case "fs.delete": {
|
|
100
|
+
await fs.deleteFile(msg.path);
|
|
101
|
+
sendFsResult(msg.id, { deleted: true });
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
// ProcessManager
|
|
105
|
+
case "process.start": {
|
|
106
|
+
const proc = await pm.start(msg.command, { cwd: msg.cwd });
|
|
107
|
+
sendFsResult(msg.id, proc);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case "process.kill": {
|
|
111
|
+
await pm.kill(msg.processId);
|
|
112
|
+
sendFsResult(msg.id, { killed: true });
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case "process.list": {
|
|
116
|
+
const procs = await pm.list();
|
|
117
|
+
sendFsResult(msg.id, procs);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
const errorMsg = {
|
|
124
|
+
type: "error",
|
|
125
|
+
id: msg.id || "unknown",
|
|
126
|
+
message: err instanceof Error ? err.message : "Command failed",
|
|
127
|
+
};
|
|
128
|
+
ws.send(JSON.stringify(errorMsg));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function sendFsResult(id, data) {
|
|
132
|
+
if (!ws || ws.readyState !== WebSocket.OPEN)
|
|
133
|
+
return;
|
|
134
|
+
const reply = { type: "fs.result", id, data };
|
|
135
|
+
ws.send(JSON.stringify(reply));
|
|
136
|
+
}
|
|
137
|
+
function cleanup() {
|
|
138
|
+
isConnected = false;
|
|
139
|
+
if (heartbeatTimer) {
|
|
140
|
+
clearInterval(heartbeatTimer);
|
|
141
|
+
heartbeatTimer = null;
|
|
142
|
+
}
|
|
143
|
+
ws = null;
|
|
144
|
+
}
|
|
145
|
+
async function disconnect() {
|
|
146
|
+
if (ws) {
|
|
147
|
+
ws.close();
|
|
148
|
+
cleanup();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
connect,
|
|
153
|
+
disconnect,
|
|
154
|
+
get connected() {
|
|
155
|
+
return isConnected;
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=create-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-client.js","sourceRoot":"","sources":["../src/create-client.ts"],"names":[],"mappings":"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"}
|