ember-scoped-css 2.0.3 → 2.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.
@@ -1,1308 +0,0 @@
1
- //#region rolldown:runtime
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
- key = keys[i];
11
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
- get: ((k) => from[k]).bind(null, key),
13
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
- });
15
- }
16
- return to;
17
- };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
- value: mod,
20
- enumerable: true
21
- }) : target, mod));
22
-
23
- //#endregion
24
- let node_assert = require("node:assert");
25
- node_assert = __toESM(node_assert);
26
- let node_fs = require("node:fs");
27
- node_fs = __toESM(node_fs);
28
- let node_module = require("node:module");
29
- node_module = __toESM(node_module);
30
- let node_path = require("node:path");
31
- node_path = __toESM(node_path);
32
- let path = require("path");
33
- path = __toESM(path);
34
- let unplugin = require("unplugin");
35
- unplugin = __toESM(unplugin);
36
- let postcss = require("postcss");
37
- postcss = __toESM(postcss);
38
- let postcss_selector_parser = require("postcss-selector-parser");
39
- postcss_selector_parser = __toESM(postcss_selector_parser);
40
- let fs = require("fs");
41
- fs = __toESM(fs);
42
- let node_process = require("node:process");
43
- node_process = __toESM(node_process);
44
- let ember_template_recast = require("ember-template-recast");
45
- ember_template_recast = __toESM(ember_template_recast);
46
-
47
- //#region src/lib/path/const.js
48
- /**
49
- * Join will convert to whatever is appropriate fro the current platform
50
- */
51
- const leadingSlashPath = {
52
- embroiderDir: path.default.join("/node_modules/.embroider/"),
53
- atEmbroider: path.default.join("/@embroider"),
54
- componentsDir: path.default.join("/components/"),
55
- templatesDir: path.default.join("/templates/"),
56
- testem: path.default.join("/testem"),
57
- src: path.default.join("/src/"),
58
- app: path.default.join("/app/")
59
- };
60
- const barePath = { pnpmDir: path.default.join("node_modules/.pnpm") };
61
-
62
- //#endregion
63
- //#region src/lib/path/md5.js
64
- /**
65
- * Add integers, wrapping at 2^32.
66
- * This uses 16-bit operations internally to work around bugs in interpreters.
67
- *
68
- * @param {number} x First integer
69
- * @param {number} y Second integer
70
- * @returns {number} Sum
71
- */
72
- function safeAdd(x, y) {
73
- var lsw = (x & 65535) + (y & 65535);
74
- return (x >> 16) + (y >> 16) + (lsw >> 16) << 16 | lsw & 65535;
75
- }
76
- /**
77
- * Bitwise rotate a 32-bit number to the left.
78
- *
79
- * @param {number} num 32-bit number
80
- * @param {number} cnt Rotation count
81
- * @returns {number} Rotated number
82
- */
83
- function bitRotateLeft(num, cnt) {
84
- return num << cnt | num >>> 32 - cnt;
85
- }
86
- /**
87
- * Basic operation the algorithm uses.
88
- *
89
- * @param {number} q q
90
- * @param {number} a a
91
- * @param {number} b b
92
- * @param {number} x x
93
- * @param {number} s s
94
- * @param {number} t t
95
- * @returns {number} Result
96
- */
97
- function md5cmn(q, a, b, x, s, t) {
98
- return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
99
- }
100
- /**
101
- * Basic operation the algorithm uses.
102
- *
103
- * @param {number} a a
104
- * @param {number} b b
105
- * @param {number} c c
106
- * @param {number} d d
107
- * @param {number} x x
108
- * @param {number} s s
109
- * @param {number} t t
110
- * @returns {number} Result
111
- */
112
- function md5ff(a, b, c, d, x, s, t) {
113
- return md5cmn(b & c | ~b & d, a, b, x, s, t);
114
- }
115
- /**
116
- * Basic operation the algorithm uses.
117
- *
118
- * @param {number} a a
119
- * @param {number} b b
120
- * @param {number} c c
121
- * @param {number} d d
122
- * @param {number} x x
123
- * @param {number} s s
124
- * @param {number} t t
125
- * @returns {number} Result
126
- */
127
- function md5gg(a, b, c, d, x, s, t) {
128
- return md5cmn(b & d | c & ~d, a, b, x, s, t);
129
- }
130
- /**
131
- * Basic operation the algorithm uses.
132
- *
133
- * @param {number} a a
134
- * @param {number} b b
135
- * @param {number} c c
136
- * @param {number} d d
137
- * @param {number} x x
138
- * @param {number} s s
139
- * @param {number} t t
140
- * @returns {number} Result
141
- */
142
- function md5hh(a, b, c, d, x, s, t) {
143
- return md5cmn(b ^ c ^ d, a, b, x, s, t);
144
- }
145
- /**
146
- * Basic operation the algorithm uses.
147
- *
148
- * @param {number} a a
149
- * @param {number} b b
150
- * @param {number} c c
151
- * @param {number} d d
152
- * @param {number} x x
153
- * @param {number} s s
154
- * @param {number} t t
155
- * @returns {number} Result
156
- */
157
- function md5ii(a, b, c, d, x, s, t) {
158
- return md5cmn(c ^ (b | ~d), a, b, x, s, t);
159
- }
160
- /**
161
- * Calculate the MD5 of an array of little-endian words, and a bit length.
162
- *
163
- * @param {Array} x Array of little-endian words
164
- * @param {number} len Bit length
165
- * @returns {Array<number>} MD5 Array
166
- */
167
- function binlMD5(x, len) {
168
- x[len >> 5] |= 128 << len % 32;
169
- x[(len + 64 >>> 9 << 4) + 14] = len;
170
- var i;
171
- var olda;
172
- var oldb;
173
- var oldc;
174
- var oldd;
175
- var a = 1732584193;
176
- var b = -271733879;
177
- var c = -1732584194;
178
- var d = 271733878;
179
- for (i = 0; i < x.length; i += 16) {
180
- olda = a;
181
- oldb = b;
182
- oldc = c;
183
- oldd = d;
184
- a = md5ff(a, b, c, d, x[i], 7, -680876936);
185
- d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
186
- c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
187
- b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
188
- a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
189
- d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
190
- c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
191
- b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
192
- a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
193
- d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
194
- c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
195
- b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
196
- a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
197
- d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
198
- c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
199
- b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
200
- a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
201
- d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
202
- c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
203
- b = md5gg(b, c, d, a, x[i], 20, -373897302);
204
- a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
205
- d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
206
- c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
207
- b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
208
- a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
209
- d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
210
- c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
211
- b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
212
- a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
213
- d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
214
- c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
215
- b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
216
- a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
217
- d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
218
- c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
219
- b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
220
- a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
221
- d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
222
- c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
223
- b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
224
- a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
225
- d = md5hh(d, a, b, c, x[i], 11, -358537222);
226
- c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
227
- b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
228
- a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
229
- d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
230
- c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
231
- b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
232
- a = md5ii(a, b, c, d, x[i], 6, -198630844);
233
- d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
234
- c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
235
- b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
236
- a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
237
- d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
238
- c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
239
- b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
240
- a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
241
- d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
242
- c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
243
- b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
244
- a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
245
- d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
246
- c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
247
- b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
248
- a = safeAdd(a, olda);
249
- b = safeAdd(b, oldb);
250
- c = safeAdd(c, oldc);
251
- d = safeAdd(d, oldd);
252
- }
253
- return [
254
- a,
255
- b,
256
- c,
257
- d
258
- ];
259
- }
260
- /**
261
- * Convert an array of little-endian words to a string
262
- *
263
- * @param {Array<number>} input MD5 Array
264
- * @returns {string} MD5 string
265
- */
266
- function binl2rstr(input) {
267
- var i;
268
- var output = "";
269
- var length32 = input.length * 32;
270
- for (i = 0; i < length32; i += 8) output += String.fromCharCode(input[i >> 5] >>> i % 32 & 255);
271
- return output;
272
- }
273
- /**
274
- * Convert a raw string to an array of little-endian words
275
- * Characters >255 have their high-byte silently ignored.
276
- *
277
- * @param {string} input Raw input string
278
- * @returns {Array<number>} Array of little-endian words
279
- */
280
- function rstr2binl(input) {
281
- var i;
282
- var output = [];
283
- output[(input.length >> 2) - 1] = void 0;
284
- for (i = 0; i < output.length; i += 1) output[i] = 0;
285
- var length8 = input.length * 8;
286
- for (i = 0; i < length8; i += 8) output[i >> 5] |= (input.charCodeAt(i / 8) & 255) << i % 32;
287
- return output;
288
- }
289
- /**
290
- * Calculate the MD5 of a raw string
291
- *
292
- * @param {string} s Input string
293
- * @returns {string} Raw MD5 string
294
- */
295
- function rstrMD5(s) {
296
- return binl2rstr(binlMD5(rstr2binl(s), s.length * 8));
297
- }
298
- /**
299
- * Calculates the HMAC-MD5 of a key and some data (raw strings)
300
- *
301
- * @param {string} key HMAC key
302
- * @param {string} data Raw input string
303
- * @returns {string} Raw MD5 string
304
- */
305
- function rstrHMACMD5(key, data) {
306
- var i;
307
- var bkey = rstr2binl(key);
308
- var ipad = [];
309
- var opad = [];
310
- var hash$2;
311
- ipad[15] = opad[15] = void 0;
312
- if (bkey.length > 16) bkey = binlMD5(bkey, key.length * 8);
313
- for (i = 0; i < 16; i += 1) {
314
- ipad[i] = bkey[i] ^ 909522486;
315
- opad[i] = bkey[i] ^ 1549556828;
316
- }
317
- hash$2 = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
318
- return binl2rstr(binlMD5(opad.concat(hash$2), 640));
319
- }
320
- /**
321
- * Convert a raw string to a hex string
322
- *
323
- * @param {string} input Raw input string
324
- * @returns {string} Hex encoded string
325
- */
326
- function rstr2hex(input) {
327
- var hexTab = "0123456789abcdef";
328
- var output = "";
329
- var x;
330
- var i;
331
- for (i = 0; i < input.length; i += 1) {
332
- x = input.charCodeAt(i);
333
- output += hexTab.charAt(x >>> 4 & 15) + hexTab.charAt(x & 15);
334
- }
335
- return output;
336
- }
337
- /**
338
- * Encode a string as UTF-8
339
- *
340
- * @param {string} input Input string
341
- * @returns {string} UTF8 string
342
- */
343
- function str2rstrUTF8(input) {
344
- return unescape(encodeURIComponent(input));
345
- }
346
- /**
347
- * Encodes input string as raw MD5 string
348
- *
349
- * @param {string} s Input string
350
- * @returns {string} Raw MD5 string
351
- */
352
- function rawMD5(s) {
353
- return rstrMD5(str2rstrUTF8(s));
354
- }
355
- /**
356
- * Encodes input string as Hex encoded string
357
- *
358
- * @param {string} s Input string
359
- * @returns {string} Hex encoded string
360
- */
361
- function hexMD5(s) {
362
- return rstr2hex(rawMD5(s));
363
- }
364
- /**
365
- * Calculates the raw HMAC-MD5 for the given key and data
366
- *
367
- * @param {string} k HMAC key
368
- * @param {string} d Input string
369
- * @returns {string} Raw MD5 string
370
- */
371
- function rawHMACMD5(k, d) {
372
- return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d));
373
- }
374
- /**
375
- * Calculates the Hex encoded HMAC-MD5 for the given key and data
376
- *
377
- * @param {string} k HMAC key
378
- * @param {string} d Input string
379
- * @returns {string} Raw MD5 string
380
- */
381
- function hexHMACMD5(k, d) {
382
- return rstr2hex(rawHMACMD5(k, d));
383
- }
384
- /**
385
- * Calculates MD5 value for a given string.
386
- * If a key is provided, calculates the HMAC-MD5 value.
387
- * Returns a Hex encoded string unless the raw argument is given.
388
- *
389
- * @param {string} string Input string
390
- * @param {string} [key] HMAC key
391
- * @param {boolean} [raw] Raw output switch
392
- * @returns {string} MD5 output
393
- */
394
- function md5(string, key, raw) {
395
- if (!key) {
396
- if (!raw) return hexMD5(string);
397
- return rawMD5(string);
398
- }
399
- if (!raw) return hexHMACMD5(key, string);
400
- return rawHMACMD5(key, string);
401
- }
402
-
403
- //#endregion
404
- //#region src/lib/path/hash-from-module-path.js
405
- /**
406
- * The intent of this function is to generate the suffix/postfix for the
407
- * css classes, based on the module-scoped path name.
408
- *
409
- * for example,
410
- * hash('my-app/components/foo')
411
- * instead of
412
- * hash('app/components/foo')
413
- *
414
- * (unless your app name is 'app')
415
- *
416
- * @param {string} modulePath
417
- * @returns {string}
418
- */
419
- function hash$1(modulePath) {
420
- return "e" + md5(modulePath).substring(0, 8);
421
- }
422
- const hashFromModulePath$1 = hash$1;
423
-
424
- //#endregion
425
- //#region src/lib/path/utils.js
426
- /**
427
- *
428
- * @param {string} filePath
429
- * @returns {string}
430
- */
431
- function hashFromModulePath(filePath) {
432
- return hashFromModulePath$1(forcePosix(filePath));
433
- }
434
- /**
435
- * @param {string} filePath
436
- */
437
- function forcePosix(filePath) {
438
- const parsed = node_path.default.parse(filePath);
439
- if (parsed.root === "") return filePath.replaceAll(node_path.default.win32.sep, node_path.default.posix.sep);
440
- return filePath.replace(/* @__PURE__ */ new RegExp(`^${RegExp.escape(parsed.root)}`), node_path.default.posix.sep).replaceAll(node_path.default.win32.sep, node_path.default.posix.sep);
441
- }
442
- let here = require("url").pathToFileURL(__filename).href;
443
- let ourRequire = globalThis.require ? globalThis.require : here && (0, node_module.createRequire)(here);
444
- if (!ourRequire) ourRequire = require;
445
- const IRRELEVANT_PATHS = [barePath.pnpmDir, "__vite-"];
446
- const UNSUPPORTED_DIRECTORIES = new Set(["tests"]);
447
- const CWD = process.cwd();
448
- /**
449
- * Based on ember's component location conventions,
450
- * this function will provide a path for where we
451
- * expect the CSS to live.
452
- *
453
- * For co-located structure:
454
- * - components/my-component.hbs
455
- * - components/my-component.css
456
- *
457
- * For nested co-located structure
458
- * - components/my-component/foo.hbs
459
- * - components/my-component/foo.css
460
- *
461
- * For Pods routes structure
462
- * - routes/my-route/template.{hbs,js}
463
- * - routes/my-route/styles.css
464
- *
465
- * Deliberately not supported:
466
- * - components w/ pods -- this is deprecated in 5.10
467
- *
468
- * @param {string} fileName - the hbs, js, gjs, gts or whatever co-located path.
469
- * @returns {string} - expected css path
470
- */
471
- function cssPathFor(fileName) {
472
- let cssPath = withoutExtension(fileName) + ".css";
473
- if (isPod(fileName)) cssPath = fileName.replace(/template\.js$/, "styles.css").replace(/template\.gjs/, "styles.css").replace(/template\.gts/, "styles.css").replace(/template\.hbs/, "styles.css");
474
- return cssPath;
475
- }
476
- /**
477
- * Note that components in the "pods" convention will
478
- * never be supported.
479
- *
480
- * @param {string} filePath
481
- */
482
- function isPodTemplate(filePath) {
483
- if (filePath.includes(leadingSlashPath.componentsDir)) return false;
484
- return filePath.endsWith("template.js") || filePath.endsWith("template.hbs") || filePath.endsWith("template.gjs") || filePath.endsWith("template.gts");
485
- }
486
- /**
487
- * Note that components in the "pods" convention will
488
- * never be supported.
489
- *
490
- * Checks if a file ends with
491
- * - template.js
492
- * - template.hbs
493
- * - styles.css
494
- *
495
- * @param {string} filePath
496
- */
497
- function isPod(filePath) {
498
- if (filePath.includes(leadingSlashPath.componentsDir)) return false;
499
- if (isPodTemplate(filePath)) return true;
500
- return filePath.endsWith("styles.css");
501
- }
502
- /**
503
- *
504
- * @param {string} filePath
505
- * @returns the same path, but without the extension
506
- */
507
- function withoutExtension(filePath) {
508
- let parsed = node_path.default.parse(filePath);
509
- return node_path.default.join(parsed.dir, parsed.name);
510
- }
511
- /**
512
- * Examples for fileName
513
- * - absolute on-disk path
514
- * - in webpack
515
- * - URL-absolute path, starting with /
516
- *
517
- * @param {string} fileName
518
- * @param {{ additionalRoots?: string[]; cwd: string }} options
519
- * @returns
520
- */
521
- function isRelevantFile(fileName, { additionalRoots, cwd }) {
522
- if (fileName.startsWith(leadingSlashPath.testem)) return false;
523
- if (fileName.startsWith("\0")) return false;
524
- if (node_path.default.isAbsolute(fileName) === false) {
525
- if (fileName.match(/^[a-zA-Z]/)) return false;
526
- }
527
- if (fileName.startsWith(leadingSlashPath.atEmbroider)) return false;
528
- if (IRRELEVANT_PATHS.some((i) => fileName.includes(i))) return false;
529
- let workspace = findWorkspacePath(fileName);
530
- (0, node_assert.default)(cwd, `cwd was not passed to isRelevantFile`);
531
- if (workspace !== findWorkspacePath(cwd)) return false;
532
- let [, ...parts] = fileName.replace(workspace, "").split(node_path.default.sep).filter(Boolean);
533
- if (UNSUPPORTED_DIRECTORIES.has(parts[0])) return false;
534
- if (![
535
- leadingSlashPath.componentsDir,
536
- leadingSlashPath.templatesDir,
537
- ...additionalRoots || []
538
- ].some((root) => fileName.includes(root))) return;
539
- return true;
540
- }
541
- function packageScopedPathToModulePath(packageScopedPath) {
542
- /**
543
- * *By convention*, `src` is omitted from component paths.
544
- * We can reflect the same behavior by replacing src/
545
- * with an empty string.
546
- *
547
- * CSS isn't emitted as a co-located module, but
548
- * to keep conventions consistent across languages,
549
- * we can pretend it is.
550
- *
551
- * Any customization beyond removing `src` and `app` is potentially confusing.
552
- * If we need further customizations, we'll want to match on `exports` in the
553
- * corresponding package.json
554
- */
555
- let packageRelative = packageScopedPath.replace(/* @__PURE__ */ new RegExp(`^${RegExp.escape(leadingSlashPath.src)}`), node_path.default.sep);
556
- let parsed = node_path.default.parse(packageRelative);
557
- if (isPod(packageRelative))
558
- /**
559
- * For pods, we chop off the whole file, and use the dir name as the "modulePath"
560
- */
561
- return parsed.dir;
562
- return node_path.default.join(parsed.dir, parsed.name);
563
- }
564
- /**
565
- * returns the app-module path of the source file
566
- *
567
- * This assumes normal ember app conventions
568
- *
569
- * which is `<package.json#name>/path-to-file`
570
- */
571
- function appPath(sourcePath) {
572
- let workspacePath = findWorkspacePath(sourcePath);
573
- let name = moduleName(sourcePath);
574
- /**
575
- * Under embroider builds, the spec-compliant version of the app
576
- * has all the files under a folder which represents the package name,
577
- * rather than "app".
578
- */
579
- let packageRelative = sourcePath.replace(workspacePath, "");
580
- /**
581
- * But we also don't want 'app' -- which is present in the v1 addon pipeline
582
- */
583
- packageRelative = packageRelative.replace(leadingSlashPath.app, node_path.default.sep);
584
- packageRelative = node_path.default.normalize(packageRelative);
585
- return `${name}${packageScopedPathToModulePath(packageRelative)}`;
586
- }
587
- /**
588
- * To avoid hitting the filesysetm, we'll store all found
589
- * project paths bere, so we can, in memory,
590
- * get the folder where a package.json exists, rather than
591
- * hit the file system every time.
592
- */
593
- const SEEN = /* @__PURE__ */ new Set();
594
- function getSeen(sourcePath) {
595
- if (SEEN.has(sourcePath)) return sourcePath;
596
- let parts = sourcePath.split(node_path.default.sep);
597
- for (let i = parts.length - 1; i > 1; i--) {
598
- let toCheck = parts.slice(0, i).join(node_path.default.sep);
599
- if (SEEN.has(toCheck)) return toCheck;
600
- }
601
- }
602
- function findWorkspacePath(sourcePath, options) {
603
- let cwd = options?.cwd ?? CWD;
604
- if (sourcePath.endsWith(node_path.default.sep)) sourcePath = sourcePath.replace(/* @__PURE__ */ new RegExp(`${RegExp.escape(node_path.default.sep)}$`), "");
605
- let seen = getSeen(sourcePath);
606
- if (seen) return seen;
607
- let candidatePath = node_path.default.join(sourcePath, "package.json");
608
- if (node_fs.default.existsSync(candidatePath)) return sourcePath;
609
- const packageJsonPath = findPackageJsonUp(sourcePath, { cwd });
610
- if (!packageJsonPath) throw new Error(`Could not determine project for ${sourcePath}`);
611
- const workspacePath = node_path.default.dirname(packageJsonPath);
612
- SEEN.add(workspacePath);
613
- return workspacePath;
614
- }
615
- function findPackageJsonUp(startPath, options) {
616
- let cwd = options?.cwd ?? CWD;
617
- let parts = startPath.split(node_path.default.sep);
618
- for (let i = parts.length - 1; i > 1; i--) {
619
- let toCheck = parts.slice(0, i).join(node_path.default.sep);
620
- let packageJson = node_path.default.join(toCheck, "package.json");
621
- if (node_fs.default.existsSync(packageJson)) return packageJson;
622
- if (toCheck === cwd) break;
623
- }
624
- return null;
625
- }
626
- const MANIFEST_CACHE = /* @__PURE__ */ new Map();
627
- /**
628
- * Will return the package.json#name, or config/environment#moudlePrefix (if v1 app)
629
- *
630
- * @param {string} sourcePath
631
- */
632
- function moduleName(sourcePath) {
633
- return getManifest(findWorkspacePath(sourcePath)).name;
634
- }
635
- /**
636
- * @param {string} workspace
637
- */
638
- function getManifest(workspace) {
639
- let existing = MANIFEST_CACHE.get(workspace);
640
- if (existing) return existing;
641
- let content = node_fs.default.readFileSync(node_path.default.join(workspace, "package.json")).toString();
642
- let json = JSON.parse(content);
643
- MANIFEST_CACHE.set(workspace, json);
644
- return json;
645
- }
646
-
647
- //#endregion
648
- //#region src/build/babel-plugin.js
649
- function _isRelevantFile(state, cwd) {
650
- let fileName = state.file.opts.filename;
651
- let additionalRoots = state.opts?.additionalRoots;
652
- return isRelevantFile(fileName, {
653
- additionalRoots,
654
- cwd
655
- });
656
- }
657
- /**
658
- * @param {any} env - babel plugin env, env.types is most commonly used (esp in TS)
659
- * @param {object} options - the options for scoped-css -- this is also available in each visitor's state.opts
660
- * @param {string} workingDirectory
661
- */
662
- const scopedCSS$1 = (config) => (env, options, workingDirectory) => {
663
- options = {
664
- ...config,
665
- ...options
666
- };
667
- /**
668
- * This babel plugin does two things:
669
- * - removes the import of scopedClass, if it exists
670
- * - if scopedClass was imported, it is removed from any component's "scope bag"
671
- * (the scope bag being a low-level object used for passing what is "in scope" for a component)
672
- */
673
- return { visitor: {
674
- Program: { enter(path$8, state) {
675
- if (!_isRelevantFile(state, workingDirectory)) {
676
- state.canSkip = true;
677
- return;
678
- }
679
- } },
680
- ImportDeclaration(path$8, state) {
681
- if (state.canSkip) return;
682
- if (path$8.node.source.value === "ember-scoped-css") {
683
- let specifier = path$8.node.specifiers.find((x) => x.imported.name === "scopedClass");
684
- if (specifier) state.file.opts.importedScopedClass = specifier.local.name;
685
- if (specifier.local.name !== "scopedClass") throw new Error(`The scopedClass import is a psuedo-helper, and may not be renamed as it is removed at build time.`);
686
- path$8.remove();
687
- }
688
- },
689
- ObjectProperty(path$8, state) {
690
- if (!state.file.opts?.importedScopedClass) return;
691
- if (path$8.node.value.type === "Identifier" && path$8.node.value.name === state.file.opts?.importedScopedClass) path$8.remove();
692
- }
693
- } };
694
- };
695
-
696
- //#endregion
697
- //#region src/lib/css/utils.js
698
- /**
699
- * @param {string} css
700
- * @return {string} hashed down version of the CSS for disambiguating
701
- */
702
- function hash(css) {
703
- return `css-${md5(css)}`;
704
- }
705
- function isInsideGlobal(node, func) {
706
- const parent = node.parent;
707
- if (!parent) return false;
708
- if (parent.type === "pseudo" && parent.value === ":global") return true;
709
- return isInsideGlobal(parent, func);
710
- }
711
- /**
712
- * @param {string} cssPath path to a CSS file
713
- */
714
- function getCSSInfo(cssPath) {
715
- if (!(0, fs.existsSync)(cssPath)) return null;
716
- return getCSSContentInfo((0, fs.readFileSync)(cssPath, "utf8"));
717
- }
718
- /**
719
- * We use this function to check each class used in the template
720
- * to see if we need to leave it alone or transform it
721
- *
722
- * @param {string} css the CSS's contents
723
- * @return {{ classes: Set<string>, tags: Set<string>, css: string, id: string }}
724
- */
725
- function getCSSContentInfo(css) {
726
- const classes = /* @__PURE__ */ new Set();
727
- const tags = /* @__PURE__ */ new Set();
728
- postcss.default.parse(css).walk((node) => {
729
- if (node.type === "rule") getClassesAndTags(node.selector, classes, tags);
730
- });
731
- return {
732
- classes,
733
- tags,
734
- css,
735
- id: hash(css)
736
- };
737
- }
738
- function getClassesAndTags(sel, classes, tags) {
739
- const transform = (sls) => {
740
- sls.walk((selector) => {
741
- if (selector.type === "class" && !isInsideGlobal(selector)) classes.add(selector.value);
742
- else if (selector.type === "tag" && !isInsideGlobal(selector)) tags.add(selector.value);
743
- });
744
- };
745
- (0, postcss_selector_parser.default)(transform).processSync(sel);
746
- }
747
-
748
- //#endregion
749
- //#region src/lib/css/rewrite.js
750
- const SEP$1 = "__";
751
- function isRule(node) {
752
- return node.type === "rule";
753
- }
754
- function isDeclaration(node) {
755
- return node.type === "decl";
756
- }
757
- /**
758
- * NOTE: "keyframes" is a singular definition, in that it's a block containing keyframes
759
- * using `@keyframes {}` with only one thing on the inside doesn't make sense.
760
- */
761
- function rewriteReferencable(node, postfix) {
762
- let originalName = node.params;
763
- let postfixedName = node.params + SEP$1 + postfix;
764
- node.params = postfixedName;
765
- return {
766
- originalName,
767
- postfixedName
768
- };
769
- }
770
- function rewriteSelector(sel, postfix) {
771
- const transform = (selectors) => {
772
- selectors.walk((selector) => {
773
- if (isInsideGlobal(selector)) return;
774
- if (selector.type === "psuedo") return;
775
- if (isNthOfType(selector)) return;
776
- if (selector.type === "class") selector.value += "_" + postfix;
777
- else if (selector.type === "tag") selector.replaceWith(postcss_selector_parser.default.tag({ value: selector.value }), postcss_selector_parser.default.className({ value: postfix }));
778
- });
779
- selectors.walk((selector) => {
780
- if (selector.type === "pseudo" && selector.value === ":global") selector.replaceWith(...selector.nodes);
781
- });
782
- };
783
- return (0, postcss_selector_parser.default)(transform).processSync(sel);
784
- }
785
- function isNthOfType(node) {
786
- if (!node) return false;
787
- return node.parent?.value === ":nth-of-type" || isNthOfType(node.parent);
788
- }
789
- function isInsideKeyframes(node) {
790
- const parent = node.parent;
791
- if (!parent) return false;
792
- if (parent.type === "atrule" && parent.name === "keyframes") return true;
793
- return isInsideKeyframes(parent);
794
- }
795
- function rewriteCss(css, postfix, fileName, layerName) {
796
- const ast = postcss.default.parse(css);
797
- /**
798
- * kind => originalName => postfixedName
799
- * @type {{ [kind: string]: { [originalName: string]: string }}}
800
- */
801
- const referencables = {
802
- keyframes: {},
803
- "counter-style": {},
804
- "position-try": {},
805
- property: {}
806
- };
807
- const availableReferencables = new Set(Object.keys(referencables));
808
- function isReferencable(node) {
809
- if (node.type !== "atrule") return;
810
- return availableReferencables.has(node.name);
811
- }
812
- function updateDirectReferences(node) {
813
- if (!node.value) return;
814
- for (let [, map] of Object.entries(referencables)) if (map[node.value]) node.value = map[node.value];
815
- }
816
- function updateShorthandContents(node) {
817
- if (node.prop === "animation") {
818
- let match = node.value.split(" ").filter((x) => referencables.keyframes[x]);
819
- if (match.length) match.forEach((x) => {
820
- let replacement = referencables.keyframes[x];
821
- if (!replacement) return;
822
- node.value = node.value.replace(x, replacement);
823
- });
824
- }
825
- for (let [lookFor, replaceWith] of Object.entries(referencables.property)) {
826
- let lookForVar = `var(${lookFor})`;
827
- let replaceWithVar = `var(${replaceWith})`;
828
- node.value = node.value.replace(lookForVar, replaceWithVar);
829
- }
830
- }
831
- /**
832
- * We have to do two passes:
833
- * 1. postfix all the referencable syntax
834
- * 2. postfix as normal, but also checking values of CSS properties
835
- * that could match postfixed referencables from step 1
836
- */
837
- ast.walk((node) => {
838
- /**
839
- * @keyframes, @counter-style, etc
840
- */
841
- if (isReferencable(node)) {
842
- let name = node.name;
843
- let { originalName, postfixedName } = rewriteReferencable(node, postfix);
844
- referencables[name][originalName] = postfixedName;
845
- return;
846
- }
847
- });
848
- ast.walk((node) => {
849
- if (isDeclaration(node)) {
850
- updateDirectReferences(node);
851
- updateShorthandContents(node);
852
- return;
853
- }
854
- if (isRule(node)) {
855
- /**
856
- * The inner-contents of a keyframe are percentages, rather than selectors
857
- */
858
- if (isInsideKeyframes(node)) return;
859
- node.selector = rewriteSelector(node.selector, postfix);
860
- return;
861
- }
862
- });
863
- const rewrittenCss = ast.toString();
864
- return [
865
- `/* ${fileName} */`,
866
- layerName ? `@layer ${layerName} {` : "",
867
- rewrittenCss.trimEnd(),
868
- layerName ? `}` : ""
869
- ].filter(Boolean).join("\n") + "\n";
870
- }
871
-
872
- //#endregion
873
- //#region src/lib/request.js
874
- const KEY = "ember-scoped.css";
875
- const SEP = "___";
876
- const request = {
877
- is: {
878
- inline(request$1) {
879
- return request$1.includes(KEY);
880
- },
881
- colocated(request$1) {
882
- return request$1.includes(".css?scoped=");
883
- }
884
- },
885
- inline: {
886
- create(cssHash, postfix, cssContents) {
887
- return `./${postfix}${SEP}${cssHash}.${KEY}?css=${encodeURIComponent(cssContents)}`;
888
- },
889
- decode(request$1) {
890
- let [left, qps] = request$1.split("?");
891
- left = left.slice(2).replace(`.${KEY}`, "");
892
- let [postfix, hash$2] = left.split(SEP);
893
- let search = new URLSearchParams(qps);
894
- return {
895
- hash: hash$2,
896
- postfix,
897
- css: search.get("css"),
898
- from: search.get("from")
899
- };
900
- }
901
- },
902
- colocated: {
903
- create(cssHash, postfix, filePath) {
904
- return `./${node_path.default.basename(filePath)}?scoped=${postfix}&cssHash=${cssHash}`;
905
- },
906
- decode(request$1) {
907
- const [fileName, qs] = request$1.split("?");
908
- const search = new URLSearchParams(qs);
909
- return {
910
- fileName,
911
- cssHash: search.get("cssHash"),
912
- postfix: search.get("scoped")
913
- };
914
- }
915
- }
916
- };
917
-
918
- //#endregion
919
- //#region src/build/unplugin-colocated.js
920
- const META$1 = "scoped-css:colocated";
921
- /**
922
- * Plugin for supporting colocated styles
923
- *
924
- * e.g.:
925
- * src/components/my-component.js
926
- * src/components/my-component.css
927
- */
928
- function colocated(options = {}) {
929
- const CWD$1 = process.cwd();
930
- /**
931
- *
932
- * @param {string} id the request id / what was imported
933
- * @param {string} filePath path on disk
934
- * @returns
935
- */
936
- function buildResponse(id, filePath) {
937
- const parsed = request.colocated.decode(id);
938
- const relativeFilePath = node_path.default.relative(CWD$1, filePath);
939
- return {
940
- id: filePath,
941
- meta: { [META$1]: {
942
- postfix: parsed.postfix,
943
- fileName: relativeFilePath,
944
- fullPath: filePath
945
- } }
946
- };
947
- }
948
- return {
949
- name: "ember-scoped-css:colocated",
950
- resolveId(id, importer) {
951
- if (request.is.colocated(id)) {
952
- const parsed = request.colocated.decode(id);
953
- const filePath = node_path.default.resolve(node_path.default.dirname(importer), node_path.default.basename(parsed.fileName));
954
- /**
955
- * Rollup doesn't normally watch CSS files
956
- */
957
- this.addWatchFile(filePath);
958
- return buildResponse(id, filePath);
959
- }
960
- },
961
- load(id) {
962
- const meta = this.getModuleInfo(id)?.meta?.[META$1];
963
- if (meta) return rewriteCss((0, node_fs.readFileSync)(meta.fullPath, "utf-8"), meta.postfix, meta.fileName, options.layerName);
964
- },
965
- vite: { load(id) {
966
- if (request.is.colocated(id)) {
967
- const parsed = request.colocated.decode(id);
968
- let code = (0, node_fs.readFileSync)(parsed.fileName, "utf-8");
969
- let relativeFilePath = node_path.default.relative(CWD$1, parsed.fileName);
970
- return rewriteCss(code, parsed.postfix, relativeFilePath, options.layerName);
971
- }
972
- } }
973
- };
974
- }
975
-
976
- //#endregion
977
- //#region src/build/unplugin-inline.js
978
- const META = "scoped-css:inline";
979
- /**
980
- * Plugin for supporting the styles from
981
- *
982
- * <template>
983
- * <style>...</style>
984
- * </template>
985
- *
986
- * This plugin can't have HMR for CSS because changes to the CSS content alters the template content
987
- */
988
- function inline(options = {}) {
989
- const CWD$1 = process.cwd();
990
- /**
991
- * @param {string} id the request id / what was imported
992
- */
993
- function buildResponse(id, filePath) {
994
- const parsed = request.inline.decode(id);
995
- const relativeFilePath = node_path.default.relative(CWD$1, filePath);
996
- const css = rewriteCss(parsed.css, parsed.postfix, `<inline>/${relativeFilePath}`, options.layerName);
997
- return {
998
- id: filePath.split("?")[0],
999
- meta: { [META]: {
1000
- css,
1001
- postfix: parsed.postfix,
1002
- fileName: relativeFilePath
1003
- } }
1004
- };
1005
- }
1006
- return {
1007
- name: "ember-scoped-css:inline",
1008
- resolveId(id, importer) {
1009
- if (request.is.inline(id)) {
1010
- const parsed = request.inline.decode(id);
1011
- return buildResponse(id, node_path.default.resolve(node_path.default.dirname(importer), `${node_path.default.basename(importer, node_path.default.extname(importer))}-${parsed.hash}.css`));
1012
- }
1013
- },
1014
- load(id) {
1015
- const meta = this.getModuleInfo(id)?.meta?.[META];
1016
- if (meta) return meta.css;
1017
- }
1018
- };
1019
- }
1020
-
1021
- //#endregion
1022
- //#region src/build/scoped-css-unplugin.js
1023
- /**
1024
- * The plugin that handles CSS requests for `<style>` elements and transforms
1025
- * for existing files
1026
- *
1027
- * vite: CSS files are resolved by vite. We use their resolver to also get
1028
- * HMR. That is, for all non-physical CSS files, we extend vite by our
1029
- * resolver and also can enrich metadata to it (for better debugging)
1030
- */
1031
- const unplugin$1 = (0, unplugin.createUnplugin)((options = {}) => {
1032
- return [colocated(options), inline(options)];
1033
- });
1034
-
1035
- //#endregion
1036
- //#region src/lib/path/template-transform-paths.js
1037
- /**
1038
- * template plugins do not hand us the correct file path.
1039
- * additionally, we may not be able to rely on this data in the future,
1040
- * so this functions acts as a means of normalizing _whatever_ we're given
1041
- * in the future.
1042
- *
1043
- * @param {string} filename
1044
- * @returns {string} the absolute path to the file
1045
- */
1046
- function fixFilename(filename) {
1047
- let fileName = filename;
1048
- let workspace = findWorkspacePath(fileName);
1049
- /**
1050
- * ember-source 5.8:
1051
- * - the filename looks like an absolute path, but swapped out the 'app' part of the path
1052
- * with the module name, so the file paths never exist on disk
1053
- *
1054
- * - in vite apps:
1055
- * the 'app' part _may_ be `src`, so we also need to ensure that `src` is excluded as well
1056
- */
1057
- let hasAppDir = fileName.includes(node_path.default.join(workspace, "app"));
1058
- let hasSrcDir = fileName.includes(node_path.default.join(workspace, "src"));
1059
- if (!(hasAppDir || hasSrcDir) && !fileName.includes(leadingSlashPath.embroiderDir)) {
1060
- let [maybeScope, ...rest] = fileName.replace(workspace, "").split(node_path.default.sep).filter(Boolean);
1061
- let parts = rest;
1062
- if (maybeScope.startsWith("@")) {
1063
- let [, ...rester] = rest;
1064
- parts = rester;
1065
- }
1066
- let relative = node_path.default.join(...parts);
1067
- return node_path.default.join(workspace, "app", relative);
1068
- }
1069
- if (!fileName.includes(workspace)) return fileName;
1070
- return fileName;
1071
- }
1072
-
1073
- //#endregion
1074
- //#region src/lib/renameClass.js
1075
- /**
1076
- *
1077
- * @param {string} className
1078
- * @param {string} postfix
1079
- * @param {Set<string>} [classesInCss]
1080
- * @returns
1081
- */
1082
- function renameClass(className, postfix, classesInCss) {
1083
- const renamedClasses = className.split(/\s+/).filter((c) => c).map((c) => c.trim()).map((c) => {
1084
- if (!classesInCss || classesInCss.has(c)) {
1085
- if (c.endsWith(postfix)) return c;
1086
- return c + "_" + postfix;
1087
- }
1088
- return c;
1089
- }).join(" ");
1090
- return className.replace(className.trimStart().trimEnd(), renamedClasses);
1091
- }
1092
-
1093
- //#endregion
1094
- //#region src/lib/rewriteHbs.js
1095
- function templatePlugin({ classes, tags, postfix }) {
1096
- let stack = [];
1097
- let scopedClassCandidates = ["scoped-class", "scopedClass"];
1098
- function isScopedClass(str) {
1099
- if (!str) return false;
1100
- return scopedClassCandidates.some((candidate) => candidate === str);
1101
- }
1102
- return {
1103
- AttrNode(node) {
1104
- if (node.name === "class") {
1105
- if (node.value.type === "TextNode" && node.value.chars) {
1106
- const renamedClass = renameClass(node.value.chars, postfix, classes);
1107
- node.value.chars = renamedClass;
1108
- } else if (node.value.type === "ConcatStatement") {
1109
- for (let part of node.value.parts) if (part.type === "TextNode" && part.chars) part.chars = renameClass(part.chars, postfix, classes);
1110
- else if (part.type === "MustacheStatement") ember_template_recast.traverse(part, { StringLiteral(node$1) {
1111
- node$1.value = renameClass(node$1.value, postfix, classes);
1112
- } });
1113
- }
1114
- }
1115
- },
1116
- ElementNode(node) {
1117
- if (tags.has(node.tag)) {
1118
- const classAttr = node.attributes.find((attr) => attr.name === "class");
1119
- if (classAttr) classAttr.value.chars += " " + postfix;
1120
- else node.attributes.push(ember_template_recast.builders.attr("class", ember_template_recast.builders.text(postfix)));
1121
- }
1122
- },
1123
- All: {
1124
- enter(node) {
1125
- stack.push(node);
1126
- },
1127
- exit() {
1128
- stack.pop();
1129
- }
1130
- },
1131
- MustacheStatement(node) {
1132
- let cssClass;
1133
- if (isScopedClass(getValue(node.path)) && node.params?.length === 1 && node.params[0].type === "StringLiteral") cssClass = node.params[0].value;
1134
- if (isScopedClass(getValue(node.path?.path)) && node.path?.params?.length === 1 && node.path?.params[0].type === "StringLiteral") cssClass = node.path.params[0].value;
1135
- if (cssClass) {
1136
- const textNode = ember_template_recast.builders.text(renameClass(cssClass, postfix));
1137
- const parent = stack[stack.length - 1];
1138
- if (parent?.type === "AttrNode") parent.quoteType = "\"";
1139
- return textNode;
1140
- }
1141
- },
1142
- SubExpression(node) {
1143
- if (isScopedClass(getValue(node.path)) && node.params?.length === 1 && node.params[0].type === "StringLiteral") {
1144
- const cssClass = node.params[0].value;
1145
- return ember_template_recast.builders.literal("StringLiteral", renameClass(cssClass, postfix));
1146
- }
1147
- }
1148
- };
1149
- }
1150
- function getValue(path$8) {
1151
- if (!path$8) return;
1152
- if ("value" in path$8) return path$8.value;
1153
- /**
1154
- * Deprecated in ember 5.9+
1155
- * (so we use the above for newer embers)
1156
- */
1157
- return path$8.original;
1158
- }
1159
-
1160
- //#endregion
1161
- //#region src/build/template-plugin.js
1162
- const noopPlugin = {
1163
- name: "ember-scoped-css:noop",
1164
- visitor: {}
1165
- };
1166
- /**
1167
- * @returns {ASTPlugin}
1168
- */
1169
- function createPlugin(config) {
1170
- /**
1171
- *
1172
- * @param {ASTPluginEnvironment} env
1173
- */
1174
- return function scopedCss(env) {
1175
- let cwd = node_process.default.cwd();
1176
- if (!isRelevantFile(env.filename, {
1177
- additionalRoots: config.additionalRoots,
1178
- cwd
1179
- })) return noopPlugin;
1180
- let absolutePath = fixFilename(env.filename);
1181
- let postfix = hashFromModulePath(appPath(absolutePath));
1182
- /**
1183
- * The list of naked tag selectors found in the CSS
1184
- *
1185
- * @type {Set<string>}
1186
- */
1187
- let scopedTags = /* @__PURE__ */ new Set();
1188
- /**
1189
- * The list of classes found in the CSS
1190
- *
1191
- * @type {Set<string>}
1192
- */
1193
- let scopedClasses = /* @__PURE__ */ new Set();
1194
- /**
1195
- * @param {{ tags: Set<string>; classes: Set<string> }} info
1196
- */
1197
- function addInfo(info$1) {
1198
- for (let item of info$1.tags) scopedTags.add(item);
1199
- for (let item of info$1.classes) scopedClasses.add(item);
1200
- }
1201
- let cssPath = cssPathFor(absolutePath);
1202
- let info = getCSSInfo(cssPath);
1203
- let localCssPath = forcePosix(cssPath.replace(cwd + node_path.default.sep, ""));
1204
- /**
1205
- * This will be falsey if we don't have a co-located CSS file.
1206
- * We'll still want to check for embedded <style scoped> tags though.
1207
- */
1208
- if (info) {
1209
- addInfo(info);
1210
- let cssRequest = request.colocated.create(info.id, postfix, localCssPath);
1211
- /**
1212
- * With this we don't need a JS plugin
1213
- */
1214
- env.meta.jsutils.importForSideEffect(cssRequest);
1215
- }
1216
- let visitors = templatePlugin({
1217
- classes: scopedClasses,
1218
- tags: scopedTags,
1219
- postfix
1220
- });
1221
- return {
1222
- name: "ember-scoped-css:template-plugin",
1223
- visitor: {
1224
- ...visitors,
1225
- Template(node) {
1226
- /**
1227
- * We only allow a scoped <style> at the root
1228
- */
1229
- let styleTag = node.body.find((n) => n.type === "ElementNode" && n.tag === "style");
1230
- if (hasScopedAttribute(styleTag)) {
1231
- let css = textContent(styleTag);
1232
- let info$1 = getCSSContentInfo(css);
1233
- addInfo(info$1);
1234
- /**
1235
- * This will be handled in ElementNode traversal
1236
- */
1237
- if (hasInlineAttribute(styleTag)) return;
1238
- let cssRequest = request.inline.create(info$1.id, postfix, css);
1239
- env.meta.jsutils.importForSideEffect(cssRequest);
1240
- }
1241
- },
1242
- AttrNode(...args) {
1243
- return visitors.AttrNode(...args);
1244
- },
1245
- ElementNode(node, walker) {
1246
- visitors.ElementNode(node, walker);
1247
- if (hasScopedAttribute(node)) {
1248
- if (walker.parent?.node.type !== "Template") throw new Error("<style scoped> tags must be at the root of the template, they cannot be nested");
1249
- if (hasInlineAttribute(node)) {
1250
- let scopedText = rewriteCss(textContent(node), postfix, localCssPath, config.layerName);
1251
- /**
1252
- * Traverse this and allow interpolation
1253
- */
1254
- node.children = [env.syntax.builders.text(scopedText)];
1255
- return;
1256
- }
1257
- return null;
1258
- }
1259
- if (hasInlineAttribute(node)) throw new Error(`<style inline> is not valid. Please add the scoped attribute: <style scoped inline>`);
1260
- },
1261
- MustacheStatement(...args) {
1262
- return visitors.MustacheStatement(...args);
1263
- },
1264
- SubExpression(...args) {
1265
- return visitors.SubExpression(...args);
1266
- }
1267
- }
1268
- };
1269
- };
1270
- }
1271
- /**
1272
- * Thanks, CardStack and @ef4 for this code.
1273
- */
1274
- const SCOPED_ATTRIBUTE_NAME = "scoped";
1275
- const INLINE_ATTRIBUTE_NAME = "inline";
1276
- function hasScopedAttribute(node) {
1277
- if (!node) return;
1278
- if (node.tag !== "style") return;
1279
- if (node.type !== "ElementNode") return;
1280
- return node.attributes.some((attribute) => attribute.name === SCOPED_ATTRIBUTE_NAME);
1281
- }
1282
- function hasInlineAttribute(node) {
1283
- if (!node) return;
1284
- if (node.tag !== "style") return;
1285
- if (node.type !== "ElementNode") return;
1286
- return node.attributes.some((attribute) => attribute.name === INLINE_ATTRIBUTE_NAME);
1287
- }
1288
- function textContent(node) {
1289
- return node.children.filter((c) => c.type === "TextNode").map((c) => c.chars).join("");
1290
- }
1291
-
1292
- //#endregion
1293
- //#region src/build/public-exports/all.js
1294
- const scopedCSS = {
1295
- vite: unplugin$1.vite,
1296
- rollup: unplugin$1.rollup,
1297
- babel: scopedCSS$1,
1298
- template: createPlugin
1299
- };
1300
-
1301
- //#endregion
1302
- Object.defineProperty(exports, 'scopedCSS', {
1303
- enumerable: true,
1304
- get: function () {
1305
- return scopedCSS;
1306
- }
1307
- });
1308
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxsLUNmQkFtWHVhLmNqcyIsIm5hbWVzIjpbImhhc2giLCJoYXNoIiwiaGFzaEZyb21Nb2R1bGVQYXRoIiwiaGFzaFBvc2l4TW9kdWxlUGF0aCIsInBhdGgiLCJmc1N5bmMiLCJzY29wZWRDU1MiLCJwYXRoIiwiU0VQIiwicGFyc2VyIiwicmVxdWVzdCIsImhhc2giLCJwYXRoIiwiTUVUQSIsIkNXRCIsInBhdGgiLCJDV0QiLCJwYXRoIiwidW5wbHVnaW4iLCJwYXRoIiwibm9kZSIsInJlY2FzdCIsInBhdGgiLCJwcm9jZXNzIiwiaW5mbyIsInBhdGgiLCJ1bnBsdWdpbiIsImJhYmVsLnNjb3BlZENTUyIsInRlbXBsYXRlLmNyZWF0ZVBsdWdpbiJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvcGF0aC9jb25zdC5qcyIsIi4uLy4uL3NyYy9saWIvcGF0aC9tZDUuanMiLCIuLi8uLi9zcmMvbGliL3BhdGgvaGFzaC1mcm9tLW1vZHVsZS1wYXRoLmpzIiwiLi4vLi4vc3JjL2xpYi9wYXRoL3V0aWxzLmpzIiwiLi4vLi4vc3JjL2J1aWxkL2JhYmVsLXBsdWdpbi5qcyIsIi4uLy4uL3NyYy9saWIvY3NzL3V0aWxzLmpzIiwiLi4vLi4vc3JjL2xpYi9jc3MvcmV3cml0ZS5qcyIsIi4uLy4uL3NyYy9saWIvcmVxdWVzdC5qcyIsIi4uLy4uL3NyYy9idWlsZC91bnBsdWdpbi1jb2xvY2F0ZWQuanMiLCIuLi8uLi9zcmMvYnVpbGQvdW5wbHVnaW4taW5saW5lLmpzIiwiLi4vLi4vc3JjL2J1aWxkL3Njb3BlZC1jc3MtdW5wbHVnaW4uanMiLCIuLi8uLi9zcmMvbGliL3BhdGgvdGVtcGxhdGUtdHJhbnNmb3JtLXBhdGhzLmpzIiwiLi4vLi4vc3JjL2xpYi9yZW5hbWVDbGFzcy5qcyIsIi4uLy4uL3NyYy9saWIvcmV3cml0ZUhicy5qcyIsIi4uLy4uL3NyYy9idWlsZC90ZW1wbGF0ZS1wbHVnaW4uanMiLCIuLi8uLi9zcmMvYnVpbGQvcHVibGljLWV4cG9ydHMvYWxsLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuXG4vKipcbiAqIEpvaW4gd2lsbCBjb252ZXJ0IHRvIHdoYXRldmVyIGlzIGFwcHJvcHJpYXRlIGZybyB0aGUgY3VycmVudCBwbGF0Zm9ybVxuICovXG5cbmV4cG9ydCBjb25zdCBsZWFkaW5nU2xhc2hQYXRoID0ge1xuICBlbWJyb2lkZXJEaXI6IHBhdGguam9pbignL25vZGVfbW9kdWxlcy8uZW1icm9pZGVyLycpLFxuICBhdEVtYnJvaWRlcjogcGF0aC5qb2luKCcvQGVtYnJvaWRlcicpLFxuICBjb21wb25lbnRzRGlyOiBwYXRoLmpvaW4oJy9jb21wb25lbnRzLycpLFxuICB0ZW1wbGF0ZXNEaXI6IHBhdGguam9pbignL3RlbXBsYXRlcy8nKSxcbiAgdGVzdGVtOiBwYXRoLmpvaW4oJy90ZXN0ZW0nKSxcbiAgc3JjOiBwYXRoLmpvaW4oJy9zcmMvJyksXG4gIGFwcDogcGF0aC5qb2luKCcvYXBwLycpLFxufTtcblxuZXhwb3J0IGNvbnN0IGJhcmVQYXRoID0ge1xuICBwbnBtRGlyOiBwYXRoLmpvaW4oJ25vZGVfbW9kdWxlcy8ucG5wbScpLFxufTtcbiIsIi8qXG4gKiBKYXZhU2NyaXB0IE1ENVxuICogaHR0cHM6Ly9naXRodWIuY29tL2JsdWVpbXAvSmF2YVNjcmlwdC1NRDVcbiAqXG4gKiBDb3B5cmlnaHQgMjAxMSwgU2ViYXN0aWFuIFRzY2hhblxuICogaHR0cHM6Ly9ibHVlaW1wLm5ldFxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZTpcbiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUXG4gKlxuICogQmFzZWQgb25cbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgUlNBIERhdGEgU2VjdXJpdHksIEluYy4gTUQ1IE1lc3NhZ2VcbiAqIERpZ2VzdCBBbGdvcml0aG0sIGFzIGRlZmluZWQgaW4gUkZDIDEzMjEuXG4gKiBWZXJzaW9uIDIuMiBDb3B5cmlnaHQgKEMpIFBhdWwgSm9obnN0b24gMTk5OSAtIDIwMDlcbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIG1vcmUgaW5mby5cbiAqXG4gKiBNb2RpZmljYXRpb25zOlxuICogLSByZW1vdmVkIElJRkUsIGV4cG9ydGVkIG1kNSAodGhpcyBmaWxlIGlzIG5vdyBFU00pXG4gKi9cblxuLyoqXG4gKiBBZGQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuXG4gKiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnMgaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIGludGVycHJldGVycy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0geCBGaXJzdCBpbnRlZ2VyXG4gKiBAcGFyYW0ge251bWJlcn0geSBTZWNvbmQgaW50ZWdlclxuICogQHJldHVybnMge251bWJlcn0gU3VtXG4gKi9cbmZ1bmN0aW9uIHNhZmVBZGQoeCwgeSkge1xuICB2YXIgbHN3ID0gKHggJiAweGZmZmYpICsgKHkgJiAweGZmZmYpO1xuICB2YXIgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG5cbiAgcmV0dXJuIChtc3cgPDwgMTYpIHwgKGxzdyAmIDB4ZmZmZik7XG59XG5cbi8qKlxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW0gMzItYml0IG51bWJlclxuICogQHBhcmFtIHtudW1iZXJ9IGNudCBSb3RhdGlvbiBjb3VudFxuICogQHJldHVybnMge251bWJlcn0gUm90YXRlZCBudW1iZXJcbiAqL1xuZnVuY3Rpb24gYml0Um90YXRlTGVmdChudW0sIGNudCkge1xuICByZXR1cm4gKG51bSA8PCBjbnQpIHwgKG51bSA+Pj4gKDMyIC0gY250KSk7XG59XG5cbi8qKlxuICogQmFzaWMgb3BlcmF0aW9uIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gcSBxXG4gKiBAcGFyYW0ge251bWJlcn0gYSBhXG4gKiBAcGFyYW0ge251bWJlcn0gYiBiXG4gKiBAcGFyYW0ge251bWJlcn0geCB4XG4gKiBAcGFyYW0ge251bWJlcn0gcyBzXG4gKiBAcGFyYW0ge251bWJlcn0gdCB0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXN1bHRcbiAqL1xuZnVuY3Rpb24gbWQ1Y21uKHEsIGEsIGIsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIHNhZmVBZGQoYml0Um90YXRlTGVmdChzYWZlQWRkKHNhZmVBZGQoYSwgcSksIHNhZmVBZGQoeCwgdCkpLCBzKSwgYik7XG59XG5cbi8qKlxuICogQmFzaWMgb3BlcmF0aW9uIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYSBhXG4gKiBAcGFyYW0ge251bWJlcn0gYiBiXG4gKiBAcGFyYW0ge251bWJlcn0gYyBjXG4gKiBAcGFyYW0ge251bWJlcn0gZCBkXG4gKiBAcGFyYW0ge251bWJlcn0geCB4XG4gKiBAcGFyYW0ge251bWJlcn0gcyBzXG4gKiBAcGFyYW0ge251bWJlcn0gdCB0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXN1bHRcbiAqL1xuZnVuY3Rpb24gbWQ1ZmYoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKChiICYgYykgfCAofmIgJiBkKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbi8qKlxuICogQmFzaWMgb3BlcmF0aW9uIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYSBhXG4gKiBAcGFyYW0ge251bWJlcn0gYiBiXG4gKiBAcGFyYW0ge251bWJlcn0gYyBjXG4gKiBAcGFyYW0ge251bWJlcn0gZCBkXG4gKiBAcGFyYW0ge251bWJlcn0geCB4XG4gKiBAcGFyYW0ge251bWJlcn0gcyBzXG4gKiBAcGFyYW0ge251bWJlcn0gdCB0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXN1bHRcbiAqL1xuZnVuY3Rpb24gbWQ1Z2coYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKChiICYgZCkgfCAoYyAmIH5kKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbi8qKlxuICogQmFzaWMgb3BlcmF0aW9uIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYSBhXG4gKiBAcGFyYW0ge251bWJlcn0gYiBiXG4gKiBAcGFyYW0ge251bWJlcn0gYyBjXG4gKiBAcGFyYW0ge251bWJlcn0gZCBkXG4gKiBAcGFyYW0ge251bWJlcn0geCB4XG4gKiBAcGFyYW0ge251bWJlcn0gcyBzXG4gKiBAcGFyYW0ge251bWJlcn0gdCB0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXN1bHRcbiAqL1xuZnVuY3Rpb24gbWQ1aGgoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGIgXiBjIF4gZCwgYSwgYiwgeCwgcywgdCk7XG59XG5cbi8qKlxuICogQmFzaWMgb3BlcmF0aW9uIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYSBhXG4gKiBAcGFyYW0ge251bWJlcn0gYiBiXG4gKiBAcGFyYW0ge251bWJlcn0gYyBjXG4gKiBAcGFyYW0ge251bWJlcn0gZCBkXG4gKiBAcGFyYW0ge251bWJlcn0geCB4XG4gKiBAcGFyYW0ge251bWJlcn0gcyBzXG4gKiBAcGFyYW0ge251bWJlcn0gdCB0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXN1bHRcbiAqL1xuZnVuY3Rpb24gbWQ1aWkoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGMgXiAoYiB8IH5kKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSBNRDUgb2YgYW4gYXJyYXkgb2YgbGl0dGxlLWVuZGlhbiB3b3JkcywgYW5kIGEgYml0IGxlbmd0aC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSB4IEFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gQml0IGxlbmd0aFxuICogQHJldHVybnMge0FycmF5PG51bWJlcj59IE1ENSBBcnJheVxuICovXG5mdW5jdGlvbiBiaW5sTUQ1KHgsIGxlbikge1xuICAvKiBhcHBlbmQgcGFkZGluZyAqL1xuICB4W2xlbiA+PiA1XSB8PSAweDgwIDw8IGxlbiAlIDMyO1xuICB4WygoKGxlbiArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNF0gPSBsZW47XG5cbiAgdmFyIGk7XG4gIHZhciBvbGRhO1xuICB2YXIgb2xkYjtcbiAgdmFyIG9sZGM7XG4gIHZhciBvbGRkO1xuICB2YXIgYSA9IDE3MzI1ODQxOTM7XG4gIHZhciBiID0gLTI3MTczMzg3OTtcbiAgdmFyIGMgPSAtMTczMjU4NDE5NDtcbiAgdmFyIGQgPSAyNzE3MzM4Nzg7XG5cbiAgZm9yIChpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KSB7XG4gICAgb2xkYSA9IGE7XG4gICAgb2xkYiA9IGI7XG4gICAgb2xkYyA9IGM7XG4gICAgb2xkZCA9IGQ7XG5cbiAgICBhID0gbWQ1ZmYoYSwgYiwgYywgZCwgeFtpXSwgNywgLTY4MDg3NjkzNik7XG4gICAgZCA9IG1kNWZmKGQsIGEsIGIsIGMsIHhbaSArIDFdLCAxMiwgLTM4OTU2NDU4Nik7XG4gICAgYyA9IG1kNWZmKGMsIGQsIGEsIGIsIHhbaSArIDJdLCAxNywgNjA2MTA1ODE5KTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgM10sIDIyLCAtMTA0NDUyNTMzMCk7XG4gICAgYSA9IG1kNWZmKGEsIGIsIGMsIGQsIHhbaSArIDRdLCA3LCAtMTc2NDE4ODk3KTtcbiAgICBkID0gbWQ1ZmYoZCwgYSwgYiwgYywgeFtpICsgNV0sIDEyLCAxMjAwMDgwNDI2KTtcbiAgICBjID0gbWQ1ZmYoYywgZCwgYSwgYiwgeFtpICsgNl0sIDE3LCAtMTQ3MzIzMTM0MSk7XG4gICAgYiA9IG1kNWZmKGIsIGMsIGQsIGEsIHhbaSArIDddLCAyMiwgLTQ1NzA1OTgzKTtcbiAgICBhID0gbWQ1ZmYoYSwgYiwgYywgZCwgeFtpICsgOF0sIDcsIDE3NzAwMzU0MTYpO1xuICAgIGQgPSBtZDVmZihkLCBhLCBiLCBjLCB4W2kgKyA5XSwgMTIsIC0xOTU4NDE0NDE3KTtcbiAgICBjID0gbWQ1ZmYoYywgZCwgYSwgYiwgeFtpICsgMTBdLCAxNywgLTQyMDYzKTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgMTFdLCAyMiwgLTE5OTA0MDQxNjIpO1xuICAgIGEgPSBtZDVmZihhLCBiLCBjLCBkLCB4W2kgKyAxMl0sIDcsIDE4MDQ2MDM2ODIpO1xuICAgIGQgPSBtZDVmZihkLCBhLCBiLCBjLCB4W2kgKyAxM10sIDEyLCAtNDAzNDExMDEpO1xuICAgIGMgPSBtZDVmZihjLCBkLCBhLCBiLCB4W2kgKyAxNF0sIDE3LCAtMTUwMjAwMjI5MCk7XG4gICAgYiA9IG1kNWZmKGIsIGMsIGQsIGEsIHhbaSArIDE1XSwgMjIsIDEyMzY1MzUzMjkpO1xuXG4gICAgYSA9IG1kNWdnKGEsIGIsIGMsIGQsIHhbaSArIDFdLCA1LCAtMTY1Nzk2NTEwKTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgNl0sIDksIC0xMDY5NTAxNjMyKTtcbiAgICBjID0gbWQ1Z2coYywgZCwgYSwgYiwgeFtpICsgMTFdLCAxNCwgNjQzNzE3NzEzKTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpXSwgMjAsIC0zNzM4OTczMDIpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyA1XSwgNSwgLTcwMTU1ODY5MSk7XG4gICAgZCA9IG1kNWdnKGQsIGEsIGIsIGMsIHhbaSArIDEwXSwgOSwgMzgwMTYwODMpO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyAxNV0sIDE0LCAtNjYwNDc4MzM1KTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpICsgNF0sIDIwLCAtNDA1NTM3ODQ4KTtcbiAgICBhID0gbWQ1Z2coYSwgYiwgYywgZCwgeFtpICsgOV0sIDUsIDU2ODQ0NjQzOCk7XG4gICAgZCA9IG1kNWdnKGQsIGEsIGIsIGMsIHhbaSArIDE0XSwgOSwgLTEwMTk4MDM2OTApO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyAzXSwgMTQsIC0xODczNjM5NjEpO1xuICAgIGIgPSBtZDVnZyhiLCBjLCBkLCBhLCB4W2kgKyA4XSwgMjAsIDExNjM1MzE1MDEpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyAxM10sIDUsIC0xNDQ0NjgxNDY3KTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgMl0sIDksIC01MTQwMzc4NCk7XG4gICAgYyA9IG1kNWdnKGMsIGQsIGEsIGIsIHhbaSArIDddLCAxNCwgMTczNTMyODQ3Myk7XG4gICAgYiA9IG1kNWdnKGIsIGMsIGQsIGEsIHhbaSArIDEyXSwgMjAsIC0xOTI2NjA3NzM0KTtcblxuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyA1XSwgNCwgLTM3ODU1OCk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaSArIDhdLCAxMSwgLTIwMjI1NzQ0NjMpO1xuICAgIGMgPSBtZDVoaChjLCBkLCBhLCBiLCB4W2kgKyAxMV0sIDE2LCAxODM5MDMwNTYyKTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgMTRdLCAyMywgLTM1MzA5NTU2KTtcbiAgICBhID0gbWQ1aGgoYSwgYiwgYywgZCwgeFtpICsgMV0sIDQsIC0xNTMwOTkyMDYwKTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpICsgNF0sIDExLCAxMjcyODkzMzUzKTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgN10sIDE2LCAtMTU1NDk3NjMyKTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgMTBdLCAyMywgLTEwOTQ3MzA2NDApO1xuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyAxM10sIDQsIDY4MTI3OTE3NCk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaV0sIDExLCAtMzU4NTM3MjIyKTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgM10sIDE2LCAtNzIyNTIxOTc5KTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgNl0sIDIzLCA3NjAyOTE4OSk7XG4gICAgYSA9IG1kNWhoKGEsIGIsIGMsIGQsIHhbaSArIDldLCA0LCAtNjQwMzY0NDg3KTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpICsgMTJdLCAxMSwgLTQyMTgxNTgzNSk7XG4gICAgYyA9IG1kNWhoKGMsIGQsIGEsIGIsIHhbaSArIDE1XSwgMTYsIDUzMDc0MjUyMCk7XG4gICAgYiA9IG1kNWhoKGIsIGMsIGQsIGEsIHhbaSArIDJdLCAyMywgLTk5NTMzODY1MSk7XG5cbiAgICBhID0gbWQ1aWkoYSwgYiwgYywgZCwgeFtpXSwgNiwgLTE5ODYzMDg0NCk7XG4gICAgZCA9IG1kNWlpKGQsIGEsIGIsIGMsIHhbaSArIDddLCAxMCwgMTEyNjg5MTQxNSk7XG4gICAgYyA9IG1kNWlpKGMsIGQsIGEsIGIsIHhbaSArIDE0XSwgMTUsIC0xNDE2MzU0OTA1KTtcbiAgICBiID0gbWQ1aWkoYiwgYywgZCwgYSwgeFtpICsgNV0sIDIxLCAtNTc0MzQwNTUpO1xuICAgIGEgPSBtZDVpaShhLCBiLCBjLCBkLCB4W2kgKyAxMl0sIDYsIDE3MDA0ODU1NzEpO1xuICAgIGQgPSBtZDVpaShkLCBhLCBiLCBjLCB4W2kgKyAzXSwgMTAsIC0xODk0OTg2NjA2KTtcbiAgICBjID0gbWQ1aWkoYywgZCwgYSwgYiwgeFtpICsgMTBdLCAxNSwgLTEwNTE1MjMpO1xuICAgIGIgPSBtZDVpaShiLCBjLCBkLCBhLCB4W2kgKyAxXSwgMjEsIC0yMDU0OTIyNzk5KTtcbiAgICBhID0gbWQ1aWkoYSwgYiwgYywgZCwgeFtpICsgOF0sIDYsIDE4NzMzMTMzNTkpO1xuICAgIGQgPSBtZDVpaShkLCBhLCBiLCBjLCB4W2kgKyAxNV0sIDEwLCAtMzA2MTE3NDQpO1xuICAgIGMgPSBtZDVpaShjLCBkLCBhLCBiLCB4W2kgKyA2XSwgMTUsIC0xNTYwMTk4MzgwKTtcbiAgICBiID0gbWQ1aWkoYiwgYywgZCwgYSwgeFtpICsgMTNdLCAyMSwgMTMwOTE1MTY0OSk7XG4gICAgYSA9IG1kNWlpKGEsIGIsIGMsIGQsIHhbaSArIDRdLCA2LCAtMTQ1NTIzMDcwKTtcbiAgICBkID0gbWQ1aWkoZCwgYSwgYiwgYywgeFtpICsgMTFdLCAxMCwgLTExMjAyMTAzNzkpO1xuICAgIGMgPSBtZDVpaShjLCBkLCBhLCBiLCB4W2kgKyAyXSwgMTUsIDcxODc4NzI1OSk7XG4gICAgYiA9IG1kNWlpKGIsIGMsIGQsIGEsIHhbaSArIDldLCAyMSwgLTM0MzQ4NTU1MSk7XG5cbiAgICBhID0gc2FmZUFkZChhLCBvbGRhKTtcbiAgICBiID0gc2FmZUFkZChiLCBvbGRiKTtcbiAgICBjID0gc2FmZUFkZChjLCBvbGRjKTtcbiAgICBkID0gc2FmZUFkZChkLCBvbGRkKTtcbiAgfVxuXG4gIHJldHVybiBbYSwgYiwgYywgZF07XG59XG5cbi8qKlxuICogQ29udmVydCBhbiBhcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzIHRvIGEgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBpbnB1dCBNRDUgQXJyYXlcbiAqIEByZXR1cm5zIHtzdHJpbmd9IE1ENSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gYmlubDJyc3RyKGlucHV0KSB7XG4gIHZhciBpO1xuICB2YXIgb3V0cHV0ID0gJyc7XG4gIHZhciBsZW5ndGgzMiA9IGlucHV0Lmxlbmd0aCAqIDMyO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBsZW5ndGgzMjsgaSArPSA4KSB7XG4gICAgb3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGlucHV0W2kgPj4gNV0gPj4+IGkgJSAzMikgJiAweGZmKTtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59XG5cbi8qKlxuICogQ29udmVydCBhIHJhdyBzdHJpbmcgdG8gYW4gYXJyYXkgb2YgbGl0dGxlLWVuZGlhbiB3b3Jkc1xuICogQ2hhcmFjdGVycyA+MjU1IGhhdmUgdGhlaXIgaGlnaC1ieXRlIHNpbGVudGx5IGlnbm9yZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IFJhdyBpbnB1dCBzdHJpbmdcbiAqIEByZXR1cm5zIHtBcnJheTxudW1iZXI+fSBBcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzXG4gKi9cbmZ1bmN0aW9uIHJzdHIyYmlubChpbnB1dCkge1xuICB2YXIgaTtcbiAgdmFyIG91dHB1dCA9IFtdO1xuICBvdXRwdXRbKGlucHV0Lmxlbmd0aCA+PiAyKSAtIDFdID0gdW5kZWZpbmVkO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBvdXRwdXQubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBvdXRwdXRbaV0gPSAwO1xuICB9XG5cbiAgdmFyIGxlbmd0aDggPSBpbnB1dC5sZW5ndGggKiA4O1xuXG4gIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg4OyBpICs9IDgpIHtcbiAgICBvdXRwdXRbaSA+PiA1XSB8PSAoaW5wdXQuY2hhckNvZGVBdChpIC8gOCkgJiAweGZmKSA8PCBpICUgMzI7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgTUQ1IG9mIGEgcmF3IHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzIElucHV0IHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ30gUmF3IE1ENSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gcnN0ck1ENShzKSB7XG4gIHJldHVybiBiaW5sMnJzdHIoYmlubE1ENShyc3RyMmJpbmwocyksIHMubGVuZ3RoICogOCkpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIEhNQUMtTUQ1IG9mIGEga2V5IGFuZCBzb21lIGRhdGEgKHJhdyBzdHJpbmdzKVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgSE1BQyBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhIFJhdyBpbnB1dCBzdHJpbmdcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJhdyBNRDUgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIHJzdHJITUFDTUQ1KGtleSwgZGF0YSkge1xuICB2YXIgaTtcbiAgdmFyIGJrZXkgPSByc3RyMmJpbmwoa2V5KTtcbiAgdmFyIGlwYWQgPSBbXTtcbiAgdmFyIG9wYWQgPSBbXTtcbiAgdmFyIGhhc2g7XG4gIGlwYWRbMTVdID0gb3BhZFsxNV0gPSB1bmRlZmluZWQ7XG5cbiAgaWYgKGJrZXkubGVuZ3RoID4gMTYpIHtcbiAgICBia2V5ID0gYmlubE1ENShia2V5LCBrZXkubGVuZ3RoICogOCk7XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkgKz0gMSkge1xuICAgIGlwYWRbaV0gPSBia2V5W2ldIF4gMHgzNjM2MzYzNjtcbiAgICBvcGFkW2ldID0gYmtleVtpXSBeIDB4NWM1YzVjNWM7XG4gIH1cblxuICBoYXNoID0gYmlubE1ENShpcGFkLmNvbmNhdChyc3RyMmJpbmwoZGF0YSkpLCA1MTIgKyBkYXRhLmxlbmd0aCAqIDgpO1xuXG4gIHJldHVybiBiaW5sMnJzdHIoYmlubE1ENShvcGFkLmNvbmNhdChoYXNoKSwgNTEyICsgMTI4KSk7XG59XG5cbi8qKlxuICogQ29udmVydCBhIHJhdyBzdHJpbmcgdG8gYSBoZXggc3RyaW5nXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IFJhdyBpbnB1dCBzdHJpbmdcbiAqIEByZXR1cm5zIHtzdHJpbmd9IEhleCBlbmNvZGVkIHN0cmluZ1xuICovXG5mdW5jdGlvbiByc3RyMmhleChpbnB1dCkge1xuICB2YXIgaGV4VGFiID0gJzAxMjM0NTY3ODlhYmNkZWYnO1xuICB2YXIgb3V0cHV0ID0gJyc7XG4gIHZhciB4O1xuICB2YXIgaTtcblxuICBmb3IgKGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpICs9IDEpIHtcbiAgICB4ID0gaW5wdXQuY2hhckNvZGVBdChpKTtcbiAgICBvdXRwdXQgKz0gaGV4VGFiLmNoYXJBdCgoeCA+Pj4gNCkgJiAweDBmKSArIGhleFRhYi5jaGFyQXQoeCAmIDB4MGYpO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBFbmNvZGUgYSBzdHJpbmcgYXMgVVRGLThcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgSW5wdXQgc3RyaW5nXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBVVEY4IHN0cmluZ1xuICovXG5mdW5jdGlvbiBzdHIycnN0clVURjgoaW5wdXQpIHtcbiAgcmV0dXJuIHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChpbnB1dCkpO1xufVxuXG4vKipcbiAqIEVuY29kZXMgaW5wdXQgc3RyaW5nIGFzIHJhdyBNRDUgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHMgSW5wdXQgc3RyaW5nXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSYXcgTUQ1IHN0cmluZ1xuICovXG5mdW5jdGlvbiByYXdNRDUocykge1xuICByZXR1cm4gcnN0ck1ENShzdHIycnN0clVURjgocykpO1xufVxuXG4vKipcbiAqIEVuY29kZXMgaW5wdXQgc3RyaW5nIGFzIEhleCBlbmNvZGVkIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzIElucHV0IHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ30gSGV4IGVuY29kZWQgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGhleE1ENShzKSB7XG4gIHJldHVybiByc3RyMmhleChyYXdNRDUocykpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHJhdyBITUFDLU1ENSBmb3IgdGhlIGdpdmVuIGtleSBhbmQgZGF0YVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrIEhNQUMga2V5XG4gKiBAcGFyYW0ge3N0cmluZ30gZCBJbnB1dCBzdHJpbmdcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJhdyBNRDUgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIHJhd0hNQUNNRDUoaywgZCkge1xuICByZXR1cm4gcnN0ckhNQUNNRDUoc3RyMnJzdHJVVEY4KGspLCBzdHIycnN0clVURjgoZCkpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIEhleCBlbmNvZGVkIEhNQUMtTUQ1IGZvciB0aGUgZ2l2ZW4ga2V5IGFuZCBkYXRhXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGsgSE1BQyBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSBkIElucHV0IHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ30gUmF3IE1ENSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gaGV4SE1BQ01ENShrLCBkKSB7XG4gIHJldHVybiByc3RyMmhleChyYXdITUFDTUQ1KGssIGQpKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGVzIE1ENSB2YWx1ZSBmb3IgYSBnaXZlbiBzdHJpbmcuXG4gKiBJZiBhIGtleSBpcyBwcm92aWRlZCwgY2FsY3VsYXRlcyB0aGUgSE1BQy1NRDUgdmFsdWUuXG4gKiBSZXR1cm5zIGEgSGV4IGVuY29kZWQgc3RyaW5nIHVubGVzcyB0aGUgcmF3IGFyZ3VtZW50IGlzIGdpdmVuLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgSW5wdXQgc3RyaW5nXG4gKiBAcGFyYW0ge3N0cmluZ30gW2tleV0gSE1BQyBrZXlcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Jhd10gUmF3IG91dHB1dCBzd2l0Y2hcbiAqIEByZXR1cm5zIHtzdHJpbmd9IE1ENSBvdXRwdXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1kNShzdHJpbmcsIGtleSwgcmF3KSB7XG4gIGlmICgha2V5KSB7XG4gICAgaWYgKCFyYXcpIHtcbiAgICAgIHJldHVybiBoZXhNRDUoc3RyaW5nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmF3TUQ1KHN0cmluZyk7XG4gIH1cblxuICBpZiAoIXJhdykge1xuICAgIHJldHVybiBoZXhITUFDTUQ1KGtleSwgc3RyaW5nKTtcbiAgfVxuXG4gIHJldHVybiByYXdITUFDTUQ1KGtleSwgc3RyaW5nKTtcbn1cbiIsImltcG9ydCB7IG1kNSB9IGZyb20gJy4vbWQ1LmpzJztcblxuLyoqXG4gKiBUaGUgaW50ZW50IG9mIHRoaXMgZnVuY3Rpb24gaXMgdG8gZ2VuZXJhdGUgdGhlIHN1ZmZpeC9wb3N0Zml4IGZvciB0aGVcbiAqIGNzcyBjbGFzc2VzLCBiYXNlZCBvbiB0aGUgbW9kdWxlLXNjb3BlZCBwYXRoIG5hbWUuXG4gKlxuICogZm9yIGV4YW1wbGUsXG4gKiAgICBoYXNoKCdteS1hcHAvY29tcG9uZW50cy9mb28nKVxuICogIGluc3RlYWQgb2ZcbiAqICAgIGhhc2goJ2FwcC9jb21wb25lbnRzL2ZvbycpXG4gKlxuICogICh1bmxlc3MgeW91ciBhcHAgbmFtZSBpcyAnYXBwJylcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlUGF0aFxuICogQHJldHVybnMge3N0cmluZ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc2gobW9kdWxlUGF0aCkge1xuICByZXR1cm4gJ2UnICsgbWQ1KG1vZHVsZVBhdGgpLnN1YnN0cmluZygwLCA4KTtcbn1cblxuaWYgKGltcG9ydC5tZXRhLnZpdGVzdCkge1xuICBjb25zdCB7IGl0LCBleHBlY3QgfSA9IGltcG9ydC5tZXRhLnZpdGVzdDtcblxuICBpdCgnc2hvdWxkIHJldHVybiBhIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBwb3N0Zml4ID0gaGFzaCgnZm9vLmNzcycpO1xuXG4gICAgZXhwZWN0KHBvc3RmaXgpLnRvLmJlLmEoJ3N0cmluZycpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJldHVybiBhIHN0cmluZyBzdGFydGluZyB3aXRoIFwiZVwiJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHBvc3RmaXggPSBoYXNoKCdmb28uY3NzJyk7XG5cbiAgICBleHBlY3QocG9zdGZpeCkudG8ubWF0Y2goL15lLyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmV0dXJuIGEgc3RyaW5nIG9mIGxlbmd0aCA5JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHBvc3RmaXggPSBoYXNoKCdmb28uY3NzJyk7XG5cbiAgICBleHBlY3QocG9zdGZpeCkudG8uaGF2ZS5sZW5ndGhPZig5KTtcbiAgfSk7XG59XG5cbmV4cG9ydCBjb25zdCBoYXNoRnJvbU1vZHVsZVBhdGggPSBoYXNoO1xuIiwiaW1wb3J0IGFzc2VydCBmcm9tICdub2RlOmFzc2VydCc7XG5pbXBvcnQgZnNTeW5jLCB7IGV4aXN0c1N5bmMgfSBmcm9tICdub2RlOmZzJztcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tICdub2RlOm1vZHVsZSc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuXG5pbXBvcnQgeyBiYXJlUGF0aCwgbGVhZGluZ1NsYXNoUGF0aCB9IGZyb20gJy4vY29uc3QuanMnO1xuaW1wb3J0IHsgaGFzaEZyb21BYnNvbHV0ZVBhdGggfSBmcm9tICcuL2hhc2gtZnJvbS1hYnNvbHV0ZS1wYXRoLmpzJztcbmltcG9ydCB7IGhhc2hGcm9tTW9kdWxlUGF0aCBhcyBoYXNoUG9zaXhNb2R1bGVQYXRoIH0gZnJvbSAnLi9oYXNoLWZyb20tbW9kdWxlLXBhdGguanMnO1xuXG5leHBvcnQgeyBoYXNoRnJvbUFic29sdXRlUGF0aCB9IGZyb20gJy4vaGFzaC1mcm9tLWFic29sdXRlLXBhdGguanMnO1xuXG4vKipcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGhcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoRnJvbU1vZHVsZVBhdGgoZmlsZVBhdGgpIHtcbiAgbGV0IHBvc2l4UGF0aCA9IGZvcmNlUG9zaXgoZmlsZVBhdGgpO1xuXG4gIHJldHVybiBoYXNoUG9zaXhNb2R1bGVQYXRoKHBvc2l4UGF0aCk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JjZVBvc2l4KGZpbGVQYXRoKSB7XG4gIGNvbnN0IHBhcnNlZCA9IHBhdGgucGFyc2UoZmlsZVBhdGgpO1xuXG4gIGlmIChwYXJzZWQucm9vdCA9PT0gJycpIHtcbiAgICByZXR1cm4gZmlsZVBhdGgucmVwbGFjZUFsbChwYXRoLndpbjMyLnNlcCwgcGF0aC5wb3NpeC5zZXApO1xuICB9XG5cbiAgbGV0IHJvb3RsZXNzID0gZmlsZVBhdGgucmVwbGFjZShcbiAgICBuZXcgUmVnRXhwKGBeJHtSZWdFeHAuZXNjYXBlKHBhcnNlZC5yb290KX1gKSxcbiAgICBwYXRoLnBvc2l4LnNlcCxcbiAgKTtcblxuICByZXR1cm4gcm9vdGxlc3MucmVwbGFjZUFsbChwYXRoLndpbjMyLnNlcCwgcGF0aC5wb3NpeC5zZXApO1xufVxuXG5jb25zdCBDT01QT05FTlRfRVhURU5TSU9OUyA9IFsnLmd0cycsICcuZ2pzJywgJy50cycsICcuanMnLCAnLmhicyddO1xuXG4vLyBDSlMgLyBFU00/XG5sZXQgaGVyZSA9IGltcG9ydC5tZXRhLnVybDtcbmxldCBvdXJSZXF1aXJlID0gZ2xvYmFsVGhpcy5yZXF1aXJlXG4gID8gZ2xvYmFsVGhpcy5yZXF1aXJlXG4gIDogaGVyZSAmJiBjcmVhdGVSZXF1aXJlKGhlcmUpO1xuXG5pZiAoIW91clJlcXVpcmUpIHtcbiAgb3VyUmVxdWlyZSA9IHJlcXVpcmU7XG59XG5cbmNvbnN0IElSUkVMRVZBTlRfUEFUSFMgPSBbYmFyZVBhdGgucG5wbURpciwgJ19fdml0ZS0nXTtcbmNvbnN0IFVOU1VQUE9SVEVEX0RJUkVDVE9SSUVTID0gbmV3IFNldChbJ3Rlc3RzJ10pO1xuXG5jb25zdCBDV0QgPSBwcm9jZXNzLmN3ZCgpO1xuXG4vKipcbiAqIFJlZ2FyZGxlc3Mgb2Ygd2hhdCB0aGUgZmlsZVBhdGggZm9ybWF0IGlzLFxuICogdGhpcyB3aWxsIHRyeSB0byByZXR1cm4gdGhlIGNvcnJlY3QgcG9zdGZpeC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGhcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoRnJvbShmaWxlUGF0aCkge1xuICBpZiAocGF0aC5pc0Fic29sdXRlKGZpbGVQYXRoKSkge1xuICAgIHJldHVybiBoYXNoRnJvbUFic29sdXRlUGF0aChmaWxlUGF0aCk7XG4gIH1cblxuICByZXR1cm4gaGFzaEZyb21Nb2R1bGVQYXRoKGZpbGVQYXRoKTtcbn1cblxuLyoqXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3NzSGFzQXNzb2NpYXRlZENvbXBvbmVudChjc3NQYXRoKSB7XG4gIHJldHVybiBjc3NIYXNTdGFuZGFyZEZpbGUoY3NzUGF0aCkgfHwgY3NzSGFzUG9kc0ZpbGUoY3NzUGF0aCk7XG59XG5cbmZ1bmN0aW9uIGNzc0hhc1N0YW5kYXJkRmlsZShpZCkge1xuICAvKipcbiAgICogTm9ybWFsbHkgd2UgZG9uJ3QgbmVlZCB0byBjaGVjayBhIEpTIHBhdGggaGVyZSwgYnV0IHdoZW4gdXNpbmdcbiAgICogZW1icm9pZGVyQDMsIHdlIGhhdmUgYSBcInJld3JpdHRlbiBhcHBcIiwgd2hpY2ggaGFzIGFsbCBvdXIgc291cmNlXG4gICAqIHByZXByb2Nlc3NlZCBhIGJpdCBiZWZvcmUgc2NvcGVkLWNzcyB0cmFuc2Zvcm1hdGlvbnMuXG4gICAqXG4gICAqIChJbiBWaXRlLCB3ZSBvcGVyYXRlIG1vcmUgZGlyZWN0bHkgd2l0aCB0aGUgc291cmNlKVxuICAgKi9cbiAgZm9yIChsZXQgZXh0IG9mIENPTVBPTkVOVF9FWFRFTlNJT05TKSB7XG4gICAgbGV0IGNhbmRpZGF0ZVBhdGggPSBpZC5yZXBsYWNlKC9cXC5jc3MkLywgZXh0KTtcblxuICAgIGlmIChleGlzdHNTeW5jKGNhbmRpZGF0ZVBhdGgpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGNzc0hhc1BvZHNGaWxlKGlkKSB7XG4gIGlmICghaWQuZW5kc1dpdGgoJ3N0eWxlcy5jc3MnKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxseSB3ZSBkb24ndCBuZWVkIHRvIGNoZWNrIGEgSlMgcGF0aCBoZXJlLCBidXQgd2hlbiB1c2luZ1xuICAgKiBlbWJyb2lkZXJAMywgd2UgaGF2ZSBhIFwicmV3cml0dGVuIGFwcFwiLCB3aGljaCBoYXMgYWxsIG91ciBzb3VyY2VcbiAgICogcHJlcHJvY2Vzc2VkIGEgYml0IGJlZm9yZSBzY29wZWQtY3NzIHRyYW5zZm9ybWF0aW9ucy5cbiAgICpcbiAgICogKEluIFZpdGUsIHdlIG9wZXJhdGUgbW9yZSBkaXJlY3RseSB3aXRoIHRoZSBzb3VyY2UpXG4gICAqL1xuICBmb3IgKGxldCBleHQgb2YgQ09NUE9ORU5UX0VYVEVOU0lPTlMpIHtcbiAgICBsZXQgY2FuZGlkYXRlUGF0aCA9IGlkLnJlcGxhY2UoL3N0eWxlc1xcLmNzcyQvLCBgdGVtcGxhdGUke2V4dH1gKTtcblxuICAgIGlmIChleGlzdHNTeW5jKGNhbmRpZGF0ZVBhdGgpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQmFzZWQgb24gZW1iZXIncyBjb21wb25lbnQgbG9jYXRpb24gY29udmVudGlvbnMsXG4gKiB0aGlzIGZ1bmN0aW9uIHdpbGwgcHJvdmlkZSBhIHBhdGggZm9yIHdoZXJlIHdlXG4gKiBleHBlY3QgdGhlIENTUyB0byBsaXZlLlxuICpcbiAqIEZvciBjby1sb2NhdGVkIHN0cnVjdHVyZTpcbiAqICAgLSBjb21wb25lbnRzL215LWNvbXBvbmVudC5oYnNcbiAqICAgLSBjb21wb25lbnRzL215LWNvbXBvbmVudC5jc3NcbiAqXG4gKiBGb3IgbmVzdGVkIGNvLWxvY2F0ZWQgc3RydWN0dXJlXG4gKiAgIC0gY29tcG9uZW50cy9teS1jb21wb25lbnQvZm9vLmhic1xuICogICAtIGNvbXBvbmVudHMvbXktY29tcG9uZW50L2Zvby5jc3NcbiAqXG4gKiBGb3IgUG9kcyByb3V0ZXMgc3RydWN0dXJlXG4gKiAgIC0gcm91dGVzL215LXJvdXRlL3RlbXBsYXRlLntoYnMsanN9XG4gKiAgIC0gcm91dGVzL215LXJvdXRlL3N0eWxlcy5jc3NcbiAqXG4gKiBEZWxpYmVyYXRlbHkgbm90IHN1cHBvcnRlZDpcbiAqICAgLSBjb21wb25lbnRzIHcvIHBvZHMgLS0gdGhpcyBpcyBkZXByZWNhdGVkIGluIDUuMTBcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZU5hbWUgLSB0aGUgaGJzLCBqcywgZ2pzLCBndHMgb3Igd2hhdGV2ZXIgY28tbG9jYXRlZCBwYXRoLlxuICogQHJldHVybnMge3N0cmluZ30gLSBleHBlY3RlZCBjc3MgcGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3NzUGF0aEZvcihmaWxlTmFtZSkge1xuICBsZXQgd2l0aG91dEV4dCA9IHdpdGhvdXRFeHRlbnNpb24oZmlsZU5hbWUpO1xuICBsZXQgY3NzUGF0aCA9IHdpdGhvdXRFeHQgKyAnLmNzcyc7XG5cbiAgaWYgKGlzUG9kKGZpbGVOYW1lKSkge1xuICAgIGNzc1BhdGggPSBmaWxlTmFtZVxuICAgICAgLnJlcGxhY2UoL3RlbXBsYXRlXFwuanMkLywgJ3N0eWxlcy5jc3MnKVxuICAgICAgLnJlcGxhY2UoL3RlbXBsYXRlXFwuZ2pzLywgJ3N0eWxlcy5jc3MnKVxuICAgICAgLnJlcGxhY2UoL3RlbXBsYXRlXFwuZ3RzLywgJ3N0eWxlcy5jc3MnKVxuICAgICAgLnJlcGxhY2UoL3RlbXBsYXRlXFwuaGJzLywgJ3N0eWxlcy5jc3MnKTtcbiAgfVxuXG4gIHJldHVybiBjc3NQYXRoO1xufVxuXG4vKipcbiAqIE5vdGUgdGhhdCBjb21wb25lbnRzIGluIHRoZSBcInBvZHNcIiBjb252ZW50aW9uIHdpbGxcbiAqIG5ldmVyIGJlIHN1cHBvcnRlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUG9kVGVtcGxhdGUoZmlsZVBhdGgpIHtcbiAgaWYgKGZpbGVQYXRoLmluY2x1ZGVzKGxlYWRpbmdTbGFzaFBhdGguY29tcG9uZW50c0RpcikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIGZpbGVQYXRoLmVuZHNXaXRoKCd0ZW1wbGF0ZS5qcycpIHx8XG4gICAgZmlsZVBhdGguZW5kc1dpdGgoJ3RlbXBsYXRlLmhicycpIHx8XG4gICAgZmlsZVBhdGguZW5kc1dpdGgoJ3RlbXBsYXRlLmdqcycpIHx8XG4gICAgZmlsZVBhdGguZW5kc1dpdGgoJ3RlbXBsYXRlLmd0cycpXG4gICk7XG59XG5cbi8qKlxuICogTm90ZSB0aGF0IGNvbXBvbmVudHMgaW4gdGhlIFwicG9kc1wiIGNvbnZlbnRpb24gd2lsbFxuICogbmV2ZXIgYmUgc3VwcG9ydGVkLlxuICpcbiAqIENoZWNrcyBpZiBhIGZpbGUgZW5kcyB3aXRoXG4gKiAtIHRlbXBsYXRlLmpzXG4gKiAtIHRlbXBsYXRlLmhic1xuICogLSBzdHlsZXMuY3NzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1BvZChmaWxlUGF0aCkge1xuICBpZiAoZmlsZVBhdGguaW5jbHVkZXMobGVhZGluZ1NsYXNoUGF0aC5jb21wb25lbnRzRGlyKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChpc1BvZFRlbXBsYXRlKGZpbGVQYXRoKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZpbGVQYXRoLmVuZHNXaXRoKCdzdHlsZXMuY3NzJyk7XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aFxuICogQHJldHVybnMgdGhlIHNhbWUgcGF0aCwgYnV0IHdpdGhvdXQgdGhlIGV4dGVuc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aG91dEV4dGVuc2lvbihmaWxlUGF0aCkge1xuICBsZXQgcGFyc2VkID0gcGF0aC5wYXJzZShmaWxlUGF0aCk7XG5cbiAgcmV0dXJuIHBhdGguam9pbihwYXJzZWQuZGlyLCBwYXJzZWQubmFtZSk7XG59XG5cbi8qKlxuICogRXhhbXBsZXMgZm9yIGZpbGVOYW1lXG4gKiAtIGFic29sdXRlIG9uLWRpc2sgcGF0aFxuICogLSBpbiB3ZWJwYWNrXG4gKiAgIC0gVVJMLWFic29sdXRlIHBhdGgsIHN0YXJ0aW5nIHdpdGggL1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlTmFtZVxuICogQHBhcmFtIHt7IGFkZGl0aW9uYWxSb290cz86IHN0cmluZ1tdOyBjd2Q6IHN0cmluZyB9fSBvcHRpb25zXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNSZWxldmFudEZpbGUoZmlsZU5hbWUsIHsgYWRkaXRpb25hbFJvb3RzLCBjd2QgfSkge1xuICAvLyBGYWtlIGZpbGUgaGFuZGxlZCBieSB0ZXN0ZW0gc2VydmVyIHdoZW4gaXQgcnVuc1xuICBpZiAoZmlsZU5hbWUuc3RhcnRzV2l0aChsZWFkaW5nU2xhc2hQYXRoLnRlc3RlbSkpIHJldHVybiBmYWxzZTtcbiAgLy8gUHJpdmF0ZSBWaXJ0dWFsIE1vZHVsZXNcbiAgaWYgKGZpbGVOYW1lLnN0YXJ0c1dpdGgoJ1xcMCcpKSByZXR1cm4gZmFsc2U7XG5cbiAgLy8gVGhlc2UgYXJlIG5vdCB2YWxpZCB1c2VybGFuZCBuYW1lcyAob3IgYXJlIGZyb20gbGlicmFyaWVzKVxuICBpZiAocGF0aC5pc0Fic29sdXRlKGZpbGVOYW1lKSA9PT0gZmFsc2UpIHtcbiAgICBpZiAoZmlsZU5hbWUubWF0Y2goL15bYS16QS1aXS8pKSByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBFeHRlcm5hbCB0byB1c1xuICBpZiAoZmlsZU5hbWUuc3RhcnRzV2l0aChsZWFkaW5nU2xhc2hQYXRoLmF0RW1icm9pZGVyKSkgcmV0dXJuIGZhbHNlO1xuICBpZiAoSVJSRUxFVkFOVF9QQVRIUy5zb21lKChpKSA9PiBmaWxlTmFtZS5pbmNsdWRlcyhpKSkpIHJldHVybiBmYWxzZTtcblxuICBsZXQgd29ya3NwYWNlID0gZmluZFdvcmtzcGFjZVBhdGgoZmlsZU5hbWUpO1xuXG4gIGFzc2VydChjd2QsIGBjd2Qgd2FzIG5vdCBwYXNzZWQgdG8gaXNSZWxldmFudEZpbGVgKTtcblxuICBsZXQgb3VyV29ya3NwYWNlID0gZmluZFdvcmtzcGFjZVBhdGgoY3dkKTtcblxuICBpZiAod29ya3NwYWNlICE9PSBvdXJXb3Jrc3BhY2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBsZXQgbG9jYWwgPSBmaWxlTmFtZS5yZXBsYWNlKHdvcmtzcGFjZSwgJycpO1xuICBsZXQgWywgLi4ucGFydHNdID0gbG9jYWwuc3BsaXQocGF0aC5zZXApLmZpbHRlcihCb29sZWFuKTtcblxuICBpZiAoVU5TVVBQT1JURURfRElSRUNUT1JJRVMuaGFzKHBhcnRzWzBdKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3N0bHkgcG9kcyBzdXBwb3J0LlxuICAgKiBmb2xrcyBuZWVkIHRvIG9wdCBpbiB0byBwb2RzIChyb3V0ZXMpLCBiZWNhdXNlIGV2ZXJ5IHBvZHMgYXBwIGNhbiBiZSBjb25maWd1cmVkIGRpZmZlcmVudGx5XG4gICAqL1xuICBsZXQgcm9vdHMgPSBbXG4gICAgbGVhZGluZ1NsYXNoUGF0aC5jb21wb25lbnRzRGlyLFxuICAgIGxlYWRpbmdTbGFzaFBhdGgudGVtcGxhdGVzRGlyLFxuICAgIC4uLihhZGRpdGlvbmFsUm9vdHMgfHwgW10pLFxuICBdO1xuXG4gIGlmICghcm9vdHMuc29tZSgocm9vdCkgPT4gZmlsZU5hbWUuaW5jbHVkZXMocm9vdCkpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYWNrYWdlU2NvcGVkUGF0aFRvTW9kdWxlUGF0aChwYWNrYWdlU2NvcGVkUGF0aCkge1xuICAvKipcbiAgICogKkJ5IGNvbnZlbnRpb24qLCBgc3JjYCBpcyBvbWl0dGVkIGZyb20gY29tcG9uZW50IHBhdGhzLlxuICAgKiBXZSBjYW4gcmVmbGVjdCB0aGUgc2FtZSBiZWhhdmlvciBieSByZXBsYWNpbmcgc3JjL1xuICAgKiB3aXRoIGFuIGVtcHR5IHN0cmluZy5cbiAgICpcbiAgICogQ1NTIGlzbid0IGVtaXR0ZWQgYXMgYSBjby1sb2NhdGVkIG1vZHVsZSwgYnV0XG4gICAqIHRvIGtlZXAgY29udmVudGlvbnMgY29uc2lzdGVudCBhY3Jvc3MgbGFuZ3VhZ2VzLFxuICAgKiB3ZSBjYW4gcHJldGVuZCBpdCBpcy5cbiAgICpcbiAgICogQW55IGN1c3RvbWl6YXRpb24gYmV5b25kIHJlbW92aW5nIGBzcmNgIGFuZCBgYXBwYCBpcyBwb3RlbnRpYWxseSBjb25mdXNpbmcuXG4gICAqIElmIHdlIG5lZWQgZnVydGhlciBjdXN0b21pemF0aW9ucywgd2UnbGwgd2FudCB0byBtYXRjaCBvbiBgZXhwb3J0c2AgaW4gdGhlXG4gICAqIGNvcnJlc3BvbmRpbmcgcGFja2FnZS5qc29uXG4gICAqL1xuICBsZXQgcGFja2FnZVJlbGF0aXZlID0gcGFja2FnZVNjb3BlZFBhdGgucmVwbGFjZShcbiAgICBuZXcgUmVnRXhwKGBeJHtSZWdFeHAuZXNjYXBlKGxlYWRpbmdTbGFzaFBhdGguc3JjKX1gKSxcbiAgICBwYXRoLnNlcCxcbiAgKTtcblxuICBsZXQgcGFyc2VkID0gcGF0aC5wYXJzZShwYWNrYWdlUmVsYXRpdmUpO1xuXG4gIGlmIChpc1BvZChwYWNrYWdlUmVsYXRpdmUpKSB7XG4gICAgLyoqXG4gICAgICogRm9yIHBvZHMsIHdlIGNob3Agb2ZmIHRoZSB3aG9sZSBmaWxlLCBhbmQgdXNlIHRoZSBkaXIgbmFtZSBhcyB0aGUgXCJtb2R1bGVQYXRoXCJcbiAgICAgKi9cbiAgICByZXR1cm4gcGFyc2VkLmRpcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiBhbiBleHRlbnNpb24gaXMgcGFzc2VkLCByZW1vdmUgaXQuXG4gICAqIFdoZW4gdXNpbmcgcGFja2FnZXJzLCBmb2xrcyBhcmUgdXNlZCB0byBub3QgaGF2aW5nIHRvIHNwZWNpZnkgZXh0ZW5zaW9ucyBmb3IgZmlsZXMuXG4gICAqIFNpbmNlIHdlIGRvbid0IGV2ZW4gZW1pdCBjc3MgZmlsZXMgY28tbG9jYXRlZCB0byBlYWNoIG1vZHVsZSxcbiAgICogdGhpcyBoZWxwcyB1cyBub3QgY29udmV5IGEgbGllIHRoYXQgYSBmaWxlIG1heSBleGlzdCBpbiBhdCBydW50aW1lLlxuICAgKlxuICAgKiBGb3IgZXhhbXBsZSBgPG1vZHVsZS1uYW1lPi9jb21wb25lbnRzL2J1dHRvbmAuXG4gICAqIEl0IGRvZXNuJ3QgbWF0dGVyIHdoYXQgdGhlIGV4dGVuc2lvbiBpcywgYmVjYXVzZSB5b3UgY2FuIG9ubHkgaGF2ZSBvbmUgY3NzIGZpbGVcbiAgICogZm9yIHRoZSBidXR0b24gbW9kdWxlIGFueXdheS5cbiAgICovXG4gIGxldCBsb2NhbFBhY2thZ2VyU3R5bGVQYXRoID0gcGF0aC5qb2luKHBhcnNlZC5kaXIsIHBhcnNlZC5uYW1lKTtcblxuICByZXR1cm4gbG9jYWxQYWNrYWdlclN0eWxlUGF0aDtcbn1cblxuLyoqXG4gKiByZXR1cm5zIHRoZSBhcHAtbW9kdWxlIHBhdGggb2YgdGhlIHNvdXJjZSBmaWxlXG4gKlxuICogVGhpcyBhc3N1bWVzIG5vcm1hbCBlbWJlciBhcHAgY29udmVudGlvbnNcbiAqXG4gKiB3aGljaCBpcyBgPHBhY2thZ2UuanNvbiNuYW1lPi9wYXRoLXRvLWZpbGVgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBQYXRoKHNvdXJjZVBhdGgpIHtcbiAgbGV0IHdvcmtzcGFjZVBhdGggPSBmaW5kV29ya3NwYWNlUGF0aChzb3VyY2VQYXRoKTtcbiAgbGV0IG5hbWUgPSBtb2R1bGVOYW1lKHNvdXJjZVBhdGgpO1xuXG4gIC8qKlxuICAgKiAgVW5kZXIgZW1icm9pZGVyIGJ1aWxkcywgdGhlIHNwZWMtY29tcGxpYW50IHZlcnNpb24gb2YgdGhlIGFwcFxuICAgKiBoYXMgYWxsIHRoZSBmaWxlcyB1bmRlciBhIGZvbGRlciB3aGljaCByZXByZXNlbnRzIHRoZSBwYWNrYWdlIG5hbWUsXG4gICAqIHJhdGhlciB0aGFuIFwiYXBwXCIuXG4gICAqL1xuICBsZXQgcGFja2FnZVJlbGF0aXZlID0gc291cmNlUGF0aC5yZXBsYWNlKHdvcmtzcGFjZVBhdGgsICcnKTtcblxuICAvKipcbiAgICogQnV0IHdlIGFsc28gZG9uJ3Qgd2FudCAnYXBwJyAtLSB3aGljaCBpcyBwcmVzZW50IGluIHRoZSB2MSBhZGRvbiBwaXBlbGluZVxuICAgKi9cbiAgcGFja2FnZVJlbGF0aXZlID0gcGFja2FnZVJlbGF0aXZlLnJlcGxhY2UobGVhZGluZ1NsYXNoUGF0aC5hcHAsIHBhdGguc2VwKTtcblxuICAvLyBBbnkgb2YgdGhlIGFib3ZlIHJlbHBhY2VtZW50cyBjb3VsZCBhY2NpZGVudGFsbHkgZ2l2ZSB1cyBhbiBleHRyYSAvIChkZXBlbmRpbmcgb24gb3VyIGJ1aWxkIGVudmlyb25tZW50KVxuICBwYWNrYWdlUmVsYXRpdmUgPSBwYXRoLm5vcm1hbGl6ZShwYWNrYWdlUmVsYXRpdmUpO1xuXG4gIGxldCBsb2NhbFBhY2thZ2VyU3R5bGVQYXRoID0gcGFja2FnZVNjb3BlZFBhdGhUb01vZHVsZVBhdGgocGFja2FnZVJlbGF0aXZlKTtcblxuICByZXR1cm4gYCR7bmFtZX0ke2xvY2FsUGFja2FnZXJTdHlsZVBhdGh9YDtcbn1cblxuLyoqXG4gKiBUbyBhdm9pZCBoaXR0aW5nIHRoZSBmaWxlc3lzZXRtLCB3ZSdsbCBzdG9yZSBhbGwgZm91bmRcbiAqIHByb2plY3QgcGF0aHMgYmVyZSwgc28gd2UgY2FuLCBpbiBtZW1vcnksXG4gKiBnZXQgdGhlIGZvbGRlciB3aGVyZSBhIHBhY2thZ2UuanNvbiBleGlzdHMsIHJhdGhlciB0aGFuXG4gKiBoaXQgdGhlIGZpbGUgc3lzdGVtIGV2ZXJ5IHRpbWUuXG4gKi9cbmNvbnN0IFNFRU4gPSBuZXcgU2V0KCk7XG5cbmZ1bmN0aW9uIGdldFNlZW4oc291cmNlUGF0aCkge1xuICBpZiAoU0VFTi5oYXMoc291cmNlUGF0aCkpIHJldHVybiBzb3VyY2VQYXRoO1xuXG4gIGxldCBwYXJ0cyA9IHNvdXJjZVBhdGguc3BsaXQocGF0aC5zZXApO1xuXG4gIGZvciAobGV0IGkgPSBwYXJ0cy5sZW5ndGggLSAxOyBpID4gMTsgaS0tKSB7XG4gICAgbGV0IHRvQ2hlY2sgPSBwYXJ0cy5zbGljZSgwLCBpKS5qb2luKHBhdGguc2VwKTtcblxuICAgIGxldCBzZWVuID0gU0VFTi5oYXModG9DaGVjayk7XG5cbiAgICBpZiAoc2Vlbikge1xuICAgICAgcmV0dXJuIHRvQ2hlY2s7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaW5kV29ya3NwYWNlUGF0aChzb3VyY2VQYXRoLCBvcHRpb25zKSB7XG4gIGxldCBjd2QgPSBvcHRpb25zPy5jd2QgPz8gQ1dEO1xuXG4gIGlmIChzb3VyY2VQYXRoLmVuZHNXaXRoKHBhdGguc2VwKSkge1xuICAgIHNvdXJjZVBhdGggPSBzb3VyY2VQYXRoLnJlcGxhY2UoXG4gICAgICBuZXcgUmVnRXhwKGAke1JlZ0V4cC5lc2NhcGUocGF0aC5zZXApfSRgKSxcbiAgICAgICcnLFxuICAgICk7XG4gIH1cblxuICBsZXQgc2VlbiA9IGdldFNlZW4oc291cmNlUGF0aCk7XG5cbiAgaWYgKHNlZW4pIHtcbiAgICByZXR1cm4gc2VlbjtcbiAgfVxuXG4gIGxldCBjYW5kaWRhdGVQYXRoID0gcGF0aC5qb2luKHNvdXJjZVBhdGgsICdwYWNrYWdlLmpzb24nKTtcblxuICBjb25zdCBpc1dvcmtzcGFjZSA9IGZzU3luYy5leGlzdHNTeW5jKGNhbmRpZGF0ZVBhdGgpO1xuXG4gIGlmIChpc1dvcmtzcGFjZSkge1xuICAgIHJldHVybiBzb3VyY2VQYXRoO1xuICB9XG5cbiAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gZmluZFBhY2thZ2VKc29uVXAoc291cmNlUGF0aCwgeyBjd2QgfSk7XG5cbiAgaWYgKCFwYWNrYWdlSnNvblBhdGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBkZXRlcm1pbmUgcHJvamVjdCBmb3IgJHtzb3VyY2VQYXRofWApO1xuICB9XG5cbiAgY29uc3Qgd29ya3NwYWNlUGF0aCA9IHBhdGguZGlybmFtZShwYWNrYWdlSnNvblBhdGgpO1xuXG4gIFNFRU4uYWRkKHdvcmtzcGFjZVBhdGgpO1xuXG4gIHJldHVybiB3b3Jrc3BhY2VQYXRoO1xufVxuXG5mdW5jdGlvbiBmaW5kUGFja2FnZUpzb25VcChzdGFydFBhdGgsIG9wdGlvbnMpIHtcbiAgbGV0IGN3ZCA9IG9wdGlvbnM/LmN3ZCA/PyBDV0Q7XG4gIGxldCBwYXJ0cyA9IHN0YXJ0UGF0aC5zcGxpdChwYXRoLnNlcCk7XG5cbiAgZm9yIChsZXQgaSA9IHBhcnRzLmxlbmd0aCAtIDE7IGkgPiAxOyBpLS0pIHtcbiAgICBsZXQgdG9DaGVjayA9IHBhcnRzLnNsaWNlKDAsIGkpLmpvaW4ocGF0aC5zZXApO1xuXG4gICAgbGV0IHBhY2thZ2VKc29uID0gcGF0aC5qb2luKHRvQ2hlY2ssICdwYWNrYWdlLmpzb24nKTtcbiAgICBsZXQgZXhpc3RzID0gZnNTeW5jLmV4aXN0c1N5bmMocGFja2FnZUpzb24pO1xuXG4gICAgaWYgKGV4aXN0cykge1xuICAgICAgcmV0dXJuIHBhY2thZ2VKc29uO1xuICAgIH1cblxuICAgIC8vIERvbid0IHRyYXZlcnNlIGFsbCB0aGUgd2F5IHRvIHRoZSByb290IG9mIHRoZSBmaWxlIHN5c3RlbS5cbiAgICBpZiAodG9DaGVjayA9PT0gY3dkKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuY29uc3QgTUFOSUZFU1RfQ0FDSEUgPSBuZXcgTWFwKCk7XG5cbi8qKlxuICogV2lsbCByZXR1cm4gdGhlIHBhY2thZ2UuanNvbiNuYW1lLCBvciBjb25maWcvZW52aXJvbm1lbnQjbW91ZGxlUHJlZml4IChpZiB2MSBhcHApXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZVBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vZHVsZU5hbWUoc291cmNlUGF0aCkge1xuICBjb25zdCB3b3Jrc3BhY2UgPSBmaW5kV29ya3NwYWNlUGF0aChzb3VyY2VQYXRoKTtcbiAgY29uc3QgbWFuaWZlc3QgPSBnZXRNYW5pZmVzdCh3b3Jrc3BhY2UpO1xuXG4gIHJldHVybiBtYW5pZmVzdC5uYW1lO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSB3b3Jrc3BhY2VcbiAqL1xuZnVuY3Rpb24gZ2V0TWFuaWZlc3Qod29ya3NwYWNlKSB7XG4gIGxldCBleGlzdGluZyA9IE1BTklGRVNUX0NBQ0hFLmdldCh3b3Jrc3BhY2UpO1xuXG4gIGlmIChleGlzdGluZykge1xuICAgIHJldHVybiBleGlzdGluZztcbiAgfVxuXG4gIGxldCBidWZmZXIgPSBmc1N5bmMucmVhZEZpbGVTeW5jKHBhdGguam9pbih3b3Jrc3BhY2UsICdwYWNrYWdlLmpzb24nKSk7XG4gIGxldCBjb250ZW50ID0gYnVmZmVyLnRvU3RyaW5nKCk7XG4gIGxldCBqc29uID0gSlNPTi5wYXJzZShjb250ZW50KTtcblxuICBNQU5JRkVTVF9DQUNIRS5zZXQod29ya3NwYWNlLCBqc29uKTtcblxuICByZXR1cm4ganNvbjtcbn1cbiIsImltcG9ydCB7IGlzUmVsZXZhbnRGaWxlIH0gZnJvbSAnLi4vbGliL3BhdGgvdXRpbHMuanMnO1xuXG5mdW5jdGlvbiBfaXNSZWxldmFudEZpbGUoc3RhdGUsIGN3ZCkge1xuICBsZXQgZmlsZU5hbWUgPSBzdGF0ZS5maWxlLm9wdHMuZmlsZW5hbWU7XG4gIGxldCBhZGRpdGlvbmFsUm9vdHMgPSBzdGF0ZS5vcHRzPy5hZGRpdGlvbmFsUm9vdHM7XG5cbiAgcmV0dXJuIGlzUmVsZXZhbnRGaWxlKGZpbGVOYW1lLCB7XG4gICAgYWRkaXRpb25hbFJvb3RzLFxuICAgIGN3ZCxcbiAgfSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHthbnl9IGVudiAtIGJhYmVsIHBsdWdpbiBlbnYsIGVudi50eXBlcyBpcyBtb3N0IGNvbW1vbmx5IHVzZWQgKGVzcCBpbiBUUylcbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zIC0gdGhlIG9wdGlvbnMgZm9yIHNjb3BlZC1jc3MgLS0gdGhpcyBpcyBhbHNvIGF2YWlsYWJsZSBpbiBlYWNoIHZpc2l0b3IncyBzdGF0ZS5vcHRzXG4gKiBAcGFyYW0ge3N0cmluZ30gd29ya2luZ0RpcmVjdG9yeVxuICovXG5leHBvcnQgY29uc3Qgc2NvcGVkQ1NTID0gKGNvbmZpZykgPT4gKGVudiwgb3B0aW9ucywgd29ya2luZ0RpcmVjdG9yeSkgPT4ge1xuICAvLyBub3QgcmVhbGx5IGEgZGVlcCBtZXJnZSwgYnV0IHRoZSBpZGVhIGlzIHRvIHVzZSBvbmUgb3IgdGhlIG90aGVyIGFuZCBub3QgbWl4IHRoZSBjb25maWdzXG4gIG9wdGlvbnMgPSB7IC4uLmNvbmZpZywgLi4ub3B0aW9ucyB9O1xuXG4gIC8qKlxuICAgKiBUaGlzIGJhYmVsIHBsdWdpbiBkb2VzIHR3byB0aGluZ3M6XG4gICAqIC0gcmVtb3ZlcyB0aGUgaW1wb3J0IG9mIHNjb3BlZENsYXNzLCBpZiBpdCBleGlzdHNcbiAgICogICAtIGlmIHNjb3BlZENsYXNzIHdhcyBpbXBvcnRlZCwgaXQgaXMgcmVtb3ZlZCBmcm9tIGFueSBjb21wb25lbnQncyBcInNjb3BlIGJhZ1wiXG4gICAqICAgICAodGhlIHNjb3BlIGJhZyBiZWluZyBhIGxvdy1sZXZlbCBvYmplY3QgdXNlZCBmb3IgcGFzc2luZyB3aGF0IGlzIFwiaW4gc2NvcGVcIiBmb3IgYSBjb21wb25lbnQpXG4gICAqL1xuICByZXR1cm4ge1xuICAgIHZpc2l0b3I6IHtcbiAgICAgIFByb2dyYW06IHtcbiAgICAgICAgZW50ZXIocGF0aCwgc3RhdGUpIHtcbiAgICAgICAgICBpZiAoIV9pc1JlbGV2YW50RmlsZShzdGF0ZSwgd29ya2luZ0RpcmVjdG9yeSkpIHtcbiAgICAgICAgICAgIHN0YXRlLmNhblNraXAgPSB0cnVlO1xuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIEltcG9ydERlY2xhcmF0aW9uKHBhdGgsIHN0YXRlKSB7XG4gICAgICAgIGlmIChzdGF0ZS5jYW5Ta2lwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhdGgubm9kZS5zb3VyY2UudmFsdWUgPT09ICdlbWJlci1zY29wZWQtY3NzJykge1xuICAgICAgICAgIGxldCBzcGVjaWZpZXIgPSBwYXRoLm5vZGUuc3BlY2lmaWVycy5maW5kKFxuICAgICAgICAgICAgKHgpID0+IHguaW1wb3J0ZWQubmFtZSA9PT0gJ3Njb3BlZENsYXNzJyxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKHNwZWNpZmllcikge1xuICAgICAgICAgICAgc3RhdGUuZmlsZS5vcHRzLmltcG9ydGVkU2NvcGVkQ2xhc3MgPSBzcGVjaWZpZXIubG9jYWwubmFtZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc3BlY2lmaWVyLmxvY2FsLm5hbWUgIT09ICdzY29wZWRDbGFzcycpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYFRoZSBzY29wZWRDbGFzcyBpbXBvcnQgaXMgYSBwc3VlZG8taGVscGVyLCBhbmQgbWF5IG5vdCBiZSByZW5hbWVkIGFzIGl0IGlzIHJlbW92ZWQgYXQgYnVpbGQgdGltZS5gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBwYXRoLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgLyoqXG4gICAgICAgKiBPbmx5IGluIHN0cmljdCBtb2RlLCBkbyB3ZSBjYXJlIGFib3V0IHJlbW9uaW5nIHRoZSBzY29wZSBiYWcgcmVmZXJlbmNlXG4gICAgICAgKi9cbiAgICAgIE9iamVjdFByb3BlcnR5KHBhdGgsIHN0YXRlKSB7XG4gICAgICAgIGlmICghc3RhdGUuZmlsZS5vcHRzPy5pbXBvcnRlZFNjb3BlZENsYXNzKSByZXR1cm47XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHBhdGgubm9kZS52YWx1ZS50eXBlID09PSAnSWRlbnRpZmllcicgJiZcbiAgICAgICAgICBwYXRoLm5vZGUudmFsdWUubmFtZSA9PT0gc3RhdGUuZmlsZS5vcHRzPy5pbXBvcnRlZFNjb3BlZENsYXNzXG4gICAgICAgICkge1xuICAgICAgICAgIHBhdGgucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcbn07XG4iLCJpbXBvcnQgeyBleGlzdHNTeW5jLCByZWFkRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgcG9zdGNzcyBmcm9tICdwb3N0Y3NzJztcbmltcG9ydCBwYXJzZXIgZnJvbSAncG9zdGNzcy1zZWxlY3Rvci1wYXJzZXInO1xuXG5pbXBvcnQgeyBtZDUgfSBmcm9tICcuLi9wYXRoL21kNS5qcyc7XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGNzc1xuICogQHJldHVybiB7c3RyaW5nfSBoYXNoZWQgZG93biB2ZXJzaW9uIG9mIHRoZSBDU1MgZm9yIGRpc2FtYmlndWF0aW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoKGNzcykge1xuICByZXR1cm4gYGNzcy0ke21kNShjc3MpfWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0luc2lkZUdsb2JhbChub2RlLCBmdW5jKSB7XG4gIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50O1xuXG4gIGlmICghcGFyZW50KSByZXR1cm4gZmFsc2U7XG4gIGlmIChwYXJlbnQudHlwZSA9PT0gJ3BzZXVkbycgJiYgcGFyZW50LnZhbHVlID09PSAnOmdsb2JhbCcpIHJldHVybiB0cnVlO1xuXG4gIHJldHVybiBpc0luc2lkZUdsb2JhbChwYXJlbnQsIGZ1bmMpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBjc3NQYXRoIHBhdGggdG8gYSBDU1MgZmlsZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q1NTSW5mbyhjc3NQYXRoKSB7XG4gIGlmICghZXhpc3RzU3luYyhjc3NQYXRoKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgbGV0IGNzcyA9IHJlYWRGaWxlU3luYyhjc3NQYXRoLCAndXRmOCcpO1xuXG4gIHJldHVybiBnZXRDU1NDb250ZW50SW5mbyhjc3MpO1xufVxuXG4vKipcbiAqIFdlIHVzZSB0aGlzIGZ1bmN0aW9uIHRvIGNoZWNrIGVhY2ggY2xhc3MgdXNlZCBpbiB0aGUgdGVtcGxhdGVcbiAqIHRvIHNlZSBpZiB3ZSBuZWVkIHRvIGxlYXZlIGl0IGFsb25lIG9yIHRyYW5zZm9ybSBpdFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjc3MgdGhlIENTUydzIGNvbnRlbnRzXG4gKiBAcmV0dXJuIHt7IGNsYXNzZXM6IFNldDxzdHJpbmc+LCB0YWdzOiBTZXQ8c3RyaW5nPiwgY3NzOiBzdHJpbmcsIGlkOiBzdHJpbmcgfX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENTU0NvbnRlbnRJbmZvKGNzcykge1xuICBjb25zdCBjbGFzc2VzID0gbmV3IFNldCgpO1xuICBjb25zdCB0YWdzID0gbmV3IFNldCgpO1xuXG4gIGNvbnN0IGFzdCA9IHBvc3Rjc3MucGFyc2UoY3NzKTtcblxuICBhc3Qud2Fsaygobm9kZSkgPT4ge1xuICAgIGlmIChub2RlLnR5cGUgPT09ICdydWxlJykge1xuICAgICAgZ2V0Q2xhc3Nlc0FuZFRhZ3Mobm9kZS5zZWxlY3RvciwgY2xhc3NlcywgdGFncyk7XG4gICAgfVxuICB9KTtcblxuICBsZXQgaWQgPSBoYXNoKGNzcyk7XG5cbiAgcmV0dXJuIHsgY2xhc3NlcywgdGFncywgY3NzLCBpZCB9O1xufVxuXG5mdW5jdGlvbiBnZXRDbGFzc2VzQW5kVGFncyhzZWwsIGNsYXNzZXMsIHRhZ3MpIHtcbiAgY29uc3QgdHJhbnNmb3JtID0gKHNscykgPT4ge1xuICAgIHNscy53YWxrKChzZWxlY3RvcikgPT4ge1xuICAgICAgaWYgKHNlbGVjdG9yLnR5cGUgPT09ICdjbGFzcycgJiYgIWlzSW5zaWRlR2xvYmFsKHNlbGVjdG9yKSkge1xuICAgICAgICBjbGFzc2VzLmFkZChzZWxlY3Rvci52YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHNlbGVjdG9yLnR5cGUgPT09ICd0YWcnICYmICFpc0luc2lkZUdsb2JhbChzZWxlY3RvcikpIHtcbiAgICAgICAgdGFncy5hZGQoc2VsZWN0b3IudmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIHBhcnNlcih0cmFuc2Zvcm0pLnByb2Nlc3NTeW5jKHNlbCk7XG59XG5cbmlmIChpbXBvcnQubWV0YS52aXRlc3QpIHtcbiAgY29uc3QgeyBpdCwgZXhwZWN0IH0gPSBpbXBvcnQubWV0YS52aXRlc3Q7XG5cbiAgaXQoJ3Nob3VsZCByZXR1cm4gY2xhc3NlcyBhbmQgdGFncyB0aGF0IGFyZSBub3QgaW4gOmdsb2JhbCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjc3MgPSAnLmJheiA6Z2xvYmFsKC5mb28pIC5iYXIgZGl2IDpnbG9iYWwocCkgIHsgY29sb3I6IHJlZDsgfSc7XG4gICAgY29uc3QgeyBjbGFzc2VzLCB0YWdzIH0gPSBnZXRDU1NDb250ZW50SW5mbyhjc3MpO1xuXG4gICAgLy8gY2xhc3NlcyBzaG91bGQgYmUgYmF6IGFuZCBiYXJcbiAgICBleHBlY3QoY2xhc3Nlcy5zaXplKS50by5lcXVhbCgyKTtcbiAgICBleHBlY3QoWy4uLmNsYXNzZXNdKS50by5oYXZlLm1lbWJlcnMoWydiYXonLCAnYmFyJ10pO1xuICAgIGV4cGVjdCh0YWdzLnNpemUpLnRvLmVxdWFsKDEpO1xuICAgIGV4cGVjdChbLi4udGFnc10pLnRvLmhhdmUubWVtYmVycyhbJ2RpdiddKTtcbiAgfSk7XG59XG4iLCIvKipcbiAqIEltcG9ydGFudCBkb2NzOlxuICogLSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvXG4gKi9cbmltcG9ydCBwb3N0Y3NzIGZyb20gJ3Bvc3Rjc3MnO1xuaW1wb3J0IHBhcnNlciBmcm9tICdwb3N0Y3NzLXNlbGVjdG9yLXBhcnNlcic7XG5cbmltcG9ydCB7IGlzSW5zaWRlR2xvYmFsIH0gZnJvbSAnLi91dGlscy5qcyc7XG5cbmNvbnN0IFNFUCA9ICdfXyc7XG5cbmZ1bmN0aW9uIGlzUnVsZShub2RlKSB7XG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdydWxlJztcbn1cblxuZnVuY3Rpb24gaXNEZWNsYXJhdGlvbihub2RlKSB7XG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdkZWNsJztcbn1cblxuLyoqXG4gKiBOT1RFOiBcImtleWZyYW1lc1wiIGlzIGEgc2luZ3VsYXIgZGVmaW5pdGlvbiwgaW4gdGhhdCBpdCdzIGEgYmxvY2sgY29udGFpbmluZyBrZXlmcmFtZXNcbiAqICAgICAgIHVzaW5nIGBAa2V5ZnJhbWVzIHt9YCB3aXRoIG9ubHkgb25lIHRoaW5nIG9uIHRoZSBpbnNpZGUgZG9lc24ndCBtYWtlIHNlbnNlLlxuICovXG5mdW5jdGlvbiByZXdyaXRlUmVmZXJlbmNhYmxlKG5vZGUsIHBvc3RmaXgpIHtcbiAgbGV0IG9yaWdpbmFsTmFtZSA9IG5vZGUucGFyYW1zO1xuICBsZXQgcG9zdGZpeGVkTmFtZSA9IG5vZGUucGFyYW1zICsgU0VQICsgcG9zdGZpeDtcblxuICBub2RlLnBhcmFtcyA9IHBvc3RmaXhlZE5hbWU7XG5cbiAgcmV0dXJuIHtcbiAgICBvcmlnaW5hbE5hbWUsXG4gICAgcG9zdGZpeGVkTmFtZSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmV3cml0ZVNlbGVjdG9yKHNlbCwgcG9zdGZpeCkge1xuICBjb25zdCB0cmFuc2Zvcm0gPSAoc2VsZWN0b3JzKSA9PiB7XG4gICAgc2VsZWN0b3JzLndhbGsoKHNlbGVjdG9yKSA9PiB7XG4gICAgICBpZiAoaXNJbnNpZGVHbG9iYWwoc2VsZWN0b3IpKSByZXR1cm47XG5cbiAgICAgIC8vIFdlIG5ldmVyIHdhbnQgdG8gdG91Y2ggcHN1ZWRvIHNlbGVjdG9ycyBzaW5jZSB3ZSBhbmQgdGhlIHVzZXIgZG9lc24ndCBvd24gdGhlbS5cbiAgICAgIGlmIChzZWxlY3Rvci50eXBlID09PSAncHN1ZWRvJykgcmV0dXJuO1xuXG4gICAgICAvLyA6bnRoLW9mLXR5cGUgaGFzIHNwZWNpYWwgc3ludGF4IHdoZXJlIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIG50aC1vZi10eXBlKClcbiAgICAgIC8vIG11c3QgZWl0aGVyIGJlIGV4YWN0bHkgXCJvZGRcIiwgXCJldmVuXCIsIG9yIGEgc2ltcGxlIGZvcm11bGFcbiAgICAgIC8vXG4gICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvOm50aC1vZi10eXBlXG4gICAgICBpZiAoaXNOdGhPZlR5cGUoc2VsZWN0b3IpKSByZXR1cm47XG5cbiAgICAgIGlmIChzZWxlY3Rvci50eXBlID09PSAnY2xhc3MnKSB7XG4gICAgICAgIHNlbGVjdG9yLnZhbHVlICs9ICdfJyArIHBvc3RmaXg7XG4gICAgICB9IGVsc2UgaWYgKHNlbGVjdG9yLnR5cGUgPT09ICd0YWcnKSB7XG4gICAgICAgIHNlbGVjdG9yLnJlcGxhY2VXaXRoKFxuICAgICAgICAgIHBhcnNlci50YWcoeyB2YWx1ZTogc2VsZWN0b3IudmFsdWUgfSksXG4gICAgICAgICAgcGFyc2VyLmNsYXNzTmFtZSh7IHZhbHVlOiBwb3N0Zml4IH0pLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gcmVtb3ZlIDpnbG9iYWxcbiAgICBzZWxlY3RvcnMud2Fsaygoc2VsZWN0b3IpID0+IHtcbiAgICAgIGlmIChzZWxlY3Rvci50eXBlID09PSAncHNldWRvJyAmJiBzZWxlY3Rvci52YWx1ZSA9PT0gJzpnbG9iYWwnKSB7XG4gICAgICAgIHNlbGVjdG9yLnJlcGxhY2VXaXRoKC4uLnNlbGVjdG9yLm5vZGVzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbiAgY29uc3QgdHJhbnNmb3JtZWQgPSBwYXJzZXIodHJhbnNmb3JtKS5wcm9jZXNzU3luYyhzZWwpO1xuXG4gIHJldHVybiB0cmFuc2Zvcm1lZDtcbn1cblxuZnVuY3Rpb24gaXNOdGhPZlR5cGUobm9kZSkge1xuICBpZiAoIW5vZGUpIHJldHVybiBmYWxzZTtcblxuICByZXR1cm4gbm9kZS5wYXJlbnQ/LnZhbHVlID09PSAnOm50aC1vZi10eXBlJyB8fCBpc050aE9mVHlwZShub2RlLnBhcmVudCk7XG59XG5cbmZ1bmN0aW9uIGlzSW5zaWRlS2V5ZnJhbWVzKG5vZGUpIHtcbiAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnQ7XG5cbiAgaWYgKCFwYXJlbnQpIHJldHVybiBmYWxzZTtcbiAgaWYgKHBhcmVudC50eXBlID09PSAnYXRydWxlJyAmJiBwYXJlbnQubmFtZSA9PT0gJ2tleWZyYW1lcycpIHJldHVybiB0cnVlO1xuXG4gIHJldHVybiBpc0luc2lkZUtleWZyYW1lcyhwYXJlbnQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmV3cml0ZUNzcyhjc3MsIHBvc3RmaXgsIGZpbGVOYW1lLCBsYXllck5hbWUpIHtcbiAgY29uc3QgYXN0ID0gcG9zdGNzcy5wYXJzZShjc3MpO1xuICAvKipcbiAgICoga2luZCA9PiBvcmlnaW5hbE5hbWUgPT4gcG9zdGZpeGVkTmFtZVxuICAgKiBAdHlwZSB7eyBba2luZDogc3RyaW5nXTogeyBbb3JpZ2luYWxOYW1lOiBzdHJpbmddOiBzdHJpbmcgfX19XG4gICAqL1xuICBjb25zdCByZWZlcmVuY2FibGVzID0ge1xuICAgIGtleWZyYW1lczoge30sXG4gICAgJ2NvdW50ZXItc3R5bGUnOiB7fSxcbiAgICAncG9zaXRpb24tdHJ5Jzoge30sXG4gICAgcHJvcGVydHk6IHt9LFxuICB9O1xuXG4gIGNvbnN0IGF2YWlsYWJsZVJlZmVyZW5jYWJsZXMgPSBuZXcgU2V0KE9iamVjdC5rZXlzKHJlZmVyZW5jYWJsZXMpKTtcblxuICBmdW5jdGlvbiBpc1JlZmVyZW5jYWJsZShub2RlKSB7XG4gICAgaWYgKG5vZGUudHlwZSAhPT0gJ2F0cnVsZScpIHJldHVybjtcblxuICAgIHJldHVybiBhdmFpbGFibGVSZWZlcmVuY2FibGVzLmhhcyhub2RlLm5hbWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlRGlyZWN0UmVmZXJlbmNlcyhub2RlKSB7XG4gICAgaWYgKCFub2RlLnZhbHVlKSByZXR1cm47XG5cbiAgICBmb3IgKGxldCBbLCBtYXBdIG9mIE9iamVjdC5lbnRyaWVzKHJlZmVyZW5jYWJsZXMpKSB7XG4gICAgICBpZiAobWFwW25vZGUudmFsdWVdKSB7XG4gICAgICAgIG5vZGUudmFsdWUgPSBtYXBbbm9kZS52YWx1ZV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlU2hvcnRoYW5kQ29udGVudHMobm9kZSkge1xuICAgIGlmIChub2RlLnByb3AgPT09ICdhbmltYXRpb24nKSB7XG4gICAgICBsZXQgcGFydHMgPSBub2RlLnZhbHVlLnNwbGl0KCcgJyk7XG4gICAgICBsZXQgbWF0Y2ggPSBwYXJ0cy5maWx0ZXIoKHgpID0+IHJlZmVyZW5jYWJsZXMua2V5ZnJhbWVzW3hdKTtcblxuICAgICAgaWYgKG1hdGNoLmxlbmd0aCkge1xuICAgICAgICBtYXRjaC5mb3JFYWNoKCh4KSA9PiB7XG4gICAgICAgICAgbGV0IHJlcGxhY2VtZW50ID0gcmVmZXJlbmNhYmxlcy5rZXlmcmFtZXNbeF07XG5cbiAgICAgICAgICBpZiAoIXJlcGxhY2VtZW50KSByZXR1cm47XG5cbiAgICAgICAgICBub2RlLnZhbHVlID0gbm9kZS52YWx1ZS5yZXBsYWNlKHgsIHJlcGxhY2VtZW50KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgW2xvb2tGb3IsIHJlcGxhY2VXaXRoXSBvZiBPYmplY3QuZW50cmllcyhyZWZlcmVuY2FibGVzLnByb3BlcnR5KSkge1xuICAgICAgbGV0IGxvb2tGb3JWYXIgPSBgdmFyKCR7bG9va0Zvcn0pYDtcbiAgICAgIGxldCByZXBsYWNlV2l0aFZhciA9IGB2YXIoJHtyZXBsYWNlV2l0aH0pYDtcblxuICAgICAgbm9kZS52YWx1ZSA9IG5vZGUudmFsdWUucmVwbGFjZShsb29rRm9yVmFyLCByZXBsYWNlV2l0aFZhcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFdlIGhhdmUgdG8gZG8gdHdvIHBhc3NlczpcbiAgICogMS4gcG9zdGZpeCBhbGwgdGhlIHJlZmVyZW5jYWJsZSBzeW50YXhcbiAgICogMi4gcG9zdGZpeCBhcyBub3JtYWwsIGJ1dCBhbHNvIGNoZWNraW5nIHZhbHVlcyBvZiBDU1MgcHJvcGVydGllc1xuICAgKiAgICB0aGF0IGNvdWxkIG1hdGNoIHBvc3RmaXhlZCByZWZlcmVuY2FibGVzIGZyb20gc3RlcCAxXG4gICAqL1xuXG4gIC8vIFN0ZXAgMTogZmluZCByZWZlcmVuY2FibGVzXG4gIGFzdC53YWxrKChub2RlKSA9PiB7XG4gICAgLyoqXG4gICAgICogQGtleWZyYW1lcywgQGNvdW50ZXItc3R5bGUsIGV0Y1xuICAgICAqL1xuICAgIGlmIChpc1JlZmVyZW5jYWJsZShub2RlKSkge1xuICAgICAgbGV0IG5hbWUgPSBub2RlLm5hbWU7XG4gICAgICBsZXQgeyBvcmlnaW5hbE5hbWUsIHBvc3RmaXhlZE5hbWUgfSA9IHJld3JpdGVSZWZlcmVuY2FibGUobm9kZSwgcG9zdGZpeCk7XG5cbiAgICAgIHJlZmVyZW5jYWJsZXNbbmFtZV1bb3JpZ2luYWxOYW1lXSA9IHBvc3RmaXhlZE5hbWU7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIFN0ZXAgMjogcG9zdGZpeCBhbmQgdXBkYXRlIHJlZmVuY2VkIHJlZmVyZW5jYWJsZXNcbiAgYXN0LndhbGsoKG5vZGUpID0+IHtcbiAgICBpZiAoaXNEZWNsYXJhdGlvbihub2RlKSkge1xuICAgICAgdXBkYXRlRGlyZWN0UmVmZXJlbmNlcyhub2RlKTtcbiAgICAgIHVwZGF0ZVNob3J0aGFuZENvbnRlbnRzKG5vZGUpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGlzUnVsZShub2RlKSkge1xuICAgICAgLyoqXG4gICAgICAgKiBUaGUgaW5uZXItY29udGVudHMgb2YgYSBrZXlmcmFtZSBhcmUgcGVyY2VudGFnZXMsIHJhdGhlciB0aGFuIHNlbGVjdG9yc1xuICAgICAgICovXG4gICAgICBpZiAoaXNJbnNpZGVLZXlmcmFtZXMobm9kZSkpIHJldHVybjtcblxuICAgICAgbm9kZS5zZWxlY3RvciA9IHJld3JpdGVTZWxlY3Rvcihub2RlLnNlbGVjdG9yLCBwb3N0Zml4KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfSk7XG5cbiAgY29uc3QgcmV3cml0dGVuQ3NzID0gYXN0LnRvU3RyaW5nKCk7XG5cbiAgcmV0dXJuIChcbiAgICBbXG4gICAgICBgLyogJHtmaWxlTmFtZX0gKi9gLFxuICAgICAgbGF5ZXJOYW1lID8gYEBsYXllciAke2xheWVyTmFtZX0ge2AgOiAnJyxcbiAgICAgIHJld3JpdHRlbkNzcy50cmltRW5kKCksXG4gICAgICBsYXllck5hbWUgPyBgfWAgOiAnJyxcbiAgICBdXG4gICAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgICAuam9pbignXFxuJykgKyAnXFxuJ1xuICApO1xufVxuIiwiaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcblxuY29uc3QgS0VZID0gJ2VtYmVyLXNjb3BlZC5jc3MnO1xuY29uc3QgU0VQID0gJ19fXyc7XG5cbmV4cG9ydCBjb25zdCByZXF1ZXN0ID0ge1xuICBpczoge1xuICAgIGlubGluZShyZXF1ZXN0KSB7XG4gICAgICByZXR1cm4gcmVxdWVzdC5pbmNsdWRlcyhLRVkpO1xuICAgIH0sXG4gICAgY29sb2NhdGVkKHJlcXVlc3QpIHtcbiAgICAgIHJldHVybiByZXF1ZXN0LmluY2x1ZGVzKCcuY3NzP3Njb3BlZD0nKTtcbiAgICB9LFxuICB9LFxuICBpbmxpbmU6IHtcbiAgICAvKipcbiAgICAgKiBNYWtlcyByZXF1ZXN0IFVSTCBmb3IgZW1iZWRkaW5nIGA8c3R5bGU+YCBhcyBgPGxpbms+YCBpbnRvIHRoZSBgPGhlYWQ+YFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNzc0hhc2ggdGhlIGhhc2ggb2YgdGhlIENTUyBjb250ZW50c1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwb3N0Zml4IHRoZSBoYXNoIG9mIHRoZSBmaWxlIHRoYXQgX2luY2x1ZGVzXyB0aGUgbGlua2VkIGZpbGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY3NzQ29udGVudHMgdGhlIGNvbnRlbnRzIG9mIHRoZSBDU1MgZmlsZVxuICAgICAqL1xuICAgIGNyZWF0ZShjc3NIYXNoLCBwb3N0Zml4LCBjc3NDb250ZW50cykge1xuICAgICAgcmV0dXJuIGAuLyR7cG9zdGZpeH0ke1NFUH0ke2Nzc0hhc2h9LiR7S0VZfT9jc3M9JHtlbmNvZGVVUklDb21wb25lbnQoY3NzQ29udGVudHMpfWA7XG4gICAgfSxcbiAgICBkZWNvZGUocmVxdWVzdCkge1xuICAgICAgbGV0IFtsZWZ0LCBxcHNdID0gcmVxdWVzdC5zcGxpdCgnPycpO1xuXG4gICAgICBsZWZ0ID0gbGVmdC5zbGljZSgyKS5yZXBsYWNlKGAuJHtLRVl9YCwgJycpO1xuXG4gICAgICBsZXQgW3Bvc3RmaXgsIGhhc2hdID0gbGVmdC5zcGxpdChTRVApO1xuXG4gICAgICBsZXQgc2VhcmNoID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhxcHMpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBoYXNoLFxuICAgICAgICBwb3N0Zml4LFxuICAgICAgICBjc3M6IHNlYXJjaC5nZXQoJ2NzcycpLFxuICAgICAgICBmcm9tOiBzZWFyY2guZ2V0KCdmcm9tJyksXG4gICAgICB9O1xuICAgIH0sXG4gIH0sXG4gIGNvbG9jYXRlZDoge1xuICAgIC8qKlxuICAgICAqIE1ha2VzIHJlcXVlc3QgVVJMIGZvciBlbWJlZGRpbmcgc2VwYXJhdGUgQ1NTIEZpbGUgYXMgYDxsaW5rPmAgaW50byB0aGUgYDxoZWFkPmBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjc3NIYXNoIHRoZSBoYXNoIG9mIHRoZSBDU1MgY29udGVudHNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcG9zdGZpeCB0aGUgaGFzaCBvZiB0aGUgZmlsZSB0aGF0IF9pbmNsdWRlc18gdGhlIGxpbmtlZCBmaWxlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoIHBhdGggdG8gdGhlIHNlcGFyYXRlIENTUyBGaWxlXG4gICAgICovXG4gICAgY3JlYXRlKGNzc0hhc2gsIHBvc3RmaXgsIGZpbGVQYXRoKSB7XG4gICAgICByZXR1cm4gYC4vJHtwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKX0/c2NvcGVkPSR7cG9zdGZpeH0mY3NzSGFzaD0ke2Nzc0hhc2h9YDtcbiAgICB9LFxuICAgIGRlY29kZShyZXF1ZXN0KSB7XG4gICAgICBjb25zdCBbZmlsZU5hbWUsIHFzXSA9IHJlcXVlc3Quc3BsaXQoJz8nKTtcbiAgICAgIGNvbnN0IHNlYXJjaCA9IG5ldyBVUkxTZWFyY2hQYXJhbXMocXMpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBmaWxlTmFtZSxcbiAgICAgICAgY3NzSGFzaDogc2VhcmNoLmdldCgnY3NzSGFzaCcpLFxuICAgICAgICBwb3N0Zml4OiBzZWFyY2guZ2V0KCdzY29wZWQnKSxcbiAgICAgIH07XG4gICAgfSxcbiAgfSxcbn07XG4iLCJpbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tICdub2RlOmZzJztcbmltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB7IHJld3JpdGVDc3MgfSBmcm9tICcuLi9saWIvY3NzL3Jld3JpdGUuanMnO1xuaW1wb3J0IHsgcmVxdWVzdCB9IGZyb20gJy4uL2xpYi9yZXF1ZXN0LmpzJztcblxuY29uc3QgTUVUQSA9ICdzY29wZWQtY3NzOmNvbG9jYXRlZCc7XG5cbi8qKlxuICogUGx1Z2luIGZvciBzdXBwb3J0aW5nIGNvbG9jYXRlZCBzdHlsZXNcbiAqXG4gKiBlLmcuOlxuICogIHNyYy9jb21wb25lbnRzL215LWNvbXBvbmVudC5qc1xuICogIHNyYy9jb21wb25lbnRzL215LWNvbXBvbmVudC5jc3NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbG9jYXRlZChvcHRpb25zID0ge30pIHtcbiAgY29uc3QgQ1dEID0gcHJvY2Vzcy5jd2QoKTtcblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGlkIHRoZSByZXF1ZXN0IGlkIC8gd2hhdCB3YXMgaW1wb3J0ZWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoICBwYXRoIG9uIGRpc2tcbiAgICogQHJldHVybnNcbiAgICovXG4gIGZ1bmN0aW9uIGJ1aWxkUmVzcG9uc2UoaWQsIGZpbGVQYXRoKSB7XG4gICAgY29uc3QgcGFyc2VkID0gcmVxdWVzdC5jb2xvY2F0ZWQuZGVjb2RlKGlkKTtcbiAgICBjb25zdCByZWxhdGl2ZUZpbGVQYXRoID0gcGF0aC5yZWxhdGl2ZShDV0QsIGZpbGVQYXRoKTtcblxuICAgIHJldHVybiB7XG4gICAgICBpZDogZmlsZVBhdGgsXG4gICAgICBtZXRhOiB7XG4gICAgICAgIFtNRVRBXToge1xuICAgICAgICAgIHBvc3RmaXg6IHBhcnNlZC5wb3N0Zml4LFxuICAgICAgICAgIGZpbGVOYW1lOiByZWxhdGl2ZUZpbGVQYXRoLFxuICAgICAgICAgIGZ1bGxQYXRoOiBmaWxlUGF0aCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ2VtYmVyLXNjb3BlZC1jc3M6Y29sb2NhdGVkJyxcbiAgICByZXNvbHZlSWQoaWQsIGltcG9ydGVyKSB7XG4gICAgICAvLyBoYW5kbGVzOiBzb21lLWZpbGUuY3NzP3Njb3BlZD1bcG9zdGZpeF1cbiAgICAgIC8vIHRoaXMgaXMgb25seSBydW4gaW4gcm9sbHVwLCB2aXRlIGhhbmRsZXMgaXQgZGlmZmVyZW50bHlcbiAgICAgIGlmIChyZXF1ZXN0LmlzLmNvbG9jYXRlZChpZCkpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gcmVxdWVzdC5jb2xvY2F0ZWQuZGVjb2RlKGlkKTtcblxuICAgICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGgucmVzb2x2ZShcbiAgICAgICAgICBwYXRoLmRpcm5hbWUoaW1wb3J0ZXIpLFxuICAgICAgICAgIHBhdGguYmFzZW5hbWUocGFyc2VkLmZpbGVOYW1lKSxcbiAgICAgICAgKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUm9sbHVwIGRvZXNuJ3Qgbm9ybWFsbHkgd2F0Y2ggQ1NTIGZpbGVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFkZFdhdGNoRmlsZShmaWxlUGF0aCk7XG5cbiAgICAgICAgcmV0dXJuIGJ1aWxkUmVzcG9uc2UoaWQsIGZpbGVQYXRoKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGxvYWQoaWQpIHtcbiAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLmdldE1vZHVsZUluZm8oaWQpPy5tZXRhPy5bTUVUQV07XG5cbiAgICAgIGlmIChtZXRhKSB7XG4gICAgICAgIGxldCBjb2RlID0gcmVhZEZpbGVTeW5jKG1ldGEuZnVsbFBhdGgsICd1dGYtOCcpO1xuXG4gICAgICAgIGxldCBjc3MgPSByZXdyaXRlQ3NzKFxuICAgICAgICAgIGNvZGUsXG4gICAgICAgICAgbWV0YS5wb3N0Zml4LFxuICAgICAgICAgIG1ldGEuZmlsZU5hbWUsXG4gICAgICAgICAgb3B0aW9ucy5sYXllck5hbWUsXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIGNzcztcbiAgICAgIH1cbiAgICB9LFxuICAgIHZpdGU6IHtcbiAgICAgIC8qKlxuICAgICAgICogVGhlcmUgbWF5IG5vdCBiZSBtZXRhIGZvciB0aGlzIHJlcXVlc3QgeWV0LlxuICAgICAgICpcbiAgICAgICAqIEBwYXJhbSB7Kn0gaWRcbiAgICAgICAqL1xuICAgICAgbG9hZChpZCkge1xuICAgICAgICBpZiAocmVxdWVzdC5pcy5jb2xvY2F0ZWQoaWQpKSB7XG4gICAgICAgICAgY29uc3QgcGFyc2VkID0gcmVxdWVzdC5jb2xvY2F0ZWQuZGVjb2RlKGlkKTtcblxuICAgICAgICAgIGxldCBjb2RlID0gcmVhZEZpbGVTeW5jKHBhcnNlZC5maWxlTmFtZSwgJ3V0Zi04Jyk7XG4gICAgICAgICAgbGV0IHJlbGF0aXZlRmlsZVBhdGggPSBwYXRoLnJlbGF0aXZlKENXRCwgcGFyc2VkLmZpbGVOYW1lKTtcblxuICAgICAgICAgIGxldCBjc3MgPSByZXdyaXRlQ3NzKFxuICAgICAgICAgICAgY29kZSxcbiAgICAgICAgICAgIHBhcnNlZC5wb3N0Zml4LFxuICAgICAgICAgICAgcmVsYXRpdmVGaWxlUGF0aCxcbiAgICAgICAgICAgIG9wdGlvbnMubGF5ZXJOYW1lLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICByZXR1cm4gY3NzO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gIH07XG59XG4iLCJpbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuXG5pbXBvcnQgeyByZXdyaXRlQ3NzIH0gZnJvbSAnLi4vbGliL2Nzcy9yZXdyaXRlLmpzJztcbmltcG9ydCB7IHJlcXVlc3QgfSBmcm9tICcuLi9saWIvcmVxdWVzdC5qcyc7XG5cbmNvbnN0IE1FVEEgPSAnc2NvcGVkLWNzczppbmxpbmUnO1xuXG4vKipcbiAqIFBsdWdpbiBmb3Igc3VwcG9ydGluZyB0aGUgc3R5bGVzIGZyb21cbiAqXG4gKiA8dGVtcGxhdGU+XG4gKiAgIDxzdHlsZT4uLi48L3N0eWxlPlxuICogPC90ZW1wbGF0ZT5cbiAqXG4gKiBUaGlzIHBsdWdpbiBjYW4ndCBoYXZlIEhNUiBmb3IgQ1NTIGJlY2F1c2UgY2hhbmdlcyB0byB0aGUgQ1NTIGNvbnRlbnQgYWx0ZXJzIHRoZSB0ZW1wbGF0ZSBjb250ZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmxpbmUob3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IENXRCA9IHByb2Nlc3MuY3dkKCk7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpZCB0aGUgcmVxdWVzdCBpZCAvIHdoYXQgd2FzIGltcG9ydGVkXG4gICAqL1xuICBmdW5jdGlvbiBidWlsZFJlc3BvbnNlKGlkLCBmaWxlUGF0aCkge1xuICAgIGNvbnN0IHBhcnNlZCA9IHJlcXVlc3QuaW5saW5lLmRlY29kZShpZCk7XG5cbiAgICBjb25zdCByZWxhdGl2ZUZpbGVQYXRoID0gcGF0aC5yZWxhdGl2ZShDV0QsIGZpbGVQYXRoKTtcblxuICAgIGNvbnN0IGNzcyA9IHJld3JpdGVDc3MoXG4gICAgICBwYXJzZWQuY3NzLFxuICAgICAgcGFyc2VkLnBvc3RmaXgsXG4gICAgICBgPGlubGluZT4vJHtyZWxhdGl2ZUZpbGVQYXRofWAsXG4gICAgICBvcHRpb25zLmxheWVyTmFtZSxcbiAgICApO1xuXG4gICAgY29uc3QgbmV4dElkID0gZmlsZVBhdGguc3BsaXQoJz8nKVswXTtcblxuICAgIHJldHVybiB7XG4gICAgICBpZDogbmV4dElkLFxuICAgICAgbWV0YToge1xuICAgICAgICBbTUVUQV06IHtcbiAgICAgICAgICBjc3MsXG4gICAgICAgICAgcG9zdGZpeDogcGFyc2VkLnBvc3RmaXgsXG4gICAgICAgICAgZmlsZU5hbWU6IHJlbGF0aXZlRmlsZVBhdGgsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdlbWJlci1zY29wZWQtY3NzOmlubGluZScsXG4gICAgcmVzb2x2ZUlkKGlkLCBpbXBvcnRlcikge1xuICAgICAgaWYgKHJlcXVlc3QuaXMuaW5saW5lKGlkKSkge1xuICAgICAgICBjb25zdCBwYXJzZWQgPSByZXF1ZXN0LmlubGluZS5kZWNvZGUoaWQpO1xuXG4gICAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5yZXNvbHZlKFxuICAgICAgICAgIHBhdGguZGlybmFtZShpbXBvcnRlciksXG4gICAgICAgICAgYCR7cGF0aC5iYXNlbmFtZShpbXBvcnRlciwgcGF0aC5leHRuYW1lKGltcG9ydGVyKSl9LSR7cGFyc2VkLmhhc2h9LmNzc2AsXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIGJ1aWxkUmVzcG9uc2UoaWQsIGZpbGVQYXRoKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGxvYWQoaWQpIHtcbiAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLmdldE1vZHVsZUluZm8oaWQpPy5tZXRhPy5bTUVUQV07XG5cbiAgICAgIGlmIChtZXRhKSB7XG4gICAgICAgIHJldHVybiBtZXRhLmNzcztcbiAgICAgIH1cbiAgICB9LFxuICB9O1xufVxuIiwiaW1wb3J0IHsgY3JlYXRlVW5wbHVnaW4gfSBmcm9tICd1bnBsdWdpbic7XG5cbmltcG9ydCB7IGNvbG9jYXRlZCB9IGZyb20gJy4vdW5wbHVnaW4tY29sb2NhdGVkLmpzJztcbmltcG9ydCB7IGlubGluZSB9IGZyb20gJy4vdW5wbHVnaW4taW5saW5lLmpzJztcblxuLyoqXG4gKiBUaGUgcGx1Z2luIHRoYXQgaGFuZGxlcyBDU1MgcmVxdWVzdHMgZm9yIGA8c3R5bGU+YCBlbGVtZW50cyBhbmQgdHJhbnNmb3Jtc1xuICogZm9yIGV4aXN0aW5nIGZpbGVzXG4gKlxuICogdml0ZTogQ1NTIGZpbGVzIGFyZSByZXNvbHZlZCBieSB2aXRlLiBXZSB1c2UgdGhlaXIgcmVzb2x2ZXIgdG8gYWxzbyBnZXRcbiAqICAgICAgIEhNUi4gVGhhdCBpcywgZm9yIGFsbCBub24tcGh5c2ljYWwgQ1NTIGZpbGVzLCB3ZSBleHRlbmQgdml0ZSBieSBvdXJcbiAqICAgICAgIHJlc29sdmVyIGFuZCBhbHNvIGNhbiBlbnJpY2ggbWV0YWRhdGEgdG8gaXQgKGZvciBiZXR0ZXIgZGVidWdnaW5nKVxuICovXG5leHBvcnQgY29uc3QgdW5wbHVnaW4gPSBjcmVhdGVVbnBsdWdpbigob3B0aW9ucyA9IHt9KSA9PiB7XG4gIHJldHVybiBbY29sb2NhdGVkKG9wdGlvbnMpLCBpbmxpbmUob3B0aW9ucyldO1xufSk7XG4iLCJpbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuXG5pbXBvcnQgeyBsZWFkaW5nU2xhc2hQYXRoIH0gZnJvbSAnLi9jb25zdC5qcyc7XG5pbXBvcnQgeyBmaW5kV29ya3NwYWNlUGF0aCB9IGZyb20gJy4vdXRpbHMuanMnO1xuXG4vKipcbiAqIHRlbXBsYXRlIHBsdWdpbnMgZG8gbm90IGhhbmQgdXMgdGhlIGNvcnJlY3QgZmlsZSBwYXRoLlxuICogYWRkaXRpb25hbGx5LCB3ZSBtYXkgbm90IGJlIGFibGUgdG8gcmVseSBvbiB0aGlzIGRhdGEgaW4gdGhlIGZ1dHVyZSxcbiAqIHNvIHRoaXMgZnVuY3Rpb25zIGFjdHMgYXMgYSBtZWFucyBvZiBub3JtYWxpemluZyBfd2hhdGV2ZXJfIHdlJ3JlIGdpdmVuXG4gKiBpbiB0aGUgZnV0dXJlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZVxuICogQHJldHVybnMge3N0cmluZ30gdGhlIGFic29sdXRlIHBhdGggdG8gdGhlIGZpbGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpeEZpbGVuYW1lKGZpbGVuYW1lKSB7XG4gIGxldCBmaWxlTmFtZSA9IGZpbGVuYW1lO1xuICBsZXQgd29ya3NwYWNlID0gZmluZFdvcmtzcGFjZVBhdGgoZmlsZU5hbWUpO1xuXG4gIC8qKlxuICAgKiBlbWJlci1zb3VyY2UgNS44OlxuICAgKiAtIHRoZSBmaWxlbmFtZSBsb29rcyBsaWtlIGFuIGFic29sdXRlIHBhdGgsIGJ1dCBzd2FwcGVkIG91dCB0aGUgJ2FwcCcgcGFydCBvZiB0aGUgcGF0aFxuICAgKiAgIHdpdGggdGhlIG1vZHVsZSBuYW1lLCBzbyB0aGUgZmlsZSBwYXRocyBuZXZlciBleGlzdCBvbiBkaXNrXG4gICAqXG4gICAqIC0gaW4gdml0ZSBhcHBzOlxuICAgKiAgIHRoZSAnYXBwJyBwYXJ0IF9tYXlfIGJlIGBzcmNgLCBzbyB3ZSBhbHNvIG5lZWQgdG8gZW5zdXJlIHRoYXQgYHNyY2AgaXMgZXhjbHVkZWQgYXMgd2VsbFxuICAgKi9cbiAgbGV0IGhhc0FwcERpciA9IGZpbGVOYW1lLmluY2x1ZGVzKHBhdGguam9pbih3b3Jrc3BhY2UsICdhcHAnKSk7XG4gIGxldCBoYXNTcmNEaXIgPSBmaWxlTmFtZS5pbmNsdWRlcyhwYXRoLmpvaW4od29ya3NwYWNlLCAnc3JjJykpO1xuXG4gIGlmIChcbiAgICAhKGhhc0FwcERpciB8fCBoYXNTcmNEaXIpICYmXG4gICAgIWZpbGVOYW1lLmluY2x1ZGVzKGxlYWRpbmdTbGFzaFBhdGguZW1icm9pZGVyRGlyKVxuICApIHtcbiAgICBsZXQgbWF5YmVNb2R1bGUgPSBmaWxlTmFtZS5yZXBsYWNlKHdvcmtzcGFjZSwgJycpO1xuICAgIGxldCBbbWF5YmVTY29wZSwgLi4ucmVzdF0gPSBtYXliZU1vZHVsZS5zcGxpdChwYXRoLnNlcCkuZmlsdGVyKEJvb2xlYW4pO1xuICAgIGxldCBwYXJ0cyA9IHJlc3Q7XG5cbiAgICBpZiAobWF5YmVTY29wZS5zdGFydHNXaXRoKCdAJykpIHtcbiAgICAgIGxldCBbLCAuLi5yZXN0ZXJdID0gcmVzdDtcblxuICAgICAgcGFydHMgPSByZXN0ZXI7XG4gICAgfVxuXG4gICAgbGV0IHJlbGF0aXZlID0gcGF0aC5qb2luKC4uLnBhcnRzKTtcblxuICAgIC8qKlxuICAgICAqIFdlIGRvbid0IGFjdHVhbGx5IGtub3cgaWYgdGhpcyBmaWxlIGlzIGFuIGFwcC5cbiAgICAgKiBpdCBjb3VsZCBiZSBhbiBhZGRvbiAodjEgb3IgdjIpXG4gICAgICpcbiAgICAgKiBTbyBoZXJlIHdlIGxvZyB0byBzZWUgaWYgd2UgaGF2ZSB1bmhhbmRsZWQgc2l0dWF0aW9ucy5cbiAgICAgKi9cbiAgICBsZXQgY2FuZGlkYXRlUGF0aCA9IHBhdGguam9pbih3b3Jrc3BhY2UsICdhcHAnLCByZWxhdGl2ZSk7XG5cbiAgICByZXR1cm4gY2FuZGlkYXRlUGF0aDtcbiAgfVxuXG4gIC8vIFRPRE86IHdoeSBhcmUgd2UgcGFzc2VkIGZpbGVzIHRvIG90aGVyIHByb2plY3RzP1xuICBpZiAoIWZpbGVOYW1lLmluY2x1ZGVzKHdvcmtzcGFjZSkpIHtcbiAgICByZXR1cm4gZmlsZU5hbWU7XG4gIH1cblxuICAvLyBGYWxsYmFjayB0byB3aGF0IHRoZSBwbHVnaW4gc3lzdGVtIGdpdmVzIHVzLlxuICAvLyBUaGlzIG1heSBiZSB3cm9uZywgYW5kIGlmIHdyb25nLCByZXZlYWxzXG4gIC8vIHVuaGFuZGxlZCBzY2VuYXJpb3Mgd2l0aCB0aGUgZmlsZSBuYW1lcyBpbiB0aGUgcGx1Z2luIGluZnJhXG4gIHJldHVybiBmaWxlTmFtZTtcbn1cbiIsIi8qKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWVcbiAqIEBwYXJhbSB7c3RyaW5nfSBwb3N0Zml4XG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSBbY2xhc3Nlc0luQ3NzXVxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmFtZUNsYXNzKGNsYXNzTmFtZSwgcG9zdGZpeCwgY2xhc3Nlc0luQ3NzKSB7XG4gIGNvbnN0IGNsYXNzZXMgPSBjbGFzc05hbWUuc3BsaXQoL1xccysvKTtcbiAgY29uc3QgcmVuYW1lZENsYXNzZXMgPSBjbGFzc2VzXG4gICAgLmZpbHRlcigoYykgPT4gYylcbiAgICAubWFwKChjKSA9PiBjLnRyaW0oKSlcbiAgICAubWFwKChjKSA9PiB7XG4gICAgICBpZiAoIWNsYXNzZXNJbkNzcyB8fCBjbGFzc2VzSW5Dc3MuaGFzKGMpKSB7XG4gICAgICAgIGlmIChjLmVuZHNXaXRoKHBvc3RmaXgpKSByZXR1cm4gYztcblxuICAgICAgICByZXR1cm4gYyArICdfJyArIHBvc3RmaXg7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjO1xuICAgIH0pXG4gICAgLmpvaW4oJyAnKTtcblxuICBjb25zdCByZW5hbWVkV2l0aFByZXNlcnZlZFNwYWNlcyA9IGNsYXNzTmFtZS5yZXBsYWNlKFxuICAgIGNsYXNzTmFtZS50cmltU3RhcnQoKS50cmltRW5kKCksXG4gICAgcmVuYW1lZENsYXNzZXMsXG4gICk7XG5cbiAgcmV0dXJuIHJlbmFtZWRXaXRoUHJlc2VydmVkU3BhY2VzO1xufVxuIiwiaW1wb3J0ICogYXMgcmVjYXN0IGZyb20gJ2VtYmVyLXRlbXBsYXRlLXJlY2FzdCc7XG5cbmltcG9ydCB7IHJlbmFtZUNsYXNzIH0gZnJvbSAnLi9yZW5hbWVDbGFzcy5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiB0ZW1wbGF0ZVBsdWdpbih7IGNsYXNzZXMsIHRhZ3MsIHBvc3RmaXggfSkge1xuICBsZXQgc3RhY2sgPSBbXTtcbiAgLy8gc2NvcGVkLWNsYXNzIGlzIGEgZ2xvYmFsIHdlIGFsbG93IGluIGhic1xuICAvLyBzY29wZWRDbGFzcyBpcyBpbXBvcnRhYmxlLCBhbmQgd2UnbGwgZXJyb3IgaWYgc29tZW9uZSB0cmllcyB0byByZW5hbWUgaXRcbiAgbGV0IHNjb3BlZENsYXNzQ2FuZGlkYXRlcyA9IFsnc2NvcGVkLWNsYXNzJywgJ3Njb3BlZENsYXNzJ107XG5cbiAgZnVuY3Rpb24gaXNTY29wZWRDbGFzcyhzdHIpIHtcbiAgICBpZiAoIXN0cikgcmV0dXJuIGZhbHNlO1xuXG4gICAgcmV0dXJuIHNjb3BlZENsYXNzQ2FuZGlkYXRlcy5zb21lKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZSA9PT0gc3RyKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgQXR0ck5vZGUobm9kZSkge1xuICAgICAgaWYgKG5vZGUubmFtZSA9PT0gJ2NsYXNzJykge1xuICAgICAgICBpZiAobm9kZS52YWx1ZS50eXBlID09PSAnVGV4dE5vZGUnICYmIG5vZGUudmFsdWUuY2hhcnMpIHtcbiAgICAgICAgICBjb25zdCByZW5hbWVkQ2xhc3MgPSByZW5hbWVDbGFzcyhub2RlLnZhbHVlLmNoYXJzLCBwb3N0Zml4LCBjbGFzc2VzKTtcblxuICAgICAgICAgIG5vZGUudmFsdWUuY2hhcnMgPSByZW5hbWVkQ2xhc3M7XG4gICAgICAgIH0gZWxzZSBpZiAobm9kZS52YWx1ZS50eXBlID09PSAnQ29uY2F0U3RhdGVtZW50Jykge1xuICAgICAgICAgIGZvciAobGV0IHBhcnQgb2Ygbm9kZS52YWx1ZS5wYXJ0cykge1xuICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ1RleHROb2RlJyAmJiBwYXJ0LmNoYXJzKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlbmFtZWRDbGFzcyA9IHJlbmFtZUNsYXNzKHBhcnQuY2hhcnMsIHBvc3RmaXgsIGNsYXNzZXMpO1xuXG4gICAgICAgICAgICAgIHBhcnQuY2hhcnMgPSByZW5hbWVkQ2xhc3M7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gJ011c3RhY2hlU3RhdGVtZW50Jykge1xuICAgICAgICAgICAgICByZWNhc3QudHJhdmVyc2UocGFydCwge1xuICAgICAgICAgICAgICAgIFN0cmluZ0xpdGVyYWwobm9kZSkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgcmVuYW1lZENsYXNzID0gcmVuYW1lQ2xhc3MoXG4gICAgICAgICAgICAgICAgICAgIG5vZGUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBvc3RmaXgsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzZXMsXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICBub2RlLnZhbHVlID0gcmVuYW1lZENsYXNzO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBFbGVtZW50Tm9kZShub2RlKSB7XG4gICAgICBpZiAodGFncy5oYXMobm9kZS50YWcpKSB7XG4gICAgICAgIC8vIGNoZWNrIGlmIGNsYXNzIGF0dHJpYnV0ZSBhbHJlYWR5IGV4aXN0c1xuICAgICAgICBjb25zdCBjbGFzc0F0dHIgPSBub2RlLmF0dHJpYnV0ZXMuZmluZCgoYXR0cikgPT4gYXR0ci5uYW1lID09PSAnY2xhc3MnKTtcblxuICAgICAgICBpZiAoY2xhc3NBdHRyKSB7XG4gICAgICAgICAgY2xhc3NBdHRyLnZhbHVlLmNoYXJzICs9ICcgJyArIHBvc3RmaXg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gcHVzaCBjbGFzcyBhdHRyaWJ1dGVcbiAgICAgICAgICBub2RlLmF0dHJpYnV0ZXMucHVzaChcbiAgICAgICAgICAgIHJlY2FzdC5idWlsZGVycy5hdHRyKCdjbGFzcycsIHJlY2FzdC5idWlsZGVycy50ZXh0KHBvc3RmaXgpKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIEFsbDoge1xuICAgICAgZW50ZXIobm9kZSkge1xuICAgICAgICBzdGFjay5wdXNoKG5vZGUpO1xuICAgICAgfSxcbiAgICAgIGV4aXQoKSB7XG4gICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgfSxcbiAgICB9LFxuXG4gICAgTXVzdGFjaGVTdGF0ZW1lbnQobm9kZSkge1xuICAgICAgbGV0IGNzc0NsYXNzO1xuXG4gICAgICBpZiAoXG4gICAgICAgIGlzU2NvcGVkQ2xhc3MoZ2V0VmFsdWUobm9kZS5wYXRoKSkgJiZcbiAgICAgICAgbm9kZS5wYXJhbXM/Lmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICBub2RlLnBhcmFtc1swXS50eXBlID09PSAnU3RyaW5nTGl0ZXJhbCdcbiAgICAgICkge1xuICAgICAgICBjc3NDbGFzcyA9IG5vZGUucGFyYW1zWzBdLnZhbHVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIGlzU2NvcGVkQ2xhc3MoZ2V0VmFsdWUobm9kZS5wYXRoPy5wYXRoKSkgJiZcbiAgICAgICAgbm9kZS5wYXRoPy5wYXJhbXM/Lmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICBub2RlLnBhdGg/LnBhcmFtc1swXS50eXBlID09PSAnU3RyaW5nTGl0ZXJhbCdcbiAgICAgICkge1xuICAgICAgICBjc3NDbGFzcyA9IG5vZGUucGF0aC5wYXJhbXNbMF0udmFsdWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChjc3NDbGFzcykge1xuICAgICAgICBjb25zdCB0ZXh0Tm9kZSA9IHJlY2FzdC5idWlsZGVycy50ZXh0KHJlbmFtZUNsYXNzKGNzc0NsYXNzLCBwb3N0Zml4KSk7XG4gICAgICAgIGNvbnN0IHBhcmVudCA9IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdO1xuXG4gICAgICAgIGlmIChwYXJlbnQ/LnR5cGUgPT09ICdBdHRyTm9kZScpIHtcbiAgICAgICAgICBwYXJlbnQucXVvdGVUeXBlID0gJ1wiJztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0ZXh0Tm9kZTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgU3ViRXhwcmVzc2lvbihub2RlKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGlzU2NvcGVkQ2xhc3MoZ2V0VmFsdWUobm9kZS5wYXRoKSkgJiZcbiAgICAgICAgbm9kZS5wYXJhbXM/Lmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICBub2RlLnBhcmFtc1swXS50eXBlID09PSAnU3RyaW5nTGl0ZXJhbCdcbiAgICAgICkge1xuICAgICAgICBjb25zdCBjc3NDbGFzcyA9IG5vZGUucGFyYW1zWzBdLnZhbHVlO1xuICAgICAgICBjb25zdCB0ZXh0Tm9kZSA9IHJlY2FzdC5idWlsZGVycy5saXRlcmFsKFxuICAgICAgICAgICdTdHJpbmdMaXRlcmFsJyxcbiAgICAgICAgICByZW5hbWVDbGFzcyhjc3NDbGFzcywgcG9zdGZpeCksXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIHRleHROb2RlO1xuICAgICAgfVxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldFZhbHVlKHBhdGgpIHtcbiAgaWYgKCFwYXRoKSByZXR1cm47XG5cbiAgaWYgKCd2YWx1ZScgaW4gcGF0aCkge1xuICAgIHJldHVybiBwYXRoLnZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIERlcHJlY2F0ZWQgaW4gZW1iZXIgNS45K1xuICAgKiAoc28gd2UgdXNlIHRoZSBhYm92ZSBmb3IgbmV3ZXIgZW1iZXJzKVxuICAgKi9cbiAgcmV0dXJuIHBhdGgub3JpZ2luYWw7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJld3JpdGVIYnMoaGJzLCBjbGFzc2VzLCB0YWdzLCBwb3N0Zml4KSB7XG4gIGxldCBhc3QgPSByZWNhc3QucGFyc2UoaGJzKTtcblxuICByZWNhc3QudHJhdmVyc2UoYXN0LCB0ZW1wbGF0ZVBsdWdpbih7IGNsYXNzZXMsIHRhZ3MsIHBvc3RmaXggfSkpO1xuXG4gIGxldCByZXN1bHQgPSByZWNhc3QucHJpbnQoYXN0KTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuIiwiLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAZ2xpbW1lci9zeW50YXgnKS5BU1RQbHVnaW59IEFTVFBsdWdpblxuICogQHR5cGVkZWYge2ltcG9ydCgnQGdsaW1tZXIvc3ludGF4JykuQVNUUGx1Z2luRW52aXJvbm1lbnR9IEFTVFBsdWdpbkVudmlyb25tZW50XG4gKlxuICovXG5cbmltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgeyByZXdyaXRlQ3NzIH0gZnJvbSAnLi4vbGliL2Nzcy9yZXdyaXRlLmpzJztcbmltcG9ydCB7IGdldENTU0NvbnRlbnRJbmZvLCBnZXRDU1NJbmZvIH0gZnJvbSAnLi4vbGliL2Nzcy91dGlscy5qcyc7XG5pbXBvcnQgeyBmaXhGaWxlbmFtZSB9IGZyb20gJy4uL2xpYi9wYXRoL3RlbXBsYXRlLXRyYW5zZm9ybS1wYXRocy5qcyc7XG5pbXBvcnQge1xuICBhcHBQYXRoLFxuICBjc3NQYXRoRm9yLFxuICBmb3JjZVBvc2l4LFxuICBoYXNoRnJvbU1vZHVsZVBhdGgsXG4gIGlzUmVsZXZhbnRGaWxlLFxufSBmcm9tICcuLi9saWIvcGF0aC91dGlscy5qcyc7XG5pbXBvcnQgeyByZXF1ZXN0IH0gZnJvbSAnLi4vbGliL3JlcXVlc3QuanMnO1xuaW1wb3J0IHsgdGVtcGxhdGVQbHVnaW4gfSBmcm9tICcuLi9saWIvcmV3cml0ZUhicy5qcyc7XG5cbmNvbnN0IG5vb3BQbHVnaW4gPSB7XG4gIG5hbWU6ICdlbWJlci1zY29wZWQtY3NzOm5vb3AnLFxuICB2aXNpdG9yOiB7fSxcbn07XG5cbi8qKlxuICogQHJldHVybnMge0FTVFBsdWdpbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVBsdWdpbihjb25maWcpIHtcbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7QVNUUGx1Z2luRW52aXJvbm1lbnR9IGVudlxuICAgKi9cbiAgcmV0dXJuIGZ1bmN0aW9uIHNjb3BlZENzcyhlbnYpIHtcbiAgICBsZXQgY3dkID0gcHJvY2Vzcy5jd2QoKTtcblxuICAgIGxldCBpc1JlbGV2YW50ID0gaXNSZWxldmFudEZpbGUoZW52LmZpbGVuYW1lLCB7XG4gICAgICBhZGRpdGlvbmFsUm9vdHM6IGNvbmZpZy5hZGRpdGlvbmFsUm9vdHMsXG4gICAgICBjd2QsXG4gICAgfSk7XG5cbiAgICBpZiAoIWlzUmVsZXZhbnQpIHtcbiAgICAgIHJldHVybiBub29wUGx1Z2luO1xuICAgIH1cblxuICAgIGxldCBhYnNvbHV0ZVBhdGggPSBmaXhGaWxlbmFtZShlbnYuZmlsZW5hbWUpO1xuICAgIGxldCBtb2R1bGVQYXRoID0gYXBwUGF0aChhYnNvbHV0ZVBhdGgpO1xuICAgIGxldCBwb3N0Zml4ID0gaGFzaEZyb21Nb2R1bGVQYXRoKG1vZHVsZVBhdGgpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGxpc3Qgb2YgbmFrZWQgdGFnIHNlbGVjdG9ycyBmb3VuZCBpbiB0aGUgQ1NTXG4gICAgICpcbiAgICAgKiBAdHlwZSB7U2V0PHN0cmluZz59XG4gICAgICovXG4gICAgbGV0IHNjb3BlZFRhZ3MgPSBuZXcgU2V0KCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbGlzdCBvZiBjbGFzc2VzIGZvdW5kIGluIHRoZSBDU1NcbiAgICAgKlxuICAgICAqIEB0eXBlIHtTZXQ8c3RyaW5nPn1cbiAgICAgKi9cbiAgICBsZXQgc2NvcGVkQ2xhc3NlcyA9IG5ldyBTZXQoKTtcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7eyB0YWdzOiBTZXQ8c3RyaW5nPjsgY2xhc3NlczogU2V0PHN0cmluZz4gfX0gaW5mb1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFkZEluZm8oaW5mbykge1xuICAgICAgZm9yIChsZXQgaXRlbSBvZiBpbmZvLnRhZ3MpIHtcbiAgICAgICAgc2NvcGVkVGFncy5hZGQoaXRlbSk7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGl0ZW0gb2YgaW5mby5jbGFzc2VzKSB7XG4gICAgICAgIHNjb3BlZENsYXNzZXMuYWRkKGl0ZW0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBjc3NQYXRoID0gY3NzUGF0aEZvcihhYnNvbHV0ZVBhdGgpO1xuICAgIGxldCBpbmZvID0gZ2V0Q1NTSW5mbyhjc3NQYXRoKTtcbiAgICBsZXQgbG9jYWxDc3NQYXRoID0gZm9yY2VQb3NpeChjc3NQYXRoLnJlcGxhY2UoY3dkICsgcGF0aC5zZXAsICcnKSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIHdpbGwgYmUgZmFsc2V5IGlmIHdlIGRvbid0IGhhdmUgYSBjby1sb2NhdGVkIENTUyBmaWxlLlxuICAgICAqIFdlJ2xsIHN0aWxsIHdhbnQgdG8gY2hlY2sgZm9yIGVtYmVkZGVkIDxzdHlsZSBzY29wZWQ+IHRhZ3MgdGhvdWdoLlxuICAgICAqL1xuICAgIGlmIChpbmZvKSB7XG4gICAgICBhZGRJbmZvKGluZm8pO1xuXG4gICAgICBsZXQgY3NzUmVxdWVzdCA9IHJlcXVlc3QuY29sb2NhdGVkLmNyZWF0ZShpbmZvLmlkLCBwb3N0Zml4LCBsb2NhbENzc1BhdGgpO1xuXG4gICAgICAvKipcbiAgICAgICAqIFdpdGggdGhpcyB3ZSBkb24ndCBuZWVkIGEgSlMgcGx1Z2luXG4gICAgICAgKi9cbiAgICAgIGVudi5tZXRhLmpzdXRpbHMuaW1wb3J0Rm9yU2lkZUVmZmVjdChjc3NSZXF1ZXN0KTtcbiAgICB9XG5cbiAgICBsZXQgdmlzaXRvcnMgPSB0ZW1wbGF0ZVBsdWdpbih7XG4gICAgICBjbGFzc2VzOiBzY29wZWRDbGFzc2VzLFxuICAgICAgdGFnczogc2NvcGVkVGFncyxcbiAgICAgIHBvc3RmaXgsXG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogJ2VtYmVyLXNjb3BlZC1jc3M6dGVtcGxhdGUtcGx1Z2luJyxcbiAgICAgIHZpc2l0b3I6IHtcbiAgICAgICAgLy8gU3RhY2sgTWFuYWdlclxuICAgICAgICAuLi52aXNpdG9ycyxcblxuICAgICAgICAvKipcbiAgICAgICAgICogV2UgaGF2ZSB0byBlYWdlcmx5IGdldCB0aGUgPHN0eWxlIHNjb3BlZD4gY29udGVudHMsIHNvIHdlIGNhbiBwcmUtcGFyc2VcbiAgICAgICAgICogdGhlIHRhZ3MgYW5kIGNsYXNzZXMgdG8gdGhlbiBwYXNzIHRvIHRoZSBvdGhlciB2aXNpdG9ycyBzbyB0aGF0IHRoZXkgY2FuXG4gICAgICAgICAqIGFwcHJvcHJpYXRlbHkgY2hhbmdlIG1hdGNoaW5nIGNsYXNzZXMgLyB0YWdzLlxuICAgICAgICAgKi9cbiAgICAgICAgVGVtcGxhdGUobm9kZSkge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFdlIG9ubHkgYWxsb3cgYSBzY29wZWQgPHN0eWxlPiBhdCB0aGUgcm9vdFxuICAgICAgICAgICAqL1xuICAgICAgICAgIGxldCBzdHlsZVRhZyA9IG5vZGUuYm9keS5maW5kKFxuICAgICAgICAgICAgKG4pID0+IG4udHlwZSA9PT0gJ0VsZW1lbnROb2RlJyAmJiBuLnRhZyA9PT0gJ3N0eWxlJyxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKGhhc1Njb3BlZEF0dHJpYnV0ZShzdHlsZVRhZykpIHtcbiAgICAgICAgICAgIGxldCBjc3MgPSB0ZXh0Q29udGVudChzdHlsZVRhZyk7XG4gICAgICAgICAgICBsZXQgaW5mbyA9IGdldENTU0NvbnRlbnRJbmZvKGNzcyk7XG5cbiAgICAgICAgICAgIGFkZEluZm8oaW5mbyk7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogVGhpcyB3aWxsIGJlIGhhbmRsZWQgaW4gRWxlbWVudE5vZGUgdHJhdmVyc2FsXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChoYXNJbmxpbmVBdHRyaWJ1dGUoc3R5bGVUYWcpKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IGNzc1JlcXVlc3QgPSByZXF1ZXN0LmlubGluZS5jcmVhdGUoaW5mby5pZCwgcG9zdGZpeCwgY3NzKTtcblxuICAgICAgICAgICAgZW52Lm1ldGEuanN1dGlscy5pbXBvcnRGb3JTaWRlRWZmZWN0KGNzc1JlcXVlc3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAvLyBWaXNpdG9ycyBicm9rZW4gb3V0IGxpa2UgdGhpcyBzbyB3ZSBjYW4gY29uZGl0aW9uYWxseVxuICAgICAgICAvLyBkZWJ1ZyBiYXNlZCBvbiBmaWxlIHBhdGguXG4gICAgICAgIEF0dHJOb2RlKC4uLmFyZ3MpIHtcbiAgICAgICAgICByZXR1cm4gdmlzaXRvcnMuQXR0ck5vZGUoLi4uYXJncyk7XG4gICAgICAgIH0sXG4gICAgICAgIEVsZW1lbnROb2RlKG5vZGUsIHdhbGtlcikge1xuICAgICAgICAgIC8vIGNsYXNzIGF0dHJpYnV0ZSBoYW5kbGluZ1xuICAgICAgICAgIHZpc2l0b3JzLkVsZW1lbnROb2RlKG5vZGUsIHdhbGtlcik7XG5cbiAgICAgICAgICBpZiAoaGFzU2NvcGVkQXR0cmlidXRlKG5vZGUpKSB7XG4gICAgICAgICAgICBpZiAod2Fsa2VyLnBhcmVudD8ubm9kZS50eXBlICE9PSAnVGVtcGxhdGUnKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAnPHN0eWxlIHNjb3BlZD4gdGFncyBtdXN0IGJlIGF0IHRoZSByb290IG9mIHRoZSB0ZW1wbGF0ZSwgdGhleSBjYW5ub3QgYmUgbmVzdGVkJyxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGhhc0lubGluZUF0dHJpYnV0ZShub2RlKSkge1xuICAgICAgICAgICAgICBsZXQgdGV4dCA9IHRleHRDb250ZW50KG5vZGUpO1xuICAgICAgICAgICAgICBsZXQgc2NvcGVkVGV4dCA9IHJld3JpdGVDc3MoXG4gICAgICAgICAgICAgICAgdGV4dCxcbiAgICAgICAgICAgICAgICBwb3N0Zml4LFxuICAgICAgICAgICAgICAgIGxvY2FsQ3NzUGF0aCxcbiAgICAgICAgICAgICAgICBjb25maWcubGF5ZXJOYW1lLFxuICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgKiBUcmF2ZXJzZSB0aGlzIGFuZCBhbGxvdyBpbnRlcnBvbGF0aW9uXG4gICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICBub2RlLmNoaWxkcmVuID0gW2Vudi5zeW50YXguYnVpbGRlcnMudGV4dChzY29wZWRUZXh0KV07XG5cbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZXR1cm5pbmcgbnVsbCByZW1vdmVzIHRoZSBub2RlXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaGFzSW5saW5lQXR0cmlidXRlKG5vZGUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgIGA8c3R5bGUgaW5saW5lPiBpcyBub3QgdmFsaWQuIFBsZWFzZSBhZGQgdGhlIHNjb3BlZCBhdHRyaWJ1dGU6IDxzdHlsZSBzY29wZWQgaW5saW5lPmAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgTXVzdGFjaGVTdGF0ZW1lbnQoLi4uYXJncykge1xuICAgICAgICAgIHJldHVybiB2aXNpdG9ycy5NdXN0YWNoZVN0YXRlbWVudCguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgU3ViRXhwcmVzc2lvbiguLi5hcmdzKSB7XG4gICAgICAgICAgcmV0dXJuIHZpc2l0b3JzLlN1YkV4cHJlc3Npb24oLi4uYXJncyk7XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH07XG59XG5cbi8qKlxuICogVGhhbmtzLCBDYXJkU3RhY2sgYW5kIEBlZjQgZm9yIHRoaXMgY29kZS5cbiAqL1xuY29uc3QgU0NPUEVEX0FUVFJJQlVURV9OQU1FID0gJ3Njb3BlZCc7XG5jb25zdCBJTkxJTkVfQVRUUklCVVRFX05BTUUgPSAnaW5saW5lJztcblxuZnVuY3Rpb24gaGFzU2NvcGVkQXR0cmlidXRlKG5vZGUpIHtcbiAgaWYgKCFub2RlKSByZXR1cm47XG4gIGlmIChub2RlLnRhZyAhPT0gJ3N0eWxlJykgcmV0dXJuO1xuICBpZiAobm9kZS50eXBlICE9PSAnRWxlbWVudE5vZGUnKSByZXR1cm47XG5cbiAgcmV0dXJuIG5vZGUuYXR0cmlidXRlcy5zb21lKFxuICAgIChhdHRyaWJ1dGUpID0+IGF0dHJpYnV0ZS5uYW1lID09PSBTQ09QRURfQVRUUklCVVRFX05BTUUsXG4gICk7XG59XG5cbmZ1bmN0aW9uIGhhc0lubGluZUF0dHJpYnV0ZShub2RlKSB7XG4gIGlmICghbm9kZSkgcmV0dXJuO1xuICBpZiAobm9kZS50YWcgIT09ICdzdHlsZScpIHJldHVybjtcbiAgaWYgKG5vZGUudHlwZSAhPT0gJ0VsZW1lbnROb2RlJykgcmV0dXJuO1xuXG4gIHJldHVybiBub2RlLmF0dHJpYnV0ZXMuc29tZShcbiAgICAoYXR0cmlidXRlKSA9PiBhdHRyaWJ1dGUubmFtZSA9PT0gSU5MSU5FX0FUVFJJQlVURV9OQU1FLFxuICApO1xufVxuXG5mdW5jdGlvbiB0ZXh0Q29udGVudChub2RlKSB7XG4gIGxldCB0ZXh0Q2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuLmZpbHRlcigoYykgPT4gYy50eXBlID09PSAnVGV4dE5vZGUnKTtcblxuICByZXR1cm4gdGV4dENoaWxkcmVuLm1hcCgoYykgPT4gYy5jaGFycykuam9pbignJyk7XG59XG4iLCJpbXBvcnQgKiBhcyBiYWJlbCBmcm9tICcuLi9iYWJlbC1wbHVnaW4uanMnO1xuaW1wb3J0IHsgdW5wbHVnaW4gfSBmcm9tICcuLi9zY29wZWQtY3NzLXVucGx1Z2luLmpzJztcbmltcG9ydCAqIGFzIHRlbXBsYXRlIGZyb20gJy4uL3RlbXBsYXRlLXBsdWdpbi5qcyc7XG5cbmV4cG9ydCBjb25zdCBzY29wZWRDU1MgPSB7XG4gIHZpdGU6IHVucGx1Z2luLnZpdGUsXG4gIHJvbGx1cDogdW5wbHVnaW4ucm9sbHVwLFxuICBiYWJlbDogYmFiZWwuc2NvcGVkQ1NTLFxuICB0ZW1wbGF0ZTogdGVtcGxhdGUuY3JlYXRlUGx1Z2luLFxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFNQSxNQUFhLG1CQUFtQjtDQUM5QixjQUFjLGFBQUssS0FBSyw0QkFBNEI7Q0FDcEQsYUFBYSxhQUFLLEtBQUssY0FBYztDQUNyQyxlQUFlLGFBQUssS0FBSyxlQUFlO0NBQ3hDLGNBQWMsYUFBSyxLQUFLLGNBQWM7Q0FDdEMsUUFBUSxhQUFLLEtBQUssVUFBVTtDQUM1QixLQUFLLGFBQUssS0FBSyxRQUFRO0NBQ3ZCLEtBQUssYUFBSyxLQUFLLFFBQVE7Q0FDeEI7QUFFRCxNQUFhLFdBQVcsRUFDdEIsU0FBUyxhQUFLLEtBQUsscUJBQXFCLEVBQ3pDOzs7Ozs7Ozs7Ozs7QUNZRCxTQUFTLFFBQVEsR0FBRyxHQUFHO0NBQ3JCLElBQUksT0FBTyxJQUFJLFVBQVcsSUFBSTtBQUc5QixTQUZXLEtBQUssT0FBTyxLQUFLLE9BQU8sT0FBTyxPQUUzQixLQUFPLE1BQU07Ozs7Ozs7OztBQVU5QixTQUFTLGNBQWMsS0FBSyxLQUFLO0FBQy9CLFFBQVEsT0FBTyxNQUFRLFFBQVMsS0FBSzs7Ozs7Ozs7Ozs7OztBQWN2QyxTQUFTLE9BQU8sR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUc7QUFDaEMsUUFBTyxRQUFRLGNBQWMsUUFBUSxRQUFRLEdBQUcsRUFBRSxFQUFFLFFBQVEsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRTs7Ozs7Ozs7Ozs7Ozs7QUFlNUUsU0FBUyxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUc7QUFDbEMsUUFBTyxPQUFRLElBQUksSUFBTSxDQUFDLElBQUksR0FBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUU7Ozs7Ozs7Ozs7Ozs7O0FBZWxELFNBQVMsTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHO0FBQ2xDLFFBQU8sT0FBUSxJQUFJLElBQU0sSUFBSSxDQUFDLEdBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFOzs7Ozs7Ozs7Ozs7OztBQWVsRCxTQUFTLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztBQUNsQyxRQUFPLE9BQU8sSUFBSSxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFOzs7Ozs7Ozs7Ozs7OztBQWV6QyxTQUFTLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRztBQUNsQyxRQUFPLE9BQU8sS0FBSyxJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUU7Ozs7Ozs7OztBQVU1QyxTQUFTLFFBQVEsR0FBRyxLQUFLO0FBRXZCLEdBQUUsT0FBTyxNQUFNLE9BQVEsTUFBTTtBQUM3QixJQUFLLE1BQU0sT0FBUSxLQUFNLEtBQUssTUFBTTtDQUVwQyxJQUFJO0NBQ0osSUFBSTtDQUNKLElBQUk7Q0FDSixJQUFJO0NBQ0osSUFBSTtDQUNKLElBQUksSUFBSTtDQUNSLElBQUksSUFBSTtDQUNSLElBQUksSUFBSTtDQUNSLElBQUksSUFBSTtBQUVSLE1BQUssSUFBSSxHQUFHLElBQUksRUFBRSxRQUFRLEtBQUssSUFBSTtBQUNqQyxTQUFPO0FBQ1AsU0FBTztBQUNQLFNBQU87QUFDUCxTQUFPO0FBRVAsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEdBQUcsV0FBVztBQUMxQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFdBQVc7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxVQUFVO0FBQzlDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksWUFBWTtBQUNoRCxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLFdBQVc7QUFDOUMsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxXQUFXO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksWUFBWTtBQUNoRCxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFVBQVU7QUFDOUMsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxXQUFXO0FBQzlDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksWUFBWTtBQUNoRCxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLE9BQU87QUFDNUMsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxZQUFZO0FBQ2pELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLEdBQUcsV0FBVztBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFVBQVU7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxZQUFZO0FBQ2pELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksV0FBVztBQUVoRCxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLFdBQVc7QUFDOUMsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxZQUFZO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksVUFBVTtBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxXQUFXO0FBQzNDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsV0FBVztBQUM5QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxHQUFHLFNBQVM7QUFDN0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxXQUFXO0FBQ2hELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksV0FBVztBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLFVBQVU7QUFDN0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssR0FBRyxZQUFZO0FBQ2hELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksV0FBVztBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFdBQVc7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssR0FBRyxZQUFZO0FBQ2hELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsVUFBVTtBQUM3QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFdBQVc7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxZQUFZO0FBRWpELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsUUFBUTtBQUMzQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFlBQVk7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxXQUFXO0FBQ2hELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksVUFBVTtBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLFlBQVk7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxXQUFXO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksV0FBVztBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFlBQVk7QUFDakQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssR0FBRyxVQUFVO0FBQzlDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLFdBQVc7QUFDM0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxXQUFXO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksU0FBUztBQUM3QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLFdBQVc7QUFDOUMsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxXQUFXO0FBQ2hELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksVUFBVTtBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFdBQVc7QUFFL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEdBQUcsV0FBVztBQUMxQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFdBQVc7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxZQUFZO0FBQ2pELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksVUFBVTtBQUM5QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxHQUFHLFdBQVc7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxZQUFZO0FBQ2hELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksU0FBUztBQUM5QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFlBQVk7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxXQUFXO0FBQzlDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksVUFBVTtBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFlBQVk7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxXQUFXO0FBQ2hELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsV0FBVztBQUM5QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFlBQVk7QUFDakQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxVQUFVO0FBQzlDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVB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