@aws-cdk/aws-elasticache-alpha 2.219.0-alpha.0 → 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.
@@ -1,12 +1,38 @@
1
1
  "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
7
35
  };
8
- var _a;
9
- var ServerlessCache_1;
10
36
  Object.defineProperty(exports, "__esModule", { value: true });
11
37
  exports.ServerlessCache = void 0;
12
38
  const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
@@ -50,380 +76,447 @@ const REQUEST_RATE_MAX_ECPU = 15000000;
50
76
  *
51
77
  * @resource AWS::ElastiCache::ServerlessCache
52
78
  */
53
- let ServerlessCache = ServerlessCache_1 = class ServerlessCache extends serverless_cache_base_1.ServerlessCacheBase {
54
- /**
55
- * Return whether the given object is a `ServerlessCache`
56
- */
57
- static isServerlessCache(x) {
58
- return x !== null && typeof (x) === 'object' && ELASTICACHE_SERVERLESSCACHE_SYMBOL in x;
59
- }
60
- /**
61
- * Import an existing serverless cache by name
62
- *
63
- * @param scope The parent creating construct (usually `this`)
64
- * @param id The construct's name
65
- * @param serverlessCacheName The name of the existing serverless cache
66
- */
67
- static fromServerlessCacheName(scope, id, serverlessCacheName) {
68
- return ServerlessCache_1.fromServerlessCacheAttributes(scope, id, { serverlessCacheName });
69
- }
70
- /**
71
- * Import an existing serverless cache by ARN
72
- *
73
- * @param scope The parent creating construct (usually `this`)
74
- * @param id The construct's name
75
- * @param serverlessCacheArn The ARN of the existing serverless cache
76
- */
77
- static fromServerlessCacheArn(scope, id, serverlessCacheArn) {
78
- return ServerlessCache_1.fromServerlessCacheAttributes(scope, id, { serverlessCacheArn });
79
- }
80
- /**
81
- * Import an existing serverless cache using attributes
82
- *
83
- * @param scope The parent creating construct (usually `this`)
84
- * @param id The construct's name
85
- * @param attrs A `ServerlessCacheAttributes` object
86
- */
87
- static fromServerlessCacheAttributes(scope, id, attrs) {
88
- try {
89
- jsiiDeprecationWarnings._aws_cdk_aws_elasticache_alpha_ServerlessCacheAttributes(attrs);
90
- }
91
- catch (error) {
92
- if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
93
- Error.captureStackTrace(error, this.fromServerlessCacheAttributes);
94
- }
95
- throw error;
79
+ let ServerlessCache = (() => {
80
+ let _classDecorators = [prop_injectable_1.propertyInjectable];
81
+ let _classDescriptor;
82
+ let _classExtraInitializers = [];
83
+ let _classThis;
84
+ let _classSuper = serverless_cache_base_1.ServerlessCacheBase;
85
+ var ServerlessCache = class extends _classSuper {
86
+ static { _classThis = this; }
87
+ static {
88
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
89
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
90
+ ServerlessCache = _classThis = _classDescriptor.value;
91
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
96
92
  }
97
- let name;
98
- let arn;
99
- const stack = core_1.Stack.of(scope);
100
- if (attrs.serverlessCacheArn && attrs.serverlessCacheName) {
101
- throw new core_1.ValidationError('Only one of serverlessCacheArn or serverlessCacheName can be provided.', scope);
93
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-elasticache-alpha.ServerlessCache", version: "2.221.0-alpha.0" };
94
+ /**
95
+ * Uniquely identifies this class.
96
+ */
97
+ static PROPERTY_INJECTION_ID = 'aws-cdk-lib.aws-elasticache.ServerlessCache';
98
+ /**
99
+ * Return whether the given object is a `ServerlessCache`
100
+ */
101
+ static isServerlessCache(x) {
102
+ return x !== null && typeof (x) === 'object' && ELASTICACHE_SERVERLESSCACHE_SYMBOL in x;
102
103
  }
103
- if (attrs.serverlessCacheArn) {
104
- arn = attrs.serverlessCacheArn;
105
- const extractedServerlessCacheName = stack.splitArn(attrs.serverlessCacheArn, core_1.ArnFormat.SLASH_RESOURCE_NAME).resourceName;
106
- if (!extractedServerlessCacheName) {
107
- throw new core_1.ValidationError('Unable to extract serverless cache name from ARN.', scope);
108
- }
109
- name = extractedServerlessCacheName;
110
- }
111
- else if (attrs.serverlessCacheName) {
112
- name = attrs.serverlessCacheName;
113
- arn = stack.formatArn({
114
- service: 'elasticache',
115
- resource: 'serverlesscache',
116
- resourceName: attrs.serverlessCacheName,
117
- });
104
+ /**
105
+ * Import an existing serverless cache by name
106
+ *
107
+ * @param scope The parent creating construct (usually `this`)
108
+ * @param id The construct's name
109
+ * @param serverlessCacheName The name of the existing serverless cache
110
+ */
111
+ static fromServerlessCacheName(scope, id, serverlessCacheName) {
112
+ return ServerlessCache.fromServerlessCacheAttributes(scope, id, { serverlessCacheName });
118
113
  }
119
- else {
120
- throw new core_1.ValidationError('One of serverlessCacheName or serverlessCacheArn is required.', scope);
114
+ /**
115
+ * Import an existing serverless cache by ARN
116
+ *
117
+ * @param scope The parent creating construct (usually `this`)
118
+ * @param id The construct's name
119
+ * @param serverlessCacheArn The ARN of the existing serverless cache
120
+ */
121
+ static fromServerlessCacheArn(scope, id, serverlessCacheArn) {
122
+ return ServerlessCache.fromServerlessCacheAttributes(scope, id, { serverlessCacheArn });
121
123
  }
122
- class Import extends serverless_cache_base_1.ServerlessCacheBase {
123
- constructor(serverlessCacheArn, serverlessCacheName) {
124
- super(scope, id);
125
- this.engine = attrs.engine;
126
- this.backupArnsToRestore = attrs.backupArnsToRestore;
127
- this.kmsKey = attrs.kmsKey;
128
- this.vpc = attrs.vpc;
129
- this.subnets = attrs.subnets;
130
- this.securityGroups = attrs.securityGroups;
131
- this.userGroup = attrs.userGroup;
132
- this.serverlessCacheArn = serverlessCacheArn;
133
- this.serverlessCacheName = serverlessCacheName;
134
- if (this.engine) {
135
- let defaultPort;
136
- switch (this.engine) {
137
- case serverless_cache_base_1.CacheEngine.VALKEY_LATEST:
138
- case serverless_cache_base_1.CacheEngine.VALKEY_7:
139
- case serverless_cache_base_1.CacheEngine.VALKEY_8:
140
- case serverless_cache_base_1.CacheEngine.REDIS_LATEST:
141
- // Document showing the default port
142
- // https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/set-up.html#elasticache-install-grant-access-VPN
143
- defaultPort = ec2.Port.tcp(6379);
144
- break;
145
- case serverless_cache_base_1.CacheEngine.MEMCACHED_LATEST:
146
- // Document showing the default port
147
- // https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/set-up.html#elasticache-install-grant-access-VPN
148
- defaultPort = ec2.Port.tcp(11211);
149
- break;
150
- default:
151
- throw new core_1.ValidationError(`Unsupported cache engine: ${this.engine}`, scope);
152
- }
153
- this.connections = new ec2.Connections({
154
- securityGroups: this.securityGroups,
155
- defaultPort: defaultPort,
156
- });
124
+ /**
125
+ * Import an existing serverless cache using attributes
126
+ *
127
+ * @param scope The parent creating construct (usually `this`)
128
+ * @param id The construct's name
129
+ * @param attrs A `ServerlessCacheAttributes` object
130
+ */
131
+ static fromServerlessCacheAttributes(scope, id, attrs) {
132
+ try {
133
+ jsiiDeprecationWarnings._aws_cdk_aws_elasticache_alpha_ServerlessCacheAttributes(attrs);
134
+ }
135
+ catch (error) {
136
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
137
+ Error.captureStackTrace(error, this.fromServerlessCacheAttributes);
157
138
  }
158
- else {
159
- this.connections = new ec2.Connections({
160
- securityGroups: this.securityGroups,
161
- });
139
+ throw error;
140
+ }
141
+ let name;
142
+ let arn;
143
+ const stack = core_1.Stack.of(scope);
144
+ if (attrs.serverlessCacheArn && attrs.serverlessCacheName) {
145
+ throw new core_1.ValidationError('Only one of serverlessCacheArn or serverlessCacheName can be provided.', scope);
146
+ }
147
+ if (attrs.serverlessCacheArn) {
148
+ arn = attrs.serverlessCacheArn;
149
+ const extractedServerlessCacheName = stack.splitArn(attrs.serverlessCacheArn, core_1.ArnFormat.SLASH_RESOURCE_NAME).resourceName;
150
+ if (!extractedServerlessCacheName) {
151
+ throw new core_1.ValidationError('Unable to extract serverless cache name from ARN.', scope);
162
152
  }
153
+ name = extractedServerlessCacheName;
163
154
  }
164
- }
165
- return new Import(arn, name);
166
- }
167
- constructor(scope, id, props) {
168
- super(scope, id, {});
169
- try {
170
- jsiiDeprecationWarnings._aws_cdk_aws_elasticache_alpha_ServerlessCacheProps(props);
171
- }
172
- catch (error) {
173
- if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
174
- Error.captureStackTrace(error, ServerlessCache);
155
+ else if (attrs.serverlessCacheName) {
156
+ name = attrs.serverlessCacheName;
157
+ arn = stack.formatArn({
158
+ service: 'elasticache',
159
+ resource: 'serverlesscache',
160
+ resourceName: attrs.serverlessCacheName,
161
+ });
175
162
  }
176
- throw error;
177
- }
178
- // Enhanced CDK Analytics Telemetry
179
- (0, metadata_resource_1.addConstructMetadata)(this, props);
180
- this.engine = props.engine ?? serverless_cache_base_1.CacheEngine.VALKEY_LATEST;
181
- this.serverlessCacheName = props.serverlessCacheName ?? core_1.Lazy.string({ produce: () => core_1.Names.uniqueId(this) });
182
- this.kmsKey = props.kmsKey;
183
- this.vpc = props.vpc;
184
- this.userGroup = props.userGroup;
185
- this.validateDescription(props.description);
186
- this.validateDataStorageLimits(props.cacheUsageLimits);
187
- this.validateRequestRateLimits(props.cacheUsageLimits);
188
- this.validateBackupSettings(props.backup);
189
- this.validateUserGroupCompatibility(this.engine, this.userGroup);
190
- const subnetConfig = this.configureSubnets(props);
191
- const subnetIds = subnetConfig.subnetIds;
192
- this.subnets = subnetConfig.subnets;
193
- const securityGroupConfig = this.configureSecurityGroups(props);
194
- const securityGroupIds = securityGroupConfig.securityGroupIds;
195
- this.securityGroups = securityGroupConfig.securityGroups;
196
- const [engine, version] = this.engine.split('_');
197
- const resource = new aws_elasticache_1.CfnServerlessCache(this, 'Resource', {
198
- engine: engine,
199
- majorEngineVersion: version,
200
- serverlessCacheName: this.serverlessCacheName,
201
- description: props.description,
202
- cacheUsageLimits: this.renderCacheUsageLimits(props.cacheUsageLimits),
203
- dailySnapshotTime: props.backup?.backupTime ? this.formatBackupTime(props.backup.backupTime) : undefined,
204
- snapshotRetentionLimit: props.backup?.backupRetentionLimit,
205
- finalSnapshotName: props.backup?.backupNameBeforeDeletion,
206
- snapshotArnsToRestore: props.backup?.backupArnsToRestore,
207
- kmsKeyId: props.kmsKey?.keyId,
208
- subnetIds: subnetIds,
209
- securityGroupIds: securityGroupIds,
210
- userGroupId: props.userGroup?.userGroupName,
211
- });
212
- if (props.userGroup) {
213
- const userGroupResource = props.userGroup.node.findChild('Resource');
214
- resource.addDependency(userGroupResource);
215
- }
216
- this.backupArnsToRestore = resource.snapshotArnsToRestore;
217
- this.serverlessCacheArn = resource.attrArn;
218
- this.serverlessCacheEndpointAddress = resource.attrEndpointAddress;
219
- this.serverlessCacheEndpointPort = resource.attrEndpointPort;
220
- this.serverlessCacheReaderEndpointAddress = resource.attrReaderEndpointAddress;
221
- this.serverlessCacheReaderEndpointPort = resource.attrReaderEndpointPort;
222
- this.serverlessCacheStatus = resource.attrStatus;
223
- this.connections = new ec2.Connections({
224
- securityGroups: this.securityGroups,
225
- defaultPort: ec2.Port.tcp(core_1.Lazy.number({ produce: () => parseInt(this.serverlessCacheEndpointPort) })),
226
- });
227
- Object.defineProperty(this, ELASTICACHE_SERVERLESSCACHE_SYMBOL, { value: true });
228
- }
229
- /**
230
- * Validate description meets AWS requirements
231
- *
232
- * @param description The description to validate
233
- */
234
- validateDescription(description) {
235
- if (!description || core_1.Token.isUnresolved(description))
236
- return;
237
- if (description.length > 255) {
238
- throw new core_1.ValidationError(`Description must not exceed 255 characters, currently has ${description.length}`, this);
239
- }
240
- if (description.includes('<') || description.includes('>')) {
241
- throw new core_1.ValidationError('Description must not contain < or > characters', this);
242
- }
243
- }
244
- /**
245
- * Validate data storage size limits
246
- *
247
- * @param limits The usage limits containing data storage settings
248
- */
249
- validateDataStorageLimits(limits) {
250
- if (!limits)
251
- return;
252
- if (limits.dataStorageMinimumSize && !limits.dataStorageMinimumSize.isUnresolved() &&
253
- (limits.dataStorageMinimumSize.toGibibytes() < DATA_STORAGE_MIN_GB || limits.dataStorageMinimumSize.toGibibytes() > DATA_STORAGE_MAX_GB)) {
254
- throw new core_1.ValidationError('Data storage minimum must be between 1 and 5000 GB.', this);
255
- }
256
- if (limits.dataStorageMaximumSize && !limits.dataStorageMaximumSize.isUnresolved() &&
257
- (limits.dataStorageMaximumSize.toGibibytes() < DATA_STORAGE_MIN_GB || limits.dataStorageMaximumSize.toGibibytes() > DATA_STORAGE_MAX_GB)) {
258
- throw new core_1.ValidationError('Data storage maximum must be between 1 and 5000 GB.', this);
259
- }
260
- if (limits.dataStorageMinimumSize && limits.dataStorageMaximumSize &&
261
- !limits.dataStorageMinimumSize.isUnresolved() && !limits.dataStorageMaximumSize.isUnresolved() &&
262
- limits.dataStorageMinimumSize.toGibibytes() > limits.dataStorageMaximumSize.toGibibytes()) {
263
- throw new core_1.ValidationError('Data storage minimum cannot be greater than maximum', this);
264
- }
265
- }
266
- /**
267
- * Validate request rate limits
268
- *
269
- * @param limits The usage limits containing request rate settings
270
- */
271
- validateRequestRateLimits(limits) {
272
- if (!limits)
273
- return;
274
- if (limits.requestRateLimitMinimum !== undefined && !core_1.Token.isUnresolved(limits.requestRateLimitMinimum) &&
275
- (limits.requestRateLimitMinimum < REQUEST_RATE_MIN_ECPU || limits.requestRateLimitMinimum > REQUEST_RATE_MAX_ECPU)) {
276
- throw new core_1.ValidationError('Request rate minimum must be between 1,000 and 15,000,000 ECPUs per second', this);
277
- }
278
- if (limits.requestRateLimitMaximum !== undefined && !core_1.Token.isUnresolved(limits.requestRateLimitMaximum) &&
279
- (limits.requestRateLimitMaximum < REQUEST_RATE_MIN_ECPU || limits.requestRateLimitMaximum > REQUEST_RATE_MAX_ECPU)) {
280
- throw new core_1.ValidationError('Request rate maximum must be between 1,000 and 15,000,000 ECPUs per second', this);
281
- }
282
- if (!core_1.Token.isUnresolved(limits.requestRateLimitMinimum) && !core_1.Token.isUnresolved(limits.requestRateLimitMaximum) &&
283
- limits.requestRateLimitMinimum !== undefined && limits.requestRateLimitMaximum !== undefined &&
284
- limits.requestRateLimitMinimum > limits.requestRateLimitMaximum) {
285
- throw new core_1.ValidationError('Request rate minimum cannot be greater than maximum', this);
286
- }
287
- }
288
- /**
289
- * Validate backup settings meet AWS requirements
290
- *
291
- * @param backup The backup settings to validate
292
- */
293
- validateBackupSettings(backup) {
294
- if (!core_1.Token.isUnresolved(backup?.backupRetentionLimit) && backup?.backupRetentionLimit !== undefined) {
295
- const limit = backup.backupRetentionLimit;
296
- if (limit < 1 || limit > 35) {
297
- throw new core_1.ValidationError('Backup retention limit must be between 1 and 35 days', this);
163
+ else {
164
+ throw new core_1.ValidationError('One of serverlessCacheName or serverlessCacheArn is required.', scope);
298
165
  }
299
- }
300
- if (!core_1.Token.isUnresolved(backup?.backupNameBeforeDeletion) && backup?.backupNameBeforeDeletion !== undefined) {
301
- const name = backup.backupNameBeforeDeletion;
302
- if (!/^[a-zA-Z]/.test(name)) {
303
- throw new core_1.ValidationError('Final backup name must begin with a letter', this);
166
+ class Import extends serverless_cache_base_1.ServerlessCacheBase {
167
+ engine = attrs.engine;
168
+ serverlessCacheName;
169
+ serverlessCacheArn;
170
+ backupArnsToRestore = attrs.backupArnsToRestore;
171
+ kmsKey = attrs.kmsKey;
172
+ vpc = attrs.vpc;
173
+ subnets = attrs.subnets;
174
+ securityGroups = attrs.securityGroups;
175
+ userGroup = attrs.userGroup;
176
+ connections;
177
+ constructor(serverlessCacheArn, serverlessCacheName) {
178
+ super(scope, id);
179
+ this.serverlessCacheArn = serverlessCacheArn;
180
+ this.serverlessCacheName = serverlessCacheName;
181
+ if (this.engine) {
182
+ let defaultPort;
183
+ switch (this.engine) {
184
+ case serverless_cache_base_1.CacheEngine.VALKEY_LATEST:
185
+ case serverless_cache_base_1.CacheEngine.VALKEY_7:
186
+ case serverless_cache_base_1.CacheEngine.VALKEY_8:
187
+ case serverless_cache_base_1.CacheEngine.REDIS_LATEST:
188
+ case serverless_cache_base_1.CacheEngine.REDIS_7:
189
+ // Document showing the default port
190
+ // https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/set-up.html#elasticache-install-grant-access-VPN
191
+ defaultPort = ec2.Port.tcp(6379);
192
+ break;
193
+ case serverless_cache_base_1.CacheEngine.MEMCACHED_LATEST:
194
+ // Document showing the default port
195
+ // https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/set-up.html#elasticache-install-grant-access-VPN
196
+ defaultPort = ec2.Port.tcp(11211);
197
+ break;
198
+ default:
199
+ throw new core_1.ValidationError(`Unsupported cache engine: ${this.engine}`, scope);
200
+ }
201
+ this.connections = new ec2.Connections({
202
+ securityGroups: this.securityGroups,
203
+ defaultPort: defaultPort,
204
+ });
205
+ }
206
+ else {
207
+ this.connections = new ec2.Connections({
208
+ securityGroups: this.securityGroups,
209
+ });
210
+ }
211
+ }
304
212
  }
305
- if (!/^[a-zA-Z0-9-]+$/.test(name)) {
306
- throw new core_1.ValidationError('Final backup name must contain only ASCII letters, digits, and hyphens', this);
213
+ return new Import(arn, name);
214
+ }
215
+ engine;
216
+ serverlessCacheName;
217
+ backupArnsToRestore;
218
+ kmsKey;
219
+ vpc;
220
+ subnets;
221
+ securityGroups;
222
+ userGroup;
223
+ /**
224
+ * The ARN of the serverless cache
225
+ *
226
+ * @attribute
227
+ */
228
+ serverlessCacheArn;
229
+ /**
230
+ * The endpoint address of the serverless cache
231
+ *
232
+ * @attribute
233
+ */
234
+ serverlessCacheEndpointAddress;
235
+ /**
236
+ * The endpoint port of the serverless cache
237
+ *
238
+ * @attribute
239
+ */
240
+ serverlessCacheEndpointPort;
241
+ /**
242
+ * The reader endpoint address of the serverless cache
243
+ *
244
+ * @attribute
245
+ */
246
+ serverlessCacheReaderEndpointAddress;
247
+ /**
248
+ * The reader endpoint port of the serverless cache
249
+ *
250
+ * @attribute
251
+ */
252
+ serverlessCacheReaderEndpointPort;
253
+ /**
254
+ * The current status of the serverless cache
255
+ * Can be 'CREATING', 'AVAILABLE', 'DELETING', 'CREATE-FAILED', 'MODIFYING'
256
+ *
257
+ * @attribute
258
+ */
259
+ serverlessCacheStatus;
260
+ /**
261
+ * Access to network connections
262
+ */
263
+ connections;
264
+ constructor(scope, id, props) {
265
+ super(scope, id, {});
266
+ try {
267
+ jsiiDeprecationWarnings._aws_cdk_aws_elasticache_alpha_ServerlessCacheProps(props);
307
268
  }
308
- if (name.endsWith('-')) {
309
- throw new core_1.ValidationError('Final backup name must not end with a hyphen', this);
269
+ catch (error) {
270
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
271
+ Error.captureStackTrace(error, ServerlessCache);
272
+ }
273
+ throw error;
310
274
  }
311
- if (name.includes('--')) {
312
- throw new core_1.ValidationError('Final backup name must not contain two consecutive hyphens', this);
275
+ // Enhanced CDK Analytics Telemetry
276
+ (0, metadata_resource_1.addConstructMetadata)(this, props);
277
+ this.engine = props.engine ?? serverless_cache_base_1.CacheEngine.VALKEY_LATEST;
278
+ this.serverlessCacheName = props.serverlessCacheName ?? core_1.Lazy.string({ produce: () => core_1.Names.uniqueId(this) });
279
+ this.kmsKey = props.kmsKey;
280
+ this.vpc = props.vpc;
281
+ this.userGroup = props.userGroup;
282
+ this.validateDescription(props.description);
283
+ this.validateDataStorageLimits(props.cacheUsageLimits);
284
+ this.validateRequestRateLimits(props.cacheUsageLimits);
285
+ this.validateBackupSettings(props.backup);
286
+ this.validateUserGroupCompatibility(this.engine, this.userGroup);
287
+ const subnetConfig = this.configureSubnets(props);
288
+ const subnetIds = subnetConfig.subnetIds;
289
+ this.subnets = subnetConfig.subnets;
290
+ const securityGroupConfig = this.configureSecurityGroups(props);
291
+ const securityGroupIds = securityGroupConfig.securityGroupIds;
292
+ this.securityGroups = securityGroupConfig.securityGroups;
293
+ const [engine, version] = this.engine.split('_');
294
+ const resource = new aws_elasticache_1.CfnServerlessCache(this, 'Resource', {
295
+ engine: engine,
296
+ majorEngineVersion: version,
297
+ serverlessCacheName: this.serverlessCacheName,
298
+ description: props.description,
299
+ cacheUsageLimits: this.renderCacheUsageLimits(props.cacheUsageLimits),
300
+ dailySnapshotTime: props.backup?.backupTime ? this.formatBackupTime(props.backup.backupTime) : undefined,
301
+ snapshotRetentionLimit: props.backup?.backupRetentionLimit,
302
+ finalSnapshotName: props.backup?.backupNameBeforeDeletion,
303
+ snapshotArnsToRestore: props.backup?.backupArnsToRestore,
304
+ kmsKeyId: props.kmsKey?.keyId,
305
+ subnetIds: subnetIds,
306
+ securityGroupIds: securityGroupIds,
307
+ userGroupId: props.userGroup?.userGroupName,
308
+ });
309
+ if (props.userGroup) {
310
+ const userGroupResource = props.userGroup.node.findChild('Resource');
311
+ resource.addDependency(userGroupResource);
313
312
  }
313
+ this.backupArnsToRestore = resource.snapshotArnsToRestore;
314
+ this.serverlessCacheArn = resource.attrArn;
315
+ this.serverlessCacheEndpointAddress = resource.attrEndpointAddress;
316
+ this.serverlessCacheEndpointPort = resource.attrEndpointPort;
317
+ this.serverlessCacheReaderEndpointAddress = resource.attrReaderEndpointAddress;
318
+ this.serverlessCacheReaderEndpointPort = resource.attrReaderEndpointPort;
319
+ this.serverlessCacheStatus = resource.attrStatus;
320
+ this.connections = new ec2.Connections({
321
+ securityGroups: this.securityGroups,
322
+ defaultPort: ec2.Port.tcp(core_1.Lazy.number({ produce: () => parseInt(this.serverlessCacheEndpointPort) })),
323
+ });
324
+ Object.defineProperty(this, ELASTICACHE_SERVERLESSCACHE_SYMBOL, { value: true });
314
325
  }
315
- }
316
- /**
317
- * Validate user group compatibility with cache engine
318
- *
319
- * @param engine The cache engine
320
- * @param userGroup The user group to validate
321
- */
322
- validateUserGroupCompatibility(engine, userGroup) {
323
- if (!userGroup)
324
- return;
325
- if (engine === serverless_cache_base_1.CacheEngine.MEMCACHED_LATEST) {
326
- throw new core_1.ValidationError('User groups cannot be used with Memcached engines. Only Redis and Valkey engines support user groups.', this);
326
+ /**
327
+ * Validate description meets AWS requirements
328
+ *
329
+ * @param description The description to validate
330
+ */
331
+ validateDescription(description) {
332
+ if (!description || core_1.Token.isUnresolved(description))
333
+ return;
334
+ if (description.length > 255) {
335
+ throw new core_1.ValidationError(`Description must not exceed 255 characters, currently has ${description.length}`, this);
336
+ }
337
+ if (description.includes('<') || description.includes('>')) {
338
+ throw new core_1.ValidationError('Description must not contain < or > characters', this);
339
+ }
327
340
  }
328
- if (engine === serverless_cache_base_1.CacheEngine.REDIS_LATEST && userGroup.engine !== common_1.UserEngine.REDIS) {
329
- throw new core_1.ValidationError('Redis cache can only use Redis user groups.', this);
341
+ /**
342
+ * Validate data storage size limits
343
+ *
344
+ * @param limits The usage limits containing data storage settings
345
+ */
346
+ validateDataStorageLimits(limits) {
347
+ if (!limits)
348
+ return;
349
+ if (limits.dataStorageMinimumSize && !limits.dataStorageMinimumSize.isUnresolved() &&
350
+ (limits.dataStorageMinimumSize.toGibibytes() < DATA_STORAGE_MIN_GB || limits.dataStorageMinimumSize.toGibibytes() > DATA_STORAGE_MAX_GB)) {
351
+ throw new core_1.ValidationError('Data storage minimum must be between 1 and 5000 GB.', this);
352
+ }
353
+ if (limits.dataStorageMaximumSize && !limits.dataStorageMaximumSize.isUnresolved() &&
354
+ (limits.dataStorageMaximumSize.toGibibytes() < DATA_STORAGE_MIN_GB || limits.dataStorageMaximumSize.toGibibytes() > DATA_STORAGE_MAX_GB)) {
355
+ throw new core_1.ValidationError('Data storage maximum must be between 1 and 5000 GB.', this);
356
+ }
357
+ if (limits.dataStorageMinimumSize && limits.dataStorageMaximumSize &&
358
+ !limits.dataStorageMinimumSize.isUnresolved() && !limits.dataStorageMaximumSize.isUnresolved() &&
359
+ limits.dataStorageMinimumSize.toGibibytes() > limits.dataStorageMaximumSize.toGibibytes()) {
360
+ throw new core_1.ValidationError('Data storage minimum cannot be greater than maximum', this);
361
+ }
330
362
  }
331
- }
332
- /**
333
- * Render cache usage limits for CloudFormation
334
- *
335
- * @param limits The usage limits to render
336
- * @returns CloudFormation-compatible usage limits object or undefined
337
- */
338
- renderCacheUsageLimits(limits) {
339
- if (!limits)
340
- return undefined;
341
- const cacheUsageLimits = {};
342
- if (limits.dataStorageMinimumSize !== undefined || limits.dataStorageMaximumSize !== undefined) {
343
- cacheUsageLimits.dataStorage = {
344
- unit: DataStorageUnit.GIGABYTES,
345
- ...(limits.dataStorageMinimumSize !== undefined && { minimum: limits.dataStorageMinimumSize.toGibibytes() }),
346
- ...(limits.dataStorageMaximumSize !== undefined && { maximum: limits.dataStorageMaximumSize.toGibibytes() }),
347
- };
363
+ /**
364
+ * Validate request rate limits
365
+ *
366
+ * @param limits The usage limits containing request rate settings
367
+ */
368
+ validateRequestRateLimits(limits) {
369
+ if (!limits)
370
+ return;
371
+ if (limits.requestRateLimitMinimum !== undefined && !core_1.Token.isUnresolved(limits.requestRateLimitMinimum) &&
372
+ (limits.requestRateLimitMinimum < REQUEST_RATE_MIN_ECPU || limits.requestRateLimitMinimum > REQUEST_RATE_MAX_ECPU)) {
373
+ throw new core_1.ValidationError('Request rate minimum must be between 1,000 and 15,000,000 ECPUs per second', this);
374
+ }
375
+ if (limits.requestRateLimitMaximum !== undefined && !core_1.Token.isUnresolved(limits.requestRateLimitMaximum) &&
376
+ (limits.requestRateLimitMaximum < REQUEST_RATE_MIN_ECPU || limits.requestRateLimitMaximum > REQUEST_RATE_MAX_ECPU)) {
377
+ throw new core_1.ValidationError('Request rate maximum must be between 1,000 and 15,000,000 ECPUs per second', this);
378
+ }
379
+ if (!core_1.Token.isUnresolved(limits.requestRateLimitMinimum) && !core_1.Token.isUnresolved(limits.requestRateLimitMaximum) &&
380
+ limits.requestRateLimitMinimum !== undefined && limits.requestRateLimitMaximum !== undefined &&
381
+ limits.requestRateLimitMinimum > limits.requestRateLimitMaximum) {
382
+ throw new core_1.ValidationError('Request rate minimum cannot be greater than maximum', this);
383
+ }
348
384
  }
349
- if (limits.requestRateLimitMinimum !== undefined || limits.requestRateLimitMaximum !== undefined) {
350
- cacheUsageLimits.ecpuPerSecond = {
351
- ...(limits.requestRateLimitMinimum !== undefined && { minimum: limits.requestRateLimitMinimum }),
352
- ...(limits.requestRateLimitMaximum !== undefined && { maximum: limits.requestRateLimitMaximum }),
353
- };
385
+ /**
386
+ * Validate backup settings meet AWS requirements
387
+ *
388
+ * @param backup The backup settings to validate
389
+ */
390
+ validateBackupSettings(backup) {
391
+ if (!core_1.Token.isUnresolved(backup?.backupRetentionLimit) && backup?.backupRetentionLimit !== undefined) {
392
+ const limit = backup.backupRetentionLimit;
393
+ if (limit < 1 || limit > 35) {
394
+ throw new core_1.ValidationError('Backup retention limit must be between 1 and 35 days', this);
395
+ }
396
+ }
397
+ if (!core_1.Token.isUnresolved(backup?.backupNameBeforeDeletion) && backup?.backupNameBeforeDeletion !== undefined) {
398
+ const name = backup.backupNameBeforeDeletion;
399
+ if (!/^[a-zA-Z]/.test(name)) {
400
+ throw new core_1.ValidationError('Final backup name must begin with a letter', this);
401
+ }
402
+ if (!/^[a-zA-Z0-9-]+$/.test(name)) {
403
+ throw new core_1.ValidationError('Final backup name must contain only ASCII letters, digits, and hyphens', this);
404
+ }
405
+ if (name.endsWith('-')) {
406
+ throw new core_1.ValidationError('Final backup name must not end with a hyphen', this);
407
+ }
408
+ if (name.includes('--')) {
409
+ throw new core_1.ValidationError('Final backup name must not contain two consecutive hyphens', this);
410
+ }
411
+ }
354
412
  }
355
- return Object.keys(cacheUsageLimits).length > 0 ? cacheUsageLimits : undefined;
356
- }
357
- /**
358
- * Configure subnets for the cache
359
- *
360
- * @param props The ServerlessCache properties
361
- * @returns Object containing subnet IDs and subnet objects
362
- */
363
- configureSubnets(props) {
364
- let selectedSubnets;
365
- if (props.vpcSubnets) {
366
- selectedSubnets = props.vpc.selectSubnets(props.vpcSubnets);
413
+ /**
414
+ * Validate user group compatibility with cache engine
415
+ *
416
+ * @param engine The cache engine
417
+ * @param userGroup The user group to validate
418
+ */
419
+ validateUserGroupCompatibility(engine, userGroup) {
420
+ if (!userGroup)
421
+ return;
422
+ if (engine === serverless_cache_base_1.CacheEngine.MEMCACHED_LATEST) {
423
+ throw new core_1.ValidationError('User groups cannot be used with Memcached engines. Only Redis and Valkey engines support user groups.', this);
424
+ }
425
+ if (engine === serverless_cache_base_1.CacheEngine.REDIS_LATEST && userGroup.engine !== common_1.UserEngine.REDIS) {
426
+ throw new core_1.ValidationError('Redis cache can only use Redis user groups.', this);
427
+ }
367
428
  }
368
- else {
369
- selectedSubnets = props.vpc.selectSubnets({
370
- subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
371
- });
429
+ /**
430
+ * Render cache usage limits for CloudFormation
431
+ *
432
+ * @param limits The usage limits to render
433
+ * @returns CloudFormation-compatible usage limits object or undefined
434
+ */
435
+ renderCacheUsageLimits(limits) {
436
+ if (!limits)
437
+ return undefined;
438
+ const cacheUsageLimits = {};
439
+ if (limits.dataStorageMinimumSize !== undefined || limits.dataStorageMaximumSize !== undefined) {
440
+ cacheUsageLimits.dataStorage = {
441
+ unit: DataStorageUnit.GIGABYTES,
442
+ ...(limits.dataStorageMinimumSize !== undefined && { minimum: limits.dataStorageMinimumSize.toGibibytes() }),
443
+ ...(limits.dataStorageMaximumSize !== undefined && { maximum: limits.dataStorageMaximumSize.toGibibytes() }),
444
+ };
445
+ }
446
+ if (limits.requestRateLimitMinimum !== undefined || limits.requestRateLimitMaximum !== undefined) {
447
+ cacheUsageLimits.ecpuPerSecond = {
448
+ ...(limits.requestRateLimitMinimum !== undefined && { minimum: limits.requestRateLimitMinimum }),
449
+ ...(limits.requestRateLimitMaximum !== undefined && { maximum: limits.requestRateLimitMaximum }),
450
+ };
451
+ }
452
+ return Object.keys(cacheUsageLimits).length > 0 ? cacheUsageLimits : undefined;
372
453
  }
373
- return {
374
- subnetIds: selectedSubnets.subnetIds.length > 0 ? selectedSubnets.subnetIds : undefined,
375
- subnets: selectedSubnets.subnets.length > 0 ? selectedSubnets.subnets : undefined,
376
- };
377
- }
378
- /**
379
- * Configure security groups for the cache
380
- *
381
- * @param props The ServerlessCache properties
382
- * @returns Object containing security group IDs and security group objects
383
- */
384
- configureSecurityGroups(props) {
385
- if (props.securityGroups && props.securityGroups.length > 0) {
454
+ /**
455
+ * Configure subnets for the cache
456
+ *
457
+ * @param props The ServerlessCache properties
458
+ * @returns Object containing subnet IDs and subnet objects
459
+ */
460
+ configureSubnets(props) {
461
+ let selectedSubnets;
462
+ if (props.vpcSubnets) {
463
+ selectedSubnets = props.vpc.selectSubnets(props.vpcSubnets);
464
+ }
465
+ else {
466
+ selectedSubnets = props.vpc.selectSubnets({
467
+ subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
468
+ });
469
+ }
386
470
  return {
387
- securityGroupIds: props.securityGroups.map(sg => sg.securityGroupId),
388
- securityGroups: props.securityGroups,
471
+ subnetIds: selectedSubnets.subnetIds.length > 0 ? selectedSubnets.subnetIds : undefined,
472
+ subnets: selectedSubnets.subnets.length > 0 ? selectedSubnets.subnets : undefined,
389
473
  };
390
474
  }
391
- else {
392
- const newSecurityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {
393
- description: `Security group for ${this.node.id} cache.`,
394
- vpc: props.vpc,
395
- });
396
- return {
397
- securityGroupIds: [newSecurityGroup.securityGroupId],
398
- securityGroups: [newSecurityGroup],
399
- };
475
+ /**
476
+ * Configure security groups for the cache
477
+ *
478
+ * @param props The ServerlessCache properties
479
+ * @returns Object containing security group IDs and security group objects
480
+ */
481
+ configureSecurityGroups(props) {
482
+ if (props.securityGroups && props.securityGroups.length > 0) {
483
+ return {
484
+ securityGroupIds: props.securityGroups.map(sg => sg.securityGroupId),
485
+ securityGroups: props.securityGroups,
486
+ };
487
+ }
488
+ else {
489
+ const newSecurityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {
490
+ description: `Security group for ${this.node.id} cache.`,
491
+ vpc: props.vpc,
492
+ });
493
+ return {
494
+ securityGroupIds: [newSecurityGroup.securityGroupId],
495
+ securityGroups: [newSecurityGroup],
496
+ };
497
+ }
400
498
  }
401
- }
402
- /**
403
- * Format schedule to HH:MM format for daily backups
404
- *
405
- * @param schedule The schedule to format
406
- * @returns Time string in HH:MM format
407
- */
408
- formatBackupTime(schedule) {
409
- const WILD_CARD = '*';
410
- const [minuteExpression, hourExpression, dayExpression, monthExpression, weekDayExpression, yearExpression,] = schedule.expressionString.substr(5).slice(0, -1).split(' ');
411
- if (dayExpression != WILD_CARD || monthExpression != WILD_CARD || yearExpression != WILD_CARD || weekDayExpression != '?') {
412
- throw new core_1.ValidationError('For now, only daily backup time is available (supports just hour and minute). Day, month, year, and weekDay are not allowed', this);
499
+ /**
500
+ * Format schedule to HH:MM format for daily backups
501
+ *
502
+ * @param schedule The schedule to format
503
+ * @returns Time string in HH:MM format
504
+ */
505
+ formatBackupTime(schedule) {
506
+ const WILD_CARD = '*';
507
+ const [minuteExpression, hourExpression, dayExpression, monthExpression, weekDayExpression, yearExpression,] = schedule.expressionString.substr(5).slice(0, -1).split(' ');
508
+ if (dayExpression != WILD_CARD || monthExpression != WILD_CARD || yearExpression != WILD_CARD || weekDayExpression != '?') {
509
+ throw new core_1.ValidationError('For now, only daily backup time is available (supports just hour and minute). Day, month, year, and weekDay are not allowed', this);
510
+ }
511
+ const hour = hourExpression == WILD_CARD ? '0' : hourExpression;
512
+ const minute = minuteExpression == WILD_CARD ? '0' : minuteExpression;
513
+ return `${hour.padStart(2, '0')}:${minute.padStart(2, '0')}`;
413
514
  }
414
- const hour = hourExpression == WILD_CARD ? '0' : hourExpression;
415
- const minute = minuteExpression == WILD_CARD ? '0' : minuteExpression;
416
- return `${hour.padStart(2, '0')}:${minute.padStart(2, '0')}`;
417
- }
418
- };
515
+ static {
516
+ __runInitializers(_classThis, _classExtraInitializers);
517
+ }
518
+ };
519
+ return ServerlessCache = _classThis;
520
+ })();
419
521
  exports.ServerlessCache = ServerlessCache;
420
- _a = JSII_RTTI_SYMBOL_1;
421
- ServerlessCache[_a] = { fqn: "@aws-cdk/aws-elasticache-alpha.ServerlessCache", version: "2.219.0-alpha.0" };
422
- /**
423
- * Uniquely identifies this class.
424
- */
425
- ServerlessCache.PROPERTY_INJECTION_ID = 'aws-cdk-lib.aws-elasticache.ServerlessCache';
426
- exports.ServerlessCache = ServerlessCache = ServerlessCache_1 = __decorate([
427
- prop_injectable_1.propertyInjectable
428
- ], ServerlessCache);
429
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVybGVzcy1jYWNoZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNlcnZlcmxlc3MtY2FjaGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUNBLHFDQUFzQztBQUN0QyxpRUFBK0U7QUFDL0UsbUVBQTZGO0FBRTdGLDJDQUEyQztBQUczQywyQ0FBK0Y7QUFDL0YsOEVBQThFO0FBQzlFLDBFQUEwRTtBQUUxRSxNQUFNLGtDQUFrQyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsMENBQTBDLENBQUMsQ0FBQztBQUVsRzs7R0FFRztBQUNILElBQUssZUFLSjtBQUxELFdBQUssZUFBZTtJQUNsQjs7T0FFRztJQUNILG1DQUFnQixDQUFBO0FBQ2xCLENBQUMsRUFMSSxlQUFlLEtBQWYsZUFBZSxRQUtuQjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLENBQUM7QUFDOUI7O0dBRUc7QUFDSCxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQztBQUNqQzs7R0FFRztBQUNILE1BQU0scUJBQXFCLEdBQUcsSUFBSSxDQUFDO0FBQ25DOztHQUVHO0FBQ0gsTUFBTSxxQkFBcUIsR0FBRyxRQUFRLENBQUM7QUFnTXZDOzs7O0dBSUc7QUFFSSxJQUFNLGVBQWUsdUJBQXJCLE1BQU0sZUFBZ0IsU0FBUSwyQ0FBbUI7SUFNdEQ7O09BRUc7SUFDSSxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBTTtRQUNwQyxPQUFPLENBQUMsS0FBSyxJQUFJLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsSUFBSSxrQ0FBa0MsSUFBSSxDQUFDLENBQUM7S0FDekY7SUFFRDs7Ozs7O09BTUc7SUFDSSxNQUFNLENBQUMsdUJBQXVCLENBQUMsS0FBZ0IsRUFBRSxFQUFVLEVBQUUsbUJBQTJCO1FBQzdGLE9BQU8saUJBQWUsQ0FBQyw2QkFBNkIsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEVBQUUsbUJBQW1CLEVBQUUs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QVMsSUFBSSxpQkFBaUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUMxSCxNQUFNLElBQUksc0JBQWUsQ0FBQyw2SEFBNkgsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNqSyxDQUFDO1FBRUQsTUFBTSxJQUFJLEdBQUcsY0FBYyxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUM7UUFDaEUsTUFBTSxNQUFNLEdBQUcsZ0JBQWdCLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDO1FBRXRFLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO0tBQzlEOztBQXJjVSwwQ0FBZTs7O0FBQzFCOztHQUVHO0FBQ29CLHFDQUFxQixHQUFXLDZDQUE2QyxBQUF4RCxDQUF5RDswQkFKMUYsZUFBZTtJQUQzQixvQ0FBa0I7R0FDTixlQUFlLENBc2MzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgVXNlckVuZ2luZSB9IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7IENmblNlcnZlcmxlc3NDYWNoZSwgQ2ZuVXNlckdyb3VwIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVsYXN0aWNhY2hlJztcbmltcG9ydCB7IElTZXJ2ZXJsZXNzQ2FjaGUsIFNlcnZlcmxlc3NDYWNoZUJhc2UsIENhY2hlRW5naW5lIH0gZnJvbSAnLi9zZXJ2ZXJsZXNzLWNhY2hlLWJhc2UnO1xuaW1wb3J0IHsgSVVzZXJHcm91cCB9IGZyb20gJy4vdXNlci1ncm91cCc7XG5pbXBvcnQgKiBhcyBlYzIgZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjMic7XG5pbXBvcnQgKiBhcyBldmVudHMgZnJvbSAnYXdzLWNkay1saWIvYXdzLWV2ZW50cyc7XG5pbXBvcnQgKiBhcyBrbXMgZnJvbSAnYXdzLWNkay1saWIvYXdzLWttcyc7XG5pbXBvcnQgeyBBcm5Gb3JtYXQsIFN0YWNrLCBTaXplLCBMYXp5LCBWYWxpZGF0aW9uRXJyb3IsIE5hbWVzLCBUb2tlbiB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUnO1xuaW1wb3J0IHsgYWRkQ29uc3RydWN0TWV0YWRhdGEgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9tZXRhZGF0YS1yZXNvdXJjZSc7XG5pbXBvcnQgeyBwcm9wZXJ0eUluamVjdGFibGUgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9wcm9wLWluamVjdGFibGUnO1xuXG5jb25zdCBFTEFTVElDQUNIRV9TRVJWRVJMRVNTQ0FDSEVfU1lNQk9MID0gU3ltYm9sLmZvcignQGF3cy1jZGsvYXdzLWVsYXN0aWNhY2hlLlNlcnZlcmxlc3NDYWNoZScpO1xuXG4vKipcbiAqIFVuaXQgdHlwZXMgZm9yIGRhdGEgc3RvcmFnZSB1c2FnZSBsaW1pdHNcbiAqL1xuZW51bSBEYXRhU3RvcmFnZVVuaXQge1xuICAvKipcbiAgICogR2lnYWJ5dGVzXG4gICAqL1xuICBHSUdBQllURVMgPSAnR0InLFxufVxuXG4vKipcbiAqIE1pbmltdW0gZGF0YSBzdG9yYWdlIHNpemUgaW4gR0IgZm9yIFNlcnZlcmxlc3NDYWNoZVxuICovXG5jb25zdCBEQVRBX1NUT1JBR0VfTUlOX0dCID0gMTtcbi8qKlxuICogTWF4aW11bSBkYXRhIHN0b3JhZ2Ugc2l6ZSBpbiBHQiBmb3IgU2VydmVybGVzc0NhY2hlXG4gKi9cbmNvbnN0IERBVEFfU1RPUkFHRV9NQVhfR0IgPSA1MDAwO1xuLyoqXG4gKiBNaW5pbXVtIHJlcXVlc3QgcmF0ZSBsaW1pdCBpbiBFQ1BVcyBwZXIgc2Vjb25kIGZvciBTZXJ2ZXJsZXNzQ2FjaGVcbiAqL1xuY29uc3QgUkVRVUVTVF9SQVRFX01JTl9FQ1BVID0gMTAwMDtcbi8qKlxuICogTWF4aW11bSByZXF1ZXN0IHJhdGUgbGltaXQgaW4gRUNQVXMgcGVyIHNlY29uZCBmb3IgU2VydmVybGVzc0NhY2hlXG4gKi9cbmNvbnN0IFJFUVVFU1RfUkFURV9NQVhfRUNQVSA9IDE1MDAwMDAwO1xuXG4vKipcbiAqIFVzYWdlIGxpbWl0cyBjb25maWd1cmF0aW9uIGZvciBTZXJ2ZXJsZXNzQ2FjaGVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDYWNoZVVzYWdlTGltaXRzUHJvcGVydHkge1xuICAvKipcbiAgICogTWluaW11bSBkYXRhIHN0b3JhZ2Ugc2l6ZSAoMSBHQilcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBtaW5pbXVtIGxpbWl0XG4gICAqL1xuICByZWFkb25seSBkYXRhU3RvcmFnZU1pbmltdW1TaXplPzogU2l6ZTtcbiAgLyoqXG4gICAqIE1heGltdW0gZGF0YSBzdG9yYWdlIHNpemUgKDUwMDAgR0IpXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gbWF4aW11bSBsaW1pdFxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YVN0b3JhZ2VNYXhpbXVtU2l6ZT86IFNpemU7XG4gIC8qKlxuICAgKiBNaW5pbXVtIHJlcXVlc3QgcmF0ZSBsaW1pdCAoMTAwMCBFQ1BVcyBwZXIgc2Vjb25kKVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIG1pbmltdW0gbGltaXRcbiAgICovXG4gIHJlYWRvbmx5IHJlcXVlc3RSYXRlTGltaXRNaW5pbXVtPzogbnVtYmVyO1xuICAvKipcbiAgICogTWF4aW11bSByZXF1ZXN0IHJhdGUgbGltaXQgKDE1MDAwMDAwIEVDUFVzIHBlciBzZWNvbmQpXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gbWF4aW11bSBsaW1pdFxuICAgKi9cbiAgcmVhZG9ubHkgcmVxdWVzdFJhdGVMaW1pdE1heGltdW0/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQmFja3VwIGNvbmZpZ3VyYXRpb24gZm9yIFNlcnZlcmxlc3NDYWNoZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJhY2t1cFNldHRpbmdzIHtcbiAgLyoqXG4gICAqIEF1dG9tYXRlZCBkYWlseSBiYWNrdXAgVVRDIHRpbWVcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBhdXRvbWF0ZWQgYmFja3Vwc1xuICAgKi9cbiAgcmVhZG9ubHkgYmFja3VwVGltZT86IGV2ZW50cy5TY2hlZHVsZTtcbiAgLyoqXG4gICAqIE51bWJlciBvZiBkYXlzIHRvIHJldGFpbiBiYWNrdXBzICgxLTM1KVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEJhY2t1cHMgYXJlIG5vdCByZXRhaW5lZFxuICAgKi9cbiAgcmVhZG9ubHkgYmFja3VwUmV0ZW50aW9uTGltaXQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBOYW1lIGZvciB0aGUgZmluYWwgYmFja3VwIHRha2VuIGJlZm9yZSBkZWxldGlvblxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGZpbmFsIGJhY2t1cFxuICAgKi9cbiAgcmVhZG9ubHkgYmFja3VwTmFtZUJlZm9yZURlbGV0aW9uPzogc3RyaW5nO1xuICAvKipcbiAgICogQVJOcyBvZiBiYWNrdXBzIGZyb20gd2hpY2ggdG8gcmVzdG9yZSBkYXRhIGludG8gdGhlIG5ldyBjYWNoZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIENyZWF0ZSBhIG5ldyBjYWNoZSB3aXRoIG5vIGV4aXN0aW5nIGRhdGFcbiAgICovXG4gIHJlYWRvbmx5IGJhY2t1cEFybnNUb1Jlc3RvcmU/OiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIFNlcnZlcmxlc3NDYWNoZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNlcnZlcmxlc3NDYWNoZVByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBjYWNoZSBlbmdpbmUgY29tYmluZWQgd2l0aCB0aGUgdmVyc2lvblxuICAgKiBFbnVtIG9wdGlvbnM6IFZBTEtFWV9ERUZBVUxULCBWQUxLRVlfNywgVkFMS0VZXzgsIFJFRElTX0RFRkFVTFQsIE1FTUNBQ0hFRF9ERUZBVUxUXG4gICAqIFRoZSBkZWZhdWx0IG9wdGlvbnMgYnJpbmcgdGhlIGxhdGVzdCB2ZXJzaW9ucyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IHdoZW4gbm90IHByb3ZpZGVkLCB0aGUgZGVmYXVsdCBlbmdpbmUgd291bGQgYmUgVmFsa2V5LCBsYXRlc3QgdmVyc2lvbiBhdmFpbGFibGUgKFZBTEtFWV9ERUZBVUxUKVxuICAgKi9cbiAgcmVhZG9ubHkgZW5naW5lPzogQ2FjaGVFbmdpbmU7XG4gIC8qKlxuICAgKiBOYW1lIGZvciB0aGUgc2VydmVybGVzcyBjYWNoZVxuICAgKlxuICAgKiBAZGVmYXVsdCBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBuYW1lIGJ5IFJlc291cmNlXG4gICAqL1xuICByZWFkb25seSBzZXJ2ZXJsZXNzQ2FjaGVOYW1lPzogc3RyaW5nO1xuICAvKipcbiAgICogQSBkZXNjcmlwdGlvbiBmb3IgdGhlIGNhY2hlXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gZGVzY3JpcHRpb25cbiAgICovXG4gIHJlYWRvbmx5IGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICAvKipcbiAgICogVXNhZ2UgbGltaXRzIGZvciB0aGUgY2FjaGVcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyB1c2FnZSBsaW1pdHNcbiAgICovXG4gIHJlYWRvbmx5IGNhY2hlVXNhZ2VMaW1pdHM/OiBDYWNoZVVzYWdlTGltaXRzUHJvcGVydHk7XG4gIC8qKlxuICAgKiBCYWNrdXAgY29uZmlndXJhdGlvblxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGJhY2t1cHMgY29uZmlndXJlZFxuICAgKi9cbiAgcmVhZG9ubHkgYmFja3VwPzogQmFja3VwU2V0dGluZ3M7XG4gIC8qKlxuICAgKiBLTVMga2V5IGZvciBlbmNyeXB0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gU2VydmljZSBtYW5hZ2VkIGVuY3J5cHRpb24gKEFXUyBvd25lZCBLTVMga2V5KVxuICAgKi9cbiAgcmVhZG9ubHkga21zS2V5Pzoga21zLklLZXk7XG4gIC8qKlxuICAgKiBUaGUgVlBDIHRvIHBsYWNlIHRoZSBjYWNoZSBpblxuICAgKi9cbiAgcmVhZG9ubHkgdnBjOiBlYzIuSVZwYztcbiAgLyoqXG4gICAqIFdoaWNoIHN1Ym5ldHMgdG8gcGxhY2UgdGhlIGNhY2hlIGluXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gUHJpdmF0ZSBzdWJuZXRzIHdpdGggZWdyZXNzXG4gICAqL1xuICByZWFkb25seSB2cGNTdWJuZXRzPzogZWMyLlN1Ym5ldFNlbGVjdGlvbjtcbiAgLyoqXG4gICAqIFNlY3VyaXR5IGdyb3VwcyBmb3IgdGhlIGNhY2hlXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQSBuZXcgc2VjdXJpdHkgZ3JvdXAgaXMgY3JlYXRlZFxuICAgKi9cbiAgcmVhZG9ubHkgc2VjdXJpdHlHcm91cHM/OiBlYzIuSVNlY3VyaXR5R3JvdXBbXTtcbiAgLyoqXG4gICAqIFVzZXIgZ3JvdXAgZm9yIGFjY2VzcyBjb250cm9sXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gdXNlciBncm91cFxuICAgKi9cbiAgcmVhZG9ubHkgdXNlckdyb3VwPzogSVVzZXJHcm91cDtcbn1cblxuLyoqXG4gKiBBdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIHNwZWNpZmllZCB3aGVuIGltcG9ydGluZyBhIFNlcnZlcmxlc3NDYWNoZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNlcnZlcmxlc3NDYWNoZUF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogVGhlIGNhY2hlIGVuZ2luZSB1c2VkIGJ5IHRoaXMgY2FjaGVcbiAgICpcbiAgICogQGRlZmF1bHQgLSBlbmdpbmUgdHlwZSBpcyB1bmtub3duXG4gICAqL1xuICByZWFkb25seSBlbmdpbmU/OiBDYWNoZUVuZ2luZTtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBzZXJ2ZXJsZXNzIGNhY2hlXG4gICAqXG4gICAqIE9uZSBvZiBgc2VydmVybGVzc0NhY2hlTmFtZWAgb3IgYHNlcnZlcmxlc3NDYWNoZUFybmAgaXMgcmVxdWlyZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZGVyaXZlZCBmcm9tIHNlcnZlcmxlc3NDYWNoZUFyblxuICAgKi9cbiAgcmVhZG9ubHkgc2VydmVybGVzc0NhY2hlTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBBUk4gb2YgdGhlIHNlcnZlcmxlc3MgY2FjaGVcbiAgICpcbiAgICogT25lIG9mIGBzZXJ2ZXJsZXNzQ2FjaGVOYW1lYCBvciBgc2VydmVybGVzc0NhY2hlQXJuYCBpcyByZXF1aXJlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBkZXJpdmVkIGZyb20gc2VydmVybGVzc0NhY2hlTmFtZVxuICAgKi9cbiAgcmVhZG9ubHkgc2VydmVybGVzc0NhY2hlQXJuPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIEFSTnMgb2YgYmFja3VwcyByZXN0b3JlZCBpbiB0aGUgY2FjaGVcbiAgICpcbiAgICogQGRlZmF1bHQgLSBiYWNrdXBzIGFyZSB1bmtub3duXG4gICAqL1xuICByZWFkb25seSBiYWNrdXBBcm5zVG9SZXN0b3JlPzogc3RyaW5nW107XG4gIC8qKlxuICAgKiBUaGUgS01TIGtleSB1c2VkIGZvciBlbmNyeXB0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZW5jcnlwdGlvbiBrZXkgaXMgdW5rbm93blxuICAgKi9cbiAgcmVhZG9ubHkga21zS2V5Pzoga21zLklLZXk7XG4gIC8qKlxuICAgKiBUaGUgVlBDIHRoaXMgY2FjaGUgaXMgZGVwbG95ZWQgaW5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBWUEMgaXMgdW5rbm93blxuICAgKi9cbiAgcmVhZG9ubHkgdnBjPzogZWMyLklWcGM7XG4gIC8qKlxuICAgKiBUaGUgc3VibmV0cyB0aGlzIGNhY2hlIGlzIGRlcGxveWVkIGluXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gc3VibmV0cyBhcmUgdW5rbm93blxuICAgKi9cbiAgcmVhZG9ubHkgc3VibmV0cz86IGVjMi5JU3VibmV0W107XG4gIC8qKlxuICAgKiBUaGUgc2VjdXJpdHkgZ3JvdXBzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGNhY2hlXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gc2VjdXJpdHkgZ3JvdXBzIGFyZSB1bmtub3duXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3Vwcz86IGVjMi5JU2VjdXJpdHlHcm91cFtdO1xuICAvKipcbiAgICogVGhlIHVzZXIgZ3JvdXAgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY2FjaGVcbiAgICpcbiAgICogQGRlZmF1bHQgLSB1c2VyIGdyb3VwIGlzIHVua25vd25cbiAgICovXG4gIHJlYWRvbmx5IHVzZXJHcm91cD86IElVc2VyR3JvdXA7XG59XG5cbi8qKlxuICogQSBzZXJ2ZXJsZXNzIEVsYXN0aUNhY2hlIGNhY2hlXG4gKlxuICogQHJlc291cmNlIEFXUzo6RWxhc3RpQ2FjaGU6OlNlcnZlcmxlc3NDYWNoZVxuICovXG5AcHJvcGVydHlJbmplY3RhYmxlXG5leHBvcnQgY2xhc3MgU2VydmVybGVzc0NhY2hlIGV4dGVuZHMgU2VydmVybGVzc0NhY2hlQmFzZSB7XG4gIC8qKlxuICAgKiBVbmlxdWVseSBpZGVudGlmaWVzIHRoaXMgY2xhc3MuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFBST1BFUlRZX0lOSkVDVElPTl9JRDogc3RyaW5nID0gJ2F3cy1jZGstbGliLmF3cy1lbGFzdGljYWNoZS5TZXJ2ZXJsZXNzQ2FjaGUnO1xuXG4gIC8qKlxuICAgKiBSZXR1cm4gd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgYFNlcnZlcmxlc3NDYWNoZWBcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgaXNTZXJ2ZXJsZXNzQ2FjaGUoeDogYW55KTogeCBpcyBTZXJ2ZXJsZXNzQ2FjaGUge1xuICAgIHJldHVybiB4ICE9PSBudWxsICYmIHR5cGVvZiAoeCkgPT09ICdvYmplY3QnICYmIEVMQVNUSUNBQ0hFX1NFUlZFUkxFU1NDQUNIRV9TWU1CT0wgaW4geDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgYW4gZXhpc3Rpbmcgc2VydmVybGVzcyBjYWNoZSBieSBuYW1lXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSBUaGUgcGFyZW50IGNyZWF0aW5nIGNvbnN0cnVjdCAodXN1YWxseSBgdGhpc2ApXG4gICAqIEBwYXJhbSBpZCBUaGUgY29uc3RydWN0J3MgbmFtZVxuICAgKiBAcGFyYW0gc2VydmVybGVzc0NhY2hlTmFtZSBUaGUgbmFtZSBvZiB0aGUgZXhpc3Rpbmcgc2VydmVybGVzcyBjYWNoZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tU2VydmVybGVzc0NhY2hlTmFtZShzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBzZXJ2ZXJsZXNzQ2FjaGVOYW1lOiBzdHJpbmcpOiBJU2VydmVybGVzc0NhY2hlIHtcbiAgICByZXR1cm4gU2VydmVybGVzc0NhY2hlLmZyb21TZXJ2ZXJsZXNzQ2FjaGVBdHRyaWJ1dGVzKHNjb3BlLCBpZCwgeyBzZXJ2ZXJsZXNzQ2FjaGVOYW1lIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEltcG9ydCBhbiBleGlzdGluZyBzZXJ2ZXJsZXNzIGNhY2hlIGJ5IEFSTlxuICAgKlxuICAgKiBAcGFyYW0gc2NvcGUgVGhlIHBhcmVudCBjcmVhdGluZyBjb25zdHJ1Y3QgKHVzdWFsbHkgYHRoaXNgKVxuICAgKiBAcGFyYW0gaWQgVGhlIGNvbnN0cnVjdCdzIG5hbWVcbiAgICogQHBhcmFtIHNlcnZlcmxlc3NDYWNoZUFybiBUaGUgQVJOIG9mIHRoZSBleGlzdGluZyBzZXJ2ZXJsZXNzIGNhY2hlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21TZXJ2ZXJsZXNzQ2FjaGVBcm4oc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgc2VydmVybGVzc0NhY2hlQXJuOiBzdHJpbmcpOiBJU2VydmVybGVzc0NhY2hlIHtcbiAgICByZXR1cm4gU2VydmVybGVzc0NhY2hlLmZyb21TZXJ2ZXJsZXNzQ2FjaGVBdHRyaWJ1dGVzKHNjb3BlLCBpZCwgeyBzZXJ2ZXJsZXNzQ2FjaGVBcm4gfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wb3J0IGFuIGV4aXN0aW5nIHNlcnZlcmxlc3MgY2FjaGUgdXNpbmcgYXR0cmlidXRlc1xuICAgKlxuICAgKiBAcGFyYW0gc2NvcGUgVGhlIHBhcmVudCBjcmVhdGluZyBjb25zdHJ1Y3QgKHVzdWFsbHkgYHRoaXNgKVxuICAgKiBAcGFyYW0gaWQgVGhlIGNvbnN0cnVjdCdzIG5hbWVcbiAgICogQHBhcmFtIGF0dHJzIEEgYFNlcnZlcmxlc3NDYWNoZUF0dHJpYnV0ZXNgIG9iamVjdFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tU2VydmVybGVzc0NhY2hlQXR0cmlidXRlcyhzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBhdHRyczogU2VydmVybGVzc0NhY2hlQXR0cmlidXRlcyk6IElTZXJ2ZXJsZXNzQ2FjaGUge1xuICAgIGxldCBuYW1lOiBzdHJpbmc7XG4gICAgbGV0IGFybjogc3RyaW5nO1xuICAgIGNvbnN0IHN0YWNrID0gU3RhY2sub2Yoc2NvcGUpO1xuXG4gICAgaWYgKGF0dHJzLnNlcnZlcmxlc3NDYWNoZUFybiAmJiBhdHRycy5zZXJ2ZXJsZXNzQ2FjaGVOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdPbmx5IG9uZSBvZiBzZXJ2ZXJsZXNzQ2FjaGVBcm4gb3Igc2VydmVybGVzc0NhY2hlTmFtZSBjYW4gYmUgcHJvdmlkZWQuJywgc2NvcGUpO1xuICAgIH1cblxuICAgIGlmIChhdHRycy5zZXJ2ZXJsZXNzQ2FjaGVBcm4pIHtcbiAgICAgIGFybiA9IGF0dHJzLnNlcnZlcmxlc3NDYWNoZUFybjtcbiAgICAgIGNvbnN0IGV4dHJhY3RlZFNlcnZlcmxlc3NDYWNoZU5hbWUgPSBzdGFjay5zcGxpdEFybihhdHRycy5zZXJ2ZXJsZXNzQ2FjaGVBcm4sIEFybkZvcm1hdC5TTEFTSF9SRVNPVVJDRV9OQU1FKS5yZXNvdXJjZU5hbWU7XG4gICAgICBpZiAoIWV4dHJhY3RlZFNlcnZlcmxlc3NDYWNoZU5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignVW5hYmxlIHRvIGV4dHJhY3Qgc2VydmVybGVzcyBjYWNoZSBuYW1lIGZyb20gQVJOLicsIHNjb3BlKTtcbiAgICAgIH1cbiAgICAgIG5hbWUgPSBleHRyYWN0ZWRTZXJ2ZXJsZXNzQ2FjaGVOYW1lO1xuICAgIH0gZWxzZSBpZiAoYXR0cnMuc2VydmVybGVzc0NhY2hlTmFtZSkge1xuICAgICAgbmFtZSA9IGF0dHJzLnNlcnZlcmxlc3NDYWNoZU5hbWU7XG4gICAgICBhcm4gPSBzdGFjay5mb3JtYXRBcm4oe1xuICAgICAgICBzZXJ2aWNlOiAnZWxhc3RpY2FjaGUnLFxuICAgICAgICByZXNvdXJjZTogJ3NlcnZlcmxlc3NjYWNoZScsXG4gICAgICAgIHJlc291cmNlTmFtZTogYXR0cnMuc2VydmVybGVzc0NhY2hlTmFtZSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdPbmUgb2Ygc2VydmVybGVzc0NhY2hlTmFtZSBvciBzZXJ2ZXJsZXNzQ2FjaGVBcm4gaXMgcmVxdWlyZWQuJywgc2NvcGUpO1xuICAgIH1cblxuICAgIGNsYXNzIEltcG9ydCBleHRlbmRzIFNlcnZlcmxlc3NDYWNoZUJhc2Uge1xuICAgICAgcHVibGljIHJlYWRvbmx5IGVuZ2luZSA9IGF0dHJzLmVuZ2luZTtcbiAgICAgIHB1YmxpYyByZWFkb25seSBzZXJ2ZXJsZXNzQ2FjaGVOYW1lOiBzdHJpbmc7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgc2VydmVybGVzc0NhY2hlQXJuOiBzdHJpbmc7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgYmFja3VwQXJuc1RvUmVzdG9yZSA9IGF0dHJzLmJhY2t1cEFybnNUb1Jlc3RvcmU7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkga21zS2V5ID0gYXR0cnMua21zS2V5O1xuICAgICAgcHVibGljIHJlYWRvbmx5IHZwYyA9IGF0dHJzLnZwYztcbiAgICAgIHB1YmxpYyByZWFkb25seSBzdWJuZXRzID0gYXR0cnMuc3VibmV0cztcbiAgICAgIHB1YmxpYyByZWFkb25seSBzZWN1cml0eUdyb3VwcyA9IGF0dHJzLnNlY3VyaXR5R3JvdXBzO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHVzZXJHcm91cCA9IGF0dHJzLnVzZXJHcm91cDtcblxuICAgICAgcHVibGljIHJlYWRvbmx5IGNvbm5lY3Rpb25zOiBlYzIuQ29ubmVjdGlvbnM7XG5cbiAgICAgIGNvbnN0cnVjdG9yKHNlcnZlcmxlc3NDYWNoZUFybjogc3RyaW5nLCBzZXJ2ZXJsZXNzQ2FjaGVOYW1lOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICAgICAgdGhpcy5zZXJ2ZXJsZXNzQ2FjaGVBcm4gPSBzZXJ2ZXJsZXNzQ2FjaGVBcm47XG4gICAgICAgIHRoaXMuc2VydmVybGVzc0NhY2hlTmFtZSA9IHNlcnZlcmxlc3NDYWNoZU5hbWU7XG5cbiAgICAgICAgaWYgKHRoaXMuZW5naW5lKSB7XG4gICAgICAgICAgbGV0IGRlZmF1bHRQb3J0OiBlYzIuUG9ydDtcbiAgICAgICAgICBzd2l0Y2ggKHRoaXMuZW5naW5lKSB7XG4gICAgICAgICAgICBjYXNlIENhY2hlRW5naW5lLlZBTEtFWV9MQVRFU1Q6XG4gICAgICAgICAgICBjYXNlIENhY2hlRW5naW5lLlZBTEtFWV83OlxuICAgICAgICAgICAgY2FzZSBDYWNoZUVuZ2luZS5WQUxLRVlfODpcbiAgICAgICAgICAgIGNhc2UgQ2FjaGVFbmdpbmUuUkVESVNfTEFURVNUOlxuICAgICAgICAgICAgICAvLyBEb2N1bWVudCBzaG93aW5nIHRoZSBkZWZhdWx0IHBvcnRcbiAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9kZy9zZXQtdXAuaHRtbCNlbGFzdGljYWNoZS1pbnN0YWxsLWdyYW50LWFjY2Vzcy1WUE5cbiAgICAgICAgICAgICAgZGVmYXVsdFBvcnQgPSBlYzIuUG9ydC50Y3AoNjM3OSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBDYWNoZUVuZ2luZS5NRU1DQUNIRURfTEFURVNUOlxuICAgICAgICAgICAgICAvLyBEb2N1bWVudCBzaG93aW5nIHRoZSBkZWZhdWx0IHBvcnRcbiAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9kZy9zZXQtdXAuaHRtbCNlbGFzdGljYWNoZS1pbnN0YWxsLWdyYW50LWFjY2Vzcy1WUE5cbiAgICAgICAgICAgICAgZGVmYXVsdFBvcnQgPSBlYzIuUG9ydC50Y3AoMTEyMTEpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYFVuc3VwcG9ydGVkIGNhY2hlIGVuZ2luZTogJHt0aGlzLmVuZ2luZX1gLCBzY29wZSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5jb25uZWN0aW9ucyA9IG5ldyBlYzIuQ29ubmVjdGlvbnMoe1xuICAgICAgICAgICAgc2VjdXJpdHlHcm91cHM6IHRoaXMuc2VjdXJpdHlHcm91cHMsXG4gICAgICAgICAgICBkZWZhdWx0UG9ydDogZGVmYXVsdFBvcnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5jb25uZWN0aW9ucyA9IG5ldyBlYzIuQ29ubmVjdGlvbnMoe1xuICAgICAgICAgICAgc2VjdXJpdHlHcm91cHM6IHRoaXMuc2VjdXJpdHlHcm91cHMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEltcG9ydChhcm4sIG5hbWUpO1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IGVuZ2luZT86IENhY2hlRW5naW5lO1xuICBwdWJsaWMgcmVhZG9ubHkgc2VydmVybGVzc0NhY2hlTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgYmFja3VwQXJuc1RvUmVzdG9yZT86IHN0cmluZ1tdO1xuICBwdWJsaWMgcmVhZG9ubHkga21zS2V5Pzoga21zLklLZXk7XG4gIHB1YmxpYyByZWFkb25seSB2cGM/OiBlYzIuSVZwYztcbiAgcHVibGljIHJlYWRvbmx5IHN1Ym5ldHM/OiBlYzIuSVN1Ym5ldFtdO1xuICBwdWJsaWMgcmVhZG9ubHkgc2VjdXJpdHlHcm91cHM/OiBlYzIuSVNlY3VyaXR5R3JvdXBbXTtcbiAgcHVibGljIHJlYWRvbmx5IHVzZXJHcm91cD86IElVc2VyR3JvdXA7XG5cbiAgLyoqXG4gICAqIFRoZSBBUk4gb2YgdGhlIHNlcnZlcmxlc3MgY2FjaGVcbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNlcnZlcmxlc3NDYWNoZUFybjogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGVuZHBvaW50IGFkZHJlc3Mgb2YgdGhlIHNlcnZlcmxlc3MgY2FjaGVcbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNlcnZlcmxlc3NDYWNoZUVuZHBvaW50QWRkcmVzczogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGVuZHBvaW50IHBvcnQgb2YgdGhlIHNlcnZlcmxlc3MgY2FjaGVcbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNlcnZlcmxlc3NDYWNoZUVuZHBvaW50UG9ydDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHJlYWRlciBlbmRwb2ludCBhZGRyZXNzIG9mIHRoZSBzZXJ2ZXJsZXNzIGNhY2hlXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzZXJ2ZXJsZXNzQ2FjaGVSZWFkZXJFbmRwb2ludEFkZHJlc3M6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSByZWFkZXIgZW5kcG9pbnQgcG9ydCBvZiB0aGUgc2VydmVybGVzcyBjYWNoZVxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2VydmVybGVzc0NhY2hlUmVhZGVyRW5kcG9pbnRQb3J0OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgY3VycmVudCBzdGF0dXMgb2YgdGhlIHNlcnZlcmxlc3MgY2FjaGVcbiAgICogQ2FuIGJlICdDUkVBVElORycsICdBVkFJTEFCTEUnLCAnREVMRVRJTkcnLCAnQ1JFQVRFLUZBSUxFRCcsICdNT0RJRllJTkcnXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzZXJ2ZXJsZXNzQ2FjaGVTdGF0dXM6IHN0cmluZztcblxuICAvKipcbiAgICogQWNjZXNzIHRvIG5ldHdvcmsgY29ubmVjdGlvbnNcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjb25uZWN0aW9uczogZWMyLkNvbm5lY3Rpb25zO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBTZXJ2ZXJsZXNzQ2FjaGVQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge30pO1xuXG4gICAgLy8gRW5oYW5jZWQgQ0RLIEFuYWx5dGljcyBUZWxlbWV0cnlcbiAgICBhZGRDb25zdHJ1Y3RNZXRhZGF0YSh0aGlzLCBwcm9wcyk7XG5cbiAgICB0aGlzLmVuZ2luZSA9IHByb3BzLmVuZ2luZSA/PyBDYWNoZUVuZ2luZS5WQUxLRVlfTEFURVNUO1xuICAgIHRoaXMuc2VydmVybGVzc0NhY2hlTmFtZSA9IHByb3BzLnNlcnZlcmxlc3NDYWNoZU5hbWUgPz8gTGF6eS5zdHJpbmcoeyBwcm9kdWNlOiAoKSA9PiBOYW1lcy51bmlxdWVJZCh0aGlzKSB9KTtcbiAgICB0aGlzLmttc0tleSA9IHByb3BzLmttc0tleTtcbiAgICB0aGlzLnZwYyA9IHByb3BzLnZwYztcbiAgICB0aGlzLnVzZXJHcm91cCA9IHByb3BzLnVzZXJHcm91cDtcblxuICAgIHRoaXMudmFsaWRhdGVEZXNjcmlwdGlvbihwcm9wcy5kZXNjcmlwdGlvbik7XG4gICAgdGhpcy52YWxpZGF0ZURhdGFTdG9yYWdlTGltaXRzKHByb3BzLmNhY2hlVXNhZ2VMaW1pdHMpO1xuICAgIHRoaXMudmFsaWRhdGVSZXF1ZXN0UmF0ZUxpbWl0cyhwcm9wcy5jYWNoZVVzYWdlTGltaXRzKTtcbiAgICB0aGlzLnZhbGlkYXRlQmFja3VwU2V0dGluZ3MocHJvcHMuYmFja3VwKTtcbiAgICB0aGlzLnZhbGlkYXRlVXNlckdyb3VwQ29tcGF0aWJpbGl0eSh0aGlzLmVuZ2luZSwgdGhpcy51c2VyR3JvdXApO1xuXG4gICAgY29uc3Qgc3VibmV0Q29uZmlnID0gdGhpcy5jb25maWd1cmVTdWJuZXRzKHByb3BzKTtcbiAgICBjb25zdCBzdWJuZXRJZHMgPSBzdWJuZXRDb25maWcuc3VibmV0SWRzO1xuICAgIHRoaXMuc3VibmV0cyA9IHN1Ym5ldENvbmZpZy5zdWJuZXRzO1xuXG4gICAgY29uc3Qgc2VjdXJpdHlHcm91cENvbmZpZyA9IHRoaXMuY29uZmlndXJlU2VjdXJpdHlHcm91cHMocHJvcHMpO1xuICAgIGNvbnN0IHNlY3VyaXR5R3JvdXBJZHMgPSBzZWN1cml0eUdyb3VwQ29uZmlnLnNlY3VyaXR5R3JvdXBJZHM7XG4gICAgdGhpcy5zZWN1cml0eUdyb3VwcyA9IHNlY3VyaXR5R3JvdXBDb25maWcuc2VjdXJpdHlHcm91cHM7XG5cbiAgICBjb25zdCBbZW5naW5lLCB2ZXJzaW9uXSA9IHRoaXMuZW5naW5lLnNwbGl0KCdfJyk7XG5cbiAgICBjb25zdCByZXNvdXJjZSA9IG5ldyBDZm5TZXJ2ZXJsZXNzQ2FjaGUodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgZW5naW5lOiBlbmdpbmUsXG4gICAgICBtYWpvckVuZ2luZVZlcnNpb246IHZlcnNpb24sXG4gICAgICBzZXJ2ZXJsZXNzQ2FjaGVOYW1lOiB0aGlzLnNlcnZlcmxlc3NDYWNoZU5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogcHJvcHMuZGVzY3JpcHRpb24sXG4gICAgICBjYWNoZVVzYWdlTGltaXRzOiB0aGlzLnJlbmRlckNhY2hlVXNhZ2VMaW1pdHMocHJvcHMuY2FjaGVVc2FnZUxpbWl0cyksXG4gICAgICBkYWlseVNuYXBzaG90VGltZTogcHJvcHMuYmFja3VwPy5iYWNrdXBUaW1lID8gdGhpcy5mb3JtYXRCYWNrdXBUaW1lKHByb3BzLmJhY2t1cC5iYWNrdXBUaW1lKSA6IHVuZGVmaW5lZCxcbiAgICAgIHNuYXBzaG90UmV0ZW50aW9uTGltaXQ6IHByb3BzLmJhY2t1cD8uYmFja3VwUmV0ZW50aW9uTGltaXQsXG4gICAgICBmaW5hbFNuYXBzaG90TmFtZTogcHJvcHMuYmFja3VwPy5iYWNrdXBOYW1lQmVmb3JlRGVsZXRpb24sXG4gICAgICBzbmFwc2hvdEFybnNUb1Jlc3RvcmU6IHByb3BzLmJhY2t1cD8uYmFja3VwQXJuc1RvUmVzdG9yZSxcbiAgICAgIGttc0tleUlkOiBwcm9wcy5rbXNLZXk/LmtleUlkLFxuICAgICAgc3VibmV0SWRzOiBzdWJuZXRJZHMsXG4gICAgICBzZWN1cml0eUdyb3VwSWRzOiBzZWN1cml0eUdyb3VwSWRzLFxuICAgICAgdXNlckdyb3VwSWQ6IHByb3BzLnVzZXJHcm91cD8udXNlckdyb3VwTmFtZSxcbiAgICB9KTtcblxuICAgIGlmIChwcm9wcy51c2VyR3JvdXApIHtcbiAgICAgIGNvbnN0IHVzZXJHcm91cFJlc291cmNlID0gcHJvcHMudXNlckdyb3VwLm5vZGUuZmluZENoaWxkKCdSZXNvdXJjZScpIGFzIENmblVzZXJHcm91cDtcbiAgICAgIHJlc291cmNlLmFkZERlcGVuZGVuY3kodXNlckdyb3VwUmVzb3VyY2UpO1xuICAgIH1cblxuICAgIHRoaXMuYmFja3VwQXJuc1RvUmVzdG9yZSA9IHJlc291cmNlLnNuYXBzaG90QXJuc1RvUmVzdG9yZTtcbiAgICB0aGlzLnNlcnZlcmxlc3NDYWNoZUFybiA9IHJlc291cmNlLmF0dHJBcm47XG4gICAgdGhpcy5zZXJ2ZXJsZXNzQ2FjaGVFbmRwb2ludEFkZHJlc3MgPSByZXNvdXJjZS5hdHRyRW5kcG9pbnRBZGRyZXNzO1xuICAgIHRoaXMuc2VydmVybGVzc0NhY2hlRW5kcG9pbnRQb3J0ID0gcmVzb3VyY2UuYXR0ckVuZHBvaW50UG9ydDtcbiAgICB0aGlzLnNlcnZlcmxlc3NDYWNoZVJlYWRlckVuZHBvaW50QWRkcmVzcyA9IHJlc291cmNlLmF0dHJSZWFkZXJFbmRwb2ludEFkZHJlc3M7XG4gICAgdGhpcy5zZXJ2ZXJsZXNzQ2FjaGVSZWFkZXJFbmRwb2ludFBvcnQgPSByZXNvdXJjZS5hdHRyUmVhZGVyRW5kcG9pbnRQb3J0O1xuICAgIHRoaXMuc2VydmVybGVzc0NhY2hlU3RhdHVzID0gcmVzb3VyY2UuYXR0clN0YXR1cztcblxuICAgIHRoaXMuY29ubmVjdGlvbnMgPSBuZXcgZWMyLkNvbm5lY3Rpb25zKHtcbiAgICAgIHNlY3VyaXR5R3JvdXBzOiB0aGlzLnNlY3VyaXR5R3JvdXBzLFxuICAgICAgZGVmYXVsdFBvcnQ6IGVjMi5Qb3J0LnRjcChMYXp5Lm51bWJlcih7IHByb2R1Y2U6ICgpID0+IHBhcnNlSW50KHRoaXMuc2VydmVybGVzc0NhY2hlRW5kcG9pbnRQb3J0KSB9KSksXG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgRUxBU1RJQ0FDSEVfU0VSVkVSTEVTU0NBQ0hFX1NZTUJPTCwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBkZXNjcmlwdGlvbiBtZWV0cyBBV1MgcmVxdWlyZW1lbnRzXG4gICAqXG4gICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBUaGUgZGVzY3JpcHRpb24gdG8gdmFsaWRhdGVcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVEZXNjcmlwdGlvbihkZXNjcmlwdGlvbj86IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghZGVzY3JpcHRpb24gfHwgVG9rZW4uaXNVbnJlc29sdmVkKGRlc2NyaXB0aW9uKSkgcmV0dXJuO1xuXG4gICAgaWYgKGRlc2NyaXB0aW9uLmxlbmd0aCA+IDI1NSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgRGVzY3JpcHRpb24gbXVzdCBub3QgZXhjZWVkIDI1NSBjaGFyYWN0ZXJzLCBjdXJyZW50bHkgaGFzICR7ZGVzY3JpcHRpb24ubGVuZ3RofWAsIHRoaXMpO1xuICAgIH1cblxuICAgIGlmIChkZXNjcmlwdGlvbi5pbmNsdWRlcygnPCcpIHx8IGRlc2NyaXB0aW9uLmluY2x1ZGVzKCc+JykpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ0Rlc2NyaXB0aW9uIG11c3Qgbm90IGNvbnRhaW4gPCBvciA+IGNoYXJhY3RlcnMnLCB0aGlzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgZGF0YSBzdG9yYWdlIHNpemUgbGltaXRzXG4gICAqXG4gICAqIEBwYXJhbSBsaW1pdHMgVGhlIHVzYWdlIGxpbWl0cyBjb250YWluaW5nIGRhdGEgc3RvcmFnZSBzZXR0aW5nc1xuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZURhdGFTdG9yYWdlTGltaXRzKGxpbWl0cz86IENhY2hlVXNhZ2VMaW1pdHNQcm9wZXJ0eSk6IHZvaWQge1xuICAgIGlmICghbGltaXRzKSByZXR1cm47XG5cbiAgICBpZiAobGltaXRzLmRhdGFTdG9yYWdlTWluaW11bVNpemUgJiYgIWxpbWl0cy5kYXRhU3RvcmFnZU1pbmltdW1TaXplLmlzVW5yZXNvbHZlZCgpICYmXG4gICAgICAobGltaXRzLmRhdGFTdG9yYWdlTWluaW11bVNpemUudG9HaWJpYnl0ZXMoKSA8IERBVEFfU1RPUkFHRV9NSU5fR0IgfHwgbGltaXRzLmRhdGFTdG9yYWdlTWluaW11bVNpemUudG9HaWJpYnl0ZXMoKSA+IERBVEFfU1RPUkFHRV9NQVhfR0IpKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdEYXRhIHN0b3JhZ2UgbWluaW11bSBtdXN0IGJlIGJldHdlZW4gMSBhbmQgNTAwMCBHQi4nLCB0aGlzKTtcbiAgICB9XG4gICAgaWYgKGxpbWl0cy5kYXRhU3RvcmFnZU1heGltdW1TaXplICYmICFsaW1pdHMuZGF0YVN0b3JhZ2VNYXhpbXVtU2l6ZS5pc1VucmVzb2x2ZWQoKSAmJlxuICAgICAgKGxpbWl0cy5kYXRhU3RvcmFnZU1heGltdW1TaXplLnRvR2liaWJ5dGVzKCkgPCBEQVRBX1NUT1JBR0VfTUlOX0dCIHx8IGxpbWl0cy5kYXRhU3RvcmFnZU1heGltdW1TaXplLnRvR2liaWJ5dGVzKCkgPiBEQVRBX1NUT1JBR0VfTUFYX0dCKSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignRGF0YSBzdG9yYWdlIG1heGltdW0gbXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDUwMDAgR0IuJywgdGhpcyk7XG4gICAgfVxuXG4gICAgaWYgKGxpbWl0cy5kYXRhU3RvcmFnZU1pbmltdW1TaXplICYmIGxpbWl0cy5kYXRhU3RvcmFnZU1heGltdW1TaXplICYmXG4gICAgICAhbGltaXRzLmRhdGFTdG9yYWdlTWluaW11bVNpemUuaXNVbnJlc29sdmVkKCkgJiYgIWxpbWl0cy5kYXRhU3RvcmFnZU1heGltdW1TaXplLmlzVW5yZXNvbHZlZCgpICYmXG4gICAgICBsaW1pdHMuZGF0YVN0b3JhZ2VNaW5pbXVtU2l6ZS50b0dpYmlieXRlcygpID4gbGltaXRzLmRhdGFTdG9yYWdlTWF4aW11bVNpemUudG9HaWJpYnl0ZXMoKSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignRGF0YSBzdG9yYWdlIG1pbmltdW0gY2Fubm90IGJlIGdyZWF0ZXIgdGhhbiBtYXhpbXVtJywgdGhpcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHJlcXVlc3QgcmF0ZSBsaW1pdHNcbiAgICpcbiAgICogQHBhcmFtIGxpbWl0cyBUaGUgdXNhZ2UgbGltaXRzIGNvbnRhaW5pbmcgcmVxdWVzdCByYXRlIHNldHRpbmdzXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlUmVxdWVzdFJhdGVMaW1pdHMobGltaXRzPzogQ2FjaGVVc2FnZUxpbWl0c1Byb3BlcnR5KTogdm9pZCB7XG4gICAgaWYgKCFsaW1pdHMpIHJldHVybjtcblxuICAgIGlmIChsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1pbmltdW0gIT09IHVuZGVmaW5lZCAmJiAhVG9rZW4uaXNVbnJlc29sdmVkKGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWluaW11bSkgJiZcbiAgICAgIChsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1pbmltdW0gPCBSRVFVRVNUX1JBVEVfTUlOX0VDUFUgfHwgbGltaXRzLnJlcXVlc3RSYXRlTGltaXRNaW5pbXVtID4gUkVRVUVTVF9SQVRFX01BWF9FQ1BVKSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignUmVxdWVzdCByYXRlIG1pbmltdW0gbXVzdCBiZSBiZXR3ZWVuIDEsMDAwIGFuZCAxNSwwMDAsMDAwIEVDUFVzIHBlciBzZWNvbmQnLCB0aGlzKTtcbiAgICB9XG4gICAgaWYgKGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWF4aW11bSAhPT0gdW5kZWZpbmVkICYmICFUb2tlbi5pc1VucmVzb2x2ZWQobGltaXRzLnJlcXVlc3RSYXRlTGltaXRNYXhpbXVtKSAmJlxuICAgICAgKGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWF4aW11bSA8IFJFUVVFU1RfUkFURV9NSU5fRUNQVSB8fCBsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1heGltdW0gPiBSRVFVRVNUX1JBVEVfTUFYX0VDUFUpKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdSZXF1ZXN0IHJhdGUgbWF4aW11bSBtdXN0IGJlIGJldHdlZW4gMSwwMDAgYW5kIDE1LDAwMCwwMDAgRUNQVXMgcGVyIHNlY29uZCcsIHRoaXMpO1xuICAgIH1cblxuICAgIGlmICghVG9rZW4uaXNVbnJlc29sdmVkKGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWluaW11bSkgJiYgIVRva2VuLmlzVW5yZXNvbHZlZChsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1heGltdW0pICYmXG4gICAgICBsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1pbmltdW0gIT09IHVuZGVmaW5lZCAmJiBsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1heGltdW0gIT09IHVuZGVmaW5lZCAmJlxuICAgICAgbGltaXRzLnJlcXVlc3RSYXRlTGltaXRNaW5pbXVtID4gbGltaXRzLnJlcXVlc3RSYXRlTGltaXRNYXhpbXVtKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdSZXF1ZXN0IHJhdGUgbWluaW11bSBjYW5ub3QgYmUgZ3JlYXRlciB0aGFuIG1heGltdW0nLCB0aGlzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYmFja3VwIHNldHRpbmdzIG1lZXQgQVdTIHJlcXVpcmVtZW50c1xuICAgKlxuICAgKiBAcGFyYW0gYmFja3VwIFRoZSBiYWNrdXAgc2V0dGluZ3MgdG8gdmFsaWRhdGVcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVCYWNrdXBTZXR0aW5ncyhiYWNrdXA/OiBCYWNrdXBTZXR0aW5ncyk6IHZvaWQge1xuICAgIGlmICghVG9rZW4uaXNVbnJlc29sdmVkKGJhY2t1cD8uYmFja3VwUmV0ZW50aW9uTGltaXQpICYmIGJhY2t1cD8uYmFja3VwUmV0ZW50aW9uTGltaXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgbGltaXQgPSBiYWNrdXAuYmFja3VwUmV0ZW50aW9uTGltaXQ7XG4gICAgICBpZiAobGltaXQgPCAxIHx8IGxpbWl0ID4gMzUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignQmFja3VwIHJldGVudGlvbiBsaW1pdCBtdXN0IGJlIGJldHdlZW4gMSBhbmQgMzUgZGF5cycsIHRoaXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghVG9rZW4uaXNVbnJlc29sdmVkKGJhY2t1cD8uYmFja3VwTmFtZUJlZm9yZURlbGV0aW9uKSAmJiBiYWNrdXA/LmJhY2t1cE5hbWVCZWZvcmVEZWxldGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBuYW1lID0gYmFja3VwLmJhY2t1cE5hbWVCZWZvcmVEZWxldGlvbjtcblxuICAgICAgaWYgKCEvXlthLXpBLVpdLy50ZXN0KG5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ0ZpbmFsIGJhY2t1cCBuYW1lIG11c3QgYmVnaW4gd2l0aCBhIGxldHRlcicsIHRoaXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIS9eW2EtekEtWjAtOS1dKyQvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignRmluYWwgYmFja3VwIG5hbWUgbXVzdCBjb250YWluIG9ubHkgQVNDSUkgbGV0dGVycywgZGlnaXRzLCBhbmQgaHlwaGVucycsIHRoaXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAobmFtZS5lbmRzV2l0aCgnLScpKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ0ZpbmFsIGJhY2t1cCBuYW1lIG11c3Qgbm90IGVuZCB3aXRoIGEgaHlwaGVuJywgdGhpcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChuYW1lLmluY2x1ZGVzKCctLScpKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ0ZpbmFsIGJhY2t1cCBuYW1lIG11c3Qgbm90IGNvbnRhaW4gdHdvIGNvbnNlY3V0aXZlIGh5cGhlbnMnLCB0aGlzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdXNlciBncm91cCBjb21wYXRpYmlsaXR5IHdpdGggY2FjaGUgZW5naW5lXG4gICAqXG4gICAqIEBwYXJhbSBlbmdpbmUgVGhlIGNhY2hlIGVuZ2luZVxuICAgKiBAcGFyYW0gdXNlckdyb3VwIFRoZSB1c2VyIGdyb3VwIHRvIHZhbGlkYXRlXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlVXNlckdyb3VwQ29tcGF0aWJpbGl0eShlbmdpbmU6IENhY2hlRW5naW5lLCB1c2VyR3JvdXA/OiBJVXNlckdyb3VwKTogdm9pZCB7XG4gICAgaWYgKCF1c2VyR3JvdXApIHJldHVybjtcblxuICAgIGlmIChlbmdpbmUgPT09IENhY2hlRW5naW5lLk1FTUNBQ0hFRF9MQVRFU1QpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1VzZXIgZ3JvdXBzIGNhbm5vdCBiZSB1c2VkIHdpdGggTWVtY2FjaGVkIGVuZ2luZXMuIE9ubHkgUmVkaXMgYW5kIFZhbGtleSBlbmdpbmVzIHN1cHBvcnQgdXNlciBncm91cHMuJywgdGhpcyk7XG4gICAgfVxuXG4gICAgaWYgKGVuZ2luZSA9PT0gQ2FjaGVFbmdpbmUuUkVESVNfTEFURVNUICYmIHVzZXJHcm91cC5lbmdpbmUgIT09IFVzZXJFbmdpbmUuUkVESVMpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1JlZGlzIGNhY2hlIGNhbiBvbmx5IHVzZSBSZWRpcyB1c2VyIGdyb3Vwcy4nLCB0aGlzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVyIGNhY2hlIHVzYWdlIGxpbWl0cyBmb3IgQ2xvdWRGb3JtYXRpb25cbiAgICpcbiAgICogQHBhcmFtIGxpbWl0cyBUaGUgdXNhZ2UgbGltaXRzIHRvIHJlbmRlclxuICAgKiBAcmV0dXJucyBDbG91ZEZvcm1hdGlvbi1jb21wYXRpYmxlIHVzYWdlIGxpbWl0cyBvYmplY3Qgb3IgdW5kZWZpbmVkXG4gICAqL1xuICBwcml2YXRlIHJlbmRlckNhY2hlVXNhZ2VMaW1pdHMobGltaXRzPzogQ2FjaGVVc2FnZUxpbWl0c1Byb3BlcnR5KTogYW55IHtcbiAgICBpZiAoIWxpbWl0cykgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGNhY2hlVXNhZ2VMaW1pdHM6IGFueSA9IHt9O1xuXG4gICAgaWYgKGxpbWl0cy5kYXRhU3RvcmFnZU1pbmltdW1TaXplICE9PSB1bmRlZmluZWQgfHwgbGltaXRzLmRhdGFTdG9yYWdlTWF4aW11bVNpemUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2FjaGVVc2FnZUxpbWl0cy5kYXRhU3RvcmFnZSA9IHtcbiAgICAgICAgdW5pdDogRGF0YVN0b3JhZ2VVbml0LkdJR0FCWVRFUyxcbiAgICAgICAgLi4uKGxpbWl0cy5kYXRhU3RvcmFnZU1pbmltdW1TaXplICE9PSB1bmRlZmluZWQgJiYgeyBtaW5pbXVtOiBsaW1pdHMuZGF0YVN0b3JhZ2VNaW5pbXVtU2l6ZS50b0dpYmlieXRlcygpIH0pLFxuICAgICAgICAuLi4obGltaXRzLmRhdGFTdG9yYWdlTWF4aW11bVNpemUgIT09IHVuZGVmaW5lZCAmJiB7IG1heGltdW06IGxpbWl0cy5kYXRhU3RvcmFnZU1heGltdW1TaXplLnRvR2liaWJ5dGVzKCkgfSksXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmIChsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1pbmltdW0gIT09IHVuZGVmaW5lZCB8fCBsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1heGltdW0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2FjaGVVc2FnZUxpbWl0cy5lY3B1UGVyU2Vjb25kID0ge1xuICAgICAgICAuLi4obGltaXRzLnJlcXVlc3RSYXRlTGltaXRNaW5pbXVtICE9PSB1bmRlZmluZWQgJiYgeyBtaW5pbXVtOiBsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1pbmltdW0gfSksXG4gICAgICAgIC4uLihsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1heGltdW0gIT09IHVuZGVmaW5lZCAmJiB7IG1heGltdW06IGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWF4aW11bSB9KSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGNhY2hlVXNhZ2VMaW1pdHMpLmxlbmd0aCA+IDAgPyBjYWNoZVVzYWdlTGltaXRzIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyZSBzdWJuZXRzIGZvciB0aGUgY2FjaGVcbiAgICpcbiAgICogQHBhcmFtIHByb3BzIFRoZSBTZXJ2ZXJsZXNzQ2FjaGUgcHJvcGVydGllc1xuICAgKiBAcmV0dXJucyBPYmplY3QgY29udGFpbmluZyBzdWJuZXQgSURzIGFuZCBzdWJuZXQgb2JqZWN0c1xuICAgKi9cbiAgcHJpdmF0ZSBjb25maWd1cmVTdWJuZXRzKHByb3BzOiBTZXJ2ZXJsZXNzQ2FjaGVQcm9wcyk6IHsgc3VibmV0SWRzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDsgc3VibmV0czogZWMyLklTdWJuZXRbXSB8IHVuZGVmaW5lZCB9IHtcbiAgICBsZXQgc2VsZWN0ZWRTdWJuZXRzO1xuICAgIGlmIChwcm9wcy52cGNTdWJuZXRzKSB7XG4gICAgICBzZWxlY3RlZFN1Ym5ldHMgPSBwcm9wcy52cGMuc2VsZWN0U3VibmV0cyhwcm9wcy52cGNTdWJuZXRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZWN0ZWRTdWJuZXRzID0gcHJvcHMudnBjLnNlbGVjdFN1Ym5ldHMoe1xuICAgICAgICBzdWJuZXRUeXBlOiBlYzIuU3VibmV0VHlwZS5QUklWQVRFX1dJVEhfRUdSRVNTLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHN1Ym5ldElkczogc2VsZWN0ZWRTdWJuZXRzLnN1Ym5ldElkcy5sZW5ndGggPiAwID8gc2VsZWN0ZWRTdWJuZXRzLnN1Ym5ldElkcyA6IHVuZGVmaW5lZCxcbiAgICAgIHN1Ym5ldHM6IHNlbGVjdGVkU3VibmV0cy5zdWJuZXRzLmxlbmd0aCA+IDAgPyBzZWxlY3RlZFN1Ym5ldHMuc3VibmV0cyA6IHVuZGVmaW5lZCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyZSBzZWN1cml0eSBncm91cHMgZm9yIHRoZSBjYWNoZVxuICAgKlxuICAgKiBAcGFyYW0gcHJvcHMgVGhlIFNlcnZlcmxlc3NDYWNoZSBwcm9wZXJ0aWVzXG4gICAqIEByZXR1cm5zIE9iamVjdCBjb250YWluaW5nIHNlY3VyaXR5IGdyb3VwIElEcyBhbmQgc2VjdXJpdHkgZ3JvdXAgb2JqZWN0c1xuICAgKi9cbiAgcHJpdmF0ZSBjb25maWd1cmVTZWN1cml0eUdyb3Vwcyhwcm9wczogU2VydmVybGVzc0NhY2hlUHJvcHMpOiB7IHNlY3VyaXR5R3JvdXBJZHM6IHN0cmluZ1tdOyBzZWN1cml0eUdyb3VwczogZWMyLklTZWN1cml0eUdyb3VwW10gfSB7XG4gICAgaWYgKHByb3BzLnNlY3VyaXR5R3JvdXBzICYmIHByb3BzLnNlY3VyaXR5R3JvdXBzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNlY3VyaXR5R3JvdXBJZHM6IHByb3BzLnNlY3VyaXR5R3JvdXBzLm1hcChzZyA9PiBzZy5zZWN1cml0eUdyb3VwSWQpLFxuICAgICAgICBzZWN1cml0eUdyb3VwczogcHJvcHMuc2VjdXJpdHlHcm91cHMsXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBuZXdTZWN1cml0eUdyb3VwID0gbmV3IGVjMi5TZWN1cml0eUdyb3VwKHRoaXMsICdTZWN1cml0eUdyb3VwJywge1xuICAgICAgICBkZXNjcmlwdGlvbjogYFNlY3VyaXR5IGdyb3VwIGZvciAke3RoaXMubm9kZS5pZH0gY2FjaGUuYCxcbiAgICAgICAgdnBjOiBwcm9wcy52cGMsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNlY3VyaXR5R3JvdXBJZHM6IFtuZXdTZWN1cml0eUdyb3VwLnNlY3VyaXR5R3JvdXBJZF0sXG4gICAgICAgIHNlY3VyaXR5R3JvdXBzOiBbbmV3U2VjdXJpdHlHcm91cF0sXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGb3JtYXQgc2NoZWR1bGUgdG8gSEg6TU0gZm9ybWF0IGZvciBkYWlseSBiYWNrdXBzXG4gICAqXG4gICAqIEBwYXJhbSBzY2hlZHVsZSBUaGUgc2NoZWR1bGUgdG8gZm9ybWF0XG4gICAqIEByZXR1cm5zIFRpbWUgc3RyaW5nIGluIEhIOk1NIGZvcm1hdFxuICAgKi9cbiAgcHJpdmF0ZSBmb3JtYXRCYWNrdXBUaW1lKHNjaGVkdWxlOiBldmVudHMuU2NoZWR1bGUpOiBzdHJpbmcge1xuICAgIGNvbnN0IFdJTERfQ0FSRCA9ICcqJztcbiAgICBjb25zdCBbXG4gICAgICBtaW51dGVFeHByZXNzaW9uLCBob3VyRXhwcmVzc2lvbixcbiAgICAgIGRheUV4cHJlc3Npb24sIG1vbnRoRXhwcmVzc2lvbixcbiAgICAgIHdlZWtEYXlFeHByZXNzaW9uLCB5ZWFyRXhwcmVzc2lvbixcbiAgICBdID0gc2NoZWR1bGUuZXhwcmVzc2lvblN0cmluZy5zdWJzdHIoNSkuc2xpY2UoMCwgLTEpLnNwbGl0KCcgJyk7XG5cbiAgICBpZiAoZGF5RXhwcmVzc2lvbiAhPSBXSUxEX0NBUkQgfHwgbW9udGhFeHByZXNzaW9uICE9IFdJTERfQ0FSRCB8fCB5ZWFyRXhwcmVzc2lvbiAhPSBXSUxEX0NBUkQgfHwgd2Vla0RheUV4cHJlc3Npb24gIT0gJz8nKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdGb3Igbm93LCBvbmx5IGRhaWx5IGJhY2t1cCB0aW1lIGlzIGF2YWlsYWJsZSAoc3VwcG9ydHMganVzdCBob3VyIGFuZCBtaW51dGUpLiBEYXksIG1vbnRoLCB5ZWFyLCBhbmQgd2Vla0RheSBhcmUgbm90IGFsbG93ZWQnLCB0aGlzKTtcbiAgICB9XG5cbiAgICBjb25zdCBob3VyID0gaG91ckV4cHJlc3Npb24gPT0gV0lMRF9DQVJEID8gJzAnIDogaG91ckV4cHJlc3Npb247XG4gICAgY29uc3QgbWludXRlID0gbWludXRlRXhwcmVzc2lvbiA9PSBXSUxEX0NBUkQgPyAnMCcgOiBtaW51dGVFeHByZXNzaW9uO1xuXG4gICAgcmV0dXJuIGAke2hvdXIucGFkU3RhcnQoMiwgJzAnKX06JHttaW51dGUucGFkU3RhcnQoMiwgJzAnKX1gO1xuICB9XG59XG4iXX0=
522
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVybGVzcy1jYWNoZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNlcnZlcmxlc3MtY2FjaGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQ0EscUNBQXNDO0FBQ3RDLGlFQUErRTtBQUMvRSxtRUFBNkY7QUFFN0YsMkNBQTJDO0FBRzNDLDJDQUErRjtBQUMvRiw4RUFBOEU7QUFDOUUsMEVBQTBFO0FBRTFFLE1BQU0sa0NBQWtDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO0FBRWxHOztHQUVHO0FBQ0gsSUFBSyxlQUtKO0FBTEQsV0FBSyxlQUFlO0lBQ2xCOztPQUVHO0lBQ0gsbUNBQWdCLENBQUE7QUFDbEIsQ0FBQyxFQUxJLGVBQWUsS0FBZixlQUFlLFFBS25CO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLG1CQUFtQixHQUFHLENBQUMsQ0FBQztBQUM5Qjs7R0FFRztBQUNILE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDO0FBQ2pDOztHQUVHO0FBQ0gsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLENBQUM7QUFDbkM7O0dBRUc7QUFDSCxNQUFNLHFCQUFxQixHQUFHLFFBQVEsQ0FBQztBQWdNdkM7Ozs7R0FJRztJQUVVLGVBQWU7NEJBRDNCLG9DQUFrQjs7OztzQkFDa0IsMkNBQW1COytCQUEzQixTQUFRLFdBQW1COzs7O1lBQXhELDZLQXVjQzs7Ozs7UUF0Y0M7O1dBRUc7UUFDSSxNQUFNLENBQVUscUJBQXFCLEdBQVcsNkNBQTZDLENBQUM7UUFFckc7O1dBRUc7UUFDSSxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBTTtZQUNwQyxPQUFPLENBQUMsS0FBSyxJQUFJLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsSUFBSSxrQ0FBa0MsSUFBSSxDQUFDLENBQUM7U0FDekY7UUFFRDs7Ozs7O1dBTUc7UUFDSSxNQUFNLENBQUMsdUJBQXVCLENBQUMsS0FBZ0IsRUFBRSxFQUFVLEVBQUUsbUJBQTJCO1lBQzdGLE9BQU8sZUFBZSxDQUFDLDZCQUE2QixDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLENBQUM7U0FDMUY7UUFFRDs7Ozs7O1dBTUc7UUFDSSxNQUFNLENBQUMsc0JBQXNCLENBQUMsS0FBZ0IsRUFBRSxFQUFVLEVBQUUsa0JBQTBCO1lBQzNGLE9BQU8sZUFBZSxDQUFDLDZCQUE2QixDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLENBQUM7U0FDekY7UUFFRDs7Ozs7O1dBTUc7UUFDSSxNQUFNLENBQUMsNkJBQTZCLENBQUMsS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBZ0M7Ozs7Ozs7Ozs7WUFDeEcsSUFBSSxJQUFZLENBQUM7WUFDakIsSUFBSSxHQUFXLENBQUM7WUFDaEIsTUFBTSxLQUFLLEdBQUcsWUFBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUU5QixJQUFJLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSxLQUFLLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztnQkFDMUQsTUFBTSxJQUFJLHNCQUFlLENBQUMsd0VBQXdFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDN0csQ0FBQztZQUVELElBQUksS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7Z0JBQzdCLEdBQUcsR0FBRyxLQUFLLENBQUMsa0JBQWtCLENBQUM7Z0JBQy9CLE1BQU0sNEJBQTRCLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEVBQUUsZ0JBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLFlBQVksQ0FBQztnQkFDMUgsSUFBSSxDQUFDLDRCQUE0QixFQUFFLENBQUM7b0JBQ2xDLE1BQU0sSUFBSSxzQkFBZSxDQUFDLG1EQUFtRCxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUN4RixDQUFDO2dCQUNELElBQUksR0FBRyw0QkFBNEIsQ0FBQztZQUN0QyxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixFQUFFLENBQUM7Z0JBQ3JDLElBQUksR0FBRyxLQUFLLENBQUMsbUJBQW1CLENBQUM7Z0JBQ2pDLEdBQUcsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO29CQUNwQixPQUFPLEVBQUUsYUFBYTtvQkFDdEIsUUFBUSxFQUFFLGlCQUFpQjtvQkFDM0IsWUFBWSxFQUFFLEtBQUssQ0FBQyxtQkFBbUI7aUJBQ3hDLENBQUMsQ0FBQztZQUNMLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLElBQUksc0JBQWUsQ0FBQywrREFBK0QsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNwRyxDQUFDO1lBRUQsTUFBTSxNQUFPLFNBQVEsMkNBQW1CO2dCQUN0QixNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztnQkFDdEIsbUJBQW1CLENBQVM7Z0JBQzVCLGtCQUFrQixDQUFTO2dCQUMzQixtQkFBbUIsR0FBRyxLQUFLLENBQUMsbUJBQW1CLENBQUM7Z0JBQ2hELE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO2dCQUN0QixHQUFHLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQztnQkFDaEIsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7Z0JBQ3hCLGNBQWMsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDO2dCQUN0QyxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQztnQkFFNUIsV0FBVyxDQUFrQjtnQkFFN0MsWUFBWSxrQkFBMEIsRUFBRSxtQkFBMkI7b0JBQ2pFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7b0JBQ2pCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztvQkFDN0MsSUFBSSxDQUFDLG1CQUFtQixHQUFHLG1CQUFtQixDQUFDO29CQUUvQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQzt3QkFDaEIsSUFBSSxXQUFxQixDQUFDO3dCQUMxQixRQUFRLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQzs0QkFDcEIsS0FBSyxtQ0FBVyxDQUFDLGFBQWEsQ0FBQzs0QkFDL0IsS0FBSyxtQ0FBVyxDQUFDLFFBQVEsQ0FBQzs0QkFDMUIsS0FBSyxtQ0FBVyxDQUFDLFFBQVEsQ0FBQzs0QkFDMUIsS0FBSyxtQ0FBVyxDQUFDLFlBQVksQ0FBQzs0QkFDOUIsS0FBSyxtQ0FBVyxDQUFDLE9BQU87Z0NBQ3RCLG9DQUFvQztnQ0FDcEMsMkdBQTJHO2dDQUMzRyxXQUFXLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7Z0NBQ2pDLE1BQU07NEJBQ1IsS0FBSyxtQ0FBVyxDQUFDLGdCQUFnQjtnQ0FDL0Isb0NBQW9DO2dDQUNwQywyR0FBMkc7Z0NBQzNHLFdBQVcsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQ0FDbEMsTUFBTTs0QkFDUjtnQ0FDRSxNQUFNLElBQUksc0JBQWUsQ0FBQyw2QkFBNkIsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO3dCQUNqRixDQUFDO3dCQUVELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxHQUFHLENBQUMsV0FBVyxDQUFDOzRCQUNyQyxjQUFjLEVBQUUsSUFBSSxDQUFDLGNBQWM7NEJBQ25DLFdBQVcsRUFBRSxXQUFXO3lCQUN6QixDQUFDLENBQUM7b0JBQ0wsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxHQUFHLENBQUMsV0FBVyxDQUFDOzRCQUNyQyxjQUFjLEVBQUUsSUFBSSxDQUFDLGNBQWM7eUJBQ3BDLENBQUMsQ0FBQztvQkFDTCxDQUFDO2dCQUNILENBQUM7YUFDRjtZQUVELE9BQU8sSUFBSSxNQUFNLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1NBQzlCO1FBRWUsTUFBTSxDQUFlO1FBQ3JCLG1CQUFtQixDQUFTO1FBQzVCLG1CQUFtQixDQUFZO1FBQy9CLE1BQU0sQ0FBWTtRQUNsQixHQUFHLENBQVk7UUFDZixPQUFPLENBQWlCO1FBQ3hCLGNBQWMsQ0FBd0I7UUFDdEMsU0FBUyxDQUFjO1FBRXZDOzs7O1dBSUc7UUFDYSxrQkFBa0IsQ0FBUztRQUMzQzs7OztXQUlHO1FBQ2EsOEJBQThCLENBQVM7UUFDdkQ7Ozs7V0FJRztRQUNhLDJCQUEyQixDQUFTO1FBQ3BEOzs7O1dBSUc7UUFDYSxvQ0FBb0MsQ0FBUztRQUM3RDs7OztXQUlHO1FBQ2EsaUNBQWlDLENBQVM7UUFDMUQ7Ozs7O1dBS0c7UUFDYSxxQkFBcUIsQ0FBUztRQUU5Qzs7V0FFRztRQUNhLFdBQVcsQ0FBa0I7UUFFN0MsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUEyQjtZQUNuRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQzs7Ozs7O21EQWhMWixlQUFlOzs7O1lBa0x4QixtQ0FBbUM7WUFDbkMsSUFBQSx3Q0FBb0IsRUFBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFbEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxJQUFJLG1DQUFXLENBQUMsYUFBYSxDQUFDO1lBQ3hELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxLQUFLLENBQUMsbUJBQW1CLElBQUksV0FBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxZQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUM3RyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDM0IsSUFBSSxDQUFDLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDO1lBQ3JCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQztZQUVqQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzVDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUN2RCxJQUFJLENBQUMseUJBQXlCLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDdkQsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMxQyxJQUFJLENBQUMsOEJBQThCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFakUsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2xELE1BQU0sU0FBUyxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUM7WUFDekMsSUFBSSxDQUFDLE9BQU8sR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDO1lBRXBDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sZ0JBQWdCLEdBQUcsbUJBQW1CLENBQUMsZ0JBQWdCLENBQUM7WUFDOUQsSUFBSSxDQUFDLGNBQWMsR0FBRyxtQkFBbUIsQ0FBQyxjQUFjLENBQUM7WUFFekQsTUFBTSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUVqRCxNQUFNLFFBQVEsR0FBRyxJQUFJLG9DQUFrQixDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7Z0JBQ3hELE1BQU0sRUFBRSxNQUFNO2dCQUNkLGtCQUFrQixFQUFFLE9BQU87Z0JBQzNCLG1CQUFtQixFQUFFLElBQUksQ0FBQyxtQkFBbUI7Z0JBQzdDLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztnQkFDOUIsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQztnQkFDckUsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO2dCQUN4RyxzQkFBc0IsRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLG9CQUFvQjtnQkFDMUQsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSx3QkFBd0I7Z0JBQ3pELHFCQUFxQixFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsbUJBQW1CO2dCQUN4RCxRQUFRLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxLQUFLO2dCQUM3QixTQUFTLEVBQUUsU0FBUztnQkFDcEIsZ0JBQWdCLEVBQUUsZ0JBQWdCO2dCQUNsQyxXQUFXLEVBQUUsS0FBSyxDQUFDLFNBQVMsRUFBRSxhQUFhO2FBQzVDLENBQUMsQ0FBQztZQUVILElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNwQixNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQWlCLENBQUM7Z0JBQ3JGLFFBQVEsQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUM1QyxDQUFDO1lBRUQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQztZQUMxRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQztZQUMzQyxJQUFJLENBQUMsOEJBQThCLEdBQUcsUUFBUSxDQUFDLG1CQUFtQixDQUFDO1lBQ25FLElBQUksQ0FBQywyQkFBMkIsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUM7WUFDN0QsSUFBSSxDQUFDLG9DQUFvQyxHQUFHLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQztZQUMvRSxJQUFJLENBQUMsaUNBQWlDLEdBQUcsUUFBUSxDQUFDLHNCQUFzQixDQUFDO1lBQ3pFLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDO1lBRWpELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxHQUFHLENBQUMsV0FBVyxDQUFDO2dCQUNyQyxjQUFjLEVBQUUsSUFBSSxDQUFDLGNBQWM7Z0JBQ25DLFdBQVcsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDdEcsQ0FBQyxDQUFDO1lBRUgsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsa0NBQWtDLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUNsRjtRQUVEOzs7O1dBSUc7UUFDSyxtQkFBbUIsQ0FBQyxXQUFvQjtZQUM5QyxJQUFJLENBQUMsV0FBVyxJQUFJLFlBQUssQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDO2dCQUFFLE9BQU87WUFFNUQsSUFBSSxXQUFXLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO2dCQUM3QixNQUFNLElBQUksc0JBQWUsQ0FBQyw2REFBNkQsV0FBVyxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3JILENBQUM7WUFFRCxJQUFJLFdBQVcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMzRCxNQUFNLElBQUksc0JBQWUsQ0FBQyxnREFBZ0QsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNwRixDQUFDO1NBQ0Y7UUFFRDs7OztXQUlHO1FBQ0sseUJBQXlCLENBQUMsTUFBaUM7WUFDakUsSUFBSSxDQUFDLE1BQU07Z0JBQUUsT0FBTztZQUVwQixJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxZQUFZLEVBQUU7Z0JBQ2hGLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLFdBQVcsRUFBRSxHQUFHLG1CQUFtQixJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxXQUFXLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxFQUFFLENBQUM7Z0JBQzNJLE1BQU0sSUFBSSxzQkFBZSxDQUFDLHFEQUFxRCxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3pGLENBQUM7WUFDRCxJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxZQUFZLEVBQUU7Z0JBQ2hGLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLFdBQVcsRUFBRSxHQUFHLG1CQUFtQixJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxXQUFXLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxFQUFFLENBQUM7Z0JBQzNJLE1BQU0sSUFBSSxzQkFBZSxDQUFDLHFEQUFxRCxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3pGLENBQUM7WUFFRCxJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsSUFBSSxNQUFNLENBQUMsc0JBQXNCO2dCQUNoRSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxZQUFZLEVBQUU7Z0JBQzlGLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxXQUFXLEVBQUUsR0FBRyxNQUFNLENBQUMsc0JBQXNCLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQztnQkFDNUYsTUFBTSxJQUFJLHNCQUFlLENBQUMscURBQXFELEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDekYsQ0FBQztTQUNGO1FBRUQ7Ozs7V0FJRztRQUNLLHlCQUF5QixDQUFDLE1BQWlDO1lBQ2pFLElBQUksQ0FBQyxNQUFNO2dCQUFFLE9BQU87WUFFcEIsSUFBSSxNQUFNLENBQUMsdUJBQXVCLEtBQUssU0FBUyxJQUFJLENBQUMsWUFBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsdUJBQXVCLENBQUM7Z0JBQ3JHLENBQUMsTUFBTSxDQUFDLHVCQUF1QixHQUFHLHFCQUFxQixJQUFJLE1BQU0sQ0FBQyx1QkFBdUIsR0FBRyxxQkFBcUIsQ0FBQyxFQUFFLENBQUM7Z0JBQ3JILE1BQU0sSUFBSSxzQkFBZSxDQUFDLDRFQUE0RSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2hILENBQUM7WUFDRCxJQUFJLE1BQU0sQ0FBQyx1QkFBdUIsS0FBSyxTQUFTLElBQUksQ0FBQyxZQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQztnQkFDckcsQ0FBQyxNQUFNLENBQUMsdUJBQXVCLEdBQUcscUJBQXFCLElBQUksTUFBTSxDQUFDLHVCQUF1QixHQUFHLHFCQUFxQixDQUFDLEVBQUUsQ0FBQztnQkFDckgsTUFBTSxJQUFJLHNCQUFlLENBQUMsNEVBQTRFLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDaEgsQ0FBQztZQUVELElBQUksQ0FBQyxZQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsWUFBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsdUJBQXVCLENBQUM7Z0JBQzVHLE1BQU0sQ0FBQyx1QkFBdUIsS0FBSyxTQUFTLElBQUksTUFBTSxDQUFDLHVCQUF1QixLQUFLLFNBQVM7Z0JBQzVGLE1BQU0sQ0FBQyx1QkFBdUIsR0FBRyxNQUFNLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztnQkFDbEUsTUFBTSxJQUFJLHNCQUFlLENBQUMscURBQXFELEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDekYsQ0FBQztTQUNGO1FBRUQ7Ozs7V0FJRztRQUNLLHNCQUFzQixDQUFDLE1BQXVCO1lBQ3BELElBQUksQ0FBQyxZQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxvQkFBb0IsQ0FBQyxJQUFJLE1BQU0sRUFBRSxvQkFBb0IsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDcEcsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixDQUFDO2dCQUMxQyxJQUFJLEtBQUssR0FBRyxDQUFDLElBQUksS0FBSyxHQUFHLEVBQUUsRUFBRSxDQUFDO29CQUM1QixNQUFNLElBQUksc0JBQWUsQ0FBQyxzREFBc0QsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDMUYsQ0FBQztZQUNILENBQUM7WUFFRCxJQUFJLENBQUMsWUFBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsd0JBQXdCLENBQUMsSUFBSSxNQUFNLEVBQUUsd0JBQXdCLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzVHLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQztnQkFFN0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztvQkFDNUIsTUFBTSxJQUFJLHNCQUFlLENBQUMsNENBQTRDLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ2hGLENBQUM7Z0JBRUQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNsQyxNQUFNLElBQUksc0JBQWUsQ0FBQyx3RUFBd0UsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDNUcsQ0FBQztnQkFFRCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDdkIsTUFBTSxJQUFJLHNCQUFlLENBQUMsOENBQThDLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ2xGLENBQUM7Z0JBRUQsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQ3hCLE1BQU0sSUFBSSxzQkFBZSxDQUFDLDREQUE0RCxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNoRyxDQUFDO1lBQ0gsQ0FBQztTQUNGO1FBRUQ7Ozs7O1dBS0c7UUFDSyw4QkFBOEIsQ0FBQyxNQUFtQixFQUFFLFNBQXNCO1lBQ2hGLElBQUksQ0FBQyxTQUFTO2dCQUFFLE9BQU87WUFFdkIsSUFBSSxNQUFNLEtBQUssbUNBQVcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2dCQUM1QyxNQUFNLElBQUksc0JBQWUsQ0FBQyx1R0FBdUcsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUMzSSxDQUFDO1lBRUQsSUFBSSxNQUFNLEtBQUssbUNBQVcsQ0FBQyxZQUFZLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxtQkFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNqRixNQUFNLElBQUksc0JBQWUsQ0FBQyw2Q0FBNkMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNqRixDQUFDO1NBQ0Y7UUFFRDs7Ozs7V0FLRztRQUNLLHNCQUFzQixDQUFDLE1BQWlDO1lBQzlELElBQUksQ0FBQyxNQUFNO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBRTlCLE1BQU0sZ0JBQWdCLEdBQVEsRUFBRSxDQUFDO1lBRWpDLElBQUksTUFBTSxDQUFDLHNCQUFzQixLQUFLLFNBQVMsSUFBSSxNQUFNLENBQUMsc0JBQXNCLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQy9GLGdCQUFnQixDQUFDLFdBQVcsR0FBRztvQkFDN0IsSUFBSSxFQUFFLGVBQWUsQ0FBQyxTQUFTO29CQUMvQixHQUFHLENBQUMsTUFBTSxDQUFDLHNCQUFzQixLQUFLLFNBQVMsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsc0JBQXNCLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQztvQkFDNUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsS0FBSyxTQUFTLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLHNCQUFzQixDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7aUJBQzdHLENBQUM7WUFDSixDQUFDO1lBRUQsSUFBSSxNQUFNLENBQUMsdUJBQXVCLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyx1QkFBdUIsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDakcsZ0JBQWdCLENBQUMsYUFBYSxHQUFHO29CQUMvQixHQUFHLENBQUMsTUFBTSxDQUFDLHVCQUF1QixLQUFLLFNBQVMsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztvQkFDaEcsR0FBRyxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsS0FBSyxTQUFTLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLHVCQUF1QixFQUFFLENBQUM7aUJBQ2pHLENBQUM7WUFDSixDQUFDO1lBRUQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztTQUNoRjtRQUVEOzs7OztXQUtHO1FBQ0ssZ0JBQWdCLENBQUMsS0FBMkI7WUFDbEQsSUFBSSxlQUFlLENBQUM7WUFDcEIsSUFBSSxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ3JCLGVBQWUsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDOUQsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGVBQWUsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQztvQkFDeEMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsbUJBQW1CO2lCQUMvQyxDQUFDLENBQUM7WUFDTCxDQUFDO1lBRUQsT0FBTztnQkFDTCxTQUFTLEVBQUUsZUFBZSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTO2dCQUN2RixPQUFPLEVBQUUsZUFBZSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTO2FBQ2xGLENBQUM7U0FDSDtRQUVEOzs7OztXQUtHO1FBQ0ssdUJBQXVCLENBQUMsS0FBMkI7WUFDekQsSUFBSSxLQUFLLENBQUMsY0FBYyxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUM1RCxPQUFPO29CQUNMLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQztvQkFDcEUsY0FBYyxFQUFFLEtBQUssQ0FBQyxjQUFjO2lCQUNyQyxDQUFDO1lBQ0osQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxHQUFHLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxlQUFlLEVBQUU7b0JBQ3BFLFdBQVcsRUFBRSxzQkFBc0IsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLFNBQVM7b0JBQ3hELEdBQUcsRUFBRSxLQUFLLENBQUMsR0FBRztpQkFDZixDQUFDLENBQUM7Z0JBQ0gsT0FBTztvQkFDTCxnQkFBZ0IsRUFBRSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQztvQkFDcEQsY0FBYyxFQUFFLENBQUMsZ0JBQWdCLENBQUM7aUJBQ25DLENBQUM7WUFDSixDQUFDO1NBQ0Y7UUFFRDs7Ozs7V0FLRztRQUNLLGdCQUFnQixDQUFDLFFBQXlCO1lBQ2hELE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQztZQUN0QixNQUFNLENBQ0osZ0JBQWdCLEVBQUUsY0FBYyxFQUNoQyxhQUFhLEVBQUUsZUFBZSxFQUM5QixpQkFBaUIsRUFBRSxjQUFjLEVBQ2xDLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWhFLElBQUksYUFBYSxJQUFJLFNBQVMsSUFBSSxlQUFlLElBQUksU0FBUyxJQUFJLGNBQWMsSUFBSSxTQUFTLElBQUksaUJBQWlCLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQzFILE1BQU0sSUFBSSxzQkFBZSxDQUFDLDZIQUE2SCxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2pLLENBQUM7WUFFRCxNQUFNLElBQUksR0FBRyxjQUFjLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQztZQUNoRSxNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUM7WUFFdEUsT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7U0FDOUQ7O1lBdGNVLHVEQUFlOzs7OztBQUFmLDBDQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBVc2VyRW5naW5lIH0gZnJvbSAnLi9jb21tb24nO1xuaW1wb3J0IHsgQ2ZuU2VydmVybGVzc0NhY2hlLCBDZm5Vc2VyR3JvdXAgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWxhc3RpY2FjaGUnO1xuaW1wb3J0IHsgSVNlcnZlcmxlc3NDYWNoZSwgU2VydmVybGVzc0NhY2hlQmFzZSwgQ2FjaGVFbmdpbmUgfSBmcm9tICcuL3NlcnZlcmxlc3MtY2FjaGUtYmFzZSc7XG5pbXBvcnQgeyBJVXNlckdyb3VwIH0gZnJvbSAnLi91c2VyLWdyb3VwJztcbmltcG9ydCAqIGFzIGVjMiBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWMyJztcbmltcG9ydCAqIGFzIGV2ZW50cyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZXZlbnRzJztcbmltcG9ydCAqIGFzIGttcyBmcm9tICdhd3MtY2RrLWxpYi9hd3Mta21zJztcbmltcG9ydCB7IEFybkZvcm1hdCwgU3RhY2ssIFNpemUsIExhenksIFZhbGlkYXRpb25FcnJvciwgTmFtZXMsIFRva2VuIH0gZnJvbSAnYXdzLWNkay1saWIvY29yZSc7XG5pbXBvcnQgeyBhZGRDb25zdHJ1Y3RNZXRhZGF0YSB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL21ldGFkYXRhLXJlc291cmNlJztcbmltcG9ydCB7IHByb3BlcnR5SW5qZWN0YWJsZSB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL3Byb3AtaW5qZWN0YWJsZSc7XG5cbmNvbnN0IEVMQVNUSUNBQ0hFX1NFUlZFUkxFU1NDQUNIRV9TWU1CT0wgPSBTeW1ib2wuZm9yKCdAYXdzLWNkay9hd3MtZWxhc3RpY2FjaGUuU2VydmVybGVzc0NhY2hlJyk7XG5cbi8qKlxuICogVW5pdCB0eXBlcyBmb3IgZGF0YSBzdG9yYWdlIHVzYWdlIGxpbWl0c1xuICovXG5lbnVtIERhdGFTdG9yYWdlVW5pdCB7XG4gIC8qKlxuICAgKiBHaWdhYnl0ZXNcbiAgICovXG4gIEdJR0FCWVRFUyA9ICdHQicsXG59XG5cbi8qKlxuICogTWluaW11bSBkYXRhIHN0b3JhZ2Ugc2l6ZSBpbiBHQiBmb3IgU2VydmVybGVzc0NhY2hlXG4gKi9cbmNvbnN0IERBVEFfU1RPUkFHRV9NSU5fR0IgPSAxO1xuLyoqXG4gKiBNYXhpbXVtIGRhdGEgc3RvcmFnZSBzaXplIGluIEdCIGZvciBTZXJ2ZXJsZXNzQ2FjaGVcbiAqL1xuY29uc3QgREFUQV9TVE9SQUdFX01BWF9HQiA9IDUwMDA7XG4vKipcbiAqIE1pbmltdW0gcmVxdWVzdCByYXRlIGxpbWl0IGluIEVDUFVzIHBlciBzZWNvbmQgZm9yIFNlcnZlcmxlc3NDYWNoZVxuICovXG5jb25zdCBSRVFVRVNUX1JBVEVfTUlOX0VDUFUgPSAxMDAwO1xuLyoqXG4gKiBNYXhpbXVtIHJlcXVlc3QgcmF0ZSBsaW1pdCBpbiBFQ1BVcyBwZXIgc2Vjb25kIGZvciBTZXJ2ZXJsZXNzQ2FjaGVcbiAqL1xuY29uc3QgUkVRVUVTVF9SQVRFX01BWF9FQ1BVID0gMTUwMDAwMDA7XG5cbi8qKlxuICogVXNhZ2UgbGltaXRzIGNvbmZpZ3VyYXRpb24gZm9yIFNlcnZlcmxlc3NDYWNoZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIENhY2hlVXNhZ2VMaW1pdHNQcm9wZXJ0eSB7XG4gIC8qKlxuICAgKiBNaW5pbXVtIGRhdGEgc3RvcmFnZSBzaXplICgxIEdCKVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIG1pbmltdW0gbGltaXRcbiAgICovXG4gIHJlYWRvbmx5IGRhdGFTdG9yYWdlTWluaW11bVNpemU/OiBTaXplO1xuICAvKipcbiAgICogTWF4aW11bSBkYXRhIHN0b3JhZ2Ugc2l6ZSAoNTAwMCBHQilcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBtYXhpbXVtIGxpbWl0XG4gICAqL1xuICByZWFkb25seSBkYXRhU3RvcmFnZU1heGltdW1TaXplPzogU2l6ZTtcbiAgLyoqXG4gICAqIE1pbmltdW0gcmVxdWVzdCByYXRlIGxpbWl0ICgxMDAwIEVDUFVzIHBlciBzZWNvbmQpXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gbWluaW11bSBsaW1pdFxuICAgKi9cbiAgcmVhZG9ubHkgcmVxdWVzdFJhdGVMaW1pdE1pbmltdW0/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBNYXhpbXVtIHJlcXVlc3QgcmF0ZSBsaW1pdCAoMTUwMDAwMDAgRUNQVXMgcGVyIHNlY29uZClcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBtYXhpbXVtIGxpbWl0XG4gICAqL1xuICByZWFkb25seSByZXF1ZXN0UmF0ZUxpbWl0TWF4aW11bT86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBCYWNrdXAgY29uZmlndXJhdGlvbiBmb3IgU2VydmVybGVzc0NhY2hlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFja3VwU2V0dGluZ3Mge1xuICAvKipcbiAgICogQXV0b21hdGVkIGRhaWx5IGJhY2t1cCBVVEMgdGltZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGF1dG9tYXRlZCBiYWNrdXBzXG4gICAqL1xuICByZWFkb25seSBiYWNrdXBUaW1lPzogZXZlbnRzLlNjaGVkdWxlO1xuICAvKipcbiAgICogTnVtYmVyIG9mIGRheXMgdG8gcmV0YWluIGJhY2t1cHMgKDEtMzUpXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQmFja3VwcyBhcmUgbm90IHJldGFpbmVkXG4gICAqL1xuICByZWFkb25seSBiYWNrdXBSZXRlbnRpb25MaW1pdD86IG51bWJlcjtcbiAgLyoqXG4gICAqIE5hbWUgZm9yIHRoZSBmaW5hbCBiYWNrdXAgdGFrZW4gYmVmb3JlIGRlbGV0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gZmluYWwgYmFja3VwXG4gICAqL1xuICByZWFkb25seSBiYWNrdXBOYW1lQmVmb3JlRGVsZXRpb24/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBUk5zIG9mIGJhY2t1cHMgZnJvbSB3aGljaCB0byByZXN0b3JlIGRhdGEgaW50byB0aGUgbmV3IGNhY2hlXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQ3JlYXRlIGEgbmV3IGNhY2hlIHdpdGggbm8gZXhpc3RpbmcgZGF0YVxuICAgKi9cbiAgcmVhZG9ubHkgYmFja3VwQXJuc1RvUmVzdG9yZT86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgU2VydmVybGVzc0NhY2hlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VydmVybGVzc0NhY2hlUHJvcHMge1xuICAvKipcbiAgICogVGhlIGNhY2hlIGVuZ2luZSBjb21iaW5lZCB3aXRoIHRoZSB2ZXJzaW9uXG4gICAqIEVudW0gb3B0aW9uczogVkFMS0VZX0RFRkFVTFQsIFZBTEtFWV83LCBWQUxLRVlfOCwgUkVESVNfREVGQVVMVCwgTUVNQ0FDSEVEX0RFRkFVTFRcbiAgICogVGhlIGRlZmF1bHQgb3B0aW9ucyBicmluZyB0aGUgbGF0ZXN0IHZlcnNpb25zIGF2YWlsYWJsZS5cbiAgICpcbiAgICogQGRlZmF1bHQgd2hlbiBub3QgcHJvdmlkZWQsIHRoZSBkZWZhdWx0IGVuZ2luZSB3b3VsZCBiZSBWYWxrZXksIGxhdGVzdCB2ZXJzaW9uIGF2YWlsYWJsZSAoVkFMS0VZX0RFRkFVTFQpXG4gICAqL1xuICByZWFkb25seSBlbmdpbmU/OiBDYWNoZUVuZ2luZTtcbiAgLyoqXG4gICAqIE5hbWUgZm9yIHRoZSBzZXJ2ZXJsZXNzIGNhY2hlXG4gICAqXG4gICAqIEBkZWZhdWx0IGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIG5hbWUgYnkgUmVzb3VyY2VcbiAgICovXG4gIHJlYWRvbmx5IHNlcnZlcmxlc3NDYWNoZU5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBIGRlc2NyaXB0aW9uIGZvciB0aGUgY2FjaGVcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBkZXNjcmlwdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBVc2FnZSBsaW1pdHMgZm9yIHRoZSBjYWNoZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIHVzYWdlIGxpbWl0c1xuICAgKi9cbiAgcmVhZG9ubHkgY2FjaGVVc2FnZUxpbWl0cz86IENhY2hlVXNhZ2VMaW1pdHNQcm9wZXJ0eTtcbiAgLyoqXG4gICAqIEJhY2t1cCBjb25maWd1cmF0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gYmFja3VwcyBjb25maWd1cmVkXG4gICAqL1xuICByZWFkb25seSBiYWNrdXA/OiBCYWNrdXBTZXR0aW5ncztcbiAgLyoqXG4gICAqIEtNUyBrZXkgZm9yIGVuY3J5cHRpb25cbiAgICpcbiAgICogQGRlZmF1bHQgLSBTZXJ2aWNlIG1hbmFnZWQgZW5jcnlwdGlvbiAoQVdTIG93bmVkIEtNUyBrZXkpXG4gICAqL1xuICByZWFkb25seSBrbXNLZXk/OiBrbXMuSUtleTtcbiAgLyoqXG4gICAqIFRoZSBWUEMgdG8gcGxhY2UgdGhlIGNhY2hlIGluXG4gICAqL1xuICByZWFkb25seSB2cGM6IGVjMi5JVnBjO1xuICAvKipcbiAgICogV2hpY2ggc3VibmV0cyB0byBwbGFjZSB0aGUgY2FjaGUgaW5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBQcml2YXRlIHN1Ym5ldHMgd2l0aCBlZ3Jlc3NcbiAgICovXG4gIHJlYWRvbmx5IHZwY1N1Ym5ldHM/OiBlYzIuU3VibmV0U2VsZWN0aW9uO1xuICAvKipcbiAgICogU2VjdXJpdHkgZ3JvdXBzIGZvciB0aGUgY2FjaGVcbiAgICpcbiAgICogQGRlZmF1bHQgLSBBIG5ldyBzZWN1cml0eSBncm91cCBpcyBjcmVhdGVkXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3Vwcz86IGVjMi5JU2VjdXJpdHlHcm91cFtdO1xuICAvKipcbiAgICogVXNlciBncm91cCBmb3IgYWNjZXNzIGNvbnRyb2xcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyB1c2VyIGdyb3VwXG4gICAqL1xuICByZWFkb25seSB1c2VyR3JvdXA/OiBJVXNlckdyb3VwO1xufVxuXG4vKipcbiAqIEF0dHJpYnV0ZXMgdGhhdCBjYW4gYmUgc3BlY2lmaWVkIHdoZW4gaW1wb3J0aW5nIGEgU2VydmVybGVzc0NhY2hlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VydmVybGVzc0NhY2hlQXR0cmlidXRlcyB7XG4gIC8qKlxuICAgKiBUaGUgY2FjaGUgZW5naW5lIHVzZWQgYnkgdGhpcyBjYWNoZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGVuZ2luZSB0eXBlIGlzIHVua25vd25cbiAgICovXG4gIHJlYWRvbmx5IGVuZ2luZT86IENhY2hlRW5naW5lO1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIHNlcnZlcmxlc3MgY2FjaGVcbiAgICpcbiAgICogT25lIG9mIGBzZXJ2ZXJsZXNzQ2FjaGVOYW1lYCBvciBgc2VydmVybGVzc0NhY2hlQXJuYCBpcyByZXF1aXJlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBkZXJpdmVkIGZyb20gc2VydmVybGVzc0NhY2hlQXJuXG4gICAqL1xuICByZWFkb25seSBzZXJ2ZXJsZXNzQ2FjaGVOYW1lPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIEFSTiBvZiB0aGUgc2VydmVybGVzcyBjYWNoZVxuICAgKlxuICAgKiBPbmUgb2YgYHNlcnZlcmxlc3NDYWNoZU5hbWVgIG9yIGBzZXJ2ZXJsZXNzQ2FjaGVBcm5gIGlzIHJlcXVpcmVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGRlcml2ZWQgZnJvbSBzZXJ2ZXJsZXNzQ2FjaGVOYW1lXG4gICAqL1xuICByZWFkb25seSBzZXJ2ZXJsZXNzQ2FjaGVBcm4/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgQVJOcyBvZiBiYWNrdXBzIHJlc3RvcmVkIGluIHRoZSBjYWNoZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGJhY2t1cHMgYXJlIHVua25vd25cbiAgICovXG4gIHJlYWRvbmx5IGJhY2t1cEFybnNUb1Jlc3RvcmU/OiBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIFRoZSBLTVMga2V5IHVzZWQgZm9yIGVuY3J5cHRpb25cbiAgICpcbiAgICogQGRlZmF1bHQgLSBlbmNyeXB0aW9uIGtleSBpcyB1bmtub3duXG4gICAqL1xuICByZWFkb25seSBrbXNLZXk/OiBrbXMuSUtleTtcbiAgLyoqXG4gICAqIFRoZSBWUEMgdGhpcyBjYWNoZSBpcyBkZXBsb3llZCBpblxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFZQQyBpcyB1bmtub3duXG4gICAqL1xuICByZWFkb25seSB2cGM/OiBlYzIuSVZwYztcbiAgLyoqXG4gICAqIFRoZSBzdWJuZXRzIHRoaXMgY2FjaGUgaXMgZGVwbG95ZWQgaW5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzdWJuZXRzIGFyZSB1bmtub3duXG4gICAqL1xuICByZWFkb25seSBzdWJuZXRzPzogZWMyLklTdWJuZXRbXTtcbiAgLyoqXG4gICAqIFRoZSBzZWN1cml0eSBncm91cHMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY2FjaGVcbiAgICpcbiAgICogQGRlZmF1bHQgLSBzZWN1cml0eSBncm91cHMgYXJlIHVua25vd25cbiAgICovXG4gIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXBzPzogZWMyLklTZWN1cml0eUdyb3VwW107XG4gIC8qKlxuICAgKiBUaGUgdXNlciBncm91cCBhc3NvY2lhdGVkIHdpdGggdGhpcyBjYWNoZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHVzZXIgZ3JvdXAgaXMgdW5rbm93blxuICAgKi9cbiAgcmVhZG9ubHkgdXNlckdyb3VwPzogSVVzZXJHcm91cDtcbn1cblxuLyoqXG4gKiBBIHNlcnZlcmxlc3MgRWxhc3RpQ2FjaGUgY2FjaGVcbiAqXG4gKiBAcmVzb3VyY2UgQVdTOjpFbGFzdGlDYWNoZTo6U2VydmVybGVzc0NhY2hlXG4gKi9cbkBwcm9wZXJ0eUluamVjdGFibGVcbmV4cG9ydCBjbGFzcyBTZXJ2ZXJsZXNzQ2FjaGUgZXh0ZW5kcyBTZXJ2ZXJsZXNzQ2FjaGVCYXNlIHtcbiAgLyoqXG4gICAqIFVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUFJPUEVSVFlfSU5KRUNUSU9OX0lEOiBzdHJpbmcgPSAnYXdzLWNkay1saWIuYXdzLWVsYXN0aWNhY2hlLlNlcnZlcmxlc3NDYWNoZSc7XG5cbiAgLyoqXG4gICAqIFJldHVybiB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBgU2VydmVybGVzc0NhY2hlYFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBpc1NlcnZlcmxlc3NDYWNoZSh4OiBhbnkpOiB4IGlzIFNlcnZlcmxlc3NDYWNoZSB7XG4gICAgcmV0dXJuIHggIT09IG51bGwgJiYgdHlwZW9mICh4KSA9PT0gJ29iamVjdCcgJiYgRUxBU1RJQ0FDSEVfU0VSVkVSTEVTU0NBQ0hFX1NZTUJPTCBpbiB4O1xuICB9XG5cbiAgLyoqXG4gICAqIEltcG9ydCBhbiBleGlzdGluZyBzZXJ2ZXJsZXNzIGNhY2hlIGJ5IG5hbWVcbiAgICpcbiAgICogQHBhcmFtIHNjb3BlIFRoZSBwYXJlbnQgY3JlYXRpbmcgY29uc3RydWN0ICh1c3VhbGx5IGB0aGlzYClcbiAgICogQHBhcmFtIGlkIFRoZSBjb25zdHJ1Y3QncyBuYW1lXG4gICAqIEBwYXJhbSBzZXJ2ZXJsZXNzQ2FjaGVOYW1lIFRoZSBuYW1lIG9mIHRoZSBleGlzdGluZyBzZXJ2ZXJsZXNzIGNhY2hlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21TZXJ2ZXJsZXNzQ2FjaGVOYW1lKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHNlcnZlcmxlc3NDYWNoZU5hbWU6IHN0cmluZyk6IElTZXJ2ZXJsZXNzQ2FjaGUge1xuICAgIHJldHVybiBTZXJ2ZXJsZXNzQ2FjaGUuZnJvbVNlcnZlcmxlc3NDYWNoZUF0dHJpYnV0ZXMoc2NvcGUsIGlkLCB7IHNlcnZlcmxlc3NDYWNoZU5hbWUgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wb3J0IGFuIGV4aXN0aW5nIHNlcnZlcmxlc3MgY2FjaGUgYnkgQVJOXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSBUaGUgcGFyZW50IGNyZWF0aW5nIGNvbnN0cnVjdCAodXN1YWxseSBgdGhpc2ApXG4gICAqIEBwYXJhbSBpZCBUaGUgY29uc3RydWN0J3MgbmFtZVxuICAgKiBAcGFyYW0gc2VydmVybGVzc0NhY2hlQXJuIFRoZSBBUk4gb2YgdGhlIGV4aXN0aW5nIHNlcnZlcmxlc3MgY2FjaGVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbVNlcnZlcmxlc3NDYWNoZUFybihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBzZXJ2ZXJsZXNzQ2FjaGVBcm46IHN0cmluZyk6IElTZXJ2ZXJsZXNzQ2FjaGUge1xuICAgIHJldHVybiBTZXJ2ZXJsZXNzQ2FjaGUuZnJvbVNlcnZlcmxlc3NDYWNoZUF0dHJpYnV0ZXMoc2NvcGUsIGlkLCB7IHNlcnZlcmxlc3NDYWNoZUFybiB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgYW4gZXhpc3Rpbmcgc2VydmVybGVzcyBjYWNoZSB1c2luZyBhdHRyaWJ1dGVzXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSBUaGUgcGFyZW50IGNyZWF0aW5nIGNvbnN0cnVjdCAodXN1YWxseSBgdGhpc2ApXG4gICAqIEBwYXJhbSBpZCBUaGUgY29uc3RydWN0J3MgbmFtZVxuICAgKiBAcGFyYW0gYXR0cnMgQSBgU2VydmVybGVzc0NhY2hlQXR0cmlidXRlc2Agb2JqZWN0XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21TZXJ2ZXJsZXNzQ2FjaGVBdHRyaWJ1dGVzKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIGF0dHJzOiBTZXJ2ZXJsZXNzQ2FjaGVBdHRyaWJ1dGVzKTogSVNlcnZlcmxlc3NDYWNoZSB7XG4gICAgbGV0IG5hbWU6IHN0cmluZztcbiAgICBsZXQgYXJuOiBzdHJpbmc7XG4gICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZihzY29wZSk7XG5cbiAgICBpZiAoYXR0cnMuc2VydmVybGVzc0NhY2hlQXJuICYmIGF0dHJzLnNlcnZlcmxlc3NDYWNoZU5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ09ubHkgb25lIG9mIHNlcnZlcmxlc3NDYWNoZUFybiBvciBzZXJ2ZXJsZXNzQ2FjaGVOYW1lIGNhbiBiZSBwcm92aWRlZC4nLCBzY29wZSk7XG4gICAgfVxuXG4gICAgaWYgKGF0dHJzLnNlcnZlcmxlc3NDYWNoZUFybikge1xuICAgICAgYXJuID0gYXR0cnMuc2VydmVybGVzc0NhY2hlQXJuO1xuICAgICAgY29uc3QgZXh0cmFjdGVkU2VydmVybGVzc0NhY2hlTmFtZSA9IHN0YWNrLnNwbGl0QXJuKGF0dHJzLnNlcnZlcmxlc3NDYWNoZUFybiwgQXJuRm9ybWF0LlNMQVNIX1JFU09VUkNFX05BTUUpLnJlc291cmNlTmFtZTtcbiAgICAgIGlmICghZXh0cmFjdGVkU2VydmVybGVzc0NhY2hlTmFtZSkge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdVbmFibGUgdG8gZXh0cmFjdCBzZXJ2ZXJsZXNzIGNhY2hlIG5hbWUgZnJvbSBBUk4uJywgc2NvcGUpO1xuICAgICAgfVxuICAgICAgbmFtZSA9IGV4dHJhY3RlZFNlcnZlcmxlc3NDYWNoZU5hbWU7XG4gICAgfSBlbHNlIGlmIChhdHRycy5zZXJ2ZXJsZXNzQ2FjaGVOYW1lKSB7XG4gICAgICBuYW1lID0gYXR0cnMuc2VydmVybGVzc0NhY2hlTmFtZTtcbiAgICAgIGFybiA9IHN0YWNrLmZvcm1hdEFybih7XG4gICAgICAgIHNlcnZpY2U6ICdlbGFzdGljYWNoZScsXG4gICAgICAgIHJlc291cmNlOiAnc2VydmVybGVzc2NhY2hlJyxcbiAgICAgICAgcmVzb3VyY2VOYW1lOiBhdHRycy5zZXJ2ZXJsZXNzQ2FjaGVOYW1lLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ09uZSBvZiBzZXJ2ZXJsZXNzQ2FjaGVOYW1lIG9yIHNlcnZlcmxlc3NDYWNoZUFybiBpcyByZXF1aXJlZC4nLCBzY29wZSk7XG4gICAgfVxuXG4gICAgY2xhc3MgSW1wb3J0IGV4dGVuZHMgU2VydmVybGVzc0NhY2hlQmFzZSB7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZW5naW5lID0gYXR0cnMuZW5naW5lO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHNlcnZlcmxlc3NDYWNoZU5hbWU6IHN0cmluZztcbiAgICAgIHB1YmxpYyByZWFkb25seSBzZXJ2ZXJsZXNzQ2FjaGVBcm46IHN0cmluZztcbiAgICAgIHB1YmxpYyByZWFkb25seSBiYWNrdXBBcm5zVG9SZXN0b3JlID0gYXR0cnMuYmFja3VwQXJuc1RvUmVzdG9yZTtcbiAgICAgIHB1YmxpYyByZWFkb25seSBrbXNLZXkgPSBhdHRycy5rbXNLZXk7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgdnBjID0gYXR0cnMudnBjO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHN1Ym5ldHMgPSBhdHRycy5zdWJuZXRzO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXBzID0gYXR0cnMuc2VjdXJpdHlHcm91cHM7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgdXNlckdyb3VwID0gYXR0cnMudXNlckdyb3VwO1xuXG4gICAgICBwdWJsaWMgcmVhZG9ubHkgY29ubmVjdGlvbnM6IGVjMi5Db25uZWN0aW9ucztcblxuICAgICAgY29uc3RydWN0b3Ioc2VydmVybGVzc0NhY2hlQXJuOiBzdHJpbmcsIHNlcnZlcmxlc3NDYWNoZU5hbWU6IHN0cmluZykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgICAgICB0aGlzLnNlcnZlcmxlc3NDYWNoZUFybiA9IHNlcnZlcmxlc3NDYWNoZUFybjtcbiAgICAgICAgdGhpcy5zZXJ2ZXJsZXNzQ2FjaGVOYW1lID0gc2VydmVybGVzc0NhY2hlTmFtZTtcblxuICAgICAgICBpZiAodGhpcy5lbmdpbmUpIHtcbiAgICAgICAgICBsZXQgZGVmYXVsdFBvcnQ6IGVjMi5Qb3J0O1xuICAgICAgICAgIHN3aXRjaCAodGhpcy5lbmdpbmUpIHtcbiAgICAgICAgICAgIGNhc2UgQ2FjaGVFbmdpbmUuVkFMS0VZX0xBVEVTVDpcbiAgICAgICAgICAgIGNhc2UgQ2FjaGVFbmdpbmUuVkFMS0VZXzc6XG4gICAgICAgICAgICBjYXNlIENhY2hlRW5naW5lLlZBTEtFWV84OlxuICAgICAgICAgICAgY2FzZSBDYWNoZUVuZ2luZS5SRURJU19MQVRFU1Q6XG4gICAgICAgICAgICBjYXNlIENhY2hlRW5naW5lLlJFRElTXzc6XG4gICAgICAgICAgICAgIC8vIERvY3VtZW50IHNob3dpbmcgdGhlIGRlZmF1bHQgcG9ydFxuICAgICAgICAgICAgICAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L2RnL3NldC11cC5odG1sI2VsYXN0aWNhY2hlLWluc3RhbGwtZ3JhbnQtYWNjZXNzLVZQTlxuICAgICAgICAgICAgICBkZWZhdWx0UG9ydCA9IGVjMi5Qb3J0LnRjcCg2Mzc5KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIENhY2hlRW5naW5lLk1FTUNBQ0hFRF9MQVRFU1Q6XG4gICAgICAgICAgICAgIC8vIERvY3VtZW50IHNob3dpbmcgdGhlIGRlZmF1bHQgcG9ydFxuICAgICAgICAgICAgICAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L2RnL3NldC11cC5odG1sI2VsYXN0aWNhY2hlLWluc3RhbGwtZ3JhbnQtYWNjZXNzLVZQTlxuICAgICAgICAgICAgICBkZWZhdWx0UG9ydCA9IGVjMi5Qb3J0LnRjcCgxMTIxMSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgVW5zdXBwb3J0ZWQgY2FjaGUgZW5naW5lOiAke3RoaXMuZW5naW5lfWAsIHNjb3BlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25zID0gbmV3IGVjMi5Db25uZWN0aW9ucyh7XG4gICAgICAgICAgICBzZWN1cml0eUdyb3VwczogdGhpcy5zZWN1cml0eUdyb3VwcyxcbiAgICAgICAgICAgIGRlZmF1bHRQb3J0OiBkZWZhdWx0UG9ydCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25zID0gbmV3IGVjMi5Db25uZWN0aW9ucyh7XG4gICAgICAgICAgICBzZWN1cml0eUdyb3VwczogdGhpcy5zZWN1cml0eUdyb3VwcyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgSW1wb3J0KGFybiwgbmFtZSk7XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgZW5naW5lPzogQ2FjaGVFbmdpbmU7XG4gIHB1YmxpYyByZWFkb25seSBzZXJ2ZXJsZXNzQ2FjaGVOYW1lOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBiYWNrdXBBcm5zVG9SZXN0b3JlPzogc3RyaW5nW107XG4gIHB1YmxpYyByZWFkb25seSBrbXNLZXk/OiBrbXMuSUtleTtcbiAgcHVibGljIHJlYWRvbmx5IHZwYz86IGVjMi5JVnBjO1xuICBwdWJsaWMgcmVhZG9ubHkgc3VibmV0cz86IGVjMi5JU3VibmV0W107XG4gIHB1YmxpYyByZWFkb25seSBzZWN1cml0eUdyb3Vwcz86IGVjMi5JU2VjdXJpdHlHcm91cFtdO1xuICBwdWJsaWMgcmVhZG9ubHkgdXNlckdyb3VwPzogSVVzZXJHcm91cDtcblxuICAvKipcbiAgICogVGhlIEFSTiBvZiB0aGUgc2VydmVybGVzcyBjYWNoZVxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2VydmVybGVzc0NhY2hlQXJuOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgZW5kcG9pbnQgYWRkcmVzcyBvZiB0aGUgc2VydmVybGVzcyBjYWNoZVxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2VydmVybGVzc0NhY2hlRW5kcG9pbnRBZGRyZXNzOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgZW5kcG9pbnQgcG9ydCBvZiB0aGUgc2VydmVybGVzcyBjYWNoZVxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2VydmVybGVzc0NhY2hlRW5kcG9pbnRQb3J0OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgcmVhZGVyIGVuZHBvaW50IGFkZHJlc3Mgb2YgdGhlIHNlcnZlcmxlc3MgY2FjaGVcbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNlcnZlcmxlc3NDYWNoZVJlYWRlckVuZHBvaW50QWRkcmVzczogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHJlYWRlciBlbmRwb2ludCBwb3J0IG9mIHRoZSBzZXJ2ZXJsZXNzIGNhY2hlXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzZXJ2ZXJsZXNzQ2FjaGVSZWFkZXJFbmRwb2ludFBvcnQ6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50IHN0YXR1cyBvZiB0aGUgc2VydmVybGVzcyBjYWNoZVxuICAgKiBDYW4gYmUgJ0NSRUFUSU5HJywgJ0FWQUlMQUJMRScsICdERUxFVElORycsICdDUkVBVEUtRkFJTEVEJywgJ01PRElGWUlORydcbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNlcnZlcmxlc3NDYWNoZVN0YXR1czogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBY2Nlc3MgdG8gbmV0d29yayBjb25uZWN0aW9uc1xuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNvbm5lY3Rpb25zOiBlYzIuQ29ubmVjdGlvbnM7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFNlcnZlcmxlc3NDYWNoZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7fSk7XG5cbiAgICAvLyBFbmhhbmNlZCBDREsgQW5hbHl0aWNzIFRlbGVtZXRyeVxuICAgIGFkZENvbnN0cnVjdE1ldGFkYXRhKHRoaXMsIHByb3BzKTtcblxuICAgIHRoaXMuZW5naW5lID0gcHJvcHMuZW5naW5lID8/IENhY2hlRW5naW5lLlZBTEtFWV9MQVRFU1Q7XG4gICAgdGhpcy5zZXJ2ZXJsZXNzQ2FjaGVOYW1lID0gcHJvcHMuc2VydmVybGVzc0NhY2hlTmFtZSA/PyBMYXp5LnN0cmluZyh7IHByb2R1Y2U6ICgpID0+IE5hbWVzLnVuaXF1ZUlkKHRoaXMpIH0pO1xuICAgIHRoaXMua21zS2V5ID0gcHJvcHMua21zS2V5O1xuICAgIHRoaXMudnBjID0gcHJvcHMudnBjO1xuICAgIHRoaXMudXNlckdyb3VwID0gcHJvcHMudXNlckdyb3VwO1xuXG4gICAgdGhpcy52YWxpZGF0ZURlc2NyaXB0aW9uKHByb3BzLmRlc2NyaXB0aW9uKTtcbiAgICB0aGlzLnZhbGlkYXRlRGF0YVN0b3JhZ2VMaW1pdHMocHJvcHMuY2FjaGVVc2FnZUxpbWl0cyk7XG4gICAgdGhpcy52YWxpZGF0ZVJlcXVlc3RSYXRlTGltaXRzKHByb3BzLmNhY2hlVXNhZ2VMaW1pdHMpO1xuICAgIHRoaXMudmFsaWRhdGVCYWNrdXBTZXR0aW5ncyhwcm9wcy5iYWNrdXApO1xuICAgIHRoaXMudmFsaWRhdGVVc2VyR3JvdXBDb21wYXRpYmlsaXR5KHRoaXMuZW5naW5lLCB0aGlzLnVzZXJHcm91cCk7XG5cbiAgICBjb25zdCBzdWJuZXRDb25maWcgPSB0aGlzLmNvbmZpZ3VyZVN1Ym5ldHMocHJvcHMpO1xuICAgIGNvbnN0IHN1Ym5ldElkcyA9IHN1Ym5ldENvbmZpZy5zdWJuZXRJZHM7XG4gICAgdGhpcy5zdWJuZXRzID0gc3VibmV0Q29uZmlnLnN1Ym5ldHM7XG5cbiAgICBjb25zdCBzZWN1cml0eUdyb3VwQ29uZmlnID0gdGhpcy5jb25maWd1cmVTZWN1cml0eUdyb3Vwcyhwcm9wcyk7XG4gICAgY29uc3Qgc2VjdXJpdHlHcm91cElkcyA9IHNlY3VyaXR5R3JvdXBDb25maWcuc2VjdXJpdHlHcm91cElkcztcbiAgICB0aGlzLnNlY3VyaXR5R3JvdXBzID0gc2VjdXJpdHlHcm91cENvbmZpZy5zZWN1cml0eUdyb3VwcztcblxuICAgIGNvbnN0IFtlbmdpbmUsIHZlcnNpb25dID0gdGhpcy5lbmdpbmUuc3BsaXQoJ18nKTtcblxuICAgIGNvbnN0IHJlc291cmNlID0gbmV3IENmblNlcnZlcmxlc3NDYWNoZSh0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICBlbmdpbmU6IGVuZ2luZSxcbiAgICAgIG1ham9yRW5naW5lVmVyc2lvbjogdmVyc2lvbixcbiAgICAgIHNlcnZlcmxlc3NDYWNoZU5hbWU6IHRoaXMuc2VydmVybGVzc0NhY2hlTmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBwcm9wcy5kZXNjcmlwdGlvbixcbiAgICAgIGNhY2hlVXNhZ2VMaW1pdHM6IHRoaXMucmVuZGVyQ2FjaGVVc2FnZUxpbWl0cyhwcm9wcy5jYWNoZVVzYWdlTGltaXRzKSxcbiAgICAgIGRhaWx5U25hcHNob3RUaW1lOiBwcm9wcy5iYWNrdXA/LmJhY2t1cFRpbWUgPyB0aGlzLmZvcm1hdEJhY2t1cFRpbWUocHJvcHMuYmFja3VwLmJhY2t1cFRpbWUpIDogdW5kZWZpbmVkLFxuICAgICAgc25hcHNob3RSZXRlbnRpb25MaW1pdDogcHJvcHMuYmFja3VwPy5iYWNrdXBSZXRlbnRpb25MaW1pdCxcbiAgICAgIGZpbmFsU25hcHNob3ROYW1lOiBwcm9wcy5iYWNrdXA/LmJhY2t1cE5hbWVCZWZvcmVEZWxldGlvbixcbiAgICAgIHNuYXBzaG90QXJuc1RvUmVzdG9yZTogcHJvcHMuYmFja3VwPy5iYWNrdXBBcm5zVG9SZXN0b3JlLFxuICAgICAga21zS2V5SWQ6IHByb3BzLmttc0tleT8ua2V5SWQsXG4gICAgICBzdWJuZXRJZHM6IHN1Ym5ldElkcyxcbiAgICAgIHNlY3VyaXR5R3JvdXBJZHM6IHNlY3VyaXR5R3JvdXBJZHMsXG4gICAgICB1c2VyR3JvdXBJZDogcHJvcHMudXNlckdyb3VwPy51c2VyR3JvdXBOYW1lLFxuICAgIH0pO1xuXG4gICAgaWYgKHByb3BzLnVzZXJHcm91cCkge1xuICAgICAgY29uc3QgdXNlckdyb3VwUmVzb3VyY2UgPSBwcm9wcy51c2VyR3JvdXAubm9kZS5maW5kQ2hpbGQoJ1Jlc291cmNlJykgYXMgQ2ZuVXNlckdyb3VwO1xuICAgICAgcmVzb3VyY2UuYWRkRGVwZW5kZW5jeSh1c2VyR3JvdXBSZXNvdXJjZSk7XG4gICAgfVxuXG4gICAgdGhpcy5iYWNrdXBBcm5zVG9SZXN0b3JlID0gcmVzb3VyY2Uuc25hcHNob3RBcm5zVG9SZXN0b3JlO1xuICAgIHRoaXMuc2VydmVybGVzc0NhY2hlQXJuID0gcmVzb3VyY2UuYXR0ckFybjtcbiAgICB0aGlzLnNlcnZlcmxlc3NDYWNoZUVuZHBvaW50QWRkcmVzcyA9IHJlc291cmNlLmF0dHJFbmRwb2ludEFkZHJlc3M7XG4gICAgdGhpcy5zZXJ2ZXJsZXNzQ2FjaGVFbmRwb2ludFBvcnQgPSByZXNvdXJjZS5hdHRyRW5kcG9pbnRQb3J0O1xuICAgIHRoaXMuc2VydmVybGVzc0NhY2hlUmVhZGVyRW5kcG9pbnRBZGRyZXNzID0gcmVzb3VyY2UuYXR0clJlYWRlckVuZHBvaW50QWRkcmVzcztcbiAgICB0aGlzLnNlcnZlcmxlc3NDYWNoZVJlYWRlckVuZHBvaW50UG9ydCA9IHJlc291cmNlLmF0dHJSZWFkZXJFbmRwb2ludFBvcnQ7XG4gICAgdGhpcy5zZXJ2ZXJsZXNzQ2FjaGVTdGF0dXMgPSByZXNvdXJjZS5hdHRyU3RhdHVzO1xuXG4gICAgdGhpcy5jb25uZWN0aW9ucyA9IG5ldyBlYzIuQ29ubmVjdGlvbnMoe1xuICAgICAgc2VjdXJpdHlHcm91cHM6IHRoaXMuc2VjdXJpdHlHcm91cHMsXG4gICAgICBkZWZhdWx0UG9ydDogZWMyLlBvcnQudGNwKExhenkubnVtYmVyKHsgcHJvZHVjZTogKCkgPT4gcGFyc2VJbnQodGhpcy5zZXJ2ZXJsZXNzQ2FjaGVFbmRwb2ludFBvcnQpIH0pKSxcbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBFTEFTVElDQUNIRV9TRVJWRVJMRVNTQ0FDSEVfU1lNQk9MLCB7IHZhbHVlOiB0cnVlIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGRlc2NyaXB0aW9uIG1lZXRzIEFXUyByZXF1aXJlbWVudHNcbiAgICpcbiAgICogQHBhcmFtIGRlc2NyaXB0aW9uIFRoZSBkZXNjcmlwdGlvbiB0byB2YWxpZGF0ZVxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZURlc2NyaXB0aW9uKGRlc2NyaXB0aW9uPzogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFkZXNjcmlwdGlvbiB8fCBUb2tlbi5pc1VucmVzb2x2ZWQoZGVzY3JpcHRpb24pKSByZXR1cm47XG5cbiAgICBpZiAoZGVzY3JpcHRpb24ubGVuZ3RoID4gMjU1KSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGBEZXNjcmlwdGlvbiBtdXN0IG5vdCBleGNlZWQgMjU1IGNoYXJhY3RlcnMsIGN1cnJlbnRseSBoYXMgJHtkZXNjcmlwdGlvbi5sZW5ndGh9YCwgdGhpcyk7XG4gICAgfVxuXG4gICAgaWYgKGRlc2NyaXB0aW9uLmluY2x1ZGVzKCc8JykgfHwgZGVzY3JpcHRpb24uaW5jbHVkZXMoJz4nKSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignRGVzY3JpcHRpb24gbXVzdCBub3QgY29udGFpbiA8IG9yID4gY2hhcmFjdGVycycsIHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBkYXRhIHN0b3JhZ2Ugc2l6ZSBsaW1pdHNcbiAgICpcbiAgICogQHBhcmFtIGxpbWl0cyBUaGUgdXNhZ2UgbGltaXRzIGNvbnRhaW5pbmcgZGF0YSBzdG9yYWdlIHNldHRpbmdzXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlRGF0YVN0b3JhZ2VMaW1pdHMobGltaXRzPzogQ2FjaGVVc2FnZUxpbWl0c1Byb3BlcnR5KTogdm9pZCB7XG4gICAgaWYgKCFsaW1pdHMpIHJldHVybjtcblxuICAgIGlmIChsaW1pdHMuZGF0YVN0b3JhZ2VNaW5pbXVtU2l6ZSAmJiAhbGltaXRzLmRhdGFTdG9yYWdlTWluaW11bVNpemUuaXNVbnJlc29sdmVkKCkgJiZcbiAgICAgIChsaW1pdHMuZGF0YVN0b3JhZ2VNaW5pbXVtU2l6ZS50b0dpYmlieXRlcygpIDwgREFUQV9TVE9SQUdFX01JTl9HQiB8fCBsaW1pdHMuZGF0YVN0b3JhZ2VNaW5pbXVtU2l6ZS50b0dpYmlieXRlcygpID4gREFUQV9TVE9SQUdFX01BWF9HQikpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ0RhdGEgc3RvcmFnZSBtaW5pbXVtIG11c3QgYmUgYmV0d2VlbiAxIGFuZCA1MDAwIEdCLicsIHRoaXMpO1xuICAgIH1cbiAgICBpZiAobGltaXRzLmRhdGFTdG9yYWdlTWF4aW11bVNpemUgJiYgIWxpbWl0cy5kYXRhU3RvcmFnZU1heGltdW1TaXplLmlzVW5yZXNvbHZlZCgpICYmXG4gICAgICAobGltaXRzLmRhdGFTdG9yYWdlTWF4aW11bVNpemUudG9HaWJpYnl0ZXMoKSA8IERBVEFfU1RPUkFHRV9NSU5fR0IgfHwgbGltaXRzLmRhdGFTdG9yYWdlTWF4aW11bVNpemUudG9HaWJpYnl0ZXMoKSA+IERBVEFfU1RPUkFHRV9NQVhfR0IpKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdEYXRhIHN0b3JhZ2UgbWF4aW11bSBtdXN0IGJlIGJldHdlZW4gMSBhbmQgNTAwMCBHQi4nLCB0aGlzKTtcbiAgICB9XG5cbiAgICBpZiAobGltaXRzLmRhdGFTdG9yYWdlTWluaW11bVNpemUgJiYgbGltaXRzLmRhdGFTdG9yYWdlTWF4aW11bVNpemUgJiZcbiAgICAgICFsaW1pdHMuZGF0YVN0b3JhZ2VNaW5pbXVtU2l6ZS5pc1VucmVzb2x2ZWQoKSAmJiAhbGltaXRzLmRhdGFTdG9yYWdlTWF4aW11bVNpemUuaXNVbnJlc29sdmVkKCkgJiZcbiAgICAgIGxpbWl0cy5kYXRhU3RvcmFnZU1pbmltdW1TaXplLnRvR2liaWJ5dGVzKCkgPiBsaW1pdHMuZGF0YVN0b3JhZ2VNYXhpbXVtU2l6ZS50b0dpYmlieXRlcygpKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdEYXRhIHN0b3JhZ2UgbWluaW11bSBjYW5ub3QgYmUgZ3JlYXRlciB0aGFuIG1heGltdW0nLCB0aGlzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgcmVxdWVzdCByYXRlIGxpbWl0c1xuICAgKlxuICAgKiBAcGFyYW0gbGltaXRzIFRoZSB1c2FnZSBsaW1pdHMgY29udGFpbmluZyByZXF1ZXN0IHJhdGUgc2V0dGluZ3NcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVSZXF1ZXN0UmF0ZUxpbWl0cyhsaW1pdHM/OiBDYWNoZVVzYWdlTGltaXRzUHJvcGVydHkpOiB2b2lkIHtcbiAgICBpZiAoIWxpbWl0cykgcmV0dXJuO1xuXG4gICAgaWYgKGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWluaW11bSAhPT0gdW5kZWZpbmVkICYmICFUb2tlbi5pc1VucmVzb2x2ZWQobGltaXRzLnJlcXVlc3RSYXRlTGltaXRNaW5pbXVtKSAmJlxuICAgICAgKGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWluaW11bSA8IFJFUVVFU1RfUkFURV9NSU5fRUNQVSB8fCBsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1pbmltdW0gPiBSRVFVRVNUX1JBVEVfTUFYX0VDUFUpKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdSZXF1ZXN0IHJhdGUgbWluaW11bSBtdXN0IGJlIGJldHdlZW4gMSwwMDAgYW5kIDE1LDAwMCwwMDAgRUNQVXMgcGVyIHNlY29uZCcsIHRoaXMpO1xuICAgIH1cbiAgICBpZiAobGltaXRzLnJlcXVlc3RSYXRlTGltaXRNYXhpbXVtICE9PSB1bmRlZmluZWQgJiYgIVRva2VuLmlzVW5yZXNvbHZlZChsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1heGltdW0pICYmXG4gICAgICAobGltaXRzLnJlcXVlc3RSYXRlTGltaXRNYXhpbXVtIDwgUkVRVUVTVF9SQVRFX01JTl9FQ1BVIHx8IGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWF4aW11bSA+IFJFUVVFU1RfUkFURV9NQVhfRUNQVSkpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1JlcXVlc3QgcmF0ZSBtYXhpbXVtIG11c3QgYmUgYmV0d2VlbiAxLDAwMCBhbmQgMTUsMDAwLDAwMCBFQ1BVcyBwZXIgc2Vjb25kJywgdGhpcyk7XG4gICAgfVxuXG4gICAgaWYgKCFUb2tlbi5pc1VucmVzb2x2ZWQobGltaXRzLnJlcXVlc3RSYXRlTGltaXRNaW5pbXVtKSAmJiAhVG9rZW4uaXNVbnJlc29sdmVkKGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWF4aW11bSkgJiZcbiAgICAgIGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWluaW11bSAhPT0gdW5kZWZpbmVkICYmIGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWF4aW11bSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICBsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1pbmltdW0gPiBsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1heGltdW0pIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1JlcXVlc3QgcmF0ZSBtaW5pbXVtIGNhbm5vdCBiZSBncmVhdGVyIHRoYW4gbWF4aW11bScsIHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBiYWNrdXAgc2V0dGluZ3MgbWVldCBBV1MgcmVxdWlyZW1lbnRzXG4gICAqXG4gICAqIEBwYXJhbSBiYWNrdXAgVGhlIGJhY2t1cCBzZXR0aW5ncyB0byB2YWxpZGF0ZVxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUJhY2t1cFNldHRpbmdzKGJhY2t1cD86IEJhY2t1cFNldHRpbmdzKTogdm9pZCB7XG4gICAgaWYgKCFUb2tlbi5pc1VucmVzb2x2ZWQoYmFja3VwPy5iYWNrdXBSZXRlbnRpb25MaW1pdCkgJiYgYmFja3VwPy5iYWNrdXBSZXRlbnRpb25MaW1pdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBsaW1pdCA9IGJhY2t1cC5iYWNrdXBSZXRlbnRpb25MaW1pdDtcbiAgICAgIGlmIChsaW1pdCA8IDEgfHwgbGltaXQgPiAzNSkge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdCYWNrdXAgcmV0ZW50aW9uIGxpbWl0IG11c3QgYmUgYmV0d2VlbiAxIGFuZCAzNSBkYXlzJywgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFUb2tlbi5pc1VucmVzb2x2ZWQoYmFja3VwPy5iYWNrdXBOYW1lQmVmb3JlRGVsZXRpb24pICYmIGJhY2t1cD8uYmFja3VwTmFtZUJlZm9yZURlbGV0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IG5hbWUgPSBiYWNrdXAuYmFja3VwTmFtZUJlZm9yZURlbGV0aW9uO1xuXG4gICAgICBpZiAoIS9eW2EtekEtWl0vLnRlc3QobmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignRmluYWwgYmFja3VwIG5hbWUgbXVzdCBiZWdpbiB3aXRoIGEgbGV0dGVyJywgdGhpcyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghL15bYS16QS1aMC05LV0rJC8udGVzdChuYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdGaW5hbCBiYWNrdXAgbmFtZSBtdXN0IGNvbnRhaW4gb25seSBBU0NJSSBsZXR0ZXJzLCBkaWdpdHMsIGFuZCBoeXBoZW5zJywgdGhpcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChuYW1lLmVuZHNXaXRoKCctJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignRmluYWwgYmFja3VwIG5hbWUgbXVzdCBub3QgZW5kIHdpdGggYSBoeXBoZW4nLCB0aGlzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5hbWUuaW5jbHVkZXMoJy0tJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignRmluYWwgYmFja3VwIG5hbWUgbXVzdCBub3QgY29udGFpbiB0d28gY29uc2VjdXRpdmUgaHlwaGVucycsIHRoaXMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB1c2VyIGdyb3VwIGNvbXBhdGliaWxpdHkgd2l0aCBjYWNoZSBlbmdpbmVcbiAgICpcbiAgICogQHBhcmFtIGVuZ2luZSBUaGUgY2FjaGUgZW5naW5lXG4gICAqIEBwYXJhbSB1c2VyR3JvdXAgVGhlIHVzZXIgZ3JvdXAgdG8gdmFsaWRhdGVcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVVc2VyR3JvdXBDb21wYXRpYmlsaXR5KGVuZ2luZTogQ2FjaGVFbmdpbmUsIHVzZXJHcm91cD86IElVc2VyR3JvdXApOiB2b2lkIHtcbiAgICBpZiAoIXVzZXJHcm91cCkgcmV0dXJuO1xuXG4gICAgaWYgKGVuZ2luZSA9PT0gQ2FjaGVFbmdpbmUuTUVNQ0FDSEVEX0xBVEVTVCkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignVXNlciBncm91cHMgY2Fubm90IGJlIHVzZWQgd2l0aCBNZW1jYWNoZWQgZW5naW5lcy4gT25seSBSZWRpcyBhbmQgVmFsa2V5IGVuZ2luZXMgc3VwcG9ydCB1c2VyIGdyb3Vwcy4nLCB0aGlzKTtcbiAgICB9XG5cbiAgICBpZiAoZW5naW5lID09PSBDYWNoZUVuZ2luZS5SRURJU19MQVRFU1QgJiYgdXNlckdyb3VwLmVuZ2luZSAhPT0gVXNlckVuZ2luZS5SRURJUykge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignUmVkaXMgY2FjaGUgY2FuIG9ubHkgdXNlIFJlZGlzIHVzZXIgZ3JvdXBzLicsIHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXIgY2FjaGUgdXNhZ2UgbGltaXRzIGZvciBDbG91ZEZvcm1hdGlvblxuICAgKlxuICAgKiBAcGFyYW0gbGltaXRzIFRoZSB1c2FnZSBsaW1pdHMgdG8gcmVuZGVyXG4gICAqIEByZXR1cm5zIENsb3VkRm9ybWF0aW9uLWNvbXBhdGlibGUgdXNhZ2UgbGltaXRzIG9iamVjdCBvciB1bmRlZmluZWRcbiAgICovXG4gIHByaXZhdGUgcmVuZGVyQ2FjaGVVc2FnZUxpbWl0cyhsaW1pdHM/OiBDYWNoZVVzYWdlTGltaXRzUHJvcGVydHkpOiBhbnkge1xuICAgIGlmICghbGltaXRzKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgY2FjaGVVc2FnZUxpbWl0czogYW55ID0ge307XG5cbiAgICBpZiAobGltaXRzLmRhdGFTdG9yYWdlTWluaW11bVNpemUgIT09IHVuZGVmaW5lZCB8fCBsaW1pdHMuZGF0YVN0b3JhZ2VNYXhpbXVtU2l6ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjYWNoZVVzYWdlTGltaXRzLmRhdGFTdG9yYWdlID0ge1xuICAgICAgICB1bml0OiBEYXRhU3RvcmFnZVVuaXQuR0lHQUJZVEVTLFxuICAgICAgICAuLi4obGltaXRzLmRhdGFTdG9yYWdlTWluaW11bVNpemUgIT09IHVuZGVmaW5lZCAmJiB7IG1pbmltdW06IGxpbWl0cy5kYXRhU3RvcmFnZU1pbmltdW1TaXplLnRvR2liaWJ5dGVzKCkgfSksXG4gICAgICAgIC4uLihsaW1pdHMuZGF0YVN0b3JhZ2VNYXhpbXVtU2l6ZSAhPT0gdW5kZWZpbmVkICYmIHsgbWF4aW11bTogbGltaXRzLmRhdGFTdG9yYWdlTWF4aW11bVNpemUudG9HaWJpYnl0ZXMoKSB9KSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWluaW11bSAhPT0gdW5kZWZpbmVkIHx8IGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWF4aW11bSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjYWNoZVVzYWdlTGltaXRzLmVjcHVQZXJTZWNvbmQgPSB7XG4gICAgICAgIC4uLihsaW1pdHMucmVxdWVzdFJhdGVMaW1pdE1pbmltdW0gIT09IHVuZGVmaW5lZCAmJiB7IG1pbmltdW06IGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWluaW11bSB9KSxcbiAgICAgICAgLi4uKGxpbWl0cy5yZXF1ZXN0UmF0ZUxpbWl0TWF4aW11bSAhPT0gdW5kZWZpbmVkICYmIHsgbWF4aW11bTogbGltaXRzLnJlcXVlc3RSYXRlTGltaXRNYXhpbXVtIH0pLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMoY2FjaGVVc2FnZUxpbWl0cykubGVuZ3RoID4gMCA/IGNhY2hlVXNhZ2VMaW1pdHMgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogQ29uZmlndXJlIHN1Ym5ldHMgZm9yIHRoZSBjYWNoZVxuICAgKlxuICAgKiBAcGFyYW0gcHJvcHMgVGhlIFNlcnZlcmxlc3NDYWNoZSBwcm9wZXJ0aWVzXG4gICAqIEByZXR1cm5zIE9iamVjdCBjb250YWluaW5nIHN1Ym5ldCBJRHMgYW5kIHN1Ym5ldCBvYmplY3RzXG4gICAqL1xuICBwcml2YXRlIGNvbmZpZ3VyZVN1Ym5ldHMocHJvcHM6IFNlcnZlcmxlc3NDYWNoZVByb3BzKTogeyBzdWJuZXRJZHM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkOyBzdWJuZXRzOiBlYzIuSVN1Ym5ldFtdIHwgdW5kZWZpbmVkIH0ge1xuICAgIGxldCBzZWxlY3RlZFN1Ym5ldHM7XG4gICAgaWYgKHByb3BzLnZwY1N1Ym5ldHMpIHtcbiAgICAgIHNlbGVjdGVkU3VibmV0cyA9IHByb3BzLnZwYy5zZWxlY3RTdWJuZXRzKHByb3BzLnZwY1N1Ym5ldHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZWxlY3RlZFN1Ym5ldHMgPSBwcm9wcy52cGMuc2VsZWN0U3VibmV0cyh7XG4gICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfV0lUSF9FR1JFU1MsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3VibmV0SWRzOiBzZWxlY3RlZFN1Ym5ldHMuc3VibmV0SWRzLmxlbmd0aCA+IDAgPyBzZWxlY3RlZFN1Ym5ldHMuc3VibmV0SWRzIDogdW5kZWZpbmVkLFxuICAgICAgc3VibmV0czogc2VsZWN0ZWRTdWJuZXRzLnN1Ym5ldHMubGVuZ3RoID4gMCA/IHNlbGVjdGVkU3VibmV0cy5zdWJuZXRzIDogdW5kZWZpbmVkLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ29uZmlndXJlIHNlY3VyaXR5IGdyb3VwcyBmb3IgdGhlIGNhY2hlXG4gICAqXG4gICAqIEBwYXJhbSBwcm9wcyBUaGUgU2VydmVybGVzc0NhY2hlIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMgT2JqZWN0IGNvbnRhaW5pbmcgc2VjdXJpdHkgZ3JvdXAgSURzIGFuZCBzZWN1cml0eSBncm91cCBvYmplY3RzXG4gICAqL1xuICBwcml2YXRlIGNvbmZpZ3VyZVNlY3VyaXR5R3JvdXBzKHByb3BzOiBTZXJ2ZXJsZXNzQ2FjaGVQcm9wcyk6IHsgc2VjdXJpdHlHcm91cElkczogc3RyaW5nW107IHNlY3VyaXR5R3JvdXBzOiBlYzIuSVNlY3VyaXR5R3JvdXBbXSB9IHtcbiAgICBpZiAocHJvcHMuc2VjdXJpdHlHcm91cHMgJiYgcHJvcHMuc2VjdXJpdHlHcm91cHMubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2VjdXJpdHlHcm91cElkczogcHJvcHMuc2VjdXJpdHlHcm91cHMubWFwKHNnID0+IHNnLnNlY3VyaXR5R3JvdXBJZCksXG4gICAgICAgIHNlY3VyaXR5R3JvdXBzOiBwcm9wcy5zZWN1cml0eUdyb3VwcyxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG5ld1NlY3VyaXR5R3JvdXAgPSBuZXcgZWMyLlNlY3VyaXR5R3JvdXAodGhpcywgJ1NlY3VyaXR5R3JvdXAnLCB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgU2VjdXJpdHkgZ3JvdXAgZm9yICR7dGhpcy5ub2RlLmlkfSBjYWNoZS5gLFxuICAgICAgICB2cGM6IHByb3BzLnZwYyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2VjdXJpdHlHcm91cElkczogW25ld1NlY3VyaXR5R3JvdXAuc2VjdXJpdHlHcm91cElkXSxcbiAgICAgICAgc2VjdXJpdHlHcm91cHM6IFtuZXdTZWN1cml0eUdyb3VwXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBzY2hlZHVsZSB0byBISDpNTSBmb3JtYXQgZm9yIGRhaWx5IGJhY2t1cHNcbiAgICpcbiAgICogQHBhcmFtIHNjaGVkdWxlIFRoZSBzY2hlZHVsZSB0byBmb3JtYXRcbiAgICogQHJldHVybnMgVGltZSBzdHJpbmcgaW4gSEg6TU0gZm9ybWF0XG4gICAqL1xuICBwcml2YXRlIGZvcm1hdEJhY2t1cFRpbWUoc2NoZWR1bGU6IGV2ZW50cy5TY2hlZHVsZSk6IHN0cmluZyB7XG4gICAgY29uc3QgV0lMRF9DQVJEID0gJyonO1xuICAgIGNvbnN0IFtcbiAgICAgIG1pbnV0ZUV4cHJlc3Npb24sIGhvdXJFeHByZXNzaW9uLFxuICAgICAgZGF5RXhwcmVzc2lvbiwgbW9udGhFeHByZXNzaW9uLFxuICAgICAgd2Vla0RheUV4cHJlc3Npb24sIHllYXJFeHByZXNzaW9uLFxuICAgIF0gPSBzY2hlZHVsZS5leHByZXNzaW9uU3RyaW5nLnN1YnN0cig1KS5zbGljZSgwLCAtMSkuc3BsaXQoJyAnKTtcblxuICAgIGlmIChkYXlFeHByZXNzaW9uICE9IFdJTERfQ0FSRCB8fCBtb250aEV4cHJlc3Npb24gIT0gV0lMRF9DQVJEIHx8IHllYXJFeHByZXNzaW9uICE9IFdJTERfQ0FSRCB8fCB3ZWVrRGF5RXhwcmVzc2lvbiAhPSAnPycpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ0ZvciBub3csIG9ubHkgZGFpbHkgYmFja3VwIHRpbWUgaXMgYXZhaWxhYmxlIChzdXBwb3J0cyBqdXN0IGhvdXIgYW5kIG1pbnV0ZSkuIERheSwgbW9udGgsIHllYXIsIGFuZCB3ZWVrRGF5IGFyZSBub3QgYWxsb3dlZCcsIHRoaXMpO1xuICAgIH1cblxuICAgIGNvbnN0IGhvdXIgPSBob3VyRXhwcmVzc2lvbiA9PSBXSUxEX0NBUkQgPyAnMCcgOiBob3VyRXhwcmVzc2lvbjtcbiAgICBjb25zdCBtaW51dGUgPSBtaW51dGVFeHByZXNzaW9uID09IFdJTERfQ0FSRCA/ICcwJyA6IG1pbnV0ZUV4cHJlc3Npb247XG5cbiAgICByZXR1cm4gYCR7aG91ci5wYWRTdGFydCgyLCAnMCcpfToke21pbnV0ZS5wYWRTdGFydCgyLCAnMCcpfWA7XG4gIH1cbn1cbiJdfQ==