@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.
Files changed (135) hide show
  1. package/README.md +2 -0
  2. package/lib/api.js +23 -7
  3. package/lib/api.mjs +41 -0
  4. package/lib/bugs/acteur-00010/plugin.test.js +139 -33
  5. package/lib/bugs/acteur-00010/plugin.test.mjs +33 -0
  6. package/lib/bugs/acteur-00010.js +166 -24
  7. package/lib/bugs/acteur-00010.mjs +31 -0
  8. package/lib/bugs/agenda-00002/plugin.test.js +178 -52
  9. package/lib/bugs/agenda-00002/plugin.test.mjs +52 -0
  10. package/lib/bugs/agenda-00002.js +507 -143
  11. package/lib/bugs/agenda-00002.mjs +197 -0
  12. package/lib/bugs/agenda-00008/plugin.test.js +143 -31
  13. package/lib/bugs/agenda-00008/plugin.test.mjs +31 -0
  14. package/lib/bugs/agenda-00008.js +180 -25
  15. package/lib/bugs/agenda-00008.mjs +30 -0
  16. package/lib/bugs/agenda-00011/plugin.test.js +371 -156
  17. package/lib/bugs/agenda-00011/plugin.test.mjs +156 -0
  18. package/lib/bugs/agenda-00011.js +416 -117
  19. package/lib/bugs/agenda-00011.mjs +150 -0
  20. package/lib/bugs.js +591 -54
  21. package/lib/bugs.mjs +93 -0
  22. package/lib/cleaners/actes_legislatifs.js +149 -61
  23. package/lib/cleaners/actes_legislatifs.mjs +311 -0
  24. package/lib/cleaners/acteurs.js +255 -123
  25. package/lib/cleaners/acteurs.mjs +211 -0
  26. package/lib/cleaners/amendements.js +242 -117
  27. package/lib/cleaners/amendements.mjs +292 -0
  28. package/lib/cleaners/documents.js +147 -62
  29. package/lib/cleaners/documents.mjs +162 -0
  30. package/lib/cleaners/dossiers_legislatifs.js +132 -45
  31. package/lib/cleaners/dossiers_legislatifs.mjs +123 -0
  32. package/lib/cleaners/index.js +64 -8
  33. package/lib/cleaners/index.mjs +8 -0
  34. package/lib/cleaners/organes.js +54 -21
  35. package/lib/cleaners/organes.mjs +64 -0
  36. package/lib/cleaners/reunions.js +237 -127
  37. package/lib/cleaners/reunions.mjs +318 -0
  38. package/lib/cleaners/scrutins.js +261 -99
  39. package/lib/cleaners/scrutins.mjs +254 -0
  40. package/lib/cleaners/xml.js +81 -16
  41. package/lib/cleaners/xml.mjs +42 -0
  42. package/lib/datasets.js +284 -153
  43. package/lib/datasets.mjs +596 -0
  44. package/lib/dates.js +93 -34
  45. package/lib/dates.mjs +98 -0
  46. package/lib/dossiers_legislatifs.js +107 -33
  47. package/lib/dossiers_legislatifs.mjs +215 -0
  48. package/lib/file_systems.js +203 -35
  49. package/lib/file_systems.mjs +64 -0
  50. package/lib/git.js +139 -41
  51. package/lib/git.mjs +114 -0
  52. package/lib/index.js +310 -16
  53. package/lib/index.mjs +16 -0
  54. package/lib/inserters.js +355 -131
  55. package/lib/inserters.mjs +413 -0
  56. package/lib/loaders.js +900 -440
  57. package/lib/loaders.mjs +678 -0
  58. package/lib/organes.js +15 -5
  59. package/lib/organes.mjs +18 -0
  60. package/lib/parsers/documents.js +241 -89
  61. package/lib/parsers/documents.mjs +433 -0
  62. package/lib/parsers/index.js +36 -3
  63. package/lib/parsers/index.mjs +3 -0
  64. package/lib/parsers/recherche_amendements.js +616 -173
  65. package/lib/parsers/recherche_amendements.mjs +189 -0
  66. package/lib/raw_types/acteurs_et_organes.d.ts +36 -148
  67. package/lib/raw_types/acteurs_et_organes.js +228 -506
  68. package/lib/raw_types/acteurs_et_organes.mjs +1240 -0
  69. package/lib/raw_types/agendas.js +165 -75
  70. package/lib/raw_types/agendas.mjs +944 -0
  71. package/lib/raw_types/amendements.js +165 -77
  72. package/lib/raw_types/amendements.mjs +1040 -0
  73. package/lib/raw_types/dossiers_legislatifs.d.ts +1 -43
  74. package/lib/raw_types/dossiers_legislatifs.js +181 -143
  75. package/lib/raw_types/dossiers_legislatifs.mjs +1792 -0
  76. package/lib/raw_types/scrutins.js +144 -61
  77. package/lib/raw_types/scrutins.mjs +645 -0
  78. package/lib/scripts/bugs_helper.js +657 -155
  79. package/lib/scripts/bugs_helper.mjs +286 -0
  80. package/lib/scripts/clean_data.js +380 -145
  81. package/lib/scripts/clean_data.mjs +190 -0
  82. package/lib/scripts/clean_reorganized_data.js +627 -331
  83. package/lib/scripts/clean_reorganized_data.mjs +520 -0
  84. package/lib/scripts/diff_amendements.js +159 -73
  85. package/lib/scripts/diff_amendements.mjs +234 -0
  86. package/lib/scripts/document_dossiers_legislatifs.js +570 -288
  87. package/lib/scripts/document_dossiers_legislatifs.mjs +494 -0
  88. package/lib/scripts/get_today_reunions.js +37 -20
  89. package/lib/scripts/get_today_reunions.mjs +41 -0
  90. package/lib/scripts/merge_scrutins.js +121 -39
  91. package/lib/scripts/merge_scrutins.mjs +69 -0
  92. package/lib/scripts/parse_textes_lois.js +179 -125
  93. package/lib/scripts/parse_textes_lois.mjs +215 -0
  94. package/lib/scripts/raw_types_from_amendements.js +276 -77
  95. package/lib/scripts/raw_types_from_amendements.mjs +118 -0
  96. package/lib/scripts/reorganize_data.js +867 -446
  97. package/lib/scripts/reorganize_data.mjs +712 -0
  98. package/lib/scripts/retrieve_deputes_photos.js +378 -157
  99. package/lib/scripts/retrieve_deputes_photos.mjs +230 -0
  100. package/lib/scripts/retrieve_documents.js +648 -172
  101. package/lib/scripts/retrieve_documents.mjs +292 -0
  102. package/lib/scripts/retrieve_open_data.js +286 -85
  103. package/lib/scripts/retrieve_open_data.mjs +125 -0
  104. package/lib/scripts/retrieve_pending_amendments.js +302 -69
  105. package/lib/scripts/retrieve_pending_amendments.mjs +130 -0
  106. package/lib/scripts/retrieve_senateurs_photos.js +374 -198
  107. package/lib/scripts/retrieve_senateurs_photos.mjs +277 -0
  108. package/lib/scripts/retrieve_textes_lois.js +343 -89
  109. package/lib/scripts/retrieve_textes_lois.mjs +168 -0
  110. package/lib/scripts/test_load.js +30 -11
  111. package/lib/scripts/test_load.mjs +26 -0
  112. package/lib/scripts/test_load_big_files.js +30 -11
  113. package/lib/scripts/test_load_big_files.mjs +26 -0
  114. package/lib/scripts/validate_json.js +370 -120
  115. package/lib/scripts/validate_json.mjs +216 -0
  116. package/lib/shared_types/codes_actes.js +50 -15
  117. package/lib/shared_types/codes_actes.mjs +228 -0
  118. package/lib/strings.js +16 -3
  119. package/lib/strings.mjs +7 -0
  120. package/lib/types/acteurs_et_organes.js +156 -71
  121. package/lib/types/acteurs_et_organes.mjs +918 -0
  122. package/lib/types/agendas.js +154 -67
  123. package/lib/types/agendas.mjs +623 -0
  124. package/lib/types/amendements.js +166 -77
  125. package/lib/types/amendements.mjs +885 -0
  126. package/lib/types/dossiers_legislatifs.d.ts +1 -42
  127. package/lib/types/dossiers_legislatifs.js +182 -143
  128. package/lib/types/dossiers_legislatifs.mjs +1120 -0
  129. package/lib/types/legislatures.js +12 -3
  130. package/lib/types/legislatures.mjs +9 -0
  131. package/lib/types/scrutins.js +144 -61
  132. package/lib/types/scrutins.mjs +528 -0
  133. package/lib/urls.js +44 -25
  134. package/lib/urls.mjs +201 -0
  135. package/package.json +33 -12
