@tricoteuses/assemblee 1.1.12 → 1.2.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 (69) hide show
  1. package/README.md +5 -5
  2. package/lib/bugs/agenda-00011.js +4 -5
  3. package/lib/bugs/agenda-00011.mjs +1 -2
  4. package/lib/bugs.js +3 -1
  5. package/lib/cleaners/actes_legislatifs.js +3 -1
  6. package/lib/cleaners/acteurs.js +3 -1
  7. package/lib/cleaners/amendements.js +3 -1
  8. package/lib/cleaners/documents.js +3 -1
  9. package/lib/cleaners/dossiers_legislatifs.js +3 -1
  10. package/lib/cleaners/reunions.js +2 -1
  11. package/lib/cleaners/scrutins.js +3 -1
  12. package/lib/cleaners/xml.js +3 -1
  13. package/lib/dates.js +1 -1
  14. package/lib/dossiers_legislatifs.d.ts +2 -1
  15. package/lib/dossiers_legislatifs.js +45 -2
  16. package/lib/dossiers_legislatifs.mjs +7 -1
  17. package/lib/file_systems.js +4 -1
  18. package/lib/index.d.ts +2 -2
  19. package/lib/index.js +13 -1
  20. package/lib/index.mjs +3 -3
  21. package/lib/inserters.js +3 -1
  22. package/lib/loaders.js +4 -1
  23. package/lib/parsers/documents.js +3 -1
  24. package/lib/parsers/recherche_amendements.js +4 -5
  25. package/lib/parsers/recherche_amendements.mjs +1 -2
  26. package/lib/raw_types/acteurs_et_organes.js +2 -1
  27. package/lib/raw_types/agendas.js +2 -1
  28. package/lib/raw_types/amendements.d.ts +1 -1
  29. package/lib/raw_types/amendements.js +3 -2
  30. package/lib/raw_types/amendements.mjs +2 -2
  31. package/lib/raw_types/debats.js +2 -1
  32. package/lib/raw_types/dossiers_legislatifs.js +2 -1
  33. package/lib/raw_types/questions.js +2 -1
  34. package/lib/raw_types/scrutins.js +2 -1
  35. package/lib/scripts/bugs_helper.js +3 -1
  36. package/lib/scripts/clean_reorganized_data.js +4 -2
  37. package/lib/scripts/clean_reorganized_data.mjs +2 -2
  38. package/lib/scripts/diff_amendements.js +3 -1
  39. package/lib/scripts/document_dossiers_legislatifs.js +2 -1
  40. package/lib/scripts/merge_scrutins.js +4 -1
  41. package/lib/scripts/parse_textes_lois.js +3 -1
  42. package/lib/scripts/raw_types_from_amendements.js +3 -1
  43. package/lib/scripts/reorganize_data.js +4 -2
  44. package/lib/scripts/reorganize_data.mjs +2 -2
  45. package/lib/scripts/retrieve_deputes_photos.js +4 -3
  46. package/lib/scripts/retrieve_deputes_photos.mjs +1 -2
  47. package/lib/scripts/retrieve_documents.js +342 -521
  48. package/lib/scripts/retrieve_documents.mjs +180 -229
  49. package/lib/scripts/retrieve_open_data.js +4 -4
  50. package/lib/scripts/retrieve_open_data.mjs +2 -3
  51. package/lib/scripts/retrieve_pending_amendments.js +3 -1
  52. package/lib/scripts/retrieve_senateurs_photos.js +5 -4
  53. package/lib/scripts/retrieve_senateurs_photos.mjs +2 -3
  54. package/lib/scripts/retrieve_textes_lois.js +7 -4
  55. package/lib/scripts/retrieve_textes_lois.mjs +5 -2
  56. package/lib/scripts/validate_json.js +3 -1
  57. package/lib/types/acteurs_et_organes.js +2 -1
  58. package/lib/types/agendas.js +2 -1
  59. package/lib/types/amendements.d.ts +1 -1
  60. package/lib/types/amendements.js +3 -2
  61. package/lib/types/amendements.mjs +2 -2
  62. package/lib/types/debats.js +2 -1
  63. package/lib/types/dossiers_legislatifs.js +2 -1
  64. package/lib/types/questions.js +2 -1
  65. package/lib/types/scrutins.js +2 -1
  66. package/lib/urls.d.ts +8 -2
  67. package/lib/urls.js +153 -23
  68. package/lib/urls.mjs +97 -22
  69. package/package.json +3 -5
@@ -1,246 +1,197 @@
1
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
- function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
1
+ import assert from "assert";
2
+ import { execSync } from "child_process";
4
3
  import commandLineArgs from "command-line-args";
5
- import commandLineUsage from "command-line-usage";
6
- import * as git from "../../src/git.mjs";
4
+ import { createHash } from "crypto";
7
5
  import fs from "fs-extra";
8
- let fetch = require("node-fetch");
9
6
  import path from "path";
