@nlabs/lex 1.49.5 → 1.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/.swcrc +35 -0
  2. package/README.md +43 -59
  3. package/config.json +32 -8
  4. package/examples/lex.config.js +110 -10
  5. package/lex.config.js +34 -7
  6. package/lib/Button.stories.js +99 -0
  7. package/lib/LexConfig.d.ts +60 -22
  8. package/lib/LexConfig.js +285 -244
  9. package/lib/commands/ai/ai.js +287 -288
  10. package/lib/commands/ai/index.js +8 -7
  11. package/lib/commands/build/build.d.ts +2 -2
  12. package/lib/commands/build/build.js +349 -458
  13. package/lib/commands/clean/clean.js +45 -33
  14. package/lib/commands/compile/compile.js +214 -228
  15. package/lib/commands/config/config.js +46 -42
  16. package/lib/commands/copy/copy.js +36 -35
  17. package/lib/commands/create/create.js +200 -121
  18. package/lib/commands/dev/dev.d.ts +1 -0
  19. package/lib/commands/dev/dev.js +261 -259
  20. package/lib/commands/init/init.js +108 -88
  21. package/lib/commands/link/link.js +18 -14
  22. package/lib/commands/lint/lint.js +735 -742
  23. package/lib/commands/migrate/migrate.js +49 -36
  24. package/lib/commands/publish/publish.js +116 -96
  25. package/lib/commands/serverless/serverless.js +611 -585
  26. package/lib/commands/storybook/storybook.js +242 -238
  27. package/lib/commands/test/test.js +381 -409
  28. package/lib/commands/update/update.js +141 -120
  29. package/lib/commands/upgrade/upgrade.js +51 -44
  30. package/lib/commands/versions/versions.d.ts +1 -1
  31. package/lib/commands/versions/versions.js +36 -38
  32. package/lib/create/changelog.js +136 -125
  33. package/lib/index.js +40 -38
  34. package/lib/lex.js +95 -68
  35. package/lib/storybook/index.js +6 -1
  36. package/lib/test-react/index.js +7 -84
  37. package/lib/types.d.ts +1 -1
  38. package/lib/types.js +7 -1
  39. package/lib/utils/aiService.js +240 -227
  40. package/lib/utils/app.js +274 -273
  41. package/lib/utils/deepMerge.js +37 -23
  42. package/lib/utils/file.js +218 -215
  43. package/lib/utils/log.js +29 -27
  44. package/lib/utils/reactShim.js +7 -85
  45. package/lib/utils/translations.js +92 -82
  46. package/package.json +63 -64
  47. package/templates/typescript/DataLayer.js.txt +218 -0
  48. package/templates/typescript/DataLayer.test.js.txt +268 -0
  49. package/templates/typescript/DataLayer.test.ts.txt +269 -0
  50. package/templates/typescript/DataLayer.ts.txt +227 -0
  51. package/webpack.config.js +38 -28
  52. package/lib/commands/lint/autofix.d.ts +0 -2
