@ng-formworks/core 17.2.7 → 17.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +836 -0
- package/esm2022/lib/framework-library/framework-library.service.mjs +175 -0
- package/esm2022/lib/framework-library/framework.mjs +15 -0
- package/esm2022/lib/framework-library/no-framework.component.mjs +18 -0
- package/esm2022/lib/framework-library/no-framework.module.mjs +27 -0
- package/esm2022/lib/framework-library/no.framework.mjs +19 -0
- package/esm2022/lib/json-schema-form.component.mjs +765 -0
- package/esm2022/lib/json-schema-form.module.mjs +26 -0
- package/esm2022/lib/json-schema-form.service.mjs +679 -0
- package/esm2022/lib/locale/de-validation-messages.mjs +60 -0
- package/esm2022/lib/locale/en-validation-messages.mjs +60 -0
- package/esm2022/lib/locale/es-validation-messages.mjs +57 -0
- package/esm2022/lib/locale/fr-validation-messages.mjs +60 -0
- package/esm2022/lib/locale/index.mjs +8 -0
- package/esm2022/lib/locale/it-validation-messages.mjs +60 -0
- package/esm2022/lib/locale/pt-validation-messages.mjs +60 -0
- package/esm2022/lib/locale/zh-validation-messages.mjs +60 -0
- package/esm2022/lib/shared/convert-schema-to-draft6.function.mjs +300 -0
- package/esm2022/lib/shared/form-group.functions.mjs +442 -0
- package/esm2022/lib/shared/format-regex.constants.mjs +54 -0
- package/esm2022/lib/shared/index.mjs +12 -0
- package/esm2022/lib/shared/json-schema.functions.mjs +784 -0
- package/esm2022/lib/shared/json.validators.mjs +884 -0
- package/esm2022/lib/shared/jsonpointer.functions.mjs +1026 -0
- package/esm2022/lib/shared/layout.functions.mjs +1154 -0
- package/esm2022/lib/shared/merge-schemas.function.mjs +345 -0
- package/esm2022/lib/shared/utility.functions.mjs +380 -0
- package/esm2022/lib/shared/validator.functions.mjs +584 -0
- package/esm2022/lib/widget-library/add-reference.component.mjs +61 -0
- package/esm2022/lib/widget-library/button.component.mjs +72 -0
- package/esm2022/lib/widget-library/checkbox.component.mjs +105 -0
- package/esm2022/lib/widget-library/checkboxes.component.mjs +147 -0
- package/esm2022/lib/widget-library/file.component.mjs +35 -0
- package/esm2022/lib/widget-library/hidden.component.mjs +54 -0
- package/esm2022/lib/widget-library/index.mjs +55 -0
- package/esm2022/lib/widget-library/input.component.mjs +119 -0
- package/esm2022/lib/widget-library/message.component.mjs +38 -0
- package/esm2022/lib/widget-library/none.component.mjs +21 -0
- package/esm2022/lib/widget-library/number.component.mjs +123 -0
- package/esm2022/lib/widget-library/one-of.component.mjs +35 -0
- package/esm2022/lib/widget-library/orderable.directive.mjs +123 -0
- package/esm2022/lib/widget-library/radios.component.mjs +153 -0
- package/esm2022/lib/widget-library/root.component.mjs +79 -0
- package/esm2022/lib/widget-library/section.component.mjs +199 -0
- package/esm2022/lib/widget-library/select-framework.component.mjs +51 -0
- package/esm2022/lib/widget-library/select-widget.component.mjs +46 -0
- package/esm2022/lib/widget-library/select.component.mjs +150 -0
- package/esm2022/lib/widget-library/submit.component.mjs +82 -0
- package/esm2022/lib/widget-library/tab.component.mjs +41 -0
- package/esm2022/lib/widget-library/tabs.component.mjs +108 -0
- package/esm2022/lib/widget-library/template.component.mjs +46 -0
- package/esm2022/lib/widget-library/textarea.component.mjs +104 -0
- package/esm2022/lib/widget-library/widget-library.module.mjs +42 -0
- package/esm2022/lib/widget-library/widget-library.service.mjs +226 -0
- package/esm2022/ng-formworks-core.mjs +5 -0
- package/esm2022/public_api.mjs +13 -0
- package/fesm2022/ng-formworks-core.mjs +10149 -0
- package/fesm2022/ng-formworks-core.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/framework-library/framework-library.service.d.ts +55 -0
- package/lib/framework-library/framework.d.ts +13 -0
- package/lib/framework-library/no-framework.component.d.ts +8 -0
- package/lib/framework-library/no-framework.module.d.ts +9 -0
- package/lib/framework-library/no.framework.d.ts +10 -0
- package/lib/json-schema-form.component.d.ts +218 -0
- package/lib/json-schema-form.module.d.ts +11 -0
- package/lib/json-schema-form.service.d.ts +115 -0
- package/lib/locale/de-validation-messages.d.ts +1 -0
- package/lib/locale/en-validation-messages.d.ts +1 -0
- package/lib/locale/es-validation-messages.d.ts +1 -0
- package/lib/locale/fr-validation-messages.d.ts +1 -0
- package/{src/lib/locale/index.ts → lib/locale/index.d.ts} +7 -7
- package/lib/locale/it-validation-messages.d.ts +1 -0
- package/lib/locale/pt-validation-messages.d.ts +1 -0
- package/lib/locale/zh-validation-messages.d.ts +1 -0
- package/lib/shared/convert-schema-to-draft6.function.d.ts +21 -0
- package/lib/shared/form-group.functions.d.ts +100 -0
- package/lib/shared/format-regex.constants.d.ts +19 -0
- package/lib/shared/index.d.ts +9 -0
- package/lib/shared/json-schema.functions.d.ts +193 -0
- package/lib/shared/json.validators.d.ts +441 -0
- package/lib/shared/jsonpointer.functions.d.ts +416 -0
- package/lib/shared/layout.functions.d.ts +83 -0
- package/lib/shared/merge-schemas.function.d.ts +19 -0
- package/lib/shared/utility.functions.d.ts +165 -0
- package/{src/lib/shared/validator.functions.ts → lib/shared/validator.functions.d.ts} +364 -601
- package/lib/widget-library/add-reference.component.d.ts +20 -0
- package/lib/widget-library/button.component.d.ts +21 -0
- package/lib/widget-library/checkbox.component.d.ts +24 -0
- package/lib/widget-library/checkboxes.component.d.ts +24 -0
- package/lib/widget-library/file.component.d.ts +21 -0
- package/lib/widget-library/hidden.component.d.ts +19 -0
- package/{src/lib/widget-library/index.ts → lib/widget-library/index.d.ts} +47 -56
- package/lib/widget-library/input.component.d.ts +22 -0
- package/lib/widget-library/message.component.d.ts +15 -0
- package/lib/widget-library/none.component.d.ts +8 -0
- package/lib/widget-library/number.component.d.ts +25 -0
- package/lib/widget-library/one-of.component.d.ts +21 -0
- package/lib/widget-library/orderable.directive.d.ts +41 -0
- package/lib/widget-library/radios.component.d.ts +23 -0
- package/lib/widget-library/root.component.d.ts +17 -0
- package/lib/widget-library/section.component.d.ts +19 -0
- package/lib/widget-library/select-framework.component.d.ts +18 -0
- package/lib/widget-library/select-widget.component.d.ts +18 -0
- package/lib/widget-library/select.component.d.ts +24 -0
- package/lib/widget-library/submit.component.d.ts +24 -0
- package/lib/widget-library/tab.component.d.ts +14 -0
- package/lib/widget-library/tabs.component.d.ts +20 -0
- package/lib/widget-library/template.component.d.ts +18 -0
- package/lib/widget-library/textarea.component.d.ts +21 -0
- package/lib/widget-library/widget-library.module.d.ts +31 -0
- package/lib/widget-library/widget-library.service.d.ts +22 -0
- package/package.json +64 -53
- package/{src/public_api.ts → public_api.d.ts} +9 -21
- package/karma.conf.js +0 -46
- package/ng-package.json +0 -11
- package/src/lib/framework-library/framework-library.service.ts +0 -195
- package/src/lib/framework-library/framework.ts +0 -11
- package/src/lib/framework-library/no-framework.component.html +0 -2
- package/src/lib/framework-library/no-framework.component.ts +0 -11
- package/src/lib/framework-library/no-framework.module.ts +0 -18
- package/src/lib/framework-library/no.framework.ts +0 -11
- package/src/lib/json-schema-form.component.html +0 -7
- package/src/lib/json-schema-form.component.ts +0 -809
- package/src/lib/json-schema-form.module.ts +0 -17
- package/src/lib/json-schema-form.service.ts +0 -907
- package/src/lib/locale/de-validation-messages.ts +0 -58
- package/src/lib/locale/en-validation-messages.ts +0 -58
- package/src/lib/locale/es-validation-messages.ts +0 -55
- package/src/lib/locale/fr-validation-messages.ts +0 -58
- package/src/lib/locale/it-validation-messages.ts +0 -58
- package/src/lib/locale/pt-validation-messages.ts +0 -58
- package/src/lib/locale/zh-validation-messages.ts +0 -58
- package/src/lib/locale-dates/en-US.ts +0 -5
- package/src/lib/shared/convert-schema-to-draft6.function.ts +0 -321
- package/src/lib/shared/form-group.functions.ts +0 -522
- package/src/lib/shared/format-regex.constants.ts +0 -73
- package/src/lib/shared/index.ts +0 -40
- package/src/lib/shared/json-schema.functions.ts +0 -788
- package/src/lib/shared/json.validators.ts +0 -878
- package/src/lib/shared/jsonpointer.functions.ts +0 -1012
- package/src/lib/shared/jspointer.functions.json.spec.ts +0 -103
- package/src/lib/shared/layout.functions.ts +0 -1233
- package/src/lib/shared/merge-schemas.function.ts +0 -329
- package/src/lib/shared/utility.functions.ts +0 -373
- package/src/lib/shared/validator.functions.spec.ts +0 -55
- package/src/lib/widget-library/add-reference.component.ts +0 -59
- package/src/lib/widget-library/button.component.ts +0 -54
- package/src/lib/widget-library/checkbox.component.ts +0 -74
- package/src/lib/widget-library/checkboxes.component.ts +0 -104
- package/src/lib/widget-library/file.component.ts +0 -36
- package/src/lib/widget-library/hidden.component.ts +0 -39
- package/src/lib/widget-library/input.component.ts +0 -76
- package/src/lib/widget-library/message.component.ts +0 -29
- package/src/lib/widget-library/none.component.ts +0 -12
- package/src/lib/widget-library/number.component.ts +0 -79
- package/src/lib/widget-library/one-of.component.ts +0 -36
- package/src/lib/widget-library/orderable.directive.ts +0 -130
- package/src/lib/widget-library/radios.component.ts +0 -101
- package/src/lib/widget-library/root.component.ts +0 -78
- package/src/lib/widget-library/section.component.ts +0 -133
- package/src/lib/widget-library/select-framework.component.ts +0 -50
- package/src/lib/widget-library/select-widget.component.ts +0 -46
- package/src/lib/widget-library/select.component.ts +0 -96
- package/src/lib/widget-library/submit.component.ts +0 -68
- package/src/lib/widget-library/tab.component.ts +0 -29
- package/src/lib/widget-library/tabs.component.ts +0 -83
- package/src/lib/widget-library/template.component.ts +0 -52
- package/src/lib/widget-library/textarea.component.ts +0 -68
- package/src/lib/widget-library/widget-library.module.ts +0 -13
- package/src/lib/widget-library/widget-library.service.ts +0 -234
- package/src/test.ts +0 -18
- package/tsconfig.lib.json +0 -25
- package/tsconfig.lib.prod.json +0 -9
- package/tsconfig.spec.json +0 -17
- package/tslint.json +0 -11
|
@@ -0,0 +1,679 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
//import Ajv, { ErrorObject, Options } from 'ajv';
|
|
3
|
+
import Ajv2019 from 'ajv/dist/2019';
|
|
4
|
+
import jsonDraft6 from 'ajv/lib/refs/json-schema-draft-06.json';
|
|
5
|
+
import jsonDraft7 from 'ajv/lib/refs/json-schema-draft-07.json';
|
|
6
|
+
import cloneDeep from 'lodash/cloneDeep';
|
|
7
|
+
import { Subject } from 'rxjs';
|
|
8
|
+
import { deValidationMessages, enValidationMessages, esValidationMessages, frValidationMessages, itValidationMessages, ptValidationMessages, zhValidationMessages } from './locale';
|
|
9
|
+
import { JsonPointer, buildFormGroup, buildFormGroupTemplate, buildLayout, buildSchemaFromData, buildSchemaFromLayout, fixTitle, forEach, formatFormData, getControl, getLayoutNode, hasOwn, hasValue, isArray, isDefined, isEmpty, isObject, removeRecursiveReferences, toTitleCase } from './shared';
|
|
10
|
+
import _isEqual from 'lodash/isEqual';
|
|
11
|
+
import * as i0 from "@angular/core";
|
|
12
|
+
export class JsonSchemaFormService {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.JsonFormCompatibility = false;
|
|
15
|
+
this.ReactJsonSchemaFormCompatibility = false;
|
|
16
|
+
this.AngularSchemaFormCompatibility = false;
|
|
17
|
+
this.tpldata = {};
|
|
18
|
+
this.ajvOptions = {
|
|
19
|
+
allErrors: true,
|
|
20
|
+
validateFormats: false,
|
|
21
|
+
strict: false
|
|
22
|
+
};
|
|
23
|
+
this.ajv = new Ajv2019(this.ajvOptions); // AJV: Another JSON Schema Validator
|
|
24
|
+
this.validateFormData = null; // Compiled AJV function to validate active form's schema
|
|
25
|
+
this.formValues = {}; // Internal form data (may not have correct types)
|
|
26
|
+
this.data = {}; // Output form data (formValues, formatted with correct data types)
|
|
27
|
+
this.schema = {}; // Internal JSON Schema
|
|
28
|
+
this.layout = []; // Internal form layout
|
|
29
|
+
this.formGroupTemplate = {}; // Template used to create formGroup
|
|
30
|
+
this.formGroup = null; // Angular formGroup, which powers the reactive form
|
|
31
|
+
this.framework = null; // Active framework component
|
|
32
|
+
this.validData = null; // Valid form data (or null) (=== isValid ? data : null)
|
|
33
|
+
this.isValid = null; // Is current form data valid?
|
|
34
|
+
this.ajvErrors = null; // Ajv errors for current data
|
|
35
|
+
this.validationErrors = null; // Any validation errors for current data
|
|
36
|
+
this.dataErrors = new Map(); //
|
|
37
|
+
this.formValueSubscription = null; // Subscription to formGroup.valueChanges observable (for un- and re-subscribing)
|
|
38
|
+
this.dataChanges = new Subject(); // Form data observable
|
|
39
|
+
this.isValidChanges = new Subject(); // isValid observable
|
|
40
|
+
this.validationErrorChanges = new Subject(); // validationErrors observable
|
|
41
|
+
this.arrayMap = new Map(); // Maps arrays in data object and number of tuple values
|
|
42
|
+
this.dataMap = new Map(); // Maps paths in form data to schema and formGroup paths
|
|
43
|
+
this.dataRecursiveRefMap = new Map(); // Maps recursive reference points in form data
|
|
44
|
+
this.schemaRecursiveRefMap = new Map(); // Maps recursive reference points in schema
|
|
45
|
+
this.schemaRefLibrary = {}; // Library of schemas for resolving schema $refs
|
|
46
|
+
this.layoutRefLibrary = { '': null }; // Library of layout nodes for adding to form
|
|
47
|
+
this.templateRefLibrary = {}; // Library of formGroup templates for adding to form
|
|
48
|
+
this.hasRootReference = false; // Does the form include a recursive reference to itself?
|
|
49
|
+
this.language = 'en-US'; // Does the form include a recursive reference to itself?
|
|
50
|
+
// Default global form options
|
|
51
|
+
this.defaultFormOptions = {
|
|
52
|
+
autocomplete: true,
|
|
53
|
+
addSubmit: 'auto',
|
|
54
|
+
// for addSubmit: true = always, false = never,
|
|
55
|
+
// 'auto' = only if layout is undefined (form is built from schema alone)
|
|
56
|
+
debug: false,
|
|
57
|
+
disableInvalidSubmit: true,
|
|
58
|
+
formDisabled: false,
|
|
59
|
+
formReadonly: false,
|
|
60
|
+
fieldsRequired: false,
|
|
61
|
+
framework: 'no-framework',
|
|
62
|
+
loadExternalAssets: false,
|
|
63
|
+
pristine: { errors: true, success: true },
|
|
64
|
+
supressPropertyTitles: false,
|
|
65
|
+
setSchemaDefaults: 'auto',
|
|
66
|
+
// true = always set (unless overridden by layout default or formValues)
|
|
67
|
+
// false = never set
|
|
68
|
+
// 'auto' = set in addable components, and everywhere if formValues not set
|
|
69
|
+
setLayoutDefaults: 'auto',
|
|
70
|
+
// true = always set (unless overridden by formValues)
|
|
71
|
+
// false = never set
|
|
72
|
+
// 'auto' = set in addable components, and everywhere if formValues not set
|
|
73
|
+
validateOnRender: 'auto',
|
|
74
|
+
// true = validate all fields immediately
|
|
75
|
+
// false = only validate fields after they are touched by user
|
|
76
|
+
// 'auto' = validate fields with values immediately, empty fields after they are touched
|
|
77
|
+
widgets: {},
|
|
78
|
+
defaultWidgetOptions: {
|
|
79
|
+
// Default options for form control widgets
|
|
80
|
+
listItems: 1,
|
|
81
|
+
addable: true,
|
|
82
|
+
orderable: true,
|
|
83
|
+
removable: true,
|
|
84
|
+
enableErrorState: true,
|
|
85
|
+
// disableErrorState: false, // Don't apply 'has-error' class when field fails validation?
|
|
86
|
+
enableSuccessState: true,
|
|
87
|
+
// disableSuccessState: false, // Don't apply 'has-success' class when field validates?
|
|
88
|
+
feedback: false,
|
|
89
|
+
feedbackOnRender: false,
|
|
90
|
+
notitle: false,
|
|
91
|
+
disabled: false,
|
|
92
|
+
readonly: false,
|
|
93
|
+
returnEmptyFields: true,
|
|
94
|
+
validationMessages: {} // set by setLanguage()
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
this.setLanguage(this.language);
|
|
98
|
+
this.ajv.addMetaSchema(jsonDraft6);
|
|
99
|
+
this.ajv.addMetaSchema(jsonDraft7);
|
|
100
|
+
}
|
|
101
|
+
ngOnDestroy() {
|
|
102
|
+
this.fcValueChangesSubs?.unsubscribe();
|
|
103
|
+
this.fcStatusChangesSubs?.unsubscribe();
|
|
104
|
+
this.formValueSubscription?.unsubscribe();
|
|
105
|
+
this.fcValueChangesSubs = null;
|
|
106
|
+
this.fcStatusChangesSubs = null;
|
|
107
|
+
this.formValueSubscription = null;
|
|
108
|
+
}
|
|
109
|
+
setLanguage(language = 'en-US') {
|
|
110
|
+
this.language = language;
|
|
111
|
+
const languageValidationMessages = {
|
|
112
|
+
de: deValidationMessages,
|
|
113
|
+
en: enValidationMessages,
|
|
114
|
+
es: esValidationMessages,
|
|
115
|
+
fr: frValidationMessages,
|
|
116
|
+
it: itValidationMessages,
|
|
117
|
+
pt: ptValidationMessages,
|
|
118
|
+
zh: zhValidationMessages,
|
|
119
|
+
};
|
|
120
|
+
const languageCode = language.slice(0, 2);
|
|
121
|
+
const validationMessages = languageValidationMessages[languageCode];
|
|
122
|
+
this.defaultFormOptions.defaultWidgetOptions.validationMessages = cloneDeep(validationMessages);
|
|
123
|
+
}
|
|
124
|
+
getData() {
|
|
125
|
+
return this.data;
|
|
126
|
+
}
|
|
127
|
+
getSchema() {
|
|
128
|
+
return this.schema;
|
|
129
|
+
}
|
|
130
|
+
getLayout() {
|
|
131
|
+
return this.layout;
|
|
132
|
+
}
|
|
133
|
+
resetAllValues() {
|
|
134
|
+
this.JsonFormCompatibility = false;
|
|
135
|
+
this.ReactJsonSchemaFormCompatibility = false;
|
|
136
|
+
this.AngularSchemaFormCompatibility = false;
|
|
137
|
+
this.tpldata = {};
|
|
138
|
+
this.validateFormData = null;
|
|
139
|
+
this.formValues = {};
|
|
140
|
+
this.schema = {};
|
|
141
|
+
this.layout = [];
|
|
142
|
+
this.formGroupTemplate = {};
|
|
143
|
+
this.formGroup = null;
|
|
144
|
+
this.framework = null;
|
|
145
|
+
this.data = {};
|
|
146
|
+
this.validData = null;
|
|
147
|
+
this.isValid = null;
|
|
148
|
+
this.validationErrors = null;
|
|
149
|
+
this.arrayMap = new Map();
|
|
150
|
+
this.dataMap = new Map();
|
|
151
|
+
this.dataRecursiveRefMap = new Map();
|
|
152
|
+
this.schemaRecursiveRefMap = new Map();
|
|
153
|
+
this.layoutRefLibrary = {};
|
|
154
|
+
this.schemaRefLibrary = {};
|
|
155
|
+
this.templateRefLibrary = {};
|
|
156
|
+
this.formOptions = cloneDeep(this.defaultFormOptions);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 'buildRemoteError' function
|
|
160
|
+
*
|
|
161
|
+
* Example errors:
|
|
162
|
+
* {
|
|
163
|
+
* last_name: [ {
|
|
164
|
+
* message: 'Last name must by start with capital letter.',
|
|
165
|
+
* code: 'capital_letter'
|
|
166
|
+
* } ],
|
|
167
|
+
* email: [ {
|
|
168
|
+
* message: 'Email must be from example.com domain.',
|
|
169
|
+
* code: 'special_domain'
|
|
170
|
+
* }, {
|
|
171
|
+
* message: 'Email must contain an @ symbol.',
|
|
172
|
+
* code: 'at_symbol'
|
|
173
|
+
* } ]
|
|
174
|
+
* }
|
|
175
|
+
* //{ErrorMessages} errors
|
|
176
|
+
*/
|
|
177
|
+
buildRemoteError(errors) {
|
|
178
|
+
forEach(errors, (value, key) => {
|
|
179
|
+
if (key in this.formGroup.controls) {
|
|
180
|
+
for (const error of value) {
|
|
181
|
+
const err = {};
|
|
182
|
+
err[error['code']] = error['message'];
|
|
183
|
+
this.formGroup.get(key).setErrors(err, { emitEvent: true });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
validateData(newValue, updateSubscriptions = true) {
|
|
189
|
+
// Format raw form data to correct data types
|
|
190
|
+
this.data = formatFormData(newValue, this.dataMap, this.dataRecursiveRefMap, this.arrayMap, this.formOptions.returnEmptyFields);
|
|
191
|
+
this.isValid = this.validateFormData(this.data);
|
|
192
|
+
this.validData = this.isValid ? this.data : null;
|
|
193
|
+
const compileErrors = (errors) => {
|
|
194
|
+
const compiledErrors = {};
|
|
195
|
+
(errors || []).forEach(error => {
|
|
196
|
+
//TODO review-seems to be a change in newer versions
|
|
197
|
+
//of ajv giving '' as instancePath for root objects
|
|
198
|
+
let errorPath = error.instancePath || "ROOT";
|
|
199
|
+
if (!compiledErrors[errorPath]) {
|
|
200
|
+
compiledErrors[errorPath] = [];
|
|
201
|
+
}
|
|
202
|
+
compiledErrors[errorPath].push(error.message);
|
|
203
|
+
});
|
|
204
|
+
return compiledErrors;
|
|
205
|
+
};
|
|
206
|
+
this.ajvErrors = this.validateFormData.errors;
|
|
207
|
+
this.validationErrors = compileErrors(this.validateFormData.errors);
|
|
208
|
+
if (updateSubscriptions) {
|
|
209
|
+
this.dataChanges.next(this.data);
|
|
210
|
+
this.isValidChanges.next(this.isValid);
|
|
211
|
+
this.validationErrorChanges.next(this.ajvErrors);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
buildFormGroupTemplate(formValues = null, setValues = true) {
|
|
215
|
+
this.formGroupTemplate = buildFormGroupTemplate(this, formValues, setValues);
|
|
216
|
+
}
|
|
217
|
+
buildFormGroup() {
|
|
218
|
+
this.formGroup = buildFormGroup(this.formGroupTemplate);
|
|
219
|
+
if (this.formGroup) {
|
|
220
|
+
this.compileAjvSchema();
|
|
221
|
+
this.validateData(this.formGroup.value);
|
|
222
|
+
// Set up observables to emit data and validation info when form data changes
|
|
223
|
+
if (this.formValueSubscription) {
|
|
224
|
+
this.formValueSubscription.unsubscribe();
|
|
225
|
+
}
|
|
226
|
+
this.formValueSubscription = this.formGroup.valueChanges.subscribe(formValue => this.validateData(formValue));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
buildLayout(widgetLibrary) {
|
|
230
|
+
this.layout = buildLayout(this, widgetLibrary);
|
|
231
|
+
}
|
|
232
|
+
setOptions(newOptions) {
|
|
233
|
+
if (isObject(newOptions)) {
|
|
234
|
+
const addOptions = cloneDeep(newOptions);
|
|
235
|
+
// Backward compatibility for 'defaultOptions' (renamed 'defaultWidgetOptions')
|
|
236
|
+
if (isObject(addOptions.defaultOptions)) {
|
|
237
|
+
Object.assign(this.formOptions.defaultWidgetOptions, addOptions.defaultOptions);
|
|
238
|
+
delete addOptions.defaultOptions;
|
|
239
|
+
}
|
|
240
|
+
if (isObject(addOptions.defaultWidgetOptions)) {
|
|
241
|
+
Object.assign(this.formOptions.defaultWidgetOptions, addOptions.defaultWidgetOptions);
|
|
242
|
+
delete addOptions.defaultWidgetOptions;
|
|
243
|
+
}
|
|
244
|
+
Object.assign(this.formOptions, addOptions);
|
|
245
|
+
// convert disableErrorState / disableSuccessState to enable...
|
|
246
|
+
const globalDefaults = this.formOptions.defaultWidgetOptions;
|
|
247
|
+
['ErrorState', 'SuccessState']
|
|
248
|
+
.filter(suffix => hasOwn(globalDefaults, 'disable' + suffix))
|
|
249
|
+
.forEach(suffix => {
|
|
250
|
+
globalDefaults['enable' + suffix] = !globalDefaults['disable' + suffix];
|
|
251
|
+
delete globalDefaults['disable' + suffix];
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
compileAjvSchema() {
|
|
256
|
+
if (!this.validateFormData) {
|
|
257
|
+
// if 'ui:order' exists in properties, move it to root before compiling with ajv
|
|
258
|
+
if (Array.isArray(this.schema.properties['ui:order'])) {
|
|
259
|
+
this.schema['ui:order'] = this.schema.properties['ui:order'];
|
|
260
|
+
delete this.schema.properties['ui:order'];
|
|
261
|
+
}
|
|
262
|
+
this.ajv.removeSchema(this.schema);
|
|
263
|
+
this.validateFormData = this.ajv.compile(this.schema);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
buildSchemaFromData(data, requireAllFields = false) {
|
|
267
|
+
if (data) {
|
|
268
|
+
return buildSchemaFromData(data, requireAllFields);
|
|
269
|
+
}
|
|
270
|
+
this.schema = buildSchemaFromData(this.formValues, requireAllFields);
|
|
271
|
+
}
|
|
272
|
+
buildSchemaFromLayout(layout) {
|
|
273
|
+
if (layout) {
|
|
274
|
+
return buildSchemaFromLayout(layout);
|
|
275
|
+
}
|
|
276
|
+
this.schema = buildSchemaFromLayout(this.layout);
|
|
277
|
+
}
|
|
278
|
+
setTpldata(newTpldata = {}) {
|
|
279
|
+
this.tpldata = newTpldata;
|
|
280
|
+
}
|
|
281
|
+
parseText(text = '', value = {}, values = {}, key = null) {
|
|
282
|
+
if (!text || !/{{.+?}}/.test(text)) {
|
|
283
|
+
return text;
|
|
284
|
+
}
|
|
285
|
+
return text.replace(/{{(.+?)}}/g, (...a) => this.parseExpression(a[1], value, values, key, this.tpldata));
|
|
286
|
+
}
|
|
287
|
+
parseExpression(expression = '', value = {}, values = {}, key = null, tpldata = null) {
|
|
288
|
+
if (typeof expression !== 'string') {
|
|
289
|
+
return '';
|
|
290
|
+
}
|
|
291
|
+
const index = typeof key === 'number' ? key + 1 + '' : key || '';
|
|
292
|
+
expression = expression.trim();
|
|
293
|
+
if ((expression[0] === "'" || expression[0] === '"') &&
|
|
294
|
+
expression[0] === expression[expression.length - 1] &&
|
|
295
|
+
expression.slice(1, expression.length - 1).indexOf(expression[0]) === -1) {
|
|
296
|
+
return expression.slice(1, expression.length - 1);
|
|
297
|
+
}
|
|
298
|
+
if (expression === 'idx' || expression === '$index') {
|
|
299
|
+
return index;
|
|
300
|
+
}
|
|
301
|
+
if (expression === 'value' && !hasOwn(values, 'value')) {
|
|
302
|
+
return value;
|
|
303
|
+
}
|
|
304
|
+
if (['"', "'", ' ', '||', '&&', '+'].every(delim => expression.indexOf(delim) === -1)) {
|
|
305
|
+
const pointer = JsonPointer.parseObjectPath(expression);
|
|
306
|
+
return pointer[0] === 'value' && JsonPointer.has(value, pointer.slice(1))
|
|
307
|
+
? JsonPointer.get(value, pointer.slice(1))
|
|
308
|
+
: pointer[0] === 'values' && JsonPointer.has(values, pointer.slice(1))
|
|
309
|
+
? JsonPointer.get(values, pointer.slice(1))
|
|
310
|
+
: pointer[0] === 'tpldata' && JsonPointer.has(tpldata, pointer.slice(1))
|
|
311
|
+
? JsonPointer.get(tpldata, pointer.slice(1))
|
|
312
|
+
: JsonPointer.has(values, pointer)
|
|
313
|
+
? JsonPointer.get(values, pointer)
|
|
314
|
+
: '';
|
|
315
|
+
}
|
|
316
|
+
if (expression.indexOf('[idx]') > -1) {
|
|
317
|
+
expression = expression.replace(/\[idx\]/g, index);
|
|
318
|
+
}
|
|
319
|
+
if (expression.indexOf('[$index]') > -1) {
|
|
320
|
+
expression = expression.replace(/\[$index\]/g, index);
|
|
321
|
+
}
|
|
322
|
+
// TODO: Improve expression evaluation by parsing quoted strings first
|
|
323
|
+
// let expressionArray = expression.match(/([^"']+|"[^"]+"|'[^']+')/g);
|
|
324
|
+
if (expression.indexOf('||') > -1) {
|
|
325
|
+
return expression
|
|
326
|
+
.split('||')
|
|
327
|
+
.reduce((all, term) => all || this.parseExpression(term, value, values, key, tpldata), '');
|
|
328
|
+
}
|
|
329
|
+
if (expression.indexOf('&&') > -1) {
|
|
330
|
+
return expression
|
|
331
|
+
.split('&&')
|
|
332
|
+
.reduce((all, term) => all && this.parseExpression(term, value, values, key, tpldata), ' ')
|
|
333
|
+
.trim();
|
|
334
|
+
}
|
|
335
|
+
if (expression.indexOf('+') > -1) {
|
|
336
|
+
return expression
|
|
337
|
+
.split('+')
|
|
338
|
+
.map(term => this.parseExpression(term, value, values, key, tpldata))
|
|
339
|
+
.join('');
|
|
340
|
+
}
|
|
341
|
+
return '';
|
|
342
|
+
}
|
|
343
|
+
setArrayItemTitle(parentCtx = {}, childNode = null, index = null) {
|
|
344
|
+
const parentNode = parentCtx.layoutNode;
|
|
345
|
+
const parentValues = this.getFormControlValue(parentCtx);
|
|
346
|
+
const isArrayItem = (parentNode.type || '').slice(-5) === 'array' && isArray(parentValues);
|
|
347
|
+
const text = JsonPointer.getFirst(isArrayItem && childNode.type !== '$ref'
|
|
348
|
+
? [
|
|
349
|
+
[childNode, '/options/legend'],
|
|
350
|
+
[childNode, '/options/title'],
|
|
351
|
+
[parentNode, '/options/title'],
|
|
352
|
+
[parentNode, '/options/legend']
|
|
353
|
+
]
|
|
354
|
+
: [
|
|
355
|
+
[childNode, '/options/title'],
|
|
356
|
+
[childNode, '/options/legend'],
|
|
357
|
+
[parentNode, '/options/title'],
|
|
358
|
+
[parentNode, '/options/legend']
|
|
359
|
+
]);
|
|
360
|
+
if (!text) {
|
|
361
|
+
return text;
|
|
362
|
+
}
|
|
363
|
+
const childValue = isArray(parentValues) && index < parentValues.length
|
|
364
|
+
? parentValues[index]
|
|
365
|
+
: parentValues;
|
|
366
|
+
return this.parseText(text, childValue, parentValues, index);
|
|
367
|
+
}
|
|
368
|
+
setItemTitle(ctx) {
|
|
369
|
+
return !ctx.options.title && /^(\d+|-)$/.test(ctx.layoutNode.name)
|
|
370
|
+
? null
|
|
371
|
+
: this.parseText(ctx.options.title || toTitleCase(ctx.layoutNode.name), this.getFormControlValue(this), (this.getFormControlGroup(this) || {}).value, ctx.dataIndex[ctx.dataIndex.length - 1]);
|
|
372
|
+
}
|
|
373
|
+
evaluateCondition(layoutNode, dataIndex) {
|
|
374
|
+
const arrayIndex = dataIndex && dataIndex[dataIndex.length - 1];
|
|
375
|
+
let result = true;
|
|
376
|
+
if (hasValue((layoutNode.options || {}).condition)) {
|
|
377
|
+
if (typeof layoutNode.options.condition === 'string') {
|
|
378
|
+
let pointer = layoutNode.options.condition;
|
|
379
|
+
if (hasValue(arrayIndex)) {
|
|
380
|
+
pointer = pointer.replace('[arrayIndex]', `[${arrayIndex}]`);
|
|
381
|
+
}
|
|
382
|
+
pointer = JsonPointer.parseObjectPath(pointer);
|
|
383
|
+
result = !!JsonPointer.get(this.data, pointer);
|
|
384
|
+
if (!result && pointer[0] === 'model') {
|
|
385
|
+
result = !!JsonPointer.get({ model: this.data }, pointer);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
else if (typeof layoutNode.options.condition === 'function') {
|
|
389
|
+
result = layoutNode.options.condition(this.data);
|
|
390
|
+
}
|
|
391
|
+
else if (typeof layoutNode.options.condition.functionBody === 'string') {
|
|
392
|
+
try {
|
|
393
|
+
const dynFn = new Function('model', 'arrayIndices', layoutNode.options.condition.functionBody);
|
|
394
|
+
result = dynFn(this.data, dataIndex);
|
|
395
|
+
}
|
|
396
|
+
catch (e) {
|
|
397
|
+
result = true;
|
|
398
|
+
console.error('condition functionBody errored out on evaluation: ' +
|
|
399
|
+
layoutNode.options.condition.functionBody);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return result;
|
|
404
|
+
}
|
|
405
|
+
initializeControl(ctx, bind = true) {
|
|
406
|
+
if (!isObject(ctx)) {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
if (isEmpty(ctx.options)) {
|
|
410
|
+
ctx.options = !isEmpty((ctx.layoutNode || {}).options)
|
|
411
|
+
? ctx.layoutNode.options
|
|
412
|
+
: cloneDeep(this.formOptions);
|
|
413
|
+
}
|
|
414
|
+
ctx.formControl = this.getFormControl(ctx);
|
|
415
|
+
ctx.boundControl = bind && !!ctx.formControl;
|
|
416
|
+
if (ctx.formControl) {
|
|
417
|
+
ctx.controlName = this.getFormControlName(ctx);
|
|
418
|
+
ctx.controlValue = ctx.formControl.value;
|
|
419
|
+
ctx.controlDisabled = ctx.formControl.disabled;
|
|
420
|
+
ctx.options.errorMessage =
|
|
421
|
+
ctx.formControl.status === 'VALID'
|
|
422
|
+
? null
|
|
423
|
+
: this.formatErrors(ctx.formControl.errors, ctx.options.validationMessages);
|
|
424
|
+
ctx.options.showErrors =
|
|
425
|
+
this.formOptions.validateOnRender === true ||
|
|
426
|
+
(this.formOptions.validateOnRender === 'auto' &&
|
|
427
|
+
hasValue(ctx.controlValue));
|
|
428
|
+
this.fcStatusChangesSubs = ctx.formControl.statusChanges.subscribe(status => (ctx.options.errorMessage =
|
|
429
|
+
status === 'VALID'
|
|
430
|
+
? null
|
|
431
|
+
: this.formatErrors(ctx.formControl.errors, ctx.options.validationMessages)));
|
|
432
|
+
this.fcValueChangesSubs = ctx.formControl.valueChanges.subscribe(value => {
|
|
433
|
+
//commented out to revert back to previous commits
|
|
434
|
+
//as seems to be causing some issues
|
|
435
|
+
/*
|
|
436
|
+
if (!!value) {
|
|
437
|
+
ctx.controlValue = value;
|
|
438
|
+
}
|
|
439
|
+
*/
|
|
440
|
+
//TODO-test,this is the original code
|
|
441
|
+
if (!_isEqual(ctx.controlValue, value)) {
|
|
442
|
+
ctx.controlValue = value;
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
ctx.controlName = ctx.layoutNode.name;
|
|
448
|
+
ctx.controlValue = ctx.layoutNode.value || null;
|
|
449
|
+
const dataPointer = this.getDataPointer(ctx);
|
|
450
|
+
if (bind && dataPointer) {
|
|
451
|
+
console.error(`warning: control "${dataPointer}" is not bound to the Angular FormGroup.`);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return ctx.boundControl;
|
|
455
|
+
}
|
|
456
|
+
formatErrors(errors, validationMessages = {}) {
|
|
457
|
+
if (isEmpty(errors)) {
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
460
|
+
if (!isObject(validationMessages)) {
|
|
461
|
+
validationMessages = {};
|
|
462
|
+
}
|
|
463
|
+
const addSpaces = string => string[0].toUpperCase() +
|
|
464
|
+
(string.slice(1) || '')
|
|
465
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
466
|
+
.replace(/_/g, ' ');
|
|
467
|
+
const formatError = error => typeof error === 'object'
|
|
468
|
+
? Object.keys(error)
|
|
469
|
+
.map(key => error[key] === true
|
|
470
|
+
? addSpaces(key)
|
|
471
|
+
: error[key] === false
|
|
472
|
+
? 'Not ' + addSpaces(key)
|
|
473
|
+
: addSpaces(key) + ': ' + formatError(error[key]))
|
|
474
|
+
.join(', ')
|
|
475
|
+
: addSpaces(error.toString());
|
|
476
|
+
const messages = [];
|
|
477
|
+
return (Object.keys(errors)
|
|
478
|
+
// Hide 'required' error, unless it is the only one
|
|
479
|
+
.filter(errorKey => errorKey !== 'required' || Object.keys(errors).length === 1)
|
|
480
|
+
.map(errorKey =>
|
|
481
|
+
// If validationMessages is a string, return it
|
|
482
|
+
typeof validationMessages === 'string'
|
|
483
|
+
? validationMessages
|
|
484
|
+
: // If custom error message is a function, return function result
|
|
485
|
+
typeof validationMessages[errorKey] === 'function'
|
|
486
|
+
? validationMessages[errorKey](errors[errorKey])
|
|
487
|
+
: // If custom error message is a string, replace placeholders and return
|
|
488
|
+
typeof validationMessages[errorKey] === 'string'
|
|
489
|
+
? // Does error message have any {{property}} placeholders?
|
|
490
|
+
!/{{.+?}}/.test(validationMessages[errorKey])
|
|
491
|
+
? validationMessages[errorKey]
|
|
492
|
+
: // Replace {{property}} placeholders with values
|
|
493
|
+
Object.keys(errors[errorKey]).reduce((errorMessage, errorProperty) => errorMessage.replace(new RegExp('{{' + errorProperty + '}}', 'g'), errors[errorKey][errorProperty]), validationMessages[errorKey])
|
|
494
|
+
: // If no custom error message, return formatted error data instead
|
|
495
|
+
addSpaces(errorKey) + ' Error: ' + formatError(errors[errorKey]))
|
|
496
|
+
.join('<br>'));
|
|
497
|
+
}
|
|
498
|
+
updateValue(ctx, value) {
|
|
499
|
+
// Set value of current control
|
|
500
|
+
ctx.controlValue = value;
|
|
501
|
+
if (ctx.boundControl) {
|
|
502
|
+
ctx.formControl.setValue(value);
|
|
503
|
+
ctx.formControl.markAsDirty();
|
|
504
|
+
}
|
|
505
|
+
ctx.layoutNode.value = value;
|
|
506
|
+
// Set values of any related controls in copyValueTo array
|
|
507
|
+
if (isArray(ctx.options.copyValueTo)) {
|
|
508
|
+
for (const item of ctx.options.copyValueTo) {
|
|
509
|
+
const targetControl = getControl(this.formGroup, item);
|
|
510
|
+
if (isObject(targetControl) &&
|
|
511
|
+
typeof targetControl.setValue === 'function') {
|
|
512
|
+
targetControl.setValue(value);
|
|
513
|
+
targetControl.markAsDirty();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
updateArrayCheckboxList(ctx, checkboxList) {
|
|
519
|
+
const formArray = this.getFormControl(ctx);
|
|
520
|
+
// Remove all existing items
|
|
521
|
+
while (formArray.value.length) {
|
|
522
|
+
formArray.removeAt(0);
|
|
523
|
+
}
|
|
524
|
+
// Re-add an item for each checked box
|
|
525
|
+
const refPointer = removeRecursiveReferences(ctx.layoutNode.dataPointer + '/-', this.dataRecursiveRefMap, this.arrayMap);
|
|
526
|
+
for (const checkboxItem of checkboxList) {
|
|
527
|
+
if (checkboxItem.checked) {
|
|
528
|
+
const newFormControl = buildFormGroup(this.templateRefLibrary[refPointer]);
|
|
529
|
+
newFormControl.setValue(checkboxItem.value);
|
|
530
|
+
formArray.push(newFormControl);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
formArray.markAsDirty();
|
|
534
|
+
}
|
|
535
|
+
getFormControl(ctx) {
|
|
536
|
+
if (!ctx.layoutNode ||
|
|
537
|
+
!isDefined(ctx.layoutNode.dataPointer) ||
|
|
538
|
+
ctx.layoutNode.type === '$ref') {
|
|
539
|
+
return null;
|
|
540
|
+
}
|
|
541
|
+
return getControl(this.formGroup, this.getDataPointer(ctx));
|
|
542
|
+
}
|
|
543
|
+
getFormControlValue(ctx) {
|
|
544
|
+
if (!ctx.layoutNode ||
|
|
545
|
+
!isDefined(ctx.layoutNode.dataPointer) ||
|
|
546
|
+
ctx.layoutNode.type === '$ref') {
|
|
547
|
+
return null;
|
|
548
|
+
}
|
|
549
|
+
const control = getControl(this.formGroup, this.getDataPointer(ctx));
|
|
550
|
+
return control ? control.value : null;
|
|
551
|
+
}
|
|
552
|
+
getFormControlGroup(ctx) {
|
|
553
|
+
if (!ctx.layoutNode || !isDefined(ctx.layoutNode.dataPointer)) {
|
|
554
|
+
return null;
|
|
555
|
+
}
|
|
556
|
+
return getControl(this.formGroup, this.getDataPointer(ctx), true);
|
|
557
|
+
}
|
|
558
|
+
getFormControlName(ctx) {
|
|
559
|
+
if (!ctx.layoutNode ||
|
|
560
|
+
!isDefined(ctx.layoutNode.dataPointer) ||
|
|
561
|
+
!hasValue(ctx.dataIndex)) {
|
|
562
|
+
return null;
|
|
563
|
+
}
|
|
564
|
+
return JsonPointer.toKey(this.getDataPointer(ctx));
|
|
565
|
+
}
|
|
566
|
+
getLayoutArray(ctx) {
|
|
567
|
+
return JsonPointer.get(this.layout, this.getLayoutPointer(ctx), 0, -1);
|
|
568
|
+
}
|
|
569
|
+
getParentNode(ctx) {
|
|
570
|
+
return JsonPointer.get(this.layout, this.getLayoutPointer(ctx), 0, -2);
|
|
571
|
+
}
|
|
572
|
+
getDataPointer(ctx) {
|
|
573
|
+
if (!ctx.layoutNode ||
|
|
574
|
+
!isDefined(ctx.layoutNode.dataPointer) ||
|
|
575
|
+
!hasValue(ctx.dataIndex)) {
|
|
576
|
+
return null;
|
|
577
|
+
}
|
|
578
|
+
return JsonPointer.toIndexedPointer(ctx.layoutNode.dataPointer, ctx.dataIndex, this.arrayMap);
|
|
579
|
+
}
|
|
580
|
+
getLayoutPointer(ctx) {
|
|
581
|
+
if (!hasValue(ctx.layoutIndex)) {
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
return '/' + ctx.layoutIndex.join('/items/');
|
|
585
|
+
}
|
|
586
|
+
isControlBound(ctx) {
|
|
587
|
+
if (!ctx.layoutNode ||
|
|
588
|
+
!isDefined(ctx.layoutNode.dataPointer) ||
|
|
589
|
+
!hasValue(ctx.dataIndex)) {
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
const controlGroup = this.getFormControlGroup(ctx);
|
|
593
|
+
const name = this.getFormControlName(ctx);
|
|
594
|
+
return controlGroup ? hasOwn(controlGroup.controls, name) : false;
|
|
595
|
+
}
|
|
596
|
+
addItem(ctx, name) {
|
|
597
|
+
if (!ctx.layoutNode ||
|
|
598
|
+
!isDefined(ctx.layoutNode.$ref) ||
|
|
599
|
+
!hasValue(ctx.dataIndex) ||
|
|
600
|
+
!hasValue(ctx.layoutIndex)) {
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
603
|
+
// Create a new Angular form control from a template in templateRefLibrary
|
|
604
|
+
const newFormGroup = buildFormGroup(this.templateRefLibrary[ctx.layoutNode.$ref]);
|
|
605
|
+
// Add the new form control to the parent formArray or formGroup
|
|
606
|
+
if (ctx.layoutNode.arrayItem) {
|
|
607
|
+
// Add new array item to formArray
|
|
608
|
+
this.getFormControlGroup(ctx).push(newFormGroup);
|
|
609
|
+
}
|
|
610
|
+
else {
|
|
611
|
+
// Add new $ref item to formGroup
|
|
612
|
+
this.getFormControlGroup(ctx).addControl(name || this.getFormControlName(ctx), newFormGroup);
|
|
613
|
+
}
|
|
614
|
+
// Copy a new layoutNode from layoutRefLibrary
|
|
615
|
+
const newLayoutNode = getLayoutNode(ctx.layoutNode, this);
|
|
616
|
+
newLayoutNode.arrayItem = ctx.layoutNode.arrayItem;
|
|
617
|
+
if (ctx.layoutNode.arrayItemType) {
|
|
618
|
+
newLayoutNode.arrayItemType = ctx.layoutNode.arrayItemType;
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
delete newLayoutNode.arrayItemType;
|
|
622
|
+
}
|
|
623
|
+
if (name) {
|
|
624
|
+
newLayoutNode.name = name;
|
|
625
|
+
newLayoutNode.dataPointer += '/' + JsonPointer.escape(name);
|
|
626
|
+
newLayoutNode.options.title = fixTitle(name);
|
|
627
|
+
}
|
|
628
|
+
// Add the new layoutNode to the form layout
|
|
629
|
+
JsonPointer.insert(this.layout, this.getLayoutPointer(ctx), newLayoutNode);
|
|
630
|
+
return true;
|
|
631
|
+
}
|
|
632
|
+
moveArrayItem(ctx, oldIndex, newIndex) {
|
|
633
|
+
if (!ctx.layoutNode ||
|
|
634
|
+
!isDefined(ctx.layoutNode.dataPointer) ||
|
|
635
|
+
!hasValue(ctx.dataIndex) ||
|
|
636
|
+
!hasValue(ctx.layoutIndex) ||
|
|
637
|
+
!isDefined(oldIndex) ||
|
|
638
|
+
!isDefined(newIndex) ||
|
|
639
|
+
oldIndex === newIndex) {
|
|
640
|
+
return false;
|
|
641
|
+
}
|
|
642
|
+
// Move item in the formArray
|
|
643
|
+
const formArray = this.getFormControlGroup(ctx);
|
|
644
|
+
const arrayItem = formArray.at(oldIndex);
|
|
645
|
+
formArray.removeAt(oldIndex);
|
|
646
|
+
formArray.insert(newIndex, arrayItem);
|
|
647
|
+
formArray.updateValueAndValidity();
|
|
648
|
+
// Move layout item
|
|
649
|
+
const layoutArray = this.getLayoutArray(ctx);
|
|
650
|
+
layoutArray.splice(newIndex, 0, layoutArray.splice(oldIndex, 1)[0]);
|
|
651
|
+
return true;
|
|
652
|
+
}
|
|
653
|
+
removeItem(ctx) {
|
|
654
|
+
if (!ctx.layoutNode ||
|
|
655
|
+
!isDefined(ctx.layoutNode.dataPointer) ||
|
|
656
|
+
!hasValue(ctx.dataIndex) ||
|
|
657
|
+
!hasValue(ctx.layoutIndex)) {
|
|
658
|
+
return false;
|
|
659
|
+
}
|
|
660
|
+
// Remove the Angular form control from the parent formArray or formGroup
|
|
661
|
+
if (ctx.layoutNode.arrayItem) {
|
|
662
|
+
// Remove array item from formArray
|
|
663
|
+
this.getFormControlGroup(ctx).removeAt(ctx.dataIndex[ctx.dataIndex.length - 1]);
|
|
664
|
+
}
|
|
665
|
+
else {
|
|
666
|
+
// Remove $ref item from formGroup
|
|
667
|
+
this.getFormControlGroup(ctx).removeControl(this.getFormControlName(ctx));
|
|
668
|
+
}
|
|
669
|
+
// Remove layoutNode from layout
|
|
670
|
+
JsonPointer.remove(this.layout, this.getLayoutPointer(ctx));
|
|
671
|
+
return true;
|
|
672
|
+
}
|
|
673
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: JsonSchemaFormService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
674
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: JsonSchemaFormService }); }
|
|
675
|
+
}
|
|
676
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: JsonSchemaFormService, decorators: [{
|
|
677
|
+
type: Injectable
|
|
678
|
+
}], ctorParameters: () => [] });
|
|
679
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1zY2hlbWEtZm9ybS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctZm9ybXdvcmtzLWNvcmUvc3JjL2xpYi9qc29uLXNjaGVtYS1mb3JtLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUV0RCxrREFBa0Q7QUFDbEQsT0FBTyxPQUFpQyxNQUFNLGVBQWUsQ0FBQztBQUU5RCxPQUFPLFVBQVUsTUFBTSx3Q0FBd0MsQ0FBQztBQUNoRSxPQUFPLFVBQVUsTUFBTSx3Q0FBd0MsQ0FBQztBQUNoRSxPQUFPLFNBQVMsTUFBTSxrQkFBa0IsQ0FBQztBQUN6QyxPQUFPLEVBQUUsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUM3QyxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLG9CQUFvQixFQUNwQixvQkFBb0IsRUFDcEIsb0JBQW9CLEVBQ3BCLG9CQUFvQixFQUNwQixvQkFBb0IsRUFDcEIsb0JBQW9CLEVBQ3JCLE1BQU0sVUFBVSxDQUFDO0FBQ2xCLE9BQU8sRUFDTCxXQUFXLEVBQ1gsY0FBYyxFQUNkLHNCQUFzQixFQUN0QixXQUFXLEVBQ1gsbUJBQW1CLEVBQ25CLHFCQUFxQixFQUNyQixRQUFRLEVBQ1IsT0FBTyxFQUNQLGNBQWMsRUFDZCxVQUFVLEVBQ1YsYUFBYSxFQUNiLE1BQU0sRUFDTixRQUFRLEVBQ1IsT0FBTyxFQUNQLFNBQVMsRUFDVCxPQUFPLEVBQ1AsUUFBUSxFQUNSLHlCQUF5QixFQUN6QixXQUFXLEVBQ1osTUFBTSxVQUFVLENBQUM7QUFFbEIsT0FBTyxRQUFRLE1BQU0sZ0JBQWdCLENBQUM7O0FBa0J0QyxNQUFNLE9BQU8scUJBQXFCO0lBZ0doQztRQS9GQSwwQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFDOUIscUNBQWdDLEdBQUcsS0FBSyxDQUFDO1FBQ3pDLG1DQUE4QixHQUFH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ZWN0YWJsZSwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgVW50eXBlZEZvcm1BcnJheSwgVW50eXBlZEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuLy9pbXBvcnQgQWp2LCB7IEVycm9yT2JqZWN0LCBPcHRpb25zIH0gZnJvbSAnYWp2JztcclxuaW1wb3J0IEFqdjIwMTksIHsgRXJyb3JPYmplY3QsIE9wdGlvbnMgfSBmcm9tICdhanYvZGlzdC8yMDE5JztcclxuXHJcbmltcG9ydCBqc29uRHJhZnQ2IGZyb20gJ2Fqdi9saWIvcmVmcy9qc29uLXNjaGVtYS1kcmFmdC0wNi5qc29uJztcclxuaW1wb3J0IGpzb25EcmFmdDcgZnJvbSAnYWp2L2xpYi9yZWZzL2pzb24tc2NoZW1hLWRyYWZ0LTA3Lmpzb24nO1xyXG5pbXBvcnQgY2xvbmVEZWVwIGZyb20gJ2xvZGFzaC9jbG9uZURlZXAnO1xyXG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHtcclxuICBkZVZhbGlkYXRpb25NZXNzYWdlcyxcclxuICBlblZhbGlkYXRpb25NZXNzYWdlcyxcclxuICBlc1ZhbGlkYXRpb25NZXNzYWdlcyxcclxuICBmclZhbGlkYXRpb25NZXNzYWdlcyxcclxuICBpdFZhbGlkYXRpb25NZXNzYWdlcyxcclxuICBwdFZhbGlkYXRpb25NZXNzYWdlcyxcclxuICB6aFZhbGlkYXRpb25NZXNzYWdlc1xyXG59IGZyb20gJy4vbG9jYWxlJztcclxuaW1wb3J0IHtcclxuICBKc29uUG9pbnRlcixcclxuICBidWlsZEZvcm1Hcm91cCxcclxuICBidWlsZEZvcm1Hcm91cFRlbXBsYXRlLFxyXG4gIGJ1aWxkTGF5b3V0LFxyXG4gIGJ1aWxkU2NoZW1hRnJvbURhdGEsXHJcbiAgYnVpbGRTY2hlbWFGcm9tTGF5b3V0LFxyXG4gIGZpeFRpdGxlLFxyXG4gIGZvckVhY2gsXHJcbiAgZm9ybWF0Rm9ybURhdGEsXHJcbiAgZ2V0Q29udHJvbCxcclxuICBnZXRMYXlvdXROb2RlLFxyXG4gIGhhc093bixcclxuICBoYXNWYWx1ZSxcclxuICBpc0FycmF5LFxyXG4gIGlzRGVmaW5lZCxcclxuICBpc0VtcHR5LFxyXG4gIGlzT2JqZWN0LFxyXG4gIHJlbW92ZVJlY3Vyc2l2ZVJlZmVyZW5jZXMsXHJcbiAgdG9UaXRsZUNhc2VcclxufSBmcm9tICcuL3NoYXJlZCc7XHJcblxyXG5pbXBvcnQgX2lzRXF1YWwgZnJvbSAnbG9kYXNoL2lzRXF1YWwnO1xyXG5cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVGl0bGVNYXBJdGVtIHtcclxuICBuYW1lPzogc3RyaW5nO1xyXG4gIHZhbHVlPzogYW55O1xyXG4gIGNoZWNrZWQ/OiBib29sZWFuO1xyXG4gIGdyb3VwPzogc3RyaW5nO1xyXG4gIGl0ZW1zPzogVGl0bGVNYXBJdGVtW107XHJcbn1cclxuZXhwb3J0IGludGVyZmFjZSBFcnJvck1lc3NhZ2VzIHtcclxuICBbY29udHJvbF9uYW1lOiBzdHJpbmddOiB7XHJcbiAgICBtZXNzYWdlOiBzdHJpbmcgfCBGdW5jdGlvbiB8IE9iamVjdDtcclxuICAgIGNvZGU6IHN0cmluZztcclxuICB9W107XHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEpzb25TY2hlbWFGb3JtU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XHJcbiAgSnNvbkZvcm1Db21wYXRpYmlsaXR5ID0gZmFsc2U7XHJcbiAgUmVhY3RKc29uU2NoZW1hRm9ybUNvbXBhdGliaWxpdHkgPSBmYWxzZTtcclxuICBBbmd1bGFyU2NoZW1hRm9ybUNvbXBhdGliaWxpdHkgPSBmYWxzZTtcclxuICB0cGxkYXRhOiBhbnkgPSB7fTtcclxuXHJcbiAgYWp2T3B0aW9uczogT3B0aW9ucyA9IHtcclxuICAgIGFsbEVycm9yczogdHJ1ZSxcclxuICAgIHZhbGlkYXRlRm9ybWF0czpmYWxzZSxcclxuICAgIHN0cmljdDpmYWxzZVxyXG4gIFxyXG4gIH07XHJcbiAgYWp2OmFueSA9IG5ldyBBanYyMDE5KHRoaXMuYWp2T3B0aW9ucyk7IC8vIEFKVjogQW5vdGhlciBKU09OIFNjaGVtYSBWYWxpZGF0b3JcclxuICBcclxuICB2YWxpZGF0ZUZvcm1EYXRhOiBhbnkgPSBudWxsOyAvLyBDb21waWxlZCBBSlYgZnVuY3Rpb24gdG8gdmFsaWRhdGUgYWN0aXZlIGZvcm0ncyBzY2hlbWFcclxuXHJcbiAgZm9ybVZhbHVlczogYW55ID0ge307IC8vIEludGVybmFsIGZvcm0gZGF0YSAobWF5IG5vdCBoYXZlIGNvcnJlY3QgdHlwZXMpXHJcbiAgZGF0YTogYW55ID0ge307IC8vIE91dHB1dCBmb3JtIGRhdGEgKGZvcm1WYWx1ZXMsIGZvcm1hdHRlZCB3aXRoIGNvcnJlY3QgZGF0YSB0eXBlcylcclxuICBzY2hlbWE6IGFueSA9IHt9OyAvLyBJbnRlcm5hbCBKU09OIFNjaGVtYVxyXG4gIGxheW91dDogYW55W10gPSBbXTsgLy8gSW50ZXJuYWwgZm9ybSBsYXlvdXRcclxuICBmb3JtR3JvdXBUZW1wbGF0ZTogYW55ID0ge307IC8vIFRlbXBsYXRlIHVzZWQgdG8gY3JlYXRlIGZvcm1Hcm91cFxyXG4gIGZvcm1Hcm91cDogYW55ID0gbnVsbDsgLy8gQW5ndWxhciBmb3JtR3JvdXAsIHdoaWNoIHBvd2VycyB0aGUgcmVhY3RpdmUgZm9ybVxyXG4gIGZyYW1ld29yazogYW55ID0gbnVsbDsgLy8gQWN0aXZlIGZyYW1ld29yayBjb21wb25lbnRcclxuICBmb3JtT3B0aW9uczogYW55OyAvLyBBY3RpdmUgb3B0aW9ucywgdXNlZCB0byBjb25maWd1cmUgdGhlIGZvcm1cclxuXHJcbiAgdmFsaWREYXRhOiBhbnkgPSBudWxsOyAvLyBWYWxpZCBmb3JtIGRhdGEgKG9yIG51bGwpICg9PT0gaXNWYWxpZCA/IGRhdGEgOiBudWxsKVxyXG4gIGlzVmFsaWQ6IGJvb2xlYW4gPSBudWxsOyAvLyBJcyBjdXJyZW50IGZvcm0gZGF0YSB2YWxpZD9cclxuICBhanZFcnJvcnM6IEVycm9yT2JqZWN0W10gPSBudWxsOyAvLyBBanYgZXJyb3JzIGZvciBjdXJyZW50IGRhdGFcclxuICB2YWxpZGF0aW9uRXJyb3JzOiBhbnkgPSBudWxsOyAvLyBBbnkgdmFsaWRhdGlvbiBlcnJvcnMgZm9yIGN1cnJlbnQgZGF0YVxyXG4gIGRhdGFFcnJvcnM6IGFueSA9IG5ldyBNYXAoKTsgLy9cclxuICBmb3JtVmFsdWVTdWJzY3JpcHRpb246IGFueSA9IG51bGw7IC8vIFN1YnNjcmlwdGlvbiB0byBmb3JtR3JvdXAudmFsdWVDaGFuZ2VzIG9ic2VydmFibGUgKGZvciB1bi0gYW5kIHJlLXN1YnNjcmliaW5nKVxyXG4gIGRhdGFDaGFuZ2VzOiBTdWJqZWN0PGFueT4gPSBuZXcgU3ViamVjdCgpOyAvLyBGb3JtIGRhdGEgb2JzZXJ2YWJsZVxyXG4gIGlzVmFsaWRDaGFuZ2VzOiBTdWJqZWN0PGFueT4gPSBuZXcgU3ViamVjdCgpOyAvLyBpc1ZhbGlkIG9ic2VydmFibGVcclxuICB2YWxpZGF0aW9uRXJyb3JDaGFuZ2VzOiBTdWJqZWN0PGFueT4gPSBuZXcgU3ViamVjdCgpOyAvLyB2YWxpZGF0aW9uRXJyb3JzIG9ic2VydmFibGVcclxuXHJcbiAgYXJyYXlNYXA6IE1hcDxzdHJpbmcsIG51bWJlcj4gPSBuZXcgTWFwKCk7IC8vIE1hcHMgYXJyYXlzIGluIGRhdGEgb2JqZWN0IGFuZCBudW1iZXIgb2YgdHVwbGUgdmFsdWVzXHJcbiAgZGF0YU1hcDogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTsgLy8gTWFwcyBwYXRocyBpbiBmb3JtIGRhdGEgdG8gc2NoZW1hIGFuZCBmb3JtR3JvdXAgcGF0aHNcclxuICBkYXRhUmVjdXJzaXZlUmVmTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcCgpOyAvLyBNYXBzIHJlY3Vyc2l2ZSByZWZlcmVuY2UgcG9pbnRzIGluIGZvcm0gZGF0YVxyXG4gIHNjaGVtYVJlY3Vyc2l2ZVJlZk1hcDogTWFwPHN0cmluZywgc3RyaW5nPiA9IG5ldyBNYXAoKTsgLy8gTWFwcyByZWN1cnNpdmUgcmVmZXJlbmNlIHBvaW50cyBpbiBzY2hlbWFcclxuICBzY2hlbWFSZWZMaWJyYXJ5OiBhbnkgPSB7fTsgLy8gTGlicmFyeSBvZiBzY2hlbWFzIGZvciByZXNvbHZpbmcgc2NoZW1hICRyZWZzXHJcbiAgbGF5b3V0UmVmTGlicmFyeTogYW55ID0geyAnJzogbnVsbCB9OyAvLyBMaWJyYXJ5IG9mIGxheW91dCBub2RlcyBmb3IgYWRkaW5nIHRvIGZvcm1cclxuICB0ZW1wbGF0ZVJlZkxpYnJhcnk6IGFueSA9IHt9OyAvLyBMaWJyYXJ5IG9mIGZvcm1Hcm91cCB0ZW1wbGF0ZXMgZm9yIGFkZGluZyB0byBmb3JtXHJcbiAgaGFzUm9vdFJlZmVyZW5jZSA9IGZhbHNlOyAvLyBEb2VzIHRoZSBmb3JtIGluY2x1ZGUgYSByZWN1cnNpdmUgcmVmZXJlbmNlIHRvIGl0c2VsZj9cclxuXHJcbiAgbGFuZ3VhZ2UgPSAnZW4tVVMnOyAvLyBEb2VzIHRoZSBmb3JtIGluY2x1ZGUgYSByZWN1cnNpdmUgcmVmZXJlbmNlIHRvIGl0c2VsZj9cclxuXHJcbiAgLy8gRGVmYXVsdCBnbG9iYWwgZm9ybSBvcHRpb25zXHJcbiAgZGVmYXVsdEZvcm1PcHRpb25zOiBhbnkgPSB7XHJcbiAgICBhdXRvY29tcGxldGU6IHRydWUsIC8vIEFsbG93IHRoZSB3ZWIgYnJvd3NlciB0byByZW1lbWJlciBwcmV2aW91cyBmb3JtIHN1Ym1pc3Npb24gdmFsdWVzIGFzIGRlZmF1bHRzXHJcbiAgICBhZGRTdWJtaXQ6ICdhdXRvJywgLy8gQWRkIGEgc3VibWl0IGJ1dHRvbiBpZiBsYXlvdXQgZG9lcyBub3QgaGF2ZSBvbmU/XHJcbiAgICAvLyBmb3IgYWRkU3VibWl0OiB0cnVlID0gYWx3YXlzLCBmYWxzZSA9IG5ldmVyLFxyXG4gICAgLy8gJ2F1dG8nID0gb25seSBpZiBsYXlvdXQgaXMgdW5kZWZpbmVkIChmb3JtIGlzIGJ1aWx0IGZyb20gc2NoZW1hIGFsb25lKVxyXG4gICAgZGVidWc6IGZhbHNlLCAvLyBTaG93IGRlYnVnZ2luZyBvdXRwdXQ/XHJcbiAgICBkaXNhYmxlSW52YWxpZFN1Ym1pdDogdHJ1ZSwgLy8gRGlzYWJsZSBzdWJtaXQgaWYgZm9ybSBpbnZhbGlkP1xyXG4gICAgZm9ybURpc2FibGVkOiBmYWxzZSwgLy8gU2V0IGVudGlyZSBmb3JtIGFzIGRpc2FibGVkPyAobm90IGVkaXRhYmxlLCBhbmQgZGlzYWJsZXMgb3V0cHV0cylcclxuICAgIGZvcm1SZWFkb25seTogZmFsc2UsIC8vIFNldCBlbnRpcmUgZm9ybSBhcyByZWFkIG9ubHk/IChub3QgZWRpdGFibGUsIGJ1dCBvdXRwdXRzIHN0aWxsIGVuYWJsZWQpXHJcbiAgICBmaWVsZHNSZXF1aXJlZDogZmFsc2UsIC8vIChzZXQgYXV0b21hdGljYWxseSkgQXJlIHRoZXJlIGFueSByZXF1aXJlZCBmaWVsZHMgaW4gdGhlIGZvcm0/XHJcbiAgICBmcmFtZXdvcms6ICduby1mcmFtZXdvcmsnLCAvLyBUaGUgZnJhbWV3b3JrIHRvIGxvYWRcclxuICAgIGxvYWRFeHRlcm5hbEFzc2V0czogZmFsc2UsIC8vIExvYWQgZXh0ZXJuYWwgY3NzIGFuZCBKYXZhU2NyaXB0IGZvciBmcmFtZXdvcms/XHJcbiAgICBwcmlzdGluZTogeyBlcnJvcnM6IHRydWUsIHN1Y2Nlc3M6IHRydWUgfSxcclxuICAgIHN1cHJlc3NQcm9wZXJ0eVRpdGxlczogZmFsc2UsXHJcbiAgICBzZXRTY2hlbWFEZWZhdWx0czogJ2F1dG8nLCAvLyBTZXQgZmVmYXVsdCB2YWx1ZXMgZnJvbSBzY2hlbWE/XHJcbiAgICAvLyB0cnVlID0gYWx3YXlzIHNldCAodW5sZXNzIG92ZXJyaWRkZW4gYnkgbGF5b3V0IGRlZmF1bHQgb3IgZm9ybVZhbHVlcylcclxuICAgIC8vIGZhbHNlID0gbmV2ZXIgc2V0XHJcbiAgICAvLyAnYXV0bycgPSBzZXQgaW4gYWRkYWJsZSBjb21wb25lbnRzLCBhbmQgZXZlcnl3aGVyZSBpZiBmb3JtVmFsdWVzIG5vdCBzZXRcclxuICAgIHNldExheW91dERlZmF1bHRzOiAnYXV0bycsIC8vIFNldCBmZWZhdWx0IHZhbHVlcyBmcm9tIGxheW91dD9cclxuICAgIC8vIHRydWUgPSBhbHdheXMgc2V0ICh1bmxlc3Mgb3ZlcnJpZGRlbiBieSBmb3JtVmFsdWVzKVxyXG4gICAgLy8gZmFsc2UgPSBuZXZlciBzZXRcclxuICAgIC8vICdhdXRvJyA9IHNldCBpbiBhZGRhYmxlIGNvbXBvbmVudHMsIGFuZCBldmVyeXdoZXJlIGlmIGZvcm1WYWx1ZXMgbm90IHNldFxyXG4gICAgdmFsaWRhdGVPblJlbmRlcjogJ2F1dG8nLCAvLyBWYWxpZGF0ZSBmaWVsZHMgaW1tZWRpYXRlbHksIGJlZm9yZSB0aGV5IGFyZSB0b3VjaGVkP1xyXG4gICAgLy8gdHJ1ZSA9IHZhbGlkYXRlIGFsbCBmaWVsZHMgaW1tZWRpYXRlbHlcclxuICAgIC8vIGZhbHNlID0gb25seSB2YWxpZGF0ZSBmaWVsZHMgYWZ0ZXIgdGhleSBhcmUgdG91Y2hlZCBieSB1c2VyXHJcbiAgICAvLyAnYXV0bycgPSB2YWxpZGF0ZSBmaWVsZHMgd2l0aCB2YWx1ZXMgaW1tZWRpYXRlbHksIGVtcHR5IGZpZWxkcyBhZnRlciB0aGV5IGFyZSB0b3VjaGVkXHJcbiAgICB3aWRnZXRzOiB7fSwgLy8gQW55IGN1c3RvbSB3aWRnZXRzIHRvIGxvYWRcclxuICAgIGRlZmF1bHRXaWRnZXRPcHRpb25zOiB7XHJcbiAgICAgIC8vIERlZmF1bHQgb3B0aW9ucyBmb3IgZm9ybSBjb250cm9sIHdpZGdldHNcclxuICAgICAgbGlzdEl0ZW1zOiAxLCAvLyBOdW1iZXIgb2YgbGlzdCBpdGVtcyB0byBpbml0aWFsbHkgYWRkIHRvIGFycmF5cyB3aXRoIG5vIGRlZmF1bHQgdmFsdWVcclxuICAgICAgYWRkYWJsZTogdHJ1ZSwgLy8gQWxsb3cgYWRkaW5nIGl0ZW1zIHRvIGFuIGFycmF5IG9yICRyZWYgcG9pbnQ/XHJcbiAgICAgIG9yZGVyYWJsZTogdHJ1ZSwgLy8gQWxsb3cgcmVvcmRlcmluZyBpdGVtcyB3aXRoaW4gYW4gYXJyYXk/XHJcbiAgICAgIHJlbW92YWJsZTogdHJ1ZSwgLy8gQWxsb3cgcmVtb3ZpbmcgaXRlbXMgZnJvbSBhbiBhcnJheSBvciAkcmVmIHBvaW50P1xyXG4gICAgICBlbmFibGVFcnJvclN0YXRlOiB0cnVlLCAvLyBBcHBseSAnaGFzLWVycm9yJyBjbGFzcyB3aGVuIGZpZWxkIGZhaWxzIHZhbGlkYXRpb24/XHJcbiAgICAgIC8vIGRpc2FibGVFcnJvclN0YXRlOiBmYWxzZSwgLy8gRG9uJ3QgYXBwbHkgJ2hhcy1lcnJvcicgY2xhc3Mgd2hlbiBmaWVsZCBmYWlscyB2YWxpZGF0aW9uP1xyXG4gICAgICBlbmFibGVTdWNjZXNzU3RhdGU6IHRydWUsIC8vIEFwcGx5ICdoYXMtc3VjY2VzcycgY2xhc3Mgd2hlbiBmaWVsZCB2YWxpZGF0ZXM/XHJcbiAgICAgIC8vIGRpc2FibGVTdWNjZXNzU3RhdGU6IGZhbHNlLCAvLyBEb24ndCBhcHBseSAnaGFzLXN1Y2Nlc3MnIGNsYXNzIHdoZW4gZmllbGQgdmFsaWRhdGVzP1xyXG4gICAgICBmZWVkYmFjazogZmFsc2UsIC8vIFNob3cgaW5saW5lIGZlZWRiYWNrIGljb25zP1xyXG4gICAgICBmZWVkYmFja09uUmVuZGVyOiBmYWxzZSwgLy8gU2hvdyBlcnJvck1lc3NhZ2Ugb24gUmVuZGVyP1xyXG4gICAgICBub3RpdGxlOiBmYWxzZSwgLy8gSGlkZSB0aXRsZT9cclxuICAgICAgZGlzYWJsZWQ6IGZhbHNlLCAvLyBTZXQgY29udHJvbCBhcyBkaXNhYmxlZD8gKG5vdCBlZGl0YWJsZSwgYW5kIGV4Y2x1ZGVkIGZyb20gb3V0cHV0KVxyXG4gICAgICByZWFkb25seTogZmFsc2UsIC8vIFNldCBjb250cm9sIGFzIHJlYWQgb25seT8gKG5vdCBlZGl0YWJsZSwgYnV0IGluY2x1ZGVkIGluIG91dHB1dClcclxuICAgICAgcmV0dXJuRW1wdHlGaWVsZHM6IHRydWUsIC8vIHJldHVybiB2YWx1ZXMgZm9yIGZpZWxkcyB0aGF0IGNvbnRhaW4gbm8gZGF0YT9cclxuICAgICAgdmFsaWRhdGlvbk1lc3NhZ2VzOiB7fSAvLyBzZXQgYnkgc2V0TGFuZ3VhZ2UoKVxyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIGZjVmFsdWVDaGFuZ2VzU3ViczpTdWJzY3JpcHRpb247XHJcbiAgZmNTdGF0dXNDaGFuZ2VzU3ViczpTdWJzY3JpcHRpb247XHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICB0aGlzLnNldExhbmd1YWdlKHRoaXMubGFuZ3VhZ2UpO1xyXG4gICAgdGhpcy5hanYuYWRkTWV0YVNjaGVtYShqc29uRHJhZnQ2KTtcclxuICAgIHRoaXMuYWp2LmFkZE1ldGFTY2hlbWEoanNvbkRyYWZ0Nyk7XHJcbiAgfVxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5mY1ZhbHVlQ2hhbmdlc1N1YnM/LnVuc3Vic2NyaWJlKCk7XHJcbiAgICB0aGlzLmZjU3RhdHVzQ2hhbmdlc1N1YnM/LnVuc3Vic2NyaWJlKCk7XHJcbiAgICB0aGlzLmZvcm1WYWx1ZVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcclxuICAgIHRoaXMuZmNWYWx1ZUNoYW5nZXNTdWJzPW51bGw7XHJcbiAgICB0aGlzLmZjU3RhdHVzQ2hhbmdlc1N1YnM9bnVsbDtcclxuICAgIHRoaXMuZm9ybVZhbHVlU3Vic2NyaXB0aW9uPW51bGw7XHJcblxyXG4gIH1cclxuXHJcbiAgc2V0TGFuZ3VhZ2UobGFuZ3VhZ2U6IHN0cmluZyA9ICdlbi1VUycpIHtcclxuICAgIHRoaXMubGFuZ3VhZ2UgPSBsYW5ndWFnZTtcclxuICAgIGNvbnN0IGxhbmd1YWdlVmFsaWRhdGlvbk1lc3NhZ2VzID0ge1xyXG4gICAgICBkZTogZGVWYWxpZGF0aW9uTWVzc2FnZXMsXHJcbiAgICAgIGVuOiBlblZhbGlkYXRpb25NZXNzYWdlcyxcclxuICAgICAgZXM6IGVzVmFsaWRhdGlvbk1lc3NhZ2VzLFxyXG4gICAgICBmcjogZnJWYWxpZGF0aW9uTWVzc2FnZXMsXHJcbiAgICAgIGl0OiBpdFZhbGlkYXRpb25NZXNzYWdlcyxcclxuICAgICAgcHQ6IHB0VmFsaWRhdGlvbk1lc3NhZ2VzLFxyXG4gICAgICB6aDogemhWYWxpZGF0aW9uTWVzc2FnZXMsXHJcbiAgICB9O1xyXG4gICAgY29uc3QgbGFuZ3VhZ2VDb2RlID0gbGFuZ3VhZ2Uuc2xpY2UoMCwgMik7XHJcblxyXG4gICAgY29uc3QgdmFsaWRhdGlvbk1lc3NhZ2VzID0gbGFuZ3VhZ2VWYWxpZGF0aW9uTWVzc2FnZXNbbGFuZ3VhZ2VDb2RlXTtcclxuXHJcbiAgICB0aGlzLmRlZmF1bHRGb3JtT3B0aW9ucy5kZWZhdWx0V2lkZ2V0T3B0aW9ucy52YWxpZGF0aW9uTWVzc2FnZXMgPSBjbG9uZURlZXAoXHJcbiAgICAgIHZhbGlkYXRpb25NZXNzYWdlc1xyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIGdldERhdGEoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5kYXRhO1xyXG4gIH1cclxuXHJcbiAgZ2V0U2NoZW1hKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc2NoZW1hO1xyXG4gIH1cclxuXHJcbiAgZ2V0TGF5b3V0KCkge1xyXG4gICAgcmV0dXJuIHRoaXMubGF5b3V0O1xyXG4gIH1cclxuXHJcbiAgcmVzZXRBbGxWYWx1ZXMoKSB7XHJcbiAgICB0aGlzLkpzb25Gb3JtQ29tcGF0aWJpbGl0eSA9IGZhbHNlO1xyXG4gICAgdGhpcy5SZWFjdEpzb25TY2hlbWFGb3JtQ29tcGF0aWJpbGl0eSA9IGZhbHNlO1xyXG4gICAgdGhpcy5Bbmd1bGFyU2NoZW1hRm9ybUNvbXBhdGliaWxpdHkgPSBmYWxzZTtcclxuICAgIHRoaXMudHBsZGF0YSA9IHt9O1xyXG4gICAgdGhpcy52YWxpZGF0ZUZvcm1EYXRhID0gbnVsbDtcclxuICAgIHRoaXMuZm9ybVZhbHVlcyA9IHt9O1xyXG4gICAgdGhpcy5zY2hlbWEgPSB7fTtcclxuICAgIHRoaXMubGF5b3V0ID0gW107XHJcbiAgICB0aGlzLmZvcm1Hcm91cFRlbXBsYXRlID0ge307XHJcbiAgICB0aGlzLmZvcm1Hcm91cCA9IG51bGw7XHJcbiAgICB0aGlzLmZyYW1ld29yayA9IG51bGw7XHJcbiAgICB0aGlzLmRhdGEgPSB7fTtcclxuICAgIHRoaXMudmFsaWREYXRhID0gbnVsbDtcclxuICAgIHRoaXMuaXNWYWxpZCA9IG51bGw7XHJcbiAgICB0aGlzLnZhbGlkYXRpb25FcnJvcnMgPSBudWxsO1xyXG4gICAgdGhpcy5hcnJheU1hcCA9IG5ldyBNYXAoKTtcclxuICAgIHRoaXMuZGF0YU1hcCA9IG5ldyBNYXAoKTtcclxuICAgIHRoaXMuZGF0YVJlY3Vyc2l2ZVJlZk1hcCA9IG5ldyBNYXAoKTtcclxuICAgIHRoaXMuc2NoZW1hUmVjdXJzaXZlUmVmTWFwID0gbmV3IE1hcCgpO1xyXG4gICAgdGhpcy5sYXlvdXRSZWZMaWJyYXJ5ID0ge307XHJcbiAgICB0aGlzLnNjaGVtYVJlZkxpYnJhcnkgPSB7fTtcclxuICAgIHRoaXMudGVtcGxhdGVSZWZMaWJyYXJ5ID0ge307XHJcbiAgICB0aGlzLmZvcm1PcHRpb25zID0gY2xvbmVEZWVwKHRoaXMuZGVmYXVsdEZvcm1PcHRpb25zKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqICdidWlsZFJlbW90ZUVycm9yJyBmdW5jdGlvblxyXG4gICAqXHJcbiAgICogRXhhbXBsZSBlcnJvcnM6XHJcbiAgICoge1xyXG4gICAqICAgbGFzdF9uYW1lOiBbIHtcclxuICAgKiAgICAgbWVzc2FnZTogJ0xhc3QgbmFtZSBtdXN0IGJ5IHN0YXJ0IHdpdGggY2FwaXRhbCBsZXR0ZXIuJyxcclxuICAgKiAgICAgY29kZTogJ2NhcGl0YWxfbGV0dGVyJ1xyXG4gICAqICAgfSBdLFxyXG4gICAqICAgZW1haWw6IFsge1xyXG4gICAqICAgICBtZXNzYWdlOiAnRW1haWwgbXVzdCBiZSBmcm9tIGV4YW1wbGUuY29tIGRvbWFpbi4nLFxyXG4gICAqICAgICBjb2RlOiAnc3BlY2lhbF9kb21haW4nXHJcbiAgICogICB9LCB7XHJcbiAgICogICAgIG1lc3NhZ2U6ICdFbWFpbCBtdXN0IGNvbnRhaW4gYW4gQCBzeW1ib2wuJyxcclxuICAgKiAgICAgY29kZTogJ2F0X3N5bWJvbCdcclxuICAgKiAgIH0gXVxyXG4gICAqIH1cclxuICAgKiAvL3tFcnJvck1lc3NhZ2VzfSBlcnJvcnNcclxuICAgKi9cclxuICBidWlsZFJlbW90ZUVycm9yKGVycm9yczogRXJyb3JNZXNzYWdlcykge1xyXG4gICAgZm9yRWFjaChlcnJvcnMsICh2YWx1ZSwga2V5KSA9PiB7XHJcbiAgICAgIGlmIChrZXkgaW4gdGhpcy5mb3JtR3JvdXAuY29udHJvbHMpIHtcclxuICAgICAgICBmb3IgKGNvbnN0IGVycm9yIG9mIHZhbHVlKSB7XHJcbiAgICAgICAgICBjb25zdCBlcnIgPSB7fTtcclxuICAgICAgICAgIGVycltlcnJvclsnY29kZSddXSA9IGVycm9yWydtZXNzYWdlJ107XHJcbiAgICAgICAgICB0aGlzLmZvcm1Hcm91cC5nZXQoa2V5KS5zZXRFcnJvcnMoZXJyLCB7IGVtaXRFdmVudDogdHJ1ZSB9KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgdmFsaWRhdGVEYXRhKG5ld1ZhbHVlOiBhbnksIHVwZGF0ZVN1YnNjcmlwdGlvbnMgPSB0cnVlKTogdm9pZCB7XHJcbiAgICAvLyBGb3JtYXQgcmF3IGZvcm0gZGF0YSB0byBjb3JyZWN0IGRhdGEgdHlwZXNcclxuICAgIHRoaXMuZGF0YSA9IGZvcm1hdEZvcm1EYXRhKFxyXG4gICAgICBuZXdWYWx1ZSxcclxuICAgICAgdGhpcy5kYXRhTWFwLFxyXG4gICAgICB0aGlzLmRhdGFSZWN1cnNpdmVSZWZNYXAsXHJcbiAgICAgIHRoaXMuYXJyYXlNYXAsXHJcbiAgICAgIHRoaXMuZm9ybU9wdGlvbnMucmV0dXJuRW1wdHlGaWVsZHNcclxuICAgICk7XHJcbiAgICB0aGlzLmlzVmFsaWQgPSB0aGlzLnZhbGlkYXRlRm9ybURhdGEodGhpcy5kYXRhKTtcclxuICAgIHRoaXMudmFsaWREYXRhID0gdGhpcy5pc1ZhbGlkID8gdGhpcy5kYXRhIDogbnVsbDtcclxuICAgIGNvbnN0IGNvbXBpbGVFcnJvcnMgPSAoZXJyb3JzOkVycm9yT2JqZWN0W10pID0+IHtcclxuICAgICAgY29uc3QgY29tcGlsZWRFcnJvcnMgPSB7fTtcclxuICAgICAgKGVycm9ycyB8fCBbXSkuZm9yRWFjaChlcnJvciA9PiB7XHJcbiAgICAgICAgLy9UT0RPIHJldmlldy1zZWVtcyB0byBiZSBhIGNoYW5nZSBpbiBuZXdlciB2ZXJzaW9uc1xyXG4gICAgICAgIC8vb2YgYWp2IGdpdmluZyAnJyBhcyBpbnN0YW5jZVBhdGggZm9yIHJvb3Qgb2JqZWN0c1xyXG4gICAgICAgIGxldCBlcnJvclBhdGg9ZXJyb3IuaW5zdGFuY2VQYXRofHxcIlJPT1RcIjtcclxuICAgICAgICBpZiAoIWNvbXBpbGVkRXJyb3JzW2Vycm9yUGF0aF0pIHtcclxuICAgICAgICAgIGNvbXBpbGVkRXJyb3JzW2Vycm9yUGF0aF0gPSBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29tcGlsZWRFcnJvcnNbZXJyb3JQYXRoXS5wdXNoKGVycm9yLm1lc3NhZ2UpO1xyXG4gICAgICB9KTtcclxuICAgICAgcmV0dXJuIGNvbXBpbGVkRXJyb3JzO1xyXG4gICAgfTtcclxuICAgIHRoaXMuYWp2RXJyb3JzID0gdGhpcy52YWxpZGF0ZUZvcm1EYXRhLmVycm9ycztcclxuICAgIHRoaXMudmFsaWRhdGlvbkVycm9ycyA9IGNvbXBpbGVFcnJvcnModGhpcy52YWxpZGF0ZUZvcm1EYXRhLmVycm9ycyk7XHJcbiAgICBpZiAodXBkYXRlU3Vic2NyaXB0aW9ucykge1xyXG4gICAgICB0aGlzLmRhdGFDaGFuZ2VzLm5leHQodGhpcy5kYXRhKTtcclxuICAgICAgdGhpcy5pc1ZhbGlkQ2hhbmdlcy5uZXh0KHRoaXMuaXNWYWxpZCk7XHJcbiAgICAgIHRoaXMudmFsaWRhdGlvbkVycm9yQ2hhbmdlcy5uZXh0KHRoaXMuYWp2RXJyb3JzKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGJ1aWxkRm9ybUdyb3VwVGVtcGxhdGUoZm9ybVZhbHVlczogYW55ID0gbnVsbCwgc2V0VmFsdWVzID0gdHJ1ZSkge1xyXG4gICAgdGhpcy5mb3JtR3JvdXBUZW1wbGF0ZSA9IGJ1aWxkRm9ybUdyb3VwVGVtcGxhdGUoXHJcbiAgICAgIHRoaXMsXHJcbiAgICAgIGZvcm1WYWx1ZXMsXHJcbiAgICAgIHNldFZhbHVlc1xyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIGJ1aWxkRm9ybUdyb3VwKCkge1xyXG4gICAgdGhpcy5mb3JtR3JvdXAgPSA8VW50eXBlZEZvcm1Hcm91cD5idWlsZEZvcm1Hcm91cCh0aGlzLmZvcm1Hcm91cFRlbXBsYXRlKTtcclxuICAgIGlmICh0aGlzLmZvcm1Hcm91cCkge1xyXG4gICAgICB0aGlzLmNvbXBpbGVBanZTY2hlbWEoKTtcclxuICAgICAgdGhpcy52YWxpZGF0ZURhdGEodGhpcy5mb3JtR3JvdXAudmFsdWUpO1xyXG5cclxuICAgICAgLy8gU2V0IHVwIG9ic2VydmFibGVzIHRvIGVtaXQgZGF0YSBhbmQgdmFsaWRhdGlvbiBpbmZvIHdoZW4gZm9ybSBkYXRhIGNoYW5nZXNcclxuICAgICAgaWYgKHRoaXMuZm9ybVZhbHVlU3Vic2NyaXB0aW9uKSB7XHJcbiAgICAgICAgdGhpcy5mb3JtVmFsdWVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmZvcm1WYWx1ZVN1YnNjcmlwdGlvbiA9IHRoaXMuZm9ybUdyb3VwLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoXHJcbiAgICAgICAgZm9ybVZhbHVlID0+IHRoaXMudmFsaWRhdGVEYXRhKGZvcm1WYWx1ZSlcclxuICAgICAgKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGJ1aWxkTGF5b3V0KHdpZGdldExpYnJhcnk6IGFueSkge1xyXG4gICAgdGhpcy5sYXlvdXQgPSBidWlsZExheW91dCh0aGlzLCB3aWRnZXRMaWJyYXJ5KTtcclxuICB9XHJcblxyXG4gIHNldE9wdGlvbnMobmV3T3B0aW9uczogYW55KSB7XHJcbiAgICBpZiAoaXNPYmplY3QobmV3T3B0aW9ucykpIHtcclxuICAgICAgY29uc3QgYWRkT3B0aW9ucyA9IGNsb25lRGVlcChuZXdPcHRpb25zKTtcclxuICAgICAgLy8gQmFja3dhcmQgY29tcGF0aWJpbGl0eSBmb3IgJ2RlZmF1bHRPcHRpb25zJyAocmVuYW1lZCAnZGVmYXVsdFdpZGdldE9wdGlvbnMnKVxyXG4gICAgICBpZiAoaXNPYmplY3QoYWRkT3B0aW9ucy5kZWZhdWx0T3B0aW9ucykpIHtcclxuICAgICAgICBPYmplY3QuYXNzaWduKFxyXG4gICAgICAgICAgdGhpcy5mb3JtT3B0aW9ucy5kZWZhdWx0V2lkZ2V0T3B0aW9ucyxcclxuICAgICAgICAgIGFkZE9wdGlvbnMuZGVmYXVsdE9wdGlvbnNcclxuICAgICAgICApO1xyXG4gICAgICAgIGRlbGV0ZSBhZGRPcHRpb25zLmRlZmF1bHRPcHRpb25zO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChpc09iamVjdChhZGRPcHRpb25zLmRlZmF1bHRXaWRnZXRPcHRpb25zKSkge1xyXG4gICAgICAgIE9iamVjdC5hc3NpZ24oXHJcbiAgICAgICAgICB0aGlzLmZvcm1PcHRpb25zLmRlZmF1bHRXaWRnZXRPcHRpb25zLFxyXG4gICAgICAgICAgYWRkT3B0aW9ucy5kZWZhdWx0V2lkZ2V0T3B0aW9uc1xyXG4gICAgICAgICk7XHJcbiAgICAgICAgZGVsZXRlIGFkZE9wdGlvbnMuZGVmYXVsdFdpZGdldE9wdGlvbnM7XHJcbiAgICAgIH1cclxuICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLmZvcm1PcHRpb25zLCBhZGRPcHRpb25zKTtcclxuXHJcbiAgICAgIC8vIGNvbnZlcnQgZGlzYWJsZUVycm9yU3RhdGUgLyBkaXNhYmxlU3VjY2Vzc1N0YXRlIHRvIGVuYWJsZS4uLlxyXG4gICAgICBjb25zdCBnbG9iYWxEZWZhdWx0cyA9IHRoaXMuZm9ybU9wdGlvbnMuZGVmYXVsdFdpZGdldE9wdGlvbnM7XHJcbiAgICAgIFsnRXJyb3JTdGF0ZScsICdTdWNjZXNzU3RhdGUnXVxyXG4gICAgICAgIC5maWx0ZXIoc3VmZml4ID0+IGhhc093bihnbG9iYWxEZWZhdWx0cywgJ2Rpc2FibGUnICsgc3VmZml4KSlcclxuICAgICAgICAuZm9yRWFjaChzdWZmaXggPT4ge1xyXG4gICAgICAgICAgZ2xvYmFsRGVmYXVsdHNbJ2VuYWJsZScgKyBzdWZmaXhdID0gIWdsb2JhbERlZmF1bHRzW1xyXG4gICAgICAgICAgICAnZGlzYWJsZScgKyBzdWZmaXhcclxuICAgICAgICAgIF07XHJcbiAgICAgICAgICBkZWxldGUgZ2xvYmFsRGVmYXVsdHNbJ2Rpc2FibGUnICsgc3VmZml4XTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNvbXBpbGVBanZTY2hlbWEoKSB7XHJcbiAgICBpZiAoIXRoaXMudmFsaWRhdGVGb3JtRGF0YSkge1xyXG4gICAgICAvLyBpZiAndWk6b3JkZXInIGV4aXN0cyBpbiBwcm9wZXJ0aWVzLCBtb3ZlIGl0IHRvIHJvb3QgYmVmb3JlIGNvbXBpbGluZyB3aXRoIGFqdlxyXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnNjaGVtYS5wcm9wZXJ0aWVzWyd1aTpvcmRlciddKSkge1xyXG4gICAgICAgIHRoaXMuc2NoZW1hWyd1aTpvcmRlciddID0gdGhpcy5zY2hlbWEucHJvcGVydGllc1sndWk6b3JkZXInXTtcclxuICAgICAgICBkZWxldGUgdGhpcy5zY2hlbWEucHJvcGVydGllc1sndWk6b3JkZXInXTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmFqdi5yZW1vdmVTY2hlbWEodGhpcy5zY2hlbWEpO1xyXG4gICAgICB0aGlzLnZhbGlkYXRlRm9ybURhdGEgPSB0aGlzLmFqdi5jb21waWxlKHRoaXMuc2NoZW1hKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGJ1aWxkU2NoZW1hRnJvbURhdGEoZGF0YT86IGFueSwgcmVxdWlyZUFsbEZpZWxkcyA9IGZhbHNlKTogYW55IHtcclxuICAgIGlmIChkYXRhKSB7XHJcbiAgICAgIHJldHVybiBidWlsZFNjaGVtYUZyb21EYXRhKGRhdGEsIHJlcXVpcmVBbGxGaWVsZHMpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5zY2hlbWEgPSBidWlsZFNjaGVtYUZyb21EYXRhKHRoaXMuZm9ybVZhbHVlcywgcmVxdWlyZUFsbEZpZWxkcyk7XHJcbiAgfVxyXG5cclxuICBidWlsZFNjaGVtYUZyb21MYXlvdXQobGF5b3V0PzogYW55KTogYW55IHtcclxuICAgIGlmIChsYXlvdXQpIHtcclxuICAgICAgcmV0dXJuIGJ1aWxkU2NoZW1hRnJvbUxheW91dChsYXlvdXQpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5zY2hlbWEgPSBidWlsZFNjaGVtYUZyb21MYXlvdXQodGhpcy5sYXlvdXQpO1xyXG4gIH1cclxuXHJcbiAgc2V0VHBsZGF0YShuZXdUcGxkYXRhOiBhbnkgPSB7fSk6IHZvaWQge1xyXG4gICAgdGhpcy50cGxkYXRhID0gbmV3VHBsZGF0YTtcclxuICB9XHJcblxyXG4gIHBhcnNlVGV4dChcclxuICAgIHRleHQgPSAnJyxcclxuICAgIHZhbHVlOiBhbnkgPSB7fSxcclxuICAgIHZhbHVlczogYW55ID0ge30sXHJcbiAgICBrZXk6IG51bWJlciB8IHN0cmluZyA9IG51bGxcclxuICApOiBzdHJpbmcge1xyXG4gICAgaWYgKCF0ZXh0IHx8ICEve3suKz99fS8udGVzdCh0ZXh0KSkge1xyXG4gICAgICByZXR1cm4gdGV4dDtcclxuICAgIH1cclxuICAgIHJldHVybiB0ZXh0LnJlcGxhY2UoL3t7KC4rPyl9fS9nLCAoLi4uYSkgPT5cclxuICAgICAgdGhpcy5wYXJzZUV4cHJlc3Npb24oYVsxXSwgdmFsdWUsIHZhbHVlcywga2V5LCB0aGlzLnRwbGRhdGEpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcGFyc2VFeHByZXNzaW9uKFxyXG4gICAgZXhwcmVzc2lvbiA9ICcnLFxyXG4gICAgdmFsdWU6IGFueSA9IHt9LFxyXG4gICAgdmFsdWVzOiBhbnkgPSB7fSxcclxuICAgIGtleTogbnVtYmVyIHwgc3RyaW5nID0gbnVsbCxcclxuICAgIHRwbGRhdGE6IGFueSA9IG51bGxcclxuICApIHtcclxuICAgIGlmICh0eXBlb2YgZXhwcmVzc2lvbiAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgcmV0dXJuICcnO1xyXG4gICAgfVxyXG4gICAgY29uc3QgaW5kZXggPSB0eXBlb2Yga2V5ID09PSAnbnVtYmVyJyA/IGtleSArIDEgKyAnJyA6IGtleSB8fCAnJztcclxuICAgIGV4cHJlc3Npb24gPSBleHByZXNzaW9uLnRyaW0oKTtcclxuICAgIGlmIChcclxuICAgICAgKGV4cHJlc3Npb25bMF0gPT09IFwiJ1wiIHx8IGV4cHJlc3Npb25bMF0gPT09ICdcIicpICYmXHJcbiAgICAgIGV4cHJlc3Npb25bMF0gPT09IGV4cHJlc3Npb25bZXhwcmVzc2lvbi5sZW5ndGggLSAxXSAmJlxyXG4gICAgICBleHByZXNzaW9uLnNsaWNlKDEsIGV4cHJlc3Npb24ubGVuZ3RoIC0gMSkuaW5kZXhPZihleHByZXNzaW9uWzBdKSA9PT0gLTFcclxuICAgICkge1xyXG4gICAgICByZXR1cm4gZXhwcmVzc2lvbi5zbGljZSgxLCBleHByZXNzaW9uLmxlbmd0aCAtIDEpO1xyXG4gICAgfVxyXG4gICAgaWYgKGV4cHJlc3Npb24gPT09ICdpZHgnIHx8IGV4cHJlc3Npb24gPT09ICckaW5kZXgnKSB7XHJcbiAgICAgIHJldHVybiBpbmRleDtcclxuICAgIH1cclxuICAgIGlmIChleHByZXNzaW9uID09PSAndmFsdWUnICYmICFoYXNPd24odmFsdWVzLCAndmFsdWUnKSkge1xyXG4gICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9XHJcbiAgICBpZiAoXHJcbiAgICAgIFsnXCInLCBcIidcIiwgJyAnLCAnfHwnLCAnJiYnLCAnKyddLmV2ZXJ5KFxyXG4gICAgICAgIGRlbGltID0+IGV4cHJlc3Npb24uaW5kZXhPZihkZWxpbSkgPT09IC0xXHJcbiAgICAgIClcclxuICAgICkge1xyXG4gICAgICBjb25zdCBwb2ludGVyID0gSnNvblBvaW50ZXIucGFyc2VPYmplY3RQYXRoKGV4cHJlc3Npb24pO1xyXG4gICAgICByZXR1cm4gcG9pbnRlclswXSA9PT0gJ3ZhbHVlJyAmJiBKc29uUG9pbnRlci5oYXModmFsdWUsIHBvaW50ZXIuc2xpY2UoMSkpXHJcbiAgICAgICAgPyBKc29uUG9pbnRlci5nZXQodmFsdWUsIHBvaW50ZXIuc2xpY2UoMSkpXHJcbiAgICAgICAgOiBwb2ludGVyWzBdID09PSAndmFsdWVzJyAmJiBKc29uUG9pbnRlci5oYXModmFsdWVzLCBwb2ludGVyLnNsaWNlKDEpKVxyXG4gICAgICAgICAgPyBKc29uUG9pbnRlci5nZXQodmFsdWVzLCBwb2ludGVyLnNsaWNlKDEpKVxyXG4gICAgICAgICAgOiBwb2ludGVyWzBdID09PSAndHBsZGF0YScgJiYgSnNvblBvaW50ZXIuaGFzKHRwbGRhdGEsIHBvaW50ZXIuc2xpY2UoMSkpXHJcbiAgICAgICAgICAgID8gSnNvblBvaW50ZXIuZ2V0KHRwbGRhdGEsIHBvaW50ZXIuc2xpY2UoMSkpXHJcbiAgICAgICAgICAgIDogSnNvblBvaW50ZXIuaGFzKHZhbHVlcywgcG9pbnRlcilcclxuICAgICAgICAgICAgICA/IEpzb25Qb2ludGVyLmdldCh2YWx1ZXMsIHBvaW50ZXIpXHJcbiAgICAgICAgICAgICAgOiAnJztcclxuICAgIH1cclxuICAgIGlmIChleHByZXNzaW9uLmluZGV4T2YoJ1tpZHhdJykgPiAtMSkge1xyXG4gICAgICBleHByZXNzaW9uID0gZXhwcmVzc2lvbi5yZXBsYWNlKC9cXFtpZHhcXF0vZywgPHN0cmluZz5pbmRleCk7XHJcbiAgICB9XHJcbiAgICBpZiAoZXhwcmVzc2lvbi5pbmRleE9mKCdbJGluZGV4XScpID4gLTEpIHtcclxuICAgICAgZXhwcmVzc2lvbiA9IGV4cHJlc3Npb24ucmVwbGFjZSgvXFxbJGluZGV4XFxdL2csIDxzdHJpbmc+aW5kZXgpO1xyXG4gICAgfVxyXG4gICAgLy8gVE9ETzogSW1wcm92ZSBleHByZXNzaW9uIGV2YWx1YXRpb24gYnkgcGFyc2luZyBxdW90ZWQgc3RyaW5ncyBmaXJzdFxyXG4gICAgLy8gbGV0IGV4cHJlc3Npb25BcnJheSA9IGV4cHJlc3Npb24ubWF0Y2goLyhbXlwiJ10rfFwiW15cIl0rXCJ8J1teJ10rJykvZyk7XHJcbiAgICBpZiAoZXhwcmVzc2lvbi5pbmRleE9mKCd8fCcpID4gLTEpIHtcclxuICAgICAgcmV0dXJuIGV4cHJlc3Npb25cclxuICAgICAgICAuc3BsaXQoJ3x8JylcclxuICAgICAgICAucmVkdWNlKFxyXG4gICAgICAgICAgKGFsbCwgdGVybSkgPT5cclxuICAgICAgICAgICAgYWxsIHx8IHRoaXMucGFyc2VFeHByZXNzaW9uKHRlcm0sIHZhbHVlLCB2YWx1ZXMsIGtleSwgdHBsZGF0YSksXHJcbiAgICAgICAgICAnJ1xyXG4gICAgICAgICk7XHJcbiAgICB9XHJcbiAgICBpZiAoZXhwcmVzc2lvbi5pbmRleE9mKCcmJicpID4gLTEpIHtcclxuICAgICAgcmV0dXJuIGV4cHJlc3Npb25cclxuICAgICAgICAuc3BsaXQoJyYmJylcclxuICAgICAgICAucmVkdWNlKFxyXG4gICAgICAgICAgKGFsbCwgdGVybSkgPT5cclxuICAgICAgICAgICAgYWxsICYmIHRoaXMucGFyc2VFeHByZXNzaW9uKHRlcm0sIHZhbHVlLCB2YWx1ZXMsIGtleSwgdHBsZGF0YSksXHJcbiAgICAgICAgICAnICdcclxuICAgICAgICApXHJcbiAgICAgICAgLnRyaW0oKTtcclxuICAgIH1cclxuICAgIGlmIChleHByZXNzaW9uLmluZGV4T2YoJysnKSA+IC0xKSB7XHJcbiAgICAgIHJldHVybiBleHByZXNzaW9uXHJcbiAgICAgICAgLnNwbGl0KCcrJylcclxuICAgICAgICAubWFwKHRlcm0gPT4gdGhpcy5wYXJzZUV4cHJlc3Npb24odGVybSwgdmFsdWUsIHZhbHVlcywga2V5LCB0cGxkYXRhKSlcclxuICAgICAgICAuam9pbignJyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gJyc7XHJcbiAgfVxyXG5cclxuICBzZXRBcnJheUl0ZW1UaXRsZShcclxuICAgIHBhcmVudEN0eDogYW55ID0ge30sXHJcbiAgICBjaGlsZE5vZGU6IGFueSA9IG51bGwsXHJcbiAgICBpbmRleDogbnVtYmVyID0gbnVsbFxyXG4gICk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBwYXJlbnROb2RlID0gcGFyZW50Q3R4LmxheW91dE5vZGU7XHJcbiAgICBjb25zdCBwYXJlbnRWYWx1ZXM6IGFueSA9IHRoaXMuZ2V0Rm9ybUNvbnRyb2xWYWx1ZShwYXJlbnRDdHgpO1xyXG4gICAgY29uc3QgaXNBcnJheUl0ZW0gPVxyXG4gICAgICAocGFyZW50Tm9kZS50eXBlIHx8ICcnKS5zbGljZSgtNSkgPT09ICdhcnJheScgJiYgaXNBcnJheShwYXJlbnRWYWx1ZXMpO1xyXG4gICAgY29uc3QgdGV4dCA9IEpzb25Qb2ludGVyLmdldEZpcnN0KFxyXG4gICAgICBpc0FycmF5SXRlbSAmJiBjaGlsZE5vZGUudHlwZSAhPT0gJyRyZWYnXHJcbiAgICAgICAgPyBbXHJcbiAgICAgICAgICBbY2hpbGROb2RlLCAnL29wdGlvbnMvbGVnZW5kJ10sXHJcbiAgICAgICAgICBbY2hpbGROb2RlLCAnL29wdGlvbnMvdGl0bGUnXSxcclxuICAgICAgICAgIFtwYXJlbnROb2RlLCAnL29wdGlvbnMvdGl0bGUnXSxcclxuICAgICAgICAgIFtwYXJlbnROb2RlLCAnL29wdGlvbnMvbGVnZW5kJ11cclxuICAgICAgICBdXHJcbiAgICAgICAgOiBbXHJcbiAgICAgICAgICBbY2hpbGROb2RlLCAnL29wdGlvbnMvdGl0bGUnXSxcclxuICAgICAgICAgIFtjaGlsZE5vZGUsICcvb3B0aW9ucy9sZWdlbmQnXSxcclxuICAgICAgICAgIFtwYXJlbnROb2RlLCAnL29wdGlvbnMvdGl0bGUnXSxcclxuICAgICAgICAgIFtwYXJlbnROb2RlLCAnL29wdGlvbnMvbGVnZW5kJ11cclxuICAgICAgICBdXHJcbiAgICApO1xyXG4gICAgaWYgKCF0ZXh0KSB7XHJcbiAgICAgIHJldHVybiB0ZXh0O1xyXG4gICAgfVxyXG4gICAgY29uc3QgY2hpbGRWYWx1ZSA9XHJcbiAgICAgIGlzQXJyYXkocGFyZW50VmFsdWVzKSAmJiBpbmRleCA8IHBhcmVudFZhbHVlcy5sZW5ndGhcclxuICAgICAgICA/IHBhcmVudFZhbHVlc1tpbmRleF1cclxuICAgICAgICA6IHBhcmVudFZhbHVlcztcclxuICAgIHJldHVybiB0aGlzLnBhcnNlVGV4dCh0ZXh0LCBjaGlsZFZhbHVlLCBwYXJlbnRWYWx1ZXMsIGluZGV4KTtcclxuICB9XHJcblxyXG4gIHNldEl0ZW1UaXRsZShjdHg6IGFueSkge1xyXG4gICAgcmV0dXJuICFjdHgub3B0aW9ucy50aXRsZSAmJiAvXihcXGQrfC0pJC8udGVzdChjdHgubGF5b3V0Tm9kZS5uYW1lKVxyXG4gICAgICA/IG51bGxcclxuICAgICAgOiB0aGlzLnBhcnNlVGV4dChcclxuICAgICAgICBjdHgub3B0aW9ucy50aXRsZSB8fCB0b1RpdGxlQ2FzZShjdHgubGF5b3V0Tm9kZS5uYW1lKSxcclxuICAgICAgICB0aGlzLmdldEZvcm1Db250cm9sVmFsdWUodGhpcyksXHJcbiAgICAgICAgKHRoaXMuZ2V0Rm9ybUNvbnRyb2xHcm91cCh0aGlzKSB8fCA8YW55Pnt9KS52YWx1ZSxcclxuICAgICAgICBjdHguZGF0YUluZGV4W2N0eC5kYXRhSW5kZXgubGVuZ3RoIC0gMV1cclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIGV2YWx1YXRlQ29uZGl0aW9uKGxheW91dE5vZGU6IGFueSwgZGF0YUluZGV4OiBudW1iZXJbXSk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgYXJyYXlJbmRleCA9IGRhdGFJbmRleCAmJiBkYXRhSW5kZXhbZGF0YUluZGV4Lmxlbmd0aCAtIDFdO1xyXG4gICAgbGV0IHJlc3VsdCA9IHRydWU7XHJcbiAgICBpZiAoaGFzVmFsdWUoKGxheW91dE5vZGUub3B0aW9ucyB8fCB7fSkuY29uZGl0aW9uKSkge1xyXG4gICAgICBpZiAodHlwZW9mIGxheW91dE5vZGUub3B0aW9ucy5jb25kaXRpb24gPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgbGV0IHBvaW50ZXIgPSBsYXlvdXROb2RlLm9wdGlvbnMuY29uZGl0aW9uO1xyXG4gICAgICAgIGlmIChoYXNWYWx1ZShhcnJheUluZGV4KSkge1xyXG4gICAgICAgICAgcG9pbnRlciA9IHBvaW50ZXIucmVwbGFjZSgnW2FycmF5SW5kZXhdJywgYFske2FycmF5SW5kZXh9XWApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwb2ludGVyID0gSnNvblBvaW50ZXIucGFyc2VPYmplY3RQYXRoKHBvaW50ZXIpO1xyXG4gICAgICAgIHJlc3VsdCA9ICEhSnNvblBvaW50ZXIuZ2V0KHRoaXMuZGF0YSwgcG9pbnRlcik7XHJcbiAgICAgICAgaWYgKCFyZXN1bHQgJiYgcG9pbnRlclswXSA9PT0gJ21vZGVsJykge1xyXG4gICAgICAgICAgcmVzdWx0ID0gISFKc29uUG9pbnRlci5nZXQoeyBtb2RlbDogdGhpcy5kYXRhIH0sIHBvaW50ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGF5b3V0Tm9kZS5vcHRpb25zLmNvbmRpdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgIHJlc3VsdCA9IGxheW91dE5vZGUub3B0aW9ucy5jb25kaXRpb24odGhpcy5kYXRhKTtcclxuICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICB0eXBlb2YgbGF5b3V0Tm9kZS5vcHRpb25zLmNvbmRpdGlvbi5mdW5jdGlvbkJvZHkgPT09ICdzdHJpbmcnXHJcbiAgICAgICkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBjb25zdCBkeW5GbiA9IG5ldyBGdW5jdGlvbihcclxuICAgICAgICAgICAgJ21vZGVsJyxcclxuICAgICAgICAgICAgJ2FycmF5SW5kaWNlcycsXHJcbiAgICAgICAgICAgIGxheW91dE5vZGUub3B0aW9ucy5jb25kaXRpb24uZnVuY3Rpb25Cb2R5XHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmVzdWx0ID0gZHluRm4odGhpcy5kYXRhLCBkYXRhSW5kZXgpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgIHJlc3VsdCA9IHRydWU7XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFxyXG4gICAgICAgICAgICAnY29uZGl0aW9uIGZ1bmN0aW9uQm9keSBlcnJvcmVkIG91dCBvbiBldmFsdWF0aW9uOiAnICtcclxuICAgICAgICAgICAgbGF5b3V0Tm9kZS5vcHRpb25zLmNvbmRpdGlvbi5mdW5jdGlvbkJvZHlcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxuXHJcbiAgaW5pdGlhbGl6ZUNvbnRyb2woY3R4OiBhbnksIGJpbmQgPSB0cnVlKTogYm9vbGVhbiB7XHJcbiAgICBpZiAoIWlzT2JqZWN0KGN0eCkpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgaWYgKGlzRW1wdHkoY3R4Lm9wdGlvbnMpKSB7XHJcbiAgICAgIGN0eC5vcHRpb25zID0gIWlzRW1wdHkoKGN0eC5sYXlvdXROb2RlIHx8IHt9KS5vcHRpb25zKVxyXG4gICAgICAgID8gY3R4LmxheW91dE5vZGUub3B0aW9uc1xyXG4gICAgICAgIDogY2xvbmVEZWVwKHRoaXMuZm9ybU9wdGlvbnMpO1xyXG4gICAgfVxyXG4gICAgY3R4LmZvcm1Db250cm9sID0gdGhpcy5nZXRGb3JtQ29udHJvbChjdHgpO1xyXG4gICAgY3R4LmJvdW5kQ29udHJvbCA9IGJpbmQgJiYgISFjdHguZm9ybUNvbnRyb2w7XHJcbiAgICBpZiAoY3R4LmZvcm1Db250cm9sKSB7XHJcbiAgICAgIGN0eC5jb250cm9sTmFtZSA9IHRoaXMuZ2V0Rm9ybUNvbnRyb2xOYW1lKGN0eCk7XHJcbiAgICAgIGN0eC5jb250cm9sVmFsdWUgPSBjdHguZm9ybUNvbnRyb2wudmFsdWU7XHJcbiAgICAgIGN0eC5jb250cm9sRGlzYWJsZWQgPSBjdHguZm9ybUNvbnRyb2wuZGlzYWJsZWQ7XHJcbiAgICAgIGN0eC5vcHRpb25zLmVycm9yTWVzc2FnZSA9XHJcbiAgICAgICAgY3R4LmZvcm1Db250cm9sLnN0YXR1cyA9PT0gJ1ZBTElEJ1xyXG4gICAgICAgICAgPyBudWxsXHJcbiAgICAgICAgICA6IHRoaXMuZm9ybWF0RXJyb3JzKFxyXG4gICAgICAgICAgICBjdHguZm9ybUNvbnRyb2wuZXJyb3JzLFxyXG4gICAgICAgICAgICBjdHgub3B0aW9ucy52YWxpZGF0aW9uTWVzc2FnZXNcclxuICAgICAgICAgICk7XHJcbiAgICAgIGN0eC5vcHRpb25zLnNob3dFcnJvcnMgPVxyXG4gICAgICAgIHRoaXMuZm9ybU9wdGlvbnMudmFsaWRhdGVPblJlbmRlciA9PT0gdHJ1ZSB8fFxyXG4gICAgICAgICh0aGlzLmZvcm1PcHRpb25zLnZhbGlkYXRlT25SZW5kZXIgPT09ICdhdXRvJyAmJlxyXG4gICAgICAgICAgaGFzVmFsdWUoY3R4LmNvbnRyb2xWYWx1ZSkpO1xyXG4gICAgICB0aGlzLmZjU3RhdHVzQ2hhbmdlc1N1YnM9Y3R4LmZvcm1Db250cm9sLnN0YXR1c0NoYW5nZXMuc3Vic2NyaWJlKFxyXG4gICAgICAgIHN0YXR1cyA9PlxyXG4gICAgICAgICAgKGN0eC5vcHRpb25zLmVycm9yTWVzc2FnZSA9XHJcbiAgICAgICAgICAgIHN0YXR1cyA9PT0gJ1ZBTElEJ1xyXG4gICAgICAgICAgICAgID8gbnVsbFxyXG4gICAgICAgICAgICAgIDogdGhpcy5mb3JtYXRFcnJvcnMoXHJcbiAgICAgICAgICAgICAgICBjdHguZm9ybUNvbnRyb2wuZXJyb3JzLFxyXG4gICAgICAgICAgICAgICAgY3R4Lm9wdGlvbnMudmFsaWRhdGlvbk1lc3NhZ2VzXHJcbiAgICAgICAgICAgICAgKSlcclxuICAgICAgKTtcclxuICAgICAgdGhpcy5mY1ZhbHVlQ2hhbmdlc1N1YnM9Y3R4LmZvcm1Db250cm9sLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUodmFsdWUgPT4ge1xyXG4gICAgICAgICAvL2NvbW1lbnRlZCBvdXQgdG8gcmV2ZXJ0IGJhY2sgdG8gcHJldmlvdXMgY29tbWl0c1xyXG4gICAgICAgICAvL2FzIHNlZW1zIHRvIGJlIGNhdXNpbmcgc29tZSBpc3N1ZXNcclxuICAgICAgICAgLypcclxuICAgICAgICBpZiAoISF2YWx1ZSkge1xyXG4gICAgICAgICAgY3R4LmNvbnRyb2xWYWx1ZSA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAqL1xyXG4gICAgICAgIC8vVE9ETy10ZXN0LHRoaXMgaXMgdGhlIG9yaWdpbmFsIGNvZGVcclxuICAgICAgICBpZiAoIV9pc0VxdWFsKGN0eC5jb250cm9sVmFsdWUsIHZhbHVlKSkgeyBjdHguY29udHJvbFZhbHVlID0gdmFsdWUgfVxyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGN0eC5jb250cm9sTmFtZSA9IGN0eC5sYXlvdXROb2RlLm5hbWU7XHJcbiAgICAgIGN0eC5jb250cm9sVmFsdWUgPSBjdHgubGF5b3V0Tm9kZS52YWx1ZSB8fCBudWxsO1xyXG4gICAgICBjb25zdCBkYXRhUG9pbnRlciA9IHRoaXMuZ2V0RGF0YVBvaW50ZXIoY3R4KTtcclxuICAgICAgaWYgKGJpbmQgJiYgZGF0YVBvaW50ZXIpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKFxyXG4gICAgICAgICAgYHdhcm5pbmc6IGNvbnRyb2wgXCIke2RhdGFQb2ludGVyfVwiIGlzIG5vdCBib3VuZCB0byB0aGUgQW5ndWxhciBGb3JtR3JvdXAuYFxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBjdHguYm91bmRDb250cm9sO1xyXG4gIH1cclxuXHJcbiAgZm9ybWF0RXJyb3JzKGVycm9yczogYW55LCB2YWxpZGF0aW9uTWVzc2FnZXM6IGFueSA9IHt9KTogc3RyaW5nIHtcclxuICAgIGlmIChpc0VtcHR5KGVycm9ycykpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICBpZiAoIWlzT2JqZWN0KHZhbGlkYXRpb25NZXNzYWdlcykpIHtcclxuICAgICAgdmFsaWRhdGlvbk1lc3NhZ2VzID0ge307XHJcbiAgICB9XHJcbiAgICBjb25zdCBhZGRTcGFjZXMgPSBzdHJpbmcgPT5cclxuICAgICAgc3RyaW5nWzBdLnRvVXBwZXJDYXNlKCkgK1xyXG4gICAgICAoc3RyaW5nLnNsaWNlKDEpIHx8ICcnKVxyXG4gICAgICAgIC5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCAnJDEgJDInKVxyXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcgJyk7XHJcbiAgICBjb25zdCBmb3JtYXRFcnJvciA9IGVycm9yID0+XHJcbiAgICAgIHR5cGVvZiBlcnJvciA9PT0gJ29iamVjdCdcclxuICAgICAgICA/IE9iamVjdC5rZXlzKGVycm9yKVxyXG4gICAgICAgICAgLm1hcChrZXkgPT5cclxuICAgICAgICAgICAgZXJyb3Jba2V5XSA9PT0gdHJ1ZVxyXG4gICAgICAgICAgICAgID8gYWRkU3BhY2VzKGtleSlcclxuICAgICAgICAgICAgICA6IGVycm9yW2tleV0gPT09IGZhbHNlXHJcbiAgICAgICAgICAgICAgICA/ICdOb3QgJyArIGFkZFNwYWNlcyhrZXkpXHJcbiAgICAgICAgICAgICAgICA6IGFkZFNwYWNlcyhrZXkpICsgJzogJyArIGZvcm1hdEVycm9yKGVycm9yW2tleV0pXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgICAuam9pbignLCAnKVxyXG4gICAgICAgIDogYWRkU3BhY2VzKGVycm9yLnRvU3RyaW5nKCkpO1xyXG4gICAgY29uc3QgbWVzc2FnZXMgPSBbXTtcclxuICAgIHJldHVybiAoXHJcbiAgICAgIE9iamVjdC5rZXlzKGVycm9ycylcclxuICAgICAgICAvLyBIaWRlICdyZXF1aXJlZCcgZXJyb3IsIHVubGVzcyBpdCBpcyB0aGUgb25seSBvbmVcclxuICAgICAgICAuZmlsdGVyKFxyXG4gICAgICAgICAgZXJyb3JLZXkgPT5cclxuICAgICAgICAgICAgZXJyb3JLZXkgIT09ICdyZXF1aXJlZCcgfHwgT2JqZWN0LmtleXMoZXJyb3JzKS5sZW5ndGggPT09IDFcclxuICAgICAgICApXHJcbiAgICAgICAgLm1hcChlcnJvcktleSA9PlxyXG4gICAgICAgICAgLy8gSWYgdmFsaWRhdGlvbk1lc3NhZ2VzIGlzIGEgc3RyaW5nLCByZXR1cm4gaXRcclxuICAgICAgICAgIHR5cGVvZiB2YWxpZGF0aW9uTWVzc2FnZXMgPT09ICdzdHJpbmcnXHJcbiAgICAgICAgICAgID8gdmFsaWRhdGlvbk1lc3NhZ2VzXHJcbiAgICAgICAgICAgIDogLy8gSWYgY3VzdG9tIGVycm9yIG1lc3NhZ2UgaXMgYSBmdW5jdGlvbiwgcmV0dXJuIGZ1bmN0aW9uIHJlc3VsdFxyXG4gICAgICAgICAgICB0eXBlb2YgdmFsaWRhdGlvbk1lc3NhZ2VzW2Vycm9yS2V5XSA9PT0gJ2Z1bmN0aW9uJ1xyXG4gICAgICAgICAgICAgID8gdmFsaWRhdGlvbk1lc3NhZ2VzW2Vycm9yS2V5XShlcnJvcnNbZXJyb3JLZXldKVxyXG4gICAgICAgICAgICAgIDogLy8gSWYgY3VzdG9tIGVycm9yIG1lc3NhZ2UgaXMgYSBzdHJpbmcsIHJlcGxhY2UgcGxhY2Vob2xkZXJzIGFuZCByZXR1cm5cclxuICAgICAgICAgICAgICB0eXBlb2YgdmFsaWRhdGlvbk1lc3NhZ2VzW2Vycm9yS2V5XSA9PT0gJ3N0cmluZydcclxuICAgICAgICAgICAgICAgID8gLy8gRG9lcyBlcnJvciBtZXNzYWdlIGhhdmUgYW55IHt7cHJvcGVydHl9fSBwbGFjZWhvbGRlcnM/XHJcbiAgICAgICAgICAgICAgICAhL3t7Lis/fX0vLnRlc3QodmFsaWRhdGlvbk1lc3NhZ2VzW2Vycm9yS2V5XSlcclxuICAgICAgICAgICAgICAgICAgPyB2YWxpZGF0aW9uTWVzc2FnZXNbZXJyb3JLZXldXHJcbiAgICAgICAgICAgICAgICAgIDogLy8gUmVwbGFjZSB7e3Byb3BlcnR5fX0gcGxhY2Vob2xkZXJzIHdpdGggdmFsdWVzXHJcbiAgICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKGVycm9yc1tlcnJvcktleV0pLnJlZHVjZShcclxuICAgICAgICAgICAgICAgICAgICAoZXJyb3JNZXNzYWdlLCBlcnJvclByb3BlcnR5KSA9PlxyXG4gICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlLnJlcGxhY2UoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSZWdFeHAoJ3t7JyArIGVycm9yUHJvcGVydHkgKyAnfX0nLCAnZycpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnNbZXJyb3JLZXldW2Vycm9yUHJvcGVydHldXHJcbiAgICAgICAgICAgICAgICAgICAgICApLFxyXG4gICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25NZXNzYWdlc1tlcnJvcktleV1cclxuICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgOiAvLyBJZiBubyBjdXN0b20gZXJyb3IgbWVzc2FnZSwgcmV0dXJuIGZvcm1hdHRlZCBlcnJvciBkYXRhIGluc3RlYWRcclxuICAgICAgICAgICAgICAgIGFkZFNwYWNlcyhlcnJvcktleSkgKyAnIEVycm9yOiAnICsgZm9ybWF0RXJyb3IoZXJyb3JzW2Vycm9yS2V5XSlcclxuICAgICAgICApXHJcbiAgICAgICAgLmpvaW4oJzxicj4nKVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHVwZGF0ZVZhbHVlKGN0eDogYW55LCB2YWx1ZTogYW55KTogdm9pZCB7XHJcbiAgICAvLyBTZXQgdmFsdWUgb2YgY3VycmVudCBjb250cm9sXHJcbiAgICBjdHguY29udHJvbFZhbHVlID0gdmFsdWU7XHJcbiAgICBpZiAoY3R4LmJvdW5kQ29udHJvbCkge1xyXG4gICAgICBjdHguZm9ybUNvbnRyb2wuc2V0VmFsdWUodmFsdWUpO1xyXG4gICAgICBjdHguZm9ybUNvbnRyb2wubWFya0FzRGlydHkoKTtcclxuICAgIH1cclxuICAgIGN0eC5sYXlvdXROb2RlLnZhbHVlID0gdmFsdWU7XHJcblxyXG4gICAgLy8gU2V0IHZhbHVlcyBvZiBhbnkgcmVsYXRlZCBjb250cm9scyBpbiBjb3B5VmFsdWVUbyBhcnJheVxyXG4gICAgaWYgKGlzQXJyYXkoY3R4Lm9wdGlvbnMuY29weVZhbHVlVG8pKSB7XHJcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBjdHgub3B0aW9ucy5jb3B5VmFsdWVUbykge1xyXG4gICAgICAgIGNvbnN0IHRhcmdldENvbnRyb2wgPSBnZXRDb250cm9sKHRoaXMuZm9ybUdyb3VwLCBpdGVtKTtcclxuICAgICAgICBpZiAoXHJcbiAgICAgICAgICBpc09iamVjdCh0YXJnZXRDb250cm9sKSAmJlxyXG4gICAgICAgICAgdHlwZW9mIHRhcmdldENvbnRyb2wuc2V0VmFsdWUgPT09ICdmdW5jdGlvbidcclxuICAgICAgICApIHtcclxuICAgICAgICAgIHRhcmdldENvbnRyb2wuc2V0VmFsdWUodmFsdWUpO1xyXG4gICAgICAgICAgdGFyZ2V0Q29udHJvbC5tYXJrQXNEaXJ0eSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdXBkYXRlQXJyYXlDaGVja2JveExpc3QoY3R4OiBhbnksIGNoZWNrYm94TGlzdDogVGl0bGVNYXBJdGVtW10pOiB2b2lkIHtcclxuICAgIGNvbnN0IGZvcm1BcnJheSA9IDxVbnR5cGVkRm9ybUFycmF5PnRoaXMuZ2V0Rm9ybUNvbnRyb2woY3R4KTtcclxuXHJcbiAgICAvLyBSZW1vdmUgYWxsIGV4aXN0aW5nIGl0ZW1zXHJcbiAgICB3aGlsZSAoZm9ybUFycmF5LnZhbHVlLmxlbmd0aCkge1xyXG4gICAgICBmb3JtQXJyYXkucmVtb3ZlQXQoMCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmUtYWRkIGFuIGl0ZW0gZm9yIGVhY2ggY2hlY2tlZCBib3hcclxuICAgIGNvbnN0IHJlZlBvaW50ZXIgPSByZW1vdmVSZWN1cnNpdmVSZWZlcmVuY2VzKFxyXG4gICAgICBjdHgubGF5b3V0Tm9kZS5kYXRhUG9pbnRlciArICcvLScsXHJcbiAgICAgIHRoaXMuZGF0YVJlY3Vyc2l2ZVJlZk1hcCxcclxuICAgICAgdGhpcy5hcnJheU1hcFxyXG4gICAgKTtcclxuICAgIGZvciAoY29uc3QgY2hlY2tib3hJdGVtIG9mIGNoZWNrYm94TGlzdCkge1xyXG4gICAgICBpZiAoY2hlY2tib3hJdGVtLmNoZWNrZWQpIHtcclxuICAgICAgICBjb25zdCBuZXdGb3JtQ29udHJvbCA9IGJ1aWxkRm9ybUdyb3VwKFxyXG4gICAgICAgICAgdGhpcy50ZW1wbGF0ZVJlZkxpYnJhcnlbcmVmUG9pbnRlcl1cclxuICAgICAgICApO1xyXG4gICAgICAgIG5ld0Zvcm1Db250cm9sLnNldFZhbHVlKGNoZWNrYm94SXRlbS52YWx1ZSk7XHJcbiAgICAgICAgZm9ybUFycmF5LnB1c2gobmV3Rm9ybUNvbnRyb2wpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBmb3JtQXJyYXkubWFya0FzRGlydHkoKTtcclxuICB9XHJcblxyXG4gIGdldEZvcm1Db250cm9sKGN0eDogYW55KTogQWJzdHJhY3RDb250cm9sIHtcclxuICAgIGlmIChcclxuICAgICAgIWN0eC5sYXlvdXROb2RlIHx8XHJcbiAgICAgICFpc0RlZmluZWQoY3R4LmxheW91dE5vZGUuZGF0YVBvaW50ZXIpIHx8XHJcbiAgICAgIGN0eC5sYXlvdXROb2RlLnR5cGUgPT09ICckcmVmJ1xyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGdldENvbnRyb2wodGhpcy5mb3JtR3JvdXAsIHRoaXMuZ2V0RGF0YVBvaW50ZXIoY3R4KSk7XHJcbiAgfVxyXG5cclxuICBnZXRGb3JtQ29udHJvbFZhbHVlKGN0eDogYW55KTogQWJzdHJhY3RDb250cm9sIHtcclxuICAgIGlmIChcclxuICAgICAgIWN0eC5sYXlvdXROb2RlIHx8XHJcbiAgICAgICFpc0RlZmluZWQoY3R4LmxheW91dE5vZGUuZGF0YVBvaW50ZXIpIHx8XHJcbiAgICAgIGN0eC5sYXlvdXROb2RlLnR5cGUgPT09ICckcmVmJ1xyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgY29uc3QgY29udHJvbCA9IGdldENvbnRyb2wodGhpcy5mb3JtR3JvdXAsIHRoaXMuZ2V0RGF0YVBvaW50ZXIoY3R4KSk7XHJcbiAgICByZXR1cm4gY29udHJvbCA/IGNvbnRyb2wudmFsdWUgOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0Rm9ybUNvbnRyb2xHcm91cChjdHg6IGFueSk6IFVudHlwZWRGb3JtQXJyYXkgfCBVbnR5cGVkRm9ybUdyb3VwIHtcclxuICAgIGlmICghY3R4LmxheW91dE5vZGUgfHwgIWlzRGVmaW5lZChjdHgubGF5b3V0Tm9kZS5kYXRhUG9pbnRlcikpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZ2V0Q29udHJvbCh0aGlzLmZvcm1Hcm91cCwgdGhpcy5nZXREYXRhUG9pbnRlcihjdHgpLCB0cnVlKTtcclxuICB9XHJcblxyXG4gIGdldEZvcm1Db250cm9sTmFtZShjdHg6IGFueSk6IHN0cmluZyB7XHJcbiAgICBpZiAoXHJcbiAgICAgICFjdHgubGF5b3V0Tm9kZSB8fFxyXG4gICAgICAhaXNEZWZpbmVkKGN0eC5sYXlvdXROb2RlLmRhdGFQb2ludGVyKSB8fFxyXG4gICAgICAhaGFzVmFsdWUoY3R4LmRhdGFJbmRleClcclxuICAgICkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIHJldHVybiBKc29uUG9pbnRlci50b0tleSh0aGlzLmdldERhdGFQb2ludGVyKGN0eCkpO1xyXG4gIH1cclxuXHJcbiAgZ2V0TGF5b3V0QXJyYXkoY3R4OiBhbnkpOiBhbnlbXSB7XHJcbiAgICByZXR1cm4gSnNvblBvaW50ZXIuZ2V0KHRoaXMubGF5b3V0LCB0aGlzLmdldExheW91dFBvaW50ZXIoY3R4KSwgMCwgLTEpO1xyXG4gIH1cclxuXHJcbiAgZ2V0UGFyZW50Tm9kZShjdHg6IGFueSk6IGFueSB7XHJcbiAgICByZXR1cm4gSnNvblBvaW50ZXIuZ2V0KHRoaXMubGF5b3V0LCB0aGlzLmdldExheW91dFBvaW50ZXIoY3R4KSwgMCwgLTIpO1xyXG4gIH1cclxuXHJcbiAgZ2V0RGF0YVBvaW50ZXIoY3R4OiBhbnkpOiBzdHJpbmcge1xyXG4gICAgaWYgKFxyXG4gICAgICAhY3R4LmxheW91dE5vZGUgfHxcclxuICAgICAgIWlzRGVmaW5lZChjdHgubGF5b3V0Tm9kZS5kYXRhUG9pbnRlcikgfHxcclxuICAgICAgIWhhc1ZhbHVlKGN0eC5kYXRhSW5kZXgpXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gSnNvblBvaW50ZXIudG9JbmRleGVkUG9pbnRlcihcclxuICAgICAgY3R4LmxheW91dE5vZGUuZGF0YVBvaW50ZXIsXHJcbiAgICAgIGN0eC5kYXRhSW5kZXgsXHJcbiAgICAgIHRoaXMuYXJyYXlNYXBcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBnZXRMYXlvdXRQb2ludGVyKGN0eDogYW55KTogc3RyaW5nIHtcclxuICAgIGlmICghaGFzVmFsdWUoY3R4LmxheW91dEluZGV4KSkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIHJldHVybiAnLycgKyBjdHgubGF5b3V0SW5kZXguam9pbignL2l0ZW1zLycpO1xyXG4gIH1cclxuXHJcbiAgaXNDb250cm9sQm91bmQoY3R4OiBhbnkpOiBib29sZWFuIHtcclxuICAgIGlmIChcclxuICAgICAgIWN0eC5sYXlvdXROb2RlIHx8XHJcbiAgICAgICFpc0RlZmluZWQoY3R4LmxheW91dE5vZGUuZGF0YVBvaW50ZXIpIHx8XHJcbiAgICAgICFoYXNWYWx1ZShjdHguZGF0YUluZGV4KVxyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGNvbnN0IGNvbnRyb2xHcm91cCA9IHRoaXMuZ2V0Rm9ybUNvbnRyb2xHcm91cChjdHgpO1xyXG4gICAgY29uc3QgbmFtZSA9IHRoaXMuZ2V0Rm9ybUNvbnRyb2xOYW1lKGN0eCk7XHJcbiAgICByZXR1cm4gY29udHJvbEdyb3VwID8gaGFzT3duKGNvbnRyb2xHcm91cC5jb250cm9scywgbmFtZSkgOiBmYWxzZTtcclxuICB9XHJcblxyXG4gIGFkZEl0ZW0oY3R4OiBhbnksIG5hbWU/OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIGlmIChcclxuICAgICAgIWN0eC5sYXlvdXROb2RlIHx8XHJcbiAgICAgICFpc0RlZmluZWQoY3R4LmxheW91dE5vZGUuJHJlZikgfHxcclxuICAgICAgIWhhc1ZhbHVlKGN0eC5kYXRhSW5kZXgpIHx8XHJcbiAgICAgICFoYXNWYWx1ZShjdHgubGF5b3V0SW5kZXgpXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENyZWF0ZSBhIG5ldyBBbmd1bGFyIGZvcm0gY29udHJvbCBmcm9tIGEgdGVtcGxhdGUgaW4gdGVtcGxhdGVSZWZMaWJyYXJ5XHJcbiAgICBjb25zdCBuZXdGb3JtR3JvdXAgPSBidWlsZEZvcm1Hcm91cChcclxuICAgICAgdGhpcy50ZW1wbGF0ZVJlZkxpYnJhcnlbY3R4LmxheW91dE5vZGUuJHJlZl1cclxuICAgICk7XHJcblxyXG4gICAgLy8gQWRkIHRoZSBuZXcgZm9ybSBjb250cm9sIHRvIHRoZSBwYXJlbnQgZm9ybUFycmF5IG9yIGZvcm1Hcm91cFxyXG4gICAgaWYgKGN0eC5sYXlvdXROb2RlLmFycmF5SXRlbSkge1xyXG4gICAgICAvLyBBZGQgbmV3IGFycmF5IGl0ZW0gdG8gZm9ybUFycmF5XHJcbiAgICAgICg8VW50eXBlZEZvcm1BcnJheT50aGlzLmdldEZvcm1Db250cm9sR3JvdXAoY3R4KSkucHVzaChuZXdGb3JtR3JvdXApO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gQWRkIG5ldyAkcmVmIGl0ZW0gdG8gZm9ybUdyb3VwXHJcbiAgICAgICg8VW50eXBlZEZvcm1Hcm91cD50aGlzLmdldEZvcm1Db250cm9sR3JvdXAoY3R4KSkuYWRkQ29udHJvbChcclxuICAgICAgICBuYW1lIHx8IHRoaXMuZ2V0Rm9ybUNvbnRyb2xOYW1lKGN0eCksXHJcbiAgICAgICAgbmV3Rm9ybUdyb3VwXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ29weSBhIG5ldyBsYXlvdXROb2RlIGZyb20gbGF5b3V0UmVmTGlicmFyeVxyXG4gICAgY29uc3QgbmV3TGF5b3V0Tm9kZSA9IGdldExheW91dE5vZGUoY3R4LmxheW91dE5vZGUsIHRoaXMpO1xyXG4gICAgbmV3TGF5b3V0Tm9kZS5hcnJheUl0ZW0gPSBjdHgubGF5b3V0Tm9kZS5hcnJheUl0ZW07XHJcbiAgICBpZiAoY3R4LmxheW91dE5vZGUuYXJyYXlJdGVtVHlwZSkge1xyXG4gICAgICBuZXdMYXlvdXROb2RlLmFycmF5SXRlbVR5cGUgPSBjdHgubGF5b3V0Tm9kZS5hcnJheUl0ZW1UeXBlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZGVsZXRlIG5ld0xheW91dE5vZGUuYXJyYXlJdGVtVHlwZTtcclxuICAgIH1cclxuICAgIGlmIChuYW1lKSB7XHJcbiAgICAgIG5ld0xheW91dE5vZGUubmFtZSA9IG5hbWU7XHJcbiAgICAgIG5ld0xheW91dE5vZGUuZGF0YVBvaW50ZXIgKz0gJy8nICsgSnNvblBvaW50ZXIuZXNjYXBlKG5hbWUpO1xyXG4gICAgICBuZXdMYXlvdXROb2RlLm9wdGlvbnMudGl0bGUgPSBmaXhUaXRsZShuYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBBZGQgdGhlIG5ldyBsYXlvdXROb2RlIHRvIHRoZSBmb3JtIGxheW91dFxyXG4gICAgSnNvblBvaW50ZXIuaW5zZXJ0KHRoaXMubGF5b3V0LCB0aGlzLmdldExheW91dFBvaW50ZXIoY3R4KSwgbmV3TGF5b3V0Tm9kZSk7XHJcblxyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICBtb3ZlQXJyYXlJdGVtKGN0eDogYW55LCBvbGRJbmRleDogbnVtYmVyLCBuZXdJbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XHJcbiAgICBpZiAoXHJcbiAgICAgICFjdHgubGF5b3V0Tm9kZSB8fFxyXG4gICAgICAhaXNEZWZpbmVkKGN0eC5sYXlvdXROb2RlLmRhdGFQb2ludGVyKSB8fFxyXG4gICAgICAhaGFzVmFsdWUoY3R4LmRhdGFJbmRleCkgfHxcclxuICAgICAgIWhhc1ZhbHVlKGN0eC5sYXlvdXRJbmRleCkgfHxcclxuICAgICAgIWlzRGVmaW5lZChvbGRJbmRleCkgfHxcclxuICAgICAgIWlzRGVmaW5lZChuZXdJbmRleCkgfHxcclxuICAgICAgb2xkSW5kZXggPT09IG5ld0luZGV4XHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIE1vdmUgaXRlbSBpbiB0aGUgZm9ybUFycmF5XHJcbiAgICBjb25zdCBmb3JtQXJyYXkgPSA8VW50eXBlZEZvcm1BcnJheT50aGlzLmdldEZvcm1Db250cm9sR3JvdXAoY3R4KTtcclxuICAgIGNvbnN0IGFycmF5SXRlbSA9IGZvcm1BcnJheS5hdChvbGRJbmRleCk7XHJcbiAgICBmb3JtQXJyYXkucmVtb3ZlQXQob2xkSW5kZXgpO1xyXG4gICAgZm9ybUFycmF5Lmluc2VydChuZXdJbmRleCwgYXJyYXlJdGVtKTtcclxuICAgIGZvcm1BcnJheS51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcblxyXG4gICAgLy8gTW92ZSBsYXlvdXQgaXRlbVxyXG4gICAgY29uc3QgbGF5b3V0QXJyYXkgPSB0aGlzLmdldExheW91dEFycmF5KGN0eCk7XHJcbiAgICBsYXlvdXRBcnJheS5zcGxpY2UobmV3SW5kZXgsIDAsIGxheW91dEFycmF5LnNwbGljZShvbGRJbmRleCwgMSlbMF0pO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICByZW1vdmVJdGVtKGN0eDogYW55KTogYm9vbGVhbiB7XHJcbiAgICBpZiAoXHJcbiAgICAgICFjdHgubGF5b3V0Tm9kZSB8fFxyXG4gICAgICAhaXNEZWZpbmVkKGN0eC5sYXlvdXROb2RlLmRhdGFQb2ludGVyKSB8fFxyXG4gICAgICAhaGFzVmFsdWUoY3R4LmRhdGFJbmRleCkgfHxcclxuICAgICAgIWhhc1ZhbHVlKGN0eC5sYXlvdXRJbmRleClcclxuICAgICkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmVtb3ZlIHRoZSBBbmd1bGFyIGZvcm0gY29udHJvbCBmcm9tIHRoZSBwYXJlbnQgZm9ybUFycmF5IG9yIGZvcm1Hcm91cFxyXG4gICAgaWYgKGN0eC5sYXlvdXROb2RlLmFycmF5SXRlbSkge1xyXG4gICAgICAvLyBSZW1vdmUgYXJyYXkgaXRlbSBmcm9tIGZvcm1BcnJheVxyXG4gICAgICAoPFVudHlwZWRGb3JtQXJyYXk+dGhpcy5nZXRGb3JtQ29udHJvbEdyb3VwKGN0eCkpLnJlbW92ZUF0KFxyXG4gICAgICAgIGN0eC5kYXRhSW5kZXhbY3R4LmRhdGFJbmRleC5sZW5ndGggLSAxXVxyXG4gICAgICApO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gUmVtb3ZlICRyZWYgaXRlbSBmcm9tIGZvcm1Hcm91cFxyXG4gICAgICAoPFVudHlwZWRGb3JtR3JvdXA+dGhpcy5nZXRGb3JtQ29udHJvbEdyb3VwKGN0eCkpLnJlbW92ZUNvbnRyb2woXHJcbiAgICAgICAgdGhpcy5nZXRGb3JtQ29udHJvbE5hbWUoY3R4KVxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFJlbW92ZSBsYXlvdXROb2RlIGZyb20gbGF5b3V0XHJcbiAgICBKc29uUG9pbnRlci5yZW1vdmUodGhpcy5sYXlvdXQsIHRoaXMuZ2V0TGF5b3V0UG9pbnRlcihjdHgpKTtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxufVxyXG4iXX0=
|