@@ -0,0 +1,234 @@
1
+ import commandLineArgs from "command-line-args";
2
+ import fs from "fs-extra";
3
+ import path from "path";
4
+ import { detailedDiff } from "deep-object-diff";
5
+ import { datasets, DatasetStructure } from "../datasets.mjs";
6
+ import { walkDir } from "../file_systems.mjs";
7
+ const diffedAmendments = [];
8
+ const newAmendments = [];
9
+ const optionsDefinitions = [{
10
+ alias: "s",
11
+ help: "don't log anything",
12
+ name: "silent",
13
+ type: Boolean
14
+ }, {
15
+ alias: "v",
16
+ help: "verbose logs",
17
+ name: "verbose",
18
+ type: Boolean
19
+ }, {
20
+ alias: "m",
21
+ help: "Diff modes.",
22
+ name: "mode",
23
+ defaultValue: "merged",
24
+ type: String
25
+ }, {
26
+ defaultOption: true,
27
+ help: "directory containing Assemblée open data files",
28
+ name: "dataDir",
29
+ type: String
30
+ }, {
31
+ alias: "p",
32
+ help: "Directory containing the previous dump of amendments",
33
+ name: "previous",
34
+ type: String
35
+ }, {
36
+ alias: "o",
37
+ help: "Output directory for diff files",
38
+ name: "output",
39
+ defaultValue: "./diff_outputs/",
40
+ type: String
41
+ }];
42
+ const options = commandLineArgs(optionsDefinitions);
43
+
44
+ function diffAmendements(dataDir) {
45
+ if (!options.previous) {
46
+ console.error("No previous data folder specified. You must provide one with the -p or --previous option. Exiting...");
47
+ process.exit();
48
+ }
49
+
50
+ if (!fs.existsSync(options.output)) {
51
+ console.error("The output dir does not exists. You must provide an existing directory. Default directory is ./diff_outputs/");
52
+ process.exit();
53
+ }
54
+
55
+ for (const dataset of datasets.amendements) {
56
+ switch (dataset.structure) {
57
+ case DatasetStructure.SegmentedFiles:
58
+ {
59
+ const originalJsonDir = path.join(dataDir, dataset.filename);
60
+
61
+ if (!options.silent) {
62
+ console.log(`Diffing ${originalJsonDir} folder...`);
63
+ }
64
+
65
+ for (const amendementSplitPath of walkDir(originalJsonDir)) {
66
+ const newFilePath = originalJsonDir + "/" + amendementSplitPath.join("/");
67
+ const newFile = JSON.parse(fs.readFileSync(newFilePath).toLocaleString());
68
+ const oldFilePath = options.previous + dataset.filename + "/" + amendementSplitPath.join("/");
69
+ const oldFileExists = fs.existsSync(oldFilePath);
70
+
71
+ if (!oldFileExists) {
72
+ // If file found does not exist in the previous dump
73
+ if (!options.silent) {
74
+ console.log("File did not exists previously. Guessing it's a new amendment. Adding to the diff list for new objects");
75
+ }
76
+
77
+ addToQueueForNewAmendments(newFile, amendementSplitPath);
78
+ continue;
79
+ } // File already existed in previous dump
80
+
81
+
82
+ let oldFile = JSON.parse("{}");
83
+
84
+ try {
85
+ // Gather data of the file and retranscript as a Json object
86
+ oldFile = JSON.parse(fs.readFileSync(oldFilePath).toLocaleString());
87
+ } catch (e) {
88
+ // Skip the process to the next iteration in case of corrupt JSON data
89
+ continue;
90
+ } // Generate the diff beetween the two JSON objects (old & new dump)
91
+
92
+
93
+ const diff = detailedDiff(oldFile, newFile); // If no changes beetween the two dumps
94
+
95
+ if (Object.keys(diff.added).length === 0 && Object.keys(diff.updated).length === 0 && Object.keys(diff.deleted).length === 0) {
96
+ // Skip to next iteration as there is no need to generate a file
97
+ continue;
98
+ } else {
99
+ if (!options.silent) {
100
+ console.log("Changes found !");
101
+ }
102
+
103
+ addToQueueForDiffedAmendments(diff, amendementSplitPath);
104
+ }
105
+
106
+ break;
107
+ }
108
+ }
109
+ }
110
+
111
+ if (!options.silent) {
112
+ console.log("Generating output(s)");
113
+ }
114
+
115
+ generateDiffFiles();
116
+ }
117
+ }
118
+ /**
119
+ * General process for output of diffs.
120
+ * The script handles two different modes :
121
+ * - merged : Will output a single file for new amendements and a single file
122
+ * for updated amendements
123
+ * - splitted : Will output a single file for each amendments, either its new or updated.
124
+ *
125
+ */
126
+
127
+
128
+ function generateDiffFiles() {
129
+ // Handles merged mode
130
+ if (options.mode === "merged") {
131
+ if (!options.silent) {
132
+ console.log("Generating merged files");
133
+ }
134
+
135
+ if (diffedAmendments.length > 0) {
136
+ if (!options.silent) {
137
+ console.log("Generating diffed amendments files");
138
+ }
139
+
140
+ fs.writeFileSync(options.output + "amendements_XV_diffed.json", JSON.stringify(diffedAmendments), {
141
+ encoding: "utf8",
142
+ flag: "w"
143
+ });
144
+ } else {
145
+ if (!options.silent) {
146
+ console.log("No diff in the already existing amendments");
147
+ }
148
+ }
149
+
150
+ if (newAmendments.length > 0) {
151
+ if (!options.silent) {
152
+ console.log("Generating new amendments file");
153
+ }
154
+
155
+ fs.writeFileSync(options.output + "amendements_XV_new.json", JSON.stringify(newAmendments), {
156
+ encoding: "utf8",
157
+ flag: "w"
158
+ });
159
+ } else {
160
+ if (!options.silent) {
161
+ console.log("No new amendement. Skipping file generation");
162
+ }
163
+ }
164
+ } else if (options.mode === "splitted") {
165
+ // Handles splitted mode
166
+ if (!options.silent) {
167
+ console.log("Generating separated files");
168
+ }
169
+ /**
170
+ * Process the copy action of the new and diffed amendments
171
+ */
172
+
173
+
174
+ diffedAmendments.forEach(diffedAmendment => {
175
+ generateSingleDiffedAmendment(diffedAmendment);
176
+ });
177
+ newAmendments.forEach(newAmendment => {
178
+ generateSingleNewAmendment(newAmendment);
179
+ });
180
+ } else {
181
+ console.error("Unknown output mode. Aborting...");
182
+ process.exit();
183
+ }
184
+ } // Pushes an amendment to the queue that will be processed to copy new amendments files
185
+
186
+
187
+ function addToQueueForNewAmendments(file, path) {
188
+ const amendment = {
189
+ path: path,
190
+ data: file
191
+ };
192
+ newAmendments.push(amendment);
193
+ } // Pushes an amendment to the queue that will be processed to copy updated amendments files
194
+
195
+
196
+ function addToQueueForDiffedAmendments(diffedData, path) {
197
+ const amendment = {
198
+ path: path,
199
+ data: diffedData
200
+ };
201
+ diffedAmendments.push(amendment);
202
+ } // generates a file with a copy of the new amendement
203
+
204
+
205
+ function generateSingleNewAmendment(newAmendment) {
206
+ newAmendment.path.shift();
207
+ const shortDir = [...newAmendment.path];
208
+ shortDir.pop();
209
+ console.log(options.output + shortDir.join("/"));
210
+ fs.mkdirSync(options.output + shortDir.join("/"), {
211
+ recursive: true
212
+ });
213
+ fs.writeFileSync(options.output + newAmendment.path.join("/").replace(/(\.json)/, ".new$1"), JSON.stringify(newAmendment.data), {
214
+ encoding: "utf8",
215
+ flag: "w"
216
+ });
217
+ } // generates a file with a copy of the modified data of the previously existing amendment;
218
+
219
+
220
+ function generateSingleDiffedAmendment(diffedAmendment) {
221
+ diffedAmendment.path.shift();
222
+ const shortDir = [...diffedAmendment.path];
223
+ shortDir.pop();
224
+ fs.mkdirSync(options.output + shortDir.join("/"), {
225
+ recursive: true
226
+ });
227
+ fs.writeFileSync(options.output + diffedAmendment.path.join("/").replace(/(\.json)/, ".diff$1"), JSON.stringify(diffedAmendment.data), {
228
+ encoding: "utf8",
229
+ flag: "w"
230
+ });
231
+ }
232
+
233
+ diffAmendements(options.dataDir);
234
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21tYW5kTGluZUFyZ3MiLCJmcyIsInBhdGgiLCJkZXRhaWxlZERpZmYiLCJkYXRhc2V0cyIsIkRhdGFzZXRTdHJ1Y3R1cmUiLCJ3YWxrRGlyIiwiZGlmZmVkQW1lbmRtZW50cyIsIm5ld0FtZW5kbWVudHMiLCJvcHRpb25zRGVmaW5pdGlvbnMiLCJhbGlhcyIsImhlbHAiLCJuYW1lIiwidHlwZSIsIkJvb2xlYW4iLCJkZWZhdWx0VmFsdWUiLCJTdHJpbmciLCJkZWZhdWx0T3B0aW9uIiwib3B0aW9ucyIsImRpZmZBbWVuZGVtZW50cyIsImRhdGFEaXIiLCJwcmV2aW91cyIsImNvbnNvbGUiLCJlcnJvciIsInByb2Nlc3MiLCJleGl0IiwiZXhpc3RzU3luYyIsIm91dHB1dCIsImRhdGFzZXQiLCJhbWVuZGVtZW50cyIsInN0cnVjdHVyZSIsIlNlZ21lbnRlZEZpbGVzIiwib3JpZ2luYWxKc29uRGlyIiwiam9pbiIsImZpbGVuYW1lIiwic2lsZW50IiwibG9nIiwiYW1lbmRlbWVudFNwbGl0UGF0aCIsIm5ld0ZpbGVQYXRoIiwibmV3RmlsZSIsIkpTT04iLCJwYXJzZSIsInJlYWRGaWxlU3luYyIsInRvTG9jYWxlU3RyaW5nIiwib2xkRmlsZVBhdGgiLCJvbGRGaWxlRXhpc3RzIiwiYWRkVG9RdWV1ZUZvck5ld0FtZW5kbWVudHMiLCJvbGRGaWxlIiwiZSIsImRpZmYiLCJPYmplY3QiLCJrZXlzIiwiYWRkZWQiLCJsZW5ndGgiLCJ1cGRhdGVkIiwiZGVsZXRlZCIsImFkZFRvUXVldWVGb3JEaWZmZWRBbWVuZG1lbnRzIiwiZ2VuZXJhdGVEaWZmRmlsZXMiLCJtb2RlIiwid3JpdGVGaWxlU3luYyIsInN0cmluZ2lmeSIsImVuY29kaW5nIiwiZmxhZyIsImZvckVhY2giLCJkaWZmZWRBbWVuZG1lbnQiLCJnZW5lcmF0ZVNpbmdsZURpZmZlZEFtZW5kbWVudCIsIm5ld0FtZW5kbWVudCIsImdlbmVyYXRlU2luZ2xlTmV3QW1lbmRtZW50IiwiZmlsZSIsImFtZW5kbWVudCIsImRhdGEiLCJwdXNoIiwiZGlmZmVkRGF0YSIsInNoaWZ0Iiwic2hvcnREaXIiLCJwb3AiLCJta2RpclN5bmMiLCJyZWN1cnNpdmUiLCJyZXBsYWNlIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NjcmlwdHMvZGlmZl9hbWVuZGVtZW50cy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY29tbWFuZExpbmVBcmdzIGZyb20gXCJjb21tYW5kLWxpbmUtYXJnc1wiXG5pbXBvcnQgZnMgZnJvbSBcImZzLWV4dHJhXCJcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCJcbmltcG9ydCB7IGRldGFpbGVkRGlmZiB9IGZyb20gXCJkZWVwLW9iamVjdC1kaWZmXCJcbmltcG9ydCB7IGRhdGFzZXRzLCBEYXRhc2V0U3RydWN0dXJlIH0gZnJvbSBcIi4uL2RhdGFzZXRzXCJcbmltcG9ydCB7IHdhbGtEaXIgfSBmcm9tIFwiLi4vZmlsZV9zeXN0ZW1zXCJcbmNvbnN0IGRpZmZlZEFtZW5kbWVudHM6IEFycmF5PGFueT4gPSBbXVxuY29uc3QgbmV3QW1lbmRtZW50czogQXJyYXk8YW55PiA9IFtdXG5cbmNvbnN0IG9wdGlvbnNEZWZpbml0aW9ucyA9IFtcbiAge1xuICAgIGFsaWFzOiBcInNcIixcbiAgICBoZWxwOiBcImRvbid0IGxvZyBhbnl0aGluZ1wiLFxuICAgIG5hbWU6IFwic2lsZW50XCIsXG4gICAgdHlwZTogQm9vbGVhbixcbiAgfSxcbiAge1xuICAgIGFsaWFzOiBcInZcIixcbiAgICBoZWxwOiBcInZlcmJvc2UgbG9nc1wiLFxuICAgIG5hbWU6IFwidmVyYm9zZVwiLFxuICAgIHR5cGU6IEJvb2xlYW4sXG4gIH0sXG4gIHtcbiAgICBhbGlhczogXCJtXCIsXG4gICAgaGVscDogXCJEaWZmIG1vZGVzLlwiLFxuICAgIG5hbWU6IFwibW9kZVwiLFxuICAgIGRlZmF1bHRWYWx1ZTogXCJtZXJnZWRcIixcbiAgICB0eXBlOiBTdHJpbmcsXG4gIH0sXG4gIHtcbiAgICBkZWZhdWx0T3B0aW9uOiB0cnVlLFxuICAgIGhlbHA6IFwiZGlyZWN0b3J5IGNvbnRhaW5pbmcgQXNzZW1ibMOpZSBvcGVuIGRhdGEgZmlsZXNcIixcbiAgICBuYW1lOiBcImRhdGFEaXJcIixcbiAgICB0eXBlOiBTdHJpbmcsXG4gIH0sXG4gIHtcbiAgICBhbGlhczogXCJwXCIsXG4gICAgaGVscDogXCJEaXJlY3RvcnkgY29udGFpbmluZyB0aGUgcHJldmlvdXMgZHVtcCBvZiBhbWVuZG1lbnRzXCIsXG4gICAgbmFtZTogXCJwcmV2aW91c1wiLFxuICAgIHR5cGU6IFN0cmluZyxcbiAgfSxcbiAge1xuICAgIGFsaWFzOiBcIm9cIixcbiAgICBoZWxwOiBcIk91dHB1dCBkaXJlY3RvcnkgZm9yIGRpZmYgZmlsZXNcIixcbiAgICBuYW1lOiBcIm91dHB1dFwiLFxuICAgIGRlZmF1bHRWYWx1ZTogXCIuL2RpZmZfb3V0cHV0cy9cIixcbiAgICB0eXBlOiBTdHJpbmcsXG4gIH0sXG5dXG5jb25zdCBvcHRpb25zID0gY29tbWFuZExpbmVBcmdzKG9wdGlvbnNEZWZpbml0aW9ucylcblxuZnVuY3Rpb24gZGlmZkFtZW5kZW1lbnRzKGRhdGFEaXI6IHN0cmluZykge1xuICBpZiAoIW9wdGlvbnMucHJldmlvdXMpIHtcbiAgICBjb25zb2xlLmVycm9yKFxuICAgICAgXCJObyBwcmV2aW91cyBkYXRhIGZvbGRlciBzcGVjaWZpZWQuIFlvdSBtdXN0IHByb3ZpZGUgb25lIHdpdGggdGhlIC1wIG9yIC0tcHJldmlvdXMgb3B0aW9uLiBFeGl0aW5nLi4uXCIsXG4gICAgKVxuICAgIHByb2Nlc3MuZXhpdCgpXG4gIH1cblxuICBpZiAoIWZzLmV4aXN0c1N5bmMob3B0aW9ucy5vdXRwdXQpKSB7XG4gICAgY29uc29sZS5lcnJvcihcbiAgICAgIFwiVGhlIG91dHB1dCBkaXIgZG9lcyBub3QgZXhpc3RzLiBZb3UgbXVzdCBwcm92aWRlIGFuIGV4aXN0aW5nIGRpcmVjdG9yeS4gRGVmYXVsdCBkaXJlY3RvcnkgaXMgLi9kaWZmX291dHB1dHMvXCIsXG4gICAgKVxuICAgIHByb2Nlc3MuZXhpdCgpXG4gIH1cblxuICBmb3IgKGNvbnN0IGRhdGFzZXQgb2YgZGF0YXNldHMuYW1lbmRlbWVudHMpIHtcbiAgICBzd2l0Y2ggKGRhdGFzZXQuc3RydWN0dXJlKSB7XG4gICAgICBjYXNlIERhdGFzZXRTdHJ1Y3R1cmUuU2VnbWVudGVkRmlsZXM6IHtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxKc29uRGlyOiBzdHJpbmcgPSBwYXRoLmpvaW4oZGF0YURpciwgZGF0YXNldC5maWxlbmFtZSlcbiAgICAgICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBEaWZmaW5nICR7b3JpZ2luYWxKc29uRGlyfSBmb2xkZXIuLi5gKVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBhbWVuZGVtZW50U3BsaXRQYXRoIG9mIHdhbGtEaXIob3JpZ2luYWxKc29uRGlyKSkge1xuICAgICAgICAgIGNvbnN0IG5ld0ZpbGVQYXRoID1cbiAgICAgICAgICAgIG9yaWdpbmFsSnNvbkRpciArIFwiL1wiICsgYW1lbmRlbWVudFNwbGl0UGF0aC5qb2luKFwiL1wiKVxuICAgICAgICAgIGNvbnN0IG5ld0ZpbGUgPSBKU09OLnBhcnNlKFxuICAgICAgICAgICAgZnMucmVhZEZpbGVTeW5jKG5ld0ZpbGVQYXRoKS50b0xvY2FsZVN0cmluZygpLFxuICAgICAgICAgIClcblxuICAgICAgICAgIGNvbnN0IG9sZEZpbGVQYXRoID1cbiAgICAgICAgICAgIG9wdGlvbnMucHJldmlvdXMgK1xuICAgICAgICAgICAgZGF0YXNldC5maWxlbmFtZSArXG4gICAgICAgICAgICBcIi9cIiArXG4gICAgICAgICAgICBhbWVuZGVtZW50U3BsaXRQYXRoLmpvaW4oXCIvXCIpXG4gICAgICAgICAgY29uc3Qgb2xkRmlsZUV4aXN0cyA9IGZzLmV4aXN0c1N5bmMob2xkRmlsZVBhdGgpXG4gICAgICAgICAgaWYgKCFvbGRGaWxlRXhpc3RzKSB7XG4gICAgICAgICAgICAvLyBJZiBmaWxlIGZvdW5kIGRvZXMgbm90IGV4aXN0IGluIHRoZSBwcmV2aW91cyBkdW1wXG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMuc2lsZW50KSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgIFwiRmlsZSBkaWQgbm90IGV4aXN0cyBwcmV2aW91c2x5LiBHdWVzc2luZyBpdCdzIGEgbmV3IGFtZW5kbWVudC4gQWRkaW5nIHRvIHRoZSBkaWZmIGxpc3QgZm9yIG5ldyBvYmplY3RzXCIsXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFkZFRvUXVldWVGb3JOZXdBbWVuZG1lbnRzKG5ld0ZpbGUsIGFtZW5kZW1lbnRTcGxpdFBhdGgpXG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEZpbGUgYWxyZWFkeSBleGlzdGVkIGluIHByZXZpb3VzIGR1bXBcbiAgICAgICAgICBsZXQgb2xkRmlsZTogSlNPTiA9IEpTT04ucGFyc2UoXCJ7fVwiKVxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBHYXRoZXIgZGF0YSBvZiB0aGUgZmlsZSBhbmQgcmV0cmFuc2NyaXB0IGFzIGEgSnNvbiBvYmplY3RcbiAgICAgICAgICAgIG9sZEZpbGUgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhvbGRGaWxlUGF0aCkudG9Mb2NhbGVTdHJpbmcoKSlcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBTa2lwIHRoZSBwcm9jZXNzIHRvIHRoZSBuZXh0IGl0ZXJhdGlvbiBpbiBjYXNlIG9mIGNvcnJ1cHQgSlNPTiBkYXRhXG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEdlbmVyYXRlIHRoZSBkaWZmIGJlZXR3ZWVuIHRoZSB0d28gSlNPTiBvYmplY3RzIChvbGQgJiBuZXcgZHVtcClcbiAgICAgICAgICBjb25zdCBkaWZmOiBhbnkgPSBkZXRhaWxlZERpZmYob2xkRmlsZSwgbmV3RmlsZSlcblxuICAgICAgICAgIC8vIElmIG5vIGNoYW5nZXMgYmVldHdlZW4gdGhlIHR3byBkdW1wc1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKGRpZmYuYWRkZWQpLmxlbmd0aCA9PT0gMCAmJlxuICAgICAgICAgICAgT2JqZWN0LmtleXMoZGlmZi51cGRhdGVkKS5sZW5ndGggPT09IDAgJiZcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKGRpZmYuZGVsZXRlZCkubGVuZ3RoID09PSAwXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBTa2lwIHRvIG5leHQgaXRlcmF0aW9uIGFzIHRoZXJlIGlzIG5vIG5lZWQgdG8gZ2VuZXJhdGUgYSBmaWxlXG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMuc2lsZW50KSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ2hhbmdlcyBmb3VuZCAhXCIpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhZGRUb1F1ZXVlRm9yRGlmZmVkQW1lbmRtZW50cyhkaWZmLCBhbWVuZGVtZW50U3BsaXRQYXRoKVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xuICAgICAgY29uc29sZS5sb2coXCJHZW5lcmF0aW5nIG91dHB1dChzKVwiKVxuICAgIH1cblxuICAgIGdlbmVyYXRlRGlmZkZpbGVzKClcbiAgfVxufVxuXG4vKipcbiAqIEdlbmVyYWwgcHJvY2VzcyBmb3Igb3V0cHV0IG9mIGRpZmZzLlxuICogVGhlIHNjcmlwdCBoYW5kbGVzIHR3byBkaWZmZXJlbnQgbW9kZXMgOlxuICogLSBtZXJnZWQgOiBXaWxsIG91dHB1dCBhIHNpbmdsZSBmaWxlIGZvciBuZXcgYW1lbmRlbWVudHMgYW5kIGEgc2luZ2xlIGZpbGVcbiAqICAgICAgICAgICAgZm9yIHVwZGF0ZWQgYW1lbmRlbWVudHNcbiAqIC0gc3BsaXR0ZWQgOiBXaWxsIG91dHB1dCBhIHNpbmdsZSBmaWxlIGZvciBlYWNoIGFtZW5kbWVudHMsIGVpdGhlciBpdHMgbmV3IG9yIHVwZGF0ZWQuXG4gKlxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZURpZmZGaWxlcygpIHtcbiAgLy8gSGFuZGxlcyBtZXJnZWQgbW9kZVxuICBpZiAob3B0aW9ucy5tb2RlID09PSBcIm1lcmdlZFwiKSB7XG4gICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xuICAgICAgY29uc29sZS5sb2coXCJHZW5lcmF0aW5nIG1lcmdlZCBmaWxlc1wiKVxuICAgIH1cblxuICAgIGlmIChkaWZmZWRBbWVuZG1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICghb3B0aW9ucy5zaWxlbnQpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJHZW5lcmF0aW5nIGRpZmZlZCBhbWVuZG1lbnRzIGZpbGVzXCIpXG4gICAgICB9XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICBvcHRpb25zLm91dHB1dCArIFwiYW1lbmRlbWVudHNfWFZfZGlmZmVkLmpzb25cIixcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoZGlmZmVkQW1lbmRtZW50cyksXG4gICAgICAgIHsgZW5jb2Rpbmc6IFwidXRmOFwiLCBmbGFnOiBcIndcIiB9LFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIW9wdGlvbnMuc2lsZW50KSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiTm8gZGlmZiBpbiB0aGUgYWxyZWFkeSBleGlzdGluZyBhbWVuZG1lbnRzXCIpXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG5ld0FtZW5kbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcIkdlbmVyYXRpbmcgbmV3IGFtZW5kbWVudHMgZmlsZVwiKVxuICAgICAgfVxuICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgb3B0aW9ucy5vdXRwdXQgKyBcImFtZW5kZW1lbnRzX1hWX25ldy5qc29uXCIsXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KG5ld0FtZW5kbWVudHMpLFxuICAgICAgICB7IGVuY29kaW5nOiBcInV0ZjhcIiwgZmxhZzogXCJ3XCIgfSxcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcIk5vIG5ldyBhbWVuZGVtZW50LiBTa2lwcGluZyBmaWxlIGdlbmVyYXRpb25cIilcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAob3B0aW9ucy5tb2RlID09PSBcInNwbGl0dGVkXCIpIHtcbiAgICAvLyBIYW5kbGVzIHNwbGl0dGVkIG1vZGVcbiAgICBpZiAoIW9wdGlvbnMuc2lsZW50KSB7XG4gICAgICBjb25zb2xlLmxvZyhcIkdlbmVyYXRpbmcgc2VwYXJhdGVkIGZpbGVzXCIpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvY2VzcyB0aGUgY29weSBhY3Rpb24gb2YgdGhlIG5ldyBhbmQgZGlmZmVkIGFtZW5kbWVudHNcbiAgICAgKi9cblxuICAgIGRpZmZlZEFtZW5kbWVudHMuZm9yRWFjaCgoZGlmZmVkQW1lbmRtZW50OiBhbnkpID0+IHtcbiAgICAgIGdlbmVyYXRlU2luZ2xlRGlmZmVkQW1lbmRtZW50KGRpZmZlZEFtZW5kbWVudClcbiAgICB9KVxuXG4gICAgbmV3QW1lbmRtZW50cy5mb3JFYWNoKChuZXdBbWVuZG1lbnQ6IGFueSkgPT4ge1xuICAgICAgZ2VuZXJhdGVTaW5nbGVOZXdBbWVuZG1lbnQobmV3QW1lbmRtZW50KVxuICAgIH0pXG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS5lcnJvcihcIlVua25vd24gb3V0cHV0IG1vZGUuIEFib3J0aW5nLi4uXCIpXG4gICAgcHJvY2Vzcy5leGl0KClcbiAgfVxufVxuXG4vLyBQdXNoZXMgYW4gYW1lbmRtZW50IHRvIHRoZSBxdWV1ZSB0aGF0IHdpbGwgYmUgcHJvY2Vzc2VkIHRvIGNvcHkgbmV3IGFtZW5kbWVudHMgZmlsZXNcbmZ1bmN0aW9uIGFkZFRvUXVldWVGb3JOZXdBbWVuZG1lbnRzKGZpbGU6IGFueSwgcGF0aDogYW55KTogdm9pZCB7XG4gIGNvbnN0IGFtZW5kbWVudDogYW55ID0ge1xuICAgIHBhdGg6IHBhdGgsXG4gICAgZGF0YTogZmlsZSxcbiAgfVxuICBuZXdBbWVuZG1lbnRzLnB1c2goYW1lbmRtZW50KVxufVxuLy8gUHVzaGVzIGFuIGFtZW5kbWVudCB0byB0aGUgcXVldWUgdGhhdCB3aWxsIGJlIHByb2Nlc3NlZCB0byBjb3B5IHVwZGF0ZWQgYW1lbmRtZW50cyBmaWxlc1xuZnVuY3Rpb24gYWRkVG9RdWV1ZUZvckRpZmZlZEFtZW5kbWVudHMoZGlmZmVkRGF0YTogYW55LCBwYXRoOiBhbnkpOiB2b2lkIHtcbiAgY29uc3QgYW1lbmRtZW50OiBhbnkgPSB7XG4gICAgcGF0aDogcGF0aCxcbiAgICBkYXRhOiBkaWZmZWREYXRhLFxuICB9XG4gIGRpZmZlZEFtZW5kbWVudHMucHVzaChhbWVuZG1lbnQpXG59XG5cbi8vIGdlbmVyYXRlcyBhIGZpbGUgd2l0aCBhIGNvcHkgb2YgdGhlIG5ldyBhbWVuZGVtZW50XG5mdW5jdGlvbiBnZW5lcmF0ZVNpbmdsZU5ld0FtZW5kbWVudChuZXdBbWVuZG1lbnQ6IHtcbiAgcGF0aDogQXJyYXk8c3RyaW5nPlxuICBkYXRhOiBhbnlcbn0pIHtcbiAgbmV3QW1lbmRtZW50LnBhdGguc2hpZnQoKVxuXG4gIGNvbnN0IHNob3J0RGlyOiBBcnJheTxhbnk+ID0gWy4uLm5ld0FtZW5kbWVudC5wYXRoXVxuICBzaG9ydERpci5wb3AoKVxuICBjb25zb2xlLmxvZyhvcHRpb25zLm91dHB1dCArIHNob3J0RGlyLmpvaW4oXCIvXCIpKVxuICBmcy5ta2RpclN5bmMob3B0aW9ucy5vdXRwdXQgKyBzaG9ydERpci5qb2luKFwiL1wiKSwge1xuICAgIHJlY3Vyc2l2ZTogdHJ1ZSxcbiAgfSlcbiAgZnMud3JpdGVGaWxlU3luYyhcbiAgICBvcHRpb25zLm91dHB1dCArIG5ld0FtZW5kbWVudC5wYXRoLmpvaW4oXCIvXCIpLnJlcGxhY2UoLyhcXC5qc29uKS8sIFwiLm5ldyQxXCIpLFxuICAgIEpTT04uc3RyaW5naWZ5KG5ld0FtZW5kbWVudC5kYXRhKSxcbiAgICB7IGVuY29kaW5nOiBcInV0ZjhcIiwgZmxhZzogXCJ3XCIgfSxcbiAgKVxufVxuXG4vLyBnZW5lcmF0ZXMgYSBmaWxlIHdpdGggYSBjb3B5IG9mIHRoZSBtb2RpZmllZCBkYXRhIG9mIHRoZSBwcmV2aW91c2x5IGV4aXN0aW5nIGFtZW5kbWVudDtcbmZ1bmN0aW9uIGdlbmVyYXRlU2luZ2xlRGlmZmVkQW1lbmRtZW50KGRpZmZlZEFtZW5kbWVudDoge1xuICBwYXRoOiBBcnJheTxzdHJpbmc+XG4gIGRhdGE6IGFueVxufSkge1xuICBkaWZmZWRBbWVuZG1lbnQucGF0aC5zaGlmdCgpXG5cbiAgY29uc3Qgc2hvcnREaXI6IEFycmF5PGFueT4gPSBbLi4uZGlmZmVkQW1lbmRtZW50LnBhdGhdXG4gIHNob3J0RGlyLnBvcCgpXG4gIGZzLm1rZGlyU3luYyhvcHRpb25zLm91dHB1dCArIHNob3J0RGlyLmpvaW4oXCIvXCIpLCB7XG4gICAgcmVjdXJzaXZlOiB0cnVlLFxuICB9KVxuXG4gIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgb3B0aW9ucy5vdXRwdXQgK1xuICAgICAgZGlmZmVkQW1lbmRtZW50LnBhdGguam9pbihcIi9cIikucmVwbGFjZSgvKFxcLmpzb24pLywgXCIuZGlmZiQxXCIpLFxuICAgIEpTT04uc3RyaW5naWZ5KGRpZmZlZEFtZW5kbWVudC5kYXRhKSxcbiAgICB7IGVuY29kaW5nOiBcInV0ZjhcIiwgZmxhZzogXCJ3XCIgfSxcbiAgKVxufVxuXG5kaWZmQW1lbmRlbWVudHMob3B0aW9ucy5kYXRhRGlyKVxuIl0sIm1hcHBpbmdz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