@decaf-ts/utils 0.1.6

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 (112) hide show
  1. package/LICENSE.md +157 -0
  2. package/README.md +95 -0
  3. package/dist/esm/utils.js +1 -0
  4. package/dist/types/bin/tag-release.d.ts +1 -0
  5. package/dist/types/bin/update-scripts.d.ts +1 -0
  6. package/dist/types/cli/command.d.ts +110 -0
  7. package/dist/types/cli/commands/index.d.ts +2 -0
  8. package/dist/types/cli/commands/tag-release.d.ts +105 -0
  9. package/dist/types/cli/commands/update-scripts.d.ts +211 -0
  10. package/dist/types/cli/constants.d.ts +73 -0
  11. package/dist/types/cli/index.d.ts +4 -0
  12. package/dist/types/cli/types.d.ts +28 -0
  13. package/dist/types/index.d.ts +39 -0
  14. package/dist/types/input/index.d.ts +2 -0
  15. package/dist/types/input/input.d.ts +472 -0
  16. package/dist/types/input/types.d.ts +76 -0
  17. package/dist/types/output/common.d.ts +51 -0
  18. package/dist/types/output/index.d.ts +3 -0
  19. package/dist/types/output/logging.d.ts +177 -0
  20. package/dist/types/output/types.d.ts +203 -0
  21. package/dist/types/utils/accumulator.d.ts +105 -0
  22. package/dist/types/utils/constants.d.ts +136 -0
  23. package/dist/types/utils/environment.d.ts +57 -0
  24. package/dist/types/utils/fs.d.ts +133 -0
  25. package/dist/types/utils/http.d.ts +41 -0
  26. package/dist/types/utils/index.d.ts +7 -0
  27. package/dist/types/utils/md.d.ts +156 -0
  28. package/dist/types/utils/tests.d.ts +170 -0
  29. package/dist/types/utils/text.d.ts +106 -0
  30. package/dist/types/utils/timeout.d.ts +1 -0
  31. package/dist/types/utils/types.d.ts +81 -0
  32. package/dist/types/utils/utils.d.ts +91 -0
  33. package/dist/types/utils/web.d.ts +7 -0
  34. package/dist/types/writers/OutputWriter.d.ts +49 -0
  35. package/dist/types/writers/RegexpOutputWriter.d.ts +69 -0
  36. package/dist/types/writers/StandardOutputWriter.d.ts +91 -0
  37. package/dist/types/writers/index.d.ts +4 -0
  38. package/dist/types/writers/types.d.ts +29 -0
  39. package/dist/utils.js +1 -0
  40. package/lib/assets/slogans.json +802 -0
  41. package/lib/bin/tag-release.cjs +12 -0
  42. package/lib/bin/update-scripts.cjs +12 -0
  43. package/lib/cli/command.cjs +153 -0
  44. package/lib/cli/commands/index.cjs +20 -0
  45. package/lib/cli/commands/tag-release.cjs +168 -0
  46. package/lib/cli/commands/update-scripts.cjs +511 -0
  47. package/lib/cli/constants.cjs +80 -0
  48. package/lib/cli/index.cjs +22 -0
  49. package/lib/cli/types.cjs +4 -0
  50. package/lib/esm/assets/slogans.json +802 -0
  51. package/lib/esm/bin/tag-release.js +10 -0
  52. package/lib/esm/bin/update-scripts.js +10 -0
  53. package/lib/esm/cli/command.js +149 -0
  54. package/lib/esm/cli/commands/index.js +4 -0
  55. package/lib/esm/cli/commands/tag-release.js +164 -0
  56. package/lib/esm/cli/commands/update-scripts.js +504 -0
  57. package/lib/esm/cli/constants.js +77 -0
  58. package/lib/esm/cli/index.js +6 -0
  59. package/lib/esm/cli/types.js +3 -0
  60. package/lib/esm/index.js +41 -0
  61. package/lib/esm/input/index.js +4 -0
  62. package/lib/esm/input/input.js +570 -0
  63. package/lib/esm/input/types.js +3 -0
  64. package/lib/esm/output/common.js +93 -0
  65. package/lib/esm/output/index.js +5 -0
  66. package/lib/esm/output/logging.js +350 -0
  67. package/lib/esm/output/types.js +3 -0
  68. package/lib/esm/utils/accumulator.js +145 -0
  69. package/lib/esm/utils/constants.js +176 -0
  70. package/lib/esm/utils/environment.js +91 -0
  71. package/lib/esm/utils/fs.js +271 -0
  72. package/lib/esm/utils/http.js +70 -0
  73. package/lib/esm/utils/index.js +9 -0
  74. package/lib/esm/utils/md.js +3 -0
  75. package/lib/esm/utils/tests.js +223 -0
  76. package/lib/esm/utils/text.js +142 -0
  77. package/lib/esm/utils/timeout.js +5 -0
  78. package/lib/esm/utils/types.js +3 -0
  79. package/lib/esm/utils/utils.js +220 -0
  80. package/lib/esm/utils/web.js +12 -0
  81. package/lib/esm/writers/OutputWriter.js +3 -0
  82. package/lib/esm/writers/RegexpOutputWriter.js +98 -0
  83. package/lib/esm/writers/StandardOutputWriter.js +127 -0
  84. package/lib/esm/writers/index.js +6 -0
  85. package/lib/esm/writers/types.js +3 -0
  86. package/lib/index.cjs +58 -0
  87. package/lib/input/index.cjs +20 -0
  88. package/lib/input/input.cjs +577 -0
  89. package/lib/input/types.cjs +4 -0
  90. package/lib/output/common.cjs +100 -0
  91. package/lib/output/index.cjs +21 -0
  92. package/lib/output/logging.cjs +355 -0
  93. package/lib/output/types.cjs +4 -0
  94. package/lib/utils/accumulator.cjs +149 -0
  95. package/lib/utils/constants.cjs +179 -0
  96. package/lib/utils/environment.cjs +95 -0
  97. package/lib/utils/fs.cjs +288 -0
  98. package/lib/utils/http.cjs +77 -0
  99. package/lib/utils/index.cjs +25 -0
  100. package/lib/utils/md.cjs +4 -0
  101. package/lib/utils/tests.cjs +263 -0
  102. package/lib/utils/text.cjs +153 -0
  103. package/lib/utils/timeout.cjs +8 -0
  104. package/lib/utils/types.cjs +4 -0
  105. package/lib/utils/utils.cjs +226 -0
  106. package/lib/utils/web.cjs +15 -0
  107. package/lib/writers/OutputWriter.cjs +4 -0
  108. package/lib/writers/RegexpOutputWriter.cjs +102 -0
  109. package/lib/writers/StandardOutputWriter.cjs +131 -0
  110. package/lib/writers/index.cjs +22 -0
  111. package/lib/writers/types.cjs +4 -0
  112. package/package.json +121 -0
