build-strap 3.0.0-dev.40 → 4.0.0-dev.1
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 +35 -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/artifactory.js
DELETED
|
@@ -1,617 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.getArtifactoryConfig = getArtifactoryConfig;exports.artifactoryRequest = artifactoryRequest;exports.artifactoryPut = artifactoryPut;exports.artifactoryDelete = artifactoryDelete;exports.artifactoryNpm = artifactoryNpm;exports.artifactoryStandard = artifactoryStandard;exports.artifactoryCleanup = artifactoryCleanup;exports.getNpmArtifacts = getNpmArtifacts;exports.getLatestRepositoryVersion = getLatestRepositoryVersion;exports.parseVersionedFilePath = parseVersionedFilePath;exports.downloadRepositoryFile = downloadRepositoryFile;
|
|
2
|
-
var _path = _interopRequireDefault(require("path"));
|
|
3
|
-
var _fsExtra = _interopRequireDefault(require("fs-extra"));
|
|
4
|
-
var _requestPromiseNative = _interopRequireDefault(require("request-promise-native"));
|
|
5
|
-
var _request = _interopRequireDefault(require("request"));
|
|
6
|
-
var _moment = _interopRequireDefault(require("moment"));
|
|
7
|
-
var _urlJoin = _interopRequireDefault(require("url-join"));
|
|
8
|
-
var _os = require("os");
|
|
9
|
-
var _fs = require("./fs");
|
|
10
|
-
var _cp = require("./cp");
|
|
11
|
-
var _pkg = require("./pkg");
|
|
12
|
-
var _version = require("./version");
|
|
13
|
-
var _run = require("./run");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
function getArtifactoryConfig() {
|
|
45
|
-
return (0, _pkg.getCfg)().artifactory || {};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const envArtifactoryCreds = process.env.ARTIFACTORY_CREDS &&
|
|
49
|
-
JSON.parse(process.env.ARTIFACTORY_CREDS) || {
|
|
50
|
-
username: '',
|
|
51
|
-
password: '',
|
|
52
|
-
email: '' };
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// Properly insert credentials into request to artifactory api
|
|
56
|
-
async function artifactoryRequest(
|
|
57
|
-
requestOptions,
|
|
58
|
-
artifactoryCreds)
|
|
59
|
-
{
|
|
60
|
-
const creds = artifactoryCreds || envArtifactoryCreds;
|
|
61
|
-
return (0, _requestPromiseNative.default)(requestOptions).auth(creds.username, creds.password);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Send a file to artifactory by doing a http PUT to the given url(s), with the given credentials
|
|
65
|
-
// if artifactoryCreds are not provided, attempt to read from environment variable
|
|
66
|
-
async function artifactoryPut(
|
|
67
|
-
artifact,
|
|
68
|
-
url,
|
|
69
|
-
artifactInfo,
|
|
70
|
-
artifactoryCreds)
|
|
71
|
-
{
|
|
72
|
-
const stream =
|
|
73
|
-
typeof artifact === 'string' ? _fsExtra.default.createReadStream(artifact) : artifact;
|
|
74
|
-
const urls = typeof url === 'string' ? [url] : url;
|
|
75
|
-
|
|
76
|
-
return Promise.all(
|
|
77
|
-
urls.map((uri) =>
|
|
78
|
-
artifactoryRequest(
|
|
79
|
-
{
|
|
80
|
-
method: 'PUT',
|
|
81
|
-
uri,
|
|
82
|
-
body: stream,
|
|
83
|
-
headers: {
|
|
84
|
-
'content-type': artifactInfo.contentType || 'application/gzip',
|
|
85
|
-
'X-Checksum-Md5': artifactInfo.md5,
|
|
86
|
-
'X-Checksum-Sha1': artifactInfo.sha1,
|
|
87
|
-
'Content-Length': artifactInfo.size } },
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
artifactoryCreds).
|
|
91
|
-
then(() => {
|
|
92
|
-
(0, _run.buildLog)(`Successful PUT to ${uri}`);
|
|
93
|
-
return uri;
|
|
94
|
-
})));
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async function artifactoryDelete(
|
|
100
|
-
url,
|
|
101
|
-
artifactoryCreds,
|
|
102
|
-
dryRun = process.argv.includes('--dry-run'))
|
|
103
|
-
{
|
|
104
|
-
const urls = typeof url === 'string' ? [url] : url;
|
|
105
|
-
if (dryRun) {
|
|
106
|
-
(0, _run.buildLog)('Skipping delete due to --dry-run');
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return Promise.allSettled(
|
|
111
|
-
urls.map((uri) =>
|
|
112
|
-
artifactoryRequest(
|
|
113
|
-
{
|
|
114
|
-
method: 'DELETE',
|
|
115
|
-
uri },
|
|
116
|
-
|
|
117
|
-
artifactoryCreds).
|
|
118
|
-
then(
|
|
119
|
-
() => {
|
|
120
|
-
(0, _run.buildLog)(`Successful DELETE of ${uri}`);
|
|
121
|
-
return uri;
|
|
122
|
-
},
|
|
123
|
-
(err) => {
|
|
124
|
-
(0, _run.buildLog)(`Failed to DELETE ${uri}`);
|
|
125
|
-
throw err;
|
|
126
|
-
})));
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Invokes `npm publish` on the distDir, using the given credentials and artifactory config
|
|
133
|
-
// artifactory config can be provided as arg, or in the package.json file
|
|
134
|
-
async function artifactoryNpm(
|
|
135
|
-
distDir,
|
|
136
|
-
artifactoryConfig,
|
|
137
|
-
artifactoryCreds,
|
|
138
|
-
npmPath,
|
|
139
|
-
tag,
|
|
140
|
-
skipExisting = false)
|
|
141
|
-
{
|
|
142
|
-
const creds = artifactoryCreds || envArtifactoryCreds;
|
|
143
|
-
const { root: rt, npm } = artifactoryConfig || getArtifactoryConfig();
|
|
144
|
-
if (!rt || !npm) {
|
|
145
|
-
(0, _run.buildLog)(
|
|
146
|
-
'npm artifactoryConfig info missing from package.json, skipping npm publish');
|
|
147
|
-
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
const existing = await getNpmArtifacts(false, artifactoryConfig, creds);
|
|
151
|
-
const { isRelease, npm: npmVersion } = await (0, _version.getVersion)();
|
|
152
|
-
const regex = new RegExp(`${npmVersion}.tgz$`);
|
|
153
|
-
const exists = !!existing.find((c) => c.path.match(regex));
|
|
154
|
-
if (exists) {
|
|
155
|
-
if (skipExisting) {
|
|
156
|
-
(0, _run.buildLog)(
|
|
157
|
-
'npm module with this same version already exists in artifactory. Skipping publish...');
|
|
158
|
-
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
throw new Error(
|
|
162
|
-
'Failed to publish npm module, this version already exists in artifactory!');
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
// Write out .npmrc with credentials
|
|
166
|
-
await (0, _fs.writeFile)(
|
|
167
|
-
_path.default.join(distDir, '.npmrc'),
|
|
168
|
-
`registry=${rt}api/npm/${npm}
|
|
169
|
-
_auth=${Buffer.from(`${creds.username}:${creds.password}`).toString('base64')}
|
|
170
|
-
always-auth=true
|
|
171
|
-
email=${creds.email}`);
|
|
172
|
-
|
|
173
|
-
await (0, _cp.spawn)(
|
|
174
|
-
npmPath || ((0, _os.platform)() === 'win32' ? 'npm.cmd' : 'npm'),
|
|
175
|
-
['publish', '--tag', tag || (isRelease ? 'latest' : 'next')],
|
|
176
|
-
{
|
|
177
|
-
stdio: 'inherit',
|
|
178
|
-
cwd: distDir });
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return true;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
async function standardUrl(
|
|
185
|
-
fileName,
|
|
186
|
-
artifactoryConfig)
|
|
187
|
-
{
|
|
188
|
-
const {
|
|
189
|
-
root: rt,
|
|
190
|
-
release,
|
|
191
|
-
integration,
|
|
192
|
-
path: aPath,
|
|
193
|
-
'version-folders': versionFolders,
|
|
194
|
-
'integration-branch-folders': intBrFolders } =
|
|
195
|
-
artifactoryConfig || getArtifactoryConfig();
|
|
196
|
-
if (!rt || !release || !integration) {
|
|
197
|
-
return false;
|
|
198
|
-
}
|
|
199
|
-
const version = await (0, _version.getVersion)();
|
|
200
|
-
const artPath = aPath || (0, _pkg.getPkgName)();
|
|
201
|
-
const versDir = versionFolders ? `/${version.info}` : '';
|
|
202
|
-
if (version.isRelease) {
|
|
203
|
-
return `${rt}${release}/${artPath}${versDir}/${fileName}`;
|
|
204
|
-
}
|
|
205
|
-
const branch = intBrFolders ? `/${version.branch}` : '';
|
|
206
|
-
return `${rt}${integration}/${artPath}${branch}${versDir}/${fileName}`;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// Use the REST api to publish as a standard artifactory artifact
|
|
210
|
-
async function artifactoryStandard(
|
|
211
|
-
artifact,
|
|
212
|
-
artifactInfo,
|
|
213
|
-
fileName,
|
|
214
|
-
artifactoryConfig,
|
|
215
|
-
artifactoryCreds)
|
|
216
|
-
{
|
|
217
|
-
const url = await standardUrl(fileName, artifactoryConfig);
|
|
218
|
-
if (!url) {
|
|
219
|
-
(0, _run.buildLog)(
|
|
220
|
-
'release/integration artifactoryConfig info missing from package.json, skipping publish');
|
|
221
|
-
|
|
222
|
-
return false;
|
|
223
|
-
}
|
|
224
|
-
await artifactoryPut(artifact, url, artifactInfo, artifactoryCreds);
|
|
225
|
-
return true;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const getRemoteArtifactInfo = async (
|
|
229
|
-
rootUri,
|
|
230
|
-
repo,
|
|
231
|
-
subPath,
|
|
232
|
-
artifactoryCreds) =>
|
|
233
|
-
|
|
234
|
-
artifactoryRequest(
|
|
235
|
-
{
|
|
236
|
-
method: 'GET',
|
|
237
|
-
uri: `${rootUri}/api/storage/${repo}/${subPath}`,
|
|
238
|
-
json: true },
|
|
239
|
-
|
|
240
|
-
artifactoryCreds);
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const getRemoteArtifactChildrenInfo = async (
|
|
244
|
-
info,
|
|
245
|
-
rootUri,
|
|
246
|
-
repo,
|
|
247
|
-
subPath,
|
|
248
|
-
artifactoryCreds) =>
|
|
249
|
-
|
|
250
|
-
Promise.all(
|
|
251
|
-
info.children.map(async (c) =>
|
|
252
|
-
getRemoteArtifactInfo(
|
|
253
|
-
rootUri,
|
|
254
|
-
repo,
|
|
255
|
-
`${subPath}${c.uri}`,
|
|
256
|
-
artifactoryCreds)));
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
async function cleanChildren({
|
|
273
|
-
rootUri,
|
|
274
|
-
repo,
|
|
275
|
-
subPath,
|
|
276
|
-
daysToKeep = 14,
|
|
277
|
-
maxToKeep = 10,
|
|
278
|
-
keepFilter,
|
|
279
|
-
artifactoryCreds,
|
|
280
|
-
ignoreErrors = true } =
|
|
281
|
-
{}) {
|
|
282
|
-
const info = await getRemoteArtifactInfo(
|
|
283
|
-
rootUri,
|
|
284
|
-
repo,
|
|
285
|
-
subPath,
|
|
286
|
-
artifactoryCreds);
|
|
287
|
-
|
|
288
|
-
const children = await getRemoteArtifactChildrenInfo(
|
|
289
|
-
info,
|
|
290
|
-
rootUri,
|
|
291
|
-
repo,
|
|
292
|
-
subPath,
|
|
293
|
-
artifactoryCreds);
|
|
294
|
-
|
|
295
|
-
// Filter out children that we absolutely will not delete
|
|
296
|
-
const integrationChildren = keepFilter ?
|
|
297
|
-
children.filter((c) => !keepFilter(c)) :
|
|
298
|
-
children;
|
|
299
|
-
|
|
300
|
-
// Determine which integration artifacts to keep (they are recent and not too numerous)
|
|
301
|
-
const timeThreshold = daysToKeep ?
|
|
302
|
-
(0, _moment.default)().subtract(daysToKeep, 'days') :
|
|
303
|
-
null;
|
|
304
|
-
const filtered = timeThreshold ?
|
|
305
|
-
integrationChildren.filter((c) =>
|
|
306
|
-
(0, _moment.default)(c.lastModified).isAfter(timeThreshold)) :
|
|
307
|
-
|
|
308
|
-
integrationChildren;
|
|
309
|
-
const limited = maxToKeep ?
|
|
310
|
-
filtered.
|
|
311
|
-
sort((a, b) => {
|
|
312
|
-
const tA = (0, _moment.default)(a.lastModified);
|
|
313
|
-
const tB = (0, _moment.default)(b.lastModified);
|
|
314
|
-
if (tA.isBefore(tB)) {
|
|
315
|
-
return -1;
|
|
316
|
-
}
|
|
317
|
-
if (tA.isAfter(tB)) {
|
|
318
|
-
return 1;
|
|
319
|
-
}
|
|
320
|
-
return 0;
|
|
321
|
-
}).
|
|
322
|
-
slice(-maxToKeep) :
|
|
323
|
-
filtered;
|
|
324
|
-
|
|
325
|
-
// Delete any integration artifacts that didn't make the limited list
|
|
326
|
-
const results = await Promise.allSettled(
|
|
327
|
-
integrationChildren.
|
|
328
|
-
filter((c) => limited.indexOf(c) < 0).
|
|
329
|
-
map(async (c) => {
|
|
330
|
-
(0, _run.buildLog)(`Deleting artifact: ${c.repo}${c.path}`);
|
|
331
|
-
return artifactoryDelete(
|
|
332
|
-
`${rootUri}/${c.repo}/${c.path}`,
|
|
333
|
-
artifactoryCreds);
|
|
334
|
-
|
|
335
|
-
}));
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
if (!ignoreErrors && results.some((r) => r.status === 'rejected')) {
|
|
339
|
-
throw new Error('Some artifacts were not deleted.');
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
return results;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
async function cleanBranchFolders({
|
|
357
|
-
rootUri,
|
|
358
|
-
repo,
|
|
359
|
-
subPath,
|
|
360
|
-
daysToKeep,
|
|
361
|
-
maxToKeep,
|
|
362
|
-
keepFilter,
|
|
363
|
-
artifactoryCreds,
|
|
364
|
-
ignoreErrors = true } =
|
|
365
|
-
{}) {
|
|
366
|
-
const info = await getRemoteArtifactInfo(
|
|
367
|
-
rootUri,
|
|
368
|
-
repo,
|
|
369
|
-
subPath,
|
|
370
|
-
artifactoryCreds);
|
|
371
|
-
|
|
372
|
-
const children = await getRemoteArtifactChildrenInfo(
|
|
373
|
-
info,
|
|
374
|
-
rootUri,
|
|
375
|
-
repo,
|
|
376
|
-
subPath,
|
|
377
|
-
artifactoryCreds);
|
|
378
|
-
|
|
379
|
-
const results = await Promise.allSettled(
|
|
380
|
-
children.map(async (c) => {
|
|
381
|
-
const [branch] = c.path.split('/').slice(-1);
|
|
382
|
-
if (branch === (0, _version.getReleaseBranch)()) {
|
|
383
|
-
(0, _run.buildLog)(
|
|
384
|
-
`Skipping cleanup of release branch: ${repo}/${subPath}/${branch}`);
|
|
385
|
-
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
(0, _run.buildLog)(`Cleaning integration branch: ${repo}/${subPath}/${branch}`);
|
|
389
|
-
await cleanChildren({
|
|
390
|
-
rootUri,
|
|
391
|
-
repo: c.repo,
|
|
392
|
-
subPath: c.path,
|
|
393
|
-
daysToKeep,
|
|
394
|
-
maxToKeep,
|
|
395
|
-
keepFilter,
|
|
396
|
-
artifactoryCreds });
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
// if branch folder is now empty, delete it
|
|
400
|
-
const cInfo = await getRemoteArtifactInfo(
|
|
401
|
-
rootUri,
|
|
402
|
-
c.repo,
|
|
403
|
-
c.path,
|
|
404
|
-
artifactoryCreds);
|
|
405
|
-
|
|
406
|
-
if (cInfo.children.length === 0) {
|
|
407
|
-
(0, _run.buildLog)(`Deleting empty branch folder: ${c.repo}/${c.path}`);
|
|
408
|
-
await artifactoryDelete(
|
|
409
|
-
`${rootUri}/${c.repo}/${c.path}`,
|
|
410
|
-
artifactoryCreds);
|
|
411
|
-
|
|
412
|
-
}
|
|
413
|
-
}));
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
if (!ignoreErrors && results.some((r) => r.status === 'rejected')) {
|
|
417
|
-
throw new Error('Some artifacts were not deleted.');
|
|
418
|
-
}
|
|
419
|
-
return results;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
async function artifactoryCleanup(
|
|
423
|
-
daysToKeep,
|
|
424
|
-
maxToKeep,
|
|
425
|
-
artifactoryConfig,
|
|
426
|
-
artifactoryCreds)
|
|
427
|
-
{
|
|
428
|
-
const {
|
|
429
|
-
root: rt,
|
|
430
|
-
'integration-days-to-keep': intDaysKeep,
|
|
431
|
-
'integration-max-to-keep': intMaxKeep,
|
|
432
|
-
integration,
|
|
433
|
-
path: aPath,
|
|
434
|
-
'integration-branch-folders': intBranchFolders,
|
|
435
|
-
'npm-clean': npmClean } =
|
|
436
|
-
artifactoryConfig || getArtifactoryConfig();
|
|
437
|
-
if (!rt) {
|
|
438
|
-
(0, _run.buildLog)(
|
|
439
|
-
'artifactory info missing from package.json, skipping artifactory cleanup');
|
|
440
|
-
|
|
441
|
-
return false;
|
|
442
|
-
}
|
|
443
|
-
const dToK = daysToKeep == null ? intDaysKeep : daysToKeep;
|
|
444
|
-
const mToK = maxToKeep == null ? intMaxKeep : maxToKeep;
|
|
445
|
-
|
|
446
|
-
if (integration) {
|
|
447
|
-
// Clean up integration repo artifacts
|
|
448
|
-
const artPath = aPath || (0, _pkg.getPkgName)();
|
|
449
|
-
if (intBranchFolders) {
|
|
450
|
-
await cleanBranchFolders({
|
|
451
|
-
rootUri: rt,
|
|
452
|
-
repo: integration,
|
|
453
|
-
subPath: artPath,
|
|
454
|
-
daysToKeep: dToK,
|
|
455
|
-
maxToKeep: mToK,
|
|
456
|
-
artifactoryCreds });
|
|
457
|
-
|
|
458
|
-
} else {
|
|
459
|
-
await cleanChildren({
|
|
460
|
-
rootUri: rt,
|
|
461
|
-
repo: integration,
|
|
462
|
-
subPath: artPath,
|
|
463
|
-
daysToKeep: dToK,
|
|
464
|
-
maxToKeep: mToK,
|
|
465
|
-
artifactoryCreds });
|
|
466
|
-
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
if (npmClean) {
|
|
471
|
-
// Clean up npm integration artifacts
|
|
472
|
-
const name = (0, _pkg.getPkgName)(false);
|
|
473
|
-
const scope = (0, _pkg.getPkgScope)();
|
|
474
|
-
const releaseRegex = new RegExp(`${name}-\\d+\\.\\d+\\.\\d+\\.tgz`, 'i');
|
|
475
|
-
await cleanChildren({
|
|
476
|
-
rootUri: rt,
|
|
477
|
-
repo: npmClean,
|
|
478
|
-
subPath: scope ? `${scope}/${name}/-/${scope}` : `${name}/-`,
|
|
479
|
-
daysToKeep: dToK,
|
|
480
|
-
maxToKeep: mToK,
|
|
481
|
-
keepFilter: (c) => !!c.path.match(releaseRegex),
|
|
482
|
-
artifactoryCreds });
|
|
483
|
-
|
|
484
|
-
}
|
|
485
|
-
return true;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
function uniqBy(a, key) {
|
|
489
|
-
const seen = new Set();
|
|
490
|
-
return a.filter((item) => {
|
|
491
|
-
const k = key(item);
|
|
492
|
-
return seen.has(k) ? false : seen.add(k);
|
|
493
|
-
});
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
async function getNpmArtifacts(
|
|
497
|
-
releasedOnly = false,
|
|
498
|
-
artifactoryConfig,
|
|
499
|
-
artifactoryCreds)
|
|
500
|
-
{
|
|
501
|
-
const { root: rt, npm } = artifactoryConfig || getArtifactoryConfig();
|
|
502
|
-
if (!rt || !npm) {
|
|
503
|
-
throw new Error('artifactoryConfig info missing from package.json');
|
|
504
|
-
}
|
|
505
|
-
const name = (0, _pkg.getPkgName)(false);
|
|
506
|
-
const scope = (0, _pkg.getPkgScope)();
|
|
507
|
-
const npmPath = scope ? `${scope}/${name}/-/${scope}` : `${name}/-`;
|
|
508
|
-
const releaseRegex = new RegExp(`${name}-\\d+\\.\\d+\\.\\d+\\.tgz`, 'i');
|
|
509
|
-
try {
|
|
510
|
-
const info = await getRemoteArtifactInfo(
|
|
511
|
-
rt,
|
|
512
|
-
npm,
|
|
513
|
-
npmPath,
|
|
514
|
-
artifactoryCreds);
|
|
515
|
-
|
|
516
|
-
const children = uniqBy(
|
|
517
|
-
await getRemoteArtifactChildrenInfo(
|
|
518
|
-
info,
|
|
519
|
-
rt,
|
|
520
|
-
npm,
|
|
521
|
-
npmPath,
|
|
522
|
-
artifactoryCreds),
|
|
523
|
-
|
|
524
|
-
(c) => c.uri);
|
|
525
|
-
|
|
526
|
-
return releasedOnly ?
|
|
527
|
-
// $FlowFixMe
|
|
528
|
-
children.filter((c) => !!c.path.match(releaseRegex)) :
|
|
529
|
-
children;
|
|
530
|
-
} catch (err) {
|
|
531
|
-
if (err.statusCode === 404) return [];
|
|
532
|
-
throw err;
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
async function getLatestRepositoryVersion(
|
|
537
|
-
repositoryPath,
|
|
538
|
-
artifactoryCreds)
|
|
539
|
-
{
|
|
540
|
-
const { root: rt } = getArtifactoryConfig();
|
|
541
|
-
if (!rt) {
|
|
542
|
-
throw new Error('artifactoryConfig info missing from package.json');
|
|
543
|
-
}
|
|
544
|
-
// get latest version number for the key
|
|
545
|
-
const lastModifiedFileInfo = await artifactoryRequest(
|
|
546
|
-
{
|
|
547
|
-
method: 'GET',
|
|
548
|
-
uri: (0, _urlJoin.default)(rt, `/api/storage/${repositoryPath}?lastModified`) },
|
|
549
|
-
|
|
550
|
-
artifactoryCreds);
|
|
551
|
-
|
|
552
|
-
const { uri } = JSON.parse(lastModifiedFileInfo);
|
|
553
|
-
const versionStartIndex = uri.indexOf(repositoryPath) + repositoryPath.length;
|
|
554
|
-
const versionEndIndex = uri.indexOf('/', versionStartIndex + 1);
|
|
555
|
-
const versionNumber = uri.substring(versionStartIndex + 1, versionEndIndex);
|
|
556
|
-
return versionNumber;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
async function parseVersionedFilePath(
|
|
560
|
-
repositoryPath,
|
|
561
|
-
filePath,
|
|
562
|
-
artifactoryCreds)
|
|
563
|
-
{
|
|
564
|
-
// eslint-disable-next-line
|
|
565
|
-
if (filePath.indexOf('{{version}}') > -1) {
|
|
566
|
-
const version = await getLatestRepositoryVersion(
|
|
567
|
-
repositoryPath,
|
|
568
|
-
artifactoryCreds);
|
|
569
|
-
|
|
570
|
-
return filePath.replace(/{{version}}/g, version);
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
return filePath;
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
/**
|
|
577
|
-
* Download a given file from a repository hosted in Artifactory
|
|
578
|
-
* @param {string} repositoryPath
|
|
579
|
-
* The path to the repository root relative to the configured artifactory root
|
|
580
|
-
* @param {string} filePath
|
|
581
|
-
* The path to the file from the repository root. If the latest version of the
|
|
582
|
-
* file is desired a tokenized string can be passed using {{version}} to indicate
|
|
583
|
-
* segments to replaced by the latest version string.
|
|
584
|
-
* ex: {{version}}/path/file-name-${{version}}.js
|
|
585
|
-
* @param {string} saveAs
|
|
586
|
-
* The local file path to save the downloaded file to.
|
|
587
|
-
* @param {ArtifactoryCreds} artifactoryCreds
|
|
588
|
-
*/
|
|
589
|
-
async function downloadRepositoryFile(
|
|
590
|
-
repositoryPath,
|
|
591
|
-
filePath,
|
|
592
|
-
saveAs,
|
|
593
|
-
artifactoryCreds)
|
|
594
|
-
{
|
|
595
|
-
const { root: rt } = getArtifactoryConfig();
|
|
596
|
-
if (!rt) {
|
|
597
|
-
throw new Error('artifactoryConfig info missing from package.json');
|
|
598
|
-
}
|
|
599
|
-
const fileUri = (0, _urlJoin.default)(
|
|
600
|
-
rt,
|
|
601
|
-
repositoryPath,
|
|
602
|
-
await parseVersionedFilePath(repositoryPath, filePath, artifactoryCreds));
|
|
603
|
-
|
|
604
|
-
(0, _run.buildLog)(`Downloading file from Artifactory: ${fileUri}`);
|
|
605
|
-
const fileStream = _fsExtra.default.createWriteStream(saveAs);
|
|
606
|
-
return new Promise((resolve, reject) => {
|
|
607
|
-
(0, _request.default)(fileUri, (error, response) => {
|
|
608
|
-
if (error) {
|
|
609
|
-
(0, _run.buildLog)(`Error downloading ${fileUri}: ${JSON.stringify(error)}`);
|
|
610
|
-
reject(error);
|
|
611
|
-
} else {
|
|
612
|
-
resolve(response);
|
|
613
|
-
}
|
|
614
|
-
}).pipe(fileStream);
|
|
615
|
-
});
|
|
616
|
-
}
|
|
617
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9hcnRpZmFjdG9yeS5qcyJdLCJuYW1lcyI6WyJnZXRBcnRpZmFjdG9yeUNvbmZpZyIsImFydGlmYWN0b3J5IiwiZW52QXJ0aWZhY3RvcnlDcmVkcyIsInByb2Nlc3MiLCJlbnYiLCJBUlRJRkFDVE9SWV9DUkVEUyIsIkpTT04iLCJwYXJzZSIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJlbWFpbCIsImFydGlmYWN0b3J5UmVxdWVzdCIsInJlcXVlc3RPcHRpb25zIiwiYXJ0aWZhY3RvcnlDcmVkcyIsImNyZWRzIiwiYXV0aCIsImFydGlmYWN0b3J5UHV0IiwiYXJ0aWZhY3QiLCJ1cmwiLCJhcnRpZmFjdEluZm8iLCJzdHJlYW0iLCJmcyIsImNyZWF0ZVJlYWRTdHJlYW0iLCJ1cmxzIiwiUHJvbWlzZSIsImFsbCIsIm1hcCIsInVyaSIsIm1ldGhvZCIsImJvZHkiLCJoZWFkZXJzIiwiY29udGVudFR5cGUiLCJtZDUiLCJzaGExIiwic2l6ZSIsInRoZW4iLCJhcnRpZmFjdG9yeURlbGV0ZSIsImRyeVJ1biIsImFyZ3YiLCJpbmNsdWRlcyIsImFsbFNldHRsZWQiLCJlcnIiLCJhcnRpZmFjdG9yeU5wbSIsImRpc3REaXIiLCJhcnRpZmFjdG9yeUNvbmZpZyIsIm5wbVBhdGgiLCJ0YWciLCJza2lwRXhpc3RpbmciLCJyb290IiwicnQiLCJucG0iLCJleGlzdGluZyIsImdldE5wbUFydGlmYWN0cyIsImlzUmVsZWFzZSIsIm5wbVZlcnNpb24iLCJyZWdleCIsIlJlZ0V4cCIsImV4aXN0cyIsImZpbmQiLCJjIiwicGF0aCIsIm1hdGNoIiwiRXJyb3IiLCJqb2luIiwiQnVmZmVyIiwiZnJvbSIsInRvU3RyaW5nIiwic3RkaW8iLCJjd2QiLCJzdGFuZGFyZFVybCIsImZpbGVOYW1lIiwicmVsZWFzZSIsImludGVncmF0aW9uIiwiYVBhdGgiLCJ2ZXJzaW9uRm9sZGVycyIsImludEJyRm9sZGVycyIsInZlcnNpb24iLCJhcnRQYXRoIiwidmVyc0RpciIsImluZm8iLCJicmFuY2giLCJhcnRpZmFjdG9yeVN0YW5kYXJkIiwiZ2V0UmVtb3RlQXJ0aWZhY3RJbmZvIiwicm9vdFVyaSIsInJlcG8iLCJzdWJQYXRoIiwianNvbiIsImdldFJlbW90ZUFydGlmYWN0Q2hpbGRyZW5JbmZvIiwiY2hpbGRyZW4iLCJjbGVhbkNoaWxkcmVuIiwiZGF5c1RvS2VlcCIsIm1heFRvS2VlcCIsImtlZXBGaWx0ZXIiLCJpZ25vcmVFcnJvcnMiLCJpbnRlZ3JhdGlvbkNoaWxkcmVuIiwiZmlsdGVyIiwidGltZVRocmVzaG9sZCIsInN1YnRyYWN0IiwiZmlsdGVyZWQiLCJsYXN0TW9kaWZpZWQiLCJpc0FmdGVyIiwibGltaXRlZCIsInNvcnQiLCJhIiwiYiIsInRBIiwidEIiLCJpc0JlZm9yZSIsInNsaWNlIiwicmVzdWx0cyIsImluZGV4T2YiLCJzb21lIiwiciIsInN0YXR1cyIsImNsZWFuQnJhbmNoRm9sZGVycyIsInNwbGl0IiwiY0luZm8iLCJsZW5ndGgiLCJhcnRpZmFjdG9yeUNsZWFudXAiLCJpbnREYXlzS2VlcCIsImludE1heEtlZXAiLCJpbnRCcmFuY2hGb2xkZXJzIiwibnBtQ2xlYW4iLCJkVG9LIiwibVRvSyIsIm5hbWUiLCJzY29wZSIsInJlbGVhc2VSZWdleCIsInVuaXFCeSIsImtleSIsInNlZW4iLCJTZXQiLCJpdGVtIiwiayIsImhhcyIsImFkZCIsInJlbGVhc2VkT25seSIsInN0YXR1c0NvZGUiLCJnZXRMYXRlc3RSZXBvc2l0b3J5VmVyc2lvbiIsInJlcG9zaXRvcnlQYXRoIiwibGFzdE1vZGlmaWVkRmlsZUluZm8iLCJ2ZXJzaW9uU3RhcnRJbmRleCIsInZlcnNpb25FbmRJbmRleCIsInZlcnNpb25OdW1iZXIiLCJzdWJzdHJpbmciLCJwYXJzZVZlcnNpb25lZEZpbGVQYXRoIiwiZmlsZVBhdGgiLCJyZXBsYWNlIiwiZG93bmxvYWRSZXBvc2l0b3J5RmlsZSIsInNhdmVBcyIsImZpbGVVcmkiLCJmaWxlU3RyZWFtIiwiY3JlYXRlV3JpdGVTdHJlYW0iLCJy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ckksZ0JBQTNCLENBSGQsQ0FBaEI7O0FBS0EscUJBQVUsc0NBQXFDeUksT0FBUSxFQUF2RDtBQUNBLFFBQU1DLFVBQVUsR0FBR2xJLGlCQUFHbUksaUJBQUgsQ0FBcUJILE1BQXJCLENBQW5CO0FBQ0EsU0FBTyxJQUFJN0gsT0FBSixDQUFZLENBQUNpSSxPQUFELEVBQVVDLE1BQVYsS0FBcUI7QUFDdEMsMEJBQVFKLE9BQVIsRUFBaUIsQ0FBQ0ssS0FBRCxFQUFRQyxRQUFSLEtBQXFCO0FBQ3BDLFVBQUlELEtBQUosRUFBVztBQUNULDJCQUFVLHFCQUFvQkwsT0FBUSxLQUFJaEosSUFBSSxDQUFDdUosU0FBTCxDQUFlRixLQUFmLENBQXNCLEVBQWhFO0FBQ0FELFFBQUFBLE1BQU0sQ0FBQ0MsS0FBRCxDQUFOO0FBQ0QsT0FIRCxNQUdPO0FBQ0xGLFFBQUFBLE9BQU8sQ0FBQ0csUUFBRCxDQUFQO0FBQ0Q7QUFDRixLQVBELEVBT0dFLElBUEgsQ0FPUVAsVUFQUjtBQVFELEdBVE0sQ0FBUDtBQVVEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCBycCBmcm9tICdyZXF1ZXN0LXByb21pc2UtbmF0aXZlJztcbmltcG9ydCByZXF1ZXN0IGZyb20gJ3JlcXVlc3QnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHVybEpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IHsgcGxhdGZvcm0gfSBmcm9tICdvcyc7XG5pbXBvcnQgeyB3cml0ZUZpbGUgfSBmcm9tICcuL2ZzJztcbmltcG9ydCB7IHNwYXduIH0gZnJvbSAnLi9jcCc7XG5pbXBvcnQgeyBnZXRDZmcsIGdldFBrZ05hbWUsIGdldFBrZ1Njb3BlIH0gZnJvbSAnLi9wa2cnO1xuaW1wb3J0IHsgZ2V0VmVyc2lvbiwgZ2V0UmVsZWFzZUJyYW5jaCB9IGZyb20gJy4vdmVyc2lvbic7XG5pbXBvcnQgeyBidWlsZExvZyB9IGZyb20gJy4vcnVuJztcbmltcG9ydCB7IHR5cGUgQXJ0aWZhY3RJbmZvIH0gZnJvbSAnLi90Z3onO1xuXG5leHBvcnQgdHlwZSBBcnRpZmFjdG9yeUNyZWRzID0ge1xuICB1c2VybmFtZTogc3RyaW5nLFxuICBwYXNzd29yZDogc3RyaW5nLFxuICBlbWFpbDogc3RyaW5nLFxufTtcblxuZXhwb3J0IHR5cGUgUmVtb3RlQXJ0aWZhY3RJbmZvID0ge1xuICB1cmk6IHN0cmluZyxcbiAgbGFzdE1vZGlmaWVkOiBzdHJpbmcsXG4gIHJlcG86IHN0cmluZyxcbiAgcGF0aDogc3RyaW5nLFxuICBjaGlsZHJlbjogUmVtb3RlQXJ0aWZhY3RJbmZvW10sXG59O1xuXG5leHBvcnQgdHlwZSBBcnRpZmFjdG9yeUNvbmZpZyA9IHtcbiAgcm9vdD86IHN0cmluZyxcbiAgcGF0aD86IHN0cmluZyxcbiAgJ3ZlcnNpb24tZm9sZGVycyc/OiBib29sZWFuLFxuICByZWxlYXNlPzogc3RyaW5nLFxuICAncmVsZWFzZS1icmFuY2gnPzogc3RyaW5nLFxuICBpbnRlZ3JhdGlvbj86IHN0cmluZyxcbiAgJ2ludGVncmF0aW9uLWJyYW5jaC1mb2xkZXJzJz86IGJvb2xlYW4sXG4gICdpbnRlZ3JhdGlvbi1kYXlzLXRvLWtlZXAnPzogbnVtYmVyLFxuICAnaW50ZWdyYXRpb24tbWF4LXRvLWtlZXAnPzogbnVtYmVyLFxuICBucG0/OiBzdHJpbmcsXG4gICducG0tY2xlYW4nPzogc3RyaW5nLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFydGlmYWN0b3J5Q29uZmlnKCk6IEFydGlmYWN0b3J5Q29uZmlnIHtcbiAgcmV0dXJuIGdldENmZygpLmFydGlmYWN0b3J5IHx8IHt9O1xufVxuXG5jb25zdCBlbnZBcnRpZmFjdG9yeUNyZWRzOiBBcnRpZmFjdG9yeUNyZWRzID0gKHByb2Nlc3MuZW52LkFSVElGQUNUT1JZX0NSRURTICYmXG4gIEpTT04ucGFyc2UocHJvY2Vzcy5lbnYuQVJUSUZBQ1RPUllfQ1JFRFMpKSB8fCB7XG4gIHVzZXJuYW1lOiAnJyxcbiAgcGFzc3dvcmQ6ICcnLFxuICBlbWFpbDogJycsXG59O1xuXG4vLyBQcm9wZXJseSBpbnNlcnQgY3JlZGVudGlhbHMgaW50byByZXF1ZXN0IHRvIGFydGlmYWN0b3J5IGFwaVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFydGlmYWN0b3J5UmVxdWVzdChcbiAgcmVxdWVzdE9wdGlvbnM6IGFueSxcbiAgYXJ0aWZhY3RvcnlDcmVkcz86IEFydGlmYWN0b3J5Q3JlZHMsXG4pOiBQcm9taXNlPGFueT4ge1xuICBjb25zdCBjcmVkcyA9IGFydGlmYWN0b3J5Q3JlZHMgfHwgZW52QXJ0aWZhY3RvcnlDcmVkcztcbiAgcmV0dXJuIHJwKHJlcXVlc3RPcHRpb25zKS5hdXRoKGNyZWRzLnVzZXJuYW1lLCBjcmVkcy5wYXNzd29yZCk7XG59XG5cbi8vIFNlbmQgYSBmaWxlIHRvIGFydGlmYWN0b3J5IGJ5IGRvaW5nIGEgaHR0cCBQVVQgdG8gdGhlIGdpdmVuIHVybChzKSwgd2l0aCB0aGUgZ2l2ZW4gY3JlZGVudGlhbHNcbi8vIGlmIGFydGlmYWN0b3J5Q3JlZHMgYXJlIG5vdCBwcm92aWRlZCwgYXR0ZW1wdCB0byByZWFkIGZyb20gZW52aXJvbm1lbnQgdmFyaWFibGVcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhcnRpZmFjdG9yeVB1dChcbiAgYXJ0aWZhY3Q6IHN0cmluZyB8IHN0cmVhbSRSZWFkYWJsZSxcbiAgdXJsOiBzdHJpbmcgfCBzdHJpbmdbXSxcbiAgYXJ0aWZhY3RJbmZvOiBBcnRpZmFjdEluZm8sXG4gIGFydGlmYWN0b3J5Q3JlZHM/OiBBcnRpZmFjdG9yeUNyZWRzLFxuKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICBjb25zdCBzdHJlYW06IHN0cmVhbSRSZWFkYWJsZSA9XG4gICAgdHlwZW9mIGFydGlmYWN0ID09PSAnc3RyaW5nJyA/IGZzLmNyZWF0ZVJlYWRTdHJlYW0oYXJ0aWZhY3QpIDogYXJ0aWZhY3Q7XG4gIGNvbnN0IHVybHMgPSB0eXBlb2YgdXJsID09PSAnc3RyaW5nJyA/IFt1cmxdIDogdXJsO1xuXG4gIHJldHVybiBQcm9taXNlLmFsbChcbiAgICB1cmxzLm1hcCgodXJpKSA9PlxuICAgICAgYXJ0aWZhY3RvcnlSZXF1ZXN0KFxuICAgICAgICB7XG4gICAgICAgICAgbWV0aG9kOiAnUFVUJyxcbiAgICAgICAgICB1cmksXG4gICAgICAgICAgYm9keTogc3RyZWFtLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiBhcnRpZmFjdEluZm8uY29udGVudFR5cGUgfHwgJ2FwcGxpY2F0aW9uL2d6aXAnLFxuICAgICAgICAgICAgJ1gtQ2hlY2tzdW0tTWQ1JzogYXJ0aWZhY3RJbmZvLm1kNSxcbiAgICAgICAgICAgICdYLUNoZWNrc3VtLVNoYTEnOiBhcnRpZmFjdEluZm8uc2hhMSxcbiAgICAgICAgICAgICdDb250ZW50LUxlbmd0aCc6IGFydGlmYWN0SW5mby5zaXplLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFydGlmYWN0b3J5Q3JlZHMsXG4gICAgICApLnRoZW4oKCkgPT4ge1xuICAgICAgICBidWlsZExvZyhgU3VjY2Vzc2Z1bCBQVVQgdG8gJHt1cml9YCk7XG4gICAgICAgIHJldHVybiB1cmk7XG4gICAgICB9KSxcbiAgICApLFxuICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXJ0aWZhY3RvcnlEZWxldGUoXG4gIHVybDogc3RyaW5nIHwgc3RyaW5nW10sXG4gIGFydGlmYWN0b3J5Q3JlZHM/OiBBcnRpZmFjdG9yeUNyZWRzLFxuICBkcnlSdW46IGJvb2xlYW4gPSBwcm9jZXNzLmFyZ3YuaW5jbHVkZXMoJy0tZHJ5LXJ1bicpLFxuKTogUHJvbWlzZTw/KCRTZXR0bGVkUHJvbWlzZVJlc3VsdDxzdHJpbmc+W10pPiB7XG4gIGNvbnN0IHVybHMgPSB0eXBlb2YgdXJsID09PSAnc3RyaW5nJyA/IFt1cmxdIDogdXJsO1xuICBpZiAoZHJ5UnVuKSB7XG4gICAgYnVpbGRMb2coJ1NraXBwaW5nIGRlbGV0ZSBkdWUgdG8gLS1kcnktcnVuJyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gUHJvbWlzZS5hbGxTZXR0bGVkKFxuICAgIHVybHMubWFwKCh1cmkpID0+XG4gICAgICBhcnRpZmFjdG9yeVJlcXVlc3QoXG4gICAgICAgIHtcbiAgICAgICAgICBtZXRob2Q6ICdERUxFVEUnLFxuICAgICAgICAgIHVyaSxcbiAgICAgICAgfSxcbiAgICAgICAgYXJ0aWZhY3RvcnlDcmVkcyxcbiAgICAgICkudGhlbihcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGJ1aWxkTG9nKGBTdWNjZXNzZnVsIERFTEVURSBvZiAke3VyaX1gKTtcbiAgICAgICAgICByZXR1cm4gdXJpO1xuICAgICAgICB9LFxuICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgYnVpbGRMb2coYEZhaWxlZCB0byBERUxFVEUgJHt1cml9YCk7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9LFxuICAgICAgKSxcbiAgICApLFxuICApO1xufVxuXG4vLyBJbnZva2VzIGBucG0gcHVibGlzaGAgb24gdGhlIGRpc3REaXIsIHVzaW5nIHRoZSBnaXZlbiBjcmVkZW50aWFscyBhbmQgYXJ0aWZhY3RvcnkgY29uZmlnXG4vLyBhcnRpZmFjdG9yeSBjb25maWcgY2FuIGJlIHByb3ZpZGVkIGFzIGFyZywgb3IgaW4gdGhlIHBhY2thZ2UuanNvbiBmaWxlXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXJ0aWZhY3RvcnlOcG0oXG4gIGRpc3REaXI6IHN0cmluZyxcbiAgYXJ0aWZhY3RvcnlDb25maWc/OiBBcnRpZmFjdG9yeUNvbmZpZyxcbiAgYXJ0aWZhY3RvcnlDcmVkcz86IEFydGlmYWN0b3J5Q3JlZHMsXG4gIG5wbVBhdGg/OiBzdHJpbmcsXG4gIHRhZz86IHN0cmluZyxcbiAgc2tpcEV4aXN0aW5nOiBib29sZWFuID0gZmFsc2UsXG4pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgY3JlZHMgPSBhcnRpZmFjdG9yeUNyZWRzIHx8IGVudkFydGlmYWN0b3J5Q3JlZHM7XG4gIGNvbnN0IHsgcm9vdDogcnQsIG5wbSB9ID0gYXJ0aWZhY3RvcnlDb25maWcgfHwgZ2V0QXJ0aWZhY3RvcnlDb25maWcoKTtcbiAgaWYgKCFydCB8fCAhbnBtKSB7XG4gICAgYnVpbGRMb2coXG4gICAgICAnbnBtIGFydGlmYWN0b3J5Q29uZmlnIGluZm8gbWlzc2luZyBmcm9tIHBhY2thZ2UuanNvbiwgc2tpcHBpbmcgbnBtIHB1Ymxpc2gnLFxuICAgICk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgZ2V0TnBtQXJ0aWZhY3RzKGZhbHNlLCBhcnRpZmFjdG9yeUNvbmZpZywgY3JlZHMpO1xuICBjb25zdCB7IGlzUmVsZWFzZSwgbnBtOiBucG1WZXJzaW9uIH0gPSBhd2FpdCBnZXRWZXJzaW9uKCk7XG4gIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgJHtucG1WZXJzaW9ufS50Z3okYCk7XG4gIGNvbnN0IGV4aXN0cyA9ICEhZXhpc3RpbmcuZmluZCgoYykgPT4gYy5wYXRoLm1hdGNoKHJlZ2V4KSk7XG4gIGlmIChleGlzdHMpIHtcbiAgICBpZiAoc2tpcEV4aXN0aW5nKSB7XG4gICAgICBidWlsZExvZyhcbiAgICAgICAgJ25wbSBtb2R1bGUgd2l0aCB0aGlzIHNhbWUgdmVyc2lvbiBhbHJlYWR5IGV4aXN0cyBpbiBhcnRpZmFjdG9yeS4gU2tpcHBpbmcgcHVibGlzaC4uLicsXG4gICAgICApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnRmFpbGVkIHRvIHB1Ymxpc2ggbnBtIG1vZHVsZSwgdGhpcyB2ZXJzaW9uIGFscmVhZHkgZXhpc3RzIGluIGFydGlmYWN0b3J5IScsXG4gICAgKTtcbiAgfVxuICAvLyBXcml0ZSBvdXQgLm5wbXJjIHdpdGggY3JlZGVudGlhbHNcbiAgYXdhaXQgd3JpdGVGaWxlKFxuICAgIHBhdGguam9pbihkaXN0RGlyLCAnLm5wbXJjJyksXG4gICAgYHJlZ2lzdHJ5PSR7cnR9YXBpL25wbS8ke25wbX1cbl9hdXRoPSR7QnVmZmVyLmZyb20oYCR7Y3JlZHMudXNlcm5hbWV9OiR7Y3JlZHMucGFzc3dvcmR9YCkudG9TdHJpbmcoJ2Jhc2U2NCcpfVxuYWx3YXlzLWF1dGg9dHJ1ZVxuZW1haWw9JHtjcmVkcy5lbWFpbH1gLFxuICApO1xuICBhd2FpdCBzcGF3bihcbiAgICBucG1QYXRoIHx8IChwbGF0Zm9ybSgpID09PSAnd2luMzInID8gJ25wbS5jbWQnIDogJ25wbScpLFxuICAgIFsncHVibGlzaCcsICctLXRhZycsIHRhZyB8fCAoaXNSZWxlYXNlID8gJ2xhdGVzdCcgOiAnbmV4dCcpXSxcbiAgICB7XG4gICAgICBzdGRpbzogJ2luaGVyaXQnLFxuICAgICAgY3dkOiBkaXN0RGlyLFxuICAgIH0sXG4gICk7XG4gIHJldHVybiB0cnVlO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzdGFuZGFyZFVybChcbiAgZmlsZU5hbWU6IHN0cmluZyxcbiAgYXJ0aWZhY3RvcnlDb25maWc/OiBBcnRpZmFjdG9yeUNvbmZpZyxcbikge1xuICBjb25zdCB7XG4gICAgcm9vdDogcnQsXG4gICAgcmVsZWFzZSxcbiAgICBpbnRlZ3JhdGlvbixcbiAgICBwYXRoOiBhUGF0aCxcbiAgICAndmVyc2lvbi1mb2xkZXJzJzogdmVyc2lvbkZvbGRlcnMsXG4gICAgJ2ludGVncmF0aW9uLWJyYW5jaC1mb2xkZXJzJzogaW50QnJGb2xkZXJzLFxuICB9ID0gYXJ0aWZhY3RvcnlDb25maWcgfHwgZ2V0QXJ0aWZhY3RvcnlDb25maWcoKTtcbiAgaWYgKCFydCB8fCAhcmVsZWFzZSB8fCAhaW50ZWdyYXRpb24pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgdmVyc2lvbiA9IGF3YWl0IGdldFZlcnNpb24oKTtcbiAgY29uc3QgYXJ0UGF0aCA9IGFQYXRoIHx8IGdldFBrZ05hbWUoKTtcbiAgY29uc3QgdmVyc0RpciA9IHZlcnNpb25Gb2xkZXJzID8gYC8ke3ZlcnNpb24uaW5mb31gIDogJyc7XG4gIGlmICh2ZXJzaW9uLmlzUmVsZWFzZSkge1xuICAgIHJldHVybiBgJHtydH0ke3JlbGVhc2V9LyR7YXJ0UGF0aH0ke3ZlcnNEaXJ9LyR7ZmlsZU5hbWV9YDtcbiAgfVxuICBjb25zdCBicmFuY2ggPSBpbnRCckZvbGRlcnMgPyBgLyR7dmVyc2lvbi5icmFuY2h9YCA6ICcnO1xuICByZXR1cm4gYCR7cnR9JHtpbnRlZ3JhdGlvbn0vJHthcnRQYXRofSR7YnJhbmNofSR7dmVyc0Rpcn0vJHtmaWxlTmFtZX1gO1xufVxuXG4vLyBVc2UgdGhlIFJFU1QgYXBpIHRvIHB1Ymxpc2ggYXMgYSBzdGFuZGFyZCBhcnRpZmFjdG9yeSBhcnRpZmFjdFxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFydGlmYWN0b3J5U3RhbmRhcmQoXG4gIGFydGlmYWN0OiBzdHJpbmcgfCBzdHJlYW0kUmVhZGFibGUsXG4gIGFydGlmYWN0SW5mbzogQXJ0aWZhY3RJbmZvLFxuICBmaWxlTmFtZTogc3RyaW5nLFxuICBhcnRpZmFjdG9yeUNvbmZpZz86IEFydGlmYWN0b3J5Q29uZmlnLFxuICBhcnRpZmFjdG9yeUNyZWRzPzogQXJ0aWZhY3RvcnlDcmVkcyxcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBjb25zdCB1cmwgPSBhd2FpdCBzdGFuZGFyZFVybChmaWxlTmFtZSwgYXJ0aWZhY3RvcnlDb25maWcpO1xuICBpZiAoIXVybCkge1xuICAgIGJ1aWxkTG9nKFxuICAgICAgJ3JlbGVhc2UvaW50ZWdyYXRpb24gYXJ0aWZhY3RvcnlDb25maWcgaW5mbyBtaXNzaW5nIGZyb20gcGFja2FnZS5qc29uLCBza2lwcGluZyBwdWJsaXNoJyxcbiAgICApO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBhd2FpdCBhcnRpZmFjdG9yeVB1dChhcnRpZmFjdCwgdXJsLCBhcnRpZmFjdEluZm8sIGFydGlmYWN0b3J5Q3JlZHMpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuY29uc3QgZ2V0UmVtb3RlQXJ0aWZhY3RJbmZvID0gYXN5bmMgKFxuICByb290VXJpOiBzdHJpbmcsXG4gIHJlcG86IHN0cmluZyxcbiAgc3ViUGF0aDogc3RyaW5nLFxuICBhcnRpZmFjdG9yeUNyZWRzPzogQXJ0aWZhY3RvcnlDcmVkcyxcbik6IFByb21pc2U8UmVtb3RlQXJ0aWZhY3RJbmZvPiA9PlxuICBhcnRpZmFjdG9yeVJlcXVlc3QoXG4gICAge1xuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIHVyaTogYCR7cm9vdFVyaX0vYXBpL3N0b3JhZ2UvJHtyZXBvfS8ke3N1YlBhdGh9YCxcbiAgICAgIGpzb246IHRydWUsXG4gICAgfSxcbiAgICBhcnRpZmFjdG9yeUNyZWRzLFxuICApO1xuXG5jb25zdCBnZXRSZW1vdGVBcnRpZmFjdENoaWxkcmVuSW5mbyA9IGFzeW5jIChcbiAgaW5mbzogUmVtb3RlQXJ0aWZhY3RJbmZvLFxuICByb290VXJpOiBzdHJpbmcsXG4gIHJlcG86IHN0cmluZyxcbiAgc3ViUGF0aDogc3RyaW5nLFxuICBhcnRpZmFjdG9yeUNyZWRzPzogQXJ0aWZhY3RvcnlDcmVkcyxcbikgPT5cbiAgUHJvbWlzZS5hbGwoXG4gICAgaW5mby5jaGlsZHJlbi5tYXAoYXN5bmMgKGMpID0+XG4gICAgICBnZXRSZW1vdGVBcnRpZmFjdEluZm8oXG4gICAgICAgIHJvb3RVcmksXG4gICAgICAgIHJlcG8sXG4gICAgICAgIGAke3N1YlBhdGh9JHtjLnVyaX1gLFxuICAgICAgICBhcnRpZmFjdG9yeUNyZWRzLFxuICAgICAgKSxcbiAgICApLFxuICApO1xuXG50eXBlIENsZWFuQ2hpbGRyZW5PcHRpb25zID0ge3xcbiAgcm9vdFVyaTogc3RyaW5nLFxuICByZXBvOiBzdHJpbmcsXG4gIHN1YlBhdGg6IHN0cmluZyxcbiAgZGF5c1RvS2VlcD86IG51bWJlcixcbiAgbWF4VG9LZWVwPzogbnVtYmVyLFxuICBrZWVwRmlsdGVyPzogPyhjaGlsZDogUmVtb3RlQXJ0aWZhY3RJbmZvKSA9PiBib29sZWFuLFxuICBhcnRpZmFjdG9yeUNyZWRzPzogQXJ0aWZhY3RvcnlDcmVkcyxcbiAgaWdub3JlRXJyb3JzPzogYm9vbGVhbixcbnx9O1xuXG5hc3luYyBmdW5jdGlvbiBjbGVhbkNoaWxkcmVuKHtcbiAgcm9vdFVyaSxcbiAgcmVwbyxcbiAgc3ViUGF0aCxcbiAgZGF5c1RvS2VlcCA9IDE0LFxuICBtYXhUb0tlZXAgPSAxMCxcbiAga2VlcEZpbHRlcixcbiAgYXJ0aWZhY3RvcnlDcmVkcyxcbiAgaWdub3JlRXJyb3JzID0gdHJ1ZSxcbn06IENsZWFuQ2hpbGRyZW5PcHRpb25zID0ge30pIHtcbiAgY29uc3QgaW5mbyA9IGF3YWl0IGdldFJlbW90ZUFydGlmYWN0SW5mbyhcbiAgICByb290VXJpLFxuICAgIHJlcG8sXG4gICAgc3ViUGF0aCxcbiAgICBhcnRpZmFjdG9yeUNyZWRzLFxuICApO1xuICBjb25zdCBjaGlsZHJlbiA9IGF3YWl0IGdldFJlbW90ZUFydGlmYWN0Q2hpbGRyZW5JbmZvKFxuICAgIGluZm8sXG4gICAgcm9vdFVyaSxcbiAgICByZXBvLFxuICAgIHN1YlBhdGgsXG4gICAgYXJ0aWZhY3RvcnlDcmVkcyxcbiAgKTtcbiAgLy8gRmlsdGVyIG91dCBjaGlsZHJlbiB0aGF0IHdlIGFic29sdXRlbHkgd2lsbCBub3QgZGVsZXRlXG4gIGNvbnN0IGludGVncmF0aW9uQ2hpbGRyZW4gPSBrZWVwRmlsdGVyXG4gICAgPyBjaGlsZHJlbi5maWx0ZXIoKGMpID0+ICFrZWVwRmlsdGVyKGMpKVxuICAgIDogY2hpbGRyZW47XG5cbiAgLy8gRGV0ZXJtaW5lIHdoaWNoIGludGVncmF0aW9uIGFydGlmYWN0cyB0byBrZWVwICh0aGV5IGFyZSByZWNlbnQgYW5kIG5vdCB0b28gbnVtZXJvdXMpXG4gIGNvbnN0IHRpbWVUaHJlc2hvbGQgPSBkYXlzVG9LZWVwXG4gICAgPyBtb21lbnQoKS5zdWJ0cmFjdChkYXlzVG9LZWVwLCAnZGF5cycpXG4gICAgOiBudWxsO1xuICBjb25zdCBmaWx0ZXJlZCA9IHRpbWVUaHJlc2hvbGRcbiAgICA/IGludGVncmF0aW9uQ2hpbGRyZW4uZmlsdGVyKChjKSA9PlxuICAgICAgICBtb21lbnQoYy5sYXN0TW9kaWZpZWQpLmlzQWZ0ZXIodGltZVRocmVzaG9sZCksXG4gICAgICApXG4gICAgOiBpbnRlZ3JhdGlvbkNoaWxkcmVuO1xuICBjb25zdCBsaW1pdGVkID0gbWF4VG9LZWVwXG4gICAgPyBmaWx0ZXJlZFxuICAgICAgICAuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgIGNvbnN0IHRBID0gbW9tZW50KGEubGFzdE1vZGlmaWVkKTtcbiAgICAgICAgICBjb25zdCB0QiA9IG1vbWVudChiLmxhc3RNb2RpZmllZCk7XG4gICAgICAgICAgaWYgKHRBLmlzQmVmb3JlKHRCKSkge1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodEEuaXNBZnRlcih0QikpIHtcbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfSlcbiAgICAgICAgLnNsaWNlKC1tYXhUb0tlZXApXG4gICAgOiBmaWx0ZXJlZDtcblxuICAvLyBEZWxldGUgYW55IGludGVncmF0aW9uIGFydGlmYWN0cyB0aGF0IGRpZG4ndCBtYWtlIHRoZSBsaW1pdGVkIGxpc3RcbiAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChcbiAgICBpbnRlZ3JhdGlvbkNoaWxkcmVuXG4gICAgICAuZmlsdGVyKChjKSA9PiBsaW1pdGVkLmluZGV4T2YoYykgPCAwKVxuICAgICAgLm1hcChhc3luYyAoYykgPT4ge1xuICAgICAgICBidWlsZExvZyhgRGVsZXRpbmcgYXJ0aWZhY3Q6ICR7Yy5yZXBvfSR7Yy5wYXRofWApO1xuICAgICAgICByZXR1cm4gYXJ0aWZhY3RvcnlEZWxldGUoXG4gICAgICAgICAgYCR7cm9vdFVyaX0vJHtjLnJlcG99LyR7Yy5wYXRofWAsXG4gICAgICAgICAgYXJ0aWZhY3RvcnlDcmVkcyxcbiAgICAgICAgKTtcbiAgICAgIH0pLFxuICApO1xuXG4gIGlmICghaWdub3JlRXJyb3JzICYmIHJlc3VsdHMuc29tZSgocikgPT4gci5zdGF0dXMgPT09ICdyZWplY3RlZCcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTb21lIGFydGlmYWN0cyB3ZXJlIG5vdCBkZWxldGVkLicpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbnR5cGUgQ2xlYW5CcmFuY2hGb2xkZXJzT3B0aW9ucyA9IHtcbiAgcm9vdFVyaTogc3RyaW5nLFxuICByZXBvOiBzdHJpbmcsXG4gIHN1YlBhdGg6IHN0cmluZyxcbiAgZGF5c1RvS2VlcD86IG51bWJlcixcbiAgbWF4VG9LZWVwPzogbnVtYmVyLFxuICBrZWVwRmlsdGVyPzogPyhjaGlsZDogUmVtb3RlQXJ0aWZhY3RJbmZvKSA9PiBib29sZWFuLFxuICBhcnRpZmFjdG9yeUNyZWRzPzogQXJ0aWZhY3RvcnlDcmVkcyxcbiAgaWdub3JlRXJyb3JzPzogYm9vbGVhbixcbn07XG5cbmFzeW5jIGZ1bmN0aW9uIGNsZWFuQnJhbmNoRm9sZGVycyh7XG4gIHJvb3RVcmksXG4gIHJlcG8sXG4gIHN1YlBhdGgsXG4gIGRheXNUb0tlZXAsXG4gIG1heFRvS2VlcCxcbiAga2VlcEZpbHRlcixcbiAgYXJ0aWZhY3RvcnlDcmVkcyxcbiAgaWdub3JlRXJyb3JzID0gdHJ1ZSxcbn06IENsZWFuQnJhbmNoRm9sZGVyc09wdGlvbnMgPSB7fSkge1xuICBjb25zdCBpbmZvID0gYXdhaXQgZ2V0UmVtb3RlQXJ0aWZhY3RJbmZvKFxuICAgIHJvb3RVcmksXG4gICAgcmVwbyxcbiAgICBzdWJQYXRoLFxuICAgIGFydGlmYWN0b3J5Q3JlZHMsXG4gICk7XG4gIGNvbnN0IGNoaWxkcmVuID0gYXdhaXQgZ2V0UmVtb3RlQXJ0aWZhY3RDaGlsZHJlbkluZm8oXG4gICAgaW5mbyxcbiAgICByb290VXJpLFxuICAgIHJlcG8sXG4gICAgc3ViUGF0aCxcbiAgICBhcnRpZmFjdG9yeUNyZWRzLFxuICApO1xuICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFxuICAgIGNoaWxkcmVuLm1hcChhc3luYyAoYykgPT4ge1xuICAgICAgY29uc3QgW2JyYW5jaF0gPSBjLnBhdGguc3BsaXQoJy8nKS5zbGljZSgtMSk7XG4gICAgICBpZiAoYnJhbmNoID09PSBnZXRSZWxlYXNlQnJhbmNoKCkpIHtcbiAgICAgICAgYnVpbGRMb2coXG4gICAgICAgICAgYFNraXBwaW5nIGNsZWFudXAgb2YgcmVsZWFzZSBicmFuY2g6ICR7cmVwb30vJHtzdWJQYXRofS8ke2JyYW5jaH1gLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBidWlsZExvZyhgQ2xlYW5pbmcgaW50ZWdyYXRpb24gYnJhbmNoOiAke3JlcG99LyR7c3ViUGF0aH0vJHticmFuY2h9YCk7XG4gICAgICBhd2FpdCBjbGVhbkNoaWxkcmVuKHtcbiAgICAgICAgcm9vdFVyaSxcbiAgICAgICAgcmVwbzogYy5yZXBvLFxuICAgICAgICBzdWJQYXRoOiBjLnBhdGgsXG4gICAgICAgIGRheXNUb0tlZXAsXG4gICAgICAgIG1heFRvS2VlcCxcbiAgICAgICAga2VlcEZpbHRlcixcbiAgICAgICAgYXJ0aWZhY3RvcnlDcmVkcyxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBpZiBicmFuY2ggZm9sZGVyIGlzIG5vdyBlbXB0eSwgZGVsZXRlIGl0XG4gICAgICBjb25zdCBjSW5mbyA9IGF3YWl0IGdldFJlbW90ZUFydGlmYWN0SW5mbyhcbiAgICAgICAgcm9vdFVyaSxcbiAgICAgICAgYy5yZXBvLFxuICAgICAgICBjLnBhdGgsXG4gICAgICAgIGFydGlmYWN0b3J5Q3JlZHMsXG4gICAgICApO1xuICAgICAgaWYgKGNJbmZvLmNoaWxkcmVuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBidWlsZExvZyhgRGVsZXRpbmcgZW1wdHkgYnJhbmNoIGZvbGRlcjogJHtjLnJlcG99LyR7Yy5wYXRofWApO1xuICAgICAgICBhd2FpdCBhcnRpZmFjdG9yeURlbGV0ZShcbiAgICAgICAgICBgJHtyb290VXJpfS8ke2MucmVwb30vJHtjLnBhdGh9YCxcbiAgICAgICAgICBhcnRpZmFjdG9yeUNyZWRzLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pLFxuICApO1xuXG4gIGlmICghaWdub3JlRXJyb3JzICYmIHJlc3VsdHMuc29tZSgocikgPT4gci5zdGF0dXMgPT09ICdyZWplY3RlZCcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTb21lIGFydGlmYWN0cyB3ZXJlIG5vdCBkZWxldGVkLicpO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXJ0aWZhY3RvcnlDbGVhbnVwKFxuICBkYXlzVG9LZWVwPzogbnVtYmVyLFxuICBtYXhUb0tlZXA/OiBudW1iZXIsXG4gIGFydGlmYWN0b3J5Q29uZmlnPzogQXJ0aWZhY3RvcnlDb25maWcsXG4gIGFydGlmYWN0b3J5Q3JlZHM/OiBBcnRpZmFjdG9yeUNyZWRzLFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IHtcbiAgICByb290OiBydCxcbiAgICAnaW50ZWdyYXRpb24tZGF5cy10by1rZWVwJzogaW50RGF5c0tlZXAsXG4gICAgJ2ludGVncmF0aW9uLW1heC10by1rZWVwJzogaW50TWF4S2VlcCxcbiAgICBpbnRlZ3JhdGlvbixcbiAgICBwYXRoOiBhUGF0aCxcbiAgICAnaW50ZWdyYXRpb24tYnJhbmNoLWZvbGRlcnMnOiBpbnRCcmFuY2hGb2xkZXJzLFxuICAgICducG0tY2xlYW4nOiBucG1DbGVhbixcbiAgfSA9IGFydGlmYWN0b3J5Q29uZmlnIHx8IGdldEFydGlmYWN0b3J5Q29uZmlnKCk7XG4gIGlmICghcnQpIHtcbiAgICBidWlsZExvZyhcbiAgICAgICdhcnRpZmFjdG9yeSBpbmZvIG1pc3NpbmcgZnJvbSBwYWNrYWdlLmpzb24sIHNraXBwaW5nIGFydGlmYWN0b3J5IGNsZWFudXAnLFxuICAgICk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IGRUb0sgPSBkYXlzVG9LZWVwID09IG51bGwgPyBpbnREYXlzS2VlcCA6IGRheXNUb0tlZXA7XG4gIGNvbnN0IG1Ub0sgPSBtYXhUb0tlZXAgPT0gbnVsbCA/IGludE1heEtlZXAgOiBtYXhUb0tlZXA7XG5cbiAgaWYgKGludGVncmF0aW9uKSB7XG4gICAgLy8gQ2xlYW4gdXAgaW50ZWdyYXRpb24gcmVwbyBhcnRpZmFjdHNcbiAgICBjb25zdCBhcnRQYXRoID0gYVBhdGggfHwgZ2V0UGtnTmFtZSgpO1xuICAgIGlmIChpbnRCcmFuY2hGb2xkZXJzKSB7XG4gICAgICBhd2FpdCBjbGVhbkJyYW5jaEZvbGRlcnMoe1xuICAgICAgICByb290VXJpOiBydCxcbiAgICAgICAgcmVwbzogaW50ZWdyYXRpb24sXG4gICAgICAgIHN1YlBhdGg6IGFydFBhdGgsXG4gICAgICAgIGRheXNUb0tlZXA6IGRUb0ssXG4gICAgICAgIG1heFRvS2VlcDogbVRvSyxcbiAgICAgICAgYXJ0aWZhY3RvcnlDcmVkcyxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCBjbGVhbkNoaWxkcmVuKHtcbiAgICAgICAgcm9vdFVyaTogcnQsXG4gICAgICAgIHJlcG86IGludGVncmF0aW9uLFxuICAgICAgICBzdWJQYXRoOiBhcnRQYXRoLFxuICAgICAgICBkYXlzVG9LZWVwOiBkVG9LLFxuICAgICAgICBtYXhUb0tlZXA6IG1Ub0ssXG4gICAgICAgIGFydGlmYWN0b3J5Q3JlZHMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZiAobnBtQ2xlYW4pIHtcbiAgICAvLyBDbGVhbiB1cCBucG0gaW50ZWdyYXRpb24gYXJ0aWZhY3RzXG4gICAgY29uc3QgbmFtZSA9IGdldFBrZ05hbWUoZmFsc2UpO1xuICAgIGNvbnN0IHNjb3BlID0gZ2V0UGtnU2NvcGUoKTtcbiAgICBjb25zdCByZWxlYXNlUmVnZXggPSBuZXcgUmVnRXhwKGAke25hbWV9LVxcXFxkK1xcXFwuXFxcXGQrXFxcXC5cXFxcZCtcXFxcLnRnemAsICdpJyk7XG4gICAgYXdhaXQgY2xlYW5DaGlsZHJlbih7XG4gICAgICByb290VXJpOiBydCxcbiAgICAgIHJlcG86IG5wbUNsZWFuLFxuICAgICAgc3ViUGF0aDogc2NvcGUgPyBgJHtzY29wZX0vJHtuYW1lfS8tLyR7c2NvcGV9YCA6IGAke25hbWV9Ly1gLFxuICAgICAgZGF5c1RvS2VlcDogZFRvSyxcbiAgICAgIG1heFRvS2VlcDogbVRvSyxcbiAgICAgIGtlZXBGaWx0ZXI6IChjKSA9PiAhIWMucGF0aC5tYXRjaChyZWxlYXNlUmVnZXgpLFxuICAgICAgYXJ0aWZhY3RvcnlDcmVkcyxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gdW5pcUJ5PFQ+KGE6IFRbXSwga2V5OiAoVCkgPT4gc3RyaW5nKTogVFtdIHtcbiAgY29uc3Qgc2VlbiA9IG5ldyBTZXQoKTtcbiAgcmV0dXJuIGEuZmlsdGVyKChpdGVtOiBUKSA9PiB7XG4gICAgY29uc3QgayA9IGtleShpdGVtKTtcbiAgICByZXR1cm4gc2Vlbi5oYXMoaykgPyBmYWxzZSA6IHNlZW4uYWRkKGspO1xuICB9KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldE5wbUFydGlmYWN0cyhcbiAgcmVsZWFzZWRPbmx5OiBib29sZWFuID0gZmFsc2UsXG4gIGFydGlmYWN0b3J5Q29uZmlnPzogQXJ0aWZhY3RvcnlDb25maWcsXG4gIGFydGlmYWN0b3J5Q3JlZHM/OiBBcnRpZmFjdG9yeUNyZWRzLFxuKTogUHJvbWlzZTxSZW1vdGVBcnRpZmFjdEluZm9bXT4ge1xuICBjb25zdCB7IHJvb3Q6IHJ0LCBucG0gfSA9IGFydGlmYWN0b3J5Q29uZmlnIHx8IGdldEFydGlmYWN0b3J5Q29uZmlnKCk7XG4gIGlmICghcnQgfHwgIW5wbSkge1xuICAgIHRocm93IG5ldyBFcnJvcignYXJ0aWZhY3RvcnlDb25maWcgaW5mbyBtaXNzaW5nIGZyb20gcGFja2FnZS5qc29uJyk7XG4gIH1cbiAgY29uc3QgbmFtZSA9IGdldFBrZ05hbWUoZmFsc2UpO1xuICBjb25zdCBzY29wZSA9IGdldFBrZ1Njb3BlKCk7XG4gIGNvbnN0IG5wbVBhdGggPSBzY29wZSA/IGAke3Njb3BlfS8ke25hbWV9Ly0vJHtzY29wZX1gIDogYCR7bmFtZX0vLWA7XG4gIGNvbnN0IHJlbGVhc2VSZWdleCA9IG5ldyBSZWdFeHAoYCR7bmFtZX0tXFxcXGQrXFxcXC5cXFxcZCtcXFxcLlxcXFxkK1xcXFwudGd6YCwgJ2knKTtcbiAgdHJ5IHtcbiAgICBjb25zdCBpbmZvID0gYXdhaXQgZ2V0UmVtb3RlQXJ0aWZhY3RJbmZvKFxuICAgICAgcnQsXG4gICAgICBucG0sXG4gICAgICBucG1QYXRoLFxuICAgICAgYXJ0aWZhY3RvcnlDcmVkcyxcbiAgICApO1xuICAgIGNvbnN0IGNoaWxkcmVuID0gdW5pcUJ5KFxuICAgICAgYXdhaXQgZ2V0UmVtb3RlQXJ0aWZhY3RDaGlsZHJlbkluZm8oXG4gICAgICAgIGluZm8sXG4gICAgICAgIHJ0LFxuICAgICAgICBucG0sXG4gICAgICAgIG5wbVBhdGgsXG4gICAgICAgIGFydGlmYWN0b3J5Q3JlZHMsXG4gICAgICApLFxuICAgICAgKGMpID0+IGMudXJpLFxuICAgICk7XG4gICAgcmV0dXJuIHJlbGVhc2VkT25seVxuICAgICAgPyAvLyAkRmxvd0ZpeE1lXG4gICAgICAgIGNoaWxkcmVuLmZpbHRlcigoYykgPT4gISFjLnBhdGgubWF0Y2gocmVsZWFzZVJlZ2V4KSlcbiAgICAgIDogY2hpbGRyZW47XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGlmIChlcnIuc3RhdHVzQ29kZSA9PT0gNDA0KSByZXR1cm4gW107XG4gICAgdGhyb3cgZXJyO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRMYXRlc3RSZXBvc2l0b3J5VmVyc2lvbihcbiAgcmVwb3NpdG9yeVBhdGg6IHN0cmluZyxcbiAgYXJ0aWZhY3RvcnlDcmVkcz86IEFydGlmYWN0b3J5Q3JlZHMsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCB7IHJvb3Q6IHJ0IH0gPSBnZXRBcnRpZmFjdG9yeUNvbmZpZygpO1xuICBpZiAoIXJ0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdhcnRpZmFjdG9yeUNvbmZpZyBpbmZvIG1pc3NpbmcgZnJvbSBwYWNrYWdlLmpzb24nKTtcbiAgfVxuICAvLyBnZXQgbGF0ZXN0IHZlcnNpb24gbnVtYmVyIGZvciB0aGUga2V5XG4gIGNvbnN0IGxhc3RNb2RpZmllZEZpbGVJbmZvID0gYXdhaXQgYXJ0aWZhY3RvcnlSZXF1ZXN0KFxuICAgIHtcbiAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICB1cmk6IHVybEpvaW4ocnQsIGAvYXBpL3N0b3JhZ2UvJHtyZXBvc2l0b3J5UGF0aH0/bGFzdE1vZGlmaWVkYCksXG4gICAgfSxcbiAgICBhcnRpZmFjdG9yeUNyZWRzLFxuICApO1xuICBjb25zdCB7IHVyaSB9ID0gSlNPTi5wYXJzZShsYXN0TW9kaWZpZWRGaWxlSW5mbyk7XG4gIGNvbnN0IHZlcnNpb25TdGFydEluZGV4ID0gdXJpLmluZGV4T2YocmVwb3NpdG9yeVBhdGgpICsgcmVwb3NpdG9yeVBhdGgubGVuZ3RoO1xuICBjb25zdCB2ZXJzaW9uRW5kSW5kZXggPSB1cmkuaW5kZXhPZignLycsIHZlcnNpb25TdGFydEluZGV4ICsgMSk7XG4gIGNvbnN0IHZlcnNpb25OdW1iZXIgPSB1cmkuc3Vic3RyaW5nKHZlcnNpb25TdGFydEluZGV4ICsgMSwgdmVyc2lvbkVuZEluZGV4KTtcbiAgcmV0dXJuIHZlcnNpb25OdW1iZXI7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZVZlcnNpb25lZEZpbGVQYXRoKFxuICByZXBvc2l0b3J5UGF0aDogc3RyaW5nLFxuICBmaWxlUGF0aDogc3RyaW5nLFxuICBhcnRpZmFjdG9yeUNyZWRzPzogQXJ0aWZhY3RvcnlDcmVkcyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICBpZiAoZmlsZVBhdGguaW5kZXhPZigne3t2ZXJzaW9ufX0nKSA+IC0xKSB7XG4gICAgY29uc3QgdmVyc2lvbiA9IGF3YWl0IGdldExhdGVzdFJlcG9zaXRvcnlWZXJzaW9uKFxuICAgICAgcmVwb3NpdG9yeVBhdGgsXG4gICAgICBhcnRpZmFjdG9yeUNyZWRzLFxuICAgICk7XG4gICAgcmV0dXJuIGZpbGVQYXRoLnJlcGxhY2UoL3t7dmVyc2lvbn19L2csIHZlcnNpb24pO1xuICB9XG5cbiAgcmV0dXJuIGZpbGVQYXRoO1xufVxuXG4vKipcbiAqIERvd25sb2FkIGEgZ2l2ZW4gZmlsZSBmcm9tIGEgcmVwb3NpdG9yeSBob3N0ZWQgaW4gQXJ0aWZhY3RvcnlcbiAqIEBwYXJhbSB7c3RyaW5nfSByZXBvc2l0b3J5UGF0aFxuICogIFRoZSBwYXRoIHRvIHRoZSByZXBvc2l0b3J5IHJvb3QgcmVsYXRpdmUgdG8gdGhlIGNvbmZpZ3VyZWQgYXJ0aWZhY3Rvcnkgcm9vdFxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoXG4gKiAgVGhlIHBhdGggdG8gdGhlIGZpbGUgZnJvbSB0aGUgcmVwb3NpdG9yeSByb290LiBJZiB0aGUgbGF0ZXN0IHZlcnNpb24gb2YgdGhlXG4gKiAgZmlsZSBpcyBkZXNpcmVkIGEgdG9rZW5pemVkIHN0cmluZyBjYW4gYmUgcGFzc2VkIHVzaW5nIHt7dmVyc2lvbn19IHRvIGluZGljYXRlXG4gKiAgc2VnbWVudHMgdG8gcmVwbGFjZWQgYnkgdGhlIGxhdGVzdCB2ZXJzaW9uIHN0cmluZy5cbiAqICAgIGV4OiB7e3ZlcnNpb259fS9wYXRoL2ZpbGUtbmFtZS0ke3t2ZXJzaW9ufX0uanNcbiAqIEBwYXJhbSB7c3RyaW5nfSBzYXZlQXNcbiAqICBUaGUgbG9jYWwgZmlsZSBwYXRoIHRvIHNhdmUgdGhlIGRvd25sb2FkZWQgZmlsZSB0by5cbiAqIEBwYXJhbSB7QXJ0aWZhY3RvcnlDcmVkc30gYXJ0aWZhY3RvcnlDcmVkc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG93bmxvYWRSZXBvc2l0b3J5RmlsZShcbiAgcmVwb3NpdG9yeVBhdGg6IHN0cmluZyxcbiAgZmlsZVBhdGg6IHN0cmluZyxcbiAgc2F2ZUFzOiBzdHJpbmcsXG4gIGFydGlmYWN0b3J5Q3JlZHM/OiBBcnRpZmFjdG9yeUNyZWRzLFxuKTogUHJvbWlzZTxSZXNwb25zZT4ge1xuICBjb25zdCB7IHJvb3Q6IHJ0IH0gPSBnZXRBcnRpZmFjdG9yeUNvbmZpZygpO1xuICBpZiAoIXJ0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdhcnRpZmFjdG9yeUNvbmZpZyBpbmZvIG1pc3NpbmcgZnJvbSBwYWNrYWdlLmpzb24nKTtcbiAgfVxuICBjb25zdCBmaWxlVXJpID0gdXJsSm9pbihcbiAgICBydCxcbiAgICByZXBvc2l0b3J5UGF0aCxcbiAgICBhd2FpdCBwYXJzZVZlcnNpb25lZEZpbGVQYXRoKHJlcG9zaXRvcnlQYXRoLCBmaWxlUGF0aCwgYXJ0aWZhY3RvcnlDcmVkcyksXG4gICk7XG4gIGJ1aWxkTG9nKGBEb3dubG9hZGluZyBmaWxlIGZyb20gQXJ0aWZhY3Rvcnk6ICR7ZmlsZVVyaX1gKTtcbiAgY29uc3QgZmlsZVN0cmVhbSA9IGZzLmNyZWF0ZVdyaXRlU3RyZWFtKHNhdmVBcyk7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgcmVxdWVzdChmaWxlVXJpLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgYnVpbGRMb2coYEVycm9yIGRvd25sb2FkaW5nICR7ZmlsZVVyaX06ICR7SlNPTi5zdHJpbmdpZnkoZXJyb3IpfWApO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICB9XG4gICAgfSkucGlwZShmaWxlU3RyZWFtKTtcbiAgfSk7XG59XG4iXX0=
|