cdk8s-plus-32 2.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.
Files changed (113) hide show
  1. package/.jsii +90710 -0
  2. package/CODE_OF_CONDUCT.md +3 -0
  3. package/CONTRIBUTING.md +185 -0
  4. package/DCO +34 -0
  5. package/LICENSE +202 -0
  6. package/NOTICE +1 -0
  7. package/OWNERS.md +5 -0
  8. package/README.md +32 -0
  9. package/SECURITY.md +5 -0
  10. package/cdk8s.yaml +9 -0
  11. package/docs/java.md +24089 -0
  12. package/docs/plus/config-map.md +98 -0
  13. package/docs/plus/container.md +133 -0
  14. package/docs/plus/cronjob.md +67 -0
  15. package/docs/plus/deployment.md +232 -0
  16. package/docs/plus/horizontal-pod-autoscaler.md +226 -0
  17. package/docs/plus/ingress.md +68 -0
  18. package/docs/plus/job.md +48 -0
  19. package/docs/plus/namespace.md +58 -0
  20. package/docs/plus/network-policy.md +341 -0
  21. package/docs/plus/pod.md +455 -0
  22. package/docs/plus/pv.md +82 -0
  23. package/docs/plus/pvc.md +77 -0
  24. package/docs/plus/rbac.md +104 -0
  25. package/docs/plus/secret.md +32 -0
  26. package/docs/plus/service-account.md +35 -0
  27. package/docs/plus/service.md +41 -0
  28. package/docs/plus/volume.md +38 -0
  29. package/docs/python.md +26313 -0
  30. package/docs/typescript.md +19695 -0
  31. package/git-hooks/README.md +9 -0
  32. package/git-hooks/prepare-commit-msg +18 -0
  33. package/git-hooks/setup.sh +10 -0
  34. package/lib/_action.d.ts +21 -0
  35. package/lib/_action.js +32 -0
  36. package/lib/api-resource.d.ts +298 -0
  37. package/lib/api-resource.js +430 -0
  38. package/lib/base.d.ts +79 -0
  39. package/lib/base.js +92 -0
  40. package/lib/config-map.d.ts +126 -0
  41. package/lib/config-map.js +159 -0
  42. package/lib/container.d.ts +1057 -0
  43. package/lib/container.js +845 -0
  44. package/lib/cron-job.d.ts +138 -0
  45. package/lib/cron-job.js +103 -0
  46. package/lib/daemon-set.d.ts +45 -0
  47. package/lib/daemon-set.js +55 -0
  48. package/lib/deployment.d.ts +223 -0
  49. package/lib/deployment.js +214 -0
  50. package/lib/handler.d.ts +62 -0
  51. package/lib/handler.js +54 -0
  52. package/lib/horizontal-pod-autoscaler.d.ts +500 -0
  53. package/lib/horizontal-pod-autoscaler.js +569 -0
  54. package/lib/imports/k8s.d.ts +21811 -0
  55. package/lib/imports/k8s.js +16678 -0
  56. package/lib/index.d.ts +26 -0
  57. package/lib/index.js +44 -0
  58. package/lib/ingress.d.ts +230 -0
  59. package/lib/ingress.js +246 -0
  60. package/lib/job.d.ts +64 -0
  61. package/lib/job.js +54 -0
  62. package/lib/namespace.d.ts +128 -0
  63. package/lib/namespace.js +109 -0
  64. package/lib/network-policy.d.ts +311 -0
  65. package/lib/network-policy.js +344 -0
  66. package/lib/pod.d.ts +1088 -0
  67. package/lib/pod.js +1141 -0
  68. package/lib/probe.d.ts +141 -0
  69. package/lib/probe.js +77 -0
  70. package/lib/pv.d.ts +375 -0
  71. package/lib/pv.js +273 -0
  72. package/lib/pvc.d.ts +163 -0
  73. package/lib/pvc.js +152 -0
  74. package/lib/role-binding.d.ts +138 -0
  75. package/lib/role-binding.js +165 -0
  76. package/lib/role.d.ts +268 -0
  77. package/lib/role.js +401 -0
  78. package/lib/secret.d.ts +195 -0
  79. package/lib/secret.js +185 -0
  80. package/lib/service-account.d.ts +83 -0
  81. package/lib/service-account.js +105 -0
  82. package/lib/service.d.ts +289 -0
  83. package/lib/service.js +182 -0
  84. package/lib/stateful-set.d.ts +169 -0
  85. package/lib/stateful-set.js +174 -0
  86. package/lib/utils.d.ts +4 -0
  87. package/lib/utils.js +33 -0
  88. package/lib/volume.d.ts +573 -0
  89. package/lib/volume.js +371 -0
  90. package/lib/workload.d.ts +121 -0
  91. package/lib/workload.js +122 -0
  92. package/node_modules/balanced-match/.github/FUNDING.yml +2 -0
  93. package/node_modules/balanced-match/LICENSE.md +21 -0
  94. package/node_modules/balanced-match/README.md +97 -0
  95. package/node_modules/balanced-match/index.js +62 -0
  96. package/node_modules/balanced-match/package.json +48 -0
  97. package/node_modules/concat-map/.travis.yml +4 -0
  98. package/node_modules/concat-map/LICENSE +18 -0
  99. package/node_modules/concat-map/README.markdown +62 -0
  100. package/node_modules/concat-map/example/map.js +6 -0
  101. package/node_modules/concat-map/index.js +13 -0
  102. package/node_modules/concat-map/package.json +43 -0
  103. package/node_modules/concat-map/test/map.js +39 -0
  104. package/node_modules/minimatch/LICENSE +15 -0
  105. package/node_modules/minimatch/README.md +230 -0
  106. package/node_modules/minimatch/minimatch.js +947 -0
  107. package/node_modules/minimatch/node_modules/brace-expansion/LICENSE +21 -0
  108. package/node_modules/minimatch/node_modules/brace-expansion/README.md +129 -0
  109. package/node_modules/minimatch/node_modules/brace-expansion/index.js +201 -0
  110. package/node_modules/minimatch/node_modules/brace-expansion/package.json +47 -0
  111. package/node_modules/minimatch/package.json +33 -0
  112. package/package.json +181 -0
  113. package/rotate.md +84 -0
