@robhan-cdk-lib/aws_grafana 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +5505 -0
- package/API.md +1340 -0
- package/LICENSE +19 -0
- package/README.md +47 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +12 -0
- package/lib/workspace.d.ts +624 -0
- package/lib/workspace.js +694 -0
- package/package.json +128 -0
package/lib/workspace.js
ADDED
|
@@ -0,0 +1,694 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Workspace = exports.Status = exports.SamlConfigurationStatuses = exports.PermissionTypes = exports.NotificationDestinations = exports.AuthenticationProviders = exports.AccountAccessType = void 0;
|
|
5
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
+
const aws_grafana_1 = require("aws-cdk-lib/aws-grafana");
|
|
7
|
+
const constructs_1 = require("constructs");
|
|
8
|
+
/**
|
|
9
|
+
* Specifies whether the workspace can access AWS resources in this AWS account only, or whether it
|
|
10
|
+
* can also access AWS resources in other accounts in the same organization. If this is
|
|
11
|
+
* ORGANIZATION, the OrganizationalUnits parameter specifies which organizational units the
|
|
12
|
+
* workspace can access.
|
|
13
|
+
*/
|
|
14
|
+
var AccountAccessType;
|
|
15
|
+
(function (AccountAccessType) {
|
|
16
|
+
/**
|
|
17
|
+
* Access is limited to the current AWS account only.
|
|
18
|
+
*/
|
|
19
|
+
AccountAccessType["CURRENT_ACCOUNT"] = "CURRENT_ACCOUNT";
|
|
20
|
+
/**
|
|
21
|
+
* Access is extended to the entire AWS organization.
|
|
22
|
+
*/
|
|
23
|
+
AccountAccessType["ORGANIZATION"] = "ORGANIZATION";
|
|
24
|
+
})(AccountAccessType || (exports.AccountAccessType = AccountAccessType = {}));
|
|
25
|
+
/**
|
|
26
|
+
* Specifies whether this workspace uses SAML 2.0, AWS IAM Identity Center, or both to authenticate
|
|
27
|
+
* users for using the Grafana console within a workspace.
|
|
28
|
+
*
|
|
29
|
+
* @see https://docs.aws.amazon.com/grafana/latest/APIReference/API_CreateWorkspace.html
|
|
30
|
+
*/
|
|
31
|
+
var AuthenticationProviders;
|
|
32
|
+
(function (AuthenticationProviders) {
|
|
33
|
+
/**
|
|
34
|
+
* AWS Single Sign-On authentication provider.
|
|
35
|
+
*/
|
|
36
|
+
AuthenticationProviders["AWS_SSO"] = "AWS_SSO";
|
|
37
|
+
/**
|
|
38
|
+
* Security Assertion Markup Language (SAML) authentication provider.
|
|
39
|
+
*/
|
|
40
|
+
AuthenticationProviders["SAML"] = "SAML";
|
|
41
|
+
})(AuthenticationProviders || (exports.AuthenticationProviders = AuthenticationProviders = {}));
|
|
42
|
+
/**
|
|
43
|
+
* The AWS notification channels that Amazon Managed Grafana can automatically create IAM roles and
|
|
44
|
+
* permissions for, to allow Amazon Managed Grafana to use these channels.
|
|
45
|
+
*/
|
|
46
|
+
var NotificationDestinations;
|
|
47
|
+
(function (NotificationDestinations) {
|
|
48
|
+
/**
|
|
49
|
+
* Amazon Simple Notification Service (SNS) as notification destination.
|
|
50
|
+
*/
|
|
51
|
+
NotificationDestinations["SNS"] = "SNS";
|
|
52
|
+
})(NotificationDestinations || (exports.NotificationDestinations = NotificationDestinations = {}));
|
|
53
|
+
/**
|
|
54
|
+
* If this is SERVICE_MANAGED, and the workplace was created through the Amazon Managed Grafana
|
|
55
|
+
* console, then Amazon Managed Grafana automatically creates the IAM roles and provisions the
|
|
56
|
+
* permissions that the workspace needs to use AWS data sources and notification channels.
|
|
57
|
+
*
|
|
58
|
+
* If this is CUSTOMER_MANAGED, you must manage those roles and permissions yourself.
|
|
59
|
+
|
|
60
|
+
* If you are working with a workspace in a member account of an organization and that account is
|
|
61
|
+
* not a delegated administrator account, and you want the workspace to access data sources in
|
|
62
|
+
* other AWS accounts in the organization, this parameter must be set to CUSTOMER_MANAGED.
|
|
63
|
+
*/
|
|
64
|
+
var PermissionTypes;
|
|
65
|
+
(function (PermissionTypes) {
|
|
66
|
+
/**
|
|
67
|
+
* Customer-managed permissions where you manage user access to Grafana.
|
|
68
|
+
*/
|
|
69
|
+
PermissionTypes["CUSTOMER_MANAGED"] = "CUSTOMER_MANAGED";
|
|
70
|
+
/**
|
|
71
|
+
* Service-managed permissions where AWS manages user access to Grafana.
|
|
72
|
+
*/
|
|
73
|
+
PermissionTypes["SERVICE_MANAGED"] = "SERVICE_MANAGED";
|
|
74
|
+
})(PermissionTypes || (exports.PermissionTypes = PermissionTypes = {}));
|
|
75
|
+
/**
|
|
76
|
+
* Status of SAML configuration for a Grafana workspace.
|
|
77
|
+
*/
|
|
78
|
+
var SamlConfigurationStatuses;
|
|
79
|
+
(function (SamlConfigurationStatuses) {
|
|
80
|
+
/**
|
|
81
|
+
* SAML is configured for the workspace.
|
|
82
|
+
*/
|
|
83
|
+
SamlConfigurationStatuses["CONFIGURED"] = "CONFIGURED";
|
|
84
|
+
/**
|
|
85
|
+
* SAML is not configured for the workspace.
|
|
86
|
+
*/
|
|
87
|
+
SamlConfigurationStatuses["NOT_CONFIGURED"] = "NOT_CONFIGURED";
|
|
88
|
+
})(SamlConfigurationStatuses || (exports.SamlConfigurationStatuses = SamlConfigurationStatuses = {}));
|
|
89
|
+
/**
|
|
90
|
+
* Status of a Grafana workspace.
|
|
91
|
+
*/
|
|
92
|
+
var Status;
|
|
93
|
+
(function (Status) {
|
|
94
|
+
/**
|
|
95
|
+
* Workspace is active and ready to use.
|
|
96
|
+
*/
|
|
97
|
+
Status["ACTIVE"] = "ACTIVE";
|
|
98
|
+
/**
|
|
99
|
+
* Workspace is being created.
|
|
100
|
+
*/
|
|
101
|
+
Status["CREATING"] = "CREATING";
|
|
102
|
+
/**
|
|
103
|
+
* Workspace is being deleted.
|
|
104
|
+
*/
|
|
105
|
+
Status["DELETING"] = "DELETING";
|
|
106
|
+
/**
|
|
107
|
+
* Workspace operation has failed.
|
|
108
|
+
*/
|
|
109
|
+
Status["FAILED"] = "FAILED";
|
|
110
|
+
/**
|
|
111
|
+
* Workspace is being updated.
|
|
112
|
+
*/
|
|
113
|
+
Status["UPDATING"] = "UPDATING";
|
|
114
|
+
/**
|
|
115
|
+
* Workspace is being upgraded.
|
|
116
|
+
*/
|
|
117
|
+
Status["UPGRADING"] = "UPGRADING";
|
|
118
|
+
/**
|
|
119
|
+
* Workspace deletion has failed.
|
|
120
|
+
*/
|
|
121
|
+
Status["DELETION_FAILED"] = "DELETION_FAILED";
|
|
122
|
+
/**
|
|
123
|
+
* Workspace creation has failed.
|
|
124
|
+
*/
|
|
125
|
+
Status["CREATION_FAILED"] = "CREATION_FAILED";
|
|
126
|
+
/**
|
|
127
|
+
* Workspace update has failed.
|
|
128
|
+
*/
|
|
129
|
+
Status["UPDATE_FAILED"] = "UPDATE_FAILED";
|
|
130
|
+
/**
|
|
131
|
+
* Workspace upgrade has failed.
|
|
132
|
+
*/
|
|
133
|
+
Status["UPGRADE_FAILED"] = "UPGRADE_FAILED";
|
|
134
|
+
/**
|
|
135
|
+
* License removal has failed.
|
|
136
|
+
*/
|
|
137
|
+
Status["LICENSE_REMOVAL_FAILED"] = "LICENSE_REMOVAL_FAILED";
|
|
138
|
+
})(Status || (exports.Status = Status = {}));
|
|
139
|
+
/**
|
|
140
|
+
* Represents an Amazon Managed Grafana workspace.
|
|
141
|
+
*
|
|
142
|
+
* This class provides a high-level abstraction for creating and managing
|
|
143
|
+
* Amazon Managed Grafana workspaces using AWS CDK.
|
|
144
|
+
*/
|
|
145
|
+
class Workspace extends constructs_1.Construct {
|
|
146
|
+
/**
|
|
147
|
+
* Validates the clientToken property.
|
|
148
|
+
*
|
|
149
|
+
* @param token - The client token to validate
|
|
150
|
+
* @returns An array of error messages if validation fails, or an empty array if valid
|
|
151
|
+
*
|
|
152
|
+
* Validation rules:
|
|
153
|
+
* - Must be a string
|
|
154
|
+
* - Must be between 1 and 64 characters long
|
|
155
|
+
* - Must contain only printable ASCII characters
|
|
156
|
+
*/
|
|
157
|
+
static validateClientToken(token) {
|
|
158
|
+
const errors = [];
|
|
159
|
+
if (token === undefined) {
|
|
160
|
+
return errors; // Optional property can be undefined
|
|
161
|
+
}
|
|
162
|
+
if (typeof token !== 'string') {
|
|
163
|
+
errors.push('clientToken must be a string');
|
|
164
|
+
return errors; // No need to check further if not a string
|
|
165
|
+
}
|
|
166
|
+
const regex = /^[!-~]{1,64}$/;
|
|
167
|
+
if (!regex.test(token)) {
|
|
168
|
+
if (token.length < 1 || token.length > 64) {
|
|
169
|
+
errors.push('clientToken must be between 1 and 64 characters long');
|
|
170
|
+
}
|
|
171
|
+
if (!/^[!-~]*$/.test(token)) {
|
|
172
|
+
errors.push('clientToken must contain only printable ASCII characters');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return errors;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Validates the description property.
|
|
179
|
+
*
|
|
180
|
+
* @param description - The description to validate
|
|
181
|
+
* @returns An array of error messages if validation fails, or an empty array if valid
|
|
182
|
+
*
|
|
183
|
+
* Validation rules:
|
|
184
|
+
* - Must be a string
|
|
185
|
+
* - Maximum length of 2048 characters
|
|
186
|
+
*/
|
|
187
|
+
static validateDescription(description) {
|
|
188
|
+
const errors = [];
|
|
189
|
+
if (description === undefined) {
|
|
190
|
+
return errors; // Optional property can be undefined
|
|
191
|
+
}
|
|
192
|
+
if (typeof description !== 'string') {
|
|
193
|
+
errors.push('description must be a string');
|
|
194
|
+
return errors; // No need to check further if not a string
|
|
195
|
+
}
|
|
196
|
+
if (description.length > 2048) {
|
|
197
|
+
errors.push('description cannot exceed 2048 characters');
|
|
198
|
+
}
|
|
199
|
+
return errors;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Validates the grafanaVersion property.
|
|
203
|
+
*
|
|
204
|
+
* @param version - The Grafana version to validate
|
|
205
|
+
* @returns An array of error messages if validation fails, or an empty array if valid
|
|
206
|
+
*
|
|
207
|
+
* Validation rules:
|
|
208
|
+
* - Must be a string
|
|
209
|
+
* - Must be between 1 and 255 characters long
|
|
210
|
+
*/
|
|
211
|
+
static validateGrafanaVersion(version) {
|
|
212
|
+
const errors = [];
|
|
213
|
+
if (version === undefined) {
|
|
214
|
+
return errors; // Optional property can be undefined
|
|
215
|
+
}
|
|
216
|
+
if (typeof version !== 'string') {
|
|
217
|
+
errors.push('grafanaVersion must be a string');
|
|
218
|
+
return errors; // No need to check further if not a string
|
|
219
|
+
}
|
|
220
|
+
if (version.length < 1) {
|
|
221
|
+
errors.push('grafanaVersion cannot be empty');
|
|
222
|
+
}
|
|
223
|
+
if (version.length > 255) {
|
|
224
|
+
errors.push('grafanaVersion cannot exceed 255 characters');
|
|
225
|
+
}
|
|
226
|
+
return errors;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Validates the name property.
|
|
230
|
+
*
|
|
231
|
+
* @param name - The workspace name to validate
|
|
232
|
+
* @returns An array of error messages if validation fails, or an empty array if valid
|
|
233
|
+
*
|
|
234
|
+
* Validation rules:
|
|
235
|
+
* - Must be a string
|
|
236
|
+
* - Must be between 1 and 255 characters long
|
|
237
|
+
* - Can only contain alphanumeric characters, hyphens, dots, underscores, and tildes
|
|
238
|
+
*/
|
|
239
|
+
static validateName(name) {
|
|
240
|
+
const errors = [];
|
|
241
|
+
if (name === undefined) {
|
|
242
|
+
return errors; // Optional property can be undefined
|
|
243
|
+
}
|
|
244
|
+
if (typeof name !== 'string') {
|
|
245
|
+
errors.push('name must be a string');
|
|
246
|
+
return errors; // No need to check further if not a string
|
|
247
|
+
}
|
|
248
|
+
const regex = /^[a-zA-Z0-9\-._~]{1,255}$/;
|
|
249
|
+
if (!regex.test(name)) {
|
|
250
|
+
if (name.length < 1 || name.length > 255) {
|
|
251
|
+
errors.push('name must be between 1 and 255 characters long');
|
|
252
|
+
}
|
|
253
|
+
if (!/^[a-zA-Z0-9\-._~]*$/.test(name)) {
|
|
254
|
+
errors.push('name can only contain alphanumeric characters, hyphens, dots, underscores, and tildes');
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return errors;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Validates the networkAccessControl property.
|
|
261
|
+
*
|
|
262
|
+
* @param nac - The network access control configuration to validate
|
|
263
|
+
* @returns An array of error messages if validation fails, or an empty array if valid
|
|
264
|
+
*
|
|
265
|
+
* Validation rules:
|
|
266
|
+
* - Must be an object
|
|
267
|
+
* - prefixLists (if present) must be an array with at most 5 items
|
|
268
|
+
* - vpcEndpoints (if present) must be an array with at most 5 items
|
|
269
|
+
*/
|
|
270
|
+
static validateNetworkAccessControl(nac) {
|
|
271
|
+
const errors = [];
|
|
272
|
+
if (nac === undefined) {
|
|
273
|
+
return errors; // Optional property can be undefined
|
|
274
|
+
}
|
|
275
|
+
if (!nac || typeof nac !== 'object') {
|
|
276
|
+
errors.push('networkAccessControl must be an object');
|
|
277
|
+
return errors;
|
|
278
|
+
}
|
|
279
|
+
const networkAccessControl = nac;
|
|
280
|
+
// Check prefixLists if present
|
|
281
|
+
if (networkAccessControl.prefixLists !== undefined) {
|
|
282
|
+
if (!Array.isArray(networkAccessControl.prefixLists)) {
|
|
283
|
+
errors.push('prefixLists must be an array');
|
|
284
|
+
}
|
|
285
|
+
else if (networkAccessControl.prefixLists.length > 5) {
|
|
286
|
+
errors.push('prefixLists can have at most 5 items');
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// Check vpcEndpoints if present
|
|
290
|
+
if (networkAccessControl.vpcEndpoints !== undefined) {
|
|
291
|
+
if (!Array.isArray(networkAccessControl.vpcEndpoints)) {
|
|
292
|
+
errors.push('vpcEndpoints must be an array');
|
|
293
|
+
}
|
|
294
|
+
else if (networkAccessControl.vpcEndpoints.length > 5) {
|
|
295
|
+
errors.push('vpcEndpoints can have at most 5 items');
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return errors;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Validates the organizationRoleName property.
|
|
302
|
+
*
|
|
303
|
+
* @param roleName - The organization role name to validate
|
|
304
|
+
* @returns An array of error messages if validation fails, or an empty array if valid
|
|
305
|
+
*
|
|
306
|
+
* Validation rules:
|
|
307
|
+
* - Must be a string
|
|
308
|
+
* - Must be between 1 and 2048 characters long
|
|
309
|
+
*/
|
|
310
|
+
static validateOrganizationRoleName(roleName) {
|
|
311
|
+
const errors = [];
|
|
312
|
+
if (roleName === undefined) {
|
|
313
|
+
return errors; // Optional property can be undefined
|
|
314
|
+
}
|
|
315
|
+
if (typeof roleName !== 'string') {
|
|
316
|
+
errors.push('organizationRoleName must be a string');
|
|
317
|
+
return errors; // No need to check further if not a string
|
|
318
|
+
}
|
|
319
|
+
if (roleName.length < 1) {
|
|
320
|
+
errors.push('organizationRoleName cannot be empty');
|
|
321
|
+
}
|
|
322
|
+
if (roleName.length > 2048) {
|
|
323
|
+
errors.push('organizationRoleName cannot exceed 2048 characters');
|
|
324
|
+
}
|
|
325
|
+
return errors;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Validates the SAML assertion attributes.
|
|
329
|
+
*
|
|
330
|
+
* @param obj - The SAML assertion attributes to validate
|
|
331
|
+
* @returns An array of error messages if validation fails, or an empty array if valid
|
|
332
|
+
*
|
|
333
|
+
* Validation rules:
|
|
334
|
+
* - Must be an object
|
|
335
|
+
* - Each attribute must be a string
|
|
336
|
+
* - Each attribute must be between 1 and 256 characters long
|
|
337
|
+
* - Valid attribute keys are: 'email', 'groups', 'login', 'name', 'org', 'role'
|
|
338
|
+
*/
|
|
339
|
+
static validateSamlAssertionAttributes(obj) {
|
|
340
|
+
const errors = [];
|
|
341
|
+
if (!obj || typeof obj !== 'object') {
|
|
342
|
+
return ['Input is not an object'];
|
|
343
|
+
}
|
|
344
|
+
const attributes = obj;
|
|
345
|
+
for (const key in attributes) {
|
|
346
|
+
const value = attributes[key];
|
|
347
|
+
if (value === undefined) {
|
|
348
|
+
continue; // Optional properties can be undefined
|
|
349
|
+
}
|
|
350
|
+
if (typeof value !== 'string') {
|
|
351
|
+
errors.push(`Property '${key}' must be a string`);
|
|
352
|
+
}
|
|
353
|
+
else if (value.length < 1) {
|
|
354
|
+
errors.push(`Property '${key}' cannot be empty`);
|
|
355
|
+
}
|
|
356
|
+
else if (value.length > 256) {
|
|
357
|
+
errors.push(`Property '${key}' exceeds maximum length of 256 characters`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return errors;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Validates the SAML IdP metadata.
|
|
364
|
+
*
|
|
365
|
+
* @param obj - The SAML IdP metadata to validate
|
|
366
|
+
* @returns An array of error messages if validation fails, or an empty array if valid
|
|
367
|
+
*
|
|
368
|
+
* Validation rules:
|
|
369
|
+
* - Must be an object
|
|
370
|
+
* - url (if present) must be a string between 1 and 2048 characters long
|
|
371
|
+
* - xml (if present) must be a string
|
|
372
|
+
*/
|
|
373
|
+
static validateSamlIdpMetadata(obj) {
|
|
374
|
+
const errors = [];
|
|
375
|
+
if (!obj || typeof obj !== 'object') {
|
|
376
|
+
return ['Input is not an object'];
|
|
377
|
+
}
|
|
378
|
+
const metadata = obj;
|
|
379
|
+
// Check url property if present
|
|
380
|
+
if (metadata.url !== undefined) {
|
|
381
|
+
if (typeof metadata.url !== 'string') {
|
|
382
|
+
errors.push("Property 'url' must be a string");
|
|
383
|
+
}
|
|
384
|
+
else if (metadata.url.length < 1) {
|
|
385
|
+
errors.push("Property 'url' cannot be empty");
|
|
386
|
+
}
|
|
387
|
+
else if (metadata.url.length > 2048) {
|
|
388
|
+
errors.push("Property 'url' exceeds maximum length of 2048 characters");
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
// Check xml property if present
|
|
392
|
+
if (metadata.xml !== undefined && typeof metadata.xml !== 'string') {
|
|
393
|
+
errors.push("Property 'xml' must be a string");
|
|
394
|
+
}
|
|
395
|
+
return errors;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Validates the SAML configuration.
|
|
399
|
+
*
|
|
400
|
+
* @param config - The SAML configuration to validate
|
|
401
|
+
* @returns An array of error messages if validation fails, or an empty array if valid
|
|
402
|
+
*
|
|
403
|
+
* Validation rules:
|
|
404
|
+
* - Must be an object
|
|
405
|
+
* - idpMetadata is required and must be valid
|
|
406
|
+
* - assertionAtrributes (if present) must be valid
|
|
407
|
+
* - allowedOrganizations (if present) must be an array of strings with 1-256 elements
|
|
408
|
+
* - loginValidityDuration (if present) must be a positive number
|
|
409
|
+
* - roleValues (if present) must be an object with valid admin and editor arrays
|
|
410
|
+
*/
|
|
411
|
+
static validateSamlConfiguration(config) {
|
|
412
|
+
const errors = [];
|
|
413
|
+
if (config === undefined) {
|
|
414
|
+
return errors; // Optional property can be undefined
|
|
415
|
+
}
|
|
416
|
+
if (!config || typeof config !== 'object') {
|
|
417
|
+
errors.push('samlConfiguration must be an object');
|
|
418
|
+
return errors;
|
|
419
|
+
}
|
|
420
|
+
const samlConfig = config;
|
|
421
|
+
// Check idpMetadata (required)
|
|
422
|
+
if (samlConfig.idpMetadata === undefined) {
|
|
423
|
+
errors.push('idpMetadata is required in samlConfiguration');
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
const idpMetadataErrors = Workspace.validateSamlIdpMetadata(samlConfig.idpMetadata);
|
|
427
|
+
if (idpMetadataErrors.length > 0) {
|
|
428
|
+
errors.push(...idpMetadataErrors.map((err) => `idpMetadata: ${err}`));
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
// Check assertionAtrributes if present
|
|
432
|
+
if (samlConfig.assertionAtrributes !== undefined) {
|
|
433
|
+
const attributeErrors = Workspace.validateSamlAssertionAttributes(samlConfig.assertionAtrributes);
|
|
434
|
+
if (attributeErrors.length > 0) {
|
|
435
|
+
errors.push(...attributeErrors.map((err) => `assertionAtrributes: ${err}`));
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
// Check allowedOrganizations if present
|
|
439
|
+
if (samlConfig.allowedOrganizations !== undefined) {
|
|
440
|
+
if (!Array.isArray(samlConfig.allowedOrganizations)) {
|
|
441
|
+
errors.push('allowedOrganizations must be an array');
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
if (samlConfig.allowedOrganizations.length < 1) {
|
|
445
|
+
errors.push('allowedOrganizations must have at least 1 element');
|
|
446
|
+
}
|
|
447
|
+
if (samlConfig.allowedOrganizations.length > 256) {
|
|
448
|
+
errors.push('allowedOrganizations cannot have more than 256 elements');
|
|
449
|
+
}
|
|
450
|
+
for (let i = 0; i < samlConfig.allowedOrganizations.length; i++) {
|
|
451
|
+
const org = samlConfig.allowedOrganizations[i];
|
|
452
|
+
if (typeof org !== 'string') {
|
|
453
|
+
errors.push(`allowedOrganizations[${i}] must be a string`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
// Check loginValidityDuration if present
|
|
459
|
+
if (samlConfig.loginValidityDuration !== undefined) {
|
|
460
|
+
if (typeof samlConfig.loginValidityDuration !== 'number') {
|
|
461
|
+
errors.push('loginValidityDuration must be a number');
|
|
462
|
+
}
|
|
463
|
+
else if (samlConfig.loginValidityDuration <= 0) {
|
|
464
|
+
errors.push('loginValidityDuration must be positive');
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
// Check roleValues if present
|
|
468
|
+
if (samlConfig.roleValues !== undefined) {
|
|
469
|
+
if (!samlConfig.roleValues || typeof samlConfig.roleValues !== 'object') {
|
|
470
|
+
errors.push('roleValues must be an object');
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
// Check admin array if present
|
|
474
|
+
if (samlConfig.roleValues.admin !== undefined) {
|
|
475
|
+
if (!Array.isArray(samlConfig.roleValues.admin)) {
|
|
476
|
+
errors.push('roleValues.admin must be an array');
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
for (let i = 0; i < samlConfig.roleValues.admin.length; i++) {
|
|
480
|
+
if (typeof samlConfig.roleValues.admin[i] !== 'string') {
|
|
481
|
+
errors.push(`roleValues.admin[${i}] must be a string`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
// Check editor array if present
|
|
487
|
+
if (samlConfig.roleValues.editor !== undefined) {
|
|
488
|
+
if (!Array.isArray(samlConfig.roleValues.editor)) {
|
|
489
|
+
errors.push('roleValues.editor must be an array');
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
for (let i = 0; i < samlConfig.roleValues.editor.length; i++) {
|
|
493
|
+
if (typeof samlConfig.roleValues.editor[i] !== 'string') {
|
|
494
|
+
errors.push(`roleValues.editor[${i}] must be a string`);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return errors;
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Validates the vpcConfiguration property.
|
|
505
|
+
*
|
|
506
|
+
* @param config - The VPC configuration to validate
|
|
507
|
+
* @returns An array of error messages if validation fails, or an empty array if valid
|
|
508
|
+
*
|
|
509
|
+
* Validation rules:
|
|
510
|
+
* - Must be an object
|
|
511
|
+
* - securityGroups is required and must be an array with 1-5 items
|
|
512
|
+
* - subnets is required and must be an array with 2-6 items
|
|
513
|
+
*/
|
|
514
|
+
static validateVpcConfiguration(config) {
|
|
515
|
+
const errors = [];
|
|
516
|
+
if (config === undefined) {
|
|
517
|
+
return errors; // Optional property can be undefined
|
|
518
|
+
}
|
|
519
|
+
if (!config || typeof config !== 'object') {
|
|
520
|
+
errors.push('vpcConfiguration must be an object');
|
|
521
|
+
return errors;
|
|
522
|
+
}
|
|
523
|
+
const vpcConfig = config;
|
|
524
|
+
// Check securityGroups (required)
|
|
525
|
+
if (vpcConfig.securityGroups === undefined) {
|
|
526
|
+
errors.push('securityGroups is required in vpcConfiguration');
|
|
527
|
+
}
|
|
528
|
+
else if (!Array.isArray(vpcConfig.securityGroups)) {
|
|
529
|
+
errors.push('securityGroups must be an array');
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
if (vpcConfig.securityGroups.length < 1) {
|
|
533
|
+
errors.push('securityGroups must have at least 1 item');
|
|
534
|
+
}
|
|
535
|
+
if (vpcConfig.securityGroups.length > 5) {
|
|
536
|
+
errors.push('securityGroups cannot have more than 5 items');
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
// Check subnets (required)
|
|
540
|
+
if (vpcConfig.subnets === undefined) {
|
|
541
|
+
errors.push('subnets is required in vpcConfiguration');
|
|
542
|
+
}
|
|
543
|
+
else if (!Array.isArray(vpcConfig.subnets)) {
|
|
544
|
+
errors.push('subnets must be an array');
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
if (vpcConfig.subnets.length < 2) {
|
|
548
|
+
errors.push('subnets must have at least 2 items');
|
|
549
|
+
}
|
|
550
|
+
if (vpcConfig.subnets.length > 6) {
|
|
551
|
+
errors.push('subnets cannot have more than 6 items');
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
return errors;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Validates all workspace properties.
|
|
558
|
+
*
|
|
559
|
+
* @param props - The workspace properties to validate
|
|
560
|
+
* @returns An array of error messages if validation fails, or an empty array if valid
|
|
561
|
+
*
|
|
562
|
+
* This method aggregates validation results from all individual property validators.
|
|
563
|
+
* It throws an error if props is not an object.
|
|
564
|
+
*/
|
|
565
|
+
static validateProps(props) {
|
|
566
|
+
const errors = [];
|
|
567
|
+
if (!props || typeof props !== 'object') {
|
|
568
|
+
throw new Error('Props is not an object');
|
|
569
|
+
}
|
|
570
|
+
const workspaceProps = props;
|
|
571
|
+
if (workspaceProps.clientToken !== undefined) {
|
|
572
|
+
const clientTokenErrors = Workspace.validateClientToken(workspaceProps.clientToken);
|
|
573
|
+
if (clientTokenErrors.length > 0) {
|
|
574
|
+
errors.push(...clientTokenErrors.map((err) => `clientToken: ${err}`));
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
if (workspaceProps.description !== undefined) {
|
|
578
|
+
const descriptionErrors = Workspace.validateDescription(workspaceProps.description);
|
|
579
|
+
if (descriptionErrors.length > 0) {
|
|
580
|
+
errors.push(...descriptionErrors.map((err) => `description: ${err}`));
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
if (workspaceProps.grafanaVersion !== undefined) {
|
|
584
|
+
const grafanaVersionErrors = Workspace.validateGrafanaVersion(workspaceProps.grafanaVersion);
|
|
585
|
+
if (grafanaVersionErrors.length > 0) {
|
|
586
|
+
errors.push(...grafanaVersionErrors.map((err) => `grafanaVersion: ${err}`));
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
if (workspaceProps.name !== undefined) {
|
|
590
|
+
const nameErrors = Workspace.validateName(workspaceProps.name);
|
|
591
|
+
if (nameErrors.length > 0) {
|
|
592
|
+
errors.push(...nameErrors.map((err) => `name: ${err}`));
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
if (workspaceProps.networkAccessControl !== undefined) {
|
|
596
|
+
const networkAccessControlErrors = Workspace.validateNetworkAccessControl(workspaceProps.networkAccessControl);
|
|
597
|
+
if (networkAccessControlErrors.length > 0) {
|
|
598
|
+
errors.push(...networkAccessControlErrors.map((err) => `networkAccessControl: ${err}`));
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
if (workspaceProps.organizationRoleName !== undefined) {
|
|
602
|
+
const organizationRoleNameErrors = Workspace.validateOrganizationRoleName(workspaceProps.organizationRoleName);
|
|
603
|
+
if (organizationRoleNameErrors.length > 0) {
|
|
604
|
+
errors.push(...organizationRoleNameErrors.map((err) => `organizationRoleName: ${err}`));
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
if (workspaceProps.samlConfiguration !== undefined) {
|
|
608
|
+
const samlConfigurationErrors = Workspace.validateSamlConfiguration(workspaceProps.samlConfiguration);
|
|
609
|
+
if (samlConfigurationErrors.length > 0) {
|
|
610
|
+
errors.push(...samlConfigurationErrors.map((err) => `samlConfiguration: ${err}`));
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
if (workspaceProps.vpcConfiguration !== undefined) {
|
|
614
|
+
const vpcConfigurationErrors = Workspace.validateVpcConfiguration(workspaceProps.vpcConfiguration);
|
|
615
|
+
if (vpcConfigurationErrors.length > 0) {
|
|
616
|
+
errors.push(...vpcConfigurationErrors.map((err) => `vpcConfiguration: ${err}`));
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
return errors;
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Creates a new Amazon Managed Grafana workspace.
|
|
623
|
+
*
|
|
624
|
+
* @param scope - The scope in which to define this construct
|
|
625
|
+
* @param id - The scoped construct ID
|
|
626
|
+
* @param props - Configuration properties for the workspace
|
|
627
|
+
*
|
|
628
|
+
* @throws Error if any of the provided properties fail validation
|
|
629
|
+
*/
|
|
630
|
+
constructor(scope, id, props) {
|
|
631
|
+
super(scope, id);
|
|
632
|
+
const errors = Workspace.validateProps(props);
|
|
633
|
+
if (errors.length > 0) {
|
|
634
|
+
throw new Error(`Invalid props:\n${errors.join('\n')}`);
|
|
635
|
+
}
|
|
636
|
+
if (props.accountAccessType === AccountAccessType.CURRENT_ACCOUNT &&
|
|
637
|
+
!props.role) {
|
|
638
|
+
throw new Error('Role must be provided when accountAccessType is CURRENT_ACCOUNT');
|
|
639
|
+
}
|
|
640
|
+
this.accountAccessType = props.accountAccessType;
|
|
641
|
+
this.authenticationProviders = props.authenticationProviders;
|
|
642
|
+
this.clientToken = props.clientToken;
|
|
643
|
+
this.dataSources = props.dataSources;
|
|
644
|
+
this.description = props.description;
|
|
645
|
+
this.networkAccessControl = props.networkAccessControl;
|
|
646
|
+
this.notificationDestinations = props.notificationDestinations;
|
|
647
|
+
this.organizationalUnits = props.organizationalUnits;
|
|
648
|
+
this.organizationRoleName = props.organizationRoleName;
|
|
649
|
+
this.permissionType = props.permissionType;
|
|
650
|
+
this.pluginAdminEnabled = props.pluginAdminEnabled;
|
|
651
|
+
this.name = props.name;
|
|
652
|
+
this.role = props.role;
|
|
653
|
+
this.samlConfiguration = props.samlConfiguration;
|
|
654
|
+
this.stackSetName = props.stackSetName;
|
|
655
|
+
this.vpcConfiguration = props.vpcConfiguration;
|
|
656
|
+
let cfnWorkspaceProps = {
|
|
657
|
+
accountAccessType: props.accountAccessType,
|
|
658
|
+
authenticationProviders: props.authenticationProviders,
|
|
659
|
+
clientToken: props.clientToken,
|
|
660
|
+
dataSources: props.dataSources,
|
|
661
|
+
description: props.description,
|
|
662
|
+
grafanaVersion: props.grafanaVersion,
|
|
663
|
+
name: props.name,
|
|
664
|
+
notificationDestinations: props.notificationDestinations,
|
|
665
|
+
organizationalUnits: props.organizationalUnits,
|
|
666
|
+
organizationRoleName: props.organizationRoleName,
|
|
667
|
+
permissionType: props.permissionType,
|
|
668
|
+
pluginAdminEnabled: props.pluginAdminEnabled,
|
|
669
|
+
roleArn: props.role?.roleArn,
|
|
670
|
+
samlConfiguration: props.samlConfiguration,
|
|
671
|
+
stackSetName: props.stackSetName,
|
|
672
|
+
vpcConfiguration: props.vpcConfiguration
|
|
673
|
+
? {
|
|
674
|
+
securityGroupIds: props.vpcConfiguration.securityGroups.map((sg) => sg.securityGroupId),
|
|
675
|
+
subnetIds: props.vpcConfiguration.subnets.map((subnet) => subnet.subnetId),
|
|
676
|
+
}
|
|
677
|
+
: undefined,
|
|
678
|
+
};
|
|
679
|
+
this.workspace = new aws_grafana_1.CfnWorkspace(this, 'Resource', cfnWorkspaceProps);
|
|
680
|
+
this.creationTimestamp = this.workspace.attrCreationTimestamp;
|
|
681
|
+
this.endpoint = this.workspace.attrEndpoint;
|
|
682
|
+
this.grafanaVersion = this.workspace.attrGrafanaVersion;
|
|
683
|
+
this.id = this.workspace.attrId;
|
|
684
|
+
this.modificationTimestamp = this.workspace.attrModificationTimestamp;
|
|
685
|
+
this.samlConfigurationStatus = this.workspace
|
|
686
|
+
.attrSamlConfigurationStatus;
|
|
687
|
+
this.ssoClientId = this.workspace.attrSsoClientId;
|
|
688
|
+
this.status = this.workspace.attrStatus;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
exports.Workspace = Workspace;
|
|
692
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
693
|
+
Workspace[_a] = { fqn: "@robhan-cdk-lib/aws_grafana.Workspace", version: "0.0.0" };
|
|
694
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya3NwYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dvcmtzcGFjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQU1BLHlEQUEwRTtBQUUxRSwyQ0FBdUM7QUFFdkM7Ozs7O0dBS0c7QUFDSCxJQUFZLGlCQVVYO0FBVkQsV0FBWSxpQkFBaUI7SUFDM0I7O09BRUc7SUFDSCx3REFBbUMsQ0FBQTtJQUVuQzs7T0FFRztJQUNILGtEQUE2QixDQUFBO0FBQy9CLENBQUMsRUFWVyxpQkFBaUIsaUNBQWpCLGlCQUFpQixRQVU1QjtBQUVEOzs7OztHQUtHO0FBQ0gsSUFBWSx1QkFVWDtBQVZELFdBQVksdUJBQXVCO0lBQ2pDOztPQUVHO0lBQ0gsOENBQW1CLENBQUE7SUFFbkI7O09BRUc7SUFDSCx3Q0FBYSxDQUFBO0FBQ2YsQ0FBQyxFQVZXLHVCQUF1Qix1Q0FBdkIsdUJBQXVCLFFBVWxDO0FBMkJEOzs7R0FHRztBQUNILElBQVksd0JBS1g7QUFMRCxXQUFZLHdCQUF3QjtJQUNsQzs7T0FFRztJQUNILHVDQUFXLENBQUE7QUFDYixDQUFDLEVBTFcsd0JBQXdCLHdDQUF4Qix3QkFBd0IsUUFLbkM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsSUFBWSxlQVVYO0FBVkQsV0FBWSxlQUFlO0lBQ3pCOztPQUVHO0lBQ0gsd0RBQXFDLENBQUE7SUFFckM7O09BRUc7SUFDSCxzREFBbUMsQ0FBQTtBQUNyQyxDQUFDLEVBVlcsZUFBZSwrQkFBZixlQUFlLFFBVTFCO0FBK1BEOztHQUVHO0FBQ0gsSUFBWSx5QkFVWDtBQVZELFdBQVkseUJBQXlCO0lBQ25DOztPQUVHO0lBQ0gsc0RBQXlCLENBQUE7SUFFekI7O09BRUc7SUFDSCw4REFBaUMsQ0FBQTtBQUNuQyxDQUFDLEVBVlcseUJBQXlCLHlDQUF6Qix5QkFBeUIsUUFVcEM7QUFFRDs7R0FFRztBQUNILElBQVksTUF1RFg7QUF2REQsV0FBWSxNQUFNO0lBQ2hCOztPQUVHO0lBQ0gsMkJBQWlCLENBQUE7SUFFakI7O09BRUc7SUFDSCwrQkFBcUIsQ0FBQTtJQUVyQjs7T0FFRztJQUNILCtCQUFxQixDQUFBO0lBRXJCOztPQUVHO0lBQ0gsMkJBQWlCLENBQUE7SUFFakI7O09BRUc7SUFDSCwrQkFBcUIsQ0FBQTtJQUVyQjs7T0FFRztJQUNILGlDQUF1QixDQUFBO0lBRXZCOztPQUVHO0lBQ0gsNkNBQW1DLENBQUE7SUFFbkM7O09BRUc7SUFDSCw2Q0FBbUMsQ0FBQTtJQUVuQzs7T0FFRztJQUNILHlDQUErQixDQUFBO0lBRS9COztPQUVHO0lBQ0gsMkNBQWlDLENBQUE7SUFFakM7O09BRUc7SUFDSCwyREFBaUQsQ0FBQTtBQUNuRCxDQUFDLEVBdkRXLE1BQU0sc0JBQU4sTUFBTSxRQXVEakI7QUFFRDs7Ozs7R0FLRztBQUNILE1BQWEsU0FBVSxTQUFRLHNCQUFTO0lBQ3RDOzs7Ozs7Ozs7O09BVUc7SUFDSyxNQUFNLENBQUMsbUJBQW1CLENBQUMsS0FBYztRQUMvQyxNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7UUFFNUIsSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDeEIsT0FBTyxNQUFNLENBQUMsQ0FBQyxxQ0FBcUM7UUFDdEQsQ0FBQztRQUVELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDOUIsTUFBTSxDQUFDLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1lBQzVDLE9BQU8sTUFBTSxDQUFDLENBQUMsMkNBQTJDO1FBQzVELENBQUM7UUFFRCxNQUFNLEtBQUssR0FBRyxlQUFlLENBQUM7UUFDOUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN2QixJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUM7Z0JBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0RBQXNELENBQUMsQ0FBQztZQUN0RSxDQUFDO1lBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDNUIsTUFBTSxDQUFDLElBQUksQ0FBQywwREFBMEQsQ0FBQyxDQUFDO1lBQzFFLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNLLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxXQUFvQjtRQUNyRCxNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7UUFFNUIsSUFBSSxXQUFXLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDOUIsT0FBTyxNQUFNLENBQUMsQ0FBQyxxQ0FBcUM7UUFDdEQsQ0FBQztRQUVELElBQUksT0FBTyxXQUFXLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDcEMsTUFBTSxDQUFDLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1lBQzVDLE9BQU8sTUFBTSxDQUFDLENBQUMsMkNBQTJDO1FBQzVELENBQUM7UUFFRCxJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxFQUFFLENBQUM7WUFDOUIsTUFBTSxDQUFDLElBQUksQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO1FBQzNELENBQUM7UUFFRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ssTUFBTSxDQUFDLHNCQUFzQixDQUFDLE9BQWdCO1FBQ3BELE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUU1QixJQUFJLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMxQixPQUFPLE1BQU0sQ0FBQyxDQUFDLHFDQUFxQztRQUN0RCxDQUFDO1FBRUQsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNoQyxNQUFNLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7WUFDL0MsT0FBTyxNQUFNLENBQUMsQ0FBQywyQ0FBMkM7UUFDNUQsQ0FBQztRQUVELElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2QixNQUFNLENBQUMsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUVELElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQztZQUN6QixNQUFNLENBQUMsSUFBSSxDQUFDLDZDQUE2QyxDQUFDLENBQUM7UUFDN0QsQ0FBQztRQUVELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ssTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFhO1FBQ3ZDLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUU1QixJQUFJLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN2QixPQUFPLE1BQU0sQ0FBQyxDQUFDLHFDQUFxQztRQUN0RCxDQUFDO1FBRUQsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUM3QixNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7WUFDckMsT0FBTyxNQUFNLENBQUMsQ0FBQywyQ0FBMkM7UUFDNUQsQ0FBQztRQUVELE1BQU0sS0FBSyxHQUFHLDJCQUEyQixDQUFDO1FBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDdEIsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO2dCQUN6QyxNQUFNLENBQUMsSUFBSSxDQUFDLGdEQUFnRCxDQUFDLENBQUM7WUFDaEUsQ0FBQztZQUVELElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDdEMsTUFBTSxDQUFDLElBQUksQ0FDVCx1RkFBdUYsQ0FDeEYsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSyxNQUFNLENBQUMsNEJBQTRCLENBQUMsR0FBWTtRQUN0RCxNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7UUFFNUIsSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDdEIsT0FBTyxNQUFNLENBQUMsQ0FBQyxxQ0FBcUM7UUFDdEQsQ0FBQztRQUVELElBQUksQ0FBQyxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDcEMsTUFBTSxDQUFDLElBQUksQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1lBQ3RELE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUM7UUFFRCxNQUFNLG9CQUFvQixHQUFHLEdBQTJCLENBQUM7UUFFekQsK0JBQStCO1FBQy9CLElBQUksb0JBQW9CLENBQUMsV0FBVyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ25ELElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3JELE1BQU0sQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsQ0FBQztZQUM5QyxDQUFDO2lCQUFNLElBQUksb0JBQW9CLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDdkQsTUFBTSxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1lBQ3RELENBQUM7UUFDSCxDQUFDO1FBRUQsZ0NBQWdDO1FBQ2hDLElBQUksb0JBQW9CLENBQUMsWUFBWSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3BELElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7Z0JBQ3RELE1BQU0sQ0FBQyxJQUFJLENBQUMsK0JBQStCLENBQUMsQ0FBQztZQUMvQyxDQUFDO2lCQUFNLElBQUksb0JBQW9CLENBQUMsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDeEQsTUFBTSxDQUFDLElBQUksQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1lBQ3ZELENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNLLE1BQU0sQ0FBQyw0QkFBNEIsQ0FBQyxRQUFpQjtRQUMzRCxNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7UUFFNUIsSUFBSSxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDM0IsT0FBTyxNQUFNLENBQUMsQ0FBQyxxQ0FBcUM7UUFDdEQsQ0FBQztRQUVELElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDakMsTUFBTSxDQUFDLElBQUksQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1lBQ3JELE9BQU8sTUFBTSxDQUFDLENBQUMsMkNBQTJDO1FBQzVELENBQUM7UUFFRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDeEIsTUFBTSxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3RELENBQUM7UUFFRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsSUFBSSxFQUFFLENBQUM7WUFDM0IsTUFBTSxDQUFDLElBQUksQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFFRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSyxNQUFNLENBQUMsK0JBQStCLENBQUMsR0FBWTtRQUN6RCxNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7UUFFNUIsSUFBSSxDQUFDLEdBQUcsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNwQyxPQUFPLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUNwQyxDQUFDO1FBRUQsTUFBTSxVQUFVLEdBQUcsR0FBOEIsQ0FBQztRQUVsRCxLQUFLLE1BQU0sR0FBRyxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQzdCLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM5QixJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDeEIsU0FBUyxDQUFDLHVDQUF1QztZQUNuRCxDQUFDO1lBRUQsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDOUIsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLEdBQUcsb0JBQW9CLENBQUMsQ0FBQztZQUNwRCxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDNUIsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLEdBQUcsbUJBQW1CLENBQUMsQ0FBQztZQUNuRCxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQztnQkFDOUIsTUFBTSxDQUFDLElBQUksQ0FDVCxhQUFhLEdBQUcsNENBQTRDLENBQzdELENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ssTUFBTSxDQUFDLHVCQUF1QixDQUFDLEdBQVk7UUFDakQsTUFBTSxNQUFNLEdBQWEsRUFBRSxDQUFDO1FBRTVCLElBQUksQ0FBQyxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDcEMsT0FBTyxDQUFDLHdCQUF3QixDQUFDLENBQUM7UUFDcEMsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLEdBQThCLENBQUM7UUFFaEQsZ0NBQWdDO1FBQ2hDLElBQUksUUFBUSxDQUFDLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMvQixJQUFJLE9BQU8sUUFBUSxDQUFDLEdBQUcsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDckMsTUFBTSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1lBQ2pELENBQUM7aUJBQU0sSUFBSSxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDbkMsTUFBTSxDQUFDLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1lBQ2hELENBQUM7aUJBQU0sSUFBSSxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxJQUFJLEVBQUUsQ0FBQztnQkFDdEMsTUFBTSxDQUFDLElBQUksQ0FBQywwREFBMEQsQ0FBQyxDQUFDO1lBQzFFLENBQUM7UUFDSCxDQUFDO1FBRUQsZ0NBQWdDO1FBQ2hDLElBQUksUUFBUSxDQUFDLEdBQUcsS0FBSyxTQUFTLElBQUksT0FBTyxRQUFRLENBQUMsR0FBRyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ25FLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSyxNQUFNLENBQUMseUJBQXlCLENBQUMsTUFBZTtRQUN0RCxNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7UUFFNUIsSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDekIsT0FBTyxNQUFNLENBQUMsQ0FBQyxxQ0FBcUM7UUFDdEQsQ0FBQztRQUVELElBQUksQ0FBQyxNQUFNLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDMUMsTUFBTSxDQUFDLElBQUksQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1lBQ25ELE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUM7UUFFRCxNQUFNLFVBQVUsR0FBRyxNQUEyQixDQUFDO1FBRS9DLCtCQUErQjtRQUMvQixJQUFJLFVBQVUsQ0FBQyxXQUFXLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDekMsTUFBTSxDQUFDLElBQUksQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO1FBQzlELENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUMsdUJBQXVCLENBQ3pELFVBQVUsQ0FBQyxXQUFXLENBQ3ZCLENBQUM7WUFDRixJQUFJLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDakMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN4RSxDQUFDO1FBQ0gsQ0FBQztRQUVELHVDQUF1QztRQUN2QyxJQUFJLFVBQVUsQ0FBQyxtQkFBbUIsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNqRCxNQUFNLGVBQWUsR0FBRyxTQUFTLENBQUMsK0JBQStCLENBQy9ELFVBQVUsQ0FBQyxtQkFBbUIsQ0FDL0IsQ0FBQztZQUNGLElBQUksZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDL0IsTUFBTSxDQUFDLElBQUksQ0FDVCxHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLHdCQUF3QixHQUFHLEVBQUUsQ0FBQyxDQUMvRCxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRCx3Q0FBd0M7UUFDeEMsSUFBSSxVQUFVLENBQUMsb0JBQW9CLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDbEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLEVBQUUsQ0FBQztnQkFDcEQsTUFBTSxDQUFDLElBQUksQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1lBQ3ZELENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQy9DLE1BQU0sQ0FBQyxJQUFJLENBQUMsbURBQW1ELENBQUMsQ0FBQztnQkFDbkUsQ0FBQztnQkFDRCxJQUFJLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUM7b0JBQ2pELE1BQU0sQ0FBQyxJQUFJLENBQ1QseURBQXlELENBQzFELENBQUM7Z0JBQ0osQ0FBQztnQkFFRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO29CQUNoRSxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQy9DLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFLENBQUM7d0JBQzVCLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsb0JBQW9CLENBQUMsQ0FBQztvQkFDN0QsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCx5Q0FBeUM7UUFDekMsSUFBSSxVQUFVLENBQUMscUJBQXFCLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDbkQsSUFBSSxPQUFPLFVBQVUsQ0FBQyxxQkFBcUIsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDekQsTUFBTSxDQUFDLElBQUksQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1lBQ3hELENBQUM7aUJBQU0sSUFBSSxVQUFVLENBQUMscUJBQXFCLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ2pELE1BQU0sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLENBQUMsQ0FBQztZQUN4RCxDQUFDO1FBQ0gsQ0FBQztRQUVELDhCQUE4QjtRQUM5QixJQUFJLFVBQVUsQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDeEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLElBQUksT0FBTyxVQUFVLENBQUMsVUFBVSxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUN4RSxNQUFNLENBQUMsSUFBSSxDQUFDLDhCQUE4QixDQUFDLENBQUM7WUFDOUMsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLCtCQUErQjtnQkFDL0IsSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDOUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO3dCQUNoRCxNQUFNLENBQUMsSUFBSSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7b0JBQ25ELENBQUM7eUJBQU0sQ0FBQzt3QkFDTixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7NEJBQzVELElBQUksT0FBTyxVQUFVLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQ0FDdkQsTUFBTSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDOzRCQUN6RCxDQUFDO3dCQUNILENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO2dCQUVELGdDQUFnQztnQkFDaEMsSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDL0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO3dCQUNqRCxNQUFNLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxDQUFDLENBQUM7b0JBQ3BELENBQUM7eUJBQU0sQ0FBQzt3QkFDTixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7NEJBQzdELElBQUksT0FBTyxVQUFVLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQ0FDeEQsTUFBTSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDOzRCQUMxRCxDQUFDO3dCQUNILENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNLLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxNQUFlO1FBQ3JELE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUU1QixJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN6QixPQUFPLE1BQU0sQ0FBQyxDQUFDLHFDQUFxQztRQUN0RCxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUMxQyxNQUFNLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxDQUFDLENBQUM7WUFDbEQsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQztRQUVELE1BQU0sU0FBUyxHQUFHLE1BQTBCLENBQUM7UUFFN0Msa0NBQWtDO1FBQ2xDLElBQUksU0FBUyxDQUFDLGNBQWMsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMzQyxNQUFNLENBQUMsSUFBSSxDQUFDLGdEQUFnRCxDQUFDLENBQUM7UUFDaEUsQ0FBQzthQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO1lBQ3BELE1BQU0sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLENBQUMsQ0FBQztRQUNqRCxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksU0FBUyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hDLE1BQU0sQ0FBQyxJQUFJLENBQUMsMENBQTBDLENBQUMsQ0FBQztZQUMxRCxDQUFDO1lBQ0QsSUFBSSxTQUFTLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDeEMsTUFBTSxDQUFDLElBQUksQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO1lBQzlELENBQUM7UUFDSCxDQUFDO1FBRUQsMkJBQTJCO1FBQzNCLElBQUksU0FBUyxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNwQyxNQUFNLENBQUMsSUFBSSxDQUFDLHlDQUF5QyxDQUFDLENBQUM7UUFDekQsQ0FBQzthQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQzdDLE1BQU0sQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUMxQyxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2pDLE1BQU0sQ0FBQyxJQUFJLENBQUMsb0NBQW9DLENBQUMsQ0FBQztZQUNwRCxDQUFDO1lBQ0QsSUFBSSxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDakMsTUFBTSxDQUFDLElBQUksQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1lBQ3ZELENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ssTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFjO1FBQ3pDLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUU1QixJQUFJLENBQUMsS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3hDLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUM1QyxDQUFDO1FBQ0QsTUFBTSxjQUFjLEdBQUcsS0FBdUIsQ0FBQztRQUUvQyxJQUFJLGNBQWMsQ0FBQyxXQUFXLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDN0MsTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUMsbUJBQW1CLENBQ3JELGNBQWMsQ0FBQyxXQUFXLENBQzNCLENBQUM7WUFDRixJQUFJLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDakMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN4RSxDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksY0FBYyxDQUFDLFdBQVcsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM3QyxNQUFNLGlCQUFpQixHQUFHLFNBQVMsQ0FBQyxtQkFBbUIsQ0FDckQsY0FBYyxDQUFDLFdBQVcsQ0FDM0IsQ0FBQztZQUNGLElBQUksaUJBQWlCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNqQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3hFLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxjQUFjLENBQUMsY0FBYyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2hELE1BQU0sb0JBQW9CLEdBQUcsU0FBUyxDQUFDLHNCQUFzQixDQUMzRCxjQUFjLENBQUMsY0FBYyxDQUM5QixDQUFDO1lBQ0YsSUFBSSxvQkFBb0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BDLE1BQU0sQ0FBQyxJQUFJLENBQ1QsR0FBRyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLG1CQUFtQixHQUFHLEVBQUUsQ0FBQyxDQUMvRCxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLGNBQWMsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDdEMsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDL0QsSUFBSSxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMxQixNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDMUQsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLGNBQWMsQ0FBQyxvQkFBb0IsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN0RCxNQUFNLDBCQUEwQixHQUFHLFNBQVMsQ0FBQyw0QkFBNEIsQ0FDdkUsY0FBYyxDQUFDLG9CQUFvQixDQUNwQyxDQUFDO1lBQ0YsSUFBSSwwQkFBMEIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQ1QsR0FBRywwQkFBMEIsQ0FBQyxHQUFHLENBQy9CLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyx5QkFBeUIsR0FBRyxFQUFFLENBQ3hDLENBQ0YsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxjQUFjLENBQUMsb0JBQW9CLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDdEQsTUFBTSwwQkFBMEIsR0FBRyxTQUFTLENBQUMsNEJBQTRCLENBQ3ZFLGNBQWMsQ0FBQyxvQkFBb0IsQ0FDcEMsQ0FBQztZQUNGLElBQUksMEJBQTBCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMxQyxNQUFNLENBQUMsSUFBSSxDQUNULEdBQUcsMEJBQTBCLENBQUMsR0FBRyxDQUMvQixDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMseUJBQXlCLEdBQUcsRUFBRSxDQUN4QyxDQUNGLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksY0FBYyxDQUFDLGlCQUFpQixLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ25ELE1BQU0sdUJBQXVCLEdBQUcsU0FBUyxDQUFDLHlCQUF5QixDQUNqRSxjQUFjLENBQUMsaUJBQWlCLENBQ2pDLENBQUM7WUFDRixJQUFJLHVCQUF1QixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDdkMsTUFBTSxDQUFDLElBQUksQ0FDVCxHQUFHLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsc0JBQXNCLEdBQUcsRUFBRSxDQUFDLENBQ3JFLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksY0FBYyxDQUFDLGdCQUFnQixLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2xELE1BQU0sc0JBQXNCLEdBQUcsU0FBUyxDQUFDLHdCQUF3QixDQUMvRCxjQUFjLENBQUMsZ0JBQWdCLENBQ2hDLENBQUM7WUFDRixJQUFJLHNCQUFzQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDdEMsTUFBTSxDQUFDLElBQUksQ0FDVCxHQUFHLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMscUJBQXFCLEdBQUcsRUFBRSxDQUFDLENBQ25FLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUErSEQ7Ozs7Ozs7O09BUUc7SUFDSCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXFCO1FBQzdELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDMUQsQ0FBQztRQUVELElBQ0UsS0FBSyxDQUFDLGlCQUFpQixLQUFLLGlCQUFpQixDQUFDLGVBQWU7WUFDN0QsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUNYLENBQUM7WUFDRCxNQUFNLElBQUksS0FBSyxDQUNiLGlFQUFpRSxDQUNsRSxDQUFDO1FBQ0osQ0FBQztRQUVELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUMsaUJBQWlCLENBQUM7UUFDakQsSUFBSSxDQUFDLHVCQUF1QixHQUFHLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQztRQUM3RCxJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUM7UUFDckMsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQztRQUNyQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsS0FBSyxDQUFDLG9CQUFvQixDQUFDO1FBQ3ZELElBQUksQ0FBQyx3QkFBd0IsR0FBRyxLQUFLLENBQUMsd0JBQXdCLENBQUM7UUFDL0QsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQztRQUNyRCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsS0FBSyxDQUFDLG9CQUFvQixDQUFDO1FBQ3ZELElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDLGNBQWMsQ0FBQztRQUMzQyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDO1FBQ25ELElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7UUFDdkIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztRQUNqRCxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUM7UUFDdkMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQztRQUUvQyxJQUFJLGlCQUFpQixHQUFzQjtZQUN6QyxpQkFBaUIsRUFBRSxLQUFLLENBQUMsaUJBQWlCO1lBQzFDLHVCQUF1QixFQUFFLEtBQUssQ0FBQyx1QkFBdUI7WUFDdEQsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXO1lBQzlCLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztZQUM5QixXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVc7WUFDOUIsY0FBYyxFQUFFLEtBQUssQ0FBQyxjQUFjO1lBQ3BDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtZQUNoQix3QkFBd0IsRUFBRSxLQUFLLENBQUMsd0JBQXdCO1lBQ3hELG1CQUFtQixFQUFFLEtBQUssQ0FBQyxtQkFBbUI7WUFDOUMsb0JBQW9CLEVBQUUsS0FBSyxDQUFDLG9CQUFvQjtZQUNoRCxjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWM7WUFDcEMsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLGtCQUFrQjtZQUM1QyxPQUFPLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxPQUFPO1lBQzVCLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxpQkFBaUI7WUFDMUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZO1lBQ2hDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7Z0JBQ3RDLENBQUMsQ0FBQztvQkFDQSxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FDekQsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxlQUFlLENBQzNCO29CQUNELFNBQVMsRUFBRSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FDM0MsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQzVCO2lCQUNGO2dCQUNELENBQUMsQ0FBQyxTQUFTO1NBQ2QsQ0FBQztRQUVGLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSwwQkFBWSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztRQUN2RSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxxQkFBcUIsQ0FBQztRQUM5RCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDO1FBQzVDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQztRQUN4RCxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLHlCQUF5QixDQUFDO1FBQ3RFLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsU0FBUzthQUMxQywyQkFBd0QsQ0FBQztRQUM1RCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDO1FBQ2xELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFvQixDQUFDO0lBQ3BELENBQUM7O0FBaHhCSCw4QkFpeEJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgSVByZWZpeExpc3QsXG4gIElTZWN1cml0eUdyb3VwLFxuICBJU3VibmV0LFxuICBJVnBjRW5kcG9pbnQsXG59IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lYzInO1xuaW1wb3J0IHsgQ2ZuV29ya3NwYWNlLCBDZm5Xb3Jrc3BhY2VQcm9wcyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1ncmFmYW5hJztcbmltcG9ydCB7IElSb2xlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqXG4gKiBTcGVjaWZpZXMgd2hldGhlciB0aGUgd29ya3NwYWNlIGNhbiBhY2Nlc3MgQVdTIHJlc291cmNlcyBpbiB0aGlzIEFXUyBhY2NvdW50IG9ubHksIG9yIHdoZXRoZXIgaXRcbiAqIGNhbiBhbHNvIGFjY2VzcyBBV1MgcmVzb3VyY2VzIGluIG90aGVyIGFjY291bnRzIGluIHRoZSBzYW1lIG9yZ2FuaXphdGlvbi4gSWYgdGhpcyBpc1xuICogT1JHQU5JWkFUSU9OLCB0aGUgT3JnYW5pemF0aW9uYWxVbml0cyBwYXJhbWV0ZXIgc3BlY2lmaWVzIHdoaWNoIG9yZ2FuaXphdGlvbmFsIHVuaXRzIHRoZVxuICogd29ya3NwYWNlIGNhbiBhY2Nlc3MuXG4gKi9cbmV4cG9ydCBlbnVtIEFjY291bnRBY2Nlc3NUeXBlIHtcbiAgLyoqXG4gICAqIEFjY2VzcyBpcyBsaW1pdGVkIHRvIHRoZSBjdXJyZW50IEFXUyBhY2NvdW50IG9ubHkuXG4gICAqL1xuICBDVVJSRU5UX0FDQ09VTlQgPSAnQ1VSUkVOVF9BQ0NPVU5UJyxcblxuICAvKipcbiAgICogQWNjZXNzIGlzIGV4dGVuZGVkIHRvIHRoZSBlbnRpcmUgQVdTIG9yZ2FuaXphdGlvbi5cbiAgICovXG4gIE9SR0FOSVpBVElPTiA9ICdPUkdBTklaQVRJT04nLFxufVxuXG4vKipcbiAqIFNwZWNpZmllcyB3aGV0aGVyIHRoaXMgd29ya3NwYWNlIHVzZXMgU0FNTCAyLjAsIEFXUyBJQU0gSWRlbnRpdHkgQ2VudGVyLCBvciBib3RoIHRvIGF1dGhlbnRpY2F0ZVxuICogdXNlcnMgZm9yIHVzaW5nIHRoZSBHcmFmYW5hIGNvbnNvbGUgd2l0aGluIGEgd29ya3NwYWNlLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dyYWZhbmEvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlV29ya3NwYWNlLmh0bWxcbiAqL1xuZXhwb3J0IGVudW0gQXV0aGVudGljYXRpb25Qcm92aWRlcnMge1xuICAvKipcbiAgICogQVdTIFNpbmdsZSBTaWduLU9uIGF1dGhlbnRpY2F0aW9uIHByb3ZpZGVyLlxuICAgKi9cbiAgQVdTX1NTTyA9ICdBV1NfU1NPJyxcblxuICAvKipcbiAgICogU2VjdXJpdHkgQXNzZXJ0aW9uIE1hcmt1cCBMYW5ndWFnZSAoU0FNTCkgYXV0aGVudGljYXRpb24gcHJvdmlkZXIuXG4gICAqL1xuICBTQU1MID0gJ1NBTUwnLFxufVxuXG4vKipcbiAqIFRoZSBjb25maWd1cmF0aW9uIHNldHRpbmdzIGZvciBuZXR3b3JrIGFjY2VzcyB0byB5b3VyIHdvcmtzcGFjZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOZXR3b3JrQWNjZXNzQ29udHJvbCB7XG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBwcmVmaXggbGlzdCBJRHMuIEEgcHJlZml4IGxpc3QgaXMgYSBsaXN0IG9mIENJRFIgcmFuZ2VzIG9mIElQIGFkZHJlc3Nlcy4gVGhlIElQXG4gICAqIGFkZHJlc3NlcyBzcGVjaWZpZWQgYXJlIGFsbG93ZWQgdG8gYWNjZXNzIHlvdXIgd29ya3NwYWNlLiBJZiB0aGUgbGlzdCBpcyBub3QgaW5jbHVkZWQgaW4gdGhlXG4gICAqIGNvbmZpZ3VyYXRpb24gKHBhc3NlZCBhbiBlbXB0eSBhcnJheSkgdGhlbiBubyBJUCBhZGRyZXNzZXMgYXJlIGFsbG93ZWQgdG8gYWNjZXNzIHRoZVxuICAgKiB3b3Jrc3BhY2UuXG4gICAqXG4gICAqIE1heGltdW0gb2YgNSBwcmVmaXggbGlzdHMgYWxsb3dlZC5cbiAgICovXG4gIHJlYWRvbmx5IHByZWZpeExpc3RzPzogSVByZWZpeExpc3RbXTtcblxuICAvKipcbiAgICogQW4gYXJyYXkgb2YgQW1hem9uIFZQQyBlbmRwb2ludCBJRHMgZm9yIHRoZSB3b3Jrc3BhY2UuIFlvdSBjYW4gY3JlYXRlIFZQQyBlbmRwb2ludHMgdG8geW91clxuICAgKiBBbWF6b24gTWFuYWdlZCBHcmFmYW5hIHdvcmtzcGFjZSBmb3IgYWNjZXNzIGZyb20gd2l0aGluIGEgVlBDLiBJZiBhIE5ldHdvcmtBY2Nlc3NDb25maWd1cmF0aW9uXG4gICAqIGlzIHNwZWNpZmllZCB0aGVuIG9ubHkgVlBDIGVuZHBvaW50cyBzcGVjaWZpZWQgaGVyZSBhcmUgYWxsb3dlZCB0byBhY2Nlc3MgdGhlIHdvcmtzcGFjZS4gSWZcbiAgICogeW91IHBhc3MgaW4gYW4gZW1wdHkgYXJyYXkgb2Ygc3RyaW5ncywgdGhlbiBubyBWUENzIGFyZSBhbGxvd2VkIHRvIGFjY2VzcyB0aGUgd29ya3NwYWNlLlxuICAgKlxuICAgKiBNYXhpbXVtIG9mIDUgVlBDIGVuZHBvaW50cyBhbGxvd2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjRW5kcG9pbnRzPzogSVZwY0VuZHBvaW50W107XG59XG5cbi8qKlxuICogVGhlIEFXUyBub3RpZmljYXRpb24gY2hhbm5lbHMgdGhhdCBBbWF6b24gTWFuYWdlZCBHcmFmYW5hIGNhbiBhdXRvbWF0aWNhbGx5IGNyZWF0ZSBJQU0gcm9sZXMgYW5kXG4gKiBwZXJtaXNzaW9ucyBmb3IsIHRvIGFsbG93IEFtYXpvbiBNYW5hZ2VkIEdyYWZhbmEgdG8gdXNlIHRoZXNlIGNoYW5uZWxzLlxuICovXG5leHBvcnQgZW51bSBOb3RpZmljYXRpb25EZXN0aW5hdGlvbnMge1xuICAvKipcbiAgICogQW1hem9uIFNpbXBsZSBOb3RpZmljYXRpb24gU2VydmljZSAoU05TKSBhcyBub3RpZmljYXRpb24gZGVzdGluYXRpb24uXG4gICAqL1xuICBTTlMgPSAnU05TJyxcbn1cblxuLyoqXG4gKiBJZiB0aGlzIGlzIFNFUlZJQ0VfTUFOQUdFRCwgYW5kIHRoZSB3b3JrcGxhY2Ugd2FzIGNyZWF0ZWQgdGhyb3VnaCB0aGUgQW1hem9uIE1hbmFnZWQgR3JhZmFuYVxuICogY29uc29sZSwgdGhlbiBBbWF6b24gTWFuYWdlZCBHcmFmYW5hIGF1dG9tYXRpY2FsbHkgY3JlYXRlcyB0aGUgSUFNIHJvbGVzIGFuZCBwcm92aXNpb25zIHRoZVxuICogcGVybWlzc2lvbnMgdGhhdCB0aGUgd29ya3NwYWNlIG5lZWRzIHRvIHVzZSBBV1MgZGF0YSBzb3VyY2VzIGFuZCBub3RpZmljYXRpb24gY2hhbm5lbHMuXG4gKlxuICogSWYgdGhpcyBpcyBDVVNUT01FUl9NQU5BR0VELCB5b3UgbXVzdCBtYW5hZ2UgdGhvc2Ugcm9sZXMgYW5kIHBlcm1pc3Npb25zIHlvdXJzZWxmLlxuXG4gKiBJZiB5b3UgYXJlIHdvcmtpbmcgd2l0aCBhIHdvcmtzcGFjZSBpbiBhIG1lbWJlciBhY2NvdW50IG9mIGFuIG9yZ2FuaXphdGlvbiBhbmQgdGhhdCBhY2NvdW50IGlzXG4gKiBub3QgYSBkZWxlZ2F0ZWQgYWRtaW5pc3RyYXRvciBhY2NvdW50LCBhbmQgeW91IHdhbnQgdGhlIHdvcmtzcGFjZSB0byBhY2Nlc3MgZGF0YSBzb3VyY2VzIGluXG4gKiBvdGhlciBBV1MgYWNjb3VudHMgaW4gdGhlIG9yZ2FuaXphdGlvbiwgdGhpcyBwYXJhbWV0ZXIgbXVzdCBiZSBzZXQgdG8gQ1VTVE9NRVJfTUFOQUdFRC5cbiAqL1xuZXhwb3J0IGVudW0gUGVybWlzc2lvblR5cGVzIHtcbiAgLyoqXG4gICAqIEN1c3RvbWVyLW1hbmFnZWQgcGVybWlzc2lvbnMgd2hlcmUgeW91IG1hbmFnZSB1c2VyIGFjY2VzcyB0byBHcmFmYW5hLlxuICAgKi9cbiAgQ1VTVE9NRVJfTUFOQUdFRCA9ICdDVVNUT01FUl9NQU5BR0VEJyxcblxuICAvKipcbiAgICogU2VydmljZS1tYW5hZ2VkIHBlcm1pc3Npb25zIHdoZXJlIEFXUyBtYW5hZ2VzIHVzZXIgYWNjZXNzIHRvIEdyYWZhbmEuXG4gICAqL1xuICBTRVJWSUNFX01BTkFHRUQgPSAnU0VSVklDRV9NQU5BR0VEJyxcbn1cblxuLyoqXG4gKiBBIHN0cnVjdHVyZSB0aGF0IGRlZmluZXMgd2hpY2ggYXR0cmlidXRlcyBpbiB0aGUgSWRQIGFzc2VydGlvbiBhcmUgdG8gYmUgdXNlZCB0byBkZWZpbmVcbiAqIGluZm9ybWF0aW9uIGFib3V0IHRoZSB1c2VycyBhdXRoZW50aWNhdGVkIGJ5IHRoZSBJZFAgdG8gdXNlIHRoZSB3b3Jrc3BhY2UuXG4gKlxuICogRWFjaCBhdHRyaWJ1dGUgbXVzdCBiZSBhIHN0cmluZyB3aXRoIGxlbmd0aCBiZXR3ZWVuIDEgYW5kIDI1NiBjaGFyYWN0ZXJzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNhbWxBc3NlcnRpb25BdHRyaWJ1dGVzIHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgd2l0aGluIHRoZSBTQU1MIGFzc2VydGlvbiB0byB1c2UgYXMgdGhlIGVtYWlsIG5hbWVzIGZvciBTQU1MIHVzZXJzLlxuICAgKlxuICAgKiBNdXN0IGJlIGJldHdlZW4gMSBhbmQgMjU2IGNoYXJhY3RlcnMgbG9uZy5cbiAgICovXG4gIHJlYWRvbmx5IGVtYWlsOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHdpdGhpbiB0aGUgU0FNTCBhc3NlcnRpb24gdG8gdXNlIGFzIHRoZSB1c2VyIGZ1bGwgXCJmcmllbmRseVwiIG5hbWVzXG4gICAqIGZvciB1c2VyIGdyb3Vwcy5cbiAgICpcbiAgICogTXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDI1NiBjaGFyYWN0ZXJzIGxvbmcuXG4gICAqL1xuICByZWFkb25seSBncm91cHM6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgd2l0aGluIHRoZSBTQU1MIGFzc2VydGlvbiB0byB1c2UgYXMgdGhlIGxvZ2luIG5hbWVzIGZvciBTQU1MIHVzZXJzLlxuICAgKlxuICAgKiBNdXN0IGJlIGJldHdlZW4gMSBhbmQgMjU2IGNoYXJhY3RlcnMgbG9uZy5cbiAgICovXG4gIHJlYWRvbmx5IGxvZ2luOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHdpdGhpbiB0aGUgU0FNTCBhc3NlcnRpb24gdG8gdXNlIGFzIHRoZSB1c2VyIGZ1bGwgXCJmcmllbmRseVwiIG5hbWVzXG4gICAqIGZvciBTQU1MIHVzZXJzLlxuICAgKlxuICAgKiBNdXN0IGJlIGJldHdlZW4gMSBhbmQgMjU2IGNoYXJhY3RlcnMgbG9uZy5cbiAgICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgd2l0aGluIHRoZSBTQU1MIGFzc2VydGlvbiB0byB1c2UgYXMgdGhlIHVzZXIgZnVsbCBcImZyaWVuZGx5XCIgbmFtZXNcbiAgICogZm9yIHRoZSB1c2Vycycgb3JnYW5pemF0aW9ucy5cbiAgICpcbiAgICogTXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDI1NiBjaGFyYWN0ZXJzIGxvbmcuXG4gICAqL1xuICByZWFkb25seSBvcmc6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgd2l0aGluIHRoZSBTQU1MIGFzc2VydGlvbiB0byB1c2UgYXMgdGhlIHVzZXIgcm9sZXMuXG4gICAqXG4gICAqIE11c3QgYmUgYmV0d2VlbiAxIGFuZCAyNTYgY2hhcmFjdGVycyBsb25nLlxuICAgKi9cbiAgcmVhZG9ubHkgcm9sZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgc3RydWN0dXJlIGNvbnRhaW5pbmcgdGhlIGlkZW50aXR5IHByb3ZpZGVyIChJZFApIG1ldGFkYXRhIHVzZWQgdG8gaW50ZWdyYXRlIHRoZSBpZGVudGl0eVxuICogcHJvdmlkZXIgd2l0aCB0aGlzIHdvcmtzcGFjZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTYW1sSWRwTWV0YWRhdGEge1xuICAvKipcbiAgICogVGhlIFVSTCBvZiB0aGUgbG9jYXRpb24gY29udGFpbmluZyB0aGUgSWRQIG1ldGFkYXRhLlxuICAgKlxuICAgKiBNdXN0IGJlIGEgc3RyaW5nIHdpdGggbGVuZ3RoIGJldHdlZW4gMSBhbmQgMjA0OCBjaGFyYWN0ZXJzLlxuICAgKi9cbiAgcmVhZG9ubHkgdXJsPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZnVsbCBJZFAgbWV0YWRhdGEsIGluIFhNTCBmb3JtYXQuXG4gICAqL1xuICByZWFkb25seSB4bWw/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSBzdHJ1Y3R1cmUgY29udGFpbmluZyBhcnJheXMgdGhhdCBtYXAgZ3JvdXAgbmFtZXMgaW4gdGhlIFNBTUwgYXNzZXJ0aW9uIHRvIHRoZSBHcmFmYW5hIEFkbWluXG4gKiBhbmQgRWRpdG9yIHJvbGVzIGluIHRoZSB3b3Jrc3BhY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2FtbFJvbGVWYWx1ZXMge1xuICAvKipcbiAgICogQSBsaXN0IG9mIGdyb3VwcyBmcm9tIHRoZSBTQU1MIGFzc2VydGlvbiBhdHRyaWJ1dGUgdG8gZ3JhbnQgdGhlIEdyYWZhbmEgQWRtaW4gcm9sZSB0by5cbiAgICpcbiAgICogTWF4aW11bSBvZiAyNTYgZWxlbWVudHMuXG4gICAqL1xuICByZWFkb25seSBhZG1pbj86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgZ3JvdXBzIGZyb20gdGhlIFNBTUwgYXNzZXJ0aW9uIGF0dHJpYnV0ZSB0byBncmFudCB0aGUgR3JhZmFuYSBFZGl0b3Igcm9sZSB0by5cbiAgICpcbiAgICogTWF4aW11bSBvZiAyNTYgZWxlbWVudHMuXG4gICAqL1xuICByZWFkb25seSBlZGl0b3I/OiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBJZiB0aGUgd29ya3NwYWNlIHVzZXMgU0FNTCwgdXNlIHRoaXMgc3RydWN0dXJlIHRvIG1hcCBTQU1MIGFzc2VydGlvbiBhdHRyaWJ1dGVzIHRvIHdvcmtzcGFjZVxuICogdXNlciBpbmZvcm1hdGlvbiBhbmQgZGVmaW5lIHdoaWNoIGdyb3VwcyBpbiB0aGUgYXNzZXJ0aW9uIGF0dHJpYnV0ZSBhcmUgdG8gaGF2ZSB0aGUgQWRtaW4gYW5kXG4gKiBFZGl0b3Igcm9sZXMgaW4gdGhlIHdvcmtzcGFjZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTYW1sQ29uZmlndXJhdGlvbiB7XG4gIC8qKlxuICAgKiBMaXN0cyB3aGljaCBvcmdhbml6YXRpb25zIGRlZmluZWQgaW4gdGhlIFNBTUwgYXNzZXJ0aW9uIGFyZSBhbGxvd2VkIHRvIHVzZSB0aGUgQW1hem9uIE1hbmFnZWRcbiAgICogR3JhZmFuYSB3b3Jrc3BhY2UuIElmIHRoaXMgaXMgZW1wdHksIGFsbCBvcmdhbml6YXRpb25zIGluIHRoZSBhc3NlcnRpb24gYXR0cmlidXRlIGhhdmUgYWNjZXNzLlxuICAgKlxuICAgKiBNdXN0IGhhdmUgYmV0d2VlbiAxIGFuZCAyNTYgZWxlbWVudHMuXG4gICAqL1xuICByZWFkb25seSBhbGxvd2VkT3JnYW5pemF0aW9ucz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBBIHN0cnVjdHVyZSB0aGF0IGRlZmluZXMgd2hpY2ggYXR0cmlidXRlcyBpbiB0aGUgU0FNTCBhc3NlcnRpb24gYXJlIHRvIGJlIHVzZWQgdG8gZGVmaW5lXG4gICAqIGluZm9ybWF0aW9uIGFib3V0IHRoZSB1c2VycyBhdXRoZW50aWNhdGVkIGJ5IHRoYXQgSWRQIHRvIHVzZSB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcmVhZG9ubHkgYXNzZXJ0aW9uQXRycmlidXRlcz86IFNhbWxBc3NlcnRpb25BdHRyaWJ1dGVzO1xuXG4gIC8qKlxuICAgKiBBIHN0cnVjdHVyZSBjb250YWluaW5nIHRoZSBpZGVudGl0eSBwcm92aWRlciAoSWRQKSBtZXRhZGF0YSB1c2VkIHRvIGludGVncmF0ZSB0aGUgaWRlbnRpdHlcbiAgICogcHJvdmlkZXIgd2l0aCB0aGlzIHdvcmtzcGFjZS5cbiAgICpcbiAgICogUmVxdWlyZWQgZmllbGQgZm9yIFNBTUwgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IGlkcE1ldGFkYXRhOiBTYW1sSWRwTWV0YWRhdGE7XG5cbiAgLyoqXG4gICAqIEhvdyBsb25nIGEgc2lnbi1vbiBzZXNzaW9uIGJ5IGEgU0FNTCB1c2VyIGlzIHZhbGlkLCBiZWZvcmUgdGhlIHVzZXIgaGFzIHRvIHNpZ24gb24gYWdhaW4uXG4gICAqXG4gICAqIE11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXIuXG4gICAqL1xuICByZWFkb25seSBsb2dpblZhbGlkaXR5RHVyYXRpb24/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEEgc3RydWN0dXJlIGNvbnRhaW5pbmcgYXJyYXlzIHRoYXQgbWFwIGdyb3VwIG5hbWVzIGluIHRoZSBTQU1MIGFzc2VydGlvbiB0byB0aGUgR3JhZmFuYSBBZG1pblxuICAgKiBhbmQgRWRpdG9yIHJvbGVzIGluIHRoZSB3b3Jrc3BhY2UuXG4gICAqL1xuICByZWFkb25seSByb2xlVmFsdWVzPzogU2FtbFJvbGVWYWx1ZXM7XG59XG5cbi8qKlxuICogVGhlIGNvbmZpZ3VyYXRpb24gc2V0dGluZ3MgZm9yIGFuIEFtYXpvbiBWUEMgdGhhdCBjb250YWlucyBkYXRhIHNvdXJjZXMgZm9yIHlvdXIgR3JhZmFuYVxuICogd29ya3NwYWNlIHRvIGNvbm5lY3QgdG8uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVnBjQ29uZmlndXJhdGlvbiB7XG4gIC8qKlxuICAgKiBUaGUgbGlzdCBvZiBBbWF6b24gRUMyIHNlY3VyaXR5IGdyb3VwcyBhdHRhY2hlZCB0byB0aGUgQW1hem9uIFZQQyBmb3IgeW91ciBHcmFmYW5hXG4gICAqIHdvcmtzcGFjZSB0byBjb25uZWN0LiBEdXBsaWNhdGVzIG5vdCBhbGxvd2VkLlxuICAgKlxuICAgKiBBcnJheSBNZW1iZXJzOiBNaW5pbXVtIG51bWJlciBvZiAxIGl0ZW1zLiBNYXhpbXVtIG51bWJlciBvZiA1IGl0ZW1zLlxuICAgKlxuICAgKiBSZXF1aXJlZCBmb3IgVlBDIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3VwczogSVNlY3VyaXR5R3JvdXBbXTtcblxuICAvKipcbiAgICogVGhlIGxpc3Qgb2YgQW1hem9uIEVDMiBzdWJuZXRzIGNyZWF0ZWQgaW4gdGhlIEFtYXpvbiBWUEMgZm9yIHlvdXIgR3JhZmFuYSB3b3Jrc3BhY2UgdG9cbiAgICogY29ubmVjdC4gRHVwbGljYXRlcyBub3QgYWxsb3dlZC5cbiAgICpcbiAgICogQXJyYXkgTWVtYmVyczogTWluaW11bSBudW1iZXIgb2YgMiBpdGVtcy4gTWF4aW11bSBudW1iZXIgb2YgNiBpdGVtcy5cbiAgICpcbiAgICogUmVxdWlyZWQgZm9yIFZQQyBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgc3VibmV0czogSVN1Ym5ldFtdO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGNyZWF0aW5nIGFuIEFtYXpvbiBNYW5hZ2VkIEdyYWZhbmEgd29ya3NwYWNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtzcGFjZVByb3BzIHtcbiAgLyoqXG4gICAqIFR5cGUgb2YgYWNjb3VudCBhY2Nlc3MgZm9yIHRoZSB3b3Jrc3BhY2UuXG4gICAqIFJlcXVpcmVkIGZpZWxkLlxuICAgKi9cbiAgcmVhZG9ubHkgYWNjb3VudEFjY2Vzc1R5cGU6IEFjY291bnRBY2Nlc3NUeXBlO1xuXG4gIC8qKlxuICAgKiBBdXRoZW50aWNhdGlvbiBwcm92aWRlcnMgdG8gZW5hYmxlIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKiBSZXF1aXJlZCBmaWVsZC5cbiAgICovXG4gIHJlYWRvbmx5IGF1dGhlbnRpY2F0aW9uUHJvdmlkZXJzOiBBdXRoZW50aWNhdGlvblByb3ZpZGVyc1tdO1xuXG4gIC8qKlxuICAgKiBDbGllbnQgdG9rZW4gZm9yIGlkZW1wb3RlbnQgd29ya3NwYWNlIGNyZWF0aW9uLlxuICAgKiBNdXN0IGJlIDEtNjQgY2hhcmFjdGVycyBsb25nIGFuZCBjb250YWluIG9ubHkgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlcnMuXG4gICAqL1xuICByZWFkb25seSBjbGllbnRUb2tlbj86IHN0cmluZztcblxuICAvKipcbiAgICogTGlzdCBvZiBkYXRhIHNvdXJjZXMgdG8gZW5hYmxlIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YVNvdXJjZXM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogRGVzY3JpcHRpb24gb2YgdGhlIHdvcmtzcGFjZS5cbiAgICogTWF4aW11bSBsZW5ndGggb2YgMjA0OCBjaGFyYWN0ZXJzLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEdyYWZhbmEgdmVyc2lvbiBmb3IgdGhlIHdvcmtzcGFjZS5cbiAgICogTXVzdCBiZSAxLTI1NSBjaGFyYWN0ZXJzIGxvbmcuXG4gICAqL1xuICByZWFkb25seSBncmFmYW5hVmVyc2lvbj86IHN0cmluZztcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgd29ya3NwYWNlLlxuICAgKiBNdXN0IGJlIDEtMjU1IGNoYXJhY3RlcnMgbG9uZyBhbmQgY29udGFpbiBvbmx5IGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzLCBoeXBoZW5zLCBkb3RzLCB1bmRlcnNjb3JlcywgYW5kIHRpbGRlcy5cbiAgICovXG4gIHJlYWRvbmx5IG5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE5ldHdvcmsgYWNjZXNzIGNvbnRyb2wgY29uZmlndXJhdGlvbiBmb3IgdGhlIHdvcmtzcGFjZS5cbiAgICovXG4gIHJlYWRvbmx5IG5ldHdvcmtBY2Nlc3NDb250cm9sPzogTmV0d29ya0FjY2Vzc0NvbnRyb2w7XG5cbiAgLyoqXG4gICAqIE5vdGlmaWNhdGlvbiBkZXN0aW5hdGlvbnMgdG8gZW5hYmxlIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcmVhZG9ubHkgbm90aWZpY2F0aW9uRGVzdGluYXRpb25zPzogTm90aWZpY2F0aW9uRGVzdGluYXRpb25zW107XG5cbiAgLyoqXG4gICAqIExpc3Qgb2Ygb3JnYW5pemF0aW9uYWwgdW5pdHMgdG8gaW5jbHVkZSBpbiB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcmVhZG9ubHkgb3JnYW5pemF0aW9uYWxVbml0cz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSBJQU0gcm9sZSB0byB1c2UgZm9yIHRoZSBvcmdhbml6YXRpb24uXG4gICAqIE1heGltdW0gbGVuZ3RoIG9mIDIwNDggY2hhcmFjdGVycy5cbiAgICovXG4gIHJlYWRvbmx5IG9yZ2FuaXphdGlvblJvbGVOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQZXJtaXNzaW9uIHR5cGUgZm9yIHRoZSB3b3Jrc3BhY2UuXG4gICAqIFJlcXVpcmVkIGZpZWxkLlxuICAgKi9cbiAgcmVhZG9ubHkgcGVybWlzc2lvblR5cGU6IFBlcm1pc3Npb25UeXBlcztcblxuICAvKipcbiAgICogV2hldGhlciB0byBlbmFibGUgdGhlIEdyYWZhbmEgcGx1Z2luIGFkbWluIHBhZ2UuXG4gICAqIERlZmF1bHQ6IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5BZG1pbkVuYWJsZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJQU0gcm9sZSB0byB1c2UgZm9yIHRoZSB3b3Jrc3BhY2UuXG4gICAqL1xuICByZWFkb25seSByb2xlPzogSVJvbGU7XG5cbiAgLyoqXG4gICAqIFNBTUwgY29uZmlndXJhdGlvbiBmb3IgdGhlIHdvcmtzcGFjZS5cbiAgICovXG4gIHJlYWRvbmx5IHNhbWxDb25maWd1cmF0aW9uPzogU2FtbENvbmZpZ3VyYXRpb247XG5cbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIENsb3VkRm9ybWF0aW9uIHN0YWNrIHNldCB0byB1c2UuXG4gICAqL1xuICByZWFkb25seSBzdGFja1NldE5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFZQQyBjb25maWd1cmF0aW9uIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjQ29uZmlndXJhdGlvbj86IFZwY0NvbmZpZ3VyYXRpb247XG59XG5cbi8qKlxuICogU3RhdHVzIG9mIFNBTUwgY29uZmlndXJhdGlvbiBmb3IgYSBHcmFmYW5hIHdvcmtzcGFjZS5cbiAqL1xuZXhwb3J0IGVudW0gU2FtbENvbmZpZ3VyYXRpb25TdGF0dXNlcyB7XG4gIC8qKlxuICAgKiBTQU1MIGlzIGNvbmZpZ3VyZWQgZm9yIHRoZSB3b3Jrc3BhY2UuXG4gICAqL1xuICBDT05GSUdVUkVEID0gJ0NPTkZJR1VSRUQnLFxuXG4gIC8qKlxuICAgKiBTQU1MIGlzIG5vdCBjb25maWd1cmVkIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgTk9UX0NPTkZJR1VSRUQgPSAnTk9UX0NPTkZJR1VSRUQnLFxufVxuXG4vKipcbiAqIFN0YXR1cyBvZiBhIEdyYWZhbmEgd29ya3NwYWNlLlxuICovXG5leHBvcnQgZW51bSBTdGF0dXMge1xuICAvKipcbiAgICogV29ya3NwYWNlIGlzIGFjdGl2ZSBhbmQgcmVhZHkgdG8gdXNlLlxuICAgKi9cbiAgQUNUSVZFID0gJ0FDVElWRScsXG5cbiAgLyoqXG4gICAqIFdvcmtzcGFjZSBpcyBiZWluZyBjcmVhdGVkLlxuICAgKi9cbiAgQ1JFQVRJTkcgPSAnQ1JFQVRJTkcnLFxuXG4gIC8qKlxuICAgKiBXb3Jrc3BhY2UgaXMgYmVpbmcgZGVsZXRlZC5cbiAgICovXG4gIERFTEVUSU5HID0gJ0RFTEVUSU5HJyxcblxuICAvKipcbiAgICogV29ya3NwYWNlIG9wZXJhdGlvbiBoYXMgZmFpbGVkLlxuICAgKi9cbiAgRkFJTEVEID0gJ0ZBSUxFRCcsXG5cbiAgLyoqXG4gICAqIFdvcmtzcGFjZSBpcyBiZWluZyB1cGRhdGVkLlxuICAgKi9cbiAgVVBEQVRJTkcgPSAnVVBEQVRJTkcnLFxuXG4gIC8qKlxuICAgKiBXb3Jrc3BhY2UgaXMgYmVpbmcgdXBncmFkZWQuXG4gICAqL1xuICBVUEdSQURJTkcgPSAnVVBHUkFESU5HJyxcblxuICAvKipcbiAgICogV29ya3NwYWNlIGRlbGV0aW9uIGhhcyBmYWlsZWQuXG4gICAqL1xuICBERUxFVElPTl9GQUlMRUQgPSAnREVMRVRJT05fRkFJTEVEJyxcblxuICAvKipcbiAgICogV29ya3NwYWNlIGNyZWF0aW9uIGhhcyBmYWlsZWQuXG4gICAqL1xuICBDUkVBVElPTl9GQUlMRUQgPSAnQ1JFQVRJT05fRkFJTEVEJyxcblxuICAvKipcbiAgICogV29ya3NwYWNlIHVwZGF0ZSBoYXMgZmFpbGVkLlxuICAgKi9cbiAgVVBEQVRFX0ZBSUxFRCA9ICdVUERBVEVfRkFJTEVEJyxcblxuICAvKipcbiAgICogV29ya3NwYWNlIHVwZ3JhZGUgaGFzIGZhaWxlZC5cbiAgICovXG4gIFVQR1JBREVfRkFJTEVEID0gJ1VQR1JBREVfRkFJTEVEJyxcblxuICAvKipcbiAgICogTGljZW5zZSByZW1vdmFsIGhhcyBmYWlsZWQuXG4gICAqL1xuICBMSUNFTlNFX1JFTU9WQUxfRkFJTEVEID0gJ0xJQ0VOU0VfUkVNT1ZBTF9GQUlMRUQnLFxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gQW1hem9uIE1hbmFnZWQgR3JhZmFuYSB3b3Jrc3BhY2UuXG4gKlxuICogVGhpcyBjbGFzcyBwcm92aWRlcyBhIGhpZ2gtbGV2ZWwgYWJzdHJhY3Rpb24gZm9yIGNyZWF0aW5nIGFuZCBtYW5hZ2luZ1xuICogQW1hem9uIE1hbmFnZWQgR3JhZmFuYSB3b3Jrc3BhY2VzIHVzaW5nIEFXUyBDREsuXG4gKi9cbmV4cG9ydCBjbGFzcyBXb3Jrc3BhY2UgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBjbGllbnRUb2tlbiBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHBhcmFtIHRva2VuIC0gVGhlIGNsaWVudCB0b2tlbiB0byB2YWxpZGF0ZVxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBlcnJvciBtZXNzYWdlcyBpZiB2YWxpZGF0aW9uIGZhaWxzLCBvciBhbiBlbXB0eSBhcnJheSBpZiB2YWxpZFxuICAgKlxuICAgKiBWYWxpZGF0aW9uIHJ1bGVzOlxuICAgKiAtIE11c3QgYmUgYSBzdHJpbmdcbiAgICogLSBNdXN0IGJlIGJldHdlZW4gMSBhbmQgNjQgY2hhcmFjdGVycyBsb25nXG4gICAqIC0gTXVzdCBjb250YWluIG9ubHkgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlcnNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHZhbGlkYXRlQ2xpZW50VG9rZW4odG9rZW46IHVua25vd24pOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKHRva2VuID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBlcnJvcnM7IC8vIE9wdGlvbmFsIHByb3BlcnR5IGNhbiBiZSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRva2VuICE9PSAnc3RyaW5nJykge1xuICAgICAgZXJyb3JzLnB1c2goJ2NsaWVudFRva2VuIG11c3QgYmUgYSBzdHJpbmcnKTtcbiAgICAgIHJldHVybiBlcnJvcnM7IC8vIE5vIG5lZWQgdG8gY2hlY2sgZnVydGhlciBpZiBub3QgYSBzdHJpbmdcbiAgICB9XG5cbiAgICBjb25zdCByZWdleCA9IC9eWyEtfl17MSw2NH0kLztcbiAgICBpZiAoIXJlZ2V4LnRlc3QodG9rZW4pKSB7XG4gICAgICBpZiAodG9rZW4ubGVuZ3RoIDwgMSB8fCB0b2tlbi5sZW5ndGggPiA2NCkge1xuICAgICAgICBlcnJvcnMucHVzaCgnY2xpZW50VG9rZW4gbXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDY0IGNoYXJhY3RlcnMgbG9uZycpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIS9eWyEtfl0qJC8udGVzdCh0b2tlbikpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goJ2NsaWVudFRva2VuIG11c3QgY29udGFpbiBvbmx5IHByaW50YWJsZSBBU0NJSSBjaGFyYWN0ZXJzJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9ycztcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgdGhlIGRlc2NyaXB0aW9uIHByb3BlcnR5LlxuICAgKlxuICAgKiBAcGFyYW0gZGVzY3JpcHRpb24gLSBUaGUgZGVzY3JpcHRpb24gdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgZXJyb3IgbWVzc2FnZXMgaWYgdmFsaWRhdGlvbiBmYWlscywgb3IgYW4gZW1wdHkgYXJyYXkgaWYgdmFsaWRcbiAgICpcbiAgICogVmFsaWRhdGlvbiBydWxlczpcbiAgICogLSBNdXN0IGJlIGEgc3RyaW5nXG4gICAqIC0gTWF4aW11bSBsZW5ndGggb2YgMjA0OCBjaGFyYWN0ZXJzXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyB2YWxpZGF0ZURlc2NyaXB0aW9uKGRlc2NyaXB0aW9uOiB1bmtub3duKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICAgIGlmIChkZXNjcmlwdGlvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZXJyb3JzOyAvLyBPcHRpb25hbCBwcm9wZXJ0eSBjYW4gYmUgdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkZXNjcmlwdGlvbiAhPT0gJ3N0cmluZycpIHtcbiAgICAgIGVycm9ycy5wdXNoKCdkZXNjcmlwdGlvbiBtdXN0IGJlIGEgc3RyaW5nJyk7XG4gICAgICByZXR1cm4gZXJyb3JzOyAvLyBObyBuZWVkIHRvIGNoZWNrIGZ1cnRoZXIgaWYgbm90IGEgc3RyaW5nXG4gICAgfVxuXG4gICAgaWYgKGRlc2NyaXB0aW9uLmxlbmd0aCA+IDIwNDgpIHtcbiAgICAgIGVycm9ycy5wdXNoKCdkZXNjcmlwdGlvbiBjYW5ub3QgZXhjZWVkIDIwNDggY2hhcmFjdGVycycpO1xuICAgIH1cblxuICAgIHJldHVybiBlcnJvcnM7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBncmFmYW5hVmVyc2lvbiBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHBhcmFtIHZlcnNpb24gLSBUaGUgR3JhZmFuYSB2ZXJzaW9uIHRvIHZhbGlkYXRlXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGVycm9yIG1lc3NhZ2VzIGlmIHZhbGlkYXRpb24gZmFpbHMsIG9yIGFuIGVtcHR5IGFycmF5IGlmIHZhbGlkXG4gICAqXG4gICAqIFZhbGlkYXRpb24gcnVsZXM6XG4gICAqIC0gTXVzdCBiZSBhIHN0cmluZ1xuICAgKiAtIE11c3QgYmUgYmV0d2VlbiAxIGFuZCAyNTUgY2hhcmFjdGVycyBsb25nXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyB2YWxpZGF0ZUdyYWZhbmFWZXJzaW9uKHZlcnNpb246IHVua25vd24pOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKHZlcnNpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGVycm9yczsgLy8gT3B0aW9uYWwgcHJvcGVydHkgY2FuIGJlIHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdmVyc2lvbiAhPT0gJ3N0cmluZycpIHtcbiAgICAgIGVycm9ycy5wdXNoKCdncmFmYW5hVmVyc2lvbiBtdXN0IGJlIGEgc3RyaW5nJyk7XG4gICAgICByZXR1cm4gZXJyb3JzOyAvLyBObyBuZWVkIHRvIGNoZWNrIGZ1cnRoZXIgaWYgbm90IGEgc3RyaW5nXG4gICAgfVxuXG4gICAgaWYgKHZlcnNpb24ubGVuZ3RoIDwgMSkge1xuICAgICAgZXJyb3JzLnB1c2goJ2dyYWZhbmFWZXJzaW9uIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cblxuICAgIGlmICh2ZXJzaW9uLmxlbmd0aCA+IDI1NSkge1xuICAgICAgZXJyb3JzLnB1c2goJ2dyYWZhbmFWZXJzaW9uIGNhbm5vdCBleGNlZWQgMjU1IGNoYXJhY3RlcnMnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXJyb3JzO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGUgbmFtZSBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHBhcmFtIG5hbWUgLSBUaGUgd29ya3NwYWNlIG5hbWUgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgZXJyb3IgbWVzc2FnZXMgaWYgdmFsaWRhdGlvbiBmYWlscywgb3IgYW4gZW1wdHkgYXJyYXkgaWYgdmFsaWRcbiAgICpcbiAgICogVmFsaWRhdGlvbiBydWxlczpcbiAgICogLSBNdXN0IGJlIGEgc3RyaW5nXG4gICAqIC0gTXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDI1NSBjaGFyYWN0ZXJzIGxvbmdcbiAgICogLSBDYW4gb25seSBjb250YWluIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzLCBoeXBoZW5zLCBkb3RzLCB1bmRlcnNjb3JlcywgYW5kIHRpbGRlc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgdmFsaWRhdGVOYW1lKG5hbWU6IHVua25vd24pOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKG5hbWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGVycm9yczsgLy8gT3B0aW9uYWwgcHJvcGVydHkgY2FuIGJlIHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIGVycm9ycy5wdXNoKCduYW1lIG11c3QgYmUgYSBzdHJpbmcnKTtcbiAgICAgIHJldHVybiBlcnJvcnM7IC8vIE5vIG5lZWQgdG8gY2hlY2sgZnVydGhlciBpZiBub3QgYSBzdHJpbmdcbiAgICB9XG5cbiAgICBjb25zdCByZWdleCA9IC9eW2EtekEtWjAtOVxcLS5ffl17MSwyNTV9JC87XG4gICAgaWYgKCFyZWdleC50ZXN0KG5hbWUpKSB7XG4gICAgICBpZiAobmFtZS5sZW5ndGggPCAxIHx8IG5hbWUubGVuZ3RoID4gMjU1KSB7XG4gICAgICAgIGVycm9ycy5wdXNoKCduYW1lIG11c3QgYmUgYmV0d2VlbiAxIGFuZCAyNTUgY2hhcmFjdGVycyBsb25nJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghL15bYS16QS1aMC05XFwtLl9+XSokLy50ZXN0KG5hbWUpKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICAgICduYW1lIGNhbiBvbmx5IGNvbnRhaW4gYWxwaGFudW1lcmljIGNoYXJhY3RlcnMsIGh5cGhlbnMsIGRvdHMsIHVuZGVyc2NvcmVzLCBhbmQgdGlsZGVzJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZXJyb3JzO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGUgbmV0d29ya0FjY2Vzc0NvbnRyb2wgcHJvcGVydHkuXG4gICAqXG4gICAqIEBwYXJhbSBuYWMgLSBUaGUgbmV0d29yayBhY2Nlc3MgY29udHJvbCBjb25maWd1cmF0aW9uIHRvIHZhbGlkYXRlXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGVycm9yIG1lc3NhZ2VzIGlmIHZhbGlkYXRpb24gZmFpbHMsIG9yIGFuIGVtcHR5IGFycmF5IGlmIHZhbGlkXG4gICAqXG4gICAqIFZhbGlkYXRpb24gcnVsZXM6XG4gICAqIC0gTXVzdCBiZSBhbiBvYmplY3RcbiAgICogLSBwcmVmaXhMaXN0cyAoaWYgcHJlc2VudCkgbXVzdCBiZSBhbiBhcnJheSB3aXRoIGF0IG1vc3QgNSBpdGVtc1xuICAgKiAtIHZwY0VuZHBvaW50cyAoaWYgcHJlc2VudCkgbXVzdCBiZSBhbiBhcnJheSB3aXRoIGF0IG1vc3QgNSBpdGVtc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgdmFsaWRhdGVOZXR3b3JrQWNjZXNzQ29udHJvbChuYWM6IHVua25vd24pOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKG5hYyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZXJyb3JzOyAvLyBPcHRpb25hbCBwcm9wZXJ0eSBjYW4gYmUgdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgaWYgKCFuYWMgfHwgdHlwZW9mIG5hYyAhPT0gJ29iamVjdCcpIHtcbiAgICAgIGVycm9ycy5wdXNoKCduZXR3b3JrQWNjZXNzQ29udHJvbCBtdXN0IGJlIGFuIG9iamVjdCcpO1xuICAgICAgcmV0dXJuIGVycm9ycztcbiAgICB9XG5cbiAgICBjb25zdCBuZXR3b3JrQWNjZXNzQ29udHJvbCA9IG5hYyBhcyBOZXR3b3JrQWNjZXNzQ29udHJvbDtcblxuICAgIC8vIENoZWNrIHByZWZpeExpc3RzIGlmIHByZXNlbnRcbiAgICBpZiAobmV0d29ya0FjY2Vzc0NvbnRyb2wucHJlZml4TGlzdHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5ldHdvcmtBY2Nlc3NDb250cm9sLnByZWZpeExpc3RzKSkge1xuICAgICAgICBlcnJvcnMucHVzaCgncHJlZml4TGlzdHMgbXVzdCBiZSBhbiBhcnJheScpO1xuICAgICAgfSBlbHNlIGlmIChuZXR3b3JrQWNjZXNzQ29udHJvbC5wcmVmaXhMaXN0cy5sZW5ndGggPiA1KSB7XG4gICAgICAgIGVycm9ycy5wdXNoKCdwcmVmaXhMaXN0cyBjYW4gaGF2ZSBhdCBtb3N0IDUgaXRlbXMnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayB2cGNFbmRwb2ludHMgaWYgcHJlc2VudFxuICAgIGlmIChuZXR3b3JrQWNjZXNzQ29udHJvbC52cGNFbmRwb2ludHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5ldHdvcmtBY2Nlc3NDb250cm9sLnZwY0VuZHBvaW50cykpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goJ3ZwY0VuZHBvaW50cyBtdXN0IGJlIGFuIGFycmF5Jyk7XG4gICAgICB9IGVsc2UgaWYgKG5ldHdvcmtBY2Nlc3NDb250cm9sLnZwY0VuZHBvaW50cy5sZW5ndGggPiA1KSB7XG4gICAgICAgIGVycm9ycy5wdXNoKCd2cGNFbmRwb2ludHMgY2FuIGhhdmUgYXQgbW9zdCA1IGl0ZW1zJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9ycztcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgdGhlIG9yZ2FuaXphdGlvblJvbGVOYW1lIHByb3BlcnR5LlxuICAgKlxuICAgKiBAcGFyYW0gcm9sZU5hbWUgLSBUaGUgb3JnYW5pemF0aW9uIHJvbGUgbmFtZSB0byB2YWxpZGF0ZVxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBlcnJvciBtZXNzYWdlcyBpZiB2YWxpZGF0aW9uIGZhaWxzLCBvciBhbiBlbXB0eSBhcnJheSBpZiB2YWxpZFxuICAgKlxuICAgKiBWYWxpZGF0aW9uIHJ1bGVzOlxuICAgKiAtIE11c3QgYmUgYSBzdHJpbmdcbiAgICogLSBNdXN0IGJlIGJldHdlZW4gMSBhbmQgMjA0OCBjaGFyYWN0ZXJzIGxvbmdcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHZhbGlkYXRlT3JnYW5pemF0aW9uUm9sZU5hbWUocm9sZU5hbWU6IHVua25vd24pOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKHJvbGVOYW1lID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBlcnJvcnM7IC8vIE9wdGlvbmFsIHByb3BlcnR5IGNhbiBiZSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHJvbGVOYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgZXJyb3JzLnB1c2goJ29yZ2FuaXphdGlvblJvbGVOYW1lIG11c3QgYmUgYSBzdHJpbmcnKTtcbiAgICAgIHJldHVybiBlcnJvcnM7IC8vIE5vIG5lZWQgdG8gY2hlY2sgZnVydGhlciBpZiBub3QgYSBzdHJpbmdcbiAgICB9XG5cbiAgICBpZiAocm9sZU5hbWUubGVuZ3RoIDwgMSkge1xuICAgICAgZXJyb3JzLnB1c2goJ29yZ2FuaXphdGlvblJvbGVOYW1lIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cblxuICAgIGlmIChyb2xlTmFtZS5sZW5ndGggPiAyMDQ4KSB7XG4gICAgICBlcnJvcnMucHVzaCgnb3JnYW5pemF0aW9uUm9sZU5hbWUgY2Fubm90IGV4Y2VlZCAyMDQ4IGNoYXJhY3RlcnMnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXJyb3JzO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGUgU0FNTCBhc3NlcnRpb24gYXR0cmlidXRlcy5cbiAgICpcbiAgICogQHBhcmFtIG9iaiAtIFRoZSBTQU1MIGFzc2VydGlvbiBhdHRyaWJ1dGVzIHRvIHZhbGlkYXRlXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGVycm9yIG1lc3NhZ2VzIGlmIHZhbGlkYXRpb24gZmFpbHMsIG9yIGFuIGVtcHR5IGFycmF5IGlmIHZhbGlkXG4gICAqXG4gICAqIFZhbGlkYXRpb24gcnVsZXM6XG4gICAqIC0gTXVzdCBiZSBhbiBvYmplY3RcbiAgICogLSBFYWNoIGF0dHJpYnV0ZSBtdXN0IGJlIGEgc3RyaW5nXG4gICAqIC0gRWFjaCBhdHRyaWJ1dGUgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDI1NiBjaGFyYWN0ZXJzIGxvbmdcbiAgICogLSBWYWxpZCBhdHRyaWJ1dGUga2V5cyBhcmU6ICdlbWFpbCcsICdncm91cHMnLCAnbG9naW4nLCAnbmFtZScsICdvcmcnLCAncm9sZSdcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHZhbGlkYXRlU2FtbEFzc2VydGlvbkF0dHJpYnV0ZXMob2JqOiB1bmtub3duKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICAgIGlmICghb2JqIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gWydJbnB1dCBpcyBub3QgYW4gb2JqZWN0J107XG4gICAgfVxuXG4gICAgY29uc3QgYXR0cmlidXRlcyA9IG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIGF0dHJpYnV0ZXMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gYXR0cmlidXRlc1trZXldO1xuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29udGludWU7IC8vIE9wdGlvbmFsIHByb3BlcnRpZXMgY2FuIGJlIHVuZGVmaW5lZFxuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgICBlcnJvcnMucHVzaChgUHJvcGVydHkgJyR7a2V5fScgbXVzdCBiZSBhIHN0cmluZ2ApO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZS5sZW5ndGggPCAxKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKGBQcm9wZXJ0eSAnJHtrZXl9JyBjYW5ub3QgYmUgZW1wdHlgKTtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUubGVuZ3RoID4gMjU2KSB7XG4gICAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICAgIGBQcm9wZXJ0eSAnJHtrZXl9JyBleGNlZWRzIG1heGltdW0gbGVuZ3RoIG9mIDI1NiBjaGFyYWN0ZXJzYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZXJyb3JzO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGUgU0FNTCBJZFAgbWV0YWRhdGEuXG4gICAqXG4gICAqIEBwYXJhbSBvYmogLSBUaGUgU0FNTCBJZFAgbWV0YWRhdGEgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgZXJyb3IgbWVzc2FnZXMgaWYgdmFsaWRhdGlvbiBmYWlscywgb3IgYW4gZW1wdHkgYXJyYXkgaWYgdmFsaWRcbiAgICpcbiAgICogVmFsaWRhdGlvbiBydWxlczpcbiAgICogLSBNdXN0IGJlIGFuIG9iamVjdFxuICAgKiAtIHVybCAoaWYgcHJlc2VudCkgbXVzdCBiZSBhIHN0cmluZyBiZXR3ZWVuIDEgYW5kIDIwNDggY2hhcmFjdGVycyBsb25nXG4gICAqIC0geG1sIChpZiBwcmVzZW50KSBtdXN0IGJlIGEgc3RyaW5nXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyB2YWxpZGF0ZVNhbWxJZHBNZXRhZGF0YShvYmo6IHVua25vd24pOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiBbJ0lucHV0IGlzIG5vdCBhbiBvYmplY3QnXTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXRhZGF0YSA9IG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuICAgIC8vIENoZWNrIHVybCBwcm9wZXJ0eSBpZiBwcmVzZW50XG4gICAgaWYgKG1ldGFkYXRhLnVybCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIG1ldGFkYXRhLnVybCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goXCJQcm9wZXJ0eSAndXJsJyBtdXN0IGJlIGEgc3RyaW5nXCIpO1xuICAgICAgfSBlbHNlIGlmIChtZXRhZGF0YS51cmwubGVuZ3RoIDwgMSkge1xuICAgICAgICBlcnJvcnMucHVzaChcIlByb3BlcnR5ICd1cmwnIGNhbm5vdCBiZSBlbXB0eVwiKTtcbiAgICAgIH0gZWxzZSBpZiAobWV0YWRhdGEudXJsLmxlbmd0aCA+IDIwNDgpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goXCJQcm9wZXJ0eSAndXJsJyBleGNlZWRzIG1heGltdW0gbGVuZ3RoIG9mIDIwNDggY2hhcmFjdGVyc1wiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayB4bWwgcHJvcGVydHkgaWYgcHJlc2VudFxuICAgIGlmIChtZXRhZGF0YS54bWwgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgbWV0YWRhdGEueG1sICE9PSAnc3RyaW5nJykge1xuICAgICAgZXJyb3JzLnB1c2goXCJQcm9wZXJ0eSAneG1sJyBtdXN0IGJlIGEgc3RyaW5nXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBlcnJvcnM7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBTQU1MIGNvbmZpZ3VyYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSBjb25maWcgLSBUaGUgU0FNTCBjb25maWd1cmF0aW9uIHRvIHZhbGlkYXRlXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGVycm9yIG1lc3NhZ2VzIGlmIHZhbGlkYXRpb24gZmFpbHMsIG9yIGFuIGVtcHR5IGFycmF5IGlmIHZhbGlkXG4gICAqXG4gICAqIFZhbGlkYXRpb24gcnVsZXM6XG4gICAqIC0gTXVzdCBiZSBhbiBvYmplY3RcbiAgICogLSBpZHBNZXRhZGF0YSBpcyByZXF1aXJlZCBhbmQgbXVzdCBiZSB2YWxpZFxuICAgKiAtIGFzc2VydGlvbkF0cnJpYnV0ZXMgKGlmIHByZXNlbnQpIG11c3QgYmUgdmFsaWRcbiAgICogLSBhbGxvd2VkT3JnYW5pemF0aW9ucyAoaWYgcHJlc2VudCkgbXVzdCBiZSBhbiBhcnJheSBvZiBzdHJpbmdzIHdpdGggMS0yNTYgZWxlbWVudHNcbiAgICogLSBsb2dpblZhbGlkaXR5RHVyYXRpb24gKGlmIHByZXNlbnQpIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXJcbiAgICogLSByb2xlVmFsdWVzIChpZiBwcmVzZW50KSBtdXN0IGJlIGFuIG9iamVjdCB3aXRoIHZhbGlkIGFkbWluIGFuZCBlZGl0b3IgYXJyYXlzXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyB2YWxpZGF0ZVNhbWxDb25maWd1cmF0aW9uKGNvbmZpZzogdW5rbm93bik6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG5cbiAgICBpZiAoY29uZmlnID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBlcnJvcnM7IC8vIE9wdGlvbmFsIHByb3BlcnR5IGNhbiBiZSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBpZiAoIWNvbmZpZyB8fCB0eXBlb2YgY29uZmlnICE9PSAnb2JqZWN0Jykge1xuICAgICAgZXJyb3JzLnB1c2goJ3NhbWxDb25maWd1cmF0aW9uIG11c3QgYmUgYW4gb2JqZWN0Jyk7XG4gICAgICByZXR1cm4gZXJyb3JzO1xuICAgIH1cblxuICAgIGNvbnN0IHNhbWxDb25maWcgPSBjb25maWcgYXMgU2FtbENvbmZpZ3VyYXRpb247XG5cbiAgICAvLyBDaGVjayBpZHBNZXRhZGF0YSAocmVxdWlyZWQpXG4gICAgaWYgKHNhbWxDb25maWcuaWRwTWV0YWRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZXJyb3JzLnB1c2goJ2lkcE1ldGFkYXRhIGlzIHJlcXVpcmVkIGluIHNhbWxDb25maWd1cmF0aW9uJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGlkcE1ldGFkYXRhRXJyb3JzID0gV29ya3NwYWNlLnZhbGlkYXRlU2FtbElkcE1ldGFkYXRhKFxuICAgICAgICBzYW1sQ29uZmlnLmlkcE1ldGFkYXRhLFxuICAgICAgKTtcbiAgICAgIGlmIChpZHBNZXRhZGF0YUVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKC4uLmlkcE1ldGFkYXRhRXJyb3JzLm1hcCgoZXJyKSA9PiBgaWRwTWV0YWRhdGE6ICR7ZXJyfWApKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBhc3NlcnRpb25BdHJyaWJ1dGVzIGlmIHByZXNlbnRcbiAgICBpZiAoc2FtbENvbmZpZy5hc3NlcnRpb25BdHJyaWJ1dGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGF0dHJpYnV0ZUVycm9ycyA9IFdvcmtzcGFjZS52YWxpZGF0ZVNhbWxBc3NlcnRpb25BdHRyaWJ1dGVzKFxuICAgICAgICBzYW1sQ29uZmlnLmFzc2VydGlvbkF0cnJpYnV0ZXMsXG4gICAgICApO1xuICAgICAgaWYgKGF0dHJpYnV0ZUVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICAgIC4uLmF0dHJpYnV0ZUVycm9ycy5tYXAoKGVycikgPT4gYGFzc2VydGlvbkF0cnJpYnV0ZXM6ICR7ZXJyfWApLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENoZWNrIGFsbG93ZWRPcmdhbml6YXRpb25zIGlmIHByZXNlbnRcbiAgICBpZiAoc2FtbENvbmZpZy5hbGxvd2VkT3JnYW5pemF0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2FtbENvbmZpZy5hbGxvd2VkT3JnYW5pemF0aW9ucykpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goJ2FsbG93ZWRPcmdhbml6YXRpb25zIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChzYW1sQ29uZmlnLmFsbG93ZWRPcmdhbml6YXRpb25zLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgICBlcnJvcnMucHVzaCgnYWxsb3dlZE9yZ2FuaXphdGlvbnMgbXVzdCBoYXZlIGF0IGxlYXN0IDEgZWxlbWVudCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzYW1sQ29uZmlnLmFsbG93ZWRPcmdhbml6YXRpb25zLmxlbmd0aCA+IDI1Nikge1xuICAgICAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICAgICAgJ2FsbG93ZWRPcmdhbml6YXRpb25zIGNhbm5vdCBoYXZlIG1vcmUgdGhhbiAyNTYgZWxlbWVudHMnLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNhbWxDb25maWcuYWxsb3dlZE9yZ2FuaXphdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBjb25zdCBvcmcgPSBzYW1sQ29uZmlnLmFsbG93ZWRPcmdhbml6YXRpb25zW2ldO1xuICAgICAgICAgIGlmICh0eXBlb2Ygb3JnICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgZXJyb3JzLnB1c2goYGFsbG93ZWRPcmdhbml6YXRpb25zWyR7aX1dIG11c3QgYmUgYSBzdHJpbmdgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBsb2dpblZhbGlkaXR5RHVyYXRpb24gaWYgcHJlc2VudFxuICAgIGlmIChzYW1sQ29uZmlnLmxvZ2luVmFsaWRpdHlEdXJhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIHNhbWxDb25maWcubG9naW5WYWxpZGl0eUR1cmF0aW9uICE9PSAnbnVtYmVyJykge1xuICAgICAgICBlcnJvcnMucHVzaCgnbG9naW5WYWxpZGl0eUR1cmF0aW9uIG11c3QgYmUgYSBudW1iZXInKTtcbiAgICAgIH0gZWxzZSBpZiAoc2FtbENvbmZpZy5sb2dpblZhbGlkaXR5RHVyYXRpb24gPD0gMCkge1xuICAgICAgICBlcnJvcnMucHVzaCgnbG9naW5WYWxpZGl0eUR1cmF0aW9uIG11c3QgYmUgcG9zaXRpdmUnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayByb2xlVmFsdWVzIGlmIHByZXNlbnRcbiAgICBpZiAoc2FtbENvbmZpZy5yb2xlVmFsdWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICghc2FtbENvbmZpZy5yb2xlVmFsdWVzIHx8IHR5cGVvZiBzYW1sQ29uZmlnLnJvbGVWYWx1ZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKCdyb2xlVmFsdWVzIG11c3QgYmUgYW4gb2JqZWN0Jyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDaGVjayBhZG1pbiBhcnJheSBpZiBwcmVzZW50XG4gICAgICAgIGlmIChzYW1sQ29uZmlnLnJvbGVWYWx1ZXMuYWRtaW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShzYW1sQ29uZmlnLnJvbGVWYWx1ZXMuYWRtaW4pKSB7XG4gICAgICAgICAgICBlcnJvcnMucHVzaCgncm9sZVZhbHVlcy5hZG1pbiBtdXN0IGJlIGFuIGFycmF5Jyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtbENvbmZpZy5yb2xlVmFsdWVzLmFkbWluLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgIGlmICh0eXBlb2Ygc2FtbENvbmZpZy5yb2xlVmFsdWVzLmFkbWluW2ldICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKGByb2xlVmFsdWVzLmFkbWluWyR7aX1dIG11c3QgYmUgYSBzdHJpbmdgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGVkaXRvciBhcnJheSBpZiBwcmVzZW50XG4gICAgICAgIGlmIChzYW1sQ29uZmlnLnJvbGVWYWx1ZXMuZWRpdG9yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2FtbENvbmZpZy5yb2xlVmFsdWVzLmVkaXRvcikpIHtcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKCdyb2xlVmFsdWVzLmVkaXRvciBtdXN0IGJlIGFuIGFycmF5Jyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtbENvbmZpZy5yb2xlVmFsdWVzLmVkaXRvci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIHNhbWxDb25maWcucm9sZVZhbHVlcy5lZGl0b3JbaV0gIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JzLnB1c2goYHJvbGVWYWx1ZXMuZWRpdG9yWyR7aX1dIG11c3QgYmUgYSBzdHJpbmdgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBlcnJvcnM7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSB2cGNDb25maWd1cmF0aW9uIHByb3BlcnR5LlxuICAgKlxuICAgKiBAcGFyYW0gY29uZmlnIC0gVGhlIFZQQyBjb25maWd1cmF0aW9uIHRvIHZhbGlkYXRlXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGVycm9yIG1lc3NhZ2VzIGlmIHZhbGlkYXRpb24gZmFpbHMsIG9yIGFuIGVtcHR5IGFycmF5IGlmIHZhbGlkXG4gICAqXG4gICAqIFZhbGlkYXRpb24gcnVsZXM6XG4gICAqIC0gTXVzdCBiZSBhbiBvYmplY3RcbiAgICogLSBzZWN1cml0eUdyb3VwcyBpcyByZXF1aXJlZCBhbmQgbXVzdCBiZSBhbiBhcnJheSB3aXRoIDEtNSBpdGVtc1xuICAgKiAtIHN1Ym5ldHMgaXMgcmVxdWlyZWQgYW5kIG11c3QgYmUgYW4gYXJyYXkgd2l0aCAyLTYgaXRlbXNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHZhbGlkYXRlVnBjQ29uZmlndXJhdGlvbihjb25maWc6IHVua25vd24pOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKGNvbmZpZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZXJyb3JzOyAvLyBPcHRpb25hbCBwcm9wZXJ0eSBjYW4gYmUgdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcgfHwgdHlwZW9mIGNvbmZpZyAhPT0gJ29iamVjdCcpIHtcbiAgICAgIGVycm9ycy5wdXNoKCd2cGNDb25maWd1cmF0aW9uIG11c3QgYmUgYW4gb2JqZWN0Jyk7XG4gICAgICByZXR1cm4gZXJyb3JzO1xuICAgIH1cblxuICAgIGNvbnN0IHZwY0NvbmZpZyA9IGNvbmZpZyBhcyBWcGNDb25maWd1cmF0aW9uO1xuXG4gICAgLy8gQ2hlY2sgc2VjdXJpdHlHcm91cHMgKHJlcXVpcmVkKVxuICAgIGlmICh2cGNDb25maWcuc2VjdXJpdHlHcm91cHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZXJyb3JzLnB1c2goJ3NlY3VyaXR5R3JvdXBzIGlzIHJlcXVpcmVkIGluIHZwY0NvbmZpZ3VyYXRpb24nKTtcbiAgICB9IGVsc2UgaWYgKCFBcnJheS5pc0FycmF5KHZwY0NvbmZpZy5zZWN1cml0eUdyb3VwcykpIHtcbiAgICAgIGVycm9ycy5wdXNoKCdzZWN1cml0eUdyb3VwcyBtdXN0IGJlIGFuIGFycmF5Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh2cGNDb25maWcuc2VjdXJpdHlHcm91cHMubGVuZ3RoIDwgMSkge1xuICAgICAgICBlcnJvcnMucHVzaCgnc2VjdXJpdHlHcm91cHMgbXVzdCBoYXZlIGF0IGxlYXN0IDEgaXRlbScpO1xuICAgICAgfVxuICAgICAgaWYgKHZwY0NvbmZpZy5zZWN1cml0eUdyb3Vwcy5sZW5ndGggPiA1KSB7XG4gICAgICAgIGVycm9ycy5wdXNoKCdzZWN1cml0eUdyb3VwcyBjYW5ub3QgaGF2ZSBtb3JlIHRoYW4gNSBpdGVtcycpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENoZWNrIHN1Ym5ldHMgKHJlcXVpcmVkKVxuICAgIGlmICh2cGNDb25maWcuc3VibmV0cyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBlcnJvcnMucHVzaCgnc3VibmV0cyBpcyByZXF1aXJlZCBpbiB2cGNDb25maWd1cmF0aW9uJyk7XG4gICAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheSh2cGNDb25maWcuc3VibmV0cykpIHtcbiAgICAgIGVycm9ycy5wdXNoKCdzdWJuZXRzIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHZwY0NvbmZpZy5zdWJuZXRzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goJ3N1Ym5ldHMgbXVzdCBoYXZlIGF0IGxlYXN0IDIgaXRlbXMnKTtcbiAgICAgIH1cbiAgICAgIGlmICh2cGNDb25maWcuc3VibmV0cy5sZW5ndGggPiA2KSB7XG4gICAgICAgIGVycm9ycy5wdXNoKCdzdWJuZXRzIGNhbm5vdCBoYXZlIG1vcmUgdGhhbiA2IGl0ZW1zJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9ycztcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYWxsIHdvcmtzcGFjZSBwcm9wZXJ0aWVzLlxuICAgKlxuICAgKiBAcGFyYW0gcHJvcHMgLSBUaGUgd29ya3NwYWNlIHByb3BlcnRpZXMgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgZXJyb3IgbWVzc2FnZXMgaWYgdmFsaWRhdGlvbiBmYWlscywgb3IgYW4gZW1wdHkgYXJyYXkgaWYgdmFsaWRcbiAgICpcbiAgICogVGhpcyBtZXRob2QgYWdncmVnYXRlcyB2YWxpZGF0aW9uIHJlc3VsdHMgZnJvbSBhbGwgaW5kaXZpZHVhbCBwcm9wZXJ0eSB2YWxpZGF0b3JzLlxuICAgKiBJdCB0aHJvd3MgYW4gZXJyb3IgaWYgcHJvcHMgaXMgbm90IGFuIG9iamVjdC5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHZhbGlkYXRlUHJvcHMocHJvcHM6IHVua25vd24pOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKCFwcm9wcyB8fCB0eXBlb2YgcHJvcHMgIT09ICdvYmplY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb3BzIGlzIG5vdCBhbiBvYmplY3QnKTtcbiAgICB9XG4gICAgY29uc3Qgd29ya3NwYWNlUHJvcHMgPSBwcm9wcyBhcyBXb3Jrc3BhY2VQcm9wcztcblxuICAgIGlmICh3b3Jrc3BhY2VQcm9wcy5jbGllbnRUb2tlbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBjbGllbnRUb2tlbkVycm9ycyA9IFdvcmtzcGFjZS52YWxpZGF0ZUNsaWVudFRva2VuKFxuICAgICAgICB3b3Jrc3BhY2VQcm9wcy5jbGllbnRUb2tlbixcbiAgICAgICk7XG4gICAgICBpZiAoY2xpZW50VG9rZW5FcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvcnMucHVzaCguLi5jbGllbnRUb2tlbkVycm9ycy5tYXAoKGVycikgPT4gYGNsaWVudFRva2VuOiAke2Vycn1gKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdvcmtzcGFjZVByb3BzLmRlc2NyaXB0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGRlc2NyaXB0aW9uRXJyb3JzID0gV29ya3NwYWNlLnZhbGlkYXRlRGVzY3JpcHRpb24oXG4gICAgICAgIHdvcmtzcGFjZVByb3BzLmRlc2NyaXB0aW9uLFxuICAgICAgKTtcbiAgICAgIGlmIChkZXNjcmlwdGlvbkVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKC4uLmRlc2NyaXB0aW9uRXJyb3JzLm1hcCgoZXJyKSA9PiBgZGVzY3JpcHRpb246ICR7ZXJyfWApKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAod29ya3NwYWNlUHJvcHMuZ3JhZmFuYVZlcnNpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZ3JhZmFuYVZlcnNpb25FcnJvcnMgPSBXb3Jrc3BhY2UudmFsaWRhdGVHcmFmYW5hVmVyc2lvbihcbiAgICAgICAgd29ya3NwYWNlUHJvcHMuZ3JhZmFuYVZlcnNpb24sXG4gICAgICApO1xuICAgICAgaWYgKGdyYWZhbmFWZXJzaW9uRXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgICAgLi4uZ3JhZmFuYVZlcnNpb25FcnJvcnMubWFwKChlcnIpID0+IGBncmFmYW5hVmVyc2lvbjogJHtlcnJ9YCksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdvcmtzcGFjZVByb3BzLm5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgbmFtZUVycm9ycyA9IFdvcmtzcGFjZS52YWxpZGF0ZU5hbWUod29ya3NwYWNlUHJvcHMubmFtZSk7XG4gICAgICBpZiAobmFtZUVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKC4uLm5hbWVFcnJvcnMubWFwKChlcnIpID0+IGBuYW1lOiAke2Vycn1gKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdvcmtzcGFjZVByb3BzLm5ldHdvcmtBY2Nlc3NDb250cm9sICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IG5ldHdvcmtBY2Nlc3NDb250cm9sRXJyb3JzID0gV29ya3NwYWNlLnZhbGlkYXRlTmV0d29ya0FjY2Vzc0NvbnRyb2woXG4gICAgICAgIHdvcmtzcGFjZVByb3BzLm5ldHdvcmtBY2Nlc3NDb250cm9sLFxuICAgICAgKTtcbiAgICAgIGlmIChuZXR3b3JrQWNjZXNzQ29udHJvbEVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICAgIC4uLm5ldHdvcmtBY2Nlc3NDb250cm9sRXJyb3JzLm1hcChcbiAgICAgICAgICAgIChlcnIpID0+IGBuZXR3b3JrQWNjZXNzQ29udHJvbDogJHtlcnJ9YCxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh3b3Jrc3BhY2VQcm9wcy5vcmdhbml6YXRpb25Sb2xlTmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBvcmdhbml6YXRpb25Sb2xlTmFtZUVycm9ycyA9IFdvcmtzcGFjZS52YWxpZGF0ZU9yZ2FuaXphdGlvblJvbGVOYW1lKFxuICAgICAgICB3b3Jrc3BhY2VQcm9wcy5vcmdhbml6YXRpb25Sb2xlTmFtZSxcbiAgICAgICk7XG4gICAgICBpZiAob3JnYW5pemF0aW9uUm9sZU5hbWVFcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgICAuLi5vcmdhbml6YXRpb25Sb2xlTmFtZUVycm9ycy5tYXAoXG4gICAgICAgICAgICAoZXJyKSA9PiBgb3JnYW5pemF0aW9uUm9sZU5hbWU6ICR7ZXJyfWAsXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAod29ya3NwYWNlUHJvcHMuc2FtbENvbmZpZ3VyYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3Qgc2FtbENvbmZpZ3VyYXRpb25FcnJvcnMgPSBXb3Jrc3BhY2UudmFsaWRhdGVTYW1sQ29uZmlndXJhdGlvbihcbiAgICAgICAgd29ya3NwYWNlUHJvcHMuc2FtbENvbmZpZ3VyYXRpb24sXG4gICAgICApO1xuICAgICAgaWYgKHNhbWxDb25maWd1cmF0aW9uRXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgICAgLi4uc2FtbENvbmZpZ3VyYXRpb25FcnJvcnMubWFwKChlcnIpID0+IGBzYW1sQ29uZmlndXJhdGlvbjogJHtlcnJ9YCksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdvcmtzcGFjZVByb3BzLnZwY0NvbmZpZ3VyYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgdnBjQ29uZmlndXJhdGlvbkVycm9ycyA9IFdvcmtzcGFjZS52YWxpZGF0ZVZwY0NvbmZpZ3VyYXRpb24oXG4gICAgICAgIHdvcmtzcGFjZVByb3BzLnZwY0NvbmZpZ3VyYXRpb24sXG4gICAgICApO1xuICAgICAgaWYgKHZwY0NvbmZpZ3VyYXRpb25FcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgICAuLi52cGNDb25maWd1cmF0aW9uRXJyb3JzLm1hcCgoZXJyKSA9PiBgdnBjQ29uZmlndXJhdGlvbjogJHtlcnJ9YCksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9ycztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiBhY2NvdW50IGFjY2VzcyBmb3IgdGhlIHdvcmtzcGFjZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhY2NvdW50QWNjZXNzVHlwZTogQWNjb3VudEFjY2Vzc1R5cGU7XG5cbiAgLyoqXG4gICAqIEF1dGhlbnRpY2F0aW9uIHByb3ZpZGVycyBlbmFibGVkIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGF1dGhlbnRpY2F0aW9uUHJvdmlkZXJzOiBBdXRoZW50aWNhdGlvblByb3ZpZGVyc1tdO1xuXG4gIC8qKlxuICAgKiBDbGllbnQgdG9rZW4gdXNlZCBmb3IgaWRlbXBvdGVudCB3b3Jrc3BhY2UgY3JlYXRpb24uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2xpZW50VG9rZW4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERhdGEgc291cmNlcyBlbmFibGVkIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRhdGFTb3VyY2VzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIERlc2NyaXB0aW9uIG9mIHRoZSB3b3Jrc3BhY2UuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIHdvcmtzcGFjZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBuYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBOZXR3b3JrIGFjY2VzcyBjb250cm9sIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSB3b3Jrc3BhY2UuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbmV0d29ya0FjY2Vzc0NvbnRyb2w/OiBOZXR3b3JrQWNjZXNzQ29udHJvbDtcblxuICAvKipcbiAgICogTm90aWZpY2F0aW9uIGRlc3RpbmF0aW9ucyBlbmFibGVkIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG5vdGlmaWNhdGlvbkRlc3RpbmF0aW9ucz86IE5vdGlmaWNhdGlvbkRlc3RpbmF0aW9uc1tdO1xuXG4gIC8qKlxuICAgKiBPcmdhbml6YXRpb25hbCB1bml0cyBpbmNsdWRlZCBpbiB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG9yZ2FuaXphdGlvbmFsVW5pdHM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgSUFNIHJvbGUgdXNlZCBmb3IgdGhlIG9yZ2FuaXphdGlvbi5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBvcmdhbml6YXRpb25Sb2xlTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogUGVybWlzc2lvbiB0eXBlIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHBlcm1pc3Npb25UeXBlOiBQZXJtaXNzaW9uVHlwZXM7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIEdyYWZhbmEgcGx1Z2luIGFkbWluIHBhZ2UgaXMgZW5hYmxlZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwbHVnaW5BZG1pbkVuYWJsZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJQU0gcm9sZSB1c2VkIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHJvbGU/OiBJUm9sZTtcblxuICAvKipcbiAgICogU0FNTCBjb25maWd1cmF0aW9uIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNhbWxDb25maWd1cmF0aW9uPzogU2FtbENvbmZpZ3VyYXRpb247XG5cbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIENsb3VkRm9ybWF0aW9uIHN0YWNrIHNldCB1c2VkLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHN0YWNrU2V0TmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVlBDIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSB3b3Jrc3BhY2UuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdnBjQ29uZmlndXJhdGlvbj86IFZwY0NvbmZpZ3VyYXRpb247XG5cbiAgLyoqXG4gICAqIFRoZSB1bmRlcmx5aW5nIENsb3VkRm9ybWF0aW9uIHJlc291cmNlLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSB3b3Jrc3BhY2U6IENmbldvcmtzcGFjZTtcblxuICAvKipcbiAgICogVGltZXN0YW1wIHdoZW4gdGhlIHdvcmtzcGFjZSB3YXMgY3JlYXRlZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjcmVhdGlvblRpbWVzdGFtcDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFbmRwb2ludCBVUkwgZm9yIHRoZSBHcmFmYW5hIHdvcmtzcGFjZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBlbmRwb2ludDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBHcmFmYW5hIHZlcnNpb24gcnVubmluZyBpbiB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGdyYWZhbmFWZXJzaW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgd29ya3NwYWNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRpbWVzdGFtcCB3aGVuIHRoZSB3b3Jrc3BhY2Ugd2FzIGxhc3QgbW9kaWZpZWQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbW9kaWZpY2F0aW9uVGltZXN0YW1wOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFN0YXR1cyBvZiBTQU1MIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSB3b3Jrc3BhY2UuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2FtbENvbmZpZ3VyYXRpb25TdGF0dXM6IFNhbWxDb25maWd1cmF0aW9uU3RhdHVzZXM7XG5cbiAgLyoqXG4gICAqIFNTTyBjbGllbnQgSUQgZm9yIHRoZSB3b3Jrc3BhY2UuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc3NvQ2xpZW50SWQ6IHN0cmluZztcblxuICAvKipcbiAgICogQ3VycmVudCBzdGF0dXMgb2YgdGhlIHdvcmtzcGFjZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzdGF0dXM6IFN0YXR1cztcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBBbWF6b24gTWFuYWdlZCBHcmFmYW5hIHdvcmtzcGFjZS5cbiAgICpcbiAgICogQHBhcmFtIHNjb3BlIC0gVGhlIHNjb3BlIGluIHdoaWNoIHRvIGRlZmluZSB0aGlzIGNvbnN0cnVjdFxuICAgKiBAcGFyYW0gaWQgLSBUaGUgc2NvcGVkIGNvbnN0cnVjdCBJRFxuICAgKiBAcGFyYW0gcHJvcHMgLSBDb25maWd1cmF0aW9uIHByb3BlcnRpZXMgZm9yIHRoZSB3b3Jrc3BhY2VcbiAgICpcbiAgICogQHRocm93cyBFcnJvciBpZiBhbnkgb2YgdGhlIHByb3ZpZGVkIHByb3BlcnRpZXMgZmFpbCB2YWxpZGF0aW9uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogV29ya3NwYWNlUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgZXJyb3JzID0gV29ya3NwYWNlLnZhbGlkYXRlUHJvcHMocHJvcHMpO1xuICAgIGlmIChlcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHByb3BzOlxcbiR7ZXJyb3JzLmpvaW4oJ1xcbicpfWApO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHByb3BzLmFjY291bnRBY2Nlc3NUeXBlID09PSBBY2NvdW50QWNjZXNzVHlwZS5DVVJSRU5UX0FDQ09VTlQgJiZcbiAgICAgICFwcm9wcy5yb2xlXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdSb2xlIG11c3QgYmUgcHJvdmlkZWQgd2hlbiBhY2NvdW50QWNjZXNzVHlwZSBpcyBDVVJSRU5UX0FDQ09VTlQnLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmFjY291bnRBY2Nlc3NUeXBlID0gcHJvcHMuYWNjb3VudEFjY2Vzc1R5cGU7XG4gICAgdGhpcy5hdXRoZW50aWNhdGlvblByb3ZpZGVycyA9IHByb3BzLmF1dGhlbnRpY2F0aW9uUHJvdmlkZXJzO1xuICAgIHRoaXMuY2xpZW50VG9rZW4gPSBwcm9wcy5jbGllbnRUb2tlbjtcbiAgICB0aGlzLmRhdGFTb3VyY2VzID0gcHJvcHMuZGF0YVNvdXJjZXM7XG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IHByb3BzLmRlc2NyaXB0aW9uO1xuICAgIHRoaXMubmV0d29ya0FjY2Vzc0NvbnRyb2wgPSBwcm9wcy5uZXR3b3JrQWNjZXNzQ29udHJvbDtcbiAgICB0aGlzLm5vdGlmaWNhdGlvbkRlc3RpbmF0aW9ucyA9IHByb3BzLm5vdGlmaWNhdGlvbkRlc3RpbmF0aW9ucztcbiAgICB0aGlzLm9yZ2FuaXphdGlvbmFsVW5pdHMgPSBwcm9wcy5vcmdhbml6YXRpb25hbFVuaXRzO1xuICAgIHRoaXMub3JnYW5pemF0aW9uUm9sZU5hbWUgPSBwcm9wcy5vcmdhbml6YXRpb25Sb2xlTmFtZTtcbiAgICB0aGlzLnBlcm1pc3Npb25UeXBlID0gcHJvcHMucGVybWlzc2lvblR5cGU7XG4gICAgdGhpcy5wbHVnaW5BZG1pbkVuYWJsZWQgPSBwcm9wcy5wbHVnaW5BZG1pbkVuYWJsZWQ7XG4gICAgdGhpcy5uYW1lID0gcHJvcHMubmFtZTtcbiAgICB0aGlzLnJvbGUgPSBwcm9wcy5yb2xlO1xuICAgIHRoaXMuc2FtbENvbmZpZ3VyYXRpb24gPSBwcm9wcy5zYW1sQ29uZmlndXJhdGlvbjtcbiAgICB0aGlzLnN0YWNrU2V0TmFtZSA9IHByb3BzLnN0YWNrU2V0TmFtZTtcbiAgICB0aGlzLnZwY0NvbmZpZ3VyYXRpb24gPSBwcm9wcy52cGNDb25maWd1cmF0aW9uO1xuXG4gICAgbGV0IGNmbldvcmtzcGFjZVByb3BzOiBDZm5Xb3Jrc3BhY2VQcm9wcyA9IHtcbiAgICAgIGFjY291bnRBY2Nlc3NUeXBlOiBwcm9wcy5hY2NvdW50QWNjZXNzVHlwZSxcbiAgICAgIGF1dGhlbnRpY2F0aW9uUHJvdmlkZXJzOiBwcm9wcy5hdXRoZW50aWNhdGlvblByb3ZpZGVycyxcbiAgICAgIGNsaWVudFRva2VuOiBwcm9wcy5jbGllbnRUb2tlbixcbiAgICAgIGRhdGFTb3VyY2VzOiBwcm9wcy5kYXRhU291cmNlcyxcbiAgICAgIGRlc2NyaXB0aW9uOiBwcm9wcy5kZXNjcmlwdGlvbixcbiAgICAgIGdyYWZhbmFWZXJzaW9uOiBwcm9wcy5ncmFmYW5hVmVyc2lvbixcbiAgICAgIG5hbWU6IHByb3BzLm5hbWUsXG4gICAgICBub3RpZmljYXRpb25EZXN0aW5hdGlvbnM6IHByb3BzLm5vdGlmaWNhdGlvbkRlc3RpbmF0aW9ucyxcbiAgICAgIG9yZ2FuaXphdGlvbmFsVW5pdHM6IHByb3BzLm9yZ2FuaXphdGlvbmFsVW5pdHMsXG4gICAgICBvcmdhbml6YXRpb25Sb2xlTmFtZTogcHJvcHMub3JnYW5pemF0aW9uUm9sZU5hbWUsXG4gICAgICBwZXJtaXNzaW9uVHlwZTogcHJvcHMucGVybWlzc2lvblR5cGUsXG4gICAgICBwbHVnaW5BZG1pbkVuYWJsZWQ6IHByb3BzLnBsdWdpbkFkbWluRW5hYmxlZCxcbiAgICAgIHJvbGVBcm46IHByb3BzLnJvbGU/LnJvbGVBcm4sXG4gICAgICBzYW1sQ29uZmlndXJhdGlvbjogcHJvcHMuc2FtbENvbmZpZ3VyYXRpb24sXG4gICAgICBzdGFja1NldE5hbWU6IHByb3BzLnN0YWNrU2V0TmFtZSxcbiAgICAgIHZwY0NvbmZpZ3VyYXRpb246IHByb3BzLnZwY0NvbmZpZ3VyYXRpb25cbiAgICAgICAgPyB7XG4gICAgICAgICAgc2VjdXJpdHlHcm91cElkczogcHJvcHMudnBjQ29uZmlndXJhdGlvbi5zZWN1cml0eUdyb3Vwcy5tYXAoXG4gICAgICAgICAgICAoc2cpID0+IHNnLnNlY3VyaXR5R3JvdXBJZCxcbiAgICAgICAgICApLFxuICAgICAgICAgIHN1Ym5ldElkczogcHJvcHMudnBjQ29uZmlndXJhdGlvbi5zdWJuZXRzLm1hcChcbiAgICAgICAgICAgIChzdWJuZXQpID0+IHN1Ym5ldC5zdWJuZXRJZCxcbiAgICAgICAgICApLFxuICAgICAgICB9XG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgIH07XG5cbiAgICB0aGlzLndvcmtzcGFjZSA9IG5ldyBDZm5Xb3Jrc3BhY2UodGhpcywgJ1Jlc291cmNlJywgY2ZuV29ya3NwYWNlUHJvcHMpO1xuICAgIHRoaXMuY3JlYXRpb25UaW1lc3RhbXAgPSB0aGlzLndvcmtzcGFjZS5hdHRyQ3JlYXRpb25UaW1lc3RhbXA7XG4gICAgdGhpcy5lbmRwb2ludCA9IHRoaXMud29ya3NwYWNlLmF0dHJFbmRwb2ludDtcbiAgICB0aGlzLmdyYWZhbmFWZXJzaW9uID0gdGhpcy53b3Jrc3BhY2UuYXR0ckdyYWZhbmFWZXJzaW9uO1xuICAgIHRoaXMuaWQgPSB0aGlzLndvcmtzcGFjZS5hdHRySWQ7XG4gICAgdGhpcy5tb2RpZmljYXRpb25UaW1lc3RhbXAgPSB0aGlzLndvcmtzcGFjZS5hdHRyTW9kaWZpY2F0aW9uVGltZXN0YW1wO1xuICAgIHRoaXMuc2FtbENvbmZpZ3VyYXRpb25TdGF0dXMgPSB0aGlzLndvcmtzcGFjZVxuICAgICAgLmF0dHJTYW1sQ29uZmlndXJhdGlvblN0YXR1cyBhcyBTYW1sQ29uZmlndXJhdGlvblN0YXR1c2VzO1xuICAgIHRoaXMuc3NvQ2xpZW50SWQgPSB0aGlzLndvcmtzcGFjZS5hdHRyU3NvQ2xpZW50SWQ7XG4gICAgdGhpcy5zdGF0dXMgPSB0aGlzLndvcmtzcGFjZS5hdHRyU3RhdHVzIGFzIFN0YXR1cztcbiAgfVxufVxuIl19
|