@coralogix/rum-cli 1.1.26 → 1.1.28

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 (77) hide show
  1. package/README.md +86 -75
  2. package/api/client/request-builder.ts +40 -57
  3. package/api/dsym.api.ts +16 -13
  4. package/api/proguard.api.ts +64 -0
  5. package/api/react-native.api.ts +8 -14
  6. package/api/source-maps.api.ts +7 -13
  7. package/cli/commands/proguard/index.ts +5 -0
  8. package/cli/commands/proguard/upload-proguard-command.ts +36 -0
  9. package/cli/rum-cli.ts +5 -0
  10. package/config/config.ts +2 -0
  11. package/consts/consts.ts +0 -1
  12. package/dist/api/client/client-factory.d.ts +40 -0
  13. package/dist/api/client/request-builder.d.ts +27 -11
  14. package/dist/api/client/request-builder.js +15 -21
  15. package/dist/api/dsym.api.d.ts +1 -1
  16. package/dist/api/dsym.api.js +9 -7
  17. package/dist/api/proguard.api.d.ts +4 -0
  18. package/dist/api/proguard.api.js +52 -0
  19. package/dist/api/react-native.api.js +5 -4
  20. package/dist/api/source-maps.api.js +5 -4
  21. package/dist/cli/commands/proguard/index.d.ts +4 -0
  22. package/dist/cli/commands/proguard/index.js +6 -0
  23. package/dist/cli/commands/proguard/upload-proguard-command.d.ts +2 -0
  24. package/dist/cli/commands/proguard/upload-proguard-command.js +45 -0
  25. package/dist/cli/rum-cli.js +4 -1
  26. package/dist/config/config.d.ts +1 -0
  27. package/dist/config/config.js +2 -1
  28. package/dist/consts/consts.js +2 -3
  29. package/dist/models/proguard-commands.model.d.ts +11 -0
  30. package/dist/models/proguard-commands.model.js +3 -0
  31. package/dist/proto-models/com/coralogix/blobset/v2/entity_metadata.d.ts +18 -0
  32. package/dist/proto-models/com/coralogix/blobset/v2/entity_metadata.js +139 -5
  33. package/dist/proto-models/com/coralogix/blobset/v2/entity_type.d.ts +2 -1
  34. package/dist/proto-models/com/coralogix/blobset/v2/entity_type.js +7 -1
  35. package/dist/proto-models/com/coralogix/rum/v2/release_entity_metadata.d.ts +18 -0
  36. package/dist/proto-models/com/coralogix/rum/v2/release_entity_metadata.js +139 -5
  37. package/dist/proto-models/com/coralogix/rum/v2/release_entity_type.d.ts +2 -1
  38. package/dist/proto-models/com/coralogix/rum/v2/release_entity_type.js +7 -1
  39. package/dist/proto-models/com/coralogix/rum/v2/rum_sdk_versions.d.ts +1 -0
  40. package/dist/proto-models/com/coralogix/rum/v2/rum_sdk_versions.js +17 -3
  41. package/dist/proto-models/com/coralogix/rum/v2/rum_service.d.ts +93 -0
  42. package/dist/proto-models/com/coralogix/rum/v2/rum_service.js +300 -4
  43. package/dist/proto-models/com/coralogix/rum/v2/rum_settings_service.d.ts +9 -8
  44. package/dist/proto-models/com/coralogix/rum/v2/rum_settings_service.js +22 -7
  45. package/dist/services/dsym.service.d.ts +1 -1
  46. package/dist/services/dsym.service.js +3 -3
  47. package/dist/services/proguard.service.d.ts +3 -0
  48. package/dist/services/proguard.service.js +36 -0
  49. package/dist/services/react-native.service.js +2 -2
  50. package/dist/services/source-maps.service.js +2 -2
  51. package/dist/utils/file-processor.utils.d.ts +5 -8
  52. package/dist/utils/file-processor.utils.js +222 -60
  53. package/mapping.txt +160886 -0
  54. package/models/proguard-commands.model.ts +11 -0
  55. package/package.json +2 -3
  56. package/proto-models/com/coralogix/blobset/v2/entity_metadata.ts +160 -4
  57. package/proto-models/com/coralogix/blobset/v2/entity_type.ts +6 -0
  58. package/proto-models/com/coralogix/rum/v2/release_entity_metadata.ts +156 -0
  59. package/proto-models/com/coralogix/rum/v2/release_entity_type.ts +6 -0
  60. package/proto-models/com/coralogix/rum/v2/rum_sdk_versions.ts +17 -1
  61. package/proto-models/com/coralogix/rum/v2/rum_service.ts +347 -1
  62. package/proto-models/com/coralogix/rum/v2/rum_settings_service.ts +23 -6
  63. package/protofetch.lock +4 -4
  64. package/protofetch.toml +3 -3
  65. package/protos/com/coralogix/blobset/v2/entity_metadata.proto +9 -0
  66. package/protos/com/coralogix/blobset/v2/entity_type.proto +1 -0
  67. package/protos/com/coralogix/rum/v2/release_entity_metadata.proto +9 -0
  68. package/protos/com/coralogix/rum/v2/release_entity_type.proto +1 -0
  69. package/protos/com/coralogix/rum/v2/rum_sdk_versions.proto +1 -0
  70. package/protos/com/coralogix/rum/v2/rum_service.proto +23 -0
  71. package/protos/com/coralogix/rum/v2/rum_settings_service.proto +3 -1
  72. package/protoset.bin +0 -0
  73. package/services/dsym.service.ts +2 -2
  74. package/services/proguard.service.ts +33 -0
  75. package/services/react-native.service.ts +1 -1
  76. package/services/source-maps.service.ts +1 -1
  77. package/utils/file-processor.utils.ts +224 -70
@@ -1,4 +1,180 @@
1
1
  "use strict";
2
+ // import * as fs from 'fs';
3
+ // import { Dirent, promises as fsPromises } from 'fs';
4
+ // import * as path from 'path';
5
+ // import { consoleError } from './shared.utils';
6
+ // import { UploadBlobRequest } from '../proto-models/com/coralogix/blobset/v2/blobset_service';
7
+ // import { UploadSourceMapsRequest } from '../proto-models/com/coralogix/rum/v2/rum_source_map_service';
8
+ // import config from '../config';
9
+ // import pako from 'pako';
10
+ // import { FileMetadata } from '../proto-models/com/coralogix/rum/v2/file';
11
+ // import { RED_COLOR } from '../consts/consts';
12
+ // import * as zlib from 'node:zlib';
13
+ //
14
+ // const { readdir, stat, readFile } = fsPromises;
15
+ //
16
+ // export class FileProcessor {
17
+ // static async traverseDsymFolder(folderPath: string, request: UploadBlobRequest): Promise<void> {
18
+ // try {
19
+ // const processDsymFolder = async (dsymFolderPath: string) => {
20
+ // const dwarfPath = await FileProcessor.getDwarfPath(dsymFolderPath);
21
+ // const content = await readFile(dwarfPath);
22
+ // const compressedContent = zlib.gzipSync(content);
23
+ // request.data = new Uint8Array(compressedContent);
24
+ // };
25
+ //
26
+ // // Check if the folder itself is a .dSYM folder
27
+ // if (folderPath.endsWith('.dSYM')) {
28
+ // await processDsymFolder(folderPath);
29
+ // return;
30
+ // }
31
+ //
32
+ // const files: Dirent[] = await readdir(folderPath, { withFileTypes: true });
33
+ //
34
+ // for (const file of files) {
35
+ // // Skip .DS_Store and hidden files
36
+ // if (file.name === '.DS_Store' || file.name.startsWith('.')) {
37
+ // continue;
38
+ // }
39
+ //
40
+ // const filePath: string = path.join(folderPath, file.name);
41
+ //
42
+ // if (file.isDirectory()) {
43
+ // if (file.name.endsWith('.dSYM')) {
44
+ // await processDsymFolder(filePath);
45
+ // return;
46
+ // } else {
47
+ // await FileProcessor.traverseDsymFolder(filePath, request);
48
+ // }
49
+ // }
50
+ // }
51
+ // } catch (error) {
52
+ // consoleError(`Error traversing directory: ${JSON.stringify(error)}`);
53
+ // }
54
+ // }
55
+ //
56
+ // static async traverseSourceMapsFolder(
57
+ // folderPath: string,
58
+ // fileExtension: string,
59
+ // request: UploadBlobRequest,
60
+ // ): Promise<number | undefined> {
61
+ // try {
62
+ // const stats = await stat(folderPath);
63
+ //
64
+ // if (stats.isFile() && folderPath.endsWith(fileExtension)) {
65
+ // return await this.processSourceMapSingleFile(folderPath, fileExtension, request);
66
+ // } else if (stats.isDirectory()) {
67
+ // return await this.processSourceMapDirectory(folderPath, fileExtension, request);
68
+ // }
69
+ // } catch (error) {
70
+ // consoleError(`Error traversing directory: ${error}`);
71
+ // }
72
+ // }
73
+ //
74
+ // private static async processSourceMapSingleFile(filePath: string, fileExtension: string, request: UploadBlobRequest): Promise<number> {
75
+ // try {
76
+ // const content = await readFile(filePath);
77
+ //
78
+ // const { name } = path.parse(filePath);
79
+ //
80
+ // const fileData = { name, content: content.toString('base64') };
81
+ //
82
+ // const compressedContent = zlib.gzipSync(Buffer.from(JSON.stringify([fileData])));
83
+ //
84
+ // request.data = new Uint8Array(compressedContent);
85
+ //
86
+ // return 1;
87
+ // } catch (error) {
88
+ // consoleError(`Error processing file: ${error}`);
89
+ // throw error;
90
+ // }
91
+ // }
92
+ //
93
+ // private static async processSourceMapDirectory(folderPath: string, fileExtension: string, request: UploadBlobRequest): Promise<number> {
94
+ // const files = await readdir(folderPath, { withFileTypes: true });
95
+ // const fileDataList: { name: string; content: string }[] = [];
96
+ //
97
+ // for (const dirent of files) {
98
+ // const filePath = path.join(folderPath, dirent.name);
99
+ //
100
+ // if (dirent.isFile() && dirent.name.endsWith(fileExtension)) {
101
+ // const content = await readFile(filePath);
102
+ // const { name } = path.parse(filePath);
103
+ // fileDataList.push({ name, content: content.toString('base64') });
104
+ // } else if (dirent.isDirectory()) {
105
+ // await this.traverseSourceMapsFolder(filePath, fileExtension, request);
106
+ // }
107
+ // }
108
+ //
109
+ // const compressedContent = zlib.gzipSync(Buffer.from(JSON.stringify(fileDataList)));
110
+ //
111
+ // request.data = new Uint8Array(compressedContent);
112
+ //
113
+ // return fileDataList.length;
114
+ // }
115
+ //
116
+ // private static async getDwarfPath(dsymPath: string): Promise<string> {
117
+ // const dwarfPath: string = 'Contents/Resources/DWARF';
118
+ // const targetPath: string = path.join(dsymPath, dwarfPath);
119
+ // const files = fs.readdirSync(targetPath);
120
+ // if (files.length === 1) {
121
+ // return path.join(dsymPath, dwarfPath, files[0]);
122
+ // } else {
123
+ // consoleError(`Expected exactly one file in the directory, but found: ${files.length}`);
124
+ // return '';
125
+ // }
126
+ // }
127
+ //
128
+ // static async traverseSourceMapsFolderOld(folderPath: string, request: UploadSourceMapsRequest): Promise<void> {
129
+ // const stack: string[] = [folderPath];
130
+ //
131
+ // while (stack.length) {
132
+ // const currentPath = stack.pop();
133
+ // const entries: Dirent[] = await readdir(currentPath!, { withFileTypes: true });
134
+ //
135
+ // await Promise.all(
136
+ // entries.map(async (file: Dirent) => {
137
+ // const { name } = file;
138
+ // const entryPath = path.join(currentPath as string, name);
139
+ // const isCorrectSuffix = file.isFile() && name.endsWith('.js.map');
140
+ //
141
+ // if (file.isDirectory()) stack.push(entryPath);
142
+ // else if (isCorrectSuffix) request.files.push(await FileProcessor.getFileMetadata(entryPath));
143
+ // }),
144
+ // );
145
+ // }
146
+ // }
147
+ //
148
+ // static compressFileContentChunks(fileContent: Uint8Array): Uint8Array {
149
+ // const { chunkSize } = config.rumApi; // 512 KB chunk size
150
+ // const deflate = new pako.Deflate();
151
+ // const totalChunks = Math.ceil(fileContent.length / chunkSize);
152
+ //
153
+ // for (let i = 0; i < totalChunks; i++) {
154
+ // const start = i * chunkSize;
155
+ // const end = start + chunkSize;
156
+ // const chunk = fileContent.subarray(start, end);
157
+ //
158
+ // const isLastChunk = i === totalChunks - 1;
159
+ //
160
+ // deflate.push(chunk, isLastChunk);
161
+ // }
162
+ //
163
+ // const { err, msg, result } = deflate;
164
+ //
165
+ // if (err) console.error(RED_COLOR, msg);
166
+ //
167
+ // return result;
168
+ // }
169
+ //
170
+ // private static async getFileMetadata(filePath: string): Promise<FileMetadata> {
171
+ // const { size } = await stat(filePath);
172
+ // const { name } = path.parse(filePath);
173
+ // const content = await readFile(filePath);
174
+ //
175
+ // return { chunkName: name, size, content };
176
+ // }
177
+ // }
2
178
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
179
  if (k2 === undefined) k2 = k;
