@edugis-org/webmapx 0.1.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 +149 -0
- package/dist-lib/WMTS-DCN4zX0-.js +1169 -0
- package/dist-lib/alert-GeHlqlN8.js +310 -0
- package/dist-lib/assets/epsg-lookup.worker-J7TVnHDq.js +1 -0
- package/dist-lib/assets/shapefile.worker-kQfZj6G2.js +4 -0
- package/dist-lib/attribution-format-B4f05_u0.js +62 -0
- package/dist-lib/button-DFdGkRPQ.js +741 -0
- package/dist-lib/cesium-adapter-BHXNytkU.js +1488 -0
- package/dist-lib/checkbox-QoR4S8tV.js +284 -0
- package/dist-lib/chunk-HEgqtunE.js +20 -0
- package/dist-lib/chunk.36O46B5H-B6ZL7Sm1.js +77 -0
- package/dist-lib/chunk.3RPBFEDE-BFO1fHVm.js +138 -0
- package/dist-lib/chunk.5JY5FUCG-DTXsslmx.js +1090 -0
- package/dist-lib/chunk.6CTB5ZDJ-DjZrBd6Y.js +99 -0
- package/dist-lib/chunk.AJ3ENQ5C-Ci7Gm2b6.js +175 -0
- package/dist-lib/chunk.LD4M4QGE-CiCfhE8r.js +8 -0
- package/dist-lib/chunk.NYIIDP5N-BikXIStD.js +99 -0
- package/dist-lib/chunk.RWUUFNUL-DFztA4uV.js +43 -0
- package/dist-lib/chunk.SI4ACBFK-CLb9VfMG.js +61 -0
- package/dist-lib/chunk.YHLNUJ7P-D-kanrCf.js +503 -0
- package/dist-lib/core-CMAlSR68.js +22 -0
- package/dist-lib/decorate-CWgUV1hU.js +1139 -0
- package/dist-lib/decorators-B35AgiCU.js +351 -0
- package/dist-lib/deferred-query-service-BJDcngw6.js +386 -0
- package/dist-lib/dist-Dm6b7XCs.js +12318 -0
- package/dist-lib/dist-Ha9LQCut.js +244 -0
- package/dist-lib/dist-c1PlDAd1.js +2359 -0
- package/dist-lib/dist-kKlmcBXq.js +50 -0
- package/dist-lib/divider-CPm675yY.js +41 -0
- package/dist-lib/dropped-config-C_GyVa8o.js +17 -0
- package/dist-lib/dropped-layer-builder-DAaYgUPk.js +396 -0
- package/dist-lib/epsg-definitions-BZLZWa8Q.js +668 -0
- package/dist-lib/esm-CTuscnN5.js +46 -0
- package/dist-lib/file-sniff-Dhxj3KTF.js +251 -0
- package/dist-lib/geo-calculations-DbFJAUoI.js +30 -0
- package/dist-lib/icon-CEOgWlro.js +9 -0
- package/dist-lib/icon-button-Da_nBTy3.js +408 -0
- package/dist-lib/input-CeGntPlT.js +590 -0
- package/dist-lib/layer-discovery-afWzu5hY.js +2825 -0
- package/dist-lib/leaflet-adapter-D9djjrKv.js +1227 -0
- package/dist-lib/lib-CdHVicAE.js +4074 -0
- package/dist-lib/map-layer-registry-2cmkiRDK.js +62 -0
- package/dist-lib/maplibre-adapter-TFc3e0G9.js +1190 -0
- package/dist-lib/maplibre-expression-evaluator-DCWUcpwf.js +7233 -0
- package/dist-lib/marker-utils-DztWXeop.js +12 -0
- package/dist-lib/ol-tilegrid-9VtyxaLG.js +64 -0
- package/dist-lib/openlayers-adapter-DVW1KCRv.js +13307 -0
- package/dist-lib/option-CBxl1mZP.js +1106 -0
- package/dist-lib/papaparse.min-B7v3c0D7.js +501 -0
- package/dist-lib/rbush-C8k41T4z.js +254 -0
- package/dist-lib/shapefile-SawVY6xg.js +207 -0
- package/dist-lib/spinner-DysxdNG9.js +6 -0
- package/dist-lib/src-CL94RDe3.js +111 -0
- package/dist-lib/throttle-BeneRNYK.js +16 -0
- package/dist-lib/toast-Cm28o9U6.js +15 -0
- package/dist-lib/togeojson.es-DAgiTBvg.js +579 -0
- package/dist-lib/tooltip-Cucn1SiD.js +197 -0
- package/dist-lib/webmapx-3d-tool-D4CTD2gB.js +176 -0
- package/dist-lib/webmapx-base-tool-Dm9NAWLD.js +75 -0
- package/dist-lib/webmapx-config-edit-tool-DCTyxqTk.js +389 -0
- package/dist-lib/webmapx-coordinates-tool-jeWohup9.js +648 -0
- package/dist-lib/webmapx-core-bundle-BDImi1RE.js +8203 -0
- package/dist-lib/webmapx-draw-tool-DooAV8cF.js +4336 -0
- package/dist-lib/webmapx-geolocation-tool-Rw3-Iad1.js +788 -0
- package/dist-lib/webmapx-import-layer-tool-DRYviHd5.js +250 -0
- package/dist-lib/webmapx-info-tool-BJA157cy.js +412 -0
- package/dist-lib/webmapx-language-osmvector-M5y_lwOg.js +489 -0
- package/dist-lib/webmapx-measure-tool-BXhMJFC6.js +590 -0
- package/dist-lib/webmapx-modal-tool-eF6Naluv.js +84 -0
- package/dist-lib/webmapx-plugin-tool-D2Hghf9n.js +45 -0
- package/dist-lib/webmapx-print-tool-ob1bOsR5.js +348 -0
- package/dist-lib/webmapx-search-tool-Cv8BrYvY.js +437 -0
- package/dist-lib/webmapx-settings-DDEJ8aoV.js +479 -0
- package/dist-lib/webmapx-truearea-tool-CMB4Orm-.js +615 -0
- package/dist-lib/webmapx-view-mode-tool-CUpLNjOj.js +106 -0
- package/dist-lib/webmapx.css +2 -0
- package/dist-lib/webmapx.js +1321 -0
- package/dist-lib/wms-feature-info-C0RVMEQC.js +145 -0
- package/dist-lib/wms-url-builder-DIJLQ1v2.js +54 -0
- package/dist-lib/zip.js-DVhmtjxZ.js +3615 -0
- package/package.json +107 -0
- package/public/data/country-epsg-codes.json +297 -0
- package/public/data/world-countries-simplified.topojson +1 -0
- package/src/locales/en/core.json +20 -0
|
@@ -0,0 +1,2825 @@
|
|
|
1
|
+
import { t as e } from "./chunk-HEgqtunE.js";
|
|
2
|
+
import { n as t } from "./lib-CdHVicAE.js";
|
|
3
|
+
import { t as n } from "./epsg-definitions-BZLZWa8Q.js";
|
|
4
|
+
import { t as r } from "./wms-url-builder-DIJLQ1v2.js";
|
|
5
|
+
//#region node_modules/@camptocamp/ogc-client/dist/worker/index.js
|
|
6
|
+
var i = 0;
|
|
7
|
+
function a() {
|
|
8
|
+
return i++;
|
|
9
|
+
}
|
|
10
|
+
var o = Object.defineProperty, s = Object.getOwnPropertyDescriptor, c = Object.getOwnPropertyNames, l = Object.prototype.hasOwnProperty, u = (e, t) => {
|
|
11
|
+
for (var n in t) o(e, n, {
|
|
12
|
+
get: t[n],
|
|
13
|
+
enumerable: !0
|
|
14
|
+
});
|
|
15
|
+
}, d = (e, t, n, r) => {
|
|
16
|
+
if (t && typeof t == "object" || typeof t == "function") for (let i of c(t)) !l.call(e, i) && i !== n && o(e, i, {
|
|
17
|
+
get: () => t[i],
|
|
18
|
+
enumerable: !(r = s(t, i)) || r.enumerable
|
|
19
|
+
});
|
|
20
|
+
return e;
|
|
21
|
+
}, f = (e) => d(o({}, "__esModule", { value: !0 }), e), p = {};
|
|
22
|
+
u(p, {
|
|
23
|
+
XmlCdata: () => ee,
|
|
24
|
+
XmlComment: () => te,
|
|
25
|
+
XmlDeclaration: () => j,
|
|
26
|
+
XmlDocument: () => ne,
|
|
27
|
+
XmlDocumentType: () => N,
|
|
28
|
+
XmlElement: () => M,
|
|
29
|
+
XmlError: () => re,
|
|
30
|
+
XmlNode: () => k,
|
|
31
|
+
XmlProcessingInstruction: () => ie,
|
|
32
|
+
XmlText: () => A,
|
|
33
|
+
parseXml: () => se
|
|
34
|
+
}), f(p);
|
|
35
|
+
var m = "", h = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, g = class {
|
|
36
|
+
constructor(e) {
|
|
37
|
+
if (this.k = this.q(e, !0), this.d = 0, this.length = e.length, this.n = this.k !== this.length, this.m = e, this.n) {
|
|
38
|
+
let t = [];
|
|
39
|
+
for (let n = 0, r = 0; r < this.k; ++r) t[r] = n, n += e.codePointAt(n) > 65535 ? 2 : 1;
|
|
40
|
+
this.y = t;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
get z() {
|
|
44
|
+
return this.d >= this.k;
|
|
45
|
+
}
|
|
46
|
+
q(e, t = this.n) {
|
|
47
|
+
return t ? e.replace(h, "_").length : e.length;
|
|
48
|
+
}
|
|
49
|
+
g(e = 1) {
|
|
50
|
+
this.d = Math.min(this.k, this.d + e);
|
|
51
|
+
}
|
|
52
|
+
i(e = this.d) {
|
|
53
|
+
return this.n ? this.y[e] ?? Infinity : e;
|
|
54
|
+
}
|
|
55
|
+
F(e = 1) {
|
|
56
|
+
let t = this.h(e);
|
|
57
|
+
return this.g(e), t;
|
|
58
|
+
}
|
|
59
|
+
G(e) {
|
|
60
|
+
if (!e.sticky) throw Error("`regex` must have a sticky flag (\"y\")");
|
|
61
|
+
e.lastIndex = this.i();
|
|
62
|
+
let t = e.exec(this.m);
|
|
63
|
+
if (t === null || t.length === 0) return m;
|
|
64
|
+
let n = t[0];
|
|
65
|
+
return this.g(this.q(n)), n;
|
|
66
|
+
}
|
|
67
|
+
v(e) {
|
|
68
|
+
let t, n = m;
|
|
69
|
+
for (; (t = this.h()) && e(t);) n += t, this.g();
|
|
70
|
+
return n;
|
|
71
|
+
}
|
|
72
|
+
Q(e) {
|
|
73
|
+
if (this.b(e)) return e;
|
|
74
|
+
if (this.n) {
|
|
75
|
+
let { length: t } = e, n = this.q(e);
|
|
76
|
+
if (n !== t && e === this.h(n)) return this.g(n), e;
|
|
77
|
+
}
|
|
78
|
+
return m;
|
|
79
|
+
}
|
|
80
|
+
b(e) {
|
|
81
|
+
let { length: t } = e;
|
|
82
|
+
return this.h(t) === e ? (this.g(t), e) : m;
|
|
83
|
+
}
|
|
84
|
+
A(e) {
|
|
85
|
+
let t = this.m.slice(this.i()), n = t.search(e);
|
|
86
|
+
if (n <= 0) return m;
|
|
87
|
+
let r = t.slice(0, n);
|
|
88
|
+
return this.g(this.q(r)), r;
|
|
89
|
+
}
|
|
90
|
+
t(e) {
|
|
91
|
+
let { m: t } = this, n = this.i(), r = t.indexOf(e, n);
|
|
92
|
+
if (r <= 0) return m;
|
|
93
|
+
let i = t.slice(n, r);
|
|
94
|
+
return this.g(this.q(i)), i;
|
|
95
|
+
}
|
|
96
|
+
h(e = 1) {
|
|
97
|
+
let { d: t, n, m: r } = this;
|
|
98
|
+
return n ? t >= this.k ? m : r.slice(this.i(t), this.i(t + e)) : r.slice(t, t + e);
|
|
99
|
+
}
|
|
100
|
+
o(e = 0) {
|
|
101
|
+
this.d = e >= 0 ? Math.min(this.k, e) : Math.max(0, this.d + e);
|
|
102
|
+
}
|
|
103
|
+
}, _ = /[^"&<]+/y, v = /[^'&<]+/y, y = /\r\n|[\n\r\t]/g, b = /<|&|]]>/, x = Object.freeze(Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
104
|
+
amp: "&",
|
|
105
|
+
apos: "'",
|
|
106
|
+
gt: ">",
|
|
107
|
+
lt: "<",
|
|
108
|
+
quot: "\""
|
|
109
|
+
}));
|
|
110
|
+
function S(e) {
|
|
111
|
+
let t = D(e);
|
|
112
|
+
return t >= 97 && t <= 122 || t >= 65 && t <= 90 || t >= 48 && t <= 57 || t === 45 || t === 46 || t === 183 || t >= 768 && t <= 879 || t >= 8255 && t <= 8256 || C(e, t);
|
|
113
|
+
}
|
|
114
|
+
function C(e, t = D(e)) {
|
|
115
|
+
return t >= 97 && t <= 122 || t >= 65 && t <= 90 || t === 58 || t === 95 || t >= 192 && t <= 214 || t >= 216 && t <= 246 || t >= 248 && t <= 767 || t >= 880 && t <= 893 || t >= 895 && t <= 8191 || t >= 8204 && t <= 8205 || t >= 8304 && t <= 8591 || t >= 11264 && t <= 12271 || t >= 12289 && t <= 55295 || t >= 63744 && t <= 64975 || t >= 65008 && t <= 65533 || t >= 65536 && t <= 983039;
|
|
116
|
+
}
|
|
117
|
+
function w(e) {
|
|
118
|
+
return e === "#" || S(e);
|
|
119
|
+
}
|
|
120
|
+
function T(e) {
|
|
121
|
+
let t = D(e);
|
|
122
|
+
return t === 32 || t === 9 || t === 10 || t === 13;
|
|
123
|
+
}
|
|
124
|
+
function E(e) {
|
|
125
|
+
return e === 9 || e === 10 || e === 13 || e >= 32 && e <= 55295 || e >= 57344 && e <= 65533 || e >= 65536 && e <= 1114111;
|
|
126
|
+
}
|
|
127
|
+
function D(e) {
|
|
128
|
+
return e.codePointAt(0) || -1;
|
|
129
|
+
}
|
|
130
|
+
var O = class {
|
|
131
|
+
constructor() {
|
|
132
|
+
this.parent = null, this.start = -1, this.end = -1;
|
|
133
|
+
}
|
|
134
|
+
get document() {
|
|
135
|
+
return this.parent?.document ?? null;
|
|
136
|
+
}
|
|
137
|
+
get isRootNode() {
|
|
138
|
+
return this.parent !== null && this.parent === this.document && this.type === O.TYPE_ELEMENT;
|
|
139
|
+
}
|
|
140
|
+
get preserveWhitespace() {
|
|
141
|
+
return !!this.parent?.preserveWhitespace;
|
|
142
|
+
}
|
|
143
|
+
get type() {
|
|
144
|
+
return "";
|
|
145
|
+
}
|
|
146
|
+
toJSON() {
|
|
147
|
+
let e = { type: this.type };
|
|
148
|
+
return this.isRootNode && (e.isRootNode = !0), this.preserveWhitespace && (e.preserveWhitespace = !0), this.start !== -1 && (e.start = this.start, e.end = this.end), e;
|
|
149
|
+
}
|
|
150
|
+
}, k = O;
|
|
151
|
+
k.TYPE_CDATA = "cdata", k.TYPE_COMMENT = "comment", k.TYPE_DOCUMENT = "document", k.TYPE_DOCUMENT_TYPE = "doctype", k.TYPE_ELEMENT = "element", k.TYPE_PROCESSING_INSTRUCTION = "pi", k.TYPE_TEXT = "text", k.TYPE_XML_DECLARATION = "xmldecl";
|
|
152
|
+
var A = class extends k {
|
|
153
|
+
constructor(e = "") {
|
|
154
|
+
super(), this.text = e;
|
|
155
|
+
}
|
|
156
|
+
get type() {
|
|
157
|
+
return k.TYPE_TEXT;
|
|
158
|
+
}
|
|
159
|
+
toJSON() {
|
|
160
|
+
return Object.assign(k.prototype.toJSON.call(this), { text: this.text });
|
|
161
|
+
}
|
|
162
|
+
}, ee = class extends A {
|
|
163
|
+
get type() {
|
|
164
|
+
return k.TYPE_CDATA;
|
|
165
|
+
}
|
|
166
|
+
}, te = class extends k {
|
|
167
|
+
constructor(e = "") {
|
|
168
|
+
super(), this.content = e;
|
|
169
|
+
}
|
|
170
|
+
get type() {
|
|
171
|
+
return k.TYPE_COMMENT;
|
|
172
|
+
}
|
|
173
|
+
toJSON() {
|
|
174
|
+
return Object.assign(k.prototype.toJSON.call(this), { content: this.content });
|
|
175
|
+
}
|
|
176
|
+
}, j = class extends k {
|
|
177
|
+
constructor(e, t, n) {
|
|
178
|
+
super(), this.version = e, this.encoding = t ?? null, this.standalone = n ?? null;
|
|
179
|
+
}
|
|
180
|
+
get type() {
|
|
181
|
+
return k.TYPE_XML_DECLARATION;
|
|
182
|
+
}
|
|
183
|
+
toJSON() {
|
|
184
|
+
let e = k.prototype.toJSON.call(this);
|
|
185
|
+
e.version = this.version;
|
|
186
|
+
for (let t of ["encoding", "standalone"]) this[t] !== null && (e[t] = this[t]);
|
|
187
|
+
return e;
|
|
188
|
+
}
|
|
189
|
+
}, M = class extends k {
|
|
190
|
+
constructor(e, t = /* @__PURE__ */ Object.create(null), n = []) {
|
|
191
|
+
super(), this.name = e, this.attributes = t, this.children = n;
|
|
192
|
+
}
|
|
193
|
+
get isEmpty() {
|
|
194
|
+
return this.children.length === 0;
|
|
195
|
+
}
|
|
196
|
+
get preserveWhitespace() {
|
|
197
|
+
let e = this;
|
|
198
|
+
for (; e instanceof M;) {
|
|
199
|
+
if ("xml:space" in e.attributes) return e.attributes["xml:space"] === "preserve";
|
|
200
|
+
e = e.parent;
|
|
201
|
+
}
|
|
202
|
+
return !1;
|
|
203
|
+
}
|
|
204
|
+
get text() {
|
|
205
|
+
return this.children.map((e) => "text" in e ? e.text : "").join("");
|
|
206
|
+
}
|
|
207
|
+
get type() {
|
|
208
|
+
return k.TYPE_ELEMENT;
|
|
209
|
+
}
|
|
210
|
+
toJSON() {
|
|
211
|
+
return Object.assign(k.prototype.toJSON.call(this), {
|
|
212
|
+
name: this.name,
|
|
213
|
+
attributes: this.attributes,
|
|
214
|
+
children: this.children.map((e) => e.toJSON())
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}, ne = class extends k {
|
|
218
|
+
constructor(e = []) {
|
|
219
|
+
super(), this.children = e;
|
|
220
|
+
}
|
|
221
|
+
get document() {
|
|
222
|
+
return this;
|
|
223
|
+
}
|
|
224
|
+
get root() {
|
|
225
|
+
for (let e of this.children) if (e instanceof M) return e;
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
get text() {
|
|
229
|
+
return this.children.map((e) => "text" in e ? e.text : "").join("");
|
|
230
|
+
}
|
|
231
|
+
get type() {
|
|
232
|
+
return k.TYPE_DOCUMENT;
|
|
233
|
+
}
|
|
234
|
+
toJSON() {
|
|
235
|
+
return Object.assign(k.prototype.toJSON.call(this), { children: this.children.map((e) => e.toJSON()) });
|
|
236
|
+
}
|
|
237
|
+
}, N = class extends k {
|
|
238
|
+
constructor(e, t, n, r) {
|
|
239
|
+
super(), this.name = e, this.publicId = t ?? null, this.systemId = n ?? null, this.internalSubset = r ?? null;
|
|
240
|
+
}
|
|
241
|
+
get type() {
|
|
242
|
+
return k.TYPE_DOCUMENT_TYPE;
|
|
243
|
+
}
|
|
244
|
+
toJSON() {
|
|
245
|
+
let e = k.prototype.toJSON.call(this);
|
|
246
|
+
e.name = this.name;
|
|
247
|
+
for (let t of [
|
|
248
|
+
"publicId",
|
|
249
|
+
"systemId",
|
|
250
|
+
"internalSubset"
|
|
251
|
+
]) this[t] !== null && (e[t] = this[t]);
|
|
252
|
+
return e;
|
|
253
|
+
}
|
|
254
|
+
}, re = class extends Error {
|
|
255
|
+
constructor(e, t, n) {
|
|
256
|
+
let r = 1, i = "", a = 1;
|
|
257
|
+
for (let e = 0; e < t; ++e) {
|
|
258
|
+
let t = n[e];
|
|
259
|
+
t === "\n" ? (r = 1, i = "", a += 1) : (r += 1, i += t);
|
|
260
|
+
}
|
|
261
|
+
let o = n.indexOf("\n", t);
|
|
262
|
+
i += o === -1 ? n.slice(t) : n.slice(t, o);
|
|
263
|
+
let s = 0;
|
|
264
|
+
i.length > 50 && (r < 40 ? i = i.slice(0, 50) : (s = r - 20, i = i.slice(s, r + 30))), super(`${e} (line ${a}, column ${r})
|
|
265
|
+
${i}
|
|
266
|
+
` + " ".repeat(r - s + 1) + "^\n"), this.column = r, this.excerpt = i, this.line = a, this.name = "XmlError", this.pos = t;
|
|
267
|
+
}
|
|
268
|
+
}, ie = class extends k {
|
|
269
|
+
constructor(e, t = "") {
|
|
270
|
+
super(), this.name = e, this.content = t;
|
|
271
|
+
}
|
|
272
|
+
get type() {
|
|
273
|
+
return k.TYPE_PROCESSING_INSTRUCTION;
|
|
274
|
+
}
|
|
275
|
+
toJSON() {
|
|
276
|
+
return Object.assign(k.prototype.toJSON.call(this), {
|
|
277
|
+
name: this.name,
|
|
278
|
+
content: this.content
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}, ae = "", oe = class {
|
|
282
|
+
constructor(e, t = {}) {
|
|
283
|
+
let n = this.document = new ne(), r = this.c = new g(e);
|
|
284
|
+
if (this.l = n, this.f = t, this.f.includeOffsets && (n.start = 0, n.end = e.length), r.b(""), this.H(), !this.B()) throw this.a("Root element is missing or invalid");
|
|
285
|
+
for (; this.w(););
|
|
286
|
+
if (!r.z) throw this.a("Extra content at the end of the document");
|
|
287
|
+
}
|
|
288
|
+
j(e, t) {
|
|
289
|
+
return e.parent = this.l, this.f.includeOffsets && (e.start = this.c.i(t), e.end = this.c.i()), this.l.children.push(e), !0;
|
|
290
|
+
}
|
|
291
|
+
x(e, t) {
|
|
292
|
+
let { children: n } = this.l, { length: r } = n;
|
|
293
|
+
if (e = P(e), r > 0) {
|
|
294
|
+
let t = n[r - 1];
|
|
295
|
+
if (t?.type === k.TYPE_TEXT) {
|
|
296
|
+
let n = t;
|
|
297
|
+
return n.text += e, this.f.includeOffsets && (n.end = this.c.i()), !0;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return this.j(new A(e), t);
|
|
301
|
+
}
|
|
302
|
+
I() {
|
|
303
|
+
let e = /* @__PURE__ */ Object.create(null);
|
|
304
|
+
for (; this.e();) {
|
|
305
|
+
let t = this.r();
|
|
306
|
+
if (!t) break;
|
|
307
|
+
let n = this.u() && this.J();
|
|
308
|
+
if (n === !1) throw this.a("Attribute value expected");
|
|
309
|
+
if (t in e) throw this.a(`Duplicate attribute: ${t}`);
|
|
310
|
+
if (t === "xml:space" && n !== "default" && n !== "preserve") throw this.a("Value of the `xml:space` attribute must be \"default\" or \"preserve\"");
|
|
311
|
+
e[t] = n;
|
|
312
|
+
}
|
|
313
|
+
if (this.f.sortAttributes) {
|
|
314
|
+
let t = Object.keys(e).sort(), n = /* @__PURE__ */ Object.create(null);
|
|
315
|
+
for (let r = 0; r < t.length; ++r) {
|
|
316
|
+
let i = t[r];
|
|
317
|
+
n[i] = e[i];
|
|
318
|
+
}
|
|
319
|
+
e = n;
|
|
320
|
+
}
|
|
321
|
+
return e;
|
|
322
|
+
}
|
|
323
|
+
J() {
|
|
324
|
+
let { c: e } = this, t = e.h();
|
|
325
|
+
if (t !== "\"" && t !== "'") return !1;
|
|
326
|
+
e.g();
|
|
327
|
+
let n, r = !1, i = ae, a = t === "\"" ? _ : v;
|
|
328
|
+
matchLoop: for (; !e.z;) switch (n = e.G(a), n && (this.p(n), i += n.replace(y, " ")), e.h()) {
|
|
329
|
+
case t:
|
|
330
|
+
r = !0;
|
|
331
|
+
break matchLoop;
|
|
332
|
+
case "&":
|
|
333
|
+
i += this.C();
|
|
334
|
+
continue;
|
|
335
|
+
case "<": throw this.a("Unescaped `<` is not allowed in an attribute value");
|
|
336
|
+
case ae: break matchLoop;
|
|
337
|
+
}
|
|
338
|
+
if (!r) throw this.a("Unclosed attribute");
|
|
339
|
+
return e.g(), i;
|
|
340
|
+
}
|
|
341
|
+
K() {
|
|
342
|
+
let { c: e } = this, t = e.d;
|
|
343
|
+
if (!e.b("<![CDATA[")) return !1;
|
|
344
|
+
let n = e.t("]]>");
|
|
345
|
+
if (this.p(n), !e.b("]]>")) throw this.a("Unclosed CDATA section");
|
|
346
|
+
return this.f.preserveCdata ? this.j(new ee(P(n)), t) : this.x(n, t);
|
|
347
|
+
}
|
|
348
|
+
L() {
|
|
349
|
+
let { c: e } = this, t = e.d, n = e.A(b);
|
|
350
|
+
if (!n) return !1;
|
|
351
|
+
if (this.p(n), e.h(3) === "]]>") throw this.a("Element content may not contain the CDATA section close delimiter `]]>`");
|
|
352
|
+
return this.x(n, t);
|
|
353
|
+
}
|
|
354
|
+
D() {
|
|
355
|
+
let { c: e } = this, t = e.d;
|
|
356
|
+
if (!e.b("<!--")) return !1;
|
|
357
|
+
let n = e.t("--");
|
|
358
|
+
if (this.p(n), !e.b("-->")) throw e.h(2) === "--" ? this.a("The string `--` isn't allowed inside a comment") : this.a("Unclosed comment");
|
|
359
|
+
return this.f.preserveComments ? this.j(new te(P(n)), t) : !0;
|
|
360
|
+
}
|
|
361
|
+
M() {
|
|
362
|
+
let e = this.c.d, t = this.C();
|
|
363
|
+
return t ? this.x(t, e) : !1;
|
|
364
|
+
}
|
|
365
|
+
N() {
|
|
366
|
+
let { c: e } = this, t = e.d;
|
|
367
|
+
if (!e.b("<!DOCTYPE")) return !1;
|
|
368
|
+
let n = this.e() && this.r();
|
|
369
|
+
if (!n) throw this.a("Expected a name");
|
|
370
|
+
let r, i;
|
|
371
|
+
if (this.e()) {
|
|
372
|
+
if (e.b("PUBLIC")) {
|
|
373
|
+
if (r = this.e() && this.O(), r === !1) throw this.a("Expected a public identifier");
|
|
374
|
+
this.e();
|
|
375
|
+
}
|
|
376
|
+
if (r !== void 0 || e.b("SYSTEM")) {
|
|
377
|
+
if (this.e(), i = this.s(), i === !1) throw this.a("Expected a system identifier");
|
|
378
|
+
this.e();
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
let a;
|
|
382
|
+
if (e.b("[")) {
|
|
383
|
+
if (a = e.A(/\][\x20\t\r\n]*>/), !e.b("]")) throw this.a("Unclosed internal subset");
|
|
384
|
+
this.e();
|
|
385
|
+
}
|
|
386
|
+
if (!e.b(">")) throw this.a("Unclosed doctype declaration");
|
|
387
|
+
return this.f.preserveDocumentType ? this.j(new N(n, r, i, a), t) : !0;
|
|
388
|
+
}
|
|
389
|
+
B() {
|
|
390
|
+
let { c: e } = this, t = e.d;
|
|
391
|
+
if (!e.b("<")) return !1;
|
|
392
|
+
let n = this.r();
|
|
393
|
+
if (!n) return e.o(t), !1;
|
|
394
|
+
let r = this.I(), i = !!e.b("/>"), a = new M(n, r);
|
|
395
|
+
if (a.parent = this.l, !i) {
|
|
396
|
+
if (!e.b(">")) throw this.a(`Unclosed start tag for element \`${n}\``);
|
|
397
|
+
this.l = a;
|
|
398
|
+
do
|
|
399
|
+
this.L();
|
|
400
|
+
while (this.B() || this.M() || this.K() || this.E() || this.D());
|
|
401
|
+
let t = e.d, r;
|
|
402
|
+
if (!e.b("</") || !(r = this.r()) || r !== n) throw e.o(t), this.a(`Missing end tag for element ${n}`);
|
|
403
|
+
if (this.e(), !e.b(">")) throw this.a(`Unclosed end tag for element ${n}`);
|
|
404
|
+
this.l = a.parent;
|
|
405
|
+
}
|
|
406
|
+
return this.j(a, t);
|
|
407
|
+
}
|
|
408
|
+
u() {
|
|
409
|
+
return this.e(), this.c.b("=") ? (this.e(), !0) : !1;
|
|
410
|
+
}
|
|
411
|
+
w() {
|
|
412
|
+
return this.D() || this.E() || this.e();
|
|
413
|
+
}
|
|
414
|
+
r() {
|
|
415
|
+
return C(this.c.h()) ? this.c.v(S) : ae;
|
|
416
|
+
}
|
|
417
|
+
E() {
|
|
418
|
+
let { c: e } = this, t = e.d;
|
|
419
|
+
if (!e.b("<?")) return !1;
|
|
420
|
+
let n = this.r();
|
|
421
|
+
if (n) {
|
|
422
|
+
if (n.toLowerCase() === "xml") throw e.o(t), this.a("XML declaration isn't allowed here");
|
|
423
|
+
} else throw this.a("Invalid processing instruction");
|
|
424
|
+
if (!this.e()) {
|
|
425
|
+
if (e.b("?>")) return this.j(new ie(n), t);
|
|
426
|
+
throw this.a("Whitespace is required after a processing instruction name");
|
|
427
|
+
}
|
|
428
|
+
let r = e.t("?>");
|
|
429
|
+
if (this.p(r), !e.b("?>")) throw this.a("Unterminated processing instruction");
|
|
430
|
+
return this.j(new ie(n, P(r)), t);
|
|
431
|
+
}
|
|
432
|
+
H() {
|
|
433
|
+
let { c: e } = this, t = e.d;
|
|
434
|
+
for (this.P(); this.w(););
|
|
435
|
+
if (this.N()) for (; this.w(););
|
|
436
|
+
return t < e.d;
|
|
437
|
+
}
|
|
438
|
+
O() {
|
|
439
|
+
let e = this.c.d, t = this.s();
|
|
440
|
+
if (t !== !1 && !/^[-\x20\r\na-zA-Z0-9'()+,./:=?;!*#@$_%]*$/.test(t)) throw this.c.o(e), this.a("Invalid character in public identifier");
|
|
441
|
+
return t;
|
|
442
|
+
}
|
|
443
|
+
C() {
|
|
444
|
+
let { c: e } = this;
|
|
445
|
+
if (!e.b("&")) return !1;
|
|
446
|
+
let t = e.v(w);
|
|
447
|
+
if (e.F() !== ";") throw this.a("Unterminated reference (a reference must end with `;`)");
|
|
448
|
+
let n;
|
|
449
|
+
if (t[0] === "#") {
|
|
450
|
+
let e = t[1] === "x" ? parseInt(t.slice(2), 16) : parseInt(t.slice(1), 10);
|
|
451
|
+
if (isNaN(e)) throw this.a("Invalid character reference");
|
|
452
|
+
if (!E(e)) throw this.a("Character reference resolves to an invalid character");
|
|
453
|
+
n = String.fromCodePoint(e);
|
|
454
|
+
} else if (n = x[t], n === void 0) {
|
|
455
|
+
let { ignoreUndefinedEntities: n, resolveUndefinedEntity: r } = this.f, i = `&${t};`;
|
|
456
|
+
if (r) {
|
|
457
|
+
let e = r(i);
|
|
458
|
+
if (e != null) {
|
|
459
|
+
let t = typeof e;
|
|
460
|
+
if (t !== "string") throw TypeError(`\`resolveUndefinedEntity()\` must return a string, \`null\`, or \`undefined\`, but returned a value of type ${t}`);
|
|
461
|
+
return e;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
if (n) return i;
|
|
465
|
+
throw e.o(-i.length), this.a(`Named entity isn't defined: ${i}`);
|
|
466
|
+
}
|
|
467
|
+
return n;
|
|
468
|
+
}
|
|
469
|
+
s() {
|
|
470
|
+
let { c: e } = this, t = e.b("\"") || e.b("'");
|
|
471
|
+
if (!t) return !1;
|
|
472
|
+
let n = e.t(t);
|
|
473
|
+
if (this.p(n), !e.b(t)) throw this.a("Missing end quote");
|
|
474
|
+
return n;
|
|
475
|
+
}
|
|
476
|
+
e() {
|
|
477
|
+
return !!this.c.v(T);
|
|
478
|
+
}
|
|
479
|
+
P() {
|
|
480
|
+
let { c: e } = this, t = e.d;
|
|
481
|
+
if (!e.b("<?xml")) return !1;
|
|
482
|
+
if (!this.e()) throw this.a("Invalid XML declaration");
|
|
483
|
+
let n = !!e.b("version") && this.u() && this.s();
|
|
484
|
+
if (n === !1) throw this.a("XML version is missing or invalid");
|
|
485
|
+
if (!/^1\.[0-9]+$/.test(n)) throw this.a("Invalid character in version number");
|
|
486
|
+
let r, i;
|
|
487
|
+
if (this.e() && (r = !!e.b("encoding") && this.u() && this.s(), r && this.e(), i = !!e.b("standalone") && this.u() && this.s(), i)) {
|
|
488
|
+
if (i !== "yes" && i !== "no") throw this.a("Only \"yes\" and \"no\" are permitted as values of `standalone`");
|
|
489
|
+
this.e();
|
|
490
|
+
}
|
|
491
|
+
if (!e.b("?>")) throw this.a("Invalid or unclosed XML declaration");
|
|
492
|
+
return this.f.preserveXmlDeclaration ? this.j(new j(n, r || void 0, i || void 0), t) : !0;
|
|
493
|
+
}
|
|
494
|
+
a(e) {
|
|
495
|
+
let { c: t } = this;
|
|
496
|
+
return new re(e, t.d, t.m);
|
|
497
|
+
}
|
|
498
|
+
p(e) {
|
|
499
|
+
let { length: t } = e;
|
|
500
|
+
for (let n = 0; n < t; ++n) {
|
|
501
|
+
let t = e.codePointAt(n);
|
|
502
|
+
if (!E(t)) throw this.c.o(-([...e].length - n)), this.a("Invalid character");
|
|
503
|
+
t > 65535 && (n += 1);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
function P(e) {
|
|
508
|
+
let t = 0;
|
|
509
|
+
for (; (t = e.indexOf("\r", t)) !== -1;) e = e[t + 1] === "\n" ? e.slice(0, t) + e.slice(t + 1) : e.slice(0, t) + "\n" + e.slice(t + 1);
|
|
510
|
+
return e;
|
|
511
|
+
}
|
|
512
|
+
function se(e, t) {
|
|
513
|
+
return new oe(e, t).document;
|
|
514
|
+
}
|
|
515
|
+
var ce = class extends Error {
|
|
516
|
+
constructor(e, t, n) {
|
|
517
|
+
super(e), this.httpStatus = t, this.isCrossOriginRelated = n, this.name = "EndpointError";
|
|
518
|
+
}
|
|
519
|
+
}, le = class extends Error {
|
|
520
|
+
constructor(e, t, n, r, i) {
|
|
521
|
+
super(e), this.requestUrl = t, this.code = n, this.locator = r, this.response = i, this.name = "ServiceExceptionError";
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
function ue(e) {
|
|
525
|
+
if (e.name === "ServiceExceptionError") {
|
|
526
|
+
let t = new le(e.message, e.requestUrl, e.code, e.locator, e.response);
|
|
527
|
+
return t.stack = e.stack, t;
|
|
528
|
+
}
|
|
529
|
+
if (e.name === "EndpointError") {
|
|
530
|
+
let t = new ce(e.message, e.httpStatus, e.isCrossOriginRelated);
|
|
531
|
+
return t.stack = e.stack, t;
|
|
532
|
+
}
|
|
533
|
+
let t = Error(e.message);
|
|
534
|
+
return t.stack = e.stack, t;
|
|
535
|
+
}
|
|
536
|
+
var de = new EventTarget();
|
|
537
|
+
function fe(e, t, n) {
|
|
538
|
+
return new Promise((r, i) => {
|
|
539
|
+
let o = a(), s = {
|
|
540
|
+
requestId: o,
|
|
541
|
+
taskName: e,
|
|
542
|
+
params: n
|
|
543
|
+
};
|
|
544
|
+
t === null ? de.dispatchEvent(new CustomEvent("ogc-client.request", { detail: s })) : t.postMessage(s);
|
|
545
|
+
let c = (e) => {
|
|
546
|
+
e.requestId === o && (t === null ? de.removeEventListener("ogc-client.response", l) : t.removeEventListener("message", u), "error" in e ? i(ue(e.error)) : r(e.response));
|
|
547
|
+
}, l = (e) => c(e.detail), u = (e) => c(e.data);
|
|
548
|
+
t === null ? de.addEventListener("ogc-client.response", l) : t.addEventListener("message", u);
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
var pe = typeof window < "u" && window.Blob && new Blob([atob("KGZ1bmN0aW9uKCkgewogICJ1c2Ugc3RyaWN0IjsKICAvKiEgQHJncm92ZS9wYXJzZS14bWwgdjQuMS4wIHwgSVNDIExpY2Vuc2UgfCBDb3B5cmlnaHQgUnlhbiBHcm92ZSAqLwogIHZhciBfX2RlZlByb3AgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7CiAgdmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOwogIHZhciBfX2dldE93blByb3BOYW1lcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzOwogIHZhciBfX2hhc093blByb3AgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5OwogIHZhciBfX2V4cG9ydCA9ICh0YXJnZXQsIGFsbCkgPT4gewogICAgZm9yICh2YXIgbmFtZSBpbiBhbGwpCiAgICAgIF9fZGVmUHJvcCh0YXJnZXQsIG5hbWUsIHsgZ2V0OiBhbGxbbmFtZV0sIGVudW1lcmFibGU6IHRydWUgfSk7CiAgfTsKICB2YXIgX19jb3B5UHJvcHMgPSAodG8sIGZyb20sIGV4Y2VwdCwgZGVzYykgPT4gewogICAgaWYgKGZyb20gJiYgdHlwZW9mIGZyb20gPT09ICJvYmplY3QiIHx8IHR5cGVvZiBmcm9tID09PSAiZnVuY3Rpb24iKSB7CiAgICAgIGZvciAobGV0IGtleSBvZiBfX2dldE93blByb3BOYW1lcyhmcm9tKSkKICAgICAgICBpZiAoIV9faGFzT3duUHJvcC5jYWxsKHRvLCBrZXkpICYmIGtleSAhPT0gZXhjZXB0KQogICAgICAgICAgX19kZWZQcm9wKHRvLCBrZXksIHsgZ2V0OiAoKSA9PiBmcm9tW2tleV0sIGVudW1lcmFibGU6ICEoZGVzYyA9IF9fZ2V0T3duUHJvcERlc2MoZnJvbSwga2V5KSkgfHwgZGVzYy5lbnVtZXJhYmxlIH0pOwogICAgfQogICAgcmV0dXJuIHRvOwogIH07CiAgdmFyIF9fdG9Db21tb25KUyA9IChtb2QpID0+IF9fY29weVByb3BzKF9fZGVmUHJvcCh7fSwgIl9fZXNNb2R1bGUiLCB7IHZhbHVlOiB0cnVlIH0pLCBtb2QpOwogIHZhciBzcmNfZXhwb3J0cyA9IHt9OwogIF9fZXhwb3J0KHNyY19leHBvcnRzLCB7CiAgICBYbWxDZGF0YTogKCkgPT4gWG1sQ2RhdGEsCiAgICBYbWxDb21tZW50OiAoKSA9PiBYbWxDb21tZW50LAogICAgWG1sRGVjbGFyYXRpb246ICgpID0+IFhtbERlY2xhcmF0aW9uLAogICAgWG1sRG9jdW1lbnQ6ICgpID0+IFhtbERvY3VtZW50LAogICAgWG1sRG9jdW1lbnRUeXBlOiAoKSA9PiBYbWxEb2N1bWVudFR5cGUsCiAgICBYbWxFbGVtZW50OiAoKSA9PiBYbWxFbGVtZW50LAogICAgWG1sRXJyb3I6ICgpID0+IFhtbEVycm9yLAogICAgWG1sTm9kZTogKCkgPT4gWG1sTm9kZSwKICAgIFhtbFByb2Nlc3NpbmdJbnN0cnVjdGlvbjogKCkgPT4gWG1sUHJvY2Vzc2luZ0luc3RydWN0aW9uLAogICAgWG1sVGV4dDogKCkgPT4gWG1sVGV4dCwKICAgIHBhcnNlWG1sOiAoKSA9PiBwYXJzZVhtbAogIH0pOwogIHZhciBicm93c2VyID0gX190b0NvbW1vbkpTKHNyY19leHBvcnRzKTsKICB2YXIgZW1wdHlTdHJpbmcgPSAiIjsKICB2YXIgc3Vycm9nYXRlUGFpciA9IC9bXHVEODAwLVx1REJGRl1bXHVEQzAwLVx1REZGRl0vZzsKICB2YXIgU3RyaW5nU2Nhbm5lciA9IGNsYXNzIHsKICAgIGNvbnN0cnVjdG9yKHN0cmluZykgewogICAgICB0aGlzLmsgPSB0aGlzLnEoc3RyaW5nLCB0cnVlKTsKICAgICAgdGhpcy5kID0gMDsKICAgICAgdGhpcy5sZW5ndGggPSBzdHJpbmcubGVuZ3RoOwogICAgICB0aGlzLm4gPSB0aGlzLmsgIT09IHRoaXMubGVuZ3RoOwogICAgICB0aGlzLm0gPSBzdHJpbmc7CiAgICAgIGlmICh0aGlzLm4pIHsKICAgICAgICBsZXQgY2hhcnNUb0J5dGVzID0gW107CiAgICAgICAgZm9yIChsZXQgYnl0ZUluZGV4ID0gMCwgY2hhckluZGV4ID0gMDsgY2hhckluZGV4IDwgdGhpcy5rOyArK2NoYXJJbmRleCkgewogICAgICAgICAgY2hhcnNUb0J5dGVzW2NoYXJJbmRleF0gPSBieXRlSW5kZXg7CiAgICAgICAgICBieXRlSW5kZXggKz0gc3RyaW5nLmNvZGVQb2ludEF0KGJ5dGVJbmRleCkgPiA2NTUzNSA/IDIgOiAxOwogICAgICAgIH0KICAgICAgICB0aGlzLnkgPSBjaGFyc1RvQnl0ZXM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogV2hldGhlciB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaW5kZXggaXMgYXQgdGhlIGVuZCBvZiB0aGUgaW5wdXQgc3RyaW5nLgogICAgICovCiAgICBnZXQgeigpIHsKICAgICAgcmV0dXJuIHRoaXMuZCA+PSB0aGlzLms7CiAgICB9CiAgICAvLyAtLSBQcm90ZWN0ZWQgTWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIGdpdmVuIHN0cmluZywgd2hpY2ggbWF5IGRpZmZlciBmcm9tCiAgICAgKiB0aGUgYnl0ZSBsZW5ndGggaWYgdGhlIHN0cmluZyBjb250YWlucyBtdWx0aWJ5dGUgY2hhcmFjdGVycy4KICAgICAqLwogICAgcShzdHJpbmcsIG11bHRpQnl0ZVNhZmUgPSB0aGlzLm4pIHsKICAgICAgcmV0dXJuIG11bHRpQnl0ZVNhZmUgPyBzdHJpbmcucmVwbGFjZShzdXJyb2dhdGVQYWlyLCAiXyIpLmxlbmd0aCA6IHN0cmluZy5sZW5ndGg7CiAgICB9CiAgICAvLyAtLSBQdWJsaWMgTWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8qKgogICAgICogQWR2YW5jZXMgdGhlIHNjYW5uZXIgYnkgdGhlIGdpdmVuIG51bWJlciBvZiBjaGFyYWN0ZXJzLCBzdG9wcGluZyBpZiB0aGUgZW5kCiAgICAgKiBvZiB0aGUgc3RyaW5nIGlzIHJlYWNoZWQuCiAgICAgKi8KICAgIGcoY291bnQgPSAxKSB7CiAgICAgIHRoaXMuZCA9IE1hdGgubWluKHRoaXMuaywgdGhpcy5kICsgY291bnQpOwogICAgfQogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBieXRlIGluZGV4IG9mIHRoZSBnaXZlbiBjaGFyYWN0ZXIgaW5kZXggaW4gdGhlIHN0cmluZy4gVGhlIHR3bwogICAgICogbWF5IGRpZmZlciBpbiBzdHJpbmdzIHRoYXQgY29udGFpbiBtdWx0aWJ5dGUgY2hhcmFjdGVycy4KICAgICAqLwogICAgaShjaGFySW5kZXggPSB0aGlzLmQpIHsKICAgICAgdmFyIF9hOwogICAgICByZXR1cm4gdGhpcy5uID8gKF9hID0gdGhpcy55W2NoYXJJbmRleF0pICE9IG51bGwgPyBfYSA6IEluZmluaXR5IDogY2hhckluZGV4OwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhbmQgcmV0dXJucyB0aGUgZ2l2ZW4gbnVtYmVyIG9mIGNoYXJhY3RlcnMgaWYgcG9zc2libGUsIGFkdmFuY2luZwogICAgICogdGhlIHNjYW5uZXIgYW5kIHN0b3BwaW5nIGlmIHRoZSBlbmQgb2YgdGhlIHN0cmluZyBpcyByZWFjaGVkLgogICAgICoKICAgICAqIElmIG5vIGNoYXJhY3RlcnMgY291bGQgYmUgY29uc3VtZWQsIGFuIGVtcHR5IHN0cmluZyB3aWxsIGJlIHJldHVybmVkLgogICAgICovCiAgICBGKGNvdW50ID0gMSkgewogICAgICBsZXQgY2hhcnMgPSB0aGlzLmgoY291bnQpOwogICAgICB0aGlzLmcoY291bnQpOwogICAgICByZXR1cm4gY2hhcnM7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgbWF0Y2ggZm9yIHRoZSBnaXZlbiBzdGlja3kgcmVnZXgsIGFkdmFuY2VzIHRoZSBzY2FubmVyLCB1cGRhdGVzCiAgICAgKiB0aGUgYGxhc3RJbmRleGAgcHJvcGVydHkgb2YgdGhlIHJlZ2V4LCBhbmQgcmV0dXJucyB0aGUgbWF0Y2hpbmcgc3RyaW5nLgogICAgICoKICAgICAqIFRoZSByZWdleCBtdXN0IGhhdmUgYSBzdGlja3kgZmxhZyAoInkiKSBzbyB0aGF0IGl0cyBgbGFzdEluZGV4YCBwcm9wIGNhbiBiZQogICAgICogdXNlZCB0byBhbmNob3IgdGhlIG1hdGNoIGF0IHRoZSBjdXJyZW50IHNjYW5uZXIgcG9zaXRpb24uCiAgICAgKgogICAgICogUmV0dXJucyB0aGUgY29uc3VtZWQgc3RyaW5nLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgY29uc3VtZWQuCiAgICAgKi8KICAgIEcocmVnZXgpIHsKICAgICAgaWYgKCFyZWdleC5zdGlja3kpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ByZWdleGAgbXVzdCBoYXZlIGEgc3RpY2t5IGZsYWcgKCJ5IiknKTsKICAgICAgfQogICAgICByZWdleC5sYXN0SW5kZXggPSB0aGlzLmkoKTsKICAgICAgbGV0IHJlc3VsdCA9IHJlZ2V4LmV4ZWModGhpcy5tKTsKICAgICAgaWYgKHJlc3VsdCA9PT0gbnVsbCB8fCByZXN1bHQubGVuZ3RoID09PSAwKSB7CiAgICAgICAgcmV0dXJuIGVtcHR5U3RyaW5nOwogICAgICB9CiAgICAgIGxldCBtYXRjaCA9IHJlc3VsdFswXTsKICAgICAgdGhpcy5nKHRoaXMucShtYXRjaCkpOwogICAgICByZXR1cm4gbWF0Y2g7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGFuZCByZXR1cm5zIGFsbCBjaGFyYWN0ZXJzIGZvciB3aGljaCB0aGUgZ2l2ZW4gZnVuY3Rpb24gcmV0dXJucyBhCiAgICAgKiB0cnV0aHkgdmFsdWUsIHN0b3BwaW5nIG9uIHRoZSBmaXJzdCBmYWxzeSByZXR1cm4gdmFsdWUgb3IgaWYgdGhlIGVuZCBvZiB0aGUKICAgICAqIGlucHV0IGlzIHJlYWNoZWQuCiAgICAgKi8KICAgIHYoZm4pIHsKICAgICAgbGV0IGNoYXI7CiAgICAgIGxldCBtYXRjaCA9IGVtcHR5U3RyaW5nOwogICAgICB3aGlsZSAoKGNoYXIgPSB0aGlzLmgoKSkgJiYgZm4oY2hhcikpIHsKICAgICAgICBtYXRjaCArPSBjaGFyOwogICAgICAgIHRoaXMuZygpOwogICAgICB9CiAgICAgIHJldHVybiBtYXRjaDsKICAgIH0KICAgIC8qKgogICAgICogQ29uc3VtZXMgdGhlIGdpdmVuIHN0cmluZyBpZiBpdCBleGlzdHMgYXQgdGhlIGN1cnJlbnQgY2hhcmFjdGVyIGluZGV4LCBhbmQKICAgICAqIGFkdmFuY2VzIHRoZSBzY2FubmVyLgogICAgICoKICAgICAqIElmIHRoZSBnaXZlbiBzdHJpbmcgZG9lc24ndCBleGlzdCBhdCB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaW5kZXgsIGFuIGVtcHR5CiAgICAgKiBzdHJpbmcgd2lsbCBiZSByZXR1cm5lZCBhbmQgdGhlIHNjYW5uZXIgd2lsbCBub3QgYmUgYWR2YW5jZWQuCiAgICAgKi8KICAgIFEoc3RyaW5nVG9Db25zdW1lKSB7CiAgICAgIGlmICh0aGlzLmIoc3RyaW5nVG9Db25zdW1lKSkgewogICAgICAgIHJldHVybiBzdHJpbmdUb0NvbnN1bWU7CiAgICAgIH0KICAgICAgaWYgKHRoaXMubikgewogICAgICAgIGxldCB7IGxlbmd0aCB9ID0gc3RyaW5nVG9Db25zdW1lOwogICAgICAgIGxldCBjaGFyTGVuZ3RoVG9NYXRjaCA9IHRoaXMucShzdHJpbmdUb0NvbnN1bWUpOwogICAgICAgIGlmIChjaGFyTGVuZ3RoVG9NYXRjaCAhPT0gbGVuZ3RoICYmIHN0cmluZ1RvQ29uc3VtZSA9PT0gdGhpcy5oKGNoYXJMZW5ndGhUb01hdGNoKSkgewogICAgICAgICAgdGhpcy5nKGNoYXJMZW5ndGhUb01hdGNoKTsKICAgICAgICAgIHJldHVybiBzdHJpbmdUb0NvbnN1bWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBlbXB0eVN0cmluZzsKICAgIH0KICAgIC8qKgogICAgICogRG9lcyB0aGUgc2FtZSB0aGluZyBhcyBgY29uc3VtZVN0cmluZygpYCwgYnV0IGRvZXNuJ3Qgc3VwcG9ydCBjb25zdW1pbmcKICAgICAqIG11bHRpYnl0ZSBjaGFyYWN0ZXJzLiBUaGlzIGNhbiBiZSBmYXN0ZXIgaWYgeW91IG9ubHkgbmVlZCB0byBtYXRjaCBzaW5nbGUKICAgICAqIGJ5dGUgY2hhcmFjdGVycy4KICAgICAqLwogICAgYihzdHJpbmdUb0NvbnN1bWUpIHsKICAgICAgbGV0IHsgbGVuZ3RoIH0gPSBzdHJpbmdUb0NvbnN1bWU7CiAgICAgIGlmICh0aGlzLmgobGVuZ3RoKSA9PT0gc3RyaW5nVG9Db25zdW1lKSB7CiAgICAgICAgdGhpcy5nKGxlbmd0aCk7CiAgICAgICAgcmV0dXJuIHN0cmluZ1RvQ29uc3VtZTsKICAgICAgfQogICAgICByZXR1cm4gZW1wdHlTdHJpbmc7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGNoYXJhY3RlcnMgdW50aWwgdGhlIGdpdmVuIGdsb2JhbCByZWdleCBpcyBtYXRjaGVkLCBhZHZhbmNpbmcgdGhlCiAgICAgKiBzY2FubmVyIHVwIHRvIChidXQgbm90IGJleW9uZCkgdGhlIGJlZ2lubmluZyBvZiB0aGUgbWF0Y2guIElmIHRoZSByZWdleAogICAgICogZG9lc24ndCBtYXRjaCwgbm90aGluZyB3aWxsIGJlIGNvbnN1bWVkLgogICAgICoKICAgICAqIFJldHVybnMgdGhlIGNvbnN1bWVkIHN0cmluZywgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG5vdGhpbmcgd2FzIGNvbnN1bWVkLgogICAgICovCiAgICBBKHJlZ2V4KSB7CiAgICAgIGxldCByZXN0T2ZTdHJpbmcgPSB0aGlzLm0uc2xpY2UodGhpcy5pKCkpOwogICAgICBsZXQgbWF0Y2hCeXRlSW5kZXggPSByZXN0T2ZTdHJpbmcuc2VhcmNoKHJlZ2V4KTsKICAgICAgaWYgKG1hdGNoQnl0ZUluZGV4IDw9IDApIHsKICAgICAgICByZXR1cm4gZW1wdHlTdHJpbmc7CiAgICAgIH0KICAgICAgbGV0IHJlc3VsdCA9IHJlc3RPZlN0cmluZy5zbGljZSgwLCBtYXRjaEJ5dGVJbmRleCk7CiAgICAgIHRoaXMuZyh0aGlzLnEocmVzdWx0KSk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGNoYXJhY3RlcnMgdW50aWwgdGhlIGdpdmVuIHN0cmluZyBpcyBmb3VuZCwgYWR2YW5jaW5nIHRoZSBzY2FubmVyCiAgICAgKiB1cCB0byAoYnV0IG5vdCBiZXlvbmQpIHRoYXQgcG9pbnQuIElmIHRoZSBzdHJpbmcgaXMgbmV2ZXIgZm91bmQsIG5vdGhpbmcKICAgICAqIHdpbGwgYmUgY29uc3VtZWQuCiAgICAgKgogICAgICogUmV0dXJucyB0aGUgY29uc3VtZWQgc3RyaW5nLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgY29uc3VtZWQuCiAgICAgKi8KICAgIHQoc2VhcmNoU3RyaW5nKSB7CiAgICAgIGxldCB7IG06IHN0cmluZyB9ID0gdGhpczsKICAgICAgbGV0IGJ5dGVJbmRleCA9IHRoaXMuaSgpOwogICAgICBsZXQgbWF0Y2hCeXRlSW5kZXggPSBzdHJpbmcuaW5kZXhPZihzZWFyY2hTdHJpbmcsIGJ5dGVJbmRleCk7CiAgICAgIGlmIChtYXRjaEJ5dGVJbmRleCA8PSAwKSB7CiAgICAgICAgcmV0dXJuIGVtcHR5U3RyaW5nOwogICAgICB9CiAgICAgIGxldCByZXN1bHQgPSBzdHJpbmcuc2xpY2UoYnl0ZUluZGV4LCBtYXRjaEJ5dGVJbmRleCk7CiAgICAgIHRoaXMuZyh0aGlzLnEocmVzdWx0KSk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGdpdmVuIG51bWJlciBvZiBjaGFyYWN0ZXJzIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IGNoYXJhY3RlcgogICAgICogaW5kZXgsIHdpdGhvdXQgYWR2YW5jaW5nIHRoZSBzY2FubmVyIGFuZCB3aXRob3V0IGV4Y2VlZGluZyB0aGUgZW5kIG9mIHRoZQogICAgICogaW5wdXQgc3RyaW5nLgogICAgICovCiAgICBoKGNvdW50ID0gMSkgewogICAgICBsZXQgeyBkOiBjaGFySW5kZXgsIG46IG11bHRpQnl0ZU1vZGUsIG06IHN0cmluZyB9ID0gdGhpczsKICAgICAgaWYgKG11bHRpQnl0ZU1vZGUpIHsKICAgICAgICBpZiAoY2hhckluZGV4ID49IHRoaXMuaykgewogICAgICAgICAgcmV0dXJuIGVtcHR5U3RyaW5nOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RyaW5nLnNsaWNlKAogICAgICAgICAgdGhpcy5pKGNoYXJJbmRleCksCiAgICAgICAgICB0aGlzLmkoY2hhckluZGV4ICsgY291bnQpCiAgICAgICAgKTsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nLnNsaWNlKGNoYXJJbmRleCwgY2hhckluZGV4ICsgY291bnQpOwogICAgfQogICAgLyoqCiAgICAgKiBSZXNldHMgdGhlIHNjYW5uZXIgcG9zaXRpb24gdG8gdGhlIGdpdmVuIGNoYXJhY3RlciBfaW5kZXhfLCBvciB0byB0aGUgc3RhcnQKICAgICAqIG9mIHRoZSBpbnB1dCBzdHJpbmcgaWYgbm8gaW5kZXggaXMgZ2l2ZW4uCiAgICAgKgogICAgICogSWYgX2luZGV4XyBpcyBuZWdhdGl2ZSwgdGhlIHNjYW5uZXIgcG9zaXRpb24gd2lsbCBiZSBtb3ZlZCBiYWNrd2FyZCBieSB0aGF0CiAgICAgKiBtYW55IGNoYXJhY3RlcnMsIHN0b3BwaW5nIGlmIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZyBpcyByZWFjaGVkLgogICAgICovCiAgICBvKGluZGV4ID0gMCkgewogICAgICB0aGlzLmQgPSBpbmRleCA+PSAwID8gTWF0aC5taW4odGhpcy5rLCBpbmRleCkgOiBNYXRoLm1heCgwLCB0aGlzLmQgKyBpbmRleCk7CiAgICB9CiAgfTsKICB2YXIgYXR0VmFsdWVDaGFyRG91YmxlUXVvdGUgPSAvW14iJjxdKy95OwogIHZhciBhdHRWYWx1ZUNoYXJTaW5nbGVRdW90ZSA9IC9bXicmPF0rL3k7CiAgdmFyIGF0dFZhbHVlTm9ybWFsaXplZFdoaXRlc3BhY2UgPSAvXHJcbnxbXG5cclx0XS9nOwogIHZhciBlbmRDaGFyRGF0YSA9IC88fCZ8XV0+LzsKICB2YXIgcHJlZGVmaW5lZEVudGl0aWVzID0gT2JqZWN0LmZyZWV6ZShPYmplY3QuYXNzaWduKC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpLCB7CiAgICBhbXA6ICImIiwKICAgIGFwb3M6ICInIiwKICAgIGd0OiAiPiIsCiAgICBsdDogIjwiLAogICAgcXVvdDogJyInCiAgfSkpOwogIGZ1bmN0aW9uIGlzTmFtZUNoYXIoY2hhcikgewogICAgbGV0IGNwID0gZ2V0Q29kZVBvaW50KGNoYXIpOwogICAgcmV0dXJuIGNwID49IDk3ICYmIGNwIDw9IDEyMiB8fCBjcCA+PSA2NSAmJiBjcCA8PSA5MCB8fCBjcCA+PSA0OCAmJiBjcCA8PSA1NyB8fCBjcCA9PT0gNDUgfHwgY3AgPT09IDQ2IHx8IGNwID09PSAxODMgfHwgY3AgPj0gNzY4ICYmIGNwIDw9IDg3OSB8fCBjcCA+PSA4MjU1ICYmIGNwIDw9IDgyNTYgfHwgaXNOYW1lU3RhcnRDaGFyKGNoYXIsIGNwKTsKICB9CiAgZnVuY3Rpb24gaXNOYW1lU3RhcnRDaGFyKGNoYXIsIGNwID0gZ2V0Q29kZVBvaW50KGNoYXIpKSB7CiAgICByZXR1cm4gY3AgPj0gOTcgJiYgY3AgPD0gMTIyIHx8IGNwID49IDY1ICYmIGNwIDw9IDkwIHx8IGNwID09PSA1OCB8fCBjcCA9PT0gOTUgfHwgY3AgPj0gMTkyICYmIGNwIDw9IDIxNCB8fCBjcCA+PSAyMTYgJiYgY3AgPD0gMjQ2IHx8IGNwID49IDI0OCAmJiBjcCA8PSA3NjcgfHwgY3AgPj0gODgwICYmIGNwIDw9IDg5MyB8fCBjcCA+PSA4OTUgJiYgY3AgPD0gODE5MSB8fCBjcCA+PSA4MjA0ICYmIGNwIDw9IDgyMDUgfHwgY3AgPj0gODMwNCAmJiBjcCA8PSA4NTkxIHx8IGNwID49IDExMjY0ICYmIGNwIDw9IDEyMjcxIHx8IGNwID49IDEyMjg5ICYmIGNwIDw9IDU1Mjk1IHx8IGNwID49IDYzNzQ0ICYmIGNwIDw9IDY0OTc1IHx8IGNwID49IDY1MDA4ICYmIGNwIDw9IDY1NTMzIHx8IGNwID49IDY1NTM2ICYmIGNwIDw9IDk4MzAzOTsKICB9CiAgZnVuY3Rpb24gaXNSZWZlcmVuY2VDaGFyKGNoYXIpIHsKICAgIHJldHVybiBjaGFyID09PSAiIyIgfHwgaXNOYW1lQ2hhcihjaGFyKTsKICB9CiAgZnVuY3Rpb24gaXNXaGl0ZXNwYWNlKGNoYXIpIHsKICAgIGxldCBjcCA9IGdldENvZGVQb2ludChjaGFyKTsKICAgIHJldHVybiBjcCA9PT0gMzIgfHwgY3AgPT09IDkgfHwgY3AgPT09IDEwIHx8IGNwID09PSAxMzsKICB9CiAgZnVuY3Rpb24gaXNYbWxDb2RlUG9pbnQoY3ApIHsKICAgIHJldHVybiBjcCA9PT0gOSB8fCBjcCA9PT0gMTAgfHwgY3AgPT09IDEzIHx8IGNwID49IDMyICYmIGNwIDw9IDU1Mjk1IHx8IGNwID49IDU3MzQ0ICYmIGNwIDw9IDY1NTMzIHx8IGNwID49IDY1NTM2ICYmIGNwIDw9IDExMTQxMTE7CiAgfQogIGZ1bmN0aW9uIGdldENvZGVQb2ludChjaGFyKSB7CiAgICByZXR1cm4gY2hhci5jb2RlUG9pbnRBdCgwKSB8fCAtMTsKICB9CiAgdmFyIF9YbWxOb2RlID0gY2xhc3MgewogICAgY29uc3RydWN0b3IoKSB7CiAgICAgIHRoaXMucGFyZW50ID0gbnVsbDsKICAgICAgdGhpcy5zdGFydCA9IC0xOwogICAgICB0aGlzLmVuZCA9IC0xOwogICAgfQogICAgLyoqCiAgICAgKiBEb2N1bWVudCB0aGF0IGNvbnRhaW5zIHRoaXMgbm9kZSwgb3IgYG51bGxgIGlmIHRoaXMgbm9kZSBpcyBub3QgYXNzb2NpYXRlZAogICAgICogd2l0aCBhIGRvY3VtZW50LgogICAgICovCiAgICBnZXQgZG9jdW1lbnQoKSB7CiAgICAgIHZhciBfYSwgX2I7CiAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLnBhcmVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9hLmRvY3VtZW50KSAhPSBudWxsID8gX2IgOiBudWxsOwogICAgfQogICAgLyoqCiAgICAgKiBXaGV0aGVyIHRoaXMgbm9kZSBpcyB0aGUgcm9vdCBub2RlIG9mIHRoZSBkb2N1bWVudCAoYWxzbyBrbm93biBhcyB0aGUKICAgICAqIGRvY3VtZW50IGVsZW1lbnQpLgogICAgICovCiAgICBnZXQgaXNSb290Tm9kZSgpIHsKICAgICAgcmV0dXJuIHRoaXMucGFyZW50ICE9PSBudWxsICYmIHRoaXMucGFyZW50ID09PSB0aGlzLmRvY3VtZW50ICYmIHRoaXMudHlwZSA9PT0gX1htbE5vZGUuVFlQRV9FTEVNRU5UOwogICAgfQogICAgLyoqCiAgICAgKiBXaGV0aGVyIHdoaXRlc3BhY2Ugc2hvdWxkIGJlIHByZXNlcnZlZCBpbiB0aGUgY29udGVudCBvZiB0aGlzIGVsZW1lbnQgYW5kCiAgICAgKiBpdHMgY2hpbGRyZW4uCiAgICAgKgogICAgICogVGhpcyBpcyBpbmZsdWVuY2VkIGJ5IHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lhbCBgeG1sOnNwYWNlYCBhdHRyaWJ1dGUsIGFuZAogICAgICogd2lsbCBiZSBgdHJ1ZWAgZm9yIGFueSBub2RlIHdob3NlIGB4bWw6c3BhY2VgIGF0dHJpYnV0ZSBpcyBzZXQgdG8KICAgICAqICJwcmVzZXJ2ZSIuIElmIGEgbm9kZSBoYXMgbm8gc3VjaCBhdHRyaWJ1dGUsIGl0IHdpbGwgaW5oZXJpdCB0aGUgdmFsdWUgb2YKICAgICAqIHRoZSBuZWFyZXN0IGFuY2VzdG9yIHRoYXQgZG9lcyAoaWYgYW55KS4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI3NlYy13aGl0ZS1zcGFjZQogICAgICovCiAgICBnZXQgcHJlc2VydmVXaGl0ZXNwYWNlKCkgewogICAgICB2YXIgX2E7CiAgICAgIHJldHVybiAhISgoX2EgPSB0aGlzLnBhcmVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9hLnByZXNlcnZlV2hpdGVzcGFjZSk7CiAgICB9CiAgICAvKioKICAgICAqIFR5cGUgb2YgdGhpcyBub2RlLgogICAgICoKICAgICAqIFRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIGEgc3RyaW5nIHRoYXQgbWF0Y2hlcyBvbmUgb2YgdGhlIHN0YXRpYwogICAgICogYFRZUEVfKmAgcHJvcGVydGllcyBvbiB0aGUgYFhtbE5vZGVgIGNsYXNzIChlLmcuIGBUWVBFX0VMRU1FTlRgLAogICAgICogYFRZUEVfVEVYVGAsIGV0Yy4pLgogICAgICoKICAgICAqIFRoZSBgWG1sTm9kZWAgY2xhc3MgaXRzZWxmIGlzIGEgYmFzZSBjbGFzcyBhbmQgZG9lc24ndCBoYXZlIGl0cyBvd24gdHlwZQogICAgICogbmFtZS4KICAgICAqLwogICAgZ2V0IHR5cGUoKSB7CiAgICAgIHJldHVybiAiIjsKICAgIH0KICAgIC8qKgogICAgICogUmV0dXJucyBhIEpTT04tc2VyaWFsaXphYmxlIG9iamVjdCByZXByZXNlbnRpbmcgdGhpcyBub2RlLCBtaW51cyBwcm9wZXJ0aWVzCiAgICAgKiB0aGF0IGNvdWxkIHJlc3VsdCBpbiBjaXJjdWxhciByZWZlcmVuY2VzLgogICAgICovCiAgICB0b0pTT04oKSB7CiAgICAgIGxldCBqc29uID0gewogICAgICAgIHR5cGU6IHRoaXMudHlwZQogICAgICB9OwogICAgICBpZiAodGhpcy5pc1Jvb3ROb2RlKSB7CiAgICAgICAganNvbi5pc1Jvb3ROb2RlID0gdHJ1ZTsKICAgICAgfQogICAgICBpZiAodGhpcy5wcmVzZXJ2ZVdoaXRlc3BhY2UpIHsKICAgICAgICBqc29uLnByZXNlcnZlV2hpdGVzcGFjZSA9IHRydWU7CiAgICAgIH0KICAgICAgaWYgKHRoaXMuc3RhcnQgIT09IC0xKSB7CiAgICAgICAganNvbi5zdGFydCA9IHRoaXMuc3RhcnQ7CiAgICAgICAganNvbi5lbmQgPSB0aGlzLmVuZDsKICAgICAgfQogICAgICByZXR1cm4ganNvbjsKICAgIH0KICB9OwogIHZhciBYbWxOb2RlID0gX1htbE5vZGU7CiAgWG1sTm9kZS5UWVBFX0NEQVRBID0gImNkYXRhIjsKICBYbWxOb2RlLlRZUEVfQ09NTUVOVCA9ICJjb21tZW50IjsKICBYbWxOb2RlLlRZUEVfRE9DVU1FTlQgPSAiZG9jdW1lbnQiOwogIFhtbE5vZGUuVFlQRV9ET0NVTUVOVF9UWVBFID0gImRvY3R5cGUiOwogIFhtbE5vZGUuVFlQRV9FTEVNRU5UID0gImVsZW1lbnQiOwogIFhtbE5vZGUuVFlQRV9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OID0gInBpIjsKICBYbWxOb2RlLlRZUEVfVEVYVCA9ICJ0ZXh0IjsKICBYbWxOb2RlLlRZUEVfWE1MX0RFQ0xBUkFUSU9OID0gInhtbGRlY2wiOwogIHZhciBYbWxUZXh0ID0gY2xhc3MgZXh0ZW5kcyBYbWxOb2RlIHsKICAgIGNvbnN0cnVjdG9yKHRleHQgPSAiIikgewogICAgICBzdXBlcigpOwogICAgICB0aGlzLnRleHQgPSB0ZXh0OwogICAgfQogICAgZ2V0IHR5cGUoKSB7CiAgICAgIHJldHVybiBYbWxOb2RlLlRZUEVfVEVYVDsKICAgIH0KICAgIHRvSlNPTigpIHsKICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oWG1sTm9kZS5wcm90b3R5cGUudG9KU09OLmNhbGwodGhpcyksIHsKICAgICAgICB0ZXh0OiB0aGlzLnRleHQKICAgICAgfSk7CiAgICB9CiAgfTsKICB2YXIgWG1sQ2RhdGEgPSBjbGFzcyBleHRlbmRzIFhtbFRleHQgewogICAgZ2V0IHR5cGUoKSB7CiAgICAgIHJldHVybiBYbWxOb2RlLlRZUEVfQ0RBVEE7CiAgICB9CiAgfTsKICB2YXIgWG1sQ29tbWVudCA9IGNsYXNzIGV4dGVuZHMgWG1sTm9kZSB7CiAgICBjb25zdHJ1Y3Rvcihjb250ZW50ID0gIiIpIHsKICAgICAgc3VwZXIoKTsKICAgICAgdGhpcy5jb250ZW50ID0gY29udGVudDsKICAgIH0KICAgIGdldCB0eXBlKCkgewogICAgICByZXR1cm4gWG1sTm9kZS5UWVBFX0NPTU1FTlQ7CiAgICB9CiAgICB0b0pTT04oKSB7CiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFhtbE5vZGUucHJvdG90eXBlLnRvSlNPTi5jYWxsKHRoaXMpLCB7CiAgICAgICAgY29udGVudDogdGhpcy5jb250ZW50CiAgICAgIH0pOwogICAgfQogIH07CiAgdmFyIFhtbERlY2xhcmF0aW9uID0gY2xhc3MgZXh0ZW5kcyBYbWxOb2RlIHsKICAgIGNvbnN0cnVjdG9yKHZlcnNpb24sIGVuY29kaW5nLCBzdGFuZGFsb25lKSB7CiAgICAgIHN1cGVyKCk7CiAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247CiAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZyAhPSBudWxsID8gZW5jb2RpbmcgOiBudWxsOwogICAgICB0aGlzLnN0YW5kYWxvbmUgPSBzdGFuZGFsb25lICE9IG51bGwgPyBzdGFuZGFsb25lIDogbnVsbDsKICAgIH0KICAgIGdldCB0eXBlKCkgewogICAgICByZXR1cm4gWG1sTm9kZS5UWVBFX1hNTF9ERUNMQVJBVElPTjsKICAgIH0KICAgIHRvSlNPTigpIHsKICAgICAgbGV0IGpzb24gPSBYbWxOb2RlLnByb3RvdHlwZS50b0pTT04uY2FsbCh0aGlzKTsKICAgICAganNvbi52ZXJzaW9uID0gdGhpcy52ZXJzaW9uOwogICAgICBmb3IgKGxldCBrZXkgb2YgWyJlbmNvZGluZyIsICJzdGFuZGFsb25lIl0pIHsKICAgICAgICBpZiAodGhpc1trZXldICE9PSBudWxsKSB7CiAgICAgICAgICBqc29uW2tleV0gPSB0aGlzW2tleV07CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBqc29uOwogICAgfQogIH07CiAgdmFyIFhtbEVsZW1lbnQgPSBjbGFzcyBleHRlbmRzIFhtbE5vZGUgewogICAgY29uc3RydWN0b3IobmFtZSwgYXR0cmlidXRlcyA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpLCBjaGlsZHJlbiA9IFtdKSB7CiAgICAgIHN1cGVyKCk7CiAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgIHRoaXMuYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXM7CiAgICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjsKICAgIH0KICAgIC8qKgogICAgICogV2hldGhlciB0aGlzIGVsZW1lbnQgaXMgZW1wdHkgKG1lYW5pbmcgaXQgaGFzIG5vIGNoaWxkcmVuKS4KICAgICAqLwogICAgZ2V0IGlzRW1wdHkoKSB7CiAgICAgIHJldHVybiB0aGlzLmNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgIH0KICAgIGdldCBwcmVzZXJ2ZVdoaXRlc3BhY2UoKSB7CiAgICAgIGxldCBub2RlID0gdGhpczsKICAgICAgd2hpbGUgKG5vZGUgaW5zdGFuY2VvZiBYbWxFbGVtZW50KSB7CiAgICAgICAgaWYgKCJ4bWw6c3BhY2UiIGluIG5vZGUuYXR0cmlidXRlcykgewogICAgICAgICAgcmV0dXJuIG5vZGUuYXR0cmlidXRlc1sieG1sOnNwYWNlIl0gPT09ICJwcmVzZXJ2ZSI7CiAgICAgICAgfQogICAgICAgIG5vZGUgPSBub2RlLnBhcmVudDsKICAgICAgfQogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICAvKioKICAgICAqIFRleHQgY29udGVudCBvZiB0aGlzIGVsZW1lbnQgYW5kIGFsbCBpdHMgZGVzY2VuZGFudHMuCiAgICAgKi8KICAgIGdldCB0ZXh0KCkgewogICAgICByZXR1cm4gdGhpcy5jaGlsZHJlbi5tYXAoKGNoaWxkKSA9PiAidGV4dCIgaW4gY2hpbGQgPyBjaGlsZC50ZXh0IDogIiIpLmpvaW4oIiIpOwogICAgfQogICAgZ2V0IHR5cGUoKSB7CiAgICAgIHJldHVybiBYbWxOb2RlLlRZUEVfRUxFTUVOVDsKICAgIH0KICAgIHRvSlNPTigpIHsKICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oWG1sTm9kZS5wcm90b3R5cGUudG9KU09OLmNhbGwodGhpcyksIHsKICAgICAgICBuYW1lOiB0aGlzLm5hbWUsCiAgICAgICAgYXR0cmlidXRlczogdGhpcy5hdHRyaWJ1dGVzLAogICAgICAgIGNoaWxkcmVuOiB0aGlzLmNoaWxkcmVuLm1hcCgoY2hpbGQpID0+IGNoaWxkLnRvSlNPTigpKQogICAgICB9KTsKICAgIH0KICB9OwogIHZhciBYbWxEb2N1bWVudCA9IGNsYXNzIGV4dGVuZHMgWG1sTm9kZSB7CiAgICBjb25zdHJ1Y3RvcihjaGlsZHJlbiA9IFtdKSB7CiAgICAgIHN1cGVyKCk7CiAgICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjsKICAgIH0KICAgIGdldCBkb2N1bWVudCgpIHsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIFJvb3QgZWxlbWVudCBvZiB0aGlzIGRvY3VtZW50LCBvciBgbnVsbGAgaWYgdGhpcyBkb2N1bWVudCBpcyBlbXB0eS4KICAgICAqLwogICAgZ2V0IHJvb3QoKSB7CiAgICAgIGZvciAobGV0IGNoaWxkIG9mIHRoaXMuY2hpbGRyZW4pIHsKICAgICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBYbWxFbGVtZW50KSB7CiAgICAgICAgICByZXR1cm4gY2hpbGQ7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgLyoqCiAgICAgKiBUZXh0IGNvbnRlbnQgb2YgdGhpcyBkb2N1bWVudCBhbmQgYWxsIGl0cyBkZXNjZW5kYW50cy4KICAgICAqLwogICAgZ2V0IHRleHQoKSB7CiAgICAgIHJldHVybiB0aGlzLmNoaWxkcmVuLm1hcCgoY2hpbGQpID0+ICJ0ZXh0IiBpbiBjaGlsZCA/IGNoaWxkLnRleHQgOiAiIikuam9pbigiIik7CiAgICB9CiAgICBnZXQgdHlwZSgpIHsKICAgICAgcmV0dXJuIFhtbE5vZGUuVFlQRV9ET0NVTUVOVDsKICAgIH0KICAgIHRvSlNPTigpIHsKICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oWG1sTm9kZS5wcm90b3R5cGUudG9KU09OLmNhbGwodGhpcyksIHsKICAgICAgICBjaGlsZHJlbjogdGhpcy5jaGlsZHJlbi5tYXAoKGNoaWxkKSA9PiBjaGlsZC50b0pTT04oKSkKICAgICAgfSk7CiAgICB9CiAgfTsKICB2YXIgWG1sRG9jdW1lbnRUeXBlID0gY2xhc3MgZXh0ZW5kcyBYbWxOb2RlIHsKICAgIGNvbnN0cnVjdG9yKG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgaW50ZXJuYWxTdWJzZXQpIHsKICAgICAgc3VwZXIoKTsKICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgdGhpcy5wdWJsaWNJZCA9IHB1YmxpY0lkICE9IG51bGwgPyBwdWJsaWNJZCA6IG51bGw7CiAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZCAhPSBudWxsID8gc3lzdGVtSWQgOiBudWxsOwogICAgICB0aGlzLmludGVybmFsU3Vic2V0ID0gaW50ZXJuYWxTdWJzZXQgIT0gbnVsbCA/IGludGVybmFsU3Vic2V0IDogbnVsbDsKICAgIH0KICAgIGdldCB0eXBlKCkgewogICAgICByZXR1cm4gWG1sTm9kZS5UWVBFX0RPQ1VNRU5UX1RZUEU7CiAgICB9CiAgICB0b0pTT04oKSB7CiAgICAgIGxldCBqc29uID0gWG1sTm9kZS5wcm90b3R5cGUudG9KU09OLmNhbGwodGhpcyk7CiAgICAgIGpzb24ubmFtZSA9IHRoaXMubmFtZTsKICAgICAgZm9yIChsZXQga2V5IG9mIFsicHVibGljSWQiLCAic3lzdGVtSWQiLCAiaW50ZXJuYWxTdWJzZXQiXSkgewogICAgICAgIGlmICh0aGlzW2tleV0gIT09IG51bGwpIHsKICAgICAgICAgIGpzb25ba2V5XSA9IHRoaXNba2V5XTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIGpzb247CiAgICB9CiAgfTsKICB2YXIgWG1sRXJyb3IgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIGNoYXJJbmRleCwgeG1sKSB7CiAgICAgIGxldCBjb2x1bW4gPSAxOwogICAgICBsZXQgZXhjZXJwdCA9ICIiOwogICAgICBsZXQgbGluZSA9IDE7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hhckluZGV4OyArK2kpIHsKICAgICAgICBsZXQgY2hhciA9IHhtbFtpXTsKICAgICAgICBpZiAoY2hhciA9PT0gIlxuIikgewogICAgICAgICAgY29sdW1uID0gMTsKICAgICAgICAgIGV4Y2VycHQgPSAiIjsKICAgICAgICAgIGxpbmUgKz0gMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY29sdW1uICs9IDE7CiAgICAgICAgICBleGNlcnB0ICs9IGNoYXI7CiAgICAgICAgfQogICAgICB9CiAgICAgIGxldCBlb2wgPSB4bWwuaW5kZXhPZigiXG4iLCBjaGFySW5kZXgpOwogICAgICBleGNlcnB0ICs9IGVvbCA9PT0gLTEgPyB4bWwuc2xpY2UoY2hhckluZGV4KSA6IHhtbC5zbGljZShjaGFySW5kZXgsIGVvbCk7CiAgICAgIGxldCBleGNlcnB0U3RhcnQgPSAwOwogICAgICBpZiAoZXhjZXJwdC5sZW5ndGggPiA1MCkgewogICAgICAgIGlmIChjb2x1bW4gPCA0MCkgewogICAgICAgICAgZXhjZXJwdCA9IGV4Y2VycHQuc2xpY2UoMCwgNTApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBleGNlcnB0U3RhcnQgPSBjb2x1bW4gLSAyMDsKICAgICAgICAgIGV4Y2VycHQgPSBleGNlcnB0LnNsaWNlKGV4Y2VycHRTdGFydCwgY29sdW1uICsgMzApOwogICAgICAgIH0KICAgICAgfQogICAgICBzdXBlcigKICAgICAgICBgJHttZXNzYWdlfSAobGluZSAke2xpbmV9LCBjb2x1bW4gJHtjb2x1bW59KQogICR7ZXhjZXJwdH0KYCArICIgIi5yZXBlYXQoY29sdW1uIC0gZXhjZXJwdFN0YXJ0ICsgMSkgKyAiXlxuIgogICAgICApOwogICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKICAgICAgdGhpcy5leGNlcnB0ID0gZXhjZXJwdDsKICAgICAgdGhpcy5saW5lID0gbGluZTsKICAgICAgdGhpcy5uYW1lID0gIlhtbEVycm9yIjsKICAgICAgdGhpcy5wb3MgPSBjaGFySW5kZXg7CiAgICB9CiAgfTsKICB2YXIgWG1sUHJvY2Vzc2luZ0luc3RydWN0aW9uID0gY2xhc3MgZXh0ZW5kcyBYbWxOb2RlIHsKICAgIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnQgPSAiIikgewogICAgICBzdXBlcigpOwogICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50OwogICAgfQogICAgZ2V0IHR5cGUoKSB7CiAgICAgIHJldHVybiBYbWxOb2RlLlRZUEVfUFJPQ0VTU0lOR19JTlNUUlVDVElPTjsKICAgIH0KICAgIHRvSlNPTigpIHsKICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oWG1sTm9kZS5wcm90b3R5cGUudG9KU09OLmNhbGwodGhpcyksIHsKICAgICAgICBuYW1lOiB0aGlzLm5hbWUsCiAgICAgICAgY29udGVudDogdGhpcy5jb250ZW50CiAgICAgIH0pOwogICAgfQogIH07CiAgdmFyIGVtcHR5U3RyaW5nMiA9ICIiOwogIHZhciBQYXJzZXIgPSBjbGFzcyB7CiAgICAvKioKICAgICAqIEBwYXJhbSB4bWwgWE1MIHN0cmluZyB0byBwYXJzZS4KICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcnNlciBvcHRpb25zLgogICAgICovCiAgICBjb25zdHJ1Y3Rvcih4bWwsIG9wdGlvbnMgPSB7fSkgewogICAgICBsZXQgZG9jID0gdGhpcy5kb2N1bWVudCA9IG5ldyBYbWxEb2N1bWVudCgpOwogICAgICBsZXQgc2Nhbm5lciA9IHRoaXMuYyA9IG5ldyBTdHJpbmdTY2FubmVyKHhtbCk7CiAgICAgIHRoaXMubCA9IGRvYzsKICAgICAgdGhpcy5mID0gb3B0aW9uczsKICAgICAgaWYgKHRoaXMuZi5pbmNsdWRlT2Zmc2V0cykgewogICAgICAgIGRvYy5zdGFydCA9IDA7CiAgICAgICAgZG9jLmVuZCA9IHhtbC5sZW5ndGg7CiAgICAgIH0KICAgICAgc2Nhbm5lci5iKCJcdUZFRkYiKTsKICAgICAgdGhpcy5IKCk7CiAgICAgIGlmICghdGhpcy5CKCkpIHsKICAgICAgICB0aHJvdyB0aGlzLmEoIlJvb3QgZWxlbWVudCBpcyBtaXNzaW5nIG9yIGludmFsaWQiKTsKICAgICAgfQogICAgICB3aGlsZSAodGhpcy53KCkpIHsKICAgICAgfQogICAgICBpZiAoIXNjYW5uZXIueikgewogICAgICAgIHRocm93IHRoaXMuYSgiRXh0cmEgY29udGVudCBhdCB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudCIpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIEFkZHMgdGhlIGdpdmVuIGBYbWxOb2RlYCBhcyBhIGNoaWxkIG9mIGB0aGlzLmN1cnJlbnROb2RlYC4KICAgICAqLwogICAgaihub2RlLCBjaGFySW5kZXgpIHsKICAgICAgbm9kZS5wYXJlbnQgPSB0aGlzLmw7CiAgICAgIGlmICh0aGlzLmYuaW5jbHVkZU9mZnNldHMpIHsKICAgICAgICBub2RlLnN0YXJ0ID0gdGhpcy5jLmkoY2hhckluZGV4KTsKICAgICAgICBub2RlLmVuZCA9IHRoaXMuYy5pKCk7CiAgICAgIH0KICAgICAgdGhpcy5sLmNoaWxkcmVuLnB1c2gobm9kZSk7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgLyoqCiAgICAgKiBBZGRzIHRoZSBnaXZlbiBfdGV4dF8gdG8gdGhlIGRvY3VtZW50LCBlaXRoZXIgYnkgYXBwZW5kaW5nIGl0IHRvIGEKICAgICAqIHByZWNlZGluZyBgWG1sVGV4dGAgbm9kZSAoaWYgcG9zc2libGUpIG9yIGJ5IGNyZWF0aW5nIGEgbmV3IGBYbWxUZXh0YCBub2RlLgogICAgICovCiAgICB4KHRleHQsIGNoYXJJbmRleCkgewogICAgICBsZXQgeyBjaGlsZHJlbiB9ID0gdGhpcy5sOwogICAgICBsZXQgeyBsZW5ndGggfSA9IGNoaWxkcmVuOwogICAgICB0ZXh0ID0gbm9ybWFsaXplTGluZUJyZWFrcyh0ZXh0KTsKICAgICAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgICBsZXQgcHJldk5vZGUgPSBjaGlsZHJlbltsZW5ndGggLSAxXTsKICAgICAgICBpZiAoKHByZXZOb2RlID09IG51bGwgPyB2b2lkIDAgOiBwcmV2Tm9kZS50eXBlKSA9PT0gWG1sTm9kZS5UWVBFX1RFWFQpIHsKICAgICAgICAgIGxldCB0ZXh0Tm9kZSA9IHByZXZOb2RlOwogICAgICAgICAgdGV4dE5vZGUudGV4dCArPSB0ZXh0OwogICAgICAgICAgaWYgKHRoaXMuZi5pbmNsdWRlT2Zmc2V0cykgewogICAgICAgICAgICB0ZXh0Tm9kZS5lbmQgPSB0aGlzLmMuaSgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB0aGlzLmoobmV3IFhtbFRleHQodGV4dCksIGNoYXJJbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGVsZW1lbnQgYXR0cmlidXRlcy4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI3NlYy1zdGFydHRhZ3MKICAgICAqLwogICAgSSgpIHsKICAgICAgbGV0IGF0dHJpYnV0ZXMgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKTsKICAgICAgd2hpbGUgKHRoaXMuZSgpKSB7CiAgICAgICAgbGV0IGF0dHJOYW1lID0gdGhpcy5yKCk7CiAgICAgICAgaWYgKCFhdHRyTmFtZSkgewogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGxldCBhdHRyVmFsdWUgPSB0aGlzLnUoKSAmJiB0aGlzLkooKTsKICAgICAgICBpZiAoYXR0clZhbHVlID09PSBmYWxzZSkgewogICAgICAgICAgdGhyb3cgdGhpcy5hKCJBdHRyaWJ1dGUgdmFsdWUgZXhwZWN0ZWQiKTsKICAgICAgICB9CiAgICAgICAgaWYgKGF0dHJOYW1lIGluIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgIHRocm93IHRoaXMuYShgRHVwbGljYXRlIGF0dHJpYnV0ZTogJHthdHRyTmFtZX1gKTsKICAgICAgICB9CiAgICAgICAgaWYgKGF0dHJOYW1lID09PSAieG1sOnNwYWNlIiAmJiBhdHRyVmFsdWUgIT09ICJkZWZhdWx0IiAmJiBhdHRyVmFsdWUgIT09ICJwcmVzZXJ2ZSIpIHsKICAgICAgICAgIHRocm93IHRoaXMuYSgnVmFsdWUgb2YgdGhlIGB4bWw6c3BhY2VgIGF0dHJpYnV0ZSBtdXN0IGJlICJkZWZhdWx0IiBvciAicHJlc2VydmUiJyk7CiAgICAgICAgfQogICAgICAgIGF0dHJpYnV0ZXNbYXR0ck5hbWVdID0gYXR0clZhbHVlOwogICAgICB9CiAgICAgIGlmICh0aGlzLmYuc29ydEF0dHJpYnV0ZXMpIHsKICAgICAgICBsZXQgYXR0ck5hbWVzID0gT2JqZWN0LmtleXMoYXR0cmlidXRlcykuc29ydCgpOwogICAgICAgIGxldCBzb3J0ZWRBdHRyaWJ1dGVzID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyTmFtZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgIGxldCBhdHRyTmFtZSA9IGF0dHJOYW1lc1tpXTsKICAgICAgICAgIHNvcnRlZEF0dHJpYnV0ZXNbYXR0ck5hbWVdID0gYXR0cmlidXRlc1thdHRyTmFtZV07CiAgICAgICAgfQogICAgICAgIGF0dHJpYnV0ZXMgPSBzb3J0ZWRBdHRyaWJ1dGVzOwogICAgICB9CiAgICAgIHJldHVybiBhdHRyaWJ1dGVzOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhbiBgQXR0VmFsdWVgIChhdHRyaWJ1dGUgdmFsdWUpIGlmIHBvc3NpYmxlLgogICAgICoKICAgICAqIEByZXR1cm5zCiAgICAgKiAgIENvbnRlbnRzIG9mIHRoZSBgQXR0VmFsdWVgIG1pbnVzIHF1b3Rlcywgb3IgYGZhbHNlYCBpZiBub3RoaW5nIHdhcwogICAgICogICBjb25zdW1lZC4gQW4gZW1wdHkgc3RyaW5nIGluZGljYXRlcyB0aGF0IGFuIGBBdHRWYWx1ZWAgd2FzIGNvbnN1bWVkIGJ1dAogICAgICogICB3YXMgZW1wdHkuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNOVC1BdHRWYWx1ZQogICAgICovCiAgICBKKCkgewogICAgICBsZXQgeyBjOiBzY2FubmVyIH0gPSB0aGlzOwogICAgICBsZXQgcXVvdGUgPSBzY2FubmVyLmgoKTsKICAgICAgaWYgKHF1b3RlICE9PSAnIicgJiYgcXVvdGUgIT09ICInIikgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBzY2FubmVyLmcoKTsKICAgICAgbGV0IGNoYXJzOwogICAgICBsZXQgaXNDbG9zZWQgPSBmYWxzZTsKICAgICAgbGV0IHZhbHVlID0gZW1wdHlTdHJpbmcyOwogICAgICBsZXQgcmVnZXggPSBxdW90ZSA9PT0gJyInID8gYXR0VmFsdWVDaGFyRG91YmxlUXVvdGUgOiBhdHRWYWx1ZUNoYXJTaW5nbGVRdW90ZTsKICAgICAgbWF0Y2hMb29wOgogICAgICAgIHdoaWxlICghc2Nhbm5lci56KSB7CiAgICAgICAgICBjaGFycyA9IHNjYW5uZXIuRyhyZWdleCk7CiAgICAgICAgICBpZiAoY2hhcnMpIHsKICAgICAgICAgICAgdGhpcy5wKGNoYXJzKTsKICAgICAgICAgICAgdmFsdWUgKz0gY2hhcnMucmVwbGFjZShhdHRWYWx1ZU5vcm1hbGl6ZWRXaGl0ZXNwYWNlLCAiICIpOwogICAgICAgICAgfQogICAgICAgICAgc3dpdGNoIChzY2FubmVyLmgoKSkgewogICAgICAgICAgICBjYXNlIHF1b3RlOgogICAgICAgICAgICAgIGlzQ2xvc2VkID0gdHJ1ZTsKICAgICAgICAgICAgICBicmVhayBtYXRjaExvb3A7CiAgICAgICAgICAgIGNhc2UgIiYiOgogICAgICAgICAgICAgIHZhbHVlICs9IHRoaXMuQygpOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBjYXNlICI8IjoKICAgICAgICAgICAgICB0aHJvdyB0aGlzLmEoIlVuZXNjYXBlZCBgPGAgaXMgbm90IGFsbG93ZWQgaW4gYW4gYXR0cmlidXRlIHZhbHVlIik7CiAgICAgICAgICAgIGNhc2UgZW1wdHlTdHJpbmcyOgogICAgICAgICAgICAgIGJyZWFrIG1hdGNoTG9vcDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIGlmICghaXNDbG9zZWQpIHsKICAgICAgICB0aHJvdyB0aGlzLmEoIlVuY2xvc2VkIGF0dHJpYnV0ZSIpOwogICAgICB9CiAgICAgIHNjYW5uZXIuZygpOwogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgQ0RBVEEgc2VjdGlvbiBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGEgQ0RBVEEgc2VjdGlvbiB3YXMgY29uc3VtZWQuCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI3NlYy1jZGF0YS1zZWN0CiAgICAgKi8KICAgIEsoKSB7CiAgICAgIGxldCB7IGM6IHNjYW5uZXIgfSA9IHRoaXM7CiAgICAgIGxldCBzdGFydEluZGV4ID0gc2Nhbm5lci5kOwogICAgICBpZiAoIXNjYW5uZXIuYigiPCFbQ0RBVEFbIikpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IHRleHQgPSBzY2FubmVyLnQoIl1dPiIpOwogICAgICB0aGlzLnAodGV4dCk7CiAgICAgIGlmICghc2Nhbm5lci5iKCJdXT4iKSkgewogICAgICAgIHRocm93IHRoaXMuYSgiVW5jbG9zZWQgQ0RBVEEgc2VjdGlvbiIpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLmYucHJlc2VydmVDZGF0YSA/IHRoaXMuaihuZXcgWG1sQ2RhdGEobm9ybWFsaXplTGluZUJyZWFrcyh0ZXh0KSksIHN0YXJ0SW5kZXgpIDogdGhpcy54KHRleHQsIHN0YXJ0SW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBjaGFyYWN0ZXIgZGF0YSBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGNoYXJhY3RlciBkYXRhIHdhcyBjb25zdW1lZC4KICAgICAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMDgvUkVDLXhtbC0yMDA4MTEyNi8jZHQtY2hhcmRhdGEKICAgICAqLwogICAgTCgpIHsKICAgICAgbGV0IHsgYzogc2Nhbm5lciB9ID0gdGhpczsKICAgICAgbGV0IHN0YXJ0SW5kZXggPSBzY2FubmVyLmQ7CiAgICAgIGxldCBjaGFyRGF0YSA9IHNjYW5uZXIuQShlbmRDaGFyRGF0YSk7CiAgICAgIGlmICghY2hhckRhdGEpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgdGhpcy5wKGNoYXJEYXRhKTsKICAgICAgaWYgKHNjYW5uZXIuaCgzKSA9PT0gIl1dPiIpIHsKICAgICAgICB0aHJvdyB0aGlzLmEoIkVsZW1lbnQgY29udGVudCBtYXkgbm90IGNvbnRhaW4gdGhlIENEQVRBIHNlY3Rpb24gY2xvc2UgZGVsaW1pdGVyIGBdXT5gIik7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMueChjaGFyRGF0YSwgc3RhcnRJbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgY29tbWVudCBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGEgY29tbWVudCB3YXMgY29uc3VtZWQuCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI05ULUNvbW1lbnQKICAgICAqLwogICAgRCgpIHsKICAgICAgbGV0IHsgYzogc2Nhbm5lciB9ID0gdGhpczsKICAgICAgbGV0IHN0YXJ0SW5kZXggPSBzY2FubmVyLmQ7CiAgICAgIGlmICghc2Nhbm5lci5iKCI8IS0tIikpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IGNvbnRlbnQgPSBzY2FubmVyLnQoIi0tIik7CiAgICAgIHRoaXMucChjb250ZW50KTsKICAgICAgaWYgKCFzY2FubmVyLmIoIi0tPiIpKSB7CiAgICAgICAgaWYgKHNjYW5uZXIuaCgyKSA9PT0gIi0tIikgewogICAgICAgICAgdGhyb3cgdGhpcy5hKCJUaGUgc3RyaW5nIGAtLWAgaXNuJ3QgYWxsb3dlZCBpbnNpZGUgYSBjb21tZW50Iik7CiAgICAgICAgfQogICAgICAgIHRocm93IHRoaXMuYSgiVW5jbG9zZWQgY29tbWVudCIpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLmYucHJlc2VydmVDb21tZW50cyA/IHRoaXMuaihuZXcgWG1sQ29tbWVudChub3JtYWxpemVMaW5lQnJlYWtzKGNvbnRlbnQpKSwgc3RhcnRJbmRleCkgOiB0cnVlOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhIHJlZmVyZW5jZSBpbiBhIGNvbnRlbnQgY29udGV4dCBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBUaGlzIGRpZmZlcnMgZnJvbSBgY29uc3VtZVJlZmVyZW5jZSgpYCBpbiB0aGF0IGEgY29uc3VtZWQgcmVmZXJlbmNlIHdpbGwgYmUKICAgICAqIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBhcyBhIHRleHQgbm9kZSBpbnN0ZWFkIG9mIHJldHVybmVkLgogICAgICoKICAgICAqIEByZXR1cm5zIFdoZXRoZXIgYSByZWZlcmVuY2Ugd2FzIGNvbnN1bWVkLgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNlbnRwcm9jCiAgICAgKi8KICAgIE0oKSB7CiAgICAgIGxldCBzdGFydEluZGV4ID0gdGhpcy5jLmQ7CiAgICAgIGxldCByZWYgPSB0aGlzLkMoKTsKICAgICAgcmV0dXJuIHJlZiA/IHRoaXMueChyZWYsIHN0YXJ0SW5kZXgpIDogZmFsc2U7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgZG9jdHlwZSBkZWNsYXJhdGlvbiBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBUaGlzIGlzIGEgbG9vc2UgaW1wbGVtZW50YXRpb24gc2luY2UgZG9jdHlwZSBkZWNsYXJhdGlvbnMgYXJlIGN1cnJlbnRseQogICAgICogZGlzY2FyZGVkIHdpdGhvdXQgZnVydGhlciBwYXJzaW5nLgogICAgICoKICAgICAqIEByZXR1cm5zIFdoZXRoZXIgYSBkb2N0eXBlIGRlY2xhcmF0aW9uIHdhcyBjb25zdW1lZC4KICAgICAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMDgvUkVDLXhtbC0yMDA4MTEyNi8jZHRkCiAgICAgKi8KICAgIE4oKSB7CiAgICAgIGxldCB7IGM6IHNjYW5uZXIgfSA9IHRoaXM7CiAgICAgIGxldCBzdGFydEluZGV4ID0gc2Nhbm5lci5kOwogICAgICBpZiAoIXNjYW5uZXIuYigiPCFET0NUWVBFIikpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IG5hbWUgPSB0aGlzLmUoKSAmJiB0aGlzLnIoKTsKICAgICAgaWYgKCFuYW1lKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJFeHBlY3RlZCBhIG5hbWUiKTsKICAgICAgfQogICAgICBsZXQgcHVibGljSWQ7CiAgICAgIGxldCBzeXN0ZW1JZDsKICAgICAgaWYgKHRoaXMuZSgpKSB7CiAgICAgICAgaWYgKHNjYW5uZXIuYigiUFVCTElDIikpIHsKICAgICAgICAgIHB1YmxpY0lkID0gdGhpcy5lKCkgJiYgdGhpcy5PKCk7CiAgICAgICAgICBpZiAocHVibGljSWQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHRocm93IHRoaXMuYSgiRXhwZWN0ZWQgYSBwdWJsaWMgaWRlbnRpZmllciIpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5lKCk7CiAgICAgICAgfQogICAgICAgIGlmIChwdWJsaWNJZCAhPT0gdm9pZCAwIHx8IHNjYW5uZXIuYigiU1lTVEVNIikpIHsKICAgICAgICAgIHRoaXMuZSgpOwogICAgICAgICAgc3lzdGVtSWQgPSB0aGlzLnMoKTsKICAgICAgICAgIGlmIChzeXN0ZW1JZCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgdGhpcy5hKCJFeHBlY3RlZCBhIHN5c3RlbSBpZGVudGlmaWVyIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLmUoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbGV0IGludGVybmFsU3Vic2V0OwogICAgICBpZiAoc2Nhbm5lci5iKCJbIikpIHsKICAgICAgICBpbnRlcm5hbFN1YnNldCA9IHNjYW5uZXIuQSgvXF1bXHgyMFx0XHJcbl0qPi8pOwogICAgICAgIGlmICghc2Nhbm5lci5iKCJdIikpIHsKICAgICAgICAgIHRocm93IHRoaXMuYSgiVW5jbG9zZWQgaW50ZXJuYWwgc3Vic2V0Iik7CiAgICAgICAgfQogICAgICAgIHRoaXMuZSgpOwogICAgICB9CiAgICAgIGlmICghc2Nhbm5lci5iKCI+IikpIHsKICAgICAgICB0aHJvdyB0aGlzLmEoIlVuY2xvc2VkIGRvY3R5cGUgZGVjbGFyYXRpb24iKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5mLnByZXNlcnZlRG9jdW1lbnRUeXBlID8gdGhpcy5qKG5ldyBYbWxEb2N1bWVudFR5cGUobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkLCBpbnRlcm5hbFN1YnNldCksIHN0YXJ0SW5kZXgpIDogdHJ1ZTsKICAgIH0KICAgIC8qKgogICAgICogQ29uc3VtZXMgYW4gZWxlbWVudCBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGFuIGVsZW1lbnQgd2FzIGNvbnN1bWVkLgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNOVC1lbGVtZW50CiAgICAgKi8KICAgIEIoKSB7CiAgICAgIGxldCB7IGM6IHNjYW5uZXIgfSA9IHRoaXM7CiAgICAgIGxldCBzdGFydEluZGV4ID0gc2Nhbm5lci5kOwogICAgICBpZiAoIXNjYW5uZXIuYigiPCIpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGxldCBuYW1lID0gdGhpcy5yKCk7CiAgICAgIGlmICghbmFtZSkgewogICAgICAgIHNjYW5uZXIubyhzdGFydEluZGV4KTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IGF0dHJpYnV0ZXMgPSB0aGlzLkkoKTsKICAgICAgbGV0IGlzRW1wdHkgPSAhIXNjYW5uZXIuYigiLz4iKTsKICAgICAgbGV0IGVsZW1lbnQgPSBuZXcgWG1sRWxlbWVudChuYW1lLCBhdHRyaWJ1dGVzKTsKICAgICAgZWxlbWVudC5wYXJlbnQgPSB0aGlzLmw7CiAgICAgIGlmICghaXNFbXB0eSkgewogICAgICAgIGlmICghc2Nhbm5lci5iKCI+IikpIHsKICAgICAgICAgIHRocm93IHRoaXMuYShgVW5jbG9zZWQgc3RhcnQgdGFnIGZvciBlbGVtZW50IFxgJHtuYW1lfVxgYCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubCA9IGVsZW1lbnQ7CiAgICAgICAgZG8gewogICAgICAgICAgdGhpcy5MKCk7CiAgICAgICAgfSB3aGlsZSAodGhpcy5CKCkgfHwgdGhpcy5NKCkgfHwgdGhpcy5LKCkgfHwgdGhpcy5FKCkgfHwgdGhpcy5EKCkpOwogICAgICAgIGxldCBlbmRUYWdNYXJrID0gc2Nhbm5lci5kOwogICAgICAgIGxldCBlbmRUYWdOYW1lOwogICAgICAgIGlmICghc2Nhbm5lci5iKCI8LyIpIHx8ICEoZW5kVGFnTmFtZSA9IHRoaXMucigpKSB8fCBlbmRUYWdOYW1lICE9PSBuYW1lKSB7CiAgICAgICAgICBzY2FubmVyLm8oZW5kVGFnTWFyayk7CiAgICAgICAgICB0aHJvdyB0aGlzLmEoYE1pc3NpbmcgZW5kIHRhZyBmb3IgZWxlbWVudCAke25hbWV9YCk7CiAgICAgICAgfQogICAgICAgIHRoaXMuZSgpOwogICAgICAgIGlmICghc2Nhbm5lci5iKCI+IikpIHsKICAgICAgICAgIHRocm93IHRoaXMuYShgVW5jbG9zZWQgZW5kIHRhZyBmb3IgZWxlbWVudCAke25hbWV9YCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubCA9IGVsZW1lbnQucGFyZW50OwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLmooZWxlbWVudCwgc3RhcnRJbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGFuIGBFcWAgcHJvZHVjdGlvbiBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGFuIGBFcWAgcHJvZHVjdGlvbiB3YXMgY29uc3VtZWQuCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI05ULUVxCiAgICAgKi8KICAgIHUoKSB7CiAgICAgIHRoaXMuZSgpOwogICAgICBpZiAodGhpcy5jLmIoIj0iKSkgewogICAgICAgIHRoaXMuZSgpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIC8qKgogICAgICogQ29uc3VtZXMgYE1pc2NgIGNvbnRlbnQgaWYgcG9zc2libGUuCiAgICAgKgogICAgICogQHJldHVybnMgV2hldGhlciBhbnl0aGluZyB3YXMgY29uc3VtZWQuCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI05ULU1pc2MKICAgICAqLwogICAgdygpIHsKICAgICAgcmV0dXJuIHRoaXMuRCgpIHx8IHRoaXMuRSgpIHx8IHRoaXMuZSgpOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBvbmUgb3IgbW9yZSBgTmFtZWAgY2hhcmFjdGVycyBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBgTmFtZWAgY2hhcmFjdGVycywgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG5vbmUgd2VyZSBjb25zdW1lZC4KICAgICAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMDgvUkVDLXhtbC0yMDA4MTEyNi8jTlQtTmFtZQogICAgICovCiAgICByKCkgewogICAgICByZXR1cm4gaXNOYW1lU3RhcnRDaGFyKHRoaXMuYy5oKCkpID8gdGhpcy5jLnYoaXNOYW1lQ2hhcikgOiBlbXB0eVN0cmluZzI7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB3YXMgY29uc3VtZWQuCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI3NlYy1waQogICAgICovCiAgICBFKCkgewogICAgICBsZXQgeyBjOiBzY2FubmVyIH0gPSB0aGlzOwogICAgICBsZXQgc3RhcnRJbmRleCA9IHNjYW5uZXIuZDsKICAgICAgaWYgKCFzY2FubmVyLmIoIjw/IikpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IG5hbWUgPSB0aGlzLnIoKTsKICAgICAgaWYgKG5hbWUpIHsKICAgICAgICBpZiAobmFtZS50b0xvd2VyQ2FzZSgpID09PSAieG1sIikgewogICAgICAgICAgc2Nhbm5lci5vKHN0YXJ0SW5kZXgpOwogICAgICAgICAgdGhyb3cgdGhpcy5hKCJYTUwgZGVjbGFyYXRpb24gaXNuJ3QgYWxsb3dlZCBoZXJlIik7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIHRocm93IHRoaXMuYSgiSW52YWxpZCBwcm9jZXNzaW5nIGluc3RydWN0aW9uIik7CiAgICAgIH0KICAgICAgaWYgKCF0aGlzLmUoKSkgewogICAgICAgIGlmIChzY2FubmVyLmIoIj8+IikpIHsKICAgICAgICAgIHJldHVybiB0aGlzLmoobmV3IFhtbFByb2Nlc3NpbmdJbnN0cnVjdGlvbihuYW1lKSwgc3RhcnRJbmRleCk7CiAgICAgICAgfQogICAgICAgIHRocm93IHRoaXMuYSgiV2hpdGVzcGFjZSBpcyByZXF1aXJlZCBhZnRlciBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbmFtZSIpOwogICAgICB9CiAgICAgIGxldCBjb250ZW50ID0gc2Nhbm5lci50KCI/PiIpOwogICAgICB0aGlzLnAoY29udGVudCk7CiAgICAgIGlmICghc2Nhbm5lci5iKCI/PiIpKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJVbnRlcm1pbmF0ZWQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiIpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLmoobmV3IFhtbFByb2Nlc3NpbmdJbnN0cnVjdGlvbihuYW1lLCBub3JtYWxpemVMaW5lQnJlYWtzKGNvbnRlbnQpKSwgc3RhcnRJbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgcHJvbG9nIGlmIHBvc3NpYmxlLgogICAgICoKICAgICAqIEByZXR1cm5zIFdoZXRoZXIgYSBwcm9sb2cgd2FzIGNvbnN1bWVkLgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNzZWMtcHJvbG9nLWR0ZAogICAgICovCiAgICBIKCkgewogICAgICBsZXQgeyBjOiBzY2FubmVyIH0gPSB0aGlzOwogICAgICBsZXQgc3RhcnRJbmRleCA9IHNjYW5uZXIuZDsKICAgICAgdGhpcy5QKCk7CiAgICAgIHdoaWxlICh0aGlzLncoKSkgewogICAgICB9CiAgICAgIGlmICh0aGlzLk4oKSkgewogICAgICAgIHdoaWxlICh0aGlzLncoKSkgewogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gc3RhcnRJbmRleCA8IHNjYW5uZXIuZDsKICAgIH0KICAgIC8qKgogICAgICogQ29uc3VtZXMgYSBwdWJsaWMgaWRlbnRpZmllciBsaXRlcmFsIGlmIHBvc3NpYmxlLgogICAgICoKICAgICAqIEByZXR1cm5zCiAgICAgKiAgIFZhbHVlIG9mIHRoZSBwdWJsaWMgaWRlbnRpZmllciBsaXRlcmFsIG1pbnVzIHF1b3Rlcywgb3IgYGZhbHNlYCBpZgogICAgICogICBub3RoaW5nIHdhcyBjb25zdW1lZC4gQW4gZW1wdHkgc3RyaW5nIGluZGljYXRlcyB0aGF0IGEgcHVibGljIGlkIGxpdGVyYWwKICAgICAqICAgd2FzIGNvbnN1bWVkIGJ1dCB3YXMgZW1wdHkuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNOVC1QdWJpZExpdGVyYWwKICAgICAqLwogICAgTygpIHsKICAgICAgbGV0IHN0YXJ0SW5kZXggPSB0aGlzLmMuZDsKICAgICAgbGV0IHZhbHVlID0gdGhpcy5zKCk7CiAgICAgIGlmICh2YWx1ZSAhPT0gZmFsc2UgJiYgIS9eWy1ceDIwXHJcbmEtekEtWjAtOScoKSssLi86PT87ISojQCRfJV0qJC8udGVzdCh2YWx1ZSkpIHsKICAgICAgICB0aGlzLmMubyhzdGFydEluZGV4KTsKICAgICAgICB0aHJvdyB0aGlzLmEoIkludmFsaWQgY2hhcmFjdGVyIGluIHB1YmxpYyBpZGVudGlmaWVyIik7CiAgICAgIH0KICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhIHJlZmVyZW5jZSBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBUaGlzIGRpZmZlcnMgZnJvbSBgY29uc3VtZUNvbnRlbnRSZWZlcmVuY2UoKWAgaW4gdGhhdCBhIGNvbnN1bWVkIHJlZmVyZW5jZQogICAgICogd2lsbCBiZSByZXR1cm5lZCByYXRoZXIgdGhhbiBhZGRlZCB0byB0aGUgZG9jdW1lbnQuCiAgICAgKgogICAgICogQHJldHVybnMKICAgICAqICAgUGFyc2VkIHJlZmVyZW5jZSB2YWx1ZSwgb3IgYGZhbHNlYCBpZiBub3RoaW5nIHdhcyBjb25zdW1lZCAodG8KICAgICAqICAgZGlzdGluZ3Vpc2ggZnJvbSBhIHJlZmVyZW5jZSB0aGF0IHJlc29sdmVzIHRvIGFuIGVtcHR5IHN0cmluZykuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNOVC1SZWZlcmVuY2UKICAgICAqLwogICAgQygpIHsKICAgICAgbGV0IHsgYzogc2Nhbm5lciB9ID0gdGhpczsKICAgICAgaWYgKCFzY2FubmVyLmIoIiYiKSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBsZXQgcmVmID0gc2Nhbm5lci52KGlzUmVmZXJlbmNlQ2hhcik7CiAgICAgIGlmIChzY2FubmVyLkYoKSAhPT0gIjsiKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJVbnRlcm1pbmF0ZWQgcmVmZXJlbmNlIChhIHJlZmVyZW5jZSBtdXN0IGVuZCB3aXRoIGA7YCkiKTsKICAgICAgfQogICAgICBsZXQgcGFyc2VkVmFsdWU7CiAgICAgIGlmIChyZWZbMF0gPT09ICIjIikgewogICAgICAgIGxldCBjb2RlUG9pbnQgPSByZWZbMV0gPT09ICJ4IiA/IHBhcnNlSW50KHJlZi5zbGljZSgyKSwgMTYpIDogcGFyc2VJbnQocmVmLnNsaWNlKDEpLCAxMCk7CiAgICAgICAgaWYgKGlzTmFOKGNvZGVQb2ludCkpIHsKICAgICAgICAgIHRocm93IHRoaXMuYSgiSW52YWxpZCBjaGFyYWN0ZXIgcmVmZXJlbmNlIik7CiAgICAgICAgfQogICAgICAgIGlmICghaXNYbWxDb2RlUG9pbnQoY29kZVBvaW50KSkgewogICAgICAgICAgdGhyb3cgdGhpcy5hKCJDaGFyYWN0ZXIgcmVmZXJlbmNlIHJlc29sdmVzIHRvIGFuIGludmFsaWQgY2hhcmFjdGVyIik7CiAgICAgICAgfQogICAgICAgIHBhcnNlZFZhbHVlID0gU3RyaW5nLmZyb21Db2RlUG9pbnQoY29kZVBvaW50KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBwYXJzZWRWYWx1ZSA9IHByZWRlZmluZWRFbnRpdGllc1tyZWZdOwogICAgICAgIGlmIChwYXJzZWRWYWx1ZSA9PT0gdm9pZCAwKSB7CiAgICAgICAgICBsZXQgewogICAgICAgICAgICBpZ25vcmVVbmRlZmluZWRFbnRpdGllcywKICAgICAgICAgICAgcmVzb2x2ZVVuZGVmaW5lZEVudGl0eQogICAgICAgICAgfSA9IHRoaXMuZjsKICAgICAgICAgIGxldCB3cmFwcGVkUmVmID0gYCYke3JlZn07YDsKICAgICAgICAgIGlmIChyZXNvbHZlVW5kZWZpbmVkRW50aXR5KSB7CiAgICAgICAgICAgIGxldCByZXNvbHZlZFZhbHVlID0gcmVzb2x2ZVVuZGVmaW5lZEVudGl0eSh3cmFwcGVkUmVmKTsKICAgICAgICAgICAgaWYgKHJlc29sdmVkVmFsdWUgIT09IG51bGwgJiYgcmVzb2x2ZWRWYWx1ZSAhPT0gdm9pZCAwKSB7CiAgICAgICAgICAgICAgbGV0IHR5cGUgPSB0eXBlb2YgcmVzb2x2ZWRWYWx1ZTsKICAgICAgICAgICAgICBpZiAodHlwZSAhPT0gInN0cmluZyIpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFxgcmVzb2x2ZVVuZGVmaW5lZEVudGl0eSgpXGAgbXVzdCByZXR1cm4gYSBzdHJpbmcsIFxgbnVsbFxgLCBvciBcYHVuZGVmaW5lZFxgLCBidXQgcmV0dXJuZWQgYSB2YWx1ZSBvZiB0eXBlICR7dHlwZX1gKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmVkVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlmIChpZ25vcmVVbmRlZmluZWRFbnRpdGllcykgewogICAgICAgICAgICByZXR1cm4gd3JhcHBlZFJlZjsKICAgICAgICAgIH0KICAgICAgICAgIHNjYW5uZXIubygtd3JhcHBlZFJlZi5sZW5ndGgpOwogICAgICAgICAgdGhyb3cgdGhpcy5hKGBOYW1lZCBlbnRpdHkgaXNuJ3QgZGVmaW5lZDogJHt3cmFwcGVkUmVmfWApOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gcGFyc2VkVmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgYFN5c3RlbUxpdGVyYWxgIGlmIHBvc3NpYmxlLgogICAgICoKICAgICAqIEEgYFN5c3RlbUxpdGVyYWxgIGlzIHNpbWlsYXIgdG8gYW4gYXR0cmlidXRlIHZhbHVlLCBidXQgYWxsb3dzIHRoZQogICAgICogY2hhcmFjdGVycyBgPGAgYW5kIGAmYCBhbmQgZG9lc24ndCByZXBsYWNlIHJlZmVyZW5jZXMuCiAgICAgKgogICAgICogQHJldHVybnMKICAgICAqICAgVmFsdWUgb2YgdGhlIGBTeXN0ZW1MaXRlcmFsYCBtaW51cyBxdW90ZXMsIG9yIGBmYWxzZWAgaWYgbm90aGluZyB3YXMKICAgICAqICAgY29uc3VtZWQuIEFuIGVtcHR5IHN0cmluZyBpbmRpY2F0ZXMgdGhhdCBhIGBTeXN0ZW1MaXRlcmFsYCB3YXMgY29uc3VtZWQKICAgICAqICAgYnV0IHdhcyBlbXB0eS4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI05ULVN5c3RlbUxpdGVyYWwKICAgICAqLwogICAgcygpIHsKICAgICAgbGV0IHsgYzogc2Nhbm5lciB9ID0gdGhpczsKICAgICAgbGV0IHF1b3RlID0gc2Nhbm5lci5iKCciJykgfHwgc2Nhbm5lci5iKCInIik7CiAgICAgIGlmICghcXVvdGUpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IHZhbHVlID0gc2Nhbm5lci50KHF1b3RlKTsKICAgICAgdGhpcy5wKHZhbHVlKTsKICAgICAgaWYgKCFzY2FubmVyLmIocXVvdGUpKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJNaXNzaW5nIGVuZCBxdW90ZSIpOwogICAgICB9CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogQ29uc3VtZXMgb25lIG9yIG1vcmUgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzIGlmIHBvc3NpYmxlLgogICAgICoKICAgICAqIEByZXR1cm5zIFdoZXRoZXIgYW55IHdoaXRlc3BhY2UgY2hhcmFjdGVycyB3ZXJlIGNvbnN1bWVkLgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyN3aGl0ZQogICAgICovCiAgICBlKCkgewogICAgICByZXR1cm4gISF0aGlzLmMudihpc1doaXRlc3BhY2UpOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhbiBYTUwgZGVjbGFyYXRpb24gaWYgcG9zc2libGUuCiAgICAgKgogICAgICogQHJldHVybnMgV2hldGhlciBhbiBYTUwgZGVjbGFyYXRpb24gd2FzIGNvbnN1bWVkLgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNOVC1YTUxEZWNsCiAgICAgKi8KICAgIFAoKSB7CiAgICAgIGxldCB7IGM6IHNjYW5uZXIgfSA9IHRoaXM7CiAgICAgIGxldCBzdGFydEluZGV4ID0gc2Nhbm5lci5kOwogICAgICBpZiAoIXNjYW5uZXIuYigiPD94bWwiKSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIXRoaXMuZSgpKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJJbnZhbGlkIFhNTCBkZWNsYXJhdGlvbiIpOwogICAgICB9CiAgICAgIGxldCB2ZXJzaW9uID0gISFzY2FubmVyLmIoInZlcnNpb24iKSAmJiB0aGlzLnUoKSAmJiB0aGlzLnMoKTsKICAgICAgaWYgKHZlcnNpb24gPT09IGZhbHNlKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJYTUwgdmVyc2lvbiBpcyBtaXNzaW5nIG9yIGludmFsaWQiKTsKICAgICAgfSBlbHNlIGlmICghL14xXC5bMC05XSskLy50ZXN0KHZlcnNpb24pKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJJbnZhbGlkIGNoYXJhY3RlciBpbiB2ZXJzaW9uIG51bWJlciIpOwogICAgICB9CiAgICAgIGxldCBlbmNvZGluZzsKICAgICAgbGV0IHN0YW5kYWxvbmU7CiAgICAgIGlmICh0aGlzLmUoKSkgewogICAgICAgIGVuY29kaW5nID0gISFzY2FubmVyLmIoImVuY29kaW5nIikgJiYgdGhpcy51KCkgJiYgdGhpcy5zKCk7CiAgICAgICAgaWYgKGVuY29kaW5nKSB7CiAgICAgICAgICB0aGlzLmUoKTsKICAgICAgICB9CiAgICAgICAgc3RhbmRhbG9uZSA9ICEhc2Nhbm5lci5iKCJzdGFuZGFsb25lIikgJiYgdGhpcy51KCkgJiYgdGhpcy5zKCk7CiAgICAgICAgaWYgKHN0YW5kYWxvbmUpIHsKICAgICAgICAgIGlmIChzdGFuZGFsb25lICE9PSAieWVzIiAmJiBzdGFuZGFsb25lICE9PSAibm8iKSB7CiAgICAgICAgICAgIHRocm93IHRoaXMuYSgnT25seSAieWVzIiBhbmQgIm5vIiBhcmUgcGVybWl0dGVkIGFzIHZhbHVlcyBvZiBgc3RhbmRhbG9uZWAnKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMuZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoIXNjYW5uZXIuYigiPz4iKSkgewogICAgICAgIHRocm93IHRoaXMuYSgiSW52YWxpZCBvciB1bmNsb3NlZCBYTUwgZGVjbGFyYXRpb24iKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5mLnByZXNlcnZlWG1sRGVjbGFyYXRpb24gPyB0aGlzLmoobmV3IFhtbERlY2xhcmF0aW9uKAogICAgICAgIHZlcnNpb24sCiAgICAgICAgZW5jb2RpbmcgfHwgdm9pZCAwLAogICAgICAgIHN0YW5kYWxvbmUgfHwgdm9pZCAwCiAgICAgICksIHN0YXJ0SW5kZXgpIDogdHJ1ZTsKICAgIH0KICAgIC8qKgogICAgICogUmV0dXJucyBhbiBgWG1sRXJyb3JgIGZvciB0aGUgY3VycmVudCBzY2FubmVyIHBvc2l0aW9uLgogICAgICovCiAgICBhKG1lc3NhZ2UpIHsKICAgICAgbGV0IHsgYzogc2Nhbm5lciB9ID0gdGhpczsKICAgICAgcmV0dXJuIG5ldyBYbWxFcnJvcihtZXNzYWdlLCBzY2FubmVyLmQsIHNjYW5uZXIubSk7CiAgICB9CiAgICAvKioKICAgICAqIFRocm93cyBhbiBpbnZhbGlkIGNoYXJhY3RlciBlcnJvciBpZiBhbnkgY2hhcmFjdGVyIGluIHRoZSBnaXZlbiBfc3RyaW5nXwogICAgICogaXNuJ3QgYSB2YWxpZCBYTUwgY2hhcmFjdGVyLgogICAgICovCiAgICBwKHN0cmluZykgewogICAgICBsZXQgeyBsZW5ndGggfSA9IHN0cmluZzsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewogICAgICAgIGxldCBjcCA9IHN0cmluZy5jb2RlUG9pbnRBdChpKTsKICAgICAgICBpZiAoIWlzWG1sQ29kZVBvaW50KGNwKSkgewogICAgICAgICAgdGhpcy5jLm8oLShbLi4uc3RyaW5nXS5sZW5ndGggLSBpKSk7CiAgICAgICAgICB0aHJvdyB0aGlzLmEoIkludmFsaWQgY2hhcmFjdGVyIik7CiAgICAgICAgfQogICAgICAgIGlmIChjcCA+IDY1NTM1KSB7CiAgICAgICAgICBpICs9IDE7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKICBmdW5jdGlvbiBub3JtYWxpemVMaW5lQnJlYWtzKHRleHQpIHsKICAgIGxldCBpID0gMDsKICAgIHdoaWxlICgoaSA9IHRleHQuaW5kZXhPZigiXHIiLCBpKSkgIT09IC0xKSB7CiAgICAgIHRleHQgPSB0ZXh0W2kgKyAxXSA9PT0gIlxuIiA/IHRleHQuc2xpY2UoMCwgaSkgKyB0ZXh0LnNsaWNlKGkgKyAxKSA6IHRleHQuc2xpY2UoMCwgaSkgKyAiXG4iICsgdGV4dC5zbGljZShpICsgMSk7CiAgICB9CiAgICByZXR1cm4gdGV4dDsKICB9CiAgZnVuY3Rpb24gcGFyc2VYbWwoeG1sLCBvcHRpb25zKSB7CiAgICByZXR1cm4gbmV3IFBhcnNlcih4bWwsIG9wdGlvbnMpLmRvY3VtZW50OwogIH0KICBjbGFzcyBYbWxQYXJzZUVycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IobWVzc2FnZSkgewogICAgICBzdXBlcihtZXNzYWdlKTsKICAgIH0KICB9CiAgZnVuY3Rpb24gcGFyc2VYbWxTdHJpbmcoeG1sU3RyaW5nKSB7CiAgICBsZXQgZG9jID0gbnVsbDsKICAgIHRyeSB7CiAgICAgIGRvYyA9IGJyb3dzZXIucGFyc2VYbWwoeG1sU3RyaW5nKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgdGhyb3cgbmV3IFhtbFBhcnNlRXJyb3IoZS5tZXNzYWdlKTsKICAgIH0KICAgIHJldHVybiBkb2M7CiAgfQogIGZ1bmN0aW9uIHN0cmlwTmFtZXNwYWNlKG5hbWUpIHsKICAgIGNvbnN0IGNvbG9uID0gbmFtZS5pbmRleE9mKCI6Iik7CiAgICByZXR1cm4gY29sb24gPiAtMSA/IG5hbWUuc3Vic3RyKGNvbG9uICsgMSkgOiBuYW1lOwogIH0KICBmdW5jdGlvbiBnZXRSb290RWxlbWVudCh4bWxEb2MpIHsKICAgIHJldHVybiB4bWxEb2MuY2hpbGRyZW5bMF07CiAgfQogIGZ1bmN0aW9uIGdldEVsZW1lbnROYW1lKGVsZW1lbnQpIHsKICAgIHJldHVybiBlbGVtZW50Lm5hbWUgfHwgIiI7CiAgfQogIGZ1bmN0aW9uIGZpbmRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCwgbmFtZSwgbmVzdGVkID0gZmFsc2UpIHsKICAgIGNvbnN0IHN0cmlwcGVkTmFtZSA9IHN0cmlwTmFtZXNwYWNlKG5hbWUpOwogICAgZnVuY3Rpb24gcmVkdWNlcihwcmV2LCBjdXJyKSB7CiAgICAgIGlmIChzdHJpcE5hbWVzcGFjZShnZXRFbGVtZW50TmFtZShjdXJyKSkgPT09IHN0cmlwcGVkTmFtZSkgewogICAgICAgIHByZXYucHVzaChjdXJyKTsKICAgICAgfQogICAgICBpZiAobmVzdGVkICYmIEFycmF5LmlzQXJyYXkoY3Vyci5jaGlsZHJlbikpIHsKICAgICAgICByZXR1cm4gWy4uLnByZXYsIC4uLmN1cnIuY2hpbGRyZW4ucmVkdWNlKHJlZHVjZXIsIFtdKV07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHByZXY7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBlbGVtZW50ICYmIEFycmF5LmlzQXJyYXkoZWxlbWVudC5jaGlsZHJlbikgPyBlbGVtZW50LmNoaWxkcmVuLnJlZHVjZShyZWR1Y2VyLCBbXSkgOiBbXTsKICB9CiAgZnVuY3Rpb24gZmluZENoaWxkRWxlbWVudChlbGVtZW50LCBuYW1lLCBuZXN0ZWQgPSBmYWxzZSkgewogICAgcmV0dXJuIGZpbmRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCwgbmFtZSwgbmVzdGVkKVswXSB8fCBudWxsOwogIH0KICBmdW5jdGlvbiBnZXRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCkgewogICAgcmV0dXJuIGVsZW1lbnQgJiYgQXJyYXkuaXNBcnJheShlbGVtZW50LmNoaWxkcmVuKSA/IFsKICAgICAgLi4uZWxlbWVudC5jaGlsZHJlbi5maWx0ZXIoCiAgICAgICAgKGVsKSA9PiBlbCBpbnN0YW5jZW9mIGJyb3dzZXIuWG1sRWxlbWVudAogICAgICApCiAgICBdIDogW107CiAgfQogIGZ1bmN0aW9uIGdldEVsZW1lbnRUZXh0KGVsZW1lbnQpIHsKICAgIGNvbnN0IHRleHROb2RlID0gZWxlbWVudCAmJiBBcnJheS5pc0FycmF5KGVsZW1lbnQuY2hpbGRyZW4pID8gZWxlbWVudC5jaGlsZHJlbi5maW5kKChub2RlKSA9PiBub2RlLnR5cGUgPT09ICJ0ZXh0IikgOiBudWxsOwogICAgcmV0dXJuIHRleHROb2RlID8gdGV4dE5vZGUudGV4dCA6ICIiOwogIH0KICBmdW5jdGlvbiBnZXRFbGVtZW50QXR0cmlidXRlKGVsZW1lbnQsIGF0dHJOYW1lKSB7CiAgICByZXR1cm4gZWxlbWVudCAmJiBlbGVtZW50LmF0dHJpYnV0ZXNbYXR0ck5hbWVdIHx8ICIiOwogIH0KICBjbGFzcyBFbmRwb2ludEVycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IobWVzc2FnZSwgaHR0cFN0YXR1cywgaXNDcm9zc09yaWdpblJlbGF0ZWQpIHsKICAgICAgc3VwZXIobWVzc2FnZSk7CiAgICAgIHRoaXMuaHR0cFN0YXR1cyA9IGh0dHBTdGF0dXM7CiAgICAgIHRoaXMuaXNDcm9zc09yaWdpblJlbGF0ZWQgPSBpc0Nyb3NzT3JpZ2luUmVsYXRlZDsKICAgICAgdGhpcy5uYW1lID0gIkVuZHBvaW50RXJyb3IiOwogICAgfQogIH0KICBjbGFzcyBTZXJ2aWNlRXhjZXB0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0gbWVzc2FnZSBFcnJvciBtZXNzYWdlCiAgICAgKiBAcGFyYW0gcmVxdWVzdFVybCBVUkwgd2hpY2ggcmVzdWx0ZWQgaW4gdGhlIFNlcnZpY2VFeGNlcHRpb24KICAgICAqIEBwYXJhbSBjb2RlIE9wdGlvbmFsIFNlcnZpY2VFeGNlcHRpb24gY29kZQogICAgICogQHBhcmFtIGxvY2F0b3IgT3B0aW9uYWwgU2VydmljZUV4Y2VwdGlvbiBsb2NhdG9yCiAgICAgKiBAcGFyYW0gcmVzcG9uc2UgT3B0aW9uYWwgcmVzcG9uc2UgY29udGVudCByZWNlaXZlZAogICAgICovCiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlLCByZXF1ZXN0VXJsLCBjb2RlLCBsb2NhdG9yLCByZXNwb25zZSkgewogICAgICBzdXBlcihtZXNzYWdlKTsKICAgICAgdGhpcy5yZXF1ZXN0VXJsID0gcmVxdWVzdFVybDsKICAgICAgdGhpcy5jb2RlID0gY29kZTsKICAgICAgdGhpcy5sb2NhdG9yID0gbG9jYXRvcjsKICAgICAgdGhpcy5yZXNwb25zZSA9IHJlc3BvbnNlOwogICAgICB0aGlzLm5hbWUgPSAiU2VydmljZUV4Y2VwdGlvbkVycm9yIjsKICAgIH0KICB9CiAgZnVuY3Rpb24gcGFyc2Uoc2VydmljZUV4Y2VwdGlvbiwgdXJsKSB7CiAgICBjb25zdCBlcnJvckNvZGUgPSBnZXRFbGVtZW50QXR0cmlidXRlKHNlcnZpY2VFeGNlcHRpb24sICJjb2RlIikgfHwgZ2V0RWxlbWVudEF0dHJpYnV0ZShzZXJ2aWNlRXhjZXB0aW9uLCAiZXhjZXB0aW9uQ29kZSIpOwogICAgY29uc3QgZXJyb3JMb2NhdG9yID0gZ2V0RWxlbWVudEF0dHJpYnV0ZShzZXJ2aWNlRXhjZXB0aW9uLCAibG9jYXRvciIpOwogICAgY29uc3QgdGV4dEVsZW1lbnQgPSBmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2VFeGNlcHRpb24sICJFeGNlcHRpb25UZXh0IikgfHwgc2VydmljZUV4Y2VwdGlvbjsKICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGdldEVsZW1lbnRUZXh0KHRleHRFbGVtZW50KS50cmltKCk7CiAgICByZXR1cm4gbmV3IFNlcnZpY2VFeGNlcHRpb25FcnJvcigKICAgICAgZXJyb3JNZXNzYWdlLAogICAgICB1cmwsCiAgICAgIGVycm9yQ29kZSwKICAgICAgZXJyb3JMb2NhdG9yLAogICAgICBzZXJ2aWNlRXhjZXB0aW9uLmRvY3VtZW50CiAgICApOwogIH0KICBmdW5jdGlvbiBjaGVjayhyZXNwb25zZSwgdXJsKSB7CiAgICBjb25zdCByb290RWwgPSBnZXRSb290RWxlbWVudChyZXNwb25zZSk7CiAgICBjb25zdCByb290RWxOYW1lID0gc3RyaXBOYW1lc3BhY2UoZ2V0RWxlbWVudE5hbWUocm9vdEVsKSk7CiAgICBpZiAocm9vdEVsTmFtZSA9PT0gIlNlcnZpY2VFeGNlcHRpb25SZXBvcnQiKSB7CiAgICAgIGNvbnN0IGVycm9yID0gZmluZENoaWxkRWxlbWVudChyb290RWwsICJTZXJ2aWNlRXhjZXB0aW9uIik7CiAgICAgIGlmIChlcnJvcikgewogICAgICAgIHRocm93IHBhcnNlKGVycm9yLCB1cmwpOwogICAgICB9CiAgICB9CiAgICBpZiAocm9vdEVsTmFtZSA9PT0gIkV4Y2VwdGlvblJlcG9ydCIpIHsKICAgICAgY29uc3QgZXJyb3IgPSBmaW5kQ2hpbGRFbGVtZW50KHJvb3RFbCwgIkV4Y2VwdGlvbiIpOwogICAgICBpZiAoZXJyb3IpIHsKICAgICAgICB0aHJvdyBwYXJzZShlcnJvciwgdXJsKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlc3BvbnNlOwogIH0KICBmdW5jdGlvbiBlbmNvZGVFcnJvcihlcnJvcikgewogICAgY29uc3QgYmFzZSA9IHsKICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZSwKICAgICAgc3RhY2s6IGVycm9yLnN0YWNrLAogICAgICBuYW1lOiBlcnJvci5uYW1lCiAgICB9OwogICAgaWYgKGVycm9yIGluc3RhbmNlb2YgU2VydmljZUV4Y2VwdGlvbkVycm9yKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgLi4uYmFzZSwKICAgICAgICBjb2RlOiBlcnJvci5jb2RlLAogICAgICAgIGxvY2F0b3I6IGVycm9yLmxvY2F0b3IsCiAgICAgICAgcmVzcG9uc2U6IGVycm9yLnJlc3BvbnNlLAogICAgICAgIHJlcXVlc3RVcmw6IGVycm9yLnJlcXVlc3RVcmwKICAgICAgfTsKICAgIH0KICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVuZHBvaW50RXJyb3IpIHsKICAgICAgcmV0dXJuIHsKICAgICAgICAuLi5iYXNlLAogICAgICAgIGh0dHBTdGF0dXM6IGVycm9yLmh0dHBTdGF0dXMsCiAgICAgICAgaXNDcm9zc09yaWdpblJlbGF0ZWQ6IGVycm9yLmlzQ3Jvc3NPcmlnaW5SZWxhdGVkCiAgICAgIH07CiAgICB9CiAgICByZXR1cm4gYmFzZTsKICB9CiAgY29uc3QgZmFsbGJhY2tFdmVudFRhcmdldCA9IG5ldyBFdmVudFRhcmdldCgpOwogIGZ1bmN0aW9uIGFkZFRhc2tIYW5kbGVyKHRhc2tOYW1lLCBzY29wZSwgaGFuZGxlcikgewogICAgY29uc3QgdXNlV29ya2VyID0gdHlwZW9mIFdvcmtlckdsb2JhbFNjb3BlICE9PSAidW5kZWZpbmVkIjsKICAgIGNvbnN0IGV2ZW50SGFuZGxlciA9IGFzeW5jIChyZXF1ZXN0KSA9PiB7CiAgICAgIGlmIChyZXF1ZXN0LnRhc2tOYW1lID09PSB0YXNrTmFtZSkgewogICAgICAgIGxldCByZXNwb25zZSwgZXJyb3I7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgaGFuZGxlcihyZXF1ZXN0LnBhcmFtcyk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgZXJyb3IgPSBlbmNvZGVFcnJvcihlKTsKICAgICAgICB9CiAgICAgICAgY29uc3QgbWVzc2FnZSA9ICgKICAgICAgICAgIC8qKiBAdHlwZSB7V29ya2VyUmVzcG9uc2V9ICovCiAgICAgICAgICB7CiAgICAgICAgICAgIHRhc2tOYW1lLAogICAgICAgICAgICByZXF1ZXN0SWQ6IHJlcXVlc3QucmVxdWVzdElkLAogICAgICAgICAgICAuLi5yZXNwb25zZSAmJiB7IHJlc3BvbnNlIH0sCiAgICAgICAgICAgIC4uLmVycm9yICYmIHsgZXJyb3IgfQogICAgICAgICAgfQogICAgICAgICk7CiAgICAgICAgaWYgKHVzZVdvcmtlcikgewogICAgICAgICAgc2NvcGUucG9zdE1lc3NhZ2UobWVzc2FnZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZhbGxiYWNrRXZlbnRUYXJnZXQuZGlzcGF0Y2hFdmVudCgKICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KCJvZ2MtY2xpZW50LnJlc3BvbnNlIiwgewogICAgICAgICAgICAgIGRldGFpbDogbWVzc2FnZQogICAgICAgICAgICB9KQogICAgICAgICAgKTsKICAgICAgICB9CiAgICAgIH0KICAgIH07CiAgICBpZiAodXNlV29ya2VyKSB7CiAgICAgIHNjb3BlLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCAoZXZlbnQpID0+IGV2ZW50SGFuZGxlcihldmVudC5kYXRhKSk7CiAgICB9IGVsc2UgewogICAgICBmYWxsYmFja0V2ZW50VGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoCiAgICAgICAgIm9nYy1jbGllbnQucmVxdWVzdCIsCiAgICAgICAgKGV2ZW50KSA9PiBldmVudEhhbmRsZXIoZXZlbnQuZGV0YWlsKQogICAgICApOwogICAgfQogIH0KICBjb25zdCBFTkNPRElOR1MgPSBbInV0Zi04IiwgInV0Zi0xNiIsICJpc28tODg1OS0xIl07CiAgY29uc3QgRkFMTEJBQ0tfRU5DT0RJTkcgPSAidXRmLTgiOwogIGZ1bmN0aW9uIGV4dHJhY3RFbmNvZGluZyhjb250ZW50VHlwZSkgewogICAgY29uc3QgbWF0Y2hlcyA9IC9jaGFyc2V0PShbXjtdKykvLmV4ZWMoY29udGVudFR5cGUpOwogICAgcmV0dXJuIG1hdGNoZXMgPyBtYXRjaGVzWzFdIDogbnVsbDsKICB9CiAgZnVuY3Rpb24gZGVjb2RlU3RyaW5nKGJ1ZmZlciwgY29udGVudFR5cGUpIHsKICAgIGNvbnN0IGVuY29kaW5nSGludCA9IGNvbnRlbnRUeXBlID8gZXh0cmFjdEVuY29kaW5nKGNvbnRlbnRUeXBlKSA6IG51bGw7CiAgICBjb25zdCBlbmNvZGluZ0F0dGVtcHRzID0gZW5jb2RpbmdIaW50ID8gW2VuY29kaW5nSGludCwgLi4uRU5DT0RJTkdTXSA6IEVOQ09ESU5HUzsKICAgIGZvciAoY29uc3QgZW5jb2Rpbmcgb2YgZW5jb2RpbmdBdHRlbXB0cykgewogICAgICB0cnkgewogICAgICAgIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoZW5jb2RpbmcsIHsgZmF0YWw6IHRydWUgfSk7CiAgICAgICAgcmV0dXJuIGRlY29kZXIuZGVjb2RlKGJ1ZmZlcik7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgfQogICAgfQogICAgY29uc29sZS53YXJuKAogICAgICBgW29nYy1jbGllbnRdIFhNTCBkb2N1bWVudCBlbmNvZGluZyBjb3VsZCBub3QgYmUgZGV0ZXJtaW5lZCwgZmFsbGluZyBiYWNrIHRvICR7RkFMTEJBQ0tfRU5DT0RJTkd9LmAKICAgICk7CiAgICByZXR1cm4gbmV3IFRleHREZWNvZGVyKEZBTExCQUNLX0VOQ09ESU5HKS5kZWNvZGUoYnVmZmVyKTsKICB9CiAgY29uc3QgZmV0Y2hQcm9taXNlcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgbGV0IGZldGNoT3B0aW9ucyA9IHt9OwogIGZ1bmN0aW9uIHNldEZldGNoT3B0aW9ucyhvcHRpb25zKSB7CiAgICBmZXRjaE9wdGlvbnMgPSBvcHRpb25zOwogIH0KICBmdW5jdGlvbiBnZXRGZXRjaE9wdGlvbnMoKSB7CiAgICByZXR1cm4gZmV0Y2hPcHRpb25zOwogIH0KICBmdW5jdGlvbiBzaGFyZWRGZXRjaCh1cmwsIG1ldGhvZCA9ICJHRVQiLCBhc0pzb24pIHsKICAgIGxldCBmZXRjaEtleSA9IGAke21ldGhvZH0jJHt1cmx9YDsKICAgIGlmIChhc0pzb24pIHsKICAgICAgZmV0Y2hLZXkgPSBgJHttZXRob2R9I2FzSnNvbiMke3VybH1gOwogICAgfQogICAgaWYgKGZldGNoUHJvbWlzZXMuaGFzKGZldGNoS2V5KSkgewogICAgICByZXR1cm4gZmV0Y2hQcm9taXNlcy5nZXQoZmV0Y2hLZXkpOwogICAgfQogICAgY29uc3Qgb3B0aW9ucyA9IHsgLi4uZ2V0RmV0Y2hPcHRpb25zKCkgfTsKICAgIG9wdGlvbnMubWV0aG9kID0gbWV0aG9kOwogICAgaWYgKGFzSnNvbikgewogICAgICBvcHRpb25zLmhlYWRlcnMgPSAiaGVhZGVycyIgaW4gb3B0aW9ucyA/IG9wdGlvbnMuaGVhZGVycyA6IHt9OwogICAgICBvcHRpb25zLmhlYWRlcnNbIkFjY2VwdCJdID0gImFwcGxpY2F0aW9uL2pzb24sYXBwbGljYXRpb24vc2NoZW1hK2pzb24iOwogICAgfQogICAgY29uc3QgcHJvbWlzZSA9IGZldGNoKHVybCwgb3B0aW9ucykuY2F0Y2goKGUpID0+IGUpLnRoZW4oKHJlc3ApID0+IHsKICAgICAgZmV0Y2hQcm9taXNlcy5kZWxldGUoZmV0Y2hLZXkpOwogICAgICByZXR1cm4gcmVzcDsKICAgIH0pOwogICAgZmV0Y2hQcm9taXNlcy5zZXQoZmV0Y2hLZXksIHByb21pc2UpOwogICAgcmV0dXJuIHByb21pc2UudGhlbigocmVzcCkgPT4gewogICAgICBpZiAocmVzcCBpbnN0YW5jZW9mIEVycm9yKQogICAgICAgIHRocm93IHJlc3A7CiAgICAgIHJldHVybiByZXNwLmNsb25lKCk7CiAgICB9KTsKICB9CiAgZnVuY3Rpb24gcXVlcnlYbWxEb2N1bWVudCh1cmwpIHsKICAgIHJldHVybiBzaGFyZWRGZXRjaCh1cmwpLmNhdGNoKAogICAgICAoKSA9PiAoCiAgICAgICAgLy8gYXR0ZW1wdCBhIEhFQUQgdG8gc2VlIGlmIHRoZSBmYWlsdXJlIGNvbWVzIGZyb20gQ09SUyBvciB0aGUgc2VydmljZSBpcyBnZW5lcmFsbHkgdW5yZWFjaGFibGUKICAgICAgICBmZXRjaCh1cmwsIHsgLi4uZ2V0RmV0Y2hPcHRpb25zKCksIG1ldGhvZDogIkhFQUQiLCBtb2RlOiAibm8tY29ycyIgfSkuY2F0Y2goKGVycm9yKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRW5kcG9pbnRFcnJvcigKICAgICAgICAgICAgYEZldGNoaW5nIHRoZSBkb2N1bWVudCBmYWlsZWQgZWl0aGVyIGR1ZSB0byBuZXR3b3JrIGVycm9ycyBvciB1bnJlYWNoYWJsZSBob3N0LCBlcnJvciBpczogJHtlcnJvci5tZXNzYWdlfWAsCiAgICAgICAgICAgIDAsCiAgICAgICAgICAgIGZhbHNlCiAgICAgICAgICApOwogICAgICAgIH0pLnRoZW4oKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVuZHBvaW50RXJyb3IoCiAgICAgICAgICAgIGBUaGUgZG9jdW1lbnQgY291bGQgbm90IGJlIGZldGNoZWQgZHVlIHRvIENPUlMgbGltaXRhdGlvbnNgLAogICAgICAgICAgICAwLAogICAgICAgICAgICB0cnVlCiAgICAgICAgICApOwogICAgICAgIH0pCiAgICAgICkKICAgICkudGhlbihhc3luYyAocmVzcCkgPT4gewogICAgICBpZiAoIXJlc3Aub2spIHsKICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVzcC50ZXh0KCk7CiAgICAgICAgdGhyb3cgbmV3IEVuZHBvaW50RXJyb3IoCiAgICAgICAgICBgUmVjZWl2ZWQgYW4gZXJyb3Igd2l0aCBjb2RlICR7cmVzcC5zdGF0dXN9OiAke3RleHR9YCwKICAgICAgICAgIHJlc3Auc3RhdHVzLAogICAgICAgICAgZmFsc2UKICAgICAgICApOwogICAgICB9CiAgICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IHJlc3AuYXJyYXlCdWZmZXIoKTsKICAgICAgY29uc3QgY29udGVudFR5cGVIZWFkZXIgPSByZXNwLmhlYWRlcnMuZ2V0KCJDb250ZW50LVR5cGUiKTsKICAgICAgcmV0dXJuIGRlY29kZVN0cmluZyhidWZmZXIsIGNvbnRlbnRUeXBlSGVhZGVyKTsKICAgIH0pLnRoZW4oKHhtbCkgPT4gcGFyc2VYbWxTdHJpbmcoeG1sKSk7CiAgfQogIGZ1bmN0aW9uIHNldFF1ZXJ5UGFyYW1zKHVybCwgcGFyYW1zKSB7CiAgICBjb25zdCBlbmNvZGVkVXJsTWF0Y2ggPSB1cmwubWF0Y2goLyhodHRwcz8lM0ElMkYlMkZbXi9dKykkLyk7CiAgICBpZiAoZW5jb2RlZFVybE1hdGNoKSB7CiAgICAgIGNvbnN0IGVuY29kZWRVcmwgPSBlbmNvZGVkVXJsTWF0Y2hbMV07CiAgICAgIGNvbnN0IG1vZGlmaWVkVXJsID0gc2V0UXVlcnlQYXJhbXMoZGVjb2RlVVJJQ29tcG9uZW50KGVuY29kZWRVcmwpLCBwYXJhbXMpOwogICAgICByZXR1cm4gdXJsLnJlcGxhY2UoZW5jb2RlZFVybCwgZW5jb2RlVVJJQ29tcG9uZW50KG1vZGlmaWVkVXJsKSk7CiAgICB9CiAgICBjb25zdCB1cmxPYmogPSBuZXcgVVJMKHVybCk7CiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMocGFyYW1zKTsKICAgIGNvbnN0IGtleXNMb3dlciA9IGtleXMubWFwKChrZXkpID0+IGtleS50b0xvd2VyQ2FzZSgpKTsKICAgIGNvbnN0IHRvRGVsZXRlID0gW107CiAgICBmb3IgKGNvbnN0IHBhcmFtIG9mIHVybE9iai5zZWFyY2hQYXJhbXMua2V5cygpKSB7CiAgICAgIGlmIChrZXlzTG93ZXIuaW5kZXhPZihwYXJhbS50b0xvd2VyQ2FzZSgpKSA+IC0xKSB7CiAgICAgICAgdG9EZWxldGUucHVzaChwYXJhbSk7CiAgICAgIH0KICAgIH0KICAgIHRvRGVsZXRlLm1hcCgocGFyYW0pID0+IHVybE9iai5zZWFyY2hQYXJhbXMuZGVsZXRlKHBhcmFtKSk7CiAgICBrZXlzLmZvckVhY2goCiAgICAgIChrZXkpID0+IHVybE9iai5zZWFyY2hQYXJhbXMuc2V0KAogICAgICAgIGtleSwKICAgICAgICBwYXJhbXNba2V5XSA9PT0gdHJ1ZSA/ICIiIDogcGFyYW1zW2tleV0KICAgICAgKQogICAgKTsKICAgIHJldHVybiB1cmxPYmoudG9TdHJpbmcoKTsKICB9CiAgY29uc3QgTGF0TG9uQ3JzTGlzdCA9IFsKICAgICJFUFNHOjQwNDYiLAogICAgLy8gUkdSREMgMjAwNQogICAgIkVQU0c6NDA3NSIsCiAgICAvLyBTUkVGOTgKICAgICJFUFNHOjQxMjAiLAogICAgLy8gR3JlZWsKICAgICJFUFNHOjQxMjIiLAogICAgLy8gQVRTNzcKICAgICJFUFNHOjQxMjQiLAogICAgLy8gUlQ5MAogICAgIkVQU0c6NDEyNiIsCiAgICAvLyBMS1M5NCAoRVRSUzg5KQogICAgIkVQU0c6NDE0OSIsCiAgICAvLyBDSDE5MDMKICAgICJFUFNHOjQxNTEiLAogICAgLy8gQ0hUUkY5NQogICAgIkVQU0c6NDE1MyIsCiAgICAvLyBSYXNzYWRpcmFuCiAgICAiRVBTRzo0MTU1IiwKICAgIC8vIERhYm9sYSAxOTgxCiAgICAiRVBTRzo0MTU3IiwKICAgIC8vIE1vdW50IERpbGxvbgogICAgIkVQU0c6NDE1OSIsCiAgICAvLyBFTEQ3OQogICAgIkVQU0c6NDE2MSIsCiAgICAvLyBQYW1wYSBkZWwgQ2FzdGlsbG8KICAgICJFUFNHOjQxNjMiLAogICAgLy8gWWVtZW4gTkdOOTYKICAgICJFUFNHOjQxNjUiLAogICAgLy8gQmlzc2F1CiAgICAiRVBTRzo0MTY3IiwKICAgIC8vIE5aR0QyMDAwCiAgICAiRVBTRzo0MTY5IiwKICAgIC8vIEFtZXJpY2FuIFNhbW9hIDE5NjIKICAgICJFUFNHOjQxNzEiLAogICAgLy8gUkdGOTMKICAgICJFUFNHOjQxNzMiLAogICAgLy8gSVJFTkVUOTUKICAgICJFUFNHOjQxNzUiLAogICAgLy8gU2llcnJhIExlb25lIDE5NjgKICAgICJFUFNHOjQxNzgiLAogICAgLy8gUHVsa292byAxOTQyKDgzKQogICAgIkVQU0c6NDE4MCIsCiAgICAvLyBFU1Q5NwogICAgIkVQU0c6NDE4MiIsCiAgICAvLyBBem9yZXMgT2NjaWRlbnRhbCAxOTM5CiAgICAiRVBTRzo0MTg0IiwKICAgIC8vIEF6b3JlcyBPcmllbnRhbCAxOTQwCiAgICAiRVBTRzo0MTg4IiwKICAgIC8vIE9TTkkgMTk1MgogICAgIkVQU0c6NDE5MCIsCiAgICAvLyBQT1NHQVIgOTgKICAgICJFUFNHOjQxOTEiLAogICAgLy8gQWxiYW5pYW4gMTk4NwogICAgIkVQU0c6NDE5NiIsCiAgICAvLyBBbW1hc3NhbGlrIDE5NTgKICAgICJFUFNHOjQxOTgiLAogICAgLy8gS291c3NlcmkKICAgICJFUFNHOjQyMDIiLAogICAgLy8gQUdENjYKICAgICJFUFNHOjQyMTAiLAogICAgLy8gQXJjIDE5NjAKICAgICJFUFNHOjQyMTEiLAogICAgLy8gQmF0YXZpYQogICAgIkVQU0c6NDIxNCIsCiAgICAvLyBCZWlqaW5nIDE5NTQKICAgICJFUFNHOjQyMjYiLAogICAgLy8gQ290ZSBkJ0l2b2lyZQogICAgIkVQU0c6NDIyOSIsCiAgICAvLyBFZ3lwdCAxOTA3CiAgICAiRVBTRzo0MjMxIiwKICAgIC8vIEVEODcKICAgICJFUFNHOjQyMzMiLAogICAgLy8gR2FuZGFqaWthIDE5NzAKICAgICJFUFNHOjQyMzYiLAogICAgLy8gSHUgVHp1IFNoYW4gMTk1MAogICAgIkVQU0c6NDIzOCIsCiAgICAvLyBJRDc0CiAgICAiRVBTRzo0MjQwIiwKICAgIC8vIEluZGlhbiAxOTc1CiAgICAiRVBTRzo0MjQyIiwKICAgIC8vIEpBRDY5CiAgICAiRVBTRzo0MjQ0IiwKICAgIC8vIEthbmRhd2FsYQogICAgIkVQU0c6NDI0NiIsCiAgICAvLyBLT0MKICAgICJFUFNHOjQyNDgiLAogICAgLy8gUFNBRDU2CiAgICAiRVBTRzo0MjUwIiwKICAgIC8vIExlaWdvbgogICAgIkVQU0c6NDI1MiIsCiAgICAvLyBMb21lCiAgICAiRVBTRzo0MjU1IiwKICAgIC8vIEhlcmF0IE5vcnRoCiAgICAiRVBTRzo0MjU4IiwKICAgIC8vIEVUUlM4OQogICAgIkVQU0c6NDI2MSIsCiAgICAvLyBNZXJjaGljaAogICAgIkVQU0c6NDI2NCIsCiAgICAvLyBNaGFzdAogICAgIkVQU0c6NDI2NyIsCiAgICAvLyBOQUQyNwogICAgIkVQU0c6NDI3MCIsCiAgICAvLyBOYWhyd2FuIDE5NjcKICAgICJFUFNHOjQyNzMiLAogICAgLy8gTkdPIDE5NDgKICAgICJFUFNHOjQyNzYiLAogICAgLy8gTlNXQyA5Wi0yCiAgICAiRVBTRzo0Mjc5IiwKICAgIC8vIE9TKFNOKTgwCiAgICAiRVBTRzo0MjgxIiwKICAgIC8vIFBhbGVzdGluZSAxOTIzCiAgICAiRVBTRzo0Mjg0IiwKICAgIC8vIFB1bGtvdm8gMTk0MgogICAgIkVQU0c6NDI4NiIsCiAgICAvLyBRYXRhciAxOTQ4CiAgICAiRVBTRzo0Mjg4IiwKICAgIC8vIExvbWEgUXVpbnRhbmEKICAgICJFUFNHOjQyOTIiLAogICAgLy8gU2FwcGVyIEhpbGwgMTk0MwogICAgIkVQU0c6NDI5NSIsCiAgICAvLyBTZXJpbmR1bmcKICAgICJFUFNHOjQyOTciLAogICAgLy8gVGFuYW5hcml2ZQogICAgIkVQU0c6NDI5OSIsCiAgICAvLyBUTTY1CiAgICAiRVBTRzo0MzAyIiwKICAgIC8vIFRyaW5pZGFkIDE5MDMKICAgICJFUFNHOjQzMjQiLAogICAgLy8gV0dTIDcyQkUKICAgICJFUFNHOjQzMjYiCiAgICAvLyBXR1MgODQKICBdOwogIGZ1bmN0aW9uIGhhc0ludmVydGVkQ29vcmRpbmF0ZXMoY3JzTmFtZSkgewogICAgcmV0dXJuIExhdExvbkNyc0xpc3QuaW5kZXhPZihzaW1wbGlmeUVwc2dVcm4oY3JzTmFtZSkpID4gLTE7CiAgfQogIGZ1bmN0aW9uIHNpbXBsaWZ5RXBzZ1VybihmdWxsQ3JzTmFtZSkgewogICAgaWYgKC9edXJuOig/OngtKT9vZ2M6ZGVmOmNyczplcHNnOi8udGVzdChmdWxsQ3JzTmFtZS50b0xvd2VyQ2FzZSgpKSkgewogICAgICBjb25zdCBjb2RlID0gLyhbMC05XSspJC8uZXhlYyhmdWxsQ3JzTmFtZSlbMV07CiAgICAgIHJldHVybiBgRVBTRzoke2NvZGV9YDsKICAgIH0KICAgIHJldHVybiBmdWxsQ3JzTmFtZTsKICB9CiAgZnVuY3Rpb24gcmVhZE9wZXJhdGlvblVybHNGcm9tQ2FwYWJpbGl0aWVzJDEoY2FwYWJpbGl0aWVzRG9jKSB7CiAgICBjb25zdCB1cmxzID0ge307CiAgICBjb25zdCBjYXBhYmlsaXR5ID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwKICAgICAgIkNhcGFiaWxpdHkiCiAgICApOwogICAgY29uc3QgcmVxdWVzdCA9IGZpbmRDaGlsZEVsZW1lbnQoY2FwYWJpbGl0eSwgIlJlcXVlc3QiKTsKICAgIGdldENoaWxkcmVuRWxlbWVudChyZXF1ZXN0KS5mb3JFYWNoKChvcGVyYXRpb24pID0+IHsKICAgICAgY29uc3Qgb3BlcmF0aW9uTmFtZSA9IHN0cmlwTmFtZXNwYWNlKGdldEVsZW1lbnROYW1lKG9wZXJhdGlvbikpOwogICAgICB1cmxzW29wZXJhdGlvbk5hbWVdID0gcGFyc2VPcGVyYXRpb24ob3BlcmF0aW9uKTsKICAgIH0pOwogICAgcmV0dXJuIHVybHM7CiAgfQogIGZ1bmN0aW9uIHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyQxKGNhcGFiaWxpdGllc0RvYykgewogICAgcmV0dXJuIGdldFJvb3RFbGVtZW50KGNhcGFiaWxpdGllc0RvYykuYXR0cmlidXRlc1sidmVyc2lvbiJdOwogIH0KICBmdW5jdGlvbiByZWFkTGF5ZXJzRnJvbUNhcGFiaWxpdGllcyQxKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3QgdmVyc2lvbiA9IHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyQxKGNhcGFiaWxpdGllc0RvYyk7CiAgICBjb25zdCBjYXBhYmlsaXR5ID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwKICAgICAgIkNhcGFiaWxpdHkiCiAgICApOwogICAgcmV0dXJuIGZpbmRDaGlsZHJlbkVsZW1lbnQoY2FwYWJpbGl0eSwgIkxheWVyIikubWFwKAogICAgICAobGF5ZXJFbCkgPT4gcGFyc2VMYXllcihsYXllckVsLCB2ZXJzaW9uKQogICAgKTsKICB9CiAgZnVuY3Rpb24gcmVhZE91dHB1dEZvcm1hdHNGcm9tQ2FwYWJpbGl0aWVzJDEoY2FwYWJpbGl0aWVzRG9jKSB7CiAgICBjb25zdCBjYXBhYmlsaXR5ID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwKICAgICAgIkNhcGFiaWxpdHkiCiAgICApOwogICAgY29uc3QgZ2V0TWFwID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgZmluZENoaWxkRWxlbWVudChjYXBhYmlsaXR5LCAiUmVxdWVzdCIpLAogICAgICAiR2V0TWFwIgogICAgKTsKICAgIGNvbnN0IG91dHB1dEZvcm1hdHMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGdldE1hcCwgIkZvcm1hdCIpLm1hcCgKICAgICAgZ2V0RWxlbWVudFRleHQKICAgICk7CiAgICByZXR1cm4gb3V0cHV0Rm9ybWF0czsKICB9CiAgZnVuY3Rpb24gcmVhZEluZm9Gb3JtYXRzRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpIHsKICAgIGNvbnN0IGNhcGFiaWxpdHkgPSBmaW5kQ2hpbGRFbGVtZW50KAogICAgICBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLAogICAgICAiQ2FwYWJpbGl0eSIKICAgICk7CiAgICBjb25zdCBnZXRGZWF0dXJlSW5mbyA9IGZpbmRDaGlsZEVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQoY2FwYWJpbGl0eSwgIlJlcXVlc3QiKSwKICAgICAgIkdldEZlYXR1cmVJbmZvIgogICAgKTsKICAgIGNvbnN0IG91dHB1dEZvcm1hdHMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGdldEZlYXR1cmVJbmZvLCAiRm9ybWF0IikubWFwKAogICAgICBnZXRFbGVtZW50VGV4dAogICAgKTsKICAgIHJldHVybiBvdXRwdXRGb3JtYXRzOwogIH0KICBmdW5jdGlvbiByZWFkRXhjZXB0aW9uRm9ybWF0c0Zyb21DYXBhYmlsaXRpZXMoY2FwYWJpbGl0aWVzRG9jKSB7CiAgICBjb25zdCBjYXBhYmlsaXR5ID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwKICAgICAgIkNhcGFiaWxpdHkiCiAgICApOwogICAgY29uc3QgZXhjZXB0aW9uID0gZmluZENoaWxkRWxlbWVudChjYXBhYmlsaXR5LCAiRXhjZXB0aW9uIik7CiAgICBjb25zdCBleGNlcHRpb25Gb3JtYXRzID0gZmluZENoaWxkcmVuRWxlbWVudChleGNlcHRpb24sICJGb3JtYXQiKS5tYXAoCiAgICAgIGdldEVsZW1lbnRUZXh0CiAgICApOwogICAgcmV0dXJuIGV4Y2VwdGlvbkZvcm1hdHM7CiAgfQogIGZ1bmN0aW9uIHJlYWRJbmZvRnJvbUNhcGFiaWxpdGllcyQyKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3Qgc2VydmljZSA9IGZpbmRDaGlsZEVsZW1lbnQoZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwgIlNlcnZpY2UiKTsKICAgIGNvbnN0IG91dHB1dEZvcm1hdHMgPSByZWFkT3V0cHV0Rm9ybWF0c0Zyb21DYXBhYmlsaXRpZXMkMShjYXBhYmlsaXRpZXNEb2MpOwogICAgY29uc3QgaW5mb0Zvcm1hdHMgPSByZWFkSW5mb0Zvcm1hdHNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYyk7CiAgICBjb25zdCBleGNlcHRpb25Gb3JtYXRzID0gcmVhZEV4Y2VwdGlvbkZvcm1hdHNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYyk7CiAgICBjb25zdCBrZXl3b3JkcyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIktleXdvcmRMaXN0IiksCiAgICAgICJLZXl3b3JkIgogICAgKS5tYXAoZ2V0RWxlbWVudFRleHQpLmZpbHRlcigodiwgaSwgYXJyKSA9PiBhcnIuaW5kZXhPZih2KSA9PT0gaSk7CiAgICBjb25zdCBwcm92aWRlciA9IHJlYWRQcm92aWRlckZyb21DYXBhYmlsaXRpZXMkMShjYXBhYmlsaXRpZXNEb2MpOwogICAgcmV0dXJuIHsKICAgICAgdGl0bGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIlRpdGxlIikpLAogICAgICBuYW1lOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJOYW1lIikpLAogICAgICBhYnN0cmFjdDogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzZXJ2aWNlLCAiQWJzdHJhY3QiKSksCiAgICAgIG91dHB1dEZvcm1hdHMsCiAgICAgIGluZm9Gb3JtYXRzLAogICAgICBleGNlcHRpb25Gb3JtYXRzLAogICAgICBmZWVzOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJGZWVzIikpLAogICAgICBjb25zdHJhaW50czogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzZXJ2aWNlLCAiQWNjZXNzQ29uc3RyYWludHMiKSksCiAgICAgIHByb3ZpZGVyLAogICAgICBrZXl3b3JkcwogICAgfTsKICB9CiAgZnVuY3Rpb24gcGFyc2VPcGVyYXRpb24ob3BlcmF0aW9uKSB7CiAgICBjb25zdCB1cmxzID0ge307CiAgICBjb25zdCBkY3BUeXBlID0gZmluZENoaWxkcmVuRWxlbWVudChvcGVyYXRpb24sICJEQ1BUeXBlIik7CiAgICBjb25zdCBodHRwID0gZGNwVHlwZS5mbGF0TWFwKChkKSA9PiBmaW5kQ2hpbGRFbGVtZW50KGQsICJIVFRQIikpOwogICAgY29uc3QgbWV0aG9kcyA9IGh0dHAuZmxhdE1hcCgoaCkgPT4gZ2V0Q2hpbGRyZW5FbGVtZW50KGgpKTsKICAgIG1ldGhvZHMuZm9yRWFjaCgobWV0aG9kKSA9PiB7CiAgICAgIGNvbnN0IG9ubGluZVJlc291cmNlID0gZmluZENoaWxkRWxlbWVudChtZXRob2QsICJPbmxpbmVSZXNvdXJjZSIpOwogICAgICBjb25zdCBtZXRob2ROYW1lID0gc3RyaXBOYW1lc3BhY2UoZ2V0RWxlbWVudE5hbWUobWV0aG9kKSk7CiAgICAgIHVybHNbbWV0aG9kTmFtZV0gPSBnZXRFbGVtZW50QXR0cmlidXRlKG9ubGluZVJlc291cmNlLCAieGxpbms6aHJlZiIpOwogICAgfSk7CiAgICByZXR1cm4gdXJsczsKICB9CiAgZnVuY3Rpb24gcGFyc2VMYXllcihsYXllckVsLCB2ZXJzaW9uLCBpbmhlcml0ZWRTcnMgPSBbXSwgaW5oZXJpdGVkU3R5bGVzID0gW10sIGluaGVyaXRlZEF0dHJpYnV0aW9uID0gbnVsbCwgaW5oZXJpdGVkQm91bmRpbmdCb3hlcyA9IG51bGwsIGluaGVyaXRlZE1heFNjYWxlRGVub20gPSBudWxsLCBpbmhlcml0ZWRNaW5TY2FsZURlbm9tID0gbnVsbCkgewogICAgY29uc3Qgc3JzVGFnID0gdmVyc2lvbiA9PT0gIjEuMy4wIiA/ICJDUlMiIDogIlNSUyI7CiAgICBjb25zdCBzcnNMaXN0ID0gZmluZENoaWxkcmVuRWxlbWVudChsYXllckVsLCBzcnNUYWcpLm1hcChnZXRFbGVtZW50VGV4dCk7CiAgICBjb25zdCBhdmFpbGFibGVDcnMgPSBzcnNMaXN0Lmxlbmd0aCA+IDAgPyBzcnNMaXN0IDogaW5oZXJpdGVkU3JzOwogICAgY29uc3QgbGF5ZXJTdHlsZXMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGxheWVyRWwsICJTdHlsZSIpLm1hcCgKICAgICAgcGFyc2VMYXllclN0eWxlCiAgICApOwogICAgY29uc3Qgc3R5bGVzID0gbGF5ZXJTdHlsZXMubGVuZ3RoID4gMCA/IGxheWVyU3R5bGVzIDogaW5oZXJpdGVkU3R5bGVzOwogICAgZnVuY3Rpb24gcGFyc2VCQm94MihiYm94RWwpIHsKICAgICAgY29uc3Qgc3JzID0gZ2V0RWxlbWVudEF0dHJpYnV0ZShiYm94RWwsIHNyc1RhZyk7CiAgICAgIGNvbnN0IGF0dHJzID0gaGFzSW52ZXJ0ZWRDb29yZGluYXRlcyhzcnMpICYmIHZlcnNpb24gPT09ICIxLjMuMCIgPyBbIm1pbnkiLCAibWlueCIsICJtYXh5IiwgIm1heHgiXSA6IFsibWlueCIsICJtaW55IiwgIm1heHgiLCAibWF4eSJdOwogICAgICByZXR1cm4gYXR0cnMubWFwKChuYW1lKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGJib3hFbCwgbmFtZSkpOwogICAgfQogICAgZnVuY3Rpb24gcGFyc2VFeEdlb2dyYXBoaWNCb3VuZGluZ0JveChiYm94RWwpIHsKICAgICAgcmV0dXJuIFsKICAgICAgICAid2VzdEJvdW5kTG9uZ2l0dWRlIiwKICAgICAgICAic291dGhCb3VuZExhdGl0dWRlIiwKICAgICAgICAiZWFzdEJvdW5kTG9uZ2l0dWRlIiwKICAgICAgICAibm9ydGhCb3VuZExhdGl0dWRlIgogICAgICBdLm1hcCgobmFtZSkgPT4gZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChiYm94RWwsIG5hbWUpKSk7CiAgICB9CiAgICBmdW5jdGlvbiBwYXJzZUxhdExvbkJvdW5kaW5nQm94KGJib3hFbCkgewogICAgICByZXR1cm4gWyJtaW54IiwgIm1pbnkiLCAibWF4eCIsICJtYXh5Il0ubWFwKAogICAgICAgIChuYW1lKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGJib3hFbCwgbmFtZSkKICAgICAgKTsKICAgIH0KICAgIGZ1bmN0aW9uIHBhcnNlU2NhbGVIaW50VmFsdWUodGV4dFZhbHVlLCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKHRleHRWYWx1ZSA9PT0gIiIpIHsKICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIHJldHVybiBNYXRoLnNxcnQoMC41ICogcGFyc2VGbG9hdCh0ZXh0VmFsdWUpICoqIDIpIC8gMjhlLTU7CiAgICB9CiAgICBmdW5jdGlvbiBwYXJzZVNjYWxlSGludCgpIHsKICAgICAgY29uc3Qgc2NhbGVIaW50ID0gZmluZENoaWxkRWxlbWVudChsYXllckVsLCAiU2NhbGVIaW50Iik7CiAgICAgIGlmICghc2NhbGVIaW50KSB7CiAgICAgICAgcmV0dXJuIFtpbmhlcml0ZWRNaW5TY2FsZURlbm9tLCBpbmhlcml0ZWRNYXhTY2FsZURlbm9tXTsKICAgICAgfQogICAgICBjb25zdCBtaW4gPSBnZXRFbGVtZW50QXR0cmlidXRlKHNjYWxlSGludCwgIm1pbiIpOwogICAgICBjb25zdCBtYXggPSBnZXRFbGVtZW50QXR0cmlidXRlKHNjYWxlSGludCwgIm1heCIpOwogICAgICByZXR1cm4gWwogICAgICAgIHBhcnNlU2NhbGVIaW50VmFsdWUobWluLCBpbmhlcml0ZWRNaW5TY2FsZURlbm9tKSwKICAgICAgICBwYXJzZVNjYWxlSGludFZhbHVlKG1heCwgaW5oZXJpdGVkTWF4U2NhbGVEZW5vbSkKICAgICAgXTsKICAgIH0KICAgIGZ1bmN0aW9uIHBhcnNlU2NhbGVEZW5vbWluYXRvcihuYW1lLCBpbmhlcml0ZWRWYWx1ZSkgewogICAgICBjb25zdCB0ZXh0VmFsdWUgPSBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGxheWVyRWwsIG5hbWUpKTsKICAgICAgcmV0dXJuIHRleHRWYWx1ZSA9PT0gIiIgPyBpbmhlcml0ZWRWYWx1ZSA6IHBhcnNlRmxvYXQodGV4dFZhbHVlKTsKICAgIH0KICAgIGNvbnN0IGF0dHJpYnV0aW9uRWwgPSBmaW5kQ2hpbGRFbGVtZW50KGxheWVyRWwsICJBdHRyaWJ1dGlvbiIpOwogICAgY29uc3QgYXR0cmlidXRpb24gPSBhdHRyaWJ1dGlvbkVsICE9PSBudWxsID8gcGFyc2VMYXllckF0dHJpYnV0aW9uKGF0dHJpYnV0aW9uRWwpIDogaW5oZXJpdGVkQXR0cmlidXRpb247CiAgICBjb25zdCBsYXRMb25CYm94RWwgPSB2ZXJzaW9uID09PSAiMS4zLjAiID8gZmluZENoaWxkRWxlbWVudChsYXllckVsLCAiRVhfR2VvZ3JhcGhpY0JvdW5kaW5nQm94IikgOiBmaW5kQ2hpbGRFbGVtZW50KGxheWVyRWwsICJMYXRMb25Cb3VuZGluZ0JveCIpOwogICAgY29uc3QgYmFzZUJvdW5kaW5nQm94ID0ge307CiAgICBpZiAobGF0TG9uQmJveEVsKSB7CiAgICAgIGJhc2VCb3VuZGluZ0JveFsiRVBTRzo0MzI2Il0gPSB2ZXJzaW9uID09PSAiMS4zLjAiID8gcGFyc2VFeEdlb2dyYXBoaWNCb3VuZGluZ0JveChsYXRMb25CYm94RWwpIDogcGFyc2VMYXRMb25Cb3VuZGluZ0JveChsYXRMb25CYm94RWwpOwogICAgfQogICAgbGV0IGJvdW5kaW5nQm94ZXMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGxheWVyRWwsICJCb3VuZGluZ0JveCIpLnJlZHVjZSgKICAgICAgKHByZXYsIGJib3hFbCkgPT4gKHsKICAgICAgICAuLi5wcmV2LAogICAgICAgIFtnZXRFbGVtZW50QXR0cmlidXRlKGJib3hFbCwgc3JzVGFnKV06IHBhcnNlQkJveDIoYmJveEVsKQogICAgICB9KSwKICAgICAgYmFzZUJvdW5kaW5nQm94CiAgICApOwogICAgYm91bmRpbmdCb3hlcyA9IE9iamVjdC5rZXlzKGJvdW5kaW5nQm94ZXMpLmxlbmd0aCA+IDAgfHwgaW5oZXJpdGVkQm91bmRpbmdCb3hlcyA9PT0gbnVsbCA/IGJvdW5kaW5nQm94ZXMgOiBpbmhlcml0ZWRCb3VuZGluZ0JveGVzOwogICAgY29uc3QgcXVlcnlhYmxlID0gbGF5ZXJFbC5hdHRyaWJ1dGVzLnF1ZXJ5YWJsZSA9PT0gIjEiIHx8IGxheWVyRWwuYXR0cmlidXRlcy5xdWVyeWFibGUgPT09ICJ0cnVlIiA/IHRydWUgOiBmYWxzZTsKICAgIGNvbnN0IG9wYXF1ZSA9IGxheWVyRWwuYXR0cmlidXRlcy5vcGFxdWUgPT09ICIxIiB8fCBsYXllckVsLmF0dHJpYnV0ZXMub3BhcXVlID09PSAidHJ1ZSIgPyB0cnVlIDogZmFsc2U7CiAgICBjb25zdCBrZXl3b3JkcyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQobGF5ZXJFbCwgIktleXdvcmRMaXN0IiksCiAgICAgICJLZXl3b3JkIgogICAgKS5tYXAoZ2V0RWxlbWVudFRleHQpLmZpbHRlcigodiwgaSwgYXJyKSA9PiBhcnIuaW5kZXhPZih2KSA9PT0gaSk7CiAgICBsZXQgbWluU2NhbGVEZW5vbWluYXRvciwgbWF4U2NhbGVEZW5vbWluYXRvcjsKICAgIGlmICh2ZXJzaW9uID09PSAiMS4zLjAiKSB7CiAgICAgIG1pblNjYWxlRGVub21pbmF0b3IgPSBwYXJzZVNjYWxlRGVub21pbmF0b3IoCiAgICAgICAgIk1pblNjYWxlRGVub21pbmF0b3IiLAogICAgICAgIGluaGVyaXRlZE1pblNjYWxlRGVub20KICAgICAgKTsKICAgICAgbWF4U2NhbGVEZW5vbWluYXRvciA9IHBhcnNlU2NhbGVEZW5vbWluYXRvcigKICAgICAgICAiTWF4U2NhbGVEZW5vbWluYXRvciIsCiAgICAgICAgaW5oZXJpdGVkTWF4U2NhbGVEZW5vbQogICAgICApOwogICAgfSBlbHNlIHsKICAgICAgW21pblNjYWxlRGVub21pbmF0b3IsIG1heFNjYWxlRGVub21pbmF0b3JdID0gcGFyc2VTY2FsZUhpbnQoKTsKICAgIH0KICAgIGNvbnN0IG1ldGFkYXRhID0gZmluZENoaWxkcmVuRWxlbWVudChsYXllckVsLCAiTWV0YWRhdGFVUkwiKS5tYXAoCiAgICAgIChtZXRhZGF0YVVybEVsKSA9PiAoewogICAgICAgIHR5cGU6IGdldEVsZW1lbnRBdHRyaWJ1dGUobWV0YWRhdGFVcmxFbCwgInR5cGUiKSwKICAgICAgICBmb3JtYXQ6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQobWV0YWRhdGFVcmxFbCwgIkZvcm1hdCIpKSwKICAgICAgICB1cmw6IGdldEVsZW1lbnRBdHRyaWJ1dGUoCiAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KG1ldGFkYXRhVXJsRWwsICJPbmxpbmVSZXNvdXJjZSIpLAogICAgICAgICAgInhsaW5rOmhyZWYiCiAgICAgICAgKQogICAgICB9KQogICAgKTsKICAgIGNvbnN0IGNoaWxkcmVuID0gZmluZENoaWxkcmVuRWxlbWVudChsYXllckVsLCAiTGF5ZXIiKS5tYXAoCiAgICAgIChsYXllcikgPT4gcGFyc2VMYXllcigKICAgICAgICBsYXllciwKICAgICAgICB2ZXJzaW9uLAogICAgICAgIGF2YWlsYWJsZUNycywKICAgICAgICBzdHlsZXMsCiAgICAgICAgYXR0cmlidXRpb24sCiAgICAgICAgYm91bmRpbmdCb3hlcywKICAgICAgICBtYXhTY2FsZURlbm9taW5hdG9yLAogICAgICAgIG1pblNjYWxlRGVub21pbmF0b3IKICAgICAgKQogICAgKTsKICAgIHJldHVybiB7CiAgICAgIG5hbWU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQobGF5ZXJFbCwgIk5hbWUiKSksCiAgICAgIHRpdGxlOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGxheWVyRWwsICJUaXRsZSIpKSwKICAgICAgYWJzdHJhY3Q6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQobGF5ZXJFbCwgIkFic3RyYWN0IikpLAogICAgICBhdmFpbGFibGVDcnMsCiAgICAgIHN0eWxlcywKICAgICAgYXR0cmlidXRpb24sCiAgICAgIGJvdW5kaW5nQm94ZXMsCiAgICAgIGtleXdvcmRzLAogICAgICBxdWVyeWFibGUsCiAgICAgIG9wYXF1ZSwKICAgICAgLi4ubWluU2NhbGVEZW5vbWluYXRvciAhPT0gbnVsbCA/IHsgbWluU2NhbGVEZW5vbWluYXRvciB9IDoge30sCiAgICAgIC4uLm1heFNjYWxlRGVub21pbmF0b3IgIT09IG51bGwgPyB7IG1heFNjYWxlRGVub21pbmF0b3IgfSA6IHt9LAogICAgICAuLi5tZXRhZGF0YS5sZW5ndGggJiYgeyBtZXRhZGF0YSB9LAogICAgICAuLi5jaGlsZHJlbi5sZW5ndGggJiYgeyBjaGlsZHJlbiB9CiAgICB9OwogIH0KICBmdW5jdGlvbiBwYXJzZUxheWVyU3R5bGUoc3R5bGVFbCkgewogICAgY29uc3QgbGVnZW5kVXJsID0gZ2V0RWxlbWVudEF0dHJpYnV0ZSgKICAgICAgZmluZENoaWxkRWxlbWVudChmaW5kQ2hpbGRFbGVtZW50KHN0eWxlRWwsICJMZWdlbmRVUkwiKSwgIk9ubGluZVJlc291cmNlIiksCiAgICAgICJ4bGluazpocmVmIgogICAgKTsKICAgIGNvbnN0IGFic3RyYWN0ID0gZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzdHlsZUVsLCAiQWJzdHJhY3QiKSk7CiAgICByZXR1cm4gewogICAgICBuYW1lOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHN0eWxlRWwsICJOYW1lIikpLAogICAgICB0aXRsZTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzdHlsZUVsLCAiVGl0bGUiKSksCiAgICAgIC4uLmFic3RyYWN0ICYmIHsgYWJzdHJhY3QgfSwKICAgICAgLi4ubGVnZW5kVXJsICYmIHsgbGVnZW5kVXJsIH0KICAgIH07CiAgfQogIGZ1bmN0aW9uIHBhcnNlTGF5ZXJBdHRyaWJ1dGlvbihhdHRyaWJ1dGlvbkVsKSB7CiAgICBjb25zdCBsb2dvVXJsID0gZ2V0RWxlbWVudEF0dHJpYnV0ZSgKICAgICAgZmluZENoaWxkRWxlbWVudCgKICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGF0dHJpYnV0aW9uRWwsICJMb2dvVVJMIiksCiAgICAgICAgIk9ubGluZVJlc291cmNlIgogICAgICApLAogICAgICAieGxpbms6aHJlZiIKICAgICk7CiAgICBjb25zdCB1cmwgPSBnZXRFbGVtZW50QXR0cmlidXRlKAogICAgICBmaW5kQ2hpbGRFbGVtZW50KGF0dHJpYnV0aW9uRWwsICJPbmxpbmVSZXNvdXJjZSIpLAogICAgICAieGxpbms6aHJlZiIKICAgICk7CiAgICBjb25zdCB0aXRsZSA9IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoYXR0cmlidXRpb25FbCwgIlRpdGxlIikpOwogICAgcmV0dXJuIHsKICAgICAgLi4udGl0bGUgJiYgeyB0aXRsZSB9LAogICAgICAuLi51cmwgJiYgeyB1cmwgfSwKICAgICAgLi4ubG9nb1VybCAmJiB7IGxvZ29VcmwgfQogICAgfTsKICB9CiAgZnVuY3Rpb24gcmVhZFByb3ZpZGVyRnJvbUNhcGFiaWxpdGllcyQxKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3Qgc2VydmljZSA9IGZpbmRDaGlsZEVsZW1lbnQoZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwgIlNlcnZpY2UiKTsKICAgIGNvbnN0IGNvbnRhY3RJbmZvcm1hdGlvbiA9IGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIkNvbnRhY3RJbmZvcm1hdGlvbiIpOwogICAgY29uc3QgY29udGFjdFBlcnNvblByaW1hcnkgPSBmaW5kQ2hpbGRFbGVtZW50KAogICAgICBjb250YWN0SW5mb3JtYXRpb24sCiAgICAgICJDb250YWN0UGVyc29uUHJpbWFyeSIKICAgICk7CiAgICBjb25zdCBhZGRyZXNzID0gZmluZENoaWxkRWxlbWVudChjb250YWN0SW5mb3JtYXRpb24sICJDb250YWN0QWRkcmVzcyIpOwogICAgcmV0dXJuIHsKICAgICAgY29udGFjdDogewogICAgICAgIG5hbWU6IGdldEVsZW1lbnRUZXh0KAogICAgICAgICAgZmluZENoaWxkRWxlbWVudChjb250YWN0UGVyc29uUHJpbWFyeSwgIkNvbnRhY3RQZXJzb24iKQogICAgICAgICksCiAgICAgICAgb3JnYW5pemF0aW9uOiBnZXRFbGVtZW50VGV4dCgKICAgICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoY29udGFjdFBlcnNvblByaW1hcnksICJDb250YWN0T3JnYW5pemF0aW9uIikKICAgICAgICApLAogICAgICAgIHBvc2l0aW9uOiBnZXRFbGVtZW50VGV4dCgKICAgICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoY29udGFjdEluZm9ybWF0aW9uLCAiQ29udGFjdFBvc2l0aW9uIikKICAgICAgICApLAogICAgICAgIHBob25lOiBnZXRFbGVtZW50VGV4dCgKICAgICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoY29udGFjdEluZm9ybWF0aW9uLCAiQ29udGFjdFZvaWNlVGVsZXBob25lIikKICAgICAgICApLAogICAgICAgIGZheDogZ2V0RWxlbWVudFRleHQoCiAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGNvbnRhY3RJbmZvcm1hdGlvbiwgIkNvbnRhY3RGYWNzaW1pbGVUZWxlcGhvbmUiKQogICAgICAgICksCiAgICAgICAgYWRkcmVzczogewogICAgICAgICAgZGVsaXZlcnlQb2ludDogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChhZGRyZXNzLCAiQWRkcmVzcyIpKSwKICAgICAgICAgIGNpdHk6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoYWRkcmVzcywgIkNpdHkiKSksCiAgICAgICAgICBhZG1pbmlzdHJhdGl2ZUFyZWE6IGdldEVsZW1lbnRUZXh0KAogICAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGFkZHJlc3MsICJTdGF0ZU9yUHJvdmluY2UiKQogICAgICAgICAgKSwKICAgICAgICAgIHBvc3RhbENvZGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoYWRkcmVzcywgIlBvc3RDb2RlIikpLAogICAgICAgICAgY291bnRyeTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChhZGRyZXNzLCAiQ291bnRyeSIpKQogICAgICAgIH0sCiAgICAgICAgZW1haWw6IGdldEVsZW1lbnRUZXh0KAogICAgICAgICAgZmluZENoaWxkRWxlbWVudChjb250YWN0SW5mb3JtYXRpb24sICJDb250YWN0RWxlY3Ryb25pY01haWxBZGRyZXNzIikKICAgICAgICApCiAgICAgIH0KICAgIH07CiAgfQogIGZ1bmN0aW9uIHJlYWRQcm92aWRlckZyb21DYXBhYmlsaXRpZXMoY2FwYWJpbGl0aWVzRG9jKSB7CiAgICBjb25zdCBzZXJ2aWNlUHJvdmlkZXIgPSBmaW5kQ2hpbGRFbGVtZW50KAogICAgICBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLAogICAgICAiU2VydmljZVByb3ZpZGVyIgogICAgKTsKICAgIGNvbnN0IHNlcnZpY2VDb250YWN0ID0gZmluZENoaWxkRWxlbWVudChzZXJ2aWNlUHJvdmlkZXIsICJTZXJ2aWNlQ29udGFjdCIpOwogICAgY29uc3QgY29udGFjdEluZm8gPSBmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2VDb250YWN0LCAiQ29udGFjdEluZm8iKTsKICAgIGNvbnN0IHBob25lID0gZmluZENoaWxkRWxlbWVudChjb250YWN0SW5mbywgIlBob25lIik7CiAgICBjb25zdCBhZGRyZXNzID0gZmluZENoaWxkRWxlbWVudChjb250YWN0SW5mbywgIkFkZHJlc3MiKTsKICAgIHJldHVybiB7CiAgICAgIG5hbWU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZVByb3ZpZGVyLCAiUHJvdmlkZXJOYW1lIikpLAogICAgICBzaXRlOiBnZXRFbGVtZW50QXR0cmlidXRlKAogICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZVByb3ZpZGVyLCAiUHJvdmlkZXJTaXRlIiksCiAgICAgICAgInhsaW5rOmhyZWYiCiAgICAgICksCiAgICAgIGNvbnRhY3Q6IHsKICAgICAgICBuYW1lOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2VDb250YWN0LCAiSW5kaXZpZHVhbE5hbWUiKSksCiAgICAgICAgcG9zaXRpb246IGdldEVsZW1lbnRUZXh0KAogICAgICAgICAgZmluZENoaWxkRWxlbWVudChzZXJ2aWNlQ29udGFjdCwgIlBvc2l0aW9uTmFtZSIpCiAgICAgICAgKSwKICAgICAgICBwaG9uZTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChwaG9uZSwgIlZvaWNlIikpLAogICAgICAgIGZheDogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChwaG9uZSwgIkZhY3NpbWlsZSIpKSwKICAgICAgICBhZGRyZXNzOiB7CiAgICAgICAgICBkZWxpdmVyeVBvaW50OiBnZXRFbGVtZW50VGV4dCgKICAgICAgICAgICAgZmluZENoaWxkRWxlbWVudChhZGRyZXNzLCAiRGVsaXZlcnlQb2ludCIpCiAgICAgICAgICApLAogICAgICAgICAgY2l0eTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChhZGRyZXNzLCAiQ2l0eSIpKSwKICAgICAgICAgIGFkbWluaXN0cmF0aXZlQXJlYTogZ2V0RWxlbWVudFRleHQoCiAgICAgICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoYWRkcmVzcywgIkFkbWluaXN0cmF0aXZlQXJlYSIpCiAgICAgICAgICApLAogICAgICAgICAgcG9zdGFsQ29kZTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChhZGRyZXNzLCAiUG9zdGFsQ29kZSIpKSwKICAgICAgICAgIGNvdW50cnk6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoYWRkcmVzcywgIkNvdW50cnkiKSkKICAgICAgICB9LAogICAgICAgIGVtYWlsOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGFkZHJlc3MsICJFbGVjdHJvbmljTWFpbEFkZHJlc3MiKSkKICAgICAgfQogICAgfTsKICB9CiAgZnVuY3Rpb24gcmVhZE9wZXJhdGlvblVybHNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3QgdXJscyA9IHt9OwogICAgY29uc3QgY2FwYWJpbGl0aWVzID0gZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKTsKICAgIGNvbnN0IG9wZXJhdGlvbnNNZXRhZGF0YSA9IGZpbmRDaGlsZEVsZW1lbnQoCiAgICAgIGNhcGFiaWxpdGllcywKICAgICAgIk9wZXJhdGlvbnNNZXRhZGF0YSIKICAgICk7CiAgICBpZiAob3BlcmF0aW9uc01ldGFkYXRhKSB7CiAgICAgIGZpbmRDaGlsZHJlbkVsZW1lbnQob3BlcmF0aW9uc01ldGFkYXRhLCAiT3BlcmF0aW9uIikuZm9yRWFjaCgKICAgICAgICAob3BlcmF0aW9uKSA9PiB7CiAgICAgICAgICBjb25zdCBuYW1lID0gZ2V0RWxlbWVudEF0dHJpYnV0ZShvcGVyYXRpb24sICJuYW1lIik7CiAgICAgICAgICB1cmxzW25hbWVdID0gcGFyc2VPcGVyYXRpb24xMTAob3BlcmF0aW9uKTsKICAgICAgICB9CiAgICAgICk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBjYXBhYmlsaXR5ID0gZmluZENoaWxkRWxlbWVudChjYXBhYmlsaXRpZXMsICJDYXBhYmlsaXR5Iik7CiAgICAgIGNvbnN0IHJlcXVlc3QgPSBmaW5kQ2hpbGRFbGVtZW50KGNhcGFiaWxpdHksICJSZXF1ZXN0Iik7CiAgICAgIGdldENoaWxkcmVuRWxlbWVudChyZXF1ZXN0KS5mb3JFYWNoKChvcGVyYXRpb24pID0+IHsKICAgICAgICBjb25zdCBuYW1lID0gc3RyaXBOYW1lc3BhY2UoZ2V0RWxlbWVudE5hbWUob3BlcmF0aW9uKSk7CiAgICAgICAgdXJsc1tuYW1lXSA9IHBhcnNlT3BlcmF0aW9uMTAwKG9wZXJhdGlvbik7CiAgICAgIH0pOwogICAgfQogICAgcmV0dXJuIHVybHM7CiAgfQogIGZ1bmN0aW9uIHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpIHsKICAgIHJldHVybiBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLmF0dHJpYnV0ZXNbInZlcnNpb24iXTsKICB9CiAgZnVuY3Rpb24gcmVhZE91dHB1dEZvcm1hdHNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3QgdmVyc2lvbiA9IHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpOwogICAgbGV0IG91dHB1dEZvcm1hdHM7CiAgICBpZiAodmVyc2lvbi5zdGFydHNXaXRoKCIxLjAiKSkgewogICAgICBjb25zdCBnZXRGZWF0dXJlID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KAogICAgICAgICAgZmluZENoaWxkRWxlbWVudChnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLCAiQ2FwYWJpbGl0eSIpLAogICAgICAgICAgIlJlcXVlc3QiCiAgICAgICAgKSwKICAgICAgICAiR2V0RmVhdHVyZSIKICAgICAgKTsKICAgICAgb3V0cHV0Rm9ybWF0cyA9IGdldENoaWxkcmVuRWxlbWVudCgKICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGdldEZlYXR1cmUsICJSZXN1bHRGb3JtYXQiKQogICAgICApLm1hcChnZXRFbGVtZW50TmFtZSk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBvcGVyYXRpb25zID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgICBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLAogICAgICAgICJPcGVyYXRpb25zTWV0YWRhdGEiCiAgICAgICk7CiAgICAgIGNvbnN0IGdldEZlYXR1cmUgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KG9wZXJhdGlvbnMsICJPcGVyYXRpb24iKS5maW5kKAogICAgICAgIChlbCkgPT4gZ2V0RWxlbWVudEF0dHJpYnV0ZShlbCwgIm5hbWUiKSA9PT0gIkdldEZlYXR1cmUiCiAgICAgICk7CiAgICAgIGNvbnN0IHBhcmFtZXRlciA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoZ2V0RmVhdHVyZSwgIlBhcmFtZXRlciIpLmZpbmQoCiAgICAgICAgKGVsKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGVsLCAibmFtZSIpID09PSAib3V0cHV0Rm9ybWF0IgogICAgICApOwogICAgICBvdXRwdXRGb3JtYXRzID0gZmluZENoaWxkcmVuRWxlbWVudChwYXJhbWV0ZXIsICJWYWx1ZSIsIHRydWUpLm1hcCgKICAgICAgICBnZXRFbGVtZW50VGV4dAogICAgICApOwogICAgfQogICAgcmV0dXJuIG91dHB1dEZvcm1hdHM7CiAgfQogIGZ1bmN0aW9uIHJlYWRJbmZvRnJvbUNhcGFiaWxpdGllcyQxKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3QgdmVyc2lvbiA9IHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpOwogICAgY29uc3Qgc2VydmljZVRhZyA9IHZlcnNpb24uc3RhcnRzV2l0aCgiMS4wIikgPyAiU2VydmljZSIgOiAiU2VydmljZUlkZW50aWZpY2F0aW9uIjsKICAgIGNvbnN0IG5hbWVUYWcgPSB2ZXJzaW9uLnN0YXJ0c1dpdGgoIjEuMCIpID8gIk5hbWUiIDogIlNlcnZpY2VUeXBlIjsKICAgIGNvbnN0IHNlcnZpY2UgPSBmaW5kQ2hpbGRFbGVtZW50KGdldFJvb3RFbGVtZW50KGNhcGFiaWxpdGllc0RvYyksIHNlcnZpY2VUYWcpOwogICAgbGV0IGtleXdvcmRzOwogICAgaWYgKHZlcnNpb24uc3RhcnRzV2l0aCgiMS4wIikpIHsKICAgICAga2V5d29yZHMgPSBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJLZXl3b3JkcyIpKS5zcGxpdCgiLCIpLm1hcCgoa2V5d29yZCkgPT4ga2V5d29yZC50cmltKCkpOwogICAgfSBlbHNlIHsKICAgICAga2V5d29yZHMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KAogICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIktleXdvcmRzIiksCiAgICAgICAgIktleXdvcmQiCiAgICAgICkubWFwKGdldEVsZW1lbnRUZXh0KTsKICAgIH0KICAgIGxldCBwcm92aWRlcjsKICAgIGlmICh2ZXJzaW9uICE9PSAiMS4wLjAiKSB7CiAgICAgIHByb3ZpZGVyID0gcmVhZFByb3ZpZGVyRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpOwogICAgfQogICAgcmV0dXJuIHsKICAgICAgdGl0bGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIlRpdGxlIikpLAogICAgICBuYW1lOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsIG5hbWVUYWcpKSwKICAgICAgYWJzdHJhY3Q6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIkFic3RyYWN0IikpLAogICAgICBmZWVzOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJGZWVzIikpLAogICAgICBjb25zdHJhaW50czogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzZXJ2aWNlLCAiQWNjZXNzQ29uc3RyYWludHMiKSksCiAgICAgIGtleXdvcmRzLAogICAgICBwcm92aWRlciwKICAgICAgb3V0cHV0Rm9ybWF0czogcmVhZE91dHB1dEZvcm1hdHNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYykKICAgIH07CiAgfQogIGZ1bmN0aW9uIHJlYWRGZWF0dXJlVHlwZXNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3QgdmVyc2lvbiA9IHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpOwogICAgY29uc3Qgb3V0cHV0Rm9ybWF0cyA9IHJlYWRPdXRwdXRGb3JtYXRzRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpOwogICAgY29uc3QgY2FwYWJpbGl0eSA9IGZpbmRDaGlsZEVsZW1lbnQoCiAgICAgIGdldFJvb3RFbGVtZW50KGNhcGFiaWxpdGllc0RvYyksCiAgICAgICJGZWF0dXJlVHlwZUxpc3QiCiAgICApOwogICAgcmV0dXJuIGZpbmRDaGlsZHJlbkVsZW1lbnQoY2FwYWJpbGl0eSwgIkZlYXR1cmVUeXBlIikubWFwKAogICAgICAoZmVhdHVyZVR5cGVFbCkgPT4gcGFyc2VGZWF0dXJlVHlwZShmZWF0dXJlVHlwZUVsLCB2ZXJzaW9uLCBvdXRwdXRGb3JtYXRzKQogICAgKTsKICB9CiAgZnVuY3Rpb24gcGFyc2VPcGVyYXRpb24xMDAob3BlcmF0aW9uKSB7CiAgICBjb25zdCB1cmxzID0ge307CiAgICBjb25zdCBkY3BUeXBlID0gZmluZENoaWxkcmVuRWxlbWVudChvcGVyYXRpb24sICJEQ1BUeXBlIik7CiAgICBjb25zdCBodHRwID0gZGNwVHlwZS5mbGF0TWFwKChkKSA9PiBmaW5kQ2hpbGRyZW5FbGVtZW50KGQsICJIVFRQIikpOwogICAgY29uc3QgbWV0aG9kcyA9IGh0dHAuZmxhdE1hcCgoaCkgPT4gZ2V0Q2hpbGRyZW5FbGVtZW50KGgpKTsKICAgIG1ldGhvZHMuZm9yRWFjaCgobWV0aG9kKSA9PiB7CiAgICAgIGNvbnN0IG1ldGhvZE5hbWUgPSBzdHJpcE5hbWVzcGFjZShnZXRFbGVtZW50TmFtZShtZXRob2QpKTsKICAgICAgdXJsc1ttZXRob2ROYW1lXSA9IGdldEVsZW1lbnRBdHRyaWJ1dGUobWV0aG9kLCAib25saW5lUmVzb3VyY2UiKTsKICAgIH0pOwogICAgcmV0dXJuIHVybHM7CiAgfQogIGZ1bmN0aW9uIHBhcnNlT3BlcmF0aW9uMTEwKG9wZXJhdGlvbikgewogICAgY29uc3QgdXJscyA9IHt9OwogICAgY29uc3QgZGNwVHlwZSA9IGZpbmRDaGlsZHJlbkVsZW1lbnQob3BlcmF0aW9uLCAiRENQIik7CiAgICBjb25zdCBodHRwID0gZGNwVHlwZS5mbGF0TWFwKChkKSA9PiBmaW5kQ2hpbGRFbGVtZW50KGQsICJIVFRQIikpOwogICAgY29uc3QgbWV0aG9kcyA9IGh0dHAuZmxhdE1hcCgoaCkgPT4gZ2V0Q2hpbGRyZW5FbGVtZW50KGgpKTsKICAgIG1ldGhvZHMuZm9yRWFjaCgobWV0aG9kKSA9PiB7CiAgICAgIGNvbnN0IG1ldGhvZE5hbWUgPSBzdHJpcE5hbWVzcGFjZShnZXRFbGVtZW50TmFtZShtZXRob2QpKTsKICAgICAgdXJsc1ttZXRob2ROYW1lXSA9IGdldEVsZW1lbnRBdHRyaWJ1dGUobWV0aG9kLCAieGxpbms6aHJlZiIpOwogICAgfSk7CiAgICByZXR1cm4gdXJsczsKICB9CiAgZnVuY3Rpb24gcGFyc2VGZWF0dXJlVHlwZShmZWF0dXJlVHlwZUVsLCBzZXJ2aWNlVmVyc2lvbiwgZGVmYXVsdE91dHB1dEZvcm1hdHMpIHsKICAgIGNvbnN0IHNyc1RhZyA9IHNlcnZpY2VWZXJzaW9uLnN0YXJ0c1dpdGgoIjIuIikgPyAiQ1JTIiA6ICJTUlMiOwogICAgY29uc3QgZGVmYXVsdFNyc1RhZyA9IHNlcnZpY2VWZXJzaW9uLnN0YXJ0c1dpdGgoIjEuMCIpID8gIlNSUyIgOiBgRGVmYXVsdCR7c3JzVGFnfWA7CiAgICBmdW5jdGlvbiBwYXJzZUJCb3gxMDAoKSB7CiAgICAgIGNvbnN0IGJib3hFbCA9IGZpbmRDaGlsZEVsZW1lbnQoZmVhdHVyZVR5cGVFbCwgIkxhdExvbmdCb3VuZGluZ0JveCIpOwogICAgICByZXR1cm4gWyJtaW54IiwgIm1pbnkiLCAibWF4eCIsICJtYXh5Il0ubWFwKChuYW1lKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGJib3hFbCwgbmFtZSkpLm1hcChwYXJzZUZsb2F0KTsKICAgIH0KICAgIGZ1bmN0aW9uIHBhcnNlQkJveDIoKSB7CiAgICAgIGNvbnN0IGJib3hFbCA9IGZpbmRDaGlsZEVsZW1lbnQoZmVhdHVyZVR5cGVFbCwgIldHUzg0Qm91bmRpbmdCb3giKTsKICAgICAgcmV0dXJuIFsiTG93ZXJDb3JuZXIiLCAiVXBwZXJDb3JuZXIiXS5tYXAoKGVsTmFtZSkgPT4gZmluZENoaWxkRWxlbWVudChiYm94RWwsIGVsTmFtZSkpLm1hcCgoY29ybmVyRWwpID0+IGdldEVsZW1lbnRUZXh0KGNvcm5lckVsKS5zcGxpdCgiICIpKS5yZWR1Y2UoKHByZXYsIGN1cnIpID0+IFsuLi5wcmV2LCAuLi5jdXJyXSkubWFwKHBhcnNlRmxvYXQpOwogICAgfQogICAgY29uc3Qgb3RoZXJDcnMgPSBzZXJ2aWNlVmVyc2lvbi5zdGFydHNXaXRoKCIxLjAiKSA/IFtdIDogZmluZENoaWxkcmVuRWxlbWVudChmZWF0dXJlVHlwZUVsLCBgT3RoZXIke3Nyc1RhZ31gKS5tYXAoZ2V0RWxlbWVudFRleHQpLm1hcChzaW1wbGlmeUVwc2dVcm4pOwogICAgY29uc3Qgb3V0cHV0Rm9ybWF0cyA9IHNlcnZpY2VWZXJzaW9uLnN0YXJ0c1dpdGgoIjEuMCIpID8gW10gOiBmaW5kQ2hpbGRyZW5FbGVtZW50KAogICAgICBmaW5kQ2hpbGRFbGVtZW50KGZlYXR1cmVUeXBlRWwsICJPdXRwdXRGb3JtYXRzIiksCiAgICAgICJGb3JtYXQiCiAgICApLm1hcChnZXRFbGVtZW50VGV4dCk7CiAgICBjb25zdCBrZXl3b3JkcyA9IHNlcnZpY2VWZXJzaW9uLnN0YXJ0c1dpdGgoIjEuMCIpID8gZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChmZWF0dXJlVHlwZUVsLCAiS2V5d29yZHMiKSkuc3BsaXQoIiwiKS5tYXAoKGtleXdvcmQpID0+IGtleXdvcmQudHJpbSgpKSA6IGZpbmRDaGlsZHJlbkVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQoZmVhdHVyZVR5cGVFbCwgIktleXdvcmRzIiksCiAgICAgICJLZXl3b3JkIgogICAgKS5tYXAoZ2V0RWxlbWVudFRleHQpLmZpbHRlcigodiwgaSwgYXJyKSA9PiBhcnIuaW5kZXhPZih2KSA9PT0gaSk7CiAgICBjb25zdCBtZXRhZGF0YSA9IHNlcnZpY2VWZXJzaW9uID09PSAiMi4wLjAiID8gZmluZENoaWxkcmVuRWxlbWVudChmZWF0dXJlVHlwZUVsLCAiTWV0YWRhdGFVUkwiKS5tYXAoCiAgICAgIChtZXRhZGF0YVVybEVsKSA9PiAoewogICAgICAgIHVybDogZ2V0RWxlbWVudEF0dHJpYnV0ZShtZXRhZGF0YVVybEVsLCAieGxpbms6aHJlZiIpCiAgICAgIH0pCiAgICApIDogZmluZENoaWxkcmVuRWxlbWVudChmZWF0dXJlVHlwZUVsLCAiTWV0YWRhdGFVUkwiKS5tYXAoCiAgICAgIChtZXRhZGF0YVVybEVsKSA9PiAoewogICAgICAgIGZvcm1hdDogZ2V0RWxlbWVudEF0dHJpYnV0ZShtZXRhZGF0YVVybEVsLCAiZm9ybWF0IiksCiAgICAgICAgdHlwZTogZ2V0RWxlbWVudEF0dHJpYnV0ZShtZXRhZGF0YVVybEVsLCAidHlwZSIpLAogICAgICAgIHVybDogZ2V0RWxlbWVudFRleHQobWV0YWRhdGFVcmxFbCkudHJpbSgpCiAgICAgIH0pCiAgICApOwogICAgcmV0dXJuIHsKICAgICAgbmFtZTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChmZWF0dXJlVHlwZUVsLCAiTmFtZSIpKSwKICAgICAgdGl0bGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZmVhdHVyZVR5cGVFbCwgIlRpdGxlIikpLAogICAgICBhYnN0cmFjdDogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChmZWF0dXJlVHlwZUVsLCAiQWJzdHJhY3QiKSksCiAgICAgIGRlZmF1bHRDcnM6IHNpbXBsaWZ5RXBzZ1VybigKICAgICAgICBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGZlYXR1cmVUeXBlRWwsIGRlZmF1bHRTcnNUYWcpKQogICAgICApLAogICAgICBvdGhlckNycywKICAgICAgb3V0cHV0Rm9ybWF0czogb3V0cHV0Rm9ybWF0cy5sZW5ndGggPiAwID8gb3V0cHV0Rm9ybWF0cyA6IGRlZmF1bHRPdXRwdXRGb3JtYXRzLAogICAgICBsYXRMb25Cb3VuZGluZ0JveDogc2VydmljZVZlcnNpb24uc3RhcnRzV2l0aCgiMS4wIikgPyBwYXJzZUJCb3gxMDAoKSA6IHBhcnNlQkJveDIoKSwKICAgICAga2V5d29yZHMsCiAgICAgIC4uLm1ldGFkYXRhLmxlbmd0aCAmJiB7IG1ldGFkYXRhIH0KICAgIH07CiAgfQogIGZ1bmN0aW9uIHBhcnNlQkJveCh4bWxFbGVtZW50KSB7CiAgICBjb25zdCByZXN1bHQgPSBbIkxvd2VyQ29ybmVyIiwgIlVwcGVyQ29ybmVyIl0ubWFwKChlbE5hbWUpID0+IGZpbmRDaGlsZEVsZW1lbnQoeG1sRWxlbWVudCwgZWxOYW1lKSkubWFwKChjb3JuZXJFbCkgPT4gZ2V0RWxlbWVudFRleHQoY29ybmVyRWwpLnNwbGl0KCIgIikpLnJlZHVjZSgocHJldiwgY3VycikgPT4gWy4uLnByZXYsIC4uLmN1cnJdKS5tYXAocGFyc2VGbG9hdCk7CiAgICBpZiAocmVzdWx0LnNvbWUoTnVtYmVyLmlzTmFOKSkKICAgICAgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICBmdW5jdGlvbiByZWFkSW5mb0Zyb21DYXBhYmlsaXRpZXMoY2FwYWJpbGl0aWVzRG9jKSB7CiAgICBjb25zdCByb290RWwgPSBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpOwogICAgY29uc3Qgc2VydmljZSA9IGZpbmRDaGlsZEVsZW1lbnQocm9vdEVsLCAiU2VydmljZUlkZW50aWZpY2F0aW9uIik7CiAgICBjb25zdCBrZXl3b3JkcyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIktleXdvcmRzIiksCiAgICAgICJLZXl3b3JkIgogICAgKS5tYXAoZ2V0RWxlbWVudFRleHQpOwogICAgY29uc3QgbWV0YWRhdGEgPSBmaW5kQ2hpbGRFbGVtZW50KHJvb3RFbCwgIk9wZXJhdGlvbnNNZXRhZGF0YSIpOwogICAgY29uc3QgZ2V0VGlsZU9wZXJhdGlvbiA9IGZpbmRDaGlsZHJlbkVsZW1lbnQobWV0YWRhdGEsICJPcGVyYXRpb24iKS5maW5kKAogICAgICAoZWwpID0+IGdldEVsZW1lbnRBdHRyaWJ1dGUoZWwsICJuYW1lIikgPT0gIkdldFRpbGUiCiAgICApOwogICAgY29uc3QgZ2V0VGlsZVVybHMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGdldFRpbGVPcGVyYXRpb24sICJHZXQiLCB0cnVlKS5yZWR1Y2UoCiAgICAgIChwcmV2LCBjdXJyKSA9PiB7CiAgICAgICAgY29uc3QgZW5jb2RpbmdUeXBlID0gZ2V0RWxlbWVudFRleHQoCiAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGN1cnIsICJWYWx1ZSIsIHRydWUpCiAgICAgICAgKTsKICAgICAgICBjb25zdCB1cmwgPSBnZXRFbGVtZW50QXR0cmlidXRlKGN1cnIsICJ4bGluazpocmVmIik7CiAgICAgICAgaWYgKGVuY29kaW5nVHlwZS50b0xvd2VyQ2FzZSgpID09PSAicmVzdGZ1bCIpCiAgICAgICAgICByZXR1cm4geyAuLi5wcmV2LCByZXN0OiB1cmwgfTsKICAgICAgICByZXR1cm4geyAuLi5wcmV2LCBrdnA6IHVybCB9OwogICAgICB9LAogICAgICB7fQogICAgKTsKICAgIHJldHVybiB7CiAgICAgIHRpdGxlOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJUaXRsZSIpKSwKICAgICAgbmFtZTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzZXJ2aWNlLCAiU2VydmljZVR5cGUiKSksCiAgICAgIGFic3RyYWN0OiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJBYnN0cmFjdCIpKSwKICAgICAgZmVlczogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzZXJ2aWNlLCAiRmVlcyIpKSwKICAgICAgY29uc3RyYWludHM6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIkFjY2Vzc0NvbnN0cmFpbnRzIikpLAogICAgICBrZXl3b3JkcywKICAgICAgcHJvdmlkZXI6IHJlYWRQcm92aWRlckZyb21DYXBhYmlsaXRpZXMoY2FwYWJpbGl0aWVzRG9jKSwKICAgICAgZ2V0VGlsZVVybHMKICAgIH07CiAgfQogIGZ1bmN0aW9uIHJlYWRNYXRyaXhTZXRzRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpIHsKICAgIGZ1bmN0aW9uIHBhcnNlTWF0cml4U2V0KGVsZW1lbnQpIHsKICAgICAgY29uc3QgdG9wTGVmdCA9IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIlRvcExlZnRDb3JuZXIiKSkuc3BsaXQoIiAiKS5tYXAocGFyc2VGbG9hdCk7CiAgICAgIHJldHVybiB7CiAgICAgICAgaWRlbnRpZmllcjogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50LCAiSWRlbnRpZmllciIpKSwKICAgICAgICB0aWxlV2lkdGg6IHBhcnNlSW50KAogICAgICAgICAgZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50LCAiVGlsZVdpZHRoIikpCiAgICAgICAgKSwKICAgICAgICB0aWxlSGVpZ2h0OiBwYXJzZUludCgKICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIlRpbGVIZWlnaHQiKSkKICAgICAgICApLAogICAgICAgIG1hdHJpeFdpZHRoOiBwYXJzZUludCgKICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIk1hdHJpeFdpZHRoIikpCiAgICAgICAgKSwKICAgICAgICBtYXRyaXhIZWlnaHQ6IHBhcnNlSW50KAogICAgICAgICAgZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50LCAiTWF0cml4SGVpZ2h0IikpCiAgICAgICAgKSwKICAgICAgICBzY2FsZURlbm9taW5hdG9yOiBwYXJzZUZsb2F0KAogICAgICAgICAgZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50LCAiU2NhbGVEZW5vbWluYXRvciIpKQogICAgICAgICksCiAgICAgICAgdG9wTGVmdAogICAgICB9OwogICAgfQogICAgY29uc3QgY29udGVudHMgPSBmaW5kQ2hpbGRFbGVtZW50KAogICAgICBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLAogICAgICAiQ29udGVudHMiCiAgICApOwogICAgY29uc3QgbWF0cml4U2V0cyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoY29udGVudHMsICJUaWxlTWF0cml4U2V0Iik7CiAgICByZXR1cm4gbWF0cml4U2V0cy5tYXAoKGVsZW1lbnQpID0+IHsKICAgICAgY29uc3Qgd2VsbEtub3duU2NhbGVTZXQgPSBnZXRFbGVtZW50VGV4dCgKICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQsICJXZWxsS25vd25TY2FsZVNldCIpCiAgICAgICk7CiAgICAgIGNvbnN0IGJvdW5kaW5nQm94ID0gcGFyc2VCQm94KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIkJvdW5kaW5nQm94IikpOwogICAgICByZXR1cm4gewogICAgICAgIGlkZW50aWZpZXI6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIklkZW50aWZpZXIiKSksCiAgICAgICAgY3JzOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQsICJTdXBwb3J0ZWRDUlMiKSksCiAgICAgICAgdGlsZU1hdHJpY2VzOiBmaW5kQ2hpbGRyZW5FbGVtZW50KGVsZW1lbnQsICJUaWxlTWF0cml4IikubWFwKAogICAgICAgICAgcGFyc2VNYXRyaXhTZXQKICAgICAgICApLAogICAgICAgIC4uLmJvdW5kaW5nQm94ICYmIHsgYm91bmRpbmdCb3ggfSwKICAgICAgICAuLi53ZWxsS25vd25TY2FsZVNldCAmJiB7IHdlbGxLbm93blNjYWxlU2V0IH0KICAgICAgfTsKICAgIH0pOwogIH0KICBmdW5jdGlvbiByZWFkTGF5ZXJzRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpIHsKICAgIGNvbnN0IHJvb3RFbCA9IGdldFJvb3RFbGVtZW50KGNhcGFiaWxpdGllc0RvYyk7CiAgICBjb25zdCBjb250ZW50c0VsID0gZmluZENoaWxkRWxlbWVudChyb290RWwsICJDb250ZW50cyIpOwogICAgZnVuY3Rpb24gZ2V0TWF0cml4U2V0Q3JzKGNvbnRlbnRzRWwyLCBpZGVudGlmaWVyKSB7CiAgICAgIGNvbnN0IG1hdHJpeFNldCA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoY29udGVudHNFbDIsICJUaWxlTWF0cml4U2V0IikuZmluZCgKICAgICAgICAobWF0cml4U2V0RWwpID0+IHsKICAgICAgICAgIGNvbnN0IGlkZW50aWZpZXJFbCA9IGZpbmRDaGlsZEVsZW1lbnQobWF0cml4U2V0RWwsICJJZGVudGlmaWVyIik7CiAgICAgICAgICByZXR1cm4gZ2V0RWxlbWVudFRleHQoaWRlbnRpZmllckVsKSA9PT0gaWRlbnRpZmllcjsKICAgICAgICB9CiAgICAgICk7CiAgICAgIHJldHVybiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KG1hdHJpeFNldCwgIlN1cHBvcnRlZENSUyIpKTsKICAgIH0KICAgIGZ1bmN0aW9uIHBhcnNlTWF0cml4U2V0TGluayhlbGVtZW50KSB7CiAgICAgIGNvbnN0IGlkZW50aWZpZXIgPSBnZXRFbGVtZW50VGV4dCgKICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQsICJUaWxlTWF0cml4U2V0IikKICAgICAgKTsKICAgICAgY29uc3QgY3JzID0gZ2V0TWF0cml4U2V0Q3JzKGNvbnRlbnRzRWwsIGlkZW50aWZpZXIpOwogICAgICByZXR1cm4gewogICAgICAgIGlkZW50aWZpZXIsCiAgICAgICAgY3JzLAogICAgICAgIGxpbWl0czogZmluZENoaWxkcmVuRWxlbWVudChlbGVtZW50LCAiVGlsZU1hdHJpeExpbWl0cyIsIHRydWUpLm1hcCgKICAgICAgICAgIChlbGVtZW50MikgPT4gKHsKICAgICAgICAgICAgdGlsZU1hdHJpeDogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50MiwgIlRpbGVNYXRyaXgiKSksCiAgICAgICAgICAgIG1pblRpbGVSb3c6IHBhcnNlSW50KAogICAgICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJNaW5UaWxlUm93IikpCiAgICAgICAgICAgICksCiAgICAgICAgICAgIG1pblRpbGVDb2w6IHBhcnNlSW50KAogICAgICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJNaW5UaWxlQ29sIikpCiAgICAgICAgICAgICksCiAgICAgICAgICAgIG1heFRpbGVSb3c6IHBhcnNlSW50KAogICAgICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJNYXhUaWxlUm93IikpCiAgICAgICAgICAgICksCiAgICAgICAgICAgIG1heFRpbGVDb2w6IHBhcnNlSW50KAogICAgICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJNYXhUaWxlQ29sIikpCiAgICAgICAgICAgICkKICAgICAgICAgIH0pCiAgICAgICAgKQogICAgICB9OwogICAgfQogICAgY29uc3QgZ2V0VGlsZU9wZXJhdGlvbiA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQocm9vdEVsLCAiT3BlcmF0aW9uc01ldGFkYXRhIiksCiAgICAgICJPcGVyYXRpb24iCiAgICApLmZpbmQoKGVsKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGVsLCAibmFtZSIpID09ICJHZXRUaWxlIik7CiAgICBjb25zdCBnZXRLdnBFbHQgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGdldFRpbGVPcGVyYXRpb24sICJHZXQiLCB0cnVlKS5maWx0ZXIoCiAgICAgIChlbHQpID0+IHsKICAgICAgICBjb25zdCBlbmNvZGluZ1R5cGUgPSBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGVsdCwgIlZhbHVlIiwgdHJ1ZSkpOwogICAgICAgIHJldHVybiBlbmNvZGluZ1R5cGUudG9Mb3dlckNhc2UoKSA9PT0gImt2cCI7CiAgICAgIH0KICAgIClbMF07CiAgICBjb25zdCBnZXRLdnBVcmwgPSBnZXRLdnBFbHQgPyBnZXRFbGVtZW50QXR0cmlidXRlKGdldEt2cEVsdCwgInhsaW5rOmhyZWYiKSA6ICIiOwogICAgY29uc3QgY29udGVudHMgPSBmaW5kQ2hpbGRFbGVtZW50KHJvb3RFbCwgIkNvbnRlbnRzIik7CiAgICBjb25zdCBsYXllcnMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGNvbnRlbnRzLCAiTGF5ZXIiKTsKICAgIHJldHVybiBsYXllcnMubWFwKChlbGVtZW50KSA9PiB7CiAgICAgIGNvbnN0IGxhdExvbkJvdW5kaW5nQm94ID0gcGFyc2VCQm94KAogICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIldHUzg0Qm91bmRpbmdCb3giKQogICAgICApOwogICAgICBsZXQgZGVmYXVsdFN0eWxlID0gIiI7CiAgICAgIGNvbnN0IHN0eWxlcyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCwgIlN0eWxlIikubWFwKChlbGVtZW50MikgPT4gewogICAgICAgIGNvbnN0IGxlZ2VuZFVybCA9IGdldEVsZW1lbnRBdHRyaWJ1dGUoCiAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQyLCAiTGVnZW5kVVJMIiksCiAgICAgICAgICAieGxpbms6aHJlZiIKICAgICAgICApOwogICAgICAgIGNvbnN0IGFic3RyYWN0ID0gZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50MiwgIkFic3RyYWN0IikpOwogICAgICAgIGNvbnN0IHN0eWxlID0gewogICAgICAgICAgdGl0bGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJUaXRsZSIpKSwKICAgICAgICAgIG5hbWU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJJZGVudGlmaWVyIikpLAogICAgICAgICAgLi4uYWJzdHJhY3QgJiYgeyBhYnN0cmFjdCB9LAogICAgICAgICAgLi4ubGVnZW5kVXJsICYmIHsgbGVnZW5kVXJsIH0KICAgICAgICB9OwogICAgICAgIGlmIChnZXRFbGVtZW50QXR0cmlidXRlKGVsZW1lbnQyLCAiaXNEZWZhdWx0IikgPT09ICJ0cnVlIikgewogICAgICAgICAgZGVmYXVsdFN0eWxlID0gc3R5bGUubmFtZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0eWxlOwogICAgICB9KTsKICAgICAgY29uc3Qgb3V0cHV0Rm9ybWF0cyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCwgIkZvcm1hdCIpLm1hcCgKICAgICAgICBnZXRFbGVtZW50VGV4dAogICAgICApOwogICAgICBjb25zdCByZXNvdXJjZUxpbmtzID0gZmluZENoaWxkcmVuRWxlbWVudCgKICAgICAgICBlbGVtZW50LAogICAgICAgICJSZXNvdXJjZVVSTCIKICAgICAgKS5maWx0ZXIoCiAgICAgICAgKGVsZW1lbnQyKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGVsZW1lbnQyLCAicmVzb3VyY2VUeXBlIikgPT09ICJ0aWxlIgogICAgICApLm1hcCgoZWxlbWVudDIpID0+IHsKICAgICAgICBjb25zdCBmb3JtYXQgPSBnZXRFbGVtZW50QXR0cmlidXRlKGVsZW1lbnQyLCAiZm9ybWF0Iik7CiAgICAgICAgY29uc3QgdXJsID0gZ2V0RWxlbWVudEF0dHJpYnV0ZShlbGVtZW50MiwgInRlbXBsYXRlIik7CiAgICAgICAgcmV0dXJuIHsgZm9ybWF0LCB1cmwsIGVuY29kaW5nOiAiUkVTVCIgfTsKICAgICAgfSk7CiAgICAgIGlmIChnZXRLdnBVcmwpIHsKICAgICAgICByZXNvdXJjZUxpbmtzLnB1c2goCiAgICAgICAgICAuLi5vdXRwdXRGb3JtYXRzLm1hcCgoZm9ybWF0KSA9PiAoewogICAgICAgICAgICBlbmNvZGluZzogIktWUCIsCiAgICAgICAgICAgIHVybDogZ2V0S3ZwVXJsLAogICAgICAgICAgICBmb3JtYXQKICAgICAgICAgIH0pKQogICAgICAgICk7CiAgICAgIH0KICAgICAgY29uc3QgbWF0cml4U2V0cyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCwgIlRpbGVNYXRyaXhTZXRMaW5rIikubWFwKAogICAgICAgIHBhcnNlTWF0cml4U2V0TGluawogICAgICApOwogICAgICBjb25zdCBkaW1lbnNpb25zID0gZmluZENoaWxkcmVuRWxlbWVudChlbGVtZW50LCAiRGltZW5zaW9uIikubWFwKAogICAgICAgIChlbGVtZW50MikgPT4gewogICAgICAgICAgY29uc3QgaWRlbnRpZmllciA9IGdldEVsZW1lbnRUZXh0KAogICAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQyLCAiSWRlbnRpZmllciIpCiAgICAgICAgICApOwogICAgICAgICAgY29uc3QgZGVmYXVsdFZhbHVlID0gZ2V0RWxlbWVudFRleHQoCiAgICAgICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJEZWZhdWx0IikKICAgICAgICAgICk7CiAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGVsZW1lbnQyLCAiVmFsdWVzIikubWFwKAogICAgICAgICAgICBnZXRFbGVtZW50VGV4dAogICAgICAgICAgKTsKICAgICAgICAgIHJldHVybiB7IGlkZW50aWZpZXIsIGRlZmF1bHRWYWx1ZSwgdmFsdWVzIH07CiAgICAgICAgfQogICAgICApOwogICAgICByZXR1cm4gewogICAgICAgIG5hbWU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIklkZW50aWZpZXIiKSksCiAgICAgICAgdGl0bGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIlRpdGxlIikpLAogICAgICAgIGFic3RyYWN0OiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQsICJBYnN0cmFjdCIpKSwKICAgICAgICBzdHlsZXMsCiAgICAgICAgcmVzb3VyY2VMaW5rcywKICAgICAgICBtYXRyaXhTZXRzLAogICAgICAgIGRlZmF1bHRTdHlsZSwKICAgICAgICAuLi5sYXRMb25Cb3VuZGluZ0JveCAmJiB7IGxhdExvbkJvdW5kaW5nQm94IH0sCiAgICAgICAgLi4uZGltZW5zaW9ucyAmJiB7IGRpbWVuc2lvbnMgfQogICAgICB9OwogICAgfSk7CiAgfQogIGZ1bmN0aW9uIHBhcnNlRmVhdHVyZVByb3BzKGdldEZlYXR1cmVzRG9jLCBmZWF0dXJlVHlwZUZ1bGwsIHNlcnZpY2VWZXJzaW9uKSB7CiAgICBjb25zdCBjb2xsZWN0aW9uID0gZ2V0Um9vdEVsZW1lbnQoZ2V0RmVhdHVyZXNEb2MpOwogICAgbGV0IG1lbWJlcnM7CiAgICBpZiAoc2VydmljZVZlcnNpb24uc3RhcnRzV2l0aCgiMi4wIikpIHsKICAgICAgbWVtYmVycyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoY29sbGVjdGlvbiwgIm1lbWJlciIpLm1hcCgKICAgICAgICAocGFyZW50KSA9PiBnZXRDaGlsZHJlbkVsZW1lbnQocGFyZW50KVswXQogICAgICApOwogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbWVtYmVyc1Jvb3QgPSBmaW5kQ2hpbGRFbGVtZW50KGNvbGxlY3Rpb24sICJmZWF0dXJlTWVtYmVycyIpOwogICAgICBtZW1iZXJzID0gbWVtYmVyc1Jvb3QgPyBnZXRDaGlsZHJlbkVsZW1lbnQobWVtYmVyc1Jvb3QpIDogZmluZENoaWxkcmVuRWxlbWVudChjb2xsZWN0aW9uLCAiZmVhdHVyZU1lbWJlciIpLm1hcCgKICAgICAgICAocGFyZW50KSA9PiBnZXRDaGlsZHJlbkVsZW1lbnQocGFyZW50KVswXQogICAgICApOwogICAgfQogICAgY29uc3QgaWRBdHRyID0gc2VydmljZVZlcnNpb24gPT09ICIxLjAuMCIgPyAiZmlkIiA6ICJnbWw6aWQiOwogICAgZnVuY3Rpb24gaXNFbGVtZW50UHJvcGVydHkocHJvcE5hbWUpIHsKICAgICAgcmV0dXJuIHByb3BOYW1lIGluIGZlYXR1cmVUeXBlRnVsbC5wcm9wZXJ0aWVzOwogICAgfQogICAgZnVuY3Rpb24gcGFyc2VFbGVtZW50UHJvcGVydHlWYWx1ZShwcm9wTmFtZSwgdmFsdWVBc1N0cmluZykgewogICAgICBjb25zdCB0eXBlID0gZmVhdHVyZVR5cGVGdWxsLnByb3BlcnRpZXNbcHJvcE5hbWVdOwogICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlICJpbnRlZ2VyIjoKICAgICAgICAgIHJldHVybiBwYXJzZUludCh2YWx1ZUFzU3RyaW5nKTsKICAgICAgICBjYXNlICJmbG9hdCI6CiAgICAgICAgICByZXR1cm4gcGFyc2VGbG9hdCh2YWx1ZUFzU3RyaW5nKTsKICAgICAgICBjYXNlICJib29sZWFuIjoKICAgICAgICAgIHJldHVybiB2YWx1ZUFzU3RyaW5nID09PSAidHJ1ZSI7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHJldHVybiB2YWx1ZUFzU3RyaW5nOwogICAgICB9CiAgICB9CiAgICBmdW5jdGlvbiBnZXRQcm9wZXJ0aWVzKG1lbWJlckVsKSB7CiAgICAgIHJldHVybiBnZXRDaGlsZHJlbkVsZW1lbnQobWVtYmVyRWwpLmZpbHRlcigoZWwpID0+IGlzRWxlbWVudFByb3BlcnR5KHN0cmlwTmFtZXNwYWNlKGdldEVsZW1lbnROYW1lKGVsKSkpKS5yZWR1Y2UoKHByZXYsIGN1cnIpID0+IHsKICAgICAgICBjb25zdCBwcm9wTmFtZSA9IHN0cmlwTmFtZXNwYWNlKGdldEVsZW1lbnROYW1lKGN1cnIpKTsKICAgICAgICByZXR1cm4gewogICAgICAgICAgLi4ucHJldiwKICAgICAgICAgIFtwcm9wTmFtZV06IHBhcnNlRWxlbWVudFByb3BlcnR5VmFsdWUocHJvcE5hbWUsIGdldEVsZW1lbnRUZXh0KGN1cnIpKQogICAgICAgIH07CiAgICAgIH0sIHt9KTsKICAgIH0KICAgIHJldHVybiBtZW1iZXJzLm1hcCgoZWwpID0+ICh7CiAgICAgIGlkOiBnZXRFbGVtZW50QXR0cmlidXRlKGVsLCBpZEF0dHIpLAogICAgICBwcm9wZXJ0aWVzOiBnZXRQcm9wZXJ0aWVzKGVsKQogICAgfSkpOwogIH0KICBmdW5jdGlvbiBjb21wdXRlRmVhdHVyZVByb3BzRGV0YWlscyhmZWF0dXJlc1dpdGhQcm9wcykgewogICAgcmV0dXJuIGZlYXR1cmVzV2l0aFByb3BzLnJlZHVjZSgocHJldiwgY3VycikgPT4gewogICAgICBmb3IgKGNvbnN0IHByb3BOYW1lIGluIGN1cnIucHJvcGVydGllcykgewogICAgICAgIGNvbnN0IHByb3BWYWx1ZSA9IGN1cnIucHJvcGVydGllc1twcm9wTmFtZV07CiAgICAgICAgaWYgKCEocHJvcE5hbWUgaW4gcHJldikpIHsKICAgICAgICAgIHByZXZbcHJvcE5hbWVdID0geyB1bmlxdWVWYWx1ZXM6IFtdIH07CiAgICAgICAgfQogICAgICAgIGNvbnN0IHVuaXF1ZVZhbHVlID0gcHJldltwcm9wTmFtZV0udW5pcXVlVmFsdWVzLmZpbmQoCiAgICAgICAgICAodikgPT4gdi52YWx1ZSA9PT0gcHJvcFZhbHVlCiAgICAgICAgKTsKICAgICAgICBpZiAodW5pcXVlVmFsdWUpCiAgICAgICAgICB1bmlxdWVWYWx1ZS5jb3VudCsrOwogICAgICAgIGVsc2UKICAgICAgICAgIHByZXZbcHJvcE5hbWVdLnVuaXF1ZVZhbHVlcy5wdXNoKHsgdmFsdWU6IHByb3BWYWx1ZSwgY291bnQ6IDEgfSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHByZXY7CiAgICB9LCB7fSk7CiAgfQogIGZ1bmN0aW9uIGdlbmVyYXRlR2V0RmVhdHVyZVVybChzZXJ2aWNlVXJsLCB2ZXJzaW9uLCBmZWF0dXJlVHlwZSwgb3V0cHV0Rm9ybWF0LCBtYXhGZWF0dXJlcywgYXR0cmlidXRlcywgaGl0c09ubHksIG91dHB1dENycywgZXh0ZW50LCBleHRlbnRDcnMsIHN0YXJ0SW5kZXgsIHNvcnRCeSkgewogICAgY29uc3QgdHlwZVBhcmFtID0gdmVyc2lvbiA9PT0gIjIuMC4wIiA/ICJUWVBFTkFNRVMiIDogIlRZUEVOQU1FIjsKICAgIGNvbnN0IGNvdW50UGFyYW0gPSB2ZXJzaW9uID09PSAiMi4wLjAiID8gIkNPVU5UIiA6ICJNQVhGRUFUVVJFUyI7CiAgICBjb25zdCBuZXdQYXJhbXMgPSB7CiAgICAgIFNFUlZJQ0U6ICJXRlMiLAogICAgICBSRVFVRVNUOiAiR2V0RmVhdHVyZSIsCiAgICAgIFZFUlNJT046IHZlcnNpb24sCiAgICAgIFt0eXBlUGFyYW1dOiBmZWF0dXJlVHlwZQogICAgfTsKICAgIGlmIChvdXRwdXRGb3JtYXQgIT09IHZvaWQgMCkKICAgICAgbmV3UGFyYW1zLk9VVFBVVEZPUk1BVCA9IG91dHB1dEZvcm1hdDsKICAgIGlmIChhdHRyaWJ1dGVzICE9PSB2b2lkIDApCiAgICAgIG5ld1BhcmFtcy5QUk9QRVJUWU5BTUUgPSBhdHRyaWJ1dGVzLmpvaW4oIiwiKTsKICAgIGlmIChoaXRzT25seSkgewogICAgICBuZXdQYXJhbXMuUkVTVUxUVFlQRSA9ICJoaXRzIjsKICAgICAgbmV3UGFyYW1zW2NvdW50UGFyYW1dID0gIjEiOwogICAgfSBlbHNlIGlmIChtYXhGZWF0dXJlcyAhPT0gdm9pZCAwKQogICAgICBuZXdQYXJhbXNbY291bnRQYXJhbV0gPSBtYXhGZWF0dXJlcy50b1N0cmluZygxMCk7CiAgICBpZiAob3V0cHV0Q3JzKSB7CiAgICAgIG5ld1BhcmFtcy5TUlNOQU1FID0gb3V0cHV0Q3JzOwogICAgfQogICAgaWYgKGV4dGVudCkgewogICAgICBjb25zdCBleHRlbnRKb2luZWQgPSBleHRlbnQuam9pbigiLCIpOwogICAgICBuZXdQYXJhbXMuQkJPWCA9IGV4dGVudENycyA/IGAke2V4dGVudEpvaW5lZH0sJHtleHRlbnRDcnN9YCA6IGV4dGVudEpvaW5lZDsKICAgIH0KICAgIGlmIChzdGFydEluZGV4KSB7CiAgICAgIG5ld1BhcmFtcy5TVEFSVElOREVYID0gc3RhcnRJbmRleC50b1N0cmluZygxMCk7CiAgICB9CiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHNldFF1ZXJ5UGFyYW1zKHNlcnZpY2VVcmwsIG5ld1BhcmFtcykpOwogICAgaWYgKEFycmF5LmlzQXJyYXkoc29ydEJ5KSAmJiBzb3J0QnkubGVuZ3RoID4gMCkgewogICAgICBjb25zdCBzb3J0cyA9IHNvcnRCeS5tYXAoKGZpZWxkU29ydCkgPT4gYCR7ZmllbGRTb3J0WzFdfSAke2ZpZWxkU29ydFswXX1gKS5qb2luKCIsIik7CiAgICAgIHVybC5zZWFyY2hQYXJhbXMuc2V0KCJTT1JUQlkiLCBzb3J0cyk7CiAgICB9CiAgICByZXR1cm4gdXJsLnRvU3RyaW5nKCk7CiAgfQogIGFkZFRhc2tIYW5kbGVyKAogICAgInBhcnNlV21zQ2FwYWJpbGl0aWVzIiwKICAgIGdsb2JhbFRoaXMsCiAgICAoeyB1cmwgfSkgPT4gcXVlcnlYbWxEb2N1bWVudCh1cmwpLnRoZW4oKHhtbERvYykgPT4gY2hlY2soeG1sRG9jLCB1cmwpKS50aGVuKCh4bWxEb2MpID0+ICh7CiAgICAgIGluZm86IHJlYWRJbmZvRnJvbUNhcGFiaWxpdGllcyQyKHhtbERvYyksCiAgICAgIGxheWVyczogcmVhZExheWVyc0Zyb21DYXBhYmlsaXRpZXMkMSh4bWxEb2MpLAogICAgICB1cmw6IHJlYWRPcGVyYXRpb25VcmxzRnJvbUNhcGFiaWxpdGllcyQxKHhtbERvYyksCiAgICAgIHZlcnNpb246IHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyQxKHhtbERvYykKICAgIH0pKQogICk7CiAgYWRkVGFza0hhbmRsZXIoCiAgICAicGFyc2VXZnNDYXBhYmlsaXRpZXMiLAogICAgZ2xvYmFsVGhpcywKICAgICh7IHVybCB9KSA9PiBxdWVyeVhtbERvY3VtZW50KHVybCkudGhlbigoeG1sRG9jKSA9PiBjaGVjayh4bWxEb2MsIHVybCkpLnRoZW4oKHhtbERvYykgPT4gKHsKICAgICAgaW5mbzogcmVhZEluZm9Gcm9tQ2FwYWJpbGl0aWVzJDEoeG1sRG9jKSwKICAgICAgZmVhdHVyZVR5cGVzOiByZWFkRmVhdHVyZVR5cGVzRnJvbUNhcGFiaWxpdGllcyh4bWxEb2MpLAogICAgICB1cmw6IHJlYWRPcGVyYXRpb25VcmxzRnJvbUNhcGFiaWxpdGllcyh4bWxEb2MpLAogICAgICB2ZXJzaW9uOiByZWFkVmVyc2lvbkZyb21DYXBhYmlsaXRpZXMoeG1sRG9jKQogICAgfSkpCiAgKTsKICBhZGRUYXNrSGFuZGxlcigKICAgICJxdWVyeVdmc0ZlYXR1cmVUeXBlRGV0YWlscyIsCiAgICBnbG9iYWxUaGlzLAogICAgKHsKICAgICAgdXJsLAogICAgICBzZXJ2aWNlVmVyc2lvbiwKICAgICAgZmVhdHVyZVR5cGVGdWxsCiAgICB9KSA9PiB7CiAgICAgIGNvbnN0IGdldEZlYXR1cmVVcmwgPSBnZW5lcmF0ZUdldEZlYXR1cmVVcmwoCiAgICAgICAgdXJsLAogICAgICAgIHNlcnZpY2VWZXJzaW9uLAogICAgICAgIGZlYXR1cmVUeXBlRnVsbC5uYW1lLAogICAgICAgIHZvaWQgMCwKICAgICAgICB2b2lkIDAsCiAgICAgICAgT2JqZWN0LmtleXMoZmVhdHVyZVR5cGVGdWxsLnByb3BlcnRpZXMpCiAgICAgICk7CiAgICAgIHJldHVybiBxdWVyeVhtbERvY3VtZW50KGdldEZlYXR1cmVVcmwpLnRoZW4oKGdldEZlYXR1cmVEb2MpID0+ICh7CiAgICAgICAgcHJvcHM6IGNvbXB1dGVGZWF0dXJlUHJvcHNEZXRhaWxzKAogICAgICAgICAgcGFyc2VGZWF0dXJlUHJvcHMoZ2V0RmVhdHVyZURvYywgZmVhdHVyZVR5cGVGdWxsLCBzZXJ2aWNlVmVyc2lvbikKICAgICAgICApCiAgICAgIH0pKTsKICAgIH0KICApOwogIGFkZFRhc2tIYW5kbGVyKAogICAgInVwZGF0ZUZldGNoT3B0aW9ucyIsCiAgICBnbG9iYWxUaGlzLAogICAgKHsgb3B0aW9ucyB9KSA9PiB7CiAgICAgIHNldEZldGNoT3B0aW9ucyhvcHRpb25zKTsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7CiAgICB9CiAgKTsKICBhZGRUYXNrSGFuZGxlcigKICAgICJwYXJzZVdtdHNDYXBhYmlsaXRpZXMiLAogICAgZ2xvYmFsVGhpcywKICAgICh7IHVybCB9KSA9PiBxdWVyeVhtbERvY3VtZW50KHVybCkudGhlbigoeG1sRG9jKSA9PiBjaGVjayh4bWxEb2MsIHVybCkpLnRoZW4oKHhtbERvYykgPT4gKHsKICAgICAgaW5mbzogcmVhZEluZm9Gcm9tQ2FwYWJpbGl0aWVzKHhtbERvYyksCiAgICAgIGxheWVyczogcmVhZExheWVyc0Zyb21DYXBhYmlsaXRpZXMoeG1sRG9jKSwKICAgICAgbWF0cml4U2V0czogcmVhZE1hdHJpeFNldHNGcm9tQ2FwYWJpbGl0aWVzKHhtbERvYykKICAgIH0pKQogICk7Cn0pKCk7Ci8vIyBzb3VyY2VNYXBwaW5nVVJMPXdvcmtlci1MRGtNT3gwZC5qcy5tYXAK")], { type: "text/javascript;charset=utf-8" });
|
|
552
|
+
function me(e) {
|
|
553
|
+
let t;
|
|
554
|
+
try {
|
|
555
|
+
if (t = pe && (window.URL || window.webkitURL).createObjectURL(pe), !t) throw "";
|
|
556
|
+
let n = new Worker(t, { name: e?.name });
|
|
557
|
+
return n.addEventListener("error", () => {
|
|
558
|
+
(window.URL || window.webkitURL).revokeObjectURL(t);
|
|
559
|
+
}), n;
|
|
560
|
+
} catch {
|
|
561
|
+
return new Worker("data:text/javascript;base64,KGZ1bmN0aW9uKCkgewogICJ1c2Ugc3RyaWN0IjsKICAvKiEgQHJncm92ZS9wYXJzZS14bWwgdjQuMS4wIHwgSVNDIExpY2Vuc2UgfCBDb3B5cmlnaHQgUnlhbiBHcm92ZSAqLwogIHZhciBfX2RlZlByb3AgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7CiAgdmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOwogIHZhciBfX2dldE93blByb3BOYW1lcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzOwogIHZhciBfX2hhc093blByb3AgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5OwogIHZhciBfX2V4cG9ydCA9ICh0YXJnZXQsIGFsbCkgPT4gewogICAgZm9yICh2YXIgbmFtZSBpbiBhbGwpCiAgICAgIF9fZGVmUHJvcCh0YXJnZXQsIG5hbWUsIHsgZ2V0OiBhbGxbbmFtZV0sIGVudW1lcmFibGU6IHRydWUgfSk7CiAgfTsKICB2YXIgX19jb3B5UHJvcHMgPSAodG8sIGZyb20sIGV4Y2VwdCwgZGVzYykgPT4gewogICAgaWYgKGZyb20gJiYgdHlwZW9mIGZyb20gPT09ICJvYmplY3QiIHx8IHR5cGVvZiBmcm9tID09PSAiZnVuY3Rpb24iKSB7CiAgICAgIGZvciAobGV0IGtleSBvZiBfX2dldE93blByb3BOYW1lcyhmcm9tKSkKICAgICAgICBpZiAoIV9faGFzT3duUHJvcC5jYWxsKHRvLCBrZXkpICYmIGtleSAhPT0gZXhjZXB0KQogICAgICAgICAgX19kZWZQcm9wKHRvLCBrZXksIHsgZ2V0OiAoKSA9PiBmcm9tW2tleV0sIGVudW1lcmFibGU6ICEoZGVzYyA9IF9fZ2V0T3duUHJvcERlc2MoZnJvbSwga2V5KSkgfHwgZGVzYy5lbnVtZXJhYmxlIH0pOwogICAgfQogICAgcmV0dXJuIHRvOwogIH07CiAgdmFyIF9fdG9Db21tb25KUyA9IChtb2QpID0+IF9fY29weVByb3BzKF9fZGVmUHJvcCh7fSwgIl9fZXNNb2R1bGUiLCB7IHZhbHVlOiB0cnVlIH0pLCBtb2QpOwogIHZhciBzcmNfZXhwb3J0cyA9IHt9OwogIF9fZXhwb3J0KHNyY19leHBvcnRzLCB7CiAgICBYbWxDZGF0YTogKCkgPT4gWG1sQ2RhdGEsCiAgICBYbWxDb21tZW50OiAoKSA9PiBYbWxDb21tZW50LAogICAgWG1sRGVjbGFyYXRpb246ICgpID0+IFhtbERlY2xhcmF0aW9uLAogICAgWG1sRG9jdW1lbnQ6ICgpID0+IFhtbERvY3VtZW50LAogICAgWG1sRG9jdW1lbnRUeXBlOiAoKSA9PiBYbWxEb2N1bWVudFR5cGUsCiAgICBYbWxFbGVtZW50OiAoKSA9PiBYbWxFbGVtZW50LAogICAgWG1sRXJyb3I6ICgpID0+IFhtbEVycm9yLAogICAgWG1sTm9kZTogKCkgPT4gWG1sTm9kZSwKICAgIFhtbFByb2Nlc3NpbmdJbnN0cnVjdGlvbjogKCkgPT4gWG1sUHJvY2Vzc2luZ0luc3RydWN0aW9uLAogICAgWG1sVGV4dDogKCkgPT4gWG1sVGV4dCwKICAgIHBhcnNlWG1sOiAoKSA9PiBwYXJzZVhtbAogIH0pOwogIHZhciBicm93c2VyID0gX190b0NvbW1vbkpTKHNyY19leHBvcnRzKTsKICB2YXIgZW1wdHlTdHJpbmcgPSAiIjsKICB2YXIgc3Vycm9nYXRlUGFpciA9IC9bXHVEODAwLVx1REJGRl1bXHVEQzAwLVx1REZGRl0vZzsKICB2YXIgU3RyaW5nU2Nhbm5lciA9IGNsYXNzIHsKICAgIGNvbnN0cnVjdG9yKHN0cmluZykgewogICAgICB0aGlzLmsgPSB0aGlzLnEoc3RyaW5nLCB0cnVlKTsKICAgICAgdGhpcy5kID0gMDsKICAgICAgdGhpcy5sZW5ndGggPSBzdHJpbmcubGVuZ3RoOwogICAgICB0aGlzLm4gPSB0aGlzLmsgIT09IHRoaXMubGVuZ3RoOwogICAgICB0aGlzLm0gPSBzdHJpbmc7CiAgICAgIGlmICh0aGlzLm4pIHsKICAgICAgICBsZXQgY2hhcnNUb0J5dGVzID0gW107CiAgICAgICAgZm9yIChsZXQgYnl0ZUluZGV4ID0gMCwgY2hhckluZGV4ID0gMDsgY2hhckluZGV4IDwgdGhpcy5rOyArK2NoYXJJbmRleCkgewogICAgICAgICAgY2hhcnNUb0J5dGVzW2NoYXJJbmRleF0gPSBieXRlSW5kZXg7CiAgICAgICAgICBieXRlSW5kZXggKz0gc3RyaW5nLmNvZGVQb2ludEF0KGJ5dGVJbmRleCkgPiA2NTUzNSA/IDIgOiAxOwogICAgICAgIH0KICAgICAgICB0aGlzLnkgPSBjaGFyc1RvQnl0ZXM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogV2hldGhlciB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaW5kZXggaXMgYXQgdGhlIGVuZCBvZiB0aGUgaW5wdXQgc3RyaW5nLgogICAgICovCiAgICBnZXQgeigpIHsKICAgICAgcmV0dXJuIHRoaXMuZCA+PSB0aGlzLms7CiAgICB9CiAgICAvLyAtLSBQcm90ZWN0ZWQgTWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIGdpdmVuIHN0cmluZywgd2hpY2ggbWF5IGRpZmZlciBmcm9tCiAgICAgKiB0aGUgYnl0ZSBsZW5ndGggaWYgdGhlIHN0cmluZyBjb250YWlucyBtdWx0aWJ5dGUgY2hhcmFjdGVycy4KICAgICAqLwogICAgcShzdHJpbmcsIG11bHRpQnl0ZVNhZmUgPSB0aGlzLm4pIHsKICAgICAgcmV0dXJuIG11bHRpQnl0ZVNhZmUgPyBzdHJpbmcucmVwbGFjZShzdXJyb2dhdGVQYWlyLCAiXyIpLmxlbmd0aCA6IHN0cmluZy5sZW5ndGg7CiAgICB9CiAgICAvLyAtLSBQdWJsaWMgTWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8qKgogICAgICogQWR2YW5jZXMgdGhlIHNjYW5uZXIgYnkgdGhlIGdpdmVuIG51bWJlciBvZiBjaGFyYWN0ZXJzLCBzdG9wcGluZyBpZiB0aGUgZW5kCiAgICAgKiBvZiB0aGUgc3RyaW5nIGlzIHJlYWNoZWQuCiAgICAgKi8KICAgIGcoY291bnQgPSAxKSB7CiAgICAgIHRoaXMuZCA9IE1hdGgubWluKHRoaXMuaywgdGhpcy5kICsgY291bnQpOwogICAgfQogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBieXRlIGluZGV4IG9mIHRoZSBnaXZlbiBjaGFyYWN0ZXIgaW5kZXggaW4gdGhlIHN0cmluZy4gVGhlIHR3bwogICAgICogbWF5IGRpZmZlciBpbiBzdHJpbmdzIHRoYXQgY29udGFpbiBtdWx0aWJ5dGUgY2hhcmFjdGVycy4KICAgICAqLwogICAgaShjaGFySW5kZXggPSB0aGlzLmQpIHsKICAgICAgdmFyIF9hOwogICAgICByZXR1cm4gdGhpcy5uID8gKF9hID0gdGhpcy55W2NoYXJJbmRleF0pICE9IG51bGwgPyBfYSA6IEluZmluaXR5IDogY2hhckluZGV4OwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhbmQgcmV0dXJucyB0aGUgZ2l2ZW4gbnVtYmVyIG9mIGNoYXJhY3RlcnMgaWYgcG9zc2libGUsIGFkdmFuY2luZwogICAgICogdGhlIHNjYW5uZXIgYW5kIHN0b3BwaW5nIGlmIHRoZSBlbmQgb2YgdGhlIHN0cmluZyBpcyByZWFjaGVkLgogICAgICoKICAgICAqIElmIG5vIGNoYXJhY3RlcnMgY291bGQgYmUgY29uc3VtZWQsIGFuIGVtcHR5IHN0cmluZyB3aWxsIGJlIHJldHVybmVkLgogICAgICovCiAgICBGKGNvdW50ID0gMSkgewogICAgICBsZXQgY2hhcnMgPSB0aGlzLmgoY291bnQpOwogICAgICB0aGlzLmcoY291bnQpOwogICAgICByZXR1cm4gY2hhcnM7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgbWF0Y2ggZm9yIHRoZSBnaXZlbiBzdGlja3kgcmVnZXgsIGFkdmFuY2VzIHRoZSBzY2FubmVyLCB1cGRhdGVzCiAgICAgKiB0aGUgYGxhc3RJbmRleGAgcHJvcGVydHkgb2YgdGhlIHJlZ2V4LCBhbmQgcmV0dXJucyB0aGUgbWF0Y2hpbmcgc3RyaW5nLgogICAgICoKICAgICAqIFRoZSByZWdleCBtdXN0IGhhdmUgYSBzdGlja3kgZmxhZyAoInkiKSBzbyB0aGF0IGl0cyBgbGFzdEluZGV4YCBwcm9wIGNhbiBiZQogICAgICogdXNlZCB0byBhbmNob3IgdGhlIG1hdGNoIGF0IHRoZSBjdXJyZW50IHNjYW5uZXIgcG9zaXRpb24uCiAgICAgKgogICAgICogUmV0dXJucyB0aGUgY29uc3VtZWQgc3RyaW5nLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgY29uc3VtZWQuCiAgICAgKi8KICAgIEcocmVnZXgpIHsKICAgICAgaWYgKCFyZWdleC5zdGlja3kpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ByZWdleGAgbXVzdCBoYXZlIGEgc3RpY2t5IGZsYWcgKCJ5IiknKTsKICAgICAgfQogICAgICByZWdleC5sYXN0SW5kZXggPSB0aGlzLmkoKTsKICAgICAgbGV0IHJlc3VsdCA9IHJlZ2V4LmV4ZWModGhpcy5tKTsKICAgICAgaWYgKHJlc3VsdCA9PT0gbnVsbCB8fCByZXN1bHQubGVuZ3RoID09PSAwKSB7CiAgICAgICAgcmV0dXJuIGVtcHR5U3RyaW5nOwogICAgICB9CiAgICAgIGxldCBtYXRjaCA9IHJlc3VsdFswXTsKICAgICAgdGhpcy5nKHRoaXMucShtYXRjaCkpOwogICAgICByZXR1cm4gbWF0Y2g7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGFuZCByZXR1cm5zIGFsbCBjaGFyYWN0ZXJzIGZvciB3aGljaCB0aGUgZ2l2ZW4gZnVuY3Rpb24gcmV0dXJucyBhCiAgICAgKiB0cnV0aHkgdmFsdWUsIHN0b3BwaW5nIG9uIHRoZSBmaXJzdCBmYWxzeSByZXR1cm4gdmFsdWUgb3IgaWYgdGhlIGVuZCBvZiB0aGUKICAgICAqIGlucHV0IGlzIHJlYWNoZWQuCiAgICAgKi8KICAgIHYoZm4pIHsKICAgICAgbGV0IGNoYXI7CiAgICAgIGxldCBtYXRjaCA9IGVtcHR5U3RyaW5nOwogICAgICB3aGlsZSAoKGNoYXIgPSB0aGlzLmgoKSkgJiYgZm4oY2hhcikpIHsKICAgICAgICBtYXRjaCArPSBjaGFyOwogICAgICAgIHRoaXMuZygpOwogICAgICB9CiAgICAgIHJldHVybiBtYXRjaDsKICAgIH0KICAgIC8qKgogICAgICogQ29uc3VtZXMgdGhlIGdpdmVuIHN0cmluZyBpZiBpdCBleGlzdHMgYXQgdGhlIGN1cnJlbnQgY2hhcmFjdGVyIGluZGV4LCBhbmQKICAgICAqIGFkdmFuY2VzIHRoZSBzY2FubmVyLgogICAgICoKICAgICAqIElmIHRoZSBnaXZlbiBzdHJpbmcgZG9lc24ndCBleGlzdCBhdCB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaW5kZXgsIGFuIGVtcHR5CiAgICAgKiBzdHJpbmcgd2lsbCBiZSByZXR1cm5lZCBhbmQgdGhlIHNjYW5uZXIgd2lsbCBub3QgYmUgYWR2YW5jZWQuCiAgICAgKi8KICAgIFEoc3RyaW5nVG9Db25zdW1lKSB7CiAgICAgIGlmICh0aGlzLmIoc3RyaW5nVG9Db25zdW1lKSkgewogICAgICAgIHJldHVybiBzdHJpbmdUb0NvbnN1bWU7CiAgICAgIH0KICAgICAgaWYgKHRoaXMubikgewogICAgICAgIGxldCB7IGxlbmd0aCB9ID0gc3RyaW5nVG9Db25zdW1lOwogICAgICAgIGxldCBjaGFyTGVuZ3RoVG9NYXRjaCA9IHRoaXMucShzdHJpbmdUb0NvbnN1bWUpOwogICAgICAgIGlmIChjaGFyTGVuZ3RoVG9NYXRjaCAhPT0gbGVuZ3RoICYmIHN0cmluZ1RvQ29uc3VtZSA9PT0gdGhpcy5oKGNoYXJMZW5ndGhUb01hdGNoKSkgewogICAgICAgICAgdGhpcy5nKGNoYXJMZW5ndGhUb01hdGNoKTsKICAgICAgICAgIHJldHVybiBzdHJpbmdUb0NvbnN1bWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBlbXB0eVN0cmluZzsKICAgIH0KICAgIC8qKgogICAgICogRG9lcyB0aGUgc2FtZSB0aGluZyBhcyBgY29uc3VtZVN0cmluZygpYCwgYnV0IGRvZXNuJ3Qgc3VwcG9ydCBjb25zdW1pbmcKICAgICAqIG11bHRpYnl0ZSBjaGFyYWN0ZXJzLiBUaGlzIGNhbiBiZSBmYXN0ZXIgaWYgeW91IG9ubHkgbmVlZCB0byBtYXRjaCBzaW5nbGUKICAgICAqIGJ5dGUgY2hhcmFjdGVycy4KICAgICAqLwogICAgYihzdHJpbmdUb0NvbnN1bWUpIHsKICAgICAgbGV0IHsgbGVuZ3RoIH0gPSBzdHJpbmdUb0NvbnN1bWU7CiAgICAgIGlmICh0aGlzLmgobGVuZ3RoKSA9PT0gc3RyaW5nVG9Db25zdW1lKSB7CiAgICAgICAgdGhpcy5nKGxlbmd0aCk7CiAgICAgICAgcmV0dXJuIHN0cmluZ1RvQ29uc3VtZTsKICAgICAgfQogICAgICByZXR1cm4gZW1wdHlTdHJpbmc7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGNoYXJhY3RlcnMgdW50aWwgdGhlIGdpdmVuIGdsb2JhbCByZWdleCBpcyBtYXRjaGVkLCBhZHZhbmNpbmcgdGhlCiAgICAgKiBzY2FubmVyIHVwIHRvIChidXQgbm90IGJleW9uZCkgdGhlIGJlZ2lubmluZyBvZiB0aGUgbWF0Y2guIElmIHRoZSByZWdleAogICAgICogZG9lc24ndCBtYXRjaCwgbm90aGluZyB3aWxsIGJlIGNvbnN1bWVkLgogICAgICoKICAgICAqIFJldHVybnMgdGhlIGNvbnN1bWVkIHN0cmluZywgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG5vdGhpbmcgd2FzIGNvbnN1bWVkLgogICAgICovCiAgICBBKHJlZ2V4KSB7CiAgICAgIGxldCByZXN0T2ZTdHJpbmcgPSB0aGlzLm0uc2xpY2UodGhpcy5pKCkpOwogICAgICBsZXQgbWF0Y2hCeXRlSW5kZXggPSByZXN0T2ZTdHJpbmcuc2VhcmNoKHJlZ2V4KTsKICAgICAgaWYgKG1hdGNoQnl0ZUluZGV4IDw9IDApIHsKICAgICAgICByZXR1cm4gZW1wdHlTdHJpbmc7CiAgICAgIH0KICAgICAgbGV0IHJlc3VsdCA9IHJlc3RPZlN0cmluZy5zbGljZSgwLCBtYXRjaEJ5dGVJbmRleCk7CiAgICAgIHRoaXMuZyh0aGlzLnEocmVzdWx0KSk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGNoYXJhY3RlcnMgdW50aWwgdGhlIGdpdmVuIHN0cmluZyBpcyBmb3VuZCwgYWR2YW5jaW5nIHRoZSBzY2FubmVyCiAgICAgKiB1cCB0byAoYnV0IG5vdCBiZXlvbmQpIHRoYXQgcG9pbnQuIElmIHRoZSBzdHJpbmcgaXMgbmV2ZXIgZm91bmQsIG5vdGhpbmcKICAgICAqIHdpbGwgYmUgY29uc3VtZWQuCiAgICAgKgogICAgICogUmV0dXJucyB0aGUgY29uc3VtZWQgc3RyaW5nLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgY29uc3VtZWQuCiAgICAgKi8KICAgIHQoc2VhcmNoU3RyaW5nKSB7CiAgICAgIGxldCB7IG06IHN0cmluZyB9ID0gdGhpczsKICAgICAgbGV0IGJ5dGVJbmRleCA9IHRoaXMuaSgpOwogICAgICBsZXQgbWF0Y2hCeXRlSW5kZXggPSBzdHJpbmcuaW5kZXhPZihzZWFyY2hTdHJpbmcsIGJ5dGVJbmRleCk7CiAgICAgIGlmIChtYXRjaEJ5dGVJbmRleCA8PSAwKSB7CiAgICAgICAgcmV0dXJuIGVtcHR5U3RyaW5nOwogICAgICB9CiAgICAgIGxldCByZXN1bHQgPSBzdHJpbmcuc2xpY2UoYnl0ZUluZGV4LCBtYXRjaEJ5dGVJbmRleCk7CiAgICAgIHRoaXMuZyh0aGlzLnEocmVzdWx0KSk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGdpdmVuIG51bWJlciBvZiBjaGFyYWN0ZXJzIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IGNoYXJhY3RlcgogICAgICogaW5kZXgsIHdpdGhvdXQgYWR2YW5jaW5nIHRoZSBzY2FubmVyIGFuZCB3aXRob3V0IGV4Y2VlZGluZyB0aGUgZW5kIG9mIHRoZQogICAgICogaW5wdXQgc3RyaW5nLgogICAgICovCiAgICBoKGNvdW50ID0gMSkgewogICAgICBsZXQgeyBkOiBjaGFySW5kZXgsIG46IG11bHRpQnl0ZU1vZGUsIG06IHN0cmluZyB9ID0gdGhpczsKICAgICAgaWYgKG11bHRpQnl0ZU1vZGUpIHsKICAgICAgICBpZiAoY2hhckluZGV4ID49IHRoaXMuaykgewogICAgICAgICAgcmV0dXJuIGVtcHR5U3RyaW5nOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RyaW5nLnNsaWNlKAogICAgICAgICAgdGhpcy5pKGNoYXJJbmRleCksCiAgICAgICAgICB0aGlzLmkoY2hhckluZGV4ICsgY291bnQpCiAgICAgICAgKTsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nLnNsaWNlKGNoYXJJbmRleCwgY2hhckluZGV4ICsgY291bnQpOwogICAgfQogICAgLyoqCiAgICAgKiBSZXNldHMgdGhlIHNjYW5uZXIgcG9zaXRpb24gdG8gdGhlIGdpdmVuIGNoYXJhY3RlciBfaW5kZXhfLCBvciB0byB0aGUgc3RhcnQKICAgICAqIG9mIHRoZSBpbnB1dCBzdHJpbmcgaWYgbm8gaW5kZXggaXMgZ2l2ZW4uCiAgICAgKgogICAgICogSWYgX2luZGV4XyBpcyBuZWdhdGl2ZSwgdGhlIHNjYW5uZXIgcG9zaXRpb24gd2lsbCBiZSBtb3ZlZCBiYWNrd2FyZCBieSB0aGF0CiAgICAgKiBtYW55IGNoYXJhY3RlcnMsIHN0b3BwaW5nIGlmIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZyBpcyByZWFjaGVkLgogICAgICovCiAgICBvKGluZGV4ID0gMCkgewogICAgICB0aGlzLmQgPSBpbmRleCA+PSAwID8gTWF0aC5taW4odGhpcy5rLCBpbmRleCkgOiBNYXRoLm1heCgwLCB0aGlzLmQgKyBpbmRleCk7CiAgICB9CiAgfTsKICB2YXIgYXR0VmFsdWVDaGFyRG91YmxlUXVvdGUgPSAvW14iJjxdKy95OwogIHZhciBhdHRWYWx1ZUNoYXJTaW5nbGVRdW90ZSA9IC9bXicmPF0rL3k7CiAgdmFyIGF0dFZhbHVlTm9ybWFsaXplZFdoaXRlc3BhY2UgPSAvXHJcbnxbXG5cclx0XS9nOwogIHZhciBlbmRDaGFyRGF0YSA9IC88fCZ8XV0+LzsKICB2YXIgcHJlZGVmaW5lZEVudGl0aWVzID0gT2JqZWN0LmZyZWV6ZShPYmplY3QuYXNzaWduKC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpLCB7CiAgICBhbXA6ICImIiwKICAgIGFwb3M6ICInIiwKICAgIGd0OiAiPiIsCiAgICBsdDogIjwiLAogICAgcXVvdDogJyInCiAgfSkpOwogIGZ1bmN0aW9uIGlzTmFtZUNoYXIoY2hhcikgewogICAgbGV0IGNwID0gZ2V0Q29kZVBvaW50KGNoYXIpOwogICAgcmV0dXJuIGNwID49IDk3ICYmIGNwIDw9IDEyMiB8fCBjcCA+PSA2NSAmJiBjcCA8PSA5MCB8fCBjcCA+PSA0OCAmJiBjcCA8PSA1NyB8fCBjcCA9PT0gNDUgfHwgY3AgPT09IDQ2IHx8IGNwID09PSAxODMgfHwgY3AgPj0gNzY4ICYmIGNwIDw9IDg3OSB8fCBjcCA+PSA4MjU1ICYmIGNwIDw9IDgyNTYgfHwgaXNOYW1lU3RhcnRDaGFyKGNoYXIsIGNwKTsKICB9CiAgZnVuY3Rpb24gaXNOYW1lU3RhcnRDaGFyKGNoYXIsIGNwID0gZ2V0Q29kZVBvaW50KGNoYXIpKSB7CiAgICByZXR1cm4gY3AgPj0gOTcgJiYgY3AgPD0gMTIyIHx8IGNwID49IDY1ICYmIGNwIDw9IDkwIHx8IGNwID09PSA1OCB8fCBjcCA9PT0gOTUgfHwgY3AgPj0gMTkyICYmIGNwIDw9IDIxNCB8fCBjcCA+PSAyMTYgJiYgY3AgPD0gMjQ2IHx8IGNwID49IDI0OCAmJiBjcCA8PSA3NjcgfHwgY3AgPj0gODgwICYmIGNwIDw9IDg5MyB8fCBjcCA+PSA4OTUgJiYgY3AgPD0gODE5MSB8fCBjcCA+PSA4MjA0ICYmIGNwIDw9IDgyMDUgfHwgY3AgPj0gODMwNCAmJiBjcCA8PSA4NTkxIHx8IGNwID49IDExMjY0ICYmIGNwIDw9IDEyMjcxIHx8IGNwID49IDEyMjg5ICYmIGNwIDw9IDU1Mjk1IHx8IGNwID49IDYzNzQ0ICYmIGNwIDw9IDY0OTc1IHx8IGNwID49IDY1MDA4ICYmIGNwIDw9IDY1NTMzIHx8IGNwID49IDY1NTM2ICYmIGNwIDw9IDk4MzAzOTsKICB9CiAgZnVuY3Rpb24gaXNSZWZlcmVuY2VDaGFyKGNoYXIpIHsKICAgIHJldHVybiBjaGFyID09PSAiIyIgfHwgaXNOYW1lQ2hhcihjaGFyKTsKICB9CiAgZnVuY3Rpb24gaXNXaGl0ZXNwYWNlKGNoYXIpIHsKICAgIGxldCBjcCA9IGdldENvZGVQb2ludChjaGFyKTsKICAgIHJldHVybiBjcCA9PT0gMzIgfHwgY3AgPT09IDkgfHwgY3AgPT09IDEwIHx8IGNwID09PSAxMzsKICB9CiAgZnVuY3Rpb24gaXNYbWxDb2RlUG9pbnQoY3ApIHsKICAgIHJldHVybiBjcCA9PT0gOSB8fCBjcCA9PT0gMTAgfHwgY3AgPT09IDEzIHx8IGNwID49IDMyICYmIGNwIDw9IDU1Mjk1IHx8IGNwID49IDU3MzQ0ICYmIGNwIDw9IDY1NTMzIHx8IGNwID49IDY1NTM2ICYmIGNwIDw9IDExMTQxMTE7CiAgfQogIGZ1bmN0aW9uIGdldENvZGVQb2ludChjaGFyKSB7CiAgICByZXR1cm4gY2hhci5jb2RlUG9pbnRBdCgwKSB8fCAtMTsKICB9CiAgdmFyIF9YbWxOb2RlID0gY2xhc3MgewogICAgY29uc3RydWN0b3IoKSB7CiAgICAgIHRoaXMucGFyZW50ID0gbnVsbDsKICAgICAgdGhpcy5zdGFydCA9IC0xOwogICAgICB0aGlzLmVuZCA9IC0xOwogICAgfQogICAgLyoqCiAgICAgKiBEb2N1bWVudCB0aGF0IGNvbnRhaW5zIHRoaXMgbm9kZSwgb3IgYG51bGxgIGlmIHRoaXMgbm9kZSBpcyBub3QgYXNzb2NpYXRlZAogICAgICogd2l0aCBhIGRvY3VtZW50LgogICAgICovCiAgICBnZXQgZG9jdW1lbnQoKSB7CiAgICAgIHZhciBfYSwgX2I7CiAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLnBhcmVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9hLmRvY3VtZW50KSAhPSBudWxsID8gX2IgOiBudWxsOwogICAgfQogICAgLyoqCiAgICAgKiBXaGV0aGVyIHRoaXMgbm9kZSBpcyB0aGUgcm9vdCBub2RlIG9mIHRoZSBkb2N1bWVudCAoYWxzbyBrbm93biBhcyB0aGUKICAgICAqIGRvY3VtZW50IGVsZW1lbnQpLgogICAgICovCiAgICBnZXQgaXNSb290Tm9kZSgpIHsKICAgICAgcmV0dXJuIHRoaXMucGFyZW50ICE9PSBudWxsICYmIHRoaXMucGFyZW50ID09PSB0aGlzLmRvY3VtZW50ICYmIHRoaXMudHlwZSA9PT0gX1htbE5vZGUuVFlQRV9FTEVNRU5UOwogICAgfQogICAgLyoqCiAgICAgKiBXaGV0aGVyIHdoaXRlc3BhY2Ugc2hvdWxkIGJlIHByZXNlcnZlZCBpbiB0aGUgY29udGVudCBvZiB0aGlzIGVsZW1lbnQgYW5kCiAgICAgKiBpdHMgY2hpbGRyZW4uCiAgICAgKgogICAgICogVGhpcyBpcyBpbmZsdWVuY2VkIGJ5IHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lhbCBgeG1sOnNwYWNlYCBhdHRyaWJ1dGUsIGFuZAogICAgICogd2lsbCBiZSBgdHJ1ZWAgZm9yIGFueSBub2RlIHdob3NlIGB4bWw6c3BhY2VgIGF0dHJpYnV0ZSBpcyBzZXQgdG8KICAgICAqICJwcmVzZXJ2ZSIuIElmIGEgbm9kZSBoYXMgbm8gc3VjaCBhdHRyaWJ1dGUsIGl0IHdpbGwgaW5oZXJpdCB0aGUgdmFsdWUgb2YKICAgICAqIHRoZSBuZWFyZXN0IGFuY2VzdG9yIHRoYXQgZG9lcyAoaWYgYW55KS4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI3NlYy13aGl0ZS1zcGFjZQogICAgICovCiAgICBnZXQgcHJlc2VydmVXaGl0ZXNwYWNlKCkgewogICAgICB2YXIgX2E7CiAgICAgIHJldHVybiAhISgoX2EgPSB0aGlzLnBhcmVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9hLnByZXNlcnZlV2hpdGVzcGFjZSk7CiAgICB9CiAgICAvKioKICAgICAqIFR5cGUgb2YgdGhpcyBub2RlLgogICAgICoKICAgICAqIFRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIGEgc3RyaW5nIHRoYXQgbWF0Y2hlcyBvbmUgb2YgdGhlIHN0YXRpYwogICAgICogYFRZUEVfKmAgcHJvcGVydGllcyBvbiB0aGUgYFhtbE5vZGVgIGNsYXNzIChlLmcuIGBUWVBFX0VMRU1FTlRgLAogICAgICogYFRZUEVfVEVYVGAsIGV0Yy4pLgogICAgICoKICAgICAqIFRoZSBgWG1sTm9kZWAgY2xhc3MgaXRzZWxmIGlzIGEgYmFzZSBjbGFzcyBhbmQgZG9lc24ndCBoYXZlIGl0cyBvd24gdHlwZQogICAgICogbmFtZS4KICAgICAqLwogICAgZ2V0IHR5cGUoKSB7CiAgICAgIHJldHVybiAiIjsKICAgIH0KICAgIC8qKgogICAgICogUmV0dXJucyBhIEpTT04tc2VyaWFsaXphYmxlIG9iamVjdCByZXByZXNlbnRpbmcgdGhpcyBub2RlLCBtaW51cyBwcm9wZXJ0aWVzCiAgICAgKiB0aGF0IGNvdWxkIHJlc3VsdCBpbiBjaXJjdWxhciByZWZlcmVuY2VzLgogICAgICovCiAgICB0b0pTT04oKSB7CiAgICAgIGxldCBqc29uID0gewogICAgICAgIHR5cGU6IHRoaXMudHlwZQogICAgICB9OwogICAgICBpZiAodGhpcy5pc1Jvb3ROb2RlKSB7CiAgICAgICAganNvbi5pc1Jvb3ROb2RlID0gdHJ1ZTsKICAgICAgfQogICAgICBpZiAodGhpcy5wcmVzZXJ2ZVdoaXRlc3BhY2UpIHsKICAgICAgICBqc29uLnByZXNlcnZlV2hpdGVzcGFjZSA9IHRydWU7CiAgICAgIH0KICAgICAgaWYgKHRoaXMuc3RhcnQgIT09IC0xKSB7CiAgICAgICAganNvbi5zdGFydCA9IHRoaXMuc3RhcnQ7CiAgICAgICAganNvbi5lbmQgPSB0aGlzLmVuZDsKICAgICAgfQogICAgICByZXR1cm4ganNvbjsKICAgIH0KICB9OwogIHZhciBYbWxOb2RlID0gX1htbE5vZGU7CiAgWG1sTm9kZS5UWVBFX0NEQVRBID0gImNkYXRhIjsKICBYbWxOb2RlLlRZUEVfQ09NTUVOVCA9ICJjb21tZW50IjsKICBYbWxOb2RlLlRZUEVfRE9DVU1FTlQgPSAiZG9jdW1lbnQiOwogIFhtbE5vZGUuVFlQRV9ET0NVTUVOVF9UWVBFID0gImRvY3R5cGUiOwogIFhtbE5vZGUuVFlQRV9FTEVNRU5UID0gImVsZW1lbnQiOwogIFhtbE5vZGUuVFlQRV9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OID0gInBpIjsKICBYbWxOb2RlLlRZUEVfVEVYVCA9ICJ0ZXh0IjsKICBYbWxOb2RlLlRZUEVfWE1MX0RFQ0xBUkFUSU9OID0gInhtbGRlY2wiOwogIHZhciBYbWxUZXh0ID0gY2xhc3MgZXh0ZW5kcyBYbWxOb2RlIHsKICAgIGNvbnN0cnVjdG9yKHRleHQgPSAiIikgewogICAgICBzdXBlcigpOwogICAgICB0aGlzLnRleHQgPSB0ZXh0OwogICAgfQogICAgZ2V0IHR5cGUoKSB7CiAgICAgIHJldHVybiBYbWxOb2RlLlRZUEVfVEVYVDsKICAgIH0KICAgIHRvSlNPTigpIHsKICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oWG1sTm9kZS5wcm90b3R5cGUudG9KU09OLmNhbGwodGhpcyksIHsKICAgICAgICB0ZXh0OiB0aGlzLnRleHQKICAgICAgfSk7CiAgICB9CiAgfTsKICB2YXIgWG1sQ2RhdGEgPSBjbGFzcyBleHRlbmRzIFhtbFRleHQgewogICAgZ2V0IHR5cGUoKSB7CiAgICAgIHJldHVybiBYbWxOb2RlLlRZUEVfQ0RBVEE7CiAgICB9CiAgfTsKICB2YXIgWG1sQ29tbWVudCA9IGNsYXNzIGV4dGVuZHMgWG1sTm9kZSB7CiAgICBjb25zdHJ1Y3Rvcihjb250ZW50ID0gIiIpIHsKICAgICAgc3VwZXIoKTsKICAgICAgdGhpcy5jb250ZW50ID0gY29udGVudDsKICAgIH0KICAgIGdldCB0eXBlKCkgewogICAgICByZXR1cm4gWG1sTm9kZS5UWVBFX0NPTU1FTlQ7CiAgICB9CiAgICB0b0pTT04oKSB7CiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFhtbE5vZGUucHJvdG90eXBlLnRvSlNPTi5jYWxsKHRoaXMpLCB7CiAgICAgICAgY29udGVudDogdGhpcy5jb250ZW50CiAgICAgIH0pOwogICAgfQogIH07CiAgdmFyIFhtbERlY2xhcmF0aW9uID0gY2xhc3MgZXh0ZW5kcyBYbWxOb2RlIHsKICAgIGNvbnN0cnVjdG9yKHZlcnNpb24sIGVuY29kaW5nLCBzdGFuZGFsb25lKSB7CiAgICAgIHN1cGVyKCk7CiAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247CiAgICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZyAhPSBudWxsID8gZW5jb2RpbmcgOiBudWxsOwogICAgICB0aGlzLnN0YW5kYWxvbmUgPSBzdGFuZGFsb25lICE9IG51bGwgPyBzdGFuZGFsb25lIDogbnVsbDsKICAgIH0KICAgIGdldCB0eXBlKCkgewogICAgICByZXR1cm4gWG1sTm9kZS5UWVBFX1hNTF9ERUNMQVJBVElPTjsKICAgIH0KICAgIHRvSlNPTigpIHsKICAgICAgbGV0IGpzb24gPSBYbWxOb2RlLnByb3RvdHlwZS50b0pTT04uY2FsbCh0aGlzKTsKICAgICAganNvbi52ZXJzaW9uID0gdGhpcy52ZXJzaW9uOwogICAgICBmb3IgKGxldCBrZXkgb2YgWyJlbmNvZGluZyIsICJzdGFuZGFsb25lIl0pIHsKICAgICAgICBpZiAodGhpc1trZXldICE9PSBudWxsKSB7CiAgICAgICAgICBqc29uW2tleV0gPSB0aGlzW2tleV07CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBqc29uOwogICAgfQogIH07CiAgdmFyIFhtbEVsZW1lbnQgPSBjbGFzcyBleHRlbmRzIFhtbE5vZGUgewogICAgY29uc3RydWN0b3IobmFtZSwgYXR0cmlidXRlcyA9IC8qIEBfX1BVUkVfXyAqLyBPYmplY3QuY3JlYXRlKG51bGwpLCBjaGlsZHJlbiA9IFtdKSB7CiAgICAgIHN1cGVyKCk7CiAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgIHRoaXMuYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXM7CiAgICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjsKICAgIH0KICAgIC8qKgogICAgICogV2hldGhlciB0aGlzIGVsZW1lbnQgaXMgZW1wdHkgKG1lYW5pbmcgaXQgaGFzIG5vIGNoaWxkcmVuKS4KICAgICAqLwogICAgZ2V0IGlzRW1wdHkoKSB7CiAgICAgIHJldHVybiB0aGlzLmNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgIH0KICAgIGdldCBwcmVzZXJ2ZVdoaXRlc3BhY2UoKSB7CiAgICAgIGxldCBub2RlID0gdGhpczsKICAgICAgd2hpbGUgKG5vZGUgaW5zdGFuY2VvZiBYbWxFbGVtZW50KSB7CiAgICAgICAgaWYgKCJ4bWw6c3BhY2UiIGluIG5vZGUuYXR0cmlidXRlcykgewogICAgICAgICAgcmV0dXJuIG5vZGUuYXR0cmlidXRlc1sieG1sOnNwYWNlIl0gPT09ICJwcmVzZXJ2ZSI7CiAgICAgICAgfQogICAgICAgIG5vZGUgPSBub2RlLnBhcmVudDsKICAgICAgfQogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICAvKioKICAgICAqIFRleHQgY29udGVudCBvZiB0aGlzIGVsZW1lbnQgYW5kIGFsbCBpdHMgZGVzY2VuZGFudHMuCiAgICAgKi8KICAgIGdldCB0ZXh0KCkgewogICAgICByZXR1cm4gdGhpcy5jaGlsZHJlbi5tYXAoKGNoaWxkKSA9PiAidGV4dCIgaW4gY2hpbGQgPyBjaGlsZC50ZXh0IDogIiIpLmpvaW4oIiIpOwogICAgfQogICAgZ2V0IHR5cGUoKSB7CiAgICAgIHJldHVybiBYbWxOb2RlLlRZUEVfRUxFTUVOVDsKICAgIH0KICAgIHRvSlNPTigpIHsKICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oWG1sTm9kZS5wcm90b3R5cGUudG9KU09OLmNhbGwodGhpcyksIHsKICAgICAgICBuYW1lOiB0aGlzLm5hbWUsCiAgICAgICAgYXR0cmlidXRlczogdGhpcy5hdHRyaWJ1dGVzLAogICAgICAgIGNoaWxkcmVuOiB0aGlzLmNoaWxkcmVuLm1hcCgoY2hpbGQpID0+IGNoaWxkLnRvSlNPTigpKQogICAgICB9KTsKICAgIH0KICB9OwogIHZhciBYbWxEb2N1bWVudCA9IGNsYXNzIGV4dGVuZHMgWG1sTm9kZSB7CiAgICBjb25zdHJ1Y3RvcihjaGlsZHJlbiA9IFtdKSB7CiAgICAgIHN1cGVyKCk7CiAgICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjsKICAgIH0KICAgIGdldCBkb2N1bWVudCgpIHsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIFJvb3QgZWxlbWVudCBvZiB0aGlzIGRvY3VtZW50LCBvciBgbnVsbGAgaWYgdGhpcyBkb2N1bWVudCBpcyBlbXB0eS4KICAgICAqLwogICAgZ2V0IHJvb3QoKSB7CiAgICAgIGZvciAobGV0IGNoaWxkIG9mIHRoaXMuY2hpbGRyZW4pIHsKICAgICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBYbWxFbGVtZW50KSB7CiAgICAgICAgICByZXR1cm4gY2hpbGQ7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgLyoqCiAgICAgKiBUZXh0IGNvbnRlbnQgb2YgdGhpcyBkb2N1bWVudCBhbmQgYWxsIGl0cyBkZXNjZW5kYW50cy4KICAgICAqLwogICAgZ2V0IHRleHQoKSB7CiAgICAgIHJldHVybiB0aGlzLmNoaWxkcmVuLm1hcCgoY2hpbGQpID0+ICJ0ZXh0IiBpbiBjaGlsZCA/IGNoaWxkLnRleHQgOiAiIikuam9pbigiIik7CiAgICB9CiAgICBnZXQgdHlwZSgpIHsKICAgICAgcmV0dXJuIFhtbE5vZGUuVFlQRV9ET0NVTUVOVDsKICAgIH0KICAgIHRvSlNPTigpIHsKICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oWG1sTm9kZS5wcm90b3R5cGUudG9KU09OLmNhbGwodGhpcyksIHsKICAgICAgICBjaGlsZHJlbjogdGhpcy5jaGlsZHJlbi5tYXAoKGNoaWxkKSA9PiBjaGlsZC50b0pTT04oKSkKICAgICAgfSk7CiAgICB9CiAgfTsKICB2YXIgWG1sRG9jdW1lbnRUeXBlID0gY2xhc3MgZXh0ZW5kcyBYbWxOb2RlIHsKICAgIGNvbnN0cnVjdG9yKG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgaW50ZXJuYWxTdWJzZXQpIHsKICAgICAgc3VwZXIoKTsKICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgdGhpcy5wdWJsaWNJZCA9IHB1YmxpY0lkICE9IG51bGwgPyBwdWJsaWNJZCA6IG51bGw7CiAgICAgIHRoaXMuc3lzdGVtSWQgPSBzeXN0ZW1JZCAhPSBudWxsID8gc3lzdGVtSWQgOiBudWxsOwogICAgICB0aGlzLmludGVybmFsU3Vic2V0ID0gaW50ZXJuYWxTdWJzZXQgIT0gbnVsbCA/IGludGVybmFsU3Vic2V0IDogbnVsbDsKICAgIH0KICAgIGdldCB0eXBlKCkgewogICAgICByZXR1cm4gWG1sTm9kZS5UWVBFX0RPQ1VNRU5UX1RZUEU7CiAgICB9CiAgICB0b0pTT04oKSB7CiAgICAgIGxldCBqc29uID0gWG1sTm9kZS5wcm90b3R5cGUudG9KU09OLmNhbGwodGhpcyk7CiAgICAgIGpzb24ubmFtZSA9IHRoaXMubmFtZTsKICAgICAgZm9yIChsZXQga2V5IG9mIFsicHVibGljSWQiLCAic3lzdGVtSWQiLCAiaW50ZXJuYWxTdWJzZXQiXSkgewogICAgICAgIGlmICh0aGlzW2tleV0gIT09IG51bGwpIHsKICAgICAgICAgIGpzb25ba2V5XSA9IHRoaXNba2V5XTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIGpzb247CiAgICB9CiAgfTsKICB2YXIgWG1sRXJyb3IgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIGNoYXJJbmRleCwgeG1sKSB7CiAgICAgIGxldCBjb2x1bW4gPSAxOwogICAgICBsZXQgZXhjZXJwdCA9ICIiOwogICAgICBsZXQgbGluZSA9IDE7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hhckluZGV4OyArK2kpIHsKICAgICAgICBsZXQgY2hhciA9IHhtbFtpXTsKICAgICAgICBpZiAoY2hhciA9PT0gIlxuIikgewogICAgICAgICAgY29sdW1uID0gMTsKICAgICAgICAgIGV4Y2VycHQgPSAiIjsKICAgICAgICAgIGxpbmUgKz0gMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY29sdW1uICs9IDE7CiAgICAgICAgICBleGNlcnB0ICs9IGNoYXI7CiAgICAgICAgfQogICAgICB9CiAgICAgIGxldCBlb2wgPSB4bWwuaW5kZXhPZigiXG4iLCBjaGFySW5kZXgpOwogICAgICBleGNlcnB0ICs9IGVvbCA9PT0gLTEgPyB4bWwuc2xpY2UoY2hhckluZGV4KSA6IHhtbC5zbGljZShjaGFySW5kZXgsIGVvbCk7CiAgICAgIGxldCBleGNlcnB0U3RhcnQgPSAwOwogICAgICBpZiAoZXhjZXJwdC5sZW5ndGggPiA1MCkgewogICAgICAgIGlmIChjb2x1bW4gPCA0MCkgewogICAgICAgICAgZXhjZXJwdCA9IGV4Y2VycHQuc2xpY2UoMCwgNTApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBleGNlcnB0U3RhcnQgPSBjb2x1bW4gLSAyMDsKICAgICAgICAgIGV4Y2VycHQgPSBleGNlcnB0LnNsaWNlKGV4Y2VycHRTdGFydCwgY29sdW1uICsgMzApOwogICAgICAgIH0KICAgICAgfQogICAgICBzdXBlcigKICAgICAgICBgJHttZXNzYWdlfSAobGluZSAke2xpbmV9LCBjb2x1bW4gJHtjb2x1bW59KQogICR7ZXhjZXJwdH0KYCArICIgIi5yZXBlYXQoY29sdW1uIC0gZXhjZXJwdFN0YXJ0ICsgMSkgKyAiXlxuIgogICAgICApOwogICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKICAgICAgdGhpcy5leGNlcnB0ID0gZXhjZXJwdDsKICAgICAgdGhpcy5saW5lID0gbGluZTsKICAgICAgdGhpcy5uYW1lID0gIlhtbEVycm9yIjsKICAgICAgdGhpcy5wb3MgPSBjaGFySW5kZXg7CiAgICB9CiAgfTsKICB2YXIgWG1sUHJvY2Vzc2luZ0luc3RydWN0aW9uID0gY2xhc3MgZXh0ZW5kcyBYbWxOb2RlIHsKICAgIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnQgPSAiIikgewogICAgICBzdXBlcigpOwogICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50OwogICAgfQogICAgZ2V0IHR5cGUoKSB7CiAgICAgIHJldHVybiBYbWxOb2RlLlRZUEVfUFJPQ0VTU0lOR19JTlNUUlVDVElPTjsKICAgIH0KICAgIHRvSlNPTigpIHsKICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oWG1sTm9kZS5wcm90b3R5cGUudG9KU09OLmNhbGwodGhpcyksIHsKICAgICAgICBuYW1lOiB0aGlzLm5hbWUsCiAgICAgICAgY29udGVudDogdGhpcy5jb250ZW50CiAgICAgIH0pOwogICAgfQogIH07CiAgdmFyIGVtcHR5U3RyaW5nMiA9ICIiOwogIHZhciBQYXJzZXIgPSBjbGFzcyB7CiAgICAvKioKICAgICAqIEBwYXJhbSB4bWwgWE1MIHN0cmluZyB0byBwYXJzZS4KICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcnNlciBvcHRpb25zLgogICAgICovCiAgICBjb25zdHJ1Y3Rvcih4bWwsIG9wdGlvbnMgPSB7fSkgewogICAgICBsZXQgZG9jID0gdGhpcy5kb2N1bWVudCA9IG5ldyBYbWxEb2N1bWVudCgpOwogICAgICBsZXQgc2Nhbm5lciA9IHRoaXMuYyA9IG5ldyBTdHJpbmdTY2FubmVyKHhtbCk7CiAgICAgIHRoaXMubCA9IGRvYzsKICAgICAgdGhpcy5mID0gb3B0aW9uczsKICAgICAgaWYgKHRoaXMuZi5pbmNsdWRlT2Zmc2V0cykgewogICAgICAgIGRvYy5zdGFydCA9IDA7CiAgICAgICAgZG9jLmVuZCA9IHhtbC5sZW5ndGg7CiAgICAgIH0KICAgICAgc2Nhbm5lci5iKCJcdUZFRkYiKTsKICAgICAgdGhpcy5IKCk7CiAgICAgIGlmICghdGhpcy5CKCkpIHsKICAgICAgICB0aHJvdyB0aGlzLmEoIlJvb3QgZWxlbWVudCBpcyBtaXNzaW5nIG9yIGludmFsaWQiKTsKICAgICAgfQogICAgICB3aGlsZSAodGhpcy53KCkpIHsKICAgICAgfQogICAgICBpZiAoIXNjYW5uZXIueikgewogICAgICAgIHRocm93IHRoaXMuYSgiRXh0cmEgY29udGVudCBhdCB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudCIpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIEFkZHMgdGhlIGdpdmVuIGBYbWxOb2RlYCBhcyBhIGNoaWxkIG9mIGB0aGlzLmN1cnJlbnROb2RlYC4KICAgICAqLwogICAgaihub2RlLCBjaGFySW5kZXgpIHsKICAgICAgbm9kZS5wYXJlbnQgPSB0aGlzLmw7CiAgICAgIGlmICh0aGlzLmYuaW5jbHVkZU9mZnNldHMpIHsKICAgICAgICBub2RlLnN0YXJ0ID0gdGhpcy5jLmkoY2hhckluZGV4KTsKICAgICAgICBub2RlLmVuZCA9IHRoaXMuYy5pKCk7CiAgICAgIH0KICAgICAgdGhpcy5sLmNoaWxkcmVuLnB1c2gobm9kZSk7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgLyoqCiAgICAgKiBBZGRzIHRoZSBnaXZlbiBfdGV4dF8gdG8gdGhlIGRvY3VtZW50LCBlaXRoZXIgYnkgYXBwZW5kaW5nIGl0IHRvIGEKICAgICAqIHByZWNlZGluZyBgWG1sVGV4dGAgbm9kZSAoaWYgcG9zc2libGUpIG9yIGJ5IGNyZWF0aW5nIGEgbmV3IGBYbWxUZXh0YCBub2RlLgogICAgICovCiAgICB4KHRleHQsIGNoYXJJbmRleCkgewogICAgICBsZXQgeyBjaGlsZHJlbiB9ID0gdGhpcy5sOwogICAgICBsZXQgeyBsZW5ndGggfSA9IGNoaWxkcmVuOwogICAgICB0ZXh0ID0gbm9ybWFsaXplTGluZUJyZWFrcyh0ZXh0KTsKICAgICAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgICBsZXQgcHJldk5vZGUgPSBjaGlsZHJlbltsZW5ndGggLSAxXTsKICAgICAgICBpZiAoKHByZXZOb2RlID09IG51bGwgPyB2b2lkIDAgOiBwcmV2Tm9kZS50eXBlKSA9PT0gWG1sTm9kZS5UWVBFX1RFWFQpIHsKICAgICAgICAgIGxldCB0ZXh0Tm9kZSA9IHByZXZOb2RlOwogICAgICAgICAgdGV4dE5vZGUudGV4dCArPSB0ZXh0OwogICAgICAgICAgaWYgKHRoaXMuZi5pbmNsdWRlT2Zmc2V0cykgewogICAgICAgICAgICB0ZXh0Tm9kZS5lbmQgPSB0aGlzLmMuaSgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB0aGlzLmoobmV3IFhtbFRleHQodGV4dCksIGNoYXJJbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGVsZW1lbnQgYXR0cmlidXRlcy4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI3NlYy1zdGFydHRhZ3MKICAgICAqLwogICAgSSgpIHsKICAgICAgbGV0IGF0dHJpYnV0ZXMgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKTsKICAgICAgd2hpbGUgKHRoaXMuZSgpKSB7CiAgICAgICAgbGV0IGF0dHJOYW1lID0gdGhpcy5yKCk7CiAgICAgICAgaWYgKCFhdHRyTmFtZSkgewogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGxldCBhdHRyVmFsdWUgPSB0aGlzLnUoKSAmJiB0aGlzLkooKTsKICAgICAgICBpZiAoYXR0clZhbHVlID09PSBmYWxzZSkgewogICAgICAgICAgdGhyb3cgdGhpcy5hKCJBdHRyaWJ1dGUgdmFsdWUgZXhwZWN0ZWQiKTsKICAgICAgICB9CiAgICAgICAgaWYgKGF0dHJOYW1lIGluIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgIHRocm93IHRoaXMuYShgRHVwbGljYXRlIGF0dHJpYnV0ZTogJHthdHRyTmFtZX1gKTsKICAgICAgICB9CiAgICAgICAgaWYgKGF0dHJOYW1lID09PSAieG1sOnNwYWNlIiAmJiBhdHRyVmFsdWUgIT09ICJkZWZhdWx0IiAmJiBhdHRyVmFsdWUgIT09ICJwcmVzZXJ2ZSIpIHsKICAgICAgICAgIHRocm93IHRoaXMuYSgnVmFsdWUgb2YgdGhlIGB4bWw6c3BhY2VgIGF0dHJpYnV0ZSBtdXN0IGJlICJkZWZhdWx0IiBvciAicHJlc2VydmUiJyk7CiAgICAgICAgfQogICAgICAgIGF0dHJpYnV0ZXNbYXR0ck5hbWVdID0gYXR0clZhbHVlOwogICAgICB9CiAgICAgIGlmICh0aGlzLmYuc29ydEF0dHJpYnV0ZXMpIHsKICAgICAgICBsZXQgYXR0ck5hbWVzID0gT2JqZWN0LmtleXMoYXR0cmlidXRlcykuc29ydCgpOwogICAgICAgIGxldCBzb3J0ZWRBdHRyaWJ1dGVzID0gLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyTmFtZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgIGxldCBhdHRyTmFtZSA9IGF0dHJOYW1lc1tpXTsKICAgICAgICAgIHNvcnRlZEF0dHJpYnV0ZXNbYXR0ck5hbWVdID0gYXR0cmlidXRlc1thdHRyTmFtZV07CiAgICAgICAgfQogICAgICAgIGF0dHJpYnV0ZXMgPSBzb3J0ZWRBdHRyaWJ1dGVzOwogICAgICB9CiAgICAgIHJldHVybiBhdHRyaWJ1dGVzOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhbiBgQXR0VmFsdWVgIChhdHRyaWJ1dGUgdmFsdWUpIGlmIHBvc3NpYmxlLgogICAgICoKICAgICAqIEByZXR1cm5zCiAgICAgKiAgIENvbnRlbnRzIG9mIHRoZSBgQXR0VmFsdWVgIG1pbnVzIHF1b3Rlcywgb3IgYGZhbHNlYCBpZiBub3RoaW5nIHdhcwogICAgICogICBjb25zdW1lZC4gQW4gZW1wdHkgc3RyaW5nIGluZGljYXRlcyB0aGF0IGFuIGBBdHRWYWx1ZWAgd2FzIGNvbnN1bWVkIGJ1dAogICAgICogICB3YXMgZW1wdHkuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNOVC1BdHRWYWx1ZQogICAgICovCiAgICBKKCkgewogICAgICBsZXQgeyBjOiBzY2FubmVyIH0gPSB0aGlzOwogICAgICBsZXQgcXVvdGUgPSBzY2FubmVyLmgoKTsKICAgICAgaWYgKHF1b3RlICE9PSAnIicgJiYgcXVvdGUgIT09ICInIikgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBzY2FubmVyLmcoKTsKICAgICAgbGV0IGNoYXJzOwogICAgICBsZXQgaXNDbG9zZWQgPSBmYWxzZTsKICAgICAgbGV0IHZhbHVlID0gZW1wdHlTdHJpbmcyOwogICAgICBsZXQgcmVnZXggPSBxdW90ZSA9PT0gJyInID8gYXR0VmFsdWVDaGFyRG91YmxlUXVvdGUgOiBhdHRWYWx1ZUNoYXJTaW5nbGVRdW90ZTsKICAgICAgbWF0Y2hMb29wOgogICAgICAgIHdoaWxlICghc2Nhbm5lci56KSB7CiAgICAgICAgICBjaGFycyA9IHNjYW5uZXIuRyhyZWdleCk7CiAgICAgICAgICBpZiAoY2hhcnMpIHsKICAgICAgICAgICAgdGhpcy5wKGNoYXJzKTsKICAgICAgICAgICAgdmFsdWUgKz0gY2hhcnMucmVwbGFjZShhdHRWYWx1ZU5vcm1hbGl6ZWRXaGl0ZXNwYWNlLCAiICIpOwogICAgICAgICAgfQogICAgICAgICAgc3dpdGNoIChzY2FubmVyLmgoKSkgewogICAgICAgICAgICBjYXNlIHF1b3RlOgogICAgICAgICAgICAgIGlzQ2xvc2VkID0gdHJ1ZTsKICAgICAgICAgICAgICBicmVhayBtYXRjaExvb3A7CiAgICAgICAgICAgIGNhc2UgIiYiOgogICAgICAgICAgICAgIHZhbHVlICs9IHRoaXMuQygpOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBjYXNlICI8IjoKICAgICAgICAgICAgICB0aHJvdyB0aGlzLmEoIlVuZXNjYXBlZCBgPGAgaXMgbm90IGFsbG93ZWQgaW4gYW4gYXR0cmlidXRlIHZhbHVlIik7CiAgICAgICAgICAgIGNhc2UgZW1wdHlTdHJpbmcyOgogICAgICAgICAgICAgIGJyZWFrIG1hdGNoTG9vcDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIGlmICghaXNDbG9zZWQpIHsKICAgICAgICB0aHJvdyB0aGlzLmEoIlVuY2xvc2VkIGF0dHJpYnV0ZSIpOwogICAgICB9CiAgICAgIHNjYW5uZXIuZygpOwogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgQ0RBVEEgc2VjdGlvbiBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGEgQ0RBVEEgc2VjdGlvbiB3YXMgY29uc3VtZWQuCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI3NlYy1jZGF0YS1zZWN0CiAgICAgKi8KICAgIEsoKSB7CiAgICAgIGxldCB7IGM6IHNjYW5uZXIgfSA9IHRoaXM7CiAgICAgIGxldCBzdGFydEluZGV4ID0gc2Nhbm5lci5kOwogICAgICBpZiAoIXNjYW5uZXIuYigiPCFbQ0RBVEFbIikpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IHRleHQgPSBzY2FubmVyLnQoIl1dPiIpOwogICAgICB0aGlzLnAodGV4dCk7CiAgICAgIGlmICghc2Nhbm5lci5iKCJdXT4iKSkgewogICAgICAgIHRocm93IHRoaXMuYSgiVW5jbG9zZWQgQ0RBVEEgc2VjdGlvbiIpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLmYucHJlc2VydmVDZGF0YSA/IHRoaXMuaihuZXcgWG1sQ2RhdGEobm9ybWFsaXplTGluZUJyZWFrcyh0ZXh0KSksIHN0YXJ0SW5kZXgpIDogdGhpcy54KHRleHQsIHN0YXJ0SW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBjaGFyYWN0ZXIgZGF0YSBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGNoYXJhY3RlciBkYXRhIHdhcyBjb25zdW1lZC4KICAgICAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMDgvUkVDLXhtbC0yMDA4MTEyNi8jZHQtY2hhcmRhdGEKICAgICAqLwogICAgTCgpIHsKICAgICAgbGV0IHsgYzogc2Nhbm5lciB9ID0gdGhpczsKICAgICAgbGV0IHN0YXJ0SW5kZXggPSBzY2FubmVyLmQ7CiAgICAgIGxldCBjaGFyRGF0YSA9IHNjYW5uZXIuQShlbmRDaGFyRGF0YSk7CiAgICAgIGlmICghY2hhckRhdGEpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgdGhpcy5wKGNoYXJEYXRhKTsKICAgICAgaWYgKHNjYW5uZXIuaCgzKSA9PT0gIl1dPiIpIHsKICAgICAgICB0aHJvdyB0aGlzLmEoIkVsZW1lbnQgY29udGVudCBtYXkgbm90IGNvbnRhaW4gdGhlIENEQVRBIHNlY3Rpb24gY2xvc2UgZGVsaW1pdGVyIGBdXT5gIik7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMueChjaGFyRGF0YSwgc3RhcnRJbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgY29tbWVudCBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGEgY29tbWVudCB3YXMgY29uc3VtZWQuCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI05ULUNvbW1lbnQKICAgICAqLwogICAgRCgpIHsKICAgICAgbGV0IHsgYzogc2Nhbm5lciB9ID0gdGhpczsKICAgICAgbGV0IHN0YXJ0SW5kZXggPSBzY2FubmVyLmQ7CiAgICAgIGlmICghc2Nhbm5lci5iKCI8IS0tIikpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IGNvbnRlbnQgPSBzY2FubmVyLnQoIi0tIik7CiAgICAgIHRoaXMucChjb250ZW50KTsKICAgICAgaWYgKCFzY2FubmVyLmIoIi0tPiIpKSB7CiAgICAgICAgaWYgKHNjYW5uZXIuaCgyKSA9PT0gIi0tIikgewogICAgICAgICAgdGhyb3cgdGhpcy5hKCJUaGUgc3RyaW5nIGAtLWAgaXNuJ3QgYWxsb3dlZCBpbnNpZGUgYSBjb21tZW50Iik7CiAgICAgICAgfQogICAgICAgIHRocm93IHRoaXMuYSgiVW5jbG9zZWQgY29tbWVudCIpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLmYucHJlc2VydmVDb21tZW50cyA/IHRoaXMuaihuZXcgWG1sQ29tbWVudChub3JtYWxpemVMaW5lQnJlYWtzKGNvbnRlbnQpKSwgc3RhcnRJbmRleCkgOiB0cnVlOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhIHJlZmVyZW5jZSBpbiBhIGNvbnRlbnQgY29udGV4dCBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBUaGlzIGRpZmZlcnMgZnJvbSBgY29uc3VtZVJlZmVyZW5jZSgpYCBpbiB0aGF0IGEgY29uc3VtZWQgcmVmZXJlbmNlIHdpbGwgYmUKICAgICAqIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBhcyBhIHRleHQgbm9kZSBpbnN0ZWFkIG9mIHJldHVybmVkLgogICAgICoKICAgICAqIEByZXR1cm5zIFdoZXRoZXIgYSByZWZlcmVuY2Ugd2FzIGNvbnN1bWVkLgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNlbnRwcm9jCiAgICAgKi8KICAgIE0oKSB7CiAgICAgIGxldCBzdGFydEluZGV4ID0gdGhpcy5jLmQ7CiAgICAgIGxldCByZWYgPSB0aGlzLkMoKTsKICAgICAgcmV0dXJuIHJlZiA/IHRoaXMueChyZWYsIHN0YXJ0SW5kZXgpIDogZmFsc2U7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgZG9jdHlwZSBkZWNsYXJhdGlvbiBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBUaGlzIGlzIGEgbG9vc2UgaW1wbGVtZW50YXRpb24gc2luY2UgZG9jdHlwZSBkZWNsYXJhdGlvbnMgYXJlIGN1cnJlbnRseQogICAgICogZGlzY2FyZGVkIHdpdGhvdXQgZnVydGhlciBwYXJzaW5nLgogICAgICoKICAgICAqIEByZXR1cm5zIFdoZXRoZXIgYSBkb2N0eXBlIGRlY2xhcmF0aW9uIHdhcyBjb25zdW1lZC4KICAgICAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMDgvUkVDLXhtbC0yMDA4MTEyNi8jZHRkCiAgICAgKi8KICAgIE4oKSB7CiAgICAgIGxldCB7IGM6IHNjYW5uZXIgfSA9IHRoaXM7CiAgICAgIGxldCBzdGFydEluZGV4ID0gc2Nhbm5lci5kOwogICAgICBpZiAoIXNjYW5uZXIuYigiPCFET0NUWVBFIikpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IG5hbWUgPSB0aGlzLmUoKSAmJiB0aGlzLnIoKTsKICAgICAgaWYgKCFuYW1lKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJFeHBlY3RlZCBhIG5hbWUiKTsKICAgICAgfQogICAgICBsZXQgcHVibGljSWQ7CiAgICAgIGxldCBzeXN0ZW1JZDsKICAgICAgaWYgKHRoaXMuZSgpKSB7CiAgICAgICAgaWYgKHNjYW5uZXIuYigiUFVCTElDIikpIHsKICAgICAgICAgIHB1YmxpY0lkID0gdGhpcy5lKCkgJiYgdGhpcy5PKCk7CiAgICAgICAgICBpZiAocHVibGljSWQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHRocm93IHRoaXMuYSgiRXhwZWN0ZWQgYSBwdWJsaWMgaWRlbnRpZmllciIpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5lKCk7CiAgICAgICAgfQogICAgICAgIGlmIChwdWJsaWNJZCAhPT0gdm9pZCAwIHx8IHNjYW5uZXIuYigiU1lTVEVNIikpIHsKICAgICAgICAgIHRoaXMuZSgpOwogICAgICAgICAgc3lzdGVtSWQgPSB0aGlzLnMoKTsKICAgICAgICAgIGlmIChzeXN0ZW1JZCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgdGhpcy5hKCJFeHBlY3RlZCBhIHN5c3RlbSBpZGVudGlmaWVyIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLmUoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbGV0IGludGVybmFsU3Vic2V0OwogICAgICBpZiAoc2Nhbm5lci5iKCJbIikpIHsKICAgICAgICBpbnRlcm5hbFN1YnNldCA9IHNjYW5uZXIuQSgvXF1bXHgyMFx0XHJcbl0qPi8pOwogICAgICAgIGlmICghc2Nhbm5lci5iKCJdIikpIHsKICAgICAgICAgIHRocm93IHRoaXMuYSgiVW5jbG9zZWQgaW50ZXJuYWwgc3Vic2V0Iik7CiAgICAgICAgfQogICAgICAgIHRoaXMuZSgpOwogICAgICB9CiAgICAgIGlmICghc2Nhbm5lci5iKCI+IikpIHsKICAgICAgICB0aHJvdyB0aGlzLmEoIlVuY2xvc2VkIGRvY3R5cGUgZGVjbGFyYXRpb24iKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5mLnByZXNlcnZlRG9jdW1lbnRUeXBlID8gdGhpcy5qKG5ldyBYbWxEb2N1bWVudFR5cGUobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkLCBpbnRlcm5hbFN1YnNldCksIHN0YXJ0SW5kZXgpIDogdHJ1ZTsKICAgIH0KICAgIC8qKgogICAgICogQ29uc3VtZXMgYW4gZWxlbWVudCBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGFuIGVsZW1lbnQgd2FzIGNvbnN1bWVkLgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNOVC1lbGVtZW50CiAgICAgKi8KICAgIEIoKSB7CiAgICAgIGxldCB7IGM6IHNjYW5uZXIgfSA9IHRoaXM7CiAgICAgIGxldCBzdGFydEluZGV4ID0gc2Nhbm5lci5kOwogICAgICBpZiAoIXNjYW5uZXIuYigiPCIpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGxldCBuYW1lID0gdGhpcy5yKCk7CiAgICAgIGlmICghbmFtZSkgewogICAgICAgIHNjYW5uZXIubyhzdGFydEluZGV4KTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IGF0dHJpYnV0ZXMgPSB0aGlzLkkoKTsKICAgICAgbGV0IGlzRW1wdHkgPSAhIXNjYW5uZXIuYigiLz4iKTsKICAgICAgbGV0IGVsZW1lbnQgPSBuZXcgWG1sRWxlbWVudChuYW1lLCBhdHRyaWJ1dGVzKTsKICAgICAgZWxlbWVudC5wYXJlbnQgPSB0aGlzLmw7CiAgICAgIGlmICghaXNFbXB0eSkgewogICAgICAgIGlmICghc2Nhbm5lci5iKCI+IikpIHsKICAgICAgICAgIHRocm93IHRoaXMuYShgVW5jbG9zZWQgc3RhcnQgdGFnIGZvciBlbGVtZW50IFxgJHtuYW1lfVxgYCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubCA9IGVsZW1lbnQ7CiAgICAgICAgZG8gewogICAgICAgICAgdGhpcy5MKCk7CiAgICAgICAgfSB3aGlsZSAodGhpcy5CKCkgfHwgdGhpcy5NKCkgfHwgdGhpcy5LKCkgfHwgdGhpcy5FKCkgfHwgdGhpcy5EKCkpOwogICAgICAgIGxldCBlbmRUYWdNYXJrID0gc2Nhbm5lci5kOwogICAgICAgIGxldCBlbmRUYWdOYW1lOwogICAgICAgIGlmICghc2Nhbm5lci5iKCI8LyIpIHx8ICEoZW5kVGFnTmFtZSA9IHRoaXMucigpKSB8fCBlbmRUYWdOYW1lICE9PSBuYW1lKSB7CiAgICAgICAgICBzY2FubmVyLm8oZW5kVGFnTWFyayk7CiAgICAgICAgICB0aHJvdyB0aGlzLmEoYE1pc3NpbmcgZW5kIHRhZyBmb3IgZWxlbWVudCAke25hbWV9YCk7CiAgICAgICAgfQogICAgICAgIHRoaXMuZSgpOwogICAgICAgIGlmICghc2Nhbm5lci5iKCI+IikpIHsKICAgICAgICAgIHRocm93IHRoaXMuYShgVW5jbG9zZWQgZW5kIHRhZyBmb3IgZWxlbWVudCAke25hbWV9YCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubCA9IGVsZW1lbnQucGFyZW50OwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLmooZWxlbWVudCwgc3RhcnRJbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGFuIGBFcWAgcHJvZHVjdGlvbiBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGFuIGBFcWAgcHJvZHVjdGlvbiB3YXMgY29uc3VtZWQuCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI05ULUVxCiAgICAgKi8KICAgIHUoKSB7CiAgICAgIHRoaXMuZSgpOwogICAgICBpZiAodGhpcy5jLmIoIj0iKSkgewogICAgICAgIHRoaXMuZSgpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIC8qKgogICAgICogQ29uc3VtZXMgYE1pc2NgIGNvbnRlbnQgaWYgcG9zc2libGUuCiAgICAgKgogICAgICogQHJldHVybnMgV2hldGhlciBhbnl0aGluZyB3YXMgY29uc3VtZWQuCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI05ULU1pc2MKICAgICAqLwogICAgdygpIHsKICAgICAgcmV0dXJuIHRoaXMuRCgpIHx8IHRoaXMuRSgpIHx8IHRoaXMuZSgpOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBvbmUgb3IgbW9yZSBgTmFtZWAgY2hhcmFjdGVycyBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBgTmFtZWAgY2hhcmFjdGVycywgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG5vbmUgd2VyZSBjb25zdW1lZC4KICAgICAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMDgvUkVDLXhtbC0yMDA4MTEyNi8jTlQtTmFtZQogICAgICovCiAgICByKCkgewogICAgICByZXR1cm4gaXNOYW1lU3RhcnRDaGFyKHRoaXMuYy5oKCkpID8gdGhpcy5jLnYoaXNOYW1lQ2hhcikgOiBlbXB0eVN0cmluZzI7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB3YXMgY29uc3VtZWQuCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI3NlYy1waQogICAgICovCiAgICBFKCkgewogICAgICBsZXQgeyBjOiBzY2FubmVyIH0gPSB0aGlzOwogICAgICBsZXQgc3RhcnRJbmRleCA9IHNjYW5uZXIuZDsKICAgICAgaWYgKCFzY2FubmVyLmIoIjw/IikpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IG5hbWUgPSB0aGlzLnIoKTsKICAgICAgaWYgKG5hbWUpIHsKICAgICAgICBpZiAobmFtZS50b0xvd2VyQ2FzZSgpID09PSAieG1sIikgewogICAgICAgICAgc2Nhbm5lci5vKHN0YXJ0SW5kZXgpOwogICAgICAgICAgdGhyb3cgdGhpcy5hKCJYTUwgZGVjbGFyYXRpb24gaXNuJ3QgYWxsb3dlZCBoZXJlIik7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIHRocm93IHRoaXMuYSgiSW52YWxpZCBwcm9jZXNzaW5nIGluc3RydWN0aW9uIik7CiAgICAgIH0KICAgICAgaWYgKCF0aGlzLmUoKSkgewogICAgICAgIGlmIChzY2FubmVyLmIoIj8+IikpIHsKICAgICAgICAgIHJldHVybiB0aGlzLmoobmV3IFhtbFByb2Nlc3NpbmdJbnN0cnVjdGlvbihuYW1lKSwgc3RhcnRJbmRleCk7CiAgICAgICAgfQogICAgICAgIHRocm93IHRoaXMuYSgiV2hpdGVzcGFjZSBpcyByZXF1aXJlZCBhZnRlciBhIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbmFtZSIpOwogICAgICB9CiAgICAgIGxldCBjb250ZW50ID0gc2Nhbm5lci50KCI/PiIpOwogICAgICB0aGlzLnAoY29udGVudCk7CiAgICAgIGlmICghc2Nhbm5lci5iKCI/PiIpKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJVbnRlcm1pbmF0ZWQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiIpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLmoobmV3IFhtbFByb2Nlc3NpbmdJbnN0cnVjdGlvbihuYW1lLCBub3JtYWxpemVMaW5lQnJlYWtzKGNvbnRlbnQpKSwgc3RhcnRJbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgcHJvbG9nIGlmIHBvc3NpYmxlLgogICAgICoKICAgICAqIEByZXR1cm5zIFdoZXRoZXIgYSBwcm9sb2cgd2FzIGNvbnN1bWVkLgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNzZWMtcHJvbG9nLWR0ZAogICAgICovCiAgICBIKCkgewogICAgICBsZXQgeyBjOiBzY2FubmVyIH0gPSB0aGlzOwogICAgICBsZXQgc3RhcnRJbmRleCA9IHNjYW5uZXIuZDsKICAgICAgdGhpcy5QKCk7CiAgICAgIHdoaWxlICh0aGlzLncoKSkgewogICAgICB9CiAgICAgIGlmICh0aGlzLk4oKSkgewogICAgICAgIHdoaWxlICh0aGlzLncoKSkgewogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gc3RhcnRJbmRleCA8IHNjYW5uZXIuZDsKICAgIH0KICAgIC8qKgogICAgICogQ29uc3VtZXMgYSBwdWJsaWMgaWRlbnRpZmllciBsaXRlcmFsIGlmIHBvc3NpYmxlLgogICAgICoKICAgICAqIEByZXR1cm5zCiAgICAgKiAgIFZhbHVlIG9mIHRoZSBwdWJsaWMgaWRlbnRpZmllciBsaXRlcmFsIG1pbnVzIHF1b3Rlcywgb3IgYGZhbHNlYCBpZgogICAgICogICBub3RoaW5nIHdhcyBjb25zdW1lZC4gQW4gZW1wdHkgc3RyaW5nIGluZGljYXRlcyB0aGF0IGEgcHVibGljIGlkIGxpdGVyYWwKICAgICAqICAgd2FzIGNvbnN1bWVkIGJ1dCB3YXMgZW1wdHkuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNOVC1QdWJpZExpdGVyYWwKICAgICAqLwogICAgTygpIHsKICAgICAgbGV0IHN0YXJ0SW5kZXggPSB0aGlzLmMuZDsKICAgICAgbGV0IHZhbHVlID0gdGhpcy5zKCk7CiAgICAgIGlmICh2YWx1ZSAhPT0gZmFsc2UgJiYgIS9eWy1ceDIwXHJcbmEtekEtWjAtOScoKSssLi86PT87ISojQCRfJV0qJC8udGVzdCh2YWx1ZSkpIHsKICAgICAgICB0aGlzLmMubyhzdGFydEluZGV4KTsKICAgICAgICB0aHJvdyB0aGlzLmEoIkludmFsaWQgY2hhcmFjdGVyIGluIHB1YmxpYyBpZGVudGlmaWVyIik7CiAgICAgIH0KICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhIHJlZmVyZW5jZSBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBUaGlzIGRpZmZlcnMgZnJvbSBgY29uc3VtZUNvbnRlbnRSZWZlcmVuY2UoKWAgaW4gdGhhdCBhIGNvbnN1bWVkIHJlZmVyZW5jZQogICAgICogd2lsbCBiZSByZXR1cm5lZCByYXRoZXIgdGhhbiBhZGRlZCB0byB0aGUgZG9jdW1lbnQuCiAgICAgKgogICAgICogQHJldHVybnMKICAgICAqICAgUGFyc2VkIHJlZmVyZW5jZSB2YWx1ZSwgb3IgYGZhbHNlYCBpZiBub3RoaW5nIHdhcyBjb25zdW1lZCAodG8KICAgICAqICAgZGlzdGluZ3Vpc2ggZnJvbSBhIHJlZmVyZW5jZSB0aGF0IHJlc29sdmVzIHRvIGFuIGVtcHR5IHN0cmluZykuCiAgICAgKgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNOVC1SZWZlcmVuY2UKICAgICAqLwogICAgQygpIHsKICAgICAgbGV0IHsgYzogc2Nhbm5lciB9ID0gdGhpczsKICAgICAgaWYgKCFzY2FubmVyLmIoIiYiKSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBsZXQgcmVmID0gc2Nhbm5lci52KGlzUmVmZXJlbmNlQ2hhcik7CiAgICAgIGlmIChzY2FubmVyLkYoKSAhPT0gIjsiKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJVbnRlcm1pbmF0ZWQgcmVmZXJlbmNlIChhIHJlZmVyZW5jZSBtdXN0IGVuZCB3aXRoIGA7YCkiKTsKICAgICAgfQogICAgICBsZXQgcGFyc2VkVmFsdWU7CiAgICAgIGlmIChyZWZbMF0gPT09ICIjIikgewogICAgICAgIGxldCBjb2RlUG9pbnQgPSByZWZbMV0gPT09ICJ4IiA/IHBhcnNlSW50KHJlZi5zbGljZSgyKSwgMTYpIDogcGFyc2VJbnQocmVmLnNsaWNlKDEpLCAxMCk7CiAgICAgICAgaWYgKGlzTmFOKGNvZGVQb2ludCkpIHsKICAgICAgICAgIHRocm93IHRoaXMuYSgiSW52YWxpZCBjaGFyYWN0ZXIgcmVmZXJlbmNlIik7CiAgICAgICAgfQogICAgICAgIGlmICghaXNYbWxDb2RlUG9pbnQoY29kZVBvaW50KSkgewogICAgICAgICAgdGhyb3cgdGhpcy5hKCJDaGFyYWN0ZXIgcmVmZXJlbmNlIHJlc29sdmVzIHRvIGFuIGludmFsaWQgY2hhcmFjdGVyIik7CiAgICAgICAgfQogICAgICAgIHBhcnNlZFZhbHVlID0gU3RyaW5nLmZyb21Db2RlUG9pbnQoY29kZVBvaW50KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBwYXJzZWRWYWx1ZSA9IHByZWRlZmluZWRFbnRpdGllc1tyZWZdOwogICAgICAgIGlmIChwYXJzZWRWYWx1ZSA9PT0gdm9pZCAwKSB7CiAgICAgICAgICBsZXQgewogICAgICAgICAgICBpZ25vcmVVbmRlZmluZWRFbnRpdGllcywKICAgICAgICAgICAgcmVzb2x2ZVVuZGVmaW5lZEVudGl0eQogICAgICAgICAgfSA9IHRoaXMuZjsKICAgICAgICAgIGxldCB3cmFwcGVkUmVmID0gYCYke3JlZn07YDsKICAgICAgICAgIGlmIChyZXNvbHZlVW5kZWZpbmVkRW50aXR5KSB7CiAgICAgICAgICAgIGxldCByZXNvbHZlZFZhbHVlID0gcmVzb2x2ZVVuZGVmaW5lZEVudGl0eSh3cmFwcGVkUmVmKTsKICAgICAgICAgICAgaWYgKHJlc29sdmVkVmFsdWUgIT09IG51bGwgJiYgcmVzb2x2ZWRWYWx1ZSAhPT0gdm9pZCAwKSB7CiAgICAgICAgICAgICAgbGV0IHR5cGUgPSB0eXBlb2YgcmVzb2x2ZWRWYWx1ZTsKICAgICAgICAgICAgICBpZiAodHlwZSAhPT0gInN0cmluZyIpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFxgcmVzb2x2ZVVuZGVmaW5lZEVudGl0eSgpXGAgbXVzdCByZXR1cm4gYSBzdHJpbmcsIFxgbnVsbFxgLCBvciBcYHVuZGVmaW5lZFxgLCBidXQgcmV0dXJuZWQgYSB2YWx1ZSBvZiB0eXBlICR7dHlwZX1gKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmVkVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlmIChpZ25vcmVVbmRlZmluZWRFbnRpdGllcykgewogICAgICAgICAgICByZXR1cm4gd3JhcHBlZFJlZjsKICAgICAgICAgIH0KICAgICAgICAgIHNjYW5uZXIubygtd3JhcHBlZFJlZi5sZW5ndGgpOwogICAgICAgICAgdGhyb3cgdGhpcy5hKGBOYW1lZCBlbnRpdHkgaXNuJ3QgZGVmaW5lZDogJHt3cmFwcGVkUmVmfWApOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gcGFyc2VkVmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIENvbnN1bWVzIGEgYFN5c3RlbUxpdGVyYWxgIGlmIHBvc3NpYmxlLgogICAgICoKICAgICAqIEEgYFN5c3RlbUxpdGVyYWxgIGlzIHNpbWlsYXIgdG8gYW4gYXR0cmlidXRlIHZhbHVlLCBidXQgYWxsb3dzIHRoZQogICAgICogY2hhcmFjdGVycyBgPGAgYW5kIGAmYCBhbmQgZG9lc24ndCByZXBsYWNlIHJlZmVyZW5jZXMuCiAgICAgKgogICAgICogQHJldHVybnMKICAgICAqICAgVmFsdWUgb2YgdGhlIGBTeXN0ZW1MaXRlcmFsYCBtaW51cyBxdW90ZXMsIG9yIGBmYWxzZWAgaWYgbm90aGluZyB3YXMKICAgICAqICAgY29uc3VtZWQuIEFuIGVtcHR5IHN0cmluZyBpbmRpY2F0ZXMgdGhhdCBhIGBTeXN0ZW1MaXRlcmFsYCB3YXMgY29uc3VtZWQKICAgICAqICAgYnV0IHdhcyBlbXB0eS4KICAgICAqCiAgICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy14bWwtMjAwODExMjYvI05ULVN5c3RlbUxpdGVyYWwKICAgICAqLwogICAgcygpIHsKICAgICAgbGV0IHsgYzogc2Nhbm5lciB9ID0gdGhpczsKICAgICAgbGV0IHF1b3RlID0gc2Nhbm5lci5iKCciJykgfHwgc2Nhbm5lci5iKCInIik7CiAgICAgIGlmICghcXVvdGUpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbGV0IHZhbHVlID0gc2Nhbm5lci50KHF1b3RlKTsKICAgICAgdGhpcy5wKHZhbHVlKTsKICAgICAgaWYgKCFzY2FubmVyLmIocXVvdGUpKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJNaXNzaW5nIGVuZCBxdW90ZSIpOwogICAgICB9CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogQ29uc3VtZXMgb25lIG9yIG1vcmUgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzIGlmIHBvc3NpYmxlLgogICAgICoKICAgICAqIEByZXR1cm5zIFdoZXRoZXIgYW55IHdoaXRlc3BhY2UgY2hhcmFjdGVycyB3ZXJlIGNvbnN1bWVkLgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyN3aGl0ZQogICAgICovCiAgICBlKCkgewogICAgICByZXR1cm4gISF0aGlzLmMudihpc1doaXRlc3BhY2UpOwogICAgfQogICAgLyoqCiAgICAgKiBDb25zdW1lcyBhbiBYTUwgZGVjbGFyYXRpb24gaWYgcG9zc2libGUuCiAgICAgKgogICAgICogQHJldHVybnMgV2hldGhlciBhbiBYTUwgZGVjbGFyYXRpb24gd2FzIGNvbnN1bWVkLgogICAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwOC9SRUMteG1sLTIwMDgxMTI2LyNOVC1YTUxEZWNsCiAgICAgKi8KICAgIFAoKSB7CiAgICAgIGxldCB7IGM6IHNjYW5uZXIgfSA9IHRoaXM7CiAgICAgIGxldCBzdGFydEluZGV4ID0gc2Nhbm5lci5kOwogICAgICBpZiAoIXNjYW5uZXIuYigiPD94bWwiKSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIXRoaXMuZSgpKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJJbnZhbGlkIFhNTCBkZWNsYXJhdGlvbiIpOwogICAgICB9CiAgICAgIGxldCB2ZXJzaW9uID0gISFzY2FubmVyLmIoInZlcnNpb24iKSAmJiB0aGlzLnUoKSAmJiB0aGlzLnMoKTsKICAgICAgaWYgKHZlcnNpb24gPT09IGZhbHNlKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJYTUwgdmVyc2lvbiBpcyBtaXNzaW5nIG9yIGludmFsaWQiKTsKICAgICAgfSBlbHNlIGlmICghL14xXC5bMC05XSskLy50ZXN0KHZlcnNpb24pKSB7CiAgICAgICAgdGhyb3cgdGhpcy5hKCJJbnZhbGlkIGNoYXJhY3RlciBpbiB2ZXJzaW9uIG51bWJlciIpOwogICAgICB9CiAgICAgIGxldCBlbmNvZGluZzsKICAgICAgbGV0IHN0YW5kYWxvbmU7CiAgICAgIGlmICh0aGlzLmUoKSkgewogICAgICAgIGVuY29kaW5nID0gISFzY2FubmVyLmIoImVuY29kaW5nIikgJiYgdGhpcy51KCkgJiYgdGhpcy5zKCk7CiAgICAgICAgaWYgKGVuY29kaW5nKSB7CiAgICAgICAgICB0aGlzLmUoKTsKICAgICAgICB9CiAgICAgICAgc3RhbmRhbG9uZSA9ICEhc2Nhbm5lci5iKCJzdGFuZGFsb25lIikgJiYgdGhpcy51KCkgJiYgdGhpcy5zKCk7CiAgICAgICAgaWYgKHN0YW5kYWxvbmUpIHsKICAgICAgICAgIGlmIChzdGFuZGFsb25lICE9PSAieWVzIiAmJiBzdGFuZGFsb25lICE9PSAibm8iKSB7CiAgICAgICAgICAgIHRocm93IHRoaXMuYSgnT25seSAieWVzIiBhbmQgIm5vIiBhcmUgcGVybWl0dGVkIGFzIHZhbHVlcyBvZiBgc3RhbmRhbG9uZWAnKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMuZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoIXNjYW5uZXIuYigiPz4iKSkgewogICAgICAgIHRocm93IHRoaXMuYSgiSW52YWxpZCBvciB1bmNsb3NlZCBYTUwgZGVjbGFyYXRpb24iKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5mLnByZXNlcnZlWG1sRGVjbGFyYXRpb24gPyB0aGlzLmoobmV3IFhtbERlY2xhcmF0aW9uKAogICAgICAgIHZlcnNpb24sCiAgICAgICAgZW5jb2RpbmcgfHwgdm9pZCAwLAogICAgICAgIHN0YW5kYWxvbmUgfHwgdm9pZCAwCiAgICAgICksIHN0YXJ0SW5kZXgpIDogdHJ1ZTsKICAgIH0KICAgIC8qKgogICAgICogUmV0dXJucyBhbiBgWG1sRXJyb3JgIGZvciB0aGUgY3VycmVudCBzY2FubmVyIHBvc2l0aW9uLgogICAgICovCiAgICBhKG1lc3NhZ2UpIHsKICAgICAgbGV0IHsgYzogc2Nhbm5lciB9ID0gdGhpczsKICAgICAgcmV0dXJuIG5ldyBYbWxFcnJvcihtZXNzYWdlLCBzY2FubmVyLmQsIHNjYW5uZXIubSk7CiAgICB9CiAgICAvKioKICAgICAqIFRocm93cyBhbiBpbnZhbGlkIGNoYXJhY3RlciBlcnJvciBpZiBhbnkgY2hhcmFjdGVyIGluIHRoZSBnaXZlbiBfc3RyaW5nXwogICAgICogaXNuJ3QgYSB2YWxpZCBYTUwgY2hhcmFjdGVyLgogICAgICovCiAgICBwKHN0cmluZykgewogICAgICBsZXQgeyBsZW5ndGggfSA9IHN0cmluZzsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewogICAgICAgIGxldCBjcCA9IHN0cmluZy5jb2RlUG9pbnRBdChpKTsKICAgICAgICBpZiAoIWlzWG1sQ29kZVBvaW50KGNwKSkgewogICAgICAgICAgdGhpcy5jLm8oLShbLi4uc3RyaW5nXS5sZW5ndGggLSBpKSk7CiAgICAgICAgICB0aHJvdyB0aGlzLmEoIkludmFsaWQgY2hhcmFjdGVyIik7CiAgICAgICAgfQogICAgICAgIGlmIChjcCA+IDY1NTM1KSB7CiAgICAgICAgICBpICs9IDE7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKICBmdW5jdGlvbiBub3JtYWxpemVMaW5lQnJlYWtzKHRleHQpIHsKICAgIGxldCBpID0gMDsKICAgIHdoaWxlICgoaSA9IHRleHQuaW5kZXhPZigiXHIiLCBpKSkgIT09IC0xKSB7CiAgICAgIHRleHQgPSB0ZXh0W2kgKyAxXSA9PT0gIlxuIiA/IHRleHQuc2xpY2UoMCwgaSkgKyB0ZXh0LnNsaWNlKGkgKyAxKSA6IHRleHQuc2xpY2UoMCwgaSkgKyAiXG4iICsgdGV4dC5zbGljZShpICsgMSk7CiAgICB9CiAgICByZXR1cm4gdGV4dDsKICB9CiAgZnVuY3Rpb24gcGFyc2VYbWwoeG1sLCBvcHRpb25zKSB7CiAgICByZXR1cm4gbmV3IFBhcnNlcih4bWwsIG9wdGlvbnMpLmRvY3VtZW50OwogIH0KICBjbGFzcyBYbWxQYXJzZUVycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IobWVzc2FnZSkgewogICAgICBzdXBlcihtZXNzYWdlKTsKICAgIH0KICB9CiAgZnVuY3Rpb24gcGFyc2VYbWxTdHJpbmcoeG1sU3RyaW5nKSB7CiAgICBsZXQgZG9jID0gbnVsbDsKICAgIHRyeSB7CiAgICAgIGRvYyA9IGJyb3dzZXIucGFyc2VYbWwoeG1sU3RyaW5nKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgdGhyb3cgbmV3IFhtbFBhcnNlRXJyb3IoZS5tZXNzYWdlKTsKICAgIH0KICAgIHJldHVybiBkb2M7CiAgfQogIGZ1bmN0aW9uIHN0cmlwTmFtZXNwYWNlKG5hbWUpIHsKICAgIGNvbnN0IGNvbG9uID0gbmFtZS5pbmRleE9mKCI6Iik7CiAgICByZXR1cm4gY29sb24gPiAtMSA/IG5hbWUuc3Vic3RyKGNvbG9uICsgMSkgOiBuYW1lOwogIH0KICBmdW5jdGlvbiBnZXRSb290RWxlbWVudCh4bWxEb2MpIHsKICAgIHJldHVybiB4bWxEb2MuY2hpbGRyZW5bMF07CiAgfQogIGZ1bmN0aW9uIGdldEVsZW1lbnROYW1lKGVsZW1lbnQpIHsKICAgIHJldHVybiBlbGVtZW50Lm5hbWUgfHwgIiI7CiAgfQogIGZ1bmN0aW9uIGZpbmRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCwgbmFtZSwgbmVzdGVkID0gZmFsc2UpIHsKICAgIGNvbnN0IHN0cmlwcGVkTmFtZSA9IHN0cmlwTmFtZXNwYWNlKG5hbWUpOwogICAgZnVuY3Rpb24gcmVkdWNlcihwcmV2LCBjdXJyKSB7CiAgICAgIGlmIChzdHJpcE5hbWVzcGFjZShnZXRFbGVtZW50TmFtZShjdXJyKSkgPT09IHN0cmlwcGVkTmFtZSkgewogICAgICAgIHByZXYucHVzaChjdXJyKTsKICAgICAgfQogICAgICBpZiAobmVzdGVkICYmIEFycmF5LmlzQXJyYXkoY3Vyci5jaGlsZHJlbikpIHsKICAgICAgICByZXR1cm4gWy4uLnByZXYsIC4uLmN1cnIuY2hpbGRyZW4ucmVkdWNlKHJlZHVjZXIsIFtdKV07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHByZXY7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBlbGVtZW50ICYmIEFycmF5LmlzQXJyYXkoZWxlbWVudC5jaGlsZHJlbikgPyBlbGVtZW50LmNoaWxkcmVuLnJlZHVjZShyZWR1Y2VyLCBbXSkgOiBbXTsKICB9CiAgZnVuY3Rpb24gZmluZENoaWxkRWxlbWVudChlbGVtZW50LCBuYW1lLCBuZXN0ZWQgPSBmYWxzZSkgewogICAgcmV0dXJuIGZpbmRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCwgbmFtZSwgbmVzdGVkKVswXSB8fCBudWxsOwogIH0KICBmdW5jdGlvbiBnZXRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCkgewogICAgcmV0dXJuIGVsZW1lbnQgJiYgQXJyYXkuaXNBcnJheShlbGVtZW50LmNoaWxkcmVuKSA/IFsKICAgICAgLi4uZWxlbWVudC5jaGlsZHJlbi5maWx0ZXIoCiAgICAgICAgKGVsKSA9PiBlbCBpbnN0YW5jZW9mIGJyb3dzZXIuWG1sRWxlbWVudAogICAgICApCiAgICBdIDogW107CiAgfQogIGZ1bmN0aW9uIGdldEVsZW1lbnRUZXh0KGVsZW1lbnQpIHsKICAgIGNvbnN0IHRleHROb2RlID0gZWxlbWVudCAmJiBBcnJheS5pc0FycmF5KGVsZW1lbnQuY2hpbGRyZW4pID8gZWxlbWVudC5jaGlsZHJlbi5maW5kKChub2RlKSA9PiBub2RlLnR5cGUgPT09ICJ0ZXh0IikgOiBudWxsOwogICAgcmV0dXJuIHRleHROb2RlID8gdGV4dE5vZGUudGV4dCA6ICIiOwogIH0KICBmdW5jdGlvbiBnZXRFbGVtZW50QXR0cmlidXRlKGVsZW1lbnQsIGF0dHJOYW1lKSB7CiAgICByZXR1cm4gZWxlbWVudCAmJiBlbGVtZW50LmF0dHJpYnV0ZXNbYXR0ck5hbWVdIHx8ICIiOwogIH0KICBjbGFzcyBFbmRwb2ludEVycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IobWVzc2FnZSwgaHR0cFN0YXR1cywgaXNDcm9zc09yaWdpblJlbGF0ZWQpIHsKICAgICAgc3VwZXIobWVzc2FnZSk7CiAgICAgIHRoaXMuaHR0cFN0YXR1cyA9IGh0dHBTdGF0dXM7CiAgICAgIHRoaXMuaXNDcm9zc09yaWdpblJlbGF0ZWQgPSBpc0Nyb3NzT3JpZ2luUmVsYXRlZDsKICAgICAgdGhpcy5uYW1lID0gIkVuZHBvaW50RXJyb3IiOwogICAgfQogIH0KICBjbGFzcyBTZXJ2aWNlRXhjZXB0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0gbWVzc2FnZSBFcnJvciBtZXNzYWdlCiAgICAgKiBAcGFyYW0gcmVxdWVzdFVybCBVUkwgd2hpY2ggcmVzdWx0ZWQgaW4gdGhlIFNlcnZpY2VFeGNlcHRpb24KICAgICAqIEBwYXJhbSBjb2RlIE9wdGlvbmFsIFNlcnZpY2VFeGNlcHRpb24gY29kZQogICAgICogQHBhcmFtIGxvY2F0b3IgT3B0aW9uYWwgU2VydmljZUV4Y2VwdGlvbiBsb2NhdG9yCiAgICAgKiBAcGFyYW0gcmVzcG9uc2UgT3B0aW9uYWwgcmVzcG9uc2UgY29udGVudCByZWNlaXZlZAogICAgICovCiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlLCByZXF1ZXN0VXJsLCBjb2RlLCBsb2NhdG9yLCByZXNwb25zZSkgewogICAgICBzdXBlcihtZXNzYWdlKTsKICAgICAgdGhpcy5yZXF1ZXN0VXJsID0gcmVxdWVzdFVybDsKICAgICAgdGhpcy5jb2RlID0gY29kZTsKICAgICAgdGhpcy5sb2NhdG9yID0gbG9jYXRvcjsKICAgICAgdGhpcy5yZXNwb25zZSA9IHJlc3BvbnNlOwogICAgICB0aGlzLm5hbWUgPSAiU2VydmljZUV4Y2VwdGlvbkVycm9yIjsKICAgIH0KICB9CiAgZnVuY3Rpb24gcGFyc2Uoc2VydmljZUV4Y2VwdGlvbiwgdXJsKSB7CiAgICBjb25zdCBlcnJvckNvZGUgPSBnZXRFbGVtZW50QXR0cmlidXRlKHNlcnZpY2VFeGNlcHRpb24sICJjb2RlIikgfHwgZ2V0RWxlbWVudEF0dHJpYnV0ZShzZXJ2aWNlRXhjZXB0aW9uLCAiZXhjZXB0aW9uQ29kZSIpOwogICAgY29uc3QgZXJyb3JMb2NhdG9yID0gZ2V0RWxlbWVudEF0dHJpYnV0ZShzZXJ2aWNlRXhjZXB0aW9uLCAibG9jYXRvciIpOwogICAgY29uc3QgdGV4dEVsZW1lbnQgPSBmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2VFeGNlcHRpb24sICJFeGNlcHRpb25UZXh0IikgfHwgc2VydmljZUV4Y2VwdGlvbjsKICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGdldEVsZW1lbnRUZXh0KHRleHRFbGVtZW50KS50cmltKCk7CiAgICByZXR1cm4gbmV3IFNlcnZpY2VFeGNlcHRpb25FcnJvcigKICAgICAgZXJyb3JNZXNzYWdlLAogICAgICB1cmwsCiAgICAgIGVycm9yQ29kZSwKICAgICAgZXJyb3JMb2NhdG9yLAogICAgICBzZXJ2aWNlRXhjZXB0aW9uLmRvY3VtZW50CiAgICApOwogIH0KICBmdW5jdGlvbiBjaGVjayhyZXNwb25zZSwgdXJsKSB7CiAgICBjb25zdCByb290RWwgPSBnZXRSb290RWxlbWVudChyZXNwb25zZSk7CiAgICBjb25zdCByb290RWxOYW1lID0gc3RyaXBOYW1lc3BhY2UoZ2V0RWxlbWVudE5hbWUocm9vdEVsKSk7CiAgICBpZiAocm9vdEVsTmFtZSA9PT0gIlNlcnZpY2VFeGNlcHRpb25SZXBvcnQiKSB7CiAgICAgIGNvbnN0IGVycm9yID0gZmluZENoaWxkRWxlbWVudChyb290RWwsICJTZXJ2aWNlRXhjZXB0aW9uIik7CiAgICAgIGlmIChlcnJvcikgewogICAgICAgIHRocm93IHBhcnNlKGVycm9yLCB1cmwpOwogICAgICB9CiAgICB9CiAgICBpZiAocm9vdEVsTmFtZSA9PT0gIkV4Y2VwdGlvblJlcG9ydCIpIHsKICAgICAgY29uc3QgZXJyb3IgPSBmaW5kQ2hpbGRFbGVtZW50KHJvb3RFbCwgIkV4Y2VwdGlvbiIpOwogICAgICBpZiAoZXJyb3IpIHsKICAgICAgICB0aHJvdyBwYXJzZShlcnJvciwgdXJsKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlc3BvbnNlOwogIH0KICBmdW5jdGlvbiBlbmNvZGVFcnJvcihlcnJvcikgewogICAgY29uc3QgYmFzZSA9IHsKICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZSwKICAgICAgc3RhY2s6IGVycm9yLnN0YWNrLAogICAgICBuYW1lOiBlcnJvci5uYW1lCiAgICB9OwogICAgaWYgKGVycm9yIGluc3RhbmNlb2YgU2VydmljZUV4Y2VwdGlvbkVycm9yKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgLi4uYmFzZSwKICAgICAgICBjb2RlOiBlcnJvci5jb2RlLAogICAgICAgIGxvY2F0b3I6IGVycm9yLmxvY2F0b3IsCiAgICAgICAgcmVzcG9uc2U6IGVycm9yLnJlc3BvbnNlLAogICAgICAgIHJlcXVlc3RVcmw6IGVycm9yLnJlcXVlc3RVcmwKICAgICAgfTsKICAgIH0KICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVuZHBvaW50RXJyb3IpIHsKICAgICAgcmV0dXJuIHsKICAgICAgICAuLi5iYXNlLAogICAgICAgIGh0dHBTdGF0dXM6IGVycm9yLmh0dHBTdGF0dXMsCiAgICAgICAgaXNDcm9zc09yaWdpblJlbGF0ZWQ6IGVycm9yLmlzQ3Jvc3NPcmlnaW5SZWxhdGVkCiAgICAgIH07CiAgICB9CiAgICByZXR1cm4gYmFzZTsKICB9CiAgY29uc3QgZmFsbGJhY2tFdmVudFRhcmdldCA9IG5ldyBFdmVudFRhcmdldCgpOwogIGZ1bmN0aW9uIGFkZFRhc2tIYW5kbGVyKHRhc2tOYW1lLCBzY29wZSwgaGFuZGxlcikgewogICAgY29uc3QgdXNlV29ya2VyID0gdHlwZW9mIFdvcmtlckdsb2JhbFNjb3BlICE9PSAidW5kZWZpbmVkIjsKICAgIGNvbnN0IGV2ZW50SGFuZGxlciA9IGFzeW5jIChyZXF1ZXN0KSA9PiB7CiAgICAgIGlmIChyZXF1ZXN0LnRhc2tOYW1lID09PSB0YXNrTmFtZSkgewogICAgICAgIGxldCByZXNwb25zZSwgZXJyb3I7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgaGFuZGxlcihyZXF1ZXN0LnBhcmFtcyk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgZXJyb3IgPSBlbmNvZGVFcnJvcihlKTsKICAgICAgICB9CiAgICAgICAgY29uc3QgbWVzc2FnZSA9ICgKICAgICAgICAgIC8qKiBAdHlwZSB7V29ya2VyUmVzcG9uc2V9ICovCiAgICAgICAgICB7CiAgICAgICAgICAgIHRhc2tOYW1lLAogICAgICAgICAgICByZXF1ZXN0SWQ6IHJlcXVlc3QucmVxdWVzdElkLAogICAgICAgICAgICAuLi5yZXNwb25zZSAmJiB7IHJlc3BvbnNlIH0sCiAgICAgICAgICAgIC4uLmVycm9yICYmIHsgZXJyb3IgfQogICAgICAgICAgfQogICAgICAgICk7CiAgICAgICAgaWYgKHVzZVdvcmtlcikgewogICAgICAgICAgc2NvcGUucG9zdE1lc3NhZ2UobWVzc2FnZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZhbGxiYWNrRXZlbnRUYXJnZXQuZGlzcGF0Y2hFdmVudCgKICAgICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KCJvZ2MtY2xpZW50LnJlc3BvbnNlIiwgewogICAgICAgICAgICAgIGRldGFpbDogbWVzc2FnZQogICAgICAgICAgICB9KQogICAgICAgICAgKTsKICAgICAgICB9CiAgICAgIH0KICAgIH07CiAgICBpZiAodXNlV29ya2VyKSB7CiAgICAgIHNjb3BlLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCAoZXZlbnQpID0+IGV2ZW50SGFuZGxlcihldmVudC5kYXRhKSk7CiAgICB9IGVsc2UgewogICAgICBmYWxsYmFja0V2ZW50VGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoCiAgICAgICAgIm9nYy1jbGllbnQucmVxdWVzdCIsCiAgICAgICAgKGV2ZW50KSA9PiBldmVudEhhbmRsZXIoZXZlbnQuZGV0YWlsKQogICAgICApOwogICAgfQogIH0KICBjb25zdCBFTkNPRElOR1MgPSBbInV0Zi04IiwgInV0Zi0xNiIsICJpc28tODg1OS0xIl07CiAgY29uc3QgRkFMTEJBQ0tfRU5DT0RJTkcgPSAidXRmLTgiOwogIGZ1bmN0aW9uIGV4dHJhY3RFbmNvZGluZyhjb250ZW50VHlwZSkgewogICAgY29uc3QgbWF0Y2hlcyA9IC9jaGFyc2V0PShbXjtdKykvLmV4ZWMoY29udGVudFR5cGUpOwogICAgcmV0dXJuIG1hdGNoZXMgPyBtYXRjaGVzWzFdIDogbnVsbDsKICB9CiAgZnVuY3Rpb24gZGVjb2RlU3RyaW5nKGJ1ZmZlciwgY29udGVudFR5cGUpIHsKICAgIGNvbnN0IGVuY29kaW5nSGludCA9IGNvbnRlbnRUeXBlID8gZXh0cmFjdEVuY29kaW5nKGNvbnRlbnRUeXBlKSA6IG51bGw7CiAgICBjb25zdCBlbmNvZGluZ0F0dGVtcHRzID0gZW5jb2RpbmdIaW50ID8gW2VuY29kaW5nSGludCwgLi4uRU5DT0RJTkdTXSA6IEVOQ09ESU5HUzsKICAgIGZvciAoY29uc3QgZW5jb2Rpbmcgb2YgZW5jb2RpbmdBdHRlbXB0cykgewogICAgICB0cnkgewogICAgICAgIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoZW5jb2RpbmcsIHsgZmF0YWw6IHRydWUgfSk7CiAgICAgICAgcmV0dXJuIGRlY29kZXIuZGVjb2RlKGJ1ZmZlcik7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgfQogICAgfQogICAgY29uc29sZS53YXJuKAogICAgICBgW29nYy1jbGllbnRdIFhNTCBkb2N1bWVudCBlbmNvZGluZyBjb3VsZCBub3QgYmUgZGV0ZXJtaW5lZCwgZmFsbGluZyBiYWNrIHRvICR7RkFMTEJBQ0tfRU5DT0RJTkd9LmAKICAgICk7CiAgICByZXR1cm4gbmV3IFRleHREZWNvZGVyKEZBTExCQUNLX0VOQ09ESU5HKS5kZWNvZGUoYnVmZmVyKTsKICB9CiAgY29uc3QgZmV0Y2hQcm9taXNlcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgbGV0IGZldGNoT3B0aW9ucyA9IHt9OwogIGZ1bmN0aW9uIHNldEZldGNoT3B0aW9ucyhvcHRpb25zKSB7CiAgICBmZXRjaE9wdGlvbnMgPSBvcHRpb25zOwogIH0KICBmdW5jdGlvbiBnZXRGZXRjaE9wdGlvbnMoKSB7CiAgICByZXR1cm4gZmV0Y2hPcHRpb25zOwogIH0KICBmdW5jdGlvbiBzaGFyZWRGZXRjaCh1cmwsIG1ldGhvZCA9ICJHRVQiLCBhc0pzb24pIHsKICAgIGxldCBmZXRjaEtleSA9IGAke21ldGhvZH0jJHt1cmx9YDsKICAgIGlmIChhc0pzb24pIHsKICAgICAgZmV0Y2hLZXkgPSBgJHttZXRob2R9I2FzSnNvbiMke3VybH1gOwogICAgfQogICAgaWYgKGZldGNoUHJvbWlzZXMuaGFzKGZldGNoS2V5KSkgewogICAgICByZXR1cm4gZmV0Y2hQcm9taXNlcy5nZXQoZmV0Y2hLZXkpOwogICAgfQogICAgY29uc3Qgb3B0aW9ucyA9IHsgLi4uZ2V0RmV0Y2hPcHRpb25zKCkgfTsKICAgIG9wdGlvbnMubWV0aG9kID0gbWV0aG9kOwogICAgaWYgKGFzSnNvbikgewogICAgICBvcHRpb25zLmhlYWRlcnMgPSAiaGVhZGVycyIgaW4gb3B0aW9ucyA/IG9wdGlvbnMuaGVhZGVycyA6IHt9OwogICAgICBvcHRpb25zLmhlYWRlcnNbIkFjY2VwdCJdID0gImFwcGxpY2F0aW9uL2pzb24sYXBwbGljYXRpb24vc2NoZW1hK2pzb24iOwogICAgfQogICAgY29uc3QgcHJvbWlzZSA9IGZldGNoKHVybCwgb3B0aW9ucykuY2F0Y2goKGUpID0+IGUpLnRoZW4oKHJlc3ApID0+IHsKICAgICAgZmV0Y2hQcm9taXNlcy5kZWxldGUoZmV0Y2hLZXkpOwogICAgICByZXR1cm4gcmVzcDsKICAgIH0pOwogICAgZmV0Y2hQcm9taXNlcy5zZXQoZmV0Y2hLZXksIHByb21pc2UpOwogICAgcmV0dXJuIHByb21pc2UudGhlbigocmVzcCkgPT4gewogICAgICBpZiAocmVzcCBpbnN0YW5jZW9mIEVycm9yKQogICAgICAgIHRocm93IHJlc3A7CiAgICAgIHJldHVybiByZXNwLmNsb25lKCk7CiAgICB9KTsKICB9CiAgZnVuY3Rpb24gcXVlcnlYbWxEb2N1bWVudCh1cmwpIHsKICAgIHJldHVybiBzaGFyZWRGZXRjaCh1cmwpLmNhdGNoKAogICAgICAoKSA9PiAoCiAgICAgICAgLy8gYXR0ZW1wdCBhIEhFQUQgdG8gc2VlIGlmIHRoZSBmYWlsdXJlIGNvbWVzIGZyb20gQ09SUyBvciB0aGUgc2VydmljZSBpcyBnZW5lcmFsbHkgdW5yZWFjaGFibGUKICAgICAgICBmZXRjaCh1cmwsIHsgLi4uZ2V0RmV0Y2hPcHRpb25zKCksIG1ldGhvZDogIkhFQUQiLCBtb2RlOiAibm8tY29ycyIgfSkuY2F0Y2goKGVycm9yKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRW5kcG9pbnRFcnJvcigKICAgICAgICAgICAgYEZldGNoaW5nIHRoZSBkb2N1bWVudCBmYWlsZWQgZWl0aGVyIGR1ZSB0byBuZXR3b3JrIGVycm9ycyBvciB1bnJlYWNoYWJsZSBob3N0LCBlcnJvciBpczogJHtlcnJvci5tZXNzYWdlfWAsCiAgICAgICAgICAgIDAsCiAgICAgICAgICAgIGZhbHNlCiAgICAgICAgICApOwogICAgICAgIH0pLnRoZW4oKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVuZHBvaW50RXJyb3IoCiAgICAgICAgICAgIGBUaGUgZG9jdW1lbnQgY291bGQgbm90IGJlIGZldGNoZWQgZHVlIHRvIENPUlMgbGltaXRhdGlvbnNgLAogICAgICAgICAgICAwLAogICAgICAgICAgICB0cnVlCiAgICAgICAgICApOwogICAgICAgIH0pCiAgICAgICkKICAgICkudGhlbihhc3luYyAocmVzcCkgPT4gewogICAgICBpZiAoIXJlc3Aub2spIHsKICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVzcC50ZXh0KCk7CiAgICAgICAgdGhyb3cgbmV3IEVuZHBvaW50RXJyb3IoCiAgICAgICAgICBgUmVjZWl2ZWQgYW4gZXJyb3Igd2l0aCBjb2RlICR7cmVzcC5zdGF0dXN9OiAke3RleHR9YCwKICAgICAgICAgIHJlc3Auc3RhdHVzLAogICAgICAgICAgZmFsc2UKICAgICAgICApOwogICAgICB9CiAgICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IHJlc3AuYXJyYXlCdWZmZXIoKTsKICAgICAgY29uc3QgY29udGVudFR5cGVIZWFkZXIgPSByZXNwLmhlYWRlcnMuZ2V0KCJDb250ZW50LVR5cGUiKTsKICAgICAgcmV0dXJuIGRlY29kZVN0cmluZyhidWZmZXIsIGNvbnRlbnRUeXBlSGVhZGVyKTsKICAgIH0pLnRoZW4oKHhtbCkgPT4gcGFyc2VYbWxTdHJpbmcoeG1sKSk7CiAgfQogIGZ1bmN0aW9uIHNldFF1ZXJ5UGFyYW1zKHVybCwgcGFyYW1zKSB7CiAgICBjb25zdCBlbmNvZGVkVXJsTWF0Y2ggPSB1cmwubWF0Y2goLyhodHRwcz8lM0ElMkYlMkZbXi9dKykkLyk7CiAgICBpZiAoZW5jb2RlZFVybE1hdGNoKSB7CiAgICAgIGNvbnN0IGVuY29kZWRVcmwgPSBlbmNvZGVkVXJsTWF0Y2hbMV07CiAgICAgIGNvbnN0IG1vZGlmaWVkVXJsID0gc2V0UXVlcnlQYXJhbXMoZGVjb2RlVVJJQ29tcG9uZW50KGVuY29kZWRVcmwpLCBwYXJhbXMpOwogICAgICByZXR1cm4gdXJsLnJlcGxhY2UoZW5jb2RlZFVybCwgZW5jb2RlVVJJQ29tcG9uZW50KG1vZGlmaWVkVXJsKSk7CiAgICB9CiAgICBjb25zdCB1cmxPYmogPSBuZXcgVVJMKHVybCk7CiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMocGFyYW1zKTsKICAgIGNvbnN0IGtleXNMb3dlciA9IGtleXMubWFwKChrZXkpID0+IGtleS50b0xvd2VyQ2FzZSgpKTsKICAgIGNvbnN0IHRvRGVsZXRlID0gW107CiAgICBmb3IgKGNvbnN0IHBhcmFtIG9mIHVybE9iai5zZWFyY2hQYXJhbXMua2V5cygpKSB7CiAgICAgIGlmIChrZXlzTG93ZXIuaW5kZXhPZihwYXJhbS50b0xvd2VyQ2FzZSgpKSA+IC0xKSB7CiAgICAgICAgdG9EZWxldGUucHVzaChwYXJhbSk7CiAgICAgIH0KICAgIH0KICAgIHRvRGVsZXRlLm1hcCgocGFyYW0pID0+IHVybE9iai5zZWFyY2hQYXJhbXMuZGVsZXRlKHBhcmFtKSk7CiAgICBrZXlzLmZvckVhY2goCiAgICAgIChrZXkpID0+IHVybE9iai5zZWFyY2hQYXJhbXMuc2V0KAogICAgICAgIGtleSwKICAgICAgICBwYXJhbXNba2V5XSA9PT0gdHJ1ZSA/ICIiIDogcGFyYW1zW2tleV0KICAgICAgKQogICAgKTsKICAgIHJldHVybiB1cmxPYmoudG9TdHJpbmcoKTsKICB9CiAgY29uc3QgTGF0TG9uQ3JzTGlzdCA9IFsKICAgICJFUFNHOjQwNDYiLAogICAgLy8gUkdSREMgMjAwNQogICAgIkVQU0c6NDA3NSIsCiAgICAvLyBTUkVGOTgKICAgICJFUFNHOjQxMjAiLAogICAgLy8gR3JlZWsKICAgICJFUFNHOjQxMjIiLAogICAgLy8gQVRTNzcKICAgICJFUFNHOjQxMjQiLAogICAgLy8gUlQ5MAogICAgIkVQU0c6NDEyNiIsCiAgICAvLyBMS1M5NCAoRVRSUzg5KQogICAgIkVQU0c6NDE0OSIsCiAgICAvLyBDSDE5MDMKICAgICJFUFNHOjQxNTEiLAogICAgLy8gQ0hUUkY5NQogICAgIkVQU0c6NDE1MyIsCiAgICAvLyBSYXNzYWRpcmFuCiAgICAiRVBTRzo0MTU1IiwKICAgIC8vIERhYm9sYSAxOTgxCiAgICAiRVBTRzo0MTU3IiwKICAgIC8vIE1vdW50IERpbGxvbgogICAgIkVQU0c6NDE1OSIsCiAgICAvLyBFTEQ3OQogICAgIkVQU0c6NDE2MSIsCiAgICAvLyBQYW1wYSBkZWwgQ2FzdGlsbG8KICAgICJFUFNHOjQxNjMiLAogICAgLy8gWWVtZW4gTkdOOTYKICAgICJFUFNHOjQxNjUiLAogICAgLy8gQmlzc2F1CiAgICAiRVBTRzo0MTY3IiwKICAgIC8vIE5aR0QyMDAwCiAgICAiRVBTRzo0MTY5IiwKICAgIC8vIEFtZXJpY2FuIFNhbW9hIDE5NjIKICAgICJFUFNHOjQxNzEiLAogICAgLy8gUkdGOTMKICAgICJFUFNHOjQxNzMiLAogICAgLy8gSVJFTkVUOTUKICAgICJFUFNHOjQxNzUiLAogICAgLy8gU2llcnJhIExlb25lIDE5NjgKICAgICJFUFNHOjQxNzgiLAogICAgLy8gUHVsa292byAxOTQyKDgzKQogICAgIkVQU0c6NDE4MCIsCiAgICAvLyBFU1Q5NwogICAgIkVQU0c6NDE4MiIsCiAgICAvLyBBem9yZXMgT2NjaWRlbnRhbCAxOTM5CiAgICAiRVBTRzo0MTg0IiwKICAgIC8vIEF6b3JlcyBPcmllbnRhbCAxOTQwCiAgICAiRVBTRzo0MTg4IiwKICAgIC8vIE9TTkkgMTk1MgogICAgIkVQU0c6NDE5MCIsCiAgICAvLyBQT1NHQVIgOTgKICAgICJFUFNHOjQxOTEiLAogICAgLy8gQWxiYW5pYW4gMTk4NwogICAgIkVQU0c6NDE5NiIsCiAgICAvLyBBbW1hc3NhbGlrIDE5NTgKICAgICJFUFNHOjQxOTgiLAogICAgLy8gS291c3NlcmkKICAgICJFUFNHOjQyMDIiLAogICAgLy8gQUdENjYKICAgICJFUFNHOjQyMTAiLAogICAgLy8gQXJjIDE5NjAKICAgICJFUFNHOjQyMTEiLAogICAgLy8gQmF0YXZpYQogICAgIkVQU0c6NDIxNCIsCiAgICAvLyBCZWlqaW5nIDE5NTQKICAgICJFUFNHOjQyMjYiLAogICAgLy8gQ290ZSBkJ0l2b2lyZQogICAgIkVQU0c6NDIyOSIsCiAgICAvLyBFZ3lwdCAxOTA3CiAgICAiRVBTRzo0MjMxIiwKICAgIC8vIEVEODcKICAgICJFUFNHOjQyMzMiLAogICAgLy8gR2FuZGFqaWthIDE5NzAKICAgICJFUFNHOjQyMzYiLAogICAgLy8gSHUgVHp1IFNoYW4gMTk1MAogICAgIkVQU0c6NDIzOCIsCiAgICAvLyBJRDc0CiAgICAiRVBTRzo0MjQwIiwKICAgIC8vIEluZGlhbiAxOTc1CiAgICAiRVBTRzo0MjQyIiwKICAgIC8vIEpBRDY5CiAgICAiRVBTRzo0MjQ0IiwKICAgIC8vIEthbmRhd2FsYQogICAgIkVQU0c6NDI0NiIsCiAgICAvLyBLT0MKICAgICJFUFNHOjQyNDgiLAogICAgLy8gUFNBRDU2CiAgICAiRVBTRzo0MjUwIiwKICAgIC8vIExlaWdvbgogICAgIkVQU0c6NDI1MiIsCiAgICAvLyBMb21lCiAgICAiRVBTRzo0MjU1IiwKICAgIC8vIEhlcmF0IE5vcnRoCiAgICAiRVBTRzo0MjU4IiwKICAgIC8vIEVUUlM4OQogICAgIkVQU0c6NDI2MSIsCiAgICAvLyBNZXJjaGljaAogICAgIkVQU0c6NDI2NCIsCiAgICAvLyBNaGFzdAogICAgIkVQU0c6NDI2NyIsCiAgICAvLyBOQUQyNwogICAgIkVQU0c6NDI3MCIsCiAgICAvLyBOYWhyd2FuIDE5NjcKICAgICJFUFNHOjQyNzMiLAogICAgLy8gTkdPIDE5NDgKICAgICJFUFNHOjQyNzYiLAogICAgLy8gTlNXQyA5Wi0yCiAgICAiRVBTRzo0Mjc5IiwKICAgIC8vIE9TKFNOKTgwCiAgICAiRVBTRzo0MjgxIiwKICAgIC8vIFBhbGVzdGluZSAxOTIzCiAgICAiRVBTRzo0Mjg0IiwKICAgIC8vIFB1bGtvdm8gMTk0MgogICAgIkVQU0c6NDI4NiIsCiAgICAvLyBRYXRhciAxOTQ4CiAgICAiRVBTRzo0Mjg4IiwKICAgIC8vIExvbWEgUXVpbnRhbmEKICAgICJFUFNHOjQyOTIiLAogICAgLy8gU2FwcGVyIEhpbGwgMTk0MwogICAgIkVQU0c6NDI5NSIsCiAgICAvLyBTZXJpbmR1bmcKICAgICJFUFNHOjQyOTciLAogICAgLy8gVGFuYW5hcml2ZQogICAgIkVQU0c6NDI5OSIsCiAgICAvLyBUTTY1CiAgICAiRVBTRzo0MzAyIiwKICAgIC8vIFRyaW5pZGFkIDE5MDMKICAgICJFUFNHOjQzMjQiLAogICAgLy8gV0dTIDcyQkUKICAgICJFUFNHOjQzMjYiCiAgICAvLyBXR1MgODQKICBdOwogIGZ1bmN0aW9uIGhhc0ludmVydGVkQ29vcmRpbmF0ZXMoY3JzTmFtZSkgewogICAgcmV0dXJuIExhdExvbkNyc0xpc3QuaW5kZXhPZihzaW1wbGlmeUVwc2dVcm4oY3JzTmFtZSkpID4gLTE7CiAgfQogIGZ1bmN0aW9uIHNpbXBsaWZ5RXBzZ1VybihmdWxsQ3JzTmFtZSkgewogICAgaWYgKC9edXJuOig/OngtKT9vZ2M6ZGVmOmNyczplcHNnOi8udGVzdChmdWxsQ3JzTmFtZS50b0xvd2VyQ2FzZSgpKSkgewogICAgICBjb25zdCBjb2RlID0gLyhbMC05XSspJC8uZXhlYyhmdWxsQ3JzTmFtZSlbMV07CiAgICAgIHJldHVybiBgRVBTRzoke2NvZGV9YDsKICAgIH0KICAgIHJldHVybiBmdWxsQ3JzTmFtZTsKICB9CiAgZnVuY3Rpb24gcmVhZE9wZXJhdGlvblVybHNGcm9tQ2FwYWJpbGl0aWVzJDEoY2FwYWJpbGl0aWVzRG9jKSB7CiAgICBjb25zdCB1cmxzID0ge307CiAgICBjb25zdCBjYXBhYmlsaXR5ID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwKICAgICAgIkNhcGFiaWxpdHkiCiAgICApOwogICAgY29uc3QgcmVxdWVzdCA9IGZpbmRDaGlsZEVsZW1lbnQoY2FwYWJpbGl0eSwgIlJlcXVlc3QiKTsKICAgIGdldENoaWxkcmVuRWxlbWVudChyZXF1ZXN0KS5mb3JFYWNoKChvcGVyYXRpb24pID0+IHsKICAgICAgY29uc3Qgb3BlcmF0aW9uTmFtZSA9IHN0cmlwTmFtZXNwYWNlKGdldEVsZW1lbnROYW1lKG9wZXJhdGlvbikpOwogICAgICB1cmxzW29wZXJhdGlvbk5hbWVdID0gcGFyc2VPcGVyYXRpb24ob3BlcmF0aW9uKTsKICAgIH0pOwogICAgcmV0dXJuIHVybHM7CiAgfQogIGZ1bmN0aW9uIHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyQxKGNhcGFiaWxpdGllc0RvYykgewogICAgcmV0dXJuIGdldFJvb3RFbGVtZW50KGNhcGFiaWxpdGllc0RvYykuYXR0cmlidXRlc1sidmVyc2lvbiJdOwogIH0KICBmdW5jdGlvbiByZWFkTGF5ZXJzRnJvbUNhcGFiaWxpdGllcyQxKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3QgdmVyc2lvbiA9IHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyQxKGNhcGFiaWxpdGllc0RvYyk7CiAgICBjb25zdCBjYXBhYmlsaXR5ID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwKICAgICAgIkNhcGFiaWxpdHkiCiAgICApOwogICAgcmV0dXJuIGZpbmRDaGlsZHJlbkVsZW1lbnQoY2FwYWJpbGl0eSwgIkxheWVyIikubWFwKAogICAgICAobGF5ZXJFbCkgPT4gcGFyc2VMYXllcihsYXllckVsLCB2ZXJzaW9uKQogICAgKTsKICB9CiAgZnVuY3Rpb24gcmVhZE91dHB1dEZvcm1hdHNGcm9tQ2FwYWJpbGl0aWVzJDEoY2FwYWJpbGl0aWVzRG9jKSB7CiAgICBjb25zdCBjYXBhYmlsaXR5ID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwKICAgICAgIkNhcGFiaWxpdHkiCiAgICApOwogICAgY29uc3QgZ2V0TWFwID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgZmluZENoaWxkRWxlbWVudChjYXBhYmlsaXR5LCAiUmVxdWVzdCIpLAogICAgICAiR2V0TWFwIgogICAgKTsKICAgIGNvbnN0IG91dHB1dEZvcm1hdHMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGdldE1hcCwgIkZvcm1hdCIpLm1hcCgKICAgICAgZ2V0RWxlbWVudFRleHQKICAgICk7CiAgICByZXR1cm4gb3V0cHV0Rm9ybWF0czsKICB9CiAgZnVuY3Rpb24gcmVhZEluZm9Gb3JtYXRzRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpIHsKICAgIGNvbnN0IGNhcGFiaWxpdHkgPSBmaW5kQ2hpbGRFbGVtZW50KAogICAgICBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLAogICAgICAiQ2FwYWJpbGl0eSIKICAgICk7CiAgICBjb25zdCBnZXRGZWF0dXJlSW5mbyA9IGZpbmRDaGlsZEVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQoY2FwYWJpbGl0eSwgIlJlcXVlc3QiKSwKICAgICAgIkdldEZlYXR1cmVJbmZvIgogICAgKTsKICAgIGNvbnN0IG91dHB1dEZvcm1hdHMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGdldEZlYXR1cmVJbmZvLCAiRm9ybWF0IikubWFwKAogICAgICBnZXRFbGVtZW50VGV4dAogICAgKTsKICAgIHJldHVybiBvdXRwdXRGb3JtYXRzOwogIH0KICBmdW5jdGlvbiByZWFkRXhjZXB0aW9uRm9ybWF0c0Zyb21DYXBhYmlsaXRpZXMoY2FwYWJpbGl0aWVzRG9jKSB7CiAgICBjb25zdCBjYXBhYmlsaXR5ID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwKICAgICAgIkNhcGFiaWxpdHkiCiAgICApOwogICAgY29uc3QgZXhjZXB0aW9uID0gZmluZENoaWxkRWxlbWVudChjYXBhYmlsaXR5LCAiRXhjZXB0aW9uIik7CiAgICBjb25zdCBleGNlcHRpb25Gb3JtYXRzID0gZmluZENoaWxkcmVuRWxlbWVudChleGNlcHRpb24sICJGb3JtYXQiKS5tYXAoCiAgICAgIGdldEVsZW1lbnRUZXh0CiAgICApOwogICAgcmV0dXJuIGV4Y2VwdGlvbkZvcm1hdHM7CiAgfQogIGZ1bmN0aW9uIHJlYWRJbmZvRnJvbUNhcGFiaWxpdGllcyQyKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3Qgc2VydmljZSA9IGZpbmRDaGlsZEVsZW1lbnQoZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwgIlNlcnZpY2UiKTsKICAgIGNvbnN0IG91dHB1dEZvcm1hdHMgPSByZWFkT3V0cHV0Rm9ybWF0c0Zyb21DYXBhYmlsaXRpZXMkMShjYXBhYmlsaXRpZXNEb2MpOwogICAgY29uc3QgaW5mb0Zvcm1hdHMgPSByZWFkSW5mb0Zvcm1hdHNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYyk7CiAgICBjb25zdCBleGNlcHRpb25Gb3JtYXRzID0gcmVhZEV4Y2VwdGlvbkZvcm1hdHNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYyk7CiAgICBjb25zdCBrZXl3b3JkcyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIktleXdvcmRMaXN0IiksCiAgICAgICJLZXl3b3JkIgogICAgKS5tYXAoZ2V0RWxlbWVudFRleHQpLmZpbHRlcigodiwgaSwgYXJyKSA9PiBhcnIuaW5kZXhPZih2KSA9PT0gaSk7CiAgICBjb25zdCBwcm92aWRlciA9IHJlYWRQcm92aWRlckZyb21DYXBhYmlsaXRpZXMkMShjYXBhYmlsaXRpZXNEb2MpOwogICAgcmV0dXJuIHsKICAgICAgdGl0bGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIlRpdGxlIikpLAogICAgICBuYW1lOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJOYW1lIikpLAogICAgICBhYnN0cmFjdDogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzZXJ2aWNlLCAiQWJzdHJhY3QiKSksCiAgICAgIG91dHB1dEZvcm1hdHMsCiAgICAgIGluZm9Gb3JtYXRzLAogICAgICBleGNlcHRpb25Gb3JtYXRzLAogICAgICBmZWVzOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJGZWVzIikpLAogICAgICBjb25zdHJhaW50czogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzZXJ2aWNlLCAiQWNjZXNzQ29uc3RyYWludHMiKSksCiAgICAgIHByb3ZpZGVyLAogICAgICBrZXl3b3JkcwogICAgfTsKICB9CiAgZnVuY3Rpb24gcGFyc2VPcGVyYXRpb24ob3BlcmF0aW9uKSB7CiAgICBjb25zdCB1cmxzID0ge307CiAgICBjb25zdCBkY3BUeXBlID0gZmluZENoaWxkcmVuRWxlbWVudChvcGVyYXRpb24sICJEQ1BUeXBlIik7CiAgICBjb25zdCBodHRwID0gZGNwVHlwZS5mbGF0TWFwKChkKSA9PiBmaW5kQ2hpbGRFbGVtZW50KGQsICJIVFRQIikpOwogICAgY29uc3QgbWV0aG9kcyA9IGh0dHAuZmxhdE1hcCgoaCkgPT4gZ2V0Q2hpbGRyZW5FbGVtZW50KGgpKTsKICAgIG1ldGhvZHMuZm9yRWFjaCgobWV0aG9kKSA9PiB7CiAgICAgIGNvbnN0IG9ubGluZVJlc291cmNlID0gZmluZENoaWxkRWxlbWVudChtZXRob2QsICJPbmxpbmVSZXNvdXJjZSIpOwogICAgICBjb25zdCBtZXRob2ROYW1lID0gc3RyaXBOYW1lc3BhY2UoZ2V0RWxlbWVudE5hbWUobWV0aG9kKSk7CiAgICAgIHVybHNbbWV0aG9kTmFtZV0gPSBnZXRFbGVtZW50QXR0cmlidXRlKG9ubGluZVJlc291cmNlLCAieGxpbms6aHJlZiIpOwogICAgfSk7CiAgICByZXR1cm4gdXJsczsKICB9CiAgZnVuY3Rpb24gcGFyc2VMYXllcihsYXllckVsLCB2ZXJzaW9uLCBpbmhlcml0ZWRTcnMgPSBbXSwgaW5oZXJpdGVkU3R5bGVzID0gW10sIGluaGVyaXRlZEF0dHJpYnV0aW9uID0gbnVsbCwgaW5oZXJpdGVkQm91bmRpbmdCb3hlcyA9IG51bGwsIGluaGVyaXRlZE1heFNjYWxlRGVub20gPSBudWxsLCBpbmhlcml0ZWRNaW5TY2FsZURlbm9tID0gbnVsbCkgewogICAgY29uc3Qgc3JzVGFnID0gdmVyc2lvbiA9PT0gIjEuMy4wIiA/ICJDUlMiIDogIlNSUyI7CiAgICBjb25zdCBzcnNMaXN0ID0gZmluZENoaWxkcmVuRWxlbWVudChsYXllckVsLCBzcnNUYWcpLm1hcChnZXRFbGVtZW50VGV4dCk7CiAgICBjb25zdCBhdmFpbGFibGVDcnMgPSBzcnNMaXN0Lmxlbmd0aCA+IDAgPyBzcnNMaXN0IDogaW5oZXJpdGVkU3JzOwogICAgY29uc3QgbGF5ZXJTdHlsZXMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGxheWVyRWwsICJTdHlsZSIpLm1hcCgKICAgICAgcGFyc2VMYXllclN0eWxlCiAgICApOwogICAgY29uc3Qgc3R5bGVzID0gbGF5ZXJTdHlsZXMubGVuZ3RoID4gMCA/IGxheWVyU3R5bGVzIDogaW5oZXJpdGVkU3R5bGVzOwogICAgZnVuY3Rpb24gcGFyc2VCQm94MihiYm94RWwpIHsKICAgICAgY29uc3Qgc3JzID0gZ2V0RWxlbWVudEF0dHJpYnV0ZShiYm94RWwsIHNyc1RhZyk7CiAgICAgIGNvbnN0IGF0dHJzID0gaGFzSW52ZXJ0ZWRDb29yZGluYXRlcyhzcnMpICYmIHZlcnNpb24gPT09ICIxLjMuMCIgPyBbIm1pbnkiLCAibWlueCIsICJtYXh5IiwgIm1heHgiXSA6IFsibWlueCIsICJtaW55IiwgIm1heHgiLCAibWF4eSJdOwogICAgICByZXR1cm4gYXR0cnMubWFwKChuYW1lKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGJib3hFbCwgbmFtZSkpOwogICAgfQogICAgZnVuY3Rpb24gcGFyc2VFeEdlb2dyYXBoaWNCb3VuZGluZ0JveChiYm94RWwpIHsKICAgICAgcmV0dXJuIFsKICAgICAgICAid2VzdEJvdW5kTG9uZ2l0dWRlIiwKICAgICAgICAic291dGhCb3VuZExhdGl0dWRlIiwKICAgICAgICAiZWFzdEJvdW5kTG9uZ2l0dWRlIiwKICAgICAgICAibm9ydGhCb3VuZExhdGl0dWRlIgogICAgICBdLm1hcCgobmFtZSkgPT4gZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChiYm94RWwsIG5hbWUpKSk7CiAgICB9CiAgICBmdW5jdGlvbiBwYXJzZUxhdExvbkJvdW5kaW5nQm94KGJib3hFbCkgewogICAgICByZXR1cm4gWyJtaW54IiwgIm1pbnkiLCAibWF4eCIsICJtYXh5Il0ubWFwKAogICAgICAgIChuYW1lKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGJib3hFbCwgbmFtZSkKICAgICAgKTsKICAgIH0KICAgIGZ1bmN0aW9uIHBhcnNlU2NhbGVIaW50VmFsdWUodGV4dFZhbHVlLCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKHRleHRWYWx1ZSA9PT0gIiIpIHsKICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIHJldHVybiBNYXRoLnNxcnQoMC41ICogcGFyc2VGbG9hdCh0ZXh0VmFsdWUpICoqIDIpIC8gMjhlLTU7CiAgICB9CiAgICBmdW5jdGlvbiBwYXJzZVNjYWxlSGludCgpIHsKICAgICAgY29uc3Qgc2NhbGVIaW50ID0gZmluZENoaWxkRWxlbWVudChsYXllckVsLCAiU2NhbGVIaW50Iik7CiAgICAgIGlmICghc2NhbGVIaW50KSB7CiAgICAgICAgcmV0dXJuIFtpbmhlcml0ZWRNaW5TY2FsZURlbm9tLCBpbmhlcml0ZWRNYXhTY2FsZURlbm9tXTsKICAgICAgfQogICAgICBjb25zdCBtaW4gPSBnZXRFbGVtZW50QXR0cmlidXRlKHNjYWxlSGludCwgIm1pbiIpOwogICAgICBjb25zdCBtYXggPSBnZXRFbGVtZW50QXR0cmlidXRlKHNjYWxlSGludCwgIm1heCIpOwogICAgICByZXR1cm4gWwogICAgICAgIHBhcnNlU2NhbGVIaW50VmFsdWUobWluLCBpbmhlcml0ZWRNaW5TY2FsZURlbm9tKSwKICAgICAgICBwYXJzZVNjYWxlSGludFZhbHVlKG1heCwgaW5oZXJpdGVkTWF4U2NhbGVEZW5vbSkKICAgICAgXTsKICAgIH0KICAgIGZ1bmN0aW9uIHBhcnNlU2NhbGVEZW5vbWluYXRvcihuYW1lLCBpbmhlcml0ZWRWYWx1ZSkgewogICAgICBjb25zdCB0ZXh0VmFsdWUgPSBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGxheWVyRWwsIG5hbWUpKTsKICAgICAgcmV0dXJuIHRleHRWYWx1ZSA9PT0gIiIgPyBpbmhlcml0ZWRWYWx1ZSA6IHBhcnNlRmxvYXQodGV4dFZhbHVlKTsKICAgIH0KICAgIGNvbnN0IGF0dHJpYnV0aW9uRWwgPSBmaW5kQ2hpbGRFbGVtZW50KGxheWVyRWwsICJBdHRyaWJ1dGlvbiIpOwogICAgY29uc3QgYXR0cmlidXRpb24gPSBhdHRyaWJ1dGlvbkVsICE9PSBudWxsID8gcGFyc2VMYXllckF0dHJpYnV0aW9uKGF0dHJpYnV0aW9uRWwpIDogaW5oZXJpdGVkQXR0cmlidXRpb247CiAgICBjb25zdCBsYXRMb25CYm94RWwgPSB2ZXJzaW9uID09PSAiMS4zLjAiID8gZmluZENoaWxkRWxlbWVudChsYXllckVsLCAiRVhfR2VvZ3JhcGhpY0JvdW5kaW5nQm94IikgOiBmaW5kQ2hpbGRFbGVtZW50KGxheWVyRWwsICJMYXRMb25Cb3VuZGluZ0JveCIpOwogICAgY29uc3QgYmFzZUJvdW5kaW5nQm94ID0ge307CiAgICBpZiAobGF0TG9uQmJveEVsKSB7CiAgICAgIGJhc2VCb3VuZGluZ0JveFsiRVBTRzo0MzI2Il0gPSB2ZXJzaW9uID09PSAiMS4zLjAiID8gcGFyc2VFeEdlb2dyYXBoaWNCb3VuZGluZ0JveChsYXRMb25CYm94RWwpIDogcGFyc2VMYXRMb25Cb3VuZGluZ0JveChsYXRMb25CYm94RWwpOwogICAgfQogICAgbGV0IGJvdW5kaW5nQm94ZXMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGxheWVyRWwsICJCb3VuZGluZ0JveCIpLnJlZHVjZSgKICAgICAgKHByZXYsIGJib3hFbCkgPT4gKHsKICAgICAgICAuLi5wcmV2LAogICAgICAgIFtnZXRFbGVtZW50QXR0cmlidXRlKGJib3hFbCwgc3JzVGFnKV06IHBhcnNlQkJveDIoYmJveEVsKQogICAgICB9KSwKICAgICAgYmFzZUJvdW5kaW5nQm94CiAgICApOwogICAgYm91bmRpbmdCb3hlcyA9IE9iamVjdC5rZXlzKGJvdW5kaW5nQm94ZXMpLmxlbmd0aCA+IDAgfHwgaW5oZXJpdGVkQm91bmRpbmdCb3hlcyA9PT0gbnVsbCA/IGJvdW5kaW5nQm94ZXMgOiBpbmhlcml0ZWRCb3VuZGluZ0JveGVzOwogICAgY29uc3QgcXVlcnlhYmxlID0gbGF5ZXJFbC5hdHRyaWJ1dGVzLnF1ZXJ5YWJsZSA9PT0gIjEiIHx8IGxheWVyRWwuYXR0cmlidXRlcy5xdWVyeWFibGUgPT09ICJ0cnVlIiA/IHRydWUgOiBmYWxzZTsKICAgIGNvbnN0IG9wYXF1ZSA9IGxheWVyRWwuYXR0cmlidXRlcy5vcGFxdWUgPT09ICIxIiB8fCBsYXllckVsLmF0dHJpYnV0ZXMub3BhcXVlID09PSAidHJ1ZSIgPyB0cnVlIDogZmFsc2U7CiAgICBjb25zdCBrZXl3b3JkcyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQobGF5ZXJFbCwgIktleXdvcmRMaXN0IiksCiAgICAgICJLZXl3b3JkIgogICAgKS5tYXAoZ2V0RWxlbWVudFRleHQpLmZpbHRlcigodiwgaSwgYXJyKSA9PiBhcnIuaW5kZXhPZih2KSA9PT0gaSk7CiAgICBsZXQgbWluU2NhbGVEZW5vbWluYXRvciwgbWF4U2NhbGVEZW5vbWluYXRvcjsKICAgIGlmICh2ZXJzaW9uID09PSAiMS4zLjAiKSB7CiAgICAgIG1pblNjYWxlRGVub21pbmF0b3IgPSBwYXJzZVNjYWxlRGVub21pbmF0b3IoCiAgICAgICAgIk1pblNjYWxlRGVub21pbmF0b3IiLAogICAgICAgIGluaGVyaXRlZE1pblNjYWxlRGVub20KICAgICAgKTsKICAgICAgbWF4U2NhbGVEZW5vbWluYXRvciA9IHBhcnNlU2NhbGVEZW5vbWluYXRvcigKICAgICAgICAiTWF4U2NhbGVEZW5vbWluYXRvciIsCiAgICAgICAgaW5oZXJpdGVkTWF4U2NhbGVEZW5vbQogICAgICApOwogICAgfSBlbHNlIHsKICAgICAgW21pblNjYWxlRGVub21pbmF0b3IsIG1heFNjYWxlRGVub21pbmF0b3JdID0gcGFyc2VTY2FsZUhpbnQoKTsKICAgIH0KICAgIGNvbnN0IG1ldGFkYXRhID0gZmluZENoaWxkcmVuRWxlbWVudChsYXllckVsLCAiTWV0YWRhdGFVUkwiKS5tYXAoCiAgICAgIChtZXRhZGF0YVVybEVsKSA9PiAoewogICAgICAgIHR5cGU6IGdldEVsZW1lbnRBdHRyaWJ1dGUobWV0YWRhdGFVcmxFbCwgInR5cGUiKSwKICAgICAgICBmb3JtYXQ6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQobWV0YWRhdGFVcmxFbCwgIkZvcm1hdCIpKSwKICAgICAgICB1cmw6IGdldEVsZW1lbnRBdHRyaWJ1dGUoCiAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KG1ldGFkYXRhVXJsRWwsICJPbmxpbmVSZXNvdXJjZSIpLAogICAgICAgICAgInhsaW5rOmhyZWYiCiAgICAgICAgKQogICAgICB9KQogICAgKTsKICAgIGNvbnN0IGNoaWxkcmVuID0gZmluZENoaWxkcmVuRWxlbWVudChsYXllckVsLCAiTGF5ZXIiKS5tYXAoCiAgICAgIChsYXllcikgPT4gcGFyc2VMYXllcigKICAgICAgICBsYXllciwKICAgICAgICB2ZXJzaW9uLAogICAgICAgIGF2YWlsYWJsZUNycywKICAgICAgICBzdHlsZXMsCiAgICAgICAgYXR0cmlidXRpb24sCiAgICAgICAgYm91bmRpbmdCb3hlcywKICAgICAgICBtYXhTY2FsZURlbm9taW5hdG9yLAogICAgICAgIG1pblNjYWxlRGVub21pbmF0b3IKICAgICAgKQogICAgKTsKICAgIHJldHVybiB7CiAgICAgIG5hbWU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQobGF5ZXJFbCwgIk5hbWUiKSksCiAgICAgIHRpdGxlOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGxheWVyRWwsICJUaXRsZSIpKSwKICAgICAgYWJzdHJhY3Q6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQobGF5ZXJFbCwgIkFic3RyYWN0IikpLAogICAgICBhdmFpbGFibGVDcnMsCiAgICAgIHN0eWxlcywKICAgICAgYXR0cmlidXRpb24sCiAgICAgIGJvdW5kaW5nQm94ZXMsCiAgICAgIGtleXdvcmRzLAogICAgICBxdWVyeWFibGUsCiAgICAgIG9wYXF1ZSwKICAgICAgLi4ubWluU2NhbGVEZW5vbWluYXRvciAhPT0gbnVsbCA/IHsgbWluU2NhbGVEZW5vbWluYXRvciB9IDoge30sCiAgICAgIC4uLm1heFNjYWxlRGVub21pbmF0b3IgIT09IG51bGwgPyB7IG1heFNjYWxlRGVub21pbmF0b3IgfSA6IHt9LAogICAgICAuLi5tZXRhZGF0YS5sZW5ndGggJiYgeyBtZXRhZGF0YSB9LAogICAgICAuLi5jaGlsZHJlbi5sZW5ndGggJiYgeyBjaGlsZHJlbiB9CiAgICB9OwogIH0KICBmdW5jdGlvbiBwYXJzZUxheWVyU3R5bGUoc3R5bGVFbCkgewogICAgY29uc3QgbGVnZW5kVXJsID0gZ2V0RWxlbWVudEF0dHJpYnV0ZSgKICAgICAgZmluZENoaWxkRWxlbWVudChmaW5kQ2hpbGRFbGVtZW50KHN0eWxlRWwsICJMZWdlbmRVUkwiKSwgIk9ubGluZVJlc291cmNlIiksCiAgICAgICJ4bGluazpocmVmIgogICAgKTsKICAgIGNvbnN0IGFic3RyYWN0ID0gZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzdHlsZUVsLCAiQWJzdHJhY3QiKSk7CiAgICByZXR1cm4gewogICAgICBuYW1lOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHN0eWxlRWwsICJOYW1lIikpLAogICAgICB0aXRsZTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzdHlsZUVsLCAiVGl0bGUiKSksCiAgICAgIC4uLmFic3RyYWN0ICYmIHsgYWJzdHJhY3QgfSwKICAgICAgLi4ubGVnZW5kVXJsICYmIHsgbGVnZW5kVXJsIH0KICAgIH07CiAgfQogIGZ1bmN0aW9uIHBhcnNlTGF5ZXJBdHRyaWJ1dGlvbihhdHRyaWJ1dGlvbkVsKSB7CiAgICBjb25zdCBsb2dvVXJsID0gZ2V0RWxlbWVudEF0dHJpYnV0ZSgKICAgICAgZmluZENoaWxkRWxlbWVudCgKICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGF0dHJpYnV0aW9uRWwsICJMb2dvVVJMIiksCiAgICAgICAgIk9ubGluZVJlc291cmNlIgogICAgICApLAogICAgICAieGxpbms6aHJlZiIKICAgICk7CiAgICBjb25zdCB1cmwgPSBnZXRFbGVtZW50QXR0cmlidXRlKAogICAgICBmaW5kQ2hpbGRFbGVtZW50KGF0dHJpYnV0aW9uRWwsICJPbmxpbmVSZXNvdXJjZSIpLAogICAgICAieGxpbms6aHJlZiIKICAgICk7CiAgICBjb25zdCB0aXRsZSA9IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoYXR0cmlidXRpb25FbCwgIlRpdGxlIikpOwogICAgcmV0dXJuIHsKICAgICAgLi4udGl0bGUgJiYgeyB0aXRsZSB9LAogICAgICAuLi51cmwgJiYgeyB1cmwgfSwKICAgICAgLi4ubG9nb1VybCAmJiB7IGxvZ29VcmwgfQogICAgfTsKICB9CiAgZnVuY3Rpb24gcmVhZFByb3ZpZGVyRnJvbUNhcGFiaWxpdGllcyQxKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3Qgc2VydmljZSA9IGZpbmRDaGlsZEVsZW1lbnQoZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKSwgIlNlcnZpY2UiKTsKICAgIGNvbnN0IGNvbnRhY3RJbmZvcm1hdGlvbiA9IGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIkNvbnRhY3RJbmZvcm1hdGlvbiIpOwogICAgY29uc3QgY29udGFjdFBlcnNvblByaW1hcnkgPSBmaW5kQ2hpbGRFbGVtZW50KAogICAgICBjb250YWN0SW5mb3JtYXRpb24sCiAgICAgICJDb250YWN0UGVyc29uUHJpbWFyeSIKICAgICk7CiAgICBjb25zdCBhZGRyZXNzID0gZmluZENoaWxkRWxlbWVudChjb250YWN0SW5mb3JtYXRpb24sICJDb250YWN0QWRkcmVzcyIpOwogICAgcmV0dXJuIHsKICAgICAgY29udGFjdDogewogICAgICAgIG5hbWU6IGdldEVsZW1lbnRUZXh0KAogICAgICAgICAgZmluZENoaWxkRWxlbWVudChjb250YWN0UGVyc29uUHJpbWFyeSwgIkNvbnRhY3RQZXJzb24iKQogICAgICAgICksCiAgICAgICAgb3JnYW5pemF0aW9uOiBnZXRFbGVtZW50VGV4dCgKICAgICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoY29udGFjdFBlcnNvblByaW1hcnksICJDb250YWN0T3JnYW5pemF0aW9uIikKICAgICAgICApLAogICAgICAgIHBvc2l0aW9uOiBnZXRFbGVtZW50VGV4dCgKICAgICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoY29udGFjdEluZm9ybWF0aW9uLCAiQ29udGFjdFBvc2l0aW9uIikKICAgICAgICApLAogICAgICAgIHBob25lOiBnZXRFbGVtZW50VGV4dCgKICAgICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoY29udGFjdEluZm9ybWF0aW9uLCAiQ29udGFjdFZvaWNlVGVsZXBob25lIikKICAgICAgICApLAogICAgICAgIGZheDogZ2V0RWxlbWVudFRleHQoCiAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGNvbnRhY3RJbmZvcm1hdGlvbiwgIkNvbnRhY3RGYWNzaW1pbGVUZWxlcGhvbmUiKQogICAgICAgICksCiAgICAgICAgYWRkcmVzczogewogICAgICAgICAgZGVsaXZlcnlQb2ludDogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChhZGRyZXNzLCAiQWRkcmVzcyIpKSwKICAgICAgICAgIGNpdHk6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoYWRkcmVzcywgIkNpdHkiKSksCiAgICAgICAgICBhZG1pbmlzdHJhdGl2ZUFyZWE6IGdldEVsZW1lbnRUZXh0KAogICAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGFkZHJlc3MsICJTdGF0ZU9yUHJvdmluY2UiKQogICAgICAgICAgKSwKICAgICAgICAgIHBvc3RhbENvZGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoYWRkcmVzcywgIlBvc3RDb2RlIikpLAogICAgICAgICAgY291bnRyeTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChhZGRyZXNzLCAiQ291bnRyeSIpKQogICAgICAgIH0sCiAgICAgICAgZW1haWw6IGdldEVsZW1lbnRUZXh0KAogICAgICAgICAgZmluZENoaWxkRWxlbWVudChjb250YWN0SW5mb3JtYXRpb24sICJDb250YWN0RWxlY3Ryb25pY01haWxBZGRyZXNzIikKICAgICAgICApCiAgICAgIH0KICAgIH07CiAgfQogIGZ1bmN0aW9uIHJlYWRQcm92aWRlckZyb21DYXBhYmlsaXRpZXMoY2FwYWJpbGl0aWVzRG9jKSB7CiAgICBjb25zdCBzZXJ2aWNlUHJvdmlkZXIgPSBmaW5kQ2hpbGRFbGVtZW50KAogICAgICBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLAogICAgICAiU2VydmljZVByb3ZpZGVyIgogICAgKTsKICAgIGNvbnN0IHNlcnZpY2VDb250YWN0ID0gZmluZENoaWxkRWxlbWVudChzZXJ2aWNlUHJvdmlkZXIsICJTZXJ2aWNlQ29udGFjdCIpOwogICAgY29uc3QgY29udGFjdEluZm8gPSBmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2VDb250YWN0LCAiQ29udGFjdEluZm8iKTsKICAgIGNvbnN0IHBob25lID0gZmluZENoaWxkRWxlbWVudChjb250YWN0SW5mbywgIlBob25lIik7CiAgICBjb25zdCBhZGRyZXNzID0gZmluZENoaWxkRWxlbWVudChjb250YWN0SW5mbywgIkFkZHJlc3MiKTsKICAgIHJldHVybiB7CiAgICAgIG5hbWU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZVByb3ZpZGVyLCAiUHJvdmlkZXJOYW1lIikpLAogICAgICBzaXRlOiBnZXRFbGVtZW50QXR0cmlidXRlKAogICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZVByb3ZpZGVyLCAiUHJvdmlkZXJTaXRlIiksCiAgICAgICAgInhsaW5rOmhyZWYiCiAgICAgICksCiAgICAgIGNvbnRhY3Q6IHsKICAgICAgICBuYW1lOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2VDb250YWN0LCAiSW5kaXZpZHVhbE5hbWUiKSksCiAgICAgICAgcG9zaXRpb246IGdldEVsZW1lbnRUZXh0KAogICAgICAgICAgZmluZENoaWxkRWxlbWVudChzZXJ2aWNlQ29udGFjdCwgIlBvc2l0aW9uTmFtZSIpCiAgICAgICAgKSwKICAgICAgICBwaG9uZTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChwaG9uZSwgIlZvaWNlIikpLAogICAgICAgIGZheDogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChwaG9uZSwgIkZhY3NpbWlsZSIpKSwKICAgICAgICBhZGRyZXNzOiB7CiAgICAgICAgICBkZWxpdmVyeVBvaW50OiBnZXRFbGVtZW50VGV4dCgKICAgICAgICAgICAgZmluZENoaWxkRWxlbWVudChhZGRyZXNzLCAiRGVsaXZlcnlQb2ludCIpCiAgICAgICAgICApLAogICAgICAgICAgY2l0eTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChhZGRyZXNzLCAiQ2l0eSIpKSwKICAgICAgICAgIGFkbWluaXN0cmF0aXZlQXJlYTogZ2V0RWxlbWVudFRleHQoCiAgICAgICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoYWRkcmVzcywgIkFkbWluaXN0cmF0aXZlQXJlYSIpCiAgICAgICAgICApLAogICAgICAgICAgcG9zdGFsQ29kZTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChhZGRyZXNzLCAiUG9zdGFsQ29kZSIpKSwKICAgICAgICAgIGNvdW50cnk6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoYWRkcmVzcywgIkNvdW50cnkiKSkKICAgICAgICB9LAogICAgICAgIGVtYWlsOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGFkZHJlc3MsICJFbGVjdHJvbmljTWFpbEFkZHJlc3MiKSkKICAgICAgfQogICAgfTsKICB9CiAgZnVuY3Rpb24gcmVhZE9wZXJhdGlvblVybHNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3QgdXJscyA9IHt9OwogICAgY29uc3QgY2FwYWJpbGl0aWVzID0gZ2V0Um9vdEVsZW1lbnQoY2FwYWJpbGl0aWVzRG9jKTsKICAgIGNvbnN0IG9wZXJhdGlvbnNNZXRhZGF0YSA9IGZpbmRDaGlsZEVsZW1lbnQoCiAgICAgIGNhcGFiaWxpdGllcywKICAgICAgIk9wZXJhdGlvbnNNZXRhZGF0YSIKICAgICk7CiAgICBpZiAob3BlcmF0aW9uc01ldGFkYXRhKSB7CiAgICAgIGZpbmRDaGlsZHJlbkVsZW1lbnQob3BlcmF0aW9uc01ldGFkYXRhLCAiT3BlcmF0aW9uIikuZm9yRWFjaCgKICAgICAgICAob3BlcmF0aW9uKSA9PiB7CiAgICAgICAgICBjb25zdCBuYW1lID0gZ2V0RWxlbWVudEF0dHJpYnV0ZShvcGVyYXRpb24sICJuYW1lIik7CiAgICAgICAgICB1cmxzW25hbWVdID0gcGFyc2VPcGVyYXRpb24xMTAob3BlcmF0aW9uKTsKICAgICAgICB9CiAgICAgICk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBjYXBhYmlsaXR5ID0gZmluZENoaWxkRWxlbWVudChjYXBhYmlsaXRpZXMsICJDYXBhYmlsaXR5Iik7CiAgICAgIGNvbnN0IHJlcXVlc3QgPSBmaW5kQ2hpbGRFbGVtZW50KGNhcGFiaWxpdHksICJSZXF1ZXN0Iik7CiAgICAgIGdldENoaWxkcmVuRWxlbWVudChyZXF1ZXN0KS5mb3JFYWNoKChvcGVyYXRpb24pID0+IHsKICAgICAgICBjb25zdCBuYW1lID0gc3RyaXBOYW1lc3BhY2UoZ2V0RWxlbWVudE5hbWUob3BlcmF0aW9uKSk7CiAgICAgICAgdXJsc1tuYW1lXSA9IHBhcnNlT3BlcmF0aW9uMTAwKG9wZXJhdGlvbik7CiAgICAgIH0pOwogICAgfQogICAgcmV0dXJuIHVybHM7CiAgfQogIGZ1bmN0aW9uIHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpIHsKICAgIHJldHVybiBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLmF0dHJpYnV0ZXNbInZlcnNpb24iXTsKICB9CiAgZnVuY3Rpb24gcmVhZE91dHB1dEZvcm1hdHNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3QgdmVyc2lvbiA9IHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpOwogICAgbGV0IG91dHB1dEZvcm1hdHM7CiAgICBpZiAodmVyc2lvbi5zdGFydHNXaXRoKCIxLjAiKSkgewogICAgICBjb25zdCBnZXRGZWF0dXJlID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KAogICAgICAgICAgZmluZENoaWxkRWxlbWVudChnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLCAiQ2FwYWJpbGl0eSIpLAogICAgICAgICAgIlJlcXVlc3QiCiAgICAgICAgKSwKICAgICAgICAiR2V0RmVhdHVyZSIKICAgICAgKTsKICAgICAgb3V0cHV0Rm9ybWF0cyA9IGdldENoaWxkcmVuRWxlbWVudCgKICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGdldEZlYXR1cmUsICJSZXN1bHRGb3JtYXQiKQogICAgICApLm1hcChnZXRFbGVtZW50TmFtZSk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBvcGVyYXRpb25zID0gZmluZENoaWxkRWxlbWVudCgKICAgICAgICBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLAogICAgICAgICJPcGVyYXRpb25zTWV0YWRhdGEiCiAgICAgICk7CiAgICAgIGNvbnN0IGdldEZlYXR1cmUgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KG9wZXJhdGlvbnMsICJPcGVyYXRpb24iKS5maW5kKAogICAgICAgIChlbCkgPT4gZ2V0RWxlbWVudEF0dHJpYnV0ZShlbCwgIm5hbWUiKSA9PT0gIkdldEZlYXR1cmUiCiAgICAgICk7CiAgICAgIGNvbnN0IHBhcmFtZXRlciA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoZ2V0RmVhdHVyZSwgIlBhcmFtZXRlciIpLmZpbmQoCiAgICAgICAgKGVsKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGVsLCAibmFtZSIpID09PSAib3V0cHV0Rm9ybWF0IgogICAgICApOwogICAgICBvdXRwdXRGb3JtYXRzID0gZmluZENoaWxkcmVuRWxlbWVudChwYXJhbWV0ZXIsICJWYWx1ZSIsIHRydWUpLm1hcCgKICAgICAgICBnZXRFbGVtZW50VGV4dAogICAgICApOwogICAgfQogICAgcmV0dXJuIG91dHB1dEZvcm1hdHM7CiAgfQogIGZ1bmN0aW9uIHJlYWRJbmZvRnJvbUNhcGFiaWxpdGllcyQxKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3QgdmVyc2lvbiA9IHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpOwogICAgY29uc3Qgc2VydmljZVRhZyA9IHZlcnNpb24uc3RhcnRzV2l0aCgiMS4wIikgPyAiU2VydmljZSIgOiAiU2VydmljZUlkZW50aWZpY2F0aW9uIjsKICAgIGNvbnN0IG5hbWVUYWcgPSB2ZXJzaW9uLnN0YXJ0c1dpdGgoIjEuMCIpID8gIk5hbWUiIDogIlNlcnZpY2VUeXBlIjsKICAgIGNvbnN0IHNlcnZpY2UgPSBmaW5kQ2hpbGRFbGVtZW50KGdldFJvb3RFbGVtZW50KGNhcGFiaWxpdGllc0RvYyksIHNlcnZpY2VUYWcpOwogICAgbGV0IGtleXdvcmRzOwogICAgaWYgKHZlcnNpb24uc3RhcnRzV2l0aCgiMS4wIikpIHsKICAgICAga2V5d29yZHMgPSBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJLZXl3b3JkcyIpKS5zcGxpdCgiLCIpLm1hcCgoa2V5d29yZCkgPT4ga2V5d29yZC50cmltKCkpOwogICAgfSBlbHNlIHsKICAgICAga2V5d29yZHMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KAogICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIktleXdvcmRzIiksCiAgICAgICAgIktleXdvcmQiCiAgICAgICkubWFwKGdldEVsZW1lbnRUZXh0KTsKICAgIH0KICAgIGxldCBwcm92aWRlcjsKICAgIGlmICh2ZXJzaW9uICE9PSAiMS4wLjAiKSB7CiAgICAgIHByb3ZpZGVyID0gcmVhZFByb3ZpZGVyRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpOwogICAgfQogICAgcmV0dXJuIHsKICAgICAgdGl0bGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIlRpdGxlIikpLAogICAgICBuYW1lOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsIG5hbWVUYWcpKSwKICAgICAgYWJzdHJhY3Q6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIkFic3RyYWN0IikpLAogICAgICBmZWVzOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJGZWVzIikpLAogICAgICBjb25zdHJhaW50czogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzZXJ2aWNlLCAiQWNjZXNzQ29uc3RyYWludHMiKSksCiAgICAgIGtleXdvcmRzLAogICAgICBwcm92aWRlciwKICAgICAgb3V0cHV0Rm9ybWF0czogcmVhZE91dHB1dEZvcm1hdHNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYykKICAgIH07CiAgfQogIGZ1bmN0aW9uIHJlYWRGZWF0dXJlVHlwZXNGcm9tQ2FwYWJpbGl0aWVzKGNhcGFiaWxpdGllc0RvYykgewogICAgY29uc3QgdmVyc2lvbiA9IHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpOwogICAgY29uc3Qgb3V0cHV0Rm9ybWF0cyA9IHJlYWRPdXRwdXRGb3JtYXRzRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpOwogICAgY29uc3QgY2FwYWJpbGl0eSA9IGZpbmRDaGlsZEVsZW1lbnQoCiAgICAgIGdldFJvb3RFbGVtZW50KGNhcGFiaWxpdGllc0RvYyksCiAgICAgICJGZWF0dXJlVHlwZUxpc3QiCiAgICApOwogICAgcmV0dXJuIGZpbmRDaGlsZHJlbkVsZW1lbnQoY2FwYWJpbGl0eSwgIkZlYXR1cmVUeXBlIikubWFwKAogICAgICAoZmVhdHVyZVR5cGVFbCkgPT4gcGFyc2VGZWF0dXJlVHlwZShmZWF0dXJlVHlwZUVsLCB2ZXJzaW9uLCBvdXRwdXRGb3JtYXRzKQogICAgKTsKICB9CiAgZnVuY3Rpb24gcGFyc2VPcGVyYXRpb24xMDAob3BlcmF0aW9uKSB7CiAgICBjb25zdCB1cmxzID0ge307CiAgICBjb25zdCBkY3BUeXBlID0gZmluZENoaWxkcmVuRWxlbWVudChvcGVyYXRpb24sICJEQ1BUeXBlIik7CiAgICBjb25zdCBodHRwID0gZGNwVHlwZS5mbGF0TWFwKChkKSA9PiBmaW5kQ2hpbGRyZW5FbGVtZW50KGQsICJIVFRQIikpOwogICAgY29uc3QgbWV0aG9kcyA9IGh0dHAuZmxhdE1hcCgoaCkgPT4gZ2V0Q2hpbGRyZW5FbGVtZW50KGgpKTsKICAgIG1ldGhvZHMuZm9yRWFjaCgobWV0aG9kKSA9PiB7CiAgICAgIGNvbnN0IG1ldGhvZE5hbWUgPSBzdHJpcE5hbWVzcGFjZShnZXRFbGVtZW50TmFtZShtZXRob2QpKTsKICAgICAgdXJsc1ttZXRob2ROYW1lXSA9IGdldEVsZW1lbnRBdHRyaWJ1dGUobWV0aG9kLCAib25saW5lUmVzb3VyY2UiKTsKICAgIH0pOwogICAgcmV0dXJuIHVybHM7CiAgfQogIGZ1bmN0aW9uIHBhcnNlT3BlcmF0aW9uMTEwKG9wZXJhdGlvbikgewogICAgY29uc3QgdXJscyA9IHt9OwogICAgY29uc3QgZGNwVHlwZSA9IGZpbmRDaGlsZHJlbkVsZW1lbnQob3BlcmF0aW9uLCAiRENQIik7CiAgICBjb25zdCBodHRwID0gZGNwVHlwZS5mbGF0TWFwKChkKSA9PiBmaW5kQ2hpbGRFbGVtZW50KGQsICJIVFRQIikpOwogICAgY29uc3QgbWV0aG9kcyA9IGh0dHAuZmxhdE1hcCgoaCkgPT4gZ2V0Q2hpbGRyZW5FbGVtZW50KGgpKTsKICAgIG1ldGhvZHMuZm9yRWFjaCgobWV0aG9kKSA9PiB7CiAgICAgIGNvbnN0IG1ldGhvZE5hbWUgPSBzdHJpcE5hbWVzcGFjZShnZXRFbGVtZW50TmFtZShtZXRob2QpKTsKICAgICAgdXJsc1ttZXRob2ROYW1lXSA9IGdldEVsZW1lbnRBdHRyaWJ1dGUobWV0aG9kLCAieGxpbms6aHJlZiIpOwogICAgfSk7CiAgICByZXR1cm4gdXJsczsKICB9CiAgZnVuY3Rpb24gcGFyc2VGZWF0dXJlVHlwZShmZWF0dXJlVHlwZUVsLCBzZXJ2aWNlVmVyc2lvbiwgZGVmYXVsdE91dHB1dEZvcm1hdHMpIHsKICAgIGNvbnN0IHNyc1RhZyA9IHNlcnZpY2VWZXJzaW9uLnN0YXJ0c1dpdGgoIjIuIikgPyAiQ1JTIiA6ICJTUlMiOwogICAgY29uc3QgZGVmYXVsdFNyc1RhZyA9IHNlcnZpY2VWZXJzaW9uLnN0YXJ0c1dpdGgoIjEuMCIpID8gIlNSUyIgOiBgRGVmYXVsdCR7c3JzVGFnfWA7CiAgICBmdW5jdGlvbiBwYXJzZUJCb3gxMDAoKSB7CiAgICAgIGNvbnN0IGJib3hFbCA9IGZpbmRDaGlsZEVsZW1lbnQoZmVhdHVyZVR5cGVFbCwgIkxhdExvbmdCb3VuZGluZ0JveCIpOwogICAgICByZXR1cm4gWyJtaW54IiwgIm1pbnkiLCAibWF4eCIsICJtYXh5Il0ubWFwKChuYW1lKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGJib3hFbCwgbmFtZSkpLm1hcChwYXJzZUZsb2F0KTsKICAgIH0KICAgIGZ1bmN0aW9uIHBhcnNlQkJveDIoKSB7CiAgICAgIGNvbnN0IGJib3hFbCA9IGZpbmRDaGlsZEVsZW1lbnQoZmVhdHVyZVR5cGVFbCwgIldHUzg0Qm91bmRpbmdCb3giKTsKICAgICAgcmV0dXJuIFsiTG93ZXJDb3JuZXIiLCAiVXBwZXJDb3JuZXIiXS5tYXAoKGVsTmFtZSkgPT4gZmluZENoaWxkRWxlbWVudChiYm94RWwsIGVsTmFtZSkpLm1hcCgoY29ybmVyRWwpID0+IGdldEVsZW1lbnRUZXh0KGNvcm5lckVsKS5zcGxpdCgiICIpKS5yZWR1Y2UoKHByZXYsIGN1cnIpID0+IFsuLi5wcmV2LCAuLi5jdXJyXSkubWFwKHBhcnNlRmxvYXQpOwogICAgfQogICAgY29uc3Qgb3RoZXJDcnMgPSBzZXJ2aWNlVmVyc2lvbi5zdGFydHNXaXRoKCIxLjAiKSA/IFtdIDogZmluZENoaWxkcmVuRWxlbWVudChmZWF0dXJlVHlwZUVsLCBgT3RoZXIke3Nyc1RhZ31gKS5tYXAoZ2V0RWxlbWVudFRleHQpLm1hcChzaW1wbGlmeUVwc2dVcm4pOwogICAgY29uc3Qgb3V0cHV0Rm9ybWF0cyA9IHNlcnZpY2VWZXJzaW9uLnN0YXJ0c1dpdGgoIjEuMCIpID8gW10gOiBmaW5kQ2hpbGRyZW5FbGVtZW50KAogICAgICBmaW5kQ2hpbGRFbGVtZW50KGZlYXR1cmVUeXBlRWwsICJPdXRwdXRGb3JtYXRzIiksCiAgICAgICJGb3JtYXQiCiAgICApLm1hcChnZXRFbGVtZW50VGV4dCk7CiAgICBjb25zdCBrZXl3b3JkcyA9IHNlcnZpY2VWZXJzaW9uLnN0YXJ0c1dpdGgoIjEuMCIpID8gZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChmZWF0dXJlVHlwZUVsLCAiS2V5d29yZHMiKSkuc3BsaXQoIiwiKS5tYXAoKGtleXdvcmQpID0+IGtleXdvcmQudHJpbSgpKSA6IGZpbmRDaGlsZHJlbkVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQoZmVhdHVyZVR5cGVFbCwgIktleXdvcmRzIiksCiAgICAgICJLZXl3b3JkIgogICAgKS5tYXAoZ2V0RWxlbWVudFRleHQpLmZpbHRlcigodiwgaSwgYXJyKSA9PiBhcnIuaW5kZXhPZih2KSA9PT0gaSk7CiAgICBjb25zdCBtZXRhZGF0YSA9IHNlcnZpY2VWZXJzaW9uID09PSAiMi4wLjAiID8gZmluZENoaWxkcmVuRWxlbWVudChmZWF0dXJlVHlwZUVsLCAiTWV0YWRhdGFVUkwiKS5tYXAoCiAgICAgIChtZXRhZGF0YVVybEVsKSA9PiAoewogICAgICAgIHVybDogZ2V0RWxlbWVudEF0dHJpYnV0ZShtZXRhZGF0YVVybEVsLCAieGxpbms6aHJlZiIpCiAgICAgIH0pCiAgICApIDogZmluZENoaWxkcmVuRWxlbWVudChmZWF0dXJlVHlwZUVsLCAiTWV0YWRhdGFVUkwiKS5tYXAoCiAgICAgIChtZXRhZGF0YVVybEVsKSA9PiAoewogICAgICAgIGZvcm1hdDogZ2V0RWxlbWVudEF0dHJpYnV0ZShtZXRhZGF0YVVybEVsLCAiZm9ybWF0IiksCiAgICAgICAgdHlwZTogZ2V0RWxlbWVudEF0dHJpYnV0ZShtZXRhZGF0YVVybEVsLCAidHlwZSIpLAogICAgICAgIHVybDogZ2V0RWxlbWVudFRleHQobWV0YWRhdGFVcmxFbCkudHJpbSgpCiAgICAgIH0pCiAgICApOwogICAgcmV0dXJuIHsKICAgICAgbmFtZTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChmZWF0dXJlVHlwZUVsLCAiTmFtZSIpKSwKICAgICAgdGl0bGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZmVhdHVyZVR5cGVFbCwgIlRpdGxlIikpLAogICAgICBhYnN0cmFjdDogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChmZWF0dXJlVHlwZUVsLCAiQWJzdHJhY3QiKSksCiAgICAgIGRlZmF1bHRDcnM6IHNpbXBsaWZ5RXBzZ1VybigKICAgICAgICBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGZlYXR1cmVUeXBlRWwsIGRlZmF1bHRTcnNUYWcpKQogICAgICApLAogICAgICBvdGhlckNycywKICAgICAgb3V0cHV0Rm9ybWF0czogb3V0cHV0Rm9ybWF0cy5sZW5ndGggPiAwID8gb3V0cHV0Rm9ybWF0cyA6IGRlZmF1bHRPdXRwdXRGb3JtYXRzLAogICAgICBsYXRMb25Cb3VuZGluZ0JveDogc2VydmljZVZlcnNpb24uc3RhcnRzV2l0aCgiMS4wIikgPyBwYXJzZUJCb3gxMDAoKSA6IHBhcnNlQkJveDIoKSwKICAgICAga2V5d29yZHMsCiAgICAgIC4uLm1ldGFkYXRhLmxlbmd0aCAmJiB7IG1ldGFkYXRhIH0KICAgIH07CiAgfQogIGZ1bmN0aW9uIHBhcnNlQkJveCh4bWxFbGVtZW50KSB7CiAgICBjb25zdCByZXN1bHQgPSBbIkxvd2VyQ29ybmVyIiwgIlVwcGVyQ29ybmVyIl0ubWFwKChlbE5hbWUpID0+IGZpbmRDaGlsZEVsZW1lbnQoeG1sRWxlbWVudCwgZWxOYW1lKSkubWFwKChjb3JuZXJFbCkgPT4gZ2V0RWxlbWVudFRleHQoY29ybmVyRWwpLnNwbGl0KCIgIikpLnJlZHVjZSgocHJldiwgY3VycikgPT4gWy4uLnByZXYsIC4uLmN1cnJdKS5tYXAocGFyc2VGbG9hdCk7CiAgICBpZiAocmVzdWx0LnNvbWUoTnVtYmVyLmlzTmFOKSkKICAgICAgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICBmdW5jdGlvbiByZWFkSW5mb0Zyb21DYXBhYmlsaXRpZXMoY2FwYWJpbGl0aWVzRG9jKSB7CiAgICBjb25zdCByb290RWwgPSBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpOwogICAgY29uc3Qgc2VydmljZSA9IGZpbmRDaGlsZEVsZW1lbnQocm9vdEVsLCAiU2VydmljZUlkZW50aWZpY2F0aW9uIik7CiAgICBjb25zdCBrZXl3b3JkcyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIktleXdvcmRzIiksCiAgICAgICJLZXl3b3JkIgogICAgKS5tYXAoZ2V0RWxlbWVudFRleHQpOwogICAgY29uc3QgbWV0YWRhdGEgPSBmaW5kQ2hpbGRFbGVtZW50KHJvb3RFbCwgIk9wZXJhdGlvbnNNZXRhZGF0YSIpOwogICAgY29uc3QgZ2V0VGlsZU9wZXJhdGlvbiA9IGZpbmRDaGlsZHJlbkVsZW1lbnQobWV0YWRhdGEsICJPcGVyYXRpb24iKS5maW5kKAogICAgICAoZWwpID0+IGdldEVsZW1lbnRBdHRyaWJ1dGUoZWwsICJuYW1lIikgPT0gIkdldFRpbGUiCiAgICApOwogICAgY29uc3QgZ2V0VGlsZVVybHMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGdldFRpbGVPcGVyYXRpb24sICJHZXQiLCB0cnVlKS5yZWR1Y2UoCiAgICAgIChwcmV2LCBjdXJyKSA9PiB7CiAgICAgICAgY29uc3QgZW5jb2RpbmdUeXBlID0gZ2V0RWxlbWVudFRleHQoCiAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGN1cnIsICJWYWx1ZSIsIHRydWUpCiAgICAgICAgKTsKICAgICAgICBjb25zdCB1cmwgPSBnZXRFbGVtZW50QXR0cmlidXRlKGN1cnIsICJ4bGluazpocmVmIik7CiAgICAgICAgaWYgKGVuY29kaW5nVHlwZS50b0xvd2VyQ2FzZSgpID09PSAicmVzdGZ1bCIpCiAgICAgICAgICByZXR1cm4geyAuLi5wcmV2LCByZXN0OiB1cmwgfTsKICAgICAgICByZXR1cm4geyAuLi5wcmV2LCBrdnA6IHVybCB9OwogICAgICB9LAogICAgICB7fQogICAgKTsKICAgIHJldHVybiB7CiAgICAgIHRpdGxlOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJUaXRsZSIpKSwKICAgICAgbmFtZTogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzZXJ2aWNlLCAiU2VydmljZVR5cGUiKSksCiAgICAgIGFic3RyYWN0OiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KHNlcnZpY2UsICJBYnN0cmFjdCIpKSwKICAgICAgZmVlczogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChzZXJ2aWNlLCAiRmVlcyIpKSwKICAgICAgY29uc3RyYWludHM6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoc2VydmljZSwgIkFjY2Vzc0NvbnN0cmFpbnRzIikpLAogICAgICBrZXl3b3JkcywKICAgICAgcHJvdmlkZXI6IHJlYWRQcm92aWRlckZyb21DYXBhYmlsaXRpZXMoY2FwYWJpbGl0aWVzRG9jKSwKICAgICAgZ2V0VGlsZVVybHMKICAgIH07CiAgfQogIGZ1bmN0aW9uIHJlYWRNYXRyaXhTZXRzRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpIHsKICAgIGZ1bmN0aW9uIHBhcnNlTWF0cml4U2V0KGVsZW1lbnQpIHsKICAgICAgY29uc3QgdG9wTGVmdCA9IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIlRvcExlZnRDb3JuZXIiKSkuc3BsaXQoIiAiKS5tYXAocGFyc2VGbG9hdCk7CiAgICAgIHJldHVybiB7CiAgICAgICAgaWRlbnRpZmllcjogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50LCAiSWRlbnRpZmllciIpKSwKICAgICAgICB0aWxlV2lkdGg6IHBhcnNlSW50KAogICAgICAgICAgZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50LCAiVGlsZVdpZHRoIikpCiAgICAgICAgKSwKICAgICAgICB0aWxlSGVpZ2h0OiBwYXJzZUludCgKICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIlRpbGVIZWlnaHQiKSkKICAgICAgICApLAogICAgICAgIG1hdHJpeFdpZHRoOiBwYXJzZUludCgKICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIk1hdHJpeFdpZHRoIikpCiAgICAgICAgKSwKICAgICAgICBtYXRyaXhIZWlnaHQ6IHBhcnNlSW50KAogICAgICAgICAgZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50LCAiTWF0cml4SGVpZ2h0IikpCiAgICAgICAgKSwKICAgICAgICBzY2FsZURlbm9taW5hdG9yOiBwYXJzZUZsb2F0KAogICAgICAgICAgZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50LCAiU2NhbGVEZW5vbWluYXRvciIpKQogICAgICAgICksCiAgICAgICAgdG9wTGVmdAogICAgICB9OwogICAgfQogICAgY29uc3QgY29udGVudHMgPSBmaW5kQ2hpbGRFbGVtZW50KAogICAgICBnZXRSb290RWxlbWVudChjYXBhYmlsaXRpZXNEb2MpLAogICAgICAiQ29udGVudHMiCiAgICApOwogICAgY29uc3QgbWF0cml4U2V0cyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoY29udGVudHMsICJUaWxlTWF0cml4U2V0Iik7CiAgICByZXR1cm4gbWF0cml4U2V0cy5tYXAoKGVsZW1lbnQpID0+IHsKICAgICAgY29uc3Qgd2VsbEtub3duU2NhbGVTZXQgPSBnZXRFbGVtZW50VGV4dCgKICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQsICJXZWxsS25vd25TY2FsZVNldCIpCiAgICAgICk7CiAgICAgIGNvbnN0IGJvdW5kaW5nQm94ID0gcGFyc2VCQm94KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIkJvdW5kaW5nQm94IikpOwogICAgICByZXR1cm4gewogICAgICAgIGlkZW50aWZpZXI6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIklkZW50aWZpZXIiKSksCiAgICAgICAgY3JzOiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQsICJTdXBwb3J0ZWRDUlMiKSksCiAgICAgICAgdGlsZU1hdHJpY2VzOiBmaW5kQ2hpbGRyZW5FbGVtZW50KGVsZW1lbnQsICJUaWxlTWF0cml4IikubWFwKAogICAgICAgICAgcGFyc2VNYXRyaXhTZXQKICAgICAgICApLAogICAgICAgIC4uLmJvdW5kaW5nQm94ICYmIHsgYm91bmRpbmdCb3ggfSwKICAgICAgICAuLi53ZWxsS25vd25TY2FsZVNldCAmJiB7IHdlbGxLbm93blNjYWxlU2V0IH0KICAgICAgfTsKICAgIH0pOwogIH0KICBmdW5jdGlvbiByZWFkTGF5ZXJzRnJvbUNhcGFiaWxpdGllcyhjYXBhYmlsaXRpZXNEb2MpIHsKICAgIGNvbnN0IHJvb3RFbCA9IGdldFJvb3RFbGVtZW50KGNhcGFiaWxpdGllc0RvYyk7CiAgICBjb25zdCBjb250ZW50c0VsID0gZmluZENoaWxkRWxlbWVudChyb290RWwsICJDb250ZW50cyIpOwogICAgZnVuY3Rpb24gZ2V0TWF0cml4U2V0Q3JzKGNvbnRlbnRzRWwyLCBpZGVudGlmaWVyKSB7CiAgICAgIGNvbnN0IG1hdHJpeFNldCA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoY29udGVudHNFbDIsICJUaWxlTWF0cml4U2V0IikuZmluZCgKICAgICAgICAobWF0cml4U2V0RWwpID0+IHsKICAgICAgICAgIGNvbnN0IGlkZW50aWZpZXJFbCA9IGZpbmRDaGlsZEVsZW1lbnQobWF0cml4U2V0RWwsICJJZGVudGlmaWVyIik7CiAgICAgICAgICByZXR1cm4gZ2V0RWxlbWVudFRleHQoaWRlbnRpZmllckVsKSA9PT0gaWRlbnRpZmllcjsKICAgICAgICB9CiAgICAgICk7CiAgICAgIHJldHVybiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KG1hdHJpeFNldCwgIlN1cHBvcnRlZENSUyIpKTsKICAgIH0KICAgIGZ1bmN0aW9uIHBhcnNlTWF0cml4U2V0TGluayhlbGVtZW50KSB7CiAgICAgIGNvbnN0IGlkZW50aWZpZXIgPSBnZXRFbGVtZW50VGV4dCgKICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQsICJUaWxlTWF0cml4U2V0IikKICAgICAgKTsKICAgICAgY29uc3QgY3JzID0gZ2V0TWF0cml4U2V0Q3JzKGNvbnRlbnRzRWwsIGlkZW50aWZpZXIpOwogICAgICByZXR1cm4gewogICAgICAgIGlkZW50aWZpZXIsCiAgICAgICAgY3JzLAogICAgICAgIGxpbWl0czogZmluZENoaWxkcmVuRWxlbWVudChlbGVtZW50LCAiVGlsZU1hdHJpeExpbWl0cyIsIHRydWUpLm1hcCgKICAgICAgICAgIChlbGVtZW50MikgPT4gKHsKICAgICAgICAgICAgdGlsZU1hdHJpeDogZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50MiwgIlRpbGVNYXRyaXgiKSksCiAgICAgICAgICAgIG1pblRpbGVSb3c6IHBhcnNlSW50KAogICAgICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJNaW5UaWxlUm93IikpCiAgICAgICAgICAgICksCiAgICAgICAgICAgIG1pblRpbGVDb2w6IHBhcnNlSW50KAogICAgICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJNaW5UaWxlQ29sIikpCiAgICAgICAgICAgICksCiAgICAgICAgICAgIG1heFRpbGVSb3c6IHBhcnNlSW50KAogICAgICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJNYXhUaWxlUm93IikpCiAgICAgICAgICAgICksCiAgICAgICAgICAgIG1heFRpbGVDb2w6IHBhcnNlSW50KAogICAgICAgICAgICAgIGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJNYXhUaWxlQ29sIikpCiAgICAgICAgICAgICkKICAgICAgICAgIH0pCiAgICAgICAgKQogICAgICB9OwogICAgfQogICAgY29uc3QgZ2V0VGlsZU9wZXJhdGlvbiA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoCiAgICAgIGZpbmRDaGlsZEVsZW1lbnQocm9vdEVsLCAiT3BlcmF0aW9uc01ldGFkYXRhIiksCiAgICAgICJPcGVyYXRpb24iCiAgICApLmZpbmQoKGVsKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGVsLCAibmFtZSIpID09ICJHZXRUaWxlIik7CiAgICBjb25zdCBnZXRLdnBFbHQgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGdldFRpbGVPcGVyYXRpb24sICJHZXQiLCB0cnVlKS5maWx0ZXIoCiAgICAgIChlbHQpID0+IHsKICAgICAgICBjb25zdCBlbmNvZGluZ1R5cGUgPSBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGVsdCwgIlZhbHVlIiwgdHJ1ZSkpOwogICAgICAgIHJldHVybiBlbmNvZGluZ1R5cGUudG9Mb3dlckNhc2UoKSA9PT0gImt2cCI7CiAgICAgIH0KICAgIClbMF07CiAgICBjb25zdCBnZXRLdnBVcmwgPSBnZXRLdnBFbHQgPyBnZXRFbGVtZW50QXR0cmlidXRlKGdldEt2cEVsdCwgInhsaW5rOmhyZWYiKSA6ICIiOwogICAgY29uc3QgY29udGVudHMgPSBmaW5kQ2hpbGRFbGVtZW50KHJvb3RFbCwgIkNvbnRlbnRzIik7CiAgICBjb25zdCBsYXllcnMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGNvbnRlbnRzLCAiTGF5ZXIiKTsKICAgIHJldHVybiBsYXllcnMubWFwKChlbGVtZW50KSA9PiB7CiAgICAgIGNvbnN0IGxhdExvbkJvdW5kaW5nQm94ID0gcGFyc2VCQm94KAogICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIldHUzg0Qm91bmRpbmdCb3giKQogICAgICApOwogICAgICBsZXQgZGVmYXVsdFN0eWxlID0gIiI7CiAgICAgIGNvbnN0IHN0eWxlcyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCwgIlN0eWxlIikubWFwKChlbGVtZW50MikgPT4gewogICAgICAgIGNvbnN0IGxlZ2VuZFVybCA9IGdldEVsZW1lbnRBdHRyaWJ1dGUoCiAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQyLCAiTGVnZW5kVVJMIiksCiAgICAgICAgICAieGxpbms6aHJlZiIKICAgICAgICApOwogICAgICAgIGNvbnN0IGFic3RyYWN0ID0gZ2V0RWxlbWVudFRleHQoZmluZENoaWxkRWxlbWVudChlbGVtZW50MiwgIkFic3RyYWN0IikpOwogICAgICAgIGNvbnN0IHN0eWxlID0gewogICAgICAgICAgdGl0bGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJUaXRsZSIpKSwKICAgICAgICAgIG5hbWU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJJZGVudGlmaWVyIikpLAogICAgICAgICAgLi4uYWJzdHJhY3QgJiYgeyBhYnN0cmFjdCB9LAogICAgICAgICAgLi4ubGVnZW5kVXJsICYmIHsgbGVnZW5kVXJsIH0KICAgICAgICB9OwogICAgICAgIGlmIChnZXRFbGVtZW50QXR0cmlidXRlKGVsZW1lbnQyLCAiaXNEZWZhdWx0IikgPT09ICJ0cnVlIikgewogICAgICAgICAgZGVmYXVsdFN0eWxlID0gc3R5bGUubmFtZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0eWxlOwogICAgICB9KTsKICAgICAgY29uc3Qgb3V0cHV0Rm9ybWF0cyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCwgIkZvcm1hdCIpLm1hcCgKICAgICAgICBnZXRFbGVtZW50VGV4dAogICAgICApOwogICAgICBjb25zdCByZXNvdXJjZUxpbmtzID0gZmluZENoaWxkcmVuRWxlbWVudCgKICAgICAgICBlbGVtZW50LAogICAgICAgICJSZXNvdXJjZVVSTCIKICAgICAgKS5maWx0ZXIoCiAgICAgICAgKGVsZW1lbnQyKSA9PiBnZXRFbGVtZW50QXR0cmlidXRlKGVsZW1lbnQyLCAicmVzb3VyY2VUeXBlIikgPT09ICJ0aWxlIgogICAgICApLm1hcCgoZWxlbWVudDIpID0+IHsKICAgICAgICBjb25zdCBmb3JtYXQgPSBnZXRFbGVtZW50QXR0cmlidXRlKGVsZW1lbnQyLCAiZm9ybWF0Iik7CiAgICAgICAgY29uc3QgdXJsID0gZ2V0RWxlbWVudEF0dHJpYnV0ZShlbGVtZW50MiwgInRlbXBsYXRlIik7CiAgICAgICAgcmV0dXJuIHsgZm9ybWF0LCB1cmwsIGVuY29kaW5nOiAiUkVTVCIgfTsKICAgICAgfSk7CiAgICAgIGlmIChnZXRLdnBVcmwpIHsKICAgICAgICByZXNvdXJjZUxpbmtzLnB1c2goCiAgICAgICAgICAuLi5vdXRwdXRGb3JtYXRzLm1hcCgoZm9ybWF0KSA9PiAoewogICAgICAgICAgICBlbmNvZGluZzogIktWUCIsCiAgICAgICAgICAgIHVybDogZ2V0S3ZwVXJsLAogICAgICAgICAgICBmb3JtYXQKICAgICAgICAgIH0pKQogICAgICAgICk7CiAgICAgIH0KICAgICAgY29uc3QgbWF0cml4U2V0cyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoZWxlbWVudCwgIlRpbGVNYXRyaXhTZXRMaW5rIikubWFwKAogICAgICAgIHBhcnNlTWF0cml4U2V0TGluawogICAgICApOwogICAgICBjb25zdCBkaW1lbnNpb25zID0gZmluZENoaWxkcmVuRWxlbWVudChlbGVtZW50LCAiRGltZW5zaW9uIikubWFwKAogICAgICAgIChlbGVtZW50MikgPT4gewogICAgICAgICAgY29uc3QgaWRlbnRpZmllciA9IGdldEVsZW1lbnRUZXh0KAogICAgICAgICAgICBmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQyLCAiSWRlbnRpZmllciIpCiAgICAgICAgICApOwogICAgICAgICAgY29uc3QgZGVmYXVsdFZhbHVlID0gZ2V0RWxlbWVudFRleHQoCiAgICAgICAgICAgIGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudDIsICJEZWZhdWx0IikKICAgICAgICAgICk7CiAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBmaW5kQ2hpbGRyZW5FbGVtZW50KGVsZW1lbnQyLCAiVmFsdWVzIikubWFwKAogICAgICAgICAgICBnZXRFbGVtZW50VGV4dAogICAgICAgICAgKTsKICAgICAgICAgIHJldHVybiB7IGlkZW50aWZpZXIsIGRlZmF1bHRWYWx1ZSwgdmFsdWVzIH07CiAgICAgICAgfQogICAgICApOwogICAgICByZXR1cm4gewogICAgICAgIG5hbWU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIklkZW50aWZpZXIiKSksCiAgICAgICAgdGl0bGU6IGdldEVsZW1lbnRUZXh0KGZpbmRDaGlsZEVsZW1lbnQoZWxlbWVudCwgIlRpdGxlIikpLAogICAgICAgIGFic3RyYWN0OiBnZXRFbGVtZW50VGV4dChmaW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQsICJBYnN0cmFjdCIpKSwKICAgICAgICBzdHlsZXMsCiAgICAgICAgcmVzb3VyY2VMaW5rcywKICAgICAgICBtYXRyaXhTZXRzLAogICAgICAgIGRlZmF1bHRTdHlsZSwKICAgICAgICAuLi5sYXRMb25Cb3VuZGluZ0JveCAmJiB7IGxhdExvbkJvdW5kaW5nQm94IH0sCiAgICAgICAgLi4uZGltZW5zaW9ucyAmJiB7IGRpbWVuc2lvbnMgfQogICAgICB9OwogICAgfSk7CiAgfQogIGZ1bmN0aW9uIHBhcnNlRmVhdHVyZVByb3BzKGdldEZlYXR1cmVzRG9jLCBmZWF0dXJlVHlwZUZ1bGwsIHNlcnZpY2VWZXJzaW9uKSB7CiAgICBjb25zdCBjb2xsZWN0aW9uID0gZ2V0Um9vdEVsZW1lbnQoZ2V0RmVhdHVyZXNEb2MpOwogICAgbGV0IG1lbWJlcnM7CiAgICBpZiAoc2VydmljZVZlcnNpb24uc3RhcnRzV2l0aCgiMi4wIikpIHsKICAgICAgbWVtYmVycyA9IGZpbmRDaGlsZHJlbkVsZW1lbnQoY29sbGVjdGlvbiwgIm1lbWJlciIpLm1hcCgKICAgICAgICAocGFyZW50KSA9PiBnZXRDaGlsZHJlbkVsZW1lbnQocGFyZW50KVswXQogICAgICApOwogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbWVtYmVyc1Jvb3QgPSBmaW5kQ2hpbGRFbGVtZW50KGNvbGxlY3Rpb24sICJmZWF0dXJlTWVtYmVycyIpOwogICAgICBtZW1iZXJzID0gbWVtYmVyc1Jvb3QgPyBnZXRDaGlsZHJlbkVsZW1lbnQobWVtYmVyc1Jvb3QpIDogZmluZENoaWxkcmVuRWxlbWVudChjb2xsZWN0aW9uLCAiZmVhdHVyZU1lbWJlciIpLm1hcCgKICAgICAgICAocGFyZW50KSA9PiBnZXRDaGlsZHJlbkVsZW1lbnQocGFyZW50KVswXQogICAgICApOwogICAgfQogICAgY29uc3QgaWRBdHRyID0gc2VydmljZVZlcnNpb24gPT09ICIxLjAuMCIgPyAiZmlkIiA6ICJnbWw6aWQiOwogICAgZnVuY3Rpb24gaXNFbGVtZW50UHJvcGVydHkocHJvcE5hbWUpIHsKICAgICAgcmV0dXJuIHByb3BOYW1lIGluIGZlYXR1cmVUeXBlRnVsbC5wcm9wZXJ0aWVzOwogICAgfQogICAgZnVuY3Rpb24gcGFyc2VFbGVtZW50UHJvcGVydHlWYWx1ZShwcm9wTmFtZSwgdmFsdWVBc1N0cmluZykgewogICAgICBjb25zdCB0eXBlID0gZmVhdHVyZVR5cGVGdWxsLnByb3BlcnRpZXNbcHJvcE5hbWVdOwogICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlICJpbnRlZ2VyIjoKICAgICAgICAgIHJldHVybiBwYXJzZUludCh2YWx1ZUFzU3RyaW5nKTsKICAgICAgICBjYXNlICJmbG9hdCI6CiAgICAgICAgICByZXR1cm4gcGFyc2VGbG9hdCh2YWx1ZUFzU3RyaW5nKTsKICAgICAgICBjYXNlICJib29sZWFuIjoKICAgICAgICAgIHJldHVybiB2YWx1ZUFzU3RyaW5nID09PSAidHJ1ZSI7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHJldHVybiB2YWx1ZUFzU3RyaW5nOwogICAgICB9CiAgICB9CiAgICBmdW5jdGlvbiBnZXRQcm9wZXJ0aWVzKG1lbWJlckVsKSB7CiAgICAgIHJldHVybiBnZXRDaGlsZHJlbkVsZW1lbnQobWVtYmVyRWwpLmZpbHRlcigoZWwpID0+IGlzRWxlbWVudFByb3BlcnR5KHN0cmlwTmFtZXNwYWNlKGdldEVsZW1lbnROYW1lKGVsKSkpKS5yZWR1Y2UoKHByZXYsIGN1cnIpID0+IHsKICAgICAgICBjb25zdCBwcm9wTmFtZSA9IHN0cmlwTmFtZXNwYWNlKGdldEVsZW1lbnROYW1lKGN1cnIpKTsKICAgICAgICByZXR1cm4gewogICAgICAgICAgLi4ucHJldiwKICAgICAgICAgIFtwcm9wTmFtZV06IHBhcnNlRWxlbWVudFByb3BlcnR5VmFsdWUocHJvcE5hbWUsIGdldEVsZW1lbnRUZXh0KGN1cnIpKQogICAgICAgIH07CiAgICAgIH0sIHt9KTsKICAgIH0KICAgIHJldHVybiBtZW1iZXJzLm1hcCgoZWwpID0+ICh7CiAgICAgIGlkOiBnZXRFbGVtZW50QXR0cmlidXRlKGVsLCBpZEF0dHIpLAogICAgICBwcm9wZXJ0aWVzOiBnZXRQcm9wZXJ0aWVzKGVsKQogICAgfSkpOwogIH0KICBmdW5jdGlvbiBjb21wdXRlRmVhdHVyZVByb3BzRGV0YWlscyhmZWF0dXJlc1dpdGhQcm9wcykgewogICAgcmV0dXJuIGZlYXR1cmVzV2l0aFByb3BzLnJlZHVjZSgocHJldiwgY3VycikgPT4gewogICAgICBmb3IgKGNvbnN0IHByb3BOYW1lIGluIGN1cnIucHJvcGVydGllcykgewogICAgICAgIGNvbnN0IHByb3BWYWx1ZSA9IGN1cnIucHJvcGVydGllc1twcm9wTmFtZV07CiAgICAgICAgaWYgKCEocHJvcE5hbWUgaW4gcHJldikpIHsKICAgICAgICAgIHByZXZbcHJvcE5hbWVdID0geyB1bmlxdWVWYWx1ZXM6IFtdIH07CiAgICAgICAgfQogICAgICAgIGNvbnN0IHVuaXF1ZVZhbHVlID0gcHJldltwcm9wTmFtZV0udW5pcXVlVmFsdWVzLmZpbmQoCiAgICAgICAgICAodikgPT4gdi52YWx1ZSA9PT0gcHJvcFZhbHVlCiAgICAgICAgKTsKICAgICAgICBpZiAodW5pcXVlVmFsdWUpCiAgICAgICAgICB1bmlxdWVWYWx1ZS5jb3VudCsrOwogICAgICAgIGVsc2UKICAgICAgICAgIHByZXZbcHJvcE5hbWVdLnVuaXF1ZVZhbHVlcy5wdXNoKHsgdmFsdWU6IHByb3BWYWx1ZSwgY291bnQ6IDEgfSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHByZXY7CiAgICB9LCB7fSk7CiAgfQogIGZ1bmN0aW9uIGdlbmVyYXRlR2V0RmVhdHVyZVVybChzZXJ2aWNlVXJsLCB2ZXJzaW9uLCBmZWF0dXJlVHlwZSwgb3V0cHV0Rm9ybWF0LCBtYXhGZWF0dXJlcywgYXR0cmlidXRlcywgaGl0c09ubHksIG91dHB1dENycywgZXh0ZW50LCBleHRlbnRDcnMsIHN0YXJ0SW5kZXgsIHNvcnRCeSkgewogICAgY29uc3QgdHlwZVBhcmFtID0gdmVyc2lvbiA9PT0gIjIuMC4wIiA/ICJUWVBFTkFNRVMiIDogIlRZUEVOQU1FIjsKICAgIGNvbnN0IGNvdW50UGFyYW0gPSB2ZXJzaW9uID09PSAiMi4wLjAiID8gIkNPVU5UIiA6ICJNQVhGRUFUVVJFUyI7CiAgICBjb25zdCBuZXdQYXJhbXMgPSB7CiAgICAgIFNFUlZJQ0U6ICJXRlMiLAogICAgICBSRVFVRVNUOiAiR2V0RmVhdHVyZSIsCiAgICAgIFZFUlNJT046IHZlcnNpb24sCiAgICAgIFt0eXBlUGFyYW1dOiBmZWF0dXJlVHlwZQogICAgfTsKICAgIGlmIChvdXRwdXRGb3JtYXQgIT09IHZvaWQgMCkKICAgICAgbmV3UGFyYW1zLk9VVFBVVEZPUk1BVCA9IG91dHB1dEZvcm1hdDsKICAgIGlmIChhdHRyaWJ1dGVzICE9PSB2b2lkIDApCiAgICAgIG5ld1BhcmFtcy5QUk9QRVJUWU5BTUUgPSBhdHRyaWJ1dGVzLmpvaW4oIiwiKTsKICAgIGlmIChoaXRzT25seSkgewogICAgICBuZXdQYXJhbXMuUkVTVUxUVFlQRSA9ICJoaXRzIjsKICAgICAgbmV3UGFyYW1zW2NvdW50UGFyYW1dID0gIjEiOwogICAgfSBlbHNlIGlmIChtYXhGZWF0dXJlcyAhPT0gdm9pZCAwKQogICAgICBuZXdQYXJhbXNbY291bnRQYXJhbV0gPSBtYXhGZWF0dXJlcy50b1N0cmluZygxMCk7CiAgICBpZiAob3V0cHV0Q3JzKSB7CiAgICAgIG5ld1BhcmFtcy5TUlNOQU1FID0gb3V0cHV0Q3JzOwogICAgfQogICAgaWYgKGV4dGVudCkgewogICAgICBjb25zdCBleHRlbnRKb2luZWQgPSBleHRlbnQuam9pbigiLCIpOwogICAgICBuZXdQYXJhbXMuQkJPWCA9IGV4dGVudENycyA/IGAke2V4dGVudEpvaW5lZH0sJHtleHRlbnRDcnN9YCA6IGV4dGVudEpvaW5lZDsKICAgIH0KICAgIGlmIChzdGFydEluZGV4KSB7CiAgICAgIG5ld1BhcmFtcy5TVEFSVElOREVYID0gc3RhcnRJbmRleC50b1N0cmluZygxMCk7CiAgICB9CiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHNldFF1ZXJ5UGFyYW1zKHNlcnZpY2VVcmwsIG5ld1BhcmFtcykpOwogICAgaWYgKEFycmF5LmlzQXJyYXkoc29ydEJ5KSAmJiBzb3J0QnkubGVuZ3RoID4gMCkgewogICAgICBjb25zdCBzb3J0cyA9IHNvcnRCeS5tYXAoKGZpZWxkU29ydCkgPT4gYCR7ZmllbGRTb3J0WzFdfSAke2ZpZWxkU29ydFswXX1gKS5qb2luKCIsIik7CiAgICAgIHVybC5zZWFyY2hQYXJhbXMuc2V0KCJTT1JUQlkiLCBzb3J0cyk7CiAgICB9CiAgICByZXR1cm4gdXJsLnRvU3RyaW5nKCk7CiAgfQogIGFkZFRhc2tIYW5kbGVyKAogICAgInBhcnNlV21zQ2FwYWJpbGl0aWVzIiwKICAgIGdsb2JhbFRoaXMsCiAgICAoeyB1cmwgfSkgPT4gcXVlcnlYbWxEb2N1bWVudCh1cmwpLnRoZW4oKHhtbERvYykgPT4gY2hlY2soeG1sRG9jLCB1cmwpKS50aGVuKCh4bWxEb2MpID0+ICh7CiAgICAgIGluZm86IHJlYWRJbmZvRnJvbUNhcGFiaWxpdGllcyQyKHhtbERvYyksCiAgICAgIGxheWVyczogcmVhZExheWVyc0Zyb21DYXBhYmlsaXRpZXMkMSh4bWxEb2MpLAogICAgICB1cmw6IHJlYWRPcGVyYXRpb25VcmxzRnJvbUNhcGFiaWxpdGllcyQxKHhtbERvYyksCiAgICAgIHZlcnNpb246IHJlYWRWZXJzaW9uRnJvbUNhcGFiaWxpdGllcyQxKHhtbERvYykKICAgIH0pKQogICk7CiAgYWRkVGFza0hhbmRsZXIoCiAgICAicGFyc2VXZnNDYXBhYmlsaXRpZXMiLAogICAgZ2xvYmFsVGhpcywKICAgICh7IHVybCB9KSA9PiBxdWVyeVhtbERvY3VtZW50KHVybCkudGhlbigoeG1sRG9jKSA9PiBjaGVjayh4bWxEb2MsIHVybCkpLnRoZW4oKHhtbERvYykgPT4gKHsKICAgICAgaW5mbzogcmVhZEluZm9Gcm9tQ2FwYWJpbGl0aWVzJDEoeG1sRG9jKSwKICAgICAgZmVhdHVyZVR5cGVzOiByZWFkRmVhdHVyZVR5cGVzRnJvbUNhcGFiaWxpdGllcyh4bWxEb2MpLAogICAgICB1cmw6IHJlYWRPcGVyYXRpb25VcmxzRnJvbUNhcGFiaWxpdGllcyh4bWxEb2MpLAogICAgICB2ZXJzaW9uOiByZWFkVmVyc2lvbkZyb21DYXBhYmlsaXRpZXMoeG1sRG9jKQogICAgfSkpCiAgKTsKICBhZGRUYXNrSGFuZGxlcigKICAgICJxdWVyeVdmc0ZlYXR1cmVUeXBlRGV0YWlscyIsCiAgICBnbG9iYWxUaGlzLAogICAgKHsKICAgICAgdXJsLAogICAgICBzZXJ2aWNlVmVyc2lvbiwKICAgICAgZmVhdHVyZVR5cGVGdWxsCiAgICB9KSA9PiB7CiAgICAgIGNvbnN0IGdldEZlYXR1cmVVcmwgPSBnZW5lcmF0ZUdldEZlYXR1cmVVcmwoCiAgICAgICAgdXJsLAogICAgICAgIHNlcnZpY2VWZXJzaW9uLAogICAgICAgIGZlYXR1cmVUeXBlRnVsbC5uYW1lLAogICAgICAgIHZvaWQgMCwKICAgICAgICB2b2lkIDAsCiAgICAgICAgT2JqZWN0LmtleXMoZmVhdHVyZVR5cGVGdWxsLnByb3BlcnRpZXMpCiAgICAgICk7CiAgICAgIHJldHVybiBxdWVyeVhtbERvY3VtZW50KGdldEZlYXR1cmVVcmwpLnRoZW4oKGdldEZlYXR1cmVEb2MpID0+ICh7CiAgICAgICAgcHJvcHM6IGNvbXB1dGVGZWF0dXJlUHJvcHNEZXRhaWxzKAogICAgICAgICAgcGFyc2VGZWF0dXJlUHJvcHMoZ2V0RmVhdHVyZURvYywgZmVhdHVyZVR5cGVGdWxsLCBzZXJ2aWNlVmVyc2lvbikKICAgICAgICApCiAgICAgIH0pKTsKICAgIH0KICApOwogIGFkZFRhc2tIYW5kbGVyKAogICAgInVwZGF0ZUZldGNoT3B0aW9ucyIsCiAgICBnbG9iYWxUaGlzLAogICAgKHsgb3B0aW9ucyB9KSA9PiB7CiAgICAgIHNldEZldGNoT3B0aW9ucyhvcHRpb25zKTsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7CiAgICB9CiAgKTsKICBhZGRUYXNrSGFuZGxlcigKICAgICJwYXJzZVdtdHNDYXBhYmlsaXRpZXMiLAogICAgZ2xvYmFsVGhpcywKICAgICh7IHVybCB9KSA9PiBxdWVyeVhtbERvY3VtZW50KHVybCkudGhlbigoeG1sRG9jKSA9PiBjaGVjayh4bWxEb2MsIHVybCkpLnRoZW4oKHhtbERvYykgPT4gKHsKICAgICAgaW5mbzogcmVhZEluZm9Gcm9tQ2FwYWJpbGl0aWVzKHhtbERvYyksCiAgICAgIGxheWVyczogcmVhZExheWVyc0Zyb21DYXBhYmlsaXRpZXMoeG1sRG9jKSwKICAgICAgbWF0cml4U2V0czogcmVhZE1hdHJpeFNldHNGcm9tQ2FwYWJpbGl0aWVzKHhtbERvYykKICAgIH0pKQogICk7Cn0pKCk7Ci8vIyBzb3VyY2VNYXBwaW5nVVJMPXdvcmtlci1MRGtNT3gwZC5qcy5tYXAK", { name: e?.name });
|
|
562
|
+
} finally {
|
|
563
|
+
t && (window.URL || window.webkitURL).revokeObjectURL(t);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
var he = !1, ge;
|
|
567
|
+
function _e() {
|
|
568
|
+
return he ? null : (ge ||= new me(), ge);
|
|
569
|
+
}
|
|
570
|
+
function ve(e) {
|
|
571
|
+
return fe("parseWmsCapabilities", _e(), { url: e });
|
|
572
|
+
}
|
|
573
|
+
function ye(e) {
|
|
574
|
+
return fe("parseWfsCapabilities", _e(), { url: e });
|
|
575
|
+
}
|
|
576
|
+
function be(e, t, n) {
|
|
577
|
+
return fe("queryWfsFeatureTypeDetails", _e(), {
|
|
578
|
+
url: e,
|
|
579
|
+
serviceVersion: t,
|
|
580
|
+
featureTypeFull: n
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
function xe(e) {
|
|
584
|
+
return fe("parseWmtsCapabilities", _e(), { url: e });
|
|
585
|
+
}
|
|
586
|
+
//#endregion
|
|
587
|
+
//#region node_modules/@camptocamp/ogc-client/dist/shared/xml-utils.js
|
|
588
|
+
var Se = (/* @__PURE__ */ e(((e, t) => {
|
|
589
|
+
var n = Object.defineProperty, r = Object.getOwnPropertyDescriptor, i = Object.getOwnPropertyNames, a = Object.prototype.hasOwnProperty, o = (e, t) => {
|
|
590
|
+
for (var r in t) n(e, r, {
|
|
591
|
+
get: t[r],
|
|
592
|
+
enumerable: !0
|
|
593
|
+
});
|
|
594
|
+
}, s = (e, t, o, s) => {
|
|
595
|
+
if (t && typeof t == "object" || typeof t == "function") for (let c of i(t)) !a.call(e, c) && c !== o && n(e, c, {
|
|
596
|
+
get: () => t[c],
|
|
597
|
+
enumerable: !(s = r(t, c)) || s.enumerable
|
|
598
|
+
});
|
|
599
|
+
return e;
|
|
600
|
+
}, c = (e) => s(n({}, "__esModule", { value: !0 }), e), l = {};
|
|
601
|
+
o(l, {
|
|
602
|
+
XmlCdata: () => E,
|
|
603
|
+
XmlComment: () => D,
|
|
604
|
+
XmlDeclaration: () => O,
|
|
605
|
+
XmlDocument: () => A,
|
|
606
|
+
XmlDocumentType: () => ee,
|
|
607
|
+
XmlElement: () => k,
|
|
608
|
+
XmlError: () => te,
|
|
609
|
+
XmlNode: () => w,
|
|
610
|
+
XmlProcessingInstruction: () => j,
|
|
611
|
+
XmlText: () => T,
|
|
612
|
+
parseXml: () => re
|
|
613
|
+
}), t.exports = c(l);
|
|
614
|
+
var u = "", d = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, f = class {
|
|
615
|
+
constructor(e) {
|
|
616
|
+
if (this.k = this.u(e, !0), this.d = 0, this.length = e.length, this.l = this.k !== this.length, this.h = e, this.l) {
|
|
617
|
+
let t = [];
|
|
618
|
+
for (let n = 0, r = 0; r < this.k; ++r) t[r] = n, n += e.codePointAt(n) > 65535 ? 2 : 1;
|
|
619
|
+
this.A = t;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
get B() {
|
|
623
|
+
return this.d >= this.k;
|
|
624
|
+
}
|
|
625
|
+
u(e, t = this.l) {
|
|
626
|
+
return t ? e.replace(d, "_").length : e.length;
|
|
627
|
+
}
|
|
628
|
+
p(e = 1) {
|
|
629
|
+
this.d = Math.min(this.k, this.d + e);
|
|
630
|
+
}
|
|
631
|
+
f(e = this.d) {
|
|
632
|
+
return this.l ? this.A[e] ?? Infinity : e;
|
|
633
|
+
}
|
|
634
|
+
G(e = 1) {
|
|
635
|
+
let t = this.m(e);
|
|
636
|
+
return this.p(e), t;
|
|
637
|
+
}
|
|
638
|
+
v(e) {
|
|
639
|
+
let t = this.f(), n = this.h.slice(t, t + e);
|
|
640
|
+
return this.p(this.u(n)), n;
|
|
641
|
+
}
|
|
642
|
+
w(e) {
|
|
643
|
+
let { length: t, l: n, h: r } = this, i = this.f(), a = i;
|
|
644
|
+
if (n) for (; a < t;) {
|
|
645
|
+
let t = r[a], n = t >= "\ud800" && t <= "\udbff";
|
|
646
|
+
if (n && (t += r[a + 1]), !e(t)) break;
|
|
647
|
+
a += n ? 2 : 1;
|
|
648
|
+
}
|
|
649
|
+
else for (; a < t && e(r[a]);) ++a;
|
|
650
|
+
return this.v(a - i);
|
|
651
|
+
}
|
|
652
|
+
b(e) {
|
|
653
|
+
let { length: t } = e, n = this.f();
|
|
654
|
+
return e === this.h.slice(n, n + t) ? (this.p(t === 1 ? 1 : this.u(e)), e) : u;
|
|
655
|
+
}
|
|
656
|
+
x(e) {
|
|
657
|
+
let t = this.h.slice(this.f()).search(e);
|
|
658
|
+
return t > 0 ? this.v(t) : u;
|
|
659
|
+
}
|
|
660
|
+
s(e) {
|
|
661
|
+
let t = this.f(), n = this.h.indexOf(e, t);
|
|
662
|
+
return n > 0 ? this.v(n - t) : u;
|
|
663
|
+
}
|
|
664
|
+
m(e = 1) {
|
|
665
|
+
let { d: t, h: n } = this;
|
|
666
|
+
return this.l ? n.slice(this.f(t), this.f(t + e)) : n.slice(t, t + e);
|
|
667
|
+
}
|
|
668
|
+
n(e = 0) {
|
|
669
|
+
this.d = e >= 0 ? Math.min(this.k, e) : Math.max(0, this.d + e);
|
|
670
|
+
}
|
|
671
|
+
}, p = /["&<]/, m = /['&<]/, h = /\r\n|[\n\r\t]/g, g = /<|&|]]>/, _ = Object.freeze(Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
672
|
+
amp: "&",
|
|
673
|
+
apos: "'",
|
|
674
|
+
gt: ">",
|
|
675
|
+
lt: "<",
|
|
676
|
+
quot: "\""
|
|
677
|
+
}));
|
|
678
|
+
function v(e) {
|
|
679
|
+
let t = e.codePointAt(0);
|
|
680
|
+
return t >= 97 && t <= 122 || t >= 65 && t <= 90 || t >= 48 && t <= 57 || t === 45 || t === 46 || t === 183 || t >= 768 && t <= 879 || t === 8255 || t === 8256 || y(e, t);
|
|
681
|
+
}
|
|
682
|
+
function y(e, t = e.codePointAt(0)) {
|
|
683
|
+
return t >= 97 && t <= 122 || t >= 65 && t <= 90 || t === 58 || t === 95 || t >= 192 && t <= 214 || t >= 216 && t <= 246 || t >= 248 && t <= 767 || t >= 880 && t <= 893 || t >= 895 && t <= 8191 || t === 8204 || t === 8205 || t >= 8304 && t <= 8591 || t >= 11264 && t <= 12271 || t >= 12289 && t <= 55295 || t >= 63744 && t <= 64975 || t >= 65008 && t <= 65533 || t >= 65536 && t <= 983039;
|
|
684
|
+
}
|
|
685
|
+
function b(e) {
|
|
686
|
+
return e === "#" || v(e);
|
|
687
|
+
}
|
|
688
|
+
function x(e) {
|
|
689
|
+
let t = e.codePointAt(0);
|
|
690
|
+
return t === 32 || t === 9 || t === 10 || t === 13;
|
|
691
|
+
}
|
|
692
|
+
function S(e) {
|
|
693
|
+
return e >= 32 && e <= 55295 || e === 10 || e === 9 || e === 13 || e >= 57344 && e <= 65533 || e >= 65536 && e <= 1114111;
|
|
694
|
+
}
|
|
695
|
+
var C = class e {
|
|
696
|
+
constructor() {
|
|
697
|
+
this.parent = null, this.start = -1, this.end = -1;
|
|
698
|
+
}
|
|
699
|
+
get document() {
|
|
700
|
+
return this.parent?.document ?? null;
|
|
701
|
+
}
|
|
702
|
+
get isRootNode() {
|
|
703
|
+
return this.parent !== null && this.parent === this.document && this.type === e.TYPE_ELEMENT;
|
|
704
|
+
}
|
|
705
|
+
get preserveWhitespace() {
|
|
706
|
+
return !!this.parent?.preserveWhitespace;
|
|
707
|
+
}
|
|
708
|
+
get type() {
|
|
709
|
+
return "";
|
|
710
|
+
}
|
|
711
|
+
toJSON() {
|
|
712
|
+
let e = { type: this.type };
|
|
713
|
+
return this.isRootNode && (e.isRootNode = !0), this.preserveWhitespace && (e.preserveWhitespace = !0), this.start !== -1 && (e.start = this.start, e.end = this.end), e;
|
|
714
|
+
}
|
|
715
|
+
};
|
|
716
|
+
C.TYPE_CDATA = "cdata", C.TYPE_COMMENT = "comment", C.TYPE_DOCUMENT = "document", C.TYPE_DOCUMENT_TYPE = "doctype", C.TYPE_ELEMENT = "element", C.TYPE_PROCESSING_INSTRUCTION = "pi", C.TYPE_TEXT = "text", C.TYPE_XML_DECLARATION = "xmldecl";
|
|
717
|
+
var w = C, T = class extends w {
|
|
718
|
+
constructor(e = "") {
|
|
719
|
+
super(), this.text = e;
|
|
720
|
+
}
|
|
721
|
+
get type() {
|
|
722
|
+
return w.TYPE_TEXT;
|
|
723
|
+
}
|
|
724
|
+
toJSON() {
|
|
725
|
+
return Object.assign(w.prototype.toJSON.call(this), { text: this.text });
|
|
726
|
+
}
|
|
727
|
+
}, E = class extends T {
|
|
728
|
+
get type() {
|
|
729
|
+
return w.TYPE_CDATA;
|
|
730
|
+
}
|
|
731
|
+
}, D = class extends w {
|
|
732
|
+
constructor(e = "") {
|
|
733
|
+
super(), this.content = e;
|
|
734
|
+
}
|
|
735
|
+
get type() {
|
|
736
|
+
return w.TYPE_COMMENT;
|
|
737
|
+
}
|
|
738
|
+
toJSON() {
|
|
739
|
+
return Object.assign(w.prototype.toJSON.call(this), { content: this.content });
|
|
740
|
+
}
|
|
741
|
+
}, O = class extends w {
|
|
742
|
+
constructor(e, t, n) {
|
|
743
|
+
super(), this.version = e, this.encoding = t ?? null, this.standalone = n ?? null;
|
|
744
|
+
}
|
|
745
|
+
get type() {
|
|
746
|
+
return w.TYPE_XML_DECLARATION;
|
|
747
|
+
}
|
|
748
|
+
toJSON() {
|
|
749
|
+
let e = w.prototype.toJSON.call(this);
|
|
750
|
+
e.version = this.version;
|
|
751
|
+
for (let t of ["encoding", "standalone"]) this[t] !== null && (e[t] = this[t]);
|
|
752
|
+
return e;
|
|
753
|
+
}
|
|
754
|
+
}, k = class e extends w {
|
|
755
|
+
constructor(e, t = /* @__PURE__ */ Object.create(null), n = []) {
|
|
756
|
+
super(), this.name = e, this.attributes = t, this.children = n;
|
|
757
|
+
}
|
|
758
|
+
get isEmpty() {
|
|
759
|
+
return this.children.length === 0;
|
|
760
|
+
}
|
|
761
|
+
get preserveWhitespace() {
|
|
762
|
+
let t = this;
|
|
763
|
+
for (; t instanceof e;) {
|
|
764
|
+
if ("xml:space" in t.attributes) return t.attributes["xml:space"] === "preserve";
|
|
765
|
+
t = t.parent;
|
|
766
|
+
}
|
|
767
|
+
return !1;
|
|
768
|
+
}
|
|
769
|
+
get text() {
|
|
770
|
+
return this.children.map((e) => "text" in e ? e.text : "").join("");
|
|
771
|
+
}
|
|
772
|
+
get type() {
|
|
773
|
+
return w.TYPE_ELEMENT;
|
|
774
|
+
}
|
|
775
|
+
toJSON() {
|
|
776
|
+
return Object.assign(w.prototype.toJSON.call(this), {
|
|
777
|
+
name: this.name,
|
|
778
|
+
attributes: this.attributes,
|
|
779
|
+
children: this.children.map((e) => e.toJSON())
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
}, A = class extends w {
|
|
783
|
+
constructor(e = []) {
|
|
784
|
+
super(), this.children = e;
|
|
785
|
+
}
|
|
786
|
+
get document() {
|
|
787
|
+
return this;
|
|
788
|
+
}
|
|
789
|
+
get root() {
|
|
790
|
+
for (let e of this.children) if (e instanceof k) return e;
|
|
791
|
+
return null;
|
|
792
|
+
}
|
|
793
|
+
get text() {
|
|
794
|
+
return this.children.map((e) => "text" in e ? e.text : "").join("");
|
|
795
|
+
}
|
|
796
|
+
get type() {
|
|
797
|
+
return w.TYPE_DOCUMENT;
|
|
798
|
+
}
|
|
799
|
+
toJSON() {
|
|
800
|
+
return Object.assign(w.prototype.toJSON.call(this), { children: this.children.map((e) => e.toJSON()) });
|
|
801
|
+
}
|
|
802
|
+
}, ee = class extends w {
|
|
803
|
+
constructor(e, t, n, r) {
|
|
804
|
+
super(), this.name = e, this.publicId = t ?? null, this.systemId = n ?? null, this.internalSubset = r ?? null;
|
|
805
|
+
}
|
|
806
|
+
get type() {
|
|
807
|
+
return w.TYPE_DOCUMENT_TYPE;
|
|
808
|
+
}
|
|
809
|
+
toJSON() {
|
|
810
|
+
let e = w.prototype.toJSON.call(this);
|
|
811
|
+
e.name = this.name;
|
|
812
|
+
for (let t of [
|
|
813
|
+
"publicId",
|
|
814
|
+
"systemId",
|
|
815
|
+
"internalSubset"
|
|
816
|
+
]) this[t] !== null && (e[t] = this[t]);
|
|
817
|
+
return e;
|
|
818
|
+
}
|
|
819
|
+
}, te = class extends Error {
|
|
820
|
+
constructor(e, t, n) {
|
|
821
|
+
let r = 1, i = "", a = 1;
|
|
822
|
+
for (let e = 0; e < t; ++e) {
|
|
823
|
+
let t = n[e];
|
|
824
|
+
t === "\n" ? (r = 1, i = "", a += 1) : (r += 1, i += t);
|
|
825
|
+
}
|
|
826
|
+
let o = n.indexOf("\n", t);
|
|
827
|
+
i += o === -1 ? n.slice(t) : n.slice(t, o);
|
|
828
|
+
let s = 0;
|
|
829
|
+
i.length > 50 && (r < 40 ? i = i.slice(0, 50) : (s = r - 20, i = i.slice(s, r + 30))), super(`${e} (line ${a}, column ${r})
|
|
830
|
+
${i}
|
|
831
|
+
` + " ".repeat(r - s + 1) + "^\n"), this.column = r, this.excerpt = i, this.line = a, this.name = "XmlError", this.pos = t;
|
|
832
|
+
}
|
|
833
|
+
}, j = class extends w {
|
|
834
|
+
constructor(e, t = "") {
|
|
835
|
+
super(), this.name = e, this.content = t;
|
|
836
|
+
}
|
|
837
|
+
get type() {
|
|
838
|
+
return w.TYPE_PROCESSING_INSTRUCTION;
|
|
839
|
+
}
|
|
840
|
+
toJSON() {
|
|
841
|
+
return Object.assign(w.prototype.toJSON.call(this), {
|
|
842
|
+
name: this.name,
|
|
843
|
+
content: this.content
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
}, M = "", ne = class {
|
|
847
|
+
constructor(e, t = {}) {
|
|
848
|
+
let n = this.document = new A();
|
|
849
|
+
this.j = n, this.g = t, this.c = new f(e), this.g.includeOffsets && (n.start = 0, n.end = e.length), this.parse();
|
|
850
|
+
}
|
|
851
|
+
i(e, t) {
|
|
852
|
+
return e.parent = this.j, this.g.includeOffsets && (e.start = this.c.f(t), e.end = this.c.f()), this.j.children.push(e), !0;
|
|
853
|
+
}
|
|
854
|
+
y(e, t) {
|
|
855
|
+
let { children: n } = this.j, { length: r } = n;
|
|
856
|
+
if (e = N(e), r > 0) {
|
|
857
|
+
let t = n[r - 1];
|
|
858
|
+
if (t?.type === w.TYPE_TEXT) {
|
|
859
|
+
let n = t;
|
|
860
|
+
return n.text += e, this.g.includeOffsets && (n.end = this.c.f()), !0;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
return this.i(new T(e), t);
|
|
864
|
+
}
|
|
865
|
+
H() {
|
|
866
|
+
let e = /* @__PURE__ */ Object.create(null);
|
|
867
|
+
for (; this.e();) {
|
|
868
|
+
let t = this.q();
|
|
869
|
+
if (!t) break;
|
|
870
|
+
let n = this.t() && this.I();
|
|
871
|
+
if (n === !1) throw this.a("Attribute value expected");
|
|
872
|
+
if (t in e) throw this.a(`Duplicate attribute: ${t}`);
|
|
873
|
+
if (t === "xml:space" && n !== "default" && n !== "preserve") throw this.a("Value of the `xml:space` attribute must be \"default\" or \"preserve\"");
|
|
874
|
+
e[t] = n;
|
|
875
|
+
}
|
|
876
|
+
if (this.g.sortAttributes) {
|
|
877
|
+
let t = Object.keys(e).sort(), n = /* @__PURE__ */ Object.create(null);
|
|
878
|
+
for (let r = 0; r < t.length; ++r) {
|
|
879
|
+
let i = t[r];
|
|
880
|
+
n[i] = e[i];
|
|
881
|
+
}
|
|
882
|
+
e = n;
|
|
883
|
+
}
|
|
884
|
+
return e;
|
|
885
|
+
}
|
|
886
|
+
I() {
|
|
887
|
+
let { c: e } = this, t = e.m();
|
|
888
|
+
if (t !== "\"" && t !== "'") return !1;
|
|
889
|
+
e.p();
|
|
890
|
+
let n, r = !1, i = M, a = t === "\"" ? p : m;
|
|
891
|
+
matchLoop: for (; !e.B;) switch (n = e.x(a), n && (this.o(n), i += n.replace(h, " ")), e.m()) {
|
|
892
|
+
case t:
|
|
893
|
+
r = !0;
|
|
894
|
+
break matchLoop;
|
|
895
|
+
case "&":
|
|
896
|
+
i += this.C();
|
|
897
|
+
continue;
|
|
898
|
+
case "<": throw this.a("Unescaped `<` is not allowed in an attribute value");
|
|
899
|
+
default: break matchLoop;
|
|
900
|
+
}
|
|
901
|
+
if (!r) throw this.a("Unclosed attribute");
|
|
902
|
+
return e.p(), i;
|
|
903
|
+
}
|
|
904
|
+
J() {
|
|
905
|
+
let { c: e } = this, t = e.d;
|
|
906
|
+
if (!e.b("<![CDATA[")) return !1;
|
|
907
|
+
let n = e.s("]]>");
|
|
908
|
+
if (this.o(n), !e.b("]]>")) throw this.a("Unclosed CDATA section");
|
|
909
|
+
return this.g.preserveCdata ? this.i(new E(N(n)), t) : this.y(n, t);
|
|
910
|
+
}
|
|
911
|
+
K() {
|
|
912
|
+
let { c: e } = this, t = e.d, n = e.x(g);
|
|
913
|
+
if (!n) return !1;
|
|
914
|
+
if (this.o(n), e.m(3) === "]]>") throw this.a("Element content may not contain the CDATA section close delimiter `]]>`");
|
|
915
|
+
return this.y(n, t);
|
|
916
|
+
}
|
|
917
|
+
D() {
|
|
918
|
+
let { c: e } = this, t = e.d;
|
|
919
|
+
if (!e.b("<!--")) return !1;
|
|
920
|
+
let n = e.s("--");
|
|
921
|
+
if (this.o(n), !e.b("-->")) throw e.m(2) === "--" ? this.a("The string `--` isn't allowed inside a comment") : this.a("Unclosed comment");
|
|
922
|
+
return this.g.preserveComments ? this.i(new D(N(n)), t) : !0;
|
|
923
|
+
}
|
|
924
|
+
L() {
|
|
925
|
+
let e = this.c.d, t = this.C();
|
|
926
|
+
return t ? this.y(t, e) : !1;
|
|
927
|
+
}
|
|
928
|
+
M() {
|
|
929
|
+
let { c: e } = this, t = e.d;
|
|
930
|
+
if (!e.b("<!DOCTYPE")) return !1;
|
|
931
|
+
let n = this.e() && this.q();
|
|
932
|
+
if (!n) throw this.a("Expected a name");
|
|
933
|
+
let r, i;
|
|
934
|
+
if (this.e()) {
|
|
935
|
+
if (e.b("PUBLIC")) {
|
|
936
|
+
if (r = this.e() && this.N(), r === !1) throw this.a("Expected a public identifier");
|
|
937
|
+
this.e();
|
|
938
|
+
}
|
|
939
|
+
if (r !== void 0 || e.b("SYSTEM")) {
|
|
940
|
+
if (this.e(), i = this.r(), i === !1) throw this.a("Expected a system identifier");
|
|
941
|
+
this.e();
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
let a;
|
|
945
|
+
if (e.b("[")) {
|
|
946
|
+
if (a = e.x(/\][\x20\t\r\n]*>/), !e.b("]")) throw this.a("Unclosed internal subset");
|
|
947
|
+
this.e();
|
|
948
|
+
}
|
|
949
|
+
if (!e.b(">")) throw this.a("Unclosed doctype declaration");
|
|
950
|
+
return this.g.preserveDocumentType ? this.i(new ee(n, r, i, a), t) : !0;
|
|
951
|
+
}
|
|
952
|
+
E() {
|
|
953
|
+
let { c: e } = this, t = e.d;
|
|
954
|
+
if (!e.b("<")) return !1;
|
|
955
|
+
let n = this.q();
|
|
956
|
+
if (!n) return e.n(t), !1;
|
|
957
|
+
let r = this.H(), i = !!e.b("/>"), a = new k(n, r);
|
|
958
|
+
if (a.parent = this.j, !i) {
|
|
959
|
+
if (!e.b(">")) throw this.a(`Unclosed start tag for element \`${n}\``);
|
|
960
|
+
this.j = a;
|
|
961
|
+
do
|
|
962
|
+
this.K();
|
|
963
|
+
while (this.E() || this.L() || this.J() || this.F() || this.D());
|
|
964
|
+
let t = e.d, r;
|
|
965
|
+
if (!e.b("</") || !(r = this.q()) || r !== n) throw e.n(t), this.a(`Missing end tag for element ${n}`);
|
|
966
|
+
if (this.e(), !e.b(">")) throw this.a(`Unclosed end tag for element ${n}`);
|
|
967
|
+
this.j = a.parent;
|
|
968
|
+
}
|
|
969
|
+
return this.i(a, t);
|
|
970
|
+
}
|
|
971
|
+
t() {
|
|
972
|
+
return this.e(), this.c.b("=") ? (this.e(), !0) : !1;
|
|
973
|
+
}
|
|
974
|
+
z() {
|
|
975
|
+
return this.D() || this.F() || this.e();
|
|
976
|
+
}
|
|
977
|
+
q() {
|
|
978
|
+
return y(this.c.m()) ? this.c.w(v) : M;
|
|
979
|
+
}
|
|
980
|
+
F() {
|
|
981
|
+
let { c: e } = this, t = e.d;
|
|
982
|
+
if (!e.b("<?")) return !1;
|
|
983
|
+
let n = this.q();
|
|
984
|
+
if (n) {
|
|
985
|
+
if (n.toLowerCase() === "xml") throw e.n(t), this.a("XML declaration isn't allowed here");
|
|
986
|
+
} else throw this.a("Invalid processing instruction");
|
|
987
|
+
if (!this.e()) {
|
|
988
|
+
if (e.b("?>")) return this.i(new j(n), t);
|
|
989
|
+
throw this.a("Whitespace is required after a processing instruction name");
|
|
990
|
+
}
|
|
991
|
+
let r = e.s("?>");
|
|
992
|
+
if (this.o(r), !e.b("?>")) throw this.a("Unterminated processing instruction");
|
|
993
|
+
return this.i(new j(n, N(r)), t);
|
|
994
|
+
}
|
|
995
|
+
O() {
|
|
996
|
+
let { c: e } = this, t = e.d;
|
|
997
|
+
for (this.P(); this.z(););
|
|
998
|
+
if (this.M()) for (; this.z(););
|
|
999
|
+
return t < e.d;
|
|
1000
|
+
}
|
|
1001
|
+
N() {
|
|
1002
|
+
let e = this.c.d, t = this.r();
|
|
1003
|
+
if (t !== !1 && !/^[-\x20\r\na-zA-Z0-9'()+,./:=?;!*#@$_%]*$/.test(t)) throw this.c.n(e), this.a("Invalid character in public identifier");
|
|
1004
|
+
return t;
|
|
1005
|
+
}
|
|
1006
|
+
C() {
|
|
1007
|
+
let { c: e } = this;
|
|
1008
|
+
if (!e.b("&")) return !1;
|
|
1009
|
+
let t = e.w(b);
|
|
1010
|
+
if (e.G() !== ";") throw this.a("Unterminated reference (a reference must end with `;`)");
|
|
1011
|
+
let n;
|
|
1012
|
+
if (t[0] === "#") {
|
|
1013
|
+
let e = t[1] === "x" ? parseInt(t.slice(2), 16) : parseInt(t.slice(1), 10);
|
|
1014
|
+
if (isNaN(e)) throw this.a("Invalid character reference");
|
|
1015
|
+
if (!S(e)) throw this.a("Character reference resolves to an invalid character");
|
|
1016
|
+
n = String.fromCodePoint(e);
|
|
1017
|
+
} else if (n = _[t], n === void 0) {
|
|
1018
|
+
let { ignoreUndefinedEntities: n, resolveUndefinedEntity: r } = this.g, i = `&${t};`;
|
|
1019
|
+
if (r) {
|
|
1020
|
+
let e = r(i);
|
|
1021
|
+
if (e != null) {
|
|
1022
|
+
let t = typeof e;
|
|
1023
|
+
if (t !== "string") throw TypeError(`\`resolveUndefinedEntity()\` must return a string, \`null\`, or \`undefined\`, but returned a value of type ${t}`);
|
|
1024
|
+
return e;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
if (n) return i;
|
|
1028
|
+
throw e.n(-i.length), this.a(`Named entity isn't defined: ${i}`);
|
|
1029
|
+
}
|
|
1030
|
+
return n;
|
|
1031
|
+
}
|
|
1032
|
+
r() {
|
|
1033
|
+
let { c: e } = this, t = e.b("\"") || e.b("'");
|
|
1034
|
+
if (!t) return !1;
|
|
1035
|
+
let n = e.s(t);
|
|
1036
|
+
if (this.o(n), !e.b(t)) throw this.a("Missing end quote");
|
|
1037
|
+
return n;
|
|
1038
|
+
}
|
|
1039
|
+
e() {
|
|
1040
|
+
return !!this.c.w(x);
|
|
1041
|
+
}
|
|
1042
|
+
P() {
|
|
1043
|
+
let { c: e } = this, t = e.d;
|
|
1044
|
+
if (!e.b("<?xml")) return !1;
|
|
1045
|
+
if (!this.e()) throw this.a("Invalid XML declaration");
|
|
1046
|
+
let n = !!e.b("version") && this.t() && this.r();
|
|
1047
|
+
if (n === !1) throw this.a("XML version is missing or invalid");
|
|
1048
|
+
if (!/^1\.[0-9]+$/.test(n)) throw this.a("Invalid character in version number");
|
|
1049
|
+
let r, i;
|
|
1050
|
+
if (this.e()) {
|
|
1051
|
+
if (r = !!e.b("encoding") && this.t() && this.r(), r) {
|
|
1052
|
+
if (!/^[A-Za-z][\w.-]*$/.test(r)) throw this.a("Invalid character in encoding name");
|
|
1053
|
+
this.e();
|
|
1054
|
+
}
|
|
1055
|
+
if (i = !!e.b("standalone") && this.t() && this.r(), i) {
|
|
1056
|
+
if (i !== "yes" && i !== "no") throw this.a("Only \"yes\" and \"no\" are permitted as values of `standalone`");
|
|
1057
|
+
this.e();
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
if (!e.b("?>")) throw this.a("Invalid or unclosed XML declaration");
|
|
1061
|
+
return this.g.preserveXmlDeclaration ? this.i(new O(n, r || void 0, i || void 0), t) : !0;
|
|
1062
|
+
}
|
|
1063
|
+
a(e) {
|
|
1064
|
+
let { c: t } = this;
|
|
1065
|
+
return new te(e, t.d, t.h);
|
|
1066
|
+
}
|
|
1067
|
+
parse() {
|
|
1068
|
+
if (this.c.b(""), this.O(), !this.E()) throw this.a("Root element is missing or invalid");
|
|
1069
|
+
for (; this.z(););
|
|
1070
|
+
if (!this.c.B) throw this.a("Extra content at the end of the document");
|
|
1071
|
+
}
|
|
1072
|
+
o(e) {
|
|
1073
|
+
let { length: t } = e;
|
|
1074
|
+
for (let n = 0; n < t; ++n) {
|
|
1075
|
+
let t = e.codePointAt(n);
|
|
1076
|
+
if (!S(t)) throw this.c.n(-([...e].length - n)), this.a("Invalid character");
|
|
1077
|
+
t > 65535 && (n += 1);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
};
|
|
1081
|
+
function N(e) {
|
|
1082
|
+
let t = 0;
|
|
1083
|
+
for (; (t = e.indexOf("\r", t)) !== -1;) e = e[t + 1] === "\n" ? e.slice(0, t) + e.slice(t + 1) : e.slice(0, t) + "\n" + e.slice(t + 1);
|
|
1084
|
+
return e;
|
|
1085
|
+
}
|
|
1086
|
+
function re(e, t) {
|
|
1087
|
+
return new ne(e, t).document;
|
|
1088
|
+
}
|
|
1089
|
+
})))(), Ce = class extends Error {
|
|
1090
|
+
constructor(e) {
|
|
1091
|
+
super(e);
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1094
|
+
function we(e) {
|
|
1095
|
+
let t = null;
|
|
1096
|
+
try {
|
|
1097
|
+
t = (0, Se.parseXml)(e);
|
|
1098
|
+
} catch (e) {
|
|
1099
|
+
throw new Ce(e.message);
|
|
1100
|
+
}
|
|
1101
|
+
return t;
|
|
1102
|
+
}
|
|
1103
|
+
function F(e) {
|
|
1104
|
+
let t = e.indexOf(":");
|
|
1105
|
+
return t > -1 ? e.substr(t + 1) : e;
|
|
1106
|
+
}
|
|
1107
|
+
function I(e) {
|
|
1108
|
+
return e.children[0];
|
|
1109
|
+
}
|
|
1110
|
+
function L(e) {
|
|
1111
|
+
return e.name || "";
|
|
1112
|
+
}
|
|
1113
|
+
function R(e, t, n = !1) {
|
|
1114
|
+
let r = F(t);
|
|
1115
|
+
function i(e, t) {
|
|
1116
|
+
return F(L(t)) === r && e.push(t), n && Array.isArray(t.children) ? [...e, ...t.children.reduce(i, [])] : e;
|
|
1117
|
+
}
|
|
1118
|
+
return e && Array.isArray(e.children) ? e.children.reduce(i, []) : [];
|
|
1119
|
+
}
|
|
1120
|
+
function z(e, t, n = !1) {
|
|
1121
|
+
return R(e, t, n)[0] || null;
|
|
1122
|
+
}
|
|
1123
|
+
function B(e) {
|
|
1124
|
+
return e && Array.isArray(e.children) ? [...e.children.filter((e) => e instanceof Se.XmlElement)] : [];
|
|
1125
|
+
}
|
|
1126
|
+
function V(e) {
|
|
1127
|
+
let t = e && Array.isArray(e.children) ? e.children.find((e) => e.type === "text") : null;
|
|
1128
|
+
return t ? t.text : "";
|
|
1129
|
+
}
|
|
1130
|
+
function H(e, t) {
|
|
1131
|
+
return e && e.attributes[t] || "";
|
|
1132
|
+
}
|
|
1133
|
+
//#endregion
|
|
1134
|
+
//#region node_modules/@camptocamp/ogc-client/dist/shared/errors.js
|
|
1135
|
+
var Te = class extends Error {
|
|
1136
|
+
constructor(e, t, n) {
|
|
1137
|
+
super(e), this.httpStatus = t, this.isCrossOriginRelated = n, this.name = "EndpointError";
|
|
1138
|
+
}
|
|
1139
|
+
}, Ee = class extends Error {
|
|
1140
|
+
constructor(e, t, n, r, i) {
|
|
1141
|
+
super(e), this.requestUrl = t, this.code = n, this.locator = r, this.response = i, this.name = "ServiceExceptionError";
|
|
1142
|
+
}
|
|
1143
|
+
};
|
|
1144
|
+
function De(e, t) {
|
|
1145
|
+
let n = H(e, "code") || H(e, "exceptionCode"), r = H(e, "locator");
|
|
1146
|
+
return new Ee(V(z(e, "ExceptionText") || e).trim(), t, n, r, e.document);
|
|
1147
|
+
}
|
|
1148
|
+
function Oe(e, t) {
|
|
1149
|
+
let n = I(e), r = F(L(n));
|
|
1150
|
+
if (r === "ServiceExceptionReport") {
|
|
1151
|
+
let e = z(n, "ServiceException");
|
|
1152
|
+
if (e) throw De(e, t);
|
|
1153
|
+
}
|
|
1154
|
+
if (r === "ExceptionReport") {
|
|
1155
|
+
let e = z(n, "Exception");
|
|
1156
|
+
if (e) throw De(e, t);
|
|
1157
|
+
}
|
|
1158
|
+
return e;
|
|
1159
|
+
}
|
|
1160
|
+
function ke(e) {
|
|
1161
|
+
let t = {
|
|
1162
|
+
message: e.message,
|
|
1163
|
+
stack: e.stack,
|
|
1164
|
+
name: e.name
|
|
1165
|
+
};
|
|
1166
|
+
return e instanceof Ee ? {
|
|
1167
|
+
...t,
|
|
1168
|
+
code: e.code,
|
|
1169
|
+
locator: e.locator,
|
|
1170
|
+
response: e.response,
|
|
1171
|
+
requestUrl: e.requestUrl
|
|
1172
|
+
} : e instanceof Te ? {
|
|
1173
|
+
...t,
|
|
1174
|
+
httpStatus: e.httpStatus,
|
|
1175
|
+
isCrossOriginRelated: e.isCrossOriginRelated
|
|
1176
|
+
} : t;
|
|
1177
|
+
}
|
|
1178
|
+
//#endregion
|
|
1179
|
+
//#region node_modules/@camptocamp/ogc-client/dist/shared/encoding.js
|
|
1180
|
+
var Ae = [
|
|
1181
|
+
"utf-8",
|
|
1182
|
+
"utf-16",
|
|
1183
|
+
"iso-8859-1"
|
|
1184
|
+
], je = "utf-8";
|
|
1185
|
+
function Me(e) {
|
|
1186
|
+
let t = /charset=([^;]+)/.exec(e);
|
|
1187
|
+
return t ? t[1] : null;
|
|
1188
|
+
}
|
|
1189
|
+
function Ne(e, t) {
|
|
1190
|
+
let n = t ? Me(t) : null, r = n ? [n, ...Ae] : Ae;
|
|
1191
|
+
for (let t of r) try {
|
|
1192
|
+
return new TextDecoder(t, { fatal: !0 }).decode(e);
|
|
1193
|
+
} catch {}
|
|
1194
|
+
return console.warn(`[ogc-client] XML document encoding could not be determined, falling back to ${je}.`), new TextDecoder(je).decode(e);
|
|
1195
|
+
}
|
|
1196
|
+
//#endregion
|
|
1197
|
+
//#region node_modules/@camptocamp/ogc-client/dist/shared/http-utils.js
|
|
1198
|
+
var Pe = /* @__PURE__ */ new Map(), Fe = {}, Ie = null;
|
|
1199
|
+
function Le(e) {
|
|
1200
|
+
Fe = e, Ie && Ie(e);
|
|
1201
|
+
}
|
|
1202
|
+
function Re() {
|
|
1203
|
+
return Fe;
|
|
1204
|
+
}
|
|
1205
|
+
function ze(e, t = "GET", n) {
|
|
1206
|
+
let r = `${t}#${e}`;
|
|
1207
|
+
if (n && (r = `${t}#asJson#${e}`), Pe.has(r)) return Pe.get(r);
|
|
1208
|
+
let i = { ...Re() };
|
|
1209
|
+
i.method = t, n && (i.headers = "headers" in i ? i.headers : {}, i.headers.Accept = "application/json,application/schema+json");
|
|
1210
|
+
let a = fetch(e, i).catch((e) => e).then((e) => (Pe.delete(r), e));
|
|
1211
|
+
return Pe.set(r, a), a.then((e) => {
|
|
1212
|
+
if (e instanceof Error) throw e;
|
|
1213
|
+
return e.clone();
|
|
1214
|
+
});
|
|
1215
|
+
}
|
|
1216
|
+
function U(e) {
|
|
1217
|
+
return ze(e).catch(() => fetch(e, {
|
|
1218
|
+
...Re(),
|
|
1219
|
+
method: "HEAD",
|
|
1220
|
+
mode: "no-cors"
|
|
1221
|
+
}).catch((e) => {
|
|
1222
|
+
throw new Te(`Fetching the document failed either due to network errors or unreachable host, error is: ${e.message}`, 0, !1);
|
|
1223
|
+
}).then(() => {
|
|
1224
|
+
throw new Te("The document could not be fetched due to CORS limitations", 0, !0);
|
|
1225
|
+
})).then(async (e) => {
|
|
1226
|
+
if (!e.ok) {
|
|
1227
|
+
let t = await e.text();
|
|
1228
|
+
throw new Te(`Received an error with code ${e.status}: ${t}`, e.status, !1);
|
|
1229
|
+
}
|
|
1230
|
+
return Ne(await e.arrayBuffer(), e.headers.get("Content-Type"));
|
|
1231
|
+
}).then((e) => we(e));
|
|
1232
|
+
}
|
|
1233
|
+
function W(e, t) {
|
|
1234
|
+
let n = e.match(/(https?%3A%2F%2F[^/]+)$/);
|
|
1235
|
+
if (n) {
|
|
1236
|
+
let r = n[1], i = W(decodeURIComponent(r), t);
|
|
1237
|
+
return e.replace(r, encodeURIComponent(i));
|
|
1238
|
+
}
|
|
1239
|
+
let r = new URL(e), i = Object.keys(t), a = i.map((e) => e.toLowerCase()), o = [];
|
|
1240
|
+
for (let e of r.searchParams.keys()) a.indexOf(e.toLowerCase()) > -1 && o.push(e);
|
|
1241
|
+
return o.map((e) => r.searchParams.delete(e)), i.forEach((e) => r.searchParams.set(e, t[e] === !0 ? "" : t[e])), r.toString();
|
|
1242
|
+
}
|
|
1243
|
+
//#endregion
|
|
1244
|
+
//#region node_modules/@camptocamp/ogc-client/dist/wfs/featuretypeinfo.js
|
|
1245
|
+
function Be(e, t, n, r) {
|
|
1246
|
+
let { name: i, title: a, abstract: o, defaultCrs: s, otherCrs: c, outputFormats: l, latLonBoundingBox: u, keywords: d, metadata: f } = e, p = r.startsWith("2.0") ? "numberMatched" : "numberOfFeatures", m = parseInt(H(I(n), p)), h = R(I(t), "complexType", !0)[0], g = R(h, "element", !0), _ = g.filter((e) => /^xsd:|^xs:/.test(H(e, "type"))).reduce((e, t) => ({
|
|
1247
|
+
...e,
|
|
1248
|
+
[H(t, "name")]: Ve(H(t, "type"))
|
|
1249
|
+
}), {}), v = g.filter((e) => H(e, "type").startsWith("gml:"))[0], y = v ? H(v, "name") : void 0, b = v ? He(H(v, "type")) : void 0;
|
|
1250
|
+
return {
|
|
1251
|
+
name: i,
|
|
1252
|
+
...a && { title: a },
|
|
1253
|
+
...o && { abstract: o },
|
|
1254
|
+
...u && { boundingBox: u },
|
|
1255
|
+
...s && { defaultCrs: s },
|
|
1256
|
+
...c && { otherCrs: c },
|
|
1257
|
+
...l && { outputFormats: l },
|
|
1258
|
+
properties: _,
|
|
1259
|
+
...y && { geometryName: y },
|
|
1260
|
+
...b && { geometryType: b },
|
|
1261
|
+
...!Number.isNaN(m) && { objectCount: m },
|
|
1262
|
+
...d && { keywords: d },
|
|
1263
|
+
...f && { metadata: f }
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
function Ve(e) {
|
|
1267
|
+
switch (e.indexOf(":") > -1 ? e.substr(e.indexOf(":") + 1) : e) {
|
|
1268
|
+
case "string": return "string";
|
|
1269
|
+
case "boolean": return "boolean";
|
|
1270
|
+
case "float":
|
|
1271
|
+
case "double":
|
|
1272
|
+
case "decimal": return "float";
|
|
1273
|
+
case "long":
|
|
1274
|
+
case "byte":
|
|
1275
|
+
case "integer":
|
|
1276
|
+
case "int":
|
|
1277
|
+
case "positiveInteger":
|
|
1278
|
+
case "negativeInteger":
|
|
1279
|
+
case "nonPositiveInteger":
|
|
1280
|
+
case "nonNegativeInteger":
|
|
1281
|
+
case "short":
|
|
1282
|
+
case "unsignedLong":
|
|
1283
|
+
case "unsignedInt":
|
|
1284
|
+
case "unsignedShort":
|
|
1285
|
+
case "unsignedByte": return "integer";
|
|
1286
|
+
default: return "string";
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
function He(e) {
|
|
1290
|
+
switch (e.indexOf(":") > -1 ? e.substr(e.indexOf(":") + 1) : e) {
|
|
1291
|
+
case "PointPropertyType": return "point";
|
|
1292
|
+
case "MultiPointPropertyType": return "multipoint";
|
|
1293
|
+
case "CurvePropertyType":
|
|
1294
|
+
case "LineStringPropertyType": return "linestring";
|
|
1295
|
+
case "MultiCurvePropertyType":
|
|
1296
|
+
case "MultiLineStringPropertyType": return "linestring";
|
|
1297
|
+
case "PolygonPropertyType":
|
|
1298
|
+
case "SurfacePropertyType": return "polygon";
|
|
1299
|
+
case "MultiPolygonPropertyType":
|
|
1300
|
+
case "MultiSurfacePropertyType": return "multipolygon";
|
|
1301
|
+
default: return "unknown";
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
//#endregion
|
|
1305
|
+
//#region node_modules/@camptocamp/ogc-client/dist/shared/cache.js
|
|
1306
|
+
var Ue = 1e3 * 60 * 60;
|
|
1307
|
+
function We() {
|
|
1308
|
+
return Ue;
|
|
1309
|
+
}
|
|
1310
|
+
var G;
|
|
1311
|
+
function K() {
|
|
1312
|
+
return G === void 0 ? "caches" in globalThis ? (G = caches.open("ogc-client").catch((e) => (console.info("[ogc-client] Cache could not be accessed for the following reason:", e), null)), G) : (G = Promise.resolve(null), G) : G;
|
|
1313
|
+
}
|
|
1314
|
+
async function Ge(e, ...t) {
|
|
1315
|
+
let n = await K();
|
|
1316
|
+
if (!n) return;
|
|
1317
|
+
let r = "https://cache/" + t.join("/");
|
|
1318
|
+
try {
|
|
1319
|
+
await n.put(r, new Response(JSON.stringify(e), { headers: { "x-expiry": (Date.now() + We()).toString(10) } }));
|
|
1320
|
+
} catch (e) {
|
|
1321
|
+
console.info("[ogc-client] Caching failed once for the following reason and will not be retried:", e), G = Promise.resolve(null);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
async function Ke(...e) {
|
|
1325
|
+
let t = await K();
|
|
1326
|
+
if (!t) return;
|
|
1327
|
+
let n = "https://cache/" + e.join("/");
|
|
1328
|
+
return t.match(n).then((e) => !!e && parseInt(e.headers.get("x-expiry")) > Date.now());
|
|
1329
|
+
}
|
|
1330
|
+
async function qe(...e) {
|
|
1331
|
+
let t = await K();
|
|
1332
|
+
if (!t) return;
|
|
1333
|
+
let n = "https://cache/" + e.join("/"), r = await t.match(n);
|
|
1334
|
+
return r ? r.clone().json() : null;
|
|
1335
|
+
}
|
|
1336
|
+
var q = /* @__PURE__ */ new Map();
|
|
1337
|
+
async function J(e, ...t) {
|
|
1338
|
+
if (await Je(), await Ke(...t)) return qe(...t);
|
|
1339
|
+
let n = t.join("#");
|
|
1340
|
+
if (q.has(n)) return q.get(n);
|
|
1341
|
+
let r = e();
|
|
1342
|
+
r instanceof Promise && (r.then(() => q.delete(n)), q.set(n, r));
|
|
1343
|
+
let i = await r;
|
|
1344
|
+
return await Ge(i, ...t), i;
|
|
1345
|
+
}
|
|
1346
|
+
async function Je() {
|
|
1347
|
+
let e = await K();
|
|
1348
|
+
if (!e) return;
|
|
1349
|
+
let t = await e.keys();
|
|
1350
|
+
for (let n of t) {
|
|
1351
|
+
let t = await e.match(n);
|
|
1352
|
+
parseInt(t.headers.get("x-expiry")) <= Date.now() && await e.delete(n);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
//#endregion
|
|
1356
|
+
//#region node_modules/@camptocamp/ogc-client/dist/wfs/url.js
|
|
1357
|
+
function Ye(e, t, n, r, i, a, o, s, c, l, u, d) {
|
|
1358
|
+
let f = t === "2.0.0" ? "TYPENAMES" : "TYPENAME", p = t === "2.0.0" ? "COUNT" : "MAXFEATURES", m = {
|
|
1359
|
+
SERVICE: "WFS",
|
|
1360
|
+
REQUEST: "GetFeature",
|
|
1361
|
+
VERSION: t,
|
|
1362
|
+
[f]: n
|
|
1363
|
+
};
|
|
1364
|
+
if (r !== void 0 && (m.OUTPUTFORMAT = r), a !== void 0 && (m.PROPERTYNAME = a.join(",")), o ? (m.RESULTTYPE = "hits", m[p] = "1") : i !== void 0 && (m[p] = i.toString(10)), s && (m.SRSNAME = s), c) {
|
|
1365
|
+
let e = c.join(",");
|
|
1366
|
+
m.BBOX = l ? `${e},${l}` : e;
|
|
1367
|
+
}
|
|
1368
|
+
u && (m.STARTINDEX = u.toString(10));
|
|
1369
|
+
let h = new URL(W(e, m));
|
|
1370
|
+
if (Array.isArray(d) && d.length > 0) {
|
|
1371
|
+
let e = d.map((e) => `${e[1]} ${e[0]}`).join(",");
|
|
1372
|
+
h.searchParams.set("SORTBY", e);
|
|
1373
|
+
}
|
|
1374
|
+
return h.toString();
|
|
1375
|
+
}
|
|
1376
|
+
function Xe(e, t, n) {
|
|
1377
|
+
return W(e, {
|
|
1378
|
+
SERVICE: "WFS",
|
|
1379
|
+
REQUEST: "DescribeFeatureType",
|
|
1380
|
+
VERSION: t,
|
|
1381
|
+
[t === "2.0.0" ? "TYPENAMES" : "TYPENAME"]: n
|
|
1382
|
+
});
|
|
1383
|
+
}
|
|
1384
|
+
//#endregion
|
|
1385
|
+
//#region node_modules/@camptocamp/ogc-client/dist/shared/mime-type.js
|
|
1386
|
+
function Ze(e) {
|
|
1387
|
+
return e.toLowerCase().indexOf("json") > -1;
|
|
1388
|
+
}
|
|
1389
|
+
//#endregion
|
|
1390
|
+
//#region node_modules/@camptocamp/ogc-client/dist/wfs/endpoint.js
|
|
1391
|
+
var Qe = class {
|
|
1392
|
+
_capabilitiesUrl;
|
|
1393
|
+
_capabilitiesPromise;
|
|
1394
|
+
_info;
|
|
1395
|
+
_featureTypes;
|
|
1396
|
+
_url;
|
|
1397
|
+
_version;
|
|
1398
|
+
constructor(e) {
|
|
1399
|
+
this._capabilitiesUrl = W(e, {
|
|
1400
|
+
SERVICE: "WFS",
|
|
1401
|
+
REQUEST: "GetCapabilities"
|
|
1402
|
+
}), this._capabilitiesPromise = J(() => ye(this._capabilitiesUrl), "WFS", "CAPABILITIES", this._capabilitiesUrl).then(({ info: e, featureTypes: t, url: n, version: r }) => {
|
|
1403
|
+
this._info = e, this._featureTypes = t, this._url = n, this._version = r;
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
isReady() {
|
|
1407
|
+
return this._capabilitiesPromise.then(() => this);
|
|
1408
|
+
}
|
|
1409
|
+
getServiceInfo() {
|
|
1410
|
+
return this._info;
|
|
1411
|
+
}
|
|
1412
|
+
getFeatureTypes() {
|
|
1413
|
+
return this._featureTypes.map((e) => ({
|
|
1414
|
+
name: e.name,
|
|
1415
|
+
..."title" in e && { title: e.title },
|
|
1416
|
+
..."abstract" in e && { abstract: e.abstract },
|
|
1417
|
+
..."latLonBoundingBox" in e && { boundingBox: e.latLonBoundingBox }
|
|
1418
|
+
}));
|
|
1419
|
+
}
|
|
1420
|
+
_getFeatureTypeByName(e) {
|
|
1421
|
+
if (!this._featureTypes) return null;
|
|
1422
|
+
let t = F(e) !== e;
|
|
1423
|
+
return this._featureTypes.find((n) => t ? n.name === e : F(n.name) === e) || null;
|
|
1424
|
+
}
|
|
1425
|
+
getFeatureTypeSummary(e) {
|
|
1426
|
+
let t = this._getFeatureTypeByName(e);
|
|
1427
|
+
return t ? {
|
|
1428
|
+
name: t.name,
|
|
1429
|
+
..."title" in t && { title: t.title },
|
|
1430
|
+
..."abstract" in t && { abstract: t.abstract },
|
|
1431
|
+
..."latLonBoundingBox" in t && { boundingBox: t.latLonBoundingBox },
|
|
1432
|
+
defaultCrs: t.defaultCrs,
|
|
1433
|
+
otherCrs: t.otherCrs,
|
|
1434
|
+
outputFormats: t.outputFormats,
|
|
1435
|
+
keywords: t.keywords,
|
|
1436
|
+
..."metadata" in t && { metadata: t.metadata }
|
|
1437
|
+
} : null;
|
|
1438
|
+
}
|
|
1439
|
+
getFeatureTypeFull(e) {
|
|
1440
|
+
let t = this._getFeatureTypeByName(e);
|
|
1441
|
+
return t ? J(() => {
|
|
1442
|
+
let n = Xe(this.getOperationUrl("DescribeFeatureType"), this._version, e), r = Ye(this.getOperationUrl("GetFeature"), this._version, e, void 0, void 0, void 0, !0);
|
|
1443
|
+
return Promise.all([U(n), U(r)]).then(([e, n]) => Be(t, e, n, this._version));
|
|
1444
|
+
}, "WFS", "FEATURETYPEINFO", this._capabilitiesUrl, e) : null;
|
|
1445
|
+
}
|
|
1446
|
+
getSingleFeatureTypeName() {
|
|
1447
|
+
return this._featureTypes && this._featureTypes.length === 1 ? this._featureTypes[0].name : null;
|
|
1448
|
+
}
|
|
1449
|
+
async getFeatureTypePropDetails(e) {
|
|
1450
|
+
let t = await this.getFeatureTypeFull(e);
|
|
1451
|
+
return t === null ? null : J(() => be(this._capabilitiesUrl, this._version, t).then((e) => e.props), "WFS", "FEATURETYPEPROPDETAILS", this._capabilitiesUrl, e);
|
|
1452
|
+
}
|
|
1453
|
+
getVersion() {
|
|
1454
|
+
return this._version;
|
|
1455
|
+
}
|
|
1456
|
+
_getJsonCompatibleOutputFormat(e) {
|
|
1457
|
+
let t = this._getFeatureTypeByName(e);
|
|
1458
|
+
if (!t) throw Error(`The following feature type was not found in the service: ${e}`);
|
|
1459
|
+
let n = t.outputFormats.filter(Ze);
|
|
1460
|
+
return n.length ? n[0] : null;
|
|
1461
|
+
}
|
|
1462
|
+
supportsJson(e) {
|
|
1463
|
+
return this._featureTypes ? !!this._getJsonCompatibleOutputFormat(e) : null;
|
|
1464
|
+
}
|
|
1465
|
+
supportsStartIndex() {
|
|
1466
|
+
return this._version ? this._version >= "2.0.0" : !1;
|
|
1467
|
+
}
|
|
1468
|
+
getFeatureUrl(e, t) {
|
|
1469
|
+
if (!this._featureTypes) return null;
|
|
1470
|
+
let { maxFeatures: n, asJson: r, outputFormat: i, outputCrs: a, extent: o, extentCrs: s, startIndex: c, attributes: l, hitsOnly: u } = t || {}, d = this._getFeatureTypeByName(e);
|
|
1471
|
+
if (!d) throw Error(`The following feature type was not found in the service: ${e}`);
|
|
1472
|
+
let f = i;
|
|
1473
|
+
if (r) {
|
|
1474
|
+
if (f = this._getJsonCompatibleOutputFormat(e) || void 0, !f) throw Error(`The endpoint does not appear to support GeoJSON for the feature type ${d.name}`);
|
|
1475
|
+
} else i && d.outputFormats.indexOf(i) === -1 && console.warn(`[ogc-client] The following output format type was not found in the feature type ${d.name}: ${i}`);
|
|
1476
|
+
return Ye(this.getOperationUrl("GetFeature"), this._version, d.name, f, n, l, u, a, o, s, c);
|
|
1477
|
+
}
|
|
1478
|
+
getCapabilitiesUrl() {
|
|
1479
|
+
let e = this.getOperationUrl("GetCapabilities");
|
|
1480
|
+
return e ? W(e, {
|
|
1481
|
+
SERVICE: "WMS",
|
|
1482
|
+
REQUEST: "GetCapabilities"
|
|
1483
|
+
}) : this._capabilitiesUrl;
|
|
1484
|
+
}
|
|
1485
|
+
getOperationUrl(e, t = "Get") {
|
|
1486
|
+
return this._url ? this._url[e]?.[t] : null;
|
|
1487
|
+
}
|
|
1488
|
+
};
|
|
1489
|
+
//#endregion
|
|
1490
|
+
//#region node_modules/@camptocamp/ogc-client/dist/wms/url.js
|
|
1491
|
+
function $e(e, t, n, r, i, a, o, s, c) {
|
|
1492
|
+
let l = t === "1.3.0" ? "CRS" : "SRS", u = {
|
|
1493
|
+
SERVICE: "WMS",
|
|
1494
|
+
REQUEST: "GetMap",
|
|
1495
|
+
VERSION: t,
|
|
1496
|
+
LAYERS: n,
|
|
1497
|
+
STYLES: c ?? ""
|
|
1498
|
+
};
|
|
1499
|
+
return u.WIDTH = r.toString(), u.HEIGHT = i.toString(), u.FORMAT = s ?? "image/png", u[l] = a, u.BBOX = o.join(","), W(e, u);
|
|
1500
|
+
}
|
|
1501
|
+
//#endregion
|
|
1502
|
+
//#region node_modules/@camptocamp/ogc-client/dist/wms/endpoint.js
|
|
1503
|
+
var et = class {
|
|
1504
|
+
_capabilitiesUrl;
|
|
1505
|
+
_capabilitiesPromise;
|
|
1506
|
+
_info;
|
|
1507
|
+
_layers;
|
|
1508
|
+
_url;
|
|
1509
|
+
_version;
|
|
1510
|
+
constructor(e) {
|
|
1511
|
+
this._capabilitiesUrl = W(e, {
|
|
1512
|
+
SERVICE: "WMS",
|
|
1513
|
+
REQUEST: "GetCapabilities"
|
|
1514
|
+
}), this._capabilitiesPromise = J(() => ve(this._capabilitiesUrl), "WMS", "CAPABILITIES", this._capabilitiesUrl).then(({ info: e, layers: t, url: n, version: r }) => {
|
|
1515
|
+
this._info = e, this._layers = t, this._url = n, this._version = r;
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
isReady() {
|
|
1519
|
+
return this._capabilitiesPromise.then(() => this);
|
|
1520
|
+
}
|
|
1521
|
+
getServiceInfo() {
|
|
1522
|
+
return this._info;
|
|
1523
|
+
}
|
|
1524
|
+
getLayers() {
|
|
1525
|
+
function e(t) {
|
|
1526
|
+
return {
|
|
1527
|
+
title: t.title,
|
|
1528
|
+
name: t.name,
|
|
1529
|
+
abstract: t.abstract,
|
|
1530
|
+
..."children" in t && { children: t.children.map(e) }
|
|
1531
|
+
};
|
|
1532
|
+
}
|
|
1533
|
+
return this._layers.map(e);
|
|
1534
|
+
}
|
|
1535
|
+
getFlattenedLayers() {
|
|
1536
|
+
return this.getLayers().flatMap(tt);
|
|
1537
|
+
}
|
|
1538
|
+
getLayerByName(e) {
|
|
1539
|
+
let t = null;
|
|
1540
|
+
function n(r) {
|
|
1541
|
+
if (t === null) {
|
|
1542
|
+
if (r.name === e) {
|
|
1543
|
+
t = r;
|
|
1544
|
+
return;
|
|
1545
|
+
}
|
|
1546
|
+
"children" in r && r.children.map(n);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
return this._layers.map(n), t;
|
|
1550
|
+
}
|
|
1551
|
+
getSingleLayerName() {
|
|
1552
|
+
if (!this._layers) return null;
|
|
1553
|
+
let e = [];
|
|
1554
|
+
function t(n) {
|
|
1555
|
+
n.name && e.push(n), "children" in n && n.children.map(t);
|
|
1556
|
+
}
|
|
1557
|
+
return this._layers.map(t), e.length === 1 ? e[0].name : null;
|
|
1558
|
+
}
|
|
1559
|
+
getVersion() {
|
|
1560
|
+
return this._version;
|
|
1561
|
+
}
|
|
1562
|
+
getMapUrl(e, t) {
|
|
1563
|
+
if (!this._layers) return null;
|
|
1564
|
+
let { widthPx: n, heightPx: r, crs: i, extent: a, outputFormat: o, styles: s } = t;
|
|
1565
|
+
return $e(this.getOperationUrl("GetMap") || this._capabilitiesUrl, this._version, e.join(","), n, r, i, a, o, s === void 0 ? "" : s.join(","));
|
|
1566
|
+
}
|
|
1567
|
+
getCapabilitiesUrl() {
|
|
1568
|
+
let e = this.getOperationUrl("GetCapabilities");
|
|
1569
|
+
return e ? W(e, {
|
|
1570
|
+
SERVICE: "WMS",
|
|
1571
|
+
REQUEST: "GetCapabilities"
|
|
1572
|
+
}) : this._capabilitiesUrl;
|
|
1573
|
+
}
|
|
1574
|
+
getOperationUrl(e, t = "Get") {
|
|
1575
|
+
return this._url ? this._url[e]?.[t] : null;
|
|
1576
|
+
}
|
|
1577
|
+
};
|
|
1578
|
+
function tt(e) {
|
|
1579
|
+
let t = {
|
|
1580
|
+
title: e.title,
|
|
1581
|
+
name: e.name,
|
|
1582
|
+
abstract: e.abstract
|
|
1583
|
+
};
|
|
1584
|
+
return "children" in e && Array.isArray(e.children) ? [t, ...e.children.flatMap(tt)] : [t];
|
|
1585
|
+
}
|
|
1586
|
+
//#endregion
|
|
1587
|
+
//#region node_modules/@camptocamp/ogc-client/dist/wmts/url.js
|
|
1588
|
+
function nt(e, t, n, r, i, a, o, s, c) {
|
|
1589
|
+
let l = {
|
|
1590
|
+
layer: n,
|
|
1591
|
+
style: r,
|
|
1592
|
+
tilematrixset: i,
|
|
1593
|
+
Service: "WMTS",
|
|
1594
|
+
Request: "GetTile",
|
|
1595
|
+
Format: c,
|
|
1596
|
+
TileMatrix: a,
|
|
1597
|
+
TileCol: s.toString(),
|
|
1598
|
+
TileRow: o.toString()
|
|
1599
|
+
};
|
|
1600
|
+
if (t === "REST") {
|
|
1601
|
+
let t = e;
|
|
1602
|
+
for (let e in l) t = t.replace(RegExp(`{${e}}`, "ig"), l[e]);
|
|
1603
|
+
return t;
|
|
1604
|
+
} else return W(e, l);
|
|
1605
|
+
}
|
|
1606
|
+
//#endregion
|
|
1607
|
+
//#region node_modules/@camptocamp/ogc-client/dist/wmts/endpoint.js
|
|
1608
|
+
var rt = class {
|
|
1609
|
+
_capabilitiesPromise;
|
|
1610
|
+
_info = null;
|
|
1611
|
+
_layers = null;
|
|
1612
|
+
_matrixSets = null;
|
|
1613
|
+
constructor(e) {
|
|
1614
|
+
let t = W(e, {
|
|
1615
|
+
SERVICE: "WMTS",
|
|
1616
|
+
REQUEST: "GetCapabilities"
|
|
1617
|
+
});
|
|
1618
|
+
this._capabilitiesPromise = J(() => xe(t), "WMTS", "CAPABILITIES", t).then(({ info: e, layers: t, matrixSets: n }) => {
|
|
1619
|
+
this._info = e, this._layers = t, this._matrixSets = n;
|
|
1620
|
+
});
|
|
1621
|
+
}
|
|
1622
|
+
isReady() {
|
|
1623
|
+
return this._capabilitiesPromise.then(() => this);
|
|
1624
|
+
}
|
|
1625
|
+
getServiceInfo() {
|
|
1626
|
+
return this._info;
|
|
1627
|
+
}
|
|
1628
|
+
getLayers() {
|
|
1629
|
+
return this._layers;
|
|
1630
|
+
}
|
|
1631
|
+
getMatrixSets() {
|
|
1632
|
+
return this._matrixSets;
|
|
1633
|
+
}
|
|
1634
|
+
getMatrixSetByIdentifier(e) {
|
|
1635
|
+
return this._matrixSets ? this._matrixSets.find((t) => t.identifier === e) ?? null : null;
|
|
1636
|
+
}
|
|
1637
|
+
getLayerByName(e) {
|
|
1638
|
+
return this._layers ? this._layers.find((t) => t.name === e) ?? null : null;
|
|
1639
|
+
}
|
|
1640
|
+
getSingleLayerName() {
|
|
1641
|
+
return this._layers && this._layers.length === 1 ? this._layers[0].name : null;
|
|
1642
|
+
}
|
|
1643
|
+
getLayerResourceLink(e, t) {
|
|
1644
|
+
if (!this._layers) return null;
|
|
1645
|
+
let n = this.getLayerByName(e), r = 0;
|
|
1646
|
+
t && (r = n.resourceLinks.findIndex((e) => e.format === t) || 0);
|
|
1647
|
+
let i = n.resourceLinks[r];
|
|
1648
|
+
return t && i.format !== t && console.warn(`[ogc-client] Requested '${t}' format for the WMTS layer but it is not available in REST encoding, falling back to '${i.format}'`), i;
|
|
1649
|
+
}
|
|
1650
|
+
getTileUrl(e, t, n, r, i, a, o) {
|
|
1651
|
+
if (!this._layers) return null;
|
|
1652
|
+
let s = this.getLayerResourceLink(e, o);
|
|
1653
|
+
return nt(s.url, s.encoding, e, t, n, r, i, a, s.format);
|
|
1654
|
+
}
|
|
1655
|
+
getDefaultDimensions(e) {
|
|
1656
|
+
if (!this._layers) return null;
|
|
1657
|
+
let t = this.getLayerByName(e);
|
|
1658
|
+
return t.dimensions ? t.dimensions.reduce((e, t) => ({
|
|
1659
|
+
...e,
|
|
1660
|
+
[t.identifier]: t.defaultValue
|
|
1661
|
+
}), {}) : {};
|
|
1662
|
+
}
|
|
1663
|
+
tileGridModule;
|
|
1664
|
+
getOpenLayersTileGrid(e, t) {
|
|
1665
|
+
if (!this._layers) return null;
|
|
1666
|
+
this.tileGridModule ||= import("./ol-tilegrid-9VtyxaLG.js").catch((e) => (console.warn("[ogc-client] Cannot use getOpenLayersTileGrid, the 'ol' package is probably not available.\n", e), null));
|
|
1667
|
+
let n = this.getLayerByName(e), r = n.matrixSets.find((e) => e.identifier === t) ?? n.matrixSets[0], i = this.getMatrixSetByIdentifier(r.identifier);
|
|
1668
|
+
return this.tileGridModule.then((e) => e ? e.buildOpenLayersTileGrid(i, r.limits) : null);
|
|
1669
|
+
}
|
|
1670
|
+
}, it = new EventTarget();
|
|
1671
|
+
function Y(e, t, n) {
|
|
1672
|
+
let r = typeof WorkerGlobalScope < "u", i = async (i) => {
|
|
1673
|
+
if (i.taskName === e) {
|
|
1674
|
+
let a, o;
|
|
1675
|
+
try {
|
|
1676
|
+
a = await n(i.params);
|
|
1677
|
+
} catch (e) {
|
|
1678
|
+
o = ke(e);
|
|
1679
|
+
}
|
|
1680
|
+
let s = {
|
|
1681
|
+
taskName: e,
|
|
1682
|
+
requestId: i.requestId,
|
|
1683
|
+
...a && { response: a },
|
|
1684
|
+
...o && { error: o }
|
|
1685
|
+
};
|
|
1686
|
+
r ? t.postMessage(s) : it.dispatchEvent(new CustomEvent("ogc-client.response", { detail: s }));
|
|
1687
|
+
}
|
|
1688
|
+
};
|
|
1689
|
+
r ? t.addEventListener("message", (e) => i(e.data)) : it.addEventListener("ogc-client.request", (e) => i(e.detail));
|
|
1690
|
+
}
|
|
1691
|
+
//#endregion
|
|
1692
|
+
//#region node_modules/@camptocamp/ogc-client/dist/shared/crs-utils.js
|
|
1693
|
+
var at = /* @__PURE__ */ "EPSG:4046.EPSG:4075.EPSG:4120.EPSG:4122.EPSG:4124.EPSG:4126.EPSG:4149.EPSG:4151.EPSG:4153.EPSG:4155.EPSG:4157.EPSG:4159.EPSG:4161.EPSG:4163.EPSG:4165.EPSG:4167.EPSG:4169.EPSG:4171.EPSG:4173.EPSG:4175.EPSG:4178.EPSG:4180.EPSG:4182.EPSG:4184.EPSG:4188.EPSG:4190.EPSG:4191.EPSG:4196.EPSG:4198.EPSG:4202.EPSG:4210.EPSG:4211.EPSG:4214.EPSG:4226.EPSG:4229.EPSG:4231.EPSG:4233.EPSG:4236.EPSG:4238.EPSG:4240.EPSG:4242.EPSG:4244.EPSG:4246.EPSG:4248.EPSG:4250.EPSG:4252.EPSG:4255.EPSG:4258.EPSG:4261.EPSG:4264.EPSG:4267.EPSG:4270.EPSG:4273.EPSG:4276.EPSG:4279.EPSG:4281.EPSG:4284.EPSG:4286.EPSG:4288.EPSG:4292.EPSG:4295.EPSG:4297.EPSG:4299.EPSG:4302.EPSG:4324.EPSG:4326".split(".");
|
|
1694
|
+
function ot(e) {
|
|
1695
|
+
return at.indexOf(st(e)) > -1;
|
|
1696
|
+
}
|
|
1697
|
+
function st(e) {
|
|
1698
|
+
return /^urn:(?:x-)?ogc:def:crs:epsg:/.test(e.toLowerCase()) ? `EPSG:${/([0-9]+)$/.exec(e)[1]}` : e;
|
|
1699
|
+
}
|
|
1700
|
+
//#endregion
|
|
1701
|
+
//#region node_modules/@camptocamp/ogc-client/dist/wms/capabilities.js
|
|
1702
|
+
function ct(e) {
|
|
1703
|
+
let t = {};
|
|
1704
|
+
return B(z(z(I(e), "Capability"), "Request")).forEach((e) => {
|
|
1705
|
+
let n = F(L(e));
|
|
1706
|
+
t[n] = ht(e);
|
|
1707
|
+
}), t;
|
|
1708
|
+
}
|
|
1709
|
+
function lt(e) {
|
|
1710
|
+
return I(e).attributes.version;
|
|
1711
|
+
}
|
|
1712
|
+
function ut(e) {
|
|
1713
|
+
let t = lt(e);
|
|
1714
|
+
return R(z(I(e), "Capability"), "Layer").map((e) => gt(e, t));
|
|
1715
|
+
}
|
|
1716
|
+
function dt(e) {
|
|
1717
|
+
return R(z(z(z(I(e), "Capability"), "Request"), "GetMap"), "Format").map(V);
|
|
1718
|
+
}
|
|
1719
|
+
function ft(e) {
|
|
1720
|
+
return R(z(z(z(I(e), "Capability"), "Request"), "GetFeatureInfo"), "Format").map(V);
|
|
1721
|
+
}
|
|
1722
|
+
function pt(e) {
|
|
1723
|
+
return R(z(z(I(e), "Capability"), "Exception"), "Format").map(V);
|
|
1724
|
+
}
|
|
1725
|
+
function mt(e) {
|
|
1726
|
+
let t = z(I(e), "Service"), n = dt(e), r = ft(e), i = pt(e), a = R(z(t, "KeywordList"), "Keyword").map(V).filter((e, t, n) => n.indexOf(e) === t), o = yt(e);
|
|
1727
|
+
return {
|
|
1728
|
+
title: V(z(t, "Title")),
|
|
1729
|
+
name: V(z(t, "Name")),
|
|
1730
|
+
abstract: V(z(t, "Abstract")),
|
|
1731
|
+
outputFormats: n,
|
|
1732
|
+
infoFormats: r,
|
|
1733
|
+
exceptionFormats: i,
|
|
1734
|
+
fees: V(z(t, "Fees")),
|
|
1735
|
+
constraints: V(z(t, "AccessConstraints")),
|
|
1736
|
+
provider: o,
|
|
1737
|
+
keywords: a
|
|
1738
|
+
};
|
|
1739
|
+
}
|
|
1740
|
+
function ht(e) {
|
|
1741
|
+
let t = {};
|
|
1742
|
+
return R(e, "DCPType").flatMap((e) => z(e, "HTTP")).flatMap((e) => B(e)).forEach((e) => {
|
|
1743
|
+
let n = z(e, "OnlineResource"), r = F(L(e));
|
|
1744
|
+
t[r] = H(n, "xlink:href");
|
|
1745
|
+
}), t;
|
|
1746
|
+
}
|
|
1747
|
+
function gt(e, t, n = [], r = [], i = null, a = null, o = null, s = null) {
|
|
1748
|
+
let c = t === "1.3.0" ? "CRS" : "SRS", l = R(e, c).map(V), u = l.length > 0 ? l : n, d = R(e, "Style").map(_t), f = d.length > 0 ? d : r;
|
|
1749
|
+
function p(e) {
|
|
1750
|
+
return (ot(H(e, c)) && t === "1.3.0" ? [
|
|
1751
|
+
"miny",
|
|
1752
|
+
"minx",
|
|
1753
|
+
"maxy",
|
|
1754
|
+
"maxx"
|
|
1755
|
+
] : [
|
|
1756
|
+
"minx",
|
|
1757
|
+
"miny",
|
|
1758
|
+
"maxx",
|
|
1759
|
+
"maxy"
|
|
1760
|
+
]).map((t) => H(e, t));
|
|
1761
|
+
}
|
|
1762
|
+
function m(e) {
|
|
1763
|
+
return [
|
|
1764
|
+
"westBoundLongitude",
|
|
1765
|
+
"southBoundLatitude",
|
|
1766
|
+
"eastBoundLongitude",
|
|
1767
|
+
"northBoundLatitude"
|
|
1768
|
+
].map((t) => V(z(e, t)));
|
|
1769
|
+
}
|
|
1770
|
+
function h(e) {
|
|
1771
|
+
return [
|
|
1772
|
+
"minx",
|
|
1773
|
+
"miny",
|
|
1774
|
+
"maxx",
|
|
1775
|
+
"maxy"
|
|
1776
|
+
].map((t) => H(e, t));
|
|
1777
|
+
}
|
|
1778
|
+
function g(e, t) {
|
|
1779
|
+
return e === "" ? t : Math.sqrt(.5 * parseFloat(e) ** 2) / 28e-5;
|
|
1780
|
+
}
|
|
1781
|
+
function _() {
|
|
1782
|
+
let t = z(e, "ScaleHint");
|
|
1783
|
+
if (!t) return [s, o];
|
|
1784
|
+
let n = H(t, "min"), r = H(t, "max");
|
|
1785
|
+
return [g(n, s), g(r, o)];
|
|
1786
|
+
}
|
|
1787
|
+
function v(t, n) {
|
|
1788
|
+
let r = V(z(e, t));
|
|
1789
|
+
return r === "" ? n : parseFloat(r);
|
|
1790
|
+
}
|
|
1791
|
+
let y = z(e, "Attribution"), b = y === null ? i : vt(y), x = t === "1.3.0" ? z(e, "EX_GeographicBoundingBox") : z(e, "LatLonBoundingBox"), S = {};
|
|
1792
|
+
x && (S["EPSG:4326"] = t === "1.3.0" ? m(x) : h(x));
|
|
1793
|
+
let C = R(e, "BoundingBox").reduce((e, t) => ({
|
|
1794
|
+
...e,
|
|
1795
|
+
[H(t, c)]: p(t)
|
|
1796
|
+
}), S);
|
|
1797
|
+
C = Object.keys(C).length > 0 || a === null ? C : a;
|
|
1798
|
+
let w = e.attributes.queryable === "1" || e.attributes.queryable === "true", T = e.attributes.opaque === "1" || e.attributes.opaque === "true", E = R(z(e, "KeywordList"), "Keyword").map(V).filter((e, t, n) => n.indexOf(e) === t), D, O;
|
|
1799
|
+
t === "1.3.0" ? (D = v("MinScaleDenominator", s), O = v("MaxScaleDenominator", o)) : [D, O] = _();
|
|
1800
|
+
let k = R(e, "MetadataURL").map((e) => ({
|
|
1801
|
+
type: H(e, "type"),
|
|
1802
|
+
format: V(z(e, "Format")),
|
|
1803
|
+
url: H(z(e, "OnlineResource"), "xlink:href")
|
|
1804
|
+
})), A = R(e, "Layer").map((e) => gt(e, t, u, f, b, C, O, D));
|
|
1805
|
+
return {
|
|
1806
|
+
name: V(z(e, "Name")),
|
|
1807
|
+
title: V(z(e, "Title")),
|
|
1808
|
+
abstract: V(z(e, "Abstract")),
|
|
1809
|
+
availableCrs: u,
|
|
1810
|
+
styles: f,
|
|
1811
|
+
attribution: b,
|
|
1812
|
+
boundingBoxes: C,
|
|
1813
|
+
keywords: E,
|
|
1814
|
+
queryable: w,
|
|
1815
|
+
opaque: T,
|
|
1816
|
+
...D === null ? {} : { minScaleDenominator: D },
|
|
1817
|
+
...O === null ? {} : { maxScaleDenominator: O },
|
|
1818
|
+
...k.length && { metadata: k },
|
|
1819
|
+
...A.length && { children: A }
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
function _t(e) {
|
|
1823
|
+
let t = H(z(z(e, "LegendURL"), "OnlineResource"), "xlink:href"), n = V(z(e, "Abstract"));
|
|
1824
|
+
return {
|
|
1825
|
+
name: V(z(e, "Name")),
|
|
1826
|
+
title: V(z(e, "Title")),
|
|
1827
|
+
...n && { abstract: n },
|
|
1828
|
+
...t && { legendUrl: t }
|
|
1829
|
+
};
|
|
1830
|
+
}
|
|
1831
|
+
function vt(e) {
|
|
1832
|
+
let t = H(z(z(e, "LogoURL"), "OnlineResource"), "xlink:href"), n = H(z(e, "OnlineResource"), "xlink:href"), r = V(z(e, "Title"));
|
|
1833
|
+
return {
|
|
1834
|
+
...r && { title: r },
|
|
1835
|
+
...n && { url: n },
|
|
1836
|
+
...t && { logoUrl: t }
|
|
1837
|
+
};
|
|
1838
|
+
}
|
|
1839
|
+
function yt(e) {
|
|
1840
|
+
let t = z(z(I(e), "Service"), "ContactInformation"), n = z(t, "ContactPersonPrimary"), r = z(t, "ContactAddress");
|
|
1841
|
+
return { contact: {
|
|
1842
|
+
name: V(z(n, "ContactPerson")),
|
|
1843
|
+
organization: V(z(n, "ContactOrganization")),
|
|
1844
|
+
position: V(z(t, "ContactPosition")),
|
|
1845
|
+
phone: V(z(t, "ContactVoiceTelephone")),
|
|
1846
|
+
fax: V(z(t, "ContactFacsimileTelephone")),
|
|
1847
|
+
address: {
|
|
1848
|
+
deliveryPoint: V(z(r, "Address")),
|
|
1849
|
+
city: V(z(r, "City")),
|
|
1850
|
+
administrativeArea: V(z(r, "StateOrProvince")),
|
|
1851
|
+
postalCode: V(z(r, "PostCode")),
|
|
1852
|
+
country: V(z(r, "Country"))
|
|
1853
|
+
},
|
|
1854
|
+
email: V(z(t, "ContactElectronicMailAddress"))
|
|
1855
|
+
} };
|
|
1856
|
+
}
|
|
1857
|
+
//#endregion
|
|
1858
|
+
//#region node_modules/@camptocamp/ogc-client/dist/shared/ows.js
|
|
1859
|
+
function bt(e) {
|
|
1860
|
+
let t = z(I(e), "ServiceProvider"), n = z(t, "ServiceContact"), r = z(n, "ContactInfo"), i = z(r, "Phone"), a = z(r, "Address");
|
|
1861
|
+
return {
|
|
1862
|
+
name: V(z(t, "ProviderName")),
|
|
1863
|
+
site: H(z(t, "ProviderSite"), "xlink:href"),
|
|
1864
|
+
contact: {
|
|
1865
|
+
name: V(z(n, "IndividualName")),
|
|
1866
|
+
position: V(z(n, "PositionName")),
|
|
1867
|
+
phone: V(z(i, "Voice")),
|
|
1868
|
+
fax: V(z(i, "Facsimile")),
|
|
1869
|
+
address: {
|
|
1870
|
+
deliveryPoint: V(z(a, "DeliveryPoint")),
|
|
1871
|
+
city: V(z(a, "City")),
|
|
1872
|
+
administrativeArea: V(z(a, "AdministrativeArea")),
|
|
1873
|
+
postalCode: V(z(a, "PostalCode")),
|
|
1874
|
+
country: V(z(a, "Country"))
|
|
1875
|
+
},
|
|
1876
|
+
email: V(z(a, "ElectronicMailAddress"))
|
|
1877
|
+
}
|
|
1878
|
+
};
|
|
1879
|
+
}
|
|
1880
|
+
//#endregion
|
|
1881
|
+
//#region node_modules/@camptocamp/ogc-client/dist/wfs/capabilities.js
|
|
1882
|
+
function xt(e) {
|
|
1883
|
+
let t = {}, n = I(e), r = z(n, "OperationsMetadata");
|
|
1884
|
+
return r ? R(r, "Operation").forEach((e) => {
|
|
1885
|
+
let n = H(e, "name");
|
|
1886
|
+
t[n] = Dt(e);
|
|
1887
|
+
}) : B(z(z(n, "Capability"), "Request")).forEach((e) => {
|
|
1888
|
+
let n = F(L(e));
|
|
1889
|
+
t[n] = Et(e);
|
|
1890
|
+
}), t;
|
|
1891
|
+
}
|
|
1892
|
+
function St(e) {
|
|
1893
|
+
return I(e).attributes.version;
|
|
1894
|
+
}
|
|
1895
|
+
function Ct(e) {
|
|
1896
|
+
let t = St(e), n;
|
|
1897
|
+
return n = t.startsWith("1.0") ? B(z(z(z(z(I(e), "Capability"), "Request"), "GetFeature"), "ResultFormat")).map(L) : R(R(R(z(I(e), "OperationsMetadata"), "Operation").find((e) => H(e, "name") === "GetFeature"), "Parameter").find((e) => H(e, "name") === "outputFormat"), "Value", !0).map(V), n;
|
|
1898
|
+
}
|
|
1899
|
+
function wt(e) {
|
|
1900
|
+
let t = St(e), n = t.startsWith("1.0") ? "Service" : "ServiceIdentification", r = t.startsWith("1.0") ? "Name" : "ServiceType", i = z(I(e), n), a;
|
|
1901
|
+
a = t.startsWith("1.0") ? V(z(i, "Keywords")).split(",").map((e) => e.trim()) : R(z(i, "Keywords"), "Keyword").map(V);
|
|
1902
|
+
let o;
|
|
1903
|
+
return t !== "1.0.0" && (o = bt(e)), {
|
|
1904
|
+
title: V(z(i, "Title")),
|
|
1905
|
+
name: V(z(i, r)),
|
|
1906
|
+
abstract: V(z(i, "Abstract")),
|
|
1907
|
+
fees: V(z(i, "Fees")),
|
|
1908
|
+
constraints: V(z(i, "AccessConstraints")),
|
|
1909
|
+
keywords: a,
|
|
1910
|
+
provider: o,
|
|
1911
|
+
outputFormats: Ct(e)
|
|
1912
|
+
};
|
|
1913
|
+
}
|
|
1914
|
+
function Tt(e) {
|
|
1915
|
+
let t = St(e), n = Ct(e);
|
|
1916
|
+
return R(z(I(e), "FeatureTypeList"), "FeatureType").map((e) => Ot(e, t, n));
|
|
1917
|
+
}
|
|
1918
|
+
function Et(e) {
|
|
1919
|
+
let t = {};
|
|
1920
|
+
return R(e, "DCPType").flatMap((e) => R(e, "HTTP")).flatMap((e) => B(e)).forEach((e) => {
|
|
1921
|
+
let n = F(L(e));
|
|
1922
|
+
t[n] = H(e, "onlineResource");
|
|
1923
|
+
}), t;
|
|
1924
|
+
}
|
|
1925
|
+
function Dt(e) {
|
|
1926
|
+
let t = {};
|
|
1927
|
+
return R(e, "DCP").flatMap((e) => z(e, "HTTP")).flatMap((e) => B(e)).forEach((e) => {
|
|
1928
|
+
let n = F(L(e));
|
|
1929
|
+
t[n] = H(e, "xlink:href");
|
|
1930
|
+
}), t;
|
|
1931
|
+
}
|
|
1932
|
+
function Ot(e, t, n) {
|
|
1933
|
+
let r = t.startsWith("2.") ? "CRS" : "SRS", i = t.startsWith("1.0") ? "SRS" : `Default${r}`;
|
|
1934
|
+
function a() {
|
|
1935
|
+
let t = z(e, "LatLongBoundingBox");
|
|
1936
|
+
return [
|
|
1937
|
+
"minx",
|
|
1938
|
+
"miny",
|
|
1939
|
+
"maxx",
|
|
1940
|
+
"maxy"
|
|
1941
|
+
].map((e) => H(t, e)).map(parseFloat);
|
|
1942
|
+
}
|
|
1943
|
+
function o() {
|
|
1944
|
+
let t = z(e, "WGS84BoundingBox");
|
|
1945
|
+
return ["LowerCorner", "UpperCorner"].map((e) => z(t, e)).map((e) => V(e).split(" ")).reduce((e, t) => [...e, ...t]).map(parseFloat);
|
|
1946
|
+
}
|
|
1947
|
+
let s = t.startsWith("1.0") ? [] : R(e, `Other${r}`).map(V).map(st), c = t.startsWith("1.0") ? [] : R(z(e, "OutputFormats"), "Format").map(V), l = t.startsWith("1.0") ? V(z(e, "Keywords")).split(",").map((e) => e.trim()) : R(z(e, "Keywords"), "Keyword").map(V).filter((e, t, n) => n.indexOf(e) === t), u = t === "2.0.0" ? R(e, "MetadataURL").map((e) => ({ url: H(e, "xlink:href") })) : R(e, "MetadataURL").map((e) => ({
|
|
1948
|
+
format: H(e, "format"),
|
|
1949
|
+
type: H(e, "type"),
|
|
1950
|
+
url: V(e).trim()
|
|
1951
|
+
}));
|
|
1952
|
+
return {
|
|
1953
|
+
name: V(z(e, "Name")),
|
|
1954
|
+
title: V(z(e, "Title")),
|
|
1955
|
+
abstract: V(z(e, "Abstract")),
|
|
1956
|
+
defaultCrs: st(V(z(e, i))),
|
|
1957
|
+
otherCrs: s,
|
|
1958
|
+
outputFormats: c.length > 0 ? c : n,
|
|
1959
|
+
latLonBoundingBox: t.startsWith("1.0") ? a() : o(),
|
|
1960
|
+
keywords: l,
|
|
1961
|
+
...u.length && { metadata: u }
|
|
1962
|
+
};
|
|
1963
|
+
}
|
|
1964
|
+
//#endregion
|
|
1965
|
+
//#region node_modules/@camptocamp/ogc-client/dist/wmts/capabilities.js
|
|
1966
|
+
function kt(e) {
|
|
1967
|
+
let t = ["LowerCorner", "UpperCorner"].map((t) => z(e, t)).map((e) => V(e).split(" ")).reduce((e, t) => [...e, ...t]).map(parseFloat);
|
|
1968
|
+
return t.some(Number.isNaN) ? null : t;
|
|
1969
|
+
}
|
|
1970
|
+
function At(e) {
|
|
1971
|
+
let t = I(e), n = z(t, "ServiceIdentification"), r = R(z(n, "Keywords"), "Keyword").map(V), i = R(R(z(t, "OperationsMetadata"), "Operation").find((e) => H(e, "name") == "GetTile"), "Get", !0).reduce((e, t) => {
|
|
1972
|
+
let n = V(z(t, "Value", !0)), r = H(t, "xlink:href");
|
|
1973
|
+
return n.toLowerCase() === "restful" ? {
|
|
1974
|
+
...e,
|
|
1975
|
+
rest: r
|
|
1976
|
+
} : {
|
|
1977
|
+
...e,
|
|
1978
|
+
kvp: r
|
|
1979
|
+
};
|
|
1980
|
+
}, {});
|
|
1981
|
+
return {
|
|
1982
|
+
title: V(z(n, "Title")),
|
|
1983
|
+
name: V(z(n, "ServiceType")),
|
|
1984
|
+
abstract: V(z(n, "Abstract")),
|
|
1985
|
+
fees: V(z(n, "Fees")),
|
|
1986
|
+
constraints: V(z(n, "AccessConstraints")),
|
|
1987
|
+
keywords: r,
|
|
1988
|
+
provider: bt(e),
|
|
1989
|
+
getTileUrls: i
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
function jt(e) {
|
|
1993
|
+
function t(e) {
|
|
1994
|
+
let t = V(z(e, "TopLeftCorner")).split(" ").map(parseFloat);
|
|
1995
|
+
return {
|
|
1996
|
+
identifier: V(z(e, "Identifier")),
|
|
1997
|
+
tileWidth: parseInt(V(z(e, "TileWidth"))),
|
|
1998
|
+
tileHeight: parseInt(V(z(e, "TileHeight"))),
|
|
1999
|
+
matrixWidth: parseInt(V(z(e, "MatrixWidth"))),
|
|
2000
|
+
matrixHeight: parseInt(V(z(e, "MatrixHeight"))),
|
|
2001
|
+
scaleDenominator: parseFloat(V(z(e, "ScaleDenominator"))),
|
|
2002
|
+
topLeft: t
|
|
2003
|
+
};
|
|
2004
|
+
}
|
|
2005
|
+
return R(z(I(e), "Contents"), "TileMatrixSet").map((e) => {
|
|
2006
|
+
let n = V(z(e, "WellKnownScaleSet")), r = kt(z(e, "BoundingBox"));
|
|
2007
|
+
return {
|
|
2008
|
+
identifier: V(z(e, "Identifier")),
|
|
2009
|
+
crs: V(z(e, "SupportedCRS")),
|
|
2010
|
+
tileMatrices: R(e, "TileMatrix").map(t),
|
|
2011
|
+
...r && { boundingBox: r },
|
|
2012
|
+
...n && { wellKnownScaleSet: n }
|
|
2013
|
+
};
|
|
2014
|
+
});
|
|
2015
|
+
}
|
|
2016
|
+
function Mt(e) {
|
|
2017
|
+
let t = I(e), n = z(t, "Contents");
|
|
2018
|
+
function r(e, t) {
|
|
2019
|
+
return V(z(R(e, "TileMatrixSet").find((e) => V(z(e, "Identifier")) === t), "SupportedCRS"));
|
|
2020
|
+
}
|
|
2021
|
+
function i(e) {
|
|
2022
|
+
let t = V(z(e, "TileMatrixSet"));
|
|
2023
|
+
return {
|
|
2024
|
+
identifier: t,
|
|
2025
|
+
crs: r(n, t),
|
|
2026
|
+
limits: R(e, "TileMatrixLimits", !0).map((e) => ({
|
|
2027
|
+
tileMatrix: V(z(e, "TileMatrix")),
|
|
2028
|
+
minTileRow: parseInt(V(z(e, "MinTileRow"))),
|
|
2029
|
+
minTileCol: parseInt(V(z(e, "MinTileCol"))),
|
|
2030
|
+
maxTileRow: parseInt(V(z(e, "MaxTileRow"))),
|
|
2031
|
+
maxTileCol: parseInt(V(z(e, "MaxTileCol")))
|
|
2032
|
+
}))
|
|
2033
|
+
};
|
|
2034
|
+
}
|
|
2035
|
+
let a = R(R(z(t, "OperationsMetadata"), "Operation").find((e) => H(e, "name") == "GetTile"), "Get", !0).filter((e) => V(z(e, "Value", !0)).toLowerCase() === "kvp")[0], o = a ? H(a, "xlink:href") : "";
|
|
2036
|
+
return R(z(t, "Contents"), "Layer").map((e) => {
|
|
2037
|
+
let t = kt(z(e, "WGS84BoundingBox")), n = "", r = R(e, "Style").map((e) => {
|
|
2038
|
+
let t = H(z(e, "LegendURL"), "xlink:href"), r = V(z(e, "Abstract")), i = {
|
|
2039
|
+
title: V(z(e, "Title")),
|
|
2040
|
+
name: V(z(e, "Identifier")),
|
|
2041
|
+
...r && { abstract: r },
|
|
2042
|
+
...t && { legendUrl: t }
|
|
2043
|
+
};
|
|
2044
|
+
return H(e, "isDefault") === "true" && (n = i.name), i;
|
|
2045
|
+
}), a = R(e, "Format").map(V), s = R(e, "ResourceURL").filter((e) => H(e, "resourceType") === "tile").map((e) => ({
|
|
2046
|
+
format: H(e, "format"),
|
|
2047
|
+
url: H(e, "template"),
|
|
2048
|
+
encoding: "REST"
|
|
2049
|
+
}));
|
|
2050
|
+
o && s.push(...a.map((e) => ({
|
|
2051
|
+
encoding: "KVP",
|
|
2052
|
+
url: o,
|
|
2053
|
+
format: e
|
|
2054
|
+
})));
|
|
2055
|
+
let c = R(e, "TileMatrixSetLink").map(i), l = R(e, "Dimension").map((e) => ({
|
|
2056
|
+
identifier: V(z(e, "Identifier")),
|
|
2057
|
+
defaultValue: V(z(e, "Default")),
|
|
2058
|
+
values: R(e, "Values").map(V)
|
|
2059
|
+
}));
|
|
2060
|
+
return {
|
|
2061
|
+
name: V(z(e, "Identifier")),
|
|
2062
|
+
title: V(z(e, "Title")),
|
|
2063
|
+
abstract: V(z(e, "Abstract")),
|
|
2064
|
+
styles: r,
|
|
2065
|
+
resourceLinks: s,
|
|
2066
|
+
matrixSets: c,
|
|
2067
|
+
defaultStyle: n,
|
|
2068
|
+
...t && { latLonBoundingBox: t },
|
|
2069
|
+
...l && { dimensions: l }
|
|
2070
|
+
};
|
|
2071
|
+
});
|
|
2072
|
+
}
|
|
2073
|
+
//#endregion
|
|
2074
|
+
//#region node_modules/@camptocamp/ogc-client/dist/wfs/featureprops.js
|
|
2075
|
+
function Nt(e, t, n) {
|
|
2076
|
+
let r = I(e), i;
|
|
2077
|
+
if (n.startsWith("2.0")) i = R(r, "member").map((e) => B(e)[0]);
|
|
2078
|
+
else {
|
|
2079
|
+
let e = z(r, "featureMembers");
|
|
2080
|
+
i = e ? B(e) : R(r, "featureMember").map((e) => B(e)[0]);
|
|
2081
|
+
}
|
|
2082
|
+
let a = n === "1.0.0" ? "fid" : "gml:id";
|
|
2083
|
+
function o(e) {
|
|
2084
|
+
return e in t.properties;
|
|
2085
|
+
}
|
|
2086
|
+
function s(e, n) {
|
|
2087
|
+
switch (t.properties[e]) {
|
|
2088
|
+
case "integer": return parseInt(n);
|
|
2089
|
+
case "float": return parseFloat(n);
|
|
2090
|
+
case "boolean": return n === "true";
|
|
2091
|
+
default: return n;
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
function c(e) {
|
|
2095
|
+
return B(e).filter((e) => o(F(L(e)))).reduce((e, t) => {
|
|
2096
|
+
let n = F(L(t));
|
|
2097
|
+
return {
|
|
2098
|
+
...e,
|
|
2099
|
+
[n]: s(n, V(t))
|
|
2100
|
+
};
|
|
2101
|
+
}, {});
|
|
2102
|
+
}
|
|
2103
|
+
return i.map((e) => ({
|
|
2104
|
+
id: H(e, a),
|
|
2105
|
+
properties: c(e)
|
|
2106
|
+
}));
|
|
2107
|
+
}
|
|
2108
|
+
function Pt(e) {
|
|
2109
|
+
return e.reduce((e, t) => {
|
|
2110
|
+
for (let n in t.properties) {
|
|
2111
|
+
let r = t.properties[n];
|
|
2112
|
+
n in e || (e[n] = { uniqueValues: [] });
|
|
2113
|
+
let i = e[n].uniqueValues.find((e) => e.value === r);
|
|
2114
|
+
i ? i.count++ : e[n].uniqueValues.push({
|
|
2115
|
+
value: r,
|
|
2116
|
+
count: 1
|
|
2117
|
+
});
|
|
2118
|
+
}
|
|
2119
|
+
return e;
|
|
2120
|
+
}, {});
|
|
2121
|
+
}
|
|
2122
|
+
Y("parseWmsCapabilities", globalThis, ({ url: e }) => U(e).then((t) => Oe(t, e)).then((e) => ({
|
|
2123
|
+
info: mt(e),
|
|
2124
|
+
layers: ut(e),
|
|
2125
|
+
url: ct(e),
|
|
2126
|
+
version: lt(e)
|
|
2127
|
+
}))), Y("parseWfsCapabilities", globalThis, ({ url: e }) => U(e).then((t) => Oe(t, e)).then((e) => ({
|
|
2128
|
+
info: wt(e),
|
|
2129
|
+
featureTypes: Tt(e),
|
|
2130
|
+
url: xt(e),
|
|
2131
|
+
version: St(e)
|
|
2132
|
+
}))), Y("queryWfsFeatureTypeDetails", globalThis, ({ url: e, serviceVersion: t, featureTypeFull: n }) => U(Ye(e, t, n.name, void 0, void 0, Object.keys(n.properties))).then((e) => ({ props: Pt(Nt(e, n, t)) }))), Y("updateFetchOptions", globalThis, ({ options: e }) => (Le(e), Promise.resolve({}))), Y("parseWmtsCapabilities", globalThis, ({ url: e }) => U(e).then((t) => Oe(t, e)).then((e) => ({
|
|
2133
|
+
info: At(e),
|
|
2134
|
+
layers: Mt(e),
|
|
2135
|
+
matrixSets: jt(e)
|
|
2136
|
+
})));
|
|
2137
|
+
//#endregion
|
|
2138
|
+
//#region src/utils/esri-drawing-info.ts
|
|
2139
|
+
function X(e, t = 1) {
|
|
2140
|
+
if (!e) return;
|
|
2141
|
+
let [n, r, i, a = 255] = e;
|
|
2142
|
+
return `rgba(${n}, ${r}, ${i}, ${a / 255 * t})`;
|
|
2143
|
+
}
|
|
2144
|
+
function Ft(e) {
|
|
2145
|
+
return typeof e == "number" ? (100 - Math.min(100, Math.max(0, e))) / 100 : 1;
|
|
2146
|
+
}
|
|
2147
|
+
function It(e) {
|
|
2148
|
+
return typeof e == "number" ? e : void 0;
|
|
2149
|
+
}
|
|
2150
|
+
var Lt = {
|
|
2151
|
+
esrislsdash: [4, 3],
|
|
2152
|
+
esrislsdot: [1, 3],
|
|
2153
|
+
esrislsdashdot: [
|
|
2154
|
+
4,
|
|
2155
|
+
3,
|
|
2156
|
+
1,
|
|
2157
|
+
3
|
|
2158
|
+
],
|
|
2159
|
+
esrislsdashdotdot: [
|
|
2160
|
+
4,
|
|
2161
|
+
3,
|
|
2162
|
+
1,
|
|
2163
|
+
3,
|
|
2164
|
+
1,
|
|
2165
|
+
3
|
|
2166
|
+
]
|
|
2167
|
+
};
|
|
2168
|
+
function Rt(e, t, n = 1) {
|
|
2169
|
+
if (!e) return {};
|
|
2170
|
+
switch (t) {
|
|
2171
|
+
case "fill": {
|
|
2172
|
+
let t = {}, r = X(e.outline?.color, n);
|
|
2173
|
+
r && (t["fill-outline-color"] = r);
|
|
2174
|
+
let i = X(e.color, n);
|
|
2175
|
+
return i && (t["fill-color"] = i), t;
|
|
2176
|
+
}
|
|
2177
|
+
case "line": {
|
|
2178
|
+
let t = {}, r = X(e.color, n);
|
|
2179
|
+
r && (t["line-color"] = r);
|
|
2180
|
+
let i = It(e.width);
|
|
2181
|
+
i !== void 0 && (t["line-width"] = i);
|
|
2182
|
+
let a = Lt[(e.style ?? "").toLowerCase()];
|
|
2183
|
+
return a && (t["line-dasharray"] = a), t;
|
|
2184
|
+
}
|
|
2185
|
+
case "circle": {
|
|
2186
|
+
let t = {}, r = X(e.color, n);
|
|
2187
|
+
r && (t["circle-color"] = r);
|
|
2188
|
+
let i = It(e.size);
|
|
2189
|
+
i !== void 0 && (t["circle-radius"] = i / 2);
|
|
2190
|
+
let a = X(e.outline?.color, n);
|
|
2191
|
+
a && (t["circle-stroke-color"] = a);
|
|
2192
|
+
let o = It(e.outline?.width);
|
|
2193
|
+
return o !== void 0 && (t["circle-stroke-width"] = o), t;
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
function zt(e, t) {
|
|
2198
|
+
let n = e?.outline, r = It(n?.width);
|
|
2199
|
+
if (!n || r === void 0 || r <= 1) return;
|
|
2200
|
+
let i = X(n.color, t);
|
|
2201
|
+
if (!i) return;
|
|
2202
|
+
let a = {
|
|
2203
|
+
"line-color": i,
|
|
2204
|
+
"line-width": r
|
|
2205
|
+
}, o = Lt[(n.style ?? "").toLowerCase()];
|
|
2206
|
+
return o && (a["line-dasharray"] = o), { paint: a };
|
|
2207
|
+
}
|
|
2208
|
+
var Bt = {
|
|
2209
|
+
fill: "fill-color",
|
|
2210
|
+
line: "line-color",
|
|
2211
|
+
circle: "circle-color"
|
|
2212
|
+
};
|
|
2213
|
+
function Vt(e) {
|
|
2214
|
+
let t = [
|
|
2215
|
+
e.field1,
|
|
2216
|
+
e.field2,
|
|
2217
|
+
e.field3
|
|
2218
|
+
].filter((e) => !!e);
|
|
2219
|
+
if (t.length === 0) return;
|
|
2220
|
+
if (t.length === 1) return ["get", t[0]];
|
|
2221
|
+
let n = e.fieldDelimiter ?? ",", r = ["concat"];
|
|
2222
|
+
return t.forEach((e, t) => {
|
|
2223
|
+
t > 0 && r.push(n), r.push(["to-string", ["get", e]]);
|
|
2224
|
+
}), r;
|
|
2225
|
+
}
|
|
2226
|
+
function Ht(e, t) {
|
|
2227
|
+
let n = e?.renderer;
|
|
2228
|
+
if (!n) return;
|
|
2229
|
+
let r = Ft(n.transparency);
|
|
2230
|
+
switch (n.type) {
|
|
2231
|
+
case "simple": {
|
|
2232
|
+
let e = Rt(n.symbol, t, r);
|
|
2233
|
+
if (!Object.keys(e).length) return;
|
|
2234
|
+
let i = t === "fill" ? zt(n.symbol, r) : void 0;
|
|
2235
|
+
return {
|
|
2236
|
+
paint: e,
|
|
2237
|
+
...i ? { outline: i } : {}
|
|
2238
|
+
};
|
|
2239
|
+
}
|
|
2240
|
+
case "uniqueValue": {
|
|
2241
|
+
let e = Vt(n), i = n.uniqueValueInfos;
|
|
2242
|
+
if (!e || !i?.length) return;
|
|
2243
|
+
let a = Bt[t], o = ["match", e], s, c = /* @__PURE__ */ new Set();
|
|
2244
|
+
for (let e of i) {
|
|
2245
|
+
let t = X(e.symbol?.color, r);
|
|
2246
|
+
t && (c.has(e.value) || (c.add(e.value), o.push(e.value, t), s ??= t));
|
|
2247
|
+
}
|
|
2248
|
+
if (s = X(n.defaultSymbol?.color, r) ?? s, !s) return;
|
|
2249
|
+
o.push(s);
|
|
2250
|
+
let l = Rt(i[0]?.symbol, t, r);
|
|
2251
|
+
l[a] = o;
|
|
2252
|
+
let u = t === "fill" ? zt(i[0]?.symbol, r) : void 0;
|
|
2253
|
+
return {
|
|
2254
|
+
paint: l,
|
|
2255
|
+
...u ? { outline: u } : {}
|
|
2256
|
+
};
|
|
2257
|
+
}
|
|
2258
|
+
case "classBreaks": {
|
|
2259
|
+
let e = n.field, i = n.classBreakInfos;
|
|
2260
|
+
if (!e || !i?.length) return;
|
|
2261
|
+
let a = Bt[t], o = ["step", ["get", e]], s = X(i[0]?.symbol?.color, r) ?? X(n.defaultSymbol?.color, r);
|
|
2262
|
+
if (!s) return;
|
|
2263
|
+
o.push(s);
|
|
2264
|
+
for (let e = 0; e < i.length - 1; e++) {
|
|
2265
|
+
let t = X(i[e + 1]?.symbol?.color, r) ?? X(n.defaultSymbol?.color, r);
|
|
2266
|
+
if (!t) return;
|
|
2267
|
+
o.push(i[e].classMaxValue, t);
|
|
2268
|
+
}
|
|
2269
|
+
let c = Rt(i[0]?.symbol, t, r);
|
|
2270
|
+
c[a] = o;
|
|
2271
|
+
let l = t === "fill" ? zt(i[0]?.symbol, r) : void 0;
|
|
2272
|
+
return {
|
|
2273
|
+
paint: c,
|
|
2274
|
+
...l ? { outline: l } : {}
|
|
2275
|
+
};
|
|
2276
|
+
}
|
|
2277
|
+
default: return;
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
//#endregion
|
|
2281
|
+
//#region src/utils/layer-discovery.ts
|
|
2282
|
+
typeof window < "u" && window.addEventListener("unhandledrejection", (e) => {
|
|
2283
|
+
e.reason?.name === "ServiceExceptionError" && /No service:\s*\(\s*WMTS\s*\)/.test(String(e.reason?.message)) && e.preventDefault();
|
|
2284
|
+
});
|
|
2285
|
+
function Ut(e) {
|
|
2286
|
+
return e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40) || "layer";
|
|
2287
|
+
}
|
|
2288
|
+
function Wt(e) {
|
|
2289
|
+
return e.split("?")[0].split("#")[0];
|
|
2290
|
+
}
|
|
2291
|
+
function Z(e, t, n = {}) {
|
|
2292
|
+
return {
|
|
2293
|
+
id: e,
|
|
2294
|
+
type: "raster",
|
|
2295
|
+
tiles: t,
|
|
2296
|
+
url: t,
|
|
2297
|
+
service: "xyz",
|
|
2298
|
+
...n
|
|
2299
|
+
};
|
|
2300
|
+
}
|
|
2301
|
+
function Gt(e) {
|
|
2302
|
+
if (!e || e.length !== 4) return;
|
|
2303
|
+
let t = e.map((e) => typeof e == "number" ? e : parseFloat(String(e)));
|
|
2304
|
+
return t.every(Number.isFinite) ? t : void 0;
|
|
2305
|
+
}
|
|
2306
|
+
function Q(e) {
|
|
2307
|
+
if (!Number.isFinite(e) || e <= 0) return 0;
|
|
2308
|
+
let t = Math.log2(559082264.02867 / e);
|
|
2309
|
+
return Math.max(0, Math.round(t * 100) / 100);
|
|
2310
|
+
}
|
|
2311
|
+
function Kt(e) {
|
|
2312
|
+
let t = e.match(/^(.*\/)(\d+)\/(\d+)\/(\d+)(\.[a-z0-9]+)?(\?.*)?$/i);
|
|
2313
|
+
if (!t) return null;
|
|
2314
|
+
let [, n, , , , r] = t, i = `${n}{z}/{x}/{y}${r ?? ""}`;
|
|
2315
|
+
return {
|
|
2316
|
+
serviceType: "xyz",
|
|
2317
|
+
title: `XYZ tiles (${n.replace(/^https?:\/\//, "")})`,
|
|
2318
|
+
source: Z("xyz", [i]),
|
|
2319
|
+
layer: {
|
|
2320
|
+
id: "xyz",
|
|
2321
|
+
type: "raster",
|
|
2322
|
+
source: "xyz",
|
|
2323
|
+
title: "XYZ tiles"
|
|
2324
|
+
}
|
|
2325
|
+
};
|
|
2326
|
+
}
|
|
2327
|
+
function qt(e) {
|
|
2328
|
+
let t = e.match(/^(.*\/)([\w.\-]+)\/mvt\/\d+\/\d+\/\d+(\?.*)?$/i);
|
|
2329
|
+
if (!t) return null;
|
|
2330
|
+
let [, n, r, i] = t, a = `${n}${r}/mvt/{z}/{x}/{y}${i ?? ""}`, o = r, s = {
|
|
2331
|
+
id: o,
|
|
2332
|
+
type: "vector",
|
|
2333
|
+
tiles: [a]
|
|
2334
|
+
}, c = [
|
|
2335
|
+
{
|
|
2336
|
+
id: "fill",
|
|
2337
|
+
type: "fill",
|
|
2338
|
+
source: o,
|
|
2339
|
+
"source-layer": r,
|
|
2340
|
+
filter: [
|
|
2341
|
+
"==",
|
|
2342
|
+
["geometry-type"],
|
|
2343
|
+
"Polygon"
|
|
2344
|
+
],
|
|
2345
|
+
paint: {
|
|
2346
|
+
"fill-color": "#3388ff",
|
|
2347
|
+
"fill-opacity": .4
|
|
2348
|
+
}
|
|
2349
|
+
},
|
|
2350
|
+
{
|
|
2351
|
+
id: "line",
|
|
2352
|
+
type: "line",
|
|
2353
|
+
source: o,
|
|
2354
|
+
"source-layer": r,
|
|
2355
|
+
filter: [
|
|
2356
|
+
"in",
|
|
2357
|
+
["geometry-type"],
|
|
2358
|
+
["literal", ["Polygon", "LineString"]]
|
|
2359
|
+
],
|
|
2360
|
+
paint: {
|
|
2361
|
+
"line-color": "#3388ff",
|
|
2362
|
+
"line-width": 1
|
|
2363
|
+
}
|
|
2364
|
+
},
|
|
2365
|
+
{
|
|
2366
|
+
id: "circle",
|
|
2367
|
+
type: "circle",
|
|
2368
|
+
source: o,
|
|
2369
|
+
"source-layer": r,
|
|
2370
|
+
filter: [
|
|
2371
|
+
"==",
|
|
2372
|
+
["geometry-type"],
|
|
2373
|
+
"Point"
|
|
2374
|
+
],
|
|
2375
|
+
paint: {
|
|
2376
|
+
"circle-color": "#3388ff",
|
|
2377
|
+
"circle-radius": 4
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
];
|
|
2381
|
+
return {
|
|
2382
|
+
serviceType: "xyz",
|
|
2383
|
+
title: `${r} (MVT)`,
|
|
2384
|
+
source: s,
|
|
2385
|
+
layer: {
|
|
2386
|
+
id: o,
|
|
2387
|
+
type: "style",
|
|
2388
|
+
version: 8,
|
|
2389
|
+
title: r,
|
|
2390
|
+
sources: { [o]: s },
|
|
2391
|
+
layers: c
|
|
2392
|
+
}
|
|
2393
|
+
};
|
|
2394
|
+
}
|
|
2395
|
+
function Jt(e) {
|
|
2396
|
+
let t = e.match(/^(.*\/(?:MapServer|ImageServer))\/tile\/\d+\/\d+\/\d+(\?.*)?$/i);
|
|
2397
|
+
if (!t) return null;
|
|
2398
|
+
let n = t[1], r = `${n}/tile/{z}/{y}/{x}`, i = "esri-tile";
|
|
2399
|
+
return {
|
|
2400
|
+
base: n,
|
|
2401
|
+
layer: {
|
|
2402
|
+
serviceType: "esri-tile",
|
|
2403
|
+
title: `Esri tile cache (${n.split("/").slice(-2).join("/")})`,
|
|
2404
|
+
source: Z(i, [r]),
|
|
2405
|
+
layer: {
|
|
2406
|
+
id: i,
|
|
2407
|
+
type: "raster",
|
|
2408
|
+
source: i,
|
|
2409
|
+
title: "Esri tile cache"
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
};
|
|
2413
|
+
}
|
|
2414
|
+
function Yt(e) {
|
|
2415
|
+
let t = e.match(/^(.*\/rest\/services\/.*\/(?:MapServer|FeatureServer|ImageServer))/i);
|
|
2416
|
+
return t ? t[1] : null;
|
|
2417
|
+
}
|
|
2418
|
+
async function $(e) {
|
|
2419
|
+
try {
|
|
2420
|
+
let t = await fetch(e);
|
|
2421
|
+
return t.ok ? await t.json() : null;
|
|
2422
|
+
} catch {
|
|
2423
|
+
return null;
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
async function Xt(e) {
|
|
2427
|
+
let t = await $(`${e}${e.includes("?") ? "&" : "?"}f=json`);
|
|
2428
|
+
return !t || typeof t.currentVersion != "number" ? null : t;
|
|
2429
|
+
}
|
|
2430
|
+
function Zt(e, t) {
|
|
2431
|
+
let n = Array.isArray(t.folders) ? t.folders : void 0, r = Array.isArray(t.services) ? t.services : void 0;
|
|
2432
|
+
if (!n && !r) return null;
|
|
2433
|
+
let i = e.replace(/\/+$/, ""), a = i.match(/^(.*\/rest\/services)/i), o = a ? a[1] : i, s = [];
|
|
2434
|
+
for (let e of n ?? []) s.push({
|
|
2435
|
+
name: e,
|
|
2436
|
+
url: `${i}/${e}`,
|
|
2437
|
+
kind: "folder"
|
|
2438
|
+
});
|
|
2439
|
+
for (let e of r ?? []) s.push({
|
|
2440
|
+
name: e.name,
|
|
2441
|
+
url: `${o}/${e.name}/${e.type}`,
|
|
2442
|
+
kind: "service",
|
|
2443
|
+
type: e.type
|
|
2444
|
+
});
|
|
2445
|
+
return s;
|
|
2446
|
+
}
|
|
2447
|
+
async function Qt(e) {
|
|
2448
|
+
try {
|
|
2449
|
+
let t = await new et(e).isReady(), n = t.getServiceInfo(), i = t.getFlattenedLayers(), a = t.getVersion(), o = [];
|
|
2450
|
+
for (let s of i) {
|
|
2451
|
+
if (!s.name) continue;
|
|
2452
|
+
let i = s.name, c = null;
|
|
2453
|
+
try {
|
|
2454
|
+
c = t.getLayerByName(s.name);
|
|
2455
|
+
} catch {
|
|
2456
|
+
c = null;
|
|
2457
|
+
}
|
|
2458
|
+
let l = Gt(c?.boundingBoxes?.["EPSG:4326"] ?? c?.boundingBoxes?.["CRS:84"]), u = typeof c?.maxScaleDenominator == "number" ? Q(c.maxScaleDenominator) : void 0, d = typeof c?.minScaleDenominator == "number" ? Q(c.minScaleDenominator) : void 0, f = c?.styles?.find((e) => e.legendUrl)?.legendUrl;
|
|
2459
|
+
o.push({
|
|
2460
|
+
serviceType: "wms",
|
|
2461
|
+
title: `${s.title || s.name} (WMS)`,
|
|
2462
|
+
...s.abstract ? { abstract: s.abstract } : {},
|
|
2463
|
+
source: Z(i, [r({
|
|
2464
|
+
baseUrl: Wt(t.getOperationUrl("GetMap") || e),
|
|
2465
|
+
layers: s.name,
|
|
2466
|
+
version: a
|
|
2467
|
+
}, "maplibre")], {
|
|
2468
|
+
...n?.title ? { attribution: n.title } : {},
|
|
2469
|
+
...l ? { bounds: l } : {},
|
|
2470
|
+
...c?.queryable ? {
|
|
2471
|
+
service: "wms",
|
|
2472
|
+
gfiUrl: Wt(t.getOperationUrl("GetFeatureInfo") || t.getOperationUrl("GetMap") || e),
|
|
2473
|
+
gfiLayers: s.name,
|
|
2474
|
+
gfiVersion: a
|
|
2475
|
+
} : {}
|
|
2476
|
+
}),
|
|
2477
|
+
layer: {
|
|
2478
|
+
id: i,
|
|
2479
|
+
type: "raster",
|
|
2480
|
+
source: i,
|
|
2481
|
+
title: s.title || s.name,
|
|
2482
|
+
...u === void 0 ? {} : { minzoom: u },
|
|
2483
|
+
...d === void 0 ? {} : { maxzoom: d },
|
|
2484
|
+
...s.abstract || l || f ? { metadata: {
|
|
2485
|
+
...s.abstract ? { abstract: s.abstract } : {},
|
|
2486
|
+
...l ? { bounds: l } : {},
|
|
2487
|
+
...f ? { legendurl: f } : {}
|
|
2488
|
+
} } : {}
|
|
2489
|
+
}
|
|
2490
|
+
});
|
|
2491
|
+
}
|
|
2492
|
+
return o;
|
|
2493
|
+
} catch {
|
|
2494
|
+
return [];
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
async function $t(e) {
|
|
2498
|
+
try {
|
|
2499
|
+
let t = await new rt(e).isReady(), n = t.getServiceInfo(), r = [];
|
|
2500
|
+
for (let e of t.getLayers()) {
|
|
2501
|
+
let i = e.matrixSets[0];
|
|
2502
|
+
if (!i) continue;
|
|
2503
|
+
let a = t.getTileUrl(e.name, e.defaultStyle, i.identifier, "{z}", "{y}", "{x}");
|
|
2504
|
+
if (!a) continue;
|
|
2505
|
+
let o = a.replace(/%7B/gi, "{").replace(/%7D/gi, "}"), s = e.name, c = Gt(e.latLonBoundingBox);
|
|
2506
|
+
r.push({
|
|
2507
|
+
serviceType: "wmts",
|
|
2508
|
+
title: `${e.name} (WMTS)`,
|
|
2509
|
+
source: Z(s, [o], {
|
|
2510
|
+
...n?.title ? { attribution: n.title } : {},
|
|
2511
|
+
...c ? { bounds: c } : {}
|
|
2512
|
+
}),
|
|
2513
|
+
layer: {
|
|
2514
|
+
id: s,
|
|
2515
|
+
type: "raster",
|
|
2516
|
+
source: s,
|
|
2517
|
+
title: e.name,
|
|
2518
|
+
...c ? { metadata: { bounds: c } } : {}
|
|
2519
|
+
}
|
|
2520
|
+
});
|
|
2521
|
+
}
|
|
2522
|
+
return r;
|
|
2523
|
+
} catch {
|
|
2524
|
+
return [];
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
async function en(e) {
|
|
2528
|
+
try {
|
|
2529
|
+
let t = await new Qe(e).isReady(), n = t.getFeatureTypes(), r = t.getVersion(), i = t.supportsStartIndex(), a = [];
|
|
2530
|
+
for (let e of n) {
|
|
2531
|
+
if (!e.name || !t.supportsJson(e.name)) continue;
|
|
2532
|
+
let n = e.name, o = t.getFeatureUrl(e.name, {
|
|
2533
|
+
outputFormat: "application/json",
|
|
2534
|
+
outputCrs: "EPSG:4326"
|
|
2535
|
+
}) ?? t.getFeatureUrl(e.name);
|
|
2536
|
+
if (!o) continue;
|
|
2537
|
+
let s = Gt(e.boundingBox);
|
|
2538
|
+
a.push({
|
|
2539
|
+
serviceType: "wfs",
|
|
2540
|
+
title: `${e.title || e.name} (WFS)`,
|
|
2541
|
+
...e.abstract ? { abstract: e.abstract } : {},
|
|
2542
|
+
source: {
|
|
2543
|
+
id: n,
|
|
2544
|
+
type: "geojson",
|
|
2545
|
+
data: o,
|
|
2546
|
+
service: "wfs",
|
|
2547
|
+
wfsVersion: r,
|
|
2548
|
+
wfsSupportsPaging: i,
|
|
2549
|
+
...s ? { bounds: s } : {}
|
|
2550
|
+
},
|
|
2551
|
+
layer: {
|
|
2552
|
+
id: n,
|
|
2553
|
+
type: "fill",
|
|
2554
|
+
source: n,
|
|
2555
|
+
title: e.title || e.name,
|
|
2556
|
+
paint: {
|
|
2557
|
+
"fill-color": "#3388ff",
|
|
2558
|
+
"fill-opacity": .5
|
|
2559
|
+
},
|
|
2560
|
+
...e.abstract || s ? { metadata: {
|
|
2561
|
+
...e.abstract ? { abstract: e.abstract } : {},
|
|
2562
|
+
...s ? { bounds: s } : {}
|
|
2563
|
+
} } : {}
|
|
2564
|
+
}
|
|
2565
|
+
});
|
|
2566
|
+
}
|
|
2567
|
+
return a;
|
|
2568
|
+
} catch {
|
|
2569
|
+
return [];
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
var tn = {
|
|
2573
|
+
esriGeometryPoint: "circle",
|
|
2574
|
+
esriGeometryMultipoint: "circle",
|
|
2575
|
+
esriGeometryPolyline: "line",
|
|
2576
|
+
esriGeometryPolygon: "fill"
|
|
2577
|
+
};
|
|
2578
|
+
function nn(e) {
|
|
2579
|
+
let r = e;
|
|
2580
|
+
if (!r) return;
|
|
2581
|
+
let i = r.spatialReference, a = i?.latestWkid ?? i?.wkid, { xmin: o, ymin: s, xmax: c, ymax: l } = r;
|
|
2582
|
+
if (![
|
|
2583
|
+
o,
|
|
2584
|
+
s,
|
|
2585
|
+
c,
|
|
2586
|
+
l
|
|
2587
|
+
].every(Number.isFinite)) return;
|
|
2588
|
+
if (a === 4326 || a === 4269) return [
|
|
2589
|
+
o,
|
|
2590
|
+
s,
|
|
2591
|
+
c,
|
|
2592
|
+
l
|
|
2593
|
+
];
|
|
2594
|
+
let u = a === void 0 ? void 0 : n[String(a)];
|
|
2595
|
+
if (u) try {
|
|
2596
|
+
let e = t(u, "EPSG:4326"), [n, r] = e.forward([o, s]), [i, a] = e.forward([c, l]);
|
|
2597
|
+
return [
|
|
2598
|
+
n,
|
|
2599
|
+
r,
|
|
2600
|
+
i,
|
|
2601
|
+
a
|
|
2602
|
+
].every(Number.isFinite) ? [
|
|
2603
|
+
n,
|
|
2604
|
+
r,
|
|
2605
|
+
i,
|
|
2606
|
+
a
|
|
2607
|
+
] : void 0;
|
|
2608
|
+
} catch {
|
|
2609
|
+
return;
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
async function rn(e, t, n, r, i) {
|
|
2613
|
+
let a = t.id, o = typeof t.geometryType == "string" ? t.geometryType : void 0;
|
|
2614
|
+
if (a === void 0 || !o || !(o in tn)) return null;
|
|
2615
|
+
let s = Ut(String(t.name ?? a)), c = `${e}/${a}/query?where=1%3D1&outFields=*&f=geojson&outSR=4326`, l = nn(t.extent) ?? n, u = typeof t.description == "string" && t.description ? t.description : r, d = typeof t.minScale == "number" && t.minScale > 0 ? Q(t.minScale) : void 0, f = typeof t.maxScale == "number" && t.maxScale > 0 ? Q(t.maxScale) : void 0, p = tn[o], m = (i === void 0 ? await $(`${e}/${a}?f=json`) : i)?.drawingInfo, h = Ht(m, p);
|
|
2616
|
+
p === "circle" && !h?.paint?.["circle-color"] && (h = {
|
|
2617
|
+
...h,
|
|
2618
|
+
paint: {
|
|
2619
|
+
"circle-color": "#3388ff",
|
|
2620
|
+
"circle-radius": 5,
|
|
2621
|
+
...h?.paint
|
|
2622
|
+
}
|
|
2623
|
+
});
|
|
2624
|
+
let g = String(t.name ?? `Layer ${a}`), _ = {
|
|
2625
|
+
id: s,
|
|
2626
|
+
type: "geojson",
|
|
2627
|
+
data: c,
|
|
2628
|
+
service: "esri-feature",
|
|
2629
|
+
...l ? { bounds: l } : {}
|
|
2630
|
+
}, v = u || l ? {
|
|
2631
|
+
...u ? { abstract: u } : {},
|
|
2632
|
+
...l ? { bounds: l } : {}
|
|
2633
|
+
} : void 0;
|
|
2634
|
+
return h?.outline ? {
|
|
2635
|
+
serviceType: "esri-feature",
|
|
2636
|
+
title: `${g} (Esri features)`,
|
|
2637
|
+
...u ? { abstract: u } : {},
|
|
2638
|
+
source: _,
|
|
2639
|
+
layer: {
|
|
2640
|
+
id: s,
|
|
2641
|
+
type: "style",
|
|
2642
|
+
version: 8,
|
|
2643
|
+
title: g,
|
|
2644
|
+
...d === void 0 ? {} : { minzoom: d },
|
|
2645
|
+
...f === void 0 ? {} : { maxzoom: f },
|
|
2646
|
+
sources: { [s]: _ },
|
|
2647
|
+
layers: [{
|
|
2648
|
+
id: "fill",
|
|
2649
|
+
type: p,
|
|
2650
|
+
source: s,
|
|
2651
|
+
...h.paint ? { paint: h.paint } : {}
|
|
2652
|
+
}, {
|
|
2653
|
+
id: "outline",
|
|
2654
|
+
type: "line",
|
|
2655
|
+
source: s,
|
|
2656
|
+
paint: h.outline.paint
|
|
2657
|
+
}],
|
|
2658
|
+
...v ? { metadata: v } : {}
|
|
2659
|
+
}
|
|
2660
|
+
} : {
|
|
2661
|
+
serviceType: "esri-feature",
|
|
2662
|
+
title: `${g} (Esri features)`,
|
|
2663
|
+
...u ? { abstract: u } : {},
|
|
2664
|
+
source: _,
|
|
2665
|
+
layer: {
|
|
2666
|
+
id: s,
|
|
2667
|
+
type: p,
|
|
2668
|
+
source: s,
|
|
2669
|
+
title: g,
|
|
2670
|
+
...d === void 0 ? {} : { minzoom: d },
|
|
2671
|
+
...f === void 0 ? {} : { maxzoom: f },
|
|
2672
|
+
...h?.paint ? { paint: h.paint } : {},
|
|
2673
|
+
...h?.layout ? { layout: h.layout } : {},
|
|
2674
|
+
...v ? { metadata: v } : {}
|
|
2675
|
+
}
|
|
2676
|
+
};
|
|
2677
|
+
}
|
|
2678
|
+
async function an(e, t, n) {
|
|
2679
|
+
let r = (await $(`${e}/${String(t.defaultStyles).replace(/^\/+/, "")}`))?.layers;
|
|
2680
|
+
if (!r?.length) return null;
|
|
2681
|
+
let i = Ut(String(t.name ?? "vector-tiles")), a = t.tileInfo, o = a?.lods, s = a?.maxLOD ?? (o?.length ? o[o.length - 1]?.level : void 0), c = {
|
|
2682
|
+
id: i,
|
|
2683
|
+
type: "vector",
|
|
2684
|
+
tiles: [`${e}/tile/{z}/{y}/{x}.pbf`],
|
|
2685
|
+
...typeof s == "number" ? { maxzoom: s } : {}
|
|
2686
|
+
}, l = r.filter((e) => e.type !== "background").map((e) => ({
|
|
2687
|
+
...e,
|
|
2688
|
+
source: i
|
|
2689
|
+
})), u = String(t.name ?? "Vector tiles");
|
|
2690
|
+
return {
|
|
2691
|
+
serviceType: "esri-vector-tile",
|
|
2692
|
+
title: `${u} (Esri vector tiles)`,
|
|
2693
|
+
...n ? { abstract: n } : {},
|
|
2694
|
+
source: c,
|
|
2695
|
+
layer: {
|
|
2696
|
+
id: i,
|
|
2697
|
+
type: "style",
|
|
2698
|
+
version: 8,
|
|
2699
|
+
title: u,
|
|
2700
|
+
sources: { [i]: c },
|
|
2701
|
+
layers: l,
|
|
2702
|
+
...n ? { metadata: { abstract: n } } : {}
|
|
2703
|
+
}
|
|
2704
|
+
};
|
|
2705
|
+
}
|
|
2706
|
+
async function on(e) {
|
|
2707
|
+
let t = await $(`${e}?f=json`);
|
|
2708
|
+
if (!t) return [];
|
|
2709
|
+
let n = [], r = nn(t.fullExtent), i = typeof t.description == "string" && t.description ? t.description : void 0;
|
|
2710
|
+
if (t.tileInfo) {
|
|
2711
|
+
let a = "esri-tile", o = `${e}/tile/{z}/{y}/{x}`;
|
|
2712
|
+
n.push({
|
|
2713
|
+
serviceType: "esri-tile",
|
|
2714
|
+
title: `${t.mapName || t.name || "Esri"} tile cache`,
|
|
2715
|
+
...i ? { abstract: i } : {},
|
|
2716
|
+
source: Z(a, [o], r ? { bounds: r } : {}),
|
|
2717
|
+
layer: {
|
|
2718
|
+
id: a,
|
|
2719
|
+
type: "raster",
|
|
2720
|
+
source: a,
|
|
2721
|
+
title: String(t.mapName || t.name || "Esri tile cache"),
|
|
2722
|
+
...i || r ? { metadata: {
|
|
2723
|
+
...i ? { abstract: i } : {},
|
|
2724
|
+
...r ? { bounds: r } : {}
|
|
2725
|
+
} } : {}
|
|
2726
|
+
}
|
|
2727
|
+
});
|
|
2728
|
+
}
|
|
2729
|
+
if (Array.isArray(t.tiles) && typeof t.defaultStyles == "string") {
|
|
2730
|
+
let r = await an(e, t, i);
|
|
2731
|
+
r && n.push(r);
|
|
2732
|
+
}
|
|
2733
|
+
let a = typeof t.capabilities == "string" ? t.capabilities.split(",").map((e) => e.trim().toUpperCase()) : [], o = t.documentInfo, s = typeof o?.Title == "string" && o.Title ? o.Title : void 0;
|
|
2734
|
+
if (a.includes("WMS")) {
|
|
2735
|
+
let t = await Qt(`${e}/WMSServer`);
|
|
2736
|
+
for (let e of t) s && (e.title = s, e.layer.title = s);
|
|
2737
|
+
n.push(...t);
|
|
2738
|
+
} else if (Array.isArray(t.layers) && t.layers.length > 0) {
|
|
2739
|
+
let a = "esri-export", o = t.layers.map((e) => e.id).filter((e) => typeof e == "number"), c = `${e}/export?bbox={bbox-epsg-3857}&bboxSR=3857&imageSR=3857&size=256,256&dpi=96&format=png32&transparent=true&f=image&layers=${encodeURIComponent(`show:${o.join(",")}`)}`, l = typeof t.minScale == "number" && t.minScale > 0 ? Q(t.minScale) : void 0, u = typeof t.maxScale == "number" && t.maxScale > 0 ? Q(t.maxScale) : void 0, d;
|
|
2740
|
+
if (t.layers.length === 1) {
|
|
2741
|
+
let t = (await $(`${e}/legend?f=json`))?.layers?.[0]?.legend?.[0];
|
|
2742
|
+
typeof t?.imageData == "string" && typeof t?.contentType == "string" && (d = `data:${t.contentType};base64,${t.imageData}`);
|
|
2743
|
+
}
|
|
2744
|
+
n.push({
|
|
2745
|
+
serviceType: "esri-tile",
|
|
2746
|
+
title: s ?? `${t.mapName || t.name || "Esri"} (export)`,
|
|
2747
|
+
...i ? { abstract: i } : {},
|
|
2748
|
+
source: Z(a, [c], r ? { bounds: r } : {}),
|
|
2749
|
+
layer: {
|
|
2750
|
+
id: a,
|
|
2751
|
+
type: "raster",
|
|
2752
|
+
source: a,
|
|
2753
|
+
title: s ?? String(t.mapName || t.name || "Esri export"),
|
|
2754
|
+
...l === void 0 ? {} : { minzoom: l },
|
|
2755
|
+
...u === void 0 ? {} : { maxzoom: u },
|
|
2756
|
+
...i || r || d ? { metadata: {
|
|
2757
|
+
...i ? { abstract: i } : {},
|
|
2758
|
+
...r ? { bounds: r } : {},
|
|
2759
|
+
...d ? { legendurl: d } : {}
|
|
2760
|
+
} } : {}
|
|
2761
|
+
}
|
|
2762
|
+
});
|
|
2763
|
+
}
|
|
2764
|
+
if (Array.isArray(t.layers)) {
|
|
2765
|
+
let a = await Promise.all(t.layers.map((t) => rn(e, t, r, i)));
|
|
2766
|
+
for (let e of a) e && n.push(e);
|
|
2767
|
+
} else if (typeof t.geometryType == "string") {
|
|
2768
|
+
let a = await rn(e.replace(/\/\d+$/, ""), t, r, i, t);
|
|
2769
|
+
a && n.push(a);
|
|
2770
|
+
}
|
|
2771
|
+
return n;
|
|
2772
|
+
}
|
|
2773
|
+
async function sn(e) {
|
|
2774
|
+
let t = e.trim();
|
|
2775
|
+
if (!t) return { layers: [] };
|
|
2776
|
+
let n = Wt(t), r = await Xt(n);
|
|
2777
|
+
if (r) {
|
|
2778
|
+
let e = Zt(n, r);
|
|
2779
|
+
return e ? {
|
|
2780
|
+
layers: [],
|
|
2781
|
+
catalog: e
|
|
2782
|
+
} : { layers: cn(await on(n), t) };
|
|
2783
|
+
}
|
|
2784
|
+
let i = [], a = [], o = qt(t);
|
|
2785
|
+
o && i.push(o);
|
|
2786
|
+
let s = o ? null : Kt(t);
|
|
2787
|
+
s && i.push(s);
|
|
2788
|
+
let c = Jt(t);
|
|
2789
|
+
c && i.push(c.layer), a.push(Qt(n)), a.push($t(n)), a.push(en(n));
|
|
2790
|
+
let l = Yt(t) ?? (c ? c.base : null);
|
|
2791
|
+
l && a.push(on(l));
|
|
2792
|
+
let u = await Promise.all(a);
|
|
2793
|
+
for (let e of u) i.push(...e);
|
|
2794
|
+
return { layers: cn(i, t) };
|
|
2795
|
+
}
|
|
2796
|
+
function cn(e, t) {
|
|
2797
|
+
let n;
|
|
2798
|
+
try {
|
|
2799
|
+
n = new URL(t).searchParams;
|
|
2800
|
+
} catch {
|
|
2801
|
+
return e;
|
|
2802
|
+
}
|
|
2803
|
+
let r = /* @__PURE__ */ new Set();
|
|
2804
|
+
for (let e of [
|
|
2805
|
+
"LAYERS",
|
|
2806
|
+
"layers",
|
|
2807
|
+
"LAYER",
|
|
2808
|
+
"layer"
|
|
2809
|
+
]) {
|
|
2810
|
+
let t = n.get(e);
|
|
2811
|
+
if (t) for (let e of t.split(",")) {
|
|
2812
|
+
let t = e.trim();
|
|
2813
|
+
t && r.add(t.toLowerCase());
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
if (r.size === 0) return e;
|
|
2817
|
+
let i = (e) => {
|
|
2818
|
+
let t = e.layer.id?.toLowerCase() ?? "";
|
|
2819
|
+
return Array.from(r).some((e) => t === e || t.includes(e));
|
|
2820
|
+
}, a = [], o = [];
|
|
2821
|
+
for (let t of e) (i(t) ? a : o).push(t);
|
|
2822
|
+
return [...a, ...o];
|
|
2823
|
+
}
|
|
2824
|
+
//#endregion
|
|
2825
|
+
export { sn as discoverLayers, Qt as discoverWms };
|