package/lib/pod.js ADDED
@@ -0,0 +1,1141 @@
1
+ "use strict";
2
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PodConnections = exports.PodConnectionsIsolation = exports.PodScheduling = exports.Topology = exports.Node = exports.NamedNode = exports.TaintedNode = exports.LabeledNode = exports.Pods = exports.NodeTaintQuery = exports.TaintEffect = exports.LabelExpression = exports.NodeLabelQuery = exports.DnsPolicy = exports.FsGroupChangePolicy = exports.RestartPolicy = exports.PodSecurityContext = exports.PodDns = exports.Pod = exports.LabelSelector = exports.AbstractPod = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const cdk8s_1 = require("cdk8s");
7
+ const constructs_1 = require("constructs");
8
+ const base = require("./base");
9
+ const container = require("./container");
10
+ const k8s = require("./imports/k8s");
11
+ const networkpolicy = require("./network-policy");
12
+ const utils_1 = require("./utils");
13
+ class AbstractPod extends base.Resource {
14
+ constructor(scope, id, props = {}) {
15
+ super(scope, id);
16
+ this._containers = [];
17
+ this._initContainers = [];
18
+ this._hostAliases = [];
19
+ this._volumes = new Map();
20
+ this.restartPolicy = props.restartPolicy ?? RestartPolicy.ALWAYS;
21
+ this.serviceAccount = props.serviceAccount;
22
+ this.securityContext = new PodSecurityContext(props.securityContext);
23
+ this.dns = new PodDns(props.dns);
24
+ this.dockerRegistryAuth = props.dockerRegistryAuth;
25
+ this.automountServiceAccountToken = props.automountServiceAccountToken ?? false;
26
+ this.shareProcessNamespace = props.shareProcessNamespace ?? false;
27
+ this.isolate = props.isolate ?? false;
28
+ this.hostNetwork = props.hostNetwork ?? false;
29
+ this.terminationGracePeriod = props.terminationGracePeriod ?? cdk8s_1.Duration.seconds(30);
30
+ if (props.containers) {
31
+ props.containers.forEach(c => this.addContainer(c));
32
+ }
33
+ if (props.volumes) {
34
+ props.volumes.forEach(v => this.addVolume(v));
35
+ }
36
+ if (props.initContainers) {
37
+ props.initContainers.forEach(c => this.addInitContainer(c));
38
+ }
39
+ if (props.hostAliases) {
40
+ props.hostAliases.forEach(c => this.addHostAlias(c));
41
+ }
42
+ }
43
+ get containers() {
44
+ return [...this._containers];
45
+ }
46
+ get initContainers() {
47
+ return [...this._initContainers];
48
+ }
49
+ get volumes() {
50
+ return Array.from(this._volumes.values());
51
+ }
52
+ get hostAliases() {
53
+ return [...this._hostAliases];
54
+ }
55
+ /**
56
+ * @see IPodSelector.toPodSelectorConfig()
57
+ */
58
+ toPodSelectorConfig() {
59
+ const podAddress = this.podMetadata.getLabel(Pod.ADDRESS_LABEL);
60
+ if (!podAddress) {
61
+ // shouldn't happen because we add this label automatically in both pods and workloads.
62
+ throw new Error(`Unable to create a label selector since ${Pod.ADDRESS_LABEL} label is missing`);
63
+ }
64
+ return {
65
+ labelSelector: LabelSelector.of({ labels: { [Pod.ADDRESS_LABEL]: podAddress } }),
66
+ namespaces: this.metadata.namespace ? {
67
+ names: [this.metadata.namespace],
68
+ } : undefined,
69
+ };
70
+ }
71
+ /**
72
+ * @see INetworkPolicyPeer.toNetworkPolicyPeerConfig()
73
+ */
74
+ toNetworkPolicyPeerConfig() {
75
+ return { podSelector: this.toPodSelectorConfig() };
76
+ }
77
+ /**
78
+ * @see INetworkPolicyPeer.toPodSelector()
79
+ */
80
+ toPodSelector() {
81
+ return this;
82
+ }
83
+ addContainer(cont) {
84
+ const impl = new container.Container(cont);
85
+ this.attachContainer(impl);
86
+ return impl;
87
+ }
88
+ attachContainer(cont) {
89
+ this._containers.push(cont);
90
+ }
91
+ addInitContainer(cont) {
92
+ // https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#differences-from-regular-containers
93
+ if (!this.isSidecarContainer(cont) && cont.readiness) {
94
+ throw new Error('Init containers must not have a readiness probe');
95
+ }
96
+ if (!this.isSidecarContainer(cont) && cont.liveness) {
97
+ throw new Error('Init containers must not have a liveness probe');
98
+ }
99
+ if (!this.isSidecarContainer(cont) && cont.startup) {
100
+ throw new Error('Init containers must not have a startup probe');
101
+ }
102
+ const impl = new container.Container({
103
+ ...cont,
104
+ name: cont.name ?? `init-${this._initContainers.length}`,
105
+ });
106
+ this._initContainers.push(impl);
107
+ return impl;
108
+ }
109
+ // Any initContainer that has `restartPolicy=Always` is a sidecar container. Please refer to
110
+ // documentation for more details:
111
+ // https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/#differences-from-init-containers
112
+ isSidecarContainer(cont) {
113
+ return cont.restartPolicy === container.ContainerRestartPolicy.ALWAYS;
114
+ }
115
+ addHostAlias(hostAlias) {
116
+ this._hostAliases.push(hostAlias);
117
+ }
118
+ addVolume(vol) {
119
+ const existingVolume = this._volumes.get(vol.name);
120
+ if (existingVolume) {
121
+ throw new Error(`Volume with name ${vol.name} already exists`);
122
+ }
123
+ this._volumes.set(vol.name, vol);
124
+ }
125
+ /**
126
+ * @see ISubect.toSubjectConfiguration()
127
+ */
128
+ toSubjectConfiguration() {
129
+ if (!this.serviceAccount && !this.automountServiceAccountToken) {
130
+ throw new Error(`${this.name} cannot be converted to a role binding subject:`
131
+ + ' You must either assign a service account to it, or use \'automountServiceAccountToken: true\'');
132
+ }
133
+ // 'default' is assumed to be the name of the default service account
134
+ // in the cluster.
135
+ const serviceAccountName = this.serviceAccount?.name ?? 'default';
136
+ return {
137
+ kind: 'ServiceAccount',
138
+ name: serviceAccountName,
139
+ apiGroup: '',
140
+ };
141
+ }
142
+ /**
143
+ * @internal
144
+ */
145
+ _toPodSpec() {
146
+ if (this.containers.length === 0) {
147
+ throw new Error('PodSpec must have at least 1 container');
148
+ }
149
+ const volumes = new Map();
150
+ const containers = [];
151
+ const initContainers = [];
152
+ for (const cont of this.containers) {
153
+ // check if restartPolicy is defined for containers
154
+ if (cont.restartPolicy) {
155
+ throw new Error(`Invalid container spec: ${cont.name} has non-empty restartPolicy field. The field can only be specified for initContainers`);
156
+ }
157
+ // automatically add volume from the container mount
158
+ // to this pod so thats its available to the container.
159
+ for (const mount of cont.mounts) {
160
+ addVolume(mount.volume);
161
+ }
162
+ containers.push(cont._toKube());
163
+ }
164
+ for (const cont of this.initContainers) {
165
+ // automatically add volume from the container mount
166
+ // to this pod so thats its available to the container.
167
+ for (const mount of cont.mounts) {
168
+ addVolume(mount.volume);
169
+ }
170
+ initContainers.push(cont._toKube());
171
+ }
172
+ for (const vol of this.volumes) {
173
+ addVolume(vol);
174
+ }
175
+ function addVolume(vol) {
176
+ const existingVolume = volumes.get(vol.name);
177
+ // its ok to call this function twice on the same volume, but its not ok to
178
+ // call it twice on a different volume with the same name.
179
+ if (existingVolume && existingVolume !== vol) {
180
+ throw new Error(`Invalid mount configuration. At least two different volumes have the same name: ${vol.name}`);
181
+ }
182
+ volumes.set(vol.name, vol);
183
+ }
184
+ const dns = this.dns._toKube();
185
+ return {
186
+ restartPolicy: this.restartPolicy,
187
+ serviceAccountName: this.serviceAccount?.name,
188
+ containers: containers,
189
+ securityContext: (0, utils_1.undefinedIfEmpty)(this.securityContext._toKube()),
190
+ initContainers: (0, utils_1.undefinedIfEmpty)(initContainers),
191
+ hostAliases: (0, utils_1.undefinedIfEmpty)(this.hostAliases),
192
+ volumes: (0, utils_1.undefinedIfEmpty)(Array.from(volumes.values()).map(v => v._toKube())),
193
+ dnsPolicy: dns.policy,
194
+ dnsConfig: (0, utils_1.undefinedIfEmpty)(dns.config),
195
+ hostname: dns.hostname,
196
+ subdomain: dns.subdomain,
197
+ setHostnameAsFqdn: dns.hostnameAsFQDN,
198
+ imagePullSecrets: this.dockerRegistryAuth ? [{ name: this.dockerRegistryAuth.name }] : undefined,
199
+ automountServiceAccountToken: this.automountServiceAccountToken,
200
+ shareProcessNamespace: this.shareProcessNamespace,
201
+ hostNetwork: this.hostNetwork,
202
+ terminationGracePeriodSeconds: this.terminationGracePeriod?.toSeconds(),
203
+ };
204
+ }
205
+ }
206
+ exports.AbstractPod = AbstractPod;
207
+ _a = JSII_RTTI_SYMBOL_1;
208
+ AbstractPod[_a] = { fqn: "cdk8s-plus-32.AbstractPod", version: "2.0.0" };
209
+ /**
210
+ * Match a resource by labels.
211
+ */
212
+ class LabelSelector {
213
+ static of(options = {}) {
214
+ return new LabelSelector(options.expressions ?? [], options.labels ?? {});
215
+ }
216
+ constructor(expressions, labels) {
217
+ this.expressions = expressions;
218
+ this.labels = labels;
219
+ }
220
+ isEmpty() {
221
+ return this.expressions.length === 0 && Object.keys(this.labels).length === 0;
222
+ }
223
+ /**
224
+ * @internal
225
+ */
226
+ _toKube() {
227
+ if (this.isEmpty()) {
228
+ return {};
229
+ }
230
+ return {
231
+ matchExpressions: (0, utils_1.undefinedIfEmpty)(this.expressions.map(q => ({ key: q.key, operator: q.operator, values: q.values }))),
232
+ matchLabels: (0, utils_1.undefinedIfEmpty)(this.labels),
233
+ };
234
+ }
235
+ }
236
+ exports.LabelSelector = LabelSelector;
237
+ _b = JSII_RTTI_SYMBOL_1;
238
+ LabelSelector[_b] = { fqn: "cdk8s-plus-32.LabelSelector", version: "2.0.0" };
239
+ /**
240
+ * Pod is a collection of containers that can run on a host. This resource is
241
+ * created by clients and scheduled onto hosts.
242
+ */
243
+ class Pod extends AbstractPod {
244
+ constructor(scope, id, props = {}) {
245
+ super(scope, id, props);
246
+ this.resourceType = 'pods';
247
+ this.apiObject = new k8s.KubePod(this, 'Resource', {
248
+ metadata: props.metadata,
249
+ spec: cdk8s_1.Lazy.any({ produce: () => this._toKube() }),
250
+ });
251
+ this.metadata.addLabel(Pod.ADDRESS_LABEL, cdk8s_1.Names.toLabelValue(this));
252
+ this.scheduling = new PodScheduling(this);
253
+ this.connections = new PodConnections(this);
254
+ if (this.isolate) {
255
+ this.connections.isolate();
256
+ }
257
+ }
258
+ get podMetadata() {
259
+ return this.metadata;
260
+ }
261
+ /**
262
+ * @internal
263
+ */
264
+ _toKube() {
265
+ const scheduling = this.scheduling._toKube();
266
+ return {
267
+ ...this._toPodSpec(),
268
+ affinity: scheduling.affinity,
269
+ nodeName: scheduling.nodeName,
270
+ tolerations: scheduling.tolerations,
271
+ };
272
+ }
273
+ }
274
+ exports.Pod = Pod;
275
+ _c = JSII_RTTI_SYMBOL_1;
276
+ Pod[_c] = { fqn: "cdk8s-plus-32.Pod", version: "2.0.0" };
277
+ /**
278
+ * This label is autoamtically added by cdk8s to any pod. It provides
279
+ * a unique and stable identifier for the pod.
280
+ */
281
+ Pod.ADDRESS_LABEL = 'cdk8s.io/metadata.addr';
282
+ /**
283
+ * Holds dns settings of the pod.
284
+ */
285
+ class PodDns {
286
+ constructor(props = {}) {
287
+ this.hostname = props.hostname;
288
+ this.subdomain = props.subdomain;
289
+ this.policy = props.policy ?? DnsPolicy.CLUSTER_FIRST;
290
+ this.hostnameAsFQDN = props.hostnameAsFQDN ?? false;
291
+ this._nameservers = props.nameservers ?? [];
292
+ this._searches = props.searches ?? [];
293
+ this._options = props.options ?? [];
294
+ }
295
+ /**
296
+ * Nameservers defined for this pod.
297
+ */
298
+ get nameservers() {
299
+ return [...this._nameservers];
300
+ }
301
+ /**
302
+ * Search domains defined for this pod.
303
+ */
304
+ get searches() {
305
+ return [...this._searches];
306
+ }
307
+ /**
308
+ * Custom dns options defined for this pod.
309
+ */
310
+ get options() {
311
+ return [...this._options];
312
+ }
313
+ /**
314
+ * Add a nameserver.
315
+ */
316
+ addNameserver(...nameservers) {
317
+ this._nameservers.push(...nameservers);
318
+ }
319
+ /**
320
+ * Add a search domain.
321
+ */
322
+ addSearch(...searches) {
323
+ this._searches.push(...searches);
324
+ }
325
+ /**
326
+ * Add a custom option.
327
+ */
328
+ addOption(...options) {
329
+ this._options.push(...options);
330
+ }
331
+ /**
332
+ * @internal
333
+ */
334
+ _toKube() {
335
+ if (this.policy === DnsPolicy.NONE && this.nameservers.length === 0) {
336
+ throw new Error('When dns policy is set to NONE, at least one nameserver is required');
337
+ }
338
+ if (this.nameservers.length > 3) {
339
+ throw new Error('There can be at most 3 nameservers specified');
340
+ }
341
+ if (this.searches.length > 6) {
342
+ throw new Error('There can be at most 6 search domains specified');
343
+ }
344
+ return {
345
+ hostname: this.hostname,
346
+ subdomain: this.subdomain,
347
+ hostnameAsFQDN: this.hostnameAsFQDN,
348
+ policy: this.policy,
349
+ config: {
350
+ nameservers: (0, utils_1.undefinedIfEmpty)(this.nameservers),
351
+ searches: (0, utils_1.undefinedIfEmpty)(this.searches),
352
+ options: (0, utils_1.undefinedIfEmpty)(this.options),
353
+ },
354
+ };
355
+ }
356
+ }
357
+ exports.PodDns = PodDns;
358
+ _d = JSII_RTTI_SYMBOL_1;
359
+ PodDns[_d] = { fqn: "cdk8s-plus-32.PodDns", version: "2.0.0" };
360
+ /**
361
+ * Holds pod-level security attributes and common container settings.
362
+ */
363
+ class PodSecurityContext {
364
+ constructor(props = {}) {
365
+ this._sysctls = [];
366
+ this.ensureNonRoot = props.ensureNonRoot ?? true;
367
+ this.fsGroupChangePolicy = props.fsGroupChangePolicy ?? FsGroupChangePolicy.ALWAYS;
368
+ this.user = props.user;
369
+ this.group = props.group;
370
+ this.fsGroup = props.fsGroup;
371
+ for (const sysctl of props.sysctls ?? []) {
372
+ this._sysctls.push(sysctl);
373
+ }
374
+ }
375
+ get sysctls() {
376
+ return [...this._sysctls];
377
+ }
378
+ /**
379
+ * @internal
380
+ */
381
+ _toKube() {
382
+ return {
383
+ runAsGroup: this.group,
384
+ runAsUser: this.user,
385
+ fsGroup: this.fsGroup,
386
+ runAsNonRoot: this.ensureNonRoot,
387
+ fsGroupChangePolicy: this.fsGroupChangePolicy,
388
+ sysctls: (0, utils_1.undefinedIfEmpty)(this._sysctls),
389
+ };
390
+ }
391
+ }
392
+ exports.PodSecurityContext = PodSecurityContext;
393
+ _e = JSII_RTTI_SYMBOL_1;
394
+ PodSecurityContext[_e] = { fqn: "cdk8s-plus-32.PodSecurityContext", version: "2.0.0" };
395
+ /**
396
+ * Restart policy for all containers within the pod.
397
+ */
398
+ var RestartPolicy;
399
+ (function (RestartPolicy) {
400
+ /**
401
+ * Always restart the pod after it exits.
402
+ */
403
+ RestartPolicy["ALWAYS"] = "Always";
404
+ /**
405
+ * Only restart if the pod exits with a non-zero exit code.
406
+ */
407
+ RestartPolicy["ON_FAILURE"] = "OnFailure";
408
+ /**
409
+ * Never restart the pod.
410
+ */
411
+ RestartPolicy["NEVER"] = "Never";
412
+ })(RestartPolicy || (exports.RestartPolicy = RestartPolicy = {}));
413
+ var FsGroupChangePolicy;
414
+ (function (FsGroupChangePolicy) {
415
+ /**
416
+ * Only change permissions and ownership if permission and ownership of root directory does
417
+ * not match with expected permissions of the volume.
418
+ * This could help shorten the time it takes to change ownership and permission of a volume
419
+ */
420
+ FsGroupChangePolicy["ON_ROOT_MISMATCH"] = "OnRootMismatch";
421
+ /**
422
+ * Always change permission and ownership of the volume when volume is mounted.
423
+ */
424
+ FsGroupChangePolicy["ALWAYS"] = "Always";
425
+ })(FsGroupChangePolicy || (exports.FsGroupChangePolicy = FsGroupChangePolicy = {}));
426
+ /**
427
+ * Pod DNS policies.
428
+ */
429
+ var DnsPolicy;
430
+ (function (DnsPolicy) {
431
+ /**
432
+ * Any DNS query that does not match the configured cluster domain suffix,
433
+ * such as "www.kubernetes.io", is forwarded to the
434
+ * upstream nameserver inherited from the node.
435
+ * Cluster administrators may have extra stub-domain and upstream DNS servers configured.
436
+ */
437
+ DnsPolicy["CLUSTER_FIRST"] = "ClusterFirst";
438
+ /**
439
+ * For Pods running with hostNetwork, you should
440
+ * explicitly set its DNS policy "ClusterFirstWithHostNet".
441
+ */
442
+ DnsPolicy["CLUSTER_FIRST_WITH_HOST_NET"] = "ClusterFirstWithHostNet";
443
+ /**
444
+ * The Pod inherits the name resolution configuration
445
+ * from the node that the pods run on.
446
+ */
447
+ DnsPolicy["DEFAULT"] = "Default";
448
+ /**
449
+ * It allows a Pod to ignore DNS settings from the Kubernetes environment.
450
+ * All DNS settings are supposed to be provided using the dnsConfig
451
+ * field in the Pod Spec.
452
+ */
453
+ DnsPolicy["NONE"] = "None";
454
+ })(DnsPolicy || (exports.DnsPolicy = DnsPolicy = {}));
455
+ /**
456
+ * Represents a query that can be performed against nodes with labels.
457
+ */
458
+ class NodeLabelQuery {
459
+ /**
460
+ * Requires value of label `key` to equal `value`.
461
+ */
462
+ static is(key, value) {
463
+ return NodeLabelQuery.in(key, [value]);
464
+ }
465
+ /**
466
+ * Requires value of label `key` to be one of `values`.
467
+ */
468
+ static in(key, values) {
469
+ return new NodeLabelQuery(key, 'In', values);
470
+ }
471
+ /**
472
+ * Requires value of label `key` to be none of `values`.
473
+ */
474
+ static notIn(key, values) {
475
+ return new NodeLabelQuery(key, 'NotIn', values);
476
+ }
477
+ /**
478
+ * Requires label `key` to exist.
479
+ */
480
+ static exists(key) {
481
+ return new NodeLabelQuery(key, 'Exists', undefined);
482
+ }
483
+ /**
484
+ * Requires label `key` to not exist.
485
+ */
486
+ static doesNotExist(key) {
487
+ return new NodeLabelQuery(key, 'DoesNotExist', undefined);
488
+ }
489
+ /**
490
+ * Requires value of label `key` to greater than all elements in `values`.
491
+ */
492
+ static gt(key, values) {
493
+ return new NodeLabelQuery(key, 'Gt', values);
494
+ }
495
+ /**
496
+ * Requires value of label `key` to less than all elements in `values`.
497
+ */
498
+ static lt(key, values) {
499
+ return new NodeLabelQuery(key, 'Lt', values);
500
+ }
501
+ constructor(key, operator, values) {
502
+ this.key = key;
503
+ this.operator = operator;
504
+ this.values = values;
505
+ }
506
+ /**
507
+ * @internal
508
+ */
509
+ _toKube() {
510
+ return {
511
+ key: this.key,
512
+ operator: this.operator,
513
+ values: this.values,
514
+ };
515
+ }
516
+ }
517
+ exports.NodeLabelQuery = NodeLabelQuery;
518
+ _f = JSII_RTTI_SYMBOL_1;
519
+ NodeLabelQuery[_f] = { fqn: "cdk8s-plus-32.NodeLabelQuery", version: "2.0.0" };
520
+ /**
521
+ * Represents a query that can be performed against resources with labels.
522
+ */
523
+ class LabelExpression {
524
+ /**
525
+ * Requires value of label `key` to be one of `values`.
526
+ */
527
+ static in(key, values) {
528
+ return new LabelExpression(key, 'In', values);
529
+ }
530
+ /**
531
+ * Requires value of label `key` to be none of `values`.
532
+ */
533
+ static notIn(key, values) {
534
+ return new LabelExpression(key, 'NotIn', values);
535
+ }
536
+ /**
537
+ * Requires label `key` to exist.
538
+ */
539
+ static exists(key) {
540
+ return new LabelExpression(key, 'Exists', undefined);
541
+ }
542
+ /**
543
+ * Requires label `key` to not exist.
544
+ */
545
+ static doesNotExist(key) {
546
+ return new LabelExpression(key, 'DoesNotExist', undefined);
547
+ }
548
+ constructor(key, operator, values) {
549
+ this.key = key;
550
+ this.operator = operator;
551
+ this.values = values;
552
+ }
553
+ }
554
+ exports.LabelExpression = LabelExpression;
555
+ _g = JSII_RTTI_SYMBOL_1;
556
+ LabelExpression[_g] = { fqn: "cdk8s-plus-32.LabelExpression", version: "2.0.0" };
557
+ /**
558
+ * Taint effects.
559
+ */
560
+ var TaintEffect;
561
+ (function (TaintEffect) {
562
+ /**
563
+ * This means that no pod will be able to schedule
564
+ * onto the node unless it has a matching toleration.
565
+ */
566
+ TaintEffect["NO_SCHEDULE"] = "NoSchedule";
567
+ /**
568
+ * This is a "preference" or "soft" version of `NO_SCHEDULE` -- the system
569
+ * will try to avoid placing a pod that does not tolerate the taint on the node,
570
+ * but it is not required
571
+ */
572
+ TaintEffect["PREFER_NO_SCHEDULE"] = "PreferNoSchedule";
573
+ /**
574
+ * This affects pods that are already running on the node as follows:
575
+ *
576
+ * - Pods that do not tolerate the taint are evicted immediately.
577
+ * - Pods that tolerate the taint without specifying `duration` remain bound forever.
578
+ * - Pods that tolerate the taint with a specified `duration` remain bound for
579
+ * the specified amount of time.
580
+ */
581
+ TaintEffect["NO_EXECUTE"] = "NoExecute";
582
+ })(TaintEffect || (exports.TaintEffect = TaintEffect = {}));
583
+ /**
584
+ * Taint queries that can be perfomed against nodes.
585
+ */
586
+ class NodeTaintQuery {
587
+ /**
588
+ * Matches a taint with a specific key and value.
589
+ */
590
+ static is(key, value, options = {}) {
591
+ return new NodeTaintQuery('Equal', key, value, options.effect, options.evictAfter);
592
+ }
593
+ /**
594
+ * Matches a tain with any value of a specific key.
595
+ */
596
+ static exists(key, options = {}) {
597
+ return new NodeTaintQuery('Exists', key, undefined, options.effect, options.evictAfter);
598
+ }
599
+ /**
600
+ * Matches any taint.
601
+ */
602
+ static any() {
603
+ return new NodeTaintQuery('Exists');
604
+ }
605
+ constructor(operator, key, value, effect, evictAfter) {
606
+ this.operator = operator;
607
+ this.key = key;
608
+ this.value = value;
609
+ this.effect = effect;
610
+ this.evictAfter = evictAfter;
611
+ if (evictAfter && effect !== TaintEffect.NO_EXECUTE) {
612
+ throw new Error('Only \'NO_EXECUTE\' effects can specify \'evictAfter\'');
613
+ }
614
+ }
615
+ /**
616
+ * @internal
617
+ */
618
+ _toKube() {
619
+ return {
620
+ effect: this.effect,
621
+ key: this.key,
622
+ operator: this.operator,
623
+ tolerationSeconds: this.evictAfter?.toSeconds(),
624
+ value: this.value,
625
+ };
626
+ }
627
+ }
628
+ exports.NodeTaintQuery = NodeTaintQuery;
629
+ _h = JSII_RTTI_SYMBOL_1;
630
+ NodeTaintQuery[_h] = { fqn: "cdk8s-plus-32.NodeTaintQuery", version: "2.0.0" };
631
+ /**
632
+ * Represents a group of pods.
633
+ */
634
+ class Pods extends constructs_1.Construct {
635
+ /**
636
+ * Select pods in the cluster with various selectors.
637
+ */
638
+ static select(scope, id, options) {
639
+ return new Pods(scope, id, options.expressions, options.labels, options.namespaces);
640
+ }
641
+ /**
642
+ * Select all pods.
643
+ */
644
+ static all(scope, id, options = {}) {
645
+ return Pods.select(scope, id, { namespaces: options.namespaces });
646
+ }
647
+ constructor(scope, id, expressions, labels, namespaces) {
648
+ super(scope, id);
649
+ this.expressions = expressions;
650
+ this.labels = labels;
651
+ this.namespaces = namespaces;
652
+ }
653
+ /**
654
+ * @see IPodSelector.toPodSelectorConfig()
655
+ */
656
+ toPodSelectorConfig() {
657
+ return {
658
+ labelSelector: LabelSelector.of({ expressions: this.expressions, labels: this.labels }),
659
+ namespaces: this.namespaces?.toNamespaceSelectorConfig(),
660
+ };
661
+ }
662
+ /**
663
+ * @see INetworkPolicyPeer.toNetworkPolicyPeerConfig()
664
+ */
665
+ toNetworkPolicyPeerConfig() {
666
+ return { podSelector: this.toPodSelectorConfig() };
667
+ }
668
+ /**
669
+ * @see INetworkPolicyPeer.toPodSelector()
670
+ */
671
+ toPodSelector() {
672
+ return this;
673
+ }
674
+ }
675
+ exports.Pods = Pods;
676
+ _j = JSII_RTTI_SYMBOL_1;
677
+ Pods[_j] = { fqn: "cdk8s-plus-32.Pods", version: "2.0.0" };
678
+ /**
679
+ * A node that is matched by label selectors.
680
+ */
681
+ class LabeledNode {
682
+ constructor(labelSelector) {
683
+ this.labelSelector = labelSelector;
684
+ }
685
+ ;
686
+ }
687
+ exports.LabeledNode = LabeledNode;
688
+ _k = JSII_RTTI_SYMBOL_1;
689
+ LabeledNode[_k] = { fqn: "cdk8s-plus-32.LabeledNode", version: "2.0.0" };
690
+ /**
691
+ * A node that is matched by taint selectors.
692
+ */
693
+ class TaintedNode {
694
+ constructor(taintSelector) {
695
+ this.taintSelector = taintSelector;
696
+ }
697
+ ;
698
+ }
699
+ exports.TaintedNode = TaintedNode;
700
+ _l = JSII_RTTI_SYMBOL_1;
701
+ TaintedNode[_l] = { fqn: "cdk8s-plus-32.TaintedNode", version: "2.0.0" };
702
+ /**
703
+ * A node that is matched by its name.
704
+ */
705
+ class NamedNode {
706
+ constructor(name) {
707
+ this.name = name;
708
+ }
709
+ ;
710
+ }
711
+ exports.NamedNode = NamedNode;
712
+ _m = JSII_RTTI_SYMBOL_1;
713
+ NamedNode[_m] = { fqn: "cdk8s-plus-32.NamedNode", version: "2.0.0" };
714
+ /**
715
+ * Represents a node in the cluster.
716
+ */
717
+ class Node {
718
+ /**
719
+ * Match a node by its labels.
720
+ */
721
+ static labeled(...labelSelector) {
722
+ return new LabeledNode(labelSelector);
723
+ }
724
+ /**
725
+ * Match a node by its name.
726
+ */
727
+ static named(nodeName) {
728
+ return new NamedNode(nodeName);
729
+ }
730
+ /**
731
+ * Match a node by its taints.
732
+ */
733
+ static tainted(...taintSelector) {
734
+ return new TaintedNode(taintSelector);
735
+ }
736
+ }
737
+ exports.Node = Node;
738
+ _o = JSII_RTTI_SYMBOL_1;
739
+ Node[_o] = { fqn: "cdk8s-plus-32.Node", version: "2.0.0" };
740
+ /**
741
+ * Available topology domains.
742
+ */
743
+ class Topology {
744
+ /**
745
+ * Custom key for the node label that the system uses to denote the topology domain.
746
+ */
747
+ static custom(key) {
748
+ return new Topology(key);
749
+ }
750
+ constructor(key) {
751
+ this.key = key;
752
+ }
753
+ ;
754
+ }
755
+ exports.Topology = Topology;
756
+ _p = JSII_RTTI_SYMBOL_1;
757
+ Topology[_p] = { fqn: "cdk8s-plus-32.Topology", version: "2.0.0" };
758
+ /**
759
+ * A hostname represents a single node in the cluster.
760
+ *
761
+ * @see https://kubernetes.io/docs/reference/labels-annotations-taints/#kubernetesiohostname
762
+ */
763
+ Topology.HOSTNAME = new Topology('kubernetes.io/hostname');
764
+ /**
765
+ * A zone represents a logical failure domain. It is common for Kubernetes clusters to
766
+ * span multiple zones for increased availability. While the exact definition of a zone is
767
+ * left to infrastructure implementations, common properties of a zone include very low
768
+ * network latency within a zone, no-cost network traffic within a zone, and failure
769
+ * independence from other zones. For example, nodes within a zone might share a network
770
+ * switch, but nodes in different zones should not.
771
+ *
772
+ * @see https://kubernetes.io/docs/reference/labels-annotations-taints/#topologykubernetesiozone
773
+ */
774
+ Topology.ZONE = new Topology('topology.kubernetes.io/zone');
775
+ /**
776
+ * A region represents a larger domain, made up of one or more zones. It is uncommon
777
+ * for Kubernetes clusters to span multiple regions. While the exact definition of a
778
+ * zone or region is left to infrastructure implementations, common properties of a region
779
+ * include higher network latency between them than within them, non-zero cost for network
780
+ * traffic between them, and failure independence from other zones or regions.
781
+ *
782
+ * For example, nodes within a region might share power infrastructure (e.g. a UPS or generator), but
783
+ * nodes in different regions typically would not.
784
+ *
785
+ * @see https://kubernetes.io/docs/reference/labels-annotations-taints/#topologykubernetesioregion
786
+ */
787
+ Topology.REGION = new Topology('topology.kubernetes.io/region');
788
+ /**
789
+ * Controls the pod scheduling strategy.
790
+ */
791
+ class PodScheduling {
792
+ constructor(instance) {
793
+ this.instance = instance;
794
+ this._nodeAffinityPreferred = [];
795
+ this._nodeAffinityRequired = [];
796
+ this._podAffinityPreferred = [];
797
+ this._podAffinityRequired = [];
798
+ this._podAntiAffinityPreferred = [];
799
+ this._podAntiAffinityRequired = [];
800
+ this._tolerations = [];
801
+ }
802
+ /**
803
+ * Assign this pod a specific node by name.
804
+ *
805
+ * The scheduler ignores the Pod, and the kubelet on the named node
806
+ * tries to place the Pod on that node. Overrules any affinity rules of the pod.
807
+ *
808
+ * Some limitations of static assignment are:
809
+ *
810
+ * - If the named node does not exist, the Pod will not run, and in some
811
+ * cases may be automatically deleted.
812
+ * - If the named node does not have the resources to accommodate the Pod,
813
+ * the Pod will fail and its reason will indicate why, for example OutOfmemory or OutOfcpu.
814
+ * - Node names in cloud environments are not always predictable or stable.
815
+ *
816
+ * Will throw is the pod is already assigned to named node.
817
+ *
818
+ * Under the hood, this method utilizes the `nodeName` property.
819
+ */
820
+ assign(node) {
821
+ if (this._nodeName) {
822
+ // disallow overriding an static node assignment
823
+ throw new Error(`Cannot assign ${this.instance.podMetadata.name} to node ${node.name}. It is already assigned to node ${this._nodeName}`);
824
+ }
825
+ else {
826
+ this._nodeName = node.name;
827
+ }
828
+ }
829
+ /**
830
+ * Allow this pod to tolerate taints matching these tolerations.
831
+ *
832
+ * You can put multiple taints on the same node and multiple tolerations on the same pod.
833
+ * The way Kubernetes processes multiple taints and tolerations is like a filter: start with
834
+ * all of a node's taints, then ignore the ones for which the pod has a matching toleration;
835
+ * the remaining un-ignored taints have the indicated effects on the pod. In particular:
836
+ *
837
+ * - if there is at least one un-ignored taint with effect NoSchedule then Kubernetes will
838
+ * not schedule the pod onto that node
839
+ * - if there is no un-ignored taint with effect NoSchedule but there is at least one un-ignored
840
+ * taint with effect PreferNoSchedule then Kubernetes will try to not schedule the pod onto the node
841
+ * - if there is at least one un-ignored taint with effect NoExecute then the pod will be evicted from
842
+ * the node (if it is already running on the node), and will not be scheduled onto the node (if it is
843
+ * not yet running on the node).
844
+ *
845
+ * Under the hood, this method utilizes the `tolerations` property.
846
+ *
847
+ * @see https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
848
+ */
849
+ tolerate(node) {
850
+ for (const query of node.taintSelector) {
851
+ this._tolerations.push(query._toKube());
852
+ }
853
+ }
854
+ /**
855
+ * Attract this pod to a node matched by selectors.
856
+ * You can select a node by using `Node.labeled()`.
857
+ *
858
+ * Attracting to multiple nodes (i.e invoking this method multiple times) acts as
859
+ * an OR condition, meaning the pod will be assigned to either one of the nodes.
860
+ *
861
+ * Under the hood, this method utilizes the `nodeAffinity` property.
862
+ *
863
+ * @see https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity
864
+ */
865
+ attract(node, options = {}) {
866
+ const term = this.createNodeAffinityTerm(node);
867
+ if (options.weight) {
868
+ this.validateWeight(options.weight);
869
+ this._nodeAffinityPreferred.push({ weight: options.weight, preference: term });
870
+ }
871
+ else {
872
+ this._nodeAffinityRequired.push(term);
873
+ }
874
+ }
875
+ /**
876
+ * Co-locate this pod with a scheduling selection.
877
+ *
878
+ * A selection can be one of:
879
+ *
880
+ * - An instance of a `Pod`.
881
+ * - An instance of a `Workload` (e.g `Deployment`, `StatefulSet`).
882
+ * - An un-managed pod that can be selected via `Pods.select()`.
883
+ *
884
+ * Co-locating with multiple selections ((i.e invoking this method multiple times)) acts as
885
+ * an AND condition. meaning the pod will be assigned to a node that satisfies all
886
+ * selections (i.e runs at least one pod that satisifies each selection).
887
+ *
888
+ * Under the hood, this method utilizes the `podAffinity` property.
889
+ *
890
+ * @see https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity
891
+ */
892
+ colocate(selector, options = {}) {
893
+ const topology = options.topology ?? Topology.HOSTNAME;
894
+ const term = this.createPodAffinityTerm(topology, selector);
895
+ if (options.weight) {
896
+ this.validateWeight(options.weight);
897
+ this._podAffinityPreferred.push({ weight: options.weight, podAffinityTerm: term });
898
+ }
899
+ else {
900
+ this._podAffinityRequired.push(term);
901
+ }
902
+ }
903
+ /**
904
+ * Seperate this pod from a scheduling selection.
905
+ *
906
+ * A selection can be one of:
907
+ *
908
+ * - An instance of a `Pod`.
909
+ * - An instance of a `Workload` (e.g `Deployment`, `StatefulSet`).
910
+ * - An un-managed pod that can be selected via `Pods.select()`.
911
+ *
912
+ * Seperating from multiple selections acts as an AND condition. meaning the pod
913
+ * will not be assigned to a node that satisfies all selections (i.e runs at least one pod that satisifies each selection).
914
+ *
915
+ * Under the hood, this method utilizes the `podAntiAffinity` property.
916
+ *
917
+ * @see https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity
918
+ */
919
+ separate(selector, options = {}) {
920
+ const topology = options.topology ?? Topology.HOSTNAME;
921
+ const term = this.createPodAffinityTerm(topology, selector);
922
+ if (options.weight) {
923
+ this.validateWeight(options.weight);
924
+ this._podAntiAffinityPreferred.push({ weight: options.weight, podAffinityTerm: term });
925
+ }
926
+ else {
927
+ this._podAntiAffinityRequired.push(term);
928
+ }
929
+ }
930
+ createPodAffinityTerm(topology, selector) {
931
+ const config = selector.toPodSelectorConfig();
932
+ return {
933
+ topologyKey: topology.key,
934
+ labelSelector: config.labelSelector._toKube(),
935
+ namespaceSelector: config.namespaces?.labelSelector?._toKube(),
936
+ namespaces: config.namespaces?.names,
937
+ };
938
+ }
939
+ createNodeAffinityTerm(node) {
940
+ return { matchExpressions: node.labelSelector.map(s => s._toKube()) };
941
+ }
942
+ validateWeight(weight) {
943
+ if (weight < 1 || weight > 100) {
944
+ // https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity-weight
945
+ throw new Error(`Invalid affinity weight: ${weight}. Must be in range 1-100`);
946
+ }
947
+ }
948
+ /**
949
+ * @internal
950
+ */
951
+ _toKube() {
952
+ const atLeastOne = (...arrays) => {
953
+ return arrays.flat().length > 0;
954
+ };
955
+ const hasNodeAffinity = atLeastOne(this._nodeAffinityPreferred, this._nodeAffinityRequired);
956
+ const hasPodAffinity = atLeastOne(this._podAffinityPreferred, this._podAffinityRequired);
957
+ const hasPodAntiAffinty = atLeastOne(this._podAntiAffinityPreferred, this._podAntiAffinityRequired);
958
+ const hasAffinity = hasNodeAffinity || hasPodAffinity || hasPodAntiAffinty;
959
+ return {
960
+ affinity: hasAffinity ? {
961
+ nodeAffinity: hasNodeAffinity ? {
962
+ preferredDuringSchedulingIgnoredDuringExecution: (0, utils_1.undefinedIfEmpty)(this._nodeAffinityPreferred),
963
+ requiredDuringSchedulingIgnoredDuringExecution: this._nodeAffinityRequired.length > 0 ? {
964
+ nodeSelectorTerms: this._nodeAffinityRequired,
965
+ } : undefined,
966
+ } : undefined,
967
+ podAffinity: hasPodAffinity ? {
968
+ preferredDuringSchedulingIgnoredDuringExecution: (0, utils_1.undefinedIfEmpty)(this._podAffinityPreferred),
969
+ requiredDuringSchedulingIgnoredDuringExecution: (0, utils_1.undefinedIfEmpty)(this._podAffinityRequired),
970
+ } : undefined,
971
+ podAntiAffinity: hasPodAntiAffinty ? {
972
+ preferredDuringSchedulingIgnoredDuringExecution: (0, utils_1.undefinedIfEmpty)(this._podAntiAffinityPreferred),
973
+ requiredDuringSchedulingIgnoredDuringExecution: (0, utils_1.undefinedIfEmpty)(this._podAntiAffinityRequired),
974
+ } : undefined,
975
+ } : undefined,
976
+ nodeName: this._nodeName,
977
+ tolerations: (0, utils_1.undefinedIfEmpty)(this._tolerations),
978
+ };
979
+ }
980
+ }
981
+ exports.PodScheduling = PodScheduling;
982
+ _q = JSII_RTTI_SYMBOL_1;
983
+ PodScheduling[_q] = { fqn: "cdk8s-plus-32.PodScheduling", version: "2.0.0" };
984
+ /**
985
+ * Isolation determines which policies are created
986
+ * when allowing connections from a a pod / workload to peers.
987
+ */
988
+ var PodConnectionsIsolation;
989
+ (function (PodConnectionsIsolation) {
990
+ /**
991
+ * Only creates network policies that select the pod.
992
+ */
993
+ PodConnectionsIsolation["POD"] = "POD";
994
+ /**
995
+ * Only creates network policies that select the peer.
996
+ */
997
+ PodConnectionsIsolation["PEER"] = "PEER";
998
+ })(PodConnectionsIsolation || (exports.PodConnectionsIsolation = PodConnectionsIsolation = {}));
999
+ /**
1000
+ * Controls network isolation rules for inter-pod communication.
1001
+ */
1002
+ class PodConnections {
1003
+ constructor(instance) {
1004
+ this.instance = instance;
1005
+ }
1006
+ /**
1007
+ * Allow network traffic from this pod to the peer.
1008
+ *
1009
+ * By default, this will create an egress network policy for this pod, and an ingress
1010
+ * network policy for the peer. This is required if both sides are already isolated.
1011
+ * Use `options.isolation` to control this behavior.
1012
+ *
1013
+ * @example
1014
+ *
1015
+ * // create only an egress policy that selects the 'web' pod to allow outgoing traffic
1016
+ * // to the 'redis' pod. this requires the 'redis' pod to not be isolated for ingress.
1017
+ * web.connections.allowTo(redis, { isolation: Isolation.POD })
1018
+ *
1019
+ * // create only an ingress policy that selects the 'redis' peer to allow incoming traffic
1020
+ * // from the 'web' pod. this requires the 'web' pod to not be isolated for egress.
1021
+ * web.connections.allowTo(redis, { isolation: Isolation.PEER })
1022
+ *
1023
+ */
1024
+ allowTo(peer, options = {}) {
1025
+ return this.allow('Egress', peer, { ports: this.extractPorts(peer), ...options });
1026
+ }
1027
+ /**
1028
+ * Allow network traffic from the peer to this pod.
1029
+ *
1030
+ * By default, this will create an ingress network policy for this pod, and an egress
1031
+ * network policy for the peer. This is required if both sides are already isolated.
1032
+ * Use `options.isolation` to control this behavior.
1033
+ *
1034
+ * @example
1035
+ *
1036
+ * // create only an egress policy that selects the 'web' pod to allow outgoing traffic
1037
+ * // to the 'redis' pod. this requires the 'redis' pod to not be isolated for ingress.
1038
+ * redis.connections.allowFrom(web, { isolation: Isolation.PEER })
1039
+ *
1040
+ * // create only an ingress policy that selects the 'redis' peer to allow incoming traffic
1041
+ * // from the 'web' pod. this requires the 'web' pod to not be isolated for egress.
1042
+ * redis.connections.allowFrom(web, { isolation: Isolation.POD })
1043
+ *
1044
+ */
1045
+ allowFrom(peer, options = {}) {
1046
+ return this.allow('Ingress', peer, { ports: this.extractPorts(this.instance), ...options });
1047
+ }
1048
+ allow(direction, peer, options = {}) {
1049
+ const config = peer.toNetworkPolicyPeerConfig();
1050
+ networkpolicy.validatePeerConfig(config);
1051
+ const peerAddress = (0, utils_1.address)(peer);
1052
+ if (!options.isolation || options.isolation === PodConnectionsIsolation.POD) {
1053
+ const src = new networkpolicy.NetworkPolicy(this.instance, `Allow${direction}${peerAddress}`, {
1054
+ selector: this.instance,
1055
+ // the policy must be defined in the namespace of the pod
1056
+ // so it can select it.
1057
+ metadata: { namespace: this.instance.metadata.namespace },
1058
+ });
1059
+ switch (direction) {
1060
+ case 'Egress':
1061
+ src.addEgressRule(peer, options.ports);
1062
+ break;
1063
+ case 'Ingress':
1064
+ src.addIngressRule(peer, options.ports);
1065
+ }
1066
+ }
1067
+ if (!options.isolation || options.isolation === PodConnectionsIsolation.PEER) {
1068
+ if (config.ipBlock) {
1069
+ // for an ip block we don't need to create the opposite policies
1070
+ return;
1071
+ }
1072
+ const podSelector = peer.toPodSelector();
1073
+ if (!podSelector) {
1074
+ throw new Error(`Unable to create policies for peer '${peer.node.addr}' since its not a pod selector`);
1075
+ }
1076
+ const oppositeDirection = direction === 'Egress' ? 'Ingress' : 'Egress';
1077
+ const podSelectorConfig = podSelector.toPodSelectorConfig();
1078
+ let namespaces;
1079
+ if (!podSelectorConfig.namespaces) {
1080
+ // if the peer doesn't specify namespaces, we assume the same namespace.
1081
+ namespaces = [this.instance.metadata.namespace];
1082
+ }
1083
+ else {
1084
+ // a peer cannot specify namespaces by labels because
1085
+ // we won't be able to extract the names of those namespaces.
1086
+ if (podSelectorConfig.namespaces.labelSelector && !podSelectorConfig.namespaces.labelSelector.isEmpty()) {
1087
+ throw new Error(`Unable to create an ${oppositeDirection} policy for peer '${peer.node.path}' (pod=${this.instance.name}). Peer must specify namespaces only by name`);
1088
+ }
1089
+ // a peer must specify namespaces by name.
1090
+ if (!podSelectorConfig.namespaces.names) {
1091
+ throw new Error(`Unable to create an ${oppositeDirection} policy for peer '${peer.node.path}' (pod=${this.instance.name}). Peer must specify namespace names`);
1092
+ }
1093
+ namespaces = podSelectorConfig.namespaces.names;
1094
+ }
1095
+ for (const name of namespaces) {
1096
+ switch (direction) {
1097
+ case 'Egress':
1098
+ new networkpolicy.NetworkPolicy(this.instance, `AllowIngress${name}${peerAddress}`, {
1099
+ selector: podSelector,
1100
+ metadata: { namespace: name },
1101
+ ingress: { rules: [{ peer: this.instance, ports: options.ports }] },
1102
+ });
1103
+ break;
1104
+ case 'Ingress':
1105
+ new networkpolicy.NetworkPolicy(this.instance, `AllowEgress${name}${peerAddress}`, {
1106
+ selector: podSelector,
1107
+ metadata: { namespace: name },
1108
+ egress: { rules: [{ peer: this.instance, ports: options.ports }] },
1109
+ });
1110
+ break;
1111
+ default:
1112
+ throw new Error(`Unsupported direction: ${direction}`);
1113
+ }
1114
+ }
1115
+ }
1116
+ }
1117
+ extractPorts(selector) {
1118
+ return container.extractContainerPorts(selector).map(n => networkpolicy.NetworkPolicyPort.tcp(n.number));
1119
+ }
1120
+ /**
1121
+ * Sets the default network policy for Pod/Workload to have all egress and ingress connections as disabled
1122
+ */
1123
+ isolate() {
1124
+ new networkpolicy.NetworkPolicy(this.instance, 'DefaultDenyAll', {
1125
+ selector: this.instance,
1126
+ // the policy must be defined in the namespace of the pod
1127
+ // so it can select it.
1128
+ metadata: { namespace: this.instance.metadata.namespace },
1129
+ egress: {
1130
+ default: networkpolicy.NetworkPolicyTrafficDefault.DENY,
1131
+ },
1132
+ ingress: {
1133
+ default: networkpolicy.NetworkPolicyTrafficDefault.DENY,
1134
+ },
1135
+ });
1136
+ }
1137
+ }
1138
+ exports.PodConnections = PodConnections;
1139
+ _r = JSII_RTTI_SYMBOL_1;
1140
+ PodConnections[_r] = { fqn: "cdk8s-plus-32.PodConnections", version: "2.0.0" };
1141
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9kLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3BvZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLGlDQUFzRjtBQUN0RiwyQ0FBbUQ7QUFDbkQsK0JBQStCO0FBQy9CLHlDQUF5QztBQUN6QyxxQ0FBcUM7QUFFckMsa0RBQWtEO0FBSWxELG1DQUFvRDtBQUdwRCxNQUFzQixXQUFZLFNBQVEsSUFBSSxDQUFDLFFBQVE7SUFxQnJELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsUUFBMEIsRUFBRTtRQUNwRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBUkYsZ0JBQVcsR0FBMEIsRUFBRSxDQUFDO1FBQ3hDLG9CQUFlLEdBQTBCLEVBQUUsQ0FBQztRQUM1QyxpQkFBWSxHQUFnQixFQUFFLENBQUM7UUFDL0IsYUFBUSxHQUErQixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBT2hFLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDLGFBQWEsSUFBSSxhQUFhLENBQUMsTUFBTSxDQUFDO1FBQ2pFLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDLGNBQWMsQ0FBQztRQUMzQyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksa0JBQWtCLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3JFLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUMsa0JBQWtCLENBQUM7UUFDbkQsSUFBSSxDQUFDLDRCQUE0QixHQUFHLEtBQUssQ0FBQyw0QkFBNEIsSUFBSSxLQUFLLENBQUM7UUFDaEYsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEtBQUssQ0FBQyxxQkFBcUIsSUFBSSxLQUFLLENBQUM7UUFDbEUsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxJQUFJLEtBQUss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dGlvbiwgRHVyYXRpb24sIExhenksIE5hbWVzIH0gZnJvbSAnY2RrOHMnO1xuaW1wb3J0IHsgQ29uc3RydWN0LCBJQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgKiBhcyBiYXNlIGZyb20gJy4vYmFzZSc7XG5pbXBvcnQgKiBhcyBjb250YWluZXIgZnJvbSAnLi9jb250YWluZXInO1xuaW1wb3J0ICogYXMgazhzIGZyb20gJy4vaW1wb3J0cy9rOHMnO1xuaW1wb3J0ICogYXMgbmFtZXNwYWNlIGZyb20gJy4vbmFtZXNwYWNlJztcbmltcG9ydCAqIGFzIG5ldHdvcmtwb2xpY3kgZnJvbSAnLi9uZXR3b3JrLXBvbGljeSc7XG5pbXBvcnQgKiBhcyByYiBmcm9tICcuL3JvbGUtYmluZGluZyc7XG5pbXBvcnQgKiBhcyBzZWNyZXQgZnJvbSAnLi9zZWNyZXQnO1xuaW1wb3J0ICogYXMgc2VydmljZWFjY291bnQgZnJvbSAnLi9zZXJ2aWNlLWFjY291bnQnO1xuaW1wb3J0IHsgdW5kZWZpbmVkSWZFbXB0eSwgYWRkcmVzcyB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0ICogYXMgdm9sdW1lIGZyb20gJy4vdm9sdW1lJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFic3RyYWN0UG9kIGV4dGVuZHMgYmFzZS5SZXNvdXJjZSBpbXBsZW1lbnRzIElQb2RTZWxlY3RvciwgbmV0d29ya3BvbGljeS5JTmV0d29ya1BvbGljeVBlZXIsIHJiLklTdWJqZWN0IHtcblxuICBwdWJsaWMgcmVhZG9ubHkgcmVzdGFydFBvbGljeT86IFJlc3RhcnRQb2xpY3k7XG4gIHB1YmxpYyByZWFkb25seSBzZXJ2aWNlQWNjb3VudD86IHNlcnZpY2VhY2NvdW50LklTZXJ2aWNlQWNjb3VudDtcbiAgcHVibGljIHJlYWRvbmx5IHNlY3VyaXR5Q29udGV4dDogUG9kU2VjdXJpdHlDb250ZXh0O1xuICBwdWJsaWMgcmVhZG9ubHkgZG5zOiBQb2REbnM7XG4gIHB1YmxpYyByZWFkb25seSBkb2NrZXJSZWdpc3RyeUF1dGg/OiBzZWNyZXQuSVNlY3JldDtcbiAgcHVibGljIHJlYWRvbmx5IGF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW46IGJvb2xlYW47XG4gIHB1YmxpYyByZWFkb25seSBzaGFyZVByb2Nlc3NOYW1lc3BhY2U6IGJvb2xlYW47XG4gIHB1YmxpYyByZWFkb25seSBob3N0TmV0d29yaz86IGJvb2xlYW47XG4gIHB1YmxpYyByZWFkb25seSB0ZXJtaW5hdGlvbkdyYWNlUGVyaW9kPzogRHVyYXRpb247XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGlzb2xhdGU6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfY29udGFpbmVyczogY29udGFpbmVyLkNvbnRhaW5lcltdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgX2luaXRDb250YWluZXJzOiBjb250YWluZXIuQ29udGFpbmVyW10gPSBbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBfaG9zdEFsaWFzZXM6IEhvc3RBbGlhc1tdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgX3ZvbHVtZXM6IE1hcDxzdHJpbmcsIHZvbHVtZS5Wb2x1bWU+ID0gbmV3IE1hcCgpO1xuXG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSBwb2RNZXRhZGF0YTogQXBpT2JqZWN0TWV0YWRhdGFEZWZpbml0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBBYnN0cmFjdFBvZFByb3BzID0ge30pIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgdGhpcy5yZXN0YXJ0UG9saWN5ID0gcHJvcHMucmVzdGFydFBvbGljeSA/PyBSZXN0YXJ0UG9saWN5LkFMV0FZUztcbiAgICB0aGlzLnNlcnZpY2VBY2NvdW50ID0gcHJvcHMuc2VydmljZUFjY291bnQ7XG4gICAgdGhpcy5zZWN1cml0eUNvbnRleHQgPSBuZXcgUG9kU2VjdXJpdHlDb250ZXh0KHByb3BzLnNlY3VyaXR5Q29udGV4dCk7XG4gICAgdGhpcy5kbnMgPSBuZXcgUG9kRG5zKHByb3BzLmRucyk7XG4gICAgdGhpcy5kb2NrZXJSZWdpc3RyeUF1dGggPSBwcm9wcy5kb2NrZXJSZWdpc3RyeUF1dGg7XG4gICAgdGhpcy5hdXRvbW91bnRTZXJ2aWNlQWNjb3VudFRva2VuID0gcHJvcHMuYXV0b21vdW50U2VydmljZUFjY291bnRUb2tlbiA/PyBmYWxzZTtcbiAgICB0aGlzLnNoYXJlUHJvY2Vzc05hbWVzcGFjZSA9IHByb3BzLnNoYXJlUHJvY2Vzc05hbWVzcGFjZSA/PyBmYWxzZTtcbiAgICB0aGlzLmlzb2xhdGUgPSBwcm9wcy5pc29sYXRlID8/IGZhbHNlO1xuICAgIHRoaXMuaG9zdE5ldHdvcmsgPSBwcm9wcy5ob3N0TmV0d29yayA/PyBmYWxzZTtcbiAgICB0aGlzLnRlcm1pbmF0aW9uR3JhY2VQZXJpb2QgPSBwcm9wcy50ZXJtaW5hdGlvbkdyYWNlUGVyaW9kID8/IER1cmF0aW9uLnNlY29uZHMoMzApO1xuXG4gICAgaWYgKHByb3BzLmNvbnRhaW5lcnMpIHtcbiAgICAgIHByb3BzLmNvbnRhaW5lcnMuZm9yRWFjaChjID0+IHRoaXMuYWRkQ29udGFpbmVyKGMpKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMudm9sdW1lcykge1xuICAgICAgcHJvcHMudm9sdW1lcy5mb3JFYWNoKHYgPT4gdGhpcy5hZGRWb2x1bWUodikpO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy5pbml0Q29udGFpbmVycykge1xuICAgICAgcHJvcHMuaW5pdENvbnRhaW5lcnMuZm9yRWFjaChjID0+IHRoaXMuYWRkSW5pdENvbnRhaW5lcihjKSk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmhvc3RBbGlhc2VzKSB7XG4gICAgICBwcm9wcy5ob3N0QWxpYXNlcy5mb3JFYWNoKGMgPT4gdGhpcy5hZGRIb3N0QWxpYXMoYykpO1xuICAgIH1cblxuICB9XG5cbiAgcHVibGljIGdldCBjb250YWluZXJzKCk6IGNvbnRhaW5lci5Db250YWluZXJbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLl9jb250YWluZXJzXTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgaW5pdENvbnRhaW5lcnMoKTogY29udGFpbmVyLkNvbnRhaW5lcltdIHtcbiAgICByZXR1cm4gWy4uLnRoaXMuX2luaXRDb250YWluZXJzXTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdm9sdW1lcygpOiB2b2x1bWUuVm9sdW1lW10ge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuX3ZvbHVtZXMudmFsdWVzKCkpO1xuICB9XG5cbiAgcHVibGljIGdldCBob3N0QWxpYXNlcygpOiBIb3N0QWxpYXNbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLl9ob3N0QWxpYXNlc107XG4gIH1cblxuICAvKipcbiAgICogQHNlZSBJUG9kU2VsZWN0b3IudG9Qb2RTZWxlY3RvckNvbmZpZygpXG4gICAqL1xuICBwdWJsaWMgdG9Qb2RTZWxlY3RvckNvbmZpZygpOiBQb2RTZWxlY3RvckNvbmZpZyB7XG4gICAgY29uc3QgcG9kQWRkcmVzcyA9IHRoaXMucG9kTWV0YWRhdGEuZ2V0TGFiZWwoUG9kLkFERFJFU1NfTEFCRUwpO1xuICAgIGlmICghcG9kQWRkcmVzcykge1xuICAgICAgLy8gc2hvdWxkbid0IGhhcHBlbiBiZWNhdXNlIHdlIGFkZCB0aGlzIGxhYmVsIGF1dG9tYXRpY2FsbHkgaW4gYm90aCBwb2RzIGFuZCB3b3JrbG9hZHMuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBjcmVhdGUgYSBsYWJlbCBzZWxlY3RvciBzaW5jZSAke1BvZC5BRERSRVNTX0xBQkVMfSBsYWJlbCBpcyBtaXNzaW5nYCk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBsYWJlbFNlbGVjdG9yOiBMYWJlbFNlbGVjdG9yLm9mKHsgbGFiZWxzOiB7IFtQb2QuQUREUkVTU19MQUJFTF06IHBvZEFkZHJlc3MgfSB9KSxcbiAgICAgIG5hbWVzcGFjZXM6IHRoaXMubWV0YWRhdGEubmFtZXNwYWNlID8ge1xuICAgICAgICBuYW1lczogW3RoaXMubWV0YWRhdGEubmFtZXNwYWNlXSxcbiAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc2VlIElOZXR3b3JrUG9saWN5UGVlci50b05ldHdvcmtQb2xpY3lQZWVyQ29uZmlnKClcbiAgICovXG4gIHB1YmxpYyB0b05ldHdvcmtQb2xpY3lQZWVyQ29uZmlnKCk6IG5ldHdvcmtwb2xpY3kuTmV0d29ya1BvbGljeVBlZXJDb25maWcge1xuICAgIHJldHVybiB7IHBvZFNlbGVjdG9yOiB0aGlzLnRvUG9kU2VsZWN0b3JDb25maWcoKSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzZWUgSU5ldHdvcmtQb2xpY3lQZWVyLnRvUG9kU2VsZWN0b3IoKVxuICAgKi9cbiAgcHVibGljIHRvUG9kU2VsZWN0b3IoKTogSVBvZFNlbGVjdG9yIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHB1YmxpYyBhZGRDb250YWluZXIoY29udDogY29udGFpbmVyLkNvbnRhaW5lclByb3BzKTogY29udGFpbmVyLkNvbnRhaW5lciB7XG4gICAgY29uc3QgaW1wbCA9IG5ldyBjb250YWluZXIuQ29udGFpbmVyKGNvbnQpO1xuICAgIHRoaXMuYXR0YWNoQ29udGFpbmVyKGltcGwpO1xuICAgIHJldHVybiBpbXBsO1xuICB9XG5cbiAgcHVibGljIGF0dGFjaENvbnRhaW5lcihjb250OiBjb250YWluZXIuQ29udGFpbmVyKSB7XG4gICAgdGhpcy5fY29udGFpbmVycy5wdXNoKGNvbnQpO1xuICB9XG5cbiAgcHVibGljIGFkZEluaXRDb250YWluZXIoY29udDogY29udGFpbmVyLkNvbnRhaW5lclByb3BzKTogY29udGFpbmVyLkNvbnRhaW5lciB7XG5cbiAgICAvLyBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9jb25jZXB0cy93b3JrbG9hZHMvcG9kcy9pbml0LWNvbnRhaW5lcnMvI2RpZmZlcmVuY2VzLWZyb20tcmVndWxhci1jb250YWluZXJzXG4gICAgaWYgKCF0aGlzLmlzU2lkZWNhckNvbnRhaW5lcihjb250KSAmJiBjb250LnJlYWRpbmVzcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbml0IGNvbnRhaW5lcnMgbXVzdCBub3QgaGF2ZSBhIHJlYWRpbmVzcyBwcm9iZScpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5pc1NpZGVjYXJDb250YWluZXIoY29udCkgJiYgY29udC5saXZlbmVzcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbml0IGNvbnRhaW5lcnMgbXVzdCBub3QgaGF2ZSBhIGxpdmVuZXNzIHByb2JlJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmlzU2lkZWNhckNvbnRhaW5lcihjb250KSAmJiBjb250LnN0YXJ0dXApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5pdCBjb250YWluZXJzIG11c3Qgbm90IGhhdmUgYSBzdGFydHVwIHByb2JlJyk7XG4gICAgfVxuXG4gICAgY29uc3QgaW1wbCA9IG5ldyBjb250YWluZXIuQ29udGFpbmVyKHtcbiAgICAgIC4uLmNvbnQsXG4gICAgICBuYW1lOiBjb250Lm5hbWUgPz8gYGluaXQtJHt0aGlzLl9pbml0Q29udGFpbmVycy5sZW5ndGh9YCxcbiAgICB9KTtcblxuICAgIHRoaXMuX2luaXRDb250YWluZXJzLnB1c2goaW1wbCk7XG4gICAgcmV0dXJuIGltcGw7XG4gIH1cblxuICAvLyBBbnkgaW5pdENvbnRhaW5lciB0aGF0IGhhcyBgcmVzdGFydFBvbGljeT1BbHdheXNgIGlzIGEgc2lkZWNhciBjb250YWluZXIuIFBsZWFzZSByZWZlciB0b1xuICAvLyBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGRldGFpbHM6XG4gIC8vIGh0dHBzOi8va3ViZXJuZXRlcy5pby9kb2NzL2NvbmNlcHRzL3dvcmtsb2Fkcy9wb2RzL3NpZGVjYXItY29udGFpbmVycy8jZGlmZmVyZW5jZXMtZnJvbS1pbml0LWNvbnRhaW5lcnNcbiAgcHJpdmF0ZSBpc1NpZGVjYXJDb250YWluZXIoY29udDogY29udGFpbmVyLkNvbnRhaW5lclByb3BzKSB7XG4gICAgcmV0dXJuIGNvbnQucmVzdGFydFBvbGljeSA9PT0gY29udGFpbmVyLkNvbnRhaW5lclJlc3RhcnRQb2xpY3kuQUxXQVlTO1xuICB9XG5cbiAgcHVibGljIGFkZEhvc3RBbGlhcyhob3N0QWxpYXM6IEhvc3RBbGlhcyk6IHZvaWQge1xuICAgIHRoaXMuX2hvc3RBbGlhc2VzLnB1c2goaG9zdEFsaWFzKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRWb2x1bWUodm9sOiB2b2x1bWUuVm9sdW1lKTogdm9pZCB7XG4gICAgY29uc3QgZXhpc3RpbmdWb2x1bWUgPSB0aGlzLl92b2x1bWVzLmdldCh2b2wubmFtZSk7XG4gICAgaWYgKGV4aXN0aW5nVm9sdW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFZvbHVtZSB3aXRoIG5hbWUgJHt2b2wubmFtZX0gYWxyZWFkeSBleGlzdHNgKTtcbiAgICB9XG4gICAgdGhpcy5fdm9sdW1lcy5zZXQodm9sLm5hbWUsIHZvbCk7XG4gIH1cblxuICAvKipcbiAgICogQHNlZSBJU3ViZWN0LnRvU3ViamVjdENvbmZpZ3VyYXRpb24oKVxuICAgKi9cbiAgcHVibGljIHRvU3ViamVjdENvbmZpZ3VyYXRpb24oKTogcmIuU3ViamVjdENvbmZpZ3VyYXRpb24ge1xuXG4gICAgaWYgKCF0aGlzLnNlcnZpY2VBY2NvdW50ICYmICF0aGlzLmF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLm5hbWV9IGNhbm5vdCBiZSBjb252ZXJ0ZWQgdG8gYSByb2xlIGJpbmRpbmcgc3ViamVjdDpgXG4gICAgICAgICsgJyBZb3UgbXVzdCBlaXRoZXIgYXNzaWduIGEgc2VydmljZSBhY2NvdW50IHRvIGl0LCBvciB1c2UgXFwnYXV0b21vdW50U2VydmljZUFjY291bnRUb2tlbjogdHJ1ZVxcJycpO1xuICAgIH1cblxuICAgIC8vICdkZWZhdWx0JyBpcyBhc3N1bWVkIHRvIGJlIHRoZSBuYW1lIG9mIHRoZSBkZWZhdWx0IHNlcnZpY2UgYWNjb3VudFxuICAgIC8vIGluIHRoZSBjbHVzdGVyLlxuICAgIGNvbnN0IHNlcnZpY2VBY2NvdW50TmFtZSA9IHRoaXMuc2VydmljZUFjY291bnQ/Lm5hbWUgPz8gJ2RlZmF1bHQnO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGtpbmQ6ICdTZXJ2aWNlQWNjb3VudCcsXG4gICAgICBuYW1lOiBzZXJ2aWNlQWNjb3VudE5hbWUsXG4gICAgICBhcGlHcm91cDogJycsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdG9Qb2RTcGVjKCk6IGs4cy5Qb2RTcGVjIHtcblxuICAgIGlmICh0aGlzLmNvbnRhaW5lcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BvZFNwZWMgbXVzdCBoYXZlIGF0IGxlYXN0IDEgY29udGFpbmVyJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgdm9sdW1lczogTWFwPHN0cmluZywgdm9sdW1lLlZvbHVtZT4gPSBuZXcgTWFwKCk7XG4gICAgY29uc3QgY29udGFpbmVyczogazhzLkNvbnRhaW5lcltdID0gW107XG4gICAgY29uc3QgaW5pdENvbnRhaW5lcnM6IGs4cy5Db250YWluZXJbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBjb250IG9mIHRoaXMuY29udGFpbmVycykge1xuICAgICAgLy8gY2hlY2sgaWYgcmVzdGFydFBvbGljeSBpcyBkZWZpbmVkIGZvciBjb250YWluZXJzXG4gICAgICBpZiAoY29udC5yZXN0YXJ0UG9saWN5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBjb250YWluZXIgc3BlYzogJHtjb250Lm5hbWV9IGhhcyBub24tZW1wdHkgcmVzdGFydFBvbGljeSBmaWVsZC4gVGhlIGZpZWxkIGNhbiBvbmx5IGJlIHNwZWNpZmllZCBmb3IgaW5pdENvbnRhaW5lcnNgKTtcbiAgICAgIH1cbiAgICAgIC8vIGF1dG9tYXRpY2FsbHkgYWRkIHZvbHVtZSBmcm9tIHRoZSBjb250YWluZXIgbW91bnRcbiAgICAgIC8vIHRvIHRoaXMgcG9kIHNvIHRoYXRzIGl0cyBhdmFpbGFibGUgdG8gdGhlIGNvbnRhaW5lci5cbiAgICAgIGZvciAoY29uc3QgbW91bnQgb2YgY29udC5tb3VudHMpIHtcbiAgICAgICAgYWRkVm9sdW1lKG1vdW50LnZvbHVtZSk7XG4gICAgICB9XG4gICAgICBjb250YWluZXJzLnB1c2goY29udC5fdG9LdWJlKCkpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgY29udCBvZiB0aGlzLmluaXRDb250YWluZXJzKSB7XG4gICAgICAvLyBhdXRvbWF0aWNhbGx5IGFkZCB2b2x1bWUgZnJvbSB0aGUgY29udGFpbmVyIG1vdW50XG4gICAgICAvLyB0byB0aGlzIHBvZCBzbyB0aGF0cyBpdHMgYXZhaWxhYmxlIHRvIHRoZSBjb250YWluZXIuXG4gICAgICBmb3IgKGNvbnN0IG1vdW50IG9mIGNvbnQubW91bnRzKSB7XG4gICAgICAgIGFkZFZvbHVtZShtb3VudC52b2x1bWUpO1xuICAgICAgfVxuICAgICAgaW5pdENvbnRhaW5lcnMucHVzaChjb250Ll90b0t1YmUoKSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCB2b2wgb2YgdGhpcy52b2x1bWVzKSB7XG4gICAgICBhZGRWb2x1bWUodm9sKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRWb2x1bWUodm9sOiB2b2x1bWUuVm9sdW1lKSB7XG4gICAgICBjb25zdCBleGlzdGluZ1ZvbHVtZSA9IHZvbHVtZXMuZ2V0KHZvbC5uYW1lKTtcbiAgICAgIC8vIGl0cyBvayB0byBjYWxsIHRoaXMgZnVuY3Rpb24gdHdpY2Ugb24gdGhlIHNhbWUgdm9sdW1lLCBidXQgaXRzIG5vdCBvayB0b1xuICAgICAgLy8gY2FsbCBpdCB0d2ljZSBvbiBhIGRpZmZlcmVudCB2b2x1bWUgd2l0aCB0aGUgc2FtZSBuYW1lLlxuICAgICAgaWYgKGV4aXN0aW5nVm9sdW1lICYmIGV4aXN0aW5nVm9sdW1lICE9PSB2b2wpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG1vdW50IGNvbmZpZ3VyYXRpb24uIEF0IGxlYXN0IHR3byBkaWZmZXJlbnQgdm9sdW1lcyBoYXZlIHRoZSBzYW1lIG5hbWU6ICR7dm9sLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICB2b2x1bWVzLnNldCh2b2wubmFtZSwgdm9sKTtcbiAgICB9XG5cbiAgICBjb25zdCBkbnMgPSB0aGlzLmRucy5fdG9LdWJlKCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVzdGFydFBvbGljeTogdGhpcy5yZXN0YXJ0UG9saWN5LFxuICAgICAgc2VydmljZUFjY291bnROYW1lOiB0aGlzLnNlcnZpY2VBY2NvdW50Py5uYW1lLFxuICAgICAgY29udGFpbmVyczogY29udGFpbmVycyxcbiAgICAgIHNlY3VyaXR5Q29udGV4dDogdW5kZWZpbmVkSWZFbXB0eSh0aGlzLnNlY3VyaXR5Q29udGV4dC5fdG9LdWJlKCkpLFxuICAgICAgaW5pdENvbnRhaW5lcnM6IHVuZGVmaW5lZElmRW1wdHkoaW5pdENvbnRhaW5lcnMpLFxuICAgICAgaG9zdEFsaWFzZXM6IHVuZGVmaW5lZElmRW1wdHkodGhpcy5ob3N0QWxpYXNlcyksXG4gICAgICB2b2x1bWVzOiB1bmRlZmluZWRJZkVtcHR5KEFycmF5LmZyb20odm9sdW1lcy52YWx1ZXMoKSkubWFwKHYgPT4gdi5fdG9LdWJlKCkpKSxcbiAgICAgIGRuc1BvbGljeTogZG5zLnBvbGljeSxcbiAgICAgIGRuc0NvbmZpZzogdW5kZWZpbmVkSWZFbXB0eShkbnMuY29uZmlnKSxcbiAgICAgIGhvc3RuYW1lOiBkbnMuaG9zdG5hbWUsXG4gICAgICBzdWJkb21haW46IGRucy5zdWJkb21haW4sXG4gICAgICBzZXRIb3N0bmFtZUFzRnFkbjogZG5zLmhvc3RuYW1lQXNGUUROLFxuICAgICAgaW1hZ2VQdWxsU2VjcmV0czogdGhpcy5kb2NrZXJSZWdpc3RyeUF1dGggPyBbeyBuYW1lOiB0aGlzLmRvY2tlclJlZ2lzdHJ5QXV0aC5uYW1lIH1dIDogdW5kZWZpbmVkLFxuICAgICAgYXV0b21vdW50U2VydmljZUFjY291bnRUb2tlbjogdGhpcy5hdXRvbW91bnRTZXJ2aWNlQWNjb3VudFRva2VuLFxuICAgICAgc2hhcmVQcm9jZXNzTmFtZXNwYWNlOiB0aGlzLnNoYXJlUHJvY2Vzc05hbWVzcGFjZSxcbiAgICAgIGhvc3ROZXR3b3JrOiB0aGlzLmhvc3ROZXR3b3JrLFxuICAgICAgdGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHM6IHRoaXMudGVybWluYXRpb25HcmFjZVBlcmlvZD8udG9TZWNvbmRzKCksXG4gICAgfTtcblxuICB9XG5cbn1cblxuLyoqXG4gKiBTeXNjdGwgZGVmaW5lcyBhIGtlcm5lbCBwYXJhbWV0ZXIgdG8gYmUgc2V0XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3lzY3RsIHtcbiAgLyoqXG4gICAqIE5hbWUgb2YgYSBwcm9wZXJ0eSB0byBzZXRcbiAgICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVmFsdWUgb2YgYSBwcm9wZXJ0eSB0byBzZXRcbiAgICovXG4gIHJlYWRvbmx5IHZhbHVlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgYFBvZFNlY3VyaXR5Q29udGV4dGBcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQb2RTZWN1cml0eUNvbnRleHRQcm9wcyB7XG5cbiAgLyoqXG4gICAqIE1vZGlmeSB0aGUgb3duZXJzaGlwIGFuZCBwZXJtaXNzaW9ucyBvZiBwb2Qgdm9sdW1lcyB0byB0aGlzIEdJRC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBWb2x1bWUgb3duZXJzaGlwIGlzIG5vdCBjaGFuZ2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgZnNHcm91cD86IG51bWJlcjtcblxuICAvKipcbiAgICogRGVmaW5lcyBiZWhhdmlvciBvZiBjaGFuZ2luZyBvd25lcnNoaXAgYW5kIHBlcm1pc3Npb24gb2YgdGhlIHZvbHVtZSBiZWZvcmUgYmVpbmcgZXhwb3NlZCBpbnNpZGUgUG9kLlxuICAgKiBUaGlzIGZpZWxkIHdpbGwgb25seSBhcHBseSB0byB2b2x1bWUgdHlwZXMgd2hpY2ggc3VwcG9ydCBmc0dyb3VwIGJhc2VkIG93bmVyc2hpcChhbmQgcGVybWlzc2lvbnMpLlxuICAgKiBJdCB3aWxsIGhhdmUgbm8gZWZmZWN0IG9uIGVwaGVtZXJhbCB2b2x1bWUgdHlwZXMgc3VjaCBhczogc2VjcmV0LCBjb25maWdtYXBzIGFuZCBlbXB0eWRpci5cbiAgICpcbiAgICogQGRlZmF1bHQgRnNHcm91cENoYW5nZVBvbGljeS5BTFdBWVNcbiAgICovXG4gIHJlYWRvbmx5IGZzR3JvdXBDaGFuZ2VQb2xpY3k/OiBGc0dyb3VwQ2hhbmdlUG9saWN5O1xuXG4gIC8qKlxuICAgKiBUaGUgVUlEIHRvIHJ1biB0aGUgZW50cnlwb2ludCBvZiB0aGUgY29udGFpbmVyIHByb2Nlc3MuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gVXNlciBzcGVjaWZpZWQgaW4gaW1hZ2UgbWV0YWRhdGFcbiAgICovXG4gIHJlYWRvbmx5IHVzZXI/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBHSUQgdG8gcnVuIHRoZSBlbnRyeXBvaW50IG9mIHRoZSBjb250YWluZXIgcHJvY2Vzcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBHcm91cCBjb25maWd1cmVkIGJ5IGNvbnRhaW5lciBydW50aW1lXG4gICAqL1xuICByZWFkb25seSBncm91cD86IG51bWJlcjtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgdGhlIGNvbnRhaW5lciBtdXN0IHJ1biBhcyBhIG5vbi1yb290IHVzZXIuXG4gICAqIElmIHRydWUsIHRoZSBLdWJlbGV0IHdpbGwgdmFsaWRhdGUgdGhlIGltYWdlIGF0IHJ1bnRpbWUgdG8gZW5zdXJlIHRoYXQgaXQgZG9lc1xuICAgKiBub3QgcnVuIGFzIFVJRCAwIChyb290KSBhbmQgZmFpbCB0byBzdGFydCB0aGUgY29udGFpbmVyIGlmIGl0IGRvZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGVuc3VyZU5vblJvb3Q/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBTeXNjdGxzIGhvbGQgYSBsaXN0IG9mIG5hbWVzcGFjZWQgc3lzY3RscyB1c2VkIGZvciB0aGUgcG9kLlxuICAgKiBQb2RzIHdpdGggdW5zdXBwb3J0ZWQgc3lzY3RscyAoYnkgdGhlIGNvbnRhaW5lciBydW50aW1lKSBtaWdodCBmYWlsIHRvIGxhdW5jaC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBzeXNjdGxzXG4gICAqL1xuICByZWFkb25seSBzeXNjdGxzPzogU3lzY3RsW107XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgYEFic3RyYWN0UG9kYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBYnN0cmFjdFBvZFByb3BzIGV4dGVuZHMgYmFzZS5SZXNvdXJjZVByb3BzIHtcblxuICAvKipcbiAgICogTGlzdCBvZiBjb250YWluZXJzIGJlbG9uZ2luZyB0byB0aGUgcG9kLiBDb250YWluZXJzIGNhbm5vdCBjdXJyZW50bHkgYmVcbiAgICogYWRkZWQgb3IgcmVtb3ZlZC4gVGhlcmUgbXVzdCBiZSBhdCBsZWFzdCBvbmUgY29udGFpbmVyIGluIGEgUG9kLlxuICAgKlxuICAgKiBZb3UgY2FuIGFkZCBhZGRpdGlvbm5hbCBjb250YWluZXJzIHVzaW5nIGBwb2RTcGVjLmFkZENvbnRhaW5lcigpYFxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGNvbnRhaW5lcnMuIE5vdGUgdGhhdCBhIHBvZCBzcGVjIG11c3QgaW5jbHVkZSBhdCBsZWFzdCBvbmUgY29udGFpbmVyLlxuICAgKi9cbiAgcmVhZG9ubHkgY29udGFpbmVycz86IGNvbnRhaW5lci5Db250YWluZXJQcm9wc1tdO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIGluaXRpYWxpemF0aW9uIGNvbnRhaW5lcnMgYmVsb25naW5nIHRvIHRoZSBwb2QuXG4gICAqIEluaXQgY29udGFpbmVycyBhcmUgZXhlY3V0ZWQgaW4gb3JkZXIgcHJpb3IgdG8gY29udGFpbmVycyBiZWluZyBzdGFydGVkLlxuICAgKiBJZiBhbnkgaW5pdCBjb250YWluZXIgZmFpbHMsIHRoZSBwb2QgaXMgY29uc2lkZXJlZCB0byBoYXZlIGZhaWxlZCBhbmQgaXMgaGFuZGxlZCBhY2NvcmRpbmcgdG8gaXRzIHJlc3RhcnRQb2xpY3kuXG4gICAqIFRoZSBuYW1lIGZvciBhbiBpbml0IGNvbnRhaW5lciBvciBub3JtYWwgY29udGFpbmVyIG11c3QgYmUgdW5pcXVlIGFtb25nIGFsbCBjb250YWluZXJzLlxuICAgKiBJbml0IGNvbnRhaW5lcnMgbWF5IG5vdCBoYXZlIExpZmVjeWNsZSBhY3Rpb25zLCBSZWFkaW5lc3MgcHJvYmVzLCBMaXZlbmVzcyBwcm9iZXMsIG9yIFN0YXJ0dXAgcHJvYmVzLlxuICAgKiBUaGUgcmVzb3VyY2VSZXF1aXJlbWVudHMgb2YgYW4gaW5pdCBjb250YWluZXIgYXJlIHRha2VuIGludG8gYWNjb3VudCBkdXJpbmcgc2NoZWR1bGluZyBieSBmaW5kaW5nIHRoZSBoaWdoZXN0IHJlcXVlc3QvbGltaXRcbiAgICogZm9yIGVhY2ggcmVzb3VyY2UgdHlwZSwgYW5kIHRoZW4gdXNpbmcgdGhlIG1heCBvZiBvZiB0aGF0IHZhbHVlIG9yIHRoZSBzdW0gb2YgdGhlIG5vcm1hbCBjb250YWluZXJzLlxuICAgKiBMaW1pdHMgYXJlIGFwcGxpZWQgdG8gaW5pdCBjb250YWluZXJzIGluIGEgc2ltaWxhciBmYXNoaW9uLlxuICAgKlxuICAgKiBJbml0IGNvbnRhaW5lcnMgY2Fubm90IGN1cnJlbnRseSBiZSBhZGRlZCAscmVtb3ZlZCBvciB1cGRhdGVkLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8va3ViZXJuZXRlcy5pby9kb2NzL2NvbmNlcHRzL3dvcmtsb2Fkcy9wb2RzL2luaXQtY29udGFpbmVycy9cbiAgICogQGRlZmF1bHQgLSBObyBpbml0IGNvbnRhaW5lcnMuXG4gICAqL1xuICByZWFkb25seSBpbml0Q29udGFpbmVycz86IGNvbnRhaW5lci5Db250YWluZXJQcm9wc1tdO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIHZvbHVtZXMgdGhhdCBjYW4gYmUgbW91bnRlZCBieSBjb250YWluZXJzIGJlbG9uZ2luZyB0byB0aGUgcG9kLlxuICAgKlxuICAgKiBZb3UgY2FuIGFsc28gYWRkIHZvbHVtZXMgbGF0ZXIgdXNpbmcgYHBvZFNwZWMuYWRkVm9sdW1lKClgXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvY29uY2VwdHMvc3RvcmFnZS92b2x1bWVzXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gdm9sdW1lcy5cbiAgICovXG4gIHJlYWRvbmx5IHZvbHVtZXM/OiB2b2x1bWUuVm9sdW1lW107XG5cbiAgLyoqXG4gICAqIFJlc3RhcnQgcG9saWN5IGZvciBhbGwgY29udGFpbmVycyB3aXRoaW4gdGhlIHBvZC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9jb25jZXB0cy93b3JrbG9hZHMvcG9kcy9wb2QtbGlmZWN5Y2xlLyNyZXN0YXJ0LXBvbGljeVxuICAgKlxuICAgKiBAZGVmYXVsdCBSZXN0YXJ0UG9saWN5LkFMV0FZU1xuICAgKi9cbiAgcmVhZG9ubHkgcmVzdGFydFBvbGljeT86IFJlc3RhcnRQb2xpY3k7XG5cbiAgLyoqXG4gICAqIEEgc2VydmljZSBhY2NvdW50IHByb3ZpZGVzIGFuIGlkZW50aXR5IGZvciBwcm9jZXNzZXMgdGhhdCBydW4gaW4gYSBQb2QuXG4gICAqXG4gICAqIFdoZW4geW91IChhIGh1bWFuKSBhY2Nlc3MgdGhlIGNsdXN0ZXIgKGZvciBleGFtcGxlLCB1c2luZyBrdWJlY3RsKSwgeW91IGFyZVxuICAgKiBhdXRoZW50aWNhdGVkIGJ5IHRoZSBhcGlzZXJ2ZXIgYXMgYSBwYXJ0aWN1bGFyIFVzZXIgQWNjb3VudCAoY3VycmVudGx5IHRoaXNcbiAgICogaXMgdXN1YWxseSBhZG1pbiwgdW5sZXNzIHlvdXIgY2x1c3RlciBhZG1pbmlzdHJhdG9yIGhhcyBjdXN0b21pemVkIHlvdXJcbiAgICogY2x1c3RlcikuIFByb2Nlc3NlcyBpbiBjb250YWluZXJzIGluc2lkZSBwb2RzIGNhbiBhbHNvIGNvbnRhY3QgdGhlXG4gICAqIGFwaXNlcnZlci4gV2hlbiB0aGV5IGRvLCB0aGV5IGFyZSBhdXRoZW50aWNhdGVkIGFzIGEgcGFydGljdWxhciBTZXJ2aWNlXG4gICAqIEFjY291bnQgKGZvciBleGFtcGxlLCBkZWZhdWx0KS5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy90YXNrcy9jb25maWd1cmUtcG9kLWNvbnRhaW5lci9jb25maWd1cmUtc2VydmljZS1hY2NvdW50L1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIHNlcnZpY2UgYWNjb3VudC5cbiAgICovXG4gIHJlYWRvbmx5IHNlcnZpY2VBY2NvdW50Pzogc2VydmljZWFjY291bnQuSVNlcnZpY2VBY2NvdW50O1xuXG4gIC8qKlxuICAgKiBTZWN1cml0eUNvbnRleHQgaG9sZHMgcG9kLWxldmVsIHNlY3VyaXR5IGF0dHJpYnV0ZXMgYW5kIGNvbW1vbiBjb250YWluZXIgc2V0dGluZ3MuXG4gICAqXG4gICAqIEBkZWZhdWx0XG4gICAqXG4gICAqICAgZnNHcm91cENoYW5nZVBvbGljeTogRnNHcm91cENoYW5nZVBvbGljeS5Gc0dyb3VwQ2hhbmdlUG9saWN5LkFMV0FZU1xuICAgKiAgIGVuc3VyZU5vblJvb3Q6IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHNlY3VyaXR5Q29udGV4dD86IFBvZFNlY3VyaXR5Q29udGV4dFByb3BzO1xuXG4gIC8qKlxuICAgKiBIb3N0QWxpYXMgaG9sZHMgdGhlIG1hcHBpbmcgYmV0d2VlbiBJUCBhbmQgaG9zdG5hbWVzIHRoYXQgd2lsbCBiZSBpbmplY3RlZCBhcyBhbiBlbnRyeSBpbiB0aGUgcG9kJ3MgaG9zdHMgZmlsZS5cbiAgICpcbiAgICogQHNjaGVtYSBpby5rOHMuYXBpLmNvcmUudjEuSG9zdEFsaWFzXG4gICAqL1xuICByZWFkb25seSBob3N0QWxpYXNlcz86IEhvc3RBbGlhc1tdO1xuXG4gIC8qKlxuICAgKiBETlMgc2V0dGluZ3MgZm9yIHRoZSBwb2QuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvY29uY2VwdHMvc2VydmljZXMtbmV0d29ya2luZy9kbnMtcG9kLXNlcnZpY2UvXG4gICAqXG4gICAqIEBkZWZhdWx0XG4gICAqXG4gICAqICBwb2xpY3k6IERuc1BvbGljeS5DTFVTVEVSX0ZJUlNUXG4gICAqICBob3N0bmFtZUFzRlFETjogZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGRucz86IFBvZERuc1Byb3BzO1xuXG4gIC8qKlxuICAgKiBBIHNlY3JldCBjb250YWluaW5nIGRvY2tlciBjcmVkZW50aWFscyBmb3IgYXV0aGVudGljYXRpbmcgdG8gYSByZWdpc3RyeS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBhdXRoLiBJbWFnZXMgYXJlIGFzc3VtZWQgdG8gYmUgcHVibGljbHkgYXZhaWxhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgZG9ja2VyUmVnaXN0cnlBdXRoPzogc2VjcmV0LklTZWNyZXQ7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIGEgc2VydmljZSBhY2NvdW50IHRva2VuIHNob3VsZCBiZSBhdXRvbWF0aWNhbGx5IG1vdW50ZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqIEBzZWUgaHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvdGFza3MvY29uZmlndXJlLXBvZC1jb250YWluZXIvY29uZmlndXJlLXNlcnZpY2UtYWNjb3VudC8jdXNlLXRoZS1kZWZhdWx0LXNlcnZpY2UtYWNjb3VudC10by1hY2Nlc3MtdGhlLWFwaS1zZXJ2ZXJcbiAgICovXG4gIHJlYWRvbmx5IGF1dG9tb3VudFNlcnZpY2VBY2NvdW50VG9rZW4/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGVuIHByb2Nlc3MgbmFtZXNwYWNlIHNoYXJpbmcgaXMgZW5hYmxlZCwgcHJvY2Vzc2VzIGluIGEgY29udGFpbmVyIGFyZSB2aXNpYmxlIHRvIGFsbCBvdGhlciBjb250YWluZXJzIGluIHRoZSBzYW1lIHBvZC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy90YXNrcy9jb25maWd1cmUtcG9kLWNvbnRhaW5lci9zaGFyZS1wcm9jZXNzLW5hbWVzcGFjZS9cbiAgICovXG4gIHJlYWRvbmx5IHNoYXJlUHJvY2Vzc05hbWVzcGFjZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIElzb2xhdGVzIHRoZSBwb2QuIFRoaXMgd2lsbCBwcmV2ZW50IGFueSBpbmdyZXNzIG9yIGVncmVzcyBjb25uZWN0aW9ucyB0byAvIGZyb20gdGhpcyBwb2QuXG4gICAqIFlvdSBjYW4gaG93ZXZlciBhbGxvdyBleHBsaWNpdCBjb25uZWN0aW9ucyBwb3N0IGluc3RhbnRpYXRpb24gYnkgdXNpbmcgdGhlIGAuY29ubmVjdGlvbnNgIHByb3BlcnR5LlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgaXNvbGF0ZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEhvc3QgbmV0d29yayBmb3IgdGhlIHBvZC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGhvc3ROZXR3b3JrPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogR3JhY2UgcGVyaW9kIHVudGlsIHRoZSBwb2QgaXMgdGVybWluYXRlZFxuICAgKlxuICAgKiBAZGVmYXVsdCBEdXJhdGlvbi5zZWNvbmRzKDMwKVxuICAgKi9cbiAgcmVhZG9ubHkgdGVybWluYXRpb25HcmFjZVBlcmlvZD86IER1cmF0aW9uO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGBQb2RgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvZFByb3BzIGV4dGVuZHMgQWJzdHJhY3RQb2RQcm9wcyB7fVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGBMYWJlbFNlbGVjdG9yLm9mYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYWJlbFNlbGVjdG9yT3B0aW9ucyB7XG5cbiAgLyoqXG4gICAqIFN0cmljdCBsYWJlbCBtYXRjaGVycy5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVscz86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG5cbiAgLyoqXG4gICAqIEV4cHJlc3Npb24gYmFzZWQgbGFiZWwgbWF0Y2hlcnMuXG4gICAqL1xuICByZWFkb25seSBleHByZXNzaW9ucz86IExhYmVsRXhwcmVzc2lvbltdO1xufVxuXG4vKipcbiAqIE1hdGNoIGEgcmVzb3VyY2UgYnkgbGFiZWxzLlxuICovXG5leHBvcnQgY2xhc3MgTGFiZWxTZWxlY3RvciB7XG5cbiAgcHVibGljIHN0YXRpYyBvZihvcHRpb25zOiBMYWJlbFNlbGVjdG9yT3B0aW9ucyA9IHt9KSB7XG4gICAgcmV0dXJuIG5ldyBMYWJlbFNlbGVjdG9yKG9wdGlvbnMuZXhwcmVzc2lvbnMgPz8gW10sIG9wdGlvbnMubGFiZWxzID8/IHt9KTtcbiAgfVxuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBleHByZXNzaW9uczogTGFiZWxFeHByZXNzaW9uW10sXG4gICAgcHJpdmF0ZSByZWFkb25seSBsYWJlbHM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0pIHt9XG5cbiAgcHVibGljIGlzRW1wdHkoKSB7XG4gICAgcmV0dXJuIHRoaXMuZXhwcmVzc2lvbnMubGVuZ3RoID09PSAwICYmIE9iamVjdC5rZXlzKHRoaXMubGFiZWxzKS5sZW5ndGggPT09IDA7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgX3RvS3ViZSgpOiBrOHMuTGFiZWxTZWxlY3RvciB7XG4gICAgaWYgKHRoaXMuaXNFbXB0eSgpKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBtYXRjaEV4cHJlc3Npb25zOiB1bmRlZmluZWRJZkVtcHR5KHRoaXMuZXhwcmVzc2lvbnMubWFwKHEgPT4gKHsga2V5OiBxLmtleSwgb3BlcmF0b3I6IHEub3BlcmF0b3IsIHZhbHVlczogcS52YWx1ZXMgfSkpKSxcbiAgICAgIG1hdGNoTGFiZWxzOiB1bmRlZmluZWRJZkVtcHR5KHRoaXMubGFiZWxzKSxcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3Igc2VsZWN0aW5nIHBvZHMsIG9wdGlvbmFsbHkgaW4gcGFydGljdWxhciBuYW1lc3BhY2VzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvZFNlbGVjdG9yQ29uZmlnIHtcblxuICAvKipcbiAgICogQSBzZWxlY3RvciB0byBzZWxlY3QgcG9kcyBieSBsYWJlbHMuXG4gICAqL1xuICByZWFkb25seSBsYWJlbFNlbGVjdG9yOiBMYWJlbFNlbGVjdG9yO1xuXG4gIC8qKlxuICAgKiBDb25maWd1cmF0aW9uIGZvciBzZWxlY3Rpbmcgd2hpY2ggbmFtZXBzYWNlcyBhcmUgdGhlIHBvZHMgYWxsb3dlZCB0byBiZSBpbi5cbiAgICovXG4gIHJlYWRvbmx5IG5hbWVzcGFjZXM/OiBuYW1lc3BhY2UuTmFtZXNwYWNlU2VsZWN0b3JDb25maWc7XG5cbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIG9iamVjdCB0aGF0IGNhbiBzZWxlY3QgcG9kcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJUG9kU2VsZWN0b3IgZXh0ZW5kcyBJQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgY29uZmlndXJhdGlvbiBvZiB0aGlzIHNlbGVjdG9yLlxuICAgKi9cbiAgdG9Qb2RTZWxlY3RvckNvbmZpZygpOiBQb2RTZWxlY3RvckNvbmZpZztcbn1cblxuLyoqXG4gKiBQb2QgaXMgYSBjb2xsZWN0aW9uIG9mIGNvbnRhaW5lcnMgdGhhdCBjYW4gcnVuIG9uIGEgaG9zdC4gVGhpcyByZXNvdXJjZSBpc1xuICogY3JlYXRlZCBieSBjbGllbnRzIGFuZCBzY2hlZHVsZWQgb250byBob3N0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFBvZCBleHRlbmRzIEFic3RyYWN0UG9kIHtcblxuICAvKipcbiAgICogVGhpcyBsYWJlbCBpcyBhdXRvYW10aWNhbGx5IGFkZGVkIGJ5IGNkazhzIHRvIGFueSBwb2QuIEl0IHByb3ZpZGVzXG4gICAqIGEgdW5pcXVlIGFuZCBzdGFibGUgaWRlbnRpZmllciBmb3IgdGhlIHBvZC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQUREUkVTU19MQUJFTCA9ICdjZGs4cy5pby9tZXRhZGF0YS5hZGRyJztcblxuICAvKipcbiAgICogQHNlZSBiYXNlLlJlc291cmNlLmFwaU9iamVjdFxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGFwaU9iamVjdDogQXBpT2JqZWN0O1xuXG4gIHB1YmxpYyByZWFkb25seSByZXNvdXJjZVR5cGUgPSAncG9kcyc7XG5cbiAgcHVibGljIHJlYWRvbmx5IHNjaGVkdWxpbmc6IFBvZFNjaGVkdWxpbmc7XG4gIHB1YmxpYyByZWFkb25seSBjb25uZWN0aW9uczogUG9kQ29ubmVjdGlvbnM7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFBvZFByb3BzID0ge30pIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcblxuICAgIHRoaXMuYXBpT2JqZWN0ID0gbmV3IGs4cy5LdWJlUG9kKHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIG1ldGFkYXRhOiBwcm9wcy5tZXRhZGF0YSxcbiAgICAgIHNwZWM6IExhenkuYW55KHsgcHJvZHVjZTogKCkgPT4gdGhpcy5fdG9LdWJlKCkgfSksXG4gICAgfSk7XG5cbiAgICB0aGlzLm1ldGFkYXRhLmFkZExhYmVsKFBvZC5BRERSRVNTX0xBQkVMLCBOYW1lcy50b0xhYmVsVmFsdWUodGhpcykpO1xuXG4gICAgdGhpcy5zY2hlZHVsaW5nID0gbmV3IFBvZFNjaGVkdWxpbmcodGhpcyk7XG4gICAgdGhpcy5jb25uZWN0aW9ucyA9IG5ldyBQb2RDb25uZWN0aW9ucyh0aGlzKTtcblxuICAgIGlmICh0aGlzLmlzb2xhdGUpIHtcbiAgICAgIHRoaXMuY29ubmVjdGlvbnMuaXNvbGF0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXQgcG9kTWV0YWRhdGEoKTogQXBpT2JqZWN0TWV0YWRhdGFEZWZpbml0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5tZXRhZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdG9LdWJlKCk6IGs4cy5Qb2RTcGVjIHtcbiAgICBjb25zdCBzY2hlZHVsaW5nID0gdGhpcy5zY2hlZHVsaW5nLl90b0t1YmUoKTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLl90b1BvZFNwZWMoKSxcbiAgICAgIGFmZmluaXR5OiBzY2hlZHVsaW5nLmFmZmluaXR5LFxuICAgICAgbm9kZU5hbWU6IHNjaGVkdWxpbmcubm9kZU5hbWUsXG4gICAgICB0b2xlcmF0aW9uczogc2NoZWR1bGluZy50b2xlcmF0aW9ucyxcbiAgICB9O1xuICB9XG5cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBgUG9kRG5zYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQb2REbnNQcm9wcyB7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB0aGUgaG9zdG5hbWUgb2YgdGhlIFBvZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBTZXQgdG8gYSBzeXN0ZW0tZGVmaW5lZCB2YWx1ZS5cbiAgICovXG4gIHJlYWRvbmx5IGhvc3RuYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBJZiBzcGVjaWZpZWQsIHRoZSBmdWxseSBxdWFsaWZpZWQgUG9kIGhvc3RuYW1lIHdpbGwgYmUgXCI8aG9zdG5hbWU+LjxzdWJkb21haW4+Ljxwb2QgbmFtZXNwYWNlPi5zdmMuPGNsdXN0ZXIgZG9tYWluPlwiLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIHN1YmRvbWFpbi5cbiAgICovXG4gIHJlYWRvbmx5IHN1YmRvbWFpbj86IHN0cmluZztcblxuICAvKipcbiAgICogSWYgdHJ1ZSB0aGUgcG9kJ3MgaG9zdG5hbWUgd2lsbCBiZSBjb25maWd1cmVkIGFzIHRoZSBwb2QncyBGUUROLCByYXRoZXIgdGhhbiB0aGUgbGVhZiBuYW1lICh0aGUgZGVmYXVsdCkuXG4gICAqIEluIExpbnV4IGNvbnRhaW5lcnMsIHRoaXMgbWVhbnMgc2V0dGluZyB0aGUgRlFETiBpbiB0aGUgaG9zdG5hbWUgZmllbGQgb2YgdGhlIGtlcm5lbCAodGhlIG5vZGVuYW1lIGZpZWxkIG9mIHN0cnVjdCB1dHNuYW1lKS5cbiAgICogSW4gV2luZG93cyBjb250YWluZXJzLCB0aGlzIG1lYW5zIHNldHRpbmcgdGhlIHJlZ2lzdHJ5IHZhbHVlIG9mIGhvc3RuYW1lIGZvciB0aGUgcmVnaXN0cnlcbiAgICoga2V5IEhLRVlfTE9DQUxfTUFDSElORVxcU1lTVEVNXFxDdXJyZW50Q29udHJvbFNldFxcU2VydmljZXNcXFRjcGlwXFxQYXJhbWV0ZXJzIHRvIEZRRE4uXG4gICAqIElmIGEgcG9kIGRvZXMgbm90IGhhdmUgRlFETiwgdGhpcyBoYXMgbm8gZWZmZWN0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgaG9zdG5hbWVBc0ZRRE4/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBTZXQgRE5TIHBvbGljeSBmb3IgdGhlIHBvZC5cbiAgICpcbiAgICogSWYgcG9saWN5IGlzIHNldCB0byBgTm9uZWAsIG90aGVyIGNvbmZpZ3VyYXRpb24gbXVzdCBiZSBzdXBwbGllZC5cbiAgICpcbiAgICogQGRlZmF1bHQgRG5zUG9saWN5LkNMVVNURVJfRklSU1RcbiAgICovXG4gIHJlYWRvbmx5IHBvbGljeT86IERuc1BvbGljeTtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIElQIGFkZHJlc3NlcyB0aGF0IHdpbGwgYmUgdXNlZCBhcyBETlMgc2VydmVycyBmb3IgdGhlIFBvZC4gVGhlcmUgY2FuIGJlIGF0IG1vc3QgMyBJUCBhZGRyZXNzZXMgc3BlY2lmaWVkLlxuICAgKiBXaGVuIHRoZSBwb2xpY3kgaXMgc2V0IHRvIFwiTk9ORVwiLCB0aGUgbGlzdCBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIElQIGFkZHJlc3MsXG4gICAqIG90aGVyd2lzZSB0aGlzIHByb3BlcnR5IGlzIG9wdGlvbmFsLlxuICAgKiBUaGUgc2VydmVycyBsaXN0ZWQgd2lsbCBiZSBjb21iaW5lZCB0byB0aGUgYmFzZSBuYW1lc2VydmVycyBnZW5lcmF0ZWQgZnJvbVxuICAgKiB0aGUgc3BlY2lmaWVkIEROUyBwb2xpY3kgd2l0aCBkdXBsaWNhdGUgYWRkcmVzc2VzIHJlbW92ZWQuXG4gICAqL1xuICByZWFkb25seSBuYW1lc2VydmVycz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgRE5TIHNlYXJjaCBkb21haW5zIGZvciBob3N0bmFtZSBsb29rdXAgaW4gdGhlIFBvZC5cbiAgICogV2hlbiBzcGVjaWZpZWQsIHRoZSBwcm92aWRlZCBsaXN0IHdpbGwgYmUgbWVyZ2VkIGludG8gdGhlIGJhc2VcbiAgICogc2VhcmNoIGRvbWFpbiBuYW1lcyBnZW5lcmF0ZWQgZnJvbSB0aGUgY2hvc2VuIEROUyBwb2xpY3kuXG4gICAqIER1cGxpY2F0ZSBkb21haW4gbmFtZXMgYXJlIHJlbW92ZWQuXG4gICAqXG4gICAqIEt1YmVybmV0ZXMgYWxsb3dzIGZvciBhdCBtb3N0IDYgc2VhcmNoIGRvbWFpbnMuXG4gICAqL1xuICByZWFkb25seSBzZWFyY2hlcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIG9iamVjdHMgd2hlcmUgZWFjaCBvYmplY3QgbWF5IGhhdmUgYSBuYW1lIHByb3BlcnR5IChyZXF1aXJlZClcbiAgICogYW5kIGEgdmFsdWUgcHJvcGVydHkgKG9wdGlvbmFsKS4gVGhlIGNvbnRlbnRzIGluIHRoaXMgcHJvcGVydHlcbiAgICogd2lsbCBiZSBtZXJnZWQgdG8gdGhlIG9wdGlvbnMgZ2VuZXJhdGVkIGZyb20gdGhlIHNwZWNpZmllZCBETlMgcG9saWN5LlxuICAgKiBEdXBsaWNhdGUgZW50cmllcyBhcmUgcmVtb3ZlZC5cbiAgICovXG4gIHJlYWRvbmx5IG9wdGlvbnM/OiBEbnNPcHRpb25bXTtcbn1cblxuLyoqXG4gKiBIb2xkcyBkbnMgc2V0dGluZ3Mgb2YgdGhlIHBvZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFBvZERucyB7XG5cbiAgLyoqXG4gICAqIFRoZSBETlMgcG9saWN5IG9mIHRoaXMgcG9kLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHBvbGljeTogRG5zUG9saWN5O1xuXG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJlZCBob3N0bmFtZSBvZiB0aGUgcG9kLiBVbmRlZmluZWQgbWVhbnMgaXRzIHNldCB0byBhIHN5c3RlbS1kZWZpbmVkIHZhbHVlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGhvc3RuYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJlZCBzdWJkb21haW4gb2YgdGhlIHBvZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzdWJkb21haW4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgb3Igbm90IHRoZSBwb2RzIGhvc3RuYW1lIGlzIHNldCB0byBpdHMgRlFETi5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBob3N0bmFtZUFzRlFETjogYm9vbGVhbjtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9uYW1lc2VydmVyczogc3RyaW5nW107XG4gIHByaXZhdGUgcmVhZG9ubHkgX3NlYXJjaGVzOiBzdHJpbmdbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBfb3B0aW9uczogRG5zT3B0aW9uW107XG5cbiAgY29uc3RydWN0b3IocHJvcHM6IFBvZERuc1Byb3BzID0ge30pIHtcbiAgICB0aGlzLmhvc3RuYW1lID0gcHJvcHMuaG9zdG5hbWU7XG4gICAgdGhpcy5zdWJkb21haW4gPSBwcm9wcy5zdWJkb21haW47XG4gICAgdGhpcy5wb2xpY3kgPSBwcm9wcy5wb2xpY3kgPz8gRG5zUG9saWN5LkNMVVNURVJfRklSU1Q7XG4gICAgdGhpcy5ob3N0bmFtZUFzRlFETiA9IHByb3BzLmhvc3RuYW1lQXNGUUROID8/IGZhbHNlO1xuICAgIHRoaXMuX25hbWVzZXJ2ZXJzID0gcHJvcHMubmFtZXNlcnZlcnMgPz8gW107XG4gICAgdGhpcy5fc2VhcmNoZXMgPSBwcm9wcy5zZWFyY2hlcyA/PyBbXTtcbiAgICB0aGlzLl9vcHRpb25zID0gcHJvcHMub3B0aW9ucyA/PyBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBOYW1lc2VydmVycyBkZWZpbmVkIGZvciB0aGlzIHBvZC5cbiAgICovXG4gIHB1YmxpYyBnZXQgbmFtZXNlcnZlcnMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbLi4udGhpcy5fbmFtZXNlcnZlcnNdO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlYXJjaCBkb21haW5zIGRlZmluZWQgZm9yIHRoaXMgcG9kLlxuICAgKi9cbiAgcHVibGljIGdldCBzZWFyY2hlcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLl9zZWFyY2hlc107XG4gIH1cblxuICAvKipcbiAgICogQ3VzdG9tIGRucyBvcHRpb25zIGRlZmluZWQgZm9yIHRoaXMgcG9kLlxuICAgKi9cbiAgcHVibGljIGdldCBvcHRpb25zKCk6IERuc09wdGlvbltdIHtcbiAgICByZXR1cm4gWy4uLnRoaXMuX29wdGlvbnNdO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIG5hbWVzZXJ2ZXIuXG4gICAqL1xuICBwdWJsaWMgYWRkTmFtZXNlcnZlciguLi5uYW1lc2VydmVyczogc3RyaW5nW10pIHtcbiAgICB0aGlzLl9uYW1lc2VydmVycy5wdXNoKC4uLm5hbWVzZXJ2ZXJzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBzZWFyY2ggZG9tYWluLlxuICAgKi9cbiAgcHVibGljIGFkZFNlYXJjaCguLi5zZWFyY2hlczogc3RyaW5nW10pIHtcbiAgICB0aGlzLl9zZWFyY2hlcy5wdXNoKC4uLnNlYXJjaGVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBjdXN0b20gb3B0aW9uLlxuICAgKi9cbiAgcHVibGljIGFkZE9wdGlvbiguLi5vcHRpb25zOiBEbnNPcHRpb25bXSkge1xuICAgIHRoaXMuX29wdGlvbnMucHVzaCguLi5vcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdG9LdWJlKCk6IHtcbiAgICBob3N0bmFtZT86IHN0cmluZztcbiAgICBzdWJkb21haW4/OiBzdHJpbmc7XG4gICAgaG9zdG5hbWVBc0ZRRE46IGJvb2xlYW47XG4gICAgcG9saWN5OiBzdHJpbmc7XG4gICAgY29uZmlnOiBrOHMuUG9kRG5zQ29uZmlnOyB9IHtcblxuICAgIGlmICh0aGlzLnBvbGljeSA9PT0gRG5zUG9saWN5Lk5PTkUgJiYgdGhpcy5uYW1lc2VydmVycy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignV2hlbiBkbnMgcG9saWN5IGlzIHNldCB0byBOT05FLCBhdCBsZWFzdCBvbmUgbmFtZXNlcnZlciBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm5hbWVzZXJ2ZXJzLmxlbmd0aCA+IDMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlcmUgY2FuIGJlIGF0IG1vc3QgMyBuYW1lc2VydmVycyBzcGVjaWZpZWQnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zZWFyY2hlcy5sZW5ndGggPiA2KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGNhbiBiZSBhdCBtb3N0IDYgc2VhcmNoIGRvbWFpbnMgc3BlY2lmaWVkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGhvc3RuYW1lOiB0aGlzLmhvc3RuYW1lLFxuICAgICAgc3ViZG9tYWluOiB0aGlzLnN1YmRvbWFpbixcbiAgICAgIGhvc3RuYW1lQXNGUUROOiB0aGlzLmhvc3RuYW1lQXNGUUROLFxuICAgICAgcG9saWN5OiB0aGlzLnBvbGljeSxcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBuYW1lc2VydmVyczogdW5kZWZpbmVkSWZFbXB0eSh0aGlzLm5hbWVzZXJ2ZXJzKSxcbiAgICAgICAgc2VhcmNoZXM6IHVuZGVmaW5lZElmRW1wdHkodGhpcy5zZWFyY2hlcyksXG4gICAgICAgIG9wdGlvbnM6IHVuZGVmaW5lZElmRW1wdHkodGhpcy5vcHRpb25zKSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG59XG5cbi8qKlxuICogSG9sZHMgcG9kLWxldmVsIHNlY3VyaXR5IGF0dHJpYnV0ZXMgYW5kIGNvbW1vbiBjb250YWluZXIgc2V0dGluZ3MuXG4gKi9cbmV4cG9ydCBjbGFzcyBQb2RTZWN1cml0eUNvbnRleHQge1xuXG4gIHB1YmxpYyByZWFkb25seSBlbnN1cmVOb25Sb290OiBib29sZWFuO1xuICBwdWJsaWMgcmVhZG9ubHkgdXNlcj86IG51bWJlcjtcbiAgcHVibGljIHJlYWRvbmx5IGdyb3VwPzogbnVtYmVyO1xuICBwdWJsaWMgcmVhZG9ubHkgZnNHcm91cD86IG51bWJlcjtcbiAgcHVibGljIHJlYWRvbmx5IGZzR3JvdXBDaGFuZ2VQb2xpY3k6IEZzR3JvdXBDaGFuZ2VQb2xpY3k7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfc3lzY3RsczogU3lzY3RsW10gPSBbXTtcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogUG9kU2VjdXJpdHlDb250ZXh0UHJvcHMgPSB7fSkge1xuICAgIHRoaXMuZW5zdXJlTm9uUm9vdCA9IHByb3BzLmVuc3VyZU5vblJvb3QgPz8gdHJ1ZTtcbiAgICB0aGlzLmZzR3JvdXBDaGFuZ2VQb2xpY3kgPSBwcm9wcy5mc0dyb3VwQ2hhbmdlUG9saWN5ID8/IEZzR3JvdXBDaGFuZ2VQb2xpY3kuQUxXQVlTO1xuICAgIHRoaXMudXNlciA9IHByb3BzLnVzZXI7XG4gICAgdGhpcy5ncm91cCA9IHByb3BzLmdyb3VwO1xuICAgIHRoaXMuZnNHcm91cCA9IHByb3BzLmZzR3JvdXA7XG5cbiAgICBmb3IgKGNvbnN0IHN5c2N0bCBvZiBwcm9wcy5zeXNjdGxzID8/IFtdKSB7XG4gICAgICB0aGlzLl9zeXNjdGxzLnB1c2goc3lzY3RsKTtcbiAgICB9XG5cbiAgfVxuXG4gIHB1YmxpYyBnZXQgc3lzY3RscygpOiBTeXNjdGxbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLl9zeXNjdGxzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdG9LdWJlKCk6IGs4cy5Qb2RTZWN1cml0eUNvbnRleHQge1xuICAgIHJldHVybiB7XG4gICAgICBydW5Bc0dyb3VwOiB0aGlzLmdyb3VwLFxuICAgICAgcnVuQXNVc2VyOiB0aGlzLnVzZXIsXG4gICAgICBmc0dyb3VwOiB0aGlzLmZzR3JvdXAsXG4gICAgICBydW5Bc05vblJvb3Q6IHRoaXMuZW5zdXJlTm9uUm9vdCxcbiAgICAgIGZzR3JvdXBDaGFuZ2VQb2xpY3k6IHRoaXMuZnNHcm91cENoYW5nZVBvbGljeSxcbiAgICAgIHN5c2N0bHM6IHVuZGVmaW5lZElmRW1wdHkodGhpcy5fc3lzY3RscyksXG4gICAgfTtcbiAgfVxuXG59XG5cbi8qKlxuICogUmVzdGFydCBwb2xpY3kgZm9yIGFsbCBjb250YWluZXJzIHdpdGhpbiB0aGUgcG9kLlxuICovXG5leHBvcnQgZW51bSBSZXN0YXJ0UG9saWN5IHtcbiAgLyoqXG4gICAqIEFsd2F5cyByZXN0YXJ0IHRoZSBwb2QgYWZ0ZXIgaXQgZXhpdHMuXG4gICAqL1xuICBBTFdBWVMgPSAnQWx3YXlzJyxcblxuICAvKipcbiAgICogT25seSByZXN0YXJ0IGlmIHRoZSBwb2QgZXhpdHMgd2l0aCBhIG5vbi16ZXJvIGV4aXQgY29kZS5cbiAgICovXG4gIE9OX0ZBSUxVUkUgPSAnT25GYWlsdXJlJyxcblxuICAvKipcbiAgICogTmV2ZXIgcmVzdGFydCB0aGUgcG9kLlxuICAgKi9cbiAgTkVWRVIgPSAnTmV2ZXInXG59XG5cbmV4cG9ydCBlbnVtIEZzR3JvdXBDaGFuZ2VQb2xpY3kge1xuXG4gIC8qKlxuICAgKiBPbmx5IGNoYW5nZSBwZXJtaXNzaW9ucyBhbmQgb3duZXJzaGlwIGlmIHBlcm1pc3Npb24gYW5kIG93bmVyc2hpcCBvZiByb290IGRpcmVjdG9yeSBkb2VzXG4gICAqIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHBlcm1pc3Npb25zIG9mIHRoZSB2b2x1bWUuXG4gICAqIFRoaXMgY291bGQgaGVscCBzaG9ydGVuIHRoZSB0aW1lIGl0IHRha2VzIHRvIGNoYW5nZSBvd25lcnNoaXAgYW5kIHBlcm1pc3Npb24gb2YgYSB2b2x1bWVcbiAgICovXG4gIE9OX1JPT1RfTUlTTUFUQ0ggPSAnT25Sb290TWlzbWF0Y2gnLFxuXG4gIC8qKlxuICAgKiBBbHdheXMgY2hhbmdlIHBlcm1pc3Npb24gYW5kIG93bmVyc2hpcCBvZiB0aGUgdm9sdW1lIHdoZW4gdm9sdW1lIGlzIG1vdW50ZWQuXG4gICAqL1xuICBBTFdBWVMgPSAnQWx3YXlzJ1xufVxuXG4vKipcbiAqIEN1c3RvbSBETlMgb3B0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERuc09wdGlvbiB7XG5cbiAgLyoqXG4gICAqIE9wdGlvbiBuYW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBPcHRpb24gdmFsdWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gdmFsdWUuXG4gICAqL1xuICByZWFkb25seSB2YWx1ZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQb2QgRE5TIHBvbGljaWVzLlxuICovXG5leHBvcnQgZW51bSBEbnNQb2xpY3kge1xuXG4gIC8qKlxuICAgKiBBbnkgRE5TIHF1ZXJ5IHRoYXQgZG9lcyBub3QgbWF0Y2ggdGhlIGNvbmZpZ3VyZWQgY2x1c3RlciBkb21haW4gc3VmZml4LFxuICAgKiBzdWNoIGFzIFwid3d3Lmt1YmVybmV0ZXMuaW9cIiwgaXMgZm9yd2FyZGVkIHRvIHRoZVxuICAgKiB1cHN0cmVhbSBuYW1lc2VydmVyIGluaGVyaXRlZCBmcm9tIHRoZSBub2RlLlxuICAgKiBDbHVzdGVyIGFkbWluaXN0cmF0b3JzIG1heSBoYXZlIGV4dHJhIHN0dWItZG9tYWluIGFuZCB1cHN0cmVhbSBETlMgc2VydmVycyBjb25maWd1cmVkLlxuICAgKi9cbiAgQ0xVU1RFUl9GSVJTVCA9ICdDbHVzdGVyRmlyc3QnLFxuXG4gIC8qKlxuICAgKiBGb3IgUG9kcyBydW5uaW5nIHdpdGggaG9zdE5ldHdvcmssIHlvdSBzaG91bGRcbiAgICogZXhwbGljaXRseSBzZXQgaXRzIEROUyBwb2xpY3kgXCJDbHVzdGVyRmlyc3RXaXRoSG9zdE5ldFwiLlxuICAgKi9cbiAgQ0xVU1RFUl9GSVJTVF9XSVRIX0hPU1RfTkVUID0gJ0NsdXN0ZXJGaXJzdFdpdGhIb3N0TmV0JyxcblxuICAvKipcbiAgICogVGhlIFBvZCBpbmhlcml0cyB0aGUgbmFtZSByZXNvbHV0aW9uIGNvbmZpZ3VyYXRpb25cbiAgICogZnJvbSB0aGUgbm9kZSB0aGF0IHRoZSBwb2RzIHJ1biBvbi5cbiAgICovXG4gIERFRkFVTFQgPSAnRGVmYXVsdCcsXG5cbiAgLyoqXG4gICAqIEl0IGFsbG93cyBhIFBvZCB0byBpZ25vcmUgRE5TIHNldHRpbmdzIGZyb20gdGhlIEt1YmVybmV0ZXMgZW52aXJvbm1lbnQuXG4gICAqIEFsbCBETlMgc2V0dGluZ3MgYXJlIHN1cHBvc2VkIHRvIGJlIHByb3ZpZGVkIHVzaW5nIHRoZSBkbnNDb25maWdcbiAgICogZmllbGQgaW4gdGhlIFBvZCBTcGVjLlxuICAgKi9cbiAgTk9ORSA9ICdOb25lJyxcblxufVxuXG4vKipcbiAqIEhvc3RBbGlhcyBob2xkcyB0aGUgbWFwcGluZyBiZXR3ZWVuIElQIGFuZCBob3N0bmFtZXMgdGhhdCB3aWxsIGJlIGluamVjdGVkIGFzXG4gKiBhbiBlbnRyeSBpbiB0aGUgcG9kJ3MgL2V0Yy9ob3N0cyBmaWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEhvc3RBbGlhcyB7XG4gIC8qKlxuICAgKiBIb3N0bmFtZXMgZm9yIHRoZSBjaG9zZW4gSVAgYWRkcmVzcy5cbiAgICovXG4gIHJlYWRvbmx5IGhvc3RuYW1lczogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIElQIGFkZHJlc3Mgb2YgdGhlIGhvc3QgZmlsZSBlbnRyeS5cbiAgICovXG4gIHJlYWRvbmx5IGlwOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHF1ZXJ5IHRoYXQgY2FuIGJlIHBlcmZvcm1lZCBhZ2FpbnN0IG5vZGVzIHdpdGggbGFiZWxzLlxuICovXG5leHBvcnQgY2xhc3MgTm9kZUxhYmVsUXVlcnkge1xuXG4gIC8qKlxuICAgKiBSZXF1aXJlcyB2YWx1ZSBvZiBsYWJlbCBga2V5YCB0byBlcXVhbCBgdmFsdWVgLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBpcyhrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZykge1xuICAgIHJldHVybiBOb2RlTGFiZWxRdWVyeS5pbihrZXksIFt2YWx1ZV0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcXVpcmVzIHZhbHVlIG9mIGxhYmVsIGBrZXlgIHRvIGJlIG9uZSBvZiBgdmFsdWVzYC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgaW4oa2V5OiBzdHJpbmcsIHZhbHVlczogc3RyaW5nW10pIHtcbiAgICByZXR1cm4gbmV3IE5vZGVMYWJlbFF1ZXJ5KGtleSwgJ0luJywgdmFsdWVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1aXJlcyB2YWx1ZSBvZiBsYWJlbCBga2V5YCB0byBiZSBub25lIG9mIGB2YWx1ZXNgLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBub3RJbihrZXk6IHN0cmluZywgdmFsdWVzOiBzdHJpbmdbXSkge1xuICAgIHJldHVybiBuZXcgTm9kZUxhYmVsUXVlcnkoa2V5LCAnTm90SW4nLCB2YWx1ZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcXVpcmVzIGxhYmVsIGBrZXlgIHRvIGV4aXN0LlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBleGlzdHMoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gbmV3IE5vZGVMYWJlbFF1ZXJ5KGtleSwgJ0V4aXN0cycsIHVuZGVmaW5lZCk7XG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZXMgbGFiZWwgYGtleWAgdG8gbm90IGV4aXN0LlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBkb2VzTm90RXhpc3Qoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gbmV3IE5vZGVMYWJlbFF1ZXJ5KGtleSwgJ0RvZXNOb3RFeGlzdCcsIHVuZGVmaW5lZCk7XG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZXMgdmFsdWUgb2YgbGFiZWwgYGtleWAgdG8gZ3JlYXRlciB0aGFuIGFsbCBlbGVtZW50cyBpbiBgdmFsdWVzYC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZ3Qoa2V5OiBzdHJpbmcsIHZhbHVlczogc3RyaW5nW10pIHtcbiAgICByZXR1cm4gbmV3IE5vZGVMYWJlbFF1ZXJ5KGtleSwgJ0d0JywgdmFsdWVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1aXJlcyB2YWx1ZSBvZiBsYWJlbCBga2V5YCB0byBsZXNzIHRoYW4gYWxsIGVsZW1lbnRzIGluIGB2YWx1ZXNgLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBsdChrZXk6IHN0cmluZywgdmFsdWVzOiBzdHJpbmdbXSkge1xuICAgIHJldHVybiBuZXcgTm9kZUxhYmVsUXVlcnkoa2V5LCAnTHQnLCB2YWx1ZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGtleTogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3BlcmF0b3I6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHZhbHVlcz86IHN0cmluZ1tdKSB7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgX3RvS3ViZSgpOiBrOHMuTm9kZVNlbGVjdG9yUmVxdWlyZW1lbnQge1xuICAgIHJldHVybiB7XG4gICAgICBrZXk6IHRoaXMua2V5LFxuICAgICAgb3BlcmF0b3I6IHRoaXMub3BlcmF0b3IsXG4gICAgICB2YWx1ZXM6IHRoaXMudmFsdWVzLFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgcXVlcnkgdGhhdCBjYW4gYmUgcGVyZm9ybWVkIGFnYWluc3QgcmVzb3VyY2VzIHdpdGggbGFiZWxzLlxuICovXG5leHBvcnQgY2xhc3MgTGFiZWxFeHByZXNzaW9uIHtcblxuICAvKipcbiAgICogUmVxdWlyZXMgdmFsdWUgb2YgbGFiZWwgYGtleWAgdG8gYmUgb25lIG9mIGB2YWx1ZXNgLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBpbihrZXk6IHN0cmluZywgdmFsdWVzOiBzdHJpbmdbXSkge1xuICAgIHJldHVybiBuZXcgTGFiZWxFeHByZXNzaW9uKGtleSwgJ0luJywgdmFsdWVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1aXJlcyB2YWx1ZSBvZiBsYWJlbCBga2V5YCB0byBiZSBub25lIG9mIGB2YWx1ZXNgLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBub3RJbihrZXk6IHN0cmluZywgdmFsdWVzOiBzdHJpbmdbXSkge1xuICAgIHJldHVybiBuZXcgTGFiZWxFeHByZXNzaW9uKGtleSwgJ05vdEluJywgdmFsdWVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1aXJlcyBsYWJlbCBga2V5YCB0byBleGlzdC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZXhpc3RzKGtleTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBMYWJlbEV4cHJlc3Npb24oa2V5LCAnRXhpc3RzJywgdW5kZWZpbmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1aXJlcyBsYWJlbCBga2V5YCB0byBub3QgZXhpc3QuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGRvZXNOb3RFeGlzdChrZXk6IHN0cmluZykge1xuICAgIHJldHVybiBuZXcgTGFiZWxFeHByZXNzaW9uKGtleSwgJ0RvZXNOb3RFeGlzdCcsIHVuZGVmaW5lZCk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSBrZXk6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgb3BlcmF0b3I6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgdmFsdWVzPzogc3RyaW5nW10pIHtcbiAgfVxuXG59XG5cbi8qKlxuICogVGFpbnQgZWZmZWN0cy5cbiAqL1xuZXhwb3J0IGVudW0gVGFpbnRFZmZlY3Qge1xuICAvKipcbiAgICogVGhpcyBtZWFucyB0aGF0IG5vIHBvZCB3aWxsIGJlIGFibGUgdG8gc2NoZWR1bGVcbiAgICogb250byB0aGUgbm9kZSB1bmxlc3MgaXQgaGFzIGEgbWF0Y2hpbmcgdG9sZXJhdGlvbi5cbiAgICovXG4gIE5PX1NDSEVEVUxFID0gJ05vU2NoZWR1bGUnLFxuXG4gIC8qKlxuICAgKiBUaGlzIGlzIGEgXCJwcmVmZXJlbmNlXCIgb3IgXCJzb2Z0XCIgdmVyc2lvbiBvZiBgTk9fU0NIRURVTEVgIC0tIHRoZSBzeXN0ZW1cbiAgICogd2lsbCB0cnkgdG8gYXZvaWQgcGxhY2luZyBhIHBvZCB0aGF0IGRvZXMgbm90IHRvbGVyYXRlIHRoZSB0YWludCBvbiB0aGUgbm9kZSxcbiAgICogYnV0IGl0IGlzIG5vdCByZXF1aXJlZFxuICAgKi9cbiAgUFJFRkVSX05PX1NDSEVEVUxFID0gJ1ByZWZlck5vU2NoZWR1bGUnLFxuXG4gIC8qKlxuICAgKiBUaGlzIGFmZmVjdHMgcG9kcyB0aGF0IGFyZSBhbHJlYWR5IHJ1bm5pbmcgb24gdGhlIG5vZGUgYXMgZm9sbG93czpcbiAgICpcbiAgICogLSBQb2RzIHRoYXQgZG8gbm90IHRvbGVyYXRlIHRoZSB0YWludCBhcmUgZXZpY3RlZCBpbW1lZGlhdGVseS5cbiAgICogLSBQb2RzIHRoYXQgdG9sZXJhdGUgdGhlIHRhaW50IHdpdGhvdXQgc3BlY2lmeWluZyBgZHVyYXRpb25gIHJlbWFpbiBib3VuZCBmb3JldmVyLlxuICAgKiAtIFBvZHMgdGhhdCB0b2xlcmF0ZSB0aGUgdGFpbnQgd2l0aCBhIHNwZWNpZmllZCBgZHVyYXRpb25gIHJlbWFpbiBib3VuZCBmb3JcbiAgICogICB0aGUgc3BlY2lmaWVkIGFtb3VudCBvZiB0aW1lLlxuICAgKi9cbiAgTk9fRVhFQ1VURSA9ICdOb0V4ZWN1dGUnLFxufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGBOb2RlVGFpbnRRdWVyeWAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTm9kZVRhaW50UXVlcnlPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSB0YWludCBlZmZlY3QgdG8gbWF0Y2guXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYWxsIGVmZmVjdHMgYXJlIG1hdGNoZWQuXG4gICAqL1xuICByZWFkb25seSBlZmZlY3Q/OiBUYWludEVmZmVjdDtcblxuICAvKipcbiAgICogSG93IG11Y2ggdGltZSBzaG91bGQgYSBwb2QgdGhhdCB0b2xlcmF0ZXMgdGhlIGBOT19FWEVDVVRFYCBlZmZlY3RcbiAgICogYmUgYm91bmQgdG8gdGhlIG5vZGUuIE9ubHkgYXBwbGllcyBmb3IgdGhlIGBOT19FWEVDVVRFYCBlZmZlY3QuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYm91bmQgZm9yZXZlci5cbiAgICovXG4gIHJlYWRvbmx5IGV2aWN0QWZ0ZXI/OiBEdXJhdGlvbjtcbn1cblxuLyoqXG4gKiBUYWludCBxdWVyaWVzIHRoYXQgY2FuIGJlIHBlcmZvbWVkIGFnYWluc3Qgbm9kZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBOb2RlVGFpbnRRdWVyeSB7XG5cbiAgLyoqXG4gICAqIE1hdGNoZXMgYSB0YWludCB3aXRoIGEgc3BlY2lmaWMga2V5IGFuZCB2YWx1ZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgaXMoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcsIG9wdGlvbnM6IE5vZGVUYWludFF1ZXJ5T3B0aW9ucyA9IHt9KTogTm9kZVRhaW50UXVlcnkge1xuICAgIHJldHVybiBuZXcgTm9kZVRhaW50UXVlcnkoJ0VxdWFsJywga2V5LCB2YWx1ZSwgb3B0aW9ucy5lZmZlY3QsIG9wdGlvbnMuZXZpY3RBZnRlcik7XG4gIH1cblxuICAvKipcbiAgICogTWF0Y2hlcyBhIHRhaW4gd2l0aCBhbnkgdmFsdWUgb2YgYSBzcGVjaWZpYyBrZXkuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGV4aXN0cyhrZXk6IHN0cmluZywgb3B0aW9uczogTm9kZVRhaW50UXVlcnlPcHRpb25zID0ge30pOiBOb2RlVGFpbnRRdWVyeSB7XG4gICAgcmV0dXJuIG5ldyBOb2RlVGFpbnRRdWVyeSgnRXhpc3RzJywga2V5LCB1bmRlZmluZWQsIG9wdGlvbnMuZWZmZWN0LCBvcHRpb25zLmV2aWN0QWZ0ZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hdGNoZXMgYW55IHRhaW50LlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhbnkoKTogTm9kZVRhaW50UXVlcnkge1xuICAgIHJldHVybiBuZXcgTm9kZVRhaW50UXVlcnkoJ0V4aXN0cycpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wZXJhdG9yOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBrZXk/OiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSB2YWx1ZT86IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGVmZmVjdD86IFRhaW50RWZmZWN0LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZXZpY3RBZnRlcj86IER1cmF0aW9uLFxuICApIHtcbiAgICBpZiAoZXZpY3RBZnRlciAmJiBlZmZlY3QgIT09IFRhaW50RWZmZWN0Lk5PX0VYRUNVVEUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBcXCdOT19FWEVDVVRFXFwnIGVmZmVjdHMgY2FuIHNwZWNpZnkgXFwnZXZpY3RBZnRlclxcJycpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdG9LdWJlKCk6IGs4cy5Ub2xlcmF0aW9uIHtcblxuICAgIHJldHVybiB7XG4gICAgICBlZmZlY3Q6IHRoaXMuZWZmZWN0LFxuICAgICAga2V5OiB0aGlzLmtleSxcbiAgICAgIG9wZXJhdG9yOiB0aGlzLm9wZXJhdG9yLFxuICAgICAgdG9sZXJhdGlvblNlY29uZHM6IHRoaXMuZXZpY3RBZnRlcj8udG9TZWNvbmRzKCksXG4gICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcbiAgICB9O1xuICB9XG5cbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBgUG9kcy5hbGxgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvZHNBbGxPcHRpb25zIHtcblxuICAvKipcbiAgICogTmFtZXNwYWNlcyB0aGUgcG9kcyBhcmUgYWxsb3dlZCB0byBiZSBpbi5cbiAgICogVXNlIGBOYW1lc3BhY2VzLmFsbCgpYCB0byBhbGxvdyBhbGwgbmFtZXNwYWNlcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB1bnNldCwgaW1wbGllcyB0aGUgbmFtZXNwYWNlIG9mIHRoZSByZXNvdXJjZSB0aGlzIHNlbGVjdGlvbiBpcyB1c2VkIGluLlxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZXNwYWNlcz86IG5hbWVzcGFjZS5OYW1lc3BhY2VzO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGBQb2RzLnNlbGVjdGAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUG9kc1NlbGVjdE9wdGlvbnMge1xuXG4gIC8qKlxuICAgKiBMYWJlbHMgdGhlIHBvZHMgbXVzdCBoYXZlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIHN0cmljdCBsYWJlbHMgcmVxdWlyZW1lbnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWxzPzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcblxuICAvKipcbiAgICAqIEV4cHJlc3Npb25zIHRoZSBwb2RzIG11c3Qgc2F0aXNpZnkuXG4gICAgKlxuICAgICogQGRlZmF1bHQgLSBubyBleHByZXNzaW9ucyByZXF1aXJlbWVudHMuXG4gICAgKi9cbiAgcmVhZG9ubHkgZXhwcmVzc2lvbnM/OiBMYWJlbEV4cHJlc3Npb25bXTtcblxuICAvKipcbiAgICogTmFtZXNwYWNlcyB0aGUgcG9kcyBhcmUgYWxsb3dlZCB0byBiZSBpbi5cbiAgICogVXNlIGBOYW1lc3BhY2VzLmFsbCgpYCB0byBhbGxvdyBhbGwgbmFtZXNwYWNlcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB1bnNldCwgaW1wbGllcyB0aGUgbmFtZXNwYWNlIG9mIHRoZSByZXNvdXJjZSB0aGlzIHNlbGVjdGlvbiBpcyB1c2VkIGluLlxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZXNwYWNlcz86IG5hbWVzcGFjZS5OYW1lc3BhY2VzO1xuXG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIGdyb3VwIG9mIHBvZHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBQb2RzIGV4dGVuZHMgQ29uc3RydWN0IGltcGxlbWVudHMgSVBvZFNlbGVjdG9yIHtcblxuICAvKipcbiAgICogU2VsZWN0IHBvZHMgaW4gdGhlIGNsdXN0ZXIgd2l0aCB2YXJpb3VzIHNlbGVjdG9ycy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgc2VsZWN0KHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIG9wdGlvbnM6IFBvZHNTZWxlY3RPcHRpb25zKTogUG9kcyB7XG4gICAgcmV0dXJuIG5ldyBQb2RzKHNjb3BlLCBpZCwgb3B0aW9ucy5leHByZXNzaW9ucywgb3B0aW9ucy5sYWJlbHMsIG9wdGlvbnMubmFtZXNwYWNlcyk7XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0IGFsbCBwb2RzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhbGwoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgb3B0aW9uczogUG9kc0FsbE9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiBQb2RzLnNlbGVjdChzY29wZSwgaWQsIHsgbmFtZXNwYWNlczogb3B0aW9ucy5uYW1lc3BhY2VzIH0pO1xuICB9XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGV4cHJlc3Npb25zPzogTGFiZWxFeHByZXNzaW9uW10sXG4gICAgcHJpdmF0ZSByZWFkb25seSBsYWJlbHM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbmFtZXNwYWNlcz86IG5hbWVzcGFjZS5JTmFtZXNwYWNlU2VsZWN0b3IpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzZWUgSVBvZFNlbGVjdG9yLnRvUG9kU2VsZWN0b3JDb25maWcoKVxuICAgKi9cbiAgcHVibGljIHRvUG9kU2VsZWN0b3JDb25maWcoKTogUG9kU2VsZWN0b3JDb25maWcge1xuICAgIHJldHVybiB7XG4gICAgICBsYWJlbFNlbGVjdG9yOiBMYWJlbFNlbGVjdG9yLm9mKHsgZXhwcmVzc2lvbnM6IHRoaXMuZXhwcmVzc2lvbnMsIGxhYmVsczogdGhpcy5sYWJlbHMgfSksXG4gICAgICBuYW1lc3BhY2VzOiB0aGlzLm5hbWVzcGFjZXM/LnRvTmFtZXNwYWNlU2VsZWN0b3JDb25maWcoKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzZWUgSU5ldHdvcmtQb2xpY3lQZWVyLnRvTmV0d29ya1BvbGljeVBlZXJDb25maWcoKVxuICAgKi9cbiAgcHVibGljIHRvTmV0d29ya1BvbGljeVBlZXJDb25maWcoKTogbmV0d29ya3BvbGljeS5OZXR3b3JrUG9saWN5UGVlckNvbmZpZyB7XG4gICAgcmV0dXJuIHsgcG9kU2VsZWN0b3I6IHRoaXMudG9Qb2RTZWxlY3RvckNvbmZpZygpIH07XG4gIH1cblxuICAvKipcbiAgICogQHNlZSBJTmV0d29ya1BvbGljeVBlZXIudG9Qb2RTZWxlY3RvcigpXG4gICAqL1xuICBwdWJsaWMgdG9Qb2RTZWxlY3RvcigpOiBJUG9kU2VsZWN0b3IgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbn1cblxuLyoqXG4gKiBBIG5vZGUgdGhhdCBpcyBtYXRjaGVkIGJ5IGxhYmVsIHNlbGVjdG9ycy5cbiAqL1xuZXhwb3J0IGNsYXNzIExhYmVsZWROb2RlIHtcbiAgcHVibGljIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSBsYWJlbFNlbGVjdG9yOiBOb2RlTGFiZWxRdWVyeVtdKSB7fTtcbn1cblxuLyoqXG4gKiBBIG5vZGUgdGhhdCBpcyBtYXRjaGVkIGJ5IHRhaW50IHNlbGVjdG9ycy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRhaW50ZWROb2RlIHtcbiAgcHVibGljIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSB0YWludFNlbGVjdG9yOiBOb2RlVGFpbnRRdWVyeVtdKSB7fTtcbn1cblxuLyoqXG4gKiBBIG5vZGUgdGhhdCBpcyBtYXRjaGVkIGJ5IGl0cyBuYW1lLlxuICovXG5leHBvcnQgY2xhc3MgTmFtZWROb2RlIHtcbiAgcHVibGljIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmcpIHt9O1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBub2RlIGluIHRoZSBjbHVzdGVyLlxuICovXG5leHBvcnQgY2xhc3MgTm9kZSB7XG5cbiAgLyoqXG4gICAqIE1hdGNoIGEgbm9kZSBieSBpdHMgbGFiZWxzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBsYWJlbGVkKC4uLmxhYmVsU2VsZWN0b3I6IE5vZGVMYWJlbFF1ZXJ5W10pOiBMYWJlbGVkTm9kZSB7XG4gICAgcmV0dXJuIG5ldyBMYWJlbGVkTm9kZShsYWJlbFNlbGVjdG9yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXRjaCBhIG5vZGUgYnkgaXRzIG5hbWUuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIG5hbWVkKG5vZGVOYW1lOiBzdHJpbmcpOiBOYW1lZE5vZGUge1xuICAgIHJldHVybiBuZXcgTmFtZWROb2RlKG5vZGVOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXRjaCBhIG5vZGUgYnkgaXRzIHRhaW50cy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgdGFpbnRlZCguLi50YWludFNlbGVjdG9yOiBOb2RlVGFpbnRRdWVyeVtdKTogVGFpbnRlZE5vZGUge1xuICAgIHJldHVybiBuZXcgVGFpbnRlZE5vZGUodGFpbnRTZWxlY3Rvcik7XG4gIH1cblxufVxuXG4vKipcbiAqIEF2YWlsYWJsZSB0b3BvbG9neSBkb21haW5zLlxuICovXG5leHBvcnQgY2xhc3MgVG9wb2xvZ3kge1xuXG4gIC8qKlxuICAgKiBBIGhvc3RuYW1lIHJlcHJlc2VudHMgYSBzaW5nbGUgbm9kZSBpbiB0aGUgY2x1c3Rlci5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9yZWZlcmVuY2UvbGFiZWxzLWFubm90YXRpb25zLXRhaW50cy8ja3ViZXJuZXRlc2lvaG9zdG5hbWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgSE9TVE5BTUUgPSBuZXcgVG9wb2xvZ3koJ2t1YmVybmV0ZXMuaW8vaG9zdG5hbWUnKTtcblxuICAvKipcbiAgICogQSB6b25lIHJlcHJlc2VudHMgYSBsb2dpY2FsIGZhaWx1cmUgZG9tYWluLiBJdCBpcyBjb21tb24gZm9yIEt1YmVybmV0ZXMgY2x1c3RlcnMgdG9cbiAgICogc3BhbiBtdWx0aXBsZSB6b25lcyBmb3IgaW5jcmVhc2VkIGF2YWlsYWJpbGl0eS4gV2hpbGUgdGhlIGV4YWN0IGRlZmluaXRpb24gb2YgYSB6b25lIGlzXG4gICAqIGxlZnQgdG8gaW5mcmFzdHJ1Y3R1cmUgaW1wbGVtZW50YXRpb25zLCBjb21tb24gcHJvcGVydGllcyBvZiBhIHpvbmUgaW5jbHVkZSB2ZXJ5IGxvd1xuICAgKiBuZXR3b3JrIGxhdGVuY3kgd2l0aGluIGEgem9uZSwgbm8tY29zdCBuZXR3b3JrIHRyYWZmaWMgd2l0aGluIGEgem9uZSwgYW5kIGZhaWx1cmVcbiAgICogaW5kZXBlbmRlbmNlIGZyb20gb3RoZXIgem9uZXMuIEZvciBleGFtcGxlLCBub2RlcyB3aXRoaW4gYSB6b25lIG1pZ2h0IHNoYXJlIGEgbmV0d29ya1xuICAgKiBzd2l0Y2gsIGJ1dCBub2RlcyBpbiBkaWZmZXJlbnQgem9uZXMgc2hvdWxkIG5vdC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9yZWZlcmVuY2UvbGFiZWxzLWFubm90YXRpb25zLXRhaW50cy8jdG9wb2xvZ3lrdWJlcm5ldGVzaW96b25lXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFpPTkUgPSBuZXcgVG9wb2xvZ3koJ3RvcG9sb2d5Lmt1YmVybmV0ZXMuaW8vem9uZScpO1xuXG4gIC8qKlxuICAgKiBBIHJlZ2lvbiByZXByZXNlbnRzIGEgbGFyZ2VyIGRvbWFpbiwgbWFkZSB1cCBvZiBvbmUgb3IgbW9yZSB6b25lcy4gSXQgaXMgdW5jb21tb25cbiAgICogZm9yIEt1YmVybmV0ZXMgY2x1c3RlcnMgdG8gc3BhbiBtdWx0aXBsZSByZWdpb25zLiBXaGlsZSB0aGUgZXhhY3QgZGVmaW5pdGlvbiBvZiBhXG4gICAqIHpvbmUgb3IgcmVnaW9uIGlzIGxlZnQgdG8gaW5mcmFzdHJ1Y3R1cmUgaW1wbGVtZW50YXRpb25zLCBjb21tb24gcHJvcGVydGllcyBvZiBhIHJlZ2lvblxuICAgKiBpbmNsdWRlIGhpZ2hlciBuZXR3b3JrIGxhdGVuY3kgYmV0d2VlbiB0aGVtIHRoYW4gd2l0aGluIHRoZW0sIG5vbi16ZXJvIGNvc3QgZm9yIG5ldHdvcmtcbiAgICogdHJhZmZpYyBiZXR3ZWVuIHRoZW0sIGFuZCBmYWlsdXJlIGluZGVwZW5kZW5jZSBmcm9tIG90aGVyIHpvbmVzIG9yIHJlZ2lvbnMuXG4gICAqXG4gICAqIEZvciBleGFtcGxlLCBub2RlcyB3aXRoaW4gYSByZWdpb24gbWlnaHQgc2hhcmUgcG93ZXIgaW5mcmFzdHJ1Y3R1cmUgKGUuZy4gYSBVUFMgb3IgZ2VuZXJhdG9yKSwgYnV0XG4gICAqIG5vZGVzIGluIGRpZmZlcmVudCByZWdpb25zIHR5cGljYWxseSB3b3VsZCBub3QuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvcmVmZXJlbmNlL2xhYmVscy1hbm5vdGF0aW9ucy10YWludHMvI3RvcG9sb2d5a3ViZXJuZXRlc2lvcmVnaW9uXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFJFR0lPTiA9IG5ldyBUb3BvbG9neSgndG9wb2xvZ3kua3ViZXJuZXRlcy5pby9yZWdpb24nKTtcblxuICAvKipcbiAgICogQ3VzdG9tIGtleSBmb3IgdGhlIG5vZGUgbGFiZWwgdGhhdCB0aGUgc3lzdGVtIHVzZXMgdG8gZGVub3RlIHRoZSB0b3BvbG9neSBkb21haW4uXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGN1c3RvbShrZXk6IHN0cmluZyk6IFRvcG9sb2d5IHtcbiAgICByZXR1cm4gbmV3IFRvcG9sb2d5KGtleSk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSBrZXk6IHN0cmluZykge307XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYFBvZFNjaGVkdWxpbmcuY29sb2NhdGVgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvZFNjaGVkdWxpbmdDb2xvY2F0ZU9wdGlvbnMge1xuICAvKipcbiAgICogV2hpY2ggdG9wb2xvZ3kgdG8gY29sb2F0ZSBvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUb3BvbG9neS5IT1NUTkFNRVxuICAgKi9cbiAgcmVhZG9ubHkgdG9wb2xvZ3k/OiBUb3BvbG9neTtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoZSBjby1sb2NhdGlvbiBpcyBvcHRpb25hbCAoc29mdCksIHdpdGggdGhpcyB3ZWlnaHQgc2NvcmUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gd2VpZ2h0LiBjby1sb2NhdGlvbiBpcyBhc3N1bWVkIHRvIGJlIHJlcXVpcmVkIChoYXJkKS5cbiAgICovXG4gIHJlYWRvbmx5IHdlaWdodD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBgUG9kU2NoZWR1bGluZy5zZXBhcmF0ZWAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUG9kU2NoZWR1bGluZ1NlcGFyYXRlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBXaGljaCB0b3BvbG9neSB0byBzZXBhcmF0ZSBvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUb3BvbG9neS5IT1NUTkFNRVxuICAgKi9cbiAgcmVhZG9ubHkgdG9wb2xvZ3k/OiBUb3BvbG9neTtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoZSBzZXBhcmF0aW9uIGlzIG9wdGlvbmFsIChzb2Z0KSwgd2l0aCB0aGlzIHdlaWdodCBzY29yZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyB3ZWlnaHQuIHNlcGFyYXRpb24gaXMgYXNzdW1lZCB0byBiZSByZXF1aXJlZCAoaGFyZCkuXG4gICAqL1xuICByZWFkb25seSB3ZWlnaHQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYFBvZFNjaGVkdWxpbmcuYXR0cmFjdGAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUG9kU2NoZWR1bGluZ0F0dHJhY3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGUgYXR0cmFjdGlvbiBpcyBvcHRpb25hbCAoc29mdCksIHdpdGggdGhpcyB3ZWlnaHQgc2NvcmUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gd2VpZ2h0LiBhc3NpZ25tZW50IGlzIGFzc3VtZWQgdG8gYmUgcmVxdWlyZWQgKGhhcmQpLlxuICAgKi9cbiAgcmVhZG9ubHkgd2VpZ2h0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIENvbnRyb2xzIHRoZSBwb2Qgc2NoZWR1bGluZyBzdHJhdGVneS5cbiAqL1xuZXhwb3J0IGNsYXNzIFBvZFNjaGVkdWxpbmcge1xuXG4gIHByaXZhdGUgX25vZGVBZmZpbml0eVByZWZlcnJlZDogazhzLlByZWZlcnJlZFNjaGVkdWxpbmdUZXJtW10gPSBbXTtcbiAgcHJpdmF0ZSBfbm9kZUFmZmluaXR5UmVxdWlyZWQ6IGs4cy5Ob2RlU2VsZWN0b3JUZXJtW10gPSBbXTtcbiAgcHJpdmF0ZSBfcG9kQWZmaW5pdHlQcmVmZXJyZWQ6IGs4cy5XZWlnaHRlZFBvZEFmZmluaXR5VGVybVtdID0gW107XG4gIHByaXZhdGUgX3BvZEFmZmluaXR5UmVxdWlyZWQ6IGs4cy5Qb2RBZmZpbml0eVRlcm1bXSA9IFtdO1xuICBwcml2YXRlIF9wb2RBbnRpQWZmaW5pdHlQcmVmZXJyZWQ6IGs4cy5XZWlnaHRlZFBvZEFmZmluaXR5VGVybVtdID0gW107XG4gIHByaXZhdGUgX3BvZEFudGlBZmZpbml0eVJlcXVpcmVkOiBrOHMuUG9kQWZmaW5pdHlUZXJtW10gPSBbXTtcbiAgcHJpdmF0ZSBfdG9sZXJhdGlvbnM6IGs4cy5Ub2xlcmF0aW9uW10gPSBbXTtcbiAgcHJpdmF0ZSBfbm9kZU5hbWU/OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIHJlYWRvbmx5IGluc3RhbmNlOiBBYnN0cmFjdFBvZCkge31cblxuICAvKipcbiAgICogQXNzaWduIHRoaXMgcG9kIGEgc3BlY2lmaWMgbm9kZSBieSBuYW1lLlxuICAgKlxuICAgKiBUaGUgc2NoZWR1bGVyIGlnbm9yZXMgdGhlIFBvZCwgYW5kIHRoZSBrdWJlbGV0IG9uIHRoZSBuYW1lZCBub2RlXG4gICAqIHRyaWVzIHRvIHBsYWNlIHRoZSBQb2Qgb24gdGhhdCBub2RlLiBPdmVycnVsZXMgYW55IGFmZmluaXR5IHJ1bGVzIG9mIHRoZSBwb2QuXG4gICAqXG4gICAqIFNvbWUgbGltaXRhdGlvbnMgb2Ygc3RhdGljIGFzc2lnbm1lbnQgYXJlOlxuICAgKlxuICAgKiAtIElmIHRoZSBuYW1lZCBub2RlIGRvZXMgbm90IGV4aXN0LCB0aGUgUG9kIHdpbGwgbm90IHJ1biwgYW5kIGluIHNvbWVcbiAgICogICBjYXNlcyBtYXkgYmUgYXV0b21hdGljYWxseSBkZWxldGVkLlxuICAgKiAtIElmIHRoZSBuYW1lZCBub2RlIGRvZXMgbm90IGhhdmUgdGhlIHJlc291cmNlcyB0byBhY2NvbW1vZGF0ZSB0aGUgUG9kLFxuICAgKiAgIHRoZSBQb2Qgd2lsbCBmYWlsIGFuZCBpdHMgcmVhc29uIHdpbGwgaW5kaWNhdGUgd2h5LCBmb3IgZXhhbXBsZSBPdXRPZm1lbW9yeSBvciBPdXRPZmNwdS5cbiAgICogLSBOb2RlIG5hbWVzIGluIGNsb3VkIGVudmlyb25tZW50cyBhcmUgbm90IGFsd2F5cyBwcmVkaWN0YWJsZSBvciBzdGFibGUuXG4gICAqXG4gICAqIFdpbGwgdGhyb3cgaXMgdGhlIHBvZCBpcyBhbHJlYWR5IGFzc2lnbmVkIHRvIG5hbWVkIG5vZGUuXG4gICAqXG4gICAqIFVuZGVyIHRoZSBob29kLCB0aGlzIG1ldGhvZCB1dGlsaXplcyB0aGUgYG5vZGVOYW1lYCBwcm9wZXJ0eS5cbiAgICovXG4gIHB1YmxpYyBhc3NpZ24obm9kZTogTmFtZWROb2RlKSB7XG5cbiAgICBpZiAodGhpcy5fbm9kZU5hbWUpIHtcbiAgICAgIC8vIGRpc2FsbG93IG92ZXJyaWRpbmcgYW4gc3RhdGljIG5vZGUgYXNzaWdubWVudFxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgYXNzaWduICR7dGhpcy5pbnN0YW5jZS5wb2RNZXRhZGF0YS5uYW1lfSB0byBub2RlICR7bm9kZS5uYW1lfS4gSXQgaXMgYWxyZWFkeSBhc3NpZ25lZCB0byBub2RlICR7dGhpcy5fbm9kZU5hbWV9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX25vZGVOYW1lID0gbm9kZS5uYW1lO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBbGxvdyB0aGlzIHBvZCB0byB0b2xlcmF0ZSB0YWludHMgbWF0Y2hpbmcgdGhlc2UgdG9sZXJhdGlvbnMuXG4gICAqXG4gICAqIFlvdSBjYW4gcHV0IG11bHRpcGxlIHRhaW50cyBvbiB0aGUgc2FtZSBub2RlIGFuZCBtdWx0aXBsZSB0b2xlcmF0aW9ucyBvbiB0aGUgc2FtZSBwb2QuXG4gICAqIFRoZSB3YXkgS3ViZXJuZXRlcyBwcm9jZXNzZXMgbXVsdGlwbGUgdGFpbnRzIGFuZCB0b2xlcmF0aW9ucyBpcyBsaWtlIGEgZmlsdGVyOiBzdGFydCB3aXRoXG4gICAqIGFsbCBvZiBhIG5vZGUncyB0YWludHMsIHRoZW4gaWdub3JlIHRoZSBvbmVzIGZvciB3aGljaCB0aGUgcG9kIGhhcyBhIG1hdGNoaW5nIHRvbGVyYXRpb247XG4gICAqIHRoZSByZW1haW5pbmcgdW4taWdub3JlZCB0YWludHMgaGF2ZSB0aGUgaW5kaWNhdGVkIGVmZmVjdHMgb24gdGhlIHBvZC4gSW4gcGFydGljdWxhcjpcbiAgICpcbiAgICogLSBpZiB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgdW4taWdub3JlZCB0YWludCB3aXRoIGVmZmVjdCBOb1NjaGVkdWxlIHRoZW4gS3ViZXJuZXRlcyB3aWxsXG4gICAqICAgbm90IHNjaGVkdWxlIHRoZSBwb2Qgb250byB0aGF0IG5vZGVcbiAgICogLSBpZiB0aGVyZSBpcyBubyB1bi1pZ25vcmVkIHRhaW50IHdpdGggZWZmZWN0IE5vU2NoZWR1bGUgYnV0IHRoZXJlIGlzIGF0IGxlYXN0IG9uZSB1bi1pZ25vcmVkXG4gICAqICAgdGFpbnQgd2l0aCBlZmZlY3QgUHJlZmVyTm9TY2hlZHVsZSB0aGVuIEt1YmVybmV0ZXMgd2lsbCB0cnkgdG8gbm90IHNjaGVkdWxlIHRoZSBwb2Qgb250byB0aGUgbm9kZVxuICAgKiAtIGlmIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSB1bi1pZ25vcmVkIHRhaW50IHdpdGggZWZmZWN0IE5vRXhlY3V0ZSB0aGVuIHRoZSBwb2Qgd2lsbCBiZSBldmljdGVkIGZyb21cbiAgICogICB0aGUgbm9kZSAoaWYgaXQgaXMgYWxyZWFkeSBydW5uaW5nIG9uIHRoZSBub2RlKSwgYW5kIHdpbGwgbm90IGJlIHNjaGVkdWxlZCBvbnRvIHRoZSBub2RlIChpZiBpdCBpc1xuICAgKiAgIG5vdCB5ZXQgcnVubmluZyBvbiB0aGUgbm9kZSkuXG4gICAqXG4gICAqIFVuZGVyIHRoZSBob29kLCB0aGlzIG1ldGhvZCB1dGlsaXplcyB0aGUgYHRvbGVyYXRpb25zYCBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9jb25jZXB0cy9zY2hlZHVsaW5nLWV2aWN0aW9uL3RhaW50LWFuZC10b2xlcmF0aW9uL1xuICAgKi9cbiAgcHVibGljIHRvbGVyYXRlKG5vZGU6IFRhaW50ZWROb2RlKSB7XG4gICAgZm9yIChjb25zdCBxdWVyeSBvZiBub2RlLnRhaW50U2VsZWN0b3IpIHtcbiAgICAgIHRoaXMuX3RvbGVyYXRpb25zLnB1c2gocXVlcnkuX3RvS3ViZSgpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQXR0cmFjdCB0aGlzIHBvZCB0byBhIG5vZGUgbWF0Y2hlZCBieSBzZWxlY3RvcnMuXG4gICAqIFlvdSBjYW4gc2VsZWN0IGEgbm9kZSBieSB1c2luZyBgTm9kZS5sYWJlbGVkKClgLlxuICAgKlxuICAgKiBBdHRyYWN0aW5nIHRvIG11bHRpcGxlIG5vZGVzIChpLmUgaW52b2tpbmcgdGhpcyBtZXRob2QgbXVsdGlwbGUgdGltZXMpIGFjdHMgYXNcbiAgICogYW4gT1IgY29uZGl0aW9uLCBtZWFuaW5nIHRoZSBwb2Qgd2lsbCBiZSBhc3NpZ25lZCB0byBlaXRoZXIgb25lIG9mIHRoZSBub2Rlcy5cbiAgICpcbiAgICogVW5kZXIgdGhlIGhvb2QsIHRoaXMgbWV0aG9kIHV0aWxpemVzIHRoZSBgbm9kZUFmZmluaXR5YCBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9jb25jZXB0cy9zY2hlZHVsaW5nLWV2aWN0aW9uL2Fzc2lnbi1wb2Qtbm9kZS8jbm9kZS1hZmZpbml0eVxuICAgKi9cbiAgcHVibGljIGF0dHJhY3Qobm9kZTogTGFiZWxlZE5vZGUsIG9wdGlvbnM6IFBvZFNjaGVkdWxpbmdBdHRyYWN0T3B0aW9ucyA9IHt9KSB7XG5cbiAgICBjb25zdCB0ZXJtID0gdGhpcy5jcmVhdGVOb2RlQWZmaW5pdHlUZXJtKG5vZGUpO1xuXG4gICAgaWYgKG9wdGlvbnMud2VpZ2h0KSB7XG4gICAgICB0aGlzLnZhbGlkYXRlV2VpZ2h0KG9wdGlvbnMud2VpZ2h0KTtcbiAgICAgIHRoaXMuX25vZGVBZmZpbml0eVByZWZlcnJlZC5wdXNoKHsgd2VpZ2h0OiBvcHRpb25zLndlaWdodCwgcHJlZmVyZW5jZTogdGVybSB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fbm9kZUFmZmluaXR5UmVxdWlyZWQucHVzaCh0ZXJtKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ28tbG9jYXRlIHRoaXMgcG9kIHdpdGggYSBzY2hlZHVsaW5nIHNlbGVjdGlvbi5cbiAgICpcbiAgICogQSBzZWxlY3Rpb24gY2FuIGJlIG9uZSBvZjpcbiAgICpcbiAgICogLSBBbiBpbnN0YW5jZSBvZiBhIGBQb2RgLlxuICAgKiAtIEFuIGluc3RhbmNlIG9mIGEgYFdvcmtsb2FkYCAoZS5nIGBEZXBsb3ltZW50YCwgYFN0YXRlZnVsU2V0YCkuXG4gICAqIC0gQW4gdW4tbWFuYWdlZCBwb2QgdGhhdCBjYW4gYmUgc2VsZWN0ZWQgdmlhIGBQb2RzLnNlbGVjdCgpYC5cbiAgICpcbiAgICogQ28tbG9jYXRpbmcgd2l0aCBtdWx0aXBsZSBzZWxlY3Rpb25zICgoaS5lIGludm9raW5nIHRoaXMgbWV0aG9kIG11bHRpcGxlIHRpbWVzKSkgYWN0cyBhc1xuICAgKiBhbiBBTkQgY29uZGl0aW9uLiBtZWFuaW5nIHRoZSBwb2Qgd2lsbCBiZSBhc3NpZ25lZCB0byBhIG5vZGUgdGhhdCBzYXRpc2ZpZXMgYWxsXG4gICAqIHNlbGVjdGlvbnMgKGkuZSBydW5zIGF0IGxlYXN0IG9uZSBwb2QgdGhhdCBzYXRpc2lmaWVzIGVhY2ggc2VsZWN0aW9uKS5cbiAgICpcbiAgICogVW5kZXIgdGhlIGhvb2QsIHRoaXMgbWV0aG9kIHV0aWxpemVzIHRoZSBgcG9kQWZmaW5pdHlgIHByb3BlcnR5LlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8va3ViZXJuZXRlcy5pby9kb2NzL2NvbmNlcHRzL3NjaGVkdWxpbmctZXZpY3Rpb24vYXNzaWduLXBvZC1ub2RlLyNpbnRlci1wb2QtYWZmaW5pdHktYW5kLWFudGktYWZmaW5pdHlcbiAgICovXG4gIHB1YmxpYyBjb2xvY2F0ZShzZWxlY3RvcjogSVBvZFNlbGVjdG9yLCBvcHRpb25zOiBQb2RTY2hlZHVsaW5nQ29sb2NhdGVPcHRpb25zID0ge30pIHtcblxuICAgIGNvbnN0IHRvcG9sb2d5ID0gb3B0aW9ucy50b3BvbG9neSA/PyBUb3BvbG9neS5IT1NUTkFNRTtcbiAgICBjb25zdCB0ZXJtID0gdGhpcy5jcmVhdGVQb2RBZmZpbml0eVRlcm0odG9wb2xvZ3ksIHNlbGVjdG9yKTtcblxuICAgIGlmIChvcHRpb25zLndlaWdodCkge1xuICAgICAgdGhpcy52YWxpZGF0ZVdlaWdodChvcHRpb25zLndlaWdodCk7XG4gICAgICB0aGlzLl9wb2RBZmZpbml0eVByZWZlcnJlZC5wdXNoKHsgd2VpZ2h0OiBvcHRpb25zLndlaWdodCwgcG9kQWZmaW5pdHlUZXJtOiB0ZXJtIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9wb2RBZmZpbml0eVJlcXVpcmVkLnB1c2godGVybSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNlcGVyYXRlIHRoaXMgcG9kIGZyb20gYSBzY2hlZHVsaW5nIHNlbGVjdGlvbi5cbiAgICpcbiAgICogQSBzZWxlY3Rpb24gY2FuIGJlIG9uZSBvZjpcbiAgICpcbiAgICogLSBBbiBpbnN0YW5jZSBvZiBhIGBQb2RgLlxuICAgKiAtIEFuIGluc3RhbmNlIG9mIGEgYFdvcmtsb2FkYCAoZS5nIGBEZXBsb3ltZW50YCwgYFN0YXRlZnVsU2V0YCkuXG4gICAqIC0gQW4gdW4tbWFuYWdlZCBwb2QgdGhhdCBjYW4gYmUgc2VsZWN0ZWQgdmlhIGBQb2RzLnNlbGVjdCgpYC5cbiAgICpcbiAgICogU2VwZXJhdGluZyBmcm9tIG11bHRpcGxlIHNlbGVjdGlvbnMgYWN0cyBhcyBhbiBBTkQgY29uZGl0aW9uLiBtZWFuaW5nIHRoZSBwb2RcbiAgICogd2lsbCBub3QgYmUgYXNzaWduZWQgdG8gYSBub2RlIHRoYXQgc2F0aXNmaWVzIGFsbCBzZWxlY3Rpb25zIChpLmUgcnVucyBhdCBsZWFzdCBvbmUgcG9kIHRoYXQgc2F0aXNpZmllcyBlYWNoIHNlbGVjdGlvbikuXG4gICAqXG4gICAqIFVuZGVyIHRoZSBob29kLCB0aGlzIG1ldGhvZCB1dGlsaXplcyB0aGUgYHBvZEFudGlBZmZpbml0eWAgcHJvcGVydHkuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvY29uY2VwdHMvc2NoZWR1bGluZy1ldmljdGlvbi9hc3NpZ24tcG9kLW5vZGUvI2ludGVyLXBvZC1hZmZpbml0eS1hbmQtYW50aS1hZmZpbml0eVxuICAgKi9cbiAgcHVibGljIHNlcGFyYXRlKHNlbGVjdG9yOiBJUG9kU2VsZWN0b3IsIG9wdGlvbnM6IFBvZFNjaGVkdWxpbmdTZXBhcmF0ZU9wdGlvbnMgPSB7fSkge1xuXG4gICAgY29uc3QgdG9wb2xvZ3kgPSBvcHRpb25zLnRvcG9sb2d5ID8/IFRvcG9sb2d5LkhPU1ROQU1FO1xuICAgIGNvbnN0IHRlcm0gPSB0aGlzLmNyZWF0ZVBvZEFmZmluaXR5VGVybSh0b3BvbG9neSwgc2VsZWN0b3IpO1xuXG4gICAgaWYgKG9wdGlvbnMud2VpZ2h0KSB7XG4gICAgICB0aGlzLnZhbGlkYXRlV2VpZ2h0KG9wdGlvbnMud2VpZ2h0KTtcbiAgICAgIHRoaXMuX3BvZEFudGlBZmZpbml0eVByZWZlcnJlZC5wdXNoKHsgd2VpZ2h0OiBvcHRpb25zLndlaWdodCwgcG9kQWZmaW5pdHlUZXJtOiB0ZXJtIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9wb2RBbnRpQWZmaW5pdHlSZXF1aXJlZC5wdXNoKHRlcm0pO1xuICAgIH1cblxuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVQb2RBZmZpbml0eVRlcm0odG9wb2xvZ3k6IFRvcG9sb2d5LCBzZWxlY3RvcjogSVBvZFNlbGVjdG9yKTogazhzLlBvZEFmZmluaXR5VGVybSB7XG4gICAgY29uc3QgY29uZmlnID0gc2VsZWN0b3IudG9Qb2RTZWxlY3RvckNvbmZpZygpO1xuICAgIHJldHVybiB7XG4gICAgICB0b3BvbG9neUtleTogdG9wb2xvZ3kua2V5LFxuICAgICAgbGFiZWxTZWxlY3RvcjogY29uZmlnLmxhYmVsU2VsZWN0b3IuX3RvS3ViZSgpLFxuICAgICAgbmFtZXNwYWNlU2VsZWN0b3I6IGNvbmZpZy5uYW1lc3BhY2VzPy5sYWJlbFNlbGVjdG9yPy5fdG9LdWJlKCksXG4gICAgICBuYW1lc3BhY2VzOiBjb25maWcubmFtZXNwYWNlcz8ubmFtZXMsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlTm9kZUFmZmluaXR5VGVybShub2RlOiBMYWJlbGVkTm9kZSk6IGs4cy5Ob2RlU2VsZWN0b3JUZXJtIHtcbiAgICByZXR1cm4geyBtYXRjaEV4cHJlc3Npb25zOiBub2RlLmxhYmVsU2VsZWN0b3IubWFwKHMgPT4gcy5fdG9LdWJlKCkpIH07XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlV2VpZ2h0KHdlaWdodDogbnVtYmVyKSB7XG4gICAgaWYgKHdlaWdodCA8IDEgfHwgd2VpZ2h0ID4gMTAwKSB7XG4gICAgICAvLyBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9jb25jZXB0cy9zY2hlZHVsaW5nLWV2aWN0aW9uL2Fzc2lnbi1wb2Qtbm9kZS8jbm9kZS1hZmZpbml0eS13ZWlnaHRcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBhZmZpbml0eSB3ZWlnaHQ6ICR7d2VpZ2h0fS4gTXVzdCBiZSBpbiByYW5nZSAxLTEwMGApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdG9LdWJlKCk6IHsgYWZmaW5pdHk/OiBrOHMuQWZmaW5pdHk7IG5vZGVOYW1lPzogc3RyaW5nOyB0b2xlcmF0aW9ucz86IGs4cy5Ub2xlcmF0aW9uW10gfSB7XG5cbiAgICBjb25zdCBhdExlYXN0T25lID0gKC4uLmFycmF5czogQXJyYXk8YW55PltdKSA9PiB7XG4gICAgICByZXR1cm4gYXJyYXlzLmZsYXQoKS5sZW5ndGggPiAwO1xuICAgIH07XG5cbiAgICBjb25zdCBoYXNOb2RlQWZmaW5pdHkgPSBhdExlYXN0T25lKHRoaXMuX25vZGVBZmZpbml0eVByZWZlcnJlZCwgdGhpcy5fbm9kZUFmZmluaXR5UmVxdWlyZWQpO1xuICAgIGNvbnN0IGhhc1BvZEFmZmluaXR5ID0gYXRMZWFzdE9uZSh0aGlzLl9wb2RBZmZpbml0eVByZWZlcnJlZCwgdGhpcy5fcG9kQWZmaW5pdHlSZXF1aXJlZCk7XG4gICAgY29uc3QgaGFzUG9kQW50aUFmZmludHkgPSBhdExlYXN0T25lKHRoaXMuX3BvZEFudGlBZmZpbml0eVByZWZlcnJlZCwgdGhpcy5fcG9kQW50aUFmZmluaXR5UmVxdWlyZWQpO1xuICAgIGNvbnN0IGhhc0FmZmluaXR5ID0gaGFzTm9kZUFmZmluaXR5IHx8IGhhc1BvZEFmZmluaXR5IHx8IGhhc1BvZEFudGlBZmZpbnR5O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFmZmluaXR5OiBoYXNBZmZpbml0eSA/IHtcbiAgICAgICAgbm9kZUFmZmluaXR5OiBoYXNOb2RlQWZmaW5pdHkgPyB7XG4gICAgICAgICAgcHJlZmVycmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb246IHVuZGVmaW5lZElmRW1wdHkodGhpcy5fbm9kZUFmZmluaXR5UHJlZmVycmVkKSxcbiAgICAgICAgICByZXF1aXJlZER1cmluZ1NjaGVkdWxpbmdJZ25vcmVkRHVyaW5nRXhlY3V0aW9uOiB0aGlzLl9ub2RlQWZmaW5pdHlSZXF1aXJlZC5sZW5ndGggPiAwID8ge1xuICAgICAgICAgICAgbm9kZVNlbGVjdG9yVGVybXM6IHRoaXMuX25vZGVBZmZpbml0eVJlcXVpcmVkLFxuICAgICAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgICAgIHBvZEFmZmluaXR5OiBoYXNQb2RBZmZpbml0eSA/IHtcbiAgICAgICAgICBwcmVmZXJyZWREdXJpbmdTY2hlZHVsaW5nSWdub3JlZER1cmluZ0V4ZWN1dGlvbjogdW5kZWZpbmVkSWZFbXB0eSh0aGlzLl9wb2RBZmZpbml0eVByZWZlcnJlZCksXG4gICAgICAgICAgcmVxdWlyZWREdXJpbmdTY2hlZHVsaW5nSWdub3JlZER1cmluZ0V4ZWN1dGlvbjogdW5kZWZpbmVkSWZFbXB0eSh0aGlzLl9wb2RBZmZpbml0eVJlcXVpcmVkKSxcbiAgICAgICAgfSA6IHVuZGVmaW5lZCxcbiAgICAgICAgcG9kQW50aUFmZmluaXR5OiBoYXNQb2RBbnRpQWZmaW50eSA/IHtcbiAgICAgICAgICBwcmVmZXJyZWREdXJpbmdTY2hlZHVsaW5nSWdub3JlZER1cmluZ0V4ZWN1dGlvbjogdW5kZWZpbmVkSWZFbXB0eSh0aGlzLl9wb2RBbnRpQWZmaW5pdHlQcmVmZXJyZWQpLFxuICAgICAgICAgIHJlcXVpcmVkRHVyaW5nU2NoZWR1bGluZ0lnbm9yZWREdXJpbmdFeGVjdXRpb246IHVuZGVmaW5lZElmRW1wdHkodGhpcy5fcG9kQW50aUFmZmluaXR5UmVxdWlyZWQpLFxuICAgICAgICB9IDogdW5kZWZpbmVkLFxuICAgICAgfSA6IHVuZGVmaW5lZCxcbiAgICAgIG5vZGVOYW1lOiB0aGlzLl9ub2RlTmFtZSxcbiAgICAgIHRvbGVyYXRpb25zOiB1bmRlZmluZWRJZkVtcHR5KHRoaXMuX3RvbGVyYXRpb25zKSxcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogSXNvbGF0aW9uIGRldGVybWluZXMgd2hpY2ggcG9saWNpZXMgYXJlIGNyZWF0ZWRcbiAqIHdoZW4gYWxsb3dpbmcgY29ubmVjdGlvbnMgZnJvbSBhIGEgcG9kIC8gd29ya2xvYWQgdG8gcGVlcnMuXG4gKi9cbmV4cG9ydCBlbnVtIFBvZENvbm5lY3Rpb25zSXNvbGF0aW9uIHtcblxuICAvKipcbiAgICogT25seSBjcmVhdGVzIG5ldHdvcmsgcG9saWNpZXMgdGhhdCBzZWxlY3QgdGhlIHBvZC5cbiAgICovXG4gIFBPRCA9ICdQT0QnLFxuXG4gIC8qKlxuICAgKiBPbmx5IGNyZWF0ZXMgbmV0d29yayBwb2xpY2llcyB0aGF0IHNlbGVjdCB0aGUgcGVlci5cbiAgICovXG4gIFBFRVIgPSAnUEVFUicsXG5cbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBgUG9kQ29ubmVjdGlvbnMuYWxsb3dUb2AuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUG9kQ29ubmVjdGlvbnNBbGxvd1RvT3B0aW9ucyB7XG5cbiAgLyoqXG4gICAqIFdoaWNoIGlzb2xhdGlvbiBzaG91bGQgYmUgYXBwbGllZCB0byBlc3RhYmxpc2ggdGhlIGNvbm5lY3Rpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdW5zZXQsIGlzb2xhdGVzIGJvdGggdGhlIHBvZCBhbmQgdGhlIHBlZXIuXG4gICAqL1xuICByZWFkb25seSBpc29sYXRpb24/OiBQb2RDb25uZWN0aW9uc0lzb2xhdGlvbjtcblxuICAvKipcbiAgICogUG9ydHMgdG8gYWxsb3cgb3V0Z29pbmcgdHJhZmZpYyB0by5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBJZiB0aGUgcGVlciBpcyBhIG1hbmFnZWQgcG9kLCB0YWtlIGl0cyBwb3J0cy4gT3RoZXJ3aXNlLCBhbGwgcG9ydHMgYXJlIGFsbG93ZWQuXG4gICAqL1xuICByZWFkb25seSBwb3J0cz86IG5ldHdvcmtwb2xpY3kuTmV0d29ya1BvbGljeVBvcnRbXTtcblxufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGBQb2RDb25uZWN0aW9ucy5hbGxvd0Zyb21gLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvZENvbm5lY3Rpb25zQWxsb3dGcm9tT3B0aW9ucyB7XG5cbiAgLyoqXG4gICAqIFdoaWNoIGlzb2xhdGlvbiBzaG91bGQgYmUgYXBwbGllZCB0byBlc3RhYmxpc2ggdGhlIGNvbm5lY3Rpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdW5zZXQsIGlzb2xhdGVzIGJvdGggdGhlIHBvZCBhbmQgdGhlIHBlZXIuXG4gICAqL1xuICByZWFkb25seSBpc29sYXRpb24/OiBQb2RDb25uZWN0aW9uc0lzb2xhdGlvbjtcblxuICAvKipcbiAgICogUG9ydHMgdG8gYWxsb3cgaW5jb21pbmcgdHJhZmZpYyB0by5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUaGUgcG9kIHBvcnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgcG9ydHM/OiBuZXR3b3JrcG9saWN5Lk5ldHdvcmtQb2xpY3lQb3J0W107XG5cbn1cblxuLyoqXG4gKiBDb250cm9scyBuZXR3b3JrIGlzb2xhdGlvbiBydWxlcyBmb3IgaW50ZXItcG9kIGNvbW11bmljYXRpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBQb2RDb25uZWN0aW9ucyB7XG5cbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIHJlYWRvbmx5IGluc3RhbmNlOiBBYnN0cmFjdFBvZCkge31cblxuICAvKipcbiAgICogQWxsb3cgbmV0d29yayB0cmFmZmljIGZyb20gdGhpcyBwb2QgdG8gdGhlIHBlZXIuXG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIHRoaXMgd2lsbCBjcmVhdGUgYW4gZWdyZXNzIG5ldHdvcmsgcG9saWN5IGZvciB0aGlzIHBvZCwgYW5kIGFuIGluZ3Jlc3NcbiAgICogbmV0d29yayBwb2xpY3kgZm9yIHRoZSBwZWVyLiBUaGlzIGlzIHJlcXVpcmVkIGlmIGJvdGggc2lkZXMgYXJlIGFscmVhZHkgaXNvbGF0ZWQuXG4gICAqIFVzZSBgb3B0aW9ucy5pc29sYXRpb25gIHRvIGNvbnRyb2wgdGhpcyBiZWhhdmlvci5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogLy8gY3JlYXRlIG9ubHkgYW4gZWdyZXNzIHBvbGljeSB0aGF0IHNlbGVjdHMgdGhlICd3ZWInIHBvZCB0byBhbGxvdyBvdXRnb2luZyB0cmFmZmljXG4gICAqIC8vIHRvIHRoZSAncmVkaXMnIHBvZC4gdGhpcyByZXF1aXJlcyB0aGUgJ3JlZGlzJyBwb2QgdG8gbm90IGJlIGlzb2xhdGVkIGZvciBpbmdyZXNzLlxuICAgKiB3ZWIuY29ubmVjdGlvbnMuYWxsb3dUbyhyZWRpcywgeyBpc29sYXRpb246IElzb2xhdGlvbi5QT0QgfSlcbiAgICpcbiAgICogLy8gY3JlYXRlIG9ubHkgYW4gaW5ncmVzcyBwb2xpY3kgdGhhdCBzZWxlY3RzIHRoZSAncmVkaXMnIHBlZXIgdG8gYWxsb3cgaW5jb21pbmcgdHJhZmZpY1xuICAgKiAvLyBmcm9tIHRoZSAnd2ViJyBwb2QuIHRoaXMgcmVxdWlyZXMgdGhlICd3ZWInIHBvZCB0byBub3QgYmUgaXNvbGF0ZWQgZm9yIGVncmVzcy5cbiAgICogd2ViLmNvbm5lY3Rpb25zLmFsbG93VG8ocmVkaXMsIHsgaXNvbGF0aW9uOiBJc29sYXRpb24uUEVFUiB9KVxuICAgKlxuICAgKi9cbiAgcHVibGljIGFsbG93VG8ocGVlcjogbmV0d29ya3BvbGljeS5JTmV0d29ya1BvbGljeVBlZXIsIG9wdGlvbnM6IFBvZENvbm5lY3Rpb25zQWxsb3dUb09wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLmFsbG93KCdFZ3Jlc3MnLCBwZWVyLCB7IHBvcnRzOiB0aGlzLmV4dHJhY3RQb3J0cyhwZWVyKSwgLi4ub3B0aW9ucyB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbGxvdyBuZXR3b3JrIHRyYWZmaWMgZnJvbSB0aGUgcGVlciB0byB0aGlzIHBvZC5cbiAgICpcbiAgICogQnkgZGVmYXVsdCwgdGhpcyB3aWxsIGNyZWF0ZSBhbiBpbmdyZXNzIG5ldHdvcmsgcG9saWN5IGZvciB0aGlzIHBvZCwgYW5kIGFuIGVncmVzc1xuICAgKiBuZXR3b3JrIHBvbGljeSBmb3IgdGhlIHBlZXIuIFRoaXMgaXMgcmVxdWlyZWQgaWYgYm90aCBzaWRlcyBhcmUgYWxyZWFkeSBpc29sYXRlZC5cbiAgICogVXNlIGBvcHRpb25zLmlzb2xhdGlvbmAgdG8gY29udHJvbCB0aGlzIGJlaGF2aW9yLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiAvLyBjcmVhdGUgb25seSBhbiBlZ3Jlc3MgcG9saWN5IHRoYXQgc2VsZWN0cyB0aGUgJ3dlYicgcG9kIHRvIGFsbG93IG91dGdvaW5nIHRyYWZmaWNcbiAgICogLy8gdG8gdGhlICdyZWRpcycgcG9kLiB0aGlzIHJlcXVpcmVzIHRoZSAncmVkaXMnIHBvZCB0byBub3QgYmUgaXNvbGF0ZWQgZm9yIGluZ3Jlc3MuXG4gICAqIHJlZGlzLmNvbm5lY3Rpb25zLmFsbG93RnJvbSh3ZWIsIHsgaXNvbGF0aW9uOiBJc29sYXRpb24uUEVFUiB9KVxuICAgKlxuICAgKiAvLyBjcmVhdGUgb25seSBhbiBpbmdyZXNzIHBvbGljeSB0aGF0IHNlbGVjdHMgdGhlICdyZWRpcycgcGVlciB0byBhbGxvdyBpbmNvbWluZyB0cmFmZmljXG4gICAqIC8vIGZyb20gdGhlICd3ZWInIHBvZC4gdGhpcyByZXF1aXJlcyB0aGUgJ3dlYicgcG9kIHRvIG5vdCBiZSBpc29sYXRlZCBmb3IgZWdyZXNzLlxuICAgKiByZWRpcy5jb25uZWN0aW9ucy5hbGxvd0Zyb20od2ViLCB7IGlzb2xhdGlvbjogSXNvbGF0aW9uLlBPRCB9KVxuICAgKlxuICAgKi9cbiAgcHVibGljIGFsbG93RnJvbShwZWVyOiBuZXR3b3JrcG9saWN5LklOZXR3b3JrUG9saWN5UGVlciwgb3B0aW9uczogUG9kQ29ubmVjdGlvbnNBbGxvd0Zyb21PcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5hbGxvdygnSW5ncmVzcycsIHBlZXIsIHsgcG9ydHM6IHRoaXMuZXh0cmFjdFBvcnRzKHRoaXMuaW5zdGFuY2UpLCAuLi5vcHRpb25zIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhbGxvdyhkaXJlY3Rpb246ICdJbmdyZXNzJyB8ICdFZ3Jlc3MnLCBwZWVyOiBuZXR3b3JrcG9saWN5LklOZXR3b3JrUG9saWN5UGVlciwgb3B0aW9uczogUG9kQ29ubmVjdGlvbnNBbGxvd1RvT3B0aW9ucyB8IFBvZENvbm5lY3Rpb25zQWxsb3dGcm9tT3B0aW9ucyA9IHt9KSB7XG5cbiAgICBjb25zdCBjb25maWcgPSBwZWVyLnRvTmV0d29ya1BvbGljeVBlZXJDb25maWcoKTtcbiAgICBuZXR3b3JrcG9saWN5LnZhbGlkYXRlUGVlckNvbmZpZyhjb25maWcpO1xuXG4gICAgY29uc3QgcGVlckFkZHJlc3MgPSBhZGRyZXNzKHBlZXIpO1xuXG4gICAgaWYgKCFvcHRpb25zLmlzb2xhdGlvbiB8fCBvcHRpb25zLmlzb2xhdGlvbiA9PT0gUG9kQ29ubmVjdGlvbnNJc29sYXRpb24uUE9EKSB7XG5cbiAgICAgIGNvbnN0IHNyYyA9IG5ldyBuZXR3b3JrcG9saWN5Lk5ldHdvcmtQb2xpY3kodGhpcy5pbnN0YW5jZSwgYEFsbG93JHtkaXJlY3Rpb259JHtwZWVyQWRkcmVzc31gLCB7XG4gICAgICAgIHNlbGVjdG9yOiB0aGlzLmluc3RhbmNlLFxuICAgICAgICAvLyB0aGUgcG9saWN5IG11c3QgYmUgZGVmaW5lZCBpbiB0aGUgbmFtZXNwYWNlIG9mIHRoZSBwb2RcbiAgICAgICAgLy8gc28gaXQgY2FuIHNlbGVjdCBpdC5cbiAgICAgICAgbWV0YWRhdGE6IHsgbmFtZXNwYWNlOiB0aGlzLmluc3RhbmNlLm1ldGFkYXRhLm5hbWVzcGFjZSB9LFxuICAgICAgfSk7XG5cbiAgICAgIHN3aXRjaCAoZGlyZWN0aW9uKSB7XG4gICAgICAgIGNhc2UgJ0VncmVzcyc6XG4gICAgICAgICAgc3JjLmFkZEVncmVzc1J1bGUocGVlciwgb3B0aW9ucy5wb3J0cyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0luZ3Jlc3MnOlxuICAgICAgICAgIHNyYy5hZGRJbmdyZXNzUnVsZShwZWVyLCBvcHRpb25zLnBvcnRzKTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIGlmICghb3B0aW9ucy5pc29sYXRpb24gfHwgb3B0aW9ucy5pc29sYXRpb24gPT09IFBvZENvbm5lY3Rpb25zSXNvbGF0aW9uLlBFRVIpIHtcblxuICAgICAgaWYgKGNvbmZpZy5pcEJsb2NrKSB7XG4gICAgICAgIC8vIGZvciBhbiBpcCBibG9jayB3ZSBkb24ndCBuZWVkIHRvIGNyZWF0ZSB0aGUgb3Bwb3NpdGUgcG9saWNpZXNcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwb2RTZWxlY3RvciA9IHBlZXIudG9Qb2RTZWxlY3RvcigpO1xuICAgICAgaWYgKCFwb2RTZWxlY3Rvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBjcmVhdGUgcG9saWNpZXMgZm9yIHBlZXIgJyR7cGVlci5ub2RlLmFkZHJ9JyBzaW5jZSBpdHMgbm90IGEgcG9kIHNlbGVjdG9yYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9wcG9zaXRlRGlyZWN0aW9uID0gZGlyZWN0aW9uID09PSAnRWdyZXNzJyA/ICdJbmdyZXNzJyA6ICdFZ3Jlc3MnO1xuXG4gICAgICBjb25zdCBwb2RTZWxlY3RvckNvbmZpZyA9IHBvZFNlbGVjdG9yLnRvUG9kU2VsZWN0b3JDb25maWcoKTtcbiAgICAgIGxldCBuYW1lc3BhY2VzOiAoc3RyaW5nIHwgdW5kZWZpbmVkKVtdO1xuXG4gICAgICBpZiAoIXBvZFNlbGVjdG9yQ29uZmlnLm5hbWVzcGFjZXMpIHtcblxuICAgICAgICAvLyBpZiB0aGUgcGVlciBkb2Vzbid0IHNwZWNpZnkgbmFtZXNwYWNlcywgd2UgYXNzdW1lIHRoZSBzYW1lIG5hbWVzcGFjZS5cbiAgICAgICAgbmFtZXNwYWNlcyA9IFt0aGlzLmluc3RhbmNlLm1ldGFkYXRhLm5hbWVzcGFjZV07XG5cbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLy8gYSBwZWVyIGNhbm5vdCBzcGVjaWZ5IG5hbWVzcGFjZXMgYnkgbGFiZWxzIGJlY2F1c2VcbiAgICAgICAgLy8gd2Ugd29uJ3QgYmUgYWJsZSB0byBleHRyYWN0IHRoZSBuYW1lcyBvZiB0aG9zZSBuYW1lc3BhY2VzLlxuICAgICAgICBpZiAocG9kU2VsZWN0b3JDb25maWcubmFtZXNwYWNlcy5sYWJlbFNlbGVjdG9yICYmICFwb2RTZWxlY3RvckNvbmZpZy5uYW1lc3BhY2VzLmxhYmVsU2VsZWN0b3IuaXNFbXB0eSgpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gY3JlYXRlIGFuICR7b3Bwb3NpdGVEaXJlY3Rpb259IHBvbGljeSBmb3IgcGVlciAnJHtwZWVyLm5vZGUucGF0aH0nIChwb2Q9JHt0aGlzLmluc3RhbmNlLm5hbWV9KS4gUGVlciBtdXN0IHNwZWNpZnkgbmFtZXNwYWNlcyBvbmx5IGJ5IG5hbWVgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGEgcGVlciBtdXN0IHNwZWNpZnkgbmFtZXNwYWNlcyBieSBuYW1lLlxuICAgICAgICBpZiAoIXBvZFNlbGVjdG9yQ29uZmlnLm5hbWVzcGFjZXMubmFtZXMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBjcmVhdGUgYW4gJHtvcHBvc2l0ZURpcmVjdGlvbn0gcG9saWN5IGZvciBwZWVyICcke3BlZXIubm9kZS5wYXRofScgKHBvZD0ke3RoaXMuaW5zdGFuY2UubmFtZX0pLiBQZWVyIG11c3Qgc3BlY2lmeSBuYW1lc3BhY2UgbmFtZXNgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5hbWVzcGFjZXMgPSBwb2RTZWxlY3RvckNvbmZpZy5uYW1lc3BhY2VzLm5hbWVzO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgbmFtZXNwYWNlcykge1xuICAgICAgICBzd2l0Y2ggKGRpcmVjdGlvbikge1xuICAgICAgICAgIGNhc2UgJ0VncmVzcyc6XG4gICAgICAgICAgICBuZXcgbmV0d29ya3BvbGljeS5OZXR3b3JrUG9saWN5KHRoaXMuaW5zdGFuY2UsIGBBbGxvd0luZ3Jlc3Mke25hbWV9JHtwZWVyQWRkcmVzc31gLCB7XG4gICAgICAgICAgICAgIHNlbGVjdG9yOiBwb2RTZWxlY3RvcixcbiAgICAgICAgICAgICAgbWV0YWRhdGE6IHsgbmFtZXNwYWNlOiBuYW1lIH0sXG4gICAgICAgICAgICAgIGluZ3Jlc3M6IHsgcnVsZXM6IFt7IHBlZXI6IHRoaXMuaW5zdGFuY2UsIHBvcnRzOiBvcHRpb25zLnBvcnRzIH1dIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ0luZ3Jlc3MnOlxuICAgICAgICAgICAgbmV3IG5ldHdvcmtwb2xpY3kuTmV0d29ya1BvbGljeSh0aGlzLmluc3RhbmNlLCBgQWxsb3dFZ3Jlc3Mke25hbWV9JHtwZWVyQWRkcmVzc31gLCB7XG4gICAgICAgICAgICAgIHNlbGVjdG9yOiBwb2RTZWxlY3RvcixcbiAgICAgICAgICAgICAgbWV0YWRhdGE6IHsgbmFtZXNwYWNlOiBuYW1lIH0sXG4gICAgICAgICAgICAgIGVncmVzczogeyBydWxlczogW3sgcGVlcjogdGhpcy5pbnN0YW5jZSwgcG9ydHM6IG9wdGlvbnMucG9ydHMgfV0gfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZGlyZWN0aW9uOiAke2RpcmVjdGlvbn1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0UG9ydHMoc2VsZWN0b3I/OiBuZXR3b3JrcG9saWN5LklOZXR3b3JrUG9saWN5UGVlcik6IG5ldHdvcmtwb2xpY3kuTmV0d29ya1BvbGljeVBvcnRbXSB7XG4gICAgcmV0dXJuIGNvbnRhaW5lci5leHRyYWN0Q29udGFpbmVyUG9ydHMoc2VsZWN0b3IpLm1hcChuID0+IG5ldHdvcmtwb2xpY3kuTmV0d29ya1BvbGljeVBvcnQudGNwKG4ubnVtYmVyKSk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgZGVmYXVsdCBuZXR3b3JrIHBvbGljeSBmb3IgUG9kL1dvcmtsb2FkIHRvIGhhdmUgYWxsIGVncmVzcyBhbmQgaW5ncmVzcyBjb25uZWN0aW9ucyBhcyBkaXNhYmxlZFxuICAgKi9cbiAgcHVibGljIGlzb2xhdGUoKSB7XG4gICAgbmV3IG5ldHdvcmtwb2xpY3kuTmV0d29ya1BvbGljeSh0aGlzLmluc3RhbmNlLCAnRGVmYXVsdERlbnlBbGwnLCB7XG4gICAgICBzZWxlY3RvcjogdGhpcy5pbnN0YW5jZSxcbiAgICAgIC8vIHRoZSBwb2xpY3kgbXVzdCBiZSBkZWZpbmVkIGluIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIHBvZFxuICAgICAgLy8gc28gaXQgY2FuIHNlbGVjdCBpdC5cbiAgICAgIG1ldGFkYXRhOiB7IG5hbWVzcGFjZTogdGhpcy5pbnN0YW5jZS5tZXRhZGF0YS5uYW1lc3BhY2UgfSxcbiAgICAgIGVncmVzczoge1xuICAgICAgICBkZWZhdWx0OiBuZXR3b3JrcG9saWN5Lk5ldHdvcmtQb2xpY3lUcmFmZmljRGVmYXVsdC5ERU5ZLFxuICAgICAgfSxcbiAgICAgIGluZ3Jlc3M6IHtcbiAgICAgICAgZGVmYXVsdDogbmV0d29ya3BvbGljeS5OZXR3b3JrUG9saWN5VHJhZmZpY0RlZmF1bHQuREVOWSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==