@7niao/doc-previewer 0.0.0-stage → 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.
Files changed (52) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +219 -2
  3. package/dist/assets/ArchiveRenderer-BZsm87A2.js +514 -0
  4. package/dist/assets/CadRenderer-DQiBmk71.js +1838 -0
  5. package/dist/assets/DocxRenderer-6BCR0R9L.js +3173 -0
  6. package/dist/assets/GisRenderer-BQ_T-z1A.js +9758 -0
  7. package/dist/assets/ImageRenderer-D1SFZkV3.js +24 -0
  8. package/dist/assets/MediaRenderer-DKj0V7cL.js +66 -0
  9. package/dist/assets/Model3dRenderer-DDk-HsYP.js +1966 -0
  10. package/dist/assets/OfdRenderer-1kDqHPDa.js +67 -0
  11. package/dist/assets/PdfRenderer-DqOFKG_L.js +16321 -0
  12. package/dist/assets/PptxRenderer-BSoVSGOz.js +48492 -0
  13. package/dist/assets/TextRenderer-pKpgA2wF.js +38 -0
  14. package/dist/assets/UnsupportedRenderer-CnjuGXg3.js +29 -0
  15. package/dist/assets/XlsxRenderer-Bohk5iIA.js +16257 -0
  16. package/dist/assets/_plugin-vue_export-helper-Djzt4Yr7.js +7 -0
  17. package/dist/assets/createLucideIcon-C_l8giLP.js +91 -0
  18. package/dist/assets/dom-Ba50_9e0.js +93 -0
  19. package/dist/assets/dwg2dxf-wasm-DO6Y5cnM.js +2148 -0
  20. package/dist/assets/file-question-mark-D7iJe3UN.js +21 -0
  21. package/dist/assets/jszip.min-OjSHaKmg.js +3039 -0
  22. package/dist/assets/ofd.es-CauEO04U.js +24255 -0
  23. package/dist/assets/rolldown-runtime-CwxnZyOB.js +22 -0
  24. package/dist/assets/three.module-B04XcvCz.js +12454 -0
  25. package/dist/assets/types-CVtHVd2P.js +168 -0
  26. package/dist/index.js +725 -0
  27. package/dist/libarchive/libarchive.wasm +0 -0
  28. package/dist/libarchive/worker-bundle.js +6 -0
  29. package/dist/style.css +2 -0
  30. package/dist/types/FileViewer.vue.d.ts +48 -0
  31. package/dist/types/components/PreviewToolbar.vue.d.ts +33 -0
  32. package/dist/types/composables/useFullscreen.d.ts +6 -0
  33. package/dist/types/composables/usePreviewSource.d.ts +14 -0
  34. package/dist/types/index.d.ts +4 -0
  35. package/dist/types/renderers/ArchiveRenderer.vue.d.ts +18 -0
  36. package/dist/types/renderers/CadRenderer.vue.d.ts +29 -0
  37. package/dist/types/renderers/DocxRenderer.vue.d.ts +16 -0
  38. package/dist/types/renderers/GisRenderer.vue.d.ts +26 -0
  39. package/dist/types/renderers/ImageRenderer.vue.d.ts +16 -0
  40. package/dist/types/renderers/MediaRenderer.vue.d.ts +17 -0
  41. package/dist/types/renderers/Model3dRenderer.vue.d.ts +29 -0
  42. package/dist/types/renderers/OfdRenderer.vue.d.ts +16 -0
  43. package/dist/types/renderers/PdfRenderer.vue.d.ts +16 -0
  44. package/dist/types/renderers/PptxRenderer.vue.d.ts +16 -0
  45. package/dist/types/renderers/TextRenderer.vue.d.ts +16 -0
  46. package/dist/types/renderers/UnsupportedRenderer.vue.d.ts +14 -0
  47. package/dist/types/renderers/XlsxRenderer.vue.d.ts +16 -0
  48. package/dist/types/types.d.ts +53 -0
  49. package/dist/types/utils/detect.d.ts +10 -0
  50. package/dist/types/utils/dom.d.ts +13 -0
  51. package/dist/types/vendor/asn1js-stub.d.ts +10 -0
  52. package/package.json +77 -3