@@ -0,0 +1,570 @@
1
+ import prompts from "prompts";
2
+ import { parseArgs } from "util";
3
+ import { Logging } from "../output/logging";
4
+ /**
5
+ * @description Represents a user input prompt with various configuration options.
6
+ * @summary This class provides a flexible interface for creating and managing user input prompts.
7
+ * It implements the PromptObject interface from the 'prompts' library and offers methods to set
8
+ * various properties of the prompt. The class also includes static methods for common input scenarios
9
+ * and argument parsing.
10
+ *
11
+ * @template R - The type of the prompt name, extending string.
12
+ *
13
+ * @param name - The name of the prompt, used as the key in the returned answers object.
14
+ *
15
+ * @class
16
+ */
17
+ export class UserInput {
18
+ static { this.logger = Logging.for(UserInput); }
19
+ /**
20
+ * @description Creates a new UserInput instance.
21
+ * @summary Initializes a new UserInput object with the given name.
22
+ *
23
+ * @param name - The name of the prompt.
24
+ */
25
+ constructor(name) {
26
+ /**
27
+ * @description The type of the prompt.
28
+ * @summary Determines the input method (e.g., text, number, confirm).
29
+ */
30
+ this.type = "text";
31
+ this.name = name;
32
+ }
33
+ /**
34
+ * @description Sets the type of the prompt.
35
+ * @summary Configures the input method for the prompt.
36
+ *
37
+ * @param type - The type of the prompt.
38
+ * @returns This UserInput instance for method chaining.
39
+ */
40
+ setType(type) {
41
+ UserInput.logger.verbose(`Setting type to: ${type}`);
42
+ this.type = type;
43
+ return this;
44
+ }
45
+ /**
46
+ * @description Sets the message of the prompt.
47
+ * @summary Configures the question or instruction presented to the user.
48
+ *
49
+ * @param value - The message to be displayed.
50
+ * @returns This UserInput instance for method chaining.
51
+ */
52
+ setMessage(value) {
53
+ UserInput.logger.verbose(`Setting message to: ${value}`);
54
+ this.message = value;
55
+ return this;
56
+ }
57
+ /**
58
+ * @description Sets the initial value of the prompt.
59
+ * @summary Configures the default value presented to the user.
60
+ *
61
+ * @param value - The initial value.
62
+ * @returns This UserInput instance for method chaining.
63
+ */
64
+ setInitial(value) {
65
+ UserInput.logger.verbose(`Setting initial value to: ${value}`);
66
+ this.initial = value;
67
+ return this;
68
+ }
69
+ /**
70
+ * @description Sets the style of the prompt.
71
+ * @summary Configures the visual style of the prompt.
72
+ *
73
+ * @param value - The style to be applied.
74
+ * @returns This UserInput instance for method chaining.
75
+ */
76
+ setStyle(value) {
77
+ UserInput.logger.verbose(`Setting style to: ${value}`);
78
+ this.style = value;
79
+ return this;
80
+ }
81
+ /**
82
+ * @description Sets the format function of the prompt.
83
+ * @summary Configures a function to format the user's input before it's returned.
84
+ *
85
+ * @param value - The format function.
86
+ * @returns This UserInput instance for method chaining.
87
+ */
88
+ setFormat(value) {
89
+ UserInput.logger.verbose(`Setting format function`);
90
+ this.format = value;
91
+ return this;
92
+ }
93
+ /**
94
+ * @description Sets the validation function of the prompt.
95
+ * @summary Configures a function to validate the user's input.
96
+ *
97
+ * @param value - The validation function.
98
+ * @returns This UserInput instance for method chaining.
99
+ */
100
+ setValidate(value) {
101
+ UserInput.logger.verbose(`Setting validate function`);
102
+ this.validate = value;
103
+ return this;
104
+ }
105
+ /**
106
+ * @description Sets the onState callback of the prompt.
107
+ * @summary Configures a function to be called when the state of the prompt changes.
108
+ *
109
+ * @param value - The onState callback function.
110
+ * @returns This UserInput instance for method chaining.
111
+ */
112
+ setOnState(value) {
113
+ UserInput.logger.verbose(`Setting onState callback`);
114
+ this.onState = value;
115
+ return this;
116
+ }
117
+ /**
118
+ * @description Sets the onRender callback of the prompt.
119
+ * @summary Configures a function to be called when the prompt is rendered.
120
+ *
121
+ * @param value - The onRender callback function.
122
+ * @returns This UserInput instance for method chaining.
123
+ */
124
+ setOnRender(value) {
125
+ UserInput.logger.verbose(`Setting onRender callback`);
126
+ this.onRender = value;
127
+ return this;
128
+ }
129
+ /**
130
+ * @description Sets the minimum value for number inputs.
131
+ * @summary Configures the lowest number the user can input.
132
+ *
133
+ * @param value - The minimum value.
134
+ * @returns This UserInput instance for method chaining.
135
+ */
136
+ setMin(value) {
137
+ UserInput.logger.verbose(`Setting min value to: ${value}`);
138
+ this.min = value;
139
+ return this;
140
+ }
141
+ /**
142
+ * @description Sets the maximum value for number inputs.
143
+ * @summary Configures the highest number the user can input.
144
+ *
145
+ * @param value - The maximum value.
146
+ * @returns This UserInput instance for method chaining.
147
+ */
148
+ setMax(value) {
149
+ UserInput.logger.verbose(`Setting max value to: ${value}`);
150
+ this.max = value;
151
+ return this;
152
+ }
153
+ /**
154
+ * @description Sets whether to allow float values for number inputs.
155
+ * @summary Configures whether decimal numbers are allowed.
156
+ *
157
+ * @param value - Whether to allow float values.
158
+ * @returns This UserInput instance for method chaining.
159
+ */
160
+ setFloat(value) {
161
+ UserInput.logger.verbose(`Setting float to: ${value}`);
162
+ this.float = value;
163
+ return this;
164
+ }
165
+ /**
166
+ * @description Sets the number of decimal places to round to for float inputs.
167
+ * @summary Configures the precision of float inputs.
168
+ *
169
+ * @param value - The number of decimal places.
170
+ * @returns This UserInput instance for method chaining.
171
+ */
172
+ setRound(value) {
173
+ UserInput.logger.verbose(`Setting round to: ${value}`);
174
+ this.round = value;
175
+ return this;
176
+ }
177
+ /**
178
+ * @description Sets the instructions for the user.
179
+ * @summary Configures additional guidance provided to the user.
180
+ *
181
+ * @param value - The instructions.
182
+ * @returns This UserInput instance for method chaining.
183
+ */
184
+ setInstructions(value) {
185
+ UserInput.logger.verbose(`Setting instructions to: ${value}`);
186
+ this.instructions = value;
187
+ return this;
188
+ }
189
+ /**
190
+ * @description Sets the increment value for number inputs.
191
+ * @summary Configures the step size when increasing or decreasing the number.
192
+ *
193
+ * @param value - The increment value.
194
+ * @returns This UserInput instance for method chaining.
195
+ */
196
+ setIncrement(value) {
197
+ UserInput.logger.verbose(`Setting increment to: ${value}`);
198
+ this.increment = value;
199
+ return this;
200
+ }
201
+ /**
202
+ * @description Sets the separator for list inputs.
203
+ * @summary Configures the character used to separate list items.
204
+ *
205
+ * @param value - The separator character.
206
+ * @returns This UserInput instance for method chaining.
207
+ */
208
+ setSeparator(value) {
209
+ UserInput.logger.verbose(`Setting separator to: ${value}`);
210
+ this.separator = value;
211
+ return this;
212
+ }
213
+ /**
214
+ * @description Sets the active option style for select inputs.
215
+ * @summary Configures the style applied to the currently selected option.
216
+ *
217
+ * @param value - The active option style.
218
+ * @returns This UserInput instance for method chaining.
219
+ */
220
+ setActive(value) {
221
+ UserInput.logger.verbose(`Setting active style to: ${value}`);
222
+ this.active = value;
223
+ return this;
224
+ }
225
+ /**
226
+ * @description Sets the inactive option style for select inputs.
227
+ * @summary Configures the style applied to non-selected options.
228
+ *
229
+ * @param value - The inactive option style.
230
+ * @returns This UserInput instance for method chaining.
231
+ */
232
+ setInactive(value) {
233
+ UserInput.logger.verbose(`Setting inactive style to: ${value}`);
234
+ this.inactive = value;
235
+ return this;
236
+ }
237
+ setChoices(value) {
238
+ UserInput.logger.verbose(`Setting choices: ${JSON.stringify(value)}`);
239
+ this.choices = value;
240
+ return this;
241
+ }
242
+ /**
243
+ * @description Sets the hint text for the prompt.
244
+ * @summary Configures additional information displayed to the user.
245
+ *
246
+ * @param value - The hint text.
247
+ * @returns This UserInput instance for method chaining.
248
+ */
249
+ setHint(value) {
250
+ UserInput.logger.verbose(`Setting hint to: ${value}`);
251
+ this.hint = value;
252
+ return this;
253
+ }
254
+ /**
255
+ * @description Sets the warning text for the prompt.
256
+ * @summary Configures a warning message displayed to the user.
257
+ *
258
+ * @param value - The warning text.
259
+ * @returns This UserInput instance for method chaining.
260
+ */
261
+ setWarn(value) {
262
+ UserInput.logger.verbose(`Setting warn to: ${value}`);
263
+ this.warn = value;
264
+ return this;
265
+ }
266
+ setSuggest(value) {
267
+ UserInput.logger.verbose(`Setting suggest function`);
268
+ this.suggest = value;
269
+ return this;
270
+ }
271
+ /**
272
+ * @description Sets the limit for list inputs.
273
+ * @summary Configures the maximum number of items that can be selected in list-type prompts.
274
+ * @template R - The type of the prompt name, extending string.
275
+ * @param value - The maximum number of items that can be selected, or a function to determine this value.
276
+ * @return This UserInput instance for method chaining.
277
+ */
278
+ setLimit(value) {
279
+ UserInput.logger.verbose(`Setting limit to: ${value}`);
280
+ this.limit = value;
281
+ return this;
282
+ }
283
+ /**
284
+ * @description Sets the mask for password inputs.
285
+ * @summary Configures the character used to hide the user's input in password-type prompts.
286
+ * @template R - The type of the prompt name, extending string.
287
+ * @param value - The character used to mask the input, or a function to determine this value.
288
+ * @return This UserInput instance for method chaining.
289
+ */
290
+ setMask(value) {
291
+ UserInput.logger.verbose(`Setting mask to: ${value}`);
292
+ this.mask = value;
293
+ return this;
294
+ }
295
+ /**
296
+ * @description Sets the stdout stream for the prompt.
297
+ * @summary Configures the output stream used by the prompt for displaying messages and results.
298
+ * @param value - The Writable stream to be used as stdout.
299
+ * @return This UserInput instance for method chaining.
300
+ */
301
+ setStdout(value) {
302
+ UserInput.logger.verbose(`Setting stdout stream`);
303
+ this.stdout = value;
304
+ return this;
305
+ }
306
+ /**
307
+ * @description Sets the stdin stream for the prompt.
308
+ * @summary Configures the input stream used by the prompt for receiving user input.
309
+ * @param value - The Readable stream to be used as stdin.
310
+ * @return This UserInput instance for method chaining.
311
+ */
312
+ setStdin(value) {
313
+ this.stdin = value;
314
+ return this;
315
+ }
316
+ /**
317
+ * @description Asks the user for input based on the current UserInput configuration.
318
+ * @summary Prompts the user and returns their response as a single value.
319
+ * @template R - The type of the prompt name, extending string.
320
+ * @return A Promise that resolves to the user's answer.
321
+ */
322
+ async ask() {
323
+ return (await UserInput.ask(this))[this.name];
324
+ }
325
+ /**
326
+ * @description Asks the user one or more questions based on the provided UserInput configurations.
327
+ * @summary Prompts the user with one or more questions and returns their answers as an object.
328
+ * @template R - The type of the prompt name, extending string.
329
+ * @param question - A single UserInput instance or an array of UserInput instances.
330
+ * @return A Promise that resolves to an object containing the user's answers.
331
+ * @mermaid
332
+ * sequenceDiagram
333
+ * participant U as User
334
+ * participant A as ask method
335
+ * participant P as prompts library
336
+ * A->>P: Call prompts with question(s)
337
+ * P->>U: Display prompt(s)
338
+ * U->>P: Provide input
339
+ * P->>A: Return answers
340
+ * A->>A: Process answers
341
+ * A-->>Caller: Return processed answers
342
+ */
343
+ static async ask(question) {
344
+ const log = UserInput.logger.for(this.ask);
345
+ if (!Array.isArray(question)) {
346
+ question = [question];
347
+ }
348
+ let answers;
349
+ try {
350
+ log.verbose(`Asking questions: ${question.map((q) => q.name).join(", ")}`);
351
+ answers = await prompts(question);
352
+ log.verbose(`Received answers: ${JSON.stringify(answers, null, 2)}`);
353
+ }
354
+ catch (error) {
355
+ throw new Error(`Error while getting input: ${error}`);
356
+ }
357
+ return answers;
358
+ }
359
+ /**
360
+ * @description Asks the user for a number input.
361
+ * @summary Prompts the user to enter a number, with optional minimum, maximum, and initial values.
362
+ * @param name - The name of the prompt, used as the key in the returned answers object.
363
+ * @param question - The message displayed to the user.
364
+ * @param min - The minimum allowed value (optional).
365
+ * @param max - The maximum allowed value (optional).
366
+ * @param initial - The initial value presented to the user (optional).
367
+ * @return A Promise that resolves to the number entered by the user.
368
+ */
369
+ static async askNumber(name, question, min, max, initial) {
370
+ const log = UserInput.logger.for(this.askNumber);
371
+ log.verbose(`Asking number input: undefined, question: ${question}, min: ${min}, max: ${max}, initial: ${initial}`);
372
+ const userInput = new UserInput(name)
373
+ .setMessage(question)
374
+ .setType("number");
375
+ if (typeof min === "number")
376
+ userInput.setMin(min);
377
+ if (typeof max === "number")
378
+ userInput.setMax(max);
379
+ if (typeof initial === "number")
380
+ userInput.setInitial(initial);
381
+ return (await this.ask(userInput))[name];
382
+ }
383
+ /**
384
+ * @description Asks the user for a text input.
385
+ * @summary Prompts the user to enter text, with optional masking and initial value.
386
+ * @param name - The name of the prompt, used as the key in the returned answers object.
387
+ * @param question - The message displayed to the user.
388
+ * @param mask - The character used to mask the input (optional, for password-like inputs).
389
+ * @param initial - The initial value presented to the user (optional).
390
+ * @return A Promise that resolves to the text entered by the user.
391
+ */
392
+ static async askText(name, question, mask = undefined, initial) {
393
+ const log = UserInput.logger.for(this.askText);
394
+ log.verbose(`Asking text input: undefined, question: ${question}, mask: ${mask}, initial: ${initial}`);
395
+ const userInput = new UserInput(name).setMessage(question);
396
+ if (mask)
397
+ userInput.setMask(mask);
398
+ if (typeof initial === "string")
399
+ userInput.setInitial(initial);
400
+ return (await this.ask(userInput))[name];
401
+ }
402
+ /**
403
+ * @description Asks the user for a confirmation (yes/no).
404
+ * @summary Prompts the user with a yes/no question and returns a boolean result.
405
+ * @param name - The name of the prompt, used as the key in the returned answers object.
406
+ * @param question - The message displayed to the user.
407
+ * @param initial - The initial value presented to the user (optional).
408
+ * @return A Promise that resolves to a boolean representing the user's answer.
409
+ */
410
+ static async askConfirmation(name, question, initial) {
411
+ const log = UserInput.logger.for(this.askConfirmation);
412
+ log.verbose(`Asking confirmation input: undefined, question: ${question}, initial: ${initial}`);
413
+ const userInput = new UserInput(name)
414
+ .setMessage(question)
415
+ .setType("confirm");
416
+ if (typeof initial !== "undefined")
417
+ userInput.setInitial(initial);
418
+ return (await this.ask(userInput))[name];
419
+ }
420
+ /**
421
+ * @description Repeatedly asks for input until a valid response is given or the limit is reached.
422
+ * @summary This method insists on getting a valid input from the user, allowing for a specified number of attempts.
423
+ *
424
+ * @template R - The type of the expected result.
425
+ * @param input - The UserInput instance to use for prompting.
426
+ * @param test - A function to validate the user's input.
427
+ * @param limit - The maximum number of attempts allowed (default is 1).
428
+ * @param defaultConfirmation
429
+ * @return A Promise that resolves to the valid input or undefined if the limit is reached.
430
+ *
431
+ * @mermaid
432
+ * sequenceDiagram
433
+ * participant U as User
434
+ * participant I as insist method
435
+ * participant A as ask method
436
+ * participant T as test function
437
+ * participant C as askConfirmation method
438
+ * loop Until valid input or limit reached
439
+ * I->>A: Call ask with input
440
+ * A->>U: Prompt user
441
+ * U->>A: Provide input
442
+ * A->>I: Return result
443
+ * I->>T: Test result
444
+ * alt Test passes
445
+ * I->>C: Ask for confirmation
446
+ * C->>U: Confirm input
447
+ * U->>C: Provide confirmation
448
+ * C->>I: Return confirmation
449
+ * alt Confirmed
450
+ * I-->>Caller: Return valid result
451
+ * else Not confirmed
452
+ * I->>I: Continue loop
453
+ * end
454
+ * else Test fails
455
+ * I->>I: Continue loop
456
+ * end
457
+ * end
458
+ * I-->>Caller: Return undefined if limit reached
459
+ */
460
+ static async insist(input, test, defaultConfirmation, limit = 1) {
461
+ const log = UserInput.logger.for(this.insist);
462
+ log.verbose(`Insisting on input: ${input.name}, test: ${test.toString()}, defaultConfirmation: ${defaultConfirmation}, limit: ${limit}`);
463
+ let result = undefined;
464
+ let count = 0;
465
+ let confirmation;
466
+ try {
467
+ do {
468
+ result = (await UserInput.ask(input))[input.name];
469
+ if (!test(result)) {
470
+ result = undefined;
471
+ continue;
472
+ }
473
+ confirmation = await UserInput.askConfirmation(`${input.name}-confirm`, `Is the ${input.type} correct?`, defaultConfirmation);
474
+ if (!confirmation)
475
+ result = undefined;
476
+ } while (typeof result === "undefined" && limit > 1 && count++ < limit);
477
+ }
478
+ catch (e) {
479
+ log.error(`Error while insisting: ${e}`);
480
+ throw e;
481
+ }
482
+ if (typeof result === "undefined")
483
+ log.info("no selection...");
484
+ return result;
485
+ }
486
+ /**
487
+ * @description Repeatedly asks for text input until a valid response is given or the limit is reached.
488
+ * @summary This method insists on getting a valid text input from the user, allowing for a specified number of attempts.
489
+ *
490
+ * @param name - The name of the prompt, used as the key in the returned answers object.
491
+ * @param question - The message displayed to the user.
492
+ * @param test - A function to validate the user's input.
493
+ * @param mask - The character used to mask the input (optional, for password-like inputs).
494
+ * @param initial - The initial value presented to the user (optional).
495
+ * @param defaultConfirmation
496
+ * @param limit - The maximum number of attempts allowed (default is -1, meaning unlimited).
497
+ * @return A Promise that resolves to the valid input or undefined if the limit is reached.
498
+ */
499
+ static async insistForText(name, question, test, mask = undefined, initial, defaultConfirmation = false, limit = -1) {
500
+ const log = UserInput.logger.for(this.insistForText);
501
+ log.verbose(`Insisting for text input: undefined, question: ${question}, test: ${test.toString()}, mask: ${mask}, initial: ${initial}, defaultConfirmation: ${defaultConfirmation}, limit: ${limit}`);
502
+ const userInput = new UserInput(name).setMessage(question);
503
+ if (mask)
504
+ userInput.setMask(mask);
505
+ if (typeof initial === "string")
506
+ userInput.setInitial(initial);
507
+ return (await this.insist(userInput, test, defaultConfirmation, limit));
508
+ }
509
+ /**
510
+ * @description Repeatedly asks for number input until a valid response is given or the limit is reached.
511
+ * @summary This method insists on getting a valid number input from the user, allowing for a specified number of attempts.
512
+ *
513
+ * @param name - The name of the prompt, used as the key in the returned answers object.
514
+ * @param question - The message displayed to the user.
515
+ * @param test - A function to validate the user's input.
516
+ * @param min - The minimum allowed value (optional).
517
+ * @param max - The maximum allowed value (optional).
518
+ * @param initial - The initial value presented to the user (optional).
519
+ * @param defaultConfirmation
520
+ * @param limit - The maximum number of attempts allowed (default is -1, meaning unlimited).
521
+ * @return A Promise that resolves to the valid input or undefined if the limit is reached.
522
+ */
523
+ static async insistForNumber(name, question, test, min, max, initial, defaultConfirmation = false, limit = -1) {
524
+ const log = UserInput.logger.for(this.insistForNumber);
525
+ log.verbose(`Insisting for number input: undefined, question: ${question}, test: ${test.toString()}, min: ${min}, max: ${max}, initial: ${initial}, defaultConfirmation: ${defaultConfirmation}, limit: ${limit}`);
526
+ const userInput = new UserInput(name)
527
+ .setMessage(question)
528
+ .setType("number");
529
+ if (typeof min === "number")
530
+ userInput.setMin(min);
531
+ if (typeof max === "number")
532
+ userInput.setMax(max);
533
+ if (typeof initial === "number")
534
+ userInput.setInitial(initial);
535
+ return (await this.insist(userInput, test, defaultConfirmation, limit));
536
+ }
537
+ /**
538
+ * @description Parses command-line arguments based on the provided options.
539
+ * @summary Uses Node.js's util.parseArgs to parse command-line arguments and return the result.
540
+ * @param options - Configuration options for parsing arguments.
541
+ * @return An object containing the parsed arguments.
542
+ * @mermaid
543
+ * sequenceDiagram
544
+ * participant C as Caller
545
+ * participant P as parseArgs method
546
+ * participant U as util.parseArgs
547
+ * C->>P: Call with options
548
+ * P->>P: Prepare args object
549
+ * P->>U: Call parseArgs with prepared args
550
+ * U->>P: Return parsed result
551
+ * P-->>C: Return ParseArgsResult
552
+ */
553
+ static parseArgs(options) {
554
+ const log = UserInput.logger.for(this.parseArgs);
555
+ const args = {
556
+ args: process.argv.slice(2),
557
+ options: options,
558
+ };
559
+ log.debug(`Parsing arguments: ${JSON.stringify(args, null, 2)}`);
560
+ try {
561
+ return parseArgs(args);
562
+ }
563
+ catch (error) {
564
+ log.debug(`Error while parsing arguments:\n${JSON.stringify(args, null, 2)}\n | options\n${JSON.stringify(options, null, 2)}\n | ${error}`);
565
+ throw new Error(`Error while parsing arguments: ${error}`);
566
+ }
567
+ }
568
+ }
569
+
570
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9pbnB1dC9pbnB1dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE9BU04sTUFBTSxTQUFTLENBQUM7QUFDakIsT0FBTyxFQUFFLFNBQVMsRUFBbUIsTUFBTSxNQUFNLENBQUM7QUFFbEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBSTVDOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILE1BQU0sT0FBTyxTQUFTO2FBQ0ksV0FBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUF4QixBQUF5QixDQUFDO0lBc0p4RDs7Ozs7T0FLRztJQUNILFlBQVksSUFBb0I7UUEzSmhDOzs7V0FHRztRQUNILFNBQUksR0FBMkQsTUFBTSxDQUFDO1FBd0pwRSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNuQixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsT0FBTyxDQUFDLElBQTREO1FBQ2xFLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLG9CQUFvQixJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILFVBQVUsQ0FBQyxLQUFzQztRQUMvQyxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyx1QkFBdUIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxVQUFVLENBQ1IsS0FHYTtRQUViLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLDZCQUE2QixLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILFFBQVEsQ0FBQyxLQUF5RDtRQUNoRSxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxTQUFTLENBQUMsS0FBc0M7UUFDOUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMseUJBQXlCLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxXQUFXLENBQ1QsS0FFYTtRQUViLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDdEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsVUFBVSxDQUFDLEtBQXNDO1FBQy9DLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDckIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsV0FBVyxDQUFDLEtBQTJDO1FBQ3JELFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDdEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsTUFBTSxDQUFDLEtBQXlEO1FBQzlELFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLHlCQUF5QixLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILE1BQU0sQ0FBQyxLQUF5RDtRQUM5RCxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyx5QkFBeUIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQztRQUNqQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxRQUFRLENBQUMsS0FBMkQ7UUFDbEUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMscUJBQXFCLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsUUFBUSxDQUFDLEtBQXlEO1FBQ2hFLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLHFCQUFxQixLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILGVBQWUsQ0FBQyxLQUFtQztRQUNqRCxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyw0QkFBNEIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxZQUFZLENBQ1YsS0FBeUQ7UUFFekQsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMseUJBQXlCLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDdkIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsWUFBWSxDQUNWLEtBQXlEO1FBRXpELFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLHlCQUF5QixLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILFNBQVMsQ0FBQyxLQUF5RDtRQUNqRSxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyw0QkFBNEIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxXQUFXLENBQUMsS0FBeUQ7UUFDbkUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsOEJBQThCLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDdEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsVUFBVSxDQUNSLEtBQTZEO1FBRTdELFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLG9CQUFvQixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN0RSxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxPQUFPLENBQUMsS0FBeUQ7UUFDL0QsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsb0JBQW9CLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUM7UUFDbEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsT0FBTyxDQUFDLEtBQXlEO1FBQy9ELFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLG9CQUFvQixLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELFVBQVUsQ0FDUixLQUFvRTtRQUVwRSxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILFFBQVEsQ0FBQyxLQUF5RDtRQUNoRSxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxPQUFPLENBQUMsS0FBeUQ7UUFDL0QsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsb0JBQW9CLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUM7UUFDbEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxTQUFTLENBQUMsS0FBMkI7UUFDbkMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRDs7Ozs7T0FLRztJQUNILFFBQVEsQ0FBQyxLQUEyQjtRQUNsQyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxHQUFHO1FBQ1AsT0FBTyxDQUFDLE1BQU0sU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUF3QixDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztPQWlCRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUNkLFFBQXVDO1FBRXZDLE1BQU0sR0FBRyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzdCLFFBQVEsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3hCLENBQUM7UUFDRCxJQUFJLE9BQW1CLENBQUM7UUFDeEIsSUFBSSxDQUFDO1lBQ0gsR0FBRyxDQUFDLE9BQU8sQ0FDVCxxQkFBcUIsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUM5RCxDQUFDO1lBQ0YsT0FBTyxHQUFHLE1BQU0sT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2xDLEdBQUcsQ0FBQyxPQUFPLENBQUMscUJBQXFCLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdkUsQ0FBQztRQUFDLE9BQU8sS0FBYyxFQUFFLENBQUM7WUFDeEIsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBQ0QsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUNwQixJQUFZLEVBQ1osUUFBZ0IsRUFDaEIsR0FBWSxFQUNaLEdBQVksRUFDWixPQUFnQjtRQUVoQixNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakQsR0FBRyxDQUFDLE9BQU8sQ0FDVCw2Q0FBNkMsUUFBUSxVQUFVLEdBQUcsVUFBVSxHQUFHLGNBQWMsT0FBTyxFQUFFLENBQ3ZHLENBQUM7UUFDRixNQUFNLFNBQVMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUM7YUFDbEMsVUFBVSxDQUFDLFFBQVEsQ0FBQzthQUNwQixPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFckIsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRO1lBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVuRCxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVE7WUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRW5ELElBQUksT0FBTyxPQUFPLEtBQUssUUFBUTtZQUFFLFNBQVMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFL0QsT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUNsQixJQUFZLEVBQ1osUUFBZ0IsRUFDaEIsT0FBMkIsU0FBUyxFQUNwQyxPQUFnQjtRQUVoQixNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0MsR0FBRyxDQUFDLE9BQU8sQ0FDVCwyQ0FBMkMsUUFBUSxXQUFXLElBQUksY0FBYyxPQUFPLEVBQUUsQ0FDMUYsQ0FBQztRQUNGLE1BQU0sU0FBUyxHQUFHLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUUzRCxJQUFJLElBQUk7WUFBRSxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xDLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUTtZQUFFLFNBQVMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0QsT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQzFCLElBQVksRUFDWixRQUFnQixFQUNoQixPQUFpQjtRQUVqQixNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDdkQsR0FBRyxDQUFDLE9BQU8sQ0FDVCxtREFBbUQsUUFBUSxjQUFjLE9BQU8sRUFBRSxDQUNuRixDQUFDO1FBQ0YsTUFBTSxTQUFTLEdBQUcsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDO2FBQ2xDLFVBQVUsQ0FBQyxRQUFRLENBQUM7YUFDcEIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXRCLElBQUksT0FBTyxPQUFPLEtBQUssV0FBVztZQUFFLFNBQVMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDbEUsT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFDRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BdUNHO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQ2pCLEtBQWdCLEVBQ2hCLElBQXVDLEVBQ3ZDLG1CQUE0QixFQUM1QixLQUFLLEdBQUcsQ0FBQztRQUVULE1BQU0sR0FBRyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QyxHQUFHLENBQUMsT0FBTyxDQUNULHVCQUF1QixLQUFLLENBQUMsSUFBSSxXQUFXLElBQUksQ0FBQyxRQUFRLEVBQUUsMEJBQTBCLG1CQUFtQixZQUFZLEtBQUssRUFBRSxDQUM1SCxDQUFDO1FBQ0YsSUFBSSxNQUFNLEdBQWdDLFNBQVMsQ0FBQztRQUNwRCxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDZCxJQUFJLFlBQXFCLENBQUM7UUFDMUIsSUFBSSxDQUFDO1lBQ0gsR0FBRyxDQUFDO2dCQUNGLE1BQU0sR0FBRyxDQUFDLE1BQU0sU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUNuQyxLQUFLLENBQUMsSUFBNkIsQ0FDMUIsQ0FBQztnQkFDWixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7b0JBQ2xCLE1BQU0sR0FBRyxTQUFTLENBQUM7b0JBQ25CLFNBQVM7Z0JBQ1gsQ0FBQztnQkFDRCxZQUFZLEdBQUcsTUFBTSxTQUFTLENBQUMsZUFBZSxDQUM1QyxHQUFHLEtBQUssQ0FBQyxJQUFJLFVBQVUsRUFDdkIsVUFBVSxLQUFLLENBQUMsSUFBSSxXQUFXLEVBQy9CLG1CQUFtQixDQUNwQixDQUFDO2dCQUNGLElBQUksQ0FBQyxZQUFZO29CQUFFLE1BQU0sR0FBRyxTQUFTLENBQUM7WUFDeEMsQ0FBQyxRQUFRLE9BQU8sTUFBTSxLQUFLLFdBQVcsSUFBSSxLQUFLLEdBQUcsQ0FBQyxJQUFJLEtBQUssRUFBRSxHQUFHLEtBQUssRUFBRTtRQUMxRSxDQUFDO1FBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztZQUNwQixHQUFHLENBQUMsS0FBSyxDQUFDLDBCQUEwQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3pDLE1BQU0sQ0FBQyxDQUFDO1FBQ1YsQ0FBQztRQUVELElBQUksT0FBTyxNQUFNLEtBQUssV0FBVztZQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUMvRCxPQUFPLE1BQXVCLENBQUM7SUFDakMsQ0FBQztJQUNEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUN4QixJQUFZLEVBQ1osUUFBZ0IsRUFDaEIsSUFBOEIsRUFDOUIsT0FBMkIsU0FBUyxFQUNwQyxPQUFnQixFQUNoQixtQkFBbUIsR0FBRyxLQUFLLEVBQzNCLEtBQUssR0FBRyxDQUFDLENBQUM7UUFFVixNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDckQsR0FBRyxDQUFDLE9BQU8sQ0FDVCxrREFBa0QsUUFBUSxXQUFXLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxJQUFJLGNBQWMsT0FBTywwQkFBMEIsbUJBQW1CLFlBQVksS0FBSyxFQUFFLENBQ3pMLENBQUM7UUFDRixNQUFNLFNBQVMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFM0QsSUFBSSxJQUFJO1lBQUUsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVE7WUFBRSxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9ELE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQ3ZCLFNBQVMsRUFDVCxJQUF5QyxFQUN6QyxtQkFBbUIsRUFDbkIsS0FBSyxDQUNOLENBQVcsQ0FBQztJQUNmLENBQUM7SUFDRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQzFCLElBQVksRUFDWixRQUFnQixFQUNoQixJQUE4QixFQUM5QixHQUFZLEVBQ1osR0FBWSxFQUNaLE9BQWdCLEVBQ2hCLG1CQUFtQixHQUFHLEtBQUssRUFDM0IsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUVWLE1BQU0sR0FBRyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN2RCxHQUFHLENBQUMsT0FBTyxDQUNULG9EQUFvRCxRQUFRLFdBQVcsSUFBSSxDQUFDLFFBQVEsRUFBRSxVQUFVLEdBQUcsVUFBVSxHQUFHLGNBQWMsT0FBTywwQkFBMEIsbUJBQW1CLFlBQVksS0FBSyxFQUFFLENBQ3RNLENBQUM7UUFDRixNQUFNLFNBQVMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUM7YUFDbEMsVUFBVSxDQUFDLFFBQVEsQ0FBQzthQUNwQixPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFckIsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRO1lBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVuRCxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVE7WUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRW5ELElBQUksT0FBTyxPQUFPLEtBQUssUUFBUTtZQUFFLFNBQVMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0QsT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FDdkIsU0FBUyxFQUNULElBQXlDLEVBQ3pDLG1CQUFtQixFQUNuQixLQUFLLENBQ04sQ0FBVyxDQUFDO0lBQ2YsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7T0FlRztJQUNILE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBK0I7UUFDOUMsTUFBTSxHQUFHLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sSUFBSSxHQUFvQjtZQUM1QixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQzNCLE9BQU8sRUFBRSxPQUFPO1NBQ2pCLENBQUM7UUFDRixHQUFHLENBQUMsS0FBSyxDQUFDLHNCQUFzQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2pFLElBQUksQ0FBQztZQUNILE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pCLENBQUM7UUFBQyxPQUFPLEtBQWMsRUFBRSxDQUFDO1lBQ3hCLEdBQUcsQ0FBQyxLQUFLLENBQ1AsbUNBQW1DLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsaUJBQWlCLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsUUFBUSxLQUFLLEVBQUUsQ0FDakksQ0FBQztZQUNGLE1BQU0sSUFBSSxLQUFLLENBQUMsa0NBQWtDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDN0QsQ0FBQztJQUNILENBQUMiLCJmaWxlIjoiaW5wdXQvaW5wdXQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcHJvbXB0cywge1xuICBBbnN3ZXJzLFxuICBDaG9pY2UsXG4gIEZhbHN5LFxuICBJbml0aWFsUmV0dXJuVmFsdWUsXG4gIFByZXZDYWxsZXIsXG4gIFByb21wdE9iamVjdCxcbiAgUHJvbXB0VHlwZSxcbiAgVmFsdWVPckZ1bmMsXG59IGZyb20gXCJwcm9tcHRzXCI7XG5pbXBvcnQgeyBwYXJzZUFyZ3MsIFBhcnNlQXJnc0NvbmZpZyB9IGZyb20gXCJ1dGlsXCI7XG5pbXBvcnQgeyBXcml0YWJsZSwgUmVhZGFibGUgfSBmcm9tIFwic3RyZWFtXCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIi4uL291dHB1dC9sb2dnaW5nXCI7XG5pbXBvcnQgeyBLbGV1ciB9IGZyb20gXCIuLi9vdXRwdXQvdHlwZXNcIjtcbmltcG9ydCB7IFBhcnNlQXJnc09wdGlvbnNDb25maWcsIFBhcnNlQXJnc1Jlc3VsdCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlcHJlc2VudHMgYSB1c2VyIGlucHV0IHByb21wdCB3aXRoIHZhcmlvdXMgY29uZmlndXJhdGlvbiBvcHRpb25zLlxuICogQHN1bW1hcnkgVGhpcyBjbGFzcyBwcm92aWRlcyBhIGZsZXhpYmxlIGludGVyZmFjZSBmb3IgY3JlYXRpbmcgYW5kIG1hbmFnaW5nIHVzZXIgaW5wdXQgcHJvbXB0cy5cbiAqIEl0IGltcGxlbWVudHMgdGhlIFByb21wdE9iamVjdCBpbnRlcmZhY2UgZnJvbSB0aGUgJ3Byb21wdHMnIGxpYnJhcnkgYW5kIG9mZmVycyBtZXRob2RzIHRvIHNldFxuICogdmFyaW91cyBwcm9wZXJ0aWVzIG9mIHRoZSBwcm9tcHQuIFRoZSBjbGFzcyBhbHNvIGluY2x1ZGVzIHN0YXRpYyBtZXRob2RzIGZvciBjb21tb24gaW5wdXQgc2NlbmFyaW9zXG4gKiBhbmQgYXJndW1lbnQgcGFyc2luZy5cbiAqXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSB0eXBlIG9mIHRoZSBwcm9tcHQgbmFtZSwgZXh0ZW5kaW5nIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9tcHQsIHVzZWQgYXMgdGhlIGtleSBpbiB0aGUgcmV0dXJuZWQgYW5zd2VycyBvYmplY3QuXG4gKlxuICogQGNsYXNzXG4gKi9cbmV4cG9ydCBjbGFzcyBVc2VySW5wdXQ8UiBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4gaW1wbGVtZW50cyBQcm9tcHRPYmplY3Q8Uj4ge1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBsb2dnZXIgPSBMb2dnaW5nLmZvcihVc2VySW5wdXQpO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSB0eXBlIG9mIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IERldGVybWluZXMgdGhlIGlucHV0IG1ldGhvZCAoZS5nLiwgdGV4dCwgbnVtYmVyLCBjb25maXJtKS5cbiAgICovXG4gIHR5cGU6IFByb21wdFR5cGUgfCBGYWxzeSB8IFByZXZDYWxsZXI8UiwgUHJvbXB0VHlwZSB8IEZhbHN5PiA9IFwidGV4dFwiO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIG5hbWUgb2YgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgVXNlZCBhcyB0aGUga2V5IGluIHRoZSByZXR1cm5lZCBhbnN3ZXJzIG9iamVjdC5cbiAgICovXG4gIG5hbWU6IFZhbHVlT3JGdW5jPFI+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIG1lc3NhZ2UgZGlzcGxheWVkIHRvIHRoZSB1c2VyLlxuICAgKiBAc3VtbWFyeSBUaGUgcXVlc3Rpb24gb3IgaW5zdHJ1Y3Rpb24gcHJlc2VudGVkIHRvIHRoZSB1c2VyLlxuICAgKi9cbiAgbWVzc2FnZT86IFZhbHVlT3JGdW5jPHN0cmluZz4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBUaGUgZGVmYXVsdCB2YWx1ZSBwcmVzZW50ZWQgdG8gdGhlIHVzZXIuXG4gICAqL1xuICBpbml0aWFsPzpcbiAgICB8IEluaXRpYWxSZXR1cm5WYWx1ZVxuICAgIHwgUHJldkNhbGxlcjxSLCBJbml0aWFsUmV0dXJuVmFsdWUgfCBQcm9taXNlPEluaXRpYWxSZXR1cm5WYWx1ZT4+XG4gICAgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgc3R5bGUgb2YgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgRGV0ZXJtaW5lcyB0aGUgdmlzdWFsIHN0eWxlIG9mIHRoZSBwcm9tcHQuXG4gICAqL1xuICBzdHlsZT86IHN0cmluZyB8IFByZXZDYWxsZXI8Uiwgc3RyaW5nIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGZvcm1hdCBmdW5jdGlvbiBmb3IgdGhlIGlucHV0LlxuICAgKiBAc3VtbWFyeSBBIGZ1bmN0aW9uIHRvIGZvcm1hdCB0aGUgdXNlcidzIGlucHV0IGJlZm9yZSBpdCdzIHJldHVybmVkLlxuICAgKi9cbiAgZm9ybWF0PzogUHJldkNhbGxlcjxSLCB2b2lkPiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSB2YWxpZGF0aW9uIGZ1bmN0aW9uIGZvciB0aGUgaW5wdXQuXG4gICAqIEBzdW1tYXJ5IEEgZnVuY3Rpb24gdG8gdmFsaWRhdGUgdGhlIHVzZXIncyBpbnB1dC5cbiAgICovXG4gIHZhbGlkYXRlPzpcbiAgICB8IFByZXZDYWxsZXI8UiwgYm9vbGVhbiB8IHN0cmluZyB8IFByb21pc2U8Ym9vbGVhbiB8IHN0cmluZz4+XG4gICAgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgb25TdGF0ZSBjYWxsYmFjayBmdW5jdGlvbi5cbiAgICogQHN1bW1hcnkgQSBmdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgc3RhdGUgb2YgdGhlIHByb21wdCBjaGFuZ2VzLlxuICAgKi9cbiAgb25TdGF0ZT86IFByZXZDYWxsZXI8Uiwgdm9pZD4gfCB1bmRlZmluZWQ7XG5cbiAgb25SZW5kZXI/OiAoKGtsZXVyOiBLbGV1cikgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgbWluaW11bSB2YWx1ZSBmb3IgbnVtYmVyIGlucHV0cy5cbiAgICogQHN1bW1hcnkgVGhlIGxvd2VzdCBudW1iZXIgdGhlIHVzZXIgY2FuIGlucHV0LlxuICAgKi9cbiAgbWluPzogbnVtYmVyIHwgUHJldkNhbGxlcjxSLCBudW1iZXIgfCBGYWxzeT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgbWF4aW11bSB2YWx1ZSBmb3IgbnVtYmVyIGlucHV0cy5cbiAgICogQHN1bW1hcnkgVGhlIGhpZ2hlc3QgbnVtYmVyIHRoZSB1c2VyIGNhbiBpbnB1dC5cbiAgICovXG4gIG1heD86IG51bWJlciB8IFByZXZDYWxsZXI8UiwgbnVtYmVyIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gV2hldGhlciB0byBhbGxvdyBmbG9hdCB2YWx1ZXMgZm9yIG51bWJlciBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IElmIHRydWUsIGFsbG93cyBkZWNpbWFsIG51bWJlcnMuXG4gICAqL1xuICBmbG9hdD86IGJvb2xlYW4gfCBQcmV2Q2FsbGVyPFIsIGJvb2xlYW4gfCBGYWxzeT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzIHRvIHJvdW5kIHRvIGZvciBmbG9hdCBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IERldGVybWluZXMgdGhlIHByZWNpc2lvbiBvZiBmbG9hdCBpbnB1dHMuXG4gICAqL1xuICByb3VuZD86IG51bWJlciB8IFByZXZDYWxsZXI8UiwgbnVtYmVyIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSW5zdHJ1Y3Rpb25zIGZvciB0aGUgdXNlci5cbiAgICogQHN1bW1hcnkgQWRkaXRpb25hbCBndWlkYW5jZSBwcm92aWRlZCB0byB0aGUgdXNlci5cbiAgICovXG4gIGluc3RydWN0aW9ucz86IHN0cmluZyB8IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgaW5jcmVtZW50IHZhbHVlIGZvciBudW1iZXIgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBUaGUgc3RlcCBzaXplIHdoZW4gaW5jcmVhc2luZyBvciBkZWNyZWFzaW5nIHRoZSBudW1iZXIuXG4gICAqL1xuICBpbmNyZW1lbnQ/OiBudW1iZXIgfCBQcmV2Q2FsbGVyPFIsIG51bWJlciB8IEZhbHN5PiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBzZXBhcmF0b3IgZm9yIGxpc3QgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBUaGUgY2hhcmFjdGVyIHVzZWQgdG8gc2VwYXJhdGUgbGlzdCBpdGVtcy5cbiAgICovXG4gIHNlcGFyYXRvcj86IHN0cmluZyB8IFByZXZDYWxsZXI8Uiwgc3RyaW5nIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGFjdGl2ZSBvcHRpb24gc3R5bGUgZm9yIHNlbGVjdCBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IFRoZSBzdHlsZSBhcHBsaWVkIHRvIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgb3B0aW9uLlxuICAgKi9cbiAgYWN0aXZlPzogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgaW5hY3RpdmUgb3B0aW9uIHN0eWxlIGZvciBzZWxlY3QgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBUaGUgc3R5bGUgYXBwbGllZCB0byBub24tc2VsZWN0ZWQgb3B0aW9ucy5cbiAgICovXG4gIGluYWN0aXZlPzogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWQ7XG5cbiAgY2hvaWNlcz86IENob2ljZVtdIHwgUHJldkNhbGxlcjxSLCBDaG9pY2VbXSB8IEZhbHN5PiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBoaW50IHRleHQgZm9yIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gZGlzcGxheWVkIHRvIHRoZSB1c2VyLlxuICAgKi9cbiAgaGludD86IHN0cmluZyB8IFByZXZDYWxsZXI8Uiwgc3RyaW5nIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIHdhcm5pbmcgdGV4dCBmb3IgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgQSB3YXJuaW5nIG1lc3NhZ2UgZGlzcGxheWVkIHRvIHRoZSB1c2VyLlxuICAgKi9cbiAgd2Fybj86IHN0cmluZyB8IFByZXZDYWxsZXI8Uiwgc3RyaW5nIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIHN1Z2dlc3Q/OiAoKGlucHV0OiBhbnksIGNob2ljZXM6IENob2ljZVtdKSA9PiBQcm9taXNlPGFueT4pIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGxpbWl0IGZvciBsaXN0IGlucHV0cy5cbiAgICogQHN1bW1hcnkgVGhlIG1heGltdW0gbnVtYmVyIG9mIGl0ZW1zIHRoYXQgY2FuIGJlIHNlbGVjdGVkLlxuICAgKi9cbiAgbGltaXQ/OiBudW1iZXIgfCBQcmV2Q2FsbGVyPFIsIG51bWJlciB8IEZhbHN5PiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBtYXNrIGZvciBwYXNzd29yZCBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IFRoZSBjaGFyYWN0ZXIgdXNlZCB0byBoaWRlIHRoZSB1c2VyJ3MgaW5wdXQuXG4gICAqL1xuICBtYXNrPzogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgc3Rkb3V0IHN0cmVhbSBmb3IgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgVGhlIG91dHB1dCBzdHJlYW0gdXNlZCBieSB0aGUgcHJvbXB0LlxuICAgKi9cbiAgc3Rkb3V0PzogV3JpdGFibGUgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgc3RkaW4gc3RyZWFtIGZvciB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBUaGUgaW5wdXQgc3RyZWFtIHVzZWQgYnkgdGhlIHByb21wdC5cbiAgICovXG4gIHN0ZGluPzogUmVhZGFibGUgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IFVzZXJJbnB1dCBpbnN0YW5jZS5cbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBuZXcgVXNlcklucHV0IG9iamVjdCB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9tcHQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihuYW1lOiBWYWx1ZU9yRnVuYzxSPikge1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIHR5cGUgb2YgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgaW5wdXQgbWV0aG9kIGZvciB0aGUgcHJvbXB0LlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFRoZSB0eXBlIG9mIHRoZSBwcm9tcHQuXG4gICAqIEByZXR1cm5zIFRoaXMgVXNlcklucHV0IGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAqL1xuICBzZXRUeXBlKHR5cGU6IFByb21wdFR5cGUgfCBGYWxzeSB8IFByZXZDYWxsZXI8UiwgUHJvbXB0VHlwZSB8IEZhbHN5Pik6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyB0eXBlIHRvOiAke3R5cGV9YCk7XG4gICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgbWVzc2FnZSBvZiB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBxdWVzdGlvbiBvciBpbnN0cnVjdGlvbiBwcmVzZW50ZWQgdG8gdGhlIHVzZXIuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBtZXNzYWdlIHRvIGJlIGRpc3BsYXllZC5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldE1lc3NhZ2UodmFsdWU6IFZhbHVlT3JGdW5jPHN0cmluZz4gfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgbWVzc2FnZSB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLm1lc3NhZ2UgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBkZWZhdWx0IHZhbHVlIHByZXNlbnRlZCB0byB0aGUgdXNlci5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAqIEByZXR1cm5zIFRoaXMgVXNlcklucHV0IGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAqL1xuICBzZXRJbml0aWFsKFxuICAgIHZhbHVlOlxuICAgICAgfCBJbml0aWFsUmV0dXJuVmFsdWVcbiAgICAgIHwgUHJldkNhbGxlcjxSLCBJbml0aWFsUmV0dXJuVmFsdWUgfCBQcm9taXNlPEluaXRpYWxSZXR1cm5WYWx1ZT4+XG4gICAgICB8IHVuZGVmaW5lZFxuICApOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgaW5pdGlhbCB2YWx1ZSB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLmluaXRpYWwgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgc3R5bGUgb2YgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgdmlzdWFsIHN0eWxlIG9mIHRoZSBwcm9tcHQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBzdHlsZSB0byBiZSBhcHBsaWVkLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0U3R5bGUodmFsdWU6IHN0cmluZyB8IFByZXZDYWxsZXI8Uiwgc3RyaW5nIHwgRmFsc3k+IHwgdW5kZWZpbmVkKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIHN0eWxlIHRvOiAke3ZhbHVlfWApO1xuICAgIHRoaXMuc3R5bGUgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgZm9ybWF0IGZ1bmN0aW9uIG9mIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgYSBmdW5jdGlvbiB0byBmb3JtYXQgdGhlIHVzZXIncyBpbnB1dCBiZWZvcmUgaXQncyByZXR1cm5lZC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIGZvcm1hdCBmdW5jdGlvbi5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldEZvcm1hdCh2YWx1ZTogUHJldkNhbGxlcjxSLCB2b2lkPiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBmb3JtYXQgZnVuY3Rpb25gKTtcbiAgICB0aGlzLmZvcm1hdCA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSB2YWxpZGF0aW9uIGZ1bmN0aW9uIG9mIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgYSBmdW5jdGlvbiB0byB2YWxpZGF0ZSB0aGUgdXNlcidzIGlucHV0LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsaWRhdGlvbiBmdW5jdGlvbi5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldFZhbGlkYXRlKFxuICAgIHZhbHVlOlxuICAgICAgfCBQcmV2Q2FsbGVyPFIsIGJvb2xlYW4gfCBzdHJpbmcgfCBQcm9taXNlPGJvb2xlYW4gfCBzdHJpbmc+PlxuICAgICAgfCB1bmRlZmluZWRcbiAgKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIHZhbGlkYXRlIGZ1bmN0aW9uYCk7XG4gICAgdGhpcy52YWxpZGF0ZSA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBvblN0YXRlIGNhbGxiYWNrIG9mIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgYSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB0aGUgc3RhdGUgb2YgdGhlIHByb21wdCBjaGFuZ2VzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgb25TdGF0ZSBjYWxsYmFjayBmdW5jdGlvbi5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldE9uU3RhdGUodmFsdWU6IFByZXZDYWxsZXI8Uiwgdm9pZD4gfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgb25TdGF0ZSBjYWxsYmFja2ApO1xuICAgIHRoaXMub25TdGF0ZSA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBvblJlbmRlciBjYWxsYmFjayBvZiB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIGEgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIHByb21wdCBpcyByZW5kZXJlZC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIG9uUmVuZGVyIGNhbGxiYWNrIGZ1bmN0aW9uLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0T25SZW5kZXIodmFsdWU6ICgoa2xldXI6IEtsZXVyKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBvblJlbmRlciBjYWxsYmFja2ApO1xuICAgIHRoaXMub25SZW5kZXIgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgbWluaW11bSB2YWx1ZSBmb3IgbnVtYmVyIGlucHV0cy5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgbG93ZXN0IG51bWJlciB0aGUgdXNlciBjYW4gaW5wdXQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBtaW5pbXVtIHZhbHVlLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0TWluKHZhbHVlOiBudW1iZXIgfCBQcmV2Q2FsbGVyPFIsIG51bWJlciB8IEZhbHN5PiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBtaW4gdmFsdWUgdG86ICR7dmFsdWV9YCk7XG4gICAgdGhpcy5taW4gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgbWF4aW11bSB2YWx1ZSBmb3IgbnVtYmVyIGlucHV0cy5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgaGlnaGVzdCBudW1iZXIgdGhlIHVzZXIgY2FuIGlucHV0LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgbWF4aW11bSB2YWx1ZS5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldE1heCh2YWx1ZTogbnVtYmVyIHwgUHJldkNhbGxlcjxSLCBudW1iZXIgfCBGYWxzeT4gfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgbWF4IHZhbHVlIHRvOiAke3ZhbHVlfWApO1xuICAgIHRoaXMubWF4ID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgd2hldGhlciB0byBhbGxvdyBmbG9hdCB2YWx1ZXMgZm9yIG51bWJlciBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgd2hldGhlciBkZWNpbWFsIG51bWJlcnMgYXJlIGFsbG93ZWQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFdoZXRoZXIgdG8gYWxsb3cgZmxvYXQgdmFsdWVzLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0RmxvYXQodmFsdWU6IGJvb2xlYW4gfCBQcmV2Q2FsbGVyPFIsIGJvb2xlYW4gfCBGYWxzeT4gfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgZmxvYXQgdG86ICR7dmFsdWV9YCk7XG4gICAgdGhpcy5mbG9hdCA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXMgdG8gcm91bmQgdG8gZm9yIGZsb2F0IGlucHV0cy5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgcHJlY2lzaW9uIG9mIGZsb2F0IGlucHV0cy5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcy5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldFJvdW5kKHZhbHVlOiBudW1iZXIgfCBQcmV2Q2FsbGVyPFIsIG51bWJlciB8IEZhbHN5PiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyByb3VuZCB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLnJvdW5kID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGluc3RydWN0aW9ucyBmb3IgdGhlIHVzZXIuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgYWRkaXRpb25hbCBndWlkYW5jZSBwcm92aWRlZCB0byB0aGUgdXNlci5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIGluc3RydWN0aW9ucy5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldEluc3RydWN0aW9ucyh2YWx1ZTogc3RyaW5nIHwgYm9vbGVhbiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBpbnN0cnVjdGlvbnMgdG86ICR7dmFsdWV9YCk7XG4gICAgdGhpcy5pbnN0cnVjdGlvbnMgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgaW5jcmVtZW50IHZhbHVlIGZvciBudW1iZXIgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBzdGVwIHNpemUgd2hlbiBpbmNyZWFzaW5nIG9yIGRlY3JlYXNpbmcgdGhlIG51bWJlci5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIGluY3JlbWVudCB2YWx1ZS5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldEluY3JlbWVudChcbiAgICB2YWx1ZTogbnVtYmVyIHwgUHJldkNhbGxlcjxSLCBudW1iZXIgfCBGYWxzeT4gfCB1bmRlZmluZWRcbiAgKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIGluY3JlbWVudCB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLmluY3JlbWVudCA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBzZXBhcmF0b3IgZm9yIGxpc3QgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBjaGFyYWN0ZXIgdXNlZCB0byBzZXBhcmF0ZSBsaXN0IGl0ZW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgc2VwYXJhdG9yIGNoYXJhY3Rlci5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldFNlcGFyYXRvcihcbiAgICB2YWx1ZTogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWRcbiAgKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIHNlcGFyYXRvciB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLnNlcGFyYXRvciA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBhY3RpdmUgb3B0aW9uIHN0eWxlIGZvciBzZWxlY3QgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBzdHlsZSBhcHBsaWVkIHRvIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgb3B0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgYWN0aXZlIG9wdGlvbiBzdHlsZS5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldEFjdGl2ZSh2YWx1ZTogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgYWN0aXZlIHN0eWxlIHRvOiAke3ZhbHVlfWApO1xuICAgIHRoaXMuYWN0aXZlID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGluYWN0aXZlIG9wdGlvbiBzdHlsZSBmb3Igc2VsZWN0IGlucHV0cy5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgc3R5bGUgYXBwbGllZCB0byBub24tc2VsZWN0ZWQgb3B0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIGluYWN0aXZlIG9wdGlvbiBzdHlsZS5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldEluYWN0aXZlKHZhbHVlOiBzdHJpbmcgfCBQcmV2Q2FsbGVyPFIsIHN0cmluZyB8IEZhbHN5PiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBpbmFjdGl2ZSBzdHlsZSB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLmluYWN0aXZlID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzZXRDaG9pY2VzKFxuICAgIHZhbHVlOiBDaG9pY2VbXSB8IFByZXZDYWxsZXI8UiwgQ2hvaWNlW10gfCBGYWxzeT4gfCB1bmRlZmluZWRcbiAgKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIGNob2ljZXM6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfWApO1xuICAgIHRoaXMuY2hvaWNlcyA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBoaW50IHRleHQgZm9yIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBoaW50IHRleHQuXG4gICAqIEByZXR1cm5zIFRoaXMgVXNlcklucHV0IGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAqL1xuICBzZXRIaW50KHZhbHVlOiBzdHJpbmcgfCBQcmV2Q2FsbGVyPFIsIHN0cmluZyB8IEZhbHN5PiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBoaW50IHRvOiAke3ZhbHVlfWApO1xuICAgIHRoaXMuaGludCA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSB3YXJuaW5nIHRleHQgZm9yIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgYSB3YXJuaW5nIG1lc3NhZ2UgZGlzcGxheWVkIHRvIHRoZSB1c2VyLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgd2FybmluZyB0ZXh0LlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0V2Fybih2YWx1ZTogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgd2FybiB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLndhcm4gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHNldFN1Z2dlc3QoXG4gICAgdmFsdWU6ICgoaW5wdXQ6IGFueSwgY2hvaWNlczogQ2hvaWNlW10pID0+IFByb21pc2U8YW55PikgfCB1bmRlZmluZWRcbiAgKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIHN1Z2dlc3QgZnVuY3Rpb25gKTtcbiAgICB0aGlzLnN1Z2dlc3QgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgbGltaXQgZm9yIGxpc3QgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBpdGVtcyB0aGF0IGNhbiBiZSBzZWxlY3RlZCBpbiBsaXN0LXR5cGUgcHJvbXB0cy5cbiAgICogQHRlbXBsYXRlIFIgLSBUaGUgdHlwZSBvZiB0aGUgcHJvbXB0IG5hbWUsIGV4dGVuZGluZyBzdHJpbmcuXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBtYXhpbXVtIG51bWJlciBvZiBpdGVtcyB0aGF0IGNhbiBiZSBzZWxlY3RlZCwgb3IgYSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgdGhpcyB2YWx1ZS5cbiAgICogQHJldHVybiBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0TGltaXQodmFsdWU6IG51bWJlciB8IFByZXZDYWxsZXI8UiwgbnVtYmVyIHwgRmFsc3k+IHwgdW5kZWZpbmVkKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIGxpbWl0IHRvOiAke3ZhbHVlfWApO1xuICAgIHRoaXMubGltaXQgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgbWFzayBmb3IgcGFzc3dvcmQgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBjaGFyYWN0ZXIgdXNlZCB0byBoaWRlIHRoZSB1c2VyJ3MgaW5wdXQgaW4gcGFzc3dvcmQtdHlwZSBwcm9tcHRzLlxuICAgKiBAdGVtcGxhdGUgUiAtIFRoZSB0eXBlIG9mIHRoZSBwcm9tcHQgbmFtZSwgZXh0ZW5kaW5nIHN0cmluZy5cbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIGNoYXJhY3RlciB1c2VkIHRvIG1hc2sgdGhlIGlucHV0LCBvciBhIGZ1bmN0aW9uIHRvIGRldGVybWluZSB0aGlzIHZhbHVlLlxuICAgKiBAcmV0dXJuIFRoaXMgVXNlcklucHV0IGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAqL1xuICBzZXRNYXNrKHZhbHVlOiBzdHJpbmcgfCBQcmV2Q2FsbGVyPFIsIHN0cmluZyB8IEZhbHN5PiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBtYXNrIHRvOiAke3ZhbHVlfWApO1xuICAgIHRoaXMubWFzayA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBzdGRvdXQgc3RyZWFtIGZvciB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBvdXRwdXQgc3RyZWFtIHVzZWQgYnkgdGhlIHByb21wdCBmb3IgZGlzcGxheWluZyBtZXNzYWdlcyBhbmQgcmVzdWx0cy5cbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIFdyaXRhYmxlIHN0cmVhbSB0byBiZSB1c2VkIGFzIHN0ZG91dC5cbiAgICogQHJldHVybiBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0U3Rkb3V0KHZhbHVlOiBXcml0YWJsZSB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBzdGRvdXQgc3RyZWFtYCk7XG4gICAgdGhpcy5zdGRvdXQgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIHN0ZGluIHN0cmVhbSBmb3IgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgaW5wdXQgc3RyZWFtIHVzZWQgYnkgdGhlIHByb21wdCBmb3IgcmVjZWl2aW5nIHVzZXIgaW5wdXQuXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBSZWFkYWJsZSBzdHJlYW0gdG8gYmUgdXNlZCBhcyBzdGRpbi5cbiAgICogQHJldHVybiBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0U3RkaW4odmFsdWU6IFJlYWRhYmxlIHwgdW5kZWZpbmVkKTogdGhpcyB7XG4gICAgdGhpcy5zdGRpbiA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBc2tzIHRoZSB1c2VyIGZvciBpbnB1dCBiYXNlZCBvbiB0aGUgY3VycmVudCBVc2VySW5wdXQgY29uZmlndXJhdGlvbi5cbiAgICogQHN1bW1hcnkgUHJvbXB0cyB0aGUgdXNlciBhbmQgcmV0dXJucyB0aGVpciByZXNwb25zZSBhcyBhIHNpbmdsZSB2YWx1ZS5cbiAgICogQHRlbXBsYXRlIFIgLSBUaGUgdHlwZSBvZiB0aGUgcHJvbXB0IG5hbWUsIGV4dGVuZGluZyBzdHJpbmcuXG4gICAqIEByZXR1cm4gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHVzZXIncyBhbnN3ZXIuXG4gICAqL1xuICBhc3luYyBhc2soKSB7XG4gICAgcmV0dXJuIChhd2FpdCBVc2VySW5wdXQuYXNrKHRoaXMpKVt0aGlzLm5hbWUgYXMga2V5b2YgQW5zd2VyczxSPl07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFza3MgdGhlIHVzZXIgb25lIG9yIG1vcmUgcXVlc3Rpb25zIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBVc2VySW5wdXQgY29uZmlndXJhdGlvbnMuXG4gICAqIEBzdW1tYXJ5IFByb21wdHMgdGhlIHVzZXIgd2l0aCBvbmUgb3IgbW9yZSBxdWVzdGlvbnMgYW5kIHJldHVybnMgdGhlaXIgYW5zd2VycyBhcyBhbiBvYmplY3QuXG4gICAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHR5cGUgb2YgdGhlIHByb21wdCBuYW1lLCBleHRlbmRpbmcgc3RyaW5nLlxuICAgKiBAcGFyYW0gcXVlc3Rpb24gLSBBIHNpbmdsZSBVc2VySW5wdXQgaW5zdGFuY2Ugb3IgYW4gYXJyYXkgb2YgVXNlcklucHV0IGluc3RhbmNlcy5cbiAgICogQHJldHVybiBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgdXNlcidzIGFuc3dlcnMuXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IFUgYXMgVXNlclxuICAgKiAgIHBhcnRpY2lwYW50IEEgYXMgYXNrIG1ldGhvZFxuICAgKiAgIHBhcnRpY2lwYW50IFAgYXMgcHJvbXB0cyBsaWJyYXJ5XG4gICAqICAgQS0+PlA6IENhbGwgcHJvbXB0cyB3aXRoIHF1ZXN0aW9uKHMpXG4gICAqICAgUC0+PlU6IERpc3BsYXkgcHJvbXB0KHMpXG4gICAqICAgVS0+PlA6IFByb3ZpZGUgaW5wdXRcbiAgICogICBQLT4+QTogUmV0dXJuIGFuc3dlcnNcbiAgICogICBBLT4+QTogUHJvY2VzcyBhbnN3ZXJzXG4gICAqICAgQS0tPj5DYWxsZXI6IFJldHVybiBwcm9jZXNzZWQgYW5zd2Vyc1xuICAgKi9cbiAgc3RhdGljIGFzeW5jIGFzazxSIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPihcbiAgICBxdWVzdGlvbjogVXNlcklucHV0PFI+IHwgVXNlcklucHV0PFI+W11cbiAgKSB7XG4gICAgY29uc3QgbG9nID0gVXNlcklucHV0LmxvZ2dlci5mb3IodGhpcy5hc2spO1xuICAgIGlmICghQXJyYXkuaXNBcnJheShxdWVzdGlvbikpIHtcbiAgICAgIHF1ZXN0aW9uID0gW3F1ZXN0aW9uXTtcbiAgICB9XG4gICAgbGV0IGFuc3dlcnM6IEFuc3dlcnM8Uj47XG4gICAgdHJ5IHtcbiAgICAgIGxvZy52ZXJib3NlKFxuICAgICAgICBgQXNraW5nIHF1ZXN0aW9uczogJHtxdWVzdGlvbi5tYXAoKHEpID0+IHEubmFtZSkuam9pbihcIiwgXCIpfWBcbiAgICAgICk7XG4gICAgICBhbnN3ZXJzID0gYXdhaXQgcHJvbXB0cyhxdWVzdGlvbik7XG4gICAgICBsb2cudmVyYm9zZShgUmVjZWl2ZWQgYW5zd2VyczogJHtKU09OLnN0cmluZ2lmeShhbnN3ZXJzLCBudWxsLCAyKX1gKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFcnJvciB3aGlsZSBnZXR0aW5nIGlucHV0OiAke2Vycm9yfWApO1xuICAgIH1cbiAgICByZXR1cm4gYW5zd2VycztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQXNrcyB0aGUgdXNlciBmb3IgYSBudW1iZXIgaW5wdXQuXG4gICAqIEBzdW1tYXJ5IFByb21wdHMgdGhlIHVzZXIgdG8gZW50ZXIgYSBudW1iZXIsIHdpdGggb3B0aW9uYWwgbWluaW11bSwgbWF4aW11bSwgYW5kIGluaXRpYWwgdmFsdWVzLlxuICAgKiBAcGFyYW0gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9tcHQsIHVzZWQgYXMgdGhlIGtleSBpbiB0aGUgcmV0dXJuZWQgYW5zd2VycyBvYmplY3QuXG4gICAqIEBwYXJhbSBxdWVzdGlvbiAtIFRoZSBtZXNzYWdlIGRpc3BsYXllZCB0byB0aGUgdXNlci5cbiAgICogQHBhcmFtIG1pbiAtIFRoZSBtaW5pbXVtIGFsbG93ZWQgdmFsdWUgKG9wdGlvbmFsKS5cbiAgICogQHBhcmFtIG1heCAtIFRoZSBtYXhpbXVtIGFsbG93ZWQgdmFsdWUgKG9wdGlvbmFsKS5cbiAgICogQHBhcmFtIGluaXRpYWwgLSBUaGUgaW5pdGlhbCB2YWx1ZSBwcmVzZW50ZWQgdG8gdGhlIHVzZXIgKG9wdGlvbmFsKS5cbiAgICogQHJldHVybiBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbnVtYmVyIGVudGVyZWQgYnkgdGhlIHVzZXIuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgYXNrTnVtYmVyKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBxdWVzdGlvbjogc3RyaW5nLFxuICAgIG1pbj86IG51bWJlcixcbiAgICBtYXg/OiBudW1iZXIsXG4gICAgaW5pdGlhbD86IG51bWJlclxuICApOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGNvbnN0IGxvZyA9IFVzZXJJbnB1dC5sb2dnZXIuZm9yKHRoaXMuYXNrTnVtYmVyKTtcbiAgICBsb2cudmVyYm9zZShcbiAgICAgIGBBc2tpbmcgbnVtYmVyIGlucHV0OiB1bmRlZmluZWQsIHF1ZXN0aW9uOiAke3F1ZXN0aW9ufSwgbWluOiAke21pbn0sIG1heDogJHttYXh9LCBpbml0aWFsOiAke2luaXRpYWx9YFxuICAgICk7XG4gICAgY29uc3QgdXNlcklucHV0ID0gbmV3IFVzZXJJbnB1dChuYW1lKVxuICAgICAgLnNldE1lc3NhZ2UocXVlc3Rpb24pXG4gICAgICAuc2V0VHlwZShcIm51bWJlclwiKTtcblxuICAgIGlmICh0eXBlb2YgbWluID09PSBcIm51bWJlclwiKSB1c2VySW5wdXQuc2V0TWluKG1pbik7XG5cbiAgICBpZiAodHlwZW9mIG1heCA9PT0gXCJudW1iZXJcIikgdXNlcklucHV0LnNldE1heChtYXgpO1xuXG4gICAgaWYgKHR5cGVvZiBpbml0aWFsID09PSBcIm51bWJlclwiKSB1c2VySW5wdXQuc2V0SW5pdGlhbChpbml0aWFsKTtcblxuICAgIHJldHVybiAoYXdhaXQgdGhpcy5hc2sodXNlcklucHV0KSlbbmFtZV07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFza3MgdGhlIHVzZXIgZm9yIGEgdGV4dCBpbnB1dC5cbiAgICogQHN1bW1hcnkgUHJvbXB0cyB0aGUgdXNlciB0byBlbnRlciB0ZXh0LCB3aXRoIG9wdGlvbmFsIG1hc2tpbmcgYW5kIGluaXRpYWwgdmFsdWUuXG4gICAqIEBwYXJhbSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHByb21wdCwgdXNlZCBhcyB0aGUga2V5IGluIHRoZSByZXR1cm5lZCBhbnN3ZXJzIG9iamVjdC5cbiAgICogQHBhcmFtIHF1ZXN0aW9uIC0gVGhlIG1lc3NhZ2UgZGlzcGxheWVkIHRvIHRoZSB1c2VyLlxuICAgKiBAcGFyYW0gbWFzayAtIFRoZSBjaGFyYWN0ZXIgdXNlZCB0byBtYXNrIHRoZSBpbnB1dCAob3B0aW9uYWwsIGZvciBwYXNzd29yZC1saWtlIGlucHV0cykuXG4gICAqIEBwYXJhbSBpbml0aWFsIC0gVGhlIGluaXRpYWwgdmFsdWUgcHJlc2VudGVkIHRvIHRoZSB1c2VyIChvcHRpb25hbCkuXG4gICAqIEByZXR1cm4gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHRleHQgZW50ZXJlZCBieSB0aGUgdXNlci5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBhc2tUZXh0KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBxdWVzdGlvbjogc3RyaW5nLFxuICAgIG1hc2s6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZCxcbiAgICBpbml0aWFsPzogc3RyaW5nXG4gICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgbG9nID0gVXNlcklucHV0LmxvZ2dlci5mb3IodGhpcy5hc2tUZXh0KTtcbiAgICBsb2cudmVyYm9zZShcbiAgICAgIGBBc2tpbmcgdGV4dCBpbnB1dDogdW5kZWZpbmVkLCBxdWVzdGlvbjogJHtxdWVzdGlvbn0sIG1hc2s6ICR7bWFza30sIGluaXRpYWw6ICR7aW5pdGlhbH1gXG4gICAgKTtcbiAgICBjb25zdCB1c2VySW5wdXQgPSBuZXcgVXNlcklucHV0KG5hbWUpLnNldE1lc3NhZ2UocXVlc3Rpb24pO1xuXG4gICAgaWYgKG1hc2spIHVzZXJJbnB1dC5zZXRNYXNrKG1hc2spO1xuICAgIGlmICh0eXBlb2YgaW5pdGlhbCA9PT0gXCJzdHJpbmdcIikgdXNlcklucHV0LnNldEluaXRpYWwoaW5pdGlhbCk7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmFzayh1c2VySW5wdXQpKVtuYW1lXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQXNrcyB0aGUgdXNlciBmb3IgYSBjb25maXJtYXRpb24gKHllcy9ubykuXG4gICAqIEBzdW1tYXJ5IFByb21wdHMgdGhlIHVzZXIgd2l0aCBhIHllcy9ubyBxdWVzdGlvbiBhbmQgcmV0dXJucyBhIGJvb2xlYW4gcmVzdWx0LlxuICAgKiBAcGFyYW0gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9tcHQsIHVzZWQgYXMgdGhlIGtleSBpbiB0aGUgcmV0dXJuZWQgYW5zd2VycyBvYmplY3QuXG4gICAqIEBwYXJhbSBxdWVzdGlvbiAtIFRoZSBtZXNzYWdlIGRpc3BsYXllZCB0byB0aGUgdXNlci5cbiAgICogQHBhcmFtIGluaXRpYWwgLSBUaGUgaW5pdGlhbCB2YWx1ZSBwcmVzZW50ZWQgdG8gdGhlIHVzZXIgKG9wdGlvbmFsKS5cbiAgICogQHJldHVybiBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSB1c2VyJ3MgYW5zd2VyLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGFza0NvbmZpcm1hdGlvbihcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgcXVlc3Rpb246IHN0cmluZyxcbiAgICBpbml0aWFsPzogYm9vbGVhblxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBsb2cgPSBVc2VySW5wdXQubG9nZ2VyLmZvcih0aGlzLmFza0NvbmZpcm1hdGlvbik7XG4gICAgbG9nLnZlcmJvc2UoXG4gICAgICBgQXNraW5nIGNvbmZpcm1hdGlvbiBpbnB1dDogdW5kZWZpbmVkLCBxdWVzdGlvbjogJHtxdWVzdGlvbn0sIGluaXRpYWw6ICR7aW5pdGlhbH1gXG4gICAgKTtcbiAgICBjb25zdCB1c2VySW5wdXQgPSBuZXcgVXNlcklucHV0KG5hbWUpXG4gICAgICAuc2V0TWVzc2FnZShxdWVzdGlvbilcbiAgICAgIC5zZXRUeXBlKFwiY29uZmlybVwiKTtcblxuICAgIGlmICh0eXBlb2YgaW5pdGlhbCAhPT0gXCJ1bmRlZmluZWRcIikgdXNlcklucHV0LnNldEluaXRpYWwoaW5pdGlhbCk7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmFzayh1c2VySW5wdXQpKVtuYW1lXTtcbiAgfVxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlcGVhdGVkbHkgYXNrcyBmb3IgaW5wdXQgdW50aWwgYSB2YWxpZCByZXNwb25zZSBpcyBnaXZlbiBvciB0aGUgbGltaXQgaXMgcmVhY2hlZC5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2QgaW5zaXN0cyBvbiBnZXR0aW5nIGEgdmFsaWQgaW5wdXQgZnJvbSB0aGUgdXNlciwgYWxsb3dpbmcgZm9yIGEgc3BlY2lmaWVkIG51bWJlciBvZiBhdHRlbXB0cy5cbiAgICpcbiAgICogQHRlbXBsYXRlIFIgLSBUaGUgdHlwZSBvZiB0aGUgZXhwZWN0ZWQgcmVzdWx0LlxuICAgKiBAcGFyYW0gaW5wdXQgLSBUaGUgVXNlcklucHV0IGluc3RhbmNlIHRvIHVzZSBmb3IgcHJvbXB0aW5nLlxuICAgKiBAcGFyYW0gdGVzdCAtIEEgZnVuY3Rpb24gdG8gdmFsaWRhdGUgdGhlIHVzZXIncyBpbnB1dC5cbiAgICogQHBhcmFtIGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzIGFsbG93ZWQgKGRlZmF1bHQgaXMgMSkuXG4gICAqIEBwYXJhbSBkZWZhdWx0Q29uZmlybWF0aW9uXG4gICAqIEByZXR1cm4gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHZhbGlkIGlucHV0IG9yIHVuZGVmaW5lZCBpZiB0aGUgbGltaXQgaXMgcmVhY2hlZC5cbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgVSBhcyBVc2VyXG4gICAqICAgcGFydGljaXBhbnQgSSBhcyBpbnNpc3QgbWV0aG9kXG4gICAqICAgcGFydGljaXBhbnQgQSBhcyBhc2sgbWV0aG9kXG4gICAqICAgcGFydGljaXBhbnQgVCBhcyB0ZXN0IGZ1bmN0aW9uXG4gICAqICAgcGFydGljaXBhbnQgQyBhcyBhc2tDb25maXJtYXRpb24gbWV0aG9kXG4gICAqICAgbG9vcCBVbnRpbCB2YWxpZCBpbnB1dCBvciBsaW1pdCByZWFjaGVkXG4gICAqICAgICBJLT4+QTogQ2FsbCBhc2sgd2l0aCBpbnB1dFxuICAgKiAgICAgQS0+PlU6IFByb21wdCB1c2VyXG4gICAqICAgICBVLT4+QTogUHJvdmlkZSBpbnB1dFxuICAgKiAgICAgQS0+Pkk6IFJldHVybiByZXN1bHRcbiAgICogICAgIEktPj5UOiBUZXN0IHJlc3VsdFxuICAgKiAgICAgYWx0IFRlc3QgcGFzc2VzXG4gICAqICAgICAgIEktPj5DOiBBc2sgZm9yIGNvbmZpcm1hdGlvblxuICAgKiAgICAgICBDLT4+VTogQ29uZmlybSBpbnB1dFxuICAgKiAgICAgICBVLT4+QzogUHJvdmlkZSBjb25maXJtYXRpb25cbiAgICogICAgICAgQy0+Pkk6IFJldHVybiBjb25maXJtYXRpb25cbiAgICogICAgICAgYWx0IENvbmZpcm1lZFxuICAgKiAgICAgICAgIEktLT4+Q2FsbGVyOiBSZXR1cm4gdmFsaWQgcmVzdWx0XG4gICAqICAgICAgIGVsc2UgTm90IGNvbmZpcm1lZFxuICAgKiAgICAgICAgIEktPj5JOiBDb250aW51ZSBsb29wXG4gICAqICAgICAgIGVuZFxuICAgKiAgICAgZWxzZSBUZXN0IGZhaWxzXG4gICAqICAgICAgIEktPj5JOiBDb250aW51ZSBsb29wXG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICogICBJLS0+PkNhbGxlcjogUmV0dXJuIHVuZGVmaW5lZCBpZiBsaW1pdCByZWFjaGVkXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgaW5zaXN0PFI+KFxuICAgIGlucHV0OiBVc2VySW5wdXQsXG4gICAgdGVzdDogKHJlczogc3RyaW5nIHwgbnVtYmVyKSA9PiBib29sZWFuLFxuICAgIGRlZmF1bHRDb25maXJtYXRpb246IGJvb2xlYW4sXG4gICAgbGltaXQgPSAxXG4gICk6IFByb21pc2U8UiB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IGxvZyA9IFVzZXJJbnB1dC5sb2dnZXIuZm9yKHRoaXMuaW5zaXN0KTtcbiAgICBsb2cudmVyYm9zZShcbiAgICAgIGBJbnNpc3Rpbmcgb24gaW5wdXQ6ICR7aW5wdXQubmFtZX0sIHRlc3Q6ICR7dGVzdC50b1N0cmluZygpfSwgZGVmYXVsdENvbmZpcm1hdGlvbjogJHtkZWZhdWx0Q29uZmlybWF0aW9ufSwgbGltaXQ6ICR7bGltaXR9YFxuICAgICk7XG4gICAgbGV0IHJlc3VsdDogc3RyaW5nIHwgbnVtYmVyIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIGxldCBjb3VudCA9IDA7XG4gICAgbGV0IGNvbmZpcm1hdGlvbjogYm9vbGVhbjtcbiAgICB0cnkge1xuICAgICAgZG8ge1xuICAgICAgICByZXN1bHQgPSAoYXdhaXQgVXNlcklucHV0LmFzayhpbnB1dCkpW1xuICAgICAgICAgIGlucHV0Lm5hbWUgYXMga2V5b2YgQW5zd2VyczxzdHJpbmc+XG4gICAgICAgIF0gYXMgc3RyaW5nO1xuICAgICAgICBpZiAoIXRlc3QocmVzdWx0KSkge1xuICAgICAgICAgIHJlc3VsdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25maXJtYXRpb24gPSBhd2FpdCBVc2VySW5wdXQuYXNrQ29uZmlybWF0aW9uKFxuICAgICAgICAgIGAke2lucHV0Lm5hbWV9LWNvbmZpcm1gLFxuICAgICAgICAgIGBJcyB0aGUgJHtpbnB1dC50eXBlfSBjb3JyZWN0P2AsXG4gICAgICAgICAgZGVmYXVsdENvbmZpcm1hdGlvblxuICAgICAgICApO1xuICAgICAgICBpZiAoIWNvbmZpcm1hdGlvbikgcmVzdWx0ID0gdW5kZWZpbmVkO1xuICAgICAgfSB3aGlsZSAodHlwZW9mIHJlc3VsdCA9PT0gXCJ1bmRlZmluZWRcIiAmJiBsaW1pdCA+IDEgJiYgY291bnQrKyA8IGxpbWl0KTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICBsb2cuZXJyb3IoYEVycm9yIHdoaWxlIGluc2lzdGluZzogJHtlfWApO1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gXCJ1bmRlZmluZWRcIikgbG9nLmluZm8oXCJubyBzZWxlY3Rpb24uLi5cIik7XG4gICAgcmV0dXJuIHJlc3VsdCBhcyBSIHwgdW5kZWZpbmVkO1xuICB9XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVwZWF0ZWRseSBhc2tzIGZvciB0ZXh0IGlucHV0IHVudGlsIGEgdmFsaWQgcmVzcG9uc2UgaXMgZ2l2ZW4gb3IgdGhlIGxpbWl0IGlzIHJlYWNoZWQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIGluc2lzdHMgb24gZ2V0dGluZyBhIHZhbGlkIHRleHQgaW5wdXQgZnJvbSB0aGUgdXNlciwgYWxsb3dpbmcgZm9yIGEgc3BlY2lmaWVkIG51bWJlciBvZiBhdHRlbXB0cy5cbiAgICpcbiAgICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvbXB0LCB1c2VkIGFzIHRoZSBrZXkgaW4gdGhlIHJldHVybmVkIGFuc3dlcnMgb2JqZWN0LlxuICAgKiBAcGFyYW0gcXVlc3Rpb24gLSBUaGUgbWVzc2FnZSBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIuXG4gICAqIEBwYXJhbSB0ZXN0IC0gQSBmdW5jdGlvbiB0byB2YWxpZGF0ZSB0aGUgdXNlcidzIGlucHV0LlxuICAgKiBAcGFyYW0gbWFzayAtIFRoZSBjaGFyYWN0ZXIgdXNlZCB0byBtYXNrIHRoZSBpbnB1dCAob3B0aW9uYWwsIGZvciBwYXNzd29yZC1saWtlIGlucHV0cykuXG4gICAqIEBwYXJhbSBpbml0aWFsIC0gVGhlIGluaXRpYWwgdmFsdWUgcHJlc2VudGVkIHRvIHRoZSB1c2VyIChvcHRpb25hbCkuXG4gICAqIEBwYXJhbSBkZWZhdWx0Q29uZmlybWF0aW9uXG4gICAqIEBwYXJhbSBsaW1pdCAtIFRoZSBtYXhpbXVtIG51bWJlciBvZiBhdHRlbXB0cyBhbGxvd2VkIChkZWZhdWx0IGlzIC0xLCBtZWFuaW5nIHVubGltaXRlZCkuXG4gICAqIEByZXR1cm4gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHZhbGlkIGlucHV0IG9yIHVuZGVmaW5lZCBpZiB0aGUgbGltaXQgaXMgcmVhY2hlZC5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBpbnNpc3RGb3JUZXh0KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBxdWVzdGlvbjogc3RyaW5nLFxuICAgIHRlc3Q6IChyZXM6IHN0cmluZykgPT4gYm9vbGVhbixcbiAgICBtYXNrOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4gICAgaW5pdGlhbD86IHN0cmluZyxcbiAgICBkZWZhdWx0Q29uZmlybWF0aW9uID0gZmFsc2UsXG4gICAgbGltaXQgPSAtMVxuICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGxvZyA9IFVzZXJJbnB1dC5sb2dnZXIuZm9yKHRoaXMuaW5zaXN0Rm9yVGV4dCk7XG4gICAgbG9nLnZlcmJvc2UoXG4gICAgICBgSW5zaXN0aW5nIGZvciB0ZXh0IGlucHV0OiB1bmRlZmluZWQsIHF1ZXN0aW9uOiAke3F1ZXN0aW9ufSwgdGVzdDogJHt0ZXN0LnRvU3RyaW5nKCl9LCBtYXNrOiAke21hc2t9LCBpbml0aWFsOiAke2luaXRpYWx9LCBkZWZhdWx0Q29uZmlybWF0aW9uOiAke2RlZmF1bHRDb25maXJtYXRpb259LCBsaW1pdDogJHtsaW1pdH1gXG4gICAgKTtcbiAgICBjb25zdCB1c2VySW5wdXQgPSBuZXcgVXNlcklucHV0KG5hbWUpLnNldE1lc3NhZ2UocXVlc3Rpb24pO1xuXG4gICAgaWYgKG1hc2spIHVzZXJJbnB1dC5zZXRNYXNrKG1hc2spO1xuICAgIGlmICh0eXBlb2YgaW5pdGlhbCA9PT0gXCJzdHJpbmdcIikgdXNlcklucHV0LnNldEluaXRpYWwoaW5pdGlhbCk7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmluc2lzdChcbiAgICAgIHVzZXJJbnB1dCxcbiAgICAgIHRlc3QgYXMgKHJlczogc3RyaW5nIHwgbnVtYmVyKSA9PiBib29sZWFuLFxuICAgICAgZGVmYXVsdENvbmZpcm1hdGlvbixcbiAgICAgIGxpbWl0XG4gICAgKSkgYXMgc3RyaW5nO1xuICB9XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVwZWF0ZWRseSBhc2tzIGZvciBudW1iZXIgaW5wdXQgdW50aWwgYSB2YWxpZCByZXNwb25zZSBpcyBnaXZlbiBvciB0aGUgbGltaXQgaXMgcmVhY2hlZC5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2QgaW5zaXN0cyBvbiBnZXR0aW5nIGEgdmFsaWQgbnVtYmVyIGlucHV0IGZyb20gdGhlIHVzZXIsIGFsbG93aW5nIGZvciBhIHNwZWNpZmllZCBudW1iZXIgb2YgYXR0ZW1wdHMuXG4gICAqXG4gICAqIEBwYXJhbSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHByb21wdCwgdXNlZCBhcyB0aGUga2V5IGluIHRoZSByZXR1cm5lZCBhbnN3ZXJzIG9iamVjdC5cbiAgICogQHBhcmFtIHF1ZXN0aW9uIC0gVGhlIG1lc3NhZ2UgZGlzcGxheWVkIHRvIHRoZSB1c2VyLlxuICAgKiBAcGFyYW0gdGVzdCAtIEEgZnVuY3Rpb24gdG8gdmFsaWRhdGUgdGhlIHVzZXIncyBpbnB1dC5cbiAgICogQHBhcmFtIG1pbiAtIFRoZSBtaW5pbXVtIGFsbG93ZWQgdmFsdWUgKG9wdGlvbmFsKS5cbiAgICogQHBhcmFtIG1heCAtIFRoZSBtYXhpbXVtIGFsbG93ZWQgdmFsdWUgKG9wdGlvbmFsKS5cbiAgICogQHBhcmFtIGluaXRpYWwgLSBUaGUgaW5pdGlhbCB2YWx1ZSBwcmVzZW50ZWQgdG8gdGhlIHVzZXIgKG9wdGlvbmFsKS5cbiAgICogQHBhcmFtIGRlZmF1bHRDb25maXJtYXRpb25cbiAgICogQHBhcmFtIGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzIGFsbG93ZWQgKGRlZmF1bHQgaXMgLTEsIG1lYW5pbmcgdW5saW1pdGVkKS5cbiAgICogQHJldHVybiBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgdmFsaWQgaW5wdXQgb3IgdW5kZWZpbmVkIGlmIHRoZSBsaW1pdCBpcyByZWFjaGVkLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGluc2lzdEZvck51bWJlcihcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgcXVlc3Rpb246IHN0cmluZyxcbiAgICB0ZXN0OiAocmVzOiBudW1iZXIpID0+IGJvb2xlYW4sXG4gICAgbWluPzogbnVtYmVyLFxuICAgIG1heD86IG51bWJlcixcbiAgICBpbml0aWFsPzogbnVtYmVyLFxuICAgIGRlZmF1bHRDb25maXJtYXRpb24gPSBmYWxzZSxcbiAgICBsaW1pdCA9IC0xXG4gICk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3QgbG9nID0gVXNlcklucHV0LmxvZ2dlci5mb3IodGhpcy5pbnNpc3RGb3JOdW1iZXIpO1xuICAgIGxvZy52ZXJib3NlKFxuICAgICAgYEluc2lzdGluZyBmb3IgbnVtYmVyIGlucHV0OiB1bmRlZmluZWQsIHF1ZXN0aW9uOiAke3F1ZXN0aW9ufSwgdGVzdDogJHt0ZXN0LnRvU3RyaW5nKCl9LCBtaW46ICR7bWlufSwgbWF4OiAke21heH0sIGluaXRpYWw6ICR7aW5pdGlhbH0sIGRlZmF1bHRDb25maXJtYXRpb246ICR7ZGVmYXVsdENvbmZpcm1hdGlvbn0sIGxpbWl0OiAke2xpbWl0fWBcbiAgICApO1xuICAgIGNvbnN0IHVzZXJJbnB1dCA9IG5ldyBVc2VySW5wdXQobmFtZSlcbiAgICAgIC5zZXRNZXNzYWdlKHF1ZXN0aW9uKVxuICAgICAgLnNldFR5cGUoXCJudW1iZXJcIik7XG5cbiAgICBpZiAodHlwZW9mIG1pbiA9PT0gXCJudW1iZXJcIikgdXNlcklucHV0LnNldE1pbihtaW4pO1xuXG4gICAgaWYgKHR5cGVvZiBtYXggPT09IFwibnVtYmVyXCIpIHVzZXJJbnB1dC5zZXRNYXgobWF4KTtcblxuICAgIGlmICh0eXBlb2YgaW5pdGlhbCA9PT0gXCJudW1iZXJcIikgdXNlcklucHV0LnNldEluaXRpYWwoaW5pdGlhbCk7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmluc2lzdChcbiAgICAgIHVzZXJJbnB1dCxcbiAgICAgIHRlc3QgYXMgKHJlczogc3RyaW5nIHwgbnVtYmVyKSA9PiBib29sZWFuLFxuICAgICAgZGVmYXVsdENvbmZpcm1hdGlvbixcbiAgICAgIGxpbWl0XG4gICAgKSkgYXMgbnVtYmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQYXJzZXMgY29tbWFuZC1saW5lIGFyZ3VtZW50cyBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgb3B0aW9ucy5cbiAgICogQHN1bW1hcnkgVXNlcyBOb2RlLmpzJ3MgdXRpbC5wYXJzZUFyZ3MgdG8gcGFyc2UgY29tbWFuZC1saW5lIGFyZ3VtZW50cyBhbmQgcmV0dXJuIHRoZSByZXN1bHQuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBwYXJzaW5nIGFyZ3VtZW50cy5cbiAgICogQHJldHVybiBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgcGFyc2VkIGFyZ3VtZW50cy5cbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQyBhcyBDYWxsZXJcbiAgICogICBwYXJ0aWNpcGFudCBQIGFzIHBhcnNlQXJncyBtZXRob2RcbiAgICogICBwYXJ0aWNpcGFudCBVIGFzIHV0aWwucGFyc2VBcmdzXG4gICAqICAgQy0+PlA6IENhbGwgd2l0aCBvcHRpb25zXG4gICAqICAgUC0+PlA6IFByZXBhcmUgYXJncyBvYmplY3RcbiAgICogICBQLT4+VTogQ2FsbCBwYXJzZUFyZ3Mgd2l0aCBwcmVwYXJlZCBhcmdzXG4gICAqICAgVS0+PlA6IFJldHVybiBwYXJzZWQgcmVzdWx0XG4gICAqICAgUC0tPj5DOiBSZXR1cm4gUGFyc2VBcmdzUmVzdWx0XG4gICAqL1xuICBzdGF0aWMgcGFyc2VBcmdzKG9wdGlvbnM6IFBhcnNlQXJnc09wdGlvbnNDb25maWcpOiBQYXJzZUFyZ3NSZXN1bHQge1xuICAgIGNvbnN0IGxvZyA9IFVzZXJJbnB1dC5sb2dnZXIuZm9yKHRoaXMucGFyc2VBcmdzKTtcbiAgICBjb25zdCBhcmdzOiBQYXJzZUFyZ3NDb25maWcgPSB7XG4gICAgICBhcmdzOiBwcm9jZXNzLmFyZ3Yuc2xpY2UoMiksXG4gICAgICBvcHRpb25zOiBvcHRpb25zLFxuICAgIH07XG4gICAgbG9nLmRlYnVnKGBQYXJzaW5nIGFyZ3VtZW50czogJHtKU09OLnN0cmluZ2lmeShhcmdzLCBudWxsLCAyKX1gKTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHBhcnNlQXJncyhhcmdzKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgbG9nLmRlYnVnKFxuICAgICAgICBgRXJyb3Igd2hpbGUgcGFyc2luZyBhcmd1bWVudHM6XFxuJHtKU09OLnN0cmluZ2lmeShhcmdzLCBudWxsLCAyKX1cXG4gfCBvcHRpb25zXFxuJHtKU09OLnN0cmluZ2lmeShvcHRpb25zLCBudWxsLCAyKX1cXG4gfCAke2Vycm9yfWBcbiAgICAgICk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIHdoaWxlIHBhcnNpbmcgYXJndW1lbnRzOiAke2Vycm9yfWApO1xuICAgIH1cbiAgfVxufVxuIl19