@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.
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya3NwYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dvcmtzcGFjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQU1BLHlEQUEwRTtBQUUxRSwyQ0FBdUM7QUFFdkM7Ozs7O0dBS0c7QUFDSCxJQUFZLGlCQVVYO0FBVkQsV0FBWSxpQkFBaUI7SUFDM0I7O09BRUc7SUFDSCx3REFBbUMsQ0FBQTtJQUVuQzs7T0FFRztJQUNILGtEQUE2QixDQUFBO0FBQy9CLENBQUMsRUFWVyxpQkFBaUIsaUNBQWpCLGlCQUFpQixRQVU1QjtBQUVEOzs7OztHQUtHO0FBQ0gsSUFBWSx1QkFVWDtBQVZELFdBQVksdUJBQXVCO0lBQ2pDOztPQUVHO0lBQ0gsOENBQW1CLENBQUE7SUFFbkI7O09BRUc7SUFDSCx3Q0FBYSxDQUFBO0FBQ2YsQ0FBQyxFQVZXLHVCQUF1Qix1Q0FBdkIsdUJBQXVCLFFBVWxDO0FBMkJEOzs7R0FHRztBQUNILElBQVksd0JBS1g7QUFMRCxXQUFZLHdCQUF3QjtJQUNsQzs7T0FFRztJQUNILHVDQUFXLENBQUE7QUFDYixDQUFDLEVBTFcsd0JBQXdCLHdDQUF4Qix3QkFBd0IsUUFLbkM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsSUFBWSxlQVVYO0FBVkQsV0FBWSxlQUFlO0lBQ3pCOztPQUVHO0lBQ0gsd0RBQXFDLENBQUE7SUFFckM7O09BRUc7SUFDSCxzREFBbUMsQ0FBQTtBQUNyQyxDQUFDLEVBVlcsZUFBZSwrQkFBZixlQUFlLFFBVTFCO0FBK1BEOztHQUVHO0FBQ0gsSUFBWSx5QkFVWDtBQVZELFdBQVkseUJBQXlCO0lBQ25DOztPQUVHO0lBQ0gsc0RBQXlCLENBQUE7SUFFekI7O09BRUc7SUFDSCw4REFBaUMsQ0FBQTtBQUNuQyxDQUFDLEVBVlcseUJBQXlCLHlDQUF6Qix5QkFBeUIsUUFVcEM7QUFFRDs7R0FFRztBQUNILElBQVksTUF1RFg7QUF2REQsV0FBWSxNQUFNO0lBQ2hCOztPQUVHO0lBQ0gs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VyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDO1FBQ2xELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFvQixDQUFDO0lBQ3BELENBQUM7O0FBaHhCSCw4QkFpeEJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgSVByZWZpeExpc3QsXG4gIElTZWN1cml0eUdyb3VwLFxuICBJU3VibmV0LFxuICBJVnBjRW5kcG9pbnQsXG59IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lYzInO1xuaW1wb3J0IHsgQ2ZuV29ya3NwYWNlLCBDZm5Xb3Jrc3BhY2VQcm9wcyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1ncmFmYW5hJztcbmltcG9ydCB7IElSb2xlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqXG4gKiBTcGVjaWZpZXMgd2hldGhlciB0aGUgd29ya3NwYWNlIGNhbiBhY2Nlc3MgQVdTIHJlc291cmNlcyBpbiB0aGlzIEFXUyBhY2NvdW50IG9ubHksIG9yIHdoZXRoZXIgaXRcbiAqIGNhbiBhbHNvIGFjY2VzcyBBV1MgcmVzb3VyY2VzIGluIG90aGVyIGFjY291bnRzIGluIHRoZSBzYW1lIG9yZ2FuaXphdGlvbi4gSWYgdGhpcyBpc1xuICogT1JHQU5JWkFUSU9OLCB0aGUgT3JnYW5pemF0aW9uYWxVbml0cyBwYXJhbWV0ZXIgc3BlY2lmaWVzIHdoaWNoIG9yZ2FuaXphdGlvbmFsIHVuaXRzIHRoZVxuICogd29ya3NwYWNlIGNhbiBhY2Nlc3MuXG4gKi9cbmV4cG9ydCBlbnVtIEFjY291bnRBY2Nlc3NUeXBlIHtcbiAgLyoqXG4gICAqIEFjY2VzcyBpcyBsaW1pdGVkIHRvIHRoZSBjdXJyZW50IEFXUyBhY2NvdW50IG9ubHkuXG4gICAqL1xuICBDVVJSRU5UX0FDQ09VTlQgPSAnQ1VSUkVOVF9BQ0NPVU5UJyxcblxuICAvKipcbiAgICogQWNjZXNzIGlzIGV4dGVuZGVkIHRvIHRoZSBlbnRpcmUgQVdTIG9yZ2FuaXphdGlvbi5cbiAgICovXG4gIE9SR0FOSVpBVElPTiA9ICdPUkdBTklaQVRJT04nLFxufVxuXG4vKipcbiAqIFNwZWNpZmllcyB3aGV0aGVyIHRoaXMgd29ya3NwYWNlIHVzZXMgU0FNTCAyLjAsIEFXUyBJQU0gSWRlbnRpdHkgQ2VudGVyLCBvciBib3RoIHRvIGF1dGhlbnRpY2F0ZVxuICogdXNlcnMgZm9yIHVzaW5nIHRoZSBHcmFmYW5hIGNvbnNvbGUgd2l0aGluIGEgd29ya3NwYWNlLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dyYWZhbmEvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlV29ya3NwYWNlLmh0bWxcbiAqL1xuZXhwb3J0IGVudW0gQXV0aGVudGljYXRpb25Qcm92aWRlcnMge1xuICAvKipcbiAgICogQVdTIFNpbmdsZSBTaWduLU9uIGF1dGhlbnRpY2F0aW9uIHByb3ZpZGVyLlxuICAgKi9cbiAgQVdTX1NTTyA9ICdBV1NfU1NPJyxcblxuICAvKipcbiAgICogU2VjdXJpdHkgQXNzZXJ0aW9uIE1hcmt1cCBMYW5ndWFnZSAoU0FNTCkgYXV0aGVudGljYXRpb24gcHJvdmlkZXIuXG4gICAqL1xuICBTQU1MID0gJ1NBTUwnLFxufVxuXG4vKipcbiAqIFRoZSBjb25maWd1cmF0aW9uIHNldHRpbmdzIGZvciBuZXR3b3JrIGFjY2VzcyB0byB5b3VyIHdvcmtzcGFjZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOZXR3b3JrQWNjZXNzQ29udHJvbCB7XG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBwcmVmaXggbGlzdCBJRHMuIEEgcHJlZml4IGxpc3QgaXMgYSBsaXN0IG9mIENJRFIgcmFuZ2VzIG9mIElQIGFkZHJlc3Nlcy4gVGhlIElQXG4gICAqIGFkZHJlc3NlcyBzcGVjaWZpZWQgYXJlIGFsbG93ZWQgdG8gYWNjZXNzIHlvdXIgd29ya3NwYWNlLiBJZiB0aGUgbGlzdCBpcyBub3QgaW5jbHVkZWQgaW4gdGhlXG4gICAqIGNvbmZpZ3VyYXRpb24gKHBhc3NlZCBhbiBlbXB0eSBhcnJheSkgdGhlbiBubyBJUCBhZGRyZXNzZXMgYXJlIGFsbG93ZWQgdG8gYWNjZXNzIHRoZVxuICAgKiB3b3Jrc3BhY2UuXG4gICAqXG4gICAqIE1heGltdW0gb2YgNSBwcmVmaXggbGlzdHMgYWxsb3dlZC5cbiAgICovXG4gIHJlYWRvbmx5IHByZWZpeExpc3RzPzogSVByZWZpeExpc3RbXTtcblxuICAvKipcbiAgICogQW4gYXJyYXkgb2YgQW1hem9uIFZQQyBlbmRwb2ludCBJRHMgZm9yIHRoZSB3b3Jrc3BhY2UuIFlvdSBjYW4gY3JlYXRlIFZQQyBlbmRwb2ludHMgdG8geW91clxuICAgKiBBbWF6b24gTWFuYWdlZCBHcmFmYW5hIHdvcmtzcGFjZSBmb3IgYWNjZXNzIGZyb20gd2l0aGluIGEgVlBDLiBJZiBhIE5ldHdvcmtBY2Nlc3NDb25maWd1cmF0aW9uXG4gICAqIGlzIHNwZWNpZmllZCB0aGVuIG9ubHkgVlBDIGVuZHBvaW50cyBzcGVjaWZpZWQgaGVyZSBhcmUgYWxsb3dlZCB0byBhY2Nlc3MgdGhlIHdvcmtzcGFjZS4gSWZcbiAgICogeW91IHBhc3MgaW4gYW4gZW1wdHkgYXJyYXkgb2Ygc3RyaW5ncywgdGhlbiBubyBWUENzIGFyZSBhbGxvd2VkIHRvIGFjY2VzcyB0aGUgd29ya3NwYWNlLlxuICAgKlxuICAgKiBNYXhpbXVtIG9mIDUgVlBDIGVuZHBvaW50cyBhbGxvd2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjRW5kcG9pbnRzPzogSVZwY0VuZHBvaW50W107XG59XG5cbi8qKlxuICogVGhlIEFXUyBub3RpZmljYXRpb24gY2hhbm5lbHMgdGhhdCBBbWF6b24gTWFuYWdlZCBHcmFmYW5hIGNhbiBhdXRvbWF0aWNhbGx5IGNyZWF0ZSBJQU0gcm9sZXMgYW5kXG4gKiBwZXJtaXNzaW9ucyBmb3IsIHRvIGFsbG93IEFtYXpvbiBNYW5hZ2VkIEdyYWZhbmEgdG8gdXNlIHRoZXNlIGNoYW5uZWxzLlxuICovXG5leHBvcnQgZW51bSBOb3RpZmljYXRpb25EZXN0aW5hdGlvbnMge1xuICAvKipcbiAgICogQW1hem9uIFNpbXBsZSBOb3RpZmljYXRpb24gU2VydmljZSAoU05TKSBhcyBub3RpZmljYXRpb24gZGVzdGluYXRpb24uXG4gICAqL1xuICBTTlMgPSAnU05TJyxcbn1cblxuLyoqXG4gKiBJZiB0aGlzIGlzIFNFUlZJQ0VfTUFOQUdFRCwgYW5kIHRoZSB3b3JrcGxhY2Ugd2FzIGNyZWF0ZWQgdGhyb3VnaCB0aGUgQW1hem9uIE1hbmFnZWQgR3JhZmFuYVxuICogY29uc29sZSwgdGhlbiBBbWF6b24gTWFuYWdlZCBHcmFmYW5hIGF1dG9tYXRpY2FsbHkgY3JlYXRlcyB0aGUgSUFNIHJvbGVzIGFuZCBwcm92aXNpb25zIHRoZVxuICogcGVybWlzc2lvbnMgdGhhdCB0aGUgd29ya3NwYWNlIG5lZWRzIHRvIHVzZSBBV1MgZGF0YSBzb3VyY2VzIGFuZCBub3RpZmljYXRpb24gY2hhbm5lbHMuXG4gKlxuICogSWYgdGhpcyBpcyBDVVNUT01FUl9NQU5BR0VELCB5b3UgbXVzdCBtYW5hZ2UgdGhvc2Ugcm9sZXMgYW5kIHBlcm1pc3Npb25zIHlvdXJzZWxmLlxuXG4gKiBJZiB5b3UgYXJlIHdvcmtpbmcgd2l0aCBhIHdvcmtzcGFjZSBpbiBhIG1lbWJlciBhY2NvdW50IG9mIGFuIG9yZ2FuaXphdGlvbiBhbmQgdGhhdCBhY2NvdW50IGlzXG4gKiBub3QgYSBkZWxlZ2F0ZWQgYWRtaW5pc3RyYXRvciBhY2NvdW50LCBhbmQgeW91IHdhbnQgdGhlIHdvcmtzcGFjZSB0byBhY2Nlc3MgZGF0YSBzb3VyY2VzIGluXG4gKiBvdGhlciBBV1MgYWNjb3VudHMgaW4gdGhlIG9yZ2FuaXphdGlvbiwgdGhpcyBwYXJhbWV0ZXIgbXVzdCBiZSBzZXQgdG8gQ1VTVE9NRVJfTUFOQUdFRC5cbiAqL1xuZXhwb3J0IGVudW0gUGVybWlzc2lvblR5cGVzIHtcbiAgLyoqXG4gICAqIEN1c3RvbWVyLW1hbmFnZWQgcGVybWlzc2lvbnMgd2hlcmUgeW91IG1hbmFnZSB1c2VyIGFjY2VzcyB0byBHcmFmYW5hLlxuICAgKi9cbiAgQ1VTVE9NRVJfTUFOQUdFRCA9ICdDVVNUT01FUl9NQU5BR0VEJyxcblxuICAvKipcbiAgICogU2VydmljZS1tYW5hZ2VkIHBlcm1pc3Npb25zIHdoZXJlIEFXUyBtYW5hZ2VzIHVzZXIgYWNjZXNzIHRvIEdyYWZhbmEuXG4gICAqL1xuICBTRVJWSUNFX01BTkFHRUQgPSAnU0VSVklDRV9NQU5BR0VEJyxcbn1cblxuLyoqXG4gKiBBIHN0cnVjdHVyZSB0aGF0IGRlZmluZXMgd2hpY2ggYXR0cmlidXRlcyBpbiB0aGUgSWRQIGFzc2VydGlvbiBhcmUgdG8gYmUgdXNlZCB0byBkZWZpbmVcbiAqIGluZm9ybWF0aW9uIGFib3V0IHRoZSB1c2VycyBhdXRoZW50aWNhdGVkIGJ5IHRoZSBJZFAgdG8gdXNlIHRoZSB3b3Jrc3BhY2UuXG4gKlxuICogRWFjaCBhdHRyaWJ1dGUgbXVzdCBiZSBhIHN0cmluZyB3aXRoIGxlbmd0aCBiZXR3ZWVuIDEgYW5kIDI1NiBjaGFyYWN0ZXJzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNhbWxBc3NlcnRpb25BdHRyaWJ1dGVzIHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgd2l0aGluIHRoZSBTQU1MIGFzc2VydGlvbiB0byB1c2UgYXMgdGhlIGVtYWlsIG5hbWVzIGZvciBTQU1MIHVzZXJzLlxuICAgKlxuICAgKiBNdXN0IGJlIGJldHdlZW4gMSBhbmQgMjU2IGNoYXJhY3RlcnMgbG9uZy5cbiAgICovXG4gIHJlYWRvbmx5IGVtYWlsOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHdpdGhpbiB0aGUgU0FNTCBhc3NlcnRpb24gdG8gdXNlIGFzIHRoZSB1c2VyIGZ1bGwgXCJmcmllbmRseVwiIG5hbWVzXG4gICAqIGZvciB1c2VyIGdyb3Vwcy5cbiAgICpcbiAgICogTXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDI1NiBjaGFyYWN0ZXJzIGxvbmcuXG4gICAqL1xuICByZWFkb25seSBncm91cHM6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgd2l0aGluIHRoZSBTQU1MIGFzc2VydGlvbiB0byB1c2UgYXMgdGhlIGxvZ2luIG5hbWVzIGZvciBTQU1MIHVzZXJzLlxuICAgKlxuICAgKiBNdXN0IGJlIGJldHdlZW4gMSBhbmQgMjU2IGNoYXJhY3RlcnMgbG9uZy5cbiAgICovXG4gIHJlYWRvbmx5IGxvZ2luOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHdpdGhpbiB0aGUgU0FNTCBhc3NlcnRpb24gdG8gdXNlIGFzIHRoZSB1c2VyIGZ1bGwgXCJmcmllbmRseVwiIG5hbWVzXG4gICAqIGZvciBTQU1MIHVzZXJzLlxuICAgKlxuICAgKiBNdXN0IGJlIGJldHdlZW4gMSBhbmQgMjU2IGNoYXJhY3RlcnMgbG9uZy5cbiAgICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgd2l0aGluIHRoZSBTQU1MIGFzc2VydGlvbiB0byB1c2UgYXMgdGhlIHVzZXIgZnVsbCBcImZyaWVuZGx5XCIgbmFtZXNcbiAgICogZm9yIHRoZSB1c2Vycycgb3JnYW5pemF0aW9ucy5cbiAgICpcbiAgICogTXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDI1NiBjaGFyYWN0ZXJzIGxvbmcuXG4gICAqL1xuICByZWFkb25seSBvcmc6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgd2l0aGluIHRoZSBTQU1MIGFzc2VydGlvbiB0byB1c2UgYXMgdGhlIHVzZXIgcm9sZXMuXG4gICAqXG4gICAqIE11c3QgYmUgYmV0d2VlbiAxIGFuZCAyNTYgY2hhcmFjdGVycyBsb25nLlxuICAgKi9cbiAgcmVhZG9ubHkgcm9sZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgc3RydWN0dXJlIGNvbnRhaW5pbmcgdGhlIGlkZW50aXR5IHByb3ZpZGVyIChJZFApIG1ldGFkYXRhIHVzZWQgdG8gaW50ZWdyYXRlIHRoZSBpZGVudGl0eVxuICogcHJvdmlkZXIgd2l0aCB0aGlzIHdvcmtzcGFjZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTYW1sSWRwTWV0YWRhdGEge1xuICAvKipcbiAgICogVGhlIFVSTCBvZiB0aGUgbG9jYXRpb24gY29udGFpbmluZyB0aGUgSWRQIG1ldGFkYXRhLlxuICAgKlxuICAgKiBNdXN0IGJlIGEgc3RyaW5nIHdpdGggbGVuZ3RoIGJldHdlZW4gMSBhbmQgMjA0OCBjaGFyYWN0ZXJzLlxuICAgKi9cbiAgcmVhZG9ubHkgdXJsPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZnVsbCBJZFAgbWV0YWRhdGEsIGluIFhNTCBmb3JtYXQuXG4gICAqL1xuICByZWFkb25seSB4bWw/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