@@ -0,0 +1,514 @@
1
+ import { t as e } from "./createLucideIcon-C_l8giLP.js";
2
+ import { r as t, s as n, t as r } from "./types-CVtHVd2P.js";
3
+ import { n as i } from "./dom-Ba50_9e0.js";
4
+ import { t as a } from "./_plugin-vue_export-helper-Djzt4Yr7.js";
5
+ import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createVNode as f, defineComponent as p, normalizeClass as ee, normalizeStyle as m, onBeforeUnmount as h, onMounted as te, openBlock as g, ref as _, renderList as v, toDisplayString as y, unref as b, vModelText as ne, withDirectives as x, withModifiers as S } from "vue";
6
+ var C = e({
7
+ name: "file",
8
+ size: 24,
9
+ node: [["path", {
10
+ d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",
11
+ key: "1oefj6"
12
+ }], ["path", {
13
+ d: "M14 2v5a1 1 0 0 0 1 1h5",
14
+ key: "wfsgrz"
15
+ }]]
16
+ }), w = e({
17
+ name: "folder-open",
18
+ size: 24,
19
+ node: [["path", {
20
+ d: "m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2",
21
+ key: "usdka0"
22
+ }]]
23
+ }), T = e({
24
+ name: "lock",
25
+ size: 24,
26
+ node: [["rect", {
27
+ width: "18",
28
+ height: "11",
29
+ x: "3",
30
+ y: "11",
31
+ rx: "2",
32
+ ry: "2",
33
+ key: "1w4ew1"
34
+ }], ["path", {
35
+ d: "M7 11V7a5 5 0 0 1 10 0v4",
36
+ key: "fwvmzm"
37
+ }]]
38
+ }), E = Symbol("Comlink.proxy"), D = Symbol("Comlink.endpoint"), O = Symbol("Comlink.releaseProxy"), k = Symbol("Comlink.finalizer"), A = Symbol("Comlink.thrown"), j = (e) => typeof e == "object" && !!e || typeof e == "function", M = /* @__PURE__ */ new Map([["proxy", {
39
+ canHandle: (e) => j(e) && e[E],
40
+ serialize(e) {
41
+ let { port1: t, port2: n } = new MessageChannel();
42
+ return N(e, t), [n, [n]];
43
+ },
44
+ deserialize: (e) => (e.start(), F(e))
45
+ }], ["throw", {
46
+ canHandle: (e) => j(e) && A in e,
47
+ serialize({ value: e }) {
48
+ let t;
49
+ return t = e instanceof Error ? {
50
+ isError: !0,
51
+ value: {
52
+ message: e.message,
53
+ name: e.name,
54
+ stack: e.stack
55
+ }
56
+ } : {
57
+ isError: !1,
58
+ value: e
59
+ }, [t, []];
60
+ },
61
+ deserialize(e) {
62
+ throw e.isError ? Object.assign(Error(e.value.message), e.value) : e.value;
63
+ }
64
+ }]]);
65
+ function N(e, t = globalThis, n = ["*"]) {
66
+ t.addEventListener("message", (function r(i) {
67
+ if (!i || !i.data) return;
68
+ if (!function(e, t) {
69
+ for (let n of e) if (t === n || n === "*" || n instanceof RegExp && n.test(t)) return !0;
70
+ return !1;
71
+ }(n, i.origin)) return void console.warn(`Invalid origin '${i.origin}' for comlink proxy`);
72
+ let { id: a, type: o, path: s } = Object.assign({ path: [] }, i.data), c = (i.data.argumentList || []).map(G), l;
73
+ try {
74
+ let t = s.slice(0, -1).reduce(((e, t) => e[t]), e), n = s.reduce(((e, t) => e[t]), e);
75
+ switch (o) {
76
+ case "GET":
77
+ l = n;
78
+ break;
79
+ case "SET":
80
+ t[s.slice(-1)[0]] = G(i.data.value), l = !0;
81
+ break;
82
+ case "APPLY":
83
+ l = n.apply(t, c);
84
+ break;
85
+ case "CONSTRUCT":
86
+ l = U(new n(...c));
87
+ break;
88
+ case "ENDPOINT":
89
+ {
90
+ let { port1: t, port2: n } = new MessageChannel();
91
+ N(e, n), l = function(e, t) {
92
+ return H.set(e, t), e;
93
+ }(t, [t]);
94
+ }
95
+ break;
96
+ case "RELEASE":
97
+ l = void 0;
98
+ break;
99
+ default: return;
100
+ }
101
+ } catch (e) {
102
+ l = {
103
+ value: e,
104
+ [A]: 0
105
+ };
106
+ }
107
+ Promise.resolve(l).catch(((e) => ({
108
+ value: e,
109
+ [A]: 0
110
+ }))).then(((n) => {
111
+ let [i, s] = W(n);
112
+ t.postMessage(Object.assign(Object.assign({}, i), { id: a }), s), o === "RELEASE" && (t.removeEventListener("message", r), P(t), k in e && typeof e[k] == "function" && e[k]());
113
+ })).catch(((e) => {
114
+ let [n, r] = W({
115
+ value: /* @__PURE__ */ TypeError("Unserializable return value"),
116
+ [A]: 0
117
+ });
118
+ t.postMessage(Object.assign(Object.assign({}, n), { id: a }), r);
119
+ }));
120
+ })), t.start && t.start();
121
+ }
122
+ function P(e) {
123
+ (function(e) {
124
+ return e.constructor.name === "MessagePort";
125
+ })(e) && e.close();
126
+ }
127
+ function F(e, t) {
128
+ return B(e, [], t);
129
+ }
130
+ function I(e) {
131
+ if (e) throw Error("Proxy has been released and is not useable");
132
+ }
133
+ function L(e) {
134
+ return K(e, { type: "RELEASE" }).then((() => {
135
+ P(e);
136
+ }));
137
+ }
138
+ var R = /* @__PURE__ */ new WeakMap(), z = "FinalizationRegistry" in globalThis && new FinalizationRegistry(((e) => {
139
+ let t = (R.get(e) || 0) - 1;
140
+ R.set(e, t), t === 0 && L(e);
141
+ }));
142
+ function B(e, t = [], n = function() {}) {
143
+ let r = !1, i = new Proxy(n, {
144
+ get(n, a) {
145
+ if (I(r), a === O) return () => {
146
+ (function(e) {
147
+ z && z.unregister(e);
148
+ })(i), L(e), r = !0;
149
+ };
150
+ if (a === "then") {
151
+ if (t.length === 0) return { then: () => i };
152
+ let n = K(e, {
153
+ type: "GET",
154
+ path: t.map(((e) => e.toString()))
155
+ }).then(G);
156
+ return n.then.bind(n);
157
+ }
158
+ return B(e, [...t, a]);
159
+ },
160
+ set(n, i, a) {
161
+ I(r);
162
+ let [o, s] = W(a);
163
+ return K(e, {
164
+ type: "SET",
165
+ path: [...t, i].map(((e) => e.toString())),
166
+ value: o
167
+ }, s).then(G);
168
+ },
169
+ apply(n, i, a) {
170
+ I(r);
171
+ let o = t[t.length - 1];
172
+ if (o === D) return K(e, { type: "ENDPOINT" }).then(G);
173
+ if (o === "bind") return B(e, t.slice(0, -1));
174
+ let [s, c] = V(a);
175
+ return K(e, {
176
+ type: "APPLY",
177
+ path: t.map(((e) => e.toString())),
178
+ argumentList: s
179
+ }, c).then(G);
180
+ },
181
+ construct(n, i) {
182
+ I(r);
183
+ let [a, o] = V(i);
184
+ return K(e, {
185
+ type: "CONSTRUCT",
186
+ path: t.map(((e) => e.toString())),
187
+ argumentList: a
188
+ }, o).then(G);
189
+ }
190
+ });
191
+ return function(e, t) {
192
+ let n = (R.get(t) || 0) + 1;
193
+ R.set(t, n), z && z.register(e, t, e);
194
+ }(i, e), i;
195
+ }
196
+ function V(e) {
197
+ let t = e.map(W);
198
+ return [t.map(((e) => e[0])), (n = t.map(((e) => e[1])), Array.prototype.concat.apply([], n))];
199
+ var n;
200
+ }
201
+ var H = /* @__PURE__ */ new WeakMap();
202
+ function U(e) {
203
+ return Object.assign(e, { [E]: !0 });
204
+ }
205
+ function W(e) {
206
+ for (let [t, n] of M) if (n.canHandle(e)) {
207
+ let [r, i] = n.serialize(e);
208
+ return [{
209
+ type: "HANDLER",
210
+ name: t,
211
+ value: r
212
+ }, i];
213
+ }
214
+ return [{
215
+ type: "RAW",
216
+ value: e
217
+ }, H.get(e) || []];
218
+ }
219
+ function G(e) {
220
+ switch (e.type) {
221
+ case "HANDLER": return M.get(e.name).deserialize(e.value);
222
+ case "RAW": return e.value;
223
+ }
224
+ }
225
+ function K(e, t, n) {
226
+ return new Promise(((r) => {
227
+ let i = [
228
+ ,
229
+ ,
230
+ ,
231
+ ,
232
+ ].fill(0).map((() => Math.floor(Math.random() * (2 ** 53 - 1)).toString(16))).join("-");
233
+ e.addEventListener("message", (function t(n) {
234
+ n.data && n.data.id && n.data.id === i && (e.removeEventListener("message", t), r(n.data));
235
+ })), e.start && e.start(), e.postMessage(Object.assign({ id: i }, t), n);
236
+ }));
237
+ }
238
+ var q = class {
239
+ constructor(e, t, n, r, i) {
240
+ this._name = e, this._size = t, this._path = n, this._lastModified = r, this._archiveRef = i;
241
+ }
242
+ get name() {
243
+ return this._name;
244
+ }
245
+ get size() {
246
+ return this._size;
247
+ }
248
+ get lastModified() {
249
+ return this._lastModified;
250
+ }
251
+ extract() {
252
+ return this._archiveRef.extractSingleFile(this._path);
253
+ }
254
+ };
255
+ function J(e) {
256
+ if (e instanceof File || e instanceof q || e === null) return e;
257
+ let t = {};
258
+ for (let n of Object.keys(e)) t[n] = J(e[n]);
259
+ return t;
260
+ }
261
+ function Y(e, t = "") {
262
+ let n = [];
263
+ for (let r of Object.keys(e)) e[r] instanceof File || e[r] instanceof q || e[r] === null ? n.push({
264
+ file: e[r] || r,
265
+ path: t
266
+ }) : n.push(...Y(e[r], `${t}${r}/`));
267
+ return n;
268
+ }
269
+ function X(e, t) {
270
+ let n = t.split("/");
271
+ n[n.length - 1] === "" && n.pop();
272
+ let r = e, i = null;
273
+ for (let e of n) r[e] = r[e] || {}, i = r, r = r[e];
274
+ return [i, n[n.length - 1]];
275
+ }
276
+ var re = class {
277
+ constructor(e, t, n) {
278
+ this._content = {}, this._processed = 0, this.file = e, this.client = t, this.worker = n;
279
+ }
280
+ open() {
281
+ return this._content = {}, this._processed = 0, new Promise(((e, t) => {
282
+ this.client.open(this.file, U((() => {
283
+ e(this);
284
+ })));
285
+ }));
286
+ }
287
+ async close() {
288
+ var e;
289
+ (e = this.worker) == null || e.terminate(), this.worker = null, this.client = null, this.file = null;
290
+ }
291
+ async hasEncryptedData() {
292
+ return await this.client.hasEncryptedData();
293
+ }
294
+ async usePassword(e) {
295
+ await this.client.usePassword(e);
296
+ }
297
+ async setLocale(e) {
298
+ await this.client.setLocale(e);
299
+ }
300
+ async getFilesObject() {
301
+ return this._processed > 0 ? Promise.resolve().then((() => this._content)) : ((await this.client.listFiles()).forEach(((e) => {
302
+ let [t, n] = X(this._content, e.path);
303
+ e.type === "FILE" && (t[n] = new q(e.fileName, e.size, e.path, e.lastModified, this));
304
+ })), this._processed = 1, J(this._content));
305
+ }
306
+ getFilesArray() {
307
+ return this.getFilesObject().then(((e) => Y(e)));
308
+ }
309
+ async extractSingleFile(e) {
310
+ if (this.worker === null) throw Error("Archive already closed");
311
+ let t = await this.client.extractSingleFile(e);
312
+ return new File([t.fileData], t.fileName, {
313
+ type: "application/octet-stream",
314
+ lastModified: t.lastModified / 1e6
315
+ });
316
+ }
317
+ async extractFiles(e = void 0) {
318
+ var t;
319
+ return this._processed > 1 ? Promise.resolve().then((() => this._content)) : ((await this.client.extractFiles()).forEach(((t) => {
320
+ let [n, r] = X(this._content, t.path);
321
+ t.type === "FILE" && (n[r] = new File([t.fileData], t.fileName, { type: "application/octet-stream" }), e !== void 0 && setTimeout(e.bind(null, {
322
+ file: n[r],
323
+ path: t.path
324
+ })));
325
+ })), this._processed = 2, (t = this.worker) == null || t.terminate(), J(this._content));
326
+ }
327
+ }, ie, ae;
328
+ (function(e) {
329
+ e.SEVEN_ZIP = "7zip", e.AR = "ar", e.ARBSD = "arbsd", e.ARGNU = "argnu", e.ARSVR4 = "arsvr4", e.BIN = "bin", e.BSDTAR = "bsdtar", e.CD9660 = "cd9660", e.CPIO = "cpio", e.GNUTAR = "gnutar", e.ISO = "iso", e.ISO9660 = "iso9660", e.MTREE = "mtree", e.MTREE_CLASSIC = "mtree-classic", e.NEWC = "newc", e.ODC = "odc", e.OLDTAR = "oldtar", e.PAX = "pax", e.PAXR = "paxr", e.POSIX = "posix", e.PWB = "pwb", e.RAW = "raw", e.RPAX = "rpax", e.SHAR = "shar", e.SHARDUMP = "shardump", e.USTAR = "ustar", e.V7TAR = "v7tar", e.V7 = "v7", e.WARC = "warc", e.XAR = "xar", e.ZIP = "zip";
330
+ })(ie ||= {}), function(e) {
331
+ e.B64ENCODE = "b64encode", e.BZIP2 = "bzip2", e.COMPRESS = "compress", e.GRZIP = "grzip", e.GZIP = "gzip", e.LRZIP = "lrzip", e.LZ4 = "lz4", e.LZIP = "lzip", e.LZMA = "lzma", e.LZOP = "lzop", e.UUENCODE = "uuencode", e.XZ = "xz", e.ZSTD = "zstd", e.NONE = "none";
332
+ }(ae ||= {});
333
+ var Z = class e {
334
+ static init(t = null) {
335
+ return e._options = t || {}, e._options;
336
+ }
337
+ static async open(t) {
338
+ let n = e.getWorker(e._options);
339
+ return await new re(t, await e.getClient(n, e._options), n).open();
340
+ }
341
+ static async write({ files: t, outputFileName: n, compression: r, format: i, passphrase: a = null }) {
342
+ let o = e.getWorker(e._options), s = await (await e.getClient(o, e._options)).writeArchive(t, r, i, a);
343
+ return o.terminate(), new File([s], n, { type: "application/octet-stream" });
344
+ }
345
+ static getWorker(e) {
346
+ return e.getWorker ? e.getWorker() : new Worker(e.workerUrl || new URL("data:text/javascript;base64,LyoqCiAqIEBsaWNlbnNlCiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMKICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjAKICovCmNvbnN0IGU9U3ltYm9sKCJDb21saW5rLnByb3h5Iikscj1TeW1ib2woIkNvbWxpbmsuZW5kcG9pbnQiKSx0PVN5bWJvbCgiQ29tbGluay5yZWxlYXNlUHJveHkiKSxuPVN5bWJvbCgiQ29tbGluay5maW5hbGl6ZXIiKSxvPVN5bWJvbCgiQ29tbGluay50aHJvd24iKSxhPWU9PiJvYmplY3QiPT10eXBlb2YgZSYmbnVsbCE9PWV8fCJmdW5jdGlvbiI9PXR5cGVvZiBlLHM9bmV3IE1hcChbWyJwcm94eSIse2NhbkhhbmRsZTpyPT5hKHIpJiZyW2VdLHNlcmlhbGl6ZShlKXtjb25zdHtwb3J0MTpyLHBvcnQyOnR9PW5ldyBNZXNzYWdlQ2hhbm5lbDtyZXR1cm4gaShlLHIpLFt0LFt0XV19LGRlc2VyaWFsaXplKGUpe3JldHVybiBlLnN0YXJ0KCksZihlLFtdLHIpO3ZhciByfX1dLFsidGhyb3ciLHtjYW5IYW5kbGU6ZT0+YShlKSYmbyBpbiBlLHNlcmlhbGl6ZSh7dmFsdWU6ZX0pe2xldCByO3JldHVybiByPWUgaW5zdGFuY2VvZiBFcnJvcj97aXNFcnJvcjohMCx2YWx1ZTp7bWVzc2FnZTplLm1lc3NhZ2UsbmFtZTplLm5hbWUsc3RhY2s6ZS5zdGFja319Ontpc0Vycm9yOiExLHZhbHVlOmV9LFtyLFtdXX0sZGVzZXJpYWxpemUoZSl7aWYoZS5pc0Vycm9yKXRocm93IE9iamVjdC5hc3NpZ24obmV3IEVycm9yKGUudmFsdWUubWVzc2FnZSksZS52YWx1ZSk7dGhyb3cgZS52YWx1ZX19XV0pO2Z1bmN0aW9uIGkocix0PWdsb2JhbFRoaXMsYT1bIioiXSl7dC5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIiwoZnVuY3Rpb24gcyhsKXtpZighbHx8IWwuZGF0YSlyZXR1cm47aWYoIWZ1bmN0aW9uKGUscil7Zm9yKGNvbnN0IHQgb2YgZSl7aWYocj09PXR8fCIqIj09PXQpcmV0dXJuITA7aWYodCBpbnN0YW5jZW9mIFJlZ0V4cCYmdC50ZXN0KHIpKXJldHVybiEwfXJldHVybiExfShhLGwub3JpZ2luKSlyZXR1cm4gdm9pZCBjb25zb2xlLndhcm4oYEludmFsaWQgb3JpZ2luICcke2wub3JpZ2lufScgZm9yIGNvbWxpbmsgcHJveHlgKTtjb25zdHtpZDpjLHR5cGU6ZCxwYXRoOmh9PU9iamVjdC5hc3NpZ24oe3BhdGg6W119LGwuZGF0YSksZj0obC5kYXRhLmFyZ3VtZW50TGlzdHx8W10pLm1hcCh3KTtsZXQgbTt0cnl7Y29uc3QgdD1oLnNsaWNlKDAsLTEpLnJlZHVjZSgoKGUscik9PmVbcl0pLHIpLG49aC5yZWR1Y2UoKChlLHIpPT5lW3JdKSxyKTtzd2l0Y2goZCl7Y2FzZSJHRVQiOm09bjticmVhaztjYXNlIlNFVCI6dFtoLnNsaWNlKC0xKVswXV09dyhsLmRhdGEudmFsdWUpLG09ITA7YnJlYWs7Y2FzZSJBUFBMWSI6bT1uLmFwcGx5KHQsZik7YnJlYWs7Y2FzZSJDT05TVFJVQ1QiOm09ZnVuY3Rpb24ocil7cmV0dXJuIE9iamVjdC5hc3NpZ24ocix7W2VdOiEwfSl9KG5ldyBuKC4uLmYpKTticmVhaztjYXNlIkVORFBPSU5UIjp7Y29uc3R7cG9ydDE6ZSxwb3J0Mjp0fT1uZXcgTWVzc2FnZUNoYW5uZWw7aShyLHQpLG09ZnVuY3Rpb24oZSxyKXtyZXR1cm4gcC5zZXQoZSxyKSxlfShlLFtlXSl9YnJlYWs7Y2FzZSJSRUxFQVNFIjptPXZvaWQgMDticmVhaztkZWZhdWx0OnJldHVybn19Y2F0Y2goZSl7bT17dmFsdWU6ZSxbb106MH19UHJvbWlzZS5yZXNvbHZlKG0pLmNhdGNoKChlPT4oe3ZhbHVlOmUsW29dOjB9KSkpLnRoZW4oKGU9Pntjb25zdFtvLGFdPXYoZSk7dC5wb3N0TWVzc2FnZShPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sbykse2lkOmN9KSxhKSwiUkVMRUFTRSI9PT1kJiYodC5yZW1vdmVFdmVudExpc3RlbmVyKCJtZXNzYWdlIixzKSx1KHQpLG4gaW4gciYmImZ1bmN0aW9uIj09dHlwZW9mIHJbbl0mJnJbbl0oKSl9KSkuY2F0Y2goKGU9Pntjb25zdFtyLG5dPXYoe3ZhbHVlOm5ldyBUeXBlRXJyb3IoIlVuc2VyaWFsaXphYmxlIHJldHVybiB2YWx1ZSIpLFtvXTowfSk7dC5wb3N0TWVzc2FnZShPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30scikse2lkOmN9KSxuKX0pKX0pKSx0LnN0YXJ0JiZ0LnN0YXJ0KCl9ZnVuY3Rpb24gdShlKXsoZnVuY3Rpb24oZSl7cmV0dXJuIk1lc3NhZ2VQb3J0Ij09PWUuY29uc3RydWN0b3IubmFtZX0pKGUpJiZlLmNsb3NlKCl9ZnVuY3Rpb24gbChlKXtpZihlKXRocm93IG5ldyBFcnJvcigiUHJveHkgaGFzIGJlZW4gcmVsZWFzZWQgYW5kIGlzIG5vdCB1c2VhYmxlIil9ZnVuY3Rpb24gYyhlKXtyZXR1cm4gZyhlLHt0eXBlOiJSRUxFQVNFIn0pLnRoZW4oKCgpPT57dShlKX0pKX1jb25zdCBkPW5ldyBXZWFrTWFwLGg9IkZpbmFsaXphdGlvblJlZ2lzdHJ5ImluIGdsb2JhbFRoaXMmJm5ldyBGaW5hbGl6YXRpb25SZWdpc3RyeSgoZT0+e2NvbnN0IHI9KGQuZ2V0KGUpfHwwKS0xO2Quc2V0KGUsciksMD09PXImJmMoZSl9KSk7ZnVuY3Rpb24gZihlLG49W10sbz1mdW5jdGlvbigpe30pe2xldCBhPSExO2NvbnN0IHM9bmV3IFByb3h5KG8se2dldChyLG8pe2lmKGwoYSksbz09PXQpcmV0dXJuKCk9PnshZnVuY3Rpb24oZSl7aCYmaC51bnJlZ2lzdGVyKGUpfShzKSxjKGUpLGE9ITB9O2lmKCJ0aGVuIj09PW8pe2lmKDA9PT1uLmxlbmd0aClyZXR1cm57dGhlbjooKT0+c307Y29uc3Qgcj1nKGUse3R5cGU6IkdFVCIscGF0aDpuLm1hcCgoZT0+ZS50b1N0cmluZygpKSl9KS50aGVuKHcpO3JldHVybiByLnRoZW4uYmluZChyKX1yZXR1cm4gZihlLFsuLi5uLG9dKX0sc2V0KHIsdCxvKXtsKGEpO2NvbnN0W3MsaV09dihvKTtyZXR1cm4gZyhlLHt0eXBlOiJTRVQiLHBhdGg6Wy4uLm4sdF0ubWFwKChlPT5lLnRvU3RyaW5nKCkpKSx2YWx1ZTpzfSxpKS50aGVuKHcpfSxhcHBseSh0LG8scyl7bChhKTtjb25zdCBpPW5bbi5sZW5ndGgtMV07aWYoaT09PXIpcmV0dXJuIGcoZSx7dHlwZToiRU5EUE9JTlQifSkudGhlbih3KTtpZigiYmluZCI9PT1pKXJldHVybiBmKGUsbi5zbGljZSgwLC0xKSk7Y29uc3RbdSxjXT1tKHMpO3JldHVybiBnKGUse3R5cGU6IkFQUExZIixwYXRoOm4ubWFwKChlPT5lLnRvU3RyaW5nKCkpKSxhcmd1bWVudExpc3Q6dX0sYykudGhlbih3KX0sY29uc3RydWN0KHIsdCl7bChhKTtjb25zdFtvLHNdPW0odCk7cmV0dXJuIGcoZSx7dHlwZToiQ09OU1RSVUNUIixwYXRoOm4ubWFwKChlPT5lLnRvU3RyaW5nKCkpKSxhcmd1bWVudExpc3Q6b30scykudGhlbih3KX19KTtyZXR1cm4gZnVuY3Rpb24oZSxyKXtjb25zdCB0PShkLmdldChyKXx8MCkrMTtkLnNldChyLHQpLGgmJmgucmVnaXN0ZXIoZSxyLGUpfShzLGUpLHN9ZnVuY3Rpb24gbShlKXtjb25zdCByPWUubWFwKHYpO3JldHVybltyLm1hcCgoZT0+ZVswXSkpLCh0PXIubWFwKChlPT5lWzFdKSksQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSx0KSldO3ZhciB0fWNvbnN0IHA9bmV3IFdlYWtNYXA7ZnVuY3Rpb24gdihlKXtmb3IoY29uc3Rbcix0XW9mIHMpaWYodC5jYW5IYW5kbGUoZSkpe2NvbnN0W24sb109dC5zZXJpYWxpemUoZSk7cmV0dXJuW3t0eXBlOiJIQU5ETEVSIixuYW1lOnIsdmFsdWU6bn0sb119cmV0dXJuW3t0eXBlOiJSQVciLHZhbHVlOmV9LHAuZ2V0KGUpfHxbXV19ZnVuY3Rpb24gdyhlKXtzd2l0Y2goZS50eXBlKXtjYXNlIkhBTkRMRVIiOnJldHVybiBzLmdldChlLm5hbWUpLmRlc2VyaWFsaXplKGUudmFsdWUpO2Nhc2UiUkFXIjpyZXR1cm4gZS52YWx1ZX19ZnVuY3Rpb24gZyhlLHIsdCl7cmV0dXJuIG5ldyBQcm9taXNlKChuPT57Y29uc3Qgbz1uZXcgQXJyYXkoNCkuZmlsbCgwKS5tYXAoKCgpPT5NYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpLnRvU3RyaW5nKDE2KSkpLmpvaW4oIi0iKTtlLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLChmdW5jdGlvbiByKHQpe3QuZGF0YSYmdC5kYXRhLmlkJiZ0LmRhdGEuaWQ9PT1vJiYoZS5yZW1vdmVFdmVudExpc3RlbmVyKCJtZXNzYWdlIixyKSxuKHQuZGF0YSkpfSkpLGUuc3RhcnQmJmUuc3RhcnQoKSxlLnBvc3RNZXNzYWdlKE9iamVjdC5hc3NpZ24oe2lkOm99LHIpLHQpfSkpfWNvbnN0IF89ezMyNzY4OiJGSUxFIiwxNjM4NDoiRElSIiw0MDk2MDoiU1lNQk9MSUNfTElOSyIsNDkxNTI6IlNPQ0tFVCIsODE5MjoiQ0hBUkFDVEVSX0RFVklDRSIsMjQ1NzY6IkJMT0NLX0RFVklDRSIsNDA5NjoiTkFNRURfUElQRSJ9O2NsYXNzIHl7Y29uc3RydWN0b3IoZSl7dGhpcy5fd2FzbU1vZHVsZT1lLHRoaXMuX3J1bkNvZGU9ZS5ydW5Db2RlLHRoaXMuX2ZpbGU9bnVsbCx0aGlzLl9wYXNzcGhyYXNlPW51bGwsdGhpcy5fbG9jYWxlPSJlbl9VUy5VVEYtOCJ9YXN5bmMgb3BlbihlKXtudWxsIT09dGhpcy5fZmlsZSYmKGNvbnNvbGUud2FybigiQ2xvc2luZyBwcmV2aW91cyBmaWxlIiksdGhpcy5jbG9zZSgpKTtjb25zdCByPWF3YWl0IHRoaXMuX2xvYWRGaWxlKGUpO3RoaXMuX2ZpbGVMZW5ndGg9ci5sZW5ndGgsdGhpcy5fZmlsZVB0cj1yLnB0cn1jbG9zZSgpe3RoaXMuX3J1bkNvZGUuY2xvc2VBcmNoaXZlKHRoaXMuX2FyY2hpdmUpLHRoaXMuX3dhc21Nb2R1bGUuX2ZyZWUodGhpcy5fZmlsZVB0ciksdGhpcy5fZmlsZT1udWxsLHRoaXMuX2ZpbGVQdHI9bnVsbCx0aGlzLl9hcmNoaXZlPW51bGx9aGFzRW5jcnlwdGVkRGF0YSgpe3RoaXMuX2FyY2hpdmU9dGhpcy5fcnVuQ29kZS5vcGVuQXJjaGl2ZSh0aGlzLl9maWxlUHRyLHRoaXMuX2ZpbGVMZW5ndGgsdGhpcy5fcGFzc3BocmFzZSx0aGlzLl9sb2NhbGUpLHRoaXMuX3J1bkNvZGUuZ2V0TmV4dEVudHJ5KHRoaXMuX2FyY2hpdmUpO2NvbnN0IGU9dGhpcy5fcnVuQ29kZS5oYXNFbmNyeXB0ZWRFbnRyaWVzKHRoaXMuX2FyY2hpdmUpO3JldHVybiAwIT09ZSYmKGU+MHx8bnVsbCl9c2V0UGFzc3BocmFzZShlKXt0aGlzLl9wYXNzcGhyYXNlPWV9c2V0TG9jYWxlKGUpe3RoaXMuX2xvY2FsZT1lfSplbnRyaWVzKGU9ITEscj1udWxsKXtsZXQgdDtmb3IodGhpcy5fYXJjaGl2ZT10aGlzLl9ydW5Db2RlLm9wZW5BcmNoaXZlKHRoaXMuX2ZpbGVQdHIsdGhpcy5fZmlsZUxlbmd0aCx0aGlzLl9wYXNzcGhyYXNlLHRoaXMuX2xvY2FsZSk7dD10aGlzLl9ydW5Db2RlLmdldE5leHRFbnRyeSh0aGlzLl9hcmNoaXZlKSwwIT09dDspe2NvbnN0IG49e3NpemU6dGhpcy5fcnVuQ29kZS5nZXRFbnRyeVNpemUodCkscGF0aDp0aGlzLl9ydW5Db2RlLmdldEVudHJ5TmFtZSh0KSx0eXBlOl9bdGhpcy5fcnVuQ29kZS5nZXRFbnRyeVR5cGUodCldLGxhc3RNb2RpZmllZDp0aGlzLl9ydW5Db2RlLmdldEVudHJ5TGFzdE1vZGlmaWVkKHQpLHJlZjp0fTtpZigiRklMRSI9PT1uLnR5cGUpe2xldCBlPW4ucGF0aC5zcGxpdCgiLyIpO24uZmlsZU5hbWU9ZVtlLmxlbmd0aC0xXX1pZihlJiZyIT09bi5wYXRoKXRoaXMuX3J1bkNvZGUuc2tpcEVudHJ5KHRoaXMuX2FyY2hpdmUpO2Vsc2V7Y29uc3QgZT10aGlzLl9ydW5Db2RlLmdldEZpbGVEYXRhKHRoaXMuX2FyY2hpdmUsbi5zaXplKTtpZihlPDApdGhyb3cgbmV3IEVycm9yKHRoaXMuX3J1bkNvZGUuZ2V0RXJyb3IodGhpcy5fYXJjaGl2ZSkpO24uZmlsZURhdGE9dGhpcy5fd2FzbU1vZHVsZS5IRUFQVTguc2xpY2UoZSxlK24uc2l6ZSksdGhpcy5fd2FzbU1vZHVsZS5fZnJlZShlKX15aWVsZCBufX1hc3luYyBfbG9hZEZpbGUoZSl7Y29uc3Qgcj1hd2FpdCBlLmFycmF5QnVmZmVyKCksdD1uZXcgVWludDhBcnJheShyKSxuPXRoaXMuX3J1bkNvZGUubWFsbG9jKHQubGVuZ3RoKTtyZXR1cm4gdGhpcy5fd2FzbU1vZHVsZS5IRUFQVTguc2V0KHQsbikse3B0cjpuLGxlbmd0aDp0Lmxlbmd0aH19fWNsYXNzIEV7Y29uc3RydWN0b3IoZSl7dGhpcy5fd2FzbU1vZHVsZT1lLHRoaXMuX3J1bkNvZGU9ZS5ydW5Db2RlLHRoaXMuX3Bhc3NwaHJhc2U9bnVsbCx0aGlzLl9sb2NhbGU9ImVuX1VTLlVURi04In1hc3luYyB3cml0ZShlLHIsdCxuPW51bGwpe2xldCBvPWUucmVkdWNlKCgoZSx7ZmlsZTpyfSk9PmUrci5zaXplKzEyOCksMCkrMTI4O2NvbnN0IGE9dGhpcy5fcnVuQ29kZS5tYWxsb2Mobykscz10aGlzLl9ydW5Db2RlLm1hbGxvYyh0aGlzLl9ydW5Db2RlLnNpemVPZlNpemVUKCkpLGk9dGhpcy5fcnVuQ29kZS5zdGFydEFyY2hpdmVXcml0ZShyLHQsYSxvLHMsbik7Zm9yKGNvbnN0e2ZpbGU6cixwYXRobmFtZTp0fW9mIGUpe2NvbnN0IGU9YXdhaXQgdGhpcy5fbG9hZEZpbGUocik7dGhpcy5fcnVuQ29kZS53cml0ZUFyY2hpdmVGaWxlKGksdHx8ci5uYW1lLGUubGVuZ3RoLGUucHRyKSx0aGlzLl9ydW5Db2RlLmZyZWUoZS5wdHIpfWNvbnN0IHU9dGhpcy5fcnVuQ29kZS5maW5pc2hBcmNoaXZlV3JpdGUoaSxzKTtpZih1PDApdGhyb3cgbmV3IEVycm9yKHRoaXMuX3J1bkNvZGUuZ2V0RXJyb3IoaSkpO3JldHVybiB0aGlzLl93YXNtTW9kdWxlLkhFQVBVOC5zbGljZShhLGErdSl9YXN5bmMgX2xvYWRGaWxlKGUpe2NvbnN0IHI9YXdhaXQgZS5hcnJheUJ1ZmZlcigpLHQ9bmV3IFVpbnQ4QXJyYXkociksbj10aGlzLl9ydW5Db2RlLm1hbGxvYyh0Lmxlbmd0aCk7cmV0dXJuIHRoaXMuX3dhc21Nb2R1bGUuSEVBUFU4LnNldCh0LG4pLHtwdHI6bixsZW5ndGg6dC5sZW5ndGh9fX12YXIgYixrPShiPWltcG9ydC5tZXRhLnVybCxhc3luYyBmdW5jdGlvbihlPXt9KXt2YXIgcix0LG49ZTtuLnJlYWR5PW5ldyBQcm9taXNlKCgoZSxuKT0+e3I9ZSx0PW59KSk7dmFyIG8sYSxzLGk9T2JqZWN0LmFzc2lnbih7fSxuKSx1PSIuL3RoaXMucHJvZ3JhbSIsbD0oZSxyKT0+e3Rocm93IHJ9LGM9Im9iamVjdCI9PXR5cGVvZiB3aW5kb3csZD0iZnVuY3Rpb24iPT10eXBlb2YgaW1wb3J0U2NyaXB0cyxoPSJvYmplY3QiPT10eXBlb2YgcHJvY2VzcyYmIm9iamVjdCI9PXR5cGVvZiBwcm9jZXNzLnZlcnNpb25zJiYic3RyaW5nIj09dHlwZW9mIHByb2Nlc3MudmVyc2lvbnMubm9kZSxmPSIiO2lmKGgpe2NvbnN0e2NyZWF0ZVJlcXVpcmU6ZX09YXdhaXQgaW1wb3J0KCJtb2R1bGUiKTt2YXIgbT1lKGltcG9ydC5tZXRhLnVybCkscD1tKCJmcyIpLHY9bSgicGF0aCIpO2Y9ZD92LmRpcm5hbWUoZikrIi8iOm0oInVybCIpLmZpbGVVUkxUb1BhdGgobmV3IFVSTCgiLi8iLGltcG9ydC5tZXRhLnVybCkpLG89KGUscik9PihlPVkoZSk/bmV3IFVSTChlKTp2Lm5vcm1hbGl6ZShlKSxwLnJlYWRGaWxlU3luYyhlLHI/dm9pZCAwOiJ1dGY4IikpLHM9ZT0+e3ZhciByPW8oZSwhMCk7cmV0dXJuIHIuYnVmZmVyfHwocj1uZXcgVWludDhBcnJheShyKSkscn0sYT0oZSxyLHQsbj0hMCk9PntlPVkoZSk/bmV3IFVSTChlKTp2Lm5vcm1hbGl6ZShlKSxwLnJlYWRGaWxlKGUsbj92b2lkIDA6InV0ZjgiLCgoZSxvKT0+e2U/dChlKTpyKG4/by5idWZmZXI6byl9KSl9LCFuLnRoaXNQcm9ncmFtJiZwcm9jZXNzLmFyZ3YubGVuZ3RoPjEmJih1PXByb2Nlc3MuYXJndlsxXS5yZXBsYWNlKC9cXC9nLCIvIikpLHByb2Nlc3MuYXJndi5zbGljZSgyKSxsPShlLHIpPT57dGhyb3cgcHJvY2Vzcy5leGl0Q29kZT1lLHJ9LG4uaW5zcGVjdD0oKT0+IltFbXNjcmlwdGVuIE1vZHVsZSBvYmplY3RdIn1lbHNlKGN8fGQpJiYoZD9mPXNlbGYubG9jYXRpb24uaHJlZjoidW5kZWZpbmVkIiE9dHlwZW9mIGRvY3VtZW50JiZkb2N1bWVudC5jdXJyZW50U2NyaXB0JiYoZj1kb2N1bWVudC5jdXJyZW50U2NyaXB0LnNyYyksYiYmKGY9YiksZj0wIT09Zi5pbmRleE9mKCJibG9iOiIpP2Yuc3Vic3RyKDAsZi5yZXBsYWNlKC9bPyNdLiovLCIiKS5sYXN0SW5kZXhPZigiLyIpKzEpOiIiLG89ZT0+e3ZhciByPW5ldyBYTUxIdHRwUmVxdWVzdDtyZXR1cm4gci5vcGVuKCJHRVQiLGUsITEpLHIuc2VuZChudWxsKSxyLnJlc3BvbnNlVGV4dH0sZCYmKHM9ZT0+e3ZhciByPW5ldyBYTUxIdHRwUmVxdWVzdDtyZXR1cm4gci5vcGVuKCJHRVQiLGUsITEpLHIucmVzcG9uc2VUeXBlPSJhcnJheWJ1ZmZlciIsci5zZW5kKG51bGwpLG5ldyBVaW50OEFycmF5KHIucmVzcG9uc2UpfSksYT0oZSxyLHQpPT57dmFyIG49bmV3IFhNTEh0dHBSZXF1ZXN0O24ub3BlbigiR0VUIixlLCEwKSxuLnJlc3BvbnNlVHlwZT0iYXJyYXlidWZmZXIiLG4ub25sb2FkPSgpPT57MjAwPT1uLnN0YXR1c3x8MD09bi5zdGF0dXMmJm4ucmVzcG9uc2U/cihuLnJlc3BvbnNlKTp0KCl9LG4ub25lcnJvcj10LG4uc2VuZChudWxsKX0pO3ZhciB3LGcsXz1uLnByaW50fHxjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpLHk9bi5wcmludEVycnx8Y29uc29sZS5lcnJvci5iaW5kKGNvbnNvbGUpO09iamVjdC5hc3NpZ24obixpKSxpPW51bGwsbi5hcmd1bWVudHMmJm4uYXJndW1lbnRzLG4udGhpc1Byb2dyYW0mJih1PW4udGhpc1Byb2dyYW0pLG4ucXVpdCYmKGw9bi5xdWl0KSxuLndhc21CaW5hcnkmJih3PW4ud2FzbUJpbmFyeSksIm9iamVjdCIhPXR5cGVvZiBXZWJBc3NlbWJseSYmTygibm8gbmF0aXZlIHdhc20gc3VwcG9ydCBkZXRlY3RlZCIpO3ZhciBFLGssUyxGLEQsTT0hMTtmdW5jdGlvbiBBKGUscil7ZXx8TyhyKX1mdW5jdGlvbiBDKCl7dmFyIGU9Zy5idWZmZXI7bi5IRUFQOD1FPW5ldyBJbnQ4QXJyYXkoZSksbi5IRUFQMTY9Uz1uZXcgSW50MTZBcnJheShlKSxuLkhFQVBVOD1rPW5ldyBVaW50OEFycmF5KGUpLG4uSEVBUFUxNj1uZXcgVWludDE2QXJyYXkoZSksbi5IRUFQMzI9Rj1uZXcgSW50MzJBcnJheShlKSxuLkhFQVBVMzI9RD1uZXcgVWludDMyQXJyYXkoZSksbi5IRUFQRjMyPW5ldyBGbG9hdDMyQXJyYXkoZSksbi5IRUFQRjY0PW5ldyBGbG9hdDY0QXJyYXkoZSl9dmFyIFA9W10sVD1bXSxSPVtdLHo9MCxVPW51bGw7ZnVuY3Rpb24gTChlKXt6Kyssbi5tb25pdG9yUnVuRGVwZW5kZW5jaWVzPy4oeil9ZnVuY3Rpb24geChlKXtpZih6LS0sbi5tb25pdG9yUnVuRGVwZW5kZW5jaWVzPy4oeiksMD09eiYmVSl7dmFyIHI9VTtVPW51bGwscigpfX1mdW5jdGlvbiBPKGUpe24ub25BYm9ydD8uKGUpLHkoZT0iQWJvcnRlZCgiK2UrIikiKSxNPSEwLGUrPSIuIEJ1aWxkIHdpdGggLXNBU1NFUlRJT05TIGZvciBtb3JlIGluZm8uIjt2YXIgcj1uZXcgV2ViQXNzZW1ibHkuUnVudGltZUVycm9yKGUpO3Rocm93IHQocikscn12YXIgTixCLGosSSxIPWU9PmUuc3RhcnRzV2l0aCgiZGF0YTphcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07YmFzZTY0LCIpLFk9ZT0+ZS5zdGFydHNXaXRoKCJmaWxlOi8vIik7ZnVuY3Rpb24gVyhlKXtpZihlPT1OJiZ3KXJldHVybiBuZXcgVWludDhBcnJheSh3KTtpZihzKXJldHVybiBzKGUpO3Rocm93ImJvdGggYXN5bmMgYW5kIHN5bmMgZmV0Y2hpbmcgb2YgdGhlIHdhc20gZmFpbGVkIn1mdW5jdGlvbiBLKGUscix0KXtyZXR1cm4gZnVuY3Rpb24oZSl7aWYoIXcmJihjfHxkKSl7aWYoImZ1bmN0aW9uIj09dHlwZW9mIGZldGNoJiYhWShlKSlyZXR1cm4gZmV0Y2goZSx7Y3JlZGVudGlhbHM6InNhbWUtb3JpZ2luIn0pLnRoZW4oKHI9PntpZighci5vayl0aHJvdyJmYWlsZWQgdG8gbG9hZCB3YXNtIGJpbmFyeSBmaWxlIGF0ICciK2UrIiciO3JldHVybiByLmFycmF5QnVmZmVyKCl9KSkuY2F0Y2goKCgpPT5XKGUpKSk7aWYoYSlyZXR1cm4gbmV3IFByb21pc2UoKChyLHQpPT57YShlLChlPT5yKG5ldyBVaW50OEFycmF5KGUpKSksdCl9KSl9cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCgpPT5XKGUpKSl9KGUpLnRoZW4oKGU9PldlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKGUscikpKS50aGVuKChlPT5lKSkudGhlbih0LChlPT57eShgZmFpbGVkIHRvIGFzeW5jaHJvbm91c2x5IHByZXBhcmUgd2FzbTogJHtlfWApLE8oZSl9KSl9ZnVuY3Rpb24gcShlKXt0aGlzLm5hbWU9IkV4aXRTdGF0dXMiLHRoaXMubWVzc2FnZT1gUHJvZ3JhbSB0ZXJtaW5hdGVkIHdpdGggZXhpdCgke2V9KWAsdGhpcy5zdGF0dXM9ZX1uLmxvY2F0ZUZpbGU/SChOPSJsaWJhcmNoaXZlLndhc20iKXx8KEI9TixOPW4ubG9jYXRlRmlsZT9uLmxvY2F0ZUZpbGUoQixmKTpmK0IpOk49bmV3IFVSTCgibGliYXJjaGl2ZS53YXNtIixpbXBvcnQubWV0YS51cmwpLmhyZWY7dmFyICQ9ZT0+e2Zvcig7ZS5sZW5ndGg+MDspZS5zaGlmdCgpKG4pfSxYPW4ubm9FeGl0UnVudGltZXx8ITAsWj17aXNBYnM6ZT0+Ii8iPT09ZS5jaGFyQXQoMCksc3BsaXRQYXRoOmU9Pi9eKFwvP3wpKFtcc1xTXSo/KSgoPzpcLnsxLDJ9fFteXC9dKz98KShcLlteLlwvXSp8KSkoPzpbXC9dKikkLy5leGVjKGUpLnNsaWNlKDEpLG5vcm1hbGl6ZUFycmF5OihlLHIpPT57Zm9yKHZhciB0PTAsbj1lLmxlbmd0aC0xO24+PTA7bi0tKXt2YXIgbz1lW25dOyIuIj09PW8/ZS5zcGxpY2UobiwxKToiLi4iPT09bz8oZS5zcGxpY2UobiwxKSx0KyspOnQmJihlLnNwbGljZShuLDEpLHQtLSl9aWYocilmb3IoO3Q7dC0tKWUudW5zaGlmdCgiLi4iKTtyZXR1cm4gZX0sbm9ybWFsaXplOmU9Pnt2YXIgcj1aLmlzQWJzKGUpLHQ9Ii8iPT09ZS5zdWJzdHIoLTEpO3JldHVybihlPVoubm9ybWFsaXplQXJyYXkoZS5zcGxpdCgiLyIpLmZpbHRlcigoZT0+ISFlKSksIXIpLmpvaW4oIi8iKSl8fHJ8fChlPSIuIiksZSYmdCYmKGUrPSIvIiksKHI/Ii8iOiIiKStlfSxkaXJuYW1lOmU9Pnt2YXIgcj1aLnNwbGl0UGF0aChlKSx0PXJbMF0sbj1yWzFdO3JldHVybiB0fHxuPyhuJiYobj1uLnN1YnN0cigwLG4ubGVuZ3RoLTEpKSx0K24pOiIuIn0sYmFzZW5hbWU6ZT0+e2lmKCIvIj09PWUpcmV0dXJuIi8iO3ZhciByPShlPShlPVoubm9ybWFsaXplKGUpKS5yZXBsYWNlKC9cLyQvLCIiKSkubGFzdEluZGV4T2YoIi8iKTtyZXR1cm4tMT09PXI/ZTplLnN1YnN0cihyKzEpfSxqb2luOmZ1bmN0aW9uKCl7dmFyIGU9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtyZXR1cm4gWi5ub3JtYWxpemUoZS5qb2luKCIvIikpfSxqb2luMjooZSxyKT0+Wi5ub3JtYWxpemUoZSsiLyIrcil9LEc9ZT0+KEc9KCgpPT57aWYoIm9iamVjdCI9PXR5cGVvZiBjcnlwdG8mJiJmdW5jdGlvbiI9PXR5cGVvZiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKXJldHVybiBlPT5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGUpO2lmKGgpdHJ5e3ZhciBlPW0oImNyeXB0byIpO2lmKGUucmFuZG9tRmlsbFN5bmMpcmV0dXJuIHI9PmUucmFuZG9tRmlsbFN5bmMocik7dmFyIHI9ZS5yYW5kb21CeXRlcztyZXR1cm4gZT0+KGUuc2V0KHIoZS5ieXRlTGVuZ3RoKSksZSl9Y2F0Y2goZSl7fU8oImluaXRSYW5kb21EZXZpY2UiKX0pKCkpKGUpLFY9e3Jlc29sdmU6ZnVuY3Rpb24oKXtmb3IodmFyIGU9IiIscj0hMSx0PWFyZ3VtZW50cy5sZW5ndGgtMTt0Pj0tMSYmIXI7dC0tKXt2YXIgbj10Pj0wP2FyZ3VtZW50c1t0XTpsZS5jd2QoKTtpZigic3RyaW5nIiE9dHlwZW9mIG4pdGhyb3cgbmV3IFR5cGVFcnJvcigiQXJndW1lbnRzIHRvIHBhdGgucmVzb2x2ZSBtdXN0IGJlIHN0cmluZ3MiKTtpZighbilyZXR1cm4iIjtlPW4rIi8iK2Uscj1aLmlzQWJzKG4pfXJldHVybihyPyIvIjoiIikrKGU9Wi5ub3JtYWxpemVBcnJheShlLnNwbGl0KCIvIikuZmlsdGVyKChlPT4hIWUpKSwhcikuam9pbigiLyIpKXx8Ii4ifSxyZWxhdGl2ZTooZSxyKT0+e2Z1bmN0aW9uIHQoZSl7Zm9yKHZhciByPTA7cjxlLmxlbmd0aCYmIiI9PT1lW3JdO3IrKyk7Zm9yKHZhciB0PWUubGVuZ3RoLTE7dD49MCYmIiI9PT1lW3RdO3QtLSk7cmV0dXJuIHI+dD9bXTplLnNsaWNlKHIsdC1yKzEpfWU9Vi5yZXNvbHZlKGUpLnN1YnN0cigxKSxyPVYucmVzb2x2ZShyKS5zdWJzdHIoMSk7Zm9yKHZhciBuPXQoZS5zcGxpdCgiLyIpKSxvPXQoci5zcGxpdCgiLyIpKSxhPU1hdGgubWluKG4ubGVuZ3RoLG8ubGVuZ3RoKSxzPWEsaT0wO2k8YTtpKyspaWYobltpXSE9PW9baV0pe3M9aTticmVha312YXIgdT1bXTtmb3IoaT1zO2k8bi5sZW5ndGg7aSsrKXUucHVzaCgiLi4iKTtyZXR1cm4odT11LmNvbmNhdChvLnNsaWNlKHMpKSkuam9pbigiLyIpfX0sSj0idW5kZWZpbmVkIiE9dHlwZW9mIFRleHREZWNvZGVyP25ldyBUZXh0RGVjb2RlcigidXRmOCIpOnZvaWQgMCxRPShlLHIsdCk9Pntmb3IodmFyIG49cit0LG89cjtlW29dJiYhKG8+PW4pOykrK287aWYoby1yPjE2JiZlLmJ1ZmZlciYmSilyZXR1cm4gSi5kZWNvZGUoZS5zdWJhcnJheShyLG8pKTtmb3IodmFyIGE9IiI7cjxvOyl7dmFyIHM9ZVtyKytdO2lmKDEyOCZzKXt2YXIgaT02MyZlW3IrK107aWYoMTkyIT0oMjI0JnMpKXt2YXIgdT02MyZlW3IrK107aWYoKHM9MjI0PT0oMjQwJnMpPygxNSZzKTw8MTJ8aTw8Nnx1Oig3JnMpPDwxOHxpPDwxMnx1PDw2fDYzJmVbcisrXSk8NjU1MzYpYSs9U3RyaW5nLmZyb21DaGFyQ29kZShzKTtlbHNle3ZhciBsPXMtNjU1MzY7YSs9U3RyaW5nLmZyb21DaGFyQ29kZSg1NTI5NnxsPj4xMCw1NjMyMHwxMDIzJmwpfX1lbHNlIGErPVN0cmluZy5mcm9tQ2hhckNvZGUoKDMxJnMpPDw2fGkpfWVsc2UgYSs9U3RyaW5nLmZyb21DaGFyQ29kZShzKX1yZXR1cm4gYX0sZWU9W10scmU9ZT0+e2Zvcih2YXIgcj0wLHQ9MDt0PGUubGVuZ3RoOysrdCl7dmFyIG49ZS5jaGFyQ29kZUF0KHQpO248PTEyNz9yKys6bjw9MjA0Nz9yKz0yOm4+PTU1Mjk2JiZuPD01NzM0Mz8ocis9NCwrK3QpOnIrPTN9cmV0dXJuIHJ9LHRlPShlLHIsdCxuKT0+e2lmKCEobj4wKSlyZXR1cm4gMDtmb3IodmFyIG89dCxhPXQrbi0xLHM9MDtzPGUubGVuZ3RoOysrcyl7dmFyIGk9ZS5jaGFyQ29kZUF0KHMpO2lmKGk+PTU1Mjk2JiZpPD01NzM0MyYmKGk9NjU1MzYrKCgxMDIzJmkpPDwxMCl8MTAyMyZlLmNoYXJDb2RlQXQoKytzKSksaTw9MTI3KXtpZih0Pj1hKWJyZWFrO3JbdCsrXT1pfWVsc2UgaWYoaTw9MjA0Nyl7aWYodCsxPj1hKWJyZWFrO3JbdCsrXT0xOTJ8aT4+NixyW3QrK109MTI4fDYzJml9ZWxzZSBpZihpPD02NTUzNSl7aWYodCsyPj1hKWJyZWFrO3JbdCsrXT0yMjR8aT4+MTIsclt0KytdPTEyOHxpPj42JjYzLHJbdCsrXT0xMjh8NjMmaX1lbHNle2lmKHQrMz49YSlicmVhaztyW3QrK109MjQwfGk+PjE4LHJbdCsrXT0xMjh8aT4+MTImNjMsclt0KytdPTEyOHxpPj42JjYzLHJbdCsrXT0xMjh8NjMmaX19cmV0dXJuIHJbdF09MCx0LW99O2Z1bmN0aW9uIG5lKGUscix0KXt2YXIgbj10PjA/dDpyZShlKSsxLG89bmV3IEFycmF5KG4pLGE9dGUoZSxvLDAsby5sZW5ndGgpO3JldHVybiByJiYoby5sZW5ndGg9YSksb312YXIgb2U9e3R0eXM6W10saW5pdCgpe30sc2h1dGRvd24oKXt9LHJlZ2lzdGVyKGUscil7b2UudHR5c1tlXT17aW5wdXQ6W10sb3V0cHV0OltdLG9wczpyfSxsZS5yZWdpc3RlckRldmljZShlLG9lLnN0cmVhbV9vcHMpfSxzdHJlYW1fb3BzOntvcGVuKGUpe3ZhciByPW9lLnR0eXNbZS5ub2RlLnJkZXZdO2lmKCFyKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQzKTtlLnR0eT1yLGUuc2Vla2FibGU9ITF9LGNsb3NlKGUpe2UudHR5Lm9wcy5mc3luYyhlLnR0eSl9LGZzeW5jKGUpe2UudHR5Lm9wcy5mc3luYyhlLnR0eSl9LHJlYWQoZSxyLHQsbixvKXtpZighZS50dHl8fCFlLnR0eS5vcHMuZ2V0X2NoYXIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNjApO2Zvcih2YXIgYT0wLHM9MDtzPG47cysrKXt2YXIgaTt0cnl7aT1lLnR0eS5vcHMuZ2V0X2NoYXIoZS50dHkpfWNhdGNoKGUpe3Rocm93IG5ldyBsZS5FcnJub0Vycm9yKDI5KX1pZih2b2lkIDA9PT1pJiYwPT09YSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig2KTtpZihudWxsPT1pKWJyZWFrO2ErKyxyW3Qrc109aX1yZXR1cm4gYSYmKGUubm9kZS50aW1lc3RhbXA9RGF0ZS5ub3coKSksYX0sd3JpdGUoZSxyLHQsbixvKXtpZighZS50dHl8fCFlLnR0eS5vcHMucHV0X2NoYXIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNjApO3RyeXtmb3IodmFyIGE9MDthPG47YSsrKWUudHR5Lm9wcy5wdXRfY2hhcihlLnR0eSxyW3QrYV0pfWNhdGNoKGUpe3Rocm93IG5ldyBsZS5FcnJub0Vycm9yKDI5KX1yZXR1cm4gbiYmKGUubm9kZS50aW1lc3RhbXA9RGF0ZS5ub3coKSksYX19LGRlZmF1bHRfdHR5X29wczp7Z2V0X2NoYXI6ZT0+KCgpPT57aWYoIWVlLmxlbmd0aCl7dmFyIGU9bnVsbDtpZihoKXt2YXIgcj1CdWZmZXIuYWxsb2MoMjU2KSx0PTAsbj1wcm9jZXNzLnN0ZGluLmZkO3RyeXt0PXAucmVhZFN5bmMobixyKX1jYXRjaChlKXtpZighZS50b1N0cmluZygpLmluY2x1ZGVzKCJFT0YiKSl0aHJvdyBlO3Q9MH1lPXQ+MD9yLnNsaWNlKDAsdCkudG9TdHJpbmcoInV0Zi04Iik6bnVsbH1lbHNlInVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3cmJiJmdW5jdGlvbiI9PXR5cGVvZiB3aW5kb3cucHJvbXB0P251bGwhPT0oZT13aW5kb3cucHJvbXB0KCJJbnB1dDogIikpJiYoZSs9IlxuIik6ImZ1bmN0aW9uIj09dHlwZW9mIHJlYWRsaW5lJiZudWxsIT09KGU9cmVhZGxpbmUoKSkmJihlKz0iXG4iKTtpZighZSlyZXR1cm4gbnVsbDtlZT1uZShlLCEwKX1yZXR1cm4gZWUuc2hpZnQoKX0pKCkscHV0X2NoYXIoZSxyKXtudWxsPT09cnx8MTA9PT1yPyhfKFEoZS5vdXRwdXQsMCkpLGUub3V0cHV0PVtdKTowIT1yJiZlLm91dHB1dC5wdXNoKHIpfSxmc3luYyhlKXtlLm91dHB1dCYmZS5vdXRwdXQubGVuZ3RoPjAmJihfKFEoZS5vdXRwdXQsMCkpLGUub3V0cHV0PVtdKX0saW9jdGxfdGNnZXRzOmU9Pih7Y19pZmxhZzoyNTg1NixjX29mbGFnOjUsY19jZmxhZzoxOTEsY19sZmxhZzozNTM4NyxjX2NjOlszLDI4LDEyNywyMSw0LDAsMSwwLDE3LDE5LDI2LDAsMTgsMTUsMjMsMjIsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMF19KSxpb2N0bF90Y3NldHM6KGUscix0KT0+MCxpb2N0bF90aW9jZ3dpbnN6OmU9PlsyNCw4MF19LGRlZmF1bHRfdHR5MV9vcHM6e3B1dF9jaGFyKGUscil7bnVsbD09PXJ8fDEwPT09cj8oeShRKGUub3V0cHV0LDApKSxlLm91dHB1dD1bXSk6MCE9ciYmZS5vdXRwdXQucHVzaChyKX0sZnN5bmMoZSl7ZS5vdXRwdXQmJmUub3V0cHV0Lmxlbmd0aD4wJiYoeShRKGUub3V0cHV0LDApKSxlLm91dHB1dD1bXSl9fX0sYWU9ZT0+e08oKX0sc2U9e29wc190YWJsZTpudWxsLG1vdW50OmU9PnNlLmNyZWF0ZU5vZGUobnVsbCwiLyIsMTY4OTUsMCksY3JlYXRlTm9kZShlLHIsdCxuKXtpZihsZS5pc0Jsa2Rldih0KXx8bGUuaXNGSUZPKHQpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYzKTtzZS5vcHNfdGFibGV8fD17ZGlyOntub2RlOntnZXRhdHRyOnNlLm5vZGVfb3BzLmdldGF0dHIsc2V0YXR0cjpzZS5ub2RlX29wcy5zZXRhdHRyLGxvb2t1cDpzZS5ub2RlX29wcy5sb29rdXAsbWtub2Q6c2Uubm9kZV9vcHMubWtub2QscmVuYW1lOnNlLm5vZGVfb3BzLnJlbmFtZSx1bmxpbms6c2Uubm9kZV9vcHMudW5saW5rLHJtZGlyOnNlLm5vZGVfb3BzLnJtZGlyLHJlYWRkaXI6c2Uubm9kZV9vcHMucmVhZGRpcixzeW1saW5rOnNlLm5vZGVfb3BzLnN5bWxpbmt9LHN0cmVhbTp7bGxzZWVrOnNlLnN0cmVhbV9vcHMubGxzZWVrfX0sZmlsZTp7bm9kZTp7Z2V0YXR0cjpzZS5ub2RlX29wcy5nZXRhdHRyLHNldGF0dHI6c2Uubm9kZV9vcHMuc2V0YXR0cn0sc3RyZWFtOntsbHNlZWs6c2Uuc3RyZWFtX29wcy5sbHNlZWsscmVhZDpzZS5zdHJlYW1fb3BzLnJlYWQsd3JpdGU6c2Uuc3RyZWFtX29wcy53cml0ZSxhbGxvY2F0ZTpzZS5zdHJlYW1fb3BzLmFsbG9jYXRlLG1tYXA6c2Uuc3RyZWFtX29wcy5tbWFwLG1zeW5jOnNlLnN0cmVhbV9vcHMubXN5bmN9fSxsaW5rOntub2RlOntnZXRhdHRyOnNlLm5vZGVfb3BzLmdldGF0dHIsc2V0YXR0cjpzZS5ub2RlX29wcy5zZXRhdHRyLHJlYWRsaW5rOnNlLm5vZGVfb3BzLnJlYWRsaW5rfSxzdHJlYW06e319LGNocmRldjp7bm9kZTp7Z2V0YXR0cjpzZS5ub2RlX29wcy5nZXRhdHRyLHNldGF0dHI6c2Uubm9kZV9vcHMuc2V0YXR0cn0sc3RyZWFtOmxlLmNocmRldl9zdHJlYW1fb3BzfX07dmFyIG89bGUuY3JlYXRlTm9kZShlLHIsdCxuKTtyZXR1cm4gbGUuaXNEaXIoby5tb2RlKT8oby5ub2RlX29wcz1zZS5vcHNfdGFibGUuZGlyLm5vZGUsby5zdHJlYW1fb3BzPXNlLm9wc190YWJsZS5kaXIuc3RyZWFtLG8uY29udGVudHM9e30pOmxlLmlzRmlsZShvLm1vZGUpPyhvLm5vZGVfb3BzPXNlLm9wc190YWJsZS5maWxlLm5vZGUsby5zdHJlYW1fb3BzPXNlLm9wc190YWJsZS5maWxlLnN0cmVhbSxvLnVzZWRCeXRlcz0wLG8uY29udGVudHM9bnVsbCk6bGUuaXNMaW5rKG8ubW9kZSk/KG8ubm9kZV9vcHM9c2Uub3BzX3RhYmxlLmxpbmsubm9kZSxvLnN0cmVhbV9vcHM9c2Uub3BzX3RhYmxlLmxpbmsuc3RyZWFtKTpsZS5pc0NocmRldihvLm1vZGUpJiYoby5ub2RlX29wcz1zZS5vcHNfdGFibGUuY2hyZGV2Lm5vZGUsby5zdHJlYW1fb3BzPXNlLm9wc190YWJsZS5jaHJkZXYuc3RyZWFtKSxvLnRpbWVzdGFtcD1EYXRlLm5vdygpLGUmJihlLmNvbnRlbnRzW3JdPW8sZS50aW1lc3RhbXA9by50aW1lc3RhbXApLG99LGdldEZpbGVEYXRhQXNUeXBlZEFycmF5OmU9PmUuY29udGVudHM/ZS5jb250ZW50cy5zdWJhcnJheT9lLmNvbnRlbnRzLnN1YmFycmF5KDAsZS51c2VkQnl0ZXMpOm5ldyBVaW50OEFycmF5KGUuY29udGVudHMpOm5ldyBVaW50OEFycmF5KDApLGV4cGFuZEZpbGVTdG9yYWdlKGUscil7dmFyIHQ9ZS5jb250ZW50cz9lLmNvbnRlbnRzLmxlbmd0aDowO2lmKCEodD49cikpe3I9TWF0aC5tYXgocix0Kih0PDEwNDg1NzY/MjoxLjEyNSk+Pj4wKSwwIT10JiYocj1NYXRoLm1heChyLDI1NikpO3ZhciBuPWUuY29udGVudHM7ZS5jb250ZW50cz1uZXcgVWludDhBcnJheShyKSxlLnVzZWRCeXRlcz4wJiZlLmNvbnRlbnRzLnNldChuLnN1YmFycmF5KDAsZS51c2VkQnl0ZXMpLDApfX0scmVzaXplRmlsZVN0b3JhZ2UoZSxyKXtpZihlLnVzZWRCeXRlcyE9cilpZigwPT1yKWUuY29udGVudHM9bnVsbCxlLnVzZWRCeXRlcz0wO2Vsc2V7dmFyIHQ9ZS5jb250ZW50cztlLmNvbnRlbnRzPW5ldyBVaW50OEFycmF5KHIpLHQmJmUuY29udGVudHMuc2V0KHQuc3ViYXJyYXkoMCxNYXRoLm1pbihyLGUudXNlZEJ5dGVzKSkpLGUudXNlZEJ5dGVzPXJ9fSxub2RlX29wczp7Z2V0YXR0cihlKXt2YXIgcj17fTtyZXR1cm4gci5kZXY9bGUuaXNDaHJkZXYoZS5tb2RlKT9lLmlkOjEsci5pbm89ZS5pZCxyLm1vZGU9ZS5tb2RlLHIubmxpbms9MSxyLnVpZD0wLHIuZ2lkPTAsci5yZGV2PWUucmRldixsZS5pc0RpcihlLm1vZGUpP3Iuc2l6ZT00MDk2OmxlLmlzRmlsZShlLm1vZGUpP3Iuc2l6ZT1lLnVzZWRCeXRlczpsZS5pc0xpbmsoZS5tb2RlKT9yLnNpemU9ZS5saW5rLmxlbmd0aDpyLnNpemU9MCxyLmF0aW1lPW5ldyBEYXRlKGUudGltZXN0YW1wKSxyLm10aW1lPW5ldyBEYXRlKGUudGltZXN0YW1wKSxyLmN0aW1lPW5ldyBEYXRlKGUudGltZXN0YW1wKSxyLmJsa3NpemU9NDA5NixyLmJsb2Nrcz1NYXRoLmNlaWwoci5zaXplL3IuYmxrc2l6ZSkscn0sc2V0YXR0cihlLHIpe3ZvaWQgMCE9PXIubW9kZSYmKGUubW9kZT1yLm1vZGUpLHZvaWQgMCE9PXIudGltZXN0YW1wJiYoZS50aW1lc3RhbXA9ci50aW1lc3RhbXApLHZvaWQgMCE9PXIuc2l6ZSYmc2UucmVzaXplRmlsZVN0b3JhZ2UoZSxyLnNpemUpfSxsb29rdXAoZSxyKXt0aHJvdyBsZS5nZW5lcmljRXJyb3JzWzQ0XX0sbWtub2Q6KGUscix0LG4pPT5zZS5jcmVhdGVOb2RlKGUscix0LG4pLHJlbmFtZShlLHIsdCl7aWYobGUuaXNEaXIoZS5tb2RlKSl7dmFyIG47dHJ5e249bGUubG9va3VwTm9kZShyLHQpfWNhdGNoKGUpe31pZihuKWZvcih2YXIgbyBpbiBuLmNvbnRlbnRzKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDU1KX1kZWxldGUgZS5wYXJlbnQuY29udGVudHNbZS5uYW1lXSxlLnBhcmVudC50aW1lc3RhbXA9RGF0ZS5ub3coKSxlLm5hbWU9dCxyLmNvbnRlbnRzW3RdPWUsci50aW1lc3RhbXA9ZS5wYXJlbnQudGltZXN0YW1wLGUucGFyZW50PXJ9LHVubGluayhlLHIpe2RlbGV0ZSBlLmNvbnRlbnRzW3JdLGUudGltZXN0YW1wPURhdGUubm93KCl9LHJtZGlyKGUscil7dmFyIHQ9bGUubG9va3VwTm9kZShlLHIpO2Zvcih2YXIgbiBpbiB0LmNvbnRlbnRzKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDU1KTtkZWxldGUgZS5jb250ZW50c1tyXSxlLnRpbWVzdGFtcD1EYXRlLm5vdygpfSxyZWFkZGlyKGUpe3ZhciByPVsiLiIsIi4uIl07Zm9yKHZhciB0IG9mIE9iamVjdC5rZXlzKGUuY29udGVudHMpKXIucHVzaCh0KTtyZXR1cm4gcn0sc3ltbGluayhlLHIsdCl7dmFyIG49c2UuY3JlYXRlTm9kZShlLHIsNDE0NzEsMCk7cmV0dXJuIG4ubGluaz10LG59LHJlYWRsaW5rKGUpe2lmKCFsZS5pc0xpbmsoZS5tb2RlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOCk7cmV0dXJuIGUubGlua319LHN0cmVhbV9vcHM6e3JlYWQoZSxyLHQsbixvKXt2YXIgYT1lLm5vZGUuY29udGVudHM7aWYobz49ZS5ub2RlLnVzZWRCeXRlcylyZXR1cm4gMDt2YXIgcz1NYXRoLm1pbihlLm5vZGUudXNlZEJ5dGVzLW8sbik7aWYocz44JiZhLnN1YmFycmF5KXIuc2V0KGEuc3ViYXJyYXkobyxvK3MpLHQpO2Vsc2UgZm9yKHZhciBpPTA7aTxzO2krKylyW3QraV09YVtvK2ldO3JldHVybiBzfSx3cml0ZShlLHIsdCxuLG8sYSl7aWYoci5idWZmZXI9PT1FLmJ1ZmZlciYmKGE9ITEpLCFuKXJldHVybiAwO3ZhciBzPWUubm9kZTtpZihzLnRpbWVzdGFtcD1EYXRlLm5vdygpLHIuc3ViYXJyYXkmJighcy5jb250ZW50c3x8cy5jb250ZW50cy5zdWJhcnJheSkpe2lmKGEpcmV0dXJuIHMuY29udGVudHM9ci5zdWJhcnJheSh0LHQrbikscy51c2VkQnl0ZXM9bixuO2lmKDA9PT1zLnVzZWRCeXRlcyYmMD09PW8pcmV0dXJuIHMuY29udGVudHM9ci5zbGljZSh0LHQrbikscy51c2VkQnl0ZXM9bixuO2lmKG8rbjw9cy51c2VkQnl0ZXMpcmV0dXJuIHMuY29udGVudHMuc2V0KHIuc3ViYXJyYXkodCx0K24pLG8pLG59aWYoc2UuZXhwYW5kRmlsZVN0b3JhZ2UocyxvK24pLHMuY29udGVudHMuc3ViYXJyYXkmJnIuc3ViYXJyYXkpcy5jb250ZW50cy5zZXQoci5zdWJhcnJheSh0LHQrbiksbyk7ZWxzZSBmb3IodmFyIGk9MDtpPG47aSsrKXMuY29udGVudHNbbytpXT1yW3QraV07cmV0dXJuIHMudXNlZEJ5dGVzPU1hdGgubWF4KHMudXNlZEJ5dGVzLG8rbiksbn0sbGxzZWVrKGUscix0KXt2YXIgbj1yO2lmKDE9PT10P24rPWUucG9zaXRpb246Mj09PXQmJmxlLmlzRmlsZShlLm5vZGUubW9kZSkmJihuKz1lLm5vZGUudXNlZEJ5dGVzKSxuPDApdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjgpO3JldHVybiBufSxhbGxvY2F0ZShlLHIsdCl7c2UuZXhwYW5kRmlsZVN0b3JhZ2UoZS5ub2RlLHIrdCksZS5ub2RlLnVzZWRCeXRlcz1NYXRoLm1heChlLm5vZGUudXNlZEJ5dGVzLHIrdCl9LG1tYXAoZSxyLHQsbixvKXtpZighbGUuaXNGaWxlKGUubm9kZS5tb2RlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0Myk7dmFyIGEscyxpPWUubm9kZS5jb250ZW50cztpZigyJm98fGkuYnVmZmVyIT09RS5idWZmZXIpe2lmKCh0PjB8fHQrcjxpLmxlbmd0aCkmJihpPWkuc3ViYXJyYXk/aS5zdWJhcnJheSh0LHQrcik6QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoaSx0LHQrcikpLHM9ITAsIShhPWFlKCkpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQ4KTtFLnNldChpLGEpfWVsc2Ugcz0hMSxhPWkuYnl0ZU9mZnNldDtyZXR1cm57cHRyOmEsYWxsb2NhdGVkOnN9fSxtc3luYzooZSxyLHQsbixvKT0+KHNlLnN0cmVhbV9vcHMud3JpdGUoZSxyLDAsbix0LCExKSwwKX19LGllPW4ucHJlbG9hZFBsdWdpbnN8fFtdLHVlPShlLHIpPT57dmFyIHQ9MDtyZXR1cm4gZSYmKHR8PTM2NSksciYmKHR8PTE0NiksdH0sbGU9e3Jvb3Q6bnVsbCxtb3VudHM6W10sZGV2aWNlczp7fSxzdHJlYW1zOltdLG5leHRJbm9kZToxLG5hbWVUYWJsZTpudWxsLGN1cnJlbnRQYXRoOiIvIixpbml0aWFsaXplZDohMSxpZ25vcmVQZXJtaXNzaW9uczohMCxFcnJub0Vycm9yOm51bGwsZ2VuZXJpY0Vycm9yczp7fSxmaWxlc3lzdGVtczpudWxsLHN5bmNGU1JlcXVlc3RzOjAsbG9va3VwUGF0aChlLHI9e30pe2lmKCEoZT1WLnJlc29sdmUoZSkpKXJldHVybntwYXRoOiIiLG5vZGU6bnVsbH07aWYoKHI9T2JqZWN0LmFzc2lnbih7Zm9sbG93X21vdW50OiEwLHJlY3Vyc2VfY291bnQ6MH0scikpLnJlY3Vyc2VfY291bnQ+OCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigzMik7Zm9yKHZhciB0PWUuc3BsaXQoIi8iKS5maWx0ZXIoKGU9PiEhZSkpLG49bGUucm9vdCxvPSIvIixhPTA7YTx0Lmxlbmd0aDthKyspe3ZhciBzPWE9PT10Lmxlbmd0aC0xO2lmKHMmJnIucGFyZW50KWJyZWFrO2lmKG49bGUubG9va3VwTm9kZShuLHRbYV0pLG89Wi5qb2luMihvLHRbYV0pLGxlLmlzTW91bnRwb2ludChuKSYmKCFzfHxzJiZyLmZvbGxvd19tb3VudCkmJihuPW4ubW91bnRlZC5yb290KSwhc3x8ci5mb2xsb3cpZm9yKHZhciBpPTA7bGUuaXNMaW5rKG4ubW9kZSk7KXt2YXIgdT1sZS5yZWFkbGluayhvKTtpZihvPVYucmVzb2x2ZShaLmRpcm5hbWUobyksdSksbj1sZS5sb29rdXBQYXRoKG8se3JlY3Vyc2VfY291bnQ6ci5yZWN1cnNlX2NvdW50KzF9KS5ub2RlLGkrKz40MCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigzMil9fXJldHVybntwYXRoOm8sbm9kZTpufX0sZ2V0UGF0aChlKXtmb3IodmFyIHI7Oyl7aWYobGUuaXNSb290KGUpKXt2YXIgdD1lLm1vdW50Lm1vdW50cG9pbnQ7cmV0dXJuIHI/Ii8iIT09dFt0Lmxlbmd0aC0xXT9gJHt0fS8ke3J9YDp0K3I6dH1yPXI/YCR7ZS5uYW1lfS8ke3J9YDplLm5hbWUsZT1lLnBhcmVudH19LGhhc2hOYW1lKGUscil7Zm9yKHZhciB0PTAsbj0wO248ci5sZW5ndGg7bisrKXQ9KHQ8PDUpLXQrci5jaGFyQ29kZUF0KG4pfDA7cmV0dXJuKGUrdD4+PjApJWxlLm5hbWVUYWJsZS5sZW5ndGh9LGhhc2hBZGROb2RlKGUpe3ZhciByPWxlLmhhc2hOYW1lKGUucGFyZW50LmlkLGUubmFtZSk7ZS5uYW1lX25leHQ9bGUubmFtZVRhYmxlW3JdLGxlLm5hbWVUYWJsZVtyXT1lfSxoYXNoUmVtb3ZlTm9kZShlKXt2YXIgcj1sZS5oYXNoTmFtZShlLnBhcmVudC5pZCxlLm5hbWUpO2lmKGxlLm5hbWVUYWJsZVtyXT09PWUpbGUubmFtZVRhYmxlW3JdPWUubmFtZV9uZXh0O2Vsc2UgZm9yKHZhciB0PWxlLm5hbWVUYWJsZVtyXTt0Oyl7aWYodC5uYW1lX25leHQ9PT1lKXt0Lm5hbWVfbmV4dD1lLm5hbWVfbmV4dDticmVha310PXQubmFtZV9uZXh0fX0sbG9va3VwTm9kZShlLHIpe3ZhciB0PWxlLm1heUxvb2t1cChlKTtpZih0KXRocm93IG5ldyBsZS5FcnJub0Vycm9yKHQsZSk7Zm9yKHZhciBuPWxlLmhhc2hOYW1lKGUuaWQsciksbz1sZS5uYW1lVGFibGVbbl07bztvPW8ubmFtZV9uZXh0KXt2YXIgYT1vLm5hbWU7aWYoby5wYXJlbnQuaWQ9PT1lLmlkJiZhPT09cilyZXR1cm4gb31yZXR1cm4gbGUubG9va3VwKGUscil9LGNyZWF0ZU5vZGUoZSxyLHQsbil7dmFyIG89bmV3IGxlLkZTTm9kZShlLHIsdCxuKTtyZXR1cm4gbGUuaGFzaEFkZE5vZGUobyksb30sZGVzdHJveU5vZGUoZSl7bGUuaGFzaFJlbW92ZU5vZGUoZSl9LGlzUm9vdDplPT5lPT09ZS5wYXJlbnQsaXNNb3VudHBvaW50OmU9PiEhZS5tb3VudGVkLGlzRmlsZTplPT4zMjc2OD09KDYxNDQwJmUpLGlzRGlyOmU9PjE2Mzg0PT0oNjE0NDAmZSksaXNMaW5rOmU9PjQwOTYwPT0oNjE0NDAmZSksaXNDaHJkZXY6ZT0+ODE5Mj09KDYxNDQwJmUpLGlzQmxrZGV2OmU9PjI0NTc2PT0oNjE0NDAmZSksaXNGSUZPOmU9PjQwOTY9PSg2MTQ0MCZlKSxpc1NvY2tldDplPT40OTE1Mj09KDQ5MTUyJmUpLGZsYWdzVG9QZXJtaXNzaW9uU3RyaW5nKGUpe3ZhciByPVsiciIsInciLCJydyJdWzMmZV07cmV0dXJuIDUxMiZlJiYocis9InciKSxyfSxub2RlUGVybWlzc2lvbnM6KGUscik9PmxlLmlnbm9yZVBlcm1pc3Npb25zfHwoIXIuaW5jbHVkZXMoInIiKXx8MjkyJmUubW9kZSkmJighci5pbmNsdWRlcygidyIpfHwxNDYmZS5tb2RlKSYmKCFyLmluY2x1ZGVzKCJ4Iil8fDczJmUubW9kZSk/MDoyLG1heUxvb2t1cChlKXt2YXIgcj1sZS5ub2RlUGVybWlzc2lvbnMoZSwieCIpO3JldHVybiByfHwoZS5ub2RlX29wcy5sb29rdXA/MDoyKX0sbWF5Q3JlYXRlKGUscil7dHJ5e3JldHVybiBsZS5sb29rdXBOb2RlKGUsciksMjB9Y2F0Y2goZSl7fXJldHVybiBsZS5ub2RlUGVybWlzc2lvbnMoZSwid3giKX0sbWF5RGVsZXRlKGUscix0KXt2YXIgbjt0cnl7bj1sZS5sb29rdXBOb2RlKGUscil9Y2F0Y2goZSl7cmV0dXJuIGUuZXJybm99dmFyIG89bGUubm9kZVBlcm1pc3Npb25zKGUsInd4Iik7aWYobylyZXR1cm4gbztpZih0KXtpZighbGUuaXNEaXIobi5tb2RlKSlyZXR1cm4gNTQ7aWYobGUuaXNSb290KG4pfHxsZS5nZXRQYXRoKG4pPT09bGUuY3dkKCkpcmV0dXJuIDEwfWVsc2UgaWYobGUuaXNEaXIobi5tb2RlKSlyZXR1cm4gMzE7cmV0dXJuIDB9LG1heU9wZW46KGUscik9PmU/bGUuaXNMaW5rKGUubW9kZSk/MzI6bGUuaXNEaXIoZS5tb2RlKSYmKCJyIiE9PWxlLmZsYWdzVG9QZXJtaXNzaW9uU3RyaW5nKHIpfHw1MTImcik/MzE6bGUubm9kZVBlcm1pc3Npb25zKGUsbGUuZmxhZ3NUb1Blcm1pc3Npb25TdHJpbmcocikpOjQ0LE1BWF9PUEVOX0ZEUzo0MDk2LG5leHRmZCgpe2Zvcih2YXIgZT0wO2U8PWxlLk1BWF9PUEVOX0ZEUztlKyspaWYoIWxlLnN0cmVhbXNbZV0pcmV0dXJuIGU7dGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMzMpfSxnZXRTdHJlYW1DaGVja2VkKGUpe3ZhciByPWxlLmdldFN0cmVhbShlKTtpZighcil0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtyZXR1cm4gcn0sZ2V0U3RyZWFtOmU9PmxlLnN0cmVhbXNbZV0sY3JlYXRlU3RyZWFtOihlLHI9LTEpPT4obGUuRlNTdHJlYW18fChsZS5GU1N0cmVhbT1mdW5jdGlvbigpe3RoaXMuc2hhcmVkPXt9fSxsZS5GU1N0cmVhbS5wcm90b3R5cGU9e30sT2JqZWN0LmRlZmluZVByb3BlcnRpZXMobGUuRlNTdHJlYW0ucHJvdG90eXBlLHtvYmplY3Q6e2dldCgpe3JldHVybiB0aGlzLm5vZGV9LHNldChlKXt0aGlzLm5vZGU9ZX19LGlzUmVhZDp7Z2V0KCl7cmV0dXJuIDEhPSgyMDk3MTU1JnRoaXMuZmxhZ3MpfX0saXNXcml0ZTp7Z2V0KCl7cmV0dXJuIDAhPSgyMDk3MTU1JnRoaXMuZmxhZ3MpfX0saXNBcHBlbmQ6e2dldCgpe3JldHVybiAxMDI0JnRoaXMuZmxhZ3N9fSxmbGFnczp7Z2V0KCl7cmV0dXJuIHRoaXMuc2hhcmVkLmZsYWdzfSxzZXQoZSl7dGhpcy5zaGFyZWQuZmxhZ3M9ZX19LHBvc2l0aW9uOntnZXQoKXtyZXR1cm4gdGhpcy5zaGFyZWQucG9zaXRpb259LHNldChlKXt0aGlzLnNoYXJlZC5wb3NpdGlvbj1lfX19KSksZT1PYmplY3QuYXNzaWduKG5ldyBsZS5GU1N0cmVhbSxlKSwtMT09ciYmKHI9bGUubmV4dGZkKCkpLGUuZmQ9cixsZS5zdHJlYW1zW3JdPWUsZSksY2xvc2VTdHJlYW0oZSl7bGUuc3RyZWFtc1tlXT1udWxsfSxjaHJkZXZfc3RyZWFtX29wczp7b3BlbihlKXt2YXIgcj1sZS5nZXREZXZpY2UoZS5ub2RlLnJkZXYpO2Uuc3RyZWFtX29wcz1yLnN0cmVhbV9vcHMsZS5zdHJlYW1fb3BzLm9wZW4/LihlKX0sbGxzZWVrKCl7dGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNzApfX0sbWFqb3I6ZT0+ZT4+OCxtaW5vcjplPT4yNTUmZSxtYWtlZGV2OihlLHIpPT5lPDw4fHIscmVnaXN0ZXJEZXZpY2UoZSxyKXtsZS5kZXZpY2VzW2VdPXtzdHJlYW1fb3BzOnJ9fSxnZXREZXZpY2U6ZT0+bGUuZGV2aWNlc1tlXSxnZXRNb3VudHMoZSl7Zm9yKHZhciByPVtdLHQ9W2VdO3QubGVuZ3RoOyl7dmFyIG49dC5wb3AoKTtyLnB1c2gobiksdC5wdXNoLmFwcGx5KHQsbi5tb3VudHMpfXJldHVybiByfSxzeW5jZnMoZSxyKXsiZnVuY3Rpb24iPT10eXBlb2YgZSYmKHI9ZSxlPSExKSxsZS5zeW5jRlNSZXF1ZXN0cysrLGxlLnN5bmNGU1JlcXVlc3RzPjEmJnkoYHdhcm5pbmc6ICR7bGUuc3luY0ZTUmVxdWVzdHN9IEZTLnN5bmNmcyBvcGVyYXRpb25zIGluIGZsaWdodCBhdCBvbmNlLCBwcm9iYWJseSBqdXN0IGRvaW5nIGV4dHJhIHdvcmtgKTt2YXIgdD1sZS5nZXRNb3VudHMobGUucm9vdC5tb3VudCksbj0wO2Z1bmN0aW9uIG8oZSl7cmV0dXJuIGxlLnN5bmNGU1JlcXVlc3RzLS0scihlKX1mdW5jdGlvbiBhKGUpe2lmKGUpcmV0dXJuIGEuZXJyb3JlZD92b2lkIDA6KGEuZXJyb3JlZD0hMCxvKGUpKTsrK24+PXQubGVuZ3RoJiZvKG51bGwpfXQuZm9yRWFjaCgocj0+e2lmKCFyLnR5cGUuc3luY2ZzKXJldHVybiBhKG51bGwpO3IudHlwZS5zeW5jZnMocixlLGEpfSkpfSxtb3VudChlLHIsdCl7dmFyIG4sbz0iLyI9PT10LGE9IXQ7aWYobyYmbGUucm9vdCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigxMCk7aWYoIW8mJiFhKXt2YXIgcz1sZS5sb29rdXBQYXRoKHQse2ZvbGxvd19tb3VudDohMX0pO2lmKHQ9cy5wYXRoLG49cy5ub2RlLGxlLmlzTW91bnRwb2ludChuKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigxMCk7aWYoIWxlLmlzRGlyKG4ubW9kZSkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNTQpfXZhciBpPXt0eXBlOmUsb3B0czpyLG1vdW50cG9pbnQ6dCxtb3VudHM6W119LHU9ZS5tb3VudChpKTtyZXR1cm4gdS5tb3VudD1pLGkucm9vdD11LG8/bGUucm9vdD11Om4mJihuLm1vdW50ZWQ9aSxuLm1vdW50JiZuLm1vdW50Lm1vdW50cy5wdXNoKGkpKSx1fSx1bm1vdW50KGUpe3ZhciByPWxlLmxvb2t1cFBhdGgoZSx7Zm9sbG93X21vdW50OiExfSk7aWYoIWxlLmlzTW91bnRwb2ludChyLm5vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTt2YXIgdD1yLm5vZGUsbj10Lm1vdW50ZWQsbz1sZS5nZXRNb3VudHMobik7T2JqZWN0LmtleXMobGUubmFtZVRhYmxlKS5mb3JFYWNoKChlPT57Zm9yKHZhciByPWxlLm5hbWVUYWJsZVtlXTtyOyl7dmFyIHQ9ci5uYW1lX25leHQ7by5pbmNsdWRlcyhyLm1vdW50KSYmbGUuZGVzdHJveU5vZGUocikscj10fX0pKSx0Lm1vdW50ZWQ9bnVsbDt2YXIgYT10Lm1vdW50Lm1vdW50cy5pbmRleE9mKG4pO3QubW91bnQubW91bnRzLnNwbGljZShhLDEpfSxsb29rdXA6KGUscik9PmUubm9kZV9vcHMubG9va3VwKGUsciksbWtub2QoZSxyLHQpe3ZhciBuPWxlLmxvb2t1cFBhdGgoZSx7cGFyZW50OiEwfSkubm9kZSxvPVouYmFzZW5hbWUoZSk7aWYoIW98fCIuIj09PW98fCIuLiI9PT1vKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTt2YXIgYT1sZS5tYXlDcmVhdGUobixvKTtpZihhKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKGEpO2lmKCFuLm5vZGVfb3BzLm1rbm9kKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYzKTtyZXR1cm4gbi5ub2RlX29wcy5ta25vZChuLG8scix0KX0sY3JlYXRlOihlLHIpPT4ocj12b2lkIDAhPT1yP3I6NDM4LHImPTQwOTUscnw9MzI3NjgsbGUubWtub2QoZSxyLDApKSxta2RpcjooZSxyKT0+KHI9dm9pZCAwIT09cj9yOjUxMSxyJj0xMDIzLHJ8PTE2Mzg0LGxlLm1rbm9kKGUsciwwKSksbWtkaXJUcmVlKGUscil7Zm9yKHZhciB0PWUuc3BsaXQoIi8iKSxuPSIiLG89MDtvPHQubGVuZ3RoOysrbylpZih0W29dKXtuKz0iLyIrdFtvXTt0cnl7bGUubWtkaXIobixyKX1jYXRjaChlKXtpZigyMCE9ZS5lcnJubyl0aHJvdyBlfX19LG1rZGV2OihlLHIsdCk9Pih2b2lkIDA9PT10JiYodD1yLHI9NDM4KSxyfD04MTkyLGxlLm1rbm9kKGUscix0KSksc3ltbGluayhlLHIpe2lmKCFWLnJlc29sdmUoZSkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNDQpO3ZhciB0PWxlLmxvb2t1cFBhdGgocix7cGFyZW50OiEwfSkubm9kZTtpZighdCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7dmFyIG49Wi5iYXNlbmFtZShyKSxvPWxlLm1heUNyZWF0ZSh0LG4pO2lmKG8pdGhyb3cgbmV3IGxlLkVycm5vRXJyb3Iobyk7aWYoIXQubm9kZV9vcHMuc3ltbGluayl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig2Myk7cmV0dXJuIHQubm9kZV9vcHMuc3ltbGluayh0LG4sZSl9LHJlbmFtZShlLHIpe3ZhciB0LG4sbz1aLmRpcm5hbWUoZSksYT1aLmRpcm5hbWUocikscz1aLmJhc2VuYW1lKGUpLGk9Wi5iYXNlbmFtZShyKTtpZih0PWxlLmxvb2t1cFBhdGgoZSx7cGFyZW50OiEwfSkubm9kZSxuPWxlLmxvb2t1cFBhdGgocix7cGFyZW50OiEwfSkubm9kZSwhdHx8IW4pdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNDQpO2lmKHQubW91bnQhPT1uLm1vdW50KXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDc1KTt2YXIgdSxsPWxlLmxvb2t1cE5vZGUodCxzKSxjPVYucmVsYXRpdmUoZSxhKTtpZigiLiIhPT1jLmNoYXJBdCgwKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOCk7aWYoIi4iIT09KGM9Vi5yZWxhdGl2ZShyLG8pKS5jaGFyQXQoMCkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNTUpO3RyeXt1PWxlLmxvb2t1cE5vZGUobixpKX1jYXRjaChlKXt9aWYobCE9PXUpe3ZhciBkPWxlLmlzRGlyKGwubW9kZSksaD1sZS5tYXlEZWxldGUodCxzLGQpO2lmKGgpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoaCk7aWYoaD11P2xlLm1heURlbGV0ZShuLGksZCk6bGUubWF5Q3JlYXRlKG4saSkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoaCk7aWYoIXQubm9kZV9vcHMucmVuYW1lKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYzKTtpZihsZS5pc01vdW50cG9pbnQobCl8fHUmJmxlLmlzTW91bnRwb2ludCh1KSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigxMCk7aWYobiE9PXQmJihoPWxlLm5vZGVQZXJtaXNzaW9ucyh0LCJ3IikpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKGgpO2xlLmhhc2hSZW1vdmVOb2RlKGwpO3RyeXt0Lm5vZGVfb3BzLnJlbmFtZShsLG4saSl9Y2F0Y2goZSl7dGhyb3cgZX1maW5hbGx5e2xlLmhhc2hBZGROb2RlKGwpfX19LHJtZGlyKGUpe3ZhciByPWxlLmxvb2t1cFBhdGgoZSx7cGFyZW50OiEwfSkubm9kZSx0PVouYmFzZW5hbWUoZSksbj1sZS5sb29rdXBOb2RlKHIsdCksbz1sZS5tYXlEZWxldGUocix0LCEwKTtpZihvKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKG8pO2lmKCFyLm5vZGVfb3BzLnJtZGlyKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYzKTtpZihsZS5pc01vdW50cG9pbnQobikpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMTApO3Iubm9kZV9vcHMucm1kaXIocix0KSxsZS5kZXN0cm95Tm9kZShuKX0scmVhZGRpcihlKXt2YXIgcj1sZS5sb29rdXBQYXRoKGUse2ZvbGxvdzohMH0pLm5vZGU7aWYoIXIubm9kZV9vcHMucmVhZGRpcil0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig1NCk7cmV0dXJuIHIubm9kZV9vcHMucmVhZGRpcihyKX0sdW5saW5rKGUpe3ZhciByPWxlLmxvb2t1cFBhdGgoZSx7cGFyZW50OiEwfSkubm9kZTtpZighcil0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7dmFyIHQ9Wi5iYXNlbmFtZShlKSxuPWxlLmxvb2t1cE5vZGUocix0KSxvPWxlLm1heURlbGV0ZShyLHQsITEpO2lmKG8pdGhyb3cgbmV3IGxlLkVycm5vRXJyb3Iobyk7aWYoIXIubm9kZV9vcHMudW5saW5rKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYzKTtpZihsZS5pc01vdW50cG9pbnQobikpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMTApO3Iubm9kZV9vcHMudW5saW5rKHIsdCksbGUuZGVzdHJveU5vZGUobil9LHJlYWRsaW5rKGUpe3ZhciByPWxlLmxvb2t1cFBhdGgoZSkubm9kZTtpZighcil0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7aWYoIXIubm9kZV9vcHMucmVhZGxpbmspdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjgpO3JldHVybiBWLnJlc29sdmUobGUuZ2V0UGF0aChyLnBhcmVudCksci5ub2RlX29wcy5yZWFkbGluayhyKSl9LHN0YXQoZSxyKXt2YXIgdD1sZS5sb29rdXBQYXRoKGUse2ZvbGxvdzohcn0pLm5vZGU7aWYoIXQpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNDQpO2lmKCF0Lm5vZGVfb3BzLmdldGF0dHIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNjMpO3JldHVybiB0Lm5vZGVfb3BzLmdldGF0dHIodCl9LGxzdGF0OmU9PmxlLnN0YXQoZSwhMCksY2htb2QoZSxyLHQpe3ZhciBuO2lmKCEobj0ic3RyaW5nIj09dHlwZW9mIGU/bGUubG9va3VwUGF0aChlLHtmb2xsb3c6IXR9KS5ub2RlOmUpLm5vZGVfb3BzLnNldGF0dHIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNjMpO24ubm9kZV9vcHMuc2V0YXR0cihuLHttb2RlOjQwOTUmcnwtNDA5NiZuLm1vZGUsdGltZXN0YW1wOkRhdGUubm93KCl9KX0sbGNobW9kKGUscil7bGUuY2htb2QoZSxyLCEwKX0sZmNobW9kKGUscil7dmFyIHQ9bGUuZ2V0U3RyZWFtQ2hlY2tlZChlKTtsZS5jaG1vZCh0Lm5vZGUscil9LGNob3duKGUscix0LG4pe3ZhciBvO2lmKCEobz0ic3RyaW5nIj09dHlwZW9mIGU/bGUubG9va3VwUGF0aChlLHtmb2xsb3c6IW59KS5ub2RlOmUpLm5vZGVfb3BzLnNldGF0dHIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNjMpO28ubm9kZV9vcHMuc2V0YXR0cihvLHt0aW1lc3RhbXA6RGF0ZS5ub3coKX0pfSxsY2hvd24oZSxyLHQpe2xlLmNob3duKGUscix0LCEwKX0sZmNob3duKGUscix0KXt2YXIgbj1sZS5nZXRTdHJlYW1DaGVja2VkKGUpO2xlLmNob3duKG4ubm9kZSxyLHQpfSx0cnVuY2F0ZShlLHIpe2lmKHI8MCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOCk7dmFyIHQ7aWYoISh0PSJzdHJpbmciPT10eXBlb2YgZT9sZS5sb29rdXBQYXRoKGUse2ZvbGxvdzohMH0pLm5vZGU6ZSkubm9kZV9vcHMuc2V0YXR0cil0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig2Myk7aWYobGUuaXNEaXIodC5tb2RlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigzMSk7aWYoIWxlLmlzRmlsZSh0Lm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTt2YXIgbj1sZS5ub2RlUGVybWlzc2lvbnModCwidyIpO2lmKG4pdGhyb3cgbmV3IGxlLkVycm5vRXJyb3Iobik7dC5ub2RlX29wcy5zZXRhdHRyKHQse3NpemU6cix0aW1lc3RhbXA6RGF0ZS5ub3coKX0pfSxmdHJ1bmNhdGUoZSxyKXt2YXIgdD1sZS5nZXRTdHJlYW1DaGVja2VkKGUpO2lmKDA9PSgyMDk3MTU1JnQuZmxhZ3MpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTtsZS50cnVuY2F0ZSh0Lm5vZGUscil9LHV0aW1lKGUscix0KXt2YXIgbj1sZS5sb29rdXBQYXRoKGUse2ZvbGxvdzohMH0pLm5vZGU7bi5ub2RlX29wcy5zZXRhdHRyKG4se3RpbWVzdGFtcDpNYXRoLm1heChyLHQpfSl9LG9wZW4oZSxyLHQpe2lmKCIiPT09ZSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7dmFyIG87aWYodD12b2lkIDA9PT10PzQzODp0LHQ9NjQmKHI9InN0cmluZyI9PXR5cGVvZiByPyhlPT57dmFyIHI9e3I6MCwicisiOjIsdzo1NzcsIncrIjo1NzgsYToxMDg5LCJhKyI6MTA5MH1bZV07aWYodm9pZCAwPT09cil0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZmlsZSBvcGVuIG1vZGU6ICR7ZX1gKTtyZXR1cm4gcn0pKHIpOnIpPzQwOTUmdHwzMjc2ODowLCJvYmplY3QiPT10eXBlb2YgZSlvPWU7ZWxzZXtlPVoubm9ybWFsaXplKGUpO3RyeXtvPWxlLmxvb2t1cFBhdGgoZSx7Zm9sbG93OiEoMTMxMDcyJnIpfSkubm9kZX1jYXRjaChlKXt9fXZhciBhPSExO2lmKDY0JnIpaWYobyl7aWYoMTI4JnIpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjApfWVsc2Ugbz1sZS5ta25vZChlLHQsMCksYT0hMDtpZighbyl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7aWYobGUuaXNDaHJkZXYoby5tb2RlKSYmKHImPS01MTMpLDY1NTM2JnImJiFsZS5pc0RpcihvLm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDU0KTtpZighYSl7dmFyIHM9bGUubWF5T3BlbihvLHIpO2lmKHMpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3Iocyl9NTEyJnImJiFhJiZsZS50cnVuY2F0ZShvLDApLHImPS0xMzE3MTM7dmFyIGk9bGUuY3JlYXRlU3RyZWFtKHtub2RlOm8scGF0aDpsZS5nZXRQYXRoKG8pLGZsYWdzOnIsc2Vla2FibGU6ITAscG9zaXRpb246MCxzdHJlYW1fb3BzOm8uc3RyZWFtX29wcyx1bmdvdHRlbjpbXSxlcnJvcjohMX0pO3JldHVybiBpLnN0cmVhbV9vcHMub3BlbiYmaS5zdHJlYW1fb3BzLm9wZW4oaSksIW4ubG9nUmVhZEZpbGVzfHwxJnJ8fChsZS5yZWFkRmlsZXN8fChsZS5yZWFkRmlsZXM9e30pLGUgaW4gbGUucmVhZEZpbGVzfHwobGUucmVhZEZpbGVzW2VdPTEpKSxpfSxjbG9zZShlKXtpZihsZS5pc0Nsb3NlZChlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtlLmdldGRlbnRzJiYoZS5nZXRkZW50cz1udWxsKTt0cnl7ZS5zdHJlYW1fb3BzLmNsb3NlJiZlLnN0cmVhbV9vcHMuY2xvc2UoZSl9Y2F0Y2goZSl7dGhyb3cgZX1maW5hbGx5e2xlLmNsb3NlU3RyZWFtKGUuZmQpfWUuZmQ9bnVsbH0saXNDbG9zZWQ6ZT0+bnVsbD09PWUuZmQsbGxzZWVrKGUscix0KXtpZihsZS5pc0Nsb3NlZChlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtpZighZS5zZWVrYWJsZXx8IWUuc3RyZWFtX29wcy5sbHNlZWspdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNzApO2lmKDAhPXQmJjEhPXQmJjIhPXQpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjgpO3JldHVybiBlLnBvc2l0aW9uPWUuc3RyZWFtX29wcy5sbHNlZWsoZSxyLHQpLGUudW5nb3R0ZW49W10sZS5wb3NpdGlvbn0scmVhZChlLHIsdCxuLG8pe2lmKG48MHx8bzwwKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTtpZihsZS5pc0Nsb3NlZChlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtpZigxPT0oMjA5NzE1NSZlLmZsYWdzKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtpZihsZS5pc0RpcihlLm5vZGUubW9kZSkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMzEpO2lmKCFlLnN0cmVhbV9vcHMucmVhZCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOCk7dmFyIGE9dm9pZCAwIT09bztpZihhKXtpZighZS5zZWVrYWJsZSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig3MCl9ZWxzZSBvPWUucG9zaXRpb247dmFyIHM9ZS5zdHJlYW1fb3BzLnJlYWQoZSxyLHQsbixvKTtyZXR1cm4gYXx8KGUucG9zaXRpb24rPXMpLHN9LHdyaXRlKGUscix0LG4sbyxhKXtpZihuPDB8fG88MCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOCk7aWYobGUuaXNDbG9zZWQoZSkpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoOCk7aWYoMD09KDIwOTcxNTUmZS5mbGFncykpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoOCk7aWYobGUuaXNEaXIoZS5ub2RlLm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDMxKTtpZighZS5zdHJlYW1fb3BzLndyaXRlKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDI4KTtlLnNlZWthYmxlJiYxMDI0JmUuZmxhZ3MmJmxlLmxsc2VlayhlLDAsMik7dmFyIHM9dm9pZCAwIT09bztpZihzKXtpZighZS5zZWVrYWJsZSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig3MCl9ZWxzZSBvPWUucG9zaXRpb247dmFyIGk9ZS5zdHJlYW1fb3BzLndyaXRlKGUscix0LG4sbyxhKTtyZXR1cm4gc3x8KGUucG9zaXRpb24rPWkpLGl9LGFsbG9jYXRlKGUscix0KXtpZihsZS5pc0Nsb3NlZChlKSl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig4KTtpZihyPDB8fHQ8PTApdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjgpO2lmKDA9PSgyMDk3MTU1JmUuZmxhZ3MpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDgpO2lmKCFsZS5pc0ZpbGUoZS5ub2RlLm1vZGUpJiYhbGUuaXNEaXIoZS5ub2RlLm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQzKTtpZighZS5zdHJlYW1fb3BzLmFsbG9jYXRlKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDEzOCk7ZS5zdHJlYW1fb3BzLmFsbG9jYXRlKGUscix0KX0sbW1hcChlLHIsdCxuLG8pe2lmKDAhPSgyJm4pJiYwPT0oMiZvKSYmMiE9KDIwOTcxNTUmZS5mbGFncykpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMik7aWYoMT09KDIwOTcxNTUmZS5mbGFncykpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMik7aWYoIWUuc3RyZWFtX29wcy5tbWFwKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQzKTtyZXR1cm4gZS5zdHJlYW1fb3BzLm1tYXAoZSxyLHQsbixvKX0sbXN5bmM6KGUscix0LG4sbyk9PmUuc3RyZWFtX29wcy5tc3luYz9lLnN0cmVhbV9vcHMubXN5bmMoZSxyLHQsbixvKTowLG11bm1hcDplPT4wLGlvY3RsKGUscix0KXtpZighZS5zdHJlYW1fb3BzLmlvY3RsKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDU5KTtyZXR1cm4gZS5zdHJlYW1fb3BzLmlvY3RsKGUscix0KX0scmVhZEZpbGUoZSxyPXt9KXtpZihyLmZsYWdzPXIuZmxhZ3N8fDAsci5lbmNvZGluZz1yLmVuY29kaW5nfHwiYmluYXJ5IiwidXRmOCIhPT1yLmVuY29kaW5nJiYiYmluYXJ5IiE9PXIuZW5jb2RpbmcpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGVuY29kaW5nIHR5cGUgIiR7ci5lbmNvZGluZ30iYCk7dmFyIHQsbj1sZS5vcGVuKGUsci5mbGFncyksbz1sZS5zdGF0KGUpLnNpemUsYT1uZXcgVWludDhBcnJheShvKTtyZXR1cm4gbGUucmVhZChuLGEsMCxvLDApLCJ1dGY4Ij09PXIuZW5jb2Rpbmc/dD1RKGEsMCk6ImJpbmFyeSI9PT1yLmVuY29kaW5nJiYodD1hKSxsZS5jbG9zZShuKSx0fSx3cml0ZUZpbGUoZSxyLHQ9e30pe3QuZmxhZ3M9dC5mbGFnc3x8NTc3O3ZhciBuPWxlLm9wZW4oZSx0LmZsYWdzLHQubW9kZSk7aWYoInN0cmluZyI9PXR5cGVvZiByKXt2YXIgbz1uZXcgVWludDhBcnJheShyZShyKSsxKSxhPXRlKHIsbywwLG8ubGVuZ3RoKTtsZS53cml0ZShuLG8sMCxhLHZvaWQgMCx0LmNhbk93bil9ZWxzZXtpZighQXJyYXlCdWZmZXIuaXNWaWV3KHIpKXRocm93IG5ldyBFcnJvcigiVW5zdXBwb3J0ZWQgZGF0YSB0eXBlIik7bGUud3JpdGUobixyLDAsci5ieXRlTGVuZ3RoLHZvaWQgMCx0LmNhbk93bil9bGUuY2xvc2Uobil9LGN3ZDooKT0+bGUuY3VycmVudFBhdGgsY2hkaXIoZSl7dmFyIHI9bGUubG9va3VwUGF0aChlLHtmb2xsb3c6ITB9KTtpZihudWxsPT09ci5ub2RlKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQ0KTtpZighbGUuaXNEaXIoci5ub2RlLm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDU0KTt2YXIgdD1sZS5ub2RlUGVybWlzc2lvbnMoci5ub2RlLCJ4Iik7aWYodCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcih0KTtsZS5jdXJyZW50UGF0aD1yLnBhdGh9LGNyZWF0ZURlZmF1bHREaXJlY3Rvcmllcygpe2xlLm1rZGlyKCIvdG1wIiksbGUubWtkaXIoIi9ob21lIiksbGUubWtkaXIoIi9ob21lL3dlYl91c2VyIil9LGNyZWF0ZURlZmF1bHREZXZpY2VzKCl7bGUubWtkaXIoIi9kZXYiKSxsZS5yZWdpc3RlckRldmljZShsZS5tYWtlZGV2KDEsMykse3JlYWQ6KCk9PjAsd3JpdGU6KGUscix0LG4sbyk9Pm59KSxsZS5ta2RldigiL2Rldi9udWxsIixsZS5tYWtlZGV2KDEsMykpLG9lLnJlZ2lzdGVyKGxlLm1ha2VkZXYoNSwwKSxvZS5kZWZhdWx0X3R0eV9vcHMpLG9lLnJlZ2lzdGVyKGxlLm1ha2VkZXYoNiwwKSxvZS5kZWZhdWx0X3R0eTFfb3BzKSxsZS5ta2RldigiL2Rldi90dHkiLGxlLm1ha2VkZXYoNSwwKSksbGUubWtkZXYoIi9kZXYvdHR5MSIsbGUubWFrZWRldig2LDApKTt2YXIgZT1uZXcgVWludDhBcnJheSgxMDI0KSxyPTAsdD0oKT0+KDA9PT1yJiYocj1HKGUpLmJ5dGVMZW5ndGgpLGVbLS1yXSk7bGUuY3JlYXRlRGV2aWNlKCIvZGV2IiwicmFuZG9tIix0KSxsZS5jcmVhdGVEZXZpY2UoIi9kZXYiLCJ1cmFuZG9tIix0KSxsZS5ta2RpcigiL2Rldi9zaG0iKSxsZS5ta2RpcigiL2Rldi9zaG0vdG1wIil9LGNyZWF0ZVNwZWNpYWxEaXJlY3Rvcmllcygpe2xlLm1rZGlyKCIvcHJvYyIpO3ZhciBlPWxlLm1rZGlyKCIvcHJvYy9zZWxmIik7bGUubWtkaXIoIi9wcm9jL3NlbGYvZmQiKSxsZS5tb3VudCh7bW91bnQoKXt2YXIgcj1sZS5jcmVhdGVOb2RlKGUsImZkIiwxNjg5NSw3Myk7cmV0dXJuIHIubm9kZV9vcHM9e2xvb2t1cChlLHIpe3ZhciB0PStyLG49bGUuZ2V0U3RyZWFtQ2hlY2tlZCh0KSxvPXtwYXJlbnQ6bnVsbCxtb3VudDp7bW91bnRwb2ludDoiZmFrZSJ9LG5vZGVfb3BzOntyZWFkbGluazooKT0+bi5wYXRofX07cmV0dXJuIG8ucGFyZW50PW8sb319LHJ9fSx7fSwiL3Byb2Mvc2VsZi9mZCIpfSxjcmVhdGVTdGFuZGFyZFN0cmVhbXMoKXtuLnN0ZGluP2xlLmNyZWF0ZURldmljZSgiL2RldiIsInN0ZGluIixuLnN0ZGluKTpsZS5zeW1saW5rKCIvZGV2L3R0eSIsIi9kZXYvc3RkaW4iKSxuLnN0ZG91dD9sZS5jcmVhdGVEZXZpY2UoIi9kZXYiLCJzdGRvdXQiLG51bGwsbi5zdGRvdXQpOmxlLnN5bWxpbmsoIi9kZXYvdHR5IiwiL2Rldi9zdGRvdXQiKSxuLnN0ZGVycj9sZS5jcmVhdGVEZXZpY2UoIi9kZXYiLCJzdGRlcnIiLG51bGwsbi5zdGRlcnIpOmxlLnN5bWxpbmsoIi9kZXYvdHR5MSIsIi9kZXYvc3RkZXJyIiksbGUub3BlbigiL2Rldi9zdGRpbiIsMCksbGUub3BlbigiL2Rldi9zdGRvdXQiLDEpLGxlLm9wZW4oIi9kZXYvc3RkZXJyIiwxKX0sZW5zdXJlRXJybm9FcnJvcigpe2xlLkVycm5vRXJyb3J8fChsZS5FcnJub0Vycm9yPWZ1bmN0aW9uKGUscil7dGhpcy5uYW1lPSJFcnJub0Vycm9yIix0aGlzLm5vZGU9cix0aGlzLnNldEVycm5vPWZ1bmN0aW9uKGUpe3RoaXMuZXJybm89ZX0sdGhpcy5zZXRFcnJubyhlKSx0aGlzLm1lc3NhZ2U9IkZTIGVycm9yIn0sbGUuRXJybm9FcnJvci5wcm90b3R5cGU9bmV3IEVycm9yLGxlLkVycm5vRXJyb3IucHJvdG90eXBlLmNvbnN0cnVjdG9yPWxlLkVycm5vRXJyb3IsWzQ0XS5mb3JFYWNoKChlPT57bGUuZ2VuZXJpY0Vycm9yc1tlXT1uZXcgbGUuRXJybm9FcnJvcihlKSxsZS5nZW5lcmljRXJyb3JzW2VdLnN0YWNrPSI8Z2VuZXJpYyBlcnJvciwgbm8gc3RhY2s+In0pKSl9LHN0YXRpY0luaXQoKXtsZS5lbnN1cmVFcnJub0Vycm9yKCksbGUubmFtZVRhYmxlPW5ldyBBcnJheSg0MDk2KSxsZS5tb3VudChzZSx7fSwiLyIpLGxlLmNyZWF0ZURlZmF1bHREaXJlY3RvcmllcygpLGxlLmNyZWF0ZURlZmF1bHREZXZpY2VzKCksbGUuY3JlYXRlU3BlY2lhbERpcmVjdG9yaWVzKCksbGUuZmlsZXN5c3RlbXM9e01FTUZTOnNlfX0saW5pdChlLHIsdCl7bGUuaW5pdC5pbml0aWFsaXplZD0hMCxsZS5lbnN1cmVFcnJub0Vycm9yKCksbi5zdGRpbj1lfHxuLnN0ZGluLG4uc3Rkb3V0PXJ8fG4uc3Rkb3V0LG4uc3RkZXJyPXR8fG4uc3RkZXJyLGxlLmNyZWF0ZVN0YW5kYXJkU3RyZWFtcygpfSxxdWl0KCl7bGUuaW5pdC5pbml0aWFsaXplZD0hMTtmb3IodmFyIGU9MDtlPGxlLnN0cmVhbXMubGVuZ3RoO2UrKyl7dmFyIHI9bGUuc3RyZWFtc1tlXTtyJiZsZS5jbG9zZShyKX19LGZpbmRPYmplY3QoZSxyKXt2YXIgdD1sZS5hbmFseXplUGF0aChlLHIpO3JldHVybiB0LmV4aXN0cz90Lm9iamVjdDpudWxsfSxhbmFseXplUGF0aChlLHIpe3RyeXtlPShuPWxlLmxvb2t1cFBhdGgoZSx7Zm9sbG93OiFyfSkpLnBhdGh9Y2F0Y2goZSl7fXZhciB0PXtpc1Jvb3Q6ITEsZXhpc3RzOiExLGVycm9yOjAsbmFtZTpudWxsLHBhdGg6bnVsbCxvYmplY3Q6bnVsbCxwYXJlbnRFeGlzdHM6ITEscGFyZW50UGF0aDpudWxsLHBhcmVudE9iamVjdDpudWxsfTt0cnl7dmFyIG49bGUubG9va3VwUGF0aChlLHtwYXJlbnQ6ITB9KTt0LnBhcmVudEV4aXN0cz0hMCx0LnBhcmVudFBhdGg9bi5wYXRoLHQucGFyZW50T2JqZWN0PW4ubm9kZSx0Lm5hbWU9Wi5iYXNlbmFtZShlKSxuPWxlLmxvb2t1cFBhdGgoZSx7Zm9sbG93OiFyfSksdC5leGlzdHM9ITAsdC5wYXRoPW4ucGF0aCx0Lm9iamVjdD1uLm5vZGUsdC5uYW1lPW4ubm9kZS5uYW1lLHQuaXNSb290PSIvIj09PW4ucGF0aH1jYXRjaChlKXt0LmVycm9yPWUuZXJybm99cmV0dXJuIHR9LGNyZWF0ZVBhdGgoZSxyLHQsbil7ZT0ic3RyaW5nIj09dHlwZW9mIGU/ZTpsZS5nZXRQYXRoKGUpO2Zvcih2YXIgbz1yLnNwbGl0KCIvIikucmV2ZXJzZSgpO28ubGVuZ3RoOyl7dmFyIGE9by5wb3AoKTtpZihhKXt2YXIgcz1aLmpvaW4yKGUsYSk7dHJ5e2xlLm1rZGlyKHMpfWNhdGNoKGUpe31lPXN9fXJldHVybiBzfSxjcmVhdGVGaWxlKGUscix0LG4sbyl7dmFyIGE9Wi5qb2luMigic3RyaW5nIj09dHlwZW9mIGU/ZTpsZS5nZXRQYXRoKGUpLHIpLHM9dWUobixvKTtyZXR1cm4gbGUuY3JlYXRlKGEscyl9LGNyZWF0ZURhdGFGaWxlKGUscix0LG4sbyxhKXt2YXIgcz1yO2UmJihlPSJzdHJpbmciPT10eXBlb2YgZT9lOmxlLmdldFBhdGgoZSkscz1yP1ouam9pbjIoZSxyKTplKTt2YXIgaT11ZShuLG8pLHU9bGUuY3JlYXRlKHMsaSk7aWYodCl7aWYoInN0cmluZyI9PXR5cGVvZiB0KXtmb3IodmFyIGw9bmV3IEFycmF5KHQubGVuZ3RoKSxjPTAsZD10Lmxlbmd0aDtjPGQ7KytjKWxbY109dC5jaGFyQ29kZUF0KGMpO3Q9bH1sZS5jaG1vZCh1LDE0NnxpKTt2YXIgaD1sZS5vcGVuKHUsNTc3KTtsZS53cml0ZShoLHQsMCx0Lmxlbmd0aCwwLGEpLGxlLmNsb3NlKGgpLGxlLmNobW9kKHUsaSl9fSxjcmVhdGVEZXZpY2UoZSxyLHQsbil7dmFyIG89Wi5qb2luMigic3RyaW5nIj09dHlwZW9mIGU/ZTpsZS5nZXRQYXRoKGUpLHIpLGE9dWUoISF0LCEhbik7bGUuY3JlYXRlRGV2aWNlLm1ham9yfHwobGUuY3JlYXRlRGV2aWNlLm1ham9yPTY0KTt2YXIgcz1sZS5tYWtlZGV2KGxlLmNyZWF0ZURldmljZS5tYWpvcisrLDApO3JldHVybiBsZS5yZWdpc3RlckRldmljZShzLHtvcGVuKGUpe2Uuc2Vla2FibGU9ITF9LGNsb3NlKGUpe24/LmJ1ZmZlcj8ubGVuZ3RoJiZuKDEwKX0scmVhZChlLHIsbixvLGEpe2Zvcih2YXIgcz0wLGk9MDtpPG87aSsrKXt2YXIgdTt0cnl7dT10KCl9Y2F0Y2goZSl7dGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjkpfWlmKHZvaWQgMD09PXUmJjA9PT1zKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDYpO2lmKG51bGw9PXUpYnJlYWs7cysrLHJbbitpXT11fXJldHVybiBzJiYoZS5ub2RlLnRpbWVzdGFtcD1EYXRlLm5vdygpKSxzfSx3cml0ZShlLHIsdCxvLGEpe2Zvcih2YXIgcz0wO3M8bztzKyspdHJ5e24oclt0K3NdKX1jYXRjaChlKXt0aHJvdyBuZXcgbGUuRXJybm9FcnJvcigyOSl9cmV0dXJuIG8mJihlLm5vZGUudGltZXN0YW1wPURhdGUubm93KCkpLHN9fSksbGUubWtkZXYobyxhLHMpfSxmb3JjZUxvYWRGaWxlKGUpe2lmKGUuaXNEZXZpY2V8fGUuaXNGb2xkZXJ8fGUubGlua3x8ZS5jb250ZW50cylyZXR1cm4hMDtpZigidW5kZWZpbmVkIiE9dHlwZW9mIFhNTEh0dHBSZXF1ZXN0KXRocm93IG5ldyBFcnJvcigiTGF6eSBsb2FkaW5nIHNob3VsZCBoYXZlIGJlZW4gcGVyZm9ybWVkIChjb250ZW50cyBzZXQpIGluIGNyZWF0ZUxhenlGaWxlLCBidXQgaXQgd2FzIG5vdC4gTGF6eSBsb2FkaW5nIG9ubHkgd29ya3MgaW4gd2ViIHdvcmtlcnMuIFVzZSAtLWVtYmVkLWZpbGUgb3IgLS1wcmVsb2FkLWZpbGUgaW4gZW1jYyBvbiB0aGUgbWFpbiB0aHJlYWQuIik7aWYoIW8pdGhyb3cgbmV3IEVycm9yKCJDYW5ub3QgbG9hZCB3aXRob3V0IHJlYWQoKSBvciBYTUxIdHRwUmVxdWVzdC4iKTt0cnl7ZS5jb250ZW50cz1uZShvKGUudXJsKSwhMCksZS51c2VkQnl0ZXM9ZS5jb250ZW50cy5sZW5ndGh9Y2F0Y2goZSl7dGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjkpfX0sY3JlYXRlTGF6eUZpbGUoZSxyLHQsbixvKXtmdW5jdGlvbiBhKCl7dGhpcy5sZW5ndGhLbm93bj0hMSx0aGlzLmNodW5rcz1bXX1pZihhLnByb3RvdHlwZS5nZXQ9ZnVuY3Rpb24oZSl7aWYoIShlPnRoaXMubGVuZ3RoLTF8fGU8MCkpe3ZhciByPWUldGhpcy5jaHVua1NpemUsdD1lL3RoaXMuY2h1bmtTaXplfDA7cmV0dXJuIHRoaXMuZ2V0dGVyKHQpW3JdfX0sYS5wcm90b3R5cGUuc2V0RGF0YUdldHRlcj1mdW5jdGlvbihlKXt0aGlzLmdldHRlcj1lfSxhLnByb3RvdHlwZS5jYWNoZUxlbmd0aD1mdW5jdGlvbigpe3ZhciBlPW5ldyBYTUxIdHRwUmVxdWVzdDtpZihlLm9wZW4oIkhFQUQiLHQsITEpLGUuc2VuZChudWxsKSwhKGUuc3RhdHVzPj0yMDAmJmUuc3RhdHVzPDMwMHx8MzA0PT09ZS5zdGF0dXMpKXRocm93IG5ldyBFcnJvcigiQ291bGRuJ3QgbG9hZCAiK3QrIi4gU3RhdHVzOiAiK2Uuc3RhdHVzKTt2YXIgcixuPU51bWJlcihlLmdldFJlc3BvbnNlSGVhZGVyKCJDb250ZW50LWxlbmd0aCIpKSxvPShyPWUuZ2V0UmVzcG9uc2VIZWFkZXIoIkFjY2VwdC1SYW5nZXMiKSkmJiJieXRlcyI9PT1yLGE9KHI9ZS5nZXRSZXNwb25zZUhlYWRlcigiQ29udGVudC1FbmNvZGluZyIpKSYmImd6aXAiPT09cixzPTEwNDg1NzY7b3x8KHM9bik7dmFyIGk9dGhpcztpLnNldERhdGFHZXR0ZXIoKGU9Pnt2YXIgcj1lKnMsbz0oZSsxKSpzLTE7aWYobz1NYXRoLm1pbihvLG4tMSksdm9pZCAwPT09aS5jaHVua3NbZV0mJihpLmNodW5rc1tlXT0oKGUscik9PntpZihlPnIpdGhyb3cgbmV3IEVycm9yKCJpbnZhbGlkIHJhbmdlICgiK2UrIiwgIityKyIpIG9yIG5vIGJ5dGVzIHJlcXVlc3RlZCEiKTtpZihyPm4tMSl0aHJvdyBuZXcgRXJyb3IoIm9ubHkgIituKyIgYnl0ZXMgYXZhaWxhYmxlISBwcm9ncmFtbWVyIGVycm9yISIpO3ZhciBvPW5ldyBYTUxIdHRwUmVxdWVzdDtpZihvLm9wZW4oIkdFVCIsdCwhMSksbiE9PXMmJm8uc2V0UmVxdWVzdEhlYWRlcigiUmFuZ2UiLCJieXRlcz0iK2UrIi0iK3IpLG8ucmVzcG9uc2VUeXBlPSJhcnJheWJ1ZmZlciIsby5vdmVycmlkZU1pbWVUeXBlJiZvLm92ZXJyaWRlTWltZVR5cGUoInRleHQvcGxhaW47IGNoYXJzZXQ9eC11c2VyLWRlZmluZWQiKSxvLnNlbmQobnVsbCksIShvLnN0YXR1cz49MjAwJiZvLnN0YXR1czwzMDB8fDMwND09PW8uc3RhdHVzKSl0aHJvdyBuZXcgRXJyb3IoIkNvdWxkbid0IGxvYWQgIit0KyIuIFN0YXR1czogIitvLnN0YXR1cyk7cmV0dXJuIHZvaWQgMCE9PW8ucmVzcG9uc2U/bmV3IFVpbnQ4QXJyYXkoby5yZXNwb25zZXx8W10pOm5lKG8ucmVzcG9uc2VUZXh0fHwiIiwhMCl9KShyLG8pKSx2b2lkIDA9PT1pLmNodW5rc1tlXSl0aHJvdyBuZXcgRXJyb3IoImRvWEhSIGZhaWxlZCEiKTtyZXR1cm4gaS5jaHVua3NbZV19KSksIWEmJm58fChzPW49MSxuPXRoaXMuZ2V0dGVyKDApLmxlbmd0aCxzPW4sXygiTGF6eUZpbGVzIG9uIGd6aXAgZm9yY2VzIGRvd25sb2FkIG9mIHRoZSB3aG9sZSBmaWxlIHdoZW4gbGVuZ3RoIGlzIGFjY2Vzc2VkIikpLHRoaXMuX2xlbmd0aD1uLHRoaXMuX2NodW5rU2l6ZT1zLHRoaXMubGVuZ3RoS25vd249ITB9LCJ1bmRlZmluZWQiIT10eXBlb2YgWE1MSHR0cFJlcXVlc3Qpe2lmKCFkKXRocm93IkNhbm5vdCBkbyBzeW5jaHJvbm91cyBiaW5hcnkgWEhScyBvdXRzaWRlIHdlYndvcmtlcnMgaW4gbW9kZXJuIGJyb3dzZXJzLiBVc2UgLS1lbWJlZC1maWxlIG9yIC0tcHJlbG9hZC1maWxlIGluIGVtY2MiO3ZhciBzPW5ldyBhO09iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHMse2xlbmd0aDp7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubGVuZ3RoS25vd258fHRoaXMuY2FjaGVMZW5ndGgoKSx0aGlzLl9sZW5ndGh9fSxjaHVua1NpemU6e2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmxlbmd0aEtub3dufHx0aGlzLmNhY2hlTGVuZ3RoKCksdGhpcy5fY2h1bmtTaXplfX19KTt2YXIgaT17aXNEZXZpY2U6ITEsY29udGVudHM6c319ZWxzZSBpPXtpc0RldmljZTohMSx1cmw6dH07dmFyIHU9bGUuY3JlYXRlRmlsZShlLHIsaSxuLG8pO2kuY29udGVudHM/dS5jb250ZW50cz1pLmNvbnRlbnRzOmkudXJsJiYodS5jb250ZW50cz1udWxsLHUudXJsPWkudXJsKSxPYmplY3QuZGVmaW5lUHJvcGVydGllcyh1LHt1c2VkQnl0ZXM6e2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmNvbnRlbnRzLmxlbmd0aH19fSk7dmFyIGw9e307ZnVuY3Rpb24gYyhlLHIsdCxuLG8pe3ZhciBhPWUubm9kZS5jb250ZW50cztpZihvPj1hLmxlbmd0aClyZXR1cm4gMDt2YXIgcz1NYXRoLm1pbihhLmxlbmd0aC1vLG4pO2lmKGEuc2xpY2UpZm9yKHZhciBpPTA7aTxzO2krKylyW3QraV09YVtvK2ldO2Vsc2UgZm9yKGk9MDtpPHM7aSsrKXJbdCtpXT1hLmdldChvK2kpO3JldHVybiBzfXJldHVybiBPYmplY3Qua2V5cyh1LnN0cmVhbV9vcHMpLmZvckVhY2goKGU9Pnt2YXIgcj11LnN0cmVhbV9vcHNbZV07bFtlXT1mdW5jdGlvbigpe3JldHVybiBsZS5mb3JjZUxvYWRGaWxlKHUpLHIuYXBwbHkobnVsbCxhcmd1bWVudHMpfX0pKSxsLnJlYWQ9KGUscix0LG4sbyk9PihsZS5mb3JjZUxvYWRGaWxlKHUpLGMoZSxyLHQsbixvKSksbC5tbWFwPShlLHIsdCxuLG8pPT57bGUuZm9yY2VMb2FkRmlsZSh1KTt2YXIgYT1hZSgpO2lmKCFhKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQ4KTtyZXR1cm4gYyhlLEUsYSxyLHQpLHtwdHI6YSxhbGxvY2F0ZWQ6ITB9fSx1LnN0cmVhbV9vcHM9bCx1fX0sY2U9KGUscik9PmU/UShrLGUscik6IiIsZGU9e0RFRkFVTFRfUE9MTE1BU0s6NSxjYWxjdWxhdGVBdChlLHIsdCl7aWYoWi5pc0FicyhyKSlyZXR1cm4gcjt2YXIgbjtpZihuPS0xMDA9PT1lP2xlLmN3ZCgpOmRlLmdldFN0cmVhbUZyb21GRChlKS5wYXRoLDA9PXIubGVuZ3RoKXtpZighdCl0aHJvdyBuZXcgbGUuRXJybm9FcnJvcig0NCk7cmV0dXJuIG59cmV0dXJuIFouam9pbjIobixyKX0sZG9TdGF0KGUscix0KXt0cnl7dmFyIG49ZShyKX1jYXRjaChlKXtpZihlJiZlLm5vZGUmJloubm9ybWFsaXplKHIpIT09Wi5ub3JtYWxpemUobGUuZ2V0UGF0aChlLm5vZGUpKSlyZXR1cm4tNTQ7dGhyb3cgZX1GW3Q+PjJdPW4uZGV2LEZbdCs0Pj4yXT1uLm1vZGUsRFt0Kzg+PjJdPW4ubmxpbmssRlt0KzEyPj4yXT1uLnVpZCxGW3QrMTY+PjJdPW4uZ2lkLEZbdCsyMD4+Ml09bi5yZGV2LEk9W24uc2l6ZT4+PjAsKGo9bi5zaXplLCtNYXRoLmFicyhqKT49MT9qPjA/K01hdGguZmxvb3Ioai80Mjk0OTY3Mjk2KT4+PjA6fn4rTWF0aC5jZWlsKChqLSsofn5qPj4+MCkpLzQyOTQ5NjcyOTYpPj4+MDowKV0sRlt0KzI0Pj4yXT1JWzBdLEZbdCsyOD4+Ml09SVsxXSxGW3QrMzI+PjJdPTQwOTYsRlt0KzM2Pj4yXT1uLmJsb2Nrczt2YXIgbz1uLmF0aW1lLmdldFRpbWUoKSxhPW4ubXRpbWUuZ2V0VGltZSgpLHM9bi5jdGltZS5nZXRUaW1lKCk7cmV0dXJuIEk9W01hdGguZmxvb3Ioby8xZTMpPj4+MCwoaj1NYXRoLmZsb29yKG8vMWUzKSwrTWF0aC5hYnMoaik+PTE/aj4wPytNYXRoLmZsb29yKGovNDI5NDk2NzI5Nik+Pj4wOn5+K01hdGguY2VpbCgoai0rKH5+aj4+PjApKS80Mjk0OTY3Mjk2KT4+PjA6MCldLEZbdCs0MD4+Ml09SVswXSxGW3QrNDQ+PjJdPUlbMV0sRFt0KzQ4Pj4yXT1vJTFlMyoxZTMsST1bTWF0aC5mbG9vcihhLzFlMyk+Pj4wLChqPU1hdGguZmxvb3IoYS8xZTMpLCtNYXRoLmFicyhqKT49MT9qPjA/K01hdGguZmxvb3Ioai80Mjk0OTY3Mjk2KT4+PjA6fn4rTWF0aC5jZWlsKChqLSsofn5qPj4+MCkpLzQyOTQ5NjcyOTYpPj4+MDowKV0sRlt0KzU2Pj4yXT1JWzBdLEZbdCs2MD4+Ml09SVsxXSxEW3QrNjQ+PjJdPWElMWUzKjFlMyxJPVtNYXRoLmZsb29yKHMvMWUzKT4+PjAsKGo9TWF0aC5mbG9vcihzLzFlMyksK01hdGguYWJzKGopPj0xP2o+MD8rTWF0aC5mbG9vcihqLzQyOTQ5NjcyOTYpPj4+MDp+fitNYXRoLmNlaWwoKGotKyh+fmo+Pj4wKSkvNDI5NDk2NzI5Nik+Pj4wOjApXSxGW3QrNzI+PjJdPUlbMF0sRlt0Kzc2Pj4yXT1JWzFdLERbdCs4MD4+Ml09cyUxZTMqMWUzLEk9W24uaW5vPj4+MCwoaj1uLmlubywrTWF0aC5hYnMoaik+PTE/aj4wPytNYXRoLmZsb29yKGovNDI5NDk2NzI5Nik+Pj4wOn5+K01hdGguY2VpbCgoai0rKH5+aj4+PjApKS80Mjk0OTY3Mjk2KT4+PjA6MCldLEZbdCs4OD4+Ml09SVswXSxGW3QrOTI+PjJdPUlbMV0sMH0sZG9Nc3luYyhlLHIsdCxuLG8pe2lmKCFsZS5pc0ZpbGUoci5ub2RlLm1vZGUpKXRocm93IG5ldyBsZS5FcnJub0Vycm9yKDQzKTtpZigyJm4pcmV0dXJuIDA7dmFyIGE9ay5zbGljZShlLGUrdCk7bGUubXN5bmMocixhLG8sdCxuKX0sdmFyYXJnczp2b2lkIDAsZ2V0KCl7dmFyIGU9RlsrZGUudmFyYXJncz4+Ml07cmV0dXJuIGRlLnZhcmFyZ3MrPTQsZX0sZ2V0cDooKT0+ZGUuZ2V0KCksZ2V0U3RyOmU9PmNlKGUpLGdldFN0cmVhbUZyb21GRDplPT5sZS5nZXRTdHJlYW1DaGVja2VkKGUpfSxoZT1lPT4oRltPZSgpPj4yXT1lLGUpLGZlPXtCVUNLRVRfQlVGRkVSX1NJWkU6ODE5Mixtb3VudDplPT5sZS5jcmVhdGVOb2RlKG51bGwsIi8iLDE2ODk1LDApLGNyZWF0ZVBpcGUoKXt2YXIgZT17YnVja2V0czpbXSxyZWZjbnQ6Mn07ZS5idWNrZXRzLnB1c2goe2J1ZmZlcjpuZXcgVWludDhBcnJheShmZS5CVUNLRVRfQlVGRkVSX1NJWkUpLG9mZnNldDowLHJvZmZzZXQ6MH0pO3ZhciByPWZlLm5leHRuYW1lKCksdD1mZS5uZXh0bmFtZSgpLG49bGUuY3JlYXRlTm9kZShmZS5yb290LHIsNDA5NiwwKSxvPWxlLmNyZWF0ZU5vZGUoZmUucm9vdCx0LDQwOTYsMCk7bi5waXBlPWUsby5waXBlPWU7dmFyIGE9bGUuY3JlYXRlU3RyZWFtKHtwYXRoOnIsbm9kZTpuLGZsYWdzOjAsc2Vla2FibGU6ITEsc3RyZWFtX29wczpmZS5zdHJlYW1fb3BzfSk7bi5zdHJlYW09YTt2YXIgcz1sZS5jcmVhdGVTdHJlYW0oe3BhdGg6dCxub2RlOm8sZmxhZ3M6MSxzZWVrYWJsZTohMSxzdHJlYW1fb3BzOmZlLnN0cmVhbV9vcHN9KTtyZXR1cm4gby5zdHJlYW09cyx7cmVhZGFibGVfZmQ6YS5mZCx3cml0YWJsZV9mZDpzLmZkfX0sc3RyZWFtX29wczp7cG9sbChlKXt2YXIgcj1lLm5vZGUucGlwZTtpZigxPT0oMjA5NzE1NSZlLmZsYWdzKSlyZXR1cm4gMjYwO2lmKHIuYnVja2V0cy5sZW5ndGg+MClmb3IodmFyIHQ9MDt0PHIuYnVja2V0cy5sZW5ndGg7dCsrKXt2YXIgbj1yLmJ1Y2tldHNbdF07aWYobi5vZmZzZXQtbi5yb2Zmc2V0PjApcmV0dXJuIDY1fXJldHVybiAwfSxpb2N0bDooZSxyLHQpPT4yOCxmc3luYzplPT4yOCxyZWFkKGUscix0LG4sbyl7Zm9yKHZhciBhPWUubm9kZS5waXBlLHM9MCxpPTA7aTxhLmJ1Y2tldHMubGVuZ3RoO2krKyl7dmFyIHU9YS5idWNrZXRzW2ldO3MrPXUub2Zmc2V0LXUucm9mZnNldH12YXIgbD1yLnN1YmFycmF5KHQsdCtuKTtpZihuPD0wKXJldHVybiAwO2lmKDA9PXMpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoNik7dmFyIGM9TWF0aC5taW4ocyxuKSxkPWMsaD0wO2ZvcihpPTA7aTxhLmJ1Y2tldHMubGVuZ3RoO2krKyl7dmFyIGY9YS5idWNrZXRzW2ldLG09Zi5vZmZzZXQtZi5yb2Zmc2V0O2lmKGM8PW0pe3ZhciBwPWYuYnVmZmVyLnN1YmFycmF5KGYucm9mZnNldCxmLm9mZnNldCk7YzxtPyhwPXAuc3ViYXJyYXkoMCxjKSxmLnJvZmZzZXQrPWMpOmgrKyxsLnNldChwKTticmVha31wPWYuYnVmZmVyLnN1YmFycmF5KGYucm9mZnNldCxmLm9mZnNldCksbC5zZXQocCksbD1sLnN1YmFycmF5KHAuYnl0ZUxlbmd0aCksYy09cC5ieXRlTGVuZ3RoLGgrK31yZXR1cm4gaCYmaD09YS5idWNrZXRzLmxlbmd0aCYmKGgtLSxhLmJ1Y2tldHNbaF0ub2Zmc2V0PTAsYS5idWNrZXRzW2hdLnJvZmZzZXQ9MCksYS5idWNrZXRzLnNwbGljZSgwLGgpLGR9LHdyaXRlKGUscix0LG4sbyl7dmFyIGE9ZS5ub2RlLnBpcGUscz1yLnN1YmFycmF5KHQsdCtuKSxpPXMuYnl0ZUxlbmd0aDtpZihpPD0wKXJldHVybiAwO3ZhciB1PW51bGw7MD09YS5idWNrZXRzLmxlbmd0aD8odT17YnVmZmVyOm5ldyBVaW50OEFycmF5KGZlLkJVQ0tFVF9CVUZGRVJfU0laRSksb2Zmc2V0OjAscm9mZnNldDowfSxhLmJ1Y2tldHMucHVzaCh1KSk6dT1hLmJ1Y2tldHNbYS5idWNrZXRzLmxlbmd0aC0xXSxBKHUub2Zmc2V0PD1mZS5CVUNLRVRfQlVGRkVSX1NJWkUpO3ZhciBsPWZlLkJVQ0tFVF9CVUZGRVJfU0laRS11Lm9mZnNldDtpZihsPj1pKXJldHVybiB1LmJ1ZmZlci5zZXQocyx1Lm9mZnNldCksdS5vZmZzZXQrPWksaTtsPjAmJih1LmJ1ZmZlci5zZXQocy5zdWJhcnJheSgwLGwpLHUub2Zmc2V0KSx1Lm9mZnNldCs9bCxzPXMuc3ViYXJyYXkobCxzLmJ5dGVMZW5ndGgpKTtmb3IodmFyIGM9cy5ieXRlTGVuZ3RoL2ZlLkJVQ0tFVF9CVUZGRVJfU0laRXwwLGQ9cy5ieXRlTGVuZ3RoJWZlLkJVQ0tFVF9CVUZGRVJfU0laRSxoPTA7aDxjO2grKyl7dmFyIGY9e2J1ZmZlcjpuZXcgVWludDhBcnJheShmZS5CVUNLRVRfQlVGRkVSX1NJWkUpLG9mZnNldDpmZS5CVUNLRVRfQlVGRkVSX1NJWkUscm9mZnNldDowfTthLmJ1Y2tldHMucHVzaChmKSxmLmJ1ZmZlci5zZXQocy5zdWJhcnJheSgwLGZlLkJVQ0tFVF9CVUZGRVJfU0laRSkpLHM9cy5zdWJhcnJheShmZS5CVUNLRVRfQlVGRkVSX1NJWkUscy5ieXRlTGVuZ3RoKX1yZXR1cm4gZD4wJiYoZj17YnVmZmVyOm5ldyBVaW50OEFycmF5KGZlLkJVQ0tFVF9CVUZGRVJfU0laRSksb2Zmc2V0OnMuYnl0ZUxlbmd0aCxyb2Zmc2V0OjB9LGEuYnVja2V0cy5wdXNoKGYpLGYuYnVmZmVyLnNldChzKSksaX0sY2xvc2UoZSl7dmFyIHI9ZS5ub2RlLnBpcGU7ci5yZWZjbnQtLSwwPT09ci5yZWZjbnQmJihyLmJ1Y2tldHM9bnVsbCl9fSxuZXh0bmFtZTooKT0+KGZlLm5leHRuYW1lLmN1cnJlbnR8fChmZS5uZXh0bmFtZS5jdXJyZW50PTApLCJwaXBlWyIrZmUubmV4dG5hbWUuY3VycmVudCsrKyJdIil9LG1lPShlLHIpPT5yKzIwOTcxNTI+Pj4wPDQxOTQzMDUtISFlPyhlPj4+MCkrNDI5NDk2NzI5NipyOk5hTixwZT1lPT5lJTQ9PTAmJihlJTEwMCE9MHx8ZSU0MDA9PTApLHZlPVswLDMxLDYwLDkxLDEyMSwxNTIsMTgyLDIxMywyNDQsMjc0LDMwNSwzMzVdLHdlPVswLDMxLDU5LDkwLDEyMCwxNTEsMTgxLDIxMiwyNDMsMjczLDMwNCwzMzRdLGdlPWU9PihwZShlLmdldEZ1bGxZZWFyKCkpP3ZlOndlKVtlLmdldE1vbnRoKCldK2UuZ2V0RGF0ZSgpLTEsX2U9KGUscix0KT0+dGUoZSxrLHIsdCkseWU9ZT0+e3ZhciByPXJlKGUpKzEsdD14ZShyKTtyZXR1cm4gdCYmX2UoZSx0LHIpLHR9LEVlPWU9Pnt2YXIgcj0oZS1nLmJ1ZmZlci5ieXRlTGVuZ3RoKzY1NTM1KS82NTUzNjt0cnl7cmV0dXJuIGcuZ3JvdyhyKSxDKCksMX1jYXRjaChlKXt9fSxiZT17fSxrZT0oKT0+e2lmKCFrZS5zdHJpbmdzKXt2YXIgZT17VVNFUjoid2ViX3VzZXIiLExPR05BTUU6IndlYl91c2VyIixQQVRIOiIvIixQV0Q6Ii8iLEhPTUU6Ii9ob21lL3dlYl91c2VyIixMQU5HOigib2JqZWN0Ij09dHlwZW9mIG5hdmlnYXRvciYmbmF2aWdhdG9yLmxhbmd1YWdlcyYmbmF2aWdhdG9yLmxhbmd1YWdlc1swXXx8IkMiKS5yZXBsYWNlKCItIiwiXyIpKyIuVVRGLTgiLF86dXx8Ii4vdGhpcy5wcm9ncmFtIn07Zm9yKHZhciByIGluIGJlKXZvaWQgMD09PWJlW3JdP2RlbGV0ZSBlW3JdOmVbcl09YmVbcl07dmFyIHQ9W107Zm9yKHZhciByIGluIGUpdC5wdXNoKGAke3J9PSR7ZVtyXX1gKTtrZS5zdHJpbmdzPXR9cmV0dXJuIGtlLnN0cmluZ3N9LFNlPWU9PntYfHwobi5vbkV4aXQ/LihlKSxNPSEwKSxsKGUsbmV3IHEoZSkpfSxGZT0oZSxyKT0+e1NlKGUpfSxEZT1bMzEsMjksMzEsMzAsMzEsMzAsMzEsMzEsMzAsMzEsMzAsMzFdLE1lPVszMSwyOCwzMSwzMCwzMSwzMCwzMSwzMSwzMCwzMSwzMCwzMV0sQWU9KGUscik9PntFLnNldChlLHIpfSxDZT1lPT5uWyJfIitlXSxQZT0oZSxyLHQsbixvKT0+e3ZhciBhPXtzdHJpbmc6ZT0+e3ZhciByPTA7cmV0dXJuIG51bGwhPWUmJjAhPT1lJiYocj0oZT0+e3ZhciByPXJlKGUpKzEsdD1IZShyKTtyZXR1cm4gX2UoZSx0LHIpLHR9KShlKSkscn0sYXJyYXk6ZT0+e3ZhciByPUhlKGUubGVuZ3RoKTtyZXR1cm4gQWUoZSxyKSxyfX0scz1DZShlKSxpPVtdLHU9MDtpZihuKWZvcih2YXIgbD0wO2w8bi5sZW5ndGg7bCsrKXt2YXIgYz1hW3RbbF1dO2M/KDA9PT11JiYodT1qZSgpKSxpW2xdPWMobltsXSkpOmlbbF09bltsXX12YXIgZD1zLmFwcGx5KG51bGwsaSk7cmV0dXJuIGQ9ZnVuY3Rpb24oZSl7cmV0dXJuIDAhPT11JiZJZSh1KSxmdW5jdGlvbihlKXtyZXR1cm4ic3RyaW5nIj09PXI/Y2UoZSk6ImJvb2xlYW4iPT09cj9Cb29sZWFuKGUpOmV9KGUpfShkKX0sVGU9ZnVuY3Rpb24oZSxyLHQsbil7ZXx8KGU9dGhpcyksdGhpcy5wYXJlbnQ9ZSx0aGlzLm1vdW50PWUubW91bnQsdGhpcy5tb3VudGVkPW51bGwsdGhpcy5pZD1sZS5uZXh0SW5vZGUrKyx0aGlzLm5hbWU9cix0aGlzLm1vZGU9dCx0aGlzLm5vZGVfb3BzPXt9LHRoaXMuc3RyZWFtX29wcz17fSx0aGlzLnJkZXY9bn0sUmU9MzY1LHplPTE0NjtPYmplY3QuZGVmaW5lUHJvcGVydGllcyhUZS5wcm90b3R5cGUse3JlYWQ6e2dldDpmdW5jdGlvbigpe3JldHVybih0aGlzLm1vZGUmUmUpPT09UmV9LHNldDpmdW5jdGlvbihlKXtlP3RoaXMubW9kZXw9UmU6dGhpcy5tb2RlJj0tMzY2fX0sd3JpdGU6e2dldDpmdW5jdGlvbigpe3JldHVybih0aGlzLm1vZGUmemUpPT09emV9LHNldDpmdW5jdGlvbihlKXtlP3RoaXMubW9kZXw9emU6dGhpcy5tb2RlJj0tMTQ3fX0saXNGb2xkZXI6e2dldDpmdW5jdGlvbigpe3JldHVybiBsZS5pc0Rpcih0aGlzLm1vZGUpfX0saXNEZXZpY2U6e2dldDpmdW5jdGlvbigpe3JldHVybiBsZS5pc0NocmRldih0aGlzLm1vZGUpfX19KSxsZS5GU05vZGU9VGUsbGUuY3JlYXRlUHJlbG9hZGVkRmlsZT0oZSxyLHQsbixvLHMsaSx1LGwsYyk9Pnt2YXIgZD1yP1YucmVzb2x2ZShaLmpvaW4yKGUscikpOmU7ZnVuY3Rpb24gaCh0KXtmdW5jdGlvbiBhKHQpe2M/LigpLHV8fCgoZSxyLHQsbixvLGEpPT57bGUuY3JlYXRlRGF0YUZpbGUoZSxyLHQsbixvLGEpfSkoZSxyLHQsbixvLGwpLHM/LigpLHgoKX0oKGUscix0LG4pPT57InVuZGVmaW5lZCIhPXR5cGVvZiBCcm93c2VyJiZCcm93c2VyLmluaXQoKTt2YXIgbz0hMTtyZXR1cm4gaWUuZm9yRWFjaCgoYT0+e298fGEuY2FuSGFuZGxlKHIpJiYoYS5oYW5kbGUoZSxyLHQsbiksbz0hMCl9KSksb30pKHQsZCxhLCgoKT0+e2k/LigpLHgoKX0pKXx8YSh0KX1MKCksInN0cmluZyI9PXR5cGVvZiB0PygoZSxyLHQsbik9Pnt2YXIgbz1uPyIiOmBhbCAke2V9YDthKGUsKHQ9PntBKHQsYExvYWRpbmcgZGF0YSBmaWxlICIke2V9IiBmYWlsZWQgKG5vIGFycmF5QnVmZmVyKS5gKSxyKG5ldyBVaW50OEFycmF5KHQpKSxvJiZ4KCl9KSwocj0+e2lmKCF0KXRocm93YExvYWRpbmcgZGF0YSBmaWxlICIke2V9IiBmYWlsZWQuYDt0KCl9KSksbyYmTCgpfSkodCwoZT0+aChlKSksaSk6aCh0KX0sbGUuc3RhdGljSW5pdCgpO3ZhciBVZT17aTpmdW5jdGlvbihlKXt0cnl7dmFyIHI9ZGUuZ2V0U3RyZWFtRnJvbUZEKGUpO3JldHVybiBsZS5jcmVhdGVTdHJlYW0ocikuZmR9Y2F0Y2goZSl7aWYodm9pZCAwPT09bGV8fCJFcnJub0Vycm9yIiE9PWUubmFtZSl0aHJvdyBlO3JldHVybi1lLmVycm5vfX0sYTpmdW5jdGlvbihlLHIsdCl7ZGUudmFyYXJncz10O3RyeXt2YXIgbj1kZS5nZXRTdHJlYW1Gcm9tRkQoZSk7c3dpdGNoKHIpe2Nhc2UgMDppZigobz1kZS5nZXQoKSk8MClyZXR1cm4tMjg7Zm9yKDtsZS5zdHJlYW1zW29dOylvKys7cmV0dXJuIGxlLmNyZWF0ZVN0cmVhbShuLG8pLmZkO2Nhc2UgMTpjYXNlIDI6Y2FzZSA2OmNhc2UgNzpyZXR1cm4gMDtjYXNlIDM6cmV0dXJuIG4uZmxhZ3M7Y2FzZSA0OnZhciBvPWRlLmdldCgpO3JldHVybiBuLmZsYWdzfD1vLDA7Y2FzZSA1OnJldHVybiBvPWRlLmdldHAoKSxTW28rMD4+MV09MiwwO2Nhc2UgMTY6Y2FzZSA4OmRlZmF1bHQ6cmV0dXJuLTI4O2Nhc2UgOTpyZXR1cm4gaGUoMjgpLC0xfX1jYXRjaChlKXtpZih2b2lkIDA9PT1sZXx8IkVycm5vRXJyb3IiIT09ZS5uYW1lKXRocm93IGU7cmV0dXJuLWUuZXJybm99fSx4OmZ1bmN0aW9uKGUscil7dHJ5e3ZhciB0PWRlLmdldFN0cmVhbUZyb21GRChlKTtyZXR1cm4gZGUuZG9TdGF0KGxlLnN0YXQsdC5wYXRoLHIpfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4tZS5lcnJub319LHU6ZnVuY3Rpb24oZSxyKXt0cnl7cmV0dXJuIGU9ZGUuZ2V0U3RyKGUpLGRlLmRvU3RhdChsZS5sc3RhdCxlLHIpfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4tZS5lcnJub319LHY6ZnVuY3Rpb24oZSxyLHQsbil7dHJ5e3I9ZGUuZ2V0U3RyKHIpO3ZhciBvPTI1NiZuLGE9NDA5NiZuO3JldHVybiBuJj0tNjQwMSxyPWRlLmNhbGN1bGF0ZUF0KGUscixhKSxkZS5kb1N0YXQobz9sZS5sc3RhdDpsZS5zdGF0LHIsdCl9Y2F0Y2goZSl7aWYodm9pZCAwPT09bGV8fCJFcnJub0Vycm9yIiE9PWUubmFtZSl0aHJvdyBlO3JldHVybi1lLmVycm5vfX0seTpmdW5jdGlvbihlLHIsdCxuKXtkZS52YXJhcmdzPW47dHJ5e3I9ZGUuZ2V0U3RyKHIpLHI9ZGUuY2FsY3VsYXRlQXQoZSxyKTt2YXIgbz1uP2RlLmdldCgpOjA7cmV0dXJuIGxlLm9wZW4ocix0LG8pLmZkfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4tZS5lcnJub319LHQ6ZnVuY3Rpb24oZSl7dHJ5e2lmKDA9PWUpdGhyb3cgbmV3IGxlLkVycm5vRXJyb3IoMjEpO3ZhciByPWZlLmNyZWF0ZVBpcGUoKTtyZXR1cm4gRltlPj4yXT1yLnJlYWRhYmxlX2ZkLEZbZSs0Pj4yXT1yLndyaXRhYmxlX2ZkLDB9Y2F0Y2goZSl7aWYodm9pZCAwPT09bGV8fCJFcnJub0Vycm9yIiE9PWUubmFtZSl0aHJvdyBlO3JldHVybi1lLmVycm5vfX0sczpmdW5jdGlvbihlLHIsdCl7dHJ5e2Zvcih2YXIgbj0wLG89MDtvPHI7bysrKXt2YXIgYT1lKzgqbyxzPUZbYT4+Ml0saT1TW2ErND4+MV0sdT0zMixsPWxlLmdldFN0cmVhbShzKTtsJiYodT1kZS5ERUZBVUxUX1BPTExNQVNLLGwuc3RyZWFtX29wcy5wb2xsJiYodT1sLnN0cmVhbV9vcHMucG9sbChsLC0xKSkpLCh1Jj0yNHxpKSYmbisrLFNbYSs2Pj4xXT11fXJldHVybiBufWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4tZS5lcnJub319LHc6ZnVuY3Rpb24oZSxyKXt0cnl7cmV0dXJuIGU9ZGUuZ2V0U3RyKGUpLGRlLmRvU3RhdChsZS5zdGF0LGUscil9Y2F0Y2goZSl7aWYodm9pZCAwPT09bGV8fCJFcnJub0Vycm9yIiE9PWUubmFtZSl0aHJvdyBlO3JldHVybi1lLmVycm5vfX0scTpmdW5jdGlvbihlLHIsdCl7dHJ5e3JldHVybiByPWRlLmdldFN0cihyKSxyPWRlLmNhbGN1bGF0ZUF0KGUsciksMD09PXQ/bGUudW5saW5rKHIpOjUxMj09PXQ/bGUucm1kaXIocik6TygiSW52YWxpZCBmbGFncyBwYXNzZWQgdG8gdW5saW5rYXQiKSwwfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4tZS5lcnJub319LEI6KCk9PjEsazpmdW5jdGlvbihlLHIsdCl7dmFyIG49bWUoZSxyKSxvPW5ldyBEYXRlKDFlMypuKTtGW3Q+PjJdPW8uZ2V0VVRDU2Vjb25kcygpLEZbdCs0Pj4yXT1vLmdldFVUQ01pbnV0ZXMoKSxGW3QrOD4+Ml09by5nZXRVVENIb3VycygpLEZbdCsxMj4+Ml09by5nZXRVVENEYXRlKCksRlt0KzE2Pj4yXT1vLmdldFVUQ01vbnRoKCksRlt0KzIwPj4yXT1vLmdldFVUQ0Z1bGxZZWFyKCktMTkwMCxGW3QrMjQ+PjJdPW8uZ2V0VVRDRGF5KCk7dmFyIGE9RGF0ZS5VVEMoby5nZXRVVENGdWxsWWVhcigpLDAsMSwwLDAsMCwwKSxzPShvLmdldFRpbWUoKS1hKS84NjRlNXwwO0ZbdCsyOD4+Ml09c30sbDpmdW5jdGlvbihlLHIsdCl7dmFyIG49bWUoZSxyKSxvPW5ldyBEYXRlKDFlMypuKTtGW3Q+PjJdPW8uZ2V0U2Vjb25kcygpLEZbdCs0Pj4yXT1vLmdldE1pbnV0ZXMoKSxGW3QrOD4+Ml09by5nZXRIb3VycygpLEZbdCsxMj4+Ml09by5nZXREYXRlKCksRlt0KzE2Pj4yXT1vLmdldE1vbnRoKCksRlt0KzIwPj4yXT1vLmdldEZ1bGxZZWFyKCktMTkwMCxGW3QrMjQ+PjJdPW8uZ2V0RGF5KCk7dmFyIGE9MHxnZShvKTtGW3QrMjg+PjJdPWEsRlt0KzM2Pj4yXT0tNjAqby5nZXRUaW1lem9uZU9mZnNldCgpO3ZhciBzPW5ldyBEYXRlKG8uZ2V0RnVsbFllYXIoKSwwLDEpLGk9bmV3IERhdGUoby5nZXRGdWxsWWVhcigpLDYsMSkuZ2V0VGltZXpvbmVPZmZzZXQoKSx1PXMuZ2V0VGltZXpvbmVPZmZzZXQoKSxsPTB8KGkhPXUmJm8uZ2V0VGltZXpvbmVPZmZzZXQoKT09TWF0aC5taW4odSxpKSk7Rlt0KzMyPj4yXT1sfSxtOmZ1bmN0aW9uKGUpe3ZhciByPSgoKT0+e3ZhciByPW5ldyBEYXRlKEZbZSsyMD4+Ml0rMTkwMCxGW2UrMTY+PjJdLEZbZSsxMj4+Ml0sRltlKzg+PjJdLEZbZSs0Pj4yXSxGW2U+PjJdLDApLHQ9RltlKzMyPj4yXSxuPXIuZ2V0VGltZXpvbmVPZmZzZXQoKSxvPW5ldyBEYXRlKHIuZ2V0RnVsbFllYXIoKSwwLDEpLGE9bmV3IERhdGUoci5nZXRGdWxsWWVhcigpLDYsMSkuZ2V0VGltZXpvbmVPZmZzZXQoKSxzPW8uZ2V0VGltZXpvbmVPZmZzZXQoKSxpPU1hdGgubWluKHMsYSk7aWYodDwwKUZbZSszMj4+Ml09TnVtYmVyKGEhPXMmJmk9PW4pO2Vsc2UgaWYodD4wIT0oaT09bikpe3ZhciB1PU1hdGgubWF4KHMsYSksbD10PjA/aTp1O3Iuc2V0VGltZShyLmdldFRpbWUoKSs2ZTQqKGwtbikpfUZbZSsyND4+Ml09ci5nZXREYXkoKTt2YXIgYz0wfGdlKHIpO0ZbZSsyOD4+Ml09YyxGW2U+PjJdPXIuZ2V0U2Vjb25kcygpLEZbZSs0Pj4yXT1yLmdldE1pbnV0ZXMoKSxGW2UrOD4+Ml09ci5nZXRIb3VycygpLEZbZSsxMj4+Ml09ci5nZXREYXRlKCksRltlKzE2Pj4yXT1yLmdldE1vbnRoKCksRltlKzIwPj4yXT1yLmdldFllYXIoKTt2YXIgZD1yLmdldFRpbWUoKTtyZXR1cm4gaXNOYU4oZCk/KGhlKDYxKSwtMSk6ZC8xZTN9KSgpO3JldHVybiBCZSgoaj1yLCtNYXRoLmFicyhqKT49MT9qPjA/K01hdGguZmxvb3Ioai80Mjk0OTY3Mjk2KT4+PjA6fn4rTWF0aC5jZWlsKChqLSsofn5qPj4+MCkpLzQyOTQ5NjcyOTYpPj4+MDowKSkscj4+PjB9LG46ZnVuY3Rpb24oZSl7dmFyIHI9KCgpPT57dmFyIHI9RGF0ZS5VVEMoRltlKzIwPj4yXSsxOTAwLEZbZSsxNj4+Ml0sRltlKzEyPj4yXSxGW2UrOD4+Ml0sRltlKzQ+PjJdLEZbZT4+Ml0sMCksdD1uZXcgRGF0ZShyKTtGW2UrMjQ+PjJdPXQuZ2V0VVRDRGF5KCk7dmFyIG49RGF0ZS5VVEModC5nZXRVVENGdWxsWWVhcigpLDAsMSwwLDAsMCwwKSxvPSh0LmdldFRpbWUoKS1uKS84NjRlNXwwO3JldHVybiBGW2UrMjg+PjJdPW8sdC5nZXRUaW1lKCkvMWUzfSkoKTtyZXR1cm4gQmUoKGo9ciwrTWF0aC5hYnMoaik+PTE/aj4wPytNYXRoLmZsb29yKGovNDI5NDk2NzI5Nik+Pj4wOn5+K01hdGguY2VpbCgoai0rKH5+aj4+PjApKS80Mjk0OTY3Mjk2KT4+PjA6MCkpLHI+Pj4wfSxyOihlLHIsdCk9Pnt2YXIgbj0obmV3IERhdGUpLmdldEZ1bGxZZWFyKCksbz1uZXcgRGF0ZShuLDAsMSksYT1uZXcgRGF0ZShuLDYsMSkscz1vLmdldFRpbWV6b25lT2Zmc2V0KCksaT1hLmdldFRpbWV6b25lT2Zmc2V0KCksdT1NYXRoLm1heChzLGkpO2Z1bmN0aW9uIGwoZSl7dmFyIHI9ZS50b1RpbWVTdHJpbmcoKS5tYXRjaCgvXCgoW0EtWmEteiBdKylcKSQvKTtyZXR1cm4gcj9yWzFdOiJHTVQifURbZT4+Ml09NjAqdSxGW3I+PjJdPU51bWJlcihzIT1pKTt2YXIgYz1sKG8pLGQ9bChhKSxoPXllKGMpLGY9eWUoZCk7aTxzPyhEW3Q+PjJdPWgsRFt0KzQ+PjJdPWYpOihEW3Q+PjJdPWYsRFt0KzQ+PjJdPWgpfSxiOigpPT57TygiIil9LGM6KCk9PkRhdGUubm93KCksaDooZSxyLHQpPT5rLmNvcHlXaXRoaW4oZSxyLHIrdCkscDplPT57dmFyIHI9ay5sZW5ndGgsdD0yMTQ3NDgzNjQ4O2lmKChlPj4+PTApPnQpcmV0dXJuITE7Zm9yKHZhciBuLG8sYT0xO2E8PTQ7YSo9Mil7dmFyIHM9ciooMSsuMi9hKTtzPU1hdGgubWluKHMsZSsxMDA2NjMyOTYpO3ZhciBpPU1hdGgubWluKHQsKG49TWF0aC5tYXgoZSxzKSkrKChvPTY1NTM2KS1uJW8pJW8pO2lmKEVlKGkpKXJldHVybiEwfXJldHVybiExfSx6OihlLHIpPT57dmFyIHQ9MDtyZXR1cm4ga2UoKS5mb3JFYWNoKCgobixvKT0+e3ZhciBhPXIrdDtEW2UrNCpvPj4yXT1hLCgoZSxyKT0+e2Zvcih2YXIgdD0wO3Q8ZS5sZW5ndGg7Kyt0KUVbcisrPj4wXT1lLmNoYXJDb2RlQXQodCk7RVtyPj4wXT0wfSkobixhKSx0Kz1uLmxlbmd0aCsxfSkpLDB9LEE6KGUscik9Pnt2YXIgdD1rZSgpO0RbZT4+Ml09dC5sZW5ndGg7dmFyIG49MDtyZXR1cm4gdC5mb3JFYWNoKChlPT5uKz1lLmxlbmd0aCsxKSksRFtyPj4yXT1uLDB9LGc6RmUsZTpmdW5jdGlvbihlKXt0cnl7dmFyIHI9ZGUuZ2V0U3RyZWFtRnJvbUZEKGUpO3JldHVybiBsZS5jbG9zZShyKSwwfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4gZS5lcnJub319LGo6ZnVuY3Rpb24oZSxyLHQsbil7dHJ5e3ZhciBvPSgoZSxyLHQsbik9Pntmb3IodmFyIG89MCxhPTA7YTx0O2ErKyl7dmFyIHM9RFtyPj4yXSxpPURbcis0Pj4yXTtyKz04O3ZhciB1PWxlLnJlYWQoZSxFLHMsaSxuKTtpZih1PDApcmV0dXJuLTE7aWYobys9dSx1PGkpYnJlYWs7dm9pZCAwIT09biYmKG4rPXUpfXJldHVybiBvfSkoZGUuZ2V0U3RyZWFtRnJvbUZEKGUpLHIsdCk7cmV0dXJuIERbbj4+Ml09bywwfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4gZS5lcnJub319LG86ZnVuY3Rpb24oZSxyLHQsbixvKXt2YXIgYT1tZShyLHQpO3RyeXtpZihpc05hTihhKSlyZXR1cm4gNjE7dmFyIHM9ZGUuZ2V0U3RyZWFtRnJvbUZEKGUpO3JldHVybiBsZS5sbHNlZWsocyxhLG4pLEk9W3MucG9zaXRpb24+Pj4wLChqPXMucG9zaXRpb24sK01hdGguYWJzKGopPj0xP2o+MD8rTWF0aC5mbG9vcihqLzQyOTQ5NjcyOTYpPj4+MDp+fitNYXRoLmNlaWwoKGotKyh+fmo+Pj4wKSkvNDI5NDk2NzI5Nik+Pj4wOjApXSxGW28+PjJdPUlbMF0sRltvKzQ+PjJdPUlbMV0scy5nZXRkZW50cyYmMD09PWEmJjA9PT1uJiYocy5nZXRkZW50cz1udWxsKSwwfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4gZS5lcnJub319LGQ6ZnVuY3Rpb24oZSxyLHQsbil7dHJ5e3ZhciBvPSgoZSxyLHQsbik9Pntmb3IodmFyIG89MCxhPTA7YTx0O2ErKyl7dmFyIHM9RFtyPj4yXSxpPURbcis0Pj4yXTtyKz04O3ZhciB1PWxlLndyaXRlKGUsRSxzLGksbik7aWYodTwwKXJldHVybi0xO28rPXUsdm9pZCAwIT09biYmKG4rPXUpfXJldHVybiBvfSkoZGUuZ2V0U3RyZWFtRnJvbUZEKGUpLHIsdCk7cmV0dXJuIERbbj4+Ml09bywwfWNhdGNoKGUpe2lmKHZvaWQgMD09PWxlfHwiRXJybm9FcnJvciIhPT1lLm5hbWUpdGhyb3cgZTtyZXR1cm4gZS5lcnJub319LGY6KGUscix0LG4pPT57dmFyIG89RFtuKzQwPj4yXSxhPXt0bV9zZWM6RltuPj4yXSx0bV9taW46RltuKzQ+PjJdLHRtX2hvdXI6RltuKzg+PjJdLHRtX21kYXk6RltuKzEyPj4yXSx0bV9tb246RltuKzE2Pj4yXSx0bV95ZWFyOkZbbisyMD4+Ml0sdG1fd2RheTpGW24rMjQ+PjJdLHRtX3lkYXk6RltuKzI4Pj4yXSx0bV9pc2RzdDpGW24rMzI+PjJdLHRtX2dtdG9mZjpGW24rMzY+PjJdLHRtX3pvbmU6bz9jZShvKToiIn0scz1jZSh0KSxpPXsiJWMiOiIlYSAlYiAlZCAlSDolTTolUyAlWSIsIiVEIjoiJW0vJWQvJXkiLCIlRiI6IiVZLSVtLSVkIiwiJWgiOiIlYiIsIiVyIjoiJUk6JU06JVMgJXAiLCIlUiI6IiVIOiVNIiwiJVQiOiIlSDolTTolUyIsIiV4IjoiJW0vJWQvJXkiLCIlWCI6IiVIOiVNOiVTIiwiJUVjIjoiJWMiLCIlRUMiOiIlQyIsIiVFeCI6IiVtLyVkLyV5IiwiJUVYIjoiJUg6JU06JVMiLCIlRXkiOiIleSIsIiVFWSI6IiVZIiwiJU9kIjoiJWQiLCIlT2UiOiIlZSIsIiVPSCI6IiVIIiwiJU9JIjoiJUkiLCIlT20iOiIlbSIsIiVPTSI6IiVNIiwiJU9TIjoiJVMiLCIlT3UiOiIldSIsIiVPVSI6IiVVIiwiJU9WIjoiJVYiLCIlT3ciOiIldyIsIiVPVyI6IiVXIiwiJU95IjoiJXkifTtmb3IodmFyIHUgaW4gaSlzPXMucmVwbGFjZShuZXcgUmVnRXhwKHUsImciKSxpW3VdKTt2YXIgbD1bIlN1bmRheSIsIk1vbmRheSIsIlR1ZXNkYXkiLCJXZWRuZXNkYXkiLCJUaHVyc2RheSIsIkZyaWRheSIsIlNhdHVyZGF5Il0sYz1bIkphbnVhcnkiLCJGZWJydWFyeSIsIk1hcmNoIiwiQXByaWwiLCJNYXkiLCJKdW5lIiwiSnVseSIsIkF1Z3VzdCIsIlNlcHRlbWJlciIsIk9jdG9iZXIiLCJOb3ZlbWJlciIsIkRlY2VtYmVyIl07ZnVuY3Rpb24gZChlLHIsdCl7Zm9yKHZhciBuPSJudW1iZXIiPT10eXBlb2YgZT9lLnRvU3RyaW5nKCk6ZXx8IiI7bi5sZW5ndGg8cjspbj10WzBdK247cmV0dXJuIG59ZnVuY3Rpb24gaChlLHIpe3JldHVybiBkKGUsciwiMCIpfWZ1bmN0aW9uIGYoZSxyKXtmdW5jdGlvbiB0KGUpe3JldHVybiBlPDA/LTE6ZT4wPzE6MH12YXIgbjtyZXR1cm4gMD09PShuPXQoZS5nZXRGdWxsWWVhcigpLXIuZ2V0RnVsbFllYXIoKSkpJiYwPT09KG49dChlLmdldE1vbnRoKCktci5nZXRNb250aCgpKSkmJihuPXQoZS5nZXREYXRlKCktci5nZXREYXRlKCkpKSxufWZ1bmN0aW9uIG0oZSl7c3dpdGNoKGUuZ2V0RGF5KCkpe2Nhc2UgMDpyZXR1cm4gbmV3IERhdGUoZS5nZXRGdWxsWWVhcigpLTEsMTEsMjkpO2Nhc2UgMTpyZXR1cm4gZTtjYXNlIDI6cmV0dXJuIG5ldyBEYXRlKGUuZ2V0RnVsbFllYXIoKSwwLDMpO2Nhc2UgMzpyZXR1cm4gbmV3IERhdGUoZS5nZXRGdWxsWWVhcigpLDAsMik7Y2FzZSA0OnJldHVybiBuZXcgRGF0ZShlLmdldEZ1bGxZZWFyKCksMCwxKTtjYXNlIDU6cmV0dXJuIG5ldyBEYXRlKGUuZ2V0RnVsbFllYXIoKS0xLDExLDMxKTtjYXNlIDY6cmV0dXJuIG5ldyBEYXRlKGUuZ2V0RnVsbFllYXIoKS0xLDExLDMwKX19ZnVuY3Rpb24gcChlKXt2YXIgcj0oKGUscik9Pntmb3IodmFyIHQ9bmV3IERhdGUoZS5nZXRUaW1lKCkpO3I+MDspe3ZhciBuPXBlKHQuZ2V0RnVsbFllYXIoKSksbz10LmdldE1vbnRoKCksYT0obj9EZTpNZSlbb107aWYoIShyPmEtdC5nZXREYXRlKCkpKXJldHVybiB0LnNldERhdGUodC5nZXREYXRlKCkrciksdDtyLT1hLXQuZ2V0RGF0ZSgpKzEsdC5zZXREYXRlKDEpLG88MTE/dC5zZXRNb250aChvKzEpOih0LnNldE1vbnRoKDApLHQuc2V0RnVsbFllYXIodC5nZXRGdWxsWWVhcigpKzEpKX1yZXR1cm4gdH0pKG5ldyBEYXRlKGUudG1feWVhcisxOTAwLDAsMSksZS50bV95ZGF5KSx0PW5ldyBEYXRlKHIuZ2V0RnVsbFllYXIoKSwwLDQpLG49bmV3IERhdGUoci5nZXRGdWxsWWVhcigpKzEsMCw0KSxvPW0odCksYT1tKG4pO3JldHVybiBmKG8scik8PTA/ZihhLHIpPD0wP3IuZ2V0RnVsbFllYXIoKSsxOnIuZ2V0RnVsbFllYXIoKTpyLmdldEZ1bGxZZWFyKCktMX12YXIgdj17IiVhIjplPT5sW2UudG1fd2RheV0uc3Vic3RyaW5nKDAsMyksIiVBIjplPT5sW2UudG1fd2RheV0sIiViIjplPT5jW2UudG1fbW9uXS5zdWJzdHJpbmcoMCwzKSwiJUIiOmU9PmNbZS50bV9tb25dLCIlQyI6ZT0+aCgoZS50bV95ZWFyKzE5MDApLzEwMHwwLDIpLCIlZCI6ZT0+aChlLnRtX21kYXksMiksIiVlIjplPT5kKGUudG1fbWRheSwyLCIgIiksIiVnIjplPT5wKGUpLnRvU3RyaW5nKCkuc3Vic3RyaW5nKDIpLCIlRyI6ZT0+cChlKSwiJUgiOmU9PmgoZS50bV9ob3VyLDIpLCIlSSI6ZT0+e3ZhciByPWUudG1faG91cjtyZXR1cm4gMD09cj9yPTEyOnI+MTImJihyLT0xMiksaChyLDIpfSwiJWoiOmU9PmgoZS50bV9tZGF5KygoZSxyKT0+e2Zvcih2YXIgdD0wLG49MDtuPD1yO3QrPWVbbisrXSk7cmV0dXJuIHR9KShwZShlLnRtX3llYXIrMTkwMCk/RGU6TWUsZS50bV9tb24tMSksMyksIiVtIjplPT5oKGUudG1fbW9uKzEsMiksIiVNIjplPT5oKGUudG1fbWluLDIpLCIlbiI6KCk9PiJcbiIsIiVwIjplPT5lLnRtX2hvdXI+PTAmJmUudG1faG91cjwxMj8iQU0iOiJQTSIsIiVTIjplPT5oKGUudG1fc2VjLDIpLCIldCI6KCk9PiJcdCIsIiV1IjplPT5lLnRtX3dkYXl8fDcsIiVVIjplPT57dmFyIHI9ZS50bV95ZGF5KzctZS50bV93ZGF5O3JldHVybiBoKE1hdGguZmxvb3Ioci83KSwyKX0sIiVWIjplPT57dmFyIHI9TWF0aC5mbG9vcigoZS50bV95ZGF5KzctKGUudG1fd2RheSs2KSU3KS83KTtpZigoZS50bV93ZGF5KzM3MS1lLnRtX3lkYXktMiklNzw9MiYmcisrLHIpe2lmKDUzPT1yKXt2YXIgdD0oZS50bV93ZGF5KzM3MS1lLnRtX3lkYXkpJTc7ND09dHx8Mz09dCYmcGUoZS50bV95ZWFyKXx8KHI9MSl9fWVsc2V7cj01Mjt2YXIgbj0oZS50bV93ZGF5KzctZS50bV95ZGF5LTEpJTc7KDQ9PW58fDU9PW4mJnBlKGUudG1feWVhciU0MDAtMSkpJiZyKyt9cmV0dXJuIGgociwyKX0sIiV3IjplPT5lLnRtX3dkYXksIiVXIjplPT57dmFyIHI9ZS50bV95ZGF5KzctKGUudG1fd2RheSs2KSU3O3JldHVybiBoKE1hdGguZmxvb3Ioci83KSwyKX0sIiV5IjplPT4oZS50bV95ZWFyKzE5MDApLnRvU3RyaW5nKCkuc3Vic3RyaW5nKDIpLCIlWSI6ZT0+ZS50bV95ZWFyKzE5MDAsIiV6IjplPT57dmFyIHI9ZS50bV9nbXRvZmYsdD1yPj0wO3JldHVybiByPShyPU1hdGguYWJzKHIpLzYwKS82MCoxMDArciU2MCwodD8iKyI6Ii0iKStTdHJpbmcoIjAwMDAiK3IpLnNsaWNlKC00KX0sIiVaIjplPT5lLnRtX3pvbmUsIiUlIjooKT0+IiUifTtmb3IodmFyIHUgaW4gcz1zLnJlcGxhY2UoLyUlL2csIlwwXDAiKSx2KXMuaW5jbHVkZXModSkmJihzPXMucmVwbGFjZShuZXcgUmVnRXhwKHUsImciKSx2W3VdKGEpKSk7dmFyIHc9bmUocz1zLnJlcGxhY2UoL1wwXDAvZywiJSIpLCExKTtyZXR1cm4gdy5sZW5ndGg+cj8wOihBZSh3LGUpLHcubGVuZ3RoLTEpfX0sTGU9ZnVuY3Rpb24oKXt2YXIgZSxyLG8sYSxzPXthOlVlfTtmdW5jdGlvbiBpKGUscil7dmFyIHQ7cmV0dXJuIExlPWUuZXhwb3J0cyxnPUxlLkMsQygpLHQ9TGUuRCxULnVuc2hpZnQodCkseCgpLExlfWlmKEwoKSxuLmluc3RhbnRpYXRlV2FzbSl0cnl7cmV0dXJuIG4uaW5zdGFudGlhdGVXYXNtKHMsaSl9Y2F0Y2goZSl7eShgTW9kdWxlLmluc3RhbnRpYXRlV2FzbSBjYWxsYmFjayBmYWlsZWQgd2l0aCBlcnJvcjogJHtlfWApLHQoZSl9cmV0dXJuKGU9dyxyPU4sbz1zLGE9ZnVuY3Rpb24oZSl7aShlLmluc3RhbmNlKX0sZXx8ImZ1bmN0aW9uIiE9dHlwZW9mIFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlU3RyZWFtaW5nfHxIKHIpfHxZKHIpfHxofHwiZnVuY3Rpb24iIT10eXBlb2YgZmV0Y2g/SyhyLG8sYSk6ZmV0Y2gocix7Y3JlZGVudGlhbHM6InNhbWUtb3JpZ2luIn0pLnRoZW4oKGU9PldlYkFzc2VtYmx5Lmluc3RhbnRpYXRlU3RyZWFtaW5nKGUsbykudGhlbihhLChmdW5jdGlvbihlKXtyZXR1cm4geShgd2FzbSBzdHJlYW1pbmcgY29tcGlsZSBmYWlsZWQ6ICR7ZX1gKSx5KCJmYWxsaW5nIGJhY2sgdG8gQXJyYXlCdWZmZXIgaW5zdGFudGlhdGlvbiIpLEsocixvLGEpfSkpKSkpLmNhdGNoKHQpLHt9fSgpO24uX2dldF92ZXJzaW9uPSgpPT4obi5fZ2V0X3ZlcnNpb249TGUuRSkoKSxuLl9hcmNoaXZlX29wZW49KGUscix0LG8pPT4obi5fYXJjaGl2ZV9vcGVuPUxlLkYpKGUscix0LG8pLG4uX2FyY2hpdmVfcmVhZF9hZGRfcGFzc3BocmFzZT0oZSxyKT0+KG4uX2FyY2hpdmVfcmVhZF9hZGRfcGFzc3BocmFzZT1MZS5HKShlLHIpLG4uX2FyY2hpdmVfZXJyb3Jfc3RyaW5nPWU9PihuLl9hcmNoaXZlX2Vycm9yX3N0cmluZz1MZS5IKShlKSxuLl9nZXRfbmV4dF9lbnRyeT1lPT4obi5fZ2V0X25leHRfZW50cnk9TGUuSSkoZSksbi5fZ2V0X2ZpbGVkYXRhPShlLHIpPT4obi5fZ2V0X2ZpbGVkYXRhPUxlLkopKGUscik7dmFyIHhlPW4uX21hbGxvYz1lPT4oeGU9bi5fbWFsbG9jPUxlLkspKGUpO24uX2FyY2hpdmVfY2xvc2U9ZT0+KG4uX2FyY2hpdmVfY2xvc2U9TGUuTCkoZSksbi5fc3RhcnRfYXJjaGl2ZV93cml0ZT0oZSxyLHQsbyxhLHMpPT4obi5fc3RhcnRfYXJjaGl2ZV93cml0ZT1MZS5NKShlLHIsdCxvLGEscyksbi5fd3JpdGVfYXJjaGl2ZV9maWxlPShlLHIsdCxvKT0+KG4uX3dyaXRlX2FyY2hpdmVfZmlsZT1MZS5OKShlLHIsdCxvKSxuLl9zaXplX29mX3NpemVfdD0oKT0+KG4uX3NpemVfb2Zfc2l6ZV90PUxlLk8pKCksbi5fZmluaXNoX2FyY2hpdmVfd3JpdGU9KGUscik9PihuLl9maW5pc2hfYXJjaGl2ZV93cml0ZT1MZS5QKShlLHIpLG4uX2ZyZWU9ZT0+KG4uX2ZyZWU9TGUuUSkoZSk7dmFyIE9lPSgpPT4oT2U9TGUuUikoKTtuLl9hcmNoaXZlX2VudHJ5X2JpcnRodGltZV9uc2VjPWU9PihuLl9hcmNoaXZlX2VudHJ5X2JpcnRodGltZV9uc2VjPUxlLlMpKGUpLG4uX2FyY2hpdmVfZW50cnlfZmlsZXR5cGU9ZT0+KG4uX2FyY2hpdmVfZW50cnlfZmlsZXR5cGU9TGUuVCkoZSksbi5fYXJjaGl2ZV9lbnRyeV9tdGltZV9uc2VjPWU9PihuLl9hcmNoaXZlX2VudHJ5X210aW1lX25zZWM9TGUuVSkoZSksbi5fYXJjaGl2ZV9lbnRyeV9wYXRobmFtZT1lPT4obi5fYXJjaGl2ZV9lbnRyeV9wYXRobmFtZT1MZS5WKShlKSxuLl9hcmNoaXZlX2VudHJ5X3BhdGhuYW1lX3V0Zjg9ZT0+KG4uX2FyY2hpdmVfZW50cnlfcGF0aG5hbWVfdXRmOD1MZS5XKShlKSxuLl9hcmNoaXZlX2VudHJ5X3NpemU9ZT0+KG4uX2FyY2hpdmVfZW50cnlfc2l6ZT1MZS5YKShlKSxuLl9hcmNoaXZlX2VudHJ5X2lzX2VuY3J5cHRlZD1lPT4obi5fYXJjaGl2ZV9lbnRyeV9pc19lbmNyeXB0ZWQ9TGUuWSkoZSksbi5fYXJjaGl2ZV9yZWFkX2hhc19lbmNyeXB0ZWRfZW50cmllcz1lPT4obi5fYXJjaGl2ZV9yZWFkX2hhc19lbmNyeXB0ZWRfZW50cmllcz1MZS5aKShlKSxuLl9hcmNoaXZlX3JlYWRfZGF0YV9za2lwPWU9PihuLl9hcmNoaXZlX3JlYWRfZGF0YV9za2lwPUxlLl8pKGUpO3ZhciBOZSxCZT1lPT4oQmU9TGUuYWEpKGUpLGplPSgpPT4oamU9TGUuYmEpKCksSWU9ZT0+KEllPUxlLmNhKShlKSxIZT1lPT4oSGU9TGUuZGEpKGUpO2Z1bmN0aW9uIFllKCl7ZnVuY3Rpb24gZSgpe05lfHwoTmU9ITAsbi5jYWxsZWRSdW49ITAsTXx8KG4ubm9GU0luaXR8fGxlLmluaXQuaW5pdGlhbGl6ZWR8fGxlLmluaXQoKSxsZS5pZ25vcmVQZXJtaXNzaW9ucz0hMSxmZS5yb290PWxlLm1vdW50KGZlLHt9LG51bGwpLCQoVCkscihuKSxuLm9uUnVudGltZUluaXRpYWxpemVkJiZuLm9uUnVudGltZUluaXRpYWxpemVkKCksZnVuY3Rpb24oKXtpZihuLnBvc3RSdW4pZm9yKCJmdW5jdGlvbiI9PXR5cGVvZiBuLnBvc3RSdW4mJihuLnBvc3RSdW49W24ucG9zdFJ1bl0pO24ucG9zdFJ1bi5sZW5ndGg7KWU9bi5wb3N0UnVuLnNoaWZ0KCksUi51bnNoaWZ0KGUpO3ZhciBlOyQoUil9KCkpKX16PjB8fChmdW5jdGlvbigpe2lmKG4ucHJlUnVuKWZvcigiZnVuY3Rpb24iPT10eXBlb2Ygbi5wcmVSdW4mJihuLnByZVJ1bj1bbi5wcmVSdW5dKTtuLnByZVJ1bi5sZW5ndGg7KWU9bi5wcmVSdW4uc2hpZnQoKSxQLnVuc2hpZnQoZSk7dmFyIGU7JChQKX0oKSx6PjB8fChuLnNldFN0YXR1cz8obi5zZXRTdGF0dXMoIlJ1bm5pbmcuLi4iKSxzZXRUaW1lb3V0KChmdW5jdGlvbigpe3NldFRpbWVvdXQoKGZ1bmN0aW9uKCl7bi5zZXRTdGF0dXMoIiIpfSksMSksZSgpfSksMSkpOmUoKSkpfWlmKG4uY3dyYXA9KGUscix0LG4pPT57dmFyIG89IXR8fHQuZXZlcnkoKGU9PiJudW1iZXIiPT09ZXx8ImJvb2xlYW4iPT09ZSkpO3JldHVybiJzdHJpbmciIT09ciYmbyYmIW4/Q2UoZSk6ZnVuY3Rpb24oKXtyZXR1cm4gUGUoZSxyLHQsYXJndW1lbnRzKX19LG4uYWxsb2NhdGU9KGUscik9Pnt2YXIgdDtyZXR1cm4gdD0xPT1yP0hlKGUubGVuZ3RoKTp4ZShlLmxlbmd0aCksZS5zdWJhcnJheXx8ZS5zbGljZXx8KGU9bmV3IFVpbnQ4QXJyYXkoZSkpLGsuc2V0KGUsdCksdH0sVT1mdW5jdGlvbiBlKCl7TmV8fFllKCksTmV8fChVPWUpfSxuLnByZUluaXQpZm9yKCJmdW5jdGlvbiI9PXR5cGVvZiBuLnByZUluaXQmJihuLnByZUluaXQ9W24ucHJlSW5pdF0pO24ucHJlSW5pdC5sZW5ndGg+MDspbi5wcmVJbml0LnBvcCgpKCk7cmV0dXJuIFllKCksZS5yZWFkeX0pO2NsYXNzIFN7Y29uc3RydWN0b3IoKXt0aGlzLnByZVJ1bj1bXSx0aGlzLnBvc3RSdW49W10sdGhpcy50b3RhbERlcGVuZGVuY2llcz0wfXByaW50KC4uLmUpe2NvbnNvbGUubG9nKGUpfXByaW50RXJyKC4uLmUpe2NvbnNvbGUuZXJyb3IoZSl9aW5pdEZ1bmN0aW9ucygpe3RoaXMucnVuQ29kZT17Z2V0VmVyc2lvbjp0aGlzLmN3cmFwKCJnZXRfdmVyc2lvbiIsInN0cmluZyIsW10pLG9wZW5BcmNoaXZlOnRoaXMuY3dyYXAoImFyY2hpdmVfb3BlbiIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiLCJzdHJpbmciLCJzdHJpbmciXSksZ2V0TmV4dEVudHJ5OnRoaXMuY3dyYXAoImdldF9uZXh0X2VudHJ5IiwibnVtYmVyIixbIm51bWJlciJdKSxnZXRGaWxlRGF0YTp0aGlzLmN3cmFwKCJnZXRfZmlsZWRhdGEiLCJudW1iZXIiLFsibnVtYmVyIiwibnVtYmVyIl0pLHNraXBFbnRyeTp0aGlzLmN3cmFwKCJhcmNoaXZlX3JlYWRfZGF0YV9za2lwIiwibnVtYmVyIixbIm51bWJlciJdKSxjbG9zZUFyY2hpdmU6dGhpcy5jd3JhcCgiYXJjaGl2ZV9jbG9zZSIsbnVsbCxbIm51bWJlciJdKSxnZXRFbnRyeVNpemU6dGhpcy5jd3JhcCgiYXJjaGl2ZV9lbnRyeV9zaXplIiwibnVtYmVyIixbIm51bWJlciJdKSxnZXRFbnRyeU5hbWU6dGhpcy5jd3JhcCgiYXJjaGl2ZV9lbnRyeV9wYXRobmFtZSIsInN0cmluZyIsWyJudW1iZXIiXSksZ2V0RW50cnlUeXBlOnRoaXMuY3dyYXAoImFyY2hpdmVfZW50cnlfZmlsZXR5cGUiLCJudW1iZXIiLFsibnVtYmVyIl0pLGdldEVudHJ5TGFzdE1vZGlmaWVkOnRoaXMuY3dyYXAoImFyY2hpdmVfZW50cnlfbXRpbWVfbnNlYyIsIm51bWJlciIsWyJudW1iZXIiXSksZ2V0RXJyb3I6dGhpcy5jd3JhcCgiYXJjaGl2ZV9lcnJvcl9zdHJpbmciLCJzdHJpbmciLFsibnVtYmVyIl0pLHN0YXJ0QXJjaGl2ZVdyaXRlOnRoaXMuY3dyYXAoInN0YXJ0X2FyY2hpdmVfd3JpdGUiLCJudW1iZXIiLFsic3RyaW5nIiwic3RyaW5nIiwibnVtYmVyIiwibnVtYmVyIiwibnVtYmVyIiwic3RyaW5nIl0pLHdyaXRlQXJjaGl2ZUZpbGU6dGhpcy5jd3JhcCgid3JpdGVfYXJjaGl2ZV9maWxlIixudWxsLFsibnVtYmVyIiwic3RyaW5nIiwibnVtYmVyIiwibnVtYmVyIl0pLGZpbmlzaEFyY2hpdmVXcml0ZTp0aGlzLmN3cmFwKCJmaW5pc2hfYXJjaGl2ZV93cml0ZSIsIm51bWJlciIsWyJudW1iZXIiLCJudW1iZXIiXSksZW50cnlJc0VuY3J5cHRlZDp0aGlzLmN3cmFwKCJhcmNoaXZlX2VudHJ5X2lzX2VuY3J5cHRlZCIsIm51bWJlciIsWyJudW1iZXIiXSksaGFzRW5jcnlwdGVkRW50cmllczp0aGlzLmN3cmFwKCJhcmNoaXZlX3JlYWRfaGFzX2VuY3J5cHRlZF9lbnRyaWVzIiwibnVtYmVyIixbIm51bWJlciJdKSxhZGRQYXNzcGhyYXNlOnRoaXMuY3dyYXAoImFyY2hpdmVfcmVhZF9hZGRfcGFzc3BocmFzZSIsIm51bWJlciIsWyJudW1iZXIiLCJzdHJpbmciXSksc3RyaW5nOmU9PnRoaXMuYWxsb2NhdGUodGhpcy5pbnRBcnJheUZyb21TdHJpbmcoZSksImk4IiwwKSxtYWxsb2M6dGhpcy5jd3JhcCgibWFsbG9jIiwibnVtYmVyIixbIm51bWJlciJdKSxmcmVlOnRoaXMuY3dyYXAoImZyZWUiLG51bGwsWyJudW1iZXIiXSksc2l6ZU9mU2l6ZVQ6dGhpcy5jd3JhcCgic2l6ZV9vZl9zaXplX3QiLCJudW1iZXIiLFtdKX19bW9uaXRvclJ1bkRlcGVuZGVuY2llcygpe319bGV0IEY9bnVsbCxEPW51bGwsTT0hMTtjbGFzcyBBe2NvbnN0cnVjdG9yKGUpe0EucmVhZHlDYWxsYmFjaz1lLE0mJnNldFRpbWVvdXQoKCgpPT5lKCkpLDApfW9wZW4oZSxyKXtGLm9wZW4oZSkudGhlbigoKCk9PnIoKSkpfWxpc3RGaWxlcygpe2xldCBlPVtdO2Zvcihjb25zdCByIG9mIEYuZW50cmllcyghMCkpZS5wdXNoKHIpO3JldHVybiBlfWV4dHJhY3RGaWxlcygpe2xldCBlPVtdO2Zvcihjb25zdCByIG9mIEYuZW50cmllcyghMSkpZS5wdXNoKHIpO3JldHVybiBlfWV4dHJhY3RTaW5nbGVGaWxlKGUpe2Zvcihjb25zdCByIG9mIEYuZW50cmllcyghMCxlKSlpZihyLmZpbGVEYXRhKXJldHVybiByfWhhc0VuY3J5cHRlZERhdGEoKXtyZXR1cm4gRi5oYXNFbmNyeXB0ZWREYXRhKCl9dXNlUGFzc3dvcmQoZSl7Ri5zZXRQYXNzcGhyYXNlKGUpfXNldExvY2FsZShlKXtGLnNldExvY2FsZShlKX13cml0ZUFyY2hpdmUoZSxyLHQsbil7cmV0dXJuIEQud3JpdGUoZSxyLHQsbil9Y2xvc2UoKXtGLmNsb3NlKCl9fXZhciBDO0M9ZT0+e0Y9bmV3IHkoZSksRD1uZXcgRShlKSxBPy5yZWFkeUNhbGxiYWNrPy4oKSxNPSEwfSxrKG5ldyBTKS50aGVuKChlPT57ZS5pbml0RnVuY3Rpb25zKCksQyhlKX0pKSxpKEEpOwo=", "" + import.meta.url), { type: "module" });
347
+ }
348
+ static async getClient(e, t) {
349
+ let n = t.createClient?.call(t, e) || F(e), { promise: r, resolve: i } = Promise.withResolvers(), a = await new n(U((() => {
350
+ i();
351
+ })));
352
+ return await r, a;
353
+ }
354
+ };
355
+ Z._options = {}, Promise.withResolvers || (Promise.withResolvers = function() {
356
+ var e, t, n = new this((function(n, r) {
357
+ e = n, t = r;
358
+ }));
359
+ return {
360
+ resolve: e,
361
+ reject: t,
362
+ promise: n
363
+ };
364
+ });
365
+ // src/components/file-viewer/renderers/ArchiveRenderer.vue?vue&type=script&setup=true&lang.ts
366
+ var oe = { class: "fv-archive-head" }, se = { class: "fv-archive-title" }, ce = { class: "fv-archive-count" }, le = {
367
+ key: 0,
368
+ class: "fv-archive-state"
369
+ }, ue = {
370
+ key: 1,
371
+ class: "fv-archive-state fv-archive-locked"
372
+ }, de = ["disabled"], fe = {
373
+ key: 0,
374
+ class: "fv-archive-hint"
375
+ }, pe = {
376
+ key: 2,
377
+ class: "fv-archive-state fv-archive-error"
378
+ }, Q = {
379
+ key: 0,
380
+ class: "fv-archive-hint"
381
+ }, me = {
382
+ key: 1,
383
+ class: "fv-archive-hint"
384
+ }, he = { class: "fv-archive-list" }, ge = ["title", "onClick"], _e = { class: "fv-archive-name" }, ve = { class: "fv-archive-size" }, ye = { class: "fv-archive-kind" }, $ = 500, be = /*#__PURE__*/ a(/* @__PURE__ */ p({
385
+ __name: "ArchiveRenderer",
386
+ props: {
387
+ source: {},
388
+ options: {},
389
+ viewportWidth: {},
390
+ viewportHeight: {}
391
+ },
392
+ emits: [
393
+ "ready",
394
+ "error",
395
+ "open-entry"
396
+ ],
397
+ setup(e, { emit: a }) {
398
+ let p = e, E = a, D = _("loading"), O = _(""), k = _([]), A = _(""), j = _(!1), M = _(""), N = _(!1), P = null, F = !1, I = s(() => ({ width: `${Math.min(760, Math.max(320, (p.viewportWidth ?? 800) - 96))}px` }));
399
+ async function L(e) {
400
+ let n = await e.getFilesArray(), r = [];
401
+ for (let e of n) {
402
+ let n = e.file;
403
+ if (!n || typeof n.extract != "function") continue;
404
+ let i = String(e.path || ""), a = String(n.name || i);
405
+ r.push({
406
+ name: a,
407
+ path: i + a,
408
+ size: Number(n.size) || 0,
409
+ kind: t(a),
410
+ extract: () => n.extract()
411
+ });
412
+ }
413
+ k.value = r.slice(0, $), N.value = r.length > $, D.value = "list";
414
+ }
415
+ async function R() {
416
+ let e = p.source;
417
+ try {
418
+ Z.init({ workerUrl: "/libarchive/worker-bundle.js" });
419
+ let t = await e.getBlob();
420
+ if (F) return;
421
+ let n = e.name || "archive.zip";
422
+ if (P = await Z.open(new globalThis.File([t], n, { type: t.type || "application/octet-stream" })), F) return;
423
+ if (await P.hasEncryptedData()) {
424
+ D.value = "locked";
425
+ return;
426
+ }
427
+ await L(P), F || E("ready");
428
+ } catch (e) {
429
+ if (F) return;
430
+ D.value = "error", O.value = e instanceof Error ? e.message : "压缩包解析失败", E("error", O.value);
431
+ }
432
+ }
433
+ async function z() {
434
+ if (P && A.value && !j.value) {
435
+ j.value = !0;
436
+ try {
437
+ await P.usePassword(A.value), P = await P.open(), await L(P);
438
+ } catch {
439
+ O.value = "密码错误或压缩包已损坏", D.value = "locked";
440
+ } finally {
441
+ j.value = !1;
442
+ }
443
+ }
444
+ }
445
+ async function B(e) {
446
+ if (!j.value) {
447
+ j.value = !0, M.value = e.path;
448
+ try {
449
+ let t = await e.extract();
450
+ E("open-entry", {
451
+ file: t,
452
+ path: e.path
453
+ });
454
+ } catch {
455
+ O.value = `无法解压 ${e.name},文件可能已加密`;
456
+ } finally {
457
+ j.value = !1, M.value = "";
458
+ }
459
+ }
460
+ }
461
+ return te(R), h(() => {
462
+ F = !0, P?.close().catch(() => void 0), P = null;
463
+ }), (t, a) => (g(), u("div", {
464
+ class: "fv-archive",
465
+ style: m(I.value)
466
+ }, [d("div", oe, [
467
+ f(b(w), { size: 16 }),
468
+ d("span", se, y(e.source.name), 1),
469
+ d("span", ce, y(k.value.length) + y(N.value ? "+" : "") + " 个文件", 1)
470
+ ]), D.value === "loading" ? (g(), u("div", le, [f(b(n), {
471
+ size: 18,
472
+ class: "fv-spin"
473
+ }), a[1] ||= d("span", null, "正在解析压缩包…", -1)])) : D.value === "locked" ? (g(), u("div", ue, [
474
+ f(b(T), { size: 18 }),
475
+ a[2] ||= d("span", null, "该压缩包已加密,请输入密码", -1),
476
+ d("form", {
477
+ class: "fv-archive-password",
478
+ onSubmit: S(z, ["prevent"])
479
+ }, [x(d("input", {
480
+ "onUpdate:modelValue": a[0] ||= (e) => A.value = e,
481
+ type: "password",
482
+ placeholder: "压缩包密码",
483
+ autocomplete: "off"
484
+ }, null, 512), [[ne, A.value]]), d("button", {
485
+ type: "submit",
486
+ disabled: j.value || !A.value
487
+ }, y(j.value ? "验证中…" : "解锁"), 9, de)], 32),
488
+ O.value ? (g(), u("p", fe, y(O.value), 1)) : l("", !0)
489
+ ])) : D.value === "error" ? (g(), u("div", pe, [d("span", null, y(O.value), 1)])) : (g(), u(o, { key: 3 }, [
490
+ N.value ? (g(), u("p", Q, "文件过多,仅展示前 " + y($) + " 项")) : l("", !0),
491
+ O.value ? (g(), u("p", me, y(O.value), 1)) : l("", !0),
492
+ d("ul", he, [(g(!0), u(o, null, v(k.value, (e) => (g(), u("li", { key: e.path }, [d("button", {
493
+ type: "button",
494
+ class: ee(["fv-archive-item", { active: e.path === M.value }]),
495
+ title: e.path,
496
+ onClick: (t) => B(e)
497
+ }, [
498
+ f(b(C), {
499
+ size: 15,
500
+ class: "fv-archive-icon"
501
+ }),
502
+ d("span", _e, y(e.path), 1),
503
+ d("span", ve, y(b(i)(e.size)), 1),
504
+ d("span", ye, y(b(r)[e.kind]), 1),
505
+ e.path === M.value ? (g(), c(b(n), {
506
+ key: 0,
507
+ size: 14,
508
+ class: "fv-spin"
509
+ })) : l("", !0)
510
+ ], 10, ge)]))), 128))])
511
+ ], 64))], 4));
512
+ }
513
+ }), [["__scopeId", "data-v-152bf0bd"]]);
514
+ export { be as default };