@alauda-fe/network 1.0.0-beta.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 (46) hide show
  1. package/esm2022/alauda-fe-network.mjs +5 -0
  2. package/esm2022/index.mjs +19 -0
  3. package/esm2022/lib/components/certificate-status/component.mjs +37 -0
  4. package/esm2022/lib/components/fixed-ip/component.mjs +503 -0
  5. package/esm2022/lib/components/loadbalancer-spec-form/component.mjs +251 -0
  6. package/esm2022/lib/components/service-annotations-form/annotations.component.mjs +681 -0
  7. package/esm2022/lib/components/service-annotations-form-item/annotations.component.mjs +106 -0
  8. package/esm2022/lib/components/service-form/component.mjs +307 -0
  9. package/esm2022/lib/components/service-form/fieldset/component.mjs +407 -0
  10. package/esm2022/lib/directives/subnet-validator.directive.mjs +111 -0
  11. package/esm2022/lib/services/alb-api.service.mjs +48 -0
  12. package/esm2022/lib/services/certificate-api.service.mjs +111 -0
  13. package/esm2022/lib/services/network-util.service.mjs +116 -0
  14. package/esm2022/lib/types/alb-exports.mjs +14 -0
  15. package/esm2022/lib/types/k8s-exports.mjs +13 -0
  16. package/esm2022/lib/types/resource-definition.mjs +16 -0
  17. package/esm2022/lib/utils/alb-exports.mjs +108 -0
  18. package/esm2022/lib/utils/alb-internals.mjs +2 -0
  19. package/esm2022/lib/utils/cidr-exports.mjs +359 -0
  20. package/esm2022/lib/utils/cluster-exports.mjs +18 -0
  21. package/esm2022/lib/utils/service-exports.mjs +58 -0
  22. package/esm2022/lib/utils/service-internals.mjs +7 -0
  23. package/esm2022/lib/utils/subnet-exports.mjs +18 -0
  24. package/index.d.ts +18 -0
  25. package/lib/components/certificate-status/component.d.ts +17 -0
  26. package/lib/components/fixed-ip/component.d.ts +67 -0
  27. package/lib/components/loadbalancer-spec-form/component.d.ts +34 -0
  28. package/lib/components/service-annotations-form/annotations.component.d.ts +74 -0
  29. package/lib/components/service-annotations-form-item/annotations.component.d.ts +14 -0
  30. package/lib/components/service-form/component.d.ts +56 -0
  31. package/lib/components/service-form/fieldset/component.d.ts +46 -0
  32. package/lib/directives/subnet-validator.directive.d.ts +34 -0
  33. package/lib/services/alb-api.service.d.ts +16 -0
  34. package/lib/services/certificate-api.service.d.ts +38 -0
  35. package/lib/services/network-util.service.d.ts +21 -0
  36. package/lib/types/alb-exports.d.ts +29 -0
  37. package/lib/types/k8s-exports.d.ts +130 -0
  38. package/lib/types/resource-definition.d.ts +25 -0
  39. package/lib/utils/alb-exports.d.ts +16 -0
  40. package/lib/utils/alb-internals.d.ts +10 -0
  41. package/lib/utils/cidr-exports.d.ts +85 -0
  42. package/lib/utils/cluster-exports.d.ts +14 -0
  43. package/lib/utils/service-exports.d.ts +18 -0
  44. package/lib/utils/service-internals.d.ts +2 -0
  45. package/lib/utils/subnet-exports.d.ts +20 -0
  46. package/package.json +31 -0