10
- import { load, getFiles } from "../file_systems.mjs";
11
- import { DocumentUrlFormat, urlFromDocument } from "../urls.mjs";
12
- function parseArgs(argv) {
13
- const optionsDefinitions = [{
14
- alias: "c",
15
- help: "commit documents",
16
- name: "commit",
17
- type: Boolean
18
- }, {
19
- help: "dry run",
20
- name: "dry-run",
21
- type: Boolean
22
- }, {
23
- help: "retry failed documents",
24
- name: "retry-failed",
25
- type: Boolean
26
- }, {
27
- help: "retry all documents",
28
- name: "retry",
29
- type: Boolean
30
- }, {
31
- alias: "l",
32
- defaultValue: "16",
33
- name: "legislature",
34
- type: String
35
- }, {
36
- alias: "r",
37
- help: "push commit to given remote",
38
- name: "remote",
39
- type: String
40
- }, {
41
- alias: "s",
42
- help: "don't log anything",
43
- name: "silent",
44
- type: Boolean
45
- }, {
46
- help: "textes dir",
47
- name: "textes",
48
- type: String
49
- }, {
50
- alias: "v",
51
- help: "verbose logs",
52
- name: "verbose",
53
- type: Boolean
54
- }, {
55
- defaultOption: true,
56
- help: "files or globs to documents",
57
- multiple: true,
58
- name: "data",
59
- type: String
60
- }];
61
- const sections = [{
62
- header: "Retrieve documents",
63
- content: "Retrieve documents"
64
- }, {
65
- header: "Options",
66
- optionList: optionsDefinitions
67
- }];
68
- const options = commandLineArgs(optionsDefinitions, {
69
- argv: argv
70
- });
71
- if ("help" in options) {
72
- const usage = commandLineUsage(sections);
73
- console.warn(usage);
74
- return null;
7
+ import { walkDocumentAndDivisions } from "../dossiers_legislatifs.mjs";
8
+ import * as git from "../git.mjs";
9
+ import { iterLoadAssembleeDocuments, pathFromDocumentUid } from "../loaders.mjs";
10
+ import { DocumentUrlFormat, iterDocumentOrDivisionUrls } from "../urls.mjs";
11
+ const optionsDefinitions = [{
12
+ alias: "c",
13
+ help: "commit documents",
14
+ name: "commit",
15
+ type: Boolean
16
+ }, {
17
+ alias: "f",
18
+ help: "retrieve all documents, even already retrieved ones",
19
+ name: "full",
20
+ type: Boolean
21
+ }, {
22
+ alias: "l",
23
+ defaultValue: "16",
24
+ help: 'legislatures to retrieve, "*" for all',
25
+ name: "legislature",
26
+ type: String
27
+ }, {
28
+ alias: "n",
29
+ help: "try to also retrieve documents that were previously not found",
30
+ name: "not-found",
31
+ type: Boolean
32
+ }, {
33
+ alias: "p",
34
+ help: "pull repositories before proceeding",
35
+ name: "pull",
36
+ type: Boolean
37
+ }, {
38
+ alias: "r",
39
+ help: "push commit to given remote",
40
+ multiple: true,
41
+ name: "remote",
42
+ type: String
43
+ }, {
44
+ alias: "s",
45
+ help: "don't log anything",
46
+ name: "silent",
47
+ type: Boolean
48
+ }, {
49
+ alias: "u",
50
+ help: "UID of first Assemblée's document or division to retrieve",
51
+ name: "uid",
52
+ type: String
53
+ }, {
54
+ alias: "v",
55
+ help: "verbose logs",
56
+ name: "verbose",
57
+ type: Boolean
58
+ }, {
59
+ defaultOption: true,
60
+ help: "directory containing Assemblée open data files",
61
+ name: "dataDir",
62
+ type: String
63
+ }];
64
+ const options = commandLineArgs(optionsDefinitions);
65
+ async function retrieveDocuments() {
66
+ assert(!options.commit || options.uid, 'Options "commit" & "uid" are incompatible');
67
+ const dataDir = options.dataDir;
68
+ const documentsDir = path.join(dataDir, "Documents");
69
+ if (options.pull) {
70
+ execSync(`git reset --hard origin/master`, {
71
+ cwd: documentsDir,
72
+ env: process.env,
73
+ encoding: "utf-8",
74
+ stdio: ["ignore", "ignore", "pipe"]
75
+ });
76
+ execSync(`git pull --rebase`, {
77
+ cwd: documentsDir,
78
+ env: process.env,
79
+ encoding: "utf-8",
80
+ stdio: ["ignore", "ignore", "pipe"]
81
+ });
75
82
  }
76
- return options;
77
- }
78
- class Retrieve {
79
- constructor(options) {
80
- _defineProperty(this, "options", void 0);
81
- this.options = options;
82
- }
83
- getDivisions(division) {
84
- let divisions = [division];
85
- if (division.divisions != undefined) {
86
- for (const d of division.divisions) divisions = divisions.concat(this.getDivisions(d));
87
- }
88
- return divisions;
89
- }
90
- getDivisionsOrDocument(document) {
91
- if (document.divisions != undefined) return [].concat(...document.divisions.map(d => this.getDivisions(d)));else return [document];
92
- }
93
- async commitAndPush(repositoryDir) {
94
- if (this.options.commit == undefined) return;
95
- git.commit(repositoryDir, "Nouvelle moisson");
96
- if (this.options.remote == undefined) return;
97
- git.run(repositoryDir, `push ${this.options.remote} HEAD:master`);
98
- }
99
- getUrls(divisionOrDocument, format) {
100
- const ext = format == "html" ? "raw" : "pdf";
101
- let urls = [`http://www.assemblee-nationale.fr/dyn/docs/${divisionOrDocument.uid}.${ext}`];
102
- if (format == "html") {
103
- urls.push(urlFromDocument(divisionOrDocument, DocumentUrlFormat.RawHtml));
104
- urls.push(urlFromDocument(divisionOrDocument, DocumentUrlFormat.Html));
105
- } else if (format == "pdf") {
106
- urls.push(urlFromDocument(divisionOrDocument, DocumentUrlFormat.Pdf));
107
- }
108
- return urls;
109
- }
110
- static sanityCheckFormat(page, format) {
111
- if (format == "pdf") {
112
- const length = Math.min(page.length, 4);
113
- const head = page.slice(0, length).toString();
114
- if (!head.startsWith("%PDF")) return [Buffer.from(""), `bad pdf ${encodeURIComponent(head)}...`];
115
- } else if (format == "html") {
116
- const length = Math.min(page.length, 50);
117
- const head = page.slice(0, length).toString();
118
- if (!head.includes("DOCTYPE") && !head.includes("<?xml")) {
119
- return [Buffer.from(""), `bad html ${encodeURIComponent(head.slice(0, 4))}...`];
120
- }
121
- }
122
- return [page, "OK"];
123
- }
124
- async needsDownload(filePath, uid) {
125
- if (fs.existsSync(filePath)) {
126
- const isNotEmpty = fs.statSync(filePath).size > 0;
127
- const retryFailed = ("retry-failed" in this.options);
128
- if (!retryFailed || isNotEmpty) {
129
- if (this.options.verbose) {
130
- if (isNotEmpty) {
131
- const urlPath = `${filePath}.url`;
132
- let url;
133
- if (fs.existsSync(urlPath)) url = fs.readFileSync(urlPath).toString();else url = "<unknown url>";
134
- console.log(`${uid}: Cached OK ${filePath} from ${url}`);
135
- } else {
136
- console.log(`${uid}: Cached FAIL ${filePath}`);
137
- }
138
- }
139
- return false;
140
- }
141
- }
142
- return true;
143
- }
144
- async get(url, filePath, format, uid) {
145
- if (this.options.verbose) console.log(`${uid}: fetch(${url})`);
146
- const response = await fetch(url);
147
- let page = await response.buffer();
148
- let status;
149
- if (!response.ok) {
150
- status = response.status;
151
- if (response.status !== 404) {
152
- if (this.options.verbose) {
153
- console.error(`Error while getting page "${url}" (uid: ${uid}):\n\nError:\n${JSON.stringify({
154
- code: response.status,
155
- message: response.statusText
156
- }, null, 2)}`);
157
- }
83
+ fs.ensureDirSync(documentsDir);
84
+ if (options.full && !options.uid) {
85
+ for (const filename of fs.readdirSync(documentsDir)) {
86
+ if (filename[0] === ".") {
87
+ continue;
158
88
  }
159
- fs.writeFileSync(filePath, "");
160
- } else {
161
- ;
162
- [page, status] = Retrieve.sanityCheckFormat(page, format);
163
- fs.writeFileSync(filePath, page);
89
+ fs.removeSync(path.join(documentsDir, filename));
164
90
  }
165
- return status;
166
91
  }
167
- static urlFromUid(uid) {
168
- const url = "https://git.en-root.org/tricoteuses/data.tricoteuses.fr/Dossiers_Legislatifs_XV/-/tree/master/documents";
169
- return `[${uid}](${url}/uid/${uid}.json)`;
170
- }
171
- async download(textesDir, divisionOrDocument, format) {
172
- const uid = divisionOrDocument.uid;
173
- const filePath = `${textesDir}/uid/${uid}.${format}`;
174
- if (!(await this.needsDownload(filePath, uid))) return 0;
175
- if (this.options.verbose) console.log(`${uid}: Checking ${filePath}`);
176
- let success = false;
177
- let info = "";
178
- let url;
179
- for (url of this.getUrls(divisionOrDocument, format)) {
180
- if ("dry-run" in this.options) {
181
- info += ` * ${url}\n`;
92
+ const firstUid = options.uid;
93
+ let skip = Boolean(firstUid);
94
+ for (const {
95
+ document
96
+ } of iterLoadAssembleeDocuments(dataDir, options.legislature)) {
97
+ for (const documentOrDivision of walkDocumentAndDivisions(document)) {
98
+ // Ignore documents from Sénat.
99
+ if (documentOrDivision.uid.substring(4, 6) === "SN") {
182
100
  continue;
183
- } else {
184
- info += ` * ${url} `;
185
101
  }
186
- const status = await this.get(url, filePath, format, uid);
187
- info += `${status}\n`;
188
- if (status == "OK") {
189
- success = true;
190
- break;
102
+ if (skip) {
103
+ if (documentOrDivision.uid === firstUid) {
104
+ skip = false;
105
+ } else {
106
+ continue;
107
+ }
191
108
  }
192
- }
193
- const urlPath = `${filePath}.url`;
194
- if (success) {
195
- fs.writeFileSync(urlPath, url);
196
- } else if (fs.existsSync(urlPath)) {
197
- fs.unlinkSync(urlPath);
198
- }
199
- if (info != "" && !this.options.silent) {
200
- console.log(`* ${Retrieve.urlFromUid(uid)}: Retrieving ${filePath}\n${info.slice(0, -1)}`);
201
- return 1;
202
- } else {
203
- return 0;
204
- }
205
- }
206
- async retrieveDocuments() {
207
- const gitDir = `${this.options.textes}/.git`;
208
- if (!fs.existsSync(gitDir)) {
209
- console.error(`${gitDir} is expected to exist but does not`);
210
- return 1;
211
- }
212
- const textesDir = path.join(this.options.textes, this.options.legislature);
213
- fs.ensureDirSync(`${textesDir}/uid`);
214
- for (const filename of getFiles(this.options.data)) {
215
- const document = load(filename);
216
- if (/^....SN/.test(document.uid) || /^DECL/.test(document.uid)) continue;
217
- for (const divisionOrDocument of this.getDivisionsOrDocument(document)) {
218
- if (/-COMPA$/.test(divisionOrDocument.uid)) continue;
219
- let status = 0;
220
- for (const format of ["html", "pdf"]) {
221
- status |= await this.download(textesDir, divisionOrDocument, format);
109
+ const documentDir = pathFromDocumentUid(documentsDir, documentOrDivision.uid);
110
+ fs.ensureDirSync(documentDir);
111
+ const filenameBySha256 = {};
112
+ const indexPath = path.join(documentDir, "index.json");
113
+ const index = fs.pathExistsSync(indexPath) ? fs.readJsonSync(indexPath) : {};
114
+ for (const {
115
+ format,
116
+ type,
117
+ url
118
+ } of iterDocumentOrDivisionUrls(documentOrDivision)) {
119
+ if (index[format] === undefined) {
120
+ index[format] = [];
121
+ }
122
+ let fileInfos = index[format].find(fileInfos => fileInfos.url === url);
123
+ if (fileInfos === undefined) {
124
+ fileInfos = {};
125
+ index[format].push(fileInfos);
126
+ }
127
+ fileInfos.url = url;
128
+ const filename = `${type}.${format === DocumentUrlFormat.Pdf ? "pdf" : "html"}`;
129
+ if (fileInfos.status === 200 && !options.full) {
130
+ filenameBySha256[fileInfos.sha256] = filename;
131
+ continue;
132
+ }
133
+ if (fileInfos.status === 404 && !options["not-found"]) {
134
+ continue;
222
135
  }
223
- if (status && !this.options.silent) console.log("---");
136
+ if (!options.silent) {
137
+ console.log(`Retrieving document or division ${documentOrDivision.uid} at ${url}…`);
138
+ }
139
+ const response = await fetch(url);
140
+ const filePath = path.join(documentDir, filename);
141
+ if (response.ok) {
142
+ const arrayBuffer = await response.arrayBuffer();
143
+ const buffer = Buffer.from(arrayBuffer);
144
+ if (format === DocumentUrlFormat.Pdf && !buffer.subarray(0, 4).toString().startsWith("%PDF")) {
145
+ // Instead of a PDF, the received data may be an HTML page with a message like
146
+ // "Document non encore publié".
147
+ if (!options.silent) {
148
+ console.warn(` PDF "${url}" not found.`);
149
+ }
150
+ fs.removeSync(filePath);
151
+ delete fileInfos.filename;
152
+ delete fileInfos.sha256;
153
+ } else {
154
+ const sha256 = createHash("sha256").update(buffer).digest("hex");
155
+ const existingFilename = filenameBySha256[sha256];
156
+ if (existingFilename === undefined) {
157
+ fs.createWriteStream(filePath).write(buffer);
158
+ fileInfos.filename = filename;
159
+ filenameBySha256[sha256] = filename;
160
+ } else {
161
+ fileInfos.filename = existingFilename;
162
+ }
163
+ fileInfos.sha256 = sha256;
164
+ }
165
+ } else {
166
+ if (response.status === 404) {
167
+ if (!options.silent) {
168
+ console.warn(` Page "${url}" not found.`);
169
+ }
170
+ } else {
171
+ console.error(` Error:\n${JSON.stringify({
172
+ code: response.status,
173
+ message: response.statusText
174
+ }, null, 2)}`);
175
+ }
176
+ fs.removeSync(filePath);
177
+ delete fileInfos.filename;
178
+ delete fileInfos.sha256;
179
+ }
180
+ fileInfos.status = response.status;
224
181
  }
182
+ fs.writeJsonSync(indexPath, index, {
183
+ encoding: "utf-8",
184
+ spaces: 2
185
+ });
225
186
  }
226
- if (!("dry-run" in this.options)) {
227
- await this.commitAndPush(textesDir);
228
- }
229
- return 0;
230
187
  }
188
+ if (options.commit) {
189
+ return git.commitAndPush(documentsDir, "Nouvelle moisson", options.remote);
190
+ }
191
+ return 0;
231
192
  }
232
- async function main(argv) {
233
- const options = parseArgs(argv);
234
- if (options === null) return 1;
235
- const retrieve = new Retrieve(options);
236
- return retrieve.retrieveDocuments();
237
- }
238
-
239
- /* istanbul ignore if */
240
- if (process.argv[1].endsWith("retrieve_documents.ts")) main(process.argv).then(exitCode => {
241
- process.exit(exitCode);
242
- }).catch(error => {
243
- console.error(error);
193
+ retrieveDocuments().then(exitCode => process.exit(exitCode)).catch(error => {
194
+ console.log(error);
244
195
  process.exit(1);
245
196
  });
246
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21tYW5kTGluZUFyZ3MiLCJjb21tYW5kTGluZVVzYWdlIiwiZ2l0IiwiZnMiLCJmZXRjaCIsInJlcXVpcmUiLCJwYXRoIiwibG9hZCIsImdldEZpbGVzIiwiRG9jdW1lbnRVcmxGb3JtYXQiLCJ1cmxGcm9tRG9jdW1lbnQiLCJwYXJzZUFyZ3MiLCJhcmd2Iiwib3B0aW9uc0RlZmluaXRpb25zIiwiYWxpYXMiLCJoZWxwIiwibmFtZSIsInR5cGUiLCJCb29sZWFuIiwiZGVmYXVsdFZhbHVlIiwiU3RyaW5nIiwiZGVmYXVsdE9wdGlvbiIsIm11bHRpcGxlIiwic2VjdGlvbnMiLCJoZWFkZXIiLCJjb250ZW50Iiwib3B0aW9uTGlzdCIsIm9wdGlvbnMiLCJ1c2FnZSIsImNvbnNvbGUiLCJ3YXJuIiwiUmV0cmlldmUiLCJjb25zdHJ1Y3RvciIsIl9kZWZpbmVQcm9wZXJ0eSIsImdldERpdmlzaW9ucyIsImRpdmlzaW9uIiwiZGl2aXNpb25zIiwidW5kZWZpbmVkIiwiZCIsImNvbmNhdCIsImdldERpdmlzaW9uc09yRG9jdW1lbnQiLCJkb2N1bWVudCIsIm1hcCIsImNvbW1pdEFuZFB1c2giLCJyZXBvc2l0b3J5RGlyIiwiY29tbWl0IiwicmVtb3RlIiwicnVuIiwiZ2V0VXJscyIsImRpdmlzaW9uT3JEb2N1bWVudCIsImZvcm1hdCIsImV4dCIsInVybHMiLCJ1aWQiLCJwdXNoIiwiUmF3SHRtbCIsIkh0bWwiLCJQZGYiLCJzYW5pdHlDaGVja0Zvcm1hdCIsInBhZ2UiLCJsZW5ndGgiLCJNYXRoIiwibWluIiwiaGVhZCIsInNsaWNlIiwidG9TdHJpbmciLCJzdGFydHNXaXRoIiwiQnVmZmVyIiwiZnJvbSIsImVuY29kZVVSSUNvbXBvbmVudCIsImluY2x1ZGVzIiwibmVlZHNEb3dubG9hZCIsImZpbGVQYXRoIiwiZXhpc3RzU3luYyIsImlzTm90RW1wdHkiLCJzdGF0U3luYyIsInNpemUiLCJyZXRyeUZhaWxlZCIsInZlcmJvc2UiLCJ1cmxQYXRoIiwidXJsIiwicmVhZEZpbGVTeW5jIiwibG9nIiwiZ2V0IiwicmVzcG9uc2UiLCJidWZmZXIiLCJzdGF0dXMiLCJvayIsImVycm9yIiwiSlNPTiIsInN0cmluZ2lmeSIsImNvZGUiLCJtZXNzYWdlIiwic3RhdHVzVGV4dCIsIndyaXRlRmlsZVN5bmMiLCJ1cmxGcm9tVWlkIiwiZG93bmxvYWQiLCJ0ZXh0ZXNEaXIiLCJzdWNjZXNzIiwiaW5mbyIsInVubGlua1N5bmMiLCJzaWxlbnQiLCJyZXRyaWV2ZURvY3VtZW50cyIsImdpdERpciIsInRleHRlcyIsImpvaW4iLCJsZWdpc2xhdHVyZSIsImVuc3VyZURpclN5bmMiLCJmaWxlbmFtZSIsImRhdGEiLCJ0ZXN0IiwibWFpbiIsInJldHJpZXZlIiwicHJvY2VzcyIsImVuZHNXaXRoIiwidGhlbiIsImV4aXRDb2RlIiwiZXhpdCIsImNhdGNoIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NjcmlwdHMvcmV0cmlldmVfZG9jdW1lbnRzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjb21tYW5kTGluZUFyZ3MgZnJvbSBcImNvbW1hbmQtbGluZS1hcmdzXCJcbmltcG9ydCBjb21tYW5kTGluZVVzYWdlIGZyb20gXCJjb21tYW5kLWxpbmUtdXNhZ2VcIlxuaW1wb3J0ICogYXMgZ2l0IGZyb20gXCIuLi8uLi9zcmMvZ2l0XCJcbmltcG9ydCBmcyBmcm9tIFwiZnMtZXh0cmFcIlxubGV0IGZldGNoID0gcmVxdWlyZShcIm5vZGUtZmV0Y2hcIilcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCJcblxuaW1wb3J0IHsgbG9hZCwgZ2V0RmlsZXMgfSBmcm9tIFwiLi4vZmlsZV9zeXN0ZW1zXCJcbmltcG9ydCB7IERvY3VtZW50VXJsRm9ybWF0LCB1cmxGcm9tRG9jdW1lbnQgfSBmcm9tIFwiLi4vdXJsc1wiXG5cbmZ1bmN0aW9uIHBhcnNlQXJncyhhcmd2OiBzdHJpbmdbXSk6IGFueSB7XG4gIGNvbnN0IG9wdGlvbnNEZWZpbml0aW9ucyA9IFtcbiAgICB7XG4gICAgICBhbGlhczogXCJjXCIsXG4gICAgICBoZWxwOiBcImNvbW1pdCBkb2N1bWVudHNcIixcbiAgICAgIG5hbWU6IFwiY29tbWl0XCIsXG4gICAgICB0eXBlOiBCb29sZWFuLFxuICAgIH0sXG4gICAge1xuICAgICAgaGVscDogXCJkcnkgcnVuXCIsXG4gICAgICBuYW1lOiBcImRyeS1ydW5cIixcbiAgICAgIHR5cGU6IEJvb2xlYW4sXG4gICAgfSxcbiAgICB7XG4gICAgICBoZWxwOiBcInJldHJ5IGZhaWxlZCBkb2N1bWVudHNcIixcbiAgICAgIG5hbWU6IFwicmV0cnktZmFpbGVkXCIsXG4gICAgICB0eXBlOiBCb29sZWFuLFxuICAgIH0sXG4gICAge1xuICAgICAgaGVscDogXCJyZXRyeSBhbGwgZG9jdW1lbnRzXCIsXG4gICAgICBuYW1lOiBcInJldHJ5XCIsXG4gICAgICB0eXBlOiBCb29sZWFuLFxuICAgIH0sXG4gICAge1xuICAgICAgYWxpYXM6IFwibFwiLFxuICAgICAgZGVmYXVsdFZhbHVlOiBcIjE2XCIsXG4gICAgICBuYW1lOiBcImxlZ2lzbGF0dXJlXCIsXG4gICAgICB0eXBlOiBTdHJpbmcsXG4gICAgfSxcbiAgICB7XG4gICAgICBhbGlhczogXCJyXCIsXG4gICAgICBoZWxwOiBcInB1c2ggY29tbWl0IHRvIGdpdmVuIHJlbW90ZVwiLFxuICAgICAgbmFtZTogXCJyZW1vdGVcIixcbiAgICAgIHR5cGU6IFN0cmluZyxcbiAgICB9LFxuICAgIHtcbiAgICAgIGFsaWFzOiBcInNcIixcbiAgICAgIGhlbHA6IFwiZG9uJ3QgbG9nIGFueXRoaW5nXCIsXG4gICAgICBuYW1lOiBcInNpbGVudFwiLFxuICAgICAgdHlwZTogQm9vbGVhbixcbiAgICB9LFxuICAgIHtcbiAgICAgIGhlbHA6IFwidGV4dGVzIGRpclwiLFxuICAgICAgbmFtZTogXCJ0ZXh0ZXNcIixcbiAgICAgIHR5cGU6IFN0cmluZyxcbiAgICB9LFxuICAgIHtcbiAgICAgIGFsaWFzOiBcInZcIixcbiAgICAgIGhlbHA6IFwidmVyYm9zZSBsb2dzXCIsXG4gICAgICBuYW1lOiBcInZlcmJvc2VcIixcbiAgICAgIHR5cGU6IEJvb2xlYW4sXG4gICAgfSxcbiAgICB7XG4gICAgICBkZWZhdWx0T3B0aW9uOiB0cnVlLFxuICAgICAgaGVscDogXCJmaWxlcyBvciBnbG9icyB0byBkb2N1bWVudHNcIixcbiAgICAgIG11bHRpcGxlOiB0cnVlLFxuICAgICAgbmFtZTogXCJkYXRhXCIsXG4gICAgICB0eXBlOiBTdHJpbmcsXG4gICAgfSxcbiAgXVxuICBjb25zdCBzZWN0aW9ucyA9IFtcbiAgICB7XG4gICAgICBoZWFkZXI6IFwiUmV0cmlldmUgZG9jdW1lbnRzXCIsXG4gICAgICBjb250ZW50OiBcIlJldHJpZXZlIGRvY3VtZW50c1wiLFxuICAgIH0sXG4gICAge1xuICAgICAgaGVhZGVyOiBcIk9wdGlvbnNcIixcbiAgICAgIG9wdGlvbkxpc3Q6IG9wdGlvbnNEZWZpbml0aW9ucyxcbiAgICB9LFxuICBdXG4gIGNvbnN0IG9wdGlvbnMgPSBjb21tYW5kTGluZUFyZ3Mob3B0aW9uc0RlZmluaXRpb25zLCB7XG4gICAgYXJndjogYXJndixcbiAgfSlcblxuICBpZiAoXCJoZWxwXCIgaW4gb3B0aW9ucykge1xuICAgIGNvbnN0IHVzYWdlID0gY29tbWFuZExpbmVVc2FnZShzZWN0aW9ucylcbiAgICBjb25zb2xlLndhcm4odXNhZ2UpXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuICByZXR1cm4gb3B0aW9uc1xufVxuXG5jbGFzcyBSZXRyaWV2ZSB7XG4gIG9wdGlvbnM6IGFueVxuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IGFueSkge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnNcbiAgfVxuXG4gIGdldERpdmlzaW9ucyhkaXZpc2lvbjogYW55KSB7XG4gICAgbGV0IGRpdmlzaW9ucyA9IFtkaXZpc2lvbl1cbiAgICBpZiAoZGl2aXNpb24uZGl2aXNpb25zICE9IHVuZGVmaW5lZCkge1xuICAgICAgZm9yIChjb25zdCBkIG9mIGRpdmlzaW9uLmRpdmlzaW9ucylcbiAgICAgICAgZGl2aXNpb25zID0gZGl2aXNpb25zLmNvbmNhdCh0aGlzLmdldERpdmlzaW9ucyhkKSlcbiAgICB9XG4gICAgcmV0dXJuIGRpdmlzaW9uc1xuICB9XG5cbiAgZ2V0RGl2aXNpb25zT3JEb2N1bWVudChkb2N1bWVudDogYW55KSB7XG4gICAgaWYgKGRvY3VtZW50LmRpdmlzaW9ucyAhPSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gW10uY29uY2F0KFxuICAgICAgICAuLi5kb2N1bWVudC5kaXZpc2lvbnMubWFwKChkOiBhbnkpID0+IHRoaXMuZ2V0RGl2aXNpb25zKGQpKSxcbiAgICAgIClcbiAgICBlbHNlIHJldHVybiBbZG9jdW1lbnRdXG4gIH1cblxuICBhc3luYyBjb21taXRBbmRQdXNoKHJlcG9zaXRvcnlEaXI6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuY29tbWl0ID09IHVuZGVmaW5lZCkgcmV0dXJuXG4gICAgZ2l0LmNvbW1pdChyZXBvc2l0b3J5RGlyLCBcIk5vdXZlbGxlIG1vaXNzb25cIilcblxuICAgIGlmICh0aGlzLm9wdGlvbnMucmVtb3RlID09IHVuZGVmaW5lZCkgcmV0dXJuXG4gICAgZ2l0LnJ1bihyZXBvc2l0b3J5RGlyLCBgcHVzaCAke3RoaXMub3B0aW9ucy5yZW1vdGV9IEhFQUQ6bWFzdGVyYClcbiAgfVxuXG4gIGdldFVybHMoZGl2aXNpb25PckRvY3VtZW50OiBhbnksIGZvcm1hdDogc3RyaW5nKSB7XG4gICAgY29uc3QgZXh0ID0gZm9ybWF0ID09IFwiaHRtbFwiID8gXCJyYXdcIiA6IFwicGRmXCJcbiAgICBsZXQgdXJsczogYW55ID0gW1xuICAgICAgYGh0dHA6Ly93d3cuYXNzZW1ibGVlLW5hdGlvbmFsZS5mci9keW4vZG9jcy8ke2RpdmlzaW9uT3JEb2N1bWVudC51aWR9LiR7ZXh0fWAsXG4gICAgXVxuICAgIGlmIChmb3JtYXQgPT0gXCJodG1sXCIpIHtcbiAgICAgIHVybHMucHVzaCh1cmxGcm9tRG9jdW1lbnQoZGl2aXNpb25PckRvY3VtZW50LCBEb2N1bWVudFVybEZvcm1hdC5SYXdIdG1sKSlcbiAgICAgIHVybHMucHVzaCh1cmxGcm9tRG9jdW1lbnQoZGl2aXNpb25PckRvY3VtZW50LCBEb2N1bWVudFVybEZvcm1hdC5IdG1sKSlcbiAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PSBcInBkZlwiKSB7XG4gICAgICB1cmxzLnB1c2godXJsRnJvbURvY3VtZW50KGRpdmlzaW9uT3JEb2N1bWVudCwgRG9jdW1lbnRVcmxGb3JtYXQuUGRmKSlcbiAgICB9XG4gICAgcmV0dXJuIHVybHNcbiAgfVxuXG4gIHN0YXRpYyBzYW5pdHlDaGVja0Zvcm1hdChwYWdlOiBCdWZmZXIsIGZvcm1hdDogc3RyaW5nKTogW0J1ZmZlciwgc3RyaW5nXSB7XG4gICAgaWYgKGZvcm1hdCA9PSBcInBkZlwiKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSBNYXRoLm1pbihwYWdlLmxlbmd0aCwgNClcbiAgICAgIGNvbnN0IGhlYWQgPSBwYWdlLnNsaWNlKDAsIGxlbmd0aCkudG9TdHJpbmcoKVxuICAgICAgaWYgKCFoZWFkLnN0YXJ0c1dpdGgoXCIlUERGXCIpKVxuICAgICAgICByZXR1cm4gW0J1ZmZlci5mcm9tKFwiXCIpLCBgYmFkIHBkZiAke2VuY29kZVVSSUNvbXBvbmVudChoZWFkKX0uLi5gXVxuICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09IFwiaHRtbFwiKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSBNYXRoLm1pbihwYWdlLmxlbmd0aCwgNTApXG4gICAgICBjb25zdCBoZWFkID0gcGFnZS5zbGljZSgwLCBsZW5ndGgpLnRvU3RyaW5nKClcbiAgICAgIGlmICghaGVhZC5pbmNsdWRlcyhcIkRPQ1RZUEVcIikgJiYgIWhlYWQuaW5jbHVkZXMoXCI8P3htbFwiKSkge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIEJ1ZmZlci5mcm9tKFwiXCIpLFxuICAgICAgICAgIGBiYWQgaHRtbCAke2VuY29kZVVSSUNvbXBvbmVudChoZWFkLnNsaWNlKDAsIDQpKX0uLi5gLFxuICAgICAgICBdXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBbcGFnZSwgXCJPS1wiXVxuICB9XG5cbiAgYXN5bmMgbmVlZHNEb3dubG9hZChmaWxlUGF0aDogc3RyaW5nLCB1aWQ6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmIChmcy5leGlzdHNTeW5jKGZpbGVQYXRoKSkge1xuICAgICAgY29uc3QgaXNOb3RFbXB0eSA9IGZzLnN0YXRTeW5jKGZpbGVQYXRoKS5zaXplID4gMFxuICAgICAgY29uc3QgcmV0cnlGYWlsZWQgPSBcInJldHJ5LWZhaWxlZFwiIGluIHRoaXMub3B0aW9uc1xuICAgICAgaWYgKCFyZXRyeUZhaWxlZCB8fCBpc05vdEVtcHR5KSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgIGlmIChpc05vdEVtcHR5KSB7XG4gICAgICAgICAgICBjb25zdCB1cmxQYXRoID0gYCR7ZmlsZVBhdGh9LnVybGBcbiAgICAgICAgICAgIGxldCB1cmxcbiAgICAgICAgICAgIGlmIChmcy5leGlzdHNTeW5jKHVybFBhdGgpKVxuICAgICAgICAgICAgICB1cmwgPSBmcy5yZWFkRmlsZVN5bmModXJsUGF0aCkudG9TdHJpbmcoKVxuICAgICAgICAgICAgZWxzZSB1cmwgPSBcIjx1bmtub3duIHVybD5cIlxuICAgICAgICAgICAgY29uc29sZS5sb2coYCR7dWlkfTogQ2FjaGVkIE9LICR7ZmlsZVBhdGh9IGZyb20gJHt1cmx9YClcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYCR7dWlkfTogQ2FjaGVkIEZBSUwgJHtmaWxlUGF0aH1gKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGFzeW5jIGdldChcbiAgICB1cmw6IHN0cmluZyxcbiAgICBmaWxlUGF0aDogc3RyaW5nLFxuICAgIGZvcm1hdDogc3RyaW5nLFxuICAgIHVpZDogc3RyaW5nLFxuICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGlmICh0aGlzLm9wdGlvbnMudmVyYm9zZSkgY29uc29sZS5sb2coYCR7dWlkfTogZmV0Y2goJHt1cmx9KWApXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpXG4gICAgbGV0IHBhZ2U6IGFueSA9IGF3YWl0IHJlc3BvbnNlLmJ1ZmZlcigpXG4gICAgbGV0IHN0YXR1c1xuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1c1xuICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1cyAhPT0gNDA0KSB7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICBgRXJyb3Igd2hpbGUgZ2V0dGluZyBwYWdlIFwiJHt1cmx9XCIgKHVpZDogJHt1aWR9KTpcXG5cXG5FcnJvcjpcXG4ke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgICB7IGNvZGU6IHJlc3BvbnNlLnN0YXR1cywgbWVzc2FnZTogcmVzcG9uc2Uuc3RhdHVzVGV4dCB9LFxuICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAyLFxuICAgICAgICAgICAgKX1gLFxuICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZnMud3JpdGVGaWxlU3luYyhmaWxlUGF0aCwgXCJcIilcbiAgICB9IGVsc2Uge1xuICAgICAgO1twYWdlLCBzdGF0dXNdID0gUmV0cmlldmUuc2FuaXR5Q2hlY2tGb3JtYXQocGFnZSwgZm9ybWF0KVxuICAgICAgZnMud3JpdGVGaWxlU3luYyhmaWxlUGF0aCwgcGFnZSlcbiAgICB9XG4gICAgcmV0dXJuIHN0YXR1c1xuICB9XG5cbiAgc3RhdGljIHVybEZyb21VaWQodWlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHVybCA9XG4gICAgICBcImh0dHBzOi8vZ2l0LmVuLXJvb3Qub3JnL3RyaWNvdGV1c2VzL2RhdGEudHJpY290ZXVzZXMuZnIvRG9zc2llcnNfTGVnaXNsYXRpZnNfWFYvLS90cmVlL21hc3Rlci9kb2N1bWVudHNcIlxuICAgIHJldHVybiBgWyR7dWlkfV0oJHt1cmx9L3VpZC8ke3VpZH0uanNvbilgXG4gIH1cblxuICBhc3luYyBkb3dubG9hZChcbiAgICB0ZXh0ZXNEaXI6IHN0cmluZyxcbiAgICBkaXZpc2lvbk9yRG9jdW1lbnQ6IGFueSxcbiAgICBmb3JtYXQ6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCB1aWQgPSBkaXZpc2lvbk9yRG9jdW1lbnQudWlkXG4gICAgY29uc3QgZmlsZVBhdGggPSBgJHt0ZXh0ZXNEaXJ9L3VpZC8ke3VpZH0uJHtmb3JtYXR9YFxuICAgIGlmICghKGF3YWl0IHRoaXMubmVlZHNEb3dubG9hZChmaWxlUGF0aCwgdWlkKSkpIHJldHVybiAwXG4gICAgaWYgKHRoaXMub3B0aW9ucy52ZXJib3NlKSBjb25zb2xlLmxvZyhgJHt1aWR9OiBDaGVja2luZyAke2ZpbGVQYXRofWApXG4gICAgbGV0IHN1Y2Nlc3MgPSBmYWxzZVxuICAgIGxldCBpbmZvID0gXCJcIlxuICAgIGxldCB1cmxcblxuICAgIGZvciAodXJsIG9mIHRoaXMuZ2V0VXJscyhkaXZpc2lvbk9yRG9jdW1lbnQsIGZvcm1hdCkpIHtcbiAgICAgIGlmIChcImRyeS1ydW5cIiBpbiB0aGlzLm9wdGlvbnMpIHtcbiAgICAgICAgaW5mbyArPSBgICAqICR7dXJsfVxcbmBcbiAgICAgICAgY29udGludWVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZm8gKz0gYCAgKiAke3VybH0gYFxuICAgICAgfVxuXG4gICAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCB0aGlzLmdldCh1cmwsIGZpbGVQYXRoLCBmb3JtYXQsIHVpZClcblxuICAgICAgaW5mbyArPSBgJHtzdGF0dXN9XFxuYFxuICAgICAgaWYgKHN0YXR1cyA9PSBcIk9LXCIpIHtcbiAgICAgICAgc3VjY2VzcyA9IHRydWVcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgdXJsUGF0aCA9IGAke2ZpbGVQYXRofS51cmxgXG4gICAgaWYgKHN1Y2Nlc3MpIHtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmModXJsUGF0aCwgdXJsKVxuICAgIH0gZWxzZSBpZiAoZnMuZXhpc3RzU3luYyh1cmxQYXRoKSkge1xuICAgICAgZnMudW5saW5rU3luYyh1cmxQYXRoKVxuICAgIH1cbiAgICBpZiAoaW5mbyAhPSBcIlwiICYmICF0aGlzLm9wdGlvbnMuc2lsZW50KSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgYCogJHtSZXRyaWV2ZS51cmxGcm9tVWlkKHVpZCl9OiBSZXRyaWV2aW5nICR7ZmlsZVBhdGh9XFxuJHtpbmZvLnNsaWNlKFxuICAgICAgICAgIDAsXG4gICAgICAgICAgLTEsXG4gICAgICAgICl9YCxcbiAgICAgIClcbiAgICAgIHJldHVybiAxXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAwXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgcmV0cmlldmVEb2N1bWVudHMoKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBnaXREaXIgPSBgJHt0aGlzLm9wdGlvbnMudGV4dGVzfS8uZ2l0YFxuICAgIGlmICghZnMuZXhpc3RzU3luYyhnaXREaXIpKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGAke2dpdERpcn0gaXMgZXhwZWN0ZWQgdG8gZXhpc3QgYnV0IGRvZXMgbm90YClcbiAgICAgIHJldHVybiAxXG4gICAgfVxuXG4gICAgY29uc3QgdGV4dGVzRGlyID0gcGF0aC5qb2luKHRoaXMub3B0aW9ucy50ZXh0ZXMsIHRoaXMub3B0aW9ucy5sZWdpc2xhdHVyZSlcbiAgICBmcy5lbnN1cmVEaXJTeW5jKGAke3RleHRlc0Rpcn0vdWlkYClcblxuICAgIGZvciAoY29uc3QgZmlsZW5hbWUgb2YgZ2V0RmlsZXModGhpcy5vcHRpb25zLmRhdGEpKSB7XG4gICAgICBjb25zdCBkb2N1bWVudCA9IGxvYWQoZmlsZW5hbWUpXG4gICAgICBpZiAoL14uLi4uU04vLnRlc3QoZG9jdW1lbnQudWlkKSB8fCAvXkRFQ0wvLnRlc3QoZG9jdW1lbnQudWlkKSkgY29udGludWVcbiAgICAgIGZvciAoY29uc3QgZGl2aXNpb25PckRvY3VtZW50IG9mIHRoaXMuZ2V0RGl2aXNpb25zT3JEb2N1bWVudChkb2N1bWVudCkpIHtcbiAgICAgICAgaWYgKC8tQ09NUEEkLy50ZXN0KGRpdmlzaW9uT3JEb2N1bWVudC51aWQpKSBjb250aW51ZVxuICAgICAgICBsZXQgc3RhdHVzID0gMFxuICAgICAgICBmb3IgKGNvbnN0IGZvcm1hdCBvZiBbXCJodG1sXCIsIFwicGRmXCJdKSB7XG4gICAgICAgICAgc3RhdHVzIHw9IGF3YWl0IHRoaXMuZG93bmxvYWQodGV4dGVzRGlyLCBkaXZpc2lvbk9yRG9jdW1lbnQsIGZvcm1hdClcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhdHVzICYmICF0aGlzLm9wdGlvbnMuc2lsZW50KSBjb25zb2xlLmxvZyhcIi0tLVwiKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghKFwiZHJ5LXJ1blwiIGluIHRoaXMub3B0aW9ucykpIHtcbiAgICAgIGF3YWl0IHRoaXMuY29tbWl0QW5kUHVzaCh0ZXh0ZXNEaXIpXG4gICAgfVxuXG4gICAgcmV0dXJuIDBcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBtYWluKGFyZ3Y6IGFueSk6IFByb21pc2U8bnVtYmVyPiB7XG4gIGNvbnN0IG9wdGlvbnMgPSBwYXJzZUFyZ3MoYXJndilcbiAgaWYgKG9wdGlvbnMgPT09IG51bGwpIHJldHVybiAxXG4gIGNvbnN0IHJldHJpZXZlID0gbmV3IFJldHJpZXZlKG9wdGlvbnMpXG4gIHJldHVybiByZXRyaWV2ZS5yZXRyaWV2ZURvY3VtZW50cygpXG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuaWYgKHByb2Nlc3MuYXJndlsxXS5lbmRzV2l0aChcInJldHJpZXZlX2RvY3VtZW50cy50c1wiKSlcbiAgbWFpbihwcm9jZXNzLmFyZ3YpXG4gICAgLnRoZW4oKGV4aXRDb2RlKSA9PiB7XG4gICAgICBwcm9jZXNzLmV4aXQoZXhpdENvZGUpXG4gICAgfSlcbiAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKVxuICAgICAgcHJvY2Vzcy5leGl0KDEpXG4gICAgfSlcbiJdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsT0FBT0EsZUFBZSxNQUFNLG1CQUFtQjtBQUMvQyxPQUFPQyxnQkFBZ0IsTUFBTSxvQkFBb0I7QUFBQSxPQUMxQyxLQUFLQyxHQUFHO0FBQ2YsT0FBT0MsRUFBRSxNQUFNLFVBQVU7QUFDekIsSUFBSUMsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBWSxDQUFDO0FBQ2pDLE9BQU9DLElBQUksTUFBTSxNQUFNO0FBQUEsU0FFZEMsSUFBSSxFQUFFQyxRQUFRO0FBQUEsU0FDZEMsaUJBQWlCLEVBQUVDLGVBQWU7QUFFM0MsU0FBU0MsU0FBU0EsQ0FBQ0MsSUFBYyxFQUFPO0VBQ3RDLE1BQU1DLGtCQUFrQixHQUFHLENBQ3pCO0lBQ0VDLEtBQUssRUFBRSxHQUFHO0lBQ1ZDLElBQUksRUFBRSxrQkFBa0I7SUFDeEJDLElBQUksRUFBRSxRQUFRO0lBQ2RDLElBQUksRUFBRUM7RUFDUixDQUFDLEVBQ0Q7SUFDRUgsSUFBSSxFQUFFLFNBQVM7SUFDZkMsSUFBSSxFQUFFLFNBQVM7SUFDZkMsSUFBSSxFQUFFQztFQUNSLENBQUMsRUFDRDtJQUNFSCxJQUFJLEVBQUUsd0JBQXdCO0lBQzlCQyxJQUFJLEVBQUUsY0FBYztJQUNwQkMsSUFBSSxFQUFFQztFQUNSLENBQUMsRUFDRDtJQUNFSCxJQUFJLEVBQUUscUJBQXFCO0lBQzNCQyxJQUFJLEVBQUUsT0FBTztJQUNiQyxJQUFJLEVBQUVDO0VBQ1IsQ0FBQyxFQUNEO0lBQ0VKLEtBQUssRUFBRSxHQUFHO0lBQ1ZLLFlBQVksRUFBRSxJQUFJO0lBQ2xCSCxJQUFJLEVBQUUsYUFBYTtJQUNuQkMsSUFBSSxFQUFFRztFQUNSLENBQUMsRUFDRDtJQUNFTixLQUFLLEVBQUUsR0FBRztJQUNWQyxJQUFJLEVBQUUsNkJBQTZCO0lBQ25DQyxJQUFJLEVBQUUsUUFBUTtJQUNkQyxJQUFJLEVBQUVHO0VBQ1IsQ0FBQyxFQUNEO0lBQ0VOLEtBQUssRUFBRSxHQUFHO0lBQ1ZDLElBQUksRUFBRSxvQkFBb0I7SUFDMUJDLElBQUksRUFBRSxRQUFRO0lBQ2RDLElBQUksRUFBRUM7RUFDUixDQUFDLEVBQ0Q7SUFDRUgsSUFBSSxFQUFFLFlBQVk7SUFDbEJDLElBQUksRUFBRSxRQUFRO0lBQ2RDLElBQUksRUFBRUc7RUFDUixDQUFDLEVBQ0Q7SUFDRU4sS0FBSyxFQUFFLEdBQUc7SUFDVkMsSUFBSSxFQUFFLGNBQWM7SUFDcEJDLElBQUksRUFBRSxTQUFTO0lBQ2ZDLElBQUksRUFBRUM7RUFDUixDQUFDLEVBQ0Q7SUFDRUcsYUFBYSxFQUFFLElBQUk7SUFDbkJOLElBQUksRUFBRSw2QkFBNkI7SUFDbkNPLFFBQVEsRUFBRSxJQUFJO0lBQ2ROLElBQUksRUFBRSxNQUFNO0lBQ1pDLElBQUksRUFBRUc7RUFDUixDQUFDLENBQ0Y7RUFDRCxNQUFNRyxRQUFRLEdBQUcsQ0FDZjtJQUNFQyxNQUFNLEVBQUUsb0JBQW9CO0lBQzVCQyxPQUFPLEVBQUU7RUFDWCxDQUFDLEVBQ0Q7SUFDRUQsTUFBTSxFQUFFLFNBQVM7SUFDakJFLFVBQVUsRUFBRWI7RUFDZCxDQUFDLENBQ0Y7RUFDRCxNQUFNYyxPQUFPLEdBQUczQixlQUFlLENBQUNhLGtCQUFrQixFQUFFO0lBQ2xERCxJQUFJLEVBQUVBO0VBQ1IsQ0FBQyxDQUFDO0VBRUYsSUFBSSxNQUFNLElBQUllLE9BQU8sRUFBRTtJQUNyQixNQUFNQyxLQUFLLEdBQUczQixnQkFBZ0IsQ0FBQ3NCLFFBQVEsQ0FBQztJQUN4Q00sT0FBTyxDQUFDQyxJQUFJLENBQUNGLEtBQUssQ0FBQztJQUNuQixPQUFPLElBQUk7RUFDYjtFQUNBLE9BQU9ELE9BQU87QUFDaEI7QUFFQSxNQUFNSSxRQUFRLENBQUM7RUFHYkMsV0FBV0EsQ0FBQ0wsT0FBWSxFQUFFO0lBQUFNLGVBQUE7SUFDeEIsSUFBSSxDQUFDTixPQUFPLEdBQUdBLE9BQU87RUFDeEI7RUFFQU8sWUFBWUEsQ0FBQ0MsUUFBYSxFQUFFO0lBQzFCLElBQUlDLFNBQVMsR0FBRyxDQUFDRCxRQUFRLENBQUM7SUFDMUIsSUFBSUEsUUFBUSxDQUFDQyxTQUFTLElBQUlDLFNBQVMsRUFBRTtNQUNuQyxLQUFLLE1BQU1DLENBQUMsSUFBSUgsUUFBUSxDQUFDQyxTQUFTLEVBQ2hDQSxTQUFTLEdBQUdBLFNBQVMsQ0FBQ0csTUFBTSxDQUFDLElBQUksQ0FBQ0wsWUFBWSxDQUFDSSxDQUFDLENBQUMsQ0FBQztJQUN0RDtJQUNBLE9BQU9GLFNBQVM7RUFDbEI7RUFFQUksc0JBQXNCQSxDQUFDQyxRQUFhLEVBQUU7SUFDcEMsSUFBSUEsUUFBUSxDQUFDTCxTQUFTLElBQUlDLFNBQVMsRUFDakMsT0FBTyxFQUFFLENBQUNFLE1BQU0sQ0FDZCxHQUFHRSxRQUFRLENBQUNMLFNBQVMsQ0FBQ00sR0FBRyxDQUFFSixDQUFNLElBQUssSUFBSSxDQUFDSixZQUFZLENBQUNJLENBQUMsQ0FBQyxDQUM1RCxDQUFDLE1BQ0UsT0FBTyxDQUFDRyxRQUFRLENBQUM7RUFDeEI7RUFFQSxNQUFNRSxhQUFhQSxDQUFDQyxhQUFxQixFQUFpQjtJQUN4RCxJQUFJLElBQUksQ0FBQ2pCLE9BQU8sQ0FBQ2tCLE1BQU0sSUFBSVIsU0FBUyxFQUFFO0lBQ3RDbkMsR0FBRyxDQUFDMkMsTUFBTSxDQUFDRCxhQUFhLEVBQUUsa0JBQWtCLENBQUM7SUFFN0MsSUFBSSxJQUFJLENBQUNqQixPQUFPLENBQUNtQixNQUFNLElBQUlULFNBQVMsRUFBRTtJQUN0Q25DLEdBQUcsQ0FBQzZDLEdBQUcsQ0FBQ0gsYUFBYSxFQUFHLFFBQU8sSUFBSSxDQUFDakIsT0FBTyxDQUFDbUIsTUFBTyxjQUFhLENBQUM7RUFDbkU7RUFFQUUsT0FBT0EsQ0FBQ0Msa0JBQXVCLEVBQUVDLE1BQWMsRUFBRTtJQUMvQyxNQUFNQyxHQUFHLEdBQUdELE1BQU0sSUFBSSxNQUFNLEdBQUcsS0FBSyxHQUFHLEtBQUs7SUFDNUMsSUFBSUUsSUFBUyxHQUFHLENBQ2IsOENBQTZDSCxrQkFBa0IsQ0FBQ0ksR0FBSSxJQUFHRixHQUFJLEVBQUMsQ0FDOUU7SUFDRCxJQUFJRCxNQUFNLElBQUksTUFBTSxFQUFFO01BQ3BCRSxJQUFJLENBQUNFLElBQUksQ0FBQzVDLGVBQWUsQ0FBQ3VDLGtCQUFrQixFQUFFeEMsaUJBQWlCLENBQUM4QyxPQUFPLENBQUMsQ0FBQztNQUN6RUgsSUFBSSxDQUFDRSxJQUFJLENBQUM1QyxlQUFlLENBQUN1QyxrQkFBa0IsRUFBRXhDLGlCQUFpQixDQUFDK0MsSUFBSSxDQUFDLENBQUM7SUFDeEUsQ0FBQyxNQUFNLElBQUlOLE1BQU0sSUFBSSxLQUFLLEVBQUU7TUFDMUJFLElBQUksQ0FBQ0UsSUFBSSxDQUFDNUMsZUFBZSxDQUFDdUMsa0JBQWtCLEVBQUV4QyxpQkFBaUIsQ0FBQ2dELEdBQUcsQ0FBQyxDQUFDO0lBQ3ZFO0lBQ0EsT0FBT0wsSUFBSTtFQUNiO0VBRUEsT0FBT00saUJBQWlCQSxDQUFDQyxJQUFZLEVBQUVULE1BQWMsRUFBb0I7SUFDdkUsSUFBSUEsTUFBTSxJQUFJLEtBQUssRUFBRTtNQUNuQixNQUFNVSxNQUFNLEdBQUdDLElBQUksQ0FBQ0MsR0FBRyxDQUFDSCxJQUFJLENBQUNDLE1BQU0sRUFBRSxDQUFDLENBQUM7TUFDdkMsTUFBTUcsSUFBSSxHQUFHSixJQUFJLENBQUNLLEtBQUssQ0FBQyxDQUFDLEVBQUVKLE1BQU0sQ0FBQyxDQUFDSyxRQUFRLENBQUMsQ0FBQztNQUM3QyxJQUFJLENBQUNGLElBQUksQ0FBQ0csVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUMxQixPQUFPLENBQUNDLE1BQU0sQ0FBQ0MsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFHLFdBQVVDLGtCQUFrQixDQUFDTixJQUFJLENBQUUsS0FBSSxDQUFDO0lBQ3RFLENBQUMsTUFBTSxJQUFJYixNQUFNLElBQUksTUFBTSxFQUFFO01BQzNCLE1BQU1VLE1BQU0sR0FBR0MsSUFBSSxDQUFDQyxHQUFHLENBQUNILElBQUksQ0FBQ0MsTUFBTSxFQUFFLEVBQUUsQ0FBQztNQUN4QyxNQUFNRyxJQUFJLEdBQUdKLElBQUksQ0FBQ0ssS0FBSyxDQUFDLENBQUMsRUFBRUosTUFBTSxDQUFDLENBQUNLLFFBQVEsQ0FBQyxDQUFDO01BQzdDLElBQUksQ0FBQ0YsSUFBSSxDQUFDTyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQ1AsSUFBSSxDQUFDTyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDeEQsT0FBTyxDQUNMSCxNQUFNLENBQUNDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFDZCxZQUFXQyxrQkFBa0IsQ0FBQ04sSUFBSSxDQUFDQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFFLEtBQUksQ0FDdEQ7TUFDSDtJQUNGO0lBQ0EsT0FBTyxDQUFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDO0VBQ3JCO0VBRUEsTUFBTVksYUFBYUEsQ0FBQ0MsUUFBZ0IsRUFBRW5CLEdBQVcsRUFBb0I7SUFDbkUsSUFBSWxELEVBQUUsQ0FBQ3NFLFVBQVUsQ0FBQ0QsUUFBUSxDQUFDLEVBQUU7TUFDM0IsTUFBTUUsVUFBVSxHQUFHdkUsRUFBRSxDQUFDd0UsUUFBUSxDQUFDSCxRQUFRLENBQUMsQ0FBQ0ksSUFBSSxHQUFHLENBQUM7TUFDakQsTUFBTUMsV0FBVyxJQUFHLGNBQWMsSUFBSSxJQUFJLENBQUNsRCxPQUFPO01BQ2xELElBQUksQ0FBQ2tELFdBQVcsSUFBSUgsVUFBVSxFQUFFO1FBQzlCLElBQUksSUFBSSxDQUFDL0MsT0FBTyxDQUFDbUQsT0FBTyxFQUFFO1VBQ3hCLElBQUlKLFVBQVUsRUFBRTtZQUNkLE1BQU1LLE9BQU8sR0FBSSxHQUFFUCxRQUFTLE1BQUs7WUFDakMsSUFBSVEsR0FBRztZQUNQLElBQUk3RSxFQUFFLENBQUNzRSxVQUFVLENBQUNNLE9BQU8sQ0FBQyxFQUN4QkMsR0FBRyxHQUFHN0UsRUFBRSxDQUFDOEUsWUFBWSxDQUFDRixPQUFPLENBQUMsQ0FBQ2QsUUFBUSxDQUFDLENBQUMsTUFDdENlLEdBQUcsR0FBRyxlQUFlO1lBQzFCbkQsT0FBTyxDQUFDcUQsR0FBRyxDQUFFLEdBQUU3QixHQUFJLGVBQWNtQixRQUFTLFNBQVFRLEdBQUksRUFBQyxDQUFDO1VBQzFELENBQUMsTUFBTTtZQUNMbkQsT0FBTyxDQUFDcUQsR0FBRyxDQUFFLEdBQUU3QixHQUFJLGlCQUFnQm1CLFFBQVMsRUFBQyxDQUFDO1VBQ2hEO1FBQ0Y7UUFDQSxPQUFPLEtBQUs7TUFDZDtJQUNGO0lBQ0EsT0FBTyxJQUFJO0VBQ2I7RUFFQSxNQUFNVyxHQUFHQSxDQUNQSCxHQUFXLEVBQ1hSLFFBQWdCLEVBQ2hCdEIsTUFBYyxFQUNkRyxHQUFXLEVBQ007SUFDakIsSUFBSSxJQUFJLENBQUMxQixPQUFPLENBQUNtRCxPQUFPLEVBQUVqRCxPQUFPLENBQUNxRCxHQUFHLENBQUUsR0FBRTdCLEdBQUksV0FBVTJCLEdBQUksR0FBRSxDQUFDO0lBQzlELE1BQU1JLFFBQVEsR0FBRyxNQUFNaEYsS0FBSyxDQUFDNEUsR0FBRyxDQUFDO0lBQ2pDLElBQUlyQixJQUFTLEdBQUcsTUFBTXlCLFFBQVEsQ0FBQ0MsTUFBTSxDQUFDLENBQUM7SUFDdkMsSUFBSUMsTUFBTTtJQUNWLElBQUksQ0FBQ0YsUUFBUSxDQUFDRyxFQUFFLEVBQUU7TUFDaEJELE1BQU0sR0FBR0YsUUFBUSxDQUFDRSxNQUFNO01BQ3hCLElBQUlGLFFBQVEsQ0FBQ0UsTUFBTSxLQUFLLEdBQUcsRUFBRTtRQUMzQixJQUFJLElBQUksQ0FBQzNELE9BQU8sQ0FBQ21ELE9BQU8sRUFBRTtVQUN4QmpELE9BQU8sQ0FBQzJELEtBQUssQ0FDViw2QkFBNEJSLEdBQUksV0FBVTNCLEdBQUksaUJBQWdCb0MsSUFBSSxDQUFDQyxTQUFTLENBQzNFO1lBQUVDLElBQUksRUFBRVAsUUFBUSxDQUFDRSxNQUFNO1lBQUVNLE9BQU8sRUFBRVIsUUFBUSxDQUFDUztVQUFXLENBQUMsRUFDdkQsSUFBSSxFQUNKLENBQ0YsQ0FBRSxFQUNKLENBQUM7UUFDSDtNQUNGO01BQ0ExRixFQUFFLENBQUMyRixhQUFhLENBQUN0QixRQUFRLEVBQUUsRUFBRSxDQUFDO0lBQ2hDLENBQUMsTUFBTTtNQUNMO01BQUMsQ0FBQ2IsSUFBSSxFQUFFMkIsTUFBTSxDQUFDLEdBQUd2RCxRQUFRLENBQUMyQixpQkFBaUIsQ0FBQ0MsSUFBSSxFQUFFVCxNQUFNLENBQUM7TUFDMUQvQyxFQUFFLENBQUMyRixhQUFhLENBQUN0QixRQUFRLEVBQUViLElBQUksQ0FBQztJQUNsQztJQUNBLE9BQU8yQixNQUFNO0VBQ2Y7RUFFQSxPQUFPUyxVQUFVQSxDQUFDMUMsR0FBVyxFQUFVO0lBQ3JDLE1BQU0yQixHQUFHLEdBQ1AseUdBQXlHO0lBQzNHLE9BQVEsSUFBRzNCLEdBQUksS0FBSTJCLEdBQUksUUFBTzNCLEdBQUksUUFBTztFQUMzQztFQUVBLE1BQU0yQyxRQUFRQSxDQUNaQyxTQUFpQixFQUNqQmhELGtCQUF1QixFQUN2QkMsTUFBYyxFQUNHO0lBQ2pCLE1BQU1HLEdBQUcsR0FBR0osa0JBQWtCLENBQUNJLEdBQUc7SUFDbEMsTUFBTW1CLFFBQVEsR0FBSSxHQUFFeUIsU0FBVSxRQUFPNUMsR0FBSSxJQUFHSCxNQUFPLEVBQUM7SUFDcEQsSUFBSSxFQUFFLE1BQU0sSUFBSSxDQUFDcUIsYUFBYSxDQUFDQyxRQUFRLEVBQUVuQixHQUFHLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQztJQUN4RCxJQUFJLElBQUksQ0FBQzFCLE9BQU8sQ0FBQ21ELE9BQU8sRUFBRWpELE9BQU8sQ0FBQ3FELEdBQUcsQ0FBRSxHQUFFN0IsR0FBSSxjQUFhbUIsUUFBUyxFQUFDLENBQUM7SUFDckUsSUFBSTBCLE9BQU8sR0FBRyxLQUFLO0lBQ25CLElBQUlDLElBQUksR0FBRyxFQUFFO0lBQ2IsSUFBSW5CLEdBQUc7SUFFUCxLQUFLQSxHQUFHLElBQUksSUFBSSxDQUFDaEMsT0FBTyxDQUFDQyxrQkFBa0IsRUFBRUMsTUFBTSxDQUFDLEVBQUU7TUFDcEQsSUFBSSxTQUFTLElBQUksSUFBSSxDQUFDdkIsT0FBTyxFQUFFO1FBQzdCd0UsSUFBSSxJQUFLLE9BQU1uQixHQUFJLElBQUc7UUFDdEI7TUFDRixDQUFDLE1BQU07UUFDTG1CLElBQUksSUFBSyxPQUFNbkIsR0FBSSxHQUFFO01BQ3ZCO01BRUEsTUFBTU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDSCxHQUFHLENBQUNILEdBQUcsRUFBRVIsUUFBUSxFQUFFdEIsTUFBTSxFQUFFRyxHQUFHLENBQUM7TUFFekQ4QyxJQUFJLElBQUssR0FBRWIsTUFBTyxJQUFHO01BQ3JCLElBQUlBLE1BQU0sSUFBSSxJQUFJLEVBQUU7UUFDbEJZLE9BQU8sR0FBRyxJQUFJO1FBQ2Q7TUFDRjtJQUNGO0lBQ0EsTUFBTW5CLE9BQU8sR0FBSSxHQUFFUCxRQUFTLE1BQUs7SUFDakMsSUFBSTBCLE9BQU8sRUFBRTtNQUNYL0YsRUFBRSxDQUFDMkYsYUFBYSxDQUFDZixPQUFPLEVBQUVDLEdBQUcsQ0FBQztJQUNoQyxDQUFDLE1BQU0sSUFBSTdFLEVBQUUsQ0FBQ3NFLFVBQVUsQ0FBQ00sT0FBTyxDQUFDLEVBQUU7TUFDakM1RSxFQUFFLENBQUNpRyxVQUFVLENBQUNyQixPQUFPLENBQUM7SUFDeEI7SUFDQSxJQUFJb0IsSUFBSSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQ3hFLE9BQU8sQ0FBQzBFLE1BQU0sRUFBRTtNQUN0Q3hFLE9BQU8sQ0FBQ3FELEdBQUcsQ0FDUixLQUFJbkQsUUFBUSxDQUFDZ0UsVUFBVSxDQUFDMUMsR0FBRyxDQUFFLGdCQUFlbUIsUUFBUyxLQUFJMkIsSUFBSSxDQUFDbkMsS0FBSyxDQUNsRSxDQUFDLEVBQ0QsQ0FBQyxDQUNILENBQUUsRUFDSixDQUFDO01BQ0QsT0FBTyxDQUFDO0lBQ1YsQ0FBQyxNQUFNO01BQ0wsT0FBTyxDQUFDO0lBQ1Y7RUFDRjtFQUVBLE1BQU1zQyxpQkFBaUJBLENBQUEsRUFBb0I7SUFDekMsTUFBTUMsTUFBTSxHQUFJLEdBQUUsSUFBSSxDQUFDNUUsT0FBTyxDQUFDNkUsTUFBTyxPQUFNO0lBQzVDLElBQUksQ0FBQ3JHLEVBQUUsQ0FBQ3NFLFVBQVUsQ0FBQzhCLE1BQU0sQ0FBQyxFQUFFO01BQzFCMUUsT0FBTyxDQUFDMkQsS0FBSyxDQUFFLEdBQUVlLE1BQU8sb0NBQW1DLENBQUM7TUFDNUQsT0FBTyxDQUFDO0lBQ1Y7SUFFQSxNQUFNTixTQUFTLEdBQUczRixJQUFJLENBQUNtRyxJQUFJLENBQUMsSUFBSSxDQUFDOUUsT0FBTyxDQUFDNkUsTUFBTSxFQUFFLElBQUksQ0FBQzdFLE9BQU8sQ0FBQytFLFdBQVcsQ0FBQztJQUMxRXZHLEVBQUUsQ0FBQ3dHLGFBQWEsQ0FBRSxHQUFFVixTQUFVLE1BQUssQ0FBQztJQUVwQyxLQUFLLE1BQU1XLFFBQVEsSUFBSXBHLFFBQVEsQ0FBQyxJQUFJLENBQUNtQixPQUFPLENBQUNrRixJQUFJLENBQUMsRUFBRTtNQUNsRCxNQUFNcEUsUUFBUSxHQUFHbEMsSUFBSSxDQUFDcUcsUUFBUSxDQUFDO01BQy9CLElBQUksU0FBUyxDQUFDRSxJQUFJLENBQUNyRSxRQUFRLENBQUNZLEdBQUcsQ0FBQyxJQUFJLE9BQU8sQ0FBQ3lELElBQUksQ0FBQ3JFLFFBQVEsQ0FBQ1ksR0FBRyxDQUFDLEVBQUU7TUFDaEUsS0FBSyxNQUFNSixrQkFBa0IsSUFBSSxJQUFJLENBQUNULHNCQUFzQixDQUFDQyxRQUFRLENBQUMsRUFBRTtRQUN0RSxJQUFJLFNBQVMsQ0FBQ3FFLElBQUksQ0FBQzdELGtCQUFrQixDQUFDSSxHQUFHLENBQUMsRUFBRTtRQUM1QyxJQUFJaUMsTUFBTSxHQUFHLENBQUM7UUFDZCxLQUFLLE1BQU1wQyxNQUFNLElBQUksQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEVBQUU7VUFDcENvQyxNQUFNLElBQUksTUFBTSxJQUFJLENBQUNVLFFBQVEsQ0FBQ0MsU0FBUyxFQUFFaEQsa0JBQWtCLEVBQUVDLE1BQU0sQ0FBQztRQUN0RTtRQUNBLElBQUlvQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMzRCxPQUFPLENBQUMwRSxNQUFNLEVBQUV4RSxPQUFPLENBQUNxRCxHQUFHLENBQUMsS0FBSyxDQUFDO01BQ3hEO0lBQ0Y7SUFFQSxJQUFJLEVBQUUsU0FBUyxJQUFJLElBQUksQ0FBQ3ZELE9BQU8sQ0FBQyxFQUFFO01BQ2hDLE1BQU0sSUFBSSxDQUFDZ0IsYUFBYSxDQUFDc0QsU0FBUyxDQUFDO0lBQ3JDO0lBRUEsT0FBTyxDQUFDO0VBQ1Y7QUFDRjtBQUVBLGVBQWVjLElBQUlBLENBQUNuRyxJQUFTLEVBQW1CO0VBQzlDLE1BQU1lLE9BQU8sR0FBR2hCLFNBQVMsQ0FBQ0MsSUFBSSxDQUFDO0VBQy9CLElBQUllLE9BQU8sS0FBSyxJQUFJLEVBQUUsT0FBTyxDQUFDO0VBQzlCLE1BQU1xRixRQUFRLEdBQUcsSUFBSWpGLFFBQVEsQ0FBQ0osT0FBTyxDQUFDO0VBQ3RDLE9BQU9xRixRQUFRLENBQUNWLGlCQUFpQixDQUFDLENBQUM7QUFDckM7O0FBRUE7QUFDQSxJQUFJVyxPQUFPLENBQUNyRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUNzRyxRQUFRLENBQUMsdUJBQXVCLENBQUMsRUFDbkRILElBQUksQ0FBQ0UsT0FBTyxDQUFDckcsSUFBSSxDQUFDLENBQ2Z1RyxJQUFJLENBQUVDLFFBQVEsSUFBSztFQUNsQkgsT0FBTyxDQUFDSSxJQUFJLENBQUNELFFBQVEsQ0FBQztBQUN4QixDQUFDLENBQUMsQ0FDREUsS0FBSyxDQUFFOUIsS0FBSyxJQUFLO0VBQ2hCM0QsT0FBTyxDQUFDMkQsS0FBSyxDQUFDQSxLQUFLLENBQUM7RUFDcEJ5QixPQUFPLENBQUNJLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDakIsQ0FBQyxDQUFDIn0=
197
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhc3NlcnQiLCJleGVjU3luYyIsImNvbW1hbmRMaW5lQXJncyIsImNyZWF0ZUhhc2giLCJmcyIsInBhdGgiLCJ3YWxrRG9jdW1lbnRBbmREaXZpc2lvbnMiLCJnaXQiLCJpdGVyTG9hZEFzc2VtYmxlZURvY3VtZW50cyIsInBhdGhGcm9tRG9jdW1lbnRVaWQiLCJEb2N1bWVudFVybEZvcm1hdCIsIml0ZXJEb2N1bWVudE9yRGl2aXNpb25VcmxzIiwib3B0aW9uc0RlZmluaXRpb25zIiwiYWxpYXMiLCJoZWxwIiwibmFtZSIsInR5cGUiLCJCb29sZWFuIiwiZGVmYXVsdFZhbHVlIiwiU3RyaW5nIiwibXVsdGlwbGUiLCJkZWZhdWx0T3B0aW9uIiwib3B0aW9ucyIsInJldHJpZXZlRG9jdW1lbnRzIiwiY29tbWl0IiwidWlkIiwiZGF0YURpciIsImRvY3VtZW50c0RpciIsImpvaW4iLCJwdWxsIiwiY3dkIiwiZW52IiwicHJvY2VzcyIsImVuY29kaW5nIiwic3RkaW8iLCJlbnN1cmVEaXJTeW5jIiwiZnVsbCIsImZpbGVuYW1lIiwicmVhZGRpclN5bmMiLCJyZW1vdmVTeW5jIiwiZmlyc3RVaWQiLCJza2lwIiwiZG9jdW1lbnQiLCJsZWdpc2xhdHVyZSIsImRvY3VtZW50T3JEaXZpc2lvbiIsInN1YnN0cmluZyIsImRvY3VtZW50RGlyIiwiZmlsZW5hbWVCeVNoYTI1NiIsImluZGV4UGF0aCIsImluZGV4IiwicGF0aEV4aXN0c1N5bmMiLCJyZWFkSnNvblN5bmMiLCJmb3JtYXQiLCJ1cmwiLCJ1bmRlZmluZWQiLCJmaWxlSW5mb3MiLCJmaW5kIiwicHVzaCIsIlBkZiIsInN0YXR1cyIsInNoYTI1NiIsInNpbGVudCIsImNvbnNvbGUiLCJsb2ciLCJyZXNwb25zZSIsImZldGNoIiwiZmlsZVBhdGgiLCJvayIsImFycmF5QnVmZmVyIiwiYnVmZmVyIiwiQnVmZmVyIiwiZnJvbSIsInN1YmFycmF5IiwidG9TdHJpbmciLCJzdGFydHNXaXRoIiwid2FybiIsInVwZGF0ZSIsImRpZ2VzdCIsImV4aXN0aW5nRmlsZW5hbWUiLCJjcmVhdGVXcml0ZVN0cmVhbSIsIndyaXRlIiwiZXJyb3IiLCJKU09OIiwic3RyaW5naWZ5IiwiY29kZSIsIm1lc3NhZ2UiLCJzdGF0dXNUZXh0Iiwid3JpdGVKc29uU3luYyIsInNwYWNlcyIsImNvbW1pdEFuZFB1c2giLCJyZW1vdGUiLCJ0aGVuIiwiZXhpdENvZGUiLCJleGl0IiwiY2F0Y2giXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NyaXB0cy9yZXRyaWV2ZV9kb2N1bWVudHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCJcbmltcG9ydCB7IGV4ZWNTeW5jIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIlxuaW1wb3J0IGNvbW1hbmRMaW5lQXJncyBmcm9tIFwiY29tbWFuZC1saW5lLWFyZ3NcIlxuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gXCJjcnlwdG9cIlxuaW1wb3J0IGZzIGZyb20gXCJmcy1leHRyYVwiXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5cbmltcG9ydCB7IHdhbGtEb2N1bWVudEFuZERpdmlzaW9ucyB9IGZyb20gXCIuLi9kb3NzaWVyc19sZWdpc2xhdGlmc1wiXG5pbXBvcnQgKiBhcyBnaXQgZnJvbSBcIi4uL2dpdFwiXG5pbXBvcnQgeyBpdGVyTG9hZEFzc2VtYmxlZURvY3VtZW50cywgcGF0aEZyb21Eb2N1bWVudFVpZCB9IGZyb20gXCIuLi9sb2FkZXJzXCJcbmltcG9ydCB7IERvY3VtZW50VXJsRm9ybWF0LCBpdGVyRG9jdW1lbnRPckRpdmlzaW9uVXJscyB9IGZyb20gXCIuLi91cmxzXCJcblxuaW50ZXJmYWNlIEZpbGVJbmZvcyB7XG4gIGZpbGVuYW1lPzogc3RyaW5nXG4gIHNoYTI1Nj86IHN0cmluZ1xuICB1cmw6IHN0cmluZ1xuICBzdGF0dXM6IG51bWJlclxufVxuXG5jb25zdCBvcHRpb25zRGVmaW5pdGlvbnMgPSBbXG4gIHtcbiAgICBhbGlhczogXCJjXCIsXG4gICAgaGVscDogXCJjb21taXQgZG9jdW1lbnRzXCIsXG4gICAgbmFtZTogXCJjb21taXRcIixcbiAgICB0eXBlOiBCb29sZWFuLFxuICB9LFxuICB7XG4gICAgYWxpYXM6IFwiZlwiLFxuICAgIGhlbHA6IFwicmV0cmlldmUgYWxsIGRvY3VtZW50cywgZXZlbiBhbHJlYWR5IHJldHJpZXZlZCBvbmVzXCIsXG4gICAgbmFtZTogXCJmdWxsXCIsXG4gICAgdHlwZTogQm9vbGVhbixcbiAgfSxcbiAge1xuICAgIGFsaWFzOiBcImxcIixcbiAgICBkZWZhdWx0VmFsdWU6IFwiMTZcIixcbiAgICBoZWxwOiAnbGVnaXNsYXR1cmVzIHRvIHJldHJpZXZlLCBcIipcIiBmb3IgYWxsJyxcbiAgICBuYW1lOiBcImxlZ2lzbGF0dXJlXCIsXG4gICAgdHlwZTogU3RyaW5nLFxuICB9LFxuICB7XG4gICAgYWxpYXM6IFwiblwiLFxuICAgIGhlbHA6IFwidHJ5IHRvIGFsc28gcmV0cmlldmUgZG9jdW1lbnRzIHRoYXQgd2VyZSBwcmV2aW91c2x5IG5vdCBmb3VuZFwiLFxuICAgIG5hbWU6IFwibm90LWZvdW5kXCIsXG4gICAgdHlwZTogQm9vbGVhbixcbiAgfSxcbiAge1xuICAgIGFsaWFzOiBcInBcIixcbiAgICBoZWxwOiBcInB1bGwgcmVwb3NpdG9yaWVzIGJlZm9yZSBwcm9jZWVkaW5nXCIsXG4gICAgbmFtZTogXCJwdWxsXCIsXG4gICAgdHlwZTogQm9vbGVhbixcbiAgfSxcbiAge1xuICAgIGFsaWFzOiBcInJcIixcbiAgICBoZWxwOiBcInB1c2ggY29tbWl0IHRvIGdpdmVuIHJlbW90ZVwiLFxuICAgIG11bHRpcGxlOiB0cnVlLFxuICAgIG5hbWU6IFwicmVtb3RlXCIsXG4gICAgdHlwZTogU3RyaW5nLFxuICB9LFxuICB7XG4gICAgYWxpYXM6IFwic1wiLFxuICAgIGhlbHA6IFwiZG9uJ3QgbG9nIGFueXRoaW5nXCIsXG4gICAgbmFtZTogXCJzaWxlbnRcIixcbiAgICB0eXBlOiBCb29sZWFuLFxuICB9LFxuICB7XG4gICAgYWxpYXM6IFwidVwiLFxuICAgIGhlbHA6IFwiVUlEIG9mIGZpcnN0IEFzc2VtYmzDqWUncyBkb2N1bWVudCBvciBkaXZpc2lvbiB0byByZXRyaWV2ZVwiLFxuICAgIG5hbWU6IFwidWlkXCIsXG4gICAgdHlwZTogU3RyaW5nLFxuICB9LFxuICB7XG4gICAgYWxpYXM6IFwidlwiLFxuICAgIGhlbHA6IFwidmVyYm9zZSBsb2dzXCIsXG4gICAgbmFtZTogXCJ2ZXJib3NlXCIsXG4gICAgdHlwZTogQm9vbGVhbixcbiAgfSxcbiAge1xuICAgIGRlZmF1bHRPcHRpb246IHRydWUsXG4gICAgaGVscDogXCJkaXJlY3RvcnkgY29udGFpbmluZyBBc3NlbWJsw6llIG9wZW4gZGF0YSBmaWxlc1wiLFxuICAgIG5hbWU6IFwiZGF0YURpclwiLFxuICAgIHR5cGU6IFN0cmluZyxcbiAgfSxcbl1cbmNvbnN0IG9wdGlvbnMgPSBjb21tYW5kTGluZUFyZ3Mob3B0aW9uc0RlZmluaXRpb25zKVxuXG5hc3luYyBmdW5jdGlvbiByZXRyaWV2ZURvY3VtZW50cygpOiBQcm9taXNlPG51bWJlcj4ge1xuICBhc3NlcnQoXG4gICAgIW9wdGlvbnMuY29tbWl0IHx8IG9wdGlvbnMudWlkLFxuICAgICdPcHRpb25zIFwiY29tbWl0XCIgJiBcInVpZFwiIGFyZSBpbmNvbXBhdGlibGUnLFxuICApXG5cbiAgY29uc3QgZGF0YURpciA9IG9wdGlvbnMuZGF0YURpclxuICBjb25zdCBkb2N1bWVudHNEaXIgPSBwYXRoLmpvaW4oZGF0YURpciwgXCJEb2N1bWVudHNcIilcbiAgaWYgKG9wdGlvbnMucHVsbCkge1xuICAgIGV4ZWNTeW5jKGBnaXQgcmVzZXQgLS1oYXJkIG9yaWdpbi9tYXN0ZXJgLCB7XG4gICAgICBjd2Q6IGRvY3VtZW50c0RpcixcbiAgICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgICBlbmNvZGluZzogXCJ1dGYtOFwiLFxuICAgICAgc3RkaW86IFtcImlnbm9yZVwiLCBcImlnbm9yZVwiLCBcInBpcGVcIl0sXG4gICAgfSlcbiAgICBleGVjU3luYyhgZ2l0IHB1bGwgLS1yZWJhc2VgLCB7XG4gICAgICBjd2Q6IGRvY3VtZW50c0RpcixcbiAgICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgICBlbmNvZGluZzogXCJ1dGYtOFwiLFxuICAgICAgc3RkaW86IFtcImlnbm9yZVwiLCBcImlnbm9yZVwiLCBcInBpcGVcIl0sXG4gICAgfSlcbiAgfVxuXG4gIGZzLmVuc3VyZURpclN5bmMoZG9jdW1lbnRzRGlyKVxuICBpZiAob3B0aW9ucy5mdWxsICYmICFvcHRpb25zLnVpZCkge1xuICAgIGZvciAoY29uc3QgZmlsZW5hbWUgb2YgZnMucmVhZGRpclN5bmMoZG9jdW1lbnRzRGlyKSkge1xuICAgICAgaWYgKGZpbGVuYW1lWzBdID09PSBcIi5cIikge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgZnMucmVtb3ZlU3luYyhwYXRoLmpvaW4oZG9jdW1lbnRzRGlyLCBmaWxlbmFtZSkpXG4gICAgfVxuICB9XG5cbiAgY29uc3QgZmlyc3RVaWQgPSBvcHRpb25zLnVpZFxuICBsZXQgc2tpcCA9IEJvb2xlYW4oZmlyc3RVaWQpXG4gIGZvciAoY29uc3QgeyBkb2N1bWVudCB9IG9mIGl0ZXJMb2FkQXNzZW1ibGVlRG9jdW1lbnRzKFxuICAgIGRhdGFEaXIsXG4gICAgb3B0aW9ucy5sZWdpc2xhdHVyZSxcbiAgKSkge1xuICAgIGZvciAoY29uc3QgZG9jdW1lbnRPckRpdmlzaW9uIG9mIHdhbGtEb2N1bWVudEFuZERpdmlzaW9ucyhkb2N1bWVudCkpIHtcbiAgICAgIC8vIElnbm9yZSBkb2N1bWVudHMgZnJvbSBTw6luYXQuXG4gICAgICBpZiAoZG9jdW1lbnRPckRpdmlzaW9uLnVpZC5zdWJzdHJpbmcoNCwgNikgPT09IFwiU05cIikge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoc2tpcCkge1xuICAgICAgICBpZiAoZG9jdW1lbnRPckRpdmlzaW9uLnVpZCA9PT0gZmlyc3RVaWQpIHtcbiAgICAgICAgICBza2lwID0gZmFsc2VcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRvY3VtZW50RGlyID0gcGF0aEZyb21Eb2N1bWVudFVpZChcbiAgICAgICAgZG9jdW1lbnRzRGlyLFxuICAgICAgICBkb2N1bWVudE9yRGl2aXNpb24udWlkLFxuICAgICAgKVxuICAgICAgZnMuZW5zdXJlRGlyU3luYyhkb2N1bWVudERpcilcblxuICAgICAgY29uc3QgZmlsZW5hbWVCeVNoYTI1NjogeyBbZGlnZXN0OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9XG4gICAgICBjb25zdCBpbmRleFBhdGggPSBwYXRoLmpvaW4oZG9jdW1lbnREaXIsIFwiaW5kZXguanNvblwiKVxuICAgICAgY29uc3QgaW5kZXggPSAoXG4gICAgICAgIGZzLnBhdGhFeGlzdHNTeW5jKGluZGV4UGF0aCkgPyBmcy5yZWFkSnNvblN5bmMoaW5kZXhQYXRoKSA6IHt9XG4gICAgICApIGFzIHsgW2Zvcm1hdDogc3RyaW5nXTogRmlsZUluZm9zW10gfVxuICAgICAgZm9yIChjb25zdCB7IGZvcm1hdCwgdHlwZSwgdXJsIH0gb2YgaXRlckRvY3VtZW50T3JEaXZpc2lvblVybHMoXG4gICAgICAgIGRvY3VtZW50T3JEaXZpc2lvbixcbiAgICAgICkpIHtcbiAgICAgICAgaWYgKGluZGV4W2Zvcm1hdF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGluZGV4W2Zvcm1hdF0gPSBbXVxuICAgICAgICB9XG4gICAgICAgIGxldCBmaWxlSW5mb3MgPSBpbmRleFtmb3JtYXRdLmZpbmQoKGZpbGVJbmZvcykgPT4gZmlsZUluZm9zLnVybCA9PT0gdXJsKVxuICAgICAgICBpZiAoZmlsZUluZm9zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBmaWxlSW5mb3MgPSB7fSBhcyBGaWxlSW5mb3NcbiAgICAgICAgICBpbmRleFtmb3JtYXRdLnB1c2goZmlsZUluZm9zKVxuICAgICAgICB9XG4gICAgICAgIGZpbGVJbmZvcy51cmwgPSB1cmxcblxuICAgICAgICBjb25zdCBmaWxlbmFtZSA9IGAke3R5cGV9LiR7XG4gICAgICAgICAgZm9ybWF0ID09PSBEb2N1bWVudFVybEZvcm1hdC5QZGYgPyBcInBkZlwiIDogXCJodG1sXCJcbiAgICAgICAgfWBcbiAgICAgICAgaWYgKGZpbGVJbmZvcy5zdGF0dXMgPT09IDIwMCAmJiAhb3B0aW9ucy5mdWxsKSB7XG4gICAgICAgICAgZmlsZW5hbWVCeVNoYTI1NltmaWxlSW5mb3Muc2hhMjU2IGFzIHN0cmluZ10gPSBmaWxlbmFtZVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbGVJbmZvcy5zdGF0dXMgPT09IDQwNCAmJiAhb3B0aW9uc1tcIm5vdC1mb3VuZFwiXSkge1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW9wdGlvbnMuc2lsZW50KSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBgUmV0cmlldmluZyBkb2N1bWVudCBvciBkaXZpc2lvbiAke2RvY3VtZW50T3JEaXZpc2lvbi51aWR9IGF0ICR7dXJsfeKApmAsXG4gICAgICAgICAgKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpXG4gICAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKGRvY3VtZW50RGlyLCBmaWxlbmFtZSlcbiAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSBhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpXG4gICAgICAgICAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmZyb20oYXJyYXlCdWZmZXIpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgZm9ybWF0ID09PSBEb2N1bWVudFVybEZvcm1hdC5QZGYgJiZcbiAgICAgICAgICAgICFidWZmZXIuc3ViYXJyYXkoMCwgNCkudG9TdHJpbmcoKS5zdGFydHNXaXRoKFwiJVBERlwiKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgLy8gSW5zdGVhZCBvZiBhIFBERiwgdGhlIHJlY2VpdmVkIGRhdGEgbWF5IGJlIGFuIEhUTUwgcGFnZSB3aXRoIGEgbWVzc2FnZSBsaWtlXG4gICAgICAgICAgICAvLyBcIkRvY3VtZW50IG5vbiBlbmNvcmUgcHVibGnDqVwiLlxuICAgICAgICAgICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYCAgUERGIFwiJHt1cmx9XCIgbm90IGZvdW5kLmApXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmcy5yZW1vdmVTeW5jKGZpbGVQYXRoKVxuICAgICAgICAgICAgZGVsZXRlIGZpbGVJbmZvcy5maWxlbmFtZVxuICAgICAgICAgICAgZGVsZXRlIGZpbGVJbmZvcy5zaGEyNTZcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc2hhMjU2ID0gY3JlYXRlSGFzaChcInNoYTI1NlwiKS51cGRhdGUoYnVmZmVyKS5kaWdlc3QoXCJoZXhcIilcbiAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nRmlsZW5hbWUgPSBmaWxlbmFtZUJ5U2hhMjU2W3NoYTI1Nl1cbiAgICAgICAgICAgIGlmIChleGlzdGluZ0ZpbGVuYW1lID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgZnMuY3JlYXRlV3JpdGVTdHJlYW0oZmlsZVBhdGgpLndyaXRlKGJ1ZmZlcilcbiAgICAgICAgICAgICAgZmlsZUluZm9zLmZpbGVuYW1lID0gZmlsZW5hbWVcbiAgICAgICAgICAgICAgZmlsZW5hbWVCeVNoYTI1NltzaGEyNTZdID0gZmlsZW5hbWVcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGZpbGVJbmZvcy5maWxlbmFtZSA9IGV4aXN0aW5nRmlsZW5hbWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbGVJbmZvcy5zaGEyNTYgPSBzaGEyNTZcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMuc2lsZW50KSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUud2FybihgICBQYWdlIFwiJHt1cmx9XCIgbm90IGZvdW5kLmApXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgIGAgIEVycm9yOlxcbiR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgICAgeyBjb2RlOiByZXNwb25zZS5zdGF0dXMsIG1lc3NhZ2U6IHJlc3BvbnNlLnN0YXR1c1RleHQgfSxcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgIDIsXG4gICAgICAgICAgICAgICl9YCxcbiAgICAgICAgICAgIClcbiAgICAgICAgICB9XG4gICAgICAgICAgZnMucmVtb3ZlU3luYyhmaWxlUGF0aClcbiAgICAgICAgICBkZWxldGUgZmlsZUluZm9zLmZpbGVuYW1lXG4gICAgICAgICAgZGVsZXRlIGZpbGVJbmZvcy5zaGEyNTZcbiAgICAgICAgfVxuICAgICAgICBmaWxlSW5mb3Muc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzXG4gICAgICB9XG4gICAgICBmcy53cml0ZUpzb25TeW5jKGluZGV4UGF0aCwgaW5kZXgsIHsgZW5jb2Rpbmc6IFwidXRmLThcIiwgc3BhY2VzOiAyIH0pXG4gICAgfVxuICB9XG5cbiAgaWYgKG9wdGlvbnMuY29tbWl0KSB7XG4gICAgcmV0dXJuIGdpdC5jb21taXRBbmRQdXNoKGRvY3VtZW50c0RpciwgXCJOb3V2ZWxsZSBtb2lzc29uXCIsIG9wdGlvbnMucmVtb3RlKVxuICB9XG4gIHJldHVybiAwXG59XG5cbnJldHJpZXZlRG9jdW1lbnRzKClcbiAgLnRoZW4oKGV4aXRDb2RlKSA9PiBwcm9jZXNzLmV4aXQoZXhpdENvZGUpKVxuICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgY29uc29sZS5sb2coZXJyb3IpXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH0pXG4iXSwibWFwcGluZ3MiOiJBQUFBLE9BQU9BLE1BQU0sTUFBTSxRQUFRO0FBQzNCLFNBQVNDLFFBQVEsUUFBUSxlQUFlO0FBQ3hDLE9BQU9DLGVBQWUsTUFBTSxtQkFBbUI7QUFDL0MsU0FBU0MsVUFBVSxRQUFRLFFBQVE7QUFDbkMsT0FBT0MsRUFBRSxNQUFNLFVBQVU7QUFDekIsT0FBT0MsSUFBSSxNQUFNLE1BQU07QUFBQSxTQUVkQyx3QkFBd0I7QUFBQSxPQUMxQixLQUFLQyxHQUFHO0FBQUEsU0FDTkMsMEJBQTBCLEVBQUVDLG1CQUFtQjtBQUFBLFNBQy9DQyxpQkFBaUIsRUFBRUMsMEJBQTBCO0FBU3RELE1BQU1DLGtCQUFrQixHQUFHLENBQ3pCO0VBQ0VDLEtBQUssRUFBRSxHQUFHO0VBQ1ZDLElBQUksRUFBRSxrQkFBa0I7RUFDeEJDLElBQUksRUFBRSxRQUFRO0VBQ2RDLElBQUksRUFBRUM7QUFDUixDQUFDLEVBQ0Q7RUFDRUosS0FBSyxFQUFFLEdBQUc7RUFDVkMsSUFBSSxFQUFFLHFEQUFxRDtFQUMzREMsSUFBSSxFQUFFLE1BQU07RUFDWkMsSUFBSSxFQUFFQztBQUNSLENBQUMsRUFDRDtFQUNFSixLQUFLLEVBQUUsR0FBRztFQUNWSyxZQUFZLEVBQUUsSUFBSTtFQUNsQkosSUFBSSxFQUFFLHVDQUF1QztFQUM3Q0MsSUFBSSxFQUFFLGFBQWE7RUFDbkJDLElBQUksRUFBRUc7QUFDUixDQUFDLEVBQ0Q7RUFDRU4sS0FBSyxFQUFFLEdBQUc7RUFDVkMsSUFBSSxFQUFFLCtEQUErRDtFQUNyRUMsSUFBSSxFQUFFLFdBQVc7RUFDakJDLElBQUksRUFBRUM7QUFDUixDQUFDLEVBQ0Q7RUFDRUosS0FBSyxFQUFFLEdBQUc7RUFDVkMsSUFB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