@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.
- package/esm2022/alauda-fe-network.mjs +5 -0
- package/esm2022/index.mjs +19 -0
- package/esm2022/lib/components/certificate-status/component.mjs +37 -0
- package/esm2022/lib/components/fixed-ip/component.mjs +503 -0
- package/esm2022/lib/components/loadbalancer-spec-form/component.mjs +251 -0
- package/esm2022/lib/components/service-annotations-form/annotations.component.mjs +681 -0
- package/esm2022/lib/components/service-annotations-form-item/annotations.component.mjs +106 -0
- package/esm2022/lib/components/service-form/component.mjs +307 -0
- package/esm2022/lib/components/service-form/fieldset/component.mjs +407 -0
- package/esm2022/lib/directives/subnet-validator.directive.mjs +111 -0
- package/esm2022/lib/services/alb-api.service.mjs +48 -0
- package/esm2022/lib/services/certificate-api.service.mjs +111 -0
- package/esm2022/lib/services/network-util.service.mjs +116 -0
- package/esm2022/lib/types/alb-exports.mjs +14 -0
- package/esm2022/lib/types/k8s-exports.mjs +13 -0
- package/esm2022/lib/types/resource-definition.mjs +16 -0
- package/esm2022/lib/utils/alb-exports.mjs +108 -0
- package/esm2022/lib/utils/alb-internals.mjs +2 -0
- package/esm2022/lib/utils/cidr-exports.mjs +359 -0
- package/esm2022/lib/utils/cluster-exports.mjs +18 -0
- package/esm2022/lib/utils/service-exports.mjs +58 -0
- package/esm2022/lib/utils/service-internals.mjs +7 -0
- package/esm2022/lib/utils/subnet-exports.mjs +18 -0
- package/index.d.ts +18 -0
- package/lib/components/certificate-status/component.d.ts +17 -0
- package/lib/components/fixed-ip/component.d.ts +67 -0
- package/lib/components/loadbalancer-spec-form/component.d.ts +34 -0
- package/lib/components/service-annotations-form/annotations.component.d.ts +74 -0
- package/lib/components/service-annotations-form-item/annotations.component.d.ts +14 -0
- package/lib/components/service-form/component.d.ts +56 -0
- package/lib/components/service-form/fieldset/component.d.ts +46 -0
- package/lib/directives/subnet-validator.directive.d.ts +34 -0
- package/lib/services/alb-api.service.d.ts +16 -0
- package/lib/services/certificate-api.service.d.ts +38 -0
- package/lib/services/network-util.service.d.ts +21 -0
- package/lib/types/alb-exports.d.ts +29 -0
- package/lib/types/k8s-exports.d.ts +130 -0
- package/lib/types/resource-definition.d.ts +25 -0
- package/lib/utils/alb-exports.d.ts +16 -0
- package/lib/utils/alb-internals.d.ts +10 -0
- package/lib/utils/cidr-exports.d.ts +85 -0
- package/lib/utils/cluster-exports.d.ts +14 -0
- package/lib/utils/service-exports.d.ts +18 -0
- package/lib/utils/service-internals.d.ts +2 -0
- package/lib/utils/subnet-exports.d.ts +20 -0
- 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=
|