4
180
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -31,22 +207,46 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
31
207
  step((generator = generator.apply(thisArg, _arguments || [])).next());
32
208
  });
33
209
  };
34
- var __importDefault = (this && this.__importDefault) || function (mod) {
35
- return (mod && mod.__esModule) ? mod : { "default": mod };
36
- };
37
210
  Object.defineProperty(exports, "__esModule", { value: true });
38
211
  exports.FileProcessor = void 0;
39
212
  const fs = __importStar(require("fs"));
40
213
  const fs_1 = require("fs");
41
214
  const path = __importStar(require("path"));
42
215
  const shared_utils_1 = require("./shared.utils");
43
- const config_1 = __importDefault(require("../config"));
44
- const pako_1 = __importDefault(require("pako"));
45
- const consts_1 = require("../consts/consts");
46
216
  const zlib = __importStar(require("node:zlib"));
47
217
  const { readdir, stat, readFile } = fs_1.promises;
48
218
  class FileProcessor {
49
- static traverseDsymFolder(folderPath, request) {
219
+ static traverseProguardFolder(proguardPath, request) {
220
+ return __awaiter(this, void 0, void 0, function* () {
221
+ try {
222
+ const processTxtFile = (proguardFile) => __awaiter(this, void 0, void 0, function* () {
223
+ const content = yield readFile(proguardFile);
224
+ const compressedContent = zlib.gzipSync(content);
225
+ request.data = new Uint8Array(compressedContent);
226
+ });
227
+ // Check if the folder itself is a .txt file
228
+ if (proguardPath.endsWith('.txt')) {
229
+ yield processTxtFile(proguardPath);
230
+ return;
231
+ }
232
+ const files = yield readdir(proguardPath, { withFileTypes: true });
233
+ for (const file of files) {
234
+ const filePath = path.join(proguardPath, file.name);
235
+ if (file.name.endsWith('.txt')) {
236
+ yield processTxtFile(filePath);
237
+ return;
238
+ }
239
+ else {
240
+ yield FileProcessor.traverseProguardFolder(filePath, request);
241
+ }
242
+ }
243
+ }
244
+ catch (error) {
245
+ (0, shared_utils_1.consoleError)(`Error traversing directory: ${JSON.stringify(error)}`);
246
+ }
247
+ });
248
+ }
249
+ static traverseDsymFolder(dsymPath, request) {
50
250
  return __awaiter(this, void 0, void 0, function* () {
51
251
  try {
52
252
  const processDsymFolder = (dsymFolderPath) => __awaiter(this, void 0, void 0, function* () {
@@ -56,17 +256,17 @@ class FileProcessor {
56
256
  request.data = new Uint8Array(compressedContent);
57
257
  });
58
258
  // Check if the folder itself is a .dSYM folder
59
- if (folderPath.endsWith('.dSYM')) {
60
- yield processDsymFolder(folderPath);
259
+ if (dsymPath.endsWith('.dSYM')) {
260
+ yield processDsymFolder(dsymPath);
61
261
  return;
62
262
  }
63
- const files = yield readdir(folderPath, { withFileTypes: true });
263
+ const files = yield readdir(dsymPath, { withFileTypes: true });
64
264
  for (const file of files) {
65
265
  // Skip .DS_Store and hidden files
66
266
  if (file.name === '.DS_Store' || file.name.startsWith('.')) {
67
267
  continue;
68
268
  }
69
- const filePath = path.join(folderPath, file.name);
269
+ const filePath = path.join(dsymPath, file.name);
70
270
  if (file.isDirectory()) {
71
271
  if (file.name.endsWith('.dSYM')) {
72
272
  yield processDsymFolder(filePath);
@@ -83,15 +283,15 @@ class FileProcessor {
83
283
  }
84
284
  });
85
285
  }
86
- static traverseSourceMapsFolder(folderPath, fileExtension, request) {
286
+ static traverse(folderPath, fileExtension, request) {
87
287
  return __awaiter(this, void 0, void 0, function* () {
88
288
  try {
89
289
  const stats = yield stat(folderPath);
90
290
  if (stats.isFile() && folderPath.endsWith(fileExtension)) {
91
- return yield this.processSourceMapSingleFile(folderPath, fileExtension, request);
291
+ return yield this.processSingleFile(folderPath, fileExtension, request);
92
292
  }
93
293
  else if (stats.isDirectory()) {
94
- return yield this.processSourceMapDirectory(folderPath, fileExtension, request);
294
+ return yield this.processDirectory(folderPath, fileExtension, request);
95
295
  }
96
296
  }
97
297
  catch (error) {
@@ -99,9 +299,13 @@ class FileProcessor {
99
299
  }
100
300
  });
101
301
  }
102
- static processSourceMapSingleFile(filePath, fileExtension, request) {
302
+ static processSingleFile(filePath, fileExtension, request) {
103
303
  return __awaiter(this, void 0, void 0, function* () {
104
304
  try {
305
+ if (!filePath.endsWith(fileExtension)) {
306
+ (0, shared_utils_1.consoleError)(`File ${filePath} does not have the correct extension: ${fileExtension}`);
307
+ return 0;
308
+ }
105
309
  const content = yield readFile(filePath);
106
310
  const { name } = path.parse(filePath);
107
311
  const fileData = { name, content: content.toString('base64') };
@@ -115,7 +319,7 @@ class FileProcessor {
115
319
  }
116
320
  });
117
321
  }
118
- static processSourceMapDirectory(folderPath, fileExtension, request) {
322
+ static processDirectory(folderPath, fileExtension, request) {
119
323
  return __awaiter(this, void 0, void 0, function* () {
120
324
  const files = yield readdir(folderPath, { withFileTypes: true });
121
325
  const fileDataList = [];
@@ -127,7 +331,7 @@ class FileProcessor {
127
331
  fileDataList.push({ name, content: content.toString('base64') });
128
332
  }
129
333
  else if (dirent.isDirectory()) {
130
- yield this.traverseSourceMapsFolder(filePath, fileExtension, request);
334
+ yield this.traverse(filePath, fileExtension, request);
131
335
  }
132
336
  }
133
337
  const compressedContent = zlib.gzipSync(Buffer.from(JSON.stringify(fileDataList)));
@@ -149,48 +353,6 @@ class FileProcessor {
149
353
  }
150
354
  });
151
355
  }
152
- static traverseSourceMapsFolderOld(folderPath, request) {
153
- return __awaiter(this, void 0, void 0, function* () {
154
- const stack = [folderPath];
155
- while (stack.length) {
156
- const currentPath = stack.pop();
157
- const entries = yield readdir(currentPath, { withFileTypes: true });
158
- yield Promise.all(entries.map((file) => __awaiter(this, void 0, void 0, function* () {
159
- const { name } = file;
160
- const entryPath = path.join(currentPath, name);
161
- const isCorrectSuffix = file.isFile() && name.endsWith('.js.map');
162
- if (file.isDirectory())
163
- stack.push(entryPath);
164
- else if (isCorrectSuffix)
165
- request.files.push(yield FileProcessor.getFileMetadata(entryPath));
166
- })));
167
- }
168
- });
169
- }
170
- static compressFileContentChunks(fileContent) {
171
- const { chunkSize } = config_1.default.rumApi; // 512 KB chunk size
172
- const deflate = new pako_1.default.Deflate();
173
- const totalChunks = Math.ceil(fileContent.length / chunkSize);
174
- for (let i = 0; i < totalChunks; i++) {
175
- const start = i * chunkSize;
176
- const end = start + chunkSize;
177
- const chunk = fileContent.subarray(start, end);
178
- const isLastChunk = i === totalChunks - 1;
179
- deflate.push(chunk, isLastChunk);
180
- }
181
- const { err, msg, result } = deflate;
182
- if (err)
183
- console.error(consts_1.RED_COLOR, msg);
184
- return result;
185
- }
186
- static getFileMetadata(filePath) {
187
- return __awaiter(this, void 0, void 0, function* () {
188
- const { size } = yield stat(filePath);
189
- const { name } = path.parse(filePath);
190
- const content = yield readFile(filePath);
191
- return { chunkName: name, size, content };
192
- });
193
- }
194
356
  }
195
357
  exports.FileProcessor = FileProcessor;
196
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1wcm9jZXNzb3IudXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi91dGlscy9maWxlLXByb2Nlc3Nvci51dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUF5QjtBQUN6QiwyQkFBb0Q7QUFDcEQsMkNBQTZCO0FBQzdCLGlEQUE4QztBQUc5Qyx1REFBK0I7QUFDL0IsZ0RBQXdCO0FBRXhCLDZDQUE2QztBQUM3QyxnREFBa0M7QUFFbEMsTUFBTSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEdBQUcsYUFBVSxDQUFDO0FBRS9DLE1BQWEsYUFBYTtJQUN4QixNQUFNLENBQU8sa0JBQWtCLENBQUMsVUFBa0IsRUFBRSxPQUEwQjs7WUFDNUUsSUFBSTtnQkFDRixNQUFNLGlCQUFpQixHQUFHLENBQU8sY0FBc0IsRUFBRSxFQUFFO29CQUN6RCxNQUFNLFNBQVMsR0FBRyxNQUFNLGFBQWEsQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLENBQUM7b0JBQ25FLE1BQU0sT0FBTyxHQUFHLE1BQU0sUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUMxQyxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ2pELE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxVQUFVLENBQUMsaUJBQWlCLENBQUMsQ0FBQztnQkFDbkQsQ0FBQyxDQUFBLENBQUM7Z0JBRUYsK0NBQStDO2dCQUMvQyxJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUU7b0JBQ2hDLE1BQU0saUJBQWlCLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ3BDLE9BQU87aUJBQ1I7Z0JBRUQsTUFBTSxLQUFLLEdBQWEsTUFBTSxPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBRTNFLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO29CQUN4QixrQ0FBa0M7b0JBQ2xDLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxXQUFXLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUU7d0JBQzFELFNBQVM7cUJBQ1Y7b0JBRUQsTUFBTSxRQUFRLEdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUUxRCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTt3QkFDdEIsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRTs0QkFDL0IsTUFBTSxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQzs0QkFDbEMsT0FBTzt5QkFDUjs2QkFBTTs0QkFDTCxNQUFNLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7eUJBQzNEO3FCQUNGO2lCQUNGO2FBQ0Y7WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDZCxJQUFBLDJCQUFZLEVBQUMsK0JBQStCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ3RFO1FBQ0gsQ0FBQztLQUFBO0lBRUQsTUFBTSxDQUFPLHdCQUF3QixDQUNuQyxVQUFrQixFQUNsQixhQUFxQixFQUNyQixPQUEwQjs7WUFFMUIsSUFBSTtnQkFDRixNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFFckMsSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsRUFBRTtvQkFDeEQsT0FBTyxNQUFNLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxVQUFVLEVBQUUsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2lCQUNsRjtxQkFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRTtvQkFDOUIsT0FBTyxNQUFNLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxVQUFVLEVBQUUsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2lCQUNqRjthQUNGO1lBQUMsT0FBTyxLQUFLLEVBQUU7Z0JBQ2QsSUFBQSwyQkFBWSxFQUFDLCtCQUErQixLQUFLLEVBQUUsQ0FBQyxDQUFDO2FBQ3REO1FBQ0gsQ0FBQztLQUFBO0lBRU8sTUFBTSxDQUFPLDBCQUEwQixDQUFDLFFBQWdCLEVBQUUsYUFBcUIsRUFBRSxPQUEwQjs7WUFDakgsSUFBSTtnQkFDRixNQUFNLE9BQU8sR0FBRyxNQUFNLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFFekMsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBRXRDLE1BQU0sUUFBUSxHQUFHLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBRS9ELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFakYsT0FBTyxDQUFDLElBQUksR0FBRyxJQUFJLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO2dCQUVqRCxPQUFPLENBQUMsQ0FBQzthQUNWO1lBQUMsT0FBTyxLQUFLLEVBQUU7Z0JBQ2QsSUFBQSwyQkFBWSxFQUFDLDBCQUEwQixLQUFLLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRCxNQUFNLEtBQUssQ0FBQzthQUNiO1FBQ0gsQ0FBQztLQUFBO0lBRU8sTUFBTSxDQUFPLHlCQUF5QixDQUFDLFVBQWtCLEVBQUUsYUFBcUIsRUFBRSxPQUEwQjs7WUFDbEgsTUFBTSxLQUFLLEdBQUcsTUFBTSxPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDakUsTUFBTSxZQUFZLEdBQXdDLEVBQUUsQ0FBQztZQUU3RCxLQUFLLE1BQU0sTUFBTSxJQUFJLEtBQUssRUFBRTtnQkFDMUIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVwRCxJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUUsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsRUFBRTtvQkFDMUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ3pDLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUN0QyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDbEU7cUJBQU0sSUFBSSxNQUFNLENBQUMsV0FBVyxFQUFFLEVBQUU7b0JBQy9CLE1BQU0sSUFBSSxDQUFDLHdCQUF3QixDQUFDLFFBQVEsRUFBRSxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7aUJBQ3ZFO2FBQ0Y7WUFFRCxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVuRixPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksVUFBVSxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFFakQsT0FBTyxZQUFZLENBQUMsTUFBTSxDQUFDO1FBQzdCLENBQUM7S0FBQTtJQUVPLE1BQU0sQ0FBTyxZQUFZLENBQUMsUUFBZ0I7O1lBQ2hELE1BQU0sU0FBUyxHQUFXLDBCQUEwQixDQUFDO1lBQ3JELE1BQU0sVUFBVSxHQUFXLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQzFELE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDekMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDdEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDakQ7aUJBQU07Z0JBQ0wsSUFBQSwyQkFBWSxFQUFDLDBEQUEwRCxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztnQkFDdkYsT0FBTyxFQUFFLENBQUM7YUFDWDtRQUNILENBQUM7S0FBQTtJQUVELE1BQU0sQ0FBTywyQkFBMkIsQ0FBQyxVQUFrQixFQUFFLE9BQWdDOztZQUMzRixNQUFNLEtBQUssR0FBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRXJDLE9BQU8sS0FBSyxDQUFDLE1BQU0sRUFBRTtnQkFDbkIsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO2dCQUNoQyxNQUFNLE9BQU8sR0FBYSxNQUFNLE9BQU8sQ0FBQyxXQUFZLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFFL0UsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUNmLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBTyxJQUFZLEVBQUUsRUFBRTtvQkFDakMsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQztvQkFDdEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFxQixFQUFFLElBQUksQ0FBQyxDQUFDO29CQUN6RCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFFbEUsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO3dCQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7eUJBQ3pDLElBQUksZUFBZTt3QkFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLGFBQWEsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztnQkFDL0YsQ0FBQyxDQUFBLENBQUMsQ0FDSCxDQUFDO2FBQ0g7UUFDSCxDQUFDO0tBQUE7SUFFRCxNQUFNLENBQUMseUJBQXlCLENBQUMsV0FBdUI7UUFDdEQsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLGdCQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsb0JBQW9CO1FBQ3pELE1BQU0sT0FBTyxHQUFHLElBQUksY0FBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25DLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0FBQztRQUU5RCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3BDLE1BQU0sS0FBSyxHQUFHLENBQUMsR0FBRyxTQUFTLENBQUM7WUFDNUIsTUFBTSxHQUFHLEdBQUcsS0FBSyxHQUFHLFNBQVMsQ0FBQztZQUM5QixNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztZQUUvQyxNQUFNLFdBQVcsR0FBRyxDQUFDLEtBQUssV0FBVyxHQUFHLENBQUMsQ0FBQztZQUUxQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztTQUNsQztRQUVELE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQztRQUVyQyxJQUFJLEdBQUc7WUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLGtCQUFTLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFdkMsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVPLE1BQU0sQ0FBTyxlQUFlLENBQUMsUUFBZ0I7O1lBQ25ELE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN0QyxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN0QyxNQUFNLE9BQU8sR0FBRyxNQUFNLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUV6QyxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7UUFDNUMsQ0FBQztLQUFBO0NBQ0Y7QUFqS0Qsc0NBaUtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHsgRGlyZW50LCBwcm9taXNlcyBhcyBmc1Byb21pc2VzIH0gZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IGNvbnNvbGVFcnJvciB9IGZyb20gJy4vc2hhcmVkLnV0aWxzJztcbmltcG9ydCB7IFVwbG9hZEJsb2JSZXF1ZXN0IH0gZnJvbSAnLi4vcHJvdG8tbW9kZWxzL2NvbS9jb3JhbG9naXgvYmxvYnNldC92Mi9ibG9ic2V0X3NlcnZpY2UnO1xuaW1wb3J0IHsgVXBsb2FkU291cmNlTWFwc1JlcXVlc3QgfSBmcm9tICcuLi9wcm90by1tb2RlbHMvY29tL2NvcmFsb2dpeC9ydW0vdjIvcnVtX3NvdXJjZV9tYXBfc2VydmljZSc7XG5pbXBvcnQgY29uZmlnIGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQgcGFrbyBmcm9tICdwYWtvJztcbmltcG9ydCB7IEZpbGVNZXRhZGF0YSB9IGZyb20gJy4uL3Byb3RvLW1vZGVscy9jb20vY29yYWxvZ2l4L3J1bS92Mi9maWxlJztcbmltcG9ydCB7IFJFRF9DT0xPUiB9IGZyb20gJy4uL2NvbnN0cy9jb25zdHMnO1xuaW1wb3J0ICogYXMgemxpYiBmcm9tICdub2RlOnpsaWInO1xuXG5jb25zdCB7IHJlYWRkaXIsIHN0YXQsIHJlYWRGaWxlIH0gPSBmc1Byb21pc2VzO1xuXG5leHBvcnQgY2xhc3MgRmlsZVByb2Nlc3NvciB7XG4gIHN0YXRpYyBhc3luYyB0cmF2ZXJzZURzeW1Gb2xkZXIoZm9sZGVyUGF0aDogc3RyaW5nLCByZXF1ZXN0OiBVcGxvYWRCbG9iUmVxdWVzdCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwcm9jZXNzRHN5bUZvbGRlciA9IGFzeW5jIChkc3ltRm9sZGVyUGF0aDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IGR3YXJmUGF0aCA9IGF3YWl0IEZpbGVQcm9jZXNzb3IuZ2V0RHdhcmZQYXRoKGRzeW1Gb2xkZXJQYXRoKTtcbiAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IHJlYWRGaWxlKGR3YXJmUGF0aCk7XG4gICAgICAgIGNvbnN0IGNvbXByZXNzZWRDb250ZW50ID0gemxpYi5nemlwU3luYyhjb250ZW50KTtcbiAgICAgICAgcmVxdWVzdC5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoY29tcHJlc3NlZENvbnRlbnQpO1xuICAgICAgfTtcblxuICAgICAgLy8gQ2hlY2sgaWYgdGhlIGZvbGRlciBpdHNlbGYgaXMgYSAuZFNZTSBmb2xkZXJcbiAgICAgIGlmIChmb2xkZXJQYXRoLmVuZHNXaXRoKCcuZFNZTScpKSB7XG4gICAgICAgIGF3YWl0IHByb2Nlc3NEc3ltRm9sZGVyKGZvbGRlclBhdGgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbGVzOiBEaXJlbnRbXSA9IGF3YWl0IHJlYWRkaXIoZm9sZGVyUGF0aCwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pO1xuXG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXMpIHtcbiAgICAgICAgLy8gU2tpcCAuRFNfU3RvcmUgYW5kIGhpZGRlbiBmaWxlc1xuICAgICAgICBpZiAoZmlsZS5uYW1lID09PSAnLkRTX1N0b3JlJyB8fCBmaWxlLm5hbWUuc3RhcnRzV2l0aCgnLicpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmaWxlUGF0aDogc3RyaW5nID0gcGF0aC5qb2luKGZvbGRlclBhdGgsIGZpbGUubmFtZSk7XG5cbiAgICAgICAgaWYgKGZpbGUuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAgIGlmIChmaWxlLm5hbWUuZW5kc1dpdGgoJy5kU1lNJykpIHtcbiAgICAgICAgICAgIGF3YWl0IHByb2Nlc3NEc3ltRm9sZGVyKGZpbGVQYXRoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXdhaXQgRmlsZVByb2Nlc3Nvci50cmF2ZXJzZURzeW1Gb2xkZXIoZmlsZVBhdGgsIHJlcXVlc3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlRXJyb3IoYEVycm9yIHRyYXZlcnNpbmcgZGlyZWN0b3J5OiAke0pTT04uc3RyaW5naWZ5KGVycm9yKX1gKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgdHJhdmVyc2VTb3VyY2VNYXBzRm9sZGVyKFxuICAgIGZvbGRlclBhdGg6IHN0cmluZyxcbiAgICBmaWxlRXh0ZW5zaW9uOiBzdHJpbmcsXG4gICAgcmVxdWVzdDogVXBsb2FkQmxvYlJlcXVlc3QsXG4gICk6IFByb21pc2U8bnVtYmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0YXRzID0gYXdhaXQgc3RhdChmb2xkZXJQYXRoKTtcblxuICAgICAgaWYgKHN0YXRzLmlzRmlsZSgpICYmIGZvbGRlclBhdGguZW5kc1dpdGgoZmlsZUV4dGVuc2lvbikpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucHJvY2Vzc1NvdXJjZU1hcFNpbmdsZUZpbGUoZm9sZGVyUGF0aCwgZmlsZUV4dGVuc2lvbiwgcmVxdWVzdCk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRzLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucHJvY2Vzc1NvdXJjZU1hcERpcmVjdG9yeShmb2xkZXJQYXRoLCBmaWxlRXh0ZW5zaW9uLCByZXF1ZXN0KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZUVycm9yKGBFcnJvciB0cmF2ZXJzaW5nIGRpcmVjdG9yeTogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBhc3luYyBwcm9jZXNzU291cmNlTWFwU2luZ2xlRmlsZShmaWxlUGF0aDogc3RyaW5nLCBmaWxlRXh0ZW5zaW9uOiBzdHJpbmcsIHJlcXVlc3Q6IFVwbG9hZEJsb2JSZXF1ZXN0KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoKTtcblxuICAgICAgY29uc3QgeyBuYW1lIH0gPSBwYXRoLnBhcnNlKGZpbGVQYXRoKTtcblxuICAgICAgY29uc3QgZmlsZURhdGEgPSB7IG5hbWUsIGNvbnRlbnQ6IGNvbnRlbnQudG9TdHJpbmcoJ2Jhc2U2NCcpIH07XG5cbiAgICAgIGNvbnN0IGNvbXByZXNzZWRDb250ZW50ID0gemxpYi5nemlwU3luYyhCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeShbZmlsZURhdGFdKSkpO1xuXG4gICAgICByZXF1ZXN0LmRhdGEgPSBuZXcgVWludDhBcnJheShjb21wcmVzc2VkQ29udGVudCk7XG5cbiAgICAgIHJldHVybiAxO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlRXJyb3IoYEVycm9yIHByb2Nlc3NpbmcgZmlsZTogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGFzeW5jIHByb2Nlc3NTb3VyY2VNYXBEaXJlY3RvcnkoZm9sZGVyUGF0aDogc3RyaW5nLCBmaWxlRXh0ZW5zaW9uOiBzdHJpbmcsIHJlcXVlc3Q6IFVwbG9hZEJsb2JSZXF1ZXN0KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBmaWxlcyA9IGF3YWl0IHJlYWRkaXIoZm9sZGVyUGF0aCwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pO1xuICAgIGNvbnN0IGZpbGVEYXRhTGlzdDogeyBuYW1lOiBzdHJpbmc7IGNvbnRlbnQ6IHN0cmluZyB9W10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgZGlyZW50IG9mIGZpbGVzKSB7XG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbihmb2xkZXJQYXRoLCBkaXJlbnQubmFtZSk7XG5cbiAgICAgIGlmIChkaXJlbnQuaXNGaWxlKCkgJiYgZGlyZW50Lm5hbWUuZW5kc1dpdGgoZmlsZUV4dGVuc2lvbikpIHtcbiAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBwYXRoLnBhcnNlKGZpbGVQYXRoKTtcbiAgICAgICAgZmlsZURhdGFMaXN0LnB1c2goeyBuYW1lLCBjb250ZW50OiBjb250ZW50LnRvU3RyaW5nKCdiYXNlNjQnKSB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZW50LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgYXdhaXQgdGhpcy50cmF2ZXJzZVNvdXJjZU1hcHNGb2xkZXIoZmlsZVBhdGgsIGZpbGVFeHRlbnNpb24sIHJlcXVlc3QpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGNvbXByZXNzZWRDb250ZW50ID0gemxpYi5nemlwU3luYyhCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeShmaWxlRGF0YUxpc3QpKSk7XG5cbiAgICByZXF1ZXN0LmRhdGEgPSBuZXcgVWludDhBcnJheShjb21wcmVzc2VkQ29udGVudCk7XG5cbiAgICByZXR1cm4gZmlsZURhdGFMaXN0Lmxlbmd0aDtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGFzeW5jIGdldER3YXJmUGF0aChkc3ltUGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBkd2FyZlBhdGg6IHN0cmluZyA9ICdDb250ZW50cy9SZXNvdXJjZXMvRFdBUkYnO1xuICAgIGNvbnN0IHRhcmdldFBhdGg6IHN0cmluZyA9IHBhdGguam9pbihkc3ltUGF0aCwgZHdhcmZQYXRoKTtcbiAgICBjb25zdCBmaWxlcyA9IGZzLnJlYWRkaXJTeW5jKHRhcmdldFBhdGgpO1xuICAgIGlmIChmaWxlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBwYXRoLmpvaW4oZHN5bVBhdGgsIGR3YXJmUGF0aCwgZmlsZXNbMF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlRXJyb3IoYEV4cGVjdGVkIGV4YWN0bHkgb25lIGZpbGUgaW4gdGhlIGRpcmVjdG9yeSwgYnV0IGZvdW5kOiAke2ZpbGVzLmxlbmd0aH1gKTtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgdHJhdmVyc2VTb3VyY2VNYXBzRm9sZGVyT2xkKGZvbGRlclBhdGg6IHN0cmluZywgcmVxdWVzdDogVXBsb2FkU291cmNlTWFwc1JlcXVlc3QpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdGFjazogc3RyaW5nW10gPSBbZm9sZGVyUGF0aF07XG5cbiAgICB3aGlsZSAoc3RhY2subGVuZ3RoKSB7XG4gICAgICBjb25zdCBjdXJyZW50UGF0aCA9IHN0YWNrLnBvcCgpO1xuICAgICAgY29uc3QgZW50cmllczogRGlyZW50W10gPSBhd2FpdCByZWFkZGlyKGN1cnJlbnRQYXRoISwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pO1xuXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgZW50cmllcy5tYXAoYXN5bmMgKGZpbGU6IERpcmVudCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgbmFtZSB9ID0gZmlsZTtcbiAgICAgICAgICBjb25zdCBlbnRyeVBhdGggPSBwYXRoLmpvaW4oY3VycmVudFBhdGggYXMgc3RyaW5nLCBuYW1lKTtcbiAgICAgICAgICBjb25zdCBpc0NvcnJlY3RTdWZmaXggPSBmaWxlLmlzRmlsZSgpICYmIG5hbWUuZW5kc1dpdGgoJy5qcy5tYXAnKTtcblxuICAgICAgICAgIGlmIChmaWxlLmlzRGlyZWN0b3J5KCkpIHN0YWNrLnB1c2goZW50cnlQYXRoKTtcbiAgICAgICAgICBlbHNlIGlmIChpc0NvcnJlY3RTdWZmaXgpIHJlcXVlc3QuZmlsZXMucHVzaChhd2FpdCBGaWxlUHJvY2Vzc29yLmdldEZpbGVNZXRhZGF0YShlbnRyeVBhdGgpKTtcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBjb21wcmVzc0ZpbGVDb250ZW50Q2h1bmtzKGZpbGVDb250ZW50OiBVaW50OEFycmF5KTogVWludDhBcnJheSB7XG4gICAgY29uc3QgeyBjaHVua1NpemUgfSA9IGNvbmZpZy5ydW1BcGk7IC8vIDUxMiBLQiBjaHVuayBzaXplXG4gICAgY29uc3QgZGVmbGF0ZSA9IG5ldyBwYWtvLkRlZmxhdGUoKTtcbiAgICBjb25zdCB0b3RhbENodW5rcyA9IE1hdGguY2VpbChmaWxlQ29udGVudC5sZW5ndGggLyBjaHVua1NpemUpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b3RhbENodW5rczsgaSsrKSB7XG4gICAgICBjb25zdCBzdGFydCA9IGkgKiBjaHVua1NpemU7XG4gICAgICBjb25zdCBlbmQgPSBzdGFydCArIGNodW5rU2l6ZTtcbiAgICAgIGNvbnN0IGNodW5rID0gZmlsZUNvbnRlbnQuc3ViYXJyYXkoc3RhcnQsIGVuZCk7XG5cbiAgICAgIGNvbnN0IGlzTGFzdENodW5rID0gaSA9PT0gdG90YWxDaHVua3MgLSAxO1xuXG4gICAgICBkZWZsYXRlLnB1c2goY2h1bmssIGlzTGFzdENodW5rKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGVyciwgbXNnLCByZXN1bHQgfSA9IGRlZmxhdGU7XG5cbiAgICBpZiAoZXJyKSBjb25zb2xlLmVycm9yKFJFRF9DT0xPUiwgbXNnKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBhc3luYyBnZXRGaWxlTWV0YWRhdGEoZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8RmlsZU1ldGFkYXRhPiB7XG4gICAgY29uc3QgeyBzaXplIH0gPSBhd2FpdCBzdGF0KGZpbGVQYXRoKTtcbiAgICBjb25zdCB7IG5hbWUgfSA9IHBhdGgucGFyc2UoZmlsZVBhdGgpO1xuICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCByZWFkRmlsZShmaWxlUGF0aCk7XG5cbiAgICByZXR1cm4geyBjaHVua05hbWU6IG5hbWUsIHNpemUsIGNvbnRlbnQgfTtcbiAgfVxufVxuIl19
358
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1wcm9jZXNzb3IudXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi91dGlscy9maWxlLXByb2Nlc3Nvci51dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsNEJBQTRCO0FBQzVCLHVEQUF1RDtBQUN2RCxnQ0FBZ0M7QUFDaEMsaURBQWlEO0FBQ2pELGdHQUFnRztBQUNoRyx5R0FBeUc7QUFDekcsa0NBQWtDO0FBQ2xDLDJCQUEyQjtBQUMzQiw0RUFBNEU7QUFDNUUsZ0RBQWdEO0FBQ2hELHFDQUFxQztBQUNyQyxFQUFFO0FBQ0Ysa0RBQWtEO0FBQ2xELEVBQUU7QUFDRiwrQkFBK0I7QUFDL0IscUdBQXFHO0FBQ3JHLFlBQVk7QUFDWixzRUFBc0U7QUFDdEUsOEVBQThFO0FBQzlFLHFEQUFxRDtBQUNyRCw0REFBNEQ7QUFDNUQsNERBQTREO0FBQzVELFdBQVc7QUFDWCxFQUFFO0FBQ0Ysd0RBQXdEO0FBQ3hELDRDQUE0QztBQUM1QywrQ0FBK0M7QUFDL0Msa0JBQWtCO0FBQ2xCLFVBQVU7QUFDVixFQUFFO0FBQ0Ysb0ZBQW9GO0FBQ3BGLEVBQUU7QUFDRixvQ0FBb0M7QUFDcEMsNkNBQTZDO0FBQzdDLHdFQUF3RTtBQUN4RSxzQkFBc0I7QUFDdEIsWUFBWTtBQUNaLEVBQUU7QUFDRixxRUFBcUU7QUFDckUsRUFBRTtBQUNGLG9DQUFvQztBQUNwQywrQ0FBK0M7QUFDL0MsaURBQWlEO0FBQ2pELHNCQUFzQjtBQUN0QixxQkFBcUI7QUFDckIseUVBQXlFO0FBQ3pFLGNBQWM7QUFDZCxZQUFZO0FBQ1osVUFBVTtBQUNWLHdCQUF3QjtBQUN4Qiw4RUFBOEU7QUFDOUUsUUFBUTtBQUNSLE1BQU07QUFDTixFQUFFO0FBQ0YsMkNBQTJDO0FBQzNDLDBCQUEwQjtBQUMxQiw2QkFBNkI7QUFDN0Isa0NBQWtDO0FBQ2xDLHFDQUFxQztBQUNyQyxZQUFZO0FBQ1osOENBQThDO0FBQzlDLEVBQUU7QUFDRixvRUFBb0U7QUFD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Q0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQztpQkFDdkQ7YUFDRjtZQUVELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRW5GLE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxVQUFVLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUVqRCxPQUFPLFlBQVksQ0FBQyxNQUFNLENBQUM7UUFDN0IsQ0FBQztLQUFBO0lBRU8sTUFBTSxDQUFPLFlBQVksQ0FBQyxRQUFnQjs7WUFDaEQsTUFBTSxTQUFTLEdBQVcsMEJBQTBCLENBQUM7WUFDckQsTUFBTSxVQUFVLEdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDMUQsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN6QyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUN0QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNqRDtpQkFBTTtnQkFDTCxJQUFBLDJCQUFZLEVBQUMsMERBQTBELEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO2dCQUN2RixPQUFPLEVBQUUsQ0FBQzthQUNYO1FBQ0gsQ0FBQztLQUFBO0NBQ0Y7QUEvSUQsc0NBK0lDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuLy8gaW1wb3J0IHsgRGlyZW50LCBwcm9taXNlcyBhcyBmc1Byb21pc2VzIH0gZnJvbSAnZnMnO1xuLy8gaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbi8vIGltcG9ydCB7IGNvbnNvbGVFcnJvciB9IGZyb20gJy4vc2hhcmVkLnV0aWxzJztcbi8vIGltcG9ydCB7IFVwbG9hZEJsb2JSZXF1ZXN0IH0gZnJvbSAnLi4vcHJvdG8tbW9kZWxzL2NvbS9jb3JhbG9naXgvYmxvYnNldC92Mi9ibG9ic2V0X3NlcnZpY2UnO1xuLy8gaW1wb3J0IHsgVXBsb2FkU291cmNlTWFwc1JlcXVlc3QgfSBmcm9tICcuLi9wcm90by1tb2RlbHMvY29tL2NvcmFsb2dpeC9ydW0vdjIvcnVtX3NvdXJjZV9tYXBfc2VydmljZSc7XG4vLyBpbXBvcnQgY29uZmlnIGZyb20gJy4uL2NvbmZpZyc7XG4vLyBpbXBvcnQgcGFrbyBmcm9tICdwYWtvJztcbi8vIGltcG9ydCB7IEZpbGVNZXRhZGF0YSB9IGZyb20gJy4uL3Byb3RvLW1vZGVscy9jb20vY29yYWxvZ2l4L3J1bS92Mi9maWxlJztcbi8vIGltcG9ydCB7IFJFRF9DT0xPUiB9IGZyb20gJy4uL2NvbnN0cy9jb25zdHMnO1xuLy8gaW1wb3J0ICogYXMgemxpYiBmcm9tICdub2RlOnpsaWInO1xuLy9cbi8vIGNvbnN0IHsgcmVhZGRpciwgc3RhdCwgcmVhZEZpbGUgfSA9IGZzUHJvbWlzZXM7XG4vL1xuLy8gZXhwb3J0IGNsYXNzIEZpbGVQcm9jZXNzb3Ige1xuLy8gICBzdGF0aWMgYXN5bmMgdHJhdmVyc2VEc3ltRm9sZGVyKGZvbGRlclBhdGg6IHN0cmluZywgcmVxdWVzdDogVXBsb2FkQmxvYlJlcXVlc3QpOiBQcm9taXNlPHZvaWQ+IHtcbi8vICAgICB0cnkge1xuLy8gICAgICAgY29uc3QgcHJvY2Vzc0RzeW1Gb2xkZXIgPSBhc3luYyAoZHN5bUZvbGRlclBhdGg6IHN0cmluZykgPT4ge1xuLy8gICAgICAgICBjb25zdCBkd2FyZlBhdGggPSBhd2FpdCBGaWxlUHJvY2Vzc29yLmdldER3YXJmUGF0aChkc3ltRm9sZGVyUGF0aCk7XG4vLyAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCByZWFkRmlsZShkd2FyZlBhdGgpO1xuLy8gICAgICAgICBjb25zdCBjb21wcmVzc2VkQ29udGVudCA9IHpsaWIuZ3ppcFN5bmMoY29udGVudCk7XG4vLyAgICAgICAgIHJlcXVlc3QuZGF0YSA9IG5ldyBVaW50OEFycmF5KGNvbXByZXNzZWRDb250ZW50KTtcbi8vICAgICAgIH07XG4vL1xuLy8gICAgICAgLy8gQ2hlY2sgaWYgdGhlIGZvbGRlciBpdHNlbGYgaXMgYSAuZFNZTSBmb2xkZXJcbi8vICAgICAgIGlmIChmb2xkZXJQYXRoLmVuZHNXaXRoKCcuZFNZTScpKSB7XG4vLyAgICAgICAgIGF3YWl0IHByb2Nlc3NEc3ltRm9sZGVyKGZvbGRlclBhdGgpO1xuLy8gICAgICAgICByZXR1cm47XG4vLyAgICAgICB9XG4vL1xuLy8gICAgICAgY29uc3QgZmlsZXM6IERpcmVudFtdID0gYXdhaXQgcmVhZGRpcihmb2xkZXJQYXRoLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG4vL1xuLy8gICAgICAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4vLyAgICAgICAgIC8vIFNraXAgLkRTX1N0b3JlIGFuZCBoaWRkZW4gZmlsZXNcbi8vICAgICAgICAgaWYgKGZpbGUubmFtZSA9PT0gJy5EU19TdG9yZScgfHwgZmlsZS5uYW1lLnN0YXJ0c1dpdGgoJy4nKSkge1xuLy8gICAgICAgICAgIGNvbnRpbnVlO1xuLy8gICAgICAgICB9XG4vL1xuLy8gICAgICAgICBjb25zdCBmaWxlUGF0aDogc3RyaW5nID0gcGF0aC5qb2luKGZvbGRlclBhdGgsIGZpbGUubmFtZSk7XG4vL1xuLy8gICAgICAgICBpZiAoZmlsZS5pc0RpcmVjdG9yeSgpKSB7XG4vLyAgICAgICAgICAgaWYgKGZpbGUubmFtZS5lbmRzV2l0aCgnLmRTWU0nKSkge1xuLy8gICAgICAgICAgICAgYXdhaXQgcHJvY2Vzc0RzeW1Gb2xkZXIoZmlsZVBhdGgpO1xuLy8gICAgICAgICAgICAgcmV0dXJuO1xuLy8gICAgICAgICAgIH0gZWxzZSB7XG4vLyAgICAgICAgICAgICBhd2FpdCBGaWxlUHJvY2Vzc29yLnRyYXZlcnNlRHN5bUZvbGRlcihmaWxlUGF0aCwgcmVxdWVzdCk7XG4vLyAgICAgICAgICAgfVxuLy8gICAgICAgICB9XG4vLyAgICAgICB9XG4vLyAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbi8vICAgICAgIGNvbnNvbGVFcnJvcihgRXJyb3IgdHJhdmVyc2luZyBkaXJlY3Rvcnk6ICR7SlNPTi5zdHJpbmdpZnkoZXJyb3IpfWApO1xuLy8gICAgIH1cbi8vICAgfVxuLy9cbi8vICAgc3RhdGljIGFzeW5jIHRyYXZlcnNlU291cmNlTWFwc0ZvbGRlcihcbi8vICAgICBmb2xkZXJQYXRoOiBzdHJpbmcsXG4vLyAgICAgZmlsZUV4dGVuc2lvbjogc3RyaW5nLFxuLy8gICAgIHJlcXVlc3Q6IFVwbG9hZEJsb2JSZXF1ZXN0LFxuLy8gICApOiBQcm9taXNlPG51bWJlciB8IHVuZGVmaW5lZD4ge1xuLy8gICAgIHRyeSB7XG4vLyAgICAgICBjb25zdCBzdGF0cyA9IGF3YWl0IHN0YXQoZm9sZGVyUGF0aCk7XG4vL1xuLy8gICAgICAgaWYgKHN0YXRzLmlzRmlsZSgpICYmIGZvbGRlclBhdGguZW5kc1dpdGgoZmlsZUV4dGVuc2lvbikpIHtcbi8vICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucHJvY2Vzc1NvdXJjZU1hcFNpbmdsZUZpbGUoZm9sZGVyUGF0aCwgZmlsZUV4dGVuc2lvbiwgcmVxdWVzdCk7XG4vLyAgICAgICB9IGVsc2UgaWYgKHN0YXRzLmlzRGlyZWN0b3J5KCkpIHtcbi8vICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucHJvY2Vzc1NvdXJjZU1hcERpcmVjdG9yeShmb2xkZXJQYXRoLCBmaWxlRXh0ZW5zaW9uLCByZXF1ZXN0KTtcbi8vICAgICAgIH1cbi8vICAgICB9IGNhdGNoIChlcnJvcikge1xuLy8gICAgICAgY29uc29sZUVycm9yKGBFcnJvciB0cmF2ZXJzaW5nIGRpcmVjdG9yeTogJHtlcnJvcn1gKTtcbi8vICAgICB9XG4vLyAgIH1cbi8vXG4vLyAgIHByaXZhdGUgc3RhdGljIGFzeW5jIHByb2Nlc3NTb3VyY2VNYXBTaW5nbGVGaWxlKGZpbGVQYXRoOiBzdHJpbmcsIGZpbGVFeHRlbnNpb246IHN0cmluZywgcmVxdWVzdDogVXBsb2FkQmxvYlJlcXVlc3QpOiBQcm9taXNlPG51bWJlcj4ge1xuLy8gICAgIHRyeSB7XG4vLyAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgcmVhZEZpbGUoZmlsZVBhdGgpO1xuLy9cbi8vICAgICAgIGNvbnN0IHsgbmFtZSB9ID0gcGF0aC5wYXJzZShmaWxlUGF0aCk7XG4vL1xuLy8gICAgICAgY29uc3QgZmlsZURhdGEgPSB7IG5hbWUsIGNvbnRlbnQ6IGNvbnRlbnQudG9TdHJpbmcoJ2Jhc2U2NCcpIH07XG4vL1xuLy8gICAgICAgY29uc3QgY29tcHJlc3NlZENvbnRlbnQgPSB6bGliLmd6aXBTeW5jKEJ1ZmZlci5mcm9tKEpTT04uc3RyaW5naWZ5KFtmaWxlRGF0YV0pKSk7XG4vL1xuLy8gICAgICAgcmVxdWVzdC5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoY29tcHJlc3NlZENvbnRlbnQpO1xuLy9cbi8vICAgICAgIHJldHVybiAxO1xuLy8gICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4vLyAgICAgICBjb25zb2xlRXJyb3IoYEVycm9yIHByb2Nlc3NpbmcgZmlsZTogJHtlcnJvcn1gKTtcbi8vICAgICAgIHRocm93IGVycm9yO1xuLy8gICAgIH1cbi8vICAgfVxuLy9cbi8vICAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgcHJvY2Vzc1NvdXJjZU1hcERpcmVjdG9yeShmb2xkZXJQYXRoOiBzdHJpbmcsIGZpbGVFeHRlbnNpb246IHN0cmluZywgcmVxdWVzdDogVXBsb2FkQmxvYlJlcXVlc3QpOiBQcm9taXNlPG51bWJlcj4ge1xuLy8gICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgcmVhZGRpcihmb2xkZXJQYXRoLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG4vLyAgICAgY29uc3QgZmlsZURhdGFMaXN0OiB7IG5hbWU6IHN0cmluZzsgY29udGVudDogc3RyaW5nIH1bXSA9IFtdO1xuLy9cbi8vICAgICBmb3IgKGNvbnN0IGRpcmVudCBvZiBmaWxlcykge1xuLy8gICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oZm9sZGVyUGF0aCwgZGlyZW50Lm5hbWUpO1xuLy9cbi8vICAgICAgIGlmIChkaXJlbnQuaXNGaWxlKCkgJiYgZGlyZW50Lm5hbWUuZW5kc1dpdGgoZmlsZUV4dGVuc2lvbikpIHtcbi8vICAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoKTtcbi8vICAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBwYXRoLnBhcnNlKGZpbGVQYXRoKTtcbi8vICAgICAgICAgZmlsZURhdGFMaXN0LnB1c2goeyBuYW1lLCBjb250ZW50OiBjb250ZW50LnRvU3RyaW5nKCdiYXNlNjQnKSB9KTtcbi8vICAgICAgIH0gZWxzZSBpZiAoZGlyZW50LmlzRGlyZWN0b3J5KCkpIHtcbi8vICAgICAgICAgYXdhaXQgdGhpcy50cmF2ZXJzZVNvdXJjZU1hcHNGb2xkZXIoZmlsZVBhdGgsIGZpbGVFeHRlbnNpb24sIHJlcXVlc3QpO1xuLy8gICAgICAgfVxuLy8gICAgIH1cbi8vXG4vLyAgICAgY29uc3QgY29tcHJlc3NlZENvbnRlbnQgPSB6bGliLmd6aXBTeW5jKEJ1ZmZlci5mcm9tKEpTT04uc3RyaW5naWZ5KGZpbGVEYXRhTGlzdCkpKTtcbi8vXG4vLyAgICAgcmVxdWVzdC5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoY29tcHJlc3NlZENvbnRlbnQpO1xuLy9cbi8vICAgICByZXR1cm4gZmlsZURhdGFMaXN0Lmxlbmd0aDtcbi8vICAgfVxuLy9cbi8vICAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgZ2V0RHdhcmZQYXRoKGRzeW1QYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuLy8gICAgIGNvbnN0IGR3YXJmUGF0aDogc3RyaW5nID0gJ0NvbnRlbnRzL1Jlc291cmNlcy9EV0FSRic7XG4vLyAgICAgY29uc3QgdGFyZ2V0UGF0aDogc3RyaW5nID0gcGF0aC5qb2luKGRzeW1QYXRoLCBkd2FyZlBhdGgpO1xuLy8gICAgIGNvbnN0IGZpbGVzID0gZnMucmVhZGRpclN5bmModGFyZ2V0UGF0aCk7XG4vLyAgICAgaWYgKGZpbGVzLmxlbmd0aCA9PT0gMSkge1xuLy8gICAgICAgcmV0dXJuIHBhdGguam9pbihkc3ltUGF0aCwgZHdhcmZQYXRoLCBmaWxlc1swXSk7XG4vLyAgICAgfSBlbHNlIHtcbi8vICAgICAgIGNvbnNvbGVFcnJvcihgRXhwZWN0ZWQgZXhhY3RseSBvbmUgZmlsZSBpbiB0aGUgZGlyZWN0b3J5LCBidXQgZm91bmQ6ICR7ZmlsZXMubGVuZ3RofWApO1xuLy8gICAgICAgcmV0dXJuICcnO1xuLy8gICAgIH1cbi8vICAgfVxuLy9cbi8vICAgc3RhdGljIGFzeW5jIHRyYXZlcnNlU291cmNlTWFwc0ZvbGRlck9sZChmb2xkZXJQYXRoOiBzdHJpbmcsIHJlcXVlc3Q6IFVwbG9hZFNvdXJjZU1hcHNSZXF1ZXN0KTogUHJvbWlzZTx2b2lkPiB7XG4vLyAgICAgY29uc3Qgc3RhY2s6IHN0cmluZ1tdID0gW2ZvbGRlclBhdGhdO1xuLy9cbi8vICAgICB3aGlsZSAoc3RhY2subGVuZ3RoKSB7XG4vLyAgICAgICBjb25zdCBjdXJyZW50UGF0aCA9IHN0YWNrLnBvcCgpO1xuLy8gICAgICAgY29uc3QgZW50cmllczogRGlyZW50W10gPSBhd2FpdCByZWFkZGlyKGN1cnJlbnRQYXRoISwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pO1xuLy9cbi8vICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuLy8gICAgICAgICBlbnRyaWVzLm1hcChhc3luYyAoZmlsZTogRGlyZW50KSA9PiB7XG4vLyAgICAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBmaWxlO1xuLy8gICAgICAgICAgIGNvbnN0IGVudHJ5UGF0aCA9IHBhdGguam9pbihjdXJyZW50UGF0aCBhcyBzdHJpbmcsIG5hbWUpO1xuLy8gICAgICAgICAgIGNvbnN0IGlzQ29ycmVjdFN1ZmZpeCA9IGZpbGUuaXNGaWxlKCkgJiYgbmFtZS5lbmRzV2l0aCgnLmpzLm1hcCcpO1xuLy9cbi8vICAgICAgICAgICBpZiAoZmlsZS5pc0RpcmVjdG9yeSgpKSBzdGFjay5wdXNoKGVudHJ5UGF0aCk7XG4vLyAgICAgICAgICAgZWxzZSBpZiAoaXNDb3JyZWN0U3VmZml4KSByZXF1ZXN0LmZpbGVzLnB1c2goYXdhaXQgRmlsZVByb2Nlc3Nvci5nZXRGaWxlTWV0YWRhdGEoZW50cnlQYXRoKSk7XG4vLyAgICAgICAgIH0pLFxuLy8gICAgICAgKTtcbi8vICAgICB9XG4vLyAgIH1cbi8vXG4vLyAgIHN0YXRpYyBjb21wcmVzc0ZpbGVDb250ZW50Q2h1bmtzKGZpbGVDb250ZW50OiBVaW50OEFycmF5KTogVWludDhBcnJheSB7XG4vLyAgICAgY29uc3QgeyBjaHVua1NpemUgfSA9IGNvbmZpZy5ydW1BcGk7IC8vIDUxMiBLQiBjaHVuayBzaXplXG4vLyAgICAgY29uc3QgZGVmbGF0ZSA9IG5ldyBwYWtvLkRlZmxhdGUoKTtcbi8vICAgICBjb25zdCB0b3RhbENodW5rcyA9IE1hdGguY2VpbChmaWxlQ29udGVudC5sZW5ndGggLyBjaHVua1NpemUpO1xuLy9cbi8vICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRvdGFsQ2h1bmtzOyBpKyspIHtcbi8vICAgICAgIGNvbnN0IHN0YXJ0ID0gaSAqIGNodW5rU2l6ZTtcbi8vICAgICAgIGNvbnN0IGVuZCA9IHN0YXJ0ICsgY2h1bmtTaXplO1xuLy8gICAgICAgY29uc3QgY2h1bmsgPSBmaWxlQ29udGVudC5zdWJhcnJheShzdGFydCwgZW5kKTtcbi8vXG4vLyAgICAgICBjb25zdCBpc0xhc3RDaHVuayA9IGkgPT09IHRvdGFsQ2h1bmtzIC0gMTtcbi8vXG4vLyAgICAgICBkZWZsYXRlLnB1c2goY2h1bmssIGlzTGFzdENodW5rKTtcbi8vICAgICB9XG4vL1xuLy8gICAgIGNvbnN0IHsgZXJyLCBtc2csIHJlc3VsdCB9ID0gZGVmbGF0ZTtcbi8vXG4vLyAgICAgaWYgKGVycikgY29uc29sZS5lcnJvcihSRURfQ09MT1IsIG1zZyk7XG4vL1xuLy8gICAgIHJldHVybiByZXN1bHQ7XG4vLyAgIH1cbi8vXG4vLyAgIHByaXZhdGUgc3RhdGljIGFzeW5jIGdldEZpbGVNZXRhZGF0YShmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxGaWxlTWV0YWRhdGE+IHtcbi8vICAgICBjb25zdCB7IHNpemUgfSA9IGF3YWl0IHN0YXQoZmlsZVBhdGgpO1xuLy8gICAgIGNvbnN0IHsgbmFtZSB9ID0gcGF0aC5wYXJzZShmaWxlUGF0aCk7XG4vLyAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoKTtcbi8vXG4vLyAgICAgcmV0dXJuIHsgY2h1bmtOYW1lOiBuYW1lLCBzaXplLCBjb250ZW50IH07XG4vLyAgIH1cbi8vIH1cblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHsgRGlyZW50LCBwcm9taXNlcyBhcyBmc1Byb21pc2VzIH0gZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IGNvbnNvbGVFcnJvciB9IGZyb20gJy4vc2hhcmVkLnV0aWxzJztcbmltcG9ydCB7IFVwbG9hZEJsb2JSZXF1ZXN0IH0gZnJvbSAnLi4vcHJvdG8tbW9kZWxzL2NvbS9jb3JhbG9naXgvYmxvYnNldC92Mi9ibG9ic2V0X3NlcnZpY2UnO1xuaW1wb3J0ICogYXMgemxpYiBmcm9tICdub2RlOnpsaWInO1xuXG5jb25zdCB7IHJlYWRkaXIsIHN0YXQsIHJlYWRGaWxlIH0gPSBmc1Byb21pc2VzO1xuXG5leHBvcnQgY2xhc3MgRmlsZVByb2Nlc3NvciB7XG4gIHN0YXRpYyBhc3luYyB0cmF2ZXJzZVByb2d1YXJkRm9sZGVyKHByb2d1YXJkUGF0aDogc3RyaW5nLCByZXF1ZXN0OiBVcGxvYWRCbG9iUmVxdWVzdCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwcm9jZXNzVHh0RmlsZSA9IGFzeW5jIChwcm9ndWFyZEZpbGU6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgcmVhZEZpbGUocHJvZ3VhcmRGaWxlKTtcbiAgICAgICAgY29uc3QgY29tcHJlc3NlZENvbnRlbnQgPSB6bGliLmd6aXBTeW5jKGNvbnRlbnQpO1xuICAgICAgICByZXF1ZXN0LmRhdGEgPSBuZXcgVWludDhBcnJheShjb21wcmVzc2VkQ29udGVudCk7XG4gICAgICB9O1xuXG4gICAgICAvLyBDaGVjayBpZiB0aGUgZm9sZGVyIGl0c2VsZiBpcyBhIC50eHQgZmlsZVxuICAgICAgaWYgKHByb2d1YXJkUGF0aC5lbmRzV2l0aCgnLnR4dCcpKSB7XG4gICAgICAgIGF3YWl0IHByb2Nlc3NUeHRGaWxlKHByb2d1YXJkUGF0aCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmlsZXM6IERpcmVudFtdID0gYXdhaXQgcmVhZGRpcihwcm9ndWFyZFBhdGgsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KTtcblxuICAgICAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICAgIGNvbnN0IGZpbGVQYXRoOiBzdHJpbmcgPSBwYXRoLmpvaW4ocHJvZ3VhcmRQYXRoLCBmaWxlLm5hbWUpO1xuXG4gICAgICAgIGlmIChmaWxlLm5hbWUuZW5kc1dpdGgoJy50eHQnKSkge1xuICAgICAgICAgIGF3YWl0IHByb2Nlc3NUeHRGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXdhaXQgRmlsZVByb2Nlc3Nvci50cmF2ZXJzZVByb2d1YXJkRm9sZGVyKGZpbGVQYXRoLCByZXF1ZXN0KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlRXJyb3IoYEVycm9yIHRyYXZlcnNpbmcgZGlyZWN0b3J5OiAke0pTT04uc3RyaW5naWZ5KGVycm9yKX1gKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgdHJhdmVyc2VEc3ltRm9sZGVyKGRzeW1QYXRoOiBzdHJpbmcsIHJlcXVlc3Q6IFVwbG9hZEJsb2JSZXF1ZXN0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHByb2Nlc3NEc3ltRm9sZGVyID0gYXN5bmMgKGRzeW1Gb2xkZXJQYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgZHdhcmZQYXRoID0gYXdhaXQgRmlsZVByb2Nlc3Nvci5nZXREd2FyZlBhdGgoZHN5bUZvbGRlclBhdGgpO1xuICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgcmVhZEZpbGUoZHdhcmZQYXRoKTtcbiAgICAgICAgY29uc3QgY29tcHJlc3NlZENvbnRlbnQgPSB6bGliLmd6aXBTeW5jKGNvbnRlbnQpO1xuICAgICAgICByZXF1ZXN0LmRhdGEgPSBuZXcgVWludDhBcnJheShjb21wcmVzc2VkQ29udGVudCk7XG4gICAgICB9O1xuXG4gICAgICAvLyBDaGVjayBpZiB0aGUgZm9sZGVyIGl0c2VsZiBpcyBhIC5kU1lNIGZvbGRlclxuICAgICAgaWYgKGRzeW1QYXRoLmVuZHNXaXRoKCcuZFNZTScpKSB7XG4gICAgICAgIGF3YWl0IHByb2Nlc3NEc3ltRm9sZGVyKGRzeW1QYXRoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmaWxlczogRGlyZW50W10gPSBhd2FpdCByZWFkZGlyKGRzeW1QYXRoLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG5cbiAgICAgIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xuICAgICAgICAvLyBTa2lwIC5EU19TdG9yZSBhbmQgaGlkZGVuIGZpbGVzXG4gICAgICAgIGlmIChmaWxlLm5hbWUgPT09ICcuRFNfU3RvcmUnIHx8IGZpbGUubmFtZS5zdGFydHNXaXRoKCcuJykpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpbGVQYXRoOiBzdHJpbmcgPSBwYXRoLmpvaW4oZHN5bVBhdGgsIGZpbGUubmFtZSk7XG5cbiAgICAgICAgaWYgKGZpbGUuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAgIGlmIChmaWxlLm5hbWUuZW5kc1dpdGgoJy5kU1lNJykpIHtcbiAgICAgICAgICAgIGF3YWl0IHByb2Nlc3NEc3ltRm9sZGVyKGZpbGVQYXRoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXdhaXQgRmlsZVByb2Nlc3Nvci50cmF2ZXJzZURzeW1Gb2xkZXIoZmlsZVBhdGgsIHJlcXVlc3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlRXJyb3IoYEVycm9yIHRyYXZlcnNpbmcgZGlyZWN0b3J5OiAke0pTT04uc3RyaW5naWZ5KGVycm9yKX1gKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgdHJhdmVyc2UoZm9sZGVyUGF0aDogc3RyaW5nLCBmaWxlRXh0ZW5zaW9uOiBzdHJpbmcsIHJlcXVlc3Q6IFVwbG9hZEJsb2JSZXF1ZXN0KTogUHJvbWlzZTxudW1iZXIgfCB1bmRlZmluZWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3RhdHMgPSBhd2FpdCBzdGF0KGZvbGRlclBhdGgpO1xuXG4gICAgICBpZiAoc3RhdHMuaXNGaWxlKCkgJiYgZm9sZGVyUGF0aC5lbmRzV2l0aChmaWxlRXh0ZW5zaW9uKSkge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5wcm9jZXNzU2luZ2xlRmlsZShmb2xkZXJQYXRoLCBmaWxlRXh0ZW5zaW9uLCByZXF1ZXN0KTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdHMuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5wcm9jZXNzRGlyZWN0b3J5KGZvbGRlclBhdGgsIGZpbGVFeHRlbnNpb24sIHJlcXVlc3QpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlRXJyb3IoYEVycm9yIHRyYXZlcnNpbmcgZGlyZWN0b3J5OiAke2Vycm9yfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGFzeW5jIHByb2Nlc3NTaW5nbGVGaWxlKGZpbGVQYXRoOiBzdHJpbmcsIGZpbGVFeHRlbnNpb246IHN0cmluZywgcmVxdWVzdDogVXBsb2FkQmxvYlJlcXVlc3QpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIHRyeSB7XG4gICAgICBpZiAoIWZpbGVQYXRoLmVuZHNXaXRoKGZpbGVFeHRlbnNpb24pKSB7XG4gICAgICAgIGNvbnNvbGVFcnJvcihgRmlsZSAke2ZpbGVQYXRofSBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGV4dGVuc2lvbjogJHtmaWxlRXh0ZW5zaW9ufWApO1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoKTtcblxuICAgICAgY29uc3QgeyBuYW1lIH0gPSBwYXRoLnBhcnNlKGZpbGVQYXRoKTtcblxuICAgICAgY29uc3QgZmlsZURhdGEgPSB7IG5hbWUsIGNvbnRlbnQ6IGNvbnRlbnQudG9TdHJpbmcoJ2Jhc2U2NCcpIH07XG5cbiAgICAgIGNvbnN0IGNvbXByZXNzZWRDb250ZW50ID0gemxpYi5nemlwU3luYyhCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeShbZmlsZURhdGFdKSkpO1xuXG4gICAgICByZXF1ZXN0LmRhdGEgPSBuZXcgVWludDhBcnJheShjb21wcmVzc2VkQ29udGVudCk7XG5cbiAgICAgIHJldHVybiAxO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlRXJyb3IoYEVycm9yIHByb2Nlc3NpbmcgZmlsZTogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGFzeW5jIHByb2Nlc3NEaXJlY3RvcnkoZm9sZGVyUGF0aDogc3RyaW5nLCBmaWxlRXh0ZW5zaW9uOiBzdHJpbmcsIHJlcXVlc3Q6IFVwbG9hZEJsb2JSZXF1ZXN0KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBmaWxlcyA9IGF3YWl0IHJlYWRkaXIoZm9sZGVyUGF0aCwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pO1xuICAgIGNvbnN0IGZpbGVEYXRhTGlzdDogeyBuYW1lOiBzdHJpbmc7IGNvbnRlbnQ6IHN0cmluZyB9W10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgZGlyZW50IG9mIGZpbGVzKSB7XG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbihmb2xkZXJQYXRoLCBkaXJlbnQubmFtZSk7XG5cbiAgICAgIGlmIChkaXJlbnQuaXNGaWxlKCkgJiYgZGlyZW50Lm5hbWUuZW5kc1dpdGgoZmlsZUV4dGVuc2lvbikpIHtcbiAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBwYXRoLnBhcnNlKGZpbGVQYXRoKTtcbiAgICAgICAgZmlsZURhdGFMaXN0LnB1c2goeyBuYW1lLCBjb250ZW50OiBjb250ZW50LnRvU3RyaW5nKCdiYXNlNjQnKSB9KTtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZW50LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgYXdhaXQgdGhpcy50cmF2ZXJzZShmaWxlUGF0aCwgZmlsZUV4dGVuc2lvbiwgcmVxdWVzdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgY29tcHJlc3NlZENvbnRlbnQgPSB6bGliLmd6aXBTeW5jKEJ1ZmZlci5mcm9tKEpTT04uc3RyaW5naWZ5KGZpbGVEYXRhTGlzdCkpKTtcblxuICAgIHJlcXVlc3QuZGF0YSA9IG5ldyBVaW50OEFycmF5KGNvbXByZXNzZWRDb250ZW50KTtcblxuICAgIHJldHVybiBmaWxlRGF0YUxpc3QubGVuZ3RoO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgZ2V0RHdhcmZQYXRoKGRzeW1QYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGR3YXJmUGF0aDogc3RyaW5nID0gJ0NvbnRlbnRzL1Jlc291cmNlcy9EV0FSRic7XG4gICAgY29uc3QgdGFyZ2V0UGF0aDogc3RyaW5nID0gcGF0aC5qb2luKGRzeW1QYXRoLCBkd2FyZlBhdGgpO1xuICAgIGNvbnN0IGZpbGVzID0gZnMucmVhZGRpclN5bmModGFyZ2V0UGF0aCk7XG4gICAgaWYgKGZpbGVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIHBhdGguam9pbihkc3ltUGF0aCwgZHdhcmZQYXRoLCBmaWxlc1swXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGVFcnJvcihgRXhwZWN0ZWQgZXhhY3RseSBvbmUgZmlsZSBpbiB0aGUgZGlyZWN0b3J5LCBidXQgZm91bmQ6ICR7ZmlsZXMubGVuZ3RofWApO1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxufVxuIl19