@reliverse/dler 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/dist/cli.d.ts +2 -0
  2. package/dist/cli.js +3 -0
  3. package/dist/cmds/build/cmd.d.ts +2 -0
  4. package/dist/cmds/build/cmd.js +564 -0
  5. package/dist/cmds/clean/cmd.d.ts +2 -0
  6. package/dist/cmds/clean/cmd.js +146 -0
  7. package/dist/cmds/clean/impl.d.ts +2 -0
  8. package/dist/cmds/clean/impl.js +627 -0
  9. package/dist/cmds/clean/presets.d.ts +10 -0
  10. package/dist/cmds/clean/presets.js +112 -0
  11. package/dist/cmds/clean/types.d.ts +62 -0
  12. package/dist/cmds/clean/types.js +0 -0
  13. package/dist/cmds/init/cmd.d.ts +3 -0
  14. package/dist/cmds/init/cmd.js +56 -0
  15. package/dist/cmds/init/impl/config.d.ts +45 -0
  16. package/dist/cmds/init/impl/config.js +99 -0
  17. package/dist/cmds/init/impl/generators.d.ts +6 -0
  18. package/dist/cmds/init/impl/generators.js +178 -0
  19. package/dist/cmds/init/impl/prompts.d.ts +2 -0
  20. package/dist/cmds/init/impl/prompts.js +98 -0
  21. package/dist/cmds/init/impl/types.d.ts +22 -0
  22. package/dist/cmds/init/impl/types.js +0 -0
  23. package/dist/cmds/init/impl/utils.d.ts +4 -0
  24. package/dist/cmds/init/impl/utils.js +11 -0
  25. package/dist/cmds/init/impl/validators.d.ts +4 -0
  26. package/dist/cmds/init/impl/validators.js +42 -0
  27. package/dist/cmds/integrate/cmd.d.ts +3 -0
  28. package/dist/cmds/integrate/cmd.js +70 -0
  29. package/dist/cmds/integrate/impl.d.ts +7 -0
  30. package/dist/cmds/integrate/impl.js +127 -0
  31. package/dist/cmds/integrate/integrations/base.d.ts +13 -0
  32. package/dist/cmds/integrate/integrations/base.js +41 -0
  33. package/dist/cmds/integrate/integrations/nextjs.d.ts +16 -0
  34. package/dist/cmds/integrate/integrations/nextjs.js +167 -0
  35. package/dist/cmds/integrate/integrations/registry.d.ts +7 -0
  36. package/dist/cmds/integrate/integrations/registry.js +31 -0
  37. package/dist/cmds/integrate/integrations/ultracite.d.ts +11 -0
  38. package/dist/cmds/integrate/integrations/ultracite.js +40 -0
  39. package/dist/cmds/integrate/types.d.ts +39 -0
  40. package/dist/cmds/integrate/types.js +0 -0
  41. package/dist/cmds/integrate/utils/biome.d.ts +4 -0
  42. package/dist/cmds/integrate/utils/biome.js +140 -0
  43. package/dist/cmds/integrate/utils/context.d.ts +3 -0
  44. package/dist/cmds/integrate/utils/context.js +111 -0
  45. package/dist/cmds/integrate/utils/temp.d.ts +3 -0
  46. package/dist/cmds/integrate/utils/temp.js +36 -0
  47. package/dist/cmds/perf/analysis/bundle.d.ts +20 -0
  48. package/dist/cmds/perf/analysis/bundle.js +225 -0
  49. package/dist/cmds/perf/analysis/filesystem.d.ts +27 -0
  50. package/dist/cmds/perf/analysis/filesystem.js +246 -0
  51. package/dist/cmds/perf/analysis/monorepo.d.ts +29 -0
  52. package/dist/cmds/perf/analysis/monorepo.js +307 -0
  53. package/dist/cmds/perf/benchmarks/command.d.ts +21 -0
  54. package/dist/cmds/perf/benchmarks/command.js +162 -0
  55. package/dist/cmds/perf/benchmarks/memory.d.ts +41 -0
  56. package/dist/cmds/perf/benchmarks/memory.js +169 -0
  57. package/dist/cmds/perf/benchmarks/runner.d.ts +22 -0
  58. package/dist/cmds/perf/benchmarks/runner.js +157 -0
  59. package/dist/cmds/perf/cmd.d.ts +2 -0
  60. package/dist/cmds/perf/cmd.js +238 -0
  61. package/dist/cmds/perf/impl.d.ts +24 -0
  62. package/dist/cmds/perf/impl.js +304 -0
  63. package/dist/cmds/perf/reporters/console.d.ts +12 -0
  64. package/dist/cmds/perf/reporters/console.js +257 -0
  65. package/dist/cmds/perf/reporters/html.d.ts +27 -0
  66. package/dist/cmds/perf/reporters/html.js +881 -0
  67. package/dist/cmds/perf/reporters/json.d.ts +9 -0
  68. package/dist/cmds/perf/reporters/json.js +32 -0
  69. package/dist/cmds/perf/types.d.ts +184 -0
  70. package/dist/cmds/perf/types.js +0 -0
  71. package/dist/cmds/perf/utils/cache.d.ts +23 -0
  72. package/dist/cmds/perf/utils/cache.js +171 -0
  73. package/dist/cmds/perf/utils/formatter.d.ts +17 -0
  74. package/dist/cmds/perf/utils/formatter.js +134 -0
  75. package/dist/cmds/perf/utils/stats.d.ts +15 -0
  76. package/dist/cmds/perf/utils/stats.js +101 -0
  77. package/dist/cmds/publish/cmd.d.ts +3 -0
  78. package/dist/cmds/publish/cmd.js +189 -0
  79. package/dist/cmds/shell/cmd.d.ts +3 -0
  80. package/dist/cmds/shell/cmd.js +50 -0
  81. package/dist/cmds/tsc/cache.d.ts +27 -0
  82. package/dist/cmds/tsc/cache.js +160 -0
  83. package/dist/cmds/tsc/cmd.d.ts +2 -0
  84. package/dist/cmds/tsc/cmd.js +111 -0
  85. package/dist/cmds/tsc/impl.d.ts +41 -0
  86. package/dist/cmds/tsc/impl.js +572 -0
  87. package/dist/cmds/tsc/types.d.ts +57 -0
  88. package/dist/cmds/tsc/types.js +0 -0
  89. package/package.json +4 -11
  90. package/src/cli.ts +8 -0
  91. package/src/cmds/build/cmd.ts +582 -0
  92. package/src/cmds/clean/cmd.ts +166 -0
  93. package/src/cmds/clean/impl.ts +900 -0
  94. package/src/cmds/clean/presets.ts +158 -0
  95. package/src/cmds/clean/types.ts +71 -0
  96. package/src/cmds/init/cmd.ts +68 -0
  97. package/src/cmds/init/impl/config.ts +105 -0
  98. package/src/cmds/init/impl/generators.ts +220 -0
  99. package/src/cmds/init/impl/prompts.ts +137 -0
  100. package/src/cmds/init/impl/types.ts +25 -0
  101. package/src/cmds/init/impl/utils.ts +17 -0
  102. package/src/cmds/init/impl/validators.ts +55 -0
  103. package/src/cmds/integrate/cmd.ts +82 -0
  104. package/src/cmds/integrate/impl.ts +204 -0
  105. package/src/cmds/integrate/integrations/base.ts +69 -0
  106. package/src/cmds/integrate/integrations/nextjs.ts +227 -0
  107. package/src/cmds/integrate/integrations/registry.ts +45 -0
  108. package/src/cmds/integrate/integrations/ultracite.ts +53 -0
  109. package/src/cmds/integrate/types.ts +48 -0
  110. package/src/cmds/integrate/utils/biome.ts +173 -0
  111. package/src/cmds/integrate/utils/context.ts +148 -0
  112. package/src/cmds/integrate/utils/temp.ts +47 -0
  113. package/src/cmds/perf/analysis/bundle.ts +311 -0
  114. package/src/cmds/perf/analysis/filesystem.ts +324 -0
  115. package/src/cmds/perf/analysis/monorepo.ts +439 -0
  116. package/src/cmds/perf/benchmarks/command.ts +230 -0
  117. package/src/cmds/perf/benchmarks/memory.ts +249 -0
  118. package/src/cmds/perf/benchmarks/runner.ts +220 -0
  119. package/src/cmds/perf/cmd.ts +285 -0
  120. package/src/cmds/perf/impl.ts +411 -0
  121. package/src/cmds/perf/reporters/console.ts +331 -0
  122. package/src/cmds/perf/reporters/html.ts +984 -0
  123. package/src/cmds/perf/reporters/json.ts +42 -0
  124. package/src/cmds/perf/types.ts +220 -0
  125. package/src/cmds/perf/utils/cache.ts +234 -0
  126. package/src/cmds/perf/utils/formatter.ts +190 -0
  127. package/src/cmds/perf/utils/stats.ts +153 -0
  128. package/src/cmds/publish/cmd.ts +215 -0
  129. package/src/cmds/shell/cmd.ts +61 -0
  130. package/src/cmds/tsc/cache.ts +237 -0
  131. package/src/cmds/tsc/cmd.ts +139 -0
  132. package/src/cmds/tsc/impl.ts +855 -0
  133. package/src/cmds/tsc/types.ts +66 -0
  134. package/tsconfig.json +9 -0
  135. package/cli.js +0 -1316
package/cli.js DELETED
@@ -1,1316 +0,0 @@
1
- #!/usr/bin/env bun
2
- // @bun
3
-
4
- // packages/launcher/src/mod.ts
5
- import { dirname } from "path";
6
- import { fileURLToPath } from "url";
7
-
8
- // packages/helpers/src/impl/write.ts
9
- var textEncoder = new TextEncoder;
10
- var writeErrorLines = (lines) => {
11
- const buffer = new Array(lines.length + 1);
12
- for (let i = 0;i < lines.length; i++) {
13
- buffer[i] = lines[i];
14
- }
15
- buffer[lines.length] = "";
16
- const encoded = textEncoder.encode(buffer.join(`
17
- `));
18
- Bun.write(Bun.stderr, encoded);
19
- };
20
- // packages/colors/src/mod.ts
21
- var RESET = "\x1B[0m";
22
- var OP_SYMBOL = Symbol("re.ops");
23
- var COLOR_LEVEL_OFF = 0;
24
- var COLOR_LEVEL_BASIC = 1;
25
- var COLOR_LEVEL_256 = 2;
26
- var COLOR_LEVEL_TRUECOLOR = 3;
27
- var MIN_BYTE = 0;
28
- var MAX_BYTE = 255;
29
- var WHITE_RGB = 255;
30
- var ANSI_256_GRAYSCALE_MIN = 8;
31
- var ANSI_256_GRAYSCALE_MAX = 248;
32
- var ANSI_256_BASE_OFFSET = 16;
33
- var ANSI_256_GRAYSCALE_BASE = 232;
34
- var ANSI_256_GRAYSCALE_RANGE = 247;
35
- var ANSI_256_GRAYSCALE_STEPS = 24;
36
- var ANSI_256_BRIGHT_THRESHOLD = 231;
37
- var ANSI_256_RGB_LEVELS = 5;
38
- var ANSI_256_RGB_RED_MULTIPLIER = 36;
39
- var ANSI_256_RGB_GREEN_MULTIPLIER = 6;
40
- var SGR_FG_BASE = 30;
41
- var SGR_BG_BASE = 40;
42
- var SGR_FG_BRIGHT_BASE = 90;
43
- var SGR_BG_BRIGHT_BASE = 100;
44
- var SGR_RESET = 0;
45
- var SGR_BOLD = 1;
46
- var SGR_DIM = 2;
47
- var SGR_ITALIC = 3;
48
- var SGR_UNDERLINE = 4;
49
- var SGR_INVERSE = 7;
50
- var SGR_HIDDEN = 8;
51
- var SGR_STRIKETHROUGH = 9;
52
- var HEX_RADIX = 16;
53
- var BRIGHT_SUFFIX_LENGTH = 6;
54
- var BG_PREFIX_LENGTH = 2;
55
- var BRIGHT_MIX_FACTOR = 0.25;
56
- var BRIGHT_SUFFIX = "Bright";
57
- var IS_BUN = typeof process !== "undefined" && process.versions?.bun !== undefined && typeof Bun !== "undefined" && typeof Bun.color === "function";
58
- var CURRENT_LEVEL = COLOR_LEVEL_TRUECOLOR;
59
- var clampByte = (n) => {
60
- if (n <= MIN_BYTE || !Number.isFinite(n))
61
- return MIN_BYTE;
62
- if (n >= MAX_BYTE)
63
- return MAX_BYTE;
64
- return Math.round(n);
65
- };
66
- var BASIC8 = Object.freeze([
67
- Object.freeze({ r: 0, g: 0, b: 0 }),
68
- Object.freeze({ r: 205, g: 0, b: 0 }),
69
- Object.freeze({ r: 0, g: 205, b: 0 }),
70
- Object.freeze({ r: 205, g: 205, b: 0 }),
71
- Object.freeze({ r: 0, g: 0, b: 238 }),
72
- Object.freeze({ r: 205, g: 0, b: 205 }),
73
- Object.freeze({ r: 0, g: 205, b: 205 }),
74
- Object.freeze({ r: 229, g: 229, b: 229 })
75
- ]);
76
- var sgrCache = new Map;
77
- var sgr = (codes) => {
78
- if (codes.length === 1) {
79
- const code = codes[0];
80
- const cached2 = sgrCache.get(String(code));
81
- if (cached2)
82
- return cached2;
83
- const seq2 = `\x1B[${code}m`;
84
- sgrCache.set(String(code), seq2);
85
- return seq2;
86
- }
87
- const key = codes.join(";");
88
- const cached = sgrCache.get(key);
89
- if (cached)
90
- return cached;
91
- const seq = `\x1B[${key}m`;
92
- sgrCache.set(key, seq);
93
- return seq;
94
- };
95
- var nearestBasicIndex = (rgb) => {
96
- if (IS_BUN) {
97
- const ansiStr = Bun.color(rgb, "ansi-16");
98
- if (ansiStr) {
99
- const match = ansiStr.match(/38;5;(\d+)/);
100
- if (match?.[1]) {
101
- return Number.parseInt(match[1], 10) & 7;
102
- }
103
- }
104
- }
105
- let best = 0;
106
- let bestDist = Number.POSITIVE_INFINITY;
107
- for (let i = 0;i < 8; i++) {
108
- const c = BASIC8[i];
109
- const dr = c.r - rgb.r;
110
- const dg = c.g - rgb.g;
111
- const db = c.b - rgb.b;
112
- if (dr === 0 && dg === 0 && db === 0)
113
- return i;
114
- const d = dr * dr + dg * dg + db * db;
115
- if (d < bestDist) {
116
- bestDist = d;
117
- best = i;
118
- }
119
- }
120
- return best;
121
- };
122
- var rgbToAnsi256 = (rgb) => {
123
- if (IS_BUN) {
124
- const ansiStr = Bun.color(rgb, "ansi-256");
125
- if (ansiStr) {
126
- const match = ansiStr.match(/38;5;(\d+)/);
127
- if (match?.[1]) {
128
- return Number.parseInt(match[1], 10);
129
- }
130
- }
131
- }
132
- if (rgb.r === rgb.g && rgb.g === rgb.b) {
133
- if (rgb.r < ANSI_256_GRAYSCALE_MIN)
134
- return ANSI_256_BASE_OFFSET;
135
- if (rgb.r > ANSI_256_GRAYSCALE_MAX)
136
- return ANSI_256_BRIGHT_THRESHOLD;
137
- const step = Math.round((rgb.r - ANSI_256_GRAYSCALE_MIN) / ANSI_256_GRAYSCALE_RANGE * ANSI_256_GRAYSCALE_STEPS);
138
- return ANSI_256_GRAYSCALE_BASE + step;
139
- }
140
- const r = (rgb.r * ANSI_256_RGB_LEVELS + 127) / MAX_BYTE | 0;
141
- const g = (rgb.g * ANSI_256_RGB_LEVELS + 127) / MAX_BYTE | 0;
142
- const b = (rgb.b * ANSI_256_RGB_LEVELS + 127) / MAX_BYTE | 0;
143
- return ANSI_256_BASE_OFFSET + r * ANSI_256_RGB_RED_MULTIPLIER + g * ANSI_256_RGB_GREEN_MULTIPLIER + b;
144
- };
145
- var NAMED_COLORS = {
146
- black: "#000000",
147
- red: "#ff0000",
148
- green: "#00ff00",
149
- yellow: "#ffff00",
150
- blue: "#0000ff",
151
- magenta: "#ff00ff",
152
- cyan: "#00ffff",
153
- white: "#ffffff",
154
- gray: "#808080",
155
- orange: "#ffa500",
156
- pink: "#ffc0cb",
157
- purple: "#800080",
158
- teal: "#008080",
159
- lime: "#00ff00",
160
- brown: "#a52a2a",
161
- navy: "#000080",
162
- maroon: "#800000",
163
- olive: "#808000",
164
- silver: "#c0c0c0"
165
- };
166
- var rgbCache = new Map;
167
- for (const name of ["black", "white", "red", "green", "blue"]) {
168
- const hex = NAMED_COLORS[name];
169
- if (hex) {
170
- const clean = hex.slice(1);
171
- const r = Number.parseInt(clean.slice(0, 2), HEX_RADIX);
172
- const g = Number.parseInt(clean.slice(2, 4), HEX_RADIX);
173
- const b = Number.parseInt(clean.slice(4, 6), HEX_RADIX);
174
- rgbCache.set(name, Object.freeze({ r, g, b }));
175
- }
176
- }
177
- var mixWithWhite = (rgb, factor) => {
178
- const invFactor = 1 - factor;
179
- return {
180
- r: clampByte(rgb.r * invFactor + WHITE_RGB * factor),
181
- g: clampByte(rgb.g * invFactor + WHITE_RGB * factor),
182
- b: clampByte(rgb.b * invFactor + WHITE_RGB * factor)
183
- };
184
- };
185
- var fromNamed = (name) => {
186
- const cached = rgbCache.get(name);
187
- if (cached)
188
- return cached;
189
- const hex = NAMED_COLORS[name];
190
- if (!hex)
191
- return { r: 0, g: 0, b: 0 };
192
- if (IS_BUN) {
193
- const rgb = Bun.color(hex, "{rgb}");
194
- if (rgb) {
195
- rgbCache.set(name, rgb);
196
- return rgb;
197
- }
198
- }
199
- const clean = hex[0] === "#" ? hex.slice(1) : hex;
200
- const len = clean.length;
201
- let r, g, b;
202
- if (len === 3) {
203
- const rv = Number.parseInt(clean[0], HEX_RADIX);
204
- const gv = Number.parseInt(clean[1], HEX_RADIX);
205
- const bv = Number.parseInt(clean[2], HEX_RADIX);
206
- r = rv << 4 | rv;
207
- g = gv << 4 | gv;
208
- b = bv << 4 | bv;
209
- } else if (len === 6) {
210
- r = Number.parseInt(clean.slice(0, 2), HEX_RADIX);
211
- g = Number.parseInt(clean.slice(2, 4), HEX_RADIX);
212
- b = Number.parseInt(clean.slice(4, 6), HEX_RADIX);
213
- } else {
214
- return { r: 0, g: 0, b: 0 };
215
- }
216
- if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) {
217
- return { r: 0, g: 0, b: 0 };
218
- }
219
- const result = Object.freeze({ r, g, b });
220
- rgbCache.set(name, result);
221
- return result;
222
- };
223
- var toBaseName = (compound) => {
224
- if (!compound)
225
- return "black";
226
- const base = compound.slice(0, -BRIGHT_SUFFIX_LENGTH);
227
- if (!base)
228
- return "black";
229
- return base[0].toLowerCase() + base.slice(1);
230
- };
231
- var parseColorName = (name) => {
232
- if (!name)
233
- return { rgb: { r: 0, g: 0, b: 0 }, wantBright: false };
234
- if (name.endsWith(BRIGHT_SUFFIX)) {
235
- const base = toBaseName(name);
236
- const rgb = fromNamed(base);
237
- const rgbAdj = mixWithWhite(rgb, BRIGHT_MIX_FACTOR);
238
- return { rgb: rgbAdj, wantBright: true };
239
- }
240
- return { rgb: fromNamed(name), wantBright: false };
241
- };
242
- var openForOp = (op) => {
243
- if (CURRENT_LEVEL === COLOR_LEVEL_OFF)
244
- return "";
245
- switch (op.kind) {
246
- case "style":
247
- return sgr(op.open);
248
- case "fg-basic": {
249
- const code = (op.bright ? SGR_FG_BRIGHT_BASE : SGR_FG_BASE) + op.idx;
250
- return sgr([code]);
251
- }
252
- case "bg-basic": {
253
- const code = (op.bright ? SGR_BG_BRIGHT_BASE : SGR_BG_BASE) + op.idx;
254
- return sgr([code]);
255
- }
256
- case "fg-256": {
257
- if (IS_BUN) {
258
- const ansi = Bun.color(op.code, "ansi-256");
259
- if (ansi)
260
- return ansi;
261
- }
262
- return `\x1B[38;5;${op.code}m`;
263
- }
264
- case "bg-256": {
265
- if (IS_BUN) {
266
- const fgAnsi = Bun.color(op.code, "ansi-256");
267
- if (fgAnsi)
268
- return fgAnsi.replace("38;5;", "48;5;");
269
- }
270
- return `\x1B[48;5;${op.code}m`;
271
- }
272
- case "fg-true": {
273
- if (IS_BUN) {
274
- const ansi = Bun.color(op.rgb, "ansi-16m");
275
- if (ansi)
276
- return ansi;
277
- }
278
- const { r, g, b } = op.rgb;
279
- return `\x1B[38;2;${r};${g};${b}m`;
280
- }
281
- case "bg-true": {
282
- if (IS_BUN) {
283
- const fgAnsi = Bun.color(op.rgb, "ansi-16m");
284
- if (fgAnsi)
285
- return fgAnsi.replace("38;2;", "48;2;");
286
- }
287
- const { r, g, b } = op.rgb;
288
- return `\x1B[48;2;${r};${g};${b}m`;
289
- }
290
- default:
291
- return "";
292
- }
293
- };
294
- var opsToOpen = (ops) => {
295
- if (CURRENT_LEVEL === COLOR_LEVEL_OFF)
296
- return "";
297
- const len = ops.length;
298
- if (len === 0)
299
- return "";
300
- if (len === 1)
301
- return openForOp(ops[0]);
302
- let result = "";
303
- for (let i = 0;i < len; i++) {
304
- result += openForOp(ops[i]);
305
- }
306
- return result;
307
- };
308
- var applyOpsToText = (ops, input) => {
309
- const text = String(input);
310
- const textLen = text.length;
311
- if (CURRENT_LEVEL === COLOR_LEVEL_OFF || ops.length === 0 || textLen === 0) {
312
- return text;
313
- }
314
- const open = opsToOpen(ops);
315
- if (!open)
316
- return text;
317
- const nlIdx = text.indexOf(`
318
- `);
319
- if (nlIdx === -1) {
320
- return `${open}${text}${RESET}`;
321
- }
322
- let result = "";
323
- let start = 0;
324
- while (start < textLen) {
325
- const end = text.indexOf(`
326
- `, start);
327
- if (end === -1) {
328
- const line2 = text.slice(start);
329
- if (line2) {
330
- if (line2.endsWith("\r")) {
331
- result += `${open}${line2.slice(0, -1)}\r${RESET}`;
332
- } else {
333
- result += `${open}${line2}${RESET}`;
334
- }
335
- }
336
- break;
337
- }
338
- if (start > 0)
339
- result += `
340
- `;
341
- const line = text.slice(start, end);
342
- if (line) {
343
- if (line.endsWith("\r")) {
344
- result += `${open}${line.slice(0, -1)}\r${RESET}`;
345
- } else {
346
- result += `${open}${line}${RESET}`;
347
- }
348
- } else {
349
- result += `${open}${RESET}`;
350
- }
351
- start = end + 1;
352
- }
353
- return result;
354
- };
355
- var mkFgOpsFromRgb = (rgb, wantBright = false) => {
356
- if (CURRENT_LEVEL === COLOR_LEVEL_BASIC) {
357
- return [
358
- { kind: "fg-basic", idx: nearestBasicIndex(rgb), bright: wantBright }
359
- ];
360
- }
361
- if (CURRENT_LEVEL === COLOR_LEVEL_256) {
362
- return [{ kind: "fg-256", code: rgbToAnsi256(rgb) }];
363
- }
364
- return [{ kind: "fg-true", rgb }];
365
- };
366
- var mkBgOpsFromRgb = (rgb, wantBright = false) => {
367
- if (CURRENT_LEVEL === COLOR_LEVEL_BASIC) {
368
- return [
369
- { kind: "bg-basic", idx: nearestBasicIndex(rgb), bright: wantBright }
370
- ];
371
- }
372
- if (CURRENT_LEVEL === COLOR_LEVEL_256) {
373
- return [{ kind: "bg-256", code: rgbToAnsi256(rgb) }];
374
- }
375
- return [{ kind: "bg-true", rgb }];
376
- };
377
- var STYLE_TABLE = {
378
- reset: Object.freeze({ kind: "style", open: [SGR_RESET] }),
379
- bold: Object.freeze({ kind: "style", open: [SGR_BOLD] }),
380
- dim: Object.freeze({ kind: "style", open: [SGR_DIM] }),
381
- italic: Object.freeze({ kind: "style", open: [SGR_ITALIC] }),
382
- underline: Object.freeze({ kind: "style", open: [SGR_UNDERLINE] }),
383
- inverse: Object.freeze({ kind: "style", open: [SGR_INVERSE] }),
384
- hidden: Object.freeze({ kind: "style", open: [SGR_HIDDEN] }),
385
- strikethrough: Object.freeze({ kind: "style", open: [SGR_STRIKETHROUGH] })
386
- };
387
- var STYLE_KEYS = Object.freeze(new Set([
388
- "reset",
389
- "bold",
390
- "dim",
391
- "italic",
392
- "underline",
393
- "inverse",
394
- "hidden",
395
- "strikethrough"
396
- ]));
397
- var COLOR_KEYS = Object.freeze(new Set(Object.keys(NAMED_COLORS)));
398
- var BRIGHT_COLOR_KEYS = Object.freeze(new Set(Object.keys(NAMED_COLORS).map((name) => `${name}Bright`)));
399
- var BG_COLOR_KEYS = Object.freeze(new Set(Object.keys(NAMED_COLORS).map((name) => `bg${name[0].toUpperCase()}${name.slice(1)}`)));
400
- var BG_BRIGHT_COLOR_KEYS = Object.freeze(new Set(Object.keys(NAMED_COLORS).map((name) => `bg${name[0].toUpperCase()}${name.slice(1)}Bright`)));
401
- var isColorKey = (key) => COLOR_KEYS.has(key) || BRIGHT_COLOR_KEYS.has(key);
402
- var isBgKey = (key) => {
403
- const len = key.length;
404
- if (len <= BG_PREFIX_LENGTH || key[0] !== "b" || key[1] !== "g") {
405
- return false;
406
- }
407
- return BG_COLOR_KEYS.has(key) || BG_BRIGHT_COLOR_KEYS.has(key);
408
- };
409
- var proxyCache = new WeakMap;
410
- var callableProxy = (ops) => {
411
- const cached = proxyCache.get(ops);
412
- if (cached)
413
- return cached;
414
- const base = (input) => applyOpsToText(ops, input);
415
- Object.defineProperty(base, OP_SYMBOL, {
416
- value: ops,
417
- enumerable: false,
418
- configurable: false,
419
- writable: false
420
- });
421
- const proxy = new Proxy(base, {
422
- apply(_target, _thisArg, argArray) {
423
- return applyOpsToText(ops, argArray[0]);
424
- },
425
- get(_target, prop) {
426
- if (prop === OP_SYMBOL)
427
- return ops;
428
- const key = String(prop);
429
- if (STYLE_KEYS.has(key)) {
430
- const op = STYLE_TABLE[key];
431
- const newOps = [...ops, op];
432
- return callableProxy(newOps);
433
- }
434
- if (isBgKey(key)) {
435
- const colorName = key[2].toLowerCase() + key.slice(3);
436
- const { rgb, wantBright } = parseColorName(colorName);
437
- const bgOps = mkBgOpsFromRgb(rgb, wantBright);
438
- const newOps = [...ops, ...bgOps];
439
- return callableProxy(newOps);
440
- }
441
- if (isColorKey(key)) {
442
- const { rgb, wantBright } = parseColorName(key);
443
- const fgOps = mkFgOpsFromRgb(rgb, wantBright);
444
- const newOps = [...ops, ...fgOps];
445
- return callableProxy(newOps);
446
- }
447
- return proxy;
448
- }
449
- });
450
- proxyCache.set(ops, proxy);
451
- return proxy;
452
- };
453
- var re = callableProxy([]);
454
-
455
- // packages/logger/src/mod.ts
456
- var textEncoder2 = new TextEncoder;
457
- var LOG_COLORS = {
458
- log: re.white,
459
- error: re.red,
460
- warn: re.yellow,
461
- info: re.blue,
462
- success: re.green,
463
- debug: re.gray
464
- };
465
- var LOG_SYMBOLS = {
466
- log: "\u2502 ",
467
- error: "\u2716 ",
468
- warn: "\u26A0 ",
469
- info: "\u25A0 ",
470
- success: "\u2713 ",
471
- debug: "\u2731 "
472
- };
473
- var writeLock = Promise.resolve();
474
- var formatMessage = (...args) => args.map(String).join(" ");
475
- var createPrefixedMessage = (level, message) => `${LOG_SYMBOLS[level]}${message}`;
476
- var writeAsync = async (text, isError = false) => {
477
- const encoded = textEncoder2.encode(`${text}
478
- `);
479
- await writeLock;
480
- writeLock = Bun.write(isError ? Bun.stderr : Bun.stdout, encoded).then(() => {});
481
- await writeLock;
482
- };
483
- var writeSync = (text, isError = false) => {
484
- const encoded = textEncoder2.encode(`${text}
485
- `);
486
- (isError ? process.stderr : process.stdout).write(encoded);
487
- };
488
- var writeColoredAsync = async (text, color, isError = false) => {
489
- const coloredText = color(text);
490
- await writeAsync(coloredText, isError);
491
- };
492
- var writeColoredSync = (text, color, isError = false) => {
493
- const coloredText = color(text);
494
- writeSync(coloredText, isError);
495
- };
496
- function createLogMethod(level, isAsync, isError = false) {
497
- if (isAsync) {
498
- return async (...args) => {
499
- const message = formatMessage(...args);
500
- const prefixedMessage = createPrefixedMessage(level, message);
501
- await writeColoredAsync(prefixedMessage, LOG_COLORS[level], isError);
502
- };
503
- }
504
- return (...args) => {
505
- const message = formatMessage(...args);
506
- const prefixedMessage = createPrefixedMessage(level, message);
507
- writeColoredSync(prefixedMessage, LOG_COLORS[level], isError);
508
- };
509
- }
510
- function createRawMethod(isAsync) {
511
- if (isAsync) {
512
- return async (...args) => {
513
- const message = formatMessage(...args);
514
- await writeAsync(message);
515
- };
516
- }
517
- return (...args) => {
518
- const message = formatMessage(...args);
519
- writeSync(message);
520
- };
521
- }
522
- var loggerAsync = {
523
- log: createLogMethod("log", true),
524
- error: createLogMethod("error", true, true),
525
- warn: createLogMethod("warn", true),
526
- info: createLogMethod("info", true),
527
- success: createLogMethod("success", true),
528
- debug: createLogMethod("debug", true),
529
- raw: createRawMethod(true)
530
- };
531
- var logger = {
532
- log: createLogMethod("log", false),
533
- error: createLogMethod("error", false, true),
534
- warn: createLogMethod("warn", false),
535
- info: createLogMethod("info", false),
536
- success: createLogMethod("success", false),
537
- debug: createLogMethod("debug", false),
538
- raw: createRawMethod(false)
539
- };
540
-
541
- // packages/mapper/src/mod.ts
542
- var pMapSkip = Symbol("skip");
543
- async function pMap(input, mapper, options = {}) {
544
- const {
545
- concurrency = Number.POSITIVE_INFINITY,
546
- stopOnError = true,
547
- signal
548
- } = options;
549
- if (!("Symbol" in globalThis) || input[Symbol.iterator] === undefined && input[Symbol.asyncIterator] === undefined) {
550
- throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, ` + `got (${typeof input})`);
551
- }
552
- if (typeof mapper !== "function") {
553
- throw new TypeError("Mapper function is required");
554
- }
555
- if (!(Number.isSafeInteger(concurrency) && concurrency >= 1 || concurrency === Number.POSITIVE_INFINITY)) {
556
- throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or ` + `\`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`);
557
- }
558
- return new Promise((resolve, reject) => {
559
- const iterator = input[Symbol.asyncIterator] !== undefined ? input[Symbol.asyncIterator]() : input[Symbol.iterator]();
560
- const results = [];
561
- const errors = [];
562
- let activeCount = 0;
563
- let currentIndex = 0;
564
- let isIterableDone = false;
565
- let isSettled = false;
566
- let isPumping = false;
567
- let iteratorClosed = false;
568
- const safeCloseIterator = async () => {
569
- if (iteratorClosed)
570
- return;
571
- const ret = iterator?.return;
572
- if (typeof ret === "function") {
573
- try {
574
- iteratorClosed = true;
575
- await ret.call(iterator);
576
- } catch {}
577
- } else {
578
- iteratorClosed = true;
579
- }
580
- };
581
- const onAbort = () => {
582
- if (isSettled)
583
- return;
584
- isSettled = true;
585
- safeCloseIterator();
586
- cleanup();
587
- reject(signal.reason);
588
- };
589
- signal?.addEventListener("abort", onAbort, { once: true });
590
- function cleanup() {
591
- signal?.removeEventListener("abort", onAbort);
592
- }
593
- function settleWithAggregateIfNeeded() {
594
- if (errors.length > 0 && !stopOnError) {
595
- cleanup();
596
- reject(new AggregateError(errors, "One or more promises rejected"));
597
- return true;
598
- }
599
- return false;
600
- }
601
- function resolveResults() {
602
- cleanup();
603
- const out = [];
604
- for (let i = 0;i < results.length; i++) {
605
- const v = results[i];
606
- if (v !== undefined && v !== pMapSkip) {
607
- out.push(v);
608
- }
609
- }
610
- resolve(out);
611
- }
612
- function checkCompletion() {
613
- if (isSettled)
614
- return;
615
- if (!isIterableDone)
616
- return;
617
- if (activeCount > 0)
618
- return;
619
- isSettled = true;
620
- if (settleWithAggregateIfNeeded()) {
621
- return;
622
- }
623
- resolveResults();
624
- }
625
- async function startMapper(valueOrPromise, index) {
626
- try {
627
- const item = await valueOrPromise;
628
- const result = await mapper(item, index);
629
- if (!isSettled) {
630
- results[index] = result;
631
- }
632
- } catch (error) {
633
- if (isSettled)
634
- return;
635
- if (stopOnError) {
636
- isSettled = true;
637
- safeCloseIterator();
638
- cleanup();
639
- reject(error);
640
- return;
641
- }
642
- errors.push(error);
643
- } finally {
644
- if (!isSettled) {
645
- activeCount--;
646
- checkCompletion();
647
- pump();
648
- }
649
- }
650
- }
651
- async function pump() {
652
- if (isSettled || isPumping)
653
- return;
654
- isPumping = true;
655
- try {
656
- while (!isSettled && !isIterableDone && activeCount < concurrency) {
657
- let next;
658
- try {
659
- next = iterator.next();
660
- next = await next;
661
- } catch (error) {
662
- if (!isSettled) {
663
- isSettled = true;
664
- safeCloseIterator();
665
- cleanup();
666
- reject(error);
667
- }
668
- return;
669
- }
670
- if (next.done) {
671
- isIterableDone = true;
672
- break;
673
- }
674
- const index = currentIndex++;
675
- activeCount++;
676
- startMapper(next.value, index);
677
- }
678
- checkCompletion();
679
- } finally {
680
- isPumping = false;
681
- }
682
- }
683
- pump();
684
- });
685
- }
686
-
687
- // packages/launcher/src/impl/discovery.ts
688
- var {Glob } = globalThis.Bun;
689
-
690
- // packages/launcher/src/impl/cache.ts
691
- import { existsSync, mkdirSync } from "fs";
692
- import { homedir } from "os";
693
- import { join } from "path";
694
- var CACHE_VERSION = "1.0.0";
695
- var CACHE_DIR = ".reliverse/dler/cache/launcher";
696
- var CACHE_FILE = "metadata.json";
697
- var getCachePath = () => {
698
- const homeDir = homedir();
699
- const cacheDir = join(homeDir, CACHE_DIR);
700
- if (!existsSync(cacheDir)) {
701
- mkdirSync(cacheDir, { recursive: true });
702
- }
703
- return join(cacheDir, CACHE_FILE);
704
- };
705
- var isCacheValid = async (entry) => {
706
- try {
707
- const file = Bun.file(entry.filePath);
708
- const stats = await file.stat();
709
- return entry.mtime === stats.mtime.getTime() && entry.size === stats.size;
710
- } catch {
711
- return false;
712
- }
713
- };
714
- var loadMetadataCache = async () => {
715
- const cachePath = getCachePath();
716
- if (!existsSync(cachePath)) {
717
- return null;
718
- }
719
- try {
720
- const cacheFile = Bun.file(cachePath);
721
- const cacheData = await cacheFile.json();
722
- if (cacheData.version !== CACHE_VERSION) {
723
- return null;
724
- }
725
- const results = await pMap(Object.entries(cacheData.entries), async ([cmdName, entry]) => ({
726
- cmdName,
727
- metadata: await isCacheValid(entry) ? entry.metadata : null
728
- }), { concurrency: 20 });
729
- const metadataMap = new Map;
730
- for (const { cmdName, metadata } of results) {
731
- if (metadata) {
732
- metadataMap.set(cmdName, metadata);
733
- }
734
- }
735
- return metadataMap.size > 0 ? metadataMap : null;
736
- } catch {
737
- return null;
738
- }
739
- };
740
- var saveMetadataCache = async (metadata, fileStats, filePaths) => {
741
- const cachePath = getCachePath();
742
- const entries = {};
743
- for (const [cmdName, cmdMetadata] of metadata) {
744
- const stats = fileStats.get(cmdName);
745
- const filePath = filePaths.get(cmdName);
746
- if (stats && filePath) {
747
- entries[cmdName] = {
748
- metadata: cmdMetadata,
749
- filePath,
750
- mtime: stats.mtime,
751
- size: stats.size
752
- };
753
- }
754
- }
755
- const cacheData = {
756
- entries,
757
- version: CACHE_VERSION
758
- };
759
- await Bun.write(cachePath, JSON.stringify(cacheData, null, 2));
760
- };
761
-
762
- // packages/launcher/src/impl/errors.ts
763
- class LauncherError extends Error {
764
- code;
765
- constructor(message, code) {
766
- super(message);
767
- this.code = code;
768
- this.name = "LauncherError";
769
- }
770
- }
771
-
772
- class CommandNotFoundError extends LauncherError {
773
- constructor(cmdName, availableCmds) {
774
- super(`Command "${cmdName}" not found. Available commands: ${availableCmds.join(", ")}`, "CMD_NOT_FOUND");
775
- this.name = "CommandNotFoundError";
776
- }
777
- }
778
-
779
- class ArgumentValidationError extends LauncherError {
780
- argName;
781
- reason;
782
- constructor(argName, reason) {
783
- super(`Invalid argument "${argName}": ${reason}`, "ARG_VALIDATION_ERROR");
784
- this.argName = argName;
785
- this.reason = reason;
786
- this.name = "ArgumentValidationError";
787
- }
788
- }
789
-
790
- class CommandLoadError extends LauncherError {
791
- constructor(cmdName, cause) {
792
- super(`Failed to load command "${cmdName}"`, "CMD_LOAD_ERROR");
793
- this.name = "CommandLoadError";
794
- this.cause = cause;
795
- }
796
- }
797
-
798
- // packages/launcher/src/impl/discovery.ts
799
- var fileStatsCache = new Map;
800
- var moduleCache = new Map;
801
- var getFileStats = async (filePath) => {
802
- const cached = fileStatsCache.get(filePath);
803
- if (cached)
804
- return cached;
805
- const stats = await Bun.file(filePath).stat();
806
- const result = { mtime: stats.mtime.getTime(), size: stats.size };
807
- fileStatsCache.set(filePath, result);
808
- return result;
809
- };
810
- var createLazyMetadataLoader = (filePath, cmdName) => {
811
- let cachedMetadata = null;
812
- let isLoading = false;
813
- let loadPromise = null;
814
- return async () => {
815
- if (cachedMetadata)
816
- return cachedMetadata;
817
- if (isLoading && loadPromise) {
818
- return loadPromise;
819
- }
820
- isLoading = true;
821
- loadPromise = (async () => {
822
- try {
823
- const module = await import(filePath);
824
- const definition = module.default;
825
- if (!definition || !definition.cfg) {
826
- throw new Error("Invalid command definition");
827
- }
828
- const cmdMetadata = {
829
- name: definition.cfg.name,
830
- description: definition.cfg.description,
831
- aliases: definition.cfg.aliases,
832
- version: definition.cfg.version,
833
- examples: definition.cfg.examples
834
- };
835
- cachedMetadata = cmdMetadata;
836
- return cmdMetadata;
837
- } catch (error) {
838
- throw new CommandLoadError(cmdName, error);
839
- } finally {
840
- isLoading = false;
841
- loadPromise = null;
842
- }
843
- })();
844
- return loadPromise;
845
- };
846
- };
847
- var discoverCommands = async (cmdsDir, baseDir) => {
848
- const registry = new Map;
849
- const aliases = new Map;
850
- const metadata = new Map;
851
- const hierarchy = new Map;
852
- const rootCommands = new Set;
853
- const fileStats = new Map;
854
- const filePaths = new Map;
855
- const loadedMetadata = new Map;
856
- const cachedMetadata = await loadMetadataCache();
857
- const cachedMetadataMap = new Map;
858
- if (cachedMetadata) {
859
- for (const [cmdName, cmdMetadata] of cachedMetadata) {
860
- cachedMetadataMap.set(cmdName, cmdMetadata);
861
- }
862
- }
863
- const glob = new Glob("**/cmd.ts");
864
- const cwd = baseDir ? `${baseDir}/${cmdsDir}` : `${process.cwd()}/${cmdsDir}`;
865
- const files = await Array.fromAsync(glob.scan(cwd));
866
- const fileData = await pMap(files, async (file) => {
867
- const pathParts = file.split(/[/\\]/);
868
- const cmdName = pathParts[pathParts.length - 2];
869
- const filePath = `${cwd}/${file}`;
870
- const stats = await getFileStats(filePath);
871
- const depth = pathParts.length - 1;
872
- const parent = depth > 1 ? pathParts[0] : undefined;
873
- const fullPath = pathParts.slice(0, -1).join("/");
874
- return {
875
- cmdName,
876
- filePath,
877
- stats,
878
- file,
879
- depth,
880
- parent,
881
- fullPath
882
- };
883
- }, { concurrency: 10 });
884
- for (const {
885
- cmdName,
886
- filePath,
887
- stats,
888
- depth,
889
- parent,
890
- fullPath
891
- } of fileData) {
892
- const loader = async () => {
893
- if (moduleCache.has(filePath)) {
894
- return moduleCache.get(filePath);
895
- }
896
- try {
897
- const module = await import(filePath);
898
- const definition = module.default;
899
- if (!definition || typeof definition.handler !== "function") {
900
- throw new Error("Invalid command definition");
901
- }
902
- moduleCache.set(filePath, definition);
903
- return definition;
904
- } catch (error) {
905
- throw new CommandLoadError(cmdName, error);
906
- }
907
- };
908
- fileStats.set(cmdName, stats);
909
- filePaths.set(cmdName, filePath);
910
- const cachedMeta = cachedMetadataMap.get(cmdName);
911
- if (cachedMeta && await isCacheValid2(filePath, stats)) {
912
- const lazyMetadataLoader = () => Promise.resolve(cachedMeta);
913
- metadata.set(cmdName, lazyMetadataLoader);
914
- loadedMetadata.set(cmdName, cachedMeta);
915
- if (cachedMeta.aliases) {
916
- for (const alias of cachedMeta.aliases) {
917
- aliases.set(alias, cmdName);
918
- }
919
- }
920
- } else {
921
- const lazyMetadataLoader = createLazyMetadataLoader(filePath, cmdName);
922
- metadata.set(cmdName, lazyMetadataLoader);
923
- }
924
- registry.set(cmdName, loader);
925
- const cmdNode = {
926
- name: cmdName,
927
- path: fullPath,
928
- depth,
929
- parent,
930
- children: new Map,
931
- loader,
932
- metadata: metadata.get(cmdName)
933
- };
934
- hierarchy.set(cmdName, cmdNode);
935
- if (depth === 1) {
936
- rootCommands.add(cmdName);
937
- }
938
- }
939
- for (const [cmdName, node] of hierarchy) {
940
- if (node.parent) {
941
- const parentNode = hierarchy.get(node.parent);
942
- if (parentNode) {
943
- parentNode.children.set(cmdName, node);
944
- }
945
- }
946
- }
947
- saveMetadataCache(loadedMetadata, fileStats, filePaths).catch(() => {});
948
- return { registry, aliases, metadata, hierarchy, rootCommands };
949
- };
950
- var isCacheValid2 = async (filePath, stats) => {
951
- try {
952
- const file = Bun.file(filePath);
953
- const fileStats = await file.stat();
954
- return fileStats.mtime.getTime() === stats.mtime && fileStats.size === stats.size;
955
- } catch {
956
- return false;
957
- }
958
- };
959
-
960
- // packages/launcher/src/impl/help.ts
961
- var HELP_TEMPLATES = {
962
- commandHeader: (name, description) => `
963
- ${name} - ${description}`,
964
- version: (version) => `Version: ${version}`,
965
- usage: (name) => `
966
- Usage:
967
- ${name} [options]`,
968
- usageWithSubCommands: (name) => `
969
- Usage:
970
- ${name} [subcommand] [options]`,
971
- optionsHeader: `
972
- Options:`,
973
- requiredNote: `
974
- * = required`,
975
- examplesHeader: `
976
- Examples:`,
977
- globalHeader: `
978
- Available commands:
979
- `,
980
- helpFooter: `
981
- Use "command --help" for command-specific help
982
- `
983
- };
984
- var formatArgName = (name, def) => {
985
- const aliases = def.aliases ? ` (-${def.aliases.join(", -")})` : "";
986
- const required = def.required ? "*" : "";
987
- return `--${name}${aliases}${required}`;
988
- };
989
- var formatArgType = (def) => {
990
- if (def.type === "boolean")
991
- return "";
992
- return `<${def.type}>`;
993
- };
994
- var argHelpCache = new Map;
995
- var helpCache = new Map;
996
- var getArgHelp = (name, def) => {
997
- const cacheKey = `${name}:${JSON.stringify(def)}`;
998
- let cached = argHelpCache.get(cacheKey);
999
- if (!cached) {
1000
- const argName = formatArgName(name, def);
1001
- const argType = formatArgType(def);
1002
- const desc = def.description ?? "";
1003
- const defaultVal = "default" in def && def.default !== undefined ? ` (default: ${def.default})` : "";
1004
- cached = ` ${argName} ${argType}
1005
- ${desc}${defaultVal}`;
1006
- argHelpCache.set(cacheKey, cached);
1007
- }
1008
- return cached;
1009
- };
1010
- var generateCommandHelp = async (definition) => {
1011
- const { cfg, args } = definition;
1012
- const cacheKey = `${cfg.name}:${JSON.stringify(cfg)}:${JSON.stringify(args)}`;
1013
- const cached = helpCache.get(cacheKey);
1014
- if (cached) {
1015
- return cached.commandHelp;
1016
- }
1017
- const lines = [
1018
- HELP_TEMPLATES.commandHeader(cfg.name, cfg.description || "No description available")
1019
- ];
1020
- if (cfg.version) {
1021
- lines.push(HELP_TEMPLATES.version(cfg.version));
1022
- }
1023
- lines.push(HELP_TEMPLATES.usage(cfg.name));
1024
- if (Object.keys(args).length > 0) {
1025
- lines.push(HELP_TEMPLATES.optionsHeader);
1026
- for (const [name, def] of Object.entries(args)) {
1027
- lines.push(getArgHelp(name, def));
1028
- }
1029
- lines.push(HELP_TEMPLATES.requiredNote);
1030
- }
1031
- if (cfg.examples && cfg.examples.length > 0) {
1032
- lines.push(HELP_TEMPLATES.examplesHeader);
1033
- for (const example of cfg.examples) {
1034
- lines.push(` ${example}`);
1035
- }
1036
- }
1037
- const helpText = lines.join(`
1038
- `);
1039
- helpCache.set(cacheKey, {
1040
- commandHelp: helpText,
1041
- globalHelp: "",
1042
- fileHash: "",
1043
- lastModified: Date.now()
1044
- });
1045
- return helpText;
1046
- };
1047
- var commandHelpCache = new Map;
1048
- var formatCommandHelp = (name, metadata) => {
1049
- const cacheKey = `${name}:${JSON.stringify(metadata)}`;
1050
- let cached = commandHelpCache.get(cacheKey);
1051
- if (!cached) {
1052
- const aliases = metadata.aliases ? ` (${metadata.aliases.join(", ")})` : "";
1053
- const description = metadata.description || "No description available";
1054
- cached = ` ${name}${aliases}
1055
- ${description}`;
1056
- commandHelpCache.set(cacheKey, cached);
1057
- }
1058
- return cached;
1059
- };
1060
- var generateGlobalHelp = async (registry) => {
1061
- const cacheKey = `global:${Array.from(registry.metadata.keys()).sort().join(",")}`;
1062
- const cached = helpCache.get(cacheKey);
1063
- if (cached && cached.globalHelp) {
1064
- return cached.globalHelp;
1065
- }
1066
- const lines = [HELP_TEMPLATES.globalHeader];
1067
- const metadataResults = await pMap(Array.from(registry.metadata.entries()), async ([name, metadataLoader]) => {
1068
- const metadata = await metadataLoader();
1069
- return [name, metadata];
1070
- }, { concurrency: 5 });
1071
- metadataResults.sort(([a], [b]) => a.localeCompare(b));
1072
- for (const [name, metadata] of metadataResults) {
1073
- lines.push(formatCommandHelp(name, metadata));
1074
- }
1075
- lines.push(HELP_TEMPLATES.helpFooter);
1076
- const helpText = lines.join(`
1077
- `);
1078
- helpCache.set(cacheKey, {
1079
- commandHelp: "",
1080
- globalHelp: helpText,
1081
- fileHash: "",
1082
- lastModified: Date.now()
1083
- });
1084
- return helpText;
1085
- };
1086
-
1087
- // packages/launcher/src/impl/validator.ts
1088
- var validateArgValue = (argName, value, definition) => {
1089
- const expectedType = definition.type === "boolean" ? "boolean" : definition.type === "number" ? "number" : "string";
1090
- if (typeof value !== expectedType) {
1091
- throw new ArgumentValidationError(argName, `Expected ${expectedType}, got ${typeof value}`);
1092
- }
1093
- if ("validate" in definition && definition.validate) {
1094
- const result = definition.validate(value);
1095
- if (result !== true) {
1096
- throw new ArgumentValidationError(argName, typeof result === "string" ? result : "Validation failed");
1097
- }
1098
- }
1099
- return true;
1100
- };
1101
-
1102
- // packages/launcher/src/impl/parser.ts
1103
- var camelCase = (str) => str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
1104
- var schemaMetadataCache = new Map;
1105
- var createSchemaMetadata = (schema) => {
1106
- const aliasMap = new Map;
1107
- const camelCaseCache = new Map;
1108
- const defaults = {};
1109
- const requiredKeys = new Set;
1110
- const availableKeys = [];
1111
- for (const [key, def] of Object.entries(schema)) {
1112
- availableKeys.push(key);
1113
- const camelKey = camelCase(key);
1114
- if (camelKey !== key) {
1115
- camelCaseCache.set(key, camelKey);
1116
- }
1117
- if (def.aliases) {
1118
- for (const alias of def.aliases) {
1119
- aliasMap.set(alias, key);
1120
- const camelAlias = camelCase(alias);
1121
- if (camelAlias !== alias) {
1122
- camelCaseCache.set(alias, camelAlias);
1123
- }
1124
- }
1125
- }
1126
- if ("default" in def && def.default !== undefined) {
1127
- defaults[key] = def.default;
1128
- }
1129
- if (def.required) {
1130
- requiredKeys.add(key);
1131
- }
1132
- }
1133
- return {
1134
- aliasMap,
1135
- camelCaseCache,
1136
- defaults,
1137
- requiredKeys,
1138
- availableKeys
1139
- };
1140
- };
1141
- var hashSchema = (schema) => {
1142
- const keys = Object.keys(schema).sort();
1143
- return keys.join("|");
1144
- };
1145
- var getSchemaMetadata = (schema) => {
1146
- const schemaKey = hashSchema(schema);
1147
- let metadata = schemaMetadataCache.get(schemaKey);
1148
- if (!metadata) {
1149
- metadata = createSchemaMetadata(schema);
1150
- schemaMetadataCache.set(schemaKey, metadata);
1151
- }
1152
- return metadata;
1153
- };
1154
- var parseArgs = (argv, schema) => {
1155
- const [cmdName, ...rawArgs] = argv;
1156
- if (!cmdName) {
1157
- throw new ArgumentValidationError("command", "No command provided");
1158
- }
1159
- const { aliasMap, camelCaseCache, defaults, requiredKeys, availableKeys } = getSchemaMetadata(schema);
1160
- const parsedArgs = { ...defaults };
1161
- for (let i = 0;i < rawArgs.length; i++) {
1162
- const arg = rawArgs[i];
1163
- if (!arg || !arg.startsWith("-"))
1164
- continue;
1165
- const isLongForm = arg.startsWith("--");
1166
- const flagName = arg.slice(isLongForm ? 2 : 1);
1167
- const actualKey = aliasMap.get(flagName) ?? camelCaseCache.get(flagName) ?? camelCase(flagName);
1168
- const definition = schema[actualKey];
1169
- if (!definition) {
1170
- throw new ArgumentValidationError(flagName, `Unknown argument. Available: ${availableKeys.join(", ")}`);
1171
- }
1172
- if (definition.type === "boolean") {
1173
- parsedArgs[actualKey] = true;
1174
- continue;
1175
- }
1176
- const nextArg = rawArgs[++i];
1177
- if (nextArg === undefined || nextArg.startsWith("-")) {
1178
- throw new ArgumentValidationError(flagName, `Expected value for argument "${flagName}"`);
1179
- }
1180
- let value = nextArg;
1181
- if (definition.type === "number") {
1182
- value = Number(nextArg);
1183
- if (Number.isNaN(value)) {
1184
- throw new ArgumentValidationError(flagName, `Expected number, got "${nextArg}"`);
1185
- }
1186
- }
1187
- validateArgValue(actualKey, value, definition);
1188
- parsedArgs[actualKey] = value;
1189
- }
1190
- for (const requiredKey of requiredKeys) {
1191
- if (!(requiredKey in parsedArgs)) {
1192
- throw new ArgumentValidationError(requiredKey, `Required argument "${requiredKey}" is missing`);
1193
- }
1194
- }
1195
- return { cmdName, parsedArgs };
1196
- };
1197
-
1198
- // packages/launcher/src/impl/registry.ts
1199
- var cachedRegistry = null;
1200
- var getRegistry = () => cachedRegistry;
1201
- var setRegistry = (registry) => {
1202
- cachedRegistry = registry;
1203
- };
1204
- var resolveCommand = (registry, cmdNameOrAlias) => {
1205
- const resolvedName = registry.aliases.get(cmdNameOrAlias) ?? cmdNameOrAlias;
1206
- return resolvedName;
1207
- };
1208
-
1209
- // packages/launcher/src/mod.ts
1210
- var getCallerDirectory = (importMetaUrl) => {
1211
- return dirname(fileURLToPath(importMetaUrl));
1212
- };
1213
- var runLauncher = async (importMetaUrl, options = {}) => {
1214
- const { cmdsDir = "./cmds", onError } = options;
1215
- try {
1216
- let registry = getRegistry();
1217
- if (!registry) {
1218
- const callerDir = getCallerDirectory(importMetaUrl);
1219
- registry = await discoverCommands(cmdsDir, callerDir);
1220
- setRegistry(registry);
1221
- }
1222
- const argv = process.argv.slice(2);
1223
- if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") {
1224
- logger.log(await generateGlobalHelp(registry));
1225
- process.exit(0);
1226
- }
1227
- const isSubCommand = argv.length > 1 && !argv[1].startsWith("-");
1228
- if (isSubCommand) {
1229
- const parentName = resolveCommand(registry, argv[0]);
1230
- const subCommandName = resolveCommand(registry, argv[1]);
1231
- const parentNode = registry.hierarchy.get(parentName);
1232
- const subCommandNode = registry.hierarchy.get(subCommandName);
1233
- if (!parentNode) {
1234
- throw new CommandNotFoundError(argv[0], Array.from(registry.registry.keys()));
1235
- }
1236
- if (!subCommandNode || subCommandNode.parent !== parentName) {
1237
- const availableSubCommands = Array.from(parentNode.children.keys());
1238
- throw new CommandNotFoundError(subCommandName, availableSubCommands);
1239
- }
1240
- const parentDefinition = await parentNode.loader();
1241
- const subCommandDefinition = await subCommandNode.loader();
1242
- if (argv.includes("--help") || argv.includes("-h")) {
1243
- logger.log(await generateCommandHelp(subCommandDefinition));
1244
- process.exit(0);
1245
- }
1246
- const subCommandIndex = argv.findIndex((arg, index) => index > 0 && !arg.startsWith("-"));
1247
- const parentArgs = [];
1248
- const subCommandArgsFiltered = [];
1249
- for (let i = 1;i < argv.length; i++) {
1250
- const arg = argv[i];
1251
- if (i === subCommandIndex) {
1252
- continue;
1253
- }
1254
- const isParentArg = Object.keys(parentDefinition.args).some((key) => {
1255
- const def = parentDefinition.args[key];
1256
- if (!def)
1257
- return false;
1258
- return arg === `--${key}` || arg === `-${key}` || def.aliases && def.aliases.some((alias) => arg === `-${alias}`);
1259
- });
1260
- if (isParentArg) {
1261
- parentArgs.push(arg);
1262
- if (i + 1 < argv.length && !argv[i + 1].startsWith("-")) {
1263
- parentArgs.push(argv[i + 1]);
1264
- i++;
1265
- }
1266
- } else {
1267
- subCommandArgsFiltered.push(arg);
1268
- }
1269
- }
1270
- let parentParsedArgs = {};
1271
- if (parentArgs.length > 0) {
1272
- const { parsedArgs } = parseArgs([parentName, ...parentArgs], parentDefinition.args);
1273
- parentParsedArgs = parsedArgs;
1274
- }
1275
- const { parsedArgs: subCommandParsedArgs } = parseArgs([subCommandName, ...subCommandArgsFiltered], subCommandDefinition.args);
1276
- await subCommandDefinition.handler(subCommandParsedArgs, parentParsedArgs);
1277
- } else {
1278
- const cmdNameOrAlias = argv[0];
1279
- const cmdName = resolveCommand(registry, cmdNameOrAlias);
1280
- const loader = registry.registry.get(cmdName);
1281
- if (!loader) {
1282
- throw new CommandNotFoundError(cmdNameOrAlias, Array.from(registry.registry.keys()));
1283
- }
1284
- const definition = await loader();
1285
- if (argv.includes("--help") || argv.includes("-h")) {
1286
- logger.log(await generateCommandHelp(definition));
1287
- process.exit(0);
1288
- }
1289
- const { parsedArgs } = parseArgs(argv, definition.args);
1290
- await definition.handler(parsedArgs);
1291
- }
1292
- } catch (error) {
1293
- if (error instanceof LauncherError) {
1294
- if (onError) {
1295
- onError(error);
1296
- } else {
1297
- const errorLines = [`
1298
- \u274C Error: ${error.message}`];
1299
- if (error instanceof CommandLoadError && error.cause) {
1300
- errorLines.push(`Cause: ${error.cause}`);
1301
- }
1302
- errorLines.push("");
1303
- writeErrorLines(errorLines);
1304
- }
1305
- process.exit(1);
1306
- } else {
1307
- throw error;
1308
- }
1309
- }
1310
- };
1311
-
1312
- // apps/dler/src/cli.ts
1313
- await runLauncher(import.meta.url);
1314
-
1315
- //# debugId=E90D77EA3D02CDB664756E2164756E21
1316
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi5cXC4uXFwuLlxccGFja2FnZXNcXGxhdW5jaGVyXFxzcmNcXG1vZC50cyIsICIuLlxcLi5cXC4uXFxwYWNrYWdlc1xcaGVscGVyc1xcc3JjXFxpbXBsXFx3cml0ZS50cyIsICIuLlxcLi5cXC4uXFxwYWNrYWdlc1xcY29sb3JzXFxzcmNcXG1vZC50cyIsICIuLlxcLi5cXC4uXFxwYWNrYWdlc1xcbG9nZ2VyXFxzcmNcXG1vZC50cyIsICIuLlxcLi5cXC4uXFxwYWNrYWdlc1xcbWFwcGVyXFxzcmNcXG1vZC50cyIsICIuLlxcLi5cXC4uXFxwYWNrYWdlc1xcbGF1bmNoZXJcXHNyY1xcaW1wbFxcZGlzY292ZXJ5LnRzIiwgIi4uXFwuLlxcLi5cXHBhY2thZ2VzXFxsYXVuY2hlclxcc3JjXFxpbXBsXFxjYWNoZS50cyIsICIuLlxcLi5cXC4uXFxwYWNrYWdlc1xcbGF1bmNoZXJcXHNyY1xcaW1wbFxcZXJyb3JzLnRzIiwgIi4uXFwuLlxcLi5cXHBhY2thZ2VzXFxsYXVuY2hlclxcc3JjXFxpbXBsXFxoZWxwLnRzIiwgIi4uXFwuLlxcLi5cXHBhY2thZ2VzXFxsYXVuY2hlclxcc3JjXFxpbXBsXFx2YWxpZGF0b3IudHMiLCAiLi5cXC4uXFwuLlxccGFja2FnZXNcXGxhdW5jaGVyXFxzcmNcXGltcGxcXHBhcnNlci50cyIsICIuLlxcLi5cXC4uXFxwYWNrYWdlc1xcbGF1bmNoZXJcXHNyY1xcaW1wbFxccmVnaXN0cnkudHMiLCAiLi5cXHNyY1xcY2xpLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgIi8vIHBhY2thZ2VzL2xhdW5jaGVyL3NyYy9pbXBsL2xhdW5jaGVyL21vZC50c1xuXG5pbXBvcnQgeyBkaXJuYW1lIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgZmlsZVVSTFRvUGF0aCB9IGZyb20gXCJub2RlOnVybFwiO1xuaW1wb3J0IHsgd3JpdGVFcnJvckxpbmVzIH0gZnJvbSBcIkByZWxpdmVyc2UvZGxlci1oZWxwZXJzXCI7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tIFwiQHJlbGl2ZXJzZS9kbGVyLWxvZ2dlclwiO1xuaW1wb3J0IHsgZGlzY292ZXJDb21tYW5kcyB9IGZyb20gXCIuL2ltcGwvZGlzY292ZXJ5XCI7XG5pbXBvcnQge1xuICBDb21tYW5kTG9hZEVycm9yLFxuICBDb21tYW5kTm90Rm91bmRFcnJvcixcbiAgTGF1bmNoZXJFcnJvcixcbn0gZnJvbSBcIi4vaW1wbC9lcnJvcnNcIjtcbmltcG9ydCB7IGdlbmVyYXRlQ29tbWFuZEhlbHAsIGdlbmVyYXRlR2xvYmFsSGVscCB9IGZyb20gXCIuL2ltcGwvaGVscFwiO1xuaW1wb3J0IHsgcGFyc2VBcmdzIH0gZnJvbSBcIi4vaW1wbC9wYXJzZXJcIjtcbmltcG9ydCB7IGdldFJlZ2lzdHJ5LCByZXNvbHZlQ29tbWFuZCwgc2V0UmVnaXN0cnkgfSBmcm9tIFwiLi9pbXBsL3JlZ2lzdHJ5XCI7XG5cbmV4cG9ydCB7IGRlZmluZUNtZCwgZGVmaW5lQ21kQXJncywgZGVmaW5lQ21kQ2ZnIH0gZnJvbSBcIi4vaW1wbC9jb21tYW5kXCI7XG5leHBvcnQge1xuICBBcmd1bWVudFZhbGlkYXRpb25FcnJvcixcbiAgQ29tbWFuZExvYWRFcnJvcixcbiAgQ29tbWFuZE5vdEZvdW5kRXJyb3IsXG4gIExhdW5jaGVyRXJyb3IsXG59IGZyb20gXCIuL2ltcGwvZXJyb3JzXCI7XG5leHBvcnQgdHlwZSB7XG4gIENtZEFyZ0RlZmluaXRpb24sXG4gIENtZEFyZ3NTY2hlbWEsXG4gIENtZENmZyxcbiAgQ21kRGVmaW5pdGlvbixcbiAgQ21kSGFuZGxlcixcbiAgQ21kTG9hZGVyLFxuICBDbWRSZWdpc3RyeSxcbiAgRGlzY292ZXJ5UmVzdWx0LFxuICBQYXJzZWRBcmdzLFxufSBmcm9tIFwiLi9pbXBsL3R5cGVzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGF1bmNoZXJPcHRpb25zIHtcbiAgY21kc0Rpcj86IHN0cmluZztcbiAgb25FcnJvcj86IChlcnJvcjogTGF1bmNoZXJFcnJvcikgPT4gdm9pZDtcbn1cblxuLy8gR2V0IHRoZSBkaXJlY3Rvcnkgb2YgdGhlIGZpbGUgdGhhdCBjYWxsZWQgcnVuTGF1bmNoZXJcbmNvbnN0IGdldENhbGxlckRpcmVjdG9yeSA9IChpbXBvcnRNZXRhVXJsOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAvLyBVc2UgcHJvdmlkZWQgaW1wb3J0Lm1ldGEudXJsIChtb3N0IHJlbGlhYmxlIGNhbGxlciBkZXRlY3Rpb24pXG4gIHJldHVybiBkaXJuYW1lKGZpbGVVUkxUb1BhdGgoaW1wb3J0TWV0YVVybCkpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJ1bkxhdW5jaGVyID0gYXN5bmMgKFxuICBpbXBvcnRNZXRhVXJsOiBzdHJpbmcsXG4gIG9wdGlvbnM6IExhdW5jaGVyT3B0aW9ucyA9IHt9LFxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGNvbnN0IHsgY21kc0RpciA9IFwiLi9jbWRzXCIsIG9uRXJyb3IgfSA9IG9wdGlvbnM7XG5cbiAgdHJ5IHtcbiAgICBsZXQgcmVnaXN0cnkgPSBnZXRSZWdpc3RyeSgpO1xuICAgIGlmICghcmVnaXN0cnkpIHtcbiAgICAgIC8vIEdldCB0aGUgY2FsbGVyJ3MgZGlyZWN0b3J5IHVzaW5nIGltcG9ydC5tZXRhLnVybFxuICAgICAgY29uc3QgY2FsbGVyRGlyID0gZ2V0Q2FsbGVyRGlyZWN0b3J5KGltcG9ydE1ldGFVcmwpO1xuICAgICAgcmVnaXN0cnkgPSBhd2FpdCBkaXNjb3ZlckNvbW1hbmRzKGNtZHNEaXIsIGNhbGxlckRpcik7XG4gICAgICBzZXRSZWdpc3RyeShyZWdpc3RyeSk7XG4gICAgfVxuXG4gICAgY29uc3QgYXJndiA9IHByb2Nlc3MuYXJndi5zbGljZSgyKTtcblxuICAgIGlmIChhcmd2Lmxlbmd0aCA9PT0gMCB8fCBhcmd2WzBdID09PSBcIi0taGVscFwiIHx8IGFyZ3ZbMF0gPT09IFwiLWhcIikge1xuICAgICAgLy8gVXNlIGNhY2hlZCBnbG9iYWwgaGVscCBmb3IgZmFzdGVyIGRpc3BsYXlcbiAgICAgIGxvZ2dlci5sb2coYXdhaXQgZ2VuZXJhdGVHbG9iYWxIZWxwKHJlZ2lzdHJ5KSk7XG4gICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIHN1Yi1jb21tYW5kIGludm9jYXRpb25cbiAgICBjb25zdCBpc1N1YkNvbW1hbmQgPSBhcmd2Lmxlbmd0aCA+IDEgJiYgIWFyZ3ZbMV0hLnN0YXJ0c1dpdGgoXCItXCIpO1xuXG4gICAgaWYgKGlzU3ViQ29tbWFuZCkge1xuICAgICAgLy8gSGFuZGxlIHN1Yi1jb21tYW5kIGV4ZWN1dGlvbiB1c2luZyBmb2xkZXItYmFzZWQgZGlzY292ZXJ5XG4gICAgICBjb25zdCBwYXJlbnROYW1lID0gcmVzb2x2ZUNvbW1hbmQocmVnaXN0cnksIGFyZ3ZbMF0hKTtcbiAgICAgIGNvbnN0IHN1YkNvbW1hbmROYW1lID0gcmVzb2x2ZUNvbW1hbmQocmVnaXN0cnksIGFyZ3ZbMV0hKTtcblxuICAgICAgLy8gQ2hlY2sgaWYgYm90aCBwYXJlbnQgYW5kIHN1Yi1jb21tYW5kIGV4aXN0IGluIHRoZSBoaWVyYXJjaHlcbiAgICAgIGNvbnN0IHBhcmVudE5vZGUgPSByZWdpc3RyeS5oaWVyYXJjaHkuZ2V0KHBhcmVudE5hbWUpO1xuICAgICAgY29uc3Qgc3ViQ29tbWFuZE5vZGUgPSByZWdpc3RyeS5oaWVyYXJjaHkuZ2V0KHN1YkNvbW1hbmROYW1lKTtcblxuICAgICAgaWYgKCFwYXJlbnROb2RlKSB7XG4gICAgICAgIHRocm93IG5ldyBDb21tYW5kTm90Rm91bmRFcnJvcihcbiAgICAgICAgICBhcmd2WzBdISxcbiAgICAgICAgICBBcnJheS5mcm9tKHJlZ2lzdHJ5LnJlZ2lzdHJ5LmtleXMoKSksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmICghc3ViQ29tbWFuZE5vZGUgfHwgc3ViQ29tbWFuZE5vZGUucGFyZW50ICE9PSBwYXJlbnROYW1lKSB7XG4gICAgICAgIC8vIEdldCBhdmFpbGFibGUgc3ViLWNvbW1hbmRzIGZvciB0aGlzIHBhcmVudFxuICAgICAgICBjb25zdCBhdmFpbGFibGVTdWJDb21tYW5kcyA9IEFycmF5LmZyb20ocGFyZW50Tm9kZS5jaGlsZHJlbi5rZXlzKCkpO1xuICAgICAgICB0aHJvdyBuZXcgQ29tbWFuZE5vdEZvdW5kRXJyb3Ioc3ViQ29tbWFuZE5hbWUsIGF2YWlsYWJsZVN1YkNvbW1hbmRzKTtcbiAgICAgIH1cblxuICAgICAgLy8gTG9hZCBib3RoIHBhcmVudCBhbmQgc3ViLWNvbW1hbmQgZGVmaW5pdGlvbnNcbiAgICAgIGNvbnN0IHBhcmVudERlZmluaXRpb24gPSBhd2FpdCBwYXJlbnROb2RlLmxvYWRlcigpO1xuICAgICAgY29uc3Qgc3ViQ29tbWFuZERlZmluaXRpb24gPSBhd2FpdCBzdWJDb21tYW5kTm9kZS5sb2FkZXIoKTtcblxuICAgICAgaWYgKGFyZ3YuaW5jbHVkZXMoXCItLWhlbHBcIikgfHwgYXJndi5pbmNsdWRlcyhcIi1oXCIpKSB7XG4gICAgICAgIGxvZ2dlci5sb2coYXdhaXQgZ2VuZXJhdGVDb21tYW5kSGVscChzdWJDb21tYW5kRGVmaW5pdGlvbikpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNlcGFyYXRlIHBhcmVudCBhbmQgc3ViLWNvbW1hbmQgYXJndW1lbnRzXG4gICAgICBjb25zdCBzdWJDb21tYW5kSW5kZXggPSBhcmd2LmZpbmRJbmRleChcbiAgICAgICAgKGFyZywgaW5kZXgpID0+IGluZGV4ID4gMCAmJiAhYXJnLnN0YXJ0c1dpdGgoXCItXCIpLFxuICAgICAgKTtcblxuICAgICAgLy8gRmlsdGVyIHBhcmVudCBhcmdzIGZyb20gdGhlIGZ1bGwgYXJndW1lbnQgbGlzdFxuICAgICAgY29uc3QgcGFyZW50QXJnczogc3RyaW5nW10gPSBbXTtcbiAgICAgIGNvbnN0IHN1YkNvbW1hbmRBcmdzRmlsdGVyZWQ6IHN0cmluZ1tdID0gW107XG5cbiAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgYXJndi5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBhcmcgPSBhcmd2W2ldITtcbiAgICAgICAgaWYgKGkgPT09IHN1YkNvbW1hbmRJbmRleCkge1xuICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIHN1Yi1jb21tYW5kIG5hbWUsIHNraXAgaXRcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGlmIHRoaXMgYXJndW1lbnQgYmVsb25ncyB0byB0aGUgcGFyZW50IGNvbW1hbmRcbiAgICAgICAgY29uc3QgaXNQYXJlbnRBcmcgPSBPYmplY3Qua2V5cyhwYXJlbnREZWZpbml0aW9uLmFyZ3MpLnNvbWUoKGtleSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGRlZiA9IHBhcmVudERlZmluaXRpb24uYXJnc1trZXldO1xuICAgICAgICAgIGlmICghZGVmKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIGFyZyA9PT0gYC0tJHtrZXl9YCB8fFxuICAgICAgICAgICAgYXJnID09PSBgLSR7a2V5fWAgfHxcbiAgICAgICAgICAgIChkZWYuYWxpYXNlcyAmJiBkZWYuYWxpYXNlcy5zb21lKChhbGlhcykgPT4gYXJnID09PSBgLSR7YWxpYXN9YCkpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGlzUGFyZW50QXJnKSB7XG4gICAgICAgICAgcGFyZW50QXJncy5wdXNoKGFyZyk7XG4gICAgICAgICAgLy8gSWYgaXQncyBhIGZsYWcgd2l0aCBhIHZhbHVlLCBhZGQgdGhlIG5leHQgYXJndW1lbnQgdG9vXG4gICAgICAgICAgaWYgKGkgKyAxIDwgYXJndi5sZW5ndGggJiYgIWFyZ3ZbaSArIDFdIS5zdGFydHNXaXRoKFwiLVwiKSkge1xuICAgICAgICAgICAgcGFyZW50QXJncy5wdXNoKGFyZ3ZbaSArIDFdISk7XG4gICAgICAgICAgICBpKys7IC8vIFNraXAgdGhlIG5leHQgYXJndW1lbnQgYXMgaXQncyB0aGUgdmFsdWVcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3ViQ29tbWFuZEFyZ3NGaWx0ZXJlZC5wdXNoKGFyZyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gUGFyc2UgcGFyZW50IGFyZ3MgKG9ubHkgaWYgdGhlcmUgYXJlIGFueSlcbiAgICAgIGxldCBwYXJlbnRQYXJzZWRBcmdzID0ge307XG4gICAgICBpZiAocGFyZW50QXJncy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHsgcGFyc2VkQXJncyB9ID0gcGFyc2VBcmdzKFxuICAgICAgICAgIFtwYXJlbnROYW1lLCAuLi5wYXJlbnRBcmdzXSxcbiAgICAgICAgICBwYXJlbnREZWZpbml0aW9uLmFyZ3MsXG4gICAgICAgICk7XG4gICAgICAgIHBhcmVudFBhcnNlZEFyZ3MgPSBwYXJzZWRBcmdzO1xuICAgICAgfVxuXG4gICAgICAvLyBQYXJzZSBzdWItY29tbWFuZCBhcmdzXG4gICAgICBjb25zdCB7IHBhcnNlZEFyZ3M6IHN1YkNvbW1hbmRQYXJzZWRBcmdzIH0gPSBwYXJzZUFyZ3MoXG4gICAgICAgIFtzdWJDb21tYW5kTmFtZSwgLi4uc3ViQ29tbWFuZEFyZ3NGaWx0ZXJlZF0sXG4gICAgICAgIHN1YkNvbW1hbmREZWZpbml0aW9uLmFyZ3MsXG4gICAgICApO1xuXG4gICAgICAvLyBFeGVjdXRlIHN1Yi1jb21tYW5kIHdpdGggcGFyZW50IGFyZ3NcbiAgICAgIGF3YWl0IHN1YkNvbW1hbmREZWZpbml0aW9uLmhhbmRsZXIoXG4gICAgICAgIHN1YkNvbW1hbmRQYXJzZWRBcmdzIGFzIG5ldmVyLFxuICAgICAgICBwYXJlbnRQYXJzZWRBcmdzIGFzIG5ldmVyLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSGFuZGxlIHNpbmdsZSBjb21tYW5kIGV4ZWN1dGlvblxuICAgICAgY29uc3QgY21kTmFtZU9yQWxpYXMgPSBhcmd2WzBdITtcbiAgICAgIGNvbnN0IGNtZE5hbWUgPSByZXNvbHZlQ29tbWFuZChyZWdpc3RyeSwgY21kTmFtZU9yQWxpYXMpO1xuXG4gICAgICBjb25zdCBsb2FkZXIgPSByZWdpc3RyeS5yZWdpc3RyeS5nZXQoY21kTmFtZSk7XG4gICAgICBpZiAoIWxvYWRlcikge1xuICAgICAgICB0aHJvdyBuZXcgQ29tbWFuZE5vdEZvdW5kRXJyb3IoXG4gICAgICAgICAgY21kTmFtZU9yQWxpYXMsXG4gICAgICAgICAgQXJyYXkuZnJvbShyZWdpc3RyeS5yZWdpc3RyeS5rZXlzKCkpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkZWZpbml0aW9uID0gYXdhaXQgbG9hZGVyKCk7XG5cbiAgICAgIGlmIChhcmd2LmluY2x1ZGVzKFwiLS1oZWxwXCIpIHx8IGFyZ3YuaW5jbHVkZXMoXCItaFwiKSkge1xuICAgICAgICBsb2dnZXIubG9nKGF3YWl0IGdlbmVyYXRlQ29tbWFuZEhlbHAoZGVmaW5pdGlvbikpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgcGFyc2VkQXJncyB9ID0gcGFyc2VBcmdzKGFyZ3YsIGRlZmluaXRpb24uYXJncyk7XG5cbiAgICAgIGF3YWl0IGRlZmluaXRpb24uaGFuZGxlcihwYXJzZWRBcmdzIGFzIG5ldmVyKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTGF1bmNoZXJFcnJvcikge1xuICAgICAgaWYgKG9uRXJyb3IpIHtcbiAgICAgICAgb25FcnJvcihlcnJvcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBlcnJvckxpbmVzID0gW2BcXG7inYwgRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gXTtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgQ29tbWFuZExvYWRFcnJvciAmJiBlcnJvci5jYXVzZSkge1xuICAgICAgICAgIGVycm9yTGluZXMucHVzaChgQ2F1c2U6ICR7ZXJyb3IuY2F1c2V9YCk7XG4gICAgICAgIH1cbiAgICAgICAgZXJyb3JMaW5lcy5wdXNoKFwiXCIpO1xuICAgICAgICB3cml0ZUVycm9yTGluZXMoZXJyb3JMaW5lcyk7XG4gICAgICB9XG4gICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxufTtcbiIsCiAgICAiLy8gT3B0aW1pemVkIG91dHB1dCBmdW5jdGlvbnMgdGhhdCBiYXRjaCB3cml0ZXNcbmNvbnN0IHRleHRFbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG5cbmV4cG9ydCBjb25zdCB3cml0ZUxpbmUgPSAodGV4dDogc3RyaW5nKTogdm9pZCA9PiB7XG4gIGNvbnN0IGVuY29kZWQgPSB0ZXh0RW5jb2Rlci5lbmNvZGUoYCR7dGV4dH1cXG5gKTtcbiAgQnVuLndyaXRlKEJ1bi5zdGRvdXQsIGVuY29kZWQpO1xufTtcblxuZXhwb3J0IGNvbnN0IHdyaXRlRXJyb3IgPSAodGV4dDogc3RyaW5nKTogdm9pZCA9PiB7XG4gIGNvbnN0IGVuY29kZWQgPSB0ZXh0RW5jb2Rlci5lbmNvZGUoYCR7dGV4dH1cXG5gKTtcbiAgQnVuLndyaXRlKEJ1bi5zdGRlcnIsIGVuY29kZWQpO1xufTtcblxuZXhwb3J0IGNvbnN0IHdyaXRlRXJyb3JMaW5lcyA9IChsaW5lczogc3RyaW5nW10pOiB2b2lkID0+IHtcbiAgLy8gUHJlLWFsbG9jYXRlIHN0cmluZyBidWZmZXIgZm9yIGJldHRlciBwZXJmb3JtYW5jZVxuICBjb25zdCBidWZmZXIgPSBuZXcgQXJyYXkobGluZXMubGVuZ3RoICsgMSk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICBidWZmZXJbaV0gPSBsaW5lc1tpXTtcbiAgfVxuICBidWZmZXJbbGluZXMubGVuZ3RoXSA9IFwiXCI7XG4gIGNvbnN0IGVuY29kZWQgPSB0ZXh0RW5jb2Rlci5lbmNvZGUoYnVmZmVyLmpvaW4oXCJcXG5cIikpO1xuICBCdW4ud3JpdGUoQnVuLnN0ZGVyciwgZW5jb2RlZCk7XG59O1xuXG5leHBvcnQgY29uc3Qgd3JpdGVKc29uRmlsZSA9IGFzeW5jIChcbiAgcGF0aDogc3RyaW5nLFxuICBkYXRhOiB1bmtub3duLFxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGF3YWl0IEJ1bi53cml0ZShwYXRoLCBKU09OLnN0cmluZ2lmeShkYXRhLCBudWxsLCAyKSArIFwiXFxuXCIpO1xufTtcblxuZXhwb3J0IGNvbnN0IHdyaXRlVGV4dEZpbGUgPSBhc3luYyAoXG4gIHBhdGg6IHN0cmluZyxcbiAgY29udGVudDogc3RyaW5nLFxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGF3YWl0IEJ1bi53cml0ZShwYXRoLCBjb250ZW50KTtcbn07XG4iLAogICAgInR5cGUgQ29sb3JMZXZlbCA9IDAgfCAxIHwgMiB8IDM7XG5cbmludGVyZmFjZSBSZ2Ige1xuICByOiBudW1iZXI7XG4gIGc6IG51bWJlcjtcbiAgYjogbnVtYmVyO1xufVxuXG50eXBlIFNnck9wID1cbiAgfCB7IGtpbmQ6IFwic3R5bGVcIjsgb3BlbjogbnVtYmVyW10gfVxuICB8IHsga2luZDogXCJmZy1iYXNpY1wiOyBpZHg6IG51bWJlcjsgYnJpZ2h0OiBib29sZWFuIH1cbiAgfCB7IGtpbmQ6IFwiYmctYmFzaWNcIjsgaWR4OiBudW1iZXI7IGJyaWdodDogYm9vbGVhbiB9XG4gIHwgeyBraW5kOiBcImZnLTI1NlwiOyBjb2RlOiBudW1iZXIgfVxuICB8IHsga2luZDogXCJiZy0yNTZcIjsgY29kZTogbnVtYmVyIH1cbiAgfCB7IGtpbmQ6IFwiZmctdHJ1ZVwiOyByZ2I6IFJnYiB9XG4gIHwgeyBraW5kOiBcImJnLXRydWVcIjsgcmdiOiBSZ2IgfTtcblxudHlwZSBBcHBseUlucHV0ID0gc3RyaW5nIHwgbnVtYmVyO1xuXG50eXBlIEZvcm1hdENhbGxhYmxlID0gKChpbnB1dDogQXBwbHlJbnB1dCkgPT4gc3RyaW5nKSAmIHtcbiAgcmVhZG9ubHkgW09QX1NZTUJPTF06IFNnck9wW107XG59O1xuXG5leHBvcnQgdHlwZSBCYXNlQ29sb3JOYW1lID1cbiAgfCBcImJsYWNrXCJcbiAgfCBcInJlZFwiXG4gIHwgXCJncmVlblwiXG4gIHwgXCJ5ZWxsb3dcIlxuICB8IFwiYmx1ZVwiXG4gIHwgXCJtYWdlbnRhXCJcbiAgfCBcImN5YW5cIlxuICB8IFwid2hpdGVcIlxuICB8IFwiZ3JheVwiXG4gIHwgXCJvcmFuZ2VcIlxuICB8IFwicGlua1wiXG4gIHwgXCJwdXJwbGVcIlxuICB8IFwidGVhbFwiXG4gIHwgXCJsaW1lXCJcbiAgfCBcImJyb3duXCJcbiAgfCBcIm5hdnlcIlxuICB8IFwibWFyb29uXCJcbiAgfCBcIm9saXZlXCJcbiAgfCBcInNpbHZlclwiO1xuXG5leHBvcnQgdHlwZSBDb2xvck5hbWUgPSBCYXNlQ29sb3JOYW1lIHwgQnJpZ2h0Q29sb3JOYW1lIHwgQmdDb2xvck5hbWU7XG5cbmV4cG9ydCB0eXBlIEJyaWdodENvbG9yTmFtZSA9XG4gIHwgXCJibGFja0JyaWdodFwiXG4gIHwgXCJyZWRCcmlnaHRcIlxuICB8IFwiZ3JlZW5CcmlnaHRcIlxuICB8IFwieWVsbG93QnJpZ2h0XCJcbiAgfCBcImJsdWVCcmlnaHRcIlxuICB8IFwibWFnZW50YUJyaWdodFwiXG4gIHwgXCJjeWFuQnJpZ2h0XCJcbiAgfCBcIndoaXRlQnJpZ2h0XCJcbiAgfCBcIm9yYW5nZUJyaWdodFwiXG4gIHwgXCJwaW5rQnJpZ2h0XCJcbiAgfCBcInB1cnBsZUJyaWdodFwiXG4gIHwgXCJ0ZWFsQnJpZ2h0XCJcbiAgfCBcImxpbWVCcmlnaHRcIlxuICB8IFwiYnJvd25CcmlnaHRcIlxuICB8IFwibmF2eUJyaWdodFwiXG4gIHwgXCJtYXJvb25CcmlnaHRcIlxuICB8IFwib2xpdmVCcmlnaHRcIlxuICB8IFwic2lsdmVyQnJpZ2h0XCI7XG5cbmV4cG9ydCB0eXBlIEJnQ29sb3JOYW1lID1cbiAgfCBgYmcke0NhcGl0YWxpemU8QmFzZUNvbG9yTmFtZT59YFxuICB8IGBiZyR7Q2FwaXRhbGl6ZTxCcmlnaHRDb2xvck5hbWU+fWA7XG5cbmV4cG9ydCB0eXBlIFJlU3R5bGVLZXkgPVxuICB8IFwicmVzZXRcIlxuICB8IFwiYm9sZFwiXG4gIHwgXCJkaW1cIlxuICB8IFwiaXRhbGljXCJcbiAgfCBcInVuZGVybGluZVwiXG4gIHwgXCJpbnZlcnNlXCJcbiAgfCBcImhpZGRlblwiXG4gIHwgXCJzdHJpa2V0aHJvdWdoXCI7XG5cbmV4cG9ydCB0eXBlIFJlID0gRm9ybWF0Q2FsbGFibGUgJiB7XG4gIHJlYWRvbmx5IFtLIGluIFJlU3R5bGVLZXldOiBSZTtcbn0gJiB7XG4gIHJlYWRvbmx5IFtLIGluIENvbG9yTmFtZV06IFJlO1xufSAmIHtcbiAgcmVhZG9ubHkgW0sgaW4gQmdDb2xvck5hbWVdOiBSZTtcbn07XG5cbi8vIENvbnN0YW50c1xuY29uc3QgUkVTRVQgPSBcIlxceDFCWzBtXCI7XG5jb25zdCBPUF9TWU1CT0w6IHVuaXF1ZSBzeW1ib2wgPSBTeW1ib2woXCJyZS5vcHNcIik7XG5cbmNvbnN0IENPTE9SX0xFVkVMX09GRiA9IDA7XG5jb25zdCBDT0xPUl9MRVZFTF9CQVNJQyA9IDE7XG5jb25zdCBDT0xPUl9MRVZFTF8yNTYgPSAyO1xuY29uc3QgQ09MT1JfTEVWRUxfVFJVRUNPTE9SID0gMztcblxuY29uc3QgTUlOX0JZVEUgPSAwO1xuY29uc3QgTUFYX0JZVEUgPSAyNTU7XG5jb25zdCBXSElURV9SR0IgPSAyNTU7XG5cbmNvbnN0IEFOU0lfMjU2X0dSQVlTQ0FMRV9NSU4gPSA4O1xuY29uc3QgQU5TSV8yNTZfR1JBWVNDQUxFX01BWCA9IDI0ODtcbmNvbnN0IEFOU0lfMjU2X0JBU0VfT0ZGU0VUID0gMTY7XG5jb25zdCBBTlNJXzI1Nl9HUkFZU0NBTEVfQkFTRSA9IDIzMjtcbmNvbnN0IEFOU0lfMjU2X0dSQVlTQ0FMRV9SQU5HRSA9IDI0NztcbmNvbnN0IEFOU0lfMjU2X0dSQVlTQ0FMRV9TVEVQUyA9IDI0O1xuY29uc3QgQU5TSV8yNTZfQlJJR0hUX1RIUkVTSE9MRCA9IDIzMTtcbmNvbnN0IEFOU0lfMjU2X1JHQl9MRVZFTFMgPSA1O1xuY29uc3QgQU5TSV8yNTZfUkdCX1JFRF9NVUxUSVBMSUVSID0gMzY7XG5jb25zdCBBTlNJXzI1Nl9SR0JfR1JFRU5fTVVMVElQTElFUiA9IDY7XG5cbmNvbnN0IFNHUl9GR19CQVNFID0gMzA7XG5jb25zdCBTR1JfQkdfQkFTRSA9IDQwO1xuY29uc3QgU0dSX0ZHX0JSSUdIVF9CQVNFID0gOTA7XG5jb25zdCBTR1JfQkdfQlJJR0hUX0JBU0UgPSAxMDA7XG5cbmNvbnN0IFNHUl9SRVNFVCA9IDA7XG5jb25zdCBTR1JfQk9MRCA9IDE7XG5jb25zdCBTR1JfRElNID0gMjtcbmNvbnN0IFNHUl9JVEFMSUMgPSAzO1xuY29uc3QgU0dSX1VOREVSTElORSA9IDQ7XG5jb25zdCBTR1JfSU5WRVJTRSA9IDc7XG5jb25zdCBTR1JfSElEREVOID0gODtcbmNvbnN0IFNHUl9TVFJJS0VUSFJPVUdIID0gOTtcblxuY29uc3QgSEVYX1JBRElYID0gMTY7XG5jb25zdCBCUklHSFRfU1VGRklYX0xFTkdUSCA9IDY7XG5jb25zdCBCR19QUkVGSVhfTEVOR1RIID0gMjtcbmNvbnN0IEJSSUdIVF9NSVhfRkFDVE9SID0gMC4yNTtcbmNvbnN0IEJSSUdIVF9TVUZGSVggPSBcIkJyaWdodFwiO1xuXG4vLyBSdW50aW1lIGRldGVjdGlvbiAoY2FjaGVkKVxuY29uc3QgSVNfQlVOID1cbiAgdHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgcHJvY2Vzcy52ZXJzaW9ucz8uYnVuICE9PSB1bmRlZmluZWQgJiZcbiAgdHlwZW9mIEJ1biAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICB0eXBlb2YgQnVuLmNvbG9yID09PSBcImZ1bmN0aW9uXCI7XG5cbmxldCBDVVJSRU5UX0xFVkVMOiBDb2xvckxldmVsID0gQ09MT1JfTEVWRUxfVFJVRUNPTE9SO1xuXG5leHBvcnQgY29uc3Qgc2V0Q29sb3JMZXZlbCA9IChsZXZlbDogQ29sb3JMZXZlbCk6IHZvaWQgPT4ge1xuICBpZiAoXG4gICAgbGV2ZWwgIT09IENPTE9SX0xFVkVMX09GRiAmJlxuICAgIGxldmVsICE9PSBDT0xPUl9MRVZFTF9CQVNJQyAmJlxuICAgIGxldmVsICE9PSBDT0xPUl9MRVZFTF8yNTYgJiZcbiAgICBsZXZlbCAhPT0gQ09MT1JfTEVWRUxfVFJVRUNPTE9SXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY29sb3IgbGV2ZWxcIik7XG4gIH1cbiAgQ1VSUkVOVF9MRVZFTCA9IGxldmVsO1xufTtcblxuLy8gYnl0ZSBjbGFtcGluZ1xuY29uc3QgY2xhbXBCeXRlID0gKG46IG51bWJlcik6IG51bWJlciA9PiB7XG4gIGlmIChuIDw9IE1JTl9CWVRFIHx8ICFOdW1iZXIuaXNGaW5pdGUobikpIHJldHVybiBNSU5fQllURTtcbiAgaWYgKG4gPj0gTUFYX0JZVEUpIHJldHVybiBNQVhfQllURTtcbiAgcmV0dXJuIE1hdGgucm91bmQobik7XG59O1xuXG4vLyBCYXNlIDgtY29sb3IgUkdCIGFuY2hvcnMgKGZyb3plbiBmb3Igb3B0aW1pemF0aW9uKVxuY29uc3QgQkFTSUM4OiByZWFkb25seSBSZ2JbXSA9IE9iamVjdC5mcmVlemUoW1xuICBPYmplY3QuZnJlZXplKHsgcjogMCwgZzogMCwgYjogMCB9KSxcbiAgT2JqZWN0LmZyZWV6ZSh7IHI6IDIwNSwgZzogMCwgYjogMCB9KSxcbiAgT2JqZWN0LmZyZWV6ZSh7IHI6IDAsIGc6IDIwNSwgYjogMCB9KSxcbiAgT2JqZWN0LmZyZWV6ZSh7IHI6IDIwNSwgZzogMjA1LCBiOiAwIH0pLFxuICBPYmplY3QuZnJlZXplKHsgcjogMCwgZzogMCwgYjogMjM4IH0pLFxuICBPYmplY3QuZnJlZXplKHsgcjogMjA1LCBnOiAwLCBiOiAyMDUgfSksXG4gIE9iamVjdC5mcmVlemUoeyByOiAwLCBnOiAyMDUsIGI6IDIwNSB9KSxcbiAgT2JqZWN0LmZyZWV6ZSh7IHI6IDIyOSwgZzogMjI5LCBiOiAyMjkgfSksXG5dKSBhcyByZWFkb25seSBSZ2JbXTtcblxuLy8gU0dSIHNlcXVlbmNlIGNhY2hlIGZvciBjb21tb24gY29kZXNcbmNvbnN0IHNnckNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcblxuY29uc3Qgc2dyID0gKGNvZGVzOiBudW1iZXJbXSk6IHN0cmluZyA9PiB7XG4gIC8vIEZhc3QgcGF0aCBmb3Igc2luZ2xlIGNvZGVzXG4gIGlmIChjb2Rlcy5sZW5ndGggPT09IDEpIHtcbiAgICBjb25zdCBjb2RlID0gY29kZXNbMF07XG4gICAgY29uc3QgY2FjaGVkID0gc2dyQ2FjaGUuZ2V0KFN0cmluZyhjb2RlKSk7XG4gICAgaWYgKGNhY2hlZCkgcmV0dXJuIGNhY2hlZDtcbiAgICBjb25zdCBzZXEgPSBgXFx4MUJbJHtjb2RlfW1gO1xuICAgIHNnckNhY2hlLnNldChTdHJpbmcoY29kZSksIHNlcSk7XG4gICAgcmV0dXJuIHNlcTtcbiAgfVxuXG4gIC8vIE11bHRpLWNvZGUgcGF0aFxuICBjb25zdCBrZXkgPSBjb2Rlcy5qb2luKFwiO1wiKTtcbiAgY29uc3QgY2FjaGVkID0gc2dyQ2FjaGUuZ2V0KGtleSk7XG4gIGlmIChjYWNoZWQpIHJldHVybiBjYWNoZWQ7XG4gIGNvbnN0IHNlcSA9IGBcXHgxQlske2tleX1tYDtcbiAgc2dyQ2FjaGUuc2V0KGtleSwgc2VxKTtcbiAgcmV0dXJuIHNlcTtcbn07XG5cbi8vIG5lYXJlc3QgYmFzaWMgY29sb3Igd2l0aCBlYXJseSBleGl0XG5jb25zdCBuZWFyZXN0QmFzaWNJbmRleCA9IChyZ2I6IFJnYik6IG51bWJlciA9PiB7XG4gIGlmIChJU19CVU4pIHtcbiAgICBjb25zdCBhbnNpU3RyID0gQnVuLmNvbG9yKHJnYiwgXCJhbnNpLTE2XCIpO1xuICAgIGlmIChhbnNpU3RyKSB7XG4gICAgICBjb25zdCBtYXRjaCA9IGFuc2lTdHIubWF0Y2goLzM4OzU7KFxcZCspLyk7XG4gICAgICBpZiAobWF0Y2g/LlsxXSkge1xuICAgICAgICByZXR1cm4gTnVtYmVyLnBhcnNlSW50KG1hdGNoWzFdLCAxMCkgJiA3OyAvLyBGYXN0ZXIgbW9kdWxvIGZvciBwb3dlciBvZiAyXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbGV0IGJlc3QgPSAwO1xuICBsZXQgYmVzdERpc3QgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG5cbiAgLy8gRWFybHkgZXhpdCBvbiBleGFjdCBtYXRjaFxuICBmb3IgKGxldCBpID0gMDsgaSA8IDg7IGkrKykge1xuICAgIGNvbnN0IGMgPSBCQVNJQzhbaV0hO1xuICAgIGNvbnN0IGRyID0gYy5yIC0gcmdiLnI7XG4gICAgY29uc3QgZGcgPSBjLmcgLSByZ2IuZztcbiAgICBjb25zdCBkYiA9IGMuYiAtIHJnYi5iO1xuXG4gICAgaWYgKGRyID09PSAwICYmIGRnID09PSAwICYmIGRiID09PSAwKSByZXR1cm4gaTsgLy8gRXhhY3QgbWF0Y2hcblxuICAgIGNvbnN0IGQgPSBkciAqIGRyICsgZGcgKiBkZyArIGRiICogZGI7XG4gICAgaWYgKGQgPCBiZXN0RGlzdCkge1xuICAgICAgYmVzdERpc3QgPSBkO1xuICAgICAgYmVzdCA9IGk7XG4gICAgfVxuICB9XG4gIHJldHVybiBiZXN0O1xufTtcblxuLy8gUkdCIHRvIEFOU0kgMjU2XG5jb25zdCByZ2JUb0Fuc2kyNTYgPSAocmdiOiBSZ2IpOiBudW1iZXIgPT4ge1xuICBpZiAoSVNfQlVOKSB7XG4gICAgY29uc3QgYW5zaVN0ciA9IEJ1bi5jb2xvcihyZ2IsIFwiYW5zaS0yNTZcIik7XG4gICAgaWYgKGFuc2lTdHIpIHtcbiAgICAgIGNvbnN0IG1hdGNoID0gYW5zaVN0ci5tYXRjaCgvMzg7NTsoXFxkKykvKTtcbiAgICAgIGlmIChtYXRjaD8uWzFdKSB7XG4gICAgICAgIHJldHVybiBOdW1iZXIucGFyc2VJbnQobWF0Y2hbMV0sIDEwKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBncmF5c2NhbGUgY2hlY2tcbiAgaWYgKHJnYi5yID09PSByZ2IuZyAmJiByZ2IuZyA9PT0gcmdiLmIpIHtcbiAgICBpZiAocmdiLnIgPCBBTlNJXzI1Nl9HUkFZU0NBTEVfTUlOKSByZXR1cm4gQU5TSV8yNTZfQkFTRV9PRkZTRVQ7XG4gICAgaWYgKHJnYi5yID4gQU5TSV8yNTZfR1JBWVNDQUxFX01BWCkgcmV0dXJuIEFOU0lfMjU2X0JSSUdIVF9USFJFU0hPTEQ7XG4gICAgY29uc3Qgc3RlcCA9IE1hdGgucm91bmQoXG4gICAgICAoKHJnYi5yIC0gQU5TSV8yNTZfR1JBWVNDQUxFX01JTikgLyBBTlNJXzI1Nl9HUkFZU0NBTEVfUkFOR0UpICpcbiAgICAgICAgQU5TSV8yNTZfR1JBWVNDQUxFX1NURVBTLFxuICAgICk7XG4gICAgcmV0dXJuIEFOU0lfMjU2X0dSQVlTQ0FMRV9CQVNFICsgc3RlcDtcbiAgfVxuXG4gIC8vIFJHQiBjYWxjdWxhdGlvbiB3aXRoIHJlZHVjZWQgb3BlcmF0aW9uc1xuICBjb25zdCByID0gKChyZ2IuciAqIEFOU0lfMjU2X1JHQl9MRVZFTFMgKyAxMjcpIC8gTUFYX0JZVEUpIHwgMDtcbiAgY29uc3QgZyA9ICgocmdiLmcgKiBBTlNJXzI1Nl9SR0JfTEVWRUxTICsgMTI3KSAvIE1BWF9CWVRFKSB8IDA7XG4gIGNvbnN0IGIgPSAoKHJnYi5iICogQU5TSV8yNTZfUkdCX0xFVkVMUyArIDEyNykgLyBNQVhfQllURSkgfCAwO1xuICByZXR1cm4gKFxuICAgIEFOU0lfMjU2X0JBU0VfT0ZGU0VUICtcbiAgICByICogQU5TSV8yNTZfUkdCX1JFRF9NVUxUSVBMSUVSICtcbiAgICBnICogQU5TSV8yNTZfUkdCX0dSRUVOX01VTFRJUExJRVIgK1xuICAgIGJcbiAgKTtcbn07XG5cbi8vIE5hbWVkIGNvbG9yc1xuY29uc3QgTkFNRURfQ09MT1JTOiBSZWNvcmQ8QmFzZUNvbG9yTmFtZSwgc3RyaW5nPiA9IHtcbiAgYmxhY2s6IFwiIzAwMDAwMFwiLFxuICByZWQ6IFwiI2ZmMDAwMFwiLFxuICBncmVlbjogXCIjMDBmZjAwXCIsXG4gIHllbGxvdzogXCIjZmZmZjAwXCIsXG4gIGJsdWU6IFwiIzAwMDBmZlwiLFxuICBtYWdlbnRhOiBcIiNmZjAwZmZcIixcbiAgY3lhbjogXCIjMDBmZmZmXCIsXG4gIHdoaXRlOiBcIiNmZmZmZmZcIixcbiAgZ3JheTogXCIjODA4MDgwXCIsXG4gIG9yYW5nZTogXCIjZmZhNTAwXCIsXG4gIHBpbms6IFwiI2ZmYzBjYlwiLFxuICBwdXJwbGU6IFwiIzgwMDA4MFwiLFxuICB0ZWFsOiBcIiMwMDgwODBcIixcbiAgbGltZTogXCIjMDBmZjAwXCIsXG4gIGJyb3duOiBcIiNhNTJhMmFcIixcbiAgbmF2eTogXCIjMDAwMDgwXCIsXG4gIG1hcm9vbjogXCIjODAwMDAwXCIsXG4gIG9saXZlOiBcIiM4MDgwMDBcIixcbiAgc2lsdmVyOiBcIiNjMGMwYzBcIixcbn07XG5cbi8vIFJHQiBjYWNoZSB3aXRoIGNvbW1vbiBjb2xvcnMgcHJlLXBvcHVsYXRlZFxuY29uc3QgcmdiQ2FjaGUgPSBuZXcgTWFwPEJhc2VDb2xvck5hbWUsIFJnYj4oKTtcblxuLy8gUHJlLXBvcHVsYXRlIGNhY2hlIHdpdGggY29tbW9uIGNvbG9yc1xuZm9yIChjb25zdCBuYW1lIG9mIFtcImJsYWNrXCIsIFwid2hpdGVcIiwgXCJyZWRcIiwgXCJncmVlblwiLCBcImJsdWVcIl0gYXMgY29uc3QpIHtcbiAgY29uc3QgaGV4ID0gTkFNRURfQ09MT1JTW25hbWVdO1xuICBpZiAoaGV4KSB7XG4gICAgY29uc3QgY2xlYW4gPSBoZXguc2xpY2UoMSk7XG4gICAgY29uc3QgciA9IE51bWJlci5wYXJzZUludChjbGVhbi5zbGljZSgwLCAyKSwgSEVYX1JBRElYKTtcbiAgICBjb25zdCBnID0gTnVtYmVyLnBhcnNlSW50KGNsZWFuLnNsaWNlKDIsIDQpLCBIRVhfUkFESVgpO1xuICAgIGNvbnN0IGIgPSBOdW1iZXIucGFyc2VJbnQoY2xlYW4uc2xpY2UoNCwgNiksIEhFWF9SQURJWCk7XG4gICAgcmdiQ2FjaGUuc2V0KG5hbWUsIE9iamVjdC5mcmVlemUoeyByLCBnLCBiIH0pKTtcbiAgfVxufVxuXG4vLyB3aGl0ZSBtaXhpbmdcbmNvbnN0IG1peFdpdGhXaGl0ZSA9IChyZ2I6IFJnYiwgZmFjdG9yOiBudW1iZXIpOiBSZ2IgPT4ge1xuICBjb25zdCBpbnZGYWN0b3IgPSAxIC0gZmFjdG9yO1xuICByZXR1cm4ge1xuICAgIHI6IGNsYW1wQnl0ZShyZ2IuciAqIGludkZhY3RvciArIFdISVRFX1JHQiAqIGZhY3RvciksXG4gICAgZzogY2xhbXBCeXRlKHJnYi5nICogaW52RmFjdG9yICsgV0hJVEVfUkdCICogZmFjdG9yKSxcbiAgICBiOiBjbGFtcEJ5dGUocmdiLmIgKiBpbnZGYWN0b3IgKyBXSElURV9SR0IgKiBmYWN0b3IpLFxuICB9O1xufTtcblxuLy8gaGV4IHBhcnNpbmcgd2l0aCBmZXdlciBzdHJpbmcgb3BlcmF0aW9uc1xuY29uc3QgZnJvbU5hbWVkID0gKG5hbWU6IEJhc2VDb2xvck5hbWUpOiBSZ2IgPT4ge1xuICBjb25zdCBjYWNoZWQgPSByZ2JDYWNoZS5nZXQobmFtZSk7XG4gIGlmIChjYWNoZWQpIHJldHVybiBjYWNoZWQ7XG5cbiAgY29uc3QgaGV4ID0gTkFNRURfQ09MT1JTW25hbWVdO1xuICBpZiAoIWhleCkgcmV0dXJuIHsgcjogMCwgZzogMCwgYjogMCB9O1xuXG4gIGlmIChJU19CVU4pIHtcbiAgICBjb25zdCByZ2IgPSBCdW4uY29sb3IoaGV4LCBcIntyZ2J9XCIpO1xuICAgIGlmIChyZ2IpIHtcbiAgICAgIHJnYkNhY2hlLnNldChuYW1lLCByZ2IpO1xuICAgICAgcmV0dXJuIHJnYjtcbiAgICB9XG4gIH1cblxuICBjb25zdCBjbGVhbiA9IGhleFswXSA9PT0gXCIjXCIgPyBoZXguc2xpY2UoMSkgOiBoZXg7XG4gIGNvbnN0IGxlbiA9IGNsZWFuLmxlbmd0aDtcblxuICBsZXQgcjogbnVtYmVyLCBnOiBudW1iZXIsIGI6IG51bWJlcjtcblxuICBpZiAobGVuID09PSAzKSB7XG4gICAgLy8gc2hvcnQgaGV4OiB1c2UgYml0IG9wZXJhdGlvbnNcbiAgICBjb25zdCBydiA9IE51bWJlci5wYXJzZUludChjbGVhblswXSEsIEhFWF9SQURJWCk7XG4gICAgY29uc3QgZ3YgPSBOdW1iZXIucGFyc2VJbnQoY2xlYW5bMV0hLCBIRVhfUkFESVgpO1xuICAgIGNvbnN0IGJ2ID0gTnVtYmVyLnBhcnNlSW50KGNsZWFuWzJdISwgSEVYX1JBRElYKTtcbiAgICByID0gKHJ2IDw8IDQpIHwgcnY7XG4gICAgZyA9IChndiA8PCA0KSB8IGd2O1xuICAgIGIgPSAoYnYgPDwgNCkgfCBidjtcbiAgfSBlbHNlIGlmIChsZW4gPT09IDYpIHtcbiAgICByID0gTnVtYmVyLnBhcnNlSW50KGNsZWFuLnNsaWNlKDAsIDIpLCBIRVhfUkFESVgpO1xuICAgIGcgPSBOdW1iZXIucGFyc2VJbnQoY2xlYW4uc2xpY2UoMiwgNCksIEhFWF9SQURJWCk7XG4gICAgYiA9IE51bWJlci5wYXJzZUludChjbGVhbi5zbGljZSg0LCA2KSwgSEVYX1JBRElYKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4geyByOiAwLCBnOiAwLCBiOiAwIH07XG4gIH1cblxuICBpZiAoTnVtYmVyLmlzTmFOKHIpIHx8IE51bWJlci5pc05hTihnKSB8fCBOdW1iZXIuaXNOYU4oYikpIHtcbiAgICByZXR1cm4geyByOiAwLCBnOiAwLCBiOiAwIH07XG4gIH1cblxuICBjb25zdCByZXN1bHQgPSBPYmplY3QuZnJlZXplKHsgciwgZywgYiB9KTtcbiAgcmdiQ2FjaGUuc2V0KG5hbWUsIHJlc3VsdCk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vLyBiYXNlIG5hbWUgZXh0cmFjdGlvblxuY29uc3QgdG9CYXNlTmFtZSA9IChjb21wb3VuZDogQnJpZ2h0Q29sb3JOYW1lKTogQmFzZUNvbG9yTmFtZSA9PiB7XG4gIGlmICghY29tcG91bmQpIHJldHVybiBcImJsYWNrXCI7XG4gIGNvbnN0IGJhc2UgPSBjb21wb3VuZC5zbGljZSgwLCAtQlJJR0hUX1NVRkZJWF9MRU5HVEgpO1xuICBpZiAoIWJhc2UpIHJldHVybiBcImJsYWNrXCI7XG4gIHJldHVybiAoYmFzZVswXSEudG9Mb3dlckNhc2UoKSArIGJhc2Uuc2xpY2UoMSkpIGFzIEJhc2VDb2xvck5hbWU7XG59O1xuXG5jb25zdCBwYXJzZUNvbG9yTmFtZSA9IChuYW1lOiBDb2xvck5hbWUpOiB7IHJnYjogUmdiOyB3YW50QnJpZ2h0OiBib29sZWFuIH0gPT4ge1xuICBpZiAoIW5hbWUpIHJldHVybiB7IHJnYjogeyByOiAwLCBnOiAwLCBiOiAwIH0sIHdhbnRCcmlnaHQ6IGZhbHNlIH07XG5cbiAgaWYgKG5hbWUuZW5kc1dpdGgoQlJJR0hUX1NVRkZJWCkpIHtcbiAgICBjb25zdCBiYXNlID0gdG9CYXNlTmFtZShuYW1lIGFzIEJyaWdodENvbG9yTmFtZSk7XG4gICAgY29uc3QgcmdiID0gZnJvbU5hbWVkKGJhc2UpO1xuICAgIGNvbnN0IHJnYkFkaiA9IG1peFdpdGhXaGl0ZShyZ2IsIEJSSUdIVF9NSVhfRkFDVE9SKTtcbiAgICByZXR1cm4geyByZ2I6IHJnYkFkaiwgd2FudEJyaWdodDogdHJ1ZSB9O1xuICB9XG4gIHJldHVybiB7IHJnYjogZnJvbU5hbWVkKG5hbWUgYXMgQmFzZUNvbG9yTmFtZSksIHdhbnRCcmlnaHQ6IGZhbHNlIH07XG59O1xuXG4vLyBBTlNJIHNlcXVlbmNlIGdlbmVyYXRpb24gd2l0aCByZWR1Y2VkIHN0cmluZyBvcGVyYXRpb25zXG5jb25zdCBvcGVuRm9yT3AgPSAob3A6IFNnck9wKTogc3RyaW5nID0+IHtcbiAgaWYgKENVUlJFTlRfTEVWRUwgPT09IENPTE9SX0xFVkVMX09GRikgcmV0dXJuIFwiXCI7XG5cbiAgc3dpdGNoIChvcC5raW5kKSB7XG4gICAgY2FzZSBcInN0eWxlXCI6XG4gICAgICByZXR1cm4gc2dyKG9wLm9wZW4pO1xuXG4gICAgY2FzZSBcImZnLWJhc2ljXCI6IHtcbiAgICAgIGNvbnN0IGNvZGUgPSAob3AuYnJpZ2h0ID8gU0dSX0ZHX0JSSUdIVF9CQVNFIDogU0dSX0ZHX0JBU0UpICsgb3AuaWR4O1xuICAgICAgcmV0dXJuIHNncihbY29kZV0pO1xuICAgIH1cblxuICAgIGNhc2UgXCJiZy1iYXNpY1wiOiB7XG4gICAgICBjb25zdCBjb2RlID0gKG9wLmJyaWdodCA/IFNHUl9CR19CUklHSFRfQkFTRSA6IFNHUl9CR19CQVNFKSArIG9wLmlkeDtcbiAgICAgIHJldHVybiBzZ3IoW2NvZGVdKTtcbiAgICB9XG5cbiAgICBjYXNlIFwiZmctMjU2XCI6IHtcbiAgICAgIGlmIChJU19CVU4pIHtcbiAgICAgICAgY29uc3QgYW5zaSA9IEJ1bi5jb2xvcihvcC5jb2RlLCBcImFuc2ktMjU2XCIpO1xuICAgICAgICBpZiAoYW5zaSkgcmV0dXJuIGFuc2k7XG4gICAgICB9XG4gICAgICByZXR1cm4gYFxceDFCWzM4OzU7JHtvcC5jb2RlfW1gO1xuICAgIH1cblxuICAgIGNhc2UgXCJiZy0yNTZcIjoge1xuICAgICAgaWYgKElTX0JVTikge1xuICAgICAgICBjb25zdCBmZ0Fuc2kgPSBCdW4uY29sb3Iob3AuY29kZSwgXCJhbnNpLTI1NlwiKTtcbiAgICAgICAgaWYgKGZnQW5zaSkgcmV0dXJuIGZnQW5zaS5yZXBsYWNlKFwiMzg7NTtcIiwgXCI0ODs1O1wiKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBgXFx4MUJbNDg7NTske29wLmNvZGV9bWA7XG4gICAgfVxuXG4gICAgY2FzZSBcImZnLXRydWVcIjoge1xuICAgICAgaWYgKElTX0JVTikge1xuICAgICAgICBjb25zdCBhbnNpID0gQnVuLmNvbG9yKG9wLnJnYiwgXCJhbnNpLTE2bVwiKTtcbiAgICAgICAgaWYgKGFuc2kpIHJldHVybiBhbnNpO1xuICAgICAgfVxuICAgICAgY29uc3QgeyByLCBnLCBiIH0gPSBvcC5yZ2I7XG4gICAgICByZXR1cm4gYFxceDFCWzM4OzI7JHtyfTske2d9OyR7Yn1tYDtcbiAgICB9XG5cbiAgICBjYXNlIFwiYmctdHJ1ZVwiOiB7XG4gICAgICBpZiAoSVNfQlVOKSB7XG4gICAgICAgIGNvbnN0IGZnQW5zaSA9IEJ1bi5jb2xvcihvcC5yZ2IsIFwiYW5zaS0xNm1cIik7XG4gICAgICAgIGlmIChmZ0Fuc2kpIHJldHVybiBmZ0Fuc2kucmVwbGFjZShcIjM4OzI7XCIsIFwiNDg7MjtcIik7XG4gICAgICB9XG4gICAgICBjb25zdCB7IHIsIGcsIGIgfSA9IG9wLnJnYjtcbiAgICAgIHJldHVybiBgXFx4MUJbNDg7Mjske3J9OyR7Z307JHtifW1gO1xuICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gXCJcIjtcbiAgfVxufTtcblxuLy8gb3BzLXRvLW9wZW4gd2l0aCBwcmUtYWxsb2NhdGVkIGFycmF5XG5jb25zdCBvcHNUb09wZW4gPSAob3BzOiBTZ3JPcFtdKTogc3RyaW5nID0+IHtcbiAgaWYgKENVUlJFTlRfTEVWRUwgPT09IENPTE9SX0xFVkVMX09GRikgcmV0dXJuIFwiXCI7XG5cbiAgY29uc3QgbGVuID0gb3BzLmxlbmd0aDtcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIFwiXCI7XG4gIGlmIChsZW4gPT09IDEpIHJldHVybiBvcGVuRm9yT3Aob3BzWzBdISk7XG5cbiAgLy8gRGlyZWN0IHN0cmluZyBidWlsZGluZyBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlXG4gIGxldCByZXN1bHQgPSBcIlwiO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgcmVzdWx0ICs9IG9wZW5Gb3JPcChvcHNbaV0hKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLy8gbXVsdGlsaW5lIHRleHQgcHJvY2Vzc2luZ1xuY29uc3QgYXBwbHlPcHNUb1RleHQgPSAob3BzOiBTZ3JPcFtdLCBpbnB1dDogQXBwbHlJbnB1dCk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHRleHQgPSBTdHJpbmcoaW5wdXQpO1xuICBjb25zdCB0ZXh0TGVuID0gdGV4dC5sZW5ndGg7XG5cbiAgaWYgKENVUlJFTlRfTEVWRUwgPT09IENPTE9SX0xFVkVMX09GRiB8fCBvcHMubGVuZ3RoID09PSAwIHx8IHRleHRMZW4gPT09IDApIHtcbiAgICByZXR1cm4gdGV4dDtcbiAgfVxuXG4gIGNvbnN0IG9wZW4gPSBvcHNUb09wZW4ob3BzKTtcbiAgaWYgKCFvcGVuKSByZXR1cm4gdGV4dDtcblxuICAvLyBGYXN0IHBhdGggZm9yIHNpbmdsZS1saW5lIHRleHQgKG1vc3QgY29tbW9uKVxuICBjb25zdCBubElkeCA9IHRleHQuaW5kZXhPZihcIlxcblwiKTtcbiAgaWYgKG5sSWR4ID09PSAtMSkge1xuICAgIHJldHVybiBgJHtvcGVufSR7dGV4dH0ke1JFU0VUfWA7XG4gIH1cblxuICAvLyBtdWx0aWxpbmUgd2l0aCBkaXJlY3Qgc3RyaW5nIGJ1aWxkaW5nXG4gIGxldCByZXN1bHQgPSBcIlwiO1xuICBsZXQgc3RhcnQgPSAwO1xuXG4gIHdoaWxlIChzdGFydCA8IHRleHRMZW4pIHtcbiAgICBjb25zdCBlbmQgPSB0ZXh0LmluZGV4T2YoXCJcXG5cIiwgc3RhcnQpO1xuXG4gICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgIC8vIExhc3QgbGluZVxuICAgICAgY29uc3QgbGluZSA9IHRleHQuc2xpY2Uoc3RhcnQpO1xuICAgICAgaWYgKGxpbmUpIHtcbiAgICAgICAgaWYgKGxpbmUuZW5kc1dpdGgoXCJcXHJcIikpIHtcbiAgICAgICAgICByZXN1bHQgKz0gYCR7b3Blbn0ke2xpbmUuc2xpY2UoMCwgLTEpfVxcciR7UkVTRVR9YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHQgKz0gYCR7b3Blbn0ke2xpbmV9JHtSRVNFVH1gO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyBMaW5lIHdpdGggbmV3bGluZVxuICAgIGlmIChzdGFydCA+IDApIHJlc3VsdCArPSBcIlxcblwiO1xuXG4gICAgY29uc3QgbGluZSA9IHRleHQuc2xpY2Uoc3RhcnQsIGVuZCk7XG4gICAgaWYgKGxpbmUpIHtcbiAgICAgIGlmIChsaW5lLmVuZHNXaXRoKFwiXFxyXCIpKSB7XG4gICAgICAgIHJlc3VsdCArPSBgJHtvcGVufSR7bGluZS5zbGljZSgwLCAtMSl9XFxyJHtSRVNFVH1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ICs9IGAke29wZW59JHtsaW5lfSR7UkVTRVR9YDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0ICs9IGAke29wZW59JHtSRVNFVH1gO1xuICAgIH1cblxuICAgIHN0YXJ0ID0gZW5kICsgMTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vLyBvcGVyYXRpb24gYnVpbGRlcnNcbmNvbnN0IG1rRmdPcHNGcm9tUmdiID0gKHJnYjogUmdiLCB3YW50QnJpZ2h0ID0gZmFsc2UpOiBTZ3JPcFtdID0+IHtcbiAgaWYgKENVUlJFTlRfTEVWRUwgPT09IENPTE9SX0xFVkVMX0JBU0lDKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHsga2luZDogXCJmZy1iYXNpY1wiLCBpZHg6IG5lYXJlc3RCYXNpY0luZGV4KHJnYiksIGJyaWdodDogd2FudEJyaWdodCB9LFxuICAgIF07XG4gIH1cbiAgaWYgKENVUlJFTlRfTEVWRUwgPT09IENPTE9SX0xFVkVMXzI1Nikge1xuICAgIHJldHVybiBbeyBraW5kOiBcImZnLTI1NlwiLCBjb2RlOiByZ2JUb0Fuc2kyNTYocmdiKSB9XTtcbiAgfVxuICByZXR1cm4gW3sga2luZDogXCJmZy10cnVlXCIsIHJnYiB9XTtcbn07XG5cbmNvbnN0IG1rQmdPcHNGcm9tUmdiID0gKHJnYjogUmdiLCB3YW50QnJpZ2h0ID0gZmFsc2UpOiBTZ3JPcFtdID0+IHtcbiAgaWYgKENVUlJFTlRfTEVWRUwgPT09IENPTE9SX0xFVkVMX0JBU0lDKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHsga2luZDogXCJiZy1iYXNpY1wiLCBpZHg6IG5lYXJlc3RCYXNpY0luZGV4KHJnYiksIGJyaWdodDogd2FudEJyaWdodCB9LFxuICAgIF07XG4gIH1cbiAgaWYgKENVUlJFTlRfTEVWRUwgPT09IENPTE9SX0xFVkVMXzI1Nikge1xuICAgIHJldHVybiBbeyBraW5kOiBcImJnLTI1NlwiLCBjb2RlOiByZ2JUb0Fuc2kyNTYocmdiKSB9XTtcbiAgfVxuICByZXR1cm4gW3sga2luZDogXCJiZy10cnVlXCIsIHJnYiB9XTtcbn07XG5cbi8vIFN0eWxlIHRhYmxlIHdpdGggZnJvemVuIG9iamVjdHNcbmNvbnN0IFNUWUxFX1RBQkxFOiBSZWNvcmQ8UmVTdHlsZUtleSwgU2dyT3A+ID0ge1xuICByZXNldDogT2JqZWN0LmZyZWV6ZSh7IGtpbmQ6IFwic3R5bGVcIiwgb3BlbjogW1NHUl9SRVNFVF0gfSksXG4gIGJvbGQ6IE9iamVjdC5mcmVlemUoeyBraW5kOiBcInN0eWxlXCIsIG9wZW46IFtTR1JfQk9MRF0gfSksXG4gIGRpbTogT2JqZWN0LmZyZWV6ZSh7IGtpbmQ6IFwic3R5bGVcIiwgb3BlbjogW1NHUl9ESU1dIH0pLFxuICBpdGFsaWM6IE9iamVjdC5mcmVlemUoeyBraW5kOiBcInN0eWxlXCIsIG9wZW46IFtTR1JfSVRBTElDXSB9KSxcbiAgdW5kZXJsaW5lOiBPYmplY3QuZnJlZXplKHsga2luZDogXCJzdHlsZVwiLCBvcGVuOiBbU0dSX1VOREVSTElORV0gfSksXG4gIGludmVyc2U6IE9iamVjdC5mcmVlemUoeyBraW5kOiBcInN0eWxlXCIsIG9wZW46IFtTR1JfSU5WRVJTRV0gfSksXG4gIGhpZGRlbjogT2JqZWN0LmZyZWV6ZSh7IGtpbmQ6IFwic3R5bGVcIiwgb3BlbjogW1NHUl9ISURERU5dIH0pLFxuICBzdHJpa2V0aHJvdWdoOiBPYmplY3QuZnJlZXplKHsga2luZDogXCJzdHlsZVwiLCBvcGVuOiBbU0dSX1NUUklLRVRIUk9VR0hdIH0pLFxufSBhcyBjb25zdDtcblxuLy8gUHJlLWNvbXB1dGVkIGxvb2t1cCBzZXRzIChmcm96ZW4pXG5jb25zdCBTVFlMRV9LRVlTID0gT2JqZWN0LmZyZWV6ZShcbiAgbmV3IFNldChbXG4gICAgXCJyZXNldFwiLFxuICAgIFwiYm9sZFwiLFxuICAgIFwiZGltXCIsXG4gICAgXCJpdGFsaWNcIixcbiAgICBcInVuZGVybGluZVwiLFxuICAgIFwiaW52ZXJzZVwiLFxuICAgIFwiaGlkZGVuXCIsXG4gICAgXCJzdHJpa2V0aHJvdWdoXCIsXG4gIF0pLFxuKTtcblxuY29uc3QgQ09MT1JfS0VZUyA9IE9iamVjdC5mcmVlemUobmV3IFNldChPYmplY3Qua2V5cyhOQU1FRF9DT0xPUlMpKSk7XG5jb25zdCBCUklHSFRfQ09MT1JfS0VZUyA9IE9iamVjdC5mcmVlemUoXG4gIG5ldyBTZXQoT2JqZWN0LmtleXMoTkFNRURfQ09MT1JTKS5tYXAoKG5hbWUpID0+IGAke25hbWV9QnJpZ2h0YCkpLFxuKTtcbmNvbnN0IEJHX0NPTE9SX0tFWVMgPSBPYmplY3QuZnJlZXplKFxuICBuZXcgU2V0KFxuICAgIE9iamVjdC5rZXlzKE5BTUVEX0NPTE9SUykubWFwKFxuICAgICAgKG5hbWUpID0+IGBiZyR7bmFtZVswXSEudG9VcHBlckNhc2UoKX0ke25hbWUuc2xpY2UoMSl9YCxcbiAgICApLFxuICApLFxuKTtcbmNvbnN0IEJHX0JSSUdIVF9DT0xPUl9LRVlTID0gT2JqZWN0LmZyZWV6ZShcbiAgbmV3IFNldChcbiAgICBPYmplY3Qua2V5cyhOQU1FRF9DT0xPUlMpLm1hcChcbiAgICAgIChuYW1lKSA9PiBgYmcke25hbWVbMF0hLnRvVXBwZXJDYXNlKCl9JHtuYW1lLnNsaWNlKDEpfUJyaWdodGAsXG4gICAgKSxcbiAgKSxcbik7XG5cbi8vIGtleSBjaGVja3Mgd2l0aCBlYXJseSByZXR1cm5zXG5jb25zdCBpc0NvbG9yS2V5ID0gKGtleTogc3RyaW5nKTogYm9vbGVhbiA9PlxuICBDT0xPUl9LRVlTLmhhcyhrZXkpIHx8IEJSSUdIVF9DT0xPUl9LRVlTLmhhcyhrZXkpO1xuXG5jb25zdCBpc0JnS2V5ID0gKGtleTogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gIGNvbnN0IGxlbiA9IGtleS5sZW5ndGg7XG4gIGlmIChsZW4gPD0gQkdfUFJFRklYX0xFTkdUSCB8fCBrZXlbMF0gIT09IFwiYlwiIHx8IGtleVsxXSAhPT0gXCJnXCIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIEJHX0NPTE9SX0tFWVMuaGFzKGtleSkgfHwgQkdfQlJJR0hUX0NPTE9SX0tFWVMuaGFzKGtleSk7XG59O1xuXG4vLyBQcm94eSBjYWNoZSBmb3IgcmV1c2luZyBjb21tb24gY2hhaW5zXG5jb25zdCBwcm94eUNhY2hlID0gbmV3IFdlYWtNYXA8U2dyT3BbXSwgUmU+KCk7XG5cbi8vIHByb3h5IHdpdGggcmVkdWNlZCBvdmVyaGVhZFxuY29uc3QgY2FsbGFibGVQcm94eSA9IChvcHM6IFNnck9wW10pOiBSZSA9PiB7XG4gIGNvbnN0IGNhY2hlZCA9IHByb3h5Q2FjaGUuZ2V0KG9wcyk7XG4gIGlmIChjYWNoZWQpIHJldHVybiBjYWNoZWQ7XG5cbiAgY29uc3QgYmFzZSA9ICgoaW5wdXQ6IEFwcGx5SW5wdXQpID0+XG4gICAgYXBwbHlPcHNUb1RleHQob3BzLCBpbnB1dCkpIGFzIEZvcm1hdENhbGxhYmxlO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShiYXNlLCBPUF9TWU1CT0wsIHtcbiAgICB2YWx1ZTogb3BzLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICB9KTtcblxuICBjb25zdCBwcm94eSA9IG5ldyBQcm94eShiYXNlIGFzIHVua25vd24gYXMgUmUsIHtcbiAgICBhcHBseShfdGFyZ2V0LCBfdGhpc0FyZywgYXJnQXJyYXkpIHtcbiAgICAgIHJldHVybiBhcHBseU9wc1RvVGV4dChvcHMsIGFyZ0FycmF5WzBdIGFzIEFwcGx5SW5wdXQpO1xuICAgIH0sXG5cbiAgICBnZXQoX3RhcmdldCwgcHJvcCkge1xuICAgICAgaWYgKHByb3AgPT09IE9QX1NZTUJPTCkgcmV0dXJuIG9wcztcblxuICAgICAgY29uc3Qga2V5ID0gU3RyaW5nKHByb3ApO1xuXG4gICAgICAvLyBTdHlsZSBrZXkgZmFzdCBwYXRoXG4gICAgICBpZiAoU1RZTEVfS0VZUy5oYXMoa2V5KSkge1xuICAgICAgICBjb25zdCBvcCA9IFNUWUxFX1RBQkxFW2tleSBhcyBSZVN0eWxlS2V5XTtcbiAgICAgICAgY29uc3QgbmV3T3BzID0gWy4uLm9wcywgb3BdO1xuICAgICAgICByZXR1cm4gY2FsbGFibGVQcm94eShuZXdPcHMpO1xuICAgICAgfVxuXG4gICAgICAvLyBCYWNrZ3JvdW5kIGNvbG9yIGZhc3QgcGF0aFxuICAgICAgaWYgKGlzQmdLZXkoa2V5KSkge1xuICAgICAgICBjb25zdCBjb2xvck5hbWUgPSAoa2V5WzJdIS50b0xvd2VyQ2FzZSgpICsga2V5LnNsaWNlKDMpKSBhcyBDb2xvck5hbWU7XG4gICAgICAgIGNvbnN0IHsgcmdiLCB3YW50QnJpZ2h0IH0gPSBwYXJzZUNvbG9yTmFtZShjb2xvck5hbWUpO1xuICAgICAgICBjb25zdCBiZ09wcyA9IG1rQmdPcHNGcm9tUmdiKHJnYiwgd2FudEJyaWdodCk7XG4gICAgICAgIGNvbnN0IG5ld09wcyA9IFsuLi5vcHMsIC4uLmJnT3BzXTtcbiAgICAgICAgcmV0dXJuIGNhbGxhYmxlUHJveHkobmV3T3BzKTtcbiAgICAgIH1cblxuICAgICAgLy8gRm9yZWdyb3VuZCBjb2xvciBmYXN0IHBhdGhcbiAgICAgIGlmIChpc0NvbG9yS2V5KGtleSkpIHtcbiAgICAgICAgY29uc3QgeyByZ2IsIHdhbnRCcmlnaHQgfSA9IHBhcnNlQ29sb3JOYW1lKGtleSBhcyBDb2xvck5hbWUpO1xuICAgICAgICBjb25zdCBmZ09wcyA9IG1rRmdPcHNGcm9tUmdiKHJnYiwgd2FudEJyaWdodCk7XG4gICAgICAgIGNvbnN0IG5ld09wcyA9IFsuLi5vcHMsIC4uLmZnT3BzXTtcbiAgICAgICAgcmV0dXJuIGNhbGxhYmxlUHJveHkobmV3T3BzKTtcbiAgICAgIH1cblxuICAgICAgLy8gVW5rbm93biBrZXkg4oaSIHJldHVybiBzZWxmIChuby1vcClcbiAgICAgIHJldHVybiBwcm94eTtcbiAgICB9LFxuICB9KTtcblxuICBwcm94eUNhY2hlLnNldChvcHMsIHByb3h5KTtcbiAgcmV0dXJuIHByb3h5O1xufTtcblxuLy8gUHVibGljIHJvb3RcbmV4cG9ydCBjb25zdCByZTogUmUgPSBjYWxsYWJsZVByb3h5KFtdKTtcblxuLy8gY2hhaW4gd2l0aCByZWR1Y2VkIGFsbG9jYXRpb25zXG5leHBvcnQgY29uc3QgY2hhaW4gPSAoLi4ucGFydHM6IEZvcm1hdENhbGxhYmxlW10pOiBSZSA9PiB7XG4gIGlmIChwYXJ0cy5sZW5ndGggPT09IDApIHJldHVybiByZTtcbiAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHBhcnRzWzBdIGFzIFJlO1xuXG4gIGNvbnN0IGNvbGxlY3RlZDogU2dyT3BbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgb3BzID0gKHBhcnRzW2ldIGFzIEZvcm1hdENhbGxhYmxlKVtPUF9TWU1CT0xdIGFzIFNnck9wW10gfCB1bmRlZmluZWQ7XG4gICAgaWYgKG9wcz8ubGVuZ3RoKSB7XG4gICAgICBjb2xsZWN0ZWQucHVzaCguLi5vcHMpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjYWxsYWJsZVByb3h5KGNvbGxlY3RlZCk7XG59O1xuXG4vLyBCdW4gY29sb3IgaW5wdXQgdHlwZVxudHlwZSBCdW5Db2xvcklucHV0ID1cbiAgfCB7IHI6IG51bWJlcjsgZzogbnVtYmVyOyBiOiBudW1iZXI7IGE/OiBudW1iZXIgfVxuICB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXVxuICB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdXG4gIHwgc3RyaW5nXG4gIHwgbnVtYmVyXG4gIHwgeyB0b1N0cmluZygpOiBzdHJpbmcgfTtcblxuLy8gY29sb3IgZnVuY3Rpb24gd2l0aCBlYXJseSByZXR1cm5zXG5leHBvcnQgY29uc3QgY29sb3IgPSAoaW5wdXQ6IEJ1bkNvbG9ySW5wdXQsIGlzQmcgPSBmYWxzZSk6IFJlID0+IHtcbiAgaWYgKCFJU19CVU4pIHtcbiAgICBpZiAoXG4gICAgICB0eXBlb2YgaW5wdXQgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgIFwiclwiIGluIGlucHV0ICYmXG4gICAgICBcImdcIiBpbiBpbnB1dCAmJlxuICAgICAgXCJiXCIgaW4gaW5wdXRcbiAgICApIHtcbiAgICAgIGNvbnN0IG9wcyA9IGlzQmdcbiAgICAgICAgPyBta0JnT3BzRnJvbVJnYihpbnB1dCwgZmFsc2UpXG4gICAgICAgIDogbWtGZ09wc0Zyb21SZ2IoaW5wdXQsIGZhbHNlKTtcbiAgICAgIHJldHVybiBjYWxsYWJsZVByb3h5KG9wcyk7XG4gICAgfVxuICAgIHJldHVybiByZTtcbiAgfVxuXG4gIGNvbnN0IHJnYiA9IEJ1bi5jb2xvcihpbnB1dCwgXCJ7cmdifVwiKTtcbiAgaWYgKCFyZ2IpIHJldHVybiByZTtcblxuICBjb25zdCBvcHMgPSBpc0JnID8gbWtCZ09wc0Zyb21SZ2IocmdiLCBmYWxzZSkgOiBta0ZnT3BzRnJvbVJnYihyZ2IsIGZhbHNlKTtcbiAgcmV0dXJuIGNhbGxhYmxlUHJveHkob3BzKTtcbn07XG4iLAogICAgIi8qIFxuV2hlbiB0byBVc2UgQXN5bmMgdnMgU3luYzpcblVzZSBTWU5DIChsb2dnZXIpIHdoZW46XG7inIUgU2VxdWVudGlhbCBsb2dnaW5nIChsaWtlIHlvdXIgdHNjIGltcGxlbWVudGF0aW9uKVxu4pyFIENMSSB0b29scyB3aXRoIG9yZGVyZWQgb3V0cHV0XG7inIUgU21hbGwsIGZyZXF1ZW50IGNvbnNvbGUgd3JpdGVzXG7inIUgRXJyb3IgcmVwb3J0aW5nIHRoYXQgbmVlZHMgdG8gbWFpbnRhaW4gb3JkZXJcblVzZSBBU1lOQyAobG9nZ2VyQXN5bmMpIHdoZW46XG7inIUgTG9nZ2luZyBmcm9tIG11bHRpcGxlIGNvbmN1cnJlbnQgYXN5bmMgb3BlcmF0aW9uc1xu4pyFIEhpZ2gtZnJlcXVlbmN5IGxvZ2dpbmcgd2hlcmUgb3JkZXIgZG9lc24ndCBtYXR0ZXJcbuKchSBMYXJnZSBsb2cgb3V0cHV0cyB0aGF0IGNvdWxkIGJsb2NrXG7inIUgV2hlbiB5b3UgbmVlZCB0byBhd2FpdCBsb2dnaW5nIGNvbXBsZXRpb25cbiovXG5cbmltcG9ydCB7IHJlIH0gZnJvbSBcIkByZWxpdmVyc2UvZGxlci1jb2xvcnNcIjtcblxuY29uc3QgdGV4dEVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcblxuY29uc3QgTE9HX0NPTE9SUyA9IHtcbiAgbG9nOiByZS53aGl0ZSxcbiAgZXJyb3I6IHJlLnJlZCxcbiAgd2FybjogcmUueWVsbG93LFxuICBpbmZvOiByZS5ibHVlLFxuICBzdWNjZXNzOiByZS5ncmVlbixcbiAgZGVidWc6IHJlLmdyYXksXG59IGFzIGNvbnN0O1xuXG5jb25zdCBMT0dfU1lNQk9MUyA9IHtcbiAgbG9nOiBcIuKUgiAgXCIsXG4gIGVycm9yOiBcIuKcliAgXCIsXG4gIHdhcm46IFwi4pqgICBcIixcbiAgaW5mbzogXCLilqAgIFwiLFxuICBzdWNjZXNzOiBcIuKckyAgXCIsXG4gIGRlYnVnOiBcIuKcsSAgXCIsXG59IGFzIGNvbnN0O1xuXG50eXBlIExvZ0xldmVsID0ga2V5b2YgdHlwZW9mIExPR19DT0xPUlM7XG5cbi8vIFdyaXRlIGxvY2sgdG8gcHJldmVudCBpbnRlcmxlYXZpbmdcbmxldCB3cml0ZUxvY2sgPSBQcm9taXNlLnJlc29sdmUoKTtcblxuLy8gR2VuZXJpYyBtZXNzYWdlIGZvcm1hdHRlclxuY29uc3QgZm9ybWF0TWVzc2FnZSA9ICguLi5hcmdzOiB1bmtub3duW10pOiBzdHJpbmcgPT5cbiAgYXJncy5tYXAoU3RyaW5nKS5qb2luKFwiIFwiKTtcblxuLy8gR2VuZXJpYyBwcmVmaXhlZCBtZXNzYWdlIGNyZWF0b3JcbmNvbnN0IGNyZWF0ZVByZWZpeGVkTWVzc2FnZSA9IChsZXZlbDogTG9nTGV2ZWwsIG1lc3NhZ2U6IHN0cmluZyk6IHN0cmluZyA9PlxuICBgJHtMT0dfU1lNQk9MU1tsZXZlbF19JHttZXNzYWdlfWA7XG5cbi8vIEdlbmVyaWMgYXN5bmMgd3JpdGVyXG5jb25zdCB3cml0ZUFzeW5jID0gYXN5bmMgKHRleHQ6IHN0cmluZywgaXNFcnJvciA9IGZhbHNlKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGNvbnN0IGVuY29kZWQgPSB0ZXh0RW5jb2Rlci5lbmNvZGUoYCR7dGV4dH1cXG5gKTtcbiAgYXdhaXQgd3JpdGVMb2NrO1xuICB3cml0ZUxvY2sgPSBCdW4ud3JpdGUoaXNFcnJvciA/IEJ1bi5zdGRlcnIgOiBCdW4uc3Rkb3V0LCBlbmNvZGVkKS50aGVuKFxuICAgICgpID0+IHt9LFxuICApO1xuICBhd2FpdCB3cml0ZUxvY2s7XG59O1xuXG4vLyBHZW5lcmljIHN5bmMgd3JpdGVyXG5jb25zdCB3cml0ZVN5bmMgPSAodGV4dDogc3RyaW5nLCBpc0Vycm9yID0gZmFsc2UpOiB2b2lkID0+IHtcbiAgY29uc3QgZW5jb2RlZCA9IHRleHRFbmNvZGVyLmVuY29kZShgJHt0ZXh0fVxcbmApO1xuICAoaXNFcnJvciA/IHByb2Nlc3Muc3RkZXJyIDogcHJvY2Vzcy5zdGRvdXQpLndyaXRlKGVuY29kZWQpO1xufTtcblxuLy8gR2VuZXJpYyBjb2xvcmVkIGFzeW5jIHdyaXRlclxuY29uc3Qgd3JpdGVDb2xvcmVkQXN5bmMgPSBhc3luYyAoXG4gIHRleHQ6IHN0cmluZyxcbiAgY29sb3I6IHR5cGVvZiByZS53aGl0ZSxcbiAgaXNFcnJvciA9IGZhbHNlLFxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGNvbnN0IGNvbG9yZWRUZXh0ID0gY29sb3IodGV4dCk7XG4gIGF3YWl0IHdyaXRlQXN5bmMoY29sb3JlZFRleHQsIGlzRXJyb3IpO1xufTtcblxuLy8gR2VuZXJpYyBjb2xvcmVkIHN5bmMgd3JpdGVyXG5jb25zdCB3cml0ZUNvbG9yZWRTeW5jID0gKFxuICB0ZXh0OiBzdHJpbmcsXG4gIGNvbG9yOiB0eXBlb2YgcmUud2hpdGUsXG4gIGlzRXJyb3IgPSBmYWxzZSxcbik6IHZvaWQgPT4ge1xuICBjb25zdCBjb2xvcmVkVGV4dCA9IGNvbG9yKHRleHQpO1xuICB3cml0ZVN5bmMoY29sb3JlZFRleHQsIGlzRXJyb3IpO1xufTtcblxuLy8gR2VuZXJpYyBsb2cgbWV0aG9kIGNyZWF0b3Igd2l0aCBvdmVybG9hZHNcbmZ1bmN0aW9uIGNyZWF0ZUxvZ01ldGhvZChcbiAgbGV2ZWw6IExvZ0xldmVsLFxuICBpc0FzeW5jOiB0cnVlLFxuICBpc0Vycm9yPzogYm9vbGVhbixcbik6ICguLi5hcmdzOiB1bmtub3duW10pID0+IFByb21pc2U8dm9pZD47XG5mdW5jdGlvbiBjcmVhdGVMb2dNZXRob2QoXG4gIGxldmVsOiBMb2dMZXZlbCxcbiAgaXNBc3luYzogZmFsc2UsXG4gIGlzRXJyb3I/OiBib29sZWFuLFxuKTogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdm9pZDtcbmZ1bmN0aW9uIGNyZWF0ZUxvZ01ldGhvZChcbiAgbGV2ZWw6IExvZ0xldmVsLFxuICBpc0FzeW5jOiBib29sZWFuLFxuICBpc0Vycm9yID0gZmFsc2UsXG4pOiAoKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdm9pZCkgfCAoKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gUHJvbWlzZTx2b2lkPikge1xuICBpZiAoaXNBc3luYykge1xuICAgIHJldHVybiBhc3luYyAoLi4uYXJnczogdW5rbm93bltdKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gZm9ybWF0TWVzc2FnZSguLi5hcmdzKTtcbiAgICAgIGNvbnN0IHByZWZpeGVkTWVzc2FnZSA9IGNyZWF0ZVByZWZpeGVkTWVzc2FnZShsZXZlbCwgbWVzc2FnZSk7XG4gICAgICBhd2FpdCB3cml0ZUNvbG9yZWRBc3luYyhwcmVmaXhlZE1lc3NhZ2UsIExPR19DT0xPUlNbbGV2ZWxdLCBpc0Vycm9yKTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuICguLi5hcmdzOiB1bmtub3duW10pOiB2b2lkID0+IHtcbiAgICBjb25zdCBtZXNzYWdlID0gZm9ybWF0TWVzc2FnZSguLi5hcmdzKTtcbiAgICBjb25zdCBwcmVmaXhlZE1lc3NhZ2UgPSBjcmVhdGVQcmVmaXhlZE1lc3NhZ2UobGV2ZWwsIG1lc3NhZ2UpO1xuICAgIHdyaXRlQ29sb3JlZFN5bmMocHJlZml4ZWRNZXNzYWdlLCBMT0dfQ09MT1JTW2xldmVsXSwgaXNFcnJvcik7XG4gIH07XG59XG5cbi8vIEdlbmVyaWMgcmF3IG1ldGhvZCBjcmVhdG9yIHdpdGggb3ZlcmxvYWRzXG5mdW5jdGlvbiBjcmVhdGVSYXdNZXRob2QoaXNBc3luYzogdHJ1ZSk6ICguLi5hcmdzOiB1bmtub3duW10pID0+IFByb21pc2U8dm9pZD47XG5mdW5jdGlvbiBjcmVhdGVSYXdNZXRob2QoaXNBc3luYzogZmFsc2UpOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkO1xuZnVuY3Rpb24gY3JlYXRlUmF3TWV0aG9kKFxuICBpc0FzeW5jOiBib29sZWFuLFxuKTogKCguLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQpIHwgKCguLi5hcmdzOiB1bmtub3duW10pID0+IFByb21pc2U8dm9pZD4pIHtcbiAgaWYgKGlzQXN5bmMpIHtcbiAgICByZXR1cm4gYXN5bmMgKC4uLmFyZ3M6IHVua25vd25bXSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGZvcm1hdE1lc3NhZ2UoLi4uYXJncyk7XG4gICAgICBhd2FpdCB3cml0ZUFzeW5jKG1lc3NhZ2UpO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gKC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBmb3JtYXRNZXNzYWdlKC4uLmFyZ3MpO1xuICAgIHdyaXRlU3luYyhtZXNzYWdlKTtcbiAgfTtcbn1cblxuLy8gQmFzZSBpbnRlcmZhY2UgZm9yIGJvdGggc3luYyBhbmQgYXN5bmNcbmludGVyZmFjZSBMb2dnZXJCYXNlIHtcbiAgbG9nOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPjtcbiAgZXJyb3I6ICguLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+O1xuICB3YXJuOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPjtcbiAgaW5mbzogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdm9pZCB8IFByb21pc2U8dm9pZD47XG4gIHN1Y2Nlc3M6ICguLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+O1xuICBkZWJ1ZzogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdm9pZCB8IFByb21pc2U8dm9pZD47XG4gIHJhdzogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdm9pZCB8IFByb21pc2U8dm9pZD47XG59XG5cbmludGVyZmFjZSBMb2dnZXJBc3luYyBleHRlbmRzIExvZ2dlckJhc2Uge1xuICBsb2c6ICguLi5hcmdzOiB1bmtub3duW10pID0+IFByb21pc2U8dm9pZD47XG4gIGVycm9yOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiBQcm9taXNlPHZvaWQ+O1xuICB3YXJuOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiBQcm9taXNlPHZvaWQ+O1xuICBpbmZvOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiBQcm9taXNlPHZvaWQ+O1xuICBzdWNjZXNzOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiBQcm9taXNlPHZvaWQ+O1xuICBkZWJ1ZzogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgcmF3OiAoLi4uYXJnczogdW5rbm93bltdKSA9PiBQcm9taXNlPHZvaWQ+O1xufVxuXG5pbnRlcmZhY2UgTG9nZ2VyIGV4dGVuZHMgTG9nZ2VyQmFzZSB7XG4gIGxvZzogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdm9pZDtcbiAgZXJyb3I6ICguLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQ7XG4gIHdhcm46ICguLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQ7XG4gIGluZm86ICguLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQ7XG4gIHN1Y2Nlc3M6ICguLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQ7XG4gIGRlYnVnOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkO1xuICByYXc6ICguLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBjb25zdCBsb2dnZXJBc3luYzogTG9nZ2VyQXN5bmMgPSB7XG4gIGxvZzogY3JlYXRlTG9nTWV0aG9kKFwibG9nXCIsIHRydWUpLFxuICBlcnJvcjogY3JlYXRlTG9nTWV0aG9kKFwiZXJyb3JcIiwgdHJ1ZSwgdHJ1ZSksXG4gIHdhcm46IGNyZWF0ZUxvZ01ldGhvZChcIndhcm5cIiwgdHJ1ZSksXG4gIGluZm86IGNyZWF0ZUxvZ01ldGhvZChcImluZm9cIiwgdHJ1ZSksXG4gIHN1Y2Nlc3M6IGNyZWF0ZUxvZ01ldGhvZChcInN1Y2Nlc3NcIiwgdHJ1ZSksXG4gIGRlYnVnOiBjcmVhdGVMb2dNZXRob2QoXCJkZWJ1Z1wiLCB0cnVlKSxcbiAgcmF3OiBjcmVhdGVSYXdNZXRob2QodHJ1ZSksXG59O1xuXG5leHBvcnQgY29uc3QgbG9nZ2VyOiBMb2dnZXIgPSB7XG4gIGxvZzogY3JlYXRlTG9nTWV0aG9kKFwibG9nXCIsIGZhbHNlKSxcbiAgZXJyb3I6IGNyZWF0ZUxvZ01ldGhvZChcImVycm9yXCIsIGZhbHNlLCB0cnVlKSxcbiAgd2FybjogY3JlYXRlTG9nTWV0aG9kKFwid2FyblwiLCBmYWxzZSksXG4gIGluZm86IGNyZWF0ZUxvZ01ldGhvZChcImluZm9cIiwgZmFsc2UpLFxuICBzdWNjZXNzOiBjcmVhdGVMb2dNZXRob2QoXCJzdWNjZXNzXCIsIGZhbHNlKSxcbiAgZGVidWc6IGNyZWF0ZUxvZ01ldGhvZChcImRlYnVnXCIsIGZhbHNlKSxcbiAgcmF3OiBjcmVhdGVSYXdNZXRob2QoZmFsc2UpLFxufTtcbiIsCiAgICAidHlwZSBCYXNlT3B0aW9ucyA9IHtcbiAgLyoqXG4gICAqIE51bWJlciBvZiBjb25jdXJyZW50bHkgcGVuZGluZyBwcm9taXNlcyByZXR1cm5lZCBieSBgbWFwcGVyYC5cbiAgICpcbiAgICogTXVzdCBiZSBhbiBpbnRlZ2VyIGZyb20gMSBhbmQgdXAgb3IgYEluZmluaXR5YC5cbiAgICpcbiAgICogQGRlZmF1bHQgSW5maW5pdHlcbiAgICovXG4gIHJlYWRvbmx5IGNvbmN1cnJlbmN5PzogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgT3B0aW9ucyA9IEJhc2VPcHRpb25zICYge1xuICAvKipcbiAgICogV2hlbiBgdHJ1ZWAsIHRoZSBmaXJzdCBtYXBwZXIgcmVqZWN0aW9uIHdpbGwgYmUgcmVqZWN0ZWQgYmFjayB0byB0aGUgY29uc3VtZXIuXG4gICAqXG4gICAqIFdoZW4gYGZhbHNlYCwgaW5zdGVhZCBvZiBzdG9wcGluZyB3aGVuIGEgcHJvbWlzZSByZWplY3RzLCBpdCB3aWxsIHdhaXQgZm9yIGFsbFxuICAgKiB0aGUgcHJvbWlzZXMgdG8gc2V0dGxlIGFuZCB0aGVuIHJlamVjdCB3aXRoIGFuIGBBZ2dyZWdhdGVFcnJvcmAgY29udGFpbmluZyBhbGxcbiAgICogdGhlIGVycm9ycyBmcm9tIHRoZSByZWplY3RlZCBwcm9taXNlcy5cbiAgICpcbiAgICogQ2F2ZWF0OiBXaGVuIGB0cnVlYCwgYW55IGFscmVhZHktc3RhcnRlZCBhc3luYyBtYXBwZXJzIHdpbGwgY29udGludWUgdG8gcnVuXG4gICAqIHVudGlsIHRoZXkgcmVzb2x2ZSBvciByZWplY3QuIEluIHRoZSBjYXNlIG9mIGluZmluaXRlIGNvbmN1cnJlbmN5IHdpdGggc3luY1xuICAgKiBpdGVyYWJsZXMsIGFsbCBtYXBwZXJzIGFyZSBpbnZva2VkIG9uIHN0YXJ0dXAgYW5kIHdpbGwgY29udGludWUgYWZ0ZXIgdGhlIGZpcnN0XG4gICAqIHJlamVjdGlvbi4gQWJvcnRDb250cm9sIGNhbiBiZSB1c2VkIHRvIHN0b3AgcHVsbGluZyBuZXcgaXRlbXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHN0b3BPbkVycm9yPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogWW91IGNhbiBhYm9ydCB0aGUgcHJvbWlzZXMgdXNpbmcgYEFib3J0Q29udHJvbGxlcmAuXG4gICAqXG4gICAqIFJlamVjdHMgd2l0aCB0aGUgYHNpZ25hbC5yZWFzb25gIGltbWVkaWF0ZWx5LCBzdG9wcyBwdWxsaW5nIG5ldyBpdGVtcywgYW5kXG4gICAqIGF0dGVtcHRzIHRvIGNsb3NlIHRoZSB1bmRlcmx5aW5nIGl0ZXJhdG9yIHZpYSBgLnJldHVybigpYCBpZiBhdmFpbGFibGUuXG4gICAqL1xuICByZWFkb25seSBzaWduYWw/OiBBYm9ydFNpZ25hbDtcbn07XG5cbmV4cG9ydCB0eXBlIEl0ZXJhYmxlT3B0aW9ucyA9IEJhc2VPcHRpb25zICYge1xuICAvKipcbiAgICogTWF4aW11bSBudW1iZXIgb2YgcHJvbWlzZXMgcmV0dXJuZWQgYnkgYG1hcHBlcmAgdGhhdCBoYXZlIHJlc29sdmVkIGJ1dCBub3QgeWV0XG4gICAqIGNvbGxlY3RlZCBieSB0aGUgY29uc3VtZXIgb2YgdGhlIGFzeW5jIGl0ZXJhYmxlLiBDYWxscyB0byBgbWFwcGVyYCB3aWxsIGJlXG4gICAqIGxpbWl0ZWQgc28gdGhhdCB0aGVyZSBpcyBuZXZlciB0b28gbXVjaCBiYWNrcHJlc3N1cmUuXG4gICAqXG4gICAqIFVzZWZ1bCB3aGVuZXZlciB5b3UgYXJlIGNvbnN1bWluZyB0aGUgaXRlcmFibGUgc2xvd2VyIHRoYW4gd2hhdCB0aGUgbWFwcGVyXG4gICAqIGZ1bmN0aW9uIGNhbiBwcm9kdWNlIGNvbmN1cnJlbnRseS5cbiAgICpcbiAgICogRGVmYXVsdDogYG9wdGlvbnMuY29uY3VycmVuY3lgXG4gICAqL1xuICByZWFkb25seSBiYWNrcHJlc3N1cmU/OiBudW1iZXI7XG59O1xuXG50eXBlIE1heWJlUHJvbWlzZTxUPiA9IFQgfCBQcm9taXNlPFQ+O1xuXG4vKipcbiAqIEZ1bmN0aW9uIHdoaWNoIGlzIGNhbGxlZCBmb3IgZXZlcnkgaXRlbSBpbiBgaW5wdXRgLiBFeHBlY3RlZCB0byByZXR1cm4gYVxuICogYFByb21pc2VgIG9yIHZhbHVlLlxuICpcbiAqIEBwYXJhbSBlbGVtZW50IC0gSXRlcmF0ZWQgZWxlbWVudC5cbiAqIEBwYXJhbSBpbmRleCAtIEluZGV4IG9mIHRoZSBlbGVtZW50IGluIHRoZSBzb3VyY2UgYXJyYXkuXG4gKi9cbmV4cG9ydCB0eXBlIE1hcHBlcjxFbGVtZW50ID0gdW5rbm93biwgTmV3RWxlbWVudCA9IHVua25vd24+ID0gKFxuICBlbGVtZW50OiBFbGVtZW50LFxuICBpbmRleDogbnVtYmVyLFxuKSA9PiBNYXliZVByb21pc2U8TmV3RWxlbWVudCB8IHR5cGVvZiBwTWFwU2tpcD47XG5cbi8qKlxuICogUmV0dXJuIHRoaXMgdmFsdWUgZnJvbSBhIGBtYXBwZXJgIGZ1bmN0aW9uIHRvIHNraXAgaW5jbHVkaW5nIHRoZSB2YWx1ZSBpbiB0aGVcbiAqIHJldHVybmVkIGFycmF5LlxuICovXG5leHBvcnQgY29uc3QgcE1hcFNraXAgPSBTeW1ib2woXCJza2lwXCIpO1xuXG4vKipcbiAqIEBwYXJhbSBpbnB1dCAtIFN5bmNocm9ub3VzIG9yIGFzeW5jaHJvbm91cyBpdGVyYWJsZSB0aGF0IGlzIGl0ZXJhdGVkIG92ZXJcbiAqIGNvbmN1cnJlbnRseSwgY2FsbGluZyB0aGUgYG1hcHBlcmAgZnVuY3Rpb24gZm9yIGVhY2ggZWxlbWVudC4gRWFjaCBpdGVyYXRlZFxuICogaXRlbSBpcyBgYXdhaXRgJ2QgYmVmb3JlIHRoZSBgbWFwcGVyYCBpcyBpbnZva2VkIHNvIHRoZSBpdGVyYWJsZSBtYXkgcmV0dXJuIGFcbiAqIGBQcm9taXNlYCB0aGF0IHJlc29sdmVzIHRvIGFuIGl0ZW0uXG4gKiBAcGFyYW0gbWFwcGVyIC0gRnVuY3Rpb24gd2hpY2ggaXMgY2FsbGVkIGZvciBldmVyeSBpdGVtIGluIGBpbnB1dGAuIEV4cGVjdGVkXG4gKiB0byByZXR1cm4gYSBgUHJvbWlzZWAgb3IgdmFsdWUuXG4gKiBAcmV0dXJucyBBIGBQcm9taXNlYCB0aGF0IGlzIGZ1bGZpbGxlZCB3aGVuIGFsbCBwcm9taXNlcyBpbiBgaW5wdXRgIGFuZCBvbmVzXG4gKiByZXR1cm5lZCBmcm9tIGBtYXBwZXJgIGFyZSBmdWxmaWxsZWQsIG9yIHJlamVjdHMgaWYgYW55IG9mIHRoZSBwcm9taXNlc1xuICogcmVqZWN0LiBUaGUgZnVsZmlsbGVkIHZhbHVlIGlzIGFuIGBBcnJheWAgb2YgdGhlIGZ1bGZpbGxlZCB2YWx1ZXMgcmV0dXJuZWRcbiAqIGZyb20gYG1hcHBlcmAgaW4gYGlucHV0YCBvcmRlciwgZXhjbHVkaW5nIGBwTWFwU2tpcGAuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGFzeW5jIGZ1bmN0aW9uIHBNYXA8RWxlbWVudCwgTmV3RWxlbWVudD4oXG4gIGlucHV0OlxuICAgIHwgQXN5bmNJdGVyYWJsZTxFbGVtZW50IHwgUHJvbWlzZTxFbGVtZW50Pj5cbiAgICB8IEl0ZXJhYmxlPEVsZW1lbnQgfCBQcm9taXNlPEVsZW1lbnQ+PixcbiAgbWFwcGVyOiBNYXBwZXI8RWxlbWVudCwgTmV3RWxlbWVudD4sXG4gIG9wdGlvbnM6IE9wdGlvbnMgPSB7fSxcbik6IFByb21pc2U8QXJyYXk8RXhjbHVkZTxOZXdFbGVtZW50LCB0eXBlb2YgcE1hcFNraXA+Pj4ge1xuICBjb25zdCB7XG4gICAgY29uY3VycmVuY3kgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksXG4gICAgc3RvcE9uRXJyb3IgPSB0cnVlLFxuICAgIHNpZ25hbCxcbiAgfSA9IG9wdGlvbnM7XG5cbiAgaWYgKFxuICAgICEoXCJTeW1ib2xcIiBpbiBnbG9iYWxUaGlzKSB8fFxuICAgICgoaW5wdXQgYXMgYW55KVtTeW1ib2wuaXRlcmF0b3JdID09PSB1bmRlZmluZWQgJiZcbiAgICAgIChpbnB1dCBhcyBhbnkpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9PT0gdW5kZWZpbmVkKVxuICApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgYEV4cGVjdGVkIFxcYGlucHV0XFxgIHRvIGJlIGVpdGhlciBhbiBcXGBJdGVyYWJsZVxcYCBvciBcXGBBc3luY0l0ZXJhYmxlXFxgLCBgICtcbiAgICAgICAgYGdvdCAoJHt0eXBlb2YgaW5wdXR9KWAsXG4gICAgKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgbWFwcGVyICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTWFwcGVyIGZ1bmN0aW9uIGlzIHJlcXVpcmVkXCIpO1xuICB9XG5cbiAgaWYgKFxuICAgICEoXG4gICAgICAoTnVtYmVyLmlzU2FmZUludGVnZXIoY29uY3VycmVuY3kpICYmIGNvbmN1cnJlbmN5ID49IDEpIHx8XG4gICAgICBjb25jdXJyZW5jeSA9PT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZXG4gICAgKVxuICApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgYEV4cGVjdGVkIFxcYGNvbmN1cnJlbmN5XFxgIHRvIGJlIGFuIGludGVnZXIgZnJvbSAxIGFuZCB1cCBvciBgICtcbiAgICAgICAgYFxcYEluZmluaXR5XFxgLCBnb3QgXFxgJHtjb25jdXJyZW5jeX1cXGAgKCR7dHlwZW9mIGNvbmN1cnJlbmN5fSlgLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IGl0ZXJhdG9yID1cbiAgICAgIChpbnB1dCBhcyBhbnkpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gKGlucHV0IGFzIGFueSlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKClcbiAgICAgICAgOiAoaW5wdXQgYXMgYW55KVtTeW1ib2wuaXRlcmF0b3JdKCk7XG5cbiAgICBjb25zdCByZXN1bHRzOiBBcnJheTxOZXdFbGVtZW50IHwgdHlwZW9mIHBNYXBTa2lwPiA9IFtdO1xuICAgIGNvbnN0IGVycm9yczogRXJyb3JbXSA9IFtdO1xuXG4gICAgbGV0IGFjdGl2ZUNvdW50ID0gMDtcbiAgICBsZXQgY3VycmVudEluZGV4ID0gMDtcbiAgICBsZXQgaXNJdGVyYWJsZURvbmUgPSBmYWxzZTtcbiAgICBsZXQgaXNTZXR0bGVkID0gZmFsc2U7XG4gICAgbGV0IGlzUHVtcGluZyA9IGZhbHNlO1xuICAgIGxldCBpdGVyYXRvckNsb3NlZCA9IGZhbHNlO1xuXG4gICAgY29uc3Qgc2FmZUNsb3NlSXRlcmF0b3IgPSBhc3luYyAoKSA9PiB7XG4gICAgICBpZiAoaXRlcmF0b3JDbG9zZWQpIHJldHVybjtcbiAgICAgIGNvbnN0IHJldCA9IChpdGVyYXRvciBhcyBhbnkpPy5yZXR1cm47XG4gICAgICBpZiAodHlwZW9mIHJldCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaXRlcmF0b3JDbG9zZWQgPSB0cnVlO1xuICAgICAgICAgIGF3YWl0IHJldC5jYWxsKGl0ZXJhdG9yKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgLy8gU3dhbGxvdyBlcnJvcnMgY2xvc2luZyB0aGUgaXRlcmF0b3JcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXRlcmF0b3JDbG9zZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBvbkFib3J0ID0gKCkgPT4ge1xuICAgICAgaWYgKGlzU2V0dGxlZCkgcmV0dXJuO1xuICAgICAgaXNTZXR0bGVkID0gdHJ1ZTtcbiAgICAgIHZvaWQgc2FmZUNsb3NlSXRlcmF0b3IoKTtcbiAgICAgIGNsZWFudXAoKTtcbiAgICAgIHJlamVjdChzaWduYWwhLnJlYXNvbik7XG4gICAgfTtcblxuICAgIHNpZ25hbD8uYWRkRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIG9uQWJvcnQsIHsgb25jZTogdHJ1ZSB9KTtcblxuICAgIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgICBzaWduYWw/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBvbkFib3J0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXR0bGVXaXRoQWdncmVnYXRlSWZOZWVkZWQoKSB7XG4gICAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDAgJiYgIXN0b3BPbkVycm9yKSB7XG4gICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgcmVqZWN0KG5ldyBBZ2dyZWdhdGVFcnJvcihlcnJvcnMsIFwiT25lIG9yIG1vcmUgcHJvbWlzZXMgcmVqZWN0ZWRcIikpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlc29sdmVSZXN1bHRzKCkge1xuICAgICAgY2xlYW51cCgpO1xuICAgICAgLy8gQnVpbGQgZmlsdGVyZWQgYXJyYXkgaW4gb25lIHBhc3MsIHByZXNlcnZpbmcgb3JkZXJcbiAgICAgIGNvbnN0IG91dDogQXJyYXk8RXhjbHVkZTxOZXdFbGVtZW50LCB0eXBlb2YgcE1hcFNraXA+PiA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHYgPSByZXN1bHRzW2ldO1xuICAgICAgICBpZiAodiAhPT0gdW5kZWZpbmVkICYmIHYgIT09IHBNYXBTa2lwKSB7XG4gICAgICAgICAgb3V0LnB1c2godiBhcyBFeGNsdWRlPE5ld0VsZW1lbnQsIHR5cGVvZiBwTWFwU2tpcD4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXNvbHZlKG91dCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2tDb21wbGV0aW9uKCkge1xuICAgICAgaWYgKGlzU2V0dGxlZCkgcmV0dXJuO1xuICAgICAgaWYgKCFpc0l0ZXJhYmxlRG9uZSkgcmV0dXJuO1xuICAgICAgaWYgKGFjdGl2ZUNvdW50ID4gMCkgcmV0dXJuO1xuXG4gICAgICBpc1NldHRsZWQgPSB0cnVlO1xuXG4gICAgICBpZiAoc2V0dGxlV2l0aEFnZ3JlZ2F0ZUlmTmVlZGVkKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICByZXNvbHZlUmVzdWx0cygpO1xuICAgIH1cblxuICAgIGFzeW5jIGZ1bmN0aW9uIHN0YXJ0TWFwcGVyKFxuICAgICAgdmFsdWVPclByb21pc2U6IEVsZW1lbnQgfCBQcm9taXNlPEVsZW1lbnQ+LFxuICAgICAgaW5kZXg6IG51bWJlcixcbiAgICApIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBhd2FpdCB2YWx1ZU9yUHJvbWlzZTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbWFwcGVyKGl0ZW0sIGluZGV4KTtcbiAgICAgICAgaWYgKCFpc1NldHRsZWQpIHtcbiAgICAgICAgICByZXN1bHRzW2luZGV4XSA9IHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGlzU2V0dGxlZCkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChzdG9wT25FcnJvcikge1xuICAgICAgICAgIGlzU2V0dGxlZCA9IHRydWU7XG4gICAgICAgICAgdm9pZCBzYWZlQ2xvc2VJdGVyYXRvcigpO1xuICAgICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGVycm9ycy5wdXNoKGVycm9yIGFzIEVycm9yKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlmICghaXNTZXR0bGVkKSB7XG4gICAgICAgICAgYWN0aXZlQ291bnQtLTtcbiAgICAgICAgICBjaGVja0NvbXBsZXRpb24oKTtcbiAgICAgICAgICB2b2lkIHB1bXAoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGZ1bmN0aW9uIHB1bXAoKSB7XG4gICAgICBpZiAoaXNTZXR0bGVkIHx8IGlzUHVtcGluZykgcmV0dXJuO1xuICAgICAgaXNQdW1waW5nID0gdHJ1ZTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gUHVsbCBuZXcgaXRlbXMgc2VxdWVudGlhbGx5OyBuZXZlciBjYWxsIGl0ZXJhdG9yLm5leHQoKSBjb25jdXJyZW50bHkuXG4gICAgICAgIHdoaWxlICghaXNTZXR0bGVkICYmICFpc0l0ZXJhYmxlRG9uZSAmJiBhY3RpdmVDb3VudCA8IGNvbmN1cnJlbmN5KSB7XG4gICAgICAgICAgbGV0IG5leHQ6XG4gICAgICAgICAgICB8IEl0ZXJhdG9yUmVzdWx0PEVsZW1lbnQgfCBQcm9taXNlPEVsZW1lbnQ+PlxuICAgICAgICAgICAgfCBQcm9taXNlPEl0ZXJhdG9yUmVzdWx0PEVsZW1lbnQgfCBQcm9taXNlPEVsZW1lbnQ+Pj47XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV4dCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICAgIC8vIEVuc3VyZSB3ZSBhd2FpdCBuZXh0IGluIGNhc2UgaXQncyBhIHByb21pc2VcbiAgICAgICAgICAgIG5leHQgPSBhd2FpdCBuZXh0O1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBpZiAoIWlzU2V0dGxlZCkge1xuICAgICAgICAgICAgICBpc1NldHRsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICB2b2lkIHNhZmVDbG9zZUl0ZXJhdG9yKCk7XG4gICAgICAgICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobmV4dC5kb25lKSB7XG4gICAgICAgICAgICBpc0l0ZXJhYmxlRG9uZSA9IHRydWU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBpbmRleCA9IGN1cnJlbnRJbmRleCsrO1xuICAgICAgICAgIGFjdGl2ZUNvdW50Kys7XG4gICAgICAgICAgdm9pZCBzdGFydE1hcHBlcihuZXh0LnZhbHVlLCBpbmRleCk7XG4gICAgICAgIH1cblxuICAgICAgICBjaGVja0NvbXBsZXRpb24oKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlzUHVtcGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZvaWQgcHVtcCgpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBAcGFyYW0gaW5wdXQgLSBTeW5jaHJvbm91cyBvciBhc3luY2hyb25vdXMgaXRlcmFibGUgdGhhdCBpcyBpdGVyYXRlZCBvdmVyXG4gKiBjb25jdXJyZW50bHksIGNhbGxpbmcgdGhlIGBtYXBwZXJgIGZ1bmN0aW9uIGZvciBlYWNoIGVsZW1lbnQuIEVhY2ggaXRlcmF0ZWRcbiAqIGl0ZW0gaXMgYGF3YWl0YCdkIGJlZm9yZSB0aGUgYG1hcHBlcmAgaXMgaW52b2tlZCBzbyB0aGUgaXRlcmFibGUgbWF5IHJldHVybiBhXG4gKiBgUHJvbWlzZWAgdGhhdCByZXNvbHZlcyB0byBhbiBpdGVtLlxuICogQHBhcmFtIG1hcHBlciAtIEZ1bmN0aW9uIHdoaWNoIGlzIGNhbGxlZCBmb3IgZXZlcnkgaXRlbSBpbiBgaW5wdXRgLiBFeHBlY3RlZFxuICogdG8gcmV0dXJuIGEgYFByb21pc2VgIG9yIHZhbHVlLlxuICogQHJldHVybnMgQW4gYXN5bmMgaXRlcmFibGUgdGhhdCBzdHJlYW1zIGVhY2ggcmV0dXJuIHZhbHVlIGZyb20gYG1hcHBlcmAgaW5cbiAqIG9yZGVyLCBleGNsdWRpbmcgYHBNYXBTa2lwYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBNYXBJdGVyYWJsZTxFbGVtZW50LCBOZXdFbGVtZW50PihcbiAgaW5wdXQ6XG4gICAgfCBBc3luY0l0ZXJhYmxlPEVsZW1lbnQgfCBQcm9taXNlPEVsZW1lbnQ+PlxuICAgIHwgSXRlcmFibGU8RWxlbWVudCB8IFByb21pc2U8RWxlbWVudD4+LFxuICBtYXBwZXI6IE1hcHBlcjxFbGVtZW50LCBOZXdFbGVtZW50PixcbiAgb3B0aW9uczogSXRlcmFibGVPcHRpb25zID0ge30sXG4pOiBBc3luY0l0ZXJhYmxlPEV4Y2x1ZGU8TmV3RWxlbWVudCwgdHlwZW9mIHBNYXBTa2lwPj4ge1xuICBjb25zdCB7IGNvbmN1cnJlbmN5ID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLCBiYWNrcHJlc3N1cmUgPSBjb25jdXJyZW5jeSB9ID1cbiAgICBvcHRpb25zO1xuXG4gIGlmIChcbiAgICAhKFwiU3ltYm9sXCIgaW4gZ2xvYmFsVGhpcykgfHxcbiAgICAoKGlucHV0IGFzIGFueSlbU3ltYm9sLml0ZXJhdG9yXSA9PT0gdW5kZWZpbmVkICYmXG4gICAgICAoaW5wdXQgYXMgYW55KVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPT09IHVuZGVmaW5lZClcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgIGBFeHBlY3RlZCBcXGBpbnB1dFxcYCB0byBiZSBlaXRoZXIgYW4gXFxgSXRlcmFibGVcXGAgb3IgXFxgQXN5bmNJdGVyYWJsZVxcYCwgYCArXG4gICAgICAgIGBnb3QgKCR7dHlwZW9mIGlucHV0fSlgLFxuICAgICk7XG4gIH1cblxuICBpZiAodHlwZW9mIG1hcHBlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk1hcHBlciBmdW5jdGlvbiBpcyByZXF1aXJlZFwiKTtcbiAgfVxuXG4gIGlmIChcbiAgICAhKFxuICAgICAgKE51bWJlci5pc1NhZmVJbnRlZ2VyKGNvbmN1cnJlbmN5KSAmJiBjb25jdXJyZW5jeSA+PSAxKSB8fFxuICAgICAgY29uY3VycmVuY3kgPT09IE51bWJlci5QT1NJVElWRV9JTkZJTklUWVxuICAgIClcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgIGBFeHBlY3RlZCBcXGBjb25jdXJyZW5jeVxcYCB0byBiZSBhbiBpbnRlZ2VyIGZyb20gMSBhbmQgdXAgb3IgYCArXG4gICAgICAgIGBcXGBJbmZpbml0eVxcYCwgZ290IFxcYCR7Y29uY3VycmVuY3l9XFxgICgke3R5cGVvZiBjb25jdXJyZW5jeX0pYCxcbiAgICApO1xuICB9XG5cbiAgaWYgKFxuICAgICEoXG4gICAgICAoTnVtYmVyLmlzU2FmZUludGVnZXIoYmFja3ByZXNzdXJlKSAmJiBiYWNrcHJlc3N1cmUgPj0gY29uY3VycmVuY3kpIHx8XG4gICAgICBiYWNrcHJlc3N1cmUgPT09IE51bWJlci5QT1NJVElWRV9JTkZJTklUWVxuICAgIClcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgIGBFeHBlY3RlZCBcXGBiYWNrcHJlc3N1cmVcXGAgdG8gYmUgYW4gaW50ZWdlciBmcm9tIGAgK1xuICAgICAgICBgXFxgY29uY3VycmVuY3lcXGAgKCR7Y29uY3VycmVuY3l9KSBhbmQgdXAgb3IgXFxgSW5maW5pdHlcXGAsIGdvdCBgICtcbiAgICAgICAgYFxcYCR7YmFja3ByZXNzdXJlfVxcYCAoJHt0eXBlb2YgYmFja3ByZXNzdXJlfSlgLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFzeW5jICpbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKCkge1xuICAgICAgY29uc3QgaXRlcmF0b3IgPVxuICAgICAgICAoaW5wdXQgYXMgYW55KVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8gKGlucHV0IGFzIGFueSlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKClcbiAgICAgICAgICA6IChpbnB1dCBhcyBhbnkpW1N5bWJvbC5pdGVyYXRvcl0oKTtcblxuICAgICAgdHlwZSBSZXN1bHRJdGVtID0ge1xuICAgICAgICB2YWx1ZT86IE5ld0VsZW1lbnQgfCB0eXBlb2YgcE1hcFNraXA7XG4gICAgICAgIGVycm9yPzogRXJyb3I7XG4gICAgICAgIGRvbmU6IGJvb2xlYW47XG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHRRdWV1ZTogQXJyYXk8UHJvbWlzZTxSZXN1bHRJdGVtPj4gPSBbXTtcbiAgICAgIGxldCBydW5uaW5nQ291bnQgPSAwO1xuICAgICAgbGV0IGN1cnJlbnRJbmRleCA9IDA7XG4gICAgICBsZXQgaXNEb25lID0gZmFsc2U7XG4gICAgICBsZXQgcHVsbGluZyA9IGZhbHNlO1xuICAgICAgbGV0IGl0ZXJhdG9yQ2xvc2VkID0gZmFsc2U7XG5cbiAgICAgIGNvbnN0IHNhZmVDbG9zZUl0ZXJhdG9yID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAoaXRlcmF0b3JDbG9zZWQpIHJldHVybjtcbiAgICAgICAgY29uc3QgcmV0ID0gKGl0ZXJhdG9yIGFzIGFueSk/LnJldHVybjtcbiAgICAgICAgaWYgKHR5cGVvZiByZXQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpdGVyYXRvckNsb3NlZCA9IHRydWU7XG4gICAgICAgICAgICBhd2FpdCByZXQuY2FsbChpdGVyYXRvcik7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzIGNsb3NpbmcgdGhlIGl0ZXJhdG9yXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZXJhdG9yQ2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2NoZWR1bGVQdWxsID0gKCkgPT4ge1xuICAgICAgICBpZiAocHVsbGluZyB8fCBpc0RvbmUpIHJldHVybjtcbiAgICAgICAgcHVsbGluZyA9IHRydWU7XG5cbiAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgd2hpbGUgKFxuICAgICAgICAgICAgICAhaXNEb25lICYmXG4gICAgICAgICAgICAgIHJ1bm5pbmdDb3VudCA8IGNvbmN1cnJlbmN5ICYmXG4gICAgICAgICAgICAgIHJlc3VsdFF1ZXVlLmxlbmd0aCA8IGJhY2twcmVzc3VyZVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGxldCBuZXh0OlxuICAgICAgICAgICAgICAgIHwgSXRlcmF0b3JSZXN1bHQ8RWxlbWVudCB8IFByb21pc2U8RWxlbWVudD4+XG4gICAgICAgICAgICAgICAgfCBQcm9taXNlPEl0ZXJhdG9yUmVzdWx0PEVsZW1lbnQgfCBQcm9taXNlPEVsZW1lbnQ+Pj47XG5cbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBuZXh0ID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgICAgICAgIG5leHQgPSBhd2FpdCBuZXh0O1xuICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGlzRG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgcmVzdWx0UXVldWUucHVzaChcbiAgICAgICAgICAgICAgICAgIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvciBhcyBFcnJvcixcbiAgICAgICAgICAgICAgICAgICAgZG9uZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKG5leHQuZG9uZSkge1xuICAgICAgICAgICAgICAgIGlzRG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgLy8gUHVzaCBhIHRlcm1pbmFsIG1hcmtlciBzbyB0aGUgY29uc3VtZXIgY2FuIGZpbmlzaCBjbGVhbmx5XG4gICAgICAgICAgICAgICAgcmVzdWx0UXVldWUucHVzaChQcm9taXNlLnJlc29sdmUoeyBkb25lOiB0cnVlIH0pKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gY3VycmVudEluZGV4Kys7XG4gICAgICAgICAgICAgIHJ1bm5pbmdDb3VudCsrO1xuXG4gICAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSAoYXN5bmMgKCk6IFByb21pc2U8UmVzdWx0SXRlbT4gPT4ge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gYXdhaXQgbmV4dC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG1hcHBlcihlbGVtZW50LCBpbmRleCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogcmVzdWx0LCBkb25lOiBmYWxzZSB9O1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4geyBlcnJvcjogZXJyb3IgYXMgRXJyb3IsIGRvbmU6IGZhbHNlIH07XG4gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgIHJ1bm5pbmdDb3VudC0tO1xuICAgICAgICAgICAgICAgICAgc2NoZWR1bGVQdWxsKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KSgpO1xuXG4gICAgICAgICAgICAgIHJlc3VsdFF1ZXVlLnB1c2gocHJvbWlzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHB1bGxpbmcgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCk7XG4gICAgICB9O1xuXG4gICAgICBzY2hlZHVsZVB1bGwoKTtcblxuICAgICAgd2hpbGUgKHJlc3VsdFF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzdWx0UXVldWUuc2hpZnQoKSE7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5lcnJvcikge1xuICAgICAgICAgIGF3YWl0IHNhZmVDbG9zZUl0ZXJhdG9yKCk7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgYXdhaXQgc2FmZUNsb3NlSXRlcmF0b3IoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzY2hlZHVsZVB1bGwoKTtcblxuICAgICAgICBpZiAocmVzdWx0LnZhbHVlICE9PSBwTWFwU2tpcCkge1xuICAgICAgICAgIHlpZWxkIHJlc3VsdC52YWx1ZSBhcyBFeGNsdWRlPE5ld0VsZW1lbnQsIHR5cGVvZiBwTWFwU2tpcD47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSWYgd2UgZXhoYXVzdGVkIHRoZSBxdWV1ZSB3aXRob3V0IHNlZWluZyBhIGRvbmUgbWFya2VyLCBlbnN1cmUgY2xlYW51cC5cbiAgICAgIGF3YWl0IHNhZmVDbG9zZUl0ZXJhdG9yKCk7XG4gICAgfSxcbiAgfTtcbn1cbiIsCiAgICAiLy8gcGFja2FnZXMvbGF1bmNoZXIvc3JjL2ltcGwvbGF1bmNoZXIvZGlzY292ZXJ5LnRzXG5cbmltcG9ydCBwTWFwIGZyb20gXCJAcmVsaXZlcnNlL2RsZXItbWFwcGVyXCI7XG5pbXBvcnQgeyBHbG9iIH0gZnJvbSBcImJ1blwiO1xuaW1wb3J0IHsgbG9hZE1ldGFkYXRhQ2FjaGUsIHNhdmVNZXRhZGF0YUNhY2hlIH0gZnJvbSBcIi4vY2FjaGVcIjtcbmltcG9ydCB7IENvbW1hbmRMb2FkRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB0eXBlIHtcbiAgQ21kRGVmaW5pdGlvbixcbiAgQ21kTWV0YWRhdGEsXG4gIENtZE5vZGUsXG4gIERpc2NvdmVyeVJlc3VsdCxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLy8gQ2FjaGUgZm9yIGZpbGUgc3RhdHMgdG8gYXZvaWQgcmVwZWF0ZWQgZmlsZXN5c3RlbSBjYWxsc1xuY29uc3QgZmlsZVN0YXRzQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgeyBtdGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfT4oKTtcblxuLy8gTW9kdWxlIGluc3RhbmNlIGNhY2hlIHRvIHByZXZlbnQgZHVwbGljYXRlIGltcG9ydHNcbmNvbnN0IG1vZHVsZUNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIENtZERlZmluaXRpb24+KCk7XG5cbmNvbnN0IGdldEZpbGVTdGF0cyA9IGFzeW5jIChmaWxlUGF0aDogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IGNhY2hlZCA9IGZpbGVTdGF0c0NhY2hlLmdldChmaWxlUGF0aCk7XG4gIGlmIChjYWNoZWQpIHJldHVybiBjYWNoZWQ7XG5cbiAgY29uc3Qgc3RhdHMgPSBhd2FpdCBCdW4uZmlsZShmaWxlUGF0aCkuc3RhdCgpO1xuICBjb25zdCByZXN1bHQgPSB7IG10aW1lOiBzdGF0cy5tdGltZS5nZXRUaW1lKCksIHNpemU6IHN0YXRzLnNpemUgfTtcbiAgZmlsZVN0YXRzQ2FjaGUuc2V0KGZpbGVQYXRoLCByZXN1bHQpO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLy8gTGF6eSBtZXRhZGF0YSBsb2FkZXIgdGhhdCBvbmx5IGxvYWRzIHdoZW4gbmVlZGVkXG5jb25zdCBjcmVhdGVMYXp5TWV0YWRhdGFMb2FkZXIgPSAoZmlsZVBhdGg6IHN0cmluZywgY21kTmFtZTogc3RyaW5nKSA9PiB7XG4gIGxldCBjYWNoZWRNZXRhZGF0YTogQ21kTWV0YWRhdGEgfCBudWxsID0gbnVsbDtcbiAgbGV0IGlzTG9hZGluZyA9IGZhbHNlO1xuICBsZXQgbG9hZFByb21pc2U6IFByb21pc2U8Q21kTWV0YWRhdGE+IHwgbnVsbCA9IG51bGw7XG5cbiAgcmV0dXJuIGFzeW5jICgpOiBQcm9taXNlPENtZE1ldGFkYXRhPiA9PiB7XG4gICAgaWYgKGNhY2hlZE1ldGFkYXRhKSByZXR1cm4gY2FjaGVkTWV0YWRhdGE7XG5cbiAgICBpZiAoaXNMb2FkaW5nICYmIGxvYWRQcm9taXNlKSB7XG4gICAgICByZXR1cm4gbG9hZFByb21pc2U7XG4gICAgfVxuXG4gICAgaXNMb2FkaW5nID0gdHJ1ZTtcbiAgICBsb2FkUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBPbmx5IGxvYWQgdGhlIG1vZHVsZSB0byBleHRyYWN0IG1ldGFkYXRhLCBkb24ndCBleGVjdXRlIGhhbmRsZXJcbiAgICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgaW1wb3J0KGZpbGVQYXRoKTtcbiAgICAgICAgY29uc3QgZGVmaW5pdGlvbiA9IG1vZHVsZS5kZWZhdWx0O1xuXG4gICAgICAgIGlmICghZGVmaW5pdGlvbiB8fCAhZGVmaW5pdGlvbi5jZmcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGNvbW1hbmQgZGVmaW5pdGlvblwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNtZE1ldGFkYXRhOiBDbWRNZXRhZGF0YSA9IHtcbiAgICAgICAgICBuYW1lOiBkZWZpbml0aW9uLmNmZy5uYW1lLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBkZWZpbml0aW9uLmNmZy5kZXNjcmlwdGlvbixcbiAgICAgICAgICBhbGlhc2VzOiBkZWZpbml0aW9uLmNmZy5hbGlhc2VzLFxuICAgICAgICAgIHZlcnNpb246IGRlZmluaXRpb24uY2ZnLnZlcnNpb24sXG4gICAgICAgICAgZXhhbXBsZXM6IGRlZmluaXRpb24uY2ZnLmV4YW1wbGVzLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNhY2hlZE1ldGFkYXRhID0gY21kTWV0YWRhdGE7XG4gICAgICAgIHJldHVybiBjbWRNZXRhZGF0YTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBDb21tYW5kTG9hZEVycm9yKGNtZE5hbWUsIGVycm9yKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICBsb2FkUHJvbWlzZSA9IG51bGw7XG4gICAgICB9XG4gICAgfSkoKTtcblxuICAgIHJldHVybiBsb2FkUHJvbWlzZTtcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBkaXNjb3ZlckNvbW1hbmRzID0gYXN5bmMgKFxuICBjbWRzRGlyOiBzdHJpbmcsXG4gIGJhc2VEaXI/OiBzdHJpbmcsXG4pOiBQcm9taXNlPERpc2NvdmVyeVJlc3VsdD4gPT4ge1xuICBjb25zdCByZWdpc3RyeSA9IG5ldyBNYXAoKTtcbiAgY29uc3QgYWxpYXNlcyA9IG5ldyBNYXAoKTtcbiAgY29uc3QgbWV0YWRhdGEgPSBuZXcgTWFwPHN0cmluZywgKCkgPT4gUHJvbWlzZTxDbWRNZXRhZGF0YT4+KCk7XG4gIGNvbnN0IGhpZXJhcmNoeSA9IG5ldyBNYXA8c3RyaW5nLCBDbWROb2RlPigpO1xuICBjb25zdCByb290Q29tbWFuZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3QgZmlsZVN0YXRzID0gbmV3IE1hcDxzdHJpbmcsIHsgbXRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0+KCk7XG4gIGNvbnN0IGZpbGVQYXRocyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIGNvbnN0IGxvYWRlZE1ldGFkYXRhID0gbmV3IE1hcDxzdHJpbmcsIENtZE1ldGFkYXRhPigpO1xuXG4gIC8vIFRyeSB0byBsb2FkIGZyb20gY2FjaGUgZmlyc3RcbiAgY29uc3QgY2FjaGVkTWV0YWRhdGEgPSBhd2FpdCBsb2FkTWV0YWRhdGFDYWNoZSgpO1xuICBjb25zdCBjYWNoZWRNZXRhZGF0YU1hcCA9IG5ldyBNYXA8c3RyaW5nLCBDbWRNZXRhZGF0YT4oKTtcblxuICBpZiAoY2FjaGVkTWV0YWRhdGEpIHtcbiAgICBmb3IgKGNvbnN0IFtjbWROYW1lLCBjbWRNZXRhZGF0YV0gb2YgY2FjaGVkTWV0YWRhdGEpIHtcbiAgICAgIGNhY2hlZE1ldGFkYXRhTWFwLnNldChjbWROYW1lLCBjbWRNZXRhZGF0YSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZ2xvYiA9IG5ldyBHbG9iKFwiKiovY21kLnRzXCIpO1xuICBjb25zdCBjd2QgPSBiYXNlRGlyID8gYCR7YmFzZURpcn0vJHtjbWRzRGlyfWAgOiBgJHtwcm9jZXNzLmN3ZCgpfS8ke2NtZHNEaXJ9YDtcblxuICAvLyBDb2xsZWN0IGFsbCBmaWxlcyBmaXJzdCwgdGhlbiBwcm9jZXNzIGluIHBhcmFsbGVsXG4gIGNvbnN0IGZpbGVzID0gYXdhaXQgQXJyYXkuZnJvbUFzeW5jKGdsb2Iuc2Nhbihjd2QpKTtcblxuICAvLyBQcm9jZXNzIGFsbCBmaWxlcyBpbiBwYXJhbGxlbCB3aXRoIGNvbnRyb2xsZWQgY29uY3VycmVuY3lcbiAgY29uc3QgZmlsZURhdGEgPSBhd2FpdCBwTWFwKFxuICAgIGZpbGVzLFxuICAgIGFzeW5jIChmaWxlKSA9PiB7XG4gICAgICBjb25zdCBwYXRoUGFydHMgPSBmaWxlLnNwbGl0KC9bL1xcXFxdLyk7XG4gICAgICBjb25zdCBjbWROYW1lID0gcGF0aFBhcnRzW3BhdGhQYXJ0cy5sZW5ndGggLSAyXTsgLy8gR2V0IHBhcmVudCBkaXJlY3RvcnkgbmFtZVxuICAgICAgY29uc3QgZmlsZVBhdGggPSBgJHtjd2R9LyR7ZmlsZX1gO1xuICAgICAgY29uc3Qgc3RhdHMgPSBhd2FpdCBnZXRGaWxlU3RhdHMoZmlsZVBhdGgpO1xuXG4gICAgICAvLyBDYWxjdWxhdGUgZGVwdGggYW5kIHBhcmVudFxuICAgICAgY29uc3QgZGVwdGggPSBwYXRoUGFydHMubGVuZ3RoIC0gMTsgLy8gU3VidHJhY3QgMSBmb3IgY21kLnRzXG4gICAgICBjb25zdCBwYXJlbnQgPSBkZXB0aCA+IDEgPyBwYXRoUGFydHNbMF0gOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGhQYXJ0cy5zbGljZSgwLCAtMSkuam9pbihcIi9cIik7IC8vIEZ1bGwgcGF0aCB3aXRob3V0IGNtZC50c1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjbWROYW1lOiBjbWROYW1lISxcbiAgICAgICAgZmlsZVBhdGgsXG4gICAgICAgIHN0YXRzLFxuICAgICAgICBmaWxlLFxuICAgICAgICBkZXB0aCxcbiAgICAgICAgcGFyZW50LFxuICAgICAgICBmdWxsUGF0aCxcbiAgICAgIH07XG4gICAgfSxcbiAgICB7IGNvbmN1cnJlbmN5OiAxMCB9LCAvLyBMaW1pdCBjb25jdXJyZW5jeSB0byBhdm9pZCBvdmVyd2hlbG1pbmcgZmlsZXN5c3RlbVxuICApO1xuXG4gIC8vIFByb2Nlc3MgYWxsIGZpbGUgZGF0YVxuICBmb3IgKGNvbnN0IHtcbiAgICBjbWROYW1lLFxuICAgIGZpbGVQYXRoLFxuICAgIHN0YXRzLFxuICAgIGRlcHRoLFxuICAgIHBhcmVudCxcbiAgICBmdWxsUGF0aCxcbiAgfSBvZiBmaWxlRGF0YSkge1xuICAgIGNvbnN0IGxvYWRlciA9IGFzeW5jICgpOiBQcm9taXNlPENtZERlZmluaXRpb24+ID0+IHtcbiAgICAgIC8vIENoZWNrIG1vZHVsZSBjYWNoZSBmaXJzdFxuICAgICAgaWYgKG1vZHVsZUNhY2hlLmhhcyhmaWxlUGF0aCkpIHtcbiAgICAgICAgcmV0dXJuIG1vZHVsZUNhY2hlLmdldChmaWxlUGF0aCkhO1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBpbXBvcnQoZmlsZVBhdGgpO1xuICAgICAgICBjb25zdCBkZWZpbml0aW9uID0gbW9kdWxlLmRlZmF1bHQ7XG5cbiAgICAgICAgaWYgKCFkZWZpbml0aW9uIHx8IHR5cGVvZiBkZWZpbml0aW9uLmhhbmRsZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY29tbWFuZCBkZWZpbml0aW9uXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2FjaGUgdGhlIG1vZHVsZSBpbnN0YW5jZVxuICAgICAgICBtb2R1bGVDYWNoZS5zZXQoZmlsZVBhdGgsIGRlZmluaXRpb24pO1xuICAgICAgICByZXR1cm4gZGVmaW5pdGlvbjtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBDb21tYW5kTG9hZEVycm9yKGNtZE5hbWUsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZmlsZVN0YXRzLnNldChjbWROYW1lLCBzdGF0cyk7XG4gICAgZmlsZVBhdGhzLnNldChjbWROYW1lLCBmaWxlUGF0aCk7XG5cbiAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIHZhbGlkIGNhY2hlZCBtZXRhZGF0YVxuICAgIGNvbnN0IGNhY2hlZE1ldGEgPSBjYWNoZWRNZXRhZGF0YU1hcC5nZXQoY21kTmFtZSk7XG4gICAgaWYgKGNhY2hlZE1ldGEgJiYgKGF3YWl0IGlzQ2FjaGVWYWxpZChmaWxlUGF0aCwgc3RhdHMpKSkge1xuICAgICAgLy8gVXNlIGNhY2hlZCBtZXRhZGF0YVxuICAgICAgY29uc3QgbGF6eU1ldGFkYXRhTG9hZGVyID0gKCkgPT4gUHJvbWlzZS5yZXNvbHZlKGNhY2hlZE1ldGEpO1xuICAgICAgbWV0YWRhdGEuc2V0KGNtZE5hbWUsIGxhenlNZXRhZGF0YUxvYWRlcik7XG4gICAgICBsb2FkZWRNZXRhZGF0YS5zZXQoY21kTmFtZSwgY2FjaGVkTWV0YSk7XG5cbiAgICAgIC8vIFJlZ2lzdGVyIGFsaWFzZXMgZnJvbSBjYWNoZWQgbWV0YWRhdGFcbiAgICAgIGlmIChjYWNoZWRNZXRhLmFsaWFzZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBhbGlhcyBvZiBjYWNoZWRNZXRhLmFsaWFzZXMpIHtcbiAgICAgICAgICBhbGlhc2VzLnNldChhbGlhcywgY21kTmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQ3JlYXRlIGxhenkgbWV0YWRhdGEgbG9hZGVyIGZvciB1bmNhY2hlZCBjb21tYW5kc1xuICAgICAgY29uc3QgbGF6eU1ldGFkYXRhTG9hZGVyID0gY3JlYXRlTGF6eU1ldGFkYXRhTG9hZGVyKGZpbGVQYXRoLCBjbWROYW1lKTtcbiAgICAgIG1ldGFkYXRhLnNldChjbWROYW1lLCBsYXp5TWV0YWRhdGFMb2FkZXIpO1xuICAgIH1cblxuICAgIHJlZ2lzdHJ5LnNldChjbWROYW1lLCBsb2FkZXIpO1xuXG4gICAgLy8gQ3JlYXRlIGNvbW1hbmQgbm9kZSBmb3IgaGllcmFyY2h5XG4gICAgY29uc3QgY21kTm9kZTogQ21kTm9kZSA9IHtcbiAgICAgIG5hbWU6IGNtZE5hbWUsXG4gICAgICBwYXRoOiBmdWxsUGF0aCxcbiAgICAgIGRlcHRoLFxuICAgICAgcGFyZW50LFxuICAgICAgY2hpbGRyZW46IG5ldyBNYXAoKSxcbiAgICAgIGxvYWRlcixcbiAgICAgIG1ldGFkYXRhOiBtZXRhZGF0YS5nZXQoY21kTmFtZSkhLFxuICAgIH07XG5cbiAgICBoaWVyYXJjaHkuc2V0KGNtZE5hbWUsIGNtZE5vZGUpO1xuXG4gICAgLy8gVHJhY2sgcm9vdCBjb21tYW5kcyAoZGVwdGggMSlcbiAgICBpZiAoZGVwdGggPT09IDEpIHtcbiAgICAgIHJvb3RDb21tYW5kcy5hZGQoY21kTmFtZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gQnVpbGQgcGFyZW50LWNoaWxkIHJlbGF0aW9uc2hpcHNcbiAgZm9yIChjb25zdCBbY21kTmFtZSwgbm9kZV0gb2YgaGllcmFyY2h5KSB7XG4gICAgaWYgKG5vZGUucGFyZW50KSB7XG4gICAgICBjb25zdCBwYXJlbnROb2RlID0gaGllcmFyY2h5LmdldChub2RlLnBhcmVudCk7XG4gICAgICBpZiAocGFyZW50Tm9kZSkge1xuICAgICAgICBwYXJlbnROb2RlLmNoaWxkcmVuLnNldChjbWROYW1lLCBub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBTYXZlIHVwZGF0ZWQgY2FjaGUgaW4gYmFja2dyb3VuZCAoZG9uJ3QgYXdhaXQpXG4gIHNhdmVNZXRhZGF0YUNhY2hlKGxvYWRlZE1ldGFkYXRhLCBmaWxlU3RhdHMsIGZpbGVQYXRocykuY2F0Y2goKCkgPT4ge1xuICAgIC8vIElnbm9yZSBjYWNoZSBzYXZlIGVycm9yc1xuICB9KTtcblxuICByZXR1cm4geyByZWdpc3RyeSwgYWxpYXNlcywgbWV0YWRhdGEsIGhpZXJhcmNoeSwgcm9vdENvbW1hbmRzIH07XG59O1xuXG5jb25zdCBpc0NhY2hlVmFsaWQgPSBhc3luYyAoXG4gIGZpbGVQYXRoOiBzdHJpbmcsXG4gIHN0YXRzOiB7IG10aW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9LFxuKTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgZmlsZSA9IEJ1bi5maWxlKGZpbGVQYXRoKTtcbiAgICBjb25zdCBmaWxlU3RhdHMgPSBhd2FpdCBmaWxlLnN0YXQoKTtcbiAgICByZXR1cm4gKFxuICAgICAgZmlsZVN0YXRzLm10aW1lLmdldFRpbWUoKSA9PT0gc3RhdHMubXRpbWUgJiYgZmlsZVN0YXRzLnNpemUgPT09IHN0YXRzLnNpemVcbiAgICApO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUNvbW1hbmRTdHJ1Y3R1cmUgPSAoXG4gIGRlZmluaXRpb246IHVua25vd24sXG4pOiBkZWZpbml0aW9uIGlzIENtZERlZmluaXRpb24gPT4ge1xuICBpZiAodHlwZW9mIGRlZmluaXRpb24gIT09IFwib2JqZWN0XCIgfHwgZGVmaW5pdGlvbiA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuXG4gIGNvbnN0IGRlZiA9IGRlZmluaXRpb24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgZGVmLmhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgIHR5cGVvZiBkZWYuYXJncyA9PT0gXCJvYmplY3RcIiAmJlxuICAgIGRlZi5hcmdzICE9PSBudWxsICYmXG4gICAgdHlwZW9mIGRlZi5jZmcgPT09IFwib2JqZWN0XCIgJiZcbiAgICBkZWYuY2ZnICE9PSBudWxsICYmXG4gICAgdHlwZW9mIChkZWYuY2ZnIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5uYW1lID09PSBcInN0cmluZ1wiXG4gICk7XG59O1xuIiwKICAgICIvLyBwYWNrYWdlcy9sYXVuY2hlci9zcmMvaW1wbC9sYXVuY2hlci9jYWNoZS50c1xuXG5pbXBvcnQgeyBleGlzdHNTeW5jLCBta2RpclN5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgaG9tZWRpciB9IGZyb20gXCJub2RlOm9zXCI7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHBNYXAgZnJvbSBcIkByZWxpdmVyc2UvZGxlci1tYXBwZXJcIjtcbmltcG9ydCB0eXBlIHsgQ21kTWV0YWRhdGEgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5pbnRlcmZhY2UgQ2FjaGVFbnRyeSB7XG4gIG1ldGFkYXRhOiBDbWRNZXRhZGF0YTtcbiAgZmlsZVBhdGg6IHN0cmluZztcbiAgbXRpbWU6IG51bWJlcjtcbiAgc2l6ZTogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQ2FjaGVEYXRhIHtcbiAgZW50cmllczogUmVjb3JkPHN0cmluZywgQ2FjaGVFbnRyeT47XG4gIHZlcnNpb246IHN0cmluZztcbn1cblxuY29uc3QgQ0FDSEVfVkVSU0lPTiA9IFwiMS4wLjBcIjtcbmNvbnN0IENBQ0hFX0RJUiA9IFwiLnJlbGl2ZXJzZS9kbGVyL2NhY2hlL2xhdW5jaGVyXCI7XG5jb25zdCBDQUNIRV9GSUxFID0gXCJtZXRhZGF0YS5qc29uXCI7XG5cbmNvbnN0IGdldENhY2hlUGF0aCA9ICgpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBob21lRGlyID0gaG9tZWRpcigpO1xuICBjb25zdCBjYWNoZURpciA9IGpvaW4oaG9tZURpciwgQ0FDSEVfRElSKTtcbiAgaWYgKCFleGlzdHNTeW5jKGNhY2hlRGlyKSkge1xuICAgIG1rZGlyU3luYyhjYWNoZURpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIH1cbiAgcmV0dXJuIGpvaW4oY2FjaGVEaXIsIENBQ0hFX0ZJTEUpO1xufTtcblxuY29uc3QgaXNDYWNoZVZhbGlkID0gYXN5bmMgKGVudHJ5OiBDYWNoZUVudHJ5KTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgZmlsZSA9IEJ1bi5maWxlKGVudHJ5LmZpbGVQYXRoKTtcbiAgICBjb25zdCBzdGF0cyA9IGF3YWl0IGZpbGUuc3RhdCgpO1xuICAgIHJldHVybiBlbnRyeS5tdGltZSA9PT0gc3RhdHMubXRpbWUuZ2V0VGltZSgpICYmIGVudHJ5LnNpemUgPT09IHN0YXRzLnNpemU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGxvYWRNZXRhZGF0YUNhY2hlID0gYXN5bmMgKCk6IFByb21pc2U8TWFwPFxuICBzdHJpbmcsXG4gIENtZE1ldGFkYXRhXG4+IHwgbnVsbD4gPT4ge1xuICBjb25zdCBjYWNoZVBhdGggPSBnZXRDYWNoZVBhdGgoKTtcblxuICBpZiAoIWV4aXN0c1N5bmMoY2FjaGVQYXRoKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBjYWNoZUZpbGUgPSBCdW4uZmlsZShjYWNoZVBhdGgpO1xuICAgIGNvbnN0IGNhY2hlRGF0YTogQ2FjaGVEYXRhID0gYXdhaXQgY2FjaGVGaWxlLmpzb24oKTtcblxuICAgIGlmIChjYWNoZURhdGEudmVyc2lvbiAhPT0gQ0FDSEVfVkVSU0lPTikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgYWxsIGNhY2hlIGVudHJpZXMgaW4gcGFyYWxsZWwgd2l0aCBjb250cm9sbGVkIGNvbmN1cnJlbmN5XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHBNYXAoXG4gICAgICBPYmplY3QuZW50cmllcyhjYWNoZURhdGEuZW50cmllcyksXG4gICAgICBhc3luYyAoW2NtZE5hbWUsIGVudHJ5XSkgPT4gKHtcbiAgICAgICAgY21kTmFtZSxcbiAgICAgICAgbWV0YWRhdGE6IChhd2FpdCBpc0NhY2hlVmFsaWQoZW50cnkpKSA/IGVudHJ5Lm1ldGFkYXRhIDogbnVsbCxcbiAgICAgIH0pLFxuICAgICAgeyBjb25jdXJyZW5jeTogMjAgfSwgLy8gSGlnaGVyIGNvbmN1cnJlbmN5IGZvciBjYWNoZSB2YWxpZGF0aW9uXG4gICAgKTtcblxuICAgIGNvbnN0IG1ldGFkYXRhTWFwID0gbmV3IE1hcDxzdHJpbmcsIENtZE1ldGFkYXRhPigpO1xuICAgIGZvciAoY29uc3QgeyBjbWROYW1lLCBtZXRhZGF0YSB9IG9mIHJlc3VsdHMpIHtcbiAgICAgIGlmIChtZXRhZGF0YSkge1xuICAgICAgICBtZXRhZGF0YU1hcC5zZXQoY21kTmFtZSwgbWV0YWRhdGEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtZXRhZGF0YU1hcC5zaXplID4gMCA/IG1ldGFkYXRhTWFwIDogbnVsbDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzYXZlTWV0YWRhdGFDYWNoZSA9IGFzeW5jIChcbiAgbWV0YWRhdGE6IE1hcDxzdHJpbmcsIENtZE1ldGFkYXRhPixcbiAgZmlsZVN0YXRzOiBNYXA8c3RyaW5nLCB7IG10aW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9PixcbiAgZmlsZVBhdGhzOiBNYXA8c3RyaW5nLCBzdHJpbmc+LFxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGNvbnN0IGNhY2hlUGF0aCA9IGdldENhY2hlUGF0aCgpO1xuICBjb25zdCBlbnRyaWVzOiBSZWNvcmQ8c3RyaW5nLCBDYWNoZUVudHJ5PiA9IHt9O1xuXG4gIGZvciAoY29uc3QgW2NtZE5hbWUsIGNtZE1ldGFkYXRhXSBvZiBtZXRhZGF0YSkge1xuICAgIGNvbnN0IHN0YXRzID0gZmlsZVN0YXRzLmdldChjbWROYW1lKTtcbiAgICBjb25zdCBmaWxlUGF0aCA9IGZpbGVQYXRocy5nZXQoY21kTmFtZSk7XG4gICAgaWYgKHN0YXRzICYmIGZpbGVQYXRoKSB7XG4gICAgICBlbnRyaWVzW2NtZE5hbWVdID0ge1xuICAgICAgICBtZXRhZGF0YTogY21kTWV0YWRhdGEsXG4gICAgICAgIGZpbGVQYXRoLFxuICAgICAgICBtdGltZTogc3RhdHMubXRpbWUsXG4gICAgICAgIHNpemU6IHN0YXRzLnNpemUsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGNhY2hlRGF0YTogQ2FjaGVEYXRhID0ge1xuICAgIGVudHJpZXMsXG4gICAgdmVyc2lvbjogQ0FDSEVfVkVSU0lPTixcbiAgfTtcblxuICBhd2FpdCBCdW4ud3JpdGUoY2FjaGVQYXRoLCBKU09OLnN0cmluZ2lmeShjYWNoZURhdGEsIG51bGwsIDIpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjbGVhck1ldGFkYXRhQ2FjaGUgPSAoKTogdm9pZCA9PiB7XG4gIGNvbnN0IGNhY2hlUGF0aCA9IGdldENhY2hlUGF0aCgpO1xuICBpZiAoZXhpc3RzU3luYyhjYWNoZVBhdGgpKSB7XG4gICAgQnVuLndyaXRlKGNhY2hlUGF0aCwgXCJ7fVwiKTtcbiAgfVxufTtcbiIsCiAgICAiLy8gcGFja2FnZXMvbGF1bmNoZXIvc3JjL2ltcGwvbGF1bmNoZXIvZXJyb3JzLnRzXG5cbmV4cG9ydCBjbGFzcyBMYXVuY2hlckVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICAgcHVibGljIGNvZGU6IHN0cmluZyxcbiAgKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gXCJMYXVuY2hlckVycm9yXCI7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIENvbW1hbmROb3RGb3VuZEVycm9yIGV4dGVuZHMgTGF1bmNoZXJFcnJvciB7XG4gIGNvbnN0cnVjdG9yKGNtZE5hbWU6IHN0cmluZywgYXZhaWxhYmxlQ21kczogc3RyaW5nW10pIHtcbiAgICBzdXBlcihcbiAgICAgIGBDb21tYW5kIFwiJHtjbWROYW1lfVwiIG5vdCBmb3VuZC4gQXZhaWxhYmxlIGNvbW1hbmRzOiAke2F2YWlsYWJsZUNtZHMuam9pbihcIiwgXCIpfWAsXG4gICAgICBcIkNNRF9OT1RfRk9VTkRcIixcbiAgICApO1xuICAgIHRoaXMubmFtZSA9IFwiQ29tbWFuZE5vdEZvdW5kRXJyb3JcIjtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQXJndW1lbnRWYWxpZGF0aW9uRXJyb3IgZXh0ZW5kcyBMYXVuY2hlckVycm9yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGFyZ05hbWU6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhc29uOiBzdHJpbmcsXG4gICkge1xuICAgIHN1cGVyKGBJbnZhbGlkIGFyZ3VtZW50IFwiJHthcmdOYW1lfVwiOiAke3JlYXNvbn1gLCBcIkFSR19WQUxJREFUSU9OX0VSUk9SXCIpO1xuICAgIHRoaXMubmFtZSA9IFwiQXJndW1lbnRWYWxpZGF0aW9uRXJyb3JcIjtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ29tbWFuZExvYWRFcnJvciBleHRlbmRzIExhdW5jaGVyRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihjbWROYW1lOiBzdHJpbmcsIGNhdXNlOiB1bmtub3duKSB7XG4gICAgc3VwZXIoYEZhaWxlZCB0byBsb2FkIGNvbW1hbmQgXCIke2NtZE5hbWV9XCJgLCBcIkNNRF9MT0FEX0VSUk9SXCIpO1xuICAgIHRoaXMubmFtZSA9IFwiQ29tbWFuZExvYWRFcnJvclwiO1xuICAgIHRoaXMuY2F1c2UgPSBjYXVzZTtcbiAgfVxufVxuIiwKICAgICIvLyBwYWNrYWdlcy9sYXVuY2hlci9zcmMvaW1wbC9sYXVuY2hlci9oZWxwLnRzXG5cbmltcG9ydCBwTWFwIGZyb20gXCJAcmVsaXZlcnNlL2RsZXItbWFwcGVyXCI7XG5pbXBvcnQgdHlwZSB7XG4gIENtZEFyZ3NTY2hlbWEsXG4gIENtZERlZmluaXRpb24sXG4gIENtZE1ldGFkYXRhLFxuICBEaXNjb3ZlcnlSZXN1bHQsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8vIFByZS1jb21wdXRlZCBoZWxwIHRlbXBsYXRlcyB0byBhdm9pZCBzdHJpbmcgY29uY2F0ZW5hdGlvblxuY29uc3QgSEVMUF9URU1QTEFURVMgPSB7XG4gIGNvbW1hbmRIZWFkZXI6IChuYW1lOiBzdHJpbmcsIGRlc2NyaXB0aW9uOiBzdHJpbmcpID0+XG4gICAgYFxcbiR7bmFtZX0gLSAke2Rlc2NyaXB0aW9ufWAsXG4gIHZlcnNpb246ICh2ZXJzaW9uOiBzdHJpbmcpID0+IGBWZXJzaW9uOiAke3ZlcnNpb259YCxcbiAgdXNhZ2U6IChuYW1lOiBzdHJpbmcpID0+IGBcXG5Vc2FnZTpcXG4gICR7bmFtZX0gW29wdGlvbnNdYCxcbiAgdXNhZ2VXaXRoU3ViQ29tbWFuZHM6IChuYW1lOiBzdHJpbmcpID0+XG4gICAgYFxcblVzYWdlOlxcbiAgJHtuYW1lfSBbc3ViY29tbWFuZF0gW29wdGlvbnNdYCxcbiAgb3B0aW9uc0hlYWRlcjogYFxcbk9wdGlvbnM6YCxcbiAgcmVxdWlyZWROb3RlOiBgXFxuKiA9IHJlcXVpcmVkYCxcbiAgZXhhbXBsZXNIZWFkZXI6IGBcXG5FeGFtcGxlczpgLFxuICBnbG9iYWxIZWFkZXI6IGBcXG5BdmFpbGFibGUgY29tbWFuZHM6XFxuYCxcbiAgaGVscEZvb3RlcjogYFxcblVzZSBcImNvbW1hbmQgLS1oZWxwXCIgZm9yIGNvbW1hbmQtc3BlY2lmaWMgaGVscFxcbmAsXG59IGFzIGNvbnN0O1xuXG5jb25zdCBmb3JtYXRBcmdOYW1lID0gKG5hbWU6IHN0cmluZywgZGVmOiBDbWRBcmdzU2NoZW1hW3N0cmluZ10pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBhbGlhc2VzID0gZGVmLmFsaWFzZXMgPyBgICgtJHtkZWYuYWxpYXNlcy5qb2luKFwiLCAtXCIpfSlgIDogXCJcIjtcbiAgY29uc3QgcmVxdWlyZWQgPSBkZWYucmVxdWlyZWQgPyBcIipcIiA6IFwiXCI7XG4gIHJldHVybiBgLS0ke25hbWV9JHthbGlhc2VzfSR7cmVxdWlyZWR9YDtcbn07XG5cbmNvbnN0IGZvcm1hdEFyZ1R5cGUgPSAoZGVmOiBDbWRBcmdzU2NoZW1hW3N0cmluZ10pOiBzdHJpbmcgPT4ge1xuICBpZiAoZGVmLnR5cGUgPT09IFwiYm9vbGVhblwiKSByZXR1cm4gXCJcIjtcbiAgcmV0dXJuIGA8JHtkZWYudHlwZX0+YDtcbn07XG5cbi8vIENhY2hlIGZvciBmb3JtYXR0ZWQgYXJndW1lbnQgaGVscCB0byBhdm9pZCByZWNvbXB1dGF0aW9uXG5jb25zdCBhcmdIZWxwQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuXG4vLyBDYWNoZSBmb3IgZ2VuZXJhdGVkIGhlbHAgdGV4dCB3aXRoIGZpbGUgaGFzaCB2YWxpZGF0aW9uXG5pbnRlcmZhY2UgSGVscENhY2hlRW50cnkge1xuICBjb21tYW5kSGVscDogc3RyaW5nO1xuICBnbG9iYWxIZWxwOiBzdHJpbmc7XG4gIGZpbGVIYXNoOiBzdHJpbmc7XG4gIGxhc3RNb2RpZmllZDogbnVtYmVyO1xufVxuXG5jb25zdCBoZWxwQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgSGVscENhY2hlRW50cnk+KCk7XG5cbmNvbnN0IGdldEFyZ0hlbHAgPSAobmFtZTogc3RyaW5nLCBkZWY6IENtZEFyZ3NTY2hlbWFbc3RyaW5nXSk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGNhY2hlS2V5ID0gYCR7bmFtZX06JHtKU09OLnN0cmluZ2lmeShkZWYpfWA7XG4gIGxldCBjYWNoZWQgPSBhcmdIZWxwQ2FjaGUuZ2V0KGNhY2hlS2V5KTtcblxuICBpZiAoIWNhY2hlZCkge1xuICAgIGNvbnN0IGFyZ05hbWUgPSBmb3JtYXRBcmdOYW1lKG5hbWUsIGRlZik7XG4gICAgY29uc3QgYXJnVHlwZSA9IGZvcm1hdEFyZ1R5cGUoZGVmKTtcbiAgICBjb25zdCBkZXNjID0gZGVmLmRlc2NyaXB0aW9uID8/IFwiXCI7XG4gICAgY29uc3QgZGVmYXVsdFZhbCA9XG4gICAgICBcImRlZmF1bHRcIiBpbiBkZWYgJiYgZGVmLmRlZmF1bHQgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IGAgKGRlZmF1bHQ6ICR7ZGVmLmRlZmF1bHR9KWBcbiAgICAgICAgOiBcIlwiO1xuXG4gICAgY2FjaGVkID0gYCAgJHthcmdOYW1lfSAke2FyZ1R5cGV9XFxuICAgICAgJHtkZXNjfSR7ZGVmYXVsdFZhbH1gO1xuICAgIGFyZ0hlbHBDYWNoZS5zZXQoY2FjaGVLZXksIGNhY2hlZCk7XG4gIH1cblxuICByZXR1cm4gY2FjaGVkO1xufTtcblxuZXhwb3J0IGNvbnN0IGdlbmVyYXRlQ29tbWFuZEhlbHAgPSBhc3luYyAoXG4gIGRlZmluaXRpb246IENtZERlZmluaXRpb24sXG4pOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICBjb25zdCB7IGNmZywgYXJncyB9ID0gZGVmaW5pdGlvbjtcblxuICAvLyBDcmVhdGUgY2FjaGUga2V5IGJhc2VkIG9uIGNvbW1hbmQgY29uZmlndXJhdGlvblxuICBjb25zdCBjYWNoZUtleSA9IGAke2NmZy5uYW1lfToke0pTT04uc3RyaW5naWZ5KGNmZyl9OiR7SlNPTi5zdHJpbmdpZnkoYXJncyl9YDtcbiAgY29uc3QgY2FjaGVkID0gaGVscENhY2hlLmdldChjYWNoZUtleSk7XG5cbiAgaWYgKGNhY2hlZCkge1xuICAgIHJldHVybiBjYWNoZWQuY29tbWFuZEhlbHA7XG4gIH1cblxuICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXG4gICAgSEVMUF9URU1QTEFURVMuY29tbWFuZEhlYWRlcihcbiAgICAgIGNmZy5uYW1lLFxuICAgICAgY2ZnLmRlc2NyaXB0aW9uIHx8IFwiTm8gZGVzY3JpcHRpb24gYXZhaWxhYmxlXCIsXG4gICAgKSxcbiAgXTtcblxuICBpZiAoY2ZnLnZlcnNpb24pIHtcbiAgICBsaW5lcy5wdXNoKEhFTFBfVEVNUExBVEVTLnZlcnNpb24oY2ZnLnZlcnNpb24pKTtcbiAgfVxuXG4gIGxpbmVzLnB1c2goSEVMUF9URU1QTEFURVMudXNhZ2UoY2ZnLm5hbWUpKTtcblxuICBpZiAoT2JqZWN0LmtleXMoYXJncykubGVuZ3RoID4gMCkge1xuICAgIGxpbmVzLnB1c2goSEVMUF9URU1QTEFURVMub3B0aW9uc0hlYWRlcik7XG5cbiAgICAvLyBVc2UgY2FjaGVkIGFyZ3VtZW50IGhlbHBcbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBkZWZdIG9mIE9iamVjdC5lbnRyaWVzKGFyZ3MpKSB7XG4gICAgICBsaW5lcy5wdXNoKGdldEFyZ0hlbHAobmFtZSwgZGVmKSk7XG4gICAgfVxuXG4gICAgbGluZXMucHVzaChIRUxQX1RFTVBMQVRFUy5yZXF1aXJlZE5vdGUpO1xuICB9XG5cbiAgaWYgKGNmZy5leGFtcGxlcyAmJiBjZmcuZXhhbXBsZXMubGVuZ3RoID4gMCkge1xuICAgIGxpbmVzLnB1c2goSEVMUF9URU1QTEFURVMuZXhhbXBsZXNIZWFkZXIpO1xuICAgIGZvciAoY29uc3QgZXhhbXBsZSBvZiBjZmcuZXhhbXBsZXMpIHtcbiAgICAgIGxpbmVzLnB1c2goYCAgJHtleGFtcGxlfWApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGhlbHBUZXh0ID0gbGluZXMuam9pbihcIlxcblwiKTtcblxuICAvLyBDYWNoZSB0aGUgZ2VuZXJhdGVkIGhlbHBcbiAgaGVscENhY2hlLnNldChjYWNoZUtleSwge1xuICAgIGNvbW1hbmRIZWxwOiBoZWxwVGV4dCxcbiAgICBnbG9iYWxIZWxwOiBcIlwiLFxuICAgIGZpbGVIYXNoOiBcIlwiLFxuICAgIGxhc3RNb2RpZmllZDogRGF0ZS5ub3coKSxcbiAgfSk7XG5cbiAgcmV0dXJuIGhlbHBUZXh0O1xufTtcblxuLy8gQ2FjaGUgZm9yIGNvbW1hbmQgaGVscCBmb3JtYXR0aW5nXG5jb25zdCBjb21tYW5kSGVscENhY2hlID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcblxuY29uc3QgZm9ybWF0Q29tbWFuZEhlbHAgPSAobmFtZTogc3RyaW5nLCBtZXRhZGF0YTogQ21kTWV0YWRhdGEpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjYWNoZUtleSA9IGAke25hbWV9OiR7SlNPTi5zdHJpbmdpZnkobWV0YWRhdGEpfWA7XG4gIGxldCBjYWNoZWQgPSBjb21tYW5kSGVscENhY2hlLmdldChjYWNoZUtleSk7XG5cbiAgaWYgKCFjYWNoZWQpIHtcbiAgICBjb25zdCBhbGlhc2VzID0gbWV0YWRhdGEuYWxpYXNlcyA/IGAgKCR7bWV0YWRhdGEuYWxpYXNlcy5qb2luKFwiLCBcIil9KWAgOiBcIlwiO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gbWV0YWRhdGEuZGVzY3JpcHRpb24gfHwgXCJObyBkZXNjcmlwdGlvbiBhdmFpbGFibGVcIjtcbiAgICBjYWNoZWQgPSBgICAke25hbWV9JHthbGlhc2VzfVxcbiAgICAgICR7ZGVzY3JpcHRpb259YDtcbiAgICBjb21tYW5kSGVscENhY2hlLnNldChjYWNoZUtleSwgY2FjaGVkKTtcbiAgfVxuXG4gIHJldHVybiBjYWNoZWQ7XG59O1xuXG5leHBvcnQgY29uc3QgZ2VuZXJhdGVHbG9iYWxIZWxwID0gYXN5bmMgKFxuICByZWdpc3RyeTogRGlzY292ZXJ5UmVzdWx0LFxuKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgLy8gQ3JlYXRlIGNhY2hlIGtleSBmb3IgZ2xvYmFsIGhlbHBcbiAgY29uc3QgY2FjaGVLZXkgPSBgZ2xvYmFsOiR7QXJyYXkuZnJvbShyZWdpc3RyeS5tZXRhZGF0YS5rZXlzKCkpLnNvcnQoKS5qb2luKFwiLFwiKX1gO1xuICBjb25zdCBjYWNoZWQgPSBoZWxwQ2FjaGUuZ2V0KGNhY2hlS2V5KTtcblxuICBpZiAoY2FjaGVkICYmIGNhY2hlZC5nbG9iYWxIZWxwKSB7XG4gICAgcmV0dXJuIGNhY2hlZC5nbG9iYWxIZWxwO1xuICB9XG5cbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW0hFTFBfVEVNUExBVEVTLmdsb2JhbEhlYWRlcl07XG5cbiAgLy8gTG9hZCBhbGwgbWV0YWRhdGEgaW4gcGFyYWxsZWwgd2l0aCBjb250cm9sbGVkIGNvbmN1cnJlbmN5XG4gIGNvbnN0IG1ldGFkYXRhUmVzdWx0cyA9IGF3YWl0IHBNYXAoXG4gICAgQXJyYXkuZnJvbShyZWdpc3RyeS5tZXRhZGF0YS5lbnRyaWVzKCkpLFxuICAgIGFzeW5jIChbbmFtZSwgbWV0YWRhdGFMb2FkZXJdKSA9PiB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IGF3YWl0IG1ldGFkYXRhTG9hZGVyKCk7XG4gICAgICByZXR1cm4gW25hbWUsIG1ldGFkYXRhXSBhcyBbc3RyaW5nLCBDbWRNZXRhZGF0YV07XG4gICAgfSxcbiAgICB7IGNvbmN1cnJlbmN5OiA1IH0sIC8vIExpbWl0IGNvbmN1cnJlbmN5IGZvciBtZXRhZGF0YSBsb2FkaW5nXG4gICk7XG5cbiAgLy8gU29ydCBjb21tYW5kcyBhbHBoYWJldGljYWxseSBieSBuYW1lXG4gIG1ldGFkYXRhUmVzdWx0cy5zb3J0KChbYV0sIFtiXSkgPT4gYS5sb2NhbGVDb21wYXJlKGIpKTtcblxuICAvLyBCdWlsZCBoZWxwIHRleHQgdXNpbmcgY2FjaGVkIGZvcm1hdHRpbmdcbiAgZm9yIChjb25zdCBbbmFtZSwgbWV0YWRhdGFdIG9mIG1ldGFkYXRhUmVzdWx0cykge1xuICAgIGxpbmVzLnB1c2goZm9ybWF0Q29tbWFuZEhlbHAobmFtZSwgbWV0YWRhdGEpKTtcbiAgfVxuXG4gIGxpbmVzLnB1c2goSEVMUF9URU1QTEFURVMuaGVscEZvb3Rlcik7XG5cbiAgY29uc3QgaGVscFRleHQgPSBsaW5lcy5qb2luKFwiXFxuXCIpO1xuXG4gIC8vIENhY2hlIHRoZSBnbG9iYWwgaGVscFxuICBoZWxwQ2FjaGUuc2V0KGNhY2hlS2V5LCB7XG4gICAgY29tbWFuZEhlbHA6IFwiXCIsXG4gICAgZ2xvYmFsSGVscDogaGVscFRleHQsXG4gICAgZmlsZUhhc2g6IFwiXCIsXG4gICAgbGFzdE1vZGlmaWVkOiBEYXRlLm5vdygpLFxuICB9KTtcblxuICByZXR1cm4gaGVscFRleHQ7XG59O1xuIiwKICAgICIvLyBwYWNrYWdlcy9sYXVuY2hlci9zcmMvaW1wbC9sYXVuY2hlci92YWxpZGF0b3IudHNcblxuaW1wb3J0IHsgQXJndW1lbnRWYWxpZGF0aW9uRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB0eXBlIHsgQ21kQXJnRGVmaW5pdGlvbiwgQ21kQXJnc1NjaGVtYSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUFyZ1ZhbHVlID0gKFxuICBhcmdOYW1lOiBzdHJpbmcsXG4gIHZhbHVlOiB1bmtub3duLFxuICBkZWZpbml0aW9uOiBDbWRBcmdEZWZpbml0aW9uLFxuKTogYm9vbGVhbiA9PiB7XG4gIGNvbnN0IGV4cGVjdGVkVHlwZSA9XG4gICAgZGVmaW5pdGlvbi50eXBlID09PSBcImJvb2xlYW5cIlxuICAgICAgPyBcImJvb2xlYW5cIlxuICAgICAgOiBkZWZpbml0aW9uLnR5cGUgPT09IFwibnVtYmVyXCJcbiAgICAgICAgPyBcIm51bWJlclwiXG4gICAgICAgIDogXCJzdHJpbmdcIjtcblxuICBpZiAodHlwZW9mIHZhbHVlICE9PSBleHBlY3RlZFR5cGUpIHtcbiAgICB0aHJvdyBuZXcgQXJndW1lbnRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICBhcmdOYW1lLFxuICAgICAgYEV4cGVjdGVkICR7ZXhwZWN0ZWRUeXBlfSwgZ290ICR7dHlwZW9mIHZhbHVlfWAsXG4gICAgKTtcbiAgfVxuXG4gIGlmIChcInZhbGlkYXRlXCIgaW4gZGVmaW5pdGlvbiAmJiBkZWZpbml0aW9uLnZhbGlkYXRlKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gZGVmaW5pdGlvbi52YWxpZGF0ZSh2YWx1ZSBhcyBuZXZlcik7XG4gICAgaWYgKHJlc3VsdCAhPT0gdHJ1ZSkge1xuICAgICAgdGhyb3cgbmV3IEFyZ3VtZW50VmFsaWRhdGlvbkVycm9yKFxuICAgICAgICBhcmdOYW1lLFxuICAgICAgICB0eXBlb2YgcmVzdWx0ID09PSBcInN0cmluZ1wiID8gcmVzdWx0IDogXCJWYWxpZGF0aW9uIGZhaWxlZFwiLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZVJlcXVpcmVkQXJncyA9IChcbiAgYXJnczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIHNjaGVtYTogQ21kQXJnc1NjaGVtYSxcbik6IHZvaWQgPT4ge1xuICBmb3IgKGNvbnN0IFtrZXksIGRlZl0gb2YgT2JqZWN0LmVudHJpZXMoc2NoZW1hKSkge1xuICAgIGlmIChkZWYucmVxdWlyZWQgJiYgIShrZXkgaW4gYXJncykpIHtcbiAgICAgIHRocm93IG5ldyBBcmd1bWVudFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAga2V5LFxuICAgICAgICBgUmVxdWlyZWQgYXJndW1lbnQgXCIke2tleX1cIiBpcyBtaXNzaW5nYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG59O1xuIiwKICAgICIvLyBwYWNrYWdlcy9sYXVuY2hlci9zcmMvaW1wbC9sYXVuY2hlci9wYXJzZXIudHNcblxuaW1wb3J0IHsgQXJndW1lbnRWYWxpZGF0aW9uRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB0eXBlIHsgQ21kQXJnc1NjaGVtYSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUFyZ1ZhbHVlIH0gZnJvbSBcIi4vdmFsaWRhdG9yXCI7XG5cbmludGVyZmFjZSBQYXJzZVJlc3VsdCB7XG4gIGNtZE5hbWU6IHN0cmluZztcbiAgcGFyc2VkQXJnczogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmludGVyZmFjZSBDaGFpblBhcnNlUmVzdWx0IHtcbiAgY21kQ2hhaW46IHN0cmluZ1tdO1xuICBwYXJzZWRBcmdzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdO1xuICByZW1haW5pbmdBcmdzOiBzdHJpbmdbXTtcbn1cblxuaW50ZXJmYWNlIFNjaGVtYU1ldGFkYXRhIHtcbiAgYWxpYXNNYXA6IE1hcDxzdHJpbmcsIHN0cmluZz47XG4gIGNhbWVsQ2FzZUNhY2hlOiBNYXA8c3RyaW5nLCBzdHJpbmc+O1xuICBkZWZhdWx0czogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIHJlcXVpcmVkS2V5czogU2V0PHN0cmluZz47XG4gIGF2YWlsYWJsZUtleXM6IHN0cmluZ1tdO1xufVxuXG5jb25zdCBjYW1lbENhc2UgPSAoc3RyOiBzdHJpbmcpOiBzdHJpbmcgPT5cbiAgc3RyLnJlcGxhY2UoLy0oW2Etel0pL2csIChfLCBsZXR0ZXIpID0+IGxldHRlci50b1VwcGVyQ2FzZSgpKTtcblxuLy8gR2xvYmFsIGNhY2hlIGZvciBzY2hlbWEgbWV0YWRhdGEgdG8gYXZvaWQgcmVjb21wdXRhdGlvblxuY29uc3Qgc2NoZW1hTWV0YWRhdGFDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBTY2hlbWFNZXRhZGF0YT4oKTtcblxuY29uc3QgY3JlYXRlU2NoZW1hTWV0YWRhdGEgPSAoc2NoZW1hOiBDbWRBcmdzU2NoZW1hKTogU2NoZW1hTWV0YWRhdGEgPT4ge1xuICBjb25zdCBhbGlhc01hcCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIGNvbnN0IGNhbWVsQ2FzZUNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgY29uc3QgZGVmYXVsdHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gIGNvbnN0IHJlcXVpcmVkS2V5cyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCBhdmFpbGFibGVLZXlzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgW2tleSwgZGVmXSBvZiBPYmplY3QuZW50cmllcyhzY2hlbWEpKSB7XG4gICAgYXZhaWxhYmxlS2V5cy5wdXNoKGtleSk7XG5cbiAgICAvLyBQcmUtY2FjaGUgY2FtZWxDYXNlIGNvbnZlcnNpb24gZm9yIG1haW4ga2V5XG4gICAgY29uc3QgY2FtZWxLZXkgPSBjYW1lbENhc2Uoa2V5KTtcbiAgICBpZiAoY2FtZWxLZXkgIT09IGtleSkge1xuICAgICAgY2FtZWxDYXNlQ2FjaGUuc2V0KGtleSwgY2FtZWxLZXkpO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBhbGlhc2VzXG4gICAgaWYgKGRlZi5hbGlhc2VzKSB7XG4gICAgICBmb3IgKGNvbnN0IGFsaWFzIG9mIGRlZi5hbGlhc2VzKSB7XG4gICAgICAgIGFsaWFzTWFwLnNldChhbGlhcywga2V5KTtcbiAgICAgICAgLy8gUHJlLWNhY2hlIGNhbWVsQ2FzZSBjb252ZXJzaW9uIGZvciBhbGlhc2VzXG4gICAgICAgIGNvbnN0IGNhbWVsQWxpYXMgPSBjYW1lbENhc2UoYWxpYXMpO1xuICAgICAgICBpZiAoY2FtZWxBbGlhcyAhPT0gYWxpYXMpIHtcbiAgICAgICAgICBjYW1lbENhc2VDYWNoZS5zZXQoYWxpYXMsIGNhbWVsQWxpYXMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVHJhY2sgZGVmYXVsdHMgYW5kIHJlcXVpcmVkIGtleXNcbiAgICBpZiAoXCJkZWZhdWx0XCIgaW4gZGVmICYmIGRlZi5kZWZhdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGRlZmF1bHRzW2tleV0gPSBkZWYuZGVmYXVsdDtcbiAgICB9XG4gICAgaWYgKGRlZi5yZXF1aXJlZCkge1xuICAgICAgcmVxdWlyZWRLZXlzLmFkZChrZXkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgYWxpYXNNYXAsXG4gICAgY2FtZWxDYXNlQ2FjaGUsXG4gICAgZGVmYXVsdHMsXG4gICAgcmVxdWlyZWRLZXlzLFxuICAgIGF2YWlsYWJsZUtleXMsXG4gIH07XG59O1xuXG4vLyBMaWdodHdlaWdodCBoYXNoIGZ1bmN0aW9uIGZvciBzY2hlbWEga2V5c1xuY29uc3QgaGFzaFNjaGVtYSA9IChzY2hlbWE6IENtZEFyZ3NTY2hlbWEpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoc2NoZW1hKS5zb3J0KCk7XG4gIHJldHVybiBrZXlzLmpvaW4oXCJ8XCIpO1xufTtcblxuY29uc3QgZ2V0U2NoZW1hTWV0YWRhdGEgPSAoc2NoZW1hOiBDbWRBcmdzU2NoZW1hKTogU2NoZW1hTWV0YWRhdGEgPT4ge1xuICAvLyBDcmVhdGUgYSBjYWNoZSBrZXkgZnJvbSBzY2hlbWEgc3RydWN0dXJlIHVzaW5nIGxpZ2h0d2VpZ2h0IGhhc2hcbiAgY29uc3Qgc2NoZW1hS2V5ID0gaGFzaFNjaGVtYShzY2hlbWEpO1xuXG4gIGxldCBtZXRhZGF0YSA9IHNjaGVtYU1ldGFkYXRhQ2FjaGUuZ2V0KHNjaGVtYUtleSk7XG4gIGlmICghbWV0YWRhdGEpIHtcbiAgICBtZXRhZGF0YSA9IGNyZWF0ZVNjaGVtYU1ldGFkYXRhKHNjaGVtYSk7XG4gICAgc2NoZW1hTWV0YWRhdGFDYWNoZS5zZXQoc2NoZW1hS2V5LCBtZXRhZGF0YSk7XG4gIH1cblxuICByZXR1cm4gbWV0YWRhdGE7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VBcmdzID0gKFxuICBhcmd2OiBzdHJpbmdbXSxcbiAgc2NoZW1hOiBDbWRBcmdzU2NoZW1hLFxuKTogUGFyc2VSZXN1bHQgPT4ge1xuICBjb25zdCBbY21kTmFtZSwgLi4ucmF3QXJnc10gPSBhcmd2O1xuXG4gIGlmICghY21kTmFtZSkge1xuICAgIHRocm93IG5ldyBBcmd1bWVudFZhbGlkYXRpb25FcnJvcihcImNvbW1hbmRcIiwgXCJObyBjb21tYW5kIHByb3ZpZGVkXCIpO1xuICB9XG5cbiAgLy8gR2V0IHByZS1jb21wdXRlZCBzY2hlbWEgbWV0YWRhdGFcbiAgY29uc3QgeyBhbGlhc01hcCwgY2FtZWxDYXNlQ2FjaGUsIGRlZmF1bHRzLCByZXF1aXJlZEtleXMsIGF2YWlsYWJsZUtleXMgfSA9XG4gICAgZ2V0U2NoZW1hTWV0YWRhdGEoc2NoZW1hKTtcblxuICBjb25zdCBwYXJzZWRBcmdzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHsgLi4uZGVmYXVsdHMgfTtcblxuICAvLyBTaW5nbGUtcGFzcyBhcmd1bWVudCBwYXJzaW5nXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmF3QXJncy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGFyZyA9IHJhd0FyZ3NbaV07XG4gICAgaWYgKCFhcmcgfHwgIWFyZy5zdGFydHNXaXRoKFwiLVwiKSkgY29udGludWU7XG5cbiAgICBjb25zdCBpc0xvbmdGb3JtID0gYXJnLnN0YXJ0c1dpdGgoXCItLVwiKTtcbiAgICBjb25zdCBmbGFnTmFtZSA9IGFyZy5zbGljZShpc0xvbmdGb3JtID8gMiA6IDEpO1xuICAgIGNvbnN0IGFjdHVhbEtleSA9XG4gICAgICBhbGlhc01hcC5nZXQoZmxhZ05hbWUpID8/XG4gICAgICBjYW1lbENhc2VDYWNoZS5nZXQoZmxhZ05hbWUpID8/XG4gICAgICBjYW1lbENhc2UoZmxhZ05hbWUpO1xuXG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IHNjaGVtYVthY3R1YWxLZXldO1xuXG4gICAgaWYgKCFkZWZpbml0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgQXJndW1lbnRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgIGZsYWdOYW1lLFxuICAgICAgICBgVW5rbm93biBhcmd1bWVudC4gQXZhaWxhYmxlOiAke2F2YWlsYWJsZUtleXMuam9pbihcIiwgXCIpfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChkZWZpbml0aW9uLnR5cGUgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICBwYXJzZWRBcmdzW2FjdHVhbEtleV0gPSB0cnVlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgbmV4dEFyZyA9IHJhd0FyZ3NbKytpXTtcbiAgICBpZiAobmV4dEFyZyA9PT0gdW5kZWZpbmVkIHx8IG5leHRBcmcuc3RhcnRzV2l0aChcIi1cIikpIHtcbiAgICAgIHRocm93IG5ldyBBcmd1bWVudFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgZmxhZ05hbWUsXG4gICAgICAgIGBFeHBlY3RlZCB2YWx1ZSBmb3IgYXJndW1lbnQgXCIke2ZsYWdOYW1lfVwiYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgbGV0IHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgPSBuZXh0QXJnO1xuICAgIGlmIChkZWZpbml0aW9uLnR5cGUgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHZhbHVlID0gTnVtYmVyKG5leHRBcmcpO1xuICAgICAgaWYgKE51bWJlci5pc05hTih2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFyZ3VtZW50VmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGZsYWdOYW1lLFxuICAgICAgICAgIGBFeHBlY3RlZCBudW1iZXIsIGdvdCBcIiR7bmV4dEFyZ31cImAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFsaWRhdGVBcmdWYWx1ZShhY3R1YWxLZXksIHZhbHVlLCBkZWZpbml0aW9uKTtcbiAgICBwYXJzZWRBcmdzW2FjdHVhbEtleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlIHJlcXVpcmVkIGFyZ3VtZW50c1xuICBmb3IgKGNvbnN0IHJlcXVpcmVkS2V5IG9mIHJlcXVpcmVkS2V5cykge1xuICAgIGlmICghKHJlcXVpcmVkS2V5IGluIHBhcnNlZEFyZ3MpKSB7XG4gICAgICB0aHJvdyBuZXcgQXJndW1lbnRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgIHJlcXVpcmVkS2V5LFxuICAgICAgICBgUmVxdWlyZWQgYXJndW1lbnQgXCIke3JlcXVpcmVkS2V5fVwiIGlzIG1pc3NpbmdgLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBjbWROYW1lLCBwYXJzZWRBcmdzIH07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDb21tYW5kQ2hhaW4gPSAoXG4gIGFyZ3Y6IHN0cmluZ1tdLFxuICBzY2hlbWFzOiBDbWRBcmdzU2NoZW1hW10sXG4pOiBDaGFpblBhcnNlUmVzdWx0ID0+IHtcbiAgY29uc3QgY21kQ2hhaW46IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHBhcnNlZEFyZ3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10gPSBbXTtcbiAgbGV0IHJlbWFpbmluZ0FyZ3MgPSBbLi4uYXJndl07XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzY2hlbWFzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgc2NoZW1hID0gc2NoZW1hc1tpXTtcbiAgICBpZiAoIXNjaGVtYSkgYnJlYWs7XG5cbiAgICAvLyBGaW5kIHRoZSBuZXh0IGNvbW1hbmQgaW4gdGhlIGNoYWluXG4gICAgbGV0IGNtZE5hbWUgPSBcIlwiO1xuICAgIGxldCBhcmdzU3RhcnRJbmRleCA9IDA7XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IHJlbWFpbmluZ0FyZ3MubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IGFyZyA9IHJlbWFpbmluZ0FyZ3Nbal07XG4gICAgICBpZiAoYXJnICYmICFhcmcuc3RhcnRzV2l0aChcIi1cIikpIHtcbiAgICAgICAgY21kTmFtZSA9IGFyZztcbiAgICAgICAgYXJnc1N0YXJ0SW5kZXggPSBqICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjbWROYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgQXJndW1lbnRWYWxpZGF0aW9uRXJyb3IoXCJjb21tYW5kXCIsIFwiTm8gY29tbWFuZCBwcm92aWRlZFwiKTtcbiAgICB9XG5cbiAgICBjbWRDaGFpbi5wdXNoKGNtZE5hbWUpO1xuXG4gICAgLy8gRXh0cmFjdCBhcmdzIGZvciB0aGlzIGNvbW1hbmRcbiAgICBjb25zdCBjb21tYW5kQXJnczogc3RyaW5nW10gPSBbXTtcbiAgICBmb3IgKGxldCBqID0gYXJnc1N0YXJ0SW5kZXg7IGogPCByZW1haW5pbmdBcmdzLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCBhcmcgPSByZW1haW5pbmdBcmdzW2pdO1xuICAgICAgaWYgKCFhcmcpIGNvbnRpbnVlO1xuXG4gICAgICBpZiAoIWFyZy5zdGFydHNXaXRoKFwiLVwiKSkge1xuICAgICAgICAvLyBGb3VuZCBuZXh0IGNvbW1hbmQsIHN0b3AgaGVyZVxuICAgICAgICByZW1haW5pbmdBcmdzID0gcmVtYWluaW5nQXJncy5zbGljZShqKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjb21tYW5kQXJncy5wdXNoKGFyZyk7XG4gICAgfVxuXG4gICAgLy8gUGFyc2UgYXJncyBmb3IgdGhpcyBjb21tYW5kXG4gICAgY29uc3QgeyBwYXJzZWRBcmdzOiBjbWRQYXJzZWRBcmdzIH0gPSBwYXJzZUFyZ3MoXG4gICAgICBbY21kTmFtZSwgLi4uY29tbWFuZEFyZ3NdLFxuICAgICAgc2NoZW1hLFxuICAgICk7XG4gICAgcGFyc2VkQXJncy5wdXNoKGNtZFBhcnNlZEFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHsgY21kQ2hhaW4sIHBhcnNlZEFyZ3MsIHJlbWFpbmluZ0FyZ3MgfTtcbn07XG4iLAogICAgIi8vIHBhY2thZ2VzL2xhdW5jaGVyL3NyYy9pbXBsL2xhdW5jaGVyL3JlZ2lzdHJ5LnRzXG5cbmltcG9ydCB0eXBlIHsgQ21kTm9kZSwgRGlzY292ZXJ5UmVzdWx0IH0gZnJvbSBcIi4vdHlwZXNcIjtcblxubGV0IGNhY2hlZFJlZ2lzdHJ5OiBEaXNjb3ZlcnlSZXN1bHQgfCBudWxsID0gbnVsbDtcblxuZXhwb3J0IGNvbnN0IGdldFJlZ2lzdHJ5ID0gKCk6IERpc2NvdmVyeVJlc3VsdCB8IG51bGwgPT4gY2FjaGVkUmVnaXN0cnk7XG5cbmV4cG9ydCBjb25zdCBzZXRSZWdpc3RyeSA9IChyZWdpc3RyeTogRGlzY292ZXJ5UmVzdWx0KTogdm9pZCA9PiB7XG4gIGNhY2hlZFJlZ2lzdHJ5ID0gcmVnaXN0cnk7XG59O1xuXG5leHBvcnQgY29uc3QgY2xlYXJSZWdpc3RyeSA9ICgpOiB2b2lkID0+IHtcbiAgY2FjaGVkUmVnaXN0cnkgPSBudWxsO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlc29sdmVDb21tYW5kID0gKFxuICByZWdpc3RyeTogRGlzY292ZXJ5UmVzdWx0LFxuICBjbWROYW1lT3JBbGlhczogc3RyaW5nLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmVzb2x2ZWROYW1lID0gcmVnaXN0cnkuYWxpYXNlcy5nZXQoY21kTmFtZU9yQWxpYXMpID8/IGNtZE5hbWVPckFsaWFzO1xuICByZXR1cm4gcmVzb2x2ZWROYW1lO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlc29sdmVDb21tYW5kQ2hhaW4gPSAoXG4gIHJlZ2lzdHJ5OiBEaXNjb3ZlcnlSZXN1bHQsXG4gIGNtZENoYWluOiBzdHJpbmdbXSxcbik6IHsgcGFyZW50PzogQ21kTm9kZTsgY2hpbGQ/OiBDbWROb2RlOyBmdWxsUGF0aDogc3RyaW5nW10gfSA9PiB7XG4gIGlmIChjbWRDaGFpbi5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJFbXB0eSBjb21tYW5kIGNoYWluXCIpO1xuICB9XG5cbiAgaWYgKGNtZENoYWluLmxlbmd0aCA9PT0gMSkge1xuICAgIGNvbnN0IGNtZE5hbWUgPSByZXNvbHZlQ29tbWFuZChyZWdpc3RyeSwgY21kQ2hhaW5bMF0hKTtcbiAgICBjb25zdCBub2RlID0gcmVnaXN0cnkuaGllcmFyY2h5LmdldChjbWROYW1lKTtcbiAgICBpZiAoIW5vZGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ29tbWFuZCBub3QgZm91bmQ6ICR7Y21kQ2hhaW5bMF19YCk7XG4gICAgfVxuICAgIHJldHVybiB7IGZ1bGxQYXRoOiBbY21kTmFtZV0gfTtcbiAgfVxuXG4gIC8vIE11bHRpLWxldmVsIGNvbW1hbmQgY2hhaW5cbiAgY29uc3QgcGFyZW50TmFtZSA9IHJlc29sdmVDb21tYW5kKHJlZ2lzdHJ5LCBjbWRDaGFpblswXSEpO1xuICBjb25zdCBjaGlsZE5hbWUgPSByZXNvbHZlQ29tbWFuZChyZWdpc3RyeSwgY21kQ2hhaW5bMV0hKTtcblxuICBjb25zdCBwYXJlbnROb2RlID0gcmVnaXN0cnkuaGllcmFyY2h5LmdldChwYXJlbnROYW1lKTtcbiAgY29uc3QgY2hpbGROb2RlID0gcmVnaXN0cnkuaGllcmFyY2h5LmdldChjaGlsZE5hbWUpO1xuXG4gIGlmICghcGFyZW50Tm9kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgUGFyZW50IGNvbW1hbmQgbm90IGZvdW5kOiAke2NtZENoYWluWzBdfWApO1xuICB9XG5cbiAgaWYgKCFjaGlsZE5vZGUgfHwgY2hpbGROb2RlLnBhcmVudCAhPT0gcGFyZW50TmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBTdWItY29tbWFuZCBub3QgZm91bmQ6ICR7Y21kQ2hhaW5bMV19IHVuZGVyICR7Y21kQ2hhaW5bMF19YCxcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBwYXJlbnQ6IHBhcmVudE5vZGUsXG4gICAgY2hpbGQ6IGNoaWxkTm9kZSxcbiAgICBmdWxsUGF0aDogW3BhcmVudE5hbWUsIGNoaWxkTmFtZV0sXG4gIH07XG59O1xuIiwKICAgICIjIS91c3IvYmluL2VudiBidW5cblxuLy8g8J+RiSBidW4gZGxlciA8Y21kPiA8YXJncz5cbi8vIPCfkqEgZGxlciA9PT0gYXBwcy9kbGVyL3NyYy9jbGkudHNcblxuaW1wb3J0IHsgcnVuTGF1bmNoZXIgfSBmcm9tIFwiQHJlbGl2ZXJzZS9kbGVyLWxhdW5jaGVyXCI7XG5cbmF3YWl0IHJ1bkxhdW5jaGVyKGltcG9ydC5tZXRhLnVybCk7XG4iCiAgXSwKICAibWFwcGluZ3MiOiAiOzs7O0FBRUE7QUFDQTs7O0FDRkEsSUFBTSxjQUFjLElBQUk7QUFZakIsSUFBTSxrQkFBa0IsQ0FBQyxVQUEwQjtBQUFBLEVBRXhELE1BQU0sU0FBUyxJQUFJLE1BQU0sTUFBTSxTQUFTLENBQUM7QUFBQSxFQUN6QyxTQUFTLElBQUksRUFBRyxJQUFJLE1BQU0sUUFBUSxLQUFLO0FBQUEsSUFDckMsT0FBTyxLQUFLLE1BQU07QUFBQSxFQUNwQjtBQUFBLEVBQ0EsT0FBTyxNQUFNLFVBQVU7QUFBQSxFQUN2QixNQUFNLFVBQVUsWUFBWSxPQUFPLE9BQU8sS0FBSztBQUFBLENBQUksQ0FBQztBQUFBLEVBQ3BELElBQUksTUFBTSxJQUFJLFFBQVEsT0FBTztBQUFBOztBQ29FL0IsSUFBTSxRQUFRO0FBQ2QsSUFBTSxZQUEyQixPQUFPLFFBQVE7QUFFaEQsSUFBTSxrQkFBa0I7QUFDeEIsSUFBTSxvQkFBb0I7QUFDMUIsSUFBTSxrQkFBa0I7QUFDeEIsSUFBTSx3QkFBd0I7QUFFOUIsSUFBTSxXQUFXO0FBQ2pCLElBQU0sV0FBVztBQUNqQixJQUFNLFlBQVk7QUFFbEIsSUFBTSx5QkFBeUI7QUFDL0IsSUFBTSx5QkFBeUI7QUFDL0IsSUFBTSx1QkFBdUI7QUFDN0IsSUFBTSwwQkFBMEI7QUFDaEMsSUFBTSwyQkFBMkI7QUFDakMsSUFBTSwyQkFBMkI7QUFDakMsSUFBTSw0QkFBNEI7QUFDbEMsSUFBTSxzQkFBc0I7QUFDNUIsSUFBTSw4QkFBOEI7QUFDcEMsSUFBTSxnQ0FBZ0M7QUFFdEMsSUFBTSxjQUFjO0FBQ3BCLElBQU0sY0FBYztBQUNwQixJQUFNLHFCQUFxQjtBQUMzQixJQUFNLHFCQUFxQjtBQUUzQixJQUFNLFlBQVk7QUFDbEIsSUFBTSxXQUFXO0FBQ2pCLElBQU0sVUFBVTtB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TUFFaEMsSUFBSSxLQUFLLFNBQVMsUUFBUSxLQUFLLEtBQUssU0FBUyxJQUFJLEdBQUc7QUFBQSxRQUNsRCxPQUFPLElBQUksTUFBTSxvQkFBb0IsVUFBVSxDQUFDO0FBQUEsUUFDaEQsUUFBUSxLQUFLLENBQUM7QUFBQSxNQUNoQjtBQUFBLE1BRUEsUUFBUSxlQUFlLFVBQVUsTUFBTSxXQUFXLElBQUk7QUFBQSxNQUV0RCxNQUFNLFdBQVcsUUFBUSxVQUFtQjtBQUFBO0FBQUEsSUFFOUMsT0FBTyxPQUFPO0FBQUEsSUFDZCxJQUFJLGlCQUFpQixlQUFlO0FBQUEsTUFDbEMsSUFBSSxTQUFTO0FBQUEsUUFDWCxRQUFRLEtBQUs7QUFBQSxNQUNmLEVBQU87QUFBQSxRQUNMLE1BQU0sYUFBYSxDQUFDO0FBQUEsZ0JBQWEsTUFBTSxTQUFTO0FBQUEsUUFDaEQsSUFBSSxpQkFBaUIsb0JBQW9CLE1BQU0sT0FBTztBQUFBLFVBQ3BELFdBQVcsS0FBSyxVQUFVLE1BQU0sT0FBTztBQUFBLFFBQ3pDO0FBQUEsUUFDQSxXQUFXLEtBQUssRUFBRTtBQUFBLFFBQ2xCLGdCQUFnQixVQUFVO0FBQUE7QUFBQSxNQUU1QixRQUFRLEtBQUssQ0FBQztBQUFBLElBQ2hCLEVBQU87QUFBQSxNQUNMLE1BQU07QUFBQTtBQUFBO0FBQUE7OztBWWxNWixNQUFNLFlBQVksWUFBWSxHQUFHOyIsCiAgImRlYnVnSWQiOiAiRTkwRDc3RUEzRDAyQ0RCNjY0NzU2RTIxNjQ3NTZFMjEiLAogICJuYW1lcyI6IFtdCn0=