@mtna/web-form-angular 0.0.1
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/_index.scss +25 -0
- package/bundles/mtna-web-form-angular.umd.js +4982 -0
- package/bundles/mtna-web-form-angular.umd.js.map +1 -0
- package/esm2015/lib/core/animations.js +8 -0
- package/esm2015/lib/core/api-config.js +3 -0
- package/esm2015/lib/core/index.js +7 -0
- package/esm2015/lib/core/pipes/coerce-date-item.pipe.js +23 -0
- package/esm2015/lib/core/pipes/coerce-form-group.pipe.js +35 -0
- package/esm2015/lib/core/pipes/date-quarter.pipe.js +43 -0
- package/esm2015/lib/core/pipes/get-auto-complete.pipe.js +42 -0
- package/esm2015/lib/core/pipes/get-available-quarters.pipe.js +29 -0
- package/esm2015/lib/core/pipes/get-form-control-error.pipe.js +20 -0
- package/esm2015/lib/core/pipes/get-list-icon.pipe.js +53 -0
- package/esm2015/lib/core/pipes/get-object-type.pipe.js +17 -0
- package/esm2015/lib/core/pipes/get-selected-option.pipe.js +20 -0
- package/esm2015/lib/core/pipes/index.js +71 -0
- package/esm2015/lib/core/pipes/items-with-value.pipe.js +30 -0
- package/esm2015/lib/core/pipes/sanitize-html.pipe.js +23 -0
- package/esm2015/lib/core/services/api.service.js +67 -0
- package/esm2015/lib/core/services/form-manager.service.js +465 -0
- package/esm2015/lib/core/services/index.js +5 -0
- package/esm2015/lib/core/services/ng-form.service.js +150 -0
- package/esm2015/lib/core/services/ui.service.js +333 -0
- package/esm2015/lib/core/utilities/find-form-control.js +29 -0
- package/esm2015/lib/core/utilities/find-form-item.js +25 -0
- package/esm2015/lib/core/utilities/flatten-steps.js +10 -0
- package/esm2015/lib/core/utilities/generate-form-steps.js +25 -0
- package/esm2015/lib/core/utilities/index.js +9 -0
- package/esm2015/lib/core/utilities/is-form-group.js +6 -0
- package/esm2015/lib/core/utilities/serializer-util.js +358 -0
- package/esm2015/lib/core/utilities/update-step-status.js +38 -0
- package/esm2015/lib/core/validators/index.js +3 -0
- package/esm2015/lib/core/validators/instant-validation-result-error-state-matcher.js +23 -0
- package/esm2015/lib/core/validators/validation-result-validator.js +19 -0
- package/esm2015/lib/file-upload/file-upload.component.js +66 -0
- package/esm2015/lib/file-upload/index.js +2 -0
- package/esm2015/lib/form/base-form-item.model.js +2 -0
- package/esm2015/lib/form/form-disabler.component.js +38 -0
- package/esm2015/lib/form/form-item.directive.js +22 -0
- package/esm2015/lib/form/form.component.js +250 -0
- package/esm2015/lib/form/form.module.js +214 -0
- package/esm2015/lib/form/index.js +5 -0
- package/esm2015/lib/form/white-list.model.js +11 -0
- package/esm2015/lib/form-item-controls/base-form-item-control.directive.js +58 -0
- package/esm2015/lib/form-item-controls/base-parent-item-control.directive.js +42 -0
- package/esm2015/lib/form-item-controls/base-single-selection-parent.directive.js +53 -0
- package/esm2015/lib/form-item-controls/date-range.component.js +84 -0
- package/esm2015/lib/form-item-controls/date.component.js +134 -0
- package/esm2015/lib/form-item-controls/dropdown.component.js +109 -0
- package/esm2015/lib/form-item-controls/index.js +8 -0
- package/esm2015/lib/form-item-controls/input.component.js +149 -0
- package/esm2015/lib/form-item-controls/year-quarter-range.component.js +75 -0
- package/esm2015/lib/form-item-controls/year-quarter.component.js +228 -0
- package/esm2015/lib/form-stepper/form-step-group.component.js +95 -0
- package/esm2015/lib/form-stepper/form-step-group.pipe.js +20 -0
- package/esm2015/lib/form-stepper/form-step.component.js +110 -0
- package/esm2015/lib/form-stepper/form-step.util.js +28 -0
- package/esm2015/lib/form-stepper/form-stepper.component.js +115 -0
- package/esm2015/lib/form-stepper/form-stepper.module.js +53 -0
- package/esm2015/lib/form-stepper/index.js +8 -0
- package/esm2015/lib/form-stepper/models/base-form-step.model.js +6 -0
- package/esm2015/lib/form-stepper/models/form-step-group.model.js +13 -0
- package/esm2015/lib/form-stepper/models/form-step.model.js +12 -0
- package/esm2015/lib/form-stepper/models/index.js +4 -0
- package/esm2015/lib/groups/form-item-dialog-data.model.js +14 -0
- package/esm2015/lib/groups/group-components.js +646 -0
- package/esm2015/lib/groups/index.js +3 -0
- package/esm2015/lib/groups/repeatable-item.component.js +23 -0
- package/esm2015/lib/item-header/index.js +2 -0
- package/esm2015/lib/item-header/item-header.component.js +108 -0
- package/esm2015/lib/static-form-items/index.js +3 -0
- package/esm2015/lib/static-form-items/ordered-list-item.js +50 -0
- package/esm2015/lib/static-form-items/unordered-list-item.js +52 -0
- package/esm2015/lib/step-card/index.js +2 -0
- package/esm2015/lib/step-card/step-card.component.js +53 -0
- package/esm2015/mtna-web-form-angular.js +5 -0
- package/esm2015/public-api.js +10 -0
- package/fesm2015/mtna-web-form-angular.js +4614 -0
- package/fesm2015/mtna-web-form-angular.js.map +1 -0
- package/lib/_index.scss +25 -0
- package/lib/core/_all-color.scss +25 -0
- package/lib/core/_all-theme.scss +28 -0
- package/lib/core/_all-typography.scss +25 -0
- package/lib/core/_core-theme.scss +43 -0
- package/lib/core/animations.d.ts +2 -0
- package/lib/core/api-config.d.ts +5 -0
- package/lib/core/index.d.ts +6 -0
- package/lib/core/pipes/coerce-date-item.pipe.d.ts +11 -0
- package/lib/core/pipes/coerce-form-group.pipe.d.ts +23 -0
- package/lib/core/pipes/date-quarter.pipe.d.ts +7 -0
- package/lib/core/pipes/get-auto-complete.pipe.d.ts +7 -0
- package/lib/core/pipes/get-available-quarters.pipe.d.ts +8 -0
- package/lib/core/pipes/get-form-control-error.pipe.d.ts +14 -0
- package/lib/core/pipes/get-list-icon.pipe.d.ts +7 -0
- package/lib/core/pipes/get-object-type.pipe.d.ts +7 -0
- package/lib/core/pipes/get-selected-option.pipe.d.ts +8 -0
- package/lib/core/pipes/index.d.ts +28 -0
- package/lib/core/pipes/items-with-value.pipe.d.ts +13 -0
- package/lib/core/pipes/sanitize-html.pipe.d.ts +10 -0
- package/lib/core/services/api.service.d.ts +41 -0
- package/lib/core/services/form-manager.service.d.ts +184 -0
- package/lib/core/services/index.d.ts +4 -0
- package/lib/core/services/ng-form.service.d.ts +76 -0
- package/lib/core/services/ui.service.d.ts +123 -0
- package/lib/core/utilities/find-form-control.d.ts +11 -0
- package/lib/core/utilities/find-form-item.d.ts +10 -0
- package/lib/core/utilities/flatten-steps.d.ts +7 -0
- package/lib/core/utilities/generate-form-steps.d.ts +3 -0
- package/lib/core/utilities/index.d.ts +8 -0
- package/lib/core/utilities/is-form-group.d.ts +3 -0
- package/lib/core/utilities/serializer-util.d.ts +81 -0
- package/lib/core/utilities/update-step-status.d.ts +14 -0
- package/lib/core/validators/index.d.ts +2 -0
- package/lib/core/validators/instant-validation-result-error-state-matcher.d.ts +13 -0
- package/lib/core/validators/validation-result-validator.d.ts +12 -0
- package/lib/file-upload/file-upload.component.d.ts +23 -0
- package/lib/file-upload/index.d.ts +1 -0
- package/lib/form/base-form-item.model.d.ts +15 -0
- package/lib/form/form-disabler.component.d.ts +6 -0
- package/lib/form/form-item.directive.d.ts +13 -0
- package/lib/form/form.component.d.ts +89 -0
- package/lib/form/form.module.d.ts +52 -0
- package/lib/form/index.d.ts +4 -0
- package/lib/form/white-list.model.d.ts +6 -0
- package/lib/form-item-controls/_date-item-theme.scss +29 -0
- package/lib/form-item-controls/_form-control-theme.scss +28 -0
- package/lib/form-item-controls/_year-quarter-item-theme.scss +28 -0
- package/lib/form-item-controls/base-form-item-control.directive.d.ts +26 -0
- package/lib/form-item-controls/base-parent-item-control.directive.d.ts +19 -0
- package/lib/form-item-controls/base-single-selection-parent.directive.d.ts +26 -0
- package/lib/form-item-controls/date-range.component.d.ts +12 -0
- package/lib/form-item-controls/date.component.d.ts +24 -0
- package/lib/form-item-controls/dropdown.component.d.ts +9 -0
- package/lib/form-item-controls/index.d.ts +7 -0
- package/lib/form-item-controls/input.component.d.ts +14 -0
- package/lib/form-item-controls/year-quarter-range.component.d.ts +9 -0
- package/lib/form-item-controls/year-quarter.component.d.ts +33 -0
- package/lib/form-stepper/_form-step-group-theme.scss +43 -0
- package/lib/form-stepper/_form-stepper-theme.scss +72 -0
- package/lib/form-stepper/form-step-group.component.d.ts +23 -0
- package/lib/form-stepper/form-step-group.pipe.d.ts +11 -0
- package/lib/form-stepper/form-step.component.d.ts +27 -0
- package/lib/form-stepper/form-step.util.d.ts +27 -0
- package/lib/form-stepper/form-stepper.component.d.ts +35 -0
- package/lib/form-stepper/form-stepper.module.d.ts +18 -0
- package/lib/form-stepper/index.d.ts +7 -0
- package/lib/form-stepper/models/base-form-step.model.d.ts +4 -0
- package/lib/form-stepper/models/form-step-group.model.d.ts +8 -0
- package/lib/form-stepper/models/form-step.model.d.ts +11 -0
- package/lib/form-stepper/models/index.d.ts +3 -0
- package/lib/groups/_checkbox-theme.scss +62 -0
- package/lib/groups/_form-group-theme.scss +32 -0
- package/lib/groups/_multiple-choice-theme.scss +65 -0
- package/lib/groups/_repeatable-item-theme.scss +28 -0
- package/lib/groups/form-item-dialog-data.model.d.ts +13 -0
- package/lib/groups/group-components.d.ts +221 -0
- package/lib/groups/index.d.ts +2 -0
- package/lib/groups/repeatable-item.component.d.ts +5 -0
- package/lib/item-header/_item-header-theme.scss +28 -0
- package/lib/item-header/index.d.ts +1 -0
- package/lib/item-header/item-header.component.d.ts +35 -0
- package/lib/static-form-items/index.d.ts +2 -0
- package/lib/static-form-items/ordered-list-item.d.ts +11 -0
- package/lib/static-form-items/unordered-list-item.d.ts +11 -0
- package/lib/step-card/_step-card-theme.scss +42 -0
- package/lib/step-card/index.d.ts +1 -0
- package/lib/step-card/step-card.component.d.ts +21 -0
- package/mtna-web-form-angular.d.ts +5 -0
- package/package.json +43 -0
- package/public-api.d.ts +9 -0
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { isType } from '@mtna/core-ts';
|
|
3
|
+
import { isConditionalItem, isForm, isFormItemGroupImpl, isOptionGroupItemImpl, isOptionItemImpl, isRepeatableItem, isSection, isTableItem, MtnaWfFormItemChange, } from '@mtna/web-form-ts';
|
|
4
|
+
import { Subject } from 'rxjs';
|
|
5
|
+
import { take } from 'rxjs/operators';
|
|
6
|
+
import { findFormControl, MtnaWfSerializer } from '../utilities';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "./api.service";
|
|
9
|
+
import * as i2 from "./ng-form.service";
|
|
10
|
+
import * as i3 from "./ui.service";
|
|
11
|
+
/**
|
|
12
|
+
* Allows a caller to (de)serializae an MtnaForm. It contains the determining logic for returning specific form controls
|
|
13
|
+
* and deserializing new MtnaForms from the reactive values, as well as registering custom Form Items & functions.
|
|
14
|
+
*
|
|
15
|
+
* @export
|
|
16
|
+
*/
|
|
17
|
+
export class MtnaWfManagerService {
|
|
18
|
+
constructor(apiService, ngFormManager, uiService) {
|
|
19
|
+
this.apiService = apiService;
|
|
20
|
+
this.ngFormManager = ngFormManager;
|
|
21
|
+
this.uiService = uiService;
|
|
22
|
+
this.components = new Map();
|
|
23
|
+
this.formChange$ = new Subject();
|
|
24
|
+
/** A map of all {@link FormItemValidationResult} keyed on id */
|
|
25
|
+
this._formItemValidationResults = {};
|
|
26
|
+
/**
|
|
27
|
+
* Any FormService extension class should override this method in order to call the
|
|
28
|
+
* dynamicWebFormItemBuilder/dynamicReactiveFormControlBuilder methods. During web form generation, this method is checked &
|
|
29
|
+
* the current FormItem is passed in, which can be used by the overriding method.
|
|
30
|
+
*
|
|
31
|
+
* @example dynamicFormConditional = (item: FormItem) => item.itemId.includes({some itemId})
|
|
32
|
+
*
|
|
33
|
+
*/
|
|
34
|
+
this.dynamicFormConditional = () => false;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Observable stream of MtnaForm changes. Used to inform a subscriber that an MtnaForm has been changed.
|
|
38
|
+
*
|
|
39
|
+
* @returns Observable<MtnaForm> to which a caller can subscribe
|
|
40
|
+
*/
|
|
41
|
+
get formChanges() {
|
|
42
|
+
return this.formChange$.asObservable();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Adds or removes a FormItem from the form & modifies other affected FormItems
|
|
46
|
+
* @param change MtnaWfFormItemChange
|
|
47
|
+
*/
|
|
48
|
+
changeMtnaFormItem(change) {
|
|
49
|
+
if (!this._mtnaForm) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (change.actionType === 'REMOVE') {
|
|
53
|
+
// remove the repeatable item from the mtnaform
|
|
54
|
+
let newForm = this._modifyFormItem(this._mtnaForm, change);
|
|
55
|
+
// modify the conditions of all effected form items
|
|
56
|
+
newForm = this._modifyFormItemConditions(newForm, change);
|
|
57
|
+
this.ngFormManager.removeControl(change.id, change.parentIds);
|
|
58
|
+
this.formChange$.next(newForm);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
this.apiService
|
|
62
|
+
.getRepeatableItem(this._mtnaForm.instanceId, change.id)
|
|
63
|
+
.pipe(take(1))
|
|
64
|
+
.subscribe((newItem) => {
|
|
65
|
+
const newFormControl = this.serializeMtnaFormItem(newItem);
|
|
66
|
+
if (newFormControl && this._mtnaForm) {
|
|
67
|
+
this.ngFormManager.addControl(newItem.instanceId, change.parentIds, newFormControl);
|
|
68
|
+
// Add the new repeatable item into the mtnaform
|
|
69
|
+
let newForm = this._modifyFormItem(this._mtnaForm, Object.assign(Object.assign({}, change), { id: newItem.instanceId }), newItem);
|
|
70
|
+
// Generate a list of all formitem conditions needing change & modify those items in the form
|
|
71
|
+
const conditionChanges = this.generateConditionChangeArray(newItem, 'ADD');
|
|
72
|
+
newForm = this._modifyFormItemConditions(newForm, Object.assign(Object.assign({}, change), { conditionChanges }));
|
|
73
|
+
this.itemToggleQue = conditionChanges;
|
|
74
|
+
// emit the new mtnaform
|
|
75
|
+
this.formChange$.next(newForm);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Returns a ConditionChange array for items existing in the <item> which enable/disable FormItems outside the <item>'s scope.
|
|
82
|
+
* @param item FormItem that effects the condition of other FormItems
|
|
83
|
+
* @param action Whether this item was added (ADD), or removed (REMOVE)
|
|
84
|
+
* @returns Array<ConditionChange>
|
|
85
|
+
*/
|
|
86
|
+
generateConditionChangeArray(item, action) {
|
|
87
|
+
const internalMap = {};
|
|
88
|
+
this._buildInternalIdsMap(item, internalMap);
|
|
89
|
+
const conditionChanges = new Array();
|
|
90
|
+
this._buildConditionChangeArray(item, conditionChanges, internalMap, action);
|
|
91
|
+
return conditionChanges;
|
|
92
|
+
}
|
|
93
|
+
/** @returns The top level validation results (usually the errors), keyed on ID. */
|
|
94
|
+
getFormItemValidationResults() {
|
|
95
|
+
return this._formItemValidationResults;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Returns a new MtnaForm using the previous MtnaForm & reactive form values.
|
|
99
|
+
*
|
|
100
|
+
* @param mtnaForm MtnaForm requiring value insertion
|
|
101
|
+
* @param ngFormValues JSON object of ngForm values
|
|
102
|
+
* @returns new MtnaForm
|
|
103
|
+
*/
|
|
104
|
+
insertNewValues(mtnaForm, ngFormValues) {
|
|
105
|
+
return Object.assign(Object.assign({}, mtnaForm), { items: MtnaWfSerializer.insertFormItemValues(mtnaForm, ngFormValues, this.uiService.getDisabledStates(), this.dynamicFormConditional, this.dynamicWebFormItemBuilder) });
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Serializes a Form | FormItem into FormControl(s)
|
|
109
|
+
*
|
|
110
|
+
* @param item Form | FormItem requiring serialization
|
|
111
|
+
* @returns FormGroup | FormControl
|
|
112
|
+
*/
|
|
113
|
+
serializeMtnaFormItem(item) {
|
|
114
|
+
return MtnaWfSerializer.determineSerializeFunctionToUse(item, this, this.dynamicFormConditional, this.dynamicReactiveFormControlBuilder);
|
|
115
|
+
}
|
|
116
|
+
//#region Custom Component/Function Registration
|
|
117
|
+
getDynamicComponent(id) {
|
|
118
|
+
return this.components.get(id);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Registers a map of components to be dynamically rendered inside an MtnaForm.
|
|
122
|
+
*
|
|
123
|
+
* @param components the map of components that a ValueItem will use for rendering
|
|
124
|
+
* @prop string - the type(itemId suffix) of component, used for retrieval
|
|
125
|
+
* @prop Type - the component to be rendered, an extension of BaseFormItem
|
|
126
|
+
*/
|
|
127
|
+
registerDynamicComponents(components) {
|
|
128
|
+
this.components = components;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Sets an MtnaForm on the service
|
|
132
|
+
* @param form MtnaForm to be used for internal modification
|
|
133
|
+
*/
|
|
134
|
+
setMtnaForm(form) {
|
|
135
|
+
this._mtnaForm = Object.assign({}, form);
|
|
136
|
+
if (!!this.itemToggleQue && !!this.itemToggleQue.length) {
|
|
137
|
+
// The form needs time to rerender, so we push this loop to the end of the stack
|
|
138
|
+
setTimeout(() => {
|
|
139
|
+
if (this.itemToggleQue) {
|
|
140
|
+
for (const change of this.itemToggleQue) {
|
|
141
|
+
this.uiService.toggleFormItems(change.enabledItems, change.disabledItems, !!change.enable, change.enablerId, true);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
this.itemToggleQue = null;
|
|
145
|
+
}, 0);
|
|
146
|
+
}
|
|
147
|
+
// Keep track of any errors coming from the server and revalidate those controls
|
|
148
|
+
this._updateServerSideErrors();
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Function to be overridden by extended service in order to handle form generation for any application-specific dynamic form components.
|
|
152
|
+
* Should return a new ValueItem<any>.
|
|
153
|
+
* Step 3
|
|
154
|
+
*
|
|
155
|
+
* @example dynamicWebFormItemBuilder(section: Section | Form, item: FormItem, ngFormValue: any): ValueItem {
|
|
156
|
+
* const newValue = this.generateNewValue(item, rfValue, section);
|
|
157
|
+
* return { ...item, ...newValue }
|
|
158
|
+
* }
|
|
159
|
+
* @param section the current FormSection
|
|
160
|
+
* @param item the current FormItem
|
|
161
|
+
* @param ngFormValue the ngForm JSON value
|
|
162
|
+
* @returns a new ValueItem
|
|
163
|
+
*/
|
|
164
|
+
dynamicWebFormItemBuilder(
|
|
165
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
166
|
+
section, item, ngFormValue, disabledState
|
|
167
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
168
|
+
) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Function to be overridden by extended service in order to handle reactive form generation
|
|
173
|
+
* for any application-specific dynamic form components.
|
|
174
|
+
* Should return FormControl | FormGroup.
|
|
175
|
+
*
|
|
176
|
+
* @example dynamicReactiveFormControlBuilder(item: FormItem) {
|
|
177
|
+
* return this.buildFormControlForDynamicComponent(item: FormItem);
|
|
178
|
+
* }
|
|
179
|
+
* @param item FormItem used to generate form controls
|
|
180
|
+
* @returns FormControl | FormGroup
|
|
181
|
+
*/
|
|
182
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
183
|
+
dynamicReactiveFormControlBuilder(item) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region INTERNAL METHODS
|
|
188
|
+
/**
|
|
189
|
+
* Recursively traverses a Form to insert or remove a designated FormItem.
|
|
190
|
+
* @param item MtnaForm to search through
|
|
191
|
+
* @param change: MtnaWfFormItemChange for adding or removing a FormItem
|
|
192
|
+
* @param newItem FormItem to add to its parent
|
|
193
|
+
*/
|
|
194
|
+
_modifyFormItem(item, change, newItem) {
|
|
195
|
+
if (!change.parentIds.length) {
|
|
196
|
+
// At this point, we reach the Parent FormItem
|
|
197
|
+
if (change.actionType === 'REPLACE') {
|
|
198
|
+
if ('items' in item) {
|
|
199
|
+
const index = item.items.findIndex((i) => i.instanceId === (newItem === null || newItem === void 0 ? void 0 : newItem.instanceId));
|
|
200
|
+
const newItems = [...item.items];
|
|
201
|
+
if (newItem) {
|
|
202
|
+
newItems.splice(index, 1, newItem);
|
|
203
|
+
}
|
|
204
|
+
return Object.assign(Object.assign({}, item), { items: newItems });
|
|
205
|
+
}
|
|
206
|
+
return item;
|
|
207
|
+
}
|
|
208
|
+
else if (isRepeatableItem(item)) {
|
|
209
|
+
return Object.assign(Object.assign({}, item), { items: change.actionType === 'ADD' ? item.items.concat(newItem || []) : item.items.filter((i) => i.instanceId !== change.id) });
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
return item;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (isForm(item) || isSection(item) || isFormItemGroupImpl(item) || isRepeatableItem(item)) {
|
|
216
|
+
const items = [...item.items];
|
|
217
|
+
const indexToModify = item.items.findIndex((i) => i.instanceId === change.parentIds[0]);
|
|
218
|
+
const itemToModify = item.items[indexToModify];
|
|
219
|
+
items.splice(indexToModify, 1, this._modifyFormItem(itemToModify, Object.assign(Object.assign({}, change), { parentIds: change.parentIds.slice(1) }), newItem));
|
|
220
|
+
return Object.assign(Object.assign({}, item), { items });
|
|
221
|
+
}
|
|
222
|
+
else if (isTableItem(item)) {
|
|
223
|
+
return this._modifyTableItem(item, change, newItem);
|
|
224
|
+
}
|
|
225
|
+
else if (isOptionItemImpl(item) || isOptionGroupItemImpl(item)) {
|
|
226
|
+
return this._modifyOptionItem(item, change, newItem)[0];
|
|
227
|
+
}
|
|
228
|
+
return item;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Traverses an OptionItemMap of a FormItem to insert or remove a designated FormItem
|
|
232
|
+
* @param optionItem FormItem with an optionItemMap, e.g. OptionItemImpl | OptionGroupItemImpl
|
|
233
|
+
* @param change MtnaWfFormItemChange for adding or removing a FormItem
|
|
234
|
+
* @param newItem FormItem to be added to its parent
|
|
235
|
+
* @returns FormItem with an optionItemMap containing FormItems
|
|
236
|
+
*/
|
|
237
|
+
_modifyOptionItem(optionItem, change, newItem) {
|
|
238
|
+
let found = false;
|
|
239
|
+
const optionItemMap = {};
|
|
240
|
+
// Loop through the map and set the items to a new map
|
|
241
|
+
// Check if any FormItem in the map matches the next parent ID
|
|
242
|
+
for (const id in optionItem.optionItemMap) {
|
|
243
|
+
if (Object.prototype.hasOwnProperty.call(optionItem.optionItemMap, id)) {
|
|
244
|
+
// If one matches, modify & set it on the new map
|
|
245
|
+
if (optionItem.optionItemMap[id].instanceId === change.parentIds[0]) {
|
|
246
|
+
found = true;
|
|
247
|
+
optionItemMap[id] = this._modifyFormItem(optionItem.optionItemMap[id], Object.assign(Object.assign({}, change), { parentIds: change.parentIds.slice(1) }), newItem);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
optionItemMap[id] = optionItem.optionItemMap[id];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// return the item with its new optionItemMap, & whether we found the matching item
|
|
255
|
+
return [Object.assign(Object.assign({}, optionItem), { optionItemMap }), found];
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Traverses table rows to insert or remove a FormItem
|
|
259
|
+
* @param tableItem TableItem to traverse
|
|
260
|
+
* @param change MtnaWfFormItemChange for adding or removing a FormItem
|
|
261
|
+
* @param newItem FormItem to be added to its parent
|
|
262
|
+
* @returns TableItem with a FormItem added or removed
|
|
263
|
+
*/
|
|
264
|
+
_modifyTableItem(tableItem, change, newItem) {
|
|
265
|
+
let found = false;
|
|
266
|
+
// Map the table rows to find the FormItem with matching instanceId
|
|
267
|
+
const tableRows = tableItem.tableRows.map((row) => {
|
|
268
|
+
// If the item was found, skip mapping further rows
|
|
269
|
+
if (!found) {
|
|
270
|
+
return Object.assign(Object.assign({}, row), { items: row.items.map((rowItem) => {
|
|
271
|
+
// If we found the next matching FormItem, toggle 'found', and return the modified FormItem
|
|
272
|
+
if (!!rowItem && rowItem.instanceId === change.parentIds[0]) {
|
|
273
|
+
found = true;
|
|
274
|
+
return this._modifyFormItem(rowItem, Object.assign(Object.assign({}, change), { parentIds: change.parentIds.slice(1) }), newItem);
|
|
275
|
+
}
|
|
276
|
+
// If the FormItem instanceId doesn't match, but it has FormItems in its 'optionItemMap',
|
|
277
|
+
// We need to check if a matching FormItem exists in its map
|
|
278
|
+
if ('optionItemMap' in rowItem) {
|
|
279
|
+
const returned = this._modifyOptionItem(rowItem, change, newItem);
|
|
280
|
+
found = returned[1];
|
|
281
|
+
return returned[0];
|
|
282
|
+
}
|
|
283
|
+
return rowItem;
|
|
284
|
+
}) });
|
|
285
|
+
}
|
|
286
|
+
return row;
|
|
287
|
+
});
|
|
288
|
+
return Object.assign(Object.assign({}, tableItem), { tableRows });
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Adds or removes instanceIds from the 'itemIds' in a FormItem's condition
|
|
292
|
+
* @param form MtnaForm to search through & replace formitems with the new condition
|
|
293
|
+
* @param change The change that recently occurred in the mtnaForm
|
|
294
|
+
*/
|
|
295
|
+
_modifyFormItemConditions(form, change) {
|
|
296
|
+
let newForm = form;
|
|
297
|
+
if (change.conditionChanges) {
|
|
298
|
+
const formItems = {};
|
|
299
|
+
for (const cc of change.conditionChanges) {
|
|
300
|
+
for (const toggledId of [...cc.enabledItems, ...cc.disabledItems]) {
|
|
301
|
+
let formItem = formItems[toggledId];
|
|
302
|
+
const formItemComponent = this.uiService.getItem(toggledId);
|
|
303
|
+
if (!formItem && (formItemComponent === null || formItemComponent === void 0 ? void 0 : formItemComponent.item)) {
|
|
304
|
+
formItem = formItemComponent === null || formItemComponent === void 0 ? void 0 : formItemComponent.item;
|
|
305
|
+
}
|
|
306
|
+
if (isConditionalItem(formItem) && formItem.condition) {
|
|
307
|
+
const itemConditionItemIds = formItem.condition.itemIds || [];
|
|
308
|
+
const itemIds = change.actionType === 'ADD'
|
|
309
|
+
? [...itemConditionItemIds, cc.enablerId]
|
|
310
|
+
: itemConditionItemIds.filter((i) => i !== cc.enablerId);
|
|
311
|
+
const newItem = Object.assign(Object.assign({}, formItem), { condition: Object.assign(Object.assign({}, formItem.condition), { itemIds }) });
|
|
312
|
+
const newChange = new MtnaWfFormItemChange(newItem.instanceId, (formItemComponent === null || formItemComponent === void 0 ? void 0 : formItemComponent.parentIds) || [], 'REPLACE');
|
|
313
|
+
newForm = this._modifyFormItem(newForm, newChange, newItem);
|
|
314
|
+
formItems[toggledId] = newItem;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (change.actionType === 'REMOVE') {
|
|
318
|
+
this.uiService.toggleFormItems(cc.enabledItems, cc.disabledItems, !!cc.enable, cc.enablerId);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return newForm;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Builds a map of all instanceIds inside an item. Checks 'items' & 'optionItemMap'
|
|
326
|
+
* @param item Item to recurse
|
|
327
|
+
* @param idMap map of the item's internal instanceIds
|
|
328
|
+
*/
|
|
329
|
+
_buildInternalIdsMap(item, idMap) {
|
|
330
|
+
idMap[item.instanceId] = true;
|
|
331
|
+
if (isType(item, 'items')) {
|
|
332
|
+
const items = item.items;
|
|
333
|
+
for (const subItem of items) {
|
|
334
|
+
this._buildInternalIdsMap(subItem, idMap);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
else if (isType(item, 'optionItemMap')) {
|
|
338
|
+
const map = item.optionItemMap;
|
|
339
|
+
for (const id in map) {
|
|
340
|
+
if (Object.prototype.hasOwnProperty.call(map, id)) {
|
|
341
|
+
this._buildInternalIdsMap(map[id], idMap);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Builds an array of ConditionChanges to be implemented in an MtnaForm.
|
|
348
|
+
* @param item FormItem that was added/removed, which affects conditions of other FormItems
|
|
349
|
+
* @param changes Array to build up
|
|
350
|
+
* @param internalIdMap Map of all instanceIds located in the item; in order to exclude them from the condition changes
|
|
351
|
+
* @param action Whether the item was added or removed
|
|
352
|
+
*/
|
|
353
|
+
_buildConditionChangeArray(item, changes, internalIdMap, action) {
|
|
354
|
+
if (isOptionItemImpl(item)) {
|
|
355
|
+
const enable = !!action && action === 'ADD' ? item.option.selected || item.value === item.option.option.id : false;
|
|
356
|
+
this._pushConditionToArray(item.instanceId, item.option.enabledItems, item.option.disabledItems, changes, internalIdMap, enable);
|
|
357
|
+
this._buildArrayFromOptionItemMap(item, changes, internalIdMap);
|
|
358
|
+
}
|
|
359
|
+
else if (isOptionGroupItemImpl(item)) {
|
|
360
|
+
for (const option of item.options) {
|
|
361
|
+
const enable = !!action && action === 'ADD' ? option.selected || (!!item.value && item.value.some((v) => v === option.option.id)) : false;
|
|
362
|
+
this._pushConditionToArray(item.instanceId, option.enabledItems, option.disabledItems, changes, internalIdMap, enable);
|
|
363
|
+
}
|
|
364
|
+
this._buildArrayFromOptionItemMap(item, changes, internalIdMap, action);
|
|
365
|
+
}
|
|
366
|
+
else if (isType(item, 'items')) {
|
|
367
|
+
const items = item.items;
|
|
368
|
+
for (const subItem of items) {
|
|
369
|
+
this._buildConditionChangeArray(subItem, changes, internalIdMap, action);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Builds an array of ConditionChanges from an item's optionItemMap
|
|
375
|
+
* @param item FormItem with an optionItemMap
|
|
376
|
+
* @param conditions Array of ConditionChanges to push on new changes
|
|
377
|
+
* @param itemMap map of instanceIds exisiting in an item; in order to exclude them from the changes
|
|
378
|
+
* @param action Whether an item was added or removed
|
|
379
|
+
*/
|
|
380
|
+
_buildArrayFromOptionItemMap(item, conditions, itemMap, action) {
|
|
381
|
+
if (item.optionItemMap) {
|
|
382
|
+
for (const id in item.optionItemMap) {
|
|
383
|
+
if (Object.prototype.hasOwnProperty.call(item.optionItemMap, id)) {
|
|
384
|
+
const subItem = item.optionItemMap[id];
|
|
385
|
+
this._buildConditionChangeArray(subItem, conditions, itemMap, action);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Pushes a new ConditionChange onto the conditions array. If a ConditionChange with matching id exists,
|
|
392
|
+
* it merges the new values into it
|
|
393
|
+
* @param enablerId instanceId of the item that enables other FormItems
|
|
394
|
+
* @param enabled the item's 'enabledItems' array
|
|
395
|
+
* @param disabled the item's 'disabledItems' array
|
|
396
|
+
* @param conditions Array of ConditionChanges to build up
|
|
397
|
+
* @param itemMap map of instanceIds inside an item; to ensure no internal ids are included in a change
|
|
398
|
+
* @param enable Whether the 'enabledItems' should toggled enabled
|
|
399
|
+
*/
|
|
400
|
+
_pushConditionToArray(enablerId, enabled, disabled, conditions, itemMap, enable) {
|
|
401
|
+
const enabledItems = enabled.filter((e) => !itemMap[e]);
|
|
402
|
+
const disabledItems = disabled.filter((d) => !itemMap[d]);
|
|
403
|
+
if (!!enabledItems.length || !!disabledItems.length) {
|
|
404
|
+
const index = conditions.findIndex((c) => c.enablerId === enablerId);
|
|
405
|
+
if (index < 0) {
|
|
406
|
+
conditions.push({ enablerId: enablerId, enabledItems, disabledItems, enable });
|
|
407
|
+
}
|
|
408
|
+
else {
|
|
409
|
+
const prev = conditions[index];
|
|
410
|
+
const newId = {
|
|
411
|
+
enablerId,
|
|
412
|
+
enabledItems: [...prev.enabledItems, ...enabledItems],
|
|
413
|
+
disabledItems: [...prev.disabledItems, ...disabledItems],
|
|
414
|
+
enable,
|
|
415
|
+
};
|
|
416
|
+
conditions.splice(index, 1, newId);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Store all validation errors on the service.
|
|
422
|
+
* Revalidate form controls that previously had errors or have new errors now.
|
|
423
|
+
*/
|
|
424
|
+
_updateServerSideErrors() {
|
|
425
|
+
var _a;
|
|
426
|
+
// Keep track of IDs for each control that needs to be revalidated
|
|
427
|
+
const controlIdsToRevalidate = new Set();
|
|
428
|
+
// Collect controls previously in error to revalidate
|
|
429
|
+
if (this._formItemValidationResults) {
|
|
430
|
+
for (const id in this._formItemValidationResults) {
|
|
431
|
+
if (Object.prototype.hasOwnProperty.call(this._formItemValidationResults, id)) {
|
|
432
|
+
controlIdsToRevalidate.add(id);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
// Clear out all previous stored errors
|
|
437
|
+
this._formItemValidationResults = {};
|
|
438
|
+
if ((_a = this._mtnaForm) === null || _a === void 0 ? void 0 : _a.validationResult) {
|
|
439
|
+
for (const result of this._mtnaForm.validationResult.formItemValidationResults) {
|
|
440
|
+
if (result.validationStatus === 'ERRORS') {
|
|
441
|
+
// Store errors so that the validationResultValidator can validate each control
|
|
442
|
+
this._formItemValidationResults[result.id] = result;
|
|
443
|
+
// We need to revalidate these controls that have errors
|
|
444
|
+
controlIdsToRevalidate.add(result.id);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
// Only revalidate controls actually changes
|
|
449
|
+
const form = this.ngFormManager.getForm();
|
|
450
|
+
if (form) {
|
|
451
|
+
for (const id of controlIdsToRevalidate) {
|
|
452
|
+
const control = findFormControl(id, form);
|
|
453
|
+
if (control) {
|
|
454
|
+
control.updateValueAndValidity();
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
MtnaWfManagerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: MtnaWfManagerService, deps: [{ token: i1.MtnaWfApiService }, { token: i2.MtnaWfNgFormService }, { token: i3.MtnaWfUIService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
461
|
+
MtnaWfManagerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: MtnaWfManagerService });
|
|
462
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: MtnaWfManagerService, decorators: [{
|
|
463
|
+
type: Injectable
|
|
464
|
+
}], ctorParameters: function () { return [{ type: i1.MtnaWfApiService }, { type: i2.MtnaWfNgFormService }, { type: i3.MtnaWfUIService }]; } });
|
|
465
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1tYW5hZ2VyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93ZWItZm9ybS1hbmd1bGFyL3NyYy9saWIvY29yZS9zZXJ2aWNlcy9mb3JtLW1hbmFnZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFRLE1BQU0sZUFBZSxDQUFDO0FBR2pELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkMsT0FBTyxFQVFMLGlCQUFpQixFQUNqQixNQUFNLEVBQ04sbUJBQW1CLEVBQ25CLHFCQUFxQixFQUNyQixnQkFBZ0IsRUFDaEIsZ0JBQWdCLEVBQ2hCLFNBQVMsRUFDVCxXQUFXLEVBQ1gsb0JBQW9CLEdBVXJCLE1BQU0sbUJBQW1CLENBQUM7QUFFM0IsT0FBTyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHdEMsT0FBTyxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7Ozs7QUFpQmpFOzs7OztHQUtHO0FBRUgsTUFBTSxPQUFPLG9CQUFvQjtJQWtCL0IsWUFBc0IsVUFBNEIsRUFBWSxhQUFrQyxFQUFZLFNBQTBCO1FBQWhILGVBQVUsR0FBVixVQUFVLENBQWtCO1FBQVksa0JBQWEsR0FBYixhQUFhLENBQXFCO1FBQVksY0FBUyxHQUFULFNBQVMsQ0FBaUI7UUFqQjVILGVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBOEIsQ0FBQztRQUNuRCxnQkFBVyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDNUMsZ0VBQWdFO1FBQ3RELCtCQUEwQixHQUE2QyxFQUFFLENBQUM7UUFtSnBGOzs7Ozs7O1dBT0c7UUFDTywyQkFBc0IsR0FBZ0MsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDO0lBN0k2RCxDQUFDO0lBVDFJOzs7O09BSUc7SUFDSCxJQUFJLFdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDekMsQ0FBQztJQUlEOzs7T0FHRztJQUNILGtCQUFrQixDQUFDLE1BQTRCO1FBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ25CLE9BQU87U0FDUjtRQUVELElBQUksTUFBTSxDQUFDLFVBQVUsS0FBSyxRQUFRLEVBQUU7WUFDbEMsK0NBQStDO1lBQy9DLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQVMsQ0FBQztZQUNuRSxtREFBbUQ7WUFDbkQsT0FBTyxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFFMUQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDOUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDaEM7YUFBTTtZQUNMLElBQUksQ0FBQyxVQUFVO2lCQUNaLGlCQUFpQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUM7aUJBQ3ZELElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ2IsU0FBUyxDQUFDLENBQUMsT0FBOEIsRUFBRSxFQUFFO2dCQUM1QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQzNELElBQUksY0FBYyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7b0JBQ3BDLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxjQUFjLENBQUMsQ0FBQztvQkFDcEYsZ0RBQWdEO29CQUNoRCxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxTQUFTLGtDQUFPLE1BQU0sS0FBRSxFQUFFLEVBQUUsT0FBTyxDQUFDLFVBQVUsS0FBSSxPQUFPLENBQVMsQ0FBQztvQkFFM0csNkZBQTZGO29CQUM3RixNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQzNFLE9BQU8sR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsT0FBTyxrQ0FBTyxNQUFNLEtBQUUsZ0JBQWdCLElBQUcsQ0FBQztvQkFDbkYsSUFBSSxDQUFDLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQztvQkFDdEMsd0JBQXdCO29CQUN4QixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztpQkFDaEM7WUFDSCxDQUFDLENBQUMsQ0FBQztTQUNOO0lBQ0gsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsNEJBQTRCLENBQUMsSUFBYyxFQUFFLE1BQW1DO1FBQzlFLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQzdDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxLQUFLLEVBQW1CLENBQUM7UUFDdEQsSUFBSSxDQUFDLDBCQUEwQixDQUFDLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDN0UsT0FBTyxnQkFBZ0IsQ0FBQztJQUMxQixDQUFDO0lBRUQsbUZBQW1GO0lBQ25GLDRCQUE0QjtRQUMxQixPQUFPLElBQUksQ0FBQywwQkFBMEIsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsZUFBZSxDQUFDLFFBQWMsRUFBRSxZQUFxQztRQUNuRSx1Q0FDSyxRQUFRLEtBQ1gsS0FBSyxFQUFFLGdCQUFnQixDQUFDLG9CQUFvQixDQUMxQyxRQUFRLEVBQ1IsWUFBWSxFQUNaLElBQUksQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEVBQUUsRUFDbEMsSUFBSSxDQUFDLHNCQUFzQixFQUMzQixJQUFJLENBQUMseUJBQXlCLENBQy9CLElBQ0Q7SUFDSixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxxQkFBcUIsQ0FBQyxJQUFrQztRQUN0RCxPQUFPLGdCQUFnQixDQUFDLCtCQUErQixDQUNyRCxJQUFJLEVBQ0osSUFBSSxFQUNKLElBQUksQ0FBQyxzQkFBc0IsRUFDM0IsSUFBSSxDQUFDLGlDQUFpQyxDQUN2QyxDQUFDO0lBQ0osQ0FBQztJQUVELGdEQUFnRDtJQUNoRCxtQkFBbUIsQ0FBQyxFQUFVO1FBQzVCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILHlCQUF5QixDQUFDLFVBQTJDO1FBQ25FLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO0lBQy9CLENBQUM7SUFFRDs7O09BR0c7SUFDSCxXQUFXLENBQUMsSUFBVTtRQUNwQixJQUFJLENBQUMsU0FBUyxxQkFBUSxJQUFJLENBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRTtZQUN2RCxnRkFBZ0Y7WUFDaEYsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDZCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7b0JBQ3RCLEtBQUssTUFBTSxNQUFNLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTt3QkFDdkMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7cUJBQ3BIO2lCQUNGO2dCQUNELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1lBQzVCLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUNQO1FBRUQsZ0ZBQWdGO1FBQ2hGLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFZRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ08seUJBQXlCO0lBQ2pDLHNEQUFzRDtJQUN0RCxPQUEwRCxFQUMxRCxJQUFjLEVBQ2QsV0FBb0IsRUFDcEIsYUFBaUQ7SUFDakQscURBQXFEOztRQUVyRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0gsNkRBQTZEO0lBQ25ELGlDQUFpQyxDQUFDLElBQWM7UUFDeEQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsWUFBWTtJQUVaLDBCQUEwQjtJQUMxQjs7Ozs7T0FLRztJQUNPLGVBQWUsQ0FDdkIsSUFBTyxFQUNQLE1BQTRCLEVBQzVCLE9BQWtCO1FBRWxCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRTtZQUM1Qiw4Q0FBOEM7WUFDOUMsSUFBSSxNQUFNLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRTtnQkFDbkMsSUFBSSxPQUFPLElBQUksSUFBSSxFQUFFO29CQUNuQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsTUFBSyxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsVUFBVSxDQUFBLENBQUMsQ0FBQztvQkFDaEYsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDakMsSUFBSSxPQUFPLEVBQUU7d0JBQ1gsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO3FCQUNwQztvQkFDRCx1Q0FBWSxJQUFJLEtBQUUsS0FBSyxFQUFFLFFBQVEsSUFBRztpQkFDckM7Z0JBQ0QsT0FBTyxJQUFJLENBQUM7YUFDYjtpQkFBTSxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUNqQyx1Q0FDSyxJQUFJLEtBQ1AsS0FBSyxFQUFFLE1BQU0sQ0FBQyxVQUFVLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxLQUFLLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFDNUg7YUFDSDtpQkFBTTtnQkFDTCxPQUFPLElBQUksQ0FBQzthQUNiO1NBQ0Y7UUFFRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDMUYsTUFBTSxLQUFLLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsS0FBSyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEYsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQW9CLENBQUM7WUFFbEUsS0FBSyxDQUFDLE1BQU0sQ0FDVixhQUFhLEVBQ2IsQ0FBQyxFQUNELElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxrQ0FBTyxNQUFNLEtBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFJLE9BQU8sQ0FBYSxDQUM3RyxDQUFDO1lBQ0YsdUNBQ0ssSUFBSSxLQUNQLEtBQUssSUFDTDtTQUNIO2FBQU0sSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDNUIsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBaUIsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7U0FDbEU7YUFBTSxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLHFCQUFxQixDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ2hFLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUMzQixJQUF1RixFQUN2RixNQUFNLEVBQ04sT0FBTyxDQUNSLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDTjtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNLLGlCQUFpQixDQUN2QixVQUEyRixFQUMzRixNQUE0QixFQUM1QixPQUFrQjtRQUVsQixJQUFJLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbEIsTUFBTSxhQUFhLEdBQStCLEVBQUUsQ0FBQztRQUNyRCxzREFBc0Q7UUFDdEQsOERBQThEO1FBQzlELEtBQUssTUFBTSxFQUFFLElBQUksVUFBVSxDQUFDLGFBQWEsRUFBRTtZQUN6QyxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQyxFQUFFO2dCQUN0RSxpREFBaUQ7Z0JBQ2pELElBQUksVUFBVSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxVQUFVLEtBQUssTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDbkUsS0FBSyxHQUFHLElBQUksQ0FBQztvQkFDYixhQUFhLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FDdEMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQW9CLGtDQUMxQyxNQUFNLEtBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUNqRCxPQUFPLENBQ0ksQ0FBQztpQkFDZjtxQkFBTTtvQkFDTCxhQUFhLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDbEQ7YUFDRjtTQUNGO1FBQ0QsbUZBQW1GO1FBQ25GLE9BQU8saUNBQU0sVUFBVSxLQUFFLGFBQWEsS0FBSSxLQUFLLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssZ0JBQWdCLENBQUMsU0FBb0IsRUFBRSxNQUE0QixFQUFFLE9BQWtCO1FBQzdGLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNsQixtRUFBbUU7UUFDbkUsTUFBTSxTQUFTLEdBQW1CLFNBQVMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBaUIsRUFBRSxFQUFFO1lBQzlFLG1EQUFtRDtZQUNuRCxJQUFJLENBQUMsS0FBSyxFQUFFO2dCQUNWLHVDQUNLLEdBQUcsS0FDTixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFpQixFQUFFLEVBQUU7d0JBQ3pDLDJGQUEyRjt3QkFDM0YsSUFBSSxDQUFDLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFVLEtBQUssTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRTs0QkFDM0QsS0FBSyxHQUFHLElBQUksQ0FBQzs0QkFDYixPQUFPLElBQUksQ0FBQyxlQUFlLENBQ3pCLE9BQTBCLGtDQUNyQixNQUFNLEtBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUNqRCxPQUFPLENBQ0ksQ0FBQzt5QkFDZjt3QkFDRCx5RkFBeUY7d0JBQ3pGLDREQUE0RDt3QkFDNUQsSUFBSSxlQUFlLElBQUksT0FBTyxFQUFFOzRCQUM5QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQ3JDLE9BQTBGLEVBQzFGLE1BQU0sRUFDTixPQUFPLENBQ1IsQ0FBQzs0QkFDRixLQUFLLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUNwQixPQUFPLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQzt5QkFDcEI7d0JBQ0QsT0FBTyxPQUFPLENBQUM7b0JBQ2pCLENBQUMsQ0FBQyxJQUNGO2FBQ0g7WUFDRCxPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUMsQ0FBQyxDQUFDO1FBQ0gsdUNBQVksU0FBUyxLQUFFLFNBQVMsSUFBRztJQUNyQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLHlCQUF5QixDQUFDLElBQVUsRUFBRSxNQUE0QjtRQUN4RSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDbkIsSUFBSSxNQUFNLENBQUMsZ0JBQWdCLEVBQUU7WUFDM0IsTUFBTSxTQUFTLEdBQWtELEVBQUUsQ0FBQztZQUNwRSxLQUFLLE1BQU0sRUFBRSxJQUFJLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDeEMsS0FBSyxNQUFNLFNBQVMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUMsRUFBRTtvQkFDakUsSUFBSSxRQUFRLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUNwQyxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUM1RCxJQUFJLENBQUMsUUFBUSxLQUFJLGlCQUFpQixhQUFqQixpQkFBaUIsdUJBQWpCLGlCQUFpQixDQUFFLElBQUksQ0FBQSxFQUFFO3dCQUN4QyxRQUFRLEdBQUcsaUJBQWlCLGFBQWpCLGlCQUFpQix1QkFBakIsaUJBQWlCLENBQUUsSUFBSSxDQUFDO3FCQUNwQztvQkFDRCxJQUFJLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxTQUFTLEVBQUU7d0JBQ3JELE1BQU0sb0JBQW9CLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDO3dCQUM5RCxNQUFNLE9BQU8sR0FDWCxNQUFNLENBQUMsVUFBVSxLQUFLLEtBQUs7NEJBQ3pCLENBQUMsQ0FBQyxDQUFDLEdBQUcsb0JBQW9CLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQzs0QkFDekMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQzt3QkFFN0QsTUFBTSxPQUFPLG1DQUF5QixRQUFRLEtBQUUsU0FBUyxrQ0FBTyxRQUFRLENBQUMsU0FBUyxLQUFFLE9BQU8sTUFBSSxDQUFDO3dCQUNoRyxNQUFNLFNBQVMsR0FBRyxJQUFJLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQSxpQkFBaUIsYUFBakIsaUJBQWlCLHVCQUFqQixpQkFBaUIsQ0FBRSxTQUFTLEtBQUksRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFDO3dCQUU5RyxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQXFDLENBQVMsQ0FBQzt3QkFDbEcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztxQkFDaEM7aUJBQ0Y7Z0JBQ0QsSUFBSSxNQUFNLENBQUMsVUFBVSxLQUFLLFFBQVEsRUFBRTtvQkFDbEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztpQkFDOUY7YUFDRjtTQUNGO1FBQ0QsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxvQkFBb0IsQ0FBQyxJQUFjLEVBQUUsS0FBOEI7UUFDekUsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUM7UUFDOUIsSUFBSSxNQUFNLENBQXdCLElBQUksRUFBRSxPQUFPLENBQUMsRUFBRTtZQUNoRCxNQUFNLEtBQUssR0FBZSxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQ3JDLEtBQUssTUFBTSxPQUFPLElBQUksS0FBSyxFQUFFO2dCQUMzQixJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQzNDO1NBQ0Y7YUFBTSxJQUFJLE1BQU0sQ0FBZ0QsSUFBSSxFQUFFLGVBQWUsQ0FBQyxFQUFFO1lBQ3ZGLE1BQU0sR0FBRyxHQUErQixJQUFJLENBQUMsYUFBYSxDQUFDO1lBQzNELEtBQUssTUFBTSxFQUFFLElBQUksR0FBRyxFQUFFO2dCQUNwQixJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUU7b0JBQ2pELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7aUJBQzNDO2FBQ0Y7U0FDRjtJQUNILENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSywwQkFBMEIsQ0FDaEMsSUFBYyxFQUNkLE9BQStCLEVBQy9CLGFBQXNDLEVBQ3RDLE1BQW1DO1FBRW5DLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDMUIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDLE1BQU0sSUFBSSxNQUFNLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO1lBQ25ILElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDakksSUFBSSxDQUFDLDRCQUE0QixDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsYUFBYSxDQUFDLENBQUM7U0FDakU7YUFBTSxJQUFJLHFCQUFxQixDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3RDLEtBQUssTUFBTSxNQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtnQkFDakMsTUFBTSxNQUFNLEdBQ1YsQ0FBQyxDQUFDLE1BQU0sSUFBSSxNQUFNLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztnQkFDN0gsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsYUFBYSxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7YUFDeEg7WUFDRCxJQUFJLENBQUMsNEJBQTRCLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7U0FDekU7YUFBTSxJQUFJLE1BQU0sQ0FBd0IsSUFBSSxFQUFFLE9BQU8sQ0FBQyxFQUFFO1lBQ3ZELE1BQU0sS0FBSyxHQUFlLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDckMsS0FBSyxNQUFNLE9BQU8sSUFBSSxLQUFLLEVBQUU7Z0JBQzNCLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQzthQUMxRTtTQUNGO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNLLDRCQUE0QixDQUNsQyxJQUFxRixFQUNyRixVQUFrQyxFQUNsQyxPQUFnQyxFQUNoQyxNQUFtQztRQUVuQyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDdEIsS0FBSyxNQUFNLEVBQUUsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO2dCQUNuQyxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQyxFQUFFO29CQUNoRSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUN2QyxJQUFJLENBQUMsMEJBQTBCLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7aUJBQ3ZFO2FBQ0Y7U0FDRjtJQUNILENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSyxxQkFBcUIsQ0FDM0IsU0FBaUIsRUFDakIsT0FBaUIsRUFDakIsUUFBa0IsRUFDbEIsVUFBa0MsRUFDbEMsT0FBZ0MsRUFDaEMsTUFBZTtRQUVmLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEQsTUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsQ0FBQyxZQUFZLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFO1lBQ25ELE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLEtBQUssU0FBUyxDQUFDLENBQUM7WUFDckUsSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFO2dCQUNiLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQzthQUNoRjtpQkFBTTtnQkFDTCxNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQy9CLE1BQU0sS0FBSyxHQUFvQjtvQkFDN0IsU0FBUztvQkFDVCxZQUFZLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsR0FBRyxZQUFZLENBQUM7b0JBQ3JELGFBQWEsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxHQUFHLGFBQWEsQ0FBQztvQkFDeEQsTUFBTTtpQkFDUCxDQUFDO2dCQUNGLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQzthQUNwQztTQUNGO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNLLHVCQUF1Qjs7UUFDN0Isa0VBQWtFO1FBQ2xFLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUVqRCxxREFBcUQ7UUFDckQsSUFBSSxJQUFJLENBQUMsMEJBQTBCLEVBQUU7WUFDbkMsS0FBSyxNQUFNLEVBQUUsSUFBSSxJQUFJLENBQUMsMEJBQTBCLEVBQUU7Z0JBQ2hELElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQywwQkFBMEIsRUFBRSxFQUFFLENBQUMsRUFBRTtvQkFDN0Usc0JBQXNCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2lCQUNoQzthQUNGO1NBQ0Y7UUFFRCx1Q0FBdUM7UUFDdkMsSUFBSSxDQUFDLDBCQUEwQixHQUFHLEVBQUUsQ0FBQztRQUNyQyxJQUFJLE1BQUEsSUFBSSxDQUFDLFNBQVMsMENBQUUsZ0JBQWdCLEVBQUU7WUFDcEMsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLHlCQUF5QixFQUFFO2dCQUM5RSxJQUFJLE1BQU0sQ0FBQyxnQkFBZ0IsS0FBSyxRQUFRLEVBQUU7b0JBQ3hDLCtFQUErRTtvQkFDL0UsSUFBSSxDQUFDLDBCQUEwQixDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUM7b0JBQ3BELHdEQUF3RDtvQkFDeEQsc0JBQXNCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDdkM7YUFDRjtTQUNGO1FBRUQsNENBQTRDO1FBQzVDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDMUMsSUFBSSxJQUFJLEVBQUU7WUFDUixLQUFLLE1BQU0sRUFBRSxJQUFJLHNCQUFzQixFQUFFO2dCQUN2QyxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUMxQyxJQUFJLE9BQU8sRUFBRTtvQkFDWCxPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztpQkFDbEM7YUFDRjtTQUNGO0lBQ0gsQ0FBQzs7a0hBeGhCVSxvQkFBb0I7c0hBQXBCLG9CQUFvQjs0RkFBcEIsb0JBQW9CO2tCQURoQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBpc1R5cGUgfSBmcm9tICdAbXRuYS9jb3JlLXRzJztcbmltcG9ydCB7XG4gIENvbmRpdGlvbmFsSXRlbSxcbiAgQ29uZGl0aW9uQ2hhbmdlLFxuICBGb3JtLFxuICBGb3JtSXRlbSxcbiAgRm9ybUl0ZW1Hcm91cCxcbiAgRm9ybUl0ZW1JbXBsLFxuICBGb3JtSXRlbVZhbGlkYXRpb25SZXN1bHQsXG4gIGlzQ29uZGl0aW9uYWxJdGVtLFxuICBpc0Zvcm0sXG4gIGlzRm9ybUl0ZW1Hcm91cEltcGwsXG4gIGlzT3B0aW9uR3JvdXBJdGVtSW1wbCxcbiAgaXNPcHRpb25JdGVtSW1wbCxcbiAgaXNSZXBlYXRhYmxlSXRlbSxcbiAgaXNTZWN0aW9uLFxuICBpc1RhYmxlSXRlbSxcbiAgTXRuYVdmRm9ybUl0ZW1DaGFuZ2UsXG4gIE10bmFXZkZvcm1JdGVtQ2hhbmdlQWN0aW9uLFxuICBPcHRpb24sXG4gIE9wdGlvbkdyb3VwSXRlbUltcGwsXG4gIE9wdGlvbkl0ZW1JbXBsLFxuICBSZXBlYXRhYmxlSXRlbSxcbiAgU2VjdGlvbixcbiAgVGFibGVJdGVtLFxuICBUYWJsZVJvd0l0ZW0sXG4gIFZhbHVlSXRlbSxcbn0gZnJvbSAnQG10bmEvd2ViLWZvcm0tdHMnO1xuXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBNdG5hV2ZBcGlTZXJ2aWNlIH0gZnJvbSAnLi9hcGkuc2VydmljZSc7XG5pbXBvcnQgeyBmaW5kRm9ybUNvbnRyb2wsIE10bmFXZlNlcmlhbGl6ZXIgfSBmcm9tICcuLi91dGlsaXRpZXMnO1xuaW1wb3J0IHsgTXRuYVdmTmdGb3JtU2VydmljZSB9IGZyb20gJy4vbmctZm9ybS5zZXJ2aWNlJztcbmltcG9ydCB7IE10bmFXZlVJU2VydmljZSB9IGZyb20gJy4vdWkuc2VydmljZSc7XG5pbXBvcnQgdHlwZSB7IEJhc2VGb3JtSXRlbSB9IGZyb20gJy4uLy4uL2Zvcm0nO1xuXG4vKipcbiAqIHR5cGVzIG9mIEZvcm1JdGVtcyB0aGF0IGNhbiBiZSBwYXNzZWQgaW50byB0aGUgJ21vZGlmeU10bmFGb3JtSXRlbScgbWV0aG9kIHRvIGFkZC9yZW1vdmUgaXRlbXNcbiAqL1xudHlwZSBQYXJlbnRJdGVtVW5pb24gPVxuICB8IEZvcm1cbiAgfCBTZWN0aW9uXG4gIHwgRm9ybUl0ZW1Hcm91cFxuICB8IFJlcGVhdGFibGVJdGVtXG4gIHwgVGFibGVJdGVtXG4gIHwgT3B0aW9uSXRlbUltcGw8T3B0aW9uPHVua25vd24+LCB1bmtub3duPlxuICB8IE9wdGlvbkdyb3VwSXRlbUltcGw8T3B0aW9uPHVua25vd24+PjtcblxuLyoqXG4gKiBBbGxvd3MgYSBjYWxsZXIgdG8gKGRlKXNlcmlhbGl6YWUgYW4gTXRuYUZvcm0uIEl0IGNvbnRhaW5zIHRoZSBkZXRlcm1pbmluZyBsb2dpYyBmb3IgcmV0dXJuaW5nIHNwZWNpZmljIGZvcm0gY29udHJvbHNcbiAqIGFuZCBkZXNlcmlhbGl6aW5nIG5ldyBNdG5hRm9ybXMgZnJvbSB0aGUgcmVhY3RpdmUgdmFsdWVzLCBhcyB3ZWxsIGFzIHJlZ2lzdGVyaW5nIGN1c3RvbSBGb3JtIEl0ZW1zICYgZnVuY3Rpb25zLlxuICpcbiAqIEBleHBvcnRcbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE10bmFXZk1hbmFnZXJTZXJ2aWNlIHtcbiAgcHJvdGVjdGVkIGNvbXBvbmVudHMgPSBuZXcgTWFwPHN0cmluZywgVHlwZTxCYXNlRm9ybUl0ZW0+PigpO1xuICBwcm90ZWN0ZWQgZm9ybUNoYW5nZSQgPSBuZXcgU3ViamVjdDxGb3JtPigpO1xuICAvKiogQSBtYXAgb2YgYWxsIHtAbGluayBGb3JtSXRlbVZhbGlkYXRpb25SZXN1bHR9IGtleWVkIG9uIGlkICovXG4gIHByb3RlY3RlZCBfZm9ybUl0ZW1WYWxpZGF0aW9uUmVzdWx0czogUmVjb3JkPHN0cmluZywgRm9ybUl0ZW1WYWxpZGF0aW9uUmVzdWx0PiA9IHt9O1xuICAvKiogQ29uZGl0aW9uQ2hhbmdlcyBvbiAnYWRkJyBtdXN0IHdhaXQgdW50aWwgdGhlIGZvcm0gcmVyZW5kZXJzIHRvIHRvZ2dsZSBpdGVtcyAqL1xuICBwcm90ZWN0ZWQgaXRlbVRvZ2dsZVF1ZTogQXJyYXk8Q29uZGl0aW9uQ2hhbmdlPiB8IG51bGwgfCB1bmRlZmluZWQ7XG4gIHByb3RlY3RlZCBfbXRuYUZvcm06IEZvcm0gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIE9ic2VydmFibGUgc3RyZWFtIG9mIE10bmFGb3JtIGNoYW5nZXMuIFVzZWQgdG8gaW5mb3JtIGEgc3Vic2NyaWJlciB0aGF0IGFuIE10bmFGb3JtIGhhcyBiZWVuIGNoYW5nZWQuXG4gICAqXG4gICAqIEByZXR1cm5zIE9ic2VydmFibGU8TXRuYUZvcm0+IHRvIHdoaWNoIGEgY2FsbGVyIGNhbiBzdWJzY3JpYmVcbiAgICovXG4gIGdldCBmb3JtQ2hhbmdlcygpOiBPYnNlcnZhYmxlPEZvcm0+IHtcbiAgICByZXR1cm4gdGhpcy5mb3JtQ2hhbmdlJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBhcGlTZXJ2aWNlOiBNdG5hV2ZBcGlTZXJ2aWNlLCBwcm90ZWN0ZWQgbmdGb3JtTWFuYWdlcjogTXRuYVdmTmdGb3JtU2VydmljZSwgcHJvdGVjdGVkIHVpU2VydmljZTogTXRuYVdmVUlTZXJ2aWNlKSB7fVxuXG4gIC8qKlxuICAgKiBBZGRzIG9yIHJlbW92ZXMgYSBGb3JtSXRlbSBmcm9tIHRoZSBmb3JtICYgbW9kaWZpZXMgb3RoZXIgYWZmZWN0ZWQgRm9ybUl0ZW1zXG4gICAqIEBwYXJhbSBjaGFuZ2UgTXRuYVdmRm9ybUl0ZW1DaGFuZ2VcbiAgICovXG4gIGNoYW5nZU10bmFGb3JtSXRlbShjaGFuZ2U6IE10bmFXZkZvcm1JdGVtQ2hhbmdlKSB7XG4gICAgaWYgKCF0aGlzLl9tdG5hRm9ybSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2UuYWN0aW9uVHlwZSA9PT0gJ1JFTU9WRScpIHtcbiAgICAgIC8vIHJlbW92ZSB0aGUgcmVwZWF0YWJsZSBpdGVtIGZyb20gdGhlIG10bmFmb3JtXG4gICAgICBsZXQgbmV3Rm9ybSA9IHRoaXMuX21vZGlmeUZvcm1JdGVtKHRoaXMuX210bmFGb3JtLCBjaGFuZ2UpIGFzIEZvcm07XG4gICAgICAvLyBtb2RpZnkgdGhlIGNvbmRpdGlvbnMgb2YgYWxsIGVmZmVjdGVkIGZvcm0gaXRlbXNcbiAgICAgIG5ld0Zvcm0gPSB0aGlzLl9tb2RpZnlGb3JtSXRlbUNvbmRpdGlvbnMobmV3Rm9ybSwgY2hhbmdlKTtcblxuICAgICAgdGhpcy5uZ0Zvcm1NYW5hZ2VyLnJlbW92ZUNvbnRyb2woY2hhbmdlLmlkLCBjaGFuZ2UucGFyZW50SWRzKTtcbiAgICAgIHRoaXMuZm9ybUNoYW5nZSQubmV4dChuZXdGb3JtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hcGlTZXJ2aWNlXG4gICAgICAgIC5nZXRSZXBlYXRhYmxlSXRlbSh0aGlzLl9tdG5hRm9ybS5pbnN0YW5jZUlkLCBjaGFuZ2UuaWQpXG4gICAgICAgIC5waXBlKHRha2UoMSkpXG4gICAgICAgIC5zdWJzY3JpYmUoKG5ld0l0ZW06IEZvcm1JdGVtSW1wbDx1bmtub3duPikgPT4ge1xuICAgICAgICAgIGNvbnN0IG5ld0Zvcm1Db250cm9sID0gdGhpcy5zZXJpYWxpemVNdG5hRm9ybUl0ZW0obmV3SXRlbSk7XG4gICAgICAgICAgaWYgKG5ld0Zvcm1Db250cm9sICYmIHRoaXMuX210bmFGb3JtKSB7XG4gICAgICAgICAgICB0aGlzLm5nRm9ybU1hbmFnZXIuYWRkQ29udHJvbChuZXdJdGVtLmluc3RhbmNlSWQsIGNoYW5nZS5wYXJlbnRJZHMsIG5ld0Zvcm1Db250cm9sKTtcbiAgICAgICAgICAgIC8vIEFkZCB0aGUgbmV3IHJlcGVhdGFibGUgaXRlbSBpbnRvIHRoZSBtdG5hZm9ybVxuICAgICAgICAgICAgbGV0IG5ld0Zvcm0gPSB0aGlzLl9tb2RpZnlGb3JtSXRlbSh0aGlzLl9tdG5hRm9ybSwgeyAuLi5jaGFuZ2UsIGlkOiBuZXdJdGVtLmluc3RhbmNlSWQgfSwgbmV3SXRlbSkgYXMgRm9ybTtcblxuICAgICAgICAgICAgLy8gR2VuZXJhdGUgYSBsaXN0IG9mIGFsbCBmb3JtaXRlbSBjb25kaXRpb25zIG5lZWRpbmcgY2hhbmdlICYgbW9kaWZ5IHRob3NlIGl0ZW1zIGluIHRoZSBmb3JtXG4gICAgICAgICAgICBjb25zdCBjb25kaXRpb25DaGFuZ2VzID0gdGhpcy5nZW5lcmF0ZUNvbmRpdGlvbkNoYW5nZUFycmF5KG5ld0l0ZW0sICdBREQnKTtcbiAgICAgICAgICAgIG5ld0Zvcm0gPSB0aGlzLl9tb2RpZnlGb3JtSXRlbUNvbmRpdGlvbnMobmV3Rm9ybSwgeyAuLi5jaGFuZ2UsIGNvbmRpdGlvbkNoYW5nZXMgfSk7XG4gICAgICAgICAgICB0aGlzLml0ZW1Ub2dnbGVRdWUgPSBjb25kaXRpb25DaGFuZ2VzO1xuICAgICAgICAgICAgLy8gZW1pdCB0aGUgbmV3IG10bmFmb3JtXG4gICAgICAgICAgICB0aGlzLmZvcm1DaGFuZ2UkLm5leHQobmV3Rm9ybSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIENvbmRpdGlvbkNoYW5nZSBhcnJheSBmb3IgaXRlbXMgZXhpc3RpbmcgaW4gdGhlIDxpdGVtPiB3aGljaCBlbmFibGUvZGlzYWJsZSBGb3JtSXRlbXMgb3V0c2lkZSB0aGUgPGl0ZW0+J3Mgc2NvcGUuXG4gICAqIEBwYXJhbSBpdGVtIEZvcm1JdGVtIHRoYXQgZWZmZWN0cyB0aGUgY29uZGl0aW9uIG9mIG90aGVyIEZvcm1JdGVtc1xuICAgKiBAcGFyYW0gYWN0aW9uIFdoZXRoZXIgdGhpcyBpdGVtIHdhcyBhZGRlZCAoQUREKSwgb3IgcmVtb3ZlZCAoUkVNT1ZFKVxuICAgKiBAcmV0dXJucyBBcnJheTxDb25kaXRpb25DaGFuZ2U+XG4gICAqL1xuICBnZW5lcmF0ZUNvbmRpdGlvbkNoYW5nZUFycmF5KGl0ZW06IEZvcm1JdGVtLCBhY3Rpb24/OiBNdG5hV2ZGb3JtSXRlbUNoYW5nZUFjdGlvbik6IEFycmF5PENvbmRpdGlvbkNoYW5nZT4ge1xuICAgIGNvbnN0IGludGVybmFsTWFwID0ge307XG4gICAgdGhpcy5fYnVpbGRJbnRlcm5hbElkc01hcChpdGVtLCBpbnRlcm5hbE1hcCk7XG4gICAgY29uc3QgY29uZGl0aW9uQ2hhbmdlcyA9IG5ldyBBcnJheTxDb25kaXRpb25DaGFuZ2U+KCk7XG4gICAgdGhpcy5fYnVpbGRDb25kaXRpb25DaGFuZ2VBcnJheShpdGVtLCBjb25kaXRpb25DaGFuZ2VzLCBpbnRlcm5hbE1hcCwgYWN0aW9uKTtcbiAgICByZXR1cm4gY29uZGl0aW9uQ2hhbmdlcztcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyBUaGUgdG9wIGxldmVsIHZhbGlkYXRpb24gcmVzdWx0cyAodXN1YWxseSB0aGUgZXJyb3JzKSwga2V5ZWQgb24gSUQuICovXG4gIGdldEZvcm1JdGVtVmFsaWRhdGlvblJlc3VsdHMoKTogUmVjb3JkPHN0cmluZywgRm9ybUl0ZW1WYWxpZGF0aW9uUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuX2Zvcm1JdGVtVmFsaWRhdGlvblJlc3VsdHM7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBNdG5hRm9ybSB1c2luZyB0aGUgcHJldmlvdXMgTXRuYUZvcm0gJiByZWFjdGl2ZSBmb3JtIHZhbHVlcy5cbiAgICpcbiAgICogQHBhcmFtIG10bmFGb3JtIE10bmFGb3JtIHJlcXVpcmluZyB2YWx1ZSBpbnNlcnRpb25cbiAgICogQHBhcmFtIG5nRm9ybVZhbHVlcyBKU09OIG9iamVjdCBvZiAgbmdGb3JtIHZhbHVlc1xuICAgKiBAcmV0dXJucyBuZXcgTXRuYUZvcm1cbiAgICovXG4gIGluc2VydE5ld1ZhbHVlcyhtdG5hRm9ybTogRm9ybSwgbmdGb3JtVmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEZvcm0ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5tdG5hRm9ybSxcbiAgICAgIGl0ZW1zOiBNdG5hV2ZTZXJpYWxpemVyLmluc2VydEZvcm1JdGVtVmFsdWVzKFxuICAgICAgICBtdG5hRm9ybSxcbiAgICAgICAgbmdGb3JtVmFsdWVzLFxuICAgICAgICB0aGlzLnVpU2VydmljZS5nZXREaXNhYmxlZFN0YXRlcygpLFxuICAgICAgICB0aGlzLmR5bmFtaWNGb3JtQ29uZGl0aW9uYWwsXG4gICAgICAgIHRoaXMuZHluYW1pY1dlYkZvcm1JdGVtQnVpbGRlclxuICAgICAgKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFNlcmlhbGl6ZXMgYSBGb3JtIHwgRm9ybUl0ZW0gaW50byBGb3JtQ29udHJvbChzKVxuICAgKlxuICAgKiBAcGFyYW0gaXRlbSBGb3JtIHwgRm9ybUl0ZW0gcmVxdWlyaW5nIHNlcmlhbGl6YXRpb25cbiAgICogQHJldHVybnMgRm9ybUdyb3VwIHwgRm9ybUNvbnRyb2xcbiAgICovXG4gIHNlcmlhbGl6ZU10bmFGb3JtSXRlbShpdGVtOiBGb3JtIHwgRm9ybUl0ZW1JbXBsPHVua25vd24+KTogQWJzdHJhY3RDb250cm9sIHwgbnVsbCB7XG4gICAgcmV0dXJuIE10bmFXZlNlcmlhbGl6ZXIuZGV0ZXJtaW5lU2VyaWFsaXplRnVuY3Rpb25Ub1VzZShcbiAgICAgIGl0ZW0sXG4gICAgICB0aGlzLFxuICAgICAgdGhpcy5keW5hbWljRm9ybUNvbmRpdGlvbmFsLFxuICAgICAgdGhpcy5keW5hbWljUmVhY3RpdmVGb3JtQ29udHJvbEJ1aWxkZXJcbiAgICApO1xuICB9XG5cbiAgLy8jcmVnaW9uIEN1c3RvbSBDb21wb25lbnQvRnVuY3Rpb24gUmVnaXN0cmF0aW9uXG4gIGdldER5bmFtaWNDb21wb25lbnQoaWQ6IHN0cmluZyk6IFR5cGU8QmFzZUZvcm1JdGVtPiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuY29tcG9uZW50cy5nZXQoaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIG1hcCBvZiBjb21wb25lbnRzIHRvIGJlIGR5bmFtaWNhbGx5IHJlbmRlcmVkIGluc2lkZSBhbiBNdG5hRm9ybS5cbiAgICpcbiAgICogQHBhcmFtIGNvbXBvbmVudHMgdGhlIG1hcCBvZiBjb21wb25lbnRzIHRoYXQgYSBWYWx1ZUl0ZW0gd2lsbCB1c2UgZm9yIHJlbmRlcmluZ1xuICAgKiBAcHJvcCBzdHJpbmcgLSB0aGUgdHlwZShpdGVtSWQgc3VmZml4KSBvZiBjb21wb25lbnQsIHVzZWQgZm9yIHJldHJpZXZhbFxuICAgKiBAcHJvcCBUeXBlIC0gdGhlIGNvbXBvbmVudCB0byBiZSByZW5kZXJlZCwgYW4gZXh0ZW5zaW9uIG9mIEJhc2VGb3JtSXRlbVxuICAgKi9cbiAgcmVnaXN0ZXJEeW5hbWljQ29tcG9uZW50cyhjb21wb25lbnRzOiBNYXA8c3RyaW5nLCBUeXBlPEJhc2VGb3JtSXRlbT4+KSB7XG4gICAgdGhpcy5jb21wb25lbnRzID0gY29tcG9uZW50cztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGFuIE10bmFGb3JtIG9uIHRoZSBzZXJ2aWNlXG4gICAqIEBwYXJhbSBmb3JtIE10bmFGb3JtIHRvIGJlIHVzZWQgZm9yIGludGVybmFsIG1vZGlmaWNhdGlvblxuICAgKi9cbiAgc2V0TXRuYUZvcm0oZm9ybTogRm9ybSkge1xuICAgIHRoaXMuX210bmFGb3JtID0geyAuLi5mb3JtIH07XG4gICAgaWYgKCEhdGhpcy5pdGVtVG9nZ2xlUXVlICYmICEhdGhpcy5pdGVtVG9nZ2xlUXVlLmxlbmd0aCkge1xuICAgICAgLy8gVGhlIGZvcm0gbmVlZHMgdGltZSB0byByZXJlbmRlciwgc28gd2UgcHVzaCB0aGlzIGxvb3AgdG8gdGhlIGVuZCBvZiB0aGUgc3RhY2tcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5pdGVtVG9nZ2xlUXVlKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBjaGFuZ2Ugb2YgdGhpcy5pdGVtVG9nZ2xlUXVlKSB7XG4gICAgICAgICAgICB0aGlzLnVpU2VydmljZS50b2dnbGVGb3JtSXRlbXMoY2hhbmdlLmVuYWJsZWRJdGVtcywgY2hhbmdlLmRpc2FibGVkSXRlbXMsICEhY2hhbmdlLmVuYWJsZSwgY2hhbmdlLmVuYWJsZXJJZCwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuaXRlbVRvZ2dsZVF1ZSA9IG51bGw7XG4gICAgICB9LCAwKTtcbiAgICB9XG5cbiAgICAvLyBLZWVwIHRyYWNrIG9mIGFueSBlcnJvcnMgY29taW5nIGZyb20gdGhlIHNlcnZlciBhbmQgcmV2YWxpZGF0ZSB0aG9zZSBjb250cm9sc1xuICAgIHRoaXMuX3VwZGF0ZVNlcnZlclNpZGVFcnJvcnMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbnkgRm9ybVNlcnZpY2UgZXh0ZW5zaW9uIGNsYXNzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZCBpbiBvcmRlciB0byBjYWxsIHRoZVxuICAgKiBkeW5hbWljV2ViRm9ybUl0ZW1CdWlsZGVyL2R5bmFtaWNSZWFjdGl2ZUZvcm1Db250cm9sQnVpbGRlciBtZXRob2RzLiBEdXJpbmcgd2ViIGZvcm0gZ2VuZXJhdGlvbiwgdGhpcyBtZXRob2QgaXMgY2hlY2tlZCAmXG4gICAqIHRoZSBjdXJyZW50IEZvcm1JdGVtIGlzIHBhc3NlZCBpbiwgd2hpY2ggY2FuIGJlIHVzZWQgYnkgdGhlIG92ZXJyaWRpbmcgbWV0aG9kLlxuICAgKlxuICAgKiBAZXhhbXBsZSBkeW5hbWljRm9ybUNvbmRpdGlvbmFsID0gKGl0ZW06IEZvcm1JdGVtKSA9PiBpdGVtLml0ZW1JZC5pbmNsdWRlcyh7c29tZSBpdGVtSWR9KVxuICAgKlxuICAgKi9cbiAgcHJvdGVjdGVkIGR5bmFtaWNGb3JtQ29uZGl0aW9uYWw6IChpdGVtOiBGb3JtSXRlbSkgPT4gYm9vbGVhbiA9ICgpID0+IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBGdW5jdGlvbiB0byBiZSBvdmVycmlkZGVuIGJ5IGV4dGVuZGVkIHNlcnZpY2UgaW4gb3JkZXIgdG8gaGFuZGxlIGZvcm0gZ2VuZXJhdGlvbiBmb3IgYW55IGFwcGxpY2F0aW9uLXNwZWNpZmljIGR5bmFtaWMgZm9ybSBjb21wb25lbnRzLlxuICAgKiBTaG91bGQgcmV0dXJuIGEgbmV3IFZhbHVlSXRlbTxhbnk+LlxuICAgKiBTdGVwIDNcbiAgICpcbiAgICogQGV4YW1wbGUgZHluYW1pY1dlYkZvcm1JdGVtQnVpbGRlcihzZWN0aW9uOiBTZWN0aW9uIHwgRm9ybSwgaXRlbTogRm9ybUl0ZW0sIG5nRm9ybVZhbHVlOiBhbnkpOiBWYWx1ZUl0ZW0ge1xuICAgKiBjb25zdCBuZXdWYWx1ZSA9IHRoaXMuZ2VuZXJhdGVOZXdWYWx1ZShpdGVtLCByZlZhbHVlLCBzZWN0aW9uKTtcbiAgICogcmV0dXJuIHsgLi4uaXRlbSwgLi4ubmV3VmFsdWUgfVxuICAgKiB9XG4gICAqIEBwYXJhbSBzZWN0aW9uIHRoZSBjdXJyZW50IEZvcm1TZWN0aW9uXG4gICAqIEBwYXJhbSBpdGVtIHRoZSBjdXJyZW50IEZvcm1JdGVtXG4gICAqIEBwYXJhbSBuZ0Zvcm1WYWx1ZSB0aGUgbmdGb3JtIEpTT04gdmFsdWVcbiAgICogQHJldHVybnMgYSBuZXcgVmFsdWVJdGVtXG4gICAqL1xuICBwcm90ZWN0ZWQgZHluYW1pY1dlYkZvcm1JdGVtQnVpbGRlcihcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbiAgICBzZWN0aW9uOiBGb3JtIHwgRm9ybUl0ZW1Hcm91cCB8IFJlcGVhdGFibGVJdGVtIHwgdW5kZWZpbmVkLFxuICAgIGl0ZW06IEZvcm1JdGVtLFxuICAgIG5nRm9ybVZhbHVlOiB1bmtub3duLFxuICAgIGRpc2FibGVkU3RhdGU/OiB7IFtpbnN0YW5jZUlkOiBzdHJpbmddOiBib29sZWFuIH1cbiAgICAvKiBlc2xpbnQtZW5hYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xuICApOiBWYWx1ZUl0ZW08dW5rbm93bj4gfCBudWxsIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBGdW5jdGlvbiB0byBiZSBvdmVycmlkZGVuIGJ5IGV4dGVuZGVkIHNlcnZpY2UgaW4gb3JkZXIgdG8gaGFuZGxlIHJlYWN0aXZlIGZvcm0gZ2VuZXJhdGlvblxuICAgKiBmb3IgYW55IGFwcGxpY2F0aW9uLXNwZWNpZmljIGR5bmFtaWMgZm9ybSBjb21wb25lbnRzLlxuICAgKiBTaG91bGQgcmV0dXJuIEZvcm1Db250cm9sIHwgRm9ybUdyb3VwLlxuICAgKlxuICAgKiBAZXhhbXBsZSBkeW5hbWljUmVhY3RpdmVGb3JtQ29udHJvbEJ1aWxkZXIoaXRlbTogRm9ybUl0ZW0pIHtcbiAgICogcmV0dXJuIHRoaXMuYnVpbGRGb3JtQ29udHJvbEZvckR5bmFtaWNDb21wb25lbnQoaXRlbTogRm9ybUl0ZW0pO1xuICAgKiB9XG4gICAqIEBwYXJhbSBpdGVtIEZvcm1JdGVtIHVzZWQgdG8gZ2VuZXJhdGUgZm9ybSBjb250cm9sc1xuICAgKiBAcmV0dXJucyBGb3JtQ29udHJvbCB8IEZvcm1Hcm91cFxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBwcm90ZWN0ZWQgZHluYW1pY1JlYWN0aXZlRm9ybUNvbnRyb2xCdWlsZGVyKGl0ZW06IEZvcm1JdGVtKTogQWJzdHJhY3RDb250cm9sIHwgbnVsbCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyNlbmRyZWdpb25cblxuICAvLyNyZWdpb24gSU5URVJOQUwgTUVUSE9EU1xuICAvKipcbiAgICogUmVjdXJzaXZlbHkgdHJhdmVyc2VzIGEgRm9ybSB0byBpbnNlcnQgb3IgcmVtb3ZlIGEgZGVzaWduYXRlZCBGb3JtSXRlbS5cbiAgICogQHBhcmFtIGl0ZW0gTXRuYUZvcm0gdG8gc2VhcmNoIHRocm91Z2hcbiAgICogQHBhcmFtIGNoYW5nZTogTXRuYVdmRm9ybUl0ZW1DaGFuZ2UgZm9yIGFkZGluZyBvciByZW1vdmluZyBhIEZvcm1JdGVtXG4gICAqIEBwYXJhbSBuZXdJdGVtIEZvcm1JdGVtIHRvIGFkZCB0byBpdHMgcGFyZW50XG4gICAqL1xuICBwcm90ZWN0ZWQgX21vZGlmeUZvcm1JdGVtPEkgZXh0ZW5kcyBGb3JtIHwgU2VjdGlvbiB8IEZvcm1JdGVtIHwgRm9ybUl0ZW1JbXBsPHVua25vd24+PihcbiAgICBpdGVtOiBJLFxuICAgIGNoYW5nZTogTXRuYVdmRm9ybUl0ZW1DaGFuZ2UsXG4gICAgbmV3SXRlbT86IEZvcm1JdGVtXG4gICk6IEZvcm0gfCBTZWN0aW9uIHwgRm9ybUl0ZW0gfCBGb3JtSXRlbUltcGw8dW5rbm93bj4ge1xuICAgIGlmICghY2hhbmdlLnBhcmVudElkcy5sZW5ndGgpIHtcbiAgICAgIC8vIEF0IHRoaXMgcG9pbnQsIHdlIHJlYWNoIHRoZSBQYXJlbnQgRm9ybUl0ZW1cbiAgICAgIGlmIChjaGFuZ2UuYWN0aW9uVHlwZSA9PT0gJ1JFUExBQ0UnKSB7XG4gICAgICAgIGlmICgnaXRlbXMnIGluIGl0ZW0pIHtcbiAgICAgICAgICBjb25zdCBpbmRleCA9IGl0ZW0uaXRlbXMuZmluZEluZGV4KChpKSA9PiBpLmluc3RhbmNlSWQgPT09IG5ld0l0ZW0/Lmluc3RhbmNlSWQpO1xuICAgICAgICAgIGNvbnN0IG5ld0l0ZW1zID0gWy4uLml0ZW0uaXRlbXNdO1xuICAgICAgICAgIGlmIChuZXdJdGVtKSB7XG4gICAgICAgICAgICBuZXdJdGVtcy5zcGxpY2UoaW5kZXgsIDEsIG5ld0l0ZW0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4geyAuLi5pdGVtLCBpdGVtczogbmV3SXRlbXMgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgIH0gZWxzZSBpZiAoaXNSZXBlYXRhYmxlSXRlbShpdGVtKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLml0ZW0sXG4gICAgICAgICAgaXRlbXM6IGNoYW5nZS5hY3Rpb25UeXBlID09PSAnQUREJyA/IGl0ZW0uaXRlbXMuY29uY2F0KG5ld0l0ZW0gfHwgW10pIDogaXRlbS5pdGVtcy5maWx0ZXIoKGkpID0+IGkuaW5zdGFuY2VJZCAhPT0gY2hhbmdlLmlkKSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBpdGVtO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc0Zvcm0oaXRlbSkgfHwgaXNTZWN0aW9uKGl0ZW0pIHx8IGlzRm9ybUl0ZW1Hcm91cEltcGwoaXRlbSkgfHwgaXNSZXBlYXRhYmxlSXRlbShpdGVtKSkge1xuICAgICAgY29uc3QgaXRlbXMgPSBbLi4uaXRlbS5pdGVtc107XG4gICAgICBjb25zdCBpbmRleFRvTW9kaWZ5ID0gaXRlbS5pdGVtcy5maW5kSW5kZXgoKGkpID0+IGkuaW5zdGFuY2VJZCA9PT0gY2hhbmdlLnBhcmVudElkc1swXSk7XG4gICAgICBjb25zdCBpdGVtVG9Nb2RpZnkgPSBpdGVtLml0ZW1zW2luZGV4VG9Nb2RpZnldIGFzIFBhcmVudEl0ZW1VbmlvbjtcblxuICAgICAgaXRlbXMuc3BsaWNlKFxuICAgICAgICBpbmRleFRvTW9kaWZ5LFxuICAgICAgICAxLFxuICAgICAgICB0aGlzLl9tb2RpZnlGb3JtSXRlbShpdGVtVG9Nb2RpZnksIHsgLi4uY2hhbmdlLCBwYXJlbnRJZHM6IGNoYW5nZS5wYXJlbnRJZHMuc2xpY2UoMSkgfSwgbmV3SXRlbSkgYXMgRm9ybUl0ZW1cbiAgICAgICk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5pdGVtLFxuICAgICAgICBpdGVtcyxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChpc1RhYmxlSXRlbShpdGVtKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX21vZGlmeVRhYmxlSXRlbShpdGVtIGFzIFRhYmxlSXRlbSwgY2hhbmdlLCBuZXdJdGVtKTtcbiAgICB9IGVsc2UgaWYgKGlzT3B0aW9uSXRlbUltcGwoaXRlbSkgfHwgaXNPcHRpb25Hcm91cEl0ZW1JbXBsKGl0ZW0pKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbW9kaWZ5T3B0aW9uSXRlbShcbiAgICAgICAgaXRlbSBhcyBPcHRpb25JdGVtSW1wbDxPcHRpb248dW5rbm93bj4sIHVua25vd24+IHwgT3B0aW9uR3JvdXBJdGVtSW1wbDxPcHRpb248dW5rbm93bj4+LFxuICAgICAgICBjaGFuZ2UsXG4gICAgICAgIG5ld0l0ZW1cbiAgICAgIClbMF07XG4gICAgfVxuICAgIHJldHVybiBpdGVtO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYXZlcnNlcyBhbiBPcHRpb25JdGVtTWFwIG9mIGEgRm9ybUl0ZW0gdG8gaW5zZXJ0IG9yIHJlbW92ZSBhIGRlc2lnbmF0ZWQgRm9ybUl0ZW1cbiAgICogQHBhcmFtIG9wdGlvbkl0ZW0gRm9ybUl0ZW0gd2l0aCBhbiBvcHRpb25JdGVtTWFwLCBlLmcuIE9wdGlvbkl0ZW1JbXBsIHwgT3B0aW9uR3JvdXBJdGVtSW1wbFxuICAgKiBAcGFyYW0gY2hhbmdlIE10bmFXZkZvcm1JdGVtQ2hhbmdlIGZvciBhZGRpbmcgb3IgcmVtb3ZpbmcgYSBGb3JtSXRlbVxuICAgKiBAcGFyYW0gbmV3SXRlbSBGb3JtSXRlbSB0byBiZSBhZGRlZCB0byBpdHMgcGFyZW50XG4gICAqIEByZXR1cm5zIEZvcm1JdGVtIHdpdGggYW4gb3B0aW9uSXRlbU1hcCBjb250YWluaW5nIEZvcm1JdGVtc1xuICAgKi9cbiAgcHJpdmF0ZSBfbW9kaWZ5T3B0aW9uSXRlbShcbiAgICBvcHRpb25JdGVtOiBPcHRpb25JdGVtSW1wbDxPcHRpb248dW5rbm93bj4sIHVua25vd24+IHwgT3B0aW9uR3JvdXBJdGVtSW1wbDxPcHRpb248dW5rbm93bj4+LFxuICAgIGNoYW5nZTogTXRuYVdmRm9ybUl0ZW1DaGFuZ2UsXG4gICAgbmV3SXRlbT86IEZvcm1JdGVtXG4gICk6IFtPcHRpb25JdGVtSW1wbDxPcHRpb248dW5rbm93bj4sIHVua25vd24+IHwgT3B0aW9uR3JvdXBJdGVtSW1wbDxPcHRpb248dW5rbm93bj4+LCBib29sZWFuXSB7XG4gICAgbGV0IGZvdW5kID0gZmFsc2U7XG4gICAgY29uc3Qgb3B0aW9uSXRlbU1hcDogeyBbaWQ6IHN0cmluZ106IEZvcm1JdGVtIH0gPSB7fTtcbiAgICAvLyBMb29wIHRocm91Z2ggdGhlIG1hcCBhbmQgc2V0IHRoZSBpdGVtcyB0byBhIG5ldyBtYXBcbiAgICAvLyBDaGVjayBpZiBhbnkgRm9ybUl0ZW0gaW4gdGhlIG1hcCBtYXRjaGVzIHRoZSBuZXh0IHBhcmVudCBJRFxuICAgIGZvciAoY29uc3QgaWQgaW4gb3B0aW9uSXRlbS5vcHRpb25JdGVtTWFwKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9wdGlvbkl0ZW0ub3B0aW9uSXRlbU1hcCwgaWQpKSB7XG4gICAgICAgIC8vIElmIG9uZSBtYXRjaGVzLCBtb2RpZnkgJiBzZXQgaXQgb24gdGhlIG5ldyBtYXBcbiAgICAgICAgaWYgKG9wdGlvbkl0ZW0ub3B0aW9uSXRlbU1hcFtpZF0uaW5zdGFuY2VJZCA9PT0gY2hhbmdlLnBhcmVudElkc1swXSkge1xuICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICBvcHRpb25JdGVtTWFwW2lkXSA9IHRoaXMuX21vZGlmeUZvcm1JdGVtKFxuICAgICAgICAgICAgb3B0aW9uSXRlbS5vcHRpb25JdGVtTWFwW2lkXSBhcyBQYXJlbnRJdGVtVW5pb24sXG4gICAgICAgICAgICB7IC4uLmNoYW5nZSwgcGFyZW50SWRzOiBjaGFuZ2UucGFyZW50SWRzLnNsaWNlKDEpIH0sXG4gICAgICAgICAgICBuZXdJdGVtXG4gICAgICAgICAgKSBhcyBGb3JtSXRlbTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvcHRpb25JdGVtTWFwW2lkXSA9IG9wdGlvbkl0ZW0ub3B0aW9uSXRlbU1hcFtpZF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gcmV0dXJuIHRoZSBpdGVtIHdpdGggaXRzIG5ldyBvcHRpb25JdGVtTWFwLCAmIHdoZXRoZXIgd2UgZm91bmQgdGhlIG1hdGNoaW5nIGl0ZW1cbiAgICByZXR1cm4gW3sgLi4ub3B0aW9uSXRlbSwgb3B0aW9uSXRlbU1hcCB9LCBmb3VuZF07XG4gIH1cblxuICAvKipcbiAgICogVHJhdmVyc2VzIHRhYmxlIHJvd3MgdG8gaW5zZXJ0IG9yIHJlbW92ZSBhIEZvcm1JdGVtXG4gICAqIEBwYXJhbSB0YWJsZUl0ZW0gVGFibGVJdGVtIHRvIHRyYXZlcnNlXG4gICAqIEBwYXJhbSBjaGFuZ2UgTXRuYVdmRm9ybUl0ZW1DaGFuZ2UgZm9yIGFkZGluZyBvciByZW1vdmluZyBhIEZvcm1JdGVtXG4gICAqIEBwYXJhbSBuZXdJdGVtIEZvcm1JdGVtIHRvIGJlIGFkZGVkIHRvIGl0cyBwYXJlbnRcbiAgICogQHJldHVybnMgVGFibGVJdGVtIHdpdGggYSBGb3JtSXRlbSBhZGRlZCBvciByZW1vdmVkXG4gICAqL1xuICBwcml2YXRlIF9tb2RpZnlUYWJsZUl0ZW0odGFibGVJdGVtOiBUYWJsZUl0ZW0sIGNoYW5nZTogTXRuYVdmRm9ybUl0ZW1DaGFuZ2UsIG5ld0l0ZW0/OiBGb3JtSXRlbSk6IFRhYmxlSXRlbSB7XG4gICAgbGV0IGZvdW5kID0gZmFsc2U7XG4gICAgLy8gTWFwIHRoZSB0YWJsZSByb3dzIHRvIGZpbmQgdGhlIEZvcm1JdGVtIHdpdGggbWF0Y2hpbmcgaW5zdGFuY2VJZFxuICAgIGNvbnN0IHRhYmxlUm93czogVGFibGVSb3dJdGVtW10gPSB0YWJsZUl0ZW0udGFibGVSb3dzLm1hcCgocm93OiBUYWJsZVJvd0l0ZW0pID0+IHtcbiAgICAgIC8vIElmIHRoZSBpdGVtIHdhcyBmb3VuZCwgc2tpcCBtYXBwaW5nIGZ1cnRoZXIgcm93c1xuICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnJvdyxcbiAgICAgICAgICBpdGVtczogcm93Lml0ZW1zLm1hcCgocm93SXRlbTogRm9ybUl0ZW0pID0+IHtcbiAgICAgICAgICAgIC8vIElmIHdlIGZvdW5kIHRoZSBuZXh0IG1hdGNoaW5nIEZvcm1JdGVtLCB0b2dnbGUgJ2ZvdW5kJywgYW5kIHJldHVybiB0aGUgbW9kaWZpZWQgRm9ybUl0ZW1cbiAgICAgICAgICAgIGlmICghIXJvd0l0ZW0gJiYgcm93SXRlbS5pbnN0YW5jZUlkID09PSBjaGFuZ2UucGFyZW50SWRzWzBdKSB7XG4gICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21vZGlmeUZvcm1JdGVtKFxuICAgICAgICAgICAgICAgIHJvd0l0ZW0gYXMgUGFyZW50SXRlbVVuaW9uLFxuICAgICAgICAgICAgICAgIHsgLi4uY2hhbmdlLCBwYXJlbnRJZHM6IGNoYW5nZS5wYXJlbnRJZHMuc2xpY2UoMSkgfSxcbiAgICAgICAgICAgICAgICBuZXdJdGVtXG4gICAgICAgICAgICAgICkgYXMgRm9ybUl0ZW07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBJZiB0aGUgRm9ybUl0ZW0gaW5zdGFuY2VJZCBkb2Vzbid0IG1hdGNoLCBidXQgaXQgaGFzIEZvcm1JdGVtcyBpbiBpdHMgJ29wdGlvbkl0ZW1NYXAnLFxuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBjaGVjayBpZiBhIG1hdGNoaW5nIEZvcm1JdGVtIGV4aXN0cyBpbiBpdHMgbWFwXG4gICAgICAgICAgICBpZiAoJ29wdGlvbkl0ZW1NYXAnIGluIHJvd0l0ZW0pIHtcbiAgICAgICAgICAgICAgY29uc3QgcmV0dXJuZWQgPSB0aGlzLl9tb2RpZnlPcHRpb25JdGVtKFxuICAgICAgICAgICAgICAgIHJvd0l0ZW0gYXMgT3B0aW9uSXRlbUltcGw8T3B0aW9uPHVua25vd24+LCB1bmtub3duPiB8IE9wdGlvbkdyb3VwSXRlbUltcGw8T3B0aW9uPHVua25vd24+PixcbiAgICAgICAgICAgICAgICBjaGFuZ2UsXG4gICAgICAgICAgICAgICAgbmV3SXRlbVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBmb3VuZCA9IHJldHVybmVkWzFdO1xuICAgICAgICAgICAgICByZXR1cm4gcmV0dXJuZWRbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcm93SXRlbTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByb3c7XG4gICAgfSk7XG4gICAgcmV0dXJuIHsgLi4udGFibGVJdGVtLCB0YWJsZVJvd3MgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIG9yIHJlbW92ZXMgaW5zdGFuY2VJZHMgZnJvbSB0aGUgJ2l0ZW1JZHMnIGluIGEgRm9ybUl0ZW0ncyBjb25kaXRpb25cbiAgICogQHBhcmFtIGZvcm0gTXRuYUZvcm0gdG8gc2VhcmNoIHRocm91Z2ggJiByZXBsYWNlIGZvcm1pdGVtcyB3aXRoIHRoZSBuZXcgY29uZGl0aW9uXG4gICAqIEBwYXJhbSBjaGFuZ2UgVGhlIGNoYW5nZSB0aGF0IHJlY2VudGx5IG9jY3VycmVkIGluIHRoZSBtdG5hRm9ybVxuICAgKi9cbiAgcHJpdmF0ZSBfbW9kaWZ5Rm9ybUl0ZW1Db25kaXRpb25zKGZvcm06IEZvcm0sIGNoYW5nZTogTXRuYVdmRm9ybUl0ZW1DaGFuZ2UpOiBGb3JtIHtcbiAgICBsZXQgbmV3Rm9ybSA9IGZvcm07XG4gICAgaWYgKGNoYW5nZS5jb25kaXRpb25DaGFuZ2VzKSB7XG4gICAgICBjb25zdCBmb3JtSXRlbXM6IHsgW2tleTogc3RyaW5nXTogRm9ybUl0ZW0gfCBDb25kaXRpb25hbEl0ZW0gfSA9IHt9O1xuICAgICAgZm9yIChjb25zdCBjYyBvZiBjaGFuZ2UuY29uZGl0aW9uQ2hhbmdlcykge1xuICAgICAgICBmb3IgKGNvbnN0IHRvZ2dsZWRJZCBvZiBbLi4uY2MuZW5hYmxlZEl0ZW1zLCAuLi5jYy5kaXNhYmxlZEl0ZW1zXSkge1xuICAgICAgICAgIGxldCBmb3JtSXRlbSA9IGZvcm1JdGVtc1t0b2dnbGVkSWRdO1xuICAgICAgICAgIGNvbnN0IGZvcm1JdGVtQ29tcG9uZW50ID0gdGhpcy51aVNlcnZpY2UuZ2V0SXRlbSh0b2dnbGVkSWQpO1xuICAgICAgICAgIGlmICghZm9ybUl0ZW0gJiYgZm9ybUl0ZW1Db21wb25lbnQ/Lml0ZW0pIHtcbiAgICAgICAgICAgIGZvcm1JdGVtID0gZm9ybUl0ZW1Db21wb25lbnQ/Lml0ZW07XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChpc0NvbmRpdGlvbmFsSXRlbShmb3JtSXRlbSkgJiYgZm9ybUl0ZW0uY29uZGl0aW9uKSB7XG4gICAgICAgICAgICBjb25zdCBpdGVtQ29uZGl0aW9uSXRlbUlkcyA9IGZvcm1JdGVtLmNvbmRpdGlvbi5pdGVtSWRzIHx8IFtdO1xuICAgICAgICAgICAgY29uc3QgaXRlbUlkcyA9XG4gICAgICAgICAgICAgIGNoYW5nZS5hY3Rpb25UeXBlID09PSAnQUREJ1xuICAgICAgICAgICAgICAgID8gWy4uLml0ZW1Db25kaXRpb25JdGVtSWRzLCBjYy5lbmFibGVySWRdXG4gICAgICAgICAgICAgICAgOiBpdGVtQ29uZGl0aW9uSXRlbUlkcy5maWx0ZXIoKGkpID0+IGkgIT09IGNjLmVuYWJsZXJJZCk7XG5cbiAgICAgICAgICAgIGNvbnN0IG5ld0l0ZW06IENvbmRpdGlvbmFsSXRlbSA9IHsgLi4uZm9ybUl0ZW0sIGNvbmRpdGlvbjogeyAuLi5mb3JtSXRlbS5jb25kaXRpb24sIGl0ZW1JZHMgfSB9O1xuICAgICAgICAgICAgY29uc3QgbmV3Q2hhbmdlID0gbmV3IE10bmFXZkZvcm1JdGVtQ2hhbmdlKG5ld0l0ZW0uaW5zdGFuY2VJZCwgZm9ybUl0ZW1Db21wb25lbnQ/LnBhcmVudElkcyB8fCBbXSwgJ1JFUExBQ0UnKTtcblxuICAgICAgICAgICAgbmV3Rm9ybSA9IHRoaXMuX21vZGlmeUZvcm1JdGVtKG5ld0Zvcm0sIG5ld0NoYW5nZSwgbmV3SXRlbSBhcyBGb3JtSXRlbSAmIENvbmRpdGlvbmFsSXRlbSkgYXMgRm9ybTtcbiAgICAgICAgICAgIGZvcm1JdGVtc1t0b2dnbGVkSWRdID0gbmV3SXRlbTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYW5nZS5hY3Rpb25UeXBlID09PSAnUkVNT1ZFJykge1xuICAgICAgICAgIHRoaXMudWlTZXJ2aWNlLnRvZ2dsZUZvcm1JdGVtcyhjYy5lbmFibGVkSXRlbXMsIGNjLmRpc2FibGVkSXRlbXMsICEhY2MuZW5hYmxlLCBjYy5lbmFibGVySWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXdGb3JtO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIG1hcCBvZiBhbGwgaW5zdGFuY2VJZHMgaW5zaWRlIGFuIGl0ZW0uIENoZWNrcyAnaXRlbXMnICYgJ29wdGlvbkl0ZW1NYXAnXG4gICAqIEBwYXJhbSBpdGVtIEl0ZW0gdG8gcmVjdXJzZVxuICAgKiBAcGFyYW0gaWRNYXAgbWFwIG9mIHRoZSBpdGVtJ3MgaW50ZXJuYWwgaW5zdGFuY2VJZHNcbiAgICovXG4gIHByaXZhdGUgX2J1aWxkSW50ZXJuYWxJZHNNYXAoaXRlbTogRm9ybUl0ZW0sIGlkTWFwOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPikge1xuICAgIGlkTWFwW2l0ZW0uaW5zdGFuY2VJZF0gPSB0cnVlO1xuICAgIGlmIChpc1R5cGU8eyBpdGVtczogRm9ybUl0ZW1bXSB9PihpdGVtLCAnaXRlbXMnKSkge1xuICAgICAgY29uc3QgaXRlbXM6IEZvcm1JdGVtW10gPSBpdGVtLml0ZW1zO1xuICAgICAgZm9yIChjb25zdCBzdWJJdGVtIG9mIGl0ZW1zKSB7XG4gICAgICAgIHRoaXMuX2J1aWxkSW50ZXJuYWxJZHNNYXAoc3ViSXRlbSwgaWRNYXApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNUeXBlPHsgb3B0aW9uSXRlbU1hcDogeyBbaWQ6IHN0cmluZ106IEZvcm1JdGVtIH0gfT4oaXRlbSwgJ29wdGlvbkl0ZW1NYXAnKSkge1xuICAgICAgY29uc3QgbWFwOiB7IFtpZDogc3RyaW5nXTogRm9ybUl0ZW0gfSA9IGl0ZW0ub3B0aW9uSXRlbU1hcDtcbiAgICAgIGZvciAoY29uc3QgaWQgaW4gbWFwKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobWFwLCBpZCkpIHtcbiAgICAgICAgICB0aGlzLl9idWlsZEludGVybmFsSWRzTWFwKG1hcFtpZF0sIGlkTWFwKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYW4gYXJyYXkgb2YgQ29uZGl0aW9uQ2hhbmdlcyB0byBiZSBpbXBsZW1lbnRlZCBpbiBhbiBNdG5hRm9ybS5cbiAgICogQHBhcmFtIGl0ZW0gRm9ybUl0ZW0gdGhhdCB3YXMgYWRkZWQvcmVtb3ZlZCwgd2hpY2ggYWZmZWN0cyBjb25kaXRpb25zIG9mIG90aGVyIEZvcm1JdGVtc1xuICAgKiBAcGFyYW0gY2hhbmdlcyBBcnJheSB0byBidWlsZCB1cFxuICAgKiBAcGFyYW0gaW50ZXJuYWxJZE1hcCBNYXAgb2YgYWxsIGluc3RhbmNlSWRzIGxvY2F0ZWQgaW4gdGhlIGl0ZW07IGluIG9yZGVyIHRvIGV4Y2x1ZGUgdGhlbSBmcm9tIHRoZSBjb25kaXRpb24gY2hhbmdlc1xuICAgKiBAcGFyYW0gYWN0aW9uIFdoZXRoZXIgdGhlIGl0ZW0gd2FzIGFkZGVkIG9yIHJlbW92ZWRcbiAgICovXG4gIHByaXZhdGUgX2J1aWxkQ29uZGl0aW9uQ2hhbmdlQXJyYXkoXG4gICAgaXRlbTogRm9ybUl0ZW0sXG4gICAgY2hhbmdlczogQXJyYXk8Q29uZGl0aW9uQ2hhbmdlPixcbiAgICBpbnRlcm5hbElkTWFwOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPixcbiAgICBhY3Rpb24/OiBNdG5hV2ZGb3JtSXRlbUNoYW5nZUFjdGlvblxuICApIHtcbiAgICBpZiAoaXNPcHRpb25JdGVtSW1wbChpdGVtKSkge1xuICAgICAgY29uc3QgZW5hYmxlID0gISFhY3Rpb24gJiYgYWN0aW9uID09PSAnQUREJyA/IGl0ZW0ub3B0aW9uLnNlbGVjdGVkIHx8IGl0ZW0udmFsdWUgPT09IGl0ZW0ub3B0aW9uLm9wdGlvbi5pZCA6IGZhbHNlO1xuICAgICAgdGhpcy5fcHVzaENvbmRpdGlvblRvQXJyYXkoaXRlbS5pbnN0YW5jZUlkLCBpdGVtLm9wdGlvbi5lbmFibGVkSXRlbXMsIGl0ZW0ub3B0aW9uLmRpc2FibGVkSXRlbXMsIGNoYW5nZXMsIGludGVybmFsSWRNYXAsIGVuYWJsZSk7XG4gICAgICB0aGlzLl9idWlsZEFycmF5RnJvbU9wdGlvbkl0ZW1NYXAoaXRlbSwgY2hhbmdlcywgaW50ZXJuYWxJZE1hcCk7XG4gICAgfSBlbHNlIGlmIChpc09wdGlvbkdyb3VwSXRlbUltcGwoaXRlbSkpIHtcbiAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIGl0ZW0ub3B0aW9ucykge1xuICAgICAgICBjb25zdCBlbmFibGUgPVxuICAgICAgICAgICEhYWN0aW9uICYmIGFjdGlvbiA9PT0gJ0FERCcgPyBvcHRpb24uc2VsZWN0ZWQgfHwgKCEhaXRlbS52YWx1ZSAmJiBpdGVtLnZhbHVlLnNvbWUoKHYpID0+IHYgPT09IG9wdGlvbi5vcHRpb24uaWQpKSA6IGZhbHNlO1xuICAgICAgICB0aGlzLl9wdXNoQ29uZGl0aW9uVG9BcnJheShpdGVtLmluc3RhbmNlSWQsIG9wdGlvbi5lbmFibGVkSXRlbXMsIG9wdGlvbi5kaXNhYmxlZEl0ZW1zLCBjaGFuZ2VzLCBpbnRlcm5hbElkTWFwLCBlbmFibGUpO1xuICAgICAgfVxuICAgICAgdGhpcy5fYnVpbGRBcnJheUZyb21PcHRpb25JdGVtTWFwKGl0ZW0sIGNoYW5nZXMsIGludGVybmFsSWRNYXAsIGFjdGlvbik7XG4gICAgfSBlbHNlIGlmIChpc1R5cGU8eyBpdGVtczogRm9ybUl0ZW1bXSB9PihpdGVtLCAnaXRlbXMnKSkge1xuICAgICAgY29uc3QgaXRlbXM6IEZvcm1JdGVtW10gPSBpdGVtLml0ZW1zO1xuICAgICAgZm9yIChjb25zdCBzdWJJdGVtIG9mIGl0ZW1zKSB7XG4gICAgICAgIHRoaXMuX2J1aWxkQ29uZGl0aW9uQ2hhbmdlQXJyYXkoc3ViSXRlbSwgY2hhbmdlcywgaW50ZXJuYWxJZE1hcCwgYWN0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIGFuIGFycmF5IG9mIENvbmRpdGlvbkNoYW5nZXMgZnJvbSBhbiBpdGVtJ3Mgb3B0aW9uSXRlbU1hcFxuICAgKiBAcGFyYW0gaXRlbSBGb3JtSXRlbSB3aXRoIGFuIG9wdGlvbkl0ZW1NYXBcbiAgICogQHBhcmFtIGNvbmRpdGlvbnMgQXJyYXkgb2YgQ29uZGl0aW9uQ2hhbmdlcyB0byBwdXNoIG9uIG5ldyBjaGFuZ2VzXG4gICAqIEBwYXJhbSBpdGVtTWFwIG1hcCBvZiBpbnN0YW5jZUlkcyBleGlzaXRpbmcgaW4gYW4gaXRlbTsgaW4gb3JkZXIgdG8gZXhjbHVkZSB0aGVtIGZyb20gdGhlIGNoYW5nZXNcbiAgICogQHBhcmFtIGFjdGlvbiBXaGV0aGVyIGFuIGl0ZW0gd2FzIGFkZGVkIG9yIHJlbW92ZWRcbiAgICovXG4gIHByaXZhdGUgX2J1aWxkQXJyYXlGcm9tT3B0aW9uSXRlbU1hcChcbiAgICBpdGVtOiBPcHRpb25JdGVtSW1wbDxPcHRpb248dW5rbm93bj4sIHVua25vd24+IHwgT3B0aW9uR3JvdXBJdGVtSW1wbDxPcHRpb248dW5rbm93bj4+LFxuICAgIGNvbmRpdGlvbnM6IEFycmF5PENvbmRpdGlvbkNoYW5nZT4sXG4gICAgaXRlbU1hcDogUmVjb3JkPHN0cmluZywgYm9vbGVhbj4sXG4gICAgYWN0aW9uPzogTXRuYVdmRm9ybUl0ZW1DaGFuZ2VBY3Rpb25cbiAgKSB7XG4gICAgaWYgKGl0ZW0ub3B0aW9uSXRlbU1hcCkge1xuICAgICAgZm9yIChjb25zdCBpZCBpbiBpdGVtLm9wdGlvbkl0ZW1NYXApIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChpdGVtLm9wdGlvbkl0ZW1NYXAsIGlkKSkge1xuICAgICAgICAgIGNvbnN0IHN1Ykl0ZW0gPSBpdGVtLm9wdGlvbkl0ZW1NYXBbaWRdO1xuICAgICAgICAgIHRoaXMuX2J1aWxkQ29uZGl0aW9uQ2hhbmdlQXJyYXkoc3ViSXRlbSwgY29uZGl0aW9ucywgaXRlbU1hcCwgYWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQdXNoZXMgYSBuZXcgQ29uZGl0aW9uQ2hhbmdlIG9udG8gdGhlIGNvbmRpdGlvbnMgYXJyYXkuIElmIGEgQ29uZGl0aW9uQ2hhbmdlIHdpdGggbWF0Y2hpbmcgaWQgZXhpc3RzLFxuICAgKiBpdCBtZXJnZXMgdGhlIG5ldyB2YWx1ZXMgaW50byBpdFxuICAgKiBAcGFyYW0gZW5hYmxlcklkIGluc3RhbmNlSWQgb2YgdGhlIGl0ZW0gdGhhdCBlbmFibGVzIG90aGVyIEZvcm1JdGVtc1xuICAgKiBAcGFyYW0gZW5hYmxlZCB0aGUgaXRlbSdzICdlbmFibGVkSXRlbXMnIGFycmF5XG4gICAqIEBwYXJhbSBkaXNhYmxlZCB0aGUgaXRlbSdzICdkaXNhYmxlZEl0ZW1zJyBhcnJheVxuICAgKiBAcGFyYW0gY29uZGl0aW9ucyBBcnJheSBvZiBDb25kaXRpb25DaGFuZ2VzIHRvIGJ1aWxkIHVwXG4gICAqIEBwYXJhbSBpdGVtTWFwIG1hcCBvZiBpbnN0YW5jZUlkcyBpbnNpZGUgYW4gaXRlbTsgdG8gZW5zdXJlIG5vIGludGVybmFsIGlkcyBhcmUgaW5jbHVkZWQgaW4gYSBjaGFuZ2VcbiAgICogQHBhcmFtIGVuYWJsZSBXaGV0aGVyIHRoZSAnZW5hYmxlZEl0ZW1zJyBzaG91bGQgdG9nZ2xlZCBlbmFibGVkXG4gICAqL1xuICBwcml2YXRlIF9wdXNoQ29uZGl0aW9uVG9BcnJheShcbiAgICBlbmFibGVySWQ6IHN0cmluZyxcbiAgICBlbmFibGVkOiBzdHJpbmdbXSxcbiAgICBkaXNhYmxlZDogc3RyaW5nW10sXG4gICAgY29uZGl0aW9uczogQXJyYXk8Q29uZGl0aW9uQ2hhbmdlPixcbiAgICBpdGVtTWFwOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPixcbiAgICBlbmFibGU6IGJvb2xlYW5cbiAgKSB7XG4gICAgY29uc3QgZW5hYmxlZEl0ZW1zID0gZW5hYmxlZC5maWx0ZXIoKGUpID0+ICFpdGVtTWFwW2VdKTtcbiAgICBjb25zdCBkaXNhYmxlZEl0ZW1zID0gZGlzYWJsZWQuZmlsdGVyKChkKSA9PiAhaXRlbU1hcFtkXSk7XG4gICAgaWYgKCEhZW5hYmxlZEl0ZW1zLmxlbmd0aCB8fCAhIWRpc2FibGVkSXRlbXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBpbmRleCA9IGNvbmRpdGlvbnMuZmluZEluZGV4KChjKSA9PiBjLmVuYWJsZXJJZCA9PT0gZW5hYmxlcklkKTtcbiAgICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgICAgY29uZGl0aW9ucy5wdXNoKHsgZW5hYmxlcklkOiBlbmFibGVySWQsIGVuYWJsZWRJdGVtcywgZGlzYWJsZWRJdGVtcywgZW5hYmxlIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgcHJldiA9IGNvbmRpdGlvbnNbaW5kZXhdO1xuICAgICAgICBjb25zdCBuZXdJZDogQ29uZGl0aW9uQ2hhbmdlID0ge1xuICAgICAgICAgIGVuYWJsZXJJZCxcbiAgICAgICAgICBlbmFibGVkSXRlbXM6IFsuLi5wcmV2LmVuYWJsZWRJdGVtcywgLi4uZW5hYmxlZEl0ZW1zXSxcbiAgICAgICAgICBkaXNhYmxlZEl0ZW1zOiBbLi4ucHJldi5kaXNhYmxlZEl0ZW1zLCAuLi5kaXNhYmxlZEl0ZW1zXSxcbiAgICAgICAgICBlbmFibGUsXG4gICAgICAgIH07XG4gICAgICAgIGNvbmRpdGlvbnMuc3BsaWNlKGluZGV4LCAxLCBuZXdJZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0b3JlIGFsbCB2YWxpZGF0aW9uIGVycm9ycyBvbiB0aGUgc2VydmljZS5cbiAgICogUmV2YWxpZGF0ZSBmb3JtIGNvbnRyb2xzIHRoYXQgcHJldmlvdXNseSBoYWQgZXJyb3JzIG9yIGhhdmUgbmV3IGVycm9ycyBub3cuXG4gICAqL1xuICBwcml2YXRlIF91cGRhdGVTZXJ2ZXJTaWRlRXJyb3JzKCkge1xuICAgIC8vIEtlZXAgdHJhY2sgb2YgSURzIGZvciBlYWNoIGNvbnRyb2wgdGhhdCBuZWVkcyB0byBiZSByZXZhbGlkYXRlZFxuICAgIGNvbnN0IGNvbnRyb2xJZHNUb1JldmFsaWRhdGUgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIC8vIENvbGxlY3QgY29udHJvbHMgcHJldmlvdXNseSBpbiBlcnJvciB0byByZXZhbGlkYXRlXG4gICAgaWYgKHRoaXMuX2Zvcm1JdGVtVmFsaWRhdGlvblJlc3VsdHMpIHtcbiAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy5fZm9ybUl0ZW1WYWxpZGF0aW9uUmVzdWx0cykge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuX2Zvcm1JdGVtVmFsaWRhdGlvblJlc3VsdHMsIGlkKSkge1xuICAgICAgICAgIGNvbnRyb2xJZHNUb1JldmFsaWRhdGUuYWRkKGlkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENsZWFyIG91dCBhbGwgcHJldmlvdXMgc3RvcmVkIGVycm9yc1xuICAgIHRoaXMuX2Zvcm1JdGVtVmFsaWRhdGlvblJlc3VsdHMgPSB7fTtcbiAgICBpZiAodGhpcy5fbXRuYUZvcm0/LnZhbGlkYXRpb25SZXN1bHQpIHtcbiAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHRoaXMuX210bmFGb3JtLnZhbGlkYXRpb25SZXN1bHQuZm9ybUl0ZW1WYWxpZGF0aW9uUmVzdWx0cykge1xuICAgICAgICBpZiAocmVzdWx0LnZhbGlkYXRpb25TdGF0dXMgPT09ICdFUlJPUlMnKSB7XG4gICAgICAgICAgLy8gU3RvcmUgZXJyb3JzIHNvIHRoYXQgdGhlIHZhbGlkYXRpb25SZXN1bHRWYWxpZGF0b3IgY2FuIHZhbGlkYXRlIGVhY2ggY29udHJvbFxuICAgICAgICAgIHRoaXMuX2Zvcm1JdGVtVmFsaWRhdGlvblJlc3VsdHNbcmVzdWx0LmlkXSA9IHJlc3VsdDtcbiAgICAgICAgICAvLyBXZSBuZWVkIHRvIHJldmFsaWRhdGUgdGhlc2UgY29udHJvbHMgdGhhdCBoYXZlIGVycm9yc1xuICAgICAgICAgIGNvbnRyb2xJZHNUb1JldmFsaWRhdGUuYWRkKHJlc3VsdC5pZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBPbmx5IHJldmFsaWRhdGUgY29udHJvbHMgYWN0dWFsbHkgY2hhbmdlc1xuICAgIGNvbnN0IGZvcm0gPSB0aGlzLm5nRm9ybU1hbmFnZXIuZ2V0Rm9ybSgpO1xuICAgIGlmIChmb3JtKSB7XG4gICAgICBmb3IgKGNvbnN0IGlkIG9mIGNvbnRyb2xJZHNUb1JldmFsaWRhdGUpIHtcbiAgICAgICAgY29uc3QgY29udHJvbCA9IGZpbmRGb3JtQ29udHJvbChpZCwgZm9ybSk7XG4gICAgICAgIGlmIChjb250cm9sKSB7XG4gICAgICAgICAgY29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyNlbmRyZWdpb25cbn1cbiJdfQ==
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './api.service';
|
|
2
|
+
export * from './form-manager.service';
|
|
3
|
+
export * from './ng-form.service';
|
|
4
|
+
export * from './ui.service';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93ZWItZm9ybS1hbmd1bGFyL3NyYy9saWIvY29yZS9zZXJ2aWNlcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2FwaS5zZXJ2aWNlJztcbmV4cG9ydCAqIGZyb20gJy4vZm9ybS1tYW5hZ2VyLnNlcnZpY2UnO1xuZXhwb3J0ICogZnJvbSAnLi9uZy1mb3JtLnNlcnZpY2UnO1xuZXhwb3J0ICogZnJvbSAnLi91aS5zZXJ2aWNlJztcbiJdfQ==
|