@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.
Files changed (170) hide show
  1. package/_index.scss +25 -0
  2. package/bundles/mtna-web-form-angular.umd.js +4982 -0
  3. package/bundles/mtna-web-form-angular.umd.js.map +1 -0
  4. package/esm2015/lib/core/animations.js +8 -0
  5. package/esm2015/lib/core/api-config.js +3 -0
  6. package/esm2015/lib/core/index.js +7 -0
  7. package/esm2015/lib/core/pipes/coerce-date-item.pipe.js +23 -0
  8. package/esm2015/lib/core/pipes/coerce-form-group.pipe.js +35 -0
  9. package/esm2015/lib/core/pipes/date-quarter.pipe.js +43 -0
  10. package/esm2015/lib/core/pipes/get-auto-complete.pipe.js +42 -0
  11. package/esm2015/lib/core/pipes/get-available-quarters.pipe.js +29 -0
  12. package/esm2015/lib/core/pipes/get-form-control-error.pipe.js +20 -0
  13. package/esm2015/lib/core/pipes/get-list-icon.pipe.js +53 -0
  14. package/esm2015/lib/core/pipes/get-object-type.pipe.js +17 -0
  15. package/esm2015/lib/core/pipes/get-selected-option.pipe.js +20 -0
  16. package/esm2015/lib/core/pipes/index.js +71 -0
  17. package/esm2015/lib/core/pipes/items-with-value.pipe.js +30 -0
  18. package/esm2015/lib/core/pipes/sanitize-html.pipe.js +23 -0
  19. package/esm2015/lib/core/services/api.service.js +67 -0
  20. package/esm2015/lib/core/services/form-manager.service.js +465 -0
  21. package/esm2015/lib/core/services/index.js +5 -0
  22. package/esm2015/lib/core/services/ng-form.service.js +150 -0
  23. package/esm2015/lib/core/services/ui.service.js +333 -0
  24. package/esm2015/lib/core/utilities/find-form-control.js +29 -0
  25. package/esm2015/lib/core/utilities/find-form-item.js +25 -0
  26. package/esm2015/lib/core/utilities/flatten-steps.js +10 -0
  27. package/esm2015/lib/core/utilities/generate-form-steps.js +25 -0
  28. package/esm2015/lib/core/utilities/index.js +9 -0
  29. package/esm2015/lib/core/utilities/is-form-group.js +6 -0
  30. package/esm2015/lib/core/utilities/serializer-util.js +358 -0
  31. package/esm2015/lib/core/utilities/update-step-status.js +38 -0
  32. package/esm2015/lib/core/validators/index.js +3 -0
  33. package/esm2015/lib/core/validators/instant-validation-result-error-state-matcher.js +23 -0
  34. package/esm2015/lib/core/validators/validation-result-validator.js +19 -0
  35. package/esm2015/lib/file-upload/file-upload.component.js +66 -0
  36. package/esm2015/lib/file-upload/index.js +2 -0
  37. package/esm2015/lib/form/base-form-item.model.js +2 -0
  38. package/esm2015/lib/form/form-disabler.component.js +38 -0
  39. package/esm2015/lib/form/form-item.directive.js +22 -0
  40. package/esm2015/lib/form/form.component.js +250 -0
  41. package/esm2015/lib/form/form.module.js +214 -0
  42. package/esm2015/lib/form/index.js +5 -0
  43. package/esm2015/lib/form/white-list.model.js +11 -0
  44. package/esm2015/lib/form-item-controls/base-form-item-control.directive.js +58 -0
  45. package/esm2015/lib/form-item-controls/base-parent-item-control.directive.js +42 -0
  46. package/esm2015/lib/form-item-controls/base-single-selection-parent.directive.js +53 -0
  47. package/esm2015/lib/form-item-controls/date-range.component.js +84 -0
  48. package/esm2015/lib/form-item-controls/date.component.js +134 -0
  49. package/esm2015/lib/form-item-controls/dropdown.component.js +109 -0
  50. package/esm2015/lib/form-item-controls/index.js +8 -0
  51. package/esm2015/lib/form-item-controls/input.component.js +149 -0
  52. package/esm2015/lib/form-item-controls/year-quarter-range.component.js +75 -0
  53. package/esm2015/lib/form-item-controls/year-quarter.component.js +228 -0
  54. package/esm2015/lib/form-stepper/form-step-group.component.js +95 -0
  55. package/esm2015/lib/form-stepper/form-step-group.pipe.js +20 -0
  56. package/esm2015/lib/form-stepper/form-step.component.js +110 -0
  57. package/esm2015/lib/form-stepper/form-step.util.js +28 -0
  58. package/esm2015/lib/form-stepper/form-stepper.component.js +115 -0
  59. package/esm2015/lib/form-stepper/form-stepper.module.js +53 -0
  60. package/esm2015/lib/form-stepper/index.js +8 -0
  61. package/esm2015/lib/form-stepper/models/base-form-step.model.js +6 -0
  62. package/esm2015/lib/form-stepper/models/form-step-group.model.js +13 -0
  63. package/esm2015/lib/form-stepper/models/form-step.model.js +12 -0
  64. package/esm2015/lib/form-stepper/models/index.js +4 -0
  65. package/esm2015/lib/groups/form-item-dialog-data.model.js +14 -0
  66. package/esm2015/lib/groups/group-components.js +646 -0
  67. package/esm2015/lib/groups/index.js +3 -0
  68. package/esm2015/lib/groups/repeatable-item.component.js +23 -0
  69. package/esm2015/lib/item-header/index.js +2 -0
  70. package/esm2015/lib/item-header/item-header.component.js +108 -0
  71. package/esm2015/lib/static-form-items/index.js +3 -0
  72. package/esm2015/lib/static-form-items/ordered-list-item.js +50 -0
  73. package/esm2015/lib/static-form-items/unordered-list-item.js +52 -0
  74. package/esm2015/lib/step-card/index.js +2 -0
  75. package/esm2015/lib/step-card/step-card.component.js +53 -0
  76. package/esm2015/mtna-web-form-angular.js +5 -0
  77. package/esm2015/public-api.js +10 -0
  78. package/fesm2015/mtna-web-form-angular.js +4614 -0
  79. package/fesm2015/mtna-web-form-angular.js.map +1 -0
  80. package/lib/_index.scss +25 -0
  81. package/lib/core/_all-color.scss +25 -0
  82. package/lib/core/_all-theme.scss +28 -0
  83. package/lib/core/_all-typography.scss +25 -0
  84. package/lib/core/_core-theme.scss +43 -0
  85. package/lib/core/animations.d.ts +2 -0
  86. package/lib/core/api-config.d.ts +5 -0
  87. package/lib/core/index.d.ts +6 -0
  88. package/lib/core/pipes/coerce-date-item.pipe.d.ts +11 -0
  89. package/lib/core/pipes/coerce-form-group.pipe.d.ts +23 -0
  90. package/lib/core/pipes/date-quarter.pipe.d.ts +7 -0
  91. package/lib/core/pipes/get-auto-complete.pipe.d.ts +7 -0
  92. package/lib/core/pipes/get-available-quarters.pipe.d.ts +8 -0
  93. package/lib/core/pipes/get-form-control-error.pipe.d.ts +14 -0
  94. package/lib/core/pipes/get-list-icon.pipe.d.ts +7 -0
  95. package/lib/core/pipes/get-object-type.pipe.d.ts +7 -0
  96. package/lib/core/pipes/get-selected-option.pipe.d.ts +8 -0
  97. package/lib/core/pipes/index.d.ts +28 -0
  98. package/lib/core/pipes/items-with-value.pipe.d.ts +13 -0
  99. package/lib/core/pipes/sanitize-html.pipe.d.ts +10 -0
  100. package/lib/core/services/api.service.d.ts +41 -0
  101. package/lib/core/services/form-manager.service.d.ts +184 -0
  102. package/lib/core/services/index.d.ts +4 -0
  103. package/lib/core/services/ng-form.service.d.ts +76 -0
  104. package/lib/core/services/ui.service.d.ts +123 -0
  105. package/lib/core/utilities/find-form-control.d.ts +11 -0
  106. package/lib/core/utilities/find-form-item.d.ts +10 -0
  107. package/lib/core/utilities/flatten-steps.d.ts +7 -0
  108. package/lib/core/utilities/generate-form-steps.d.ts +3 -0
  109. package/lib/core/utilities/index.d.ts +8 -0
  110. package/lib/core/utilities/is-form-group.d.ts +3 -0
  111. package/lib/core/utilities/serializer-util.d.ts +81 -0
  112. package/lib/core/utilities/update-step-status.d.ts +14 -0
  113. package/lib/core/validators/index.d.ts +2 -0
  114. package/lib/core/validators/instant-validation-result-error-state-matcher.d.ts +13 -0
  115. package/lib/core/validators/validation-result-validator.d.ts +12 -0
  116. package/lib/file-upload/file-upload.component.d.ts +23 -0
  117. package/lib/file-upload/index.d.ts +1 -0
  118. package/lib/form/base-form-item.model.d.ts +15 -0
  119. package/lib/form/form-disabler.component.d.ts +6 -0
  120. package/lib/form/form-item.directive.d.ts +13 -0
  121. package/lib/form/form.component.d.ts +89 -0
  122. package/lib/form/form.module.d.ts +52 -0
  123. package/lib/form/index.d.ts +4 -0
  124. package/lib/form/white-list.model.d.ts +6 -0
  125. package/lib/form-item-controls/_date-item-theme.scss +29 -0
  126. package/lib/form-item-controls/_form-control-theme.scss +28 -0
  127. package/lib/form-item-controls/_year-quarter-item-theme.scss +28 -0
  128. package/lib/form-item-controls/base-form-item-control.directive.d.ts +26 -0
  129. package/lib/form-item-controls/base-parent-item-control.directive.d.ts +19 -0
  130. package/lib/form-item-controls/base-single-selection-parent.directive.d.ts +26 -0
  131. package/lib/form-item-controls/date-range.component.d.ts +12 -0
  132. package/lib/form-item-controls/date.component.d.ts +24 -0
  133. package/lib/form-item-controls/dropdown.component.d.ts +9 -0
  134. package/lib/form-item-controls/index.d.ts +7 -0
  135. package/lib/form-item-controls/input.component.d.ts +14 -0
  136. package/lib/form-item-controls/year-quarter-range.component.d.ts +9 -0
  137. package/lib/form-item-controls/year-quarter.component.d.ts +33 -0
  138. package/lib/form-stepper/_form-step-group-theme.scss +43 -0
  139. package/lib/form-stepper/_form-stepper-theme.scss +72 -0
  140. package/lib/form-stepper/form-step-group.component.d.ts +23 -0
  141. package/lib/form-stepper/form-step-group.pipe.d.ts +11 -0
  142. package/lib/form-stepper/form-step.component.d.ts +27 -0
  143. package/lib/form-stepper/form-step.util.d.ts +27 -0
  144. package/lib/form-stepper/form-stepper.component.d.ts +35 -0
  145. package/lib/form-stepper/form-stepper.module.d.ts +18 -0
  146. package/lib/form-stepper/index.d.ts +7 -0
  147. package/lib/form-stepper/models/base-form-step.model.d.ts +4 -0
  148. package/lib/form-stepper/models/form-step-group.model.d.ts +8 -0
  149. package/lib/form-stepper/models/form-step.model.d.ts +11 -0
  150. package/lib/form-stepper/models/index.d.ts +3 -0
  151. package/lib/groups/_checkbox-theme.scss +62 -0
  152. package/lib/groups/_form-group-theme.scss +32 -0
  153. package/lib/groups/_multiple-choice-theme.scss +65 -0
  154. package/lib/groups/_repeatable-item-theme.scss +28 -0
  155. package/lib/groups/form-item-dialog-data.model.d.ts +13 -0
  156. package/lib/groups/group-components.d.ts +221 -0
  157. package/lib/groups/index.d.ts +2 -0
  158. package/lib/groups/repeatable-item.component.d.ts +5 -0
  159. package/lib/item-header/_item-header-theme.scss +28 -0
  160. package/lib/item-header/index.d.ts +1 -0
  161. package/lib/item-header/item-header.component.d.ts +35 -0
  162. package/lib/static-form-items/index.d.ts +2 -0
  163. package/lib/static-form-items/ordered-list-item.d.ts +11 -0
  164. package/lib/static-form-items/unordered-list-item.d.ts +11 -0
  165. package/lib/step-card/_step-card-theme.scss +42 -0
  166. package/lib/step-card/index.d.ts +1 -0
  167. package/lib/step-card/step-card.component.d.ts +21 -0
  168. package/mtna-web-form-angular.d.ts +5 -0
  169. package/package.json +43 -0
  170. 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1tYW5hZ2VyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93ZWItZm9ybS1hbmd1bGFyL3NyYy9saWIvY29yZS9zZXJ2aWNlcy9mb3JtLW1hbmFnZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFRLE1BQU0sZUFBZSxDQUFDO0FBR2pELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkMsT0FBTyxFQVFMLGlCQUFpQixFQUNqQixNQUFNLEVBQ04sbUJBQW1CLEVBQ25CLHFCQUFxQixFQUNyQixnQkFBZ0IsRUFDaEIsZ0JBQWdCLEVBQ2hCLFNBQVMsRUFDVCxXQUFXLEVBQ1gsb0JBQW9CLEdBVXJCLE1BQU0sbUJBQW1CLENBQUM7QUFFM0IsT0FBTyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHdEMsT0FBTyxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7Ozs7QUFpQmpFOzs7OztHQUtHO0FBRUgsTUFBTSxPQUFPLG9CQUFvQjtJQWtCL0IsWUFBc0IsVUFBNEIsRUFBWSxhQUFrQyxFQUFZLFNBQTBCO1FBQWhILGVBQVUsR0FBVixVQUFVLENBQWtCO1FBQVksa0JBQWEsR0FBYixhQUFhLENBQXFCO1FBQVksY0FBUyxHQUFULFNBQVMsQ0FBaUI7UUFqQjVILGVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBOEIsQ0FBQztRQUNuRCxnQkFBVyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDNUMsZ0VBQWdFO1FBQ3RELCtCQUEwQixHQUE2QyxFQUFFLENBQUM7UUFtSnBGOzs7Ozs7O1dBT0c7UUFDTywyQkFBc0IsR0FBZ0MsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDO0lBN0k2RCxD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QUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDdkM7YUFDRjtTQUNGO1FBRUQsNENBQTRDO1FBQzVDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDMUMsSUFBSSxJQUFJLEVBQUU7WUFDUixLQUFLLE1BQU0sRUFBRSxJQUFJLHNCQUFzQixFQUFFO2dCQUN2QyxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUMxQyxJQUFJLE9BQU8sRUFBRTtvQkFDWCxPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztpQkFDbEM7YUFDRjtTQUNGO0lBQ0gsQ0FBQzs7a0hBeGhCVSxvQkFBb0I7c0hBQXBCLG9CQUFvQjs0RkFBcEIsb0JBQW9CO2tCQURoQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBpc1R5cGUgfSBmcm9tICdAbXRuYS9jb3JlLXRzJztcbmltcG9ydCB7XG4gIENvbmRpdGlvbmFsSXRlbSxcbiAgQ29uZGl0aW9uQ2hhbmdlLFxuICBGb3JtLFxuICBGb3JtSXRlbSxcbiAgRm9ybUl0ZW1Hcm91cCxcbiAgRm9ybUl0ZW1JbXBsLFxuICBGb3JtSXRlbVZhbGlkYXRpb25SZXN1bHQsXG4gIGlzQ29uZGl0aW9uYWxJdGVtLFxuICBpc0Zvcm0sXG4gIGlzRm9ybUl0ZW1Hcm91cEltcGwsXG4gIGlzT3B0aW9uR3JvdXBJdGVtSW1wbCxcbiAgaXNPcHRpb25JdGVtSW1wbCxcbiAgaXNSZXBlYXRhYmxlSXRlbSxcbiAgaXNTZWN0aW9uLFxuICBpc1RhYmxlSXRlbSxcbiAgTXRuYVdmRm9ybUl0ZW1DaGFuZ2UsXG4gIE10bmFXZkZvcm1JdGVtQ2hhbmdlQWN0aW9uLFxuICBPcHRpb24sXG4gIE9wdGlvbkdyb3VwSXRlbUltcGwsXG4gIE9wdGlvbkl0ZW1JbXBsLFxuICBSZXBlYXRhYmxlSXRlbSxcbiAgU2VjdGlvbixcbiAgVGFibGVJdGVtLFxuICBUYWJsZVJvd0l0ZW0sXG4gIFZhbHVlSXRlbSxcbn0gZnJvbSAnQG10bmEvd2ViLWZvcm0tdHMnO1xuXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBNdG5hV2ZBcGlTZXJ2aWNlIH0gZnJvbSAnLi9hcGkuc2VydmljZSc7XG5pbXBvcnQgeyBmaW5kRm9ybUNvbnRyb2wsIE10bmFXZlNlcmlhbGl6ZXIgfSBmcm9tICcuLi91dGlsaXRpZXMnO1xuaW1wb3J0IHsgTXRuYVdmTmdGb3JtU2VydmljZSB9IGZyb20gJy4vbmctZm9ybS5zZXJ2aWNlJztcbmltcG9ydCB7IE10bmFXZlVJU2VydmljZSB9IGZyb20gJy4vdWkuc2VydmljZSc7XG5pbXBvcnQgdHlwZSB7IEJhc2VGb3JtSXRlbSB9IGZyb20gJy4uLy4uL2Zvcm0nO1xuXG4vKipcbiAqIHR5cGVzIG9mIEZvcm1JdGVtcyB0aGF0IGNhbiBiZSBwYXNzZWQgaW50byB0aGUgJ21vZGlmeU10bmFGb3JtSXRlbScgbWV0aG9kIHRvIGFkZC9yZW1vdmUgaXRlbXNcbiAqL1xudHlwZSBQYXJlbnRJdGVtVW5pb24gPVxuICB8IEZvcm1cbiAgfCBTZWN0aW9uXG4gIHwgRm9ybUl0ZW1Hcm91cFxuICB8IFJlcGVhdGFibGVJdGVtXG4gIHwgVGFibGVJdGVtXG4gIHwgT3B0aW9uSXRlbUltcGw8T3B0aW9uPHVua25vd24+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==