@huntsman-cancer-institute/dictionary-editor 16.0.0 → 17.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/components/detail.component.d.ts +90 -90
  2. package/components/home.component.d.ts +13 -13
  3. package/components/new-row.component.d.ts +20 -20
  4. package/dictionary-editor.component.d.ts +43 -43
  5. package/dictionary-editor.module.d.ts +24 -24
  6. package/dictionary-editor.routes.d.ts +4 -4
  7. package/esm2022/components/detail.component.mjs +606 -606
  8. package/esm2022/components/home.component.mjs +28 -28
  9. package/esm2022/components/new-row.component.mjs +81 -81
  10. package/esm2022/dictionary-editor.component.mjs +169 -169
  11. package/esm2022/dictionary-editor.module.mjs +76 -76
  12. package/esm2022/dictionary-editor.routes.mjs +14 -14
  13. package/esm2022/grid-editors/ag-grid-date-cell-editor.component.mjs +30 -30
  14. package/esm2022/grid-editors/ag-grid-editor.module.mjs +55 -55
  15. package/esm2022/grid-editors/datepicker.component.mjs +93 -93
  16. package/esm2022/grid-editors/select.editor.mjs +142 -142
  17. package/esm2022/grid-renderers/ag-grid-renderer.module.mjs +36 -36
  18. package/esm2022/grid-renderers/cell-renderer-validation.mjs +345 -345
  19. package/esm2022/grid-renderers/date.renderer.mjs +68 -68
  20. package/esm2022/grid-renderers/select.renderer.mjs +95 -95
  21. package/esm2022/huntsman-cancer-institute-dictionary-editor.mjs +4 -4
  22. package/esm2022/index.mjs +4 -4
  23. package/fesm2022/huntsman-cancer-institute-dictionary-editor.mjs +1718 -1718
  24. package/fesm2022/huntsman-cancer-institute-dictionary-editor.mjs.map +1 -1
  25. package/grid-editors/ag-grid-date-cell-editor.component.d.ts +11 -11
  26. package/grid-editors/ag-grid-editor.module.d.ts +15 -15
  27. package/grid-editors/datepicker.component.d.ts +16 -16
  28. package/grid-editors/select.editor.d.ts +30 -30
  29. package/grid-renderers/ag-grid-renderer.module.d.ts +10 -10
  30. package/grid-renderers/cell-renderer-validation.d.ts +69 -69
  31. package/grid-renderers/date.renderer.d.ts +15 -15
  32. package/grid-renderers/select.renderer.d.ts +17 -17
  33. package/index.d.ts +4 -4
  34. package/package.json +18 -10
