@tricoteuses/assemblee 1.9.13 → 1.10.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.
- package/README.md +0 -5
- package/lib/api.js +1 -1
- package/lib/api.mjs +1 -1
- package/lib/bugs/acteur-00010/plugin.test.js +5 -5
- package/lib/bugs/acteur-00010/plugin.test.mjs +1 -1
- package/lib/bugs/acteur-00010.js +17 -18
- package/lib/bugs/acteur-00010.mjs +1 -1
- package/lib/bugs/agenda-00002/plugin.test.js +6 -6
- package/lib/bugs/agenda-00002/plugin.test.mjs +1 -1
- package/lib/bugs/agenda-00002.js +31 -32
- package/lib/bugs/agenda-00002.mjs +3 -3
- package/lib/bugs/agenda-00008/plugin.test.js +5 -5
- package/lib/bugs/agenda-00008/plugin.test.mjs +1 -1
- package/lib/bugs/agenda-00008.js +17 -18
- package/lib/bugs/agenda-00008.mjs +1 -1
- package/lib/bugs/agenda-00011/plugin.test.js +10 -10
- package/lib/bugs/agenda-00011/plugin.test.mjs +1 -1
- package/lib/bugs/agenda-00011.js +28 -29
- package/lib/bugs/agenda-00011.mjs +3 -3
- package/lib/bugs.js +27 -29
- package/lib/bugs.mjs +3 -3
- package/lib/cleaners/actes_legislatifs.js +5 -5
- package/lib/cleaners/actes_legislatifs.mjs +1 -1
- package/lib/cleaners/acteurs.js +5 -5
- package/lib/cleaners/acteurs.mjs +1 -1
- package/lib/cleaners/amendements.js +5 -5
- package/lib/cleaners/amendements.mjs +1 -1
- package/lib/cleaners/debats.js +1 -1
- package/lib/cleaners/debats.mjs +1 -1
- package/lib/cleaners/documents.js +5 -5
- package/lib/cleaners/documents.mjs +1 -1
- package/lib/cleaners/dossiers_legislatifs.js +5 -5
- package/lib/cleaners/dossiers_legislatifs.mjs +1 -1
- package/lib/cleaners/index.d.ts +0 -1
- package/lib/cleaners/index.js +1 -8
- package/lib/cleaners/index.mjs +1 -2
- package/lib/cleaners/organes.js +2 -2
- package/lib/cleaners/organes.mjs +1 -1
- package/lib/cleaners/questions.js +1 -1
- package/lib/cleaners/questions.mjs +1 -1
- package/lib/cleaners/reunions.js +5 -5
- package/lib/cleaners/reunions.mjs +1 -1
- package/lib/cleaners/scrutins.js +8 -8
- package/lib/cleaners/scrutins.mjs +1 -1
- package/lib/cleaners/xml.js +8 -8
- package/lib/cleaners/xml.mjs +1 -1
- package/lib/datasets.d.ts +1 -13
- package/lib/datasets.js +10 -29
- package/lib/datasets.mjs +2 -21
- package/lib/dates.js +3 -4
- package/lib/dates.mjs +1 -1
- package/lib/dossiers_legislatifs.js +8 -8
- package/lib/dossiers_legislatifs.mjs +1 -1
- package/lib/file_systems.js +15 -14
- package/lib/file_systems.mjs +3 -3
- package/lib/git.js +5 -5
- package/lib/git.mjs +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +8 -1
- package/lib/index.mjs +2 -1
- package/lib/inserters.js +4 -4
- package/lib/inserters.mjs +1 -1
- package/lib/loaders.d.ts +0 -5
- package/lib/loaders.js +255 -299
- package/lib/loaders.mjs +1 -13
- package/lib/logger.js +1 -1
- package/lib/logger.mjs +1 -1
- package/lib/organes.js +1 -1
- package/lib/organes.mjs +1 -1
- package/lib/parsers/documents.js +11 -11
- package/lib/parsers/documents.mjs +1 -1
- package/lib/parsers/index.d.ts +1 -0
- package/lib/parsers/index.js +8 -1
- package/lib/parsers/index.mjs +2 -1
- package/lib/parsers/recherche_amendements.js +17 -15
- package/lib/parsers/recherche_amendements.mjs +1 -1
- package/lib/parsers/textes_lois.d.ts +22 -15
- package/lib/parsers/textes_lois.js +264 -752
- package/lib/parsers/textes_lois.mjs +249 -597
- package/lib/raw_types/acteurs_et_organes.js +9 -9
- package/lib/raw_types/acteurs_et_organes.mjs +1 -1
- package/lib/raw_types/agendas.d.ts +1 -0
- package/lib/raw_types/agendas.js +11 -10
- package/lib/raw_types/agendas.mjs +3 -2
- package/lib/raw_types/amendements.js +9 -9
- package/lib/raw_types/amendements.mjs +1 -1
- package/lib/raw_types/debats.js +9 -9
- package/lib/raw_types/debats.mjs +1 -1
- package/lib/raw_types/dossiers_legislatifs.js +9 -9
- package/lib/raw_types/dossiers_legislatifs.mjs +1 -1
- package/lib/raw_types/questions.js +9 -9
- package/lib/raw_types/questions.mjs +1 -1
- package/lib/raw_types/scrutins.js +9 -9
- package/lib/raw_types/scrutins.mjs +1 -1
- package/lib/scripts/bugs_helper.js +25 -26
- package/lib/scripts/bugs_helper.mjs +3 -3
- package/lib/scripts/clean_reorganized_data.js +256 -245
- package/lib/scripts/clean_reorganized_data.mjs +18 -29
- package/lib/scripts/diff_amendements.js +9 -8
- package/lib/scripts/diff_amendements.mjs +1 -1
- package/lib/scripts/document_dossiers_legislatifs.js +24 -27
- package/lib/scripts/document_dossiers_legislatifs.mjs +3 -3
- package/lib/scripts/get_today_reunions.js +3 -2
- package/lib/scripts/get_today_reunions.mjs +1 -1
- package/lib/scripts/merge_scrutins.js +9 -8
- package/lib/scripts/merge_scrutins.mjs +1 -1
- package/lib/scripts/parse_textes_lois.js +6 -5
- package/lib/scripts/parse_textes_lois.mjs +1 -1
- package/lib/scripts/process_open_dataset.d.ts +0 -2
- package/lib/scripts/process_open_dataset.js +19 -19
- package/lib/scripts/process_open_dataset.mjs +3 -5
- package/lib/scripts/raw_types_from_amendements.d.ts +0 -1
- package/lib/scripts/raw_types_from_amendements.js +122 -198
- package/lib/scripts/raw_types_from_amendements.mjs +105 -60
- package/lib/scripts/reorganize_data.js +14 -15
- package/lib/scripts/reorganize_data.mjs +3 -3
- package/lib/scripts/retrieve_deputes_photos.js +40 -31
- package/lib/scripts/retrieve_deputes_photos.mjs +10 -2
- package/lib/scripts/retrieve_documents.d.ts +1 -1
- package/lib/scripts/retrieve_documents.js +230 -138
- package/lib/scripts/retrieve_documents.mjs +87 -38
- package/lib/scripts/retrieve_open_data.js +27 -30
- package/lib/scripts/retrieve_open_data.mjs +5 -8
- package/lib/scripts/retrieve_pending_amendments.js +14 -14
- package/lib/scripts/retrieve_pending_amendments.mjs +1 -1
- package/lib/scripts/retrieve_senateurs_photos.js +10 -10
- package/lib/scripts/retrieve_senateurs_photos.mjs +1 -1
- package/lib/scripts/retrieve_textes_lois.js +17 -15
- package/lib/scripts/retrieve_textes_lois.mjs +1 -1
- package/lib/scripts/shared/cli_helpers.d.ts +11 -0
- package/lib/scripts/shared/cli_helpers.js +13 -2
- package/lib/scripts/shared/cli_helpers.mjs +12 -1
- package/lib/scripts/test_iter_load.js +5 -19
- package/lib/scripts/test_iter_load.mjs +2 -9
- package/lib/scripts/test_load.js +2 -2
- package/lib/scripts/test_load.mjs +1 -1
- package/lib/scripts/test_load_big_files.js +2 -2
- package/lib/scripts/test_load_big_files.mjs +1 -1
- package/lib/scripts/validate_json.js +17 -18
- package/lib/scripts/validate_json.mjs +3 -3
- package/lib/shared_types/codes_actes.js +1 -1
- package/lib/shared_types/codes_actes.mjs +1 -1
- package/lib/strings.js +1 -1
- package/lib/strings.mjs +1 -1
- package/lib/types/acteurs_et_organes.js +9 -9
- package/lib/types/acteurs_et_organes.mjs +1 -1
- package/lib/types/agendas.d.ts +1 -0
- package/lib/types/agendas.js +11 -10
- package/lib/types/agendas.mjs +3 -2
- package/lib/types/amendements.js +9 -9
- package/lib/types/amendements.mjs +1 -1
- package/lib/types/debats.js +9 -9
- package/lib/types/debats.mjs +1 -1
- package/lib/types/dossiers_legislatifs.d.ts +13 -0
- package/lib/types/dossiers_legislatifs.js +47 -9
- package/lib/types/dossiers_legislatifs.mjs +39 -1
- package/lib/types/legislatures.js +1 -1
- package/lib/types/legislatures.mjs +1 -1
- package/lib/types/questions.js +9 -9
- package/lib/types/questions.mjs +1 -1
- package/lib/types/scrutins.js +9 -9
- package/lib/types/scrutins.mjs +1 -1
- package/lib/urls.js +2 -2
- package/lib/urls.mjs +1 -1
- package/package.json +14 -20
- package/lib/cleaners/textes_loi.d.ts +0 -1
- package/lib/cleaners/textes_loi.js +0 -12
- package/lib/cleaners/textes_loi.mjs +0 -5
- package/lib/examples/PIONANR5L15B0020/input.d.ts +0 -2
- package/lib/examples/PIONANR5L15B0020/input.js +0 -10
- package/lib/examples/PIONANR5L15B0020/input.mjs +0 -193
- package/lib/examples/PIONANR5L15B0020/input.ts +0 -193
- package/lib/examples/PIONANR5L15B0020/loi.json +0 -26
- package/lib/examples/PIONANR5L15B0020/loi_populated.json +0 -29
- package/lib/examples/PIONANR5L15B0020/meta.json +0 -28
- package/lib/examples/PIONANR5L15B0020/motifs.json +0 -5
- package/lib/examples/PIONANR5L15B0020/motifs_populated.json +0 -6
- package/lib/examples/PIONANR5L15B0020/sommaire.json +0 -3
- package/lib/examples/PRJLANR5L16B0914/input.d.ts +0 -2
- package/lib/examples/PRJLANR5L16B0914/input.js +0 -10
- package/lib/examples/PRJLANR5L16B0914/input.mjs +0 -322
- package/lib/examples/PRJLANR5L16B0914/input.ts +0 -322
- package/lib/examples/PRJLANR5L16B0914/loi.json +0 -14
- package/lib/examples/PRJLANR5L16B0914/loi_populated.json +0 -20
- package/lib/examples/PRJLANR5L16B0914/meta.json +0 -35
- package/lib/examples/PRJLANR5L16B0914/motifs.json +0 -4
- package/lib/examples/PRJLANR5L16B0914/motifs_populated.json +0 -5
- package/lib/examples/PRJLANR5L16B0914/sommaire.json +0 -3
- package/lib/examples/PRJLANR5L16B2014/README.md +0 -2
- package/lib/examples/PRJLANR5L16B2014/input.d.ts +0 -2
- package/lib/examples/PRJLANR5L16B2014/input.js +0 -10
- package/lib/examples/PRJLANR5L16B2014/input.mjs +0 -577
- package/lib/examples/PRJLANR5L16B2014/input.ts +0 -577
- package/lib/examples/PRJLANR5L16B2014/loi.json +0 -369
- package/lib/examples/PRJLANR5L16B2014/meta.json +0 -31
- package/lib/examples/PRJLANR5L16B2014/motifs.json +0 -5
- package/lib/examples/PRJLANR5L16B2014/sommaire.json +0 -51
- package/lib/examples/PRJLANR5L16B2424/alineas.json +0 -44
- package/lib/examples/PRJLANR5L16B2424/input.d.ts +0 -2
- package/lib/examples/PRJLANR5L16B2424/input.js +0 -10
- package/lib/examples/PRJLANR5L16B2424/input.mjs +0 -322
- package/lib/examples/PRJLANR5L16B2424/input.ts +0 -322
- package/lib/examples/PRJLANR5L16B2424/loi.json +0 -74
- package/lib/examples/PRJLANR5L16B2424/loi_populated.json +0 -87
- package/lib/examples/PRJLANR5L16B2424/meta.json +0 -31
- package/lib/examples/PRJLANR5L16B2424/motifs.json +0 -4
- package/lib/examples/PRJLANR5L16B2424/motifs_populated.json +0 -5
- package/lib/examples/PRJLANR5L16B2424/sommaire.json +0 -3
- package/lib/examples/PRJLANR5L16B2462/input.d.ts +0 -2
- package/lib/examples/PRJLANR5L16B2462/input.js +0 -10
- package/lib/examples/PRJLANR5L16B2462/input.mjs +0 -1308
- package/lib/examples/PRJLANR5L16B2462/input.ts +0 -1308
- package/lib/examples/PRJLANR5L16B2462/loi.json +0 -74
- package/lib/examples/PRJLANR5L16B2462/loi_populated.json +0 -310
- package/lib/examples/PRJLANR5L16B2462/meta.json +0 -29
- package/lib/examples/PRJLANR5L16B2462/motifs.json +0 -6
- package/lib/examples/PRJLANR5L16B2462/motifs_populated.json +0 -6
- package/lib/examples/PRJLANR5L16B2462/sommaire.json +0 -50
- package/lib/examples/README.md +0 -3
- package/lib/raw_types/textes_loi.d.ts +0 -93
- package/lib/raw_types/textes_loi.js +0 -429
- package/lib/raw_types/textes_loi.mjs +0 -378
- package/lib/schemas/texte_loi/Alinea.json +0 -36
- package/lib/schemas/texte_loi/ExposeMotifs.json +0 -24
- package/lib/schemas/texte_loi/MetaDonnees.json +0 -126
- package/lib/schemas/texte_loi/ProjetLoi.json +0 -64
- package/lib/schemas/texte_loi/Sommaire.json +0 -48
- package/lib/schemas/texte_loi/TexteLoi.json +0 -225
- package/lib/schemas/texte_loi/TexteLoiPartiel.json +0 -237
- package/lib/scripts/process_textes_loi_dataset.d.ts +0 -7
- package/lib/scripts/process_textes_loi_dataset.js +0 -373
- package/lib/scripts/process_textes_loi_dataset.mjs +0 -239
- package/lib/types/textes_loi.d.ts +0 -94
- package/lib/types/textes_loi.js +0 -429
- package/lib/types/textes_loi.mjs +0 -378
|
@@ -1,608 +1,260 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* LLM model.
|
|
56
|
-
*/
|
|
57
|
-
let MODEL = null;
|
|
58
|
-
if (process.env.OPENAI_API_KEY) {
|
|
59
|
-
MODEL = new ChatOpenAI({
|
|
60
|
-
temperature: 0,
|
|
61
|
-
topP: 0.0,
|
|
62
|
-
model: "gpt-4o-mini",
|
|
63
|
-
apiKey: process.env.OPENAI_API_KEY,
|
|
64
|
-
maxTokens: -1
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* System input template for the LLM.
|
|
70
|
-
*/
|
|
71
|
-
const SYSTEM_TEMPLATE = `
|
|
72
|
-
# Instructions :
|
|
73
|
-
|
|
74
|
-
Tu es un expert de la loi et de l'analyse de pages HTML.
|
|
75
|
-
Tu dois analyser un texte de loi afin de séparer et de structurer les éléments qui le composent. Le format d'entrée est HTML.
|
|
76
|
-
|
|
77
|
-
Le texte est divisé en deux parties :
|
|
78
|
-
A) un exposé des motifs qui indique les raisons pour lesquelles ce projet est soumis au Parlement. Il peut contenir 3 éléments : 1) une citation au début d'un document, 2) le texte principal qui développe les arguments de l'auteur à l'appui de la modification législative ou des dispositions nouvelles qu'il propose, 3) des paragraphes qui présentent les articles.
|
|
79
|
-
B) le dispositif qui est la partie normative et rédigée en articles. Il peut comporter des divisions nommées titres, chapitres, sections, sous-sections. Lorsqu'il y a un seul niveau de structure, on retrouvera le chapitre ; s’il y a deux niveaux de structure, on retrouvera des chapitres puis des sections. S’il y a trois niveaux de structure, on retrouvera des titres puis des chapitres puis des sections.
|
|
80
|
-
|
|
81
|
-
Si le texte de loi ne comporte pas de division, le sommaire doit rester vide.
|
|
82
|
-
Toutes les lignes qui débutent par un '«' ne sont pas à prendre en compte dans les divisions
|
|
83
|
-
Ta réponse doit être un JSON structuré avec les éléments du texte de loi en respectant le schéma JSON fourni.
|
|
84
|
-
`;
|
|
85
|
-
let SILENT_LOG = false;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Parses the given HTML string and returns the parsed textes loi.
|
|
89
|
-
*
|
|
90
|
-
* @param {string} html - The HTML string to parse.
|
|
91
|
-
* @return {Promise<{partial: {sommaire: any, loi: any, motifs: any, meta: any}, completed: {sommaire: any, loi: any, motifs: any, meta: any}}>} - The parsed textes loi, including the partial and completed versions.
|
|
92
|
-
*/
|
|
93
|
-
export async function parseTexteLoi(html, options = {
|
|
94
|
-
silent: false
|
|
95
|
-
}) {
|
|
96
|
-
SILENT_LOG = options.silent;
|
|
97
|
-
runLogFun(console.info("Start extracting loi..."), options);
|
|
98
|
-
const meta = await extractMetaDonnees(html);
|
|
99
|
-
const sommaire = await extractSommaire(html);
|
|
100
|
-
const partialMotifs = await extractMotifs(html);
|
|
101
|
-
const partialLoi = await extractProjetLoi(html);
|
|
102
|
-
const exposeMotifs = await populateMotifs(partialMotifs, html);
|
|
103
|
-
const loi = await populateProjetLoi(partialLoi, html);
|
|
104
|
-
return {
|
|
105
|
-
sommaire,
|
|
106
|
-
loi,
|
|
107
|
-
exposeMotifs,
|
|
108
|
-
meta
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Cleans the given HTML string by removing unnecessary tags and content.
|
|
114
|
-
*
|
|
115
|
-
* @param {string} html - The HTML string to be cleaned.
|
|
116
|
-
* @return {string} The cleaned HTML string.
|
|
117
|
-
*/
|
|
118
|
-
function cleanHtml(html) {
|
|
119
|
-
let cleanedHtml = html.replace(/(<style[\w\W]+style>)/g, "");
|
|
120
|
-
cleanedHtml = cleanedHtml.replace(/(<head[\w\W]+head>)/g, "");
|
|
121
|
-
cleanedHtml = cleanedHtml.replace(/<img[^>]*>/g, "");
|
|
122
|
-
return cleanedHtml;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Removes all HTML tags from the given HTML string and returns the cleaned text.
|
|
127
|
-
*
|
|
128
|
-
* @param {string} html - The HTML string from which to remove tags.
|
|
129
|
-
* @return {string} The cleaned text without any HTML tags.
|
|
130
|
-
*/
|
|
131
|
-
function removeHtmlTags(html) {
|
|
132
|
-
// Regular expression to match HTML tags
|
|
133
|
-
const htmlTagRegex = /<[^>]*>/g;
|
|
134
|
-
|
|
135
|
-
// Replace all HTML tags with an empty string
|
|
136
|
-
const textWithoutTags = html.replace(htmlTagRegex, "");
|
|
137
|
-
return textWithoutTags;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Populates the motifs object with the extracted text from the given HTML.
|
|
142
|
-
*
|
|
143
|
-
* @param {Record<string, any>} motifs - The motifs object to be populated.
|
|
144
|
-
* @param {string} html - The HTML string from which to extract the text.
|
|
145
|
-
* @return {Promise<Record<string, any>>} - The populated motifs object.
|
|
146
|
-
*/
|
|
147
|
-
async function populateMotifs(motifs, html) {
|
|
148
|
-
runLogFun(console.info("Populating expose motifs..."));
|
|
149
|
-
let cleanedHtml = cleanHtml(html);
|
|
150
|
-
if (motifs.debut === motifs.fin || !motifs.fin) {
|
|
151
|
-
motifs.texte = motifs.debut;
|
|
152
|
-
} else {
|
|
153
|
-
const systemTemplate = `
|
|
154
|
-
# Instructions :
|
|
155
|
-
|
|
156
|
-
Tu es un expert de la loi et de l'analyse de pages HTML.
|
|
157
|
-
Tu dois analyser un texte de loi afin d'en extraire certaines parties.
|
|
158
|
-
Le format d'entrée est du HTML. Le format de sortie est du texte.
|
|
159
|
-
Récupère l'intégralité du texte commençant par :
|
|
160
|
-
|
|
161
|
-
"""
|
|
162
|
-
{debut}
|
|
163
|
-
"""
|
|
164
|
-
|
|
165
|
-
Et finissant par :
|
|
166
|
-
|
|
167
|
-
"""
|
|
168
|
-
{fin}
|
|
169
|
-
"""
|
|
170
|
-
`;
|
|
171
|
-
const prompt = ChatPromptTemplate.fromMessages([["system", systemTemplate], ["human", "{input}"]]);
|
|
172
|
-
const structuredModel = MODEL.withStructuredOutput(FULL_TEXTE_SCHEMA);
|
|
173
|
-
const chain = prompt.pipe(structuredModel);
|
|
174
|
-
const articlePromptResult = await chain.invoke({
|
|
175
|
-
input: cleanedHtml,
|
|
176
|
-
debut: motifs.debut,
|
|
177
|
-
fin: motifs.fin
|
|
178
|
-
});
|
|
179
|
-
motifs.texte = articlePromptResult.texte;
|
|
180
|
-
}
|
|
181
|
-
runLogFun(console.info("Opération de peuplement de l'exposé des motifs terminée ✅"), {
|
|
182
|
-
silent: SILENT_LOG
|
|
183
|
-
});
|
|
184
|
-
delimiter(SILENT_LOG);
|
|
185
|
-
delete motifs.debut;
|
|
186
|
-
delete motifs.fin;
|
|
187
|
-
return motifs;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Asynchronously populates a projet loi object with the full text of each article and alinea in the given HTML.
|
|
192
|
-
*
|
|
193
|
-
* @param {Record<string, any>} partial - The partial projet loi object to be populated.
|
|
194
|
-
* @param {string} html - The HTML containing the text of the articles and alineas.
|
|
195
|
-
* @return {Promise<Record<string, any>>} A Promise that resolves to the fully populated projet loi object.
|
|
196
|
-
*/
|
|
197
|
-
async function populateProjetLoi(partial, html) {
|
|
198
|
-
runLogFun(console.group("Peuplement du projet loi..."), {
|
|
199
|
-
silent: SILENT_LOG
|
|
200
|
-
});
|
|
201
|
-
let cleanedHtml = cleanHtml(html);
|
|
202
|
-
const articles = partial.articles;
|
|
203
|
-
const fullArticles = [];
|
|
204
|
-
const systemTemplate = `
|
|
205
|
-
# Instructions :
|
|
206
|
-
|
|
207
|
-
Tu es un expert de la loi et de l'analyse de pages HTML.
|
|
208
|
-
Tu dois analyser un texte de loi afin d'en extraire certaines parties.
|
|
209
|
-
Le format d'entrée est du HTML. Le format de sortie est du texte.
|
|
210
|
-
Récupère l'intégralité du texte commençant par :
|
|
211
|
-
|
|
212
|
-
"""
|
|
213
|
-
{debut}
|
|
214
|
-
"""
|
|
215
|
-
|
|
216
|
-
Et finissant par :
|
|
217
|
-
|
|
218
|
-
"""
|
|
219
|
-
{fin}
|
|
220
|
-
"""
|
|
221
|
-
`;
|
|
222
|
-
const prompt = ChatPromptTemplate.fromMessages([["system", systemTemplate], ["human", "{input}"]]);
|
|
223
|
-
const structuredModel = MODEL.withStructuredOutput(FULL_TEXTE_SCHEMA);
|
|
224
|
-
const chain = prompt.pipe(structuredModel);
|
|
225
|
-
for (const article of articles) {
|
|
226
|
-
if (article.debut === article.fin || !article.fin) {
|
|
227
|
-
article.texte = article.debut;
|
|
228
|
-
} else {
|
|
229
|
-
const articlePromptResult = await chain.invoke({
|
|
230
|
-
input: cleanedHtml,
|
|
231
|
-
debut: article.debut,
|
|
232
|
-
fin: article.fin
|
|
233
|
-
});
|
|
234
|
-
article.texte = articlePromptResult.texte;
|
|
1
|
+
import assert from "assert";
|
|
2
|
+
import { JSDOM } from "jsdom";
|
|
3
|
+
function parseHeader(header) {
|
|
4
|
+
const headersMapping = [{
|
|
5
|
+
regex: /^(RAPPORT_)?ANNEXE(_|$)|^ETAT_/,
|
|
6
|
+
level: 0,
|
|
7
|
+
name: "Annexe"
|
|
8
|
+
}, {
|
|
9
|
+
regex: /^TOME_/,
|
|
10
|
+
level: 1,
|
|
11
|
+
name: "Tome"
|
|
12
|
+
}, {
|
|
13
|
+
regex: /^PARTIE_|^(PREMIERE|SECONDE|DEUXIEME|TROISIEME|QUATRIEME)_PARTIE(_|$)/,
|
|
14
|
+
level: 2,
|
|
15
|
+
name: "Partie"
|
|
16
|
+
}, {
|
|
17
|
+
regex: /^LIVRE_/,
|
|
18
|
+
level: 3,
|
|
19
|
+
name: "Livre"
|
|
20
|
+
}, {
|
|
21
|
+
regex: /^TITRE_/,
|
|
22
|
+
level: 4,
|
|
23
|
+
name: "Titre"
|
|
24
|
+
}, {
|
|
25
|
+
regex: /^SOUSTITRE_/,
|
|
26
|
+
level: 5,
|
|
27
|
+
name: "SousTitre"
|
|
28
|
+
}, {
|
|
29
|
+
regex: /^CHAPITRE_/,
|
|
30
|
+
level: 6,
|
|
31
|
+
name: "Chapitre"
|
|
32
|
+
}, {
|
|
33
|
+
regex: /^SECTION_/,
|
|
34
|
+
level: 7,
|
|
35
|
+
name: "Section"
|
|
36
|
+
}, {
|
|
37
|
+
regex: /^SOUSSECTION_/,
|
|
38
|
+
level: 8,
|
|
39
|
+
name: "SousSection"
|
|
40
|
+
}, {
|
|
41
|
+
regex: /^ARTICLES?_|^EXPOSE_DES_MOTIFS$/,
|
|
42
|
+
level: 9,
|
|
43
|
+
name: "Article"
|
|
44
|
+
}];
|
|
45
|
+
for (let {
|
|
46
|
+
regex,
|
|
47
|
+
level,
|
|
48
|
+
name
|
|
49
|
+
} of headersMapping) {
|
|
50
|
+
if (header.match(regex)) {
|
|
51
|
+
return [level, name];
|
|
235
52
|
}
|
|
236
|
-
for (const alinea of article.alineas) {
|
|
237
|
-
if (alinea.debut === alinea.fin || !alinea.fin) {
|
|
238
|
-
alinea.texte = alinea.debut;
|
|
239
|
-
continue;
|
|
240
|
-
}
|
|
241
|
-
const alineaPromptResult = await chain.invoke({
|
|
242
|
-
input: article.texte,
|
|
243
|
-
debut: alinea.debut,
|
|
244
|
-
fin: alinea.fin
|
|
245
|
-
});
|
|
246
|
-
delete alinea.debut;
|
|
247
|
-
delete alinea.fin;
|
|
248
|
-
alinea.texte = alineaPromptResult.texte;
|
|
249
|
-
}
|
|
250
|
-
runLogFun(console.info("Opération de peuplement du contenu du projet de loi terminée ✅"), {
|
|
251
|
-
silent: SILENT_LOG
|
|
252
|
-
});
|
|
253
|
-
delete article.debut;
|
|
254
|
-
delete article.fin;
|
|
255
|
-
fullArticles.push(article);
|
|
256
53
|
}
|
|
257
|
-
|
|
258
|
-
...partial,
|
|
259
|
-
articles: fullArticles
|
|
260
|
-
};
|
|
261
|
-
runLogFun(console.groupEnd(), {
|
|
262
|
-
silent: SILENT_LOG
|
|
263
|
-
});
|
|
264
|
-
delimiter();
|
|
265
|
-
return projetLoi;
|
|
54
|
+
return [null, ""];
|
|
266
55
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
* Asynchronously extracts the "expose motifs" from the given HTML.
|
|
270
|
-
*
|
|
271
|
-
* @param {string} html - The HTML string from which to extract the "expose motifs".
|
|
272
|
-
* @return {Promise<Record<string, any>>} - A Promise that resolves to the extracted "expose motifs" object.
|
|
273
|
-
* The object contains the following properties:
|
|
274
|
-
* - `debut`: The beginning of the "expose motifs".
|
|
275
|
-
* - `fin`: The end of the "expose motifs".
|
|
276
|
-
* @throws {Error} - If the extracted "expose motifs" do not validate against the EXPOSE_MOTIFS_SCHEMA.
|
|
277
|
-
*/
|
|
278
|
-
async function extractMotifs(html) {
|
|
279
|
-
runLogFun(console.group("Parsing expose motifs..."), {
|
|
280
|
-
silent: SILENT_LOG
|
|
281
|
-
});
|
|
282
|
-
let cleanedHtml = cleanHtml(html);
|
|
283
|
-
cleanedHtml = removeHtmlTags(cleanedHtml);
|
|
284
|
-
const structuredModel = MODEL.withStructuredOutput(EXPOSE_MOTIFS_SCHEMA);
|
|
285
|
-
const motifsSystemTemplate = `
|
|
286
|
-
${SYSTEM_TEMPLATE}
|
|
287
|
-
|
|
288
|
-
# Examples:
|
|
289
|
-
|
|
290
|
-
## Exemple 1 User Input :
|
|
291
|
-
"""
|
|
292
|
-
{example1}
|
|
293
|
-
"""
|
|
294
|
-
|
|
295
|
-
## Exemple 1 JSON Output :
|
|
296
|
-
"""
|
|
297
|
-
{output1}
|
|
298
|
-
"""
|
|
299
|
-
|
|
300
|
-
## Exemple 2 User Input :
|
|
301
|
-
"""
|
|
302
|
-
{example2}
|
|
303
|
-
"""
|
|
304
|
-
|
|
305
|
-
## Exemple 2 JSON Output :
|
|
306
|
-
"""
|
|
307
|
-
{output2}
|
|
308
|
-
"""
|
|
309
|
-
`;
|
|
310
|
-
const prompt = ChatPromptTemplate.fromMessages([["system", motifsSystemTemplate], ["human", "{input}"]]);
|
|
311
|
-
const chain = prompt.pipe(structuredModel);
|
|
312
|
-
const motifsPromptResult = await chain.invoke({
|
|
313
|
-
input: cleanedHtml,
|
|
314
|
-
example1: EXAMPLES.PRJLANR5L16B0914.input,
|
|
315
|
-
example2: EXAMPLES.PRJLANR5L16B2424.input,
|
|
316
|
-
output1: EXAMPLES.PRJLANR5L16B0914.motifs,
|
|
317
|
-
output2: EXAMPLES.PRJLANR5L16B2424.motifs
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
// console.log(JSON.stringify(motifsPromptResult))
|
|
321
|
-
runLogFun(console.table([["Début", motifsPromptResult.debut.substring(0, 30)], ["Fin", motifsPromptResult.fin.substring(0, 30)]]), {
|
|
322
|
-
silent: SILENT_LOG
|
|
323
|
-
});
|
|
324
|
-
runLogFun(console.groupEnd(), {
|
|
325
|
-
silent: SILENT_LOG
|
|
326
|
-
});
|
|
327
|
-
delimiter();
|
|
328
|
-
const ajv = new Ajv();
|
|
329
|
-
if (ajv.validate(EXPOSE_MOTIFS_SCHEMA, motifsPromptResult)) {
|
|
330
|
-
runLogFun(console.info("Exposé des motifs OK 👌"), {
|
|
331
|
-
silent: SILENT_LOG
|
|
332
|
-
});
|
|
333
|
-
return motifsPromptResult;
|
|
334
|
-
}
|
|
335
|
-
runLogFun(console.warn("Exposé des motifs KO ❌"), {
|
|
336
|
-
silent: SILENT_LOG
|
|
337
|
-
});
|
|
338
|
-
return {};
|
|
56
|
+
function cleanText(text) {
|
|
57
|
+
return text?.replace(/[\n\t]+/g, "").trim() || "";
|
|
339
58
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
${SYSTEM_TEMPLATE}
|
|
360
|
-
`;
|
|
361
|
-
const prompt = ChatPromptTemplate.fromMessages([["system", metaDonneesSystemTemplate], ["human", "{input}"]]);
|
|
362
|
-
const chain = prompt.pipe(structuredModel);
|
|
363
|
-
const result = await chain.invoke({
|
|
364
|
-
input: cleanedHtml,
|
|
365
|
-
example1: EXAMPLES.PRJLANR5L16B0914.input,
|
|
366
|
-
example2: EXAMPLES.PRJLANR5L16B2424.input,
|
|
367
|
-
output1: EXAMPLES.PRJLANR5L16B0914.meta,
|
|
368
|
-
output2: EXAMPLES.PRJLANR5L16B2424.meta
|
|
369
|
-
});
|
|
370
|
-
console.group("Meta-données");
|
|
371
|
-
console.table([["Référence", result.documentRef], ["Titre", result.titre], ["Numéro du texte", result.numeroTexte], ["Procédure accéléré", result.procedureAcceleree]]);
|
|
372
|
-
console.groupEnd();
|
|
373
|
-
delimiter();
|
|
374
|
-
const ajv = new Ajv();
|
|
375
|
-
if (ajv.validate(META_DONNEES_SCHEMA, result)) {
|
|
376
|
-
runLogFun(console.warn("Meta-données OK 👌"), {
|
|
377
|
-
silent: SILENT_LOG
|
|
378
|
-
});
|
|
379
|
-
return result;
|
|
380
|
-
}
|
|
381
|
-
runLogFun(console.warn("Meta-données non-conforme ❌"), {
|
|
382
|
-
silent: SILENT_LOG
|
|
383
|
-
});
|
|
384
|
-
return {};
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* Asynchronously extracts the "projet de loi" from the given HTML.
|
|
389
|
-
*
|
|
390
|
-
* @param {string} html - The HTML string from which to extract the "projet de loi".
|
|
391
|
-
* @return {Promise<Record<string, any>>} - A Promise that resolves to the extracted "projet de loi" object.
|
|
392
|
-
* The object contains the following properties:
|
|
393
|
-
* - `articles`: An array of article objects, each containing the following properties:
|
|
394
|
-
* - `numeroArticle`: The number of the article.
|
|
395
|
-
* - `cardinal`: The cardinal of the article.
|
|
396
|
-
* - `titre`: The title of the article.
|
|
397
|
-
* - `debut`: The beginning of the article.
|
|
398
|
-
* - `fin`: The end of the article.
|
|
399
|
-
* - `alineas`: An array of alineas.
|
|
400
|
-
* @throws {Error} - If the extracted "projet de loi" does not validate against the PROJET_LOI_SCHEMA.
|
|
401
|
-
*/
|
|
402
|
-
async function extractProjetLoi(html) {
|
|
403
|
-
runLogFun(console.group("Parsing loi..."), {
|
|
404
|
-
silent: SILENT_LOG
|
|
405
|
-
});
|
|
406
|
-
let cleanedHtml = cleanHtml(html);
|
|
407
|
-
const structuredModel = MODEL.withStructuredOutput(PROJET_LOI_SCHEMA);
|
|
408
|
-
const projetLoiSystemTemplate = `
|
|
409
|
-
${SYSTEM_TEMPLATE}
|
|
410
|
-
|
|
411
|
-
# Examples:
|
|
412
|
-
|
|
413
|
-
## Exemple 1 User Input :
|
|
414
|
-
"""
|
|
415
|
-
{example1}
|
|
416
|
-
"""
|
|
417
|
-
|
|
418
|
-
## Exemple 1 JSON Output :
|
|
419
|
-
"""
|
|
420
|
-
{output1}
|
|
421
|
-
"""
|
|
422
|
-
|
|
423
|
-
## Exemple 2 User Input :
|
|
424
|
-
"""
|
|
425
|
-
{example2}
|
|
426
|
-
"""
|
|
427
|
-
|
|
428
|
-
## Exemple 2 JSON Output :
|
|
429
|
-
"""
|
|
430
|
-
{output2}
|
|
431
|
-
"""
|
|
432
|
-
`;
|
|
433
|
-
const prompt = ChatPromptTemplate.fromMessages([["system", projetLoiSystemTemplate], ["human", "{input}"]]);
|
|
434
|
-
const chain = prompt.pipe(structuredModel);
|
|
435
|
-
const articlesPromptResult = await chain.invoke({
|
|
436
|
-
input: cleanedHtml,
|
|
437
|
-
example1: EXAMPLES.PRJLANR5L16B0914.input,
|
|
438
|
-
example2: EXAMPLES.PRJLANR5L16B2424.input,
|
|
439
|
-
output1: EXAMPLES.PRJLANR5L16B0914.loi,
|
|
440
|
-
output2: EXAMPLES.PRJLANR5L16B2424.loi
|
|
441
|
-
});
|
|
442
|
-
runLogFun(console.log("Found ", articlesPromptResult.articles.length, " articles."), {
|
|
443
|
-
silent: SILENT_LOG
|
|
444
|
-
});
|
|
445
|
-
for (const article of articlesPromptResult.articles) {
|
|
446
|
-
article.alineas = await extractAlineas(html, article);
|
|
447
|
-
}
|
|
448
|
-
runLogFun(console.table(articlesPromptResult.articles.map(article => [article.numeroArticle, article.titre, article.debut.substring(0, 10), article.fin.substring(0, 10), `Nombre d'alineas : ${article.alineas.length}`])), {
|
|
449
|
-
silent: SILENT_LOG
|
|
450
|
-
});
|
|
451
|
-
runLogFun(console.groupEnd(), {
|
|
452
|
-
silent: SILENT_LOG
|
|
453
|
-
});
|
|
454
|
-
const ajv = new Ajv();
|
|
455
|
-
if (ajv.validate(PROJET_LOI_SCHEMA, articlesPromptResult)) {
|
|
456
|
-
runLogFun(console.info("Projet de loi OK 👌"), {
|
|
457
|
-
silent: SILENT_LOG
|
|
458
|
-
});
|
|
459
|
-
delimiter();
|
|
460
|
-
return articlesPromptResult;
|
|
461
|
-
}
|
|
462
|
-
runLogFun(console.warn("Projet de loi KO ❌"), {
|
|
463
|
-
silent: SILENT_LOG
|
|
464
|
-
});
|
|
465
|
-
delimiter();
|
|
466
|
-
return {};
|
|
467
|
-
}
|
|
468
|
-
async function extractAlineas(html, article) {
|
|
469
|
-
runLogFun(console.group("Parsing alineas..."), {
|
|
470
|
-
silent: SILENT_LOG
|
|
471
|
-
});
|
|
472
|
-
let cleanedHtml = cleanHtml(html);
|
|
473
|
-
const structuredModel = MODEL.withStructuredOutput(ALINEA_SCHEMA);
|
|
474
|
-
const alineasSystemTemplate = `
|
|
475
|
-
${SYSTEM_TEMPLATE}
|
|
476
|
-
|
|
477
|
-
Extrais tous les alineas de la portion de texte commençant par « {debut} » et finissant par « {fin} ».
|
|
478
|
-
Un alinéa contiennent toujours une balise « <img ».
|
|
479
|
-
|
|
480
|
-
# Examples:
|
|
481
|
-
|
|
482
|
-
## Exemple 1 User Input :
|
|
483
|
-
"""
|
|
484
|
-
{example1}
|
|
485
|
-
"""
|
|
486
|
-
|
|
487
|
-
## Exemple 1 JSON Output :
|
|
488
|
-
"""
|
|
489
|
-
{output1}
|
|
490
|
-
"""
|
|
491
|
-
`;
|
|
492
|
-
const prompt = ChatPromptTemplate.fromMessages([["system", alineasSystemTemplate], ["human", "{input}"]]);
|
|
493
|
-
const chain = prompt.pipe(structuredModel);
|
|
494
|
-
const alineasPromptResult = await chain.invoke({
|
|
495
|
-
input: cleanedHtml,
|
|
496
|
-
debut: article.debut,
|
|
497
|
-
fin: article.fin,
|
|
498
|
-
example1: EXAMPLES.PRJLANR5L16B2424.input,
|
|
499
|
-
output1: EXAMPLES.PRJLANR5L16B2424.alineas
|
|
500
|
-
});
|
|
501
|
-
const ajv = new Ajv();
|
|
502
|
-
if (ajv.validate(ALINEA_SCHEMA, alineasPromptResult)) {
|
|
503
|
-
runLogFun(console.info("Found ", alineasPromptResult.alineas.length, " alineas for Article ", article.numeroArticle, article.titre), {
|
|
504
|
-
silent: SILENT_LOG
|
|
505
|
-
});
|
|
506
|
-
runLogFun(console.groupEnd(), {
|
|
507
|
-
silent: SILENT_LOG
|
|
508
|
-
});
|
|
509
|
-
delimiter();
|
|
510
|
-
return alineasPromptResult.alineas;
|
|
511
|
-
}
|
|
512
|
-
runLogFun(console.warn("Alineas KO"), {
|
|
513
|
-
silent: SILENT_LOG
|
|
514
|
-
});
|
|
515
|
-
delimiter();
|
|
516
|
-
return {};
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
/**
|
|
520
|
-
* Asynchronously extracts the "sommaire" (outline) from the given HTML.
|
|
521
|
-
*
|
|
522
|
-
* @param {string} html - The HTML string from which to extract the "sommaire".
|
|
523
|
-
* @return {Promise<Record<string, any>>} - A Promise that resolves to the extracted "sommaire" object.
|
|
524
|
-
* The object contains the following properties:
|
|
525
|
-
* - `sommaire`: An array of main division objects, each containing the following properties:
|
|
526
|
-
* - `numeroDivision`: The number of the main division.
|
|
527
|
-
* - `titre`: The title of the main division.
|
|
528
|
-
* - `typeDivision`: The type of content in the main division.
|
|
529
|
-
* - `sequence`: The sequence of the main division.
|
|
530
|
-
* - `parent`: The parent of the main division.
|
|
531
|
-
* @throws {Error} - If the extracted "sommaire" does not validate against the SOMMAIRE_SCHEMA.
|
|
532
|
-
*/
|
|
533
|
-
async function extractSommaire(html) {
|
|
534
|
-
let cleanedHtml = cleanHtml(html);
|
|
535
|
-
cleanedHtml = removeHtmlTags(cleanedHtml);
|
|
536
|
-
const structuredModel = MODEL.withStructuredOutput(SOMMAIRE_SCHEMA);
|
|
537
|
-
const sommaireSystemTemplate = `
|
|
538
|
-
${SYSTEM_TEMPLATE}
|
|
539
|
-
|
|
540
|
-
# Examples:
|
|
541
|
-
|
|
542
|
-
## Exemple 1 User Input :
|
|
543
|
-
"""
|
|
544
|
-
{example1}
|
|
545
|
-
"""
|
|
546
|
-
|
|
547
|
-
## Exemple 1 JSON Output :
|
|
548
|
-
"""
|
|
549
|
-
{output1}
|
|
550
|
-
"""
|
|
551
|
-
|
|
552
|
-
## Exemple 2 User Input :
|
|
553
|
-
"""
|
|
554
|
-
{example2}
|
|
555
|
-
"""
|
|
556
|
-
|
|
557
|
-
## Exemple 2 JSON Output :
|
|
558
|
-
"""
|
|
559
|
-
{output2}
|
|
560
|
-
"""
|
|
561
|
-
`;
|
|
562
|
-
const prompt = ChatPromptTemplate.fromMessages([["system", sommaireSystemTemplate], ["human", "{input}"]]);
|
|
563
|
-
const chain = prompt.pipe(structuredModel);
|
|
564
|
-
const sommairePromptResult = await chain.invoke({
|
|
565
|
-
input: cleanedHtml,
|
|
566
|
-
example1: EXAMPLES.PRJLANR5L16B2014.input,
|
|
567
|
-
output1: EXAMPLES.PRJLANR5L16B2014.sommaire,
|
|
568
|
-
example2: EXAMPLES.PRJLANR5L16B0914.input,
|
|
569
|
-
output2: EXAMPLES.PRJLANR5L16B0914.sommaire
|
|
570
|
-
});
|
|
571
|
-
if (!sommairePromptResult.sommaire) {
|
|
572
|
-
runLogFun(console.warn("Aucun sommaire n'a été trouvé ❓"), {
|
|
573
|
-
silent: SILENT_LOG
|
|
574
|
-
});
|
|
575
|
-
delimiter();
|
|
59
|
+
const excludedAlineas = [/^Délibéré en séance publique/, /^Fait le/, /^Le Président,$/, /^Signé/];
|
|
60
|
+
export function parseTexte(assembleeUrl, page) {
|
|
61
|
+
// Repair HTML.
|
|
62
|
+
let html = page.replace(/(<style[\w\W]+style>)/g, "");
|
|
63
|
+
|
|
64
|
+
// Extract subdivisions from HTML.
|
|
65
|
+
const {
|
|
66
|
+
window
|
|
67
|
+
} = new JSDOM(html);
|
|
68
|
+
const {
|
|
69
|
+
document
|
|
70
|
+
} = window;
|
|
71
|
+
assert.strictEqual(document.children.length, 1);
|
|
72
|
+
const htmlElement = document.children[0];
|
|
73
|
+
assert.strictEqual(htmlElement.children.length, 2);
|
|
74
|
+
const bodyElement = htmlElement.children[1];
|
|
75
|
+
if (bodyElement.children.length < 3) {
|
|
76
|
+
// Occurs in http://www.assemblee-nationale.fr/15/textes/0326.asp.
|
|
77
|
+
window.close(); // Free memory.
|
|
576
78
|
return {
|
|
577
|
-
|
|
79
|
+
error: {
|
|
80
|
+
code: -1,
|
|
81
|
+
message: "Texte de loi sans contenu"
|
|
82
|
+
},
|
|
83
|
+
html,
|
|
84
|
+
page
|
|
578
85
|
};
|
|
579
86
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
87
|
+
assert.strictEqual(bodyElement.children[0].tagName, "DIV");
|
|
88
|
+
// First child is a DIV describing the document (Assemblée's header). Skip it for now.
|
|
89
|
+
let bodyChild = bodyElement.children[1];
|
|
90
|
+
assert.strictEqual(bodyChild.tagName, "BR");
|
|
91
|
+
let alineaElement = null;
|
|
92
|
+
let isMultiLinesHeader = false;
|
|
93
|
+
let level = null;
|
|
94
|
+
let levels = [];
|
|
95
|
+
let nextParentState = null;
|
|
96
|
+
let state = "nextBodyChild";
|
|
97
|
+
const subdivisions = [];
|
|
98
|
+
let subdivisionAlineas = null;
|
|
99
|
+
let subdivisionHeaders = null;
|
|
100
|
+
while (state !== null) {
|
|
101
|
+
switch (state) {
|
|
102
|
+
case "nextBodyChild":
|
|
103
|
+
if (bodyChild.nextElementSibling === null) {
|
|
104
|
+
// The document has been fully parsed.
|
|
105
|
+
state = null;
|
|
106
|
+
} else {
|
|
107
|
+
bodyChild = bodyChild.nextElementSibling;
|
|
108
|
+
if (bodyChild.tagName === "DIV") {
|
|
109
|
+
alineaElement = bodyChild.children[0];
|
|
110
|
+
if (alineaElement === undefined || bodyChild.id.includes("ftn")) {
|
|
111
|
+
// No alinea in current bodyChild: go to next bodyChild.
|
|
112
|
+
state = "nextBodyChild";
|
|
113
|
+
} else {
|
|
114
|
+
state = "alineaElement";
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
// <P/> is for footnotes
|
|
118
|
+
assert(["BR", "HR", "P"].includes(bodyChild.tagName), `Unexpected tag name "${bodyChild.tagName}" for body child`);
|
|
119
|
+
// Stay in the same state to go to next bodyChild.
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
case "alineaElement":
|
|
124
|
+
switch (alineaElement.tagName) {
|
|
125
|
+
case "DIV":
|
|
126
|
+
state = "nextAlineaElement";
|
|
127
|
+
break;
|
|
128
|
+
case "H4":
|
|
129
|
+
// TODO
|
|
130
|
+
nextParentState = "nextAlineaElement";
|
|
131
|
+
state = "firstParagraphChild";
|
|
132
|
+
break;
|
|
133
|
+
case "P":
|
|
134
|
+
nextParentState = "nextAlineaElement";
|
|
135
|
+
state = "firstParagraphChild";
|
|
136
|
+
break;
|
|
137
|
+
case "OL":
|
|
138
|
+
// TODO
|
|
139
|
+
state = "nextAlineaElement";
|
|
140
|
+
break;
|
|
141
|
+
case "TABLE":
|
|
142
|
+
nextParentState = "nextAlineaElement";
|
|
143
|
+
state = "firstParagraphChild";
|
|
144
|
+
break;
|
|
145
|
+
default:
|
|
146
|
+
return {
|
|
147
|
+
error: {
|
|
148
|
+
code: -2,
|
|
149
|
+
message: `Unexpected tag name for alinea element: ${alineaElement.tagName}`
|
|
150
|
+
},
|
|
151
|
+
html,
|
|
152
|
+
page
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
break;
|
|
156
|
+
case "firstParagraphChild":
|
|
157
|
+
const headerText = alineaElement.textContent;
|
|
158
|
+
const nameComputed = (headerText || "").normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/\(nouveau\)/, "").replace(/\(Pour coordination\)/, "").replace(/\(Supprimés?\)/, "").replace(/ /g, " ").replace(/[\-,.…]/g, "").trim().replace(/ {1,}/g, "_");
|
|
159
|
+
const nameUpper = nameComputed.toUpperCase();
|
|
160
|
+
const [nextLevel, paragraphType] = parseHeader(nameUpper);
|
|
161
|
+
if (!nameUpper || nameUpper.match(/^(PROJET|PROPOSITION)_DE_LOI(_|$)/) !== null) {
|
|
162
|
+
// Occurs in:
|
|
163
|
+
// * http://www.assemblee-nationale.fr/15/textes/0232.asp
|
|
164
|
+
// * http://www.assemblee-nationale.fr/15/textes/0626.asp
|
|
165
|
+
// * http://www.assemblee-nationale.fr/15/textes/0676.asp
|
|
166
|
+
state = nextParentState;
|
|
167
|
+
break;
|
|
168
|
+
} else if (nameUpper === "JEUX_OLYMPIQUES_ET_PARALYMPIQUES_DE_2024") {
|
|
169
|
+
// Occurs in http://www.assemblee-nationale.fr/15/textes/0676.asp
|
|
170
|
+
state = nextParentState;
|
|
171
|
+
break;
|
|
172
|
+
} else if (nameUpper === "TEXTE_DE_LA_COMMISSION_MIXTE_PARITAIRE") {
|
|
173
|
+
// Occurs in http://www.assemblee-nationale.fr/15/textes/1294.asp
|
|
174
|
+
state = nextParentState;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
const lineHtml = cleanText(alineaElement.outerHTML);
|
|
178
|
+
const lineText = cleanText(alineaElement.textContent);
|
|
179
|
+
if (nextLevel === null) {
|
|
180
|
+
// It is a regular alinea
|
|
181
|
+
// Exclude some alineas
|
|
182
|
+
let excludeAlinea = false;
|
|
183
|
+
for (let regex of excludedAlineas) {
|
|
184
|
+
if (regex.test(lineText)) {
|
|
185
|
+
excludeAlinea = true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (excludeAlinea) {
|
|
189
|
+
state = nextParentState;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
if (subdivisionHeaders.length === 0 || isMultiLinesHeader && subdivisionAlineas.length === 0) {
|
|
193
|
+
subdivisionHeaders.push({
|
|
194
|
+
texte: lineText,
|
|
195
|
+
html: lineHtml
|
|
196
|
+
});
|
|
197
|
+
} else {
|
|
198
|
+
subdivisionAlineas.push({
|
|
199
|
+
texte: lineText,
|
|
200
|
+
html: lineHtml
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
if (isMultiLinesHeader && subdivisionHeaders.length >= 2) {
|
|
204
|
+
isMultiLinesHeader = false;
|
|
205
|
+
}
|
|
206
|
+
// Skip paragraph.
|
|
207
|
+
state = nextParentState;
|
|
208
|
+
break;
|
|
209
|
+
} else if (nextLevel !== null) {
|
|
210
|
+
// It is a header
|
|
211
|
+
level = nextLevel;
|
|
212
|
+
while (levels.length > 0 && level < levels[levels.length - 1]) {
|
|
213
|
+
levels.pop();
|
|
214
|
+
}
|
|
215
|
+
if (levels.length === 0 || level > levels[levels.length - 1]) {
|
|
216
|
+
levels.push(level);
|
|
217
|
+
}
|
|
218
|
+
subdivisionAlineas = [];
|
|
219
|
+
subdivisionHeaders = [{
|
|
220
|
+
texte: lineText,
|
|
221
|
+
html: lineHtml
|
|
222
|
+
}];
|
|
223
|
+
|
|
224
|
+
// Articles & "Exposé des motifs" are the only divisions without second title.
|
|
225
|
+
isMultiLinesHeader = nameUpper.match(/^ARTICLES?_/) === null && nameUpper.match(/^EXPOSE_DES_MOTIFS$/) === null;
|
|
226
|
+
subdivisions.push({
|
|
227
|
+
id: "D_" + nameComputed,
|
|
228
|
+
type: paragraphType,
|
|
229
|
+
niveau: level + 1,
|
|
230
|
+
niveauRelatif: levels.length,
|
|
231
|
+
titres: subdivisionHeaders,
|
|
232
|
+
alineas: subdivisionAlineas
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
state = nextParentState;
|
|
236
|
+
break;
|
|
237
|
+
case "nextAlineaElement":
|
|
238
|
+
alineaElement = alineaElement.nextElementSibling;
|
|
239
|
+
if (alineaElement === null) {
|
|
240
|
+
// The bodyChild has been fully parsed. Go to next bodyChild
|
|
241
|
+
state = "nextBodyChild";
|
|
242
|
+
} else {
|
|
243
|
+
state = "alineaElement";
|
|
244
|
+
}
|
|
245
|
+
break;
|
|
246
|
+
default:
|
|
247
|
+
throw `Unexpected state: ${state}`;
|
|
248
|
+
}
|
|
599
249
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
});
|
|
603
|
-
delimiter();
|
|
250
|
+
window.close(); // Free memory.
|
|
251
|
+
|
|
604
252
|
return {
|
|
605
|
-
|
|
253
|
+
error: null,
|
|
254
|
+
html,
|
|
255
|
+
page,
|
|
256
|
+
subdivisions,
|
|
257
|
+
url: assembleeUrl
|
|
606
258
|
};
|
|
607
259
|
}
|
|
608
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDaGF0T3BlbkFJIiwiQ2hhdFByb21wdFRlbXBsYXRlIiwiQWp2IiwiZGVsaW1pdGVyIiwicnVuTG9nRnVuIiwiQUxJTkVBX1NDSEVNQSIsInJlcXVpcmUiLCJFWFBPU0VfTU9USUZTX1NDSEVNQSIsIk1FVEFfRE9OTkVFU19TQ0hFTUEiLCJQUk9KRVRfTE9JX1NDSEVNQSIsIlNPTU1BSVJFX1NDSEVNQSIsIkVYQU1QTEVTIiwiUFJKTEFOUjVMMTZCMDkxNCIsIm1vdGlmcyIsImlucHV0IiwibG9pIiwibWV0YSIsInNvbW1haXJlIiwiUFJKTEFOUjVMMTZCMjAxNCIsIlBSSkxBTlI1TDE2QjI0MjQiLCJhbGluZWFzIiwiRlVMTF9URVhURV9TQ0hFTUEiLCIkc2NoZW1hIiwidGl0bGUiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJwcm9wZXJ0aWVzIiwidGV4dGUiLCJyZXF1aXJlZCIsIk1PREVMIiwicHJvY2VzcyIsImVudiIsIk9QRU5BSV9BUElfS0VZIiwidGVtcGVyYXR1cmUiLCJ0b3BQIiwibW9kZWwiLCJhcGlLZXkiLCJtYXhUb2tlbnMiLCJTWVNURU1fVEVNUExBVEUiLCJTSUxFTlRfTE9HIiwicGFyc2VUZXh0ZUxvaSIsImh0bWwiLCJvcHRpb25zIiwic2lsZW50IiwiY29uc29sZSIsImluZm8iLCJleHRyYWN0TWV0YURvbm5lZXMiLCJleHRyYWN0U29tbWFpcmUiLCJwYXJ0aWFsTW90aWZzIiwiZXh0cmFjdE1vdGlmcyIsInBhcnRpYWxMb2kiLCJleHRyYWN0UHJvamV0TG9pIiwiZXhwb3NlTW90aWZzIiwicG9wdWxhdGVNb3RpZnMiLCJwb3B1bGF0ZVByb2pldExvaSIsImNsZWFuSHRtbCIsImNsZWFuZWRIdG1sIiwicmVwbGFjZSIsInJlbW92ZUh0bWxUYWdzIiwiaHRtbFRhZ1JlZ2V4IiwidGV4dFdpdGhvdXRUYWdzIiwiZGVidXQiLCJmaW4iLCJzeXN0ZW1UZW1wbGF0ZSIsInByb21wdCIsImZyb21NZXNzYWdlcyIsInN0cnVjdHVyZWRNb2RlbCIsIndpdGhTdHJ1Y3R1cmVkT3V0cHV0IiwiY2hhaW4iLCJwaXBlIiwiYXJ0aWNsZVByb21wdFJlc3VsdCIsImludm9rZSIsInBhcnRpYWwiLCJncm91cCIsImFydGljbGVzIiwiZnVsbEFydGljbGVzIiwiYXJ0aWNsZSIsImFsaW5lYSIsImFsaW5lYVByb21wdFJlc3VsdCIsInB1c2giLCJwcm9qZXRMb2kiLCJncm91cEVuZCIsIm1vdGlmc1N5c3RlbVRlbXBsYXRlIiwibW90aWZzUHJvbXB0UmVzdWx0IiwiZXhhbXBsZTEiLCJleGFtcGxlMiIsIm91dHB1dDEiLCJvdXRwdXQyIiwidGFibGUiLCJzdWJzdHJpbmciLCJhanYiLCJ2YWxpZGF0ZSIsIndhcm4iLCJtZXRhRG9ubmVlc1N5c3RlbVRlbXBsYXRlIiwicmVzdWx0IiwiZG9jdW1lbnRSZWYiLCJ0aXRyZSIsIm51bWVyb1RleHRlIiwicHJvY2VkdXJlQWNjZWxlcmVlIiwicHJvamV0TG9pU3lzdGVtVGVtcGxhdGUiLCJhcnRpY2xlc1Byb21wdFJlc3VsdCIsImxvZyIsImxlbmd0aCIsImV4dHJhY3RBbGluZWFzIiwibWFwIiwibnVtZXJvQXJ0aWNsZSIsImFsaW5lYXNTeXN0ZW1UZW1wbGF0ZSIsImFsaW5lYXNQcm9tcHRSZXN1bHQiLCJzb21tYWlyZVN5c3RlbVRlbXBsYXRlIiwic29tbWFpcmVQcm9tcHRSZXN1bHQiLCJpdGVtIiwic2VxdWVuY2UiLCJ0eXBlRGl2aXNpb24iLCJwYXJlbnQiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvcGFyc2Vycy90ZXh0ZXNfbG9pcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGF0T3BlbkFJIH0gZnJvbSBcIkBsYW5nY2hhaW4vb3BlbmFpXCJcbmltcG9ydCB7IENoYXRQcm9tcHRUZW1wbGF0ZSB9IGZyb20gXCJAbGFuZ2NoYWluL2NvcmUvcHJvbXB0c1wiXG5pbXBvcnQgQWp2IGZyb20gXCJhanZcIlxuXG5pbXBvcnQgeyBkZWxpbWl0ZXIsIHJ1bkxvZ0Z1biB9IGZyb20gXCIuLi9sb2dnZXJcIlxuXG5jb25zdCBBTElORUFfU0NIRU1BID0gcmVxdWlyZShcIi4uL3NjaGVtYXMvdGV4dGVfbG9pL0FsaW5lYS5qc29uXCIpXG5jb25zdCBFWFBPU0VfTU9USUZTX1NDSEVNQSA9IHJlcXVpcmUoXCIuLi9zY2hlbWFzL3RleHRlX2xvaS9FeHBvc2VNb3RpZnMuanNvblwiKVxuY29uc3QgTUVUQV9ET05ORUVTX1NDSEVNQSA9IHJlcXVpcmUoXCIuLi9zY2hlbWFzL3RleHRlX2xvaS9NZXRhRG9ubmVlcy5qc29uXCIpXG5jb25zdCBQUk9KRVRfTE9JX1NDSEVNQSA9IHJlcXVpcmUoXCIuLi9zY2hlbWFzL3RleHRlX2xvaS9Qcm9qZXRMb2kuanNvblwiKVxuY29uc3QgU09NTUFJUkVfU0NIRU1BID0gcmVxdWlyZShcIi4uL3NjaGVtYXMvdGV4dGVfbG9pL1NvbW1haXJlLmpzb25cIilcblxuLyoqXG4gKiBPYmplY3QgY29udGFpbmluZyBpbnB1dCBleGFtcGxlcyBhbmQgdGhlaXIgb3V0cHV0IHNjaGVtYXMuXG4gKiBVc2VkIHRvIHRyYWluIHRoZSBMTE0uXG4gKiBAdHlwZSB7UmVjb3JkPHN0cmluZywge21vdGlmczogYW55LCBpbnB1dDogYW55LCBsb2k6IGFueSwgbWV0YTogYW55LCBzb21tYWlyZTogYW55fT59XG4gKi9cbmNvbnN0IEVYQU1QTEVTID0ge1xuICBQUkpMQU5SNUwxNkIwOTE0OiB7XG4gICAgbW90aWZzOiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMDkxNC9tb3RpZnMuanNvblwiKSxcbiAgICBpbnB1dDogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjA5MTQvaW5wdXRcIiksXG4gICAgbG9pOiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMDkxNC9sb2kuanNvblwiKSxcbiAgICBtZXRhOiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMDkxNC9tZXRhLmpzb25cIiksXG4gICAgc29tbWFpcmU6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIwOTE0L3NvbW1haXJlLmpzb25cIiksXG4gIH0sXG4gIFBSSkxBTlI1TDE2QjIwMTQ6IHtcbiAgICBtb3RpZnM6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyMDE0L21vdGlmcy5qc29uXCIpLFxuICAgIGlucHV0OiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMjAxNC9pbnB1dFwiKSxcbiAgICBsb2k6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyMDE0L2xvaS5qc29uXCIpLFxuICAgIG1ldGE6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyMDE0L21ldGEuanNvblwiKSxcbiAgICBzb21tYWlyZTogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjIwMTQvc29tbWFpcmUuanNvblwiKSxcbiAgfSxcbiAgUFJKTEFOUjVMMTZCMjQyNDoge1xuICAgIGFsaW5lYXM6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyNDI0L2FsaW5lYXMuanNvblwiKSxcbiAgICBtb3RpZnM6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyNDI0L21vdGlmcy5qc29uXCIpLFxuICAgIGlucHV0OiByZXF1aXJlKFwiLi4vZXhhbXBsZXMvUFJKTEFOUjVMMTZCMjQyNC9pbnB1dFwiKSxcbiAgICBsb2k6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyNDI0L2xvaS5qc29uXCIpLFxuICAgIG1ldGE6IHJlcXVpcmUoXCIuLi9leGFtcGxlcy9QUkpMQU5SNUwxNkIyNDI0L21ldGEuanNvblwiKSxcbiAgICBzb21tYWlyZTogcmVxdWlyZShcIi4uL2V4YW1wbGVzL1BSSkxBTlI1TDE2QjI0MjQvc29tbWFpcmUuanNvblwiKSxcbiAgfSxcbn1cblxuY29uc3QgRlVMTF9URVhURV9TQ0hFTUEgPSB7XG4gICRzY2hlbWE6IFwiaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjXCIsXG4gIHRpdGxlOiBcIlNvbW1haXJlXCIsXG4gIGRlc2NyaXB0aW9uOiBcIlLDqWN1cMOpcmF0aW9uIGQndW4gdGV4dGUgY29tcGxldFwiLFxuICB0eXBlOiBcIm9iamVjdFwiLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgdGV4dGU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlRleHRlIGNvbXBsZXQgZGUgbGEgc2VjdGlvbiBpbmRpcXXDqWUuXCIsXG4gICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgIH0sXG4gIH0sXG4gIHJlcXVpcmVkOiBbXCJ0ZXh0ZVwiXSxcbn1cblxuLyoqXG4gKiBMTE0gbW9kZWwuXG4gKi9cbmxldCBNT0RFTDogYW55ID0gbnVsbFxuXG5pZiAocHJvY2Vzcy5lbnYuT1BFTkFJX0FQSV9LRVkpIHtcbiAgTU9ERUwgPSBuZXcgQ2hhdE9wZW5BSSh7XG4gICAgdGVtcGVyYXR1cmU6IDAsXG4gICAgdG9wUDogMC4wLFxuICAgIG1vZGVsOiBcImdwdC00by1taW5pXCIsXG4gICAgYXBpS2V5OiBwcm9jZXNzLmVudi5PUEVOQUlfQVBJX0tFWSxcbiAgICBtYXhUb2tlbnM6IC0xLFxuICB9KVxufVxuXG4vKipcbiAqIFN5c3RlbSBpbnB1dCB0ZW1wbGF0ZSBmb3IgdGhlIExMTS5cbiAqL1xuY29uc3QgU1lTVEVNX1RFTVBMQVRFOiBzdHJpbmcgPSBgXG4gICMgSW5zdHJ1Y3Rpb25zIDpcbiAgXG4gIFR1IGVzIHVuIGV4cGVydCBkZSBsYSBsb2kgZXQgZGUgbCdhbmFseXNlIGRlIHBhZ2VzIEhUTUwuXG4gIFR1IGRvaXMgYW5hbHlzZXIgdW4gdGV4dGUgZGUgbG9pIGFmaW4gZGUgc8OpcGFyZXIgZXQgZGUgc3RydWN0dXJlciBsZXMgw6lsw6ltZW50cyBxdWkgbGUgY29tcG9zZW50LiBMZSBmb3JtYXQgZCdlbnRyw6llIGVzdCBIVE1MLlxuXG4gIExlIHRleHRlIGVzdCBkaXZpc8OpIGVuIGRldXggcGFydGllcyA6XG4gIEEpIHVuIGV4cG9zw6kgZGVzIG1vdGlmcyBxdWkgaW5kaXF1ZSBsZXMgcmFpc29ucyBwb3VyIGxlc3F1ZWxsZXMgY2UgcHJvamV0IGVzdCBzb3VtaXMgYXUgUGFybGVtZW50LiBJbCBwZXV0IGNvbnRlbmlyIDMgw6lsw6ltZW50cyA6IDEpIHVuZSBjaXRhdGlvbiBhdSBkw6lidXQgZCd1biBkb2N1bWVudCwgMikgbGUgdGV4dGUgcHJpbmNpcGFsIHF1aSBkw6l2ZWxvcHBlIGxlcyBhcmd1bWVudHMgZGUgbCdhdXRldXIgw6AgbCdhcHB1aSBkZSBsYSBtb2RpZmljYXRpb24gbMOpZ2lzbGF0aXZlIG91IGRlcyBkaXNwb3NpdGlvbnMgbm91dmVsbGVzIHF1J2lsIHByb3Bvc2UsIDMpIGRlcyBwYXJhZ3JhcGhlcyBxdWkgcHLDqXNlbnRlbnQgbGVzIGFydGljbGVzLlxuICBCKSBsZSBkaXNwb3NpdGlmIHF1aSBlc3QgbGEgcGFydGllIG5vcm1hdGl2ZSBldCByw6lkaWfDqWUgZW4gYXJ0aWNsZXMuIElsIHBldXQgY29tcG9ydGVyIGRlcyBkaXZpc2lvbnMgbm9tbcOpZXMgdGl0cmVzLCBjaGFwaXRyZXMsIHNlY3Rpb25zLCBzb3VzLXNlY3Rpb25zLiBMb3JzcXUnaWwgeSBhIHVuIHNldWwgbml2ZWF1IGRlIHN0cnVjdHVyZSwgb24gcmV0cm91dmVyYSBsZSBjaGFwaXRyZSA7IHPigJlpbCB5IGEgZGV1eCBuaXZlYXV4IGRlIHN0cnVjdHVyZSwgb24gcmV0cm91dmVyYSBkZXMgY2hhcGl0cmVzIHB1aXMgZGVzIHNlY3Rpb25zLiBT4oCZaWwgeSBhIHRyb2lzIG5pdmVhdXggZGUgc3RydWN0dXJlLCBvbiByZXRyb3V2ZXJhIGRlcyB0aXRyZXMgcHVpcyBkZXMgY2hhcGl0cmVzIHB1aXMgZGVzIHNlY3Rpb25zLlxuXG4gIFNpIGxlIHRleHRlIGRlIGxvaSBuZSBjb21wb3J0ZSBwYXMgZGUgZGl2aXNpb24sIGxlIHNvbW1haXJlIGRvaXQgcmVzdGVyIHZpZGUuXG4gIFRvdXRlcyBsZXMgbGlnbmVzIHF1aSBkw6lidXRlbnQgcGFyIHVuICfCqycgbmUgc29udCBwYXMgw6AgcHJlbmRyZSBlbiBjb21wdGUgZGFucyBsZXMgZGl2aXNpb25zXG4gIFRhIHLDqXBvbnNlIGRvaXQgw6p0cmUgdW4gSlNPTiBzdHJ1Y3R1csOpIGF2ZWMgbGVzIMOpbMOpbWVudHMgZHUgdGV4dGUgZGUgbG9pIGVuIHJlc3BlY3RhbnQgbGUgc2Now6ltYSBKU09OIGZvdXJuaS5cbmBcblxubGV0IFNJTEVOVF9MT0cgPSBmYWxzZVxuXG4vKipcbiAqIFBhcnNlcyB0aGUgZ2l2ZW4gSFRNTCBzdHJpbmcgYW5kIHJldHVybnMgdGhlIHBhcnNlZCB0ZXh0ZXMgbG9pLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgc3RyaW5nIHRvIHBhcnNlLlxuICogQHJldHVybiB7UHJvbWlzZTx7cGFydGlhbDoge3NvbW1haXJlOiBhbnksIGxvaTogYW55LCBtb3RpZnM6IGFueSwgbWV0YTogYW55fSwgY29tcGxldGVkOiB7c29tbWFpcmU6IGFueSwgbG9pOiBhbnksIG1vdGlmczogYW55LCBtZXRhOiBhbnl9fT59IC0gVGhlIHBhcnNlZCB0ZXh0ZXMgbG9pLCBpbmNsdWRpbmcgdGhlIHBhcnRpYWwgYW5kIGNvbXBsZXRlZCB2ZXJzaW9ucy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBhcnNlVGV4dGVMb2koaHRtbDogc3RyaW5nLCBvcHRpb25zID0geyBzaWxlbnQ6IGZhbHNlIH0pIHtcbiAgU0lMRU5UX0xPRyA9IG9wdGlvbnMuc2lsZW50XG5cbiAgcnVuTG9nRnVuKGNvbnNvbGUuaW5mbyhcIlN0YXJ0IGV4dHJhY3RpbmcgbG9pLi4uXCIpLCBvcHRpb25zKVxuICBjb25zdCBtZXRhID0gYXdhaXQgZXh0cmFjdE1ldGFEb25uZWVzKGh0bWwpXG4gIGNvbnN0IHNvbW1haXJlID0gYXdhaXQgZXh0cmFjdFNvbW1haXJlKGh0bWwpXG4gIGNvbnN0IHBhcnRpYWxNb3RpZnM6IGFueSA9IGF3YWl0IGV4dHJhY3RNb3RpZnMoaHRtbClcbiAgY29uc3QgcGFydGlhbExvaTogYW55ID0gYXdhaXQgZXh0cmFjdFByb2pldExvaShodG1sKVxuICBjb25zdCBleHBvc2VNb3RpZnMgPSBhd2FpdCBwb3B1bGF0ZU1vdGlmcyhwYXJ0aWFsTW90aWZzLCBodG1sKVxuICBjb25zdCBsb2kgPSBhd2FpdCBwb3B1bGF0ZVByb2pldExvaShwYXJ0aWFsTG9pLCBodG1sKVxuXG4gIHJldHVybiB7XG4gICAgc29tbWFpcmUsXG4gICAgbG9pLFxuICAgIGV4cG9zZU1vdGlmcyxcbiAgICBtZXRhLFxuICB9XG59XG5cbi8qKlxuICogQ2xlYW5zIHRoZSBnaXZlbiBIVE1MIHN0cmluZyBieSByZW1vdmluZyB1bm5lY2Vzc2FyeSB0YWdzIGFuZCBjb250ZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgc3RyaW5nIHRvIGJlIGNsZWFuZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBjbGVhbmVkIEhUTUwgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBjbGVhbkh0bWwoaHRtbDogc3RyaW5nKSB7XG4gIGxldCBjbGVhbmVkSHRtbCA9IGh0bWwucmVwbGFjZSgvKDxzdHlsZVtcXHdcXFddK3N0eWxlPikvZywgXCJcIilcbiAgY2xlYW5lZEh0bWwgPSBjbGVhbmVkSHRtbC5yZXBsYWNlKC8oPGhlYWRbXFx3XFxXXStoZWFkPikvZywgXCJcIilcbiAgY2xlYW5lZEh0bWwgPSBjbGVhbmVkSHRtbC5yZXBsYWNlKC88aW1nW14+XSo+L2csIFwiXCIpXG5cbiAgcmV0dXJuIGNsZWFuZWRIdG1sXG59XG5cbi8qKlxuICogUmVtb3ZlcyBhbGwgSFRNTCB0YWdzIGZyb20gdGhlIGdpdmVuIEhUTUwgc3RyaW5nIGFuZCByZXR1cm5zIHRoZSBjbGVhbmVkIHRleHQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGh0bWwgLSBUaGUgSFRNTCBzdHJpbmcgZnJvbSB3aGljaCB0byByZW1vdmUgdGFncy5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGNsZWFuZWQgdGV4dCB3aXRob3V0IGFueSBIVE1MIHRhZ3MuXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUh0bWxUYWdzKGh0bWw6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIFJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYXRjaCBIVE1MIHRhZ3NcbiAgY29uc3QgaHRtbFRhZ1JlZ2V4ID0gLzxbXj5dKj4vZ1xuXG4gIC8vIFJlcGxhY2UgYWxsIEhUTUwgdGFncyB3aXRoIGFuIGVtcHR5IHN0cmluZ1xuICBjb25zdCB0ZXh0V2l0aG91dFRhZ3MgPSBodG1sLnJlcGxhY2UoaHRtbFRhZ1JlZ2V4LCBcIlwiKVxuICByZXR1cm4gdGV4dFdpdGhvdXRUYWdzXG59XG5cbi8qKlxuICogUG9wdWxhdGVzIHRoZSBtb3RpZnMgb2JqZWN0IHdpdGggdGhlIGV4dHJhY3RlZCB0ZXh0IGZyb20gdGhlIGdpdmVuIEhUTUwuXG4gKlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBtb3RpZnMgLSBUaGUgbW90aWZzIG9iamVjdCB0byBiZSBwb3B1bGF0ZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbCAtIFRoZSBIVE1MIHN0cmluZyBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdGhlIHRleHQuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSAtIFRoZSBwb3B1bGF0ZWQgbW90aWZzIG9iamVjdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcG9wdWxhdGVNb3RpZnMobW90aWZzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBodG1sOiBzdHJpbmcpIHtcbiAgcnVuTG9nRnVuKGNvbnNvbGUuaW5mbyhcIlBvcHVsYXRpbmcgZXhwb3NlIG1vdGlmcy4uLlwiKSlcbiAgbGV0IGNsZWFuZWRIdG1sID0gY2xlYW5IdG1sKGh0bWwpXG5cbiAgaWYgKG1vdGlmcy5kZWJ1dCA9PT0gbW90aWZzLmZpbiB8fCAhbW90aWZzLmZpbikge1xuICAgIG1vdGlmcy50ZXh0ZSA9IG1vdGlmcy5kZWJ1dFxuICB9IGVsc2Uge1xuICAgIGNvbnN0IHN5c3RlbVRlbXBsYXRlID0gYFxuICAgICAgIyBJbnN0cnVjdGlvbnMgOlxuXG4gICAgICBUdSBlcyB1biBleHBlcnQgZGUgbGEgbG9pIGV0IGRlIGwnYW5hbHlzZSBkZSBwYWdlcyBIVE1MLlxuICAgICAgVHUgZG9pcyBhbmFseXNlciB1biB0ZXh0ZSBkZSBsb2kgYWZpbiBkJ2VuIGV4dHJhaXJlIGNlcnRhaW5lcyBwYXJ0aWVzLiBcbiAgICAgIExlIGZvcm1hdCBkJ2VudHLDqWUgZXN0IGR1IEhUTUwuIExlIGZvcm1hdCBkZSBzb3J0aWUgZXN0IGR1IHRleHRlLlxuICAgICAgUsOpY3Vww6hyZSBsJ2ludMOpZ3JhbGl0w6kgZHUgdGV4dGUgY29tbWVuw6dhbnQgcGFyIDpcblxuICAgICAgXCJcIlwiXG4gICAgICB7ZGVidXR9XG4gICAgICBcIlwiXCJcblxuICAgICAgRXQgZmluaXNzYW50IHBhciA6XG5cbiAgICAgIFwiXCJcIlxuICAgICAge2Zpbn1cbiAgICAgIFwiXCJcIlxuICAgIGBcblxuICAgIGNvbnN0IHByb21wdCA9IENoYXRQcm9tcHRUZW1wbGF0ZS5mcm9tTWVzc2FnZXMoW1xuICAgICAgW1wic3lzdGVtXCIsIHN5c3RlbVRlbXBsYXRlXSxcbiAgICAgIFtcImh1bWFuXCIsIFwie2lucHV0fVwiXSxcbiAgICBdKVxuXG4gICAgY29uc3Qgc3RydWN0dXJlZE1vZGVsID0gTU9ERUwud2l0aFN0cnVjdHVyZWRPdXRwdXQoRlVMTF9URVhURV9TQ0hFTUEpXG4gICAgY29uc3QgY2hhaW4gPSBwcm9tcHQucGlwZShzdHJ1Y3R1cmVkTW9kZWwpXG5cbiAgICBjb25zdCBhcnRpY2xlUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgICAgaW5wdXQ6IGNsZWFuZWRIdG1sLFxuICAgICAgZGVidXQ6IG1vdGlmcy5kZWJ1dCxcbiAgICAgIGZpbjogbW90aWZzLmZpbixcbiAgICB9KVxuXG4gICAgbW90aWZzLnRleHRlID0gYXJ0aWNsZVByb21wdFJlc3VsdC50ZXh0ZVxuICB9XG5cbiAgcnVuTG9nRnVuKFxuICAgIGNvbnNvbGUuaW5mbyhcIk9ww6lyYXRpb24gZGUgcGV1cGxlbWVudCBkZSBsJ2V4cG9zw6kgZGVzIG1vdGlmcyB0ZXJtaW7DqWUg4pyFXCIpLFxuICAgIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0sXG4gIClcbiAgZGVsaW1pdGVyKFNJTEVOVF9MT0cpXG5cbiAgZGVsZXRlIG1vdGlmcy5kZWJ1dFxuICBkZWxldGUgbW90aWZzLmZpblxuICByZXR1cm4gbW90aWZzXG59XG5cbi8qKlxuICogQXN5bmNocm9ub3VzbHkgcG9wdWxhdGVzIGEgcHJvamV0IGxvaSBvYmplY3Qgd2l0aCB0aGUgZnVsbCB0ZXh0IG9mIGVhY2ggYXJ0aWNsZSBhbmQgYWxpbmVhIGluIHRoZSBnaXZlbiBIVE1MLlxuICpcbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gcGFydGlhbCAtIFRoZSBwYXJ0aWFsIHByb2pldCBsb2kgb2JqZWN0IHRvIGJlIHBvcHVsYXRlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgY29udGFpbmluZyB0aGUgdGV4dCBvZiB0aGUgYXJ0aWNsZXMgYW5kIGFsaW5lYXMuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgZnVsbHkgcG9wdWxhdGVkIHByb2pldCBsb2kgb2JqZWN0LlxuICovXG5hc3luYyBmdW5jdGlvbiBwb3B1bGF0ZVByb2pldExvaShwYXJ0aWFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBodG1sOiBzdHJpbmcpIHtcbiAgcnVuTG9nRnVuKGNvbnNvbGUuZ3JvdXAoXCJQZXVwbGVtZW50IGR1IHByb2pldCBsb2kuLi5cIiksIHtcbiAgICBzaWxlbnQ6IFNJTEVOVF9MT0csXG4gIH0pXG4gIGxldCBjbGVhbmVkSHRtbCA9IGNsZWFuSHRtbChodG1sKVxuXG4gIGNvbnN0IGFydGljbGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10gPSBwYXJ0aWFsLmFydGljbGVzXG4gIGNvbnN0IGZ1bGxBcnRpY2xlczogUmVjb3JkPHN0cmluZywgYW55PltdID0gW11cblxuICBjb25zdCBzeXN0ZW1UZW1wbGF0ZSA9IGBcbiAgICAjIEluc3RydWN0aW9ucyA6XG5cbiAgICBUdSBlcyB1biBleHBlcnQgZGUgbGEgbG9pIGV0IGRlIGwnYW5hbHlzZSBkZSBwYWdlcyBIVE1MLlxuICAgIFR1IGRvaXMgYW5hbHlzZXIgdW4gdGV4dGUgZGUgbG9pIGFmaW4gZCdlbiBleHRyYWlyZSBjZXJ0YWluZXMgcGFydGllcy4gXG4gICAgTGUgZm9ybWF0IGQnZW50csOpZSBlc3QgZHUgSFRNTC4gTGUgZm9ybWF0IGRlIHNvcnRpZSBlc3QgZHUgdGV4dGUuXG4gICAgUsOpY3Vww6hyZSBsJ2ludMOpZ3JhbGl0w6kgZHUgdGV4dGUgY29tbWVuw6dhbnQgcGFyIDpcblxuICAgIFwiXCJcIlxuICAgIHtkZWJ1dH1cbiAgICBcIlwiXCJcblxuICAgIEV0IGZpbmlzc2FudCBwYXIgOlxuXG4gICAgXCJcIlwiXG4gICAge2Zpbn1cbiAgICBcIlwiXCJcbiAgYFxuXG4gIGNvbnN0IHByb21wdCA9IENoYXRQcm9tcHRUZW1wbGF0ZS5mcm9tTWVzc2FnZXMoW1xuICAgIFtcInN5c3RlbVwiLCBzeXN0ZW1UZW1wbGF0ZV0sXG4gICAgW1wiaHVtYW5cIiwgXCJ7aW5wdXR9XCJdLFxuICBdKVxuXG4gIGNvbnN0IHN0cnVjdHVyZWRNb2RlbCA9IE1PREVMLndpdGhTdHJ1Y3R1cmVkT3V0cHV0KEZVTExfVEVYVEVfU0NIRU1BKVxuICBjb25zdCBjaGFpbiA9IHByb21wdC5waXBlKHN0cnVjdHVyZWRNb2RlbClcblxuICBmb3IgKGNvbnN0IGFydGljbGUgb2YgYXJ0aWNsZXMpIHtcbiAgICBpZiAoYXJ0aWNsZS5kZWJ1dCA9PT0gYXJ0aWNsZS5maW4gfHwgIWFydGljbGUuZmluKSB7XG4gICAgICBhcnRpY2xlLnRleHRlID0gYXJ0aWNsZS5kZWJ1dFxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBhcnRpY2xlUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgICAgICBpbnB1dDogY2xlYW5lZEh0bWwsXG4gICAgICAgIGRlYnV0OiBhcnRpY2xlLmRlYnV0LFxuICAgICAgICBmaW46IGFydGljbGUuZmluLFxuICAgICAgfSlcblxuICAgICAgYXJ0aWNsZS50ZXh0ZSA9IGFydGljbGVQcm9tcHRSZXN1bHQudGV4dGVcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGFsaW5lYSBvZiBhcnRpY2xlLmFsaW5lYXMpIHtcbiAgICAgIGlmIChhbGluZWEuZGVidXQgPT09IGFsaW5lYS5maW4gfHwgIWFsaW5lYS5maW4pIHtcbiAgICAgICAgYWxpbmVhLnRleHRlID0gYWxpbmVhLmRlYnV0XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFsaW5lYVByb21wdFJlc3VsdDogYW55ID0gYXdhaXQgY2hhaW4uaW52b2tlKHtcbiAgICAgICAgaW5wdXQ6IGFydGljbGUudGV4dGUsXG4gICAgICAgIGRlYnV0OiBhbGluZWEuZGVidXQsXG4gICAgICAgIGZpbjogYWxpbmVhLmZpbixcbiAgICAgIH0pXG5cbiAgICAgIGRlbGV0ZSBhbGluZWEuZGVidXRcbiAgICAgIGRlbGV0ZSBhbGluZWEuZmluXG4gICAgICBhbGluZWEudGV4dGUgPSBhbGluZWFQcm9tcHRSZXN1bHQudGV4dGVcbiAgICB9XG5cbiAgICBydW5Mb2dGdW4oXG4gICAgICBjb25zb2xlLmluZm8oXG4gICAgICAgIFwiT3DDqXJhdGlvbiBkZSBwZXVwbGVtZW50IGR1IGNvbnRlbnUgZHUgcHJvamV0IGRlIGxvaSB0ZXJtaW7DqWUg4pyFXCIsXG4gICAgICApLFxuICAgICAgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSxcbiAgICApXG4gICAgZGVsZXRlIGFydGljbGUuZGVidXRcbiAgICBkZWxldGUgYXJ0aWNsZS5maW5cbiAgICBmdWxsQXJ0aWNsZXMucHVzaChhcnRpY2xlKVxuICB9XG5cbiAgY29uc3QgcHJvamV0TG9pID0ge1xuICAgIC4uLnBhcnRpYWwsXG4gICAgYXJ0aWNsZXM6IGZ1bGxBcnRpY2xlcyxcbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIGRlbGltaXRlcigpXG4gIHJldHVybiBwcm9qZXRMb2lcbn1cblxuLyoqXG4gKiBBc3luY2hyb25vdXNseSBleHRyYWN0cyB0aGUgXCJleHBvc2UgbW90aWZzXCIgZnJvbSB0aGUgZ2l2ZW4gSFRNTC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbCAtIFRoZSBIVE1MIHN0cmluZyBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdGhlIFwiZXhwb3NlIG1vdGlmc1wiLlxuICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gLSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgZXh0cmFjdGVkIFwiZXhwb3NlIG1vdGlmc1wiIG9iamVjdC5cbiAqIFRoZSBvYmplY3QgY29udGFpbnMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICogLSBgZGVidXRgOiBUaGUgYmVnaW5uaW5nIG9mIHRoZSBcImV4cG9zZSBtb3RpZnNcIi5cbiAqIC0gYGZpbmA6IFRoZSBlbmQgb2YgdGhlIFwiZXhwb3NlIG1vdGlmc1wiLlxuICogQHRocm93cyB7RXJyb3J9IC0gSWYgdGhlIGV4dHJhY3RlZCBcImV4cG9zZSBtb3RpZnNcIiBkbyBub3QgdmFsaWRhdGUgYWdhaW5zdCB0aGUgRVhQT1NFX01PVElGU19TQ0hFTUEuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RNb3RpZnMoaHRtbDogc3RyaW5nKSB7XG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwKFwiUGFyc2luZyBleHBvc2UgbW90aWZzLi4uXCIpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICBsZXQgY2xlYW5lZEh0bWwgPSBjbGVhbkh0bWwoaHRtbClcbiAgY2xlYW5lZEh0bWwgPSByZW1vdmVIdG1sVGFncyhjbGVhbmVkSHRtbClcblxuICBjb25zdCBzdHJ1Y3R1cmVkTW9kZWwgPSBNT0RFTC53aXRoU3RydWN0dXJlZE91dHB1dChFWFBPU0VfTU9USUZTX1NDSEVNQSlcblxuICBjb25zdCBtb3RpZnNTeXN0ZW1UZW1wbGF0ZSA9IGBcbiAgICAke1NZU1RFTV9URU1QTEFURX1cblxuICAgICMgRXhhbXBsZXM6IFxuXG4gICAgIyMgRXhlbXBsZSAxIFVzZXIgSW5wdXQgOlxuICAgIFwiXCJcIlxuICAgIHtleGFtcGxlMX1cbiAgICBcIlwiXCJcbiAgICBcbiAgICAjIyBFeGVtcGxlIDEgSlNPTiBPdXRwdXQgOlxuICAgIFwiXCJcIlxuICAgIHtvdXRwdXQxfVxuICAgIFwiXCJcIlxuXG4gICAgIyMgRXhlbXBsZSAyIFVzZXIgSW5wdXQgOlxuICAgIFwiXCJcIlxuICAgIHtleGFtcGxlMn1cbiAgICBcIlwiXCJcbiAgICBcbiAgICAjIyBFeGVtcGxlIDIgSlNPTiBPdXRwdXQgOlxuICAgIFwiXCJcIlxuICAgIHtvdXRwdXQyfVxuICAgIFwiXCJcIlxuICAgIGBcblxuICBjb25zdCBwcm9tcHQgPSBDaGF0UHJvbXB0VGVtcGxhdGUuZnJvbU1lc3NhZ2VzKFtcbiAgICBbXCJzeXN0ZW1cIiwgbW90aWZzU3lzdGVtVGVtcGxhdGVdLFxuICAgIFtcImh1bWFuXCIsIFwie2lucHV0fVwiXSxcbiAgXSlcblxuICBjb25zdCBjaGFpbiA9IHByb21wdC5waXBlKHN0cnVjdHVyZWRNb2RlbClcbiAgY29uc3QgbW90aWZzUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBleGFtcGxlMTogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMDkxNC5pbnB1dCxcbiAgICBleGFtcGxlMjogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMjQyNC5pbnB1dCxcbiAgICBvdXRwdXQxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0Lm1vdGlmcyxcbiAgICBvdXRwdXQyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0Lm1vdGlmcyxcbiAgfSlcblxuICAvLyBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShtb3RpZnNQcm9tcHRSZXN1bHQpKVxuICBydW5Mb2dGdW4oXG4gICAgY29uc29sZS50YWJsZShbXG4gICAgICBbXCJEw6lidXRcIiwgbW90aWZzUHJvbXB0UmVzdWx0LmRlYnV0LnN1YnN0cmluZygwLCAzMCldLFxuICAgICAgW1wiRmluXCIsIG1vdGlmc1Byb21wdFJlc3VsdC5maW4uc3Vic3RyaW5nKDAsIDMwKV0sXG4gICAgXSksXG4gICAgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSxcbiAgKVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIGRlbGltaXRlcigpXG5cbiAgY29uc3QgYWp2ID0gbmV3IEFqdigpXG4gIGlmIChhanYudmFsaWRhdGUoRVhQT1NFX01PVElGU19TQ0hFTUEsIG1vdGlmc1Byb21wdFJlc3VsdCkpIHtcbiAgICBydW5Mb2dGdW4oY29uc29sZS5pbmZvKFwiRXhwb3PDqSBkZXMgbW90aWZzIE9LIPCfkYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gICAgcmV0dXJuIG1vdGlmc1Byb21wdFJlc3VsdFxuICB9XG5cbiAgcnVuTG9nRnVuKGNvbnNvbGUud2FybihcIkV4cG9zw6kgZGVzIG1vdGlmcyBLTyDinYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIHJldHVybiB7fVxufVxuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IGV4dHJhY3RzIHRoZSBtZXRhZGF0YSBmcm9tIHRoZSBnaXZlbiBIVE1MLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sIC0gVGhlIEhUTUwgc3RyaW5nIGZyb20gd2hpY2ggdG8gZXh0cmFjdCB0aGUgbWV0YWRhdGEuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSAtIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBleHRyYWN0ZWQgbWV0YWRhdGEgb2JqZWN0LlxuICogVGhlIG9iamVjdCBjb250YWlucyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKiAtIGBkb2N1bWVudFJlZmA6IFRoZSByZWZlcmVuY2Ugb2YgdGhlIGRvY3VtZW50LlxuICogLSBgdGl0cmVgOiBUaGUgdGl0bGUgb2YgdGhlIGRvY3VtZW50LlxuICogLSBgbnVtZXJvVGV4dGVgOiBUaGUgbnVtYmVyIG9mIHRoZSB0ZXh0LlxuICogLSBgcHJvY2VkdXJlQWNjZWxlcmVlYDogVGhlIGFjY2VsZXJhdGVkIHByb2NlZHVyZS5cbiAqIEB0aHJvd3Mge0Vycm9yfSAtIElmIHRoZSBleHRyYWN0ZWQgbWV0YWRhdGEgZG8gbm90IHZhbGlkYXRlIGFnYWluc3QgdGhlIE1FVEFfRE9OTkVFU19TQ0hFTUEuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RNZXRhRG9ubmVlcyhodG1sOiBzdHJpbmcpIHtcbiAgZGVsaW1pdGVyKClcbiAgbGV0IGNsZWFuZWRIdG1sID0gY2xlYW5IdG1sKGh0bWwpXG4gIGNsZWFuZWRIdG1sID0gcmVtb3ZlSHRtbFRhZ3MoY2xlYW5lZEh0bWwpXG5cbiAgY29uc3Qgc3RydWN0dXJlZE1vZGVsID0gTU9ERUwud2l0aFN0cnVjdHVyZWRPdXRwdXQoTUVUQV9ET05ORUVTX1NDSEVNQSlcblxuICBjb25zdCBtZXRhRG9ubmVlc1N5c3RlbVRlbXBsYXRlID0gYFxuICAgICR7U1lTVEVNX1RFTVBMQVRFfVxuICAgIGBcblxuICBjb25zdCBwcm9tcHQgPSBDaGF0UHJvbXB0VGVtcGxhdGUuZnJvbU1lc3NhZ2VzKFtcbiAgICBbXCJzeXN0ZW1cIiwgbWV0YURvbm5lZXNTeXN0ZW1UZW1wbGF0ZV0sXG4gICAgW1wiaHVtYW5cIiwgXCJ7aW5wdXR9XCJdLFxuICBdKVxuXG4gIGNvbnN0IGNoYWluID0gcHJvbXB0LnBpcGUoc3RydWN0dXJlZE1vZGVsKVxuICBjb25zdCByZXN1bHQ6IGFueSA9IGF3YWl0IGNoYWluLmludm9rZSh7XG4gICAgaW5wdXQ6IGNsZWFuZWRIdG1sLFxuICAgIGV4YW1wbGUxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0LmlucHV0LFxuICAgIGV4YW1wbGUyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0LmlucHV0LFxuICAgIG91dHB1dDE6IEVYQU1QTEVTLlBSSkxBTlI1TDE2QjA5MTQubWV0YSxcbiAgICBvdXRwdXQyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0Lm1ldGEsXG4gIH0pXG5cbiAgY29uc29sZS5ncm91cChcIk1ldGEtZG9ubsOpZXNcIilcbiAgY29uc29sZS50YWJsZShbXG4gICAgW1wiUsOpZsOpcmVuY2VcIiwgcmVzdWx0LmRvY3VtZW50UmVmXSxcbiAgICBbXCJUaXRyZVwiLCByZXN1bHQudGl0cmVdLFxuICAgIFtcIk51bcOpcm8gZHUgdGV4dGVcIiwgcmVzdWx0Lm51bWVyb1RleHRlXSxcbiAgICBbXCJQcm9jw6lkdXJlIGFjY8OpbMOpcsOpXCIsIHJlc3VsdC5wcm9jZWR1cmVBY2NlbGVyZWVdLFxuICBdKVxuICBjb25zb2xlLmdyb3VwRW5kKClcbiAgZGVsaW1pdGVyKClcblxuICBjb25zdCBhanYgPSBuZXcgQWp2KClcbiAgaWYgKGFqdi52YWxpZGF0ZShNRVRBX0RPTk5FRVNfU0NIRU1BLCByZXN1bHQpKSB7XG4gICAgcnVuTG9nRnVuKGNvbnNvbGUud2FybihcIk1ldGEtZG9ubsOpZXMgT0sg8J+RjFwiKSwgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSlcbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICBydW5Mb2dGdW4oY29uc29sZS53YXJuKFwiTWV0YS1kb25uw6llcyBub24tY29uZm9ybWUg4p2MXCIpLCB7XG4gICAgc2lsZW50OiBTSUxFTlRfTE9HLFxuICB9KVxuICByZXR1cm4ge31cbn1cblxuLyoqXG4gKiBBc3luY2hyb25vdXNseSBleHRyYWN0cyB0aGUgXCJwcm9qZXQgZGUgbG9pXCIgZnJvbSB0aGUgZ2l2ZW4gSFRNTC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbCAtIFRoZSBIVE1MIHN0cmluZyBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdGhlIFwicHJvamV0IGRlIGxvaVwiLlxuICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gLSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgZXh0cmFjdGVkIFwicHJvamV0IGRlIGxvaVwiIG9iamVjdC5cbiAqIFRoZSBvYmplY3QgY29udGFpbnMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICogLSBgYXJ0aWNsZXNgOiBBbiBhcnJheSBvZiBhcnRpY2xlIG9iamVjdHMsIGVhY2ggY29udGFpbmluZyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKiAgIC0gYG51bWVyb0FydGljbGVgOiBUaGUgbnVtYmVyIG9mIHRoZSBhcnRpY2xlLlxuICogICAtIGBjYXJkaW5hbGA6IFRoZSBjYXJkaW5hbCBvZiB0aGUgYXJ0aWNsZS5cbiAqICAgLSBgdGl0cmVgOiBUaGUgdGl0bGUgb2YgdGhlIGFydGljbGUuXG4gKiAgIC0gYGRlYnV0YDogVGhlIGJlZ2lubmluZyBvZiB0aGUgYXJ0aWNsZS5cbiAqICAgLSBgZmluYDogVGhlIGVuZCBvZiB0aGUgYXJ0aWNsZS5cbiAqICAgLSBgYWxpbmVhc2A6IEFuIGFycmF5IG9mIGFsaW5lYXMuXG4gKiBAdGhyb3dzIHtFcnJvcn0gLSBJZiB0aGUgZXh0cmFjdGVkIFwicHJvamV0IGRlIGxvaVwiIGRvZXMgbm90IHZhbGlkYXRlIGFnYWluc3QgdGhlIFBST0pFVF9MT0lfU0NIRU1BLlxuICovXG5hc3luYyBmdW5jdGlvbiBleHRyYWN0UHJvamV0TG9pKGh0bWw6IHN0cmluZykge1xuICBydW5Mb2dGdW4oY29uc29sZS5ncm91cChcIlBhcnNpbmcgbG9pLi4uXCIpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICBsZXQgY2xlYW5lZEh0bWwgPSBjbGVhbkh0bWwoaHRtbClcbiAgY29uc3Qgc3RydWN0dXJlZE1vZGVsID0gTU9ERUwud2l0aFN0cnVjdHVyZWRPdXRwdXQoUFJPSkVUX0xPSV9TQ0hFTUEpXG5cbiAgY29uc3QgcHJvamV0TG9pU3lzdGVtVGVtcGxhdGUgPSBgXG4gICAgJHtTWVNURU1fVEVNUExBVEV9XG5cbiAgICAjIEV4YW1wbGVzOiBcblxuICAgICMjIEV4ZW1wbGUgMSBVc2VyIElucHV0IDpcbiAgICBcIlwiXCJcbiAgICB7ZXhhbXBsZTF9XG4gICAgXCJcIlwiXG4gICAgXG4gICAgIyMgRXhlbXBsZSAxIEpTT04gT3V0cHV0IDpcbiAgICBcIlwiXCJcbiAgICB7b3V0cHV0MX1cbiAgICBcIlwiXCJcblxuICAgICMjIEV4ZW1wbGUgMiBVc2VyIElucHV0IDpcbiAgICBcIlwiXCJcbiAgICB7ZXhhbXBsZTJ9XG4gICAgXCJcIlwiXG4gICAgXG4gICAgIyMgRXhlbXBsZSAyIEpTT04gT3V0cHV0IDpcbiAgICBcIlwiXCJcbiAgICB7b3V0cHV0Mn1cbiAgICBcIlwiXCJcbiAgICBgXG5cbiAgY29uc3QgcHJvbXB0ID0gQ2hhdFByb21wdFRlbXBsYXRlLmZyb21NZXNzYWdlcyhbXG4gICAgW1wic3lzdGVtXCIsIHByb2pldExvaVN5c3RlbVRlbXBsYXRlXSxcbiAgICBbXCJodW1hblwiLCBcIntpbnB1dH1cIl0sXG4gIF0pXG5cbiAgY29uc3QgY2hhaW4gPSBwcm9tcHQucGlwZShzdHJ1Y3R1cmVkTW9kZWwpXG4gIGNvbnN0IGFydGljbGVzUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBleGFtcGxlMTogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMDkxNC5pbnB1dCxcbiAgICBleGFtcGxlMjogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMjQyNC5pbnB1dCxcbiAgICBvdXRwdXQxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0LmxvaSxcbiAgICBvdXRwdXQyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0LmxvaSxcbiAgfSlcblxuICBydW5Mb2dGdW4oXG4gICAgY29uc29sZS5sb2coXCJGb3VuZCBcIiwgYXJ0aWNsZXNQcm9tcHRSZXN1bHQuYXJ0aWNsZXMubGVuZ3RoLCBcIiBhcnRpY2xlcy5cIiksXG4gICAgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSxcbiAgKVxuXG4gIGZvciAoY29uc3QgYXJ0aWNsZSBvZiBhcnRpY2xlc1Byb21wdFJlc3VsdC5hcnRpY2xlcykge1xuICAgIGFydGljbGUuYWxpbmVhcyA9IGF3YWl0IGV4dHJhY3RBbGluZWFzKGh0bWwsIGFydGljbGUpXG4gIH1cblxuICBydW5Mb2dGdW4oXG4gICAgY29uc29sZS50YWJsZShcbiAgICAgIGFydGljbGVzUHJvbXB0UmVzdWx0LmFydGljbGVzLm1hcCgoYXJ0aWNsZTogYW55KSA9PiBbXG4gICAgICAgIGFydGljbGUubnVtZXJvQXJ0aWNsZSxcbiAgICAgICAgYXJ0aWNsZS50aXRyZSxcbiAgICAgICAgYXJ0aWNsZS5kZWJ1dC5zdWJzdHJpbmcoMCwgMTApLFxuICAgICAgICBhcnRpY2xlLmZpbi5zdWJzdHJpbmcoMCwgMTApLFxuICAgICAgICBgTm9tYnJlIGQnYWxpbmVhcyA6ICR7YXJ0aWNsZS5hbGluZWFzLmxlbmd0aH1gLFxuICAgICAgXSksXG4gICAgKSxcbiAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICApXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG5cbiAgY29uc3QgYWp2ID0gbmV3IEFqdigpXG4gIGlmIChhanYudmFsaWRhdGUoUFJPSkVUX0xPSV9TQ0hFTUEsIGFydGljbGVzUHJvbXB0UmVzdWx0KSkge1xuICAgIHJ1bkxvZ0Z1bihjb25zb2xlLmluZm8oXCJQcm9qZXQgZGUgbG9pIE9LIPCfkYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gICAgZGVsaW1pdGVyKClcbiAgICByZXR1cm4gYXJ0aWNsZXNQcm9tcHRSZXN1bHRcbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLndhcm4oXCJQcm9qZXQgZGUgbG9pIEtPIOKdjFwiKSwgeyBzaWxlbnQ6IFNJTEVOVF9MT0cgfSlcbiAgZGVsaW1pdGVyKClcbiAgcmV0dXJuIHt9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RBbGluZWFzKGh0bWw6IHN0cmluZywgYXJ0aWNsZTogYW55KSB7XG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwKFwiUGFyc2luZyBhbGluZWFzLi4uXCIpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICBsZXQgY2xlYW5lZEh0bWwgPSBjbGVhbkh0bWwoaHRtbClcblxuICBjb25zdCBzdHJ1Y3R1cmVkTW9kZWwgPSBNT0RFTC53aXRoU3RydWN0dXJlZE91dHB1dChBTElORUFfU0NIRU1BKVxuXG4gIGNvbnN0IGFsaW5lYXNTeXN0ZW1UZW1wbGF0ZSA9IGBcbiAgICAke1NZU1RFTV9URU1QTEFURX1cblxuICAgIEV4dHJhaXMgdG91cyBsZXMgYWxpbmVhcyBkZSBsYSBwb3J0aW9uIGRlIHRleHRlIGNvbW1lbsOnYW50IHBhciDCqyB7ZGVidXR9IMK7IGV0IGZpbmlzc2FudCBwYXIgwqsge2Zpbn0gwrsuXG4gICAgVW4gYWxpbsOpYSBjb250aWVubmVudCB0b3Vqb3VycyB1bmUgYmFsaXNlIMKrIDxpbWcgwrsuXG5cbiAgICAjIEV4YW1wbGVzOiBcblxuICAgICMjIEV4ZW1wbGUgMSBVc2VyIElucHV0IDpcbiAgICBcIlwiXCJcbiAgICB7ZXhhbXBsZTF9XG4gICAgXCJcIlwiXG4gICAgXG4gICAgIyMgRXhlbXBsZSAxIEpTT04gT3V0cHV0IDpcbiAgICBcIlwiXCJcbiAgICB7b3V0cHV0MX1cbiAgICBcIlwiXCJcbiAgICBgXG5cbiAgY29uc3QgcHJvbXB0ID0gQ2hhdFByb21wdFRlbXBsYXRlLmZyb21NZXNzYWdlcyhbXG4gICAgW1wic3lzdGVtXCIsIGFsaW5lYXNTeXN0ZW1UZW1wbGF0ZV0sXG4gICAgW1wiaHVtYW5cIiwgXCJ7aW5wdXR9XCJdLFxuICBdKVxuXG4gIGNvbnN0IGNoYWluID0gcHJvbXB0LnBpcGUoc3RydWN0dXJlZE1vZGVsKVxuICBjb25zdCBhbGluZWFzUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBkZWJ1dDogYXJ0aWNsZS5kZWJ1dCxcbiAgICBmaW46IGFydGljbGUuZmluLFxuICAgIGV4YW1wbGUxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyNDI0LmlucHV0LFxuICAgIG91dHB1dDE6IEVYQU1QTEVTLlBSSkxBTlI1TDE2QjI0MjQuYWxpbmVhcyxcbiAgfSlcblxuICBjb25zdCBhanYgPSBuZXcgQWp2KClcbiAgaWYgKGFqdi52YWxpZGF0ZShBTElORUFfU0NIRU1BLCBhbGluZWFzUHJvbXB0UmVzdWx0IGFzIGFueSkpIHtcbiAgICBydW5Mb2dGdW4oXG4gICAgICBjb25zb2xlLmluZm8oXG4gICAgICAgIFwiRm91bmQgXCIsXG4gICAgICAgIGFsaW5lYXNQcm9tcHRSZXN1bHQuYWxpbmVhcy5sZW5ndGgsXG4gICAgICAgIFwiIGFsaW5lYXMgZm9yIEFydGljbGUgXCIsXG4gICAgICAgIGFydGljbGUubnVtZXJvQXJ0aWNsZSxcbiAgICAgICAgYXJ0aWNsZS50aXRyZSxcbiAgICAgICksXG4gICAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICAgIClcbiAgICBydW5Mb2dGdW4oY29uc29sZS5ncm91cEVuZCgpLCB7IHNpbGVudDogU0lMRU5UX0xPRyB9KVxuICAgIGRlbGltaXRlcigpXG4gICAgcmV0dXJuIGFsaW5lYXNQcm9tcHRSZXN1bHQuYWxpbmVhc1xuICB9XG5cbiAgcnVuTG9nRnVuKGNvbnNvbGUud2FybihcIkFsaW5lYXMgS09cIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIGRlbGltaXRlcigpXG4gIHJldHVybiB7fVxufVxuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IGV4dHJhY3RzIHRoZSBcInNvbW1haXJlXCIgKG91dGxpbmUpIGZyb20gdGhlIGdpdmVuIEhUTUwuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGh0bWwgLSBUaGUgSFRNTCBzdHJpbmcgZnJvbSB3aGljaCB0byBleHRyYWN0IHRoZSBcInNvbW1haXJlXCIuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSAtIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBleHRyYWN0ZWQgXCJzb21tYWlyZVwiIG9iamVjdC5cbiAqIFRoZSBvYmplY3QgY29udGFpbnMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICogLSBgc29tbWFpcmVgOiBBbiBhcnJheSBvZiBtYWluIGRpdmlzaW9uIG9iamVjdHMsIGVhY2ggY29udGFpbmluZyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKiAgIC0gYG51bWVyb0RpdmlzaW9uYDogVGhlIG51bWJlciBvZiB0aGUgbWFpbiBkaXZpc2lvbi5cbiAqICAgLSBgdGl0cmVgOiBUaGUgdGl0bGUgb2YgdGhlIG1haW4gZGl2aXNpb24uXG4gKiAgIC0gYHR5cGVEaXZpc2lvbmA6IFRoZSB0eXBlIG9mIGNvbnRlbnQgaW4gdGhlIG1haW4gZGl2aXNpb24uXG4gKiAgIC0gYHNlcXVlbmNlYDogVGhlIHNlcXVlbmNlIG9mIHRoZSBtYWluIGRpdmlzaW9uLlxuICogICAtIGBwYXJlbnRgOiBUaGUgcGFyZW50IG9mIHRoZSBtYWluIGRpdmlzaW9uLlxuICogQHRocm93cyB7RXJyb3J9IC0gSWYgdGhlIGV4dHJhY3RlZCBcInNvbW1haXJlXCIgZG9lcyBub3QgdmFsaWRhdGUgYWdhaW5zdCB0aGUgU09NTUFJUkVfU0NIRU1BLlxuICovXG5hc3luYyBmdW5jdGlvbiBleHRyYWN0U29tbWFpcmUoaHRtbDogc3RyaW5nKSB7XG4gIGxldCBjbGVhbmVkSHRtbCA9IGNsZWFuSHRtbChodG1sKVxuICBjbGVhbmVkSHRtbCA9IHJlbW92ZUh0bWxUYWdzKGNsZWFuZWRIdG1sKVxuXG4gIGNvbnN0IHN0cnVjdHVyZWRNb2RlbCA9IE1PREVMLndpdGhTdHJ1Y3R1cmVkT3V0cHV0KFNPTU1BSVJFX1NDSEVNQSlcblxuICBjb25zdCBzb21tYWlyZVN5c3RlbVRlbXBsYXRlID0gYFxuICAgICR7U1lTVEVNX1RFTVBMQVRFfVxuXG4gICAgIyBFeGFtcGxlczogXG5cbiAgICAjIyBFeGVtcGxlIDEgVXNlciBJbnB1dCA6XG4gICAgXCJcIlwiXG4gICAge2V4YW1wbGUxfVxuICAgIFwiXCJcIlxuICAgIFxuICAgICMjIEV4ZW1wbGUgMSBKU09OIE91dHB1dCA6XG4gICAgXCJcIlwiXG4gICAge291dHB1dDF9XG4gICAgXCJcIlwiXG5cbiAgICAjIyBFeGVtcGxlIDIgVXNlciBJbnB1dCA6XG4gICAgXCJcIlwiXG4gICAge2V4YW1wbGUyfVxuICAgIFwiXCJcIlxuICAgIFxuICAgICMjIEV4ZW1wbGUgMiBKU09OIE91dHB1dCA6XG4gICAgXCJcIlwiXG4gICAge291dHB1dDJ9XG4gICAgXCJcIlwiXG4gICAgYFxuXG4gIGNvbnN0IHByb21wdCA9IENoYXRQcm9tcHRUZW1wbGF0ZS5mcm9tTWVzc2FnZXMoW1xuICAgIFtcInN5c3RlbVwiLCBzb21tYWlyZVN5c3RlbVRlbXBsYXRlXSxcbiAgICBbXCJodW1hblwiLCBcIntpbnB1dH1cIl0sXG4gIF0pXG5cbiAgY29uc3QgY2hhaW4gPSBwcm9tcHQucGlwZShzdHJ1Y3R1cmVkTW9kZWwpXG4gIGNvbnN0IHNvbW1haXJlUHJvbXB0UmVzdWx0OiBhbnkgPSBhd2FpdCBjaGFpbi5pbnZva2Uoe1xuICAgIGlucHV0OiBjbGVhbmVkSHRtbCxcbiAgICBleGFtcGxlMTogRVhBTVBMRVMuUFJKTEFOUjVMMTZCMjAxNC5pbnB1dCxcbiAgICBvdXRwdXQxOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIyMDE0LnNvbW1haXJlLFxuICAgIGV4YW1wbGUyOiBFWEFNUExFUy5QUkpMQU5SNUwxNkIwOTE0LmlucHV0LFxuICAgIG91dHB1dDI6IEVYQU1QTEVTLlBSSkxBTlI1TDE2QjA5MTQuc29tbWFpcmUsXG4gIH0pXG5cbiAgaWYgKCFzb21tYWlyZVByb21wdFJlc3VsdC5zb21tYWlyZSkge1xuICAgIHJ1bkxvZ0Z1bihjb25zb2xlLndhcm4oXCJBdWN1biBzb21tYWlyZSBuJ2Egw6l0w6kgdHJvdXbDqSDinZNcIiksIHtcbiAgICAgIHNpbGVudDogU0lMRU5UX0xPRyxcbiAgICB9KVxuICAgIGRlbGltaXRlcigpXG4gICAgcmV0dXJuIHsgc29tbWFpcmU6IFtdIH1cbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwKFwiU29tbWFpcmVcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gIHJ1bkxvZ0Z1bihcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIFwiRm91bmQgXCIsXG4gICAgICBzb21tYWlyZVByb21wdFJlc3VsdC5zb21tYWlyZS5sZW5ndGgsXG4gICAgICBcIiBtYWluIGRpdmlzaW9ucyAobGV2ZWwgMSkuXCIsXG4gICAgKSxcbiAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICApXG4gIHJ1bkxvZ0Z1bihcbiAgICBjb25zb2xlLnRhYmxlKFxuICAgICAgc29tbWFpcmVQcm9tcHRSZXN1bHQuc29tbWFpcmUubWFwKChpdGVtOiBhbnkpID0+IFtcbiAgICAgICAgaXRlbS5zZXF1ZW5jZSxcbiAgICAgICAgaXRlbS50aXRyZSxcbiAgICAgICAgaXRlbS50eXBlRGl2aXNpb24sXG4gICAgICAgIGl0ZW0ucGFyZW50LFxuICAgICAgXSksXG4gICAgKSxcbiAgICB7IHNpbGVudDogU0lMRU5UX0xPRyB9LFxuICApXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLmdyb3VwRW5kKCksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG5cbiAgY29uc3QgYWp2ID0gbmV3IEFqdigpXG4gIGlmIChhanYudmFsaWRhdGUoU09NTUFJUkVfU0NIRU1BLCBzb21tYWlyZVByb21wdFJlc3VsdCBhcyBhbnkpKSB7XG4gICAgcnVuTG9nRnVuKGNvbnNvbGUuaW5mbyhcIlNvbW1haXJlIE9LIPCfkYxcIiksIHsgc2lsZW50OiBTSUxFTlRfTE9HIH0pXG4gICAgZGVsaW1pdGVyKClcbiAgICByZXR1cm4gc29tbWFpcmVQcm9tcHRSZXN1bHQuc29tbWFpcmVcbiAgfVxuXG4gIHJ1bkxvZ0Z1bihjb25zb2xlLndhcm4oXCJMYSBjb25zdHJ1Y3Rpb24gZHUgc29tbWFpcmUgZXN0IEtPIOKdjFwiKSwge1xuICAgIHNpbGVudDogU0lMRU5UX0xPRyxcbiAgfSlcbiAgZGVsaW1pdGVyKClcbiAgcmV0dXJuIHsgc29tbWFpcmU6IFtdIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsVUFBVSxRQUFRLG1CQUFtQjtBQUM5QyxTQUFTQyxrQkFBa0IsUUFBUSx5QkFBeUI7QUFDNUQsT0FBT0MsR0FBRyxNQUFNLEtBQUs7QUFBQSxTQUVaQyxTQUFTLEVBQUVDLFNBQVM7QUFFN0IsTUFBTUMsYUFBYSxHQUFHQyxPQUFPLENBQUMsa0NBQWtDLENBQUM7QUFDakUsTUFBTUMsb0JBQW9CLEdBQUdELE9BQU8sQ0FBQyx3Q0FBd0MsQ0FBQztBQUM5RSxNQUFNRSxtQkFBbUIsR0FBR0YsT0FBTyxDQUFDLHVDQUF1QyxDQUFDO0FBQzVFLE1BQU1HLGlCQUFpQixHQUFHSCxPQUFPLENBQUMscUNBQXFDLENBQUM7QUFDeEUsTUFBTUksZUFBZSxHQUFHSixPQUFPLENBQUMsb0NBQW9DLENBQUM7O0FBRXJFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNSyxRQUFRLEdBQUc7RUFDZkMsZ0JBQWdCLEVBQUU7SUFDaEJDLE1BQU0sRUFBRVAsT0FBTyxDQUFDLDBDQUEwQyxDQUFDO0lBQzNEUSxLQUFLLEVBQUVSLE9BQU8sQ0FBQyxvQ0FBb0MsQ0FBQztJQUNwRFMsR0FBRyxFQUFFVCxPQUFPLENBQUMsdUNBQXVDLENBQUM7SUFDckRVLElBQUksRUFBRVYsT0FBTyxDQUFDLHdDQUF3QyxDQUFDO0lBQ3ZEVyxRQUFRLEVBQUVYLE9BQU8sQ0FBQyw0Q0FBNEM7RUFDaEUsQ0FBQztFQUNEWSxnQkFBZ0IsRUFBRTtJQUNoQkwsTUFB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
|
|
260
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhc3NlcnQiLCJKU0RPTSIsInBhcnNlSGVhZGVyIiwiaGVhZGVyIiwiaGVhZGVyc01hcHBpbmciLCJyZWdleCIsImxldmVsIiwibmFtZSIsIm1hdGNoIiwiY2xlYW5UZXh0IiwidGV4dCIsInJlcGxhY2UiLCJ0cmltIiwiZXhjbHVkZWRBbGluZWFzIiwicGFyc2VUZXh0ZSIsImFzc2VtYmxlZVVybCIsInBhZ2UiLCJodG1sIiwid2luZG93IiwiZG9jdW1lbnQiLCJzdHJpY3RFcXVhbCIsImNoaWxkcmVuIiwibGVuZ3RoIiwiaHRtbEVsZW1lbnQiLCJib2R5RWxlbWVudCIsImNsb3NlIiwiZXJyb3IiLCJjb2RlIiwibWVzc2FnZSIsInRhZ05hbWUiLCJib2R5Q2hpbGQiLCJhbGluZWFFbGVtZW50IiwiaXNNdWx0aUxpbmVzSGVhZGVyIiwibGV2ZWxzIiwibmV4dFBhcmVudFN0YXRlIiwic3RhdGUiLCJzdWJkaXZpc2lvbnMiLCJzdWJkaXZpc2lvbkFsaW5lYXMiLCJzdWJkaXZpc2lvbkhlYWRlcnMiLCJuZXh0RWxlbWVudFNpYmxpbmciLCJ1bmRlZmluZWQiLCJpZCIsImluY2x1ZGVzIiwiaGVhZGVyVGV4dCIsInRleHRDb250ZW50IiwibmFtZUNvbXB1dGVkIiwibm9ybWFsaXplIiwibmFtZVVwcGVyIiwidG9VcHBlckNhc2UiLCJuZXh0TGV2ZWwiLCJwYXJhZ3JhcGhUeXBlIiwibGluZUh0bWwiLCJvdXRlckhUTUwiLCJsaW5lVGV4dCIsImV4Y2x1ZGVBbGluZWEiLCJ0ZXN0IiwicHVzaCIsInRleHRlIiwicG9wIiwidHlwZSIsIm5pdmVhdSIsIm5pdmVhdVJlbGF0aWYiLCJ0aXRyZXMiLCJhbGluZWFzIiwidXJsIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BhcnNlcnMvdGV4dGVzX2xvaXMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCJcbmltcG9ydCB7IEpTRE9NIH0gZnJvbSBcImpzZG9tXCJcblxuZnVuY3Rpb24gcGFyc2VIZWFkZXIoaGVhZGVyOiBzdHJpbmcpOiBbbnVtYmVyIHwgbnVsbCwgc3RyaW5nXSB7XG4gIGNvbnN0IGhlYWRlcnNNYXBwaW5nOiB7IHJlZ2V4OiBSZWdFeHA7IGxldmVsOiBudW1iZXI7IG5hbWU6IHN0cmluZyB9W10gPSBbXG4gICAgeyByZWdleDogL14oUkFQUE9SVF8pP0FOTkVYRShffCQpfF5FVEFUXy8sIGxldmVsOiAwLCBuYW1lOiBcIkFubmV4ZVwiIH0sXG4gICAgeyByZWdleDogL15UT01FXy8sIGxldmVsOiAxLCBuYW1lOiBcIlRvbWVcIiB9LFxuICAgIHtcbiAgICAgIHJlZ2V4OlxuICAgICAgICAvXlBBUlRJRV98XihQUkVNSUVSRXxTRUNPTkRFfERFVVhJRU1FfFRST0lTSUVNRXxRVUFUUklFTUUpX1BBUlRJRShffCQpLyxcbiAgICAgIGxldmVsOiAyLFxuICAgICAgbmFtZTogXCJQYXJ0aWVcIixcbiAgICB9LFxuICAgIHsgcmVnZXg6IC9eTElWUkVfLywgbGV2ZWw6IDMsIG5hbWU6IFwiTGl2cmVcIiB9LFxuICAgIHsgcmVnZXg6IC9eVElUUkVfLywgbGV2ZWw6IDQsIG5hbWU6IFwiVGl0cmVcIiB9LFxuICAgIHsgcmVnZXg6IC9eU09VU1RJVFJFXy8sIGxldmVsOiA1LCBuYW1lOiBcIlNvdXNUaXRyZVwiIH0sXG4gICAgeyByZWdleDogL15DSEFQSVRSRV8vLCBsZXZlbDogNiwgbmFtZTogXCJDaGFwaXRyZVwiIH0sXG4gICAgeyByZWdleDogL15TRUNUSU9OXy8sIGxldmVsOiA3LCBuYW1lOiBcIlNlY3Rpb25cIiB9LFxuICAgIHsgcmVnZXg6IC9eU09VU1NFQ1RJT05fLywgbGV2ZWw6IDgsIG5hbWU6IFwiU291c1NlY3Rpb25cIiB9LFxuICAgIHsgcmVnZXg6IC9eQVJUSUNMRVM/X3xeRVhQT1NFX0RFU19NT1RJRlMkLywgbGV2ZWw6IDksIG5hbWU6IFwiQXJ0aWNsZVwiIH0sXG4gIF1cblxuICBmb3IgKGxldCB7IHJlZ2V4LCBsZXZlbCwgbmFtZSB9IG9mIGhlYWRlcnNNYXBwaW5nKSB7XG4gICAgaWYgKGhlYWRlci5tYXRjaChyZWdleCkpIHtcbiAgICAgIHJldHVybiBbbGV2ZWwsIG5hbWVdXG4gICAgfVxuICB9XG4gIHJldHVybiBbbnVsbCwgXCJcIl1cbn1cblxuZnVuY3Rpb24gY2xlYW5UZXh0KHRleHQ6IHN0cmluZyB8IG51bGwpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dD8ucmVwbGFjZSgvW1xcblxcdF0rL2csIFwiXCIpLnRyaW0oKSB8fCBcIlwiXG59XG5cbmNvbnN0IGV4Y2x1ZGVkQWxpbmVhcyA9IFtcbiAgL15Ew6lsaWLDqXLDqSBlbiBzw6lhbmNlIHB1YmxpcXVlLyxcbiAgL15GYWl0IGxlLyxcbiAgL15MZSBQcsOpc2lkZW50LCQvLFxuICAvXlNpZ27DqS8sXG5dXG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVRleHRlKGFzc2VtYmxlZVVybDogc3RyaW5nLCBwYWdlOiBzdHJpbmcpIHtcbiAgLy8gUmVwYWlyIEhUTUwuXG4gIGxldCBodG1sID0gcGFnZS5yZXBsYWNlKC8oPHN0eWxlW1xcd1xcV10rc3R5bGU+KS9nLCBcIlwiKVxuXG4gIC8vIEV4dHJhY3Qgc3ViZGl2aXNpb25zIGZyb20gSFRNTC5cbiAgY29uc3QgeyB3aW5kb3cgfSA9IG5ldyBKU0RPTShodG1sKVxuICBjb25zdCB7IGRvY3VtZW50IH0gPSB3aW5kb3dcbiAgYXNzZXJ0LnN0cmljdEVxdWFsKGRvY3VtZW50LmNoaWxkcmVuLmxlbmd0aCwgMSlcbiAgY29uc3QgaHRtbEVsZW1lbnQgPSBkb2N1bWVudC5jaGlsZHJlblswXVxuICBhc3NlcnQuc3RyaWN0RXF1YWwoaHRtbEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoLCAyKVxuICBjb25zdCBib2R5RWxlbWVudCA9IGh0bWxFbGVtZW50LmNoaWxkcmVuWzFdXG5cbiAgaWYgKGJvZHlFbGVtZW50LmNoaWxkcmVuLmxlbmd0aCA8IDMpIHtcbiAgICAvLyBPY2N1cnMgaW4gaHR0cDovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyLzE1L3RleHRlcy8wMzI2LmFzcC5cbiAgICB3aW5kb3cuY2xvc2UoKSAvLyBGcmVlIG1lbW9yeS5cbiAgICByZXR1cm4ge1xuICAgICAgZXJyb3I6IHsgY29kZTogLTEsIG1lc3NhZ2U6IFwiVGV4dGUgZGUgbG9pIHNhbnMgY29udGVudVwiIH0sXG4gICAgICBodG1sLFxuICAgICAgcGFnZSxcbiAgICB9XG4gIH1cbiAgYXNzZXJ0LnN0cmljdEVxdWFsKGJvZHlFbGVtZW50LmNoaWxkcmVuWzBdLnRhZ05hbWUsIFwiRElWXCIpXG4gIC8vIEZpcnN0IGNoaWxkIGlzIGEgRElWIGRlc2NyaWJpbmcgdGhlIGRvY3VtZW50IChBc3NlbWJsw6llJ3MgaGVhZGVyKS4gU2tpcCBpdCBmb3Igbm93LlxuICBsZXQgYm9keUNoaWxkID0gYm9keUVsZW1lbnQuY2hpbGRyZW5bMV1cblxuICBhc3NlcnQuc3RyaWN0RXF1YWwoYm9keUNoaWxkLnRhZ05hbWUsIFwiQlJcIilcbiAgbGV0IGFsaW5lYUVsZW1lbnQ6IEVsZW1lbnQgfCBudWxsID0gbnVsbFxuICBsZXQgaXNNdWx0aUxpbmVzSGVhZGVyOiBib29sZWFuID0gZmFsc2VcbiAgbGV0IGxldmVsOiBudW1iZXIgfCBudWxsID0gbnVsbFxuICBsZXQgbGV2ZWxzOiBudW1iZXJbXSA9IFtdXG4gIGxldCBuZXh0UGFyZW50U3RhdGUgPSBudWxsXG4gIGxldCBzdGF0ZTogc3RyaW5nIHwgbnVsbCA9IFwibmV4dEJvZHlDaGlsZFwiXG4gIGNvbnN0IHN1YmRpdmlzaW9ucyA9IFtdXG4gIGxldCBzdWJkaXZpc2lvbkFsaW5lYXM6IG9iamVjdFtdIHwgbnVsbCA9IG51bGxcbiAgbGV0IHN1YmRpdmlzaW9uSGVhZGVyczogb2JqZWN0W10gfCBudWxsID0gbnVsbFxuICB3aGlsZSAoc3RhdGUgIT09IG51bGwpIHtcbiAgICBzd2l0Y2ggKHN0YXRlKSB7XG4gICAgICBjYXNlIFwibmV4dEJvZHlDaGlsZFwiOlxuICAgICAgICBpZiAoYm9keUNoaWxkLm5leHRFbGVtZW50U2libGluZyA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIFRoZSBkb2N1bWVudCBoYXMgYmVlbiBmdWxseSBwYXJzZWQuXG4gICAgICAgICAgc3RhdGUgPSBudWxsXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYm9keUNoaWxkID0gYm9keUNoaWxkLm5leHRFbGVtZW50U2libGluZ1xuICAgICAgICAgIGlmIChib2R5Q2hpbGQudGFnTmFtZSA9PT0gXCJESVZcIikge1xuICAgICAgICAgICAgYWxpbmVhRWxlbWVudCA9IGJvZHlDaGlsZC5jaGlsZHJlblswXVxuXG4gICAgICAgICAgICBpZiAoYWxpbmVhRWxlbWVudCA9PT0gdW5kZWZpbmVkIHx8IGJvZHlDaGlsZC5pZC5pbmNsdWRlcyhcImZ0blwiKSkge1xuICAgICAgICAgICAgICAvLyBObyBhbGluZWEgaW4gY3VycmVudCBib2R5Q2hpbGQ6IGdvIHRvIG5leHQgYm9keUNoaWxkLlxuICAgICAgICAgICAgICBzdGF0ZSA9IFwibmV4dEJvZHlDaGlsZFwiXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzdGF0ZSA9IFwiYWxpbmVhRWxlbWVudFwiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIDxQLz4gaXMgZm9yIGZvb3Rub3Rlc1xuICAgICAgICAgICAgYXNzZXJ0KFxuICAgICAgICAgICAgICBbXCJCUlwiLCBcIkhSXCIsIFwiUFwiXS5pbmNsdWRlcyhib2R5Q2hpbGQudGFnTmFtZSksXG4gICAgICAgICAgICAgIGBVbmV4cGVjdGVkIHRhZyBuYW1lIFwiJHtib2R5Q2hpbGQudGFnTmFtZX1cIiBmb3IgYm9keSBjaGlsZGAsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAvLyBTdGF5IGluIHRoZSBzYW1lIHN0YXRlIHRvIGdvIHRvIG5leHQgYm9keUNoaWxkLlxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSBcImFsaW5lYUVsZW1lbnRcIjpcbiAgICAgICAgc3dpdGNoIChhbGluZWFFbGVtZW50IS50YWdOYW1lKSB7XG4gICAgICAgICAgY2FzZSBcIkRJVlwiOlxuICAgICAgICAgICAgc3RhdGUgPSBcIm5leHRBbGluZWFFbGVtZW50XCJcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgY2FzZSBcIkg0XCI6XG4gICAgICAgICAgICAvLyBUT0RPXG4gICAgICAgICAgICBuZXh0UGFyZW50U3RhdGUgPSBcIm5leHRBbGluZWFFbGVtZW50XCJcbiAgICAgICAgICAgIHN0YXRlID0gXCJmaXJzdFBhcmFncmFwaENoaWxkXCJcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgY2FzZSBcIlBcIjpcbiAgICAgICAgICAgIG5leHRQYXJlbnRTdGF0ZSA9IFwibmV4dEFsaW5lYUVsZW1lbnRcIlxuICAgICAgICAgICAgc3RhdGUgPSBcImZpcnN0UGFyYWdyYXBoQ2hpbGRcIlxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICBjYXNlIFwiT0xcIjpcbiAgICAgICAgICAgIC8vIFRPRE9cbiAgICAgICAgICAgIHN0YXRlID0gXCJuZXh0QWxpbmVhRWxlbWVudFwiXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIGNhc2UgXCJUQUJMRVwiOlxuICAgICAgICAgICAgbmV4dFBhcmVudFN0YXRlID0gXCJuZXh0QWxpbmVhRWxlbWVudFwiXG4gICAgICAgICAgICBzdGF0ZSA9IFwiZmlyc3RQYXJhZ3JhcGhDaGlsZFwiXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgICAgIGNvZGU6IC0yLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBVbmV4cGVjdGVkIHRhZyBuYW1lIGZvciBhbGluZWEgZWxlbWVudDogJHtcbiAgICAgICAgICAgICAgICAgIGFsaW5lYUVsZW1lbnQhLnRhZ05hbWVcbiAgICAgICAgICAgICAgICB9YCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgaHRtbCxcbiAgICAgICAgICAgICAgcGFnZSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSBcImZpcnN0UGFyYWdyYXBoQ2hpbGRcIjpcbiAgICAgICAgY29uc3QgaGVhZGVyVGV4dCA9IGFsaW5lYUVsZW1lbnQhLnRleHRDb250ZW50XG4gICAgICAgIGNvbnN0IG5hbWVDb21wdXRlZCA9IChoZWFkZXJUZXh0IHx8IFwiXCIpXG4gICAgICAgICAgLm5vcm1hbGl6ZShcIk5GRFwiKVxuICAgICAgICAgIC5yZXBsYWNlKC9bXFx1MDMwMC1cXHUwMzZmXS9nLCBcIlwiKVxuICAgICAgICAgIC5yZXBsYWNlKC9cXChub3V2ZWF1XFwpLywgXCJcIilcbiAgICAgICAgICAucmVwbGFjZSgvXFwoUG91ciBjb29yZGluYXRpb25cXCkvLCBcIlwiKVxuICAgICAgICAgIC5yZXBsYWNlKC9cXChTdXBwcmltw6lzP1xcKS8sIFwiXCIpXG4gICAgICAgICAgLnJlcGxhY2UoL8KgL2csIFwiIFwiKVxuICAgICAgICAgIC5yZXBsYWNlKC9bXFwtLC7igKZdL2csIFwiXCIpXG4gICAgICAgICAgLnRyaW0oKVxuICAgICAgICAgIC5yZXBsYWNlKC8gezEsfS9nLCBcIl9cIilcblxuICAgICAgICBjb25zdCBuYW1lVXBwZXIgPSBuYW1lQ29tcHV0ZWQudG9VcHBlckNhc2UoKVxuICAgICAgICBjb25zdCBbbmV4dExldmVsLCBwYXJhZ3JhcGhUeXBlXSA9IHBhcnNlSGVhZGVyKG5hbWVVcHBlcilcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgIW5hbWVVcHBlciB8fFxuICAgICAgICAgIG5hbWVVcHBlci5tYXRjaCgvXihQUk9KRVR8UFJPUE9TSVRJT04pX0RFX0xPSShffCQpLykgIT09IG51bGxcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gT2NjdXJzIGluOlxuICAgICAgICAgIC8vICogaHR0cDovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyLzE1L3RleHRlcy8wMjMyLmFzcFxuICAgICAgICAgIC8vICogaHR0cDovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyLzE1L3RleHRlcy8wNjI2LmFzcFxuICAgICAgICAgIC8vICogaHR0cDovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyLzE1L3RleHRlcy8wNjc2LmFzcFxuICAgICAgICAgIHN0YXRlID0gbmV4dFBhcmVudFN0YXRlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfSBlbHNlIGlmIChuYW1lVXBwZXIgPT09IFwiSkVVWF9PTFlNUElRVUVTX0VUX1BBUkFMWU1QSVFVRVNfREVfMjAyNFwiKSB7XG4gICAgICAgICAgLy8gT2NjdXJzIGluIGh0dHA6Ly93d3cuYXNzZW1ibGVlLW5hdGlvbmFsZS5mci8xNS90ZXh0ZXMvMDY3Ni5hc3BcbiAgICAgICAgICBzdGF0ZSA9IG5leHRQYXJlbnRTdGF0ZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH0gZWxzZSBpZiAobmFtZVVwcGVyID09PSBcIlRFWFRFX0RFX0xBX0NPTU1JU1NJT05fTUlYVEVfUEFSSVRBSVJFXCIpIHtcbiAgICAgICAgICAvLyBPY2N1cnMgaW4gaHR0cDovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyLzE1L3RleHRlcy8xMjk0LmFzcFxuICAgICAgICAgIHN0YXRlID0gbmV4dFBhcmVudFN0YXRlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxpbmVIdG1sID0gY2xlYW5UZXh0KGFsaW5lYUVsZW1lbnQhLm91dGVySFRNTClcbiAgICAgICAgY29uc3QgbGluZVRleHQgPSBjbGVhblRleHQoYWxpbmVhRWxlbWVudCEudGV4dENvbnRlbnQpXG5cbiAgICAgICAgaWYgKG5leHRMZXZlbCA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIEl0IGlzIGEgcmVndWxhciBhbGluZWFcbiAgICAgICAgICAvLyBFeGNsdWRlIHNvbWUgYWxpbmVhc1xuICAgICAgICAgIGxldCBleGNsdWRlQWxpbmVhID0gZmFsc2VcbiAgICAgICAgICBmb3IgKGxldCByZWdleCBvZiBleGNsdWRlZEFsaW5lYXMpIHtcbiAgICAgICAgICAgIGlmIChyZWdleC50ZXN0KGxpbmVUZXh0KSkge1xuICAgICAgICAgICAgICBleGNsdWRlQWxpbmVhID0gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZXhjbHVkZUFsaW5lYSkge1xuICAgICAgICAgICAgc3RhdGUgPSBuZXh0UGFyZW50U3RhdGVcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHN1YmRpdmlzaW9uSGVhZGVycyEubGVuZ3RoID09PSAwIHx8XG4gICAgICAgICAgICAoaXNNdWx0aUxpbmVzSGVhZGVyICYmIHN1YmRpdmlzaW9uQWxpbmVhcyEubGVuZ3RoID09PSAwKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgc3ViZGl2aXNpb25IZWFkZXJzIS5wdXNoKHtcbiAgICAgICAgICAgICAgdGV4dGU6IGxpbmVUZXh0LFxuICAgICAgICAgICAgICBodG1sOiBsaW5lSHRtbCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN1YmRpdmlzaW9uQWxpbmVhcyEucHVzaCh7XG4gICAgICAgICAgICAgIHRleHRlOiBsaW5lVGV4dCxcbiAgICAgICAgICAgICAgaHRtbDogbGluZUh0bWwsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaXNNdWx0aUxpbmVzSGVhZGVyICYmIHN1YmRpdmlzaW9uSGVhZGVycyEubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgIGlzTXVsdGlMaW5lc0hlYWRlciA9IGZhbHNlXG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFNraXAgcGFyYWdyYXBoLlxuICAgICAgICAgIHN0YXRlID0gbmV4dFBhcmVudFN0YXRlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfSBlbHNlIGlmIChuZXh0TGV2ZWwgIT09IG51bGwpIHtcbiAgICAgICAgICAvLyBJdCBpcyBhIGhlYWRlclxuICAgICAgICAgIGxldmVsID0gbmV4dExldmVsXG4gICAgICAgICAgd2hpbGUgKGxldmVscy5sZW5ndGggPiAwICYmIGxldmVsIDwgbGV2ZWxzW2xldmVscy5sZW5ndGggLSAxXSkge1xuICAgICAgICAgICAgbGV2ZWxzLnBvcCgpXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChsZXZlbHMubGVuZ3RoID09PSAwIHx8IGxldmVsID4gbGV2ZWxzW2xldmVscy5sZW5ndGggLSAxXSkge1xuICAgICAgICAgICAgbGV2ZWxzLnB1c2gobGV2ZWwpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3ViZGl2aXNpb25BbGluZWFzID0gW11cbiAgICAgICAgICBzdWJkaXZpc2lvbkhlYWRlcnMgPSBbeyB0ZXh0ZTogbGluZVRleHQsIGh0bWw6IGxpbmVIdG1sIH1dXG5cbiAgICAgICAgICAvLyBBcnRpY2xlcyAmIFwiRXhwb3PDqSBkZXMgbW90aWZzXCIgYXJlIHRoZSBvbmx5IGRpdmlzaW9ucyB3aXRob3V0IHNlY29uZCB0aXRsZS5cbiAgICAgICAgICBpc011bHRpTGluZXNIZWFkZXIgPVxuICAgICAgICAgICAgbmFtZVVwcGVyLm1hdGNoKC9eQVJUSUNMRVM/Xy8pID09PSBudWxsICYmXG4gICAgICAgICAgICBuYW1lVXBwZXIubWF0Y2goL15FWFBPU0VfREVTX01PVElGUyQvKSA9PT0gbnVsbFxuXG4gICAgICAgICAgc3ViZGl2aXNpb25zLnB1c2goe1xuICAgICAgICAgICAgaWQ6IFwiRF9cIiArIG5hbWVDb21wdXRlZCxcbiAgICAgICAgICAgIHR5cGU6IHBhcmFncmFwaFR5cGUsXG4gICAgICAgICAgICBuaXZlYXU6IGxldmVsICsgMSxcbiAgICAgICAgICAgIG5pdmVhdVJlbGF0aWY6IGxldmVscy5sZW5ndGgsXG4gICAgICAgICAgICB0aXRyZXM6IHN1YmRpdmlzaW9uSGVhZGVycyxcbiAgICAgICAgICAgIGFsaW5lYXM6IHN1YmRpdmlzaW9uQWxpbmVhcyxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGUgPSBuZXh0UGFyZW50U3RhdGVcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgXCJuZXh0QWxpbmVhRWxlbWVudFwiOlxuICAgICAgICBhbGluZWFFbGVtZW50ID0gYWxpbmVhRWxlbWVudCEubmV4dEVsZW1lbnRTaWJsaW5nXG4gICAgICAgIGlmIChhbGluZWFFbGVtZW50ID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gVGhlIGJvZHlDaGlsZCBoYXMgYmVlbiBmdWxseSBwYXJzZWQuIEdvIHRvIG5leHQgYm9keUNoaWxkXG4gICAgICAgICAgc3RhdGUgPSBcIm5leHRCb2R5Q2hpbGRcIlxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXRlID0gXCJhbGluZWFFbGVtZW50XCJcbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgYFVuZXhwZWN0ZWQgc3RhdGU6ICR7c3RhdGV9YFxuICAgIH1cbiAgfVxuXG4gIHdpbmRvdy5jbG9zZSgpIC8vIEZyZWUgbWVtb3J5LlxuXG4gIHJldHVybiB7XG4gICAgZXJyb3I6IG51bGwsXG4gICAgaHRtbCxcbiAgICBwYWdlLFxuICAgIHN1YmRpdmlzaW9ucyxcbiAgICB1cmw6IGFzc2VtYmxlZVVybCxcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPQSxNQUFNLE1BQU0sUUFBUTtBQUMzQixTQUFTQyxLQUFLLFFBQVEsT0FBTztBQUU3QixTQUFTQyxXQUFXQSxDQUFDQyxNQUFjLEVBQTJCO0VBQzVELE1BQU1DLGNBQWdFLEdBQUcsQ0FDdkU7SUFBRUMsS0FBSyxFQUFFLGdDQUFnQztJQUFFQyxLQUFLLEVBQUUsQ0FBQztJQUFFQyxJQUFJLEVBQUU7RUFBUyxD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
|