@@ -0,0 +1,503 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ /* eslint-disable sonarjs/cognitive-complexity */
3
+ import { AutocompleteModule, CommonFormControl, FormItemWidth, FormModule, IconModule, InputModule, TagsInputComponent, TooltipModule, } from '@alauda/ui';
4
+ import { K8sApiService, K8sUtilService, ObservableInput, publishRef, skipError, matchExpressionsToString, bind, TranslateModule, ErrorsMapperModule, RESOURCE_TYPES, E2eAttributeBindingDirective, TranslateService, } from '@alauda-fe/common';
5
+ import { AsyncPipe, NgFor, NgIf } from '@angular/common';
6
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, ViewChild, forwardRef, } from '@angular/core';
7
+ import { toSignal } from '@angular/core/rxjs-interop';
8
+ import { AbstractControl, FormsModule, NG_ASYNC_VALIDATORS, NG_VALUE_ACCESSOR, NgModel, } from '@angular/forms';
9
+ import { uniq, values } from 'lodash-es';
10
+ import { Observable, combineLatest, filter, first, fromEvent, map, merge, of, switchMap, forkJoin, startWith, tap, } from 'rxjs';
11
+ import { NetworkUtilService } from '../../services/network-util.service';
12
+ import { NETWORK_RESOURCE_TYPES } from '../../types/resource-definition';
13
+ import { IPMode, NetworkMode, adaptIpMode, adaptSubnetCidrs, getIpAddressSuggestionsByCidrs, ipAddressEqual, isBelongCidr, isBroadcastAddr, isIpAddressValid, isNetworkAddr, } from '../../utils/cidr-exports';
14
+ import { ClusterNetworkType, KUBE_OVN_ANNOTATION_PREFIX, } from '../../utils/subnet-exports';
15
+ import * as i0 from "@angular/core";
16
+ import * as i1 from "@alauda-fe/common";
17
+ import * as i2 from "../../services/network-util.service";
18
+ import * as i3 from "@alauda/ui";
19
+ import * as i4 from "@angular/forms";
20
+ const _c0 = ["ipAddress"];
21
+ const _c1 = ["tagsInput"];
22
+ function FixedIpInputComponent_input_4_Template(rf, ctx) { if (rf & 1) {
23
+ const _r8 = i0.ɵɵgetCurrentView();
24
+ i0.ɵɵelementStart(0, "input", 9, 10);
25
+ i0.ɵɵlistener("ngModelChange", function FixedIpInputComponent_input_4_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r7 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r7.emitValue($event)); });
26
+ i0.ɵɵpipe(2, "translate");
27
+ i0.ɵɵelementEnd();
28
+ } if (rf & 2) {
29
+ const ctx_r0 = i0.ɵɵnextContext();
30
+ const _r2 = i0.ɵɵreference(7);
31
+ i0.ɵɵproperty("ngModel", ctx_r0.model)("placeholder", ctx_r0.placeholder || i0.ɵɵpipeBind1(2, 3, "dhcp_placeholder"))("auiAutocomplete", _r2);
32
+ } }
33
+ function FixedIpInputComponent_aui_tags_input_5_Template(rf, ctx) { if (rf & 1) {
34
+ const _r12 = i0.ɵɵgetCurrentView();
35
+ i0.ɵɵelementStart(0, "aui-tags-input", 11, 12);
36
+ i0.ɵɵlistener("ngModelChange", function FixedIpInputComponent_aui_tags_input_5_Template_aui_tags_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r11 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r11.emitValue(ctx_r11.uniq($event))); });
37
+ i0.ɵɵpipe(3, "translate");
38
+ i0.ɵɵelementEnd();
39
+ } if (rf & 2) {
40
+ const ctx_r1 = i0.ɵɵnextContext();
41
+ const _r2 = i0.ɵɵreference(7);
42
+ i0.ɵɵproperty("ngModel", ctx_r1.model)("placeholder", ctx_r1.placeholder || i0.ɵɵpipeBind1(3, 4, "dhcp_placeholder"))("auiAutocomplete", _r2)("inputAsyncValidator", ctx_r1.validate);
43
+ } }
44
+ function FixedIpInputComponent_aui_suggestion_8_Template(rf, ctx) { if (rf & 1) {
45
+ i0.ɵɵelementStart(0, "aui-suggestion", 13);
46
+ i0.ɵɵtext(1);
47
+ i0.ɵɵelementEnd();
48
+ } if (rf & 2) {
49
+ const ipAddressSuggestion_r13 = ctx.$implicit;
50
+ i0.ɵɵproperty("value", ipAddressSuggestion_r13);
51
+ i0.ɵɵadvance(1);
52
+ i0.ɵɵtextInterpolate1(" ", ipAddressSuggestion_r13, " ");
53
+ } }
54
+ function FixedIpInputComponent_ng_container_14_aui_icon_1_Template(rf, ctx) { if (rf & 1) {
55
+ i0.ɵɵelement(0, "aui-icon", 16);
56
+ } if (rf & 2) {
57
+ const ctx_r14 = i0.ɵɵnextContext(2);
58
+ i0.ɵɵproperty("auiTooltip", ctx_r14.addonTip);
59
+ } }
60
+ function FixedIpInputComponent_ng_container_14_Template(rf, ctx) { if (rf & 1) {
61
+ i0.ɵɵelementContainerStart(0, 14);
62
+ i0.ɵɵtemplate(1, FixedIpInputComponent_ng_container_14_aui_icon_1_Template, 1, 1, "aui-icon", 15);
63
+ i0.ɵɵelementContainerEnd();
64
+ } if (rf & 2) {
65
+ const ctx_r4 = i0.ɵɵnextContext();
66
+ i0.ɵɵadvance(1);
67
+ i0.ɵɵproperty("ngIf", ctx_r4.addonTip);
68
+ } }
69
+ const _c2 = function (a0) { return { cidr: a0 }; };
70
+ function FixedIpInputComponent_div_18_Template(rf, ctx) { if (rf & 1) {
71
+ i0.ɵɵelementStart(0, "div", 17);
72
+ i0.ɵɵtext(1);
73
+ i0.ɵɵpipe(2, "translate");
74
+ i0.ɵɵpipe(3, "async");
75
+ i0.ɵɵelementEnd();
76
+ } if (rf & 2) {
77
+ const ctx_r5 = i0.ɵɵnextContext();
78
+ i0.ɵɵadvance(1);
79
+ i0.ɵɵtextInterpolate1(" ", ctx_r5.hint || i0.ɵɵpipeBind2(2, 1, "fix_ip_should_belong_tip", i0.ɵɵpureFunction1(6, _c2, i0.ɵɵpipeBind1(3, 4, ctx_r5.cidr$))), " ");
80
+ } }
81
+ export class FixedIpInputComponent extends CommonFormControl {
82
+ get isCalico() {
83
+ return this.networkType === ClusterNetworkType.CALICO;
84
+ }
85
+ constructor(cdr, k8sUtil, k8sApi, networkUtilService, translate) {
86
+ super(cdr);
87
+ this.cdr = cdr;
88
+ this.k8sUtil = k8sUtil;
89
+ this.k8sApi = k8sApi;
90
+ this.networkUtilService = networkUtilService;
91
+ this.translate = translate;
92
+ this.formItemWidth = FormItemWidth.Medium;
93
+ // 虚拟机更新时排除掉自身
94
+ this.skipOccupied = false;
95
+ // 目前双栈固定 IP 只支持 IPv4
96
+ this.enableFixIpV6ForDual = false;
97
+ this.uniq = uniq;
98
+ this.namespaceResource$ = combineLatest([
99
+ this.cluster$,
100
+ this.namespace$,
101
+ ]).pipe(filter(([cluster, namespace]) => !!cluster && !!namespace), switchMap(([cluster, namespace]) => this.k8sApi.getResource({
102
+ type: RESOURCE_TYPES.NAMESPACE,
103
+ cluster,
104
+ name: namespace,
105
+ })), publishRef());
106
+ this.networkMode$ = this.cluster$.pipe(switchMap(cluster => this.networkUtilService.getNetworkMode$(cluster)), publishRef());
107
+ this.$networkMode = toSignal(this.networkMode$);
108
+ this.subnetDetails$ = combineLatest([
109
+ this.cluster$,
110
+ this.networkType$,
111
+ this.subnet$,
112
+ ]).pipe(filter(([cluster, networkType]) => !!cluster && !!networkType), switchMap(([cluster, _networkType, subnet]) => subnet
113
+ ? of({
114
+ cluster,
115
+ subnets: [subnet],
116
+ subnet,
117
+ gateway: subnet.spec?.gateway,
118
+ })
119
+ : this.isCalico
120
+ ? this.k8sApi
121
+ .getResourceList({
122
+ type: NETWORK_RESOURCE_TYPES.SUBNET_KUBE_OVN,
123
+ cluster,
124
+ })
125
+ .pipe(map(res => res.items), skipError([]), map(subnets => ({
126
+ cluster,
127
+ subnets,
128
+ subnet: null,
129
+ gateway: '',
130
+ })))
131
+ : of({
132
+ cluster,
133
+ subnets: [],
134
+ subnet: null,
135
+ gateway: '',
136
+ })));
137
+ this.subnetInfo$ = combineLatest([
138
+ this.networkMode$,
139
+ this.namespaceResource$.pipe(filter(Boolean)),
140
+ this.subnetDetails$,
141
+ ]).pipe(map(([networkMode, namespace, { cluster, subnets, subnet, gateway }]) => {
142
+ return {
143
+ cluster,
144
+ subnetCidrs: this.isCalico
145
+ ? this.networkUtilService.getCalicoCidrs(namespace, subnets, networkMode, this.enableFixIpV6ForDual)
146
+ : adaptSubnetCidrs(subnet == null
147
+ ? this.k8sUtil.getAnnotation(namespace, {
148
+ type: 'cidr',
149
+ baseDomain: KUBE_OVN_ANNOTATION_PREFIX,
150
+ })
151
+ : subnet.spec?.cidrBlock ?? '', this.$networkMode(), this.enableFixIpV6ForDual),
152
+ subnetName: subnet == null
153
+ ? this.k8sUtil.getAnnotation(namespace, {
154
+ type: 'logical_switch',
155
+ baseDomain: KUBE_OVN_ANNOTATION_PREFIX,
156
+ })
157
+ : this.k8sUtil.getName(subnet),
158
+ gateway,
159
+ };
160
+ }), switchMap(subnetInfo => {
161
+ if (this.networkType === ClusterNetworkType.KUBE_OVN &&
162
+ !subnetInfo.gateway) {
163
+ return forkJoin(subnetInfo.subnetName.split(',').map(subnetName => this.k8sApi
164
+ .getResource({
165
+ type: NETWORK_RESOURCE_TYPES.SUBNET_KUBE_OVN,
166
+ cluster: subnetInfo.cluster,
167
+ name: subnetName,
168
+ })
169
+ .pipe(skipError(null)))).pipe(map(list => list.filter(Boolean)), map(subnetList => subnetList.length
170
+ ? {
171
+ ...subnetInfo,
172
+ gateway: subnetList
173
+ .map(item => item.spec?.gateway)
174
+ .filter(Boolean)
175
+ .join(','),
176
+ }
177
+ : subnetInfo));
178
+ }
179
+ return of(subnetInfo);
180
+ }), switchMap(subnetInfo => {
181
+ if (subnetInfo.subnetCidrs.length) {
182
+ return of(subnetInfo);
183
+ }
184
+ // fallback to default subnet
185
+ return this.k8sApi
186
+ .getResource({
187
+ type: NETWORK_RESOURCE_TYPES.SUBNET_KUBE_OVN,
188
+ cluster: subnetInfo.cluster,
189
+ name: this.isCalico
190
+ ? `default-ip${this.$networkMode() === 'dual' ? 'v4' : this.$networkMode()}-ippool`
191
+ : 'ovn-default',
192
+ })
193
+ .pipe(map(subnet => ({
194
+ ...subnetInfo,
195
+ subnetCidrs: adaptSubnetCidrs(subnet.spec.cidrBlock, this.$networkMode(), this.enableFixIpV6ForDual),
196
+ subnetName: this.k8sUtil.getName(subnet),
197
+ gateway: subnet.spec.gateway,
198
+ })));
199
+ }), publishRef());
200
+ this.$subnetInfo = toSignal(this.subnetInfo$);
201
+ this.cidr$ = this.subnetInfo$.pipe(map(subnetInfo => subnetInfo?.subnetCidrs.join('、')));
202
+ this.innerErrorsMapper$ = combineLatest([
203
+ this.cidr$,
204
+ this.translate.locale$,
205
+ ]).pipe(map(([cidr]) => ({
206
+ pattern: this.translate.get('fixed_ip_pattern_tips', {
207
+ ipMode: ['dual', 'v4'].includes(this.$networkMode()) ? 'IPv4' : 'IPv6',
208
+ }),
209
+ occupied: this.translate.get('fixed_ip_occupied_tips', {
210
+ cidr,
211
+ }),
212
+ out_of_range: this.translate.get('fixed_ip_out_of_range_tips', {
213
+ cidr,
214
+ }),
215
+ })));
216
+ this.combinedErrorsMapper$ = combineLatest([
217
+ this.innerErrorsMapper$,
218
+ this.errorsMapper$,
219
+ ]).pipe(map(([innerErrorsMapper, errorsMapper]) => ({
220
+ ...innerErrorsMapper,
221
+ ...errorsMapper,
222
+ })));
223
+ this.inputErrors$ = this.errors$.pipe(tap(errors => {
224
+ this.setErrors(errors);
225
+ this.ipAddress?.control.markAsDirty();
226
+ this.onValidatorChange?.();
227
+ }));
228
+ this.usedIps$ = combineLatest([
229
+ this.cluster$,
230
+ this.subnetInfo$,
231
+ this.model$.pipe(first()),
232
+ ]).pipe(switchMap(([cluster, { subnetName, gateway }, ip]) => this.isCalico
233
+ ? of([])
234
+ : this.k8sApi
235
+ .getResourceList({
236
+ type: NETWORK_RESOURCE_TYPES.SUBNET_KUBE_OVN_IP,
237
+ cluster,
238
+ queryParams: {
239
+ labelSelector: matchExpressionsToString([
240
+ {
241
+ key: `${KUBE_OVN_ANNOTATION_PREFIX}/subnet`,
242
+ operator: 'in',
243
+ values: subnetName.split(','),
244
+ },
245
+ ]),
246
+ },
247
+ })
248
+ .pipe(map(res => res.items), skipError([]), map(subnetIps => subnetIps.reduce((usedIps, { spec: { ipAddress } }) => {
249
+ ipAddress.split(',').forEach(item => {
250
+ if (ip !== item) {
251
+ usedIps.push(item);
252
+ }
253
+ });
254
+ return usedIps;
255
+ }, gateway.split(','))))), publishRef());
256
+ this.$usedIps = toSignal(this.usedIps$);
257
+ this.ipAddressSuggestions$ = combineLatest([
258
+ this.subnetInfo$,
259
+ this.usedIps$,
260
+ this.networkMode$,
261
+ this.model$,
262
+ this.tagsInput$.pipe(switchMap(tagsInput => tagsInput
263
+ ? merge(fromEvent(tagsInput.inputRef.nativeElement, 'input').pipe(map(ev => ev.target.value)), tagsInput.inputControl.valueChanges)
264
+ : this.model$)),
265
+ ]).pipe(map(([{ subnetCidrs }, usedIps, networkMode, addedIps, inputValue]) => getIpAddressSuggestionsByCidrs(subnetCidrs, networkMode, [
266
+ ...usedIps,
267
+ ...(Array.isArray(addedIps) ? addedIps : [addedIps].filter(Boolean)),
268
+ ], inputValue, this.isCalico)), startWith([]), skipError([]), publishRef());
269
+ }
270
+ registerOnValidatorChange(fn) {
271
+ this.onValidatorChange = fn;
272
+ }
273
+ validate(ctrl) {
274
+ const ipAddress = ctrl.value;
275
+ return ipAddress && !Array.isArray(ipAddress)
276
+ ? this.usedIps$.pipe(first(), map(() => this.setErrors(this.validateFixedIp(ipAddress))))
277
+ : of(this.setErrors(null));
278
+ }
279
+ setErrors(errors) {
280
+ const combinedErrors = this.multiple
281
+ ? { ...this.ipAddress?.control.errors, ...errors } // 可能存在传入的 errors
282
+ : errors;
283
+ const validationErrors = values(combinedErrors).length
284
+ ? combinedErrors
285
+ : null;
286
+ this.ipAddress?.control.setErrors(validationErrors);
287
+ return validationErrors;
288
+ }
289
+ validateFixedIp(ipAddress) {
290
+ const { subnetCidrs, gateway } = this.$subnetInfo();
291
+ const ipMode = this.adaptIpMode(ipAddress);
292
+ const isIpV4 = ipMode === IPMode.IPV4;
293
+ const judgeCidrs = subnetCidrs.filter(cidr => {
294
+ const isIpV6 = cidr.includes(':');
295
+ return isIpV4 ? !isIpV6 : isIpV6;
296
+ });
297
+ if (subnetCidrs.length && !judgeCidrs.length) {
298
+ return {
299
+ pattern: true,
300
+ };
301
+ }
302
+ // invalid ip pattern, not broadcast ip, not network ip
303
+ if (!isIpAddressValid(ipAddress, ipMode) ||
304
+ judgeCidrs.some(calicoCidr => isBroadcastAddr(ipAddress, calicoCidr, ipMode) ||
305
+ isNetworkAddr(ipAddress, calicoCidr, ipMode))) {
306
+ return {
307
+ pattern: true,
308
+ };
309
+ }
310
+ let v4Gateway;
311
+ let v6Gateway;
312
+ if (gateway) {
313
+ const gatewayParts = gateway.split(',');
314
+ v4Gateway = gatewayParts[0];
315
+ v6Gateway = gatewayParts[1];
316
+ }
317
+ const ipGateway = isIpV4 ? v4Gateway : v6Gateway;
318
+ if (
319
+ // https://jira.alauda.cn/browse/ACP-12136?focusedCommentId=215460&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-215460
320
+ (ipGateway && ipAddressEqual(ipGateway, ipAddress, ipMode)) ||
321
+ (!this.skipOccupied &&
322
+ this.$usedIps().some(usedIp => ipAddressEqual(usedIp, ipAddress, ipMode)))) {
323
+ return {
324
+ occupied: true,
325
+ };
326
+ }
327
+ if (judgeCidrs.length &&
328
+ !judgeCidrs.some(cidr => cidr && isBelongCidr(cidr, ipAddress, ipMode))) {
329
+ return {
330
+ out_of_range: true,
331
+ };
332
+ }
333
+ }
334
+ adaptIpMode(ipAddress) {
335
+ return adaptIpMode(ipAddress, !this.enableFixIpV6ForDual && this.$networkMode() === NetworkMode.DUAL
336
+ ? NetworkMode.IPV4
337
+ : this.$networkMode());
338
+ }
339
+ static { this.ɵfac = function FixedIpInputComponent_Factory(t) { return new (t || FixedIpInputComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.K8sUtilService), i0.ɵɵdirectiveInject(i1.K8sApiService), i0.ɵɵdirectiveInject(i2.NetworkUtilService), i0.ɵɵdirectiveInject(i1.TranslateService)); }; }
340
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FixedIpInputComponent, selectors: [["acl-fixed-ip-input"]], viewQuery: function FixedIpInputComponent_Query(rf, ctx) { if (rf & 1) {
341
+ i0.ɵɵviewQuery(_c0, 5);
342
+ i0.ɵɵviewQuery(_c1, 5);
343
+ } if (rf & 2) {
344
+ let _t;
345
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.ipAddress = _t.first);
346
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.tagsInput = _t.first);
347
+ } }, inputs: { cluster: "cluster", namespace: "namespace", networkType: "networkType", subnet: "subnet", label: "label", placeholder: "placeholder", hint: "hint", addonTip: "addonTip", multiple: "multiple", formItemWidth: "formItemWidth", skipOccupied: "skipOccupied", enableFixIpV6ForDual: "enableFixIpV6ForDual", errors: "errors", errorsMapper: "errorsMapper" }, standalone: true, features: [i0.ɵɵProvidersFeature([
348
+ {
349
+ provide: NG_VALUE_ACCESSOR,
350
+ useExisting: forwardRef(() => FixedIpInputComponent),
351
+ multi: true,
352
+ },
353
+ {
354
+ provide: NG_ASYNC_VALIDATORS,
355
+ useExisting: forwardRef(() => FixedIpInputComponent),
356
+ multi: true,
357
+ },
358
+ ]), i0.ɵɵInheritDefinitionFeature, i0.ɵɵStandaloneFeature], decls: 20, vars: 24, consts: [[3, "width"], ["auiFormItemLabel", ""], ["aui-input", "", "auiFormItemControl", "", 3, "ngModel", "placeholder", "auiAutocomplete", "ngModelChange", 4, "ngIf"], ["class", "flex-1", "auiFormItemControl", "", 3, "ngModel", "placeholder", "auiAutocomplete", "inputAsyncValidator", "ngModelChange", 4, "ngIf"], ["suggestions", ""], [3, "value", 4, "ngFor", "ngForOf"], ["auiFormItemAddon", "", 4, "ngIf"], ["auiFormItemError", "", 3, "errors", "errorsMapper"], ["auiFormItemHint", "", 4, "ngIf"], ["aui-input", "", "auiFormItemControl", "", 3, "ngModel", "placeholder", "auiAutocomplete", "ngModelChange"], ["ipAddress", "ngModel"], ["auiFormItemControl", "", 1, "flex-1", 3, "ngModel", "placeholder", "auiAutocomplete", "inputAsyncValidator", "ngModelChange"], ["tagsInput", "", "ipAddress", "ngModel"], [3, "value"], ["auiFormItemAddon", ""], ["icon", "question_circle", "class", "icon--help", "auiTooltipPosition", "end", 3, "auiTooltip", 4, "ngIf"], ["icon", "question_circle", "auiTooltipPosition", "end", 1, "icon--help", 3, "auiTooltip"], ["auiFormItemHint", ""]], template: function FixedIpInputComponent_Template(rf, ctx) { if (rf & 1) {
359
+ i0.ɵɵelementStart(0, "aui-form-item", 0)(1, "label", 1);
360
+ i0.ɵɵtext(2);
361
+ i0.ɵɵpipe(3, "translate");
362
+ i0.ɵɵelementEnd();
363
+ i0.ɵɵtemplate(4, FixedIpInputComponent_input_4_Template, 3, 5, "input", 2);
364
+ i0.ɵɵtemplate(5, FixedIpInputComponent_aui_tags_input_5_Template, 4, 6, "aui-tags-input", 3);
365
+ i0.ɵɵelementStart(6, "aui-autocomplete", null, 4);
366
+ i0.ɵɵtemplate(8, FixedIpInputComponent_aui_suggestion_8_Template, 2, 2, "aui-suggestion", 5);
367
+ i0.ɵɵpipe(9, "async");
368
+ i0.ɵɵelementStart(10, "aui-autocomplete-placeholder");
369
+ i0.ɵɵtext(11);
370
+ i0.ɵɵpipe(12, "translate");
371
+ i0.ɵɵpipe(13, "async");
372
+ i0.ɵɵelementEnd()();
373
+ i0.ɵɵtemplate(14, FixedIpInputComponent_ng_container_14_Template, 2, 1, "ng-container", 6);
374
+ i0.ɵɵelement(15, "acl-errors-mapper", 7);
375
+ i0.ɵɵpipe(16, "async");
376
+ i0.ɵɵpipe(17, "async");
377
+ i0.ɵɵtemplate(18, FixedIpInputComponent_div_18_Template, 4, 8, "div", 8);
378
+ i0.ɵɵpipe(19, "async");
379
+ i0.ɵɵelementEnd();
380
+ } if (rf & 2) {
381
+ i0.ɵɵproperty("width", ctx.formItemWidth);
382
+ i0.ɵɵadvance(2);
383
+ i0.ɵɵtextInterpolate(ctx.label || i0.ɵɵpipeBind1(3, 10, "ip_address"));
384
+ i0.ɵɵadvance(2);
385
+ i0.ɵɵproperty("ngIf", !ctx.multiple);
386
+ i0.ɵɵadvance(1);
387
+ i0.ɵɵproperty("ngIf", ctx.multiple);
388
+ i0.ɵɵadvance(3);
389
+ i0.ɵɵproperty("ngForOf", i0.ɵɵpipeBind1(9, 12, ctx.ipAddressSuggestions$));
390
+ i0.ɵɵadvance(3);
391
+ i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(12, 14, i0.ɵɵpipeBind1(13, 16, ctx.ipAddressSuggestions$) ? "no_available_suggestion" : "loading"), " ");
392
+ i0.ɵɵadvance(3);
393
+ i0.ɵɵproperty("ngIf", ctx.addonTip != null);
394
+ i0.ɵɵadvance(1);
395
+ i0.ɵɵproperty("errors", (ctx.ipAddress == null ? null : ctx.ipAddress.errors == null ? null : ctx.ipAddress.errors.input_data_error) || (ctx.ipAddress == null ? null : ctx.ipAddress.errors) || i0.ɵɵpipeBind1(16, 18, ctx.inputErrors$))("errorsMapper", i0.ɵɵpipeBind1(17, 20, ctx.combinedErrorsMapper$));
396
+ i0.ɵɵadvance(3);
397
+ i0.ɵɵproperty("ngIf", ctx.hint !== null && (ctx.hint || i0.ɵɵpipeBind1(19, 22, ctx.cidr$)));
398
+ } }, dependencies: [AutocompleteModule, i3.AutoCompleteDirective, i3.CustomAutoCompleteDirective, i3.AutocompleteComponent, i3.SuggestionComponent, i3.AutocompletePlaceholderComponent, AsyncPipe,
399
+ E2eAttributeBindingDirective,
400
+ ErrorsMapperModule, i1.ErrorsMapperComponent, FormModule, i3.FormItemComponent, i3.FormItemAddonDirective, i3.FormItemErrorDirective, i3.FormItemHintDirective, i3.FormItemLabelDirective, i3.FormItemControlDirective, NgIf,
401
+ NgFor,
402
+ InputModule, i3.InputComponent, i3.TagsInputComponent, IconModule, i3.IconComponent, TooltipModule, i3.TooltipDirective, FormsModule, i4.DefaultValueAccessor, i4.NgControlStatus, i4.NgModel, TranslateModule, i1.TranslatePipe], styles: ["[_nghost-%COMP%]:not(:last-child) aui-form-item[_ngcontent-%COMP%] .aui-form-item{margin-bottom:16px}"], changeDetection: 0 }); }
403
+ }
404
+ __decorate([
405
+ ObservableInput(),
406
+ __metadata("design:type", Observable)
407
+ ], FixedIpInputComponent.prototype, "cluster$", void 0);
408
+ __decorate([
409
+ ObservableInput(),
410
+ __metadata("design:type", Observable)
411
+ ], FixedIpInputComponent.prototype, "namespace$", void 0);
412
+ __decorate([
413
+ ObservableInput(),
414
+ __metadata("design:type", Observable)
415
+ ], FixedIpInputComponent.prototype, "networkType$", void 0);
416
+ __decorate([
417
+ ObservableInput(),
418
+ __metadata("design:type", Observable)
419
+ ], FixedIpInputComponent.prototype, "subnet$", void 0);
420
+ __decorate([
421
+ ObservableInput(),
422
+ __metadata("design:type", Observable)
423
+ ], FixedIpInputComponent.prototype, "tagsInput$", void 0);
424
+ __decorate([
425
+ ObservableInput(),
426
+ __metadata("design:type", Observable)
427
+ ], FixedIpInputComponent.prototype, "errors$", void 0);
428
+ __decorate([
429
+ ObservableInput(),
430
+ __metadata("design:type", Observable)
431
+ ], FixedIpInputComponent.prototype, "errorsMapper$", void 0);
432
+ __decorate([
433
+ bind,
434
+ __metadata("design:type", Function),
435
+ __metadata("design:paramtypes", [AbstractControl]),
436
+ __metadata("design:returntype", void 0)
437
+ ], FixedIpInputComponent.prototype, "validate", null);
438
+ (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FixedIpInputComponent, [{
439
+ type: Component,
440
+ args: [{ standalone: true, selector: 'acl-fixed-ip-input', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
441
+ {
442
+ provide: NG_VALUE_ACCESSOR,
443
+ useExisting: forwardRef(() => FixedIpInputComponent),
444
+ multi: true,
445
+ },
446
+ {
447
+ provide: NG_ASYNC_VALIDATORS,
448
+ useExisting: forwardRef(() => FixedIpInputComponent),
449
+ multi: true,
450
+ },
451
+ ], imports: [
452
+ AutocompleteModule,
453
+ AsyncPipe,
454
+ E2eAttributeBindingDirective,
455
+ ErrorsMapperModule,
456
+ FormModule,
457
+ NgIf,
458
+ NgFor,
459
+ InputModule,
460
+ IconModule,
461
+ TooltipModule,
462
+ FormsModule,
463
+ TranslateModule,
464
+ ], template: "<aui-form-item [width]=\"formItemWidth\">\n <label auiFormItemLabel>{{ label || ('ip_address' | translate) }}</label>\n <input\n *ngIf=\"!multiple\"\n aui-input\n auiFormItemControl\n [ngModel]=\"model\"\n (ngModelChange)=\"emitValue($event)\"\n #ipAddress=\"ngModel\"\n [placeholder]=\"placeholder || ('dhcp_placeholder' | translate)\"\n [auiAutocomplete]=\"suggestions\"\n />\n <aui-tags-input\n *ngIf=\"multiple\"\n class=\"flex-1\"\n auiFormItemControl\n #tagsInput\n [ngModel]=\"model\"\n (ngModelChange)=\"emitValue(uniq($event))\"\n #ipAddress=\"ngModel\"\n [placeholder]=\"placeholder || ('dhcp_placeholder' | translate)\"\n [auiAutocomplete]=\"suggestions\"\n [inputAsyncValidator]=\"validate\"\n ></aui-tags-input>\n <aui-autocomplete #suggestions>\n <aui-suggestion\n *ngFor=\"let ipAddressSuggestion of ipAddressSuggestions$ | async\"\n [value]=\"ipAddressSuggestion\"\n >\n {{ ipAddressSuggestion }}\n </aui-suggestion>\n <aui-autocomplete-placeholder>\n {{\n ((ipAddressSuggestions$ | async)\n ? 'no_available_suggestion'\n : 'loading'\n ) | translate\n }}\n </aui-autocomplete-placeholder>\n </aui-autocomplete>\n <ng-container\n *ngIf=\"addonTip != null\"\n auiFormItemAddon\n >\n <aui-icon\n *ngIf=\"addonTip\"\n icon=\"question_circle\"\n class=\"icon--help\"\n [auiTooltip]=\"addonTip\"\n auiTooltipPosition=\"end\"\n ></aui-icon>\n </ng-container>\n <acl-errors-mapper\n auiFormItemError\n [errors]=\"\n ipAddress?.errors?.input_data_error ||\n ipAddress?.errors ||\n (inputErrors$ | async)\n \"\n [errorsMapper]=\"combinedErrorsMapper$ | async\"\n ></acl-errors-mapper>\n <div\n auiFormItemHint\n *ngIf=\"hint !== null && (hint || (cidr$ | async))\"\n >\n {{\n hint ||\n ('fix_ip_should_belong_tip' | translate: { cidr: (cidr$ | async) })\n }}\n </div>\n</aui-form-item>\n", styles: [":host:not(:last-child) aui-form-item ::ng-deep .aui-form-item{margin-bottom:16px}\n"] }]
465
+ }], function () { return [{ type: i0.ChangeDetectorRef }, { type: i1.K8sUtilService }, { type: i1.K8sApiService }, { type: i2.NetworkUtilService }, { type: i1.TranslateService }]; }, { cluster: [{
466
+ type: Input,
467
+ args: [{ required: true }]
468
+ }], cluster$: [], namespace: [{
469
+ type: Input,
470
+ args: [{ required: true }]
471
+ }], namespace$: [], networkType: [{
472
+ type: Input,
473
+ args: [{ required: true }]
474
+ }], networkType$: [], subnet: [{
475
+ type: Input
476
+ }], subnet$: [], label: [{
477
+ type: Input
478
+ }], placeholder: [{
479
+ type: Input
480
+ }], hint: [{
481
+ type: Input
482
+ }], addonTip: [{
483
+ type: Input
484
+ }], multiple: [{
485
+ type: Input
486
+ }], ipAddress: [{
487
+ type: ViewChild,
488
+ args: ['ipAddress', { static: false }]
489
+ }], tagsInput: [{
490
+ type: ViewChild,
491
+ args: ['tagsInput', { static: false }]
492
+ }], formItemWidth: [{
493
+ type: Input
494
+ }], tagsInput$: [], skipOccupied: [{
495
+ type: Input
496
+ }], enableFixIpV6ForDual: [{
497
+ type: Input
498
+ }], errors: [{
499
+ type: Input
500
+ }], errors$: [], errorsMapper: [{
501
+ type: Input
502
+ }], errorsMapper$: [], validate: [] }); })();
503
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbW9kdWxlcy9uZXR3b3JrL3NyYy9saWIvY29tcG9uZW50cy9maXhlZC1pcC9jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9tb2R1bGVzL25ldHdvcmsvc3JjL2xpYi9jb21wb25lbnRzL2ZpeGVkLWlwL3RlbXBsYXRlLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLGlEQUFpRDtBQUNqRCxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLGlCQUFpQixFQUNqQixhQUFhLEVBQ2IsVUFBVSxFQUNWLFVBQVUsRUFDVixXQUFXLEVBQ1gsa0JBQWtCLEVBQ2xCLGFBQWEsR0FDZCxNQUFNLFlBQVksQ0FBQztBQUNwQixPQUFPLEVBQ0wsYUFBYSxFQUNiLGNBQWMsRUFDZCxlQUFlLEVBQ2YsVUFBVSxFQUNWLFNBQVMsRUFDVCx3QkFBd0IsRUFFeEIsSUFBSSxFQUNKLGVBQWUsRUFDZixrQkFBa0IsRUFDbEIsY0FBYyxFQUNkLDRCQUE0QixFQUM1QixnQkFBZ0IsR0FFakIsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsS0FBSyxFQUNMLFNBQVMsRUFDVCxVQUFVLEdBQ1gsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3RELE9BQU8sRUFDTCxlQUFlLEVBRWYsV0FBVyxFQUNYLG1CQUFtQixFQUNuQixpQkFBaUIsRUFDakIsT0FBTyxHQUVSLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDekMsT0FBTyxF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RSxRQUFRLEVBQUUsSUFBSSxFQUFFO1lBSXpCLFlBQVksTUFHWixNQUFNO2tCQURMLEtBQUs7WUFJTixPQUFPLE1BR1AsS0FBSztrQkFESixLQUFLO1lBSU4sV0FBVztrQkFEVixLQUFLO1lBSU4sSUFBSTtrQkFESCxLQUFLO1lBSU4sUUFBUTtrQkFEUCxLQUFLO1lBSU4sUUFBUTtrQkFEUCxLQUFLO1lBSU4sU0FBUztrQkFEUixTQUFTO21CQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7WUFJekMsU0FBUztrQkFEUixTQUFTO21CQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7WUFJekMsYUFBYTtrQkFEWixLQUFLO1lBSU4sVUFBVSxNQUlWLFlBQVk7a0JBRFgsS0FBSztZQUtOLG9CQUFvQjtrQkFEbkIsS0FBSztZQUdHLE1BQU07a0JBQWQsS0FBSztZQUVOLE9BQU8sTUFFRSxZQUFZO2tCQUFwQixLQUFLO1lBRU4sYUFBYSxNQWlUYixRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgc29uYXJqcy9jb2duaXRpdmUtY29tcGxleGl0eSAqL1xuaW1wb3J0IHtcbiAgQXV0b2NvbXBsZXRlTW9kdWxlLFxuICBDb21tb25Gb3JtQ29udHJvbCxcbiAgRm9ybUl0ZW1XaWR0aCxcbiAgRm9ybU1vZHVsZSxcbiAgSWNvbk1vZHVsZSxcbiAgSW5wdXRNb2R1bGUsXG4gIFRhZ3NJbnB1dENvbXBvbmVudCxcbiAgVG9vbHRpcE1vZHVsZSxcbn0gZnJvbSAnQGFsYXVkYS91aSc7XG5pbXBvcnQge1xuICBLOHNBcGlTZXJ2aWNlLFxuICBLOHNVdGlsU2VydmljZSxcbiAgT2JzZXJ2YWJsZUlucHV0LFxuICBwdWJsaXNoUmVmLFxuICBza2lwRXJyb3IsXG4gIG1hdGNoRXhwcmVzc2lvbnNUb1N0cmluZyxcbiAgTmFtZXNwYWNlLFxuICBiaW5kLFxuICBUcmFuc2xhdGVNb2R1bGUsXG4gIEVycm9yc01hcHBlck1vZHVsZSxcbiAgUkVTT1VSQ0VfVFlQRVMsXG4gIEUyZUF0dHJpYnV0ZUJpbmRpbmdEaXJlY3RpdmUsXG4gIFRyYW5zbGF0ZVNlcnZpY2UsXG4gIFN0cmluZ01hcCxcbn0gZnJvbSAnQGFsYXVkYS1mZS9jb21tb24nO1xuaW1wb3J0IHsgQXN5bmNQaXBlLCBOZ0ZvciwgTmdJZiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIFZpZXdDaGlsZCxcbiAgZm9yd2FyZFJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0b1NpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7XG4gIEFic3RyYWN0Q29udHJvbCxcbiAgQXN5bmNWYWxpZGF0b3IsXG4gIEZvcm1zTW9kdWxlLFxuICBOR19BU1lOQ19WQUxJREFUT1JTLFxuICBOR19WQUxVRV9BQ0NFU1NPUixcbiAgTmdNb2RlbCxcbiAgVmFsaWRhdGlvbkVycm9ycyxcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgdW5pcSwgdmFsdWVzIH0gZnJvbSAnbG9kYXNoLWVzJztcbmltcG9ydCB7XG4gIE9ic2VydmFibGUsXG4gIGNvbWJpbmVMYXRlc3QsXG4gIGZpbHRlcixcbiAgZmlyc3QsXG4gIGZyb21FdmVudCxcbiAgbWFwLFxuICBtZXJnZSxcbiAgb2YsXG4gIHN3aXRjaE1hcCxcbiAgZm9ya0pvaW4sXG4gIHN0YXJ0V2l0aCxcbiAgdGFwLFxufSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgTmV0d29ya1V0aWxTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbmV0d29yay11dGlsLnNlcnZpY2UnO1xuaW1wb3J0IHsgU3VibmV0LCBTdWJuZXRJcCB9IGZyb20gJy4uLy4uL3R5cGVzL2s4cy1leHBvcnRzJztcbmltcG9ydCB7IE5FVFdPUktfUkVTT1VSQ0VfVFlQRVMgfSBmcm9tICcuLi8uLi90eXBlcy9yZXNvdXJjZS1kZWZpbml0aW9uJztcbmltcG9ydCB7XG4gIElQTW9kZSxcbiAgTmV0d29ya01vZGUsXG4gIGFkYXB0SXBNb2RlLFxuICBhZGFwdFN1Ym5ldENpZHJzLFxuICBnZXRJcEFkZHJlc3NTdWdnZXN0aW9uc0J5Q2lkcnMsXG4gIGlwQWRkcmVzc0VxdWFsLFxuICBpc0JlbG9uZ0NpZHIsXG4gIGlzQnJvYWRjYXN0QWRkcixcbiAgaXNJcEFkZHJlc3NWYWxpZCxcbiAgaXNOZXR3b3JrQWRkcixcbn0gZnJvbSAnLi4vLi4vdXRpbHMvY2lkci1leHBvcnRzJztcbmltcG9ydCB7XG4gIENsdXN0ZXJOZXR3b3JrVHlwZSxcbiAgS1VCRV9PVk5fQU5OT1RBVElPTl9QUkVGSVgsXG59IGZyb20gJy4uLy4uL3V0aWxzL3N1Ym5ldC1leHBvcnRzJztcblxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHNlbGVjdG9yOiAnYWNsLWZpeGVkLWlwLWlucHV0JyxcbiAgdGVtcGxhdGVVcmw6ICd0ZW1wbGF0ZS5odG1sJyxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgOmhvc3Q6bm90KDpsYXN0LWNoaWxkKSBhdWktZm9ybS1pdGVtIDo6bmctZGVlcCAuYXVpLWZvcm0taXRlbSB7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDE2cHg7XG4gICAgICB9XG4gICAgYCxcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gRml4ZWRJcElucHV0Q29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgIH0sXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfQVNZTkNfVkFMSURBVE9SUyxcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IEZpeGVkSXBJbnB1dENvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZSxcbiAgICB9LFxuICBdLFxuICBpbXBvcnRzOiBbXG4gICAgQXV0b2NvbXBsZXRlTW9kdWxlLFxuICAgIEFzeW5jUGlwZSxcbiAgICBFMmVBdHRyaWJ1dGVCaW5kaW5nRGlyZWN0aXZlLFxuICAgIEVycm9yc01hcHBlck1vZHVsZSxcbiAgICBGb3JtTW9kdWxlLFxuICAgIE5nSWYsXG4gICAgTmdGb3IsXG4gICAgSW5wdXRNb2R1bGUsXG4gICAgSWNvbk1vZHVsZSxcbiAgICBUb29sdGlwTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIFRyYW5zbGF0ZU1vZHVsZSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgRml4ZWRJcElucHV0Q29tcG9uZW50XG4gIGV4dGVuZHMgQ29tbW9uRm9ybUNvbnRyb2w8c3RyaW5nIHwgc3RyaW5nW10+XG4gIGltcGxlbWVudHMgQXN5bmNWYWxpZGF0b3JcbntcbiAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSlcbiAgY2x1c3Rlcjogc3RyaW5nO1xuXG4gIEBPYnNlcnZhYmxlSW5wdXQoKVxuICBjbHVzdGVyJCE6IE9ic2VydmFibGU8c3RyaW5nPjtcblxuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KVxuICBuYW1lc3BhY2U6IHN0cmluZztcblxuICBAT2JzZXJ2YWJsZUlucHV0KClcbiAgbmFtZXNwYWNlJCE6IE9ic2VydmFibGU8c3RyaW5nPjtcblxuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KVxuICBuZXR3b3JrVHlwZTogQ2x1c3Rlck5ldHdvcmtUeXBlO1xuXG4gIEBPYnNlcnZhYmxlSW5wdXQoKVxuICBuZXR3b3JrVHlwZSQhOiBPYnNlcnZhYmxlPENsdXN0ZXJOZXR3b3JrVHlwZT47XG5cbiAgQElucHV0KClcbiAgc3VibmV0OiBTdWJuZXQ7XG5cbiAgQE9ic2VydmFibGVJbnB1dCgpXG4gIHN1Ym5ldCQhOiBPYnNlcnZhYmxlPFN1Ym5ldD47XG5cbiAgQElucHV0KClcbiAgbGFiZWw6IHN0cmluZztcblxuICBASW5wdXQoKVxuICBwbGFjZWhvbGRlcjogc3RyaW5nO1xuXG4gIEBJbnB1dCgpXG4gIGhpbnQ6IHN0cmluZztcblxuICBASW5wdXQoKVxuICBhZGRvblRpcDogc3RyaW5nO1xuXG4gIEBJbnB1dCgpXG4gIG11bHRpcGxlOiBib29sZWFuO1xuXG4gIEBWaWV3Q2hpbGQoJ2lwQWRkcmVzcycsIHsgc3RhdGljOiBmYWxzZSB9KVxuICBpcEFkZHJlc3M6IE5nTW9kZWw7XG5cbiAgQFZpZXdDaGlsZCgndGFnc0lucHV0JywgeyBzdGF0aWM6IGZhbHNlIH0pXG4gIHRhZ3NJbnB1dDogVGFnc0lucHV0Q29tcG9uZW50O1xuXG4gIEBJbnB1dCgpXG4gIGZvcm1JdGVtV2lkdGg6IEZvcm1JdGVtV2lkdGggPSBGb3JtSXRlbVdpZHRoLk1lZGl1bTtcblxuICBAT2JzZXJ2YWJsZUlucHV0KClcbiAgdGFnc0lucHV0JCE6IE9ic2VydmFibGU8VGFnc0lucHV0Q29tcG9uZW50PjtcblxuICAvLyDomZrmi5/mnLrmm7TmlrDml7bmjpLpmaTmjonoh6rouqtcbiAgQElucHV0KClcbiAgc2tpcE9jY3VwaWVkID0gZmFsc2U7XG5cbiAgLy8g55uu5YmN5Y+M5qCI5Zu65a6aIElQIOWPquaUr+aMgSBJUHY0XG4gIEBJbnB1dCgpXG4gIGVuYWJsZUZpeElwVjZGb3JEdWFsID0gZmFsc2U7XG5cbiAgQElucHV0KCkgZXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JzO1xuICBAT2JzZXJ2YWJsZUlucHV0KClcbiAgZXJyb3JzJCE6IE9ic2VydmFibGU8VmFsaWRhdGlvbkVycm9ycz47XG5cbiAgQElucHV0KCkgZXJyb3JzTWFwcGVyOiBTdHJpbmdNYXA7XG4gIEBPYnNlcnZhYmxlSW5wdXQoKVxuICBlcnJvcnNNYXBwZXIkITogT2JzZXJ2YWJsZTxTdHJpbmdNYXA+O1xuXG4gIHVuaXEgPSB1bmlxO1xuICBvblZhbGlkYXRvckNoYW5nZTogKCkgPT4gdm9pZDtcblxuICBnZXQgaXNDYWxpY28oKSB7XG4gICAgcmV0dXJuIHRoaXMubmV0d29ya1R5cGUgPT09IENsdXN0ZXJOZXR3b3JrVHlwZS5DQUxJQ087XG4gIH1cblxuICBwcml2YXRlIHJlYWRvbmx5IG5hbWVzcGFjZVJlc291cmNlJCA9IGNvbWJpbmVMYXRlc3QoW1xuICAgIHRoaXMuY2x1c3RlciQsXG4gICAgdGhpcy5uYW1lc3BhY2UkLFxuICBdKS5waXBlKFxuICAgIGZpbHRlcigoW2NsdXN0ZXIsIG5hbWVzcGFjZV0pID0+ICEhY2x1c3RlciAmJiAhIW5hbWVzcGFjZSksXG4gICAgc3dpdGNoTWFwKChbY2x1c3RlciwgbmFtZXNwYWNlXSkgPT5cbiAgICAgIHRoaXMuazhzQXBpLmdldFJlc291cmNlPE5hbWVzcGFjZT4oe1xuICAgICAgICB0eXBlOiBSRVNPVVJDRV9UWVBFUy5OQU1FU1BBQ0UsXG4gICAgICAgIGNsdXN0ZXIsXG4gICAgICAgIG5hbWU6IG5hbWVzcGFjZSxcbiAgICAgIH0pLFxuICAgICksXG4gICAgcHVibGlzaFJlZigpLFxuICApO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgbmV0d29ya01vZGUkID0gdGhpcy5jbHVzdGVyJC5waXBlKFxuICAgIHN3aXRjaE1hcChjbHVzdGVyID0+IHRoaXMubmV0d29ya1V0aWxTZXJ2aWNlLmdldE5ldHdvcmtNb2RlJChjbHVzdGVyKSksXG4gICAgcHVibGlzaFJlZigpLFxuICApO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgJG5ldHdvcmtNb2RlID0gdG9TaWduYWwodGhpcy5uZXR3b3JrTW9kZSQpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgc3VibmV0RGV0YWlscyQgPSBjb21iaW5lTGF0ZXN0KFtcbiAgICB0aGlzLmNsdXN0ZXIkLFxuICAgIHRoaXMubmV0d29ya1R5cGUkLFxuICAgIHRoaXMuc3VibmV0JCxcbiAgXSkucGlwZShcbiAgICBmaWx0ZXIoKFtjbHVzdGVyLCBuZXR3b3JrVHlwZV0pID0+ICEhY2x1c3RlciAmJiAhIW5ldHdvcmtUeXBlKSxcbiAgICBzd2l0Y2hNYXAoKFtjbHVzdGVyLCBfbmV0d29ya1R5cGUsIHN1Ym5ldF0pID0+XG4gICAgICBzdWJuZXRcbiAgICAgICAgPyBvZih7XG4gICAgICAgICAgICBjbHVzdGVyLFxuICAgICAgICAgICAgc3VibmV0czogW3N1Ym5ldF0sXG4gICAgICAgICAgICBzdWJuZXQsXG4gICAgICAgICAgICBnYXRld2F5OiBzdWJuZXQuc3BlYz8uZ2F0ZXdheSxcbiAgICAgICAgICB9KVxuICAgICAgICA6IHRoaXMuaXNDYWxpY29cbiAgICAgICAgPyB0aGlzLms4c0FwaVxuICAgICAgICAgICAgLmdldFJlc291cmNlTGlzdDxTdWJuZXQ+KHtcbiAgICAgICAgICAgICAgdHlwZTogTkVUV09SS19SRVNPVVJDRV9UWVBFUy5TVUJORVRfS1VCRV9PVk4sXG4gICAgICAgICAgICAgIGNsdXN0ZXIsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgIG1hcChyZXMgPT4gcmVzLml0ZW1zKSxcbiAgICAgICAgICAgICAgc2tpcEVycm9yKFtdIGFzIFN1Ym5ldFtdKSxcbiAgICAgICAgICAgICAgbWFwKHN1Ym5ldHMgPT4gKHtcbiAgICAgICAgICAgICAgICBjbHVzdGVyLFxuICAgICAgICAgICAgICAgIHN1Ym5ldHMsXG4gICAgICAgICAgICAgICAgc3VibmV0OiBudWxsIGFzIFN1Ym5ldCxcbiAgICAgICAgICAgICAgICBnYXRld2F5OiAnJyxcbiAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgKVxuICAgICAgICA6IG9mKHtcbiAgICAgICAgICAgIGNsdXN0ZXIsXG4gICAgICAgICAgICBzdWJuZXRzOiBbXSBhcyBTdWJuZXRbXSxcbiAgICAgICAgICAgIHN1Ym5ldDogbnVsbCBhcyBTdWJuZXQsXG4gICAgICAgICAgICBnYXRld2F5OiAnJyxcbiAgICAgICAgICB9KSxcbiAgICApLFxuICApO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgc3VibmV0SW5mbyQgPSBjb21iaW5lTGF0ZXN0KFtcbiAgICB0aGlzLm5ldHdvcmtNb2RlJCxcbiAgICB0aGlzLm5hbWVzcGFjZVJlc291cmNlJC5waXBlKGZpbHRlcihCb29sZWFuKSksXG4gICAgdGhpcy5zdWJuZXREZXRhaWxzJCxcbiAgXSkucGlwZShcbiAgICBtYXAoKFtuZXR3b3JrTW9kZSwgbmFtZXNwYWNlLCB7IGNsdXN0ZXIsIHN1Ym5ldHMsIHN1Ym5ldCwgZ2F0ZXdheSB9XSkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY2x1c3RlcixcbiAgICAgICAgc3VibmV0Q2lkcnM6IHRoaXMuaXNDYWxpY29cbiAgICAgICAgICA/IHRoaXMubmV0d29ya1V0aWxTZXJ2aWNlLmdldENhbGljb0NpZHJzKFxuICAgICAgICAgICAgICBuYW1lc3BhY2UsXG4gICAgICAgICAgICAgIHN1Ym5ldHMsXG4gICAgICAgICAgICAgIG5ldHdvcmtNb2RlLFxuICAgICAgICAgICAgICB0aGlzLmVuYWJsZUZpeElwVjZGb3JEdWFsLFxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogYWRhcHRTdWJuZXRDaWRycyhcbiAgICAgICAgICAgICAgc3VibmV0ID09IG51bGxcbiAgICAgICAgICAgICAgICA/IHRoaXMuazhzVXRpbC5nZXRBbm5vdGF0aW9uKG5hbWVzcGFjZSwge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnY2lkcicsXG4gICAgICAgICAgICAgICAgICAgIGJhc2VEb21haW46IEtVQkVfT1ZOX0FOTk9UQVRJT05fUFJFRklYLFxuICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICA6IHN1Ym5ldC5zcGVjPy5jaWRyQmxvY2sgPz8gJycsXG4gICAgICAgICAgICAgIHRoaXMuJG5ldHdvcmtNb2RlKCksXG4gICAgICAgICAgICAgIHRoaXMuZW5hYmxlRml4SXBWNkZvckR1YWwsXG4gICAgICAgICAgICApLFxuICAgICAgICBzdWJuZXROYW1lOlxuICAgICAgICAgIHN1Ym5ldCA9PSBudWxsXG4gICAgICAgICAgICA/IHRoaXMuazhzVXRpbC5nZXRBbm5vdGF0aW9uKG5hbWVzcGFjZSwge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdsb2dpY2FsX3N3aXRjaCcsXG4gICAgICAgICAgICAgICAgYmFzZURvbWFpbjogS1VCRV9PVk5fQU5OT1RBVElPTl9QUkVGSVgsXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICA6IHRoaXMuazhzVXRpbC5nZXROYW1lKHN1Ym5ldCksXG4gICAgICAgIGdhdGV3YXksXG4gICAgICB9O1xuICAgIH0pLFxuICAgIHN3aXRjaE1hcChzdWJuZXRJbmZvID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5uZXR3b3JrVHlwZSA9PT0gQ2x1c3Rlck5ldHdvcmtUeXBlLktVQkVfT1ZOICYmXG4gICAgICAgICFzdWJuZXRJbmZvLmdhdGV3YXlcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gZm9ya0pvaW4oXG4gICAgICAgICAgc3VibmV0SW5mby5zdWJuZXROYW1lLnNwbGl0KCcsJykubWFwKHN1Ym5ldE5hbWUgPT5cbiAgICAgICAgICAgIHRoaXMuazhzQXBpXG4gICAgICAgICAgICAgIC5nZXRSZXNvdXJjZTxTdWJuZXQ+KHtcbiAgICAgICAgICAgICAgICB0eXBlOiBORVRXT1JLX1JFU09VUkNFX1RZUEVTLlNVQk5FVF9LVUJFX09WTixcbiAgICAgICAgICAgICAgICBjbHVzdGVyOiBzdWJuZXRJbmZvLmNsdXN0ZXIsXG4gICAgICAgICAgICAgICAgbmFtZTogc3VibmV0TmFtZSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLnBpcGUoc2tpcEVycm9yKG51bGwgYXMgU3VibmV0KSksXG4gICAgICAgICAgKSxcbiAgICAgICAgKS5waXBlKFxuICAgICAgICAgIG1hcChsaXN0ID0+IGxpc3QuZmlsdGVyKEJvb2xlYW4pKSxcbiAgICAgICAgICBtYXAoc3VibmV0TGlzdCA9PlxuICAgICAgICAgICAgc3VibmV0TGlzdC5sZW5ndGhcbiAgICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgICAuLi5zdWJuZXRJbmZvLFxuICAgICAgICAgICAgICAgICAgZ2F0ZXdheTogc3VibmV0TGlzdFxuICAgICAgICAgICAgICAgICAgICAubWFwKGl0ZW0gPT4gaXRlbS5zcGVjPy5nYXRld2F5KVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgICAgICAgICAgICAgICAgIC5qb2luKCcsJyksXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA6IHN1Ym5ldEluZm8sXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvZihzdWJuZXRJbmZvKTtcbiAgICB9KSxcbiAgICBzd2l0Y2hNYXAoc3VibmV0SW5mbyA9PiB7XG4gICAgICBpZiAoc3VibmV0SW5mby5zdWJuZXRDaWRycy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIG9mKHN1Ym5ldEluZm8pO1xuICAgICAgfVxuXG4gICAgICAvLyBmYWxsYmFjayB0byBkZWZhdWx0IHN1Ym5ldFxuICAgICAgcmV0dXJuIHRoaXMuazhzQXBpXG4gICAgICAgIC5nZXRSZXNvdXJjZTxTdWJuZXQ+KHtcbiAgICAgICAgICB0eXBlOiBORVRXT1JLX1JFU09VUkNFX1RZUEVTLlNVQk5FVF9LVUJFX09WTixcbiAgICAgICAgICBjbHVzdGVyOiBzdWJuZXRJbmZvLmNsdXN0ZXIsXG4gICAgICAgICAgbmFtZTogdGhpcy5pc0NhbGljb1xuICAgICAgICAgICAgPyBgZGVmYXVsdC1pcCR7XG4gICAgICAgICAgICAgICAgdGhpcy4kbmV0d29ya01vZGUoKSA9PT0gJ2R1YWwnID8gJ3Y0JyA6IHRoaXMuJG5ldHdvcmtNb2RlKClcbiAgICAgICAgICAgICAgfS1pcHBvb2xgXG4gICAgICAgICAgICA6ICdvdm4tZGVmYXVsdCcsXG4gICAgICAgIH0pXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIG1hcChzdWJuZXQgPT4gKHtcbiAgICAgICAgICAgIC4uLnN1Ym5ldEluZm8sXG4gICAgICAgICAgICBzdWJuZXRDaWRyczogYWRhcHRTdWJuZXRDaWRycyhcbiAgICAgICAgICAgICAgc3VibmV0LnNwZWMuY2lkckJsb2NrLFxuICAgICAgICAgICAgICB0aGlzLiRuZXR3b3JrTW9kZSgpLFxuICAgICAgICAgICAgICB0aGlzLmVuYWJsZUZpeElwVjZGb3JEdWFsLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHN1Ym5ldE5hbWU6IHRoaXMuazhzVXRpbC5nZXROYW1lKHN1Ym5ldCksXG4gICAgICAgICAgICBnYXRld2F5OiBzdWJuZXQuc3BlYy5nYXRld2F5LFxuICAgICAgICAgIH0pKSxcbiAgICAgICAgKTtcbiAgICB9KSxcbiAgICBwdWJsaXNoUmVmKCksXG4gICk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSAkc3VibmV0SW5mbyA9IHRvU2lnbmFsKHRoaXMuc3VibmV0SW5mbyQpO1xuXG4gIGNpZHIkID0gdGhpcy5zdWJuZXRJbmZvJC5waXBlKFxuICAgIG1hcChzdWJuZXRJbmZvID0+IHN1Ym5ldEluZm8/LnN1Ym5ldENpZHJzLmpvaW4oJ+OAgScpKSxcbiAgKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGlubmVyRXJyb3JzTWFwcGVyJCA9IGNvbWJpbmVMYXRlc3QoW1xuICAgIHRoaXMuY2lkciQsXG4gICAgdGhpcy50cmFuc2xhdGUubG9jYWxlJCxcbiAgXSkucGlwZShcbiAgICBtYXAoKFtjaWRyXSkgPT4gKHtcbiAgICAgIHBhdHRlcm46IHRoaXMudHJhbnNsYXRlLmdldCgnZml4ZWRfaXBfcGF0dGVybl90aXBzJywge1xuICAgICAgICBpcE1vZGU6IFsnZHVhbCcsICd2NCddLmluY2x1ZGVzKHRoaXMuJG5ldHdvcmtNb2RlKCkpID8gJ0lQdjQnIDogJ0lQdjYnLFxuICAgICAgfSksXG4gICAgICBvY2N1cGllZDogdGhpcy50cmFuc2xhdGUuZ2V0KCdmaXhlZF9pcF9vY2N1cGllZF90aXBzJywge1xuICAgICAgICBjaWRyLFxuICAgICAgfSksXG4gICAgICBvdXRfb2ZfcmFuZ2U6IHRoaXMudHJhbnNsYXRlLmdldCgnZml4ZWRfaXBfb3V0X29mX3JhbmdlX3RpcHMnLCB7XG4gICAgICAgIGNpZHIsXG4gICAgICB9KSxcbiAgICB9KSksXG4gICk7XG5cbiAgY29tYmluZWRFcnJvcnNNYXBwZXIkID0gY29tYmluZUxhdGVzdChbXG4gICAgdGhpcy5pbm5lckVycm9yc01hcHBlciQsXG4gICAgdGhpcy5lcnJvcnNNYXBwZXIkLFxuICBdKS5waXBlKFxuICAgIG1hcCgoW2lubmVyRXJyb3JzTWFwcGVyLCBlcnJvcnNNYXBwZXJdKSA9PiAoe1xuICAgICAgLi4uaW5uZXJFcnJvcnNNYXBwZXIsXG4gICAgICAuLi5lcnJvcnNNYXBwZXIsXG4gICAgfSkpLFxuICApO1xuXG4gIGlucHV0RXJyb3JzJCA9IHRoaXMuZXJyb3JzJC5waXBlKFxuICAgIHRhcChlcnJvcnMgPT4ge1xuICAgICAgdGhpcy5zZXRFcnJvcnMoZXJyb3JzKTtcbiAgICAgIHRoaXMuaXBBZGRyZXNzPy5jb250cm9sLm1hcmtBc0RpcnR5KCk7XG4gICAgICB0aGlzLm9uVmFsaWRhdG9yQ2hhbmdlPy4oKTtcbiAgICB9KSxcbiAgKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHVzZWRJcHMkID0gY29tYmluZUxhdGVzdChbXG4gICAgdGhpcy5jbHVzdGVyJCxcbiAgICB0aGlzLnN1Ym5ldEluZm8kLFxuICAgIHRoaXMubW9kZWwkLnBpcGUoZmlyc3QoKSksXG4gIF0pLnBpcGUoXG4gICAgc3dpdGNoTWFwKChbY2x1c3RlciwgeyBzdWJuZXROYW1lLCBnYXRld2F5IH0sIGlwXSkgPT5cbiAgICAgIHRoaXMuaXNDYWxpY29cbiAgICAgICAgPyBvZihbXSBhcyBzdHJpbmdbXSlcbiAgICAgICAgOiB0aGlzLms4c0FwaVxuICAgICAgICAgICAgLmdldFJlc291cmNlTGlzdDxTdWJuZXRJcD4oe1xuICAgICAgICAgICAgICB0eXBlOiBORVRXT1JLX1JFU09VUkNFX1RZUEVTLlNVQk5FVF9LVUJFX09WTl9JUCxcbiAgICAgICAgICAgICAgY2x1c3RlcixcbiAgICAgICAgICAgICAgcXVlcnlQYXJhbXM6IHtcbiAgICAgICAgICAgICAgICBsYWJlbFNlbGVjdG9yOiBtYXRjaEV4cHJlc3Npb25zVG9TdHJpbmcoW1xuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBrZXk6IGAke0tVQkVfT1ZOX0FOTk9UQVRJT05fUFJFRklYfS9zdWJuZXRgLFxuICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcjogJ2luJyxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiBzdWJuZXROYW1lLnNwbGl0KCcsJyksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICBtYXAocmVzID0+IHJlcy5pdGVtcyksXG4gICAgICAgICAgICAgIHNraXBFcnJvcihbXSBhcyBTdWJuZXRJcFtdKSxcbiAgICAgICAgICAgICAgbWFwKHN1Ym5ldElwcyA9PlxuICAgICAgICAgICAgICAgIHN1Ym5ldElwcy5yZWR1Y2U8c3RyaW5nW10+KFxuICAgICAgICAgICAgICAgICAgKHVzZWRJcHMsIHsgc3BlYzogeyBpcEFkZHJlc3MgfSB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlwQWRkcmVzcy5zcGxpdCgnLCcpLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGlwICE9PSBpdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1c2VkSXBzLnB1c2goaXRlbSk7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVzZWRJcHM7XG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgZ2F0ZXdheS5zcGxpdCgnLCcpLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApLFxuICAgICksXG4gICAgcHVibGlzaFJlZigpLFxuICApO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgJHVzZWRJcHMgPSB0b1NpZ25hbCh0aGlzLnVzZWRJcHMkKTtcblxuICBpcEFkZHJlc3NTdWdnZXN0aW9ucyQgPSBjb21iaW5lTGF0ZXN0KFtcbiAgICB0aGlzLnN1Ym5ldEluZm8kLFxuICAgIHRoaXMudXNlZElwcyQsXG4gICAgdGhpcy5uZXR3b3JrTW9kZSQsXG4gICAgdGhpcy5tb2RlbCQsXG4gICAgdGhpcy50YWdzSW5wdXQkLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAodGFnc0lucHV0ID0+XG4gICAgICAgIHRhZ3NJbnB1dFxuICAgICAgICAgID8gbWVyZ2UoXG4gICAgICAgICAgICAgIGZyb21FdmVudCh0YWdzSW5wdXQuaW5wdXRSZWYubmF0aXZlRWxlbWVudCwgJ2lucHV0JykucGlwZShcbiAgICAgICAgICAgICAgICBtYXAoZXYgPT4gKGV2LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZSksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIHRhZ3NJbnB1dC5pbnB1dENvbnRyb2wudmFsdWVDaGFuZ2VzIGFzIE9ic2VydmFibGU8c3RyaW5nPixcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6ICh0aGlzLm1vZGVsJCBhcyBPYnNlcnZhYmxlPHN0cmluZz4pLFxuICAgICAgKSxcbiAgICApLFxuICBdKS5waXBlKFxuICAgIG1hcCgoW3sgc3VibmV0Q2lkcnMgfSwgdXNlZElwcywgbmV0d29ya01vZGUsIGFkZGVkSXBzLCBpbnB1dFZhbHVlXSkgPT5cbiAgICAgIGdldElwQWRkcmVzc1N1Z2dlc3Rpb25zQnlDaWRycyhcbiAgICAgICAgc3VibmV0Q2lkcnMsXG4gICAgICAgIG5ldHdvcmtNb2RlLFxuICAgICAgICBbXG4gICAgICAgICAgLi4udXNlZElwcyxcbiAgICAgICAgICAuLi4oQXJyYXkuaXNBcnJheShhZGRlZElwcykgPyBhZGRlZElwcyA6IFthZGRlZElwc10uZmlsdGVyKEJvb2xlYW4pKSxcbiAgICAgICAgXSxcbiAgICAgICAgaW5wdXRWYWx1ZSxcbiAgICAgICAgdGhpcy5pc0NhbGljbyxcbiAgICAgICksXG4gICAgKSxcbiAgICBzdGFydFdpdGgoW10gYXMgc3RyaW5nW10pLFxuICAgIHNraXBFcnJvcihbXSBhcyBzdHJpbmdbXSksXG4gICAgcHVibGlzaFJlZigpLFxuICApO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBvdmVycmlkZSByZWFkb25seSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgazhzVXRpbDogSzhzVXRpbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBrOHNBcGk6IEs4c0FwaVNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBuZXR3b3JrVXRpbFNlcnZpY2U6IE5ldHdvcmtVdGlsU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgKSB7XG4gICAgc3VwZXIoY2RyKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25WYWxpZGF0b3JDaGFuZ2UoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uVmFsaWRhdG9yQ2hhbmdlID0gZm47XG4gIH1cblxuICBAYmluZFxuICB2YWxpZGF0ZShjdHJsOiBBYnN0cmFjdENvbnRyb2wpIHtcbiAgICBjb25zdCBpcEFkZHJlc3M6IHN0cmluZyB8IHN0cmluZ1tdID0gY3RybC52YWx1ZTtcbiAgICByZXR1cm4gaXBBZGRyZXNzICYmICFBcnJheS5pc0FycmF5KGlwQWRkcmVzcylcbiAgICAgID8gdGhpcy51c2VkSXBzJC5waXBlKFxuICAgICAgICAgIGZpcnN0KCksXG4gICAgICAgICAgbWFwKCgpID0+IHRoaXMuc2V0RXJyb3JzKHRoaXMudmFsaWRhdGVGaXhlZElwKGlwQWRkcmVzcykpKSxcbiAgICAgICAgKVxuICAgICAgOiBvZih0aGlzLnNldEVycm9ycyhudWxsKSk7XG4gIH1cblxuICBwcml2YXRlIHNldEVycm9ycyhlcnJvcnM6IFZhbGlkYXRpb25FcnJvcnMpIHtcbiAgICBjb25zdCBjb21iaW5lZEVycm9ycyA9IHRoaXMubXVsdGlwbGVcbiAgICAgID8geyAuLi50aGlzLmlwQWRkcmVzcz8uY29udHJvbC5lcnJvcnMsIC4uLmVycm9ycyB9IC8vIOWPr+iDveWtmOWcqOS8oOWFpeeahCBlcnJvcnNcbiAgICAgIDogZXJyb3JzO1xuICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWx1ZXMoY29tYmluZWRFcnJvcnMpLmxlbmd0aFxuICAgICAgPyBjb21iaW5lZEVycm9yc1xuICAgICAgOiBudWxsO1xuICAgIHRoaXMuaXBBZGRyZXNzPy5jb250cm9sLnNldEVycm9ycyh2YWxpZGF0aW9uRXJyb3JzKTtcbiAgICByZXR1cm4gdmFsaWRhdGlvbkVycm9ycztcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVGaXhlZElwKGlwQWRkcmVzczogc3RyaW5nKSB7XG4gICAgY29uc3QgeyBzdWJuZXRDaWRycywgZ2F0ZXdheSB9ID0gdGhpcy4kc3VibmV0SW5mbygpO1xuXG4gICAgY29uc3QgaXBNb2RlID0gdGhpcy5hZGFwdElwTW9kZShpcEFkZHJlc3MpO1xuICAgIGNvbnN0IGlzSXBWNCA9IGlwTW9kZSA9PT0gSVBNb2RlLklQVjQ7XG5cbiAgICBjb25zdCBqdWRnZUNpZHJzID0gc3VibmV0Q2lkcnMuZmlsdGVyKGNpZHIgPT4ge1xuICAgICAgY29uc3QgaXNJcFY2ID0gY2lkci5pbmNsdWRlcygnOicpO1xuICAgICAgcmV0dXJuIGlzSXBWNCA/ICFpc0lwVjYgOiBpc0lwVjY7XG4gICAgfSk7XG5cbiAgICBpZiAoc3VibmV0Q2lkcnMubGVuZ3RoICYmICFqdWRnZUNpZHJzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGF0dGVybjogdHJ1ZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gaW52YWxpZCBpcCBwYXR0ZXJuLCBub3QgYnJvYWRjYXN0IGlwLCBub3QgbmV0d29yayBpcFxuICAgIGlmIChcbiAgICAgICFpc0lwQWRkcmVzc1ZhbGlkKGlwQWRkcmVzcywgaXBNb2RlKSB8fFxuICAgICAganVkZ2VDaWRycy5zb21lKFxuICAgICAgICBjYWxpY29DaWRyID0+XG4gICAgICAgICAgaXNCcm9hZGNhc3RBZGRyKGlwQWRkcmVzcywgY2FsaWNvQ2lkciwgaXBNb2RlKSB8fFxuICAgICAgICAgIGlzTmV0d29ya0FkZHIoaXBBZGRyZXNzLCBjYWxpY29DaWRyLCBpcE1vZGUpLFxuICAgICAgKVxuICAgICkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGF0dGVybjogdHJ1ZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgbGV0IHY0R2F0ZXdheTogc3RyaW5nO1xuICAgIGxldCB2NkdhdGV3YXk6IHN0cmluZztcblxuICAgIGlmIChnYXRld2F5KSB7XG4gICAgICBjb25zdCBnYXRld2F5UGFydHMgPSBnYXRld2F5LnNwbGl0KCcsJyk7XG4gICAgICB2NEdhdGV3YXkgPSBnYXRld2F5UGFydHNbMF07XG4gICAgICB2NkdhdGV3YXkgPSBnYXRld2F5UGFydHNbMV07XG4gICAgfVxuXG4gICAgY29uc3QgaXBHYXRld2F5ID0gaXNJcFY0ID8gdjRHYXRld2F5IDogdjZHYXRld2F5O1xuXG4gICAgaWYgKFxuICAgICAgLy8gaHR0cHM6Ly9qaXJhLmFsYXVkYS5jbi9icm93c2UvQUNQLTEyMTM2P2ZvY3VzZWRDb21tZW50SWQ9MjE1NDYwJnBhZ2U9Y29tLmF0bGFzc2lhbi5qaXJhLnBsdWdpbi5zeXN0ZW0uaXNzdWV0YWJwYW5lbHMlM0Fjb21tZW50LXRhYnBhbmVsI2NvbW1lbnQtMjE1NDYwXG4gICAgICAoaXBHYXRld2F5ICYmIGlwQWRkcmVzc0VxdWFsKGlwR2F0ZXdheSwgaXBBZGRyZXNzLCBpcE1vZGUpKSB8fFxuICAgICAgKCF0aGlzLnNraXBPY2N1cGllZCAmJlxuICAgICAgICB0aGlzLiR1c2VkSXBzKCkuc29tZSh1c2VkSXAgPT5cbiAgICAgICAgICBpcEFkZHJlc3NFcXVhbCh1c2VkSXAsIGlwQWRkcmVzcywgaXBNb2RlKSxcbiAgICAgICAgKSlcbiAgICApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9jY3VwaWVkOiB0cnVlLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBqdWRnZUNpZHJzLmxlbmd0aCAmJlxuICAgICAgIWp1ZGdlQ2lkcnMuc29tZShjaWRyID0+IGNpZHIgJiYgaXNCZWxvbmdDaWRyKGNpZHIsIGlwQWRkcmVzcywgaXBNb2RlKSlcbiAgICApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG91dF9vZl9yYW5nZTogdHJ1ZSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGFwdElwTW9kZShpcEFkZHJlc3M6IHN0cmluZykge1xuICAgIHJldHVybiBhZGFwdElwTW9kZShcbiAgICAgIGlwQWRkcmVzcyxcbiAgICAgICF0aGlzLmVuYWJsZUZpeElwVjZGb3JEdWFsICYmIHRoaXMuJG5ldHdvcmtNb2RlKCkgPT09IE5ldHdvcmtNb2RlLkRVQUxcbiAgICAgICAgPyBOZXR3b3JrTW9kZS5JUFY0XG4gICAgICAgIDogdGhpcy4kbmV0d29ya01vZGUoKSxcbiAgICApO1xuICB9XG59XG4iLCI8YXVpLWZvcm0taXRlbSBbd2lkdGhdPVwiZm9ybUl0ZW1XaWR0aFwiPlxuICA8bGFiZWwgYXVpRm9ybUl0ZW1MYWJlbD57eyBsYWJlbCB8fCAoJ2lwX2FkZHJlc3MnIHwgdHJhbnNsYXRlKSB9fTwvbGFiZWw+XG4gIDxpbnB1dFxuICAgICpuZ0lmPVwiIW11bHRpcGxlXCJcbiAgICBhdWktaW5wdXRcbiAgICBhdWlGb3JtSXRlbUNvbnRyb2xcbiAgICBbbmdNb2RlbF09XCJtb2RlbFwiXG4gICAgKG5nTW9kZWxDaGFuZ2UpPVwiZW1pdFZhbHVlKCRldmVudClcIlxuICAgICNpcEFkZHJlc3M9XCJuZ01vZGVsXCJcbiAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXIgfHwgKCdkaGNwX3BsYWNlaG9sZGVyJyB8IHRyYW5zbGF0ZSlcIlxuICAgIFthdWlBdXRvY29tcGxldGVdPVwic3VnZ2VzdGlvbnNcIlxuICAvPlxuICA8YXVpLXRhZ3MtaW5wdXRcbiAgICAqbmdJZj1cIm11bHRpcGxlXCJcbiAgICBjbGFzcz1cImZsZXgtMVwiXG4gICAgYXVpRm9ybUl0ZW1Db250cm9sXG4gICAgI3RhZ3NJbnB1dFxuICAgIFtuZ01vZGVsXT1cIm1vZGVsXCJcbiAgICAobmdNb2RlbENoYW5nZSk9XCJlbWl0VmFsdWUodW5pcSgkZXZlbnQpKVwiXG4gICAgI2lwQWRkcmVzcz1cIm5nTW9kZWxcIlxuICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlciB8fCAoJ2RoY3BfcGxhY2Vob2xkZXInIHwgdHJhbnNsYXRlKVwiXG4gICAgW2F1aUF1dG9jb21wbGV0ZV09XCJzdWdnZXN0aW9uc1wiXG4gICAgW2lucHV0QXN5bmNWYWxpZGF0b3JdPVwidmFsaWRhdGVcIlxuICA+PC9hdWktdGFncy1pbnB1dD5cbiAgPGF1aS1hdXRvY29tcGxldGUgI3N1Z2dlc3Rpb25zPlxuICAgIDxhdWktc3VnZ2VzdGlvblxuICAgICAgKm5nRm9yPVwibGV0IGlwQWRkcmVzc1N1Z2dlc3Rpb24gb2YgaXBBZGRyZXNzU3VnZ2VzdGlvbnMkIHwgYXN5bmNcIlxuICAgICAgW3ZhbHVlXT1cImlwQWRkcmVzc1N1Z2dlc3Rpb25cIlxuICAgID5cbiAgICAgIHt7IGlwQWRkcmVzc1N1Z2dlc3Rpb24gfX1cbiAgICA8L2F1aS1zdWdnZXN0aW9uPlxuICAgIDxhdWktYXV0b2NvbXBsZXRlLXBsYWNlaG9sZGVyPlxuICAgICAge3tcbiAgICAgICAgKChpcEFkZHJlc3NTdWdnZXN0aW9ucyQgfCBhc3luYylcbiAgICAgICAgICA/ICdub19hdmFpbGFibGVfc3VnZ2VzdGlvbidcbiAgICAgICAgICA6ICdsb2FkaW5nJ1xuICAgICAgICApIHwgdHJhbnNsYXRlXG4gICAgICB9fVxuICAgIDwvYXVpLWF1dG9jb21wbGV0ZS1wbGFjZWhvbGRlcj5cbiAgPC9hdWktYXV0b2NvbXBsZXRlPlxuICA8bmctY29udGFpbmVyXG4gICAgKm5nSWY9XCJhZGRvblRpcCAhPSBudWxsXCJcbiAgICBhdWlGb3JtSXRlbUFkZG9uXG4gID5cbiAgICA8YXVpLWljb25cbiAgICAgICpuZ0lmPVwiYWRkb25UaXBcIlxuICAgICAgaWNvbj1cInF1ZXN0aW9uX2NpcmNsZVwiXG4gICAgICBjbGFzcz1cImljb24tLWhlbHBcIlxuICAgICAgW2F1aVRvb2x0aXBdPVwiYWRkb25UaXBcIlxuICAgICAgYXVpVG9vbHRpcFBvc2l0aW9uPVwiZW5kXCJcbiAgICA+PC9hdWktaWNvbj5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxhY2wtZXJyb3JzLW1hcHBlclxuICAgIGF1aUZvcm1JdGVtRXJyb3JcbiAgICBbZXJyb3JzXT1cIlxuICAgICAgaXBBZGRyZXNzPy5lcnJvcnM/LmlucHV0X2RhdGFfZXJyb3IgfHxcbiAgICAgIGlwQWRkcmVzcz8uZXJyb3JzIHx8XG4gICAgICAoaW5wdXRFcnJvcnMkIHwgYXN5bmMpXG4gICAgXCJcbiAgICBbZXJyb3JzTWFwcGVyXT1cImNvbWJpbmVkRXJyb3JzTWFwcGVyJCB8IGFzeW5jXCJcbiAgPjwvYWNsLWVycm9ycy1tYXBwZXI+XG4gIDxkaXZcbiAgICBhdWlGb3JtSXRlbUhpbnRcbiAgICAqbmdJZj1cImhpbnQgIT09IG51bGwgJiYgKGhpbnQgfHwgKGNpZHIkIHwgYXN5bmMpKVwiXG4gID5cbiAgICB7e1xuICAgICAgaGludCB8fFxuICAgICAgICAoJ2ZpeF9pcF9zaG91bGRfYmVsb25nX3RpcCcgfCB0cmFuc2xhdGU6IHsgY2lkcjogKGNpZHIkIHwgYXN5bmMpIH0pXG4gICAgfX1cbiAgPC9kaXY+XG48L2F1aS1mb3JtLWl0ZW0+XG4iXX0=