@aws-cdk/aws-bedrock-agentcore-alpha 2.221.0-alpha.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.
- package/.eslintrc.js +4 -0
- package/.jsii +12000 -0
- package/.jsii.tabl.json.gz +0 -0
- package/.warnings.jsii.js +183 -0
- package/LICENSE +201 -0
- package/NOTICE +2 -0
- package/README.md +796 -0
- package/agentcore/index.d.ts +11 -0
- package/agentcore/index.js +36 -0
- package/agentcore/network/network-configuration.d.ts +152 -0
- package/agentcore/network/network-configuration.js +234 -0
- package/agentcore/runtime/perms.d.ts +67 -0
- package/agentcore/runtime/perms.js +101 -0
- package/agentcore/runtime/runtime-artifact.d.ts +42 -0
- package/agentcore/runtime/runtime-artifact.js +90 -0
- package/agentcore/runtime/runtime-authorizer-configuration.d.ts +62 -0
- package/agentcore/runtime/runtime-authorizer-configuration.js +165 -0
- package/agentcore/runtime/runtime-base.d.ts +309 -0
- package/agentcore/runtime/runtime-base.js +207 -0
- package/agentcore/runtime/runtime-endpoint-base.d.ts +130 -0
- package/agentcore/runtime/runtime-endpoint-base.js +31 -0
- package/agentcore/runtime/runtime-endpoint.d.ts +182 -0
- package/agentcore/runtime/runtime-endpoint.js +372 -0
- package/agentcore/runtime/runtime.d.ts +230 -0
- package/agentcore/runtime/runtime.js +590 -0
- package/agentcore/runtime/types.d.ts +16 -0
- package/agentcore/runtime/types.js +21 -0
- package/agentcore/runtime/validation-helpers.d.ts +37 -0
- package/agentcore/runtime/validation-helpers.js +85 -0
- package/agentcore/tools/browser.d.ts +519 -0
- package/agentcore/tools/browser.js +641 -0
- package/agentcore/tools/code-interpreter.d.ts +447 -0
- package/agentcore/tools/code-interpreter.js +553 -0
- package/agentcore/tools/perms.d.ts +74 -0
- package/agentcore/tools/perms.js +122 -0
- package/agentcore/tools/validation-helpers.d.ts +37 -0
- package/agentcore/tools/validation-helpers.js +85 -0
- package/jest.config.js +2 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +22 -0
- package/package.json +122 -0
- package/rosetta/_generated.ts-fixture +6 -0
- package/rosetta/default.ts-fixture +19 -0
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
3
|
+
var useValue = arguments.length > 2;
|
|
4
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
5
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
6
|
+
}
|
|
7
|
+
return useValue ? value : void 0;
|
|
8
|
+
};
|
|
9
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
10
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
11
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
12
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
13
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
14
|
+
var _, done = false;
|
|
15
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
16
|
+
var context = {};
|
|
17
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
18
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
19
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
20
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
21
|
+
if (kind === "accessor") {
|
|
22
|
+
if (result === void 0) continue;
|
|
23
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
24
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
25
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
26
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
27
|
+
}
|
|
28
|
+
else if (_ = accept(result)) {
|
|
29
|
+
if (kind === "field") initializers.unshift(_);
|
|
30
|
+
else descriptor[key] = _;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
34
|
+
done = true;
|
|
35
|
+
};
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.Runtime = void 0;
|
|
38
|
+
const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
|
|
39
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
40
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
41
|
+
const bedrockagentcore = require("aws-cdk-lib/aws-bedrockagentcore");
|
|
42
|
+
const ec2 = require("aws-cdk-lib/aws-ec2");
|
|
43
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
44
|
+
const metadata_resource_1 = require("aws-cdk-lib/core/lib/metadata-resource");
|
|
45
|
+
const prop_injectable_1 = require("aws-cdk-lib/core/lib/prop-injectable");
|
|
46
|
+
const perms_1 = require("./perms");
|
|
47
|
+
const runtime_base_1 = require("./runtime-base");
|
|
48
|
+
const runtime_endpoint_1 = require("./runtime-endpoint");
|
|
49
|
+
const network_configuration_1 = require("../network/network-configuration");
|
|
50
|
+
const types_1 = require("./types");
|
|
51
|
+
const validation_helpers_1 = require("./validation-helpers");
|
|
52
|
+
/******************************************************************************
|
|
53
|
+
* Class
|
|
54
|
+
*****************************************************************************/
|
|
55
|
+
/**
|
|
56
|
+
* Bedrock Agent Core Runtime
|
|
57
|
+
* Enables running containerized agents with specific network configurations,
|
|
58
|
+
* security settings, and runtime artifacts.
|
|
59
|
+
*
|
|
60
|
+
* @resource AWS::BedrockAgentCore::Runtime
|
|
61
|
+
* @see https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime.html
|
|
62
|
+
*/
|
|
63
|
+
let Runtime = (() => {
|
|
64
|
+
let _classDecorators = [prop_injectable_1.propertyInjectable];
|
|
65
|
+
let _classDescriptor;
|
|
66
|
+
let _classExtraInitializers = [];
|
|
67
|
+
let _classThis;
|
|
68
|
+
let _classSuper = runtime_base_1.RuntimeBase;
|
|
69
|
+
let _instanceExtraInitializers = [];
|
|
70
|
+
let _addEndpoint_decorators;
|
|
71
|
+
var Runtime = class extends _classSuper {
|
|
72
|
+
static { _classThis = this; }
|
|
73
|
+
static {
|
|
74
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
75
|
+
_addEndpoint_decorators = [(0, metadata_resource_1.MethodMetadata)()];
|
|
76
|
+
__esDecorate(this, null, _addEndpoint_decorators, { kind: "method", name: "addEndpoint", static: false, private: false, access: { has: obj => "addEndpoint" in obj, get: obj => obj.addEndpoint }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
77
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
78
|
+
Runtime = _classThis = _classDescriptor.value;
|
|
79
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
80
|
+
}
|
|
81
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-bedrock-agentcore-alpha.Runtime", version: "2.221.0-alpha.0" };
|
|
82
|
+
/** Uniquely identifies this class. */
|
|
83
|
+
static PROPERTY_INJECTION_ID = '@aws-cdk.aws-bedrock-agentcore-alpha.Runtime';
|
|
84
|
+
/**
|
|
85
|
+
* Import an existing Agent Runtime using attributes
|
|
86
|
+
* This allows you to reference an Agent Runtime that was created outside of CDK
|
|
87
|
+
*
|
|
88
|
+
* @param scope The construct scope
|
|
89
|
+
* @param id The construct id
|
|
90
|
+
* @param attrs The attributes of the existing Agent Runtime
|
|
91
|
+
* @returns An IBedrockAgentRuntime instance representing the imported runtime
|
|
92
|
+
*/
|
|
93
|
+
static fromAgentRuntimeAttributes(scope, id, attrs) {
|
|
94
|
+
try {
|
|
95
|
+
jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_AgentRuntimeAttributes(attrs);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
99
|
+
Error.captureStackTrace(error, this.fromAgentRuntimeAttributes);
|
|
100
|
+
}
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
class ImportedBedrockAgentRuntime extends runtime_base_1.RuntimeBase {
|
|
104
|
+
agentRuntimeArn = attrs.agentRuntimeArn;
|
|
105
|
+
agentRuntimeId = attrs.agentRuntimeId;
|
|
106
|
+
agentRuntimeName = attrs.agentRuntimeName;
|
|
107
|
+
agentRuntimeVersion = attrs.agentRuntimeVersion;
|
|
108
|
+
agentStatus = attrs.agentStatus;
|
|
109
|
+
description = attrs.description;
|
|
110
|
+
createdAt = attrs.createdAt;
|
|
111
|
+
lastUpdatedAt = attrs.lastUpdatedAt;
|
|
112
|
+
role;
|
|
113
|
+
grantPrincipal;
|
|
114
|
+
constructor(s, i) {
|
|
115
|
+
super(s, i);
|
|
116
|
+
this.role = iam.Role.fromRoleArn(this, 'Role', attrs.roleArn);
|
|
117
|
+
this.grantPrincipal = this.role;
|
|
118
|
+
if (attrs.securityGroups) {
|
|
119
|
+
this._connections = new ec2.Connections({
|
|
120
|
+
securityGroups: attrs.securityGroups,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return new ImportedBedrockAgentRuntime(scope, id);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The ARN of the agent runtime
|
|
129
|
+
* @attribute
|
|
130
|
+
* @returns a token representing the ARN of this agent runtime
|
|
131
|
+
*/
|
|
132
|
+
agentRuntimeArn = __runInitializers(this, _instanceExtraInitializers);
|
|
133
|
+
/**
|
|
134
|
+
* The unique identifier of the agent runtime
|
|
135
|
+
* @attribute
|
|
136
|
+
* @returns a token representing the ID of this agent runtime
|
|
137
|
+
*/
|
|
138
|
+
agentRuntimeId;
|
|
139
|
+
/**
|
|
140
|
+
* The name of the agent runtime
|
|
141
|
+
* @attribute
|
|
142
|
+
* @returns a token representing the name of this agent runtime
|
|
143
|
+
*/
|
|
144
|
+
agentRuntimeName;
|
|
145
|
+
role;
|
|
146
|
+
/**
|
|
147
|
+
* The version of the agent runtime
|
|
148
|
+
* @attribute
|
|
149
|
+
* @returns a token representing the version of this agent runtime
|
|
150
|
+
*/
|
|
151
|
+
agentRuntimeVersion;
|
|
152
|
+
/**
|
|
153
|
+
* The status of the agent runtime
|
|
154
|
+
* @attribute
|
|
155
|
+
* @returns a token representing the status of this agent runtime
|
|
156
|
+
*/
|
|
157
|
+
agentStatus;
|
|
158
|
+
/**
|
|
159
|
+
* Optional description for the agent runtime
|
|
160
|
+
*/
|
|
161
|
+
description;
|
|
162
|
+
/**
|
|
163
|
+
* The timestamp when the agent runtime was created
|
|
164
|
+
* @attribute
|
|
165
|
+
* @returns a token representing the creation timestamp of this agent runtime
|
|
166
|
+
*/
|
|
167
|
+
createdAt;
|
|
168
|
+
/**
|
|
169
|
+
* The timestamp when the agent runtime was last updated
|
|
170
|
+
* @attribute
|
|
171
|
+
* @returns a token representing the last update timestamp of this agent runtime
|
|
172
|
+
*/
|
|
173
|
+
lastUpdatedAt;
|
|
174
|
+
grantPrincipal;
|
|
175
|
+
runtimeResource;
|
|
176
|
+
/**
|
|
177
|
+
* The artifact configuration for the agent runtime
|
|
178
|
+
*/
|
|
179
|
+
agentRuntimeArtifact;
|
|
180
|
+
networkConfiguration;
|
|
181
|
+
protocolConfiguration;
|
|
182
|
+
authorizerConfiguration;
|
|
183
|
+
constructor(scope, id, props) {
|
|
184
|
+
super(scope, id);
|
|
185
|
+
try {
|
|
186
|
+
jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_RuntimeProps(props);
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
190
|
+
Error.captureStackTrace(error, Runtime);
|
|
191
|
+
}
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
// CDK Analytics Telemetry
|
|
195
|
+
(0, metadata_resource_1.addConstructMetadata)(this, props);
|
|
196
|
+
this.agentRuntimeName = props.runtimeName;
|
|
197
|
+
this.validateRuntimeName();
|
|
198
|
+
this.description = props.description;
|
|
199
|
+
if (this.description) {
|
|
200
|
+
this.validateDescription();
|
|
201
|
+
}
|
|
202
|
+
if (props.environmentVariables) {
|
|
203
|
+
this.validateEnvironmentVariables(props.environmentVariables);
|
|
204
|
+
}
|
|
205
|
+
if (props.tags) {
|
|
206
|
+
this.validateTags(props.tags);
|
|
207
|
+
}
|
|
208
|
+
if (props.executionRole) {
|
|
209
|
+
this.role = props.executionRole;
|
|
210
|
+
if (!aws_cdk_lib_1.Token.isUnresolved(props.executionRole.roleArn)) {
|
|
211
|
+
this.validateRoleArn(props.executionRole.roleArn);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
this.role = this.createExecutionRole();
|
|
216
|
+
}
|
|
217
|
+
this.grantPrincipal = this.role;
|
|
218
|
+
this.agentRuntimeArtifact = props.agentRuntimeArtifact;
|
|
219
|
+
// Set up network configuration with VPC support
|
|
220
|
+
this.networkConfiguration = props.networkConfiguration ?? network_configuration_1.RuntimeNetworkConfiguration.usingPublicNetwork();
|
|
221
|
+
// Set connections - create a shared connections object
|
|
222
|
+
if (this.networkConfiguration.connections) {
|
|
223
|
+
// Use the network configuration's connections as the shared object
|
|
224
|
+
this._connections = this.networkConfiguration.connections;
|
|
225
|
+
}
|
|
226
|
+
this.protocolConfiguration = props.protocolConfiguration ?? types_1.ProtocolType.HTTP;
|
|
227
|
+
this.authorizerConfiguration = props.authorizerConfiguration;
|
|
228
|
+
const cfnProps = {
|
|
229
|
+
agentRuntimeName: this.agentRuntimeName,
|
|
230
|
+
roleArn: this.role.roleArn,
|
|
231
|
+
agentRuntimeArtifact: aws_cdk_lib_1.Lazy.any({
|
|
232
|
+
produce: () => this.renderAgentRuntimeArtifact(),
|
|
233
|
+
}),
|
|
234
|
+
networkConfiguration: aws_cdk_lib_1.Lazy.any({
|
|
235
|
+
produce: () => this.networkConfiguration._render(this._connections),
|
|
236
|
+
}),
|
|
237
|
+
protocolConfiguration: aws_cdk_lib_1.Lazy.string({
|
|
238
|
+
produce: () => this.protocolConfiguration,
|
|
239
|
+
}),
|
|
240
|
+
description: props.description,
|
|
241
|
+
environmentVariables: aws_cdk_lib_1.Lazy.any({
|
|
242
|
+
produce: () => this.renderEnvironmentVariables(props.environmentVariables),
|
|
243
|
+
}),
|
|
244
|
+
tags: props.tags ?? {},
|
|
245
|
+
};
|
|
246
|
+
if (props.authorizerConfiguration) {
|
|
247
|
+
cfnProps.authorizerConfiguration = aws_cdk_lib_1.Lazy.any({
|
|
248
|
+
produce: () => this.authorizerConfiguration._render(),
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
this.runtimeResource = new bedrockagentcore.CfnRuntime(this, 'Resource', cfnProps);
|
|
252
|
+
// Add dependency on the role (for both custom and auto-created roles)
|
|
253
|
+
// This ensures the Runtime waits for the role and all its policies (including ECR permissions) to be created
|
|
254
|
+
this.runtimeResource.node.addDependency(this.role);
|
|
255
|
+
this.agentRuntimeId = this.runtimeResource.attrAgentRuntimeId;
|
|
256
|
+
this.agentRuntimeArn = this.runtimeResource.attrAgentRuntimeArn;
|
|
257
|
+
this.agentStatus = this.runtimeResource.attrStatus;
|
|
258
|
+
this.agentRuntimeVersion = this.runtimeResource.attrAgentRuntimeVersion;
|
|
259
|
+
this.createdAt = this.runtimeResource.attrCreatedAt;
|
|
260
|
+
this.lastUpdatedAt = this.runtimeResource.attrLastUpdatedAt;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Renders the environment variables for CloudFormation
|
|
264
|
+
* @internal
|
|
265
|
+
*/
|
|
266
|
+
renderEnvironmentVariables(envVars) {
|
|
267
|
+
if (!envVars || Object.keys(envVars).length === 0) {
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
return envVars;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Creates an execution role for the agent runtime with proper permissions
|
|
274
|
+
* Based on: https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-permissions.html
|
|
275
|
+
*/
|
|
276
|
+
createExecutionRole() {
|
|
277
|
+
const role = new iam.Role(this, 'ExecutionRole', {
|
|
278
|
+
assumedBy: new iam.ServicePrincipal('bedrock-agentcore.amazonaws.com'),
|
|
279
|
+
description: 'Execution role for Bedrock Agent Core Runtime',
|
|
280
|
+
maxSessionDuration: aws_cdk_lib_1.Duration.hours(8),
|
|
281
|
+
});
|
|
282
|
+
const region = aws_cdk_lib_1.Stack.of(this).region;
|
|
283
|
+
const account = aws_cdk_lib_1.Stack.of(this).account;
|
|
284
|
+
// CloudWatch Logs - Log Group operations
|
|
285
|
+
role.addToPolicy(new iam.PolicyStatement({
|
|
286
|
+
sid: 'LogGroupAccess',
|
|
287
|
+
effect: iam.Effect.ALLOW,
|
|
288
|
+
actions: perms_1.RUNTIME_LOGS_GROUP_ACTIONS,
|
|
289
|
+
resources: [`arn:${aws_cdk_lib_1.Stack.of(this).partition}:logs:${region}:${account}:log-group:/aws/bedrock-agentcore/runtimes/*`],
|
|
290
|
+
}));
|
|
291
|
+
// CloudWatch Logs - Describe all log groups
|
|
292
|
+
role.addToPolicy(new iam.PolicyStatement({
|
|
293
|
+
sid: 'DescribeLogGroups',
|
|
294
|
+
effect: iam.Effect.ALLOW,
|
|
295
|
+
actions: perms_1.RUNTIME_LOGS_DESCRIBE_ACTIONS,
|
|
296
|
+
resources: [`arn:${aws_cdk_lib_1.Stack.of(this).partition}:logs:${region}:${account}:log-group:*`],
|
|
297
|
+
}));
|
|
298
|
+
// CloudWatch Logs - Log Stream operations
|
|
299
|
+
role.addToPolicy(new iam.PolicyStatement({
|
|
300
|
+
sid: 'LogStreamAccess',
|
|
301
|
+
effect: iam.Effect.ALLOW,
|
|
302
|
+
actions: perms_1.RUNTIME_LOGS_STREAM_ACTIONS,
|
|
303
|
+
resources: [`arn:${aws_cdk_lib_1.Stack.of(this).partition}:logs:${region}:${account}:log-group:/aws/bedrock-agentcore/runtimes/*:log-stream:*`],
|
|
304
|
+
}));
|
|
305
|
+
// X-Ray Tracing - must be * for tracing
|
|
306
|
+
role.addToPolicy(new iam.PolicyStatement({
|
|
307
|
+
sid: 'XRayAccess',
|
|
308
|
+
effect: iam.Effect.ALLOW,
|
|
309
|
+
actions: perms_1.RUNTIME_XRAY_ACTIONS,
|
|
310
|
+
resources: ['*'],
|
|
311
|
+
}));
|
|
312
|
+
// CloudWatch Metrics - scoped to bedrock-agentcore namespace
|
|
313
|
+
role.addToPolicy(new iam.PolicyStatement({
|
|
314
|
+
sid: 'CloudWatchMetrics',
|
|
315
|
+
effect: iam.Effect.ALLOW,
|
|
316
|
+
actions: perms_1.RUNTIME_CLOUDWATCH_METRICS_ACTIONS,
|
|
317
|
+
resources: ['*'],
|
|
318
|
+
conditions: {
|
|
319
|
+
StringEquals: {
|
|
320
|
+
'cloudwatch:namespace': perms_1.RUNTIME_CLOUDWATCH_NAMESPACE,
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
}));
|
|
324
|
+
// Bedrock AgentCore Workload Identity Access
|
|
325
|
+
// Note: The agent name will be determined at runtime, so we use a wildcard pattern
|
|
326
|
+
role.addToPolicy(new iam.PolicyStatement({
|
|
327
|
+
sid: 'GetAgentAccessToken',
|
|
328
|
+
effect: iam.Effect.ALLOW,
|
|
329
|
+
actions: perms_1.RUNTIME_WORKLOAD_IDENTITY_ACTIONS,
|
|
330
|
+
resources: [
|
|
331
|
+
`arn:${aws_cdk_lib_1.Stack.of(this).partition}:bedrock-agentcore:${region}:${account}:workload-identity-directory/default`,
|
|
332
|
+
`arn:${aws_cdk_lib_1.Stack.of(this).partition}:bedrock-agentcore:${region}:${account}:workload-identity-directory/default/workload-identity/*`,
|
|
333
|
+
],
|
|
334
|
+
}));
|
|
335
|
+
return role;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Renders the artifact configuration for CloudFormation
|
|
339
|
+
* @internal
|
|
340
|
+
*/
|
|
341
|
+
renderAgentRuntimeArtifact() {
|
|
342
|
+
// set permission with bind
|
|
343
|
+
this.agentRuntimeArtifact.bind(this, this);
|
|
344
|
+
const config = this.agentRuntimeArtifact._render();
|
|
345
|
+
const containerUri = config.containerUri;
|
|
346
|
+
if (containerUri) {
|
|
347
|
+
this.validateContainerUri(containerUri);
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
containerConfiguration: {
|
|
351
|
+
containerUri: containerUri,
|
|
352
|
+
},
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Validates the runtime name format
|
|
357
|
+
* Pattern: ^[a-zA-Z][a-zA-Z0-9_]{0,47}$
|
|
358
|
+
* @throws Error if validation fails
|
|
359
|
+
*/
|
|
360
|
+
validateRuntimeName() {
|
|
361
|
+
// Skip validation if the name contains CDK tokens (unresolved values)
|
|
362
|
+
if (aws_cdk_lib_1.Token.isUnresolved(this.agentRuntimeName)) {
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
// Validate length
|
|
366
|
+
const lengthErrors = (0, validation_helpers_1.validateStringField)({
|
|
367
|
+
value: this.agentRuntimeName,
|
|
368
|
+
fieldName: 'Runtime name',
|
|
369
|
+
minLength: 1,
|
|
370
|
+
maxLength: 48,
|
|
371
|
+
});
|
|
372
|
+
// Validate pattern
|
|
373
|
+
const patternErrors = (0, validation_helpers_1.validateFieldPattern)(this.agentRuntimeName, 'Runtime name', /^[a-zA-Z][a-zA-Z0-9_]{0,47}$/, 'Runtime name must start with a letter and contain only letters, numbers, and underscores');
|
|
374
|
+
// Combine and throw if any errors
|
|
375
|
+
const allErrors = [...lengthErrors, ...patternErrors];
|
|
376
|
+
if (allErrors.length > 0) {
|
|
377
|
+
throw new validation_helpers_1.ValidationError(allErrors.join('\n'));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Validates the description format
|
|
382
|
+
* Must be between 1 and 1200 characters (per CloudFormation specification)
|
|
383
|
+
* @throws Error if validation fails
|
|
384
|
+
*/
|
|
385
|
+
validateDescription() {
|
|
386
|
+
// Skip validation if the description contains CDK tokens (unresolved values)
|
|
387
|
+
if (aws_cdk_lib_1.Token.isUnresolved(this.description)) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (this.description) {
|
|
391
|
+
const errors = (0, validation_helpers_1.validateStringField)({
|
|
392
|
+
value: this.description,
|
|
393
|
+
fieldName: 'Description',
|
|
394
|
+
minLength: 1,
|
|
395
|
+
maxLength: 1200,
|
|
396
|
+
});
|
|
397
|
+
if (errors.length > 0) {
|
|
398
|
+
throw new validation_helpers_1.ValidationError(errors.join('\n'));
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Validates environment variables
|
|
404
|
+
* - Maximum 50 entries
|
|
405
|
+
* - Key: 1-100 characters
|
|
406
|
+
* - Value: 0-2048 characters (per CloudFormation specification)
|
|
407
|
+
* @throws Error if validation fails
|
|
408
|
+
*/
|
|
409
|
+
validateEnvironmentVariables(envVars) {
|
|
410
|
+
const entries = Object.entries(envVars);
|
|
411
|
+
// Validate number of entries (0-50)
|
|
412
|
+
if (entries.length > 50) {
|
|
413
|
+
throw new validation_helpers_1.ValidationError(`Too many environment variables: ${entries.length}. Maximum allowed is 50`);
|
|
414
|
+
}
|
|
415
|
+
for (const [key, value] of entries) {
|
|
416
|
+
// Skip validation if key or value contains CDK tokens
|
|
417
|
+
if (aws_cdk_lib_1.Token.isUnresolved(key) || aws_cdk_lib_1.Token.isUnresolved(value)) {
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
// Validate key length
|
|
421
|
+
const lengthErrors = (0, validation_helpers_1.validateStringField)({
|
|
422
|
+
value: key,
|
|
423
|
+
fieldName: `Environment variable key '${key}'`,
|
|
424
|
+
minLength: 1,
|
|
425
|
+
maxLength: 100,
|
|
426
|
+
});
|
|
427
|
+
// Validate key pattern
|
|
428
|
+
const patternErrors = (0, validation_helpers_1.validateFieldPattern)(key, `Environment variable key '${key}'`, /^[a-zA-Z_][a-zA-Z0-9_]*$/, `Environment variable key '${key}' must start with a letter or underscore and contain only letters, numbers, and underscores`);
|
|
429
|
+
// Combine and throw if any errors
|
|
430
|
+
const allErrors = [...lengthErrors, ...patternErrors];
|
|
431
|
+
if (allErrors.length > 0) {
|
|
432
|
+
throw new validation_helpers_1.ValidationError(allErrors.join('\n'));
|
|
433
|
+
}
|
|
434
|
+
// Validate value length (0-2048 characters per CloudFormation)
|
|
435
|
+
if (value.length > 2048) {
|
|
436
|
+
throw new validation_helpers_1.ValidationError(`Invalid environment variable value length for key '${key}': ${value.length} characters. ` +
|
|
437
|
+
'Values must not exceed 2048 characters');
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Validates the tags format
|
|
443
|
+
* @param tags The tags object to validate
|
|
444
|
+
* @throws Error if validation fails
|
|
445
|
+
*/
|
|
446
|
+
validateTags(tags) {
|
|
447
|
+
// Validate each tag key and value
|
|
448
|
+
for (const [key, value] of Object.entries(tags)) {
|
|
449
|
+
// Skip validation if key or value contains CDK tokens
|
|
450
|
+
if (aws_cdk_lib_1.Token.isUnresolved(key) || aws_cdk_lib_1.Token.isUnresolved(value)) {
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
// Validate tag key length
|
|
454
|
+
const keyLengthErrors = (0, validation_helpers_1.validateStringField)({
|
|
455
|
+
value: key,
|
|
456
|
+
fieldName: `Tag key "${key}"`,
|
|
457
|
+
minLength: 1,
|
|
458
|
+
maxLength: 256,
|
|
459
|
+
});
|
|
460
|
+
// Validate tag key pattern
|
|
461
|
+
const keyPatternErrors = (0, validation_helpers_1.validateFieldPattern)(key, `Tag key "${key}"`, /^[a-zA-Z0-9\s._:/=+@-]*$/, `Tag key "${key}" can only contain letters (a-z, A-Z), numbers (0-9), spaces, and special characters (._:/=+@-)`);
|
|
462
|
+
// Combine key errors and throw if any
|
|
463
|
+
const keyErrors = [...keyLengthErrors, ...keyPatternErrors];
|
|
464
|
+
if (keyErrors.length > 0) {
|
|
465
|
+
throw new validation_helpers_1.ValidationError(keyErrors.join('\n'));
|
|
466
|
+
}
|
|
467
|
+
if (value === undefined || value === null) {
|
|
468
|
+
throw new validation_helpers_1.ValidationError(`Tag value for key "${key}" cannot be null or undefined`);
|
|
469
|
+
}
|
|
470
|
+
// Validate tag value length
|
|
471
|
+
const valueLengthErrors = (0, validation_helpers_1.validateStringField)({
|
|
472
|
+
value: value,
|
|
473
|
+
fieldName: `Tag value for key "${key}"`,
|
|
474
|
+
minLength: 0,
|
|
475
|
+
maxLength: 256,
|
|
476
|
+
});
|
|
477
|
+
// Validate tag value pattern
|
|
478
|
+
const valuePatternErrors = (0, validation_helpers_1.validateFieldPattern)(value, `Tag value for key "${key}"`, /^[a-zA-Z0-9\s._:/=+@-]*$/, `Tag value for key "${key}" can only contain letters (a-z, A-Z), numbers (0-9), spaces, and special characters (._:/=+@-)`);
|
|
479
|
+
// Combine value errors and throw if any
|
|
480
|
+
const valueErrors = [...valueLengthErrors, ...valuePatternErrors];
|
|
481
|
+
if (valueErrors.length > 0) {
|
|
482
|
+
throw new validation_helpers_1.ValidationError(valueErrors.join('\n'));
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Validates the container URI format
|
|
488
|
+
*/
|
|
489
|
+
validateContainerUri(uri) {
|
|
490
|
+
// Skip validation if the URI contains CDK tokens (unresolved values)
|
|
491
|
+
if (aws_cdk_lib_1.Token.isUnresolved(uri)) {
|
|
492
|
+
// Add a warning that validation will be skipped for token-based URIs
|
|
493
|
+
aws_cdk_lib_1.Annotations.of(this).addInfo('Container URI validation skipped as it contains unresolved CDK tokens. ' +
|
|
494
|
+
'The URI will be validated at deployment time.');
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
// Only validate if the URI is a concrete string (not a token)
|
|
498
|
+
const pattern = /^\d{12}\.dkr\.ecr\.([a-z0-9-]+)\.amazonaws\.com\/((?:[a-z0-9]+(?:[._-][a-z0-9]+)*\/)*[a-z0-9]+(?:[._-][a-z0-9]+)*)([:@]\S+)$/;
|
|
499
|
+
if (!pattern.test(uri)) {
|
|
500
|
+
throw new validation_helpers_1.ValidationError(`Invalid container URI format: ${uri}. Must be a valid ECR URI (e.g., 123456789012.dkr.ecr.us-west-2.amazonaws.com/my-agent:latest)`);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Validates the IAM role ARN format and structure
|
|
505
|
+
* @throws Error if validation fails
|
|
506
|
+
*/
|
|
507
|
+
validateRoleArn(roleArn) {
|
|
508
|
+
// Validate basic ARN format for IAM roles
|
|
509
|
+
const arnPattern = /^arn:[a-z\-]+:iam::\d{12}:role\/[a-zA-Z0-9+=,.@\-_\/]+$/;
|
|
510
|
+
if (!arnPattern.test(roleArn)) {
|
|
511
|
+
throw new validation_helpers_1.ValidationError(`Invalid IAM role ARN format: ${roleArn}. ` +
|
|
512
|
+
'Expected format: arn:<partition>:iam::<account-id>:role/<role-name> or arn:<partition>:iam::<account-id>:role/<path>/<role-name>');
|
|
513
|
+
}
|
|
514
|
+
// Parse the ARN components using CDK's Arn.split()
|
|
515
|
+
// Use SLASH_RESOURCE_NAME format for IAM roles (which use format: role/role-name or role/path/to/role-name)
|
|
516
|
+
const arnComponents = aws_cdk_lib_1.Arn.split(roleArn, aws_cdk_lib_1.ArnFormat.SLASH_RESOURCE_NAME);
|
|
517
|
+
if (arnComponents.service !== 'iam') {
|
|
518
|
+
throw new validation_helpers_1.ValidationError(`Invalid service in ARN: ${arnComponents.service}. Expected 'iam' for IAM role ARN.`);
|
|
519
|
+
}
|
|
520
|
+
const accountId = arnComponents.account;
|
|
521
|
+
if (!accountId || !/^\d{12}$/.test(accountId)) {
|
|
522
|
+
throw new validation_helpers_1.ValidationError(`Invalid AWS account ID in role ARN: ${accountId}. Must be a 12-digit number.`);
|
|
523
|
+
}
|
|
524
|
+
// Extract role name from resource
|
|
525
|
+
// For IAM roles, resource will be "role" and resourceName will be the role name (with optional path)
|
|
526
|
+
const resource = arnComponents.resource;
|
|
527
|
+
const resourceName = arnComponents.resourceName;
|
|
528
|
+
if (resource !== 'role') {
|
|
529
|
+
throw new validation_helpers_1.ValidationError(`Invalid resource type in ARN: ${resource}. Expected 'role' for IAM role ARN.`);
|
|
530
|
+
}
|
|
531
|
+
if (!resourceName) {
|
|
532
|
+
throw new validation_helpers_1.ValidationError('Role name is missing in the ARN');
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
const rolePathParts = resourceName.split('/');
|
|
536
|
+
const roleName = rolePathParts[rolePathParts.length - 1];
|
|
537
|
+
if (roleName.length > 64) {
|
|
538
|
+
throw new validation_helpers_1.ValidationError(`Role name exceeds maximum length of 64 characters: ${roleName}`);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
const stackAccount = aws_cdk_lib_1.Stack.of(this).account;
|
|
542
|
+
if (!aws_cdk_lib_1.Token.isUnresolved(stackAccount) && accountId !== stackAccount) {
|
|
543
|
+
aws_cdk_lib_1.Annotations.of(this).addWarning(`IAM role is from a different account (${accountId}) than the stack account (${stackAccount}). ` +
|
|
544
|
+
'Ensure cross-account permissions are properly configured.');
|
|
545
|
+
}
|
|
546
|
+
// Validate the region (IAM is global, so region should be empty)
|
|
547
|
+
const region = arnComponents.region;
|
|
548
|
+
const stackRegion = aws_cdk_lib_1.Stack.of(this).region;
|
|
549
|
+
if (region && region !== '' && region !== stackRegion && !aws_cdk_lib_1.Token.isUnresolved(stackRegion)) {
|
|
550
|
+
aws_cdk_lib_1.Annotations.of(this).addWarning(`IAM role ARN contains a region (${region}) that doesn't match the stack region (${stackRegion}). ` +
|
|
551
|
+
'IAM is a global service, so this might be intentional.');
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Add an endpoint to this runtime
|
|
556
|
+
* This is a convenience method that creates a RuntimeEndpoint associated with this runtime
|
|
557
|
+
*
|
|
558
|
+
* @param endpointName The name of the endpoint
|
|
559
|
+
* @param options Optional configuration for the endpoint
|
|
560
|
+
* @returns The created RuntimeEndpoint
|
|
561
|
+
*/
|
|
562
|
+
addEndpoint(endpointName, options) {
|
|
563
|
+
try {
|
|
564
|
+
jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_AddEndpointOptions(options);
|
|
565
|
+
}
|
|
566
|
+
catch (error) {
|
|
567
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
568
|
+
Error.captureStackTrace(error, this.addEndpoint);
|
|
569
|
+
}
|
|
570
|
+
throw error;
|
|
571
|
+
}
|
|
572
|
+
// Create the endpoint (security configuration is no longer supported)
|
|
573
|
+
const endpoint = new runtime_endpoint_1.RuntimeEndpoint(this, `Endpoint${endpointName}`, {
|
|
574
|
+
endpointName: endpointName,
|
|
575
|
+
agentRuntimeId: this.agentRuntimeId,
|
|
576
|
+
agentRuntimeVersion: options?.version ?? this.agentRuntimeVersion ?? '1',
|
|
577
|
+
description: options?.description,
|
|
578
|
+
});
|
|
579
|
+
// Add dependency: endpoint must wait for runtime to be created
|
|
580
|
+
endpoint.node.addDependency(this.runtimeResource);
|
|
581
|
+
return endpoint;
|
|
582
|
+
}
|
|
583
|
+
static {
|
|
584
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
return Runtime = _classThis;
|
|
588
|
+
})();
|
|
589
|
+
exports.Runtime = Runtime;
|
|
590
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInJ1bnRpbWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQ0EsNkNBQXdGO0FBQ3hGLHFFQUFxRTtBQUNyRSwyQ0FBMkM7QUFDM0MsMkNBQTJDO0FBQzNDLDhFQUE4RjtBQUM5RiwwRUFBMEU7QUFFMUUsbUNBUWlCO0FBR2pCLGlEQUEyRjtBQUMzRix5REFBcUQ7QUFDckQsNEVBQStFO0FBQy9FLG1DQUF1QztBQUN2Qyw2REFBa0c7QUEwRmxHOzsrRUFFK0U7QUFFL0U7Ozs7Ozs7R0FPRztJQUVVLE9BQU87NEJBRG5CLG9DQUFrQjs7OztzQkFDVSwwQkFBVzs7O3VCQUFuQixTQUFRLFdBQVc7Ozs7dUNBK2lCckMsSUFBQSxrQ0FBYyxHQUFFO1lBQ2pCLG9MQUFPLFdBQVcsNkRBZ0JqQjtZQWhrQkgsNktBaWtCQzs7Ozs7UUFoa0JDLHNDQUFzQztRQUMvQixNQUFNLENBQVUscUJBQXFCLEdBQVcsOENBQThDLENBQUM7UUFFdEc7Ozs7Ozs7O1dBUUc7UUFDSSxNQUFNLENBQUMsMEJBQTBCLENBQ3RDLEtBQWdCLEVBQ2hCLEVBQVUsRUFDVixLQUE2Qjs7Ozs7Ozs7OztZQUU3QixNQUFNLDJCQUE0QixTQUFRLDBCQUFXO2dCQUNuQyxlQUFlLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQztnQkFDeEMsY0FBYyxHQUFHLEtBQUssQ0FBQyxjQUFjLENBQUM7Z0JBQ3RDLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQztnQkFDMUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDLG1CQUFtQixDQUFDO2dCQUNoRCxXQUFXLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQztnQkFDaEMsV0FBVyxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUM7Z0JBQ2hDLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO2dCQUM1QixhQUFhLEdB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TUFBTSxJQUFJLE1BQU0sS0FBSyxFQUFFLElBQUksTUFBTSxLQUFLLFdBQVcsSUFBSSxDQUFDLG1CQUFLLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7Z0JBQzFGLHlCQUFXLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FDN0IsbUNBQW1DLE1BQU0sMENBQTBDLFdBQVcsS0FBSztvQkFDbkcsd0RBQXdELENBQ3pELENBQUM7WUFDSixDQUFDO1NBQ0Y7UUFFRDs7Ozs7OztXQU9HO1FBRUksV0FBVyxDQUNoQixZQUFvQixFQUNwQixPQUE0Qjs7Ozs7Ozs7OztZQUU1QixzRUFBc0U7WUFDdEUsTUFBTSxRQUFRLEdBQUcsSUFBSSxrQ0FBZSxDQUFDLElBQUksRUFBRSxXQUFXLFlBQVksRUFBRSxFQUFFO2dCQUNwRSxZQUFZLEVBQUUsWUFBWTtnQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyxjQUFjO2dCQUNuQyxtQkFBbUIsRUFBRSxPQUFPLEVBQUUsT0FBTyxJQUFJLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxHQUFHO2dCQUN4RSxXQUFXLEVBQUUsT0FBTyxFQUFFLFdBQVc7YUFDbEMsQ0FBQyxDQUFDO1lBRUgsK0RBQStEO1lBQy9ELFFBQVEsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUVsRCxPQUFPLFFBQVEsQ0FBQztTQUNqQjs7WUFoa0JVLHVEQUFPOzs7OztBQUFQLDBCQUFPIiwic291cmNlc0NvbnRlbnQiOlsiXG5pbXBvcnQgeyBEdXJhdGlvbiwgU3RhY2ssIEFubm90YXRpb25zLCBUb2tlbiwgQXJuLCBBcm5Gb3JtYXQsIExhenkgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBiZWRyb2NrYWdlbnRjb3JlIGZyb20gJ2F3cy1jZGstbGliL2F3cy1iZWRyb2NrYWdlbnRjb3JlJztcbmltcG9ydCAqIGFzIGVjMiBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWMyJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IGFkZENvbnN0cnVjdE1ldGFkYXRhLCBNZXRob2RNZXRhZGF0YSB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL21ldGFkYXRhLXJlc291cmNlJztcbmltcG9ydCB7IHByb3BlcnR5SW5qZWN0YWJsZSB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL3Byb3AtaW5qZWN0YWJsZSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7XG4gIFJVTlRJTUVfTE9HU19HUk9VUF9BQ1RJT05TLFxuICBSVU5USU1FX0xPR1NfREVTQ1JJQkVfQUNUSU9OUyxcbiAgUlVOVElNRV9MT0dTX1NUUkVBTV9BQ1RJT05TLFxuICBSVU5USU1FX1hSQVlfQUNUSU9OUyxcbiAgUlVOVElNRV9DTE9VRFdBVENIX01FVFJJQ1NfQUNUSU9OUyxcbiAgUlVOVElNRV9DTE9VRFdBVENIX05BTUVTUEFDRSxcbiAgUlVOVElNRV9XT1JLTE9BRF9JREVOVElUWV9BQ1RJT05TLFxufSBmcm9tICcuL3Blcm1zJztcbmltcG9ydCB7IEFnZW50UnVudGltZUFydGlmYWN0IH0gZnJvbSAnLi9ydW50aW1lLWFydGlmYWN0JztcbmltcG9ydCB7IFJ1bnRpbWVBdXRob3JpemVyQ29uZmlndXJhdGlvbiB9IGZyb20gJy4vcnVudGltZS1hdXRob3JpemVyLWNvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgUnVudGltZUJhc2UsIElCZWRyb2NrQWdlbnRSdW50aW1lLCBBZ2VudFJ1bnRpbWVBdHRyaWJ1dGVzIH0gZnJvbSAnLi9ydW50aW1lLWJhc2UnO1xuaW1wb3J0IHsgUnVudGltZUVuZHBvaW50IH0gZnJvbSAnLi9ydW50aW1lLWVuZHBvaW50JztcbmltcG9ydCB7IFJ1bnRpbWVOZXR3b3JrQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL25ldHdvcmsvbmV0d29yay1jb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFByb3RvY29sVHlwZSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgdmFsaWRhdGVTdHJpbmdGaWVsZCwgVmFsaWRhdGlvbkVycm9yLCB2YWxpZGF0ZUZpZWxkUGF0dGVybiB9IGZyb20gJy4vdmFsaWRhdGlvbi1oZWxwZXJzJztcblxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByb3BzXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgY3JlYXRpbmcgYSBCZWRyb2NrIEFnZW50IENvcmUgUnVudGltZSByZXNvdXJjZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJ1bnRpbWVQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgYWdlbnQgcnVudGltZVxuICAgKiBWYWxpZCBjaGFyYWN0ZXJzIGFyZSBhLXosIEEtWiwgMC05LCBfICh1bmRlcnNjb3JlKVxuICAgKiBNdXN0IHN0YXJ0IHdpdGggYSBsZXR0ZXIgYW5kIGNhbiBiZSB1cCB0byA0OCBjaGFyYWN0ZXJzIGxvbmdcbiAgICogUGF0dGVybjogXlthLXpBLVpdW2EtekEtWjAtOV9dezAsNDd9JFxuICAgKi9cbiAgcmVhZG9ubHkgcnVudGltZU5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGFydGlmYWN0IGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBhZ2VudCBydW50aW1lXG4gICAqIENvbnRhaW5zIHRoZSBjb250YWluZXIgY29uZmlndXJhdGlvbiB3aXRoIEVDUiBVUklcbiAgICovXG4gIHJlYWRvbmx5IGFnZW50UnVudGltZUFydGlmYWN0OiBBZ2VudFJ1bnRpbWVBcnRpZmFjdDtcblxuICAvKipcbiAgICogVGhlIElBTSByb2xlIHRoYXQgcHJvdmlkZXMgcGVybWlzc2lvbnMgZm9yIHRoZSBhZ2VudCBydW50aW1lXG4gICAqIElmIG5vdCBwcm92aWRlZCwgYSByb2xlIHdpbGwgYmUgY3JlYXRlZCBhdXRvbWF0aWNhbGx5XG4gICAqIEBkZWZhdWx0IC0gQSBuZXcgcm9sZSB3aWxsIGJlIGNyZWF0ZWRcbiAgICovXG4gIHJlYWRvbmx5IGV4ZWN1dGlvblJvbGU/OiBpYW0uSVJvbGU7XG5cbiAgLyoqXG4gICAqIE5ldHdvcmsgY29uZmlndXJhdGlvbiBmb3IgdGhlIGFnZW50IHJ1bnRpbWVcbiAgICogQGRlZmF1bHQgLSBSdW50aW1lTmV0d29ya0NvbmZpZ3VyYXRpb24udXNpbmdQdWJsaWNOZXR3b3JrKClcbiAgICovXG4gIHJlYWRvbmx5IG5ldHdvcmtDb25maWd1cmF0aW9uPzogUnVudGltZU5ldHdvcmtDb25maWd1cmF0aW9uO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBkZXNjcmlwdGlvbiBmb3IgdGhlIGFnZW50IHJ1bnRpbWVcbiAgICogQGRlZmF1bHQgLSBObyBkZXNjcmlwdGlvblxuICAgKiBMZW5ndGggTWluaW11bTogMSAsIE1heGltdW06IDEyMDBcbiAgICovXG4gIHJlYWRvbmx5IGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQcm90b2NvbCBjb25maWd1cmF0aW9uIGZvciB0aGUgYWdlbnQgcnVudGltZVxuICAgKiBAZGVmYXVsdCAtIFByb3RvY29sVHlwZS5IVFRQXG4gICAqL1xuICByZWFkb25seSBwcm90b2NvbENvbmZpZ3VyYXRpb24/OiBQcm90b2NvbFR5cGU7XG5cbiAgLyoqXG4gICAqIEVudmlyb25tZW50IHZhcmlhYmxlcyBmb3IgdGhlIGFnZW50IHJ1bnRpbWVcbiAgICogLSBNYXhpbXVtIDUwIGVudmlyb25tZW50IHZhcmlhYmxlc1xuICAgKiAtIEtleTogTXVzdCBiZSAxLTEwMCBjaGFyYWN0ZXJzLCBzdGFydCB3aXRoIGxldHRlciBvciB1bmRlcnNjb3JlLCBjb250YWluIG9ubHkgbGV0dGVycywgbnVtYmVycywgYW5kIHVuZGVyc2NvcmVzXG4gICAqIC0gVmFsdWU6IE11c3QgYmUgMC0yMDQ4IGNoYXJhY3RlcnMgKHBlciBDbG91ZEZvcm1hdGlvbiBzcGVjaWZpY2F0aW9uKVxuICAgKiBAZGVmYXVsdCAtIE5vIGVudmlyb25tZW50IHZhcmlhYmxlc1xuICAgKi9cbiAgcmVhZG9ubHkgZW52aXJvbm1lbnRWYXJpYWJsZXM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuXG4gIC8qKlxuICAgKiBBdXRob3JpemVyIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBhZ2VudCBydW50aW1lXG4gICAqIFVzZSBSdW50aW1lQXV0aG9yaXplckNvbmZpZ3VyYXRpb24gc3RhdGljIG1ldGhvZHMgdG8gY3JlYXRlIHRoZSBjb25maWd1cmF0aW9uXG4gICAqIEBkZWZhdWx0IC0gUnVudGltZUF1dGhvcml6ZXJDb25maWd1cmF0aW9uLmlhbSgpIChJQU0gYXV0aGVudGljYXRpb24pXG4gICAqL1xuICByZWFkb25seSBhdXRob3JpemVyQ29uZmlndXJhdGlvbj86IFJ1bnRpbWVBdXRob3JpemVyQ29uZmlndXJhdGlvbjtcblxuICAvKipcbiAgICogVGFncyBmb3IgdGhlIGFnZW50IHJ1bnRpbWVcbiAgICogQSBsaXN0IG9mIGtleTp2YWx1ZSBwYWlycyBvZiB0YWdzIHRvIGFwcGx5IHRvIHRoaXMgUnVudGltZSByZXNvdXJjZVxuICAgKiBAZGVmYXVsdCB7fSAtIG5vIHRhZ3NcbiAgICovXG4gIHJlYWRvbmx5IHRhZ3M/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGFkZGluZyBhbiBlbmRwb2ludCB0byB0aGUgcnVudGltZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFkZEVuZHBvaW50T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBEZXNjcmlwdGlvbiBmb3IgdGhlIGVuZHBvaW50LCBNdXN0IGJlIGJldHdlZW4gMSBhbmQgMTIwMCBjaGFyYWN0ZXJzXG4gICAqIEBkZWZhdWx0IC0gTm8gZGVzY3JpcHRpb25cbiAgICovXG4gIHJlYWRvbmx5IGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICAvKipcbiAgICogT3ZlcnJpZGUgdGhlIHJ1bnRpbWUgdmVyc2lvbiBmb3IgdGhpcyBlbmRwb2ludFxuICAgKiBAZGVmYXVsdCAgMVxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZztcbn1cblxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbi8qKlxuICogQmVkcm9jayBBZ2VudCBDb3JlIFJ1bnRpbWVcbiAqIEVuYWJsZXMgcnVubmluZyBjb250YWluZXJpemVkIGFnZW50cyB3aXRoIHNwZWNpZmljIG5ldHdvcmsgY29uZmlndXJhdGlvbnMsXG4gKiBzZWN1cml0eSBzZXR0aW5ncywgYW5kIHJ1bnRpbWUgYXJ0aWZhY3RzLlxuICpcbiAqIEByZXNvdXJjZSBBV1M6OkJlZHJvY2tBZ2VudENvcmU6OlJ1bnRpbWVcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2JlZHJvY2stYWdlbnRjb3JlL2xhdGVzdC9kZXZndWlkZS9ydW50aW1lLmh0bWxcbiAqL1xuQHByb3BlcnR5SW5qZWN0YWJsZVxuZXhwb3J0IGNsYXNzIFJ1bnRpbWUgZXh0ZW5kcyBSdW50aW1lQmFzZSB7XG4gIC8qKiBVbmlxdWVseSBpZGVudGlmaWVzIHRoaXMgY2xhc3MuICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUFJPUEVSVFlfSU5KRUNUSU9OX0lEOiBzdHJpbmcgPSAnQGF3cy1jZGsuYXdzLWJlZHJvY2stYWdlbnRjb3JlLWFscGhhLlJ1bnRpbWUnO1xuXG4gIC8qKlxuICAgKiBJbXBvcnQgYW4gZXhpc3RpbmcgQWdlbnQgUnVudGltZSB1c2luZyBhdHRyaWJ1dGVzXG4gICAqIFRoaXMgYWxsb3dzIHlvdSB0byByZWZlcmVuY2UgYW4gQWdlbnQgUnVudGltZSB0aGF0IHdhcyBjcmVhdGVkIG91dHNpZGUgb2YgQ0RLXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSBUaGUgY29uc3RydWN0IHNjb3BlXG4gICAqIEBwYXJhbSBpZCBUaGUgY29uc3RydWN0IGlkXG4gICAqIEBwYXJhbSBhdHRycyBUaGUgYXR0cmlidXRlcyBvZiB0aGUgZXhpc3RpbmcgQWdlbnQgUnVudGltZVxuICAgKiBAcmV0dXJucyBBbiBJQmVkcm9ja0FnZW50UnVudGltZSBpbnN0YW5jZSByZXByZXNlbnRpbmcgdGhlIGltcG9ydGVkIHJ1bnRpbWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbUFnZW50UnVudGltZUF0dHJpYnV0ZXMoXG4gICAgc2NvcGU6IENvbnN0cnVjdCxcbiAgICBpZDogc3RyaW5nLFxuICAgIGF0dHJzOiBBZ2VudFJ1bnRpbWVBdHRyaWJ1dGVzLFxuICApOiBJQmVkcm9ja0FnZW50UnVudGltZSB7XG4gICAgY2xhc3MgSW1wb3J0ZWRCZWRyb2NrQWdlbnRSdW50aW1lIGV4dGVuZHMgUnVudGltZUJhc2Uge1xuICAgICAgcHVibGljIHJlYWRvbmx5IGFnZW50UnVudGltZUFybiA9IGF0dHJzLmFnZW50UnVudGltZUFybjtcbiAgICAgIHB1YmxpYyByZWFkb25seSBhZ2VudFJ1bnRpbWVJZCA9IGF0dHJzLmFnZW50UnVudGltZUlkO1xuICAgICAgcHVibGljIHJlYWRvbmx5IGFnZW50UnVudGltZU5hbWUgPSBhdHRycy5hZ2VudFJ1bnRpbWVOYW1lO1xuICAgICAgcHVibGljIHJlYWRvbmx5IGFnZW50UnVudGltZVZlcnNpb24gPSBhdHRycy5hZ2VudFJ1bnRpbWVWZXJzaW9uO1xuICAgICAgcHVibGljIHJlYWRvbmx5IGFnZW50U3RhdHVzID0gYXR0cnMuYWdlbnRTdGF0dXM7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZGVzY3JpcHRpb24gPSBhdHRycy5kZXNjcmlwdGlvbjtcbiAgICAgIHB1YmxpYyByZWFkb25seSBjcmVhdGVkQXQgPSBhdHRycy5jcmVhdGVkQXQ7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgbGFzdFVwZGF0ZWRBdCA9IGF0dHJzLmxhc3RVcGRhdGVkQXQ7XG5cbiAgICAgIHB1YmxpYyByZWFkb25seSByb2xlOiBpYW0uSVJvbGU7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnRQcmluY2lwYWw6IGlhbS5JUHJpbmNpcGFsO1xuXG4gICAgICBjb25zdHJ1Y3RvcihzOiBDb25zdHJ1Y3QsIGk6IHN0cmluZykge1xuICAgICAgICBzdXBlcihzLCBpKTtcbiAgICAgICAgdGhpcy5yb2xlID0gaWFtLlJvbGUuZnJvbVJvbGVBcm4odGhpcywgJ1JvbGUnLCBhdHRycy5yb2xlQXJuKTtcbiAgICAgICAgdGhpcy5ncmFudFByaW5jaXBhbCA9IHRoaXMucm9sZTtcbiAgICAgICAgaWYgKGF0dHJzLnNlY3VyaXR5R3JvdXBzKSB7XG4gICAgICAgICAgdGhpcy5fY29ubmVjdGlvbnMgPSBuZXcgZWMyLkNvbm5lY3Rpb25zKHtcbiAgICAgICAgICAgIHNlY3VyaXR5R3JvdXBzOiBhdHRycy5zZWN1cml0eUdyb3VwcyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgSW1wb3J0ZWRCZWRyb2NrQWdlbnRSdW50aW1lKHNjb3BlLCBpZCk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIEFSTiBvZiB0aGUgYWdlbnQgcnVudGltZVxuICAgKiBAYXR0cmlidXRlXG4gICAqIEByZXR1cm5zIGEgdG9rZW4gcmVwcmVzZW50aW5nIHRoZSBBUk4gb2YgdGhpcyBhZ2VudCBydW50aW1lXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYWdlbnRSdW50aW1lQXJuOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGFnZW50IHJ1bnRpbWVcbiAgICogQGF0dHJpYnV0ZVxuICAgKiBAcmV0dXJucyBhIHRva2VuIHJlcHJlc2VudGluZyB0aGUgSUQgb2YgdGhpcyBhZ2VudCBydW50aW1lXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYWdlbnRSdW50aW1lSWQ6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBhZ2VudCBydW50aW1lXG4gICAqIEBhdHRyaWJ1dGVcbiAgICogQHJldHVybnMgYSB0b2tlbiByZXByZXNlbnRpbmcgdGhlIG5hbWUgb2YgdGhpcyBhZ2VudCBydW50aW1lXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYWdlbnRSdW50aW1lTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcm9sZTogaWFtLklSb2xlO1xuICAvKipcbiAgICogVGhlIHZlcnNpb24gb2YgdGhlIGFnZW50IHJ1bnRpbWVcbiAgICogQGF0dHJpYnV0ZVxuICAgKiBAcmV0dXJucyBhIHRva2VuIHJlcHJlc2VudGluZyB0aGUgdmVyc2lvbiBvZiB0aGlzIGFnZW50IHJ1bnRpbWVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhZ2VudFJ1bnRpbWVWZXJzaW9uPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHN0YXR1cyBvZiB0aGUgYWdlbnQgcnVudGltZVxuICAgKiBAYXR0cmlidXRlXG4gICAqIEByZXR1cm5zIGEgdG9rZW4gcmVwcmVzZW50aW5nIHRoZSBzdGF0dXMgb2YgdGhpcyBhZ2VudCBydW50aW1lXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYWdlbnRTdGF0dXM/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBkZXNjcmlwdGlvbiBmb3IgdGhlIGFnZW50IHJ1bnRpbWVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSB0aW1lc3RhbXAgd2hlbiB0aGUgYWdlbnQgcnVudGltZSB3YXMgY3JlYXRlZFxuICAgKiBAYXR0cmlidXRlXG4gICAqIEByZXR1cm5zIGEgdG9rZW4gcmVwcmVzZW50aW5nIHRoZSBjcmVhdGlvbiB0aW1lc3RhbXAgb2YgdGhpcyBhZ2VudCBydW50aW1lXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY3JlYXRlZEF0Pzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHRpbWVzdGFtcCB3aGVuIHRoZSBhZ2VudCBydW50aW1lIHdhcyBsYXN0IHVwZGF0ZWRcbiAgICogQGF0dHJpYnV0ZVxuICAgKiBAcmV0dXJucyBhIHRva2VuIHJlcHJlc2VudGluZyB0aGUgbGFzdCB1cGRhdGUgdGltZXN0YW1wIG9mIHRoaXMgYWdlbnQgcnVudGltZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGxhc3RVcGRhdGVkQXQ/OiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBncmFudFByaW5jaXBhbDogaWFtLklQcmluY2lwYWw7XG4gIHByaXZhdGUgcmVhZG9ubHkgcnVudGltZVJlc291cmNlOiBiZWRyb2NrYWdlbnRjb3JlLkNmblJ1bnRpbWU7XG4gIC8qKlxuICAgKiBUaGUgYXJ0aWZhY3QgY29uZmlndXJhdGlvbiBmb3IgdGhlIGFnZW50IHJ1bnRpbWVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhZ2VudFJ1bnRpbWVBcnRpZmFjdDogQWdlbnRSdW50aW1lQXJ0aWZhY3Q7XG4gIHByaXZhdGUgcmVhZG9ubHkgbmV0d29ya0NvbmZpZ3VyYXRpb246IFJ1bnRpbWVOZXR3b3JrQ29uZmlndXJhdGlvbiA7XG4gIHByaXZhdGUgcmVhZG9ubHkgcHJvdG9jb2xDb25maWd1cmF0aW9uOiBQcm90b2NvbFR5cGU7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXV0aG9yaXplckNvbmZpZ3VyYXRpb24/OiBSdW50aW1lQXV0aG9yaXplckNvbmZpZ3VyYXRpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFJ1bnRpbWVQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICAvLyBDREsgQW5hbHl0aWNzIFRlbGVtZXRyeVxuICAgIGFkZENvbnN0cnVjdE1ldGFkYXRhKHRoaXMsIHByb3BzKTtcblxuICAgIHRoaXMuYWdlbnRSdW50aW1lTmFtZSA9IHByb3BzLnJ1bnRpbWVOYW1lO1xuICAgIHRoaXMudmFsaWRhdGVSdW50aW1lTmFtZSgpO1xuXG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IHByb3BzLmRlc2NyaXB0aW9uO1xuICAgIGlmICh0aGlzLmRlc2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlRGVzY3JpcHRpb24oKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuZW52aXJvbm1lbnRWYXJpYWJsZXMpIHtcbiAgICAgIHRoaXMudmFsaWRhdGVFbnZpcm9ubWVudFZhcmlhYmxlcyhwcm9wcy5lbnZpcm9ubWVudFZhcmlhYmxlcyk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnRhZ3MpIHtcbiAgICAgIHRoaXMudmFsaWRhdGVUYWdzKHByb3BzLnRhZ3MpO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy5leGVjdXRpb25Sb2xlKSB7XG4gICAgICB0aGlzLnJvbGUgPSBwcm9wcy5leGVjdXRpb25Sb2xlO1xuICAgICAgaWYgKCFUb2tlbi5pc1VucmVzb2x2ZWQocHJvcHMuZXhlY3V0aW9uUm9sZS5yb2xlQXJuKSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlUm9sZUFybihwcm9wcy5leGVjdXRpb25Sb2xlLnJvbGVBcm4pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJvbGUgPSB0aGlzLmNyZWF0ZUV4ZWN1dGlvblJvbGUoKTtcbiAgICB9XG5cbiAgICB0aGlzLmdyYW50UHJpbmNpcGFsID0gdGhpcy5yb2xlO1xuICAgIHRoaXMuYWdlbnRSdW50aW1lQXJ0aWZhY3QgPSBwcm9wcy5hZ2VudFJ1bnRpbWVBcnRpZmFjdDtcbiAgICAvLyBTZXQgdXAgbmV0d29yayBjb25maWd1cmF0aW9uIHdpdGggVlBDIHN1cHBvcnRcbiAgICB0aGlzLm5ldHdvcmtDb25maWd1cmF0aW9uID0gcHJvcHMubmV0d29ya0NvbmZpZ3VyYXRpb24gPz8gUnVudGltZU5ldHdvcmtDb25maWd1cmF0aW9uLnVzaW5nUHVibGljTmV0d29yaygpO1xuICAgIC8vIFNldCBjb25uZWN0aW9ucyAtIGNyZWF0ZSBhIHNoYXJlZCBjb25uZWN0aW9ucyBvYmplY3RcbiAgICBpZiAodGhpcy5uZXR3b3JrQ29uZmlndXJhdGlvbi5jb25uZWN0aW9ucykge1xuICAgICAgLy8gVXNlIHRoZSBuZXR3b3JrIGNvbmZpZ3VyYXRpb24ncyBjb25uZWN0aW9ucyBhcyB0aGUgc2hhcmVkIG9iamVjdFxuICAgICAgdGhpcy5fY29ubmVjdGlvbnMgPSB0aGlzLm5ldHdvcmtDb25maWd1cmF0aW9uLmNvbm5lY3Rpb25zO1xuICAgIH1cbiAgICB0aGlzLnByb3RvY29sQ29uZmlndXJhdGlvbiA9IHByb3BzLnByb3RvY29sQ29uZmlndXJhdGlvbiA/PyBQcm90b2NvbFR5cGUuSFRUUDtcbiAgICB0aGlzLmF1dGhvcml6ZXJDb25maWd1cmF0aW9uID0gcHJvcHMuYXV0aG9yaXplckNvbmZpZ3VyYXRpb247XG5cbiAgICBjb25zdCBjZm5Qcm9wczogYW55ID0ge1xuICAgICAgYWdlbnRSdW50aW1lTmFtZTogdGhpcy5hZ2VudFJ1bnRpbWVOYW1lLFxuICAgICAgcm9sZUFybjogdGhpcy5yb2xlLnJvbGVBcm4sXG4gICAgICBhZ2VudFJ1bnRpbWVBcnRpZmFjdDogTGF6eS5hbnkoe1xuICAgICAgICBwcm9kdWNlOiAoKSA9PiB0aGlzLnJlbmRlckFnZW50UnVudGltZUFydGlmYWN0KCksXG4gICAgICB9KSxcbiAgICAgIG5ldHdvcmtDb25maWd1cmF0aW9uOiBMYXp5LmFueSh7XG4gICAgICAgIHByb2R1Y2U6ICgpID0+IHRoaXMubmV0d29ya0NvbmZpZ3VyYXRpb24uX3JlbmRlcih0aGlzLl9jb25uZWN0aW9ucyksXG4gICAgICB9KSxcbiAgICAgIHByb3RvY29sQ29uZmlndXJhdGlvbjogTGF6eS5zdHJpbmcoe1xuICAgICAgICBwcm9kdWNlOiAoKSA9PiB0aGlzLnByb3RvY29sQ29uZmlndXJhdGlvbixcbiAgICAgIH0pLFxuICAgICAgZGVzY3JpcHRpb246IHByb3BzLmRlc2NyaXB0aW9uLFxuICAgICAgZW52aXJvbm1lbnRWYXJpYWJsZXM6IExhenkuYW55KHtcbiAgICAgICAgcHJvZHVjZTogKCkgPT4gdGhpcy5yZW5kZXJFbnZpcm9ubWVudFZhcmlhYmxlcyhwcm9wcy5lbnZpcm9ubWVudFZhcmlhYmxlcyksXG4gICAgICB9KSxcbiAgICAgIHRhZ3M6IHByb3BzLnRhZ3MgPz8ge30sXG4gICAgfTtcbiAgICBpZiAocHJvcHMuYXV0aG9yaXplckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIGNmblByb3BzLmF1dGhvcml6ZXJDb25maWd1cmF0aW9uID0gTGF6eS5hbnkoe1xuICAgICAgICBwcm9kdWNlOiAoKSA9PiB0aGlzLmF1dGhvcml6ZXJDb25maWd1cmF0aW9uIS5fcmVuZGVyKCksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnJ1bnRpbWVSZXNvdXJjZSA9IG5ldyBiZWRyb2NrYWdlbnRjb3JlLkNmblJ1bnRpbWUodGhpcywgJ1Jlc291cmNlJywgY2ZuUHJvcHMgYXMgYmVkcm9ja2FnZW50Y29yZS5DZm5SdW50aW1lUHJvcHMpO1xuXG4gICAgLy8gQWRkIGRlcGVuZGVuY3kgb24gdGhlIHJvbGUgKGZvciBib3RoIGN1c3RvbSBhbmQgYXV0by1jcmVhdGVkIHJvbGVzKVxuICAgIC8vIFRoaXMgZW5zdXJlcyB0aGUgUnVudGltZSB3YWl0cyBmb3IgdGhlIHJvbGUgYW5kIGFsbCBpdHMgcG9saWNpZXMgKGluY2x1ZGluZyBFQ1IgcGVybWlzc2lvbnMpIHRvIGJlIGNyZWF0ZWRcbiAgICB0aGlzLnJ1bnRpbWVSZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3kodGhpcy5yb2xlKTtcblxuICAgIHRoaXMuYWdlbnRSdW50aW1lSWQgPSB0aGlzLnJ1bnRpbWVSZXNvdXJjZS5hdHRyQWdlbnRSdW50aW1lSWQ7XG4gICAgdGhpcy5hZ2VudFJ1bnRpbWVBcm4gPSB0aGlzLnJ1bnRpbWVSZXNvdXJjZS5hdHRyQWdlbnRSdW50aW1lQXJuO1xuICAgIHRoaXMuYWdlbnRTdGF0dXMgPSB0aGlzLnJ1bnRpbWVSZXNvdXJjZS5hdHRyU3RhdHVzO1xuICAgIHRoaXMuYWdlbnRSdW50aW1lVmVyc2lvbiA9IHRoaXMucnVudGltZVJlc291cmNlLmF0dHJBZ2VudFJ1bnRpbWVWZXJzaW9uO1xuICAgIHRoaXMuY3JlYXRlZEF0ID0gdGhpcy5ydW50aW1lUmVzb3VyY2UuYXR0ckNyZWF0ZWRBdDtcbiAgICB0aGlzLmxhc3RVcGRhdGVkQXQgPSB0aGlzLnJ1bnRpbWVSZXNvdXJjZS5hdHRyTGFzdFVwZGF0ZWRBdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXJzIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgZm9yIENsb3VkRm9ybWF0aW9uXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHJpdmF0ZSByZW5kZXJFbnZpcm9ubWVudFZhcmlhYmxlcyhlbnZWYXJzPzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSk6IGFueSB7XG4gICAgaWYgKCFlbnZWYXJzIHx8IE9iamVjdC5rZXlzKGVudlZhcnMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIGVudlZhcnM7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBleGVjdXRpb24gcm9sZSBmb3IgdGhlIGFnZW50IHJ1bnRpbWUgd2l0aCBwcm9wZXIgcGVybWlzc2lvbnNcbiAgICogQmFzZWQgb246IGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9iZWRyb2NrLWFnZW50Y29yZS9sYXRlc3QvZGV2Z3VpZGUvcnVudGltZS1wZXJtaXNzaW9ucy5odG1sXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUV4ZWN1dGlvblJvbGUoKTogaWFtLlJvbGUge1xuICAgIGNvbnN0IHJvbGUgPSBuZXcgaWFtLlJvbGUodGhpcywgJ0V4ZWN1dGlvblJvbGUnLCB7XG4gICAgICBhc3N1bWVkQnk6IG5ldyBpYW0uU2VydmljZVByaW5jaXBhbCgnYmVkcm9jay1hZ2VudGNvcmUuYW1hem9uYXdzLmNvbScpLFxuICAgICAgZGVzY3JpcHRpb246ICdFeGVjdXRpb24gcm9sZSBmb3IgQmVkcm9jayBBZ2VudCBDb3JlIFJ1bnRpbWUnLFxuICAgICAgbWF4U2Vzc2lvbkR1cmF0aW9uOiBEdXJhdGlvbi5ob3Vycyg4KSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlZ2lvbiA9IFN0YWNrLm9mKHRoaXMpLnJlZ2lvbjtcbiAgICBjb25zdCBhY2NvdW50ID0gU3RhY2sub2YodGhpcykuYWNjb3VudDtcblxuICAgIC8vIENsb3VkV2F0Y2ggTG9ncyAtIExvZyBHcm91cCBvcGVyYXRpb25zXG4gICAgcm9sZS5hZGRUb1BvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBzaWQ6ICdMb2dHcm91cEFjY2VzcycsXG4gICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgICBhY3Rpb25zOiBSVU5USU1FX0xPR1NfR1JPVVBfQUNUSU9OUyxcbiAgICAgIHJlc291cmNlczogW2Bhcm46JHtTdGFjay5vZih0aGlzKS5wYXJ0aXRpb259OmxvZ3M6JHtyZWdpb259OiR7YWNjb3VudH06bG9nLWdyb3VwOi9hd3MvYmVkcm9jay1hZ2VudGNvcmUvcnVudGltZXMvKmBdLFxuICAgIH0pKTtcblxuICAgIC8vIENsb3VkV2F0Y2ggTG9ncyAtIERlc2NyaWJlIGFsbCBsb2cgZ3JvdXBzXG4gICAgcm9sZS5hZGRUb1BvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBzaWQ6ICdEZXNjcmliZUxvZ0dyb3VwcycsXG4gICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgICBhY3Rpb25zOiBSVU5USU1FX0xPR1NfREVTQ1JJQkVfQUNUSU9OUyxcbiAgICAgIHJlc291cmNlczogW2Bhcm46JHtTdGFjay5vZih0aGlzKS5wYXJ0aXRpb259OmxvZ3M6JHtyZWdpb259OiR7YWNjb3VudH06bG9nLWdyb3VwOipgXSxcbiAgICB9KSk7XG5cbiAgICAvLyBDbG91ZFdhdGNoIExvZ3MgLSBMb2cgU3RyZWFtIG9wZXJhdGlvbnNcbiAgICByb2xlLmFkZFRvUG9saWN5KG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIHNpZDogJ0xvZ1N0cmVhbUFjY2VzcycsXG4gICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgICBhY3Rpb25zOiBSVU5USU1FX0xPR1NfU1RSRUFNX0FDVElPTlMsXG4gICAgICByZXNvdXJjZXM6IFtgYXJuOiR7U3RhY2sub2YodGhpcykucGFydGl0aW9ufTpsb2dzOiR7cmVnaW9ufToke2FjY291bnR9OmxvZy1ncm91cDovYXdzL2JlZHJvY2stYWdlbnRjb3JlL3J1bnRpbWVzLyo6bG9nLXN0cmVhbToqYF0sXG4gICAgfSkpO1xuXG4gICAgLy8gWC1SYXkgVHJhY2luZyAtIG11c3QgYmUgKiBmb3IgdHJhY2luZ1xuICAgIHJvbGUuYWRkVG9Qb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgc2lkOiAnWFJheUFjY2VzcycsXG4gICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgICBhY3Rpb25zOiBSVU5USU1FX1hSQVlfQUNUSU9OUyxcbiAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgfSkpO1xuXG4gICAgLy8gQ2xvdWRXYXRjaCBNZXRyaWNzIC0gc2NvcGVkIHRvIGJlZHJvY2stYWdlbnRjb3JlIG5hbWVzcGFjZVxuICAgIHJvbGUuYWRkVG9Qb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgc2lkOiAnQ2xvdWRXYXRjaE1ldHJpY3MnLFxuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgYWN0aW9uczogUlVOVElNRV9DTE9VRFdBVENIX01FVFJJQ1NfQUNUSU9OUyxcbiAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgICBjb25kaXRpb25zOiB7XG4gICAgICAgIFN0cmluZ0VxdWFsczoge1xuICAgICAgICAgICdjbG91ZHdhdGNoOm5hbWVzcGFjZSc6IFJVTlRJTUVfQ0xPVURXQVRDSF9OQU1FU1BBQ0UsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pKTtcblxuICAgIC8vIEJlZHJvY2sgQWdlbnRDb3JlIFdvcmtsb2FkIElkZW50aXR5IEFjY2Vzc1xuICAgIC8vIE5vdGU6IFRoZSBhZ2VudCBuYW1lIHdpbGwgYmUgZGV0ZXJtaW5lZCBhdCBydW50aW1lLCBzbyB3ZSB1c2UgYSB3aWxkY2FyZCBwYXR0ZXJuXG4gICAgcm9sZS5hZGRUb1BvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBzaWQ6ICdHZXRBZ2VudEFjY2Vzc1Rva2VuJyxcbiAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgIGFjdGlvbnM6IFJVTlRJTUVfV09SS0xPQURfSURFTlRJVFlfQUNUSU9OUyxcbiAgICAgIHJlc291cmNlczogW1xuICAgICAgICBgYXJuOiR7U3RhY2sub2YodGhpcykucGFydGl0aW9ufTpiZWRyb2NrLWFnZW50Y29yZToke3JlZ2lvbn06JHthY2NvdW50fTp3b3JrbG9hZC1pZGVudGl0eS1kaXJlY3RvcnkvZGVmYXVsdGAsXG4gICAgICAgIGBhcm46JHtTdGFjay5vZih0aGlzKS5wYXJ0aXRpb259OmJlZHJvY2stYWdlbnRjb3JlOiR7cmVnaW9ufToke2FjY291bnR9Ondvcmtsb2FkLWlkZW50aXR5LWRpcmVjdG9yeS9kZWZhdWx0L3dvcmtsb2FkLWlkZW50aXR5LypgLFxuICAgICAgXSxcbiAgICB9KSk7XG4gICAgcmV0dXJuIHJvbGU7XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVycyB0aGUgYXJ0aWZhY3QgY29uZmlndXJhdGlvbiBmb3IgQ2xvdWRGb3JtYXRpb25cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcml2YXRlIHJlbmRlckFnZW50UnVudGltZUFydGlmYWN0KCk6IGFueSB7XG4gICAgLy8gc2V0IHBlcm1pc3Npb24gd2l0aCBiaW5kXG4gICAgdGhpcy5hZ2VudFJ1bnRpbWVBcnRpZmFjdC5iaW5kKHRoaXMsIHRoaXMpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuYWdlbnRSdW50aW1lQXJ0aWZhY3QuX3JlbmRlcigpO1xuICAgIGNvbnN0IGNvbnRhaW5lclVyaSA9IChjb25maWcgYXMgYW55KS5jb250YWluZXJVcmk7XG4gICAgaWYgKGNvbnRhaW5lclVyaSkge1xuICAgICAgdGhpcy52YWxpZGF0ZUNvbnRhaW5lclVyaShjb250YWluZXJVcmkpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgY29udGFpbmVyQ29uZmlndXJhdGlvbjoge1xuICAgICAgICBjb250YWluZXJVcmk6IGNvbnRhaW5lclVyaSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgdGhlIHJ1bnRpbWUgbmFtZSBmb3JtYXRcbiAgICogUGF0dGVybjogXlthLXpBLVpdW2EtekEtWjAtOV9dezAsNDd9JFxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHZhbGlkYXRpb24gZmFpbHNcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVSdW50aW1lTmFtZSgpOiB2b2lkIHtcbiAgICAvLyBTa2lwIHZhbGlkYXRpb24gaWYgdGhlIG5hbWUgY29udGFpbnMgQ0RLIHRva2VucyAodW5yZXNvbHZlZCB2YWx1ZXMpXG4gICAgaWYgKFRva2VuLmlzVW5yZXNvbHZlZCh0aGlzLmFnZW50UnVudGltZU5hbWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgbGVuZ3RoXG4gICAgY29uc3QgbGVuZ3RoRXJyb3JzID0gdmFsaWRhdGVTdHJpbmdGaWVsZCh7XG4gICAgICB2YWx1ZTogdGhpcy5hZ2VudFJ1bnRpbWVOYW1lLFxuICAgICAgZmllbGROYW1lOiAnUnVudGltZSBuYW1lJyxcbiAgICAgIG1pbkxlbmd0aDogMSxcbiAgICAgIG1heExlbmd0aDogNDgsXG4gICAgfSk7XG5cbiAgICAvLyBWYWxpZGF0ZSBwYXR0ZXJuXG4gICAgY29uc3QgcGF0dGVybkVycm9ycyA9IHZhbGlkYXRlRmllbGRQYXR0ZXJuKFxuICAgICAgdGhpcy5hZ2VudFJ1bnRpbWVOYW1lLFxuICAgICAgJ1J1bnRpbWUgbmFtZScsXG4gICAgICAvXlthLXpBLVpdW2EtekEtWjAtOV9dezAsNDd9JC8sXG4gICAgICAnUnVudGltZSBuYW1lIG11c3Qgc3RhcnQgd2l0aCBhIGxldHRlciBhbmQgY29udGFpbiBvbmx5IGxldHRlcnMsIG51bWJlcnMsIGFuZCB1bmRlcnNjb3JlcycsXG4gICAgKTtcblxuICAgIC8vIENvbWJpbmUgYW5kIHRocm93IGlmIGFueSBlcnJvcnNcbiAgICBjb25zdCBhbGxFcnJvcnMgPSBbLi4ubGVuZ3RoRXJyb3JzLCAuLi5wYXR0ZXJuRXJyb3JzXTtcbiAgICBpZiAoYWxsRXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYWxsRXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBkZXNjcmlwdGlvbiBmb3JtYXRcbiAgICogTXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDEyMDAgY2hhcmFjdGVycyAocGVyIENsb3VkRm9ybWF0aW9uIHNwZWNpZmljYXRpb24pXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdmFsaWRhdGlvbiBmYWlsc1xuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZURlc2NyaXB0aW9uKCk6IHZvaWQge1xuICAgIC8vIFNraXAgdmFsaWRhdGlvbiBpZiB0aGUgZGVzY3JpcHRpb24gY29udGFpbnMgQ0RLIHRva2VucyAodW5yZXNvbHZlZCB2YWx1ZXMpXG4gICAgaWYgKFRva2VuLmlzVW5yZXNvbHZlZCh0aGlzLmRlc2NyaXB0aW9uKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmRlc2NyaXB0aW9uKSB7XG4gICAgICBjb25zdCBlcnJvcnMgPSB2YWxpZGF0ZVN0cmluZ0ZpZWxkKHtcbiAgICAgICAgdmFsdWU6IHRoaXMuZGVzY3JpcHRpb24sXG4gICAgICAgIGZpZWxkTmFtZTogJ0Rlc2NyaXB0aW9uJyxcbiAgICAgICAgbWluTGVuZ3RoOiAxLFxuICAgICAgICBtYXhMZW5ndGg6IDEyMDAsXG4gICAgICB9KTtcblxuICAgICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGVudmlyb25tZW50IHZhcmlhYmxlc1xuICAgKiAtIE1heGltdW0gNTAgZW50cmllc1xuICAgKiAtIEtleTogMS0xMDAgY2hhcmFjdGVyc1xuICAgKiAtIFZhbHVlOiAwLTIwNDggY2hhcmFjdGVycyAocGVyIENsb3VkRm9ybWF0aW9uIHNwZWNpZmljYXRpb24pXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdmFsaWRhdGlvbiBmYWlsc1xuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUVudmlyb25tZW50VmFyaWFibGVzKGVudlZhcnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0pOiB2b2lkIHtcbiAgICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXMoZW52VmFycyk7XG5cbiAgICAvLyBWYWxpZGF0ZSBudW1iZXIgb2YgZW50cmllcyAoMC01MClcbiAgICBpZiAoZW50cmllcy5sZW5ndGggPiA1MCkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgYFRvbyBtYW55IGVudmlyb25tZW50IHZhcmlhYmxlczogJHtlbnRyaWVzLmxlbmd0aH0uIE1heGltdW0gYWxsb3dlZCBpcyA1MGAsXG4gICAgICApO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIGVudHJpZXMpIHtcbiAgICAgIC8vIFNraXAgdmFsaWRhdGlvbiBpZiBrZXkgb3IgdmFsdWUgY29udGFpbnMgQ0RLIHRva2Vuc1xuICAgICAgaWYgKFRva2VuLmlzVW5yZXNvbHZlZChrZXkpIHx8IFRva2VuLmlzVW5yZXNvbHZlZCh2YWx1ZSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIFZhbGlkYXRlIGtleSBsZW5ndGhcbiAgICAgIGNvbnN0IGxlbmd0aEVycm9ycyA9IHZhbGlkYXRlU3RyaW5nRmllbGQoe1xuICAgICAgICB2YWx1ZToga2V5LFxuICAgICAgICBmaWVsZE5hbWU6IGBFbnZpcm9ubWVudCB2YXJpYWJsZSBrZXkgJyR7a2V5fSdgLFxuICAgICAgICBtaW5MZW5ndGg6IDEsXG4gICAgICAgIG1heExlbmd0aDogMTAwLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFZhbGlkYXRlIGtleSBwYXR0ZXJuXG4gICAgICBjb25zdCBwYXR0ZXJuRXJyb3JzID0gdmFsaWRhdGVGaWVsZFBhdHRlcm4oXG4gICAgICAgIGtleSxcbiAgICAgICAgYEVudmlyb25tZW50IHZhcmlhYmxlIGtleSAnJHtrZXl9J2AsXG4gICAgICAgIC9eW2EtekEtWl9dW2EtekEtWjAtOV9dKiQvLFxuICAgICAgICBgRW52aXJvbm1lbnQgdmFyaWFibGUga2V5ICcke2tleX0nIG11c3Qgc3RhcnQgd2l0aCBhIGxldHRlciBvciB1bmRlcnNjb3JlIGFuZCBjb250YWluIG9ubHkgbGV0dGVycywgbnVtYmVycywgYW5kIHVuZGVyc2NvcmVzYCxcbiAgICAgICk7XG5cbiAgICAgIC8vIENvbWJpbmUgYW5kIHRocm93IGlmIGFueSBlcnJvcnNcbiAgICAgIGNvbnN0IGFsbEVycm9ycyA9IFsuLi5sZW5ndGhFcnJvcnMsIC4uLnBhdHRlcm5FcnJvcnNdO1xuICAgICAgaWYgKGFsbEVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYWxsRXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICAgIH1cblxuICAgICAgLy8gVmFsaWRhdGUgdmFsdWUgbGVuZ3RoICgwLTIwNDggY2hhcmFjdGVycyBwZXIgQ2xvdWRGb3JtYXRpb24pXG4gICAgICBpZiAodmFsdWUubGVuZ3RoID4gMjA0OCkge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGBJbnZhbGlkIGVudmlyb25tZW50IHZhcmlhYmxlIHZhbHVlIGxlbmd0aCBmb3Iga2V5ICcke2tleX0nOiAke3ZhbHVlLmxlbmd0aH0gY2hhcmFjdGVycy4gYCArXG4gICAgICAgICAgJ1ZhbHVlcyBtdXN0IG5vdCBleGNlZWQgMjA0OCBjaGFyYWN0ZXJzJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSB0YWdzIGZvcm1hdFxuICAgKiBAcGFyYW0gdGFncyBUaGUgdGFncyBvYmplY3QgdG8gdmFsaWRhdGVcbiAgICogQHRocm93cyBFcnJvciBpZiB2YWxpZGF0aW9uIGZhaWxzXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlVGFncyh0YWdzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KTogdm9pZCB7XG4gICAgLy8gVmFsaWRhdGUgZWFjaCB0YWcga2V5IGFuZCB2YWx1ZVxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHRhZ3MpKSB7XG4gICAgICAvLyBTa2lwIHZhbGlkYXRpb24gaWYga2V5IG9yIHZhbHVlIGNvbnRhaW5zIENESyB0b2tlbnNcbiAgICAgIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQoa2V5KSB8fCBUb2tlbi5pc1VucmVzb2x2ZWQodmFsdWUpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBWYWxpZGF0ZSB0YWcga2V5IGxlbmd0aFxuICAgICAgY29uc3Qga2V5TGVuZ3RoRXJyb3JzID0gdmFsaWRhdGVTdHJpbmdGaWVsZCh7XG4gICAgICAgIHZhbHVlOiBrZXksXG4gICAgICAgIGZpZWxkTmFtZTogYFRhZyBrZXkgXCIke2tleX1cImAsXG4gICAgICAgIG1pbkxlbmd0aDogMSxcbiAgICAgICAgbWF4TGVuZ3RoOiAyNTYsXG4gICAgICB9KTtcblxuICAgICAgLy8gVmFsaWRhdGUgdGFnIGtleSBwYXR0ZXJuXG4gICAgICBjb25zdCBrZXlQYXR0ZXJuRXJyb3JzID0gdmFsaWRhdGVGaWVsZFBhdHRlcm4oXG4gICAgICAgIGtleSxcbiAgICAgICAgYFRhZyBrZXkgXCIke2tleX1cImAsXG4gICAgICAgIC9eW2EtekEtWjAtOVxccy5fOi89K0AtXSokLyxcbiAgICAgICAgYFRhZyBrZXkgXCIke2tleX1cIiBjYW4gb25seSBjb250YWluIGxldHRlcnMgKGEteiwgQS1aKSwgbnVtYmVycyAoMC05KSwgc3BhY2VzLCBhbmQgc3BlY2lhbCBjaGFyYWN0ZXJzICguXzovPStALSlgLFxuICAgICAgKTtcblxuICAgICAgLy8gQ29tYmluZSBrZXkgZXJyb3JzIGFuZCB0aHJvdyBpZiBhbnlcbiAgICAgIGNvbnN0IGtleUVycm9ycyA9IFsuLi5rZXlMZW5ndGhFcnJvcnMsIC4uLmtleVBhdHRlcm5FcnJvcnNdO1xuICAgICAgaWYgKGtleUVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3Ioa2V5RXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgVGFnIHZhbHVlIGZvciBrZXkgXCIke2tleX1cIiBjYW5ub3QgYmUgbnVsbCBvciB1bmRlZmluZWRgKTtcbiAgICAgIH1cblxuICAgICAgLy8gVmFsaWRhdGUgdGFnIHZhbHVlIGxlbmd0aFxuICAgICAgY29uc3QgdmFsdWVMZW5ndGhFcnJvcnMgPSB2YWxpZGF0ZVN0cmluZ0ZpZWxkKHtcbiAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICBmaWVsZE5hbWU6IGBUYWcgdmFsdWUgZm9yIGtleSBcIiR7a2V5fVwiYCxcbiAgICAgICAgbWluTGVuZ3RoOiAwLFxuICAgICAgICBtYXhMZW5ndGg6IDI1NixcbiAgICAgIH0pO1xuXG4gICAgICAvLyBWYWxpZGF0ZSB0YWcgdmFsdWUgcGF0dGVyblxuICAgICAgY29uc3QgdmFsdWVQYXR0ZXJuRXJyb3JzID0gdmFsaWRhdGVGaWVsZFBhdHRlcm4oXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBgVGFnIHZhbHVlIGZvciBrZXkgXCIke2tleX1cImAsXG4gICAgICAgIC9eW2EtekEtWjAtOVxccy5fOi89K0AtXSokLyxcbiAgICAgICAgYFRhZyB2YWx1ZSBmb3Iga2V5IFwiJHtrZXl9XCIgY2FuIG9ubHkgY29udGFpbiBsZXR0ZXJzIChhLXosIEEtWiksIG51bWJlcnMgKDAtOSksIHNwYWNlcywgYW5kIHNwZWNpYWwgY2hhcmFjdGVycyAoLl86Lz0rQC0pYCxcbiAgICAgICk7XG5cbiAgICAgIC8vIENvbWJpbmUgdmFsdWUgZXJyb3JzIGFuZCB0aHJvdyBpZiBhbnlcbiAgICAgIGNvbnN0IHZhbHVlRXJyb3JzID0gWy4uLnZhbHVlTGVuZ3RoRXJyb3JzLCAuLi52YWx1ZVBhdHRlcm5FcnJvcnNdO1xuICAgICAgaWYgKHZhbHVlRXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcih2YWx1ZUVycm9ycy5qb2luKCdcXG4nKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGUgY29udGFpbmVyIFVSSSBmb3JtYXRcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVDb250YWluZXJVcmkodXJpOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAvLyBTa2lwIHZhbGlkYXRpb24gaWYgdGhlIFVSSSBjb250YWlucyBDREsgdG9rZW5zICh1bnJlc29sdmVkIHZhbHVlcylcbiAgICBpZiAoVG9rZW4uaXNVbnJlc29sdmVkKHVyaSkpIHtcbiAgICAgIC8vIEFkZCBhIHdhcm5pbmcgdGhhdCB2YWxpZGF0aW9uIHdpbGwgYmUgc2tpcHBlZCBmb3IgdG9rZW4tYmFzZWQgVVJJc1xuICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkSW5mbyhcbiAgICAgICAgJ0NvbnRhaW5lciBVUkkgdmFsaWRhdGlvbiBza2lwcGVkIGFzIGl0IGNvbnRhaW5zIHVucmVzb2x2ZWQgQ0RLIHRva2Vucy4gJyArXG4gICAgICAgICdUaGUgVVJJIHdpbGwgYmUgdmFsaWRhdGVkIGF0IGRlcGxveW1lbnQgdGltZS4nLFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBPbmx5IHZhbGlkYXRlIGlmIHRoZSBVUkkgaXMgYSBjb25jcmV0ZSBzdHJpbmcgKG5vdCBhIHRva2VuKVxuICAgIGNvbnN0IHBhdHRlcm4gPSAvXlxcZHsxMn1cXC5ka3JcXC5lY3JcXC4oW2EtejAtOS1dKylcXC5hbWF6b25hd3NcXC5jb21cXC8oKD86W2EtejAtOV0rKD86Wy5fLV1bYS16MC05XSspKlxcLykqW2EtejAtOV0rKD86Wy5fLV1bYS16MC05XSspKikoWzpAXVxcUyspJC87XG4gICAgaWYgKCFwYXR0ZXJuLnRlc3QodXJpKSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgYEludmFsaWQgY29udGFpbmVyIFVSSSBmb3JtYXQ6ICR7dXJpfS4gTXVzdCBiZSBhIHZhbGlkIEVDUiBVUkkgKGUuZy4sIDEyMzQ1Njc4OTAxMi5ka3IuZWNyLnVzLXdlc3QtMi5hbWF6b25hd3MuY29tL215LWFnZW50OmxhdGVzdClgLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBJQU0gcm9sZSBBUk4gZm9ybWF0IGFuZCBzdHJ1Y3R1cmVcbiAgICogQHRocm93cyBFcnJvciBpZiB2YWxpZGF0aW9uIGZhaWxzXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlUm9sZUFybihyb2xlQXJuOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAvLyBWYWxpZGF0ZSBiYXNpYyBBUk4gZm9ybWF0IGZvciBJQU0gcm9sZXNcbiAgICBjb25zdCBhcm5QYXR0ZXJuID0gL15hcm46W2EtelxcLV0rOmlhbTo6XFxkezEyfTpyb2xlXFwvW2EtekEtWjAtOSs9LC5AXFwtX1xcL10rJC87XG4gICAgaWYgKCFhcm5QYXR0ZXJuLnRlc3Qocm9sZUFybikpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgSUFNIHJvbGUgQVJOIGZvcm1hdDogJHtyb2xlQXJufS4gYCArXG4gICdFeHBlY3RlZCBmb3JtYXQ6IGFybjo8cGFydGl0aW9uPjppYW06OjxhY2NvdW50LWlkPjpyb2xlLzxyb2xlLW5hbWU+IG9yIGFybjo8cGFydGl0aW9uPjppYW06OjxhY2NvdW50LWlkPjpyb2xlLzxwYXRoPi88cm9sZS1uYW1lPicpO1xuICAgIH1cblxuICAgIC8vIFBhcnNlIHRoZSBBUk4gY29tcG9uZW50cyB1c2luZyBDREsncyBBcm4uc3BsaXQoKVxuICAgIC8vIFVzZSBTTEFTSF9SRVNPVVJDRV9OQU1FIGZvcm1hdCBmb3IgSUFNIHJvbGVzICh3aGljaCB1c2UgZm9ybWF0OiByb2xlL3JvbGUtbmFtZSBvciByb2xlL3BhdGgvdG8vcm9sZS1uYW1lKVxuICAgIGNvbnN0IGFybkNvbXBvbmVudHMgPSBBcm4uc3BsaXQocm9sZUFybiwgQXJuRm9ybWF0LlNMQVNIX1JFU09VUkNFX05BTUUpO1xuXG4gICAgaWYgKGFybkNvbXBvbmVudHMuc2VydmljZSAhPT0gJ2lhbScpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgc2VydmljZSBpbiBBUk46ICR7YXJuQ29tcG9uZW50cy5zZXJ2aWNlfS4gRXhwZWN0ZWQgJ2lhbScgZm9yIElBTSByb2xlIEFSTi5gKTtcbiAgICB9XG5cbiAgICBjb25zdCBhY2NvdW50SWQgPSBhcm5Db21wb25lbnRzLmFjY291bnQ7XG4gICAgaWYgKCFhY2NvdW50SWQgfHwgIS9eXFxkezEyfSQvLnRlc3QoYWNjb3VudElkKSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBBV1MgYWNjb3VudCBJRCBpbiByb2xlIEFSTjogJHthY2NvdW50SWR9LiBNdXN0IGJlIGEgMTItZGlnaXQgbnVtYmVyLmApO1xuICAgIH1cblxuICAgIC8vIEV4dHJhY3Qgcm9sZSBuYW1lIGZyb20gcmVzb3VyY2VcbiAgICAvLyBGb3IgSUFNIHJvbGVzLCByZXNvdXJjZSB3aWxsIGJlIFwicm9sZVwiIGFuZCByZXNvdXJjZU5hbWUgd2lsbCBiZSB0aGUgcm9sZSBuYW1lICh3aXRoIG9wdGlvbmFsIHBhdGgpXG4gICAgY29uc3QgcmVzb3VyY2UgPSBhcm5Db21wb25lbnRzLnJlc291cmNlO1xuICAgIGNvbnN0IHJlc291cmNlTmFtZSA9IGFybkNvbXBvbmVudHMucmVzb3VyY2VOYW1lO1xuXG4gICAgaWYgKHJlc291cmNlICE9PSAncm9sZScpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgcmVzb3VyY2UgdHlwZSBpbiBBUk46ICR7cmVzb3VyY2V9LiBFeHBlY3RlZCAncm9sZScgZm9yIElBTSByb2xlIEFSTi5gKTtcbiAgICB9XG5cbiAgICBpZiAoIXJlc291cmNlTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignUm9sZSBuYW1lIGlzIG1pc3NpbmcgaW4gdGhlIEFSTicpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCByb2xlUGF0aFBhcnRzID0gcmVzb3VyY2VOYW1lLnNwbGl0KCcvJyk7XG4gICAgICBjb25zdCByb2xlTmFtZSA9IHJvbGVQYXRoUGFydHNbcm9sZVBhdGhQYXJ0cy5sZW5ndGggLSAxXTtcblxuICAgICAgaWYgKHJvbGVOYW1lLmxlbmd0aCA+IDY0KSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYFJvbGUgbmFtZSBleGNlZWRzIG1heGltdW0gbGVuZ3RoIG9mIDY0IGNoYXJhY3RlcnM6ICR7cm9sZU5hbWV9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhY2tBY2NvdW50ID0gU3RhY2sub2YodGhpcykuYWNjb3VudDtcbiAgICBpZiAoIVRva2VuLmlzVW5yZXNvbHZlZChzdGFja0FjY291bnQpICYmIGFjY291bnRJZCAhPT0gc3RhY2tBY2NvdW50KSB7XG4gICAgICBBbm5vdGF0aW9ucy5vZih0aGlzKS5hZGRXYXJuaW5nKFxuICAgICAgICBgSUFNIHJvbGUgaXMgZnJvbSBhIGRpZmZlcmVudCBhY2NvdW50ICgke2FjY291bnRJZH0pIHRoYW4gdGhlIHN0YWNrIGFjY291bnQgKCR7c3RhY2tBY2NvdW50fSkuIGAgK1xuICAgICAgICAnRW5zdXJlIGNyb3NzLWFjY291bnQgcGVybWlzc2lvbnMgYXJlIHByb3Blcmx5IGNvbmZpZ3VyZWQuJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgdGhlIHJlZ2lvbiAoSUFNIGlzIGdsb2JhbCwgc28gcmVnaW9uIHNob3VsZCBiZSBlbXB0eSlcbiAgICBjb25zdCByZWdpb24gPSBhcm5Db21wb25lbnRzLnJlZ2lvbjtcbiAgICBjb25zdCBzdGFja1JlZ2lvbiA9IFN0YWNrLm9mKHRoaXMpLnJlZ2lvbjtcbiAgICBpZiAocmVnaW9uICYmIHJlZ2lvbiAhPT0gJycgJiYgcmVnaW9uICE9PSBzdGFja1JlZ2lvbiAmJiAhVG9rZW4uaXNVbnJlc29sdmVkKHN0YWNrUmVnaW9uKSkge1xuICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkV2FybmluZyhcbiAgICAgICAgYElBTSByb2xlIEFSTiBjb250YWlucyBhIHJlZ2lvbiAoJHtyZWdpb259KSB0aGF0IGRvZXNuJ3QgbWF0Y2ggdGhlIHN0YWNrIHJlZ2lvbiAoJHtzdGFja1JlZ2lvbn0pLiBgICtcbiAgICAgICAgJ0lBTSBpcyBhIGdsb2JhbCBzZXJ2aWNlLCBzbyB0aGlzIG1pZ2h0IGJlIGludGVudGlvbmFsLicsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYW4gZW5kcG9pbnQgdG8gdGhpcyBydW50aW1lXG4gICAqIFRoaXMgaXMgYSBjb252ZW5pZW5jZSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgUnVudGltZUVuZHBvaW50IGFzc29jaWF0ZWQgd2l0aCB0aGlzIHJ1bnRpbWVcbiAgICpcbiAgICogQHBhcmFtIGVuZHBvaW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgZW5kcG9pbnRcbiAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9uYWwgY29uZmlndXJhdGlvbiBmb3IgdGhlIGVuZHBvaW50XG4gICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIFJ1bnRpbWVFbmRwb2ludFxuICAgKi9cbiAgQE1ldGhvZE1ldGFkYXRhKClcbiAgcHVibGljIGFkZEVuZHBvaW50KFxuICAgIGVuZHBvaW50TmFtZTogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBBZGRFbmRwb2ludE9wdGlvbnMsXG4gICk6IFJ1bnRpbWVFbmRwb2ludCB7XG4gICAgLy8gQ3JlYXRlIHRoZSBlbmRwb2ludCAoc2VjdXJpdHkgY29uZmlndXJhdGlvbiBpcyBubyBsb25nZXIgc3VwcG9ydGVkKVxuICAgIGNvbnN0IGVuZHBvaW50ID0gbmV3IFJ1bnRpbWVFbmRwb2ludCh0aGlzLCBgRW5kcG9pbnQke2VuZHBvaW50TmFtZX1gLCB7XG4gICAgICBlbmRwb2ludE5hbWU6IGVuZHBvaW50TmFtZSxcbiAgICAgIGFnZW50UnVudGltZUlkOiB0aGlzLmFnZW50UnVudGltZUlkLFxuICAgICAgYWdlbnRSdW50aW1lVmVyc2lvbjogb3B0aW9ucz8udmVyc2lvbiA/PyB0aGlzLmFnZW50UnVudGltZVZlcnNpb24gPz8gJzEnLFxuICAgICAgZGVzY3JpcHRpb246IG9wdGlvbnM/LmRlc2NyaXB0aW9uLFxuICAgIH0pO1xuXG4gICAgLy8gQWRkIGRlcGVuZGVuY3k6IGVuZHBvaW50IG11c3Qgd2FpdCBmb3IgcnVudGltZSB0byBiZSBjcmVhdGVkXG4gICAgZW5kcG9pbnQubm9kZS5hZGREZXBlbmRlbmN5KHRoaXMucnVudGltZVJlc291cmNlKTtcblxuICAgIHJldHVybiBlbmRwb2ludDtcbiAgfVxufVxuIl19
|