1 | ;
|
2 | var _a, _b, _c;
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | exports.AccessLogFormat = exports.AccessLogField = exports.LogGroupLogDestination = void 0;
|
5 | const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
|
6 | const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
7 | /**
|
8 | * Use CloudWatch Logs as a custom access log destination for API Gateway.
|
9 | */
|
10 | class LogGroupLogDestination {
|
11 | constructor(logGroup) {
|
12 | this.logGroup = logGroup;
|
13 | }
|
14 | /**
|
15 | * Binds this destination to the CloudWatch Logs.
|
16 | */
|
17 | bind(_stage) {
|
18 | try {
|
19 | jsiiDeprecationWarnings._aws_cdk_aws_apigateway_IStage(_stage);
|
20 | }
|
21 | catch (error) {
|
22 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
23 | Error.captureStackTrace(error, this.bind);
|
24 | }
|
25 | throw error;
|
26 | }
|
27 | return {
|
28 | destinationArn: this.logGroup.logGroupArn,
|
29 | };
|
30 | }
|
31 | }
|
32 | exports.LogGroupLogDestination = LogGroupLogDestination;
|
33 | _a = JSII_RTTI_SYMBOL_1;
|
34 | LogGroupLogDestination[_a] = { fqn: "@aws-cdk/aws-apigateway.LogGroupLogDestination", version: "1.173.0" };
|
35 | /**
|
36 | * $context variables that can be used to customize access log pattern.
|
37 | */
|
38 | class AccessLogField {
|
39 | /**
|
40 | * The API owner's AWS account ID.
|
41 | */
|
42 | static contextAccountId() {
|
43 | return '$context.identity.accountId';
|
44 | }
|
45 | /**
|
46 | * The identifier API Gateway assigns to your API.
|
47 | */
|
48 | static contextApiId() {
|
49 | return '$context.apiId';
|
50 | }
|
51 | /**
|
52 | * A property of the claims returned from the Amazon Cognito user pool after the method caller is successfully authenticated.
|
53 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html
|
54 | *
|
55 | * @param property A property key of the claims.
|
56 | */
|
57 | static contextAuthorizerClaims(property) {
|
58 | return `$context.authorizer.claims.${property}`;
|
59 | }
|
60 | /**
|
61 | * The principal user identification associated with the token sent by the client and returned
|
62 | * from an API Gateway Lambda authorizer (formerly known as a custom authorizer).
|
63 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html
|
64 | */
|
65 | static contextAuthorizerPrincipalId() {
|
66 | return '$context.authorizer.principalId';
|
67 | }
|
68 | /**
|
69 | * The stringified value of the specified key-value pair of the `context` map returned from an API Gateway Lambda authorizer function.
|
70 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html
|
71 | * @param property key of the context map.
|
72 | */
|
73 | static contextAuthorizer(property) {
|
74 | return `$context.authorizer.${property}`;
|
75 | }
|
76 | /**
|
77 | * The AWS endpoint's request ID.
|
78 | */
|
79 | static contextAwsEndpointRequestId() {
|
80 | return '$context.awsEndpointRequestId';
|
81 | }
|
82 | /**
|
83 | * The full domain name used to invoke the API. This should be the same as the incoming `Host` header.
|
84 | */
|
85 | static contextDomainName() {
|
86 | return '$context.domainName';
|
87 | }
|
88 | /**
|
89 | * The first label of the `$context.domainName`. This is often used as a caller/customer identifier.
|
90 | */
|
91 | static contextDomainPrefix() {
|
92 | return '$context.domainPrefix';
|
93 | }
|
94 | /**
|
95 | * A string containing an API Gateway error message.
|
96 | */
|
97 | static contextErrorMessage() {
|
98 | return '$context.error.message';
|
99 | }
|
100 | /**
|
101 | * The quoted value of $context.error.message, namely "$context.error.message".
|
102 | */
|
103 | static contextErrorMessageString() {
|
104 | return '$context.error.messageString';
|
105 | }
|
106 | /**
|
107 | * A type of GatewayResponse. This variable can only be used for simple variable substitution in a GatewayResponse body-mapping template,
|
108 | * which is not processed by the Velocity Template Language engine, and in access logging.
|
109 | *
|
110 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-logging.html
|
111 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/customize-gateway-responses.html
|
112 | */
|
113 | static contextErrorResponseType() {
|
114 | return '$context.error.responseType';
|
115 | }
|
116 | /**
|
117 | * A string containing a detailed validation error message.
|
118 | */
|
119 | static contextErrorValidationErrorString() {
|
120 | return '$context.error.validationErrorString';
|
121 | }
|
122 | /**
|
123 | * The extended ID that API Gateway assigns to the API request, which contains more useful information for debugging/troubleshooting.
|
124 | */
|
125 | static contextExtendedRequestId() {
|
126 | return '$context.extendedRequestId';
|
127 | }
|
128 | /**
|
129 | * The HTTP method used. Valid values include: `DELETE`, `GET`, `HEAD`, `OPTIONS`, `PATCH`, `POST`, and `PUT`.
|
130 | */
|
131 | static contextHttpMethod() {
|
132 | return '$context.httpMethod';
|
133 | }
|
134 | /**
|
135 | * The AWS account ID associated with the request.
|
136 | */
|
137 | static contextIdentityAccountId() {
|
138 | return '$context.identity.accountId';
|
139 | }
|
140 | /**
|
141 | * For API methods that require an API key, this variable is the API key associated with the method request.
|
142 | * For methods that don't require an API key, this variable is
|
143 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html
|
144 | */
|
145 | static contextIdentityApiKey() {
|
146 | return '$context.identity.apiKey';
|
147 | }
|
148 | /**
|
149 | * The API key ID associated with an API request that requires an API key.
|
150 | */
|
151 | static contextIdentityApiKeyId() {
|
152 | return '$context.identity.apiKeyId';
|
153 | }
|
154 | /**
|
155 | * The principal identifier of the caller making the request.
|
156 | */
|
157 | static contextIdentityCaller() {
|
158 | return '$context.identity.caller';
|
159 | }
|
160 | /**
|
161 | * The Amazon Cognito authentication provider used by the caller making the request.
|
162 | * Available only if the request was signed with Amazon Cognito credentials.
|
163 | * @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html
|
164 | */
|
165 | static contextIdentityCognitoAuthenticationProvider() {
|
166 | return '$context.identity.cognitoAuthenticationProvider';
|
167 | }
|
168 | /**
|
169 | * The Amazon Cognito authentication type of the caller making the request.
|
170 | * Available only if the request was signed with Amazon Cognito credentials.
|
171 | */
|
172 | static contextIdentityCognitoAuthenticationType() {
|
173 | return '$context.identity.cognitoAuthenticationType';
|
174 | }
|
175 | /**
|
176 | * The Amazon Cognito identity ID of the caller making the request. Available only if the request was signed with Amazon Cognito credentials.
|
177 | */
|
178 | static contextIdentityCognitoIdentityId() {
|
179 | return '$context.identity.cognitoIdentityId';
|
180 | }
|
181 | /**
|
182 | * The Amazon Cognito identity pool ID of the caller making the request.
|
183 | * Available only if the request was signed with Amazon Cognito credentials.
|
184 | */
|
185 | static contextIdentityCognitoIdentityPoolId() {
|
186 | return '$context.identity.cognitoIdentityPoolId';
|
187 | }
|
188 | /**
|
189 | * The AWS organization ID.
|
190 | */
|
191 | static contextIdentityPrincipalOrgId() {
|
192 | return '$context.identity.principalOrgId';
|
193 | }
|
194 | /**
|
195 | * The source IP address of the TCP connection making the request to API Gateway.
|
196 | * Warning: You should not trust this value if there is any chance that the `X-Forwarded-For` header could be forged.
|
197 | */
|
198 | static contextIdentitySourceIp() {
|
199 | return '$context.identity.sourceIp';
|
200 | }
|
201 | /**
|
202 | * The principal identifier of the user making the request. Used in Lambda authorizers.
|
203 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html
|
204 | */
|
205 | static contextIdentityUser() {
|
206 | return '$context.identity.user';
|
207 | }
|
208 | /**
|
209 | * The User-Agent header of the API caller.
|
210 | */
|
211 | static contextIdentityUserAgent() {
|
212 | return '$context.identity.userAgent';
|
213 | }
|
214 | /**
|
215 | * The Amazon Resource Name (ARN) of the effective user identified after authentication.
|
216 | * @see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html
|
217 | */
|
218 | static contextIdentityUserArn() {
|
219 | return '$context.identity.userArn';
|
220 | }
|
221 | /**
|
222 | * The request path.
|
223 | * For example, for a non-proxy request URL of https://{rest-api-id.execute-api.{region}.amazonaws.com/{stage}/root/child,
|
224 | * this value is /{stage}/root/child.
|
225 | */
|
226 | static contextPath() {
|
227 | return '$context.path';
|
228 | }
|
229 | /**
|
230 | * The request protocol, for example, HTTP/1.1.
|
231 | */
|
232 | static contextProtocol() {
|
233 | return '$context.protocol';
|
234 | }
|
235 | /**
|
236 | * The ID that API Gateway assigns to the API request.
|
237 | */
|
238 | static contextRequestId() {
|
239 | return '$context.requestId';
|
240 | }
|
241 | /**
|
242 | * The request header override.
|
243 | * If this parameter is defined, it contains the headers to be used instead of the HTTP Headers that are defined in the Integration Request pane.
|
244 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-override-request-response-parameters.html
|
245 | *
|
246 | * @param headerName
|
247 | */
|
248 | static contextRequestOverrideHeader(headerName) {
|
249 | return `$context.requestOverride.header.${headerName}`;
|
250 | }
|
251 | /**
|
252 | * The request path override. If this parameter is defined,
|
253 | * it contains the request path to be used instead of the URL Path Parameters that are defined in the Integration Request pane.
|
254 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-override-request-response-parameters.html
|
255 | *
|
256 | * @param pathName
|
257 | */
|
258 | static contextRequestOverridePath(pathName) {
|
259 | return `$context.requestOverride.path.${pathName}`;
|
260 | }
|
261 | /**
|
262 | * The request query string override.
|
263 | * If this parameter is defined, it contains the request query strings to be used instead
|
264 | * of the URL Query String Parameters that are defined in the Integration Request pane.
|
265 | *
|
266 | * @param querystringName
|
267 | */
|
268 | static contextRequestOverrideQuerystring(querystringName) {
|
269 | return `$context.requestOverride.querystring.${querystringName}`;
|
270 | }
|
271 | /**
|
272 | * The response header override.
|
273 | * If this parameter is defined, it contains the header to be returned instead of the Response header
|
274 | * that is defined as the Default mapping in the Integration Response pane.
|
275 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-override-request-response-parameters.html
|
276 | *
|
277 | * @param headerName
|
278 | */
|
279 | static contextResponseOverrideHeader(headerName) {
|
280 | return `$context.responseOverride.header.${headerName}`;
|
281 | }
|
282 | /**
|
283 | * The response status code override.
|
284 | * If this parameter is defined, it contains the status code to be returned instead of the Method response status
|
285 | * that is defined as the Default mapping in the Integration Response pane.
|
286 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-override-request-response-parameters.html
|
287 | */
|
288 | static contextResponseOverrideStatus() {
|
289 | return '$context.responseOverride.status';
|
290 | }
|
291 | /**
|
292 | * The CLF-formatted request time (dd/MMM/yyyy:HH:mm:ss +-hhmm).
|
293 | */
|
294 | static contextRequestTime() {
|
295 | return '$context.requestTime';
|
296 | }
|
297 | /**
|
298 | * The Epoch-formatted request time.
|
299 | */
|
300 | static contextRequestTimeEpoch() {
|
301 | return '$context.requestTimeEpoch';
|
302 | }
|
303 | /**
|
304 | * The identifier that API Gateway assigns to your resource.
|
305 | */
|
306 | static contextResourceId() {
|
307 | return '$context.resourceId';
|
308 | }
|
309 | /**
|
310 | * The path to your resource.
|
311 | * For example, for the non-proxy request URI of `https://{rest-api-id.execute-api.{region}.amazonaws.com/{stage}/root/child`,
|
312 | * The $context.resourcePath value is `/root/child`.
|
313 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-step-by-step.html
|
314 | */
|
315 | static contextResourcePath() {
|
316 | return '$context.resourcePath';
|
317 | }
|
318 | /**
|
319 | * The deployment stage of the API request (for example, `Beta` or `Prod`).
|
320 | */
|
321 | static contextStage() {
|
322 | return '$context.stage';
|
323 | }
|
324 | /**
|
325 | * The response received from AWS WAF: `WAF_ALLOW` or `WAF_BLOCK`. Will not be set if the stage is not associated with a web ACL.
|
326 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-aws-waf.html
|
327 | */
|
328 | static contextWafResponseCode() {
|
329 | return '$context.wafResponseCode';
|
330 | }
|
331 | /**
|
332 | * The complete ARN of the web ACL that is used to decide whether to allow or block the request.
|
333 | * Will not be set if the stage is not associated with a web ACL.
|
334 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-aws-waf.html
|
335 | */
|
336 | static contextWebaclArn() {
|
337 | return '$context.webaclArn';
|
338 | }
|
339 | /**
|
340 | * The trace ID for the X-Ray trace.
|
341 | * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-enabling-xray.html
|
342 | */
|
343 | static contextXrayTraceId() {
|
344 | return '$context.xrayTraceId';
|
345 | }
|
346 | /**
|
347 | * The authorizer latency in ms.
|
348 | */
|
349 | static contextAuthorizerIntegrationLatency() {
|
350 | return '$context.authorizer.integrationLatency';
|
351 | }
|
352 | /**
|
353 | * The integration latency in ms.
|
354 | */
|
355 | static contextIntegrationLatency() {
|
356 | return '$context.integrationLatency';
|
357 | }
|
358 | /**
|
359 | * For Lambda proxy integration, this parameter represents the status code returned from AWS Lambda,
|
360 | * not from the backend Lambda function.
|
361 | */
|
362 | static contextIntegrationStatus() {
|
363 | return '$context.integrationStatus';
|
364 | }
|
365 | /**
|
366 | * The response latency in ms.
|
367 | */
|
368 | static contextResponseLatency() {
|
369 | return '$context.responseLatency';
|
370 | }
|
371 | /**
|
372 | * The response payload length.
|
373 | */
|
374 | static contextResponseLength() {
|
375 | return '$context.responseLength';
|
376 | }
|
377 | /**
|
378 | * The method response status.
|
379 | */
|
380 | static contextStatus() {
|
381 | return '$context.status';
|
382 | }
|
383 | }
|
384 | exports.AccessLogField = AccessLogField;
|
385 | _b = JSII_RTTI_SYMBOL_1;
|
386 | AccessLogField[_b] = { fqn: "@aws-cdk/aws-apigateway.AccessLogField", version: "1.173.0" };
|
387 | /**
|
388 | * factory methods for access log format.
|
389 | */
|
390 | class AccessLogFormat {
|
391 | constructor(format) {
|
392 | this.format = format;
|
393 | }
|
394 | /**
|
395 | * Custom log format.
|
396 | * You can create any log format string. You can easily get the $ context variable by using the methods of AccessLogField.
|
397 | * @param format
|
398 | * @example
|
399 | *
|
400 | * apigateway.AccessLogFormat.custom(JSON.stringify({
|
401 | * requestId: apigateway.AccessLogField.contextRequestId(),
|
402 | * sourceIp: apigateway.AccessLogField.contextIdentitySourceIp(),
|
403 | * method: apigateway.AccessLogField.contextHttpMethod(),
|
404 | * userContext: {
|
405 | * sub: apigateway.AccessLogField.contextAuthorizerClaims('sub'),
|
406 | * email: apigateway.AccessLogField.contextAuthorizerClaims('email')
|
407 | * }
|
408 | * }))
|
409 | */
|
410 | static custom(format) {
|
411 | return new AccessLogFormat(format);
|
412 | }
|
413 | /**
|
414 | * Generate Common Log Format.
|
415 | */
|
416 | static clf() {
|
417 | const requester = [AccessLogField.contextIdentitySourceIp(), AccessLogField.contextIdentityCaller(), AccessLogField.contextIdentityUser()].join(' ');
|
418 | const requestTime = AccessLogField.contextRequestTime();
|
419 | const request = [AccessLogField.contextHttpMethod(), AccessLogField.contextResourcePath(), AccessLogField.contextProtocol()].join(' ');
|
420 | const status = [AccessLogField.contextStatus(), AccessLogField.contextResponseLength(), AccessLogField.contextRequestId()].join(' ');
|
421 | return new AccessLogFormat(`${requester} [${requestTime}] "${request}" ${status}`);
|
422 | }
|
423 | /**
|
424 | * Access log will be produced in the JSON format with a set of fields most useful in the access log. All fields are turned on by default with the
|
425 | * option to turn off specific fields.
|
426 | */
|
427 | static jsonWithStandardFields(fields = {
|
428 | ip: true,
|
429 | user: true,
|
430 | caller: true,
|
431 | requestTime: true,
|
432 | httpMethod: true,
|
433 | resourcePath: true,
|
434 | status: true,
|
435 | protocol: true,
|
436 | responseLength: true,
|
437 | }) {
|
438 | try {
|
439 | jsiiDeprecationWarnings._aws_cdk_aws_apigateway_JsonWithStandardFieldProps(fields);
|
440 | }
|
441 | catch (error) {
|
442 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
443 | Error.captureStackTrace(error, this.jsonWithStandardFields);
|
444 | }
|
445 | throw error;
|
446 | }
|
447 | return this.custom(JSON.stringify({
|
448 | requestId: AccessLogField.contextRequestId(),
|
449 | ip: fields.ip ? AccessLogField.contextIdentitySourceIp() : undefined,
|
450 | user: fields.user ? AccessLogField.contextIdentityUser() : undefined,
|
451 | caller: fields.caller ? AccessLogField.contextIdentityCaller() : undefined,
|
452 | requestTime: fields.requestTime ? AccessLogField.contextRequestTime() : undefined,
|
453 | httpMethod: fields.httpMethod ? AccessLogField.contextHttpMethod() : undefined,
|
454 | resourcePath: fields.resourcePath ? AccessLogField.contextResourcePath() : undefined,
|
455 | status: fields.status ? AccessLogField.contextStatus() : undefined,
|
456 | protocol: fields.protocol ? AccessLogField.contextProtocol() : undefined,
|
457 | responseLength: fields.responseLength ? AccessLogField.contextResponseLength() : undefined,
|
458 | }));
|
459 | }
|
460 | /**
|
461 | * Output a format string to be used with CloudFormation.
|
462 | */
|
463 | toString() {
|
464 | return this.format;
|
465 | }
|
466 | }
|
467 | exports.AccessLogFormat = AccessLogFormat;
|
468 | _c = JSII_RTTI_SYMBOL_1;
|
469 | AccessLogFormat[_c] = { fqn: "@aws-cdk/aws-apigateway.AccessLogFormat", version: "1.173.0" };
|
470 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWxvZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImFjY2Vzcy1sb2cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBdUJBOztHQUVHO0FBQ0gsTUFBYSxzQkFBc0I7SUFDakMsWUFBNkIsUUFBbUI7UUFBbkIsYUFBUSxHQUFSLFFBQVEsQ0FBVztLQUMvQztJQUVEOztPQUVHO0lBQ0ksSUFBSSxDQUFDLE1BQWM7Ozs7Ozs7Ozs7UUFDeEIsT0FBTztZQUNMLGNBQWMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVc7U0FDMUMsQ0FBQztLQUNIOztBQVhILHdEQVlDOzs7QUFFRDs7R0FFRztBQUNILE1BQWEsY0FBYztJQUN6Qjs7T0FFRztJQUNJLE1BQU0sQ0FBQyxnQkFBZ0I7UUFDNUIsT0FBTyw2QkFBNkIsQ0FBQztLQUN0QztJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLFlBQVk7UUFDeEIsT0FBTyxnQkFBZ0IsQ0FBQztLQUN6QjtJQUVEOzs7OztPQUtHO0lBQ0ksTUFBTSxDQUFDLHVCQUF1QixDQUFDLFFBQWdCO1FBQ3BELE9BQU8sOEJBQThCLFFBQVEsRUFBRSxDQUFDO0tBQ2pEO0lBRUQ7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyw0QkFBNEI7UUFDeEMsT0FBTyxpQ0FBaUMsQ0FBQztLQUMxQztJQUVEOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsaUJBQWlCLENBQUMsUUFBZ0I7UUFDOUMsT0FBTyx1QkFBdUIsUUFBUSxFQUFFLENBQUM7S0FDMUM7SUFFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQywyQkFBMkI7UUFDdkMsT0FBTywrQkFBK0IsQ0FBQztLQUN4QztJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLGlCQUFpQjtRQUM3QixPQUFPLHFCQUFxQixDQUFDO0tBQzlCO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsbUJBQW1CO1FBQy9CLE9BQU8sdUJBQXVCLENBQUM7S0FDaEM7SUFFRDs7T0FFRztJQUNJLE1BQU0s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QUFDLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVM7U0FDM0YsQ0FBQyxDQUFDLENBQUM7S0FDTDtJQVdEOztPQUVHO0lBQ0ksUUFBUTtRQUNiLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztLQUNwQjs7QUE3RUgsMENBOEVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSUxvZ0dyb3VwIH0gZnJvbSAnQGF3cy1jZGsvYXdzLWxvZ3MnO1xuaW1wb3J0IHsgSVN0YWdlIH0gZnJvbSAnLi9zdGFnZSc7XG5cbi8qKlxuICogQWNjZXNzIGxvZyBkZXN0aW5hdGlvbiBmb3IgYSBSZXN0QXBpIFN0YWdlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElBY2Nlc3NMb2dEZXN0aW5hdGlvbiB7XG4gIC8qKlxuICAgKiBCaW5kcyB0aGlzIGRlc3RpbmF0aW9uIHRvIHRoZSBSZXN0QXBpIFN0YWdlLlxuICAgKi9cbiAgYmluZChzdGFnZTogSVN0YWdlKTogQWNjZXNzTG9nRGVzdGluYXRpb25Db25maWdcbn1cblxuLyoqXG4gKiBPcHRpb25zIHdoZW4gYmluZGluZyBhIGxvZyBkZXN0aW5hdGlvbiB0byBhIFJlc3RBcGkgU3RhZ2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWNjZXNzTG9nRGVzdGluYXRpb25Db25maWcge1xuICAvKipcbiAgICogVGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSBkZXN0aW5hdGlvbiByZXNvdXJjZVxuICAgKi9cbiAgcmVhZG9ubHkgZGVzdGluYXRpb25Bcm46IHN0cmluZztcbn1cblxuLyoqXG4gKiBVc2UgQ2xvdWRXYXRjaCBMb2dzIGFzIGEgY3VzdG9tIGFjY2VzcyBsb2cgZGVzdGluYXRpb24gZm9yIEFQSSBHYXRld2F5LlxuICovXG5leHBvcnQgY2xhc3MgTG9nR3JvdXBMb2dEZXN0aW5hdGlvbiBpbXBsZW1lbnRzIElBY2Nlc3NMb2dEZXN0aW5hdGlvbiB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgbG9nR3JvdXA6IElMb2dHcm91cCkge1xuICB9XG5cbiAgLyoqXG4gICAqIEJpbmRzIHRoaXMgZGVzdGluYXRpb24gdG8gdGhlIENsb3VkV2F0Y2ggTG9ncy5cbiAgICovXG4gIHB1YmxpYyBiaW5kKF9zdGFnZTogSVN0YWdlKTogQWNjZXNzTG9nRGVzdGluYXRpb25Db25maWcge1xuICAgIHJldHVybiB7XG4gICAgICBkZXN0aW5hdGlvbkFybjogdGhpcy5sb2dHcm91cC5sb2dHcm91cEFybixcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogJGNvbnRleHQgdmFyaWFibGVzIHRoYXQgY2FuIGJlIHVzZWQgdG8gY3VzdG9taXplIGFjY2VzcyBsb2cgcGF0dGVybi5cbiAqL1xuZXhwb3J0IGNsYXNzIEFjY2Vzc0xvZ0ZpZWxkIHtcbiAgLyoqXG4gICAqIFRoZSBBUEkgb3duZXIncyBBV1MgYWNjb3VudCBJRC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dEFjY291bnRJZCgpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LmlkZW50aXR5LmFjY291bnRJZCc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGlkZW50aWZpZXIgQVBJIEdhdGV3YXkgYXNzaWducyB0byB5b3VyIEFQSS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dEFwaUlkKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuYXBpSWQnO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgcHJvcGVydHkgb2YgdGhlIGNsYWltcyByZXR1cm5lZCBmcm9tIHRoZSBBbWF6b24gQ29nbml0byB1c2VyIHBvb2wgYWZ0ZXIgdGhlIG1ldGhvZCBjYWxsZXIgaXMgc3VjY2Vzc2Z1bGx5IGF1dGhlbnRpY2F0ZWQuXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2FwaWdhdGV3YXkvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2FwaWdhdGV3YXktaW50ZWdyYXRlLXdpdGgtY29nbml0by5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBwcm9wZXJ0eSBBIHByb3BlcnR5IGtleSBvZiB0aGUgY2xhaW1zLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0QXV0aG9yaXplckNsYWltcyhwcm9wZXJ0eTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGAkY29udGV4dC5hdXRob3JpemVyLmNsYWltcy4ke3Byb3BlcnR5fWA7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHByaW5jaXBhbCB1c2VyIGlkZW50aWZpY2F0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgdG9rZW4gc2VudCBieSB0aGUgY2xpZW50IGFuZCByZXR1cm5lZFxuICAgKiBmcm9tIGFuIEFQSSBHYXRld2F5IExhbWJkYSBhdXRob3JpemVyIChmb3JtZXJseSBrbm93biBhcyBhIGN1c3RvbSBhdXRob3JpemVyKS5cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvYXBpZ2F0ZXdheS11c2UtbGFtYmRhLWF1dGhvcml6ZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0QXV0aG9yaXplclByaW5jaXBhbElkKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuYXV0aG9yaXplci5wcmluY2lwYWxJZCc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHN0cmluZ2lmaWVkIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQga2V5LXZhbHVlIHBhaXIgb2YgdGhlIGBjb250ZXh0YCBtYXAgcmV0dXJuZWQgZnJvbSBhbiBBUEkgR2F0ZXdheSBMYW1iZGEgYXV0aG9yaXplciBmdW5jdGlvbi5cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvYXBpZ2F0ZXdheS11c2UtbGFtYmRhLWF1dGhvcml6ZXIuaHRtbFxuICAgKiBAcGFyYW0gcHJvcGVydHkga2V5IG9mIHRoZSBjb250ZXh0IG1hcC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dEF1dGhvcml6ZXIocHJvcGVydHk6IHN0cmluZykge1xuICAgIHJldHVybiBgJGNvbnRleHQuYXV0aG9yaXplci4ke3Byb3BlcnR5fWA7XG4gIH1cblxuICAvKipcbiAgICogVGhlIEFXUyBlbmRwb2ludCdzIHJlcXVlc3QgSUQuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRBd3NFbmRwb2ludFJlcXVlc3RJZCgpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LmF3c0VuZHBvaW50UmVxdWVzdElkJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgZnVsbCBkb21haW4gbmFtZSB1c2VkIHRvIGludm9rZSB0aGUgQVBJLiBUaGlzIHNob3VsZCBiZSB0aGUgc2FtZSBhcyB0aGUgaW5jb21pbmcgYEhvc3RgIGhlYWRlci5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dERvbWFpbk5hbWUoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5kb21haW5OYW1lJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgZmlyc3QgbGFiZWwgb2YgdGhlIGAkY29udGV4dC5kb21haW5OYW1lYC4gVGhpcyBpcyBvZnRlbiB1c2VkIGFzIGEgY2FsbGVyL2N1c3RvbWVyIGlkZW50aWZpZXIuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHREb21haW5QcmVmaXgoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5kb21haW5QcmVmaXgnO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3RyaW5nIGNvbnRhaW5pbmcgYW4gQVBJIEdhdGV3YXkgZXJyb3IgbWVzc2FnZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dEVycm9yTWVzc2FnZSgpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LmVycm9yLm1lc3NhZ2UnO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBxdW90ZWQgdmFsdWUgb2YgJGNvbnRleHQuZXJyb3IubWVzc2FnZSwgbmFtZWx5IFwiJGNvbnRleHQuZXJyb3IubWVzc2FnZVwiLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0RXJyb3JNZXNzYWdlU3RyaW5nKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuZXJyb3IubWVzc2FnZVN0cmluZyc7XG4gIH1cblxuICAvKipcbiAgICogQSB0eXBlIG9mIEdhdGV3YXlSZXNwb25zZS4gVGhpcyB2YXJpYWJsZSBjYW4gb25seSBiZSB1c2VkIGZvciBzaW1wbGUgdmFyaWFibGUgc3Vic3RpdHV0aW9uIGluIGEgR2F0ZXdheVJlc3BvbnNlIGJvZHktbWFwcGluZyB0ZW1wbGF0ZSxcbiAgICogd2hpY2ggaXMgbm90IHByb2Nlc3NlZCBieSB0aGUgVmVsb2NpdHkgVGVtcGxhdGUgTGFuZ3VhZ2UgZW5naW5lLCBhbmQgaW4gYWNjZXNzIGxvZ2dpbmcuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2FwaWdhdGV3YXkvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2FwaWdhdGV3YXktd2Vic29ja2V0LWFwaS1sb2dnaW5nLmh0bWxcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvY3VzdG9taXplLWdhdGV3YXktcmVzcG9uc2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dEVycm9yUmVzcG9uc2VUeXBlKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuZXJyb3IucmVzcG9uc2VUeXBlJztcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHN0cmluZyBjb250YWluaW5nIGEgZGV0YWlsZWQgdmFsaWRhdGlvbiBlcnJvciBtZXNzYWdlLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0RXJyb3JWYWxpZGF0aW9uRXJyb3JTdHJpbmcoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5lcnJvci52YWxpZGF0aW9uRXJyb3JTdHJpbmcnO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBleHRlbmRlZCBJRCB0aGF0IEFQSSBHYXRld2F5IGFzc2lnbnMgdG8gdGhlIEFQSSByZXF1ZXN0LCB3aGljaCBjb250YWlucyBtb3JlIHVzZWZ1bCBpbmZvcm1hdGlvbiBmb3IgZGVidWdnaW5nL3Ryb3VibGVzaG9vdGluZy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dEV4dGVuZGVkUmVxdWVzdElkKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuZXh0ZW5kZWRSZXF1ZXN0SWQnO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBIVFRQIG1ldGhvZCB1c2VkLiBWYWxpZCB2YWx1ZXMgaW5jbHVkZTogYERFTEVURWAsIGBHRVRgLCBgSEVBRGAsIGBPUFRJT05TYCwgYFBBVENIYCwgYFBPU1RgLCBhbmQgYFBVVGAuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRIdHRwTWV0aG9kKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuaHR0cE1ldGhvZCc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIEFXUyBhY2NvdW50IElEIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVxdWVzdC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dElkZW50aXR5QWNjb3VudElkKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuaWRlbnRpdHkuYWNjb3VudElkJztcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3IgQVBJIG1ldGhvZHMgdGhhdCByZXF1aXJlIGFuIEFQSSBrZXksIHRoaXMgdmFyaWFibGUgaXMgdGhlIEFQSSBrZXkgYXNzb2NpYXRlZCB3aXRoIHRoZSBtZXRob2QgcmVxdWVzdC5cbiAgICogRm9yIG1ldGhvZHMgdGhhdCBkb24ndCByZXF1aXJlIGFuIEFQSSBrZXksIHRoaXMgdmFyaWFibGUgaXNcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvYXBpLWdhdGV3YXktYXBpLXVzYWdlLXBsYW5zLmh0bWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dElkZW50aXR5QXBpS2V5KCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuaWRlbnRpdHkuYXBpS2V5JztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgQVBJIGtleSBJRCBhc3NvY2lhdGVkIHdpdGggYW4gQVBJIHJlcXVlc3QgdGhhdCByZXF1aXJlcyBhbiBBUEkga2V5LlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0SWRlbnRpdHlBcGlLZXlJZCgpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LmlkZW50aXR5LmFwaUtleUlkJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcHJpbmNpcGFsIGlkZW50aWZpZXIgb2YgdGhlIGNhbGxlciBtYWtpbmcgdGhlIHJlcXVlc3QuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRJZGVudGl0eUNhbGxlcigpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LmlkZW50aXR5LmNhbGxlcic7XG4gIH1cblxuICAvKipcbiAgICogVGhlIEFtYXpvbiBDb2duaXRvIGF1dGhlbnRpY2F0aW9uIHByb3ZpZGVyIHVzZWQgYnkgdGhlIGNhbGxlciBtYWtpbmcgdGhlIHJlcXVlc3QuXG4gICAqIEF2YWlsYWJsZSBvbmx5IGlmIHRoZSByZXF1ZXN0IHdhcyBzaWduZWQgd2l0aCBBbWF6b24gQ29nbml0byBjcmVkZW50aWFscy5cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY29nbml0by9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvY29nbml0by1pZGVudGl0eS5odG1sXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRJZGVudGl0eUNvZ25pdG9BdXRoZW50aWNhdGlvblByb3ZpZGVyKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuaWRlbnRpdHkuY29nbml0b0F1dGhlbnRpY2F0aW9uUHJvdmlkZXInO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBBbWF6b24gQ29nbml0byBhdXRoZW50aWNhdGlvbiB0eXBlIG9mIHRoZSBjYWxsZXIgbWFraW5nIHRoZSByZXF1ZXN0LlxuICAgKiBBdmFpbGFibGUgb25seSBpZiB0aGUgcmVxdWVzdCB3YXMgc2lnbmVkIHdpdGggQW1hem9uIENvZ25pdG8gY3JlZGVudGlhbHMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRJZGVudGl0eUNvZ25pdG9BdXRoZW50aWNhdGlvblR5cGUoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5pZGVudGl0eS5jb2duaXRvQXV0aGVudGljYXRpb25UeXBlJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgQW1hem9uIENvZ25pdG8gaWRlbnRpdHkgSUQgb2YgdGhlIGNhbGxlciBtYWtpbmcgdGhlIHJlcXVlc3QuIEF2YWlsYWJsZSBvbmx5IGlmIHRoZSByZXF1ZXN0IHdhcyBzaWduZWQgd2l0aCBBbWF6b24gQ29nbml0byBjcmVkZW50aWFscy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dElkZW50aXR5Q29nbml0b0lkZW50aXR5SWQoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5pZGVudGl0eS5jb2duaXRvSWRlbnRpdHlJZCc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIEFtYXpvbiBDb2duaXRvIGlkZW50aXR5IHBvb2wgSUQgb2YgdGhlIGNhbGxlciBtYWtpbmcgdGhlIHJlcXVlc3QuXG4gICAqIEF2YWlsYWJsZSBvbmx5IGlmIHRoZSByZXF1ZXN0IHdhcyBzaWduZWQgd2l0aCBBbWF6b24gQ29nbml0byBjcmVkZW50aWFscy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dElkZW50aXR5Q29nbml0b0lkZW50aXR5UG9vbElkKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuaWRlbnRpdHkuY29nbml0b0lkZW50aXR5UG9vbElkJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgQVdTIG9yZ2FuaXphdGlvbiBJRC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dElkZW50aXR5UHJpbmNpcGFsT3JnSWQoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5pZGVudGl0eS5wcmluY2lwYWxPcmdJZCc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHNvdXJjZSBJUCBhZGRyZXNzIG9mIHRoZSBUQ1AgY29ubmVjdGlvbiBtYWtpbmcgdGhlIHJlcXVlc3QgdG8gQVBJIEdhdGV3YXkuXG4gICAqIFdhcm5pbmc6IFlvdSBzaG91bGQgbm90IHRydXN0IHRoaXMgdmFsdWUgaWYgdGhlcmUgaXMgYW55IGNoYW5jZSB0aGF0IHRoZSBgWC1Gb3J3YXJkZWQtRm9yYCBoZWFkZXIgY291bGQgYmUgZm9yZ2VkLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0SWRlbnRpdHlTb3VyY2VJcCgpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LmlkZW50aXR5LnNvdXJjZUlwJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcHJpbmNpcGFsIGlkZW50aWZpZXIgb2YgdGhlIHVzZXIgbWFraW5nIHRoZSByZXF1ZXN0LiBVc2VkIGluIExhbWJkYSBhdXRob3JpemVycy5cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvYXBpLWdhdGV3YXktbGFtYmRhLWF1dGhvcml6ZXItb3V0cHV0Lmh0bWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dElkZW50aXR5VXNlcigpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LmlkZW50aXR5LnVzZXInO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBVc2VyLUFnZW50IGhlYWRlciBvZiB0aGUgQVBJIGNhbGxlci5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dElkZW50aXR5VXNlckFnZW50KCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuaWRlbnRpdHkudXNlckFnZW50JztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIGVmZmVjdGl2ZSB1c2VyIGlkZW50aWZpZWQgYWZ0ZXIgYXV0aGVudGljYXRpb24uXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3VzZXJzLmh0bWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dElkZW50aXR5VXNlckFybigpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LmlkZW50aXR5LnVzZXJBcm4nO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSByZXF1ZXN0IHBhdGguXG4gICAqIEZvciBleGFtcGxlLCBmb3IgYSBub24tcHJveHkgcmVxdWVzdCBVUkwgb2YgaHR0cHM6Ly97cmVzdC1hcGktaWQuZXhlY3V0ZS1hcGkue3JlZ2lvbn0uYW1hem9uYXdzLmNvbS97c3RhZ2V9L3Jvb3QvY2hpbGQsXG4gICAqIHRoaXMgdmFsdWUgaXMgL3tzdGFnZX0vcm9vdC9jaGlsZC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dFBhdGgoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5wYXRoJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcmVxdWVzdCBwcm90b2NvbCwgZm9yIGV4YW1wbGUsIEhUVFAvMS4xLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0UHJvdG9jb2woKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5wcm90b2NvbCc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIElEIHRoYXQgQVBJIEdhdGV3YXkgYXNzaWducyB0byB0aGUgQVBJIHJlcXVlc3QuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRSZXF1ZXN0SWQoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5yZXF1ZXN0SWQnO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSByZXF1ZXN0IGhlYWRlciBvdmVycmlkZS5cbiAgICogSWYgdGhpcyBwYXJhbWV0ZXIgaXMgZGVmaW5lZCwgaXQgY29udGFpbnMgdGhlIGhlYWRlcnMgdG8gYmUgdXNlZCBpbnN0ZWFkIG9mIHRoZSBIVFRQIEhlYWRlcnMgdGhhdCBhcmUgZGVmaW5lZCBpbiB0aGUgSW50ZWdyYXRpb24gUmVxdWVzdCBwYW5lLlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hcGlnYXRld2F5L2xhdGVzdC9kZXZlbG9wZXJndWlkZS9hcGlnYXRld2F5LW92ZXJyaWRlLXJlcXVlc3QtcmVzcG9uc2UtcGFyYW1ldGVycy5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBoZWFkZXJOYW1lXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRSZXF1ZXN0T3ZlcnJpZGVIZWFkZXIoaGVhZGVyTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGAkY29udGV4dC5yZXF1ZXN0T3ZlcnJpZGUuaGVhZGVyLiR7aGVhZGVyTmFtZX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSByZXF1ZXN0IHBhdGggb3ZlcnJpZGUuIElmIHRoaXMgcGFyYW1ldGVyIGlzIGRlZmluZWQsXG4gICAqIGl0IGNvbnRhaW5zIHRoZSByZXF1ZXN0IHBhdGggdG8gYmUgdXNlZCBpbnN0ZWFkIG9mIHRoZSBVUkwgUGF0aCBQYXJhbWV0ZXJzIHRoYXQgYXJlIGRlZmluZWQgaW4gdGhlIEludGVncmF0aW9uIFJlcXVlc3QgcGFuZS5cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvYXBpZ2F0ZXdheS1vdmVycmlkZS1yZXF1ZXN0LXJlc3BvbnNlLXBhcmFtZXRlcnMuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gcGF0aE5hbWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dFJlcXVlc3RPdmVycmlkZVBhdGgocGF0aE5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiBgJGNvbnRleHQucmVxdWVzdE92ZXJyaWRlLnBhdGguJHtwYXRoTmFtZX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSByZXF1ZXN0IHF1ZXJ5IHN0cmluZyBvdmVycmlkZS5cbiAgICogSWYgdGhpcyBwYXJhbWV0ZXIgaXMgZGVmaW5lZCwgaXQgY29udGFpbnMgdGhlIHJlcXVlc3QgcXVlcnkgc3RyaW5ncyB0byBiZSB1c2VkIGluc3RlYWRcbiAgICogb2YgdGhlIFVSTCBRdWVyeSBTdHJpbmcgUGFyYW1ldGVycyB0aGF0IGFyZSBkZWZpbmVkIGluIHRoZSBJbnRlZ3JhdGlvbiBSZXF1ZXN0IHBhbmUuXG4gICAqXG4gICAqIEBwYXJhbSBxdWVyeXN0cmluZ05hbWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dFJlcXVlc3RPdmVycmlkZVF1ZXJ5c3RyaW5nKHF1ZXJ5c3RyaW5nTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGAkY29udGV4dC5yZXF1ZXN0T3ZlcnJpZGUucXVlcnlzdHJpbmcuJHtxdWVyeXN0cmluZ05hbWV9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcmVzcG9uc2UgaGVhZGVyIG92ZXJyaWRlLlxuICAgKiBJZiB0aGlzIHBhcmFtZXRlciBpcyBkZWZpbmVkLCBpdCBjb250YWlucyB0aGUgaGVhZGVyIHRvIGJlIHJldHVybmVkIGluc3RlYWQgb2YgdGhlIFJlc3BvbnNlIGhlYWRlclxuICAgKiB0aGF0IGlzIGRlZmluZWQgYXMgdGhlIERlZmF1bHQgbWFwcGluZyBpbiB0aGUgSW50ZWdyYXRpb24gUmVzcG9uc2UgcGFuZS5cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvYXBpZ2F0ZXdheS1vdmVycmlkZS1yZXF1ZXN0LXJlc3BvbnNlLXBhcmFtZXRlcnMuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gaGVhZGVyTmFtZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0UmVzcG9uc2VPdmVycmlkZUhlYWRlcihoZWFkZXJOYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYCRjb250ZXh0LnJlc3BvbnNlT3ZlcnJpZGUuaGVhZGVyLiR7aGVhZGVyTmFtZX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSByZXNwb25zZSBzdGF0dXMgY29kZSBvdmVycmlkZS5cbiAgICogSWYgdGhpcyBwYXJhbWV0ZXIgaXMgZGVmaW5lZCwgaXQgY29udGFpbnMgdGhlIHN0YXR1cyBjb2RlIHRvIGJlIHJldHVybmVkIGluc3RlYWQgb2YgdGhlIE1ldGhvZCByZXNwb25zZSBzdGF0dXNcbiAgICogdGhhdCBpcyBkZWZpbmVkIGFzIHRoZSBEZWZhdWx0IG1hcHBpbmcgaW4gdGhlIEludGVncmF0aW9uIFJlc3BvbnNlIHBhbmUuXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2FwaWdhdGV3YXkvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2FwaWdhdGV3YXktb3ZlcnJpZGUtcmVxdWVzdC1yZXNwb25zZS1wYXJhbWV0ZXJzLmh0bWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dFJlc3BvbnNlT3ZlcnJpZGVTdGF0dXMoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5yZXNwb25zZU92ZXJyaWRlLnN0YXR1cyc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIENMRi1mb3JtYXR0ZWQgcmVxdWVzdCB0aW1lIChkZC9NTU0veXl5eTpISDptbTpzcyArLWhobW0pLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0UmVxdWVzdFRpbWUoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5yZXF1ZXN0VGltZSc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIEVwb2NoLWZvcm1hdHRlZCByZXF1ZXN0IHRpbWUuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRSZXF1ZXN0VGltZUVwb2NoKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQucmVxdWVzdFRpbWVFcG9jaCc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGlkZW50aWZpZXIgdGhhdCBBUEkgR2F0ZXdheSBhc3NpZ25zIHRvIHlvdXIgcmVzb3VyY2UuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRSZXNvdXJjZUlkKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQucmVzb3VyY2VJZCc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHBhdGggdG8geW91ciByZXNvdXJjZS5cbiAgICogRm9yIGV4YW1wbGUsIGZvciB0aGUgbm9uLXByb3h5IHJlcXVlc3QgVVJJIG9mIGBodHRwczovL3tyZXN0LWFwaS1pZC5leGVjdXRlLWFwaS57cmVnaW9ufS5hbWF6b25hd3MuY29tL3tzdGFnZX0vcm9vdC9jaGlsZGAsXG4gICAqIFRoZSAkY29udGV4dC5yZXNvdXJjZVBhdGggdmFsdWUgaXMgYC9yb290L2NoaWxkYC5cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvYXBpLWdhdGV3YXktY3JlYXRlLWFwaS1zdGVwLWJ5LXN0ZXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0UmVzb3VyY2VQYXRoKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQucmVzb3VyY2VQYXRoJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgZGVwbG95bWVudCBzdGFnZSBvZiB0aGUgQVBJIHJlcXVlc3QgKGZvciBleGFtcGxlLCBgQmV0YWAgb3IgYFByb2RgKS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dFN0YWdlKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQuc3RhZ2UnO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSByZXNwb25zZSByZWNlaXZlZCBmcm9tIEFXUyBXQUY6IGBXQUZfQUxMT1dgIG9yIGBXQUZfQkxPQ0tgLiBXaWxsIG5vdCBiZSBzZXQgaWYgdGhlIHN0YWdlIGlzIG5vdCBhc3NvY2lhdGVkIHdpdGggYSB3ZWIgQUNMLlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hcGlnYXRld2F5L2xhdGVzdC9kZXZlbG9wZXJndWlkZS9hcGlnYXRld2F5LWNvbnRyb2wtYWNjZXNzLWF3cy13YWYuaHRtbFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0V2FmUmVzcG9uc2VDb2RlKCkge1xuICAgIHJldHVybiAnJGNvbnRleHQud2FmUmVzcG9uc2VDb2RlJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgY29tcGxldGUgQVJOIG9mIHRoZSB3ZWIgQUNMIHRoYXQgaXMgdXNlZCB0byBkZWNpZGUgd2hldGhlciB0byBhbGxvdyBvciBibG9jayB0aGUgcmVxdWVzdC5cbiAgICogV2lsbCBub3QgYmUgc2V0IGlmIHRoZSBzdGFnZSBpcyBub3QgYXNzb2NpYXRlZCB3aXRoIGEgd2ViIEFDTC5cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvYXBpZ2F0ZXdheS1jb250cm9sLWFjY2Vzcy1hd3Mtd2FmLmh0bWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dFdlYmFjbEFybigpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LndlYmFjbEFybic7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHRyYWNlIElEIGZvciB0aGUgWC1SYXkgdHJhY2UuXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2FwaWdhdGV3YXkvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2FwaWdhdGV3YXktZW5hYmxpbmcteHJheS5odG1sXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRYcmF5VHJhY2VJZCgpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LnhyYXlUcmFjZUlkJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYXV0aG9yaXplciBsYXRlbmN5IGluIG1zLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0QXV0aG9yaXplckludGVncmF0aW9uTGF0ZW5jeSgpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LmF1dGhvcml6ZXIuaW50ZWdyYXRpb25MYXRlbmN5JztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgaW50ZWdyYXRpb24gbGF0ZW5jeSBpbiBtcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dEludGVncmF0aW9uTGF0ZW5jeSgpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LmludGVncmF0aW9uTGF0ZW5jeSc7XG4gIH1cblxuICAvKipcbiAgICogRm9yIExhbWJkYSBwcm94eSBpbnRlZ3JhdGlvbiwgdGhpcyBwYXJhbWV0ZXIgcmVwcmVzZW50cyB0aGUgc3RhdHVzIGNvZGUgcmV0dXJuZWQgZnJvbSBBV1MgTGFtYmRhLFxuICAgKiBub3QgZnJvbSB0aGUgYmFja2VuZCBMYW1iZGEgZnVuY3Rpb24uXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRJbnRlZ3JhdGlvblN0YXR1cygpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LmludGVncmF0aW9uU3RhdHVzJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcmVzcG9uc2UgbGF0ZW5jeSBpbiBtcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dFJlc3BvbnNlTGF0ZW5jeSgpIHtcbiAgICByZXR1cm4gJyRjb250ZXh0LnJlc3BvbnNlTGF0ZW5jeSc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHJlc3BvbnNlIHBheWxvYWQgbGVuZ3RoLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250ZXh0UmVzcG9uc2VMZW5ndGgoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5yZXNwb25zZUxlbmd0aCc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG1ldGhvZCByZXNwb25zZSBzdGF0dXMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnRleHRTdGF0dXMoKSB7XG4gICAgcmV0dXJuICckY29udGV4dC5zdGF0dXMnO1xuICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgY29udHJvbGxpbmcgaXRlbXMgb3V0cHV0IGluIEpTT04gc3RhbmRhcmQgZm9ybWF0XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSnNvbldpdGhTdGFuZGFyZEZpZWxkUHJvcHMge1xuICAvKipcbiAgICogSWYgdGhpcyBmbGFnIGlzIGVuYWJsZWQsIHRoZSBzb3VyY2UgSVAgb2YgcmVxdWVzdCB3aWxsIGJlIG91dHB1dCB0byB0aGUgbG9nXG4gICAqL1xuICByZWFkb25seSBpcDogYm9vbGVhbixcbiAgLyoqXG4gICAqIElmIHRoaXMgZmxhZyBpcyBlbmFibGVkLCB0aGUgcHJpbmNpcGFsIGlkZW50aWZpZXIgb2YgdGhlIGNhbGxlciB3aWxsIGJlIG91dHB1dCB0byB0aGUgbG9nXG4gICAqL1xuICByZWFkb25seSBjYWxsZXI6IGJvb2xlYW4sXG4gIC8qKlxuICAgKiBJZiB0aGlzIGZsYWcgaXMgZW5hYmxlZCwgdGhlIHByaW5jaXBhbCBpZGVudGlmaWVyIG9mIHRoZSB1c2VyIHdpbGwgYmUgb3V0cHV0IHRvIHRoZSBsb2dcbiAgICovXG4gIHJlYWRvbmx5IHVzZXI6IGJvb2xlYW4sXG4gIC8qKlxuICAgKiBJZiB0aGlzIGZsYWcgaXMgZW5hYmxlZCwgdGhlIENMRi1mb3JtYXR0ZWQgcmVxdWVzdCB0aW1lKChkZC9NTU0veXl5eTpISDptbTpzcyArLWhobW0pIHdpbGwgYmUgb3V0cHV0IHRvIHRoZSBsb2dcbiAgICovXG4gIHJlYWRvbmx5IHJlcXVlc3RUaW1lOiBib29sZWFuLFxuICAvKipcbiAgICogSWYgdGhpcyBmbGFnIGlzIGVuYWJsZWQsIHRoZSBodHRwIG1ldGhvZCB3aWxsIGJlIG91dHB1dCB0byB0aGUgbG9nXG4gICAqL1xuICByZWFkb25seSBodHRwTWV0aG9kOiBib29sZWFuLFxuICAvKipcbiAgICogSWYgdGhpcyBmbGFnIGlzIGVuYWJsZWQsIHRoZSBwYXRoIHRvIHlvdXIgcmVzb3VyY2Ugd2lsbCBiZSBvdXRwdXQgdG8gdGhlIGxvZ1xuICAgKi9cbiAgcmVhZG9ubHkgcmVzb3VyY2VQYXRoOiBib29sZWFuLFxuICAvKipcbiAgICogSWYgdGhpcyBmbGFnIGlzIGVuYWJsZWQsIHRoZSBtZXRob2QgcmVzcG9uc2Ugc3RhdHVzIHdpbGwgYmUgb3V0cHV0IHRvIHRoZSBsb2dcbiAgICovXG4gIHJlYWRvbmx5IHN0YXR1czogYm9vbGVhbixcbiAgLyoqXG4gICAqIElmIHRoaXMgZmxhZyBpcyBlbmFibGVkLCB0aGUgcmVxdWVzdCBwcm90b2NvbCB3aWxsIGJlIG91dHB1dCB0byB0aGUgbG9nXG4gICAqL1xuICByZWFkb25seSBwcm90b2NvbDogYm9vbGVhbixcbiAgLyoqXG4gICAqIElmIHRoaXMgZmxhZyBpcyBlbmFibGVkLCB0aGUgcmVzcG9uc2UgcGF5bG9hZCBsZW5ndGggd2lsbCBiZSBvdXRwdXQgdG8gdGhlIGxvZ1xuICAgKi9cbiAgcmVhZG9ubHkgcmVzcG9uc2VMZW5ndGg6IGJvb2xlYW5cbn1cblxuLyoqXG4gKiBmYWN0b3J5IG1ldGhvZHMgZm9yIGFjY2VzcyBsb2cgZm9ybWF0LlxuICovXG5leHBvcnQgY2xhc3MgQWNjZXNzTG9nRm9ybWF0IHtcbiAgLyoqXG4gICAqIEN1c3RvbSBsb2cgZm9ybWF0LlxuICAgKiBZb3UgY2FuIGNyZWF0ZSBhbnkgbG9nIGZvcm1hdCBzdHJpbmcuIFlvdSBjYW4gZWFzaWx5IGdldCB0aGUgJCBjb250ZXh0IHZhcmlhYmxlIGJ5IHVzaW5nIHRoZSBtZXRob2RzIG9mIEFjY2Vzc0xvZ0ZpZWxkLlxuICAgKiBAcGFyYW0gZm9ybWF0XG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqICBhcGlnYXRld2F5LkFjY2Vzc0xvZ0Zvcm1hdC5jdXN0b20oSlNPTi5zdHJpbmdpZnkoe1xuICAgKiAgICAgIHJlcXVlc3RJZDogYXBpZ2F0ZXdheS5BY2Nlc3NMb2dGaWVsZC5jb250ZXh0UmVxdWVzdElkKCksXG4gICAqICAgICAgc291cmNlSXA6IGFwaWdhdGV3YXkuQWNjZXNzTG9nRmllbGQuY29udGV4dElkZW50aXR5U291cmNlSXAoKSxcbiAgICogICAgICBtZXRob2Q6IGFwaWdhdGV3YXkuQWNjZXNzTG9nRmllbGQuY29udGV4dEh0dHBNZXRob2QoKSxcbiAgICogICAgICB1c2VyQ29udGV4dDoge1xuICAgKiAgICAgICAgc3ViOiBhcGlnYXRld2F5LkFjY2Vzc0xvZ0ZpZWxkLmNvbnRleHRBdXRob3JpemVyQ2xhaW1zKCdzdWInKSxcbiAgICogICAgICAgIGVtYWlsOiBhcGlnYXRld2F5LkFjY2Vzc0xvZ0ZpZWxkLmNvbnRleHRBdXRob3JpemVyQ2xhaW1zKCdlbWFpbCcpXG4gICAqICAgICAgfVxuICAgKiAgIH0pKVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjdXN0b20oZm9ybWF0OiBzdHJpbmcpOiBBY2Nlc3NMb2dGb3JtYXQge1xuICAgIHJldHVybiBuZXcgQWNjZXNzTG9nRm9ybWF0KGZvcm1hdCk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgQ29tbW9uIExvZyBGb3JtYXQuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNsZigpOiBBY2Nlc3NMb2dGb3JtYXQge1xuICAgIGNvbnN0IHJlcXVlc3RlciA9IFtBY2Nlc3NMb2dGaWVsZC5jb250ZXh0SWRlbnRpdHlTb3VyY2VJcCgpLCBBY2Nlc3NMb2dGaWVsZC5jb250ZXh0SWRlbnRpdHlDYWxsZXIoKSwgQWNjZXNzTG9nRmllbGQuY29udGV4dElkZW50aXR5VXNlcigpXS5qb2luKCcgJyk7XG4gICAgY29uc3QgcmVxdWVzdFRpbWUgPSBBY2Nlc3NMb2dGaWVsZC5jb250ZXh0UmVxdWVzdFRpbWUoKTtcbiAgICBjb25zdCByZXF1ZXN0ID0gW0FjY2Vzc0xvZ0ZpZWxkLmNvbnRleHRIdHRwTWV0aG9kKCksIEFjY2Vzc0xvZ0ZpZWxkLmNvbnRleHRSZXNvdXJjZVBhdGgoKSwgQWNjZXNzTG9nRmllbGQuY29udGV4dFByb3RvY29sKCldLmpvaW4oJyAnKTtcbiAgICBjb25zdCBzdGF0dXMgPSBbQWNjZXNzTG9nRmllbGQuY29udGV4dFN0YXR1cygpLCBBY2Nlc3NMb2dGaWVsZC5jb250ZXh0UmVzcG9uc2VMZW5ndGgoKSwgQWNjZXNzTG9nRmllbGQuY29udGV4dFJlcXVlc3RJZCgpXS5qb2luKCcgJyk7XG5cbiAgICByZXR1cm4gbmV3IEFjY2Vzc0xvZ0Zvcm1hdChgJHtyZXF1ZXN0ZXJ9IFske3JlcXVlc3RUaW1lfV0gXCIke3JlcXVlc3R9XCIgJHtzdGF0dXN9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWNjZXNzIGxvZyB3aWxsIGJlIHByb2R1Y2VkIGluIHRoZSBKU09OIGZvcm1hdCB3aXRoIGEgc2V0IG9mIGZpZWxkcyBtb3N0IHVzZWZ1bCBpbiB0aGUgYWNjZXNzIGxvZy4gQWxsIGZpZWxkcyBhcmUgdHVybmVkIG9uIGJ5IGRlZmF1bHQgd2l0aCB0aGVcbiAgICogb3B0aW9uIHRvIHR1cm4gb2ZmIHNwZWNpZmljIGZpZWxkcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMganNvbldpdGhTdGFuZGFyZEZpZWxkcyhcbiAgICBmaWVsZHM6IEpzb25XaXRoU3RhbmRhcmRGaWVsZFByb3BzID0ge1xuICAgICAgaXA6IHRydWUsXG4gICAgICB1c2VyOiB0cnVlLFxuICAgICAgY2FsbGVyOiB0cnVlLFxuICAgICAgcmVxdWVzdFRpbWU6IHRydWUsXG4gICAgICBodHRwTWV0aG9kOiB0cnVlLFxuICAgICAgcmVzb3VyY2VQYXRoOiB0cnVlLFxuICAgICAgc3RhdHVzOiB0cnVlLFxuICAgICAgcHJvdG9jb2w6IHRydWUsXG4gICAgICByZXNwb25zZUxlbmd0aDogdHJ1ZSxcbiAgICB9KTogQWNjZXNzTG9nRm9ybWF0IHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b20oSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgcmVxdWVzdElkOiBBY2Nlc3NMb2dGaWVsZC5jb250ZXh0UmVxdWVzdElkKCksXG4gICAgICBpcDogZmllbGRzLmlwID8gQWNjZXNzTG9nRmllbGQuY29udGV4dElkZW50aXR5U291cmNlSXAoKSA6IHVuZGVmaW5lZCxcbiAgICAgIHVzZXI6IGZpZWxkcy51c2VyID8gQWNjZXNzTG9nRmllbGQuY29udGV4dElkZW50aXR5VXNlcigpIDogdW5kZWZpbmVkLFxuICAgICAgY2FsbGVyOiBmaWVsZHMuY2FsbGVyID8gQWNjZXNzTG9nRmllbGQuY29udGV4dElkZW50aXR5Q2FsbGVyKCkgOiB1bmRlZmluZWQsXG4gICAgICByZXF1ZXN0VGltZTogZmllbGRzLnJlcXVlc3RUaW1lID8gQWNjZXNzTG9nRmllbGQuY29udGV4dFJlcXVlc3RUaW1lKCkgOiB1bmRlZmluZWQsXG4gICAgICBodHRwTWV0aG9kOiBmaWVsZHMuaHR0cE1ldGhvZCA/IEFjY2Vzc0xvZ0ZpZWxkLmNvbnRleHRIdHRwTWV0aG9kKCkgOiB1bmRlZmluZWQsXG4gICAgICByZXNvdXJjZVBhdGg6IGZpZWxkcy5yZXNvdXJjZVBhdGggPyBBY2Nlc3NMb2dGaWVsZC5jb250ZXh0UmVzb3VyY2VQYXRoKCkgOiB1bmRlZmluZWQsXG4gICAgICBzdGF0dXM6IGZpZWxkcy5zdGF0dXMgPyBBY2Nlc3NMb2dGaWVsZC5jb250ZXh0U3RhdHVzKCkgOiB1bmRlZmluZWQsXG4gICAgICBwcm90b2NvbDogZmllbGRzLnByb3RvY29sID8gQWNjZXNzTG9nRmllbGQuY29udGV4dFByb3RvY29sKCkgOiB1bmRlZmluZWQsXG4gICAgICByZXNwb25zZUxlbmd0aDogZmllbGRzLnJlc3BvbnNlTGVuZ3RoID8gQWNjZXNzTG9nRmllbGQuY29udGV4dFJlc3BvbnNlTGVuZ3RoKCkgOiB1bmRlZmluZWQsXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgQVBJIEdhdGV3YXkgY3VzdG9tIGFjY2VzcyBsb2cgZm9ybWF0XG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGZvcm1hdDogc3RyaW5nO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoZm9ybWF0OiBzdHJpbmcpIHtcbiAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBPdXRwdXQgYSBmb3JtYXQgc3RyaW5nIHRvIGJlIHVzZWQgd2l0aCBDbG91ZEZvcm1hdGlvbi5cbiAgICovXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmZvcm1hdDtcbiAgfVxufVxuIl19 |
\ | No newline at end of file |