@tricoteuses/assemblee 1.0.0-next.2 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/lib/api.js +23 -7
- package/lib/api.mjs +41 -0
- package/lib/bugs/acteur-00010/plugin.test.js +139 -33
- package/lib/bugs/acteur-00010/plugin.test.mjs +33 -0
- package/lib/bugs/acteur-00010.js +166 -24
- package/lib/bugs/acteur-00010.mjs +31 -0
- package/lib/bugs/agenda-00002/plugin.test.js +178 -52
- package/lib/bugs/agenda-00002/plugin.test.mjs +52 -0
- package/lib/bugs/agenda-00002.js +507 -143
- package/lib/bugs/agenda-00002.mjs +197 -0
- package/lib/bugs/agenda-00008/plugin.test.js +143 -31
- package/lib/bugs/agenda-00008/plugin.test.mjs +31 -0
- package/lib/bugs/agenda-00008.js +180 -25
- package/lib/bugs/agenda-00008.mjs +30 -0
- package/lib/bugs/agenda-00011/plugin.test.js +371 -156
- package/lib/bugs/agenda-00011/plugin.test.mjs +156 -0
- package/lib/bugs/agenda-00011.js +416 -117
- package/lib/bugs/agenda-00011.mjs +150 -0
- package/lib/bugs.js +591 -54
- package/lib/bugs.mjs +93 -0
- package/lib/cleaners/actes_legislatifs.js +149 -61
- package/lib/cleaners/actes_legislatifs.mjs +311 -0
- package/lib/cleaners/acteurs.js +255 -123
- package/lib/cleaners/acteurs.mjs +211 -0
- package/lib/cleaners/amendements.js +242 -117
- package/lib/cleaners/amendements.mjs +292 -0
- package/lib/cleaners/documents.js +147 -62
- package/lib/cleaners/documents.mjs +162 -0
- package/lib/cleaners/dossiers_legislatifs.js +132 -45
- package/lib/cleaners/dossiers_legislatifs.mjs +123 -0
- package/lib/cleaners/index.js +64 -8
- package/lib/cleaners/index.mjs +8 -0
- package/lib/cleaners/organes.js +54 -21
- package/lib/cleaners/organes.mjs +64 -0
- package/lib/cleaners/reunions.js +237 -127
- package/lib/cleaners/reunions.mjs +318 -0
- package/lib/cleaners/scrutins.js +261 -99
- package/lib/cleaners/scrutins.mjs +254 -0
- package/lib/cleaners/xml.js +81 -16
- package/lib/cleaners/xml.mjs +42 -0
- package/lib/datasets.js +284 -153
- package/lib/datasets.mjs +596 -0
- package/lib/dates.js +93 -34
- package/lib/dates.mjs +98 -0
- package/lib/dossiers_legislatifs.js +107 -33
- package/lib/dossiers_legislatifs.mjs +215 -0
- package/lib/file_systems.js +203 -35
- package/lib/file_systems.mjs +64 -0
- package/lib/git.js +139 -41
- package/lib/git.mjs +114 -0
- package/lib/index.js +310 -16
- package/lib/index.mjs +16 -0
- package/lib/inserters.js +355 -131
- package/lib/inserters.mjs +413 -0
- package/lib/loaders.js +900 -440
- package/lib/loaders.mjs +678 -0
- package/lib/organes.js +15 -5
- package/lib/organes.mjs +18 -0
- package/lib/parsers/documents.js +241 -89
- package/lib/parsers/documents.mjs +433 -0
- package/lib/parsers/index.js +36 -3
- package/lib/parsers/index.mjs +3 -0
- package/lib/parsers/recherche_amendements.js +616 -173
- package/lib/parsers/recherche_amendements.mjs +189 -0
- package/lib/raw_types/acteurs_et_organes.d.ts +36 -148
- package/lib/raw_types/acteurs_et_organes.js +228 -506
- package/lib/raw_types/acteurs_et_organes.mjs +1240 -0
- package/lib/raw_types/agendas.js +165 -75
- package/lib/raw_types/agendas.mjs +944 -0
- package/lib/raw_types/amendements.js +165 -77
- package/lib/raw_types/amendements.mjs +1040 -0
- package/lib/raw_types/dossiers_legislatifs.d.ts +1 -43
- package/lib/raw_types/dossiers_legislatifs.js +181 -143
- package/lib/raw_types/dossiers_legislatifs.mjs +1792 -0
- package/lib/raw_types/scrutins.js +144 -61
- package/lib/raw_types/scrutins.mjs +645 -0
- package/lib/scripts/bugs_helper.js +657 -155
- package/lib/scripts/bugs_helper.mjs +286 -0
- package/lib/scripts/clean_data.js +380 -145
- package/lib/scripts/clean_data.mjs +190 -0
- package/lib/scripts/clean_reorganized_data.js +627 -331
- package/lib/scripts/clean_reorganized_data.mjs +520 -0
- package/lib/scripts/diff_amendements.js +159 -73
- package/lib/scripts/diff_amendements.mjs +234 -0
- package/lib/scripts/document_dossiers_legislatifs.js +570 -288
- package/lib/scripts/document_dossiers_legislatifs.mjs +494 -0
- package/lib/scripts/get_today_reunions.js +37 -20
- package/lib/scripts/get_today_reunions.mjs +41 -0
- package/lib/scripts/merge_scrutins.js +121 -39
- package/lib/scripts/merge_scrutins.mjs +69 -0
- package/lib/scripts/parse_textes_lois.js +179 -125
- package/lib/scripts/parse_textes_lois.mjs +215 -0
- package/lib/scripts/raw_types_from_amendements.js +276 -77
- package/lib/scripts/raw_types_from_amendements.mjs +118 -0
- package/lib/scripts/reorganize_data.js +867 -446
- package/lib/scripts/reorganize_data.mjs +712 -0
- package/lib/scripts/retrieve_deputes_photos.js +378 -157
- package/lib/scripts/retrieve_deputes_photos.mjs +230 -0
- package/lib/scripts/retrieve_documents.js +648 -172
- package/lib/scripts/retrieve_documents.mjs +292 -0
- package/lib/scripts/retrieve_open_data.js +286 -85
- package/lib/scripts/retrieve_open_data.mjs +125 -0
- package/lib/scripts/retrieve_pending_amendments.js +302 -69
- package/lib/scripts/retrieve_pending_amendments.mjs +130 -0
- package/lib/scripts/retrieve_senateurs_photos.js +374 -198
- package/lib/scripts/retrieve_senateurs_photos.mjs +277 -0
- package/lib/scripts/retrieve_textes_lois.js +343 -89
- package/lib/scripts/retrieve_textes_lois.mjs +168 -0
- package/lib/scripts/test_load.js +30 -11
- package/lib/scripts/test_load.mjs +26 -0
- package/lib/scripts/test_load_big_files.js +30 -11
- package/lib/scripts/test_load_big_files.mjs +26 -0
- package/lib/scripts/validate_json.js +370 -120
- package/lib/scripts/validate_json.mjs +216 -0
- package/lib/shared_types/codes_actes.js +50 -15
- package/lib/shared_types/codes_actes.mjs +228 -0
- package/lib/strings.js +16 -3
- package/lib/strings.mjs +7 -0
- package/lib/types/acteurs_et_organes.js +156 -71
- package/lib/types/acteurs_et_organes.mjs +918 -0
- package/lib/types/agendas.js +154 -67
- package/lib/types/agendas.mjs +623 -0
- package/lib/types/amendements.js +166 -77
- package/lib/types/amendements.mjs +885 -0
- package/lib/types/dossiers_legislatifs.d.ts +1 -42
- package/lib/types/dossiers_legislatifs.js +182 -143
- package/lib/types/dossiers_legislatifs.mjs +1120 -0
- package/lib/types/legislatures.js +12 -3
- package/lib/types/legislatures.mjs +9 -0
- package/lib/types/scrutins.js +144 -61
- package/lib/types/scrutins.mjs +528 -0
- package/lib/urls.js +44 -25
- package/lib/urls.mjs +201 -0
- package/package.json +33 -12
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
import assert from "assert";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import commandLineArgs from "command-line-args";
|
|
4
|
+
import fs from "fs-extra";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { cleanActeur, cleanAmendement, cleanDocumentOrDivision, cleanDossierParlementaire, cleanOrgane, cleanReunion, cleanScrutin } from "../cleaners/index.mjs";
|
|
7
|
+
import { datasets, EnabledDatasets } from "../datasets.mjs";
|
|
8
|
+
import { existingDateToJson, patchedDateToJson } from "../dates.mjs";
|
|
9
|
+
import { walkDir } from "../file_systems.mjs";
|
|
10
|
+
import * as git from "../git.mjs";
|
|
11
|
+
import { Convert as ActeursEtOrganesConvert } from "../types/acteurs_et_organes.mjs";
|
|
12
|
+
import { Convert as AgendasConvert } from "../types/agendas.mjs";
|
|
13
|
+
import { Convert as AmendementsConvert } from "../types/amendements.mjs";
|
|
14
|
+
import { Convert as DossiersLegislatifsConvert } from "../types/dossiers_legislatifs.mjs";
|
|
15
|
+
import { Convert as ScrutinsConvert } from "../types/scrutins.mjs";
|
|
16
|
+
|
|
17
|
+
function parseArgs(argv) {
|
|
18
|
+
const optionsDefinitions = [{
|
|
19
|
+
alias: "C",
|
|
20
|
+
help: "clone repositories from given group (or organization) git URL",
|
|
21
|
+
name: "clone",
|
|
22
|
+
type: String
|
|
23
|
+
}, {
|
|
24
|
+
alias: "c",
|
|
25
|
+
help: "commit clean files",
|
|
26
|
+
name: "commit",
|
|
27
|
+
type: Boolean
|
|
28
|
+
}, {
|
|
29
|
+
alias: "d",
|
|
30
|
+
help: "single dataset to reorganize",
|
|
31
|
+
name: "dataset",
|
|
32
|
+
type: String
|
|
33
|
+
}, {
|
|
34
|
+
alias: "k",
|
|
35
|
+
defaultValue: ["All"],
|
|
36
|
+
help: "categories of datasets to reorganize",
|
|
37
|
+
multiple: true,
|
|
38
|
+
name: "categories",
|
|
39
|
+
type: String
|
|
40
|
+
}, {
|
|
41
|
+
alias: "r",
|
|
42
|
+
help: "push commit to given remote",
|
|
43
|
+
multiple: true,
|
|
44
|
+
name: "remote",
|
|
45
|
+
type: String
|
|
46
|
+
}, {
|
|
47
|
+
alias: "s",
|
|
48
|
+
help: "don't log anything",
|
|
49
|
+
name: "silent",
|
|
50
|
+
type: Boolean
|
|
51
|
+
}, {
|
|
52
|
+
help: "do not reset --hard after commit to save I/O if the working tree is to be discarded",
|
|
53
|
+
name: "no-reset-after-commit",
|
|
54
|
+
type: Boolean
|
|
55
|
+
}, {
|
|
56
|
+
alias: "v",
|
|
57
|
+
help: "verbose logs",
|
|
58
|
+
name: "verbose",
|
|
59
|
+
type: Boolean
|
|
60
|
+
}, {
|
|
61
|
+
defaultOption: true,
|
|
62
|
+
help: "directory containing Assemblée open data files",
|
|
63
|
+
name: "dataDir",
|
|
64
|
+
type: String
|
|
65
|
+
}];
|
|
66
|
+
const options = commandLineArgs(optionsDefinitions, {
|
|
67
|
+
argv: argv
|
|
68
|
+
});
|
|
69
|
+
return options;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function cleanReorganizedData(options) {
|
|
73
|
+
const dataDir = options.dataDir;
|
|
74
|
+
Date.prototype.toJSON = patchedDateToJson;
|
|
75
|
+
let error = false;
|
|
76
|
+
const gitGroupUrl = options.clone ? options.clone.trim().replace(/\/+$/, "") : undefined;
|
|
77
|
+
options.categories.map(datasetName => assert.notStrictEqual(EnabledDatasets[datasetName], undefined, `Unknown name of dataset: ${datasetName}`));
|
|
78
|
+
const enabledDatasets = options.categories.reduce((enabledDatasets, datasetName) => enabledDatasets | EnabledDatasets[datasetName], EnabledDatasets.None);
|
|
79
|
+
|
|
80
|
+
if (enabledDatasets & EnabledDatasets.ActeursEtOrganes) {
|
|
81
|
+
for (const dataset of datasets.acteursEtOrganes) {
|
|
82
|
+
const datasetName = path.basename(dataset.filename, ".json");
|
|
83
|
+
|
|
84
|
+
if (options.dataset && datasetName !== options.dataset) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (gitGroupUrl !== undefined) {
|
|
89
|
+
execSync(`git clone ${gitGroupUrl}/${datasetName}_nettoye.git`, {
|
|
90
|
+
cwd: dataDir,
|
|
91
|
+
env: process.env,
|
|
92
|
+
encoding: "utf-8",
|
|
93
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
analyzeAndRemove(datasetName, options);
|
|
98
|
+
const datasetRawDir = path.join(dataDir, datasetName);
|
|
99
|
+
const datasetCleanDir = datasetRawDir + "_nettoye";
|
|
100
|
+
|
|
101
|
+
for (const acteurSplitPath of walkDir(datasetRawDir, ["acteurs"])) {
|
|
102
|
+
const acteurFilename = acteurSplitPath[acteurSplitPath.length - 1];
|
|
103
|
+
|
|
104
|
+
if (!acteurFilename.endsWith(".json")) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const acteurRawFilePath = path.join(datasetRawDir, ...acteurSplitPath);
|
|
109
|
+
|
|
110
|
+
if (options.verbose) {
|
|
111
|
+
console.log(` Cleaning file: ${acteurRawFilePath}…`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const acteurRawJson = fs.readFileSync(acteurRawFilePath, {
|
|
115
|
+
encoding: "utf8"
|
|
116
|
+
});
|
|
117
|
+
const acteur = JSON.parse(acteurRawJson);
|
|
118
|
+
cleanActeur(acteur);
|
|
119
|
+
const acteurJson = JSON.stringify(acteur, null, 2); // Validate generated JSON.
|
|
120
|
+
|
|
121
|
+
const acteurClean = ActeursEtOrganesConvert.toActeur(acteurJson);
|
|
122
|
+
const acteurCleanJson = ActeursEtOrganesConvert.acteurToJson(acteurClean);
|
|
123
|
+
const acteurCleanFilePath = path.join(datasetCleanDir, ...acteurSplitPath);
|
|
124
|
+
fs.ensureDirSync(path.dirname(acteurCleanFilePath));
|
|
125
|
+
fs.writeFileSync(acteurCleanFilePath, acteurCleanJson, {
|
|
126
|
+
encoding: "utf8"
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
for (const organeSplitPath of walkDir(datasetRawDir, ["organes"])) {
|
|
131
|
+
const organeFilename = organeSplitPath[organeSplitPath.length - 1];
|
|
132
|
+
|
|
133
|
+
if (!organeFilename.endsWith(".json")) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const organeRawFilePath = path.join(datasetRawDir, ...organeSplitPath);
|
|
138
|
+
|
|
139
|
+
if (options.verbose) {
|
|
140
|
+
console.log(` Cleaning file: ${organeRawFilePath}…`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const organeRawJson = fs.readFileSync(organeRawFilePath, {
|
|
144
|
+
encoding: "utf8"
|
|
145
|
+
});
|
|
146
|
+
const organe = JSON.parse(organeRawJson);
|
|
147
|
+
cleanOrgane(organe);
|
|
148
|
+
const organeJson = JSON.stringify(organe, null, 2); // Validate generated JSON.
|
|
149
|
+
|
|
150
|
+
const organeClean = ActeursEtOrganesConvert.toOrgane(organeJson);
|
|
151
|
+
const organeCleanJson = ActeursEtOrganesConvert.organeToJson(organeClean);
|
|
152
|
+
const organeCleanFilePath = path.join(datasetCleanDir, ...organeSplitPath);
|
|
153
|
+
fs.ensureDirSync(path.dirname(organeCleanFilePath));
|
|
154
|
+
fs.writeFileSync(organeCleanFilePath, organeCleanJson, {
|
|
155
|
+
encoding: "utf8"
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (commitAndPush(datasetCleanDir, options, options.remote)) {
|
|
160
|
+
error = true;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (commitAndPushUid(datasetCleanDir, options, ["acteurs", "organes"])) {
|
|
164
|
+
error = true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (enabledDatasets & EnabledDatasets.Agendas) {
|
|
170
|
+
for (const dataset of datasets.agendas) {
|
|
171
|
+
const datasetName = path.basename(dataset.filename, ".json");
|
|
172
|
+
|
|
173
|
+
if (options.dataset && datasetName !== options.dataset) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (gitGroupUrl !== undefined) {
|
|
178
|
+
execSync(`git clone ${gitGroupUrl}/${datasetName}_nettoye.git`, {
|
|
179
|
+
cwd: dataDir,
|
|
180
|
+
env: process.env,
|
|
181
|
+
encoding: "utf-8",
|
|
182
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
analyzeAndRemove(datasetName, options);
|
|
187
|
+
const datasetRawDir = path.join(dataDir, datasetName);
|
|
188
|
+
const datasetCleanDir = datasetRawDir + "_nettoye";
|
|
189
|
+
|
|
190
|
+
for (const reunionSplitPath of walkDir(datasetRawDir)) {
|
|
191
|
+
const reunionFilename = reunionSplitPath[reunionSplitPath.length - 1];
|
|
192
|
+
|
|
193
|
+
if (!reunionFilename.endsWith(".json")) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const reunionRawFilePath = path.join(datasetRawDir, ...reunionSplitPath);
|
|
198
|
+
|
|
199
|
+
if (options.verbose) {
|
|
200
|
+
console.log(` Cleaning file: ${reunionRawFilePath}…`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const reunionRawJson = fs.readFileSync(reunionRawFilePath, {
|
|
204
|
+
encoding: "utf8"
|
|
205
|
+
});
|
|
206
|
+
const reunion = JSON.parse(reunionRawJson);
|
|
207
|
+
cleanReunion(reunion);
|
|
208
|
+
const reunionJson = JSON.stringify(reunion, null, 2); // Validate generated JSON.
|
|
209
|
+
|
|
210
|
+
const reunionClean = AgendasConvert.toReunion(reunionJson);
|
|
211
|
+
const reunionCleanJson = AgendasConvert.reunionToJson(reunionClean);
|
|
212
|
+
const reunionCleanFilePath = path.join(datasetCleanDir, ...reunionSplitPath);
|
|
213
|
+
fs.ensureDirSync(path.dirname(reunionCleanFilePath));
|
|
214
|
+
fs.writeFileSync(reunionCleanFilePath, reunionCleanJson, {
|
|
215
|
+
encoding: "utf8"
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (commitAndPush(datasetCleanDir, options, options.remote)) {
|
|
220
|
+
error = true;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (commitAndPushUid(datasetCleanDir, options, ["."])) {
|
|
224
|
+
error = true;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (enabledDatasets & EnabledDatasets.Amendements) {
|
|
230
|
+
for (const dataset of datasets.amendements) {
|
|
231
|
+
const datasetName = path.basename(dataset.filename, ".json");
|
|
232
|
+
|
|
233
|
+
if (options.dataset && datasetName !== options.dataset) {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (gitGroupUrl !== undefined) {
|
|
238
|
+
execSync(`git clone ${gitGroupUrl}/${datasetName}_nettoye.git`, {
|
|
239
|
+
cwd: dataDir,
|
|
240
|
+
env: process.env,
|
|
241
|
+
encoding: "utf-8",
|
|
242
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
analyzeAndRemove(datasetName, options);
|
|
247
|
+
const datasetRawDir = path.join(dataDir, datasetName);
|
|
248
|
+
const datasetCleanDir = datasetRawDir + "_nettoye";
|
|
249
|
+
|
|
250
|
+
for (const amendementSplitPath of walkDir(datasetRawDir)) {
|
|
251
|
+
const amendementFilename = amendementSplitPath[amendementSplitPath.length - 1];
|
|
252
|
+
|
|
253
|
+
if (!amendementFilename.endsWith(".json")) {
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const amendementRawFilePath = path.join(datasetRawDir, ...amendementSplitPath);
|
|
258
|
+
|
|
259
|
+
if (options.verbose) {
|
|
260
|
+
console.log(` Cleaning file: ${amendementRawFilePath}…`);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const amendementRawJson = fs.readFileSync(amendementRawFilePath, {
|
|
264
|
+
encoding: "utf8"
|
|
265
|
+
});
|
|
266
|
+
const amendement = JSON.parse(amendementRawJson);
|
|
267
|
+
cleanAmendement(amendement);
|
|
268
|
+
const amendementJson = JSON.stringify(amendement, null, 2); // Validate generated JSON.
|
|
269
|
+
|
|
270
|
+
const amendementClean = AmendementsConvert.toAmendement(amendementJson);
|
|
271
|
+
const amendementCleanJson = AmendementsConvert.amendementToJson(amendementClean);
|
|
272
|
+
const amendementCleanFilePath = path.join(datasetCleanDir, ...amendementSplitPath);
|
|
273
|
+
fs.ensureDirSync(path.dirname(amendementCleanFilePath));
|
|
274
|
+
fs.writeFileSync(amendementCleanFilePath, amendementCleanJson, {
|
|
275
|
+
encoding: "utf8"
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (commitAndPush(datasetCleanDir, options, options.remote)) {
|
|
280
|
+
error = true;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (commitAndPushUid(datasetCleanDir, options, ["."])) {
|
|
284
|
+
error = true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (enabledDatasets & EnabledDatasets.DossiersLegislatifs) {
|
|
290
|
+
for (const dataset of datasets.dossiersLegislatifs) {
|
|
291
|
+
const datasetName = path.basename(dataset.filename, ".json");
|
|
292
|
+
|
|
293
|
+
if (options.dataset && datasetName !== options.dataset) {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (gitGroupUrl !== undefined) {
|
|
298
|
+
execSync(`git clone ${gitGroupUrl}/${datasetName}_nettoye.git`, {
|
|
299
|
+
cwd: dataDir,
|
|
300
|
+
env: process.env,
|
|
301
|
+
encoding: "utf-8",
|
|
302
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
analyzeAndRemove(datasetName, options);
|
|
307
|
+
const datasetRawDir = path.join(dataDir, datasetName);
|
|
308
|
+
const datasetCleanDir = datasetRawDir + "_nettoye";
|
|
309
|
+
|
|
310
|
+
for (const documentSplitPath of walkDir(datasetRawDir, ["documents"])) {
|
|
311
|
+
const documentFilename = documentSplitPath[documentSplitPath.length - 1];
|
|
312
|
+
|
|
313
|
+
if (!documentFilename.endsWith(".json")) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const documentRawFilePath = path.join(datasetRawDir, ...documentSplitPath);
|
|
318
|
+
|
|
319
|
+
if (options.verbose) {
|
|
320
|
+
console.log(` Cleaning file: ${documentRawFilePath}…`);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const documentRawJson = fs.readFileSync(documentRawFilePath, {
|
|
324
|
+
encoding: "utf8"
|
|
325
|
+
});
|
|
326
|
+
const document = JSON.parse(documentRawJson);
|
|
327
|
+
cleanDocumentOrDivision(document);
|
|
328
|
+
const documentJson = JSON.stringify(document, null, 2); // Validate generated JSON.
|
|
329
|
+
|
|
330
|
+
const documentClean = DossiersLegislatifsConvert.toDocument(documentJson);
|
|
331
|
+
const documentCleanJson = DossiersLegislatifsConvert.documentToJson(documentClean);
|
|
332
|
+
const documentCleanFilePath = path.join(datasetCleanDir, ...documentSplitPath);
|
|
333
|
+
fs.ensureDirSync(path.dirname(documentCleanFilePath));
|
|
334
|
+
fs.writeFileSync(documentCleanFilePath, documentCleanJson, {
|
|
335
|
+
encoding: "utf8"
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
for (const dossierSplitPath of walkDir(datasetRawDir, ["dossiers"])) {
|
|
340
|
+
const dossierFilename = dossierSplitPath[dossierSplitPath.length - 1];
|
|
341
|
+
|
|
342
|
+
if (!dossierFilename.endsWith(".json")) {
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const dossierRawFilePath = path.join(datasetRawDir, ...dossierSplitPath);
|
|
347
|
+
|
|
348
|
+
if (options.verbose) {
|
|
349
|
+
console.log(` Cleaning file: ${dossierRawFilePath}…`);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const dossierRawJson = fs.readFileSync(dossierRawFilePath, {
|
|
353
|
+
encoding: "utf8"
|
|
354
|
+
});
|
|
355
|
+
const dossier = JSON.parse(dossierRawJson);
|
|
356
|
+
cleanDossierParlementaire(dossier);
|
|
357
|
+
const dossierJson = JSON.stringify(dossier, null, 2); // Validate generated JSON.
|
|
358
|
+
|
|
359
|
+
const dossierClean = DossiersLegislatifsConvert.toDossierParlementaire(dossierJson);
|
|
360
|
+
const dossierCleanJson = DossiersLegislatifsConvert.dossierParlementaireToJson(dossierClean);
|
|
361
|
+
const dossierCleanFilePath = path.join(datasetCleanDir, ...dossierSplitPath);
|
|
362
|
+
fs.ensureDirSync(path.dirname(dossierCleanFilePath));
|
|
363
|
+
fs.writeFileSync(dossierCleanFilePath, dossierCleanJson, {
|
|
364
|
+
encoding: "utf8"
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (commitAndPush(datasetCleanDir, options, options.remote)) {
|
|
369
|
+
error = true;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (commitAndPushUid(datasetCleanDir, options, ["documents", "dossiers"])) {
|
|
373
|
+
error = true;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (enabledDatasets & EnabledDatasets.Scrutins) {
|
|
379
|
+
for (const dataset of datasets.scrutins) {
|
|
380
|
+
const datasetName = path.basename(dataset.filename, ".json");
|
|
381
|
+
|
|
382
|
+
if (options.dataset && datasetName !== options.dataset) {
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (gitGroupUrl !== undefined) {
|
|
387
|
+
execSync(`git clone ${gitGroupUrl}/${datasetName}_nettoye.git`, {
|
|
388
|
+
cwd: dataDir,
|
|
389
|
+
env: process.env,
|
|
390
|
+
encoding: "utf-8",
|
|
391
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
analyzeAndRemove(datasetName, options);
|
|
396
|
+
const datasetRawDir = path.join(dataDir, datasetName);
|
|
397
|
+
const datasetCleanDir = datasetRawDir + "_nettoye";
|
|
398
|
+
|
|
399
|
+
for (const scrutinSplitPath of walkDir(datasetRawDir)) {
|
|
400
|
+
const scrutinFilename = scrutinSplitPath[scrutinSplitPath.length - 1];
|
|
401
|
+
|
|
402
|
+
if (!scrutinFilename.endsWith(".json")) {
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const scrutinRawFilePath = path.join(datasetRawDir, ...scrutinSplitPath);
|
|
407
|
+
|
|
408
|
+
if (options.verbose) {
|
|
409
|
+
console.log(` Cleaning file: ${scrutinRawFilePath}…`);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const scrutinRawJson = fs.readFileSync(scrutinRawFilePath, {
|
|
413
|
+
encoding: "utf8"
|
|
414
|
+
});
|
|
415
|
+
const scrutin = JSON.parse(scrutinRawJson);
|
|
416
|
+
cleanScrutin(scrutin);
|
|
417
|
+
const scrutinJson = JSON.stringify(scrutin, null, 2); // Validate generated JSON.
|
|
418
|
+
|
|
419
|
+
const scrutinClean = ScrutinsConvert.toScrutin(scrutinJson);
|
|
420
|
+
const scrutinCleanJson = ScrutinsConvert.scrutinToJson(scrutinClean);
|
|
421
|
+
const scrutinCleanFilePath = path.join(datasetCleanDir, ...scrutinSplitPath);
|
|
422
|
+
fs.ensureDirSync(path.dirname(scrutinCleanFilePath));
|
|
423
|
+
fs.writeFileSync(scrutinCleanFilePath, scrutinCleanJson, {
|
|
424
|
+
encoding: "utf8"
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (commitAndPush(datasetCleanDir, options, options.remote)) {
|
|
429
|
+
error = true;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (commitAndPushUid(datasetCleanDir, options, ["."])) {
|
|
433
|
+
error = true;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
} // Restore standard conversion of dates to JSON.
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
Date.prototype.toJSON = existingDateToJson;
|
|
440
|
+
return error;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function analyzeAndRemove(datasetName, options) {
|
|
444
|
+
const dataDir = options.dataDir;
|
|
445
|
+
const datasetRawDir = path.join(dataDir, datasetName);
|
|
446
|
+
const datasetCleanDir = datasetRawDir + "_nettoye";
|
|
447
|
+
|
|
448
|
+
if (!options.silent) {
|
|
449
|
+
console.log(`Cleaning directory: ${datasetCleanDir}…`);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
fs.ensureDirSync(datasetCleanDir);
|
|
453
|
+
|
|
454
|
+
for (const filename of fs.readdirSync(datasetCleanDir)) {
|
|
455
|
+
if (filename[0] === ".") {
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const pathname = path.join(datasetCleanDir, filename);
|
|
460
|
+
fs.removeSync(pathname);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function commitAndPush(repositoryDir, options, remotes) {
|
|
465
|
+
let error = false;
|
|
466
|
+
|
|
467
|
+
if (options.commit) {
|
|
468
|
+
git.commit(repositoryDir, "Nouvelle moisson");
|
|
469
|
+
|
|
470
|
+
for (const remote of remotes || []) {
|
|
471
|
+
try {
|
|
472
|
+
execSync(`git push ${remote} master`, {
|
|
473
|
+
cwd: repositoryDir,
|
|
474
|
+
env: process.env,
|
|
475
|
+
encoding: "utf-8",
|
|
476
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
477
|
+
});
|
|
478
|
+
} catch (childProcess) {
|
|
479
|
+
// Don't stop when push fails.
|
|
480
|
+
console.error(childProcess.output);
|
|
481
|
+
error = true;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
return error;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function commitAndPushUid(repositoryDir, options, subdirectories) {
|
|
490
|
+
let error = false;
|
|
491
|
+
|
|
492
|
+
if (options.commit) {
|
|
493
|
+
git.uidBranchUpdate(repositoryDir, subdirectories, options["no-reset-after-commit"]);
|
|
494
|
+
|
|
495
|
+
for (const remote of options.remote || []) {
|
|
496
|
+
try {
|
|
497
|
+
git.run(repositoryDir, `push --quiet ${remote} uid:uid`);
|
|
498
|
+
} catch (childProcess) {
|
|
499
|
+
error = true;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return error;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
function main(argv) {
|
|
508
|
+
const options = parseArgs(argv);
|
|
509
|
+
|
|
510
|
+
if (cleanReorganizedData(options)) {
|
|
511
|
+
return 1;
|
|
512
|
+
} else {
|
|
513
|
+
return 0;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
/* istanbul ignore if */
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
if (process.argv[1].endsWith("clean_reorganized_data.ts")) process.exit(main(process.argv));
|
|
520
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhc3NlcnQiLCJleGVjU3luYyIsImNvbW1hbmRMaW5lQXJncyIsImZzIiwicGF0aCIsImNsZWFuQWN0ZXVyIiwiY2xlYW5BbWVuZGVtZW50IiwiY2xlYW5Eb2N1bWVudE9yRGl2aXNpb24iLCJjbGVhbkRvc3NpZXJQYXJsZW1lbnRhaXJlIiwiY2xlYW5PcmdhbmUiLCJjbGVhblJldW5pb24iLCJjbGVhblNjcnV0aW4iLCJkYXRhc2V0cyIsIkVuYWJsZWREYXRhc2V0cyIsImV4aXN0aW5nRGF0ZVRvSnNvbiIsInBhdGNoZWREYXRlVG9Kc29uIiwid2Fsa0RpciIsImdpdCIsIkNvbnZlcnQiLCJBY3RldXJzRXRPcmdhbmVzQ29udmVydCIsIkFnZW5kYXNDb252ZXJ0IiwiQW1lbmRlbWVudHNDb252ZXJ0IiwiRG9zc2llcnNMZWdpc2xhdGlmc0NvbnZlcnQiLCJTY3J1dGluc0NvbnZlcnQiLCJwYXJzZUFyZ3MiLCJhcmd2Iiwib3B0aW9uc0RlZmluaXRpb25zIiwiYWxpYXMiLCJoZWxwIiwibmFtZSIsInR5cGUiLCJTdHJpbmciLCJCb29sZWFuIiwiZGVmYXVsdFZhbHVlIiwibXVsdGlwbGUiLCJkZWZhdWx0T3B0aW9uIiwib3B0aW9ucyIsImNsZWFuUmVvcmdhbml6ZWREYXRhIiwiZGF0YURpciIsIkRhdGUiLCJwcm90b3R5cGUiLCJ0b0pTT04iLCJlcnJvciIsImdpdEdyb3VwVXJsIiwiY2xvbmUiLCJ0cmltIiwicmVwbGFjZSIsInVuZGVmaW5lZCIsImNhdGVnb3JpZXMiLCJtYXAiLCJkYXRhc2V0TmFtZSIsIm5vdFN0cmljdEVxdWFsIiwiZW5hYmxlZERhdGFzZXRzIiwicmVkdWNlIiwiTm9uZSIsIkFjdGV1cnNFdE9yZ2FuZXMiLCJkYXRhc2V0IiwiYWN0ZXVyc0V0T3JnYW5lcyIsImJhc2VuYW1lIiwiZmlsZW5hbWUiLCJjd2QiLCJlbnYiLCJwcm9jZXNzIiwiZW5jb2RpbmciLCJzdGRpbyIsImFuYWx5emVBbmRSZW1vdmUiLCJkYXRhc2V0UmF3RGlyIiwiam9pbiIsImRhdGFzZXRDbGVhbkRpciIsImFjdGV1clNwbGl0UGF0aCIsImFjdGV1ckZpbGVuYW1lIiwibGVuZ3RoIiwiZW5kc1dpdGgiLCJhY3RldXJSYXdGaWxlUGF0aCIsInZlcmJvc2UiLCJjb25zb2xlIiwibG9nIiwiYWN0ZXVyUmF3SnNvbiIsInJlYWRGaWxlU3luYyIsImFjdGV1ciIsIkpTT04iLCJwYXJzZSIsImFjdGV1ckpzb24iLCJzdHJpbmdpZnkiLCJhY3RldXJDbGVhbiIsInRvQWN0ZXVyIiwiYWN0ZXVyQ2xlYW5Kc29uIiwiYWN0ZXVyVG9Kc29uIiwiYWN0ZXVyQ2xlYW5GaWxlUGF0aCIsImVuc3VyZURpclN5bmMiLCJkaXJuYW1lIiwid3JpdGVGaWxlU3luYyIsIm9yZ2FuZVNwbGl0UGF0aCIsIm9yZ2FuZUZpbGVuYW1lIiwib3JnYW5lUmF3RmlsZVBhdGgiLCJvcmdhbmVSYXdKc29uIiwib3JnYW5lIiwib3JnYW5lSnNvbiIsIm9yZ2FuZUNsZWFuIiwidG9PcmdhbmUiLCJvcmdhbmVDbGVhbkpzb24iLCJvcmdhbmVUb0pzb24iLCJvcmdhbmVDbGVhbkZpbGVQYXRoIiwiY29tbWl0QW5kUHVzaCIsInJlbW90ZSIsImNvbW1pdEFuZFB1c2hVaWQiLCJBZ2VuZGFzIiwiYWdlbmRhcyIsInJldW5pb25TcGxpdFBhdGgiLCJyZXVuaW9uRmlsZW5hbWUiLCJyZXVuaW9uUmF3RmlsZVBhdGgiLCJyZXVuaW9uUmF3SnNvbiIsInJldW5pb24iLCJyZXVuaW9uSnNvbiIsInJldW5pb25DbGVhbiIsInRvUmV1bmlvbiIsInJldW5pb25DbGVhbkpzb24iLCJyZXVuaW9uVG9Kc29uIiwicmV1bmlvbkNsZWFuRmlsZVBhdGgiLCJBbWVuZGVtZW50cyIsImFtZW5kZW1lbnRzIiwiYW1lbmRlbWVudFNwbGl0UGF0aCIsImFtZW5kZW1lbnRGaWxlbmFtZSIsImFtZW5kZW1lbnRSYXdGaWxlUGF0aCIsImFtZW5kZW1lbnRSYXdKc29uIiwiYW1lbmRlbWVudCIsImFtZW5kZW1lbnRKc29uIiwiYW1lbmRlbWVudENsZWFuIiwidG9BbWVuZGVtZW50IiwiYW1lbmRlbWVudENsZWFuSnNvbiIsImFtZW5kZW1lbnRUb0pzb24iLCJhbWVuZGVtZW50Q2xlYW5GaWxlUGF0aCIsIkRvc3NpZXJzTGVnaXNsYXRpZnMiLCJkb3NzaWVyc0xlZ2lzbGF0aWZzIiwiZG9jdW1lbnRTcGxpdFBhdGgiLCJkb2N1bWVudEZpbGVuYW1lIiwiZG9jdW1lbnRSYXdGaWxlUGF0aCIsImRvY3VtZW50UmF3SnNvbiIsImRvY3VtZW50IiwiZG9jdW1lbnRKc29uIiwiZG9jdW1lbnRDbGVhbiIsInRvRG9jdW1lbnQiLCJkb2N1bWVudENsZWFuSnNvbiIsImRvY3VtZW50VG9Kc29uIiwiZG9jdW1lbnRDbGVhbkZpbGVQYXRoIiwiZG9zc2llclNwbGl0UGF0aCIsImRvc3NpZXJGaWxlbmFtZSIsImRvc3NpZXJSYXdGaWxlUGF0aCIsImRvc3NpZXJSYXdKc29uIiwiZG9zc2llciIsImRvc3NpZXJKc29uIiwiZG9zc2llckNsZWFuIiwidG9Eb3NzaWVyUGFybGVtZW50YWlyZSIsImRvc3NpZXJDbGVhbkpzb24iLCJkb3NzaWVyUGFybGVtZW50YWlyZVRvSnNvbiIsImRvc3NpZXJDbGVhbkZpbGVQYXRoIiwiU2NydXRpbnMiLCJzY3J1dGlucyIsInNjcnV0aW5TcGxpdFBhdGgiLCJzY3J1dGluRmlsZW5hbWUiLCJzY3J1dGluUmF3RmlsZVBhdGgiLCJzY3J1dGluUmF3SnNvbiIsInNjcnV0aW4iLCJzY3J1dGluSnNvbiIsInNjcnV0aW5DbGVhbiIsInRvU2NydXRpbiIsInNjcnV0aW5DbGVhbkpzb24iLCJzY3J1dGluVG9Kc29uIiwic2NydXRpbkNsZWFuRmlsZVBhdGgiLCJzaWxlbnQiLCJyZWFkZGlyU3luYyIsInBhdGhuYW1lIiwicmVtb3ZlU3luYyIsInJlcG9zaXRvcnlEaXIiLCJyZW1vdGVzIiwiY29tbWl0IiwiY2hpbGRQcm9jZXNzIiwib3V0cHV0Iiwic3ViZGlyZWN0b3JpZXMiLCJ1aWRCcmFuY2hVcGRhdGUiLCJydW4iLCJtYWluIiwiZXhpdCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JpcHRzL2NsZWFuX3Jlb3JnYW5pemVkX2RhdGEudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCJcbmltcG9ydCB7IGV4ZWNTeW5jIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIlxuaW1wb3J0IGNvbW1hbmRMaW5lQXJncyBmcm9tIFwiY29tbWFuZC1saW5lLWFyZ3NcIlxuaW1wb3J0IGZzIGZyb20gXCJmcy1leHRyYVwiXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5cbmltcG9ydCB7XG4gIGNsZWFuQWN0ZXVyLFxuICBjbGVhbkFtZW5kZW1lbnQsXG4gIGNsZWFuRG9jdW1lbnRPckRpdmlzaW9uLFxuICBjbGVhbkRvc3NpZXJQYXJsZW1lbnRhaXJlLFxuICBjbGVhbk9yZ2FuZSxcbiAgY2xlYW5SZXVuaW9uLFxuICBjbGVhblNjcnV0aW4sXG59IGZyb20gXCIuLi9jbGVhbmVyc1wiXG5pbXBvcnQgeyBkYXRhc2V0cywgRW5hYmxlZERhdGFzZXRzIH0gZnJvbSBcIi4uL2RhdGFzZXRzXCJcbmltcG9ydCB7IGV4aXN0aW5nRGF0ZVRvSnNvbiwgcGF0Y2hlZERhdGVUb0pzb24gfSBmcm9tIFwiLi4vZGF0ZXNcIlxuaW1wb3J0IHsgd2Fsa0RpciB9IGZyb20gXCIuLi9maWxlX3N5c3RlbXNcIlxuaW1wb3J0ICogYXMgZ2l0IGZyb20gXCIuLi9naXRcIlxuaW1wb3J0IHtcbiAgQWN0ZXVyLFxuICBDb252ZXJ0IGFzIEFjdGV1cnNFdE9yZ2FuZXNDb252ZXJ0LFxuICBPcmdhbmUsXG59IGZyb20gXCIuLi90eXBlcy9hY3RldXJzX2V0X29yZ2FuZXNcIlxuaW1wb3J0IHsgQ29udmVydCBhcyBBZ2VuZGFzQ29udmVydCwgUmV1bmlvbiB9IGZyb20gXCIuLi90eXBlcy9hZ2VuZGFzXCJcbmltcG9ydCB7IEFtZW5kZW1lbnQsIENvbnZlcnQgYXMgQW1lbmRlbWVudHNDb252ZXJ0IH0gZnJvbSBcIi4uL3R5cGVzL2FtZW5kZW1lbnRzXCJcbmltcG9ydCB7XG4gIENvbnZlcnQgYXMgRG9zc2llcnNMZWdpc2xhdGlmc0NvbnZlcnQsXG4gIERvY3VtZW50LFxuICBEb3NzaWVyUGFybGVtZW50YWlyZSxcbn0gZnJvbSBcIi4uL3R5cGVzL2Rvc3NpZXJzX2xlZ2lzbGF0aWZzXCJcbmltcG9ydCB7IENvbnZlcnQgYXMgU2NydXRpbnNDb252ZXJ0LCBTY3J1dGluIH0gZnJvbSBcIi4uL3R5cGVzL3NjcnV0aW5zXCJcblxuZnVuY3Rpb24gcGFyc2VBcmdzKGFyZ3Y6IHN0cmluZ1tdKTogYW55IHtcbiAgY29uc3Qgb3B0aW9uc0RlZmluaXRpb25zID0gW1xuICAgIHtcbiAgICAgIGFsaWFzOiBcIkNcIixcbiAgICAgIGhlbHA6IFwiY2xvbmUgcmVwb3NpdG9yaWVzIGZyb20gZ2l2ZW4gZ3JvdXAgKG9yIG9yZ2FuaXphdGlvbikgZ2l0IFVSTFwiLFxuICAgICAgbmFtZTogXCJjbG9uZVwiLFxuICAgICAgdHlwZTogU3RyaW5nLFxuICAgIH0sXG4gICAge1xuICAgICAgYWxpYXM6IFwiY1wiLFxuICAgICAgaGVscDogXCJjb21taXQgY2xlYW4gZmlsZXNcIixcbiAgICAgIG5hbWU6IFwiY29tbWl0XCIsXG4gICAgICB0eXBlOiBCb29sZWFuLFxuICAgIH0sXG4gICAge1xuICAgICAgYWxpYXM6IFwiZFwiLFxuICAgICAgaGVscDogXCJzaW5nbGUgZGF0YXNldCB0byByZW9yZ2FuaXplXCIsXG4gICAgICBuYW1lOiBcImRhdGFzZXRcIixcbiAgICAgIHR5cGU6IFN0cmluZyxcbiAgICB9LFxuICAgIHtcbiAgICAgIGFsaWFzOiBcImtcIixcbiAgICAgIGRlZmF1bHRWYWx1ZTogW1wiQWxsXCJdLFxuICAgICAgaGVscDogXCJjYXRlZ29yaWVzIG9mIGRhdGFzZXRzIHRvIHJlb3JnYW5pemVcIixcbiAgICAgIG11bHRpcGxlOiB0cnVlLFxuICAgICAgbmFtZTogXCJjYXRlZ29yaWVzXCIsXG4gICAgICB0eXBlOiBTdHJpbmcsXG4gICAgfSxcbiAgICB7XG4gICAgICBhbGlhczogXCJyXCIsXG4gICAgICBoZWxwOiBcInB1c2ggY29tbWl0IHRvIGdpdmVuIHJlbW90ZVwiLFxuICAgICAgbXVsdGlwbGU6IHRydWUsXG4gICAgICBuYW1lOiBcInJlbW90ZVwiLFxuICAgICAgdHlwZTogU3RyaW5nLFxuICAgIH0sXG4gICAge1xuICAgICAgYWxpYXM6IFwic1wiLFxuICAgICAgaGVscDogXCJkb24ndCBsb2cgYW55dGhpbmdcIixcbiAgICAgIG5hbWU6IFwic2lsZW50XCIsXG4gICAgICB0eXBlOiBCb29sZWFuLFxuICAgIH0sXG4gICAge1xuICAgICAgaGVscDogXCJkbyBub3QgcmVzZXQgLS1oYXJkIGFmdGVyIGNvbW1pdCB0byBzYXZlIEkvTyBpZiB0aGUgd29ya2luZyB0cmVlIGlzIHRvIGJlIGRpc2NhcmRlZFwiLFxuICAgICAgbmFtZTogXCJuby1yZXNldC1hZnRlci1jb21taXRcIixcbiAgICAgIHR5cGU6IEJvb2xlYW4sXG4gICAgfSxcbiAgICB7XG4gICAgICBhbGlhczogXCJ2XCIsXG4gICAgICBoZWxwOiBcInZlcmJvc2UgbG9nc1wiLFxuICAgICAgbmFtZTogXCJ2ZXJib3NlXCIsXG4gICAgICB0eXBlOiBCb29sZWFuLFxuICAgIH0sXG4gICAge1xuICAgICAgZGVmYXVsdE9wdGlvbjogdHJ1ZSxcbiAgICAgIGhlbHA6IFwiZGlyZWN0b3J5IGNvbnRhaW5pbmcgQXNzZW1ibMOpZSBvcGVuIGRhdGEgZmlsZXNcIixcbiAgICAgIG5hbWU6IFwiZGF0YURpclwiLFxuICAgICAgdHlwZTogU3RyaW5nLFxuICAgIH0sXG4gIF1cbiAgY29uc3Qgb3B0aW9ucyA9IGNvbW1hbmRMaW5lQXJncyhvcHRpb25zRGVmaW5pdGlvbnMsIHtcbiAgICBhcmd2OiBhcmd2LFxuICB9KVxuICByZXR1cm4gb3B0aW9uc1xufVxuXG5mdW5jdGlvbiBjbGVhblJlb3JnYW5pemVkRGF0YShvcHRpb25zOiBhbnkpOiBib29sZWFuIHtcbiAgY29uc3QgZGF0YURpcjogc3RyaW5nID0gb3B0aW9ucy5kYXRhRGlyXG5cbiAgRGF0ZS5wcm90b3R5cGUudG9KU09OID0gcGF0Y2hlZERhdGVUb0pzb25cblxuICBsZXQgZXJyb3IgPSBmYWxzZVxuICBjb25zdCBnaXRHcm91cFVybCA9IG9wdGlvbnMuY2xvbmVcbiAgICA/IG9wdGlvbnMuY2xvbmUudHJpbSgpLnJlcGxhY2UoL1xcLyskLywgXCJcIilcbiAgICA6IHVuZGVmaW5lZFxuXG4gIG9wdGlvbnMuY2F0ZWdvcmllcy5tYXAoKGRhdGFzZXROYW1lOiBzdHJpbmcpID0+XG4gICAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKFxuICAgICAgKEVuYWJsZWREYXRhc2V0cyBhcyBhbnkgYXMgeyBbbmFtZTogc3RyaW5nXTogRW5hYmxlZERhdGFzZXRzIH0pW1xuICAgICAgICBkYXRhc2V0TmFtZVxuICAgICAgXSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIGBVbmtub3duIG5hbWUgb2YgZGF0YXNldDogJHtkYXRhc2V0TmFtZX1gLFxuICAgICksXG4gIClcbiAgY29uc3QgZW5hYmxlZERhdGFzZXRzID0gb3B0aW9ucy5jYXRlZ29yaWVzLnJlZHVjZShcbiAgICAoZW5hYmxlZERhdGFzZXRzOiBFbmFibGVkRGF0YXNldHMsIGRhdGFzZXROYW1lOiBzdHJpbmcpOiBFbmFibGVkRGF0YXNldHMgPT5cbiAgICAgIGVuYWJsZWREYXRhc2V0cyB8XG4gICAgICAoRW5hYmxlZERhdGFzZXRzIGFzIGFueSBhcyB7IFtuYW1lOiBzdHJpbmddOiBFbmFibGVkRGF0YXNldHMgfSlbXG4gICAgICAgIGRhdGFzZXROYW1lXG4gICAgICBdLFxuICAgIEVuYWJsZWREYXRhc2V0cy5Ob25lLFxuICApXG5cbiAgaWYgKGVuYWJsZWREYXRhc2V0cyAmIEVuYWJsZWREYXRhc2V0cy5BY3RldXJzRXRPcmdhbmVzKSB7XG4gICAgZm9yIChjb25zdCBkYXRhc2V0IG9mIGRhdGFzZXRzLmFjdGV1cnNFdE9yZ2FuZXMpIHtcbiAgICAgIGNvbnN0IGRhdGFzZXROYW1lID0gcGF0aC5iYXNlbmFtZShkYXRhc2V0LmZpbGVuYW1lLCBcIi5qc29uXCIpXG4gICAgICBpZiAob3B0aW9ucy5kYXRhc2V0ICYmIGRhdGFzZXROYW1lICE9PSBvcHRpb25zLmRhdGFzZXQpIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGdpdEdyb3VwVXJsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZXhlY1N5bmMoYGdpdCBjbG9uZSAke2dpdEdyb3VwVXJsfS8ke2RhdGFzZXROYW1lfV9uZXR0b3llLmdpdGAsIHtcbiAgICAgICAgICBjd2Q6IGRhdGFEaXIsXG4gICAgICAgICAgZW52OiBwcm9jZXNzLmVudixcbiAgICAgICAgICBlbmNvZGluZzogXCJ1dGYtOFwiLFxuICAgICAgICAgIHN0ZGlvOiBbXCJpZ25vcmVcIiwgXCJpZ25vcmVcIiwgXCJwaXBlXCJdLFxuICAgICAgICB9KVxuICAgICAgfVxuICAgICAgYW5hbHl6ZUFuZFJlbW92ZShkYXRhc2V0TmFtZSwgb3B0aW9ucylcbiAgICAgIGNvbnN0IGRhdGFzZXRSYXdEaXI6IHN0cmluZyA9IHBhdGguam9pbihkYXRhRGlyLCBkYXRhc2V0TmFtZSlcbiAgICAgIGNvbnN0IGRhdGFzZXRDbGVhbkRpcjogc3RyaW5nID0gZGF0YXNldFJhd0RpciArIFwiX25ldHRveWVcIlxuICAgICAgZm9yIChjb25zdCBhY3RldXJTcGxpdFBhdGggb2Ygd2Fsa0RpcihkYXRhc2V0UmF3RGlyLCBbXCJhY3RldXJzXCJdKSkge1xuICAgICAgICBjb25zdCBhY3RldXJGaWxlbmFtZSA9IGFjdGV1clNwbGl0UGF0aFthY3RldXJTcGxpdFBhdGgubGVuZ3RoIC0gMV1cbiAgICAgICAgaWYgKCFhY3RldXJGaWxlbmFtZS5lbmRzV2l0aChcIi5qc29uXCIpKSB7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhY3RldXJSYXdGaWxlUGF0aCA9IHBhdGguam9pbihkYXRhc2V0UmF3RGlyLCAuLi5hY3RldXJTcGxpdFBhdGgpXG4gICAgICAgIGlmIChvcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgICBDbGVhbmluZyBmaWxlOiAke2FjdGV1clJhd0ZpbGVQYXRofeKApmApXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYWN0ZXVyUmF3SnNvbjogc3RyaW5nID0gZnMucmVhZEZpbGVTeW5jKGFjdGV1clJhd0ZpbGVQYXRoLCB7XG4gICAgICAgICAgZW5jb2Rpbmc6IFwidXRmOFwiLFxuICAgICAgICB9KVxuICAgICAgICBjb25zdCBhY3RldXIgPSBKU09OLnBhcnNlKGFjdGV1clJhd0pzb24pXG4gICAgICAgIGNsZWFuQWN0ZXVyKGFjdGV1cilcbiAgICAgICAgY29uc3QgYWN0ZXVySnNvbjogc3RyaW5nID0gSlNPTi5zdHJpbmdpZnkoYWN0ZXVyLCBudWxsLCAyKVxuXG4gICAgICAgIC8vIFZhbGlkYXRlIGdlbmVyYXRlZCBKU09OLlxuICAgICAgICBjb25zdCBhY3RldXJDbGVhbjogQWN0ZXVyID0gQWN0ZXVyc0V0T3JnYW5lc0NvbnZlcnQudG9BY3RldXIoYWN0ZXVySnNvbilcbiAgICAgICAgY29uc3QgYWN0ZXVyQ2xlYW5Kc29uOiBzdHJpbmcgPVxuICAgICAgICAgIEFjdGV1cnNFdE9yZ2FuZXNDb252ZXJ0LmFjdGV1clRvSnNvbihhY3RldXJDbGVhbilcblxuICAgICAgICBjb25zdCBhY3RldXJDbGVhbkZpbGVQYXRoOiBzdHJpbmcgPSBwYXRoLmpvaW4oXG4gICAgICAgICAgZGF0YXNldENsZWFuRGlyLFxuICAgICAgICAgIC4uLmFjdGV1clNwbGl0UGF0aCxcbiAgICAgICAgKVxuICAgICAgICBmcy5lbnN1cmVEaXJTeW5jKHBhdGguZGlybmFtZShhY3RldXJDbGVhbkZpbGVQYXRoKSlcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhhY3RldXJDbGVhbkZpbGVQYXRoLCBhY3RldXJDbGVhbkpzb24sIHtcbiAgICAgICAgICBlbmNvZGluZzogXCJ1dGY4XCIsXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3Qgb3JnYW5lU3BsaXRQYXRoIG9mIHdhbGtEaXIoZGF0YXNldFJhd0RpciwgW1wib3JnYW5lc1wiXSkpIHtcbiAgICAgICAgY29uc3Qgb3JnYW5lRmlsZW5hbWUgPSBvcmdhbmVTcGxpdFBhdGhbb3JnYW5lU3BsaXRQYXRoLmxlbmd0aCAtIDFdXG4gICAgICAgIGlmICghb3JnYW5lRmlsZW5hbWUuZW5kc1dpdGgoXCIuanNvblwiKSkge1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3JnYW5lUmF3RmlsZVBhdGggPSBwYXRoLmpvaW4oZGF0YXNldFJhd0RpciwgLi4ub3JnYW5lU3BsaXRQYXRoKVxuICAgICAgICBpZiAob3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYCAgQ2xlYW5pbmcgZmlsZTogJHtvcmdhbmVSYXdGaWxlUGF0aH3igKZgKVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9yZ2FuZVJhd0pzb246IHN0cmluZyA9IGZzLnJlYWRGaWxlU3luYyhvcmdhbmVSYXdGaWxlUGF0aCwge1xuICAgICAgICAgIGVuY29kaW5nOiBcInV0ZjhcIixcbiAgICAgICAgfSlcbiAgICAgICAgY29uc3Qgb3JnYW5lID0gSlNPTi5wYXJzZShvcmdhbmVSYXdKc29uKVxuICAgICAgICBjbGVhbk9yZ2FuZShvcmdhbmUpXG4gICAgICAgIGNvbnN0IG9yZ2FuZUpzb246IHN0cmluZyA9IEpTT04uc3RyaW5naWZ5KG9yZ2FuZSwgbnVsbCwgMilcblxuICAgICAgICAvLyBWYWxpZGF0ZSBnZW5lcmF0ZWQgSlNPTi5cbiAgICAgICAgY29uc3Qgb3JnYW5lQ2xlYW46IE9yZ2FuZSA9IEFjdGV1cnNFdE9yZ2FuZXNDb252ZXJ0LnRvT3JnYW5lKG9yZ2FuZUpzb24pXG4gICAgICAgIGNvbnN0IG9yZ2FuZUNsZWFuSnNvbjogc3RyaW5nID1cbiAgICAgICAgICBBY3RldXJzRXRPcmdhbmVzQ29udmVydC5vcmdhbmVUb0pzb24ob3JnYW5lQ2xlYW4pXG5cbiAgICAgICAgY29uc3Qgb3JnYW5lQ2xlYW5GaWxlUGF0aDogc3RyaW5nID0gcGF0aC5qb2luKFxuICAgICAgICAgIGRhdGFzZXRDbGVhbkRpcixcbiAgICAgICAgICAuLi5vcmdhbmVTcGxpdFBhdGgsXG4gICAgICAgIClcbiAgICAgICAgZnMuZW5zdXJlRGlyU3luYyhwYXRoLmRpcm5hbWUob3JnYW5lQ2xlYW5GaWxlUGF0aCkpXG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMob3JnYW5lQ2xlYW5GaWxlUGF0aCwgb3JnYW5lQ2xlYW5Kc29uLCB7XG4gICAgICAgICAgZW5jb2Rpbmc6IFwidXRmOFwiLFxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBpZiAoY29tbWl0QW5kUHVzaChkYXRhc2V0Q2xlYW5EaXIsIG9wdGlvbnMsIG9wdGlvbnMucmVtb3RlKSkge1xuICAgICAgICBlcnJvciA9IHRydWVcbiAgICAgIH1cbiAgICAgIGlmIChjb21taXRBbmRQdXNoVWlkKGRhdGFzZXRDbGVhbkRpciwgb3B0aW9ucywgW1wiYWN0ZXVyc1wiLCBcIm9yZ2FuZXNcIl0pKSB7XG4gICAgICAgIGVycm9yID0gdHJ1ZVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChlbmFibGVkRGF0YXNldHMgJiBFbmFibGVkRGF0YXNldHMuQWdlbmRhcykge1xuICAgIGZvciAoY29uc3QgZGF0YXNldCBvZiBkYXRhc2V0cy5hZ2VuZGFzKSB7XG4gICAgICBjb25zdCBkYXRhc2V0TmFtZSA9IHBhdGguYmFzZW5hbWUoZGF0YXNldC5maWxlbmFtZSwgXCIuanNvblwiKVxuICAgICAgaWYgKG9wdGlvbnMuZGF0YXNldCAmJiBkYXRhc2V0TmFtZSAhPT0gb3B0aW9ucy5kYXRhc2V0KSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChnaXRHcm91cFVybCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGV4ZWNTeW5jKGBnaXQgY2xvbmUgJHtnaXRHcm91cFVybH0vJHtkYXRhc2V0TmFtZX1fbmV0dG95ZS5naXRgLCB7XG4gICAgICAgICAgY3dkOiBkYXRhRGlyLFxuICAgICAgICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgICAgICAgZW5jb2Rpbmc6IFwidXRmLThcIixcbiAgICAgICAgICBzdGRpbzogW1wiaWdub3JlXCIsIFwiaWdub3JlXCIsIFwicGlwZVwiXSxcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIGFuYWx5emVBbmRSZW1vdmUoZGF0YXNldE5hbWUsIG9wdGlvbnMpXG4gICAgICBjb25zdCBkYXRhc2V0UmF3RGlyOiBzdHJpbmcgPSBwYXRoLmpvaW4oZGF0YURpciwgZGF0YXNldE5hbWUpXG4gICAgICBjb25zdCBkYXRhc2V0Q2xlYW5EaXI6IHN0cmluZyA9IGRhdGFzZXRSYXdEaXIgKyBcIl9uZXR0b3llXCJcbiAgICAgIGZvciAoY29uc3QgcmV1bmlvblNwbGl0UGF0aCBvZiB3YWxrRGlyKGRhdGFzZXRSYXdEaXIpKSB7XG4gICAgICAgIGNvbnN0IHJldW5pb25GaWxlbmFtZSA9IHJldW5pb25TcGxpdFBhdGhbcmV1bmlvblNwbGl0UGF0aC5sZW5ndGggLSAxXVxuICAgICAgICBpZiAoIXJldW5pb25GaWxlbmFtZS5lbmRzV2l0aChcIi5qc29uXCIpKSB7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXVuaW9uUmF3RmlsZVBhdGggPSBwYXRoLmpvaW4oZGF0YXNldFJhd0RpciwgLi4ucmV1bmlvblNwbGl0UGF0aClcbiAgICAgICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgIENsZWFuaW5nIGZpbGU6ICR7cmV1bmlvblJhd0ZpbGVQYXRofeKApmApXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmV1bmlvblJhd0pzb246IHN0cmluZyA9IGZzLnJlYWRGaWxlU3luYyhyZXVuaW9uUmF3RmlsZVBhdGgsIHtcbiAgICAgICAgICBlbmNvZGluZzogXCJ1dGY4XCIsXG4gICAgICAgIH0pXG4gICAgICAgIGNvbnN0IHJldW5pb24gPSBKU09OLnBhcnNlKHJldW5pb25SYXdKc29uKVxuICAgICAgICBjbGVhblJldW5pb24ocmV1bmlvbilcbiAgICAgICAgY29uc3QgcmV1bmlvbkpzb246IHN0cmluZyA9IEpTT04uc3RyaW5naWZ5KHJldW5pb24sIG51bGwsIDIpXG5cbiAgICAgICAgLy8gVmFsaWRhdGUgZ2VuZXJhdGVkIEpTT04uXG4gICAgICAgIGNvbnN0IHJldW5pb25DbGVhbjogUmV1bmlvbiA9IEFnZW5kYXNDb252ZXJ0LnRvUmV1bmlvbihyZXVuaW9uSnNvbilcbiAgICAgICAgY29uc3QgcmV1bmlvbkNsZWFuSnNvbjogc3RyaW5nID1cbiAgICAgICAgICBBZ2VuZGFzQ29udmVydC5yZXVuaW9uVG9Kc29uKHJldW5pb25DbGVhbilcblxuICAgICAgICBjb25zdCByZXVuaW9uQ2xlYW5GaWxlUGF0aDogc3RyaW5nID0gcGF0aC5qb2luKFxuICAgICAgICAgIGRhdGFzZXRDbGVhbkRpcixcbiAgICAgICAgICAuLi5yZXVuaW9uU3BsaXRQYXRoLFxuICAgICAgICApXG4gICAgICAgIGZzLmVuc3VyZURpclN5bmMocGF0aC5kaXJuYW1lKHJldW5pb25DbGVhbkZpbGVQYXRoKSlcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhyZXVuaW9uQ2xlYW5GaWxlUGF0aCwgcmV1bmlvbkNsZWFuSnNvbiwge1xuICAgICAgICAgIGVuY29kaW5nOiBcInV0ZjhcIixcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbW1pdEFuZFB1c2goZGF0YXNldENsZWFuRGlyLCBvcHRpb25zLCBvcHRpb25zLnJlbW90ZSkpIHtcbiAgICAgICAgZXJyb3IgPSB0cnVlXG4gICAgICB9XG4gICAgICBpZiAoY29tbWl0QW5kUHVzaFVpZChkYXRhc2V0Q2xlYW5EaXIsIG9wdGlvbnMsIFtcIi5cIl0pKSB7XG4gICAgICAgIGVycm9yID0gdHJ1ZVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChlbmFibGVkRGF0YXNldHMgJiBFbmFibGVkRGF0YXNldHMuQW1lbmRlbWVudHMpIHtcbiAgICBmb3IgKGNvbnN0IGRhdGFzZXQgb2YgZGF0YXNldHMuYW1lbmRlbWVudHMpIHtcbiAgICAgIGNvbnN0IGRhdGFzZXROYW1lID0gcGF0aC5iYXNlbmFtZShkYXRhc2V0LmZpbGVuYW1lLCBcIi5qc29uXCIpXG4gICAgICBpZiAob3B0aW9ucy5kYXRhc2V0ICYmIGRhdGFzZXROYW1lICE9PSBvcHRpb25zLmRhdGFzZXQpIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGdpdEdyb3VwVXJsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZXhlY1N5bmMoYGdpdCBjbG9uZSAke2dpdEdyb3VwVXJsfS8ke2RhdGFzZXROYW1lfV9uZXR0b3llLmdpdGAsIHtcbiAgICAgICAgICBjd2Q6IGRhdGFEaXIsXG4gICAgICAgICAgZW52OiBwcm9jZXNzLmVudixcbiAgICAgICAgICBlbmNvZGluZzogXCJ1dGYtOFwiLFxuICAgICAgICAgIHN0ZGlvOiBbXCJpZ25vcmVcIiwgXCJpZ25vcmVcIiwgXCJwaXBlXCJdLFxuICAgICAgICB9KVxuICAgICAgfVxuICAgICAgYW5hbHl6ZUFuZFJlbW92ZShkYXRhc2V0TmFtZSwgb3B0aW9ucylcbiAgICAgIGNvbnN0IGRhdGFzZXRSYXdEaXI6IHN0cmluZyA9IHBhdGguam9pbihkYXRhRGlyLCBkYXRhc2V0TmFtZSlcbiAgICAgIGNvbnN0IGRhdGFzZXRDbGVhbkRpcjogc3RyaW5nID0gZGF0YXNldFJhd0RpciArIFwiX25ldHRveWVcIlxuICAgICAgZm9yIChjb25zdCBhbWVuZGVtZW50U3BsaXRQYXRoIG9mIHdhbGtEaXIoZGF0YXNldFJhd0RpcikpIHtcbiAgICAgICAgY29uc3QgYW1lbmRlbWVudEZpbGVuYW1lID1cbiAgICAgICAgICBhbWVuZGVtZW50U3BsaXRQYXRoW2FtZW5kZW1lbnRTcGxpdFBhdGgubGVuZ3RoIC0gMV1cbiAgICAgICAgaWYgKCFhbWVuZGVtZW50RmlsZW5hbWUuZW5kc1dpdGgoXCIuanNvblwiKSkge1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYW1lbmRlbWVudFJhd0ZpbGVQYXRoID0gcGF0aC5qb2luKFxuICAgICAgICAgIGRhdGFzZXRSYXdEaXIsXG4gICAgICAgICAgLi4uYW1lbmRlbWVudFNwbGl0UGF0aCxcbiAgICAgICAgKVxuICAgICAgICBpZiAob3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYCAgQ2xlYW5pbmcgZmlsZTogJHthbWVuZGVtZW50UmF3RmlsZVBhdGh94oCmYClcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhbWVuZGVtZW50UmF3SnNvbjogc3RyaW5nID0gZnMucmVhZEZpbGVTeW5jKFxuICAgICAgICAgIGFtZW5kZW1lbnRSYXdGaWxlUGF0aCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBlbmNvZGluZzogXCJ1dGY4XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgKVxuICAgICAgICBjb25zdCBhbWVuZGVtZW50ID0gSlNPTi5wYXJzZShhbWVuZGVtZW50UmF3SnNvbilcbiAgICAgICAgY2xlYW5BbWVuZGVtZW50KGFtZW5kZW1lbnQpXG4gICAgICAgIGNvbnN0IGFtZW5kZW1lbnRKc29uOiBzdHJpbmcgPSBKU09OLnN0cmluZ2lmeShhbWVuZGVtZW50LCBudWxsLCAyKVxuXG4gICAgICAgIC8vIFZhbGlkYXRlIGdlbmVyYXRlZCBKU09OLlxuICAgICAgICBjb25zdCBhbWVuZGVtZW50Q2xlYW46IEFtZW5kZW1lbnQgPVxuICAgICAgICAgIEFtZW5kZW1lbnRzQ29udmVydC50b0FtZW5kZW1lbnQoYW1lbmRlbWVudEpzb24pXG4gICAgICAgIGNvbnN0IGFtZW5kZW1lbnRDbGVhbkpzb246IHN0cmluZyA9XG4gICAgICAgICAgQW1lbmRlbWVudHNDb252ZXJ0LmFtZW5kZW1lbnRUb0pzb24oYW1lbmRlbWVudENsZWFuKVxuXG4gICAgICAgIGNvbnN0IGFtZW5kZW1lbnRDbGVhbkZpbGVQYXRoOiBzdHJpbmcgPSBwYXRoLmpvaW4oXG4gICAgICAgICAgZGF0YXNldENsZWFuRGlyLFxuICAgICAgICAgIC4uLmFtZW5kZW1lbnRTcGxpdFBhdGgsXG4gICAgICAgIClcbiAgICAgICAgZnMuZW5zdXJlRGlyU3luYyhwYXRoLmRpcm5hbWUoYW1lbmRlbWVudENsZWFuRmlsZVBhdGgpKVxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKGFtZW5kZW1lbnRDbGVhbkZpbGVQYXRoLCBhbWVuZGVtZW50Q2xlYW5Kc29uLCB7XG4gICAgICAgICAgZW5jb2Rpbmc6IFwidXRmOFwiLFxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBpZiAoY29tbWl0QW5kUHVzaChkYXRhc2V0Q2xlYW5EaXIsIG9wdGlvbnMsIG9wdGlvbnMucmVtb3RlKSkge1xuICAgICAgICBlcnJvciA9IHRydWVcbiAgICAgIH1cbiAgICAgIGlmIChjb21taXRBbmRQdXNoVWlkKGRhdGFzZXRDbGVhbkRpciwgb3B0aW9ucywgW1wiLlwiXSkpIHtcbiAgICAgICAgZXJyb3IgPSB0cnVlXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGVuYWJsZWREYXRhc2V0cyAmIEVuYWJsZWREYXRhc2V0cy5Eb3NzaWVyc0xlZ2lzbGF0aWZzKSB7XG4gICAgZm9yIChjb25zdCBkYXRhc2V0IG9mIGRhdGFzZXRzLmRvc3NpZXJzTGVnaXNsYXRpZnMpIHtcbiAgICAgIGNvbnN0IGRhdGFzZXROYW1lID0gcGF0aC5iYXNlbmFtZShkYXRhc2V0LmZpbGVuYW1lLCBcIi5qc29uXCIpXG4gICAgICBpZiAob3B0aW9ucy5kYXRhc2V0ICYmIGRhdGFzZXROYW1lICE9PSBvcHRpb25zLmRhdGFzZXQpIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGdpdEdyb3VwVXJsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZXhlY1N5bmMoYGdpdCBjbG9uZSAke2dpdEdyb3VwVXJsfS8ke2RhdGFzZXROYW1lfV9uZXR0b3llLmdpdGAsIHtcbiAgICAgICAgICBjd2Q6IGRhdGFEaXIsXG4gICAgICAgICAgZW52OiBwcm9jZXNzLmVudixcbiAgICAgICAgICBlbmNvZGluZzogXCJ1dGYtOFwiLFxuICAgICAgICAgIHN0ZGlvOiBbXCJpZ25vcmVcIiwgXCJpZ25vcmVcIiwgXCJwaXBlXCJdLFxuICAgICAgICB9KVxuICAgICAgfVxuICAgICAgYW5hbHl6ZUFuZFJlbW92ZShkYXRhc2V0TmFtZSwgb3B0aW9ucylcbiAgICAgIGNvbnN0IGRhdGFzZXRSYXdEaXI6IHN0cmluZyA9IHBhdGguam9pbihkYXRhRGlyLCBkYXRhc2V0TmFtZSlcbiAgICAgIGNvbnN0IGRhdGFzZXRDbGVhbkRpcjogc3RyaW5nID0gZGF0YXNldFJhd0RpciArIFwiX25ldHRveWVcIlxuICAgICAgZm9yIChjb25zdCBkb2N1bWVudFNwbGl0UGF0aCBvZiB3YWxrRGlyKGRhdGFzZXRSYXdEaXIsIFtcImRvY3VtZW50c1wiXSkpIHtcbiAgICAgICAgY29uc3QgZG9jdW1lbnRGaWxlbmFtZSA9IGRvY3VtZW50U3BsaXRQYXRoW2RvY3VtZW50U3BsaXRQYXRoLmxlbmd0aCAtIDFdXG4gICAgICAgIGlmICghZG9jdW1lbnRGaWxlbmFtZS5lbmRzV2l0aChcIi5qc29uXCIpKSB7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkb2N1bWVudFJhd0ZpbGVQYXRoID0gcGF0aC5qb2luKFxuICAgICAgICAgIGRhdGFzZXRSYXdEaXIsXG4gICAgICAgICAgLi4uZG9jdW1lbnRTcGxpdFBhdGgsXG4gICAgICAgIClcbiAgICAgICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgIENsZWFuaW5nIGZpbGU6ICR7ZG9jdW1lbnRSYXdGaWxlUGF0aH3igKZgKVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRvY3VtZW50UmF3SnNvbjogc3RyaW5nID0gZnMucmVhZEZpbGVTeW5jKGRvY3VtZW50UmF3RmlsZVBhdGgsIHtcbiAgICAgICAgICBlbmNvZGluZzogXCJ1dGY4XCIsXG4gICAgICAgIH0pXG4gICAgICAgIGNvbnN0IGRvY3VtZW50ID0gSlNPTi5wYXJzZShkb2N1bWVudFJhd0pzb24pXG4gICAgICAgIGNsZWFuRG9jdW1lbnRPckRpdmlzaW9uKGRvY3VtZW50KVxuICAgICAgICBjb25zdCBkb2N1bWVudEpzb246IHN0cmluZyA9IEpTT04uc3RyaW5naWZ5KGRvY3VtZW50LCBudWxsLCAyKVxuXG4gICAgICAgIC8vIFZhbGlkYXRlIGdlbmVyYXRlZCBKU09OLlxuICAgICAgICBjb25zdCBkb2N1bWVudENsZWFuOiBEb2N1bWVudCA9XG4gICAgICAgICAgRG9zc2llcnNMZWdpc2xhdGlmc0NvbnZlcnQudG9Eb2N1bWVudChkb2N1bWVudEpzb24pXG4gICAgICAgIGNvbnN0IGRvY3VtZW50Q2xlYW5Kc29uOiBzdHJpbmcgPVxuICAgICAgICAgIERvc3NpZXJzTGVnaXNsYXRpZnNDb252ZXJ0LmRvY3VtZW50VG9Kc29uKGRvY3VtZW50Q2xlYW4pXG5cbiAgICAgICAgY29uc3QgZG9jdW1lbnRDbGVhbkZpbGVQYXRoOiBzdHJpbmcgPSBwYXRoLmpvaW4oXG4gICAgICAgICAgZGF0YXNldENsZWFuRGlyLFxuICAgICAgICAgIC4uLmRvY3VtZW50U3BsaXRQYXRoLFxuICAgICAgICApXG4gICAgICAgIGZzLmVuc3VyZURpclN5bmMocGF0aC5kaXJuYW1lKGRvY3VtZW50Q2xlYW5GaWxlUGF0aCkpXG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoZG9jdW1lbnRDbGVhbkZpbGVQYXRoLCBkb2N1bWVudENsZWFuSnNvbiwge1xuICAgICAgICAgIGVuY29kaW5nOiBcInV0ZjhcIixcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBkb3NzaWVyU3BsaXRQYXRoIG9mIHdhbGtEaXIoZGF0YXNldFJhd0RpciwgW1wiZG9zc2llcnNcIl0pKSB7XG4gICAgICAgIGNvbnN0IGRvc3NpZXJGaWxlbmFtZSA9IGRvc3NpZXJTcGxpdFBhdGhbZG9zc2llclNwbGl0UGF0aC5sZW5ndGggLSAxXVxuICAgICAgICBpZiAoIWRvc3NpZXJGaWxlbmFtZS5lbmRzV2l0aChcIi5qc29uXCIpKSB7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkb3NzaWVyUmF3RmlsZVBhdGggPSBwYXRoLmpvaW4oZGF0YXNldFJhd0RpciwgLi4uZG9zc2llclNwbGl0UGF0aClcbiAgICAgICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgIENsZWFuaW5nIGZpbGU6ICR7ZG9zc2llclJhd0ZpbGVQYXRofeKApmApXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZG9zc2llclJhd0pzb246IHN0cmluZyA9IGZzLnJlYWRGaWxlU3luYyhkb3NzaWVyUmF3RmlsZVBhdGgsIHtcbiAgICAgICAgICBlbmNvZGluZzogXCJ1dGY4XCIsXG4gICAgICAgIH0pXG4gICAgICAgIGNvbnN0IGRvc3NpZXIgPSBKU09OLnBhcnNlKGRvc3NpZXJSYXdKc29uKVxuICAgICAgICBjbGVhbkRvc3NpZXJQYXJsZW1lbnRhaXJlKGRvc3NpZXIpXG4gICAgICAgIGNvbnN0IGRvc3NpZXJKc29uOiBzdHJpbmcgPSBKU09OLnN0cmluZ2lmeShkb3NzaWVyLCBudWxsLCAyKVxuXG4gICAgICAgIC8vIFZhbGlkYXRlIGdlbmVyYXRlZCBKU09OLlxuICAgICAgICBjb25zdCBkb3NzaWVyQ2xlYW46IERvc3NpZXJQYXJsZW1lbnRhaXJlID1cbiAgICAgICAgICBEb3NzaWVyc0xlZ2lzbGF0aWZzQ29udmVydC50b0Rvc3NpZXJQYXJsZW1lbnRhaXJlKGRvc3NpZXJKc29uKVxuICAgICAgICBjb25zdCBkb3NzaWVyQ2xlYW5Kc29uOiBzdHJpbmcgPVxuICAgICAgICAgIERvc3NpZXJzTGVnaXNsYXRpZnNDb252ZXJ0LmRvc3NpZXJQYXJsZW1lbnRhaXJlVG9Kc29uKGRvc3NpZXJDbGVhbilcblxuICAgICAgICBjb25zdCBkb3NzaWVyQ2xlYW5GaWxlUGF0aDogc3RyaW5nID0gcGF0aC5qb2luKFxuICAgICAgICAgIGRhdGFzZXRDbGVhbkRpcixcbiAgICAgICAgICAuLi5kb3NzaWVyU3BsaXRQYXRoLFxuICAgICAgICApXG4gICAgICAgIGZzLmVuc3VyZURpclN5bmMocGF0aC5kaXJuYW1lKGRvc3NpZXJDbGVhbkZpbGVQYXRoKSlcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhkb3NzaWVyQ2xlYW5GaWxlUGF0aCwgZG9zc2llckNsZWFuSnNvbiwge1xuICAgICAgICAgIGVuY29kaW5nOiBcInV0ZjhcIixcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbW1pdEFuZFB1c2goZGF0YXNldENsZWFuRGlyLCBvcHRpb25zLCBvcHRpb25zLnJlbW90ZSkpIHtcbiAgICAgICAgZXJyb3IgPSB0cnVlXG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIGNvbW1pdEFuZFB1c2hVaWQoZGF0YXNldENsZWFuRGlyLCBvcHRpb25zLCBbXCJkb2N1bWVudHNcIiwgXCJkb3NzaWVyc1wiXSlcbiAgICAgICkge1xuICAgICAgICBlcnJvciA9IHRydWVcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoZW5hYmxlZERhdGFzZXRzICYgRW5hYmxlZERhdGFzZXRzLlNjcnV0aW5zKSB7XG4gICAgZm9yIChjb25zdCBkYXRhc2V0IG9mIGRhdGFzZXRzLnNjcnV0aW5zKSB7XG4gICAgICBjb25zdCBkYXRhc2V0TmFtZSA9IHBhdGguYmFzZW5hbWUoZGF0YXNldC5maWxlbmFtZSwgXCIuanNvblwiKVxuICAgICAgaWYgKG9wdGlvbnMuZGF0YXNldCAmJiBkYXRhc2V0TmFtZSAhPT0gb3B0aW9ucy5kYXRhc2V0KSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChnaXRHcm91cFVybCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGV4ZWNTeW5jKGBnaXQgY2xvbmUgJHtnaXRHcm91cFVybH0vJHtkYXRhc2V0TmFtZX1fbmV0dG95ZS5naXRgLCB7XG4gICAgICAgICAgY3dkOiBkYXRhRGlyLFxuICAgICAgICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgICAgICAgZW5jb2Rpbmc6IFwidXRmLThcIixcbiAgICAgICAgICBzdGRpbzogW1wiaWdub3JlXCIsIFwiaWdub3JlXCIsIFwicGlwZVwiXSxcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIGFuYWx5emVBbmRSZW1vdmUoZGF0YXNldE5hbWUsIG9wdGlvbnMpXG4gICAgICBjb25zdCBkYXRhc2V0UmF3RGlyOiBzdHJpbmcgPSBwYXRoLmpvaW4oZGF0YURpciwgZGF0YXNldE5hbWUpXG4gICAgICBjb25zdCBkYXRhc2V0Q2xlYW5EaXI6IHN0cmluZyA9IGRhdGFzZXRSYXdEaXIgKyBcIl9uZXR0b3llXCJcbiAgICAgIGZvciAoY29uc3Qgc2NydXRpblNwbGl0UGF0aCBvZiB3YWxrRGlyKGRhdGFzZXRSYXdEaXIpKSB7XG4gICAgICAgIGNvbnN0IHNjcnV0aW5GaWxlbmFtZSA9IHNjcnV0aW5TcGxpdFBhdGhbc2NydXRpblNwbGl0UGF0aC5sZW5ndGggLSAxXVxuICAgICAgICBpZiAoIXNjcnV0aW5GaWxlbmFtZS5lbmRzV2l0aChcIi5qc29uXCIpKSB7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzY3J1dGluUmF3RmlsZVBhdGggPSBwYXRoLmpvaW4oZGF0YXNldFJhd0RpciwgLi4uc2NydXRpblNwbGl0UGF0aClcbiAgICAgICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgIENsZWFuaW5nIGZpbGU6ICR7c2NydXRpblJhd0ZpbGVQYXRofeKApmApXG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2NydXRpblJhd0pzb246IHN0cmluZyA9IGZzLnJlYWRGaWxlU3luYyhzY3J1dGluUmF3RmlsZVBhdGgsIHtcbiAgICAgICAgICBlbmNvZGluZzogXCJ1dGY4XCIsXG4gICAgICAgIH0pXG4gICAgICAgIGNvbnN0IHNjcnV0aW4gPSBKU09OLnBhcnNlKHNjcnV0aW5SYXdKc29uKVxuICAgICAgICBjbGVhblNjcnV0aW4oc2NydXRpbilcbiAgICAgICAgY29uc3Qgc2NydXRpbkpzb246IHN0cmluZyA9IEpTT04uc3RyaW5naWZ5KHNjcnV0aW4sIG51bGwsIDIpXG5cbiAgICAgICAgLy8gVmFsaWRhdGUgZ2VuZXJhdGVkIEpTT04uXG4gICAgICAgIGNvbnN0IHNjcnV0aW5DbGVhbjogU2NydXRpbiA9IFNjcnV0aW5zQ29udmVydC50b1NjcnV0aW4oc2NydXRpbkpzb24pXG4gICAgICAgIGNvbnN0IHNjcnV0aW5DbGVhbkpzb246IHN0cmluZyA9XG4gICAgICAgICAgU2NydXRpbnNDb252ZXJ0LnNjcnV0aW5Ub0pzb24oc2NydXRpbkNsZWFuKVxuXG4gICAgICAgIGNvbnN0IHNjcnV0aW5DbGVhbkZpbGVQYXRoOiBzdHJpbmcgPSBwYXRoLmpvaW4oXG4gICAgICAgICAgZGF0YXNldENsZWFuRGlyLFxuICAgICAgICAgIC4uLnNjcnV0aW5TcGxpdFBhdGgsXG4gICAgICAgIClcbiAgICAgICAgZnMuZW5zdXJlRGlyU3luYyhwYXRoLmRpcm5hbWUoc2NydXRpbkNsZWFuRmlsZVBhdGgpKVxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHNjcnV0aW5DbGVhbkZpbGVQYXRoLCBzY3J1dGluQ2xlYW5Kc29uLCB7XG4gICAgICAgICAgZW5jb2Rpbmc6IFwidXRmOFwiLFxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBpZiAoY29tbWl0QW5kUHVzaChkYXRhc2V0Q2xlYW5EaXIsIG9wdGlvbnMsIG9wdGlvbnMucmVtb3RlKSkge1xuICAgICAgICBlcnJvciA9IHRydWVcbiAgICAgIH1cbiAgICAgIGlmIChjb21taXRBbmRQdXNoVWlkKGRhdGFzZXRDbGVhbkRpciwgb3B0aW9ucywgW1wiLlwiXSkpIHtcbiAgICAgICAgZXJyb3IgPSB0cnVlXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gUmVzdG9yZSBzdGFuZGFyZCBjb252ZXJzaW9uIG9mIGRhdGVzIHRvIEpTT04uXG4gIERhdGUucHJvdG90eXBlLnRvSlNPTiA9IGV4aXN0aW5nRGF0ZVRvSnNvblxuXG4gIHJldHVybiBlcnJvclxufVxuXG5mdW5jdGlvbiBhbmFseXplQW5kUmVtb3ZlKGRhdGFzZXROYW1lOiBzdHJpbmcsIG9wdGlvbnM6IGFueSk6IGFueSB7XG4gIGNvbnN0IGRhdGFEaXIgPSBvcHRpb25zLmRhdGFEaXJcbiAgY29uc3QgZGF0YXNldFJhd0Rpcjogc3RyaW5nID0gcGF0aC5qb2luKGRhdGFEaXIsIGRhdGFzZXROYW1lKVxuICBjb25zdCBkYXRhc2V0Q2xlYW5EaXI6IHN0cmluZyA9IGRhdGFzZXRSYXdEaXIgKyBcIl9uZXR0b3llXCJcbiAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xuICAgIGNvbnNvbGUubG9nKGBDbGVhbmluZyBkaXJlY3Rvcnk6ICR7ZGF0YXNldENsZWFuRGlyfeKApmApXG4gIH1cbiAgZnMuZW5zdXJlRGlyU3luYyhkYXRhc2V0Q2xlYW5EaXIpXG4gIGZvciAoY29uc3QgZmlsZW5hbWUgb2YgZnMucmVhZGRpclN5bmMoZGF0YXNldENsZWFuRGlyKSkge1xuICAgIGlmIChmaWxlbmFtZVswXSA9PT0gXCIuXCIpIHtcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGNvbnN0IHBhdGhuYW1lID0gcGF0aC5qb2luKGRhdGFzZXRDbGVhbkRpciwgZmlsZW5hbWUpXG4gICAgZnMucmVtb3ZlU3luYyhwYXRobmFtZSlcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRBbmRQdXNoKFxuICByZXBvc2l0b3J5RGlyOiBzdHJpbmcsXG4gIG9wdGlvbnM6IGFueSxcbiAgcmVtb3Rlcz86IHN0cmluZ1tdLFxuKTogYm9vbGVhbiB7XG4gIGxldCBlcnJvciA9IGZhbHNlXG4gIGlmIChvcHRpb25zLmNvbW1pdCkge1xuICAgIGdpdC5jb21taXQocmVwb3NpdG9yeURpciwgXCJOb3V2ZWxsZSBtb2lzc29uXCIpXG4gICAgZm9yIChjb25zdCByZW1vdGUgb2YgcmVtb3RlcyB8fCBbXSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZXhlY1N5bmMoYGdpdCBwdXNoICR7cmVtb3RlfSBtYXN0ZXJgLCB7XG4gICAgICAgICAgY3dkOiByZXBvc2l0b3J5RGlyLFxuICAgICAgICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgICAgICAgZW5jb2Rpbmc6IFwidXRmLThcIixcbiAgICAgICAgICBzdGRpbzogW1wiaWdub3JlXCIsIFwiaWdub3JlXCIsIFwicGlwZVwiXSxcbiAgICAgICAgfSlcbiAgICAgIH0gY2F0Y2ggKGNoaWxkUHJvY2Vzcykge1xuICAgICAgICAvLyBEb24ndCBzdG9wIHdoZW4gcHVzaCBmYWlscy5cbiAgICAgICAgY29uc29sZS5lcnJvcigoY2hpbGRQcm9jZXNzIGFzIGFueSkub3V0cHV0KVxuICAgICAgICBlcnJvciA9IHRydWVcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGVycm9yXG59XG5cbmZ1bmN0aW9uIGNvbW1pdEFuZFB1c2hVaWQoXG4gIHJlcG9zaXRvcnlEaXI6IHN0cmluZyxcbiAgb3B0aW9uczogYW55LFxuICBzdWJkaXJlY3RvcmllczogYW55LFxuKTogYm9vbGVhbiB7XG4gIGxldCBlcnJvciA9IGZhbHNlXG4gIGlmIChvcHRpb25zLmNvbW1pdCkge1xuICAgIGdpdC51aWRCcmFuY2hVcGRhdGUoXG4gICAgICByZXBvc2l0b3J5RGlyLFxuICAgICAgc3ViZGlyZWN0b3JpZXMsXG4gICAgICBvcHRpb25zW1wibm8tcmVzZXQtYWZ0ZXItY29tbWl0XCJdLFxuICAgIClcbiAgICBmb3IgKGNvbnN0IHJlbW90ZSBvZiBvcHRpb25zLnJlbW90ZSB8fCBbXSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZ2l0LnJ1bihyZXBvc2l0b3J5RGlyLCBgcHVzaCAtLXF1aWV0ICR7cmVtb3RlfSB1aWQ6dWlkYClcbiAgICAgIH0gY2F0Y2ggKGNoaWxkUHJvY2Vzcykge1xuICAgICAgICBlcnJvciA9IHRydWVcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGVycm9yXG59XG5cbmZ1bmN0aW9uIG1haW4oYXJndjogYW55KTogbnVtYmVyIHtcbiAgY29uc3Qgb3B0aW9ucyA9IHBhcnNlQXJncyhhcmd2KVxuICBpZiAoY2xlYW5SZW9yZ2FuaXplZERhdGEob3B0aW9ucykpIHtcbiAgICByZXR1cm4gMVxuICB9IGVsc2Uge1xuICAgIHJldHVybiAwXG4gIH1cbn1cblxuLyogaXN0YW5idWwgaWdub3JlIGlmICovXG5pZiAocHJvY2Vzcy5hcmd2WzFdLmVuZHNXaXRoKFwiY2xlYW5fcmVvcmdhbml6ZWRfZGF0YS50c1wiKSlcbiAgcHJvY2Vzcy5leGl0KG1haW4ocHJvY2Vzcy5hcmd2KSlcbiJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBT0EsTUFBUCxNQUFtQixRQUFuQjtBQUNBLFNBQVNDLFFBQVQsUUFBeUIsZUFBekI7QUFDQSxPQUFPQyxlQUFQLE1BQTRCLG1CQUE1QjtBQUNBLE9BQU9DLEVBQVAsTUFBZSxVQUFmO0FBQ0EsT0FBT0MsSUFBUCxNQUFpQixNQUFqQjtTQUdFQyxXLEVBQ0FDLGUsRUFDQUMsdUIsRUFDQUMseUIsRUFDQUMsVyxFQUNBQyxZLEVBQ0FDLFk7U0FFT0MsUSxFQUFVQyxlO1NBQ1ZDLGtCLEVBQW9CQyxpQjtTQUNwQkMsTztPQUNGLEtBQUtDLEc7U0FHVkMsT0FBTyxJQUFJQyx1QjtTQUdKRCxPQUFPLElBQUlFLGM7U0FDQ0YsT0FBTyxJQUFJRyxrQjtTQUU5QkgsT0FBTyxJQUFJSSwwQjtTQUlKSixPQUFPLElBQUlLLGU7O0FBRXBCLFNBQVNDLFNBQVQsQ0FBbUJDLElBQW5CLEVBQXdDO0VBQ3RDLE1BQU1DLGtCQUFrQixHQUFHLENBQ3pC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
|