@@ -1,345 +1,345 @@
1
- import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from "@angular/forms";
2
- /**
3
- * This class' purpose is to place FormControls on cells in the grid, and to link them by rows, and rows to the grid as a whole.
4
- * It allows you to add validators for a cells' value and link an error type to an error message to display in a tooltip, or
5
- * you can provide a function to test some information about the row and provide an error message.
6
- *
7
- * The class works off of a number of properties added to the columnDefs in the ag-grid.
8
- *
9
- * We are looking for the following properties:
10
- * 1. errorMessageHeader : a string to display at the top of the list of any errors found for the cell
11
- * 2. validators : an array of angular validators to describe the cell value
12
- * 3. errorNameErrorMessageMap : an array of objects with "errorName"s and "errorMessage"s that are used to create a displayed list for the user
13
- * 4. setErrors: a function with the signature:
14
- * (value: any, data: any, node: any, colDef: any, rowIndex: any, gridApi: any) => string
15
- * which is called to generate a custom error message, if needed. An empty or null string
16
- * is treated as not being an error.
17
- *
18
- * Example column definition:
19
- * {
20
- * headerName: "Name",
21
- * editable: false,
22
- * width: 600,
23
- * cellRendererFramework: TextAlignLeftMiddleRenderer,
24
- * setErrors: (value: any,
25
- * data: any,
26
- * node: any,
27
- * colDef: any,
28
- * rowIndex: any,
29
- * gridApi: any) => {
30
- * return (value && value === 'TEST') ? 'Invalid name' : '';
31
- * },
32
- * validators: [ Validators.minLength(10) ],
33
- * errorMessageHeader: 'TestingTestingTesting',
34
- * errorNameErrorMessageMap: [
35
- * { errorName: 'minlength', errorMessage: 'Name is too short' }
36
- * ],
37
- * field: "name"
38
- * }
39
- *
40
- * To use with a new renderer, extend this class, do not override agInit, or call super.agInit(params) first.
41
- * (You can use agInit2 instead, called right after agInit).
42
- *
43
- * To display a tooltip with the error messages, include an element with a matTooltip pointing to this.errorMessage, like:
44
- * <div [matTooltip]="this.errorMessage" [matTooltipShowDelay]="300" [matTooltipHideDelay]="300" ...
45
- * For cell highlighting, you can add a CSS class something like :
46
- * .error {
47
- * background: linear-gradient(rgba(255,0,0,0.25), rgba(255,0,0,0.25), rgba(255,0,0,0.25));
48
- * border: solid red 2px;
49
- * }
50
- * and a conditional class on an element in the template, like :
51
- * class="{{this.errorMessage && this.errorMessage !== '' ? 'error' : ''}}"
52
- */
53
- export class CellRendererValidation {
54
- constructor() {
55
- this.errorMessage = "";
56
- }
57
- agInit(params) {
58
- this.params = params;
59
- this.formBuilder = new UntypedFormBuilder();
60
- if (this.params
61
- && this.params.node
62
- && this.params.node.gridApi
63
- && this.params.node.gridApi.formGroup === undefined) {
64
- let foundDelayValidationProperty = false;
65
- for (let columnDef of params.node.gridApi.columnController.columnDefs) {
66
- if (columnDef.delayValidation && columnDef.delayValidation === true) {
67
- foundDelayValidationProperty = true;
68
- }
69
- }
70
- if (!foundDelayValidationProperty) {
71
- this.determineIfAllRowsNeedValidationInAdvance();
72
- this.createAllFormControls();
73
- }
74
- }
75
- this.getErrorMessage();
76
- this.agInit2(params);
77
- }
78
- refresh(params) {
79
- return false;
80
- }
81
- // This function iterates over every cell in the grid and prepares all their needed formGroups and formControls.
82
- //
83
- // This was done this way (in the cell renderer) for three reasons :
84
- // 1. We need to wait until the column and row data have been provided to the grid
85
- // 2. We don't want the programmer to have to implement it themselves every time they create a grid
86
- // 3. The grid does not create all the cell renderers in advance, just those that fit on the screen
87
- // (plus a few nearby) meaning we can't just use the cell renderer's constructor, since we don't
88
- // know if the information we start with is valid on every screen, and because we have some calls
89
- // that send back the entire grid's worth of data.
90
- //
91
- // There may be a better way to do this, in which case this should probably be replaced!
92
- createAllFormControls() {
93
- if (this.params
94
- && this.params.column
95
- && this.params.column.colDef
96
- && this.params.data
97
- && this.params.node
98
- && this.params.node.gridApi
99
- && this.params.node.gridApi.getModel()) {
100
- if (this.params.node.gridApi.gridOptionsWrapper
101
- && this.params.node.gridApi.gridOptionsWrapper.gridOptions
102
- && !this.params.node.gridApi.gridOptionsWrapper.gridOptions._eventsChangedByCellRendererValidation) {
103
- this.changeGridOptionsEvents();
104
- this.params.node.gridApi.gridOptionsWrapper.gridOptions._eventsChangedByCellRendererValidation = true;
105
- }
106
- let allNodes = [];
107
- if (this.params.node.gridApi.mode_needToValidateOnlyRenderedCells) {
108
- allNodes = this.params.node.gridApi.getRenderedNodes();
109
- }
110
- else {
111
- allNodes = this.params.node.gridApi.getModel().rowsToDisplay;
112
- }
113
- if (!this.params.node.gridApi.formGroup
114
- || (this.params.node.gridApi.formGroup
115
- && this.params.node.gridApi.formGroup.controls
116
- && this.params.node.gridApi.formGroup.controls.length != allNodes.length)) {
117
- this.params.node.gridApi.formGroup = new UntypedFormGroup({});
118
- }
119
- if (this.params.node.gridApi.columnController
120
- && this.params.node.gridApi.columnController.columnDefs) {
121
- for (let columnDef of this.params.node.gridApi.columnController.columnDefs) {
122
- if (columnDef.outerForm && columnDef.formName) {
123
- if (!columnDef.outerForm.get(columnDef.formName)) {
124
- columnDef.outerForm.addControl(columnDef.formName, this.params.node.gridApi.formGroup);
125
- }
126
- else {
127
- columnDef.outerForm.setControl(columnDef.formName, this.params.node.gridApi.formGroup);
128
- }
129
- }
130
- }
131
- }
132
- let columns;
133
- if (this.params && this.params.columnApi && this.params.columnApi.columnController) {
134
- columns = this.params.columnApi.columnController.gridColumns.filter((column) => {
135
- return column.colDef
136
- && column.colDef.field
137
- && (column.colDef.validators || column.colDef.setErrors);
138
- });
139
- }
140
- for (let node of allNodes) {
141
- for (let column of columns) {
142
- if (column.colDef
143
- && column.colDef.field
144
- && (column.colDef.validators || column.colDef.setErrors)) {
145
- node[column.colDef.field + "_errorMessage"] = '';
146
- let formControl = new UntypedFormControl(column.colDef.field + '_formControl', []);
147
- if (!node.formGroup) {
148
- node.formGroup = new UntypedFormGroup({});
149
- }
150
- node.formGroup.addControl(column.colDef.field + '_formControl', formControl);
151
- if (!Array.isArray(column.colDef.validators)) {
152
- column.colDef.validators = [column.colDef.validators];
153
- }
154
- formControl.setValidators(column.colDef.validators);
155
- this.updateErrorMessage(formControl, node, column.colDef);
156
- }
157
- }
158
- if (!this.params.node.gridApi.formGroup.contains('RowGroup_' + node.rowIndex)) {
159
- if (!node.formGroup) {
160
- node.formGroup = new UntypedFormGroup({});
161
- }
162
- this.params.node.gridApi.formGroup.addControl('RowGroup_' + node.rowIndex, node.formGroup);
163
- }
164
- }
165
- }
166
- }
167
- changeGridOptionsEvents() {
168
- if (!this.params
169
- || !this.params.node
170
- || !this.params.node.gridApi
171
- || !this.params.node.gridApi.gridOptionsWrapper
172
- || !this.params.node.gridApi.gridOptionsWrapper.gridOptions) {
173
- return;
174
- }
175
- if (this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged) {
176
- this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged2 = this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged;
177
- }
178
- this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged = ((event) => {
179
- this.createAllFormControls();
180
- this.fetchErrorMessagesForCurrentlyRenderedCells();
181
- if (this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged2) {
182
- this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged2(event);
183
- }
184
- });
185
- if (this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged) {
186
- this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged2 = this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged;
187
- }
188
- this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged = ((event) => {
189
- this.determineIfAllRowsNeedValidationInAdvance();
190
- this.createAllFormControls();
191
- this.fetchErrorMessagesForCurrentlyRenderedCells();
192
- if (this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged2) {
193
- this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged2(event);
194
- }
195
- });
196
- }
197
- getErrorMessage() {
198
- if (this.params
199
- && this.params.node
200
- && this.params.node.formGroup
201
- && this.params.column
202
- && this.params.column.colDef
203
- && this.params.column.colDef.field) {
204
- let formControl = this.params.node.formGroup.get(this.params.column.colDef.field + '_formControl');
205
- this.updateErrorMessage(formControl, this.params.node, this.params.column.colDef);
206
- this.errorMessage = this.params.node[this.params.column.colDef.field + "_errorMessage"];
207
- }
208
- }
209
- refreshFormControlValue(formControl, data, fieldName) {
210
- if (formControl && data && fieldName && data[fieldName] !== undefined) {
211
- formControl.setValue(data[fieldName]);
212
- formControl.updateValueAndValidity();
213
- }
214
- }
215
- updateErrorMessage(formControl, node, columnDefinition) {
216
- if (!formControl || !node || !columnDefinition) {
217
- return '';
218
- }
219
- let customErrorMessage = '';
220
- if (columnDefinition.setErrors) {
221
- customErrorMessage = columnDefinition.setErrors(node.data[columnDefinition.field], node.data, node, columnDefinition, node.rowIndex, node.gridApi);
222
- }
223
- let errorMessageName = columnDefinition.field + "_errorMessage";
224
- this.refreshFormControlValue(formControl, node.data, columnDefinition.field);
225
- node[errorMessageName] = '';
226
- if (formControl.invalid || (customErrorMessage && customErrorMessage !== '')) {
227
- if (columnDefinition.errorMessageHeader) {
228
- node[errorMessageName] += '' + columnDefinition.errorMessageHeader + '\n';
229
- }
230
- else {
231
- node[errorMessageName] +=
232
- 'Invalid value "' + node.data[columnDefinition.field] + '" for field (' + columnDefinition.field + ')\n';
233
- }
234
- }
235
- if (columnDefinition.errorNameErrorMessageMap) {
236
- if (!Array.isArray(columnDefinition.errorNameErrorMessageMap)) {
237
- columnDefinition.errorNameErrorMessageMap = [columnDefinition.errorNameErrorMessageMap];
238
- }
239
- for (let errorNameErrorMessagePair of columnDefinition.errorNameErrorMessageMap) {
240
- if (!!errorNameErrorMessagePair.errorName && !!errorNameErrorMessagePair.errorMessage) {
241
- if (formControl.hasError(errorNameErrorMessagePair.errorName)) {
242
- node[errorMessageName] += errorNameErrorMessagePair.errorMessage + '\n';
243
- }
244
- }
245
- }
246
- }
247
- node[errorMessageName] += customErrorMessage;
248
- return node[errorMessageName];
249
- }
250
- determineIfAllRowsNeedValidationInAdvance() {
251
- if (this.params
252
- && this.params.node
253
- && this.params.node.gridApi
254
- && this.params.columnApi
255
- && this.params.columnApi.columnController
256
- && this.params.columnApi.columnController.gridColumns) {
257
- let columns = this.params.columnApi.columnController.gridColumns.filter((column) => {
258
- return column.colDef
259
- && column.colDef.field
260
- && (column.colDef.validators || column.colDef.setErrors)
261
- && column.colDef.editable === true
262
- && !(column.colDef.validateOnlyRenderedCells
263
- && column.colDef.validateOnlyRenderedCells === true);
264
- });
265
- this.params.node.gridApi.mode_needToValidateOnlyRenderedCells = Array.isArray(columns) && columns.length === 0;
266
- }
267
- }
268
- fetchErrorMessagesForCurrentlyRenderedCells() {
269
- if (this.params
270
- && this.params.node
271
- && this.params.node.gridApi) {
272
- let getCellRendererParams = { rowNodes: this.params.node.gridApi.getRenderedNodes() };
273
- for (let cellRenderer of this.params.node.gridApi.getCellRendererInstances(getCellRendererParams)) {
274
- if (cellRenderer._agAwareComponent && cellRenderer._agAwareComponent.getErrorMessage) {
275
- cellRenderer._agAwareComponent.getErrorMessage();
276
- }
277
- }
278
- }
279
- }
280
- updateValidation() {
281
- console.log("Successfully reached!");
282
- // add this form control
283
- let columns = this.params.columnApi.columnController.gridColumns.filter((column) => {
284
- return column.colDef
285
- && column.colDef.field
286
- && (column.colDef.validators || column.colDef.setErrors)
287
- && column.colDef.field === this.params.field;
288
- });
289
- if (this.params.colDef
290
- && this.params.colDef.field
291
- && (this.params.colDef.validators || this.params.colDef.setErrors)) {
292
- this.params.node[this.params.colDef.field + "_errorMessage"] = '';
293
- let formControl = new UntypedFormControl(this.params.colDef.field + '_formControl', []);
294
- if (!this.params.node.formGroup) {
295
- this.params.node.formGroup = new UntypedFormGroup({});
296
- if (!this.params.node.gridApi.formGroup) {
297
- this.params.node.gridApi.formGroup = new UntypedFormGroup({});
298
- }
299
- else {
300
- // check for any removed nodes & remove their validators if needed.
301
- for (let controlName of Object.keys(this.params.node.gridApi.formGroup.controls)) {
302
- if (('' + controlName).toLowerCase().substr(0, 9) === 'rowgroup_') {
303
- let found = false;
304
- for (let node of this.params.node.gridApi.getModel().rowsToDisplay) {
305
- if (('' + node.rowIndex) === ('' + controlName).substr(9)) {
306
- found = true;
307
- break;
308
- }
309
- }
310
- if (!found) {
311
- this.params.node.gridApi.formGroup.removeControl(controlName);
312
- }
313
- }
314
- }
315
- }
316
- this.params.node.gridApi.formGroup.addControl('RowGroup_' + this.params.node.rowIndex, this.params.node.formGroup);
317
- }
318
- if (!this.params.node.formGroup.controls[this.params.colDef.field + '_formControl']) {
319
- this.params.node.formGroup.addControl(this.params.colDef.field + '_formControl', formControl);
320
- if (Array.isArray(this.params.colDef.validators)) {
321
- this.params.node.formGroup.controls[this.params.colDef.field + '_formControl'].setValidators(this.params.colDef.validators);
322
- }
323
- if (this.params.node.gridApi.columnController
324
- && this.params.node.gridApi.columnController.columnDefs) {
325
- for (let columnDef of this.params.node.gridApi.columnController.columnDefs) {
326
- if (columnDef.outerForm && columnDef.formName) {
327
- if (!columnDef.outerForm.get(columnDef.formName)) {
328
- columnDef.outerForm.addControl(columnDef.formName, this.params.node.gridApi.formGroup);
329
- }
330
- else {
331
- columnDef.outerForm.setControl(columnDef.formName, this.params.node.gridApi.formGroup);
332
- }
333
- }
334
- }
335
- }
336
- }
337
- this.updateErrorMessage(formControl, this.params.node, this.params.colDef);
338
- }
339
- // add column control groups if needed
340
- // add row control groups if needed
341
- // setup grid control group if needed
342
- // Might need to trigger cell validation to run with the new validation.
343
- }
344
- }
345
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VsbC1yZW5kZXJlci12YWxpZGF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvZGljdGlvbmFyeS1lZGl0b3Ivc3JjL2dyaWQtcmVuZGVyZXJzL2NlbGwtcmVuZGVyZXItdmFsaWRhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUMsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQWEsTUFBTSxnQkFBZ0IsQ0FBQztBQUVwRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrREc7QUFDSCxNQUFNLE9BQWdCLHNCQUFzQjtJQUE1QztRQUlXLGlCQUFZLEdBQVcsRUFBRSxDQUFDO0lBZ1hyQyxDQUFDO0lBNVdHLE1BQU0sQ0FBQyxNQUFXO1FBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLGtCQUFrQixFQUFFLENBQUM7UUFFNUMsSUFBSSxJQUFJLENBQUMsTUFBTTtlQUNSLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSTtlQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPO2VBQ3hCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFO1lBRXJELElBQUksNEJBQTRCLEdBQVksS0FBSyxDQUFDO1lBRWxELEtBQUssSUFBSSxTQUFTLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFO2dCQUNuRSxJQUFJLFNBQVMsQ0FBQyxlQUFlLElBQUksU0FBUyxDQUFDLGVBQWUsS0FBSyxJQUFJLEVBQUU7b0JBQ2pFLDRCQUE0QixHQUFHLElBQUksQ0FBQztpQkFDdkM7YUFDSjtZQUVELElBQUksQ0FBQyw0QkFBNEIsRUFBRTtnQkFDL0Is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QzFGO2lDQUFNO2dDQUNILFNBQVMsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDOzZCQUMxRjt5QkFDSjtxQkFDSjtpQkFDSjthQUNKO1lBRUQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQzlFO1FBRUQsc0NBQXNDO1FBQ3RDLG1DQUFtQztRQUNuQyxxQ0FBcUM7UUFDckMsd0VBQXdFO0lBQzVFLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SUNlbGxSZW5kZXJlckFuZ3VsYXJDb21wfSBmcm9tIFwiYWctZ3JpZC1hbmd1bGFyXCI7XHJcbmltcG9ydCB7VW50eXBlZEZvcm1CdWlsZGVyLCBVbnR5cGVkRm9ybUNvbnRyb2wsIFVudHlwZWRGb3JtR3JvdXAsIFZhbGlkYXRvcnN9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xyXG5cclxuLyoqXHJcbiAqIFRoaXMgY2xhc3MnIHB1cnBvc2UgaXMgdG8gcGxhY2UgRm9ybUNvbnRyb2xzIG9uIGNlbGxzIGluIHRoZSBncmlkLCBhbmQgdG8gbGluayB0aGVtIGJ5IHJvd3MsIGFuZCByb3dzIHRvIHRoZSBncmlkIGFzIGEgd2hvbGUuXHJcbiAqIEl0IGFsbG93cyB5b3UgdG8gYWRkIHZhbGlkYXRvcnMgZm9yIGEgY2VsbHMnIHZhbHVlIGFuZCBsaW5rIGFuIGVycm9yIHR5cGUgdG8gYW4gZXJyb3IgbWVzc2FnZSB0byBkaXNwbGF5IGluIGEgdG9vbHRpcCwgb3JcclxuICogeW91IGNhbiBwcm92aWRlIGEgZnVuY3Rpb24gdG8gdGVzdCBzb21lIGluZm9ybWF0aW9uIGFib3V0IHRoZSByb3cgYW5kIHByb3ZpZGUgYW4gZXJyb3IgbWVzc2FnZS5cclxuICpcclxuICogVGhlIGNsYXNzIHdvcmtzIG9mZiBvZiBhIG51bWJlciBvZiBwcm9wZXJ0aWVzIGFkZGVkIHRvIHRoZSBjb2x1bW5EZWZzIGluIHRoZSBhZy1ncmlkLlxyXG4gKlxyXG4gKiBXZSBhcmUgbG9va2luZyBmb3IgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxyXG4gKiAgIDEuIGVycm9yTWVzc2FnZUhlYWRlciA6IGEgc3RyaW5nIHRvIGRpc3BsYXkgYXQgdGhlIHRvcCBvZiB0aGUgbGlzdCBvZiBhbnkgZXJyb3JzIGZvdW5kIGZvciB0aGUgY2VsbFxyXG4gKiAgIDIuIHZhbGlkYXRvcnMgOiBhbiBhcnJheSBvZiBhbmd1bGFyIHZhbGlkYXRvcnMgdG8gZGVzY3JpYmUgdGhlIGNlbGwgdmFsdWVcclxuICogICAzLiBlcnJvck5hbWVFcnJvck1lc3NhZ2VNYXAgOiBhbiBhcnJheSBvZiBvYmplY3RzIHdpdGggXCJlcnJvck5hbWVcInMgYW5kIFwiZXJyb3JNZXNzYWdlXCJzIHRoYXQgYXJlIHVzZWQgdG8gY3JlYXRlIGEgZGlzcGxheWVkIGxpc3QgZm9yIHRoZSB1c2VyXHJcbiAqICAgNC4gc2V0RXJyb3JzOiBhIGZ1bmN0aW9uIHdpdGggdGhlIHNpZ25hdHVyZTpcclxuICogICAgICAgICAgICAgICAgICh2YWx1ZTogYW55LCBkYXRhOiBhbnksIG5vZGU6IGFueSwgY29sRGVmOiBhbnksIHJvd0luZGV4OiBhbnksIGdyaWRBcGk6IGFueSkgPT4gc3RyaW5nXHJcbiAqICAgICAgICAgICAgICAgICB3aGljaCBpcyBjYWxsZWQgdG8gZ2VuZXJhdGUgYSBjdXN0b20gZXJyb3IgbWVzc2FnZSwgaWYgbmVlZGVkLiBBbiBlbXB0eSBvciBudWxsIHN0cmluZ1xyXG4gKiAgICAgICAgICAgICAgICAgaXMgdHJlYXRlZCBhcyBub3QgYmVpbmcgYW4gZXJyb3IuXHJcbiAqXHJcbiAqIEV4YW1wbGUgY29sdW1uIGRlZmluaXRpb246XHJcbiAqICAgICAge1xyXG4gKiAgICAgICAgICBoZWFkZXJOYW1lOiBcIk5hbWVcIixcclxuICogICAgICAgICAgZWRpdGFibGU6IGZhbHNlLFxyXG4gKiAgICAgICAgICB3aWR0aDogNjAwLFxyXG4gKiAgICAgICAgICBjZWxsUmVuZGVyZXJGcmFtZXdvcms6IFRleHRBbGlnbkxlZnRNaWRkbGVSZW5kZXJlcixcclxuICogICAgICAgICAgc2V0RXJyb3JzOiAodmFsdWU6IGFueSxcclxuICogICAgICAgICAgICAgICAgICAgICAgZGF0YTogYW55LFxyXG4gKiAgICAgICAgICAgICAgICAgICAgICBub2RlOiBhbnksXHJcbiAqICAgICAgICAgICAgICAgICAgICAgIGNvbERlZjogYW55LFxyXG4gKiAgICAgICAgICAgICAgICAgICAgICByb3dJbmRleDogYW55LFxyXG4gKiAgICAgICAgICAgICAgICAgICAgICBncmlkQXBpOiBhbnkpID0+IHtcclxuICogICAgICAgICAgICAgIHJldHVybiAodmFsdWUgJiYgdmFsdWUgPT09ICdURVNUJykgPyAnSW52YWxpZCBuYW1lJyA6ICcnO1xyXG4gKiAgICAgICAgICB9LFxyXG4gKiAgICAgICAgICB2YWxpZGF0b3JzOiBbIFZhbGlkYXRvcnMubWluTGVuZ3RoKDEwKSBdLFxyXG4gKiAgICAgICAgICBlcnJvck1lc3NhZ2VIZWFkZXI6ICdUZXN0aW5nVGVzdGluZ1Rlc3RpbmcnLFxyXG4gKiAgICAgICAgICBlcnJvck5hbWVFcnJvck1lc3NhZ2VNYXA6IFtcclxuICogICAgICAgICAgICAgIHsgZXJyb3JOYW1lOiAnbWlubGVuZ3RoJywgZXJyb3JNZXNzYWdlOiAnTmFtZSBpcyB0b28gc2hvcnQnIH1cclxuICogICAgICAgICAgXSxcclxuICogICAgICAgICAgZmllbGQ6IFwibmFtZVwiXHJcbiAqICAgICAgfVxyXG4gKlxyXG4gKiBUbyB1c2Ugd2l0aCBhIG5ldyByZW5kZXJlciwgZXh0ZW5kIHRoaXMgY2xhc3MsIGRvIG5vdCBvdmVycmlkZSBhZ0luaXQsIG9yIGNhbGwgc3VwZXIuYWdJbml0KHBhcmFtcykgZmlyc3QuXHJcbiAqIChZb3UgY2FuIHVzZSBhZ0luaXQyIGluc3RlYWQsIGNhbGxlZCByaWdodCBhZnRlciBhZ0luaXQpLlxyXG4gKlxyXG4gKiBUbyBkaXNwbGF5IGEgdG9vbHRpcCB3aXRoIHRoZSBlcnJvciBtZXNzYWdlcywgaW5jbHVkZSBhbiBlbGVtZW50IHdpdGggYSBtYXRUb29sdGlwIHBvaW50aW5nIHRvIHRoaXMuZXJyb3JNZXNzYWdlLCBsaWtlOlxyXG4gKiAgICAgIDxkaXYgW21hdFRvb2x0aXBdPVwidGhpcy5lcnJvck1lc3NhZ2VcIiBbbWF0VG9vbHRpcFNob3dEZWxheV09XCIzMDBcIiBbbWF0VG9vbHRpcEhpZGVEZWxheV09XCIzMDBcIiAuLi5cclxuICogRm9yIGNlbGwgaGlnaGxpZ2h0aW5nLCB5b3UgY2FuIGFkZCBhIENTUyBjbGFzcyBzb21ldGhpbmcgbGlrZSA6XHJcbiAqICAgICAgLmVycm9yIHtcclxuICogICAgICBcdGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudChyZ2JhKDI1NSwwLDAsMC4yNSksIHJnYmEoMjU1LDAsMCwwLjI1KSwgcmdiYSgyNTUsMCwwLDAuMjUpKTtcclxuICogICAgICBcdGJvcmRlcjogc29saWQgcmVkIDJweDtcclxuICogICAgICB9XHJcbiAqICAgYW5kIGEgY29uZGl0aW9uYWwgY2xhc3Mgb24gYW4gZWxlbWVudCBpbiB0aGUgdGVtcGxhdGUsIGxpa2UgOlxyXG4gKiAgICAgIGNsYXNzPVwie3t0aGlzLmVycm9yTWVzc2FnZSAmJiB0aGlzLmVycm9yTWVzc2FnZSAhPT0gJycgPyAnZXJyb3InIDogJyd9fVwiXHJcbiAqL1xyXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ2VsbFJlbmRlcmVyVmFsaWRhdGlvbiBpbXBsZW1lbnRzIElDZWxsUmVuZGVyZXJBbmd1bGFyQ29tcCB7XHJcblxyXG4gICAgcHJvdGVjdGVkIHBhcmFtczogYW55O1xyXG5cclxuICAgIHB1YmxpYyBlcnJvck1lc3NhZ2U6IHN0cmluZyA9IFwiXCI7XHJcblxyXG4gICAgZm9ybUJ1aWxkZXI6IFVudHlwZWRGb3JtQnVpbGRlcjtcclxuXHJcbiAgICBhZ0luaXQocGFyYW1zOiBhbnkpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnBhcmFtcyA9IHBhcmFtcztcclxuICAgICAgICB0aGlzLmZvcm1CdWlsZGVyID0gbmV3IFVudHlwZWRGb3JtQnVpbGRlcigpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5wYXJhbXNcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZVxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGlcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmZvcm1Hcm91cCA9PT0gdW5kZWZpbmVkKSB7XHJcblxyXG4gICAgICAgICAgICBsZXQgZm91bmREZWxheVZhbGlkYXRpb25Qcm9wZXJ0eTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgZm9yIChsZXQgY29sdW1uRGVmIG9mIHBhcmFtcy5ub2RlLmdyaWRBcGkuY29sdW1uQ29udHJvbGxlci5jb2x1bW5EZWZzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29sdW1uRGVmLmRlbGF5VmFsaWRhdGlvbiAmJiBjb2x1bW5EZWYuZGVsYXlWYWxpZGF0aW9uID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm91bmREZWxheVZhbGlkYXRpb25Qcm9wZXJ0eSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghZm91bmREZWxheVZhbGlkYXRpb25Qcm9wZXJ0eSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kZXRlcm1pbmVJZkFsbFJvd3NOZWVkVmFsaWRhdGlvbkluQWR2YW5jZSgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVBbGxGb3JtQ29udHJvbHMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5nZXRFcnJvck1lc3NhZ2UoKTtcclxuXHJcbiAgICAgICAgdGhpcy5hZ0luaXQyKHBhcmFtcyk7XHJcbiAgICB9XHJcblxyXG4gICAgYWJzdHJhY3QgYWdJbml0MihwYXJhbXMpOiB2b2lkO1xyXG5cclxuXHJcbiAgICByZWZyZXNoKHBhcmFtczogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFRoaXMgZnVuY3Rpb24gaXRlcmF0ZXMgb3ZlciBldmVyeSBjZWxsIGluIHRoZSBncmlkIGFuZCBwcmVwYXJlcyBhbGwgdGhlaXIgbmVlZGVkIGZvcm1Hcm91cHMgYW5kIGZvcm1Db250cm9scy5cclxuICAgIC8vXHJcbiAgICAvLyBUaGlzIHdhcyBkb25lIHRoaXMgd2F5IChpbiB0aGUgY2VsbCByZW5kZXJlcikgZm9yIHRocmVlIHJlYXNvbnMgOlxyXG4gICAgLy8gICAxLiBXZSBuZWVkIHRvIHdhaXQgdW50aWwgdGhlIGNvbHVtbiBhbmQgcm93IGRhdGEgaGF2ZSBiZWVuIHByb3ZpZGVkIHRvIHRoZSBncmlkXHJcbiAgICAvLyAgIDIuIFdlIGRvbid0IHdhbnQgdGhlIHByb2dyYW1tZXIgdG8gaGF2ZSB0byBpbXBsZW1lbnQgaXQgdGhlbXNlbHZlcyBldmVyeSB0aW1lIHRoZXkgY3JlYXRlIGEgZ3JpZFxyXG4gICAgLy8gICAzLiBUaGUgZ3JpZCBkb2VzIG5vdCBjcmVhdGUgYWxsIHRoZSBjZWxsIHJlbmRlcmVycyBpbiBhZHZhbmNlLCBqdXN0IHRob3NlIHRoYXQgZml0IG9uIHRoZSBzY3JlZW5cclxuICAgIC8vICAgICAgKHBsdXMgYSBmZXcgbmVhcmJ5KSBtZWFuaW5nIHdlIGNhbid0IGp1c3QgdXNlIHRoZSBjZWxsIHJlbmRlcmVyJ3MgY29uc3RydWN0b3IsIHNpbmNlIHdlIGRvbid0XHJcbiAgICAvLyAgICAgIGtub3cgaWYgdGhlIGluZm9ybWF0aW9uIHdlIHN0YXJ0IHdpdGggaXMgdmFsaWQgb24gZXZlcnkgc2NyZWVuLCBhbmQgYmVjYXVzZSB3ZSBoYXZlIHNvbWUgY2FsbHNcclxuICAgIC8vICAgICAgdGhhdCBzZW5kIGJhY2sgdGhlIGVudGlyZSBncmlkJ3Mgd29ydGggb2YgZGF0YS5cclxuICAgIC8vXHJcbiAgICAvLyBUaGVyZSBtYXkgYmUgYSBiZXR0ZXIgd2F5IHRvIGRvIHRoaXMsIGluIHdoaWNoIGNhc2UgdGhpcyBzaG91bGQgcHJvYmFibHkgYmUgcmVwbGFjZWQhXHJcbiAgICBjcmVhdGVBbGxGb3JtQ29udHJvbHMoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMucGFyYW1zXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLmNvbHVtblxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5jb2x1bW4uY29sRGVmXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLmRhdGFcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZVxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGlcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdldE1vZGVsKCkpIHtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ3JpZE9wdGlvbnNXcmFwcGVyXHJcbiAgICAgICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ3JpZE9wdGlvbnNXcmFwcGVyLmdyaWRPcHRpb25zXHJcbiAgICAgICAgICAgICAgICAmJiAhdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlci5ncmlkT3B0aW9ucy5fZXZlbnRzQ2hhbmdlZEJ5Q2VsbFJlbmRlcmVyVmFsaWRhdGlvbikge1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlR3JpZE9wdGlvbnNFdmVudHMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ3JpZE9wdGlvbnNXcmFwcGVyLmdyaWRPcHRpb25zLl9ldmVudHNDaGFuZ2VkQnlDZWxsUmVuZGVyZXJWYWxpZGF0aW9uID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGV0IGFsbE5vZGVzID0gW107XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLm1vZGVfbmVlZFRvVmFsaWRhdGVPbmx5UmVuZGVyZWRDZWxscykge1xyXG4gICAgICAgICAgICAgICAgYWxsTm9kZXMgPSB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ2V0UmVuZGVyZWROb2RlcygpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYWxsTm9kZXMgPSB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ2V0TW9kZWwoKS5yb3dzVG9EaXNwbGF5O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXBcclxuICAgICAgICAgICAgICAgIHx8ICh0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZm9ybUdyb3VwXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmZvcm1Hcm91cC5jb250cm9sc1xyXG4gICAgICAgICAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXAuY29udHJvbHMubGVuZ3RoICE9IGFsbE5vZGVzLmxlbmd0aCkpIHtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZm9ybUdyb3VwID0gbmV3IFVudHlwZWRGb3JtR3JvdXAoe30pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmNvbHVtbkNvbnRyb2xsZXJcclxuICAgICAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5jb2x1bW5Db250cm9sbGVyLmNvbHVtbkRlZnMpIHtcclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBjb2x1bW5EZWYgb2YgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmNvbHVtbkNvbnRyb2xsZXIuY29sdW1uRGVmcykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb2x1bW5EZWYub3V0ZXJGb3JtICYmIGNvbHVtbkRlZi5mb3JtTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbHVtbkRlZi5vdXRlckZvcm0uZ2V0KGNvbHVtbkRlZi5mb3JtTmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbkRlZi5vdXRlckZvcm0uYWRkQ29udHJvbChjb2x1bW5EZWYuZm9ybU5hbWUsIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uRGVmLm91dGVyRm9ybS5zZXRDb250cm9sKGNvbHVtbkRlZi5mb3JtTmFtZSwgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmZvcm1Hcm91cCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGxldCBjb2x1bW5zOiBhbnlbXTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnBhcmFtcyAmJiB0aGlzLnBhcmFtcy5jb2x1bW5BcGkgJiYgdGhpcy5wYXJhbXMuY29sdW1uQXBpLmNvbHVtbkNvbnRyb2xsZXIpIHtcclxuICAgICAgICAgICAgICAgIGNvbHVtbnMgPSB0aGlzLnBhcmFtcy5jb2x1bW5BcGkuY29sdW1uQ29udHJvbGxlci5ncmlkQ29sdW1ucy5maWx0ZXIoKGNvbHVtbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb2x1bW4uY29sRGVmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICYmIGNvbHVtbi5jb2xEZWYuZmllbGRcclxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGNvbHVtbi5jb2xEZWYudmFsaWRhdG9ycyB8fCBjb2x1bW4uY29sRGVmLnNldEVycm9ycyk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZm9yIChsZXQgbm9kZSBvZiBhbGxOb2Rlcykge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgY29sdW1uIG9mIGNvbHVtbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY29sdW1uLmNvbERlZlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiBjb2x1bW4uY29sRGVmLmZpZWxkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICYmIChjb2x1bW4uY29sRGVmLnZhbGlkYXRvcnMgfHwgY29sdW1uLmNvbERlZi5zZXRFcnJvcnMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVbY29sdW1uLmNvbERlZi5maWVsZCArIFwiX2Vycm9yTWVzc2FnZVwiXSA9ICcnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZvcm1Db250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wgPSBuZXcgVW50eXBlZEZvcm1Db250cm9sKGNvbHVtbi5jb2xEZWYuZmllbGQgKyAnX2Zvcm1Db250cm9sJywgW10pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFub2RlLmZvcm1Hcm91cCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5mb3JtR3JvdXAgPSBuZXcgVW50eXBlZEZvcm1Hcm91cCh7fSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuZm9ybUdyb3VwLmFkZENvbnRyb2woY29sdW1uLmNvbERlZi5maWVsZCArICdfZm9ybUNvbnRyb2wnLCBmb3JtQ29udHJvbCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoY29sdW1uLmNvbERlZi52YWxpZGF0b3JzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uLmNvbERlZi52YWxpZGF0b3JzID0gW2NvbHVtbi5jb2xEZWYudmFsaWRhdG9yc107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sLnNldFZhbGlkYXRvcnMoY29sdW1uLmNvbERlZi52YWxpZGF0b3JzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRXJyb3JNZXNzYWdlKGZvcm1Db250cm9sLCBub2RlLCBjb2x1bW4uY29sRGVmKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZm9ybUdyb3VwLmNvbnRhaW5zKCdSb3dHcm91cF8nICsgbm9kZS5yb3dJbmRleCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vZGUuZm9ybUdyb3VwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuZm9ybUdyb3VwID0gbmV3IFVudHlwZWRGb3JtR3JvdXAoe30pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZm9ybUdyb3VwLmFkZENvbnRyb2woJ1Jvd0dyb3VwXycgKyBub2RlLnJvd0luZGV4LCBub2RlLmZvcm1Hcm91cCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBjaGFuZ2VHcmlkT3B0aW9uc0V2ZW50cygpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMucGFyYW1zXHJcbiAgICAgICAgICAgIHx8ICF0aGlzLnBhcmFtcy5ub2RlXHJcbiAgICAgICAgICAgIHx8ICF0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGlcclxuICAgICAgICAgICAgfHwgIXRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXJcclxuICAgICAgICAgICAgfHwgIXRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXIuZ3JpZE9wdGlvbnMpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXIuZ3JpZE9wdGlvbnMub25Sb3dEYXRhQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ3JpZE9wdGlvbnNXcmFwcGVyLmdyaWRPcHRpb25zLm9uUm93RGF0YUNoYW5nZWQyID0gdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlci5ncmlkT3B0aW9ucy5vblJvd0RhdGFDaGFuZ2VkO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlci5ncmlkT3B0aW9ucy5vblJvd0RhdGFDaGFuZ2VkID0gKChldmVudDogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlQWxsRm9ybUNvbnRyb2xzKCk7XHJcbiAgICAgICAgICAgIHRoaXMuZmV0Y2hFcnJvck1lc3NhZ2VzRm9yQ3VycmVudGx5UmVuZGVyZWRDZWxscygpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXIuZ3JpZE9wdGlvbnMub25Sb3dEYXRhQ2hhbmdlZDIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXIuZ3JpZE9wdGlvbnMub25Sb3dEYXRhQ2hhbmdlZDIoZXZlbnQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG5cclxuICAgICAgICBpZiAodGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlci5ncmlkT3B0aW9ucy5vbkdyaWRDb2x1bW5zQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ3JpZE9wdGlvbnNXcmFwcGVyLmdyaWRPcHRpb25zLm9uR3JpZENvbHVtbnNDaGFuZ2VkMiA9IHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXIuZ3JpZE9wdGlvbnMub25HcmlkQ29sdW1uc0NoYW5nZWQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ3JpZE9wdGlvbnNXcmFwcGVyLmdyaWRPcHRpb25zLm9uR3JpZENvbHVtbnNDaGFuZ2VkID0gKChldmVudDogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuZGV0ZXJtaW5lSWZBbGxSb3dzTmVlZFZhbGlkYXRpb25JbkFkdmFuY2UoKTtcclxuICAgICAgICAgICAgdGhpcy5jcmVhdGVBbGxGb3JtQ29udHJvbHMoKTtcclxuICAgICAgICAgICAgdGhpcy5mZXRjaEVycm9yTWVzc2FnZXNGb3JDdXJyZW50bHlSZW5kZXJlZENlbGxzKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlci5ncmlkT3B0aW9ucy5vbkdyaWRDb2x1bW5zQ2hhbmdlZDIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXIuZ3JpZE9wdGlvbnMub25HcmlkQ29sdW1uc0NoYW5nZWQyKGV2ZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0RXJyb3JNZXNzYWdlKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLnBhcmFtc1xyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLm5vZGUuZm9ybUdyb3VwXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLmNvbHVtblxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5jb2x1bW4uY29sRGVmXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLmNvbHVtbi5jb2xEZWYuZmllbGQpIHtcclxuXHJcbiAgICAgICAgICAgIGxldCBmb3JtQ29udHJvbCA9IHRoaXMucGFyYW1zLm5vZGUuZm9ybUdyb3VwLmdldCh0aGlzLnBhcmFtcy5jb2x1bW4uY29sRGVmLmZpZWxkICsgJ19mb3JtQ29udHJvbCcpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy51cGRhdGVFcnJvck1lc3NhZ2UoZm9ybUNvbnRyb2wsIHRoaXMucGFyYW1zLm5vZGUsIHRoaXMucGFyYW1zLmNvbHVtbi5jb2xEZWYpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5lcnJvck1lc3NhZ2UgPSB0aGlzLnBhcmFtcy5ub2RlW3RoaXMucGFyYW1zLmNvbHVtbi5jb2xEZWYuZmllbGQgKyBcIl9lcnJvck1lc3NhZ2VcIl07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgcmVmcmVzaEZvcm1Db250cm9sVmFsdWUoZm9ybUNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCwgZGF0YTogYW55LCBmaWVsZE5hbWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGlmIChmb3JtQ29udHJvbCAmJiBkYXRhICYmIGZpZWxkTmFtZSAmJiBkYXRhW2ZpZWxkTmFtZV0gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBmb3JtQ29udHJvbC5zZXRWYWx1ZShkYXRhW2ZpZWxkTmFtZV0pO1xyXG4gICAgICAgICAgICBmb3JtQ29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgdXBkYXRlRXJyb3JNZXNzYWdlKGZvcm1Db250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wsIG5vZGU6IGFueSwgY29sdW1uRGVmaW5pdGlvbjogYW55KTogc3RyaW5nIHtcclxuICAgICAgICBpZiAoIWZvcm1Db250cm9sIHx8ICFub2RlIHx8ICFjb2x1bW5EZWZpbml0aW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBjdXN0b21FcnJvck1lc3NhZ2U6IHN0cmluZyA9ICcnO1xyXG5cclxuICAgICAgICBpZiAoY29sdW1uRGVmaW5pdGlvbi5zZXRFcnJvcnMpIHtcclxuICAgICAgICAgICAgY3VzdG9tRXJyb3JNZXNzYWdlID0gY29sdW1uRGVmaW5pdGlvbi5zZXRFcnJvcnMoXHJcbiAgICAgICAgICAgICAgICBub2RlLmRhdGFbY29sdW1uRGVmaW5pdGlvbi5maWVsZF0sXHJcbiAgICAgICAgICAgICAgICBub2RlLmRhdGEsXHJcbiAgICAgICAgICAgICAgICBub2RlLFxyXG4gICAgICAgICAgICAgICAgY29sdW1uRGVmaW5pdGlvbixcclxuICAgICAgICAgICAgICAgIG5vZGUucm93SW5kZXgsXHJcbiAgICAgICAgICAgICAgICBub2RlLmdyaWRBcGlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBlcnJvck1lc3NhZ2VOYW1lOiBzdHJpbmcgPSBjb2x1bW5EZWZpbml0aW9uLmZpZWxkICsgXCJfZXJyb3JNZXNzYWdlXCI7XHJcblxyXG4gICAgICAgIHRoaXMucmVmcmVzaEZvcm1Db250cm9sVmFsdWUoZm9ybUNvbnRyb2wsIG5vZGUuZGF0YSwgY29sdW1uRGVmaW5pdGlvbi5maWVsZCk7XHJcblxyXG4gICAgICAgIG5vZGVbZXJyb3JNZXNzYWdlTmFtZV0gPSAnJztcclxuXHJcbiAgICAgICAgaWYgKGZvcm1Db250cm9sLmludmFsaWQgfHwgKGN1c3RvbUVycm9yTWVzc2FnZSAmJiBjdXN0b21FcnJvck1lc3NhZ2UgIT09ICcnKSkge1xyXG4gICAgICAgICAgICBpZiAoY29sdW1uRGVmaW5pdGlvbi5lcnJvck1lc3NhZ2VIZWFkZXIpIHtcclxuICAgICAgICAgICAgICAgIG5vZGVbZXJyb3JNZXNzYWdlTmFtZV0gKz0gJycgKyBjb2x1bW5EZWZpbml0aW9uLmVycm9yTWVzc2FnZUhlYWRlciArICdcXG4nO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbm9kZVtlcnJvck1lc3NhZ2VOYW1lXSArPVxyXG4gICAgICAgICAgICAgICAgICAgICdJbnZhbGlkIHZhbHVlIFwiJyArIG5vZGUuZGF0YVtjb2x1bW5EZWZpbml0aW9uLmZpZWxkXSArICdcIiBmb3IgZmllbGQgKCcgKyBjb2x1bW5EZWZpbml0aW9uLmZpZWxkICsgJylcXG4nO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoY29sdW1uRGVmaW5pdGlvbi5lcnJvck5hbWVFcnJvck1lc3NhZ2VNYXApIHtcclxuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGNvbHVtbkRlZmluaXRpb24uZXJyb3JOYW1lRXJyb3JNZXNzYWdlTWFwKSkge1xyXG4gICAgICAgICAgICAgICAgY29sdW1uRGVmaW5pdGlvbi5lcnJvck5hbWVFcnJvck1lc3NhZ2VNYXAgPSBbY29sdW1uRGVmaW5pdGlvbi5lcnJvck5hbWVFcnJvck1lc3NhZ2VNYXBdO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBlcnJvck5hbWVFcnJvck1lc3NhZ2VQYWlyIG9mIGNvbHVtbkRlZmluaXRpb24uZXJyb3JOYW1lRXJyb3JNZXNzYWdlTWFwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvck5hbWVFcnJvck1lc3NhZ2VQYWlyLmVycm9yTmFtZSAmJiAhIWVycm9yTmFtZUVycm9yTWVzc2FnZVBhaXIuZXJyb3JNZXNzYWdlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZvcm1Db250cm9sLmhhc0Vycm9yKGVycm9yTmFtZUVycm9yTWVzc2FnZVBhaXIuZXJyb3JOYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlW2Vycm9yTWVzc2FnZU5hbWVdICs9IGVycm9yTmFtZUVycm9yTWVzc2FnZVBhaXIuZXJyb3JNZXNzYWdlICsnXFxuJztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG5vZGVbZXJyb3JNZXNzYWdlTmFtZV0gKz0gY3VzdG9tRXJyb3JNZXNzYWdlO1xyXG5cclxuICAgICAgICByZXR1cm4gbm9kZVtlcnJvck1lc3NhZ2VOYW1lXTtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgZGV0ZXJtaW5lSWZBbGxSb3dzTmVlZFZhbGlkYXRpb25JbkFkdmFuY2UoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMucGFyYW1zXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLm5vZGVcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLmNvbHVtbkFwaVxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5jb2x1bW5BcGkuY29sdW1uQ29udHJvbGxlclxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5jb2x1bW5BcGkuY29sdW1uQ29udHJvbGxlci5ncmlkQ29sdW1ucykge1xyXG5cclxuICAgICAgICAgICAgbGV0IGNvbHVtbnMgPSB0aGlzLnBhcmFtcy5jb2x1bW5BcGkuY29sdW1uQ29udHJvbGxlci5ncmlkQ29sdW1ucy5maWx0ZXIoKGNvbHVtbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbHVtbi5jb2xEZWZcclxuICAgICAgICAgICAgICAgICAgICAmJiBjb2x1bW4uY29sRGVmLmZpZWxkXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgKGNvbHVtbi5jb2xEZWYudmFsaWRhdG9ycyB8fCBjb2x1bW4uY29sRGVmLnNldEVycm9ycylcclxuICAgICAgICAgICAgICAgICAgICAmJiBjb2x1bW4uY29sRGVmLmVkaXRhYmxlID09PSB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgIShjb2x1bW4uY29sRGVmLnZhbGlkYXRlT25seVJlbmRlcmVkQ2VsbHNcclxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgY29sdW1uLmNvbERlZi52YWxpZGF0ZU9ubHlSZW5kZXJlZENlbGxzID09PSB0cnVlKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkubW9kZV9uZWVkVG9WYWxpZGF0ZU9ubHlSZW5kZXJlZENlbGxzID0gQXJyYXkuaXNBcnJheShjb2x1bW5zKSAmJiBjb2x1bW5zLmxlbmd0aCA9PT0gMDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGZldGNoRXJyb3JNZXNzYWdlc0ZvckN1cnJlbnRseVJlbmRlcmVkQ2VsbHMoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMucGFyYW1zXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLm5vZGVcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpKSB7XHJcblxyXG4gICAgICAgICAgICBsZXQgZ2V0Q2VsbFJlbmRlcmVyUGFyYW1zOiBhbnkgPSB7IHJvd05vZGVzOiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ2V0UmVuZGVyZWROb2RlcygpIH07XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBjZWxsUmVuZGVyZXIgb2YgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdldENlbGxSZW5kZXJlckluc3RhbmNlcyhnZXRDZWxsUmVuZGVyZXJQYXJhbXMpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY2VsbFJlbmRlcmVyLl9hZ0F3YXJlQ29tcG9uZW50ICYmIGNlbGxSZW5kZXJlci5fYWdBd2FyZUNvbXBvbmVudC5nZXRFcnJvck1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBjZWxsUmVuZGVyZXIuX2FnQXdhcmVDb21wb25lbnQuZ2V0RXJyb3JNZXNzYWdlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHVwZGF0ZVZhbGlkYXRpb24oKTogdm9pZCB7XHJcbiAgICAgICAgY29uc29sZS5sb2coXCJTdWNjZXNzZnVsbHkgcmVhY2hlZCFcIik7XHJcbiAgICAgICAgLy8gYWRkIHRoaXMgZm9ybSBjb250cm9sXHJcblxyXG4gICAgICAgIGxldCBjb2x1bW5zID0gdGhpcy5wYXJhbXMuY29sdW1uQXBpLmNvbHVtbkNvbnRyb2xsZXIuZ3JpZENvbHVtbnMuZmlsdGVyKChjb2x1bW4pID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIGNvbHVtbi5jb2xEZWZcclxuICAgICAgICAgICAgICAgICYmIGNvbHVtbi5jb2xEZWYuZmllbGRcclxuICAgICAgICAgICAgICAgICYmIChjb2x1bW4uY29sRGVmLnZhbGlkYXRvcnMgfHwgY29sdW1uLmNvbERlZi5zZXRFcnJvcnMpXHJcbiAgICAgICAgICAgICAgICAmJiBjb2x1bW4uY29sRGVmLmZpZWxkID09PSB0aGlzLnBhcmFtcy5maWVsZDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMucGFyYW1zLmNvbERlZlxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5jb2xEZWYuZmllbGRcclxuICAgICAgICAgICAgJiYgKHRoaXMucGFyYW1zLmNvbERlZi52YWxpZGF0b3JzIHx8IHRoaXMucGFyYW1zLmNvbERlZi5zZXRFcnJvcnMpKSB7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnBhcmFtcy5ub2RlW3RoaXMucGFyYW1zLmNvbERlZi5maWVsZCArIFwiX2Vycm9yTWVzc2FnZVwiXSA9ICcnO1xyXG5cclxuICAgICAgICAgICAgbGV0IGZvcm1Db250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wgPSBuZXcgVW50eXBlZEZvcm1Db250cm9sKHRoaXMucGFyYW1zLmNvbERlZi5maWVsZCArICdfZm9ybUNvbnRyb2wnLCBbXSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMucGFyYW1zLm5vZGUuZm9ybUdyb3VwKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBhcmFtcy5ub2RlLmZvcm1Hcm91cCA9IG5ldyBVbnR5cGVkRm9ybUdyb3VwKHt9KTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZm9ybUdyb3VwID0gbmV3IFVudHlwZWRGb3JtR3JvdXAoe30pO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBmb3IgYW55IHJlbW92ZWQgbm9kZXMgJiByZW1vdmUgdGhlaXIgdmFsaWRhdG9ycyBpZiBuZWVkZWQuXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgY29udHJvbE5hbWUgb2YgT2JqZWN0LmtleXModGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmZvcm1Hcm91cC5jb250cm9scykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgnJyArIGNvbnRyb2xOYW1lKS50b0xvd2VyQ2FzZSgpLnN1YnN0cigwLCA5KSA9PT0gJ3Jvd2dyb3VwXycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmb3VuZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgbm9kZSBvZiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ2V0TW9kZWwoKS5yb3dzVG9EaXNwbGF5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgnJyArIG5vZGUucm93SW5kZXgpID09PSAoJycgKyBjb250cm9sTmFtZSkuc3Vic3RyKDkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmb3VuZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXAucmVtb3ZlQ29udHJvbChjb250cm9sTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXAuYWRkQ29udHJvbCgnUm93R3JvdXBfJyArIHRoaXMucGFyYW1zLm5vZGUucm93SW5kZXgsIHRoaXMucGFyYW1zLm5vZGUuZm9ybUdyb3VwKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLnBhcmFtcy5ub2RlLmZvcm1Hcm91cC5jb250cm9sc1t0aGlzLnBhcmFtcy5jb2xEZWYuZmllbGQgKyAnX2Zvcm1Db250cm9sJ10pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZm9ybUdyb3VwLmFkZENvbnRyb2wodGhpcy5wYXJhbXMuY29sRGVmLmZpZWxkICsgJ19mb3JtQ29udHJvbCcsIGZvcm1Db250cm9sKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnBhcmFtcy5jb2xEZWYudmFsaWRhdG9ycykpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmFtcy5ub2RlLmZvcm1Hcm91cC5jb250cm9sc1t0aGlzLnBhcmFtcy5jb2xEZWYuZmllbGQgKyAnX2Zvcm1Db250cm9sJ10uc2V0VmFsaWRhdG9ycyh0aGlzLnBhcmFtcy5jb2xEZWYudmFsaWRhdG9ycyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5jb2x1bW5Db250cm9sbGVyXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmNvbHVtbkNvbnRyb2xsZXIuY29sdW1uRGVmcykge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBjb2x1bW5EZWYgb2YgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmNvbHVtbkNvbnRyb2xsZXIuY29sdW1uRGVmcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29sdW1uRGVmLm91dGVyRm9ybSAmJiBjb2x1bW5EZWYuZm9ybU5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29sdW1uRGVmLm91dGVyRm9ybS5nZXQoY29sdW1uRGVmLmZvcm1OYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbkRlZi5vdXRlckZvcm0uYWRkQ29udHJvbChjb2x1bW5EZWYuZm9ybU5hbWUsIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5EZWYub3V0ZXJGb3JtLnNldENvbnRyb2woY29sdW1uRGVmLmZvcm1OYW1lLCB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZm9ybUdyb3VwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy51cGRhdGVFcnJvck1lc3NhZ2UoZm9ybUNvbnRyb2wsIHRoaXMucGFyYW1zLm5vZGUsIHRoaXMucGFyYW1zLmNvbERlZik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBhZGQgY29sdW1uIGNvbnRyb2wgZ3JvdXBzIGlmIG5lZWRlZFxyXG4gICAgICAgIC8vIGFkZCByb3cgY29udHJvbCBncm91cHMgaWYgbmVlZGVkXHJcbiAgICAgICAgLy8gc2V0dXAgZ3JpZCBjb250cm9sIGdyb3VwIGlmIG5lZWRlZFxyXG4gICAgICAgIC8vIE1pZ2h0IG5lZWQgdG8gdHJpZ2dlciBjZWxsIHZhbGlkYXRpb24gdG8gcnVuIHdpdGggdGhlIG5ldyB2YWxpZGF0aW9uLlxyXG4gICAgfVxyXG59XHJcbiJdfQ==
1
+ import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from "@angular/forms";
2
+ /**
3
+ * This class' purpose is to place FormControls on cells in the grid, and to link them by rows, and rows to the grid as a whole.
4
+ * It allows you to add validators for a cells' value and link an error type to an error message to display in a tooltip, or
5
+ * you can provide a function to test some information about the row and provide an error message.
6
+ *
7
+ * The class works off of a number of properties added to the columnDefs in the ag-grid.
8
+ *
9
+ * We are looking for the following properties:
10
+ * 1. errorMessageHeader : a string to display at the top of the list of any errors found for the cell
11
+ * 2. validators : an array of angular validators to describe the cell value
12
+ * 3. errorNameErrorMessageMap : an array of objects with "errorName"s and "errorMessage"s that are used to create a displayed list for the user
13
+ * 4. setErrors: a function with the signature:
14
+ * (value: any, data: any, node: any, colDef: any, rowIndex: any, gridApi: any) => string
15
+ * which is called to generate a custom error message, if needed. An empty or null string
16
+ * is treated as not being an error.
17
+ *
18
+ * Example column definition:
19
+ * {
20
+ * headerName: "Name",
21
+ * editable: false,
22
+ * width: 600,
23
+ * cellRendererFramework: TextAlignLeftMiddleRenderer,
24
+ * setErrors: (value: any,
25
+ * data: any,
26
+ * node: any,
27
+ * colDef: any,
28
+ * rowIndex: any,
29
+ * gridApi: any) => {
30
+ * return (value && value === 'TEST') ? 'Invalid name' : '';
31
+ * },
32
+ * validators: [ Validators.minLength(10) ],
33
+ * errorMessageHeader: 'TestingTestingTesting',
34
+ * errorNameErrorMessageMap: [
35
+ * { errorName: 'minlength', errorMessage: 'Name is too short' }
36
+ * ],
37
+ * field: "name"
38
+ * }
39
+ *
40
+ * To use with a new renderer, extend this class, do not override agInit, or call super.agInit(params) first.
41
+ * (You can use agInit2 instead, called right after agInit).
42
+ *
43
+ * To display a tooltip with the error messages, include an element with a matTooltip pointing to this.errorMessage, like:
44
+ * <div [matTooltip]="this.errorMessage" [matTooltipShowDelay]="300" [matTooltipHideDelay]="300" ...
45
+ * For cell highlighting, you can add a CSS class something like :
46
+ * .error {
47
+ * background: linear-gradient(rgba(255,0,0,0.25), rgba(255,0,0,0.25), rgba(255,0,0,0.25));
48
+ * border: solid red 2px;
49
+ * }
50
+ * and a conditional class on an element in the template, like :
51
+ * class="{{this.errorMessage && this.errorMessage !== '' ? 'error' : ''}}"
52
+ */
53
+ export class CellRendererValidation {
54
+ constructor() {
55
+ this.errorMessage = "";
56
+ }
57
+ agInit(params) {
58
+ this.params = params;
59
+ this.formBuilder = new UntypedFormBuilder();
60
+ if (this.params
61
+ && this.params.node
62
+ && this.params.node.gridApi
63
+ && this.params.node.gridApi.formGroup === undefined) {
64
+ let foundDelayValidationProperty = false;
65
+ for (let columnDef of params.node.gridApi.columnController.columnDefs) {
66
+ if (columnDef.delayValidation && columnDef.delayValidation === true) {
67
+ foundDelayValidationProperty = true;
68
+ }
69
+ }
70
+ if (!foundDelayValidationProperty) {
71
+ this.determineIfAllRowsNeedValidationInAdvance();
72
+ this.createAllFormControls();
73
+ }
74
+ }
75
+ this.getErrorMessage();
76
+ this.agInit2(params);
77
+ }
78
+ refresh(params) {
79
+ return false;
80
+ }
81
+ // This function iterates over every cell in the grid and prepares all their needed formGroups and formControls.
82
+ //
83
+ // This was done this way (in the cell renderer) for three reasons :
84
+ // 1. We need to wait until the column and row data have been provided to the grid
85
+ // 2. We don't want the programmer to have to implement it themselves every time they create a grid
86
+ // 3. The grid does not create all the cell renderers in advance, just those that fit on the screen
87
+ // (plus a few nearby) meaning we can't just use the cell renderer's constructor, since we don't
88
+ // know if the information we start with is valid on every screen, and because we have some calls
89
+ // that send back the entire grid's worth of data.
90
+ //
91
+ // There may be a better way to do this, in which case this should probably be replaced!
92
+ createAllFormControls() {
93
+ if (this.params
94
+ && this.params.column
95
+ && this.params.column.colDef
96
+ && this.params.data
97
+ && this.params.node
98
+ && this.params.node.gridApi
99
+ && this.params.node.gridApi.getModel()) {
100
+ if (this.params.node.gridApi.gridOptionsWrapper
101
+ && this.params.node.gridApi.gridOptionsWrapper.gridOptions
102
+ && !this.params.node.gridApi.gridOptionsWrapper.gridOptions._eventsChangedByCellRendererValidation) {
103
+ this.changeGridOptionsEvents();
104
+ this.params.node.gridApi.gridOptionsWrapper.gridOptions._eventsChangedByCellRendererValidation = true;
105
+ }
106
+ let allNodes = [];
107
+ if (this.params.node.gridApi.mode_needToValidateOnlyRenderedCells) {
108
+ allNodes = this.params.node.gridApi.getRenderedNodes();
109
+ }
110
+ else {
111
+ allNodes = this.params.node.gridApi.getModel().rowsToDisplay;
112
+ }
113
+ if (!this.params.node.gridApi.formGroup
114
+ || (this.params.node.gridApi.formGroup
115
+ && this.params.node.gridApi.formGroup.controls
116
+ && this.params.node.gridApi.formGroup.controls.length != allNodes.length)) {
117
+ this.params.node.gridApi.formGroup = new UntypedFormGroup({});
118
+ }
119
+ if (this.params.node.gridApi.columnController
120
+ && this.params.node.gridApi.columnController.columnDefs) {
121
+ for (let columnDef of this.params.node.gridApi.columnController.columnDefs) {
122
+ if (columnDef.outerForm && columnDef.formName) {
123
+ if (!columnDef.outerForm.get(columnDef.formName)) {
124
+ columnDef.outerForm.addControl(columnDef.formName, this.params.node.gridApi.formGroup);
125
+ }
126
+ else {
127
+ columnDef.outerForm.setControl(columnDef.formName, this.params.node.gridApi.formGroup);
128
+ }
129
+ }
130
+ }
131
+ }
132
+ let columns;
133
+ if (this.params && this.params.columnApi && this.params.columnApi.columnController) {
134
+ columns = this.params.columnApi.columnController.gridColumns.filter((column) => {
135
+ return column.colDef
136
+ && column.colDef.field
137
+ && (column.colDef.validators || column.colDef.setErrors);
138
+ });
139
+ }
140
+ for (let node of allNodes) {
141
+ for (let column of columns) {
142
+ if (column.colDef
143
+ && column.colDef.field
144
+ && (column.colDef.validators || column.colDef.setErrors)) {
145
+ node[column.colDef.field + "_errorMessage"] = '';
146
+ let formControl = new UntypedFormControl(column.colDef.field + '_formControl', []);
147
+ if (!node.formGroup) {
148
+ node.formGroup = new UntypedFormGroup({});
149
+ }
150
+ node.formGroup.addControl(column.colDef.field + '_formControl', formControl);
151
+ if (!Array.isArray(column.colDef.validators)) {
152
+ column.colDef.validators = [column.colDef.validators];
153
+ }
154
+ formControl.setValidators(column.colDef.validators);
155
+ this.updateErrorMessage(formControl, node, column.colDef);
156
+ }
157
+ }
158
+ if (!this.params.node.gridApi.formGroup.contains('RowGroup_' + node.rowIndex)) {
159
+ if (!node.formGroup) {
160
+ node.formGroup = new UntypedFormGroup({});
161
+ }
162
+ this.params.node.gridApi.formGroup.addControl('RowGroup_' + node.rowIndex, node.formGroup);
163
+ }
164
+ }
165
+ }
166
+ }
167
+ changeGridOptionsEvents() {
168
+ if (!this.params
169
+ || !this.params.node
170
+ || !this.params.node.gridApi
171
+ || !this.params.node.gridApi.gridOptionsWrapper
172
+ || !this.params.node.gridApi.gridOptionsWrapper.gridOptions) {
173
+ return;
174
+ }
175
+ if (this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged) {
176
+ this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged2 = this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged;
177
+ }
178
+ this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged = ((event) => {
179
+ this.createAllFormControls();
180
+ this.fetchErrorMessagesForCurrentlyRenderedCells();
181
+ if (this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged2) {
182
+ this.params.node.gridApi.gridOptionsWrapper.gridOptions.onRowDataChanged2(event);
183
+ }
184
+ });
185
+ if (this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged) {
186
+ this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged2 = this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged;
187
+ }
188
+ this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged = ((event) => {
189
+ this.determineIfAllRowsNeedValidationInAdvance();
190
+ this.createAllFormControls();
191
+ this.fetchErrorMessagesForCurrentlyRenderedCells();
192
+ if (this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged2) {
193
+ this.params.node.gridApi.gridOptionsWrapper.gridOptions.onGridColumnsChanged2(event);
194
+ }
195
+ });
196
+ }
197
+ getErrorMessage() {
198
+ if (this.params
199
+ && this.params.node
200
+ && this.params.node.formGroup
201
+ && this.params.column
202
+ && this.params.column.colDef
203
+ && this.params.column.colDef.field) {
204
+ let formControl = this.params.node.formGroup.get(this.params.column.colDef.field + '_formControl');
205
+ this.updateErrorMessage(formControl, this.params.node, this.params.column.colDef);
206
+ this.errorMessage = this.params.node[this.params.column.colDef.field + "_errorMessage"];
207
+ }
208
+ }
209
+ refreshFormControlValue(formControl, data, fieldName) {
210
+ if (formControl && data && fieldName && data[fieldName] !== undefined) {
211
+ formControl.setValue(data[fieldName]);
212
+ formControl.updateValueAndValidity();
213
+ }
214
+ }
215
+ updateErrorMessage(formControl, node, columnDefinition) {
216
+ if (!formControl || !node || !columnDefinition) {
217
+ return '';
218
+ }
219
+ let customErrorMessage = '';
220
+ if (columnDefinition.setErrors) {
221
+ customErrorMessage = columnDefinition.setErrors(node.data[columnDefinition.field], node.data, node, columnDefinition, node.rowIndex, node.gridApi);
222
+ }
223
+ let errorMessageName = columnDefinition.field + "_errorMessage";
224
+ this.refreshFormControlValue(formControl, node.data, columnDefinition.field);
225
+ node[errorMessageName] = '';
226
+ if (formControl.invalid || (customErrorMessage && customErrorMessage !== '')) {
227
+ if (columnDefinition.errorMessageHeader) {
228
+ node[errorMessageName] += '' + columnDefinition.errorMessageHeader + '\n';
229
+ }
230
+ else {
231
+ node[errorMessageName] +=
232
+ 'Invalid value "' + node.data[columnDefinition.field] + '" for field (' + columnDefinition.field + ')\n';
233
+ }
234
+ }
235
+ if (columnDefinition.errorNameErrorMessageMap) {
236
+ if (!Array.isArray(columnDefinition.errorNameErrorMessageMap)) {
237
+ columnDefinition.errorNameErrorMessageMap = [columnDefinition.errorNameErrorMessageMap];
238
+ }
239
+ for (let errorNameErrorMessagePair of columnDefinition.errorNameErrorMessageMap) {
240
+ if (!!errorNameErrorMessagePair.errorName && !!errorNameErrorMessagePair.errorMessage) {
241
+ if (formControl.hasError(errorNameErrorMessagePair.errorName)) {
242
+ node[errorMessageName] += errorNameErrorMessagePair.errorMessage + '\n';
243
+ }
244
+ }
245
+ }
246
+ }
247
+ node[errorMessageName] += customErrorMessage;
248
+ return node[errorMessageName];
249
+ }
250
+ determineIfAllRowsNeedValidationInAdvance() {
251
+ if (this.params
252
+ && this.params.node
253
+ && this.params.node.gridApi
254
+ && this.params.columnApi
255
+ && this.params.columnApi.columnController
256
+ && this.params.columnApi.columnController.gridColumns) {
257
+ let columns = this.params.columnApi.columnController.gridColumns.filter((column) => {
258
+ return column.colDef
259
+ && column.colDef.field
260
+ && (column.colDef.validators || column.colDef.setErrors)
261
+ && column.colDef.editable === true
262
+ && !(column.colDef.validateOnlyRenderedCells
263
+ && column.colDef.validateOnlyRenderedCells === true);
264
+ });
265
+ this.params.node.gridApi.mode_needToValidateOnlyRenderedCells = Array.isArray(columns) && columns.length === 0;
266
+ }
267
+ }
268
+ fetchErrorMessagesForCurrentlyRenderedCells() {
269
+ if (this.params
270
+ && this.params.node
271
+ && this.params.node.gridApi) {
272
+ let getCellRendererParams = { rowNodes: this.params.node.gridApi.getRenderedNodes() };
273
+ for (let cellRenderer of this.params.node.gridApi.getCellRendererInstances(getCellRendererParams)) {
274
+ if (cellRenderer._agAwareComponent && cellRenderer._agAwareComponent.getErrorMessage) {
275
+ cellRenderer._agAwareComponent.getErrorMessage();
276
+ }
277
+ }
278
+ }
279
+ }
280
+ updateValidation() {
281
+ console.log("Successfully reached!");
282
+ // add this form control
283
+ let columns = this.params.columnApi.columnController.gridColumns.filter((column) => {
284
+ return column.colDef
285
+ && column.colDef.field
286
+ && (column.colDef.validators || column.colDef.setErrors)
287
+ && column.colDef.field === this.params.field;
288
+ });
289
+ if (this.params.colDef
290
+ && this.params.colDef.field
291
+ && (this.params.colDef.validators || this.params.colDef.setErrors)) {
292
+ this.params.node[this.params.colDef.field + "_errorMessage"] = '';
293
+ let formControl = new UntypedFormControl(this.params.colDef.field + '_formControl', []);
294
+ if (!this.params.node.formGroup) {
295
+ this.params.node.formGroup = new UntypedFormGroup({});
296
+ if (!this.params.node.gridApi.formGroup) {
297
+ this.params.node.gridApi.formGroup = new UntypedFormGroup({});
298
+ }
299
+ else {
300
+ // check for any removed nodes & remove their validators if needed.
301
+ for (let controlName of Object.keys(this.params.node.gridApi.formGroup.controls)) {
302
+ if (('' + controlName).toLowerCase().substr(0, 9) === 'rowgroup_') {
303
+ let found = false;
304
+ for (let node of this.params.node.gridApi.getModel().rowsToDisplay) {
305
+ if (('' + node.rowIndex) === ('' + controlName).substr(9)) {
306
+ found = true;
307
+ break;
308
+ }
309
+ }
310
+ if (!found) {
311
+ this.params.node.gridApi.formGroup.removeControl(controlName);
312
+ }
313
+ }
314
+ }
315
+ }
316
+ this.params.node.gridApi.formGroup.addControl('RowGroup_' + this.params.node.rowIndex, this.params.node.formGroup);
317
+ }
318
+ if (!this.params.node.formGroup.controls[this.params.colDef.field + '_formControl']) {
319
+ this.params.node.formGroup.addControl(this.params.colDef.field + '_formControl', formControl);
320
+ if (Array.isArray(this.params.colDef.validators)) {
321
+ this.params.node.formGroup.controls[this.params.colDef.field + '_formControl'].setValidators(this.params.colDef.validators);
322
+ }
323
+ if (this.params.node.gridApi.columnController
324
+ && this.params.node.gridApi.columnController.columnDefs) {
325
+ for (let columnDef of this.params.node.gridApi.columnController.columnDefs) {
326
+ if (columnDef.outerForm && columnDef.formName) {
327
+ if (!columnDef.outerForm.get(columnDef.formName)) {
328
+ columnDef.outerForm.addControl(columnDef.formName, this.params.node.gridApi.formGroup);
329
+ }
330
+ else {
331
+ columnDef.outerForm.setControl(columnDef.formName, this.params.node.gridApi.formGroup);
332
+ }
333
+ }
334
+ }
335
+ }
336
+ }
337
+ this.updateErrorMessage(formControl, this.params.node, this.params.colDef);
338
+ }
339
+ // add column control groups if needed
340
+ // add row control groups if needed
341
+ // setup grid control group if needed
342
+ // Might need to trigger cell validation to run with the new validation.
343
+ }
344
+ }
345
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VsbC1yZW5kZXJlci12YWxpZGF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvZGljdGlvbmFyeS1lZGl0b3Ivc3JjL2dyaWQtcmVuZGVyZXJzL2NlbGwtcmVuZGVyZXItdmFsaWRhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUMsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQWEsTUFBTSxnQkFBZ0IsQ0FBQztBQUVwRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrREc7QUFDSCxNQUFNLE9BQWdCLHNCQUFzQjtJQUE1QztRQUlXLGlCQUFZLEdBQVcsRUFBRSxDQUFDO0lBZ1hyQyxDQUFDO0lBNVdHLE1BQU0sQ0FBQyxNQUFXO1FBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLGtCQUFrQixFQUFFLENBQUM7UUFFNUMsSUFBSSxJQUFJLENBQUMsTUFBTTtlQUNSLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSTtlQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPO2VBQ3hCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7WUFFdEQsSUFBSSw0QkFBNEIsR0FBWSxLQUFLLENBQUM7WUFFbEQsS0FBSyxJQUFJLFNBQVMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDcEUsSUFBSSxTQUFTLENBQUMsZUFBZSxJQUFJLFNBQVMsQ0FBQyxlQUFlLEtBQUssSUFBSSxFQUFFLENBQUM7b0JBQ2xFLDRCQUE0QixHQUFHLElBQUksQ0FBQztnQkFDeEMsQ0FBQztZQUNMLENBQUM7WUFFRCxJQUFJ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SUFDNUUsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJQ2VsbFJlbmRlcmVyQW5ndWxhckNvbXB9IGZyb20gXCJhZy1ncmlkLWFuZ3VsYXJcIjtcclxuaW1wb3J0IHtVbnR5cGVkRm9ybUJ1aWxkZXIsIFVudHlwZWRGb3JtQ29udHJvbCwgVW50eXBlZEZvcm1Hcm91cCwgVmFsaWRhdG9yc30gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XHJcblxyXG4vKipcclxuICogVGhpcyBjbGFzcycgcHVycG9zZSBpcyB0byBwbGFjZSBGb3JtQ29udHJvbHMgb24gY2VsbHMgaW4gdGhlIGdyaWQsIGFuZCB0byBsaW5rIHRoZW0gYnkgcm93cywgYW5kIHJvd3MgdG8gdGhlIGdyaWQgYXMgYSB3aG9sZS5cclxuICogSXQgYWxsb3dzIHlvdSB0byBhZGQgdmFsaWRhdG9ycyBmb3IgYSBjZWxscycgdmFsdWUgYW5kIGxpbmsgYW4gZXJyb3IgdHlwZSB0byBhbiBlcnJvciBtZXNzYWdlIHRvIGRpc3BsYXkgaW4gYSB0b29sdGlwLCBvclxyXG4gKiB5b3UgY2FuIHByb3ZpZGUgYSBmdW5jdGlvbiB0byB0ZXN0IHNvbWUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHJvdyBhbmQgcHJvdmlkZSBhbiBlcnJvciBtZXNzYWdlLlxyXG4gKlxyXG4gKiBUaGUgY2xhc3Mgd29ya3Mgb2ZmIG9mIGEgbnVtYmVyIG9mIHByb3BlcnRpZXMgYWRkZWQgdG8gdGhlIGNvbHVtbkRlZnMgaW4gdGhlIGFnLWdyaWQuXHJcbiAqXHJcbiAqIFdlIGFyZSBsb29raW5nIGZvciB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XHJcbiAqICAgMS4gZXJyb3JNZXNzYWdlSGVhZGVyIDogYSBzdHJpbmcgdG8gZGlzcGxheSBhdCB0aGUgdG9wIG9mIHRoZSBsaXN0IG9mIGFueSBlcnJvcnMgZm91bmQgZm9yIHRoZSBjZWxsXHJcbiAqICAgMi4gdmFsaWRhdG9ycyA6IGFuIGFycmF5IG9mIGFuZ3VsYXIgdmFsaWRhdG9ycyB0byBkZXNjcmliZSB0aGUgY2VsbCB2YWx1ZVxyXG4gKiAgIDMuIGVycm9yTmFtZUVycm9yTWVzc2FnZU1hcCA6IGFuIGFycmF5IG9mIG9iamVjdHMgd2l0aCBcImVycm9yTmFtZVwicyBhbmQgXCJlcnJvck1lc3NhZ2VcInMgdGhhdCBhcmUgdXNlZCB0byBjcmVhdGUgYSBkaXNwbGF5ZWQgbGlzdCBmb3IgdGhlIHVzZXJcclxuICogICA0LiBzZXRFcnJvcnM6IGEgZnVuY3Rpb24gd2l0aCB0aGUgc2lnbmF0dXJlOlxyXG4gKiAgICAgICAgICAgICAgICAgKHZhbHVlOiBhbnksIGRhdGE6IGFueSwgbm9kZTogYW55LCBjb2xEZWY6IGFueSwgcm93SW5kZXg6IGFueSwgZ3JpZEFwaTogYW55KSA9PiBzdHJpbmdcclxuICogICAgICAgICAgICAgICAgIHdoaWNoIGlzIGNhbGxlZCB0byBnZW5lcmF0ZSBhIGN1c3RvbSBlcnJvciBtZXNzYWdlLCBpZiBuZWVkZWQuIEFuIGVtcHR5IG9yIG51bGwgc3RyaW5nXHJcbiAqICAgICAgICAgICAgICAgICBpcyB0cmVhdGVkIGFzIG5vdCBiZWluZyBhbiBlcnJvci5cclxuICpcclxuICogRXhhbXBsZSBjb2x1bW4gZGVmaW5pdGlvbjpcclxuICogICAgICB7XHJcbiAqICAgICAgICAgIGhlYWRlck5hbWU6IFwiTmFtZVwiLFxyXG4gKiAgICAgICAgICBlZGl0YWJsZTogZmFsc2UsXHJcbiAqICAgICAgICAgIHdpZHRoOiA2MDAsXHJcbiAqICAgICAgICAgIGNlbGxSZW5kZXJlckZyYW1ld29yazogVGV4dEFsaWduTGVmdE1pZGRsZVJlbmRlcmVyLFxyXG4gKiAgICAgICAgICBzZXRFcnJvcnM6ICh2YWx1ZTogYW55LFxyXG4gKiAgICAgICAgICAgICAgICAgICAgICBkYXRhOiBhbnksXHJcbiAqICAgICAgICAgICAgICAgICAgICAgIG5vZGU6IGFueSxcclxuICogICAgICAgICAgICAgICAgICAgICAgY29sRGVmOiBhbnksXHJcbiAqICAgICAgICAgICAgICAgICAgICAgIHJvd0luZGV4OiBhbnksXHJcbiAqICAgICAgICAgICAgICAgICAgICAgIGdyaWRBcGk6IGFueSkgPT4ge1xyXG4gKiAgICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSAmJiB2YWx1ZSA9PT0gJ1RFU1QnKSA/ICdJbnZhbGlkIG5hbWUnIDogJyc7XHJcbiAqICAgICAgICAgIH0sXHJcbiAqICAgICAgICAgIHZhbGlkYXRvcnM6IFsgVmFsaWRhdG9ycy5taW5MZW5ndGgoMTApIF0sXHJcbiAqICAgICAgICAgIGVycm9yTWVzc2FnZUhlYWRlcjogJ1Rlc3RpbmdUZXN0aW5nVGVzdGluZycsXHJcbiAqICAgICAgICAgIGVycm9yTmFtZUVycm9yTWVzc2FnZU1hcDogW1xyXG4gKiAgICAgICAgICAgICAgeyBlcnJvck5hbWU6ICdtaW5sZW5ndGgnLCBlcnJvck1lc3NhZ2U6ICdOYW1lIGlzIHRvbyBzaG9ydCcgfVxyXG4gKiAgICAgICAgICBdLFxyXG4gKiAgICAgICAgICBmaWVsZDogXCJuYW1lXCJcclxuICogICAgICB9XHJcbiAqXHJcbiAqIFRvIHVzZSB3aXRoIGEgbmV3IHJlbmRlcmVyLCBleHRlbmQgdGhpcyBjbGFzcywgZG8gbm90IG92ZXJyaWRlIGFnSW5pdCwgb3IgY2FsbCBzdXBlci5hZ0luaXQocGFyYW1zKSBmaXJzdC5cclxuICogKFlvdSBjYW4gdXNlIGFnSW5pdDIgaW5zdGVhZCwgY2FsbGVkIHJpZ2h0IGFmdGVyIGFnSW5pdCkuXHJcbiAqXHJcbiAqIFRvIGRpc3BsYXkgYSB0b29sdGlwIHdpdGggdGhlIGVycm9yIG1lc3NhZ2VzLCBpbmNsdWRlIGFuIGVsZW1lbnQgd2l0aCBhIG1hdFRvb2x0aXAgcG9pbnRpbmcgdG8gdGhpcy5lcnJvck1lc3NhZ2UsIGxpa2U6XHJcbiAqICAgICAgPGRpdiBbbWF0VG9vbHRpcF09XCJ0aGlzLmVycm9yTWVzc2FnZVwiIFttYXRUb29sdGlwU2hvd0RlbGF5XT1cIjMwMFwiIFttYXRUb29sdGlwSGlkZURlbGF5XT1cIjMwMFwiIC4uLlxyXG4gKiBGb3IgY2VsbCBoaWdobGlnaHRpbmcsIHlvdSBjYW4gYWRkIGEgQ1NTIGNsYXNzIHNvbWV0aGluZyBsaWtlIDpcclxuICogICAgICAuZXJyb3Ige1xyXG4gKiAgICAgIFx0YmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KHJnYmEoMjU1LDAsMCwwLjI1KSwgcmdiYSgyNTUsMCwwLDAuMjUpLCByZ2JhKDI1NSwwLDAsMC4yNSkpO1xyXG4gKiAgICAgIFx0Ym9yZGVyOiBzb2xpZCByZWQgMnB4O1xyXG4gKiAgICAgIH1cclxuICogICBhbmQgYSBjb25kaXRpb25hbCBjbGFzcyBvbiBhbiBlbGVtZW50IGluIHRoZSB0ZW1wbGF0ZSwgbGlrZSA6XHJcbiAqICAgICAgY2xhc3M9XCJ7e3RoaXMuZXJyb3JNZXNzYWdlICYmIHRoaXMuZXJyb3JNZXNzYWdlICE9PSAnJyA/ICdlcnJvcicgOiAnJ319XCJcclxuICovXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBDZWxsUmVuZGVyZXJWYWxpZGF0aW9uIGltcGxlbWVudHMgSUNlbGxSZW5kZXJlckFuZ3VsYXJDb21wIHtcclxuXHJcbiAgICBwcm90ZWN0ZWQgcGFyYW1zOiBhbnk7XHJcblxyXG4gICAgcHVibGljIGVycm9yTWVzc2FnZTogc3RyaW5nID0gXCJcIjtcclxuXHJcbiAgICBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyO1xyXG5cclxuICAgIGFnSW5pdChwYXJhbXM6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMucGFyYW1zID0gcGFyYW1zO1xyXG4gICAgICAgIHRoaXMuZm9ybUJ1aWxkZXIgPSBuZXcgVW50eXBlZEZvcm1CdWlsZGVyKCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnBhcmFtc1xyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaVxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZm9ybUdyb3VwID09PSB1bmRlZmluZWQpIHtcclxuXHJcbiAgICAgICAgICAgIGxldCBmb3VuZERlbGF5VmFsaWRhdGlvblByb3BlcnR5OiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBjb2x1bW5EZWYgb2YgcGFyYW1zLm5vZGUuZ3JpZEFwaS5jb2x1bW5Db250cm9sbGVyLmNvbHVtbkRlZnMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChjb2x1bW5EZWYuZGVsYXlWYWxpZGF0aW9uICYmIGNvbHVtbkRlZi5kZWxheVZhbGlkYXRpb24gPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3VuZERlbGF5VmFsaWRhdGlvblByb3BlcnR5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCFmb3VuZERlbGF5VmFsaWRhdGlvblByb3BlcnR5KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRldGVybWluZUlmQWxsUm93c05lZWRWYWxpZGF0aW9uSW5BZHZhbmNlKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZUFsbEZvcm1Db250cm9scygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmdldEVycm9yTWVzc2FnZSgpO1xyXG5cclxuICAgICAgICB0aGlzLmFnSW5pdDIocGFyYW1zKTtcclxuICAgIH1cclxuXHJcbiAgICBhYnN0cmFjdCBhZ0luaXQyKHBhcmFtcyk6IHZvaWQ7XHJcblxyXG5cclxuICAgIHJlZnJlc2gocGFyYW1zOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBpdGVyYXRlcyBvdmVyIGV2ZXJ5IGNlbGwgaW4gdGhlIGdyaWQgYW5kIHByZXBhcmVzIGFsbCB0aGVpciBuZWVkZWQgZm9ybUdyb3VwcyBhbmQgZm9ybUNvbnRyb2xzLlxyXG4gICAgLy9cclxuICAgIC8vIFRoaXMgd2FzIGRvbmUgdGhpcyB3YXkgKGluIHRoZSBjZWxsIHJlbmRlcmVyKSBmb3IgdGhyZWUgcmVhc29ucyA6XHJcbiAgICAvLyAgIDEuIFdlIG5lZWQgdG8gd2FpdCB1bnRpbCB0aGUgY29sdW1uIGFuZCByb3cgZGF0YSBoYXZlIGJlZW4gcHJvdmlkZWQgdG8gdGhlIGdyaWRcclxuICAgIC8vICAgMi4gV2UgZG9uJ3Qgd2FudCB0aGUgcHJvZ3JhbW1lciB0byBoYXZlIHRvIGltcGxlbWVudCBpdCB0aGVtc2VsdmVzIGV2ZXJ5IHRpbWUgdGhleSBjcmVhdGUgYSBncmlkXHJcbiAgICAvLyAgIDMuIFRoZSBncmlkIGRvZXMgbm90IGNyZWF0ZSBhbGwgdGhlIGNlbGwgcmVuZGVyZXJzIGluIGFkdmFuY2UsIGp1c3QgdGhvc2UgdGhhdCBmaXQgb24gdGhlIHNjcmVlblxyXG4gICAgLy8gICAgICAocGx1cyBhIGZldyBuZWFyYnkpIG1lYW5pbmcgd2UgY2FuJ3QganVzdCB1c2UgdGhlIGNlbGwgcmVuZGVyZXIncyBjb25zdHJ1Y3Rvciwgc2luY2Ugd2UgZG9uJ3RcclxuICAgIC8vICAgICAga25vdyBpZiB0aGUgaW5mb3JtYXRpb24gd2Ugc3RhcnQgd2l0aCBpcyB2YWxpZCBvbiBldmVyeSBzY3JlZW4sIGFuZCBiZWNhdXNlIHdlIGhhdmUgc29tZSBjYWxsc1xyXG4gICAgLy8gICAgICB0aGF0IHNlbmQgYmFjayB0aGUgZW50aXJlIGdyaWQncyB3b3J0aCBvZiBkYXRhLlxyXG4gICAgLy9cclxuICAgIC8vIFRoZXJlIG1heSBiZSBhIGJldHRlciB3YXkgdG8gZG8gdGhpcywgaW4gd2hpY2ggY2FzZSB0aGlzIHNob3VsZCBwcm9iYWJseSBiZSByZXBsYWNlZCFcclxuICAgIGNyZWF0ZUFsbEZvcm1Db250cm9scygpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5wYXJhbXNcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMuY29sdW1uXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLmNvbHVtbi5jb2xEZWZcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMuZGF0YVxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaVxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ2V0TW9kZWwoKSkge1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXJcclxuICAgICAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXIuZ3JpZE9wdGlvbnNcclxuICAgICAgICAgICAgICAgICYmICF0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ3JpZE9wdGlvbnNXcmFwcGVyLmdyaWRPcHRpb25zLl9ldmVudHNDaGFuZ2VkQnlDZWxsUmVuZGVyZXJWYWxpZGF0aW9uKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VHcmlkT3B0aW9uc0V2ZW50cygpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXIuZ3JpZE9wdGlvbnMuX2V2ZW50c0NoYW5nZWRCeUNlbGxSZW5kZXJlclZhbGlkYXRpb24gPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgYWxsTm9kZXMgPSBbXTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkubW9kZV9uZWVkVG9WYWxpZGF0ZU9ubHlSZW5kZXJlZENlbGxzKSB7XHJcbiAgICAgICAgICAgICAgICBhbGxOb2RlcyA9IHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5nZXRSZW5kZXJlZE5vZGVzKCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBhbGxOb2RlcyA9IHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5nZXRNb2RlbCgpLnJvd3NUb0Rpc3BsYXk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmZvcm1Hcm91cFxyXG4gICAgICAgICAgICAgICAgfHwgKHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXBcclxuICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZm9ybUdyb3VwLmNvbnRyb2xzXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmZvcm1Hcm91cC5jb250cm9scy5sZW5ndGggIT0gYWxsTm9kZXMubGVuZ3RoKSkge1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXAgPSBuZXcgVW50eXBlZEZvcm1Hcm91cCh7fSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuY29sdW1uQ29udHJvbGxlclxyXG4gICAgICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmNvbHVtbkNvbnRyb2xsZXIuY29sdW1uRGVmcykge1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGNvbHVtbkRlZiBvZiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuY29sdW1uQ29udHJvbGxlci5jb2x1bW5EZWZzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbHVtbkRlZi5vdXRlckZvcm0gJiYgY29sdW1uRGVmLmZvcm1OYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29sdW1uRGVmLm91dGVyRm9ybS5nZXQoY29sdW1uRGVmLmZvcm1OYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uRGVmLm91dGVyRm9ybS5hZGRDb250cm9sKGNvbHVtbkRlZi5mb3JtTmFtZSwgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmZvcm1Hcm91cCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5EZWYub3V0ZXJGb3JtLnNldENvbnRyb2woY29sdW1uRGVmLmZvcm1OYW1lLCB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZm9ybUdyb3VwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGV0IGNvbHVtbnM6IGFueVtdO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMucGFyYW1zICYmIHRoaXMucGFyYW1zLmNvbHVtbkFwaSAmJiB0aGlzLnBhcmFtcy5jb2x1bW5BcGkuY29sdW1uQ29udHJvbGxlcikge1xyXG4gICAgICAgICAgICAgICAgY29sdW1ucyA9IHRoaXMucGFyYW1zLmNvbHVtbkFwaS5jb2x1bW5Db250cm9sbGVyLmdyaWRDb2x1bW5zLmZpbHRlcigoY29sdW1uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbHVtbi5jb2xEZWZcclxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgY29sdW1uLmNvbERlZi5maWVsZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiAoY29sdW1uLmNvbERlZi52YWxpZGF0b3JzIHx8IGNvbHVtbi5jb2xEZWYuc2V0RXJyb3JzKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBub2RlIG9mIGFsbE5vZGVzKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBjb2x1bW4gb2YgY29sdW1ucykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb2x1bW4uY29sRGVmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICYmIGNvbHVtbi5jb2xEZWYuZmllbGRcclxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGNvbHVtbi5jb2xEZWYudmFsaWRhdG9ycyB8fCBjb2x1bW4uY29sRGVmLnNldEVycm9ycykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVtjb2x1bW4uY29sRGVmLmZpZWxkICsgXCJfZXJyb3JNZXNzYWdlXCJdID0gJyc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZm9ybUNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCA9IG5ldyBVbnR5cGVkRm9ybUNvbnRyb2woY29sdW1uLmNvbERlZi5maWVsZCArICdfZm9ybUNvbnRyb2wnLCBbXSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5vZGUuZm9ybUdyb3VwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLmZvcm1Hcm91cCA9IG5ldyBVbnR5cGVkRm9ybUdyb3VwKHt9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5mb3JtR3JvdXAuYWRkQ29udHJvbChjb2x1bW4uY29sRGVmLmZpZWxkICsgJ19mb3JtQ29udHJvbCcsIGZvcm1Db250cm9sKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShjb2x1bW4uY29sRGVmLnZhbGlkYXRvcnMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW4uY29sRGVmLnZhbGlkYXRvcnMgPSBbY29sdW1uLmNvbERlZi52YWxpZGF0b3JzXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2wuc2V0VmFsaWRhdG9ycyhjb2x1bW4uY29sRGVmLnZhbGlkYXRvcnMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVFcnJvck1lc3NhZ2UoZm9ybUNvbnRyb2wsIG5vZGUsIGNvbHVtbi5jb2xEZWYpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXAuY29udGFpbnMoJ1Jvd0dyb3VwXycgKyBub2RlLnJvd0luZGV4KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9kZS5mb3JtR3JvdXApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5mb3JtR3JvdXAgPSBuZXcgVW50eXBlZEZvcm1Hcm91cCh7fSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXAuYWRkQ29udHJvbCgnUm93R3JvdXBfJyArIG5vZGUucm93SW5kZXgsIG5vZGUuZm9ybUdyb3VwKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGNoYW5nZUdyaWRPcHRpb25zRXZlbnRzKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICghdGhpcy5wYXJhbXNcclxuICAgICAgICAgICAgfHwgIXRoaXMucGFyYW1zLm5vZGVcclxuICAgICAgICAgICAgfHwgIXRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaVxyXG4gICAgICAgICAgICB8fCAhdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlclxyXG4gICAgICAgICAgICB8fCAhdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlci5ncmlkT3B0aW9ucykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlci5ncmlkT3B0aW9ucy5vblJvd0RhdGFDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXIuZ3JpZE9wdGlvbnMub25Sb3dEYXRhQ2hhbmdlZDIgPSB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ3JpZE9wdGlvbnNXcmFwcGVyLmdyaWRPcHRpb25zLm9uUm93RGF0YUNoYW5nZWQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ3JpZE9wdGlvbnNXcmFwcGVyLmdyaWRPcHRpb25zLm9uUm93RGF0YUNoYW5nZWQgPSAoKGV2ZW50OiBhbnkpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5jcmVhdGVBbGxGb3JtQ29udHJvbHMoKTtcclxuICAgICAgICAgICAgdGhpcy5mZXRjaEVycm9yTWVzc2FnZXNGb3JDdXJyZW50bHlSZW5kZXJlZENlbGxzKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlci5ncmlkT3B0aW9ucy5vblJvd0RhdGFDaGFuZ2VkMikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlci5ncmlkT3B0aW9ucy5vblJvd0RhdGFDaGFuZ2VkMihldmVudCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICAgIGlmICh0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ3JpZE9wdGlvbnNXcmFwcGVyLmdyaWRPcHRpb25zLm9uR3JpZENvbHVtbnNDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXIuZ3JpZE9wdGlvbnMub25HcmlkQ29sdW1uc0NoYW5nZWQyID0gdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlci5ncmlkT3B0aW9ucy5vbkdyaWRDb2x1bW5zQ2hhbmdlZDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5ncmlkT3B0aW9uc1dyYXBwZXIuZ3JpZE9wdGlvbnMub25HcmlkQ29sdW1uc0NoYW5nZWQgPSAoKGV2ZW50OiBhbnkpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5kZXRlcm1pbmVJZkFsbFJvd3NOZWVkVmFsaWRhdGlvbkluQWR2YW5jZSgpO1xyXG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUFsbEZvcm1Db250cm9scygpO1xyXG4gICAgICAgICAgICB0aGlzLmZldGNoRXJyb3JNZXNzYWdlc0ZvckN1cnJlbnRseVJlbmRlcmVkQ2VsbHMoKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ3JpZE9wdGlvbnNXcmFwcGVyLmdyaWRPcHRpb25zLm9uR3JpZENvbHVtbnNDaGFuZ2VkMikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmdyaWRPcHRpb25zV3JhcHBlci5ncmlkT3B0aW9ucy5vbkdyaWRDb2x1bW5zQ2hhbmdlZDIoZXZlbnQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRFcnJvck1lc3NhZ2UoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMucGFyYW1zXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLm5vZGVcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZS5mb3JtR3JvdXBcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMuY29sdW1uXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLmNvbHVtbi5jb2xEZWZcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMuY29sdW1uLmNvbERlZi5maWVsZCkge1xyXG5cclxuICAgICAgICAgICAgbGV0IGZvcm1Db250cm9sID0gdGhpcy5wYXJhbXMubm9kZS5mb3JtR3JvdXAuZ2V0KHRoaXMucGFyYW1zLmNvbHVtbi5jb2xEZWYuZmllbGQgKyAnX2Zvcm1Db250cm9sJyk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUVycm9yTWVzc2FnZShmb3JtQ29udHJvbCwgdGhpcy5wYXJhbXMubm9kZSwgdGhpcy5wYXJhbXMuY29sdW1uLmNvbERlZik7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmVycm9yTWVzc2FnZSA9IHRoaXMucGFyYW1zLm5vZGVbdGhpcy5wYXJhbXMuY29sdW1uLmNvbERlZi5maWVsZCArIFwiX2Vycm9yTWVzc2FnZVwiXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZWZyZXNoRm9ybUNvbnRyb2xWYWx1ZShmb3JtQ29udHJvbDogVW50eXBlZEZvcm1Db250cm9sLCBkYXRhOiBhbnksIGZpZWxkTmFtZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGZvcm1Db250cm9sICYmIGRhdGEgJiYgZmllbGROYW1lICYmIGRhdGFbZmllbGROYW1lXSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGZvcm1Db250cm9sLnNldFZhbHVlKGRhdGFbZmllbGROYW1lXSk7XHJcbiAgICAgICAgICAgIGZvcm1Db250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSB1cGRhdGVFcnJvck1lc3NhZ2UoZm9ybUNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCwgbm9kZTogYW55LCBjb2x1bW5EZWZpbml0aW9uOiBhbnkpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmICghZm9ybUNvbnRyb2wgfHwgIW5vZGUgfHwgIWNvbHVtbkRlZmluaXRpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGN1c3RvbUVycm9yTWVzc2FnZTogc3RyaW5nID0gJyc7XHJcblxyXG4gICAgICAgIGlmIChjb2x1bW5EZWZpbml0aW9uLnNldEVycm9ycykge1xyXG4gICAgICAgICAgICBjdXN0b21FcnJvck1lc3NhZ2UgPSBjb2x1bW5EZWZpbml0aW9uLnNldEVycm9ycyhcclxuICAgICAgICAgICAgICAgIG5vZGUuZGF0YVtjb2x1bW5EZWZpbml0aW9uLmZpZWxkXSxcclxuICAgICAgICAgICAgICAgIG5vZGUuZGF0YSxcclxuICAgICAgICAgICAgICAgIG5vZGUsXHJcbiAgICAgICAgICAgICAgICBjb2x1bW5EZWZpbml0aW9uLFxyXG4gICAgICAgICAgICAgICAgbm9kZS5yb3dJbmRleCxcclxuICAgICAgICAgICAgICAgIG5vZGUuZ3JpZEFwaVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGVycm9yTWVzc2FnZU5hbWU6IHN0cmluZyA9IGNvbHVtbkRlZmluaXRpb24uZmllbGQgKyBcIl9lcnJvck1lc3NhZ2VcIjtcclxuXHJcbiAgICAgICAgdGhpcy5yZWZyZXNoRm9ybUNvbnRyb2xWYWx1ZShmb3JtQ29udHJvbCwgbm9kZS5kYXRhLCBjb2x1bW5EZWZpbml0aW9uLmZpZWxkKTtcclxuXHJcbiAgICAgICAgbm9kZVtlcnJvck1lc3NhZ2VOYW1lXSA9ICcnO1xyXG5cclxuICAgICAgICBpZiAoZm9ybUNvbnRyb2wuaW52YWxpZCB8fCAoY3VzdG9tRXJyb3JNZXNzYWdlICYmIGN1c3RvbUVycm9yTWVzc2FnZSAhPT0gJycpKSB7XHJcbiAgICAgICAgICAgIGlmIChjb2x1bW5EZWZpbml0aW9uLmVycm9yTWVzc2FnZUhlYWRlcikge1xyXG4gICAgICAgICAgICAgICAgbm9kZVtlcnJvck1lc3NhZ2VOYW1lXSArPSAnJyArIGNvbHVtbkRlZmluaXRpb24uZXJyb3JNZXNzYWdlSGVhZGVyICsgJ1xcbic7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBub2RlW2Vycm9yTWVzc2FnZU5hbWVdICs9XHJcbiAgICAgICAgICAgICAgICAgICAgJ0ludmFsaWQgdmFsdWUgXCInICsgbm9kZS5kYXRhW2NvbHVtbkRlZmluaXRpb24uZmllbGRdICsgJ1wiIGZvciBmaWVsZCAoJyArIGNvbHVtbkRlZmluaXRpb24uZmllbGQgKyAnKVxcbic7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChjb2x1bW5EZWZpbml0aW9uLmVycm9yTmFtZUVycm9yTWVzc2FnZU1hcCkge1xyXG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoY29sdW1uRGVmaW5pdGlvbi5lcnJvck5hbWVFcnJvck1lc3NhZ2VNYXApKSB7XHJcbiAgICAgICAgICAgICAgICBjb2x1bW5EZWZpbml0aW9uLmVycm9yTmFtZUVycm9yTWVzc2FnZU1hcCA9IFtjb2x1bW5EZWZpbml0aW9uLmVycm9yTmFtZUVycm9yTWVzc2FnZU1hcF07XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGVycm9yTmFtZUVycm9yTWVzc2FnZVBhaXIgb2YgY29sdW1uRGVmaW5pdGlvbi5lcnJvck5hbWVFcnJvck1lc3NhZ2VNYXApIHtcclxuICAgICAgICAgICAgICAgIGlmICghIWVycm9yTmFtZUVycm9yTWVzc2FnZVBhaXIuZXJyb3JOYW1lICYmICEhZXJyb3JOYW1lRXJyb3JNZXNzYWdlUGFpci5lcnJvck1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZm9ybUNvbnRyb2wuaGFzRXJyb3IoZXJyb3JOYW1lRXJyb3JNZXNzYWdlUGFpci5lcnJvck5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVbZXJyb3JNZXNzYWdlTmFtZV0gKz0gZXJyb3JOYW1lRXJyb3JNZXNzYWdlUGFpci5lcnJvck1lc3NhZ2UgKydcXG4nO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbm9kZVtlcnJvck1lc3NhZ2VOYW1lXSArPSBjdXN0b21FcnJvck1lc3NhZ2U7XHJcblxyXG4gICAgICAgIHJldHVybiBub2RlW2Vycm9yTWVzc2FnZU5hbWVdO1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBkZXRlcm1pbmVJZkFsbFJvd3NOZWVkVmFsaWRhdGlvbkluQWR2YW5jZSgpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5wYXJhbXNcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZVxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGlcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMuY29sdW1uQXBpXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLmNvbHVtbkFwaS5jb2x1bW5Db250cm9sbGVyXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLmNvbHVtbkFwaS5jb2x1bW5Db250cm9sbGVyLmdyaWRDb2x1bW5zKSB7XHJcblxyXG4gICAgICAgICAgICBsZXQgY29sdW1ucyA9IHRoaXMucGFyYW1zLmNvbHVtbkFwaS5jb2x1bW5Db250cm9sbGVyLmdyaWRDb2x1bW5zLmZpbHRlcigoY29sdW1uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sdW1uLmNvbERlZlxyXG4gICAgICAgICAgICAgICAgICAgICYmIGNvbHVtbi5jb2xEZWYuZmllbGRcclxuICAgICAgICAgICAgICAgICAgICAmJiAoY29sdW1uLmNvbERlZi52YWxpZGF0b3JzIHx8IGNvbHVtbi5jb2xEZWYuc2V0RXJyb3JzKVxyXG4gICAgICAgICAgICAgICAgICAgICYmIGNvbHVtbi5jb2xEZWYuZWRpdGFibGUgPT09IHRydWVcclxuICAgICAgICAgICAgICAgICAgICAmJiAhKGNvbHVtbi5jb2xEZWYudmFsaWRhdGVPbmx5UmVuZGVyZWRDZWxsc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiBjb2x1bW4uY29sRGVmLnZhbGlkYXRlT25seVJlbmRlcmVkQ2VsbHMgPT09IHRydWUpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5tb2RlX25lZWRUb1ZhbGlkYXRlT25seVJlbmRlcmVkQ2VsbHMgPSBBcnJheS5pc0FycmF5KGNvbHVtbnMpICYmIGNvbHVtbnMubGVuZ3RoID09PSAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgZmV0Y2hFcnJvck1lc3NhZ2VzRm9yQ3VycmVudGx5UmVuZGVyZWRDZWxscygpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5wYXJhbXNcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJhbXMubm9kZVxyXG4gICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkpIHtcclxuXHJcbiAgICAgICAgICAgIGxldCBnZXRDZWxsUmVuZGVyZXJQYXJhbXM6IGFueSA9IHsgcm93Tm9kZXM6IHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5nZXRSZW5kZXJlZE5vZGVzKCkgfTtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGNlbGxSZW5kZXJlciBvZiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZ2V0Q2VsbFJlbmRlcmVySW5zdGFuY2VzKGdldENlbGxSZW5kZXJlclBhcmFtcykpIHtcclxuICAgICAgICAgICAgICAgIGlmIChjZWxsUmVuZGVyZXIuX2FnQXdhcmVDb21wb25lbnQgJiYgY2VsbFJlbmRlcmVyLl9hZ0F3YXJlQ29tcG9uZW50LmdldEVycm9yTWVzc2FnZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNlbGxSZW5kZXJlci5fYWdBd2FyZUNvbXBvbmVudC5nZXRFcnJvck1lc3NhZ2UoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgdXBkYXRlVmFsaWRhdGlvbigpOiB2b2lkIHtcclxuICAgICAgICBjb25zb2xlLmxvZyhcIlN1Y2Nlc3NmdWxseSByZWFjaGVkIVwiKTtcclxuICAgICAgICAvLyBhZGQgdGhpcyBmb3JtIGNvbnRyb2xcclxuXHJcbiAgICAgICAgbGV0IGNvbHVtbnMgPSB0aGlzLnBhcmFtcy5jb2x1bW5BcGkuY29sdW1uQ29udHJvbGxlci5ncmlkQ29sdW1ucy5maWx0ZXIoKGNvbHVtbikgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gY29sdW1uLmNvbERlZlxyXG4gICAgICAgICAgICAgICAgJiYgY29sdW1uLmNvbERlZi5maWVsZFxyXG4gICAgICAgICAgICAgICAgJiYgKGNvbHVtbi5jb2xEZWYudmFsaWRhdG9ycyB8fCBjb2x1bW4uY29sRGVmLnNldEVycm9ycylcclxuICAgICAgICAgICAgICAgICYmIGNvbHVtbi5jb2xEZWYuZmllbGQgPT09IHRoaXMucGFyYW1zLmZpZWxkO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5wYXJhbXMuY29sRGVmXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyYW1zLmNvbERlZi5maWVsZFxyXG4gICAgICAgICAgICAmJiAodGhpcy5wYXJhbXMuY29sRGVmLnZhbGlkYXRvcnMgfHwgdGhpcy5wYXJhbXMuY29sRGVmLnNldEVycm9ycykpIHtcclxuXHJcbiAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGVbdGhpcy5wYXJhbXMuY29sRGVmLmZpZWxkICsgXCJfZXJyb3JNZXNzYWdlXCJdID0gJyc7XHJcblxyXG4gICAgICAgICAgICBsZXQgZm9ybUNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCA9IG5ldyBVbnR5cGVkRm9ybUNvbnRyb2wodGhpcy5wYXJhbXMuY29sRGVmLmZpZWxkICsgJ19mb3JtQ29udHJvbCcsIFtdKTtcclxuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5wYXJhbXMubm9kZS5mb3JtR3JvdXApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZm9ybUdyb3VwID0gbmV3IFVudHlwZWRGb3JtR3JvdXAoe30pO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmZvcm1Hcm91cCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXAgPSBuZXcgVW50eXBlZEZvcm1Hcm91cCh7fSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGZvciBhbnkgcmVtb3ZlZCBub2RlcyAmIHJlbW92ZSB0aGVpciB2YWxpZGF0b3JzIGlmIG5lZWRlZC5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBjb250cm9sTmFtZSBvZiBPYmplY3Qua2V5cyh0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuZm9ybUdyb3VwLmNvbnRyb2xzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKCcnICsgY29udHJvbE5hbWUpLnRvTG93ZXJDYXNlKCkuc3Vic3RyKDAsIDkpID09PSAncm93Z3JvdXBfJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZvdW5kOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBub2RlIG9mIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5nZXRNb2RlbCgpLnJvd3NUb0Rpc3BsYXkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKCcnICsgbm9kZS5yb3dJbmRleCkgPT09ICgnJyArIGNvbnRyb2xOYW1lKS5zdWJzdHIoOSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmZvcm1Hcm91cC5yZW1vdmVDb250cm9sKGNvbnRyb2xOYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmZvcm1Hcm91cC5hZGRDb250cm9sKCdSb3dHcm91cF8nICsgdGhpcy5wYXJhbXMubm9kZS5yb3dJbmRleCwgdGhpcy5wYXJhbXMubm9kZS5mb3JtR3JvdXApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMucGFyYW1zLm5vZGUuZm9ybUdyb3VwLmNvbnRyb2xzW3RoaXMucGFyYW1zLmNvbERlZi5maWVsZCArICdfZm9ybUNvbnRyb2wnXSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJhbXMubm9kZS5mb3JtR3JvdXAuYWRkQ29udHJvbCh0aGlzLnBhcmFtcy5jb2xEZWYuZmllbGQgKyAnX2Zvcm1Db250cm9sJywgZm9ybUNvbnRyb2wpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMucGFyYW1zLmNvbERlZi52YWxpZGF0b3JzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGFyYW1zLm5vZGUuZm9ybUdyb3VwLmNvbnRyb2xzW3RoaXMucGFyYW1zLmNvbERlZi5maWVsZCArICdfZm9ybUNvbnRyb2wnXS5zZXRWYWxpZGF0b3JzKHRoaXMucGFyYW1zLmNvbERlZi52YWxpZGF0b3JzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmNvbHVtbkNvbnRyb2xsZXJcclxuICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuY29sdW1uQ29udHJvbGxlci5jb2x1bW5EZWZzKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNvbHVtbkRlZiBvZiB0aGlzLnBhcmFtcy5ub2RlLmdyaWRBcGkuY29sdW1uQ29udHJvbGxlci5jb2x1bW5EZWZzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2x1bW5EZWYub3V0ZXJGb3JtICYmIGNvbHVtbkRlZi5mb3JtTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjb2x1bW5EZWYub3V0ZXJGb3JtLmdldChjb2x1bW5EZWYuZm9ybU5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uRGVmLm91dGVyRm9ybS5hZGRDb250cm9sKGNvbHVtbkRlZi5mb3JtTmFtZSwgdGhpcy5wYXJhbXMubm9kZS5ncmlkQXBpLmZvcm1Hcm91cCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbkRlZi5vdXRlckZvcm0uc2V0Q29udHJvbChjb2x1bW5EZWYuZm9ybU5hbWUsIHRoaXMucGFyYW1zLm5vZGUuZ3JpZEFwaS5mb3JtR3JvdXApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUVycm9yTWVzc2FnZShmb3JtQ29udHJvbCwgdGhpcy5wYXJhbXMubm9kZSwgdGhpcy5wYXJhbXMuY29sRGVmKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGFkZCBjb2x1bW4gY29udHJvbCBncm91cHMgaWYgbmVlZGVkXHJcbiAgICAgICAgLy8gYWRkIHJvdyBjb250cm9sIGdyb3VwcyBpZiBuZWVkZWRcclxuICAgICAgICAvLyBzZXR1cCBncmlkIGNvbnRyb2wgZ3JvdXAgaWYgbmVlZGVkXHJcbiAgICAgICAgLy8gTWlnaHQgbmVlZCB0byB0cmlnZ2VyIGNlbGwgdmFsaWRhdGlvbiB0byBydW4gd2l0aCB0aGUgbmV3IHZhbGlkYXRpb24uXHJcbiAgICB9XHJcbn1cclxuIl19