@boxlite-ai/boxlite 0.1.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.
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ /**
3
+ * BrowserBox - Secure browser with remote debugging.
4
+ *
5
+ * Provides a minimal, elegant API for running isolated browsers that can be
6
+ * controlled from outside using standard tools like Puppeteer or Playwright.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.BrowserBox = void 0;
43
+ const simplebox_1 = require("./simplebox");
44
+ const errors_1 = require("./errors");
45
+ const constants = __importStar(require("./constants"));
46
+ /**
47
+ * Secure browser environment with remote debugging.
48
+ *
49
+ * Auto-starts a browser with Chrome DevTools Protocol enabled.
50
+ * Connect from outside using Puppeteer, Playwright, Selenium, or DevTools.
51
+ *
52
+ * ## Usage
53
+ *
54
+ * ```typescript
55
+ * const browser = new BrowserBox();
56
+ * try {
57
+ * await browser.start(); // Manually start browser
58
+ * console.log(`Connect to: ${browser.endpoint()}`);
59
+ * // Use Puppeteer/Playwright from your host to connect
60
+ * await new Promise(resolve => setTimeout(resolve, 60000));
61
+ * } finally {
62
+ * await browser.stop();
63
+ * }
64
+ * ```
65
+ *
66
+ * ## Example with custom options
67
+ *
68
+ * ```typescript
69
+ * const browser = new BrowserBox({
70
+ * browser: 'firefox',
71
+ * memoryMib: 4096,
72
+ * cpus: 4
73
+ * });
74
+ * try {
75
+ * await browser.start();
76
+ * const endpoint = browser.endpoint();
77
+ * // Connect using Playwright or Puppeteer
78
+ * } finally {
79
+ * await browser.stop();
80
+ * }
81
+ * ```
82
+ */
83
+ class BrowserBox extends simplebox_1.SimpleBox {
84
+ /**
85
+ * Create a new BrowserBox.
86
+ *
87
+ * @param options - BrowserBox configuration options
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * const browser = new BrowserBox({
92
+ * browser: 'chromium',
93
+ * memoryMib: 2048,
94
+ * cpus: 2
95
+ * });
96
+ * ```
97
+ */
98
+ constructor(options = {}) {
99
+ const { browser = 'chromium', memoryMib = 2048, cpus = 2, ...restOptions } = options;
100
+ super({
101
+ ...restOptions,
102
+ image: BrowserBox.DEFAULT_IMAGE,
103
+ memoryMib,
104
+ cpus,
105
+ });
106
+ this._browser = browser;
107
+ this._port = BrowserBox.PORTS[browser] || 9222;
108
+ }
109
+ /**
110
+ * Start the browser with remote debugging enabled.
111
+ *
112
+ * Call this method after creating the BrowserBox to start the browser process.
113
+ * Waits for the browser to be ready before returning.
114
+ *
115
+ * @param timeout - Maximum time to wait for browser to start in seconds (default: 30)
116
+ * @throws {TimeoutError} If browser doesn't start within timeout
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * const browser = new BrowserBox();
121
+ * try {
122
+ * await browser.start();
123
+ * console.log(`Connect to: ${browser.endpoint()}`);
124
+ * } finally {
125
+ * await browser.stop();
126
+ * }
127
+ * ```
128
+ */
129
+ async start(timeout = 30) {
130
+ let cmd;
131
+ let processPattern;
132
+ if (this._browser === 'chromium') {
133
+ const binary = '/ms-playwright/chromium-*/chrome-linux/chrome';
134
+ cmd =
135
+ `${binary} --headless --no-sandbox --disable-dev-shm-usage ` +
136
+ `--disable-gpu --remote-debugging-address=0.0.0.0 ` +
137
+ `--remote-debugging-port=${this._port} ` +
138
+ `> /tmp/browser.log 2>&1 &`;
139
+ processPattern = 'chrome';
140
+ }
141
+ else if (this._browser === 'firefox') {
142
+ const binary = '/ms-playwright/firefox-*/firefox/firefox';
143
+ cmd =
144
+ `${binary} --headless ` +
145
+ `--remote-debugging-port=${this._port} ` +
146
+ `> /tmp/browser.log 2>&1 &`;
147
+ processPattern = 'firefox';
148
+ }
149
+ else {
150
+ // webkit
151
+ cmd =
152
+ `playwright run-server --browser webkit ` +
153
+ `--port ${this._port} > /tmp/browser.log 2>&1 &`;
154
+ processPattern = 'playwright';
155
+ }
156
+ // Start browser in background
157
+ await this.exec('sh', '-c', `nohup ${cmd}`);
158
+ // Wait for browser to be ready
159
+ await this.waitForBrowser(processPattern, timeout);
160
+ }
161
+ /**
162
+ * Wait for the browser process to be running.
163
+ *
164
+ * @param processPattern - Pattern to match browser process name
165
+ * @param timeout - Maximum wait time in seconds
166
+ * @throws {TimeoutError} If browser doesn't start within timeout
167
+ */
168
+ async waitForBrowser(processPattern, timeout) {
169
+ const startTime = Date.now();
170
+ const pollInterval = 0.5;
171
+ while (true) {
172
+ const elapsed = (Date.now() - startTime) / 1000;
173
+ if (elapsed > timeout) {
174
+ throw new errors_1.TimeoutError(`Browser '${this._browser}' did not start within ${timeout} seconds`);
175
+ }
176
+ // Check if browser process is running
177
+ const result = await this.exec('pgrep', '-f', processPattern);
178
+ if (result.exitCode === 0 && result.stdout.trim()) {
179
+ // Browser process found, give it a moment to initialize
180
+ await new Promise(resolve => setTimeout(resolve, 500));
181
+ return;
182
+ }
183
+ // Wait before retrying
184
+ await new Promise(resolve => setTimeout(resolve, pollInterval * 1000));
185
+ }
186
+ }
187
+ /**
188
+ * Get the connection endpoint for remote debugging.
189
+ *
190
+ * Returns the HTTP endpoint URL for Chrome DevTools Protocol.
191
+ * Use this with Puppeteer, Playwright, or Selenium to connect to the browser.
192
+ *
193
+ * @returns HTTP endpoint URL (e.g., 'http://localhost:9222')
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * const browser = new BrowserBox();
198
+ * try {
199
+ * await browser.start();
200
+ * const url = browser.endpoint();
201
+ *
202
+ * // Use with Puppeteer:
203
+ * // const browserWSEndpoint = await fetch(`${url}/json/version`)
204
+ * // .then(r => r.json())
205
+ * // .then(d => d.webSocketDebuggerUrl);
206
+ * // const browser = await puppeteer.connect({ browserWSEndpoint });
207
+ *
208
+ * // Use with Playwright:
209
+ * // const browser = await chromium.connectOverCDP(url);
210
+ * } finally {
211
+ * await browser.stop();
212
+ * }
213
+ * ```
214
+ */
215
+ endpoint() {
216
+ return `http://localhost:${this._port}`;
217
+ }
218
+ /**
219
+ * Override async disposal to start browser automatically.
220
+ *
221
+ * @internal
222
+ */
223
+ async [Symbol.asyncDispose]() {
224
+ await super[Symbol.asyncDispose]();
225
+ }
226
+ }
227
+ exports.BrowserBox = BrowserBox;
228
+ BrowserBox.DEFAULT_IMAGE = 'mcr.microsoft.com/playwright:v1.47.2-jammy';
229
+ BrowserBox.PORTS = {
230
+ chromium: constants.BROWSERBOX_PORT_CHROMIUM,
231
+ firefox: constants.BROWSERBOX_PORT_FIREFOX,
232
+ webkit: constants.BROWSERBOX_PORT_WEBKIT,
233
+ };
234
+ //# sourceMappingURL=browserbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserbox.js","sourceRoot":"","sources":["../lib/browserbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * CodeBox - Secure Python code execution container.
3
+ *
4
+ * Provides a simple, secure environment for running untrusted Python code.
5
+ */
6
+ import { SimpleBox, type SimpleBoxOptions } from './simplebox';
7
+ /**
8
+ * Options for creating a CodeBox.
9
+ */
10
+ export interface CodeBoxOptions extends Omit<SimpleBoxOptions, 'image'> {
11
+ /** Container image with Python (default: 'python:slim') */
12
+ image?: string;
13
+ }
14
+ /**
15
+ * Secure container for executing Python code.
16
+ *
17
+ * CodeBox provides an isolated environment for running untrusted Python code
18
+ * with built-in safety and result formatting.
19
+ *
20
+ * ## Usage
21
+ *
22
+ * ```typescript
23
+ * const codebox = new CodeBox();
24
+ * try {
25
+ * const result = await codebox.run("print('Hello, World!')");
26
+ * console.log(result); // Hello, World!
27
+ * } finally {
28
+ * await codebox.stop();
29
+ * }
30
+ * ```
31
+ *
32
+ * Or with async disposal (TypeScript 5.2+):
33
+ *
34
+ * ```typescript
35
+ * await using codebox = new CodeBox();
36
+ * const result = await codebox.run("print('Hello, World!')");
37
+ * // Automatically stopped when leaving scope
38
+ * ```
39
+ */
40
+ export declare class CodeBox extends SimpleBox {
41
+ /**
42
+ * Create a new CodeBox.
43
+ *
44
+ * @param options - CodeBox configuration options
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const codebox = new CodeBox({
49
+ * image: 'python:slim',
50
+ * memoryMib: 512,
51
+ * cpus: 2
52
+ * });
53
+ * ```
54
+ */
55
+ constructor(options?: CodeBoxOptions);
56
+ /**
57
+ * Execute Python code in the secure container.
58
+ *
59
+ * @param code - Python code to execute
60
+ *
61
+ * @returns Promise resolving to stdout output
62
+ * @throws {ExecError} If Python execution fails (non-zero exit code)
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const codebox = new CodeBox();
67
+ * try {
68
+ * const result = await codebox.run("print('Hello, World!')");
69
+ * console.log(result); // Hello, World!
70
+ * } finally {
71
+ * await codebox.stop();
72
+ * }
73
+ * ```
74
+ *
75
+ * @remarks
76
+ * Uses python3 from the container image.
77
+ * For custom Python paths, use exec() directly:
78
+ * ```typescript
79
+ * const result = await codebox.exec('/path/to/python', '-c', code);
80
+ * ```
81
+ */
82
+ run(code: string): Promise<string>;
83
+ /**
84
+ * Execute a Python script file in the container.
85
+ *
86
+ * @param scriptPath - Path to the Python script on the host
87
+ *
88
+ * @returns Promise resolving to execution output
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * const codebox = new CodeBox();
93
+ * try {
94
+ * const result = await codebox.runScript('./my_script.py');
95
+ * console.log(result);
96
+ * } finally {
97
+ * await codebox.stop();
98
+ * }
99
+ * ```
100
+ */
101
+ runScript(scriptPath: string): Promise<string>;
102
+ /**
103
+ * Install a Python package in the container using pip.
104
+ *
105
+ * @param packageName - Package name (e.g., 'requests', 'numpy==1.24.0')
106
+ *
107
+ * @returns Promise resolving to installation output
108
+ * @throws {ExecError} If pip installation fails
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const codebox = new CodeBox();
113
+ * try {
114
+ * await codebox.installPackage('requests');
115
+ * const result = await codebox.run('import requests; print(requests.__version__)');
116
+ * console.log(result);
117
+ * } finally {
118
+ * await codebox.stop();
119
+ * }
120
+ * ```
121
+ */
122
+ installPackage(packageName: string): Promise<string>;
123
+ /**
124
+ * Install multiple Python packages.
125
+ *
126
+ * @param packages - Package names to install
127
+ *
128
+ * @returns Promise resolving to installation output
129
+ * @throws {ExecError} If pip installation fails
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * const codebox = new CodeBox();
134
+ * try {
135
+ * await codebox.installPackages('requests', 'numpy', 'pandas');
136
+ * const result = await codebox.run('import requests, numpy, pandas');
137
+ * } finally {
138
+ * await codebox.stop();
139
+ * }
140
+ * ```
141
+ */
142
+ installPackages(...packages: string[]): Promise<string>;
143
+ }
144
+ //# sourceMappingURL=codebox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebox.d.ts","sourceRoot":"","sources":["../lib/codebox.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/D;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACrE,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,OAAQ,SAAQ,SAAS;IACpC;;;;;;;;;;;;;OAaG;gBACS,OAAO,GAAE,cAAmB;IAOxC;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACG,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQxC;;;;;;;;;;;;;;;;;OAiBG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMpD;;;;;;;;;;;;;;;;;;;OAmBG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ1D;;;;;;;;;;;;;;;;;;OAkBG;IACG,eAAe,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAO9D"}
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ /**
3
+ * CodeBox - Secure Python code execution container.
4
+ *
5
+ * Provides a simple, secure environment for running untrusted Python code.
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.CodeBox = void 0;
42
+ const simplebox_1 = require("./simplebox");
43
+ const errors_1 = require("./errors");
44
+ /**
45
+ * Secure container for executing Python code.
46
+ *
47
+ * CodeBox provides an isolated environment for running untrusted Python code
48
+ * with built-in safety and result formatting.
49
+ *
50
+ * ## Usage
51
+ *
52
+ * ```typescript
53
+ * const codebox = new CodeBox();
54
+ * try {
55
+ * const result = await codebox.run("print('Hello, World!')");
56
+ * console.log(result); // Hello, World!
57
+ * } finally {
58
+ * await codebox.stop();
59
+ * }
60
+ * ```
61
+ *
62
+ * Or with async disposal (TypeScript 5.2+):
63
+ *
64
+ * ```typescript
65
+ * await using codebox = new CodeBox();
66
+ * const result = await codebox.run("print('Hello, World!')");
67
+ * // Automatically stopped when leaving scope
68
+ * ```
69
+ */
70
+ class CodeBox extends simplebox_1.SimpleBox {
71
+ /**
72
+ * Create a new CodeBox.
73
+ *
74
+ * @param options - CodeBox configuration options
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const codebox = new CodeBox({
79
+ * image: 'python:slim',
80
+ * memoryMib: 512,
81
+ * cpus: 2
82
+ * });
83
+ * ```
84
+ */
85
+ constructor(options = {}) {
86
+ super({
87
+ ...options,
88
+ image: options.image ?? 'python:slim',
89
+ });
90
+ }
91
+ /**
92
+ * Execute Python code in the secure container.
93
+ *
94
+ * @param code - Python code to execute
95
+ *
96
+ * @returns Promise resolving to stdout output
97
+ * @throws {ExecError} If Python execution fails (non-zero exit code)
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * const codebox = new CodeBox();
102
+ * try {
103
+ * const result = await codebox.run("print('Hello, World!')");
104
+ * console.log(result); // Hello, World!
105
+ * } finally {
106
+ * await codebox.stop();
107
+ * }
108
+ * ```
109
+ *
110
+ * @remarks
111
+ * Uses python3 from the container image.
112
+ * For custom Python paths, use exec() directly:
113
+ * ```typescript
114
+ * const result = await codebox.exec('/path/to/python', '-c', code);
115
+ * ```
116
+ */
117
+ async run(code) {
118
+ const result = await this.exec('/usr/local/bin/python', '-c', code);
119
+ if (result.exitCode !== 0) {
120
+ throw new errors_1.ExecError('run()', result.exitCode, result.stderr);
121
+ }
122
+ return result.stdout;
123
+ }
124
+ /**
125
+ * Execute a Python script file in the container.
126
+ *
127
+ * @param scriptPath - Path to the Python script on the host
128
+ *
129
+ * @returns Promise resolving to execution output
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * const codebox = new CodeBox();
134
+ * try {
135
+ * const result = await codebox.runScript('./my_script.py');
136
+ * console.log(result);
137
+ * } finally {
138
+ * await codebox.stop();
139
+ * }
140
+ * ```
141
+ */
142
+ async runScript(scriptPath) {
143
+ const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
144
+ const code = await fs.readFile(scriptPath, 'utf-8');
145
+ return this.run(code);
146
+ }
147
+ /**
148
+ * Install a Python package in the container using pip.
149
+ *
150
+ * @param packageName - Package name (e.g., 'requests', 'numpy==1.24.0')
151
+ *
152
+ * @returns Promise resolving to installation output
153
+ * @throws {ExecError} If pip installation fails
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * const codebox = new CodeBox();
158
+ * try {
159
+ * await codebox.installPackage('requests');
160
+ * const result = await codebox.run('import requests; print(requests.__version__)');
161
+ * console.log(result);
162
+ * } finally {
163
+ * await codebox.stop();
164
+ * }
165
+ * ```
166
+ */
167
+ async installPackage(packageName) {
168
+ const result = await this.exec('pip', 'install', packageName);
169
+ if (result.exitCode !== 0) {
170
+ throw new errors_1.ExecError(`installPackage('${packageName}')`, result.exitCode, result.stderr);
171
+ }
172
+ return result.stdout;
173
+ }
174
+ /**
175
+ * Install multiple Python packages.
176
+ *
177
+ * @param packages - Package names to install
178
+ *
179
+ * @returns Promise resolving to installation output
180
+ * @throws {ExecError} If pip installation fails
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * const codebox = new CodeBox();
185
+ * try {
186
+ * await codebox.installPackages('requests', 'numpy', 'pandas');
187
+ * const result = await codebox.run('import requests, numpy, pandas');
188
+ * } finally {
189
+ * await codebox.stop();
190
+ * }
191
+ * ```
192
+ */
193
+ async installPackages(...packages) {
194
+ const result = await this.exec('pip', 'install', ...packages);
195
+ if (result.exitCode !== 0) {
196
+ throw new errors_1.ExecError(`installPackages(${packages.join(', ')})`, result.exitCode, result.stderr);
197
+ }
198
+ return result.stdout;
199
+ }
200
+ }
201
+ exports.CodeBox = CodeBox;
202
+ //# sourceMappingURL=codebox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebox.js","sourceRoot":"","sources":["../lib/codebox.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,2CAA+D;AAC/D,qCAAqC;AAUrC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAa,OAAQ,SAAQ,qBAAS;IACpC;;;;;;;;;;;;;OAaG;IACH,YAAY,UAA0B,EAAE;QACtC,KAAK,CAAC;YACJ,GAAG,OAAO;YACV,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,aAAa;SACtC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,KAAK,CAAC,GAAG,CAAC,IAAY;QACpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACpE,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,kBAAS,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,SAAS,CAAC,UAAkB;QAChC,MAAM,EAAE,GAAG,wDAAa,aAAa,GAAC,CAAC;QACvC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,KAAK,CAAC,cAAc,CAAC,WAAmB;QACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QAC9D,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,kBAAS,CAAC,mBAAmB,WAAW,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1F,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,eAAe,CAAC,GAAG,QAAkB;QACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC,CAAC;QAC9D,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,kBAAS,CAAC,mBAAmB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACjG,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;CACF;AAtID,0BAsIC"}