@@ -1,242 +1,228 @@
1
- import { execa } from "execa";
2
- import { existsSync, lstatSync, readdirSync } from "fs";
3
- import { sync as globSync } from "glob";
4
- import { extname as pathExtname, join as pathJoin, resolve as pathResolve } from "path";
5
- import { LexConfig, getTypeScriptConfigPath } from "../../LexConfig.js";
6
- import { checkLinkedModules, copyConfiguredFiles, copyFiles, createSpinner, getFilesByExt, removeFiles } from "../../utils/app.js";
7
- import { getDirName, resolveBinaryPath } from "../../utils/file.js";
8
- import { log } from "../../utils/log.js";
9
- const hasFileType = (startPath, ext) => {
10
- if (!existsSync(startPath)) {
11
- return false;
12
- }
13
- const files = readdirSync(startPath);
14
- return files.some((file) => {
15
- const filename = pathJoin(startPath, file);
16
- const fileExt = pathExtname(filename);
17
- const stat = lstatSync(filename);
18
- if (stat.isDirectory()) {
19
- return hasFileType(filename, ext);
1
+ /**
2
+ * Copyright (c) 2018-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */ import { transform } from '@swc/core';
5
+ import { execa } from 'execa';
6
+ import { existsSync, lstatSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
7
+ import { sync as globSync } from 'glob';
8
+ import { extname as pathExtname, join as pathJoin, resolve as pathResolve, dirname } from 'path';
9
+ import { LexConfig, getTypeScriptConfigPath } from '../../LexConfig.js';
10
+ import { checkLinkedModules, copyConfiguredFiles, copyFiles, createSpinner, getFilesByExt, removeFiles } from '../../utils/app.js';
11
+ import { getDirName, resolveBinaryPath } from '../../utils/file.js';
12
+ import { log } from '../../utils/log.js';
13
+ export const hasFileType = (startPath, ext)=>{
14
+ if (!existsSync(startPath)) {
15
+ return false;
20
16
  }
21
- return ext.includes(fileExt);
22
- });
17
+ const files = readdirSync(startPath);
18
+ return files.some((file)=>{
19
+ const filename = pathJoin(startPath, file);
20
+ const fileExt = pathExtname(filename);
21
+ const stat = lstatSync(filename);
22
+ if (stat.isDirectory()) {
23
+ return hasFileType(filename, ext);
24
+ }
25
+ return ext.includes(fileExt);
26
+ });
23
27
  };
24
- const compile = async (cmd, callback = () => ({})) => {
25
- const {
26
- cliName = "Lex",
27
- config,
28
- format = "esm",
29
- outputPath,
30
- quiet,
31
- remove,
32
- sourcePath,
33
- watch
34
- } = cmd;
35
- const spinner = createSpinner(quiet);
36
- log(`${cliName} compiling...`, "info", quiet);
37
- await LexConfig.parseConfig(cmd);
38
- const { outputFullPath, sourceFullPath, useTypescript } = LexConfig.config;
39
- const outputDir = outputPath || outputFullPath;
40
- const sourceDir = sourcePath ? pathResolve(process.cwd(), `./${sourcePath}`) : sourceFullPath || "";
41
- const dirName = getDirName();
42
- const dirPath = pathResolve(dirName, "../..");
43
- checkLinkedModules();
44
- if (remove) {
45
- await removeFiles(outputDir);
46
- }
47
- if (useTypescript) {
48
- LexConfig.checkCompileTypescriptConfig();
49
- const typescriptPath = resolveBinaryPath("tsc", "typescript");
50
- if (!typescriptPath) {
51
- log(`
52
- ${cliName} Error: TypeScript binary not found in Lex's node_modules or monorepo root`, "error", quiet);
53
- log("Please reinstall Lex or check your installation.", "info", quiet);
54
- return 1;
28
+ export const compile = async (cmd, callback = ()=>({}))=>{
29
+ const { cliName = 'Lex', config, format = 'esm', outputPath, quiet, remove, sourcePath, watch } = cmd;
30
+ const spinner = createSpinner(quiet);
31
+ log(`${cliName} compiling...`, 'info', quiet);
32
+ await LexConfig.parseConfig(cmd);
33
+ const { outputFullPath, sourceFullPath, swc: swcConfig, useTypescript } = LexConfig.config;
34
+ const outputDir = outputPath || outputFullPath;
35
+ const sourceDir = sourcePath ? pathResolve(process.cwd(), `./${sourcePath}`) : sourceFullPath || '';
36
+ const dirName = getDirName();
37
+ const dirPath = pathResolve(dirName, '../..');
38
+ checkLinkedModules();
39
+ if (remove) {
40
+ await removeFiles(outputDir);
55
41
  }
56
- const typescriptOptions = config ? ["-p", config] : ["-p", getTypeScriptConfigPath("tsconfig.build.json")];
57
- spinner.start("Static type checking with Typescript...");
58
- try {
59
- await execa(typescriptPath, typescriptOptions, { encoding: "utf8" });
60
- spinner.succeed("Successfully completed type checking!");
61
- } catch (error) {
62
- log(`
63
- ${cliName} Error: ${error.message}`, "error", quiet);
64
- spinner.fail("Type checking failed.");
65
- callback(1);
66
- return 1;
42
+ if (useTypescript) {
43
+ LexConfig.checkCompileTypescriptConfig();
44
+ const typescriptPath = resolveBinaryPath('tsc', 'typescript');
45
+ if (!typescriptPath) {
46
+ log(`\n${cliName} Error: TypeScript binary not found in Lex's node_modules or monorepo root`, 'error', quiet);
47
+ log('Please reinstall Lex or check your installation.', 'info', quiet);
48
+ return 1;
49
+ }
50
+ const typescriptOptions = config ? [
51
+ '-p',
52
+ config
53
+ ] : [
54
+ '-p',
55
+ getTypeScriptConfigPath('tsconfig.build.json')
56
+ ];
57
+ spinner.start('Static type checking with Typescript...');
58
+ try {
59
+ await execa(typescriptPath, typescriptOptions, {
60
+ encoding: 'utf8'
61
+ });
62
+ spinner.succeed('Successfully completed type checking!');
63
+ } catch (error) {
64
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
65
+ spinner.fail('Type checking failed.');
66
+ callback(1);
67
+ return 1;
68
+ }
67
69
  }
68
- }
69
- const globOptions = {
70
- cwd: sourceDir,
71
- dot: false,
72
- nodir: true,
73
- nosort: true
74
- };
75
- const tsFiles = globSync(`${sourceDir}/**/!(*.spec|*.test|*.integration).ts*`, globOptions);
76
- const jsFiles = globSync(`${sourceDir}/**/!(*.spec|*.test|*.integration).js`, globOptions);
77
- const sourceFiles = [...tsFiles, ...jsFiles];
78
- const esbuildConfig = LexConfig.config.esbuild || {};
79
- const isProduction = process.env.NODE_ENV === "production";
80
- let shouldMinify;
81
- if (typeof esbuildConfig.minify === "boolean") {
82
- shouldMinify = esbuildConfig.minify;
83
- } else {
84
- shouldMinify = isProduction;
85
- }
86
- const esbuildPath = resolveBinaryPath("esbuild", "esbuild");
87
- if (!esbuildPath) {
88
- log(`
89
- ${cliName} Error: esbuild binary not found in Lex's node_modules or monorepo root`, "error", quiet);
90
- log("Please reinstall Lex or check your installation.", "info", quiet);
91
- return 1;
92
- }
93
- const esbuildOptions = [
94
- ...sourceFiles,
95
- "--color=true",
96
- `--format=${format || esbuildConfig.format || "esm"}`,
97
- `--outdir=${outputDir}`,
98
- `--platform=${esbuildConfig.platform || "node"}`,
99
- `--sourcemap=${esbuildConfig.sourcemap || "inline"}`,
100
- `--target=${esbuildConfig.target || "node20"}`
101
- ];
102
- if (shouldMinify) {
103
- esbuildOptions.push("--minify");
104
- }
105
- if (esbuildConfig.treeShaking !== false) {
106
- esbuildOptions.push("--tree-shaking=true");
107
- }
108
- if (esbuildConfig.drop && esbuildConfig.drop.length > 0) {
109
- esbuildConfig.drop.forEach((item) => {
110
- esbuildOptions.push(`--drop:${item}`);
111
- });
112
- }
113
- if (esbuildConfig.pure && esbuildConfig.pure.length > 0) {
114
- esbuildConfig.pure.forEach((item) => {
115
- esbuildOptions.push(`--pure:${item}`);
116
- });
117
- }
118
- if (esbuildConfig.legalComments) {
119
- esbuildOptions.push(`--legal-comments=${esbuildConfig.legalComments}`);
120
- }
121
- if (esbuildConfig.banner) {
122
- Object.entries(esbuildConfig.banner).forEach(([type, content]) => {
123
- esbuildOptions.push(`--banner:${type}=${content}`);
124
- });
125
- }
126
- if (esbuildConfig.footer) {
127
- Object.entries(esbuildConfig.footer).forEach(([type, content]) => {
128
- esbuildOptions.push(`--footer:${type}=${content}`);
129
- });
130
- }
131
- if (esbuildConfig.define) {
132
- Object.entries(esbuildConfig.define).forEach(([key, value]) => {
133
- esbuildOptions.push(`--define:${key}=${value}`);
134
- });
135
- }
136
- if (watch) {
137
- esbuildOptions.push("--watch");
138
- }
139
- const cssFiles = getFilesByExt(".css", LexConfig.config);
140
- if (cssFiles.length) {
141
- const postcssPath = resolveBinaryPath("postcss", "postcss-cli");
142
- if (!postcssPath) {
143
- log(`
144
- ${cliName} Error: PostCSS binary not found in Lex's node_modules or monorepo root`, "error", quiet);
145
- log("Please reinstall Lex or check your installation.", "info", quiet);
146
- return 1;
70
+ const globOptions = {
71
+ cwd: sourceDir,
72
+ dot: false,
73
+ nodir: true,
74
+ nosort: true
75
+ };
76
+ const tsFiles = globSync(`${sourceDir}/**/!(*.spec|*.test|*.integration).ts*`, globOptions);
77
+ const jsFiles = globSync(`${sourceDir}/**/!(*.spec|*.test|*.integration).js`, globOptions);
78
+ const sourceFiles = [
79
+ ...tsFiles,
80
+ ...jsFiles
81
+ ];
82
+ const cssFiles = getFilesByExt('.css', LexConfig.config);
83
+ if (cssFiles.length) {
84
+ const postcssPath = resolveBinaryPath('postcss', 'postcss-cli');
85
+ if (!postcssPath) {
86
+ log(`\n${cliName} Error: PostCSS binary not found in Lex's node_modules or monorepo root`, 'error', quiet);
87
+ log('Please reinstall Lex or check your installation.', 'info', quiet);
88
+ return 1;
89
+ }
90
+ const postcssOptions = [
91
+ `${sourceDir}/**/**.css`,
92
+ '--base',
93
+ sourceDir,
94
+ '--dir',
95
+ outputDir,
96
+ '--config',
97
+ pathResolve(dirName, '../../postcss.config.js')
98
+ ];
99
+ try {
100
+ await execa(postcssPath, postcssOptions, {
101
+ encoding: 'utf8'
102
+ });
103
+ spinner.succeed(`Successfully formatted ${cssFiles.length} css files!`);
104
+ } catch (error) {
105
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
106
+ spinner.fail('Failed formatting css.');
107
+ callback(1);
108
+ return 1;
109
+ }
147
110
  }
148
- const postcssOptions = [
149
- `${sourceDir}/**/**.css`,
150
- "--base",
151
- sourceDir,
152
- "--dir",
153
- outputDir,
154
- "--config",
155
- pathResolve(dirName, "../../postcss.config.js")
111
+ const gifFiles = getFilesByExt('.gif', LexConfig.config);
112
+ const jpgFiles = getFilesByExt('.jpg', LexConfig.config);
113
+ const pngFiles = getFilesByExt('.png', LexConfig.config);
114
+ const svgFiles = getFilesByExt('.svg', LexConfig.config);
115
+ const imageFiles = [
116
+ ...gifFiles,
117
+ ...jpgFiles,
118
+ ...pngFiles,
119
+ ...svgFiles
156
120
  ];
157
- try {
158
- await execa(postcssPath, postcssOptions, { encoding: "utf8" });
159
- spinner.succeed(`Successfully formatted ${cssFiles.length} css files!`);
160
- } catch (error) {
161
- log(`
162
- ${cliName} Error: ${error.message}`, "error", quiet);
163
- spinner.fail("Failed formatting css.");
164
- callback(1);
165
- return 1;
121
+ if (imageFiles.length) {
122
+ try {
123
+ await copyFiles(imageFiles, 'image', spinner, LexConfig.config);
124
+ } catch (error) {
125
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
126
+ spinner.fail('Failed to move images to output directory.');
127
+ callback(1);
128
+ return 1;
129
+ }
166
130
  }
167
- }
168
- const gifFiles = getFilesByExt(".gif", LexConfig.config);
169
- const jpgFiles = getFilesByExt(".jpg", LexConfig.config);
170
- const pngFiles = getFilesByExt(".png", LexConfig.config);
171
- const svgFiles = getFilesByExt(".svg", LexConfig.config);
172
- const imageFiles = [...gifFiles, ...jpgFiles, ...pngFiles, ...svgFiles];
173
- if (imageFiles.length) {
174
- try {
175
- await copyFiles(imageFiles, "image", spinner, LexConfig.config);
176
- } catch (error) {
177
- log(`
178
- ${cliName} Error: ${error.message}`, "error", quiet);
179
- spinner.fail("Failed to move images to output directory.");
180
- callback(1);
181
- return 1;
131
+ const ttfFiles = getFilesByExt('.ttf', LexConfig.config);
132
+ const otfFiles = getFilesByExt('.otf', LexConfig.config);
133
+ const woffFiles = getFilesByExt('.woff', LexConfig.config);
134
+ const woff2Files = getFilesByExt('.woff2', LexConfig.config);
135
+ const fontFiles = [
136
+ ...ttfFiles,
137
+ ...otfFiles,
138
+ ...woffFiles,
139
+ ...woff2Files
140
+ ];
141
+ if (fontFiles.length) {
142
+ try {
143
+ await copyFiles(fontFiles, 'font', spinner, LexConfig.config);
144
+ } catch (error) {
145
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
146
+ spinner.fail('Failed to move fonts to output directory.');
147
+ callback(1);
148
+ return 1;
149
+ }
182
150
  }
183
- }
184
- const ttfFiles = getFilesByExt(".ttf", LexConfig.config);
185
- const otfFiles = getFilesByExt(".otf", LexConfig.config);
186
- const woffFiles = getFilesByExt(".woff", LexConfig.config);
187
- const woff2Files = getFilesByExt(".woff2", LexConfig.config);
188
- const fontFiles = [...ttfFiles, ...otfFiles, ...woffFiles, ...woff2Files];
189
- if (fontFiles.length) {
190
- try {
191
- await copyFiles(fontFiles, "font", spinner, LexConfig.config);
192
- } catch (error) {
193
- log(`
194
- ${cliName} Error: ${error.message}`, "error", quiet);
195
- spinner.fail("Failed to move fonts to output directory.");
196
- callback(1);
197
- return 1;
151
+ const mdFiles = getFilesByExt('.md', LexConfig.config);
152
+ if (mdFiles.length) {
153
+ try {
154
+ await copyFiles(mdFiles, 'documents', spinner, LexConfig.config);
155
+ } catch (error) {
156
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
157
+ spinner.fail('Failed to move docs to output directory.');
158
+ callback(1);
159
+ return 1;
160
+ }
198
161
  }
199
- }
200
- const mdFiles = getFilesByExt(".md", LexConfig.config);
201
- if (mdFiles.length) {
162
+ spinner.start(watch ? 'Watching for changes...' : 'Compiling with SWC...');
202
163
  try {
203
- await copyFiles(mdFiles, "documents", spinner, LexConfig.config);
164
+ // Compile each file with SWC
165
+ for (const file of sourceFiles){
166
+ const sourcePath = pathResolve(sourceDir, file);
167
+ const outputPath = pathResolve(outputDir, file.replace(/\.(ts|tsx)$/, '.js'));
168
+ // Ensure output directory exists
169
+ const outputDirPath = dirname(outputPath);
170
+ if (!existsSync(outputDirPath)) {
171
+ mkdirSync(outputDirPath, {
172
+ recursive: true
173
+ });
174
+ }
175
+ const sourceCode = readFileSync(sourcePath, 'utf8');
176
+ const isTSX = file.endsWith('.tsx');
177
+ // Merge SWC config with command-specific overrides
178
+ const swcOptions = {
179
+ filename: file,
180
+ ...swcConfig,
181
+ jsc: {
182
+ ...swcConfig?.jsc,
183
+ parser: {
184
+ decorators: swcConfig?.jsc?.parser?.decorators ?? true,
185
+ dynamicImport: swcConfig?.jsc?.parser?.dynamicImport ?? true,
186
+ syntax: 'typescript',
187
+ tsx: isTSX
188
+ },
189
+ target: swcConfig?.jsc?.target ?? 'es2020',
190
+ transform: isTSX ? {
191
+ ...swcConfig?.jsc?.transform,
192
+ react: {
193
+ runtime: 'automatic',
194
+ ...swcConfig?.jsc?.transform?.react
195
+ }
196
+ } : swcConfig?.jsc?.transform
197
+ },
198
+ module: {
199
+ ...swcConfig?.module,
200
+ type: format === 'cjs' ? 'commonjs' : swcConfig?.module?.type || 'es6'
201
+ }
202
+ };
203
+ const result = await transform(sourceCode, swcOptions);
204
+ writeFileSync(outputPath, result.code);
205
+ }
206
+ spinner.succeed('Compile completed successfully!');
204
207
  } catch (error) {
205
- log(`
206
- ${cliName} Error: ${error.message}`, "error", quiet);
207
- spinner.fail("Failed to move docs to output directory.");
208
- callback(1);
209
- return 1;
208
+ log(`\n${cliName} Error: ${error.message}`, 'error', quiet);
209
+ if (!quiet) {
210
+ console.error(error);
211
+ }
212
+ spinner.fail('Code compiling failed.');
213
+ callback(1);
214
+ return 1;
210
215
  }
211
- }
212
- spinner.start(watch ? "Watching for changes..." : "Compiling with ESBuild...");
213
- try {
214
- await execa(esbuildPath, esbuildOptions, { encoding: "utf8" });
215
- spinner.succeed("Compile completed successfully!");
216
- } catch (error) {
217
- log(`
218
- ${cliName} Error: ${error.message}`, "error", quiet);
219
- if (!quiet) {
220
- console.error(error);
216
+ try {
217
+ await copyConfiguredFiles(spinner, LexConfig.config, quiet);
218
+ } catch (copyError) {
219
+ log(`\n${cliName} Error: Failed to copy configured files: ${copyError.message}`, 'error', quiet);
220
+ spinner.fail('Failed to copy configured files.');
221
+ callback(1);
222
+ return 1;
221
223
  }
222
- spinner.fail("Code compiling failed.");
223
- callback(1);
224
- return 1;
225
- }
226
- try {
227
- await copyConfiguredFiles(spinner, LexConfig.config, quiet);
228
- } catch (copyError) {
229
- log(`
230
- ${cliName} Error: Failed to copy configured files: ${copyError.message}`, "error", quiet);
231
- spinner.fail("Failed to copy configured files.");
232
- callback(1);
233
- return 1;
234
- }
235
- callback(0);
236
- return 0;
237
- };
238
- export {
239
- compile,
240
- hasFileType
224
+ callback(0);
225
+ return 0;
241
226
  };
242
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL2NvbXBpbGUvY29tcGlsZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhlY2F9IGZyb20gJ2V4ZWNhJztcbmltcG9ydCB7ZXhpc3RzU3luYywgbHN0YXRTeW5jLCByZWFkZGlyU3luY30gZnJvbSAnZnMnO1xuaW1wb3J0IHtzeW5jIGFzIGdsb2JTeW5jfSBmcm9tICdnbG9iJztcbmltcG9ydCB7ZXh0bmFtZSBhcyBwYXRoRXh0bmFtZSwgam9pbiBhcyBwYXRoSm9pbiwgcmVzb2x2ZSBhcyBwYXRoUmVzb2x2ZX0gZnJvbSAncGF0aCc7XG5cbmltcG9ydCB7TGV4Q29uZmlnLCBnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aH0gZnJvbSAnLi4vLi4vTGV4Q29uZmlnLmpzJztcbmltcG9ydCB7Y2hlY2tMaW5rZWRNb2R1bGVzLCBjb3B5Q29uZmlndXJlZEZpbGVzLCBjb3B5RmlsZXMsIGNyZWF0ZVNwaW5uZXIsIGdldEZpbGVzQnlFeHQsIHJlbW92ZUZpbGVzfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtnZXREaXJOYW1lLCByZXNvbHZlQmluYXJ5UGF0aH0gZnJvbSAnLi4vLi4vdXRpbHMvZmlsZS5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJztcblxuZXhwb3J0IGNvbnN0IGhhc0ZpbGVUeXBlID0gKHN0YXJ0UGF0aDogc3RyaW5nLCBleHQ6IHN0cmluZ1tdKTogYm9vbGVhbiA9PiB7XG4gIGlmKCFleGlzdHNTeW5jKHN0YXJ0UGF0aCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBmaWxlczogc3RyaW5nW10gPSByZWFkZGlyU3luYyhzdGFydFBhdGgpO1xuXG4gIHJldHVybiBmaWxlcy5zb21lKChmaWxlOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBmaWxlbmFtZTogc3RyaW5nID0gcGF0aEpvaW4oc3RhcnRQYXRoLCBmaWxlKTtcbiAgICBjb25zdCBmaWxlRXh0OiBzdHJpbmcgPSBwYXRoRXh0bmFtZShmaWxlbmFtZSk7XG4gICAgY29uc3Qgc3RhdCA9IGxzdGF0U3luYyhmaWxlbmFtZSk7XG5cbiAgICBpZihzdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIHJldHVybiBoYXNGaWxlVHlwZShmaWxlbmFtZSwgZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXh0LmluY2x1ZGVzKGZpbGVFeHQpO1xuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb21waWxlID0gYXN5bmMgKGNtZDogYW55LCBjYWxsYmFjazogYW55ID0gKCkgPT4gKHt9KSk6IFByb21pc2U8bnVtYmVyPiA9PiB7XG4gIGNvbnN0IHtcbiAgICBjbGlOYW1lID0gJ0xleCcsXG4gICAgY29uZmlnLFxuICAgIGZvcm1hdCA9ICdlc20nLFxuICAgIG91dHB1dFBhdGgsXG4gICAgcXVpZXQsXG4gICAgcmVtb3ZlLFxuICAgIHNvdXJjZVBhdGgsXG4gICAgd2F0Y2hcbiAgfSA9IGNtZDtcblxuICBjb25zdCBzcGlubmVyID0gY3JlYXRlU3Bpbm5lcihxdWlldCk7XG5cbiAgbG9nKGAke2NsaU5hbWV9IGNvbXBpbGluZy4uLmAsICdpbmZvJywgcXVpZXQpO1xuXG4gIGF3YWl0IExleENvbmZpZy5wYXJzZUNvbmZpZyhjbWQpO1xuXG4gIGNvbnN0IHtvdXRwdXRGdWxsUGF0aCwgc291cmNlRnVsbFBhdGgsIHVzZVR5cGVzY3JpcHR9ID0gTGV4Q29uZmlnLmNvbmZpZztcbiAgY29uc3Qgb3V0cHV0RGlyOiBzdHJpbmcgPSBvdXRwdXRQYXRoIHx8IG91dHB1dEZ1bGxQYXRoO1xuICBjb25zdCBzb3VyY2VEaXI6IHN0cmluZyA9IHNvdXJjZVBhdGggPyBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBgLi8ke3NvdXJjZVBhdGh9YCkgOiBzb3VyY2VGdWxsUGF0aCB8fCAnJztcbiAgY29uc3QgZGlyTmFtZSA9IGdldERpck5hbWUoKTtcbiAgY29uc3QgZGlyUGF0aDogc3RyaW5nID0gcGF0aFJlc29sdmUoZGlyTmFtZSwgJy4uLy4uJyk7XG5cbiAgY2hlY2tMaW5rZWRNb2R1bGVzKCk7XG5cbiAgaWYocmVtb3ZlKSB7XG4gICAgYXdhaXQgcmVtb3ZlRmlsZXMob3V0cHV0RGlyKTtcbiAgfVxuXG4gIGlmKHVzZVR5cGVzY3JpcHQpIHtcbiAgICBMZXhDb25maWcuY2hlY2tDb21waWxlVHlwZXNjcmlwdENvbmZpZygpO1xuXG4gICAgY29uc3QgdHlwZXNjcmlwdFBhdGg6IHN0cmluZyA9IHJlc29sdmVCaW5hcnlQYXRoKCd0c2MnLCAndHlwZXNjcmlwdCcpO1xuXG4gICAgaWYoIXR5cGVzY3JpcHRQYXRoKSB7XG4gICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IFR5cGVTY3JpcHQgYmluYXJ5IG5vdCBmb3VuZCBpbiBMZXgncyBub2RlX21vZHVsZXMgb3IgbW9ub3JlcG8gcm9vdGAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgIGxvZygnUGxlYXNlIHJlaW5zdGFsbCBMZXggb3IgY2hlY2sgeW91ciBpbnN0YWxsYXRpb24uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlc2NyaXB0T3B0aW9uczogc3RyaW5nW10gPSBjb25maWcgP1xuICAgICAgWyctcCcsIGNvbmZpZ10gOlxuICAgICAgWyctcCcsIGdldFR5cGVTY3JpcHRDb25maWdQYXRoKCd0c2NvbmZpZy5idWlsZC5qc29uJyldO1xuXG4gICAgc3Bpbm5lci5zdGFydCgnU3RhdGljIHR5cGUgY2hlY2tpbmcgd2l0aCBUeXBlc2NyaXB0Li4uJyk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgZXhlY2EodHlwZXNjcmlwdFBhdGgsIHR5cGVzY3JpcHRPcHRpb25zLCB7ZW5jb2Rpbmc6ICd1dGY4J30pO1xuXG4gICAgICBzcGlubmVyLnN1Y2NlZWQoJ1N1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgdHlwZSBjaGVja2luZyEnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBzcGlubmVyLmZhaWwoJ1R5cGUgY2hlY2tpbmcgZmFpbGVkLicpO1xuXG4gICAgICBjYWxsYmFjaygxKTtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGdsb2JPcHRpb25zID0ge1xuICAgIGN3ZDogc291cmNlRGlyLFxuICAgIGRvdDogZmFsc2UsXG4gICAgbm9kaXI6IHRydWUsXG4gICAgbm9zb3J0OiB0cnVlXG4gIH07XG4gIGNvbnN0IHRzRmlsZXM6IHN0cmluZ1tdID0gZ2xvYlN5bmMoYCR7c291cmNlRGlyfS8qKi8hKCouc3BlY3wqLnRlc3R8Ki5pbnRlZ3JhdGlvbikudHMqYCwgZ2xvYk9wdGlvbnMpO1xuICBjb25zdCBqc0ZpbGVzOiBzdHJpbmdbXSA9IGdsb2JTeW5jKGAke3NvdXJjZURpcn0vKiovISgqLnNwZWN8Ki50ZXN0fCouaW50ZWdyYXRpb24pLmpzYCwgZ2xvYk9wdGlvbnMpO1xuICBjb25zdCBzb3VyY2VGaWxlczogc3RyaW5nW10gPSBbLi4udHNGaWxlcywgLi4uanNGaWxlc107XG4gIGNvbnN0IGVzYnVpbGRDb25maWcgPSBMZXhDb25maWcuY29uZmlnLmVzYnVpbGQgfHwge307XG4gIGNvbnN0IGlzUHJvZHVjdGlvbiA9IHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbic7XG4gIGxldCBzaG91bGRNaW5pZnk6IGJvb2xlYW47XG5cbiAgaWYodHlwZW9mIGVzYnVpbGRDb25maWcubWluaWZ5ID09PSAnYm9vbGVhbicpIHtcbiAgICBzaG91bGRNaW5pZnkgPSBlc2J1aWxkQ29uZmlnLm1pbmlmeTtcbiAgfSBlbHNlIHtcbiAgICBzaG91bGRNaW5pZnkgPSBpc1Byb2R1Y3Rpb247XG4gIH1cblxuICBjb25zdCBlc2J1aWxkUGF0aDogc3RyaW5nID0gcmVzb2x2ZUJpbmFyeVBhdGgoJ2VzYnVpbGQnLCAnZXNidWlsZCcpO1xuXG4gIGlmKCFlc2J1aWxkUGF0aCkge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogZXNidWlsZCBiaW5hcnkgbm90IGZvdW5kIGluIExleCdzIG5vZGVfbW9kdWxlcyBvciBtb25vcmVwbyByb290YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgIGxvZygnUGxlYXNlIHJlaW5zdGFsbCBMZXggb3IgY2hlY2sgeW91ciBpbnN0YWxsYXRpb24uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICBjb25zdCBlc2J1aWxkT3B0aW9uczogc3RyaW5nW10gPSBbXG4gICAgLi4uc291cmNlRmlsZXMsXG4gICAgJy0tY29sb3I9dHJ1ZScsXG4gICAgYC0tZm9ybWF0PSR7Zm9ybWF0IHx8IGVzYnVpbGRDb25maWcuZm9ybWF0IHx8ICdlc20nfWAsXG4gICAgYC0tb3V0ZGlyPSR7b3V0cHV0RGlyfWAsXG4gICAgYC0tcGxhdGZvcm09JHtlc2J1aWxkQ29uZmlnLnBsYXRmb3JtIHx8ICdub2RlJ31gLFxuICAgIGAtLXNvdXJjZW1hcD0ke2VzYnVpbGRDb25maWcuc291cmNlbWFwIHx8ICdpbmxpbmUnfWAsXG4gICAgYC0tdGFyZ2V0PSR7ZXNidWlsZENvbmZpZy50YXJnZXQgfHwgJ25vZGUyMCd9YFxuICBdO1xuXG4gIGlmKHNob3VsZE1pbmlmeSkge1xuICAgIGVzYnVpbGRPcHRpb25zLnB1c2goJy0tbWluaWZ5Jyk7XG4gIH1cblxuICBpZihlc2J1aWxkQ29uZmlnLnRyZWVTaGFraW5nICE9PSBmYWxzZSkge1xuICAgIGVzYnVpbGRPcHRpb25zLnB1c2goJy0tdHJlZS1zaGFraW5nPXRydWUnKTtcbiAgfVxuXG4gIGlmKGVzYnVpbGRDb25maWcuZHJvcCAmJiBlc2J1aWxkQ29uZmlnLmRyb3AubGVuZ3RoID4gMCkge1xuICAgIGVzYnVpbGRDb25maWcuZHJvcC5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICBlc2J1aWxkT3B0aW9ucy5wdXNoKGAtLWRyb3A6JHtpdGVtfWApO1xuICAgIH0pO1xuICB9XG5cbiAgaWYoZXNidWlsZENvbmZpZy5wdXJlICYmIGVzYnVpbGRDb25maWcucHVyZS5sZW5ndGggPiAwKSB7XG4gICAgZXNidWlsZENvbmZpZy5wdXJlLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIGVzYnVpbGRPcHRpb25zLnB1c2goYC0tcHVyZToke2l0ZW19YCk7XG4gICAgfSk7XG4gIH1cblxuICBpZihlc2J1aWxkQ29uZmlnLmxlZ2FsQ29tbWVudHMpIHtcbiAgICBlc2J1aWxkT3B0aW9ucy5wdXNoKGAtLWxlZ2FsLWNvbW1lbnRzPSR7ZXNidWlsZENvbmZpZy5sZWdhbENvbW1lbnRzfWApO1xuICB9XG5cbiAgaWYoZXNidWlsZENvbmZpZy5iYW5uZXIpIHtcbiAgICBPYmplY3QuZW50cmllcyhlc2J1aWxkQ29uZmlnLmJhbm5lcikuZm9yRWFjaCgoW3R5cGUsIGNvbnRlbnRdKSA9PiB7XG4gICAgICBlc2J1aWxkT3B0aW9ucy5wdXNoKGAtLWJhbm5lcjoke3R5cGV9PSR7Y29udGVudH1gKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmKGVzYnVpbGRDb25maWcuZm9vdGVyKSB7XG4gICAgT2JqZWN0LmVudHJpZXMoZXNidWlsZENvbmZpZy5mb290ZXIpLmZvckVhY2goKFt0eXBlLCBjb250ZW50XSkgPT4ge1xuICAgICAgZXNidWlsZE9wdGlvbnMucHVzaChgLS1mb290ZXI6JHt0eXBlfT0ke2NvbnRlbnR9YCk7XG4gICAgfSk7XG4gIH1cblxuICBpZihlc2J1aWxkQ29uZmlnLmRlZmluZSkge1xuICAgIE9iamVjdC5lbnRyaWVzKGVzYnVpbGRDb25maWcuZGVmaW5lKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGVzYnVpbGRPcHRpb25zLnB1c2goYC0tZGVmaW5lOiR7a2V5fT0ke3ZhbHVlfWApO1xuICAgIH0pO1xuICB9XG5cbiAgaWYod2F0Y2gpIHtcbiAgICBlc2J1aWxkT3B0aW9ucy5wdXNoKCctLXdhdGNoJyk7XG4gIH1cblxuICBjb25zdCBjc3NGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcuY3NzJywgTGV4Q29uZmlnLmNvbmZpZyk7XG5cbiAgaWYoY3NzRmlsZXMubGVuZ3RoKSB7XG4gICAgY29uc3QgcG9zdGNzc1BhdGg6IHN0cmluZyA9IHJlc29sdmVCaW5hcnlQYXRoKCdwb3N0Y3NzJywgJ3Bvc3Rjc3MtY2xpJyk7XG5cbiAgICBpZighcG9zdGNzc1BhdGgpIHtcbiAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogUG9zdENTUyBiaW5hcnkgbm90IGZvdW5kIGluIExleCdzIG5vZGVfbW9kdWxlcyBvciBtb25vcmVwbyByb290YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgICAgbG9nKCdQbGVhc2UgcmVpbnN0YWxsIExleCBvciBjaGVjayB5b3VyIGluc3RhbGxhdGlvbi4nLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIGNvbnN0IHBvc3Rjc3NPcHRpb25zOiBzdHJpbmdbXSA9IFtcbiAgICAgIGAke3NvdXJjZURpcn0vKiovKiouY3NzYCxcbiAgICAgICctLWJhc2UnLFxuICAgICAgc291cmNlRGlyLFxuICAgICAgJy0tZGlyJyxcbiAgICAgIG91dHB1dERpcixcbiAgICAgICctLWNvbmZpZycsXG4gICAgICBwYXRoUmVzb2x2ZShkaXJOYW1lLCAnLi4vLi4vcG9zdGNzcy5jb25maWcuanMnKVxuICAgIF07XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgZXhlY2EocG9zdGNzc1BhdGgsIHBvc3Rjc3NPcHRpb25zLCB7ZW5jb2Rpbmc6ICd1dGY4J30pO1xuICAgICAgc3Bpbm5lci5zdWNjZWVkKGBTdWNjZXNzZnVsbHkgZm9ybWF0dGVkICR7Y3NzRmlsZXMubGVuZ3RofSBjc3MgZmlsZXMhYCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgICAgc3Bpbm5lci5mYWlsKCdGYWlsZWQgZm9ybWF0dGluZyBjc3MuJyk7XG5cbiAgICAgIGNhbGxiYWNrKDEpO1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZ2lmRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLmdpZicsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCBqcGdGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcuanBnJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IHBuZ0ZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy5wbmcnLCBMZXhDb25maWcuY29uZmlnKTtcbiAgY29uc3Qgc3ZnRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLnN2ZycsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCBpbWFnZUZpbGVzOiBzdHJpbmdbXSA9IFsuLi5naWZGaWxlcywgLi4uanBnRmlsZXMsIC4uLnBuZ0ZpbGVzLCAuLi5zdmdGaWxlc107XG5cbiAgaWYoaW1hZ2VGaWxlcy5sZW5ndGgpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29weUZpbGVzKGltYWdlRmlsZXMsICdpbWFnZScsIHNwaW5uZXIsIExleENvbmZpZy5jb25maWcpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICAgIHNwaW5uZXIuZmFpbCgnRmFpbGVkIHRvIG1vdmUgaW1hZ2VzIHRvIG91dHB1dCBkaXJlY3RvcnkuJyk7XG5cbiAgICAgIGNhbGxiYWNrKDEpO1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgdHRmRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLnR0ZicsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCBvdGZGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcub3RmJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IHdvZmZGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcud29mZicsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCB3b2ZmMkZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy53b2ZmMicsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCBmb250RmlsZXM6IHN0cmluZ1tdID0gWy4uLnR0ZkZpbGVzLCAuLi5vdGZGaWxlcywgLi4ud29mZkZpbGVzLCAuLi53b2ZmMkZpbGVzXTtcblxuICBpZihmb250RmlsZXMubGVuZ3RoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNvcHlGaWxlcyhmb250RmlsZXMsICdmb250Jywgc3Bpbm5lciwgTGV4Q29uZmlnLmNvbmZpZyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgICAgc3Bpbm5lci5mYWlsKCdGYWlsZWQgdG8gbW92ZSBmb250cyB0byBvdXRwdXQgZGlyZWN0b3J5LicpO1xuXG4gICAgICBjYWxsYmFjaygxKTtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG1kRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLm1kJywgTGV4Q29uZmlnLmNvbmZpZyk7XG5cbiAgaWYobWRGaWxlcy5sZW5ndGgpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29weUZpbGVzKG1kRmlsZXMsICdkb2N1bWVudHMnLCBzcGlubmVyLCBMZXhDb25maWcuY29uZmlnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBzcGlubmVyLmZhaWwoJ0ZhaWxlZCB0byBtb3ZlIGRvY3MgdG8gb3V0cHV0IGRpcmVjdG9yeS4nKTtcblxuICAgICAgY2FsbGJhY2soMSk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuICBzcGlubmVyLnN0YXJ0KHdhdGNoID8gJ1dhdGNoaW5nIGZvciBjaGFuZ2VzLi4uJyA6ICdDb21waWxpbmcgd2l0aCBFU0J1aWxkLi4uJyk7XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCBleGVjYShlc2J1aWxkUGF0aCwgZXNidWlsZE9wdGlvbnMsIHtlbmNvZGluZzogJ3V0ZjgnfSk7XG5cbiAgICBzcGlubmVyLnN1Y2NlZWQoJ0NvbXBpbGUgY29tcGxldGVkIHN1Y2Nlc3NmdWxseSEnKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICBpZighcXVpZXQpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgIH1cblxuICAgIHNwaW5uZXIuZmFpbCgnQ29kZSBjb21waWxpbmcgZmFpbGVkLicpO1xuXG4gICAgY2FsbGJhY2soMSk7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICB0cnkge1xuICAgIGF3YWl0IGNvcHlDb25maWd1cmVkRmlsZXMoc3Bpbm5lciwgTGV4Q29uZmlnLmNvbmZpZywgcXVpZXQpO1xuICB9IGNhdGNoIChjb3B5RXJyb3IpIHtcbiAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IEZhaWxlZCB0byBjb3B5IGNvbmZpZ3VyZWQgZmlsZXM6ICR7Y29weUVycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgc3Bpbm5lci5mYWlsKCdGYWlsZWQgdG8gY29weSBjb25maWd1cmVkIGZpbGVzLicpO1xuXG4gICAgY2FsbGJhY2soMSk7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICBjYWxsYmFjaygwKTtcbiAgcmV0dXJuIDA7XG59OyJdLAogICJtYXBwaW5ncyI6ICJBQUlBLFNBQVEsYUFBWTtBQUNwQixTQUFRLFlBQVksV0FBVyxtQkFBa0I7QUFDakQsU0FBUSxRQUFRLGdCQUFlO0FBQy9CLFNBQVEsV0FBVyxhQUFhLFFBQVEsVUFBVSxXQUFXLG1CQUFrQjtBQUUvRSxTQUFRLFdBQVcsK0JBQThCO0FBQ2pELFNBQVEsb0JBQW9CLHFCQUFxQixXQUFXLGVBQWUsZUFBZSxtQkFBa0I7QUFDNUcsU0FBUSxZQUFZLHlCQUF3QjtBQUM1QyxTQUFRLFdBQVU7QUFFWCxNQUFNLGNBQWMsQ0FBQyxXQUFtQixRQUEyQjtBQUN4RSxNQUFHLENBQUMsV0FBVyxTQUFTLEdBQUc7QUFDekIsV0FBTztBQUFBLEVBQ1Q7QUFFQSxRQUFNLFFBQWtCLFlBQVksU0FBUztBQUU3QyxTQUFPLE1BQU0sS0FBSyxDQUFDLFNBQWlCO0FBQ2xDLFVBQU0sV0FBbUIsU0FBUyxXQUFXLElBQUk7QUFDakQsVUFBTSxVQUFrQixZQUFZLFFBQVE7QUFDNUMsVUFBTSxPQUFPLFVBQVUsUUFBUTtBQUUvQixRQUFHLEtBQUssWUFBWSxHQUFHO0FBQ3JCLGFBQU8sWUFBWSxVQUFVLEdBQUc7QUFBQSxJQUNsQztBQUVBLFdBQU8sSUFBSSxTQUFTLE9BQU87QUFBQSxFQUM3QixDQUFDO0FBQ0g7QUFFTyxNQUFNLFVBQVUsT0FBTyxLQUFVLFdBQWdCLE9BQU8sQ0FBQyxPQUF3QjtBQUN0RixRQUFNO0FBQUEsSUFDSixVQUFVO0FBQUEsSUFDVjtBQUFBLElBQ0EsU0FBUztBQUFBLElBQ1Q7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDRixJQUFJO0FBRUosUUFB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TTtBQUNuRSxRQUFNLGFBQXVCLGNBQWMsVUFBVSxVQUFVLE1BQU07QUFDckUsUUFBTSxZQUFzQixDQUFDLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxXQUFXLEdBQUcsVUFBVTtBQUVsRixNQUFHLFVBQVUsUUFBUTtBQUNuQixRQUFJO0FBQ0YsWUFBTSxVQUFVLFdBQVcsUUFBUSxTQUFTLFVBQVUsTUFBTTtBQUFBLElBQzlELFNBQVMsT0FBTztBQUNkLFVBQUk7QUFBQSxFQUFLLE9BQU8sV0FBVyxNQUFNLE9BQU8sSUFBSSxTQUFTLEtBQUs7QUFFMUQsY0FBUSxLQUFLLDJDQUEyQztBQUV4RCxlQUFTLENBQUM7QUFDVixhQUFPO0FBQUEsSUFDVDtBQUFBLEVBQ0Y7QUFFQSxRQUFNLFVBQW9CLGNBQWMsT0FBTyxVQUFVLE1BQU07QUFFL0QsTUFBRyxRQUFRLFFBQVE7QUFDakIsUUFBSTtBQUNGLFlBQU0sVUFBVSxTQUFTLGFBQWEsU0FBUyxVQUFVLE1BQU07QUFBQSxJQUNqRSxTQUFTLE9BQU87QUFDZCxVQUFJO0FBQUEsRUFBSyxPQUFPLFdBQVcsTUFBTSxPQUFPLElBQUksU0FBUyxLQUFLO0FBRTFELGNBQVEsS0FBSywwQ0FBMEM7QUFFdkQsZUFBUyxDQUFDO0FBQ1YsYUFBTztBQUFBLElBQ1Q7QUFBQSxFQUNGO0FBRUEsVUFBUSxNQUFNLFFBQVEsNEJBQTRCLDJCQUEyQjtBQUU3RSxNQUFJO0FBQ0YsVUFBTSxNQUFNLGFBQWEsZ0JBQWdCLEVBQUMsVUFBVSxPQUFNLENBQUM7QUFFM0QsWUFBUSxRQUFRLGlDQUFpQztBQUFBLEVBQ25ELFNBQVMsT0FBTztBQUNkLFFBQUk7QUFBQSxFQUFLLE9BQU8sV0FBVyxNQUFNLE9BQU8sSUFBSSxTQUFTLEtBQUs7QUFFMUQsUUFBRyxDQUFDLE9BQU87QUFDVCxjQUFRLE1BQU0sS0FBSztBQUFBLElBQ3JCO0FBRUEsWUFBUSxLQUFLLHdCQUF3QjtBQUVyQyxhQUFTLENBQUM7QUFDVixXQUFPO0FBQUEsRUFDVDtBQUVBLE1BQUk7QUFDRixVQUFNLG9CQUFvQixTQUFTLFVBQVUsUUFBUSxLQUFLO0FBQUEsRUFDNUQsU0FBUyxXQUFXO0FBQ2xCLFFBQUk7QUFBQSxFQUFLLE9BQU8sNENBQTRDLFVBQVUsT0FBTyxJQUFJLFNBQVMsS0FBSztBQUUvRixZQUFRLEtBQUssa0NBQWtDO0FBRS9DLGFBQVMsQ0FBQztBQUNWLFdBQU87QUFBQSxFQUNUO0FBRUEsV0FBUyxDQUFDO0FBQ1YsU0FBTztBQUNUOyIsCiAgIm5hbWVzIjogW10KfQo=
227
+
228
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9jb21waWxlL2NvbXBpbGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7dHJhbnNmb3JtfSBmcm9tICdAc3djL2NvcmUnO1xuaW1wb3J0IHtleGVjYX0gZnJvbSAnZXhlY2EnO1xuaW1wb3J0IHtleGlzdHNTeW5jLCBsc3RhdFN5bmMsIHJlYWRkaXJTeW5jLCByZWFkRmlsZVN5bmMsIHdyaXRlRmlsZVN5bmMsIG1rZGlyU3luY30gZnJvbSAnZnMnO1xuaW1wb3J0IHtzeW5jIGFzIGdsb2JTeW5jfSBmcm9tICdnbG9iJztcbmltcG9ydCB7ZXh0bmFtZSBhcyBwYXRoRXh0bmFtZSwgam9pbiBhcyBwYXRoSm9pbiwgcmVzb2x2ZSBhcyBwYXRoUmVzb2x2ZSwgZGlybmFtZX0gZnJvbSAncGF0aCc7XG5cbmltcG9ydCB7TGV4Q29uZmlnLCBnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aH0gZnJvbSAnLi4vLi4vTGV4Q29uZmlnLmpzJztcbmltcG9ydCB7Y2hlY2tMaW5rZWRNb2R1bGVzLCBjb3B5Q29uZmlndXJlZEZpbGVzLCBjb3B5RmlsZXMsIGNyZWF0ZVNwaW5uZXIsIGdldEZpbGVzQnlFeHQsIHJlbW92ZUZpbGVzfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtnZXREaXJOYW1lLCByZXNvbHZlQmluYXJ5UGF0aH0gZnJvbSAnLi4vLi4vdXRpbHMvZmlsZS5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJztcblxuZXhwb3J0IGNvbnN0IGhhc0ZpbGVUeXBlID0gKHN0YXJ0UGF0aDogc3RyaW5nLCBleHQ6IHN0cmluZ1tdKTogYm9vbGVhbiA9PiB7XG4gIGlmKCFleGlzdHNTeW5jKHN0YXJ0UGF0aCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBmaWxlczogc3RyaW5nW10gPSByZWFkZGlyU3luYyhzdGFydFBhdGgpO1xuXG4gIHJldHVybiBmaWxlcy5zb21lKChmaWxlOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBmaWxlbmFtZTogc3RyaW5nID0gcGF0aEpvaW4oc3RhcnRQYXRoLCBmaWxlKTtcbiAgICBjb25zdCBmaWxlRXh0OiBzdHJpbmcgPSBwYXRoRXh0bmFtZShmaWxlbmFtZSk7XG4gICAgY29uc3Qgc3RhdCA9IGxzdGF0U3luYyhmaWxlbmFtZSk7XG5cbiAgICBpZihzdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIHJldHVybiBoYXNGaWxlVHlwZShmaWxlbmFtZSwgZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXh0LmluY2x1ZGVzKGZpbGVFeHQpO1xuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb21waWxlID0gYXN5bmMgKGNtZDogYW55LCBjYWxsYmFjazogYW55ID0gKCkgPT4gKHt9KSk6IFByb21pc2U8bnVtYmVyPiA9PiB7XG4gIGNvbnN0IHtcbiAgICBjbGlOYW1lID0gJ0xleCcsXG4gICAgY29uZmlnLFxuICAgIGZvcm1hdCA9ICdlc20nLFxuICAgIG91dHB1dFBhdGgsXG4gICAgcXVpZXQsXG4gICAgcmVtb3ZlLFxuICAgIHNvdXJjZVBhdGgsXG4gICAgd2F0Y2hcbiAgfSA9IGNtZDtcblxuICBjb25zdCBzcGlubmVyID0gY3JlYXRlU3Bpbm5lcihxdWlldCk7XG5cbiAgbG9nKGAke2NsaU5hbWV9IGNvbXBpbGluZy4uLmAsICdpbmZvJywgcXVpZXQpO1xuXG4gIGF3YWl0IExleENvbmZpZy5wYXJzZUNvbmZpZyhjbWQpO1xuXG4gIGNvbnN0IHtvdXRwdXRGdWxsUGF0aCwgc291cmNlRnVsbFBhdGgsIHN3Yzogc3djQ29uZmlnLCB1c2VUeXBlc2NyaXB0fSA9IExleENvbmZpZy5jb25maWc7XG4gIGNvbnN0IG91dHB1dERpcjogc3RyaW5nID0gb3V0cHV0UGF0aCB8fCBvdXRwdXRGdWxsUGF0aDtcbiAgY29uc3Qgc291cmNlRGlyOiBzdHJpbmcgPSBzb3VyY2VQYXRoID8gcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgYC4vJHtzb3VyY2VQYXRofWApIDogc291cmNlRnVsbFBhdGggfHwgJyc7XG4gIGNvbnN0IGRpck5hbWUgPSBnZXREaXJOYW1lKCk7XG4gIGNvbnN0IGRpclBhdGg6IHN0cmluZyA9IHBhdGhSZXNvbHZlKGRpck5hbWUsICcuLi8uLicpO1xuXG4gIGNoZWNrTGlua2VkTW9kdWxlcygpO1xuXG4gIGlmKHJlbW92ZSkge1xuICAgIGF3YWl0IHJlbW92ZUZpbGVzKG91dHB1dERpcik7XG4gIH1cblxuICBpZih1c2VUeXBlc2NyaXB0KSB7XG4gICAgTGV4Q29uZmlnLmNoZWNrQ29tcGlsZVR5cGVzY3JpcHRDb25maWcoKTtcblxuICAgIGNvbnN0IHR5cGVzY3JpcHRQYXRoOiBzdHJpbmcgPSByZXNvbHZlQmluYXJ5UGF0aCgndHNjJywgJ3R5cGVzY3JpcHQnKTtcblxuICAgIGlmKCF0eXBlc2NyaXB0UGF0aCkge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiBUeXBlU2NyaXB0IGJpbmFyeSBub3QgZm91bmQgaW4gTGV4J3Mgbm9kZV9tb2R1bGVzIG9yIG1vbm9yZXBvIHJvb3RgLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICBsb2coJ1BsZWFzZSByZWluc3RhbGwgTGV4IG9yIGNoZWNrIHlvdXIgaW5zdGFsbGF0aW9uLicsICdpbmZvJywgcXVpZXQpO1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuXG4gICAgY29uc3QgdHlwZXNjcmlwdE9wdGlvbnM6IHN0cmluZ1tdID0gY29uZmlnID9cbiAgICAgIFsnLXAnLCBjb25maWddIDpcbiAgICAgIFsnLXAnLCBnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aCgndHNjb25maWcuYnVpbGQuanNvbicpXTtcblxuICAgIHNwaW5uZXIuc3RhcnQoJ1N0YXRpYyB0eXBlIGNoZWNraW5nIHdpdGggVHlwZXNjcmlwdC4uLicpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGV4ZWNhKHR5cGVzY3JpcHRQYXRoLCB0eXBlc2NyaXB0T3B0aW9ucywge2VuY29kaW5nOiAndXRmOCd9KTtcblxuICAgICAgc3Bpbm5lci5zdWNjZWVkKCdTdWNjZXNzZnVsbHkgY29tcGxldGVkIHR5cGUgY2hlY2tpbmchJyk7XG4gICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBzcGlubmVyLmZhaWwoJ1R5cGUgY2hlY2tpbmcgZmFpbGVkLicpO1xuXG4gICAgICBjYWxsYmFjaygxKTtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGdsb2JPcHRpb25zID0ge1xuICAgIGN3ZDogc291cmNlRGlyLFxuICAgIGRvdDogZmFsc2UsXG4gICAgbm9kaXI6IHRydWUsXG4gICAgbm9zb3J0OiB0cnVlXG4gIH07XG4gIGNvbnN0IHRzRmlsZXM6IHN0cmluZ1tdID0gZ2xvYlN5bmMoYCR7c291cmNlRGlyfS8qKi8hKCouc3BlY3wqLnRlc3R8Ki5pbnRlZ3JhdGlvbikudHMqYCwgZ2xvYk9wdGlvbnMpO1xuICBjb25zdCBqc0ZpbGVzOiBzdHJpbmdbXSA9IGdsb2JTeW5jKGAke3NvdXJjZURpcn0vKiovISgqLnNwZWN8Ki50ZXN0fCouaW50ZWdyYXRpb24pLmpzYCwgZ2xvYk9wdGlvbnMpO1xuICBjb25zdCBzb3VyY2VGaWxlczogc3RyaW5nW10gPSBbLi4udHNGaWxlcywgLi4uanNGaWxlc107XG5cbiAgY29uc3QgY3NzRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLmNzcycsIExleENvbmZpZy5jb25maWcpO1xuXG4gIGlmKGNzc0ZpbGVzLmxlbmd0aCkge1xuICAgIGNvbnN0IHBvc3Rjc3NQYXRoOiBzdHJpbmcgPSByZXNvbHZlQmluYXJ5UGF0aCgncG9zdGNzcycsICdwb3N0Y3NzLWNsaScpO1xuXG4gICAgaWYoIXBvc3Rjc3NQYXRoKSB7XG4gICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IFBvc3RDU1MgYmluYXJ5IG5vdCBmb3VuZCBpbiBMZXgncyBub2RlX21vZHVsZXMgb3IgbW9ub3JlcG8gcm9vdGAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgIGxvZygnUGxlYXNlIHJlaW5zdGFsbCBMZXggb3IgY2hlY2sgeW91ciBpbnN0YWxsYXRpb24uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG5cbiAgICBjb25zdCBwb3N0Y3NzT3B0aW9uczogc3RyaW5nW10gPSBbXG4gICAgICBgJHtzb3VyY2VEaXJ9LyoqLyoqLmNzc2AsXG4gICAgICAnLS1iYXNlJyxcbiAgICAgIHNvdXJjZURpcixcbiAgICAgICctLWRpcicsXG4gICAgICBvdXRwdXREaXIsXG4gICAgICAnLS1jb25maWcnLFxuICAgICAgcGF0aFJlc29sdmUoZGlyTmFtZSwgJy4uLy4uL3Bvc3Rjc3MuY29uZmlnLmpzJylcbiAgICBdO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGV4ZWNhKHBvc3Rjc3NQYXRoLCBwb3N0Y3NzT3B0aW9ucywge2VuY29kaW5nOiAndXRmOCd9KTtcbiAgICAgIHNwaW5uZXIuc3VjY2VlZChgU3VjY2Vzc2Z1bGx5IGZvcm1hdHRlZCAke2Nzc0ZpbGVzLmxlbmd0aH0gY3NzIGZpbGVzIWApO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgICAgc3Bpbm5lci5mYWlsKCdGYWlsZWQgZm9ybWF0dGluZyBjc3MuJyk7XG5cbiAgICAgIGNhbGxiYWNrKDEpO1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZ2lmRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLmdpZicsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCBqcGdGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcuanBnJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IHBuZ0ZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy5wbmcnLCBMZXhDb25maWcuY29uZmlnKTtcbiAgY29uc3Qgc3ZnRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLnN2ZycsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCBpbWFnZUZpbGVzOiBzdHJpbmdbXSA9IFsuLi5naWZGaWxlcywgLi4uanBnRmlsZXMsIC4uLnBuZ0ZpbGVzLCAuLi5zdmdGaWxlc107XG5cbiAgaWYoaW1hZ2VGaWxlcy5sZW5ndGgpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29weUZpbGVzKGltYWdlRmlsZXMsICdpbWFnZScsIHNwaW5uZXIsIExleENvbmZpZy5jb25maWcpO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgICAgc3Bpbm5lci5mYWlsKCdGYWlsZWQgdG8gbW92ZSBpbWFnZXMgdG8gb3V0cHV0IGRpcmVjdG9yeS4nKTtcblxuICAgICAgY2FsbGJhY2soMSk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuICBjb25zdCB0dGZGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcudHRmJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IG90ZkZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy5vdGYnLCBMZXhDb25maWcuY29uZmlnKTtcbiAgY29uc3Qgd29mZkZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy53b2ZmJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IHdvZmYyRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLndvZmYyJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IGZvbnRGaWxlczogc3RyaW5nW10gPSBbLi4udHRmRmlsZXMsIC4uLm90ZkZpbGVzLCAuLi53b2ZmRmlsZXMsIC4uLndvZmYyRmlsZXNdO1xuXG4gIGlmKGZvbnRGaWxlcy5sZW5ndGgpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29weUZpbGVzKGZvbnRGaWxlcywgJ2ZvbnQnLCBzcGlubmVyLCBMZXhDb25maWcuY29uZmlnKTtcbiAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICAgIHNwaW5uZXIuZmFpbCgnRmFpbGVkIHRvIG1vdmUgZm9udHMgdG8gb3V0cHV0IGRpcmVjdG9yeS4nKTtcblxuICAgICAgY2FsbGJhY2soMSk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBtZEZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy5tZCcsIExleENvbmZpZy5jb25maWcpO1xuXG4gIGlmKG1kRmlsZXMubGVuZ3RoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNvcHlGaWxlcyhtZEZpbGVzLCAnZG9jdW1lbnRzJywgc3Bpbm5lciwgTGV4Q29uZmlnLmNvbmZpZyk7XG4gICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBzcGlubmVyLmZhaWwoJ0ZhaWxlZCB0byBtb3ZlIGRvY3MgdG8gb3V0cHV0IGRpcmVjdG9yeS4nKTtcblxuICAgICAgY2FsbGJhY2soMSk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuICBzcGlubmVyLnN0YXJ0KHdhdGNoID8gJ1dhdGNoaW5nIGZvciBjaGFuZ2VzLi4uJyA6ICdDb21waWxpbmcgd2l0aCBTV0MuLi4nKTtcblxuICB0cnkge1xuICAgIC8vIENvbXBpbGUgZWFjaCBmaWxlIHdpdGggU1dDXG4gICAgZm9yKGNvbnN0IGZpbGUgb2Ygc291cmNlRmlsZXMpIHtcbiAgICAgIGNvbnN0IHNvdXJjZVBhdGggPSBwYXRoUmVzb2x2ZShzb3VyY2VEaXIsIGZpbGUpO1xuICAgICAgY29uc3Qgb3V0cHV0UGF0aCA9IHBhdGhSZXNvbHZlKG91dHB1dERpciwgZmlsZS5yZXBsYWNlKC9cXC4odHN8dHN4KSQvLCAnLmpzJykpO1xuXG4gICAgICAvLyBFbnN1cmUgb3V0cHV0IGRpcmVjdG9yeSBleGlzdHNcbiAgICAgIGNvbnN0IG91dHB1dERpclBhdGggPSBkaXJuYW1lKG91dHB1dFBhdGgpO1xuICAgICAgaWYoIWV4aXN0c1N5bmMob3V0cHV0RGlyUGF0aCkpIHtcbiAgICAgICAgbWtkaXJTeW5jKG91dHB1dERpclBhdGgsIHtyZWN1cnNpdmU6IHRydWV9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc291cmNlQ29kZSA9IHJlYWRGaWxlU3luYyhzb3VyY2VQYXRoLCAndXRmOCcpO1xuXG4gICAgICBjb25zdCBpc1RTWCA9IGZpbGUuZW5kc1dpdGgoJy50c3gnKTtcblxuICAgICAgLy8gTWVyZ2UgU1dDIGNvbmZpZyB3aXRoIGNvbW1hbmQtc3BlY2lmaWMgb3ZlcnJpZGVzXG4gICAgICBjb25zdCBzd2NPcHRpb25zID0ge1xuICAgICAgICBmaWxlbmFtZTogZmlsZSxcbiAgICAgICAgLi4uc3djQ29uZmlnLFxuICAgICAgICBqc2M6IHtcbiAgICAgICAgICAuLi5zd2NDb25maWc/LmpzYyxcbiAgICAgICAgICBwYXJzZXI6IHtcbiAgICAgICAgICAgIGRlY29yYXRvcnM6IHN3Y0NvbmZpZz8uanNjPy5wYXJzZXI/LmRlY29yYXRvcnMgPz8gdHJ1ZSxcbiAgICAgICAgICAgIGR5bmFtaWNJbXBvcnQ6IHN3Y0NvbmZpZz8uanNjPy5wYXJzZXI/LmR5bmFtaWNJbXBvcnQgPz8gdHJ1ZSxcbiAgICAgICAgICAgIHN5bnRheDogJ3R5cGVzY3JpcHQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgdHN4OiBpc1RTWFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGFyZ2V0OiBzd2NDb25maWc/LmpzYz8udGFyZ2V0ID8/ICdlczIwMjAnLFxuICAgICAgICAgIHRyYW5zZm9ybTogaXNUU1ggPyB7XG4gICAgICAgICAgICAuLi5zd2NDb25maWc/LmpzYz8udHJhbnNmb3JtLFxuICAgICAgICAgICAgcmVhY3Q6IHtcbiAgICAgICAgICAgICAgcnVudGltZTogJ2F1dG9tYXRpYycgYXMgY29uc3QsXG4gICAgICAgICAgICAgIC4uLnN3Y0NvbmZpZz8uanNjPy50cmFuc2Zvcm0/LnJlYWN0XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSA6IHN3Y0NvbmZpZz8uanNjPy50cmFuc2Zvcm1cbiAgICAgICAgfSxcbiAgICAgICAgbW9kdWxlOiB7XG4gICAgICAgICAgLi4uc3djQ29uZmlnPy5tb2R1bGUsXG4gICAgICAgICAgdHlwZTogZm9ybWF0ID09PSAnY2pzJyA/ICdjb21tb25qcycgYXMgY29uc3QgOiAoc3djQ29uZmlnPy5tb2R1bGU/LnR5cGUgYXMgJ2VzNicgfHwgJ2VzNicpXG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRyYW5zZm9ybShzb3VyY2VDb2RlLCBzd2NPcHRpb25zKTtcblxuICAgICAgd3JpdGVGaWxlU3luYyhvdXRwdXRQYXRoLCByZXN1bHQuY29kZSk7XG4gICAgfVxuXG4gICAgc3Bpbm5lci5zdWNjZWVkKCdDb21waWxlIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkhJyk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICBpZighcXVpZXQpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgIH1cblxuICAgIHNwaW5uZXIuZmFpbCgnQ29kZSBjb21waWxpbmcgZmFpbGVkLicpO1xuXG4gICAgY2FsbGJhY2soMSk7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICB0cnkge1xuICAgIGF3YWl0IGNvcHlDb25maWd1cmVkRmlsZXMoc3Bpbm5lciwgTGV4Q29uZmlnLmNvbmZpZywgcXVpZXQpO1xuICB9IGNhdGNoKGNvcHlFcnJvcikge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogRmFpbGVkIHRvIGNvcHkgY29uZmlndXJlZCBmaWxlczogJHtjb3B5RXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICBzcGlubmVyLmZhaWwoJ0ZhaWxlZCB0byBjb3B5IGNvbmZpZ3VyZWQgZmlsZXMuJyk7XG5cbiAgICBjYWxsYmFjaygxKTtcbiAgICByZXR1cm4gMTtcbiAgfVxuXG4gIGNhbGxiYWNrKDApO1xuICByZXR1cm4gMDtcbn07Il0sIm5hbWVzIjpbInRyYW5zZm9ybSIsImV4ZWNhIiwiZXhpc3RzU3luYyIsImxzdGF0U3luYyIsInJlYWRkaXJTeW5jIiwicmVhZEZpbGVTeW5jIiwid3JpdGVGaWxlU3luYyIsIm1rZGlyU3luYyIsInN5bmMiLCJnbG9iU3luYyIsImV4dG5hbWUiLCJwYXRoRXh0bmFtZSIsImpvaW4iLCJwYXRoSm9pbiIsInJlc29sdmUiLCJwYXRoUmVzb2x2ZSIsImRpcm5hbWUiLCJMZXhDb25maWciLCJnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aCIsImNoZWNrTGlua2VkTW9kdWxlcyIsImNvcHlDb25maWd1cmVkRmlsZXMiLCJjb3B5RmlsZXMiLCJjcmVhdGVTcGlubmVyIiwiZ2V0RmlsZXNCeUV4dCIsInJlbW92ZUZpbGVzIiwiZ2V0RGlyTmFtZSIsInJlc29sdmVCaW5hcnlQYXRoIiwibG9nIiwiaGFzRmlsZVR5cGUiLCJzdGFydFBhdGgiLCJleHQiLCJmaWxlcyIsInNvbWUiLCJmaWxlIiwiZmlsZW5hbWUiLCJmaWxlRXh0Iiwic3RhdCIsImlzRGlyZWN0b3J5IiwiaW5jbHVkZXMiLCJjb21waWxlIiwiY21kIiwiY2FsbGJhY2siLCJjbGlOYW1lIiwiY29uZmlnIiwiZm9ybWF0Iiwib3V0cHV0UGF0aCIsInF1aWV0IiwicmVtb3ZlIiwic291cmNlUGF0aCIsIndhdGNoIiwic3Bpbm5lciIsInBhcnNlQ29uZmlnIiwib3V0cHV0RnVsbFBhdGgiLCJzb3VyY2VGdWxsUGF0aCIsInN3YyIsInN3Y0NvbmZpZyIsInVzZVR5cGVzY3JpcHQiLCJvdXRwdXREaXIiLCJzb3VyY2VEaXIiLCJwcm9jZXNzIiwiY3dkIiwiZGlyTmFtZSIsImRpclBhdGgiLCJjaGVja0NvbXBpbGVUeXBlc2NyaXB0Q29uZmlnIiwidHlwZXNjcmlwdFBhdGgiLCJ0eXBlc2NyaXB0T3B0aW9ucyIsInN0YXJ0IiwiZW5jb2RpbmciLCJzdWNjZWVkIiwiZXJyb3IiLCJtZXNzYWdlIiwiZmFpbCIsImdsb2JPcHRpb25zIiwiZG90Iiwibm9kaXIiLCJub3NvcnQiLCJ0c0ZpbGVzIiwianNGaWxlcyIsInNvdXJjZUZpbGVzIiwiY3NzRmlsZXMiLCJsZW5ndGgiLCJwb3N0Y3NzUGF0aCIsInBvc3Rjc3NPcHRpb25zIiwiZ2lmRmlsZXMiLCJqcGdGaWxlcyIsInBuZ0ZpbGVzIiwic3ZnRmlsZXMiLCJpbWFnZUZpbGVzIiwidHRmRmlsZXMiLCJvdGZGaWxlcyIsIndvZmZGaWxlcyIsIndvZmYyRmlsZXMiLCJmb250RmlsZXMiLCJtZEZpbGVzIiwicmVwbGFjZSIsIm91dHB1dERpclBhdGgiLCJyZWN1cnNpdmUiLCJzb3VyY2VDb2RlIiwiaXNUU1giLCJlbmRzV2l0aCIsInN3Y09wdGlvbnMiLCJqc2MiLCJwYXJzZXIiLCJkZWNvcmF0b3JzIiwiZHluYW1pY0ltcG9ydCIsInN5bnRheCIsInRzeCIsInRhcmdldCIsInJlYWN0IiwicnVudGltZSIsIm1vZHVsZSIsInR5cGUiLCJyZXN1bHQiLCJjb2RlIiwiY29u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