aws-cdk 2.175.0 → 2.176.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CONTRIBUTING.md +4 -4
  2. package/build-info.json +2 -2
  3. package/db.json.gz +0 -0
  4. package/lib/api/aws-auth/credential-plugins.js +5 -5
  5. package/lib/api/aws-auth/sdk-provider.js +3 -2
  6. package/lib/api/aws-auth/sdk.js +3 -2
  7. package/lib/api/cxapp/cloud-assembly.js +4 -4
  8. package/lib/api/deploy-stack.js +11 -10
  9. package/lib/api/deployments.js +4 -4
  10. package/lib/api/environment-access.js +3 -2
  11. package/lib/api/environment-resources.js +3 -2
  12. package/lib/api/garbage-collection/garbage-collector.js +9 -9
  13. package/lib/api/garbage-collection/progress-printer.js +3 -3
  14. package/lib/api/hotswap-deployments.js +11 -10
  15. package/lib/api/logs/find-cloudwatch-logs.js +3 -2
  16. package/lib/api/logs/logs-monitor.js +3 -3
  17. package/lib/api/nested-stack-helpers.js +3 -2
  18. package/lib/api/plugin/plugin.js +1 -1
  19. package/lib/api/util/cloudformation/stack-activity-monitor.d.ts +4 -4
  20. package/lib/api/util/cloudformation/stack-activity-monitor.js +9 -9
  21. package/lib/api/util/cloudformation/stack-event-poller.js +3 -2
  22. package/lib/api/util/cloudformation.js +3 -3
  23. package/lib/cdk-toolkit.d.ts +0 -1
  24. package/lib/cdk-toolkit.js +32 -76
  25. package/lib/cli.js +12 -7
  26. package/lib/commands/context.js +20 -20
  27. package/lib/commands/docs.js +2 -2
  28. package/lib/commands/doctor.js +9 -9
  29. package/lib/commands/migrate.js +16 -16
  30. package/lib/config.d.ts +6 -3
  31. package/lib/config.js +10 -7
  32. package/lib/context-providers/ami.js +2 -2
  33. package/lib/context-providers/index.js +3 -2
  34. package/lib/convert-to-user-input.d.ts +3 -0
  35. package/lib/convert-to-user-input.js +431 -0
  36. package/lib/diff.js +3 -3
  37. package/lib/import.js +6 -6
  38. package/lib/index.js +50 -35
  39. package/lib/init-hooks.js +3 -2
  40. package/lib/init-templates/.init-version.json +1 -1
  41. package/lib/init-templates/.recommended-feature-flags.json +2 -1
  42. package/lib/init-templates/app/csharp/src/%name.PascalCased%/%name.PascalCased%.template.csproj +1 -1
  43. package/lib/init-templates/app/fsharp/src/%name.PascalCased%/%name.PascalCased%.template.fsproj +1 -1
  44. package/lib/init-templates/sample-app/csharp/src/%name.PascalCased%/%name.PascalCased%.template.csproj +1 -1
  45. package/lib/init-templates/sample-app/fsharp/src/%name.PascalCased%/%name.PascalCased%.template.fsproj +1 -1
  46. package/lib/init.d.ts +1 -1
  47. package/lib/init.js +20 -19
  48. package/lib/logging.d.ts +112 -48
  49. package/lib/logging.js +176 -133
  50. package/lib/notices.js +13 -12
  51. package/lib/parse-command-line-arguments.js +2 -2
  52. package/lib/settings.d.ts +2 -0
  53. package/lib/settings.js +3 -1
  54. package/lib/toolkit/cli-io-host.d.ts +56 -25
  55. package/lib/toolkit/cli-io-host.js +49 -22
  56. package/lib/toolkit/error.js +2 -2
  57. package/lib/{cli-arguments.d.ts → user-input.d.ts} +8 -8
  58. package/lib/user-input.js +3 -0
  59. package/lib/util/archive.js +3 -2
  60. package/lib/util/asset-publishing.js +3 -3
  61. package/lib/util/error.d.ts +9 -0
  62. package/lib/util/error.js +22 -0
  63. package/lib/version.js +2 -2
  64. package/package.json +12 -11
  65. package/scripts/user-input-gen +2 -0
  66. package/scripts/user-input-gen.js +17 -0
  67. package/test/api/exec.test.js +3 -3
  68. package/test/api/fake-sts.js +3 -2
  69. package/test/api/logs/logging.test.js +269 -0
  70. package/test/api/sdk-provider.test.js +3 -3
  71. package/test/api/stack-activity-monitor.test.js +16 -16
  72. package/test/api/util/error.test.d.ts +1 -0
  73. package/test/api/util/error.test.js +26 -0
  74. package/test/cdk-toolkit.test.js +1 -46
  75. package/test/cli-arguments.test.js +126 -81
  76. package/test/cli.test.js +8 -8
  77. package/test/init.test.js +5 -5
  78. package/test/jest-bufferedconsole.d.ts +14 -0
  79. package/test/jest-bufferedconsole.js +72 -0
  80. package/test/notices.test.js +14 -14
  81. package/test/toolkit/cli-io-host.test.js +93 -188
  82. package/test/util/silent.js +2 -2
  83. package/test/version.test.js +5 -5
  84. package/lib/cli-arguments.js +0 -3
  85. package/lib/convert-to-cli-args.d.ts +0 -2
  86. package/lib/convert-to-cli-args.js +0 -234
  87. package/scripts/cli-args-gen +0 -2
  88. package/scripts/cli-args-gen.js +0 -16
  89. package/test/api/logs/cli-logging.test.js +0 -135
  90. /package/scripts/{cli-args-gen.d.ts → user-input-gen.d.ts} +0 -0
  91. /package/test/api/logs/{cli-logging.test.d.ts → logging.test.d.ts} +0 -0
package/lib/logging.js CHANGED
@@ -1,67 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.highlight = exports.success = exports.trace = exports.debug = exports.data = exports.print = exports.info = exports.warning = exports.error = exports.LogLevel = void 0;
4
- exports.setLogLevel = setLogLevel;
3
+ exports.highlight = exports.success = exports.trace = exports.debug = exports.data = exports.info = exports.warning = exports.error = void 0;
4
+ exports.setIoMessageThreshold = setIoMessageThreshold;
5
5
  exports.setCI = setCI;
6
6
  exports.withCorkedLogging = withCorkedLogging;
7
- exports.log = log;
8
- exports.prefix = prefix;
9
7
  const util = require("util");
10
8
  const chalk = require("chalk");
11
- /**
12
- * Available log levels in order of increasing verbosity.
13
- */
14
- var LogLevel;
15
- (function (LogLevel) {
16
- LogLevel["ERROR"] = "error";
17
- LogLevel["WARN"] = "warn";
18
- LogLevel["INFO"] = "info";
19
- LogLevel["DEBUG"] = "debug";
20
- LogLevel["TRACE"] = "trace";
21
- })(LogLevel || (exports.LogLevel = LogLevel = {}));
22
- const { stdout, stderr } = process;
9
+ const cli_io_host_1 = require("./toolkit/cli-io-host");
23
10
  // Corking mechanism
24
11
  let CORK_COUNTER = 0;
25
12
  const logBuffer = [];
26
- // Style mappings
27
- const styleMap = {
28
- [LogLevel.ERROR]: chalk.red,
29
- [LogLevel.WARN]: chalk.yellow,
30
- [LogLevel.INFO]: chalk.white,
31
- [LogLevel.DEBUG]: chalk.gray,
32
- [LogLevel.TRACE]: chalk.gray,
33
- };
34
- // Stream selection
35
- let CI = false;
36
- /**
37
- * Determines which output stream to use based on log level and configuration.
38
- * @param level - The log level to determine stream for
39
- * @param forceStdout - Whether to force stdout regardless of level
40
- * @returns The appropriate Writable stream
41
- */
42
- const getStream = (level, forceStdout) => {
43
- // Special case - data() calls should always go to stdout
44
- if (forceStdout) {
45
- return stdout;
46
- }
47
- if (level === LogLevel.ERROR)
48
- return stderr;
49
- return CI ? stdout : stderr;
50
- };
51
13
  const levelPriority = {
52
- [LogLevel.ERROR]: 0,
53
- [LogLevel.WARN]: 1,
54
- [LogLevel.INFO]: 2,
55
- [LogLevel.DEBUG]: 3,
56
- [LogLevel.TRACE]: 4,
14
+ error: 0,
15
+ warn: 1,
16
+ info: 2,
17
+ debug: 3,
18
+ trace: 4,
57
19
  };
58
- let currentLogLevel = LogLevel.INFO;
20
+ let currentIoMessageThreshold = 'info';
59
21
  /**
60
- * Sets the current log level. Messages with a lower priority level will be filtered out.
61
- * @param level - The new log level to set
22
+ * Sets the current threshold. Messages with a lower priority level will be ignored.
23
+ * @param level The new log level threshold
62
24
  */
