UNPKG

73.1 kBJavaScriptView Raw
1"use strict";
2// tslint:disable:no-any
3// tslint:disable:no-unsafe-any
4Object.defineProperty(exports, "__esModule", { value: true });
5const fs_1 = require("fs");
6const path = require("path");
7const error_models_1 = require("../error-models");
8const utils_1 = require("../utils");
9const normalize_environment_1 = require("./normalize-environment");
10function applyProjectConfigWithEnvironment(projectConfig, env) {
11 if (!projectConfig ||
12 !projectConfig.envOverrides ||
13 Object.keys(projectConfig.envOverrides).length === 0) {
14 return;
15 }
16 const buildTargets = [];
17 if (env.production || env.prod) {
18 if (!buildTargets.includes('prod')) {
19 buildTargets.push('prod');
20 }
21 if (!buildTargets.includes('production')) {
22 buildTargets.push('production');
23 }
24 }
25 else if (env.dev || env.development) {
26 buildTargets.push('dev');
27 buildTargets.push('development');
28 }
29 const preDefinedKeys = ['prod', 'production', 'dev', 'development'];
30 Object.keys(env)
31 .filter(key => !preDefinedKeys.includes(key.toLowerCase()) &&
32 !buildTargets.includes(key) &&
33 env[key] &&
34 (typeof env[key] === 'boolean' || env[key] === 'true'))
35 .forEach(key => {
36 buildTargets.push(key);
37 });
38 Object.keys(projectConfig.envOverrides)
39 .forEach((buildTargetKey) => {
40 const targetName = buildTargetKey;
41 const targets = targetName.split(',');
42 targets.forEach(t => {
43 t = t.trim();
44 if (buildTargets.indexOf(t) > -1) {
45 const newConfig = projectConfig.envOverrides[t];
46 if (newConfig && typeof newConfig === 'object') {
47 overrideProjectConfig(projectConfig, newConfig);
48 }
49 }
50 });
51 });
52}
53exports.applyProjectConfigWithEnvironment = applyProjectConfigWithEnvironment;
54// tslint:disable:max-func-body-length
55function applyProjectConfigExtends(projectConfig, projects) {
56 if (!projectConfig.extends) {
57 return;
58 }
59 const extendArray = Array.isArray(projectConfig.extends) ? projectConfig.extends : [projectConfig.extends];
60 for (const extendName of extendArray) {
61 if (!extendName) {
62 continue;
63 }
64 let foundBaseProject = null;
65 if (extendName.startsWith('ngb:') || extendName.startsWith('angular-build:')) {
66 let builtInConfigFileName = extendName.startsWith('ngb:')
67 ? extendName.substr('ngb:'.length).trim()
68 : extendName.substr('angular-build:'.length).trim();
69 if (!builtInConfigFileName) {
70 throw new error_models_1.InvalidConfigError(`Can't extend from non existed config file - ${extendName}, check your configuration file - ${projectConfig._configPath}.`);
71 }
72 const targetProjectType = /^lib-/.test(builtInConfigFileName) ? 'lib' : 'app';
73 if (targetProjectType !== projectConfig._projectType) {
74 throw new error_models_1.InvalidConfigError(`Can't extend from different project type, check your configuration file - ${projectConfig._configPath}.`);
75 }
76 builtInConfigFileName = `ngb-${builtInConfigFileName}.json`;
77 let builtInConfigPath = '';
78 if (fs_1.existsSync(path.resolve(__dirname, `../configs/${builtInConfigFileName}`))) {
79 builtInConfigPath = path.resolve(__dirname, `../configs/${builtInConfigFileName}`);
80 }
81 else if (fs_1.existsSync(path.resolve(__dirname, `../../configs/${builtInConfigFileName}`))) {
82 builtInConfigPath = path.resolve(__dirname, `../../configs/${builtInConfigFileName}`);
83 }
84 if (!builtInConfigPath) {
85 throw new error_models_1.InvalidConfigError(`Can't extend from non existed config file - ${builtInConfigPath}, check your configuration file - ${projectConfig._configPath}.`);
86 }
87 const config = utils_1.readJsonSync(builtInConfigPath);
88 config._projectType = projectConfig._projectType;
89 config._configPath = builtInConfigPath;
90 const extendLevel = projectConfig._extendLevel || 0;
91 config._extendLevel = extendLevel + 1;
92 foundBaseProject = config;
93 }
94 else if (extendName.startsWith('projects:')) {
95 if (projectConfig._extendLevel || !projects || projects.length < 2) {
96 continue;
97 }
98 const projectName = extendName.substr('projects:'.length).trim();
99 if (!projectName) {
100 throw new error_models_1.InvalidConfigError(`Can't extend from non existed config file - ${extendName}, check your configuration file - ${projectConfig._configPath}.`);
101 }
102 const tempFoundProject = projects.find(project => project.name === projectName);
103 if (!tempFoundProject) {
104 throw new error_models_1.InvalidConfigError(`Can't extend from non existed config file - ${extendName}, check your configuration file - ${projectConfig._configPath}.`);
105 }
106 if (tempFoundProject._projectType !== projectConfig._projectType) {
107 throw new error_models_1.InvalidConfigError(`Can't extend from different project type, check your configuration file - ${projectConfig._configPath}.`);
108 }
109 if (tempFoundProject.name !== projectConfig.name &&
110 tempFoundProject._index !== projectConfig._index &&
111 (!tempFoundProject._configPath || (tempFoundProject._configPath === projectConfig._configPath))) {
112 foundBaseProject = tempFoundProject;
113 }
114 }
115 else if (projectConfig._configPath) {
116 let destPath = extendName;
117 let projectType = '';
118 let projectName = '';
119 if (extendName.indexOf(':') > 0) {
120 const parts = extendName.split(':');
121 if (parts.length === 3) {
122 [destPath, projectType, projectName] = parts;
123 }
124 }
125 destPath = path.isAbsolute(destPath)
126 ? path.resolve(destPath)
127 : path.resolve(path.dirname(projectConfig._configPath), destPath);
128 if (!fs_1.existsSync(destPath)) {
129 throw new error_models_1.InvalidConfigError(`Can't extend from non existed config file - ${destPath}, check your configuration file - ${projectConfig._configPath}.`);
130 }
131 let config = null;
132 try {
133 config = utils_1.readJsonSync(destPath);
134 }
135 catch (jsonErr2) {
136 throw new error_models_1.InvalidConfigError(`Invalid configuration, error: ${jsonErr2.message || jsonErr2}.`);
137 }
138 if (!config) {
139 throw new error_models_1.InvalidConfigError(`Can't extend from non existed config file - ${destPath}, check your configuration file - ${projectConfig._configPath}.`);
140 }
141 if (projectName) {
142 if (projectType !== projectConfig._projectType) {
143 throw new error_models_1.InvalidConfigError(`Can't extend from different project type, check your configuration file - ${projectConfig._configPath}.`);
144 }
145 const angularBuildConfig = config;
146 if (projectConfig._configPath !== destPath) {
147 // Validate schema
148 const schemaFileName = 'schema.json';
149 let schemaPath = '';
150 if (fs_1.existsSync(path.resolve(__dirname, `../schemas/${schemaFileName}`))) {
151 schemaPath = `../schemas/${schemaFileName}`;
152 }
153 else if (fs_1.existsSync(path.resolve(__dirname, `../../schemas/${schemaFileName}`))) {
154 schemaPath = `../../schemas/${schemaFileName}`;
155 }
156 if (!schemaPath) {
157 throw new error_models_1.InternalError("The angular-build schema file doesn't exist.");
158 }
159 // tslint:disable-next-line:non-literal-require
160 const schema = require(schemaPath);
161 if (schema.$schema) {
162 delete schema.$schema;
163 }
164 if (angularBuildConfig.$schema) {
165 delete angularBuildConfig.$schema;
166 }
167 const errors = utils_1.validateSchema(schema, angularBuildConfig);
168 if (errors.length) {
169 const errMsg = errors.map(err => utils_1.formatValidationError(schema, err)).join('\n');
170 throw new error_models_1.InvalidConfigError(`Invalid configuration.\n\n${errMsg}`);
171 }
172 }
173 // Set angular build defaults
174 const angularBuildConfigInternal = angularBuildConfig;
175 angularBuildConfigInternal.libs = angularBuildConfigInternal.libs || [];
176 angularBuildConfigInternal.apps = angularBuildConfigInternal.apps || [];
177 // extends
178 if (projectConfig._projectType === 'lib') {
179 for (let i = 0; i < angularBuildConfigInternal.libs.length; i++) {
180 const libConfig = angularBuildConfigInternal.libs[i];
181 libConfig._index = i;
182 libConfig._projectType = 'lib';
183 libConfig._configPath = destPath;
184 if (libConfig.name === projectName) {
185 foundBaseProject = libConfig;
186 const extendLevel = projectConfig._extendLevel || 0;
187 foundBaseProject._extendLevel = extendLevel + 1;
188 break;
189 }
190 }
191 }
192 else {
193 for (let i = 0; i < angularBuildConfigInternal.apps.length; i++) {
194 const appConfig = angularBuildConfigInternal.apps[i];
195 appConfig._index = i;
196 appConfig._projectType = 'app';
197 appConfig._configPath = destPath;
198 if (appConfig.name === projectName) {
199 foundBaseProject = appConfig;
200 const extendLevel = projectConfig._extendLevel || 0;
201 foundBaseProject._extendLevel = extendLevel + 1;
202 break;
203 }
204 }
205 }
206 }
207 else {
208 // validate
209 const schemaFileName = projectConfig._projectType === 'lib'
210 ? 'lib-project-config-schema.json'
211 : 'app-project-config-schema.json';
212 let schemaPath = '';
213 if (fs_1.existsSync(path.resolve(__dirname, `../schemas/${schemaFileName}`))) {
214 schemaPath = `../schemas/${schemaFileName}`;
215 }
216 else if (fs_1.existsSync(path.resolve(__dirname, `../../schemas/${schemaFileName}`))) {
217 schemaPath = `../../schemas/${schemaFileName}`;
218 }
219 if (!schemaPath) {
220 throw new error_models_1.InternalError("The angular-build schema file doesn't exist.");
221 }
222 // tslint:disable-next-line:non-literal-require
223 const schema = require(schemaPath);
224 if (schema.$schema) {
225 delete schema.$schema;
226 }
227 if (config.$schema) {
228 delete config.$schema;
229 }
230 const errors = utils_1.validateSchema(schema, config);
231 if (errors.length) {
232 const errMsg = errors.map(err => utils_1.formatValidationError(schema, err)).join('\n');
233 throw new error_models_1.InvalidConfigError(`Invalid configuration.\n\n${errMsg}`);
234 }
235 config._projectType = projectConfig._projectType;
236 config._configPath = projectConfig._configPath;
237 const extendLevel = projectConfig._extendLevel || 0;
238 config._extendLevel = extendLevel + 1;
239 foundBaseProject = config;
240 }
241 }
242 if (!foundBaseProject) {
243 continue;
244 }
245 const clonedBaseProject = JSON.parse(JSON.stringify(foundBaseProject));
246 if (clonedBaseProject.extends) {
247 applyProjectConfigExtends(clonedBaseProject, projects);
248 delete clonedBaseProject.extends;
249 }
250 if (clonedBaseProject.name) {
251 delete clonedBaseProject.name;
252 }
253 if (clonedBaseProject.$schema) {
254 delete clonedBaseProject.$schema;
255 }
256 const extendedConfig = Object.assign({}, clonedBaseProject, projectConfig);
257 Object.assign(projectConfig, extendedConfig);
258 }
259}
260exports.applyProjectConfigExtends = applyProjectConfigExtends;
261function getBuildOptionsFromBuilderOptions(options) {
262 const buildOptions = { environment: {} };
263 if (options.environment) {
264 const env = normalize_environment_1.normalizeEnvironment(options.environment);
265 buildOptions.environment = env;
266 delete options.environment;
267 }
268 if (options.filter) {
269 buildOptions.filter = options.filter;
270 delete options.filter;
271 }
272 if (options.verbose != null) {
273 if (options.verbose) {
274 buildOptions.logLevel = 'debug';
275 }
276 delete options.verbose;
277 }
278 if (options.logLevel) {
279 buildOptions.logLevel = options.logLevel;
280 delete options.logLevel;
281 }
282 if (options.progress != null) {
283 if (options.progress) {
284 buildOptions.progress = true;
285 }
286 delete options.progress;
287 }
288 if (options.poll != null) {
289 buildOptions.watchOptions = {
290 poll: options.poll
291 };
292 delete options.poll;
293 }
294 if (options.cleanOutDir != null) {
295 if (options.cleanOutDir) {
296 buildOptions.cleanOutDir = true;
297 }
298 delete options.cleanOutDir;
299 }
300 if (options.watch != null) {
301 if (options.watch) {
302 buildOptions.watch = true;
303 }
304 delete options.watch;
305 }
306 if (options.watchOptions) {
307 buildOptions.watchOptions = Object.assign({}, options.watchOptions);
308 delete options.watchOptions;
309 }
310 if (options.beep != null) {
311 if (options.beep) {
312 buildOptions.beep = true;
313 }
314 delete options.beep;
315 }
316 return buildOptions;
317}
318exports.getBuildOptionsFromBuilderOptions = getBuildOptionsFromBuilderOptions;
319function applyAppConfigCompat(appConfig) {
320 if (appConfig.target && !appConfig.platformTarget) {
321 appConfig.platformTarget = appConfig.target;
322 delete appConfig.target;
323 }
324 if (appConfig.platform && !appConfig.platformTarget) {
325 appConfig.platformTarget = appConfig.platform === 'server' ? 'node' : 'web';
326 delete appConfig.platform;
327 }
328 if (appConfig.outDir && !appConfig.outputPath) {
329 appConfig.outputPath = appConfig.outDir;
330 delete appConfig.outDir;
331 }
332 if (appConfig.main && !appConfig.entry) {
333 appConfig.entry = appConfig.main;
334 delete appConfig.main;
335 }
336 if (appConfig.index && !appConfig.htmlInject) {
337 appConfig.htmlInject = {
338 index: appConfig.index
339 };
340 delete appConfig.index;
341 }
342 if (appConfig.evalSourceMap && !appConfig.sourceMapDevTool) {
343 appConfig.sourceMapDevTool = 'eval';
344 delete appConfig.evalSourceMap;
345 }
346 if (appConfig.deployUrl && !appConfig.publicPath) {
347 appConfig.publicPath = appConfig.deployUrl;
348 delete appConfig.deployUrl;
349 }
350 if (appConfig.assets &&
351 Array.isArray(appConfig.assets) &&
352 (!appConfig.copy || (Array.isArray(appConfig.copy) && !appConfig.copy.length))) {
353 appConfig.copy = appConfig.assets.map((assetEntry) => {
354 if (typeof assetEntry === 'string') {
355 return assetEntry;
356 }
357 return {
358 from: path.join(assetEntry.input, assetEntry.glob || ''),
359 to: assetEntry.output,
360 exclude: assetEntry.ignore
361 };
362 });
363 delete appConfig.assets;
364 }
365 if (appConfig.deleteOutputPath && !appConfig.clean) {
366 appConfig.clean = {
367 beforeBuild: {
368 cleanOutDir: true
369 }
370 };
371 delete appConfig.deleteOutputPath;
372 }
373 if (appConfig.statsJson && !appConfig.bundleAnalyzer) {
374 appConfig.bundleAnalyzer = {
375 generateStatsFile: true
376 };
377 delete appConfig.statsJson;
378 }
379 if (appConfig.bundleDependencies && appConfig.bundleDependencies === 'none') {
380 appConfig.nodeModulesAsExternals = true;
381 const externals = [
382 /^@angular/,
383 (_, request, callback) => {
384 // Absolute & Relative paths are not externals
385 if (request.match(/^\.{0,2}\//)) {
386 callback();
387 return;
388 }
389 try {
390 // Attempt to resolve the module via Node
391 const e = require.resolve(request);
392 if (/node_modules/.test(e)) {
393 // It's a node_module
394 callback(null, request);
395 }
396 else {
397 // It's a system thing (.ie util, fs...)
398 callback();
399 }
400 }
401 catch (e) {
402 // Node couldn't find it, so it must be user-aliased
403 callback();
404 }
405 }
406 ];
407 if (!appConfig.externals) {
408 appConfig.externals = externals;
409 }
410 else {
411 if (Array.isArray(appConfig.externals)) {
412 appConfig.externals = [...appConfig.externals, ...externals];
413 }
414 else {
415 appConfig.externals = [appConfig.externals, ...externals];
416 }
417 }
418 delete appConfig.bundleDependencies;
419 }
420}
421exports.applyAppConfigCompat = applyAppConfigCompat;
422function applyLibConfigCompat(libConfig) {
423 if (libConfig.target && !libConfig.platformTarget) {
424 libConfig.platformTarget = libConfig.target;
425 delete libConfig.target;
426 }
427 if (libConfig.platform && !libConfig.platformTarget) {
428 libConfig.platformTarget = libConfig.platform === 'server' ? 'node' : 'web';
429 delete libConfig.platform;
430 }
431 if (libConfig.outDir && !libConfig.outputPath) {
432 libConfig.outputPath = libConfig.outDir;
433 delete libConfig.outDir;
434 }
435 if (libConfig.assets &&
436 Array.isArray(libConfig.assets) &&
437 (!libConfig.copy || (Array.isArray(libConfig.copy) && !libConfig.copy.length))) {
438 libConfig.copy = libConfig.assets.map(assetEntry => {
439 if (typeof assetEntry === 'string') {
440 return assetEntry;
441 }
442 return {
443 from: path.join(assetEntry.input, assetEntry.glob || ''),
444 to: assetEntry.output,
445 exclude: assetEntry.ignore
446 };
447 });
448 delete libConfig.assets;
449 }
450 if (libConfig.deleteOutputPath && !libConfig.clean) {
451 libConfig.clean = {
452 beforeBuild: {
453 cleanOutDir: true
454 }
455 };
456 delete libConfig.deleteOutputPath;
457 }
458 if (libConfig.bundleDependencies && libConfig.bundleDependencies === 'all') {
459 libConfig.nodeModulesAsExternals = false;
460 }
461}
462exports.applyLibConfigCompat = applyLibConfigCompat;
463function mergeAppProjectConfigWithWebpackCli(appConfig, commandOptions) {
464 if (commandOptions.target && !appConfig.platformTarget) {
465 appConfig.platformTarget = commandOptions.target;
466 }
467 if (commandOptions.outputPublicPath) {
468 appConfig.publicPath = commandOptions.outputPublicPath;
469 }
470 if (commandOptions.devtool) {
471 appConfig.sourceMap = true;
472 appConfig.sourceMapDevTool = commandOptions.devtool;
473 }
474}
475exports.mergeAppProjectConfigWithWebpackCli = mergeAppProjectConfigWithWebpackCli;
476function overrideProjectConfig(oldConfig, newConfig) {
477 if (!newConfig || !oldConfig || typeof newConfig !== 'object' || Object.keys(newConfig).length === 0) {
478 return;
479 }
480 Object.keys(newConfig).filter((key) => key !== 'envOverrides').forEach((key) => {
481 oldConfig[key] = JSON.parse(JSON.stringify(newConfig[key]));
482 });
483}
484//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlcGFyZS1jb25maWdzLmpzIiwic291cmNlUm9vdCI6IkM6L3Byb2plY3RzL2FuZ3VsYXItYnVpbGQvIiwic291cmNlcyI6WyJzcmMvaGVscGVycy9wcmVwYXJlLWNvbmZpZ3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUF3QjtBQUN4QiwrQkFBK0I7O0FBRS9CLDJCQUFnQztBQUNoQyw2QkFBNkI7QUFFN0Isa0RBQW9FO0FBaUJwRSxvQ0FBK0U7QUFFL0UsbUVBQStEO0FBRS9ELDJDQUNJLGFBQWtFLEVBQ2xFLEdBQXdDO0lBRXhDLElBQUksQ0FBQyxhQUFhO1FBQ2QsQ0FBQyxhQUFhLENBQUMsWUFBWTtRQUMzQixNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1FBQ3RELE9BQU87S0FDVjtJQUVELE1BQU0sWUFBWSxHQUFhLEVBQUUsQ0FBQztJQUVsQyxJQUFJLEdBQUcsQ0FBQyxVQUFVLElBQUksR0FBRyxDQUFDLElBQUksRUFBRTtRQUM1QixJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNoQyxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQzdCO1FBQ0QsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLEVBQUU7WUFDdEMsWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUNuQztLQUNKO1NBQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLEVBQUU7UUFDbkMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QixZQUFZLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0tBQ3BDO0lBRUQsTUFBTSxjQUFjLEdBQUcsQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxhQUFhLENBQUMsQ0FBQztJQUVwRSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztTQUNYLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDdEQsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztRQUMzQixHQUFHLENBQUMsR0FBRyxDQUFDO1FBQ1IsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxTQUFTLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxDQUFDO1NBQzFELE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUNYLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFFUCxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUM7U0FDbEMsT0FBTyxDQUFDLENBQUMsY0FBc0IsRUFBRSxFQUFFO1FBQ2hDLE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQztRQUNsQyxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3RDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDaEIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNiLElBQUksWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRTtnQkFDOUIsTUFBTSxTQUFTLEdBQUksYUFBYSxDQUFDLFlBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3pELElBQUksU0FBUyxJQUFJLE9BQU8sU0FBUyxLQUFLLFFBQVEsRUFBRTtvQkFDNUMscUJBQXFCLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2lCQUNuRDthQUNKO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDLENBQUMsQ0FBQztBQUNYLENBQUM7QUFqREQsOEVBaURDO0FBRUQsc0NBQXNDO0FBQ3RDLG1DQUE2RSxhQUMzQyxFQUM5QixRQUEyQztJQUMzQyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRTtRQUN4QixPQUFPO0tBQ1Y7SUFFRCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDM0csS0FBSyxNQUFNLFVBQVUsSUFBSSxXQUFXLEVBQUU7UUFDbEMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNiLFNBQVM7U0FDWjtRQUVELElBQUksZ0JBQWdCLEdBQTJFLElBQUksQ0FBQztRQUVwRyxJQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO1lBQzFFLElBQUkscUJBQXFCLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUM7Z0JBQ3JELENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUU7Z0JBQ3pDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3hELElBQUksQ0FBQyxxQkFBcUIsRUFBRTtnQkFDeEIsTUFBTSxJQUFJLGlDQUFrQixDQUN4QiwrQ0FBK0MsVUFBVSxxQ0FDekQsYUFBYSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUM7YUFDckM7WUFFRCxNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7WUFDOUUsSUFBSSxpQkFBaUIsS0FBSyxhQUFhLENBQUMsWUFBWSxFQUFFO2dCQUNsRCxNQUFNLElBQUksaUNBQWtCLENBQ3hCLDZFQUNBLGFBQWEsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO2FBQ3JDO1lBRUQscUJBQXFCLEdBQUcsT0FBTyxxQkFBcUIsT0FBTyxDQUFDO1lBQzVELElBQUksaUJBQWlCLEdBQUcsRUFBRSxDQUFDO1lBRTNCLElBQUksZUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLGNBQWMscUJBQXFCLEVBQUUsQ0FBQyxDQUFDLEVBQUU7Z0JBQzVFLGlCQUFpQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLGNBQWMscUJBQXFCLEVBQUUsQ0FBQyxDQUFDO2FBQ3RGO2lCQUFNLElBQUksZUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLGlCQUFpQixxQkFBcUIsRUFBRSxDQUFDLENBQUMsRUFBRTtnQkFDdEYsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLHFCQUFxQixFQUFFLENBQUMsQ0FBQzthQUN6RjtZQUVELElBQUksQ0FBQyxpQkFBaUIsRUFBRTtnQkFDcEIsTUFBTSxJQUFJLGlDQUFrQixDQUN4QiwrQ0FBK0MsaUJBQWlCLHFDQUNoRSxhQUFhLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQzthQUNyQztZQUVELE1BQU0sTUFBTSxHQUFHLG9CQUFZLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUU5QyxNQUF5QyxDQUFDLFlBQVksR0FBRyxhQUFhLENBQUMsWUFBWSxDQUFDO1lBQ3BGLE1BQXlDLENBQUMsV0FBVyxHQUFHLGlCQUFpQixDQUFDO1lBRTNFLE1BQU0sV0FBVyxHQUFZLGFBQXFCLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQztZQUNyRSxNQUFNLENBQUMsWUFBWSxHQUFHLFdBQVcsR0FBRyxDQUFDLENBQUM7WUFFdEMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDO1NBQzdCO2FBQU0sSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQzNDLElBQUssYUFBcUIsQ0FBQyxZQUFZLElBQUksQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0JBQ3pFLFNBQVM7YUFDWjtZQUVELE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2pFLElBQUksQ0FBQyxXQUFXLEVBQUU7Z0JBQ2QsTUFBTSxJQUFJLGlDQUFrQixDQUN4QiwrQ0FBK0MsVUFBVSxxQ0FDekQsYUFBYSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUM7YUFDckM7WUFFRCxNQUFNLGdCQUFnQixHQUNsQixRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxXQUFXLENBQUMsQ0FBQztZQUUzRCxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7Z0JBQ25CLE1BQU0sSUFBSSxpQ0FBa0IsQ0FDeEIsK0NBQStDLFVBQVUscUNBQ3pELGFBQWEsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO2FBQ3JDO1lBRUQsSUFBSSxnQkFBZ0IsQ0FBQyxZQUFZLEtBQUssYUFBYSxDQUFDLFlBQVksRUFBRTtnQkFDOUQsTUFBTSxJQUFJLGlDQUFrQixDQUN4Qiw2RUFDQSxhQUFhLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQzthQUNyQztZQUVELElBQUksZ0JBQWdCLENBQUMsSUFBSSxLQUFLLGFBQWEsQ0FBQyxJQUFJO2dCQUM1QyxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssYUFBYSxDQUFDLE1BQU07Z0JBQ2hELENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEtBQUssYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2pHLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO2FBQ3ZDO1NBQ0o7YUFBTSxJQUFJLGFBQWEsQ0FBQyxXQUFXLEVBQUU7WUFDbEMsSUFBSSxRQUFRLEdBQUcsVUFBVSxDQUFDO1lBQzFCLElBQUksV0FBVyxHQUFHLEVBQUUsQ0FBQztZQUNyQixJQUFJLFdBQVcsR0FBRyxFQUFFLENBQUM7WUFFckIsSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDN0IsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDcEMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtvQkFDcEIsQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLFdBQVcsQ0FBQyxHQUFHLEtBQUssQ0FBQztpQkFDaEQ7YUFDSjtZQUVELFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQztnQkFDaEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO2dCQUN4QixDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUV0RSxJQUFJLENBQUMsZUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFO2dCQUN2QixNQUFNLElBQUksaUNBQWtCLENBQ3hCLCtDQUErQyxRQUFRLHFDQUN2RCxhQUFhLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQzthQUNyQztZQUVELElBQUksTUFBTSxHQUFRLElBQUksQ0FBQztZQUV2QixJQUFJO2dCQUNBLE1BQU0sR0FBRyxvQkFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBRW5DO1lBQUMsT0FBTyxRQUFRLEVBQUU7Z0JBQ2YsTUFBTSxJQUFJLGlDQUFrQixDQUFDLGlDQUFpQyxRQUFRLENBQUMsT0FBTyxJQUFJLFFBQVEsR0FBRyxDQUFDLENBQUM7YUFDbEc7WUFFRCxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUNULE1BQU0sSUFBSSxpQ0FBa0IsQ0FDeEIsK0NBQStDLFFBQVEscUNBQ3ZELGFBQWEsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO2FBQ3JDO1lBRUQsSUFBSSxXQUFXLEVBQUU7Z0JBQ2IsSUFBSSxXQUFXLEtBQUssYUFBYSxDQUFDLFlBQVksRUFBRTtvQkFDNUMsTUFBTSxJQUFJLGlDQUFrQixDQUN4Qiw2RUFDQSxhQUFhLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQztpQkFDckM7Z0JBRUQsTUFBTSxrQkFBa0IsR0FBRyxNQUE0QixDQUFDO2dCQUV4RCxJQUFJLGFBQWEsQ0FBQyxXQUFXLEtBQUssUUFBUSxFQUFFO29CQUN4QyxrQkFBa0I7b0JBQ2xCLE1BQU0sY0FBYyxHQUFHLGFBQWEsQ0FBQztvQkFDckMsSUFBSSxVQUFVLEdBQUcsRUFBRSxDQUFDO29CQUNwQixJQUFJLGVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxjQUFjLGNBQWMsRUFBRSxDQUFDLENBQUMsRUFBRTt3QkFDckUsVUFBVSxHQUFHLGNBQWMsY0FBYyxFQUFFLENBQUM7cUJBQy9DO3lCQUFNLElBQUksZUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLGlCQUFpQixjQUFjLEVBQUUsQ0FBQyxDQUFDLEVBQUU7d0JBQy9FLFVBQVUsR0FBRyxpQkFBaUIsY0FBYyxFQUFFLENBQUM7cUJBQ2xEO29CQUVELElBQUksQ0FBQyxVQUFVLEVBQUU7d0JBQ2IsTUFBTSxJQUFJLDRCQUFhLENBQUMsOENBQThDLENBQUMsQ0FBQztxQkFDM0U7b0JBRUQsK0NBQStDO29CQUMvQyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ25DLElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRTt3QkFDaEIsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDO3FCQUN6QjtvQkFDRCxJQUFJLGtCQUFrQixDQUFDLE9BQU8sRUFBRTt3QkFDNUIsT0FBTyxrQkFBa0IsQ0FBQyxPQUFPLENBQUM7cUJBQ3JDO29CQUVELE1BQU0sTUFBTSxHQUFHLHNCQUFjLENBQUMsTUFBTSxFQUFFLGtCQUFrQixDQUFDLENBQUM7b0JBQzFELElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRTt3QkFDZixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsNkJBQXFCLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUNoRixNQUFNLElBQUksaUNBQWtCLENBQ3hCLDZCQUNBLE1BQU0sRUFBRSxDQUFDLENBQUM7cUJBQ2pCO2lCQUNKO2dCQUVELDZCQUE2QjtnQkFDN0IsTUFBTSwwQkFBMEIsR0FBRyxrQkFBZ0QsQ0FBQztnQkFDcEYsMEJBQTBCLENBQUMsSUFBSSxHQUFHLDBCQUEwQixDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ3hFLDBCQUEwQixDQUFDLElBQUksR0FBRywwQkFBMEIsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO2dCQUV4RSxVQUFVO2dCQUNWLElBQUksYUFBYSxDQUFDLFlBQVksS0FBSyxLQUFLLEVBQUU7b0JBQ3RDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO3dCQUM3RCxNQUFNLFNBQVMsR0FBRywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBRXJELFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO3dCQUNyQixTQUFTLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQzt3QkFDL0IsU0FBUyxDQUFDLFdBQVcsR0FBRyxRQUFRLENBQUM7d0JBRWpDLElBQUksU0FBUyxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUU7NEJBQ2hDLGdCQUFnQixHQUFHLFNBQVMsQ0FBQzs0QkFFN0IsTUFBTSxXQUFXLEdBQVksYUFBcUIsQ0FBQyxZQUFZLElBQUksQ0FBQyxDQUFDOzRCQUNwRSxnQkFBd0IsQ0FBQyxZQUFZLEdBQUcsV0FBVyxHQUFHLENBQUMsQ0FBQzs0QkFFekQsTUFBTTt5QkFDVDtxQkFDSjtpQkFDSjtxQkFBTTtvQkFDSCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsMEJBQTBCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTt3QkFDN0QsTUFBTSxTQUFTLEdBQUcsMEJBQTBCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUNyRCxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQzt3QkFDckIsU0FBUyxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7d0JBQy9CLFNBQVMsQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDO3dCQUVqQyxJQUFJLFNBQVMsQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUFFOzRCQUNoQyxnQkFBZ0IsR0FBRyxTQUFTLENBQUM7NEJBRTdCLE1BQU0sV0FBVyxHQUFZLGFBQXFCLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQzs0QkFDcEUsZ0JBQXdCLENBQUMsWUFBWSxHQUFHLFdBQVcsR0FBRyxDQUFDLENBQUM7NEJBRXpELE1BQU07eUJBQ1Q7cUJBQ0o7aUJBQ0o7YUFDSjtpQkFBTTtnQkFDSCxXQUFXO2dCQUNYLE1BQU0sY0FBYyxHQUFHLGFBQWEsQ0FBQyxZQUFZLEtBQUssS0FBSztvQkFDdkQsQ0FBQyxDQUFDLGdDQUFnQztvQkFDbEMsQ0FBQyxDQUFDLGdDQUFnQyxDQUFDO2dCQUN2QyxJQUFJLFVBQVUsR0FBRyxFQUFFLENBQUM7Z0JBRXBCLElBQUksZUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLGNBQWMsY0FBYyxFQUFFLENBQUMsQ0FBQyxFQUFFO29CQUNyRSxVQUFVLEdBQUcsY0FBYyxjQUFjLEVBQUUsQ0FBQztpQkFDL0M7cUJBQU0sSUFBSSxlQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLGNBQWMsRUFBRSxDQUFDLENBQUMsRUFBRTtvQkFDL0UsVUFBVSxHQUFHLGlCQUFpQixjQUFjLEVBQUUsQ0FBQztpQkFDbEQ7Z0JBRUQsSUFBSSxDQUFDLFVBQVUsRUFBRTtvQkFDYixNQUFNLElBQUksNEJBQWEsQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO2lCQUMzRTtnQkFFRCwrQ0FBK0M7Z0JBQy9DLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDbkMsSUFBSSxNQUFNLENBQUMsT0FBTyxFQUFFO29CQUNoQixPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUM7aUJBQ3pCO2dCQUNELElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRTtvQkFDaEIsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDO2lCQUN6QjtnQkFFRCxNQUFNLE1BQU0sR0FBRyxzQkFBYyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDOUMsSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFO29CQUNmLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyw2QkFBcUIsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ2hGLE1BQU0sSUFBSSxpQ0FBa0IsQ0FDeEIsNkJBQ0EsTUFBTSxFQUFFLENBQUMsQ0FBQztpQkFDakI7Z0JBRUEsTUFBeUMsQ0FBQyxZQUFZLEdBQUcsYUFBYSxDQUFDLFlBQVksQ0FBQztnQkFDcEYsTUFBeUMsQ0FBQyxXQUFXLEdBQUcsYUFBYSxDQUFDLFdBQVcsQ0FBQztnQkFFbkYsTUFBTSxXQUFXLEdBQVksYUFBcUIsQ0FBQyxZQUFZLElBQUksQ0FBQyxDQUFDO2dCQUNyRSxNQUFNLENBQUMsWUFBWSxHQUFHLFdBQVcsR0FBRyxDQUFDLENBQUM7Z0JBRXRDLGdCQUFnQixHQUFHLE1BQU0sQ0FBQzthQUM3QjtTQUNKO1FBRUQsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQ25CLFNBQVM7U0FDWjtRQUVELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQW1DLENBQUM7UUFDekcsSUFBSSxpQkFBaUIsQ0FBQyxPQUFPLEVBQUU7WUFDM0IseUJBQXlCLENBQUMsaUJBQWlCLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFFdkQsT0FBTyxpQkFBaUIsQ0FBQyxPQUFPLENBQUM7U0FDcEM7UUFFRCxJQUFJLGlCQUFpQixDQUFDLElBQUksRUFBRTtZQUN4QixPQUFPLGlCQUFpQixDQUFDLElBQUksQ0FBQztTQUNqQztRQUVELElBQUksaUJBQWlCLENBQUMsT0FBTyxFQUFFO1lBQzNCLE9BQU8saUJBQWlCLENBQUMsT0FBTyxDQUFDO1NBQ3BDO1FBRUQsTUFBTSxjQUFjLHFCQUFRLGlCQUFpQixFQUFLLGFBQWEsQ0FBRSxDQUFDO1FBQ2xFLE1BQU0sQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0tBQ2hEO0FBQ0wsQ0FBQztBQWhSRCw4REFnUkM7QUFFRCwyQ0FBa0QsT0FBMEM7SUFDeEYsTUFBTSxZQUFZLEdBQXdCLEVBQUUsV0FBVyxFQUFFLEVBQUUsRUFBRSxDQUFDO0lBRTlELElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRTtRQUNyQixNQUFNLEdBQUcsR0FBRyw0Q0FBb0IsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdEQsWUFBWSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUM7UUFDL0IsT0FBTyxPQUFPLENBQUMsV0FBVyxDQUFDO0tBQzlCO0lBRUQsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFO1FBQ2hCLFlBQVksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUNyQyxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUM7S0FDekI7SUFFRCxJQUFJLE9BQU8sQ0FBQyxPQUFPLElBQUksSUFBSSxFQUFFO1FBQ3pCLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRTtZQUNqQixZQUFZLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztTQUNuQztRQUNELE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQztLQUMxQjtJQUVELElBQUksT0FBTyxDQUFDLFFBQVEsRUFBRTtRQUNsQixZQUFZLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDekMsT0FBTyxPQUFPLENBQUMsUUFBUSxDQUFDO0tBQzNCO0lBRUQsSUFBSSxPQUFPLENBQUMsUUFBUSxJQUFJLElBQUksRUFBRTtRQUMxQixJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUU7WUFDbEIsWUFBWSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7U0FDaEM7UUFDRCxPQUFPLE9BQU8sQ0FBQyxRQUFRLENBQUM7S0FDM0I7SUFFRCxJQUFJLE9BQU8sQ0FBQyxJQUFJLElBQUksSUFBSSxFQUFFO1FBQ3RCLFlBQVksQ0FBQyxZQUFZLEdBQUc7WUFDeEIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO1NBQ3JCLENBQUM7UUFDRixPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUM7S0FDdkI7SUFFRCxJQUFJLE9BQU8sQ0FBQyxXQUFXLElBQUksSUFBSSxFQUFFO1FBQzdCLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRTtZQUNyQixZQUFZLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztTQUNuQztRQUNELE9BQU8sT0FBTyxDQUFDLFdBQVcsQ0FBQztLQUM5QjtJQUVELElBQUksT0FBTyxDQUFDLEtBQUssSUFBSSxJQUFJLEVBQUU7UUFDdkIsSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFO1lBQ2YsWUFBWSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7U0FDN0I7UUFDRCxPQUFPLE9BQU8sQ0FBQyxLQUFLLENBQUM7S0FDeEI7SUFFRCxJQUFJLE9BQU8sQ0FBQyxZQUFZLEVBQUU7UUFDdEIsWUFBWSxDQUFDLFlBQVkscUJBQVEsT0FBTyxDQUFDLFlBQVksQ0FBRSxDQUFDO1FBQ3hELE9BQU8sT0FBTyxDQUFDLFlBQVksQ0FBQztLQUMvQjtJQUVELElBQUksT0FBTyxDQUFDLElBQUksSUFBSSxJQUFJLEVBQUU7UUFDdEIsSUFBSSxPQUFPLENBQUMsSUFBSSxFQUFFO1lBQ2QsWUFBWSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7U0FDNUI7UUFDRCxPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUM7S0FDdkI7SUFFRCxPQUFPLFlBQVksQ0FBQztBQUN4QixDQUFDO0FBbkVELDhFQW1FQztBQUVELDhCQUFxQyxTQUE0QjtJQUM3RCxJQUFJLFNBQVMsQ0FBQyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFO1FBQy9DLFNBQVMsQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDLE1BQWEsQ0FBQztRQUNuRCxPQUFPLFNBQVMsQ0FBQyxNQUFNLENBQUM7S0FDM0I7SUFDRCxJQUFJLFNBQVMsQ0FBQyxRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFO1FBQ2pELFNBQVMsQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQzVFLE9BQU8sU0FBUyxDQUFDLFFBQVEsQ0FBQztLQUM3QjtJQUNELElBQUksU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUU7UUFDM0MsU0FBUyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQ3hDLE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQztLQUMzQjtJQUNELElBQUksU0FBUyxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUU7UUFDcEMsU0FBUyxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDO1FBQ2pDLE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQztLQUN6QjtJQUNELElBQUksU0FBUyxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUU7UUFDMUMsU0FBUyxDQUFDLFVBQVUsR0FBRztZQUNuQixLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUs7U0FDekIsQ0FBQztRQUNGLE9BQU8sU0FBUyxDQUFDLEtBQUssQ0FBQztLQUMxQjtJQUNELElBQUksU0FBUyxDQUFDLGFBQWEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN4RCxTQUFTLENBQUMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDO1FBQ3BDLE9BQU8sU0FBUyxDQUFDLGFBQWEsQ0FBQztLQUNsQztJQUNELElBQUksU0FBUyxDQUFDLFNBQVMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUU7UUFDOUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDO1FBQzNDLE9BQU8sU0FBUyxDQUFDLFNBQVMsQ0FBQztLQUM5QjtJQUNELElBQUksU0FBUyxDQUFDLE1BQU07UUFDaEIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQy9CLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUU7UUFDaEYsU0FBUyxDQUFDLElBQUksR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFVBQTZDLEVBQUUsRUFBRTtZQUNwRixJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsRUFBRTtnQkFDaEMsT0FBTyxVQUFVLENBQUM7YUFDckI7WUFFRCxPQUFPO2dCQUNILElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ3hELEVBQUUsRUFBRSxVQUFVLENBQUMsTUFBTTtnQkFDckIsT0FBTyxFQUFFLFVBQVUsQ0FBQyxNQUFNO2FBQzdCLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQztLQUMzQjtJQUNELElBQUksU0FBUyxDQUFDLGdCQUFnQixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRTtRQUNoRCxTQUFTLENBQUMsS0FBSyxHQUFHO1lBQ2QsV0FBVyxFQUFFO2dCQUNULFdBQVcsRUFBRSxJQUFJO2FBQ3BCO1NBQ0osQ0FBQztRQUNGLE9BQU8sU0FBUyxDQUFDLGdCQUFnQixDQUFDO0tBQ3JDO0lBQ0QsSUFBSSxTQUFTLENBQUMsU0FBUyxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRTtRQUNsRCxTQUFTLENBQUMsY0FBYyxHQUFHO1lBQ3ZCLGlCQUFpQixFQUFFLElBQUk7U0FDMUIsQ0FBQztRQUNGLE9BQU8sU0FBUyxDQUFDLFNBQVMsQ0FBQztLQUM5QjtJQUNELElBQUksU0FBUyxDQUFDLGtCQUFrQixJQUFJLFNBQVMsQ0FBQyxrQkFBa0IsS0FBSyxNQUFNLEVBQUU7UUFDekUsU0FBUyxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQztRQUN4QyxNQUFNLFNBQVMsR0FBRztZQUNkLFdBQVc7WUFDWCxDQUFDLENBQU0sRUFBRSxPQUFZLEVBQUUsUUFBNkMsRUFBRSxFQUFFO2dCQUNwRSw4Q0FBOEM7Z0JBQzlDLElBQUksT0FBTyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRTtvQkFDN0IsUUFBUSxFQUFFLENBQUM7b0JBRVgsT0FBTztpQkFDVjtnQkFFRCxJQUFJO29CQUNBLHlDQUF5QztvQkFDekMsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDbkMsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFO3dCQUN4QixxQkFBcUI7d0JBQ3JCLFFBQVEsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7cUJBQzNCO3lCQUFNO3dCQUNILHdDQUF3Qzt3QkFDeEMsUUFBUSxFQUFFLENBQUM7cUJBQ2Q7aUJBQ0o7Z0JBQUMsT0FBTyxDQUFDLEVBQUU7b0JBQ1Isb0RBQW9EO29CQUNwRCxRQUFRLEVBQUUsQ0FBQztpQkFDZDtZQUNMLENBQUM7U0FDSixDQUFDO1FBQ0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUU7WUFDdEIsU0FBUyxDQUFDLFNBQVMsR0FBRyxTQUFnQixDQUFDO1NBQzFDO2FBQU07WUFDSCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFO2dCQUNwQyxTQUFTLENBQUMsU0FBUyxHQUFHLENBQUMsR0FBSSxTQUFTLENBQUMsU0FBbUIsRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDO2FBQzNFO2lCQUFNO2dCQUNILFNBQVMsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxTQUFTLENBQUMsU0FBZ0IsRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDO2FBQ3BFO1NBQ0o7UUFDRCxPQUFPLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQztLQUN2QztBQUNMLENBQUM7QUFwR0Qsb0RBb0dDO0FBRUQsOEJBQXFDLFNBQTRCO0lBQzdELElBQUksU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUU7UUFDL0MsU0FBUyxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUMsTUFBYSxDQUFDO1FBQ25ELE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQztLQUMzQjtJQUVELElBQUksU0FBUyxDQUFDLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUU7UUFDakQsU0FBUyxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUMsUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFDNUUsT0FBTyxTQUFTLENBQUMsUUFBUSxDQUFDO0tBQzdCO0lBRUQsSUFBSSxTQUFTLENBQUMsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRTtRQUMzQyxTQUFTLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7UUFDeEMsT0FBTyxTQUFTLENBQUMsTUFBTSxDQUFDO0tBQzNCO0lBRUQsSUFBSSxTQUFTLENBQUMsTUFBTTtRQUNoQixLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7UUFDL0IsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRTtRQUNoRixTQUFTLENBQUMsSUFBSSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQy9DLElBQUksT0FBTyxVQUFVLEtBQUssUUFBUSxFQUFFO2dCQUNoQyxPQUFPLFVBQVUsQ0FBQzthQUNyQjtZQUVELE9BQU87Z0JBQ0gsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDeEQsRUFBRSxFQUFFLFVBQVUsQ0FBQyxNQUFNO2dCQUNyQixPQUFPLEVBQUUsVUFBVSxDQUFDLE1BQU07YUFDN0IsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxTQUFTLENBQUMsTUFBTSxDQUFDO0tBQzNCO0lBRUQsSUFBSSxTQUFTLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFO1FBQ2hELFNBQVMsQ0FBQyxLQUFLLEdBQUc7WUFDZCxXQUFXLEVBQUU7Z0JBQ1QsV0FBVyxFQUFFLElBQUk7YUFDcEI7U0FDSixDQUFDO1FBQ0YsT0FBTyxTQUFTLENBQUMsZ0JBQWdCLENBQUM7S0FDckM7SUFFRCxJQUFJLFNBQVMsQ0FBQyxrQkFBa0IsSUFBSSxTQUFTLENBQUMsa0JBQWtCLEtBQUssS0FBSyxFQUFFO1FBQ3hFLFNBQVMsQ0FBQyxzQkFBc0IsR0FBRyxLQUFLLENBQUM7S0FDNUM7QUFDTCxDQUFDO0FBN0NELG9EQTZDQztBQUVELDZDQUFvRCxTQUFtQyxFQUNuRixjQUFzQztJQUN0QyxJQUFJLGNBQWMsQ0FBQyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFO1FBQ3BELFNBQVMsQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQztLQUNwRDtJQUVELElBQUksY0FBYyxDQUFDLGdCQUFnQixFQUFFO1FBQ2pDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsY0FBYyxDQUFDLGdCQUFnQixDQUFDO0tBQzFEO0lBRUQsSUFBSSxjQUFjLENBQUMsT0FBTyxFQUFFO1FBQ3hCLFNBQVMsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBQzNCLFNBQVMsQ0FBQyxnQkFBZ0IsR0FBRyxjQUFjLENBQUMsT0FBTyxDQUFDO0tBQ3ZEO0FBQ0wsQ0FBQztBQWRELGtGQWNDO0FBRUQsK0JBQStCLFNBQWMsRUFBRSxTQUFjO0lBQ3pELElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxTQUFTLElBQUksT0FBTyxTQUFTLEtBQUssUUFBUSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUNsRyxPQUFPO0tBQ1Y7SUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQVcsRUFBRSxFQUFFLENBQUMsR0FBRyxLQUFLLGNBQWMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQVcsRUFBRSxFQUFFO1FBQzNGLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoRSxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0c2xpbnQ6ZGlzYWJsZTpuby1hbnlcbi8vIHRzbGludDpkaXNhYmxlOm5vLXVuc2FmZS1hbnlcblxuaW1wb3J0IHsgZXhpc3RzU3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5cbmltcG9ydCB7IEludGVybmFsRXJyb3IsIEludmFsaWRDb25maWdFcnJvciB9IGZyb20gJy4uL2Vycm9yLW1vZGVscyc7XG5pbXBvcnQge1xuICAgIEFuZ3VsYXJCdWlsZENvbmZpZyxcbiAgICBBcHBCdWlsZGVyT3B0aW9ucyxcbiAgICBBc3NldFBhdHRlcm5PYmplY3RDb21wYXQsXG4gICAgQnVpbGRPcHRpb25zLFxuICAgIEJ1aWxkT3B0aW9uc0NvbXBhdCxcbiAgICBMaWJCdWlsZGVyT3B0aW9ucyxcbiAgICBQcm9qZWN0Q29uZmlnQmFzZVxufSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7XG4gICAgQW5ndWxhckJ1aWxkQ29uZmlnSW50ZXJuYWwsXG4gICAgQXBwUHJvamVjdENvbmZpZ0ludGVybmFsLFxuICAgIEJ1aWxkT3B0aW9uSW50ZXJuYWwsXG4gICAgTGliUHJvamVjdENvbmZpZ0ludGVybmFsLFxuICAgIFByb2plY3RDb25maWdJbnRlcm5hbFxufSBmcm9tICcuLi9pbnRlcmZhY2VzL2ludGVybmFscyc7XG5pbXBvcnQgeyBmb3JtYXRWYWxpZGF0aW9uRXJyb3IsIHJlYWRKc29uU3luYywgdmFsaWRhdGVTY2hlbWEgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IG5vcm1hbGl6ZUVudmlyb25tZW50IH0gZnJvbSAnLi9ub3JtYWxpemUtZW52aXJvbm1lbnQnO1xuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlQcm9qZWN0Q29uZmlnV2l0aEVudmlyb25tZW50KFxuICAgIHByb2plY3RDb25maWc6IEFwcFByb2plY3RDb25maWdJbnRlcm5hbCB8IExpYlByb2plY3RDb25maWdJbnRlcm5hbCxcbiAgICBlbnY6IHsgW2tleTogc3RyaW5nXTogYm9vbGVhbiB8IHN0cmluZyB9KTogdm9pZCB7XG5cbiAgICBpZiAoIXByb2plY3RDb25maWcgfHxcbiAgICAgICAgIXByb2plY3RDb25maWcuZW52T3ZlcnJpZGVzIHx8XG4gICAgICAgIE9iamVjdC5rZXlzKHByb2plY3RDb25maWcuZW52T3ZlcnJpZGVzKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGJ1aWxkVGFyZ2V0czogc3RyaW5nW10gPSBbXTtcblxuICAgIGlmIChlbnYucHJvZHVjdGlvbiB8fCBlbnYucHJvZCkge1xuICAgICAgICBpZiAoIWJ1aWxkVGFyZ2V0cy5pbmNsdWRlcygncHJvZCcpKSB7XG4gICAgICAgICAgICBidWlsZFRhcmdldHMucHVzaCgncHJvZCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghYnVpbGRUYXJnZXRzLmluY2x1ZGVzKCdwcm9kdWN0aW9uJykpIHtcbiAgICAgICAgICAgIGJ1aWxkVGFyZ2V0cy5wdXNoKCdwcm9kdWN0aW9uJyk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVudi5kZXYgfHwgZW52LmRldmVsb3BtZW50KSB7XG4gICAgICAgIGJ1aWxkVGFyZ2V0cy5wdXNoKCdkZXYnKTtcbiAgICAgICAgYnVpbGRUYXJnZXRzLnB1c2goJ2RldmVsb3BtZW50Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJlRGVmaW5lZEtleXMgPSBbJ3Byb2QnLCAncHJvZHVjdGlvbicsICdkZXYnLCAnZGV2ZWxvcG1lbnQnXTtcblxuICAgIE9iamVjdC5rZXlzKGVudilcbiAgICAgICAgLmZpbHRlcihrZXkgPT4gIXByZURlZmluZWRLZXlzLmluY2x1ZGVzKGtleS50b0xvd2VyQ2FzZSgpKSAmJlxuICAgICAgICAgICAgIWJ1aWxkVGFyZ2V0cy5pbmNsdWRlcyhrZXkpICYmXG4gICAgICAgICAgICBlbnZba2V5XSAmJlxuICAgICAgICAgICAgKHR5cGVvZiBlbnZba2V5XSA9PT0gJ2Jvb2xlYW4nIHx8IGVudltrZXldID09PSAndHJ1ZScpKVxuICAgICAgICAuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgYnVpbGRUYXJnZXRzLnB1c2goa2V5KTtcbiAgICAgICAgfSk7XG5cbiAgICBPYmplY3Qua2V5cyhwcm9qZWN0Q29uZmlnLmVudk92ZXJyaWRlcylcbiAgICAgICAgLmZvckVhY2goKGJ1aWxkVGFyZ2V0S2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldE5hbWUgPSBidWlsZFRhcmdldEtleTtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldHMgPSB0YXJnZXROYW1lLnNwbGl0KCcsJyk7XG4gICAgICAgICAgICB0YXJnZXRzLmZvckVhY2godCA9PiB7XG4gICAgICAgICAgICAgICAgdCA9IHQudHJpbSgpO1xuICAgICAgICAgICAgICAgIGlmIChidWlsZFRhcmdldHMuaW5kZXhPZih0KSA+IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0NvbmZpZyA9IChwcm9qZWN0Q29uZmlnLmVudk92ZXJyaWRlcyBhcyBhbnkpW3RdO1xuICAgICAgICAgICAgICAgICAgICBpZiAobmV3Q29uZmlnICYmIHR5cGVvZiBuZXdDb25maWcgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvdmVycmlkZVByb2plY3RDb25maWcocHJvamVjdENvbmZpZywgbmV3Q29uZmlnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbn1cblxuLy8gdHNsaW50OmRpc2FibGU6bWF4LWZ1bmMtYm9keS1sZW5ndGhcbmV4cG9ydCBmdW5jdGlvbiBhcHBseVByb2plY3RDb25maWdFeHRlbmRzPFRDb25maWcgZXh0ZW5kcyBQcm9qZWN0Q29uZmlnQmFzZT4ocHJvamVjdENvbmZpZzpcbiAgICBQcm9qZWN0Q29uZmlnSW50ZXJuYWw8VENvbmZpZz4sXG4gICAgcHJvamVjdHM/OiBQcm9qZWN0Q29uZmlnSW50ZXJuYWw8VENvbmZpZz5bXSk6IHZvaWQge1xuICAgIGlmICghcHJvamVjdENvbmZpZy5leHRlbmRzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBleHRlbmRBcnJheSA9IEFycmF5LmlzQXJyYXkocHJvamVjdENvbmZpZy5leHRlbmRzKSA/IHByb2plY3RDb25maWcuZXh0ZW5kcyA6IFtwcm9qZWN0Q29uZmlnLmV4dGVuZHNdO1xuICAgIGZvciAoY29uc3QgZXh0ZW5kTmFtZSBvZiBleHRlbmRBcnJheSkge1xuICAgICAgICBpZiAoIWV4dGVuZE5hbWUpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGZvdW5kQmFzZVByb2plY3Q6IEFwcFByb2plY3RDb25maWdJbnRlcm5hbCB8IExpYlByb2plY3RDb25maWdJbnRlcm5hbCB8IG51bGwgfCB1bmRlZmluZWQgPSBudWxsO1xuXG4gICAgICAgIGlmIChleHRlbmROYW1lLnN0YXJ0c1dpdGgoJ25nYjonKSB8fCBleHRlbmROYW1lLnN0YXJ0c1dpdGgoJ2FuZ3VsYXItYnVpbGQ6JykpIHtcbiAgICAgICAgICAgIGxldCBidWlsdEluQ29uZmlnRmlsZU5hbWUgPSBleHRlbmROYW1lLnN0YXJ0c1dpdGgoJ25nYjonKVxuICAgICAgICAgICAgICAgID8gZXh0ZW5kTmFtZS5zdWJzdHIoJ25nYjonLmxlbmd0aCkudHJpbSgpXG4gICAgICAgICAgICAgICAgOiBleHRlbmROYW1lLnN1YnN0cignYW5ndWxhci1idWlsZDonLmxlbmd0aCkudHJpbSgpO1xuICAgICAgICAgICAgaWYgKCFidWlsdEluQ29uZmlnRmlsZU5hbWUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZENvbmZpZ0Vycm9yKFxuICAgICAgICAgICAgICAgICAgICBgQ2FuJ3QgZXh0ZW5kIGZyb20gbm9uIGV4aXN0ZWQgY29uZmlnIGZpbGUgLSAke2V4dGVuZE5hbWV9LCBjaGVjayB5b3VyIGNvbmZpZ3VyYXRpb24gZmlsZSAtICR7XG4gICAgICAgICAgICAgICAgICAgIHByb2plY3RDb25maWcuX2NvbmZpZ1BhdGh9LmApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0YXJnZXRQcm9qZWN0VHlwZSA9IC9ebGliLS8udGVzdChidWlsdEluQ29uZmlnRmlsZU5hbWUpID8gJ2xpYicgOiAnYXBwJztcbiAgICAgICAgICAgIGlmICh0YXJnZXRQcm9qZWN0VHlwZSAhPT0gcHJvamVjdENvbmZpZy5fcHJvamVjdFR5cGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZENvbmZpZ0Vycm9yKFxuICAgICAgICAgICAgICAgICAgICBgQ2FuJ3QgZXh0ZW5kIGZyb20gZGlmZmVyZW50IHByb2plY3QgdHlwZSwgY2hlY2sgeW91ciBjb25maWd1cmF0aW9uIGZpbGUgLSAke1xuICAgICAgICAgICAgICAgICAgICBwcm9qZWN0Q29uZmlnLl9jb25maWdQYXRofS5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnVpbHRJbkNvbmZpZ0ZpbGVOYW1lID0gYG5nYi0ke2J1aWx0SW5Db25maWdGaWxlTmFtZX0uanNvbmA7XG4gICAgICAgICAgICBsZXQgYnVpbHRJbkNvbmZpZ1BhdGggPSAnJztcblxuICAgICAgICAgICAgaWYgKGV4aXN0c1N5bmMocGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgYC4uL2NvbmZpZ3MvJHtidWlsdEluQ29uZmlnRmlsZU5hbWV9YCkpKSB7XG4gICAgICAgICAgICAgICAgYnVpbHRJbkNvbmZpZ1BhdGggPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCBgLi4vY29uZmlncy8ke2J1aWx0SW5Db25maWdGaWxlTmFtZX1gKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZXhpc3RzU3luYyhwYXRoLnJlc29sdmUoX19kaXJuYW1lLCBgLi4vLi4vY29uZmlncy8ke2J1aWx0SW5Db25maWdGaWxlTmFtZX1gKSkpIHtcbiAgICAgICAgICAgICAgICBidWlsdEluQ29uZmlnUGF0aCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsIGAuLi8uLi9jb25maWdzLyR7YnVpbHRJbkNvbmZpZ0ZpbGVOYW1lfWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWJ1aWx0SW5Db25maWdQYXRoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRDb25maWdFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYENhbid0IGV4dGVuZCBmcm9tIG5vbiBleGlzdGVkIGNvbmZpZyBmaWxlIC0gJHtidWlsdEluQ29uZmlnUGF0aH0sIGNoZWNrIHlvdXIgY29uZmlndXJhdGlvbiBmaWxlIC0gJHtcbiAgICAgICAgICAgICAgICAgICAgcHJvamVjdENvbmZpZy5fY29uZmlnUGF0aH0uYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IHJlYWRKc29uU3luYyhidWlsdEluQ29uZmlnUGF0aCk7XG5cbiAgICAgICAgICAgIChjb25maWcgYXMgUHJvamVjdENvbmZpZ0ludGVybmFsPFRDb25maWc+KS5fcHJvamVjdFR5cGUgPSBwcm9qZWN0Q29uZmlnLl9wcm9qZWN0VHlwZTtcbiAgICAgICAgICAgIChjb25maWcgYXMgUHJvamVjdENvbmZpZ0ludGVybmFsPFRDb25maWc+KS5fY29uZmlnUGF0aCA9IGJ1aWx0SW5Db25maWdQYXRoO1xuXG4gICAgICAgICAgICBjb25zdCBleHRlbmRMZXZlbDogbnVtYmVyID0gKHByb2plY3RDb25maWcgYXMgYW55KS5fZXh0ZW5kTGV2ZWwgfHwgMDtcbiAgICAgICAgICAgIGNvbmZpZy5fZXh0ZW5kTGV2ZWwgPSBleHRlbmRMZXZlbCArIDE7XG5cbiAgICAgICAgICAgIGZvdW5kQmFzZVByb2plY3QgPSBjb25maWc7XG4gICAgICAgIH0gZWxzZSBpZiAoZXh0ZW5kTmFtZS5zdGFydHNXaXRoKCdwcm9qZWN0czonKSkge1xuICAgICAgICAgICAgaWYgKChwcm9qZWN0Q29uZmlnIGFzIGFueSkuX2V4dGVuZExldmVsIHx8ICFwcm9qZWN0cyB8fCBwcm9qZWN0cy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHByb2plY3ROYW1lID0gZXh0ZW5kTmFtZS5zdWJzdHIoJ3Byb2plY3RzOicubGVuZ3RoKS50cmltKCk7XG4gICAgICAgICAgICBpZiAoIXByb2plY3ROYW1lKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRDb25maWdFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYENhbid0IGV4dGVuZCBmcm9tIG5vbiBleGlzdGVkIGNvbmZpZyBmaWxlIC0gJHtleHRlbmROYW1lfSwgY2hlY2sgeW91ciBjb25maWd1cmF0aW9uIGZpbGUgLSAke1xuICAgICAgICAgICAgICAgICAgICBwcm9qZWN0Q29uZmlnLl9jb25maWdQYXRofS5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdGVtcEZvdW5kUHJvamVjdCA9XG4gICAgICAgICAgICAgICAgcHJvamVjdHMuZmluZChwcm9qZWN0ID0+IHByb2plY3QubmFtZSA9PT0gcHJvamVjdE5hbWUpO1xuXG4gICAgICAgICAgICBpZiAoIXRlbXBGb3VuZFByb2plY3QpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZENvbmZpZ0Vycm9yKFxuICAgICAgICAgICAgICAgICAgICBgQ2FuJ3QgZXh0ZW5kIGZyb20gbm9uIGV4aXN0ZWQgY29uZmlnIGZpbGUgLSAke2V4dGVuZE5hbWV9LCBjaGVjayB5b3VyIGNvbmZpZ3VyYXRpb24gZmlsZSAtICR7XG4gICAgICAgICAgICAgICAgICAgIHByb2plY3RDb25maWcuX2NvbmZpZ1BhdGh9LmApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGVtcEZvdW5kUHJvamVjdC5fcHJvamVjdFR5cGUgIT09IHByb2plY3RDb25maWcuX3Byb2plY3RUeXBlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRDb25maWdFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYENhbid0IGV4dGVuZCBmcm9tIGRpZmZlcmVudCBwcm9qZWN0IHR5cGUsIGNoZWNrIHlvdXIgY29uZmlndXJhdGlvbiBmaWxlIC0gJHtcbiAgICAgICAgICAgICAgICAgICAgcHJvamVjdENvbmZpZy5fY29uZmlnUGF0aH0uYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0ZW1wRm91bmRQcm9qZWN0Lm5hbWUgIT09IHByb2plY3RDb25maWcubmFtZSAmJlxuICAgICAgICAgICAgICAgIHRlbXBGb3VuZFByb2plY3QuX2luZGV4ICE9PSBwcm9qZWN0Q29uZmlnLl9pbmRleCAmJlxuICAgICAgICAgICAgICAgICghdGVtcEZvdW5kUHJvamVjdC5fY29uZmlnUGF0aCB8fCAodGVtcEZvdW5kUHJvamVjdC5fY29uZmlnUGF0aCA9PT0gcHJvamVjdENvbmZpZy5fY29uZmlnUGF0aCkpKSB7XG4gICAgICAgICAgICAgICAgZm91bmRCYXNlUHJvamVjdCA9IHRlbXBGb3VuZFByb2plY3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAocHJvamVjdENvbmZpZy5fY29uZmlnUGF0aCkge1xuICAgICAgICAgICAgbGV0IGRlc3RQYXRoID0gZXh0ZW5kTmFtZTtcbiAgICAgICAgICAgIGxldCBwcm9qZWN0VHlwZSA9ICcnO1xuICAgICAgICAgICAgbGV0IHByb2plY3ROYW1lID0gJyc7XG5cbiAgICAgICAgICAgIGlmIChleHRlbmROYW1lLmluZGV4T2YoJzonKSA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJ0cyA9IGV4dGVuZE5hbWUuc3BsaXQoJzonKTtcbiAgICAgICAgICAgICAgICBpZiAocGFydHMubGVuZ3RoID09PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgIFtkZXN0UGF0aCwgcHJvamVjdFR5cGUsIHByb2plY3ROYW1lXSA9IHBhcnRzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGVzdFBhdGggPSBwYXRoLmlzQWJzb2x1dGUoZGVzdFBhdGgpXG4gICAgICAgICAgICAgICAgPyBwYXRoLnJlc29sdmUoZGVzdFBhdGgpXG4gICAgICAgICAgICAgICAgOiBwYXRoLnJlc29sdmUocGF0aC5kaXJuYW1lKHByb2plY3RDb25maWcuX2NvbmZpZ1BhdGgpLCBkZXN0UGF0aCk7XG5cbiAgICAgICAgICAgIGlmICghZXhpc3RzU3luYyhkZXN0UGF0aCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZENvbmZpZ0Vycm9yKFxuICAgICAgICAgICAgICAgICAgICBgQ2FuJ3QgZXh0ZW5kIGZyb20gbm9uIGV4aXN0ZWQgY29uZmlnIGZpbGUgLSAke2Rlc3RQYXRofSwgY2hlY2sgeW91ciBjb25maWd1cmF0aW9uIGZpbGUgLSAke1xuICAgICAgICAgICAgICAgICAgICBwcm9qZWN0Q29uZmlnLl9jb25maWdQYXRofS5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IGNvbmZpZzogYW55ID0gbnVsbDtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25maWcgPSByZWFkSnNvblN5bmMoZGVzdFBhdGgpO1xuXG4gICAgICAgICAgICB9IGNhdGNoIChqc29uRXJyMikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQ29uZmlnRXJyb3IoYEludmFsaWQgY29uZmlndXJhdGlvbiwgZXJyb3I6ICR7anNvbkVycjIubWVzc2FnZSB8fCBqc29uRXJyMn0uYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghY29uZmlnKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRDb25maWdFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYENhbid0IGV4dGVuZCBmcm9tIG5vbiBleGlzdGVkIGNvbmZpZyBmaWxlIC0gJHtkZXN0UGF0aH0sIGNoZWNrIHlvdXIgY29uZmlndXJhdGlvbiBmaWxlIC0gJHtcbiAgICAgICAgICAgICAgICAgICAgcHJvamVjdENvbmZpZy5fY29uZmlnUGF0aH0uYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwcm9qZWN0TmFtZSkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9qZWN0VHlwZSAhPT0gcHJvamVjdENvbmZpZy5fcHJvamVjdFR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRDb25maWdFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIGBDYW4ndCBleHRlbmQgZnJvbSBkaWZmZXJlbnQgcHJvamVjdCB0eXBlLCBjaGVjayB5b3VyIGNvbmZpZ3VyYXRpb24gZmlsZSAtICR7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9qZWN0Q29uZmlnLl9jb25maWdQYXRofS5gKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBhbmd1bGFyQnVpbGRDb25maWcgPSBjb25maWcgYXMgQW5ndWxhckJ1aWxkQ29uZmlnO1xuXG4gICAgICAgICAgICAgICAgaWYgKHByb2plY3RDb25maWcuX2NvbmZpZ1BhdGggIT09IGRlc3RQYXRoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFZhbGlkYXRlIHNjaGVtYVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWFGaWxlTmFtZSA9ICdzY2hlbWEuanNvbic7XG4gICAgICAgICAgICAgICAgICAgIGxldCBzY2hlbWFQYXRoID0gJyc7XG4gICAgICAgICAgICAgICAgICAgIGlmIChleGlzdHNTeW5jKHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsIGAuLi9zY2hlbWFzLyR7c2NoZW1hRmlsZU5hbWV9YCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFQYXRoID0gYC4uL3NjaGVtYXMvJHtzY2hlbWFGaWxlTmFtZX1gO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV4aXN0c1N5bmMocGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgYC4uLy4uL3NjaGVtYXMvJHtzY2hlbWFGaWxlTmFtZX1gKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYVBhdGggPSBgLi4vLi4vc2NoZW1hcy8ke3NjaGVtYUZpbGVOYW1lfWA7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoIXNjaGVtYVBhdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiVGhlIGFuZ3VsYXItYnVpbGQgc2NoZW1hIGZpbGUgZG9lc24ndCBleGlzdC5cIik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm9uLWxpdGVyYWwtcmVxdWlyZVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWEgPSByZXF1aXJlKHNjaGVtYVBhdGgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2NoZW1hLiRzY2hlbWEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBzY2hlbWEuJHNjaGVtYTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5ndWxhckJ1aWxkQ29uZmlnLiRzY2hlbWEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhbmd1bGFyQnVpbGRDb25maWcuJHNjaGVtYTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9ycyA9IHZhbGlkYXRlU2NoZW1hKHNjaGVtYSwgYW5ndWxhckJ1aWxkQ29uZmlnKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVyck1zZyA9IGVycm9ycy5tYXAoZXJyID0+IGZvcm1hdFZhbGlkYXRpb25FcnJvcihzY2hlbWEsIGVycikpLmpvaW4oJ1xcbicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRDb25maWdFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgSW52YWxpZCBjb25maWd1cmF0aW9uLlxcblxcbiR7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyTXNnfWApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gU2V0IGFuZ3VsYXIgYnVpbGQgZGVmYXVsdHNcbiAgICAgICAgICAgICAgICBjb25zdCBhbmd1bGFyQnVpbGRDb25maWdJbnRlcm5hbCA9IGFuZ3VsYXJCdWlsZENvbmZpZyBhcyBBbmd1bGFyQnVpbGRDb25maWdJbnRlcm5hbDtcbiAgICAgICAgICAgICAgICBhbmd1bGFyQnVpbGRDb25maWdJbnRlcm5hbC5saWJzID0gYW5ndWxhckJ1aWxkQ29uZmlnSW50ZXJuYWwubGlicyB8fCBbXTtcbiAgICAgICAgICAgICAgICBhbmd1bGFyQnVpbGRDb25maWdJbnRlcm5hbC5hcHBzID0gYW5ndWxhckJ1aWxkQ29uZmlnSW50ZXJuYWwuYXBwcyB8fCBbXTtcblxuICAgICAgICAgICAgICAgIC8vIGV4dGVuZHNcbiAgICAgICAgICAgICAgICBpZiAocHJvamVjdENvbmZpZy5fcHJvamVjdFR5cGUgPT09ICdsaWInKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYW5ndWxhckJ1aWxkQ29uZmlnSW50ZXJuYWwubGlicy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGliQ29uZmlnID0gYW5ndWxhckJ1aWxkQ29uZmlnSW50ZXJuYWwubGlic1tpXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbGliQ29uZmlnLl9pbmRleCA9IGk7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaWJDb25maWcuX3Byb2plY3RUeXBlID0gJ2xpYic7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaWJDb25maWcuX2NvbmZpZ1BhdGggPSBkZXN0UGF0aDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpYkNvbmZpZy5uYW1lID09PSBwcm9qZWN0TmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kQmFzZVByb2plY3QgPSBsaWJDb25maWc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleHRlbmRMZXZlbDogbnVtYmVyID0gKHByb2plY3RDb25maWcgYXMgYW55KS5fZXh0ZW5kTGV2ZWwgfHwgMDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm91bmRCYXNlUHJvamVjdCBhcyBhbnkpLl9leHRlbmRMZXZlbCA9IGV4dGVuZExldmVsICsgMTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhbmd1bGFyQnVpbGRDb25maWdJbnRlcm5hbC5hcHBzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhcHBDb25maWcgPSBhbmd1bGFyQnVpbGRDb25maWdJbnRlcm5hbC5hcHBzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXBwQ29uZmlnLl9pbmRleCA9IGk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBDb25maWcuX3Byb2plY3RUeXBlID0gJ2FwcCc7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBDb25maWcuX2NvbmZpZ1BhdGggPSBkZXN0UGF0aDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFwcENvbmZpZy5uYW1lID09PSBwcm9qZWN0TmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kQmFzZVByb2plY3QgPSBhcHBDb25maWc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleHRlbmRMZXZlbDogbnVtYmVyID0gKHByb2plY3RDb25maWcgYXMgYW55KS5fZXh0ZW5kTGV2ZWwgfHwgMDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm91bmRCYXNlUHJvamVjdCBhcyBhbnkpLl9leHRlbmRMZXZlbCA9IGV4dGVuZExldmVsICsgMTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyB2YWxpZGF0ZVxuICAgICAgICAgICAgICAgIGNvbnN0IHNjaGVtYUZpbGVOYW1lID0gcHJvamVjdENvbmZpZy5fcHJvamVjdFR5cGUgPT09ICdsaWInXG4gICAgICAgICAgICAgICAgICAgID8gJ2xpYi1wcm9qZWN0LWNvbmZpZy1zY2hlbWEuanNvbidcbiAgICAgICAgICAgICAgICAgICAgOiAnYXBwLXByb2plY3QtY29uZmlnLXNjaGVtYS5qc29uJztcbiAgICAgICAgICAgICAgICBsZXQgc2NoZW1hUGF0aCA9ICcnO1xuXG4gICAgICAgICAgICAgICAgaWYgKGV4aXN0c1N5bmMocGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgYC4uL3NjaGVtYXMvJHtzY2hlbWFGaWxlTmFtZX1gKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hUGF0aCA9IGAuLi9zY2hlbWFzLyR7c2NoZW1hRmlsZU5hbWV9YDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV4aXN0c1N5bmMocGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgYC4uLy4uL3NjaGVtYXMvJHtzY2hlbWFGaWxlTmFtZX1gKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hUGF0aCA9IGAuLi8uLi9zY2hlbWFzLyR7c2NoZW1hRmlsZU5hbWV9YDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIXNjaGVtYVBhdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJUaGUgYW5ndWxhci1idWlsZCBzY2hlbWEgZmlsZSBkb2Vzbid0IGV4aXN0LlwiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm9uLWxpdGVyYWwtcmVxdWlyZVxuICAgICAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHJlcXVpcmUoc2NoZW1hUGF0aCk7XG4gICAgICAgICAgICAgICAgaWYgKHNjaGVtYS4kc2NoZW1hKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBzY2hlbWEuJHNjaGVtYTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGNvbmZpZy4kc2NoZW1hKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjb25maWcuJHNjaGVtYTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvcnMgPSB2YWxpZGF0ZVNjaGVtYShzY2hlbWEsIGNvbmZpZyk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyTXNnID0gZXJyb3JzLm1hcChlcnIgPT4gZm9ybWF0VmFsaWRhdGlvbkVycm9yKHNjaGVtYSwgZXJyKSkuam9pbignXFxuJyk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQ29uZmlnRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBgSW52YWxpZCBjb25maWd1cmF0aW9uLlxcblxcbiR7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJNc2d9YCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgKGNvbmZpZyBhcyBQcm9qZWN0Q29uZmlnSW50ZXJuYWw8VENvbmZpZz4pLl9wcm9qZWN0VHlwZSA9IHByb2plY3RDb25maWcuX3Byb2plY3RUeXBlO1xuICAgICAgICAgICAgICAgIChjb25maWcgYXMgUHJvamVjdENvbmZpZ0ludGVybmFsPFRDb25maWc+KS5fY29uZmlnUGF0aCA9IHByb2plY3RDb25maWcuX2NvbmZpZ1BhdGg7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBleHRlbmRMZXZlbDogbnVtYmVyID0gKHByb2plY3RDb25maWcgYXMgYW55KS5fZXh0ZW5kTGV2ZWwgfHwgMDtcbiAgICAgICAgICAgICAgICBjb25maWcuX2V4dGVuZExldmVsID0gZXh0ZW5kTGV2ZWwgKyAxO1xuXG4gICAgICAgICAgICAgICAgZm91bmRCYXNlUHJvamVjdCA9IGNvbmZpZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZm91bmRCYXNlUHJvamVjdCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjbG9uZWRCYXNlUHJvamVjdCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZm91bmRCYXNlUHJvamVjdCkpIGFzIFByb2plY3RDb25maWdJbnRlcm5hbDxUQ29uZmlnPjtcbiAgICAgICAgaWYgKGNsb25lZEJhc2VQcm9qZWN0LmV4dGVuZHMpIHtcbiAgICAgICAgICAgIGFwcGx5UHJvamVjdENvbmZpZ0V4dGVuZHMoY2xvbmVkQmFzZVByb2plY3QsIHByb2plY3RzKTtcblxuICAgICAgICAgICAgZGVsZXRlIGNsb25lZEJhc2VQcm9qZWN0LmV4dGVuZHM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2xvbmVkQmFzZVByb2plY3QubmFtZSkge1xuICAgICAgICAgICAgZGVsZXRlIGNsb25lZEJhc2VQcm9qZWN0Lm5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2xvbmVkQmFzZVByb2plY3QuJHNjaGVtYSkge1xuICAgICAgICAgICAgZGVsZXRlIGNsb25lZEJhc2VQcm9qZWN0LiRzY2hlbWE7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBleHRlbmRlZENvbmZpZyA9IHsgLi4uY2xvbmVkQmFzZVByb2plY3QsIC4uLnByb2plY3RDb25maWcgfTtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihwcm9qZWN0Q29uZmlnLCBleHRlbmRlZENvbmZpZyk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QnVpbGRPcHRpb25zRnJvbUJ1aWxkZXJPcHRpb25zKG9wdGlvbnM6IEJ1aWxkT3B0aW9ucyAmIEJ1aWxkT3B0aW9uc0NvbXBhdCk6IEJ1aWxkT3B0aW9uSW50ZXJuYWwge1xuICAgIGNvbnN0IGJ1aWxkT3B0aW9uczogQnVpbGRPcHRpb25JbnRlcm5hbCA9IHsgZW52aXJvbm1lbnQ6IHt9IH07XG5cbiAgICBpZiAob3B0aW9ucy5lbnZpcm9ubWVudCkge1xuICAgICAgICBjb25zdCBlbnYgPSBub3JtYWxpemVFbnZpcm9ubWVudChvcHRpb25zLmVudmlyb25tZW50KTtcbiAgICAgICAgYnVpbGRPcHRpb25zLmVudmlyb25tZW50ID0gZW52O1xuICAgICAgICBkZWxldGUgb3B0aW9ucy5lbnZpcm9ubWVudDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5maWx0ZXIpIHtcbiAgICAgICAgYnVpbGRPcHRpb25zLmZpbHRlciA9IG9wdGlvbnMuZmlsdGVyO1xuICAgICAgICBkZWxldGUgb3B0aW9ucy5maWx0ZXI7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMudmVyYm9zZSAhPSBudWxsKSB7XG4gICAgICAgIGlmIChvcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgICAgIGJ1aWxkT3B0aW9ucy5sb2dMZXZlbCA9ICdkZWJ1Zyc7XG4gICAgICAgIH1cbiAgICAgICAgZGVsZXRlIG9wdGlvbnMudmVyYm9zZTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5sb2dMZXZlbCkge1xuICAgICAgICBidWlsZE9wdGlvbnMubG9nTGV2ZWwgPSBvcHRpb25zLmxvZ0xldmVsO1xuICAgICAgICBkZWxldGUgb3B0aW9ucy5sb2dMZXZlbDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5wcm9ncmVzcyAhPSBudWxsKSB7XG4gICAgICAgIGlmIChvcHRpb25zLnByb2dyZXNzKSB7XG4gICAgICAgICAgICBidWlsZE9wdGlvbnMucHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGRlbGV0ZSBvcHRpb25zLnByb2dyZXNzO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnBvbGwgIT0gbnVsbCkge1xuICAgICAgICBidWlsZE9wdGlvbnMud2F0Y2hPcHRpb25zID0ge1xuICAgICAgICAgICAgcG9sbDogb3B0aW9ucy5wb2xsXG4gICAgICAgIH07XG4gICAgICAgIGRlbGV0ZSBvcHRpb25zLnBvbGw7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuY2xlYW5PdXREaXIgIT0gbnVsbCkge1xuICAgICAgICBpZiAob3B0aW9ucy5jbGVhbk91dERpcikge1xuICAgICAgICAgICAgYnVpbGRPcHRpb25zLmNsZWFuT3V0RGlyID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBkZWxldGUgb3B0aW9ucy5jbGVhbk91dERpcjtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy53YXRjaCAhPSBudWxsKSB7XG4gICAgICAgIGlmIChvcHRpb25zLndhdGNoKSB7XG4gICAgICAgICAgICBidWlsZE9wdGlvbnMud2F0Y2ggPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGRlbGV0ZSBvcHRpb25zLndhdGNoO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLndhdGNoT3B0aW9ucykge1xuICAgICAgICBidWlsZE9wdGlvbnMud2F0Y2hPcHRpb25zID0geyAuLi5vcHRpb25zLndhdGNoT3B0aW9ucyB9O1xuICAgICAgICBkZWxldGUgb3B0aW9ucy53YXRjaE9wdGlvbnM7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuYmVlcCAhPSBudWxsKSB7XG4gICAgICAgIGlmIChvcHRpb25zLmJlZXApIHtcbiAgICAgICAgICAgIGJ1aWxkT3B0aW9ucy5iZWVwID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBkZWxldGUgb3B0aW9ucy5iZWVwO1xuICAgIH1cblxuICAgIHJldHVybiBidWlsZE9wdGlvbnM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcHBseUFwcENvbmZpZ0NvbXBhdChhcHBDb25maWc6IEFwcEJ1aWxkZXJPcHRpb25zKTogdm9pZCB7XG4gICAgaWYgKGFwcENvbmZpZy50YXJnZXQgJiYgIWFwcENvbmZpZy5wbGF0Zm9ybVRhcmdldCkge1xuICAgICAgICBhcHBDb25maWcucGxhdGZvcm1UYXJnZXQgPSBhcHBDb25maWcudGFyZ2V0IGFzIGFueTtcbiAgICAgICAgZGVsZXRlIGFwcENvbmZpZy50YXJnZXQ7XG4gICAgfVxuICAgIGlmIChhcHBDb25maWcucGxhdGZvcm0gJiYgIWFwcENvbmZpZy5wbGF0Zm9ybVRhcmdldCkge1xuICAgICAgICBhcHBDb25maWcucGxhdGZvcm1UYXJnZXQgPSBhcHBDb25maWcucGxhdGZvcm0gPT09ICdzZXJ2ZXInID8gJ25vZGUnIDogJ3dlYic7XG4gICAgICAgIGRlbGV0ZSBhcHBDb25maWcucGxhdGZvcm07XG4gICAgfVxuICAgIGlmIChhcHBDb25maWcub3V0RGlyICYmICFhcHBDb25maWcub3V0cHV0UGF0aCkge1xuICAgICAgICBhcHBDb25maWcub3V0cHV0UGF0aCA9IGFwcENvbmZpZy5vdXREaXI7XG4gICAgICAgIGRlbGV0ZSBhcHBDb25maWcub3V0RGlyO1xuICAgIH1cbiAgICBpZiAoYXBwQ29uZmlnLm1haW4gJiYgIWFwcENvbmZpZy5lbnRyeSkge1xuICAgICAgICBhcHBDb25maWcuZW50cnkgPSBhcHBDb25maWcubWFpbjtcbiAgICAgICAgZGVsZXRlIGFwcENvbmZpZy5tYWluO1xuICAgIH1cbiAgICBpZiAoYXBwQ29uZmlnLmluZGV4ICYmICFhcHBDb25maWcuaHRtbEluamVjdCkge1xuICAgICAgICBhcHBDb25maWcuaHRtbEluamVjdCA9IHtcbiAgICAgICAgICAgIGluZGV4OiBhcHBDb25maWcuaW5kZXhcbiAgICAgICAgfTtcbiAgICAgICAgZGVsZXRlIGFwcENvbmZpZy5pbmRleDtcbiAgICB9XG4gICAgaWYgKGFwcENvbmZpZy5ldmFsU291cmNlTWFwICYmICFhcHBDb25maWcuc291cmNlTWFwRGV2VG9vbCkge1xuICAgICAgICBhcHBDb25maWcuc291cmNlTWFwRGV2VG9vbCA9ICdldmFsJztcbiAgICAgICAgZGVsZXRlIGFwcENvbmZpZy5ldmFsU291cmNlTWFwO1xuICAgIH1cbiAgICBpZiAoYXBwQ29uZmlnLmRlcGxveVVybCAmJiAhYXBwQ29uZmlnLnB1YmxpY1BhdGgpIHtcbiAgICAgICAgYXBwQ29uZmlnLnB1YmxpY1BhdGggPSBhcHBDb25maWcuZGVwbG95VXJsO1xuICAgICAgICBkZWxldGUgYXBwQ29uZmlnLmRlcGxveVVybDtcbiAgICB9XG4gICAgaWYgKGFwcENvbmZpZy5hc3NldHMgJiZcbiAgICAgICAgQXJyYXkuaXNBcnJheShhcHBDb25maWcuYXNzZXRzKSAmJlxuICAgICAgICAoIWFwcENvbmZpZy5jb3B5IHx8IChBcnJheS5pc0FycmF5KGFwcENvbmZpZy5jb3B5KSAmJiAhYXBwQ29uZmlnLmNvcHkubGVuZ3RoKSkpIHtcbiAgICAgICAgYXBwQ29uZmlnLmNvcHkgPSBhcHBDb25maWcuYXNzZXRzLm1hcCgoYXNzZXRFbnRyeTogc3RyaW5nIHwgQXNzZXRQYXR0ZXJuT2JqZWN0Q29tcGF0KSA9PiB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGFzc2V0RW50cnkgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFzc2V0RW50cnk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZnJvbTogcGF0aC5qb2luKGFzc2V0RW50cnkuaW5wdXQsIGFzc2V0RW50cnkuZ2xvYiB8fCAnJyksXG4gICAgICAgICAgICAgICAgdG86IGFzc2V0RW50cnkub3V0cHV0LFxuICAgICAgICAgICAgICAgIGV4Y2x1ZGU6IGFzc2V0RW50cnkuaWdub3JlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgZGVsZXRlIGFwcENvbmZpZy5hc3NldHM7XG4gICAgfVxuICAgIGlmIChhcHBDb25maWcuZGVsZXRlT3V0cHV0UGF0aCAmJiAhYXBwQ29uZmlnLmNsZWFuKSB7XG4gICAgICAgIGFwcENvbmZpZy5jbGVhbiA9IHtcbiAgICAgICAgICAgIGJlZm9yZUJ1aWxkOiB7XG4gICAgICAgICAgICAgICAgY2xlYW5PdXREaXI6IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgZGVsZXRlIGFwcENvbmZpZy5kZWxldGVPdXRwdXRQYXRoO1xuICAgIH1cbiAgICBpZiAoYXBwQ29uZmlnLnN0YXRzSnNvbiAmJiAhYXBwQ29uZmlnLmJ1bmRsZUFuYWx5emVyKSB7XG4gICAgICAgIGFwcENvbmZpZy5idW5kbGVBbmFseXplciA9IHtcbiAgICAgICAgICAgIGdlbmVyYXRlU3RhdHNGaWxlOiB0cnVlXG4gICAgICAgIH07XG4gICAgICAgIGRlbGV0ZSBhcHBDb25maWcuc3RhdHNKc29uO1xuICAgIH1cbiAgICBpZiAoYXBwQ29uZmlnLmJ1bmRsZURlcGVuZGVuY2llcyAmJiBhcHBDb25maWcuYnVuZGxlRGVwZW5kZW5jaWVzID09PSAnbm9uZScpIHtcbiAgICAgICAgYXBwQ29uZmlnLm5vZGVNb2R1bGVzQXNFeHRlcm5hbHMgPSB0cnVlO1xuICAgICAgICBjb25zdCBleHRlcm5hbHMgPSBbXG4gICAgICAgICAgICAvXkBhbmd1bGFyLyxcbiAgICAgICAgICAgIChfOiBhbnksIHJlcXVlc3Q6IGFueSwgY2FsbGJhY2s6IChlcnJvcj86IGFueSwgcmVzdWx0PzogYW55KSA9PiB2b2lkKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQWJzb2x1dGUgJiBSZWxhdGl2ZSBwYXRocyBhcmUgbm90IGV4dGVybmFsc1xuICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0Lm1hdGNoKC9eXFwuezAsMn1cXC8vKSkge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAvLyBBdHRlbXB0IHRvIHJlc29sdmUgdGhlIG1vZHVsZSB2aWEgTm9kZVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBlID0gcmVxdWlyZS5yZXNvbHZlKHJlcXVlc3QpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoL25vZGVfbW9kdWxlcy8udGVzdChlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXQncyBhIG5vZGVfbW9kdWxlXG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCByZXF1ZXN0KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEl0J3MgYSBzeXN0ZW0gdGhpbmcgKC5pZSB1dGlsLCBmcy4uLilcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE5vZGUgY291bGRuJ3QgZmluZCBpdCwgc28gaXQgbXVzdCBiZSB1c2VyLWFsaWFzZWRcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIF07XG4gICAgICAgIGlmICghYXBwQ29uZmlnLmV4dGVybmFscykge1xuICAgICAgICAgICAgYXBwQ29uZmlnLmV4dGVybmFscyA9IGV4dGVybmFscyBhcyBhbnk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhcHBDb25maWcuZXh0ZXJuYWxzKSkge1xuICAgICAgICAgICAgICAgIGFwcENvbmZpZy5leHRlcm5hbHMgPSBbLi4uKGFwcENvbmZpZy5leHRlcm5hbHMgYXMgYW55W10pLCAuLi5leHRlcm5hbHNdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhcHBDb25maWcuZXh0ZXJuYWxzID0gW2FwcENvbmZpZy5leHRlcm5hbHMgYXMgYW55LCAuLi5leHRlcm5hbHNdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGRlbGV0ZSBhcHBDb25maWcuYnVuZGxlRGVwZW5kZW5jaWVzO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5TGliQ29uZmlnQ29tcGF0KGxpYkNvbmZpZzogTGliQnVpbGRlck9wdGlvbnMpOiB2b2lkIHtcbiAgICBpZiAobGliQ29uZmlnLnRhcmdldCAmJiAhbGliQ29uZmlnLnBsYXRmb3JtVGFyZ2V0KSB7XG4gICAgICAgIGxpYkNvbmZpZy5wbGF0Zm9ybVRhcmdldCA9IGxpYkNvbmZpZy50YXJnZXQgYXMgYW55O1xuICAgICAgICBkZWxldGUgbGliQ29uZmlnLnRhcmdldDtcbiAgICB9XG5cbiAgICBpZiAobGliQ29uZmlnLnBsYXRmb3JtICYmICFsaWJDb25maWcucGxhdGZvcm1UYXJnZXQpIHtcbiAgICAgICAgbGliQ29uZmlnLnBsYXRmb3JtVGFyZ2V0ID0gbGliQ29uZmlnLnBsYXRmb3JtID09PSAnc2VydmVyJyA/ICdub2RlJyA6ICd3ZWInO1xuICAgICAgICBkZWxldGUgbGliQ29uZmlnLnBsYXRmb3JtO1xuICAgIH1cblxuICAgIGlmIChsaWJDb25maWcub3V0RGlyICYmICFsaWJDb25maWcub3V0cHV0UGF0aCkge1xuICAgICAgICBsaWJDb25maWcub3V0cHV0UGF0aCA9IGxpYkNvbmZpZy5vdXREaXI7XG4gICAgICAgIGRlbGV0ZSBsaWJDb25maWcub3V0RGlyO1xuICAgIH1cblxuICAgIGlmIChsaWJDb25maWcuYXNzZXRzICYmXG4gICAgICAgIEFycmF5LmlzQXJyYXkobGliQ29uZmlnLmFzc2V0cykgJiZcbiAgICAgICAgKCFsaWJDb25maWcuY29weSB8fCAoQXJyYXkuaXNBcnJheShsaWJDb25maWcuY29weSkgJiYgIWxpYkNvbmZpZy5jb3B5Lmxlbmd0aCkpKSB7XG4gICAgICAgIGxpYkNvbmZpZy5jb3B5ID0gbGliQ29uZmlnLmFzc2V0cy5tYXAoYXNzZXRFbnRyeSA9PiB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGFzc2V0RW50cnkgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFzc2V0RW50cnk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZnJvbTogcGF0aC5qb2luKGFzc2V0RW50cnkuaW5wdXQsIGFzc2V0RW50cnkuZ2xvYiB8fCAnJyksXG4gICAgICAgICAgICAgICAgdG86IGFzc2V0RW50cnkub3V0cHV0LFxuICAgICAgICAgICAgICAgIGV4Y2x1ZGU6IGFzc2V0RW50cnkuaWdub3JlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgZGVsZXRlIGxpYkNvbmZpZy5hc3NldHM7XG4gICAgfVxuXG4gICAgaWYgKGxpYkNvbmZpZy5kZWxldGVPdXRwdXRQYXRoICYmICFsaWJDb25maWcuY2xlYW4pIHtcbiAgICAgICAgbGliQ29uZmlnLmNsZWFuID0ge1xuICAgICAgICAgICAgYmVmb3JlQnVpbGQ6IHtcbiAgICAgICAgICAgICAgICBjbGVhbk91dERpcjogdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBkZWxldGUgbGliQ29uZmlnLmRlbGV0ZU91dHB1dFBhdGg7XG4gICAgfVxuXG4gICAgaWYgKGxpYkNvbmZpZy5idW5kbGVEZXBlbmRlbmNpZXMgJiYgbGliQ29uZmlnLmJ1bmRsZURlcGVuZGVuY2llcyA9PT0gJ2FsbCcpIHtcbiAgICAgICAgbGliQ29uZmlnLm5vZGVNb2R1bGVzQXNFeHRlcm5hbHMgPSBmYWxzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUFwcFByb2plY3RDb25maWdXaXRoV2VicGFja0NsaShhcHBDb25maWc6IEFwcFByb2plY3RDb25maWdJbnRlcm5hbCxcbiAgICBjb21tYW5kT3B0aW9uczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSk6IHZvaWQge1xuICAgIGlmIChjb21tYW5kT3B0aW9ucy50YXJnZXQgJiYgIWFwcENvbmZpZy5wbGF0Zm9ybVRhcmdldCkge1xuICAgICAgICBhcHBDb25maWcucGxhdGZvcm1UYXJnZXQgPSBjb21tYW5kT3B0aW9ucy50YXJnZXQ7XG4gICAgfVxuXG4gICAgaWYgKGNvbW1hbmRPcHRpb25zLm91dHB1dFB1YmxpY1BhdGgpIHtcbiAgICAgICAgYXBwQ29uZmlnLnB1YmxpY1BhdGggPSBjb21tYW5kT3B0aW9ucy5vdXRwdXRQdWJsaWNQYXRoO1xuICAgIH1cblxuICAgIGlmIChjb21tYW5kT3B0aW9ucy5kZXZ0b29sKSB7XG4gICAgICAgIGFwcENvbmZpZy5zb3VyY2VNYXAgPSB0cnVlO1xuICAgICAgICBhcHBDb25maWcuc291cmNlTWFwRGV2VG9vbCA9IGNvbW1hbmRPcHRpb25zLmRldnRvb2w7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBvdmVycmlkZVByb2plY3RDb25maWcob2xkQ29uZmlnOiBhbnksIG5ld0NvbmZpZzogYW55KTogdm9pZCB7XG4gICAgaWYgKCFuZXdDb25maWcgfHwgIW9sZENvbmZpZyB8fCB0eXBlb2YgbmV3Q29uZmlnICE9PSAnb2JqZWN0JyB8fCBPYmplY3Qua2V5cyhuZXdDb25maWcpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXMobmV3Q29uZmlnKS5maWx0ZXIoKGtleTogc3RyaW5nKSA9PiBrZXkgIT09ICdlbnZPdmVycmlkZXMnKS5mb3JFYWNoKChrZXk6IHN0cmluZykgPT4ge1xuICAgICAgICBvbGRDb25maWdba2V5XSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobmV3Q29uZmlnW2tleV0pKTtcbiAgICB9KTtcbn1cbiJdfQ==
\No newline at end of file