piclist 0.0.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/.eslintignore +2 -0
- package/.eslintrc.js +25 -0
- package/.github/workflows/alpha.yml +22 -0
- package/.github/workflows/main.yml +22 -0
- package/.github/workflows/manually.yml +19 -0
- package/CHANGELOG.md +549 -0
- package/License +21 -0
- package/README.md +116 -0
- package/bin/picgo +22 -0
- package/dist/core/Lifecycle.d.ts +15 -0
- package/dist/core/PicGo.d.ts +49 -0
- package/dist/i18n/en.d.ts +2 -0
- package/dist/i18n/index.d.ts +18 -0
- package/dist/i18n/zh-CN.d.ts +91 -0
- package/dist/i18n/zh-TW.d.ts +2 -0
- package/dist/index.cjs.js +3807 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.esm.js +3769 -0
- package/dist/lib/Commander.d.ts +22 -0
- package/dist/lib/LifecyclePlugins.d.ts +17 -0
- package/dist/lib/Logger.d.ts +19 -0
- package/dist/lib/PluginHandler.d.ts +10 -0
- package/dist/lib/PluginLoader.d.ts +27 -0
- package/dist/lib/Request.d.ts +12 -0
- package/dist/plugins/commander/config.d.ts +3 -0
- package/dist/plugins/commander/i18n.d.ts +3 -0
- package/dist/plugins/commander/index.d.ts +3 -0
- package/dist/plugins/commander/init.d.ts +3 -0
- package/dist/plugins/commander/pluginHandler.d.ts +3 -0
- package/dist/plugins/commander/proxy.d.ts +3 -0
- package/dist/plugins/commander/setting.d.ts +5 -0
- package/dist/plugins/commander/upload.d.ts +3 -0
- package/dist/plugins/commander/use.d.ts +3 -0
- package/dist/plugins/transformer/base64.d.ts +5 -0
- package/dist/plugins/transformer/index.d.ts +3 -0
- package/dist/plugins/transformer/path.d.ts +5 -0
- package/dist/plugins/uploader/aliyun.d.ts +2 -0
- package/dist/plugins/uploader/github.d.ts +2 -0
- package/dist/plugins/uploader/imgur.d.ts +2 -0
- package/dist/plugins/uploader/index.d.ts +3 -0
- package/dist/plugins/uploader/qiniu.d.ts +2 -0
- package/dist/plugins/uploader/smms.d.ts +2 -0
- package/dist/plugins/uploader/tcyun.d.ts +8 -0
- package/dist/plugins/uploader/upyun.d.ts +2 -0
- package/dist/types/index.d.ts +537 -0
- package/dist/types/oldRequest.d.ts +19 -0
- package/dist/utils/common.d.ts +106 -0
- package/dist/utils/createContext.d.ts +6 -0
- package/dist/utils/db.d.ts +15 -0
- package/dist/utils/enum.d.ts +27 -0
- package/dist/utils/eventBus.d.ts +4 -0
- package/dist/utils/getClipboardImage.d.ts +4 -0
- package/dist/utils/initUtils.d.ts +26 -0
- package/dist/utils/interfaces.d.ts +203 -0
- package/dist/utils/static.d.ts +1 -0
- package/logo.png +0 -0
- package/package.json +133 -0
- package/rollup.config.js +87 -0
|
@@ -0,0 +1,3769 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* picgo@0.0.1, https://github.com/PicGo/PicGo-Core
|
|
3
|
+
* (c) 2018-2023 PicGo Group
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'fs-extra';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { EventEmitter } from 'events';
|
|
9
|
+
import os, { homedir } from 'os';
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import inquirer from 'inquirer';
|
|
12
|
+
import { imageSize } from 'image-size';
|
|
13
|
+
import { URL } from 'url';
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
import match from 'minimatch';
|
|
16
|
+
import globby from 'globby';
|
|
17
|
+
import ejs from 'ejs';
|
|
18
|
+
import download from 'download-git-repo';
|
|
19
|
+
import rm from 'rimraf';
|
|
20
|
+
import dayjs from 'dayjs';
|
|
21
|
+
import util from 'util';
|
|
22
|
+
import crypto from 'crypto';
|
|
23
|
+
import mime from 'mime-types';
|
|
24
|
+
import qiniu from 'qiniu';
|
|
25
|
+
import MD5 from 'md5';
|
|
26
|
+
import resolve from 'resolve';
|
|
27
|
+
import { merge, get, set, unset } from 'lodash';
|
|
28
|
+
import { spawn } from 'child_process';
|
|
29
|
+
import isWsl from 'is-wsl';
|
|
30
|
+
import axios from 'axios';
|
|
31
|
+
import FormData from 'form-data';
|
|
32
|
+
import https from 'https';
|
|
33
|
+
import tunnel from 'tunnel';
|
|
34
|
+
import { JSONStore } from '@picgo/store';
|
|
35
|
+
import spawn$1 from 'cross-spawn';
|
|
36
|
+
import yaml from 'js-yaml';
|
|
37
|
+
import { ObjectAdapter, I18n } from '@picgo/i18n';
|
|
38
|
+
|
|
39
|
+
const pluginHandler = {
|
|
40
|
+
handle: (ctx) => {
|
|
41
|
+
// const pluginHandler = new PluginHandler(ctx)
|
|
42
|
+
const cmd = ctx.cmd;
|
|
43
|
+
cmd.program
|
|
44
|
+
.command('install <plugins...>')
|
|
45
|
+
.description('install picgo plugin')
|
|
46
|
+
.alias('add')
|
|
47
|
+
.option('-p, --proxy <proxy>', 'Add proxy for installing')
|
|
48
|
+
.option('-r, --registry <registry>', 'Choose a registry for installing')
|
|
49
|
+
.action((plugins, program) => {
|
|
50
|
+
const { proxy, registry } = program;
|
|
51
|
+
const options = {
|
|
52
|
+
proxy,
|
|
53
|
+
registry
|
|
54
|
+
};
|
|
55
|
+
ctx.pluginHandler.install(plugins, options).catch((e) => { ctx.log.error(e); });
|
|
56
|
+
});
|
|
57
|
+
cmd.program
|
|
58
|
+
.command('uninstall <plugins...>')
|
|
59
|
+
.alias('rm')
|
|
60
|
+
.description('uninstall picgo plugin')
|
|
61
|
+
.action((plugins) => {
|
|
62
|
+
ctx.pluginHandler.uninstall(plugins).catch((e) => { ctx.log.error(e); });
|
|
63
|
+
});
|
|
64
|
+
cmd.program
|
|
65
|
+
.command('update <plugins...>')
|
|
66
|
+
.description('update picgo plugin')
|
|
67
|
+
.option('-p, --proxy <proxy>', 'Add proxy for installing')
|
|
68
|
+
.option('-r, --registry <registry>', 'Choose a registry for installing')
|
|
69
|
+
.action((plugins, program) => {
|
|
70
|
+
const { proxy, registry } = program;
|
|
71
|
+
const options = {
|
|
72
|
+
proxy,
|
|
73
|
+
registry
|
|
74
|
+
};
|
|
75
|
+
ctx.pluginHandler.update(plugins, options).catch((e) => { ctx.log.error(e); });
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const config$7 = {
|
|
81
|
+
handle: (ctx) => {
|
|
82
|
+
const cmd = ctx.cmd;
|
|
83
|
+
cmd.program
|
|
84
|
+
.option('-c, --config <path>', 'set config path');
|
|
85
|
+
// will handle in `bin/picgo`
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const isUrl = (url) => (url.startsWith('http://') || url.startsWith('https://'));
|
|
90
|
+
const isUrlEncode = (url) => {
|
|
91
|
+
url = url || '';
|
|
92
|
+
try {
|
|
93
|
+
// the whole url encode or decode shold not use encodeURIComponent or decodeURIComponent
|
|
94
|
+
return url !== decodeURI(url);
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
// if some error caught, try to let it go
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const handleUrlEncode = (url) => {
|
|
102
|
+
if (!isUrlEncode(url)) {
|
|
103
|
+
url = encodeURI(url);
|
|
104
|
+
}
|
|
105
|
+
return url;
|
|
106
|
+
};
|
|
107
|
+
const getImageSize = (file) => {
|
|
108
|
+
try {
|
|
109
|
+
const { width = 0, height = 0 } = imageSize(file);
|
|
110
|
+
return {
|
|
111
|
+
real: true,
|
|
112
|
+
width,
|
|
113
|
+
height
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
// fallback to 200 * 200
|
|
118
|
+
return {
|
|
119
|
+
real: false,
|
|
120
|
+
width: 200,
|
|
121
|
+
height: 200
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const getFSFile = async (filePath) => {
|
|
126
|
+
try {
|
|
127
|
+
return {
|
|
128
|
+
extname: path.extname(filePath),
|
|
129
|
+
fileName: path.basename(filePath),
|
|
130
|
+
buffer: await fs.readFile(filePath),
|
|
131
|
+
success: true
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
catch (_a) {
|
|
135
|
+
return {
|
|
136
|
+
reason: `read file ${filePath} error`,
|
|
137
|
+
success: false
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
const getURLFile = async (url, ctx) => {
|
|
142
|
+
url = handleUrlEncode(url);
|
|
143
|
+
let isImage = false;
|
|
144
|
+
let extname = '';
|
|
145
|
+
let timeoutId;
|
|
146
|
+
const requestFn = new Promise((resolve, reject) => {
|
|
147
|
+
(async () => {
|
|
148
|
+
var _a;
|
|
149
|
+
try {
|
|
150
|
+
const res = await ctx.request({
|
|
151
|
+
method: 'get',
|
|
152
|
+
url,
|
|
153
|
+
resolveWithFullResponse: true,
|
|
154
|
+
responseType: 'arraybuffer'
|
|
155
|
+
})
|
|
156
|
+
.then((resp) => {
|
|
157
|
+
const contentType = resp.headers['content-type'];
|
|
158
|
+
if (contentType === null || contentType === void 0 ? void 0 : contentType.includes('image')) {
|
|
159
|
+
isImage = true;
|
|
160
|
+
extname = `.${contentType.split('image/')[1]}`;
|
|
161
|
+
}
|
|
162
|
+
return resp.data;
|
|
163
|
+
});
|
|
164
|
+
clearTimeout(timeoutId);
|
|
165
|
+
if (isImage) {
|
|
166
|
+
const urlPath = new URL(url).pathname;
|
|
167
|
+
resolve({
|
|
168
|
+
buffer: res,
|
|
169
|
+
fileName: path.basename(urlPath),
|
|
170
|
+
extname,
|
|
171
|
+
success: true
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
resolve({
|
|
176
|
+
success: false,
|
|
177
|
+
reason: `${url} is not image`
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
clearTimeout(timeoutId);
|
|
183
|
+
resolve({
|
|
184
|
+
success: false,
|
|
185
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
186
|
+
reason: `request ${url} error, ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : ''}`
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
})().catch(reject);
|
|
190
|
+
});
|
|
191
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
192
|
+
timeoutId = setTimeout(() => {
|
|
193
|
+
resolve({
|
|
194
|
+
success: false,
|
|
195
|
+
reason: `request ${url} timeout`
|
|
196
|
+
});
|
|
197
|
+
}, 10000);
|
|
198
|
+
});
|
|
199
|
+
return Promise.race([requestFn, timeoutPromise]);
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* detect the input string's type
|
|
203
|
+
* for example
|
|
204
|
+
* 1. @xxx/picgo-plugin-xxx -> scope
|
|
205
|
+
* 2. picgo-plugin-xxx -> normal
|
|
206
|
+
* 3. xxx -> simple
|
|
207
|
+
* 4. not exists or is a path -> unknown
|
|
208
|
+
* @param name
|
|
209
|
+
*/
|
|
210
|
+
const getPluginNameType = (name) => {
|
|
211
|
+
if (/^@[^/]+\/picgo-plugin-/.test(name)) {
|
|
212
|
+
return 'scope';
|
|
213
|
+
}
|
|
214
|
+
else if (name.startsWith('picgo-plugin-')) {
|
|
215
|
+
return 'normal';
|
|
216
|
+
}
|
|
217
|
+
else if (isSimpleName(name)) {
|
|
218
|
+
return 'simple';
|
|
219
|
+
}
|
|
220
|
+
return 'unknown';
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* detect the input string is a simple plugin name or not
|
|
224
|
+
* for example
|
|
225
|
+
* 1. xxx -> true
|
|
226
|
+
* 2. /Usr/xx/xxxx/picgo-plugin-xxx -> false
|
|
227
|
+
* @param name pluginNameOrPath
|
|
228
|
+
*/
|
|
229
|
+
const isSimpleName = (nameOrPath) => {
|
|
230
|
+
if (path.isAbsolute(nameOrPath)) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
const pluginPath = path.join(process.cwd(), nameOrPath);
|
|
234
|
+
if (fs.existsSync(pluginPath)) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
if (nameOrPath.includes('/') || nameOrPath.includes('\\')) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
return true;
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* complete plugin name to full name
|
|
244
|
+
* for example:
|
|
245
|
+
* 1. xxx -> picgo-plugin-xxx
|
|
246
|
+
* 2. picgo-plugin-xxx -> picgo-plugin-xxx
|
|
247
|
+
* @param name pluginSimpleName
|
|
248
|
+
* @param scope pluginScope
|
|
249
|
+
*/
|
|
250
|
+
const handleCompletePluginName = (name, scope = '') => {
|
|
251
|
+
if (scope) {
|
|
252
|
+
return `@${scope}/picgo-plugin-${name}`;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
return `picgo-plugin-${name}`;
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
/**
|
|
259
|
+
* handle install/uninstall/update plugin name or path
|
|
260
|
+
* for example
|
|
261
|
+
* 1. picgo-plugin-xxx -> picgo-plugin-xxx
|
|
262
|
+
* 2. @xxx/picgo-plugin-xxx -> @xxx/picgo-plugin-xxx
|
|
263
|
+
* 3. xxx -> picgo-plugin-xxx
|
|
264
|
+
* 4. ./xxxx/picgo-plugin-xxx -> /absolutePath/.../xxxx/picgo-plugin-xxx
|
|
265
|
+
* 5. /absolutePath/.../picgo-plugin-xxx -> /absolutePath/.../picgo-plugin-xxx
|
|
266
|
+
* @param nameOrPath pluginName or pluginPath
|
|
267
|
+
*/
|
|
268
|
+
const getProcessPluginName = (nameOrPath, logger = console) => {
|
|
269
|
+
const pluginNameType = getPluginNameType(nameOrPath);
|
|
270
|
+
switch (pluginNameType) {
|
|
271
|
+
case 'normal':
|
|
272
|
+
case 'scope':
|
|
273
|
+
return nameOrPath;
|
|
274
|
+
case 'simple':
|
|
275
|
+
return handleCompletePluginName(nameOrPath);
|
|
276
|
+
default: {
|
|
277
|
+
// now, the pluginNameType is unknow here
|
|
278
|
+
// 1. check if is an absolute path
|
|
279
|
+
let pluginPath = nameOrPath;
|
|
280
|
+
if (path.isAbsolute(nameOrPath) && fs.existsSync(nameOrPath)) {
|
|
281
|
+
return handleUnixStylePath(pluginPath);
|
|
282
|
+
}
|
|
283
|
+
// 2. check if is a relative path
|
|
284
|
+
pluginPath = path.join(process.cwd(), nameOrPath);
|
|
285
|
+
if (fs.existsSync(pluginPath)) {
|
|
286
|
+
return handleUnixStylePath(pluginPath);
|
|
287
|
+
}
|
|
288
|
+
// 3. invalid nameOrPath
|
|
289
|
+
logger.warn(`Can't find plugin ${nameOrPath}`);
|
|
290
|
+
return '';
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
/**
|
|
295
|
+
* get the normal plugin name
|
|
296
|
+
* for example:
|
|
297
|
+
* 1. picgo-plugin-xxx -> picgo-plugin-xxx
|
|
298
|
+
* 2. @xxx/picgo-plugin-xxx -> @xxx/picgo-plugin-xxx
|
|
299
|
+
* 3. ./xxxx/picgo-plugin-xxx -> picgo-plugin-xxx
|
|
300
|
+
* 4. /absolutePath/.../picgo-plugin-xxx -> picgo-plugin-xxx
|
|
301
|
+
* 5. an exception: [package.json's name] !== [folder name]
|
|
302
|
+
* then use [package.json's name], usually match the scope package.
|
|
303
|
+
* 6. if plugin name has version: picgo-plugin-xxx@x.x.x then remove the version
|
|
304
|
+
* @param nameOrPath
|
|
305
|
+
*/
|
|
306
|
+
const getNormalPluginName = (nameOrPath, logger = console) => {
|
|
307
|
+
var _a;
|
|
308
|
+
const pluginNameType = getPluginNameType(nameOrPath);
|
|
309
|
+
switch (pluginNameType) {
|
|
310
|
+
case 'normal':
|
|
311
|
+
return removePluginVersion(nameOrPath);
|
|
312
|
+
case 'scope':
|
|
313
|
+
return removePluginVersion(nameOrPath, true);
|
|
314
|
+
case 'simple':
|
|
315
|
+
return removePluginVersion(handleCompletePluginName(nameOrPath));
|
|
316
|
+
default: {
|
|
317
|
+
// now, the nameOrPath must be path
|
|
318
|
+
// the nameOrPath here will be ensured with unix style
|
|
319
|
+
// we need to find the package.json's name cause npm using the name in package.json's name filed
|
|
320
|
+
if (!fs.existsSync(nameOrPath)) {
|
|
321
|
+
logger.warn(`Can't find plugin: ${nameOrPath}`);
|
|
322
|
+
return '';
|
|
323
|
+
}
|
|
324
|
+
const packageJSONPath = path.posix.join(nameOrPath, 'package.json');
|
|
325
|
+
if (!fs.existsSync(packageJSONPath)) {
|
|
326
|
+
logger.warn(`Can't find plugin: ${nameOrPath}`);
|
|
327
|
+
return '';
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
const pkg = fs.readJSONSync(packageJSONPath) || {};
|
|
331
|
+
if (!((_a = pkg.name) === null || _a === void 0 ? void 0 : _a.includes('picgo-plugin-'))) {
|
|
332
|
+
logger.warn(`The plugin package.json's name filed is ${pkg.name || 'empty'}, need to include the prefix: picgo-plugin-`);
|
|
333
|
+
return '';
|
|
334
|
+
}
|
|
335
|
+
return pkg.name;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* handle transform the path to unix style
|
|
342
|
+
* for example
|
|
343
|
+
* 1. C:\\xxx\\xxx -> C:/xxx/xxx
|
|
344
|
+
* 2. /xxx/xxx -> /xxx/xxx
|
|
345
|
+
* @param path
|
|
346
|
+
*/
|
|
347
|
+
const handleUnixStylePath = (pathStr) => {
|
|
348
|
+
const pathArr = pathStr.split(path.sep);
|
|
349
|
+
return pathArr.join('/');
|
|
350
|
+
};
|
|
351
|
+
/**
|
|
352
|
+
* remove plugin version when register plugin name
|
|
353
|
+
* 1. picgo-plugin-xxx@1.0.0 -> picgo-plugin-xxx
|
|
354
|
+
* 2. @xxx/picgo-plugin-xxx@1.0.0 -> @xxx/picgo-plugin-xxx
|
|
355
|
+
* @param nameOrPath
|
|
356
|
+
* @param scope
|
|
357
|
+
*/
|
|
358
|
+
const removePluginVersion = (nameOrPath, scope = false) => {
|
|
359
|
+
if (!nameOrPath.includes('@')) {
|
|
360
|
+
return nameOrPath;
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
let reg = /(.+\/)?(picgo-plugin-\w+)(@.+)*/;
|
|
364
|
+
// if is a scope pkg
|
|
365
|
+
if (scope) {
|
|
366
|
+
reg = /(.+\/)?(^@[^/]+\/picgo-plugin-\w+)(@.+)*/;
|
|
367
|
+
}
|
|
368
|
+
const matchArr = nameOrPath.match(reg);
|
|
369
|
+
if (!matchArr) {
|
|
370
|
+
console.warn('can not remove plugin version');
|
|
371
|
+
return nameOrPath;
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
return matchArr[2];
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* the config black item list which won't be setted
|
|
380
|
+
* only can be got
|
|
381
|
+
*/
|
|
382
|
+
const configBlackList = [];
|
|
383
|
+
/**
|
|
384
|
+
* check some config key is in blackList
|
|
385
|
+
* @param key
|
|
386
|
+
*/
|
|
387
|
+
const isConfigKeyInBlackList = (key) => {
|
|
388
|
+
return configBlackList.some(blackItem => key.startsWith(blackItem));
|
|
389
|
+
};
|
|
390
|
+
/**
|
|
391
|
+
* check the input config is valid
|
|
392
|
+
* config must be object such as { xxx: 'xxx' }
|
|
393
|
+
* && can't be array
|
|
394
|
+
* @param config
|
|
395
|
+
* @returns
|
|
396
|
+
*/
|
|
397
|
+
const isInputConfigValid = (config) => {
|
|
398
|
+
if (typeof config === 'object' &&
|
|
399
|
+
!Array.isArray(config) &&
|
|
400
|
+
Object.keys(config).length > 0) {
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
return false;
|
|
404
|
+
};
|
|
405
|
+
function safeParse(str) {
|
|
406
|
+
try {
|
|
407
|
+
return JSON.parse(str);
|
|
408
|
+
}
|
|
409
|
+
catch (error) {
|
|
410
|
+
return str;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
// hold...
|
|
414
|
+
// export const configWhiteList: RegExp[] = [
|
|
415
|
+
// /^picBed/,
|
|
416
|
+
// /^picgoPlugins/,
|
|
417
|
+
// /^@[^/]+\/picgo-plugin-/,
|
|
418
|
+
// /debug/,
|
|
419
|
+
// /silent/,
|
|
420
|
+
// /configPath/,
|
|
421
|
+
// /^settings/,
|
|
422
|
+
// ]
|
|
423
|
+
// export const isConfigKeyInWhiteList = (key: string): boolean => {
|
|
424
|
+
// return configWhiteList.some(whiteItem => whiteItem.test(key))
|
|
425
|
+
// }
|
|
426
|
+
const forceNumber = (num = 0) => {
|
|
427
|
+
return isNaN(Number(num)) ? 0 : Number(num);
|
|
428
|
+
};
|
|
429
|
+
const isDev = () => {
|
|
430
|
+
return process.env.NODE_ENV === 'development';
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
const upload = {
|
|
434
|
+
handle: (ctx) => {
|
|
435
|
+
const cmd = ctx.cmd;
|
|
436
|
+
cmd.program
|
|
437
|
+
.command('upload')
|
|
438
|
+
.description('upload, go go go')
|
|
439
|
+
.arguments('[input...]')
|
|
440
|
+
.alias('u')
|
|
441
|
+
.action((input) => {
|
|
442
|
+
(async () => {
|
|
443
|
+
const inputList = input
|
|
444
|
+
.map((item) => {
|
|
445
|
+
return isUrl(item) ? item : path.resolve(item);
|
|
446
|
+
})
|
|
447
|
+
.filter((item) => {
|
|
448
|
+
const exist = fs.existsSync(item) || isUrl(item);
|
|
449
|
+
if (!exist) {
|
|
450
|
+
ctx.log.warn(`${item} does not exist.`);
|
|
451
|
+
}
|
|
452
|
+
return exist;
|
|
453
|
+
});
|
|
454
|
+
await ctx.upload(inputList);
|
|
455
|
+
})().catch((e) => { ctx.log.error(e); });
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
// handle modules config -> save to picgo config file
|
|
461
|
+
const handleConfig = async (ctx, prompts, module, name) => {
|
|
462
|
+
const answer = await ctx.cmd.inquirer.prompt(prompts);
|
|
463
|
+
const configName = module === 'uploader'
|
|
464
|
+
? `picBed.${name}` : module === 'transformer'
|
|
465
|
+
? `transformer.${name}` : name;
|
|
466
|
+
ctx.saveConfig({
|
|
467
|
+
[configName]: answer
|
|
468
|
+
});
|
|
469
|
+
};
|
|
470
|
+
const setting = {
|
|
471
|
+
handle: (ctx) => {
|
|
472
|
+
const cmd = ctx.cmd;
|
|
473
|
+
cmd.program
|
|
474
|
+
.command('set')
|
|
475
|
+
.alias('config')
|
|
476
|
+
.arguments('<module> [name]')
|
|
477
|
+
.description('configure config of picgo modules')
|
|
478
|
+
.action((module, name) => {
|
|
479
|
+
(async () => {
|
|
480
|
+
var _a, _b;
|
|
481
|
+
try {
|
|
482
|
+
// // load third-party plugins
|
|
483
|
+
// await ctx.pluginLoader.load()
|
|
484
|
+
// if a module is specific, then just set this option in config
|
|
485
|
+
switch (module) {
|
|
486
|
+
case 'uploader':
|
|
487
|
+
case 'transformer':
|
|
488
|
+
if (name) {
|
|
489
|
+
const item = ctx.helper[module].get(name);
|
|
490
|
+
if (!item) {
|
|
491
|
+
return ctx.log.error(`No ${module} named ${name}`);
|
|
492
|
+
}
|
|
493
|
+
if (item.config) {
|
|
494
|
+
await handleConfig(ctx, item.config(ctx), module, name);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
const prompts = [
|
|
499
|
+
{
|
|
500
|
+
type: 'list',
|
|
501
|
+
name: `${module}`,
|
|
502
|
+
choices: ctx.helper[module].getIdList(),
|
|
503
|
+
message: `Choose a(n) ${module}`
|
|
504
|
+
// default: ctx.getConfig('picBed.uploader') || ctx.getConfig('picBed.current')
|
|
505
|
+
}
|
|
506
|
+
];
|
|
507
|
+
const answer = await ctx.cmd.inquirer.prompt(prompts);
|
|
508
|
+
const item = ctx.helper[module].get(answer[module]);
|
|
509
|
+
if (item === null || item === void 0 ? void 0 : item.config) {
|
|
510
|
+
await handleConfig(ctx, item.config(ctx), module, answer[module]);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
break;
|
|
514
|
+
case 'plugin':
|
|
515
|
+
if (name) {
|
|
516
|
+
if (!name.includes('picgo-plugin-')) {
|
|
517
|
+
name = `picgo-plugin-${name}`;
|
|
518
|
+
}
|
|
519
|
+
if (Object.keys(ctx.getConfig('picgoPlugins')).includes(name)) {
|
|
520
|
+
if ((_a = ctx.pluginLoader.getPlugin(name)) === null || _a === void 0 ? void 0 : _a.config) {
|
|
521
|
+
await handleConfig(ctx, ctx.pluginLoader.getPlugin(name).config(ctx), 'plugin', name);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
return ctx.log.error(`No plugin named ${name}`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
const prompts = [
|
|
530
|
+
{
|
|
531
|
+
type: 'list',
|
|
532
|
+
name: 'plugin',
|
|
533
|
+
choices: ctx.pluginLoader.getFullList(),
|
|
534
|
+
message: 'Choose a plugin'
|
|
535
|
+
}
|
|
536
|
+
];
|
|
537
|
+
const answer = await ctx.cmd.inquirer.prompt(prompts);
|
|
538
|
+
if ((_b = ctx.pluginLoader.getPlugin(answer.plugin)) === null || _b === void 0 ? void 0 : _b.config) {
|
|
539
|
+
await handleConfig(ctx, ctx.pluginLoader.getPlugin(answer.plugin).config(ctx), 'plugin', answer.plugin);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
break;
|
|
543
|
+
default:
|
|
544
|
+
ctx.log.warn(`No module named ${module}`);
|
|
545
|
+
return ctx.log.warn('Available modules are uploader|transformer|plugin');
|
|
546
|
+
}
|
|
547
|
+
const useModuleName = module === 'plugin' ? 'plugins' : module;
|
|
548
|
+
ctx.log.success('Configure config successfully!');
|
|
549
|
+
ctx.log.info(`If you want to use this config, please run 'picgo use ${useModuleName}'`);
|
|
550
|
+
}
|
|
551
|
+
catch (e) {
|
|
552
|
+
ctx.log.error(e);
|
|
553
|
+
if (process.argv.includes('--debug')) {
|
|
554
|
+
throw e;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
})().catch((e) => { ctx.log.error(e); });
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
const use = {
|
|
563
|
+
handle: async (ctx) => {
|
|
564
|
+
const cmd = ctx.cmd;
|
|
565
|
+
cmd.program
|
|
566
|
+
.command('use')
|
|
567
|
+
.arguments('[module]')
|
|
568
|
+
.description('use modules of picgo')
|
|
569
|
+
.action((module) => {
|
|
570
|
+
(async () => {
|
|
571
|
+
try {
|
|
572
|
+
// // load third-party plugins
|
|
573
|
+
// await ctx.pluginLoader.load()
|
|
574
|
+
let prompts = [];
|
|
575
|
+
const config = {
|
|
576
|
+
uploader: {
|
|
577
|
+
type: 'list',
|
|
578
|
+
name: 'uploader',
|
|
579
|
+
message: 'Use an uploader',
|
|
580
|
+
choices: ctx.helper.uploader.getIdList(),
|
|
581
|
+
default: ctx.getConfig('picBed.uploader') || ctx.getConfig('picBed.current') || 'smms'
|
|
582
|
+
},
|
|
583
|
+
transformer: {
|
|
584
|
+
type: 'list',
|
|
585
|
+
name: 'transformer',
|
|
586
|
+
message: 'Use a transformer',
|
|
587
|
+
choices: ctx.helper.transformer.getIdList(),
|
|
588
|
+
default: ctx.getConfig('picBed.transformer') || 'path'
|
|
589
|
+
},
|
|
590
|
+
plugins: {
|
|
591
|
+
type: 'checkbox',
|
|
592
|
+
name: 'plugins',
|
|
593
|
+
message: 'Use plugins',
|
|
594
|
+
choices: ctx.pluginLoader.getFullList(),
|
|
595
|
+
default: Object.keys(ctx.getConfig('picgoPlugins')).filter((item) => ctx.getConfig(`picgoPlugins.${item}`))
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
// if an option is specific, then just set this option in config
|
|
599
|
+
if (module) {
|
|
600
|
+
if (config[module]) {
|
|
601
|
+
prompts.push(config[module]);
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
ctx.log.warn(`No module named ${module}`);
|
|
605
|
+
return ctx.log.warn('Available modules are uploader|transformer|plugins');
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
prompts = Object.keys(config).map((item) => config[item]);
|
|
610
|
+
}
|
|
611
|
+
const answer = await cmd.inquirer.prompt(prompts);
|
|
612
|
+
// handle for plugins option from Array to object
|
|
613
|
+
if (answer.plugins) {
|
|
614
|
+
const plugins = ctx.getConfig('picgoPlugins');
|
|
615
|
+
Object.keys(plugins).map((item) => {
|
|
616
|
+
if (answer.plugins.includes(item)) {
|
|
617
|
+
plugins[item] = true;
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
plugins[item] = false;
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
// save config for plugins
|
|
624
|
+
ctx.saveConfig({
|
|
625
|
+
picgoPlugins: plugins
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
// save config for uploader & transformer
|
|
629
|
+
ctx.saveConfig({
|
|
630
|
+
'picBed.current': answer.uploader || ctx.getConfig('picBed.current'),
|
|
631
|
+
'picBed.uploader': answer.uploader || ctx.getConfig('picBed.current'),
|
|
632
|
+
'picBed.transformer': answer.transformer || 'path'
|
|
633
|
+
});
|
|
634
|
+
ctx.log.success('Configure config successfully!');
|
|
635
|
+
}
|
|
636
|
+
catch (e) {
|
|
637
|
+
ctx.log.error(e);
|
|
638
|
+
if (process.argv.includes('--debug')) {
|
|
639
|
+
throw e;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
})().catch((e) => { ctx.log.error(e); });
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
const proxy = {
|
|
648
|
+
handle: (ctx) => {
|
|
649
|
+
const cmd = ctx.cmd;
|
|
650
|
+
cmd.program
|
|
651
|
+
.option('-p, --proxy <url>', 'set proxy for uploading', (proxy) => {
|
|
652
|
+
ctx.setConfig({
|
|
653
|
+
'picBed.proxy': proxy
|
|
654
|
+
});
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Generate template files to destination files.
|
|
661
|
+
* @param {PicGo} ctx
|
|
662
|
+
* @param {IOptions} options
|
|
663
|
+
*/
|
|
664
|
+
const generate = async (ctx, options) => {
|
|
665
|
+
try {
|
|
666
|
+
const opts = getOptions(options.tmp);
|
|
667
|
+
const source = path.join(options.tmp, 'template');
|
|
668
|
+
let answers = {};
|
|
669
|
+
if (opts.prompts && opts.prompts.length > 0) {
|
|
670
|
+
answers = await ctx.cmd.inquirer.prompt(opts.prompts);
|
|
671
|
+
}
|
|
672
|
+
let _files = await globby(['**/*'], { cwd: source, dot: true }); // get files' name array
|
|
673
|
+
_files = _files.filter((item) => {
|
|
674
|
+
let glob = '';
|
|
675
|
+
Object.keys(opts.filters).forEach((key) => {
|
|
676
|
+
if (match(item, key, { dot: true })) {
|
|
677
|
+
glob = item;
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
if (glob) { // find a filter expression
|
|
681
|
+
return filters(ctx, opts.filters[glob], answers);
|
|
682
|
+
}
|
|
683
|
+
else {
|
|
684
|
+
return true;
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
if (_files.length === 0) {
|
|
688
|
+
return ctx.log.warn('Template files not found!');
|
|
689
|
+
}
|
|
690
|
+
const files = render(_files, source, answers);
|
|
691
|
+
writeFileTree(options.dest, files);
|
|
692
|
+
if (typeof opts.complete === 'function') {
|
|
693
|
+
opts.complete({ answers, options, files: _files, ctx });
|
|
694
|
+
}
|
|
695
|
+
if (opts.completeMessage) {
|
|
696
|
+
ctx.log.success(opts.completeMessage);
|
|
697
|
+
}
|
|
698
|
+
ctx.log.success('Done!');
|
|
699
|
+
}
|
|
700
|
+
catch (e) {
|
|
701
|
+
return ctx.log.error(e);
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
/**
|
|
705
|
+
* Return the filters' result
|
|
706
|
+
* @param ctx PicGo
|
|
707
|
+
* @param exp condition expression
|
|
708
|
+
* @param data options data
|
|
709
|
+
*/
|
|
710
|
+
const filters = (ctx, exp, data) => {
|
|
711
|
+
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands, no-new-func, @typescript-eslint/no-implied-eval
|
|
712
|
+
const fn = new Function('data', 'with (data) { return ' + exp + '}');
|
|
713
|
+
try {
|
|
714
|
+
return fn(data);
|
|
715
|
+
}
|
|
716
|
+
catch (e) {
|
|
717
|
+
ctx.log.error(`Error when evaluating filter condition: ${JSON.stringify(exp)}`);
|
|
718
|
+
return false;
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
/**
|
|
722
|
+
* Get template options
|
|
723
|
+
* @param {string} templatePath
|
|
724
|
+
*/
|
|
725
|
+
const getOptions = (templatePath) => {
|
|
726
|
+
const optionsPath = path.join(templatePath, 'index.js');
|
|
727
|
+
if (fs.existsSync(optionsPath)) {
|
|
728
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
729
|
+
const options = require(optionsPath);
|
|
730
|
+
return options;
|
|
731
|
+
}
|
|
732
|
+
else {
|
|
733
|
+
return {};
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
/**
|
|
737
|
+
* Render files to a virtual tree object
|
|
738
|
+
* @param {array} files
|
|
739
|
+
*/
|
|
740
|
+
const render = (files, source, options) => {
|
|
741
|
+
const fileTree = {};
|
|
742
|
+
files.forEach((filePath) => {
|
|
743
|
+
const file = fs.readFileSync(path.join(source, filePath), 'utf8');
|
|
744
|
+
const content = ejs.render(file, options);
|
|
745
|
+
if (Buffer.isBuffer(content) || /[^\s]/.test(content)) {
|
|
746
|
+
fileTree[filePath] = content;
|
|
747
|
+
}
|
|
748
|
+
});
|
|
749
|
+
return fileTree;
|
|
750
|
+
};
|
|
751
|
+
/**
|
|
752
|
+
* Write rendered files' content to real file
|
|
753
|
+
* @param {string} dir
|
|
754
|
+
* @param {object} files
|
|
755
|
+
*/
|
|
756
|
+
const writeFileTree = (dir, files) => {
|
|
757
|
+
Object.keys(files).forEach((name) => {
|
|
758
|
+
const filePath = path.join(dir, name);
|
|
759
|
+
fs.ensureDirSync(path.dirname(filePath));
|
|
760
|
+
fs.writeFileSync(filePath, files[name]);
|
|
761
|
+
});
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
const run = (ctx, options) => {
|
|
765
|
+
// const name = options.inPlace ? path.relative('../', process.cwd()) : options.project
|
|
766
|
+
if (options.offline) { // offline mode
|
|
767
|
+
if (fs.existsSync(options.template)) {
|
|
768
|
+
generate(ctx, options).catch((e) => { ctx.log.error(e); });
|
|
769
|
+
}
|
|
770
|
+
else {
|
|
771
|
+
ctx.log.error(`Local template ${options.template} not found`);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
else { // online mode
|
|
775
|
+
options.template = !options.hasSlash
|
|
776
|
+
? 'PicGo/picgo-template-' + options.template // official template
|
|
777
|
+
: options.template;
|
|
778
|
+
downloadAndGenerate(ctx, options);
|
|
779
|
+
}
|
|
780
|
+
};
|
|
781
|
+
/**
|
|
782
|
+
* download template & generate
|
|
783
|
+
* @param { PicGo } ctx
|
|
784
|
+
* @param { IOptions } options
|
|
785
|
+
*/
|
|
786
|
+
const downloadAndGenerate = (ctx, options) => {
|
|
787
|
+
if (fs.existsSync(options.tmp)) {
|
|
788
|
+
rm.sync(options.tmp);
|
|
789
|
+
}
|
|
790
|
+
ctx.log.info('Template files are downloading...');
|
|
791
|
+
download(options.template, options.tmp, { clone: options.clone }, (err) => {
|
|
792
|
+
if (err) {
|
|
793
|
+
return ctx.log.error(err);
|
|
794
|
+
}
|
|
795
|
+
ctx.log.success('Template files are downloaded!');
|
|
796
|
+
generate(ctx, options).catch((e) => { ctx.log.error(e); });
|
|
797
|
+
});
|
|
798
|
+
};
|
|
799
|
+
const init = {
|
|
800
|
+
handle: async (ctx) => {
|
|
801
|
+
const cmd = ctx.cmd;
|
|
802
|
+
cmd.program
|
|
803
|
+
.command('init')
|
|
804
|
+
.arguments('<template> [project]')
|
|
805
|
+
.option('--clone', 'use git clone')
|
|
806
|
+
.option('--offline', 'use cached template')
|
|
807
|
+
.description('create picgo plugin\'s development templates')
|
|
808
|
+
.action((template, project, program) => {
|
|
809
|
+
(async () => {
|
|
810
|
+
// Thanks to vue-cli init: https://github.com/vuejs/vue-cli/blob/master/bin/vue-init
|
|
811
|
+
try {
|
|
812
|
+
const hasSlash = template.includes('/');
|
|
813
|
+
const inPlace = !project || project === '.';
|
|
814
|
+
const dest = path.resolve(project || '.');
|
|
815
|
+
const clone = program.clone || false;
|
|
816
|
+
const offline = program.offline || false;
|
|
817
|
+
const tmp = path.join(homedir(), '.picgo/templates', template.replace(/[/:]/g, '-')); // for caching template
|
|
818
|
+
if (program.offline) {
|
|
819
|
+
template = tmp;
|
|
820
|
+
}
|
|
821
|
+
const options = {
|
|
822
|
+
template,
|
|
823
|
+
project,
|
|
824
|
+
hasSlash,
|
|
825
|
+
inPlace,
|
|
826
|
+
dest,
|
|
827
|
+
clone,
|
|
828
|
+
tmp,
|
|
829
|
+
offline
|
|
830
|
+
};
|
|
831
|
+
// check if project is empty or exist
|
|
832
|
+
if (inPlace || fs.existsSync(dest)) {
|
|
833
|
+
await ctx.cmd.inquirer.prompt([
|
|
834
|
+
{
|
|
835
|
+
type: 'confirm',
|
|
836
|
+
message: inPlace
|
|
837
|
+
? 'Generate project in current directory?'
|
|
838
|
+
: 'Target directory exists. Continue?',
|
|
839
|
+
name: 'ok'
|
|
840
|
+
}
|
|
841
|
+
]).then((answer) => {
|
|
842
|
+
if (answer.ok) {
|
|
843
|
+
run(ctx, options);
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
else { // project is given
|
|
848
|
+
run(ctx, options);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
catch (e) {
|
|
852
|
+
ctx.log.error(e);
|
|
853
|
+
if (process.argv.includes('--debug')) {
|
|
854
|
+
throw e;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
})().catch((e) => { ctx.log.error(e); });
|
|
858
|
+
})
|
|
859
|
+
.on('--help', () => {
|
|
860
|
+
console.log();
|
|
861
|
+
console.log('Examples:');
|
|
862
|
+
console.log();
|
|
863
|
+
console.log(chalk.gray(' # create a new project with an official template'));
|
|
864
|
+
console.log(' $ picgo init plugin my-project');
|
|
865
|
+
console.log();
|
|
866
|
+
console.log(chalk.gray(' # create a new project straight from a github template'));
|
|
867
|
+
console.log(' $ picgo init username/repo my-project');
|
|
868
|
+
console.log();
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
|
|
873
|
+
const i18n = {
|
|
874
|
+
handle: (ctx) => {
|
|
875
|
+
const cmd = ctx.cmd;
|
|
876
|
+
cmd.program
|
|
877
|
+
.command('i18n')
|
|
878
|
+
.arguments('[lang]')
|
|
879
|
+
.description('change picgo language')
|
|
880
|
+
.action(async (lang = '') => {
|
|
881
|
+
const list = ctx.i18n.getLanguageList();
|
|
882
|
+
if (!lang) {
|
|
883
|
+
const prompts = [
|
|
884
|
+
{
|
|
885
|
+
type: 'list',
|
|
886
|
+
name: 'i18n',
|
|
887
|
+
choices: list,
|
|
888
|
+
message: 'Choose a language',
|
|
889
|
+
default: ctx.getConfig('settings.language') || 'zh-CN'
|
|
890
|
+
}
|
|
891
|
+
];
|
|
892
|
+
const answer = await ctx.cmd.inquirer.prompt(prompts);
|
|
893
|
+
ctx.i18n.setLanguage(answer.i18n);
|
|
894
|
+
ctx.log.success(`Language set to ${answer.i18n}`);
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
if (!list.includes(lang)) {
|
|
898
|
+
return ctx.log.warn('No such language');
|
|
899
|
+
}
|
|
900
|
+
ctx.i18n.setLanguage(lang);
|
|
901
|
+
ctx.log.success(`Language set to ${lang}`);
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
var commanders = (ctx) => {
|
|
907
|
+
ctx.cmd.register('pluginHandler', pluginHandler);
|
|
908
|
+
ctx.cmd.register('config', config$7);
|
|
909
|
+
ctx.cmd.register('setting', setting);
|
|
910
|
+
ctx.cmd.register('upload', upload);
|
|
911
|
+
ctx.cmd.register('use', use);
|
|
912
|
+
ctx.cmd.register('proxy', proxy);
|
|
913
|
+
ctx.cmd.register('init', init);
|
|
914
|
+
ctx.cmd.register('i18n', i18n);
|
|
915
|
+
};
|
|
916
|
+
|
|
917
|
+
class LifecyclePlugins {
|
|
918
|
+
constructor(name) {
|
|
919
|
+
this.name = name;
|
|
920
|
+
this.list = new Map();
|
|
921
|
+
this.pluginIdMap = new Map();
|
|
922
|
+
}
|
|
923
|
+
register(id, plugin) {
|
|
924
|
+
var _a;
|
|
925
|
+
if (!id)
|
|
926
|
+
throw new TypeError('id is required!');
|
|
927
|
+
if (typeof plugin.handle !== 'function')
|
|
928
|
+
throw new TypeError('plugin.handle must be a function!');
|
|
929
|
+
if (this.list.has(id))
|
|
930
|
+
throw new TypeError(`${this.name} duplicate id: ${id}!`);
|
|
931
|
+
this.list.set(id, plugin);
|
|
932
|
+
if (LifecyclePlugins.currentPlugin) {
|
|
933
|
+
if (this.pluginIdMap.has(LifecyclePlugins.currentPlugin)) {
|
|
934
|
+
(_a = this.pluginIdMap.get(LifecyclePlugins.currentPlugin)) === null || _a === void 0 ? void 0 : _a.push(id);
|
|
935
|
+
}
|
|
936
|
+
else {
|
|
937
|
+
this.pluginIdMap.set(LifecyclePlugins.currentPlugin, [id]);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
unregister(pluginName) {
|
|
942
|
+
if (this.pluginIdMap.has(pluginName)) {
|
|
943
|
+
const pluginList = this.pluginIdMap.get(pluginName);
|
|
944
|
+
pluginList === null || pluginList === void 0 ? void 0 : pluginList.forEach((plugin) => {
|
|
945
|
+
this.list.delete(plugin);
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
getName() {
|
|
950
|
+
return this.name;
|
|
951
|
+
}
|
|
952
|
+
get(id) {
|
|
953
|
+
return this.list.get(id);
|
|
954
|
+
}
|
|
955
|
+
getList() {
|
|
956
|
+
return [...this.list.values()];
|
|
957
|
+
}
|
|
958
|
+
getIdList() {
|
|
959
|
+
return [...this.list.keys()];
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
const setCurrentPluginName = (name = null) => {
|
|
963
|
+
LifecyclePlugins.currentPlugin = name;
|
|
964
|
+
};
|
|
965
|
+
const getCurrentPluginName = () => {
|
|
966
|
+
return LifecyclePlugins.currentPlugin;
|
|
967
|
+
};
|
|
968
|
+
|
|
969
|
+
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
970
|
+
class Commander {
|
|
971
|
+
constructor(ctx) {
|
|
972
|
+
this.name = 'commander';
|
|
973
|
+
this.list = new Map();
|
|
974
|
+
this.pluginIdMap = new Map();
|
|
975
|
+
this.program = new Command();
|
|
976
|
+
this.inquirer = inquirer;
|
|
977
|
+
this.ctx = ctx;
|
|
978
|
+
}
|
|
979
|
+
getName() {
|
|
980
|
+
return this.name;
|
|
981
|
+
}
|
|
982
|
+
init() {
|
|
983
|
+
this.program
|
|
984
|
+
.version("0.0.1", '-v, --version')
|
|
985
|
+
.option('-d, --debug', 'debug mode', () => {
|
|
986
|
+
this.ctx.setConfig({
|
|
987
|
+
debug: true
|
|
988
|
+
});
|
|
989
|
+
})
|
|
990
|
+
.option('-s, --silent', 'silent mode', () => {
|
|
991
|
+
this.ctx.setConfig({
|
|
992
|
+
silent: true
|
|
993
|
+
});
|
|
994
|
+
})
|
|
995
|
+
.on('command:*', () => {
|
|
996
|
+
this.ctx.log.error(`Invalid command: ${this.program.args.join(' ')}\nSee --help for a list of available commands.`);
|
|
997
|
+
process.exit(1);
|
|
998
|
+
});
|
|
999
|
+
// built-in commands
|
|
1000
|
+
commanders(this.ctx);
|
|
1001
|
+
}
|
|
1002
|
+
register(id, plugin) {
|
|
1003
|
+
var _a;
|
|
1004
|
+
if (!id)
|
|
1005
|
+
throw new TypeError('name is required!');
|
|
1006
|
+
if (typeof plugin.handle !== 'function')
|
|
1007
|
+
throw new TypeError('plugin.handle must be a function!');
|
|
1008
|
+
if (this.list.has(id))
|
|
1009
|
+
throw new TypeError(`${this.name} plugin duplicate id: ${id}!`);
|
|
1010
|
+
this.list.set(id, plugin);
|
|
1011
|
+
const currentPluginName = getCurrentPluginName();
|
|
1012
|
+
if (currentPluginName !== null) {
|
|
1013
|
+
if (this.pluginIdMap.has(currentPluginName)) {
|
|
1014
|
+
(_a = this.pluginIdMap.get(currentPluginName)) === null || _a === void 0 ? void 0 : _a.push(id);
|
|
1015
|
+
}
|
|
1016
|
+
else {
|
|
1017
|
+
this.pluginIdMap.set(currentPluginName, [id]);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
unregister(pluginName) {
|
|
1022
|
+
if (this.pluginIdMap.has(pluginName)) {
|
|
1023
|
+
const pluginList = this.pluginIdMap.get(pluginName);
|
|
1024
|
+
pluginList === null || pluginList === void 0 ? void 0 : pluginList.forEach((plugin) => {
|
|
1025
|
+
this.list.delete(plugin);
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
loadCommands() {
|
|
1030
|
+
this.getList().forEach((item) => {
|
|
1031
|
+
try {
|
|
1032
|
+
item.handle(this.ctx);
|
|
1033
|
+
}
|
|
1034
|
+
catch (e) {
|
|
1035
|
+
this.ctx.log.error(e);
|
|
1036
|
+
}
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
get(id) {
|
|
1040
|
+
return this.list.get(id);
|
|
1041
|
+
}
|
|
1042
|
+
getList() {
|
|
1043
|
+
return [...this.list.values()];
|
|
1044
|
+
}
|
|
1045
|
+
getIdList() {
|
|
1046
|
+
return [...this.list.keys()];
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
var ILogType;
|
|
1051
|
+
(function (ILogType) {
|
|
1052
|
+
ILogType["success"] = "success";
|
|
1053
|
+
ILogType["info"] = "info";
|
|
1054
|
+
ILogType["warn"] = "warn";
|
|
1055
|
+
ILogType["error"] = "error";
|
|
1056
|
+
})(ILogType || (ILogType = {}));
|
|
1057
|
+
/**
|
|
1058
|
+
* these events will be catched by users
|
|
1059
|
+
*/
|
|
1060
|
+
var IBuildInEvent;
|
|
1061
|
+
(function (IBuildInEvent) {
|
|
1062
|
+
IBuildInEvent["UPLOAD_PROGRESS"] = "uploadProgress";
|
|
1063
|
+
IBuildInEvent["FAILED"] = "failed";
|
|
1064
|
+
IBuildInEvent["BEFORE_TRANSFORM"] = "beforeTransform";
|
|
1065
|
+
IBuildInEvent["BEFORE_UPLOAD"] = "beforeUpload";
|
|
1066
|
+
IBuildInEvent["AFTER_UPLOAD"] = "afterUpload";
|
|
1067
|
+
IBuildInEvent["FINISHED"] = "finished";
|
|
1068
|
+
IBuildInEvent["INSTALL"] = "install";
|
|
1069
|
+
IBuildInEvent["UNINSTALL"] = "uninstall";
|
|
1070
|
+
IBuildInEvent["UPDATE"] = "update";
|
|
1071
|
+
IBuildInEvent["NOTIFICATION"] = "notification";
|
|
1072
|
+
})(IBuildInEvent || (IBuildInEvent = {}));
|
|
1073
|
+
/**
|
|
1074
|
+
* these events will be catched only by picgo
|
|
1075
|
+
*/
|
|
1076
|
+
var IBusEvent;
|
|
1077
|
+
(function (IBusEvent) {
|
|
1078
|
+
IBusEvent["CONFIG_CHANGE"] = "CONFIG_CHANGE";
|
|
1079
|
+
})(IBusEvent || (IBusEvent = {}));
|
|
1080
|
+
|
|
1081
|
+
class Logger {
|
|
1082
|
+
constructor(ctx) {
|
|
1083
|
+
this.level = {
|
|
1084
|
+
[ILogType.success]: 'green',
|
|
1085
|
+
[ILogType.info]: 'blue',
|
|
1086
|
+
[ILogType.warn]: 'yellow',
|
|
1087
|
+
[ILogType.error]: 'red'
|
|
1088
|
+
};
|
|
1089
|
+
this.ctx = ctx;
|
|
1090
|
+
}
|
|
1091
|
+
handleLog(type, ...msg) {
|
|
1092
|
+
// check config.silent
|
|
1093
|
+
if (!this.ctx.getConfig('silent')) {
|
|
1094
|
+
const logHeader = chalk[this.level[type]](`[PicGo ${type.toUpperCase()}]:`);
|
|
1095
|
+
console.log(logHeader, ...msg);
|
|
1096
|
+
this.logLevel = this.ctx.getConfig('settings.logLevel');
|
|
1097
|
+
this.logPath = this.ctx.getConfig('settings.logPath') || path.join(this.ctx.baseDir, './picgo.log');
|
|
1098
|
+
setTimeout(() => {
|
|
1099
|
+
// fix log file is too large, now the log file's default size is 10 MB
|
|
1100
|
+
try {
|
|
1101
|
+
const result = this.checkLogFileIsLarge(this.logPath);
|
|
1102
|
+
if (result.isLarge) {
|
|
1103
|
+
const warningMsg = `Log file is too large (> ${(result.logFileSizeLimit) / 1024 / 1024 || '10'} MB), recreate log file`;
|
|
1104
|
+
console.log(chalk.yellow('[PicGo WARN]:'), warningMsg);
|
|
1105
|
+
this.recreateLogFile(this.logPath);
|
|
1106
|
+
msg.unshift(warningMsg);
|
|
1107
|
+
}
|
|
1108
|
+
this.handleWriteLog(this.logPath, type, ...msg);
|
|
1109
|
+
}
|
|
1110
|
+
catch (e) {
|
|
1111
|
+
// why???
|
|
1112
|
+
console.error('[PicGo Error] on checking log file size', e);
|
|
1113
|
+
}
|
|
1114
|
+
}, 0);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
checkLogFileIsLarge(logPath) {
|
|
1118
|
+
if (fs.existsSync(logPath)) {
|
|
1119
|
+
const logFileSize = fs.statSync(logPath).size;
|
|
1120
|
+
const logFileSizeLimit = forceNumber(this.ctx.getConfig('settings.logFileSizeLimit') || 10) * 1024 * 1024; // 10 MB default
|
|
1121
|
+
return {
|
|
1122
|
+
isLarge: logFileSize > logFileSizeLimit,
|
|
1123
|
+
logFileSize,
|
|
1124
|
+
logFileSizeLimit
|
|
1125
|
+
};
|
|
1126
|
+
}
|
|
1127
|
+
return {
|
|
1128
|
+
isLarge: false
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
recreateLogFile(logPath) {
|
|
1132
|
+
if (fs.existsSync(logPath)) {
|
|
1133
|
+
fs.unlinkSync(logPath);
|
|
1134
|
+
fs.createFileSync(logPath);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
handleWriteLog(logPath, type, ...msg) {
|
|
1138
|
+
try {
|
|
1139
|
+
if (this.checkLogLevel(type, this.logLevel)) {
|
|
1140
|
+
let log = `${dayjs().format('YYYY-MM-DD HH:mm:ss')} [PicGo ${type.toUpperCase()}] `;
|
|
1141
|
+
msg.forEach((item) => {
|
|
1142
|
+
if (item instanceof Error && type === 'error') {
|
|
1143
|
+
log += `\n------Error Stack Begin------\n${util.format(item === null || item === void 0 ? void 0 : item.stack)}\n-------Error Stack End------- `;
|
|
1144
|
+
}
|
|
1145
|
+
else {
|
|
1146
|
+
if (typeof item === 'object') {
|
|
1147
|
+
item = JSON.stringify(item, null, 2);
|
|
1148
|
+
}
|
|
1149
|
+
log += `${item} `;
|
|
1150
|
+
}
|
|
1151
|
+
});
|
|
1152
|
+
log += '\n';
|
|
1153
|
+
// A synchronized approach to avoid log msg sequence errors
|
|
1154
|
+
fs.appendFileSync(logPath, log);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
catch (e) {
|
|
1158
|
+
console.error('[PicGo Error] on writing log file', e);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
checkLogLevel(type, level) {
|
|
1162
|
+
if (level === undefined || level === 'all') {
|
|
1163
|
+
return true;
|
|
1164
|
+
}
|
|
1165
|
+
if (Array.isArray(level)) {
|
|
1166
|
+
return level.some((item) => (item === type || item === 'all'));
|
|
1167
|
+
}
|
|
1168
|
+
else {
|
|
1169
|
+
return type === level;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
success(...msg) {
|
|
1173
|
+
return this.handleLog(ILogType.success, ...msg);
|
|
1174
|
+
}
|
|
1175
|
+
info(...msg) {
|
|
1176
|
+
return this.handleLog(ILogType.info, ...msg);
|
|
1177
|
+
}
|
|
1178
|
+
error(...msg) {
|
|
1179
|
+
return this.handleLog(ILogType.error, ...msg);
|
|
1180
|
+
}
|
|
1181
|
+
warn(...msg) {
|
|
1182
|
+
return this.handleLog(ILogType.warn, ...msg);
|
|
1183
|
+
}
|
|
1184
|
+
debug(...msg) {
|
|
1185
|
+
if (isDev()) {
|
|
1186
|
+
this.handleLog(ILogType.info, ...msg);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/**
|
|
1192
|
+
* create an unique context for each upload process
|
|
1193
|
+
* @param ctx
|
|
1194
|
+
*/
|
|
1195
|
+
const createContext = (ctx) => {
|
|
1196
|
+
return {
|
|
1197
|
+
configPath: ctx.configPath,
|
|
1198
|
+
baseDir: ctx.baseDir,
|
|
1199
|
+
log: ctx.log,
|
|
1200
|
+
cmd: ctx.cmd,
|
|
1201
|
+
output: [],
|
|
1202
|
+
input: [],
|
|
1203
|
+
pluginLoader: ctx.pluginLoader,
|
|
1204
|
+
pluginHandler: ctx.pluginHandler,
|
|
1205
|
+
Request: ctx.Request,
|
|
1206
|
+
helper: ctx.helper,
|
|
1207
|
+
VERSION: ctx.VERSION,
|
|
1208
|
+
GUI_VERSION: ctx.GUI_VERSION,
|
|
1209
|
+
request: ctx.request,
|
|
1210
|
+
i18n: ctx.i18n,
|
|
1211
|
+
getConfig: ctx.getConfig.bind(ctx),
|
|
1212
|
+
saveConfig: ctx.saveConfig.bind(ctx),
|
|
1213
|
+
removeConfig: ctx.removeConfig.bind(ctx),
|
|
1214
|
+
setConfig: ctx.setConfig.bind(ctx),
|
|
1215
|
+
unsetConfig: ctx.unsetConfig.bind(ctx),
|
|
1216
|
+
upload: ctx.upload.bind(ctx),
|
|
1217
|
+
addListener: ctx.addListener.bind(ctx),
|
|
1218
|
+
on: ctx.on.bind(ctx),
|
|
1219
|
+
once: ctx.once.bind(ctx),
|
|
1220
|
+
removeListener: ctx.removeListener.bind(ctx),
|
|
1221
|
+
off: ctx.off.bind(ctx),
|
|
1222
|
+
removeAllListeners: ctx.removeAllListeners.bind(ctx),
|
|
1223
|
+
setMaxListeners: ctx.setMaxListeners.bind(ctx),
|
|
1224
|
+
getMaxListeners: ctx.getMaxListeners.bind(ctx),
|
|
1225
|
+
listeners: ctx.listeners.bind(ctx),
|
|
1226
|
+
rawListeners: ctx.rawListeners.bind(ctx),
|
|
1227
|
+
emit: ctx.emit.bind(ctx),
|
|
1228
|
+
listenerCount: ctx.listenerCount.bind(ctx),
|
|
1229
|
+
prependListener: ctx.prependListener.bind(ctx),
|
|
1230
|
+
prependOnceListener: ctx.prependOnceListener.bind(ctx),
|
|
1231
|
+
eventNames: ctx.eventNames.bind(ctx)
|
|
1232
|
+
};
|
|
1233
|
+
};
|
|
1234
|
+
|
|
1235
|
+
class Lifecycle extends EventEmitter {
|
|
1236
|
+
constructor(ctx) {
|
|
1237
|
+
super();
|
|
1238
|
+
this.ctx = ctx;
|
|
1239
|
+
}
|
|
1240
|
+
async start(input) {
|
|
1241
|
+
// ensure every upload process has an unique context
|
|
1242
|
+
const ctx = createContext(this.ctx);
|
|
1243
|
+
try {
|
|
1244
|
+
// images input
|
|
1245
|
+
if (!Array.isArray(input)) {
|
|
1246
|
+
throw new Error('Input must be an array.');
|
|
1247
|
+
}
|
|
1248
|
+
ctx.input = input;
|
|
1249
|
+
ctx.output = [];
|
|
1250
|
+
// lifecycle main
|
|
1251
|
+
await this.beforeTransform(ctx);
|
|
1252
|
+
await this.doTransform(ctx);
|
|
1253
|
+
await this.beforeUpload(ctx);
|
|
1254
|
+
await this.doUpload(ctx);
|
|
1255
|
+
await this.afterUpload(ctx);
|
|
1256
|
+
return ctx;
|
|
1257
|
+
}
|
|
1258
|
+
catch (e) {
|
|
1259
|
+
ctx.log.warn(IBuildInEvent.FAILED);
|
|
1260
|
+
ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, -1);
|
|
1261
|
+
ctx.emit(IBuildInEvent.FAILED, e);
|
|
1262
|
+
ctx.log.error(e);
|
|
1263
|
+
if (ctx.getConfig('debug')) {
|
|
1264
|
+
throw e;
|
|
1265
|
+
}
|
|
1266
|
+
return ctx;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
async beforeTransform(ctx) {
|
|
1270
|
+
ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 0);
|
|
1271
|
+
ctx.emit(IBuildInEvent.BEFORE_TRANSFORM, ctx);
|
|
1272
|
+
ctx.log.info('Before transform');
|
|
1273
|
+
await this.handlePlugins(ctx.helper.beforeTransformPlugins, ctx);
|
|
1274
|
+
return ctx;
|
|
1275
|
+
}
|
|
1276
|
+
async doTransform(ctx) {
|
|
1277
|
+
ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 30);
|
|
1278
|
+
const type = ctx.getConfig('picBed.transformer') || 'path';
|
|
1279
|
+
let currentTransformer = type;
|
|
1280
|
+
let transformer = ctx.helper.transformer.get(type);
|
|
1281
|
+
if (!transformer) {
|
|
1282
|
+
transformer = ctx.helper.transformer.get('path');
|
|
1283
|
+
currentTransformer = 'path';
|
|
1284
|
+
ctx.log.warn(`Can't find transformer - ${type}, switch to default transformer - path`);
|
|
1285
|
+
}
|
|
1286
|
+
ctx.log.info(`Transforming... Current transformer is [${currentTransformer}]`);
|
|
1287
|
+
await (transformer === null || transformer === void 0 ? void 0 : transformer.handle(ctx));
|
|
1288
|
+
return ctx;
|
|
1289
|
+
}
|
|
1290
|
+
async beforeUpload(ctx) {
|
|
1291
|
+
ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 60);
|
|
1292
|
+
ctx.log.info('Before upload');
|
|
1293
|
+
ctx.emit(IBuildInEvent.BEFORE_UPLOAD, ctx);
|
|
1294
|
+
await this.handlePlugins(ctx.helper.beforeUploadPlugins, ctx);
|
|
1295
|
+
return ctx;
|
|
1296
|
+
}
|
|
1297
|
+
async doUpload(ctx) {
|
|
1298
|
+
let type = ctx.getConfig('picBed.uploader') || ctx.getConfig('picBed.current') || 'smms';
|
|
1299
|
+
let uploader = ctx.helper.uploader.get(type);
|
|
1300
|
+
let currentTransformer = type;
|
|
1301
|
+
if (!uploader) {
|
|
1302
|
+
type = 'smms';
|
|
1303
|
+
currentTransformer = 'smms';
|
|
1304
|
+
uploader = ctx.helper.uploader.get('smms');
|
|
1305
|
+
ctx.log.warn(`Can't find uploader - ${type}, switch to default uploader - smms`);
|
|
1306
|
+
}
|
|
1307
|
+
ctx.log.info(`Uploading... Current uploader is [${currentTransformer}]`);
|
|
1308
|
+
await (uploader === null || uploader === void 0 ? void 0 : uploader.handle(ctx));
|
|
1309
|
+
for (const outputImg of ctx.output) {
|
|
1310
|
+
outputImg.type = type;
|
|
1311
|
+
}
|
|
1312
|
+
return ctx;
|
|
1313
|
+
}
|
|
1314
|
+
async afterUpload(ctx) {
|
|
1315
|
+
ctx.emit(IBuildInEvent.AFTER_UPLOAD, ctx);
|
|
1316
|
+
ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 100);
|
|
1317
|
+
await this.handlePlugins(ctx.helper.afterUploadPlugins, ctx);
|
|
1318
|
+
let msg = '';
|
|
1319
|
+
const length = ctx.output.length;
|
|
1320
|
+
for (let i = 0; i < length; i++) {
|
|
1321
|
+
if (typeof ctx.output[i].imgUrl !== 'undefined') {
|
|
1322
|
+
msg += handleUrlEncode(ctx.output[i].imgUrl);
|
|
1323
|
+
if (i !== length - 1) {
|
|
1324
|
+
msg += '\n';
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
delete ctx.output[i].base64Image;
|
|
1328
|
+
delete ctx.output[i].buffer;
|
|
1329
|
+
}
|
|
1330
|
+
ctx.emit(IBuildInEvent.FINISHED, ctx);
|
|
1331
|
+
ctx.log.success(`\n${msg}`);
|
|
1332
|
+
return ctx;
|
|
1333
|
+
}
|
|
1334
|
+
async handlePlugins(lifeCyclePlugins, ctx) {
|
|
1335
|
+
const plugins = lifeCyclePlugins.getList();
|
|
1336
|
+
const pluginNames = lifeCyclePlugins.getIdList();
|
|
1337
|
+
const lifeCycleName = lifeCyclePlugins.getName();
|
|
1338
|
+
await Promise.all(plugins.map(async (plugin, index) => {
|
|
1339
|
+
try {
|
|
1340
|
+
ctx.log.info(`${lifeCycleName}: ${pluginNames[index]} running`);
|
|
1341
|
+
await plugin.handle(ctx);
|
|
1342
|
+
}
|
|
1343
|
+
catch (e) {
|
|
1344
|
+
ctx.log.error(`${lifeCycleName}: ${pluginNames[index]} error`);
|
|
1345
|
+
throw e;
|
|
1346
|
+
}
|
|
1347
|
+
}));
|
|
1348
|
+
return ctx;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
const postOptions$6 = (fileName, image, apiToken, backupDomain = '') => {
|
|
1353
|
+
const domain = backupDomain || 'sm.ms';
|
|
1354
|
+
return {
|
|
1355
|
+
method: 'POST',
|
|
1356
|
+
url: `https://${domain}/api/v2/upload`,
|
|
1357
|
+
headers: {
|
|
1358
|
+
contentType: 'multipart/form-data',
|
|
1359
|
+
'User-Agent': 'PicGo',
|
|
1360
|
+
Authorization: apiToken
|
|
1361
|
+
},
|
|
1362
|
+
formData: {
|
|
1363
|
+
smfile: {
|
|
1364
|
+
value: image,
|
|
1365
|
+
options: {
|
|
1366
|
+
filename: fileName
|
|
1367
|
+
}
|
|
1368
|
+
},
|
|
1369
|
+
ssl: 'true'
|
|
1370
|
+
}
|
|
1371
|
+
};
|
|
1372
|
+
};
|
|
1373
|
+
const handle$8 = async (ctx) => {
|
|
1374
|
+
const smmsConfig = ctx.getConfig('picBed.smms');
|
|
1375
|
+
if (!smmsConfig) {
|
|
1376
|
+
throw new Error('Can not find smms config!');
|
|
1377
|
+
}
|
|
1378
|
+
const imgList = ctx.output;
|
|
1379
|
+
for (const img of imgList) {
|
|
1380
|
+
if (img.fileName && img.buffer) {
|
|
1381
|
+
let image = img.buffer;
|
|
1382
|
+
if (!image && img.base64Image) {
|
|
1383
|
+
image = Buffer.from(img.base64Image, 'base64');
|
|
1384
|
+
}
|
|
1385
|
+
const postConfig = postOptions$6(img.fileName, image, smmsConfig === null || smmsConfig === void 0 ? void 0 : smmsConfig.token, smmsConfig === null || smmsConfig === void 0 ? void 0 : smmsConfig.backupDomain);
|
|
1386
|
+
try {
|
|
1387
|
+
const res = await ctx.request(postConfig);
|
|
1388
|
+
const body = JSON.parse(res);
|
|
1389
|
+
if (body.code === 'success') {
|
|
1390
|
+
delete img.base64Image;
|
|
1391
|
+
delete img.buffer;
|
|
1392
|
+
img.imgUrl = body.data.url;
|
|
1393
|
+
}
|
|
1394
|
+
else if (body.code === 'image_repeated' && typeof body.images === 'string') { // do extra check since this error return is not documented at https://doc.sm.ms/#api-Image-Upload
|
|
1395
|
+
delete img.base64Image;
|
|
1396
|
+
delete img.buffer;
|
|
1397
|
+
img.imgUrl = body.images;
|
|
1398
|
+
}
|
|
1399
|
+
else {
|
|
1400
|
+
ctx.emit(IBuildInEvent.NOTIFICATION, {
|
|
1401
|
+
title: ctx.i18n.translate('UPLOAD_FAILED'),
|
|
1402
|
+
body: body.message
|
|
1403
|
+
});
|
|
1404
|
+
throw new Error(body);
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
catch (e) {
|
|
1408
|
+
ctx.log.error(e);
|
|
1409
|
+
throw new Error(e);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
return ctx;
|
|
1414
|
+
};
|
|
1415
|
+
const config$6 = (ctx) => {
|
|
1416
|
+
const userConfig = ctx.getConfig('picBed.smms') || {};
|
|
1417
|
+
const config = [
|
|
1418
|
+
{
|
|
1419
|
+
name: 'token',
|
|
1420
|
+
message: 'api token',
|
|
1421
|
+
type: 'password',
|
|
1422
|
+
get alias() { return ctx.i18n.translate('PICBED_SMMS_TOKEN'); },
|
|
1423
|
+
default: userConfig.token || '',
|
|
1424
|
+
required: true
|
|
1425
|
+
},
|
|
1426
|
+
{
|
|
1427
|
+
name: 'backupDomain',
|
|
1428
|
+
type: 'input',
|
|
1429
|
+
get prefix() { return ctx.i18n.translate('PICBED_SMMS_BACKUP_DOMAIN'); },
|
|
1430
|
+
get message() {
|
|
1431
|
+
return ctx.i18n.translate('PICBED_SMMS_MESSAGE_BACKUP_DOMAIN');
|
|
1432
|
+
},
|
|
1433
|
+
get alias() { return ctx.i18n.translate('PICBED_SMMS_BACKUP_DOMAIN'); },
|
|
1434
|
+
default: userConfig.backupDomain || '',
|
|
1435
|
+
required: false
|
|
1436
|
+
}
|
|
1437
|
+
];
|
|
1438
|
+
return config;
|
|
1439
|
+
};
|
|
1440
|
+
function register$6(ctx) {
|
|
1441
|
+
ctx.helper.uploader.register('smms', {
|
|
1442
|
+
get name() { return ctx.i18n.translate('PICBED_SMMS'); },
|
|
1443
|
+
handle: handle$8,
|
|
1444
|
+
config: config$6
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
const generateSignature$2 = (options, fileName) => {
|
|
1449
|
+
const secretId = options.secretId;
|
|
1450
|
+
const secretKey = options.secretKey;
|
|
1451
|
+
const appId = options.appId;
|
|
1452
|
+
const bucket = options.bucket;
|
|
1453
|
+
let signature;
|
|
1454
|
+
let signTime = '';
|
|
1455
|
+
if (!options.version || options.version === 'v4') {
|
|
1456
|
+
const random = Math.floor(Math.random() * 10000000000);
|
|
1457
|
+
const current = Math.floor(new Date().getTime() / 1000) - 1;
|
|
1458
|
+
const expired = current + 3600;
|
|
1459
|
+
const multiSignature = `a=${appId}&b=${bucket}&k=${secretId}&e=${expired}&t=${current}&r=${random}&f=`;
|
|
1460
|
+
const signHexKey = crypto.createHmac('sha1', secretKey).update(multiSignature).digest();
|
|
1461
|
+
const tempString = Buffer.concat([signHexKey, Buffer.from(multiSignature)]);
|
|
1462
|
+
signature = Buffer.from(tempString).toString('base64');
|
|
1463
|
+
}
|
|
1464
|
+
else {
|
|
1465
|
+
// https://cloud.tencent.com/document/product/436/7778#signature
|
|
1466
|
+
const today = Math.floor(new Date().getTime() / 1000);
|
|
1467
|
+
const tomorrow = today + 86400;
|
|
1468
|
+
signTime = `${today};${tomorrow}`;
|
|
1469
|
+
const signKey = crypto.createHmac('sha1', secretKey).update(signTime).digest('hex');
|
|
1470
|
+
const httpString = `put\n/${options.path}${fileName}\n\nhost=${options.bucket}.cos.${options.area}.myqcloud.com\n`;
|
|
1471
|
+
const sha1edHttpString = crypto.createHash('sha1').update(httpString).digest('hex');
|
|
1472
|
+
const stringToSign = `sha1\n${signTime}\n${sha1edHttpString}\n`;
|
|
1473
|
+
signature = crypto.createHmac('sha1', signKey).update(stringToSign).digest('hex');
|
|
1474
|
+
}
|
|
1475
|
+
return {
|
|
1476
|
+
signature,
|
|
1477
|
+
appId,
|
|
1478
|
+
bucket,
|
|
1479
|
+
signTime
|
|
1480
|
+
};
|
|
1481
|
+
};
|
|
1482
|
+
const postOptions$5 = (options, fileName, signature, image, version) => {
|
|
1483
|
+
const area = options.area;
|
|
1484
|
+
const path = options.path;
|
|
1485
|
+
if (!options.version || options.version === 'v4') {
|
|
1486
|
+
return {
|
|
1487
|
+
method: 'POST',
|
|
1488
|
+
url: `http://${area}.file.myqcloud.com/files/v2/${signature.appId}/${signature.bucket}/${encodeURI(path)}${fileName}`,
|
|
1489
|
+
headers: {
|
|
1490
|
+
Host: `${area}.file.myqcloud.com`,
|
|
1491
|
+
Authorization: signature.signature,
|
|
1492
|
+
contentType: 'multipart/form-data',
|
|
1493
|
+
userAgent: `PicGo;${version};null;null`
|
|
1494
|
+
},
|
|
1495
|
+
formData: {
|
|
1496
|
+
op: 'upload',
|
|
1497
|
+
filecontent: image
|
|
1498
|
+
},
|
|
1499
|
+
resolveWithFullResponse: true
|
|
1500
|
+
};
|
|
1501
|
+
}
|
|
1502
|
+
else {
|
|
1503
|
+
return {
|
|
1504
|
+
method: 'PUT',
|
|
1505
|
+
url: `http://${options.bucket}.cos.${options.area}.myqcloud.com/${encodeURIComponent(path)}${encodeURIComponent(fileName)}`,
|
|
1506
|
+
headers: {
|
|
1507
|
+
Host: `${options.bucket}.cos.${options.area}.myqcloud.com`,
|
|
1508
|
+
Authorization: `q-sign-algorithm=sha1&q-ak=${options.secretId}&q-sign-time=${signature.signTime}&q-key-time=${signature.signTime}&q-header-list=host&q-url-param-list=&q-signature=${signature.signature}`,
|
|
1509
|
+
contentType: mime.lookup(fileName),
|
|
1510
|
+
userAgent: `PicGo;${version};null;null`
|
|
1511
|
+
},
|
|
1512
|
+
body: image,
|
|
1513
|
+
resolveWithFullResponse: true
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
const handle$7 = async (ctx) => {
|
|
1518
|
+
var _a, _b, _c;
|
|
1519
|
+
const tcYunOptions = ctx.getConfig('picBed.tcyun');
|
|
1520
|
+
if (!tcYunOptions) {
|
|
1521
|
+
throw new Error('Can\'t find tencent COS config');
|
|
1522
|
+
}
|
|
1523
|
+
try {
|
|
1524
|
+
const imgList = ctx.output;
|
|
1525
|
+
const customUrl = tcYunOptions.customUrl;
|
|
1526
|
+
const path = tcYunOptions.path;
|
|
1527
|
+
const useV4 = !tcYunOptions.version || tcYunOptions.version === 'v4';
|
|
1528
|
+
for (const img of imgList) {
|
|
1529
|
+
if (img.fileName && img.buffer) {
|
|
1530
|
+
const signature = generateSignature$2(tcYunOptions, img.fileName);
|
|
1531
|
+
if (!signature) {
|
|
1532
|
+
return false;
|
|
1533
|
+
}
|
|
1534
|
+
let image = img.buffer;
|
|
1535
|
+
if (!image && img.base64Image) {
|
|
1536
|
+
image = Buffer.from(img.base64Image, 'base64');
|
|
1537
|
+
}
|
|
1538
|
+
const options = postOptions$5(tcYunOptions, img.fileName, signature, image, ctx.GUI_VERSION || ctx.VERSION);
|
|
1539
|
+
const res = await ctx.request(options)
|
|
1540
|
+
.then((res) => res)
|
|
1541
|
+
.catch((err) => {
|
|
1542
|
+
return {
|
|
1543
|
+
statusCode: 400,
|
|
1544
|
+
body: {
|
|
1545
|
+
msg: ctx.i18n.translate('AUTH_FAILED'),
|
|
1546
|
+
err
|
|
1547
|
+
}
|
|
1548
|
+
};
|
|
1549
|
+
});
|
|
1550
|
+
let body;
|
|
1551
|
+
if (useV4 && typeof res === 'string') {
|
|
1552
|
+
body = JSON.parse(res);
|
|
1553
|
+
}
|
|
1554
|
+
else {
|
|
1555
|
+
body = res;
|
|
1556
|
+
}
|
|
1557
|
+
if (body.statusCode === 400) {
|
|
1558
|
+
if ((_a = body === null || body === void 0 ? void 0 : body.body) === null || _a === void 0 ? void 0 : _a.err) {
|
|
1559
|
+
throw body.body.err;
|
|
1560
|
+
}
|
|
1561
|
+
else {
|
|
1562
|
+
throw new Error(((_b = body === null || body === void 0 ? void 0 : body.body) === null || _b === void 0 ? void 0 : _b.msg) || ((_c = body === null || body === void 0 ? void 0 : body.body) === null || _c === void 0 ? void 0 : _c.message));
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
const optionUrl = tcYunOptions.options || '';
|
|
1566
|
+
if (useV4 && body.message === 'SUCCESS') {
|
|
1567
|
+
delete img.base64Image;
|
|
1568
|
+
delete img.buffer;
|
|
1569
|
+
if (customUrl) {
|
|
1570
|
+
img.imgUrl = `${customUrl}/${path}${img.fileName}`;
|
|
1571
|
+
}
|
|
1572
|
+
else {
|
|
1573
|
+
img.imgUrl = `${body.data.source_url}${optionUrl}`;
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
else if (!useV4 && body && body.statusCode === 200) {
|
|
1577
|
+
delete img.base64Image;
|
|
1578
|
+
delete img.buffer;
|
|
1579
|
+
if (customUrl) {
|
|
1580
|
+
img.imgUrl = `${customUrl}/${encodeURI(path)}${encodeURI(img.fileName)}${optionUrl}`;
|
|
1581
|
+
}
|
|
1582
|
+
else {
|
|
1583
|
+
img.imgUrl = `https://${tcYunOptions.bucket}.cos.${tcYunOptions.area}.myqcloud.com/${encodeURI(path)}${encodeURI(img.fileName)}${optionUrl}`;
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
else {
|
|
1587
|
+
throw new Error(res.body.msg);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
return ctx;
|
|
1592
|
+
}
|
|
1593
|
+
catch (err) {
|
|
1594
|
+
if (!tcYunOptions.version || tcYunOptions.version === 'v4') {
|
|
1595
|
+
try {
|
|
1596
|
+
const body = JSON.parse(err.error);
|
|
1597
|
+
ctx.emit(IBuildInEvent.NOTIFICATION, {
|
|
1598
|
+
title: ctx.i18n.translate('UPLOAD_FAILED'),
|
|
1599
|
+
body: ctx.i18n.translate('UPLOAD_FAILED_REASON', {
|
|
1600
|
+
code: body.code
|
|
1601
|
+
}),
|
|
1602
|
+
text: 'https://cloud.tencent.com/document/product/436/8432'
|
|
1603
|
+
});
|
|
1604
|
+
}
|
|
1605
|
+
catch (e) { }
|
|
1606
|
+
}
|
|
1607
|
+
throw err;
|
|
1608
|
+
}
|
|
1609
|
+
};
|
|
1610
|
+
const config$5 = (ctx) => {
|
|
1611
|
+
const userConfig = ctx.getConfig('picBed.tcyun') || {};
|
|
1612
|
+
const config = [
|
|
1613
|
+
{
|
|
1614
|
+
name: 'version',
|
|
1615
|
+
type: 'list',
|
|
1616
|
+
alias: ctx.i18n.translate('PICBED_TENCENTCLOUD_VERSION'),
|
|
1617
|
+
choices: ['v4', 'v5'],
|
|
1618
|
+
default: 'v5',
|
|
1619
|
+
required: false
|
|
1620
|
+
},
|
|
1621
|
+
{
|
|
1622
|
+
name: 'secretId',
|
|
1623
|
+
type: 'input',
|
|
1624
|
+
get alias() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_SECRETID'); },
|
|
1625
|
+
default: userConfig.secretId || '',
|
|
1626
|
+
required: true
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
name: 'secretKey',
|
|
1630
|
+
type: 'password',
|
|
1631
|
+
get alias() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_SECRETKEY'); },
|
|
1632
|
+
default: userConfig.secretKey || '',
|
|
1633
|
+
required: true
|
|
1634
|
+
},
|
|
1635
|
+
{
|
|
1636
|
+
name: 'bucket',
|
|
1637
|
+
type: 'input',
|
|
1638
|
+
get alias() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_BUCKET'); },
|
|
1639
|
+
default: userConfig.bucket || '',
|
|
1640
|
+
required: true
|
|
1641
|
+
},
|
|
1642
|
+
{
|
|
1643
|
+
name: 'appId',
|
|
1644
|
+
type: 'input',
|
|
1645
|
+
get prefix() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_APPID'); },
|
|
1646
|
+
get alias() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_APPID'); },
|
|
1647
|
+
default: userConfig.appId || '',
|
|
1648
|
+
get message() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_MESSAGE_APPID'); },
|
|
1649
|
+
required: true
|
|
1650
|
+
},
|
|
1651
|
+
{
|
|
1652
|
+
name: 'area',
|
|
1653
|
+
type: 'input',
|
|
1654
|
+
get prefix() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_AREA'); },
|
|
1655
|
+
get alias() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_AREA'); },
|
|
1656
|
+
default: userConfig.area || '',
|
|
1657
|
+
get message() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_MESSAGE_AREA'); },
|
|
1658
|
+
required: true
|
|
1659
|
+
},
|
|
1660
|
+
{
|
|
1661
|
+
name: 'path',
|
|
1662
|
+
type: 'input',
|
|
1663
|
+
get prefix() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_PATH'); },
|
|
1664
|
+
get alias() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_PATH'); },
|
|
1665
|
+
default: userConfig.path || '',
|
|
1666
|
+
get message() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_MESSAGE_PATH'); },
|
|
1667
|
+
required: false
|
|
1668
|
+
},
|
|
1669
|
+
{
|
|
1670
|
+
name: 'customUrl',
|
|
1671
|
+
type: 'input',
|
|
1672
|
+
get prefix() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_CUSTOMURL'); },
|
|
1673
|
+
get alias() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_CUSTOMURL'); },
|
|
1674
|
+
default: userConfig.customUrl || '',
|
|
1675
|
+
get message() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_MESSAGE_CUSTOMURL'); },
|
|
1676
|
+
required: false
|
|
1677
|
+
},
|
|
1678
|
+
{
|
|
1679
|
+
name: 'options',
|
|
1680
|
+
type: 'input',
|
|
1681
|
+
default: userConfig.options || '',
|
|
1682
|
+
get prefix() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_OPTIONS'); },
|
|
1683
|
+
get alias() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_OPTIONS'); },
|
|
1684
|
+
get message() { return ctx.i18n.translate('PICBED_TENCENTCLOUD_MESSAGE_OPTIONS'); },
|
|
1685
|
+
required: false
|
|
1686
|
+
}
|
|
1687
|
+
];
|
|
1688
|
+
return config;
|
|
1689
|
+
};
|
|
1690
|
+
function register$5(ctx) {
|
|
1691
|
+
ctx.helper.uploader.register('tcyun', {
|
|
1692
|
+
get name() { return ctx.i18n.translate('PICBED_TENCENTCLOUD'); },
|
|
1693
|
+
handle: handle$7,
|
|
1694
|
+
config: config$5
|
|
1695
|
+
});
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
const postOptions$4 = (fileName, options, data) => {
|
|
1699
|
+
const path = options.path || '';
|
|
1700
|
+
const { token, repo } = options;
|
|
1701
|
+
return {
|
|
1702
|
+
method: 'PUT',
|
|
1703
|
+
url: `https://api.github.com/repos/${repo}/contents/${encodeURI(path)}${encodeURI(fileName)}`,
|
|
1704
|
+
headers: {
|
|
1705
|
+
Authorization: `token ${token}`,
|
|
1706
|
+
'User-Agent': 'PicGo',
|
|
1707
|
+
'Content-Type': mime.lookup(fileName)
|
|
1708
|
+
},
|
|
1709
|
+
body: data,
|
|
1710
|
+
json: true
|
|
1711
|
+
};
|
|
1712
|
+
};
|
|
1713
|
+
const handle$6 = async (ctx) => {
|
|
1714
|
+
const githubOptions = ctx.getConfig('picBed.github');
|
|
1715
|
+
if (!githubOptions) {
|
|
1716
|
+
throw new Error('Can\'t find github config');
|
|
1717
|
+
}
|
|
1718
|
+
try {
|
|
1719
|
+
const imgList = ctx.output;
|
|
1720
|
+
for (const img of imgList) {
|
|
1721
|
+
if (img.fileName && img.buffer) {
|
|
1722
|
+
const base64Image = img.base64Image || Buffer.from(img.buffer).toString('base64');
|
|
1723
|
+
const data = {
|
|
1724
|
+
message: 'Upload by PicGo',
|
|
1725
|
+
branch: githubOptions.branch,
|
|
1726
|
+
content: base64Image,
|
|
1727
|
+
path: githubOptions.path + encodeURI(img.fileName)
|
|
1728
|
+
};
|
|
1729
|
+
const postConfig = postOptions$4(img.fileName, githubOptions, data);
|
|
1730
|
+
const body = await ctx.request(postConfig);
|
|
1731
|
+
if (body) {
|
|
1732
|
+
delete img.base64Image;
|
|
1733
|
+
delete img.buffer;
|
|
1734
|
+
if (githubOptions.customUrl) {
|
|
1735
|
+
img.imgUrl = `${githubOptions.customUrl}/${githubOptions.path}${img.fileName}`;
|
|
1736
|
+
}
|
|
1737
|
+
else {
|
|
1738
|
+
img.imgUrl = body.content.download_url;
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
else {
|
|
1742
|
+
throw new Error('Server error, please try again');
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
return ctx;
|
|
1747
|
+
}
|
|
1748
|
+
catch (err) {
|
|
1749
|
+
ctx.emit(IBuildInEvent.NOTIFICATION, {
|
|
1750
|
+
title: ctx.i18n.translate('UPLOAD_FAILED'),
|
|
1751
|
+
body: ctx.i18n.translate('CHECK_SETTINGS_AND_NETWORK')
|
|
1752
|
+
});
|
|
1753
|
+
throw err;
|
|
1754
|
+
}
|
|
1755
|
+
};
|
|
1756
|
+
const config$4 = (ctx) => {
|
|
1757
|
+
const userConfig = ctx.getConfig('picBed.github') || {};
|
|
1758
|
+
const config = [
|
|
1759
|
+
{
|
|
1760
|
+
name: 'repo',
|
|
1761
|
+
type: 'input',
|
|
1762
|
+
get prefix() { return ctx.i18n.translate('PICBED_GITHUB_REPO'); },
|
|
1763
|
+
get alias() { return ctx.i18n.translate('PICBED_GITHUB_REPO'); },
|
|
1764
|
+
get message() { return ctx.i18n.translate('PICBED_GITHUB_MESSAGE_REPO'); },
|
|
1765
|
+
default: userConfig.repo || '',
|
|
1766
|
+
required: true
|
|
1767
|
+
},
|
|
1768
|
+
{
|
|
1769
|
+
name: 'branch',
|
|
1770
|
+
type: 'input',
|
|
1771
|
+
get prefix() { return ctx.i18n.translate('PICBED_GITHUB_BRANCH'); },
|
|
1772
|
+
get alias() { return ctx.i18n.translate('PICBED_GITHUB_BRANCH'); },
|
|
1773
|
+
get message() { return ctx.i18n.translate('PICBED_GITHUB_MESSAGE_BRANCH'); },
|
|
1774
|
+
default: userConfig.branch || 'master',
|
|
1775
|
+
required: true
|
|
1776
|
+
},
|
|
1777
|
+
{
|
|
1778
|
+
name: 'token',
|
|
1779
|
+
type: 'password',
|
|
1780
|
+
get alias() { return ctx.i18n.translate('PICBED_GITHUB_TOKEN'); },
|
|
1781
|
+
default: userConfig.token || '',
|
|
1782
|
+
required: true
|
|
1783
|
+
},
|
|
1784
|
+
{
|
|
1785
|
+
name: 'path',
|
|
1786
|
+
type: 'input',
|
|
1787
|
+
get prefix() { return ctx.i18n.translate('PICBED_GITHUB_PATH'); },
|
|
1788
|
+
get alias() { return ctx.i18n.translate('PICBED_GITHUB_PATH'); },
|
|
1789
|
+
get message() { return ctx.i18n.translate('PICBED_GITHUB_MESSAGE_PATH'); },
|
|
1790
|
+
default: userConfig.path || '',
|
|
1791
|
+
required: false
|
|
1792
|
+
},
|
|
1793
|
+
{
|
|
1794
|
+
name: 'customUrl',
|
|
1795
|
+
type: 'input',
|
|
1796
|
+
get prefix() { return ctx.i18n.translate('PICBED_GITHUB_CUSTOMURL'); },
|
|
1797
|
+
get alias() { return ctx.i18n.translate('PICBED_GITHUB_CUSTOMURL'); },
|
|
1798
|
+
get message() { return ctx.i18n.translate('PICBED_GITHUB_MESSAGE_CUSTOMURL'); },
|
|
1799
|
+
default: userConfig.customUrl || '',
|
|
1800
|
+
required: false
|
|
1801
|
+
}
|
|
1802
|
+
];
|
|
1803
|
+
return config;
|
|
1804
|
+
};
|
|
1805
|
+
function register$4(ctx) {
|
|
1806
|
+
ctx.helper.uploader.register('github', {
|
|
1807
|
+
get name() { return ctx.i18n.translate('PICBED_GITHUB'); },
|
|
1808
|
+
handle: handle$6,
|
|
1809
|
+
config: config$4
|
|
1810
|
+
});
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
function postOptions$3(options, fileName, token, imgBase64) {
|
|
1814
|
+
const area = selectArea(options.area || 'z0');
|
|
1815
|
+
const path = options.path || '';
|
|
1816
|
+
const base64FileName = Buffer.from(path + fileName, 'utf-8').toString('base64').replace(/\+/g, '-').replace(/\//g, '_');
|
|
1817
|
+
return {
|
|
1818
|
+
method: 'POST',
|
|
1819
|
+
url: `http://upload${area}.qiniup.com/putb64/-1/key/${base64FileName}`,
|
|
1820
|
+
headers: {
|
|
1821
|
+
Authorization: `UpToken ${token}`,
|
|
1822
|
+
'Content-Type': mime.lookup(fileName) || 'application/octet-stream'
|
|
1823
|
+
},
|
|
1824
|
+
body: imgBase64
|
|
1825
|
+
};
|
|
1826
|
+
}
|
|
1827
|
+
function selectArea(area) {
|
|
1828
|
+
return area === 'z0' ? '' : '-' + area;
|
|
1829
|
+
}
|
|
1830
|
+
function getToken(qiniuOptions) {
|
|
1831
|
+
const accessKey = qiniuOptions.accessKey;
|
|
1832
|
+
const secretKey = qiniuOptions.secretKey;
|
|
1833
|
+
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
|
|
1834
|
+
const options = {
|
|
1835
|
+
scope: qiniuOptions.bucket
|
|
1836
|
+
};
|
|
1837
|
+
const putPolicy = new qiniu.rs.PutPolicy(options);
|
|
1838
|
+
return putPolicy.uploadToken(mac);
|
|
1839
|
+
}
|
|
1840
|
+
const handle$5 = async (ctx) => {
|
|
1841
|
+
const qiniuOptions = ctx.getConfig('picBed.qiniu');
|
|
1842
|
+
if (!qiniuOptions) {
|
|
1843
|
+
throw new Error('Can\'t find qiniu config');
|
|
1844
|
+
}
|
|
1845
|
+
try {
|
|
1846
|
+
const imgList = ctx.output;
|
|
1847
|
+
for (const img of imgList) {
|
|
1848
|
+
if (img.fileName && img.buffer) {
|
|
1849
|
+
const base64Image = img.base64Image || Buffer.from(img.buffer).toString('base64');
|
|
1850
|
+
const options = postOptions$3(qiniuOptions, img.fileName, getToken(qiniuOptions), base64Image);
|
|
1851
|
+
const res = await ctx.request(options);
|
|
1852
|
+
const body = JSON.parse(res);
|
|
1853
|
+
if (body === null || body === void 0 ? void 0 : body.key) {
|
|
1854
|
+
delete img.base64Image;
|
|
1855
|
+
delete img.buffer;
|
|
1856
|
+
const baseUrl = qiniuOptions.url;
|
|
1857
|
+
const options = qiniuOptions.options;
|
|
1858
|
+
img.imgUrl = `${baseUrl}/${body.key}${options}`;
|
|
1859
|
+
}
|
|
1860
|
+
else {
|
|
1861
|
+
ctx.emit(IBuildInEvent.NOTIFICATION, {
|
|
1862
|
+
title: ctx.i18n.translate('UPLOAD_FAILED'),
|
|
1863
|
+
body: body.msg
|
|
1864
|
+
});
|
|
1865
|
+
ctx.log.error('qiniu error', body);
|
|
1866
|
+
throw new Error('Upload failed');
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
return ctx;
|
|
1871
|
+
}
|
|
1872
|
+
catch (err) {
|
|
1873
|
+
if (err.message !== 'Upload failed') {
|
|
1874
|
+
// err.response maybe undefined
|
|
1875
|
+
if (err.response) {
|
|
1876
|
+
const error = err.response.body;
|
|
1877
|
+
ctx.emit(IBuildInEvent.NOTIFICATION, {
|
|
1878
|
+
title: ctx.i18n.translate('UPLOAD_FAILED'),
|
|
1879
|
+
body: error.error
|
|
1880
|
+
});
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
throw err;
|
|
1884
|
+
}
|
|
1885
|
+
};
|
|
1886
|
+
const config$3 = (ctx) => {
|
|
1887
|
+
const userConfig = ctx.getConfig('picBed.qiniu') || {};
|
|
1888
|
+
const config = [
|
|
1889
|
+
{
|
|
1890
|
+
name: 'accessKey',
|
|
1891
|
+
type: 'input',
|
|
1892
|
+
get alias() { return ctx.i18n.translate('PICBED_QINIU_ACCESSKEY'); },
|
|
1893
|
+
default: userConfig.accessKey || '',
|
|
1894
|
+
required: true
|
|
1895
|
+
},
|
|
1896
|
+
{
|
|
1897
|
+
name: 'secretKey',
|
|
1898
|
+
type: 'password',
|
|
1899
|
+
get alias() { return ctx.i18n.translate('PICBED_QINIU_SECRETKEY'); },
|
|
1900
|
+
default: userConfig.secretKey || '',
|
|
1901
|
+
required: true
|
|
1902
|
+
},
|
|
1903
|
+
{
|
|
1904
|
+
name: 'bucket',
|
|
1905
|
+
type: 'input',
|
|
1906
|
+
get alias() { return ctx.i18n.translate('PICBED_QINIU_BUCKET'); },
|
|
1907
|
+
default: userConfig.bucket || '',
|
|
1908
|
+
required: true
|
|
1909
|
+
},
|
|
1910
|
+
{
|
|
1911
|
+
name: 'url',
|
|
1912
|
+
type: 'input',
|
|
1913
|
+
get prefix() { return ctx.i18n.translate('PICBED_QINIU_URL'); },
|
|
1914
|
+
get alias() { return ctx.i18n.translate('PICBED_QINIU_URL'); },
|
|
1915
|
+
get message() { return ctx.i18n.translate('PICBED_QINIU_MESSAGE_URL'); },
|
|
1916
|
+
default: userConfig.url || '',
|
|
1917
|
+
required: true
|
|
1918
|
+
},
|
|
1919
|
+
{
|
|
1920
|
+
name: 'area',
|
|
1921
|
+
type: 'input',
|
|
1922
|
+
get prefix() { return ctx.i18n.translate('PICBED_QINIU_AREA'); },
|
|
1923
|
+
get alias() { return ctx.i18n.translate('PICBED_QINIU_AREA'); },
|
|
1924
|
+
get message() { return ctx.i18n.translate('PICBED_QINIU_MESSAGE_AREA'); },
|
|
1925
|
+
default: userConfig.area || '',
|
|
1926
|
+
required: true
|
|
1927
|
+
},
|
|
1928
|
+
{
|
|
1929
|
+
name: 'options',
|
|
1930
|
+
type: 'input',
|
|
1931
|
+
get prefix() { return ctx.i18n.translate('PICBED_QINIU_OPTIONS'); },
|
|
1932
|
+
get alias() { return ctx.i18n.translate('PICBED_QINIU_OPTIONS'); },
|
|
1933
|
+
get message() { return ctx.i18n.translate('PICBED_QINIU_MESSAGE_OPTIONS'); },
|
|
1934
|
+
default: userConfig.options || '',
|
|
1935
|
+
required: false
|
|
1936
|
+
},
|
|
1937
|
+
{
|
|
1938
|
+
name: 'path',
|
|
1939
|
+
type: 'input',
|
|
1940
|
+
get prefix() { return ctx.i18n.translate('PICBED_QINIU_PATH'); },
|
|
1941
|
+
get alias() { return ctx.i18n.translate('PICBED_QINIU_PATH'); },
|
|
1942
|
+
get message() { return ctx.i18n.translate('PICBED_QINIU_MESSAGE_PATH'); },
|
|
1943
|
+
default: userConfig.path || '',
|
|
1944
|
+
required: false
|
|
1945
|
+
}
|
|
1946
|
+
];
|
|
1947
|
+
return config;
|
|
1948
|
+
};
|
|
1949
|
+
function register$3(ctx) {
|
|
1950
|
+
ctx.helper.uploader.register('qiniu', {
|
|
1951
|
+
get name() { return ctx.i18n.translate('PICBED_QINIU'); },
|
|
1952
|
+
handle: handle$5,
|
|
1953
|
+
config: config$3
|
|
1954
|
+
});
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
const postOptions$2 = (options, fileName, imgBase64) => {
|
|
1958
|
+
const clientId = options.clientId;
|
|
1959
|
+
const obj = {
|
|
1960
|
+
method: 'POST',
|
|
1961
|
+
url: 'https://api.imgur.com/3/image',
|
|
1962
|
+
headers: {
|
|
1963
|
+
Authorization: `Client-ID ${clientId}`,
|
|
1964
|
+
'content-type': 'multipart/form-data',
|
|
1965
|
+
Host: 'api.imgur.com',
|
|
1966
|
+
'User-Agent': 'PicGo'
|
|
1967
|
+
},
|
|
1968
|
+
formData: {
|
|
1969
|
+
image: imgBase64,
|
|
1970
|
+
type: 'base64',
|
|
1971
|
+
name: fileName
|
|
1972
|
+
}
|
|
1973
|
+
};
|
|
1974
|
+
if (options.proxy) {
|
|
1975
|
+
obj.proxy = options.proxy;
|
|
1976
|
+
}
|
|
1977
|
+
return obj;
|
|
1978
|
+
};
|
|
1979
|
+
const handle$4 = async (ctx) => {
|
|
1980
|
+
var _a;
|
|
1981
|
+
const imgurOptions = ctx.getConfig('picBed.imgur');
|
|
1982
|
+
if (!imgurOptions) {
|
|
1983
|
+
throw new Error('Can\'t find imgur config');
|
|
1984
|
+
}
|
|
1985
|
+
try {
|
|
1986
|
+
const imgList = ctx.output;
|
|
1987
|
+
for (const img of imgList) {
|
|
1988
|
+
if (img.fileName && img.buffer) {
|
|
1989
|
+
const base64Image = img.base64Image || Buffer.from(img.buffer).toString('base64');
|
|
1990
|
+
const options = postOptions$2(imgurOptions, img.fileName, base64Image);
|
|
1991
|
+
const res = await ctx.request(options);
|
|
1992
|
+
const body = typeof res === 'string' ? JSON.parse(res) : res;
|
|
1993
|
+
if (body.success) {
|
|
1994
|
+
delete img.base64Image;
|
|
1995
|
+
delete img.buffer;
|
|
1996
|
+
img.imgUrl = body.data.link;
|
|
1997
|
+
}
|
|
1998
|
+
else {
|
|
1999
|
+
throw new Error('Server error, please try again');
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
return ctx;
|
|
2004
|
+
}
|
|
2005
|
+
catch (err) {
|
|
2006
|
+
ctx.emit(IBuildInEvent.NOTIFICATION, {
|
|
2007
|
+
title: ctx.i18n.translate('UPLOAD_FAILED'),
|
|
2008
|
+
body: ctx.i18n.translate('CHECK_SETTINGS_AND_NETWORK'),
|
|
2009
|
+
text: 'http://docs.imgur.com/api/errno/'
|
|
2010
|
+
});
|
|
2011
|
+
// @ts-expect-error
|
|
2012
|
+
throw ((_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.data) || err;
|
|
2013
|
+
}
|
|
2014
|
+
};
|
|
2015
|
+
const config$2 = (ctx) => {
|
|
2016
|
+
const userConfig = ctx.getConfig('picBed.imgur') || {};
|
|
2017
|
+
const config = [
|
|
2018
|
+
{
|
|
2019
|
+
name: 'clientId',
|
|
2020
|
+
type: 'input',
|
|
2021
|
+
get alias() { return ctx.i18n.translate('PICBED_IMGUR_CLIENTID'); },
|
|
2022
|
+
default: userConfig.clientId || '',
|
|
2023
|
+
required: true
|
|
2024
|
+
},
|
|
2025
|
+
{
|
|
2026
|
+
name: 'proxy',
|
|
2027
|
+
type: 'input',
|
|
2028
|
+
get prefix() { return ctx.i18n.translate('PICBED_IMGUR_PROXY'); },
|
|
2029
|
+
get alias() { return ctx.i18n.translate('PICBED_IMGUR_PROXY'); },
|
|
2030
|
+
get message() { return ctx.i18n.translate('PICBED_IMGUR_MESSAGE_PROXY'); },
|
|
2031
|
+
default: userConfig.proxy || '',
|
|
2032
|
+
required: false
|
|
2033
|
+
}
|
|
2034
|
+
];
|
|
2035
|
+
return config;
|
|
2036
|
+
};
|
|
2037
|
+
function register$2(ctx) {
|
|
2038
|
+
ctx.helper.uploader.register('imgur', {
|
|
2039
|
+
get name() { return ctx.i18n.translate('PICBED_IMGUR'); },
|
|
2040
|
+
handle: handle$4,
|
|
2041
|
+
config: config$2
|
|
2042
|
+
});
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
// generate OSS signature
|
|
2046
|
+
const generateSignature$1 = (options, fileName) => {
|
|
2047
|
+
const date = new Date().toUTCString();
|
|
2048
|
+
const mimeType = mime.lookup(fileName);
|
|
2049
|
+
if (!mimeType)
|
|
2050
|
+
throw Error(`No mime type found for file ${fileName}`);
|
|
2051
|
+
const signString = `PUT\n\n${mimeType}\n${date}\n/${options.bucket}/${options.path}${fileName}`;
|
|
2052
|
+
const signature = crypto.createHmac('sha1', options.accessKeySecret).update(signString).digest('base64');
|
|
2053
|
+
return `OSS ${options.accessKeyId}:${signature}`;
|
|
2054
|
+
};
|
|
2055
|
+
const postOptions$1 = (options, fileName, signature, image) => {
|
|
2056
|
+
return {
|
|
2057
|
+
method: 'PUT',
|
|
2058
|
+
url: `https://${options.bucket}.${options.area}.aliyuncs.com/${encodeURI(options.path)}${encodeURI(fileName)}`,
|
|
2059
|
+
headers: {
|
|
2060
|
+
Host: `${options.bucket}.${options.area}.aliyuncs.com`,
|
|
2061
|
+
Authorization: signature,
|
|
2062
|
+
Date: new Date().toUTCString(),
|
|
2063
|
+
'Content-Type': mime.lookup(fileName)
|
|
2064
|
+
},
|
|
2065
|
+
body: image,
|
|
2066
|
+
resolveWithFullResponse: true
|
|
2067
|
+
};
|
|
2068
|
+
};
|
|
2069
|
+
const handle$3 = async (ctx) => {
|
|
2070
|
+
const aliYunOptions = ctx.getConfig('picBed.aliyun');
|
|
2071
|
+
if (!aliYunOptions) {
|
|
2072
|
+
throw new Error('Can\'t find aliYun OSS config');
|
|
2073
|
+
}
|
|
2074
|
+
try {
|
|
2075
|
+
const imgList = ctx.output;
|
|
2076
|
+
const customUrl = aliYunOptions.customUrl;
|
|
2077
|
+
const path = aliYunOptions.path;
|
|
2078
|
+
for (const img of imgList) {
|
|
2079
|
+
if (img.fileName && img.buffer) {
|
|
2080
|
+
const signature = generateSignature$1(aliYunOptions, img.fileName);
|
|
2081
|
+
let image = img.buffer;
|
|
2082
|
+
if (!image && img.base64Image) {
|
|
2083
|
+
image = Buffer.from(img.base64Image, 'base64');
|
|
2084
|
+
}
|
|
2085
|
+
const options = postOptions$1(aliYunOptions, img.fileName, signature, image);
|
|
2086
|
+
const body = await ctx.request(options);
|
|
2087
|
+
if (body.statusCode === 200) {
|
|
2088
|
+
delete img.base64Image;
|
|
2089
|
+
delete img.buffer;
|
|
2090
|
+
const optionUrl = aliYunOptions.options || '';
|
|
2091
|
+
if (customUrl) {
|
|
2092
|
+
img.imgUrl = `${customUrl}/${path}${img.fileName}${optionUrl}`;
|
|
2093
|
+
}
|
|
2094
|
+
else {
|
|
2095
|
+
img.imgUrl = `https://${aliYunOptions.bucket}.${aliYunOptions.area}.aliyuncs.com/${path}${img.fileName}${optionUrl}`;
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
else {
|
|
2099
|
+
throw new Error('Upload failed');
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
return ctx;
|
|
2104
|
+
}
|
|
2105
|
+
catch (err) {
|
|
2106
|
+
ctx.emit(IBuildInEvent.NOTIFICATION, {
|
|
2107
|
+
title: ctx.i18n.translate('UPLOAD_FAILED'),
|
|
2108
|
+
body: ctx.i18n.translate('CHECK_SETTINGS')
|
|
2109
|
+
});
|
|
2110
|
+
throw err;
|
|
2111
|
+
}
|
|
2112
|
+
};
|
|
2113
|
+
const config$1 = (ctx) => {
|
|
2114
|
+
const userConfig = ctx.getConfig('picBed.aliyun') || {};
|
|
2115
|
+
const config = [
|
|
2116
|
+
{
|
|
2117
|
+
name: 'accessKeyId',
|
|
2118
|
+
type: 'input',
|
|
2119
|
+
get alias() { return ctx.i18n.translate('PICBED_ALICLOUD_ACCESSKEYID'); },
|
|
2120
|
+
default: userConfig.accessKeyId || '',
|
|
2121
|
+
required: true
|
|
2122
|
+
},
|
|
2123
|
+
{
|
|
2124
|
+
name: 'accessKeySecret',
|
|
2125
|
+
type: 'password',
|
|
2126
|
+
get alias() { return ctx.i18n.translate('PICBED_ALICLOUD_ACCESSKEYSECRET'); },
|
|
2127
|
+
default: userConfig.accessKeySecret || '',
|
|
2128
|
+
required: true
|
|
2129
|
+
},
|
|
2130
|
+
{
|
|
2131
|
+
name: 'bucket',
|
|
2132
|
+
type: 'input',
|
|
2133
|
+
get alias() { return ctx.i18n.translate('PICBED_ALICLOUD_BUCKET'); },
|
|
2134
|
+
default: userConfig.bucket || '',
|
|
2135
|
+
required: true
|
|
2136
|
+
},
|
|
2137
|
+
{
|
|
2138
|
+
name: 'area',
|
|
2139
|
+
type: 'input',
|
|
2140
|
+
get prefix() { return ctx.i18n.translate('PICBED_ALICLOUD_AREA'); },
|
|
2141
|
+
get alias() { return ctx.i18n.translate('PICBED_ALICLOUD_AREA'); },
|
|
2142
|
+
default: userConfig.area || '',
|
|
2143
|
+
get message() { return ctx.i18n.translate('PICBED_ALICLOUD_MESSAGE_AREA'); },
|
|
2144
|
+
required: true
|
|
2145
|
+
},
|
|
2146
|
+
{
|
|
2147
|
+
name: 'path',
|
|
2148
|
+
type: 'input',
|
|
2149
|
+
get prefix() { return ctx.i18n.translate('PICBED_ALICLOUD_PATH'); },
|
|
2150
|
+
get alias() { return ctx.i18n.translate('PICBED_ALICLOUD_PATH'); },
|
|
2151
|
+
get message() { return ctx.i18n.translate('PICBED_ALICLOUD_MESSAGE_PATH'); },
|
|
2152
|
+
default: userConfig.path || '',
|
|
2153
|
+
required: false
|
|
2154
|
+
},
|
|
2155
|
+
{
|
|
2156
|
+
name: 'customUrl',
|
|
2157
|
+
type: 'input',
|
|
2158
|
+
get prefix() { return ctx.i18n.translate('PICBED_ALICLOUD_CUSTOMURL'); },
|
|
2159
|
+
get alias() { return ctx.i18n.translate('PICBED_ALICLOUD_CUSTOMURL'); },
|
|
2160
|
+
get message() { return ctx.i18n.translate('PICBED_ALICLOUD_MESSAGE_CUSTOMURL'); },
|
|
2161
|
+
default: userConfig.customUrl || '',
|
|
2162
|
+
required: false
|
|
2163
|
+
},
|
|
2164
|
+
{
|
|
2165
|
+
name: 'options',
|
|
2166
|
+
type: 'input',
|
|
2167
|
+
get prefix() { return ctx.i18n.translate('PICBED_ALICLOUD_OPTIONS'); },
|
|
2168
|
+
get alias() { return ctx.i18n.translate('PICBED_ALICLOUD_OPTIONS'); },
|
|
2169
|
+
get message() { return ctx.i18n.translate('PICBED_ALICLOUD_MESSAGE_OPTIONS'); },
|
|
2170
|
+
default: userConfig.options || '',
|
|
2171
|
+
required: false
|
|
2172
|
+
}
|
|
2173
|
+
];
|
|
2174
|
+
return config;
|
|
2175
|
+
};
|
|
2176
|
+
function register$1(ctx) {
|
|
2177
|
+
ctx.helper.uploader.register('aliyun', {
|
|
2178
|
+
get name() {
|
|
2179
|
+
return ctx.i18n.translate('PICBED_ALICLOUD');
|
|
2180
|
+
},
|
|
2181
|
+
handle: handle$3,
|
|
2182
|
+
config: config$1
|
|
2183
|
+
});
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
// generate COS signature string
|
|
2187
|
+
const generateSignature = (options, fileName) => {
|
|
2188
|
+
const path = options.path || '';
|
|
2189
|
+
const operator = options.operator;
|
|
2190
|
+
const password = options.password;
|
|
2191
|
+
const md5Password = MD5(password);
|
|
2192
|
+
const date = new Date().toUTCString();
|
|
2193
|
+
const uri = `/${options.bucket}/${encodeURI(path)}${encodeURI(fileName)}`;
|
|
2194
|
+
const value = `PUT&${uri}&${date}`;
|
|
2195
|
+
const sign = crypto.createHmac('sha1', md5Password).update(value).digest('base64');
|
|
2196
|
+
return `UPYUN ${operator}:${sign}`;
|
|
2197
|
+
};
|
|
2198
|
+
const postOptions = (options, fileName, signature, image) => {
|
|
2199
|
+
const bucket = options.bucket;
|
|
2200
|
+
const path = options.path || '';
|
|
2201
|
+
return {
|
|
2202
|
+
method: 'PUT',
|
|
2203
|
+
url: `https://v0.api.upyun.com/${bucket}/${encodeURI(path)}${encodeURI(fileName)}`,
|
|
2204
|
+
headers: {
|
|
2205
|
+
Authorization: signature,
|
|
2206
|
+
Date: new Date().toUTCString(),
|
|
2207
|
+
'Content-Type': mime.lookup(fileName) || 'application/octet-stream'
|
|
2208
|
+
},
|
|
2209
|
+
body: image,
|
|
2210
|
+
resolveWithFullResponse: true
|
|
2211
|
+
};
|
|
2212
|
+
};
|
|
2213
|
+
const handle$2 = async (ctx) => {
|
|
2214
|
+
const upyunOptions = ctx.getConfig('picBed.upyun');
|
|
2215
|
+
if (!upyunOptions) {
|
|
2216
|
+
throw new Error('Can\'t find upYun config');
|
|
2217
|
+
}
|
|
2218
|
+
try {
|
|
2219
|
+
const imgList = ctx.output;
|
|
2220
|
+
const path = upyunOptions.path || '';
|
|
2221
|
+
for (const img of imgList) {
|
|
2222
|
+
if (img.fileName && img.buffer) {
|
|
2223
|
+
let image = img.buffer;
|
|
2224
|
+
if (!image && img.base64Image) {
|
|
2225
|
+
image = Buffer.from(img.base64Image, 'base64');
|
|
2226
|
+
}
|
|
2227
|
+
const signature = generateSignature(upyunOptions, img.fileName);
|
|
2228
|
+
const options = postOptions(upyunOptions, img.fileName, signature, image);
|
|
2229
|
+
const body = await ctx.request(options);
|
|
2230
|
+
if (body.statusCode === 200) {
|
|
2231
|
+
delete img.base64Image;
|
|
2232
|
+
delete img.buffer;
|
|
2233
|
+
img.imgUrl = `${upyunOptions.url}/${path}${img.fileName}${upyunOptions.options}`;
|
|
2234
|
+
}
|
|
2235
|
+
else {
|
|
2236
|
+
throw new Error('Upload failed');
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
return ctx;
|
|
2241
|
+
}
|
|
2242
|
+
catch (err) {
|
|
2243
|
+
if (err.message === 'Upload failed') {
|
|
2244
|
+
ctx.emit(IBuildInEvent.NOTIFICATION, {
|
|
2245
|
+
title: ctx.i18n.translate('UPLOAD_FAILED'),
|
|
2246
|
+
body: ctx.i18n.translate('CHECK_SETTINGS')
|
|
2247
|
+
});
|
|
2248
|
+
}
|
|
2249
|
+
else {
|
|
2250
|
+
const body = safeParse(err.error);
|
|
2251
|
+
ctx.emit(IBuildInEvent.NOTIFICATION, {
|
|
2252
|
+
title: ctx.i18n.translate('UPLOAD_FAILED'),
|
|
2253
|
+
body: ctx.i18n.translate('UPLOAD_FAILED_REASON', {
|
|
2254
|
+
code: typeof body === 'object' ? body.code : body
|
|
2255
|
+
}),
|
|
2256
|
+
text: 'http://docs.upyun.com/api/errno/'
|
|
2257
|
+
});
|
|
2258
|
+
}
|
|
2259
|
+
throw err;
|
|
2260
|
+
}
|
|
2261
|
+
};
|
|
2262
|
+
const config = (ctx) => {
|
|
2263
|
+
const userConfig = ctx.getConfig('picBed.upyun') || {};
|
|
2264
|
+
const config = [
|
|
2265
|
+
{
|
|
2266
|
+
name: 'bucket',
|
|
2267
|
+
type: 'input',
|
|
2268
|
+
get alias() { return ctx.i18n.translate('PICBED_UPYUN_BUCKET'); },
|
|
2269
|
+
default: userConfig.bucket || '',
|
|
2270
|
+
required: true
|
|
2271
|
+
},
|
|
2272
|
+
{
|
|
2273
|
+
name: 'operator',
|
|
2274
|
+
type: 'input',
|
|
2275
|
+
get alias() { return ctx.i18n.translate('PICBED_UPYUN_OPERATOR'); },
|
|
2276
|
+
get prefix() {
|
|
2277
|
+
return ctx.i18n.translate('PICBED_UPYUN_OPERATOR');
|
|
2278
|
+
},
|
|
2279
|
+
get message() { return ctx.i18n.translate('PICBED_UPYUN_MESSAGE_OPERATOR'); },
|
|
2280
|
+
default: userConfig.operator || '',
|
|
2281
|
+
required: true
|
|
2282
|
+
},
|
|
2283
|
+
{
|
|
2284
|
+
name: 'password',
|
|
2285
|
+
type: 'password',
|
|
2286
|
+
get prefix() { return ctx.i18n.translate('PICBED_UPYUN_MESSAGE_PASSWORD'); },
|
|
2287
|
+
get alias() { return ctx.i18n.translate('PICBED_UPYUN_PASSWORD'); },
|
|
2288
|
+
get message() { return ctx.i18n.translate('PICBED_UPYUN_MESSAGE_PASSWORD'); },
|
|
2289
|
+
default: userConfig.password || '',
|
|
2290
|
+
required: true
|
|
2291
|
+
},
|
|
2292
|
+
{
|
|
2293
|
+
name: 'url',
|
|
2294
|
+
type: 'input',
|
|
2295
|
+
get alias() { return ctx.i18n.translate('PICBED_UPYUN_URL'); },
|
|
2296
|
+
get message() { return ctx.i18n.translate('PICBED_UPYUN_MESSAGE_URL'); },
|
|
2297
|
+
default: userConfig.url || '',
|
|
2298
|
+
required: true
|
|
2299
|
+
},
|
|
2300
|
+
{
|
|
2301
|
+
name: 'options',
|
|
2302
|
+
type: 'input',
|
|
2303
|
+
get prefix() { return ctx.i18n.translate('PICBED_UPYUN_OPTIONS'); },
|
|
2304
|
+
get alias() { return ctx.i18n.translate('PICBED_UPYUN_OPTIONS'); },
|
|
2305
|
+
get message() { return ctx.i18n.translate('PICBED_UPYUN_MESSAGE_OPTIONS'); },
|
|
2306
|
+
default: userConfig.options || '',
|
|
2307
|
+
required: false
|
|
2308
|
+
},
|
|
2309
|
+
{
|
|
2310
|
+
name: 'path',
|
|
2311
|
+
type: 'input',
|
|
2312
|
+
get prefix() { return ctx.i18n.translate('PICBED_UPYUN_PATH'); },
|
|
2313
|
+
get alias() { return ctx.i18n.translate('PICBED_UPYUN_PATH'); },
|
|
2314
|
+
get message() { return ctx.i18n.translate('PICBED_UPYUN_MESSAGE_PATH'); },
|
|
2315
|
+
default: userConfig.path || '',
|
|
2316
|
+
required: false
|
|
2317
|
+
}
|
|
2318
|
+
];
|
|
2319
|
+
return config;
|
|
2320
|
+
};
|
|
2321
|
+
function register(ctx) {
|
|
2322
|
+
ctx.helper.uploader.register('upyun', {
|
|
2323
|
+
get name() { return ctx.i18n.translate('PICBED_UPYUN'); },
|
|
2324
|
+
handle: handle$2,
|
|
2325
|
+
config
|
|
2326
|
+
});
|
|
2327
|
+
}
|
|
2328
|
+
|
|
2329
|
+
const buildInUploaders = () => {
|
|
2330
|
+
return {
|
|
2331
|
+
register(ctx) {
|
|
2332
|
+
register$1(ctx);
|
|
2333
|
+
register$5(ctx);
|
|
2334
|
+
register$6(ctx);
|
|
2335
|
+
register$4(ctx);
|
|
2336
|
+
register$3(ctx);
|
|
2337
|
+
register$2(ctx);
|
|
2338
|
+
register(ctx);
|
|
2339
|
+
}
|
|
2340
|
+
};
|
|
2341
|
+
};
|
|
2342
|
+
|
|
2343
|
+
const handle$1 = async (ctx) => {
|
|
2344
|
+
const results = ctx.output;
|
|
2345
|
+
await Promise.all(ctx.input.map(async (item, index) => {
|
|
2346
|
+
let info;
|
|
2347
|
+
if (isUrl(item)) {
|
|
2348
|
+
info = await getURLFile(item, ctx);
|
|
2349
|
+
}
|
|
2350
|
+
else {
|
|
2351
|
+
info = await getFSFile(item);
|
|
2352
|
+
}
|
|
2353
|
+
if (info.success && info.buffer) {
|
|
2354
|
+
const imgSize = getImgSize(ctx, info.buffer, item);
|
|
2355
|
+
results[index] = {
|
|
2356
|
+
buffer: info.buffer,
|
|
2357
|
+
fileName: info.fileName,
|
|
2358
|
+
width: imgSize.width,
|
|
2359
|
+
height: imgSize.height,
|
|
2360
|
+
extname: info.extname
|
|
2361
|
+
};
|
|
2362
|
+
}
|
|
2363
|
+
else {
|
|
2364
|
+
throw new Error(info.reason);
|
|
2365
|
+
}
|
|
2366
|
+
}));
|
|
2367
|
+
// remove empty item
|
|
2368
|
+
ctx.output = results.filter(item => item);
|
|
2369
|
+
return ctx;
|
|
2370
|
+
};
|
|
2371
|
+
const getImgSize = (ctx, file, path) => {
|
|
2372
|
+
const imageSize = getImageSize(file);
|
|
2373
|
+
if (!imageSize.real) {
|
|
2374
|
+
ctx.log.warn(`can't get ${path}'s image size`);
|
|
2375
|
+
ctx.log.warn('fallback to 200 * 200');
|
|
2376
|
+
}
|
|
2377
|
+
return imageSize;
|
|
2378
|
+
};
|
|
2379
|
+
var ImgFromPath = {
|
|
2380
|
+
handle: handle$1
|
|
2381
|
+
};
|
|
2382
|
+
|
|
2383
|
+
const handle = async (ctx) => {
|
|
2384
|
+
ctx.output.push(...ctx.input);
|
|
2385
|
+
return ctx;
|
|
2386
|
+
};
|
|
2387
|
+
var ImgFromBase64 = {
|
|
2388
|
+
handle
|
|
2389
|
+
};
|
|
2390
|
+
|
|
2391
|
+
const buildInTransformers = () => {
|
|
2392
|
+
return {
|
|
2393
|
+
register(ctx) {
|
|
2394
|
+
ctx.helper.transformer.register('path', ImgFromPath);
|
|
2395
|
+
ctx.helper.transformer.register('base64', ImgFromBase64);
|
|
2396
|
+
}
|
|
2397
|
+
};
|
|
2398
|
+
};
|
|
2399
|
+
|
|
2400
|
+
/**
|
|
2401
|
+
* Local plugin loader, file system is required
|
|
2402
|
+
*/
|
|
2403
|
+
class PluginLoader {
|
|
2404
|
+
constructor(ctx) {
|
|
2405
|
+
this.list = [];
|
|
2406
|
+
this.fullList = new Set();
|
|
2407
|
+
this.pluginMap = new Map();
|
|
2408
|
+
this.ctx = ctx;
|
|
2409
|
+
this.init();
|
|
2410
|
+
}
|
|
2411
|
+
init() {
|
|
2412
|
+
const packagePath = path.join(this.ctx.baseDir, 'package.json');
|
|
2413
|
+
if (!fs.existsSync(packagePath)) {
|
|
2414
|
+
const pkg = {
|
|
2415
|
+
name: 'picgo-plugins',
|
|
2416
|
+
description: 'picgo-plugins',
|
|
2417
|
+
repository: 'https://github.com/PicGo/PicGo-Core',
|
|
2418
|
+
license: 'MIT'
|
|
2419
|
+
};
|
|
2420
|
+
fs.writeFileSync(packagePath, JSON.stringify(pkg), 'utf8');
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
// get plugin entry
|
|
2424
|
+
resolvePlugin(ctx, name) {
|
|
2425
|
+
try {
|
|
2426
|
+
return resolve.sync(name, { basedir: ctx.baseDir });
|
|
2427
|
+
}
|
|
2428
|
+
catch (err) {
|
|
2429
|
+
return path.join(ctx.baseDir, 'node_modules', name);
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
// load all third party plugin
|
|
2433
|
+
load() {
|
|
2434
|
+
const packagePath = path.join(this.ctx.baseDir, 'package.json');
|
|
2435
|
+
const pluginDir = path.join(this.ctx.baseDir, 'node_modules/');
|
|
2436
|
+
// Thanks to hexo -> https://github.com/hexojs/hexo/blob/master/lib/hexo/load_plugins.js
|
|
2437
|
+
if (!fs.existsSync(pluginDir)) {
|
|
2438
|
+
return false;
|
|
2439
|
+
}
|
|
2440
|
+
const json = fs.readJSONSync(packagePath);
|
|
2441
|
+
const deps = Object.keys(json.dependencies || {});
|
|
2442
|
+
const devDeps = Object.keys(json.devDependencies || {});
|
|
2443
|
+
const modules = deps.concat(devDeps).filter((name) => {
|
|
2444
|
+
if (!/^picgo-plugin-|^@[^/]+\/picgo-plugin-/.test(name))
|
|
2445
|
+
return false;
|
|
2446
|
+
const path = this.resolvePlugin(this.ctx, name);
|
|
2447
|
+
return fs.existsSync(path);
|
|
2448
|
+
});
|
|
2449
|
+
for (const module of modules) {
|
|
2450
|
+
this.registerPlugin(module);
|
|
2451
|
+
}
|
|
2452
|
+
return true;
|
|
2453
|
+
}
|
|
2454
|
+
registerPlugin(name, plugin) {
|
|
2455
|
+
if (!name || typeof name !== 'string') {
|
|
2456
|
+
this.ctx.log.warn('Please provide valid plugin');
|
|
2457
|
+
return;
|
|
2458
|
+
}
|
|
2459
|
+
this.fullList.add(name);
|
|
2460
|
+
try {
|
|
2461
|
+
// register local plugin
|
|
2462
|
+
if (!plugin) {
|
|
2463
|
+
if (this.ctx.getConfig(`picgoPlugins.${name}`) === true || (this.ctx.getConfig(`picgoPlugins.${name}`) === undefined)) {
|
|
2464
|
+
this.list.push(name);
|
|
2465
|
+
setCurrentPluginName(name);
|
|
2466
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
2467
|
+
this.getPlugin(name).register(this.ctx);
|
|
2468
|
+
const plugin = `picgoPlugins[${name}]`;
|
|
2469
|
+
this.ctx.saveConfig({
|
|
2470
|
+
[plugin]: true
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
else {
|
|
2475
|
+
// register provided plugin
|
|
2476
|
+
// && won't write config to files
|
|
2477
|
+
this.list.push(name);
|
|
2478
|
+
setCurrentPluginName(name);
|
|
2479
|
+
const pluginInterface = plugin(this.ctx);
|
|
2480
|
+
this.pluginMap.set(name, pluginInterface);
|
|
2481
|
+
pluginInterface.register(this.ctx);
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
catch (e) {
|
|
2485
|
+
this.pluginMap.delete(name);
|
|
2486
|
+
this.list = this.list.filter((item) => item !== name);
|
|
2487
|
+
this.fullList.delete(name);
|
|
2488
|
+
this.ctx.log.error(e);
|
|
2489
|
+
this.ctx.emit(IBuildInEvent.NOTIFICATION, {
|
|
2490
|
+
title: `Plugin ${name} Load Error`,
|
|
2491
|
+
body: e
|
|
2492
|
+
});
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
unregisterPlugin(name) {
|
|
2496
|
+
this.list = this.list.filter((item) => item !== name);
|
|
2497
|
+
this.fullList.delete(name);
|
|
2498
|
+
this.pluginMap.delete(name);
|
|
2499
|
+
setCurrentPluginName(name);
|
|
2500
|
+
this.ctx.helper.uploader.unregister(name);
|
|
2501
|
+
this.ctx.helper.transformer.unregister(name);
|
|
2502
|
+
this.ctx.helper.beforeTransformPlugins.unregister(name);
|
|
2503
|
+
this.ctx.helper.beforeUploadPlugins.unregister(name);
|
|
2504
|
+
this.ctx.helper.afterUploadPlugins.unregister(name);
|
|
2505
|
+
this.ctx.cmd.unregister(name);
|
|
2506
|
+
this.ctx.removeConfig('picgoPlugins', name);
|
|
2507
|
+
}
|
|
2508
|
+
// get plugin by name
|
|
2509
|
+
getPlugin(name) {
|
|
2510
|
+
if (this.pluginMap.has(name)) {
|
|
2511
|
+
return this.pluginMap.get(name);
|
|
2512
|
+
}
|
|
2513
|
+
const pluginDir = path.join(this.ctx.baseDir, 'node_modules/');
|
|
2514
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
2515
|
+
const plugin = require(pluginDir + name)(this.ctx);
|
|
2516
|
+
this.pluginMap.set(name, plugin);
|
|
2517
|
+
return plugin;
|
|
2518
|
+
}
|
|
2519
|
+
/**
|
|
2520
|
+
* Get the list of enabled plugins
|
|
2521
|
+
*/
|
|
2522
|
+
getList() {
|
|
2523
|
+
return this.list;
|
|
2524
|
+
}
|
|
2525
|
+
hasPlugin(name) {
|
|
2526
|
+
return this.fullList.has(name);
|
|
2527
|
+
}
|
|
2528
|
+
/**
|
|
2529
|
+
* Get the full list of plugins, whether it is enabled or not
|
|
2530
|
+
*/
|
|
2531
|
+
getFullList() {
|
|
2532
|
+
return [...this.fullList];
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
var macClipboardScript = "-- From https://github.com/mushanshitiancai/vscode-paste-image\r\nproperty fileTypes : {{«class PNGf», \".png\"}}\r\n\r\non run argv\r\n\tif argv is {} then\r\n\t\treturn \"\"\r\n\tend if\r\n\r\n\tif ((clipboard info) as string) contains \"«class furl»\" then\r\n\t\treturn POSIX path of (the clipboard as «class furl»)\r\n\telse\r\n\t\tset imagePath to (item 1 of argv)\r\n\t\tset theType to getType()\r\n\r\n\t\tif theType is not missing value then\r\n\t\t\ttry\r\n\t\t\t\tset myFile to (open for access imagePath with write permission)\r\n\t\t\t\tset eof myFile to 0\r\n\t\t\t\twrite (the clipboard as (first item of theType)) to myFile\r\n\t\t\t\tclose access myFile\r\n\t\t\t\treturn (POSIX path of imagePath)\r\n\t\t\ton error\r\n\t\t\t\ttry\r\n\t\t\t\t\tclose access myFile\r\n\t\t\t\tend try\r\n\t\t\t\treturn \"no image\"\r\n\t\t\tend try\r\n\t\telse\r\n\t\t\treturn \"no image\"\r\n\t\tend if\r\n\tend if\r\nend run\r\n\r\non getType()\r\n\trepeat with aType in fileTypes\r\n\t\trepeat with theInfo in (clipboard info)\r\n\t\t\tif (first item of theInfo) is equal to (first item of aType) then return aType\r\n\t\tend repeat\r\n\tend repeat\r\n\treturn missing value\r\nend getType\r\n";
|
|
2537
|
+
|
|
2538
|
+
var windowsClipboardScript = "\r\nparam($imagePath)\r\n\r\n# Adapted from https://github.com/octan3/img-clipboard-dump/blob/master/dump-clipboard-png.ps1\r\n\r\nAdd-Type -Assembly PresentationCore\r\n$img = [Windows.Clipboard]::GetImage()\r\n\r\nif ($img -eq $null) {\r\n \"no image\"\r\n Exit 1\r\n}\r\n\r\nif (-not $imagePath) {\r\n \"no image\"\r\n Exit 1\r\n}\r\n\r\n$fcb = new-object Windows.Media.Imaging.FormatConvertedBitmap($img, [Windows.Media.PixelFormats]::Rgb24, $null, 0)\r\n$stream = [IO.File]::Open($imagePath, \"OpenOrCreate\")\r\n$encoder = New-Object Windows.Media.Imaging.PngBitmapEncoder\r\n$encoder.Frames.Add([Windows.Media.Imaging.BitmapFrame]::Create($fcb)) | out-null\r\n$encoder.Save($stream) | out-null\r\n$stream.Dispose() | out-null\r\n\r\n$imagePath\r\n";
|
|
2539
|
+
|
|
2540
|
+
var windows10ClipboardScript = "# Adapted from https://github.com/octan3/img-clipboard-dump/blob/master/dump-clipboard-png.ps1\r\nparam($imagePath)\r\n\r\n# https://github.com/PowerShell/PowerShell/issues/7233\r\n# fix the output encoding bug\r\n[console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding\r\n\r\nAdd-Type -Assembly PresentationCore\r\nfunction main {\r\n $img = [Windows.Clipboard]::GetImage()\r\n\r\n if ($img -eq $null) {\r\n \"no image\"\r\n Exit 1\r\n }\r\n\r\n if (-not $imagePath) {\r\n \"no image\"\r\n Exit 1\r\n }\r\n\r\n $fcb = new-object Windows.Media.Imaging.FormatConvertedBitmap($img, [Windows.Media.PixelFormats]::Rgb24, $null, 0)\r\n $stream = [IO.File]::Open($imagePath, \"OpenOrCreate\")\r\n $encoder = New-Object Windows.Media.Imaging.PngBitmapEncoder\r\n $encoder.Frames.Add([Windows.Media.Imaging.BitmapFrame]::Create($fcb)) | out-null\r\n $encoder.Save($stream) | out-null\r\n $stream.Dispose() | out-null\r\n\r\n $imagePath\r\n # fix windows 10 native cmd crash bug when \"picgo upload\"\r\n # https://github.com/PicGo/PicGo-Core/issues/32\r\n Exit 1\r\n}\r\n\r\ntry {\r\n # For WIN10\r\n $file = Get-Clipboard -Format FileDropList\r\n if ($file -ne $null) {\r\n Convert-Path $file\r\n Exit 1\r\n }\r\n} catch {\r\n # For WIN7 WIN8 WIN10\r\n main\r\n}\r\n\r\nmain";
|
|
2541
|
+
|
|
2542
|
+
var linuxClipboardScript = "#!/bin/sh\r\n\r\nif [ -z \"$DISPLAY\" ]; then\r\n echo \"no support\" >&2\r\n exit 1\r\nfi\r\n\r\ncase \"$XDG_SESSION_TYPE\" in\r\nwayland)\r\n command -v wl-copy >/dev/null 2>&1 || {\r\n echo >&2 \"no wl-clipboard\"\r\n exit 1\r\n }\r\n filePath=$(wl-copy -o 2>/dev/null | grep ^file:// | cut -c8-)\r\n if [ -z \"$filePath\" ]; then\r\n if\r\n wl-copy -t image/png image/png -o >\"$1\" 2>/dev/null\r\n then\r\n echo \"$1\"\r\n else\r\n rm -f \"$1\"\r\n echo \"no image\"\r\n fi\r\n else\r\n echo \"$filePath\"\r\n fi\r\n ;;\r\nx11 | tty)\r\n # require xclip(see http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script/677212#677212)\r\n command -v xclip >/dev/null 2>&1 || {\r\n echo >&2 \"no xclip\"\r\n exit 1\r\n }\r\n # write image in clipboard to file (see http://unix.stackexchange.com/questions/145131/copy-image-from-clipboard-to-file)\r\n filePath=$(xclip -selection clipboard -o 2>/dev/null | grep ^file:// | cut -c8-)\r\n if [ -z \"$filePath\" ]; then\r\n if\r\n xclip -selection clipboard -target image/png -o >\"$1\" 2>/dev/null\r\n then\r\n echo \"$1\"\r\n else\r\n rm -f \"$1\"\r\n echo \"no image\"\r\n fi\r\n else\r\n echo \"$filePath\"\r\n fi\r\n ;;\r\nesac\r\n";
|
|
2543
|
+
|
|
2544
|
+
var wslClipboardScript = "#!/bin/sh\r\n# grab the paths\r\nscriptPath=$(echo $0 | awk '{ print substr( $0, 1, length($0)-6 ) }')\"windows10.ps1\"\r\nimagePath=$(echo $1 | awk '{ print substr( $0, 1, length($0)-18 ) }')\r\nimageName=$(echo $1 | awk '{ print substr( $0, length($0)-17, length($0) ) }')\r\n\r\n# run the powershell script\r\nres=$(powershell.exe -noprofile -noninteractive -nologo -sta -executionpolicy unrestricted -file $(wslpath -w $scriptPath) $(wslpath -w $imagePath)\"\\\\\"$imageName)\r\n\r\n# note that there is a return symbol in powershell result\r\nnoImage=$(echo \"no image\\r\")\r\n\r\n# check whether image exists\r\nif [ \"$res\" = \"$noImage\" ] ;then\r\n echo \"no image\"\r\nelse\r\n echo $(wslpath -u -a \"${res}\")\r\nfi\r\n";
|
|
2545
|
+
|
|
2546
|
+
const CLIPBOARD_IMAGE_FOLDER = 'picgo-clipboard-images';
|
|
2547
|
+
|
|
2548
|
+
const getCurrentPlatform = () => {
|
|
2549
|
+
const platform = process.platform;
|
|
2550
|
+
if (isWsl) {
|
|
2551
|
+
return 'wsl';
|
|
2552
|
+
}
|
|
2553
|
+
if (platform === 'win32') {
|
|
2554
|
+
const currentOS = os.release().split('.')[0];
|
|
2555
|
+
if (currentOS === '10') {
|
|
2556
|
+
return 'win10';
|
|
2557
|
+
}
|
|
2558
|
+
else {
|
|
2559
|
+
return 'win32';
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
else if (platform === 'darwin') {
|
|
2563
|
+
return 'darwin';
|
|
2564
|
+
}
|
|
2565
|
+
else {
|
|
2566
|
+
return 'linux';
|
|
2567
|
+
}
|
|
2568
|
+
};
|
|
2569
|
+
const platform2ScriptContent = {
|
|
2570
|
+
darwin: macClipboardScript,
|
|
2571
|
+
win32: windowsClipboardScript,
|
|
2572
|
+
win10: windows10ClipboardScript,
|
|
2573
|
+
linux: linuxClipboardScript,
|
|
2574
|
+
wsl: wslClipboardScript
|
|
2575
|
+
};
|
|
2576
|
+
/**
|
|
2577
|
+
* powershell will report error if file does not have a '.ps1' extension,
|
|
2578
|
+
* so we should keep the extension name consistent with corresponding shell
|
|
2579
|
+
*/
|
|
2580
|
+
const platform2ScriptFilename = {
|
|
2581
|
+
darwin: 'mac.applescript',
|
|
2582
|
+
win32: 'windows.ps1',
|
|
2583
|
+
win10: 'windows10.ps1',
|
|
2584
|
+
linux: 'linux.sh',
|
|
2585
|
+
wsl: 'wsl.sh'
|
|
2586
|
+
};
|
|
2587
|
+
function createImageFolder(ctx) {
|
|
2588
|
+
const imagePath = path.join(ctx.baseDir, CLIPBOARD_IMAGE_FOLDER);
|
|
2589
|
+
if (!fs.existsSync(imagePath)) {
|
|
2590
|
+
fs.mkdirSync(imagePath);
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
// Thanks to vs-picgo: https://github.com/Spades-S/vs-picgo/blob/master/src/extension.ts
|
|
2594
|
+
const getClipboardImage = async (ctx) => {
|
|
2595
|
+
createImageFolder(ctx);
|
|
2596
|
+
// add an clipboard image folder to control the image cache file
|
|
2597
|
+
const imagePath = path.join(ctx.baseDir, CLIPBOARD_IMAGE_FOLDER, `${dayjs().format('YYYYMMDDHHmmss')}.png`);
|
|
2598
|
+
return await new Promise((resolve, reject) => {
|
|
2599
|
+
const platform = getCurrentPlatform();
|
|
2600
|
+
const scriptPath = path.join(ctx.baseDir, platform2ScriptFilename[platform]);
|
|
2601
|
+
// If the script does not exist yet, we need to write the content to the script file
|
|
2602
|
+
if (!fs.existsSync(scriptPath)) {
|
|
2603
|
+
fs.writeFileSync(scriptPath, platform2ScriptContent[platform], 'utf8');
|
|
2604
|
+
}
|
|
2605
|
+
let execution;
|
|
2606
|
+
if (platform === 'darwin') {
|
|
2607
|
+
execution = spawn('osascript', [scriptPath, imagePath]);
|
|
2608
|
+
}
|
|
2609
|
+
else if (platform === 'win32' || platform === 'win10') {
|
|
2610
|
+
execution = spawn('powershell', [
|
|
2611
|
+
'-noprofile',
|
|
2612
|
+
'-noninteractive',
|
|
2613
|
+
'-nologo',
|
|
2614
|
+
'-sta',
|
|
2615
|
+
'-executionpolicy', 'unrestricted',
|
|
2616
|
+
// fix windows 10 native cmd crash bug when "picgo upload"
|
|
2617
|
+
// https://github.com/PicGo/PicGo-Core/issues/32
|
|
2618
|
+
// '-windowstyle','hidden',
|
|
2619
|
+
// '-noexit',
|
|
2620
|
+
'-file', scriptPath,
|
|
2621
|
+
imagePath
|
|
2622
|
+
]);
|
|
2623
|
+
}
|
|
2624
|
+
else {
|
|
2625
|
+
execution = spawn('sh', [scriptPath, imagePath]);
|
|
2626
|
+
}
|
|
2627
|
+
execution.stdout.on('data', (data) => {
|
|
2628
|
+
if (platform === 'linux') {
|
|
2629
|
+
if (data.toString().trim() === 'no xclip or wl-clipboard') {
|
|
2630
|
+
ctx.emit(IBuildInEvent.NOTIFICATION, {
|
|
2631
|
+
title: 'xclip or wl-clipboard not found',
|
|
2632
|
+
body: 'Please install xclip(for x11) or wl-clipboard(for wayland) before run picgo'
|
|
2633
|
+
});
|
|
2634
|
+
return reject(new Error('Please install xclip(for x11) or wl-clipboard(for wayland) before run picgo'));
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
const imgPath = data.toString().trim();
|
|
2638
|
+
// if the filePath is the real file in system
|
|
2639
|
+
// we should keep it instead of removing
|
|
2640
|
+
let shouldKeepAfterUploading = false;
|
|
2641
|
+
// in macOS if your copy the file in system, it's basename will not equal to our default basename
|
|
2642
|
+
if (path.basename(imgPath) !== path.basename(imagePath)) {
|
|
2643
|
+
// if the path is not generate by picgo
|
|
2644
|
+
// but the path exists, we should keep it
|
|
2645
|
+
if (fs.existsSync(imgPath)) {
|
|
2646
|
+
shouldKeepAfterUploading = true;
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
// if the imgPath is invalid
|
|
2650
|
+
if (imgPath !== 'no image' && !fs.existsSync(imgPath)) {
|
|
2651
|
+
return reject(new Error(`Can't find ${imgPath}`));
|
|
2652
|
+
}
|
|
2653
|
+
resolve({
|
|
2654
|
+
imgPath,
|
|
2655
|
+
shouldKeepAfterUploading
|
|
2656
|
+
});
|
|
2657
|
+
});
|
|
2658
|
+
});
|
|
2659
|
+
};
|
|
2660
|
+
|
|
2661
|
+
const eventBus = new EventEmitter();
|
|
2662
|
+
|
|
2663
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
2664
|
+
const httpsAgent = new https.Agent({
|
|
2665
|
+
maxVersion: 'TLSv1.2',
|
|
2666
|
+
minVersion: 'TLSv1.2'
|
|
2667
|
+
});
|
|
2668
|
+
// thanks for https://github.dev/request/request/blob/master/index.js
|
|
2669
|
+
function appendFormData(form, key, data) {
|
|
2670
|
+
if (typeof data === 'object' && 'value' in data && 'options' in data) {
|
|
2671
|
+
form.append(key, data.value, data.options);
|
|
2672
|
+
}
|
|
2673
|
+
else {
|
|
2674
|
+
form.append(key, data);
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
function requestInterceptor(options) {
|
|
2678
|
+
var _a;
|
|
2679
|
+
let __isOldOptions = false;
|
|
2680
|
+
const opt = Object.assign(Object.assign({}, options), { url: options.url || '', headers: options.headers || {} });
|
|
2681
|
+
// user request config proxy
|
|
2682
|
+
if (options.proxy) {
|
|
2683
|
+
let proxyOptions = options.proxy;
|
|
2684
|
+
if (typeof proxyOptions === 'string') {
|
|
2685
|
+
try {
|
|
2686
|
+
proxyOptions = new URL(options.proxy);
|
|
2687
|
+
}
|
|
2688
|
+
catch (e) {
|
|
2689
|
+
proxyOptions = false;
|
|
2690
|
+
opt.proxy = false;
|
|
2691
|
+
console.error(e);
|
|
2692
|
+
}
|
|
2693
|
+
__isOldOptions = true;
|
|
2694
|
+
}
|
|
2695
|
+
if (proxyOptions) {
|
|
2696
|
+
if ((_a = options.url) === null || _a === void 0 ? void 0 : _a.startsWith('https://')) {
|
|
2697
|
+
opt.proxy = false;
|
|
2698
|
+
opt.httpsAgent = tunnel.httpsOverHttp({
|
|
2699
|
+
proxy: {
|
|
2700
|
+
host: proxyOptions === null || proxyOptions === void 0 ? void 0 : proxyOptions.hostname,
|
|
2701
|
+
port: parseInt(proxyOptions === null || proxyOptions === void 0 ? void 0 : proxyOptions.port, 10)
|
|
2702
|
+
}
|
|
2703
|
+
});
|
|
2704
|
+
}
|
|
2705
|
+
else {
|
|
2706
|
+
opt.proxy = {
|
|
2707
|
+
host: proxyOptions.hostname,
|
|
2708
|
+
port: parseInt(proxyOptions.port, 10),
|
|
2709
|
+
protocol: 'http'
|
|
2710
|
+
};
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
if ('formData' in options) {
|
|
2715
|
+
const form = new FormData();
|
|
2716
|
+
for (const key in options.formData) {
|
|
2717
|
+
const data = options.formData[key];
|
|
2718
|
+
appendFormData(form, key, data);
|
|
2719
|
+
}
|
|
2720
|
+
opt.data = form;
|
|
2721
|
+
opt.headers = Object.assign(opt.headers || {}, form.getHeaders());
|
|
2722
|
+
__isOldOptions = true;
|
|
2723
|
+
// @ts-expect-error
|
|
2724
|
+
delete opt.formData;
|
|
2725
|
+
}
|
|
2726
|
+
if ('body' in options) {
|
|
2727
|
+
opt.data = options.body;
|
|
2728
|
+
__isOldOptions = true;
|
|
2729
|
+
// @ts-expect-error
|
|
2730
|
+
delete opt.body;
|
|
2731
|
+
}
|
|
2732
|
+
if ('qs' in options) {
|
|
2733
|
+
opt.params = options.qs;
|
|
2734
|
+
__isOldOptions = true;
|
|
2735
|
+
}
|
|
2736
|
+
opt.__isOldOptions = __isOldOptions;
|
|
2737
|
+
return opt;
|
|
2738
|
+
}
|
|
2739
|
+
function responseInterceptor(response) {
|
|
2740
|
+
return Object.assign(Object.assign({}, response), { statusCode: response.status, body: response.data });
|
|
2741
|
+
}
|
|
2742
|
+
function responseErrorHandler(error) {
|
|
2743
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2744
|
+
// if (error.response) {
|
|
2745
|
+
// // The request was made and the server responded with a status code
|
|
2746
|
+
// // that falls out of the range of 2xx
|
|
2747
|
+
// return Promise.reject(erro)
|
|
2748
|
+
// } else if (error.request) {
|
|
2749
|
+
// // The request was made but no response was received
|
|
2750
|
+
// // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
|
2751
|
+
// // http.ClientRequest in node.js
|
|
2752
|
+
// return Promise.reject(error.request)
|
|
2753
|
+
// } else {
|
|
2754
|
+
// // Something happened in setting up the request that triggered an Error
|
|
2755
|
+
// return Promise.reject(error.message)
|
|
2756
|
+
// }
|
|
2757
|
+
const errorObj = {
|
|
2758
|
+
method: ((_b = (_a = error === null || error === void 0 ? void 0 : error.config) === null || _a === void 0 ? void 0 : _a.method) === null || _b === void 0 ? void 0 : _b.toUpperCase()) || '',
|
|
2759
|
+
url: ((_c = error === null || error === void 0 ? void 0 : error.config) === null || _c === void 0 ? void 0 : _c.url) || '',
|
|
2760
|
+
statusCode: ((_d = error === null || error === void 0 ? void 0 : error.response) === null || _d === void 0 ? void 0 : _d.status) || 0,
|
|
2761
|
+
message: (error === null || error === void 0 ? void 0 : error.message) || '',
|
|
2762
|
+
stack: (error === null || error === void 0 ? void 0 : error.stack) || {},
|
|
2763
|
+
response: {
|
|
2764
|
+
status: ((_e = error === null || error === void 0 ? void 0 : error.response) === null || _e === void 0 ? void 0 : _e.status) || 0,
|
|
2765
|
+
statusCode: ((_f = error === null || error === void 0 ? void 0 : error.response) === null || _f === void 0 ? void 0 : _f.status) || 0,
|
|
2766
|
+
body: ((_g = error === null || error === void 0 ? void 0 : error.response) === null || _g === void 0 ? void 0 : _g.data) || ''
|
|
2767
|
+
}
|
|
2768
|
+
};
|
|
2769
|
+
return Promise.reject(errorObj);
|
|
2770
|
+
}
|
|
2771
|
+
class Request {
|
|
2772
|
+
constructor(ctx) {
|
|
2773
|
+
this.proxy = '';
|
|
2774
|
+
this.options = {};
|
|
2775
|
+
this.ctx = ctx;
|
|
2776
|
+
this.init();
|
|
2777
|
+
eventBus.on(IBusEvent.CONFIG_CHANGE, (data) => {
|
|
2778
|
+
var _a;
|
|
2779
|
+
switch (data.configName) {
|
|
2780
|
+
case 'picBed':
|
|
2781
|
+
if ((_a = data.value) === null || _a === void 0 ? void 0 : _a.proxy) {
|
|
2782
|
+
this.proxy = data.value.proxy;
|
|
2783
|
+
}
|
|
2784
|
+
break;
|
|
2785
|
+
case 'picBed.proxy':
|
|
2786
|
+
this.proxy = data.value;
|
|
2787
|
+
break;
|
|
2788
|
+
}
|
|
2789
|
+
});
|
|
2790
|
+
}
|
|
2791
|
+
init() {
|
|
2792
|
+
const proxy = this.ctx.getConfig('picBed.proxy');
|
|
2793
|
+
if (proxy) {
|
|
2794
|
+
this.proxy = proxy;
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2797
|
+
handleProxy() {
|
|
2798
|
+
if (this.proxy) {
|
|
2799
|
+
try {
|
|
2800
|
+
const proxyOptions = new URL(this.proxy);
|
|
2801
|
+
return {
|
|
2802
|
+
host: proxyOptions.hostname,
|
|
2803
|
+
port: parseInt(proxyOptions.port || '0', 10),
|
|
2804
|
+
protocol: proxyOptions.protocol
|
|
2805
|
+
};
|
|
2806
|
+
}
|
|
2807
|
+
catch (e) {
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2810
|
+
return false;
|
|
2811
|
+
}
|
|
2812
|
+
// #64 dynamic get proxy value
|
|
2813
|
+
request(options) {
|
|
2814
|
+
var _a;
|
|
2815
|
+
this.options.proxy = this.handleProxy();
|
|
2816
|
+
this.options.headers = options.headers || {};
|
|
2817
|
+
this.options.maxBodyLength = Infinity;
|
|
2818
|
+
this.options.maxContentLength = Infinity;
|
|
2819
|
+
if (this.options.proxy && ((_a = options.url) === null || _a === void 0 ? void 0 : _a.startsWith('https://'))) {
|
|
2820
|
+
this.options.httpsAgent = tunnel.httpsOverHttp({
|
|
2821
|
+
proxy: {
|
|
2822
|
+
host: this.options.proxy.host,
|
|
2823
|
+
port: this.options.proxy.port
|
|
2824
|
+
}
|
|
2825
|
+
});
|
|
2826
|
+
this.options.proxy = false;
|
|
2827
|
+
}
|
|
2828
|
+
else {
|
|
2829
|
+
this.options.httpsAgent = httpsAgent;
|
|
2830
|
+
}
|
|
2831
|
+
// !NOTICE this.options !== options
|
|
2832
|
+
// this.options is the default options
|
|
2833
|
+
const instance = axios.create(this.options);
|
|
2834
|
+
instance.interceptors.response.use(responseInterceptor, responseErrorHandler);
|
|
2835
|
+
// compatible with old request options to new options
|
|
2836
|
+
const opt = requestInterceptor(options);
|
|
2837
|
+
instance.interceptors.request.use(function (obj) {
|
|
2838
|
+
var _a, _b, _c;
|
|
2839
|
+
// handle Content-Type
|
|
2840
|
+
let contentType = '';
|
|
2841
|
+
if ((_a = obj === null || obj === void 0 ? void 0 : obj.headers) === null || _a === void 0 ? void 0 : _a.contentType) {
|
|
2842
|
+
contentType = obj.headers.contentType;
|
|
2843
|
+
delete obj.headers.contentType;
|
|
2844
|
+
}
|
|
2845
|
+
else if ((_b = obj === null || obj === void 0 ? void 0 : obj.headers) === null || _b === void 0 ? void 0 : _b.ContentType) {
|
|
2846
|
+
contentType = obj.headers.ContentType;
|
|
2847
|
+
delete obj.headers.ContentType;
|
|
2848
|
+
}
|
|
2849
|
+
else if ((_c = obj === null || obj === void 0 ? void 0 : obj.headers) === null || _c === void 0 ? void 0 : _c['content-type']) {
|
|
2850
|
+
contentType = obj.headers['content-type'];
|
|
2851
|
+
delete obj.headers['content-type'];
|
|
2852
|
+
}
|
|
2853
|
+
if (contentType !== '' && obj.headers) {
|
|
2854
|
+
obj.headers['Content-Type'] = contentType;
|
|
2855
|
+
}
|
|
2856
|
+
return obj;
|
|
2857
|
+
});
|
|
2858
|
+
if ('resolveWithFullResponse' in options && options.resolveWithFullResponse) {
|
|
2859
|
+
return instance.request(opt);
|
|
2860
|
+
}
|
|
2861
|
+
else {
|
|
2862
|
+
return instance.request(opt).then(res => {
|
|
2863
|
+
// use old request option format
|
|
2864
|
+
if (opt.__isOldOptions) {
|
|
2865
|
+
if ('json' in options) {
|
|
2866
|
+
if (options.json) {
|
|
2867
|
+
return res.data;
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
else {
|
|
2871
|
+
return JSON.stringify(res.data);
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
else {
|
|
2875
|
+
return res.data;
|
|
2876
|
+
}
|
|
2877
|
+
});
|
|
2878
|
+
}
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2882
|
+
class DB {
|
|
2883
|
+
constructor(ctx) {
|
|
2884
|
+
this.ctx = ctx;
|
|
2885
|
+
this.db = new JSONStore(this.ctx.configPath);
|
|
2886
|
+
if (!this.db.has('picBed')) {
|
|
2887
|
+
try {
|
|
2888
|
+
this.db.set('picBed', {
|
|
2889
|
+
uploader: 'smms',
|
|
2890
|
+
current: 'smms'
|
|
2891
|
+
});
|
|
2892
|
+
}
|
|
2893
|
+
catch (e) {
|
|
2894
|
+
this.ctx.log.error(e);
|
|
2895
|
+
throw e;
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
if (!this.db.has('picgoPlugins')) {
|
|
2899
|
+
try {
|
|
2900
|
+
this.db.set('picgoPlugins', {});
|
|
2901
|
+
}
|
|
2902
|
+
catch (e) {
|
|
2903
|
+
this.ctx.log.error(e);
|
|
2904
|
+
throw e;
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
read(flush) {
|
|
2909
|
+
return this.db.read(flush);
|
|
2910
|
+
}
|
|
2911
|
+
get(key = '') {
|
|
2912
|
+
this.read(true);
|
|
2913
|
+
return this.db.get(key);
|
|
2914
|
+
}
|
|
2915
|
+
set(key, value) {
|
|
2916
|
+
this.read(true);
|
|
2917
|
+
return this.db.set(key, value);
|
|
2918
|
+
}
|
|
2919
|
+
has(key) {
|
|
2920
|
+
this.read(true);
|
|
2921
|
+
return this.db.has(key);
|
|
2922
|
+
}
|
|
2923
|
+
unset(key, value) {
|
|
2924
|
+
this.read(true);
|
|
2925
|
+
return this.db.unset(key, value);
|
|
2926
|
+
}
|
|
2927
|
+
saveConfig(config) {
|
|
2928
|
+
Object.keys(config).forEach((name) => {
|
|
2929
|
+
this.set(name, config[name]);
|
|
2930
|
+
});
|
|
2931
|
+
}
|
|
2932
|
+
removeConfig(config) {
|
|
2933
|
+
Object.keys(config).forEach((name) => {
|
|
2934
|
+
this.unset(name, config[name]);
|
|
2935
|
+
});
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
// const initConfig = (configPath: string): lowdb.LowdbSync<any> => {
|
|
2939
|
+
// }
|
|
2940
|
+
// const saveConfig = (configPath: string, config: any): void => {
|
|
2941
|
+
// const db = initConfig(configPath)
|
|
2942
|
+
// Object.keys(config).forEach((name: string) => {
|
|
2943
|
+
// db.read().set(name, config[name]).write()
|
|
2944
|
+
// })
|
|
2945
|
+
// }
|
|
2946
|
+
// export {
|
|
2947
|
+
// initConfig,
|
|
2948
|
+
// saveConfig
|
|
2949
|
+
// }
|
|
2950
|
+
|
|
2951
|
+
class PluginHandler {
|
|
2952
|
+
constructor(ctx) {
|
|
2953
|
+
this.ctx = ctx;
|
|
2954
|
+
}
|
|
2955
|
+
async install(plugins, options = {}, env) {
|
|
2956
|
+
const installedPlugins = [];
|
|
2957
|
+
const processPlugins = plugins
|
|
2958
|
+
.map((item) => handlePluginNameProcess(this.ctx, item))
|
|
2959
|
+
.filter((item) => {
|
|
2960
|
+
// detect if has already installed
|
|
2961
|
+
// or will cause error
|
|
2962
|
+
if (this.ctx.pluginLoader.hasPlugin(item.pkgName)) {
|
|
2963
|
+
installedPlugins.push(item.pkgName);
|
|
2964
|
+
this.ctx.log.success(`PicGo has already installed ${item.pkgName}`);
|
|
2965
|
+
return false;
|
|
2966
|
+
}
|
|
2967
|
+
// if something wrong, filter it out
|
|
2968
|
+
if (!item.success) {
|
|
2969
|
+
return false;
|
|
2970
|
+
}
|
|
2971
|
+
return true;
|
|
2972
|
+
});
|
|
2973
|
+
const fullNameList = processPlugins.map(item => item.fullName);
|
|
2974
|
+
const pkgNameList = processPlugins.map(item => item.pkgName);
|
|
2975
|
+
if (fullNameList.length > 0) {
|
|
2976
|
+
// install plugins must use fullNameList:
|
|
2977
|
+
// 1. install remote pacage
|
|
2978
|
+
// 2. install local pacage
|
|
2979
|
+
const result = await this.execCommand('install', fullNameList, this.ctx.baseDir, options, env);
|
|
2980
|
+
if (!result.code) {
|
|
2981
|
+
pkgNameList.forEach((pluginName) => {
|
|
2982
|
+
this.ctx.pluginLoader.registerPlugin(pluginName);
|
|
2983
|
+
});
|
|
2984
|
+
this.ctx.log.success(this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS'));
|
|
2985
|
+
this.ctx.emit('installSuccess', {
|
|
2986
|
+
title: this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS'),
|
|
2987
|
+
body: [...pkgNameList, ...installedPlugins]
|
|
2988
|
+
});
|
|
2989
|
+
const res = {
|
|
2990
|
+
success: true,
|
|
2991
|
+
body: [...pkgNameList, ...installedPlugins]
|
|
2992
|
+
};
|
|
2993
|
+
return res;
|
|
2994
|
+
}
|
|
2995
|
+
else {
|
|
2996
|
+
const err = this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON', {
|
|
2997
|
+
code: `${result.code}`,
|
|
2998
|
+
data: result.data
|
|
2999
|
+
});
|
|
3000
|
+
this.ctx.log.error(err);
|
|
3001
|
+
this.ctx.emit('installFailed', {
|
|
3002
|
+
title: this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED'),
|
|
3003
|
+
body: err
|
|
3004
|
+
});
|
|
3005
|
+
const res = {
|
|
3006
|
+
success: false,
|
|
3007
|
+
body: err
|
|
3008
|
+
};
|
|
3009
|
+
return res;
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
else if (installedPlugins.length === 0) {
|
|
3013
|
+
const err = this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID');
|
|
3014
|
+
this.ctx.log.error(err);
|
|
3015
|
+
this.ctx.emit('installFailed', {
|
|
3016
|
+
title: this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED'),
|
|
3017
|
+
body: err
|
|
3018
|
+
});
|
|
3019
|
+
const res = {
|
|
3020
|
+
success: false,
|
|
3021
|
+
body: err
|
|
3022
|
+
};
|
|
3023
|
+
return res;
|
|
3024
|
+
}
|
|
3025
|
+
else {
|
|
3026
|
+
this.ctx.log.success(this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS'));
|
|
3027
|
+
this.ctx.emit('installSuccess', {
|
|
3028
|
+
title: this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS'),
|
|
3029
|
+
body: [...pkgNameList, ...installedPlugins]
|
|
3030
|
+
});
|
|
3031
|
+
const res = {
|
|
3032
|
+
success: true,
|
|
3033
|
+
body: [...pkgNameList, ...installedPlugins]
|
|
3034
|
+
};
|
|
3035
|
+
return res;
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
async uninstall(plugins) {
|
|
3039
|
+
const processPlugins = plugins.map((item) => handlePluginNameProcess(this.ctx, item)).filter(item => item.success);
|
|
3040
|
+
const pkgNameList = processPlugins.map(item => item.pkgName);
|
|
3041
|
+
if (pkgNameList.length > 0) {
|
|
3042
|
+
// uninstall plugins must use pkgNameList:
|
|
3043
|
+
// npm uninstall will use the package.json's name
|
|
3044
|
+
const result = await this.execCommand('uninstall', pkgNameList, this.ctx.baseDir);
|
|
3045
|
+
if (!result.code) {
|
|
3046
|
+
pkgNameList.forEach((pluginName) => {
|
|
3047
|
+
this.ctx.pluginLoader.unregisterPlugin(pluginName);
|
|
3048
|
+
});
|
|
3049
|
+
this.ctx.log.success(this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS'));
|
|
3050
|
+
this.ctx.emit('uninstallSuccess', {
|
|
3051
|
+
title: this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS'),
|
|
3052
|
+
body: pkgNameList
|
|
3053
|
+
});
|
|
3054
|
+
const res = {
|
|
3055
|
+
success: true,
|
|
3056
|
+
body: pkgNameList
|
|
3057
|
+
};
|
|
3058
|
+
return res;
|
|
3059
|
+
}
|
|
3060
|
+
else {
|
|
3061
|
+
const err = this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON', {
|
|
3062
|
+
code: `${result.code}`,
|
|
3063
|
+
data: result.data
|
|
3064
|
+
});
|
|
3065
|
+
this.ctx.log.error(err);
|
|
3066
|
+
this.ctx.emit('uninstallFailed', {
|
|
3067
|
+
title: this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED'),
|
|
3068
|
+
body: err
|
|
3069
|
+
});
|
|
3070
|
+
const res = {
|
|
3071
|
+
success: false,
|
|
3072
|
+
body: err
|
|
3073
|
+
};
|
|
3074
|
+
return res;
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
else {
|
|
3078
|
+
const err = this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID');
|
|
3079
|
+
this.ctx.log.error(err);
|
|
3080
|
+
this.ctx.emit('uninstallFailed', {
|
|
3081
|
+
title: this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED'),
|
|
3082
|
+
body: err
|
|
3083
|
+
});
|
|
3084
|
+
const res = {
|
|
3085
|
+
success: false,
|
|
3086
|
+
body: err
|
|
3087
|
+
};
|
|
3088
|
+
return res;
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
3091
|
+
async update(plugins, options = {}, env) {
|
|
3092
|
+
const processPlugins = plugins.map((item) => handlePluginNameProcess(this.ctx, item)).filter(item => item.success);
|
|
3093
|
+
const pkgNameList = processPlugins.map(item => item.pkgName);
|
|
3094
|
+
if (pkgNameList.length > 0) {
|
|
3095
|
+
// update plugins must use pkgNameList:
|
|
3096
|
+
// npm update will use the package.json's name
|
|
3097
|
+
const result = await this.execCommand('update', pkgNameList, this.ctx.baseDir, options, env);
|
|
3098
|
+
if (!result.code) {
|
|
3099
|
+
this.ctx.log.success(this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS'));
|
|
3100
|
+
this.ctx.emit('updateSuccess', {
|
|
3101
|
+
title: this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS'),
|
|
3102
|
+
body: pkgNameList
|
|
3103
|
+
});
|
|
3104
|
+
const res = {
|
|
3105
|
+
success: true,
|
|
3106
|
+
body: pkgNameList
|
|
3107
|
+
};
|
|
3108
|
+
return res;
|
|
3109
|
+
}
|
|
3110
|
+
else {
|
|
3111
|
+
const err = this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON', {
|
|
3112
|
+
code: `${result.code}`,
|
|
3113
|
+
data: result.data
|
|
3114
|
+
});
|
|
3115
|
+
this.ctx.log.error(err);
|
|
3116
|
+
this.ctx.emit('updateFailed', {
|
|
3117
|
+
title: this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED'),
|
|
3118
|
+
body: err
|
|
3119
|
+
});
|
|
3120
|
+
const res = {
|
|
3121
|
+
success: false,
|
|
3122
|
+
body: err
|
|
3123
|
+
};
|
|
3124
|
+
return res;
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3127
|
+
else {
|
|
3128
|
+
const err = this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID');
|
|
3129
|
+
this.ctx.log.error(err);
|
|
3130
|
+
this.ctx.emit('updateFailed', {
|
|
3131
|
+
title: this.ctx.i18n.translate('PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED'),
|
|
3132
|
+
body: err
|
|
3133
|
+
});
|
|
3134
|
+
const res = {
|
|
3135
|
+
success: false,
|
|
3136
|
+
body: err
|
|
3137
|
+
};
|
|
3138
|
+
return res;
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
async execCommand(cmd, modules, where, options = {}, env = {}) {
|
|
3142
|
+
// options first
|
|
3143
|
+
const registry = options.registry || this.ctx.getConfig('settings.registry');
|
|
3144
|
+
const proxy = options.proxy || this.ctx.getConfig('settings.proxy');
|
|
3145
|
+
return await new Promise((resolve) => {
|
|
3146
|
+
var _a, _b;
|
|
3147
|
+
let args = [cmd].concat(modules).concat('--color=always').concat('--save');
|
|
3148
|
+
if (registry) {
|
|
3149
|
+
args = args.concat(`--registry=${registry}`);
|
|
3150
|
+
}
|
|
3151
|
+
if (proxy) {
|
|
3152
|
+
args = args.concat(`--proxy=${proxy}`);
|
|
3153
|
+
}
|
|
3154
|
+
try {
|
|
3155
|
+
const npm = spawn$1('npm', args, { cwd: where, env: Object.assign({}, process.env, env) });
|
|
3156
|
+
let output = '';
|
|
3157
|
+
(_a = npm.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
3158
|
+
output += data;
|
|
3159
|
+
}).pipe(process.stdout);
|
|
3160
|
+
(_b = npm.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
|
|
3161
|
+
output += data;
|
|
3162
|
+
}).pipe(process.stderr);
|
|
3163
|
+
npm.on('close', (code) => {
|
|
3164
|
+
if (!code) {
|
|
3165
|
+
resolve({ code: 0, data: output });
|
|
3166
|
+
}
|
|
3167
|
+
else {
|
|
3168
|
+
resolve({ code: code, data: output });
|
|
3169
|
+
}
|
|
3170
|
+
});
|
|
3171
|
+
// for users who haven't installed node.js
|
|
3172
|
+
npm.on('error', (err) => {
|
|
3173
|
+
this.ctx.log.error(err);
|
|
3174
|
+
this.ctx.log.error('NPM is not installed');
|
|
3175
|
+
this.ctx.emit(IBuildInEvent.FAILED, 'NPM is not installed');
|
|
3176
|
+
});
|
|
3177
|
+
}
|
|
3178
|
+
catch (e) {
|
|
3179
|
+
this.ctx.log.error(e);
|
|
3180
|
+
this.ctx.emit(IBuildInEvent.FAILED, e);
|
|
3181
|
+
}
|
|
3182
|
+
});
|
|
3183
|
+
}
|
|
3184
|
+
}
|
|
3185
|
+
/**
|
|
3186
|
+
* transform the input plugin name or path string to valid result
|
|
3187
|
+
* @param ctx
|
|
3188
|
+
* @param nameOrPath
|
|
3189
|
+
*/
|
|
3190
|
+
const handlePluginNameProcess = (ctx, nameOrPath) => {
|
|
3191
|
+
const res = {
|
|
3192
|
+
success: false,
|
|
3193
|
+
fullName: '',
|
|
3194
|
+
pkgName: ''
|
|
3195
|
+
};
|
|
3196
|
+
const result = getProcessPluginName(nameOrPath, ctx.log);
|
|
3197
|
+
if (!result) {
|
|
3198
|
+
return res;
|
|
3199
|
+
}
|
|
3200
|
+
// first get result then do this process
|
|
3201
|
+
// or some error will log twice
|
|
3202
|
+
const pkgName = getNormalPluginName(result, ctx.log);
|
|
3203
|
+
if (!pkgName) {
|
|
3204
|
+
return res;
|
|
3205
|
+
}
|
|
3206
|
+
return {
|
|
3207
|
+
success: true,
|
|
3208
|
+
fullName: result,
|
|
3209
|
+
pkgName
|
|
3210
|
+
};
|
|
3211
|
+
};
|
|
3212
|
+
|
|
3213
|
+
/* eslint-disable no-template-curly-in-string */
|
|
3214
|
+
const ZH_CN = {
|
|
3215
|
+
UPLOAD_FAILED: '上传失败',
|
|
3216
|
+
CHECK_SETTINGS: '请检查你的配置项是否正确',
|
|
3217
|
+
CHECK_SETTINGS_AND_NETWORK: '请检查你的配置项以及网络',
|
|
3218
|
+
UPLOAD_FAILED_REASON: '错误码:${code},请打开浏览器粘贴地址查看相关原因',
|
|
3219
|
+
SERVER_ERROR: '服务端出错,请重试',
|
|
3220
|
+
AUTH_FAILED: '认证失败',
|
|
3221
|
+
// smms
|
|
3222
|
+
PICBED_SMMS: 'SM.MS',
|
|
3223
|
+
PICBED_SMMS_TOKEN: '设定Token',
|
|
3224
|
+
PICBED_SMMS_BACKUP_DOMAIN: '备用上传域名',
|
|
3225
|
+
PICBED_SMMS_MESSAGE_BACKUP_DOMAIN: '例如 smms.app',
|
|
3226
|
+
// Ali-cloud
|
|
3227
|
+
PICBED_ALICLOUD: '阿里云OSS',
|
|
3228
|
+
PICBED_ALICLOUD_ACCESSKEYID: '设定KeyId',
|
|
3229
|
+
PICBED_ALICLOUD_ACCESSKEYSECRET: '设定KeySecret',
|
|
3230
|
+
PICBED_ALICLOUD_BUCKET: '设定Bucket',
|
|
3231
|
+
PICBED_ALICLOUD_AREA: '设定存储区域',
|
|
3232
|
+
PICBED_ALICLOUD_PATH: '设定存储路径',
|
|
3233
|
+
PICBED_ALICLOUD_CUSTOMURL: '设定自定义域名',
|
|
3234
|
+
PICBED_ALICLOUD_OPTIONS: '设定网址后缀',
|
|
3235
|
+
PICBED_ALICLOUD_MESSAGE_AREA: '例如:oss-cn-beijing',
|
|
3236
|
+
PICBED_ALICLOUD_MESSAGE_PATH: '例如:test/',
|
|
3237
|
+
PICBED_ALICLOUD_MESSAGE_OPTIONS: '例如:?x-oss-process=xxx',
|
|
3238
|
+
PICBED_ALICLOUD_MESSAGE_CUSTOMURL: '例如:https://test.com',
|
|
3239
|
+
// Tencent-cloud
|
|
3240
|
+
PICBED_TENCENTCLOUD: '腾讯云COS',
|
|
3241
|
+
PICBED_TENCENTCLOUD_VERSION: 'COS版本',
|
|
3242
|
+
PICBED_TENCENTCLOUD_SECRETID: '设定SecretId',
|
|
3243
|
+
PICBED_TENCENTCLOUD_SECRETKEY: '设定SecretKey',
|
|
3244
|
+
PICBED_TENCENTCLOUD_APPID: '设定AppId',
|
|
3245
|
+
PICBED_TENCENTCLOUD_BUCKET: '设定Bucket',
|
|
3246
|
+
PICBED_TENCENTCLOUD_AREA: '设定存储区域',
|
|
3247
|
+
PICBED_TENCENTCLOUD_PATH: '设定存储路径',
|
|
3248
|
+
PICBED_TENCENTCLOUD_OPTIONS: '设定网址后缀',
|
|
3249
|
+
PICBED_TENCENTCLOUD_CUSTOMURL: '设定自定义域名',
|
|
3250
|
+
PICBED_TENCENTCLOUD_MESSAGE_APPID: '例如:1234567890',
|
|
3251
|
+
PICBED_TENCENTCLOUD_MESSAGE_AREA: '例如:ap-beijing',
|
|
3252
|
+
PICBED_TENCENTCLOUD_MESSAGE_PATH: '例如:test/',
|
|
3253
|
+
PICBED_TENCENTCLOUD_MESSAGE_CUSTOMURL: '例如:https://test.com',
|
|
3254
|
+
PICBED_TENCENTCLOUD_MESSAGE_OPTIONS: '例如:?imageMogr2',
|
|
3255
|
+
// GitHub
|
|
3256
|
+
PICBED_GITHUB: 'GitHub',
|
|
3257
|
+
PICBED_GITHUB_TOKEN: '设定Token',
|
|
3258
|
+
PICBED_GITHUB_REPO: '设定仓库名',
|
|
3259
|
+
PICBED_GITHUB_PATH: '设定存储路径',
|
|
3260
|
+
PICBED_GITHUB_BRANCH: '设定分支名',
|
|
3261
|
+
PICBED_GITHUB_CUSTOMURL: '设定自定义域名',
|
|
3262
|
+
PICBED_GITHUB_MESSAGE_REPO: '格式:username/repo',
|
|
3263
|
+
PICBED_GITHUB_MESSAGE_BRANCH: '例如:main',
|
|
3264
|
+
PICBED_GITHUB_MESSAGE_PATH: '例如:test/',
|
|
3265
|
+
PICBED_GITHUB_MESSAGE_CUSTOMURL: '例如:https://test.com',
|
|
3266
|
+
// qiniu
|
|
3267
|
+
PICBED_QINIU: '七牛云',
|
|
3268
|
+
PICBED_QINIU_ACCESSKEY: '设定AccessKey',
|
|
3269
|
+
PICBED_QINIU_SECRETKEY: '设定SecretKey',
|
|
3270
|
+
PICBED_QINIU_BUCKET: '设定Bucket',
|
|
3271
|
+
PICBED_QINIU_PATH: '设定存储路径',
|
|
3272
|
+
PICBED_QINIU_URL: '设定访问网址',
|
|
3273
|
+
PICBED_QINIU_OPTIONS: '设定网址后缀',
|
|
3274
|
+
PICBED_QINIU_AREA: '设定存储区域',
|
|
3275
|
+
PICBED_QINIU_MESSAGE_PATH: '例如:test/',
|
|
3276
|
+
PICBED_QINIU_MESSAGE_AREA: '例如:z0',
|
|
3277
|
+
PICBED_QINIU_MESSAGE_OPTIONS: '例如:?imageslim',
|
|
3278
|
+
PICBED_QINIU_MESSAGE_URL: '例如:https://xxx.yyy.glb.clouddn.com',
|
|
3279
|
+
// imgur
|
|
3280
|
+
PICBED_IMGUR: 'Imgur',
|
|
3281
|
+
PICBED_IMGUR_CLIENTID: '设定ClientId',
|
|
3282
|
+
PICBED_IMGUR_PROXY: '设定代理',
|
|
3283
|
+
PICBED_IMGUR_MESSAGE_PROXY: '例如:http://127.0.0.1:1080',
|
|
3284
|
+
// upyun
|
|
3285
|
+
PICBED_UPYUN: '又拍云',
|
|
3286
|
+
PICBED_UPYUN_BUCKET: '设定Bucket',
|
|
3287
|
+
PICBED_UPYUN_OPERATOR: '设定操作员',
|
|
3288
|
+
PICBED_UPYUN_PASSWORD: '设定操作员密码',
|
|
3289
|
+
PICBED_UPYUN_PATH: '设定存储路径',
|
|
3290
|
+
PICBED_UPYUN_URL: '设定加速域名',
|
|
3291
|
+
PICBED_UPYUN_OPTIONS: '设定网址后缀',
|
|
3292
|
+
PICBED_UPYUN_MESSAGE_OPERATOR: '例如:me',
|
|
3293
|
+
PICBED_UPYUN_MESSAGE_PASSWORD: '输入操作员密码',
|
|
3294
|
+
PICBED_UPYUN_MESSAGE_URL: '例如:http://xxx.test.upcdn.net',
|
|
3295
|
+
PICBED_UPYUN_MESSAGE_OPTIONS: '例如:!imgslim',
|
|
3296
|
+
PICBED_UPYUN_MESSAGE_PATH: '例如:test/',
|
|
3297
|
+
// Plugin Handler
|
|
3298
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS: '插件安装成功',
|
|
3299
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED: '插件安装失败',
|
|
3300
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON: '插件安装失败,失败码为${code},错误日志为 \n ${data}',
|
|
3301
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_PATH: '插件安装失败,请输入合法插件名或合法安装路径',
|
|
3302
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS: '插件卸载成功',
|
|
3303
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED: '插件卸载失败',
|
|
3304
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON: '插件卸载失败,失败码为${code},错误日志为 \n ${data}',
|
|
3305
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID: '插件卸载失败,请输入合法插件名',
|
|
3306
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS: '插件更新成功',
|
|
3307
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED: '插件更新失败',
|
|
3308
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON: '插件更新失败,失败码为${code},错误日志为 \n ${data}',
|
|
3309
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID: '插件更新失败,请输入合法插件名'
|
|
3310
|
+
};
|
|
3311
|
+
|
|
3312
|
+
/* eslint-disable no-template-curly-in-string */
|
|
3313
|
+
const EN = {
|
|
3314
|
+
UPLOAD_FAILED: 'Upload failed',
|
|
3315
|
+
CHECK_SETTINGS: 'Please check your settings',
|
|
3316
|
+
CHECK_SETTINGS_AND_NETWORK: 'Please check your settings and network',
|
|
3317
|
+
UPLOAD_FAILED_REASON: 'Error code: ${code}, please open the browser and paste the address to see the reason',
|
|
3318
|
+
SERVER_ERROR: 'Server error, please try again later',
|
|
3319
|
+
AUTH_FAILED: 'Authentication failed',
|
|
3320
|
+
// smms
|
|
3321
|
+
PICBED_SMMS: 'SM.MS',
|
|
3322
|
+
PICBED_SMMS_TOKEN: 'Set Token',
|
|
3323
|
+
PICBED_SMMS_BACKUP_DOMAIN: 'Set Backup Upload Domain',
|
|
3324
|
+
PICBED_SMMS_MESSAGE_BACKUP_DOMAIN: 'Ex. smms.app',
|
|
3325
|
+
// Ali-cloud
|
|
3326
|
+
PICBED_ALICLOUD: 'Ali Cloud',
|
|
3327
|
+
PICBED_ALICLOUD_ACCESSKEYID: 'Set KeyId',
|
|
3328
|
+
PICBED_ALICLOUD_ACCESSKEYSECRET: 'Set KeySecret',
|
|
3329
|
+
PICBED_ALICLOUD_BUCKET: 'Set Bucket',
|
|
3330
|
+
PICBED_ALICLOUD_AREA: 'Set Area',
|
|
3331
|
+
PICBED_ALICLOUD_PATH: 'Set Path',
|
|
3332
|
+
PICBED_ALICLOUD_CUSTOMURL: 'Set Custom URL',
|
|
3333
|
+
PICBED_ALICLOUD_OPTIONS: 'Set URL Suffix',
|
|
3334
|
+
PICBED_ALICLOUD_MESSAGE_AREA: 'Ex. oss-cn-beijing',
|
|
3335
|
+
PICBED_ALICLOUD_MESSAGE_PATH: 'Ex. test/',
|
|
3336
|
+
PICBED_ALICLOUD_MESSAGE_OPTIONS: 'Ex. ?x-oss-process=xxx',
|
|
3337
|
+
PICBED_ALICLOUD_MESSAGE_CUSTOMURL: 'Ex. https://test.com',
|
|
3338
|
+
// Tencent-cloud
|
|
3339
|
+
PICBED_TENCENTCLOUD: 'Tencent Cloud',
|
|
3340
|
+
PICBED_TENCENTCLOUD_VERSION: 'Choose COS version',
|
|
3341
|
+
PICBED_TENCENTCLOUD_SECRETID: 'Set SecretId',
|
|
3342
|
+
PICBED_TENCENTCLOUD_SECRETKEY: 'Set SecretKey',
|
|
3343
|
+
PICBED_TENCENTCLOUD_APPID: 'Set AppId',
|
|
3344
|
+
PICBED_TENCENTCLOUD_BUCKET: 'Set Bucket',
|
|
3345
|
+
PICBED_TENCENTCLOUD_AREA: 'Set Area',
|
|
3346
|
+
PICBED_TENCENTCLOUD_PATH: 'Set Path',
|
|
3347
|
+
PICBED_TENCENTCLOUD_OPTIONS: 'Set URL Suffix',
|
|
3348
|
+
PICBED_TENCENTCLOUD_CUSTOMURL: 'Set Custom URL',
|
|
3349
|
+
PICBED_TENCENTCLOUD_MESSAGE_APPID: 'Ex. 1234567890',
|
|
3350
|
+
PICBED_TENCENTCLOUD_MESSAGE_AREA: 'Ex. ap-beijing',
|
|
3351
|
+
PICBED_TENCENTCLOUD_MESSAGE_PATH: 'Ex. test/',
|
|
3352
|
+
PICBED_TENCENTCLOUD_MESSAGE_CUSTOMURL: 'Ex. http://test.com',
|
|
3353
|
+
PICBED_TENCENTCLOUD_MESSAGE_OPTIONS: 'Ex. ?imageMogr2',
|
|
3354
|
+
// GitHub
|
|
3355
|
+
PICBED_GITHUB: 'GitHub',
|
|
3356
|
+
PICBED_GITHUB_TOKEN: 'Set Token',
|
|
3357
|
+
PICBED_GITHUB_REPO: 'Set Repo Name',
|
|
3358
|
+
PICBED_GITHUB_PATH: 'Set Path',
|
|
3359
|
+
PICBED_GITHUB_BRANCH: 'Set Branch',
|
|
3360
|
+
PICBED_GITHUB_CUSTOMURL: 'Set Custom URL',
|
|
3361
|
+
PICBED_GITHUB_MESSAGE_REPO: 'Ex. username/repo',
|
|
3362
|
+
PICBED_GITHUB_MESSAGE_BRANCH: 'Ex. main',
|
|
3363
|
+
PICBED_GITHUB_MESSAGE_PATH: 'Ex. test/',
|
|
3364
|
+
PICBED_GITHUB_MESSAGE_CUSTOMURL: 'Ex. https://test.com',
|
|
3365
|
+
// qiniu
|
|
3366
|
+
PICBED_QINIU: 'Qiniu',
|
|
3367
|
+
PICBED_QINIU_ACCESSKEY: 'Set AccessKey',
|
|
3368
|
+
PICBED_QINIU_SECRETKEY: 'Set SecretKey',
|
|
3369
|
+
PICBED_QINIU_BUCKET: 'Set Bucket',
|
|
3370
|
+
PICBED_QINIU_PATH: 'Set Path',
|
|
3371
|
+
PICBED_QINIU_URL: 'Set URL',
|
|
3372
|
+
PICBED_QINIU_OPTIONS: 'Set URL Suffix',
|
|
3373
|
+
PICBED_QINIU_AREA: 'Set Area',
|
|
3374
|
+
PICBED_QINIU_MESSAGE_PATH: 'Ex. test/',
|
|
3375
|
+
PICBED_QINIU_MESSAGE_AREA: 'Ex. z0',
|
|
3376
|
+
PICBED_QINIU_MESSAGE_OPTIONS: 'Ex. ?imageslim',
|
|
3377
|
+
PICBED_QINIU_MESSAGE_URL: 'Ex. https://xxx.yyy.glb.clouddn.com',
|
|
3378
|
+
// imgur
|
|
3379
|
+
PICBED_IMGUR: 'Imgur',
|
|
3380
|
+
PICBED_IMGUR_CLIENTID: 'Set ClientId',
|
|
3381
|
+
PICBED_IMGUR_PROXY: 'Set Proxy',
|
|
3382
|
+
PICBED_IMGUR_MESSAGE_PROXY: 'Ex. http://127.0.0.1:1080',
|
|
3383
|
+
// upyun
|
|
3384
|
+
PICBED_UPYUN: 'Upyun',
|
|
3385
|
+
PICBED_UPYUN_BUCKET: 'Set Bucket',
|
|
3386
|
+
PICBED_UPYUN_OPERATOR: 'Set Operator',
|
|
3387
|
+
PICBED_UPYUN_PASSWORD: 'Set Operator Password',
|
|
3388
|
+
PICBED_UPYUN_PATH: 'Set Path',
|
|
3389
|
+
PICBED_UPYUN_URL: 'Set URL',
|
|
3390
|
+
PICBED_UPYUN_OPTIONS: 'Set URL Suffix',
|
|
3391
|
+
PICBED_UPYUN_MESSAGE_OPERATOR: 'Ex. me',
|
|
3392
|
+
PICBED_UPYUN_MESSAGE_PASSWORD: 'Please type the operator password',
|
|
3393
|
+
PICBED_UPYUN_MESSAGE_URL: 'Ex. http://xxx.test.upcdn.net',
|
|
3394
|
+
PICBED_UPYUN_MESSAGE_OPTIONS: 'Ex. !imgslim',
|
|
3395
|
+
PICBED_UPYUN_MESSAGE_PATH: 'Ex. test/',
|
|
3396
|
+
// Plugin Handler
|
|
3397
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS: 'Plugin installed successfully',
|
|
3398
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED: 'Plugin installation failed',
|
|
3399
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON: 'Plugin installation failed, error code is ${code}, error log is \n ${data}',
|
|
3400
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_PATH: 'Plugin installation failed, please enter a valid plugin name or valid installation path',
|
|
3401
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS: 'Plugin uninstalled successfully',
|
|
3402
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED: 'Plugin uninstall failed',
|
|
3403
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON: 'Plugin uninstall failed, error code is ${code}, error log is \n ${data}',
|
|
3404
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID: 'Plugin uninstall failed, please enter a valid plugin name',
|
|
3405
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS: 'Plugin updated successfully',
|
|
3406
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED: 'Plugin update failed',
|
|
3407
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON: 'Plugin update failed, error code is ${code}, error log is \n ${data}',
|
|
3408
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID: 'Plugin update failed, please enter a valid plugin name'
|
|
3409
|
+
};
|
|
3410
|
+
|
|
3411
|
+
/* eslint-disable no-template-curly-in-string */
|
|
3412
|
+
const ZH_TW = {
|
|
3413
|
+
UPLOAD_FAILED: '上傳失敗',
|
|
3414
|
+
CHECK_SETTINGS: '請檢查你的設定是否正確',
|
|
3415
|
+
CHECK_SETTINGS_AND_NETWORK: '請檢查你的設定及網路',
|
|
3416
|
+
UPLOAD_FAILED_REASON: '錯誤碼:${code},請打開瀏覽器貼上地址查看相關原因',
|
|
3417
|
+
SERVER_ERROR: '伺服器出錯,請重試',
|
|
3418
|
+
AUTH_FAILED: '認證失敗',
|
|
3419
|
+
// smms
|
|
3420
|
+
PICBED_SMMS: 'SM.MS',
|
|
3421
|
+
PICBED_SMMS_TOKEN: '設定Token',
|
|
3422
|
+
PICBED_SMMS_BACKUP_DOMAIN: '備用上傳網址',
|
|
3423
|
+
PICBED_SMMS_MESSAGE_BACKUP_DOMAIN: '例如 smms.app',
|
|
3424
|
+
// Ali-cloud
|
|
3425
|
+
PICBED_ALICLOUD: '阿里云OSS',
|
|
3426
|
+
PICBED_ALICLOUD_ACCESSKEYID: '設定KeyId',
|
|
3427
|
+
PICBED_ALICLOUD_ACCESSKEYSECRET: '設定KeySecret',
|
|
3428
|
+
PICBED_ALICLOUD_BUCKET: '設定Bucket',
|
|
3429
|
+
PICBED_ALICLOUD_AREA: '設定儲存區域',
|
|
3430
|
+
PICBED_ALICLOUD_PATH: '設定儲存路徑',
|
|
3431
|
+
PICBED_ALICLOUD_CUSTOMURL: '設定自訂網址',
|
|
3432
|
+
PICBED_ALICLOUD_OPTIONS: '設定網址後綴',
|
|
3433
|
+
PICBED_ALICLOUD_MESSAGE_AREA: '例如:oss-cn-beijing',
|
|
3434
|
+
PICBED_ALICLOUD_MESSAGE_PATH: '例如:test/',
|
|
3435
|
+
PICBED_ALICLOUD_MESSAGE_OPTIONS: '例如:?x-oss-process=xxx',
|
|
3436
|
+
PICBED_ALICLOUD_MESSAGE_CUSTOMURL: '例如:https://test.com',
|
|
3437
|
+
// Tencent-cloud
|
|
3438
|
+
PICBED_TENCENTCLOUD: '騰訊云COS',
|
|
3439
|
+
PICBED_TENCENTCLOUD_VERSION: 'COS版本',
|
|
3440
|
+
PICBED_TENCENTCLOUD_SECRETID: '設定SecretId',
|
|
3441
|
+
PICBED_TENCENTCLOUD_SECRETKEY: '設定SecretKey',
|
|
3442
|
+
PICBED_TENCENTCLOUD_APPID: '設定AppId',
|
|
3443
|
+
PICBED_TENCENTCLOUD_BUCKET: '設定Bucket',
|
|
3444
|
+
PICBED_TENCENTCLOUD_AREA: '設定儲存區域',
|
|
3445
|
+
PICBED_TENCENTCLOUD_PATH: '設定儲存路徑',
|
|
3446
|
+
PICBED_TENCENTCLOUD_OPTIONS: '設定網址後綴',
|
|
3447
|
+
PICBED_TENCENTCLOUD_CUSTOMURL: '設定自訂網址',
|
|
3448
|
+
PICBED_TENCENTCLOUD_MESSAGE_APPID: '例如:1234567890',
|
|
3449
|
+
PICBED_TENCENTCLOUD_MESSAGE_AREA: '例如:ap-beijing',
|
|
3450
|
+
PICBED_TENCENTCLOUD_MESSAGE_PATH: '例如:test/',
|
|
3451
|
+
PICBED_TENCENTCLOUD_MESSAGE_CUSTOMURL: '例如:https://test.com',
|
|
3452
|
+
PICBED_TENCENTCLOUD_MESSAGE_OPTIONS: '例如:?imageMogr2',
|
|
3453
|
+
// GitHub
|
|
3454
|
+
PICBED_GITHUB: 'GitHub',
|
|
3455
|
+
PICBED_GITHUB_TOKEN: '設定Token',
|
|
3456
|
+
PICBED_GITHUB_REPO: '設定倉庫名稱',
|
|
3457
|
+
PICBED_GITHUB_PATH: '設定儲存路徑',
|
|
3458
|
+
PICBED_GITHUB_BRANCH: '設定分支名稱',
|
|
3459
|
+
PICBED_GITHUB_CUSTOMURL: '設定自訂網址',
|
|
3460
|
+
PICBED_GITHUB_MESSAGE_REPO: '格式:username/repo',
|
|
3461
|
+
PICBED_GITHUB_MESSAGE_BRANCH: '例如:main',
|
|
3462
|
+
PICBED_GITHUB_MESSAGE_PATH: '例如:test/',
|
|
3463
|
+
PICBED_GITHUB_MESSAGE_CUSTOMURL: '例如:https://test.com',
|
|
3464
|
+
// qiniu
|
|
3465
|
+
PICBED_QINIU: '七牛云',
|
|
3466
|
+
PICBED_QINIU_ACCESSKEY: '設定AccessKey',
|
|
3467
|
+
PICBED_QINIU_SECRETKEY: '設定SecretKey',
|
|
3468
|
+
PICBED_QINIU_BUCKET: '設定Bucket',
|
|
3469
|
+
PICBED_QINIU_PATH: '設定儲存路徑',
|
|
3470
|
+
PICBED_QINIU_URL: '設定訪問網址',
|
|
3471
|
+
PICBED_QINIU_OPTIONS: '設定網址後綴',
|
|
3472
|
+
PICBED_QINIU_AREA: '設定儲存區域',
|
|
3473
|
+
PICBED_QINIU_MESSAGE_PATH: '例如:test/',
|
|
3474
|
+
PICBED_QINIU_MESSAGE_AREA: '例如:z0',
|
|
3475
|
+
PICBED_QINIU_MESSAGE_OPTIONS: '例如:?imageslim',
|
|
3476
|
+
PICBED_QINIU_MESSAGE_URL: '例如:https://xxx.yyy.glb.clouddn.com',
|
|
3477
|
+
// imgur
|
|
3478
|
+
PICBED_IMGUR: 'Imgur',
|
|
3479
|
+
PICBED_IMGUR_CLIENTID: '設定ClientId',
|
|
3480
|
+
PICBED_IMGUR_PROXY: '設定PROXY',
|
|
3481
|
+
PICBED_IMGUR_MESSAGE_PROXY: '例如:http://127.0.0.1:1080',
|
|
3482
|
+
// upyun
|
|
3483
|
+
PICBED_UPYUN: '又拍云',
|
|
3484
|
+
PICBED_UPYUN_BUCKET: '設定Bucket',
|
|
3485
|
+
PICBED_UPYUN_OPERATOR: '設定操作員',
|
|
3486
|
+
PICBED_UPYUN_PASSWORD: '設定操作員密碼',
|
|
3487
|
+
PICBED_UPYUN_PATH: '設定儲存路徑',
|
|
3488
|
+
PICBED_UPYUN_URL: '設定加速網址',
|
|
3489
|
+
PICBED_UPYUN_OPTIONS: '設定網址後綴',
|
|
3490
|
+
PICBED_UPYUN_MESSAGE_OPERATOR: '例如:me',
|
|
3491
|
+
PICBED_UPYUN_MESSAGE_PASSWORD: '輸入操作員密碼',
|
|
3492
|
+
PICBED_UPYUN_MESSAGE_URL: '例如:http://xxx.test.upcdn.net',
|
|
3493
|
+
PICBED_UPYUN_MESSAGE_OPTIONS: '例如:!imgslim',
|
|
3494
|
+
PICBED_UPYUN_MESSAGE_PATH: '例如:test/',
|
|
3495
|
+
// Plugin Handler
|
|
3496
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS: '插件安裝成功',
|
|
3497
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED: '插件安裝失敗',
|
|
3498
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON: '插件安裝失敗,失敗碼為${code},錯誤紀錄為 \n ${data}',
|
|
3499
|
+
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_PATH: '插件安裝失敗,請輸入正確的插件名稱或正確的安裝路徑',
|
|
3500
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS: '插件卸載成功',
|
|
3501
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED: '插件卸載失敗',
|
|
3502
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON: '插件卸載失敗,失敗碼為${code},錯誤紀錄為 \n ${data}',
|
|
3503
|
+
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID: '插件卸載失敗,請輸入正確的插件名稱',
|
|
3504
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS: '插件更新成功',
|
|
3505
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED: '插件更新失敗',
|
|
3506
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON: '插件更新失敗,失敗碼為${code},錯誤紀錄為 \n ${data}',
|
|
3507
|
+
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID: '插件更新失敗,請輸入正確的插件名稱'
|
|
3508
|
+
};
|
|
3509
|
+
|
|
3510
|
+
const languageList = {
|
|
3511
|
+
'zh-CN': ZH_CN,
|
|
3512
|
+
'zh-TW': ZH_TW,
|
|
3513
|
+
en: EN
|
|
3514
|
+
};
|
|
3515
|
+
class I18nManager {
|
|
3516
|
+
constructor(ctx) {
|
|
3517
|
+
this.ctx = ctx;
|
|
3518
|
+
this.objectAdapter = new ObjectAdapter(languageList);
|
|
3519
|
+
let language = this.ctx.getConfig('settings.language') || 'zh-CN';
|
|
3520
|
+
if (!languageList[language]) {
|
|
3521
|
+
language = 'zh-CN'; // use default
|
|
3522
|
+
}
|
|
3523
|
+
this.i18n = new I18n({
|
|
3524
|
+
adapter: this.objectAdapter,
|
|
3525
|
+
defaultLanguage: language
|
|
3526
|
+
});
|
|
3527
|
+
this.loadOutterI18n();
|
|
3528
|
+
}
|
|
3529
|
+
loadOutterI18n() {
|
|
3530
|
+
const i18nFolder = this.getOutterI18nFolder();
|
|
3531
|
+
const files = fs.readdirSync(i18nFolder, {
|
|
3532
|
+
withFileTypes: true
|
|
3533
|
+
});
|
|
3534
|
+
files.forEach(file => {
|
|
3535
|
+
if (file.isFile() && file.name.endsWith('.yml')) {
|
|
3536
|
+
const i18nFilePath = path.join(i18nFolder, file.name);
|
|
3537
|
+
const i18nFile = fs.readFileSync(i18nFilePath, 'utf8');
|
|
3538
|
+
try {
|
|
3539
|
+
const i18nFileObj = yaml.load(i18nFile);
|
|
3540
|
+
languageList[file.name.replace(/\.yml$/, '')] = i18nFileObj;
|
|
3541
|
+
}
|
|
3542
|
+
catch (e) {
|
|
3543
|
+
console.error(e);
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
});
|
|
3547
|
+
}
|
|
3548
|
+
getOutterI18nFolder() {
|
|
3549
|
+
const i18nFolder = path.join(this.ctx.baseDir, 'i18n-cli');
|
|
3550
|
+
if (!fs.pathExistsSync(i18nFolder)) {
|
|
3551
|
+
fs.ensureDirSync(i18nFolder);
|
|
3552
|
+
}
|
|
3553
|
+
return i18nFolder;
|
|
3554
|
+
}
|
|
3555
|
+
translate(key, args) {
|
|
3556
|
+
return this.i18n.translate(key, args) || key;
|
|
3557
|
+
}
|
|
3558
|
+
setLanguage(language) {
|
|
3559
|
+
this.i18n.setLanguage(language);
|
|
3560
|
+
this.ctx.saveConfig({
|
|
3561
|
+
'settings.language': language
|
|
3562
|
+
});
|
|
3563
|
+
}
|
|
3564
|
+
addLocale(language, locales) {
|
|
3565
|
+
const originLocales = this.objectAdapter.getLocale(language);
|
|
3566
|
+
if (!originLocales) {
|
|
3567
|
+
return false;
|
|
3568
|
+
}
|
|
3569
|
+
const newLocales = merge(originLocales, locales);
|
|
3570
|
+
this.objectAdapter.setLocale(language, newLocales);
|
|
3571
|
+
return true;
|
|
3572
|
+
}
|
|
3573
|
+
addLanguage(language, locales) {
|
|
3574
|
+
const originLocales = this.objectAdapter.getLocale(language);
|
|
3575
|
+
if (originLocales) {
|
|
3576
|
+
return false;
|
|
3577
|
+
}
|
|
3578
|
+
this.objectAdapter.setLocale(language, locales);
|
|
3579
|
+
languageList[language] = locales;
|
|
3580
|
+
return true;
|
|
3581
|
+
}
|
|
3582
|
+
getLanguageList() {
|
|
3583
|
+
return Object.keys(languageList);
|
|
3584
|
+
}
|
|
3585
|
+
}
|
|
3586
|
+
|
|
3587
|
+
class PicGo extends EventEmitter {
|
|
3588
|
+
constructor(configPath = '') {
|
|
3589
|
+
super();
|
|
3590
|
+
this.VERSION = "0.0.1";
|
|
3591
|
+
this.configPath = configPath;
|
|
3592
|
+
this.output = [];
|
|
3593
|
+
this.input = [];
|
|
3594
|
+
this.helper = {
|
|
3595
|
+
transformer: new LifecyclePlugins('transformer'),
|
|
3596
|
+
uploader: new LifecyclePlugins('uploader'),
|
|
3597
|
+
beforeTransformPlugins: new LifecyclePlugins('beforeTransformPlugins'),
|
|
3598
|
+
beforeUploadPlugins: new LifecyclePlugins('beforeUploadPlugins'),
|
|
3599
|
+
afterUploadPlugins: new LifecyclePlugins('afterUploadPlugins')
|
|
3600
|
+
};
|
|
3601
|
+
this.initConfigPath();
|
|
3602
|
+
this.log = new Logger(this);
|
|
3603
|
+
this.cmd = new Commander(this);
|
|
3604
|
+
this.pluginHandler = new PluginHandler(this);
|
|
3605
|
+
this.initConfig();
|
|
3606
|
+
this.init();
|
|
3607
|
+
}
|
|
3608
|
+
get pluginLoader() {
|
|
3609
|
+
return this._pluginLoader;
|
|
3610
|
+
}
|
|
3611
|
+
initConfigPath() {
|
|
3612
|
+
if (this.configPath === '') {
|
|
3613
|
+
this.configPath = homedir() + '/.picgo/config.json';
|
|
3614
|
+
}
|
|
3615
|
+
if (path.extname(this.configPath).toUpperCase() !== '.JSON') {
|
|
3616
|
+
this.configPath = '';
|
|
3617
|
+
throw Error('The configuration file only supports JSON format.');
|
|
3618
|
+
}
|
|
3619
|
+
this.baseDir = path.dirname(this.configPath);
|
|
3620
|
+
const exist = fs.pathExistsSync(this.configPath);
|
|
3621
|
+
if (!exist) {
|
|
3622
|
+
fs.ensureFileSync(`${this.configPath}`);
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
initConfig() {
|
|
3626
|
+
this.db = new DB(this);
|
|
3627
|
+
this._config = this.db.read(true);
|
|
3628
|
+
}
|
|
3629
|
+
init() {
|
|
3630
|
+
try {
|
|
3631
|
+
// init 18n at first
|
|
3632
|
+
this.i18n = new I18nManager(this);
|
|
3633
|
+
this.Request = new Request(this);
|
|
3634
|
+
this._pluginLoader = new PluginLoader(this);
|
|
3635
|
+
// load self plugins
|
|
3636
|
+
setCurrentPluginName('picgo');
|
|
3637
|
+
buildInUploaders(this).register(this);
|
|
3638
|
+
buildInTransformers(this).register(this);
|
|
3639
|
+
setCurrentPluginName('');
|
|
3640
|
+
// load third-party plugins
|
|
3641
|
+
this._pluginLoader.load();
|
|
3642
|
+
this.lifecycle = new Lifecycle(this);
|
|
3643
|
+
}
|
|
3644
|
+
catch (e) {
|
|
3645
|
+
this.emit(IBuildInEvent.UPLOAD_PROGRESS, -1);
|
|
3646
|
+
this.log.error(e);
|
|
3647
|
+
throw e;
|
|
3648
|
+
}
|
|
3649
|
+
}
|
|
3650
|
+
/**
|
|
3651
|
+
* easily mannually load a plugin
|
|
3652
|
+
* if provide plugin name, will register plugin by name
|
|
3653
|
+
* or just instantiate a plugin
|
|
3654
|
+
*/
|
|
3655
|
+
use(plugin, name) {
|
|
3656
|
+
if (name) {
|
|
3657
|
+
this.pluginLoader.registerPlugin(name, plugin);
|
|
3658
|
+
return this.pluginLoader.getPlugin(name);
|
|
3659
|
+
}
|
|
3660
|
+
else {
|
|
3661
|
+
const pluginInstance = plugin(this);
|
|
3662
|
+
return pluginInstance;
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3665
|
+
registerCommands() {
|
|
3666
|
+
if (this.configPath !== '') {
|
|
3667
|
+
this.cmd.init();
|
|
3668
|
+
this.cmd.loadCommands();
|
|
3669
|
+
}
|
|
3670
|
+
}
|
|
3671
|
+
getConfig(name) {
|
|
3672
|
+
if (!name) {
|
|
3673
|
+
return this._config;
|
|
3674
|
+
}
|
|
3675
|
+
else {
|
|
3676
|
+
return get(this._config, name);
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
saveConfig(config) {
|
|
3680
|
+
if (!isInputConfigValid(config)) {
|
|
3681
|
+
this.log.warn('the format of config is invalid, please provide object');
|
|
3682
|
+
return;
|
|
3683
|
+
}
|
|
3684
|
+
this.setConfig(config);
|
|
3685
|
+
this.db.saveConfig(config);
|
|
3686
|
+
}
|
|
3687
|
+
removeConfig(key, propName) {
|
|
3688
|
+
if (!key || !propName)
|
|
3689
|
+
return;
|
|
3690
|
+
if (isConfigKeyInBlackList(key)) {
|
|
3691
|
+
this.log.warn(`the config.${key} can't be removed`);
|
|
3692
|
+
return;
|
|
3693
|
+
}
|
|
3694
|
+
this.unsetConfig(key, propName);
|
|
3695
|
+
this.db.unset(key, propName);
|
|
3696
|
+
}
|
|
3697
|
+
setConfig(config) {
|
|
3698
|
+
if (!isInputConfigValid(config)) {
|
|
3699
|
+
this.log.warn('the format of config is invalid, please provide object');
|
|
3700
|
+
return;
|
|
3701
|
+
}
|
|
3702
|
+
Object.keys(config).forEach((name) => {
|
|
3703
|
+
if (isConfigKeyInBlackList(name)) {
|
|
3704
|
+
this.log.warn(`the config.${name} can't be modified`);
|
|
3705
|
+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
3706
|
+
delete config[name];
|
|
3707
|
+
}
|
|
3708
|
+
set(this._config, name, config[name]);
|
|
3709
|
+
eventBus.emit(IBusEvent.CONFIG_CHANGE, {
|
|
3710
|
+
configName: name,
|
|
3711
|
+
value: config[name]
|
|
3712
|
+
});
|
|
3713
|
+
});
|
|
3714
|
+
}
|
|
3715
|
+
unsetConfig(key, propName) {
|
|
3716
|
+
if (!key || !propName)
|
|
3717
|
+
return;
|
|
3718
|
+
if (isConfigKeyInBlackList(key)) {
|
|
3719
|
+
this.log.warn(`the config.${key} can't be unset`);
|
|
3720
|
+
return;
|
|
3721
|
+
}
|
|
3722
|
+
unset(this.getConfig(key), propName);
|
|
3723
|
+
}
|
|
3724
|
+
get request() {
|
|
3725
|
+
return this.Request.request.bind(this.Request);
|
|
3726
|
+
}
|
|
3727
|
+
async upload(input) {
|
|
3728
|
+
if (this.configPath === '') {
|
|
3729
|
+
this.log.error('The configuration file only supports JSON format.');
|
|
3730
|
+
return [];
|
|
3731
|
+
}
|
|
3732
|
+
// upload from clipboard
|
|
3733
|
+
if (input === undefined || input.length === 0) {
|
|
3734
|
+
try {
|
|
3735
|
+
const { imgPath, shouldKeepAfterUploading } = await getClipboardImage(this);
|
|
3736
|
+
if (imgPath === 'no image') {
|
|
3737
|
+
throw new Error('image not found in clipboard');
|
|
3738
|
+
}
|
|
3739
|
+
else {
|
|
3740
|
+
this.once(IBuildInEvent.FAILED, () => {
|
|
3741
|
+
if (!shouldKeepAfterUploading) {
|
|
3742
|
+
// 删除 picgo 生成的图片文件,例如 `~/.picgo/20200621205720.png`
|
|
3743
|
+
fs.remove(imgPath).catch((e) => { this.log.error(e); });
|
|
3744
|
+
}
|
|
3745
|
+
});
|
|
3746
|
+
this.once('finished', () => {
|
|
3747
|
+
if (!shouldKeepAfterUploading) {
|
|
3748
|
+
fs.remove(imgPath).catch((e) => { this.log.error(e); });
|
|
3749
|
+
}
|
|
3750
|
+
});
|
|
3751
|
+
const { output } = await this.lifecycle.start([imgPath]);
|
|
3752
|
+
return output;
|
|
3753
|
+
}
|
|
3754
|
+
}
|
|
3755
|
+
catch (e) {
|
|
3756
|
+
this.emit(IBuildInEvent.FAILED, e);
|
|
3757
|
+
throw e;
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
else {
|
|
3761
|
+
// upload from path
|
|
3762
|
+
const { output } = await this.lifecycle.start(input);
|
|
3763
|
+
return output;
|
|
3764
|
+
}
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
|
|
3768
|
+
export { Commander, Lifecycle, LifecyclePlugins, Logger, PicGo, PluginHandler, PluginLoader, Request };
|
|
3769
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZXNtLmpzIiwic291cmNlcyI6WyIuLi9zcmMvcGx1Z2lucy9jb21tYW5kZXIvcGx1Z2luSGFuZGxlci50cyIsIi4uL3NyYy9wbHVnaW5zL2NvbW1hbmRlci9jb25maWcudHMiLCIuLi9zcmMvdXRpbHMvY29tbW9uLnRzIiwiLi4vc3JjL3BsdWdpbnMvY29tbWFuZGVyL3VwbG9hZC50cyIsIi4uL3NyYy9wbHVnaW5zL2NvbW1hbmRlci9zZXR0aW5nLnRzIiwiLi4vc3JjL3BsdWdpbnMvY29tbWFuZGVyL3VzZS50cyIsIi4uL3NyYy9wbHVnaW5zL2NvbW1hbmRlci9wcm94eS50cyIsIi4uL3NyYy91dGlscy9pbml0VXRpbHMudHMiLCIuLi9zcmMvcGx1Z2lucy9jb21tYW5kZXIvaW5pdC50cyIsIi4uL3NyYy9wbHVnaW5zL2NvbW1hbmRlci9pMThuLnRzIiwiLi4vc3JjL3BsdWdpbnMvY29tbWFuZGVyL2luZGV4LnRzIiwiLi4vc3JjL2xpYi9MaWZlY3ljbGVQbHVnaW5zLnRzIiwiLi4vc3JjL2xpYi9Db21tYW5kZXIudHMiLCIuLi9zcmMvdXRpbHMvZW51bS50cyIsIi4uL3NyYy9saWIvTG9nZ2VyLnRzIiwiLi4vc3JjL3V0aWxzL2NyZWF0ZUNvbnRleHQudHMiLCIuLi9zcmMvY29yZS9MaWZlY3ljbGUudHMiLCIuLi9zcmMvcGx1Z2lucy91cGxvYWRlci9zbW1zLnRzIiwiLi4vc3JjL3BsdWdpbnMvdXBsb2FkZXIvdGN5dW4udHMiLCIuLi9zcmMvcGx1Z2lucy91cGxvYWRlci9naXRodWIudHMiLCIuLi9zcmMvcGx1Z2lucy91cGxvYWRlci9xaW5pdS50cyIsIi4uL3NyYy9wbHVnaW5zL3VwbG9hZGVyL2ltZ3VyLnRzIiwiLi4vc3JjL3BsdWdpbnMvdXBsb2FkZXIvYWxpeXVuLnRzIiwiLi4vc3JjL3BsdWdpbnMvdXBsb2FkZXIvdXB5dW4udHMiLCIuLi9zcmMvcGx1Z2lucy91cGxvYWRlci9pbmRleC50cyIsIi4uL3NyYy9wbHVnaW5zL3RyYW5zZm9ybWVyL3BhdGgudHMiLCIuLi9zcmMvcGx1Z2lucy90cmFuc2Zvcm1lci9iYXNlNjQudHMiLCIuLi9zcmMvcGx1Z2lucy90cmFuc2Zvcm1lci9pbmRleC50cyIsIi4uL3NyYy9saWIvUGx1Z2luTG9hZGVyLnRzIiwiLi4vc3JjL3V0aWxzL3N0YXRpYy50cyIsIi4uL3NyYy91dGlscy9nZXRDbGlwYm9hcmRJbWFnZS50cyIsIi4uL3NyYy91dGlscy9ldmVudEJ1cy50cyIsIi4uL3NyYy9saWIvUmVxdWVzdC50cyIsIi4uL3NyYy91dGlscy9kYi50cyIsIi4uL3NyYy9saWIvUGx1Z2luSGFuZGxlci50cyIsIi4uL3NyYy9pMThuL3poLUNOLnRzIiwiLi4vc3JjL2kxOG4vZW4udHMiLCIuLi9zcmMvaTE4bi96aC1UVy50cyIsIi4uL3NyYy9pMThuL2luZGV4LnRzIiwiLi4vc3JjL2NvcmUvUGljR28udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSVBpY0dvLCBJUGx1Z2luIH0gZnJvbSAnLi4vLi4vdHlwZXMnXHJcblxyXG5jb25zdCBwbHVnaW5IYW5kbGVyOiBJUGx1Z2luID0ge1xyXG4gIGhhbmRsZTogKGN0eDogSVBpY0dvKSA9PiB7XHJcbiAgICAvLyBjb25zdCBwbHVnaW5IYW5kbGVyID0gbmV3IFBsdWdpbkhhbmRsZXIoY3R4KVxyXG4gICAgY29uc3QgY21kID0gY3R4LmNtZFxyXG4gICAgY21kLnByb2dyYW1cclxuICAgICAgLmNvbW1hbmQoJ2luc3RhbGwgPHBsdWdpbnMuLi4+JylcclxuICAgICAgLmRlc2NyaXB0aW9uKCdpbnN0YWxsIHBpY2dvIHBsdWdpbicpXHJcbiAgICAgIC5hbGlhcygnYWRkJylcclxuICAgICAgLm9wdGlvbignLXAsIC0tcHJveHkgPHByb3h5PicsICdBZGQgcHJveHkgZm9yIGluc3RhbGxpbmcnKVxyXG4gICAgICAub3B0aW9uKCctciwgLS1yZWdpc3RyeSA8cmVnaXN0cnk+JywgJ0Nob29zZSBhIHJlZ2lzdHJ5IGZvciBpbnN0YWxsaW5nJylcclxuICAgICAgLmFjdGlvbigocGx1Z2luczogc3RyaW5nW10sIHByb2dyYW06IGFueSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHsgcHJveHksIHJlZ2lzdHJ5IH0gPSBwcm9ncmFtXHJcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcclxuICAgICAgICAgIHByb3h5LFxyXG4gICAgICAgICAgcmVnaXN0cnlcclxuICAgICAgICB9XHJcbiAgICAgICAgY3R4LnBsdWdpbkhhbmRsZXIuaW5zdGFsbChwbHVnaW5zLCBvcHRpb25zKS5jYXRjaCgoZSkgPT4geyBjdHgubG9nLmVycm9yKGUpIH0pXHJcbiAgICAgIH0pXHJcbiAgICBjbWQucHJvZ3JhbVxyXG4gICAgICAuY29tbWFuZCgndW5pbnN0YWxsIDxwbHVnaW5zLi4uPicpXHJcbiAgICAgIC5hbGlhcygncm0nKVxyXG4gICAgICAuZGVzY3JpcHRpb24oJ3VuaW5zdGFsbCBwaWNnbyBwbHVnaW4nKVxyXG4gICAgICAuYWN0aW9uKChwbHVnaW5zOiBzdHJpbmdbXSkgPT4ge1xyXG4gICAgICAgIGN0eC5wbHVnaW5IYW5kbGVyLnVuaW5zdGFsbChwbHVnaW5zKS5jYXRjaCgoZSkgPT4geyBjdHgubG9nLmVycm9yKGUpIH0pXHJcbiAgICAgIH0pXHJcbiAgICBjbWQucHJvZ3JhbVxyXG4gICAgICAuY29tbWFuZCgndXBkYXRlIDxwbHVnaW5zLi4uPicpXHJcbiAgICAgIC5kZXNjcmlwdGlvbigndXBkYXRlIHBpY2dvIHBsdWdpbicpXHJcbiAgICAgIC5vcHRpb24oJy1wLCAtLXByb3h5IDxwcm94eT4nLCAnQWRkIHByb3h5IGZvciBpbnN0YWxsaW5nJylcclxuICAgICAgLm9wdGlvbignLXIsIC0tcmVnaXN0cnkgPHJlZ2lzdHJ5PicsICdDaG9vc2UgYSByZWdpc3RyeSBmb3IgaW5zdGFsbGluZycpXHJcbiAgICAgIC5hY3Rpb24oKHBsdWdpbnM6IHN0cmluZ1tdLCBwcm9ncmFtOiBhbnkpID0+IHtcclxuICAgICAgICBjb25zdCB7IHByb3h5LCByZWdpc3RyeSB9ID0gcHJvZ3JhbVxyXG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XHJcbiAgICAgICAgICBwcm94eSxcclxuICAgICAgICAgIHJlZ2lzdHJ5XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGN0eC5wbHVnaW5IYW5kbGVyLnVwZGF0ZShwbHVnaW5zLCBvcHRpb25zKS5jYXRjaCgoZTogRXJyb3IpID0+IHsgY3R4LmxvZy5lcnJvcihlKSB9KVxyXG4gICAgICB9KVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgcGx1Z2luSGFuZGxlclxyXG4iLCJpbXBvcnQgeyBJUGljR28sIElQbHVnaW4gfSBmcm9tICcuLi8uLi90eXBlcydcclxuXHJcbmNvbnN0IGNvbmZpZzogSVBsdWdpbiA9IHtcclxuICBoYW5kbGU6IChjdHg6IElQaWNHbykgPT4ge1xyXG4gICAgY29uc3QgY21kID0gY3R4LmNtZFxyXG4gICAgY21kLnByb2dyYW1cclxuICAgICAgLm9wdGlvbignLWMsIC0tY29uZmlnIDxwYXRoPicsICdzZXQgY29uZmlnIHBhdGgnKVxyXG4gICAgICAvLyB3aWxsIGhhbmRsZSBpbiBgYmluL3BpY2dvYFxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgY29uZmlnXHJcbiIsImltcG9ydCBmcyBmcm9tICdmcy1leHRyYSdcclxuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcclxuaW1wb3J0IHsgaW1hZ2VTaXplIH0gZnJvbSAnaW1hZ2Utc2l6ZSdcclxuaW1wb3J0IHtcclxuICBJSW1nU2l6ZSxcclxuICBJUGF0aFRyYW5zZm9ybWVkSW1nSW5mbyxcclxuICBJUGx1Z2luTmFtZVR5cGUsXHJcbiAgSUxvZ2dlcixcclxuICBJUGljR29cclxufSBmcm9tICcuLi90eXBlcydcclxuaW1wb3J0IHsgVVJMIH0gZnJvbSAndXJsJ1xyXG5cclxuZXhwb3J0IGNvbnN0IGlzVXJsID0gKHVybDogc3RyaW5nKTogYm9vbGVhbiA9PiAodXJsLnN0YXJ0c1dpdGgoJ2h0dHA6Ly8nKSB8fCB1cmwuc3RhcnRzV2l0aCgnaHR0cHM6Ly8nKSlcclxuZXhwb3J0IGNvbnN0IGlzVXJsRW5jb2RlID0gKHVybDogc3RyaW5nKTogYm9vbGVhbiA9PiB7XHJcbiAgdXJsID0gdXJsIHx8ICcnXHJcbiAgdHJ5IHtcclxuICAgIC8vIHRoZSB3aG9sZSB1cmwgZW5jb2RlIG9yIGRlY29kZSBzaG9sZCBub3QgdXNlIGVuY29kZVVSSUNvbXBvbmVudCBvciBkZWNvZGVVUklDb21wb25lbnRcclxuICAgIHJldHVybiB1cmwgIT09IGRlY29kZVVSSSh1cmwpXHJcbiAgfSBjYXRjaCAoZSkge1xyXG4gICAgLy8gaWYgc29tZSBlcnJvciBjYXVnaHQsIHRyeSB0byBsZXQgaXQgZ29cclxuICAgIHJldHVybiB0cnVlXHJcbiAgfVxyXG59XHJcbmV4cG9ydCBjb25zdCBoYW5kbGVVcmxFbmNvZGUgPSAodXJsOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xyXG4gIGlmICghaXNVcmxFbmNvZGUodXJsKSkge1xyXG4gICAgdXJsID0gZW5jb2RlVVJJKHVybClcclxuICB9XHJcbiAgcmV0dXJuIHVybFxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgZ2V0SW1hZ2VTaXplID0gKGZpbGU6IEJ1ZmZlcik6IElJbWdTaXplID0+IHtcclxuICB0cnkge1xyXG4gICAgY29uc3QgeyB3aWR0aCA9IDAsIGhlaWdodCA9IDAgfSA9IGltYWdlU2l6ZShmaWxlKVxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgcmVhbDogdHJ1ZSxcclxuICAgICAgd2lkdGgsXHJcbiAgICAgIGhlaWdodFxyXG4gICAgfVxyXG4gIH0gY2F0Y2ggKGUpIHtcclxuICAgIC8vIGZhbGxiYWNrIHRvIDIwMCAqIDIwMFxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgcmVhbDogZmFsc2UsXHJcbiAgICAgIHdpZHRoOiAyMDAsXHJcbiAgICAgIGhlaWdodDogMjAwXHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgZ2V0RlNGaWxlID0gYXN5bmMgKGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPElQYXRoVHJhbnNmb3JtZWRJbWdJbmZvPiA9PiB7XHJcbiAgdHJ5IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGV4dG5hbWU6IHBhdGguZXh0bmFtZShmaWxlUGF0aCksXHJcbiAgICAgIGZpbGVOYW1lOiBwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKSxcclxuICAgICAgYnVmZmVyOiBhd2FpdCBmcy5yZWFkRmlsZShmaWxlUGF0aCksXHJcbiAgICAgIHN1Y2Nlc3M6IHRydWVcclxuICAgIH1cclxuICB9IGNhdGNoIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIHJlYXNvbjogYHJlYWQgZmlsZSAke2ZpbGVQYXRofSBlcnJvcmAsXHJcbiAgICAgIHN1Y2Nlc3M6IGZhbHNlXHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgZ2V0VVJMRmlsZSA9IGFzeW5jICh1cmw6IHN0cmluZywgY3R4OiBJUGljR28pOiBQcm9taXNlPElQYXRoVHJhbnNmb3JtZWRJbWdJbmZvPiA9PiB7XHJcbiAgdXJsID0gaGFuZGxlVXJsRW5jb2RlKHVybClcclxuICBsZXQgaXNJbWFnZSA9IGZhbHNlXHJcbiAgbGV0IGV4dG5hbWUgPSAnJ1xyXG4gIGxldCB0aW1lb3V0SWQ6IE5vZGVKUy5UaW1lb3V0XHJcbiAgY29uc3QgcmVxdWVzdEZuID0gbmV3IFByb21pc2U8SVBhdGhUcmFuc2Zvcm1lZEltZ0luZm8+KChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgIChhc3luYyAoKSA9PiB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgY3R4LnJlcXVlc3Qoe1xyXG4gICAgICAgICAgbWV0aG9kOiAnZ2V0JyxcclxuICAgICAgICAgIHVybCxcclxuICAgICAgICAgIHJlc29sdmVXaXRoRnVsbFJlc3BvbnNlOiB0cnVlLFxyXG4gICAgICAgICAgcmVzcG9uc2VUeXBlOiAnYXJyYXlidWZmZXInXHJcbiAgICAgICAgfSlcclxuICAgICAgICAgIC50aGVuKChyZXNwKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVzcC5oZWFkZXJzWydjb250ZW50LXR5cGUnXVxyXG4gICAgICAgICAgICBpZiAoY29udGVudFR5cGU/LmluY2x1ZGVzKCdpbWFnZScpKSB7XHJcbiAgICAgICAgICAgICAgaXNJbWFnZSA9IHRydWVcclxuICAgICAgICAgICAgICBleHRuYW1lID0gYC4ke2NvbnRlbnRUeXBlLnNwbGl0KCdpbWFnZS8nKVsxXX1gXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJlc3AuZGF0YSBhcyBCdWZmZXJcclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZClcclxuICAgICAgICBpZiAoaXNJbWFnZSkge1xyXG4gICAgICAgICAgY29uc3QgdXJsUGF0aCA9IG5ldyBVUkwodXJsKS5wYXRobmFtZVxyXG4gICAgICAgICAgcmVzb2x2ZSh7XHJcbiAgICAgICAgICAgIGJ1ZmZlcjogcmVzLFxyXG4gICAgICAgICAgICBmaWxlTmFtZTogcGF0aC5iYXNlbmFtZSh1cmxQYXRoKSxcclxuICAgICAgICAgICAgZXh0bmFtZSxcclxuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZVxyXG4gICAgICAgICAgfSlcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgcmVzb2x2ZSh7XHJcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxyXG4gICAgICAgICAgICByZWFzb246IGAke3VybH0gaXMgbm90IGltYWdlYFxyXG4gICAgICAgICAgfSlcclxuICAgICAgICB9XHJcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcclxuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKVxyXG4gICAgICAgIHJlc29sdmUoe1xyXG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXHJcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3Jlc3RyaWN0LXRlbXBsYXRlLWV4cHJlc3Npb25zXHJcbiAgICAgICAgICByZWFzb246IGByZXF1ZXN0ICR7dXJsfSBlcnJvciwgJHtlcnJvcj8ubWVzc2FnZSA/PyAnJ31gXHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gICAgfSkoKS5jYXRjaChyZWplY3QpXHJcbiAgfSlcclxuICBjb25zdCB0aW1lb3V0UHJvbWlzZSA9IG5ldyBQcm9taXNlPElQYXRoVHJhbnNmb3JtZWRJbWdJbmZvPigocmVzb2x2ZSk6IHZvaWQgPT4ge1xyXG4gICAgdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIHJlc29sdmUoe1xyXG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxyXG4gICAgICAgIHJlYXNvbjogYHJlcXVlc3QgJHt1cmx9IHRpbWVvdXRgXHJcbiAgICAgIH0pXHJcbiAgICB9LCAxMDAwMClcclxuICB9KVxyXG4gIHJldHVybiBQcm9taXNlLnJhY2UoW3JlcXVlc3RGbiwgdGltZW91dFByb21pc2VdKVxyXG59XHJcblxyXG4vKipcclxuICogZGV0ZWN0IHRoZSBpbnB1dCBzdHJpbmcncyB0eXBlXHJcbiAqIGZvciBleGFtcGxlXHJcbiAqIDEuIEB4eHgvcGljZ28tcGx1Z2luLXh4eCAtPiBzY29wZVxyXG4gKiAyLiBwaWNnby1wbHVnaW4teHh4IC0+IG5vcm1hbFxyXG4gKiAzLiB4eHggLT4gc2ltcGxlXHJcbiAqIDQuIG5vdCBleGlzdHMgb3IgaXMgYSBwYXRoIC0+IHVua25vd25cclxuICogQHBhcmFtIG5hbWVcclxuICovXHJcbmV4cG9ydCBjb25zdCBnZXRQbHVnaW5OYW1lVHlwZSA9IChuYW1lOiBzdHJpbmcpOiBJUGx1Z2luTmFtZVR5cGUgPT4ge1xyXG4gIGlmICgvXkBbXi9dK1xcL3BpY2dvLXBsdWdpbi0vLnRlc3QobmFtZSkpIHtcclxuICAgIHJldHVybiAnc2NvcGUnXHJcbiAgfSBlbHNlIGlmIChuYW1lLnN0YXJ0c1dpdGgoJ3BpY2dvLXBsdWdpbi0nKSkge1xyXG4gICAgcmV0dXJuICdub3JtYWwnXHJcbiAgfSBlbHNlIGlmIChpc1NpbXBsZU5hbWUobmFtZSkpIHtcclxuICAgIHJldHVybiAnc2ltcGxlJ1xyXG4gIH1cclxuICByZXR1cm4gJ3Vua25vd24nXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBkZXRlY3QgdGhlIGlucHV0IHN0cmluZyBpcyBhIHNpbXBsZSBwbHVnaW4gbmFtZSBvciBub3RcclxuICogZm9yIGV4YW1wbGVcclxuICogMS4geHh4IC0+IHRydWVcclxuICogMi4gL1Vzci94eC94eHh4L3BpY2dvLXBsdWdpbi14eHggLT4gZmFsc2VcclxuICogQHBhcmFtIG5hbWUgcGx1Z2luTmFtZU9yUGF0aFxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGlzU2ltcGxlTmFtZSA9IChuYW1lT3JQYXRoOiBzdHJpbmcpOiBib29sZWFuID0+IHtcclxuICBpZiAocGF0aC5pc0Fic29sdXRlKG5hbWVPclBhdGgpKSB7XHJcbiAgICByZXR1cm4gZmFsc2VcclxuICB9XHJcbiAgY29uc3QgcGx1Z2luUGF0aCA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBuYW1lT3JQYXRoKVxyXG4gIGlmIChmcy5leGlzdHNTeW5jKHBsdWdpblBhdGgpKSB7XHJcbiAgICByZXR1cm4gZmFsc2VcclxuICB9XHJcbiAgaWYgKG5hbWVPclBhdGguaW5jbHVkZXMoJy8nKSB8fCBuYW1lT3JQYXRoLmluY2x1ZGVzKCdcXFxcJykpIHtcclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxuICByZXR1cm4gdHJ1ZVxyXG59XHJcblxyXG4vKipcclxuICogc3RyZWFtbGluZSB0aGUgZnVsbCBwbHVnaW4gbmFtZSB0byBhIHNpbXBsZSBvbmVcclxuICogZm9yIGV4YW1wbGU6XHJcbiAqIDEuIHBpY2dvLXBsdWdpbi14eHggLT4geHh4XHJcbiAqIDIuIEB4eHgvcGljZ28tcGx1Z2luLXl5eSAtPiB5eXlcclxuICogQHBhcmFtIG5hbWUgcGx1Z2luRnVsbE5hbWVcclxuICovXHJcbmV4cG9ydCBjb25zdCBoYW5kbGVTdHJlYW1saW5lUGx1Z2luTmFtZSA9IChuYW1lOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xyXG4gIGlmICgvXkBbXi9dK1xcL3BpY2dvLXBsdWdpbi0vLnRlc3QobmFtZSkpIHtcclxuICAgIHJldHVybiBuYW1lLnJlcGxhY2UoL15AW14vXStcXC9waWNnby1wbHVnaW4tLywgJycpXHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBuYW1lLnJlcGxhY2UoL3BpY2dvLXBsdWdpbi0vLCAnJylcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBjb21wbGV0ZSBwbHVnaW4gbmFtZSB0byBmdWxsIG5hbWVcclxuICogZm9yIGV4YW1wbGU6XHJcbiAqIDEuIHh4eCAtPiBwaWNnby1wbHVnaW4teHh4XHJcbiAqIDIuIHBpY2dvLXBsdWdpbi14eHggLT4gcGljZ28tcGx1Z2luLXh4eFxyXG4gKiBAcGFyYW0gbmFtZSBwbHVnaW5TaW1wbGVOYW1lXHJcbiAqIEBwYXJhbSBzY29wZSBwbHVnaW5TY29wZVxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGhhbmRsZUNvbXBsZXRlUGx1Z2luTmFtZSA9IChuYW1lOiBzdHJpbmcsIHNjb3BlID0gJycpOiBzdHJpbmcgPT4ge1xyXG4gIGlmIChzY29wZSkge1xyXG4gICAgcmV0dXJuIGBAJHtzY29wZX0vcGljZ28tcGx1Z2luLSR7bmFtZX1gXHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBgcGljZ28tcGx1Z2luLSR7bmFtZX1gXHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogaGFuZGxlIGluc3RhbGwvdW5pbnN0YWxsL3VwZGF0ZSBwbHVnaW4gbmFtZSBvciBwYXRoXHJcbiAqIGZvciBleGFtcGxlXHJcbiAqIDEuIHBpY2dvLXBsdWdpbi14eHggLT4gcGljZ28tcGx1Z2luLXh4eFxyXG4gKiAyLiBAeHh4L3BpY2dvLXBsdWdpbi14eHggLT4gQHh4eC9waWNnby1wbHVnaW4teHh4XHJcbiAqIDMuIHh4eCAtPiBwaWNnby1wbHVnaW4teHh4XHJcbiAqIDQuIC4veHh4eC9waWNnby1wbHVnaW4teHh4IC0+IC9hYnNvbHV0ZVBhdGgvLi4uL3h4eHgvcGljZ28tcGx1Z2luLXh4eFxyXG4gKiA1LiAvYWJzb2x1dGVQYXRoLy4uLi9waWNnby1wbHVnaW4teHh4IC0+IC9hYnNvbHV0ZVBhdGgvLi4uL3BpY2dvLXBsdWdpbi14eHhcclxuICogQHBhcmFtIG5hbWVPclBhdGggcGx1Z2luTmFtZSBvciBwbHVnaW5QYXRoXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgZ2V0UHJvY2Vzc1BsdWdpbk5hbWUgPSAobmFtZU9yUGF0aDogc3RyaW5nLCBsb2dnZXI6IElMb2dnZXIgfCBDb25zb2xlID0gY29uc29sZSk6IHN0cmluZyA9PiB7XHJcbiAgY29uc3QgcGx1Z2luTmFtZVR5cGUgPSBnZXRQbHVnaW5OYW1lVHlwZShuYW1lT3JQYXRoKVxyXG4gIHN3aXRjaCAocGx1Z2luTmFtZVR5cGUpIHtcclxuICAgIGNhc2UgJ25vcm1hbCc6XHJcbiAgICBjYXNlICdzY29wZSc6XHJcbiAgICAgIHJldHVybiBuYW1lT3JQYXRoXHJcbiAgICBjYXNlICdzaW1wbGUnOlxyXG4gICAgICByZXR1cm4gaGFuZGxlQ29tcGxldGVQbHVnaW5OYW1lKG5hbWVPclBhdGgpXHJcbiAgICBkZWZhdWx0OiB7XHJcbiAgICAgIC8vIG5vdywgdGhlIHBsdWdpbk5hbWVUeXBlIGlzIHVua25vdyBoZXJlXHJcbiAgICAgIC8vIDEuIGNoZWNrIGlmIGlzIGFuIGFic29sdXRlIHBhdGhcclxuICAgICAgbGV0IHBsdWdpblBhdGggPSBuYW1lT3JQYXRoXHJcbiAgICAgIGlmIChwYXRoLmlzQWJzb2x1dGUobmFtZU9yUGF0aCkgJiYgZnMuZXhpc3RzU3luYyhuYW1lT3JQYXRoKSkge1xyXG4gICAgICAgIHJldHVybiBoYW5kbGVVbml4U3R5bGVQYXRoKHBsdWdpblBhdGgpXHJcbiAgICAgIH1cclxuICAgICAgLy8gMi4gY2hlY2sgaWYgaXMgYSByZWxhdGl2ZSBwYXRoXHJcbiAgICAgIHBsdWdpblBhdGggPSBwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgbmFtZU9yUGF0aClcclxuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMocGx1Z2luUGF0aCkpIHtcclxuICAgICAgICByZXR1cm4gaGFuZGxlVW5peFN0eWxlUGF0aChwbHVnaW5QYXRoKVxyXG4gICAgICB9XHJcbiAgICAgIC8vIDMuIGludmFsaWQgbmFtZU9yUGF0aFxyXG4gICAgICBsb2dnZXIud2FybihgQ2FuJ3QgZmluZCBwbHVnaW4gJHtuYW1lT3JQYXRofWApXHJcbiAgICAgIHJldHVybiAnJ1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIGdldCB0aGUgbm9ybWFsIHBsdWdpbiBuYW1lXHJcbiAqIGZvciBleGFtcGxlOlxyXG4gKiAxLiBwaWNnby1wbHVnaW4teHh4IC0+IHBpY2dvLXBsdWdpbi14eHhcclxuICogMi4gQHh4eC9waWNnby1wbHVnaW4teHh4IC0+IEB4eHgvcGljZ28tcGx1Z2luLXh4eFxyXG4gKiAzLiAuL3h4eHgvcGljZ28tcGx1Z2luLXh4eCAtPiBwaWNnby1wbHVnaW4teHh4XHJcbiAqIDQuIC9hYnNvbHV0ZVBhdGgvLi4uL3BpY2dvLXBsdWdpbi14eHggLT4gcGljZ28tcGx1Z2luLXh4eFxyXG4gKiA1LiBhbiBleGNlcHRpb246IFtwYWNrYWdlLmpzb24ncyBuYW1lXSAhPT0gW2ZvbGRlciBuYW1lXVxyXG4gKiB0aGVuIHVzZSBbcGFja2FnZS5qc29uJ3MgbmFtZV0sIHVzdWFsbHkgbWF0Y2ggdGhlIHNjb3BlIHBhY2thZ2UuXHJcbiAqIDYuIGlmIHBsdWdpbiBuYW1lIGhhcyB2ZXJzaW9uOiBwaWNnby1wbHVnaW4teHh4QHgueC54IHRoZW4gcmVtb3ZlIHRoZSB2ZXJzaW9uXHJcbiAqIEBwYXJhbSBuYW1lT3JQYXRoXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgZ2V0Tm9ybWFsUGx1Z2luTmFtZSA9IChuYW1lT3JQYXRoOiBzdHJpbmcsIGxvZ2dlcjogSUxvZ2dlciB8IENvbnNvbGUgPSBjb25zb2xlKTogc3RyaW5nID0+IHtcclxuICBjb25zdCBwbHVnaW5OYW1lVHlwZSA9IGdldFBsdWdpbk5hbWVUeXBlKG5hbWVPclBhdGgpXHJcbiAgc3dpdGNoIChwbHVnaW5OYW1lVHlwZSkge1xyXG4gICAgY2FzZSAnbm9ybWFsJzpcclxuICAgICAgcmV0dXJuIHJlbW92ZVBsdWdpblZlcnNpb24obmFtZU9yUGF0aClcclxuICAgIGNhc2UgJ3Njb3BlJzpcclxuICAgICAgcmV0dXJuIHJlbW92ZVBsdWdpblZlcnNpb24obmFtZU9yUGF0aCwgdHJ1ZSlcclxuICAgIGNhc2UgJ3NpbXBsZSc6XHJcbiAgICAgIHJldHVybiByZW1vdmVQbHVnaW5WZXJzaW9uKGhhbmRsZUNvbXBsZXRlUGx1Z2luTmFtZShuYW1lT3JQYXRoKSlcclxuICAgIGRlZmF1bHQ6IHtcclxuICAgICAgLy8gbm93LCB0aGUgbmFtZU9yUGF0aCBtdXN0IGJlIHBhdGhcclxuICAgICAgLy8gdGhlIG5hbWVPclBhdGggaGVyZSB3aWxsIGJlIGVuc3VyZWQgd2l0aCB1bml4IHN0eWxlXHJcbiAgICAgIC8vIHdlIG5lZWQgdG8gZmluZCB0aGUgcGFja2FnZS5qc29uJ3MgbmFtZSBjYXVzZSBucG0gdXNpbmcgdGhlIG5hbWUgaW4gcGFja2FnZS5qc29uJ3MgbmFtZSBmaWxlZFxyXG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMobmFtZU9yUGF0aCkpIHtcclxuICAgICAgICBsb2dnZXIud2FybihgQ2FuJ3QgZmluZCBwbHVnaW46ICR7bmFtZU9yUGF0aH1gKVxyXG4gICAgICAgIHJldHVybiAnJ1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IHBhY2thZ2VKU09OUGF0aCA9IHBhdGgucG9zaXguam9pbihuYW1lT3JQYXRoLCAncGFja2FnZS5qc29uJylcclxuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHBhY2thZ2VKU09OUGF0aCkpIHtcclxuICAgICAgICBsb2dnZXIud2FybihgQ2FuJ3QgZmluZCBwbHVnaW46ICR7bmFtZU9yUGF0aH1gKVxyXG4gICAgICAgIHJldHVybiAnJ1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IHBrZyA9IGZzLnJlYWRKU09OU3luYyhwYWNrYWdlSlNPTlBhdGgpIHx8IHt9XHJcbiAgICAgICAgaWYgKCFwa2cubmFtZT8uaW5jbHVkZXMoJ3BpY2dvLXBsdWdpbi0nKSkge1xyXG4gICAgICAgICAgbG9nZ2VyLndhcm4oYFRoZSBwbHVnaW4gcGFja2FnZS5qc29uJ3MgbmFtZSBmaWxlZCBpcyAke3BrZy5uYW1lIGFzIHN0cmluZyB8fCAnZW1wdHknfSwgbmVlZCB0byBpbmNsdWRlIHRoZSBwcmVmaXg6IHBpY2dvLXBsdWdpbi1gKVxyXG4gICAgICAgICAgcmV0dXJuICcnXHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwa2cubmFtZVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogaGFuZGxlIHRyYW5zZm9ybSB0aGUgcGF0aCB0byB1bml4IHN0eWxlXHJcbiAqIGZvciBleGFtcGxlXHJcbiAqIDEuIEM6XFxcXHh4eFxcXFx4eHggLT4gQzoveHh4L3h4eFxyXG4gKiAyLiAveHh4L3h4eCAtPiAveHh4L3h4eFxyXG4gKiBAcGFyYW0gcGF0aFxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGhhbmRsZVVuaXhTdHlsZVBhdGggPSAocGF0aFN0cjogc3RyaW5nKTogc3RyaW5nID0+IHtcclxuICBjb25zdCBwYXRoQXJyID0gcGF0aFN0ci5zcGxpdChwYXRoLnNlcClcclxuICByZXR1cm4gcGF0aEFyci5qb2luKCcvJylcclxufVxyXG5cclxuLyoqXHJcbiAqIHJlbW92ZSBwbHVnaW4gdmVyc2lvbiB3aGVuIHJlZ2lzdGVyIHBsdWdpbiBuYW1lXHJcbiAqIDEuIHBpY2dvLXBsdWdpbi14eHhAMS4wLjAgLT4gcGljZ28tcGx1Z2luLXh4eFxyXG4gKiAyLiBAeHh4L3BpY2dvLXBsdWdpbi14eHhAMS4wLjAgLT4gQHh4eC9waWNnby1wbHVnaW4teHh4XHJcbiAqIEBwYXJhbSBuYW1lT3JQYXRoXHJcbiAqIEBwYXJhbSBzY29wZVxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IHJlbW92ZVBsdWdpblZlcnNpb24gPSAobmFtZU9yUGF0aDogc3RyaW5nLCBzY29wZTogYm9vbGVhbiA9IGZhbHNlKTogc3RyaW5nID0+IHtcclxuICBpZiAoIW5hbWVPclBhdGguaW5jbHVkZXMoJ0AnKSkge1xyXG4gICAgcmV0dXJuIG5hbWVPclBhdGhcclxuICB9IGVsc2Uge1xyXG4gICAgbGV0IHJlZyA9IC8oLitcXC8pPyhwaWNnby1wbHVnaW4tXFx3KykoQC4rKSovXHJcbiAgICAvLyBpZiBpcyBhIHNjb3BlIHBrZ1xyXG4gICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgIHJlZyA9IC8oLitcXC8pPyheQFteL10rXFwvcGljZ28tcGx1Z2luLVxcdyspKEAuKykqL1xyXG4gICAgfVxyXG4gICAgY29uc3QgbWF0Y2hBcnIgPSBuYW1lT3JQYXRoLm1hdGNoKHJlZylcclxuICAgIGlmICghbWF0Y2hBcnIpIHtcclxuICAgICAgY29uc29sZS53YXJuKCdjYW4gbm90IHJlbW92ZSBwbHVnaW4gdmVyc2lvbicpXHJcbiAgICAgIHJldHVybiBuYW1lT3JQYXRoXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gbWF0Y2hBcnJbMl1cclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiB0aGUgY29uZmlnIGJsYWNrIGl0ZW0gbGlzdCB3aGljaCB3b24ndCBiZSBzZXR0ZWRcclxuICogb25seSBjYW4gYmUgZ290XHJcbiAqL1xyXG5leHBvcnQgY29uc3QgY29uZmlnQmxhY2tMaXN0ID0gW11cclxuXHJcbi8qKlxyXG4gKiBjaGVjayBzb21lIGNvbmZpZyBrZXkgaXMgaW4gYmxhY2tMaXN0XHJcbiAqIEBwYXJhbSBrZXlcclxuICovXHJcbmV4cG9ydCBjb25zdCBpc0NvbmZpZ0tleUluQmxhY2tMaXN0ID0gKGtleTogc3RyaW5nKTogYm9vbGVhbiA9PiB7XHJcbiAgcmV0dXJuIGNvbmZpZ0JsYWNrTGlzdC5zb21lKGJsYWNrSXRlbSA9PiBrZXkuc3RhcnRzV2l0aChibGFja0l0ZW0pKVxyXG59XHJcblxyXG4vKipcclxuICogY2hlY2sgdGhlIGlucHV0IGNvbmZpZyBpcyB2YWxpZFxyXG4gKiBjb25maWcgbXVzdCBiZSBvYmplY3Qgc3VjaCBhcyB7IHh4eDogJ3h4eCcgfVxyXG4gKiAmJiBjYW4ndCBiZSBhcnJheVxyXG4gKiBAcGFyYW0gY29uZmlnXHJcbiAqIEByZXR1cm5zXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgaXNJbnB1dENvbmZpZ1ZhbGlkID0gKGNvbmZpZzogYW55KTogYm9vbGVhbiA9PiB7XHJcbiAgaWYgKFxyXG4gICAgdHlwZW9mIGNvbmZpZyA9PT0gJ29iamVjdCcgJiZcclxuICAgICFBcnJheS5pc0FycmF5KGNvbmZpZykgJiZcclxuICAgIE9iamVjdC5rZXlzKGNvbmZpZykubGVuZ3RoID4gMFxyXG4gICkge1xyXG4gICAgcmV0dXJuIHRydWVcclxuICB9XHJcbiAgcmV0dXJuIGZhbHNlXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBzYWZlUGFyc2U8VD4gKHN0cjogc3RyaW5nKTogVCB8IHN0cmluZyB7XHJcbiAgdHJ5IHtcclxuICAgIHJldHVybiBKU09OLnBhcnNlKHN0cilcclxuICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgcmV0dXJuIHN0clxyXG4gIH1cclxufVxyXG5cclxuLy8gaG9sZC4uLlxyXG4vLyBleHBvcnQgY29uc3QgY29uZmlnV2hpdGVMaXN0OiBSZWdFeHBbXSA9IFtcclxuLy8gICAvXnBpY0JlZC8sXHJcbi8vICAgL15waWNnb1BsdWdpbnMvLFxyXG4vLyAgIC9eQFteL10rXFwvcGljZ28tcGx1Z2luLS8sXHJcbi8vICAgL2RlYnVnLyxcclxuLy8gICAvc2lsZW50LyxcclxuLy8gICAvY29uZmlnUGF0aC8sXHJcbi8vICAgL15zZXR0aW5ncy8sXHJcbi8vIF1cclxuXHJcbi8vIGV4cG9ydCBjb25zdCBpc0NvbmZpZ0tleUluV2hpdGVMaXN0ID0gKGtleTogc3RyaW5nKTogYm9vbGVhbiA9PiB7XHJcbi8vICAgcmV0dXJuIGNvbmZpZ1doaXRlTGlzdC5zb21lKHdoaXRlSXRlbSA9PiB3aGl0ZUl0ZW0udGVzdChrZXkpKVxyXG4vLyB9XHJcblxyXG5leHBvcnQgY29uc3QgZm9yY2VOdW1iZXIgPSAobnVtOiBzdHJpbmcgfCBudW1iZXIgPSAwKTogbnVtYmVyID0+IHtcclxuICByZXR1cm4gaXNOYU4oTnVtYmVyKG51bSkpID8gMCA6IE51bWJlcihudW0pXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBpc0RldiA9ICgpOiBib29sZWFuID0+IHtcclxuICByZXR1cm4gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdkZXZlbG9wbWVudCdcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGlzUHJvZCA9ICgpOiBib29sZWFuID0+IHtcclxuICByZXR1cm4gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJ1xyXG59XHJcbiIsImltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXHJcbmltcG9ydCBmcyBmcm9tICdmcy1leHRyYSdcclxuaW1wb3J0IHsgaXNVcmwgfSBmcm9tICcuLi8uLi91dGlscy9jb21tb24nXHJcbmltcG9ydCB7IElQaWNHbywgSVBsdWdpbiB9IGZyb20gJy4uLy4uL3R5cGVzJ1xyXG5cclxuY29uc3QgdXBsb2FkOiBJUGx1Z2luID0ge1xyXG4gIGhhbmRsZTogKGN0eDogSVBpY0dvKSA9PiB7XHJcbiAgICBjb25zdCBjbWQgPSBjdHguY21kXHJcbiAgICBjbWQucHJvZ3JhbVxyXG4gICAgICAuY29tbWFuZCgndXBsb2FkJylcclxuICAgICAgLmRlc2NyaXB0aW9uKCd1cGxvYWQsIGdvIGdvIGdvJylcclxuICAgICAgLmFyZ3VtZW50cygnW2lucHV0Li4uXScpXHJcbiAgICAgIC5hbGlhcygndScpXHJcbiAgICAgIC5hY3Rpb24oKGlucHV0OiBzdHJpbmdbXSkgPT4ge1xyXG4gICAgICAgIChhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICBjb25zdCBpbnB1dExpc3QgPSBpbnB1dFxyXG4gICAgICAgICAgICAubWFwKChpdGVtOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgICAgICByZXR1cm4gaXNVcmwoaXRlbSkgPyBpdGVtIDogcGF0aC5yZXNvbHZlKGl0ZW0pXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5maWx0ZXIoKGl0ZW06IHN0cmluZykgPT4ge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGV4aXN0ID0gZnMuZXhpc3RzU3luYyhpdGVtKSB8fCBpc1VybChpdGVtKVxyXG4gICAgICAgICAgICAgIGlmICghZXhpc3QpIHtcclxuICAgICAgICAgICAgICAgIGN0eC5sb2cud2FybihgJHtpdGVtfSBkb2VzIG5vdCBleGlzdC5gKVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICByZXR1cm4gZXhpc3RcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgIGF3YWl0IGN0eC51cGxvYWQoaW5wdXRMaXN0KVxyXG4gICAgICAgIH0pKCkuY2F0Y2goKGUpID0+IHsgY3R4LmxvZy5lcnJvcihlKSB9KVxyXG4gICAgICB9KVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgdXBsb2FkXHJcbiIsImltcG9ydCB7IElQaWNHbywgSVBsdWdpbkNvbmZpZywgSVN0cmluZ0tleU1hcCB9IGZyb20gJy4uLy4uL3R5cGVzJ1xyXG5cclxuLy8gaGFuZGxlIG1vZHVsZXMgY29uZmlnIC0+IHNhdmUgdG8gcGljZ28gY29uZmlnIGZpbGVcclxuY29uc3QgaGFuZGxlQ29uZmlnID0gYXN5bmMgKGN0eDogSVBpY0dvLCBwcm9tcHRzOiBJUGx1Z2luQ29uZmlnW10sIG1vZHVsZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+ID0+IHtcclxuICBjb25zdCBhbnN3ZXIgPSBhd2FpdCBjdHguY21kLmlucXVpcmVyLnByb21wdChwcm9tcHRzKVxyXG4gIGNvbnN0IGNvbmZpZ05hbWUgPSBtb2R1bGUgPT09ICd1cGxvYWRlcidcclxuICAgID8gYHBpY0JlZC4ke25hbWV9YCA6IG1vZHVsZSA9PT0gJ3RyYW5zZm9ybWVyJ1xyXG4gICAgICA/IGB0cmFuc2Zvcm1lci4ke25hbWV9YCA6IG5hbWVcclxuICBjdHguc2F2ZUNvbmZpZyh7XHJcbiAgICBbY29uZmlnTmFtZV06IGFuc3dlclxyXG4gIH0pXHJcbn1cclxuXHJcbmNvbnN0IHNldHRpbmcgPSB7XHJcbiAgaGFuZGxlOiAoY3R4OiBJUGljR28pID0+IHtcclxuICAgIGNvbnN0IGNtZCA9IGN0eC5jbWRcclxuICAgIGNtZC5wcm9ncmFtXHJcbiAgICAgIC5jb21tYW5kKCdzZXQnKVxyXG4gICAgICAuYWxpYXMoJ2NvbmZpZycpXHJcbiAgICAgIC5hcmd1bWVudHMoJzxtb2R1bGU+IFtuYW1lXScpXHJcbiAgICAgIC5kZXNjcmlwdGlvbignY29uZmlndXJlIGNvbmZpZyBvZiBwaWNnbyBtb2R1bGVzJylcclxuICAgICAgLmFjdGlvbigobW9kdWxlOiBzdHJpbmcsIG5hbWU6IHN0cmluZykgPT4ge1xyXG4gICAgICAgIChhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAvLyAvLyBsb2FkIHRoaXJkLXBhcnR5IHBsdWdpbnNcclxuICAgICAgICAgICAgLy8gYXdhaXQgY3R4LnBsdWdpbkxvYWRlci5sb2FkKClcclxuICAgICAgICAgICAgLy8gaWYgYSBtb2R1bGUgaXMgc3BlY2lmaWMsIHRoZW4ganVzdCBzZXQgdGhpcyBvcHRpb24gaW4gY29uZmlnXHJcbiAgICAgICAgICAgIHN3aXRjaCAobW9kdWxlKSB7XHJcbiAgICAgICAgICAgICAgY2FzZSAndXBsb2FkZXInOlxyXG4gICAgICAgICAgICAgIGNhc2UgJ3RyYW5zZm9ybWVyJzpcclxuICAgICAgICAgICAgICAgIGlmIChuYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBjdHguaGVscGVyW21vZHVsZV0uZ2V0KG5hbWUpXHJcbiAgICAgICAgICAgICAgICAgIGlmICghaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjdHgubG9nLmVycm9yKGBObyAke21vZHVsZX0gbmFtZWQgJHtuYW1lfWApXHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0uY29uZmlnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgaGFuZGxlQ29uZmlnKGN0eCwgaXRlbS5jb25maWcoY3R4KSwgbW9kdWxlLCBuYW1lKVxyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICBjb25zdCBwcm9tcHRzID0gW1xyXG4gICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdsaXN0JyxcclxuICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IGAke21vZHVsZX1gLFxyXG4gICAgICAgICAgICAgICAgICAgICAgY2hvaWNlczogY3R4LmhlbHBlclttb2R1bGVdLmdldElkTGlzdCgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogYENob29zZSBhKG4pICR7bW9kdWxlfWBcclxuICAgICAgICAgICAgICAgICAgICAgIC8vIGRlZmF1bHQ6IGN0eC5nZXRDb25maWcoJ3BpY0JlZC51cGxvYWRlcicpIHx8IGN0eC5nZXRDb25maWcoJ3BpY0JlZC5jdXJyZW50JylcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIF1cclxuICAgICAgICAgICAgICAgICAgY29uc3QgYW5zd2VyID0gYXdhaXQgY3R4LmNtZC5pbnF1aXJlci5wcm9tcHQ8SVN0cmluZ0tleU1hcDxhbnk+Pihwcm9tcHRzKVxyXG4gICAgICAgICAgICAgICAgICBjb25zdCBpdGVtID0gY3R4LmhlbHBlclttb2R1bGVdLmdldChhbnN3ZXJbbW9kdWxlXSlcclxuICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0/LmNvbmZpZykge1xyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGhhbmRsZUNvbmZpZyhjdHgsIGl0ZW0uY29uZmlnKGN0eCksIG1vZHVsZSwgYW5zd2VyW21vZHVsZV0pXHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgICAgY2FzZSAncGx1Z2luJzpcclxuICAgICAgICAgICAgICAgIGlmIChuYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgIGlmICghbmFtZS5pbmNsdWRlcygncGljZ28tcGx1Z2luLScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGBwaWNnby1wbHVnaW4tJHtuYW1lfWBcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoY3R4LmdldENvbmZpZygncGljZ29QbHVnaW5zJykpLmluY2x1ZGVzKG5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eC5wbHVnaW5Mb2FkZXIuZ2V0UGx1Z2luKG5hbWUpPy5jb25maWcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IGhhbmRsZUNvbmZpZyhjdHgsIGN0eC5wbHVnaW5Mb2FkZXIuZ2V0UGx1Z2luKG5hbWUpIS5jb25maWchKGN0eCksICdwbHVnaW4nLCBuYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3R4LmxvZy5lcnJvcihgTm8gcGx1Z2luIG5hbWVkICR7bmFtZX1gKVxyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICBjb25zdCBwcm9tcHRzID0gW1xyXG4gICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdsaXN0JyxcclxuICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdwbHVnaW4nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgY2hvaWNlczogY3R4LnBsdWdpbkxvYWRlci5nZXRGdWxsTGlzdCgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ0Nob29zZSBhIHBsdWdpbidcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIF1cclxuICAgICAgICAgICAgICAgICAgY29uc3QgYW5zd2VyID0gYXdhaXQgY3R4LmNtZC5pbnF1aXJlci5wcm9tcHQ8YW55Pihwcm9tcHRzKVxyXG4gICAgICAgICAgICAgICAgICBpZiAoY3R4LnBsdWdpbkxvYWRlci5nZXRQbHVnaW4oYW5zd2VyLnBsdWdpbik/LmNvbmZpZykge1xyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGhhbmRsZUNvbmZpZyhjdHgsIGN0eC5wbHVnaW5Mb2FkZXIuZ2V0UGx1Z2luKGFuc3dlci5wbHVnaW4pIS5jb25maWchKGN0eCksICdwbHVnaW4nLCBhbnN3ZXIucGx1Z2luKVxyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVha1xyXG4gICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICBjdHgubG9nLndhcm4oYE5vIG1vZHVsZSBuYW1lZCAke21vZHVsZX1gKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5sb2cud2FybignQXZhaWxhYmxlIG1vZHVsZXMgYXJlIHVwbG9hZGVyfHRyYW5zZm9ybWVyfHBsdWdpbicpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgdXNlTW9kdWxlTmFtZSA9IG1vZHVsZSA9PT0gJ3BsdWdpbicgPyAncGx1Z2lucycgOiBtb2R1bGVcclxuICAgICAgICAgICAgY3R4LmxvZy5zdWNjZXNzKCdDb25maWd1cmUgY29uZmlnIHN1Y2Nlc3NmdWxseSEnKVxyXG4gICAgICAgICAgICBjdHgubG9nLmluZm8oYElmIHlvdSB3YW50IHRvIHVzZSB0aGlzIGNvbmZpZywgcGxlYXNlIHJ1biAncGljZ28gdXNlICR7dXNlTW9kdWxlTmFtZX0nYClcclxuICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xyXG4gICAgICAgICAgICBjdHgubG9nLmVycm9yKGUpXHJcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmFyZ3YuaW5jbHVkZXMoJy0tZGVidWcnKSkge1xyXG4gICAgICAgICAgICAgIHRocm93IGVcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pKCkuY2F0Y2goKGUpID0+IHsgY3R4LmxvZy5lcnJvcihlKSB9KVxyXG4gICAgICB9KVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgc2V0dGluZ1xyXG4iLCJpbXBvcnQgeyBJUGljR28sIElQbHVnaW4sIFVuZGVmaW5hYmxlLCBJQ0xJQ29uZmlncywgSVN0cmluZ0tleU1hcCB9IGZyb20gJy4uLy4uL3R5cGVzJ1xyXG5cclxuY29uc3QgdXNlOiBJUGx1Z2luID0ge1xyXG4gIGhhbmRsZTogYXN5bmMgKGN0eDogSVBpY0dvKSA9PiB7XHJcbiAgICBjb25zdCBjbWQgPSBjdHguY21kXHJcbiAgICBjbWQucHJvZ3JhbVxyXG4gICAgICAuY29tbWFuZCgndXNlJylcclxuICAgICAgLmFyZ3VtZW50cygnW21vZHVsZV0nKVxyXG4gICAgICAuZGVzY3JpcHRpb24oJ3VzZSBtb2R1bGVzIG9mIHBpY2dvJylcclxuICAgICAgLmFjdGlvbigobW9kdWxlOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAoYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgLy8gLy8gbG9hZCB0aGlyZC1wYXJ0eSBwbHVnaW5zXHJcbiAgICAgICAgICAgIC8vIGF3YWl0IGN0eC5wbHVnaW5Mb2FkZXIubG9hZCgpXHJcbiAgICAgICAgICAgIGxldCBwcm9tcHRzOiBhbnlbXSA9IFtdXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbmZpZzogSUNMSUNvbmZpZ3MgPSB7XHJcbiAgICAgICAgICAgICAgdXBsb2FkZXI6IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6ICdsaXN0JyxcclxuICAgICAgICAgICAgICAgIG5hbWU6ICd1cGxvYWRlcicsXHJcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnVXNlIGFuIHVwbG9hZGVyJyxcclxuICAgICAgICAgICAgICAgIGNob2ljZXM6IGN0eC5oZWxwZXIudXBsb2FkZXIuZ2V0SWRMaXN0KCksXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBjdHguZ2V0Q29uZmlnKCdwaWNCZWQudXBsb2FkZXInKSB8fCBjdHguZ2V0Q29uZmlnKCdwaWNCZWQuY3VycmVudCcpIHx8ICdzbW1zJ1xyXG4gICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgdHJhbnNmb3JtZXI6IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6ICdsaXN0JyxcclxuICAgICAgICAgICAgICAgIG5hbWU6ICd0cmFuc2Zvcm1lcicsXHJcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnVXNlIGEgdHJhbnNmb3JtZXInLFxyXG4gICAgICAgICAgICAgICAgY2hvaWNlczogY3R4LmhlbHBlci50cmFuc2Zvcm1lci5nZXRJZExpc3QoKSxcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGN0eC5nZXRDb25maWc8VW5kZWZpbmFibGU8c3RyaW5nPj4oJ3BpY0JlZC50cmFuc2Zvcm1lcicpIHx8ICdwYXRoJ1xyXG4gICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgcGx1Z2luczoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogJ2NoZWNrYm94JyxcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdwbHVnaW5zJyxcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdVc2UgcGx1Z2lucycsXHJcbiAgICAgICAgICAgICAgICBjaG9pY2VzOiBjdHgucGx1Z2luTG9hZGVyLmdldEZ1bGxMaXN0KCksXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBPYmplY3Qua2V5cyhjdHguZ2V0Q29uZmlnKCdwaWNnb1BsdWdpbnMnKSkuZmlsdGVyKChpdGVtOiBzdHJpbmcpID0+IGN0eC5nZXRDb25maWcoYHBpY2dvUGx1Z2lucy4ke2l0ZW19YCkpXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGlmIGFuIG9wdGlvbiBpcyBzcGVjaWZpYywgdGhlbiBqdXN0IHNldCB0aGlzIG9wdGlvbiBpbiBjb25maWdcclxuICAgICAgICAgICAgaWYgKG1vZHVsZSkge1xyXG4gICAgICAgICAgICAgIGlmIChjb25maWdbbW9kdWxlXSkge1xyXG4gICAgICAgICAgICAgICAgcHJvbXB0cy5wdXNoKGNvbmZpZ1ttb2R1bGVdKVxyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjdHgubG9nLndhcm4oYE5vIG1vZHVsZSBuYW1lZCAke21vZHVsZX1gKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5sb2cud2FybignQXZhaWxhYmxlIG1vZHVsZXMgYXJlIHVwbG9hZGVyfHRyYW5zZm9ybWVyfHBsdWdpbnMnKVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBwcm9tcHRzID0gT2JqZWN0LmtleXMoY29uZmlnKS5tYXAoKGl0ZW06IHN0cmluZykgPT4gY29uZmlnW2l0ZW1dKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGFuc3dlciA9IGF3YWl0IGNtZC5pbnF1aXJlci5wcm9tcHQ8YW55Pihwcm9tcHRzKVxyXG5cclxuICAgICAgICAgICAgLy8gaGFuZGxlIGZvciBwbHVnaW5zIG9wdGlvbiBmcm9tIEFycmF5IHRvIG9iamVjdFxyXG4gICAgICAgICAgICBpZiAoYW5zd2VyLnBsdWdpbnMpIHtcclxuICAgICAgICAgICAgICBjb25zdCBwbHVnaW5zID0gY3R4LmdldENvbmZpZzxJU3RyaW5nS2V5TWFwPGJvb2xlYW4+PigncGljZ29QbHVnaW5zJylcclxuICAgICAgICAgICAgICBPYmplY3Qua2V5cyhwbHVnaW5zKS5tYXAoKGl0ZW06IHN0cmluZykgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFuc3dlci5wbHVnaW5zLmluY2x1ZGVzKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgIHBsdWdpbnNbaXRlbV0gPSB0cnVlXHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICBwbHVnaW5zW2l0ZW1dID0gZmFsc2VcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgIC8vIHNhdmUgY29uZmlnIGZvciBwbHVnaW5zXHJcbiAgICAgICAgICAgICAgY3R4LnNhdmVDb25maWcoe1xyXG4gICAgICAgICAgICAgICAgcGljZ29QbHVnaW5zOiBwbHVnaW5zXHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBzYXZlIGNvbmZpZyBmb3IgdXBsb2FkZXIgJiB0cmFuc2Zvcm1lclxyXG4gICAgICAgICAgICBjdHguc2F2ZUNvbmZpZyh7XHJcbiAgICAgICAgICAgICAgJ3BpY0JlZC5jdXJyZW50JzogYW5zd2VyLnVwbG9hZGVyIHx8IGN0eC5nZXRDb25maWc8c3RyaW5nPigncGljQmVkLmN1cnJlbnQnKSxcclxuICAgICAgICAgICAgICAncGljQmVkLnVwbG9hZGVyJzogYW5zd2VyLnVwbG9hZGVyIHx8IGN0eC5nZXRDb25maWc8c3RyaW5nPigncGljQmVkLmN1cnJlbnQnKSxcclxuICAgICAgICAgICAgICAncGljQmVkLnRyYW5zZm9ybWVyJzogYW5zd2VyLnRyYW5zZm9ybWVyIHx8ICdwYXRoJ1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICBjdHgubG9nLnN1Y2Nlc3MoJ0NvbmZpZ3VyZSBjb25maWcgc3VjY2Vzc2Z1bGx5IScpXHJcbiAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcclxuICAgICAgICAgICAgY3R4LmxvZy5lcnJvcihlKVxyXG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5hcmd2LmluY2x1ZGVzKCctLWRlYnVnJykpIHtcclxuICAgICAgICAgICAgICB0aHJvdyBlXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9KSgpLmNhdGNoKChlKSA9PiB7IGN0eC5sb2cuZXJyb3IoZSkgfSlcclxuICAgICAgfSlcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IHVzZVxyXG4iLCJpbXBvcnQgeyBJUGljR28sIElQbHVnaW4gfSBmcm9tICcuLi8uLi90eXBlcydcclxuXHJcbmNvbnN0IHByb3h5OiBJUGx1Z2luID0ge1xyXG4gIGhhbmRsZTogKGN0eDogSVBpY0dvKSA9PiB7XHJcbiAgICBjb25zdCBjbWQgPSBjdHguY21kXHJcbiAgICBjbWQucHJvZ3JhbVxyXG4gICAgICAub3B0aW9uKCctcCwgLS1wcm94eSA8dXJsPicsICdzZXQgcHJveHkgZm9yIHVwbG9hZGluZycsIChwcm94eTogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgY3R4LnNldENvbmZpZyh7XHJcbiAgICAgICAgICAncGljQmVkLnByb3h5JzogcHJveHlcclxuICAgICAgICB9KVxyXG4gICAgICB9KVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgcHJveHlcclxuIiwiaW1wb3J0IG1hdGNoIGZyb20gJ21pbmltYXRjaCdcclxuaW1wb3J0IHsgSVBpY0dvLCBJT3B0aW9ucywgSUZpbGVUcmVlIH0gZnJvbSAnLi4vdHlwZXMnXHJcbmltcG9ydCBmcyBmcm9tICdmcy1leHRyYSdcclxuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcclxuaW1wb3J0IGdsb2JieSBmcm9tICdnbG9iYnknXHJcbmltcG9ydCBlanMgZnJvbSAnZWpzJ1xyXG5cclxuLyoqXHJcbiAqIEdlbmVyYXRlIHRlbXBsYXRlIGZpbGVzIHRvIGRlc3RpbmF0aW9uIGZpbGVzLlxyXG4gKiBAcGFyYW0ge1BpY0dvfSBjdHhcclxuICogQHBhcmFtIHtJT3B0aW9uc30gb3B0aW9uc1xyXG4gKi9cclxuY29uc3QgZ2VuZXJhdGUgPSBhc3luYyAoY3R4OiBJUGljR28sIG9wdGlvbnM6IElPcHRpb25zKTogUHJvbWlzZTxhbnk+ID0+IHtcclxuICB0cnkge1xyXG4gICAgY29uc3Qgb3B0cyA9IGdldE9wdGlvbnMob3B0aW9ucy50bXApXHJcbiAgICBjb25zdCBzb3VyY2UgPSBwYXRoLmpvaW4ob3B0aW9ucy50bXAsICd0ZW1wbGF0ZScpXHJcbiAgICBsZXQgYW5zd2VycyA9IHt9XHJcbiAgICBpZiAob3B0cy5wcm9tcHRzICYmIG9wdHMucHJvbXB0cy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGFuc3dlcnMgPSBhd2FpdCBjdHguY21kLmlucXVpcmVyLnByb21wdChvcHRzLnByb21wdHMpXHJcbiAgICB9XHJcbiAgICBsZXQgX2ZpbGVzOiBzdHJpbmdbXSA9IGF3YWl0IGdsb2JieShbJyoqLyonXSwgeyBjd2Q6IHNvdXJjZSwgZG90OiB0cnVlIH0pIC8vIGdldCBmaWxlcycgbmFtZSBhcnJheVxyXG4gICAgX2ZpbGVzID0gX2ZpbGVzLmZpbHRlcigoaXRlbTogc3RyaW5nKSA9PiB7XHJcbiAgICAgIGxldCBnbG9iID0gJydcclxuICAgICAgT2JqZWN0LmtleXMob3B0cy5maWx0ZXJzKS5mb3JFYWNoKChrZXk6IHN0cmluZykgPT4ge1xyXG4gICAgICAgIGlmIChtYXRjaChpdGVtLCBrZXksIHsgZG90OiB0cnVlIH0pKSB7XHJcbiAgICAgICAgICBnbG9iID0gaXRlbVxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICAgaWYgKGdsb2IpIHsgLy8gZmluZCBhIGZpbHRlciBleHByZXNzaW9uXHJcbiAgICAgICAgcmV0dXJuIGZpbHRlcnMoY3R4LCBvcHRzLmZpbHRlcnNbZ2xvYl0sIGFuc3dlcnMpXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHRydWVcclxuICAgICAgfVxyXG4gICAgfSlcclxuICAgIGlmIChfZmlsZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHJldHVybiBjdHgubG9nLndhcm4oJ1RlbXBsYXRlIGZpbGVzIG5vdCBmb3VuZCEnKVxyXG4gICAgfVxyXG4gICAgY29uc3QgZmlsZXMgPSByZW5kZXIoX2ZpbGVzLCBzb3VyY2UsIGFuc3dlcnMpXHJcbiAgICB3cml0ZUZpbGVUcmVlKG9wdGlvbnMuZGVzdCwgZmlsZXMpXHJcbiAgICBpZiAodHlwZW9mIG9wdHMuY29tcGxldGUgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgb3B0cy5jb21wbGV0ZSh7IGFuc3dlcnMsIG9wdGlvbnMsIGZpbGVzOiBfZmlsZXMsIGN0eCB9KVxyXG4gICAgfVxyXG4gICAgaWYgKG9wdHMuY29tcGxldGVNZXNzYWdlKSB7XHJcbiAgICAgIGN0eC5sb2cuc3VjY2VzcyhvcHRzLmNvbXBsZXRlTWVzc2FnZSlcclxuICAgIH1cclxuICAgIGN0eC5sb2cuc3VjY2VzcygnRG9uZSEnKVxyXG4gIH0gY2F0Y2ggKGU6IGFueSkge1xyXG4gICAgcmV0dXJuIGN0eC5sb2cuZXJyb3IoZSlcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm4gdGhlIGZpbHRlcnMnIHJlc3VsdFxyXG4gKiBAcGFyYW0gY3R4IFBpY0dvXHJcbiAqIEBwYXJhbSBleHAgY29uZGl0aW9uIGV4cHJlc3Npb25cclxuICogQHBhcmFtIGRhdGEgb3B0aW9ucyBkYXRhXHJcbiAqL1xyXG5jb25zdCBmaWx0ZXJzID0gKGN0eDogSVBpY0dvLCBleHA6IGFueSwgZGF0YTogYW55KTogYm9vbGVhbiA9PiB7XHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9yZXN0cmljdC1wbHVzLW9wZXJhbmRzLCBuby1uZXctZnVuYywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWltcGxpZWQtZXZhbFxyXG4gIGNvbnN0IGZuID0gbmV3IEZ1bmN0aW9uKCdkYXRhJywgJ3dpdGggKGRhdGEpIHsgcmV0dXJuICcgKyBleHAgKyAnfScpXHJcbiAgdHJ5IHtcclxuICAgIHJldHVybiBmbihkYXRhKVxyXG4gIH0gY2F0Y2ggKGUpIHtcclxuICAgIGN0eC5sb2cuZXJyb3IoYEVycm9yIHdoZW4gZXZhbHVhdGluZyBmaWx0ZXIgY29uZGl0aW9uOiAke0pTT04uc3RyaW5naWZ5KGV4cCl9YClcclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0ZW1wbGF0ZSBvcHRpb25zXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZW1wbGF0ZVBhdGhcclxuICovXHJcbmNvbnN0IGdldE9wdGlvbnMgPSAodGVtcGxhdGVQYXRoOiBzdHJpbmcpOiBhbnkgPT4ge1xyXG4gIGNvbnN0IG9wdGlvbnNQYXRoID0gcGF0aC5qb2luKHRlbXBsYXRlUGF0aCwgJ2luZGV4LmpzJylcclxuICBpZiAoZnMuZXhpc3RzU3luYyhvcHRpb25zUGF0aCkpIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzXHJcbiAgICBjb25zdCBvcHRpb25zID0gcmVxdWlyZShvcHRpb25zUGF0aClcclxuICAgIHJldHVybiBvcHRpb25zXHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiB7fVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFJlbmRlciBmaWxlcyB0byBhIHZpcnR1YWwgdHJlZSBvYmplY3RcclxuICogQHBhcmFtIHthcnJheX0gZmlsZXNcclxuICovXHJcbmNvbnN0IHJlbmRlciA9IChmaWxlczogc3RyaW5nW10sIHNvdXJjZTogc3RyaW5nLCBvcHRpb25zOiBhbnkpOiBhbnkgPT4ge1xyXG4gIGNvbnN0IGZpbGVUcmVlOiBJRmlsZVRyZWUgPSB7fVxyXG4gIGZpbGVzLmZvckVhY2goKGZpbGVQYXRoOiBzdHJpbmcpOiB2b2lkID0+IHtcclxuICAgIGNvbnN0IGZpbGUgPSBmcy5yZWFkRmlsZVN5bmMocGF0aC5qb2luKHNvdXJjZSwgZmlsZVBhdGgpLCAndXRmOCcpXHJcbiAgICBjb25zdCBjb250ZW50ID0gZWpzLnJlbmRlcihmaWxlLCBvcHRpb25zKVxyXG4gICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihjb250ZW50KSB8fCAvW15cXHNdLy50ZXN0KGNvbnRlbnQpKSB7XHJcbiAgICAgIGZpbGVUcmVlW2ZpbGVQYXRoXSA9IGNvbnRlbnRcclxuICAgIH1cclxuICB9KVxyXG4gIHJldHVybiBmaWxlVHJlZVxyXG59XHJcblxyXG4vKipcclxuICogV3JpdGUgcmVuZGVyZWQgZmlsZXMnIGNvbnRlbnQgdG8gcmVhbCBmaWxlXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXJcclxuICogQHBhcmFtIHtvYmplY3R9IGZpbGVzXHJcbiAqL1xyXG5jb25zdCB3cml0ZUZpbGVUcmVlID0gKGRpcjogc3RyaW5nLCBmaWxlczogYW55KTogdm9pZCA9PiB7XHJcbiAgT2JqZWN0LmtleXMoZmlsZXMpLmZvckVhY2goKG5hbWU6IHN0cmluZykgPT4ge1xyXG4gICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oZGlyLCBuYW1lKVxyXG4gICAgZnMuZW5zdXJlRGlyU3luYyhwYXRoLmRpcm5hbWUoZmlsZVBhdGgpKVxyXG4gICAgZnMud3JpdGVGaWxlU3luYyhmaWxlUGF0aCwgZmlsZXNbbmFtZV0pXHJcbiAgfSlcclxufVxyXG5cclxuZXhwb3J0IHtcclxuICBmaWx0ZXJzLFxyXG4gIGdlbmVyYXRlLFxyXG4gIHJlbmRlcixcclxuICB3cml0ZUZpbGVUcmVlXHJcbn1cclxuIiwiaW1wb3J0IGNoYWxrIGZyb20gJ2NoYWxrJ1xyXG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJ1xyXG5pbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnXHJcbmltcG9ydCB7IGdlbmVyYXRlIH0gZnJvbSAnLi4vLi4vdXRpbHMvaW5pdFV0aWxzJ1xyXG5pbXBvcnQgeyBob21lZGlyIH0gZnJvbSAnb3MnXHJcbmltcG9ydCBkb3dubG9hZCBmcm9tICdkb3dubG9hZC1naXQtcmVwbydcclxuaW1wb3J0IHsgSU9wdGlvbnMsIElQbHVnaW4sIElQaWNHbyB9IGZyb20gJy4uLy4uL3R5cGVzJ1xyXG5pbXBvcnQgcm0gZnJvbSAncmltcmFmJ1xyXG5cclxuY29uc3QgcnVuID0gKGN0eDogSVBpY0dvLCBvcHRpb25zOiBJT3B0aW9ucyk6IHZvaWQgPT4ge1xyXG4gIC8vIGNvbnN0IG5hbWUgPSBvcHRpb25zLmluUGxhY2UgPyBwYXRoLnJlbGF0aXZlKCcuLi8nLCBwcm9jZXNzLmN3ZCgpKSA6IG9wdGlvbnMucHJvamVjdFxyXG4gIGlmIChvcHRpb25zLm9mZmxpbmUpIHsgLy8gb2ZmbGluZSBtb2RlXHJcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhvcHRpb25zLnRlbXBsYXRlKSkge1xyXG4gICAgICBnZW5lcmF0ZShjdHgsIG9wdGlvbnMpLmNhdGNoKChlKSA9PiB7IGN0eC5sb2cuZXJyb3IoZSkgfSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGN0eC5sb2cuZXJyb3IoYExvY2FsIHRlbXBsYXRlICR7b3B0aW9ucy50ZW1wbGF0ZX0gbm90IGZvdW5kYClcclxuICAgIH1cclxuICB9IGVsc2UgeyAvLyBvbmxpbmUgbW9kZVxyXG4gICAgb3B0aW9ucy50ZW1wbGF0ZSA9ICFvcHRpb25zLmhhc1NsYXNoXHJcbiAgICAgID8gJ1BpY0dvL3BpY2dvLXRlbXBsYXRlLScgKyBvcHRpb25zLnRlbXBsYXRlIC8vIG9mZmljaWFsIHRlbXBsYXRlXHJcbiAgICAgIDogb3B0aW9ucy50ZW1wbGF0ZVxyXG4gICAgZG93bmxvYWRBbmRHZW5lcmF0ZShjdHgsIG9wdGlvbnMpXHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogZG93bmxvYWQgdGVtcGxhdGUgJiBnZW5lcmF0ZVxyXG4gKiBAcGFyYW0geyBQaWNHbyB9IGN0eFxyXG4gKiBAcGFyYW0geyBJT3B0aW9ucyB9IG9wdGlvbnNcclxuICovXHJcbmNvbnN0IGRvd25sb2FkQW5kR2VuZXJhdGUgPSAoY3R4OiBJUGljR28sIG9wdGlvbnM6IElPcHRpb25zKTogdm9pZCA9PiB7XHJcbiAgaWYgKGZzLmV4aXN0c1N5bmMob3B0aW9ucy50bXApKSB7XHJcbiAgICBybS5zeW5jKG9wdGlvbnMudG1wKVxyXG4gIH1cclxuICBjdHgubG9nLmluZm8oJ1RlbXBsYXRlIGZpbGVzIGFyZSBkb3dubG9hZGluZy4uLicpXHJcbiAgZG93bmxvYWQob3B0aW9ucy50ZW1wbGF0ZSwgb3B0aW9ucy50bXAsIHsgY2xvbmU6IG9wdGlvbnMuY2xvbmUgfSwgKGVycjogRXJyb3IpID0+IHtcclxuICAgIGlmIChlcnIpIHtcclxuICAgICAgcmV0dXJuIGN0eC5sb2cuZXJyb3IoZXJyKVxyXG4gICAgfVxyXG4gICAgY3R4LmxvZy5zdWNjZXNzKCdUZW1wbGF0ZSBmaWxlcyBhcmUgZG93bmxvYWRlZCEnKVxyXG4gICAgZ2VuZXJhdGUoY3R4LCBvcHRpb25zKS5jYXRjaCgoZSkgPT4geyBjdHgubG9nLmVycm9yKGUpIH0pXHJcbiAgfSlcclxufVxyXG5cclxuY29uc3QgaW5pdDogSVBsdWdpbiA9IHtcclxuICBoYW5kbGU6IGFzeW5jIChjdHg6IElQaWNHbykgPT4ge1xyXG4gICAgY29uc3QgY21kID0gY3R4LmNtZFxyXG4gICAgY21kLnByb2dyYW1cclxuICAgICAgLmNvbW1hbmQoJ2luaXQnKVxyXG4gICAgICAuYXJndW1lbnRzKCc8dGVtcGxhdGU+IFtwcm9qZWN0XScpXHJcbiAgICAgIC5vcHRpb24oJy0tY2xvbmUnLCAndXNlIGdpdCBjbG9uZScpXHJcbiAgICAgIC5vcHRpb24oJy0tb2ZmbGluZScsICd1c2UgY2FjaGVkIHRlbXBsYXRlJylcclxuICAgICAgLmRlc2NyaXB0aW9uKCdjcmVhdGUgcGljZ28gcGx1Z2luXFwncyBkZXZlbG9wbWVudCB0ZW1wbGF0ZXMnKVxyXG4gICAgICAuYWN0aW9uKCh0ZW1wbGF0ZTogc3RyaW5nLCBwcm9qZWN0OiBzdHJpbmcsIHByb2dyYW06IGFueSkgPT4ge1xyXG4gICAgICAgIChhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAvLyBUaGFua3MgdG8gdnVlLWNsaSBpbml0OiBodHRwczovL2dpdGh1Yi5jb20vdnVlanMvdnVlLWNsaS9ibG9iL21hc3Rlci9iaW4vdnVlLWluaXRcclxuICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGhhc1NsYXNoID0gdGVtcGxhdGUuaW5jbHVkZXMoJy8nKVxyXG4gICAgICAgICAgICBjb25zdCBpblBsYWNlID0gIXByb2plY3QgfHwgcHJvamVjdCA9PT0gJy4nXHJcbiAgICAgICAgICAgIGNvbnN0IGRlc3QgPSBwYXRoLnJlc29sdmUocHJvamVjdCB8fCAnLicpXHJcbiAgICAgICAgICAgIGNvbnN0IGNsb25lID0gcHJvZ3JhbS5jbG9uZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICBjb25zdCBvZmZsaW5lID0gcHJvZ3JhbS5vZmZsaW5lIHx8IGZhbHNlXHJcbiAgICAgICAgICAgIGNvbnN0IHRtcCA9IHBhdGguam9pbihob21lZGlyKCksICcucGljZ28vdGVtcGxhdGVzJywgdGVtcGxhdGUucmVwbGFjZSgvWy86XS9nLCAnLScpKSAvLyBmb3IgY2FjaGluZyB0ZW1wbGF0ZVxyXG5cclxuICAgICAgICAgICAgaWYgKHByb2dyYW0ub2ZmbGluZSkge1xyXG4gICAgICAgICAgICAgIHRlbXBsYXRlID0gdG1wXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XHJcbiAgICAgICAgICAgICAgdGVtcGxhdGUsXHJcbiAgICAgICAgICAgICAgcHJvamVjdCxcclxuICAgICAgICAgICAgICBoYXNTbGFzaCxcclxuICAgICAgICAgICAgICBpblBsYWNlLFxyXG4gICAgICAgICAgICAgIGRlc3QsXHJcbiAgICAgICAgICAgICAgY2xvbmUsXHJcbiAgICAgICAgICAgICAgdG1wLFxyXG4gICAgICAgICAgICAgIG9mZmxpbmVcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gY2hlY2sgaWYgcHJvamVjdCBpcyBlbXB0eSBvciBleGlzdFxyXG4gICAgICAgICAgICBpZiAoaW5QbGFjZSB8fCBmcy5leGlzdHNTeW5jKGRlc3QpKSB7XHJcbiAgICAgICAgICAgICAgYXdhaXQgY3R4LmNtZC5pbnF1aXJlci5wcm9tcHQoW1xyXG4gICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICB0eXBlOiAnY29uZmlybScsXHJcbiAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGluUGxhY2VcclxuICAgICAgICAgICAgICAgICAgICA/ICdHZW5lcmF0ZSBwcm9qZWN0IGluIGN1cnJlbnQgZGlyZWN0b3J5PydcclxuICAgICAgICAgICAgICAgICAgICA6ICdUYXJnZXQgZGlyZWN0b3J5IGV4aXN0cy4gQ29udGludWU/JyxcclxuICAgICAgICAgICAgICAgICAgbmFtZTogJ29rJ1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIF0pLnRoZW4oKGFuc3dlcjogYW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYW5zd2VyLm9rKSB7XHJcbiAgICAgICAgICAgICAgICAgIHJ1bihjdHgsIG9wdGlvbnMpXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfSBlbHNlIHsgLy8gcHJvamVjdCBpcyBnaXZlblxyXG4gICAgICAgICAgICAgIHJ1bihjdHgsIG9wdGlvbnMpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xyXG4gICAgICAgICAgICBjdHgubG9nLmVycm9yKGUpXHJcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmFyZ3YuaW5jbHVkZXMoJy0tZGVidWcnKSkge1xyXG4gICAgICAgICAgICAgIHRocm93IGVcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pKCkuY2F0Y2goKGUpID0+IHsgY3R4LmxvZy5lcnJvcihlKSB9KVxyXG4gICAgICB9KVxyXG4gICAgICAub24oJy0taGVscCcsICgpID0+IHtcclxuICAgICAgICBjb25zb2xlLmxvZygpXHJcbiAgICAgICAgY29uc29sZS5sb2coJ0V4YW1wbGVzOicpXHJcbiAgICAgICAgY29uc29sZS5sb2coKVxyXG4gICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmdyYXkoJyAgIyBjcmVhdGUgYSBuZXcgcHJvamVjdCB3aXRoIGFuIG9mZmljaWFsIHRlbXBsYXRlJykpXHJcbiAgICAgICAgY29uc29sZS5sb2coJyAgJCBwaWNnbyBpbml0IHBsdWdpbiBteS1wcm9qZWN0JylcclxuICAgICAgICBjb25zb2xlLmxvZygpXHJcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JheSgnICAjIGNyZWF0ZSBhIG5ldyBwcm9qZWN0IHN0cmFpZ2h0IGZyb20gYSBnaXRodWIgdGVtcGxhdGUnKSlcclxuICAgICAgICBjb25zb2xlLmxvZygnICAkIHBpY2dvIGluaXQgdXNlcm5hbWUvcmVwbyBteS1wcm9qZWN0JylcclxuICAgICAgICBjb25zb2xlLmxvZygpXHJcbiAgICAgIH0pXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBpbml0XHJcbiIsImltcG9ydCB7IElQbHVnaW4sIElQaWNHbywgSVN0cmluZ0tleU1hcCB9IGZyb20gJy4uLy4uL3R5cGVzJ1xyXG5cclxuY29uc3QgaTE4bjogSVBsdWdpbiA9IHtcclxuICBoYW5kbGU6IChjdHg6IElQaWNHbykgPT4ge1xyXG4gICAgY29uc3QgY21kID0gY3R4LmNtZFxyXG4gICAgY21kLnByb2dyYW1cclxuICAgICAgLmNvbW1hbmQoJ2kxOG4nKVxyXG4gICAgICAuYXJndW1lbnRzKCdbbGFuZ10nKVxyXG4gICAgICAuZGVzY3JpcHRpb24oJ2NoYW5nZSBwaWNnbyBsYW5ndWFnZScpXHJcbiAgICAgIC5hY3Rpb24oYXN5bmMgKGxhbmc6IHN0cmluZyA9ICcnKSA9PiB7XHJcbiAgICAgICAgY29uc3QgbGlzdCA9IGN0eC5pMThuLmdldExhbmd1YWdlTGlzdCgpXHJcbiAgICAgICAgaWYgKCFsYW5nKSB7XHJcbiAgICAgICAgICBjb25zdCBwcm9tcHRzID0gW1xyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgdHlwZTogJ2xpc3QnLFxyXG4gICAgICAgICAgICAgIG5hbWU6ICdpMThuJyxcclxuICAgICAgICAgICAgICBjaG9pY2VzOiBsaXN0LFxyXG4gICAgICAgICAgICAgIG1lc3NhZ2U6ICdDaG9vc2UgYSBsYW5ndWFnZScsXHJcbiAgICAgICAgICAgICAgZGVmYXVsdDogY3R4LmdldENvbmZpZygnc2V0dGluZ3MubGFuZ3VhZ2UnKSB8fCAnemgtQ04nXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIF1cclxuICAgICAgICAgIGNvbnN0IGFuc3dlciA9IGF3YWl0IGN0eC5jbWQuaW5xdWlyZXIucHJvbXB0PElTdHJpbmdLZXlNYXA8c3RyaW5nPj4ocHJvbXB0cylcclxuICAgICAgICAgIGN0eC5pMThuLnNldExhbmd1YWdlKGFuc3dlci5pMThuKVxyXG4gICAgICAgICAgY3R4LmxvZy5zdWNjZXNzKGBMYW5ndWFnZSBzZXQgdG8gJHthbnN3ZXIuaTE4bn1gKVxyXG4gICAgICAgICAgcmV0dXJuXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghbGlzdC5pbmNsdWRlcyhsYW5nKSkge1xyXG4gICAgICAgICAgcmV0dXJuIGN0eC5sb2cud2FybignTm8gc3VjaCBsYW5ndWFnZScpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGN0eC5pMThuLnNldExhbmd1YWdlKGxhbmcpXHJcbiAgICAgICAgY3R4LmxvZy5zdWNjZXNzKGBMYW5ndWFnZSBzZXQgdG8gJHtsYW5nfWApXHJcbiAgICAgIH0pXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBpMThuXHJcbiIsImltcG9ydCBwbHVnaW5IYW5kbGVyIGZyb20gJy4vcGx1Z2luSGFuZGxlcidcclxuaW1wb3J0IGNvbmZpZyBmcm9tICcuL2NvbmZpZydcclxuaW1wb3J0IHVwbG9hZCBmcm9tICcuL3VwbG9hZCdcclxuaW1wb3J0IHNldHRpbmcgZnJvbSAnLi9zZXR0aW5nJ1xyXG5pbXBvcnQgdXNlIGZyb20gJy4vdXNlJ1xyXG5pbXBvcnQgcHJveHkgZnJvbSAnLi9wcm94eSdcclxuaW1wb3J0IGluaXQgZnJvbSAnLi9pbml0J1xyXG5pbXBvcnQgaTE4biBmcm9tICcuL2kxOG4nXHJcbmltcG9ydCB7IElQaWNHbyB9IGZyb20gJy4uLy4uL3R5cGVzJ1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgKGN0eDogSVBpY0dvKTogdm9pZCA9PiB7XHJcbiAgY3R4LmNtZC5yZWdpc3RlcigncGx1Z2luSGFuZGxlcicsIHBsdWdpbkhhbmRsZXIpXHJcbiAgY3R4LmNtZC5yZWdpc3RlcignY29uZmlnJywgY29uZmlnKVxyXG4gIGN0eC5jbWQucmVnaXN0ZXIoJ3NldHRpbmcnLCBzZXR0aW5nKVxyXG4gIGN0eC5jbWQucmVnaXN0ZXIoJ3VwbG9hZCcsIHVwbG9hZClcclxuICBjdHguY21kLnJlZ2lzdGVyKCd1c2UnLCB1c2UpXHJcbiAgY3R4LmNtZC5yZWdpc3RlcigncHJveHknLCBwcm94eSlcclxuICBjdHguY21kLnJlZ2lzdGVyKCdpbml0JywgaW5pdClcclxuICBjdHguY21kLnJlZ2lzdGVyKCdpMThuJywgaTE4bilcclxufVxyXG4iLCJpbXBvcnQgeyBJUGx1Z2luLCBJTGlmZWN5Y2xlUGx1Z2lucyB9IGZyb20gJy4uL3R5cGVzJ1xyXG5cclxuZXhwb3J0IGNsYXNzIExpZmVjeWNsZVBsdWdpbnMgaW1wbGVtZW50cyBJTGlmZWN5Y2xlUGx1Z2lucyB7XHJcbiAgc3RhdGljIGN1cnJlbnRQbHVnaW46IHN0cmluZyB8IG51bGxcclxuICBwcml2YXRlIHJlYWRvbmx5IGxpc3Q6IE1hcDxzdHJpbmcsIElQbHVnaW4+XHJcbiAgcHJpdmF0ZSByZWFkb25seSBwbHVnaW5JZE1hcDogTWFwPHN0cmluZywgc3RyaW5nW10+XHJcbiAgcHJpdmF0ZSByZWFkb25seSBuYW1lOiBzdHJpbmdcclxuXHJcbiAgY29uc3RydWN0b3IgKG5hbWU6IHN0cmluZykge1xyXG4gICAgdGhpcy5uYW1lID0gbmFtZVxyXG4gICAgdGhpcy5saXN0ID0gbmV3IE1hcCgpXHJcbiAgICB0aGlzLnBsdWdpbklkTWFwID0gbmV3IE1hcCgpXHJcbiAgfVxyXG5cclxuICByZWdpc3RlciAoaWQ6IHN0cmluZywgcGx1Z2luOiBJUGx1Z2luKTogdm9pZCB7XHJcbiAgICBpZiAoIWlkKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdpZCBpcyByZXF1aXJlZCEnKVxyXG4gICAgaWYgKHR5cGVvZiBwbHVnaW4uaGFuZGxlICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdwbHVnaW4uaGFuZGxlIG11c3QgYmUgYSBmdW5jdGlvbiEnKVxyXG4gICAgaWYgKHRoaXMubGlzdC5oYXMoaWQpKSB0aHJvdyBuZXcgVHlwZUVycm9yKGAke3RoaXMubmFtZX0gZHVwbGljYXRlIGlkOiAke2lkfSFgKVxyXG4gICAgdGhpcy5saXN0LnNldChpZCwgcGx1Z2luKVxyXG4gICAgaWYgKExpZmVjeWNsZVBsdWdpbnMuY3VycmVudFBsdWdpbikge1xyXG4gICAgICBpZiAodGhpcy5wbHVnaW5JZE1hcC5oYXMoTGlmZWN5Y2xlUGx1Z2lucy5jdXJyZW50UGx1Z2luKSkge1xyXG4gICAgICAgIHRoaXMucGx1Z2luSWRNYXAuZ2V0KExpZmVjeWNsZVBsdWdpbnMuY3VycmVudFBsdWdpbik/LnB1c2goaWQpXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5wbHVnaW5JZE1hcC5zZXQoTGlmZWN5Y2xlUGx1Z2lucy5jdXJyZW50UGx1Z2luLCBbaWRdKVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB1bnJlZ2lzdGVyIChwbHVnaW5OYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnBsdWdpbklkTWFwLmhhcyhwbHVnaW5OYW1lKSkge1xyXG4gICAgICBjb25zdCBwbHVnaW5MaXN0ID0gdGhpcy5wbHVnaW5JZE1hcC5nZXQocGx1Z2luTmFtZSlcclxuICAgICAgcGx1Z2luTGlzdD8uZm9yRWFjaCgocGx1Z2luOiBzdHJpbmcpID0+IHtcclxuICAgICAgICB0aGlzLmxpc3QuZGVsZXRlKHBsdWdpbilcclxuICAgICAgfSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldE5hbWUgKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5uYW1lXHJcbiAgfVxyXG5cclxuICBnZXQgKGlkOiBzdHJpbmcpOiBJUGx1Z2luIHwgdW5kZWZpbmVkIHtcclxuICAgIHJldHVybiB0aGlzLmxpc3QuZ2V0KGlkKVxyXG4gIH1cclxuXHJcbiAgZ2V0TGlzdCAoKTogSVBsdWdpbltdIHtcclxuICAgIHJldHVybiBbLi4udGhpcy5saXN0LnZhbHVlcygpXVxyXG4gIH1cclxuXHJcbiAgZ2V0SWRMaXN0ICgpOiBzdHJpbmdbXSB7XHJcbiAgICByZXR1cm4gWy4uLnRoaXMubGlzdC5rZXlzKCldXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3Qgc2V0Q3VycmVudFBsdWdpbk5hbWUgPSAobmFtZTogc3RyaW5nIHwgbnVsbCA9IG51bGwpOiB2b2lkID0+IHtcclxuICBMaWZlY3ljbGVQbHVnaW5zLmN1cnJlbnRQbHVnaW4gPSBuYW1lXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBnZXRDdXJyZW50UGx1Z2luTmFtZSA9ICgpOiBzdHJpbmcgfCBudWxsID0+IHtcclxuICByZXR1cm4gTGlmZWN5Y2xlUGx1Z2lucy5jdXJyZW50UGx1Z2luXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IExpZmVjeWNsZVBsdWdpbnNcclxuIiwiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW1pc3VzZWQtcHJvbWlzZXMgKi9cclxuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcidcclxuaW1wb3J0IGlucXVpcmVyLCB7IElucXVpcmVyIH0gZnJvbSAnaW5xdWlyZXInXHJcbmltcG9ydCB7IElQbHVnaW4sIElDb21tYW5kZXIsIElQaWNHbyB9IGZyb20gJy4uL3R5cGVzJ1xyXG5pbXBvcnQgY29tbWFuZGVycyBmcm9tICcuLi9wbHVnaW5zL2NvbW1hbmRlcidcclxuaW1wb3J0IHsgZ2V0Q3VycmVudFBsdWdpbk5hbWUgfSBmcm9tICcuL0xpZmVjeWNsZVBsdWdpbnMnXHJcblxyXG5leHBvcnQgY2xhc3MgQ29tbWFuZGVyIGltcGxlbWVudHMgSUNvbW1hbmRlciB7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBuYW1lID0gJ2NvbW1hbmRlcidcclxuICBzdGF0aWMgY3VycmVudFBsdWdpbjogc3RyaW5nIHwgbnVsbFxyXG4gIHByaXZhdGUgcmVhZG9ubHkgbGlzdDogTWFwPHN0cmluZywgSVBsdWdpbj4gPSBuZXcgTWFwKClcclxuICBwcml2YXRlIHJlYWRvbmx5IHBsdWdpbklkTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmdbXT4gPSBuZXcgTWFwKClcclxuICBwcml2YXRlIHJlYWRvbmx5IGN0eDogSVBpY0dvXHJcblxyXG4gIHByb2dyYW06IENvbW1hbmRcclxuICBpbnF1aXJlcjogSW5xdWlyZXJcclxuXHJcbiAgY29uc3RydWN0b3IgKGN0eDogSVBpY0dvKSB7XHJcbiAgICB0aGlzLnByb2dyYW0gPSBuZXcgQ29tbWFuZCgpXHJcbiAgICB0aGlzLmlucXVpcmVyID0gaW5xdWlyZXJcclxuICAgIHRoaXMuY3R4ID0gY3R4XHJcbiAgfVxyXG5cclxuICBnZXROYW1lICgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMubmFtZVxyXG4gIH1cclxuXHJcbiAgaW5pdCAoKTogdm9pZCB7XHJcbiAgICB0aGlzLnByb2dyYW1cclxuICAgICAgLnZlcnNpb24ocHJvY2Vzcy5lbnYuUElDR09fVkVSU0lPTiwgJy12LCAtLXZlcnNpb24nKVxyXG4gICAgICAub3B0aW9uKCctZCwgLS1kZWJ1ZycsICdkZWJ1ZyBtb2RlJywgKCkgPT4ge1xyXG4gICAgICAgIHRoaXMuY3R4LnNldENvbmZpZyh7XHJcbiAgICAgICAgICBkZWJ1ZzogdHJ1ZVxyXG4gICAgICAgIH0pXHJcbiAgICAgIH0pXHJcbiAgICAgIC5vcHRpb24oJy1zLCAtLXNpbGVudCcsICdzaWxlbnQgbW9kZScsICgpID0+IHtcclxuICAgICAgICB0aGlzLmN0eC5zZXRDb25maWcoe1xyXG4gICAgICAgICAgc2lsZW50OiB0cnVlXHJcbiAgICAgICAgfSlcclxuICAgICAgfSlcclxuICAgICAgLm9uKCdjb21tYW5kOionLCAoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5jdHgubG9nLmVycm9yKGBJbnZhbGlkIGNvbW1hbmQ6ICR7dGhpcy5wcm9ncmFtLmFyZ3Muam9pbignICcpfVxcblNlZSAtLWhlbHAgZm9yIGEgbGlzdCBvZiBhdmFpbGFibGUgY29tbWFuZHMuYClcclxuICAgICAgICBwcm9jZXNzLmV4aXQoMSlcclxuICAgICAgfSlcclxuXHJcbiAgICAvLyBidWlsdC1pbiBjb21tYW5kc1xyXG4gICAgY29tbWFuZGVycyh0aGlzLmN0eClcclxuICB9XHJcblxyXG4gIHJlZ2lzdGVyIChpZDogc3RyaW5nLCBwbHVnaW46IElQbHVnaW4pOiB2b2lkIHtcclxuICAgIGlmICghaWQpIHRocm93IG5ldyBUeXBlRXJyb3IoJ25hbWUgaXMgcmVxdWlyZWQhJylcclxuICAgIGlmICh0eXBlb2YgcGx1Z2luLmhhbmRsZSAhPT0gJ2Z1bmN0aW9uJykgdGhyb3cgbmV3IFR5cGVFcnJvcigncGx1Z2luLmhhbmRsZSBtdXN0IGJlIGEgZnVuY3Rpb24hJylcclxuICAgIGlmICh0aGlzLmxpc3QuaGFzKGlkKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHt0aGlzLm5hbWV9IHBsdWdpbiBkdXBsaWNhdGUgaWQ6ICR7aWR9IWApXHJcbiAgICB0aGlzLmxpc3Quc2V0KGlkLCBwbHVnaW4pXHJcbiAgICBjb25zdCBjdXJyZW50UGx1Z2luTmFtZSA9IGdldEN1cnJlbnRQbHVnaW5OYW1lKClcclxuICAgIGlmIChjdXJyZW50UGx1Z2luTmFtZSAhPT0gbnVsbCkge1xyXG4gICAgICBpZiAodGhpcy5wbHVnaW5JZE1hcC5oYXMoY3VycmVudFBsdWdpbk5hbWUpKSB7XHJcbiAgICAgICAgdGhpcy5wbHVnaW5JZE1hcC5nZXQoY3VycmVudFBsdWdpbk5hbWUpPy5wdXNoKGlkKVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMucGx1Z2luSWRNYXAuc2V0KGN1cnJlbnRQbHVnaW5OYW1lLCBbaWRdKVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB1bnJlZ2lzdGVyIChwbHVnaW5OYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnBsdWdpbklkTWFwLmhhcyhwbHVnaW5OYW1lKSkge1xyXG4gICAgICBjb25zdCBwbHVnaW5MaXN0ID0gdGhpcy5wbHVnaW5JZE1hcC5nZXQocGx1Z2luTmFtZSlcclxuICAgICAgcGx1Z2luTGlzdD8uZm9yRWFjaCgocGx1Z2luOiBzdHJpbmcpID0+IHtcclxuICAgICAgICB0aGlzLmxpc3QuZGVsZXRlKHBsdWdpbilcclxuICAgICAgfSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGxvYWRDb21tYW5kcyAoKTogdm9pZCB7XHJcbiAgICB0aGlzLmdldExpc3QoKS5mb3JFYWNoKChpdGVtOiBJUGx1Z2luKSA9PiB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgaXRlbS5oYW5kbGUodGhpcy5jdHgpXHJcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xyXG4gICAgICAgIHRoaXMuY3R4LmxvZy5lcnJvcihlKVxyXG4gICAgICB9XHJcbiAgICB9KVxyXG4gIH1cclxuXHJcbiAgZ2V0IChpZDogc3RyaW5nKTogSVBsdWdpbiB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gdGhpcy5saXN0LmdldChpZClcclxuICB9XHJcblxyXG4gIGdldExpc3QgKCk6IElQbHVnaW5bXSB7XHJcbiAgICByZXR1cm4gWy4uLnRoaXMubGlzdC52YWx1ZXMoKV1cclxuICB9XHJcblxyXG4gIGdldElkTGlzdCAoKTogc3RyaW5nW10ge1xyXG4gICAgcmV0dXJuIFsuLi50aGlzLmxpc3Qua2V5cygpXVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ29tbWFuZGVyXHJcbiIsImV4cG9ydCBlbnVtIElMb2dUeXBlIHtcclxuICBzdWNjZXNzID0gJ3N1Y2Nlc3MnLFxyXG4gIGluZm8gPSAnaW5mbycsXHJcbiAgd2FybiA9ICd3YXJuJyxcclxuICBlcnJvciA9ICdlcnJvcidcclxufVxyXG5cclxuLyoqXHJcbiAqIHRoZXNlIGV2ZW50cyB3aWxsIGJlIGNhdGNoZWQgYnkgdXNlcnNcclxuICovXHJcbmV4cG9ydCBlbnVtIElCdWlsZEluRXZlbnQge1xyXG4gIFVQTE9BRF9QUk9HUkVTUyA9ICd1cGxvYWRQcm9ncmVzcycsXHJcbiAgRkFJTEVEID0gJ2ZhaWxlZCcsXHJcbiAgQkVGT1JFX1RSQU5TRk9STSA9ICdiZWZvcmVUcmFuc2Zvcm0nLFxyXG4gIEJFRk9SRV9VUExPQUQgPSAnYmVmb3JlVXBsb2FkJyxcclxuICBBRlRFUl9VUExPQUQgPSAnYWZ0ZXJVcGxvYWQnLFxyXG4gIEZJTklTSEVEID0gJ2ZpbmlzaGVkJyxcclxuICBJTlNUQUxMID0gJ2luc3RhbGwnLFxyXG4gIFVOSU5TVEFMTCA9ICd1bmluc3RhbGwnLFxyXG4gIFVQREFURSA9ICd1cGRhdGUnLFxyXG4gIE5PVElGSUNBVElPTiA9ICdub3RpZmljYXRpb24nXHJcbn1cclxuXHJcbi8qKlxyXG4gKiB0aGVzZSBldmVudHMgd2lsbCBiZSBjYXRjaGVkIG9ubHkgYnkgcGljZ29cclxuICovXHJcbmV4cG9ydCBlbnVtIElCdXNFdmVudCB7XHJcbiAgQ09ORklHX0NIQU5HRSA9ICdDT05GSUdfQ0hBTkdFJ1xyXG59XHJcbiIsImltcG9ydCBjaGFsayBmcm9tICdjaGFsaydcclxuaW1wb3J0IGRheWpzIGZyb20gJ2RheWpzJ1xyXG5pbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnXHJcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXHJcbmltcG9ydCB1dGlsIGZyb20gJ3V0aWwnXHJcbmltcG9ydCB7IElMb2dUeXBlIH0gZnJvbSAnLi4vdXRpbHMvZW51bSdcclxuaW1wb3J0IHtcclxuICBJTG9nQXJndlR5cGUsXHJcbiAgSUxvZ0FyZ3ZUeXBlV2l0aEVycm9yLFxyXG4gIFVuZGVmaW5hYmxlLFxyXG4gIElMb2dDb2xvcixcclxuICBJTG9nZ2VyLFxyXG4gIElQaWNHb1xyXG59IGZyb20gJy4uL3R5cGVzJ1xyXG5pbXBvcnQgeyBmb3JjZU51bWJlciwgaXNEZXYgfSBmcm9tICcuLi91dGlscy9jb21tb24nXHJcblxyXG5leHBvcnQgY2xhc3MgTG9nZ2VyIGltcGxlbWVudHMgSUxvZ2dlciB7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBsZXZlbCA9IHtcclxuICAgIFtJTG9nVHlwZS5zdWNjZXNzXTogJ2dyZWVuJyxcclxuICAgIFtJTG9nVHlwZS5pbmZvXTogJ2JsdWUnLFxyXG4gICAgW0lMb2dUeXBlLndhcm5dOiAneWVsbG93JyxcclxuICAgIFtJTG9nVHlwZS5lcnJvcl06ICdyZWQnXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IGN0eDogSVBpY0dvXHJcbiAgcHJpdmF0ZSBsb2dMZXZlbCE6IHN0cmluZ1xyXG4gIHByaXZhdGUgbG9nUGF0aCE6IHN0cmluZ1xyXG4gIGNvbnN0cnVjdG9yIChjdHg6IElQaWNHbykge1xyXG4gICAgdGhpcy5jdHggPSBjdHhcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaGFuZGxlTG9nICh0eXBlOiBJTG9nVHlwZSwgLi4ubXNnOiBJTG9nQXJndlR5cGVXaXRoRXJyb3JbXSk6IHZvaWQge1xyXG4gICAgLy8gY2hlY2sgY29uZmlnLnNpbGVudFxyXG4gICAgaWYgKCF0aGlzLmN0eC5nZXRDb25maWc8VW5kZWZpbmFibGU8c3RyaW5nPj4oJ3NpbGVudCcpKSB7XHJcbiAgICAgIGNvbnN0IGxvZ0hlYWRlciA9IGNoYWxrW3RoaXMubGV2ZWxbdHlwZV0gYXMgSUxvZ0NvbG9yXShgW1BpY0dvICR7dHlwZS50b1VwcGVyQ2FzZSgpfV06YClcclxuICAgICAgY29uc29sZS5sb2cobG9nSGVhZGVyLCAuLi5tc2cpXHJcbiAgICAgIHRoaXMubG9nTGV2ZWwgPSB0aGlzLmN0eC5nZXRDb25maWcoJ3NldHRpbmdzLmxvZ0xldmVsJylcclxuICAgICAgdGhpcy5sb2dQYXRoID0gdGhpcy5jdHguZ2V0Q29uZmlnPFVuZGVmaW5hYmxlPHN0cmluZz4+KCdzZXR0aW5ncy5sb2dQYXRoJykgfHwgcGF0aC5qb2luKHRoaXMuY3R4LmJhc2VEaXIsICcuL3BpY2dvLmxvZycpXHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgIC8vIGZpeCBsb2cgZmlsZSBpcyB0b28gbGFyZ2UsIG5vdyB0aGUgbG9nIGZpbGUncyBkZWZhdWx0IHNpemUgaXMgMTAgTUJcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jaGVja0xvZ0ZpbGVJc0xhcmdlKHRoaXMubG9nUGF0aClcclxuICAgICAgICAgIGlmIChyZXN1bHQuaXNMYXJnZSkge1xyXG4gICAgICAgICAgICBjb25zdCB3YXJuaW5nTXNnID0gYExvZyBmaWxlIGlzIHRvbyBsYXJnZSAoPiAkeyhyZXN1bHQubG9nRmlsZVNpemVMaW1pdCEpIC8gMTAyNCAvIDEwMjQgfHwgJzEwJ30gTUIpLCByZWNyZWF0ZSBsb2cgZmlsZWBcclxuICAgICAgICAgICAgY29uc29sZS5sb2coY2hhbGsueWVsbG93KCdbUGljR28gV0FSTl06JyksIHdhcm5pbmdNc2cpXHJcbiAgICAgICAgICAgIHRoaXMucmVjcmVhdGVMb2dGaWxlKHRoaXMubG9nUGF0aClcclxuICAgICAgICAgICAgbXNnLnVuc2hpZnQod2FybmluZ01zZylcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHRoaXMuaGFuZGxlV3JpdGVMb2codGhpcy5sb2dQYXRoLCB0eXBlLCAuLi5tc2cpXHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgLy8gd2h5Pz8/XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdbUGljR28gRXJyb3JdIG9uIGNoZWNraW5nIGxvZyBmaWxlIHNpemUnLCBlKVxyXG4gICAgICAgIH1cclxuICAgICAgfSwgMClcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2hlY2tMb2dGaWxlSXNMYXJnZSAobG9nUGF0aDogc3RyaW5nKToge1xyXG4gICAgaXNMYXJnZTogYm9vbGVhblxyXG4gICAgbG9nRmlsZVNpemU/OiBudW1iZXJcclxuICAgIGxvZ0ZpbGVTaXplTGltaXQ/OiBudW1iZXJcclxuICB9IHtcclxuICAgIGlmIChmcy5leGlzdHNTeW5jKGxvZ1BhdGgpKSB7XHJcbiAgICAgIGNvbnN0IGxvZ0ZpbGVTaXplID0gZnMuc3RhdFN5bmMobG9nUGF0aCkuc2l6ZVxyXG4gICAgICBjb25zdCBsb2dGaWxlU2l6ZUxpbWl0ID0gZm9yY2VOdW1iZXIodGhpcy5jdHguZ2V0Q29uZmlnPFVuZGVmaW5hYmxlPG51bWJlcj4+KCdzZXR0aW5ncy5sb2dGaWxlU2l6ZUxpbWl0JykgfHwgMTApICogMTAyNCAqIDEwMjQgLy8gMTAgTUIgZGVmYXVsdFxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGlzTGFyZ2U6IGxvZ0ZpbGVTaXplID4gbG9nRmlsZVNpemVMaW1pdCxcclxuICAgICAgICBsb2dGaWxlU2l6ZSxcclxuICAgICAgICBsb2dGaWxlU2l6ZUxpbWl0XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgIGlzTGFyZ2U6IGZhbHNlXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlY3JlYXRlTG9nRmlsZSAobG9nUGF0aDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhsb2dQYXRoKSkge1xyXG4gICAgICBmcy51bmxpbmtTeW5jKGxvZ1BhdGgpXHJcbiAgICAgIGZzLmNyZWF0ZUZpbGVTeW5jKGxvZ1BhdGgpXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGhhbmRsZVdyaXRlTG9nIChsb2dQYXRoOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgLi4ubXNnOiBJTG9nQXJndlR5cGVXaXRoRXJyb3JbXSk6IHZvaWQge1xyXG4gICAgdHJ5IHtcclxuICAgICAgaWYgKHRoaXMuY2hlY2tMb2dMZXZlbCh0eXBlLCB0aGlzLmxvZ0xldmVsKSkge1xyXG4gICAgICAgIGxldCBsb2cgPSBgJHtkYXlqcygpLmZvcm1hdCgnWVlZWS1NTS1ERCBISDptbTpzcycpfSBbUGljR28gJHt0eXBlLnRvVXBwZXJDYXNlKCl9XSBgXHJcbiAgICAgICAgbXNnLmZvckVhY2goKGl0ZW06IElMb2dBcmd2VHlwZVdpdGhFcnJvcikgPT4ge1xyXG4gICAgICAgICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBFcnJvciAmJiB0eXBlID09PSAnZXJyb3InKSB7XHJcbiAgICAgICAgICAgIGxvZyArPSBgXFxuLS0tLS0tRXJyb3IgU3RhY2sgQmVnaW4tLS0tLS1cXG4ke3V0aWwuZm9ybWF0KGl0ZW0/LnN0YWNrKX1cXG4tLS0tLS0tRXJyb3IgU3RhY2sgRW5kLS0tLS0tLSBgXHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGl0ZW0gPT09ICdvYmplY3QnKSB7XHJcbiAgICAgICAgICAgICAgaXRlbSA9IEpTT04uc3RyaW5naWZ5KGl0ZW0sIG51bGwsIDIpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbG9nICs9IGAke2l0ZW0gYXMgc3RyaW5nfSBgXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgICBsb2cgKz0gJ1xcbidcclxuICAgICAgICAvLyBBIHN5bmNocm9uaXplZCBhcHByb2FjaCB0byBhdm9pZCBsb2cgbXNnIHNlcXVlbmNlIGVycm9yc1xyXG4gICAgICAgIGZzLmFwcGVuZEZpbGVTeW5jKGxvZ1BhdGgsIGxvZylcclxuICAgICAgfVxyXG4gICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdbUGljR28gRXJyb3JdIG9uIHdyaXRpbmcgbG9nIGZpbGUnLCBlKVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjaGVja0xvZ0xldmVsICh0eXBlOiBzdHJpbmcsIGxldmVsOiB1bmRlZmluZWQgfCBzdHJpbmcgfCBzdHJpbmdbXSk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKGxldmVsID09PSB1bmRlZmluZWQgfHwgbGV2ZWwgPT09ICdhbGwnKSB7XHJcbiAgICAgIHJldHVybiB0cnVlXHJcbiAgICB9XHJcbiAgICBpZiAoQXJyYXkuaXNBcnJheShsZXZlbCkpIHtcclxuICAgICAgcmV0dXJuIGxldmVsLnNvbWUoKGl0ZW06IHN0cmluZykgPT4gKGl0ZW0gPT09IHR5cGUgfHwgaXRlbSA9PT0gJ2FsbCcpKVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHR5cGUgPT09IGxldmVsXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzdWNjZXNzICguLi5tc2c6IElMb2dBcmd2VHlwZVtdKTogdm9pZCB7XHJcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2coSUxvZ1R5cGUuc3VjY2VzcywgLi4ubXNnKVxyXG4gIH1cclxuXHJcbiAgaW5mbyAoLi4ubXNnOiBJTG9nQXJndlR5cGVbXSk6IHZvaWQge1xyXG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlTG9nKElMb2dUeXBlLmluZm8sIC4uLm1zZylcclxuICB9XHJcblxyXG4gIGVycm9yICguLi5tc2c6IElMb2dBcmd2VHlwZVdpdGhFcnJvcltdKTogdm9pZCB7XHJcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2coSUxvZ1R5cGUuZXJyb3IsIC4uLm1zZylcclxuICB9XHJcblxyXG4gIHdhcm4gKC4uLm1zZzogSUxvZ0FyZ3ZUeXBlW10pOiB2b2lkIHtcclxuICAgIHJldHVybiB0aGlzLmhhbmRsZUxvZyhJTG9nVHlwZS53YXJuLCAuLi5tc2cpXHJcbiAgfVxyXG5cclxuICBkZWJ1ZyAoLi4ubXNnOiBJTG9nQXJndlR5cGVbXSk6IHZvaWQge1xyXG4gICAgaWYgKGlzRGV2KCkpIHtcclxuICAgICAgdGhpcy5oYW5kbGVMb2coSUxvZ1R5cGUuaW5mbywgLi4ubXNnKVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgTG9nZ2VyXHJcbiIsImltcG9ydCB7IElQaWNHbyB9IGZyb20gJy4uL3R5cGVzJ1xyXG5cclxuLyoqXHJcbiAqIGNyZWF0ZSBhbiB1bmlxdWUgY29udGV4dCBmb3IgZWFjaCB1cGxvYWQgcHJvY2Vzc1xyXG4gKiBAcGFyYW0gY3R4XHJcbiAqL1xyXG5leHBvcnQgY29uc3QgY3JlYXRlQ29udGV4dCA9IChjdHg6IElQaWNHbyk6IElQaWNHbyA9PiB7XHJcbiAgcmV0dXJuIHtcclxuICAgIGNvbmZpZ1BhdGg6IGN0eC5jb25maWdQYXRoLFxyXG4gICAgYmFzZURpcjogY3R4LmJhc2VEaXIsXHJcbiAgICBsb2c6IGN0eC5sb2csXHJcbiAgICBjbWQ6IGN0eC5jbWQsXHJcbiAgICBvdXRwdXQ6IFtdLFxyXG4gICAgaW5wdXQ6IFtdLFxyXG4gICAgcGx1Z2luTG9hZGVyOiBjdHgucGx1Z2luTG9hZGVyLFxyXG4gICAgcGx1Z2luSGFuZGxlcjogY3R4LnBsdWdpbkhhbmRsZXIsXHJcbiAgICBSZXF1ZXN0OiBjdHguUmVxdWVzdCxcclxuICAgIGhlbHBlcjogY3R4LmhlbHBlcixcclxuICAgIFZFUlNJT046IGN0eC5WRVJTSU9OLFxyXG4gICAgR1VJX1ZFUlNJT046IGN0eC5HVUlfVkVSU0lPTixcclxuICAgIHJlcXVlc3Q6IGN0eC5yZXF1ZXN0LFxyXG4gICAgaTE4bjogY3R4LmkxOG4sXHJcbiAgICBnZXRDb25maWc6IGN0eC5nZXRDb25maWcuYmluZChjdHgpLFxyXG4gICAgc2F2ZUNvbmZpZzogY3R4LnNhdmVDb25maWcuYmluZChjdHgpLFxyXG4gICAgcmVtb3ZlQ29uZmlnOiBjdHgucmVtb3ZlQ29uZmlnLmJpbmQoY3R4KSxcclxuICAgIHNldENvbmZpZzogY3R4LnNldENvbmZpZy5iaW5kKGN0eCksXHJcbiAgICB1bnNldENvbmZpZzogY3R4LnVuc2V0Q29uZmlnLmJpbmQoY3R4KSxcclxuICAgIHVwbG9hZDogY3R4LnVwbG9hZC5iaW5kKGN0eCksXHJcbiAgICBhZGRMaXN0ZW5lcjogY3R4LmFkZExpc3RlbmVyLmJpbmQoY3R4KSxcclxuICAgIG9uOiBjdHgub24uYmluZChjdHgpLFxyXG4gICAgb25jZTogY3R4Lm9uY2UuYmluZChjdHgpLFxyXG4gICAgcmVtb3ZlTGlzdGVuZXI6IGN0eC5yZW1vdmVMaXN0ZW5lci5iaW5kKGN0eCksXHJcbiAgICBvZmY6IGN0eC5vZmYuYmluZChjdHgpLFxyXG4gICAgcmVtb3ZlQWxsTGlzdGVuZXJzOiBjdHgucmVtb3ZlQWxsTGlzdGVuZXJzLmJpbmQoY3R4KSxcclxuICAgIHNldE1heExpc3RlbmVyczogY3R4LnNldE1heExpc3RlbmVycy5iaW5kKGN0eCksXHJcbiAgICBnZXRNYXhMaXN0ZW5lcnM6IGN0eC5nZXRNYXhMaXN0ZW5lcnMuYmluZChjdHgpLFxyXG4gICAgbGlzdGVuZXJzOiBjdHgubGlzdGVuZXJzLmJpbmQoY3R4KSxcclxuICAgIHJhd0xpc3RlbmVyczogY3R4LnJhd0xpc3RlbmVycy5iaW5kKGN0eCksXHJcbiAgICBlbWl0OiBjdHguZW1pdC5iaW5kKGN0eCksXHJcbiAgICBsaXN0ZW5lckNvdW50OiBjdHgubGlzdGVuZXJDb3VudC5iaW5kKGN0eCksXHJcbiAgICBwcmVwZW5kTGlzdGVuZXI6IGN0eC5wcmVwZW5kTGlzdGVuZXIuYmluZChjdHgpLFxyXG4gICAgcHJlcGVuZE9uY2VMaXN0ZW5lcjogY3R4LnByZXBlbmRPbmNlTGlzdGVuZXIuYmluZChjdHgpLFxyXG4gICAgZXZlbnROYW1lczogY3R4LmV2ZW50TmFtZXMuYmluZChjdHgpXHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJ2V2ZW50cydcclxuaW1wb3J0IHsgSUxpZmVjeWNsZVBsdWdpbnMsIElQaWNHbywgSVBsdWdpbiwgVW5kZWZpbmFibGUgfSBmcm9tICcuLi90eXBlcydcclxuaW1wb3J0IHsgaGFuZGxlVXJsRW5jb2RlIH0gZnJvbSAnLi4vdXRpbHMvY29tbW9uJ1xyXG5pbXBvcnQgeyBJQnVpbGRJbkV2ZW50IH0gZnJvbSAnLi4vdXRpbHMvZW51bSdcclxuaW1wb3J0IHsgY3JlYXRlQ29udGV4dCB9IGZyb20gJy4uL3V0aWxzL2NyZWF0ZUNvbnRleHQnXHJcblxyXG5leHBvcnQgY2xhc3MgTGlmZWN5Y2xlIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcclxuICBwcml2YXRlIHJlYWRvbmx5IGN0eDogSVBpY0dvXHJcblxyXG4gIGNvbnN0cnVjdG9yIChjdHg6IElQaWNHbykge1xyXG4gICAgc3VwZXIoKVxyXG4gICAgdGhpcy5jdHggPSBjdHhcclxuICB9XHJcblxyXG4gIGFzeW5jIHN0YXJ0IChpbnB1dDogYW55W10pOiBQcm9taXNlPElQaWNHbz4ge1xyXG4gICAgLy8gZW5zdXJlIGV2ZXJ5IHVwbG9hZCBwcm9jZXNzIGhhcyBhbiB1bmlxdWUgY29udGV4dFxyXG4gICAgY29uc3QgY3R4ID0gY3JlYXRlQ29udGV4dCh0aGlzLmN0eClcclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIGltYWdlcyBpbnB1dFxyXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoaW5wdXQpKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBtdXN0IGJlIGFuIGFycmF5LicpXHJcbiAgICAgIH1cclxuICAgICAgY3R4LmlucHV0ID0gaW5wdXRcclxuICAgICAgY3R4Lm91dHB1dCA9IFtdXHJcblxyXG4gICAgICAvLyBsaWZlY3ljbGUgbWFpblxyXG4gICAgICBhd2FpdCB0aGlzLmJlZm9yZVRyYW5zZm9ybShjdHgpXHJcbiAgICAgIGF3YWl0IHRoaXMuZG9UcmFuc2Zvcm0oY3R4KVxyXG4gICAgICBhd2FpdCB0aGlzLmJlZm9yZVVwbG9hZChjdHgpXHJcbiAgICAgIGF3YWl0IHRoaXMuZG9VcGxvYWQoY3R4KVxyXG4gICAgICBhd2FpdCB0aGlzLmFmdGVyVXBsb2FkKGN0eClcclxuICAgICAgcmV0dXJuIGN0eFxyXG4gICAgfSBjYXRjaCAoZTogYW55KSB7XHJcbiAgICAgIGN0eC5sb2cud2FybihJQnVpbGRJbkV2ZW50LkZBSUxFRClcclxuICAgICAgY3R4LmVtaXQoSUJ1aWxkSW5FdmVudC5VUExPQURfUFJPR1JFU1MsIC0xKVxyXG4gICAgICBjdHguZW1pdChJQnVpbGRJbkV2ZW50LkZBSUxFRCwgZSlcclxuICAgICAgY3R4LmxvZy5lcnJvcihlKVxyXG4gICAgICBpZiAoY3R4LmdldENvbmZpZzxVbmRlZmluYWJsZTxzdHJpbmc+PignZGVidWcnKSkge1xyXG4gICAgICAgIHRocm93IGVcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gY3R4XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGJlZm9yZVRyYW5zZm9ybSAoY3R4OiBJUGljR28pOiBQcm9taXNlPElQaWNHbz4ge1xyXG4gICAgY3R4LmVtaXQoSUJ1aWxkSW5FdmVudC5VUExPQURfUFJPR1JFU1MsIDApXHJcbiAgICBjdHguZW1pdChJQnVpbGRJbkV2ZW50LkJFRk9SRV9UUkFOU0ZPUk0sIGN0eClcclxuICAgIGN0eC5sb2cuaW5mbygnQmVmb3JlIHRyYW5zZm9ybScpXHJcbiAgICBhd2FpdCB0aGlzLmhhbmRsZVBsdWdpbnMoY3R4LmhlbHBlci5iZWZvcmVUcmFuc2Zvcm1QbHVnaW5zLCBjdHgpXHJcbiAgICByZXR1cm4gY3R4XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGRvVHJhbnNmb3JtIChjdHg6IElQaWNHbyk6IFByb21pc2U8SVBpY0dvPiB7XHJcbiAgICBjdHguZW1pdChJQnVpbGRJbkV2ZW50LlVQTE9BRF9QUk9HUkVTUywgMzApXHJcbiAgICBjb25zdCB0eXBlID0gY3R4LmdldENvbmZpZzxVbmRlZmluYWJsZTxzdHJpbmc+PigncGljQmVkLnRyYW5zZm9ybWVyJykgfHwgJ3BhdGgnXHJcbiAgICBsZXQgY3VycmVudFRyYW5zZm9ybWVyID0gdHlwZVxyXG4gICAgbGV0IHRyYW5zZm9ybWVyID0gY3R4LmhlbHBlci50cmFuc2Zvcm1lci5nZXQodHlwZSlcclxuICAgIGlmICghdHJhbnNmb3JtZXIpIHtcclxuICAgICAgdHJhbnNmb3JtZXIgPSBjdHguaGVscGVyLnRyYW5zZm9ybWVyLmdldCgncGF0aCcpXHJcbiAgICAgIGN1cnJlbnRUcmFuc2Zvcm1lciA9ICdwYXRoJ1xyXG4gICAgICBjdHgubG9nLndhcm4oYENhbid0IGZpbmQgdHJhbnNmb3JtZXIgLSAke3R5cGV9LCBzd2l0Y2ggdG8gZGVmYXVsdCB0cmFuc2Zvcm1lciAtIHBhdGhgKVxyXG4gICAgfVxyXG4gICAgY3R4LmxvZy5pbmZvKGBUcmFuc2Zvcm1pbmcuLi4gQ3VycmVudCB0cmFuc2Zvcm1lciBpcyBbJHtjdXJyZW50VHJhbnNmb3JtZXJ9XWApXHJcbiAgICBhd2FpdCB0cmFuc2Zvcm1lcj8uaGFuZGxlKGN0eClcclxuICAgIHJldHVybiBjdHhcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgYmVmb3JlVXBsb2FkIChjdHg6IElQaWNHbyk6IFByb21pc2U8SVBpY0dvPiB7XHJcbiAgICBjdHguZW1pdChJQnVpbGRJbkV2ZW50LlVQTE9BRF9QUk9HUkVTUywgNjApXHJcbiAgICBjdHgubG9nLmluZm8oJ0JlZm9yZSB1cGxvYWQnKVxyXG4gICAgY3R4LmVtaXQoSUJ1aWxkSW5FdmVudC5CRUZPUkVfVVBMT0FELCBjdHgpXHJcbiAgICBhd2FpdCB0aGlzLmhhbmRsZVBsdWdpbnMoY3R4LmhlbHBlci5iZWZvcmVVcGxvYWRQbHVnaW5zLCBjdHgpXHJcbiAgICByZXR1cm4gY3R4XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGRvVXBsb2FkIChjdHg6IElQaWNHbyk6IFByb21pc2U8SVBpY0dvPiB7XHJcbiAgICBsZXQgdHlwZSA9IGN0eC5nZXRDb25maWc8VW5kZWZpbmFibGU8c3RyaW5nPj4oJ3BpY0JlZC51cGxvYWRlcicpIHx8IGN0eC5nZXRDb25maWc8VW5kZWZpbmFibGU8c3RyaW5nPj4oJ3BpY0JlZC5jdXJyZW50JykgfHwgJ3NtbXMnXHJcbiAgICBsZXQgdXBsb2FkZXIgPSBjdHguaGVscGVyLnVwbG9hZGVyLmdldCh0eXBlKVxyXG4gICAgbGV0IGN1cnJlbnRUcmFuc2Zvcm1lciA9IHR5cGVcclxuICAgIGlmICghdXBsb2FkZXIpIHtcclxuICAgICAgdHlwZSA9ICdzbW1zJ1xyXG4gICAgICBjdXJyZW50VHJhbnNmb3JtZXIgPSAnc21tcydcclxuICAgICAgdXBsb2FkZXIgPSBjdHguaGVscGVyLnVwbG9hZGVyLmdldCgnc21tcycpXHJcbiAgICAgIGN0eC5sb2cud2FybihgQ2FuJ3QgZmluZCB1cGxvYWRlciAtICR7dHlwZX0sIHN3aXRjaCB0byBkZWZhdWx0IHVwbG9hZGVyIC0gc21tc2ApXHJcbiAgICB9XHJcbiAgICBjdHgubG9nLmluZm8oYFVwbG9hZGluZy4uLiBDdXJyZW50IHVwbG9hZGVyIGlzIFske2N1cnJlbnRUcmFuc2Zvcm1lcn1dYClcclxuICAgIGF3YWl0IHVwbG9hZGVyPy5oYW5kbGUoY3R4KVxyXG4gICAgZm9yIChjb25zdCBvdXRwdXRJbWcgb2YgY3R4Lm91dHB1dCkge1xyXG4gICAgICBvdXRwdXRJbWcudHlwZSA9IHR5cGVcclxuICAgIH1cclxuICAgIHJldHVybiBjdHhcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgYWZ0ZXJVcGxvYWQgKGN0eDogSVBpY0dvKTogUHJvbWlzZTxJUGljR28+IHtcclxuICAgIGN0eC5lbWl0KElCdWlsZEluRXZlbnQuQUZURVJfVVBMT0FELCBjdHgpXHJcbiAgICBjdHguZW1pdChJQnVpbGRJbkV2ZW50LlVQTE9BRF9QUk9HUkVTUywgMTAwKVxyXG4gICAgYXdhaXQgdGhpcy5oYW5kbGVQbHVnaW5zKGN0eC5oZWxwZXIuYWZ0ZXJVcGxvYWRQbHVnaW5zLCBjdHgpXHJcbiAgICBsZXQgbXNnID0gJydcclxuICAgIGNvbnN0IGxlbmd0aCA9IGN0eC5vdXRwdXQubGVuZ3RoXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGlmICh0eXBlb2YgY3R4Lm91dHB1dFtpXS5pbWdVcmwgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgbXNnICs9IGhhbmRsZVVybEVuY29kZShjdHgub3V0cHV0W2ldLmltZ1VybCEpXHJcbiAgICAgICAgaWYgKGkgIT09IGxlbmd0aCAtIDEpIHtcclxuICAgICAgICAgIG1zZyArPSAnXFxuJ1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBkZWxldGUgY3R4Lm91dHB1dFtpXS5iYXNlNjRJbWFnZVxyXG4gICAgICBkZWxldGUgY3R4Lm91dHB1dFtpXS5idWZmZXJcclxuICAgIH1cclxuICAgIGN0eC5lbWl0KElCdWlsZEluRXZlbnQuRklOSVNIRUQsIGN0eClcclxuICAgIGN0eC5sb2cuc3VjY2VzcyhgXFxuJHttc2d9YClcclxuICAgIHJldHVybiBjdHhcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlUGx1Z2lucyAobGlmZUN5Y2xlUGx1Z2luczogSUxpZmVjeWNsZVBsdWdpbnMsIGN0eDogSVBpY0dvKTogUHJvbWlzZTxJUGljR28+IHtcclxuICAgIGNvbnN0IHBsdWdpbnMgPSBsaWZlQ3ljbGVQbHVnaW5zLmdldExpc3QoKVxyXG4gICAgY29uc3QgcGx1Z2luTmFtZXMgPSBsaWZlQ3ljbGVQbHVnaW5zLmdldElkTGlzdCgpXHJcbiAgICBjb25zdCBsaWZlQ3ljbGVOYW1lID0gbGlmZUN5Y2xlUGx1Z2lucy5nZXROYW1lKClcclxuICAgIGF3YWl0IFByb21pc2UuYWxsKHBsdWdpbnMubWFwKGFzeW5jIChwbHVnaW46IElQbHVnaW4sIGluZGV4OiBudW1iZXIpID0+IHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjdHgubG9nLmluZm8oYCR7bGlmZUN5Y2xlTmFtZX06ICR7cGx1Z2luTmFtZXNbaW5kZXhdfSBydW5uaW5nYClcclxuICAgICAgICBhd2FpdCBwbHVnaW4uaGFuZGxlKGN0eClcclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIGN0eC5sb2cuZXJyb3IoYCR7bGlmZUN5Y2xlTmFtZX06ICR7cGx1Z2luTmFtZXNbaW5kZXhdfSBlcnJvcmApXHJcbiAgICAgICAgdGhyb3cgZVxyXG4gICAgICB9XHJcbiAgICB9KSlcclxuICAgIHJldHVybiBjdHhcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IExpZmVjeWNsZVxyXG4iLCJpbXBvcnQgeyBJUGljR28sIElQbHVnaW5Db25maWcsIElTbW1zQ29uZmlnLCBJT2xkUmVxT3B0aW9ucyB9IGZyb20gJy4uLy4uL3R5cGVzJ1xyXG5pbXBvcnQgeyBJQnVpbGRJbkV2ZW50IH0gZnJvbSAnLi4vLi4vdXRpbHMvZW51bSdcclxuaW1wb3J0IHsgSUxvY2FsZXNLZXkgfSBmcm9tICcuLi8uLi9pMThuL3poLUNOJ1xyXG5cclxuY29uc3QgcG9zdE9wdGlvbnMgPSAoZmlsZU5hbWU6IHN0cmluZywgaW1hZ2U6IEJ1ZmZlciwgYXBpVG9rZW46IHN0cmluZywgYmFja3VwRG9tYWluID0gJycpOiBJT2xkUmVxT3B0aW9ucyA9PiB7XHJcbiAgY29uc3QgZG9tYWluID0gYmFja3VwRG9tYWluIHx8ICdzbS5tcydcclxuICByZXR1cm4ge1xyXG4gICAgbWV0aG9kOiAnUE9TVCcsXHJcbiAgICB1cmw6IGBodHRwczovLyR7ZG9tYWlufS9hcGkvdjIvdXBsb2FkYCxcclxuICAgIGhlYWRlcnM6IHtcclxuICAgICAgY29udGVudFR5cGU6ICdtdWx0aXBhcnQvZm9ybS1kYXRhJyxcclxuICAgICAgJ1VzZXItQWdlbnQnOiAnUGljR28nLFxyXG4gICAgICBBdXRob3JpemF0aW9uOiBhcGlUb2tlblxyXG4gICAgfSxcclxuICAgIGZvcm1EYXRhOiB7XHJcbiAgICAgIHNtZmlsZToge1xyXG4gICAgICAgIHZhbHVlOiBpbWFnZSxcclxuICAgICAgICBvcHRpb25zOiB7XHJcbiAgICAgICAgICBmaWxlbmFtZTogZmlsZU5hbWVcclxuICAgICAgICB9XHJcbiAgICAgIH0sXHJcbiAgICAgIHNzbDogJ3RydWUnXHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5jb25zdCBoYW5kbGUgPSBhc3luYyAoY3R4OiBJUGljR28pOiBQcm9taXNlPElQaWNHbz4gPT4ge1xyXG4gIGNvbnN0IHNtbXNDb25maWcgPSBjdHguZ2V0Q29uZmlnPElTbW1zQ29uZmlnPigncGljQmVkLnNtbXMnKVxyXG4gIGlmICghc21tc0NvbmZpZykge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gbm90IGZpbmQgc21tcyBjb25maWchJylcclxuICB9XHJcbiAgY29uc3QgaW1nTGlzdCA9IGN0eC5vdXRwdXRcclxuICBmb3IgKGNvbnN0IGltZyBvZiBpbWdMaXN0KSB7XHJcbiAgICBpZiAoaW1nLmZpbGVOYW1lICYmIGltZy5idWZmZXIpIHtcclxuICAgICAgbGV0IGltYWdlID0gaW1nLmJ1ZmZlclxyXG4gICAgICBpZiAoIWltYWdlICYmIGltZy5iYXNlNjRJbWFnZSkge1xyXG4gICAgICAgIGltYWdlID0gQnVmZmVyLmZyb20oaW1nLmJhc2U2NEltYWdlLCAnYmFzZTY0JylcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBwb3N0Q29uZmlnID0gcG9zdE9wdGlvbnMoaW1nLmZpbGVOYW1lLCBpbWFnZSwgc21tc0NvbmZpZz8udG9rZW4sIHNtbXNDb25maWc/LmJhY2t1cERvbWFpbilcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjb25zdCByZXM6IHN0cmluZyA9IGF3YWl0IGN0eC5yZXF1ZXN0KHBvc3RDb25maWcpXHJcbiAgICAgICAgY29uc3QgYm9keSA9IEpTT04ucGFyc2UocmVzKVxyXG4gICAgICAgIGlmIChib2R5LmNvZGUgPT09ICdzdWNjZXNzJykge1xyXG4gICAgICAgICAgZGVsZXRlIGltZy5iYXNlNjRJbWFnZVxyXG4gICAgICAgICAgZGVsZXRlIGltZy5idWZmZXJcclxuICAgICAgICAgIGltZy5pbWdVcmwgPSBib2R5LmRhdGEudXJsXHJcbiAgICAgICAgfSBlbHNlIGlmIChib2R5LmNvZGUgPT09ICdpbWFnZV9yZXBlYXRlZCcgJiYgdHlwZW9mIGJvZHkuaW1hZ2VzID09PSAnc3RyaW5nJykgeyAvLyBkbyBleHRyYSBjaGVjayBzaW5jZSB0aGlzIGVycm9yIHJldHVybiBpcyBub3QgZG9jdW1lbnRlZCBhdCBodHRwczovL2RvYy5zbS5tcy8jYXBpLUltYWdlLVVwbG9hZFxyXG4gICAgICAgICAgZGVsZXRlIGltZy5iYXNlNjRJbWFnZVxyXG4gICAgICAgICAgZGVsZXRlIGltZy5idWZmZXJcclxuICAgICAgICAgIGltZy5pbWdVcmwgPSBib2R5LmltYWdlc1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjdHguZW1pdChJQnVpbGRJbkV2ZW50Lk5PVElGSUNBVElPTiwge1xyXG4gICAgICAgICAgICB0aXRsZTogY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignVVBMT0FEX0ZBSUxFRCcpLFxyXG4gICAgICAgICAgICBib2R5OiBib2R5Lm1lc3NhZ2VcclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYm9keSlcclxuICAgICAgICB9XHJcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xyXG4gICAgICAgIGN0eC5sb2cuZXJyb3IoZSlcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZSlcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gY3R4XHJcbn1cclxuXHJcbmNvbnN0IGNvbmZpZyA9IChjdHg6IElQaWNHbyk6IElQbHVnaW5Db25maWdbXSA9PiB7XHJcbiAgY29uc3QgdXNlckNvbmZpZyA9IGN0eC5nZXRDb25maWc8SVNtbXNDb25maWc+KCdwaWNCZWQuc21tcycpIHx8IHt9XHJcbiAgY29uc3QgY29uZmlnOiBJUGx1Z2luQ29uZmlnW10gPSBbXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICd0b2tlbicsXHJcbiAgICAgIG1lc3NhZ2U6ICdhcGkgdG9rZW4nLFxyXG4gICAgICB0eXBlOiAncGFzc3dvcmQnLFxyXG4gICAgICBnZXQgYWxpYXMgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1NNTVNfVE9LRU4nKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLnRva2VuIHx8ICcnLFxyXG4gICAgICByZXF1aXJlZDogdHJ1ZVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbmFtZTogJ2JhY2t1cERvbWFpbicsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBwcmVmaXggKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1NNTVNfQkFDS1VQX0RPTUFJTicpIH0sXHJcbiAgICAgIGdldCBtZXNzYWdlICgpIHtcclxuICAgICAgICByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1NNTVNfTUVTU0FHRV9CQUNLVVBfRE9NQUlOJylcclxuICAgICAgfSxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9TTU1TX0JBQ0tVUF9ET01BSU4nKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLmJhY2t1cERvbWFpbiB8fCAnJyxcclxuICAgICAgcmVxdWlyZWQ6IGZhbHNlXHJcbiAgICB9XHJcbiAgXVxyXG4gIHJldHVybiBjb25maWdcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmVnaXN0ZXIgKGN0eDogSVBpY0dvKTogdm9pZCB7XHJcbiAgY3R4LmhlbHBlci51cGxvYWRlci5yZWdpc3Rlcignc21tcycsIHtcclxuICAgIGdldCBuYW1lICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9TTU1TJykgfSxcclxuICAgIGhhbmRsZSxcclxuICAgIGNvbmZpZ1xyXG4gIH0pXHJcbn1cclxuIiwiaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nXHJcbmltcG9ydCBtaW1lIGZyb20gJ21pbWUtdHlwZXMnXHJcbmltcG9ydCB7IElQaWNHbywgSVBsdWdpbkNvbmZpZywgSVRjeXVuQ29uZmlnLCBJT2xkUmVxT3B0aW9uc1dpdGhGdWxsUmVzcG9uc2UgfSBmcm9tICcuLi8uLi90eXBlcydcclxuaW1wb3J0IHsgSUJ1aWxkSW5FdmVudCB9IGZyb20gJy4uLy4uL3V0aWxzL2VudW0nXHJcbmltcG9ydCB7IElMb2NhbGVzS2V5IH0gZnJvbSAnLi4vLi4vaTE4bi96aC1DTidcclxuXHJcbi8vIGdlbmVyYXRlIENPUyBzaWduYXR1cmUgc3RyaW5nXHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIElTaWduYXR1cmUge1xyXG4gIHNpZ25hdHVyZTogc3RyaW5nXHJcbiAgYXBwSWQ6IHN0cmluZ1xyXG4gIGJ1Y2tldDogc3RyaW5nXHJcbiAgc2lnblRpbWU6IHN0cmluZ1xyXG59XHJcblxyXG5jb25zdCBnZW5lcmF0ZVNpZ25hdHVyZSA9IChvcHRpb25zOiBJVGN5dW5Db25maWcsIGZpbGVOYW1lOiBzdHJpbmcpOiBJU2lnbmF0dXJlID0+IHtcclxuICBjb25zdCBzZWNyZXRJZCA9IG9wdGlvbnMuc2VjcmV0SWRcclxuICBjb25zdCBzZWNyZXRLZXkgPSBvcHRpb25zLnNlY3JldEtleVxyXG4gIGNvbnN0IGFwcElkID0gb3B0aW9ucy5hcHBJZFxyXG4gIGNvbnN0IGJ1Y2tldCA9IG9wdGlvbnMuYnVja2V0XHJcbiAgbGV0IHNpZ25hdHVyZVxyXG4gIGxldCBzaWduVGltZTogc3RyaW5nID0gJydcclxuICBpZiAoIW9wdGlvbnMudmVyc2lvbiB8fCBvcHRpb25zLnZlcnNpb24gPT09ICd2NCcpIHtcclxuICAgIGNvbnN0IHJhbmRvbSA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDEwMDAwMDAwMDAwKVxyXG4gICAgY29uc3QgY3VycmVudCA9IE1hdGguZmxvb3IobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKSAtIDFcclxuICAgIGNvbnN0IGV4cGlyZWQgPSBjdXJyZW50ICsgMzYwMFxyXG5cclxuICAgIGNvbnN0IG11bHRpU2lnbmF0dXJlID0gYGE9JHthcHBJZH0mYj0ke2J1Y2tldH0maz0ke3NlY3JldElkfSZlPSR7ZXhwaXJlZH0mdD0ke2N1cnJlbnR9JnI9JHtyYW5kb219JmY9YFxyXG5cclxuICAgIGNvbnN0IHNpZ25IZXhLZXkgPSBjcnlwdG8uY3JlYXRlSG1hYygnc2hhMScsIHNlY3JldEtleSkudXBkYXRlKG11bHRpU2lnbmF0dXJlKS5kaWdlc3QoKVxyXG4gICAgY29uc3QgdGVtcFN0cmluZyA9IEJ1ZmZlci5jb25jYXQoW3NpZ25IZXhLZXksIEJ1ZmZlci5mcm9tKG11bHRpU2lnbmF0dXJlKV0pXHJcbiAgICBzaWduYXR1cmUgPSBCdWZmZXIuZnJvbSh0ZW1wU3RyaW5nKS50b1N0cmluZygnYmFzZTY0JylcclxuICB9IGVsc2Uge1xyXG4gICAgLy8gaHR0cHM6Ly9jbG91ZC50ZW5jZW50LmNvbS9kb2N1bWVudC9wcm9kdWN0LzQzNi83Nzc4I3NpZ25hdHVyZVxyXG4gICAgY29uc3QgdG9kYXkgPSBNYXRoLmZsb29yKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMClcclxuICAgIGNvbnN0IHRvbW9ycm93ID0gdG9kYXkgKyA4NjQwMFxyXG4gICAgc2lnblRpbWUgPSBgJHt0b2RheX07JHt0b21vcnJvd31gXHJcbiAgICBjb25zdCBzaWduS2V5ID0gY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTEnLCBzZWNyZXRLZXkpLnVwZGF0ZShzaWduVGltZSkuZGlnZXN0KCdoZXgnKVxyXG4gICAgY29uc3QgaHR0cFN0cmluZyA9IGBwdXRcXG4vJHtvcHRpb25zLnBhdGh9JHtmaWxlTmFtZX1cXG5cXG5ob3N0PSR7b3B0aW9ucy5idWNrZXR9LmNvcy4ke29wdGlvbnMuYXJlYX0ubXlxY2xvdWQuY29tXFxuYFxyXG4gICAgY29uc3Qgc2hhMWVkSHR0cFN0cmluZyA9IGNyeXB0by5jcmVhdGVIYXNoKCdzaGExJykudXBkYXRlKGh0dHBTdHJpbmcpLmRpZ2VzdCgnaGV4JylcclxuICAgIGNvbnN0IHN0cmluZ1RvU2lnbiA9IGBzaGExXFxuJHtzaWduVGltZX1cXG4ke3NoYTFlZEh0dHBTdHJpbmd9XFxuYFxyXG4gICAgc2lnbmF0dXJlID0gY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTEnLCBzaWduS2V5KS51cGRhdGUoc3RyaW5nVG9TaWduKS5kaWdlc3QoJ2hleCcpXHJcbiAgfVxyXG4gIHJldHVybiB7XHJcbiAgICBzaWduYXR1cmUsXHJcbiAgICBhcHBJZCxcclxuICAgIGJ1Y2tldCxcclxuICAgIHNpZ25UaW1lXHJcbiAgfVxyXG59XHJcblxyXG5jb25zdCBwb3N0T3B0aW9ucyA9IChvcHRpb25zOiBJVGN5dW5Db25maWcsIGZpbGVOYW1lOiBzdHJpbmcsIHNpZ25hdHVyZTogSVNpZ25hdHVyZSwgaW1hZ2U6IEJ1ZmZlciwgdmVyc2lvbjogc3RyaW5nKTogSU9sZFJlcU9wdGlvbnNXaXRoRnVsbFJlc3BvbnNlID0+IHtcclxuICBjb25zdCBhcmVhID0gb3B0aW9ucy5hcmVhXHJcbiAgY29uc3QgcGF0aCA9IG9wdGlvbnMucGF0aFxyXG4gIGlmICghb3B0aW9ucy52ZXJzaW9uIHx8IG9wdGlvbnMudmVyc2lvbiA9PT0gJ3Y0Jykge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgbWV0aG9kOiAnUE9TVCcsXHJcbiAgICAgIHVybDogYGh0dHA6Ly8ke2FyZWF9LmZpbGUubXlxY2xvdWQuY29tL2ZpbGVzL3YyLyR7c2lnbmF0dXJlLmFwcElkfS8ke3NpZ25hdHVyZS5idWNrZXR9LyR7ZW5jb2RlVVJJKHBhdGgpfSR7ZmlsZU5hbWV9YCxcclxuICAgICAgaGVhZGVyczoge1xyXG4gICAgICAgIEhvc3Q6IGAke2FyZWF9LmZpbGUubXlxY2xvdWQuY29tYCxcclxuICAgICAgICBBdXRob3JpemF0aW9uOiBzaWduYXR1cmUuc2lnbmF0dXJlLFxyXG4gICAgICAgIGNvbnRlbnRUeXBlOiAnbXVsdGlwYXJ0L2Zvcm0tZGF0YScsXHJcbiAgICAgICAgdXNlckFnZW50OiBgUGljR287JHt2ZXJzaW9ufTtudWxsO251bGxgXHJcbiAgICAgIH0sXHJcbiAgICAgIGZvcm1EYXRhOiB7XHJcbiAgICAgICAgb3A6ICd1cGxvYWQnLFxyXG4gICAgICAgIGZpbGVjb250ZW50OiBpbWFnZVxyXG4gICAgICB9LFxyXG4gICAgICByZXNvbHZlV2l0aEZ1bGxSZXNwb25zZTogdHJ1ZVxyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBtZXRob2Q6ICdQVVQnLFxyXG4gICAgICB1cmw6IGBodHRwOi8vJHtvcHRpb25zLmJ1Y2tldH0uY29zLiR7b3B0aW9ucy5hcmVhfS5teXFjbG91ZC5jb20vJHtlbmNvZGVVUklDb21wb25lbnQocGF0aCl9JHtlbmNvZGVVUklDb21wb25lbnQoZmlsZU5hbWUpfWAsXHJcbiAgICAgIGhlYWRlcnM6IHtcclxuICAgICAgICBIb3N0OiBgJHtvcHRpb25zLmJ1Y2tldH0uY29zLiR7b3B0aW9ucy5hcmVhfS5teXFjbG91ZC5jb21gLFxyXG4gICAgICAgIEF1dGhvcml6YXRpb246IGBxLXNpZ24tYWxnb3JpdGhtPXNoYTEmcS1haz0ke29wdGlvbnMuc2VjcmV0SWR9JnEtc2lnbi10aW1lPSR7c2lnbmF0dXJlLnNpZ25UaW1lfSZxLWtleS10aW1lPSR7c2lnbmF0dXJlLnNpZ25UaW1lfSZxLWhlYWRlci1saXN0PWhvc3QmcS11cmwtcGFyYW0tbGlzdD0mcS1zaWduYXR1cmU9JHtzaWduYXR1cmUuc2lnbmF0dXJlfWAsXHJcbiAgICAgICAgY29udGVudFR5cGU6IG1pbWUubG9va3VwKGZpbGVOYW1lKSxcclxuICAgICAgICB1c2VyQWdlbnQ6IGBQaWNHbzske3ZlcnNpb259O251bGw7bnVsbGBcclxuICAgICAgfSxcclxuICAgICAgYm9keTogaW1hZ2UsXHJcbiAgICAgIHJlc29sdmVXaXRoRnVsbFJlc3BvbnNlOiB0cnVlXHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5jb25zdCBoYW5kbGUgPSBhc3luYyAoY3R4OiBJUGljR28pOiBQcm9taXNlPElQaWNHbyB8IGJvb2xlYW4+ID0+IHtcclxuICBjb25zdCB0Y1l1bk9wdGlvbnMgPSBjdHguZ2V0Q29uZmlnPElUY3l1bkNvbmZpZz4oJ3BpY0JlZC50Y3l1bicpXHJcbiAgaWYgKCF0Y1l1bk9wdGlvbnMpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcignQ2FuXFwndCBmaW5kIHRlbmNlbnQgQ09TIGNvbmZpZycpXHJcbiAgfVxyXG4gIHRyeSB7XHJcbiAgICBjb25zdCBpbWdMaXN0ID0gY3R4Lm91dHB1dFxyXG4gICAgY29uc3QgY3VzdG9tVXJsID0gdGNZdW5PcHRpb25zLmN1c3RvbVVybFxyXG4gICAgY29uc3QgcGF0aCA9IHRjWXVuT3B0aW9ucy5wYXRoXHJcbiAgICBjb25zdCB1c2VWNCA9ICF0Y1l1bk9wdGlvbnMudmVyc2lvbiB8fCB0Y1l1bk9wdGlvbnMudmVyc2lvbiA9PT0gJ3Y0J1xyXG4gICAgZm9yIChjb25zdCBpbWcgb2YgaW1nTGlzdCkge1xyXG4gICAgICBpZiAoaW1nLmZpbGVOYW1lICYmIGltZy5idWZmZXIpIHtcclxuICAgICAgICBjb25zdCBzaWduYXR1cmUgPSBnZW5lcmF0ZVNpZ25hdHVyZSh0Y1l1bk9wdGlvbnMsIGltZy5maWxlTmFtZSlcclxuICAgICAgICBpZiAoIXNpZ25hdHVyZSkge1xyXG4gICAgICAgICAgcmV0dXJuIGZhbHNlXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBpbWFnZSA9IGltZy5idWZmZXJcclxuICAgICAgICBpZiAoIWltYWdlICYmIGltZy5iYXNlNjRJbWFnZSkge1xyXG4gICAgICAgICAgaW1hZ2UgPSBCdWZmZXIuZnJvbShpbWcuYmFzZTY0SW1hZ2UsICdiYXNlNjQnKVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBvcHRpb25zID0gcG9zdE9wdGlvbnModGNZdW5PcHRpb25zLCBpbWcuZmlsZU5hbWUsIHNpZ25hdHVyZSwgaW1hZ2UsIGN0eC5HVUlfVkVSU0lPTiB8fCBjdHguVkVSU0lPTilcclxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBjdHgucmVxdWVzdChvcHRpb25zKVxyXG4gICAgICAgICAgLnRoZW4oKHJlczogYW55KSA9PiByZXMpXHJcbiAgICAgICAgICAuY2F0Y2goKGVycjogRXJyb3IpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICBzdGF0dXNDb2RlOiA0MDAsXHJcbiAgICAgICAgICAgICAgYm9keToge1xyXG4gICAgICAgICAgICAgICAgbXNnOiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdBVVRIX0ZBSUxFRCcpLFxyXG4gICAgICAgICAgICAgICAgZXJyXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgIGxldCBib2R5XHJcbiAgICAgICAgaWYgKHVzZVY0ICYmIHR5cGVvZiByZXMgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICBib2R5ID0gSlNPTi5wYXJzZShyZXMpXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGJvZHkgPSByZXNcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJvZHkuc3RhdHVzQ29kZSA9PT0gNDAwKSB7XHJcbiAgICAgICAgICBpZiAoYm9keT8uYm9keT8uZXJyKSB7XHJcbiAgICAgICAgICAgIHRocm93IGJvZHkuYm9keS5lcnJcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihib2R5Py5ib2R5Py5tc2cgfHwgYm9keT8uYm9keT8ubWVzc2FnZSlcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgb3B0aW9uVXJsID0gdGNZdW5PcHRpb25zLm9wdGlvbnMgfHwgJydcclxuICAgICAgICBpZiAodXNlVjQgJiYgYm9keS5tZXNzYWdlID09PSAnU1VDQ0VTUycpIHtcclxuICAgICAgICAgIGRlbGV0ZSBpbWcuYmFzZTY0SW1hZ2VcclxuICAgICAgICAgIGRlbGV0ZSBpbWcuYnVmZmVyXHJcbiAgICAgICAgICBpZiAoY3VzdG9tVXJsKSB7XHJcbiAgICAgICAgICAgIGltZy5pbWdVcmwgPSBgJHtjdXN0b21Vcmx9LyR7cGF0aH0ke2ltZy5maWxlTmFtZX1gXHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpbWcuaW1nVXJsID0gYCR7Ym9keS5kYXRhLnNvdXJjZV91cmwgYXMgc3RyaW5nfSR7b3B0aW9uVXJsfWBcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKCF1c2VWNCAmJiBib2R5ICYmIGJvZHkuc3RhdHVzQ29kZSA9PT0gMjAwKSB7XHJcbiAgICAgICAgICBkZWxldGUgaW1nLmJhc2U2NEltYWdlXHJcbiAgICAgICAgICBkZWxldGUgaW1nLmJ1ZmZlclxyXG4gICAgICAgICAgaWYgKGN1c3RvbVVybCkge1xyXG4gICAgICAgICAgICBpbWcuaW1nVXJsID0gYCR7Y3VzdG9tVXJsfS8ke2VuY29kZVVSSShwYXRoKX0ke2VuY29kZVVSSShpbWcuZmlsZU5hbWUpfSR7b3B0aW9uVXJsfWBcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGltZy5pbWdVcmwgPSBgaHR0cHM6Ly8ke3RjWXVuT3B0aW9ucy5idWNrZXR9LmNvcy4ke3RjWXVuT3B0aW9ucy5hcmVhfS5teXFjbG91ZC5jb20vJHtlbmNvZGVVUkkocGF0aCl9JHtlbmNvZGVVUkkoaW1nLmZpbGVOYW1lKX0ke29wdGlvblVybH1gXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihyZXMuYm9keS5tc2cpXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY3R4XHJcbiAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcclxuICAgIGlmICghdGNZdW5PcHRpb25zLnZlcnNpb24gfHwgdGNZdW5PcHRpb25zLnZlcnNpb24gPT09ICd2NCcpIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjb25zdCBib2R5ID0gSlNPTi5wYXJzZShlcnIuZXJyb3IpXHJcbiAgICAgICAgY3R4LmVtaXQoSUJ1aWxkSW5FdmVudC5OT1RJRklDQVRJT04sIHtcclxuICAgICAgICAgIHRpdGxlOiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdVUExPQURfRkFJTEVEJyksXHJcbiAgICAgICAgICBib2R5OiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdVUExPQURfRkFJTEVEX1JFQVNPTicsIHtcclxuICAgICAgICAgICAgY29kZTogYm9keS5jb2RlIGFzIHN0cmluZ1xyXG4gICAgICAgICAgfSksXHJcbiAgICAgICAgICB0ZXh0OiAnaHR0cHM6Ly9jbG91ZC50ZW5jZW50LmNvbS9kb2N1bWVudC9wcm9kdWN0LzQzNi84NDMyJ1xyXG4gICAgICAgIH0pXHJcbiAgICAgIH0gY2F0Y2ggKGUpIHt9XHJcbiAgICB9XHJcbiAgICB0aHJvdyBlcnJcclxuICB9XHJcbn1cclxuXHJcbmNvbnN0IGNvbmZpZyA9IChjdHg6IElQaWNHbyk6IElQbHVnaW5Db25maWdbXSA9PiB7XHJcbiAgY29uc3QgdXNlckNvbmZpZyA9IGN0eC5nZXRDb25maWc8SVRjeXVuQ29uZmlnPigncGljQmVkLnRjeXVuJykgfHwge31cclxuICBjb25zdCBjb25maWc6IElQbHVnaW5Db25maWdbXSA9IFtcclxuICAgIHtcclxuICAgICAgbmFtZTogJ3ZlcnNpb24nLFxyXG4gICAgICB0eXBlOiAnbGlzdCcsXHJcbiAgICAgIGFsaWFzOiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVEVOQ0VOVENMT1VEX1ZFUlNJT04nKSxcclxuICAgICAgY2hvaWNlczogWyd2NCcsICd2NSddLFxyXG4gICAgICBkZWZhdWx0OiAndjUnLFxyXG4gICAgICByZXF1aXJlZDogZmFsc2VcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdzZWNyZXRJZCcsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVEVOQ0VOVENMT1VEX1NFQ1JFVElEJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5zZWNyZXRJZCB8fCAnJyxcclxuICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdzZWNyZXRLZXknLFxyXG4gICAgICB0eXBlOiAncGFzc3dvcmQnLFxyXG4gICAgICBnZXQgYWxpYXMgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1RFTkNFTlRDTE9VRF9TRUNSRVRLRVknKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLnNlY3JldEtleSB8fCAnJyxcclxuICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdidWNrZXQnLFxyXG4gICAgICB0eXBlOiAnaW5wdXQnLFxyXG4gICAgICBnZXQgYWxpYXMgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1RFTkNFTlRDTE9VRF9CVUNLRVQnKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLmJ1Y2tldCB8fCAnJyxcclxuICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdhcHBJZCcsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBwcmVmaXggKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1RFTkNFTlRDTE9VRF9BUFBJRCcpIH0sXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVEVOQ0VOVENMT1VEX0FQUElEJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5hcHBJZCB8fCAnJyxcclxuICAgICAgZ2V0IG1lc3NhZ2UgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1RFTkNFTlRDTE9VRF9NRVNTQUdFX0FQUElEJykgfSxcclxuICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdhcmVhJyxcclxuICAgICAgdHlwZTogJ2lucHV0JyxcclxuICAgICAgZ2V0IHByZWZpeCAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVEVOQ0VOVENMT1VEX0FSRUEnKSB9LFxyXG4gICAgICBnZXQgYWxpYXMgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1RFTkNFTlRDTE9VRF9BUkVBJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5hcmVhIHx8ICcnLFxyXG4gICAgICBnZXQgbWVzc2FnZSAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVEVOQ0VOVENMT1VEX01FU1NBR0VfQVJFQScpIH0sXHJcbiAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiAncGF0aCcsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBwcmVmaXggKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1RFTkNFTlRDTE9VRF9QQVRIJykgfSxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9URU5DRU5UQ0xPVURfUEFUSCcpIH0sXHJcbiAgICAgIGRlZmF1bHQ6IHVzZXJDb25maWcucGF0aCB8fCAnJyxcclxuICAgICAgZ2V0IG1lc3NhZ2UgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1RFTkNFTlRDTE9VRF9NRVNTQUdFX1BBVEgnKSB9LFxyXG4gICAgICByZXF1aXJlZDogZmFsc2VcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdjdXN0b21VcmwnLFxyXG4gICAgICB0eXBlOiAnaW5wdXQnLFxyXG4gICAgICBnZXQgcHJlZml4ICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9URU5DRU5UQ0xPVURfQ1VTVE9NVVJMJykgfSxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9URU5DRU5UQ0xPVURfQ1VTVE9NVVJMJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5jdXN0b21VcmwgfHwgJycsXHJcbiAgICAgIGdldCBtZXNzYWdlICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9URU5DRU5UQ0xPVURfTUVTU0FHRV9DVVNUT01VUkwnKSB9LFxyXG4gICAgICByZXF1aXJlZDogZmFsc2VcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdvcHRpb25zJyxcclxuICAgICAgdHlwZTogJ2lucHV0JyxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5vcHRpb25zIHx8ICcnLFxyXG4gICAgICBnZXQgcHJlZml4ICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9URU5DRU5UQ0xPVURfT1BUSU9OUycpIH0sXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVEVOQ0VOVENMT1VEX09QVElPTlMnKSB9LFxyXG4gICAgICBnZXQgbWVzc2FnZSAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVEVOQ0VOVENMT1VEX01FU1NBR0VfT1BUSU9OUycpIH0sXHJcbiAgICAgIHJlcXVpcmVkOiBmYWxzZVxyXG4gICAgfVxyXG4gIF1cclxuICByZXR1cm4gY29uZmlnXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlZ2lzdGVyIChjdHg6IElQaWNHbyk6IHZvaWQge1xyXG4gIGN0eC5oZWxwZXIudXBsb2FkZXIucmVnaXN0ZXIoJ3RjeXVuJywge1xyXG4gICAgZ2V0IG5hbWUgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1RFTkNFTlRDTE9VRCcpIH0sXHJcbiAgICBoYW5kbGUsXHJcbiAgICBjb25maWdcclxuICB9KVxyXG59XHJcbiIsImltcG9ydCB7IElQaWNHbywgSVBsdWdpbkNvbmZpZywgSUdpdGh1YkNvbmZpZywgSU9sZFJlcU9wdGlvbnNXaXRoSlNPTiB9IGZyb20gJy4uLy4uL3R5cGVzJ1xyXG5pbXBvcnQgeyBJQnVpbGRJbkV2ZW50IH0gZnJvbSAnLi4vLi4vdXRpbHMvZW51bSdcclxuaW1wb3J0IHsgSUxvY2FsZXNLZXkgfSBmcm9tICcuLi8uLi9pMThuL3poLUNOJ1xyXG5pbXBvcnQgbWltZSBmcm9tICdtaW1lLXR5cGVzJ1xyXG5cclxuY29uc3QgcG9zdE9wdGlvbnMgPSAoZmlsZU5hbWU6IHN0cmluZywgb3B0aW9uczogSUdpdGh1YkNvbmZpZywgZGF0YTogYW55KTogSU9sZFJlcU9wdGlvbnNXaXRoSlNPTiA9PiB7XHJcbiAgY29uc3QgcGF0aCA9IG9wdGlvbnMucGF0aCB8fCAnJ1xyXG4gIGNvbnN0IHsgdG9rZW4sIHJlcG8gfSA9IG9wdGlvbnNcclxuICByZXR1cm4ge1xyXG4gICAgbWV0aG9kOiAnUFVUJyxcclxuICAgIHVybDogYGh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvJHtyZXBvfS9jb250ZW50cy8ke2VuY29kZVVSSShwYXRoKX0ke2VuY29kZVVSSShmaWxlTmFtZSl9YCxcclxuICAgIGhlYWRlcnM6IHtcclxuICAgICAgQXV0aG9yaXphdGlvbjogYHRva2VuICR7dG9rZW59YCxcclxuICAgICAgJ1VzZXItQWdlbnQnOiAnUGljR28nLFxyXG4gICAgICAnQ29udGVudC1UeXBlJzogbWltZS5sb29rdXAoZmlsZU5hbWUpXHJcbiAgICB9LFxyXG4gICAgYm9keTogZGF0YSxcclxuICAgIGpzb246IHRydWVcclxuICB9IGFzIGNvbnN0XHJcbn1cclxuXHJcbmNvbnN0IGhhbmRsZSA9IGFzeW5jIChjdHg6IElQaWNHbyk6IFByb21pc2U8SVBpY0dvPiA9PiB7XHJcbiAgY29uc3QgZ2l0aHViT3B0aW9ucyA9IGN0eC5nZXRDb25maWc8SUdpdGh1YkNvbmZpZz4oJ3BpY0JlZC5naXRodWInKVxyXG4gIGlmICghZ2l0aHViT3B0aW9ucykge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXCd0IGZpbmQgZ2l0aHViIGNvbmZpZycpXHJcbiAgfVxyXG4gIHRyeSB7XHJcbiAgICBjb25zdCBpbWdMaXN0ID0gY3R4Lm91dHB1dFxyXG4gICAgZm9yIChjb25zdCBpbWcgb2YgaW1nTGlzdCkge1xyXG4gICAgICBpZiAoaW1nLmZpbGVOYW1lICYmIGltZy5idWZmZXIpIHtcclxuICAgICAgICBjb25zdCBiYXNlNjRJbWFnZSA9IGltZy5iYXNlNjRJbWFnZSB8fCBCdWZmZXIuZnJvbShpbWcuYnVmZmVyKS50b1N0cmluZygnYmFzZTY0JylcclxuICAgICAgICBjb25zdCBkYXRhID0ge1xyXG4gICAgICAgICAgbWVzc2FnZTogJ1VwbG9hZCBieSBQaWNHbycsXHJcbiAgICAgICAgICBicmFuY2g6IGdpdGh1Yk9wdGlvbnMuYnJhbmNoLFxyXG4gICAgICAgICAgY29udGVudDogYmFzZTY0SW1hZ2UsXHJcbiAgICAgICAgICBwYXRoOiBnaXRodWJPcHRpb25zLnBhdGggKyBlbmNvZGVVUkkoaW1nLmZpbGVOYW1lKVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBwb3N0Q29uZmlnID0gcG9zdE9wdGlvbnMoaW1nLmZpbGVOYW1lLCBnaXRodWJPcHRpb25zLCBkYXRhKVxyXG4gICAgICAgIGNvbnN0IGJvZHk6IHtcclxuICAgICAgICAgIGNvbnRlbnQ6IHtcclxuICAgICAgICAgICAgZG93bmxvYWRfdXJsOiBzdHJpbmdcclxuICAgICAgICAgIH1cclxuICAgICAgICB9ID0gYXdhaXQgY3R4LnJlcXVlc3QocG9zdENvbmZpZylcclxuICAgICAgICBpZiAoYm9keSkge1xyXG4gICAgICAgICAgZGVsZXRlIGltZy5iYXNlNjRJbWFnZVxyXG4gICAgICAgICAgZGVsZXRlIGltZy5idWZmZXJcclxuICAgICAgICAgIGlmIChnaXRodWJPcHRpb25zLmN1c3RvbVVybCkge1xyXG4gICAgICAgICAgICBpbWcuaW1nVXJsID0gYCR7Z2l0aHViT3B0aW9ucy5jdXN0b21Vcmx9LyR7Z2l0aHViT3B0aW9ucy5wYXRofSR7aW1nLmZpbGVOYW1lfWBcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGltZy5pbWdVcmwgPSBib2R5LmNvbnRlbnQuZG93bmxvYWRfdXJsXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU2VydmVyIGVycm9yLCBwbGVhc2UgdHJ5IGFnYWluJylcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBjdHhcclxuICB9IGNhdGNoIChlcnIpIHtcclxuICAgIGN0eC5lbWl0KElCdWlsZEluRXZlbnQuTk9USUZJQ0FUSU9OLCB7XHJcbiAgICAgIHRpdGxlOiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdVUExPQURfRkFJTEVEJyksXHJcbiAgICAgIGJvZHk6IGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ0NIRUNLX1NFVFRJTkdTX0FORF9ORVRXT1JLJylcclxuICAgIH0pXHJcbiAgICB0aHJvdyBlcnJcclxuICB9XHJcbn1cclxuXHJcbmNvbnN0IGNvbmZpZyA9IChjdHg6IElQaWNHbyk6IElQbHVnaW5Db25maWdbXSA9PiB7XHJcbiAgY29uc3QgdXNlckNvbmZpZyA9IGN0eC5nZXRDb25maWc8SUdpdGh1YkNvbmZpZz4oJ3BpY0JlZC5naXRodWInKSB8fCB7fVxyXG4gIGNvbnN0IGNvbmZpZzogSVBsdWdpbkNvbmZpZ1tdID0gW1xyXG4gICAge1xyXG4gICAgICBuYW1lOiAncmVwbycsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBwcmVmaXggKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX0dJVEhVQl9SRVBPJykgfSxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9HSVRIVUJfUkVQTycpIH0sXHJcbiAgICAgIGdldCBtZXNzYWdlICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9HSVRIVUJfTUVTU0FHRV9SRVBPJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5yZXBvIHx8ICcnLFxyXG4gICAgICByZXF1aXJlZDogdHJ1ZVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbmFtZTogJ2JyYW5jaCcsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBwcmVmaXggKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX0dJVEhVQl9CUkFOQ0gnKSB9LFxyXG4gICAgICBnZXQgYWxpYXMgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX0dJVEhVQl9CUkFOQ0gnKSB9LFxyXG4gICAgICBnZXQgbWVzc2FnZSAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfR0lUSFVCX01FU1NBR0VfQlJBTkNIJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5icmFuY2ggfHwgJ21hc3RlcicsXHJcbiAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiAndG9rZW4nLFxyXG4gICAgICB0eXBlOiAncGFzc3dvcmQnLFxyXG4gICAgICBnZXQgYWxpYXMgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX0dJVEhVQl9UT0tFTicpIH0sXHJcbiAgICAgIGRlZmF1bHQ6IHVzZXJDb25maWcudG9rZW4gfHwgJycsXHJcbiAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiAncGF0aCcsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBwcmVmaXggKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX0dJVEhVQl9QQVRIJykgfSxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9HSVRIVUJfUEFUSCcpIH0sXHJcbiAgICAgIGdldCBtZXNzYWdlICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9HSVRIVUJfTUVTU0FHRV9QQVRIJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5wYXRoIHx8ICcnLFxyXG4gICAgICByZXF1aXJlZDogZmFsc2VcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdjdXN0b21VcmwnLFxyXG4gICAgICB0eXBlOiAnaW5wdXQnLFxyXG4gICAgICBnZXQgcHJlZml4ICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9HSVRIVUJfQ1VTVE9NVVJMJykgfSxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9HSVRIVUJfQ1VTVE9NVVJMJykgfSxcclxuICAgICAgZ2V0IG1lc3NhZ2UgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX0dJVEhVQl9NRVNTQUdFX0NVU1RPTVVSTCcpIH0sXHJcbiAgICAgIGRlZmF1bHQ6IHVzZXJDb25maWcuY3VzdG9tVXJsIHx8ICcnLFxyXG4gICAgICByZXF1aXJlZDogZmFsc2VcclxuICAgIH1cclxuICBdXHJcbiAgcmV0dXJuIGNvbmZpZ1xyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiByZWdpc3RlciAoY3R4OiBJUGljR28pOiB2b2lkIHtcclxuICBjdHguaGVscGVyLnVwbG9hZGVyLnJlZ2lzdGVyKCdnaXRodWInLCB7XHJcbiAgICBnZXQgbmFtZSAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfR0lUSFVCJykgfSxcclxuICAgIGhhbmRsZSxcclxuICAgIGNvbmZpZ1xyXG4gIH0pXHJcbn1cclxuIiwiaW1wb3J0IHFpbml1IGZyb20gJ3Fpbml1J1xyXG5pbXBvcnQgeyBJUGx1Z2luQ29uZmlnLCBJUWluaXVDb25maWcsIElQaWNHbywgSU9sZFJlcU9wdGlvbnMgfSBmcm9tICcuLi8uLi90eXBlcydcclxuaW1wb3J0IHsgSUJ1aWxkSW5FdmVudCB9IGZyb20gJy4uLy4uL3V0aWxzL2VudW0nXHJcbmltcG9ydCB7IElMb2NhbGVzS2V5IH0gZnJvbSAnLi4vLi4vaTE4bi96aC1DTidcclxuaW1wb3J0IG1pbWUgZnJvbSAnbWltZS10eXBlcydcclxuXHJcbmZ1bmN0aW9uIHBvc3RPcHRpb25zIChvcHRpb25zOiBJUWluaXVDb25maWcsIGZpbGVOYW1lOiBzdHJpbmcsIHRva2VuOiBzdHJpbmcsIGltZ0Jhc2U2NDogc3RyaW5nKTogSU9sZFJlcU9wdGlvbnMge1xyXG4gIGNvbnN0IGFyZWEgPSBzZWxlY3RBcmVhKG9wdGlvbnMuYXJlYSB8fCAnejAnKVxyXG4gIGNvbnN0IHBhdGggPSBvcHRpb25zLnBhdGggfHwgJydcclxuICBjb25zdCBiYXNlNjRGaWxlTmFtZSA9IEJ1ZmZlci5mcm9tKHBhdGggKyBmaWxlTmFtZSwgJ3V0Zi04JykudG9TdHJpbmcoJ2Jhc2U2NCcpLnJlcGxhY2UoL1xcKy9nLCAnLScpLnJlcGxhY2UoL1xcLy9nLCAnXycpXHJcbiAgcmV0dXJuIHtcclxuICAgIG1ldGhvZDogJ1BPU1QnLFxyXG4gICAgdXJsOiBgaHR0cDovL3VwbG9hZCR7YXJlYX0ucWluaXVwLmNvbS9wdXRiNjQvLTEva2V5LyR7YmFzZTY0RmlsZU5hbWV9YCxcclxuICAgIGhlYWRlcnM6IHtcclxuICAgICAgQXV0aG9yaXphdGlvbjogYFVwVG9rZW4gJHt0b2tlbn1gLFxyXG4gICAgICAnQ29udGVudC1UeXBlJzogbWltZS5sb29rdXAoZmlsZU5hbWUpIHx8ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nXHJcbiAgICB9LFxyXG4gICAgYm9keTogaW1nQmFzZTY0XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBzZWxlY3RBcmVhIChhcmVhOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gIHJldHVybiBhcmVhID09PSAnejAnID8gJycgOiAnLScgKyBhcmVhXHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldFRva2VuIChxaW5pdU9wdGlvbnM6IGFueSk6IHN0cmluZyB7XHJcbiAgY29uc3QgYWNjZXNzS2V5ID0gcWluaXVPcHRpb25zLmFjY2Vzc0tleVxyXG4gIGNvbnN0IHNlY3JldEtleSA9IHFpbml1T3B0aW9ucy5zZWNyZXRLZXlcclxuICBjb25zdCBtYWMgPSBuZXcgcWluaXUuYXV0aC5kaWdlc3QuTWFjKGFjY2Vzc0tleSwgc2VjcmV0S2V5KVxyXG4gIGNvbnN0IG9wdGlvbnMgPSB7XHJcbiAgICBzY29wZTogcWluaXVPcHRpb25zLmJ1Y2tldFxyXG4gIH1cclxuICBjb25zdCBwdXRQb2xpY3kgPSBuZXcgcWluaXUucnMuUHV0UG9saWN5KG9wdGlvbnMpXHJcbiAgcmV0dXJuIHB1dFBvbGljeS51cGxvYWRUb2tlbihtYWMpXHJcbn1cclxuXHJcbmNvbnN0IGhhbmRsZSA9IGFzeW5jIChjdHg6IElQaWNHbyk6IFByb21pc2U8SVBpY0dvPiA9PiB7XHJcbiAgY29uc3QgcWluaXVPcHRpb25zID0gY3R4LmdldENvbmZpZzxJUWluaXVDb25maWc+KCdwaWNCZWQucWluaXUnKVxyXG4gIGlmICghcWluaXVPcHRpb25zKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcJ3QgZmluZCBxaW5pdSBjb25maWcnKVxyXG4gIH1cclxuICB0cnkge1xyXG4gICAgY29uc3QgaW1nTGlzdCA9IGN0eC5vdXRwdXRcclxuICAgIGZvciAoY29uc3QgaW1nIG9mIGltZ0xpc3QpIHtcclxuICAgICAgaWYgKGltZy5maWxlTmFtZSAmJiBpbWcuYnVmZmVyKSB7XHJcbiAgICAgICAgY29uc3QgYmFzZTY0SW1hZ2UgPSBpbWcuYmFzZTY0SW1hZ2UgfHwgQnVmZmVyLmZyb20oaW1nLmJ1ZmZlcikudG9TdHJpbmcoJ2Jhc2U2NCcpXHJcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHBvc3RPcHRpb25zKHFpbml1T3B0aW9ucywgaW1nLmZpbGVOYW1lLCBnZXRUb2tlbihxaW5pdU9wdGlvbnMpLCBiYXNlNjRJbWFnZSlcclxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBjdHgucmVxdWVzdChvcHRpb25zKVxyXG4gICAgICAgIGNvbnN0IGJvZHkgPSBKU09OLnBhcnNlKHJlcylcclxuICAgICAgICBpZiAoYm9keT8ua2V5KSB7XHJcbiAgICAgICAgICBkZWxldGUgaW1nLmJhc2U2NEltYWdlXHJcbiAgICAgICAgICBkZWxldGUgaW1nLmJ1ZmZlclxyXG4gICAgICAgICAgY29uc3QgYmFzZVVybCA9IHFpbml1T3B0aW9ucy51cmxcclxuICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSBxaW5pdU9wdGlvbnMub3B0aW9uc1xyXG4gICAgICAgICAgaW1nLmltZ1VybCA9IGAke2Jhc2VVcmx9LyR7Ym9keS5rZXkgYXMgc3RyaW5nfSR7b3B0aW9uc31gXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGN0eC5lbWl0KElCdWlsZEluRXZlbnQuTk9USUZJQ0FUSU9OLCB7XHJcbiAgICAgICAgICAgIHRpdGxlOiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdVUExPQURfRkFJTEVEJyksXHJcbiAgICAgICAgICAgIGJvZHk6IGJvZHkubXNnXHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgICAgY3R4LmxvZy5lcnJvcigncWluaXUgZXJyb3InLCBib2R5KVxyXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVcGxvYWQgZmFpbGVkJylcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBjdHhcclxuICB9IGNhdGNoIChlcnI6IGFueSkge1xyXG4gICAgaWYgKGVyci5tZXNzYWdlICE9PSAnVXBsb2FkIGZhaWxlZCcpIHtcclxuICAgICAgLy8gZXJyLnJlc3BvbnNlIG1heWJlIHVuZGVmaW5lZFxyXG4gICAgICBpZiAoZXJyLnJlc3BvbnNlKSB7XHJcbiAgICAgICAgY29uc3QgZXJyb3IgPSBlcnIucmVzcG9uc2UuYm9keVxyXG4gICAgICAgIGN0eC5lbWl0KElCdWlsZEluRXZlbnQuTk9USUZJQ0FUSU9OLCB7XHJcbiAgICAgICAgICB0aXRsZTogY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignVVBMT0FEX0ZBSUxFRCcpLFxyXG4gICAgICAgICAgYm9keTogZXJyb3IuZXJyb3JcclxuICAgICAgICB9KVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aHJvdyBlcnJcclxuICB9XHJcbn1cclxuXHJcbmNvbnN0IGNvbmZpZyA9IChjdHg6IElQaWNHbyk6IElQbHVnaW5Db25maWdbXSA9PiB7XHJcbiAgY29uc3QgdXNlckNvbmZpZyA9IGN0eC5nZXRDb25maWc8SVFpbml1Q29uZmlnPigncGljQmVkLnFpbml1JykgfHwge31cclxuICBjb25zdCBjb25maWc6IElQbHVnaW5Db25maWdbXSA9IFtcclxuICAgIHtcclxuICAgICAgbmFtZTogJ2FjY2Vzc0tleScsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfUUlOSVVfQUNDRVNTS0VZJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5hY2Nlc3NLZXkgfHwgJycsXHJcbiAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiAnc2VjcmV0S2V5JyxcclxuICAgICAgdHlwZTogJ3Bhc3N3b3JkJyxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9RSU5JVV9TRUNSRVRLRVknKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLnNlY3JldEtleSB8fCAnJyxcclxuICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdidWNrZXQnLFxyXG4gICAgICB0eXBlOiAnaW5wdXQnLFxyXG4gICAgICBnZXQgYWxpYXMgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1FJTklVX0JVQ0tFVCcpIH0sXHJcbiAgICAgIGRlZmF1bHQ6IHVzZXJDb25maWcuYnVja2V0IHx8ICcnLFxyXG4gICAgICByZXF1aXJlZDogdHJ1ZVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbmFtZTogJ3VybCcsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBwcmVmaXggKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1FJTklVX1VSTCcpIH0sXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfUUlOSVVfVVJMJykgfSxcclxuICAgICAgZ2V0IG1lc3NhZ2UgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1FJTklVX01FU1NBR0VfVVJMJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy51cmwgfHwgJycsXHJcbiAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiAnYXJlYScsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBwcmVmaXggKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1FJTklVX0FSRUEnKSB9LFxyXG4gICAgICBnZXQgYWxpYXMgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1FJTklVX0FSRUEnKSB9LFxyXG4gICAgICBnZXQgbWVzc2FnZSAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfUUlOSVVfTUVTU0FHRV9BUkVBJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5hcmVhIHx8ICcnLFxyXG4gICAgICByZXF1aXJlZDogdHJ1ZVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbmFtZTogJ29wdGlvbnMnLFxyXG4gICAgICB0eXBlOiAnaW5wdXQnLFxyXG4gICAgICBnZXQgcHJlZml4ICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9RSU5JVV9PUFRJT05TJykgfSxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9RSU5JVV9PUFRJT05TJykgfSxcclxuICAgICAgZ2V0IG1lc3NhZ2UgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1FJTklVX01FU1NBR0VfT1BUSU9OUycpIH0sXHJcbiAgICAgIGRlZmF1bHQ6IHVzZXJDb25maWcub3B0aW9ucyB8fCAnJyxcclxuICAgICAgcmVxdWlyZWQ6IGZhbHNlXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiAncGF0aCcsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBwcmVmaXggKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1FJTklVX1BBVEgnKSB9LFxyXG4gICAgICBnZXQgYWxpYXMgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1FJTklVX1BBVEgnKSB9LFxyXG4gICAgICBnZXQgbWVzc2FnZSAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfUUlOSVVfTUVTU0FHRV9QQVRIJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5wYXRoIHx8ICcnLFxyXG4gICAgICByZXF1aXJlZDogZmFsc2VcclxuICAgIH1cclxuICBdXHJcbiAgcmV0dXJuIGNvbmZpZ1xyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiByZWdpc3RlciAoY3R4OiBJUGljR28pOiB2b2lkIHtcclxuICBjdHguaGVscGVyLnVwbG9hZGVyLnJlZ2lzdGVyKCdxaW5pdScsIHtcclxuICAgIGdldCBuYW1lICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9RSU5JVScpIH0sXHJcbiAgICBoYW5kbGUsXHJcbiAgICBjb25maWdcclxuICB9KVxyXG59XHJcbiIsImltcG9ydCB7IElQaWNHbywgSVBsdWdpbkNvbmZpZywgSUltZ3VyQ29uZmlnLCBJT2xkUmVxT3B0aW9ucyB9IGZyb20gJy4uLy4uL3R5cGVzJ1xyXG5pbXBvcnQgeyBJQnVpbGRJbkV2ZW50IH0gZnJvbSAnLi4vLi4vdXRpbHMvZW51bSdcclxuaW1wb3J0IHsgSUxvY2FsZXNLZXkgfSBmcm9tICcuLi8uLi9pMThuL3poLUNOJ1xyXG5cclxuY29uc3QgcG9zdE9wdGlvbnMgPSAob3B0aW9uczogSUltZ3VyQ29uZmlnLCBmaWxlTmFtZTogc3RyaW5nLCBpbWdCYXNlNjQ6IHN0cmluZyk6IElPbGRSZXFPcHRpb25zID0+IHtcclxuICBjb25zdCBjbGllbnRJZCA9IG9wdGlvbnMuY2xpZW50SWRcclxuICBjb25zdCBvYmo6IElPbGRSZXFPcHRpb25zID0ge1xyXG4gICAgbWV0aG9kOiAnUE9TVCcsXHJcbiAgICB1cmw6ICdodHRwczovL2FwaS5pbWd1ci5jb20vMy9pbWFnZScsXHJcbiAgICBoZWFkZXJzOiB7XHJcbiAgICAgIEF1dGhvcml6YXRpb246IGBDbGllbnQtSUQgJHtjbGllbnRJZH1gLFxyXG4gICAgICAnY29udGVudC10eXBlJzogJ211bHRpcGFydC9mb3JtLWRhdGEnLFxyXG4gICAgICBIb3N0OiAnYXBpLmltZ3VyLmNvbScsXHJcbiAgICAgICdVc2VyLUFnZW50JzogJ1BpY0dvJ1xyXG4gICAgfSxcclxuICAgIGZvcm1EYXRhOiB7XHJcbiAgICAgIGltYWdlOiBpbWdCYXNlNjQsXHJcbiAgICAgIHR5cGU6ICdiYXNlNjQnLFxyXG4gICAgICBuYW1lOiBmaWxlTmFtZVxyXG4gICAgfVxyXG4gIH1cclxuICBpZiAob3B0aW9ucy5wcm94eSkge1xyXG4gICAgb2JqLnByb3h5ID0gb3B0aW9ucy5wcm94eVxyXG4gIH1cclxuICByZXR1cm4gb2JqXHJcbn1cclxuXHJcbmNvbnN0IGhhbmRsZSA9IGFzeW5jIChjdHg6IElQaWNHbyk6IFByb21pc2U8SVBpY0dvPiA9PiB7XHJcbiAgY29uc3QgaW1ndXJPcHRpb25zID0gY3R4LmdldENvbmZpZzxJSW1ndXJDb25maWc+KCdwaWNCZWQuaW1ndXInKVxyXG4gIGlmICghaW1ndXJPcHRpb25zKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcJ3QgZmluZCBpbWd1ciBjb25maWcnKVxyXG4gIH1cclxuICB0cnkge1xyXG4gICAgY29uc3QgaW1nTGlzdCA9IGN0eC5vdXRwdXRcclxuICAgIGZvciAoY29uc3QgaW1nIG9mIGltZ0xpc3QpIHtcclxuICAgICAgaWYgKGltZy5maWxlTmFtZSAmJiBpbWcuYnVmZmVyKSB7XHJcbiAgICAgICAgY29uc3QgYmFzZTY0SW1hZ2UgPSBpbWcuYmFzZTY0SW1hZ2UgfHwgQnVmZmVyLmZyb20oaW1nLmJ1ZmZlcikudG9TdHJpbmcoJ2Jhc2U2NCcpXHJcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHBvc3RPcHRpb25zKGltZ3VyT3B0aW9ucywgaW1nLmZpbGVOYW1lLCBiYXNlNjRJbWFnZSlcclxuICAgICAgICBjb25zdCByZXM6IHN0cmluZyA9IGF3YWl0IGN0eC5yZXF1ZXN0KG9wdGlvbnMpXHJcbiAgICAgICAgY29uc3QgYm9keSA9IHR5cGVvZiByZXMgPT09ICdzdHJpbmcnID8gSlNPTi5wYXJzZShyZXMpIDogcmVzXHJcbiAgICAgICAgaWYgKGJvZHkuc3VjY2Vzcykge1xyXG4gICAgICAgICAgZGVsZXRlIGltZy5iYXNlNjRJbWFnZVxyXG4gICAgICAgICAgZGVsZXRlIGltZy5idWZmZXJcclxuICAgICAgICAgIGltZy5pbWdVcmwgPSBib2R5LmRhdGEubGlua1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlcnZlciBlcnJvciwgcGxlYXNlIHRyeSBhZ2FpbicpXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY3R4XHJcbiAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICBjdHguZW1pdChJQnVpbGRJbkV2ZW50Lk5PVElGSUNBVElPTiwge1xyXG4gICAgICB0aXRsZTogY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignVVBMT0FEX0ZBSUxFRCcpLFxyXG4gICAgICBib2R5OiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdDSEVDS19TRVRUSU5HU19BTkRfTkVUV09SSycpLFxyXG4gICAgICB0ZXh0OiAnaHR0cDovL2RvY3MuaW1ndXIuY29tL2FwaS9lcnJuby8nXHJcbiAgICB9KVxyXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvclxyXG4gICAgdGhyb3cgZXJyPy5yZXNwb25zZT8uZGF0YSB8fCBlcnJcclxuICB9XHJcbn1cclxuXHJcbmNvbnN0IGNvbmZpZyA9IChjdHg6IElQaWNHbyk6IElQbHVnaW5Db25maWdbXSA9PiB7XHJcbiAgY29uc3QgdXNlckNvbmZpZyA9IGN0eC5nZXRDb25maWc8SUltZ3VyQ29uZmlnPigncGljQmVkLmltZ3VyJykgfHwge31cclxuICBjb25zdCBjb25maWc6IElQbHVnaW5Db25maWdbXSA9IFtcclxuICAgIHtcclxuICAgICAgbmFtZTogJ2NsaWVudElkJyxcclxuICAgICAgdHlwZTogJ2lucHV0JyxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9JTUdVUl9DTElFTlRJRCcpIH0sXHJcbiAgICAgIGRlZmF1bHQ6IHVzZXJDb25maWcuY2xpZW50SWQgfHwgJycsXHJcbiAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiAncHJveHknLFxyXG4gICAgICB0eXBlOiAnaW5wdXQnLFxyXG4gICAgICBnZXQgcHJlZml4ICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9JTUdVUl9QUk9YWScpIH0sXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfSU1HVVJfUFJPWFknKSB9LFxyXG4gICAgICBnZXQgbWVzc2FnZSAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfSU1HVVJfTUVTU0FHRV9QUk9YWScpIH0sXHJcbiAgICAgIGRlZmF1bHQ6IHVzZXJDb25maWcucHJveHkgfHwgJycsXHJcbiAgICAgIHJlcXVpcmVkOiBmYWxzZVxyXG4gICAgfVxyXG4gIF1cclxuICByZXR1cm4gY29uZmlnXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlZ2lzdGVyIChjdHg6IElQaWNHbyk6IHZvaWQge1xyXG4gIGN0eC5oZWxwZXIudXBsb2FkZXIucmVnaXN0ZXIoJ2ltZ3VyJywge1xyXG4gICAgZ2V0IG5hbWUgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX0lNR1VSJykgfSxcclxuICAgIGhhbmRsZSxcclxuICAgIGNvbmZpZ1xyXG4gIH0pXHJcbn1cclxuIiwiaW1wb3J0IHsgSVBpY0dvLCBJUGx1Z2luQ29uZmlnLCBJQWxpeXVuQ29uZmlnLCBJT2xkUmVxT3B0aW9uc1dpdGhGdWxsUmVzcG9uc2UgfSBmcm9tICcuLi8uLi90eXBlcydcclxuaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nXHJcbmltcG9ydCBtaW1lIGZyb20gJ21pbWUtdHlwZXMnXHJcbmltcG9ydCB7IElCdWlsZEluRXZlbnQgfSBmcm9tICcuLi8uLi91dGlscy9lbnVtJ1xyXG5pbXBvcnQgeyBJTG9jYWxlc0tleSB9IGZyb20gJy4uLy4uL2kxOG4vemgtQ04nXHJcblxyXG4vLyBnZW5lcmF0ZSBPU1Mgc2lnbmF0dXJlXHJcbmNvbnN0IGdlbmVyYXRlU2lnbmF0dXJlID0gKG9wdGlvbnM6IElBbGl5dW5Db25maWcsIGZpbGVOYW1lOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xyXG4gIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpLnRvVVRDU3RyaW5nKClcclxuICBjb25zdCBtaW1lVHlwZSA9IG1pbWUubG9va3VwKGZpbGVOYW1lKVxyXG4gIGlmICghbWltZVR5cGUpIHRocm93IEVycm9yKGBObyBtaW1lIHR5cGUgZm91bmQgZm9yIGZpbGUgJHtmaWxlTmFtZX1gKVxyXG5cclxuICBjb25zdCBzaWduU3RyaW5nID0gYFBVVFxcblxcbiR7bWltZVR5cGV9XFxuJHtkYXRlfVxcbi8ke29wdGlvbnMuYnVja2V0fS8ke29wdGlvbnMucGF0aH0ke2ZpbGVOYW1lfWBcclxuXHJcbiAgY29uc3Qgc2lnbmF0dXJlID0gY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTEnLCBvcHRpb25zLmFjY2Vzc0tleVNlY3JldCkudXBkYXRlKHNpZ25TdHJpbmcpLmRpZ2VzdCgnYmFzZTY0JylcclxuICByZXR1cm4gYE9TUyAke29wdGlvbnMuYWNjZXNzS2V5SWR9OiR7c2lnbmF0dXJlfWBcclxufVxyXG5cclxuY29uc3QgcG9zdE9wdGlvbnMgPSAob3B0aW9uczogSUFsaXl1bkNvbmZpZywgZmlsZU5hbWU6IHN0cmluZywgc2lnbmF0dXJlOiBzdHJpbmcsIGltYWdlOiBCdWZmZXIpOiBJT2xkUmVxT3B0aW9uc1dpdGhGdWxsUmVzcG9uc2UgPT4ge1xyXG4gIHJldHVybiB7XHJcbiAgICBtZXRob2Q6ICdQVVQnLFxyXG4gICAgdXJsOiBgaHR0cHM6Ly8ke29wdGlvbnMuYnVja2V0fS4ke29wdGlvbnMuYXJlYX0uYWxpeXVuY3MuY29tLyR7ZW5jb2RlVVJJKG9wdGlvbnMucGF0aCl9JHtlbmNvZGVVUkkoZmlsZU5hbWUpfWAsXHJcbiAgICBoZWFkZXJzOiB7XHJcbiAgICAgIEhvc3Q6IGAke29wdGlvbnMuYnVja2V0fS4ke29wdGlvbnMuYXJlYX0uYWxpeXVuY3MuY29tYCxcclxuICAgICAgQXV0aG9yaXphdGlvbjogc2lnbmF0dXJlLFxyXG4gICAgICBEYXRlOiBuZXcgRGF0ZSgpLnRvVVRDU3RyaW5nKCksXHJcbiAgICAgICdDb250ZW50LVR5cGUnOiBtaW1lLmxvb2t1cChmaWxlTmFtZSlcclxuICAgIH0sXHJcbiAgICBib2R5OiBpbWFnZSxcclxuICAgIHJlc29sdmVXaXRoRnVsbFJlc3BvbnNlOiB0cnVlXHJcbiAgfVxyXG59XHJcblxyXG5jb25zdCBoYW5kbGUgPSBhc3luYyAoY3R4OiBJUGljR28pOiBQcm9taXNlPElQaWNHbz4gPT4ge1xyXG4gIGNvbnN0IGFsaVl1bk9wdGlvbnMgPSBjdHguZ2V0Q29uZmlnPElBbGl5dW5Db25maWc+KCdwaWNCZWQuYWxpeXVuJylcclxuICBpZiAoIWFsaVl1bk9wdGlvbnMpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcignQ2FuXFwndCBmaW5kIGFsaVl1biBPU1MgY29uZmlnJylcclxuICB9XHJcbiAgdHJ5IHtcclxuICAgIGNvbnN0IGltZ0xpc3QgPSBjdHgub3V0cHV0XHJcbiAgICBjb25zdCBjdXN0b21VcmwgPSBhbGlZdW5PcHRpb25zLmN1c3RvbVVybFxyXG4gICAgY29uc3QgcGF0aCA9IGFsaVl1bk9wdGlvbnMucGF0aFxyXG4gICAgZm9yIChjb25zdCBpbWcgb2YgaW1nTGlzdCkge1xyXG4gICAgICBpZiAoaW1nLmZpbGVOYW1lICYmIGltZy5idWZmZXIpIHtcclxuICAgICAgICBjb25zdCBzaWduYXR1cmUgPSBnZW5lcmF0ZVNpZ25hdHVyZShhbGlZdW5PcHRpb25zLCBpbWcuZmlsZU5hbWUpXHJcbiAgICAgICAgbGV0IGltYWdlID0gaW1nLmJ1ZmZlclxyXG4gICAgICAgIGlmICghaW1hZ2UgJiYgaW1nLmJhc2U2NEltYWdlKSB7XHJcbiAgICAgICAgICBpbWFnZSA9IEJ1ZmZlci5mcm9tKGltZy5iYXNlNjRJbWFnZSwgJ2Jhc2U2NCcpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBwb3N0T3B0aW9ucyhhbGlZdW5PcHRpb25zLCBpbWcuZmlsZU5hbWUsIHNpZ25hdHVyZSwgaW1hZ2UpXHJcbiAgICAgICAgY29uc3QgYm9keSA9IGF3YWl0IGN0eC5yZXF1ZXN0KG9wdGlvbnMpXHJcbiAgICAgICAgaWYgKGJvZHkuc3RhdHVzQ29kZSA9PT0gMjAwKSB7XHJcbiAgICAgICAgICBkZWxldGUgaW1nLmJhc2U2NEltYWdlXHJcbiAgICAgICAgICBkZWxldGUgaW1nLmJ1ZmZlclxyXG4gICAgICAgICAgY29uc3Qgb3B0aW9uVXJsID0gYWxpWXVuT3B0aW9ucy5vcHRpb25zIHx8ICcnXHJcbiAgICAgICAgICBpZiAoY3VzdG9tVXJsKSB7XHJcbiAgICAgICAgICAgIGltZy5pbWdVcmwgPSBgJHtjdXN0b21Vcmx9LyR7cGF0aH0ke2ltZy5maWxlTmFtZX0ke29wdGlvblVybH1gXHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpbWcuaW1nVXJsID0gYGh0dHBzOi8vJHthbGlZdW5PcHRpb25zLmJ1Y2tldH0uJHthbGlZdW5PcHRpb25zLmFyZWF9LmFsaXl1bmNzLmNvbS8ke3BhdGh9JHtpbWcuZmlsZU5hbWV9JHtvcHRpb25Vcmx9YFxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VwbG9hZCBmYWlsZWQnKVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGN0eFxyXG4gIH0gY2F0Y2ggKGVycikge1xyXG4gICAgY3R4LmVtaXQoSUJ1aWxkSW5FdmVudC5OT1RJRklDQVRJT04sIHtcclxuICAgICAgdGl0bGU6IGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1VQTE9BRF9GQUlMRUQnKSxcclxuICAgICAgYm9keTogY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignQ0hFQ0tfU0VUVElOR1MnKVxyXG4gICAgfSlcclxuICAgIHRocm93IGVyclxyXG4gIH1cclxufVxyXG5cclxuY29uc3QgY29uZmlnID0gKGN0eDogSVBpY0dvKTogSVBsdWdpbkNvbmZpZ1tdID0+IHtcclxuICBjb25zdCB1c2VyQ29uZmlnID0gY3R4LmdldENvbmZpZzxJQWxpeXVuQ29uZmlnPigncGljQmVkLmFsaXl1bicpIHx8IHt9XHJcbiAgY29uc3QgY29uZmlnOiBJUGx1Z2luQ29uZmlnW10gPSBbXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdhY2Nlc3NLZXlJZCcsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfQUxJQ0xPVURfQUNDRVNTS0VZSUQnKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLmFjY2Vzc0tleUlkIHx8ICcnLFxyXG4gICAgICByZXF1aXJlZDogdHJ1ZVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbmFtZTogJ2FjY2Vzc0tleVNlY3JldCcsXHJcbiAgICAgIHR5cGU6ICdwYXNzd29yZCcsXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfQUxJQ0xPVURfQUNDRVNTS0VZU0VDUkVUJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5hY2Nlc3NLZXlTZWNyZXQgfHwgJycsXHJcbiAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiAnYnVja2V0JyxcclxuICAgICAgdHlwZTogJ2lucHV0JyxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9BTElDTE9VRF9CVUNLRVQnKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLmJ1Y2tldCB8fCAnJyxcclxuICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdhcmVhJyxcclxuICAgICAgdHlwZTogJ2lucHV0JyxcclxuICAgICAgZ2V0IHByZWZpeCAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfQUxJQ0xPVURfQVJFQScpIH0sXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfQUxJQ0xPVURfQVJFQScpIH0sXHJcbiAgICAgIGRlZmF1bHQ6IHVzZXJDb25maWcuYXJlYSB8fCAnJyxcclxuICAgICAgZ2V0IG1lc3NhZ2UgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX0FMSUNMT1VEX01FU1NBR0VfQVJFQScpIH0sXHJcbiAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiAncGF0aCcsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBwcmVmaXggKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX0FMSUNMT1VEX1BBVEgnKSB9LFxyXG4gICAgICBnZXQgYWxpYXMgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX0FMSUNMT1VEX1BBVEgnKSB9LFxyXG4gICAgICBnZXQgbWVzc2FnZSAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfQUxJQ0xPVURfTUVTU0FHRV9QQVRIJykgfSxcclxuICAgICAgZGVmYXVsdDogdXNlckNvbmZpZy5wYXRoIHx8ICcnLFxyXG4gICAgICByZXF1aXJlZDogZmFsc2VcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdjdXN0b21VcmwnLFxyXG4gICAgICB0eXBlOiAnaW5wdXQnLFxyXG4gICAgICBnZXQgcHJlZml4ICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9BTElDTE9VRF9DVVNUT01VUkwnKSB9LFxyXG4gICAgICBnZXQgYWxpYXMgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX0FMSUNMT1VEX0NVU1RPTVVSTCcpIH0sXHJcbiAgICAgIGdldCBtZXNzYWdlICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9BTElDTE9VRF9NRVNTQUdFX0NVU1RPTVVSTCcpIH0sXHJcbiAgICAgIGRlZmF1bHQ6IHVzZXJDb25maWcuY3VzdG9tVXJsIHx8ICcnLFxyXG4gICAgICByZXF1aXJlZDogZmFsc2VcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdvcHRpb25zJyxcclxuICAgICAgdHlwZTogJ2lucHV0JyxcclxuICAgICAgZ2V0IHByZWZpeCAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfQUxJQ0xPVURfT1BUSU9OUycpIH0sXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfQUxJQ0xPVURfT1BUSU9OUycpIH0sXHJcbiAgICAgIGdldCBtZXNzYWdlICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9BTElDTE9VRF9NRVNTQUdFX09QVElPTlMnKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLm9wdGlvbnMgfHwgJycsXHJcbiAgICAgIHJlcXVpcmVkOiBmYWxzZVxyXG4gICAgfVxyXG4gIF1cclxuICByZXR1cm4gY29uZmlnXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlZ2lzdGVyIChjdHg6IElQaWNHbyk6IHZvaWQge1xyXG4gIGN0eC5oZWxwZXIudXBsb2FkZXIucmVnaXN0ZXIoJ2FsaXl1bicsIHtcclxuICAgIGdldCBuYW1lICgpIHtcclxuICAgICAgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9BTElDTE9VRCcpXHJcbiAgICB9LFxyXG4gICAgaGFuZGxlLFxyXG4gICAgY29uZmlnXHJcbiAgfSlcclxufVxyXG4iLCJpbXBvcnQgeyBJUGljR28sIElQbHVnaW5Db25maWcsIElVcHl1bkNvbmZpZywgSU9sZFJlcU9wdGlvbnNXaXRoRnVsbFJlc3BvbnNlIH0gZnJvbSAnLi4vLi4vdHlwZXMnXHJcbmltcG9ydCBjcnlwdG8gZnJvbSAnY3J5cHRvJ1xyXG5pbXBvcnQgTUQ1IGZyb20gJ21kNSdcclxuaW1wb3J0IHsgSUJ1aWxkSW5FdmVudCB9IGZyb20gJy4uLy4uL3V0aWxzL2VudW0nXHJcbmltcG9ydCB7IElMb2NhbGVzS2V5IH0gZnJvbSAnLi4vLi4vaTE4bi96aC1DTidcclxuaW1wb3J0IHsgc2FmZVBhcnNlIH0gZnJvbSAnLi4vLi4vdXRpbHMvY29tbW9uJ1xyXG5pbXBvcnQgbWltZSBmcm9tICdtaW1lLXR5cGVzJ1xyXG5cclxuLy8gZ2VuZXJhdGUgQ09TIHNpZ25hdHVyZSBzdHJpbmdcclxuY29uc3QgZ2VuZXJhdGVTaWduYXR1cmUgPSAob3B0aW9uczogSVVweXVuQ29uZmlnLCBmaWxlTmFtZTogc3RyaW5nKTogc3RyaW5nID0+IHtcclxuICBjb25zdCBwYXRoID0gb3B0aW9ucy5wYXRoIHx8ICcnXHJcbiAgY29uc3Qgb3BlcmF0b3IgPSBvcHRpb25zLm9wZXJhdG9yXHJcbiAgY29uc3QgcGFzc3dvcmQgPSBvcHRpb25zLnBhc3N3b3JkXHJcbiAgY29uc3QgbWQ1UGFzc3dvcmQgPSBNRDUocGFzc3dvcmQpXHJcbiAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCkudG9VVENTdHJpbmcoKVxyXG4gIGNvbnN0IHVyaSA9IGAvJHtvcHRpb25zLmJ1Y2tldH0vJHtlbmNvZGVVUkkocGF0aCl9JHtlbmNvZGVVUkkoZmlsZU5hbWUpfWBcclxuICBjb25zdCB2YWx1ZSA9IGBQVVQmJHt1cml9JiR7ZGF0ZX1gXHJcbiAgY29uc3Qgc2lnbiA9IGNyeXB0by5jcmVhdGVIbWFjKCdzaGExJywgbWQ1UGFzc3dvcmQpLnVwZGF0ZSh2YWx1ZSkuZGlnZXN0KCdiYXNlNjQnKVxyXG4gIHJldHVybiBgVVBZVU4gJHtvcGVyYXRvcn06JHtzaWdufWBcclxufVxyXG5cclxuY29uc3QgcG9zdE9wdGlvbnMgPSAob3B0aW9uczogSVVweXVuQ29uZmlnLCBmaWxlTmFtZTogc3RyaW5nLCBzaWduYXR1cmU6IHN0cmluZywgaW1hZ2U6IEJ1ZmZlcik6IElPbGRSZXFPcHRpb25zV2l0aEZ1bGxSZXNwb25zZSA9PiB7XHJcbiAgY29uc3QgYnVja2V0ID0gb3B0aW9ucy5idWNrZXRcclxuICBjb25zdCBwYXRoID0gb3B0aW9ucy5wYXRoIHx8ICcnXHJcbiAgcmV0dXJuIHtcclxuICAgIG1ldGhvZDogJ1BVVCcsXHJcbiAgICB1cmw6IGBodHRwczovL3YwLmFwaS51cHl1bi5jb20vJHtidWNrZXR9LyR7ZW5jb2RlVVJJKHBhdGgpfSR7ZW5jb2RlVVJJKGZpbGVOYW1lKX1gLFxyXG4gICAgaGVhZGVyczoge1xyXG4gICAgICBBdXRob3JpemF0aW9uOiBzaWduYXR1cmUsXHJcbiAgICAgIERhdGU6IG5ldyBEYXRlKCkudG9VVENTdHJpbmcoKSxcclxuICAgICAgJ0NvbnRlbnQtVHlwZSc6IG1pbWUubG9va3VwKGZpbGVOYW1lKSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJ1xyXG4gICAgfSxcclxuICAgIGJvZHk6IGltYWdlLFxyXG4gICAgcmVzb2x2ZVdpdGhGdWxsUmVzcG9uc2U6IHRydWVcclxuICB9XHJcbn1cclxuXHJcbmNvbnN0IGhhbmRsZSA9IGFzeW5jIChjdHg6IElQaWNHbyk6IFByb21pc2U8SVBpY0dvPiA9PiB7XHJcbiAgY29uc3QgdXB5dW5PcHRpb25zID0gY3R4LmdldENvbmZpZzxJVXB5dW5Db25maWc+KCdwaWNCZWQudXB5dW4nKVxyXG4gIGlmICghdXB5dW5PcHRpb25zKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcJ3QgZmluZCB1cFl1biBjb25maWcnKVxyXG4gIH1cclxuICB0cnkge1xyXG4gICAgY29uc3QgaW1nTGlzdCA9IGN0eC5vdXRwdXRcclxuICAgIGNvbnN0IHBhdGggPSB1cHl1bk9wdGlvbnMucGF0aCB8fCAnJ1xyXG4gICAgZm9yIChjb25zdCBpbWcgb2YgaW1nTGlzdCkge1xyXG4gICAgICBpZiAoaW1nLmZpbGVOYW1lICYmIGltZy5idWZmZXIpIHtcclxuICAgICAgICBsZXQgaW1hZ2UgPSBpbWcuYnVmZmVyXHJcbiAgICAgICAgaWYgKCFpbWFnZSAmJiBpbWcuYmFzZTY0SW1hZ2UpIHtcclxuICAgICAgICAgIGltYWdlID0gQnVmZmVyLmZyb20oaW1nLmJhc2U2NEltYWdlLCAnYmFzZTY0JylcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlID0gZ2VuZXJhdGVTaWduYXR1cmUodXB5dW5PcHRpb25zLCBpbWcuZmlsZU5hbWUpXHJcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHBvc3RPcHRpb25zKHVweXVuT3B0aW9ucywgaW1nLmZpbGVOYW1lLCBzaWduYXR1cmUsIGltYWdlKVxyXG4gICAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCBjdHgucmVxdWVzdChvcHRpb25zKVxyXG4gICAgICAgIGlmIChib2R5LnN0YXR1c0NvZGUgPT09IDIwMCkge1xyXG4gICAgICAgICAgZGVsZXRlIGltZy5iYXNlNjRJbWFnZVxyXG4gICAgICAgICAgZGVsZXRlIGltZy5idWZmZXJcclxuICAgICAgICAgIGltZy5pbWdVcmwgPSBgJHt1cHl1bk9wdGlvbnMudXJsfS8ke3BhdGh9JHtpbWcuZmlsZU5hbWV9JHt1cHl1bk9wdGlvbnMub3B0aW9uc31gXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVXBsb2FkIGZhaWxlZCcpXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY3R4XHJcbiAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcclxuICAgIGlmIChlcnIubWVzc2FnZSA9PT0gJ1VwbG9hZCBmYWlsZWQnKSB7XHJcbiAgICAgIGN0eC5lbWl0KElCdWlsZEluRXZlbnQuTk9USUZJQ0FUSU9OLCB7XHJcbiAgICAgICAgdGl0bGU6IGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1VQTE9BRF9GQUlMRUQnKSxcclxuICAgICAgICBib2R5OiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdDSEVDS19TRVRUSU5HUycpXHJcbiAgICAgIH0pXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBib2R5ID0gc2FmZVBhcnNlPHsgY29kZTogc3RyaW5nIH0+KGVyci5lcnJvcilcclxuICAgICAgY3R4LmVtaXQoSUJ1aWxkSW5FdmVudC5OT1RJRklDQVRJT04sIHtcclxuICAgICAgICB0aXRsZTogY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignVVBMT0FEX0ZBSUxFRCcpLFxyXG4gICAgICAgIGJvZHk6IGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1VQTE9BRF9GQUlMRURfUkVBU09OJywge1xyXG4gICAgICAgICAgY29kZTogdHlwZW9mIGJvZHkgPT09ICdvYmplY3QnID8gYm9keS5jb2RlIDogYm9keVxyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIHRleHQ6ICdodHRwOi8vZG9jcy51cHl1bi5jb20vYXBpL2Vycm5vLydcclxuICAgICAgfSlcclxuICAgIH1cclxuICAgIHRocm93IGVyclxyXG4gIH1cclxufVxyXG5cclxuY29uc3QgY29uZmlnID0gKGN0eDogSVBpY0dvKTogSVBsdWdpbkNvbmZpZ1tdID0+IHtcclxuICBjb25zdCB1c2VyQ29uZmlnID0gY3R4LmdldENvbmZpZzxJVXB5dW5Db25maWc+KCdwaWNCZWQudXB5dW4nKSB8fCB7fVxyXG4gIGNvbnN0IGNvbmZpZzogSVBsdWdpbkNvbmZpZ1tdID0gW1xyXG4gICAge1xyXG4gICAgICBuYW1lOiAnYnVja2V0JyxcclxuICAgICAgdHlwZTogJ2lucHV0JyxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9VUFlVTl9CVUNLRVQnKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLmJ1Y2tldCB8fCAnJyxcclxuICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdvcGVyYXRvcicsXHJcbiAgICAgIHR5cGU6ICdpbnB1dCcsXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVVBZVU5fT1BFUkFUT1InKSB9LFxyXG4gICAgICBnZXQgcHJlZml4ICgpIHtcclxuICAgICAgICByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1VQWVVOX09QRVJBVE9SJylcclxuICAgICAgfSxcclxuICAgICAgZ2V0IG1lc3NhZ2UgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1VQWVVOX01FU1NBR0VfT1BFUkFUT1InKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLm9wZXJhdG9yIHx8ICcnLFxyXG4gICAgICByZXF1aXJlZDogdHJ1ZVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbmFtZTogJ3Bhc3N3b3JkJyxcclxuICAgICAgdHlwZTogJ3Bhc3N3b3JkJyxcclxuICAgICAgZ2V0IHByZWZpeCAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVVBZVU5fTUVTU0FHRV9QQVNTV09SRCcpIH0sXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVVBZVU5fUEFTU1dPUkQnKSB9LFxyXG4gICAgICBnZXQgbWVzc2FnZSAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVVBZVU5fTUVTU0FHRV9QQVNTV09SRCcpIH0sXHJcbiAgICAgIGRlZmF1bHQ6IHVzZXJDb25maWcucGFzc3dvcmQgfHwgJycsXHJcbiAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiAndXJsJyxcclxuICAgICAgdHlwZTogJ2lucHV0JyxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9VUFlVTl9VUkwnKSB9LFxyXG4gICAgICBnZXQgbWVzc2FnZSAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVVBZVU5fTUVTU0FHRV9VUkwnKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLnVybCB8fCAnJyxcclxuICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6ICdvcHRpb25zJyxcclxuICAgICAgdHlwZTogJ2lucHV0JyxcclxuICAgICAgZ2V0IHByZWZpeCAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVVBZVU5fT1BUSU9OUycpIH0sXHJcbiAgICAgIGdldCBhbGlhcyAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVVBZVU5fT1BUSU9OUycpIH0sXHJcbiAgICAgIGdldCBtZXNzYWdlICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9VUFlVTl9NRVNTQUdFX09QVElPTlMnKSB9LFxyXG4gICAgICBkZWZhdWx0OiB1c2VyQ29uZmlnLm9wdGlvbnMgfHwgJycsXHJcbiAgICAgIHJlcXVpcmVkOiBmYWxzZVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbmFtZTogJ3BhdGgnLFxyXG4gICAgICB0eXBlOiAnaW5wdXQnLFxyXG4gICAgICBnZXQgcHJlZml4ICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9VUFlVTl9QQVRIJykgfSxcclxuICAgICAgZ2V0IGFsaWFzICgpIHsgcmV0dXJuIGN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BJQ0JFRF9VUFlVTl9QQVRIJykgfSxcclxuICAgICAgZ2V0IG1lc3NhZ2UgKCkgeyByZXR1cm4gY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUElDQkVEX1VQWVVOX01FU1NBR0VfUEFUSCcpIH0sXHJcbiAgICAgIGRlZmF1bHQ6IHVzZXJDb25maWcucGF0aCB8fCAnJyxcclxuICAgICAgcmVxdWlyZWQ6IGZhbHNlXHJcbiAgICB9XHJcbiAgXVxyXG4gIHJldHVybiBjb25maWdcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmVnaXN0ZXIgKGN0eDogSVBpY0dvKTogdm9pZCB7XHJcbiAgY3R4LmhlbHBlci51cGxvYWRlci5yZWdpc3RlcigndXB5dW4nLCB7XHJcbiAgICBnZXQgbmFtZSAoKSB7IHJldHVybiBjdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQSUNCRURfVVBZVU4nKSB9LFxyXG4gICAgaGFuZGxlLFxyXG4gICAgY29uZmlnXHJcbiAgfSlcclxufVxyXG4iLCJpbXBvcnQgeyBJUGljR28sIElQaWNHb1BsdWdpbiB9IGZyb20gJy4uLy4uL3R5cGVzJ1xyXG5pbXBvcnQgU01NU1VwbG9hZGVyIGZyb20gJy4vc21tcydcclxuaW1wb3J0IHRjWXVuVXBsb2FkZXIgZnJvbSAnLi90Y3l1bidcclxuaW1wb3J0IGdpdGh1YlVwbG9hZGVyIGZyb20gJy4vZ2l0aHViJ1xyXG5pbXBvcnQgcWluaXVVcGxvYWRlciBmcm9tICcuL3Fpbml1J1xyXG5pbXBvcnQgaW1ndXJVcGxvYWRlciBmcm9tICcuL2ltZ3VyJ1xyXG5pbXBvcnQgYWxpWXVuVXBsb2FkZXIgZnJvbSAnLi9hbGl5dW4nXHJcbmltcG9ydCB1cFl1blVwbG9hZGVyIGZyb20gJy4vdXB5dW4nXHJcblxyXG5jb25zdCBidWlsZEluVXBsb2FkZXJzOiBJUGljR29QbHVnaW4gPSAoKSA9PiB7XHJcbiAgcmV0dXJuIHtcclxuICAgIHJlZ2lzdGVyIChjdHg6IElQaWNHbykge1xyXG4gICAgICBhbGlZdW5VcGxvYWRlcihjdHgpXHJcbiAgICAgIHRjWXVuVXBsb2FkZXIoY3R4KVxyXG4gICAgICBTTU1TVXBsb2FkZXIoY3R4KVxyXG4gICAgICBnaXRodWJVcGxvYWRlcihjdHgpXHJcbiAgICAgIHFpbml1VXBsb2FkZXIoY3R4KVxyXG4gICAgICBpbWd1clVwbG9hZGVyKGN0eClcclxuICAgICAgdXBZdW5VcGxvYWRlcihjdHgpXHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBidWlsZEluVXBsb2FkZXJzXHJcbiIsImltcG9ydCB7XHJcbiAgaXNVcmwsXHJcbiAgZ2V0SW1hZ2VTaXplLFxyXG4gIGdldEZTRmlsZSxcclxuICBnZXRVUkxGaWxlXHJcbn0gZnJvbSAnLi4vLi4vdXRpbHMvY29tbW9uJ1xyXG5pbXBvcnQgeyBJUGljR28sIElQYXRoVHJhbnNmb3JtZWRJbWdJbmZvLCBJSW1nSW5mbywgSUltZ1NpemUgfSBmcm9tICcuLi8uLi90eXBlcydcclxuXHJcbmNvbnN0IGhhbmRsZSA9IGFzeW5jIChjdHg6IElQaWNHbyk6IFByb21pc2U8SVBpY0dvPiA9PiB7XHJcbiAgY29uc3QgcmVzdWx0czogSUltZ0luZm9bXSA9IGN0eC5vdXRwdXRcclxuICBhd2FpdCBQcm9taXNlLmFsbChjdHguaW5wdXQubWFwKGFzeW5jIChpdGVtOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcclxuICAgIGxldCBpbmZvOiBJUGF0aFRyYW5zZm9ybWVkSW1nSW5mb1xyXG4gICAgaWYgKGlzVXJsKGl0ZW0pKSB7XHJcbiAgICAgIGluZm8gPSBhd2FpdCBnZXRVUkxGaWxlKGl0ZW0sIGN0eClcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGluZm8gPSBhd2FpdCBnZXRGU0ZpbGUoaXRlbSlcclxuICAgIH1cclxuICAgIGlmIChpbmZvLnN1Y2Nlc3MgJiYgaW5mby5idWZmZXIpIHtcclxuICAgICAgY29uc3QgaW1nU2l6ZSA9IGdldEltZ1NpemUoY3R4LCBpbmZvLmJ1ZmZlciwgaXRlbSlcclxuICAgICAgcmVzdWx0c1tpbmRleF0gPSB7XHJcbiAgICAgICAgYnVmZmVyOiBpbmZvLmJ1ZmZlcixcclxuICAgICAgICBmaWxlTmFtZTogaW5mby5maWxlTmFtZSxcclxuICAgICAgICB3aWR0aDogaW1nU2l6ZS53aWR0aCxcclxuICAgICAgICBoZWlnaHQ6IGltZ1NpemUuaGVpZ2h0LFxyXG4gICAgICAgIGV4dG5hbWU6IGluZm8uZXh0bmFtZVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoaW5mby5yZWFzb24pXHJcbiAgICB9XHJcbiAgfSkpXHJcbiAgLy8gcmVtb3ZlIGVtcHR5IGl0ZW1cclxuICBjdHgub3V0cHV0ID0gcmVzdWx0cy5maWx0ZXIoaXRlbSA9PiBpdGVtKVxyXG4gIHJldHVybiBjdHhcclxufVxyXG5cclxuY29uc3QgZ2V0SW1nU2l6ZSA9IChjdHg6IElQaWNHbywgZmlsZTogQnVmZmVyLCBwYXRoOiBzdHJpbmcpOiBJSW1nU2l6ZSA9PiB7XHJcbiAgY29uc3QgaW1hZ2VTaXplID0gZ2V0SW1hZ2VTaXplKGZpbGUpXHJcbiAgaWYgKCFpbWFnZVNpemUucmVhbCkge1xyXG4gICAgY3R4LmxvZy53YXJuKGBjYW4ndCBnZXQgJHtwYXRofSdzIGltYWdlIHNpemVgKVxyXG4gICAgY3R4LmxvZy53YXJuKCdmYWxsYmFjayB0byAyMDAgKiAyMDAnKVxyXG4gIH1cclxuICByZXR1cm4gaW1hZ2VTaXplXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICBoYW5kbGVcclxufVxyXG4iLCJpbXBvcnQgeyBJUGljR28gfSBmcm9tICcuLi8uLi90eXBlcydcclxuY29uc3QgaGFuZGxlID0gYXN5bmMgKGN0eDogSVBpY0dvKTogUHJvbWlzZTxJUGljR28+ID0+IHtcclxuICBjdHgub3V0cHV0LnB1c2goLi4uY3R4LmlucHV0KVxyXG4gIHJldHVybiBjdHhcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gIGhhbmRsZVxyXG59XHJcbiIsImltcG9ydCB7IElQaWNHbywgSVBpY0dvUGx1Z2luIH0gZnJvbSAnLi4vLi4vdHlwZXMnXHJcbmltcG9ydCBJbWdGcm9tUGF0aCBmcm9tICcuL3BhdGgnXHJcbmltcG9ydCBJbWdGcm9tQmFzZTY0IGZyb20gJy4vYmFzZTY0J1xyXG5cclxuY29uc3QgYnVpbGRJblRyYW5zZm9ybWVyczogSVBpY0dvUGx1Z2luID0gKCkgPT4ge1xyXG4gIHJldHVybiB7XHJcbiAgICByZWdpc3RlciAoY3R4OiBJUGljR28pIHtcclxuICAgICAgY3R4LmhlbHBlci50cmFuc2Zvcm1lci5yZWdpc3RlcigncGF0aCcsIEltZ0Zyb21QYXRoKVxyXG4gICAgICBjdHguaGVscGVyLnRyYW5zZm9ybWVyLnJlZ2lzdGVyKCdiYXNlNjQnLCBJbWdGcm9tQmFzZTY0KVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgYnVpbGRJblRyYW5zZm9ybWVyc1xyXG4iLCJpbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnXHJcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXHJcbmltcG9ydCByZXNvbHZlIGZyb20gJ3Jlc29sdmUnXHJcbmltcG9ydCB7IElCdWlsZEluRXZlbnQgfSBmcm9tICcuLi91dGlscy9lbnVtJ1xyXG5pbXBvcnQgeyBJUGljR28sIElQaWNHb1BsdWdpbiwgSVBsdWdpbkxvYWRlciwgSVBpY0dvUGx1Z2luSW50ZXJmYWNlIH0gZnJvbSAnLi4vdHlwZXMvaW5kZXgnXHJcbmltcG9ydCB7IHNldEN1cnJlbnRQbHVnaW5OYW1lIH0gZnJvbSAnLi9MaWZlY3ljbGVQbHVnaW5zJ1xyXG5cclxuLyoqXHJcbiAqIExvY2FsIHBsdWdpbiBsb2FkZXIsIGZpbGUgc3lzdGVtIGlzIHJlcXVpcmVkXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgUGx1Z2luTG9hZGVyIGltcGxlbWVudHMgSVBsdWdpbkxvYWRlciB7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBjdHg6IElQaWNHb1xyXG4gIHByaXZhdGUgbGlzdDogc3RyaW5nW10gPSBbXVxyXG4gIHByaXZhdGUgcmVhZG9ubHkgZnVsbExpc3Q6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpXHJcbiAgcHJpdmF0ZSByZWFkb25seSBwbHVnaW5NYXA6IE1hcDxzdHJpbmcsIElQaWNHb1BsdWdpbkludGVyZmFjZT4gPSBuZXcgTWFwKClcclxuICBjb25zdHJ1Y3RvciAoY3R4OiBJUGljR28pIHtcclxuICAgIHRoaXMuY3R4ID0gY3R4XHJcbiAgICB0aGlzLmluaXQoKVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbml0ICgpOiB2b2lkIHtcclxuICAgIGNvbnN0IHBhY2thZ2VQYXRoID0gcGF0aC5qb2luKHRoaXMuY3R4LmJhc2VEaXIsICdwYWNrYWdlLmpzb24nKVxyXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHBhY2thZ2VQYXRoKSkge1xyXG4gICAgICBjb25zdCBwa2cgPSB7XHJcbiAgICAgICAgbmFtZTogJ3BpY2dvLXBsdWdpbnMnLFxyXG4gICAgICAgIGRlc2NyaXB0aW9uOiAncGljZ28tcGx1Z2lucycsXHJcbiAgICAgICAgcmVwb3NpdG9yeTogJ2h0dHBzOi8vZ2l0aHViLmNvbS9QaWNHby9QaWNHby1Db3JlJyxcclxuICAgICAgICBsaWNlbnNlOiAnTUlUJ1xyXG4gICAgICB9XHJcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMocGFja2FnZVBhdGgsIEpTT04uc3RyaW5naWZ5KHBrZyksICd1dGY4JylcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIGdldCBwbHVnaW4gZW50cnlcclxuICBwcml2YXRlIHJlc29sdmVQbHVnaW4gKGN0eDogSVBpY0dvLCBuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgdHJ5IHtcclxuICAgICAgcmV0dXJuIHJlc29sdmUuc3luYyhuYW1lLCB7IGJhc2VkaXI6IGN0eC5iYXNlRGlyIH0pXHJcbiAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgcmV0dXJuIHBhdGguam9pbihjdHguYmFzZURpciwgJ25vZGVfbW9kdWxlcycsIG5hbWUpXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBsb2FkIGFsbCB0aGlyZCBwYXJ0eSBwbHVnaW5cclxuICBsb2FkICgpOiBib29sZWFuIHtcclxuICAgIGNvbnN0IHBhY2thZ2VQYXRoID0gcGF0aC5qb2luKHRoaXMuY3R4LmJhc2VEaXIsICdwYWNrYWdlLmpzb24nKVxyXG4gICAgY29uc3QgcGx1Z2luRGlyID0gcGF0aC5qb2luKHRoaXMuY3R4LmJhc2VEaXIsICdub2RlX21vZHVsZXMvJylcclxuICAgIC8vIFRoYW5rcyB0byBoZXhvIC0+IGh0dHBzOi8vZ2l0aHViLmNvbS9oZXhvanMvaGV4by9ibG9iL21hc3Rlci9saWIvaGV4by9sb2FkX3BsdWdpbnMuanNcclxuICAgIGlmICghZnMuZXhpc3RzU3luYyhwbHVnaW5EaXIpKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG4gICAgY29uc3QganNvbiA9IGZzLnJlYWRKU09OU3luYyhwYWNrYWdlUGF0aClcclxuICAgIGNvbnN0IGRlcHMgPSBPYmplY3Qua2V5cyhqc29uLmRlcGVuZGVuY2llcyB8fCB7fSlcclxuICAgIGNvbnN0IGRldkRlcHMgPSBPYmplY3Qua2V5cyhqc29uLmRldkRlcGVuZGVuY2llcyB8fCB7fSlcclxuICAgIGNvbnN0IG1vZHVsZXMgPSBkZXBzLmNvbmNhdChkZXZEZXBzKS5maWx0ZXIoKG5hbWU6IHN0cmluZykgPT4ge1xyXG4gICAgICBpZiAoIS9ecGljZ28tcGx1Z2luLXxeQFteL10rXFwvcGljZ28tcGx1Z2luLS8udGVzdChuYW1lKSkgcmV0dXJuIGZhbHNlXHJcbiAgICAgIGNvbnN0IHBhdGggPSB0aGlzLnJlc29sdmVQbHVnaW4odGhpcy5jdHgsIG5hbWUpXHJcbiAgICAgIHJldHVybiBmcy5leGlzdHNTeW5jKHBhdGgpXHJcbiAgICB9KVxyXG4gICAgZm9yIChjb25zdCBtb2R1bGUgb2YgbW9kdWxlcykge1xyXG4gICAgICB0aGlzLnJlZ2lzdGVyUGx1Z2luKG1vZHVsZSlcclxuICAgIH1cclxuICAgIHJldHVybiB0cnVlXHJcbiAgfVxyXG5cclxuICByZWdpc3RlclBsdWdpbiAobmFtZTogc3RyaW5nLCBwbHVnaW4/OiBJUGljR29QbHVnaW4pOiB2b2lkIHtcclxuICAgIGlmICghbmFtZSB8fCB0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgdGhpcy5jdHgubG9nLndhcm4oJ1BsZWFzZSBwcm92aWRlIHZhbGlkIHBsdWdpbicpXHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG4gICAgdGhpcy5mdWxsTGlzdC5hZGQobmFtZSlcclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIHJlZ2lzdGVyIGxvY2FsIHBsdWdpblxyXG4gICAgICBpZiAoIXBsdWdpbikge1xyXG4gICAgICAgIGlmICh0aGlzLmN0eC5nZXRDb25maWcoYHBpY2dvUGx1Z2lucy4ke25hbWV9YCkgPT09IHRydWUgfHwgKHRoaXMuY3R4LmdldENvbmZpZyhgcGljZ29QbHVnaW5zLiR7bmFtZX1gKSA9PT0gdW5kZWZpbmVkKSkge1xyXG4gICAgICAgICAgdGhpcy5saXN0LnB1c2gobmFtZSlcclxuICAgICAgICAgIHNldEN1cnJlbnRQbHVnaW5OYW1lKG5hbWUpXHJcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxyXG4gICAgICAgICAgdGhpcy5nZXRQbHVnaW4obmFtZSkhLnJlZ2lzdGVyKHRoaXMuY3R4KVxyXG4gICAgICAgICAgY29uc3QgcGx1Z2luID0gYHBpY2dvUGx1Z2luc1ske25hbWV9XWBcclxuICAgICAgICAgIHRoaXMuY3R4LnNhdmVDb25maWcoXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICBbcGx1Z2luXTogdHJ1ZVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICApXHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIHJlZ2lzdGVyIHByb3ZpZGVkIHBsdWdpblxyXG4gICAgICAgIC8vICYmIHdvbid0IHdyaXRlIGNvbmZpZyB0byBmaWxlc1xyXG4gICAgICAgIHRoaXMubGlzdC5wdXNoKG5hbWUpXHJcbiAgICAgICAgc2V0Q3VycmVudFBsdWdpbk5hbWUobmFtZSlcclxuICAgICAgICBjb25zdCBwbHVnaW5JbnRlcmZhY2UgPSBwbHVnaW4odGhpcy5jdHgpXHJcbiAgICAgICAgdGhpcy5wbHVnaW5NYXAuc2V0KG5hbWUsIHBsdWdpbkludGVyZmFjZSlcclxuICAgICAgICBwbHVnaW5JbnRlcmZhY2UucmVnaXN0ZXIodGhpcy5jdHgpXHJcbiAgICAgIH1cclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgdGhpcy5wbHVnaW5NYXAuZGVsZXRlKG5hbWUpXHJcbiAgICAgIHRoaXMubGlzdCA9IHRoaXMubGlzdC5maWx0ZXIoKGl0ZW06IHN0cmluZykgPT4gaXRlbSAhPT0gbmFtZSlcclxuICAgICAgdGhpcy5mdWxsTGlzdC5kZWxldGUobmFtZSlcclxuICAgICAgdGhpcy5jdHgubG9nLmVycm9yKGUgYXMgRXJyb3IpXHJcbiAgICAgIHRoaXMuY3R4LmVtaXQoSUJ1aWxkSW5FdmVudC5OT1RJRklDQVRJT04sIHtcclxuICAgICAgICB0aXRsZTogYFBsdWdpbiAke25hbWV9IExvYWQgRXJyb3JgLFxyXG4gICAgICAgIGJvZHk6IGVcclxuICAgICAgfSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHVucmVnaXN0ZXJQbHVnaW4gKG5hbWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy5saXN0ID0gdGhpcy5saXN0LmZpbHRlcigoaXRlbTogc3RyaW5nKSA9PiBpdGVtICE9PSBuYW1lKVxyXG4gICAgdGhpcy5mdWxsTGlzdC5kZWxldGUobmFtZSlcclxuICAgIHRoaXMucGx1Z2luTWFwLmRlbGV0ZShuYW1lKVxyXG4gICAgc2V0Q3VycmVudFBsdWdpbk5hbWUobmFtZSlcclxuICAgIHRoaXMuY3R4LmhlbHBlci51cGxvYWRlci51bnJlZ2lzdGVyKG5hbWUpXHJcbiAgICB0aGlzLmN0eC5oZWxwZXIudHJhbnNmb3JtZXIudW5yZWdpc3RlcihuYW1lKVxyXG4gICAgdGhpcy5jdHguaGVscGVyLmJlZm9yZVRyYW5zZm9ybVBsdWdpbnMudW5yZWdpc3RlcihuYW1lKVxyXG4gICAgdGhpcy5jdHguaGVscGVyLmJlZm9yZVVwbG9hZFBsdWdpbnMudW5yZWdpc3RlcihuYW1lKVxyXG4gICAgdGhpcy5jdHguaGVscGVyLmFmdGVyVXBsb2FkUGx1Z2lucy51bnJlZ2lzdGVyKG5hbWUpXHJcbiAgICB0aGlzLmN0eC5jbWQudW5yZWdpc3RlcihuYW1lKVxyXG4gICAgdGhpcy5jdHgucmVtb3ZlQ29uZmlnKCdwaWNnb1BsdWdpbnMnLCBuYW1lKVxyXG4gIH1cclxuXHJcbiAgLy8gZ2V0IHBsdWdpbiBieSBuYW1lXHJcbiAgZ2V0UGx1Z2luIChuYW1lOiBzdHJpbmcpOiBJUGljR29QbHVnaW5JbnRlcmZhY2UgfCB1bmRlZmluZWQge1xyXG4gICAgaWYgKHRoaXMucGx1Z2luTWFwLmhhcyhuYW1lKSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5wbHVnaW5NYXAuZ2V0KG5hbWUpXHJcbiAgICB9XHJcbiAgICBjb25zdCBwbHVnaW5EaXIgPSBwYXRoLmpvaW4odGhpcy5jdHguYmFzZURpciwgJ25vZGVfbW9kdWxlcy8nKVxyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXNcclxuICAgIGNvbnN0IHBsdWdpbiA9IHJlcXVpcmUocGx1Z2luRGlyICsgbmFtZSkodGhpcy5jdHgpXHJcbiAgICB0aGlzLnBsdWdpbk1hcC5zZXQobmFtZSwgcGx1Z2luKVxyXG4gICAgcmV0dXJuIHBsdWdpblxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBsaXN0IG9mIGVuYWJsZWQgcGx1Z2luc1xyXG4gICAqL1xyXG4gIGdldExpc3QgKCk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiB0aGlzLmxpc3RcclxuICB9XHJcblxyXG4gIGhhc1BsdWdpbiAobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5mdWxsTGlzdC5oYXMobmFtZSlcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0aGUgZnVsbCBsaXN0IG9mIHBsdWdpbnMsIHdoZXRoZXIgaXQgaXMgZW5hYmxlZCBvciBub3RcclxuICAgKi9cclxuICBnZXRGdWxsTGlzdCAoKTogc3RyaW5nW10ge1xyXG4gICAgcmV0dXJuIFsuLi50aGlzLmZ1bGxMaXN0XVxyXG4gIH1cclxufVxyXG5leHBvcnQgZGVmYXVsdCBQbHVnaW5Mb2FkZXJcclxuIiwiZXhwb3J0IGNvbnN0IENMSVBCT0FSRF9JTUFHRV9GT0xERVIgPSAncGljZ28tY2xpcGJvYXJkLWltYWdlcydcclxuIiwiaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcclxuaW1wb3J0IHsgc3Bhd24gfSBmcm9tICdjaGlsZF9wcm9jZXNzJ1xyXG5pbXBvcnQgZGF5anMgZnJvbSAnZGF5anMnXHJcbmltcG9ydCBvcyBmcm9tICdvcydcclxuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJ1xyXG5pbXBvcnQgaXNXc2wgZnJvbSAnaXMtd3NsJ1xyXG5pbXBvcnQgeyBJUGljR28sIElDbGlwYm9hcmRJbWFnZSB9IGZyb20gJy4uL3R5cGVzJ1xyXG5pbXBvcnQgeyBJQnVpbGRJbkV2ZW50IH0gZnJvbSAnLi9lbnVtJ1xyXG5pbXBvcnQgbWFjQ2xpcGJvYXJkU2NyaXB0IGZyb20gJy4vY2xpcGJvYXJkL21hYy5hcHBsZXNjcmlwdCdcclxuaW1wb3J0IHdpbmRvd3NDbGlwYm9hcmRTY3JpcHQgZnJvbSAnLi9jbGlwYm9hcmQvd2luZG93cy5wczEnXHJcbmltcG9ydCB3aW5kb3dzMTBDbGlwYm9hcmRTY3JpcHQgZnJvbSAnLi9jbGlwYm9hcmQvd2luZG93czEwLnBzMSdcclxuaW1wb3J0IGxpbnV4Q2xpcGJvYXJkU2NyaXB0IGZyb20gJy4vY2xpcGJvYXJkL2xpbnV4LnNoJ1xyXG5pbXBvcnQgd3NsQ2xpcGJvYXJkU2NyaXB0IGZyb20gJy4vY2xpcGJvYXJkL3dzbC5zaCdcclxuaW1wb3J0IHsgQ0xJUEJPQVJEX0lNQUdFX0ZPTERFUiB9IGZyb20gJy4vc3RhdGljJ1xyXG5cclxuZXhwb3J0IHR5cGUgUGxhdGZvcm0gPSAnZGFyd2luJyB8ICd3aW4zMicgfCAnd2luMTAnIHwgJ2xpbnV4JyB8ICd3c2wnXHJcblxyXG5jb25zdCBnZXRDdXJyZW50UGxhdGZvcm0gPSAoKTogUGxhdGZvcm0gPT4ge1xyXG4gIGNvbnN0IHBsYXRmb3JtID0gcHJvY2Vzcy5wbGF0Zm9ybVxyXG4gIGlmIChpc1dzbCkge1xyXG4gICAgcmV0dXJuICd3c2wnXHJcbiAgfVxyXG4gIGlmIChwbGF0Zm9ybSA9PT0gJ3dpbjMyJykge1xyXG4gICAgY29uc3QgY3VycmVudE9TID0gb3MucmVsZWFzZSgpLnNwbGl0KCcuJylbMF1cclxuICAgIGlmIChjdXJyZW50T1MgPT09ICcxMCcpIHtcclxuICAgICAgcmV0dXJuICd3aW4xMCdcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiAnd2luMzInXHJcbiAgICB9XHJcbiAgfSBlbHNlIGlmIChwbGF0Zm9ybSA9PT0gJ2RhcndpbicpIHtcclxuICAgIHJldHVybiAnZGFyd2luJ1xyXG4gIH0gZWxzZSB7XHJcbiAgICByZXR1cm4gJ2xpbnV4J1xyXG4gIH1cclxufVxyXG5cclxuY29uc3QgcGxhdGZvcm0yU2NyaXB0Q29udGVudDoge1xyXG4gIFtrZXkgaW4gUGxhdGZvcm1dOiBzdHJpbmdcclxufSA9IHtcclxuICBkYXJ3aW46IG1hY0NsaXBib2FyZFNjcmlwdCxcclxuICB3aW4zMjogd2luZG93c0NsaXBib2FyZFNjcmlwdCxcclxuICB3aW4xMDogd2luZG93czEwQ2xpcGJvYXJkU2NyaXB0LFxyXG4gIGxpbnV4OiBsaW51eENsaXBib2FyZFNjcmlwdCxcclxuICB3c2w6IHdzbENsaXBib2FyZFNjcmlwdFxyXG59XHJcbi8qKlxyXG4gKiBwb3dlcnNoZWxsIHdpbGwgcmVwb3J0IGVycm9yIGlmIGZpbGUgZG9lcyBub3QgaGF2ZSBhICcucHMxJyBleHRlbnNpb24sXHJcbiAqIHNvIHdlIHNob3VsZCBrZWVwIHRoZSBleHRlbnNpb24gbmFtZSBjb25zaXN0ZW50IHdpdGggY29ycmVzcG9uZGluZyBzaGVsbFxyXG4gKi9cclxuY29uc3QgcGxhdGZvcm0yU2NyaXB0RmlsZW5hbWU6IHtcclxuICBba2V5IGluIFBsYXRmb3JtXTogc3RyaW5nXHJcbn0gPSB7XHJcbiAgZGFyd2luOiAnbWFjLmFwcGxlc2NyaXB0JyxcclxuICB3aW4zMjogJ3dpbmRvd3MucHMxJyxcclxuICB3aW4xMDogJ3dpbmRvd3MxMC5wczEnLFxyXG4gIGxpbnV4OiAnbGludXguc2gnLFxyXG4gIHdzbDogJ3dzbC5zaCdcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlSW1hZ2VGb2xkZXIgKGN0eDogSVBpY0dvKTogdm9pZCB7XHJcbiAgY29uc3QgaW1hZ2VQYXRoID0gcGF0aC5qb2luKGN0eC5iYXNlRGlyLCBDTElQQk9BUkRfSU1BR0VfRk9MREVSKVxyXG4gIGlmICghZnMuZXhpc3RzU3luYyhpbWFnZVBhdGgpKSB7XHJcbiAgICBmcy5ta2RpclN5bmMoaW1hZ2VQYXRoKVxyXG4gIH1cclxufVxyXG5cclxuLy8gVGhhbmtzIHRvIHZzLXBpY2dvOiBodHRwczovL2dpdGh1Yi5jb20vU3BhZGVzLVMvdnMtcGljZ28vYmxvYi9tYXN0ZXIvc3JjL2V4dGVuc2lvbi50c1xyXG5jb25zdCBnZXRDbGlwYm9hcmRJbWFnZSA9IGFzeW5jIChjdHg6IElQaWNHbyk6IFByb21pc2U8SUNsaXBib2FyZEltYWdlPiA9PiB7XHJcbiAgY3JlYXRlSW1hZ2VGb2xkZXIoY3R4KVxyXG4gIC8vIGFkZCBhbiBjbGlwYm9hcmQgaW1hZ2UgZm9sZGVyIHRvIGNvbnRyb2wgdGhlIGltYWdlIGNhY2hlIGZpbGVcclxuICBjb25zdCBpbWFnZVBhdGggPSBwYXRoLmpvaW4oY3R4LmJhc2VEaXIsIENMSVBCT0FSRF9JTUFHRV9GT0xERVIsIGAke2RheWpzKCkuZm9ybWF0KCdZWVlZTU1EREhIbW1zcycpfS5wbmdgKVxyXG4gIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZTxJQ2xpcGJvYXJkSW1hZ2U+KChyZXNvbHZlOiBGdW5jdGlvbiwgcmVqZWN0OiBGdW5jdGlvbik6IHZvaWQgPT4ge1xyXG4gICAgY29uc3QgcGxhdGZvcm0gPSBnZXRDdXJyZW50UGxhdGZvcm0oKVxyXG4gICAgY29uc3Qgc2NyaXB0UGF0aCA9IHBhdGguam9pbihjdHguYmFzZURpciwgcGxhdGZvcm0yU2NyaXB0RmlsZW5hbWVbcGxhdGZvcm1dKVxyXG4gICAgLy8gSWYgdGhlIHNjcmlwdCBkb2VzIG5vdCBleGlzdCB5ZXQsIHdlIG5lZWQgdG8gd3JpdGUgdGhlIGNvbnRlbnQgdG8gdGhlIHNjcmlwdCBmaWxlXHJcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoc2NyaXB0UGF0aCkpIHtcclxuICAgICAgZnMud3JpdGVGaWxlU3luYyhcclxuICAgICAgICBzY3JpcHRQYXRoLFxyXG4gICAgICAgIHBsYXRmb3JtMlNjcmlwdENvbnRlbnRbcGxhdGZvcm1dLFxyXG4gICAgICAgICd1dGY4J1xyXG4gICAgICApXHJcbiAgICB9XHJcbiAgICBsZXQgZXhlY3V0aW9uXHJcbiAgICBpZiAocGxhdGZvcm0gPT09ICdkYXJ3aW4nKSB7XHJcbiAgICAgIGV4ZWN1dGlvbiA9IHNwYXduKCdvc2FzY3JpcHQnLCBbc2NyaXB0UGF0aCwgaW1hZ2VQYXRoXSlcclxuICAgIH0gZWxzZSBpZiAocGxhdGZvcm0gPT09ICd3aW4zMicgfHwgcGxhdGZvcm0gPT09ICd3aW4xMCcpIHtcclxuICAgICAgZXhlY3V0aW9uID0gc3Bhd24oJ3Bvd2Vyc2hlbGwnLCBbXHJcbiAgICAgICAgJy1ub3Byb2ZpbGUnLFxyXG4gICAgICAgICctbm9uaW50ZXJhY3RpdmUnLFxyXG4gICAgICAgICctbm9sb2dvJyxcclxuICAgICAgICAnLXN0YScsXHJcbiAgICAgICAgJy1leGVjdXRpb25wb2xpY3knLCAndW5yZXN0cmljdGVkJyxcclxuICAgICAgICAvLyBmaXggd2luZG93cyAxMCBuYXRpdmUgY21kIGNyYXNoIGJ1ZyB3aGVuIFwicGljZ28gdXBsb2FkXCJcclxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vUGljR28vUGljR28tQ29yZS9pc3N1ZXMvMzJcclxuICAgICAgICAvLyAnLXdpbmRvd3N0eWxlJywnaGlkZGVuJyxcclxuICAgICAgICAvLyAnLW5vZXhpdCcsXHJcbiAgICAgICAgJy1maWxlJywgc2NyaXB0UGF0aCxcclxuICAgICAgICBpbWFnZVBhdGhcclxuICAgICAgXSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGV4ZWN1dGlvbiA9IHNwYXduKCdzaCcsIFtzY3JpcHRQYXRoLCBpbWFnZVBhdGhdKVxyXG4gICAgfVxyXG5cclxuICAgIGV4ZWN1dGlvbi5zdGRvdXQub24oJ2RhdGEnLCAoZGF0YTogQnVmZmVyKSA9PiB7XHJcbiAgICAgIGlmIChwbGF0Zm9ybSA9PT0gJ2xpbnV4Jykge1xyXG4gICAgICAgIGlmIChkYXRhLnRvU3RyaW5nKCkudHJpbSgpID09PSAnbm8geGNsaXAgb3Igd2wtY2xpcGJvYXJkJykge1xyXG4gICAgICAgICAgY3R4LmVtaXQoSUJ1aWxkSW5FdmVudC5OT1RJRklDQVRJT04sIHtcclxuICAgICAgICAgICAgdGl0bGU6ICd4Y2xpcCBvciB3bC1jbGlwYm9hcmQgbm90IGZvdW5kJyxcclxuICAgICAgICAgICAgYm9keTogJ1BsZWFzZSBpbnN0YWxsIHhjbGlwKGZvciB4MTEpIG9yIHdsLWNsaXBib2FyZChmb3Igd2F5bGFuZCkgYmVmb3JlIHJ1biBwaWNnbydcclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignUGxlYXNlIGluc3RhbGwgeGNsaXAoZm9yIHgxMSkgb3Igd2wtY2xpcGJvYXJkKGZvciB3YXlsYW5kKSBiZWZvcmUgcnVuIHBpY2dvJykpXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IGltZ1BhdGggPSBkYXRhLnRvU3RyaW5nKCkudHJpbSgpXHJcblxyXG4gICAgICAvLyBpZiB0aGUgZmlsZVBhdGggaXMgdGhlIHJlYWwgZmlsZSBpbiBzeXN0ZW1cclxuICAgICAgLy8gd2Ugc2hvdWxkIGtlZXAgaXQgaW5zdGVhZCBvZiByZW1vdmluZ1xyXG4gICAgICBsZXQgc2hvdWxkS2VlcEFmdGVyVXBsb2FkaW5nID0gZmFsc2VcclxuXHJcbiAgICAgIC8vIGluIG1hY09TIGlmIHlvdXIgY29weSB0aGUgZmlsZSBpbiBzeXN0ZW0sIGl0J3MgYmFzZW5hbWUgd2lsbCBub3QgZXF1YWwgdG8gb3VyIGRlZmF1bHQgYmFzZW5hbWVcclxuICAgICAgaWYgKHBhdGguYmFzZW5hbWUoaW1nUGF0aCkgIT09IHBhdGguYmFzZW5hbWUoaW1hZ2VQYXRoKSkge1xyXG4gICAgICAgIC8vIGlmIHRoZSBwYXRoIGlzIG5vdCBnZW5lcmF0ZSBieSBwaWNnb1xyXG4gICAgICAgIC8vIGJ1dCB0aGUgcGF0aCBleGlzdHMsIHdlIHNob3VsZCBrZWVwIGl0XHJcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoaW1nUGF0aCkpIHtcclxuICAgICAgICAgIHNob3VsZEtlZXBBZnRlclVwbG9hZGluZyA9IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgLy8gaWYgdGhlIGltZ1BhdGggaXMgaW52YWxpZFxyXG4gICAgICBpZiAoaW1nUGF0aCAhPT0gJ25vIGltYWdlJyAmJiAhZnMuZXhpc3RzU3luYyhpbWdQYXRoKSkge1xyXG4gICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKGBDYW4ndCBmaW5kICR7aW1nUGF0aH1gKSlcclxuICAgICAgfVxyXG5cclxuICAgICAgcmVzb2x2ZSh7XHJcbiAgICAgICAgaW1nUGF0aCxcclxuICAgICAgICBzaG91bGRLZWVwQWZ0ZXJVcGxvYWRpbmdcclxuICAgICAgfSlcclxuICAgIH0pXHJcbiAgfSlcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgZ2V0Q2xpcGJvYXJkSW1hZ2VcclxuIiwiaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRzJ1xyXG5cclxuY29uc3QgZXZlbnRCdXMgPSBuZXcgRXZlbnRFbWl0dGVyKClcclxuZXhwb3J0IHtcclxuICBldmVudEJ1c1xyXG59XHJcbiIsIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9leHBsaWNpdC1mdW5jdGlvbi1yZXR1cm4tdHlwZSAqL1xyXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvcHJvbWlzZS1mdW5jdGlvbi1hc3luYyAqL1xyXG5pbXBvcnQgYXhpb3MsIHsgQXhpb3NSZXF1ZXN0Q29uZmlnLCBBeGlvc1Jlc3BvbnNlIH0gZnJvbSAnYXhpb3MnXHJcbmltcG9ydCB7IElQaWNHbywgVW5kZWZpbmFibGUsIElDb25maWdDaGFuZ2VQYXlsb2FkLCBJQ29uZmlnLCBJUmVxdWVzdENvbmZpZywgSU9sZFJlcU9wdGlvbnMsIElSZXNwb25zZSwgSUZ1bGxSZXNwb25zZSwgSVJlcXVlc3QgfSBmcm9tICcuLi90eXBlcydcclxuaW1wb3J0IHsgSUJ1c0V2ZW50IH0gZnJvbSAnLi4vdXRpbHMvZW51bSdcclxuaW1wb3J0IHsgZXZlbnRCdXMgfSBmcm9tICcuLi91dGlscy9ldmVudEJ1cydcclxuaW1wb3J0IHsgVVJMIH0gZnJvbSAndXJsJ1xyXG5pbXBvcnQgRm9ybURhdGEgZnJvbSAnZm9ybS1kYXRhJ1xyXG5pbXBvcnQgaHR0cHMgZnJvbSAnaHR0cHMnXHJcbmltcG9ydCB0dW5uZWwgZnJvbSAndHVubmVsJ1xyXG5jb25zdCBodHRwc0FnZW50ID0gbmV3IGh0dHBzLkFnZW50KHtcclxuICBtYXhWZXJzaW9uOiAnVExTdjEuMicsXHJcbiAgbWluVmVyc2lvbjogJ1RMU3YxLjInXHJcbn0pXHJcblxyXG4vLyB0aGFua3MgZm9yIGh0dHBzOi8vZ2l0aHViLmRldi9yZXF1ZXN0L3JlcXVlc3QvYmxvYi9tYXN0ZXIvaW5kZXguanNcclxuZnVuY3Rpb24gYXBwZW5kRm9ybURhdGEgKGZvcm06IEZvcm1EYXRhLCBrZXk6IHN0cmluZywgZGF0YTogYW55KTogdm9pZCB7XHJcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnb2JqZWN0JyAmJiAndmFsdWUnIGluIGRhdGEgJiYgJ29wdGlvbnMnIGluIGRhdGEpIHtcclxuICAgIGZvcm0uYXBwZW5kKGtleSwgZGF0YS52YWx1ZSwgZGF0YS5vcHRpb25zKVxyXG4gIH0gZWxzZSB7XHJcbiAgICBmb3JtLmFwcGVuZChrZXksIGRhdGEpXHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiByZXF1ZXN0SW50ZXJjZXB0b3IgKG9wdGlvbnM6IElPbGRSZXFPcHRpb25zIHwgQXhpb3NSZXF1ZXN0Q29uZmlnKTogQXhpb3NSZXF1ZXN0Q29uZmlnICYge1xyXG4gIF9faXNPbGRPcHRpb25zPzogYm9vbGVhblxyXG59IHtcclxuICBsZXQgX19pc09sZE9wdGlvbnMgPSBmYWxzZVxyXG4gIGNvbnN0IG9wdDogQXhpb3NSZXF1ZXN0Q29uZmlnPGFueT4gJiB7XHJcbiAgICBfX2lzT2xkT3B0aW9ucz86IGJvb2xlYW5cclxuICB9ID0ge1xyXG4gICAgLi4ub3B0aW9ucyxcclxuICAgIHVybDogKG9wdGlvbnMudXJsIGFzIHN0cmluZykgfHwgJycsXHJcbiAgICBoZWFkZXJzOiBvcHRpb25zLmhlYWRlcnMgfHwge31cclxuICB9XHJcbiAgLy8gdXNlciByZXF1ZXN0IGNvbmZpZyBwcm94eVxyXG4gIGlmIChvcHRpb25zLnByb3h5KSB7XHJcbiAgICBsZXQgcHJveHlPcHRpb25zID0gb3B0aW9ucy5wcm94eVxyXG4gICAgaWYgKHR5cGVvZiBwcm94eU9wdGlvbnMgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgcHJveHlPcHRpb25zID0gbmV3IFVSTChvcHRpb25zLnByb3h5KVxyXG4gICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgcHJveHlPcHRpb25zID0gZmFsc2VcclxuICAgICAgICBvcHQucHJveHkgPSBmYWxzZVxyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSlcclxuICAgICAgfVxyXG4gICAgICBfX2lzT2xkT3B0aW9ucyA9IHRydWVcclxuICAgIH1cclxuICAgIGlmIChwcm94eU9wdGlvbnMpIHtcclxuICAgICAgaWYgKG9wdGlvbnMudXJsPy5zdGFydHNXaXRoKCdodHRwczovLycpKSB7XHJcbiAgICAgICAgb3B0LnByb3h5ID0gZmFsc2VcclxuICAgICAgICBvcHQuaHR0cHNBZ2VudCA9IHR1bm5lbC5odHRwc092ZXJIdHRwKHtcclxuICAgICAgICAgIHByb3h5OiB7XHJcbiAgICAgICAgICAgIGhvc3Q6IHByb3h5T3B0aW9ucz8uaG9zdG5hbWUsXHJcbiAgICAgICAgICAgIHBvcnQ6IHBhcnNlSW50KHByb3h5T3B0aW9ucz8ucG9ydCwgMTApXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBvcHQucHJveHkgPSB7XHJcbiAgICAgICAgICBob3N0OiBwcm94eU9wdGlvbnMuaG9zdG5hbWUsXHJcbiAgICAgICAgICBwb3J0OiBwYXJzZUludChwcm94eU9wdGlvbnMucG9ydCwgMTApLFxyXG4gICAgICAgICAgcHJvdG9jb2w6ICdodHRwJ1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICBpZiAoJ2Zvcm1EYXRhJyBpbiBvcHRpb25zKSB7XHJcbiAgICBjb25zdCBmb3JtID0gbmV3IEZvcm1EYXRhKClcclxuICAgIGZvciAoY29uc3Qga2V5IGluIG9wdGlvbnMuZm9ybURhdGEpIHtcclxuICAgICAgY29uc3QgZGF0YSA9IG9wdGlvbnMuZm9ybURhdGFba2V5XVxyXG4gICAgICBhcHBlbmRGb3JtRGF0YShmb3JtLCBrZXksIGRhdGEpXHJcbiAgICB9XHJcbiAgICBvcHQuZGF0YSA9IGZvcm1cclxuICAgIG9wdC5oZWFkZXJzID0gT2JqZWN0LmFzc2lnbihvcHQuaGVhZGVycyB8fCB7fSwgZm9ybS5nZXRIZWFkZXJzKCkpXHJcbiAgICBfX2lzT2xkT3B0aW9ucyA9IHRydWVcclxuICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcclxuICAgIGRlbGV0ZSBvcHQuZm9ybURhdGFcclxuICB9XHJcbiAgaWYgKCdib2R5JyBpbiBvcHRpb25zKSB7XHJcbiAgICBvcHQuZGF0YSA9IG9wdGlvbnMuYm9keVxyXG4gICAgX19pc09sZE9wdGlvbnMgPSB0cnVlXHJcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yXHJcbiAgICBkZWxldGUgb3B0LmJvZHlcclxuICB9XHJcbiAgaWYgKCdxcycgaW4gb3B0aW9ucykge1xyXG4gICAgb3B0LnBhcmFtcyA9IG9wdGlvbnMucXNcclxuICAgIF9faXNPbGRPcHRpb25zID0gdHJ1ZVxyXG4gIH1cclxuICBvcHQuX19pc09sZE9wdGlvbnMgPSBfX2lzT2xkT3B0aW9uc1xyXG4gIHJldHVybiBvcHRcclxufVxyXG5cclxuZnVuY3Rpb24gcmVzcG9uc2VJbnRlcmNlcHRvciAocmVzcG9uc2U6IEF4aW9zUmVzcG9uc2UpOiBJRnVsbFJlc3BvbnNlIHtcclxuICByZXR1cm4ge1xyXG4gICAgLi4ucmVzcG9uc2UsXHJcbiAgICBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXMsXHJcbiAgICBib2R5OiByZXNwb25zZS5kYXRhXHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiByZXNwb25zZUVycm9ySGFuZGxlciAoZXJyb3I6IGFueSkge1xyXG4gIC8vIGlmIChlcnJvci5yZXNwb25zZSkge1xyXG4gIC8vICAgLy8gVGhlIHJlcXVlc3Qgd2FzIG1hZGUgYW5kIHRoZSBzZXJ2ZXIgcmVzcG9uZGVkIHdpdGggYSBzdGF0dXMgY29kZVxyXG4gIC8vICAgLy8gdGhhdCBmYWxscyBvdXQgb2YgdGhlIHJhbmdlIG9mIDJ4eFxyXG4gIC8vICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm8pXHJcbiAgLy8gfSBlbHNlIGlmIChlcnJvci5yZXF1ZXN0KSB7XHJcbiAgLy8gICAvLyBUaGUgcmVxdWVzdCB3YXMgbWFkZSBidXQgbm8gcmVzcG9uc2Ugd2FzIHJlY2VpdmVkXHJcbiAgLy8gICAvLyBgZXJyb3IucmVxdWVzdGAgaXMgYW4gaW5zdGFuY2Ugb2YgWE1MSHR0cFJlcXVlc3QgaW4gdGhlIGJyb3dzZXIgYW5kIGFuIGluc3RhbmNlIG9mXHJcbiAgLy8gICAvLyBodHRwLkNsaWVudFJlcXVlc3QgaW4gbm9kZS5qc1xyXG4gIC8vICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yLnJlcXVlc3QpXHJcbiAgLy8gfSBlbHNlIHtcclxuICAvLyAgIC8vIFNvbWV0aGluZyBoYXBwZW5lZCBpbiBzZXR0aW5nIHVwIHRoZSByZXF1ZXN0IHRoYXQgdHJpZ2dlcmVkIGFuIEVycm9yXHJcbiAgLy8gICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IubWVzc2FnZSlcclxuICAvLyB9XHJcbiAgY29uc3QgZXJyb3JPYmogPSB7XHJcbiAgICBtZXRob2Q6IGVycm9yPy5jb25maWc/Lm1ldGhvZD8udG9VcHBlckNhc2UoKSB8fCAnJyxcclxuICAgIHVybDogZXJyb3I/LmNvbmZpZz8udXJsIHx8ICcnLFxyXG4gICAgc3RhdHVzQ29kZTogZXJyb3I/LnJlc3BvbnNlPy5zdGF0dXMgfHwgMCxcclxuICAgIG1lc3NhZ2U6IGVycm9yPy5tZXNzYWdlIHx8ICcnLFxyXG4gICAgc3RhY2s6IGVycm9yPy5zdGFjayB8fCB7fSxcclxuICAgIHJlc3BvbnNlOiB7XHJcbiAgICAgIHN0YXR1czogZXJyb3I/LnJlc3BvbnNlPy5zdGF0dXMgfHwgMCxcclxuICAgICAgc3RhdHVzQ29kZTogZXJyb3I/LnJlc3BvbnNlPy5zdGF0dXMgfHwgMCxcclxuICAgICAgYm9keTogZXJyb3I/LnJlc3BvbnNlPy5kYXRhIHx8ICcnXHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvck9iailcclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFJlcXVlc3QgaW1wbGVtZW50cyBJUmVxdWVzdCB7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBjdHg6IElQaWNHb1xyXG4gIHByaXZhdGUgcHJveHk6IFVuZGVmaW5hYmxlPHN0cmluZz4gPSAnJ1xyXG4gIG9wdGlvbnM6IEF4aW9zUmVxdWVzdENvbmZpZzxhbnk+ID0ge31cclxuICBjb25zdHJ1Y3RvciAoY3R4OiBJUGljR28pIHtcclxuICAgIHRoaXMuY3R4ID0gY3R4XHJcbiAgICB0aGlzLmluaXQoKVxyXG4gICAgZXZlbnRCdXMub24oSUJ1c0V2ZW50LkNPTkZJR19DSEFOR0UsIChkYXRhOiBJQ29uZmlnQ2hhbmdlUGF5bG9hZDxzdHJpbmcgfCBJQ29uZmlnWydwaWNCZWQnXT4pID0+IHtcclxuICAgICAgc3dpdGNoIChkYXRhLmNvbmZpZ05hbWUpIHtcclxuICAgICAgICBjYXNlICdwaWNCZWQnOlxyXG4gICAgICAgICAgaWYgKChkYXRhLnZhbHVlIGFzIElDb25maWdbJ3BpY0JlZCddKT8ucHJveHkpIHtcclxuICAgICAgICAgICAgdGhpcy5wcm94eSA9IChkYXRhLnZhbHVlIGFzIElDb25maWdbJ3BpY0JlZCddKS5wcm94eVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgYnJlYWtcclxuICAgICAgICBjYXNlICdwaWNCZWQucHJveHknOlxyXG4gICAgICAgICAgdGhpcy5wcm94eSA9IGRhdGEudmFsdWUgYXMgc3RyaW5nXHJcbiAgICAgICAgICBicmVha1xyXG4gICAgICB9XHJcbiAgICB9KVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbml0ICgpOiB2b2lkIHtcclxuICAgIGNvbnN0IHByb3h5ID0gdGhpcy5jdHguZ2V0Q29uZmlnPFVuZGVmaW5hYmxlPHN0cmluZz4+KCdwaWNCZWQucHJveHknKVxyXG4gICAgaWYgKHByb3h5KSB7XHJcbiAgICAgIHRoaXMucHJveHkgPSBwcm94eVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBoYW5kbGVQcm94eSAoKTogQXhpb3NSZXF1ZXN0Q29uZmlnWydwcm94eSddIHwgZmFsc2Uge1xyXG4gICAgaWYgKHRoaXMucHJveHkpIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjb25zdCBwcm94eU9wdGlvbnMgPSBuZXcgVVJMKHRoaXMucHJveHkpXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgIGhvc3Q6IHByb3h5T3B0aW9ucy5ob3N0bmFtZSxcclxuICAgICAgICAgIHBvcnQ6IHBhcnNlSW50KHByb3h5T3B0aW9ucy5wb3J0IHx8ICcwJywgMTApLFxyXG4gICAgICAgICAgcHJvdG9jb2w6IHByb3h5T3B0aW9ucy5wcm90b2NvbFxyXG4gICAgICAgIH1cclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2VcclxuICB9XHJcblxyXG4gIC8vICM2NCBkeW5hbWljIGdldCBwcm94eSB2YWx1ZVxyXG4gIHJlcXVlc3Q8VCwgVSBleHRlbmRzIChcclxuICAgIElSZXF1ZXN0Q29uZmlnPFU+IGV4dGVuZHMgSU9sZFJlcU9wdGlvbnMgPyBJT2xkUmVxT3B0aW9ucyA6IElSZXF1ZXN0Q29uZmlnPFU+IGV4dGVuZHMgQXhpb3NSZXF1ZXN0Q29uZmlnID8gQXhpb3NSZXF1ZXN0Q29uZmlnIDogbmV2ZXJcclxuICApPiAob3B0aW9uczogVSk6IFByb21pc2U8SVJlc3BvbnNlPFQsIFU+PiB7XHJcbiAgICB0aGlzLm9wdGlvbnMucHJveHkgPSB0aGlzLmhhbmRsZVByb3h5KClcclxuICAgIHRoaXMub3B0aW9ucy5oZWFkZXJzID0gb3B0aW9ucy5oZWFkZXJzIHx8IHt9XHJcbiAgICB0aGlzLm9wdGlvbnMubWF4Qm9keUxlbmd0aCA9IEluZmluaXR5XHJcbiAgICB0aGlzLm9wdGlvbnMubWF4Q29udGVudExlbmd0aCA9IEluZmluaXR5XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLnByb3h5ICYmIG9wdGlvbnMudXJsPy5zdGFydHNXaXRoKCdodHRwczovLycpKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5odHRwc0FnZW50ID0gdHVubmVsLmh0dHBzT3Zlckh0dHAoe1xyXG4gICAgICAgIHByb3h5OiB7XHJcbiAgICAgICAgICBob3N0OiB0aGlzLm9wdGlvbnMucHJveHkuaG9zdCxcclxuICAgICAgICAgIHBvcnQ6IHRoaXMub3B0aW9ucy5wcm94eS5wb3J0XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgICB0aGlzLm9wdGlvbnMucHJveHkgPSBmYWxzZVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5vcHRpb25zLmh0dHBzQWdlbnQgPSBodHRwc0FnZW50XHJcbiAgICB9XHJcbiAgICAvLyAhTk9USUNFIHRoaXMub3B0aW9ucyAhPT0gb3B0aW9uc1xyXG4gICAgLy8gdGhpcy5vcHRpb25zIGlzIHRoZSBkZWZhdWx0IG9wdGlvbnNcclxuICAgIGNvbnN0IGluc3RhbmNlID0gYXhpb3MuY3JlYXRlKHRoaXMub3B0aW9ucylcclxuICAgIGluc3RhbmNlLmludGVyY2VwdG9ycy5yZXNwb25zZS51c2UocmVzcG9uc2VJbnRlcmNlcHRvciwgcmVzcG9uc2VFcnJvckhhbmRsZXIpXHJcblxyXG4gICAgLy8gY29tcGF0aWJsZSB3aXRoIG9sZCByZXF1ZXN0IG9wdGlvbnMgdG8gbmV3IG9wdGlvbnNcclxuICAgIGNvbnN0IG9wdCA9IHJlcXVlc3RJbnRlcmNlcHRvcihvcHRpb25zKVxyXG5cclxuICAgIGluc3RhbmNlLmludGVyY2VwdG9ycy5yZXF1ZXN0LnVzZShmdW5jdGlvbiAob2JqKSB7XHJcbiAgICAgIC8vIGhhbmRsZSBDb250ZW50LVR5cGVcclxuICAgICAgbGV0IGNvbnRlbnRUeXBlID0gJydcclxuICAgICAgaWYgKG9iaj8uaGVhZGVycz8uY29udGVudFR5cGUpIHtcclxuICAgICAgICBjb250ZW50VHlwZSA9IG9iai5oZWFkZXJzLmNvbnRlbnRUeXBlIGFzIHN0cmluZ1xyXG4gICAgICAgIGRlbGV0ZSBvYmouaGVhZGVycy5jb250ZW50VHlwZVxyXG4gICAgICB9IGVsc2UgaWYgKG9iaj8uaGVhZGVycz8uQ29udGVudFR5cGUpIHtcclxuICAgICAgICBjb250ZW50VHlwZSA9IG9iai5oZWFkZXJzLkNvbnRlbnRUeXBlIGFzIHN0cmluZ1xyXG4gICAgICAgIGRlbGV0ZSBvYmouaGVhZGVycy5Db250ZW50VHlwZVxyXG4gICAgICB9IGVsc2UgaWYgKG9iaj8uaGVhZGVycz8uWydjb250ZW50LXR5cGUnXSkge1xyXG4gICAgICAgIGNvbnRlbnRUeXBlID0gb2JqLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddIGFzIHN0cmluZ1xyXG4gICAgICAgIGRlbGV0ZSBvYmouaGVhZGVyc1snY29udGVudC10eXBlJ11cclxuICAgICAgfVxyXG4gICAgICBpZiAoY29udGVudFR5cGUgIT09ICcnICYmIG9iai5oZWFkZXJzKSB7XHJcbiAgICAgICAgb2JqLmhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gY29udGVudFR5cGVcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gb2JqXHJcbiAgICB9KVxyXG4gICAgaWYgKCdyZXNvbHZlV2l0aEZ1bGxSZXNwb25zZScgaW4gb3B0aW9ucyAmJiBvcHRpb25zLnJlc29sdmVXaXRoRnVsbFJlc3BvbnNlKSB7XHJcbiAgICAgIHJldHVybiBpbnN0YW5jZS5yZXF1ZXN0KG9wdClcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBpbnN0YW5jZS5yZXF1ZXN0KG9wdCkudGhlbihyZXMgPT4ge1xyXG4gICAgICAgIC8vIHVzZSBvbGQgcmVxdWVzdCBvcHRpb24gZm9ybWF0XHJcbiAgICAgICAgaWYgKG9wdC5fX2lzT2xkT3B0aW9ucykge1xyXG4gICAgICAgICAgaWYgKCdqc29uJyBpbiBvcHRpb25zKSB7XHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmpzb24pIHtcclxuICAgICAgICAgICAgICByZXR1cm4gcmVzLmRhdGFcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHJlcy5kYXRhKVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICByZXR1cm4gcmVzLmRhdGFcclxuICAgICAgICB9XHJcbiAgICAgIH0pIGFzIFByb21pc2U8SVJlc3BvbnNlPFQsIFU+PlxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgUmVxdWVzdFxyXG4iLCJpbXBvcnQgeyBJQ29uZmlnLCBJUGljR28gfSBmcm9tICcuLi90eXBlcydcclxuaW1wb3J0IHsgSlNPTlN0b3JlIH0gZnJvbSAnQHBpY2dvL3N0b3JlJ1xyXG5pbXBvcnQgeyBJSlNPTiB9IGZyb20gJ0BwaWNnby9zdG9yZS9kaXN0L3R5cGVzJ1xyXG5cclxuY2xhc3MgREIge1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgY3R4OiBJUGljR29cclxuICBwcml2YXRlIHJlYWRvbmx5IGRiOiBKU09OU3RvcmVcclxuICBjb25zdHJ1Y3RvciAoY3R4OiBJUGljR28pIHtcclxuICAgIHRoaXMuY3R4ID0gY3R4XHJcbiAgICB0aGlzLmRiID0gbmV3IEpTT05TdG9yZSh0aGlzLmN0eC5jb25maWdQYXRoKVxyXG5cclxuICAgIGlmICghdGhpcy5kYi5oYXMoJ3BpY0JlZCcpKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgdGhpcy5kYi5zZXQoJ3BpY0JlZCcsIHtcclxuICAgICAgICAgIHVwbG9hZGVyOiAnc21tcycsXHJcbiAgICAgICAgICBjdXJyZW50OiAnc21tcydcclxuICAgICAgICB9KVxyXG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcclxuICAgICAgICB0aGlzLmN0eC5sb2cuZXJyb3IoZSlcclxuICAgICAgICB0aHJvdyBlXHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICghdGhpcy5kYi5oYXMoJ3BpY2dvUGx1Z2lucycpKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgdGhpcy5kYi5zZXQoJ3BpY2dvUGx1Z2lucycsIHt9KVxyXG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcclxuICAgICAgICB0aGlzLmN0eC5sb2cuZXJyb3IoZSlcclxuICAgICAgICB0aHJvdyBlXHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJlYWQgKGZsdXNoPzogYm9vbGVhbik6IElKU09OIHtcclxuICAgIHJldHVybiB0aGlzLmRiLnJlYWQoZmx1c2gpXHJcbiAgfVxyXG5cclxuICBnZXQgKGtleTogc3RyaW5nID0gJycpOiBhbnkge1xyXG4gICAgdGhpcy5yZWFkKHRydWUpXHJcbiAgICByZXR1cm4gdGhpcy5kYi5nZXQoa2V5KVxyXG4gIH1cclxuXHJcbiAgc2V0IChrZXk6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5yZWFkKHRydWUpXHJcbiAgICByZXR1cm4gdGhpcy5kYi5zZXQoa2V5LCB2YWx1ZSlcclxuICB9XHJcblxyXG4gIGhhcyAoa2V5OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHRoaXMucmVhZCh0cnVlKVxyXG4gICAgcmV0dXJuIHRoaXMuZGIuaGFzKGtleSlcclxuICB9XHJcblxyXG4gIHVuc2V0IChrZXk6IHN0cmluZywgdmFsdWU6IGFueSk6IGJvb2xlYW4ge1xyXG4gICAgdGhpcy5yZWFkKHRydWUpXHJcbiAgICByZXR1cm4gdGhpcy5kYi51bnNldChrZXksIHZhbHVlKVxyXG4gIH1cclxuXHJcbiAgc2F2ZUNvbmZpZyAoY29uZmlnOiBQYXJ0aWFsPElDb25maWc+KTogdm9pZCB7XHJcbiAgICBPYmplY3Qua2V5cyhjb25maWcpLmZvckVhY2goKG5hbWU6IHN0cmluZykgPT4ge1xyXG4gICAgICB0aGlzLnNldChuYW1lLCBjb25maWdbbmFtZV0pXHJcbiAgICB9KVxyXG4gIH1cclxuXHJcbiAgcmVtb3ZlQ29uZmlnIChjb25maWc6IElDb25maWcpOiB2b2lkIHtcclxuICAgIE9iamVjdC5rZXlzKGNvbmZpZykuZm9yRWFjaCgobmFtZTogc3RyaW5nKSA9PiB7XHJcbiAgICAgIHRoaXMudW5zZXQobmFtZSwgY29uZmlnW25hbWVdKVxyXG4gICAgfSlcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IERCXHJcblxyXG4vLyBjb25zdCBpbml0Q29uZmlnID0gKGNvbmZpZ1BhdGg6IHN0cmluZyk6IGxvd2RiLkxvd2RiU3luYzxhbnk+ID0+IHtcclxuLy8gfVxyXG5cclxuLy8gY29uc3Qgc2F2ZUNvbmZpZyA9IChjb25maWdQYXRoOiBzdHJpbmcsIGNvbmZpZzogYW55KTogdm9pZCA9PiB7XHJcbi8vICAgY29uc3QgZGIgPSBpbml0Q29uZmlnKGNvbmZpZ1BhdGgpXHJcbi8vICAgT2JqZWN0LmtleXMoY29uZmlnKS5mb3JFYWNoKChuYW1lOiBzdHJpbmcpID0+IHtcclxuLy8gICAgIGRiLnJlYWQoKS5zZXQobmFtZSwgY29uZmlnW25hbWVdKS53cml0ZSgpXHJcbi8vICAgfSlcclxuLy8gfVxyXG5cclxuLy8gZXhwb3J0IHtcclxuLy8gaW5pdENvbmZpZyxcclxuLy8gc2F2ZUNvbmZpZ1xyXG4vLyB9XHJcbiIsImltcG9ydCBzcGF3biBmcm9tICdjcm9zcy1zcGF3bidcclxuaW1wb3J0IHtcclxuICBJUmVzdWx0LFxyXG4gIElQcm9jZXNzRW52LFxyXG4gIElQbHVnaW5Qcm9jZXNzUmVzdWx0LFxyXG4gIElQbHVnaW5IYW5kbGVyLFxyXG4gIElQbHVnaW5IYW5kbGVyT3B0aW9ucyxcclxuICBVbmRlZmluYWJsZSxcclxuICBJUGljR28sXHJcbiAgSVBsdWdpbkhhbmRsZXJSZXN1bHRcclxufSBmcm9tICcuLi90eXBlcydcclxuaW1wb3J0IHsgSUJ1aWxkSW5FdmVudCB9IGZyb20gJy4uL3V0aWxzL2VudW0nXHJcbmltcG9ydCB7IGdldFByb2Nlc3NQbHVnaW5OYW1lLCBnZXROb3JtYWxQbHVnaW5OYW1lIH0gZnJvbSAnLi4vdXRpbHMvY29tbW9uJ1xyXG5pbXBvcnQgeyBJTG9jYWxlc0tleSB9IGZyb20gJy4uL2kxOG4vemgtQ04nXHJcblxyXG5leHBvcnQgY2xhc3MgUGx1Z2luSGFuZGxlciBpbXBsZW1lbnRzIElQbHVnaW5IYW5kbGVyIHtcclxuICAvLyBUaGFua3MgdG8gZmVmbG93IC0+IGh0dHBzOi8vZ2l0aHViLmNvbS9mZWZsb3cvZmVmbG93L2Jsb2IvbWFzdGVyL2xpYi9pbnRlcm5hbC9pbnN0YWxsL3BsdWdpbi5qc1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgY3R4OiBJUGljR29cclxuICBjb25zdHJ1Y3RvciAoY3R4OiBJUGljR28pIHtcclxuICAgIHRoaXMuY3R4ID0gY3R4XHJcbiAgfVxyXG5cclxuICBhc3luYyBpbnN0YWxsIChwbHVnaW5zOiBzdHJpbmdbXSwgb3B0aW9uczogSVBsdWdpbkhhbmRsZXJPcHRpb25zID0ge30sIGVudj86IElQcm9jZXNzRW52KTogUHJvbWlzZTxJUGx1Z2luSGFuZGxlclJlc3VsdDxib29sZWFuPj4ge1xyXG4gICAgY29uc3QgaW5zdGFsbGVkUGx1Z2luczogc3RyaW5nW10gPSBbXVxyXG4gICAgY29uc3QgcHJvY2Vzc1BsdWdpbnMgPSBwbHVnaW5zXHJcbiAgICAgIC5tYXAoKGl0ZW06IHN0cmluZykgPT4gaGFuZGxlUGx1Z2luTmFtZVByb2Nlc3ModGhpcy5jdHgsIGl0ZW0pKVxyXG4gICAgICAuZmlsdGVyKChpdGVtKSA9PiB7XHJcbiAgICAgICAgLy8gZGV0ZWN0IGlmIGhhcyBhbHJlYWR5IGluc3RhbGxlZFxyXG4gICAgICAgIC8vIG9yIHdpbGwgY2F1c2UgZXJyb3JcclxuICAgICAgICBpZiAodGhpcy5jdHgucGx1Z2luTG9hZGVyLmhhc1BsdWdpbihpdGVtLnBrZ05hbWUpKSB7XHJcbiAgICAgICAgICBpbnN0YWxsZWRQbHVnaW5zLnB1c2goaXRlbS5wa2dOYW1lKVxyXG4gICAgICAgICAgdGhpcy5jdHgubG9nLnN1Y2Nlc3MoYFBpY0dvIGhhcyBhbHJlYWR5IGluc3RhbGxlZCAke2l0ZW0ucGtnTmFtZX1gKVxyXG4gICAgICAgICAgcmV0dXJuIGZhbHNlXHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIHNvbWV0aGluZyB3cm9uZywgZmlsdGVyIGl0IG91dFxyXG4gICAgICAgIGlmICghaXRlbS5zdWNjZXNzKSB7XHJcbiAgICAgICAgICByZXR1cm4gZmFsc2VcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRydWVcclxuICAgICAgfSlcclxuICAgIGNvbnN0IGZ1bGxOYW1lTGlzdCA9IHByb2Nlc3NQbHVnaW5zLm1hcChpdGVtID0+IGl0ZW0uZnVsbE5hbWUpXHJcbiAgICBjb25zdCBwa2dOYW1lTGlzdCA9IHByb2Nlc3NQbHVnaW5zLm1hcChpdGVtID0+IGl0ZW0ucGtnTmFtZSlcclxuICAgIGlmIChmdWxsTmFtZUxpc3QubGVuZ3RoID4gMCkge1xyXG4gICAgICAvLyBpbnN0YWxsIHBsdWdpbnMgbXVzdCB1c2UgZnVsbE5hbWVMaXN0OlxyXG4gICAgICAvLyAxLiBpbnN0YWxsIHJlbW90ZSBwYWNhZ2VcclxuICAgICAgLy8gMi4gaW5zdGFsbCBsb2NhbCBwYWNhZ2VcclxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5leGVjQ29tbWFuZCgnaW5zdGFsbCcsIGZ1bGxOYW1lTGlzdCwgdGhpcy5jdHguYmFzZURpciwgb3B0aW9ucywgZW52KVxyXG4gICAgICBpZiAoIXJlc3VsdC5jb2RlKSB7XHJcbiAgICAgICAgcGtnTmFtZUxpc3QuZm9yRWFjaCgocGx1Z2luTmFtZTogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmN0eC5wbHVnaW5Mb2FkZXIucmVnaXN0ZXJQbHVnaW4ocGx1Z2luTmFtZSlcclxuICAgICAgICB9KVxyXG4gICAgICAgIHRoaXMuY3R4LmxvZy5zdWNjZXNzKHRoaXMuY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUExVR0lOX0hBTkRMRVJfUExVR0lOX0lOU1RBTExfU1VDQ0VTUycpKVxyXG4gICAgICAgIHRoaXMuY3R4LmVtaXQoJ2luc3RhbGxTdWNjZXNzJywge1xyXG4gICAgICAgICAgdGl0bGU6IHRoaXMuY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUExVR0lOX0hBTkRMRVJfUExVR0lOX0lOU1RBTExfU1VDQ0VTUycpLFxyXG4gICAgICAgICAgYm9keTogWy4uLnBrZ05hbWVMaXN0LCAuLi5pbnN0YWxsZWRQbHVnaW5zXVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgY29uc3QgcmVzOiBJUGx1Z2luSGFuZGxlclJlc3VsdDx0cnVlPiA9IHtcclxuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXHJcbiAgICAgICAgICBib2R5OiBbLi4ucGtnTmFtZUxpc3QsIC4uLmluc3RhbGxlZFBsdWdpbnNdXHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXNcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zdCBlcnIgPSB0aGlzLmN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BMVUdJTl9IQU5ETEVSX1BMVUdJTl9JTlNUQUxMX0ZBSUxFRF9SRUFTT04nLCB7XHJcbiAgICAgICAgICBjb2RlOiBgJHtyZXN1bHQuY29kZX1gLFxyXG4gICAgICAgICAgZGF0YTogcmVzdWx0LmRhdGFcclxuICAgICAgICB9KVxyXG4gICAgICAgIHRoaXMuY3R4LmxvZy5lcnJvcihlcnIpXHJcbiAgICAgICAgdGhpcy5jdHguZW1pdCgnaW5zdGFsbEZhaWxlZCcsIHtcclxuICAgICAgICAgIHRpdGxlOiB0aGlzLmN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BMVUdJTl9IQU5ETEVSX1BMVUdJTl9JTlNUQUxMX0ZBSUxFRCcpLFxyXG4gICAgICAgICAgYm9keTogZXJyXHJcbiAgICAgICAgfSlcclxuICAgICAgICBjb25zdCByZXM6IElQbHVnaW5IYW5kbGVyUmVzdWx0PGZhbHNlPiA9IHtcclxuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxyXG4gICAgICAgICAgYm9keTogZXJyXHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXNcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmIChpbnN0YWxsZWRQbHVnaW5zLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICBjb25zdCBlcnIgPSB0aGlzLmN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BMVUdJTl9IQU5ETEVSX1BMVUdJTl9VTklOU1RBTExfRkFJTEVEX1ZBTElEJylcclxuICAgICAgdGhpcy5jdHgubG9nLmVycm9yKGVycilcclxuICAgICAgdGhpcy5jdHguZW1pdCgnaW5zdGFsbEZhaWxlZCcsIHtcclxuICAgICAgICB0aXRsZTogdGhpcy5jdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQTFVHSU5fSEFORExFUl9QTFVHSU5fSU5TVEFMTF9GQUlMRUQnKSxcclxuICAgICAgICBib2R5OiBlcnJcclxuICAgICAgfSlcclxuICAgICAgY29uc3QgcmVzOiBJUGx1Z2luSGFuZGxlclJlc3VsdDxmYWxzZT4gPSB7XHJcbiAgICAgICAgc3VjY2VzczogZmFsc2UsXHJcbiAgICAgICAgYm9keTogZXJyXHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHJlc1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5jdHgubG9nLnN1Y2Nlc3ModGhpcy5jdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQTFVHSU5fSEFORExFUl9QTFVHSU5fSU5TVEFMTF9TVUNDRVNTJykpXHJcbiAgICAgIHRoaXMuY3R4LmVtaXQoJ2luc3RhbGxTdWNjZXNzJywge1xyXG4gICAgICAgIHRpdGxlOiB0aGlzLmN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BMVUdJTl9IQU5ETEVSX1BMVUdJTl9JTlNUQUxMX1NVQ0NFU1MnKSxcclxuICAgICAgICBib2R5OiBbLi4ucGtnTmFtZUxpc3QsIC4uLmluc3RhbGxlZFBsdWdpbnNdXHJcbiAgICAgIH0pXHJcbiAgICAgIGNvbnN0IHJlczogSVBsdWdpbkhhbmRsZXJSZXN1bHQ8dHJ1ZT4gPSB7XHJcbiAgICAgICAgc3VjY2VzczogdHJ1ZSxcclxuICAgICAgICBib2R5OiBbLi4ucGtnTmFtZUxpc3QsIC4uLmluc3RhbGxlZFBsdWdpbnNdXHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHJlc1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYXN5bmMgdW5pbnN0YWxsIChwbHVnaW5zOiBzdHJpbmdbXSk6IFByb21pc2U8SVBsdWdpbkhhbmRsZXJSZXN1bHQ8Ym9vbGVhbj4+IHtcclxuICAgIGNvbnN0IHByb2Nlc3NQbHVnaW5zID0gcGx1Z2lucy5tYXAoKGl0ZW06IHN0cmluZykgPT4gaGFuZGxlUGx1Z2luTmFtZVByb2Nlc3ModGhpcy5jdHgsIGl0ZW0pKS5maWx0ZXIoaXRlbSA9PiBpdGVtLnN1Y2Nlc3MpXHJcbiAgICBjb25zdCBwa2dOYW1lTGlzdCA9IHByb2Nlc3NQbHVnaW5zLm1hcChpdGVtID0+IGl0ZW0ucGtnTmFtZSlcclxuICAgIGlmIChwa2dOYW1lTGlzdC5sZW5ndGggPiAwKSB7XHJcbiAgICAgIC8vIHVuaW5zdGFsbCBwbHVnaW5zIG11c3QgdXNlIHBrZ05hbWVMaXN0OlxyXG4gICAgICAvLyBucG0gdW5pbnN0YWxsIHdpbGwgdXNlIHRoZSBwYWNrYWdlLmpzb24ncyBuYW1lXHJcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZXhlY0NvbW1hbmQoJ3VuaW5zdGFsbCcsIHBrZ05hbWVMaXN0LCB0aGlzLmN0eC5iYXNlRGlyKVxyXG4gICAgICBpZiAoIXJlc3VsdC5jb2RlKSB7XHJcbiAgICAgICAgcGtnTmFtZUxpc3QuZm9yRWFjaCgocGx1Z2luTmFtZTogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmN0eC5wbHVnaW5Mb2FkZXIudW5yZWdpc3RlclBsdWdpbihwbHVnaW5OYW1lKVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgdGhpcy5jdHgubG9nLnN1Y2Nlc3ModGhpcy5jdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQTFVHSU5fSEFORExFUl9QTFVHSU5fVU5JTlNUQUxMX1NVQ0NFU1MnKSlcclxuICAgICAgICB0aGlzLmN0eC5lbWl0KCd1bmluc3RhbGxTdWNjZXNzJywge1xyXG4gICAgICAgICAgdGl0bGU6IHRoaXMuY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUExVR0lOX0hBTkRMRVJfUExVR0lOX1VOSU5TVEFMTF9TVUNDRVNTJyksXHJcbiAgICAgICAgICBib2R5OiBwa2dOYW1lTGlzdFxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgY29uc3QgcmVzOiBJUGx1Z2luSGFuZGxlclJlc3VsdDx0cnVlPiA9IHtcclxuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXHJcbiAgICAgICAgICBib2R5OiBwa2dOYW1lTGlzdFxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgZXJyID0gdGhpcy5jdHguaTE4bi50cmFuc2xhdGU8SUxvY2FsZXNLZXk+KCdQTFVHSU5fSEFORExFUl9QTFVHSU5fVU5JTlNUQUxMX0ZBSUxFRF9SRUFTT04nLCB7XHJcbiAgICAgICAgICBjb2RlOiBgJHtyZXN1bHQuY29kZX1gLFxyXG4gICAgICAgICAgZGF0YTogcmVzdWx0LmRhdGFcclxuICAgICAgICB9KVxyXG4gICAgICAgIHRoaXMuY3R4LmxvZy5lcnJvcihlcnIpXHJcbiAgICAgICAgdGhpcy5jdHguZW1pdCgndW5pbnN0YWxsRmFpbGVkJywge1xyXG4gICAgICAgICAgdGl0bGU6IHRoaXMuY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUExVR0lOX0hBTkRMRVJfUExVR0lOX1VOSU5TVEFMTF9GQUlMRUQnKSxcclxuICAgICAgICAgIGJvZHk6IGVyclxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgY29uc3QgcmVzOiBJUGx1Z2luSGFuZGxlclJlc3VsdDxmYWxzZT4gPSB7XHJcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcclxuICAgICAgICAgIGJvZHk6IGVyclxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzXHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IGVyciA9IHRoaXMuY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUExVR0lOX0hBTkRMRVJfUExVR0lOX1VOSU5TVEFMTF9GQUlMRURfVkFMSUQnKVxyXG4gICAgICB0aGlzLmN0eC5sb2cuZXJyb3IoZXJyKVxyXG4gICAgICB0aGlzLmN0eC5lbWl0KCd1bmluc3RhbGxGYWlsZWQnLCB7XHJcbiAgICAgICAgdGl0bGU6IHRoaXMuY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUExVR0lOX0hBTkRMRVJfUExVR0lOX1VOSU5TVEFMTF9GQUlMRUQnKSxcclxuICAgICAgICBib2R5OiBlcnJcclxuICAgICAgfSlcclxuICAgICAgY29uc3QgcmVzOiBJUGx1Z2luSGFuZGxlclJlc3VsdDxmYWxzZT4gPSB7XHJcbiAgICAgICAgc3VjY2VzczogZmFsc2UsXHJcbiAgICAgICAgYm9keTogZXJyXHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHJlc1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYXN5bmMgdXBkYXRlIChwbHVnaW5zOiBzdHJpbmdbXSwgb3B0aW9uczogSVBsdWdpbkhhbmRsZXJPcHRpb25zID0ge30sIGVudj86IElQcm9jZXNzRW52KTogUHJvbWlzZTxJUGx1Z2luSGFuZGxlclJlc3VsdDxib29sZWFuPj4ge1xyXG4gICAgY29uc3QgcHJvY2Vzc1BsdWdpbnMgPSBwbHVnaW5zLm1hcCgoaXRlbTogc3RyaW5nKSA9PiBoYW5kbGVQbHVnaW5OYW1lUHJvY2Vzcyh0aGlzLmN0eCwgaXRlbSkpLmZpbHRlcihpdGVtID0+IGl0ZW0uc3VjY2VzcylcclxuICAgIGNvbnN0IHBrZ05hbWVMaXN0ID0gcHJvY2Vzc1BsdWdpbnMubWFwKGl0ZW0gPT4gaXRlbS5wa2dOYW1lKVxyXG4gICAgaWYgKHBrZ05hbWVMaXN0Lmxlbmd0aCA+IDApIHtcclxuICAgICAgLy8gdXBkYXRlIHBsdWdpbnMgbXVzdCB1c2UgcGtnTmFtZUxpc3Q6XHJcbiAgICAgIC8vIG5wbSB1cGRhdGUgd2lsbCB1c2UgdGhlIHBhY2thZ2UuanNvbidzIG5hbWVcclxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5leGVjQ29tbWFuZCgndXBkYXRlJywgcGtnTmFtZUxpc3QsIHRoaXMuY3R4LmJhc2VEaXIsIG9wdGlvbnMsIGVudilcclxuICAgICAgaWYgKCFyZXN1bHQuY29kZSkge1xyXG4gICAgICAgIHRoaXMuY3R4LmxvZy5zdWNjZXNzKHRoaXMuY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUExVR0lOX0hBTkRMRVJfUExVR0lOX1VQREFURV9TVUNDRVNTJykpXHJcbiAgICAgICAgdGhpcy5jdHguZW1pdCgndXBkYXRlU3VjY2VzcycsIHtcclxuICAgICAgICAgIHRpdGxlOiB0aGlzLmN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BMVUdJTl9IQU5ETEVSX1BMVUdJTl9VUERBVEVfU1VDQ0VTUycpLFxyXG4gICAgICAgICAgYm9keTogcGtnTmFtZUxpc3RcclxuICAgICAgICB9KVxyXG4gICAgICAgIGNvbnN0IHJlczogSVBsdWdpbkhhbmRsZXJSZXN1bHQ8dHJ1ZT4gPSB7XHJcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxyXG4gICAgICAgICAgYm9keTogcGtnTmFtZUxpc3RcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IGVyciA9IHRoaXMuY3R4LmkxOG4udHJhbnNsYXRlPElMb2NhbGVzS2V5PignUExVR0lOX0hBTkRMRVJfUExVR0lOX1VQREFURV9GQUlMRURfUkVBU09OJywge1xyXG4gICAgICAgICAgY29kZTogYCR7cmVzdWx0LmNvZGV9YCxcclxuICAgICAgICAgIGRhdGE6IHJlc3VsdC5kYXRhXHJcbiAgICAgICAgfSlcclxuICAgICAgICB0aGlzLmN0eC5sb2cuZXJyb3IoZXJyKVxyXG4gICAgICAgIHRoaXMuY3R4LmVtaXQoJ3VwZGF0ZUZhaWxlZCcsIHtcclxuICAgICAgICAgIHRpdGxlOiB0aGlzLmN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BMVUdJTl9IQU5ETEVSX1BMVUdJTl9VUERBVEVfRkFJTEVEJyksXHJcbiAgICAgICAgICBib2R5OiBlcnJcclxuICAgICAgICB9KVxyXG4gICAgICAgIGNvbnN0IHJlczogSVBsdWdpbkhhbmRsZXJSZXN1bHQ8ZmFsc2U+ID0ge1xyXG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXHJcbiAgICAgICAgICBib2R5OiBlcnJcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBlcnIgPSB0aGlzLmN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BMVUdJTl9IQU5ETEVSX1BMVUdJTl9VUERBVEVfRkFJTEVEX1ZBTElEJylcclxuICAgICAgdGhpcy5jdHgubG9nLmVycm9yKGVycilcclxuICAgICAgdGhpcy5jdHguZW1pdCgndXBkYXRlRmFpbGVkJywge1xyXG4gICAgICAgIHRpdGxlOiB0aGlzLmN0eC5pMThuLnRyYW5zbGF0ZTxJTG9jYWxlc0tleT4oJ1BMVUdJTl9IQU5ETEVSX1BMVUdJTl9VUERBVEVfRkFJTEVEJyksXHJcbiAgICAgICAgYm9keTogZXJyXHJcbiAgICAgIH0pXHJcbiAgICAgIGNvbnN0IHJlczogSVBsdWdpbkhhbmRsZXJSZXN1bHQ8ZmFsc2U+ID0ge1xyXG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxyXG4gICAgICAgIGJvZHk6IGVyclxyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiByZXNcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgZXhlY0NvbW1hbmQgKGNtZDogc3RyaW5nLCBtb2R1bGVzOiBzdHJpbmdbXSwgd2hlcmU6IHN0cmluZywgb3B0aW9uczogSVBsdWdpbkhhbmRsZXJPcHRpb25zID0ge30sIGVudjogSVByb2Nlc3NFbnYgPSB7fSk6IFByb21pc2U8SVJlc3VsdD4ge1xyXG4gICAgLy8gb3B0aW9ucyBmaXJzdFxyXG4gICAgY29uc3QgcmVnaXN0cnkgPSBvcHRpb25zLnJlZ2lzdHJ5IHx8IHRoaXMuY3R4LmdldENvbmZpZzxVbmRlZmluYWJsZTxzdHJpbmc+Pignc2V0dGluZ3MucmVnaXN0cnknKVxyXG4gICAgY29uc3QgcHJveHkgPSBvcHRpb25zLnByb3h5IHx8IHRoaXMuY3R4LmdldENvbmZpZzxVbmRlZmluYWJsZTxzdHJpbmc+Pignc2V0dGluZ3MucHJveHknKVxyXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlOiBhbnkpOiB2b2lkID0+IHtcclxuICAgICAgbGV0IGFyZ3MgPSBbY21kXS5jb25jYXQobW9kdWxlcykuY29uY2F0KCctLWNvbG9yPWFsd2F5cycpLmNvbmNhdCgnLS1zYXZlJylcclxuICAgICAgaWYgKHJlZ2lzdHJ5KSB7XHJcbiAgICAgICAgYXJncyA9IGFyZ3MuY29uY2F0KGAtLXJlZ2lzdHJ5PSR7cmVnaXN0cnl9YClcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJveHkpIHtcclxuICAgICAgICBhcmdzID0gYXJncy5jb25jYXQoYC0tcHJveHk9JHtwcm94eX1gKVxyXG4gICAgICB9XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgY29uc3QgbnBtID0gc3Bhd24oJ25wbScsIGFyZ3MsIHsgY3dkOiB3aGVyZSwgZW52OiBPYmplY3QuYXNzaWduKHt9LCBwcm9jZXNzLmVudiwgZW52KSB9KVxyXG5cclxuICAgICAgICBsZXQgb3V0cHV0ID0gJydcclxuICAgICAgICBucG0uc3Rkb3V0Py5vbignZGF0YScsIChkYXRhOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgIG91dHB1dCArPSBkYXRhXHJcbiAgICAgICAgfSkucGlwZShwcm9jZXNzLnN0ZG91dClcclxuXHJcbiAgICAgICAgbnBtLnN0ZGVycj8ub24oJ2RhdGEnLCAoZGF0YTogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgICBvdXRwdXQgKz0gZGF0YVxyXG4gICAgICAgIH0pLnBpcGUocHJvY2Vzcy5zdGRlcnIpXHJcblxyXG4gICAgICAgIG5wbS5vbignY2xvc2UnLCAoY29kZTogbnVtYmVyKSA9PiB7XHJcbiAgICAgICAgICBpZiAoIWNvZGUpIHtcclxuICAgICAgICAgICAgcmVzb2x2ZSh7IGNvZGU6IDAsIGRhdGE6IG91dHB1dCB9KVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmVzb2x2ZSh7IGNvZGU6IGNvZGUsIGRhdGE6IG91dHB1dCB9KVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLy8gZm9yIHVzZXJzIHdobyBoYXZlbid0IGluc3RhbGxlZCBub2RlLmpzXHJcbiAgICAgICAgbnBtLm9uKCdlcnJvcicsIChlcnI6IEVycm9yKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmN0eC5sb2cuZXJyb3IoZXJyKVxyXG4gICAgICAgICAgdGhpcy5jdHgubG9nLmVycm9yKCdOUE0gaXMgbm90IGluc3RhbGxlZCcpXHJcbiAgICAgICAgICB0aGlzLmN0eC5lbWl0KElCdWlsZEluRXZlbnQuRkFJTEVELCAnTlBNIGlzIG5vdCBpbnN0YWxsZWQnKVxyXG4gICAgICAgIH0pXHJcbiAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICB0aGlzLmN0eC5sb2cuZXJyb3IoZSBhcyBFcnJvcilcclxuICAgICAgICB0aGlzLmN0eC5lbWl0KElCdWlsZEluRXZlbnQuRkFJTEVELCBlKVxyXG4gICAgICB9XHJcbiAgICB9KVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIHRyYW5zZm9ybSB0aGUgaW5wdXQgcGx1Z2luIG5hbWUgb3IgcGF0aCBzdHJpbmcgdG8gdmFsaWQgcmVzdWx0XHJcbiAqIEBwYXJhbSBjdHhcclxuICogQHBhcmFtIG5hbWVPclBhdGhcclxuICovXHJcbmNvbnN0IGhhbmRsZVBsdWdpbk5hbWVQcm9jZXNzID0gKGN0eDogSVBpY0dvLCBuYW1lT3JQYXRoOiBzdHJpbmcpOiBJUGx1Z2luUHJvY2Vzc1Jlc3VsdCA9PiB7XHJcbiAgY29uc3QgcmVzID0ge1xyXG4gICAgc3VjY2VzczogZmFsc2UsXHJcbiAgICBmdWxsTmFtZTogJycsXHJcbiAgICBwa2dOYW1lOiAnJ1xyXG4gIH1cclxuICBjb25zdCByZXN1bHQgPSBnZXRQcm9jZXNzUGx1Z2luTmFtZShuYW1lT3JQYXRoLCBjdHgubG9nKVxyXG4gIGlmICghcmVzdWx0KSB7XHJcbiAgICByZXR1cm4gcmVzXHJcbiAgfVxyXG4gIC8vIGZpcnN0IGdldCByZXN1bHQgdGhlbiBkbyB0aGlzIHByb2Nlc3NcclxuICAvLyBvciBzb21lIGVycm9yIHdpbGwgbG9nIHR3aWNlXHJcbiAgY29uc3QgcGtnTmFtZSA9IGdldE5vcm1hbFBsdWdpbk5hbWUocmVzdWx0LCBjdHgubG9nKVxyXG4gIGlmICghcGtnTmFtZSkge1xyXG4gICAgcmV0dXJuIHJlc1xyXG4gIH1cclxuICByZXR1cm4ge1xyXG4gICAgc3VjY2VzczogdHJ1ZSxcclxuICAgIGZ1bGxOYW1lOiByZXN1bHQsXHJcbiAgICBwa2dOYW1lXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBQbHVnaW5IYW5kbGVyXHJcbiIsIi8qIGVzbGludC1kaXNhYmxlIG5vLXRlbXBsYXRlLWN1cmx5LWluLXN0cmluZyAqL1xyXG5leHBvcnQgY29uc3QgWkhfQ04gPSB7XHJcbiAgVVBMT0FEX0ZBSUxFRDogJ+S4iuS8oOWksei0pScsXHJcbiAgQ0hFQ0tfU0VUVElOR1M6ICfor7fmo4Dmn6XkvaDnmoTphY3nva7pobnmmK/lkKbmraPnoa4nLFxyXG4gIENIRUNLX1NFVFRJTkdTX0FORF9ORVRXT1JLOiAn6K+35qOA5p+l5L2g55qE6YWN572u6aG55Lul5Y+K572R57ucJyxcclxuICBVUExPQURfRkFJTEVEX1JFQVNPTjogJ+mUmeivr+egge+8miR7Y29kZX3vvIzor7fmiZPlvIDmtY/op4jlmajnspjotLTlnLDlnYDmn6XnnIvnm7jlhbPljp/lm6AnLFxyXG4gIFNFUlZFUl9FUlJPUjogJ+acjeWKoeerr+WHuumUme+8jOivt+mHjeivlScsXHJcbiAgQVVUSF9GQUlMRUQ6ICforqTor4HlpLHotKUnLFxyXG5cclxuICAvLyBzbW1zXHJcbiAgUElDQkVEX1NNTVM6ICdTTS5NUycsXHJcbiAgUElDQkVEX1NNTVNfVE9LRU46ICforr7lrppUb2tlbicsXHJcbiAgUElDQkVEX1NNTVNfQkFDS1VQX0RPTUFJTjogJ+Wkh+eUqOS4iuS8oOWfn+WQjScsXHJcbiAgUElDQkVEX1NNTVNfTUVTU0FHRV9CQUNLVVBfRE9NQUlOOiAn5L6L5aaCIHNtbXMuYXBwJyxcclxuXHJcbiAgLy8gQWxpLWNsb3VkXHJcbiAgUElDQkVEX0FMSUNMT1VEOiAn6Zi/6YeM5LqRT1NTJyxcclxuICBQSUNCRURfQUxJQ0xPVURfQUNDRVNTS0VZSUQ6ICforr7lrppLZXlJZCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX0FDQ0VTU0tFWVNFQ1JFVDogJ+iuvuWumktleVNlY3JldCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX0JVQ0tFVDogJ+iuvuWumkJ1Y2tldCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX0FSRUE6ICforr7lrprlrZjlgqjljLrln58nLFxyXG4gIFBJQ0JFRF9BTElDTE9VRF9QQVRIOiAn6K6+5a6a5a2Y5YKo6Lev5b6EJyxcclxuICBQSUNCRURfQUxJQ0xPVURfQ1VTVE9NVVJMOiAn6K6+5a6a6Ieq5a6a5LmJ5Z+f5ZCNJyxcclxuICBQSUNCRURfQUxJQ0xPVURfT1BUSU9OUzogJ+iuvuWumue9keWdgOWQjue8gCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX01FU1NBR0VfQVJFQTogJ+S+i+Wmgu+8mm9zcy1jbi1iZWlqaW5nJyxcclxuICBQSUNCRURfQUxJQ0xPVURfTUVTU0FHRV9QQVRIOiAn5L6L5aaC77yadGVzdC8nLFxyXG4gIFBJQ0JFRF9BTElDTE9VRF9NRVNTQUdFX09QVElPTlM6ICfkvovlpoLvvJo/eC1vc3MtcHJvY2Vzcz14eHgnLFxyXG4gIFBJQ0JFRF9BTElDTE9VRF9NRVNTQUdFX0NVU1RPTVVSTDogJ+S+i+Wmgu+8mmh0dHBzOi8vdGVzdC5jb20nLFxyXG5cclxuICAvLyBUZW5jZW50LWNsb3VkXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRDogJ+iFvuiur+S6kUNPUycsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9WRVJTSU9OOiAnQ09T54mI5pysJyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX1NFQ1JFVElEOiAn6K6+5a6aU2VjcmV0SWQnLFxyXG4gIFBJQ0JFRF9URU5DRU5UQ0xPVURfU0VDUkVUS0VZOiAn6K6+5a6aU2VjcmV0S2V5JyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX0FQUElEOiAn6K6+5a6aQXBwSWQnLFxyXG4gIFBJQ0JFRF9URU5DRU5UQ0xPVURfQlVDS0VUOiAn6K6+5a6aQnVja2V0JyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX0FSRUE6ICforr7lrprlrZjlgqjljLrln58nLFxyXG4gIFBJQ0JFRF9URU5DRU5UQ0xPVURfUEFUSDogJ+iuvuWumuWtmOWCqOi3r+W+hCcsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9PUFRJT05TOiAn6K6+5a6a572R5Z2A5ZCO57yAJyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX0NVU1RPTVVSTDogJ+iuvuWumuiHquWumuS5ieWfn+WQjScsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9NRVNTQUdFX0FQUElEOiAn5L6L5aaC77yaMTIzNDU2Nzg5MCcsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9NRVNTQUdFX0FSRUE6ICfkvovlpoLvvJphcC1iZWlqaW5nJyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX01FU1NBR0VfUEFUSDogJ+S+i+Wmgu+8mnRlc3QvJyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX01FU1NBR0VfQ1VTVE9NVVJMOiAn5L6L5aaC77yaaHR0cHM6Ly90ZXN0LmNvbScsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9NRVNTQUdFX09QVElPTlM6ICfkvovlpoLvvJo/aW1hZ2VNb2dyMicsXHJcblxyXG4gIC8vIEdpdEh1YlxyXG4gIFBJQ0JFRF9HSVRIVUI6ICdHaXRIdWInLFxyXG4gIFBJQ0JFRF9HSVRIVUJfVE9LRU46ICforr7lrppUb2tlbicsXHJcbiAgUElDQkVEX0dJVEhVQl9SRVBPOiAn6K6+5a6a5LuT5bqT5ZCNJyxcclxuICBQSUNCRURfR0lUSFVCX1BBVEg6ICforr7lrprlrZjlgqjot6/lvoQnLFxyXG4gIFBJQ0JFRF9HSVRIVUJfQlJBTkNIOiAn6K6+5a6a5YiG5pSv5ZCNJyxcclxuICBQSUNCRURfR0lUSFVCX0NVU1RPTVVSTDogJ+iuvuWumuiHquWumuS5ieWfn+WQjScsXHJcbiAgUElDQkVEX0dJVEhVQl9NRVNTQUdFX1JFUE86ICfmoLzlvI/vvJp1c2VybmFtZS9yZXBvJyxcclxuICBQSUNCRURfR0lUSFVCX01FU1NBR0VfQlJBTkNIOiAn5L6L5aaC77yabWFpbicsXHJcbiAgUElDQkVEX0dJVEhVQl9NRVNTQUdFX1BBVEg6ICfkvovlpoLvvJp0ZXN0LycsXHJcbiAgUElDQkVEX0dJVEhVQl9NRVNTQUdFX0NVU1RPTVVSTDogJ+S+i+Wmgu+8mmh0dHBzOi8vdGVzdC5jb20nLFxyXG5cclxuICAvLyBxaW5pdVxyXG4gIFBJQ0JFRF9RSU5JVTogJ+S4g+eJm+S6kScsXHJcbiAgUElDQkVEX1FJTklVX0FDQ0VTU0tFWTogJ+iuvuWumkFjY2Vzc0tleScsXHJcbiAgUElDQkVEX1FJTklVX1NFQ1JFVEtFWTogJ+iuvuWumlNlY3JldEtleScsXHJcbiAgUElDQkVEX1FJTklVX0JVQ0tFVDogJ+iuvuWumkJ1Y2tldCcsXHJcbiAgUElDQkVEX1FJTklVX1BBVEg6ICforr7lrprlrZjlgqjot6/lvoQnLFxyXG4gIFBJQ0JFRF9RSU5JVV9VUkw6ICforr7lrprorr/pl67nvZHlnYAnLFxyXG4gIFBJQ0JFRF9RSU5JVV9PUFRJT05TOiAn6K6+5a6a572R5Z2A5ZCO57yAJyxcclxuICBQSUNCRURfUUlOSVVfQVJFQTogJ+iuvuWumuWtmOWCqOWMuuWfnycsXHJcbiAgUElDQkVEX1FJTklVX01FU1NBR0VfUEFUSDogJ+S+i+Wmgu+8mnRlc3QvJyxcclxuICBQSUNCRURfUUlOSVVfTUVTU0FHRV9BUkVBOiAn5L6L5aaC77yaejAnLFxyXG4gIFBJQ0JFRF9RSU5JVV9NRVNTQUdFX09QVElPTlM6ICfkvovlpoLvvJo/aW1hZ2VzbGltJyxcclxuICBQSUNCRURfUUlOSVVfTUVTU0FHRV9VUkw6ICfkvovlpoLvvJpodHRwczovL3h4eC55eXkuZ2xiLmNsb3VkZG4uY29tJyxcclxuXHJcbiAgLy8gaW1ndXJcclxuICBQSUNCRURfSU1HVVI6ICdJbWd1cicsXHJcbiAgUElDQkVEX0lNR1VSX0NMSUVOVElEOiAn6K6+5a6aQ2xpZW50SWQnLFxyXG4gIFBJQ0JFRF9JTUdVUl9QUk9YWTogJ+iuvuWumuS7o+eQhicsXHJcbiAgUElDQkVEX0lNR1VSX01FU1NBR0VfUFJPWFk6ICfkvovlpoLvvJpodHRwOi8vMTI3LjAuMC4xOjEwODAnLFxyXG5cclxuICAvLyB1cHl1blxyXG4gIFBJQ0JFRF9VUFlVTjogJ+WPiOaLjeS6kScsXHJcbiAgUElDQkVEX1VQWVVOX0JVQ0tFVDogJ+iuvuWumkJ1Y2tldCcsXHJcbiAgUElDQkVEX1VQWVVOX09QRVJBVE9SOiAn6K6+5a6a5pON5L2c5ZGYJyxcclxuICBQSUNCRURfVVBZVU5fUEFTU1dPUkQ6ICforr7lrprmk43kvZzlkZjlr4bnoIEnLFxyXG4gIFBJQ0JFRF9VUFlVTl9QQVRIOiAn6K6+5a6a5a2Y5YKo6Lev5b6EJyxcclxuICBQSUNCRURfVVBZVU5fVVJMOiAn6K6+5a6a5Yqg6YCf5Z+f5ZCNJyxcclxuICBQSUNCRURfVVBZVU5fT1BUSU9OUzogJ+iuvuWumue9keWdgOWQjue8gCcsXHJcbiAgUElDQkVEX1VQWVVOX01FU1NBR0VfT1BFUkFUT1I6ICfkvovlpoLvvJptZScsXHJcbiAgUElDQkVEX1VQWVVOX01FU1NBR0VfUEFTU1dPUkQ6ICfovpPlhaXmk43kvZzlkZjlr4bnoIEnLFxyXG4gIFBJQ0JFRF9VUFlVTl9NRVNTQUdFX1VSTDogJ+S+i+Wmgu+8mmh0dHA6Ly94eHgudGVzdC51cGNkbi5uZXQnLFxyXG4gIFBJQ0JFRF9VUFlVTl9NRVNTQUdFX09QVElPTlM6ICfkvovlpoLvvJohaW1nc2xpbScsXHJcbiAgUElDQkVEX1VQWVVOX01FU1NBR0VfUEFUSDogJ+S+i+Wmgu+8mnRlc3QvJyxcclxuXHJcbiAgLy8gUGx1Z2luIEhhbmRsZXJcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fSU5TVEFMTF9TVUNDRVNTOiAn5o+S5Lu25a6J6KOF5oiQ5YqfJyxcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fSU5TVEFMTF9GQUlMRUQ6ICfmj5Lku7blronoo4XlpLHotKUnLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9JTlNUQUxMX0ZBSUxFRF9SRUFTT046ICfmj5Lku7blronoo4XlpLHotKXvvIzlpLHotKXnoIHkuLoke2NvZGV977yM6ZSZ6K+v5pel5b+X5Li6IFxcbiAke2RhdGF9JyxcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fSU5TVEFMTF9GQUlMRURfUEFUSDogJ+aPkuS7tuWuieijheWksei0pe+8jOivt+i+k+WFpeWQiOazleaPkuS7tuWQjeaIluWQiOazleWuieijhei3r+W+hCcsXHJcbiAgUExVR0lOX0hBTkRMRVJfUExVR0lOX1VOSU5TVEFMTF9TVUNDRVNTOiAn5o+S5Lu25Y246L295oiQ5YqfJyxcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fVU5JTlNUQUxMX0ZBSUxFRDogJ+aPkuS7tuWNuOi9veWksei0pScsXHJcbiAgUExVR0lOX0hBTkRMRVJfUExVR0lOX1VOSU5TVEFMTF9GQUlMRURfUkVBU09OOiAn5o+S5Lu25Y246L295aSx6LSl77yM5aSx6LSl56CB5Li6JHtjb2Rlfe+8jOmUmeivr+aXpeW/l+S4uiBcXG4gJHtkYXRhfScsXHJcbiAgUExVR0lOX0hBTkRMRVJfUExVR0lOX1VOSU5TVEFMTF9GQUlMRURfVkFMSUQ6ICfmj5Lku7bljbjovb3lpLHotKXvvIzor7fovpPlhaXlkIjms5Xmj5Lku7blkI0nLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9VUERBVEVfU1VDQ0VTUzogJ+aPkuS7tuabtOaWsOaIkOWKnycsXHJcbiAgUExVR0lOX0hBTkRMRVJfUExVR0lOX1VQREFURV9GQUlMRUQ6ICfmj5Lku7bmm7TmlrDlpLHotKUnLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9VUERBVEVfRkFJTEVEX1JFQVNPTjogJ+aPkuS7tuabtOaWsOWksei0pe+8jOWksei0peeggeS4uiR7Y29kZX3vvIzplJnor6/ml6Xlv5fkuLogXFxuICR7ZGF0YX0nLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9VUERBVEVfRkFJTEVEX1ZBTElEOiAn5o+S5Lu25pu05paw5aSx6LSl77yM6K+36L6T5YWl5ZCI5rOV5o+S5Lu25ZCNJ1xyXG59XHJcblxyXG5leHBvcnQgdHlwZSBJTG9jYWxlc0tleSA9IGtleW9mIHR5cGVvZiBaSF9DTlxyXG5leHBvcnQgdHlwZSBJTG9jYWxlcyA9IHR5cGVvZiBaSF9DTlxyXG4iLCJpbXBvcnQgeyBJTG9jYWxlcyB9IGZyb20gJy4vemgtQ04nXHJcblxyXG4vKiBlc2xpbnQtZGlzYWJsZSBuby10ZW1wbGF0ZS1jdXJseS1pbi1zdHJpbmcgKi9cclxuZXhwb3J0IGNvbnN0IEVOOiBJTG9jYWxlcyA9IHtcclxuICBVUExPQURfRkFJTEVEOiAnVXBsb2FkIGZhaWxlZCcsXHJcbiAgQ0hFQ0tfU0VUVElOR1M6ICdQbGVhc2UgY2hlY2sgeW91ciBzZXR0aW5ncycsXHJcbiAgQ0hFQ0tfU0VUVElOR1NfQU5EX05FVFdPUks6ICdQbGVhc2UgY2hlY2sgeW91ciBzZXR0aW5ncyBhbmQgbmV0d29yaycsXHJcbiAgVVBMT0FEX0ZBSUxFRF9SRUFTT046ICdFcnJvciBjb2RlOiAke2NvZGV9LCBwbGVhc2Ugb3BlbiB0aGUgYnJvd3NlciBhbmQgcGFzdGUgdGhlIGFkZHJlc3MgdG8gc2VlIHRoZSByZWFzb24nLFxyXG4gIFNFUlZFUl9FUlJPUjogJ1NlcnZlciBlcnJvciwgcGxlYXNlIHRyeSBhZ2FpbiBsYXRlcicsXHJcbiAgQVVUSF9GQUlMRUQ6ICdBdXRoZW50aWNhdGlvbiBmYWlsZWQnLFxyXG5cclxuICAvLyBzbW1zXHJcbiAgUElDQkVEX1NNTVM6ICdTTS5NUycsXHJcbiAgUElDQkVEX1NNTVNfVE9LRU46ICdTZXQgVG9rZW4nLFxyXG4gIFBJQ0JFRF9TTU1TX0JBQ0tVUF9ET01BSU46ICdTZXQgQmFja3VwIFVwbG9hZCBEb21haW4nLFxyXG4gIFBJQ0JFRF9TTU1TX01FU1NBR0VfQkFDS1VQX0RPTUFJTjogJ0V4LiBzbW1zLmFwcCcsXHJcblxyXG4gIC8vIEFsaS1jbG91ZFxyXG4gIFBJQ0JFRF9BTElDTE9VRDogJ0FsaSBDbG91ZCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX0FDQ0VTU0tFWUlEOiAnU2V0IEtleUlkJyxcclxuICBQSUNCRURfQUxJQ0xPVURfQUNDRVNTS0VZU0VDUkVUOiAnU2V0IEtleVNlY3JldCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX0JVQ0tFVDogJ1NldCBCdWNrZXQnLFxyXG4gIFBJQ0JFRF9BTElDTE9VRF9BUkVBOiAnU2V0IEFyZWEnLFxyXG4gIFBJQ0JFRF9BTElDTE9VRF9QQVRIOiAnU2V0IFBhdGgnLFxyXG4gIFBJQ0JFRF9BTElDTE9VRF9DVVNUT01VUkw6ICdTZXQgQ3VzdG9tIFVSTCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX09QVElPTlM6ICdTZXQgVVJMIFN1ZmZpeCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX01FU1NBR0VfQVJFQTogJ0V4LiBvc3MtY24tYmVpamluZycsXHJcbiAgUElDQkVEX0FMSUNMT1VEX01FU1NBR0VfUEFUSDogJ0V4LiB0ZXN0LycsXHJcbiAgUElDQkVEX0FMSUNMT1VEX01FU1NBR0VfT1BUSU9OUzogJ0V4LiA/eC1vc3MtcHJvY2Vzcz14eHgnLFxyXG4gIFBJQ0JFRF9BTElDTE9VRF9NRVNTQUdFX0NVU1RPTVVSTDogJ0V4LiBodHRwczovL3Rlc3QuY29tJyxcclxuXHJcbiAgLy8gVGVuY2VudC1jbG91ZFxyXG4gIFBJQ0JFRF9URU5DRU5UQ0xPVUQ6ICdUZW5jZW50IENsb3VkJyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX1ZFUlNJT046ICdDaG9vc2UgQ09TIHZlcnNpb24nLFxyXG4gIFBJQ0JFRF9URU5DRU5UQ0xPVURfU0VDUkVUSUQ6ICdTZXQgU2VjcmV0SWQnLFxyXG4gIFBJQ0JFRF9URU5DRU5UQ0xPVURfU0VDUkVUS0VZOiAnU2V0IFNlY3JldEtleScsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9BUFBJRDogJ1NldCBBcHBJZCcsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9CVUNLRVQ6ICdTZXQgQnVja2V0JyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX0FSRUE6ICdTZXQgQXJlYScsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9QQVRIOiAnU2V0IFBhdGgnLFxyXG4gIFBJQ0JFRF9URU5DRU5UQ0xPVURfT1BUSU9OUzogJ1NldCBVUkwgU3VmZml4JyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX0NVU1RPTVVSTDogJ1NldCBDdXN0b20gVVJMJyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX01FU1NBR0VfQVBQSUQ6ICdFeC4gMTIzNDU2Nzg5MCcsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9NRVNTQUdFX0FSRUE6ICdFeC4gYXAtYmVpamluZycsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9NRVNTQUdFX1BBVEg6ICdFeC4gdGVzdC8nLFxyXG4gIFBJQ0JFRF9URU5DRU5UQ0xPVURfTUVTU0FHRV9DVVNUT01VUkw6ICdFeC4gaHR0cDovL3Rlc3QuY29tJyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX01FU1NBR0VfT1BUSU9OUzogJ0V4LiA/aW1hZ2VNb2dyMicsXHJcblxyXG4gIC8vIEdpdEh1YlxyXG4gIFBJQ0JFRF9HSVRIVUI6ICdHaXRIdWInLFxyXG4gIFBJQ0JFRF9HSVRIVUJfVE9LRU46ICdTZXQgVG9rZW4nLFxyXG4gIFBJQ0JFRF9HSVRIVUJfUkVQTzogJ1NldCBSZXBvIE5hbWUnLFxyXG4gIFBJQ0JFRF9HSVRIVUJfUEFUSDogJ1NldCBQYXRoJyxcclxuICBQSUNCRURfR0lUSFVCX0JSQU5DSDogJ1NldCBCcmFuY2gnLFxyXG4gIFBJQ0JFRF9HSVRIVUJfQ1VTVE9NVVJMOiAnU2V0IEN1c3RvbSBVUkwnLFxyXG4gIFBJQ0JFRF9HSVRIVUJfTUVTU0FHRV9SRVBPOiAnRXguIHVzZXJuYW1lL3JlcG8nLFxyXG4gIFBJQ0JFRF9HSVRIVUJfTUVTU0FHRV9CUkFOQ0g6ICdFeC4gbWFpbicsXHJcbiAgUElDQkVEX0dJVEhVQl9NRVNTQUdFX1BBVEg6ICdFeC4gdGVzdC8nLFxyXG4gIFBJQ0JFRF9HSVRIVUJfTUVTU0FHRV9DVVNUT01VUkw6ICdFeC4gaHR0cHM6Ly90ZXN0LmNvbScsXHJcblxyXG4gIC8vIHFpbml1XHJcbiAgUElDQkVEX1FJTklVOiAnUWluaXUnLFxyXG4gIFBJQ0JFRF9RSU5JVV9BQ0NFU1NLRVk6ICdTZXQgQWNjZXNzS2V5JyxcclxuICBQSUNCRURfUUlOSVVfU0VDUkVUS0VZOiAnU2V0IFNlY3JldEtleScsXHJcbiAgUElDQkVEX1FJTklVX0JVQ0tFVDogJ1NldCBCdWNrZXQnLFxyXG4gIFBJQ0JFRF9RSU5JVV9QQVRIOiAnU2V0IFBhdGgnLFxyXG4gIFBJQ0JFRF9RSU5JVV9VUkw6ICdTZXQgVVJMJyxcclxuICBQSUNCRURfUUlOSVVfT1BUSU9OUzogJ1NldCBVUkwgU3VmZml4JyxcclxuICBQSUNCRURfUUlOSVVfQVJFQTogJ1NldCBBcmVhJyxcclxuICBQSUNCRURfUUlOSVVfTUVTU0FHRV9QQVRIOiAnRXguIHRlc3QvJyxcclxuICBQSUNCRURfUUlOSVVfTUVTU0FHRV9BUkVBOiAnRXguIHowJyxcclxuICBQSUNCRURfUUlOSVVfTUVTU0FHRV9PUFRJT05TOiAnRXguID9pbWFnZXNsaW0nLFxyXG4gIFBJQ0JFRF9RSU5JVV9NRVNTQUdFX1VSTDogJ0V4LiBodHRwczovL3h4eC55eXkuZ2xiLmNsb3VkZG4uY29tJyxcclxuXHJcbiAgLy8gaW1ndXJcclxuICBQSUNCRURfSU1HVVI6ICdJbWd1cicsXHJcbiAgUElDQkVEX0lNR1VSX0NMSUVOVElEOiAnU2V0IENsaWVudElkJyxcclxuICBQSUNCRURfSU1HVVJfUFJPWFk6ICdTZXQgUHJveHknLFxyXG4gIFBJQ0JFRF9JTUdVUl9NRVNTQUdFX1BST1hZOiAnRXguIGh0dHA6Ly8xMjcuMC4wLjE6MTA4MCcsXHJcblxyXG4gIC8vIHVweXVuXHJcbiAgUElDQkVEX1VQWVVOOiAnVXB5dW4nLFxyXG4gIFBJQ0JFRF9VUFlVTl9CVUNLRVQ6ICdTZXQgQnVja2V0JyxcclxuICBQSUNCRURfVVBZVU5fT1BFUkFUT1I6ICdTZXQgT3BlcmF0b3InLFxyXG4gIFBJQ0JFRF9VUFlVTl9QQVNTV09SRDogJ1NldCBPcGVyYXRvciBQYXNzd29yZCcsXHJcbiAgUElDQkVEX1VQWVVOX1BBVEg6ICdTZXQgUGF0aCcsXHJcbiAgUElDQkVEX1VQWVVOX1VSTDogJ1NldCBVUkwnLFxyXG4gIFBJQ0JFRF9VUFlVTl9PUFRJT05TOiAnU2V0IFVSTCBTdWZmaXgnLFxyXG4gIFBJQ0JFRF9VUFlVTl9NRVNTQUdFX09QRVJBVE9SOiAnRXguIG1lJyxcclxuICBQSUNCRURfVVBZVU5fTUVTU0FHRV9QQVNTV09SRDogJ1BsZWFzZSB0eXBlIHRoZSBvcGVyYXRvciBwYXNzd29yZCcsXHJcbiAgUElDQkVEX1VQWVVOX01FU1NBR0VfVVJMOiAnRXguIGh0dHA6Ly94eHgudGVzdC51cGNkbi5uZXQnLFxyXG4gIFBJQ0JFRF9VUFlVTl9NRVNTQUdFX09QVElPTlM6ICdFeC4gIWltZ3NsaW0nLFxyXG4gIFBJQ0JFRF9VUFlVTl9NRVNTQUdFX1BBVEg6ICdFeC4gdGVzdC8nLFxyXG5cclxuICAvLyBQbHVnaW4gSGFuZGxlclxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9JTlNUQUxMX1NVQ0NFU1M6ICdQbHVnaW4gaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseScsXHJcbiAgUExVR0lOX0hBTkRMRVJfUExVR0lOX0lOU1RBTExfRkFJTEVEOiAnUGx1Z2luIGluc3RhbGxhdGlvbiBmYWlsZWQnLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9JTlNUQUxMX0ZBSUxFRF9SRUFTT046ICdQbHVnaW4gaW5zdGFsbGF0aW9uIGZhaWxlZCwgZXJyb3IgY29kZSBpcyAke2NvZGV9LCBlcnJvciBsb2cgaXMgXFxuICR7ZGF0YX0nLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9JTlNUQUxMX0ZBSUxFRF9QQVRIOiAnUGx1Z2luIGluc3RhbGxhdGlvbiBmYWlsZWQsIHBsZWFzZSBlbnRlciBhIHZhbGlkIHBsdWdpbiBuYW1lIG9yIHZhbGlkIGluc3RhbGxhdGlvbiBwYXRoJyxcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fVU5JTlNUQUxMX1NVQ0NFU1M6ICdQbHVnaW4gdW5pbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5JyxcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fVU5JTlNUQUxMX0ZBSUxFRDogJ1BsdWdpbiB1bmluc3RhbGwgZmFpbGVkJyxcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fVU5JTlNUQUxMX0ZBSUxFRF9SRUFTT046ICdQbHVnaW4gdW5pbnN0YWxsIGZhaWxlZCwgZXJyb3IgY29kZSBpcyAke2NvZGV9LCBlcnJvciBsb2cgaXMgXFxuICR7ZGF0YX0nLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9VTklOU1RBTExfRkFJTEVEX1ZBTElEOiAnUGx1Z2luIHVuaW5zdGFsbCBmYWlsZWQsIHBsZWFzZSBlbnRlciBhIHZhbGlkIHBsdWdpbiBuYW1lJyxcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fVVBEQVRFX1NVQ0NFU1M6ICdQbHVnaW4gdXBkYXRlZCBzdWNjZXNzZnVsbHknLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9VUERBVEVfRkFJTEVEOiAnUGx1Z2luIHVwZGF0ZSBmYWlsZWQnLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9VUERBVEVfRkFJTEVEX1JFQVNPTjogJ1BsdWdpbiB1cGRhdGUgZmFpbGVkLCBlcnJvciBjb2RlIGlzICR7Y29kZX0sIGVycm9yIGxvZyBpcyBcXG4gJHtkYXRhfScsXHJcbiAgUExVR0lOX0hBTkRMRVJfUExVR0lOX1VQREFURV9GQUlMRURfVkFMSUQ6ICdQbHVnaW4gdXBkYXRlIGZhaWxlZCwgcGxlYXNlIGVudGVyIGEgdmFsaWQgcGx1Z2luIG5hbWUnXHJcbn1cclxuIiwiaW1wb3J0IHsgSUxvY2FsZXMgfSBmcm9tICcuL3poLUNOJ1xyXG5cclxuLyogZXNsaW50LWRpc2FibGUgbm8tdGVtcGxhdGUtY3VybHktaW4tc3RyaW5nICovXHJcbmV4cG9ydCBjb25zdCBaSF9UVzogSUxvY2FsZXMgPSB7XHJcbiAgVVBMT0FEX0ZBSUxFRDogJ+S4iuWCs+WkseaVlycsXHJcbiAgQ0hFQ0tfU0VUVElOR1M6ICfoq4vmqqLmn6XkvaDnmoToqK3lrprmmK/lkKbmraPnoronLFxyXG4gIENIRUNLX1NFVFRJTkdTX0FORF9ORVRXT1JLOiAn6KuL5qqi5p+l5L2g55qE6Kit5a6a5Y+K57ay6LevJyxcclxuICBVUExPQURfRkFJTEVEX1JFQVNPTjogJ+mMr+iqpOeivO+8miR7Y29kZX3vvIzoq4vmiZPplovngI/opr3lmajosrzkuIrlnLDlnYDmn6XnnIvnm7jpl5zljp/lm6AnLFxyXG4gIFNFUlZFUl9FUlJPUjogJ+S8uuacjeWZqOWHuumMr++8jOiri+mHjeippicsXHJcbiAgQVVUSF9GQUlMRUQ6ICfoqo3orYnlpLHmlZcnLFxyXG5cclxuICAvLyBzbW1zXHJcbiAgUElDQkVEX1NNTVM6ICdTTS5NUycsXHJcbiAgUElDQkVEX1NNTVNfVE9LRU46ICfoqK3lrppUb2tlbicsXHJcbiAgUElDQkVEX1NNTVNfQkFDS1VQX0RPTUFJTjogJ+WCmeeUqOS4iuWCs+e2suWdgCcsXHJcbiAgUElDQkVEX1NNTVNfTUVTU0FHRV9CQUNLVVBfRE9NQUlOOiAn5L6L5aaCIHNtbXMuYXBwJyxcclxuXHJcbiAgLy8gQWxpLWNsb3VkXHJcbiAgUElDQkVEX0FMSUNMT1VEOiAn6Zi/6YeM5LqRT1NTJyxcclxuICBQSUNCRURfQUxJQ0xPVURfQUNDRVNTS0VZSUQ6ICfoqK3lrppLZXlJZCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX0FDQ0VTU0tFWVNFQ1JFVDogJ+ioreWumktleVNlY3JldCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX0JVQ0tFVDogJ+ioreWumkJ1Y2tldCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX0FSRUE6ICfoqK3lrprlhLLlrZjljYDln58nLFxyXG4gIFBJQ0JFRF9BTElDTE9VRF9QQVRIOiAn6Kit5a6a5YSy5a2Y6Lev5b6RJyxcclxuICBQSUNCRURfQUxJQ0xPVURfQ1VTVE9NVVJMOiAn6Kit5a6a6Ieq6KiC57ay5Z2AJyxcclxuICBQSUNCRURfQUxJQ0xPVURfT1BUSU9OUzogJ+ioreWumue2suWdgOW+jOe2tCcsXHJcbiAgUElDQkVEX0FMSUNMT1VEX01FU1NBR0VfQVJFQTogJ+S+i+Wmgu+8mm9zcy1jbi1iZWlqaW5nJyxcclxuICBQSUNCRURfQUxJQ0xPVURfTUVTU0FHRV9QQVRIOiAn5L6L5aaC77yadGVzdC8nLFxyXG4gIFBJQ0JFRF9BTElDTE9VRF9NRVNTQUdFX09QVElPTlM6ICfkvovlpoLvvJo/eC1vc3MtcHJvY2Vzcz14eHgnLFxyXG4gIFBJQ0JFRF9BTElDTE9VRF9NRVNTQUdFX0NVU1RPTVVSTDogJ+S+i+Wmgu+8mmh0dHBzOi8vdGVzdC5jb20nLFxyXG5cclxuICAvLyBUZW5jZW50LWNsb3VkXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRDogJ+mosOioiuS6kUNPUycsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9WRVJTSU9OOiAnQ09T54mI5pysJyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX1NFQ1JFVElEOiAn6Kit5a6aU2VjcmV0SWQnLFxyXG4gIFBJQ0JFRF9URU5DRU5UQ0xPVURfU0VDUkVUS0VZOiAn6Kit5a6aU2VjcmV0S2V5JyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX0FQUElEOiAn6Kit5a6aQXBwSWQnLFxyXG4gIFBJQ0JFRF9URU5DRU5UQ0xPVURfQlVDS0VUOiAn6Kit5a6aQnVja2V0JyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX0FSRUE6ICfoqK3lrprlhLLlrZjljYDln58nLFxyXG4gIFBJQ0JFRF9URU5DRU5UQ0xPVURfUEFUSDogJ+ioreWumuWEsuWtmOi3r+W+kScsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9PUFRJT05TOiAn6Kit5a6a57ay5Z2A5b6M57a0JyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX0NVU1RPTVVSTDogJ+ioreWumuiHquiogue2suWdgCcsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9NRVNTQUdFX0FQUElEOiAn5L6L5aaC77yaMTIzNDU2Nzg5MCcsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9NRVNTQUdFX0FSRUE6ICfkvovlpoLvvJphcC1iZWlqaW5nJyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX01FU1NBR0VfUEFUSDogJ+S+i+Wmgu+8mnRlc3QvJyxcclxuICBQSUNCRURfVEVOQ0VOVENMT1VEX01FU1NBR0VfQ1VTVE9NVVJMOiAn5L6L5aaC77yaaHR0cHM6Ly90ZXN0LmNvbScsXHJcbiAgUElDQkVEX1RFTkNFTlRDTE9VRF9NRVNTQUdFX09QVElPTlM6ICfkvovlpoLvvJo/aW1hZ2VNb2dyMicsXHJcblxyXG4gIC8vIEdpdEh1YlxyXG4gIFBJQ0JFRF9HSVRIVUI6ICdHaXRIdWInLFxyXG4gIFBJQ0JFRF9HSVRIVUJfVE9LRU46ICfoqK3lrppUb2tlbicsXHJcbiAgUElDQkVEX0dJVEhVQl9SRVBPOiAn6Kit5a6a5YCJ5bqr5ZCN56ixJyxcclxuICBQSUNCRURfR0lUSFVCX1BBVEg6ICfoqK3lrprlhLLlrZjot6/lvpEnLFxyXG4gIFBJQ0JFRF9HSVRIVUJfQlJBTkNIOiAn6Kit5a6a5YiG5pSv5ZCN56ixJyxcclxuICBQSUNCRURfR0lUSFVCX0NVU1RPTVVSTDogJ+ioreWumuiHquiogue2suWdgCcsXHJcbiAgUElDQkVEX0dJVEhVQl9NRVNTQUdFX1JFUE86ICfmoLzlvI/vvJp1c2VybmFtZS9yZXBvJyxcclxuICBQSUNCRURfR0lUSFVCX01FU1NBR0VfQlJBTkNIOiAn5L6L5aaC77yabWFpbicsXHJcbiAgUElDQkVEX0dJVEhVQl9NRVNTQUdFX1BBVEg6ICfkvovlpoLvvJp0ZXN0LycsXHJcbiAgUElDQkVEX0dJVEhVQl9NRVNTQUdFX0NVU1RPTVVSTDogJ+S+i+Wmgu+8mmh0dHBzOi8vdGVzdC5jb20nLFxyXG5cclxuICAvLyBxaW5pdVxyXG4gIFBJQ0JFRF9RSU5JVTogJ+S4g+eJm+S6kScsXHJcbiAgUElDQkVEX1FJTklVX0FDQ0VTU0tFWTogJ+ioreWumkFjY2Vzc0tleScsXHJcbiAgUElDQkVEX1FJTklVX1NFQ1JFVEtFWTogJ+ioreWumlNlY3JldEtleScsXHJcbiAgUElDQkVEX1FJTklVX0JVQ0tFVDogJ+ioreWumkJ1Y2tldCcsXHJcbiAgUElDQkVEX1FJTklVX1BBVEg6ICfoqK3lrprlhLLlrZjot6/lvpEnLFxyXG4gIFBJQ0JFRF9RSU5JVV9VUkw6ICfoqK3lrproqKrllY/ntrLlnYAnLFxyXG4gIFBJQ0JFRF9RSU5JVV9PUFRJT05TOiAn6Kit5a6a57ay5Z2A5b6M57a0JyxcclxuICBQSUNCRURfUUlOSVVfQVJFQTogJ+ioreWumuWEsuWtmOWNgOWfnycsXHJcbiAgUElDQkVEX1FJTklVX01FU1NBR0VfUEFUSDogJ+S+i+Wmgu+8mnRlc3QvJyxcclxuICBQSUNCRURfUUlOSVVfTUVTU0FHRV9BUkVBOiAn5L6L5aaC77yaejAnLFxyXG4gIFBJQ0JFRF9RSU5JVV9NRVNTQUdFX09QVElPTlM6ICfkvovlpoLvvJo/aW1hZ2VzbGltJyxcclxuICBQSUNCRURfUUlOSVVfTUVTU0FHRV9VUkw6ICfkvovlpoLvvJpodHRwczovL3h4eC55eXkuZ2xiLmNsb3VkZG4uY29tJyxcclxuXHJcbiAgLy8gaW1ndXJcclxuICBQSUNCRURfSU1HVVI6ICdJbWd1cicsXHJcbiAgUElDQkVEX0lNR1VSX0NMSUVOVElEOiAn6Kit5a6aQ2xpZW50SWQnLFxyXG4gIFBJQ0JFRF9JTUdVUl9QUk9YWTogJ+ioreWumlBST1hZJyxcclxuICBQSUNCRURfSU1HVVJfTUVTU0FHRV9QUk9YWTogJ+S+i+Wmgu+8mmh0dHA6Ly8xMjcuMC4wLjE6MTA4MCcsXHJcblxyXG4gIC8vIHVweXVuXHJcbiAgUElDQkVEX1VQWVVOOiAn5Y+I5ouN5LqRJyxcclxuICBQSUNCRURfVVBZVU5fQlVDS0VUOiAn6Kit5a6aQnVja2V0JyxcclxuICBQSUNCRURfVVBZVU5fT1BFUkFUT1I6ICfoqK3lrprmk43kvZzlk6EnLFxyXG4gIFBJQ0JFRF9VUFlVTl9QQVNTV09SRDogJ+ioreWumuaTjeS9nOWToeWvhueivCcsXHJcbiAgUElDQkVEX1VQWVVOX1BBVEg6ICfoqK3lrprlhLLlrZjot6/lvpEnLFxyXG4gIFBJQ0JFRF9VUFlVTl9VUkw6ICfoqK3lrprliqDpgJ/ntrLlnYAnLFxyXG4gIFBJQ0JFRF9VUFlVTl9PUFRJT05TOiAn6Kit5a6a57ay5Z2A5b6M57a0JyxcclxuICBQSUNCRURfVVBZVU5fTUVTU0FHRV9PUEVSQVRPUjogJ+S+i+Wmgu+8mm1lJyxcclxuICBQSUNCRURfVVBZVU5fTUVTU0FHRV9QQVNTV09SRDogJ+i8uOWFpeaTjeS9nOWToeWvhueivCcsXHJcbiAgUElDQkVEX1VQWVVOX01FU1NBR0VfVVJMOiAn5L6L5aaC77yaaHR0cDovL3h4eC50ZXN0LnVwY2RuLm5ldCcsXHJcbiAgUElDQkVEX1VQWVVOX01FU1NBR0VfT1BUSU9OUzogJ+S+i+Wmgu+8miFpbWdzbGltJyxcclxuICBQSUNCRURfVVBZVU5fTUVTU0FHRV9QQVRIOiAn5L6L5aaC77yadGVzdC8nLFxyXG5cclxuICAvLyBQbHVnaW4gSGFuZGxlclxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9JTlNUQUxMX1NVQ0NFU1M6ICfmj5Lku7blronoo53miJDlip8nLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9JTlNUQUxMX0ZBSUxFRDogJ+aPkuS7tuWuieijneWkseaVlycsXHJcbiAgUExVR0lOX0hBTkRMRVJfUExVR0lOX0lOU1RBTExfRkFJTEVEX1JFQVNPTjogJ+aPkuS7tuWuieijneWkseaVl++8jOWkseaVl+eivOeCuiR7Y29kZX3vvIzpjK/oqqTntIDpjITngrogXFxuICR7ZGF0YX0nLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9JTlNUQUxMX0ZBSUxFRF9QQVRIOiAn5o+S5Lu25a6J6KOd5aSx5pWX77yM6KuL6Ly45YWl5q2j56K655qE5o+S5Lu25ZCN56ix5oiW5q2j56K655qE5a6J6KOd6Lev5b6RJyxcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fVU5JTlNUQUxMX1NVQ0NFU1M6ICfmj5Lku7bljbjovInmiJDlip8nLFxyXG4gIFBMVUdJTl9IQU5ETEVSX1BMVUdJTl9VTklOU1RBTExfRkFJTEVEOiAn5o+S5Lu25Y246LyJ5aSx5pWXJyxcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fVU5JTlNUQUxMX0ZBSUxFRF9SRUFTT046ICfmj5Lku7bljbjovInlpLHmlZfvvIzlpLHmlZfnorzngroke2NvZGV977yM6Yyv6Kqk57SA6YyE54K6IFxcbiAke2RhdGF9JyxcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fVU5JTlNUQUxMX0ZBSUxFRF9WQUxJRDogJ+aPkuS7tuWNuOi8ieWkseaVl++8jOiri+i8uOWFpeato+eiuueahOaPkuS7tuWQjeeosScsXHJcbiAgUExVR0lOX0hBTkRMRVJfUExVR0lOX1VQREFURV9TVUNDRVNTOiAn5o+S5Lu25pu05paw5oiQ5YqfJyxcclxuICBQTFVHSU5fSEFORExFUl9QTFVHSU5fVVBEQVRFX0ZBSUxFRDogJ+aPkuS7tuabtOaWsOWkseaVlycsXHJcbiAgUExVR0lOX0hBTkRMRVJfUExVR0lOX1VQREFURV9GQUlMRURfUkVBU09OOiAn5o+S5Lu25pu05paw5aSx5pWX77yM5aSx5pWX56K854K6JHtjb2Rlfe+8jOmMr+iqpOe0gOmMhOeCuiBcXG4gJHtkYXRhfScsXHJcbiAgUExVR0lOX0hBTkRMRVJfUExVR0lOX1VQREFURV9GQUlMRURfVkFMSUQ6ICfmj5Lku7bmm7TmlrDlpLHmlZfvvIzoq4vovLjlhaXmraPnorrnmoTmj5Lku7blkI3nqLEnXHJcbn1cclxuIiwiaW1wb3J0IHsgWkhfQ04sIElMb2NhbGVzS2V5LCBJTG9jYWxlcyB9IGZyb20gJy4vemgtQ04nXHJcbmltcG9ydCB7IG1lcmdlIH0gZnJvbSAnbG9kYXNoJ1xyXG5pbXBvcnQgeyBJUGljR28gfSBmcm9tICcuLi90eXBlcydcclxuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcclxuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJ1xyXG5pbXBvcnQgeWFtbCBmcm9tICdqcy15YW1sJ1xyXG5cclxuaW1wb3J0IHsgT2JqZWN0QWRhcHRlciwgSTE4biB9IGZyb20gJ0BwaWNnby9pMThuJ1xyXG5pbXBvcnQgeyBJU3RyaW5nS2V5TWFwLCBJSTE4bk1hbmFnZXIgfSBmcm9tICcuLi90eXBlcy9pbmRleCdcclxuaW1wb3J0IHsgSUxvY2FsZSB9IGZyb20gJ0BwaWNnby9pMThuL2Rpc3QvdHlwZXMnXHJcbmltcG9ydCB7IEVOIH0gZnJvbSAnLi9lbidcclxuaW1wb3J0IHsgWkhfVFcgfSBmcm9tICcuL3poLVRXJ1xyXG5cclxuY29uc3QgbGFuZ3VhZ2VMaXN0OiBJU3RyaW5nS2V5TWFwPElTdHJpbmdLZXlNYXA8c3RyaW5nPj4gPSB7XHJcbiAgJ3poLUNOJzogWkhfQ04sXHJcbiAgJ3poLVRXJzogWkhfVFcsXHJcbiAgZW46IEVOXHJcbn1cclxuXHJcbmNsYXNzIEkxOG5NYW5hZ2VyIGltcGxlbWVudHMgSUkxOG5NYW5hZ2VyIHtcclxuICBwcml2YXRlIHJlYWRvbmx5IGkxOG46IEkxOG5cclxuICBwcml2YXRlIHJlYWRvbmx5IG9iamVjdEFkYXB0ZXI6IE9iamVjdEFkYXB0ZXJcclxuICBwcml2YXRlIHJlYWRvbmx5IGN0eDogSVBpY0dvXHJcbiAgY29uc3RydWN0b3IgKGN0eDogSVBpY0dvKSB7XHJcbiAgICB0aGlzLmN0eCA9IGN0eFxyXG4gICAgdGhpcy5vYmplY3RBZGFwdGVyID0gbmV3IE9iamVjdEFkYXB0ZXIobGFuZ3VhZ2VMaXN0KVxyXG4gICAgbGV0IGxhbmd1YWdlID0gdGhpcy5jdHguZ2V0Q29uZmlnPHN0cmluZz4oJ3NldHRpbmdzLmxhbmd1YWdlJykgfHwgJ3poLUNOJ1xyXG4gICAgaWYgKCFsYW5ndWFnZUxpc3RbbGFuZ3VhZ2VdKSB7XHJcbiAgICAgIGxhbmd1YWdlID0gJ3poLUNOJyAvLyB1c2UgZGVmYXVsdFxyXG4gICAgfVxyXG4gICAgdGhpcy5pMThuID0gbmV3IEkxOG4oe1xyXG4gICAgICBhZGFwdGVyOiB0aGlzLm9iamVjdEFkYXB0ZXIsXHJcbiAgICAgIGRlZmF1bHRMYW5ndWFnZTogbGFuZ3VhZ2VcclxuICAgIH0pXHJcbiAgICB0aGlzLmxvYWRPdXR0ZXJJMThuKClcclxuICB9XHJcblxyXG4gIHByaXZhdGUgbG9hZE91dHRlckkxOG4gKCk6IHZvaWQge1xyXG4gICAgY29uc3QgaTE4bkZvbGRlciA9IHRoaXMuZ2V0T3V0dGVySTE4bkZvbGRlcigpXHJcbiAgICBjb25zdCBmaWxlcyA9IGZzLnJlYWRkaXJTeW5jKGkxOG5Gb2xkZXIsIHtcclxuICAgICAgd2l0aEZpbGVUeXBlczogdHJ1ZVxyXG4gICAgfSlcclxuICAgIGZpbGVzLmZvckVhY2goZmlsZSA9PiB7XHJcbiAgICAgIGlmIChmaWxlLmlzRmlsZSgpICYmIGZpbGUubmFtZS5lbmRzV2l0aCgnLnltbCcpKSB7XHJcbiAgICAgICAgY29uc3QgaTE4bkZpbGVQYXRoID0gcGF0aC5qb2luKGkxOG5Gb2xkZXIsIGZpbGUubmFtZSlcclxuICAgICAgICBjb25zdCBpMThuRmlsZSA9IGZzLnJlYWRGaWxlU3luYyhpMThuRmlsZVBhdGgsICd1dGY4JylcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgY29uc3QgaTE4bkZpbGVPYmogPSB5YW1sLmxvYWQoaTE4bkZpbGUpIGFzIElMb2NhbGVzXHJcbiAgICAgICAgICBsYW5ndWFnZUxpc3RbZmlsZS5uYW1lLnJlcGxhY2UoL1xcLnltbCQvLCAnJyldID0gaTE4bkZpbGVPYmpcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGUpXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRPdXR0ZXJJMThuRm9sZGVyICgpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgaTE4bkZvbGRlciA9IHBhdGguam9pbih0aGlzLmN0eC5iYXNlRGlyLCAnaTE4bi1jbGknKVxyXG4gICAgaWYgKCFmcy5wYXRoRXhpc3RzU3luYyhpMThuRm9sZGVyKSkge1xyXG4gICAgICBmcy5lbnN1cmVEaXJTeW5jKGkxOG5Gb2xkZXIpXHJcbiAgICB9XHJcbiAgICByZXR1cm4gaTE4bkZvbGRlclxyXG4gIH1cclxuXHJcbiAgdHJhbnNsYXRlPFQgZXh0ZW5kcyBzdHJpbmc+KGtleTogSUxvY2FsZXNLZXkgfCBULCBhcmdzPzogSVN0cmluZ0tleU1hcDxzdHJpbmc+KTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLmkxOG4udHJhbnNsYXRlKGtleSwgYXJncykgfHwga2V5XHJcbiAgfVxyXG5cclxuICBzZXRMYW5ndWFnZSAobGFuZ3VhZ2U6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy5pMThuLnNldExhbmd1YWdlKGxhbmd1YWdlKVxyXG4gICAgdGhpcy5jdHguc2F2ZUNvbmZpZyh7XHJcbiAgICAgICdzZXR0aW5ncy5sYW5ndWFnZSc6IGxhbmd1YWdlXHJcbiAgICB9KVxyXG4gIH1cclxuXHJcbiAgYWRkTG9jYWxlIChsYW5ndWFnZTogc3RyaW5nLCBsb2NhbGVzOiBJTG9jYWxlKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBvcmlnaW5Mb2NhbGVzID0gdGhpcy5vYmplY3RBZGFwdGVyLmdldExvY2FsZShsYW5ndWFnZSlcclxuICAgIGlmICghb3JpZ2luTG9jYWxlcykge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuICAgIGNvbnN0IG5ld0xvY2FsZXMgPSBtZXJnZShvcmlnaW5Mb2NhbGVzLCBsb2NhbGVzKVxyXG4gICAgdGhpcy5vYmplY3RBZGFwdGVyLnNldExvY2FsZShsYW5ndWFnZSwgbmV3TG9jYWxlcylcclxuICAgIHJldHVybiB0cnVlXHJcbiAgfVxyXG5cclxuICBhZGRMYW5ndWFnZSAobGFuZ3VhZ2U6IHN0cmluZywgbG9jYWxlczogSUxvY2FsZSk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3Qgb3JpZ2luTG9jYWxlcyA9IHRoaXMub2JqZWN0QWRhcHRlci5nZXRMb2NhbGUobGFuZ3VhZ2UpXHJcbiAgICBpZiAob3JpZ2luTG9jYWxlcykge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuICAgIHRoaXMub2JqZWN0QWRhcHRlci5zZXRMb2NhbGUobGFuZ3VhZ2UsIGxvY2FsZXMpXHJcbiAgICBsYW5ndWFnZUxpc3RbbGFuZ3VhZ2VdID0gbG9jYWxlc1xyXG4gICAgcmV0dXJuIHRydWVcclxuICB9XHJcblxyXG4gIGdldExhbmd1YWdlTGlzdCAoKTogc3RyaW5nW10ge1xyXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGxhbmd1YWdlTGlzdClcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCB7XHJcbiAgSTE4bk1hbmFnZXJcclxufVxyXG4iLCJpbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnXHJcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXHJcbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJ2V2ZW50cydcclxuaW1wb3J0IHsgaG9tZWRpciB9IGZyb20gJ29zJ1xyXG5pbXBvcnQgQ29tbWFuZGVyIGZyb20gJy4uL2xpYi9Db21tYW5kZXInXHJcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uL2xpYi9Mb2dnZXInXHJcbmltcG9ydCBMaWZlY3ljbGUgZnJvbSAnLi9MaWZlY3ljbGUnXHJcbmltcG9ydCBMaWZlY3ljbGVQbHVnaW5zLCB7IHNldEN1cnJlbnRQbHVnaW5OYW1lIH0gZnJvbSAnLi4vbGliL0xpZmVjeWNsZVBsdWdpbnMnXHJcbmltcG9ydCB1cGxvYWRlcnMgZnJvbSAnLi4vcGx1Z2lucy91cGxvYWRlcidcclxuaW1wb3J0IHRyYW5zZm9ybWVycyBmcm9tICcuLi9wbHVnaW5zL3RyYW5zZm9ybWVyJ1xyXG5pbXBvcnQgUGx1Z2luTG9hZGVyIGZyb20gJy4uL2xpYi9QbHVnaW5Mb2FkZXInXHJcbmltcG9ydCB7IGdldCwgc2V0LCB1bnNldCB9IGZyb20gJ2xvZGFzaCdcclxuaW1wb3J0IHsgSUhlbHBlciwgSUltZ0luZm8sIElDb25maWcsIElQaWNHbywgSVN0cmluZ0tleU1hcCwgSVBsdWdpbkxvYWRlciwgSUkxOG5NYW5hZ2VyLCBJUGljR29QbHVnaW4sIElQaWNHb1BsdWdpbkludGVyZmFjZSwgSVJlcXVlc3QgfSBmcm9tICcuLi90eXBlcydcclxuaW1wb3J0IGdldENsaXBib2FyZEltYWdlIGZyb20gJy4uL3V0aWxzL2dldENsaXBib2FyZEltYWdlJ1xyXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuLi9saWIvUmVxdWVzdCdcclxuaW1wb3J0IERCIGZyb20gJy4uL3V0aWxzL2RiJ1xyXG5pbXBvcnQgUGx1Z2luSGFuZGxlciBmcm9tICcuLi9saWIvUGx1Z2luSGFuZGxlcidcclxuaW1wb3J0IHsgSUJ1aWxkSW5FdmVudCwgSUJ1c0V2ZW50IH0gZnJvbSAnLi4vdXRpbHMvZW51bSdcclxuaW1wb3J0IHsgZXZlbnRCdXMgfSBmcm9tICcuLi91dGlscy9ldmVudEJ1cydcclxuaW1wb3J0IHsgaXNDb25maWdLZXlJbkJsYWNrTGlzdCwgaXNJbnB1dENvbmZpZ1ZhbGlkIH0gZnJvbSAnLi4vdXRpbHMvY29tbW9uJ1xyXG5pbXBvcnQgeyBJMThuTWFuYWdlciB9IGZyb20gJy4uL2kxOG4nXHJcblxyXG5leHBvcnQgY2xhc3MgUGljR28gZXh0ZW5kcyBFdmVudEVtaXR0ZXIgaW1wbGVtZW50cyBJUGljR28ge1xyXG4gIHByaXZhdGUgX2NvbmZpZyE6IElDb25maWdcclxuICBwcml2YXRlIGxpZmVjeWNsZSE6IExpZmVjeWNsZVxyXG4gIHByaXZhdGUgZGIhOiBEQlxyXG4gIHByaXZhdGUgX3BsdWdpbkxvYWRlciE6IFBsdWdpbkxvYWRlclxyXG4gIGNvbmZpZ1BhdGg6IHN0cmluZ1xyXG4gIGJhc2VEaXIhOiBzdHJpbmdcclxuICBoZWxwZXIhOiBJSGVscGVyXHJcbiAgbG9nOiBMb2dnZXJcclxuICBjbWQ6IENvbW1hbmRlclxyXG4gIG91dHB1dDogSUltZ0luZm9bXVxyXG4gIGlucHV0OiBhbnlbXVxyXG4gIHBsdWdpbkhhbmRsZXI6IFBsdWdpbkhhbmRsZXJcclxuICAvKipcclxuICAgKiBAZGVwcmVjYXRlZCB3aWxsIGJlIHJlbW92ZWQgaW4gdjEuNS4wK1xyXG4gICAqXHJcbiAgICogdXNlIHJlcXVlc3QgaW5zdGVhZFxyXG4gICAqL1xyXG4gIFJlcXVlc3QhOiBSZXF1ZXN0XHJcbiAgaTE4biE6IElJMThuTWFuYWdlclxyXG4gIFZFUlNJT046IHN0cmluZyA9IHByb2Nlc3MuZW52LlBJQ0dPX1ZFUlNJT05cclxuICBHVUlfVkVSU0lPTj86IHN0cmluZ1xyXG5cclxuICBnZXQgcGx1Z2luTG9hZGVyICgpOiBJUGx1Z2luTG9hZGVyIHtcclxuICAgIHJldHVybiB0aGlzLl9wbHVnaW5Mb2FkZXJcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yIChjb25maWdQYXRoOiBzdHJpbmcgPSAnJykge1xyXG4gICAgc3VwZXIoKVxyXG4gICAgdGhpcy5jb25maWdQYXRoID0gY29uZmlnUGF0aFxyXG4gICAgdGhpcy5vdXRwdXQgPSBbXVxyXG4gICAgdGhpcy5pbnB1dCA9IFtdXHJcbiAgICB0aGlzLmhlbHBlciA9IHtcclxuICAgICAgdHJhbnNmb3JtZXI6IG5ldyBMaWZlY3ljbGVQbHVnaW5zKCd0cmFuc2Zvcm1lcicpLFxyXG4gICAgICB1cGxvYWRlcjogbmV3IExpZmVjeWNsZVBsdWdpbnMoJ3VwbG9hZGVyJyksXHJcbiAgICAgIGJlZm9yZVRyYW5zZm9ybVBsdWdpbnM6IG5ldyBMaWZlY3ljbGVQbHVnaW5zKCdiZWZvcmVUcmFuc2Zvcm1QbHVnaW5zJyksXHJcbiAgICAgIGJlZm9yZVVwbG9hZFBsdWdpbnM6IG5ldyBMaWZlY3ljbGVQbHVnaW5zKCdiZWZvcmVVcGxvYWRQbHVnaW5zJyksXHJcbiAgICAgIGFmdGVyVXBsb2FkUGx1Z2luczogbmV3IExpZmVjeWNsZVBsdWdpbnMoJ2FmdGVyVXBsb2FkUGx1Z2lucycpXHJcbiAgICB9XHJcbiAgICB0aGlzLmluaXRDb25maWdQYXRoKClcclxuICAgIHRoaXMubG9nID0gbmV3IExvZ2dlcih0aGlzKVxyXG4gICAgdGhpcy5jbWQgPSBuZXcgQ29tbWFuZGVyKHRoaXMpXHJcbiAgICB0aGlzLnBsdWdpbkhhbmRsZXIgPSBuZXcgUGx1Z2luSGFuZGxlcih0aGlzKVxyXG4gICAgdGhpcy5pbml0Q29uZmlnKClcclxuICAgIHRoaXMuaW5pdCgpXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluaXRDb25maWdQYXRoICgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmNvbmZpZ1BhdGggPT09ICcnKSB7XHJcbiAgICAgIHRoaXMuY29uZmlnUGF0aCA9IGhvbWVkaXIoKSArICcvLnBpY2dvL2NvbmZpZy5qc29uJ1xyXG4gICAgfVxyXG4gICAgaWYgKHBhdGguZXh0bmFtZSh0aGlzLmNvbmZpZ1BhdGgpLnRvVXBwZXJDYXNlKCkgIT09ICcuSlNPTicpIHtcclxuICAgICAgdGhpcy5jb25maWdQYXRoID0gJydcclxuICAgICAgdGhyb3cgRXJyb3IoJ1RoZSBjb25maWd1cmF0aW9uIGZpbGUgb25seSBzdXBwb3J0cyBKU09OIGZvcm1hdC4nKVxyXG4gICAgfVxyXG4gICAgdGhpcy5iYXNlRGlyID0gcGF0aC5kaXJuYW1lKHRoaXMuY29uZmlnUGF0aClcclxuICAgIGNvbnN0IGV4aXN0ID0gZnMucGF0aEV4aXN0c1N5bmModGhpcy5jb25maWdQYXRoKVxyXG4gICAgaWYgKCFleGlzdCkge1xyXG4gICAgICBmcy5lbnN1cmVGaWxlU3luYyhgJHt0aGlzLmNvbmZpZ1BhdGh9YClcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgaW5pdENvbmZpZyAoKTogdm9pZCB7XHJcbiAgICB0aGlzLmRiID0gbmV3IERCKHRoaXMpXHJcbiAgICB0aGlzLl9jb25maWcgPSB0aGlzLmRiLnJlYWQodHJ1ZSkgYXMgSUNvbmZpZ1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbml0ICgpOiB2b2lkIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIGluaXQgMThuIGF0IGZpcnN0XHJcbiAgICAgIHRoaXMuaTE4biA9IG5ldyBJMThuTWFuYWdlcih0aGlzKVxyXG4gICAgICB0aGlzLlJlcXVlc3QgPSBuZXcgUmVxdWVzdCh0aGlzKVxyXG4gICAgICB0aGlzLl9wbHVnaW5Mb2FkZXIgPSBuZXcgUGx1Z2luTG9hZGVyKHRoaXMpXHJcbiAgICAgIC8vIGxvYWQgc2VsZiBwbHVnaW5zXHJcbiAgICAgIHNldEN1cnJlbnRQbHVnaW5OYW1lKCdwaWNnbycpXHJcbiAgICAgIHVwbG9hZGVycyh0aGlzKS5yZWdpc3Rlcih0aGlzKVxyXG4gICAgICB0cmFuc2Zvcm1lcnModGhpcykucmVnaXN0ZXIodGhpcylcclxuICAgICAgc2V0Q3VycmVudFBsdWdpbk5hbWUoJycpXHJcbiAgICAgIC8vIGxvYWQgdGhpcmQtcGFydHkgcGx1Z2luc1xyXG4gICAgICB0aGlzLl9wbHVnaW5Mb2FkZXIubG9hZCgpXHJcbiAgICAgIHRoaXMubGlmZWN5Y2xlID0gbmV3IExpZmVjeWNsZSh0aGlzKVxyXG4gICAgfSBjYXRjaCAoZTogYW55KSB7XHJcbiAgICAgIHRoaXMuZW1pdChJQnVpbGRJbkV2ZW50LlVQTE9BRF9QUk9HUkVTUywgLTEpXHJcbiAgICAgIHRoaXMubG9nLmVycm9yKGUpXHJcbiAgICAgIHRocm93IGVcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGVhc2lseSBtYW5udWFsbHkgbG9hZCBhIHBsdWdpblxyXG4gICAqIGlmIHByb3ZpZGUgcGx1Z2luIG5hbWUsIHdpbGwgcmVnaXN0ZXIgcGx1Z2luIGJ5IG5hbWVcclxuICAgKiBvciBqdXN0IGluc3RhbnRpYXRlIGEgcGx1Z2luXHJcbiAgICovXHJcbiAgdXNlIChwbHVnaW46IElQaWNHb1BsdWdpbiwgbmFtZT86IHN0cmluZyk6IElQaWNHb1BsdWdpbkludGVyZmFjZSB7XHJcbiAgICBpZiAobmFtZSkge1xyXG4gICAgICB0aGlzLnBsdWdpbkxvYWRlci5yZWdpc3RlclBsdWdpbihuYW1lLCBwbHVnaW4pXHJcbiAgICAgIHJldHVybiB0aGlzLnBsdWdpbkxvYWRlci5nZXRQbHVnaW4obmFtZSkhXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBwbHVnaW5JbnN0YW5jZSA9IHBsdWdpbih0aGlzKVxyXG4gICAgICByZXR1cm4gcGx1Z2luSW5zdGFuY2VcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJlZ2lzdGVyQ29tbWFuZHMgKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuY29uZmlnUGF0aCAhPT0gJycpIHtcclxuICAgICAgdGhpcy5jbWQuaW5pdCgpXHJcbiAgICAgIHRoaXMuY21kLmxvYWRDb21tYW5kcygpXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXRDb25maWc8VD4gKG5hbWU/OiBzdHJpbmcpOiBUIHtcclxuICAgIGlmICghbmFtZSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY29uZmlnIGFzIHVua25vd24gYXMgVFxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIGdldCh0aGlzLl9jb25maWcsIG5hbWUpXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzYXZlQ29uZmlnIChjb25maWc6IElTdHJpbmdLZXlNYXA8YW55Pik6IHZvaWQge1xyXG4gICAgaWYgKCFpc0lucHV0Q29uZmlnVmFsaWQoY29uZmlnKSkge1xyXG4gICAgICB0aGlzLmxvZy53YXJuKCd0aGUgZm9ybWF0IG9mIGNvbmZpZyBpcyBpbnZhbGlkLCBwbGVhc2UgcHJvdmlkZSBvYmplY3QnKVxyXG4gICAgICByZXR1cm5cclxuICAgIH1cclxuICAgIHRoaXMuc2V0Q29uZmlnKGNvbmZpZylcclxuICAgIHRoaXMuZGIuc2F2ZUNvbmZpZyhjb25maWcpXHJcbiAgfVxyXG5cclxuICByZW1vdmVDb25maWcgKGtleTogc3RyaW5nLCBwcm9wTmFtZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBpZiAoIWtleSB8fCAhcHJvcE5hbWUpIHJldHVyblxyXG4gICAgaWYgKGlzQ29uZmlnS2V5SW5CbGFja0xpc3Qoa2V5KSkge1xyXG4gICAgICB0aGlzLmxvZy53YXJuKGB0aGUgY29uZmlnLiR7a2V5fSBjYW4ndCBiZSByZW1vdmVkYClcclxuICAgICAgcmV0dXJuXHJcbiAgICB9XHJcbiAgICB0aGlzLnVuc2V0Q29uZmlnKGtleSwgcHJvcE5hbWUpXHJcbiAgICB0aGlzLmRiLnVuc2V0KGtleSwgcHJvcE5hbWUpXHJcbiAgfVxyXG5cclxuICBzZXRDb25maWcgKGNvbmZpZzogSVN0cmluZ0tleU1hcDxhbnk+KTogdm9pZCB7XHJcbiAgICBpZiAoIWlzSW5wdXRDb25maWdWYWxpZChjb25maWcpKSB7XHJcbiAgICAgIHRoaXMubG9nLndhcm4oJ3RoZSBmb3JtYXQgb2YgY29uZmlnIGlzIGludmFsaWQsIHBsZWFzZSBwcm92aWRlIG9iamVjdCcpXHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG4gICAgT2JqZWN0LmtleXMoY29uZmlnKS5mb3JFYWNoKChuYW1lOiBzdHJpbmcpID0+IHtcclxuICAgICAgaWYgKGlzQ29uZmlnS2V5SW5CbGFja0xpc3QobmFtZSkpIHtcclxuICAgICAgICB0aGlzLmxvZy53YXJuKGB0aGUgY29uZmlnLiR7bmFtZX0gY2FuJ3QgYmUgbW9kaWZpZWRgKVxyXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZHluYW1pYy1kZWxldGVcclxuICAgICAgICBkZWxldGUgY29uZmlnW25hbWVdXHJcbiAgICAgIH1cclxuICAgICAgc2V0KHRoaXMuX2NvbmZpZywgbmFtZSwgY29uZmlnW25hbWVdKVxyXG4gICAgICBldmVudEJ1cy5lbWl0KElCdXNFdmVudC5DT05GSUdfQ0hBTkdFLCB7XHJcbiAgICAgICAgY29uZmlnTmFtZTogbmFtZSxcclxuICAgICAgICB2YWx1ZTogY29uZmlnW25hbWVdXHJcbiAgICAgIH0pXHJcbiAgICB9KVxyXG4gIH1cclxuXHJcbiAgdW5zZXRDb25maWcgKGtleTogc3RyaW5nLCBwcm9wTmFtZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBpZiAoIWtleSB8fCAhcHJvcE5hbWUpIHJldHVyblxyXG4gICAgaWYgKGlzQ29uZmlnS2V5SW5CbGFja0xpc3Qoa2V5KSkge1xyXG4gICAgICB0aGlzLmxvZy53YXJuKGB0aGUgY29uZmlnLiR7a2V5fSBjYW4ndCBiZSB1bnNldGApXHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG4gICAgdW5zZXQodGhpcy5nZXRDb25maWcoa2V5KSwgcHJvcE5hbWUpXHJcbiAgfVxyXG5cclxuICBnZXQgcmVxdWVzdCAoKTogSVJlcXVlc3RbJ3JlcXVlc3QnXSB7XHJcbiAgICByZXR1cm4gdGhpcy5SZXF1ZXN0LnJlcXVlc3QuYmluZCh0aGlzLlJlcXVlc3QpXHJcbiAgfVxyXG5cclxuICBhc3luYyB1cGxvYWQgKGlucHV0PzogYW55W10pOiBQcm9taXNlPElJbWdJbmZvW10gfCBFcnJvcj4ge1xyXG4gICAgaWYgKHRoaXMuY29uZmlnUGF0aCA9PT0gJycpIHtcclxuICAgICAgdGhpcy5sb2cuZXJyb3IoJ1RoZSBjb25maWd1cmF0aW9uIGZpbGUgb25seSBzdXBwb3J0cyBKU09OIGZvcm1hdC4nKVxyXG4gICAgICByZXR1cm4gW11cclxuICAgIH1cclxuICAgIC8vIHVwbG9hZCBmcm9tIGNsaXBib2FyZFxyXG4gICAgaWYgKGlucHV0ID09PSB1bmRlZmluZWQgfHwgaW5wdXQubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgY29uc3QgeyBpbWdQYXRoLCBzaG91bGRLZWVwQWZ0ZXJVcGxvYWRpbmcgfSA9IGF3YWl0IGdldENsaXBib2FyZEltYWdlKHRoaXMpXHJcbiAgICAgICAgaWYgKGltZ1BhdGggPT09ICdubyBpbWFnZScpIHtcclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignaW1hZ2Ugbm90IGZvdW5kIGluIGNsaXBib2FyZCcpXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMub25jZShJQnVpbGRJbkV2ZW50LkZBSUxFRCwgKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIXNob3VsZEtlZXBBZnRlclVwbG9hZGluZykge1xyXG4gICAgICAgICAgICAgIC8vIOWIoOmZpCBwaWNnbyDnlJ/miJDnmoTlm77niYfmlofku7bvvIzkvovlpoIgYH4vLnBpY2dvLzIwMjAwNjIxMjA1NzIwLnBuZ2BcclxuICAgICAgICAgICAgICBmcy5yZW1vdmUoaW1nUGF0aCkuY2F0Y2goKGUpID0+IHsgdGhpcy5sb2cuZXJyb3IoZSkgfSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSlcclxuICAgICAgICAgIHRoaXMub25jZSgnZmluaXNoZWQnLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghc2hvdWxkS2VlcEFmdGVyVXBsb2FkaW5nKSB7XHJcbiAgICAgICAgICAgICAgZnMucmVtb3ZlKGltZ1BhdGgpLmNhdGNoKChlKSA9PiB7IHRoaXMubG9nLmVycm9yKGUpIH0pXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgICBjb25zdCB7IG91dHB1dCB9ID0gYXdhaXQgdGhpcy5saWZlY3ljbGUuc3RhcnQoW2ltZ1BhdGhdKVxyXG4gICAgICAgICAgcmV0dXJuIG91dHB1dFxyXG4gICAgICAgIH1cclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIHRoaXMuZW1pdChJQnVpbGRJbkV2ZW50LkZBSUxFRCwgZSlcclxuICAgICAgICB0aHJvdyBlXHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIHVwbG9hZCBmcm9tIHBhdGhcclxuICAgICAgY29uc3QgeyBvdXRwdXQgfSA9IGF3YWl0IHRoaXMubGlmZWN5Y2xlLnN0YXJ0KGlucHV0KVxyXG4gICAgICByZXR1cm4gb3V0cHV0XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiJdLCJuYW1lcyI6WyJjb25maWciLCJwb3N0T3B0aW9ucyIsImhhbmRsZSIsInJlZ2lzdGVyIiwiZ2VuZXJhdGVTaWduYXR1cmUiLCJhbGlZdW5VcGxvYWRlciIsInRjWXVuVXBsb2FkZXIiLCJTTU1TVXBsb2FkZXIiLCJnaXRodWJVcGxvYWRlciIsInFpbml1VXBsb2FkZXIiLCJpbWd1clVwbG9hZGVyIiwidXBZdW5VcGxvYWRlciIsInNwYXduIiwidXBsb2FkZXJzIiwidHJhbnNmb3JtZXJzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLE1BQU0sYUFBYSxHQUFZO0lBQzdCLE1BQU0sRUFBRSxDQUFDLEdBQVc7O1FBRWxCLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUE7UUFDbkIsR0FBRyxDQUFDLE9BQU87YUFDUixPQUFPLENBQUMsc0JBQXNCLENBQUM7YUFDL0IsV0FBVyxDQUFDLHNCQUFzQixDQUFDO2FBQ25DLEtBQUssQ0FBQyxLQUFLLENBQUM7YUFDWixNQUFNLENBQUMscUJBQXFCLEVBQUUsMEJBQTBCLENBQUM7YUFDekQsTUFBTSxDQUFD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
|