63
- function setLogLevel(level) {
64
- currentLogLevel = level;
25
+ function setIoMessageThreshold(level) {
26
+ currentIoMessageThreshold = level;
65
27
  }
66
28
  /**
67
29
  * Sets whether the logger is running in CI mode.
@@ -69,20 +31,11 @@ function setLogLevel(level) {
69
31
  * @param newCI - Whether CI mode should be enabled
70
32
  */
71
33
  function setCI(newCI) {
72
- CI = newCI;
73
- }
74
- /**
75
- * Formats a date object into a timestamp string (HH:MM:SS).
76
- * @param d - Date object to format
77
- * @returns Formatted time string
78
- */
79
- function formatTime(d) {
80
- const pad = (n) => n.toString().padStart(2, '0');
81
- return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
34
+ cli_io_host_1.CliIoHost.ci = newCI;
82
35
  }
83
36
  /**
84
37
  * Executes a block of code with corked logging. All log messages during execution
85
- * are buffered and only written after the block completes.
38
+ * are buffered and only written when all nested cork blocks complete (when CORK_COUNTER reaches 0).
86
39
  * @param block - Async function to execute with corked logging
87
40
  * @returns Promise that resolves with the block's return value
88
41
  */
@@ -94,93 +47,183 @@ async function withCorkedLogging(block) {
94
47
  finally {
95
48
  CORK_COUNTER--;
96
49
  if (CORK_COUNTER === 0) {
97
- logBuffer.forEach(([stream, str]) => stream.write(str + '\n'));
50
+ // Process each buffered message through notify
51
+ for (const ioMessage of logBuffer) {
52
+ void cli_io_host_1.CliIoHost.getIoHost().notify(ioMessage);
53
+ }
98
54
  logBuffer.splice(0);
99
55
  }
100
56
  }
101
57
  }
102
- function log(levelOrEntry, fmt, ...args) {
103
- // Normalize input
104
- const entry = typeof levelOrEntry === 'string'
105
- ? { level: levelOrEntry, message: util.format(fmt, ...args) }
106
- : levelOrEntry;
107
- // Check if we should log this level
108
- if (levelPriority[entry.level] > levelPriority[currentLogLevel]) {
58
+ /**
59
+ * Internal core logging function that writes messages through the CLI IO host.
60
+ * @param options Configuration options for the log message. See {@link LogOptions}
61
+ */
62
+ function log(options) {
63
+ if (levelPriority[options.level] > levelPriority[currentIoMessageThreshold]) {
109
64
  return;
110
65
  }
111
- // Format the message
112
- let finalMessage = entry.message;
113
- // Add timestamp first if requested
114
- if (entry.timestamp) {
115
- finalMessage = `[${formatTime(new Date())}] ${finalMessage}`;
116
- }
117
- // Add prefix AFTER timestamp
118
- if (entry.prefix) {
119
- finalMessage = `${entry.prefix} ${finalMessage}`;
120
- }
121
- // Apply custom style if provided, otherwise use level-based style
122
- const style = entry.style || styleMap[entry.level];
123
- finalMessage = style(finalMessage);
124
- // Get appropriate stream - pass through forceStdout flag
125
- const stream = getStream(entry.level, entry.forceStdout);
126
- // Handle corking
66
+ const ioMessage = {
67
+ level: options.level,
68
+ message: options.message,
69
+ forceStdout: options.forceStdout,
70
+ time: new Date(),
71
+ action: cli_io_host_1.CliIoHost.currentAction ?? 'none',
72
+ code: options.code,
73
+ };
127
74
  if (CORK_COUNTER > 0) {
128
- logBuffer.push([stream, finalMessage]);
75
+ logBuffer.push(ioMessage);
129
76
  return;
130
77
  }
131
- // Write to stream
132
- stream.write(finalMessage + '\n');
78
+ void cli_io_host_1.CliIoHost.getIoHost().notify(ioMessage);
79
+ }
80
+ /**
81
+ * Internal helper that processes log inputs into a consistent format.
82
+ * Handles string interpolation, format strings, and object parameter styles.
83
+ * Applies optional styling and prepares the final message for logging.
84
+ */
85
+ function formatMessageAndLog(level, forceStdout, input, style, ...args) {
86
+ // Extract message and code from input, using new default code format
87
+ const { message, code = getDefaultCode(level) } = typeof input === 'object' ? input : { message: input };
88
+ // Format message if args are provided
89
+ const formattedMessage = args.length > 0
90
+ ? util.format(message, ...args)
91
+ : message;
92
+ // Apply style if provided
93
+ const finalMessage = style ? style(formattedMessage) : formattedMessage;
94
+ log({
95
+ level,
96
+ message: finalMessage,
97
+ code,
98
+ forceStdout,
99
+ });
100
+ }
101
+ function getDefaultCode(level, category = 'TOOLKIT') {
102
+ const levelIndicator = level === 'error' ? 'E' :
103
+ level === 'warn' ? 'W' :
104
+ 'I';
105
+ return `CDK_${category}_${levelIndicator}0000`;
133
106
  }
134
- // Convenience logging methods
135
- const error = (fmt, ...args) => log(LogLevel.ERROR, fmt, ...args);
107
+ // Exported logging functions. If any additional logging functionality is required, it should be added as
108
+ // a new logging function here.
109
+ /**
110
+ * Logs an error level message.
111
+ *
112
+ * Can be used in multiple ways:
113
+ * ```ts
114
+ * error(`operation failed: ${e}`) // infers default error code `CDK_TOOLKIT_E000`
115
+ * error('operation failed: %s', e) // infers default error code `CDK_TOOLKIT_E000`
116
+ * error({ message: 'operation failed', code: 'CDK_SDK_E001' }) // specifies error code `CDK_SDK_E001`
117
+ * error({ message: 'operation failed: %s', code: 'CDK_SDK_E001' }, e) // specifies error code `CDK_SDK_E001`
118
+ * ```
119
+ */
120
+ const error = (input, ...args) => {
121
+ return formatMessageAndLog('error', false, input, undefined, ...args);
122
+ };
136
123
  exports.error = error;
137
- const warning = (fmt, ...args) => log(LogLevel.WARN, fmt, ...args);
124
+ /**
125
+ * Logs an warning level message.
126
+ *
127
+ * Can be used in multiple ways:
128
+ * ```ts
129
+ * warning(`deprected feature: ${message}`) // infers default warning code `CDK_TOOLKIT_W000`
130
+ * warning('deprected feature: %s', message) // infers default warning code `CDK_TOOLKIT_W000`
131
+ * warning({ message: 'deprected feature', code: 'CDK_SDK_W001' }) // specifies warning code `CDK_SDK_W001`
132
+ * warning({ message: 'deprected feature: %s', code: 'CDK_SDK_W001' }, message) // specifies warning code `CDK_SDK_W001`
133
+ * ```
134
+ */
135
+ const warning = (input, ...args) => {
136
+ return formatMessageAndLog('warn', false, input, undefined, ...args);
137
+ };
138
138
  exports.warning = warning;
139
- const info = (fmt, ...args) => log(LogLevel.INFO, fmt, ...args);
139
+ /**
140
+ * Logs an info level message.
141
+ *
142
+ * Can be used in multiple ways:
143
+ * ```ts
144
+ * info(`processing: ${message}`) // infers default info code `CDK_TOOLKIT_I000`
145
+ * info('processing: %s', message) // infers default info code `CDK_TOOLKIT_I000`
146
+ * info({ message: 'processing', code: 'CDK_TOOLKIT_I001' }) // specifies info code `CDK_TOOLKIT_I001`
147
+ * info({ message: 'processing: %s', code: 'CDK_TOOLKIT_I001' }, message) // specifies info code `CDK_TOOLKIT_I001`
148
+ * ```
149
+ */
150
+ const info = (input, ...args) => {
151
+ return formatMessageAndLog('info', false, input, undefined, ...args);
152
+ };
140
153
  exports.info = info;
141
- const print = (fmt, ...args) => log(LogLevel.INFO, fmt, ...args);
142
- exports.print = print;
143
- const data = (fmt, ...args) => log({
144
- level: LogLevel.INFO,
145
- message: util.format(fmt, ...args),
146
- forceStdout: true,
147
- });
154
+ /**
155
+ * Logs an info level message to stdout.
156
+ *
157
+ * Can be used in multiple ways:
158
+ * ```ts
159
+ * data(`${JSON.stringify(stats)}`) // infers default info code `CDK_TOOLKIT_I000`
160
+ * data('{"count": %d}', count) // infers default info code `CDK_TOOLKIT_I000`
161
+ * data({ message: 'stats: %j', code: 'CDK_DATA_I001' }) // specifies info code `CDK_DATA_I001`
162
+ * data({ message: 'stats: %j', code: 'CDK_DATA_I001' }, stats) // specifies info code `CDK_DATA_I001`
163
+ * ```
164
+ */
165
+ const data = (input, ...args) => {
166
+ return formatMessageAndLog('info', true, input, undefined, ...args);
167
+ };
148
168
  exports.data = data;
149
- const debug = (fmt, ...args) => log({
150
- level: LogLevel.DEBUG,
151
- message: util.format(fmt, ...args),
152
- timestamp: true,
153
- });
169
+ /**
170
+ * Logs a debug level message.
171
+ *
172
+ * Can be used in multiple ways:
173
+ * ```ts
174
+ * debug(`state: ${JSON.stringify(state)}`) // infers default info code `CDK_TOOLKIT_I000`
175
+ * debug('cache hit ratio: %d%%', ratio) // infers default info code `CDK_TOOLKIT_I000`
176
+ * debug({ message: 'state update', code: 'CDK_TOOLKIT_I001' }) // specifies info code `CDK_TOOLKIT_I001`
177
+ * debug({ message: 'ratio: %d%%', code: 'CDK_TOOLKIT_I001' }, ratio) // specifies info code `CDK_TOOLKIT_I001`
178
+ * ```
179
+ */
180
+ const debug = (input, ...args) => {
181
+ return formatMessageAndLog('debug', false, input, undefined, ...args);
182
+ };
154
183
  exports.debug = debug;
155
- const trace = (fmt, ...args) => log({
156
- level: LogLevel.TRACE,
157
- message: util.format(fmt, ...args),
158
- timestamp: true,
159
- });
184
+ /**
185
+ * Logs a trace level message.
186
+ *
187
+ * Can be used in multiple ways:
188
+ * ```ts
189
+ * trace(`entered ${name} with ${args}`) // infers default info code `CDK_TOOLKIT_I000`
190
+ * trace('method: %s, args: %j', name, args) // infers default info code `CDK_TOOLKIT_I000`
191
+ * trace({ message: 'entered', code: 'CDK_TOOLKIT_I001' }) // specifies info code `CDK_TOOLKIT_I001`
192
+ * trace({ message: 'method: %s', code: 'CDK_TOOLKIT_I001' }, name) // specifies info code `CDK_TOOLKIT_I001`
193
+ * ```
194
+ */
195
+ const trace = (input, ...args) => {
196
+ return formatMessageAndLog('trace', false, input, undefined, ...args);
197
+ };
160
198
  exports.trace = trace;
161
- const success = (fmt, ...args) => log({
162
- level: LogLevel.INFO,
163
- message: util.format(fmt, ...args),
164
- style: chalk.green,
165
- });
199
+ /**
200
+ * Logs an info level success message in green text.
201
+ *
202
+ * Can be used in multiple ways:
203
+ * ```ts
204
+ * success(`deployment completed: ${name}`) // infers default info code `CDK_TOOLKIT_I000`
205
+ * success('processed %d items', count) // infers default info code `CDK_TOOLKIT_I000`
206
+ * success({ message: 'completed', code: 'CDK_TOOLKIT_I001' }) // specifies info code `CDK_TOOLKIT_I001`
207
+ * success({ message: 'items: %d', code: 'CDK_TOOLKIT_I001' }, count) // specifies info code `CDK_TOOLKIT_I001`
208
+ * ```
209
+ */
210
+ const success = (input, ...args) => {
211
+ return formatMessageAndLog('info', false, input, chalk.green, ...args);
212
+ };
166
213
  exports.success = success;
167
- const highlight = (fmt, ...args) => log({
168
- level: LogLevel.INFO,
169
- message: util.format(fmt, ...args),
170
- style: chalk.bold,
171
- });
172
- exports.highlight = highlight;
173
214
  /**
174
- * Creates a logging function that prepends a prefix to all messages.
175
- * @param prefixString - String to prepend to all messages
176
- * @param level - Log level to use (defaults to INFO)
177
- * @returns Logging function that accepts format string and arguments
215
+ * Logs an info level message in bold text.
216
+ *
217
+ * Can be used in multiple ways:
218
+ * ```ts
219
+ * highlight(`important: ${msg}`) // infers default info code `CDK_TOOLKIT_I000`
220
+ * highlight('attention required: %s', reason) // infers default info code `CDK_TOOLKIT_I000`
221
+ * highlight({ message: 'notice', code: 'CDK_TOOLKIT_I001' }) // specifies info code `CDK_TOOLKIT_I001`
222
+ * highlight({ message: 'notice: %s', code: 'CDK_TOOLKIT_I001' }, msg) // specifies info code `CDK_TOOLKIT_I001`
223
+ * ```
178
224
  */
179
- function prefix(prefixString, level = LogLevel.INFO) {
180
- return (fmt, ...args) => log({
181
- level,
182
- message: util.format(fmt, ...args),
183
- prefix: prefixString,
184
- });
185
- }
186
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxvZ2dpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBMEVBLGtDQUVDO0FBT0Qsc0JBRUM7QUFrQkQsOENBV0M7QUFVRCxrQkF1Q0M7QUEwQ0Qsd0JBTUM7QUFsTkQsNkJBQTZCO0FBQzdCLCtCQUErQjtBQUUvQjs7R0FFRztBQUNILElBQVksUUFNWDtBQU5ELFdBQVksUUFBUTtJQUNsQiwyQkFBZSxDQUFBO0lBQ2YseUJBQWEsQ0FBQTtJQUNiLHlCQUFhLENBQUE7SUFDYiwyQkFBZSxDQUFBO0lBQ2YsMkJBQWUsQ0FBQTtBQUNqQixDQUFDLEVBTlcsUUFBUSx3QkFBUixRQUFRLFFBTW5CO0FBY0QsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUM7QUFFbkMsb0JBQW9CO0FBQ3BCLElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQztBQUNyQixNQUFNLFNBQVMsR0FBeUIsRUFBRSxDQUFDO0FBRTNDLGlCQUFpQjtBQUNqQixNQUFNLFFBQVEsR0FBOEM7SUFDMUQsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLEdBQUc7SUFDM0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLE1BQU07SUFDN0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLEtBQUs7SUFDNUIsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLElBQUk7SUFDNUIsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLElBQUk7Q0FDN0IsQ0FBQztBQUVGLG1CQUFtQjtBQUNuQixJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUM7QUFFZjs7Ozs7R0FLRztBQUNILE1BQU0sU0FBUyxHQUFHLENBQUMsS0FBZSxFQUFFLFdBQXFCLEVBQVksRUFBRTtJQUNyRSx5REFBeUQ7SUFDekQs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RUksTUFBTSxPQUFPLEdBQUcsQ0FBQyxHQUFXLEVBQUUsR0FBRyxJQUFlLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQztJQUM5RCxLQUFLLEVBQUUsUUFBUSxDQUFDLElBQUk7SUFDcEIsT0FBTyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0lBQ2xDLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSztDQUNuQixDQUFDLENBQUM7QUFKVSxRQUFBLE9BQU8sV0FJakI7QUFFSSxNQUFNLFNBQVMsR0FBRyxDQUFDLEdBQVcsRUFBRSxHQUFHLElBQWUsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDO0lBQ2hFLEtBQUssRUFBRSxRQUFRLENBQUMsSUFBSTtJQUNwQixPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7SUFDbEMsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJO0NBQ2xCLENBQUMsQ0FBQztBQUpVLFFBQUEsU0FBUyxhQUluQjtBQUVIOzs7OztHQUtHO0FBQ0gsU0FBZ0IsTUFBTSxDQUFDLFlBQW9CLEVBQUUsUUFBa0IsUUFBUSxDQUFDLElBQUk7SUFDMUUsT0FBTyxDQUFDLEdBQVcsRUFBRSxHQUFHLElBQWUsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDO1FBQzlDLEtBQUs7UUFDTCxPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFDbEMsTUFBTSxFQUFFLFlBQVk7S0FDckIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFdyaXRhYmxlIH0gZnJvbSAnc3RyZWFtJztcbmltcG9ydCAqIGFzIHV0aWwgZnJvbSAndXRpbCc7XG5pbXBvcnQgKiBhcyBjaGFsayBmcm9tICdjaGFsayc7XG5cbi8qKlxuICogQXZhaWxhYmxlIGxvZyBsZXZlbHMgaW4gb3JkZXIgb2YgaW5jcmVhc2luZyB2ZXJib3NpdHkuXG4gKi9cbmV4cG9ydCBlbnVtIExvZ0xldmVsIHtcbiAgRVJST1IgPSAnZXJyb3InLFxuICBXQVJOID0gJ3dhcm4nLFxuICBJTkZPID0gJ2luZm8nLFxuICBERUJVRyA9ICdkZWJ1ZycsXG4gIFRSQUNFID0gJ3RyYWNlJyxcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIGEgbG9nIGVudHJ5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExvZ0VudHJ5IHtcbiAgbGV2ZWw6IExvZ0xldmVsO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIHRpbWVzdGFtcD86IGJvb2xlYW47XG4gIHByZWZpeD86IHN0cmluZztcbiAgc3R5bGU/OiAoKHN0cjogc3RyaW5nKSA9PiBzdHJpbmcpO1xuICBmb3JjZVN0ZG91dD86IGJvb2xlYW47XG59XG5cbmNvbnN0IHsgc3Rkb3V0LCBzdGRlcnIgfSA9IHByb2Nlc3M7XG5cbi8vIENvcmtpbmcgbWVjaGFuaXNtXG5sZXQgQ09SS19DT1VOVEVSID0gMDtcbmNvbnN0IGxvZ0J1ZmZlcjogW1dyaXRhYmxlLCBzdHJpbmddW10gPSBbXTtcblxuLy8gU3R5bGUgbWFwcGluZ3NcbmNvbnN0IHN0eWxlTWFwOiBSZWNvcmQ8TG9nTGV2ZWwsIChzdHI6IHN0cmluZykgPT4gc3RyaW5nPiA9IHtcbiAgW0xvZ0xldmVsLkVSUk9SXTogY2hhbGsucmVkLFxuICBbTG9nTGV2ZWwuV0FSTl06IGNoYWxrLnllbGxvdyxcbiAgW0xvZ0xldmVsLklORk9dOiBjaGFsay53aGl0ZSxcbiAgW0xvZ0xldmVsLkRFQlVHXTogY2hhbGsuZ3JheSxcbiAgW0xvZ0xldmVsLlRSQUNFXTogY2hhbGsuZ3JheSxcbn07XG5cbi8vIFN0cmVhbSBzZWxlY3Rpb25cbmxldCBDSSA9IGZhbHNlO1xuXG4vKipcbiAqIERldGVybWluZXMgd2hpY2ggb3V0cHV0IHN0cmVhbSB0byB1c2UgYmFzZWQgb24gbG9nIGxldmVsIGFuZCBjb25maWd1cmF0aW9uLlxuICogQHBhcmFtIGxldmVsIC0gVGhlIGxvZyBsZXZlbCB0byBkZXRlcm1pbmUgc3RyZWFtIGZvclxuICogQHBhcmFtIGZvcmNlU3Rkb3V0IC0gV2hldGhlciB0byBmb3JjZSBzdGRvdXQgcmVnYXJkbGVzcyBvZiBsZXZlbFxuICogQHJldHVybnMgVGhlIGFwcHJvcHJpYXRlIFdyaXRhYmxlIHN0cmVhbVxuICovXG5jb25zdCBnZXRTdHJlYW0gPSAobGV2ZWw6IExvZ0xldmVsLCBmb3JjZVN0ZG91dD86IGJvb2xlYW4pOiBXcml0YWJsZSA9PiB7XG4gIC8vIFNwZWNpYWwgY2FzZSAtIGRhdGEoKSBjYWxscyBzaG91bGQgYWx3YXlzIGdvIHRvIHN0ZG91dFxuICBpZiAoZm9yY2VTdGRvdXQpIHtcbiAgICByZXR1cm4gc3Rkb3V0O1xuICB9XG4gIGlmIChsZXZlbCA9PT0gTG9nTGV2ZWwuRVJST1IpIHJldHVybiBzdGRlcnI7XG4gIHJldHVybiBDSSA/IHN0ZG91dCA6IHN0ZGVycjtcbn07XG5cbmNvbnN0IGxldmVsUHJpb3JpdHk6IFJlY29yZDxMb2dMZXZlbCwgbnVtYmVyPiA9IHtcbiAgW0xvZ0xldmVsLkVSUk9SXTogMCxcbiAgW0xvZ0xldmVsLldBUk5dOiAxLFxuICBbTG9nTGV2ZWwuSU5GT106IDIsXG4gIFtMb2dMZXZlbC5ERUJVR106IDMsXG4gIFtMb2dMZXZlbC5UUkFDRV06IDQsXG59O1xuXG5sZXQgY3VycmVudExvZ0xldmVsOiBMb2dMZXZlbCA9IExvZ0xldmVsLklORk87XG5cbi8qKlxuICogU2V0cyB0aGUgY3VycmVudCBsb2cgbGV2ZWwuIE1lc3NhZ2VzIHdpdGggYSBsb3dlciBwcmlvcml0eSBsZXZlbCB3aWxsIGJlIGZpbHRlcmVkIG91dC5cbiAqIEBwYXJhbSBsZXZlbCAtIFRoZSBuZXcgbG9nIGxldmVsIHRvIHNldFxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0TG9nTGV2ZWwobGV2ZWw6IExvZ0xldmVsKSB7XG4gIGN1cnJlbnRMb2dMZXZlbCA9IGxldmVsO1xufVxuXG4vKipcbiAqIFNldHMgd2hldGhlciB0aGUgbG9nZ2VyIGlzIHJ1bm5pbmcgaW4gQ0kgbW9kZS5cbiAqIEluIENJIG1vZGUsIGFsbCBub24tZXJyb3Igb3V0cHV0IGdvZXMgdG8gc3Rkb3V0IGluc3RlYWQgb2Ygc3RkZXJyLlxuICogQHBhcmFtIG5ld0NJIC0gV2hldGhlciBDSSBtb2RlIHNob3VsZCBiZSBlbmFibGVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRDSShuZXdDSTogYm9vbGVhbikge1xuICBDSSA9IG5ld0NJO1xufVxuXG4vKipcbiAqIEZvcm1hdHMgYSBkYXRlIG9iamVjdCBpbnRvIGEgdGltZXN0YW1wIHN0cmluZyAoSEg6TU06U1MpLlxuICogQHBhcmFtIGQgLSBEYXRlIG9iamVjdCB0byBmb3JtYXRcbiAqIEByZXR1cm5zIEZvcm1hdHRlZCB0aW1lIHN0cmluZ1xuICovXG5mdW5jdGlvbiBmb3JtYXRUaW1lKGQ6IERhdGUpOiBzdHJpbmcge1xuICBjb25zdCBwYWQgPSAobjogbnVtYmVyKTogc3RyaW5nID0+IG4udG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpO1xuICByZXR1cm4gYCR7cGFkKGQuZ2V0SG91cnMoKSl9OiR7cGFkKGQuZ2V0TWludXRlcygpKX06JHtwYWQoZC5nZXRTZWNvbmRzKCkpfWA7XG59XG5cbi8qKlxuICogRXhlY3V0ZXMgYSBibG9jayBvZiBjb2RlIHdpdGggY29ya2VkIGxvZ2dpbmcuIEFsbCBsb2cgbWVzc2FnZXMgZHVyaW5nIGV4ZWN1dGlvblxuICogYXJlIGJ1ZmZlcmVkIGFuZCBvbmx5IHdyaXR0ZW4gYWZ0ZXIgdGhlIGJsb2NrIGNvbXBsZXRlcy5cbiAqIEBwYXJhbSBibG9jayAtIEFzeW5jIGZ1bmN0aW9uIHRvIGV4ZWN1dGUgd2l0aCBjb3JrZWQgbG9nZ2luZ1xuICogQHJldHVybnMgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGJsb2NrJ3MgcmV0dXJuIHZhbHVlXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3aXRoQ29ya2VkTG9nZ2luZzxUPihibG9jazogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICBDT1JLX0NPVU5URVIrKztcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgYmxvY2soKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBDT1JLX0NPVU5URVItLTtcbiAgICBpZiAoQ09SS19DT1VOVEVSID09PSAwKSB7XG4gICAgICBsb2dCdWZmZXIuZm9yRWFjaCgoW3N0cmVhbSwgc3RyXSkgPT4gc3RyZWFtLndyaXRlKHN0ciArICdcXG4nKSk7XG4gICAgICBsb2dCdWZmZXIuc3BsaWNlKDApO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIENvcmUgbG9nZ2luZyBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgYWxsIGxvZyBvdXRwdXQuXG4gKiBAcGFyYW0gZW50cnkgLSBMb2dFbnRyeSBvYmplY3Qgb3IgbG9nIGxldmVsXG4gKiBAcGFyYW0gZm10IC0gRm9ybWF0IHN0cmluZyAod2hlbiB1c2luZyB3aXRoIGxvZyBsZXZlbClcbiAqIEBwYXJhbSBhcmdzIC0gRm9ybWF0IGFyZ3VtZW50cyAod2hlbiB1c2luZyB3aXRoIGxvZyBsZXZlbClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZyhlbnRyeTogTG9nRW50cnkpOiB2b2lkO1xuZXhwb3J0IGZ1bmN0aW9uIGxvZyhsZXZlbDogTG9nTGV2ZWwsIGZtdDogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkO1xuZXhwb3J0IGZ1bmN0aW9uIGxvZyhsZXZlbE9yRW50cnk6IExvZ0xldmVsIHwgTG9nRW50cnksIGZtdD86IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKTogdm9pZCB7XG4gIC8vIE5vcm1hbGl6ZSBpbnB1dFxuICBjb25zdCBlbnRyeTogTG9nRW50cnkgPSB0eXBlb2YgbGV2ZWxPckVudHJ5ID09PSAnc3RyaW5nJ1xuICAgID8geyBsZXZlbDogbGV2ZWxPckVudHJ5IGFzIExvZ0xldmVsLCBtZXNzYWdlOiB1dGlsLmZvcm1hdChmbXQhLCAuLi5hcmdzKSB9XG4gICAgOiBsZXZlbE9yRW50cnk7XG5cbiAgLy8gQ2hlY2sgaWYgd2Ugc2hvdWxkIGxvZyB0aGlzIGxldmVsXG4gIGlmIChsZXZlbFByaW9yaXR5W2VudHJ5LmxldmVsXSA+IGxldmVsUHJpb3JpdHlbY3VycmVudExvZ0xldmVsXSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEZvcm1hdCB0aGUgbWVzc2FnZVxuICBsZXQgZmluYWxNZXNzYWdlID0gZW50cnkubWVzc2FnZTtcblxuICAvLyBBZGQgdGltZXN0YW1wIGZpcnN0IGlmIHJlcXVlc3RlZFxuICBpZiAoZW50cnkudGltZXN0YW1wKSB7XG4gICAgZmluYWxNZXNzYWdlID0gYFske2Zvcm1hdFRpbWUobmV3IERhdGUoKSl9XSAke2ZpbmFsTWVzc2FnZX1gO1xuICB9XG5cbiAgLy8gQWRkIHByZWZpeCBBRlRFUiB0aW1lc3RhbXBcbiAgaWYgKGVudHJ5LnByZWZpeCkge1xuICAgIGZpbmFsTWVzc2FnZSA9IGAke2VudHJ5LnByZWZpeH0gJHtmaW5hbE1lc3NhZ2V9YDtcbiAgfVxuXG4gIC8vIEFwcGx5IGN1c3RvbSBzdHlsZSBpZiBwcm92aWRlZCwgb3RoZXJ3aXNlIHVzZSBsZXZlbC1iYXNlZCBzdHlsZVxuICBjb25zdCBzdHlsZSA9IGVudHJ5LnN0eWxlIHx8IHN0eWxlTWFwW2VudHJ5LmxldmVsXTtcbiAgZmluYWxNZXNzYWdlID0gc3R5bGUoZmluYWxNZXNzYWdlKTtcblxuICAvLyBHZXQgYXBwcm9wcmlhdGUgc3RyZWFtIC0gcGFzcyB0aHJvdWdoIGZvcmNlU3Rkb3V0IGZsYWdcbiAgY29uc3Qgc3RyZWFtID0gZ2V0U3RyZWFtKGVudHJ5LmxldmVsLCBlbnRyeS5mb3JjZVN0ZG91dCk7XG5cbiAgLy8gSGFuZGxlIGNvcmtpbmdcbiAgaWYgKENPUktfQ09VTlRFUiA+IDApIHtcbiAgICBsb2dCdWZmZXIucHVzaChbc3RyZWFtLCBmaW5hbE1lc3NhZ2VdKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBXcml0ZSB0byBzdHJlYW1cbiAgc3RyZWFtLndyaXRlKGZpbmFsTWVzc2FnZSArICdcXG4nKTtcbn1cblxuLy8gQ29udmVuaWVuY2UgbG9nZ2luZyBtZXRob2RzXG5leHBvcnQgY29uc3QgZXJyb3IgPSAoZm10OiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSkgPT4gbG9nKExvZ0xldmVsLkVSUk9SLCBmbXQsIC4uLmFyZ3MpO1xuZXhwb3J0IGNvbnN0IHdhcm5pbmcgPSAoZm10OiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSkgPT4gbG9nKExvZ0xldmVsLldBUk4sIGZtdCwgLi4uYXJncyk7XG5leHBvcnQgY29uc3QgaW5mbyA9IChmbXQ6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKSA9PiBsb2coTG9nTGV2ZWwuSU5GTywgZm10LCAuLi5hcmdzKTtcbmV4cG9ydCBjb25zdCBwcmludCA9IChmbXQ6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKSA9PiBsb2coTG9nTGV2ZWwuSU5GTywgZm10LCAuLi5hcmdzKTtcbmV4cG9ydCBjb25zdCBkYXRhID0gKGZtdDogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pID0+IGxvZyh7XG4gIGxldmVsOiBMb2dMZXZlbC5JTkZPLFxuICBtZXNzYWdlOiB1dGlsLmZvcm1hdChmbXQsIC4uLmFyZ3MpLFxuICBmb3JjZVN0ZG91dDogdHJ1ZSxcbn0pO1xuZXhwb3J0IGNvbnN0IGRlYnVnID0gKGZtdDogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pID0+IGxvZyh7XG4gIGxldmVsOiBMb2dMZXZlbC5ERUJVRyxcbiAgbWVzc2FnZTogdXRpbC5mb3JtYXQoZm10LCAuLi5hcmdzKSxcbiAgdGltZXN0YW1wOiB0cnVlLFxufSk7XG5cbmV4cG9ydCBjb25zdCB0cmFjZSA9IChmbXQ6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKSA9PiBsb2coe1xuICBsZXZlbDogTG9nTGV2ZWwuVFJBQ0UsXG4gIG1lc3NhZ2U6IHV0aWwuZm9ybWF0KGZtdCwgLi4uYXJncyksXG4gIHRpbWVzdGFtcDogdHJ1ZSxcbn0pO1xuXG5leHBvcnQgY29uc3Qgc3VjY2VzcyA9IChmbXQ6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKSA9PiBsb2coe1xuICBsZXZlbDogTG9nTGV2ZWwuSU5GTyxcbiAgbWVzc2FnZTogdXRpbC5mb3JtYXQoZm10LCAuLi5hcmdzKSxcbiAgc3R5bGU6IGNoYWxrLmdyZWVuLFxufSk7XG5cbmV4cG9ydCBjb25zdCBoaWdobGlnaHQgPSAoZm10OiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSkgPT4gbG9nKHtcbiAgbGV2ZWw6IExvZ0xldmVsLklORk8sXG4gIG1lc3NhZ2U6IHV0aWwuZm9ybWF0KGZtdCwgLi4uYXJncyksXG4gIHN0eWxlOiBjaGFsay5ib2xkLFxufSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGxvZ2dpbmcgZnVuY3Rpb24gdGhhdCBwcmVwZW5kcyBhIHByZWZpeCB0byBhbGwgbWVzc2FnZXMuXG4gKiBAcGFyYW0gcHJlZml4U3RyaW5nIC0gU3RyaW5nIHRvIHByZXBlbmQgdG8gYWxsIG1lc3NhZ2VzXG4gKiBAcGFyYW0gbGV2ZWwgLSBMb2cgbGV2ZWwgdG8gdXNlIChkZWZhdWx0cyB0byBJTkZPKVxuICogQHJldHVybnMgTG9nZ2luZyBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgZm9ybWF0IHN0cmluZyBhbmQgYXJndW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVmaXgocHJlZml4U3RyaW5nOiBzdHJpbmcsIGxldmVsOiBMb2dMZXZlbCA9IExvZ0xldmVsLklORk8pOiAoZm10OiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdm9pZCB7XG4gIHJldHVybiAoZm10OiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSkgPT4gbG9nKHtcbiAgICBsZXZlbCxcbiAgICBtZXNzYWdlOiB1dGlsLmZvcm1hdChmbXQsIC4uLmFyZ3MpLFxuICAgIHByZWZpeDogcHJlZml4U3RyaW5nLFxuICB9KTtcbn1cbiJdfQ==
225
+ const highlight = (input, ...args) => {
226
+ return formatMessageAndLog('info', false, input, chalk.bold, ...args);
227
+ };
228
+ exports.highlight = highlight;
229
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxvZ2dpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBc0JBLHNEQUVDO0FBT0Qsc0JBRUM7QUFRRCw4Q0FjQztBQXZERCw2QkFBNkI7QUFDN0IsK0JBQStCO0FBQy9CLHVEQUF1SjtBQUV2SixvQkFBb0I7QUFDcEIsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO0FBQ3JCLE1BQU0sU0FBUyxHQUFnQixFQUFFLENBQUM7QUFFbEMsTUFBTSxhQUFhLEdBQW1DO0lBQ3BELEtBQUssRUFBRSxDQUFDO0lBQ1IsSUFBSSxFQUFFLENBQUM7SUFDUCxJQUFJLEVBQUUsQ0FBQztJQUNQLEtBQUssRUFBRSxDQUFDO0lBQ1IsS0FBSyxFQUFFLENBQUM7Q0FDVCxDQUFDO0FBRUYsSUFBSSx5QkFBeUIsR0FBbUIsTUFBTSxDQUFDO0FBRXZEOzs7R0FHRztBQUNILFNBQWdCLHFCQUFxQixDQUFDLEtBQXFCO0lBQ3pELHlCQUF5QixHQUFHLEtBQUssQ0FBQztBQUNwQyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQWdCLEtBQUssQ0FBQyxLQUFjO0lBQ2xDLHVCQUFTLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQztBQUN2QixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSSxLQUFLLFVBQVUsaUJBQWlCLENBQUksS0FBdUI7SUFDaEUsWUFBWSxFQUFFLENBQUM7SUFDZixJQUFJLENBQUM7UUFDSCxPQUFPLE1BQU0sS0FBSyxFQUFFLENBQUM7SUFDdkIsQ0FBQztZQUFTLENBQUM7UUFDVCxZQUFZLEVBQUUsQ0FBQztRQUNmLElBQUksWUFBWSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLCtDQUErQztZQUMvQyxLQUFLLE1BQU0sU0FBUyxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNsQyxLQUFLLHVCQUFTLENBQUMsU0FBUyxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQy9DLENBQUM7WUFDRCxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQXdCRDs7O0dBR0c7QUFDSCxTQUFTLEdBQUcsQ0FBQyxPQUFtQjtJQUM5QixJQUFJLGFBQWEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsYUFBYSxDQUFDLHlCQUF5QixDQUFDLEVBQUUsQ0FBQztRQUM1RSxPQUFPO0lBQ1QsQ0FBQztJQUVELE1BQU0sU0FBUyxHQUFjO1FBQzNCLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSztRQUNwQixPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87UUFDeEIsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXO1FBQ2hDLElBQUksRUFBRSxJQUFJLElBQUksRUFBRTtRQUNoQixNQUFNLEVBQUUsdUJBQVMsQ0FBQyxhQUFhLElBQUksTUFBTTtRQUN6QyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7S0FDbkIsQ0FBQztJQUVGLElBQUksWUFBWSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3JCLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDMUIsT0FBTztJQUNULENBQUM7SUFFRCxLQUFLLHVCQUFTLENBQUMsU0FBUyxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQy9DLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FDMUIsS0FBcUIsRUFDckIsV0FBb0IsRUFDcEIsS0FBNEIsRUFDNUIsS0FBK0IsRUFDL0IsR0FBRyxJQUFlO0lBRWxCLHFFQUFxRTtJQUNyRSxNQUFNLEVBQUUsT0FBTyxFQUFFLElBQUksR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxPQUFPLEtBQUssS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFFekcsc0NBQXNDO0lBQ3RDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQztRQUMvQixDQUFDLENBQUMsT0FBTyxDQUFDO0lBRVosMEJBQTBCO0lBQzFCLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDO0lBRXhFLEdBQUcsQ0FBQztRQUNGLEtBQUs7UUFDTCxPQUFPLEVBQUUsWUFBWTtRQUNyQixJQUFJO1FBQ0osV0FBVztLQUNaLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxLQUFxQixFQUFFLFdBQWtDLFNBQVM7SUFDeEYsTUFBTSxjQUFjLEdBQUcsS0FBSyxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUMsS0FBSyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdEIsR0FBRyxDQUFDO0lBQ1IsT0FBTyxPQUFPLFFBQVEsSUFBSSxjQUFjLE1BQU0sQ0FBQztBQUNqRCxDQUFDO0FBaUJELHlHQUF5RztBQUN6RywrQkFBK0I7QUFFL0I7Ozs7Ozs7Ozs7R0FVRztBQUNJLE1BQU0sS0FBSyxHQUFHLENBQUMsS0FBb0IsRUFBRSxHQUFHLElBQWUsRUFBRSxFQUFFO0lBQ2hFLE9BQU8sbUJBQW1CLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFDeEUsQ0FBQyxDQUFDO0FBRlcsUUFBQSxLQUFLLFNBRWhCO0FBRUY7Ozs7Ozs7Ozs7R0FVRztBQUNJLE1BQU0sT0FBTyxHQUFHLENBQUMsS0FBb0IsRUFBRSxHQUFHLElBQWUsRUFBRSxFQUFFO0lBQ2xFLE9BQU8sbUJBQW1CLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFDdkUsQ0FBQyxDQUFDO0FBRlcsUUFBQSxPQUFPLFdBRWxCO0FBRUY7Ozs7Ozs7Ozs7R0FVRztBQUNJLE1BQU0sSUFBSSxHQUFHLENBQUMsS0FBb0IsRUFBRSxHQUFHLElBQWUsRUFBRSxFQUFFO0lBQy9ELE9BQU8sbUJBQW1CLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFDdkUsQ0FBQyxDQUFDO0FBRlcsUUFBQSxJQUFJLFFBRWY7QUFFRjs7Ozs7Ozs7OztHQVVHO0FBQ0ksTUFBTSxJQUFJLEdBQUcsQ0FBQyxLQUFvQixFQUFFLEdBQUcsSUFBZSxFQUFFLEVBQUU7SUFDL0QsT0FBTyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUN0RSxDQUFDLENBQUM7QUFGVyxRQUFBLElBQUksUUFFZjtBQUVGOzs7Ozs7Ozs7O0dBVUc7QUFDSSxNQUFNLEtBQUssR0FBRyxDQUFDLEtBQW9CLEVBQUUsR0FBRyxJQUFlLEVBQUUsRUFBRTtJQUNoRSxPQUFPLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQ3hFLENBQUMsQ0FBQztBQUZXLFFBQUEsS0FBSyxTQUVoQjtBQUVGOzs7Ozs7Ozs7O0dBVUc7QUFDSSxNQUFNLEtBQUssR0FBRyxDQUFDLEtBQW9CLEVBQUUsR0FBRyxJQUFlLEVBQUUsRUFBRTtJQUNoRSxPQUFPLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQ3hFLENBQUMsQ0FBQztBQUZXLFFBQUEsS0FBSyxTQUVoQjtBQUVGOzs7Ozs7Ozs7O0dBVUc7QUFDSSxNQUFNLE9BQU8sR0FBRyxDQUFDLEtBQW9CLEVBQUUsR0FBRyxJQUFlLEVBQUUsRUFBRTtJQUNsRSxPQUFPLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUN6RSxDQUFDLENBQUM7QUFGVyxRQUFBLE9BQU8sV0FFbEI7QUFFRjs7Ozs7Ozs7OztHQVVHO0FBQ0ksTUFBTSxTQUFTLEdBQUcsQ0FBQyxLQUFvQixFQUFFLEdBQUcsSUFBZSxFQUFFLEVBQUU7SUFDcEUsT0FBTyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFDeEUsQ0FBQyxDQUFDO0FBRlcsUUFBQSxTQUFTLGFBRXBCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgdXRpbCBmcm9tICd1dGlsJztcbmltcG9ydCAqIGFzIGNoYWxrIGZyb20gJ2NoYWxrJztcbmltcG9ydCB7IElvTWVzc2FnZUxldmVsLCBJb01lc3NhZ2UsIENsaUlvSG9zdCwgSW9NZXNzYWdlU3BlY2lmaWNDb2RlLCBJb01lc3NhZ2VDb2RlLCBJb01lc3NhZ2VDb2RlQ2F0ZWdvcnksIElvQ29kZUxldmVsIH0gZnJvbSAnLi90b29sa2l0L2NsaS1pby1ob3N0JztcblxuLy8gQ29ya2luZyBtZWNoYW5pc21cbmxldCBDT1JLX0NPVU5URVIgPSAwO1xuY29uc3QgbG9nQnVmZmVyOiBJb01lc3NhZ2VbXSA9IFtdO1xuXG5jb25zdCBsZXZlbFByaW9yaXR5OiBSZWNvcmQ8SW9NZXNzYWdlTGV2ZWwsIG51bWJlcj4gPSB7XG4gIGVycm9yOiAwLFxuICB3YXJuOiAxLFxuICBpbmZvOiAyLFxuICBkZWJ1ZzogMyxcbiAgdHJhY2U6IDQsXG59O1xuXG5sZXQgY3VycmVudElvTWVzc2FnZVRocmVzaG9sZDogSW9NZXNzYWdlTGV2ZWwgPSAnaW5mbyc7XG5cbi8qKlxuICogU2V0cyB0aGUgY3VycmVudCB0aHJlc2hvbGQuIE1lc3NhZ2VzIHdpdGggYSBsb3dlciBwcmlvcml0eSBsZXZlbCB3aWxsIGJlIGlnbm9yZWQuXG4gKiBAcGFyYW0gbGV2ZWwgVGhlIG5ldyBsb2cgbGV2ZWwgdGhyZXNob2xkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRJb01lc3NhZ2VUaHJlc2hvbGQobGV2ZWw6IElvTWVzc2FnZUxldmVsKSB7XG4gIGN1cnJlbnRJb01lc3NhZ2VUaHJlc2hvbGQgPSBsZXZlbDtcbn1cblxuLyoqXG4gKiBTZXRzIHdoZXRoZXIgdGhlIGxvZ2dlciBpcyBydW5uaW5nIGluIENJIG1vZGUuXG4gKiBJbiBDSSBtb2RlLCBhbGwgbm9uLWVycm9yIG91dHB1dCBnb2VzIHRvIHN0ZG91dCBpbnN0ZWFkIG9mIHN0ZGVyci5cbiAqIEBwYXJhbSBuZXdDSSAtIFdoZXRoZXIgQ0kgbW9kZSBzaG91bGQgYmUgZW5hYmxlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0Q0kobmV3Q0k6IGJvb2xlYW4pIHtcbiAgQ2xpSW9Ib3N0LmNpID0gbmV3Q0k7XG59XG5cbi8qKlxuICogRXhlY3V0ZXMgYSBibG9jayBvZiBjb2RlIHdpdGggY29ya2VkIGxvZ2dpbmcuIEFsbCBsb2cgbWVzc2FnZXMgZHVyaW5nIGV4ZWN1dGlvblxuICogYXJlIGJ1ZmZlcmVkIGFuZCBvbmx5IHdyaXR0ZW4gd2hlbiBhbGwgbmVzdGVkIGNvcmsgYmxvY2tzIGNvbXBsZXRlICh3aGVuIENPUktfQ09VTlRFUiByZWFjaGVzIDApLlxuICogQHBhcmFtIGJsb2NrIC0gQXN5bmMgZnVuY3Rpb24gdG8gZXhlY3V0ZSB3aXRoIGNvcmtlZCBsb2dnaW5nXG4gKiBAcmV0dXJucyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgYmxvY2sncyByZXR1cm4gdmFsdWVcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhDb3JrZWRMb2dnaW5nPFQ+KGJsb2NrOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gIENPUktfQ09VTlRFUisrO1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBibG9jaygpO1xuICB9IGZpbmFsbHkge1xuICAgIENPUktfQ09VTlRFUi0tO1xuICAgIGlmIChDT1JLX0NPVU5URVIgPT09IDApIHtcbiAgICAgIC8vIFByb2Nlc3MgZWFjaCBidWZmZXJlZCBtZXNzYWdlIHRocm91Z2ggbm90aWZ5XG4gICAgICBmb3IgKGNvbnN0IGlvTWVzc2FnZSBvZiBsb2dCdWZmZXIpIHtcbiAgICAgICAgdm9pZCBDbGlJb0hvc3QuZ2V0SW9Ib3N0KCkubm90aWZ5KGlvTWVzc2FnZSk7XG4gICAgICB9XG4gICAgICBsb2dCdWZmZXIuc3BsaWNlKDApO1xuICAgIH1cbiAgfVxufVxuXG5pbnRlcmZhY2UgTG9nT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgbG9nIGxldmVsIHRvIHVzZVxuICAgKi9cbiAgcmVhZG9ubHkgbGV2ZWw6IElvTWVzc2FnZUxldmVsO1xuICAvKipcbiAgICogVGhlIG1lc3NhZ2UgdG8gbG9nXG4gICAqL1xuICByZWFkb25seSBtZXNzYWdlOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGZvcmNlIHN0ZG91dFxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZm9yY2VTdGRvdXQ/OiBib29sZWFuO1xuICAvKipcbiAgICogTWVzc2FnZSBjb2RlIG9mIHRoZSBmb3JtYXQgW0NBVEVHT1JZXV9bTlVNQkVSX0NPREVdXG4gICAqIEBwYXR0ZXJuIFtBLVpdK19bMC0yXVswLTldezN9XG4gICAqIEBkZWZhdWx0IFRPT0xLSVRfWzAvMS8yXTAwMFxuICAgKi9cbiAgcmVhZG9ubHkgY29kZTogSW9NZXNzYWdlQ29kZTtcbn1cblxuLyoqXG4gKiBJbnRlcm5hbCBjb3JlIGxvZ2dpbmcgZnVuY3Rpb24gdGhhdCB3cml0ZXMgbWVzc2FnZXMgdGhyb3VnaCB0aGUgQ0xJIElPIGhvc3QuXG4gKiBAcGFyYW0gb3B0aW9ucyBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIHRoZSBsb2cgbWVzc2FnZS4gU2VlICB7QGxpbmsgTG9nT3B0aW9uc31cbiAqL1xuZnVuY3Rpb24gbG9nKG9wdGlvbnM6IExvZ09wdGlvbnMpIHtcbiAgaWYgKGxldmVsUHJpb3JpdHlbb3B0aW9ucy5sZXZlbF0gPiBsZXZlbFByaW9yaXR5W2N1cnJlbnRJb01lc3NhZ2VUaHJlc2hvbGRdKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgaW9NZXNzYWdlOiBJb01lc3NhZ2UgPSB7XG4gICAgbGV2ZWw6IG9wdGlvbnMubGV2ZWwsXG4gICAgbWVzc2FnZTogb3B0aW9ucy5tZXNzYWdlLFxuICAgIGZvcmNlU3Rkb3V0OiBvcHRpb25zLmZvcmNlU3Rkb3V0LFxuICAgIHRpbWU6IG5ldyBEYXRlKCksXG4gICAgYWN0aW9uOiBDbGlJb0hvc3QuY3VycmVudEFjdGlvbiA/PyAnbm9uZScsXG4gICAgY29kZTogb3B0aW9ucy5jb2RlLFxuICB9O1xuXG4gIGlmIChDT1JLX0NPVU5URVIgPiAwKSB7XG4gICAgbG9nQnVmZmVyLnB1c2goaW9NZXNzYWdlKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB2b2lkIENsaUlvSG9zdC5nZXRJb0hvc3QoKS5ub3RpZnkoaW9NZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBJbnRlcm5hbCBoZWxwZXIgdGhhdCBwcm9jZXNzZXMgbG9nIGlucHV0cyBpbnRvIGEgY29uc2lzdGVudCBmb3JtYXQuXG4gKiBIYW5kbGVzIHN0cmluZyBpbnRlcnBvbGF0aW9uLCBmb3JtYXQgc3RyaW5ncywgYW5kIG9iamVjdCBwYXJhbWV0ZXIgc3R5bGVzLlxuICogQXBwbGllcyBvcHRpb25hbCBzdHlsaW5nIGFuZCBwcmVwYXJlcyB0aGUgZmluYWwgbWVzc2FnZSBmb3IgbG9nZ2luZy5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0TWVzc2FnZUFuZExvZyhcbiAgbGV2ZWw6IElvTWVzc2FnZUxldmVsLFxuICBmb3JjZVN0ZG91dDogYm9vbGVhbixcbiAgaW5wdXQ6IExvZ0lucHV0PElvQ29kZUxldmVsPixcbiAgc3R5bGU/OiAoc3RyOiBzdHJpbmcpID0+IHN0cmluZyxcbiAgLi4uYXJnczogdW5rbm93bltdXG4pOiB2b2lkIHtcbiAgLy8gRXh0cmFjdCBtZXNzYWdlIGFuZCBjb2RlIGZyb20gaW5wdXQsIHVzaW5nIG5ldyBkZWZhdWx0IGNvZGUgZm9ybWF0XG4gIGNvbnN0IHsgbWVzc2FnZSwgY29kZSA9IGdldERlZmF1bHRDb2RlKGxldmVsKSB9ID0gdHlwZW9mIGlucHV0ID09PSAnb2JqZWN0JyA/IGlucHV0IDogeyBtZXNzYWdlOiBpbnB1dCB9O1xuXG4gIC8vIEZvcm1hdCBtZXNzYWdlIGlmIGFyZ3MgYXJlIHByb3ZpZGVkXG4gIGNvbnN0IGZvcm1hdHRlZE1lc3NhZ2UgPSBhcmdzLmxlbmd0aCA+IDBcbiAgICA/IHV0aWwuZm9ybWF0KG1lc3NhZ2UsIC4uLmFyZ3MpXG4gICAgOiBtZXNzYWdlO1xuXG4gIC8vIEFwcGx5IHN0eWxlIGlmIHByb3ZpZGVkXG4gIGNvbnN0IGZpbmFsTWVzc2FnZSA9IHN0eWxlID8gc3R5bGUoZm9ybWF0dGVkTWVzc2FnZSkgOiBmb3JtYXR0ZWRNZXNzYWdlO1xuXG4gIGxvZyh7XG4gICAgbGV2ZWwsXG4gICAgbWVzc2FnZTogZmluYWxNZXNzYWdlLFxuICAgIGNvZGUsXG4gICAgZm9yY2VTdGRvdXQsXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBnZXREZWZhdWx0Q29kZShsZXZlbDogSW9NZXNzYWdlTGV2ZWwsIGNhdGVnb3J5OiBJb01lc3NhZ2VDb2RlQ2F0ZWdvcnkgPSAnVE9PTEtJVCcpOiBJb01lc3NhZ2VDb2RlIHtcbiAgY29uc3QgbGV2ZWxJbmRpY2F0b3IgPSBsZXZlbCA9PT0gJ2Vycm9yJyA/ICdFJyA6XG4gICAgbGV2ZWwgPT09ICd3YXJuJyA/ICdXJyA6XG4gICAgICAnSSc7XG4gIHJldHVybiBgQ0RLXyR7Y2F0ZWdvcnl9XyR7bGV2ZWxJbmRpY2F0b3J9MDAwMGA7XG59XG5cbi8vIFR5cGUgZm9yIHRoZSBvYmplY3QgcGFyYW1ldGVyIHN0eWxlXG5pbnRlcmZhY2UgTG9nUGFyYW1zPEwgZXh0ZW5kcyBJb0NvZGVMZXZlbD4ge1xuICAvKipcbiAgICogQHNlZSB7QGxpbmsgSW9NZXNzYWdlLmNvZGV9XG4gICAqL1xuICByZWFkb25seSBjb2RlPzogSW9NZXNzYWdlU3BlY2lmaWNDb2RlPEw+O1xuICAvKipcbiAgICogQHNlZSB7QGxpbmsgSW9NZXNzYWdlLm1lc3NhZ2V9XG4gICAqL1xuICByZWFkb25seSBtZXNzYWdlOiBzdHJpbmc7XG59XG5cbi8vIFR5cGUgZm9yIHRoZSBleHBvcnRlZCBsb2cgZnVuY3Rpb24gYXJndW1lbnRzXG50eXBlIExvZ0lucHV0PEwgZXh0ZW5kcyBJb0NvZGVMZXZlbD4gPSBzdHJpbmcgfCBMb2dQYXJhbXM8TD47XG5cbi8vIEV4cG9ydGVkIGxvZ2dpbmcgZnVuY3Rpb25zLiBJZiBhbnkgYWRkaXRpb25hbCBsb2dnaW5nIGZ1bmN0aW9uYWxpdHkgaXMgcmVxdWlyZWQsIGl0IHNob3VsZCBiZSBhZGRlZCBhc1xuLy8gYSBuZXcgbG9nZ2luZyBmdW5jdGlvbiBoZXJlLlxuXG4vKipcbiAqIExvZ3MgYW4gZXJyb3IgbGV2ZWwgbWVzc2FnZS5cbiAqXG4gKiBDYW4gYmUgdXNlZCBpbiBtdWx0aXBsZSB3YXlzOlxuICogYGBgdHNcbiAqIGVycm9yKGBvcGVyYXRpb24gZmFpbGVkOiAke2V9YCkgLy8gaW5mZXJzIGRlZmF1bHQgZXJyb3IgY29kZSBgQ0RLX1RPT0xLSVRfRTAwMGBcbiAqIGVycm9yKCdvcGVyYXRpb24gZmFpbGVkOiAlcycsIGUpIC8vIGluZmVycyBkZWZhdWx0IGVycm9yIGNvZGUgYENES19UT09MS0lUX0UwMDBgXG4gKiBlcnJvcih7IG1lc3NhZ2U6ICdvcGVyYXRpb24gZmFpbGVkJywgY29kZTogJ0NES19TREtfRTAwMScgfSkgLy8gc3BlY2lmaWVzIGVycm9yIGNvZGUgYENES19TREtfRTAwMWBcbiAqIGVycm9yKHsgbWVzc2FnZTogJ29wZXJhdGlvbiBmYWlsZWQ6ICVzJywgY29kZTogJ0NES19TREtfRTAwMScgfSwgZSkgLy8gc3BlY2lmaWVzIGVycm9yIGNvZGUgYENES19TREtfRTAwMWBcbiAqIGBgYFxuICovXG5leHBvcnQgY29uc3QgZXJyb3IgPSAoaW5wdXQ6IExvZ0lucHV0PCdFJz4sIC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICByZXR1cm4gZm9ybWF0TWVzc2FnZUFuZExvZygnZXJyb3InLCBmYWxzZSwgaW5wdXQsIHVuZGVmaW5lZCwgLi4uYXJncyk7XG59O1xuXG4vKipcbiAqIExvZ3MgYW4gd2FybmluZyBsZXZlbCBtZXNzYWdlLlxuICpcbiAqIENhbiBiZSB1c2VkIGluIG11bHRpcGxlIHdheXM6XG4gKiBgYGB0c1xuICogd2FybmluZyhgZGVwcmVjdGVkIGZlYXR1cmU6ICR7bWVzc2FnZX1gKSAvLyBpbmZlcnMgZGVmYXVsdCB3YXJuaW5nIGNvZGUgYENES19UT09MS0lUX1cwMDBgXG4gKiB3YXJuaW5nKCdkZXByZWN0ZWQgZmVhdHVyZTogJXMnLCBtZXNzYWdlKSAvLyBpbmZlcnMgZGVmYXVsdCB3YXJuaW5nIGNvZGUgYENES19UT09MS0lUX1cwMDBgXG4gKiB3YXJuaW5nKHsgbWVzc2FnZTogJ2RlcHJlY3RlZCBmZWF0dXJlJywgY29kZTogJ0NES19TREtfVzAwMScgfSkgLy8gc3BlY2lmaWVzIHdhcm5pbmcgY29kZSBgQ0RLX1NES19XMDAxYFxuICogd2FybmluZyh7IG1lc3NhZ2U6ICdkZXByZWN0ZWQgZmVhdHVyZTogJXMnLCBjb2RlOiAnQ0RLX1NES19XMDAxJyB9LCBtZXNzYWdlKSAvLyBzcGVjaWZpZXMgd2FybmluZyBjb2RlIGBDREtfU0RLX1cwMDFgXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IHdhcm5pbmcgPSAoaW5wdXQ6IExvZ0lucHV0PCdXJz4sIC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICByZXR1cm4gZm9ybWF0TWVzc2FnZUFuZExvZygnd2FybicsIGZhbHNlLCBpbnB1dCwgdW5kZWZpbmVkLCAuLi5hcmdzKTtcbn07XG5cbi8qKlxuICogTG9ncyBhbiBpbmZvIGxldmVsIG1lc3NhZ2UuXG4gKlxuICogQ2FuIGJlIHVzZWQgaW4gbXVsdGlwbGUgd2F5czpcbiAqIGBgYHRzXG4gKiBpbmZvKGBwcm9jZXNzaW5nOiAke21lc3NhZ2V9YCkgLy8gaW5mZXJzIGRlZmF1bHQgaW5mbyBjb2RlIGBDREtfVE9PTEtJVF9JMDAwYFxuICogaW5mbygncHJvY2Vzc2luZzogJXMnLCBtZXNzYWdlKSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiBpbmZvKHsgbWVzc2FnZTogJ3Byb2Nlc3NpbmcnLCBjb2RlOiAnQ0RLX1RPT0xLSVRfSTAwMScgfSkgLy8gc3BlY2lmaWVzIGluZm8gY29kZSBgQ0RLX1RPT0xLSVRfSTAwMWBcbiAqIGluZm8oeyBtZXNzYWdlOiAncHJvY2Vzc2luZzogJXMnLCBjb2RlOiAnQ0RLX1RPT0xLSVRfSTAwMScgfSwgbWVzc2FnZSkgLy8gc3BlY2lmaWVzIGluZm8gY29kZSBgQ0RLX1RPT0xLSVRfSTAwMWBcbiAqIGBgYFxuICovXG5leHBvcnQgY29uc3QgaW5mbyA9IChpbnB1dDogTG9nSW5wdXQ8J0knPiwgLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gIHJldHVybiBmb3JtYXRNZXNzYWdlQW5kTG9nKCdpbmZvJywgZmFsc2UsIGlucHV0LCB1bmRlZmluZWQsIC4uLmFyZ3MpO1xufTtcblxuLyoqXG4gKiBMb2dzIGFuIGluZm8gbGV2ZWwgbWVzc2FnZSB0byBzdGRvdXQuXG4gKlxuICogQ2FuIGJlIHVzZWQgaW4gbXVsdGlwbGUgd2F5czpcbiAqIGBgYHRzXG4gKiBkYXRhKGAke0pTT04uc3RyaW5naWZ5KHN0YXRzKX1gKSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiBkYXRhKCd7XCJjb3VudFwiOiAlZH0nLCBjb3VudCkgLy8gaW5mZXJzIGRlZmF1bHQgaW5mbyBjb2RlIGBDREtfVE9PTEtJVF9JMDAwYFxuICogZGF0YSh7IG1lc3NhZ2U6ICdzdGF0czogJWonLCBjb2RlOiAnQ0RLX0RBVEFfSTAwMScgfSkgLy8gc3BlY2lmaWVzIGluZm8gY29kZSBgQ0RLX0RBVEFfSTAwMWBcbiAqIGRhdGEoeyBtZXNzYWdlOiAnc3RhdHM6ICVqJywgY29kZTogJ0NES19EQVRBX0kwMDEnIH0sIHN0YXRzKSAvLyBzcGVjaWZpZXMgaW5mbyBjb2RlIGBDREtfREFUQV9JMDAxYFxuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBkYXRhID0gKGlucHV0OiBMb2dJbnB1dDwnSSc+LCAuLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgcmV0dXJuIGZvcm1hdE1lc3NhZ2VBbmRMb2coJ2luZm8nLCB0cnVlLCBpbnB1dCwgdW5kZWZpbmVkLCAuLi5hcmdzKTtcbn07XG5cbi8qKlxuICogTG9ncyBhIGRlYnVnIGxldmVsIG1lc3NhZ2UuXG4gKlxuICogQ2FuIGJlIHVzZWQgaW4gbXVsdGlwbGUgd2F5czpcbiAqIGBgYHRzXG4gKiBkZWJ1Zyhgc3RhdGU6ICR7SlNPTi5zdHJpbmdpZnkoc3RhdGUpfWApIC8vIGluZmVycyBkZWZhdWx0IGluZm8gY29kZSBgQ0RLX1RPT0xLSVRfSTAwMGBcbiAqIGRlYnVnKCdjYWNoZSBoaXQgcmF0aW86ICVkJSUnLCByYXRpbykgLy8gaW5mZXJzIGRlZmF1bHQgaW5mbyBjb2RlIGBDREtfVE9PTEtJVF9JMDAwYFxuICogZGVidWcoeyBtZXNzYWdlOiAnc3RhdGUgdXBkYXRlJywgY29kZTogJ0NES19UT09MS0lUX0kwMDEnIH0pIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiBkZWJ1Zyh7IG1lc3NhZ2U6ICdyYXRpbzogJWQlJScsIGNvZGU6ICdDREtfVE9PTEtJVF9JMDAxJyB9LCByYXRpbykgLy8gc3BlY2lmaWVzIGluZm8gY29kZSBgQ0RLX1RPT0xLSVRfSTAwMWBcbiAqIGBgYFxuICovXG5leHBvcnQgY29uc3QgZGVidWcgPSAoaW5wdXQ6IExvZ0lucHV0PCdJJz4sIC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICByZXR1cm4gZm9ybWF0TWVzc2FnZUFuZExvZygnZGVidWcnLCBmYWxzZSwgaW5wdXQsIHVuZGVmaW5lZCwgLi4uYXJncyk7XG59O1xuXG4vKipcbiAqIExvZ3MgYSB0cmFjZSBsZXZlbCBtZXNzYWdlLlxuICpcbiAqIENhbiBiZSB1c2VkIGluIG11bHRpcGxlIHdheXM6XG4gKiBgYGB0c1xuICogdHJhY2UoYGVudGVyZWQgJHtuYW1lfSB3aXRoICR7YXJnc31gKSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiB0cmFjZSgnbWV0aG9kOiAlcywgYXJnczogJWonLCBuYW1lLCBhcmdzKSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiB0cmFjZSh7IG1lc3NhZ2U6ICdlbnRlcmVkJywgY29kZTogJ0NES19UT09MS0lUX0kwMDEnIH0pIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiB0cmFjZSh7IG1lc3NhZ2U6ICdtZXRob2Q6ICVzJywgY29kZTogJ0NES19UT09MS0lUX0kwMDEnIH0sIG5hbWUpIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IHRyYWNlID0gKGlucHV0OiBMb2dJbnB1dDwnSSc+LCAuLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgcmV0dXJuIGZvcm1hdE1lc3NhZ2VBbmRMb2coJ3RyYWNlJywgZmFsc2UsIGlucHV0LCB1bmRlZmluZWQsIC4uLmFyZ3MpO1xufTtcblxuLyoqXG4gKiBMb2dzIGFuIGluZm8gbGV2ZWwgc3VjY2VzcyBtZXNzYWdlIGluIGdyZWVuIHRleHQuXG4gKlxuICogQ2FuIGJlIHVzZWQgaW4gbXVsdGlwbGUgd2F5czpcbiAqIGBgYHRzXG4gKiBzdWNjZXNzKGBkZXBsb3ltZW50IGNvbXBsZXRlZDogJHtuYW1lfWApIC8vIGluZmVycyBkZWZhdWx0IGluZm8gY29kZSBgQ0RLX1RPT0xLSVRfSTAwMGBcbiAqIHN1Y2Nlc3MoJ3Byb2Nlc3NlZCAlZCBpdGVtcycsIGNvdW50KSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiBzdWNjZXNzKHsgbWVzc2FnZTogJ2NvbXBsZXRlZCcsIGNvZGU6ICdDREtfVE9PTEtJVF9JMDAxJyB9KSAvLyBzcGVjaWZpZXMgaW5mbyBjb2RlIGBDREtfVE9PTEtJVF9JMDAxYFxuICogc3VjY2Vzcyh7IG1lc3NhZ2U6ICdpdGVtczogJWQnLCBjb2RlOiAnQ0RLX1RPT0xLSVRfSTAwMScgfSwgY291bnQpIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IHN1Y2Nlc3MgPSAoaW5wdXQ6IExvZ0lucHV0PCdJJz4sIC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICByZXR1cm4gZm9ybWF0TWVzc2FnZUFuZExvZygnaW5mbycsIGZhbHNlLCBpbnB1dCwgY2hhbGsuZ3JlZW4sIC4uLmFyZ3MpO1xufTtcblxuLyoqXG4gKiBMb2dzIGFuIGluZm8gbGV2ZWwgbWVzc2FnZSBpbiBib2xkIHRleHQuXG4gKlxuICogQ2FuIGJlIHVzZWQgaW4gbXVsdGlwbGUgd2F5czpcbiAqIGBgYHRzXG4gKiBoaWdobGlnaHQoYGltcG9ydGFudDogJHttc2d9YCkgLy8gaW5mZXJzIGRlZmF1bHQgaW5mbyBjb2RlIGBDREtfVE9PTEtJVF9JMDAwYFxuICogaGlnaGxpZ2h0KCdhdHRlbnRpb24gcmVxdWlyZWQ6ICVzJywgcmVhc29uKSAvLyBpbmZlcnMgZGVmYXVsdCBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDBgXG4gKiBoaWdobGlnaHQoeyBtZXNzYWdlOiAnbm90aWNlJywgY29kZTogJ0NES19UT09MS0lUX0kwMDEnIH0pIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiBoaWdobGlnaHQoeyBtZXNzYWdlOiAnbm90aWNlOiAlcycsIGNvZGU6ICdDREtfVE9PTEtJVF9JMDAxJyB9LCBtc2cpIC8vIHNwZWNpZmllcyBpbmZvIGNvZGUgYENES19UT09MS0lUX0kwMDFgXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IGhpZ2hsaWdodCA9IChpbnB1dDogTG9nSW5wdXQ8J0knPiwgLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gIHJldHVybiBmb3JtYXRNZXNzYWdlQW5kTG9nKCdpbmZvJywgZmFsc2UsIGlucHV0LCBjaGFsay5ib2xkLCAuLi5hcmdzKTtcbn07XG4iXX0=