build-strap 3.0.0-dev.42 → 4.0.0-dev.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/LICENSE +1 -1
- package/README.md +3 -34
- package/ant.d.ts +19 -0
- package/ant.js +12 -37
- package/cert.d.ts +12 -0
- package/cert.js +89 -151
- package/clean.d.ts +4 -0
- package/clean.js +7 -16
- package/copy.d.ts +7 -0
- package/copy.js +49 -76
- package/cp.d.ts +17 -0
- package/cp.js +85 -170
- package/docker.container.d.ts +73 -0
- package/docker.container.js +219 -362
- package/docker.d.ts +68 -0
- package/docker.js +167 -347
- package/docker.network.d.ts +42 -0
- package/docker.network.js +69 -144
- package/docker.volume.d.ts +26 -0
- package/docker.volume.js +52 -126
- package/dockerCleanup.d.ts +38 -0
- package/dockerCleanup.js +66 -141
- package/dockerCompose.d.ts +154 -0
- package/dockerCompose.js +400 -727
- package/fs.d.ts +5 -0
- package/fs.js +38 -95
- package/git.d.ts +9 -0
- package/git.js +19 -30
- package/index.d.ts +20 -0
- package/index.js +20 -27
- package/maps.d.ts +33 -0
- package/maps.js +16 -87
- package/npm.d.ts +34 -0
- package/npm.js +97 -138
- package/package.json +23 -19
- package/pkg.d.ts +39 -0
- package/pkg.js +26 -74
- package/publish.d.ts +27 -0
- package/publish.js +52 -140
- package/run.d.ts +13 -0
- package/run.js +39 -85
- package/tgz.d.ts +13 -0
- package/tgz.js +61 -96
- package/version.d.ts +34 -0
- package/version.js +86 -127
- package/yarn.d.ts +26 -0
- package/yarn.js +70 -119
- package/ant.js.flow +0 -42
- package/artifactory.js +0 -617
- package/artifactory.js.flow +0 -616
- package/cert.conf +0 -20
- package/cert.js.flow +0 -152
- package/clean.js.flow +0 -19
- package/copy.js.flow +0 -79
- package/cp.js.flow +0 -172
- package/docker.container.js.flow +0 -389
- package/docker.js.flow +0 -367
- package/docker.network.js.flow +0 -159
- package/docker.volume.js.flow +0 -136
- package/dockerCleanup.js.flow +0 -151
- package/dockerCompose.js.flow +0 -765
- package/flow.js +0 -21
- package/flow.js.flow +0 -20
- package/fs.js.flow +0 -96
- package/git.js.flow +0 -34
- package/hg.js +0 -35
- package/hg.js.flow +0 -34
- package/index.js.flow +0 -26
- package/inline-resources.js +0 -158
- package/inline-resources.js.flow +0 -157
- package/maps.js.flow +0 -111
- package/npm.js.flow +0 -144
- package/pkg.js.flow +0 -80
- package/publish.js.flow +0 -144
- package/run.js.flow +0 -89
- package/src/ant.js +0 -42
- package/src/artifactory.js +0 -616
- package/src/cert.conf +0 -20
- package/src/cert.js +0 -152
- package/src/clean.js +0 -19
- package/src/copy.js +0 -79
- package/src/cp.js +0 -172
- package/src/docker.container.js +0 -389
- package/src/docker.js +0 -367
- package/src/docker.network.js +0 -159
- package/src/docker.volume.js +0 -136
- package/src/dockerCleanup.js +0 -151
- package/src/dockerCompose.js +0 -765
- package/src/flow.js +0 -20
- package/src/fs.js +0 -96
- package/src/git.js +0 -34
- package/src/hg.js +0 -34
- package/src/index.js +0 -26
- package/src/inline-resources.js +0 -157
- package/src/maps.js +0 -111
- package/src/npm.js +0 -144
- package/src/pkg.js +0 -80
- package/src/publish.js +0 -144
- package/src/run.js +0 -89
- package/src/test.js +0 -55
- package/src/tgz.js +0 -101
- package/src/version.js +0 -141
- package/src/yarn.js +0 -123
- package/test.js +0 -56
- package/test.js.flow +0 -55
- package/tgz.js.flow +0 -101
- package/version.js.flow +0 -141
- package/yarn.js.flow +0 -123
package/dockerCompose.js
CHANGED
|
@@ -1,766 +1,439 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const dockerComposeCreateResourceTracker = () => ({
|
|
36
|
-
networks: new Map(),
|
|
37
|
-
services: new Map(),
|
|
38
|
-
containers: new Map(),
|
|
39
|
-
volumes: new Map(),
|
|
40
|
-
cleaning: null });exports.dockerComposeCreateResourceTracker = dockerComposeCreateResourceTracker;
|
|
41
|
-
|
|
42
|
-
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _DockerComposeService_name, _DockerComposeService_svcDef, _DockerComposeService_dockerCompose, _DockerComposeService_tracker, _DockerComposeService_parsedPorts, _DockerComposeService_parsedNetworks, _DockerComposeService_parsedVolumes, _DockerComposeService_baseRunArgs;
|
|
13
|
+
import fs from 'fs-extra';
|
|
14
|
+
import getPort from 'get-port';
|
|
15
|
+
import yaml from 'js-yaml';
|
|
16
|
+
import path from 'path';
|
|
17
|
+
import { dockerContainerFind, dockerContainerRunDaemon, } from './docker.container.js';
|
|
18
|
+
import { dockerPull } from './docker.js';
|
|
19
|
+
import { dockerNetworkCreate, dockerNetworkDelete, } from './docker.network.js';
|
|
20
|
+
import { dockerVolumeCreate, dockerVolumeRm, } from './docker.volume.js';
|
|
21
|
+
import { mapValuesAsync } from './maps.js';
|
|
22
|
+
import { buildLog } from './run.js';
|
|
23
|
+
export const dockerComposeCreateResourceTracker = () => ({
|
|
24
|
+
cleaning: null,
|
|
25
|
+
containers: new Map(),
|
|
26
|
+
networks: new Map(),
|
|
27
|
+
services: new Map(),
|
|
28
|
+
volumes: new Map(),
|
|
29
|
+
});
|
|
43
30
|
const defaultTracker = dockerComposeCreateResourceTracker();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
31
|
/**
|
|
88
32
|
* Parse a docker-compose.yml file into a pojo representation
|
|
89
33
|
* @param {string} filePath Path to the docker-compose.yml file
|
|
90
34
|
*/
|
|
91
|
-
const dockerComposeParse = async (
|
|
92
|
-
filePath = './docker-compose.yml') =>
|
|
93
|
-
_jsYaml.default.load(await _fsExtra.default.readFile(filePath));exports.dockerComposeParse = dockerComposeParse;
|
|
94
|
-
|
|
35
|
+
export const dockerComposeParse = async (filePath = './docker-compose.yml') => yaml.load(await fs.readFile(filePath, 'utf8'));
|
|
95
36
|
let dc = null;
|
|
96
|
-
|
|
97
37
|
/**
|
|
98
38
|
* Get the main docker-compose.yml from the root of the repo
|
|
99
39
|
* @param {boolean} force Force reload from file
|
|
100
40
|
*/
|
|
101
|
-
const dockerComposeGetMain = async (
|
|
102
|
-
force
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
dc
|
|
106
|
-
}
|
|
107
|
-
return dc;
|
|
41
|
+
export const dockerComposeGetMain = async (force = false) => {
|
|
42
|
+
if (force || !dc) {
|
|
43
|
+
dc = await dockerComposeParse();
|
|
44
|
+
}
|
|
45
|
+
return dc;
|
|
108
46
|
};
|
|
109
|
-
|
|
110
47
|
// Function that handles passed dockerCompose as either a file path or `DockerCompose` object.
|
|
111
48
|
// If not passed, defaults to the main docker-compose.yml from the root of the repo
|
|
112
|
-
|
|
113
|
-
dockerCompose
|
|
114
|
-
force)
|
|
115
|
-
|
|
116
|
-
typeof dockerCompose === 'string' ?
|
|
117
|
-
dockerComposeParse(dockerCompose) :
|
|
118
|
-
dockerCompose || dockerComposeGetMain(force);
|
|
119
|
-
|
|
49
|
+
const dockerComposeResolve = async (dockerCompose, force) => typeof dockerCompose === 'string'
|
|
50
|
+
? dockerComposeParse(dockerCompose)
|
|
51
|
+
: dockerCompose || dockerComposeGetMain(force);
|
|
120
52
|
// Determines an unnamed resource's name from the dirname combined with the key
|
|
121
|
-
const prefixName = (name) => `${
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const parsePorts = async (
|
|
147
|
-
portsCfg = [],
|
|
148
|
-
avoidConflicts = true,
|
|
149
|
-
mapLocal = true,
|
|
150
|
-
host = '0.0.0.0') =>
|
|
151
|
-
{
|
|
152
|
-
const ports = [];
|
|
153
|
-
const runArgs = await portsCfg.reduce(async (args, portStr) => {
|
|
154
|
-
const [lp, dp] = portStr.split(':');
|
|
155
|
-
const localDefault = parseInt(lp, 10);
|
|
156
|
-
const docker = parseInt(dp, 10);
|
|
157
|
-
const local = mapLocal ?
|
|
158
|
-
avoidConflicts ?
|
|
159
|
-
await (0, _getPort.default)({ port: localDefault, host }) :
|
|
160
|
-
localDefault :
|
|
161
|
-
null;
|
|
162
|
-
ports.push({ local, localDefault, docker });
|
|
163
|
-
return local ? [...(await args), '-p', `${local}:${docker}`] : args;
|
|
164
|
-
}, []);
|
|
165
|
-
return { runArgs, ports };
|
|
53
|
+
const prefixName = (name) => `${path.basename(__dirname)}_${name}`;
|
|
54
|
+
const getServiceDef = async (name, force, dockerCompose) => (await dockerComposeResolve(dockerCompose, force)).services?.[name] || null;
|
|
55
|
+
const parsePorts = async (portsCfg = [], avoidConflicts = true, mapLocal = true, host = '0.0.0.0') => {
|
|
56
|
+
const ports = [];
|
|
57
|
+
const runArgs = await portsCfg.reduce(async (args, portStr) => {
|
|
58
|
+
const [lp, dp] = portStr.split(':');
|
|
59
|
+
const localDefault = parseInt(lp, 10);
|
|
60
|
+
const docker = parseInt(dp, 10);
|
|
61
|
+
const local = mapLocal
|
|
62
|
+
? avoidConflicts
|
|
63
|
+
? await getPort({ host, port: localDefault })
|
|
64
|
+
: localDefault
|
|
65
|
+
: null;
|
|
66
|
+
ports.push({ docker, local, localDefault });
|
|
67
|
+
return local ? [...(await args), '-p', `${local}:${docker}`] : args;
|
|
68
|
+
}, Promise.resolve([]));
|
|
69
|
+
return { ports, runArgs };
|
|
166
70
|
};
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
(
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
{
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (name) {
|
|
200
|
-
volumes.push(name);
|
|
201
|
-
}
|
|
202
|
-
const realSrc = name || _path.default.resolve(src);
|
|
203
|
-
return [realSrc, ...rest].join(':');
|
|
204
|
-
}).
|
|
205
|
-
flatMap((v) => ['-v', v]);
|
|
206
|
-
return { runArgs, volumes };
|
|
71
|
+
const parseEnv = (env = []) => Array.isArray(env)
|
|
72
|
+
? env.flatMap((e) => ['-e', e])
|
|
73
|
+
: Object.entries(env).flatMap(([k, v]) => ['-e', `${k}=${v}`]);
|
|
74
|
+
const parseULimits = (ul = {}) => Object.entries(ul).flatMap(([k, v]) => [
|
|
75
|
+
'--ulimit',
|
|
76
|
+
`${k}=${typeof v === 'number' ? v : `${v.soft}${v.hard ? `:${v.hard}` : ''}`}`,
|
|
77
|
+
]);
|
|
78
|
+
const parseVolumes = async (volCfg = [], nameSuffix = '', dockerCompose = null) => {
|
|
79
|
+
const { volumes: volMap } = await dockerComposeResolve(dockerCompose);
|
|
80
|
+
const volumes = [];
|
|
81
|
+
const runArgs = volCfg
|
|
82
|
+
.map((v) => {
|
|
83
|
+
const [src, ...rest] = v.split(':');
|
|
84
|
+
const name = volMap?.[src]
|
|
85
|
+
? `${volMap[src].name || prefixName(src)}${nameSuffix}`
|
|
86
|
+
: null;
|
|
87
|
+
if (name) {
|
|
88
|
+
volumes.push(name);
|
|
89
|
+
}
|
|
90
|
+
const realSrc = name || path.resolve(src);
|
|
91
|
+
return [realSrc, ...rest].join(':');
|
|
92
|
+
})
|
|
93
|
+
.flatMap((v) => ['-v', v]);
|
|
94
|
+
return { runArgs, volumes };
|
|
95
|
+
};
|
|
96
|
+
const parseNetworks = async (netCfg = [], dockerCompose = null) => {
|
|
97
|
+
const { networks: netMap } = await dockerComposeResolve(dockerCompose);
|
|
98
|
+
const networks = netCfg.map((n) => netMap?.[n].name || prefixName(n));
|
|
99
|
+
return {
|
|
100
|
+
networks,
|
|
101
|
+
runArgs: networks.flatMap((n) => ['--network', n]),
|
|
102
|
+
};
|
|
207
103
|
};
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
104
|
+
export const dockerComposeCreateNetworks = async (names, dockerCompose, tracker = defaultTracker) => {
|
|
105
|
+
const { networks = {} } = await dockerComposeResolve(dockerCompose);
|
|
106
|
+
await Promise.all(Object.entries(networks).map(async ([key, val]) => {
|
|
107
|
+
const name = val?.name || prefixName(key);
|
|
108
|
+
if (names?.includes(name)) {
|
|
109
|
+
const network = await dockerNetworkCreate(name, val);
|
|
110
|
+
if (network) {
|
|
111
|
+
tracker.networks.set(name, network);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}));
|
|
115
|
+
};
|
|
116
|
+
export const dockerComposeCreateVolumes = async (names, dockerCompose, tracker = defaultTracker) => {
|
|
117
|
+
const { volumes = {} } = await dockerComposeResolve(dockerCompose);
|
|
118
|
+
await Promise.all(Object.entries(volumes).map(async ([key, val]) => {
|
|
119
|
+
const name = val?.name || prefixName(key);
|
|
120
|
+
if (!names || names.includes(name)) {
|
|
121
|
+
const volume = await dockerVolumeCreate(name, val);
|
|
122
|
+
if (volume) {
|
|
123
|
+
tracker.volumes.set(name, volume);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}));
|
|
224
127
|
};
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
128
|
+
export class DockerComposeService {
|
|
129
|
+
constructor(name, serviceDef, dockerCompose) {
|
|
130
|
+
_DockerComposeService_name.set(this, void 0);
|
|
131
|
+
_DockerComposeService_svcDef.set(this, void 0);
|
|
132
|
+
_DockerComposeService_dockerCompose.set(this, void 0);
|
|
133
|
+
_DockerComposeService_tracker.set(this, dockerComposeCreateResourceTracker());
|
|
134
|
+
// lazily computed
|
|
135
|
+
_DockerComposeService_parsedPorts.set(this, null);
|
|
136
|
+
_DockerComposeService_parsedNetworks.set(this, null);
|
|
137
|
+
_DockerComposeService_parsedVolumes.set(this, null);
|
|
138
|
+
_DockerComposeService_baseRunArgs.set(this, null);
|
|
139
|
+
__classPrivateFieldSet(this, _DockerComposeService_name, name, "f");
|
|
140
|
+
__classPrivateFieldSet(this, _DockerComposeService_svcDef, serviceDef, "f");
|
|
141
|
+
__classPrivateFieldSet(this, _DockerComposeService_dockerCompose, dockerCompose || null, "f");
|
|
240
142
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
};exports.dockerComposeCreateNetworks = dockerComposeCreateNetworks;
|
|
244
|
-
|
|
245
|
-
const dockerComposeCreateVolumes = async (
|
|
246
|
-
names,
|
|
247
|
-
dockerCompose,
|
|
248
|
-
tracker = defaultTracker) =>
|
|
249
|
-
{
|
|
250
|
-
const { volumes = {} } = await dockerComposeResolve(dockerCompose);
|
|
251
|
-
await Promise.all(
|
|
252
|
-
(0, _maps.entries)(volumes).map(async ([key, val]) => {
|
|
253
|
-
const name = (val === null || val === void 0 ? void 0 : val.name) || prefixName(key);
|
|
254
|
-
if (!names || names.includes(name)) {
|
|
255
|
-
const volume = await (0, _docker4.dockerVolumeCreate)(name, val || {});
|
|
256
|
-
if (volume) {
|
|
257
|
-
tracker.volumes.set(name, volume);
|
|
258
|
-
}
|
|
143
|
+
get name() {
|
|
144
|
+
return __classPrivateFieldGet(this, _DockerComposeService_name, "f");
|
|
259
145
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
};exports.dockerComposeCreateVolumes = dockerComposeCreateVolumes;var _name = /*#__PURE__*/new WeakMap();var _svcDef = /*#__PURE__*/new WeakMap();var _dockerCompose = /*#__PURE__*/new WeakMap();var _tracker = /*#__PURE__*/new WeakMap();var _parsedPorts = /*#__PURE__*/new WeakMap();var _parsedNetworks = /*#__PURE__*/new WeakMap();var _parsedVolumes = /*#__PURE__*/new WeakMap();var _baseRunArgs = /*#__PURE__*/new WeakMap();
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
class DockerComposeService {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
// lazily computed
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
constructor(
|
|
304
|
-
name,
|
|
305
|
-
serviceDef,
|
|
306
|
-
dockerCompose)
|
|
307
|
-
{_classPrivateFieldInitSpec(this, _name, { writable: true, value: void 0 });_classPrivateFieldInitSpec(this, _svcDef, { writable: true, value: void 0 });_classPrivateFieldInitSpec(this, _dockerCompose, { writable: true, value: void 0 });_classPrivateFieldInitSpec(this, _tracker, { writable: true, value: dockerComposeCreateResourceTracker() });_classPrivateFieldInitSpec(this, _parsedPorts, { writable: true, value: null });_classPrivateFieldInitSpec(this, _parsedNetworks, { writable: true, value: null });_classPrivateFieldInitSpec(this, _parsedVolumes, { writable: true, value: null });_classPrivateFieldInitSpec(this, _baseRunArgs, { writable: true, value: null });
|
|
308
|
-
_classPrivateFieldSet(this, _name, name);
|
|
309
|
-
_classPrivateFieldSet(this, _svcDef, serviceDef);
|
|
310
|
-
_classPrivateFieldSet(this, _dockerCompose, dockerCompose || null);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
get name() {
|
|
314
|
-
return _classPrivateFieldGet(this, _name);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
get serviceDef() {
|
|
318
|
-
return _classPrivateFieldGet(this, _svcDef);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
get image() {
|
|
322
|
-
return _classPrivateFieldGet(this, _svcDef).image || null;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
get defaultContainerName() {
|
|
326
|
-
return _classPrivateFieldGet(this, _svcDef).container_name || _classPrivateFieldGet(this, _name);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
get cmd() {
|
|
330
|
-
return _classPrivateFieldGet(this, _svcDef).command || [];
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
get envArgs() {
|
|
334
|
-
return parseEnv(_classPrivateFieldGet(this, _svcDef).environment);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Find (available) container name and alias(es)
|
|
339
|
-
* @param {boolean} avoidConflicts if `true`, find a container name that is unused
|
|
340
|
-
* @param {number} max maximum number of names to try
|
|
341
|
-
*/
|
|
342
|
-
async getNames(
|
|
343
|
-
avoidConflicts = false,
|
|
344
|
-
max = 100)
|
|
345
|
-
{
|
|
346
|
-
/* eslint-disable no-await-in-loop */
|
|
347
|
-
for (let i = 0; i < max; i += 1) {
|
|
348
|
-
const suffix = i ? `-${i}` : '';
|
|
349
|
-
const testName = `${this.defaultContainerName}${suffix}`;
|
|
350
|
-
const container = await (0, _docker2.dockerContainerFind)(testName, { all: true });
|
|
351
|
-
if (!avoidConflicts || !container) {
|
|
352
|
-
return {
|
|
353
|
-
name: testName,
|
|
354
|
-
aliases: [`${this.name}${suffix}`],
|
|
355
|
-
suffix };
|
|
356
|
-
|
|
357
|
-
}
|
|
146
|
+
get serviceDef() {
|
|
147
|
+
return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f");
|
|
358
148
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
`Failed to find available container name for ${this.defaultContainerName}`);
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// Get (available) port mappings
|
|
366
|
-
async getPorts(
|
|
367
|
-
avoidConflicts = false,
|
|
368
|
-
mapLocal = true)
|
|
369
|
-
{
|
|
370
|
-
return parsePorts(_classPrivateFieldGet(this, _svcDef).ports, avoidConflicts, mapLocal);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
async getDefaultPortInfo() {
|
|
374
|
-
if (!_classPrivateFieldGet(this, _parsedPorts)) {
|
|
375
|
-
_classPrivateFieldSet(this, _parsedPorts, await this.getPorts());
|
|
149
|
+
get image() {
|
|
150
|
+
return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").image || null;
|
|
376
151
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
async getDefaultPorts() {
|
|
381
|
-
const { ports } = await this.getDefaultPortInfo();
|
|
382
|
-
return ports;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
async getDefaultPortArgs() {
|
|
386
|
-
const { runArgs } = await this.getDefaultPortInfo();
|
|
387
|
-
return runArgs;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
async getDefaultUrls() {
|
|
391
|
-
return this.constructor.getUrls(
|
|
392
|
-
await this.getDefaultPorts(),
|
|
393
|
-
this.defaultContainerName);
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
async getDefaultNetworkInfo() {
|
|
398
|
-
if (!_classPrivateFieldGet(this, _parsedNetworks)) {
|
|
399
|
-
_classPrivateFieldSet(this, _parsedNetworks, await parseNetworks(_classPrivateFieldGet(this, _svcDef).networks));
|
|
152
|
+
get defaultContainerName() {
|
|
153
|
+
return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").container_name || __classPrivateFieldGet(this, _DockerComposeService_name, "f");
|
|
400
154
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
async getDefaultNetworks() {
|
|
405
|
-
const { networks } = await this.getDefaultNetworkInfo();
|
|
406
|
-
return networks;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
async getDefaultNetworkArgs() {
|
|
410
|
-
const { runArgs } = await this.getDefaultNetworkInfo();
|
|
411
|
-
return runArgs;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
async getDefaultVolumeInfo() {
|
|
415
|
-
if (!_classPrivateFieldGet(this, _parsedVolumes)) {
|
|
416
|
-
_classPrivateFieldSet(this, _parsedVolumes, await parseVolumes(_classPrivateFieldGet(this, _svcDef).networks));
|
|
155
|
+
get cmd() {
|
|
156
|
+
return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").command || [];
|
|
417
157
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
async getDefaultVolumes() {
|
|
422
|
-
const { volumes } = await this.getDefaultVolumeInfo();
|
|
423
|
-
return volumes;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
async getDefaultVolumeArgs() {
|
|
427
|
-
const { runArgs } = await this.getDefaultVolumeInfo();
|
|
428
|
-
return runArgs;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
async pull() {
|
|
432
|
-
if (!this.image) {
|
|
433
|
-
throw new Error(`Cannot pull '${this.name}', no image configured.`);
|
|
158
|
+
get envArgs() {
|
|
159
|
+
return parseEnv(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").environment);
|
|
434
160
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
161
|
+
/**
|
|
162
|
+
* Find (available) container name and alias(es)
|
|
163
|
+
* @param {boolean} avoidConflicts if `true`, find a container name that is unused
|
|
164
|
+
* @param {number} max maximum number of names to try
|
|
165
|
+
*/
|
|
166
|
+
async getNames(avoidConflicts = false, max = 100) {
|
|
167
|
+
/* eslint-disable no-await-in-loop */
|
|
168
|
+
for (let i = 0; i < max; i += 1) {
|
|
169
|
+
const suffix = i ? `-${i}` : '';
|
|
170
|
+
const testName = `${this.defaultContainerName}${suffix}`;
|
|
171
|
+
const container = await dockerContainerFind(testName, { all: true });
|
|
172
|
+
if (!avoidConflicts || !container) {
|
|
173
|
+
return {
|
|
174
|
+
aliases: [`${this.name}${suffix}`],
|
|
175
|
+
name: testName,
|
|
176
|
+
suffix,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/* eslint-enable no-await-in-loop */
|
|
181
|
+
throw new Error(`Failed to find available container name for ${this.defaultContainerName}`);
|
|
445
182
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
async assembleRunArgs(
|
|
450
|
-
containerName = this.defaultContainerName,
|
|
451
|
-
aliases = [this.name],
|
|
452
|
-
additionalArgs)
|
|
453
|
-
{
|
|
454
|
-
const additional = additionalArgs || [
|
|
455
|
-
...(await this.getDefaultPortArgs()),
|
|
456
|
-
...(await this.getDefaultVolumeArgs())];
|
|
457
|
-
|
|
458
|
-
return [
|
|
459
|
-
...(await this.getBaseRunArgs()),
|
|
460
|
-
...(containerName ? ['--name', containerName] : []),
|
|
461
|
-
...aliases.flatMap((a) => a ? ['--network-alias', a] : []),
|
|
462
|
-
...additional];
|
|
463
|
-
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
async getRunArgs(
|
|
467
|
-
avoidConflicts = false,
|
|
468
|
-
mapLocalPorts = true)
|
|
469
|
-
{
|
|
470
|
-
const { name: cName, aliases, suffix } = await this.getNames(
|
|
471
|
-
avoidConflicts);
|
|
472
|
-
|
|
473
|
-
const { runArgs: pArgs } = await this.getPorts(
|
|
474
|
-
avoidConflicts,
|
|
475
|
-
mapLocalPorts);
|
|
476
|
-
|
|
477
|
-
const { runArgs: vArgs } = await parseVolumes(_classPrivateFieldGet(this, _svcDef).volumes, suffix);
|
|
478
|
-
return this.assembleRunArgs(cName, aliases, [...pArgs, ...vArgs]);
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
async up({
|
|
482
|
-
healthCheck,
|
|
483
|
-
avoidConflicts = false,
|
|
484
|
-
mapVolumes = true,
|
|
485
|
-
mapPorts = true,
|
|
486
|
-
cmd = this.cmd,
|
|
487
|
-
tracker = defaultTracker } =
|
|
488
|
-
{}) {
|
|
489
|
-
const { image } = this;
|
|
490
|
-
if (!image) {
|
|
491
|
-
throw new Error(
|
|
492
|
-
`Cannot bring up service '${this.name}', no image defined.`);
|
|
493
|
-
|
|
183
|
+
// Get (available) port mappings
|
|
184
|
+
async getPorts(avoidConflicts = false, mapLocal = true) {
|
|
185
|
+
return parsePorts(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").ports, avoidConflicts, mapLocal);
|
|
494
186
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
187
|
+
async getDefaultPortInfo() {
|
|
188
|
+
if (!__classPrivateFieldGet(this, _DockerComposeService_parsedPorts, "f")) {
|
|
189
|
+
__classPrivateFieldSet(this, _DockerComposeService_parsedPorts, await this.getPorts(), "f");
|
|
190
|
+
}
|
|
191
|
+
return __classPrivateFieldGet(this, _DockerComposeService_parsedPorts, "f");
|
|
499
192
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
const { runArgs: pArgs, ports } = await this.getPorts(
|
|
504
|
-
avoidConflicts,
|
|
505
|
-
mapPorts);
|
|
506
|
-
|
|
507
|
-
const { runArgs: vArgs, volumes } = mapVolumes ?
|
|
508
|
-
await parseVolumes(_classPrivateFieldGet(this, _svcDef).volumes, suffix) :
|
|
509
|
-
{ runArgs: [], volumes: [] };
|
|
510
|
-
|
|
511
|
-
let container = await (0, _docker2.dockerContainerFind)(containerName, { all: true });
|
|
512
|
-
if (container && !(await container.isRunning())) {
|
|
513
|
-
await container.start();
|
|
193
|
+
async getDefaultPorts() {
|
|
194
|
+
const { ports } = await this.getDefaultPortInfo();
|
|
195
|
+
return ports;
|
|
514
196
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
await this.getDefaultNetworks(), _classPrivateFieldGet(
|
|
519
|
-
this, _dockerCompose), _classPrivateFieldGet(
|
|
520
|
-
this, _tracker));
|
|
521
|
-
|
|
522
|
-
await dockerComposeCreateVolumes(
|
|
523
|
-
volumes, _classPrivateFieldGet(
|
|
524
|
-
this, _dockerCompose), _classPrivateFieldGet(
|
|
525
|
-
this, _tracker));
|
|
526
|
-
|
|
527
|
-
const runArgs = await this.assembleRunArgs(containerName, aliases, [
|
|
528
|
-
...pArgs,
|
|
529
|
-
...vArgs]);
|
|
530
|
-
|
|
531
|
-
container = await (0, _docker2.dockerContainerRunDaemon)({
|
|
532
|
-
image,
|
|
533
|
-
runArgs,
|
|
534
|
-
cmd });
|
|
535
|
-
|
|
536
|
-
} else {
|
|
537
|
-
(0, _run.buildLog)(`Reusing existing container for '${this.name}' service.`);
|
|
197
|
+
async getDefaultPortArgs() {
|
|
198
|
+
const { runArgs } = await this.getDefaultPortInfo();
|
|
199
|
+
return runArgs;
|
|
538
200
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
// The passed tracker needs to track this service
|
|
542
|
-
tracker.services.set(this.name, this);
|
|
543
|
-
|
|
544
|
-
const idAlias = container.id.slice(0, 12);
|
|
545
|
-
aliases.push(idAlias);
|
|
546
|
-
const urls = this.constructor.getUrls(ports, idAlias);
|
|
547
|
-
|
|
548
|
-
const info = {
|
|
549
|
-
service: this,
|
|
550
|
-
container,
|
|
551
|
-
containerName,
|
|
552
|
-
aliases,
|
|
553
|
-
ports,
|
|
554
|
-
volumes,
|
|
555
|
-
urls };
|
|
556
|
-
|
|
557
|
-
await (healthCheck === null || healthCheck === void 0 ? void 0 : healthCheck(info));
|
|
558
|
-
return info;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
async down({
|
|
562
|
-
includeDefaults = false,
|
|
563
|
-
includeVolumes = false,
|
|
564
|
-
includeNetworks = false } =
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
{}) {
|
|
570
|
-
(0, _run.buildLog)(`Bringing down <${this.name}> service...`);
|
|
571
|
-
await dockerComposeTeardown({
|
|
572
|
-
tracker: _classPrivateFieldGet(this, _tracker),
|
|
573
|
-
includeVolumes,
|
|
574
|
-
includeNetworks });
|
|
575
|
-
|
|
576
|
-
if (includeDefaults) {
|
|
577
|
-
const container = await (0, _docker2.dockerContainerFind)(this.defaultContainerName);
|
|
578
|
-
if (container) {
|
|
579
|
-
await container.teardown(true);
|
|
580
|
-
}
|
|
201
|
+
async getDefaultUrls() {
|
|
202
|
+
return DockerComposeService.getUrls(await this.getDefaultPorts(), this.defaultContainerName);
|
|
581
203
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
name,
|
|
586
|
-
force = true,
|
|
587
|
-
dockerCompose)
|
|
588
|
-
{
|
|
589
|
-
const svcDef = await getServiceDef(name, force, dockerCompose);
|
|
590
|
-
return svcDef ? new this(name, svcDef, dockerCompose) : null;
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
static getUrls(ports, alias) {
|
|
594
|
-
return ports.map(({ local, docker }) => ({
|
|
595
|
-
local: local ? `http://localhost:${local}` : null,
|
|
596
|
-
docker: docker ? `http://${alias}:${docker}` : null }));
|
|
597
|
-
|
|
598
|
-
}}exports.DockerComposeService = DockerComposeService;
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
async function dockerComposeGetAllServices(
|
|
602
|
-
dockerCompose)
|
|
603
|
-
{
|
|
604
|
-
const { services } = await dockerComposeResolve(dockerCompose);
|
|
605
|
-
return (0, _maps.mapValuesAsync)(services, (s, name) =>
|
|
606
|
-
DockerComposeService.parse(name));
|
|
607
|
-
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
async function dockerComposeTeardown({
|
|
611
|
-
includeDefaults = false,
|
|
612
|
-
includeVolumes = false,
|
|
613
|
-
includeNetworks = false,
|
|
614
|
-
dockerCompose,
|
|
615
|
-
tracker = defaultTracker } =
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
{}) {
|
|
623
|
-
if (!tracker.cleaning) {
|
|
624
|
-
// eslint-disable-next-line no-param-reassign
|
|
625
|
-
tracker.cleaning = (async () => {
|
|
626
|
-
if (tracker.services.size) {
|
|
627
|
-
(0, _run.buildLog)('Bringing down started docker services...');
|
|
628
|
-
const promises = Promise.all(
|
|
629
|
-
Array.from(tracker.services.values()).map(async (s) =>
|
|
630
|
-
s.down({ includeVolumes, includeNetworks })));
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
tracker.services.clear();
|
|
634
|
-
await promises;
|
|
635
|
-
}
|
|
636
|
-
if (includeDefaults) {
|
|
637
|
-
const { services } = await dockerComposeResolve(dockerCompose);
|
|
638
|
-
const svcNames = (0, _maps.keys)(services);
|
|
639
|
-
if (svcNames.length) {
|
|
640
|
-
(0, _run.buildLog)('Bringing down default docker services...');
|
|
641
|
-
await Promise.all(
|
|
642
|
-
svcNames.map(async (s) => {var _await$DockerComposeS;return (_await$DockerComposeS =
|
|
643
|
-
await DockerComposeService.parse(s)) === null || _await$DockerComposeS === void 0 ? void 0 : _await$DockerComposeS.down({
|
|
644
|
-
includeDefaults,
|
|
645
|
-
includeVolumes,
|
|
646
|
-
includeNetworks });}));
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
204
|
+
async getDefaultNetworkInfo() {
|
|
205
|
+
if (!__classPrivateFieldGet(this, _DockerComposeService_parsedNetworks, "f")) {
|
|
206
|
+
__classPrivateFieldSet(this, _DockerComposeService_parsedNetworks, await parseNetworks(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").networks), "f");
|
|
650
207
|
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if (includeVolumes) {
|
|
665
|
-
if (tracker.volumes.size) {
|
|
666
|
-
(0, _run.buildLog)('Removing created docker volumes...');
|
|
667
|
-
const promises = Promise.all(
|
|
668
|
-
Array.from(tracker.volumes.values()).map(async (v) => v.rm()));
|
|
669
|
-
|
|
670
|
-
tracker.volumes.clear();
|
|
671
|
-
await promises;
|
|
208
|
+
return __classPrivateFieldGet(this, _DockerComposeService_parsedNetworks, "f");
|
|
209
|
+
}
|
|
210
|
+
async getDefaultNetworks() {
|
|
211
|
+
const { networks } = await this.getDefaultNetworkInfo();
|
|
212
|
+
return networks;
|
|
213
|
+
}
|
|
214
|
+
async getDefaultNetworkArgs() {
|
|
215
|
+
const { runArgs } = await this.getDefaultNetworkInfo();
|
|
216
|
+
return runArgs;
|
|
217
|
+
}
|
|
218
|
+
async getDefaultVolumeInfo() {
|
|
219
|
+
if (!__classPrivateFieldGet(this, _DockerComposeService_parsedVolumes, "f")) {
|
|
220
|
+
__classPrivateFieldSet(this, _DockerComposeService_parsedVolumes, await parseVolumes(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").networks), "f");
|
|
672
221
|
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
222
|
+
return __classPrivateFieldGet(this, _DockerComposeService_parsedVolumes, "f");
|
|
223
|
+
}
|
|
224
|
+
async getDefaultVolumes() {
|
|
225
|
+
const { volumes } = await this.getDefaultVolumeInfo();
|
|
226
|
+
return volumes;
|
|
227
|
+
}
|
|
228
|
+
async getDefaultVolumeArgs() {
|
|
229
|
+
const { runArgs } = await this.getDefaultVolumeInfo();
|
|
230
|
+
return runArgs;
|
|
231
|
+
}
|
|
232
|
+
async pull() {
|
|
233
|
+
if (!this.image) {
|
|
234
|
+
throw new Error(`Cannot pull '${this.name}', no image configured.`);
|
|
682
235
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
if (
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
236
|
+
await dockerPull({ image: this.image });
|
|
237
|
+
}
|
|
238
|
+
async getBaseRunArgs() {
|
|
239
|
+
if (!__classPrivateFieldGet(this, _DockerComposeService_baseRunArgs, "f")) {
|
|
240
|
+
const envArgs = parseEnv(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").environment);
|
|
241
|
+
const ulArgs = parseULimits(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").ulimits);
|
|
242
|
+
const netArgs = await this.getDefaultNetworkArgs();
|
|
243
|
+
__classPrivateFieldSet(this, _DockerComposeService_baseRunArgs, ['--rm', ...envArgs, ...netArgs, ...ulArgs], "f");
|
|
244
|
+
}
|
|
245
|
+
return __classPrivateFieldGet(this, _DockerComposeService_baseRunArgs, "f");
|
|
246
|
+
}
|
|
247
|
+
async assembleRunArgs(containerName = this.defaultContainerName, aliases = [this.name], additionalArgs = null) {
|
|
248
|
+
const additional = additionalArgs || [
|
|
249
|
+
...(await this.getDefaultPortArgs()),
|
|
250
|
+
...(await this.getDefaultVolumeArgs()),
|
|
251
|
+
];
|
|
252
|
+
return [
|
|
253
|
+
...(await this.getBaseRunArgs()),
|
|
254
|
+
...(containerName ? ['--name', containerName] : []),
|
|
255
|
+
...aliases.flatMap((a) => (a ? ['--network-alias', a] : [])),
|
|
256
|
+
...additional,
|
|
257
|
+
];
|
|
258
|
+
}
|
|
259
|
+
async getRunArgs(avoidConflicts = false, mapLocalPorts = true) {
|
|
260
|
+
const { aliases, name: cName, suffix, } = await this.getNames(avoidConflicts);
|
|
261
|
+
const { runArgs: pArgs } = await this.getPorts(avoidConflicts, mapLocalPorts);
|
|
262
|
+
const { runArgs: vArgs } = await parseVolumes(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").volumes, suffix);
|
|
263
|
+
return this.assembleRunArgs(cName, aliases, [...pArgs, ...vArgs]);
|
|
264
|
+
}
|
|
265
|
+
async up({ healthCheck, avoidConflicts = false, mapVolumes = true, mapPorts = true, cmd = this.cmd, tracker = defaultTracker, } = {}) {
|
|
266
|
+
const { image } = this;
|
|
267
|
+
if (!image) {
|
|
268
|
+
throw new Error(`Cannot bring up service '${this.name}', no image defined.`);
|
|
269
|
+
}
|
|
270
|
+
if (__classPrivateFieldGet(this, _DockerComposeService_tracker, "f").containers.size) {
|
|
271
|
+
buildLog(`Warning: up called on service '${this.name}' with already running container`);
|
|
693
272
|
}
|
|
273
|
+
const { aliases, name: containerName, suffix, } = await this.getNames(avoidConflicts);
|
|
274
|
+
const { ports, runArgs: pArgs } = await this.getPorts(avoidConflicts, mapPorts);
|
|
275
|
+
const { runArgs: vArgs, volumes } = mapVolumes
|
|
276
|
+
? await parseVolumes(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").volumes, suffix)
|
|
277
|
+
: { runArgs: [], volumes: [] };
|
|
278
|
+
let container = await dockerContainerFind(containerName, { all: true });
|
|
279
|
+
if (container && !(await container.isRunning())) {
|
|
280
|
+
await container.start();
|
|
281
|
+
}
|
|
282
|
+
if (!container) {
|
|
283
|
+
await this.pull();
|
|
284
|
+
await dockerComposeCreateNetworks(await this.getDefaultNetworks(), __classPrivateFieldGet(this, _DockerComposeService_dockerCompose, "f"), __classPrivateFieldGet(this, _DockerComposeService_tracker, "f"));
|
|
285
|
+
await dockerComposeCreateVolumes(volumes, __classPrivateFieldGet(this, _DockerComposeService_dockerCompose, "f"), __classPrivateFieldGet(this, _DockerComposeService_tracker, "f"));
|
|
286
|
+
const runArgs = await this.assembleRunArgs(containerName, aliases, [
|
|
287
|
+
...pArgs,
|
|
288
|
+
...vArgs,
|
|
289
|
+
]);
|
|
290
|
+
container = await dockerContainerRunDaemon({
|
|
291
|
+
cmd,
|
|
292
|
+
image,
|
|
293
|
+
runArgs,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
buildLog(`Reusing existing container for '${this.name}' service.`);
|
|
298
|
+
}
|
|
299
|
+
// This service tracks the things it created
|
|
300
|
+
__classPrivateFieldGet(this, _DockerComposeService_tracker, "f").containers.set(containerName, container);
|
|
301
|
+
// The passed tracker needs to track this service
|
|
302
|
+
tracker.services.set(this.name, this);
|
|
303
|
+
const idAlias = container.id.slice(0, 12);
|
|
304
|
+
aliases.push(idAlias);
|
|
305
|
+
const urls = DockerComposeService.getUrls(ports, idAlias);
|
|
306
|
+
const info = {
|
|
307
|
+
aliases,
|
|
308
|
+
container,
|
|
309
|
+
containerName,
|
|
310
|
+
ports,
|
|
311
|
+
service: this,
|
|
312
|
+
urls,
|
|
313
|
+
volumes,
|
|
314
|
+
};
|
|
315
|
+
await healthCheck?.(info);
|
|
316
|
+
return info;
|
|
317
|
+
}
|
|
318
|
+
async down({ includeDefaults = false, includeNetworks = false, includeVolumes = false, } = {}) {
|
|
319
|
+
buildLog(`Bringing down <${this.name}> service...`);
|
|
320
|
+
await dockerComposeTeardown({
|
|
321
|
+
includeNetworks,
|
|
322
|
+
includeVolumes,
|
|
323
|
+
tracker: __classPrivateFieldGet(this, _DockerComposeService_tracker, "f"),
|
|
324
|
+
});
|
|
694
325
|
if (includeDefaults) {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
(0, _maps.entries)(networks).map(async ([key, val]) => {
|
|
699
|
-
const name = (val === null || val === void 0 ? void 0 : val.name) || prefixName(key);
|
|
700
|
-
try {
|
|
701
|
-
await (0, _docker3.dockerNetworkDelete)(name);
|
|
702
|
-
} catch (err) {
|
|
703
|
-
(0, _run.buildLog)(`Error deleting network '${name}': ${err.message}`);
|
|
326
|
+
const container = await dockerContainerFind(this.defaultContainerName);
|
|
327
|
+
if (container) {
|
|
328
|
+
await container.teardown(true);
|
|
704
329
|
}
|
|
705
|
-
}));
|
|
706
|
-
|
|
707
330
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
331
|
+
}
|
|
332
|
+
static async parse(name, force = true, dockerCompose = null) {
|
|
333
|
+
const svcDef = await getServiceDef(name, force, dockerCompose);
|
|
334
|
+
return svcDef ? new this(name, svcDef, dockerCompose) : null;
|
|
335
|
+
}
|
|
336
|
+
static getUrls(ports, alias) {
|
|
337
|
+
return ports.map(({ docker, local }) => ({
|
|
338
|
+
docker: docker ? `http://${alias}:${docker}` : null,
|
|
339
|
+
local: local ? `http://localhost:${local}` : null,
|
|
340
|
+
}));
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
_DockerComposeService_name = new WeakMap(), _DockerComposeService_svcDef = new WeakMap(), _DockerComposeService_dockerCompose = new WeakMap(), _DockerComposeService_tracker = new WeakMap(), _DockerComposeService_parsedPorts = new WeakMap(), _DockerComposeService_parsedNetworks = new WeakMap(), _DockerComposeService_parsedVolumes = new WeakMap(), _DockerComposeService_baseRunArgs = new WeakMap();
|
|
344
|
+
export async function dockerComposeGetAllServices(dockerCompose) {
|
|
345
|
+
const { services } = await dockerComposeResolve(dockerCompose);
|
|
346
|
+
return mapValuesAsync(services, (s, name) => DockerComposeService.parse(name));
|
|
714
347
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
348
|
+
export async function dockerComposeTeardown({ includeDefaults = false, includeVolumes = false, includeNetworks = false, dockerCompose, tracker = defaultTracker, } = {}) {
|
|
349
|
+
if (!tracker.cleaning) {
|
|
350
|
+
// eslint-disable-next-line no-param-reassign
|
|
351
|
+
tracker.cleaning = (async () => {
|
|
352
|
+
if (tracker.services.size) {
|
|
353
|
+
buildLog('Bringing down started docker services...');
|
|
354
|
+
const promises = Promise.all(Array.from(tracker.services.values()).map(async (s) => s.down({ includeNetworks, includeVolumes })));
|
|
355
|
+
tracker.services.clear();
|
|
356
|
+
await promises;
|
|
357
|
+
}
|
|
358
|
+
if (includeDefaults) {
|
|
359
|
+
const { services } = await dockerComposeResolve(dockerCompose);
|
|
360
|
+
const svcNames = Object.keys(services ?? {});
|
|
361
|
+
if (svcNames.length) {
|
|
362
|
+
buildLog('Bringing down default docker services...');
|
|
363
|
+
await Promise.all(svcNames.map(async (s) => (await DockerComposeService.parse(s))?.down({
|
|
364
|
+
includeDefaults,
|
|
365
|
+
includeNetworks,
|
|
366
|
+
includeVolumes,
|
|
367
|
+
})));
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (tracker.containers.size) {
|
|
371
|
+
buildLog('Stopping created docker containers...');
|
|
372
|
+
const promises = Promise.all(Array.from(tracker.containers.values()).map(async (c) => c.teardown(true)));
|
|
373
|
+
tracker.containers.clear();
|
|
374
|
+
await promises;
|
|
375
|
+
}
|
|
376
|
+
if (includeVolumes) {
|
|
377
|
+
if (tracker.volumes.size) {
|
|
378
|
+
buildLog('Removing created docker volumes...');
|
|
379
|
+
const promises = Promise.all(Array.from(tracker.volumes.values()).map(async (v) => v.rm()));
|
|
380
|
+
tracker.volumes.clear();
|
|
381
|
+
await promises;
|
|
382
|
+
}
|
|
383
|
+
if (includeDefaults) {
|
|
384
|
+
buildLog('Removing default docker volumes...');
|
|
385
|
+
const { volumes } = await dockerComposeResolve(dockerCompose);
|
|
386
|
+
await Promise.all(Object.entries(volumes ?? {}).map(async ([key, val]) => {
|
|
387
|
+
const name = val?.name || prefixName(key);
|
|
388
|
+
await dockerVolumeRm(name, true);
|
|
389
|
+
}));
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (includeNetworks) {
|
|
393
|
+
if (tracker.networks.size) {
|
|
394
|
+
buildLog('Removing created docker networks...');
|
|
395
|
+
const promises = Promise.all(Array.from(tracker.networks.values()).map(async (n) => n.rm()));
|
|
396
|
+
tracker.networks.clear();
|
|
397
|
+
await promises;
|
|
398
|
+
}
|
|
399
|
+
if (includeDefaults) {
|
|
400
|
+
buildLog('Removing default docker networks...');
|
|
401
|
+
const { networks } = await dockerComposeResolve(dockerCompose);
|
|
402
|
+
await Promise.all(Object.entries(networks ?? {}).map(async ([key, val]) => {
|
|
403
|
+
const name = val?.name || prefixName(key);
|
|
404
|
+
try {
|
|
405
|
+
await dockerNetworkDelete(name);
|
|
406
|
+
}
|
|
407
|
+
catch (err) {
|
|
408
|
+
buildLog(`Error deleting network '${name}': ${err.message}`);
|
|
409
|
+
}
|
|
410
|
+
}));
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
// eslint-disable-next-line no-param-reassign
|
|
414
|
+
tracker.cleaning = null;
|
|
415
|
+
})();
|
|
416
|
+
}
|
|
417
|
+
return tracker.cleaning;
|
|
418
|
+
}
|
|
419
|
+
export async function dockerComposeRunService(key, upOptions = {}, dockerCompose = null) {
|
|
420
|
+
const service = await DockerComposeService.parse(key, false, dockerCompose);
|
|
421
|
+
if (!service) {
|
|
422
|
+
throw new Error(`Failed to find service '${key}'`);
|
|
423
|
+
}
|
|
424
|
+
buildLog(`Starting <${service.name}> service...`);
|
|
425
|
+
const upResult = await service.up(upOptions);
|
|
426
|
+
const { container, urls, urls: [{ docker: dockerUrl, local: url }], ports: [{ docker: dockerPort, local: port }], } = upResult;
|
|
427
|
+
const { id, image, name } = container;
|
|
428
|
+
urls.forEach(({ local }) => local && buildLog(`<${service.name}> accessible at ${local}`));
|
|
429
|
+
return {
|
|
430
|
+
...upResult,
|
|
431
|
+
dockerPort,
|
|
432
|
+
dockerUrl,
|
|
433
|
+
id,
|
|
434
|
+
image,
|
|
435
|
+
name,
|
|
436
|
+
port,
|
|
437
|
+
url,
|
|
438
|
+
};
|
|
765
439
|
}
|
|
766
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kb2NrZXJDb21wb3NlLmpzIl0sIm5hbWVzIjpbImRvY2tlckNvbXBvc2VDcmVhdGVSZXNvdXJjZVRyYWNrZXIiLCJuZXR3b3JrcyIsIk1hcCIsInNlcnZpY2VzIiwiY29udGFpbmVycyIsInZvbHVtZXMiLCJjbGVhbmluZyIsImRlZmF1bHRUcmFja2VyIiwiZG9ja2VyQ29tcG9zZVBhcnNlIiwiZmlsZVBhdGgiLCJ5YW1sIiwibG9hZCIsImZzIiwicmVhZEZpbGUiLCJkYyIsImRvY2tlckNvbXBvc2VHZXRNYWluIiwiZm9yY2UiLCJkb2NrZXJDb21wb3NlUmVzb2x2ZSIsImRvY2tlckNvbXBvc2UiLCJwcmVmaXhOYW1lIiwibmFtZSIsInBhdGgiLCJiYXNlbmFtZSIsIl9fZGlybmFtZSIsImdldFNlcnZpY2VEZWYiLCJwYXJzZVBvcnRzIiwicG9ydHNDZmciLCJhdm9pZENvbmZsaWN0cyIsIm1hcExvY2FsIiwiaG9zdCIsInBvcnRzIiwicnVuQXJncyIsInJlZHVjZSIsImFyZ3MiLCJwb3J0U3RyIiwibHAiLCJkcCIsInNwbGl0IiwibG9jYWxEZWZhdWx0IiwicGFyc2VJbnQiLCJkb2NrZXIiLCJsb2NhbCIsInBvcnQiLCJwdXNoIiwicGFyc2VFbnYiLCJlbnYiLCJBcnJheSIsImlzQXJyYXkiLCJmbGF0TWFwIiwiZSIsImsiLCJ2IiwicGFyc2VVTGltaXRzIiwidWwiLCJzb2Z0IiwiaGFyZCIsInBhcnNlVm9sdW1lcyIsInZvbENmZyIsIm5hbWVTdWZmaXgiLCJ2b2xNYXAiLCJtYXAiLCJzcmMiLCJyZXN0IiwicmVhbFNyYyIsInJlc29sdmUiLCJqb2luIiwicGFyc2VOZXR3b3JrcyIsIm5ldENmZyIsIm5ldE1hcCIsIm4iLCJkb2NrZXJDb21wb3NlQ3JlYXRlTmV0d29ya3MiLCJuYW1lcyIsInRyYWNrZXIiLCJQcm9taXNlIiwiYWxsIiwia2V5IiwidmFsIiwiaW5jbHVkZXMiLCJuZXR3b3JrIiwic2V0IiwiZG9ja2VyQ29tcG9zZUNyZWF0ZVZvbHVtZXMiLCJ2b2x1bWUiLCJEb2NrZXJDb21wb3NlU2VydmljZSIsImNvbnN0cnVjdG9yIiwic2VydmljZURlZiIsImltYWdlIiwiZGVmYXVsdENvbnRhaW5lck5hbWUiLCJjb250YWluZXJfbmFtZSIsImNtZCIsImNvbW1hbmQiLCJlbnZBcmdzIiwiZW52aXJvbm1lbnQiLCJnZXROYW1lcyIsIm1heCIsImkiLCJzdWZmaXgiLCJ0ZXN0TmFtZSIsImNvbnRhaW5lciIsImFsaWFzZXMiLCJFcnJvciIsImdldFBvcnRzIiwiZ2V0RGVmYXVsdFBvcnRJbmZvIiwiZ2V0RGVmYXVsdFBvcnRzIiwiZ2V0RGVmYXVsdFBvcnRBcmdzIiwiZ2V0RGVmYXVsdFVybHMiLCJnZXRVcmxzIiwiZ2V0RGVmYXVsdE5ldHdvcmtJbmZvIiwiZ2V0RGVmYXVsdE5ldHdvcmtzIiwiZ2V0RGVmYXVsdE5ldHdvcmtBcmdzIiwiZ2V0RGVmYXVsdFZvbHVtZUluZm8iLCJnZXREZWZhdWx0Vm9sdW1lcyIsImdldERlZmF1bHRWb2x1bWVBcmdzIiwicHVsbCIsImdldEJhc2VSdW5BcmdzIiwidWxBcmdzIiwidWxpbWl0cyIsIm5ldEFyZ3MiLCJhc3NlbWJsZVJ1bkFyZ3MiLCJjb250YWluZXJOYW1lIiwiYWRkaXRpb25hbEFyZ3MiLCJhZGRpdGlvbmFsIiwiYSIsImdldFJ1bkFyZ3MiLCJtYXBMb2NhbFBvcnRzIiwiY05hbWUiLCJwQXJncyIsInZBcmdzIiwidXAiLCJoZWFsdGhDaGVjayIsIm1hcFZvbHVtZXMiLCJtYXBQb3J0cyIsInNpemUiLCJpc1J1bm5pbmciLCJzdGFydCIsImlkQWxpYXMiLCJpZCIsInNsaWNlIiwidXJscyIsImluZm8iLCJzZXJ2aWNlIiwiZG93biIsImluY2x1ZGVEZWZhdWx0cyIsImluY2x1ZGVWb2x1bWVzIiwiaW5jbHVkZU5ldHdvcmtzIiwiZG9ja2VyQ29tcG9zZVRlYXJkb3duIiwidGVhcmRvd24iLCJwYXJzZSIsInN2Y0RlZiIsImFsaWFzIiwiZG9ja2VyQ29tcG9zZUdldEFsbFNlcnZpY2VzIiwicyIsInByb21pc2VzIiwiZnJvbSIsInZhbHVlcyIsImNsZWFyIiwic3ZjTmFtZXMiLCJsZW5ndGgiLCJjIiwicm0iLCJlcnIiLCJtZXNzYWdlIiwiZG9ja2VyQ29tcG9zZVJ1blNlcnZpY2UiLCJ1cE9wdGlvbnMiLCJ1cFJlc3VsdCIsInVybCIsImRvY2tlclVybCIsImRvY2tlclBvcnQiLCJmb3JFYWNoIl0sIm1hcHBpbmdzIjoiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7Ozs7OztBQU1BLDBDOzs7Ozs7Ozs7Ozs7OztBQWNPLE1BQU1BLGtDQUFrQyxHQUFHLE9BQXFDO0FBQ3JGQyxFQUFBQSxRQUFRLEVBQUUsSUFBSUMsR0FBSixFQUQyRTtBQUVyRkMsRUFBQUEsUUFBUSxFQUFFLElBQUlELEdBQUosRUFGMkU7QUFHckZFLEVBQUFBLFVBQVUsRUFBRSxJQUFJRixHQUFKLEVBSHlFO0FBSXJGRyxFQUFBQSxPQUFPLEVBQUUsSUFBSUgsR0FBSixFQUo0RTtBQUtyRkksRUFBQUEsUUFBUSxFQUFFLElBTDJFLEVBQXJDLENBQTNDLEM7OztBQVFQLE1BQU1DLGNBQWMsR0FBR1Asa0NBQWtDLEVBQXpEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTRDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1RLGtCQUFrQixHQUFHO0FBQ2hDQyxRQUFpQixHQUFHLHNCQURZO0FBRUpDLGdCQUFLQyxJQUFMLENBQVUsTUFBTUMsaUJBQUdDLFFBQUgsQ0FBWUosUUFBWixDQUFoQixDQUZ2QixDOztBQUlQLElBQUlLLEVBQWtCLEdBQUcsSUFBekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNQyxvQkFBb0IsR0FBRztBQUNsQ0MsS0FBZSxHQUFHLEtBRGdCO0FBRVA7QUFDM0IsTUFBSUEsS0FBSyxJQUFJLENBQUNGLEVBQWQsRUFBa0I7QUFDaEJBLElBQUFBLEVBQUUsR0FBRyxNQUFNTixrQkFBa0IsRUFBN0I7QUFDRDtB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LENBSEY7QUFJSnZJLElBQUFBLEtBQUssRUFBRSxDQUFDLEVBQUVXLEtBQUssRUFBRUMsSUFBVCxFQUFlRixNQUFNLEVBQUU4SCxVQUF2QixFQUFELENBSkg7QUFLRkgsRUFBQUEsUUFMSjtBQU1BLFFBQU0sRUFBRTVCLEVBQUYsRUFBTW5ILElBQU4sRUFBWWlFLEtBQVosS0FBc0JZLFNBQTVCO0FBQ0F3QyxFQUFBQSxJQUFJLENBQUM4QixPQUFMO0FBQ0UsR0FBQyxFQUFFOUgsS0FBRixFQUFEO0FBQ0VBLEVBQUFBLEtBQUssSUFBSSxtQkFBVSxJQUFHa0csT0FBTyxDQUFDdkgsSUFBSyxtQkFBa0JxQixLQUFNLEVBQWxELENBRmI7O0FBSUEsU0FBTztBQUNMLE9BQUcwSCxRQURFO0FBRUw1QixJQUFBQSxFQUZLO0FBR0xsRCxJQUFBQSxLQUhLO0FBSUxqRSxJQUFBQSxJQUpLO0FBS0xzQixJQUFBQSxJQUxLO0FBTUw0SCxJQUFBQSxVQU5LO0FBT0xGLElBQUFBLEdBUEs7QUFRTEMsSUFBQUEsU0FSSyxFQUFQOztBQVVEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgeWFtbCBmcm9tICdqcy15YW1sJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGdldFBvcnQgZnJvbSAnZ2V0LXBvcnQnO1xuaW1wb3J0IHsga2V5cywgZW50cmllcywgbWFwVmFsdWVzQXN5bmMsIHR5cGUgTWFwT2JqIH0gZnJvbSAnLi9tYXBzJztcblxuaW1wb3J0IHsgYnVpbGRMb2cgfSBmcm9tICcuL3J1bic7XG5pbXBvcnQgeyBkb2NrZXJQdWxsIH0gZnJvbSAnLi9kb2NrZXInO1xuaW1wb3J0IHtcbiAgZG9ja2VyQ29udGFpbmVyRmluZCxcbiAgZG9ja2VyQ29udGFpbmVyUnVuRGFlbW9uLFxuICB0eXBlIERvY2tlckNvbnRhaW5lcixcbn0gZnJvbSAnLi9kb2NrZXIuY29udGFpbmVyJztcbmltcG9ydCB7XG4gIGRvY2tlck5ldHdvcmtEZWxldGUsXG4gIGRvY2tlck5ldHdvcmtDcmVhdGUsXG4gIHR5cGUgRG9ja2VyTmV0d29ya0NyZWF0ZU9wdGlvbnMsXG4gIHR5cGUgRG9ja2VyTmV0d29yayxcbn0gZnJvbSAnLi9kb2NrZXIubmV0d29yayc7XG5pbXBvcnQge1xuICBkb2NrZXJWb2x1bWVDcmVhdGUsXG4gIGRvY2tlclZvbHVtZVJtLFxuICB0eXBlIERvY2tlclZvbHVtZSxcbn0gZnJvbSAnLi9kb2NrZXIudm9sdW1lJztcblxuZXhwb3J0IHR5cGUgRG9ja2VyQ29tcG9zZVJlc291cmNlVHJhY2tlciA9IHtcbiAgc2VydmljZXM6IE1hcDxzdHJpbmcsIERvY2tlckNvbXBvc2VTZXJ2aWNlPixcbiAgbmV0d29ya3M6IE1hcDxzdHJpbmcsIERvY2tlck5ldHdvcms+LFxuICBjb250YWluZXJzOiBNYXA8c3RyaW5nLCBEb2NrZXJDb250YWluZXI+LFxuICB2b2x1bWVzOiBNYXA8c3RyaW5nLCBEb2NrZXJWb2x1bWU+LFxuICBjbGVhbmluZzogP1Byb21pc2U8dm9pZD4sXG59O1xuXG5leHBvcnQgY29uc3QgZG9ja2VyQ29tcG9zZUNyZWF0ZVJlc291cmNlVHJhY2tlciA9ICgpOiBEb2NrZXJDb21wb3NlUmVzb3VyY2VUcmFja2VyID0+ICh7XG4gIG5ldHdvcmtzOiBuZXcgTWFwKCksXG4gIHNlcnZpY2VzOiBuZXcgTWFwKCksXG4gIGNvbnRhaW5lcnM6IG5ldyBNYXAoKSxcbiAgdm9sdW1lczogbmV3IE1hcCgpLFxuICBjbGVhbmluZzogbnVsbCxcbn0pO1xuXG5jb25zdCBkZWZhdWx0VHJhY2tlciA9IGRvY2tlckNvbXBvc2VDcmVhdGVSZXNvdXJjZVRyYWNrZXIoKTtcblxudHlwZSBEb2NrZXJDb21wb3NlRW52RGVmID0gc3RyaW5nW10gfCB7IFtzdHJpbmddOiBzdHJpbmcgfTtcblxudHlwZSBEb2NrZXJDb21wb3NlVUxpbWl0RGVmID0gbnVtYmVyIHwgeyBzb2Z0OiBudW1iZXIsIGhhcmQ6IG51bWJlciB9O1xuXG50eXBlIERvY2tlckNvbXBvc2VVTGltaXRzRGVmID0ge1xuICBbc3RyaW5nXTogRG9ja2VyQ29tcG9zZVVMaW1pdERlZixcbn07XG5cbnR5cGUgRG9ja2VyQ29tcG9zZVNlcnZpY2VEZWYgPSB7XG4gIGNvbnRhaW5lcl9uYW1lPzogc3RyaW5nLFxuICBpbWFnZT86IHN0cmluZyxcbiAgcG9ydHM/OiBzdHJpbmdbXSxcbiAgdm9sdW1lcz86IHN0cmluZ1tdLFxuICBjb21tYW5kPzogc3RyaW5nW10sXG4gIG5ldHdvcmtzPzogc3RyaW5nW10sXG4gIGVudmlyb25tZW50PzogRG9ja2VyQ29tcG9zZUVudkRlZixcbiAgbGlua3M/OiBzdHJpbmdbXSxcbiAgdWxpbWl0cz86IERvY2tlckNvbXBvc2VVTGltaXRzRGVmLFxufTtcblxudHlwZSBEb2NrZXJDb21wb3NlVm9sdW1lRGVmID0ge1xuICBuYW1lPzogc3RyaW5nLFxufTtcblxudHlwZSBEb2NrZXJDb21wb3NlTmV0d29ya0RlZiA9IHtcbiAgLi4uRG9ja2VyTmV0d29ya0NyZWF0ZU9wdGlvbnMsXG4gIG5hbWU/OiBzdHJpbmcsXG59O1xuXG50eXBlIERvY2tlckNvbXBvc2UgPSB7XG4gIHZlcnNpb246IHN0cmluZyxcbiAgc2VydmljZXM/OiB7XG4gICAgW3N0cmluZ106IERvY2tlckNvbXBvc2VTZXJ2aWNlRGVmLFxuICB9LFxuICB2b2x1bWVzPzoge1xuICAgIFtzdHJpbmddOiBEb2NrZXJDb21wb3NlVm9sdW1lRGVmLFxuICB9LFxuICBuZXR3b3Jrcz86IHtcbiAgICBbc3RyaW5nXTogRG9ja2VyQ29tcG9zZU5ldHdvcmtEZWYsXG4gIH0sXG59O1xuXG4vKipcbiAqIFBhcnNlIGEgZG9ja2VyLWNvbXBvc2UueW1sIGZpbGUgaW50byBhIHBvam8gcmVwcmVzZW50YXRpb25cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCBQYXRoIHRvIHRoZSBkb2NrZXItY29tcG9zZS55bWwgZmlsZVxuICovXG5leHBvcnQgY29uc3QgZG9ja2VyQ29tcG9zZVBhcnNlID0gYXN5bmMgKFxuICBmaWxlUGF0aD86IHN0cmluZyA9ICcuL2RvY2tlci1jb21wb3NlLnltbCcsXG4pOiBQcm9taXNlPERvY2tlckNvbXBvc2U+ID0+ICh5YW1sLmxvYWQoYXdhaXQgZnMucmVhZEZpbGUoZmlsZVBhdGgpKTogYW55KTtcblxubGV0IGRjOiA/RG9ja2VyQ29tcG9zZSA9IG51bGw7XG5cbi8qKlxuICogR2V0IHRoZSBtYWluIGRvY2tlci1jb21wb3NlLnltbCBmcm9tIHRoZSByb290IG9mIHRoZSByZXBvXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGZvcmNlIEZvcmNlIHJlbG9hZCBmcm9tIGZpbGVcbiAqL1xuZXhwb3J0IGNvbnN0IGRvY2tlckNvbXBvc2VHZXRNYWluID0gYXN5bmMgKFxuICBmb3JjZT86IGJvb2xlYW4gPSBmYWxzZSxcbik6IFByb21pc2U8RG9ja2VyQ29tcG9zZT4gPT4ge1xuICBpZiAoZm9yY2UgfHwgIWRjKSB7XG4gICAgZGMgPSBhd2FpdCBkb2NrZXJDb21wb3NlUGFyc2UoKTtcbiAgfVxuICByZXR1cm4gZGM7XG59O1xuXG4vLyBGdW5jdGlvbiB0aGF0IGhhbmRsZXMgcGFzc2VkIGRvY2tlckNvbXBvc2UgYXMgZWl0aGVyIGEgZmlsZSBwYXRoIG9yIGBEb2NrZXJDb21wb3NlYCBvYmplY3QuXG4vLyBJZiBub3QgcGFzc2VkLCBkZWZhdWx0cyB0byB0aGUgbWFpbiBkb2NrZXItY29tcG9zZS55bWwgZnJvbSB0aGUgcm9vdCBvZiB0aGUgcmVwb1xuY29uc3QgZG9ja2VyQ29tcG9zZVJlc29sdmUgPSBhc3luYyAoXG4gIGRvY2tlckNvbXBvc2U/OiA/KHN0cmluZyB8IERvY2tlckNvbXBvc2UpLFxuICBmb3JjZT86IGJvb2xlYW4sXG4pOiBQcm9taXNlPERvY2tlckNvbXBvc2U+ID0+XG4gIHR5cGVvZiBkb2NrZXJDb21wb3NlID09PSAnc3RyaW5nJ1xuICAgID8gZG9ja2VyQ29tcG9zZVBhcnNlKGRvY2tlckNvbXBvc2UpXG4gICAgOiBkb2NrZXJDb21wb3NlIHx8IGRvY2tlckNvbXBvc2VHZXRNYWluKGZvcmNlKTtcblxuLy8gRGV0ZXJtaW5lcyBhbiB1bm5hbWVkIHJlc291cmNlJ3MgbmFtZSBmcm9tIHRoZSBkaXJuYW1lIGNvbWJpbmVkIHdpdGggdGhlIGtleVxuY29uc3QgcHJlZml4TmFtZSA9IChuYW1lOiBzdHJpbmcpID0+IGAke3BhdGguYmFzZW5hbWUoX19kaXJuYW1lKX1fJHtuYW1lfWA7XG5cbmNvbnN0IGdldFNlcnZpY2VEZWYgPSBhc3luYyAoXG4gIG5hbWU6IHN0cmluZyxcbiAgZm9yY2U/OiBib29sZWFuLFxuICBkb2NrZXJDb21wb3NlPzogPyhzdHJpbmcgfCBEb2NrZXJDb21wb3NlKSxcbik6IFByb21pc2U8P0RvY2tlckNvbXBvc2VTZXJ2aWNlRGVmPiA9PlxuICAoYXdhaXQgZG9ja2VyQ29tcG9zZVJlc29sdmUoZG9ja2VyQ29tcG9zZSwgZm9yY2UpKS5zZXJ2aWNlcz8uW25hbWVdIHx8IG51bGw7XG5cbnR5cGUgUG9ydE1hcCA9IHtcbiAgbG9jYWw6ID9udW1iZXIsXG4gIGxvY2FsRGVmYXVsdDogbnVtYmVyLFxuICBkb2NrZXI6IG51bWJlcixcbn07XG5cbnR5cGUgVXJsTWFwID0ge1xuICBsb2NhbDogP3N0cmluZyxcbiAgZG9ja2VyOiA/c3RyaW5nLFxufTtcblxudHlwZSBQYXJzZWRQb3J0SW5mbyA9IHtcbiAgcnVuQXJnczogc3RyaW5nW10sXG4gIHBvcnRzOiBQb3J0TWFwW10sXG59O1xuXG5jb25zdCBwYXJzZVBvcnRzID0gYXN5bmMgKFxuICBwb3J0c0NmZz86IHN0cmluZ1tdID0gW10sXG4gIGF2b2lkQ29uZmxpY3RzPzogYm9vbGVhbiA9IHRydWUsXG4gIG1hcExvY2FsPzogYm9vbGVhbiA9IHRydWUsXG4gIGhvc3Q/OiBzdHJpbmcgPSAnMC4wLjAuMCcsXG4pOiBQcm9taXNlPFBhcnNlZFBvcnRJbmZvPiA9PiB7XG4gIGNvbnN0IHBvcnRzOiBQb3J0TWFwW10gPSBbXTtcbiAgY29uc3QgcnVuQXJncyA9IGF3YWl0IHBvcnRzQ2ZnLnJlZHVjZShhc3luYyAoYXJncywgcG9ydFN0cikgPT4ge1xuICAgIGNvbnN0IFtscCwgZHBdID0gcG9ydFN0ci5zcGxpdCgnOicpO1xuICAgIGNvbnN0IGxvY2FsRGVmYXVsdCA9IHBhcnNlSW50KGxwLCAxMCk7XG4gICAgY29uc3QgZG9ja2VyID0gcGFyc2VJbnQoZHAsIDEwKTtcbiAgICBjb25zdCBsb2NhbCA9IG1hcExvY2FsXG4gICAgICA/IGF2b2lkQ29uZmxpY3RzXG4gICAgICAgID8gYXdhaXQgZ2V0UG9ydCh7IHBvcnQ6IGxvY2FsRGVmYXVsdCwgaG9zdCB9KVxuICAgICAgICA6IGxvY2FsRGVmYXVsdFxuICAgICAgOiBudWxsO1xuICAgIHBvcnRzLnB1c2goeyBsb2NhbCwgbG9jYWxEZWZhdWx0LCBkb2NrZXIgfSk7XG4gICAgcmV0dXJuIGxvY2FsID8gWy4uLihhd2FpdCBhcmdzKSwgJy1wJywgYCR7bG9jYWx9OiR7ZG9ja2VyfWBdIDogYXJncztcbiAgfSwgW10pO1xuICByZXR1cm4geyBydW5BcmdzLCBwb3J0cyB9O1xufTtcblxuY29uc3QgcGFyc2VFbnYgPSAoZW52PzogRG9ja2VyQ29tcG9zZUVudkRlZiA9IFtdKTogc3RyaW5nW10gPT5cbiAgQXJyYXkuaXNBcnJheShlbnYpXG4gICAgPyBlbnYuZmxhdE1hcCgoZSkgPT4gWyctZScsIGVdKVxuICAgIDogZW50cmllcyhlbnYpLmZsYXRNYXAoKFtrLCB2XSkgPT4gWyctZScsIGAke2t9PSR7dn1gXSk7XG5cbmNvbnN0IHBhcnNlVUxpbWl0cyA9ICh1bD86IERvY2tlckNvbXBvc2VVTGltaXRzRGVmID0ge30pOiBzdHJpbmdbXSA9PlxuICBlbnRyaWVzKHVsKS5mbGF0TWFwKChbaywgdl0pID0+IFtcbiAgICAnLS11bGltaXQnLFxuICAgIGAke2t9PSR7XG4gICAgICB0eXBlb2YgdiA9PT0gJ251bWJlcicgPyB2IDogYCR7di5zb2Z0fSR7di5oYXJkID8gYDoke3YuaGFyZH1gIDogJyd9YFxuICAgIH1gLFxuICBdKTtcblxudHlwZSBQYXJzZWRWb2x1bWVJbmZvID0ge1xuICBydW5BcmdzOiBzdHJpbmdbXSxcbiAgdm9sdW1lczogc3RyaW5nW10sXG59O1xuXG5jb25zdCBwYXJzZVZvbHVtZXMgPSBhc3luYyAoXG4gIHZvbENmZz86IHN0cmluZ1tdID0gW10sXG4gIG5hbWVTdWZmaXg/OiBzdHJpbmcgPSAnJyxcbiAgZG9ja2VyQ29tcG9zZT86ID8oc3RyaW5nIHwgRG9ja2VyQ29tcG9zZSksXG4pOiBQcm9taXNlPFBhcnNlZFZvbHVtZUluZm8+ID0+IHtcbiAgY29uc3QgeyB2b2x1bWVzOiB2b2xNYXAgfSA9IGF3YWl0IGRvY2tlckNvbXBvc2VSZXNvbHZlKGRvY2tlckNvbXBvc2UpO1xuICBjb25zdCB2b2x1bWVzID0gW107XG4gIGNvbnN0IHJ1bkFyZ3M6IHN0cmluZ1tdID0gdm9sQ2ZnXG4gICAgLm1hcCgodikgPT4ge1xuICAgICAgY29uc3QgW3NyYywgLi4ucmVzdF0gPSB2LnNwbGl0KCc6Jyk7XG4gICAgICBjb25zdCBuYW1lID0gdm9sTWFwPy5bc3JjXVxuICAgICAgICA/IGAke3ZvbE1hcFtzcmNdLm5hbWUgfHwgcHJlZml4TmFtZShzcmMpfSR7bmFtZVN1ZmZpeH1gXG4gICAgICAgIDogbnVsbDtcbiAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgIHZvbHVtZXMucHVzaChuYW1lKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlYWxTcmMgPSBuYW1lIHx8IHBhdGgucmVzb2x2ZShzcmMpO1xuICAgICAgcmV0dXJuIFtyZWFsU3JjLCAuLi5yZXN0XS5qb2luKCc6Jyk7XG4gICAgfSlcbiAgICAuZmxhdE1hcCgodikgPT4gWyctdicsIHZdKTtcbiAgcmV0dXJuIHsgcnVuQXJncywgdm9sdW1lcyB9O1xufTtcblxudHlwZSBQYXJzZWROZXR3b3JrSW5mbyA9IHtcbiAgcnVuQXJnczogc3RyaW5nW10sXG4gIG5ldHdvcmtzOiBzdHJpbmdbXSxcbn07XG5cbmNvbnN0IHBhcnNlTmV0d29ya3MgPSBhc3luYyAoXG4gIG5ldENmZz86IHN0cmluZ1tdID0gW10sXG4gIGRvY2tlckNvbXBvc2U/OiA/KHN0cmluZyB8IERvY2tlckNvbXBvc2UpLFxuKTogUHJvbWlzZTxQYXJzZWROZXR3b3JrSW5mbz4gPT4ge1xuICBjb25zdCB7IG5ldHdvcmtzOiBuZXRNYXAgfSA9IGF3YWl0IGRvY2tlckNvbXBvc2VSZXNvbHZlKGRvY2tlckNvbXBvc2UpO1xuICBjb25zdCBuZXR3b3JrcyA9IG5ldENmZy5tYXAoKG4pID0+IG5ldE1hcD8uW25dLm5hbWUgfHwgcHJlZml4TmFtZShuKSk7XG4gIHJldHVybiB7XG4gICAgbmV0d29ya3MsXG4gICAgcnVuQXJnczogKG5ldHdvcmtzLmZsYXRNYXAoKG4pID0+IFsnLS1uZXR3b3JrJywgbl0pOiBzdHJpbmdbXSksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgZG9ja2VyQ29tcG9zZUNyZWF0ZU5ldHdvcmtzID0gYXN5bmMgKFxuICBuYW1lcz86ID8oc3RyaW5nW10pLFxuICBkb2NrZXJDb21wb3NlPzogPyhzdHJpbmcgfCBEb2NrZXJDb21wb3NlKSxcbiAgdHJhY2tlcj86IERvY2tlckNvbXBvc2VSZXNvdXJjZVRyYWNrZXIgPSBkZWZhdWx0VHJhY2tlcixcbikgPT4ge1xuICBjb25zdCB7IG5ldHdvcmtzID0ge30gfSA9IGF3YWl0IGRvY2tlckNvbXBvc2VSZXNvbHZlKGRvY2tlckNvbXBvc2UpO1xuICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBlbnRyaWVzKG5ldHdvcmtzKS5tYXAoYXN5bmMgKFtrZXksIHZhbF0pID0+IHtcbiAgICAgIGNvbnN0IG5hbWUgPSB2YWw/Lm5hbWUgfHwgcHJlZml4TmFtZShrZXkpO1xuICAgICAgaWYgKCFuYW1lcyB8fCBuYW1lcy5pbmNsdWRlcyhuYW1lKSkge1xuICAgICAgICBjb25zdCBuZXR3b3JrID0gYXdhaXQgZG9ja2VyTmV0d29ya0NyZWF0ZShuYW1lLCAodmFsIHx8IHt9OiBhbnkpKTtcbiAgICAgICAgaWYgKG5ldHdvcmspIHtcbiAgICAgICAgICB0cmFja2VyLm5ldHdvcmtzLnNldChuYW1lLCBuZXR3b3JrKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pLFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGRvY2tlckNvbXBvc2VDcmVhdGVWb2x1bWVzID0gYXN5bmMgKFxuICBuYW1lcz86IHN0cmluZ1tdLFxuICBkb2NrZXJDb21wb3NlPzogPyhzdHJpbmcgfCBEb2NrZXJDb21wb3NlKSxcbiAgdHJhY2tlcj86IERvY2tlckNvbXBvc2VSZXNvdXJjZVRyYWNrZXIgPSBkZWZhdWx0VHJhY2tlcixcbikgPT4ge1xuICBjb25zdCB7IHZvbHVtZXMgPSB7fSB9ID0gYXdhaXQgZG9ja2VyQ29tcG9zZVJlc29sdmUoZG9ja2VyQ29tcG9zZSk7XG4gIGF3YWl0IFByb21pc2UuYWxsKFxuICAgIGVudHJpZXModm9sdW1lcykubWFwKGFzeW5jIChba2V5LCB2YWxdKSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gdmFsPy5uYW1lIHx8IHByZWZpeE5hbWUoa2V5KTtcbiAgICAgIGlmICghbmFtZXMgfHwgbmFtZXMuaW5jbHVkZXMobmFtZSkpIHtcbiAgICAgICAgY29uc3Qgdm9sdW1lID0gYXdhaXQgZG9ja2VyVm9sdW1lQ3JlYXRlKG5hbWUsICh2YWwgfHwge306IGFueSkpO1xuICAgICAgICBpZiAodm9sdW1lKSB7XG4gICAgICAgICAgdHJhY2tlci52b2x1bWVzLnNldChuYW1lLCB2b2x1bWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSksXG4gICk7XG59O1xuXG50eXBlIEhlYWx0aENoZWNrRm4gPSAoVXBSZXN1bHQpID0+IFByb21pc2U8dm9pZD47XG5cbnR5cGUgVXBPcHRpb25zID0ge1xuICBoZWFsdGhDaGVjaz86IEhlYWx0aENoZWNrRm4sXG4gIGF2b2lkQ29uZmxpY3RzPzogYm9vbGVhbixcbiAgbWFwVm9sdW1lcz86IGJvb2xlYW4sXG4gIG1hcFBvcnRzPzogYm9vbGVhbixcbiAgY21kPzogc3RyaW5nW10sXG4gIHRyYWNrZXI/OiBEb2NrZXJDb21wb3NlUmVzb3VyY2VUcmFja2VyLFxufTtcblxudHlwZSBTZXJ2aWNlTmFtZUluZm8gPSB7XG4gIG5hbWU6IHN0cmluZyxcbiAgYWxpYXNlczogc3RyaW5nW10sXG4gIHN1ZmZpeDogc3RyaW5nLFxufTtcblxudHlwZSBVcFJlc3VsdCA9IHt8XG4gIHNlcnZpY2U6IERvY2tlckNvbXBvc2VTZXJ2aWNlLFxuICBjb250YWluZXI6IERvY2tlckNvbnRhaW5lcixcbiAgY29udGFpbmVyTmFtZTogc3RyaW5nLFxuICBhbGlhc2VzOiBzdHJpbmdbXSxcbiAgcG9ydHM6IFBvcnRNYXBbXSxcbiAgdXJsczogVXJsTWFwW10sXG4gIHZvbHVtZXM6IHN0cmluZ1tdLFxufH07XG5cbmV4cG9ydCBjbGFzcyBEb2NrZXJDb21wb3NlU2VydmljZSB7XG4gICNuYW1lOiBzdHJpbmc7XG4gICNzdmNEZWY6IERvY2tlckNvbXBvc2VTZXJ2aWNlRGVmO1xuICAjZG9ja2VyQ29tcG9zZTogPyhEb2NrZXJDb21wb3NlIHwgc3RyaW5nKTtcbiAgI3RyYWNrZXI6IERvY2tlckNvbXBvc2VSZXNvdXJjZVRyYWNrZXIgPSBkb2NrZXJDb21wb3NlQ3JlYXRlUmVzb3VyY2VUcmFja2VyKCk7XG5cbiAgLy8gbGF6aWx5IGNvbXB1dGVkXG4gICNwYXJzZWRQb3J0czogP1BhcnNlZFBvcnRJbmZvID0gbnVsbDtcbiAgI3BhcnNlZE5ldHdvcmtzOiA/UGFyc2VkTmV0d29ya0luZm8gPSBudWxsO1xuICAjcGFyc2VkVm9sdW1lczogP1BhcnNlZFZvbHVtZUluZm8gPSBudWxsO1xuICAjYmFzZVJ1bkFyZ3M6ID8oc3RyaW5nW10pID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgc2VydmljZURlZjogRG9ja2VyQ29tcG9zZVNlcnZpY2VEZWYsXG4gICAgZG9ja2VyQ29tcG9zZT86ID8oRG9ja2VyQ29tcG9zZSB8IHN0cmluZyksXG4gICkge1xuICAgIHRoaXMuI25hbWUgPSBuYW1lO1xuICAgIHRoaXMuI3N2Y0RlZiA9IHNlcnZpY2VEZWY7XG4gICAgdGhpcy4jZG9ja2VyQ29tcG9zZSA9IGRvY2tlckNvbXBvc2UgfHwgbnVsbDtcbiAgfVxuXG4gIGdldCBuYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuI25hbWU7XG4gIH1cblxuICBnZXQgc2VydmljZURlZigpOiBEb2NrZXJDb21wb3NlU2VydmljZURlZiB7XG4gICAgcmV0dXJuIHRoaXMuI3N2Y0RlZjtcbiAgfVxuXG4gIGdldCBpbWFnZSgpOiA/c3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy4jc3ZjRGVmLmltYWdlIHx8IG51bGw7XG4gIH1cblxuICBnZXQgZGVmYXVsdENvbnRhaW5lck5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy4jc3ZjRGVmLmNvbnRhaW5lcl9uYW1lIHx8IHRoaXMuI25hbWU7XG4gIH1cblxuICBnZXQgY21kKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy4jc3ZjRGVmLmNvbW1hbmQgfHwgW107XG4gIH1cblxuICBnZXQgZW52QXJncygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHBhcnNlRW52KHRoaXMuI3N2Y0RlZi5lbnZpcm9ubWVudCk7XG4gIH1cblxuICAvKipcbiAgICogRmluZCAoYXZhaWxhYmxlKSBjb250YWluZXIgbmFtZSBhbmQgYWxpYXMoZXMpXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gYXZvaWRDb25mbGljdHMgaWYgYHRydWVgLCBmaW5kIGEgY29udGFpbmVyIG5hbWUgdGhhdCBpcyB1bnVzZWRcbiAgICogQHBhcmFtIHtudW1iZXJ9IG1heCBtYXhpbXVtIG51bWJlciBvZiBuYW1lcyB0byB0cnlcbiAgICovXG4gIGFzeW5jIGdldE5hbWVzKFxuICAgIGF2b2lkQ29uZmxpY3RzPzogYm9vbGVhbiA9IGZhbHNlLFxuICAgIG1heD86IG51bWJlciA9IDEwMCxcbiAgKTogUHJvbWlzZTxTZXJ2aWNlTmFtZUluZm8+IHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1hd2FpdC1pbi1sb29wICovXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXg7IGkgKz0gMSkge1xuICAgICAgY29uc3Qgc3VmZml4ID0gaSA/IGAtJHtpfWAgOiAnJztcbiAgICAgIGNvbnN0IHRlc3ROYW1lID0gYCR7dGhpcy5kZWZhdWx0Q29udGFpbmVyTmFtZX0ke3N1ZmZpeH1gO1xuICAgICAgY29uc3QgY29udGFpbmVyID0gYXdhaXQgZG9ja2VyQ29udGFpbmVyRmluZCh0ZXN0TmFtZSwgeyBhbGw6IHRydWUgfSk7XG4gICAgICBpZiAoIWF2b2lkQ29uZmxpY3RzIHx8ICFjb250YWluZXIpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuYW1lOiB0ZXN0TmFtZSxcbiAgICAgICAgICBhbGlhc2VzOiBbYCR7dGhpcy5uYW1lfSR7c3VmZml4fWBdLFxuICAgICAgICAgIHN1ZmZpeCxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgLyogZXNsaW50LWVuYWJsZSBuby1hd2FpdC1pbi1sb29wICovXG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEZhaWxlZCB0byBmaW5kIGF2YWlsYWJsZSBjb250YWluZXIgbmFtZSBmb3IgJHt0aGlzLmRlZmF1bHRDb250YWluZXJOYW1lfWAsXG4gICAgKTtcbiAgfVxuXG4gIC8vIEdldCAoYXZhaWxhYmxlKSBwb3J0IG1hcHBpbmdzXG4gIGFzeW5jIGdldFBvcnRzKFxuICAgIGF2b2lkQ29uZmxpY3RzPzogYm9vbGVhbiA9IGZhbHNlLFxuICAgIG1hcExvY2FsPzogYm9vbGVhbiA9IHRydWUsXG4gICk6IFByb21pc2U8UGFyc2VkUG9ydEluZm8+IHtcbiAgICByZXR1cm4gcGFyc2VQb3J0cyh0aGlzLiNzdmNEZWYucG9ydHMsIGF2b2lkQ29uZmxpY3RzLCBtYXBMb2NhbCk7XG4gIH1cblxuICBhc3luYyBnZXREZWZhdWx0UG9ydEluZm8oKTogUHJvbWlzZTxQYXJzZWRQb3J0SW5mbz4ge1xuICAgIGlmICghdGhpcy4jcGFyc2VkUG9ydHMpIHtcbiAgICAgIHRoaXMuI3BhcnNlZFBvcnRzID0gYXdhaXQgdGhpcy5nZXRQb3J0cygpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy4jcGFyc2VkUG9ydHM7XG4gIH1cblxuICBhc3luYyBnZXREZWZhdWx0UG9ydHMoKTogUHJvbWlzZTxQb3J0TWFwW10+IHtcbiAgICBjb25zdCB7IHBvcnRzIH0gPSBhd2FpdCB0aGlzLmdldERlZmF1bHRQb3J0SW5mbygpO1xuICAgIHJldHVybiBwb3J0cztcbiAgfVxuXG4gIGFzeW5jIGdldERlZmF1bHRQb3J0QXJncygpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgeyBydW5BcmdzIH0gPSBhd2FpdCB0aGlzLmdldERlZmF1bHRQb3J0SW5mbygpO1xuICAgIHJldHVybiBydW5BcmdzO1xuICB9XG5cbiAgYXN5bmMgZ2V0RGVmYXVsdFVybHMoKTogUHJvbWlzZTxVcmxNYXBbXT4ge1xuICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLmdldFVybHMoXG4gICAgICBhd2FpdCB0aGlzLmdldERlZmF1bHRQb3J0cygpLFxuICAgICAgdGhpcy5kZWZhdWx0Q29udGFpbmVyTmFtZSxcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZ2V0RGVmYXVsdE5ldHdvcmtJbmZvKCk6IFByb21pc2U8UGFyc2VkTmV0d29ya0luZm8+IHtcbiAgICBpZiAoIXRoaXMuI3BhcnNlZE5ldHdvcmtzKSB7XG4gICAgICB0aGlzLiNwYXJzZWROZXR3b3JrcyA9IGF3YWl0IHBhcnNlTmV0d29ya3ModGhpcy4jc3ZjRGVmLm5ldHdvcmtzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuI3BhcnNlZE5ldHdvcmtzO1xuICB9XG5cbiAgYXN5bmMgZ2V0RGVmYXVsdE5ldHdvcmtzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBjb25zdCB7IG5ldHdvcmtzIH0gPSBhd2FpdCB0aGlzLmdldERlZmF1bHROZXR3b3JrSW5mbygpO1xuICAgIHJldHVybiBuZXR3b3JrcztcbiAgfVxuXG4gIGFzeW5jIGdldERlZmF1bHROZXR3b3JrQXJncygpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgeyBydW5BcmdzIH0gPSBhd2FpdCB0aGlzLmdldERlZmF1bHROZXR3b3JrSW5mbygpO1xuICAgIHJldHVybiBydW5BcmdzO1xuICB9XG5cbiAgYXN5bmMgZ2V0RGVmYXVsdFZvbHVtZUluZm8oKTogUHJvbWlzZTxQYXJzZWRWb2x1bWVJbmZvPiB7XG4gICAgaWYgKCF0aGlzLiNwYXJzZWRWb2x1bWVzKSB7XG4gICAgICB0aGlzLiNwYXJzZWRWb2x1bWVzID0gYXdhaXQgcGFyc2VWb2x1bWVzKHRoaXMuI3N2Y0RlZi5uZXR3b3Jrcyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLiNwYXJzZWRWb2x1bWVzO1xuICB9XG5cbiAgYXN5bmMgZ2V0RGVmYXVsdFZvbHVtZXMoKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHsgdm9sdW1lcyB9ID0gYXdhaXQgdGhpcy5nZXREZWZhdWx0Vm9sdW1lSW5mbygpO1xuICAgIHJldHVybiB2b2x1bWVzO1xuICB9XG5cbiAgYXN5bmMgZ2V0RGVmYXVsdFZvbHVtZUFyZ3MoKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHsgcnVuQXJncyB9ID0gYXdhaXQgdGhpcy5nZXREZWZhdWx0Vm9sdW1lSW5mbygpO1xuICAgIHJldHVybiBydW5BcmdzO1xuICB9XG5cbiAgYXN5bmMgcHVsbCgpIHtcbiAgICBpZiAoIXRoaXMuaW1hZ2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHB1bGwgJyR7dGhpcy5uYW1lfScsIG5vIGltYWdlIGNvbmZpZ3VyZWQuYCk7XG4gICAgfVxuICAgIGF3YWl0IGRvY2tlclB1bGwoeyBpbWFnZTogdGhpcy5pbWFnZSB9KTtcbiAgfVxuXG4gIGFzeW5jIGdldEJhc2VSdW5BcmdzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBpZiAoIXRoaXMuI2Jhc2VSdW5BcmdzKSB7XG4gICAgICBjb25zdCBlbnZBcmdzID0gcGFyc2VFbnYodGhpcy4jc3ZjRGVmLmVudmlyb25tZW50KTtcbiAgICAgIGNvbnN0IHVsQXJncyA9IHBhcnNlVUxpbWl0cyh0aGlzLiNzdmNEZWYudWxpbWl0cyk7XG4gICAgICBjb25zdCBuZXRBcmdzID0gYXdhaXQgdGhpcy5nZXREZWZhdWx0TmV0d29ya0FyZ3MoKTtcblxuICAgICAgdGhpcy4jYmFzZVJ1bkFyZ3MgPSBbJy0tcm0nLCAuLi5lbnZBcmdzLCAuLi5uZXRBcmdzLCAuLi51bEFyZ3NdO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy4jYmFzZVJ1bkFyZ3M7XG4gIH1cblxuICBhc3luYyBhc3NlbWJsZVJ1bkFyZ3MoXG4gICAgY29udGFpbmVyTmFtZT86IHN0cmluZyA9IHRoaXMuZGVmYXVsdENvbnRhaW5lck5hbWUsXG4gICAgYWxpYXNlcz86IHN0cmluZ1tdID0gW3RoaXMubmFtZV0sXG4gICAgYWRkaXRpb25hbEFyZ3M/OiBzdHJpbmdbXSxcbiAgKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IGFkZGl0aW9uYWwgPSBhZGRpdGlvbmFsQXJncyB8fCBbXG4gICAgICAuLi4oYXdhaXQgdGhpcy5nZXREZWZhdWx0UG9ydEFyZ3MoKSksXG4gICAgICAuLi4oYXdhaXQgdGhpcy5nZXREZWZhdWx0Vm9sdW1lQXJncygpKSxcbiAgICBdO1xuICAgIHJldHVybiBbXG4gICAgICAuLi4oYXdhaXQgdGhpcy5nZXRCYXNlUnVuQXJncygpKSxcbiAgICAgIC4uLihjb250YWluZXJOYW1lID8gWyctLW5hbWUnLCBjb250YWluZXJOYW1lXSA6IFtdKSxcbiAgICAgIC4uLmFsaWFzZXMuZmxhdE1hcCgoYSkgPT4gKGEgPyBbJy0tbmV0d29yay1hbGlhcycsIGFdIDogW10pKSxcbiAgICAgIC4uLmFkZGl0aW9uYWwsXG4gICAgXTtcbiAgfVxuXG4gIGFzeW5jIGdldFJ1bkFyZ3MoXG4gICAgYXZvaWRDb25mbGljdHM/OiBib29sZWFuID0gZmFsc2UsXG4gICAgbWFwTG9jYWxQb3J0cz86IGJvb2xlYW4gPSB0cnVlLFxuICApOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgeyBuYW1lOiBjTmFtZSwgYWxpYXNlcywgc3VmZml4IH0gPSBhd2FpdCB0aGlzLmdldE5hbWVzKFxuICAgICAgYXZvaWRDb25mbGljdHMsXG4gICAgKTtcbiAgICBjb25zdCB7IHJ1bkFyZ3M6IHBBcmdzIH0gPSBhd2FpdCB0aGlzLmdldFBvcnRzKFxuICAgICAgYXZvaWRDb25mbGljdHMsXG4gICAgICBtYXBMb2NhbFBvcnRzLFxuICAgICk7XG4gICAgY29uc3QgeyBydW5BcmdzOiB2QXJncyB9ID0gYXdhaXQgcGFyc2VWb2x1bWVzKHRoaXMuI3N2Y0RlZi52b2x1bWVzLCBzdWZmaXgpO1xuICAgIHJldHVybiB0aGlzLmFzc2VtYmxlUnVuQXJncyhjTmFtZSwgYWxpYXNlcywgWy4uLnBBcmdzLCAuLi52QXJnc10pO1xuICB9XG5cbiAgYXN5bmMgdXAoe1xuICAgIGhlYWx0aENoZWNrLFxuICAgIGF2b2lkQ29uZmxpY3RzID0gZmFsc2UsXG4gICAgbWFwVm9sdW1lcyA9IHRydWUsXG4gICAgbWFwUG9ydHMgPSB0cnVlLFxuICAgIGNtZCA9IHRoaXMuY21kLFxuICAgIHRyYWNrZXIgPSBkZWZhdWx0VHJhY2tlcixcbiAgfTogVXBPcHRpb25zID0ge30pOiBQcm9taXNlPFVwUmVzdWx0PiB7XG4gICAgY29uc3QgeyBpbWFnZSB9ID0gdGhpcztcbiAgICBpZiAoIWltYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDYW5ub3QgYnJpbmcgdXAgc2VydmljZSAnJHt0aGlzLm5hbWV9Jywgbm8gaW1hZ2UgZGVmaW5lZC5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuI3RyYWNrZXIuY29udGFpbmVycy5zaXplKSB7XG4gICAgICBidWlsZExvZyhcbiAgICAgICAgYFdhcm5pbmc6IHVwIGNhbGxlZCBvbiBzZXJ2aWNlICcke3RoaXMubmFtZX0nIHdpdGggYWxyZWFkeSBydW5uaW5nIGNvbnRhaW5lcmAsXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCB7IG5hbWU6IGNvbnRhaW5lck5hbWUsIGFsaWFzZXMsIHN1ZmZpeCB9ID0gYXdhaXQgdGhpcy5nZXROYW1lcyhcbiAgICAgIGF2b2lkQ29uZmxpY3RzLFxuICAgICk7XG4gICAgY29uc3QgeyBydW5BcmdzOiBwQXJncywgcG9ydHMgfSA9IGF3YWl0IHRoaXMuZ2V0UG9ydHMoXG4gICAgICBhdm9pZENvbmZsaWN0cyxcbiAgICAgIG1hcFBvcnRzLFxuICAgICk7XG4gICAgY29uc3QgeyBydW5BcmdzOiB2QXJncywgdm9sdW1lcyB9ID0gbWFwVm9sdW1lc1xuICAgICAgPyBhd2FpdCBwYXJzZVZvbHVtZXModGhpcy4jc3ZjRGVmLnZvbHVtZXMsIHN1ZmZpeClcbiAgICAgIDogeyBydW5BcmdzOiBbXSwgdm9sdW1lczogW10gfTtcblxuICAgIGxldCBjb250YWluZXIgPSBhd2FpdCBkb2NrZXJDb250YWluZXJGaW5kKGNvbnRhaW5lck5hbWUsIHsgYWxsOiB0cnVlIH0pO1xuICAgIGlmIChjb250YWluZXIgJiYgIShhd2FpdCBjb250YWluZXIuaXNSdW5uaW5nKCkpKSB7XG4gICAgICBhd2FpdCBjb250YWluZXIuc3RhcnQoKTtcbiAgICB9XG4gICAgaWYgKCFjb250YWluZXIpIHtcbiAgICAgIGF3YWl0IHRoaXMucHVsbCgpO1xuICAgICAgYXdhaXQgZG9ja2VyQ29tcG9zZUNyZWF0ZU5ldHdvcmtzKFxuICAgICAgICBhd2FpdCB0aGlzLmdldERlZmF1bHROZXR3b3JrcygpLFxuICAgICAgICB0aGlzLiNkb2NrZXJDb21wb3NlLFxuICAgICAgICB0aGlzLiN0cmFja2VyLFxuICAgICAgKTtcbiAgICAgIGF3YWl0IGRvY2tlckNvbXBvc2VDcmVhdGVWb2x1bWVzKFxuICAgICAgICB2b2x1bWVzLFxuICAgICAgICB0aGlzLiNkb2NrZXJDb21wb3NlLFxuICAgICAgICB0aGlzLiN0cmFja2VyLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHJ1bkFyZ3MgPSBhd2FpdCB0aGlzLmFzc2VtYmxlUnVuQXJncyhjb250YWluZXJOYW1lLCBhbGlhc2VzLCBbXG4gICAgICAgIC4uLnBBcmdzLFxuICAgICAgICAuLi52QXJncyxcbiAgICAgIF0pO1xuICAgICAgY29udGFpbmVyID0gYXdhaXQgZG9ja2VyQ29udGFpbmVyUnVuRGFlbW9uKHtcbiAgICAgICAgaW1hZ2UsXG4gICAgICAgIHJ1bkFyZ3MsXG4gICAgICAgIGNtZCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBidWlsZExvZyhgUmV1c2luZyBleGlzdGluZyBjb250YWluZXIgZm9yICcke3RoaXMubmFtZX0nIHNlcnZpY2UuYCk7XG4gICAgfVxuICAgIC8vIFRoaXMgc2VydmljZSB0cmFja3MgdGhlIHRoaW5ncyBpdCBjcmVhdGVkXG4gICAgdGhpcy4jdHJhY2tlci5jb250YWluZXJzLnNldChjb250YWluZXJOYW1lLCBjb250YWluZXIpO1xuICAgIC8vIFRoZSBwYXNzZWQgdHJhY2tlciBuZWVkcyB0byB0cmFjayB0aGlzIHNlcnZpY2VcbiAgICB0cmFja2VyLnNlcnZpY2VzLnNldCh0aGlzLm5hbWUsIHRoaXMpO1xuXG4gICAgY29uc3QgaWRBbGlhcyA9IGNvbnRhaW5lci5pZC5zbGljZSgwLCAxMik7XG4gICAgYWxpYXNlcy5wdXNoKGlkQWxpYXMpO1xuICAgIGNvbnN0IHVybHMgPSB0aGlzLmNvbnN0cnVjdG9yLmdldFVybHMocG9ydHMsIGlkQWxpYXMpO1xuXG4gICAgY29uc3QgaW5mbzogVXBSZXN1bHQgPSB7XG4gICAgICBzZXJ2aWNlOiB0aGlzLFxuICAgICAgY29udGFpbmVyLFxuICAgICAgY29udGFpbmVyTmFtZSxcbiAgICAgIGFsaWFzZXMsXG4gICAgICBwb3J0cyxcbiAgICAgIHZvbHVtZXMsXG4gICAgICB1cmxzLFxuICAgIH07XG4gICAgYXdhaXQgaGVhbHRoQ2hlY2s/LihpbmZvKTtcbiAgICByZXR1cm4gaW5mbztcbiAgfVxuXG4gIGFzeW5jIGRvd24oe1xuICAgIGluY2x1ZGVEZWZhdWx0cyA9IGZhbHNlLFxuICAgIGluY2x1ZGVWb2x1bWVzID0gZmFsc2UsXG4gICAgaW5jbHVkZU5ldHdvcmtzID0gZmFsc2UsXG4gIH06IHtcbiAgICBpbmNsdWRlRGVmYXVsdHM/OiBib29sZWFuLFxuICAgIGluY2x1ZGVWb2x1bWVzPzogYm9vbGVhbixcbiAgICBpbmNsdWRlTmV0d29ya3M/OiBib29sZWFuLFxuICB9ID0ge30pIHtcbiAgICBidWlsZExvZyhgQnJpbmdpbmcgZG93biA8JHt0aGlzLm5hbWV9PiBzZXJ2aWNlLi4uYCk7XG4gICAgYXdhaXQgZG9ja2VyQ29tcG9zZVRlYXJkb3duKHtcbiAgICAgIHRyYWNrZXI6IHRoaXMuI3RyYWNrZXIsXG4gICAgICBpbmNsdWRlVm9sdW1lcyxcbiAgICAgIGluY2x1ZGVOZXR3b3JrcyxcbiAgICB9KTtcbiAgICBpZiAoaW5jbHVkZURlZmF1bHRzKSB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSBhd2FpdCBkb2NrZXJDb250YWluZXJGaW5kKHRoaXMuZGVmYXVsdENvbnRhaW5lck5hbWUpO1xuICAgICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgICBhd2FpdCBjb250YWluZXIudGVhcmRvd24odHJ1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGFzeW5jIHBhcnNlKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBmb3JjZT86IGJvb2xlYW4gPSB0cnVlLFxuICAgIGRvY2tlckNvbXBvc2U/OiA/KERvY2tlckNvbXBvc2UgfCBzdHJpbmcpLFxuICApOiBQcm9taXNlPD9Eb2NrZXJDb21wb3NlU2VydmljZT4ge1xuICAgIGNvbnN0IHN2Y0RlZiA9IGF3YWl0IGdldFNlcnZpY2VEZWYobmFtZSwgZm9yY2UsIGRvY2tlckNvbXBvc2UpO1xuICAgIHJldHVybiBzdmNEZWYgPyBuZXcgdGhpcyhuYW1lLCBzdmNEZWYsIGRvY2tlckNvbXBvc2UpIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBnZXRVcmxzKHBvcnRzOiBQb3J0TWFwW10sIGFsaWFzOiBzdHJpbmcpOiBVcmxNYXBbXSB7XG4gICAgcmV0dXJuIHBvcnRzLm1hcCgoeyBsb2NhbCwgZG9ja2VyIH0pID0+ICh7XG4gICAgICBsb2NhbDogbG9jYWwgPyBgaHR0cDovL2xvY2FsaG9zdDoke2xvY2FsfWAgOiBudWxsLFxuICAgICAgZG9ja2VyOiBkb2NrZXIgPyBgaHR0cDovLyR7YWxpYXN9OiR7ZG9ja2VyfWAgOiBudWxsLFxuICAgIH0pKTtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9ja2VyQ29tcG9zZUdldEFsbFNlcnZpY2VzKFxuICBkb2NrZXJDb21wb3NlPzogPyhzdHJpbmcgfCBEb2NrZXJDb21wb3NlKSxcbik6IFByb21pc2U8TWFwT2JqPHN0cmluZywgRG9ja2VyQ29tcG9zZVNlcnZpY2U+PiB7XG4gIGNvbnN0IHsgc2VydmljZXMgfSA9IGF3YWl0IGRvY2tlckNvbXBvc2VSZXNvbHZlKGRvY2tlckNvbXBvc2UpO1xuICByZXR1cm4gbWFwVmFsdWVzQXN5bmMoc2VydmljZXMsIChzLCBuYW1lKSA9PlxuICAgIERvY2tlckNvbXBvc2VTZXJ2aWNlLnBhcnNlKG5hbWUpLFxuICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9ja2VyQ29tcG9zZVRlYXJkb3duKHtcbiAgaW5jbHVkZURlZmF1bHRzID0gZmFsc2UsXG4gIGluY2x1ZGVWb2x1bWVzID0gZmFsc2UsXG4gIGluY2x1ZGVOZXR3b3JrcyA9IGZhbHNlLFxuICBkb2NrZXJDb21wb3NlLFxuICB0cmFja2VyID0gZGVmYXVsdFRyYWNrZXIsXG59OiB7XG4gIGluY2x1ZGVEZWZhdWx0cz86IGJvb2xlYW4sXG4gIGluY2x1ZGVWb2x1bWVzPzogYm9vbGVhbixcbiAgaW5jbHVkZU5ldHdvcmtzPzogYm9vbGVhbixcbiAgZG9ja2VyQ29tcG9zZT86ID8oc3RyaW5nIHwgRG9ja2VyQ29tcG9zZSksXG4gIHRyYWNrZXI/OiBEb2NrZXJDb21wb3NlUmVzb3VyY2VUcmFja2VyLFxufSA9IHt9KTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmICghdHJhY2tlci5jbGVhbmluZykge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICAgIHRyYWNrZXIuY2xlYW5pbmcgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgaWYgKHRyYWNrZXIuc2VydmljZXMuc2l6ZSkge1xuICAgICAgICBidWlsZExvZygnQnJpbmdpbmcgZG93biBzdGFydGVkIGRvY2tlciBzZXJ2aWNlcy4uLicpO1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IFByb21pc2UuYWxsKFxuICAgICAgICAgIEFycmF5LmZyb20odHJhY2tlci5zZXJ2aWNlcy52YWx1ZXMoKSkubWFwKGFzeW5jIChzKSA9PlxuICAgICAgICAgICAgcy5kb3duKHsgaW5jbHVkZVZvbHVtZXMsIGluY2x1ZGVOZXR3b3JrcyB9KSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgICB0cmFja2VyLnNlcnZpY2VzLmNsZWFyKCk7XG4gICAgICAgIGF3YWl0IHByb21pc2VzO1xuICAgICAgfVxuICAgICAgaWYgKGluY2x1ZGVEZWZhdWx0cykge1xuICAgICAgICBjb25zdCB7IHNlcnZpY2VzIH0gPSBhd2FpdCBkb2NrZXJDb21wb3NlUmVzb2x2ZShkb2NrZXJDb21wb3NlKTtcbiAgICAgICAgY29uc3Qgc3ZjTmFtZXMgPSBrZXlzKHNlcnZpY2VzKTtcbiAgICAgICAgaWYgKHN2Y05hbWVzLmxlbmd0aCkge1xuICAgICAgICAgIGJ1aWxkTG9nKCdCcmluZ2luZyBkb3duIGRlZmF1bHQgZG9ja2VyIHNlcnZpY2VzLi4uJyk7XG4gICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBzdmNOYW1lcy5tYXAoYXN5bmMgKHMpID0+XG4gICAgICAgICAgICAgIChhd2FpdCBEb2NrZXJDb21wb3NlU2VydmljZS5wYXJzZShzKSk/LmRvd24oe1xuICAgICAgICAgICAgICAgIGluY2x1ZGVEZWZhdWx0cyxcbiAgICAgICAgICAgICAgICBpbmNsdWRlVm9sdW1lcyxcbiAgICAgICAgICAgICAgICBpbmNsdWRlTmV0d29ya3MsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0cmFja2VyLmNvbnRhaW5lcnMuc2l6ZSkge1xuICAgICAgICBidWlsZExvZygnU3RvcHBpbmcgY3JlYXRlZCBkb2NrZXIgY29udGFpbmVycy4uLicpO1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IFByb21pc2UuYWxsKFxuICAgICAgICAgIEFycmF5LmZyb20odHJhY2tlci5jb250YWluZXJzLnZhbHVlcygpKS5tYXAoYXN5bmMgKGMpID0+XG4gICAgICAgICAgICBjLnRlYXJkb3duKHRydWUpLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIHRyYWNrZXIuY29udGFpbmVycy5jbGVhcigpO1xuICAgICAgICBhd2FpdCBwcm9taXNlcztcbiAgICAgIH1cblxuICAgICAgaWYgKGluY2x1ZGVWb2x1bWVzKSB7XG4gICAgICAgIGlmICh0cmFja2VyLnZvbHVtZXMuc2l6ZSkge1xuICAgICAgICAgIGJ1aWxkTG9nKCdSZW1vdmluZyBjcmVhdGVkIGRvY2tlciB2b2x1bWVzLi4uJyk7XG4gICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBQcm9taXNlLmFsbChcbiAgICAgICAgICAgIEFycmF5LmZyb20odHJhY2tlci52b2x1bWVzLnZhbHVlcygpKS5tYXAoYXN5bmMgKHYpID0+IHYucm0oKSksXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0cmFja2VyLnZvbHVtZXMuY2xlYXIoKTtcbiAgICAgICAgICBhd2FpdCBwcm9taXNlcztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5jbHVkZURlZmF1bHRzKSB7XG4gICAgICAgICAgYnVpbGRMb2coJ1JlbW92aW5nIGRlZmF1bHQgZG9ja2VyIHZvbHVtZXMuLi4nKTtcbiAgICAgICAgICBjb25zdCB7IHZvbHVtZXMgfSA9IGF3YWl0IGRvY2tlckNvbXBvc2VSZXNvbHZlKGRvY2tlckNvbXBvc2UpO1xuICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgZW50cmllcyh2b2x1bWVzKS5tYXAoYXN5bmMgKFtrZXksIHZhbF0pID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgbmFtZSA9IHZhbD8ubmFtZSB8fCBwcmVmaXhOYW1lKGtleSk7XG4gICAgICAgICAgICAgIGF3YWl0IGRvY2tlclZvbHVtZVJtKG5hbWUsIHRydWUpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoaW5jbHVkZU5ldHdvcmtzKSB7XG4gICAgICAgIGlmICh0cmFja2VyLm5ldHdvcmtzLnNpemUpIHtcbiAgICAgICAgICBidWlsZExvZygnUmVtb3ZpbmcgY3JlYXRlZCBkb2NrZXIgbmV0d29ya3MuLi4nKTtcbiAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgQXJyYXkuZnJvbSh0cmFja2VyLm5ldHdvcmtzLnZhbHVlcygpKS5tYXAoYXN5bmMgKG4pID0+IG4ucm0oKSksXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0cmFja2VyLm5ldHdvcmtzLmNsZWFyKCk7XG4gICAgICAgICAgYXdhaXQgcHJvbWlzZXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGluY2x1ZGVEZWZhdWx0cykge1xuICAgICAgICAgIGJ1aWxkTG9nKCdSZW1vdmluZyBkZWZhdWx0IGRvY2tlciBuZXR3b3Jrcy4uLicpO1xuICAgICAgICAgIGNvbnN0IHsgbmV0d29ya3MgfSA9IGF3YWl0IGRvY2tlckNvbXBvc2VSZXNvbHZlKGRvY2tlckNvbXBvc2UpO1xuICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgZW50cmllcyhuZXR3b3JrcykubWFwKGFzeW5jIChba2V5LCB2YWxdKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IG5hbWUgPSB2YWw/Lm5hbWUgfHwgcHJlZml4TmFtZShrZXkpO1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IGRvY2tlck5ldHdvcmtEZWxldGUobmFtZSk7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGJ1aWxkTG9nKGBFcnJvciBkZWxldGluZyBuZXR3b3JrICcke25hbWV9JzogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICB0cmFja2VyLmNsZWFuaW5nID0gbnVsbDtcbiAgICB9KSgpO1xuICB9XG4gIHJldHVybiB0cmFja2VyLmNsZWFuaW5nO1xufVxuXG5leHBvcnQgdHlwZSBEb2NrZXJDb250YWluZXJJbmZvID0ge3xcbiAgLi4uVXBSZXN1bHQsXG4gIGlkOiBzdHJpbmcsXG4gIGltYWdlOiBzdHJpbmcsXG4gIG5hbWU/OiA/c3RyaW5nLFxuXG4gIC8vIGZvciBjb252ZW5pZW5jZSwgdGhlIGZpcnN0IHBvcnQgbWFwcGluZyBpbmZvXG4gIHBvcnQ/OiA/bnVtYmVyLFxuICBkb2NrZXJQb3J0PzogP251bWJlcixcbiAgdXJsPzogP3N0cmluZyxcbiAgZG9ja2VyVXJsPzogP3N0cmluZyxcbnx9O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9ja2VyQ29tcG9zZVJ1blNlcnZpY2UoXG4gIGtleTogc3RyaW5nLFxuICB1cE9wdGlvbnM/OiBVcE9wdGlvbnMgPSB7fSxcbiAgZG9ja2VyQ29tcG9zZT86ID8oc3RyaW5nIHwgRG9ja2VyQ29tcG9zZSksXG4pOiBQcm9taXNlPERvY2tlckNvbnRhaW5lckluZm8+IHtcbiAgY29uc3Qgc2VydmljZTogP0RvY2tlckNvbXBvc2VTZXJ2aWNlID0gYXdhaXQgRG9ja2VyQ29tcG9zZVNlcnZpY2UucGFyc2UoXG4gICAga2V5LFxuICAgIGZhbHNlLFxuICAgIGRvY2tlckNvbXBvc2UsXG4gICk7XG4gIGlmICghc2VydmljZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGZpbmQgc2VydmljZSAnJHtrZXl9J2ApO1xuICB9XG4gIGJ1aWxkTG9nKGBTdGFydGluZyA8JHtzZXJ2aWNlLm5hbWV9PiBzZXJ2aWNlLi4uYCk7XG4gIGNvbnN0IHVwUmVzdWx0OiBVcFJlc3VsdCA9IGF3YWl0IHNlcnZpY2UudXAodXBPcHRpb25zKTtcbiAgY29uc3Qge1xuICAgIGNvbnRhaW5lcixcbiAgICB1cmxzLFxuICAgIHVybHM6IFt7IGxvY2FsOiB1cmwsIGRvY2tlcjogZG9ja2VyVXJsIH1dLFxuICAgIHBvcnRzOiBbeyBsb2NhbDogcG9ydCwgZG9ja2VyOiBkb2NrZXJQb3J0IH1dLFxuICB9ID0gdXBSZXN1bHQ7XG4gIGNvbnN0IHsgaWQsIG5hbWUsIGltYWdlIH0gPSBjb250YWluZXI7XG4gIHVybHMuZm9yRWFjaChcbiAgICAoeyBsb2NhbCB9KSA9PlxuICAgICAgbG9jYWwgJiYgYnVpbGRMb2coYDwke3NlcnZpY2UubmFtZX0+IGFjY2Vzc2libGUgYXQgJHtsb2NhbH1gKSxcbiAgKTtcbiAgcmV0dXJuIHtcbiAgICAuLi51cFJlc3VsdCxcbiAgICBpZCxcbiAgICBpbWFnZSxcbiAgICBuYW1lLFxuICAgIHBvcnQsXG4gICAgZG9ja2VyUG9ydCxcbiAgICB1cmwsXG4gICAgZG9ja2VyVXJsLFxuICB9O1xufVxuIl19
|