docker-client-mx 1.35.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/LICENSE +21 -0
- package/README.md +233 -0
- package/bin/docker-client-mx.js +42 -0
- package/build/icons/icon-1024.png +0 -0
- package/build/icons/icon-128.png +0 -0
- package/build/icons/icon-16.png +0 -0
- package/build/icons/icon-256.png +0 -0
- package/build/icons/icon-32.png +0 -0
- package/build/icons/icon-48.png +0 -0
- package/build/icons/icon-512.png +0 -0
- package/build/icons/icon-64.png +0 -0
- package/build/icons/icon.ico +0 -0
- package/build/icons/icon.iconset/icon_128x128.png +0 -0
- package/build/icons/icon.iconset/icon_128x128@2x.png +0 -0
- package/build/icons/icon.iconset/icon_16x16.png +0 -0
- package/build/icons/icon.iconset/icon_16x16@2x.png +0 -0
- package/build/icons/icon.iconset/icon_256x256.png +0 -0
- package/build/icons/icon.iconset/icon_256x256@2x.png +0 -0
- package/build/icons/icon.iconset/icon_32x32.png +0 -0
- package/build/icons/icon.iconset/icon_32x32@2x.png +0 -0
- package/build/icons/icon.iconset/icon_512x512.png +0 -0
- package/build/icons/icon.iconset/icon_512x512@2x.png +0 -0
- package/build/icons/icon.png +0 -0
- package/dist/docker-desktop-mx/browser/chunk-64WWLMUP.js +39 -0
- package/dist/docker-desktop-mx/browser/chunk-N4VBBC4W.js +1 -0
- package/dist/docker-desktop-mx/browser/favicon.ico +0 -0
- package/dist/docker-desktop-mx/browser/index.html +14 -0
- package/dist/docker-desktop-mx/browser/main-CTIRTSOI.js +5 -0
- package/dist/docker-desktop-mx/browser/styles-JS3HDDI4.css +1 -0
- package/dist-electron/api.js +10 -0
- package/dist-electron/api.js.map +1 -0
- package/dist-electron/assistant-key.js +70 -0
- package/dist-electron/assistant-key.js.map +1 -0
- package/dist-electron/assistant-models.js +19 -0
- package/dist-electron/assistant-models.js.map +1 -0
- package/dist-electron/assistant-tools.js +335 -0
- package/dist-electron/assistant-tools.js.map +1 -0
- package/dist-electron/assistant.js +302 -0
- package/dist-electron/assistant.js.map +1 -0
- package/dist-electron/attention.js +75 -0
- package/dist-electron/attention.js.map +1 -0
- package/dist-electron/channels.js +113 -0
- package/dist-electron/channels.js.map +1 -0
- package/dist-electron/compose-files.js +104 -0
- package/dist-electron/compose-files.js.map +1 -0
- package/dist-electron/compose.js +271 -0
- package/dist-electron/compose.js.map +1 -0
- package/dist-electron/container-events.js +188 -0
- package/dist-electron/container-events.js.map +1 -0
- package/dist-electron/containers.js +165 -0
- package/dist-electron/containers.js.map +1 -0
- package/dist-electron/context-menu.js +56 -0
- package/dist-electron/context-menu.js.map +1 -0
- package/dist-electron/contexts.js +346 -0
- package/dist-electron/contexts.js.map +1 -0
- package/dist-electron/crash.js +129 -0
- package/dist-electron/crash.js.map +1 -0
- package/dist-electron/diagnosis.js +338 -0
- package/dist-electron/diagnosis.js.map +1 -0
- package/dist-electron/docker-client.js +284 -0
- package/dist-electron/docker-client.js.map +1 -0
- package/dist-electron/engine.js +145 -0
- package/dist-electron/engine.js.map +1 -0
- package/dist-electron/event-store.js +146 -0
- package/dist-electron/event-store.js.map +1 -0
- package/dist-electron/events.js +132 -0
- package/dist-electron/events.js.map +1 -0
- package/dist-electron/exec.js +138 -0
- package/dist-electron/exec.js.map +1 -0
- package/dist-electron/files.js +407 -0
- package/dist-electron/files.js.map +1 -0
- package/dist-electron/health.js +92 -0
- package/dist-electron/health.js.map +1 -0
- package/dist-electron/host-overview.js +50 -0
- package/dist-electron/host-overview.js.map +1 -0
- package/dist-electron/host-shell.js +196 -0
- package/dist-electron/host-shell.js.map +1 -0
- package/dist-electron/i18n.js +58 -0
- package/dist-electron/i18n.js.map +1 -0
- package/dist-electron/image-history.js +87 -0
- package/dist-electron/image-history.js.map +1 -0
- package/dist-electron/images.js +141 -0
- package/dist-electron/images.js.map +1 -0
- package/dist-electron/ipc.js +783 -0
- package/dist-electron/ipc.js.map +1 -0
- package/dist-electron/links.js +46 -0
- package/dist-electron/links.js.map +1 -0
- package/dist-electron/logs.js +153 -0
- package/dist-electron/logs.js.map +1 -0
- package/dist-electron/main.js +494 -0
- package/dist-electron/main.js.map +1 -0
- package/dist-electron/merged-logs.js +127 -0
- package/dist-electron/merged-logs.js.map +1 -0
- package/dist-electron/navigation.js +37 -0
- package/dist-electron/navigation.js.map +1 -0
- package/dist-electron/ndjson.js +30 -0
- package/dist-electron/ndjson.js.map +1 -0
- package/dist-electron/networks.js +507 -0
- package/dist-electron/networks.js.map +1 -0
- package/dist-electron/port-conflicts.js +106 -0
- package/dist-electron/port-conflicts.js.map +1 -0
- package/dist-electron/preload.js +257 -0
- package/dist-electron/preload.js.map +1 -0
- package/dist-electron/pull.js +220 -0
- package/dist-electron/pull.js.map +1 -0
- package/dist-electron/redact.js +129 -0
- package/dist-electron/redact.js.map +1 -0
- package/dist-electron/registry-auth.js +150 -0
- package/dist-electron/registry-auth.js.map +1 -0
- package/dist-electron/renew.js +162 -0
- package/dist-electron/renew.js.map +1 -0
- package/dist-electron/restart-policy.js +58 -0
- package/dist-electron/restart-policy.js.map +1 -0
- package/dist-electron/run-command.js +146 -0
- package/dist-electron/run-command.js.map +1 -0
- package/dist-electron/run.js +151 -0
- package/dist-electron/run.js.map +1 -0
- package/dist-electron/self-update.js +163 -0
- package/dist-electron/self-update.js.map +1 -0
- package/dist-electron/servers.js +108 -0
- package/dist-electron/servers.js.map +1 -0
- package/dist-electron/settings.js +146 -0
- package/dist-electron/settings.js.map +1 -0
- package/dist-electron/ssh.js +574 -0
- package/dist-electron/ssh.js.map +1 -0
- package/dist-electron/stats.js +209 -0
- package/dist-electron/stats.js.map +1 -0
- package/dist-electron/streams.js +63 -0
- package/dist-electron/streams.js.map +1 -0
- package/dist-electron/system.js +123 -0
- package/dist-electron/system.js.map +1 -0
- package/dist-electron/terminal-transcript.js +55 -0
- package/dist-electron/terminal-transcript.js.map +1 -0
- package/dist-electron/updates.js +136 -0
- package/dist-electron/updates.js.map +1 -0
- package/dist-electron/volume-backup.js +203 -0
- package/dist-electron/volume-backup.js.map +1 -0
- package/dist-electron/volume-files.js +124 -0
- package/dist-electron/volume-files.js.map +1 -0
- package/dist-electron/volumes.js +253 -0
- package/dist-electron/volumes.js.map +1 -0
- package/dist-electron/wiring-watch.js +93 -0
- package/dist-electron/wiring-watch.js.map +1 -0
- package/dist-electron/wiring.js +71 -0
- package/dist-electron/wiring.js.map +1 -0
- package/dist-electron/wsl.js +167 -0
- package/dist-electron/wsl.js.map +1 -0
- package/package.json +125 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.normalizeContainerPath = normalizeContainerPath;
|
|
37
|
+
exports.parseListing = parseListing;
|
|
38
|
+
exports.describeListProblem = describeListProblem;
|
|
39
|
+
exports.withoutParents = withoutParents;
|
|
40
|
+
exports.toChanges = toChanges;
|
|
41
|
+
exports.listChanges = listChanges;
|
|
42
|
+
exports.listDirectory = listDirectory;
|
|
43
|
+
exports.downloadPath = downloadPath;
|
|
44
|
+
exports.extractSingleFile = extractSingleFile;
|
|
45
|
+
exports.uploadFiles = uploadFiles;
|
|
46
|
+
const node_fs_1 = require("node:fs");
|
|
47
|
+
const promises_1 = require("node:fs/promises");
|
|
48
|
+
const path = __importStar(require("node:path"));
|
|
49
|
+
const node_stream_1 = require("node:stream");
|
|
50
|
+
const promises_2 = require("node:stream/promises");
|
|
51
|
+
const tar = __importStar(require("tar-stream"));
|
|
52
|
+
const docker_client_1 = require("./docker-client");
|
|
53
|
+
const i18n_1 = require("./i18n");
|
|
54
|
+
/**
|
|
55
|
+
* Het bestandssysteem van een container: bladeren, downloaden en uploaden.
|
|
56
|
+
*
|
|
57
|
+
* Downloaden en uploaden gaan via `getArchive` en `putArchive` van de Engine API, zonder shell
|
|
58
|
+
* en zonder `docker cp`, en werken ook bij een gestopte container. Bladeren kan dat niet: de
|
|
59
|
+
* Engine API beschrijft één pad, maar somt geen map op, en `getArchive` op `/` zou het hele
|
|
60
|
+
* bestandssysteem streamen om de namen van de eerste laag te vinden. Daarvoor draaien we `ls`
|
|
61
|
+
* in de container, met argumenten en niet via een shell. Dat vraagt een draaiende container
|
|
62
|
+
* met `ls`; bij een distroless-image zegt de tab dat.
|
|
63
|
+
*/
|
|
64
|
+
/** Zoveel symlinks volgen we bij een download; een kring houdt zo vanzelf op. */
|
|
65
|
+
const MAX_LINK_HOPS = 8;
|
|
66
|
+
/** Zo lang mag `ls` erover doen. Een map met tienduizenden bestanden is nog ruim binnen de tijd. */
|
|
67
|
+
const LIST_TIMEOUT_MS = 10_000;
|
|
68
|
+
/**
|
|
69
|
+
* Maakt van een pad uit de renderer een net, absoluut POSIX-pad. `..` wordt opgelost, niet
|
|
70
|
+
* geweigerd: in de container is dat gewoon de bovenliggende map, en naar buiten kan niet.
|
|
71
|
+
*/
|
|
72
|
+
function normalizeContainerPath(input) {
|
|
73
|
+
if (input.includes('\0')) {
|
|
74
|
+
throw new Error((0, i18n_1.t)({
|
|
75
|
+
en: 'A path may not contain a null byte.',
|
|
76
|
+
nl: 'Een pad mag geen nulbyte bevatten.',
|
|
77
|
+
de: 'Ein Pfad darf kein Nullbyte enthalten.',
|
|
78
|
+
fr: 'Un chemin ne peut pas contenir d’octet nul.',
|
|
79
|
+
es: 'Una ruta no puede contener un byte nulo.',
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
return path.posix.normalize(path.posix.join('/', input));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Leest de uitvoer van `ls -1Ap`: één naam per regel, een map met een `/` erachter. Mappen
|
|
86
|
+
* eerst, dan bestanden, allebei op naam; zo staat wat je in wilt eerst.
|
|
87
|
+
*/
|
|
88
|
+
function parseListing(output) {
|
|
89
|
+
return output
|
|
90
|
+
.split('\n')
|
|
91
|
+
.filter((line) => line !== '')
|
|
92
|
+
.map((line) => (line.endsWith('/') ? { name: line.slice(0, -1), kind: 'dir' } : { name: line, kind: 'file' }))
|
|
93
|
+
.sort((a, b) => (a.kind === b.kind ? a.name.localeCompare(b.name) : a.kind === 'dir' ? -1 : 1));
|
|
94
|
+
}
|
|
95
|
+
/** Een fout van exec of ls in gewone taal. */
|
|
96
|
+
function describeListProblem(text, dir) {
|
|
97
|
+
const lower = text.toLowerCase();
|
|
98
|
+
if (lower.includes('is not running')) {
|
|
99
|
+
return (0, i18n_1.t)({
|
|
100
|
+
en: 'Start the container to browse its files.',
|
|
101
|
+
nl: 'Start de container om door zijn bestanden te bladeren.',
|
|
102
|
+
de: 'Starten Sie den Container, um seine Dateien zu durchsuchen.',
|
|
103
|
+
fr: 'Démarrez le conteneur pour parcourir ses fichiers.',
|
|
104
|
+
es: 'Inicia el contenedor para explorar sus archivos.',
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (lower.includes('executable file not found') || lower.includes('no such file or directory: unknown')) {
|
|
108
|
+
return (0, i18n_1.t)({
|
|
109
|
+
en: 'This container has no ls, for example because it is a distroless image. Browsing is not possible here.',
|
|
110
|
+
nl: 'Deze container heeft geen ls, bijvoorbeeld omdat het een distroless-image is. Bladeren kan hier niet.',
|
|
111
|
+
de: 'Dieser Container hat kein ls, zum Beispiel weil es ein distroless-Image ist. Durchsuchen ist hier nicht möglich.',
|
|
112
|
+
fr: 'Ce conteneur n’a pas de ls, par exemple parce que c’est une image distroless. La navigation n’est pas possible ici.',
|
|
113
|
+
es: 'Este contenedor no tiene ls, por ejemplo porque es una image distroless. Aquí no se puede explorar.',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (lower.includes('no such file') || lower.includes('not found')) {
|
|
117
|
+
return (0, i18n_1.t)({
|
|
118
|
+
en: `${dir} does not exist in this container.`,
|
|
119
|
+
nl: `${dir} bestaat niet in deze container.`,
|
|
120
|
+
de: `${dir} gibt es in diesem Container nicht.`,
|
|
121
|
+
fr: `${dir} n’existe pas dans ce conteneur.`,
|
|
122
|
+
es: `${dir} no existe en este contenedor.`,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
if (lower.includes('permission denied')) {
|
|
126
|
+
return (0, i18n_1.t)({
|
|
127
|
+
en: `No access to ${dir} for the user the container runs as.`,
|
|
128
|
+
nl: `Geen toegang tot ${dir} voor de gebruiker waarmee de container draait.`,
|
|
129
|
+
de: `Kein Zugriff auf ${dir} für den Benutzer, unter dem der Container läuft.`,
|
|
130
|
+
fr: `Aucun accès à ${dir} pour l’utilisateur sous lequel tourne le conteneur.`,
|
|
131
|
+
es: `Sin acceso a ${dir} para el usuario con el que se ejecuta el contenedor.`,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return (0, i18n_1.t)({
|
|
135
|
+
en: `Could not read ${dir}: ${text.trim()}`,
|
|
136
|
+
nl: `Kon ${dir} niet lezen: ${text.trim()}`,
|
|
137
|
+
de: `${dir} konnte nicht gelesen werden: ${text.trim()}`,
|
|
138
|
+
fr: `Impossible de lire ${dir} : ${text.trim()}`,
|
|
139
|
+
es: `No se ha podido leer ${dir}: ${text.trim()}`,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/** Draait `ls` en geeft stdout, stderr en de afsluitcode terug. */
|
|
143
|
+
async function runLs(id, dir) {
|
|
144
|
+
const { docker } = (0, docker_client_1.getConnection)();
|
|
145
|
+
const exec = await docker.getContainer(id).exec({
|
|
146
|
+
// `--` zodat een map die met een streepje begint geen optie wordt.
|
|
147
|
+
Cmd: ['ls', '-1Ap', '--', dir],
|
|
148
|
+
AttachStdout: true,
|
|
149
|
+
AttachStderr: true,
|
|
150
|
+
});
|
|
151
|
+
const stream = (await exec.start({ hijack: true, stdin: false }));
|
|
152
|
+
const stdout = new node_stream_1.PassThrough();
|
|
153
|
+
const stderr = new node_stream_1.PassThrough();
|
|
154
|
+
const out = [];
|
|
155
|
+
const err = [];
|
|
156
|
+
stdout.on('data', (chunk) => out.push(chunk));
|
|
157
|
+
stderr.on('data', (chunk) => err.push(chunk));
|
|
158
|
+
// Zonder Tty zijn stdout en stderr in één stream verweven, met een kopje per blok.
|
|
159
|
+
docker.modem.demuxStream(stream, stdout, stderr);
|
|
160
|
+
await new Promise((resolve, reject) => {
|
|
161
|
+
const timer = setTimeout(() => {
|
|
162
|
+
stream.destroy();
|
|
163
|
+
reject(new Error((0, i18n_1.t)({
|
|
164
|
+
en: 'ls did not respond in time.',
|
|
165
|
+
nl: 'ls reageerde niet op tijd.',
|
|
166
|
+
de: 'ls hat nicht rechtzeitig geantwortet.',
|
|
167
|
+
fr: 'ls n’a pas répondu à temps.',
|
|
168
|
+
es: 'ls no ha respondido a tiempo.',
|
|
169
|
+
})));
|
|
170
|
+
}, LIST_TIMEOUT_MS);
|
|
171
|
+
stream.on('end', () => {
|
|
172
|
+
clearTimeout(timer);
|
|
173
|
+
resolve();
|
|
174
|
+
});
|
|
175
|
+
stream.on('error', (error) => {
|
|
176
|
+
clearTimeout(timer);
|
|
177
|
+
reject(error);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
const inspected = (await exec.inspect());
|
|
181
|
+
return { stdout: Buffer.concat(out).toString('utf8'), stderr: Buffer.concat(err).toString('utf8'), exitCode: inspected.ExitCode ?? 0 };
|
|
182
|
+
}
|
|
183
|
+
/** Docker's soorten in `/changes`: 0 gewijzigd, 1 toegevoegd, 2 verwijderd. */
|
|
184
|
+
const CHANGE_KINDS = ['modified', 'added', 'deleted'];
|
|
185
|
+
/**
|
|
186
|
+
* Haalt de mappen weg die alleen in de lijst staan omdat er iets ín zit.
|
|
187
|
+
*
|
|
188
|
+
* Docker markeert elke bovenliggende map als gewijzigd: één aangepaste `default.conf` levert
|
|
189
|
+
* ook `C /etc`, `C /etc/nginx` en `C /etc/nginx/conf.d` op. Die regels zeggen niets wat de
|
|
190
|
+
* regel eronder niet al zegt, en ze vormen het grootste deel van de lijst. Alleen een
|
|
191
|
+
* gewijzigde map verdwijnt zo; toegevoegd en verwijderd blijven altijd staan, want dat is de
|
|
192
|
+
* map zelf.
|
|
193
|
+
*/
|
|
194
|
+
function withoutParents(changes) {
|
|
195
|
+
const parents = new Set();
|
|
196
|
+
for (const change of changes) {
|
|
197
|
+
const parts = change.path.split('/').filter((part) => part !== '');
|
|
198
|
+
for (let index = 1; index < parts.length; index += 1) {
|
|
199
|
+
parents.add(`/${parts.slice(0, index).join('/')}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return changes.filter((change) => change.kind !== 'modified' || !parents.has(change.path));
|
|
203
|
+
}
|
|
204
|
+
/** Wat deze container veranderd heeft aan het bestandssysteem van zijn image. */
|
|
205
|
+
function toChanges(raw) {
|
|
206
|
+
const changes = raw
|
|
207
|
+
.filter((entry) => typeof entry.Path === 'string' && entry.Path !== '')
|
|
208
|
+
.map((entry) => ({ path: entry.Path, kind: CHANGE_KINDS[entry.Kind ?? 0] ?? 'modified' }));
|
|
209
|
+
return withoutParents(changes).sort((a, b) => a.path.localeCompare(b.path));
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Wat er afwijkt van de image, in één aanroep. Volumes tellen niet mee: die zitten niet in de
|
|
213
|
+
* schrijflaag van de container, en dat is precies waarom dit antwoord bruikbaar is.
|
|
214
|
+
*/
|
|
215
|
+
async function listChanges(id) {
|
|
216
|
+
try {
|
|
217
|
+
const { docker } = (0, docker_client_1.getConnection)();
|
|
218
|
+
const raw = (await docker.getContainer(id).changes());
|
|
219
|
+
return { ok: true, changes: toChanges(raw ?? []) };
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
return { ok: false, problem: err instanceof Error ? err.message : String(err) };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/** De inhoud van een map in de container. */
|
|
226
|
+
async function listDirectory(id, requested) {
|
|
227
|
+
const dir = normalizeContainerPath(requested);
|
|
228
|
+
try {
|
|
229
|
+
const result = await runLs(id, dir);
|
|
230
|
+
if (result.exitCode !== 0) {
|
|
231
|
+
return { ok: false, path: dir, problem: describeListProblem(result.stderr || result.stdout, dir) };
|
|
232
|
+
}
|
|
233
|
+
return { ok: true, path: dir, entries: parseListing(result.stdout) };
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
return { ok: false, path: dir, problem: describeListProblem(err instanceof Error ? err.message : String(err), dir) };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Downloadt een bestand of een map. Een bestand wordt het bestand zelf, uit het archief gehaald
|
|
241
|
+
* dat Docker levert; een map blijft dat archief, als `.tar`. Een map uitpakken op Windows zou
|
|
242
|
+
* rechten en symlinks verliezen die er in de container wel toe deden, en dat zie je dan niet.
|
|
243
|
+
*/
|
|
244
|
+
async function downloadPath(id, requested, kind, choose) {
|
|
245
|
+
const source = normalizeContainerPath(requested);
|
|
246
|
+
const name = path.posix.basename(source) || 'root';
|
|
247
|
+
const target = await choose(kind === 'dir' ? `${name}.tar` : name);
|
|
248
|
+
if (target === null) {
|
|
249
|
+
return { ok: true, savedTo: null };
|
|
250
|
+
}
|
|
251
|
+
try {
|
|
252
|
+
const { docker } = (0, docker_client_1.getConnection)();
|
|
253
|
+
const archive = (await docker.getContainer(id).getArchive({ path: source }));
|
|
254
|
+
if (kind === 'dir') {
|
|
255
|
+
await (0, promises_2.pipeline)(archive, (0, node_fs_1.createWriteStream)(target));
|
|
256
|
+
return { ok: true, savedTo: target };
|
|
257
|
+
}
|
|
258
|
+
await downloadFile(id, source, archive, target);
|
|
259
|
+
return { ok: true, savedTo: target };
|
|
260
|
+
}
|
|
261
|
+
catch (err) {
|
|
262
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
263
|
+
return { ok: false, problem: (0, i18n_1.t)({
|
|
264
|
+
en: `Downloading ${source} failed: ${reason}`,
|
|
265
|
+
nl: `Downloaden van ${source} mislukte: ${reason}`,
|
|
266
|
+
de: `Herunterladen von ${source} fehlgeschlagen: ${reason}`,
|
|
267
|
+
fr: `Le téléchargement de ${source} a échoué : ${reason}`,
|
|
268
|
+
es: `La descarga de ${source} ha fallado: ${reason}`,
|
|
269
|
+
}) };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Een bestand downloaden, ook als het een symlink is. `getArchive` levert dan de link en niet
|
|
274
|
+
* waar hij heen wijst; in alpine is zelfs /etc/os-release er een. We volgen hem zoals de
|
|
275
|
+
* container dat zou doen, relatief aan de map waar de link staat.
|
|
276
|
+
*/
|
|
277
|
+
async function downloadFile(id, source, first, target) {
|
|
278
|
+
const { docker } = (0, docker_client_1.getConnection)();
|
|
279
|
+
let current = source;
|
|
280
|
+
let archive = first;
|
|
281
|
+
for (let hop = 0; hop <= MAX_LINK_HOPS; hop += 1) {
|
|
282
|
+
const outcome = await extractSingleFile(archive, target);
|
|
283
|
+
if (outcome.kind === 'file') {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (outcome.kind === 'dir') {
|
|
287
|
+
throw new Error((0, i18n_1.t)({
|
|
288
|
+
en: `${current} is a folder; download it as a folder.`,
|
|
289
|
+
nl: `${current} is een map; download die als map.`,
|
|
290
|
+
de: `${current} ist ein Ordner; laden Sie ihn als Ordner herunter.`,
|
|
291
|
+
fr: `${current} est un dossier ; téléchargez-le en tant que dossier.`,
|
|
292
|
+
es: `${current} es una carpeta; descárgala como carpeta.`,
|
|
293
|
+
}));
|
|
294
|
+
}
|
|
295
|
+
current = path.posix.resolve(path.posix.dirname(current), outcome.linkTarget);
|
|
296
|
+
archive = (await docker.getContainer(id).getArchive({ path: current }));
|
|
297
|
+
}
|
|
298
|
+
throw new Error((0, i18n_1.t)({
|
|
299
|
+
en: `too many symlinks in a row from ${source}.`,
|
|
300
|
+
nl: `te veel symlinks achter elkaar vanaf ${source}.`,
|
|
301
|
+
de: `zu viele Symlinks hintereinander ab ${source}.`,
|
|
302
|
+
fr: `trop de liens symboliques à la suite depuis ${source}.`,
|
|
303
|
+
es: `demasiados symlinks seguidos desde ${source}.`,
|
|
304
|
+
}));
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Leest de eerste entry van een tar-stroom. Is het een bestand, dan gaat het naar `target`
|
|
308
|
+
* zonder het archief in het geheugen te houden; anders zegt het wat het wel was.
|
|
309
|
+
*/
|
|
310
|
+
async function extractSingleFile(archive, target) {
|
|
311
|
+
const extract = tar.extract();
|
|
312
|
+
let outcome = null;
|
|
313
|
+
archive.pipe(extract);
|
|
314
|
+
// tar-stream 3 is gebouwd op streamx en niet op Node-streams; de async iterator is de weg die
|
|
315
|
+
// het zelf aanraadt, en Readable.from maakt er voor pipeline weer een Node-stream van.
|
|
316
|
+
for await (const entry of extract) {
|
|
317
|
+
if (outcome === null && entry.header.type === 'file') {
|
|
318
|
+
await (0, promises_2.pipeline)(node_stream_1.Readable.from(entry), (0, node_fs_1.createWriteStream)(target));
|
|
319
|
+
outcome = { kind: 'file' };
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
if (outcome === null && entry.header.type === 'symlink' && entry.header.linkname) {
|
|
323
|
+
outcome = { kind: 'symlink', linkTarget: entry.header.linkname };
|
|
324
|
+
}
|
|
325
|
+
else if (outcome === null && entry.header.type === 'directory') {
|
|
326
|
+
outcome = { kind: 'dir' };
|
|
327
|
+
}
|
|
328
|
+
entry.resume();
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (outcome === null) {
|
|
332
|
+
throw new Error((0, i18n_1.t)({
|
|
333
|
+
en: 'there was no file in the archive.',
|
|
334
|
+
nl: 'er zat geen bestand in het archief.',
|
|
335
|
+
de: 'im Archiv war keine Datei.',
|
|
336
|
+
fr: 'il n’y avait aucun fichier dans l’archive.',
|
|
337
|
+
es: 'no había ningún archivo en el archivo comprimido.',
|
|
338
|
+
}));
|
|
339
|
+
}
|
|
340
|
+
return outcome;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Zet lokale bestanden in een map in de container. Alleen bestanden: een map meeslepen zou
|
|
344
|
+
* een recursieve inpakslag worden met zijn eigen randgevallen, en dat is voor later.
|
|
345
|
+
*/
|
|
346
|
+
async function uploadFiles(id, requested, localPaths) {
|
|
347
|
+
const dir = normalizeContainerPath(requested);
|
|
348
|
+
const files = [];
|
|
349
|
+
for (const local of localPaths) {
|
|
350
|
+
const info = await (0, promises_1.stat)(local);
|
|
351
|
+
if (!info.isFile()) {
|
|
352
|
+
const name = path.basename(local);
|
|
353
|
+
return { ok: false, problem: (0, i18n_1.t)({
|
|
354
|
+
en: `${name} is a folder. Only individual files can be uploaded.`,
|
|
355
|
+
nl: `${name} is een map. Alleen losse bestanden kunnen erin.`,
|
|
356
|
+
de: `${name} ist ein Ordner. Es lassen sich nur einzelne Dateien hochladen.`,
|
|
357
|
+
fr: `${name} est un dossier. Seuls des fichiers isolés peuvent être envoyés.`,
|
|
358
|
+
es: `${name} es una carpeta. Solo se pueden subir archivos sueltos.`,
|
|
359
|
+
}) };
|
|
360
|
+
}
|
|
361
|
+
files.push({ local, size: info.size, mtime: info.mtime, mode: 0o644 });
|
|
362
|
+
}
|
|
363
|
+
if (files.length === 0) {
|
|
364
|
+
return { ok: true, count: 0 };
|
|
365
|
+
}
|
|
366
|
+
const pack = tar.pack();
|
|
367
|
+
// Vullen terwijl Docker leest: zo gaat een groot bestand er als stroom doorheen. Een entry
|
|
368
|
+
// is een streamx-stream; pipe en de callback van entry() zijn de weg die tar-stream aanwijst.
|
|
369
|
+
const filled = (async () => {
|
|
370
|
+
for (const file of files) {
|
|
371
|
+
await new Promise((resolve, reject) => {
|
|
372
|
+
const entry = pack.entry({ name: path.basename(file.local), size: file.size, mtime: file.mtime, mode: file.mode }, (error) => (error ? reject(error) : resolve()));
|
|
373
|
+
(0, node_fs_1.createReadStream)(file.local).on('error', reject).pipe(entry);
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
pack.finalize();
|
|
377
|
+
})();
|
|
378
|
+
try {
|
|
379
|
+
const { docker } = (0, docker_client_1.getConnection)();
|
|
380
|
+
// docker-modem roept alleen .pipe() aan op wat het meekrijgt, en dat kan een streamx-stream.
|
|
381
|
+
await Promise.all([docker.getContainer(id).putArchive(pack, { path: dir }), filled]);
|
|
382
|
+
return { ok: true, count: files.length };
|
|
383
|
+
}
|
|
384
|
+
catch (err) {
|
|
385
|
+
pack.destroy();
|
|
386
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
387
|
+
return {
|
|
388
|
+
ok: false,
|
|
389
|
+
problem: message.toLowerCase().includes('not a directory') || message.includes('404')
|
|
390
|
+
? (0, i18n_1.t)({
|
|
391
|
+
en: `${dir} is not a folder in this container.`,
|
|
392
|
+
nl: `${dir} is geen map in deze container.`,
|
|
393
|
+
de: `${dir} ist kein Ordner in diesem Container.`,
|
|
394
|
+
fr: `${dir} n’est pas un dossier dans ce conteneur.`,
|
|
395
|
+
es: `${dir} no es una carpeta en este contenedor.`,
|
|
396
|
+
})
|
|
397
|
+
: (0, i18n_1.t)({
|
|
398
|
+
en: `Uploading to ${dir} failed: ${message}`,
|
|
399
|
+
nl: `Uploaden naar ${dir} mislukte: ${message}`,
|
|
400
|
+
de: `Hochladen nach ${dir} fehlgeschlagen: ${message}`,
|
|
401
|
+
fr: `L’envoi vers ${dir} a échoué : ${message}`,
|
|
402
|
+
es: `La subida a ${dir} ha fallado: ${message}`,
|
|
403
|
+
}),
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../electron/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toTest = toTest;
|
|
4
|
+
exports.toContainerHealth = toContainerHealth;
|
|
5
|
+
exports.readContainerHealth = readContainerHealth;
|
|
6
|
+
const docker_client_1 = require("./docker-client");
|
|
7
|
+
/**
|
|
8
|
+
* De healthcheck van een container: wat hij draait, en wat de laatste keren de uitslag was.
|
|
9
|
+
*
|
|
10
|
+
* Los van `containers.ts` omdat de omzetting het werk is. Docker levert het ritme in
|
|
11
|
+
* nanoseconden, zet `CMD` of `CMD-SHELL` voor het commando, en gebruikt `["NONE"]` om te zeggen
|
|
12
|
+
* dat de healthcheck uit staat. Dat zijn drie dingen die je stilletjes verkeerd doet, dus ze
|
|
13
|
+
* staan hier bij elkaar met een test eromheen.
|
|
14
|
+
*
|
|
15
|
+
* De uitvoer gaat ongeschoond naar de renderer, net als de logs: dit blijft in de app. De
|
|
16
|
+
* opschoning uit `redact.ts` is er voor de diagnose, die je ergens plakt.
|
|
17
|
+
*/
|
|
18
|
+
/** Docker's duurvelden zijn nanoseconden. */
|
|
19
|
+
const NS_PER_MS = 1_000_000;
|
|
20
|
+
/** Wat Docker een healthcheck noemt die uit staat. */
|
|
21
|
+
const DISABLED = 'NONE';
|
|
22
|
+
/** De wrappers die Docker voor het commando zet. `CMD-SHELL` betekent: één regel, via de shell. */
|
|
23
|
+
const WRAPPERS = new Set(['CMD', 'CMD-SHELL']);
|
|
24
|
+
const STATUSES = ['starting', 'healthy', 'unhealthy'];
|
|
25
|
+
/** Nanoseconden naar milliseconden. Nul betekent "niets ingevuld": dan geldt Docker's eigen standaard. */
|
|
26
|
+
function toMs(nanoseconds) {
|
|
27
|
+
if (nanoseconds === undefined || nanoseconds <= 0) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return Math.round(nanoseconds / NS_PER_MS);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Het commando zonder de wrapper. `["CMD", "pg_isready"]` wordt `["pg_isready"]`, en
|
|
34
|
+
* `["CMD-SHELL", "curl -f … || exit 1"]` wordt die ene regel.
|
|
35
|
+
*/
|
|
36
|
+
function toTest(test) {
|
|
37
|
+
const parts = test ?? [];
|
|
38
|
+
if (parts.length > 0 && WRAPPERS.has(parts[0])) {
|
|
39
|
+
return parts.slice(1);
|
|
40
|
+
}
|
|
41
|
+
return parts;
|
|
42
|
+
}
|
|
43
|
+
/** Of deze container een healthcheck heeft die iets doet. */
|
|
44
|
+
function hasCheck(raw) {
|
|
45
|
+
const test = raw.Config?.Healthcheck?.Test ?? [];
|
|
46
|
+
if (test.length > 0) {
|
|
47
|
+
return test[0] !== DISABLED;
|
|
48
|
+
}
|
|
49
|
+
// Zonder `Healthcheck` in Config kan er nog steeds een check uit de image komen; die zie je
|
|
50
|
+
// dan alleen terug aan de uitslagen die de daemon bijhoudt.
|
|
51
|
+
return raw.State?.Health?.Status !== undefined;
|
|
52
|
+
}
|
|
53
|
+
function toStatus(status) {
|
|
54
|
+
return STATUSES.find((known) => known === status) ?? null;
|
|
55
|
+
}
|
|
56
|
+
function toProbe(entry) {
|
|
57
|
+
return {
|
|
58
|
+
finishedAt: entry.End ?? null,
|
|
59
|
+
exitCode: entry.ExitCode ?? null,
|
|
60
|
+
output: entry.Output ?? '',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* De vorm die de renderer kent, of `null` als er niets te tonen is.
|
|
65
|
+
*
|
|
66
|
+
* De uitslagen gaan omgekeerd de deur uit. Docker bewaart ze oudste eerst, maar je leest van
|
|
67
|
+
* boven naar beneden en de laatste uitslag is degene waarvoor je kijkt.
|
|
68
|
+
*/
|
|
69
|
+
function toContainerHealth(raw) {
|
|
70
|
+
if (!hasCheck(raw)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const check = raw.Config?.Healthcheck;
|
|
74
|
+
const health = raw.State?.Health;
|
|
75
|
+
return {
|
|
76
|
+
status: toStatus(health?.Status),
|
|
77
|
+
failingStreak: health?.FailingStreak ?? 0,
|
|
78
|
+
test: toTest(check?.Test),
|
|
79
|
+
intervalMs: toMs(check?.Interval),
|
|
80
|
+
timeoutMs: toMs(check?.Timeout),
|
|
81
|
+
startPeriodMs: toMs(check?.StartPeriod),
|
|
82
|
+
retries: check?.Retries !== undefined && check.Retries > 0 ? check.Retries : null,
|
|
83
|
+
probes: [...(health?.Log ?? [])].reverse().map(toProbe),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/** De healthcheck van deze container, of `null` als hij er geen heeft. */
|
|
87
|
+
async function readContainerHealth(id) {
|
|
88
|
+
const { docker } = (0, docker_client_1.getConnection)();
|
|
89
|
+
const raw = (await docker.getContainer(id).inspect());
|
|
90
|
+
return toContainerHealth(raw);
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../electron/health.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderHostOverview = renderHostOverview;
|
|
4
|
+
const redact_1 = require("./redact");
|
|
5
|
+
/** Meer containers dan dit zet het overzicht niet op een rij; Claude kan ze zelf opvragen. */
|
|
6
|
+
const MAX_LISTED = 60;
|
|
7
|
+
/**
|
|
8
|
+
* Het begin van een gesprek over de host: welke engine, en welke containers er zijn. Kort
|
|
9
|
+
* gehouden: wat Claude meer wil weten, vraagt hij met de tools op. Geen geheimen: namen,
|
|
10
|
+
* images en toestanden, en de statustekst gaat nog door redactText.
|
|
11
|
+
*
|
|
12
|
+
* Engels, in beide talen: alleen Claude leest dit, net als de systeemprompt. De gebruiker ziet
|
|
13
|
+
* het niet, anders dan de diagnose van een container.
|
|
14
|
+
*/
|
|
15
|
+
function renderHostOverview(input) {
|
|
16
|
+
const { engine, containers } = input;
|
|
17
|
+
const lines = [
|
|
18
|
+
'## The Docker host',
|
|
19
|
+
'',
|
|
20
|
+
`- App: Docker Client MX ${input.appVersion}, context \`${input.context}\``,
|
|
21
|
+
`- Endpoint: \`${engine.endpoint}\``,
|
|
22
|
+
];
|
|
23
|
+
if (!engine.connected) {
|
|
24
|
+
lines.push(`- **No connection to the daemon:** ${engine.problem ?? 'unknown cause'}`);
|
|
25
|
+
}
|
|
26
|
+
if (engine.version !== undefined) {
|
|
27
|
+
lines.push(`- Engine: Docker ${engine.version.version} (API ${engine.version.apiVersion}), ${engine.version.os}/${engine.version.arch}`);
|
|
28
|
+
}
|
|
29
|
+
if (engine.info !== undefined) {
|
|
30
|
+
const info = engine.info;
|
|
31
|
+
lines.push(`- Host: \`${info.name}\`, ${String(info.cpus)} CPU's, ${String(Math.round(info.memoryBytes / 1024 ** 3))} GiB memory`, `- Containers: ${String(info.containers)} (${String(info.containersRunning)} running, ` +
|
|
32
|
+
`${String(info.containersPaused)} paused, ${String(info.containersStopped)} stopped), images: ${String(info.images)}`);
|
|
33
|
+
}
|
|
34
|
+
lines.push('', '### Containers', '');
|
|
35
|
+
if (containers.length === 0) {
|
|
36
|
+
lines.push('No containers.');
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
lines.push('| name | image | state | status | compose |', '| --- | --- | --- | --- | --- |');
|
|
40
|
+
for (const item of containers.slice(0, MAX_LISTED)) {
|
|
41
|
+
lines.push(`| ${item.name} | ${item.image} | ${item.state} | ${item.status} | ${item.composeProject ?? ''} |`);
|
|
42
|
+
}
|
|
43
|
+
if (containers.length > MAX_LISTED) {
|
|
44
|
+
lines.push('', `And ${String(containers.length - MAX_LISTED)} more; see list_containers.`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
lines.push('', 'The user has a root shell open on this host. Read what is in the terminal with terminal_output.', '');
|
|
48
|
+
return (0, redact_1.redactText)(lines.join('\n')).text;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=host-overview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-overview.js","sourceRoot":"","sources":["../electron/host-overview.ts"],"names":[],"mappings":";;AAqBA,gDAmDC;AAvED,qCAAsC;AAEtC,8FAA8F;AAC9F,MAAM,UAAU,GAAG,EAAE,CAAC;AAStB;;;;;;;GAOG;AACH,SAAgB,kBAAkB,CAAC,KAAwB;IAEzD,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IACrC,MAAM,KAAK,GAAG;QACZ,oBAAoB;QACpB,EAAE;QACF,2BAA2B,KAAK,CAAC,UAAU,eAAe,KAAK,CAAC,OAAO,IAAI;QAC3E,iBAAiB,MAAM,CAAC,QAAQ,IAAI;KACrC,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,sCAAsC,MAAM,CAAC,OAAO,IAAI,eAAe,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,oBAAoB,MAAM,CAAC,OAAO,CAAC,OAAO,SAAS,MAAM,CAAC,OAAO,CAAC,UAAU,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3I,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QAEzB,KAAK,CAAC,IAAI,CACR,aAAa,IAAI,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,aAAa,EACtH,iBAAiB,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,YAAY;YACrF,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,YAAY,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,sBAAsB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CACxH,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAErC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,6CAA6C,EAAE,iCAAiC,CAAC,CAAC;QAE7F,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC,cAAc,IAAI,EAAE,IAAI,CAAC,CAAC;QACjH,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,6BAA6B,CAAC,CAAC;QAC7F,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CACR,EAAE,EACF,iGAAiG,EACjG,EAAE,CACH,CAAC;IAEF,OAAO,IAAA,mBAAU,EAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C,CAAC"}
|