@qbs-origin/origin-form 0.5.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/README.md +24 -0
- package/esm2022/lib/action-step-handler.mjs +163 -0
- package/esm2022/lib/auth-client.service.mjs +69 -0
- package/esm2022/lib/enums/label.keys.mjs +721 -0
- package/esm2022/lib/form-css.helper.mjs +367 -0
- package/esm2022/lib/formly/baseFormlyControlComponent.mjs +52 -0
- package/esm2022/lib/formly/baseFormlyStepComponent.mjs +59 -0
- package/esm2022/lib/formly/custom-section-separator.component.mjs +32 -0
- package/esm2022/lib/formly/form-section-separator.component.mjs +36 -0
- package/esm2022/lib/formly/formly-action.mjs +56 -0
- package/esm2022/lib/formly/formly-checkbox/formly-checkbox.component.mjs +52 -0
- package/esm2022/lib/formly/formly-dictionary-dropdown-tree/formly-dictionary-dropdown-tree.component.mjs +261 -0
- package/esm2022/lib/formly/formly-download-documents/formly-download-documents.component.mjs +126 -0
- package/esm2022/lib/formly/formly-enrol-card/formly-enrol-card.component.mjs +120 -0
- package/esm2022/lib/formly/formly-field-stepper/formly-field-stepper.component.mjs +762 -0
- package/esm2022/lib/formly/formly-generate-documents/formly-generate-documents.component.mjs +57 -0
- package/esm2022/lib/formly/formly-identification.component.mjs +84 -0
- package/esm2022/lib/formly/formly-open-banking/formly-open-banking.component.mjs +590 -0
- package/esm2022/lib/formly/formly-paragraph/formly-paragraph.component.mjs +35 -0
- package/esm2022/lib/formly/formly-radio/formly-radio-component.mjs +49 -0
- package/esm2022/lib/formly/formly-row-fille.mjs +12 -0
- package/esm2022/lib/formly/formly-scan-id/formly-scan-id.component.mjs +284 -0
- package/esm2022/lib/formly/formly-sign/formly-sign.component.mjs +173 -0
- package/esm2022/lib/formly/formly-upload-documents/formly-upload-documents.component.mjs +198 -0
- package/esm2022/lib/formly/formly-validate-contact-info/formly-validate-contact-info.component.mjs +124 -0
- package/esm2022/lib/formly/formly-view-documents/formly-view-documents.component.mjs +245 -0
- package/esm2022/lib/formly/formly-view-offers/formly-view-offers.component.mjs +160 -0
- package/esm2022/lib/model-population.helper.mjs +265 -0
- package/esm2022/lib/models/application-type.model.mjs +12 -0
- package/esm2022/lib/models/application.model.mjs +30 -0
- package/esm2022/lib/models/auth/users.model.mjs +2 -0
- package/esm2022/lib/models/dictionary.model.mjs +20 -0
- package/esm2022/lib/models/flux.model.mjs +105 -0
- package/esm2022/lib/models/forms.model.mjs +572 -0
- package/esm2022/lib/models/label-info.model.mjs +2 -0
- package/esm2022/lib/models/label.model.mjs +2 -0
- package/esm2022/lib/models/language.model.mjs +3 -0
- package/esm2022/lib/models/list.model.mjs +2 -0
- package/esm2022/lib/models/partner.model.mjs +3 -0
- package/esm2022/lib/models/treeview.model.mjs +15 -0
- package/esm2022/lib/origin-form-auth.service.mjs +40 -0
- package/esm2022/lib/origin-form-config.model.mjs +2 -0
- package/esm2022/lib/origin-form-token.interceptor.mjs +35 -0
- package/esm2022/lib/origin-form.component.mjs +2391 -0
- package/esm2022/lib/origin-form.module.mjs +479 -0
- package/esm2022/lib/origin-form.service.mjs +14 -0
- package/esm2022/lib/others/check-list.database.mjs +55 -0
- package/esm2022/lib/others/config-service.mjs +42 -0
- package/esm2022/lib/others/dictionary-label-info.mjs +3 -0
- package/esm2022/lib/others/environment-type.mjs +21 -0
- package/esm2022/lib/others/external-link.directive.mjs +49 -0
- package/esm2022/lib/others/flux-helper.mjs +1397 -0
- package/esm2022/lib/others/picker.component.mjs +119 -0
- package/esm2022/lib/others/translation.pipe.mjs +21 -0
- package/esm2022/lib/others/translations-helper.mjs +258 -0
- package/esm2022/lib/others/utils.mjs +272 -0
- package/esm2022/lib/services/applicationData.service.mjs +145 -0
- package/esm2022/lib/services/auth-http.service.mjs +80 -0
- package/esm2022/lib/services/dialog.service.mjs +56 -0
- package/esm2022/lib/services/dictionary.service.mjs +198 -0
- package/esm2022/lib/services/forms.service.mjs +47 -0
- package/esm2022/lib/services/labels.service.mjs +29 -0
- package/esm2022/lib/services/language.service.mjs +24 -0
- package/esm2022/lib/services/open-banking.service.mjs +194 -0
- package/esm2022/lib/services/origin-form-signalr-handler.service.mjs +107 -0
- package/esm2022/lib/services/origin-form-signalr.service.mjs +105 -0
- package/esm2022/lib/services/otp.service.mjs +28 -0
- package/esm2022/lib/services/proxy.service.mjs +79 -0
- package/esm2022/lib/services/scroll-to-error.service.mjs +369 -0
- package/esm2022/lib/services/translation.service.mjs +27 -0
- package/esm2022/lib/shared-components/confirmation.component.mjs +34 -0
- package/esm2022/lib/shared-components/dictionaries-tree.component.mjs +301 -0
- package/esm2022/lib/shared-components/grid.component.mjs +241 -0
- package/esm2022/lib/shared-components/treeview/treeview.component.mjs +224 -0
- package/esm2022/lib/theme-css.mjs +2254 -0
- package/esm2022/lib/theme-injector.service.mjs +26 -0
- package/esm2022/public-api.mjs +4 -0
- package/esm2022/qbs-origin-origin-form.mjs +5 -0
- package/fesm2022/qbs-origin-origin-form.mjs +15215 -0
- package/fesm2022/qbs-origin-origin-form.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/action-step-handler.d.ts +49 -0
- package/lib/auth-client.service.d.ts +17 -0
- package/lib/enums/label.keys.d.ts +720 -0
- package/lib/form-css.helper.d.ts +28 -0
- package/lib/formly/baseFormlyControlComponent.d.ts +25 -0
- package/lib/formly/baseFormlyStepComponent.d.ts +29 -0
- package/lib/formly/custom-section-separator.component.d.ts +6 -0
- package/lib/formly/form-section-separator.component.d.ts +10 -0
- package/lib/formly/formly-action.d.ts +13 -0
- package/lib/formly/formly-checkbox/formly-checkbox.component.d.ts +15 -0
- package/lib/formly/formly-dictionary-dropdown-tree/formly-dictionary-dropdown-tree.component.d.ts +45 -0
- package/lib/formly/formly-download-documents/formly-download-documents.component.d.ts +22 -0
- package/lib/formly/formly-enrol-card/formly-enrol-card.component.d.ts +114 -0
- package/lib/formly/formly-field-stepper/formly-field-stepper.component.d.ts +79 -0
- package/lib/formly/formly-generate-documents/formly-generate-documents.component.d.ts +17 -0
- package/lib/formly/formly-identification.component.d.ts +19 -0
- package/lib/formly/formly-open-banking/formly-open-banking.component.d.ts +119 -0
- package/lib/formly/formly-paragraph/formly-paragraph.component.d.ts +10 -0
- package/lib/formly/formly-radio/formly-radio-component.d.ts +15 -0
- package/lib/formly/formly-row-fille.d.ts +6 -0
- package/lib/formly/formly-scan-id/formly-scan-id.component.d.ts +41 -0
- package/lib/formly/formly-sign/formly-sign.component.d.ts +36 -0
- package/lib/formly/formly-upload-documents/formly-upload-documents.component.d.ts +25 -0
- package/lib/formly/formly-validate-contact-info/formly-validate-contact-info.component.d.ts +79 -0
- package/lib/formly/formly-view-documents/formly-view-documents.component.d.ts +33 -0
- package/lib/formly/formly-view-offers/formly-view-offers.component.d.ts +23 -0
- package/lib/model-population.helper.d.ts +8 -0
- package/lib/models/application-type.model.d.ts +27 -0
- package/lib/models/application.model.d.ts +107 -0
- package/lib/models/auth/users.model.d.ts +20 -0
- package/lib/models/dictionary.model.d.ts +77 -0
- package/lib/models/flux.model.d.ts +101 -0
- package/lib/models/forms.model.d.ts +504 -0
- package/lib/models/label-info.model.d.ts +10 -0
- package/lib/models/label.model.d.ts +4 -0
- package/lib/models/language.model.d.ts +5 -0
- package/lib/models/list.model.d.ts +8 -0
- package/lib/models/partner.model.d.ts +12 -0
- package/lib/models/treeview.model.d.ts +17 -0
- package/lib/origin-form-auth.service.d.ts +15 -0
- package/lib/origin-form-config.model.d.ts +12 -0
- package/lib/origin-form-token.interceptor.d.ts +12 -0
- package/lib/origin-form.component.d.ts +231 -0
- package/lib/origin-form.module.d.ts +84 -0
- package/lib/origin-form.service.d.ts +6 -0
- package/lib/others/check-list.database.d.ts +16 -0
- package/lib/others/config-service.d.ts +22 -0
- package/lib/others/dictionary-label-info.d.ts +6 -0
- package/lib/others/environment-type.d.ts +8 -0
- package/lib/others/external-link.directive.d.ts +12 -0
- package/lib/others/flux-helper.d.ts +115 -0
- package/lib/others/picker.component.d.ts +36 -0
- package/lib/others/translation.pipe.d.ts +10 -0
- package/lib/others/translations-helper.d.ts +31 -0
- package/lib/others/utils.d.ts +37 -0
- package/lib/services/applicationData.service.d.ts +35 -0
- package/lib/services/auth-http.service.d.ts +21 -0
- package/lib/services/dialog.service.d.ts +20 -0
- package/lib/services/dictionary.service.d.ts +89 -0
- package/lib/services/forms.service.d.ts +17 -0
- package/lib/services/labels.service.d.ts +13 -0
- package/lib/services/language.service.d.ts +14 -0
- package/lib/services/open-banking.service.d.ts +137 -0
- package/lib/services/origin-form-signalr-handler.service.d.ts +29 -0
- package/lib/services/origin-form-signalr.service.d.ts +24 -0
- package/lib/services/otp.service.d.ts +22 -0
- package/lib/services/proxy.service.d.ts +29 -0
- package/lib/services/scroll-to-error.service.d.ts +54 -0
- package/lib/services/translation.service.d.ts +10 -0
- package/lib/shared-components/confirmation.component.d.ts +77 -0
- package/lib/shared-components/dictionaries-tree.component.d.ts +51 -0
- package/lib/shared-components/grid.component.d.ts +138 -0
- package/lib/shared-components/treeview/treeview.component.d.ts +121 -0
- package/lib/theme-css.d.ts +2 -0
- package/lib/theme-injector.service.d.ts +8 -0
- package/package.json +42 -0
- package/public-api.d.ts +3 -0
- package/schematics-compiled/collection.json +10 -0
- package/schematics-compiled/ng-add/index.d.ts +2 -0
- package/schematics-compiled/ng-add/index.js +67 -0
- package/schematics-compiled/ng-add/index.js.map +1 -0
- package/schematics-compiled/ng-add/schema.json +8 -0
- package/src/lib/assets/fonts/Figtree-Bold.ttf +0 -0
- package/src/lib/assets/fonts/Figtree-Light.ttf +0 -0
- package/src/lib/assets/fonts/Figtree-Regular.ttf +0 -0
- package/src/lib/assets/fonts/Sora-ExtraBold.ttf +0 -0
- package/src/lib/assets/fonts/Sora-Light.ttf +0 -0
- package/src/lib/assets/fonts/Sora-Regular.ttf +0 -0
- package/src/lib/assets/fonts/ttrounds-bold-webfont.woff +0 -0
- package/src/lib/assets/fonts/ttrounds-bold-webfont.woff2 +0 -0
- package/src/lib/assets/fonts/ttrounds-regular-webfont.woff +0 -0
- package/src/lib/assets/fonts/ttrounds-regular-webfont.woff2 +0 -0
- package/src/lib/assets/fonts/ttrounds-thin-webfont.woff +0 -0
- package/src/lib/assets/fonts/ttrounds-thin-webfont.woff2 +0 -0
- package/src/lib/assets/images/flag/icon-flag-de.svg +10 -0
- package/src/lib/assets/images/flag/icon-flag-en.svg +1 -0
- package/src/lib/assets/images/flag/icon-flag-es.svg +11 -0
- package/src/lib/assets/images/flag/icon-flag-fr.svg +1 -0
- package/src/lib/assets/images/flag/icon-flag-ro.svg +11 -0
- package/src/lib/assets/images/flag/origin-form/new-id-card.png +0 -0
- package/src/lib/assets/images/flag/origin-form/old-id-card.png +0 -0
|
@@ -0,0 +1,762 @@
|
|
|
1
|
+
import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper';
|
|
2
|
+
import { Component, ViewChild, } from '@angular/core';
|
|
3
|
+
import { MatStepper } from '@angular/material/stepper';
|
|
4
|
+
import { FieldType } from '@ngx-formly/core';
|
|
5
|
+
import { timer, firstValueFrom, catchError, of } from 'rxjs';
|
|
6
|
+
import { AppData, FluxType, AppDataStep, AppDataSection, AppDataControl, AppDataFill, StepControlType, } from '../../models/forms.model';
|
|
7
|
+
import { ApplicationDataService } from '../../services/applicationData.service';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "../../services/applicationData.service";
|
|
10
|
+
import * as i2 from "../../origin-form.component";
|
|
11
|
+
import * as i3 from "../../services/scroll-to-error.service";
|
|
12
|
+
import * as i4 from "@angular/common";
|
|
13
|
+
import * as i5 from "@angular/material/stepper";
|
|
14
|
+
import * as i6 from "@angular/material/button";
|
|
15
|
+
import * as i7 from "@angular/material/progress-spinner";
|
|
16
|
+
import * as i8 from "@ngx-formly/core";
|
|
17
|
+
export class FormlyFieldStepperComponent extends FieldType {
|
|
18
|
+
constructor(applicationDataService, collectorForm, cdr, scrollToErrorService) {
|
|
19
|
+
super();
|
|
20
|
+
this.applicationDataService = applicationDataService;
|
|
21
|
+
this.collectorForm = collectorForm;
|
|
22
|
+
this.cdr = cdr;
|
|
23
|
+
this.scrollToErrorService = scrollToErrorService;
|
|
24
|
+
this.buttonsGroups = [];
|
|
25
|
+
this.showSteps = true;
|
|
26
|
+
this.showStepsLabels = true;
|
|
27
|
+
this.showStepsCounter = true;
|
|
28
|
+
this.showFinalStep = false;
|
|
29
|
+
this.isFlowFinished = false;
|
|
30
|
+
this.isDisplayMode = false;
|
|
31
|
+
this.isDebug = false;
|
|
32
|
+
this.isNavigationInProgress = false;
|
|
33
|
+
this.isSaving = false;
|
|
34
|
+
this.currentStepIndex = 0;
|
|
35
|
+
this.loadedSteps = [];
|
|
36
|
+
this.concatenatedFormStyle = {};
|
|
37
|
+
this.buttonsVerticalPosition = 'bottom';
|
|
38
|
+
this.isNavigating = false;
|
|
39
|
+
this.filteredVisibleSteps = [];
|
|
40
|
+
this.progressBarStyles = {};
|
|
41
|
+
}
|
|
42
|
+
async ngOnInit() {
|
|
43
|
+
this.props['component'] = this;
|
|
44
|
+
this.applyProgressBarStyles();
|
|
45
|
+
this.configUpdateSubscription =
|
|
46
|
+
this.collectorForm.formlyConfigUpdated.subscribe(() => {
|
|
47
|
+
if (this.field && this.field.fieldGroup) {
|
|
48
|
+
this.field.fieldGroup = this.extractFinalStepIfNecessary(this.field.fieldGroup);
|
|
49
|
+
}
|
|
50
|
+
this.createFieldGroupButtons();
|
|
51
|
+
});
|
|
52
|
+
this.visibleFieldsUpdatedSubscription =
|
|
53
|
+
this.collectorForm.visibleFieldsUpdated.subscribe((visibleFields) => {
|
|
54
|
+
this.filteredVisibleSteps = visibleFields;
|
|
55
|
+
});
|
|
56
|
+
this.updateAndGoNextSubscription =
|
|
57
|
+
this.collectorForm.formlyUpdateAndGoNext.subscribe(async (e) => {
|
|
58
|
+
if (e && e.selectedOfferId && this.appData?.fillData) {
|
|
59
|
+
this.appData.fillData.metadata.offerId = e.selectedOfferId;
|
|
60
|
+
}
|
|
61
|
+
const step = this.field.fieldGroup[this.currentStepIndex];
|
|
62
|
+
await this.navigateAsync('next', step);
|
|
63
|
+
});
|
|
64
|
+
this.goNextSubscription = this.collectorForm.formlyGoNext.subscribe((e) => {
|
|
65
|
+
this.goNext();
|
|
66
|
+
});
|
|
67
|
+
await this.initStep();
|
|
68
|
+
}
|
|
69
|
+
async ngOnChanges(changes) {
|
|
70
|
+
if (changes.field) {
|
|
71
|
+
await this.updateAppData(false);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async ngAfterViewInit() {
|
|
75
|
+
await this.createAppData(this.field.props);
|
|
76
|
+
if (this.currentStepIndex >= this.totalStepsCount) {
|
|
77
|
+
this.showFinalStep = true;
|
|
78
|
+
this.showSteps = false;
|
|
79
|
+
this.showStepsCounter = false;
|
|
80
|
+
}
|
|
81
|
+
else if (this.stepper) {
|
|
82
|
+
this.stepper.linear = false;
|
|
83
|
+
this.stepper.selectedIndex = this.currentStepIndex;
|
|
84
|
+
const steps = this.stepper._steps.toArray();
|
|
85
|
+
for (let i = 0; i < this.currentStepIndex; i++) {
|
|
86
|
+
steps[i].completed = true;
|
|
87
|
+
}
|
|
88
|
+
setTimeout(() => {
|
|
89
|
+
this.stepper.linear = true;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (this.field.fieldGroup && this.field.fieldGroup.length > 0) {
|
|
93
|
+
this.loadedSteps = Array(this.field.fieldGroup.length).fill(false);
|
|
94
|
+
this.loadedSteps[this.currentStepIndex] = true;
|
|
95
|
+
this.cdr.detectChanges();
|
|
96
|
+
}
|
|
97
|
+
if (!this.showSteps || this.currentStepIndex == 0) {
|
|
98
|
+
this.triggerOnPageSelectedForIndex(this.currentStepIndex);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
ngOnDestroy() {
|
|
102
|
+
if (this.configUpdateSubscription) {
|
|
103
|
+
this.configUpdateSubscription.unsubscribe();
|
|
104
|
+
}
|
|
105
|
+
if (this.updateAndGoNextSubscription) {
|
|
106
|
+
this.updateAndGoNextSubscription.unsubscribe();
|
|
107
|
+
}
|
|
108
|
+
if (this.goNextSubscription) {
|
|
109
|
+
this.goNextSubscription.unsubscribe();
|
|
110
|
+
}
|
|
111
|
+
if (this.visibleFieldsUpdatedSubscription) {
|
|
112
|
+
this.visibleFieldsUpdatedSubscription.unsubscribe();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async initStep() {
|
|
116
|
+
if (this.field) {
|
|
117
|
+
if (this.field.fieldGroup) {
|
|
118
|
+
this.field.fieldGroup = this.extractFinalStepIfNecessary(this.field.fieldGroup);
|
|
119
|
+
this.loadedSteps = Array(this.field.fieldGroup.length).fill(false);
|
|
120
|
+
this.loadedSteps[this.currentStepIndex] = true;
|
|
121
|
+
}
|
|
122
|
+
if (this.field.props) {
|
|
123
|
+
this.filteredVisibleSteps = this.field.props['filteredFlux'];
|
|
124
|
+
this.isDebug = this.field.props['isDebug'];
|
|
125
|
+
const stepSettings = this.field.props['stepsSettings'];
|
|
126
|
+
if (stepSettings) {
|
|
127
|
+
this.showSteps = stepSettings.showAllSteps;
|
|
128
|
+
this.showStepsCounter = stepSettings.showCounter;
|
|
129
|
+
this.showStepsLabels = stepSettings.showLabels;
|
|
130
|
+
this.showProgressBar = stepSettings.showProgressBar;
|
|
131
|
+
}
|
|
132
|
+
const designConfig = this.field.props['designConfig'];
|
|
133
|
+
if (designConfig) {
|
|
134
|
+
this.showButtonsOnTop =
|
|
135
|
+
designConfig.buttonsVerticalPosition === 'top';
|
|
136
|
+
}
|
|
137
|
+
Object.entries(this.field.props['design'])
|
|
138
|
+
.filter((i) => i[0].startsWith('.form'))
|
|
139
|
+
.forEach((i) => {
|
|
140
|
+
const prop = i[1];
|
|
141
|
+
Object.keys(prop).forEach((j) => {
|
|
142
|
+
this.concatenatedFormStyle[j] = prop[j];
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
this.buttonsVerticalPosition =
|
|
146
|
+
this.field.props['design']['.buttons-container']['align-items'] ==
|
|
147
|
+
'flex-start'
|
|
148
|
+
? 'top'
|
|
149
|
+
: 'bottom';
|
|
150
|
+
}
|
|
151
|
+
this.createFieldGroupButtons();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
get totalStepsCount() {
|
|
155
|
+
return (this.field?.fieldGroup?.filter((step) => step.props?.['fluxType'] !== FluxType.Final).length ?? 0);
|
|
156
|
+
}
|
|
157
|
+
extractFinalStepIfNecessary(fieldConfigs) {
|
|
158
|
+
let filteredConfig = [];
|
|
159
|
+
this.field.fieldGroup?.forEach((f) => {
|
|
160
|
+
if (f.props && f.props['fluxType'] == FluxType.Final) {
|
|
161
|
+
this.finalStepFieldConfig = f;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
filteredConfig.push(f);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
return filteredConfig;
|
|
168
|
+
}
|
|
169
|
+
createFieldGroupButtons() {
|
|
170
|
+
if (this.field.fieldGroup) {
|
|
171
|
+
this.buttonsGroups = [];
|
|
172
|
+
this.field.fieldGroup.forEach((fg, i) => {
|
|
173
|
+
const isLast = i === this.field.fieldGroup.length - 1;
|
|
174
|
+
let btnDisabled = false;
|
|
175
|
+
if (fg.props) {
|
|
176
|
+
const fluxType = fg.props['fluxType'];
|
|
177
|
+
if (fluxType === FluxType.Kyc ||
|
|
178
|
+
fluxType === FluxType.GenerateDocument ||
|
|
179
|
+
fluxType === FluxType.Sign ||
|
|
180
|
+
fluxType === FluxType.Email ||
|
|
181
|
+
fluxType === FluxType.Phone ||
|
|
182
|
+
fluxType === FluxType.OpenBanking) {
|
|
183
|
+
this.buttonsGroups.push([]);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
btnDisabled =
|
|
187
|
+
fluxType === FluxType.Kyc ||
|
|
188
|
+
fluxType === FluxType.Phone ||
|
|
189
|
+
fluxType === FluxType.Email;
|
|
190
|
+
fg.props['buttonsDisabled'] === true;
|
|
191
|
+
if ((fluxType === FluxType.Kyc ||
|
|
192
|
+
fluxType === FluxType.Phone ||
|
|
193
|
+
fluxType === FluxType.Email) &&
|
|
194
|
+
fg.props['buttonsDisabled'] === false) {
|
|
195
|
+
btnDisabled = false;
|
|
196
|
+
}
|
|
197
|
+
const componentsWithDefaultLabels = this.getComponentsWithDefaultLabels();
|
|
198
|
+
if (componentsWithDefaultLabels[fluxType]) {
|
|
199
|
+
fg.props['label'] = componentsWithDefaultLabels[fluxType];
|
|
200
|
+
fg.props['description'] = '';
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (fg.props?.['fluxType'] === FluxType.ViewOffer ||
|
|
204
|
+
fg.props?.['fluxType'] === FluxType.Pause) {
|
|
205
|
+
//12=list offers
|
|
206
|
+
this.buttonsGroups.push([]);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
const btns = this.createButtons(fg, i, isLast, btnDisabled);
|
|
210
|
+
if (this.props['demoMode'] === true) {
|
|
211
|
+
btns.forEach((b) => {
|
|
212
|
+
if (b.type === 'submit') {
|
|
213
|
+
btns.splice(btns.indexOf(b), 1);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
if (this.props['noButtonsInView'] === true) {
|
|
218
|
+
btns.splice(0, btns.length);
|
|
219
|
+
}
|
|
220
|
+
this.buttonsGroups.push(btns);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async createAppData(props) {
|
|
226
|
+
const appDataId = props['appDataId'];
|
|
227
|
+
const applicationId = props['applicationId'] || 0;
|
|
228
|
+
const currentStepId = props.metaData?.currentStepId || props.flux[0]?.identifier;
|
|
229
|
+
if (props['hasDictionaryDependentSteps']) {
|
|
230
|
+
await timer(150).toPromise();
|
|
231
|
+
}
|
|
232
|
+
const stepIndex = this.field.fieldGroup?.findIndex((s) => s.props?.['stepId'] === currentStepId) || 0;
|
|
233
|
+
this.isDisplayMode = props['isDisplayMode'] || false;
|
|
234
|
+
this.currentStepIndex =
|
|
235
|
+
stepIndex >= 0 && !this.isDisplayMode ? stepIndex : 0;
|
|
236
|
+
const statusId = props['statusId'] || '';
|
|
237
|
+
const defaultLanguage = props['defaultLanguage'];
|
|
238
|
+
const flux = (props['flux'] || []).map((step) => new AppDataStep(step.identifier, step.type, (step.sections || []).map((section) => new AppDataSection(section.identifier, (section.controls || []).map((control) => new AppDataControl(control.identifier, control.fillValue || ''))))));
|
|
239
|
+
const offerId = props?.fillData?.metadata?.offerId || '';
|
|
240
|
+
const isSubmitted = props?.fillData?.metadata?.isSubmitted || false;
|
|
241
|
+
const fillData = new AppDataFill(appDataId, applicationId, currentStepId, statusId, defaultLanguage, flux, offerId, isSubmitted);
|
|
242
|
+
this.appData = new AppData({
|
|
243
|
+
appDataId: appDataId,
|
|
244
|
+
appConfigurationId: applicationId,
|
|
245
|
+
fillData: fillData,
|
|
246
|
+
withNextStep: false,
|
|
247
|
+
blockPreviousStep: props['blockPreviousStep'] ?? false,
|
|
248
|
+
env: props['env'],
|
|
249
|
+
});
|
|
250
|
+
if (!this.isDisplayMode && !props['fillData']) {
|
|
251
|
+
await this.saveAppData();
|
|
252
|
+
this.collectorForm.fillData = fillData;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
async saveAppData() {
|
|
256
|
+
if (this.isDisplayMode || this.props['demoMode'] === true) {
|
|
257
|
+
console.log('[Demo Mode] Skipping saveAppData request.');
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
this.isSaving = true;
|
|
261
|
+
try {
|
|
262
|
+
const data = await firstValueFrom(this.applicationDataService.saveApp(this.appData).pipe(catchError((error) => {
|
|
263
|
+
console.error('Error creating AppData', error);
|
|
264
|
+
return of(null);
|
|
265
|
+
})));
|
|
266
|
+
if (data) {
|
|
267
|
+
this.appData.fillData = JSON.parse(data.fillData);
|
|
268
|
+
this.appData.blockPreviousStep = data.blockPreviousStep;
|
|
269
|
+
this.collectorForm.formlyConfigUpdated.emit();
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
console.error('Error occurred during saveStep', error);
|
|
274
|
+
}
|
|
275
|
+
finally {
|
|
276
|
+
this.isSaving = false;
|
|
277
|
+
this.cdr.detectChanges();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
async getPreviousStep() {
|
|
281
|
+
if (this.isDisplayMode || this.props['demoMode'] === true) {
|
|
282
|
+
console.log('[Demo Mode] Skipping getPreviousStep request.');
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
await firstValueFrom(this.applicationDataService.getPreviousStep(this.appData.appDataId).pipe(catchError((error) => {
|
|
286
|
+
console.error('Error getting the previousStep', error);
|
|
287
|
+
return of(null);
|
|
288
|
+
})))
|
|
289
|
+
.then((data) => {
|
|
290
|
+
if (data) {
|
|
291
|
+
console.log(data);
|
|
292
|
+
this.appData.fillData = JSON.parse(data.fillData);
|
|
293
|
+
this.appData.blockPreviousStep = data.blockPreviousStep;
|
|
294
|
+
this.collectorForm.formlyConfigUpdated.emit();
|
|
295
|
+
}
|
|
296
|
+
return true;
|
|
297
|
+
})
|
|
298
|
+
.catch((error) => {
|
|
299
|
+
console.error('Error occurred during getPreviousStep', error);
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
async saveAppDataStep() {
|
|
303
|
+
if (this.isDisplayMode || this.props['demoMode'] === true) {
|
|
304
|
+
console.log('[Demo Mode] Skipping saveAppDataStep request.');
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
// Get the current visible step based on currentStepIndex
|
|
308
|
+
const currentVisibleStep = this.filteredVisibleSteps[this.currentStepIndex];
|
|
309
|
+
if (!currentVisibleStep) {
|
|
310
|
+
console.warn('No current visible step found');
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
// Find the corresponding step in fillData.flux based on the visible step identifier
|
|
314
|
+
let currentStep = this.appData.fillData?.flux.find((s) => s.stepId === currentVisibleStep.identifier);
|
|
315
|
+
// If we can't find it by identifier, create it or update metadata
|
|
316
|
+
if (!currentStep && this.appData.fillData) {
|
|
317
|
+
// Update the currentStepId in metadata to match the current visible step
|
|
318
|
+
this.appData.fillData.metadata.currentStepId =
|
|
319
|
+
currentVisibleStep.identifier;
|
|
320
|
+
// Try to find it again after updating metadata
|
|
321
|
+
currentStep = this.appData.fillData.flux.find((s) => s.stepId === currentVisibleStep.identifier);
|
|
322
|
+
}
|
|
323
|
+
console.log('Saving step data for step:', currentVisibleStep.identifier, 'Step data:', currentStep);
|
|
324
|
+
await firstValueFrom(this.applicationDataService
|
|
325
|
+
.saveStep(this.appData.appDataId, currentStep, this.appData.fillData?.metadata.offerId)
|
|
326
|
+
.pipe(catchError((error) => {
|
|
327
|
+
console.error('Error saving AppData', error);
|
|
328
|
+
return of(null);
|
|
329
|
+
})))
|
|
330
|
+
.then((data) => {
|
|
331
|
+
if (data) {
|
|
332
|
+
this.collectorForm.fillData = this.appData.fillData = JSON.parse(data.fillData);
|
|
333
|
+
this.appData.blockPreviousStep = data.blockPreviousStep;
|
|
334
|
+
this.collectorForm.formlyConfigUpdated.emit();
|
|
335
|
+
}
|
|
336
|
+
// Clear the saving after actions flag
|
|
337
|
+
this.collectorForm.clearSavingAfterActionsState();
|
|
338
|
+
return true;
|
|
339
|
+
})
|
|
340
|
+
.catch((error) => {
|
|
341
|
+
console.error('Error occurred during saveStep', error);
|
|
342
|
+
// Clear the saving after actions flag on error as well
|
|
343
|
+
this.collectorForm.clearSavingAfterActionsState();
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
async updateAppData(saveChanges) {
|
|
347
|
+
const formValues = this.form.value;
|
|
348
|
+
// Get the current visible step to ensure we're updating the right step data
|
|
349
|
+
const currentVisibleStep = this.filteredVisibleSteps[this.currentStepIndex];
|
|
350
|
+
const flux = (this.field?.props?.['flux'] || []).map((step) => new AppDataStep(step.identifier, step.type, (step.sections || []).map((section) => new AppDataSection(section.identifier, (section.controls || [])
|
|
351
|
+
.filter((control) => control.identifier != undefined)
|
|
352
|
+
.map((control) => {
|
|
353
|
+
const value = formValues[control.identifier];
|
|
354
|
+
if (control.type !== StepControlType.Dictionary) {
|
|
355
|
+
let fillValue = '';
|
|
356
|
+
if (value !== null && value !== undefined) {
|
|
357
|
+
if (value instanceof Date) {
|
|
358
|
+
const pad = (n) => n.toString().padStart(2, '0');
|
|
359
|
+
const formatted = `${pad(value.getDate())}.${pad(value.getMonth() + 1)}.${value.getFullYear()}`;
|
|
360
|
+
fillValue = formatted;
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
fillValue =
|
|
364
|
+
typeof value === 'boolean' ? String(value) : value;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return new AppDataControl(control.identifier, fillValue);
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
let fillValueId = '';
|
|
371
|
+
let fillValueName = '';
|
|
372
|
+
if (value !== null && value !== undefined) {
|
|
373
|
+
if (typeof value === 'object' && value.id != null) {
|
|
374
|
+
fillValueId = String(value.id);
|
|
375
|
+
fillValueName = value.name || '';
|
|
376
|
+
}
|
|
377
|
+
else if (typeof value === 'number' ||
|
|
378
|
+
typeof value === 'string') {
|
|
379
|
+
fillValueId = String(value);
|
|
380
|
+
const dictionaryControlData = control.specificControlData;
|
|
381
|
+
if (dictionaryControlData?.dictionaryUUID) {
|
|
382
|
+
const dictionary = this.collectorForm.dictionaryMap.get(dictionaryControlData.dictionaryUUID);
|
|
383
|
+
const selectedOption = dictionary?.values?.find((v) => v.id == value);
|
|
384
|
+
if (selectedOption) {
|
|
385
|
+
fillValueName = selectedOption.name || '';
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
console.warn(`Could not find dictionary value name for ID: ${value} in dictionary ${dictionaryControlData.dictionaryUUID}`);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
console.warn(`Dictionary UUID not found for control: ${control.identifier}`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return new AppDataControl(control.identifier, fillValueName, fillValueId);
|
|
397
|
+
}
|
|
398
|
+
})))));
|
|
399
|
+
if (this.appData.fillData) {
|
|
400
|
+
this.appData.fillData.flux = flux;
|
|
401
|
+
// Ensure the metadata reflects the current visible step
|
|
402
|
+
if (currentVisibleStep) {
|
|
403
|
+
this.appData.fillData.metadata.currentStepId =
|
|
404
|
+
currentVisibleStep.identifier;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (saveChanges) {
|
|
408
|
+
await this.saveAppDataStep();
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
createButtons(step, stepIndex, last, btnDisabled) {
|
|
412
|
+
let buttons = [];
|
|
413
|
+
if (step.props?.['buttons']?.length > 0) {
|
|
414
|
+
buttons = step.props?.['buttons'];
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
buttons = this.getDefaultButtons(stepIndex, last);
|
|
418
|
+
}
|
|
419
|
+
buttons.forEach((b) => this.setupButtonProperties(b, btnDisabled));
|
|
420
|
+
if (this.appData?.fillData?.metadata?.isSubmitted) {
|
|
421
|
+
buttons = [];
|
|
422
|
+
}
|
|
423
|
+
return buttons;
|
|
424
|
+
}
|
|
425
|
+
getDefaultButtons(index, last) {
|
|
426
|
+
const buttons = [];
|
|
427
|
+
if (this.appData?.fillData?.metadata?.isSubmitted === true) {
|
|
428
|
+
return buttons;
|
|
429
|
+
}
|
|
430
|
+
if (this.isDisplayMode) {
|
|
431
|
+
buttons.push({
|
|
432
|
+
type: 'back',
|
|
433
|
+
label: 'Back',
|
|
434
|
+
styleKey: '.button-back',
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
if (index !== 0 && this.appData?.blockPreviousStep === false) {
|
|
439
|
+
buttons.push({
|
|
440
|
+
type: 'back',
|
|
441
|
+
label: 'Back',
|
|
442
|
+
styleKey: '.button-back',
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
if (!last) {
|
|
446
|
+
buttons.push({ type: 'next', label: 'Next', styleKey: '.button-next' });
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
buttons.push({
|
|
450
|
+
type: 'submit',
|
|
451
|
+
label: 'Submit',
|
|
452
|
+
styleKey: '.button-submit',
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return buttons;
|
|
457
|
+
}
|
|
458
|
+
applyProgressBarStyles() {
|
|
459
|
+
const designConfig = this.field.props?.['design'];
|
|
460
|
+
if (designConfig) {
|
|
461
|
+
const progressBarConfig = designConfig['.component-progress-bar'];
|
|
462
|
+
if (progressBarConfig) {
|
|
463
|
+
this.progressBarStyles = {
|
|
464
|
+
backgroundColor: progressBarConfig.backgroundColor || '#ffffff',
|
|
465
|
+
borderColor: progressBarConfig.borderColor || '#000000',
|
|
466
|
+
borderRadius: progressBarConfig.borderRadius || '7px',
|
|
467
|
+
color: progressBarConfig.color || '#000000',
|
|
468
|
+
startColor: progressBarConfig.startColor || '#8884BF',
|
|
469
|
+
endColor: progressBarConfig.endColor || '#8884BF',
|
|
470
|
+
height: progressBarConfig.height || '4px',
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
setupButtonProperties(button, btnDisabled) {
|
|
476
|
+
button.style = this.field.props?.['design'][button.styleKey] || {};
|
|
477
|
+
button.disabled = this.props['demoMode'] === false ? btnDisabled : false;
|
|
478
|
+
}
|
|
479
|
+
async buttonClick(type, step) {
|
|
480
|
+
if (!this.isNavigationInProgress) {
|
|
481
|
+
this.isNavigationInProgress = true;
|
|
482
|
+
await this.navigateAsync(type, step);
|
|
483
|
+
this.isNavigationInProgress = false;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
async navigateNextAsync() {
|
|
487
|
+
const currentStep = this.field?.fieldGroup[this.currentStepIndex];
|
|
488
|
+
if (currentStep) {
|
|
489
|
+
await this.buttonClick('next', currentStep);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
async retryClick(step) {
|
|
493
|
+
if (step?.fieldGroup?.length) {
|
|
494
|
+
this.retryRecursively(step.fieldGroup);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
getProgressBarFill() {
|
|
498
|
+
const start = this.progressBarStyles.startColor || '#8884BF';
|
|
499
|
+
const end = this.progressBarStyles.endColor || '#8884BF';
|
|
500
|
+
return `linear-gradient(to right, ${start}, ${end})`;
|
|
501
|
+
}
|
|
502
|
+
retryRecursively(fieldGroup) {
|
|
503
|
+
if (fieldGroup && fieldGroup.length > 0) {
|
|
504
|
+
fieldGroup.forEach((f) => {
|
|
505
|
+
const component = f.props?.['component'];
|
|
506
|
+
if (component && component.retry) {
|
|
507
|
+
component.retry();
|
|
508
|
+
}
|
|
509
|
+
if (component && component.retryAsync) {
|
|
510
|
+
component.retryAsync();
|
|
511
|
+
}
|
|
512
|
+
this.retryRecursively(f.fieldGroup);
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
async navigateAsync(type, step) {
|
|
517
|
+
this.isNavigating = true;
|
|
518
|
+
const steps = this.field?.fieldGroup || [];
|
|
519
|
+
const currentIndex = steps.indexOf(step);
|
|
520
|
+
if (currentIndex < 0)
|
|
521
|
+
return;
|
|
522
|
+
const prevIndex = currentIndex - 1;
|
|
523
|
+
if ((type === 'next' || type === 'submit') &&
|
|
524
|
+
currentIndex <= steps.length - 1) {
|
|
525
|
+
if (this.props['demoMode'] === false && !this.validateForm(step)) {
|
|
526
|
+
this.isNavigating = false;
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
if (!this.showSteps) {
|
|
530
|
+
const currentFieldGroup = steps[currentIndex]?.fieldGroup;
|
|
531
|
+
const canAdvance = this.canAdvanceRecursively(currentFieldGroup);
|
|
532
|
+
if (!canAdvance) {
|
|
533
|
+
this.isNavigating = false;
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
await this.updateAppData(true);
|
|
537
|
+
const nextIndex = currentIndex + 1;
|
|
538
|
+
const hasActionSteps = await this.field?.props?.['onSelectedPageChanging']({
|
|
539
|
+
from: this.currentStepIndex,
|
|
540
|
+
to: nextIndex,
|
|
541
|
+
current: this.currentStepIndex,
|
|
542
|
+
callback: () => this.checkIfFlowIsFinished(),
|
|
543
|
+
});
|
|
544
|
+
console.log('hasActionSteps', hasActionSteps);
|
|
545
|
+
if (hasActionSteps) {
|
|
546
|
+
await this.updateAppData(true);
|
|
547
|
+
}
|
|
548
|
+
if (!this.isFlowFinished) {
|
|
549
|
+
this.currentStepIndex = nextIndex;
|
|
550
|
+
this.loadedSteps[nextIndex] = true;
|
|
551
|
+
this.field?.props?.['onSelectedPageChanged'](this.currentStepIndex);
|
|
552
|
+
}
|
|
553
|
+
this.cdr.detectChanges();
|
|
554
|
+
await this.triggerOnPageSelectedForIndex(this.currentStepIndex);
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
if (step?.fieldGroup?.length) {
|
|
558
|
+
const canAdvance = this.canAdvanceRecursively(step.fieldGroup);
|
|
559
|
+
if (!canAdvance) {
|
|
560
|
+
this.isNavigating = false;
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
await this.updateAndGoNext();
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
await this.updateAndGoNext();
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
else if (type === 'back' && currentIndex > 0) {
|
|
571
|
+
await this.getPreviousStep();
|
|
572
|
+
if (!this.showSteps) {
|
|
573
|
+
const hasActionSteps = await this.field?.props?.['onSelectedPageChanging']({
|
|
574
|
+
from: this.currentStepIndex,
|
|
575
|
+
to: prevIndex,
|
|
576
|
+
current: this.currentStepIndex,
|
|
577
|
+
});
|
|
578
|
+
if (hasActionSteps) {
|
|
579
|
+
await this.updateAppData(true);
|
|
580
|
+
}
|
|
581
|
+
this.currentStepIndex = prevIndex;
|
|
582
|
+
this.loadedSteps[prevIndex] = true;
|
|
583
|
+
this.cdr.detectChanges();
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
const targetIndex = this.stepper.selectedIndex - 1;
|
|
587
|
+
const hasActionSteps = await this.field?.props?.['onSelectedPageChanging']({
|
|
588
|
+
from: this.stepper.selectedIndex,
|
|
589
|
+
to: targetIndex,
|
|
590
|
+
current: this.stepper.selectedIndex,
|
|
591
|
+
});
|
|
592
|
+
if (hasActionSteps) {
|
|
593
|
+
await this.updateAppData(true);
|
|
594
|
+
}
|
|
595
|
+
this.stepper.previous();
|
|
596
|
+
this.currentStepIndex = this.stepper.selectedIndex;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
this.isNavigating = false;
|
|
600
|
+
this.cdr.detectChanges();
|
|
601
|
+
}
|
|
602
|
+
async updateAndGoNext() {
|
|
603
|
+
await this.updateAppData(true);
|
|
604
|
+
this.goNext();
|
|
605
|
+
}
|
|
606
|
+
async goNext() {
|
|
607
|
+
const currentIdx = this.stepper.selectedIndex;
|
|
608
|
+
const nextIdx = currentIdx + 1;
|
|
609
|
+
const hasActionSteps = await this.field?.props?.['onSelectedPageChanging']({
|
|
610
|
+
from: currentIdx,
|
|
611
|
+
to: nextIdx,
|
|
612
|
+
current: currentIdx,
|
|
613
|
+
callback: () => this.checkIfFlowIsFinished(),
|
|
614
|
+
});
|
|
615
|
+
if (hasActionSteps) {
|
|
616
|
+
await this.updateAppData(true);
|
|
617
|
+
}
|
|
618
|
+
this.stepper.next();
|
|
619
|
+
this.currentStepIndex = this.stepper.selectedIndex;
|
|
620
|
+
this.field?.props?.['onSelectedPageChanged'](this.stepper.selectedIndex);
|
|
621
|
+
this.cdr.detectChanges();
|
|
622
|
+
}
|
|
623
|
+
checkIfFlowIsFinished() {
|
|
624
|
+
if (this.stepper &&
|
|
625
|
+
this.stepper.selectedIndex === this.field?.fieldGroup?.length - 1) {
|
|
626
|
+
this.isFlowFinished = true;
|
|
627
|
+
}
|
|
628
|
+
else if (this.currentStepIndex === this.field?.fieldGroup?.length - 1) {
|
|
629
|
+
this.isFlowFinished = true;
|
|
630
|
+
}
|
|
631
|
+
if (this.isFlowFinished) {
|
|
632
|
+
if (this.finalStepFieldConfig) {
|
|
633
|
+
this.showFinalStep = true;
|
|
634
|
+
}
|
|
635
|
+
this.field?.props?.['completionEvent']();
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
validateForm(step) {
|
|
639
|
+
if (this.props['demoMode'] === true) {
|
|
640
|
+
return true;
|
|
641
|
+
}
|
|
642
|
+
let isValid = true;
|
|
643
|
+
let firstInvalidFieldKey = null;
|
|
644
|
+
if (step.fieldGroup) {
|
|
645
|
+
step.fieldGroup.forEach((f) => {
|
|
646
|
+
if (f.fieldGroup) {
|
|
647
|
+
f.fieldGroup.forEach((c) => {
|
|
648
|
+
c.formControl.markAsTouched();
|
|
649
|
+
c.formControl.updateValueAndValidity();
|
|
650
|
+
if (c.formControl.errors && !c._hide) {
|
|
651
|
+
isValid = false;
|
|
652
|
+
// Find the first invalid field key for scrolling
|
|
653
|
+
if (!firstInvalidFieldKey && c.key) {
|
|
654
|
+
firstInvalidFieldKey = c.key;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
// If validation failed and we have a field to scroll to, use the scroll service
|
|
662
|
+
if (!isValid && firstInvalidFieldKey) {
|
|
663
|
+
this.scrollToErrorService.scrollToField(firstInvalidFieldKey);
|
|
664
|
+
}
|
|
665
|
+
return isValid;
|
|
666
|
+
}
|
|
667
|
+
isValid(field) {
|
|
668
|
+
if (field.key) {
|
|
669
|
+
return field.formControl?.valid ?? false;
|
|
670
|
+
}
|
|
671
|
+
return field.fieldGroup
|
|
672
|
+
? field.fieldGroup.every((f) => this.isValid(f))
|
|
673
|
+
: true;
|
|
674
|
+
}
|
|
675
|
+
isCustomStep(index) {
|
|
676
|
+
const stepType = this.field.fieldGroup[index]?.props?.['fluxType'];
|
|
677
|
+
return stepType === FluxType.Custom;
|
|
678
|
+
}
|
|
679
|
+
async onStepChange(event) {
|
|
680
|
+
if (event && event.selectedIndex) {
|
|
681
|
+
await this.triggerOnPageSelectedForIndex(event.selectedIndex);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
async triggerOnPageSelectedForIndex(index) {
|
|
685
|
+
const fg = this.field.fieldGroup[index]?.fieldGroup;
|
|
686
|
+
this.triggerOnPageSelectedRecursively(fg);
|
|
687
|
+
}
|
|
688
|
+
async triggerOnPageSelectedRecursively(fg) {
|
|
689
|
+
if (fg && fg.length > 0) {
|
|
690
|
+
fg.forEach(async (f) => {
|
|
691
|
+
const component = f.props?.['component'];
|
|
692
|
+
if (component?.onPageSelectedAsync) {
|
|
693
|
+
await component?.onPageSelectedAsync();
|
|
694
|
+
}
|
|
695
|
+
if (component?.onPageSelected) {
|
|
696
|
+
component?.onPageSelected();
|
|
697
|
+
}
|
|
698
|
+
this.triggerOnPageSelectedRecursively(f.fieldGroup);
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
canAdvanceRecursively(fg) {
|
|
703
|
+
let valid = true;
|
|
704
|
+
let firstInvalidFieldKey = null;
|
|
705
|
+
if (fg && fg.length > 0) {
|
|
706
|
+
fg.forEach(async (f) => {
|
|
707
|
+
let innerResult = true;
|
|
708
|
+
const component = f.props?.['component'];
|
|
709
|
+
if (component?.canAdvance) {
|
|
710
|
+
innerResult = component?.canAdvance();
|
|
711
|
+
if (innerResult === false) {
|
|
712
|
+
valid = false;
|
|
713
|
+
// Try to get the field key for scrolling
|
|
714
|
+
if (!firstInvalidFieldKey && f.key) {
|
|
715
|
+
firstInvalidFieldKey = f.key;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
innerResult = this.canAdvanceRecursively(f.fieldGroup);
|
|
720
|
+
if (innerResult === false) {
|
|
721
|
+
valid = false;
|
|
722
|
+
}
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
// If validation failed and we have a field to scroll to, use the scroll service
|
|
726
|
+
if (!valid && firstInvalidFieldKey) {
|
|
727
|
+
this.scrollToErrorService.scrollToField(firstInvalidFieldKey);
|
|
728
|
+
}
|
|
729
|
+
else if (!valid) {
|
|
730
|
+
// Fallback: try to scroll to first error using the collector form's method
|
|
731
|
+
this.collectorForm.scrollToFirstValidationError();
|
|
732
|
+
}
|
|
733
|
+
return valid;
|
|
734
|
+
}
|
|
735
|
+
getComponentsWithDefaultLabels() {
|
|
736
|
+
return {
|
|
737
|
+
[FluxType.Kyc]: 'Kyc',
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFieldStepperComponent, deps: [{ token: i1.ApplicationDataService }, { token: i2.CollectorFormComponent }, { token: i0.ChangeDetectorRef }, { token: i3.ScrollToErrorService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
741
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FormlyFieldStepperComponent, selector: "app-formly-field-stepper", providers: [
|
|
742
|
+
{
|
|
743
|
+
provide: STEPPER_GLOBAL_OPTIONS,
|
|
744
|
+
useValue: { displayDefaultIndicatorType: false },
|
|
745
|
+
},
|
|
746
|
+
ApplicationDataService,
|
|
747
|
+
], viewQueries: [{ propertyName: "stepper", first: true, predicate: MatStepper, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"showSteps; else singleStepTemplate\">\n <div [ngStyle]=\"concatenatedFormStyle\">\n <formly-field\n *ngIf=\"showFinalStep\"\n [field]=\"finalStepFieldConfig\"\n ></formly-field>\n </div>\n\n <mat-horizontal-stepper\n #stepper\n *ngIf=\"!showFinalStep\"\n [linear]=\"true\"\n (selectionChange)=\"onStepChange($event)\"\n [ngStyle]=\"concatenatedFormStyle\"\n >\n <mat-step *ngFor=\"let step of field.fieldGroup; let index = index\">\n <ng-template matStepLabel *ngIf=\"showStepsLabels\">\n {{ step.props?.label }}\n </ng-template>\n\n <ng-container\n *ngIf=\"buttonsVerticalPosition == 'top'\"\n [ngTemplateOutlet]=\"buttonsContainer\"\n />\n\n <h3 [ngStyle]=\"field.props?.['design']['.font-heading-3'] || {}\">\n {{ step.props?.description }}\n </h3>\n <formly-field [field]=\"step\"></formly-field>\n\n <ng-container\n *ngIf=\"buttonsVerticalPosition == 'bottom'\"\n [ngTemplateOutlet]=\"buttonsContainer\"\n />\n </mat-step>\n <!-- <ng-template *ngIf=\"!showStepsCounter\" matStepperIcon=\"number\">\n <mat-icon>radio_button_checked</mat-icon>\n </ng-template> -->\n </mat-horizontal-stepper>\n</div>\n\n<ng-template #singleStepTemplate>\n <div [ngStyle]=\"concatenatedFormStyle\">\n <formly-field\n *ngIf=\"showFinalStep\"\n [field]=\"finalStepFieldConfig\"\n ></formly-field>\n </div>\n <div\n class=\"single-step-container\"\n *ngIf=\"!showFinalStep\"\n [ngStyle]=\"concatenatedFormStyle\"\n >\n <div\n class=\"progress-bar-wrapper\"\n *ngIf=\"showProgressBar\"\n [ngStyle]=\"{\n 'border-radius': progressBarStyles.borderRadius,\n height: progressBarStyles.height,\n overflow: 'hidden'\n }\"\n >\n <div\n class=\"progress-bar-fill\"\n [ngStyle]=\"{\n width: ((currentStepIndex + 1) / totalStepsCount) * 100 + '%',\n background: getProgressBarFill(),\n height: '100%'\n }\"\n ></div>\n </div>\n <div class=\"single-step-header\">\n <div\n class=\"single-step-indicator\"\n *ngIf=\"showStepsCounter;\"\n >\n <span class=\"step-current\">{{ currentStepIndex + 1 }}</span>\n <span class=\"step-separator\">/</span>\n <span class=\"step-total\">{{ totalStepsCount }}</span>\n </div>\n <h1 *ngIf=\"showStepsLabels\" class=\"single-step-label\" [ngStyle]=\"field.props?.['design']['.font-heading-1'] || {}\">\n {{ field.fieldGroup![currentStepIndex]!.props!.label }}\n </h1>\n </div>\n\n <ng-container\n *ngIf=\"buttonsVerticalPosition == 'top'\"\n [ngTemplateOutlet]=\"buttonsContainer\"\n />\n\n <h3 [ngStyle]=\"field.props?.['design']['.font-heading-3'] || {}\">\n {{ field!.fieldGroup![currentStepIndex]!.props!.description }}\n </h3>\n <formly-field\n *ngIf=\"loadedSteps[currentStepIndex]\"\n [field]=\"field!.fieldGroup![currentStepIndex]\"\n ></formly-field>\n\n <ng-container\n *ngIf=\"buttonsVerticalPosition == 'bottom'\"\n [ngTemplateOutlet]=\"buttonsContainer\"\n />\n </div>\n</ng-template>\n\n<ng-template #buttonsContainer>\n <ng-container\n *ngTemplateOutlet=\"\n buttonsTemplate;\n context: {\n index: currentStepIndex,\n step: field!.fieldGroup![currentStepIndex]\n }\n \"\n ></ng-container>\n</ng-template>\n\n<ng-template #buttonsTemplate let-index=\"index\" let-step=\"step\">\n <div\n *ngIf=\"!isFlowFinished\"\n class=\"buttons-container\"\n [ngStyle]=\"field.props?.['design']['.buttons-container'] || {}\"\n >\n <button mat-flat-button *ngIf=\"isDebug\" (click)=\"retryClick(step)\">\n Debug Retry\n </button>\n <ng-container *ngFor=\"let button of buttonsGroups[index]\">\n <button\n mat-flat-button\n [color]=\"button.color || 'primary'\"\n [type]=\"button.type === 'submit' ? 'submit' : 'button'\"\n (click)=\"buttonClick(button.type, step)\"\n [disabled]=\"button.disabled || isSaving\"\n [ngStyle]=\"button.style\"\n >\n {{ button.label }}\n </button>\n </ng-container>\n <div *ngIf=\"isNavigating || isSaving\" class=\"loading-spinner\">\n <mat-spinner [diameter]=\"32\"></mat-spinner>\n </div>\n <button mat-flat-button *ngIf=\"isDebug\" (click)=\"buttonClick('next', step)\">\n Debug Next\n </button>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";.buttons-container button{margin-right:5px}::ng-deep .mat-horizontal-stepper-header{pointer-events:none!important}.single-step-container{overflow:hidden;padding:0 24px 24px}.single-step-indicator{color:#000;display:flex;align-items:center;justify-content:center;margin-right:1%;font-weight:600}.step-current{font-size:1rem}.step-separator{font-size:.8rem;opacity:.8;margin:0 2px}.step-total{font-size:.9rem;opacity:.8}.single-step-icon{font-size:1.5rem;color:#6b7de1;opacity:.7;transition:opacity .2s ease}.single-step-icon:hover{opacity:1}.single-step-header{position:relative;display:flex;align-items:center;justify-content:center;gap:.5rem;padding-bottom:.75rem}.single-step-header:after{content:\"\";position:absolute;bottom:0;left:50%;transform:translate(-50%);width:var(--progress-percent, 0);height:4px;border-radius:2px;background:linear-gradient(135deg,#6b7de1,#9fa8f5);transition:width .3s ease}.single-step-header{display:flex;align-items:center;justify-content:center}.single-step-label{width:auto!important}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i5.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i5.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i5.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i8.FormlyField, selector: "formly-field", inputs: ["field"] }] }); }
|
|
748
|
+
}
|
|
749
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormlyFieldStepperComponent, decorators: [{
|
|
750
|
+
type: Component,
|
|
751
|
+
args: [{ selector: 'app-formly-field-stepper', providers: [
|
|
752
|
+
{
|
|
753
|
+
provide: STEPPER_GLOBAL_OPTIONS,
|
|
754
|
+
useValue: { displayDefaultIndicatorType: false },
|
|
755
|
+
},
|
|
756
|
+
ApplicationDataService,
|
|
757
|
+
], template: "<div *ngIf=\"showSteps; else singleStepTemplate\">\n <div [ngStyle]=\"concatenatedFormStyle\">\n <formly-field\n *ngIf=\"showFinalStep\"\n [field]=\"finalStepFieldConfig\"\n ></formly-field>\n </div>\n\n <mat-horizontal-stepper\n #stepper\n *ngIf=\"!showFinalStep\"\n [linear]=\"true\"\n (selectionChange)=\"onStepChange($event)\"\n [ngStyle]=\"concatenatedFormStyle\"\n >\n <mat-step *ngFor=\"let step of field.fieldGroup; let index = index\">\n <ng-template matStepLabel *ngIf=\"showStepsLabels\">\n {{ step.props?.label }}\n </ng-template>\n\n <ng-container\n *ngIf=\"buttonsVerticalPosition == 'top'\"\n [ngTemplateOutlet]=\"buttonsContainer\"\n />\n\n <h3 [ngStyle]=\"field.props?.['design']['.font-heading-3'] || {}\">\n {{ step.props?.description }}\n </h3>\n <formly-field [field]=\"step\"></formly-field>\n\n <ng-container\n *ngIf=\"buttonsVerticalPosition == 'bottom'\"\n [ngTemplateOutlet]=\"buttonsContainer\"\n />\n </mat-step>\n <!-- <ng-template *ngIf=\"!showStepsCounter\" matStepperIcon=\"number\">\n <mat-icon>radio_button_checked</mat-icon>\n </ng-template> -->\n </mat-horizontal-stepper>\n</div>\n\n<ng-template #singleStepTemplate>\n <div [ngStyle]=\"concatenatedFormStyle\">\n <formly-field\n *ngIf=\"showFinalStep\"\n [field]=\"finalStepFieldConfig\"\n ></formly-field>\n </div>\n <div\n class=\"single-step-container\"\n *ngIf=\"!showFinalStep\"\n [ngStyle]=\"concatenatedFormStyle\"\n >\n <div\n class=\"progress-bar-wrapper\"\n *ngIf=\"showProgressBar\"\n [ngStyle]=\"{\n 'border-radius': progressBarStyles.borderRadius,\n height: progressBarStyles.height,\n overflow: 'hidden'\n }\"\n >\n <div\n class=\"progress-bar-fill\"\n [ngStyle]=\"{\n width: ((currentStepIndex + 1) / totalStepsCount) * 100 + '%',\n background: getProgressBarFill(),\n height: '100%'\n }\"\n ></div>\n </div>\n <div class=\"single-step-header\">\n <div\n class=\"single-step-indicator\"\n *ngIf=\"showStepsCounter;\"\n >\n <span class=\"step-current\">{{ currentStepIndex + 1 }}</span>\n <span class=\"step-separator\">/</span>\n <span class=\"step-total\">{{ totalStepsCount }}</span>\n </div>\n <h1 *ngIf=\"showStepsLabels\" class=\"single-step-label\" [ngStyle]=\"field.props?.['design']['.font-heading-1'] || {}\">\n {{ field.fieldGroup![currentStepIndex]!.props!.label }}\n </h1>\n </div>\n\n <ng-container\n *ngIf=\"buttonsVerticalPosition == 'top'\"\n [ngTemplateOutlet]=\"buttonsContainer\"\n />\n\n <h3 [ngStyle]=\"field.props?.['design']['.font-heading-3'] || {}\">\n {{ field!.fieldGroup![currentStepIndex]!.props!.description }}\n </h3>\n <formly-field\n *ngIf=\"loadedSteps[currentStepIndex]\"\n [field]=\"field!.fieldGroup![currentStepIndex]\"\n ></formly-field>\n\n <ng-container\n *ngIf=\"buttonsVerticalPosition == 'bottom'\"\n [ngTemplateOutlet]=\"buttonsContainer\"\n />\n </div>\n</ng-template>\n\n<ng-template #buttonsContainer>\n <ng-container\n *ngTemplateOutlet=\"\n buttonsTemplate;\n context: {\n index: currentStepIndex,\n step: field!.fieldGroup![currentStepIndex]\n }\n \"\n ></ng-container>\n</ng-template>\n\n<ng-template #buttonsTemplate let-index=\"index\" let-step=\"step\">\n <div\n *ngIf=\"!isFlowFinished\"\n class=\"buttons-container\"\n [ngStyle]=\"field.props?.['design']['.buttons-container'] || {}\"\n >\n <button mat-flat-button *ngIf=\"isDebug\" (click)=\"retryClick(step)\">\n Debug Retry\n </button>\n <ng-container *ngFor=\"let button of buttonsGroups[index]\">\n <button\n mat-flat-button\n [color]=\"button.color || 'primary'\"\n [type]=\"button.type === 'submit' ? 'submit' : 'button'\"\n (click)=\"buttonClick(button.type, step)\"\n [disabled]=\"button.disabled || isSaving\"\n [ngStyle]=\"button.style\"\n >\n {{ button.label }}\n </button>\n </ng-container>\n <div *ngIf=\"isNavigating || isSaving\" class=\"loading-spinner\">\n <mat-spinner [diameter]=\"32\"></mat-spinner>\n </div>\n <button mat-flat-button *ngIf=\"isDebug\" (click)=\"buttonClick('next', step)\">\n Debug Next\n </button>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";.buttons-container button{margin-right:5px}::ng-deep .mat-horizontal-stepper-header{pointer-events:none!important}.single-step-container{overflow:hidden;padding:0 24px 24px}.single-step-indicator{color:#000;display:flex;align-items:center;justify-content:center;margin-right:1%;font-weight:600}.step-current{font-size:1rem}.step-separator{font-size:.8rem;opacity:.8;margin:0 2px}.step-total{font-size:.9rem;opacity:.8}.single-step-icon{font-size:1.5rem;color:#6b7de1;opacity:.7;transition:opacity .2s ease}.single-step-icon:hover{opacity:1}.single-step-header{position:relative;display:flex;align-items:center;justify-content:center;gap:.5rem;padding-bottom:.75rem}.single-step-header:after{content:\"\";position:absolute;bottom:0;left:50%;transform:translate(-50%);width:var(--progress-percent, 0);height:4px;border-radius:2px;background:linear-gradient(135deg,#6b7de1,#9fa8f5);transition:width .3s ease}.single-step-header{display:flex;align-items:center;justify-content:center}.single-step-label{width:auto!important}\n"] }]
|
|
758
|
+
}], ctorParameters: () => [{ type: i1.ApplicationDataService }, { type: i2.CollectorFormComponent }, { type: i0.ChangeDetectorRef }, { type: i3.ScrollToErrorService }], propDecorators: { stepper: [{
|
|
759
|
+
type: ViewChild,
|
|
760
|
+
args: [MatStepper]
|
|
761
|
+
}] } });
|
|
762
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybWx5LWZpZWxkLXN0ZXBwZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb3JpZ2luLWZvcm0vc3JjL2xpYi9mb3JtbHkvZm9ybWx5LWZpZWxkLXN0ZXBwZXIvZm9ybWx5LWZpZWxkLXN0ZXBwZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb3JpZ2luLWZvcm0vc3JjL2xpYi9mb3JtbHkvZm9ybWx5LWZpZWxkLXN0ZXBwZXIvZm9ybWx5LWZpZWxkLXN0ZXBwZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDOUQsT0FBTyxFQUVMLFNBQVMsRUFHVCxTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxTQUFTLEVBQXFCLE1BQU0sa0JBQWtCLENBQUM7QUFDaEUsT0FBTyxFQUFnQixLQUFLLEVBQUUsY0FBYyxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0UsT0FBTyxFQUNMLE9BQU8sRUFDUCxRQUFRLEVBQ1IsV0FBVyxFQUNYLGNBQWMsRUFDZCxjQUFjLEVBQ2QsV0FBVyxFQUNYLGVBQWUsR0FFaEIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQzs7Ozs7Ozs7OztBQWdCaEYsTUFBTSxPQUFPLDJCQUNYLFNBQVEsU0FBUztJQStCakIsWUFDVSxzQkFBOEMsRUFDOUMsYUFBcUMsRUFDckMsR0FBc0IsRUFDdEIsb0JBQTBDO1FBRWxELEtBQUssRUFBRSxDQUFDO1FBTEEsMkJBQXNCLEdBQXRCLHNCQUFzQixDQUF3QjtRQUM5QyxrQkFBYSxHQUFiLGFBQWEsQ0FBd0I7UUFDckMsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFDdEIseUJBQW9CLEdBQXBCLG9CQUFvQixDQUFzQjtRQWhDcEQsa0JBQWEsR0FBWSxFQUFFLENBQUM7UUFDNUIsY0FBUyxHQUFZLElBQUksQ0FBQztRQUMxQixvQkFBZSxHQUFZLElBQUksQ0FBQztRQUNoQyxxQkFBZ0IsR0FBWSxJQUFJLENBQUM7UUFHakMsa0JBQWEsR0FBWSxLQUFLLENBQUM7UUFDL0IsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFFaEMsa0JBQWEsR0FBWSxLQUFLLENBQUM7UUFDL0IsWUFBTyxHQUFZLEtBQUssQ0FBQztRQUN6QiwyQkFBc0IsR0FBWSxLQUFLLENBQUM7UUFDeEMsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUMxQixxQkFBZ0IsR0FBVyxDQUFDLENBQUM7UUFDN0IsZ0JBQVcsR0FBYyxFQUFFLENBQUM7UUFLNUIsMEJBQXFCLEdBQVEsRUFBRSxDQUFDO1FBQ2hDLDRCQUF1QixHQUFXLFFBQVEsQ0FBQztRQUUzQyxpQkFBWSxHQUFZLEtBQUssQ0FBQztRQUc5Qix5QkFBb0IsR0FBVSxFQUFFLENBQUM7UUFDakMsc0JBQWlCLEdBQVEsRUFBRSxDQUFDO0lBUzVCLENBQUM7SUFFRCxLQUFLLENBQUMsUUFBUTtRQUNaLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQy9CLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyx3QkFBd0I7WUFDM0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO2dCQUNwRCxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztvQkFDeEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUN0RCxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FDdEIsQ0FBQztnQkFDSixDQUFDO2dCQUNELElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1lBQ2pDLENBQUMsQ0FBQyxDQUFDO1FBRUwsSUFBSSxDQUFDLGdDQUFnQztZQUNuQyxJQUFJLENBQUMsYUFBYSxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxFQUFFO2dCQUNsRSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsYUFBYSxDQUFDO1lBQzVDLENBQUMsQ0FBQyxDQUFDO1FBRUwsSUFBSSxDQUFDLDJCQUEyQjtZQUM5QixJQUFJLENBQUMsYUFBYSxDQUFDLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQzdELElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxlQUFlLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsQ0FBQztvQkFDckQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsZUFBZSxDQUFDO2dCQUM3RCxDQUFDO2dCQUNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUMzRCxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3pDLENBQUMsQ0FBQyxDQUFDO1FBRUwsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ3hFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNoQixDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRCxLQUFLLENBQUMsV0FBVyxDQUFDLE9BQVk7UUFDNUIsSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbEIsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGVBQWU7UUFDbkIsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0MsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ2xELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1lBQzFCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFDaEMsQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztZQUM1QixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7WUFDbkQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDNUMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUMvQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztZQUM1QixDQUFDO1lBQ0QsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDZCxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7WUFDN0IsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDOUQsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ25FLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQy9DLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDM0IsQ0FBQztRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNsRCxJQUFJLENBQUMsNkJBQTZCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDNUQsQ0FBQztJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDOUMsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLDJCQUEyQixFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2pELENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN4QyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsZ0NBQWdDLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsZ0NBQWdDLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDdEQsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsUUFBUTtRQUNaLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUMxQixJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsMkJBQTJCLENBQ3RELElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUN0QixDQUFDO2dCQUNGLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDbkUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDakQsQ0FBQztZQUNELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDckIsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUM3RCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUMzQyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztnQkFDdkQsSUFBSSxZQUFZLEVBQUUsQ0FBQztvQkFDakIsSUFBSSxDQUFDLFNBQVMsR0FBRyxZQUFZLENBQUMsWUFBWSxDQUFDO29CQUMzQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsWUFBWSxDQUFDLFdBQVcsQ0FBQztvQkFDakQsSUFBSSxDQUFDLGVBQWUsR0FBRyxZQUFZLENBQUMsVUFBVSxDQUFDO29CQUMvQyxJQUFJLENBQUMsZUFBZSxHQUFHLFlBQVksQ0FBQyxlQUFlLENBQUM7Z0JBQ3RELENBQUM7Z0JBQ0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQ3RELElBQUksWUFBWSxFQUFFLENBQUM7b0JBQ2pCLElBQUksQ0FBQyxnQkFBZ0I7d0JBQ25CLFlBQVksQ0FBQyx1QkFBdUIsS0FBSyxLQUFLLENBQUM7Z0JBQ25ELENBQUM7Z0JBRUQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztxQkFDdkMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO3FCQUN2QyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtvQkFDYixNQUFNLElBQUksR0FBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3ZCLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7d0JBQzlCLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQzFDLENBQUMsQ0FBQyxDQUFDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO2dCQUVMLElBQUksQ0FBQyx1QkFBdUI7b0JBQzFCLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUMsYUFBYSxDQUFDO3dCQUM3RCxZQUFZO3dCQUNaLENBQUMsQ0FBQyxLQUFLO3dCQUNQLENBQUMsQ0FBQyxRQUFRLENBQUM7WUFDakIsQ0FBQztZQUNELElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQ2pDLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxlQUFlO1FBQ2pCLE9BQU8sQ0FDTCxJQUFJLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQzVCLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsVUFBVSxDQUFDLEtBQUssUUFBUSxDQUFDLEtBQUssQ0FDdEQsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUNkLENBQUM7SUFDSixDQUFDO0lBRUQsMkJBQTJCLENBQ3pCLFlBQWlDO1FBRWpDLElBQUksY0FBYyxHQUF3QixFQUFFLENBQUM7UUFDN0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDbkMsSUFBSSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNyRCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO1lBQ2hDLENBQUM7aUJBQU0sQ0FBQztnQkFDTixjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pCLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUM7SUFFRCx1QkFBdUI7UUFDckIsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDdEMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0JBRXZELElBQUksV0FBVyxHQUFHLEtBQUssQ0FBQztnQkFDeEIsSUFBSSxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ2IsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDdEMsSUFDRSxRQUFRLEtBQUssUUFBUSxDQUFDLEdBQUc7d0JBQ3pCLFFBQVEsS0FBSyxRQUFRLENBQUMsZ0JBQWdCO3dCQUN0QyxRQUFRLEtBQUssUUFBUSxDQUFDLElBQUk7d0JBQzFCLFFBQVEsS0FBSyxRQUFRLENBQUMsS0FBSzt3QkFDM0IsUUFBUSxLQUFLLFFBQVEsQ0FBQyxLQUFLO3dCQUMzQixRQUFRLEtBQUssUUFBUSxDQUFDLFdBQVcsRUFDakMsQ0FBQzt3QkFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQzt3QkFDNUIsT0FBTztvQkFDVCxDQUFDO29CQUVELFdBQVc7d0JBQ1QsUUFBUSxLQUFLLFFBQVEsQ0FBQyxHQUFHOzRCQUN6QixRQUFRLEtBQUssUUFBUSxDQUFDLEtBQUs7NEJBQzNCLFFBQVEsS0FBSyxRQUFRLENBQUMsS0FBSyxDQUFDO29CQUM5QixFQUFFLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEtBQUssSUFBSSxDQUFDO29CQUNyQyxJQUNFLENBQUMsUUFBUSxLQUFLLFFBQVEsQ0FBQyxHQUFHO3dCQUN4QixRQUFRLEtBQUssUUFBUSxDQUFDLEtBQUs7d0JBQzNCLFFBQVEsS0FBSyxRQUFRLENBQUMsS0FBSyxDQUFDO3dCQUM5QixFQUFFLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEtBQUssS0FBSyxFQUNyQyxDQUFDO3dCQUNELFdBQVcsR0FBRyxLQUFLLENBQUM7b0JBQ3RCLENBQUM7b0JBRUQsTUFBTSwyQkFBMkIsR0FDL0IsSUFBSSxDQUFDLDhCQUE4QixFQUFFLENBQUM7b0JBQ3hDLElBQUksMkJBQTJCLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQzt3QkFDMUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRywyQkFBMkIsQ0FBQyxRQUFRLENBQUMsQ0FBQzt3QkFDMUQsRUFBRSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLENBQUM7b0JBQy9CLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxJQUNFLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxVQUFVLENBQUMsS0FBSyxRQUFRLENBQUMsU0FBUztvQkFDN0MsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDLFVBQVUsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxLQUFLLEVBQ3pDLENBQUM7b0JBQ0QsZ0JBQWdCO29CQUNoQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDOUIsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7b0JBQzVELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQzt3QkFDcEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQW1CLEVBQUUsRUFBRTs0QkFDbkMsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO2dDQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7NEJBQ2xDLENBQUM7d0JBQ0gsQ0FBQyxDQUFDLENBQUM7b0JBQ0wsQ0FBQztvQkFDRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQzt3QkFDM0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUM5QixDQUFDO29CQUNELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNoQyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBVTtRQUM1QixNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDckMsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsRCxNQUFNLGFBQWEsR0FDakIsS0FBSyxDQUFDLFFBQVEsRUFBRSxhQUFhLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUM7UUFFN0QsSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsRUFBRSxDQUFDO1lBQ3pDLE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQy9CLENBQUM7UUFFRCxNQUFNLFNBQVMsR0FDYixJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQzlCLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssYUFBYSxDQUM3QyxJQUFJLENBQUMsQ0FBQztRQUNULElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxJQUFJLEtBQUssQ0FBQztRQUVyRCxJQUFJLENBQUMsZ0JBQWdCO1lBQ25CLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV4RCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3pDLE1BQU0sZUFBZSxHQUFHLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBRWpELE1BQU0sSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FDcEMsQ0FBQyxJQUFTLEVBQUUsRUFBRSxDQUNaLElBQUksV0FBVyxDQUNiLElBQUksQ0FBQyxVQUFVLEVBQ2YsSUFBSSxDQUFDLElBQUksRUFDVCxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUN2QixDQUFDLE9BQVksRUFBRSxFQUFFLENBQ2YsSUFBSSxjQUFjLENBQ2hCLE9BQU8sQ0FBQyxVQUFVLEVBQ2xCLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQzFCLENBQUMsT0FBWSxFQUFFLEVBQUUsQ0FDZixJQUFJLGNBQWMsQ0FDaEIsT0FBTyxDQUFDLFVBQVUsRUFDbEIsT0FBTyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQ3hCLENBQ0osQ0FDRixDQUNKLENBQ0YsQ0FDSixDQUFDO1FBQ0YsTUFBTSxPQUFPLEdBQUcsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUN6RCxNQUFNLFdBQVcsR0FBRyxLQUFLLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxXQUFXLElBQUksS0FBSyxDQUFDO1FBRXBFLE1BQU0sUUFBUSxHQUFHLElBQUksV0FBVyxDQUM5QixTQUFTLEVBQ1QsYUFBYSxFQUNiLGFBQWEsRUFDYixRQUFRLEVBQ1IsZUFBZSxFQUNmLElBQUksRUFDSixPQUFPLEVBQ1AsV0FBVyxDQUNaLENBQUM7UUFFRixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDO1lBQ3pCLFNBQVMsRUFBRSxTQUFTO1lBQ3BCLGtCQUFrQixFQUFFLGFBQWE7WUFDakMsUUFBUSxFQUFFLFFBQVE7WUFDbEIsWUFBWSxFQUFFLEtBQUs7WUFDbkIsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLG1CQUFtQixDQUFDLElBQUksS0FBSztZQUN0RCxHQUFHLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQztTQUNsQixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQzlDLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QyxDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxXQUFXO1FBQ2YsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDMUQsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO1lBQ3pELE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDckIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLEdBQUcsTUFBTSxjQUFjLENBQy9CLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FDcEQsVUFBVSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQ25CLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0JBQXdCLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQy9DLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xCLENBQUMsQ0FBQyxDQUNILENBQ0YsQ0FBQztZQUNGLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ1QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2xELElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDO2dCQUN4RCxJQUFJLENBQUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2hELENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekQsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7WUFDdEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxlQUFlO1FBQ25CLElBQUksSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQzFELE9BQU8sQ0FBQyxHQUFHLENBQUMsK0NBQStDLENBQUMsQ0FBQztZQUM3RCxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sY0FBYyxDQUNsQixJQUFJLENBQUMsc0JBQXNCLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUN0RSxVQUFVLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3ZELE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xCLENBQUMsQ0FBQyxDQUNILENBQ0Y7YUFDRSxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNiLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ1QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDbEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2xELElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDO2dCQUN4RCxJQUFJLENBQUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2hELENBQUM7WUFDRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUMsQ0FBQzthQUNELEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyx1Q0FBdUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNoRSxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxLQUFLLENBQUMsZUFBZTtRQUNuQixJQUFJLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUMxRCxPQUFPLENBQUMsR0FBRyxDQUFDLCtDQUErQyxDQUFDLENBQUM7WUFDN0QsT0FBTztRQUNULENBQUM7UUFFRCx5REFBeUQ7UUFFekQsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFNUUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDeEIsT0FBTyxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1lBQzlDLE9BQU87UUFDVCxDQUFDO1FBRUQsb0ZBQW9GO1FBQ3BGLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQ2hELENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxLQUFLLGtCQUFrQixDQUFDLFVBQVUsQ0FDbEQsQ0FBQztRQUVGLGtFQUFrRTtRQUNsRSxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDMUMseUVBQXlFO1lBQ3pFLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxhQUFhO2dCQUMxQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUM7WUFFaEMsK0NBQStDO1lBQy9DLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUMzQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxrQkFBa0IsQ0FBQyxVQUFVLENBQ2xELENBQUM7UUFDSixDQUFDO1FBRUQsT0FBTyxDQUFDLEdBQUcsQ0FDVCw0QkFBNEIsRUFDNUIsa0JBQWtCLENBQUMsVUFBVSxFQUM3QixZQUFZLEVBQ1osV0FBVyxDQUNaLENBQUM7UUFFRixNQUFNLGNBQWMsQ0FDbEIsSUFBSSxDQUFDLHNCQUFzQjthQUN4QixRQUFRLENBQ1AsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQ3RCLFdBQVcsRUFDWCxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsT0FBTyxDQUN4QzthQUNBLElBQUksQ0FDSCxVQUFVLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzdDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xCLENBQUMsQ0FBQyxDQUNILENBQ0o7YUFDRSxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNiLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ1QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FDOUQsSUFBSSxDQUFDLFFBQVEsQ0FDZCxDQUFDO2dCQUNGLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDO2dCQUN4RCxJQUFJLENBQUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2hELENBQUM7WUFDRCxzQ0FBc0M7WUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyw0QkFBNEIsRUFBRSxDQUFDO1lBQ2xELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQyxDQUFDO2FBQ0QsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3ZELHVEQUF1RDtZQUN2RCxJQUFJLENBQUMsYUFBYSxDQUFDLDRCQUE0QixFQUFFLENBQUM7UUFDcEQsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWEsQ0FBQyxXQUFvQjtRQUN0QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUVuQyw0RUFBNEU7UUFDNUUsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFNUUsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FDbEQsQ0FBQyxJQUFTLEVBQUUsRUFBRSxDQUNaLElBQUksV0FBVyxDQUNiLElBQUksQ0FBQyxVQUFVLEVBQ2YsSUFBSSxDQUFDLElBQUksRUFDVCxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUN2QixDQUFDLE9BQVksRUFBRSxFQUFFLENBQ2YsSUFBSSxjQUFjLENBQ2hCLE9BQU8sQ0FBQyxVQUFVLEVBQ2xCLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7YUFDckIsTUFBTSxDQUFDLENBQUMsT0FBWSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBVSxJQUFJLFNBQVMsQ0FBQzthQUN6RCxHQUFHLENBQUMsQ0FBQyxPQUFZLEVBQUUsRUFBRTtZQUNwQixNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzdDLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxlQUFlLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ2hELElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQztnQkFDbkIsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDMUMsSUFBSSxLQUFLLFlBQVksSUFBSSxFQUFFLENBQUM7d0JBQzFCLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FDeEIsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7d0JBQ2hDLE1BQU0sU0FBUyxHQUFHLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLEdBQUcsQ0FDOUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FDckIsSUFBSSxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQzt3QkFDM0IsU0FBUyxHQUFHLFNBQVMsQ0FBQztvQkFDeEIsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLFNBQVM7NEJBQ1AsT0FBTyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztvQkFDdkQsQ0FBQztnQkFDSCxDQUFDO2dCQUNELE9BQU8sSUFBSSxjQUFjLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUMzRCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxXQUFXLEdBQUcsRUFBRSxDQUFDO2dCQUNyQixJQUFJLGFBQWEsR0FBRyxFQUFFLENBQUM7Z0JBRXZCLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQzFDLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxFQUFFLElBQUksSUFBSSxFQUFFLENBQUM7d0JBQ2xELFdBQVcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO3dCQUMvQixhQUFhLEdBQUcsS0FBSyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7b0JBQ25DLENBQUM7eUJBQU0sSUFDTCxPQUFPLEtBQUssS0FBSyxRQUFRO3dCQUN6QixPQUFPLEtBQUssS0FBSyxRQUFRLEVBQ3pCLENBQUM7d0JBQ0QsV0FBVyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDNUIsTUFBTSxxQkFBcUIsR0FDekIsT0FBTyxDQUFDLG1CQUE0QyxDQUFDO3dCQUN2RCxJQUFJLHFCQUFxQixFQUFFLGNBQWMsRUFBRSxDQUFDOzRCQUMxQyxNQUFNLFVBQVUsR0FDZCxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQ2xDLHFCQUFxQixDQUFDLGNBQWMsQ0FDckMsQ0FBQzs0QkFDSixNQUFNLGNBQWMsR0FBRyxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FDN0MsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksS0FBSyxDQUNyQixDQUFDOzRCQUNGLElBQUksY0FBYyxFQUFFLENBQUM7Z0NBQ25CLGFBQWEsR0FBRyxjQUFjLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQzs0QkFDNUMsQ0FBQztpQ0FBTSxDQUFDO2dDQUNOLE9BQU8sQ0FBQyxJQUFJLENBQ1YsZ0RBQWdELEtBQUssa0JBQWtCLHFCQUFxQixDQUFDLGNBQWMsRUFBRSxDQUM5RyxDQUFDOzRCQUNKLENBQUM7d0JBQ0gsQ0FBQzs2QkFBTSxDQUFDOzRCQUNOLE9BQU8sQ0FBQyxJQUFJLENBQ1YsMENBQTBDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FDL0QsQ0FBQzt3QkFDSixDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxPQUFPLElBQUksY0FBYyxDQUN2QixPQUFPLENBQUMsVUFBVSxFQUNsQixhQUFhLEVBQ2IsV0FBVyxDQUNaLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQ0wsQ0FDSixDQUNGLENBQ0osQ0FBQztRQUVGLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBRWxDLHdEQUF3RDtZQUN4RCxJQUFJLGtCQUFrQixFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxhQUFhO29CQUMxQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUM7WUFDbEMsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO0lBRUQsYUFBYSxDQUNYLElBQVMsRUFDVCxTQUFpQixFQUNqQixJQUFhLEVBQ2IsV0FBb0I7UUFFcEIsSUFBSSxPQUFPLEdBQVUsRUFBRSxDQUFDO1FBQ3hCLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDcEQsQ0FBQztRQUNELE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUNuRSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsQ0FBQztZQUNsRCxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2YsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFTyxpQkFBaUIsQ0FBQyxLQUFhLEVBQUUsSUFBYTtRQUNwRCxNQUFNLE9BQU8sR0FBVSxFQUFFLENBQUM7UUFFMUIsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsV0FBVyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQzNELE9BQU8sT0FBTyxDQUFDO1FBQ2pCLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN2QixPQUFPLENBQUMsSUFBSSxDQUFDO2dCQUNYLElBQUksRUFBRSxNQUFNO2dCQUNaLEtBQUssRUFBRSxNQUFNO2dCQUNiLFFBQVEsRUFBRSxjQUFjO2FBQ3pCLENBQUMsQ0FBQztRQUNMLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxLQUFLLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLEtBQUssS0FBSyxFQUFFLENBQUM7Z0JBQzdELE9BQU8sQ0FBQyxJQUFJLENBQUM7b0JBQ1gsSUFBSSxFQUFFLE1BQU07b0JBQ1osS0FBSyxFQUFFLE1BQU07b0JBQ2IsUUFBUSxFQUFFLGNBQWM7aUJBQ3pCLENBQUMsQ0FBQztZQUNMLENBQUM7WUFDRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ1YsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztZQUMxRSxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sT0FBTyxDQUFDLElBQUksQ0FBQztvQkFDWCxJQUFJLEVBQUUsUUFBUTtvQkFDZCxLQUFLLEVBQUUsUUFBUTtvQkFDZixRQUFRLEVBQUUsZ0JBQWdCO2lCQUMzQixDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRCxzQkFBc0I7UUFDcEIsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVsRCxJQUFJLFlBQVksRUFBRSxDQUFDO1lBQ2pCLE1BQU0saUJBQWlCLEdBQUcsWUFBWSxDQUFDLHlCQUF5QixDQUFDLENBQUM7WUFDbEUsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO2dCQUN0QixJQUFJLENBQUMsaUJBQWlCLEdBQUc7b0JBQ3ZCLGVBQWUsRUFBRSxpQkFBaUIsQ0FBQyxlQUFlLElBQUksU0FBUztvQkFDL0QsV0FBVyxFQUFFLGlCQUFpQixDQUFDLFdBQVcsSUFBSSxTQUFTO29CQUN2RCxZQUFZLEVBQUUsaUJBQWlCLENBQUMsWUFBWSxJQUFJLEtBQUs7b0JBQ3JELEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxLQUFLLElBQUksU0FBUztvQkFDM0MsVUFBVSxFQUFFLGlCQUFpQixDQUFDLFVBQVUsSUFBSSxTQUFTO29CQUNyRCxRQUFRLEVBQUUsaUJBQWlCLENBQUMsUUFBUSxJQUFJLFNBQVM7b0JBQ2pELE1BQU0sRUFBRSxpQkFBaUIsQ0FBQyxNQUFNLElBQUksS0FBSztpQkFDMUMsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELHFCQUFxQixDQUFDLE1BQVcsRUFBRSxXQUFvQjtRQUNyRCxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNuRSxNQUFNLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUMzRSxDQUFDO0lBRUQsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFZLEVBQUUsSUFBdUI7UUFDckQsSUFBSSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUM7WUFDbkMsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsS0FBSyxDQUFDO1FBQ3RDLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGlCQUFpQjtRQUNyQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLFVBQVcsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNuRSxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDOUMsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsVUFBVSxDQUFDLElBQVM7UUFDeEIsSUFBSSxJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDekMsQ0FBQztJQUNILENBQUM7SUFFRCxrQkFBa0I7UUFDaEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsSUFBSSxTQUFTLENBQUM7UUFDN0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsSUFBSSxTQUFTLENBQUM7UUFDekQsT0FBTyw2QkFBNkIsS0FBSyxLQUFLLEdBQUcsR0FBRyxDQUFDO0lBQ3ZELENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxVQUFlO1FBQzlCLElBQUksVUFBVSxJQUFJLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDeEMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFO2dCQUM1QixNQUFNLFNBQVMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQ3pDLElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDakMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNwQixDQUFDO2dCQUNELElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztvQkFDdEMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUN6QixDQUFDO2dCQUNELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQUMsSUFBWSxFQUFFLElBQXVCO1FBQ3ZELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsVUFBVSxJQUFJLEVBQUUsQ0FBQztRQUMzQyxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXpDLElBQUksWUFBWSxHQUFHLENBQUM7WUFBRSxPQUFPO1FBRTdCLE1BQU0sU0FBUyxHQUFHLFlBQVksR0FBRyxDQUFDLENBQUM7UUFFbkMsSUFDRSxDQUFDLElBQUksS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLFFBQVEsQ0FBQztZQUN0QyxZQUFZLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQ2hDLENBQUM7WUFDRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNqRSxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztnQkFDMUIsT0FBTztZQUNULENBQUM7WUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNwQixNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxVQUFVLENBQUM7Z0JBQzFELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO2dCQUNqRSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7b0JBQ2hCLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO29CQUMxQixPQUFPO2dCQUNULENBQUM7Z0JBRUQsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMvQixNQUFNLFNBQVMsR0FBRyxZQUFZLEdBQUcsQ0FBQyxDQUFDO2dCQUNuQyxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQzlDLHdCQUF3QixDQUN6QixDQUFDO29CQUNBLElBQUksRUFBRSxJQUFJLENBQUMsZ0JBQWdCO29CQUMzQixFQUFFLEVBQUUsU0FBUztvQkFDYixPQUFPLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtvQkFDOUIsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRTtpQkFDN0MsQ0FBQyxDQUFDO2dCQUNILE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsY0FBYyxDQUFDLENBQUM7Z0JBRTlDLElBQUksY0FBYyxFQUFFLENBQUM7b0JBQ25CLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDakMsQ0FBQztnQkFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO29CQUN6QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsU0FBUyxDQUFDO29CQUNsQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQztvQkFDbkMsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUN0RSxDQUFDO2dCQUNELElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3pCLE1BQU0sSUFBSSxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xFLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLENBQUM7b0JBQzdCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQy9ELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQzt3QkFDaEIsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7d0JBQzFCLE9BQU87b0JBQ1QsQ0FBQztvQkFDRCxNQUFNLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDL0IsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUMvQixDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7YUFBTSxJQUFJLElBQUksS0FBSyxNQUFNLElBQUksWUFBWSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQy9DLE1BQU0sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FDOUMsd0JBQXdCLENBQ3pCLENBQUM7b0JBQ0EsSUFBSSxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7b0JBQzNCLEVBQUUsRUFBRSxTQUFTO29CQUNiLE9BQU8sRUFBRSxJQUFJLENBQUMsZ0JBQWdCO2lCQUMvQixDQUFDLENBQUM7Z0JBRUgsSUFBSSxjQUFjLEVBQUUsQ0FBQztvQkFDbkIsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNqQyxDQUFDO2dCQUVELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxTQUFTLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDO2dCQUNuQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzNCLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUM7Z0JBQ25ELE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FDOUMsd0JBQXdCLENBQ3pCLENBQUM7b0JBQ0EsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYTtvQkFDaEMsRUFBRSxFQUFFLFdBQVc7b0JBQ2YsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYTtpQkFDcEMsQ0FBQyxDQUFDO2dCQUVILElBQUksY0FBYyxFQUFFLENBQUM7b0JBQ25CLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDakMsQ0FBQztnQkFFRCxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUN4QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUM7WUFDckQsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFTyxLQUFLLENBQUMsZUFBZTtRQUMzQixNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFFTyxLQUFLLENBQUMsTUFBTTtRQUNsQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQztRQUM5QyxNQUFNLE9BQU8sR0FBRyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBRS9CLE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQ3pFLElBQUksRUFBRSxVQUFVO1lBQ2hCLEVBQUUsRUFBRSxPQUFPO1lBQ1gsT0FBTyxFQUFFLFVBQVU7WUFDbkIsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRTtTQUM3QyxDQUFDLENBQUM7UUFFSCxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ25CLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQyxDQUFDO1FBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUM7UUFDbkQsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDekUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRU8scUJBQXFCO1FBQzNCLElBQ0UsSUFBSSxDQUFDLE9BQU87WUFDWixJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFPLEdBQUcsQ0FBQyxFQUNsRSxDQUFDO1lBQ0QsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDN0IsQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN6RSxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUM3QixDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEIsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztnQkFDOUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7WUFDNUIsQ0FBQztZQUNELElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO1FBQzNDLENBQUM7SUFDSCxDQUFDO0lBRUQsWUFBWSxDQUFDLElBQXVCO1FBQ2xDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNwQyxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDbkIsSUFBSSxvQkFBb0IsR0FBa0IsSUFBSSxDQUFDO1FBRS9DLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQzVCLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO29CQUNqQixDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFO3dCQUM5QixDQUFDLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxDQUFDO3dCQUM5QixDQUFDLENBQUMsV0FBVyxDQUFDLHNCQUFzQixFQUFFLENBQUM7d0JBQ3ZDLElBQUksQ0FBQyxDQUFDLFdBQVcsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7NEJBQ3JDLE9BQU8sR0FBRyxLQUFLLENBQUM7NEJBRWhCLGlEQUFpRDs0QkFDakQsSUFBSSxDQUFDLG9CQUFvQixJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQ0FDbkMsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQzs0QkFDL0IsQ0FBQzt3QkFDSCxDQUFDO29CQUNILENBQUMsQ0FBQyxDQUFDO2dCQUNMLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxnRkFBZ0Y7UUFDaEYsSUFBSSxDQUFDLE9BQU8sSUFBSSxvQkFBb0IsRUFBRSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUNoRSxDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELE9BQU8sQ0FBQyxLQUF3QjtRQUM5QixJQUFJLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNkLE9BQU8sS0FBSyxDQUFDLFdBQVcsRUFBRSxLQUFLLElBQUksS0FBSyxDQUFDO1FBQzNDLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQyxVQUFVO1lBQ3JCLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoRCxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ1gsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFhO1FBQ3hCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVyxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3BFLE9BQU8sUUFBUSxLQUFLLFFBQVEsQ0FBQyxNQUFNLENBQUM7SUFDdEMsQ0FBQztJQUVELEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBVTtRQUMzQixJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDakMsTUFBTSxJQUFJLENBQUMsNkJBQTZCLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2hFLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLDZCQUE2QixDQUFDLEtBQWE7UUFDL0MsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsVUFBVSxDQUFDO1FBQ3JELElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQsS0FBSyxDQUFDLGdDQUFnQyxDQUFDLEVBQU87UUFDNUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QixFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFNLEVBQUUsRUFBRTtnQkFDMUIsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUN6QyxJQUFJLFNBQVMsRUFBRSxtQkFBbUIsRUFBRSxDQUFDO29CQUNuQyxNQUFNLFNBQVMsRUFBRSxtQkFBbUIsRUFBRSxDQUFDO2dCQUN6QyxDQUFDO2dCQUNELElBQUksU0FBUyxFQUFFLGNBQWMsRUFBRSxDQUFDO29CQUM5QixTQUFTLEVBQUUsY0FBYyxFQUFFLENBQUM7Z0JBQzlCLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN0RCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRUQscUJBQXFCLENBQUMsRUFBTztRQUMzQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxvQkFBb0IsR0FBa0IsSUFBSSxDQUFDO1FBRS9DLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDeEIsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBTSxFQUFFLEVBQUU7Z0JBQzFCLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQztnQkFDdkIsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUN6QyxJQUFJLFNBQVMsRUFBRSxVQUFVLEVBQUUsQ0FBQztvQkFDMUIsV0FBVyxHQUFHLFNBQVMsRUFBRSxVQUFVLEVBQUUsQ0FBQztvQkFDdEMsSUFBSSxXQUFXLEtBQUssS0FBSyxFQUFFLENBQUM7d0JBQzFCLEtBQUssR0FBRyxLQUFLLENBQUM7d0JBQ2QseUNBQXlDO3dCQUN6QyxJQUFJLENBQUMsb0JBQW9CLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDOzRCQUNuQyxvQkFBb0IsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDO3dCQUMvQixDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztnQkFDRCxXQUFXLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDdkQsSUFBSSxXQUFXLEtBQUssS0FBSyxFQUFFLENBQUM7b0JBQzFCLEtBQUssR0FBRyxLQUFLLENBQUM7Z0JBQ2hCLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxnRkFBZ0Y7UUFDaEYsSUFBSSxDQUFDLEtBQUssSUFBSSxvQkFBb0IsRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUNoRSxDQUFDO2FBQU0sSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2xCLDJFQUEyRTtZQUMzRSxJQUFJLENBQUMsYUFBYSxDQUFDLDRCQUE0QixFQUFFLENBQUM7UUFDcEQsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELDhCQUE4QjtRQUM1QixPQUFPO1lBQ0wsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSztTQUN0QixDQUFDO0lBQ0osQ0FBQzsrR0FsNkJVLDJCQUEyQjttR0FBM0IsMkJBQTJCLG1EQVIzQjtZQUNUO2dCQUNFLE9BQU8sRUFBRSxzQkFBc0I7Z0JBQy9CLFFBQVEsRUFBRSxFQUFFLDJCQUEyQixFQUFFLEtBQUssRUFBRTthQUNqRDtZQUNELHNCQUFzQjtTQUN2QixtRUFLVSxVQUFVLDRGQ3hDdkIsMjdJQWtKQTs7NEZEN0dhLDJCQUEyQjtrQkFadkMsU0FBUzsrQkFDRSwwQkFBMEIsYUFHekI7d0JBQ1Q7NEJBQ0UsT0FBTyxFQUFFLHNCQUFzQjs0QkFDL0IsUUFBUSxFQUFFLEVBQUUsMkJBQTJCLEVBQUUsS0FBSyxFQUFFO3lCQUNqRDt3QkFDRCxzQkFBc0I7cUJBQ3ZCO21NQUtzQixPQUFPO3NCQUE3QixTQUFTO3VCQUFDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTVEVQUEVSX0dMT0JBTF9PUFRJT05TIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3N0ZXBwZXInO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIFZpZXdDaGlsZCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNYXRTdGVwcGVyIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc3RlcHBlcic7XG5pbXBvcnQgeyBGaWVsZFR5cGUsIEZvcm1seUZpZWxkQ29uZmlnIH0gZnJvbSAnQG5neC1mb3JtbHkvY29yZSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIHRpbWVyLCBmaXJzdFZhbHVlRnJvbSwgY2F0Y2hFcnJvciwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIEFwcERhdGEsXG4gIEZsdXhUeXBlLFxuICBBcHBEYXRhU3RlcCxcbiAgQXBwRGF0YVNlY3Rpb24sXG4gIEFwcERhdGFDb250cm9sLFxuICBBcHBEYXRhRmlsbCxcbiAgU3RlcENvbnRyb2xUeXBlLFxuICBEaWN0aW9uYXJ5Q29udHJvbERhdGEsXG59IGZyb20gJy4uLy4uL21vZGVscy9mb3Jtcy5tb2RlbCc7XG5pbXBvcnQgeyBBcHBsaWNhdGlvbkRhdGFTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYXBwbGljYXRpb25EYXRhLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ29sbGVjdG9yRm9ybUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL29yaWdpbi1mb3JtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTY3JvbGxUb0Vycm9yU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3Njcm9sbC10by1lcnJvci5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWZvcm1seS1maWVsZC1zdGVwcGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2Zvcm1seS1maWVsZC1zdGVwcGVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZm9ybWx5LWZpZWxkLXN0ZXBwZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogU1RFUFBFUl9HTE9CQUxfT1BUSU9OUyxcbiAgICAgIHVzZVZhbHVlOiB7IGRpc3BsYXlEZWZhdWx0SW5kaWNhdG9yVHlwZTogZmFsc2UgfSxcbiAgICB9LFxuICAgIEFwcGxpY2F0aW9uRGF0YVNlcnZpY2UsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIEZvcm1seUZpZWxkU3RlcHBlckNvbXBvbmVudFxuICBleHRlbmRzIEZpZWxkVHlwZVxuICBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQFZpZXdDaGlsZChNYXRTdGVwcGVyKSBzdGVwcGVyITogTWF0U3RlcHBlcjtcbiAgYnV0dG9uc0dyb3VwczogYW55W11bXSA9IFtdO1xuICBzaG93U3RlcHM6IGJvb2xlYW4gPSB0cnVlO1xuICBzaG93U3RlcHNMYWJlbHM6IGJvb2xlYW4gPSB0cnVlO1xuICBzaG93U3RlcHNDb3VudGVyOiBib29sZWFuID0gdHJ1ZTtcbiAgc2hvd0J1dHRvbnNPblRvcDogYm9vbGVhbjtcbiAgc2hvd1Byb2dyZXNzQmFyOiBib29sZWFuO1xuICBzaG93RmluYWxTdGVwOiBib29sZWFuID0gZmFsc2U7XG4gIGlzRmxvd0ZpbmlzaGVkOiBib29sZWFuID0gZmFsc2U7XG4gIGFwcERhdGE6IEFwcERhdGE7XG4gIGlzRGlzcGxheU1vZGU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNEZWJ1ZzogYm9vbGVhbiA9IGZhbHNlO1xuICBpc05hdmlnYXRpb25JblByb2dyZXNzOiBib29sZWFuID0gZmFsc2U7XG4gIGlzU2F2aW5nOiBib29sZWFuID0gZmFsc2U7XG4gIGN1cnJlbnRTdGVwSW5kZXg6IG51bWJlciA9IDA7XG4gIGxvYWRlZFN0ZXBzOiBib29sZWFuW10gPSBbXTtcbiAgcHJpdmF0ZSBjb25maWdVcGRhdGVTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSB2aXNpYmxlRmllbGRzVXBkYXRlZFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBwcml2YXRlIHVwZGF0ZUFuZEdvTmV4dFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBwcml2YXRlIGdvTmV4dFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBjb25jYXRlbmF0ZWRGb3JtU3R5bGU6IGFueSA9IHt9O1xuICBidXR0b25zVmVydGljYWxQb3NpdGlvbjogc3RyaW5nID0gJ2JvdHRvbSc7XG5cbiAgaXNOYXZpZ2F0aW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgZmluYWxTdGVwRmllbGRDb25maWc6IEZvcm1seUZpZWxkQ29uZmlnO1xuICBmaWx0ZXJlZFZpc2libGVTdGVwczogYW55W10gPSBbXTtcbiAgcHJvZ3Jlc3NCYXJTdHlsZXM6IGFueSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYXBwbGljYXRpb25EYXRhU2VydmljZTogQXBwbGljYXRpb25EYXRhU2VydmljZSxcbiAgICBwcml2YXRlIGNvbGxlY3RvckZvcm06IENvbGxlY3RvckZvcm1Db21wb25lbnQsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgc2Nyb2xsVG9FcnJvclNlcnZpY2U6IFNjcm9sbFRvRXJyb3JTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBhc3luYyBuZ09uSW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnByb3BzWydjb21wb25lbnQnXSA9IHRoaXM7XG4gICAgdGhpcy5hcHBseVByb2dyZXNzQmFyU3R5bGVzKCk7XG4gICAgdGhpcy5jb25maWdVcGRhdGVTdWJzY3JpcHRpb24gPVxuICAgICAgdGhpcy5jb2xsZWN0b3JGb3JtLmZvcm1seUNvbmZpZ1VwZGF0ZWQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuZmllbGQgJiYgdGhpcy5maWVsZC5maWVsZEdyb3VwKSB7XG4gICAgICAgICAgdGhpcy5maWVsZC5maWVsZEdyb3VwID0gdGhpcy5leHRyYWN0RmluYWxTdGVwSWZOZWNlc3NhcnkoXG4gICAgICAgICAgICB0aGlzLmZpZWxkLmZpZWxkR3JvdXBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY3JlYXRlRmllbGRHcm91cEJ1dHRvbnMoKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy52aXNpYmxlRmllbGRzVXBkYXRlZFN1YnNjcmlwdGlvbiA9XG4gICAgICB0aGlzLmNvbGxlY3RvckZvcm0udmlzaWJsZUZpZWxkc1VwZGF0ZWQuc3Vic2NyaWJlKCh2aXNpYmxlRmllbGRzKSA9PiB7XG4gICAgICAgIHRoaXMuZmlsdGVyZWRWaXNpYmxlU3RlcHMgPSB2aXNpYmxlRmllbGRzO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLnVwZGF0ZUFuZEdvTmV4dFN1YnNjcmlwdGlvbiA9XG4gICAgICB0aGlzLmNvbGxlY3RvckZvcm0uZm9ybWx5VXBkYXRlQW5kR29OZXh0LnN1YnNjcmliZShhc3luYyAoZSkgPT4ge1xuICAgICAgICBpZiAoZSAmJiBlLnNlbGVjdGVkT2ZmZXJJZCAmJiB0aGlzLmFwcERhdGE/LmZpbGxEYXRhKSB7XG4gICAgICAgICAgdGhpcy5hcHBEYXRhLmZpbGxEYXRhLm1ldGFkYXRhLm9mZmVySWQgPSBlLnNlbGVjdGVkT2ZmZXJJZDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdGVwID0gdGhpcy5maWVsZC5maWVsZEdyb3VwIVt0aGlzLmN1cnJlbnRTdGVwSW5kZXhdO1xuICAgICAgICBhd2FpdCB0aGlzLm5hdmlnYXRlQXN5bmMoJ25leHQnLCBzdGVwKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5nb05leHRTdWJzY3JpcHRpb24gPSB0aGlzLmNvbGxlY3RvckZvcm0uZm9ybWx5R29OZXh0LnN1YnNjcmliZSgoZSkgPT4ge1xuICAgICAgdGhpcy5nb05leHQoKTtcbiAgICB9KTtcbiAgICBhd2FpdCB0aGlzLmluaXRTdGVwKCk7XG4gIH1cblxuICBhc3luYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoY2hhbmdlcy5maWVsZCkge1xuICAgICAgYXdhaXQgdGhpcy51cGRhdGVBcHBEYXRhKGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgYXdhaXQgdGhpcy5jcmVhdGVBcHBEYXRhKHRoaXMuZmllbGQucHJvcHMpO1xuICAgIGlmICh0aGlzLmN1cnJlbnRTdGVwSW5kZXggPj0gdGhpcy50b3RhbFN0ZXBzQ291bnQpIHtcbiAgICAgIHRoaXMuc2hvd0ZpbmFsU3RlcCA9IHRydWU7XG4gICAgICB0aGlzLnNob3dTdGVwcyA9IGZhbHNlO1xuICAgICAgdGhpcy5zaG93U3RlcHNDb3VudGVyID0gZmFsc2U7XG4gICAgfSBlbHNlIGlmICh0aGlzLnN0ZXBwZXIpIHtcbiAgICAgIHRoaXMuc3RlcHBlci5saW5lYXIgPSBmYWxzZTtcbiAgICAgIHRoaXMuc3RlcHBlci5zZWxlY3RlZEluZGV4ID0gdGhpcy5jdXJyZW50U3RlcEluZGV4O1xuICAgICAgY29uc3Qgc3RlcHMgPSB0aGlzLnN0ZXBwZXIuX3N0ZXBzLnRvQXJyYXkoKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jdXJyZW50U3RlcEluZGV4OyBpKyspIHtcbiAgICAgICAgc3RlcHNbaV0uY29tcGxldGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnN0ZXBwZXIubGluZWFyID0gdHJ1ZTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAodGhpcy5maWVsZC5maWVsZEdyb3VwICYmIHRoaXMuZmllbGQuZmllbGRHcm91cC5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmxvYWRlZFN0ZXBzID0gQXJyYXkodGhpcy5maWVsZC5maWVsZEdyb3VwLmxlbmd0aCkuZmlsbChmYWxzZSk7XG4gICAgICB0aGlzLmxvYWRlZFN0ZXBzW3RoaXMuY3VycmVudFN0ZXBJbmRleF0gPSB0cnVlO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc2hvd1N0ZXBzIHx8IHRoaXMuY3VycmVudFN0ZXBJbmRleCA9PSAwKSB7XG4gICAgICB0aGlzLnRyaWdnZXJPblBhZ2VTZWxlY3RlZEZvckluZGV4KHRoaXMuY3VycmVudFN0ZXBJbmRleCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29uZmlnVXBkYXRlU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLmNvbmZpZ1VwZGF0ZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICBpZiAodGhpcy51cGRhdGVBbmRHb05leHRTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMudXBkYXRlQW5kR29OZXh0U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmdvTmV4dFN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5nb05leHRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudmlzaWJsZUZpZWxkc1VwZGF0ZWRTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMudmlzaWJsZUZpZWxkc1VwZGF0ZWRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBpbml0U3RlcCgpIHtcbiAgICBpZiAodGhpcy5maWVsZCkge1xuICAgICAgaWYgKHRoaXMuZmllbGQuZmllbGRHcm91cCkge1xuICAgICAgICB0aGlzLmZpZWxkLmZpZWxkR3JvdXAgPSB0aGlzLmV4dHJhY3RGaW5hbFN0ZXBJZk5lY2Vzc2FyeShcbiAgICAgICAgICB0aGlzLmZpZWxkLmZpZWxkR3JvdXBcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5sb2FkZWRTdGVwcyA9IEFycmF5KHRoaXMuZmllbGQuZmllbGRHcm91cC5sZW5ndGgpLmZpbGwoZmFsc2UpO1xuICAgICAgICB0aGlzLmxvYWRlZFN0ZXBzW3RoaXMuY3VycmVudFN0ZXBJbmRleF0gPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuZmllbGQucHJvcHMpIHtcbiAgICAgICAgdGhpcy5maWx0ZXJlZFZpc2libGVTdGVwcyA9IHRoaXMuZmllbGQucHJvcHNbJ2ZpbHRlcmVkRmx1eCddO1xuICAgICAgICB0aGlzLmlzRGVidWcgPSB0aGlzLmZpZWxkLnByb3BzWydpc0RlYnVnJ107XG4gICAgICAgIGNvbnN0IHN0ZXBTZXR0aW5ncyA9IHRoaXMuZmllbGQucHJvcHNbJ3N0ZXBzU2V0dGluZ3MnXTtcbiAgICAgICAgaWYgKHN0ZXBTZXR0aW5ncykge1xuICAgICAgICAgIHRoaXMuc2hvd1N0ZXBzID0gc3RlcFNldHRpbmdzLnNob3dBbGxTdGVwcztcbiAgICAgICAgICB0aGlzLnNob3dTdGVwc0NvdW50ZXIgPSBzdGVwU2V0dGluZ3Muc2hvd0NvdW50ZXI7XG4gICAgICAgICAgdGhpcy5zaG93U3RlcHNMYWJlbHMgPSBzdGVwU2V0dGluZ3Muc2hvd0xhYmVscztcbiAgICAgICAgICB0aGlzLnNob3dQcm9ncmVzc0JhciA9IHN0ZXBTZXR0aW5ncy5zaG93UHJvZ3Jlc3NCYXI7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGVzaWduQ29uZmlnID0gdGhpcy5maWVsZC5wcm9wc1snZGVzaWduQ29uZmlnJ107XG4gICAgICAgIGlmIChkZXNpZ25Db25maWcpIHtcbiAgICAgICAgICB0aGlzLnNob3dCdXR0b25zT25Ub3AgPVxuICAgICAgICAgICAgZGVzaWduQ29uZmlnLmJ1dHRvbnNWZXJ0aWNhbFBvc2l0aW9uID09PSAndG9wJztcbiAgICAgICAgfVxuXG4gICAgICAgIE9iamVjdC5lbnRyaWVzKHRoaXMuZmllbGQucHJvcHNbJ2Rlc2lnbiddKVxuICAgICAgICAgIC5maWx0ZXIoKGkpID0+IGlbMF0uc3RhcnRzV2l0aCgnLmZvcm0nKSlcbiAgICAgICAgICAuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcHJvcDogYW55ID0gaVsxXTtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHByb3ApLmZvckVhY2goKGopID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5jb25jYXRlbmF0ZWRGb3JtU3R5bGVbal0gPSBwcm9wW2pdO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5idXR0b25zVmVydGljYWxQb3NpdGlvbiA9XG4gICAgICAgICAgdGhpcy5maWVsZC5wcm9wc1snZGVzaWduJ11bJy5idXR0b25zLWNvbnRhaW5lciddWydhbGlnbi1pdGVtcyddID09XG4gICAgICAgICAgICAnZmxleC1zdGFydCdcbiAgICAgICAgICAgID8gJ3RvcCdcbiAgICAgICAgICAgIDogJ2JvdHRvbSc7XG4gICAgICB9XG4gICAgICB0aGlzLmNyZWF0ZUZpZWxkR3JvdXBCdXR0b25zKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHRvdGFsU3RlcHNDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmZpZWxkPy5maWVsZEdyb3VwPy5maWx0ZXIoXG4gICAgICAgIChzdGVwKSA9PiBzdGVwLnByb3BzPy5bJ2ZsdXhUeXBlJ10gIT09IEZsdXhUeXBlLkZpbmFsXG4gICAgICApLmxlbmd0aCA/PyAwXG4gICAgKTtcbiAgfVxuXG4gIGV4dHJhY3RGaW5hbFN0ZXBJZk5lY2Vzc2FyeShcbiAgICBmaWVsZENvbmZpZ3M6IEZvcm1seUZpZWxkQ29uZmlnW11cbiAgKTogRm9ybWx5RmllbGRDb25maWdbXSB7XG4gICAgbGV0IGZpbHRlcmVkQ29uZmlnOiBGb3JtbHlGaWVsZENvbmZpZ1tdID0gW107XG4gICAgdGhpcy5maWVsZC5maWVsZEdyb3VwPy5mb3JFYWNoKChmKSA9PiB7XG4gICAgICBpZiAoZi5wcm9wcyAmJiBmLnByb3BzWydmbHV4VHlwZSddID09IEZsdXhUeXBlLkZpbmFsKSB7XG4gICAgICAgIHRoaXMuZmluYWxTdGVwRmllbGRDb25maWcgPSBmO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZmlsdGVyZWRDb25maWcucHVzaChmKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gZmlsdGVyZWRDb25maWc7XG4gIH1cblxuICBjcmVhdGVGaWVsZEdyb3VwQnV0dG9ucygpIHtcbiAgICBpZiAodGhpcy5maWVsZC5maWVsZEdyb3VwKSB7XG4gICAgICB0aGlzLmJ1dHRvbnNHcm91cHMgPSBbXTtcbiAgICAgIHRoaXMuZmllbGQuZmllbGRHcm91cC5mb3JFYWNoKChmZywgaSkgPT4ge1xuICAgICAgICBjb25zdCBpc0xhc3QgPSBpID09PSB0aGlzLmZpZWxkLmZpZWxkR3JvdXAhLmxlbmd0aCAtIDE7XG5cbiAgICAgICAgbGV0IGJ0bkRpc2FibGVkID0gZmFsc2U7XG4gICAgICAgIGlmIChmZy5wcm9wcykge1xuICAgICAgICAgIGNvbnN0IGZsdXhUeXBlID0gZmcucHJvcHNbJ2ZsdXhUeXBlJ107XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgZmx1eFR5cGUgPT09IEZsdXhUeXBlLkt5YyB8fFxuICAgICAgICAgICAgZmx1eFR5cGUgPT09IEZsdXhUeXBlLkdlbmVyYXRlRG9jdW1lbnQgfHxcbiAgICAgICAgICAgIGZsdXhUeXBlID09PSBGbHV4VHlwZS5TaWduIHx8XG4gICAgICAgICAgICBmbHV4VHlwZSA9PT0gRmx1eFR5cGUuRW1haWwgfHxcbiAgICAgICAgICAgIGZsdXhUeXBlID09PSBGbHV4VHlwZS5QaG9uZSB8fFxuICAgICAgICAgICAgZmx1eFR5cGUgPT09IEZsdXhUeXBlLk9wZW5CYW5raW5nXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLmJ1dHRvbnNHcm91cHMucHVzaChbXSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnRuRGlzYWJsZWQgPVxuICAgICAgICAgICAgZmx1eFR5cGUgPT09IEZsdXhUeXBlLkt5YyB8fFxuICAgICAgICAgICAgZmx1eFR5cGUgPT09IEZsdXhUeXBlLlBob25lIHx8XG4gICAgICAgICAgICBmbHV4VHlwZSA9PT0gRmx1eFR5cGUuRW1haWw7XG4gICAgICAgICAgZmcucHJvcHNbJ2J1dHRvbnNEaXNhYmxlZCddID09PSB0cnVlO1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIChmbHV4VHlwZSA9PT0gRmx1eFR5cGUuS3ljIHx8XG4gICAgICAgICAgICAgIGZsdXhUeXBlID09PSBGbHV4VHlwZS5QaG9uZSB8fFxuICAgICAgICAgICAgICBmbHV4VHlwZSA9PT0gRmx1eFR5cGUuRW1haWwpICYmXG4gICAgICAgICAgICBmZy5wcm9wc1snYnV0dG9uc0Rpc2FibGVkJ10gPT09IGZhbHNlXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBidG5EaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGNvbXBvbmVudHNXaXRoRGVmYXVsdExhYmVscyA9XG4gICAgICAgICAgICB0aGlzLmdldENvbXBvbmVudHNXaXRoRGVmYXVsdExhYmVscygpO1xuICAgICAgICAgIGlmIChjb21wb25lbnRzV2l0aERlZmF1bHRMYWJlbHNbZmx1eFR5cGVdKSB7XG4gICAgICAgICAgICBmZy5wcm9wc1snbGFiZWwnXSA9IGNvbXBvbmVudHNXaXRoRGVmYXVsdExhYmVsc1tmbHV4VHlwZV07XG4gICAgICAgICAgICBmZy5wcm9wc1snZGVzY3JpcHRpb24nXSA9ICcnO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBmZy5wcm9wcz8uWydmbHV4VHlwZSddID09PSBGbHV4VHlwZS5WaWV3T2ZmZXIgfHxcbiAgICAgICAgICBmZy5wcm9wcz8uWydmbHV4VHlwZSddID09PSBGbHV4VHlwZS5QYXVzZVxuICAgICAgICApIHtcbiAgICAgICAgICAvLzEyPWxpc3Qgb2ZmZXJzXG4gICAgICAgICAgdGhpcy5idXR0b25zR3JvdXBzLnB1c2goW10pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGJ0bnMgPSB0aGlzLmNyZWF0ZUJ1dHRvbnMoZmcsIGksIGlzTGFzdCwgYnRuRGlzYWJsZWQpO1xuICAgICAgICAgIGlmICh0aGlzLnByb3BzWydkZW1vTW9kZSddID09PSB0cnVlKSB7XG4gICAgICAgICAgICBidG5zLmZvckVhY2goKGI6IHsgdHlwZTogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgICAgICAgaWYgKGIudHlwZSA9PT0gJ3N1Ym1pdCcpIHtcbiAgICAgICAgICAgICAgICBidG5zLnNwbGljZShidG5zLmluZGV4T2YoYiksIDEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHRoaXMucHJvcHNbJ25vQnV0dG9uc0luVmlldyddID09PSB0cnVlKSB7XG4gICAgICAgICAgICBidG5zLnNwbGljZSgwLCBidG5zLmxlbmd0aCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuYnV0dG9uc0dyb3Vwcy5wdXNoKGJ0bnMpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjcmVhdGVBcHBEYXRhKHByb3BzOiBhbnkpIHtcbiAgICBjb25zdCBhcHBEYXRhSWQgPSBwcm9wc1snYXBwRGF0YUlkJ107XG4gICAgY29uc3QgYXBwbGljYXRpb25JZCA9IHByb3BzWydhcHBsaWNhdGlvbklkJ10gfHwgMDtcbiAgICBjb25zdCBjdXJyZW50U3RlcElkID1cbiAgICAgIHByb3BzLm1ldGFEYXRhPy5jdXJyZW50U3RlcElkIHx8IHByb3BzLmZsdXhbMF0/LmlkZW50aWZpZXI7XG5cbiAgICBpZiAocHJvcHNbJ2hhc0RpY3Rpb25hcnlEZXBlbmRlbnRTdGVwcyddKSB7XG4gICAgICBhd2FpdCB0aW1lcigxNTApLnRvUHJvbWlzZSgpO1xuICAgIH1cblxuICAgIGNvbnN0IHN0ZXBJbmRleCA9XG4gICAgICB0aGlzLmZpZWxkLmZpZWxkR3JvdXA/LmZpbmRJbmRleChcbiAgICAgICAgKHMpID0+IHMucHJvcHM/Llsnc3RlcElkJ10gPT09IGN1cnJlbnRTdGVwSWRcbiAgICAgICkgfHwgMDtcbiAgICB0aGlzLmlzRGlzcGxheU1vZGUgPSBwcm9wc1snaXNEaXNwbGF5TW9kZSddIHx8IGZhbHNlO1xuXG4gICAgdGhpcy5jdXJyZW50U3RlcEluZGV4ID1cbiAgICAgIHN0ZXBJbmRleCA+PSAwICYmICF0aGlzLmlzRGlzcGxheU1vZGUgPyBzdGVwSW5kZXggOiAwO1xuXG4gICAgY29uc3Qgc3RhdHVzSWQgPSBwcm9wc1snc3RhdHVzSWQnXSB8fCAnJztcbiAgICBjb25zdCBkZWZhdWx0TGFuZ3VhZ2UgPSBwcm9wc1snZGVmYXVsdExhbmd1YWdlJ107XG5cbiAgICBjb25zdCBmbHV4ID0gKHByb3BzWydmbHV4J10gfHwgW10pLm1hcChcbiAgICAgIChzdGVwOiBhbnkpID0+XG4gICAgICAgIG5ldyBBcHBEYXRhU3RlcChcbiAgICAgICAgICBzdGVwLmlkZW50aWZpZXIsXG4gICAgICAgICAgc3RlcC50eXBlLFxuICAgICAgICAgIChzdGVwLnNlY3Rpb25zIHx8IFtdKS5tYXAoXG4gICAgICAgICAgICAoc2VjdGlvbjogYW55KSA9PlxuICAgICAgICAgICAgICBuZXcgQXBwRGF0YVNlY3Rpb24oXG4gICAgICAgICAgICAgICAgc2VjdGlvbi5pZGVudGlmaWVyLFxuICAgICAgICAgICAgICAgIChzZWN0aW9uLmNvbnRyb2xzIHx8IFtdKS5tYXAoXG4gICAgICAgICAgICAgICAgICAoY29udHJvbDogYW55KSA9PlxuICAgICAgICAgICAgICAgICAgICBuZXcgQXBwRGF0YUNvbnRyb2woXG4gICAgICAgICAgICAgICAgICAgICAgY29udHJvbC5pZGVudGlmaWVyLFxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wuZmlsbFZhbHVlIHx8ICcnXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgIClcbiAgICApO1xuICAgIGNvbnN0IG9mZmVySWQgPSBwcm9wcz8uZmlsbERhdGE/Lm1ldGFkYXRhPy5vZmZlcklkIHx8ICcnO1xuICAgIGNvbnN0IGlzU3VibWl0dGVkID0gcHJvcHM/LmZpbGxEYXRhPy5tZXRhZGF0YT8uaXNTdWJtaXR0ZWQgfHwgZmFsc2U7XG5cbiAgICBjb25zdCBmaWxsRGF0YSA9IG5ldyBBcHBEYXRhRmlsbChcbiAgICAgIGFwcERhdGFJZCxcbiAgICAgIGFwcGxpY2F0aW9uSWQsXG4gICAgICBjdXJyZW50U3RlcElkLFxuICAgICAgc3RhdHVzSWQsXG4gICAgICBkZWZhdWx0TGFuZ3VhZ2UsXG4gICAgICBmbHV4LFxuICAgICAgb2ZmZXJJZCxcbiAgICAgIGlzU3VibWl0dGVkXG4gICAgKTtcblxuICAgIHRoaXMuYXBwRGF0YSA9IG5ldyBBcHBEYXRhKHtcbiAgICAgIGFwcERhdGFJZDogYXBwRGF0YUlkLFxuICAgICAgYXBwQ29uZmlndXJhdGlvbklkOiBhcHBsaWNhdGlvbklkLFxuICAgICAgZmlsbERhdGE6IGZpbGxEYXRhLFxuICAgICAgd2l0aE5leHRTdGVwOiBmYWxzZSxcbiAgICAgIGJsb2NrUHJldmlvdXNTdGVwOiBwcm9wc1snYmxvY2tQcmV2aW91c1N0ZXAnXSA/PyBmYWxzZSxcbiAgICAgIGVudjogcHJvcHNbJ2VudiddLFxuICAgIH0pO1xuXG4gICAgaWYgKCF0aGlzLmlzRGlzcGxheU1vZGUgJiYgIXByb3BzWydmaWxsRGF0YSddKSB7XG4gICAgICBhd2FpdCB0aGlzLnNhdmVBcHBEYXRhKCk7XG4gICAgICB0aGlzLmNvbGxlY3RvckZvcm0uZmlsbERhdGEgPSBmaWxsRGF0YTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlQXBwRGF0YSgpIHtcbiAgICBpZiAodGhpcy5pc0Rpc3BsYXlNb2RlIHx8IHRoaXMucHJvcHNbJ2RlbW9Nb2RlJ10gPT09IHRydWUpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdbRGVtbyBNb2RlXSBTa2lwcGluZyBzYXZlQXBwRGF0YSByZXF1ZXN0LicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmlzU2F2aW5nID0gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKFxuICAgICAgICB0aGlzLmFwcGxpY2F0aW9uRGF0YVNlcnZpY2Uuc2F2ZUFwcCh0aGlzLmFwcERhdGEpLnBpcGUoXG4gICAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGNyZWF0aW5nIEFwcERhdGEnLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgIHRoaXMuYXBwRGF0YS5maWxsRGF0YSA9IEpTT04ucGFyc2UoZGF0YS5maWxsRGF0YSk7XG4gICAgICAgIHRoaXMuYXBwRGF0YS5ibG9ja1ByZXZpb3VzU3RlcCA9IGRhdGEuYmxvY2tQcmV2aW91c1N0ZXA7XG4gICAgICAgIHRoaXMuY29sbGVjdG9yRm9ybS5mb3JtbHlDb25maWdVcGRhdGVkLmVtaXQoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3Igb2NjdXJyZWQgZHVyaW5nIHNhdmVTdGVwJywgZXJyb3IpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmlzU2F2aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0UHJldmlvdXNTdGVwKCkge1xuICAgIGlmICh0aGlzLmlzRGlzcGxheU1vZGUgfHwgdGhpcy5wcm9wc1snZGVtb01vZGUnXSA9PT0gdHJ1ZSkge1xuICAgICAgY29uc29sZS5sb2coJ1tEZW1vIE1vZGVdIFNraXBwaW5nIGdldFByZXZpb3VzU3RlcCByZXF1ZXN0LicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhd2FpdCBmaXJzdFZhbHVlRnJvbShcbiAgICAgIHRoaXMuYXBwbGljYXRpb25EYXRhU2VydmljZS5nZXRQcmV2aW91c1N0ZXAodGhpcy5hcHBEYXRhLmFwcERhdGFJZCkucGlwZShcbiAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBnZXR0aW5nIHRoZSBwcmV2aW91c1N0ZXAnLCBlcnJvcik7XG4gICAgICAgICAgcmV0dXJuIG9mKG51bGwpO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgIClcbiAgICAgIC50aGVuKChkYXRhKSA9PiB7XG4gICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coZGF0YSk7XG4gICAgICAgICAgdGhpcy5hcHBEYXRhLmZpbGxEYXRhID0gSlNPTi5wYXJzZShkYXRhLmZpbGxEYXRhKTtcbiAgICAgICAgICB0aGlzLmFwcERhdGEuYmxvY2tQcmV2aW91c1N0ZXAgPSBkYXRhLmJsb2NrUHJldmlvdXNTdGVwO1xuICAgICAgICAgIHRoaXMuY29sbGVjdG9yRm9ybS5mb3JtbHlDb25maWdVcGRhdGVkLmVtaXQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIG9jY3VycmVkIGR1cmluZyBnZXRQcmV2aW91c1N0ZXAnLCBlcnJvcik7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHNhdmVBcHBEYXRhU3RlcCgpIHtcbiAgICBpZiAodGhpcy5pc0Rpc3BsYXlNb2RlIHx8IHRoaXMucHJvcHNbJ2RlbW9Nb2RlJ10gPT09IHRydWUpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdbRGVtbyBNb2RlXSBTa2lwcGluZyBzYXZlQXBwRGF0YVN0ZXAgcmVxdWVzdC4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBHZXQgdGhlIGN1cnJlbnQgdmlzaWJsZSBzdGVwIGJhc2VkIG9uIGN1cnJlbnRTdGVwSW5kZXhcblxuICAgIGNvbnN0IGN1cnJlbnRWaXNpYmxlU3RlcCA9IHRoaXMuZmlsdGVyZWRWaXNpYmxlU3RlcHNbdGhpcy5jdXJyZW50U3RlcEluZGV4XTtcblxuICAgIGlmICghY3VycmVudFZpc2libGVTdGVwKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ05vIGN1cnJlbnQgdmlzaWJsZSBzdGVwIGZvdW5kJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRmluZCB0aGUgY29ycmVzcG9uZGluZyBzdGVwIGluIGZpbGxEYXRhLmZsdXggYmFzZWQgb24gdGhlIHZpc2libGUgc3RlcCBpZGVudGlmaWVyXG4gICAgbGV0IGN1cnJlbnRTdGVwID0gdGhpcy5hcHBEYXRhLmZpbGxEYXRhPy5mbHV4LmZpbmQoXG4gICAgICAocykgPT4gcy5zdGVwSWQgPT09IGN1cnJlbnRWaXNpYmxlU3RlcC5pZGVudGlmaWVyXG4gICAgKTtcblxuICAgIC8vIElmIHdlIGNhbid0IGZpbmQgaXQgYnkgaWRlbnRpZmllciwgY3JlYXRlIGl0IG9yIHVwZGF0ZSBtZXRhZGF0YVxuICAgIGlmICghY3VycmVudFN0ZXAgJiYgdGhpcy5hcHBEYXRhLmZpbGxEYXRhKSB7XG4gICAgICAvLyBVcGRhdGUgdGhlIGN1cnJlbnRTdGVwSWQgaW4gbWV0YWRhdGEgdG8gbWF0Y2ggdGhlIGN1cnJlbnQgdmlzaWJsZSBzdGVwXG4gICAgICB0aGlzLmFwcERhdGEuZmlsbERhdGEubWV0YWRhdGEuY3VycmVudFN0ZXBJZCA9XG4gICAgICAgIGN1cnJlbnRWaXNpYmxlU3RlcC5pZGVudGlmaWVyO1xuXG4gICAgICAvLyBUcnkgdG8gZmluZCBpdCBhZ2FpbiBhZnRlciB1cGRhdGluZyBtZXRhZGF0YVxuICAgICAgY3VycmVudFN0ZXAgPSB0aGlzLmFwcERhdGEuZmlsbERhdGEuZmx1eC5maW5kKFxuICAgICAgICAocykgPT4gcy5zdGVwSWQgPT09IGN1cnJlbnRWaXNpYmxlU3RlcC5pZGVudGlmaWVyXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKFxuICAgICAgJ1NhdmluZyBzdGVwIGRhdGEgZm9yIHN0ZXA6JyxcbiAgICAgIGN1cnJlbnRWaXNpYmxlU3RlcC5pZGVudGlmaWVyLFxuICAgICAgJ1N0ZXAgZGF0YTonLFxuICAgICAgY3VycmVudFN0ZXBcbiAgICApO1xuXG4gICAgYXdhaXQgZmlyc3RWYWx1ZUZyb20oXG4gICAgICB0aGlzLmFwcGxpY2F0aW9uRGF0YVNlcnZpY2VcbiAgICAgICAgLnNhdmVTdGVwKFxuICAgICAgICAgIHRoaXMuYXBwRGF0YS5hcHBEYXRhSWQsXG4gICAgICAgICAgY3VycmVudFN0ZXAsXG4gICAgICAgICAgdGhpcy5hcHBEYXRhLmZpbGxEYXRhPy5tZXRhZGF0YS5vZmZlcklkXG4gICAgICAgIClcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNhdmluZyBBcHBEYXRhJywgZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIG9mKG51bGwpO1xuICAgICAgICAgIH0pXG4gICAgICAgIClcbiAgICApXG4gICAgICAudGhlbigoZGF0YSkgPT4ge1xuICAgICAgICBpZiAoZGF0YSkge1xuICAgICAgICAgIHRoaXMuY29sbGVjdG9yRm9ybS5maWxsRGF0YSA9IHRoaXMuYXBwRGF0YS5maWxsRGF0YSA9IEpTT04ucGFyc2UoXG4gICAgICAgICAgICBkYXRhLmZpbGxEYXRhXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLmFwcERhdGEuYmxvY2tQcmV2aW91c1N0ZXAgPSBkYXRhLmJsb2NrUHJldmlvdXNTdGVwO1xuICAgICAgICAgIHRoaXMuY29sbGVjdG9yRm9ybS5mb3JtbHlDb25maWdVcGRhdGVkLmVtaXQoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBDbGVhciB0aGUgc2F2aW5nIGFmdGVyIGFjdGlvbnMgZmxhZ1xuICAgICAgICB0aGlzLmNvbGxlY3RvckZvcm0uY2xlYXJTYXZpbmdBZnRlckFjdGlvbnNTdGF0ZSgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIG9jY3VycmVkIGR1cmluZyBzYXZlU3RlcCcsIGVycm9yKTtcbiAgICAgICAgLy8gQ2xlYXIgdGhlIHNhdmluZyBhZnRlciBhY3Rpb25zIGZsYWcgb24gZXJyb3IgYXMgd2VsbFxuICAgICAgICB0aGlzLmNvbGxlY3RvckZvcm0uY2xlYXJTYXZpbmdBZnRlckFjdGlvbnNTdGF0ZSgpO1xuICAgICAgfSk7XG4gIH1cblxuICBhc3luYyB1cGRhdGVBcHBEYXRhKHNhdmVDaGFuZ2VzOiBib29sZWFuKSB7XG4gICAgY29uc3QgZm9ybVZhbHVlcyA9IHRoaXMuZm9ybS52YWx1ZTtcblxuICAgIC8vIEdldCB0aGUgY3VycmVudCB2aXNpYmxlIHN0ZXAgdG8gZW5zdXJlIHdlJ3JlIHVwZGF0aW5nIHRoZSByaWdodCBzdGVwIGRhdGFcbiAgICBjb25zdCBjdXJyZW50VmlzaWJsZVN0ZXAgPSB0aGlzLmZpbHRlcmVkVmlzaWJsZVN0ZXBzW3RoaXMuY3VycmVudFN0ZXBJbmRleF07XG5cbiAgICBjb25zdCBmbHV4ID0gKHRoaXMuZmllbGQ/LnByb3BzPy5bJ2ZsdXgnXSB8fCBbXSkubWFwKFxuICAgICAgKHN0ZXA6IGFueSkgPT5cbiAgICAgICAgbmV3IEFwcERhdGFTdGVwKFxuICAgICAgICAgIHN0ZXAuaWRlbnRpZmllcixcbiAgICAgICAgICBzdGVwLnR5cGUsXG4gICAgICAgICAgKHN0ZXAuc2VjdGlvbnMgfHwgW10pLm1hcChcbiAgICAgICAgICAgIChzZWN0aW9uOiBhbnkpID0+XG4gICAgICAgICAgICAgIG5ldyBBcHBEYXRhU2VjdGlvbihcbiAgICAgICAgICAgICAgICBzZWN0aW9uLmlkZW50aWZpZXIsXG4gICAgICAgICAgICAgICAgKHNlY3Rpb24uY29udHJvbHMgfHwgW10pXG4gICAgICAgICAgICAgICAgICAuZmlsdGVyKChjb250cm9sOiBhbnkpID0+IGNvbnRyb2wuaWRlbnRpZmllciAhPSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgICAubWFwKChjb250cm9sOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBmb3JtVmFsdWVzW2NvbnRyb2wuaWRlbnRpZmllcl07XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250cm9sLnR5cGUgIT09IFN0ZXBDb250cm9sVHlwZS5EaWN0aW9uYXJ5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbGxWYWx1ZSA9ICcnO1xuICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhZCA9IChuOiBudW1iZXIpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbi50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IGAke3BhZCh2YWx1ZS5nZXREYXRlKCkpfS4ke3BhZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5nZXRNb250aCgpICsgMVxuICAgICAgICAgICAgICAgICAgICAgICAgICApfS4ke3ZhbHVlLmdldEZ1bGxZZWFyKCl9YDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbFZhbHVlID0gZm9ybWF0dGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbFZhbHVlID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJyA/IFN0cmluZyh2YWx1ZSkgOiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBcHBEYXRhQ29udHJvbChjb250cm9sLmlkZW50aWZpZXIsIGZpbGxWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbGxWYWx1ZUlkID0gJyc7XG4gICAgICAgICAgICAgICAgICAgICAgbGV0IGZpbGxWYWx1ZU5hbWUgPSAnJztcblxuICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZS5pZCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGxWYWx1ZUlkID0gU3RyaW5nKHZhbHVlLmlkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbFZhbHVlTmFtZSA9IHZhbHVlLm5hbWUgfHwgJyc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsVmFsdWVJZCA9IFN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpY3Rpb25hcnlDb250cm9sRGF0YSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC5zcGVjaWZpY0NvbnRyb2xEYXRhIGFzIERpY3Rpb25hcnlDb250cm9sRGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRpY3Rpb25hcnlDb250cm9sRGF0YT8uZGljdGlvbmFyeVVVSUQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkaWN0aW9uYXJ5ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29sbGVjdG9yRm9ybS5kaWN0aW9uYXJ5TWFwLmdldChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGljdGlvbmFyeUNvbnRyb2xEYXRhLmRpY3Rpb25hcnlVVUlEXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkT3B0aW9uID0gZGljdGlvbmFyeT8udmFsdWVzPy5maW5kKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHYpID0+IHYuaWQgPT0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZE9wdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbFZhbHVlTmFtZSA9IHNlbGVjdGVkT3B0aW9uLm5hbWUgfHwgJyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYENvdWxkIG5vdCBmaW5kIGRpY3Rpb25hcnkgdmFsdWUgbmFtZSBmb3IgSUQ6ICR7dmFsdWV9IGluIGRpY3Rpb25hcnkgJHtkaWN0aW9uYXJ5Q29udHJvbERhdGEuZGljdGlvbmFyeVVVSUR9YFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYERpY3Rpb25hcnkgVVVJRCBub3QgZm91bmQgZm9yIGNvbnRyb2w6ICR7Y29udHJvbC5pZGVudGlmaWVyfWBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBcHBEYXRhQ29udHJvbChcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wuaWRlbnRpZmllcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGxWYWx1ZU5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsVmFsdWVJZFxuICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgIClcbiAgICApO1xuXG4gICAgaWYgKHRoaXMuYXBwRGF0YS5maWxsRGF0YSkge1xuICAgICAgdGhpcy5hcHBEYXRhLmZpbGxEYXRhLmZsdXggPSBmbHV4O1xuXG4gICAgICAvLyBFbnN1cmUgdGhlIG1ldGFkYXRhIHJlZmxlY3RzIHRoZSBjdXJyZW50IHZpc2libGUgc3RlcFxuICAgICAgaWYgKGN1cnJlbnRWaXNpYmxlU3RlcCkge1xuICAgICAgICB0aGlzLmFwcERhdGEuZmlsbERhdGEubWV0YWRhdGEuY3VycmVudFN0ZXBJZCA9XG4gICAgICAgICAgY3VycmVudFZpc2libGVTdGVwLmlkZW50aWZpZXI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNhdmVDaGFuZ2VzKSB7XG4gICAgICBhd2FpdCB0aGlzLnNhdmVBcHBEYXRhU3RlcCgpO1xuICAgIH1cbiAgfVxuXG4gIGNyZWF0ZUJ1dHRvbnMoXG4gICAgc3RlcDogYW55LFxuICAgIHN0ZXBJbmRleDogbnVtYmVyLFxuICAgIGxhc3Q6IGJvb2xlYW4sXG4gICAgYnRuRGlzYWJsZWQ6IGJvb2xlYW5cbiAgKTogYW55IHtcbiAgICBsZXQgYnV0dG9uczogYW55W10gPSBbXTtcbiAgICBpZiAoc3RlcC5wcm9wcz8uWydidXR0b25zJ10/Lmxlbmd0aCA+IDApIHtcbiAgICAgIGJ1dHRvbnMgPSBzdGVwLnByb3BzPy5bJ2J1dHRvbnMnXTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnV0dG9ucyA9IHRoaXMuZ2V0RGVmYXVsdEJ1dHRvbnMoc3RlcEluZGV4LCBsYXN0KTtcbiAgICB9XG4gICAgYnV0dG9ucy5mb3JFYWNoKChiKSA9PiB0aGlzLnNldHVwQnV0dG9uUHJvcGVydGllcyhiLCBidG5EaXNhYmxlZCkpO1xuICAgIGlmICh0aGlzLmFwcERhdGE/LmZpbGxEYXRhPy5tZXRhZGF0YT8uaXNTdWJtaXR0ZWQpIHtcbiAgICAgIGJ1dHRvbnMgPSBbXTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1dHRvbnM7XG4gIH1cblxuICBwcml2YXRlIGdldERlZmF1bHRCdXR0b25zKGluZGV4OiBudW1iZXIsIGxhc3Q6IGJvb2xlYW4pOiBhbnlbXSB7XG4gICAgY29uc3QgYnV0dG9uczogYW55W10gPSBbXTtcblxuICAgIGlmICh0aGlzLmFwcERhdGE/LmZpbGxEYXRhPy5tZXRhZGF0YT8uaXNTdWJtaXR0ZWQgPT09IHRydWUpIHtcbiAgICAgIHJldHVybiBidXR0b25zO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzRGlzcGxheU1vZGUpIHtcbiAgICAgIGJ1dHRvbnMucHVzaCh7XG4gICAgICAgIHR5cGU6ICdiYWNrJyxcbiAgICAgICAgbGFiZWw6ICdCYWNrJyxcbiAgICAgICAgc3R5bGVLZXk6ICcuYnV0dG9uLWJhY2snLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpbmRleCAhPT0gMCAmJiB0aGlzLmFwcERhdGE/LmJsb2NrUHJldmlvdXNTdGVwID09PSBmYWxzZSkge1xuICAgICAgICBidXR0b25zLnB1c2goe1xuICAgICAgICAgIHR5cGU6ICdiYWNrJyxcbiAgICAgICAgICBsYWJlbDogJ0JhY2snLFxuICAgICAgICAgIHN0eWxlS2V5OiAnLmJ1dHRvbi1iYWNrJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoIWxhc3QpIHtcbiAgICAgICAgYnV0dG9ucy5wdXNoKHsgdHlwZTogJ25leHQnLCBsYWJlbDogJ05leHQnLCBzdHlsZUtleTogJy5idXR0b24tbmV4dCcgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBidXR0b25zLnB1c2goe1xuICAgICAgICAgIHR5cGU6ICdzdWJtaXQnLFxuICAgICAgICAgIGxhYmVsOiAnU3VibWl0JyxcbiAgICAgICAgICBzdHlsZUtleTogJy5idXR0b24tc3VibWl0JyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBidXR0b25zO1xuICB9XG5cbiAgYXBwbHlQcm9ncmVzc0JhclN0eWxlcygpIHtcbiAgICBjb25zdCBkZXNpZ25Db25maWcgPSB0aGlzLmZpZWxkLnByb3BzPy5bJ2Rlc2lnbiddO1xuXG4gICAgaWYgKGRlc2lnbkNvbmZpZykge1xuICAgICAgY29uc3QgcHJvZ3Jlc3NCYXJDb25maWcgPSBkZXNpZ25Db25maWdbJy5jb21wb25lbnQtcHJvZ3Jlc3MtYmFyJ107XG4gICAgICBpZiAocHJvZ3Jlc3NCYXJDb25maWcpIHtcbiAgICAgICAgdGhpcy5wcm9ncmVzc0JhclN0eWxlcyA9IHtcbiAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHByb2dyZXNzQmFyQ29uZmlnLmJhY2tncm91bmRDb2xvciB8fCAnI2ZmZmZmZicsXG4gICAgICAgICAgYm9yZGVyQ29sb3I6IHByb2dyZXNzQmFyQ29uZmlnLmJvcmRlckNvbG9yIHx8ICcjMDAwMDAwJyxcbiAgICAgICAgICBib3JkZXJSYWRpdXM6IHByb2dyZXNzQmFyQ29uZmlnLmJvcmRlclJhZGl1cyB8fCAnN3B4JyxcbiAgICAgICAgICBjb2xvcjogcHJvZ3Jlc3NCYXJDb25maWcuY29sb3IgfHwgJyMwMDAwMDAnLFxuICAgICAgICAgIHN0YXJ0Q29sb3I6IHByb2dyZXNzQmFyQ29uZmlnLnN0YXJ0Q29sb3IgfHwgJyM4ODg0QkYnLFxuICAgICAgICAgIGVuZENvbG9yOiBwcm9ncmVzc0JhckNvbmZpZy5lbmRDb2xvciB8fCAnIzg4ODRCRicsXG4gICAgICAgICAgaGVpZ2h0OiBwcm9ncmVzc0JhckNvbmZpZy5oZWlnaHQgfHwgJzRweCcsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc2V0dXBCdXR0b25Qcm9wZXJ0aWVzKGJ1dHRvbjogYW55LCBidG5EaXNhYmxlZDogYm9vbGVhbikge1xuICAgIGJ1dHRvbi5zdHlsZSA9IHRoaXMuZmllbGQucHJvcHM/LlsnZGVzaWduJ11bYnV0dG9uLnN0eWxlS2V5XSB8fCB7fTtcbiAgICBidXR0b24uZGlzYWJsZWQgPSB0aGlzLnByb3BzWydkZW1vTW9kZSddID09PSBmYWxzZSA/IGJ0bkRpc2FibGVkIDogZmFsc2U7XG4gIH1cblxuICBhc3luYyBidXR0b25DbGljayh0eXBlOiBzdHJpbmcsIHN0ZXA6IEZvcm1seUZpZWxkQ29uZmlnKSB7XG4gICAgaWYgKCF0aGlzLmlzTmF2aWdhdGlvbkluUHJvZ3Jlc3MpIHtcbiAgICAgIHRoaXMuaXNOYXZpZ2F0aW9uSW5Qcm9ncmVzcyA9IHRydWU7XG4gICAgICBhd2FpdCB0aGlzLm5hdmlnYXRlQXN5bmModHlwZSwgc3RlcCk7XG4gICAgICB0aGlzLmlzTmF2aWdhdGlvbkluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBuYXZpZ2F0ZU5leHRBc3luYygpIHtcbiAgICBjb25zdCBjdXJyZW50U3RlcCA9IHRoaXMuZmllbGQ/LmZpZWxkR3JvdXAhW3RoaXMuY3VycmVudFN0ZXBJbmRleF07XG4gICAgaWYgKGN1cnJlbnRTdGVwKSB7XG4gICAgICBhd2FpdCB0aGlzLmJ1dHRvbkNsaWNrKCduZXh0JywgY3VycmVudFN0ZXApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHJldHJ5Q2xpY2soc3RlcDogYW55KSB7XG4gICAgaWYgKHN0ZXA/LmZpZWxkR3JvdXA/Lmxlbmd0aCkge1xuICAgICAgdGhpcy5yZXRyeVJlY3Vyc2l2ZWx5KHN0ZXAuZmllbGRHcm91cCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0UHJvZ3Jlc3NCYXJGaWxsKCk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLnByb2dyZXNzQmFyU3R5bGVzLnN0YXJ0Q29sb3IgfHwgJyM4ODg0QkYnO1xuICAgIGNvbnN0IGVuZCA9IHRoaXMucHJvZ3Jlc3NCYXJTdHlsZXMuZW5kQ29sb3IgfHwgJyM4ODg0QkYnO1xuICAgIHJldHVybiBgbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCAke3N0YXJ0fSwgJHtlbmR9KWA7XG4gIH1cblxuICByZXRyeVJlY3Vyc2l2ZWx5KGZpZWxkR3JvdXA6IGFueSkge1xuICAgIGlmIChmaWVsZEdyb3VwICYmIGZpZWxkR3JvdXAubGVuZ3RoID4gMCkge1xuICAgICAgZmllbGRHcm91cC5mb3JFYWNoKChmOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgY29tcG9uZW50ID0gZi5wcm9wcz8uWydjb21wb25lbnQnXTtcbiAgICAgICAgaWYgKGNvbXBvbmVudCAmJiBjb21wb25lbnQucmV0cnkpIHtcbiAgICAgICAgICBjb21wb25lbnQucmV0cnkoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29tcG9uZW50ICYmIGNvbXBvbmVudC5yZXRyeUFzeW5jKSB7XG4gICAgICAgICAgY29tcG9uZW50LnJldHJ5QXN5bmMoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJldHJ5UmVjdXJzaXZlbHkoZi5maWVsZEdyb3VwKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIG5hdmlnYXRlQXN5bmModHlwZTogc3RyaW5nLCBzdGVwOiBGb3JtbHlGaWVsZENvbmZpZykge1xuICAgIHRoaXMuaXNOYXZpZ2F0aW5nID0gdHJ1ZTtcbiAgICBjb25zdCBzdGVwcyA9IHRoaXMuZmllbGQ/LmZpZWxkR3JvdXAgfHwgW107XG4gICAgY29uc3QgY3VycmVudEluZGV4ID0gc3RlcHMuaW5kZXhPZihzdGVwKTtcblxuICAgIGlmIChjdXJyZW50SW5kZXggPCAwKSByZXR1cm47XG5cbiAgICBjb25zdCBwcmV2SW5kZXggPSBjdXJyZW50SW5kZXggLSAxO1xuXG4gICAgaWYgKFxuICAgICAgKHR5cGUgPT09ICduZXh0JyB8fCB0eXBlID09PSAnc3VibWl0JykgJiZcbiAgICAgIGN1cnJlbnRJbmRleCA8PSBzdGVwcy5sZW5ndGggLSAxXG4gICAgKSB7XG4gICAgICBpZiAodGhpcy5wcm9wc1snZGVtb01vZGUnXSA9PT0gZmFsc2UgJiYgIXRoaXMudmFsaWRhdGVGb3JtKHN0ZXApKSB7XG4gICAgICAgIHRoaXMuaXNOYXZpZ2F0aW5nID0gZmFsc2U7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLnNob3dTdGVwcykge1xuICAgICAgICBjb25zdCBjdXJyZW50RmllbGRHcm91cCA9IHN0ZXBzW2N1cnJlbnRJbmRleF0/LmZpZWxkR3JvdXA7XG4gICAgICAgIGNvbnN0IGNhbkFkdmFuY2UgPSB0aGlzLmNhbkFkdmFuY2VSZWN1cnNpdmVseShjdXJyZW50RmllbGRHcm91cCk7XG4gICAgICAgIGlmICghY2FuQWR2YW5jZSkge1xuICAgICAgICAgIHRoaXMuaXNOYXZpZ2F0aW5nID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVBcHBEYXRhKHRydWUpO1xuICAgICAgICBjb25zdCBuZXh0SW5kZXggPSBjdXJyZW50SW5kZXggKyAxO1xuICAgICAgICBjb25zdCBoYXNBY3Rpb25TdGVwcyA9IGF3YWl0IHRoaXMuZmllbGQ/LnByb3BzPy5bXG4gICAgICAgICAgJ29uU2VsZWN0ZWRQYWdlQ2hhbmdpbmcnXG4gICAgICAgIF0oe1xuICAgICAgICAgIGZyb206IHRoaXMuY3VycmVudFN0ZXBJbmRleCxcbiAgICAgICAgICB0bzogbmV4dEluZGV4LFxuICAgICAgICAgIGN1cnJlbnQ6IHRoaXMuY3VycmVudFN0ZXBJbmRleCxcbiAgICAgICAgICBjYWxsYmFjazogKCkgPT4gdGhpcy5jaGVja0lmRmxvd0lzRmluaXNoZWQoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdoYXNBY3Rpb25TdGVwcycsIGhhc0FjdGlvblN0ZXBzKTtcblxuICAgICAgICBpZiAoaGFzQWN0aW9uU3RlcHMpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZUFwcERhdGEodHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuaXNGbG93RmluaXNoZWQpIHtcbiAgICAgICAgICB0aGlzLmN1cnJlbnRTdGVwSW5kZXggPSBuZXh0SW5kZXg7XG4gICAgICAgICAgdGhpcy5sb2FkZWRTdGVwc1tuZXh0SW5kZXhdID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLmZpZWxkPy5wcm9wcz8uWydvblNlbGVjdGVkUGFnZUNoYW5nZWQnXSh0aGlzLmN1cnJlbnRTdGVwSW5kZXgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgYXdhaXQgdGhpcy50cmlnZ2VyT25QYWdlU2VsZWN0ZWRGb3JJbmRleCh0aGlzLmN1cnJlbnRTdGVwSW5kZXgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHN0ZXA/LmZpZWxkR3JvdXA/Lmxlbmd0aCkge1xuICAgICAgICAgIGNvbnN0IGNhbkFkdmFuY2UgPSB0aGlzLmNhbkFkdmFuY2VSZWN1cnNpdmVseShzdGVwLmZpZWxkR3JvdXApO1xuICAgICAgICAgIGlmICghY2FuQWR2YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5pc05hdmlnYXRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVBbmRHb05leHQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZUFuZEdvTmV4dCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYmFjaycgJiYgY3VycmVudEluZGV4ID4gMCkge1xuICAgICAgYXdhaXQgdGhpcy5nZXRQcmV2aW91c1N0ZXAoKTtcbiAgICAgIGlmICghdGhpcy5zaG93U3RlcHMpIHtcbiAgICAgICAgY29uc3QgaGFzQWN0aW9uU3RlcHMgPSBhd2FpdCB0aGlzLmZpZWxkPy5wcm9wcz8uW1xuICAgICAgICAgICdvblNlbGVjdGVkUGFnZUNoYW5naW5nJ1xuICAgICAgICBdKHtcbiAgICAgICAgICBmcm9tOiB0aGlzLmN1cnJlbnRTdGVwSW5kZXgsXG4gICAgICAgICAgdG86IHByZXZJbmRleCxcbiAgICAgICAgICBjdXJyZW50OiB0aGlzLmN1cnJlbnRTdGVwSW5kZXgsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChoYXNBY3Rpb25TdGVwcykge1xuICAgICAgICAgIGF3YWl0IHRoaXMudXBkYXRlQXBwRGF0YSh0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY3VycmVudFN0ZXBJbmRleCA9IHByZXZJbmRleDtcbiAgICAgICAgdGhpcy5sb2FkZWRTdGVwc1twcmV2SW5kZXhdID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdGFyZ2V0SW5kZXggPSB0aGlzLnN0ZXBwZXIuc2VsZWN0ZWRJbmRleCAtIDE7XG4gICAgICAgIGNvbnN0IGhhc0FjdGlvblN0ZXBzID0gYXdhaXQgdGhpcy5maWVsZD8ucHJvcHM/LltcbiAgICAgICAgICAnb25TZWxlY3RlZFBhZ2VDaGFuZ2luZydcbiAgICAgICAgXSh7XG4gICAgICAgICAgZnJvbTogdGhpcy5zdGVwcGVyLnNlbGVjdGVkSW5kZXgsXG4gICAgICAgICAgdG86IHRhcmdldEluZGV4LFxuICAgICAgICAgIGN1cnJlbnQ6IHRoaXMuc3RlcHBlci5zZWxlY3RlZEluZGV4LFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoaGFzQWN0aW9uU3RlcHMpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZUFwcERhdGEodHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0ZXBwZXIucHJldmlvdXMoKTtcbiAgICAgICAgdGhpcy5jdXJyZW50U3RlcEluZGV4ID0gdGhpcy5zdGVwcGVyLnNlbGVjdGVkSW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuaXNOYXZpZ2F0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVBbmRHb05leHQoKSB7XG4gICAgYXdhaXQgdGhpcy51cGRhdGVBcHBEYXRhKHRydWUpO1xuICAgIHRoaXMuZ29OZXh0KCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdvTmV4dCgpIHtcbiAgICBjb25zdCBjdXJyZW50SWR4ID0gdGhpcy5zdGVwcGVyLnNlbGVjdGVkSW5kZXg7XG4gICAgY29uc3QgbmV4dElkeCA9IGN1cnJlbnRJZHggKyAxO1xuXG4gICAgY29uc3QgaGFzQWN0aW9uU3RlcHMgPSBhd2FpdCB0aGlzLmZpZWxkPy5wcm9wcz8uWydvblNlbGVjdGVkUGFnZUNoYW5naW5nJ10oe1xuICAgICAgZnJvbTogY3VycmVudElkeCxcbiAgICAgIHRvOiBuZXh0SWR4LFxuICAgICAgY3VycmVudDogY3VycmVudElkeCxcbiAgICAgIGNhbGxiYWNrOiAoKSA9PiB0aGlzLmNoZWNrSWZGbG93SXNGaW5pc2hlZCgpLFxuICAgIH0pO1xuXG4gICAgaWYgKGhhc0FjdGlvblN0ZXBzKSB7XG4gICAgICBhd2FpdCB0aGlzLnVwZGF0ZUFwcERhdGEodHJ1ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5zdGVwcGVyLm5leHQoKTtcbiAgICB0aGlzLmN1cnJlbnRTdGVwSW5kZXggPSB0aGlzLnN0ZXBwZXIuc2VsZWN0ZWRJbmRleDtcbiAgICB0aGlzLmZpZWxkPy5wcm9wcz8uWydvblNlbGVjdGVkUGFnZUNoYW5nZWQnXSh0aGlzLnN0ZXBwZXIuc2VsZWN0ZWRJbmRleCk7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0lmRmxvd0lzRmluaXNoZWQoKSB7XG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGVwcGVyICYmXG4gICAgICB0aGlzLnN0ZXBwZXIuc2VsZWN0ZWRJbmRleCA9PT0gdGhpcy5maWVsZD8uZmllbGRHcm91cD8ubGVuZ3RoISAtIDFcbiAgICApIHtcbiAgICAgIHRoaXMuaXNGbG93RmluaXNoZWQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAodGhpcy5jdXJyZW50U3RlcEluZGV4ID09PSB0aGlzLmZpZWxkPy5maWVsZEdyb3VwPy5sZW5ndGghIC0gMSkge1xuICAgICAgdGhpcy5pc0Zsb3dGaW5pc2hlZCA9IHRydWU7XG4gICAgfVxuICAgIGlmICh0aGlzLmlzRmxvd0ZpbmlzaGVkKSB7XG4gICAgICBpZiAodGhpcy5maW5hbFN0ZXBGaWVsZENvbmZpZykge1xuICAgICAgICB0aGlzLnNob3dGaW5hbFN0ZXAgPSB0cnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5maWVsZD8ucHJvcHM/LlsnY29tcGxldGlvbkV2ZW50J10oKTtcbiAgICB9XG4gIH1cblxuICB2YWxpZGF0ZUZvcm0oc3RlcDogRm9ybWx5RmllbGRDb25maWcpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5wcm9wc1snZGVtb01vZGUnXSA9PT0gdHJ1ZSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGxldCBpc1ZhbGlkID0gdHJ1ZTtcbiAgICBsZXQgZmlyc3RJbnZhbGlkRmllbGRLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gICAgaWYgKHN0ZXAuZmllbGRHcm91cCkge1xuICAgICAgc3RlcC5maWVsZEdyb3VwLmZvckVhY2goKGYpID0+IHtcbiAgICAgICAgaWYgKGYuZmllbGRHcm91cCkge1xuICAgICAgICAgIGYuZmllbGRHcm91cC5mb3JFYWNoKChjOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGMuZm9ybUNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xuICAgICAgICAgICAgYy5mb3JtQ29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gICAgICAgICAgICBpZiAoYy5mb3JtQ29udHJvbC5lcnJvcnMgJiYgIWMuX2hpZGUpIHtcbiAgICAgICAgICAgICAgaXNWYWxpZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgIC8vIEZpbmQgdGhlIGZpcnN0IGludmFsaWQgZmllbGQga2V5IGZvciBzY3JvbGxpbmdcbiAgICAgICAgICAgICAgaWYgKCFmaXJzdEludmFsaWRGaWVsZEtleSAmJiBjLmtleSkge1xuICAgICAgICAgICAgICAgIGZpcnN0SW52YWxpZEZpZWxkS2V5ID0gYy5rZXk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gSWYgdmFsaWRhdGlvbiBmYWlsZWQgYW5kIHdlIGhhdmUgYSBmaWVsZCB0byBzY3JvbGwgdG8sIHVzZSB0aGUgc2Nyb2xsIHNlcnZpY2VcbiAgICBpZiAoIWlzVmFsaWQgJiYgZmlyc3RJbnZhbGlkRmllbGRLZXkpIHtcbiAgICAgIHRoaXMuc2Nyb2xsVG9FcnJvclNlcnZpY2Uuc2Nyb2xsVG9GaWVsZChmaXJzdEludmFsaWRGaWVsZEtleSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzVmFsaWQ7XG4gIH1cblxuICBpc1ZhbGlkKGZpZWxkOiBGb3JtbHlGaWVsZENvbmZpZyk6IGJvb2xlYW4ge1xuICAgIGlmIChmaWVsZC5rZXkpIHtcbiAgICAgIHJldHVybiBmaWVsZC5mb3JtQ29udHJvbD8udmFsaWQgPz8gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBmaWVsZC5maWVsZEdyb3VwXG4gICAgICA/IGZpZWxkLmZpZWxkR3JvdXAuZXZlcnkoKGYpID0+IHRoaXMuaXNWYWxpZChmKSlcbiAgICAgIDogdHJ1ZTtcbiAgfVxuXG4gIGlzQ3VzdG9tU3RlcChpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc3RlcFR5cGUgPSB0aGlzLmZpZWxkLmZpZWxkR3JvdXAhW2luZGV4XT8ucHJvcHM/LlsnZmx1eFR5cGUnXTtcbiAgICByZXR1cm4gc3RlcFR5cGUgPT09IEZsdXhUeXBlLkN1c3RvbTtcbiAgfVxuXG4gIGFzeW5jIG9uU3RlcENoYW5nZShldmVudDogYW55KSB7XG4gICAgaWYgKGV2ZW50ICYmIGV2ZW50LnNlbGVjdGVkSW5kZXgpIHtcbiAgICAgIGF3YWl0IHRoaXMudHJpZ2dlck9uUGFnZVNlbGVjdGVkRm9ySW5kZXgoZXZlbnQuc2VsZWN0ZWRJbmRleCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgdHJpZ2dlck9uUGFnZVNlbGVjdGVkRm9ySW5kZXgoaW5kZXg6IG51bWJlcikge1xuICAgIGNvbnN0IGZnID0gdGhpcy5maWVsZC5maWVsZEdyb3VwIVtpbmRleF0/LmZpZWxkR3JvdXA7XG4gICAgdGhpcy50cmlnZ2VyT25QYWdlU2VsZWN0ZWRSZWN1cnNpdmVseShmZyk7XG4gIH1cblxuICBhc3luYyB0cmlnZ2VyT25QYWdlU2VsZWN0ZWRSZWN1cnNpdmVseShmZzogYW55KSB7XG4gICAgaWYgKGZnICYmIGZnLmxlbmd0aCA+IDApIHtcbiAgICAgIGZnLmZvckVhY2goYXN5bmMgKGY6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCBjb21wb25lbnQgPSBmLnByb3BzPy5bJ2NvbXBvbmVudCddO1xuICAgICAgICBpZiAoY29tcG9uZW50Py5vblBhZ2VTZWxlY3RlZEFzeW5jKSB7XG4gICAgICAgICAgYXdhaXQgY29tcG9uZW50Py5vblBhZ2VTZWxlY3RlZEFzeW5jKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbXBvbmVudD8ub25QYWdlU2VsZWN0ZWQpIHtcbiAgICAgICAgICBjb21wb25lbnQ/Lm9uUGFnZVNlbGVjdGVkKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50cmlnZ2VyT25QYWdlU2VsZWN0ZWRSZWN1cnNpdmVseShmLmZpZWxkR3JvdXApO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgY2FuQWR2YW5jZVJlY3Vyc2l2ZWx5KGZnOiBhbnkpOiBib29sZWFuIHtcbiAgICBsZXQgdmFsaWQgPSB0cnVlO1xuICAgIGxldCBmaXJzdEludmFsaWRGaWVsZEtleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgICBpZiAoZmcgJiYgZmcubGVuZ3RoID4gMCkge1xuICAgICAgZmcuZm9yRWFjaChhc3luYyAoZjogYW55KSA9PiB7XG4gICAgICAgIGxldCBpbm5lclJlc3VsdCA9IHRydWU7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudCA9IGYucHJvcHM/LlsnY29tcG9uZW50J107XG4gICAgICAgIGlmIChjb21wb25lbnQ/LmNhbkFkdmFuY2UpIHtcbiAgICAgICAgICBpbm5lclJlc3VsdCA9IGNvbXBvbmVudD8uY2FuQWR2YW5jZSgpO1xuICAgICAgICAgIGlmIChpbm5lclJlc3VsdCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAvLyBUcnkgdG8gZ2V0IHRoZSBmaWVsZCBrZXkgZm9yIHNjcm9sbGluZ1xuICAgICAgICAgICAgaWYgKCFmaXJzdEludmFsaWRGaWVsZEtleSAmJiBmLmtleSkge1xuICAgICAgICAgICAgICBmaXJzdEludmFsaWRGaWVsZEtleSA9IGYua2V5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpbm5lclJlc3VsdCA9IHRoaXMuY2FuQWR2YW5jZVJlY3Vyc2l2ZWx5KGYuZmllbGRHcm91cCk7XG4gICAgICAgIGlmIChpbm5lclJlc3VsdCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICB2YWxpZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBJZiB2YWxpZGF0aW9uIGZhaWxlZCBhbmQgd2UgaGF2ZSBhIGZpZWxkIHRvIHNjcm9sbCB0bywgdXNlIHRoZSBzY3JvbGwgc2VydmljZVxuICAgIGlmICghdmFsaWQgJiYgZmlyc3RJbnZhbGlkRmllbGRLZXkpIHtcbiAgICAgIHRoaXMuc2Nyb2xsVG9FcnJvclNlcnZpY2Uuc2Nyb2xsVG9GaWVsZChmaXJzdEludmFsaWRGaWVsZEtleSk7XG4gICAgfSBlbHNlIGlmICghdmFsaWQpIHtcbiAgICAgIC8vIEZhbGxiYWNrOiB0cnkgdG8gc2Nyb2xsIHRvIGZpcnN0IGVycm9yIHVzaW5nIHRoZSBjb2xsZWN0b3IgZm9ybSdzIG1ldGhvZFxuICAgICAgdGhpcy5jb2xsZWN0b3JGb3JtLnNjcm9sbFRvRmlyc3RWYWxpZGF0aW9uRXJyb3IoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsaWQ7XG4gIH1cblxuICBnZXRDb21wb25lbnRzV2l0aERlZmF1bHRMYWJlbHMoKTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIFtGbHV4VHlwZS5LeWNdOiAnS3ljJyxcbiAgICB9O1xuICB9XG59XG4iLCI8ZGl2ICpuZ0lmPVwic2hvd1N0ZXBzOyBlbHNlIHNpbmdsZVN0ZXBUZW1wbGF0ZVwiPlxuICA8ZGl2IFtuZ1N0eWxlXT1cImNvbmNhdGVuYXRlZEZvcm1TdHlsZVwiPlxuICAgIDxmb3JtbHktZmllbGRcbiAgICAgICpuZ0lmPVwic2hvd0ZpbmFsU3RlcFwiXG4gICAgICBbZmllbGRdPVwiZmluYWxTdGVwRmllbGRDb25maWdcIlxuICAgID48L2Zvcm1seS1maWVsZD5cbiAgPC9kaXY+XG5cbiAgPG1hdC1ob3Jpem9udGFsLXN0ZXBwZXJcbiAgICAjc3RlcHBlclxuICAgICpuZ0lmPVwiIXNob3dGaW5hbFN0ZXBcIlxuICAgIFtsaW5lYXJdPVwidHJ1ZVwiXG4gICAgKHNlbGVjdGlvbkNoYW5nZSk9XCJvblN0ZXBDaGFuZ2UoJGV2ZW50KVwiXG4gICAgW25nU3R5bGVdPVwiY29uY2F0ZW5hdGVkRm9ybVN0eWxlXCJcbiAgPlxuICAgIDxtYXQtc3RlcCAqbmdGb3I9XCJsZXQgc3RlcCBvZiBmaWVsZC5maWVsZEdyb3VwOyBsZXQgaW5kZXggPSBpbmRleFwiPlxuICAgICAgPG5nLXRlbXBsYXRlIG1hdFN0ZXBMYWJlbCAqbmdJZj1cInNob3dTdGVwc0xhYmVsc1wiPlxuICAgICAgICB7eyBzdGVwLnByb3BzPy5sYWJlbCB9fVxuICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAqbmdJZj1cImJ1dHRvbnNWZXJ0aWNhbFBvc2l0aW9uID09ICd0b3AnXCJcbiAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiYnV0dG9uc0NvbnRhaW5lclwiXG4gICAgICAvPlxuXG4gICAgICA8aDMgW25nU3R5bGVdPVwiZmllbGQucHJvcHM/LlsnZGVzaWduJ11bJy5mb250LWhlYWRpbmctMyddIHx8IHt9XCI+XG4gICAgICAgIHt7IHN0ZXAucHJvcHM/LmRlc2NyaXB0aW9uIH19XG4gICAgICA8L2gzPlxuICAgICAgPGZvcm1seS1maWVsZCBbZmllbGRdPVwic3RlcFwiPjwvZm9ybWx5LWZpZWxkPlxuXG4gICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICpuZ0lmPVwiYnV0dG9uc1ZlcnRpY2FsUG9zaXRpb24gPT0gJ2JvdHRvbSdcIlxuICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJidXR0b25zQ29udGFpbmVyXCJcbiAgICAgIC8+XG4gICAgPC9tYXQtc3RlcD5cbiAgICA8IS0tIDxuZy10ZW1wbGF0ZSAqbmdJZj1cIiFzaG93U3RlcHNDb3VudGVyXCIgbWF0U3RlcHBlckljb249XCJudW1iZXJcIj5cbiAgICAgIDxtYXQtaWNvbj5yYWRpb19idXR0b25fY2hlY2tlZDwvbWF0LWljb24+XG4gICAgPC9uZy10ZW1wbGF0ZT4gLS0+XG4gIDwvbWF0LWhvcml6b250YWwtc3RlcHBlcj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI3NpbmdsZVN0ZXBUZW1wbGF0ZT5cbiAgPGRpdiBbbmdTdHlsZV09XCJjb25jYXRlbmF0ZWRGb3JtU3R5bGVcIj5cbiAgICA8Zm9ybWx5LWZpZWxkXG4gICAgICAqbmdJZj1cInNob3dGaW5hbFN0ZXBcIlxuICAgICAgW2ZpZWxkXT1cImZpbmFsU3RlcEZpZWxkQ29uZmlnXCJcbiAgICA+PC9mb3JtbHktZmllbGQ+XG4gIDwvZGl2PlxuICA8ZGl2XG4gICAgY2xhc3M9XCJzaW5nbGUtc3RlcC1jb250YWluZXJcIlxuICAgICpuZ0lmPVwiIXNob3dGaW5hbFN0ZXBcIlxuICAgIFtuZ1N0eWxlXT1cImNvbmNhdGVuYXRlZEZvcm1TdHlsZVwiXG4gID5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cInByb2dyZXNzLWJhci13cmFwcGVyXCJcbiAgICAgICpuZ0lmPVwic2hvd1Byb2dyZXNzQmFyXCJcbiAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgJ2JvcmRlci1yYWRpdXMnOiBwcm9ncmVzc0JhclN0eWxlcy5ib3JkZXJSYWRpdXMsXG4gICAgICAgICBoZWlnaHQ6IHByb2dyZXNzQmFyU3R5bGVzLmhlaWdodCxcbiAgICAgICAgIG92ZXJmbG93OiAnaGlkZGVuJ1xuICAgICAgfVwiXG4gICAgPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cInByb2dyZXNzLWJhci1maWxsXCJcbiAgICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAgIHdpZHRoOiAoKGN1cnJlbnRTdGVwSW5kZXggKyAxKSAvIHRvdGFsU3RlcHNDb3VudCkgKiAxMDAgKyAnJScsXG4gICAgICAgICAgYmFja2dyb3VuZDogZ2V0UHJvZ3Jlc3NCYXJGaWxsKCksXG4gICAgICAgICAgaGVpZ2h0OiAnMTAwJSdcbiAgICAgICAgfVwiXG4gICAgICA+PC9kaXY+XG4gICAgPC9kaXY+XG4gICA8ZGl2IGNsYXNzPVwic2luZ2xlLXN0ZXAtaGVhZGVyXCI+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwic2luZ2xlLXN0ZXAtaW5kaWNhdG9yXCJcbiAgICAgICAgKm5nSWY9XCJzaG93U3RlcHNDb3VudGVyO1wiXG4gICAgICA+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic3RlcC1jdXJyZW50XCI+e3sgY3VycmVudFN0ZXBJbmRleCArIDEgfX08L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic3RlcC1zZXBhcmF0b3JcIj4vPC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInN0ZXAtdG90YWxcIj57eyB0b3RhbFN0ZXBzQ291bnQgfX08L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxoMSAqbmdJZj1cInNob3dTdGVwc0xhYmVsc1wiIGNsYXNzPVwic2luZ2xlLXN0ZXAtbGFiZWxcIiAgW25nU3R5bGVdPVwiZmllbGQucHJvcHM/LlsnZGVzaWduJ11bJy5mb250LWhlYWRpbmctMSddIHx8IHt9XCI+XG4gICAgICAgIHt7IGZpZWxkLmZpZWxkR3JvdXAhW2N1cnJlbnRTdGVwSW5kZXhdIS5wcm9wcyEubGFiZWwgfX1cbiAgICAgIDwvaDE+XG4gICAgPC9kaXY+XG5cbiAgICA8bmctY29udGFpbmVyXG4gICAgICAqbmdJZj1cImJ1dHRvbnNWZXJ0aWNhbFBvc2l0aW9uID09ICd0b3AnXCJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImJ1dHRvbnNDb250YWluZXJcIlxuICAgIC8+XG5cbiAgICA8aDMgW25nU3R5bGVdPVwiZmllbGQucHJvcHM/LlsnZGVzaWduJ11bJy5mb250LWhlYWRpbmctMyddIHx8IHt9XCI+XG4gICAgICB7eyBmaWVsZCEuZmllbGRHcm91cCFbY3VycmVudFN0ZXBJbmRleF0hLnByb3BzIS5kZXNjcmlwdGlvbiB9fVxuICAgIDwvaDM+XG4gICAgPGZvcm1seS1maWVsZFxuICAgICAgKm5nSWY9XCJsb2FkZWRTdGVwc1tjdXJyZW50U3RlcEluZGV4XVwiXG4gICAgICBbZmllbGRdPVwiZmllbGQhLmZpZWxkR3JvdXAhW2N1cnJlbnRTdGVwSW5kZXhdXCJcbiAgICA+PC9mb3JtbHktZmllbGQ+XG5cbiAgICA8bmctY29udGFpbmVyXG4gICAgICAqbmdJZj1cImJ1dHRvbnNWZXJ0aWNhbFBvc2l0aW9uID09ICdib3R0b20nXCJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImJ1dHRvbnNDb250YWluZXJcIlxuICAgIC8+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNidXR0b25zQ29udGFpbmVyPlxuICA8bmctY29udGFpbmVyXG4gICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJcbiAgICAgIGJ1dHRvbnNUZW1wbGF0ZTtcbiAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgaW5kZXg6IGN1cnJlbnRTdGVwSW5kZXgsXG4gICAgICAgIHN0ZXA6IGZpZWxkIS5maWVsZEdyb3VwIVtjdXJyZW50U3RlcEluZGV4XVxuICAgICAgfVxuICAgIFwiXG4gID48L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjYnV0dG9uc1RlbXBsYXRlIGxldC1pbmRleD1cImluZGV4XCIgbGV0LXN0ZXA9XCJzdGVwXCI+XG4gIDxkaXZcbiAgICAqbmdJZj1cIiFpc0Zsb3dGaW5pc2hlZFwiXG4gICAgY2xhc3M9XCJidXR0b25zLWNvbnRhaW5lclwiXG4gICAgW25nU3R5bGVdPVwiZmllbGQucHJvcHM/LlsnZGVzaWduJ11bJy5idXR0b25zLWNvbnRhaW5lciddIHx8IHt9XCJcbiAgPlxuICAgIDxidXR0b24gbWF0LWZsYXQtYnV0dG9uICpuZ0lmPVwiaXNEZWJ1Z1wiIChjbGljayk9XCJyZXRyeUNsaWNrKHN0ZXApXCI+XG4gICAgICBEZWJ1ZyBSZXRyeVxuICAgIDwvYnV0dG9uPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGJ1dHRvbiBvZiBidXR0b25zR3JvdXBzW2luZGV4XVwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBtYXQtZmxhdC1idXR0b25cbiAgICAgICAgW2NvbG9yXT1cImJ1dHRvbi5jb2xvciB8fCAncHJpbWFyeSdcIlxuICAgICAgICBbdHlwZV09XCJidXR0b24udHlwZSA9PT0gJ3N1Ym1pdCcgPyAnc3VibWl0JyA6ICdidXR0b24nXCJcbiAgICAgICAgKGNsaWNrKT1cImJ1dHRvbkNsaWNrKGJ1dHRvbi50eXBlLCBzdGVwKVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJidXR0b24uZGlzYWJsZWQgfHwgaXNTYXZpbmdcIlxuICAgICAgICBbbmdTdHlsZV09XCJidXR0b24uc3R5bGVcIlxuICAgICAgPlxuICAgICAgICB7eyBidXR0b24ubGFiZWwgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxkaXYgKm5nSWY9XCJpc05hdmlnYXRpbmcgfHwgaXNTYXZpbmdcIiBjbGFzcz1cImxvYWRpbmctc3Bpbm5lclwiPlxuICAgICAgPG1hdC1zcGlubmVyIFtkaWFtZXRlcl09XCIzMlwiPjwvbWF0LXNwaW5uZXI+XG4gICAgPC9kaXY+XG4gICAgPGJ1dHRvbiBtYXQtZmxhdC1idXR0b24gKm5nSWY9XCJpc0RlYnVnXCIgKGNsaWNrKT1cImJ1dHRvbkNsaWNrKCduZXh0Jywgc3RlcClcIj5cbiAgICAgIERlYnVnIE5leHRcbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19
|