isol8 0.12.1 → 0.12.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/cli.js
CHANGED
|
@@ -55592,13 +55592,39 @@ function validatePackageName(name) {
|
|
|
55592
55592
|
}
|
|
55593
55593
|
|
|
55594
55594
|
// src/engine/image-builder.ts
|
|
55595
|
+
var exports_image_builder = {};
|
|
55596
|
+
__export(exports_image_builder, {
|
|
55597
|
+
normalizePackages: () => normalizePackages,
|
|
55598
|
+
imageExists: () => imageExists,
|
|
55599
|
+
getCustomImageTag: () => getCustomImageTag,
|
|
55600
|
+
ensureImages: () => ensureImages,
|
|
55601
|
+
buildCustomImages: () => buildCustomImages,
|
|
55602
|
+
buildCustomImage: () => buildCustomImage,
|
|
55603
|
+
buildBaseImages: () => buildBaseImages
|
|
55604
|
+
});
|
|
55595
55605
|
import { createHash as createHash2 } from "node:crypto";
|
|
55596
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
55597
|
-
import { join as join3 } from "node:path";
|
|
55606
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
|
|
55607
|
+
import { dirname, join as join3 } from "node:path";
|
|
55598
55608
|
function resolveDockerDir() {
|
|
55599
|
-
const
|
|
55600
|
-
if (existsSync3(
|
|
55601
|
-
return
|
|
55609
|
+
const fromExec = join3(dirname(process.execPath), "docker");
|
|
55610
|
+
if (existsSync3(fromExec) && statSync2(fromExec).isDirectory()) {
|
|
55611
|
+
return fromExec;
|
|
55612
|
+
}
|
|
55613
|
+
if (!import.meta.url.includes("$bunfs")) {
|
|
55614
|
+
const fromBundled = new URL("./docker", import.meta.url).pathname;
|
|
55615
|
+
if (existsSync3(fromBundled)) {
|
|
55616
|
+
return fromBundled;
|
|
55617
|
+
}
|
|
55618
|
+
}
|
|
55619
|
+
if (!import.meta.url.includes("$bunfs")) {
|
|
55620
|
+
const fromDev = new URL("../../docker", import.meta.url).pathname;
|
|
55621
|
+
if (existsSync3(fromDev)) {
|
|
55622
|
+
return fromDev;
|
|
55623
|
+
}
|
|
55624
|
+
}
|
|
55625
|
+
const fromCwd = join3(process.cwd(), "docker");
|
|
55626
|
+
if (existsSync3(fromCwd)) {
|
|
55627
|
+
return fromCwd;
|
|
55602
55628
|
}
|
|
55603
55629
|
return new URL("../../docker", import.meta.url).pathname;
|
|
55604
55630
|
}
|
|
@@ -55650,8 +55676,9 @@ async function removeImage(docker, imageId) {
|
|
|
55650
55676
|
logger.debug(`[ImageBuilder] Could not remove image ${imageId.slice(0, 12)}: ${err}`);
|
|
55651
55677
|
}
|
|
55652
55678
|
}
|
|
55653
|
-
async function buildBaseImages(docker, onProgress, force = false) {
|
|
55654
|
-
const
|
|
55679
|
+
async function buildBaseImages(docker, onProgress, force = false, onlyRuntimes) {
|
|
55680
|
+
const allRuntimes = RuntimeRegistry.list();
|
|
55681
|
+
const runtimes = onlyRuntimes ? allRuntimes.filter((r) => onlyRuntimes.includes(r.name)) : allRuntimes;
|
|
55655
55682
|
const dockerHash = computeDockerDirHash();
|
|
55656
55683
|
logger.debug(`[ImageBuilder] Docker directory hash: ${dockerHash.slice(0, 16)}...`);
|
|
55657
55684
|
for (const adapter of runtimes) {
|
|
@@ -55801,6 +55828,26 @@ ${installCmd}
|
|
|
55801
55828
|
}
|
|
55802
55829
|
onProgress?.({ runtime, status: "done" });
|
|
55803
55830
|
}
|
|
55831
|
+
async function imageExists(docker, imageName) {
|
|
55832
|
+
try {
|
|
55833
|
+
await docker.getImage(imageName).inspect();
|
|
55834
|
+
return true;
|
|
55835
|
+
} catch {
|
|
55836
|
+
return false;
|
|
55837
|
+
}
|
|
55838
|
+
}
|
|
55839
|
+
async function ensureImages(docker, onProgress) {
|
|
55840
|
+
const runtimes = RuntimeRegistry.list();
|
|
55841
|
+
const missing = [];
|
|
55842
|
+
for (const adapter of runtimes) {
|
|
55843
|
+
if (!await imageExists(docker, adapter.image)) {
|
|
55844
|
+
missing.push(adapter.name);
|
|
55845
|
+
}
|
|
55846
|
+
}
|
|
55847
|
+
if (missing.length > 0) {
|
|
55848
|
+
await buildBaseImages(docker, onProgress, false, missing);
|
|
55849
|
+
}
|
|
55850
|
+
}
|
|
55804
55851
|
var DOCKERFILE_DIR, LABELS, DOCKER_BUILD_FILES;
|
|
55805
55852
|
var init_image_builder = __esm(() => {
|
|
55806
55853
|
init_runtime();
|
|
@@ -56699,6 +56746,25 @@ class DockerIsol8 {
|
|
|
56699
56746
|
resolvedImage = legacyCustomTag;
|
|
56700
56747
|
} catch {}
|
|
56701
56748
|
}
|
|
56749
|
+
try {
|
|
56750
|
+
await this.docker.getImage(resolvedImage).inspect();
|
|
56751
|
+
} catch {
|
|
56752
|
+
logger.debug(`[ImageBuilder] Image ${resolvedImage} not found. Building...`);
|
|
56753
|
+
const { buildBaseImages: buildBaseImages2, buildCustomImage: buildCustomImage2 } = await Promise.resolve().then(() => (init_image_builder(), exports_image_builder));
|
|
56754
|
+
if (resolvedImage !== adapter.image && normalizedDeps.length > 0) {
|
|
56755
|
+
try {
|
|
56756
|
+
await this.docker.getImage(adapter.image).inspect();
|
|
56757
|
+
} catch {
|
|
56758
|
+
logger.debug(`[ImageBuilder] Base image ${adapter.image} missing. Building...`);
|
|
56759
|
+
await buildBaseImages2(this.docker, undefined, false, [adapter.name]);
|
|
56760
|
+
}
|
|
56761
|
+
logger.debug(`[ImageBuilder] Building custom image for ${adapter.name}...`);
|
|
56762
|
+
await buildCustomImage2(this.docker, adapter.name, normalizedDeps);
|
|
56763
|
+
} else {
|
|
56764
|
+
logger.debug(`[ImageBuilder] Building base image for ${adapter.name}...`);
|
|
56765
|
+
await buildBaseImages2(this.docker, undefined, false, [adapter.name]);
|
|
56766
|
+
}
|
|
56767
|
+
}
|
|
56702
56768
|
this.imageCache.set(cacheKey, resolvedImage);
|
|
56703
56769
|
return resolvedImage;
|
|
56704
56770
|
}
|
|
@@ -57272,7 +57338,7 @@ var package_default;
|
|
|
57272
57338
|
var init_package = __esm(() => {
|
|
57273
57339
|
package_default = {
|
|
57274
57340
|
name: "isol8",
|
|
57275
|
-
version: "0.12.
|
|
57341
|
+
version: "0.12.1",
|
|
57276
57342
|
description: "Secure code execution engine for AI agents",
|
|
57277
57343
|
author: "Illusion47586",
|
|
57278
57344
|
license: "MIT",
|
|
@@ -63571,4 +63637,4 @@ if (!process.argv.slice(2).length) {
|
|
|
63571
63637
|
}
|
|
63572
63638
|
program2.parse();
|
|
63573
63639
|
|
|
63574
|
-
//# debugId=
|
|
63640
|
+
//# debugId=D193290D2EBA50ED64756E2164756E21
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
2
3
|
var __export = (target, all) => {
|
|
3
4
|
for (var name in all)
|
|
@@ -9,6 +10,7 @@ var __export = (target, all) => {
|
|
|
9
10
|
});
|
|
10
11
|
};
|
|
11
12
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
13
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
12
14
|
|
|
13
15
|
// src/runtime/adapter.ts
|
|
14
16
|
var adapters, extensionMap, RuntimeRegistry;
|
|
@@ -613,16 +615,161 @@ var init_default_seccomp_profile = __esm(() => {
|
|
|
613
615
|
});
|
|
614
616
|
});
|
|
615
617
|
|
|
618
|
+
// src/engine/utils.ts
|
|
619
|
+
var exports_utils = {};
|
|
620
|
+
__export(exports_utils, {
|
|
621
|
+
validatePackageName: () => validatePackageName,
|
|
622
|
+
truncateOutput: () => truncateOutput,
|
|
623
|
+
parseMemoryLimit: () => parseMemoryLimit,
|
|
624
|
+
maskSecrets: () => maskSecrets,
|
|
625
|
+
extractFromTar: () => extractFromTar,
|
|
626
|
+
createTarBuffer: () => createTarBuffer
|
|
627
|
+
});
|
|
628
|
+
function parseMemoryLimit(limit) {
|
|
629
|
+
const match = limit.match(/^(\d+(?:\.\d+)?)\s*([kmgt]?)b?$/i);
|
|
630
|
+
if (!match) {
|
|
631
|
+
throw new Error(`Invalid memory limit format: "${limit}". Use e.g. "512m", "1g".`);
|
|
632
|
+
}
|
|
633
|
+
const value = Number.parseFloat(match[1]);
|
|
634
|
+
const unit = (match[2] || "b").toLowerCase();
|
|
635
|
+
const multipliers = {
|
|
636
|
+
b: 1,
|
|
637
|
+
k: 1024,
|
|
638
|
+
m: 1024 ** 2,
|
|
639
|
+
g: 1024 ** 3,
|
|
640
|
+
t: 1024 ** 4
|
|
641
|
+
};
|
|
642
|
+
return Math.floor(value * (multipliers[unit] ?? 1));
|
|
643
|
+
}
|
|
644
|
+
function truncateOutput(output, maxBytes) {
|
|
645
|
+
const encoder = new TextEncoder;
|
|
646
|
+
const bytes = encoder.encode(output);
|
|
647
|
+
if (bytes.length <= maxBytes) {
|
|
648
|
+
return { text: output, truncated: false };
|
|
649
|
+
}
|
|
650
|
+
const decoder = new TextDecoder("utf-8", { fatal: false });
|
|
651
|
+
const truncated = decoder.decode(bytes.slice(0, maxBytes));
|
|
652
|
+
return {
|
|
653
|
+
text: `${truncated}
|
|
654
|
+
|
|
655
|
+
--- OUTPUT TRUNCATED (${bytes.length} bytes, limit: ${maxBytes}) ---`,
|
|
656
|
+
truncated: true
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
function maskSecrets(text, secrets) {
|
|
660
|
+
let result = text;
|
|
661
|
+
for (const value of Object.values(secrets)) {
|
|
662
|
+
if (value.length > 0) {
|
|
663
|
+
result = result.replaceAll(value, "***");
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
return result;
|
|
667
|
+
}
|
|
668
|
+
function createTarBuffer(filePath, content) {
|
|
669
|
+
const data = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
|
|
670
|
+
const headerSize = 512;
|
|
671
|
+
const dataBlocks = Math.ceil(data.length / 512);
|
|
672
|
+
const totalSize = headerSize + dataBlocks * 512 + 1024;
|
|
673
|
+
const buf = Buffer.alloc(totalSize);
|
|
674
|
+
buf.write(filePath.replace(/^\//, ""), 0, 100, "utf-8");
|
|
675
|
+
buf.write("0000644\x00", 100, 8, "utf-8");
|
|
676
|
+
buf.write("0000000\x00", 108, 8, "utf-8");
|
|
677
|
+
buf.write("0000000\x00", 116, 8, "utf-8");
|
|
678
|
+
buf.write(`${data.length.toString(8).padStart(11, "0")}\x00`, 124, 12, "utf-8");
|
|
679
|
+
buf.write(`${Math.floor(Date.now() / 1000).toString(8).padStart(11, "0")}\x00`, 136, 12, "utf-8");
|
|
680
|
+
buf.write("0", 156, 1, "utf-8");
|
|
681
|
+
buf.write("ustar\x00", 257, 6, "utf-8");
|
|
682
|
+
buf.write("00", 263, 2, "utf-8");
|
|
683
|
+
buf.write(" ", 148, 8, "utf-8");
|
|
684
|
+
let checksum = 0;
|
|
685
|
+
for (let i = 0;i < headerSize; i++) {
|
|
686
|
+
checksum += buf[i];
|
|
687
|
+
}
|
|
688
|
+
buf.write(`${checksum.toString(8).padStart(6, "0")}\x00 `, 148, 8, "utf-8");
|
|
689
|
+
data.copy(buf, headerSize);
|
|
690
|
+
return buf;
|
|
691
|
+
}
|
|
692
|
+
function extractFromTar(tarBuffer, targetPath) {
|
|
693
|
+
const normalizedTarget = targetPath.replace(/^\//, "");
|
|
694
|
+
const basename = targetPath.split("/").pop() ?? targetPath;
|
|
695
|
+
let offset = 0;
|
|
696
|
+
while (offset < tarBuffer.length - 512) {
|
|
697
|
+
const nameEnd = tarBuffer.indexOf(0, offset);
|
|
698
|
+
const name = tarBuffer.subarray(offset, Math.min(nameEnd, offset + 100)).toString("utf-8");
|
|
699
|
+
if (name.length === 0) {
|
|
700
|
+
break;
|
|
701
|
+
}
|
|
702
|
+
const sizeStr = tarBuffer.subarray(offset + 124, offset + 136).toString("utf-8").trim();
|
|
703
|
+
const size = Number.parseInt(sizeStr, 8);
|
|
704
|
+
if (Number.isNaN(size)) {
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
const dataStart = offset + 512;
|
|
708
|
+
const dataBlocks = Math.ceil(size / 512);
|
|
709
|
+
if (name === normalizedTarget || name.endsWith(`/${normalizedTarget}`) || name === basename) {
|
|
710
|
+
return Buffer.from(tarBuffer.subarray(dataStart, dataStart + size));
|
|
711
|
+
}
|
|
712
|
+
offset = dataStart + dataBlocks * 512;
|
|
713
|
+
}
|
|
714
|
+
throw new Error(`File "${targetPath}" not found in tar archive`);
|
|
715
|
+
}
|
|
716
|
+
function validatePackageName(name) {
|
|
717
|
+
if (!/^[@a-zA-Z0-9_./\-=]+$/.test(name)) {
|
|
718
|
+
throw new Error(`Invalid package name: "${name}". Only alphanumeric, -, _, ., /, @, and = are allowed.`);
|
|
719
|
+
}
|
|
720
|
+
return name;
|
|
721
|
+
}
|
|
722
|
+
|
|
616
723
|
// src/engine/image-builder.ts
|
|
724
|
+
var exports_image_builder = {};
|
|
725
|
+
__export(exports_image_builder, {
|
|
726
|
+
normalizePackages: () => normalizePackages,
|
|
727
|
+
imageExists: () => imageExists,
|
|
728
|
+
getCustomImageTag: () => getCustomImageTag,
|
|
729
|
+
ensureImages: () => ensureImages,
|
|
730
|
+
buildCustomImages: () => buildCustomImages,
|
|
731
|
+
buildCustomImage: () => buildCustomImage,
|
|
732
|
+
buildBaseImages: () => buildBaseImages
|
|
733
|
+
});
|
|
617
734
|
import { createHash as createHash2 } from "node:crypto";
|
|
618
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
735
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
|
|
736
|
+
import { dirname, join as join3 } from "node:path";
|
|
619
737
|
function resolveDockerDir() {
|
|
620
|
-
const
|
|
621
|
-
if (existsSync3(
|
|
622
|
-
return
|
|
738
|
+
const fromExec = join3(dirname(process.execPath), "docker");
|
|
739
|
+
if (existsSync3(fromExec) && statSync2(fromExec).isDirectory()) {
|
|
740
|
+
return fromExec;
|
|
741
|
+
}
|
|
742
|
+
if (!import.meta.url.includes("$bunfs")) {
|
|
743
|
+
const fromBundled = new URL("./docker", import.meta.url).pathname;
|
|
744
|
+
if (existsSync3(fromBundled)) {
|
|
745
|
+
return fromBundled;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
if (!import.meta.url.includes("$bunfs")) {
|
|
749
|
+
const fromDev = new URL("../../docker", import.meta.url).pathname;
|
|
750
|
+
if (existsSync3(fromDev)) {
|
|
751
|
+
return fromDev;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
const fromCwd = join3(process.cwd(), "docker");
|
|
755
|
+
if (existsSync3(fromCwd)) {
|
|
756
|
+
return fromCwd;
|
|
623
757
|
}
|
|
624
758
|
return new URL("../../docker", import.meta.url).pathname;
|
|
625
759
|
}
|
|
760
|
+
function computeDockerDirHash() {
|
|
761
|
+
const hash = createHash2("sha256");
|
|
762
|
+
const files = [...DOCKER_BUILD_FILES].sort();
|
|
763
|
+
for (const file of files) {
|
|
764
|
+
const filePath = join3(DOCKERFILE_DIR, file);
|
|
765
|
+
if (existsSync3(filePath)) {
|
|
766
|
+
const content = readFileSync2(filePath);
|
|
767
|
+
hash.update(file);
|
|
768
|
+
hash.update(content);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
return hash.digest("hex");
|
|
772
|
+
}
|
|
626
773
|
function computeDepsHash(runtime, packages) {
|
|
627
774
|
const hash = createHash2("sha256");
|
|
628
775
|
hash.update(runtime);
|
|
@@ -640,11 +787,206 @@ function getCustomImageTag(runtime, packages) {
|
|
|
640
787
|
const shortHash = depsHash.slice(0, 12);
|
|
641
788
|
return `isol8:${runtime}-custom-${shortHash}`;
|
|
642
789
|
}
|
|
643
|
-
|
|
790
|
+
async function getImageLabels(docker, imageName) {
|
|
791
|
+
try {
|
|
792
|
+
const image = docker.getImage(imageName);
|
|
793
|
+
const inspect = await image.inspect();
|
|
794
|
+
return inspect.Config?.Labels ?? {};
|
|
795
|
+
} catch {
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
async function removeImage(docker, imageId) {
|
|
800
|
+
try {
|
|
801
|
+
const image = docker.getImage(imageId);
|
|
802
|
+
await image.remove();
|
|
803
|
+
logger.debug(`[ImageBuilder] Removed old image: ${imageId.slice(0, 12)}`);
|
|
804
|
+
} catch (err) {
|
|
805
|
+
logger.debug(`[ImageBuilder] Could not remove image ${imageId.slice(0, 12)}: ${err}`);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
async function buildBaseImages(docker, onProgress, force = false, onlyRuntimes) {
|
|
809
|
+
const allRuntimes = RuntimeRegistry.list();
|
|
810
|
+
const runtimes = onlyRuntimes ? allRuntimes.filter((r) => onlyRuntimes.includes(r.name)) : allRuntimes;
|
|
811
|
+
const dockerHash = computeDockerDirHash();
|
|
812
|
+
logger.debug(`[ImageBuilder] Docker directory hash: ${dockerHash.slice(0, 16)}...`);
|
|
813
|
+
for (const adapter of runtimes) {
|
|
814
|
+
const target = adapter.name;
|
|
815
|
+
const imageName = adapter.image;
|
|
816
|
+
if (!force) {
|
|
817
|
+
const labels = await getImageLabels(docker, imageName);
|
|
818
|
+
if (labels && labels[LABELS.dockerHash] === dockerHash) {
|
|
819
|
+
logger.debug(`[ImageBuilder] Base image ${target} is up to date, skipping build`);
|
|
820
|
+
onProgress?.({ runtime: target, status: "done", message: "Up to date" });
|
|
821
|
+
continue;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
let oldImageId = null;
|
|
825
|
+
try {
|
|
826
|
+
const oldImage = await docker.getImage(imageName).inspect();
|
|
827
|
+
oldImageId = oldImage.Id;
|
|
828
|
+
logger.debug(`[ImageBuilder] Existing image ${target} ID: ${oldImageId.slice(0, 12)}`);
|
|
829
|
+
} catch {
|
|
830
|
+
logger.debug(`[ImageBuilder] No existing image for ${target}`);
|
|
831
|
+
}
|
|
832
|
+
onProgress?.({ runtime: target, status: "building" });
|
|
833
|
+
try {
|
|
834
|
+
const stream = await docker.buildImage({ context: DOCKERFILE_DIR, src: DOCKER_BUILD_FILES }, {
|
|
835
|
+
t: imageName,
|
|
836
|
+
target,
|
|
837
|
+
dockerfile: "Dockerfile",
|
|
838
|
+
labels: {
|
|
839
|
+
[LABELS.dockerHash]: dockerHash
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
await new Promise((resolve2, reject) => {
|
|
843
|
+
docker.modem.followProgress(stream, (err) => {
|
|
844
|
+
if (err) {
|
|
845
|
+
reject(err);
|
|
846
|
+
} else {
|
|
847
|
+
resolve2();
|
|
848
|
+
}
|
|
849
|
+
});
|
|
850
|
+
});
|
|
851
|
+
if (oldImageId) {
|
|
852
|
+
await removeImage(docker, oldImageId);
|
|
853
|
+
}
|
|
854
|
+
onProgress?.({ runtime: target, status: "done" });
|
|
855
|
+
} catch (err) {
|
|
856
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
857
|
+
onProgress?.({ runtime: target, status: "error", message });
|
|
858
|
+
throw new Error(`Failed to build image for ${target}: ${message}`);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
async function buildCustomImages(docker, config, onProgress, force = false) {
|
|
863
|
+
const deps = config.dependencies;
|
|
864
|
+
const python = deps.python ? normalizePackages(deps.python) : [];
|
|
865
|
+
const node = deps.node ? normalizePackages(deps.node) : [];
|
|
866
|
+
const bun = deps.bun ? normalizePackages(deps.bun) : [];
|
|
867
|
+
const deno = deps.deno ? normalizePackages(deps.deno) : [];
|
|
868
|
+
const bash = deps.bash ? normalizePackages(deps.bash) : [];
|
|
869
|
+
if (python.length) {
|
|
870
|
+
await buildCustomImage(docker, "python", python, onProgress, force);
|
|
871
|
+
}
|
|
872
|
+
if (node.length) {
|
|
873
|
+
await buildCustomImage(docker, "node", node, onProgress, force);
|
|
874
|
+
}
|
|
875
|
+
if (bun.length) {
|
|
876
|
+
await buildCustomImage(docker, "bun", bun, onProgress, force);
|
|
877
|
+
}
|
|
878
|
+
if (deno.length) {
|
|
879
|
+
await buildCustomImage(docker, "deno", deno, onProgress, force);
|
|
880
|
+
}
|
|
881
|
+
if (bash.length) {
|
|
882
|
+
await buildCustomImage(docker, "bash", bash, onProgress, force);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
async function buildCustomImage(docker, runtime, packages, onProgress, force = false) {
|
|
886
|
+
const normalizedPackages = normalizePackages(packages);
|
|
887
|
+
const tag = getCustomImageTag(runtime, normalizedPackages);
|
|
888
|
+
const depsHash = computeDepsHash(runtime, normalizedPackages);
|
|
889
|
+
logger.debug(`[ImageBuilder] ${runtime} custom deps hash: ${depsHash.slice(0, 16)}...`);
|
|
890
|
+
if (!force) {
|
|
891
|
+
const labels = await getImageLabels(docker, tag);
|
|
892
|
+
if (labels && labels[LABELS.depsHash] === depsHash) {
|
|
893
|
+
logger.debug(`[ImageBuilder] Custom image ${runtime} is up to date, skipping build`);
|
|
894
|
+
onProgress?.({ runtime, status: "done", message: "Up to date" });
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
let oldImageId = null;
|
|
899
|
+
try {
|
|
900
|
+
const oldImage = await docker.getImage(tag).inspect();
|
|
901
|
+
oldImageId = oldImage.Id;
|
|
902
|
+
logger.debug(`[ImageBuilder] Existing custom image ${runtime} ID: ${oldImageId.slice(0, 12)}`);
|
|
903
|
+
} catch {
|
|
904
|
+
logger.debug(`[ImageBuilder] No existing custom image for ${runtime}`);
|
|
905
|
+
}
|
|
906
|
+
onProgress?.({
|
|
907
|
+
runtime,
|
|
908
|
+
status: "building",
|
|
909
|
+
message: `Custom: ${normalizedPackages.join(", ")}`
|
|
910
|
+
});
|
|
911
|
+
let installCmd;
|
|
912
|
+
switch (runtime) {
|
|
913
|
+
case "python":
|
|
914
|
+
installCmd = `RUN pip install --no-cache-dir ${normalizedPackages.join(" ")}`;
|
|
915
|
+
break;
|
|
916
|
+
case "node":
|
|
917
|
+
installCmd = `RUN npm install -g ${normalizedPackages.join(" ")}`;
|
|
918
|
+
break;
|
|
919
|
+
case "bun":
|
|
920
|
+
installCmd = `RUN bun install -g ${normalizedPackages.join(" ")}`;
|
|
921
|
+
break;
|
|
922
|
+
case "deno":
|
|
923
|
+
installCmd = normalizedPackages.map((p) => `RUN deno cache ${p}`).join(`
|
|
924
|
+
`);
|
|
925
|
+
break;
|
|
926
|
+
case "bash":
|
|
927
|
+
installCmd = `RUN apk add --no-cache ${normalizedPackages.join(" ")}`;
|
|
928
|
+
break;
|
|
929
|
+
default:
|
|
930
|
+
throw new Error(`Unknown runtime: ${runtime}`);
|
|
931
|
+
}
|
|
932
|
+
const dockerfileContent = `FROM isol8:${runtime}
|
|
933
|
+
${installCmd}
|
|
934
|
+
`;
|
|
935
|
+
const { createTarBuffer: createTarBuffer2, validatePackageName: validatePackageName2 } = await Promise.resolve().then(() => exports_utils);
|
|
936
|
+
const { Readable } = await import("node:stream");
|
|
937
|
+
normalizedPackages.forEach(validatePackageName2);
|
|
938
|
+
const tarBuffer = createTarBuffer2("Dockerfile", dockerfileContent);
|
|
939
|
+
const stream = await docker.buildImage(Readable.from(tarBuffer), {
|
|
940
|
+
t: tag,
|
|
941
|
+
dockerfile: "Dockerfile",
|
|
942
|
+
labels: {
|
|
943
|
+
[LABELS.depsHash]: depsHash
|
|
944
|
+
}
|
|
945
|
+
});
|
|
946
|
+
await new Promise((resolve2, reject) => {
|
|
947
|
+
docker.modem.followProgress(stream, (err) => {
|
|
948
|
+
if (err) {
|
|
949
|
+
reject(err);
|
|
950
|
+
} else {
|
|
951
|
+
resolve2();
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
});
|
|
955
|
+
if (oldImageId) {
|
|
956
|
+
await removeImage(docker, oldImageId);
|
|
957
|
+
}
|
|
958
|
+
onProgress?.({ runtime, status: "done" });
|
|
959
|
+
}
|
|
960
|
+
async function imageExists(docker, imageName) {
|
|
961
|
+
try {
|
|
962
|
+
await docker.getImage(imageName).inspect();
|
|
963
|
+
return true;
|
|
964
|
+
} catch {
|
|
965
|
+
return false;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
async function ensureImages(docker, onProgress) {
|
|
969
|
+
const runtimes = RuntimeRegistry.list();
|
|
970
|
+
const missing = [];
|
|
971
|
+
for (const adapter of runtimes) {
|
|
972
|
+
if (!await imageExists(docker, adapter.image)) {
|
|
973
|
+
missing.push(adapter.name);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
if (missing.length > 0) {
|
|
977
|
+
await buildBaseImages(docker, onProgress, false, missing);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
var DOCKERFILE_DIR, LABELS, DOCKER_BUILD_FILES;
|
|
644
981
|
var init_image_builder = __esm(() => {
|
|
645
982
|
init_runtime();
|
|
646
983
|
init_logger();
|
|
647
984
|
DOCKERFILE_DIR = resolveDockerDir();
|
|
985
|
+
LABELS = {
|
|
986
|
+
dockerHash: "org.isol8.build.hash",
|
|
987
|
+
depsHash: "org.isol8.deps.hash"
|
|
988
|
+
};
|
|
989
|
+
DOCKER_BUILD_FILES = ["Dockerfile", "proxy.sh", "proxy-handler.sh"];
|
|
648
990
|
});
|
|
649
991
|
|
|
650
992
|
// src/engine/pool.ts
|
|
@@ -926,96 +1268,6 @@ function calculateResourceDelta(before, after) {
|
|
|
926
1268
|
};
|
|
927
1269
|
}
|
|
928
1270
|
|
|
929
|
-
// src/engine/utils.ts
|
|
930
|
-
function parseMemoryLimit(limit) {
|
|
931
|
-
const match = limit.match(/^(\d+(?:\.\d+)?)\s*([kmgt]?)b?$/i);
|
|
932
|
-
if (!match) {
|
|
933
|
-
throw new Error(`Invalid memory limit format: "${limit}". Use e.g. "512m", "1g".`);
|
|
934
|
-
}
|
|
935
|
-
const value = Number.parseFloat(match[1]);
|
|
936
|
-
const unit = (match[2] || "b").toLowerCase();
|
|
937
|
-
const multipliers = {
|
|
938
|
-
b: 1,
|
|
939
|
-
k: 1024,
|
|
940
|
-
m: 1024 ** 2,
|
|
941
|
-
g: 1024 ** 3,
|
|
942
|
-
t: 1024 ** 4
|
|
943
|
-
};
|
|
944
|
-
return Math.floor(value * (multipliers[unit] ?? 1));
|
|
945
|
-
}
|
|
946
|
-
function truncateOutput(output, maxBytes) {
|
|
947
|
-
const encoder = new TextEncoder;
|
|
948
|
-
const bytes = encoder.encode(output);
|
|
949
|
-
if (bytes.length <= maxBytes) {
|
|
950
|
-
return { text: output, truncated: false };
|
|
951
|
-
}
|
|
952
|
-
const decoder = new TextDecoder("utf-8", { fatal: false });
|
|
953
|
-
const truncated = decoder.decode(bytes.slice(0, maxBytes));
|
|
954
|
-
return {
|
|
955
|
-
text: `${truncated}
|
|
956
|
-
|
|
957
|
-
--- OUTPUT TRUNCATED (${bytes.length} bytes, limit: ${maxBytes}) ---`,
|
|
958
|
-
truncated: true
|
|
959
|
-
};
|
|
960
|
-
}
|
|
961
|
-
function maskSecrets(text, secrets) {
|
|
962
|
-
let result = text;
|
|
963
|
-
for (const value of Object.values(secrets)) {
|
|
964
|
-
if (value.length > 0) {
|
|
965
|
-
result = result.replaceAll(value, "***");
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
return result;
|
|
969
|
-
}
|
|
970
|
-
function createTarBuffer(filePath, content) {
|
|
971
|
-
const data = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
|
|
972
|
-
const headerSize = 512;
|
|
973
|
-
const dataBlocks = Math.ceil(data.length / 512);
|
|
974
|
-
const totalSize = headerSize + dataBlocks * 512 + 1024;
|
|
975
|
-
const buf = Buffer.alloc(totalSize);
|
|
976
|
-
buf.write(filePath.replace(/^\//, ""), 0, 100, "utf-8");
|
|
977
|
-
buf.write("0000644\x00", 100, 8, "utf-8");
|
|
978
|
-
buf.write("0000000\x00", 108, 8, "utf-8");
|
|
979
|
-
buf.write("0000000\x00", 116, 8, "utf-8");
|
|
980
|
-
buf.write(`${data.length.toString(8).padStart(11, "0")}\x00`, 124, 12, "utf-8");
|
|
981
|
-
buf.write(`${Math.floor(Date.now() / 1000).toString(8).padStart(11, "0")}\x00`, 136, 12, "utf-8");
|
|
982
|
-
buf.write("0", 156, 1, "utf-8");
|
|
983
|
-
buf.write("ustar\x00", 257, 6, "utf-8");
|
|
984
|
-
buf.write("00", 263, 2, "utf-8");
|
|
985
|
-
buf.write(" ", 148, 8, "utf-8");
|
|
986
|
-
let checksum = 0;
|
|
987
|
-
for (let i = 0;i < headerSize; i++) {
|
|
988
|
-
checksum += buf[i];
|
|
989
|
-
}
|
|
990
|
-
buf.write(`${checksum.toString(8).padStart(6, "0")}\x00 `, 148, 8, "utf-8");
|
|
991
|
-
data.copy(buf, headerSize);
|
|
992
|
-
return buf;
|
|
993
|
-
}
|
|
994
|
-
function extractFromTar(tarBuffer, targetPath) {
|
|
995
|
-
const normalizedTarget = targetPath.replace(/^\//, "");
|
|
996
|
-
const basename = targetPath.split("/").pop() ?? targetPath;
|
|
997
|
-
let offset = 0;
|
|
998
|
-
while (offset < tarBuffer.length - 512) {
|
|
999
|
-
const nameEnd = tarBuffer.indexOf(0, offset);
|
|
1000
|
-
const name = tarBuffer.subarray(offset, Math.min(nameEnd, offset + 100)).toString("utf-8");
|
|
1001
|
-
if (name.length === 0) {
|
|
1002
|
-
break;
|
|
1003
|
-
}
|
|
1004
|
-
const sizeStr = tarBuffer.subarray(offset + 124, offset + 136).toString("utf-8").trim();
|
|
1005
|
-
const size = Number.parseInt(sizeStr, 8);
|
|
1006
|
-
if (Number.isNaN(size)) {
|
|
1007
|
-
break;
|
|
1008
|
-
}
|
|
1009
|
-
const dataStart = offset + 512;
|
|
1010
|
-
const dataBlocks = Math.ceil(size / 512);
|
|
1011
|
-
if (name === normalizedTarget || name.endsWith(`/${normalizedTarget}`) || name === basename) {
|
|
1012
|
-
return Buffer.from(tarBuffer.subarray(dataStart, dataStart + size));
|
|
1013
|
-
}
|
|
1014
|
-
offset = dataStart + dataBlocks * 512;
|
|
1015
|
-
}
|
|
1016
|
-
throw new Error(`File "${targetPath}" not found in tar archive`);
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
1271
|
// src/engine/docker.ts
|
|
1020
1272
|
var exports_docker = {};
|
|
1021
1273
|
__export(exports_docker, {
|
|
@@ -1624,6 +1876,25 @@ class DockerIsol8 {
|
|
|
1624
1876
|
resolvedImage = legacyCustomTag;
|
|
1625
1877
|
} catch {}
|
|
1626
1878
|
}
|
|
1879
|
+
try {
|
|
1880
|
+
await this.docker.getImage(resolvedImage).inspect();
|
|
1881
|
+
} catch {
|
|
1882
|
+
logger.debug(`[ImageBuilder] Image ${resolvedImage} not found. Building...`);
|
|
1883
|
+
const { buildBaseImages: buildBaseImages2, buildCustomImage: buildCustomImage2 } = await Promise.resolve().then(() => (init_image_builder(), exports_image_builder));
|
|
1884
|
+
if (resolvedImage !== adapter.image && normalizedDeps.length > 0) {
|
|
1885
|
+
try {
|
|
1886
|
+
await this.docker.getImage(adapter.image).inspect();
|
|
1887
|
+
} catch {
|
|
1888
|
+
logger.debug(`[ImageBuilder] Base image ${adapter.image} missing. Building...`);
|
|
1889
|
+
await buildBaseImages2(this.docker, undefined, false, [adapter.name]);
|
|
1890
|
+
}
|
|
1891
|
+
logger.debug(`[ImageBuilder] Building custom image for ${adapter.name}...`);
|
|
1892
|
+
await buildCustomImage2(this.docker, adapter.name, normalizedDeps);
|
|
1893
|
+
} else {
|
|
1894
|
+
logger.debug(`[ImageBuilder] Building base image for ${adapter.name}...`);
|
|
1895
|
+
await buildBaseImages2(this.docker, undefined, false, [adapter.name]);
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1627
1898
|
this.imageCache.set(cacheKey, resolvedImage);
|
|
1628
1899
|
return resolvedImage;
|
|
1629
1900
|
}
|
|
@@ -2445,7 +2716,7 @@ init_logger();
|
|
|
2445
2716
|
// package.json
|
|
2446
2717
|
var package_default = {
|
|
2447
2718
|
name: "isol8",
|
|
2448
|
-
version: "0.12.
|
|
2719
|
+
version: "0.12.1",
|
|
2449
2720
|
description: "Secure code execution engine for AI agents",
|
|
2450
2721
|
author: "Illusion47586",
|
|
2451
2722
|
license: "MIT",
|
|
@@ -2878,4 +3149,4 @@ export {
|
|
|
2878
3149
|
BunAdapter
|
|
2879
3150
|
};
|
|
2880
3151
|
|
|
2881
|
-
//# debugId=
|
|
3152
|
+
//# debugId=134AC8BB795B367A64756E2164756E21
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../../src/engine/docker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,MAAM,MAAM,WAAW,CAAC;AAG/B,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EAEf,WAAW,EAEX,YAAY,EAKZ,YAAY,EACZ,WAAW,EACZ,MAAM,UAAU,CAAC;AAuWlB,2HAA2H;AAC3H,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,WAAY,YAAW,WAAW;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAsB;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4C;IACrE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IAEpD,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;YAE1C,uBAAuB;IA6BrC;;;OAGG;gBACS,OAAO,GAAE,kBAAuB,EAAE,aAAa,SAAK;IA4ChE;;;;;OAKG;IACG,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCtD,kFAAkF;IAC5E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAgB9D;;OAEG;YACW,WAAW;IAoDzB;;OAEG;YACW,qBAAqB;IA8CnC;;OAEG;YACW,kBAAkB;IA+DhC;;;;;;;OAOG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYpE;;;;;;OAMG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmB5C,6GAA6G;IAC7G,IAAI,WAAW,IAAI,MAAM,GAAG,IAAI,CAE/B;IAED;;;OAGG;IACI,aAAa,CAAC,GAAG,EAAE,gBAAgB,GAAG,aAAa,CAAC,WAAW,CAAC;YAuFzD,YAAY;
|
|
1
|
+
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../../src/engine/docker.ts"],"names":[],"mappings":"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"}
|
|
@@ -43,7 +43,7 @@ type ProgressCallback = (progress: BuildProgress) => void;
|
|
|
43
43
|
* @param onProgress - Optional callback for build progress updates.
|
|
44
44
|
* @param force - If true, always rebuild even if image is up to date.
|
|
45
45
|
*/
|
|
46
|
-
export declare function buildBaseImages(docker: Docker, onProgress?: ProgressCallback, force?: boolean): Promise<void>;
|
|
46
|
+
export declare function buildBaseImages(docker: Docker, onProgress?: ProgressCallback, force?: boolean, onlyRuntimes?: string[]): Promise<void>;
|
|
47
47
|
/**
|
|
48
48
|
* Builds custom images with user-specified dependencies layered on top of
|
|
49
49
|
* the base images. Reads package lists from the config's `dependencies` field.
|
|
@@ -58,6 +58,7 @@ export declare function buildBaseImages(docker: Docker, onProgress?: ProgressCal
|
|
|
58
58
|
* @param force - If true, always rebuild even if image is up to date.
|
|
59
59
|
*/
|
|
60
60
|
export declare function buildCustomImages(docker: Docker, config: Isol8Config, onProgress?: ProgressCallback, force?: boolean): Promise<void>;
|
|
61
|
+
export declare function buildCustomImage(docker: Docker, runtime: import("../types").Runtime | string, packages: string[], onProgress?: ProgressCallback, force?: boolean): Promise<void>;
|
|
61
62
|
/**
|
|
62
63
|
* Checks if an image exists locally.
|
|
63
64
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-builder.d.ts","sourceRoot":"","sources":["../../../src/engine/image-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,MAAM,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"image-builder.d.ts","sourceRoot":"","sources":["../../../src/engine/image-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,MAAM,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AA6F5C;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAK7E;AAkCD,mDAAmD;AACnD,UAAU,aAAa;IACrB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;IACtC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,KAAK,gBAAgB,GAAG,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;AAE1D;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,gBAAgB,EAC7B,KAAK,UAAQ,EACb,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAuEf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,EACnB,UAAU,CAAC,EAAE,gBAAgB,EAC7B,KAAK,UAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,UAAU,EAAE,OAAO,GAAG,MAAM,EAC5C,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,CAAC,EAAE,gBAAgB,EAC7B,KAAK,UAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,CA2Ff;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOrF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAa/F"}
|