-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.js
480 lines (475 loc) · 50.5 KB
/
main.js
1
2
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
__markAsModule(target);
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// main.ts
__export(exports, {
default: () => MyPlugin
});
var import_obsidian = __toModule(require("obsidian"));
var { exec } = require("child_process");
var nodeData = {};
var edgeData = {};
var graphDot = {};
var bcNodeList = app.plugins.plugins.breadcrumbs.mainG.toJSON().nodes;
var bcEdgeList = app.plugins.plugins.breadcrumbs.mainG.toJSON().edges;
function debug() {
console.log("nodeData", nodeData);
console.log("edgeData", edgeData);
console.log("graphDot", graphDot);
console.log("process.cwd()", process.cwd());
}
var workingDirectory = app.vault.adapter.getBasePath() + "\\" + app.vault.configDir + "\\plugins\\dotmaker\\graphs\\";
console.log("Starting directory: " + process.cwd());
try {
process.chdir(workingDirectory);
console.log("New directory: " + process.cwd());
} catch (err) {
console.log("chdir: " + err);
}
var MyPlugin = class extends import_obsidian.Plugin {
onload() {
return __async(this, null, function* () {
console.clear();
const nodeTypeListDeclaration = {
masterGraph: {
style: 'shape=plaintext style="filled, rounded" fontname="Lato" margin=0.2 fillcolor="#c6cac3"',
graphHeader: `//splines=ortho;
overlap=false
style=rounded
// ranksep="0.4";
label="Thay \u0111\u1ED5i ni\u1EC1m tin ng\u01B0\u1EDDi c\xF3 ni\u1EC1m tin ti\xEAu c\u1EF1c";
sep=10
fontsize = 30
labelloc="t";
fontname="Lato";`
},
Giaiphap: {
method: "End of edge type"
},
Ytuongtothon: {
method: "End of edge type",
style: 'shape=box, penwidth=1.5 fillcolor="#D1E4DD"'
},
Yeutohotro: {
method: "End of edge type",
style: 'shape=note fillcolor="#D1D1E4"'
},
Thamkhao: {
method: "End of edge type",
style: "shape=plain fillcolor=white"
},
Hanhdong: {
method: "End of edge type",
style: 'fillcolor="#E4D1D1" shape=polygon'
},
branch_1a: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "1a Megan c\u1EA3m th\u1EA5y qu\u1EA3 th\u1EF1c vi\u1EC7c n\xF3i chuy\u1EC7n v\u1EDBi Cueball s\u1EBD \u0111em l\u1EA1i \u0111i\u1EC1u m\xE0 m\xECnh lu\xF4n mong m\u1ECFi"\ncolor="#D1E4DD"\nstyle="filled, rounded"'
},
branch_1b: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "1b Megan c\u1EA3m th\u1EA5y nh\u1EEFng ng\u01B0\u1EDDi xung quanh c\xF4 c\u1EA3m th\u1EA5y c\xF4 n\xEAn tr\xF2 chuy\u1EC7n v\u1EDBi Cuball"\ncolor="#D1DFE4"\nstyle="filled, rounded"'
},
branch_i: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "i Megan d\xE1m n\xF3i r\u1EB1ng \\"t\xF4i s\u1EBD kh\xF4ng \u0111\u1EC3 n\u1ED7i s\u1EE3 chi ph\u1ED1i m\xECnh\\""'
},
branch_j: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "j Megan s\u1EBD kh\xF4ng d\u1EF1a v\xE0o c\u1EA3m x\xFAc \u0111\u1EC3 bi\u1EC7n minh cho h\xE0nh \u0111\u1ED9ng c\u1EE7a m\xECnh"'
},
branch_k: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "k Megan nghe \u0111\u01B0\u1EE3c c\xE1c c\xE2u chuy\u1EC7n c\u1EE7a nh\u1EEFng ng\u01B0\u1EDDi t\u01B0\u01A1ng t\u1EF1 ho\xE0n c\u1EA3nh c\u1EE7a m\xECnh"'
},
branch_l: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "l Megan mu\u1ED1n \u0111\u1EB7t c\xE2u h\u1ECFi v\u1EC1 t\u1EA5t c\u1EA3 nh\u1EEFng g\xEC m\xECnh ngh\u0129"'
},
branch_m: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "m Nh\u1EEFng Megan trong friendlist QC s\u1EBD l\xE0m \u0111i\u1EC1u t\u01B0\u01A1ng t\u1EF1"'
},
branch_n: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "n T\u1ED5 ch\u1EE9c th\xE0nh c\xF4ng cu\u1ED9c \u0111\u1ED1i tho\u1EA1i gi\u1EEFa nh\u1EEFng ng\u01B0\u1EDDi kh\xE1c bi\u1EC7t quan \u0111i\u1EC3m"'
},
branch_o: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "o T\u1ED5 ch\u1EE9c th\xE0nh c\xF4ng nh\u1EEFng bu\u1ED5i chia s\u1EBB v\xF2ng tr\xF2n"'
},
branch_p: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "p T\u1ED5 ch\u1EE9c th\xE0nh c\xF4ng c\xE1c bu\u1ED5i n\xF3i chuy\u1EC7n c\u1EE7a ng\u01B0\u1EDDi c\xF3 chuy\xEAn m\xF4n"'
},
branch_q: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "q C\xE1c ch\u1EE7 doanh nghi\u1EC7p \u0111\u1ED3ng \xFD h\u1ED7 tr\u1EE3 nh\xE2n vi\xEAn"'
},
branch_r: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "r C\u1ED9ng \u0111\u1ED3ng b\u1EA1n b\xE8 QC ph\xE1t tri\u1EC3n"'
},
branch_s: {
method: "Index",
cluster: true,
subgraphSetting: 'label = "s K\u1EBFt h\u1EE3p \u0111\u01B0\u1EE3c v\u1EDBi c\xE1c d\u1EF1 \xE1n kh\xE1c"'
}
};
const edgeTypeListDeclaration = {
masterGraph: {
style: "penwidth=1"
},
Giaiphap: {},
Dichung: {
pairing: true,
style: "minlen=0 style=bold penwidth=5 dir=both arrowtype=odiamond"
},
Ytuongtothon: {},
Yeutohotro: {},
Thamkhao: {
style: "style=dashed "
},
Hanhdong: {}
};
const nodeTypeList = Object.keys(nodeTypeListDeclaration);
const edgeTypeList = Object.keys(edgeTypeListDeclaration);
var IsBreadcrumbsrunning = new Promise((resolve, reject) => {
if (bcEdgeList.length !== 0) {
resolve("Breadcrumbs is running properly");
} else {
reject("Breadcrumbs has problem");
}
});
IsBreadcrumbsrunning.then((message) => console.log(message)).catch((message) => console.log(message));
function makeLabel(name) {
return name.replace(/(?![^\n]{1,32}$)([^\n]{1,32})\s/g, "$1\\n").replace(/[❝❞]/g, '\\"');
}
function IndividualNodeType(nodetype, i2) {
this.settings = nodeTypeListDeclaration[nodetype];
this.settings.order = i2;
this.nodes = [];
this.neighborNode = {
sourceOf: [],
targetOf: []
};
}
function IndividualNode(name, nodetype) {
this.name = name;
this.label = makeLabel(this.name);
this.index = this.name.split(" ")[0];
this.path = this.name + ".md";
this.folder = this.path.split("/").slice(0, -1).join("/");
this.tag = "none";
this.frontmatter = "none";
this.inMetadata = false;
this.endOfEdgeType = nodetype;
this.neighbor = {
sourceOf: bcEdgeList.filter((edge) => edge.source == this.name).map((edge) => edge.target),
targetOf: bcEdgeList.filter((edge) => edge.target == this.name).map((edge) => edge.source)
};
this.existsInMetadata = function() {
if (Object.keys(app.metadataCache.fileCache).includes(this.path)) {
this.inMetadata = true;
var nodeMetadata = app.metadataCache.getCache(this.path);
if (nodeMetadata.frontmatter !== void 0) {
this.frontmatter = nodeMetadata.frontmatter;
}
if (nodeMetadata.tags !== void 0) {
this.tag = nodeMetadata.tags;
}
}
};
}
function createNodeTmp(item, nodetype, nodeTypeTmp) {
const nodeTmp = new IndividualNode(item.target, nodetype);
nodeTmp.existsInMetadata();
nodeTypeTmp.nodes.push(nodeTmp);
}
let i = 0;
nodeTypeList.forEach((nodetype) => {
const method = nodeTypeListDeclaration[nodetype].method;
const nodeTypeTmp = new IndividualNodeType(nodetype, i);
bcEdgeList.forEach((item) => {
if (method == "End of edge type") {
if (item.attributes.field == nodetype) {
createNodeTmp(item, nodetype, nodeTypeTmp);
}
}
if (method == "Index") {
var branchIndex = nodetype.split("_")[nodetype.split("_").length - 1];
var itemIndex = item.target.split(" ")[0];
var itemBranchIndex = itemIndex.split("-")[0].split(".")[0];
if (itemBranchIndex == branchIndex || itemBranchIndex + "+" == branchIndex) {
createNodeTmp(item, nodetype, nodeTypeTmp);
}
}
});
nodeData[nodetype] = nodeTypeTmp;
i++;
});
nodeTypeList.forEach((nodetype) => {
var tmpTarget = [];
var tmpSource = [];
nodeData[nodetype].nodes.forEach((node) => {
tmpTarget = tmpTarget.concat(node.neighbor.targetOf);
tmpSource = tmpSource.concat(node.neighbor.sourceOf);
});
nodeData[nodetype].neighborNode.targetOf = [...new Set(tmpTarget)];
nodeData[nodetype].neighborNode.sourceOf = [...new Set(tmpSource)];
});
function IndividualEdgeType() {
this.settings = "";
this.edges = [];
}
function IndividualEdge(start, dir, end, id) {
this.start = start;
this.end = end;
this.id = id;
}
const edgeTypeNoDeclare = new IndividualEdgeType();
edgeTypeNoDeclare.type = "This link field in Breadcrumbs plugin isn't declared in Hierarchical Graph plugin";
let j = 0;
edgeTypeList.forEach((edgetype) => {
const edgeTypeTmp = new IndividualEdgeType();
edgeTypeTmp.settings = edgeTypeListDeclaration[edgetype];
edgeTypeTmp.settings.order = j;
bcEdgeList.forEach((edge) => {
var bcEdgeField = edge.attributes.field;
const edgeTmp = new IndividualEdge();
edgeTmp.start = edge.source;
edgeTmp.end = edge.target;
edgeTmp.id = edge.key;
if (bcEdgeField == edgetype) {
edgeTypeTmp.edges.push(edgeTmp);
} else if (!edgeTypeList.includes(bcEdgeField)) {
edgeTypeNoDeclare.edges.push(edgeTmp);
}
});
edgeData[edgetype] = edgeTypeTmp;
j++;
});
edgeData["No Declared"] = edgeTypeNoDeclare;
function addNodesForEachGraph(graph, nodetype, node) {
const neighborNode = nodeData[graph].neighborNode;
if (graph == "masterGraph") {
graphDot.masterGraph.nodeSection += `"${node.name}" [ label = "${node.label}" ]
`;
}
if (graph !== "masterGraph" && nodetype == graph) {
graphDot[graph].nodeSection += `"${node.name}" [ label = "${node.label}" ]
`;
}
if (graph !== "masterGraph" && nodetype !== graph && (neighborNode.sourceOf.includes(node.name) || neighborNode.targetOf.includes(node.name))) {
graphDot[graph].nodeSection += `"${node.name}" [ label = "${node.label}" ]
`;
}
}
function addPairingEdgesForEachGraph(graph, edgetype, edge, k2, style) {
if (graph == "masterGraph") {
graphDot.masterGraph.edgeSection += `
subgraph cluster_${edgetype}_${k2}{
rank=same
edge [ ${style} ]
"${edge.start}" -> "${edge.end}"
}`;
}
if (graph != "masterGraph" && edgetype == graph) {
graphDot[graph].edgeSection += `
subgraph cluster_${edgetype}_${k2}{
rank=same
edge [ ${style} ]
"${edge.start}" -> "${edge.end}"
}`;
}
k2++;
}
function addNonPairingEdgesForEachGraph(graph, edgetype, edge) {
if (graph == "masterGraph") {
graphDot.masterGraph.edgeSection += `"${edge.start}" -> "${edge.end}"
`;
}
function checkNodeRelationToCurrentGraph(edgetype2, edge2, graph2) {
var a = nodeData[graph2].nodes.filter((node) => node.name == edge2.start || node.name == edge2.end);
if (a.length != 0) {
return true;
}
}
if (graph !== "masterGraph" && checkNodeRelationToCurrentGraph(edgetype, edge, graph)) {
graphDot[graph].edgeSection += `"${edge.start}" -> "${edge.end}"
`;
}
}
for (const graph in nodeTypeListDeclaration) {
graphDot[graph] = {
nodeSection: "",
edgeSection: "",
final: ""
};
graphDot[graph].nodeSection = `//NODES
//====================
`;
nodeTypeList.forEach((nodetype) => {
const style = nodeData[nodetype].settings.style;
const cluster = nodeData[nodetype].settings.cluster;
const subgraphSetting = nodeData[nodetype].settings.subgraphSetting;
graphDot[graph].nodeSection += `
node [ ${nodeData.masterGraph.settings.style} ] //Reset style
`;
graphDot[graph].nodeSection += `//All ${nodetype} nodes
`;
if (cluster == true) {
graphDot[graph].nodeSection += `subgraph cluster_${nodetype}{
${subgraphSetting}
`;
}
if (style !== void 0) {
graphDot[graph].nodeSection += `
node [ ${style} ]
`;
}
nodeData[nodetype].nodes.forEach((node) => addNodesForEachGraph(graph, nodetype, node));
if (cluster == true) {
graphDot[graph].nodeSection += `}
`;
}
});
graphDot[graph].edgeSection = `
//EDGES
//====================
`;
var k = 0;
edgeTypeList.forEach((edgetype) => {
const sameRank = edgeData[edgetype].settings.sameRank;
const cluster = edgeData[edgetype].settings.cluster;
const style = edgeData[edgetype].settings.style;
const pairing = edgeData[edgetype].settings.pairing;
if (edgeData.masterGraph.settings.style !== void 0) {
graphDot[graph].edgeSection += `
edge [ ${edgeData.masterGraph.settings.style} ] //Reset style
`;
}
graphDot[graph].edgeSection += `
//All ${edgetype} edges
`;
if (pairing == true) {
edgeData[edgetype].edges.forEach((edge) => {
addPairingEdgesForEachGraph(graph, edgetype, edge, k, style);
k++;
});
} else {
if (cluster == true && sameRank == true) {
graphDot[graph].edgeSection += `subgraph cluster_${edgetype}{
rank=same
`;
}
if (cluster == true && sameRank !== true) {
graphDot[graph].edgeSection += `subgraph cluster_${edgetype}{
`;
}
if (cluster !== true && sameRank == true) {
graphDot[graph].edgeSection += `subgraph {
rank=same
`;
}
if (style !== void 0) {
graphDot[graph].edgeSection += `
edge [ ${style} ]
`;
}
edgeData[edgetype].edges.forEach((edge) => {
addNonPairingEdgesForEachGraph(graph, edgetype, edge);
});
if (cluster == true || sameRank == true) {
graphDot[graph].edgeSection += `}
`;
}
}
});
graphDot[graph].edgeSection += `
}`;
graphDot[graph].final = `digraph ${graph}{
${nodeData.masterGraph.settings.graphHeader}
`;
graphDot[graph].final += graphDot[graph].nodeSection + graphDot[graph].edgeSection;
const commandList = [
`unflatten -l 3 ${graph}.dot -o unflatten_${graph}.dot`,
`dot -Tpng unflatten_${graph}.dot -o dot_${graph}.png`
];
var filePath = app.vault.configDir + "\\plugins\\dotmaker\\graphs\\" + graph + ".dot";
app.vault.adapter.write(filePath, graphDot[graph].final);
commandList.forEach((command) => exec(command, (error, stdout, stderr) => {
console.log("filePath:", filePath);
console.log(graph, command);
console.log("stdout:", stdout);
console.log("stderr:", stderr);
if (error !== null) {
console.log(`exec error: ${error}`);
}
}));
}
debug();
console.log("done");
});
}
onunload() {
console.log("unloading plugin");
}
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vR2l0SHViL09ic2lkaWFuL2RvdG1ha2VyL21haW4udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qIE5hbWluZyBjb252ZW50aW9uXHJcbmJjIHByZWZpeDogQnJlYWRjcnVtYnNcclxuTm8gcHJlZml4OiBIaWVyYXJjaGljYWwgR3JhcGhcclxuYWxsbG93ZXJjYXNlOiBpdGVyYXRpb24gaXRlbSBvZiBhbiBhcnJheS5mb3JFYWNoKClcclxufCAgICAgICAgICAgICAgICAgICB8IEJyZWFkY3J1bWJzICAgICAgICB8IEhpZXJhcmNoaWNhbCBncmFwaCB8XHJcbnwtLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tfFxyXG58IFJlbGF0aW9uc2hpcCAgICAgIHwgTGluayAgICAgICAgICAgICAgIHwgRWRnZSAgICAgICAgICAgICAgIHxcclxufCBSZWxhdGlvbnNoaXAgdHlwZSB8IExpbmsgZmllbGQgICAgICAgICB8IEVkZ2UgdHlwZSAgICAgICAgICB8XHJcbnwgTm9kZSAgICAgICAgICAgICAgfCBTb3VyY2UvdGFyZ2V0IG5vZGUgfCBTdGFydC9lbmQgbm9kZSAgICAgfFxyXG4qL1xyXG5pbXBvcnQgeyBQbHVnaW4gfSBmcm9tICdvYnNpZGlhbic7XHJcbmNvbnN0IHsgZXhlYyB9ID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpO1xyXG5cclxudmFyIG5vZGVEYXRhID0ge30gXHJcbnZhciBlZGdlRGF0YSA9IHt9XHJcbmNvbnN0IGdyYXBoRG90ID0ge30gICAgXHJcblxyXG5jb25zdCBiY05vZGVMaXN0ID0gYXBwLnBsdWdpbnMucGx1Z2lucy5icmVhZGNydW1icy5tYWluRy50b0pTT04oKS5ub2RlcyAvL1RoZSBvYmplY3Qgc3RydWN0dXJlIGluIHRoZSBCcmVhZGNydW1icyBub2RlIGxpc3QgaXNcclxuY29uc3QgYmNFZGdlTGlzdCA9IGFwcC5wbHVnaW5zLnBsdWdpbnMuYnJlYWRjcnVtYnMubWFpbkcudG9KU09OKCkuZWRnZXMgLy9kaWZmZXJlbnQgdG8gdGhlIG9iamVjdCBzdHJ1Y3R1cmUgaW4gdGhlIGVkZ2UgbGlzdFxyXG5mdW5jdGlvbiBkZWJ1ZygpIHtcclxuXHRjb25zb2xlLmxvZyhcIm5vZGVEYXRhXCIsIG5vZGVEYXRhKVxyXG5cdGNvbnNvbGUubG9nKFwiZWRnZURhdGFcIiwgZWRnZURhdGEpXHJcblx0Y29uc29sZS5sb2coXCJncmFwaERvdFwiLCBncmFwaERvdClcclxuXHRjb25zb2xlLmxvZyhcInByb2Nlc3MuY3dkKClcIiwgcHJvY2Vzcy5jd2QoKSlcclxufSBcclxuY29uc3Qgd29ya2luZ0RpcmVjdG9yeSA9IGFwcC52YXVsdC5hZGFwdGVyLmdldEJhc2VQYXRoKCkgKyBcIlxcXFxcIiArIGFwcC52YXVsdC5jb25maWdEaXIgKyBcIlxcXFxwbHVnaW5zXFxcXGRvdG1ha2VyXFxcXGdyYXBoc1xcXFxcIiBcclxuY29uc29sZS5sb2coJ1N0YXJ0aW5nIGRpcmVjdG9yeTogJyArIHByb2Nlc3MuY3dkKCkpO1xyXG50cnkge1xyXG5cdHByb2Nlc3MuY2hkaXIod29ya2luZ0RpcmVjdG9yeSk7XHJcblx0Y29uc29sZS5sb2coJ05ldyBkaXJlY3Rvcnk6ICcgKyBwcm9jZXNzLmN3ZCgpKTtcclxufVxyXG5jYXRjaCAoZXJyKSB7XHJcblx0Y29uc29sZS5sb2coJ2NoZGlyOiAnICsgZXJyKTtcclxufVxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNeVBsdWdpbiBleHRlbmRzIFBsdWdpbiB7XHJcblx0YXN5bmMgb25sb2FkKCkge1xyXG5cdFx0XHJcbmNvbnNvbGUuY2xlYXIoKVxyXG4vKiBQYXJ0IDE6IEluaXRpYWwgZGF0YSAqL1xyXG5cclxuY29uc3Qgbm9kZVR5cGVMaXN0RGVjbGFyYXRpb24gPSB7IC8vU3R5bGVzIHVzZWQgaW4gZmluYWwgZ3JhcGggZm9yIGVhY2ggbm9kZSB0eXBlXHJcblx0bWFzdGVyR3JhcGg6IHsgXHJcblx0XHRzdHlsZTogXCJzaGFwZT1wbGFpbnRleHQgc3R5bGU9XFxcImZpbGxlZCwgcm91bmRlZFxcXCIgZm9udG5hbWU9XFxcIkxhdG9cXFwiIG1hcmdpbj0wLjIgZmlsbGNvbG9yPVxcXCIjYzZjYWMzXFxcIlwiLFxyXG5cdFx0Z3JhcGhIZWFkZXI6IFxyXG5cdFx0YC8vc3BsaW5lcz1vcnRobztcclxuXHRcdG92ZXJsYXA9ZmFsc2VcclxuXHRcdHN0eWxlPXJvdW5kZWRcclxuXHRcdC8vIHJhbmtzZXA9XCIwLjRcIjtcclxuXHRcdGxhYmVsPVwiVGhheSBcdTAxMTFcdTFFRDVpIG5pXHUxRUMxbSB0aW4gbmdcdTAxQjBcdTFFRERpIGNcdTAwRjMgbmlcdTFFQzFtIHRpbiB0aVx1MDBFQXUgY1x1MUVGMWNcIjtcclxuXHRcdHNlcD0xMFxyXG5cdFx0Zm9udHNpemUgPSAzMFxyXG5cdFx0bGFiZWxsb2M9XCJ0XCI7XHJcblx0XHRmb250bmFtZT1cIkxhdG9cIjtgLFxyXG5cdH0sXHJcblx0R2lhaXBoYXA6IHsgXHJcblx0XHRtZXRob2Q6IFwiRW5kIG9mIGVkZ2UgdHlwZVwiLFxyXG5cdH0sXHJcblx0WXR1b25ndG90aG9uOiB7XHJcblx0XHRtZXRob2Q6IFwiRW5kIG9mIGVkZ2UgdHlwZVwiLCAgLy9FbmQgb2YgZWRnZSB0eXBlIChlbmQgb2YgQnJlYWRjcnVtYnMgZmllbGQpLCBpbmRleCwgdGFnLCBmcm9udG1hdHRlciwgXHJcblx0XHRzdHlsZTogXCJzaGFwZT1ib3gsIHBlbndpZHRoPTEuNSBmaWxsY29sb3I9XFxcIiNEMUU0RERcXFwiXCIsIC8vZ3JlZW5cclxuXHR9LFxyXG5cdFlldXRvaG90cm86IHtcclxuXHRcdG1ldGhvZDogXCJFbmQgb2YgZWRnZSB0eXBlXCIsXHJcblx0XHRzdHlsZTogXCJzaGFwZT1ub3RlIGZpbGxjb2xvcj1cXFwiI0QxRDFFNFxcXCJcIiwgLy9wdXJwbGVcclxuXHR9LFxyXG5cdFRoYW1raGFvOiB7XHJcblx0XHRtZXRob2Q6IFwiRW5kIG9mIGVkZ2UgdHlwZVwiLFxyXG5cdFx0c3R5bGU6IFwic2hhcGU9cGxhaW4gZmlsbGNvbG9yPXdoaXRlXCIsXHJcblx0fSxcclxuXHRIYW5oZG9uZzoge1xyXG5cdFx0bWV0aG9kOiBcIkVuZCBvZiBlZGdlIHR5cGVcIixcclxuXHRcdHN0eWxlOiBcImZpbGxjb2xvcj1cXFwiI0U0RDFEMVxcXCIgc2hhcGU9cG9seWdvblwiXHJcblx0fSxcclxuXHRicmFuY2hfMWE6IHtcclxuXHRcdG1ldGhvZDogXCJJbmRleFwiLFxyXG5cdFx0Y2x1c3RlcjogdHJ1ZSxcclxuXHRcdHN1YmdyYXBoU2V0dGluZzogXCJsYWJlbCA9IFxcXCIxYSBNZWdhbiBjXHUxRUEzbSB0aFx1MUVBNXkgcXVcdTFFQTMgdGhcdTFFRjFjIHZpXHUxRUM3YyBuXHUwMEYzaSBjaHV5XHUxRUM3biB2XHUxRURCaSBDdWViYWxsIHNcdTFFQkQgXHUwMTExZW0gbFx1MUVBMWkgXHUwMTExaVx1MUVDMXUgbVx1MDBFMCBtXHUwMEVDbmggbHVcdTAwRjRuIG1vbmcgbVx1MUVDRmlcXFwiXFxuY29sb3I9XFxcIiNEMUU0RERcXFwiXFxuc3R5bGU9XFxcImZpbGxlZCwgcm91bmRlZFxcXCJcIlxyXG5cdH0sXHJcblx0YnJhbmNoXzFiOiB7IFxyXG5cdFx0bWV0aG9kOiBcIkluZGV4XCIsXHJcblx0XHRjbHVzdGVyOiB0cnVlLFxyXG5cdFx0c3ViZ3JhcGhTZXR0aW5nOiBcImxhYmVsID0gXFxcIjFiIE1lZ2FuIGNcdTFFQTNtIHRoXHUxRUE1eSBuaFx1MUVFRm5nIG5nXHUwMUIwXHUxRUREaSB4dW5nIHF1YW5oIGNcdTAwRjQgY1x1MUVBM20gdGhcdTFFQTV5IGNcdTAwRjQgblx1MDBFQW4gdHJcdTAwRjIgY2h1eVx1MUVDN24gdlx1MUVEQmkgQ3ViYWxsXFxcIlxcbmNvbG9yPVxcXCIjRDFERkU0XFxcIlxcbnN0eWxlPVxcXCJmaWxsZWQsIHJvdW5kZWRcXFwiXCJcclxuXHR9LFxyXG5cdGJyYW5jaF9pOiB7XHJcblx0XHRtZXRob2Q6IFwiSW5kZXhcIixcclxuXHRcdGNsdXN0ZXI6IHRydWUsXHJcblx0XHRzdWJncmFwaFNldHRpbmc6IFwibGFiZWwgPSBcXFwiaSBNZWdhbiBkXHUwMEUxbSBuXHUwMEYzaSByXHUxRUIxbmcgXFxcXFxcXCJ0XHUwMEY0aSBzXHUxRUJEIGtoXHUwMEY0bmcgXHUwMTExXHUxRUMzIG5cdTFFRDdpIHNcdTFFRTMgY2hpIHBoXHUxRUQxaSBtXHUwMEVDbmhcXFxcXFxcIlxcXCJcIixcclxuXHR9LFxyXG5cdGJyYW5jaF9qOiB7XHJcblx0XHRtZXRob2Q6IFwiSW5kZXhcIixcclxuXHRcdGNsdXN0ZXI6IHRydWUsXHJcblx0XHRzdWJncmFwaFNldHRpbmc6IFwibGFiZWwgPSBcXFwiaiBNZWdhbiBzXHUxRUJEIGtoXHUwMEY0bmcgZFx1MUVGMWEgdlx1MDBFMG8gY1x1MUVBM20geFx1MDBGQWMgXHUwMTExXHUxRUMzIGJpXHUxRUM3biBtaW5oIGNobyBoXHUwMEUwbmggXHUwMTExXHUxRUQ5bmcgY1x1MUVFN2EgbVx1MDBFQ25oXFxcIlwiLFxyXG5cdH0sXHJcblx0YnJhbmNoX2s6IHtcclxuXHRcdG1ldGhvZDogXCJJbmRleFwiLFxyXG5cdFx0Y2x1c3RlcjogdHJ1ZSxcclxuXHRcdHN1YmdyYXBoU2V0dGluZzogXCJsYWJlbCA9IFxcXCJrIE1lZ2FuIG5naGUgXHUwMTExXHUwMUIwXHUxRUUzYyBjXHUwMEUxYyBjXHUwMEUydSBjaHV5XHUxRUM3biBjXHUxRUU3YSBuaFx1MUVFRm5nIG5nXHUwMUIwXHUxRUREaSB0XHUwMUIwXHUwMUExbmcgdFx1MUVGMSBob1x1MDBFMG4gY1x1MUVBM25oIGNcdTFFRTdhIG1cdTAwRUNuaFxcXCJcIixcclxuXHR9LFxyXG5cdGJyYW5jaF9sOiB7XHJcblx0XHRtZXRob2Q6IFwiSW5kZXhcIixcclxuXHRcdGNsdXN0ZXI6IHRydWUsXHJcblx0XHRzdWJncmFwaFNldHRpbmc6IFwibGFiZWwgPSBcXFwibCBNZWdhbiBtdVx1MUVEMW4gXHUwMTExXHUxRUI3dCBjXHUwMEUydSBoXHUxRUNGaSB2XHUxRUMxIHRcdTFFQTV0IGNcdTFFQTMgbmhcdTFFRUZuZyBnXHUwMEVDIG1cdTAwRUNuaCBuZ2hcdTAxMjlcXFwiXCIsXHJcblx0fSxcclxuXHRicmFuY2hfbToge1xyXG5cdFx0bWV0aG9kOiBcIkluZGV4XCIsXHJcblx0XHRjbHVzdGVyOiB0cnVlLFxyXG5cdFx0c3ViZ3JhcGhTZXR0aW5nOiBcImxhYmVsID0gXFxcIm0gTmhcdTFFRUZuZyBNZWdhbiB0cm9uZyBmcmllbmRsaXN0IFFDIHNcdTFFQkQgbFx1MDBFMG0gXHUwMTExaVx1MUVDMXUgdFx1MDFCMFx1MDFBMW5nIHRcdTFFRjFcXFwiXCIsXHJcblx0XHRcclxuXHR9LFxyXG5cdGJyYW5jaF9uOiB7XHJcblx0XHRtZXRob2Q6IFwiSW5kZXhcIixcclxuXHRcdGNsdXN0ZXI6IHRydWUsXHJcblx0XHRzdWJncmFwaFNldHRpbmc6IFwibGFiZWwgPSBcXFwibiBUXHUxRUQ1IGNoXHUxRUU5YyB0aFx1MDBFMG5oIGNcdTAwRjRuZyBjdVx1MUVEOWMgXHUwMTExXHUxRUQxaSB0aG9cdTFFQTFpIGdpXHUxRUVGYSBuaFx1MUVFRm5nIG5nXHUwMUIwXHUxRUREaSBraFx1MDBFMWMgYmlcdTFFQzd0IHF1YW4gXHUwMTExaVx1MUVDM21cXFwiXCIsXHJcblx0fSxcclxuXHRicmFuY2hfbzoge1xyXG5cdFx0bWV0aG9kOiBcIkluZGV4XCIsXHJcblx0XHRjbHVzdGVyOiB0cnVlLFxyXG5cdFx0c3ViZ3JhcGhTZXR0aW5nOiBcImxhYmVsID0gXFxcIm8gVFx1MUVENSBjaFx1MUVFOWMgdGhcdTAwRTBuaCBjXHUwMEY0bmcgbmhcdTFFRUZuZyBidVx1MUVENWkgY2hpYSBzXHUxRUJCIHZcdTAwRjJuZyB0clx1MDBGMm5cXFwiXCIsXHJcblx0fSxcclxuXHRicmFuY2hfcDoge1xyXG5cdFx0bWV0aG9kOiBcIkluZGV4XCIsXHJcblx0XHRjbHVzdGVyOiB0cnVlLFxyXG5cdFx0c3ViZ3JhcGhTZXR0aW5nOiBcImxhYmVsID0gXFxcInAgVFx1MUVENSBjaFx1MUVFOWMgdGhcdTAwRTBuaCBjXHUwMEY0bmcgY1x1MDBFMWMgYnVcdTFFRDVpIG5cdTAwRjNpIGNodXlcdTFFQzduIGNcdTFFRTdhIG5nXHUwMUIwXHUxRUREaSBjXHUwMEYzIGNodXlcdTAwRUFuIG1cdTAwRjRuXFxcIlwiLFxyXG5cdH0sXHJcblx0YnJhbmNoX3E6IHtcclxuXHRcdG1ldGhvZDogXCJJbmRleFwiLFxyXG5cdFx0Y2x1c3RlcjogdHJ1ZSxcclxuXHRcdHN1YmdyYXBoU2V0dGluZzogXCJsYWJlbCA9IFxcXCJxIENcdTAwRTFjIGNoXHUxRUU3IGRvYW5oIG5naGlcdTFFQzdwIFx1MDExMVx1MUVEM25nIFx1MDBGRCBoXHUxRUQ3IHRyXHUxRUUzIG5oXHUwMEUybiB2aVx1MDBFQW5cXFwiXCIsXHJcblx0fSxcclxuXHRicmFuY2hfcjoge1xyXG5cdFx0bWV0aG9kOiBcIkluZGV4XCIsXHJcblx0XHRjbHVzdGVyOiB0cnVlLFxyXG5cdFx0c3ViZ3JhcGhTZXR0aW5nOiBcImxhYmVsID0gXFxcInIgQ1x1MUVEOW5nIFx1MDExMVx1MUVEM25nIGJcdTFFQTFuIGJcdTAwRTggUUMgcGhcdTAwRTF0IHRyaVx1MUVDM25cXFwiXCIsXHJcblx0fSxcclxuXHRicmFuY2hfczoge1xyXG5cdFx0bWV0aG9kOiBcIkluZGV4XCIsXHJcblx0XHRjbHVzdGVyOiB0cnVlLFxyXG5cdFx0c3ViZ3JhcGhTZXR0aW5nOiBcImxhYmVsID0gXFxcInMgS1x1MUVCRnQgaFx1MUVFM3AgXHUwMTExXHUwMUIwXHUxRUUzYyB2XHUxRURCaSBjXHUwMEUxYyBkXHUxRUYxIFx1MDBFMW4ga2hcdTAwRTFjXFxcIlwiLFxyXG5cdH0sXHJcbn1cclxuY29uc3QgZWRnZVR5cGVMaXN0RGVjbGFyYXRpb24gPSB7IC8vU3R5bGVzIHVzZWQgaW4gZmluYWwgZ3JhcGggZm9yIGVhY2ggZWRnZSB0eXBlXHJcblx0bWFzdGVyR3JhcGg6IHtcclxuXHRcdHN0eWxlOiBcInBlbndpZHRoPTFcIiBcclxuXHR9LFxyXG5cdEdpYWlwaGFwOiB7XHJcblx0fSxcclxuXHREaWNodW5nOiB7XHJcblx0XHRwYWlyaW5nOiB0cnVlLFxyXG5cdFx0c3R5bGU6IFwibWlubGVuPTAgc3R5bGU9Ym9sZCBwZW53aWR0aD01IGRpcj1ib3RoIGFycm93dHlwZT1vZGlhbW9uZFwiIFxyXG5cdH0sXHJcblx0WXR1b25ndG90aG9uOiB7XHJcblx0fSxcclxuXHRZZXV0b2hvdHJvOiB7XHJcblx0fSxcclxuXHRUaGFta2hhbzoge1xyXG5cdFx0c3R5bGU6IFwic3R5bGU9ZGFzaGVkIFwiIFxyXG5cdH0sXHJcblx0SGFuaGRvbmc6IHtcclxuXHR9IFxyXG59XHJcbmNvbnN0IG5vZGVUeXBlTGlzdCA9IE9iamVjdC5rZXlzKG5vZGVUeXBlTGlzdERlY2xhcmF0aW9uKVxyXG5jb25zdCBlZGdlVHlwZUxpc3QgPSBPYmplY3Qua2V5cyhlZGdlVHlwZUxpc3REZWNsYXJhdGlvbilcclxuXHJcbnZhciBJc0JyZWFkY3J1bWJzcnVubmluZyA9IG5ldyBQcm9taXNlKChyZXNvbHZlLHJlamVjdCkgPT4ge1xyXG5cdGlmKGJjRWRnZUxpc3QubGVuZ3RoICE9PSAwKXtcclxuXHRcdHJlc29sdmUoJ0JyZWFkY3J1bWJzIGlzIHJ1bm5pbmcgcHJvcGVybHknKSBcclxuXHR9IGVsc2Uge1xyXG5cdFx0cmVqZWN0KCdCcmVhZGNydW1icyBoYXMgcHJvYmxlbScpIFxyXG5cdH0gXHJcbn0pXHJcbklzQnJlYWRjcnVtYnNydW5uaW5nLnRoZW4obWVzc2FnZSA9PiBjb25zb2xlLmxvZyhtZXNzYWdlKSlcclxuLmNhdGNoKG1lc3NhZ2UgPT4gY29uc29sZS5sb2cobWVzc2FnZSkpXHJcblxyXG5cclxuLyogUGFydCAyOiBSZXN0cnVjdHVyaW5nIHRoZSBCcmVhZGNydW1icyBkYXRhYmFzZTsgY3JlYXRpbmcgYmV0dGVyIHN1aXRlZCBkYXRhYmFzZSBmb3IgdGhlIGdvYWwgKi9cclxuLyogUGFydCAyLjE6IEJ1bGRpbmcgbm9kZSBvYmplY3QgKi9cclxuZnVuY3Rpb24gbWFrZUxhYmVsKG5hbWUpeyBcclxuXHRyZXR1cm4gbmFtZS5yZXBsYWNlKC8oPyFbXlxcbl17MSwzMn0kKShbXlxcbl17MSwzMn0pXFxzL2csICckMVxcXFxuJykucmVwbGFjZSgvW1x1Mjc1RFx1Mjc1RV0vZywnXFxcXFwiJylcclxufSBcclxuZnVuY3Rpb24gSW5kaXZpZHVhbE5vZGVUeXBlKG5vZGV0eXBlOiBzdHJpbmcsIGk6IG51bWJlcil7XHJcblx0dGhpcy5zZXR0aW5ncyA9IG5vZGVUeXBlTGlzdERlY2xhcmF0aW9uW25vZGV0eXBlXVxyXG5cdHRoaXMuc2V0dGluZ3Mub3JkZXIgPSBpXHJcblx0dGhpcy5ub2RlcyA9IFtdXHJcblx0dGhpcy5uZWlnaGJvck5vZGUgPSB7XHJcblx0XHRzb3VyY2VPZjogW10gLFxyXG5cdFx0dGFyZ2V0T2Y6IFtdfSBcclxufVxyXG5mdW5jdGlvbiBJbmRpdmlkdWFsTm9kZSAoIG5hbWU6IHN0cmluZywgbm9kZXR5cGU6IHN0cmluZykge1xyXG5cdHRoaXMubmFtZSA9IG5hbWVcclxuXHR0aGlzLmxhYmVsID0gbWFrZUxhYmVsKHRoaXMubmFtZSlcclxuXHR0aGlzLmluZGV4ID0gdGhpcy5uYW1lLnNwbGl0KFwiIFwiKVswXVxyXG5cdHRoaXMucGF0aCA9IHRoaXMubmFtZStcIi5tZFwiXHJcblx0dGhpcy5mb2xkZXIgPSB0aGlzLnBhdGguc3BsaXQoXCIvXCIpLnNsaWNlKDAsIC0xKS5qb2luKCcvJylcclxuXHR0aGlzLnRhZyA9IFwibm9uZVwiXHJcblx0dGhpcy5mcm9udG1hdHRlciA9IFwibm9uZVwiXHJcblx0dGhpcy5pbk1ldGFkYXRhID0gZmFsc2VcclxuXHR0aGlzLmVuZE9mRWRnZVR5cGUgPSBub2RldHlwZVxyXG5cdHRoaXMubmVpZ2hib3IgPSB7IFxyXG5cdFx0c291cmNlT2Y6IGJjRWRnZUxpc3QuZmlsdGVyKGVkZ2UgPT4gZWRnZS5zb3VyY2U9PXRoaXMubmFtZSkubWFwKGVkZ2UgPT4gZWRnZS50YXJnZXQpLFxyXG5cdFx0dGFyZ2V0T2Y6IGJjRWRnZUxpc3QuZmlsdGVyKGVkZ2UgPT4gZWRnZS50YXJnZXQ9PXRoaXMubmFtZSkubWFwKGVkZ2UgPT4gZWRnZS5zb3VyY2UpfSBcclxuXHRcclxuXHR0aGlzLmV4aXN0c0luTWV0YWRhdGEgPSBmdW5jdGlvbigpIHtcclxuXHRcdGlmIChPYmplY3Qua2V5cyhhcHAubWV0YWRhdGFDYWNoZS5maWxlQ2FjaGUpLmluY2x1ZGVzKHRoaXMucGF0aCkpeyBcclxuXHRcdFx0dGhpcy5pbk1ldGFkYXRhID0gdHJ1ZVxyXG5cdFx0XHR2YXIgbm9kZU1ldGFkYXRhID0gYXBwLm1ldGFkYXRhQ2FjaGUuZ2V0Q2FjaGUodGhpcy5wYXRoKVxyXG5cdFx0XHRpZiAobm9kZU1ldGFkYXRhLmZyb250bWF0dGVyICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0XHR0aGlzLmZyb250bWF0dGVyID0gbm9kZU1ldGFkYXRhLmZyb250bWF0dGVyXHJcblx0XHRcdH0gXHJcblx0XHRcdGlmIChub2RlTWV0YWRhdGEudGFncyAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdFx0dGhpcy50YWcgPSBub2RlTWV0YWRhdGEudGFnc1xyXG5cdFx0XHR9IFxyXG5cdFx0fVxyXG5cdH0gXHJcbn1cclxuZnVuY3Rpb24gY3JlYXRlTm9kZVRtcChpdGVtLCBub2RldHlwZSwgbm9kZVR5cGVUbXApe1xyXG5cdGNvbnN0IG5vZGVUbXAgPSBuZXcgSW5kaXZpZHVhbE5vZGUoaXRlbS50YXJnZXQsIG5vZGV0eXBlKSBcclxuXHRcdFx0XHJcblx0bm9kZVRtcC5leGlzdHNJbk1ldGFkYXRhKCkgXHJcblx0bm9kZVR5cGVUbXAubm9kZXMucHVzaChub2RlVG1wKSBcdFxyXG59IFxyXG5sZXQgaT0wXHJcbm5vZGVUeXBlTGlzdC5mb3JFYWNoKG5vZGV0eXBlID0+IHtcclxuXHRjb25zdCBtZXRob2QgPSBub2RlVHlwZUxpc3REZWNsYXJhdGlvbltub2RldHlwZV0ubWV0aG9kXHJcblx0Y29uc3Qgbm9kZVR5cGVUbXAgPSBuZXcgSW5kaXZpZHVhbE5vZGVUeXBlKG5vZGV0eXBlLCBpKSBcclxuXHJcblx0YmNFZGdlTGlzdC5mb3JFYWNoKGl0ZW0gPT4ge1xyXG5cdFx0aWYgKG1ldGhvZD09XCJFbmQgb2YgZWRnZSB0eXBlXCIpIHtcclxuXHRcdFx0aWYoaXRlbS5hdHRyaWJ1dGVzLmZpZWxkID09IG5vZGV0eXBlKSB7XHJcblx0XHRcdFx0Y3JlYXRlTm9kZVRtcChpdGVtLCBub2RldHlwZSwgbm9kZVR5cGVUbXApIFxyXG5cdFx0XHR9XHJcblx0XHR9IFxyXG5cdFx0aWYgKG1ldGhvZD09XCJJbmRleFwiKSB7XHJcblx0XHRcdHZhciBicmFuY2hJbmRleCA9IG5vZGV0eXBlLnNwbGl0KFwiX1wiKVtub2RldHlwZS5zcGxpdChcIl9cIikubGVuZ3RoIC0gMV0gXHJcblx0XHRcdHZhciBpdGVtSW5kZXggPSBpdGVtLnRhcmdldC5zcGxpdChcIiBcIilbMF1cclxuXHRcdFx0dmFyIGl0ZW1CcmFuY2hJbmRleCA9IGl0ZW1JbmRleC5zcGxpdChcIi1cIilbMF0uc3BsaXQoXCIuXCIpWzBdXHJcblx0XHRcdFxyXG5cdFx0XHRpZiAoaXRlbUJyYW5jaEluZGV4ID09IGJyYW5jaEluZGV4IHx8IGl0ZW1CcmFuY2hJbmRleCtcIitcIiA9PSBicmFuY2hJbmRleCkge1xyXG5cdFx0XHRcdGNyZWF0ZU5vZGVUbXAoaXRlbSwgbm9kZXR5cGUsIG5vZGVUeXBlVG1wKVxyXG5cdFx0XHR9IFxyXG5cdFx0fVxyXG5cdH0pXHJcblx0bm9kZURhdGFbbm9kZXR5cGVdID0gbm9kZVR5cGVUbXBcclxuXHRpKytcclxufSlcclxubm9kZVR5cGVMaXN0LmZvckVhY2gobm9kZXR5cGUgPT4ge1xyXG5cdHZhciB0bXBUYXJnZXQgPSBbXSBcclxuXHR2YXIgdG1wU291cmNlID0gW10gXHJcblx0bm9kZURhdGFbbm9kZXR5cGVdLm5vZGVzLmZvckVhY2gobm9kZT0+IHtcclxuXHRcdHRtcFRhcmdldCA9IHRtcFRhcmdldC5jb25jYXQobm9kZS5uZWlnaGJvci50YXJnZXRPZilcclxuXHRcdHRtcFNvdXJjZSA9IHRtcFNvdXJjZS5jb25jYXQobm9kZS5uZWlnaGJvci5zb3VyY2VPZilcclxuXHR9KVxyXG5cdG5vZGVEYXRhW25vZGV0eXBlXS5uZWlnaGJvck5vZGUudGFyZ2V0T2YgPSBbLi4ubmV3IFNldCh0bXBUYXJnZXQpXVxyXG5cdG5vZGVEYXRhW25vZGV0eXBlXS5uZWlnaGJvck5vZGUuc291cmNlT2YgPSBbLi4ubmV3IFNldCh0bXBTb3VyY2UpXVxyXG59KVxyXG5cclxuLyogUGFydCAyLjI6IEJ1bGRpbmcgZWRnZSBvYmplY3QgKi9cclxuZnVuY3Rpb24gSW5kaXZpZHVhbEVkZ2VUeXBlKCl7XHJcblx0dGhpcy5zZXR0aW5ncyA9IFwiXCIgXHJcblx0dGhpcy5lZGdlcyA9IFtdXHJcbn1cclxuZnVuY3Rpb24gSW5kaXZpZHVhbEVkZ2UgKHN0YXJ0OiBzdHJpbmcsIGRpcjogc3RyaW5nLCBlbmQ6IHN0cmluZywgaWQ6IHN0cmluZykge1xyXG5cdHRoaXMuc3RhcnQgPSBzdGFydFxyXG5cdHRoaXMuZW5kID0gZW5kXHJcblx0dGhpcy5pZCA9IGlkXHJcbn1cclxuY29uc3QgZWRnZVR5cGVOb0RlY2xhcmUgPSBuZXcgSW5kaXZpZHVhbEVkZ2VUeXBlKCkgXHJcbmVkZ2VUeXBlTm9EZWNsYXJlLnR5cGUgPSBcIlRoaXMgbGluayBmaWVsZCBpbiBCcmVhZGNydW1icyBwbHVnaW4gaXNuJ3QgZGVjbGFyZWQgaW4gSGllcmFyY2hpY2FsIEdyYXBoIHBsdWdpblwiIFxyXG5sZXQgaj0wXHJcblxyXG5lZGdlVHlwZUxpc3QuZm9yRWFjaChlZGdldHlwZSA9PiB7XHJcblx0Y29uc3QgZWRnZVR5cGVUbXAgPSBuZXcgSW5kaXZpZHVhbEVkZ2VUeXBlKCkgXHJcblx0ZWRnZVR5cGVUbXAuc2V0dGluZ3MgPSBlZGdlVHlwZUxpc3REZWNsYXJhdGlvbltlZGdldHlwZV1cclxuXHRlZGdlVHlwZVRtcC5zZXR0aW5ncy5vcmRlciA9IGpcclxuXHJcblx0YmNFZGdlTGlzdC5mb3JFYWNoKGVkZ2UgPT4ge1xyXG5cdFx0dmFyIGJjRWRnZUZpZWxkID0gZWRnZS5hdHRyaWJ1dGVzLmZpZWxkXHJcblx0XHRjb25zdCBlZGdlVG1wID0gbmV3IEluZGl2aWR1YWxFZGdlKCkgXHJcblx0XHRlZGdlVG1wLnN0YXJ0ID0gZWRnZS5zb3VyY2VcclxuXHRcdGVkZ2VUbXAuZW5kID0gZWRnZS50YXJnZXRcclxuXHRcdGVkZ2VUbXAuaWQgPSBlZGdlLmtleVxyXG5cdFx0aWYgKGJjRWRnZUZpZWxkID09IGVkZ2V0eXBlKSB7IFxyXG5cdFx0XHRlZGdlVHlwZVRtcC5lZGdlcy5wdXNoKGVkZ2VUbXApIFxyXG5cdFx0fSBcclxuXHRcdGVsc2UgaWYgKCFlZGdlVHlwZUxpc3QuaW5jbHVkZXMoYmNFZGdlRmllbGQpKSB7IFxyXG5cdFx0XHRlZGdlVHlwZU5vRGVjbGFyZS5lZGdlcy5wdXNoKGVkZ2VUbXApXHJcblx0XHR9XHJcblx0fSk7IC8vUnVuIHRocm91Z2ggYWxsIGVkZ2VzIGluIEJDIGVkZ2UgbGlzdCAoYmNFZGdlTGlzdCkgXHJcblx0ZWRnZURhdGFbZWRnZXR5cGVdID0gZWRnZVR5cGVUbXBcclxuXHRqKytcclxufSkgLy9SdW4gdGhyb3VnaCBhbGwgZWRnZSB0eXBlcyBpbiBIRyBlZGdlIHR5cGUgZGVjbGFyYXRpb24gKGVkZ2VUeXBlTGlzdClcclxuZWRnZURhdGFbXCJObyBEZWNsYXJlZFwiXSA9IGVkZ2VUeXBlTm9EZWNsYXJlXHJcblxyXG4vKiBQYXJ0IDM6IE1ha2luZyBkb3QgZmlsZSAqL1xyXG5cclxuXHJcbmZ1bmN0aW9uIGFkZE5vZGVzRm9yRWFjaEdyYXBoKGdyYXBoLG5vZGV0eXBlLG5vZGUpOiB2b2lkIHtcclxuXHRjb25zdCBuZWlnaGJvck5vZGUgPSBub2RlRGF0YVtncmFwaF0ubmVpZ2hib3JOb2RlXHJcblx0XHJcblx0aWYgKGdyYXBoID09IFwibWFzdGVyR3JhcGhcIikge1xyXG5cdFx0Z3JhcGhEb3QubWFzdGVyR3JhcGgubm9kZVNlY3Rpb24gKz0gYFwiJHtub2RlLm5hbWV9XCIgWyBsYWJlbCA9IFwiJHtub2RlLmxhYmVsfVwiIF0gXFxuYFxyXG5cdH0gXHJcblx0aWYgKGdyYXBoICE9PSBcIm1hc3RlckdyYXBoXCIgJiYgbm9kZXR5cGUgPT0gZ3JhcGgpIHtcclxuXHRcdGdyYXBoRG90W2dyYXBoXS5ub2RlU2VjdGlvbiArPSBgXCIke25vZGUubmFtZX1cIiBbIGxhYmVsID0gXCIke25vZGUubGFiZWx9XCIgXSBcXG5gXHJcblx0fSBcclxuXHRpZiAoZ3JhcGggIT09IFwibWFzdGVyR3JhcGhcIiAmJiBub2RldHlwZSAhPT0gZ3JhcGggJiYgKG5laWdoYm9yTm9kZS5zb3VyY2VPZi5pbmNsdWRlcyhub2RlLm5hbWUpIHx8IG5laWdoYm9yTm9kZS50YXJnZXRPZi5pbmNsdWRlcyhub2RlLm5hbWUpKSkge1xyXG5cdFx0Z3JhcGhEb3RbZ3JhcGhdLm5vZGVTZWN0aW9uICs9IGBcIiR7bm9kZS5uYW1lfVwiIFsgbGFiZWwgPSBcIiR7bm9kZS5sYWJlbH1cIiBdIFxcbmBcclxuXHR9IFxyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRQYWlyaW5nRWRnZXNGb3JFYWNoR3JhcGgoZ3JhcGgsZWRnZXR5cGUsZWRnZSxrLHN0eWxlKSB7XHJcblx0aWYgKGdyYXBoID09IFwibWFzdGVyR3JhcGhcIikge1xyXG5cdFx0Z3JhcGhEb3QubWFzdGVyR3JhcGguZWRnZVNlY3Rpb24gKz0gYFxyXG5zdWJncmFwaCBjbHVzdGVyXyR7ZWRnZXR5cGV9XyR7a317XHJcbnJhbms9c2FtZVxyXG5lZGdlIFsgJHtzdHlsZX0gXVxyXG5cIiR7ZWRnZS5zdGFydH1cIiAtPiBcIiR7ZWRnZS5lbmR9XCJcXG59YFxyXG5cdH0gXHJcblx0aWYgKGdyYXBoICE9IFwibWFzdGVyR3JhcGhcIiAmJiBlZGdldHlwZSA9PSBncmFwaCkge1xyXG5cdFx0Z3JhcGhEb3RbZ3JhcGhdLmVkZ2VTZWN0aW9uICs9IGBcclxuXHRcdHN1YmdyYXBoIGNsdXN0ZXJfJHtlZGdldHlwZX1fJHtrfXtcclxuXHRcdFx0cmFuaz1zYW1lXHJcblx0XHRcdGVkZ2UgWyAke3N0eWxlfSBdXHJcblx0XHRcdFwiJHtlZGdlLnN0YXJ0fVwiIC0+IFwiJHtlZGdlLmVuZH1cIlxcbn1gXHJcblx0XHR9XHJcblx0XHRrKytcclxuXHR9XHJcbmZ1bmN0aW9uIGFkZE5vblBhaXJpbmdFZGdlc0ZvckVhY2hHcmFwaChncmFwaCxlZGdldHlwZSxlZGdlKSB7XHJcblx0aWYgKGdyYXBoID09IFwibWFzdGVyR3JhcGhcIikge1xyXG5cdFx0Z3JhcGhEb3QubWFzdGVyR3JhcGguZWRnZVNlY3Rpb24gKz0gYFwiJHtlZGdlLnN0YXJ0fVwiIC0+IFwiJHtlZGdlLmVuZH1cIlxcbmBcclxuXHR9XHJcblx0ZnVuY3Rpb24gY2hlY2tOb2RlUmVsYXRpb25Ub0N1cnJlbnRHcmFwaChlZGdldHlwZSwgZWRnZSwgZ3JhcGgpIHtcclxuXHRcdHZhciBhID0gbm9kZURhdGFbZ3JhcGhdLm5vZGVzLmZpbHRlcihub2RlID0+IG5vZGUubmFtZT09ZWRnZS5zdGFydCB8fCBub2RlLm5hbWU9PWVkZ2UuZW5kKVxyXG5cdFx0aWYgKGEubGVuZ3RoICE9MCApIHtcclxuXHRcdFx0Ly8gY29uc29sZS5sb2coZ3JhcGgsZWRnZXR5cGUsIGVkZ2UsIGEpXHJcblx0XHRcdHJldHVybiB0cnVlXHJcblx0XHR9IFxyXG5cdH1cclxuXHRcclxuXHRpZiAoZ3JhcGggIT09IFwibWFzdGVyR3JhcGhcIiAmJiBjaGVja05vZGVSZWxhdGlvblRvQ3VycmVudEdyYXBoKGVkZ2V0eXBlLCBlZGdlLCBncmFwaCkpIHtcclxuXHRcdGdyYXBoRG90W2dyYXBoXS5lZGdlU2VjdGlvbiArPSBgXCIke2VkZ2Uuc3RhcnR9XCIgLT4gXCIke2VkZ2UuZW5kfVwiXFxuYFxyXG5cdH1cclxufVxyXG5cclxuZm9yIChjb25zdCBncmFwaCBpbiBub2RlVHlwZUxpc3REZWNsYXJhdGlvbikge1xyXG5cdGdyYXBoRG90W2dyYXBoXSA9IHtcclxuXHRcdG5vZGVTZWN0aW9uOiBcIlwiLFxyXG5cdFx0ZWRnZVNlY3Rpb246IFwiXCIsXHJcblx0XHRmaW5hbDogXCJcIiBcclxuXHR9XHJcblxyXG5cdC8qIDMuMTogUHJpbnQgYWxsIG5vZGVzIGJ5IHR5cGUgKi9cclxuXHRncmFwaERvdFtncmFwaF0ubm9kZVNlY3Rpb24gPSBgLy9OT0RFU1xcbi8vPT09PT09PT09PT09PT09PT09PT1cXG5cXG5gIFxyXG5cdG5vZGVUeXBlTGlzdC5mb3JFYWNoKG5vZGV0eXBlID0+IHtcclxuXHRcdGNvbnN0IHN0eWxlID0gbm9kZURhdGFbbm9kZXR5cGVdLnNldHRpbmdzLnN0eWxlXHJcblx0XHRjb25zdCBjbHVzdGVyID0gbm9kZURhdGFbbm9kZXR5cGVdLnNldHRpbmdzLmNsdXN0ZXJcclxuXHRcdGNvbnN0IHN1YmdyYXBoU2V0dGluZyA9IG5vZGVEYXRhW25vZGV0eXBlXS5zZXR0aW5ncy5zdWJncmFwaFNldHRpbmdcclxuXHRcdFxyXG5cdFx0Z3JhcGhEb3RbZ3JhcGhdLm5vZGVTZWN0aW9uICs9XHQgYFxcbm5vZGUgWyAke25vZGVEYXRhLm1hc3RlckdyYXBoLnNldHRpbmdzLnN0eWxlfSBdIC8vUmVzZXQgc3R5bGVcXG5cXG5gIFxyXG5cdFx0Z3JhcGhEb3RbZ3JhcGhdLm5vZGVTZWN0aW9uICs9IGAvL0FsbCAke25vZGV0eXBlfSBub2Rlc1xcbmAgO1xyXG5cdFx0aWYoY2x1c3RlciA9PSB0cnVlKSB7XHJcblx0XHRcdGdyYXBoRG90W2dyYXBoXS5ub2RlU2VjdGlvbiArPSBgc3ViZ3JhcGggY2x1c3Rlcl8ke25vZGV0eXBlfXtcXG4ke3N1YmdyYXBoU2V0dGluZ31cXG5gXHJcblx0XHR9IFxyXG5cdFx0aWYgKHN0eWxlICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0Z3JhcGhEb3RbZ3JhcGhdLm5vZGVTZWN0aW9uICs9IGBcXG5ub2RlIFsgJHtzdHlsZX0gXVxcbmBcclxuXHRcdH0gXHJcblx0XHRcclxuXHRcdG5vZGVEYXRhW25vZGV0eXBlXS5ub2Rlcy5mb3JFYWNoKG5vZGUgPT4gYWRkTm9kZXNGb3JFYWNoR3JhcGgoZ3JhcGgsbm9kZXR5cGUsbm9kZSkpXHJcblx0XHRcclxuXHRcdGlmKGNsdXN0ZXIgPT0gdHJ1ZSkge1xyXG5cdFx0XHRncmFwaERvdFtncmFwaF0ubm9kZVNlY3Rpb24gKz0gYH1cXG5gXHJcblx0XHR9IFxyXG5cdH0pXHJcblx0XHJcblx0XHJcblx0LyogMy4yOiBQcmludCBhbGwgZWRnZXMgYnkgdHlwZSAqL1xyXG5cdGdyYXBoRG90W2dyYXBoXS5lZGdlU2VjdGlvbiA9IGBcXG5cXG4vL0VER0VTXFxuLy89PT09PT09PT09PT09PT09PT09PVxcbmAgO1xyXG5cdHZhciBrPTBcclxuXHRcclxuXHRlZGdlVHlwZUxpc3QuZm9yRWFjaChlZGdldHlwZSA9PiB7XHJcblx0XHRjb25zdCBzYW1lUmFuayA9IGVkZ2VEYXRhW2VkZ2V0eXBlXS5zZXR0aW5ncy5zYW1lUmFua1xyXG5cdFx0Y29uc3QgY2x1c3RlciA9IGVkZ2VEYXRhW2VkZ2V0eXBlXS5zZXR0aW5ncy5jbHVzdGVyXHJcblx0XHRjb25zdCBzdHlsZSA9IGVkZ2VEYXRhW2VkZ2V0eXBlXS5zZXR0aW5ncy5zdHlsZVxyXG5cdFx0Y29uc3QgcGFpcmluZyA9IGVkZ2VEYXRhW2VkZ2V0eXBlXS5zZXR0aW5ncy5wYWlyaW5nXHJcblx0XHRcclxuXHRcdGlmIChlZGdlRGF0YS5tYXN0ZXJHcmFwaC5zZXR0aW5ncy5zdHlsZSAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdGdyYXBoRG90W2dyYXBoXS5lZGdlU2VjdGlvbiArPSBgXFxuZWRnZSBbICR7ZWRnZURhdGEubWFzdGVyR3JhcGguc2V0dGluZ3Muc3R5bGV9IF0gLy9SZXNldCBzdHlsZVxcbmBcclxuXHRcdH0gXHJcblx0XHRncmFwaERvdFtncmFwaF0uZWRnZVNlY3Rpb24gKz0gYFxcbi8vQWxsICR7ZWRnZXR5cGV9IGVkZ2VzXFxuYFxyXG5cdFx0XHJcblx0XHRpZiAocGFpcmluZyA9PSB0cnVlKSB7XHJcblx0XHRcdGVkZ2VEYXRhW2VkZ2V0eXBlXS5lZGdlcy5mb3JFYWNoIChlZGdlID0+IHsgXHJcblx0XHRcdFx0YWRkUGFpcmluZ0VkZ2VzRm9yRWFjaEdyYXBoKGdyYXBoLGVkZ2V0eXBlLGVkZ2UsayxzdHlsZSkgXHJcblx0XHRcdFx0aysrXHJcblx0XHRcdH0pO1xyXG5cdFx0fSBlbHNlIHsgXHJcblx0XHRcdGlmIChjbHVzdGVyID09IHRydWUgJiYgc2FtZVJhbmsgPT0gdHJ1ZSkge1xyXG5cdFx0XHRcdGdyYXBoRG90W2dyYXBoXS5lZGdlU2VjdGlvbiArPSBgc3ViZ3JhcGggY2x1c3Rlcl8ke2VkZ2V0eXBlfXtcXG5yYW5rPXNhbWVcXG5gXHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKGNsdXN0ZXIgPT0gdHJ1ZSAmJiBzYW1lUmFuayAhPT0gdHJ1ZSkge1xyXG5cdFx0XHRcdGdyYXBoRG90W2dyYXBoXS5lZGdlU2VjdGlvbiArPSBgc3ViZ3JhcGggY2x1c3Rlcl8ke2VkZ2V0eXBlfXtcXG5gXHJcblx0XHRcdH0gXHJcblx0XHRcdGlmIChjbHVzdGVyICE9PSB0cnVlICYmIHNhbWVSYW5rID09IHRydWUpIHtcclxuXHRcdFx0XHRncmFwaERvdFtncmFwaF0uZWRnZVNlY3Rpb24gKz0gYHN1YmdyYXBoIHtcXG5yYW5rPXNhbWVcXG5gXHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKHN0eWxlICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0XHRncmFwaERvdFtncmFwaF0uZWRnZVNlY3Rpb24gKz0gYFxcbmVkZ2UgWyAke3N0eWxlfSBdXFxuYFxyXG5cdFx0XHR9IFxyXG5cdFx0XHRlZGdlRGF0YVtlZGdldHlwZV0uZWRnZXMuZm9yRWFjaCAoZWRnZSA9PiB7IFxyXG5cdFx0XHRcdGFkZE5vblBhaXJpbmdFZGdlc0ZvckVhY2hHcmFwaChncmFwaCxlZGdldHlwZSxlZGdlKVx0XHJcblx0XHRcdH0pXHJcblx0XHRcdFxyXG5cdFx0XHRpZiAoY2x1c3RlciA9PSB0cnVlIHx8IHNhbWVSYW5rID09IHRydWUpIHtcclxuXHRcdFx0XHRncmFwaERvdFtncmFwaF0uZWRnZVNlY3Rpb24gKz0gYH1cXG5gXHJcblx0XHRcdH0gXHJcblx0XHR9IFxyXG5cdH0pXHJcblx0Z3JhcGhEb3RbZ3JhcGhdLmVkZ2VTZWN0aW9uICs9IGBcXG59YFxyXG5cclxuXHQvKiAzLjM6IENyZWF0aW5nIGZpbmFsIG91dHB1dCAqL1xyXG5cdGdyYXBoRG90W2dyYXBoXS5maW5hbCA9IGBkaWdyYXBoICR7Z3JhcGh9e1xcbiR7bm9kZURhdGEubWFzdGVyR3JhcGguc2V0dGluZ3MuZ3JhcGhIZWFkZXJ9XFxuYCA7XHJcblx0Z3JhcGhEb3RbZ3JhcGhdLmZpbmFsICs9IGdyYXBoRG90W2dyYXBoXS5ub2RlU2VjdGlvbiArIGdyYXBoRG90W2dyYXBoXS5lZGdlU2VjdGlvbjtcclxuXHJcblx0Ly8gY29uc29sZS5sb2coZ3JhcGhEb3RbZ3JhcGhdLm5vZGVTZWN0aW9uKVxyXG5cdC8vIGNvbnNvbGUubG9nKGdyYXBoRG90W2dyYXBoXS5lZGdlU2VjdGlvbilcclxuXHQvLyBjb25zb2xlLmxvZyhncmFwaERvdFtncmFwaF0uZmluYWwpXHJcblx0XHJcbi8qIFBhcnQgNDogRXhwb3J0IHRvIGZpbGUgKi9cdFxyXG5cdGNvbnN0IGNvbW1hbmRMaXN0ID0gW1xyXG5cdFx0YHVuZmxhdHRlbiAtbCAzICR7Z3JhcGh9LmRvdCAtbyB1bmZsYXR0ZW5fJHtncmFwaH0uZG90YCxcclxuXHRcdGBkb3QgLVRwbmcgdW5mbGF0dGVuXyR7Z3JhcGh9LmRvdCAtbyBkb3RfJHtncmFwaH0ucG5nYCxcclxuXHRcdC8vIGBuZWF0byAtVHBuZyAke2dyYXBofS5kb3QgLW8gbmVhdG9fJHtncmFwaH0ucG5nYCxcclxuXHRcdC8vIGB0d29waSAtVHBuZyAke2dyYXBofS5kb3QgLW8gdHdvcGlfJHtncmFwaH0ucG5nYCxcclxuXHRcdC8vIGBjaXJjbyAtVHBuZyAke2dyYXBofS5kb3QgLW8gY2lyY29fJHtncmFwaH0ucG5nYCxcclxuXHRcdC8vIGBzZmRwIC1UcG5nICR7Z3JhcGh9LmRvdCAtbyBzZmRwXyR7Z3JhcGh9LnBuZ2AsXHJcblx0XSBcdFxyXG5cclxuXHR2YXIgZmlsZVBhdGggPSBhcHAudmF1bHQuY29uZmlnRGlyICsgXCJcXFxccGx1Z2luc1xcXFxkb3RtYWtlclxcXFxncmFwaHNcXFxcXCIgICsgZ3JhcGggKyBcIi5kb3RcIjtcclxuXHRhcHAudmF1bHQuYWRhcHRlci53cml0ZShmaWxlUGF0aCxncmFwaERvdFtncmFwaF0uZmluYWwpXHJcblx0Ly8gY29uc29sZS5sb2coZ3JhcGhEb3RbZ3JhcGhdIClcclxuXHRjb21tYW5kTGlzdC5mb3JFYWNoKGNvbW1hbmQgPT4gZXhlYyhjb21tYW5kLCAoZXJyb3IsIHN0ZG91dCwgc3RkZXJyKSA9PiB7XHJcblx0XHRjb25zb2xlLmxvZyhcImZpbGVQYXRoOlwiLCBmaWxlUGF0aClcclxuXHRcdGNvbnNvbGUubG9nKGdyYXBoLCBjb21tYW5kKVxyXG5cdFx0Y29uc29sZS5sb2coXCJzdGRvdXQ6XCIsIHN0ZG91dCk7XHJcblx0XHRjb25zb2xlLmxvZyhcInN0ZGVycjpcIiwgc3RkZXJyKTtcclxuXHRcdGlmIChlcnJvciAhPT0gbnVsbCkge1xyXG5cdFx0XHRjb25zb2xlLmxvZyhgZXhlYyBlcnJvcjogJHtlcnJvcn1gKTtcclxuXHRcdH1cclxuXHR9KSlcclxufVxyXG5kZWJ1ZygpXHJcbmNvbnNvbGUubG9nKCdkb25lJylcclxuXHJcbn07XHJcbm9udW5sb2FkKCkge1xyXG5cdGNvbnNvbGUubG9nKCd1bmxvYWRpbmcgcGx1Z2luJylcclxufVxyXG59Il0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFVQSxzQkFBdUI7QUFDdkIsSUFBTSxFQUFFLFNBQVMsUUFBUTtBQUV6QixJQUFJLFdBQVc7QUFDZixJQUFJLFdBQVc7QUFDZixJQUFNLFdBQVc7QUFFakIsSUFBTSxhQUFhLElBQUksUUFBUSxRQUFRLFlBQVksTUFBTSxTQUFTO0FBQ2xFLElBQU0sYUFBYSxJQUFJLFFBQVEsUUFBUSxZQUFZLE1BQU0sU0FBUztB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