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