@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,1154 @@
|
|
|
1
|
+
import cloneDeep from 'lodash/cloneDeep';
|
|
2
|
+
import _isArray from 'lodash/isArray';
|
|
3
|
+
import _isPlainObject from 'lodash/isPlainObject';
|
|
4
|
+
import uniqueId from 'lodash/uniqueId';
|
|
5
|
+
import { checkInlineType, getFromSchema, getInputType, isInputRequired, removeRecursiveReferences, updateInputOptions } from './json-schema.functions';
|
|
6
|
+
import { JsonPointer } from './jsonpointer.functions';
|
|
7
|
+
import { copy, fixTitle, forEach, hasOwn } from './utility.functions';
|
|
8
|
+
import { inArray, isArray, isDefined, isEmpty, isNumber, isObject, isString } from './validator.functions';
|
|
9
|
+
/**
|
|
10
|
+
* Layout function library:
|
|
11
|
+
*
|
|
12
|
+
* buildLayout: Builds a complete layout from an input layout and schema
|
|
13
|
+
*
|
|
14
|
+
* buildLayoutFromSchema: Builds a complete layout entirely from an input schema
|
|
15
|
+
*
|
|
16
|
+
* mapLayout:
|
|
17
|
+
*
|
|
18
|
+
* getLayoutNode:
|
|
19
|
+
*
|
|
20
|
+
* buildTitleMap:
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* 'buildLayout' function
|
|
24
|
+
*
|
|
25
|
+
* // jsf
|
|
26
|
+
* // widgetLibrary
|
|
27
|
+
* //
|
|
28
|
+
*/
|
|
29
|
+
export function buildLayout_original(jsf, widgetLibrary) {
|
|
30
|
+
let hasSubmitButton = !JsonPointer.get(jsf, '/formOptions/addSubmit');
|
|
31
|
+
const formLayout = mapLayout(jsf.layout, (layoutItem, index, layoutPointer) => {
|
|
32
|
+
const newNode = {
|
|
33
|
+
_id: uniqueId(),
|
|
34
|
+
options: {},
|
|
35
|
+
};
|
|
36
|
+
if (isObject(layoutItem)) {
|
|
37
|
+
Object.assign(newNode, layoutItem);
|
|
38
|
+
Object.keys(newNode)
|
|
39
|
+
.filter(option => !inArray(option, [
|
|
40
|
+
'_id', '$ref', 'arrayItem', 'arrayItemType', 'dataPointer', 'dataType',
|
|
41
|
+
'items', 'key', 'name', 'options', 'recursiveReference', 'type', 'widget'
|
|
42
|
+
]))
|
|
43
|
+
.forEach(option => {
|
|
44
|
+
newNode.options[option] = newNode[option];
|
|
45
|
+
delete newNode[option];
|
|
46
|
+
});
|
|
47
|
+
if (!hasOwn(newNode, 'type') && isString(newNode.widget)) {
|
|
48
|
+
newNode.type = newNode.widget;
|
|
49
|
+
delete newNode.widget;
|
|
50
|
+
}
|
|
51
|
+
if (!hasOwn(newNode.options, 'title')) {
|
|
52
|
+
if (hasOwn(newNode.options, 'legend')) {
|
|
53
|
+
newNode.options.title = newNode.options.legend;
|
|
54
|
+
delete newNode.options.legend;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!hasOwn(newNode.options, 'validationMessages')) {
|
|
58
|
+
if (hasOwn(newNode.options, 'errorMessages')) {
|
|
59
|
+
newNode.options.validationMessages = newNode.options.errorMessages;
|
|
60
|
+
delete newNode.options.errorMessages;
|
|
61
|
+
// Convert Angular Schema Form (AngularJS) 'validationMessage' to
|
|
62
|
+
// Angular JSON Schema Form 'validationMessages'
|
|
63
|
+
// TV4 codes from https://github.com/geraintluff/tv4/blob/master/source/api.js
|
|
64
|
+
}
|
|
65
|
+
else if (hasOwn(newNode.options, 'validationMessage')) {
|
|
66
|
+
if (typeof newNode.options.validationMessage === 'string') {
|
|
67
|
+
newNode.options.validationMessages = newNode.options.validationMessage;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
newNode.options.validationMessages = {};
|
|
71
|
+
Object.keys(newNode.options.validationMessage).forEach(key => {
|
|
72
|
+
const code = key + '';
|
|
73
|
+
const newKey = code === '0' ? 'type' :
|
|
74
|
+
code === '1' ? 'enum' :
|
|
75
|
+
code === '100' ? 'multipleOf' :
|
|
76
|
+
code === '101' ? 'minimum' :
|
|
77
|
+
code === '102' ? 'exclusiveMinimum' :
|
|
78
|
+
code === '103' ? 'maximum' :
|
|
79
|
+
code === '104' ? 'exclusiveMaximum' :
|
|
80
|
+
code === '200' ? 'minLength' :
|
|
81
|
+
code === '201' ? 'maxLength' :
|
|
82
|
+
code === '202' ? 'pattern' :
|
|
83
|
+
code === '300' ? 'minProperties' :
|
|
84
|
+
code === '301' ? 'maxProperties' :
|
|
85
|
+
code === '302' ? 'required' :
|
|
86
|
+
code === '304' ? 'dependencies' :
|
|
87
|
+
code === '400' ? 'minItems' :
|
|
88
|
+
code === '401' ? 'maxItems' :
|
|
89
|
+
code === '402' ? 'uniqueItems' :
|
|
90
|
+
code === '500' ? 'format' : code + '';
|
|
91
|
+
newNode.options.validationMessages[newKey] = newNode.options.validationMessage[key];
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
delete newNode.options.validationMessage;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else if (JsonPointer.isJsonPointer(layoutItem)) {
|
|
99
|
+
newNode.dataPointer = layoutItem;
|
|
100
|
+
}
|
|
101
|
+
else if (isString(layoutItem)) {
|
|
102
|
+
newNode.key = layoutItem;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
console.error('buildLayout error: Form layout element not recognized:');
|
|
106
|
+
console.error(layoutItem);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
let nodeSchema = null;
|
|
110
|
+
// If newNode does not have a dataPointer, try to find an equivalent
|
|
111
|
+
if (!hasOwn(newNode, 'dataPointer')) {
|
|
112
|
+
// If newNode has a key, change it to a dataPointer
|
|
113
|
+
if (hasOwn(newNode, 'key')) {
|
|
114
|
+
newNode.dataPointer = newNode.key === '*' ? newNode.key :
|
|
115
|
+
JsonPointer.compile(JsonPointer.parseObjectPath(newNode.key), '-');
|
|
116
|
+
delete newNode.key;
|
|
117
|
+
// If newNode is an array, search for dataPointer in child nodes
|
|
118
|
+
}
|
|
119
|
+
else if (hasOwn(newNode, 'type') && newNode.type.slice(-5) === 'array') {
|
|
120
|
+
const findDataPointer = (items) => {
|
|
121
|
+
if (items === null || typeof items !== 'object') {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (hasOwn(items, 'dataPointer')) {
|
|
125
|
+
return items.dataPointer;
|
|
126
|
+
}
|
|
127
|
+
if (isArray(items.items)) {
|
|
128
|
+
for (const item of items.items) {
|
|
129
|
+
if (hasOwn(item, 'dataPointer') && item.dataPointer.indexOf('/-') !== -1) {
|
|
130
|
+
return item.dataPointer;
|
|
131
|
+
}
|
|
132
|
+
if (hasOwn(item, 'items')) {
|
|
133
|
+
const searchItem = findDataPointer(item);
|
|
134
|
+
if (searchItem) {
|
|
135
|
+
return searchItem;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
const childDataPointer = findDataPointer(newNode);
|
|
142
|
+
if (childDataPointer) {
|
|
143
|
+
newNode.dataPointer =
|
|
144
|
+
childDataPointer.slice(0, childDataPointer.lastIndexOf('/-'));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (hasOwn(newNode, 'dataPointer')) {
|
|
149
|
+
if (newNode.dataPointer === '*') {
|
|
150
|
+
return buildLayoutFromSchema(jsf, widgetLibrary, jsf.formValues);
|
|
151
|
+
}
|
|
152
|
+
const nodeValue = JsonPointer.get(jsf.formValues, newNode.dataPointer.replace(/\/-/g, '/1'));
|
|
153
|
+
// TODO: Create function getFormValues(jsf, dataPointer, forRefLibrary)
|
|
154
|
+
// check formOptions.setSchemaDefaults and formOptions.setLayoutDefaults
|
|
155
|
+
// then set apropriate values from initialVaues, schema, or layout
|
|
156
|
+
newNode.dataPointer =
|
|
157
|
+
JsonPointer.toGenericPointer(newNode.dataPointer, jsf.arrayMap);
|
|
158
|
+
const LastKey = JsonPointer.toKey(newNode.dataPointer);
|
|
159
|
+
if (!newNode.name && isString(LastKey) && LastKey !== '-') {
|
|
160
|
+
newNode.name = LastKey;
|
|
161
|
+
}
|
|
162
|
+
const shortDataPointer = removeRecursiveReferences(newNode.dataPointer, jsf.dataRecursiveRefMap, jsf.arrayMap);
|
|
163
|
+
const recursive = !shortDataPointer.length ||
|
|
164
|
+
shortDataPointer !== newNode.dataPointer;
|
|
165
|
+
let schemaPointer;
|
|
166
|
+
if (!jsf.dataMap.has(shortDataPointer)) {
|
|
167
|
+
jsf.dataMap.set(shortDataPointer, new Map());
|
|
168
|
+
}
|
|
169
|
+
const nodeDataMap = jsf.dataMap.get(shortDataPointer);
|
|
170
|
+
if (nodeDataMap.has('schemaPointer')) {
|
|
171
|
+
schemaPointer = nodeDataMap.get('schemaPointer');
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
schemaPointer = JsonPointer.toSchemaPointer(shortDataPointer, jsf.schema);
|
|
175
|
+
nodeDataMap.set('schemaPointer', schemaPointer);
|
|
176
|
+
}
|
|
177
|
+
nodeDataMap.set('disabled', !!newNode.options.disabled);
|
|
178
|
+
nodeSchema = JsonPointer.get(jsf.schema, schemaPointer);
|
|
179
|
+
if (nodeSchema) {
|
|
180
|
+
if (!hasOwn(newNode, 'type')) {
|
|
181
|
+
newNode.type = getInputType(nodeSchema, newNode);
|
|
182
|
+
}
|
|
183
|
+
else if (!widgetLibrary.hasWidget(newNode.type)) {
|
|
184
|
+
const oldWidgetType = newNode.type;
|
|
185
|
+
newNode.type = getInputType(nodeSchema, newNode);
|
|
186
|
+
console.error(`error: widget type "${oldWidgetType}" ` +
|
|
187
|
+
`not found in library. Replacing with "${newNode.type}".`);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
newNode.type = checkInlineType(newNode.type, nodeSchema, newNode);
|
|
191
|
+
}
|
|
192
|
+
if (nodeSchema.type === 'object' && isArray(nodeSchema.required)) {
|
|
193
|
+
nodeDataMap.set('required', nodeSchema.required);
|
|
194
|
+
}
|
|
195
|
+
newNode.dataType =
|
|
196
|
+
nodeSchema.type || (hasOwn(nodeSchema, '$ref') ? '$ref' : null);
|
|
197
|
+
updateInputOptions(newNode, nodeSchema, jsf);
|
|
198
|
+
// Present checkboxes as single control, rather than array
|
|
199
|
+
if (newNode.type === 'checkboxes' && hasOwn(nodeSchema, 'items')) {
|
|
200
|
+
updateInputOptions(newNode, nodeSchema.items, jsf);
|
|
201
|
+
}
|
|
202
|
+
else if (newNode.dataType === 'array') {
|
|
203
|
+
newNode.options.maxItems = Math.min(nodeSchema.maxItems || 1000, newNode.options.maxItems || 1000);
|
|
204
|
+
newNode.options.minItems = Math.max(nodeSchema.minItems || 0, newNode.options.minItems || 0);
|
|
205
|
+
newNode.options.listItems = Math.max(newNode.options.listItems || 0, isArray(nodeValue) ? nodeValue.length : 0);
|
|
206
|
+
newNode.options.tupleItems =
|
|
207
|
+
isArray(nodeSchema.items) ? nodeSchema.items.length : 0;
|
|
208
|
+
if (newNode.options.maxItems < newNode.options.tupleItems) {
|
|
209
|
+
newNode.options.tupleItems = newNode.options.maxItems;
|
|
210
|
+
newNode.options.listItems = 0;
|
|
211
|
+
}
|
|
212
|
+
else if (newNode.options.maxItems <
|
|
213
|
+
newNode.options.tupleItems + newNode.options.listItems) {
|
|
214
|
+
newNode.options.listItems =
|
|
215
|
+
newNode.options.maxItems - newNode.options.tupleItems;
|
|
216
|
+
}
|
|
217
|
+
else if (newNode.options.minItems >
|
|
218
|
+
newNode.options.tupleItems + newNode.options.listItems) {
|
|
219
|
+
newNode.options.listItems =
|
|
220
|
+
newNode.options.minItems - newNode.options.tupleItems;
|
|
221
|
+
}
|
|
222
|
+
if (!nodeDataMap.has('maxItems')) {
|
|
223
|
+
nodeDataMap.set('maxItems', newNode.options.maxItems);
|
|
224
|
+
nodeDataMap.set('minItems', newNode.options.minItems);
|
|
225
|
+
nodeDataMap.set('tupleItems', newNode.options.tupleItems);
|
|
226
|
+
nodeDataMap.set('listItems', newNode.options.listItems);
|
|
227
|
+
}
|
|
228
|
+
if (!jsf.arrayMap.has(shortDataPointer)) {
|
|
229
|
+
jsf.arrayMap.set(shortDataPointer, newNode.options.tupleItems);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (isInputRequired(jsf.schema, schemaPointer)) {
|
|
233
|
+
newNode.options.required = true;
|
|
234
|
+
jsf.fieldsRequired = true;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
// TODO: create item in FormGroup model from layout key (?)
|
|
239
|
+
updateInputOptions(newNode, {}, jsf);
|
|
240
|
+
}
|
|
241
|
+
if (!newNode.options.title && !/^\d+$/.test(newNode.name)) {
|
|
242
|
+
newNode.options.title = fixTitle(newNode.name);
|
|
243
|
+
}
|
|
244
|
+
if (hasOwn(newNode.options, 'copyValueTo')) {
|
|
245
|
+
if (typeof newNode.options.copyValueTo === 'string') {
|
|
246
|
+
newNode.options.copyValueTo = [newNode.options.copyValueTo];
|
|
247
|
+
}
|
|
248
|
+
if (isArray(newNode.options.copyValueTo)) {
|
|
249
|
+
newNode.options.copyValueTo = newNode.options.copyValueTo.map(item => JsonPointer.compile(JsonPointer.parseObjectPath(item), '-'));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
newNode.widget = widgetLibrary.getWidget(newNode.type);
|
|
253
|
+
nodeDataMap.set('inputType', newNode.type);
|
|
254
|
+
nodeDataMap.set('widget', newNode.widget);
|
|
255
|
+
if (newNode.dataType === 'array' &&
|
|
256
|
+
(hasOwn(newNode, 'items') || hasOwn(newNode, 'additionalItems'))) {
|
|
257
|
+
const itemRefPointer = removeRecursiveReferences(newNode.dataPointer + '/-', jsf.dataRecursiveRefMap, jsf.arrayMap);
|
|
258
|
+
if (!jsf.dataMap.has(itemRefPointer)) {
|
|
259
|
+
jsf.dataMap.set(itemRefPointer, new Map());
|
|
260
|
+
}
|
|
261
|
+
jsf.dataMap.get(itemRefPointer).set('inputType', 'section');
|
|
262
|
+
// Fix insufficiently nested array item groups
|
|
263
|
+
if (newNode.items.length > 1) {
|
|
264
|
+
const arrayItemGroup = [];
|
|
265
|
+
for (let i = newNode.items.length - 1; i >= 0; i--) {
|
|
266
|
+
const subItem = newNode.items[i];
|
|
267
|
+
if (hasOwn(subItem, 'dataPointer') &&
|
|
268
|
+
subItem.dataPointer.slice(0, itemRefPointer.length) === itemRefPointer) {
|
|
269
|
+
const arrayItem = newNode.items.splice(i, 1)[0];
|
|
270
|
+
arrayItem.dataPointer = newNode.dataPointer + '/-' +
|
|
271
|
+
arrayItem.dataPointer.slice(itemRefPointer.length);
|
|
272
|
+
arrayItemGroup.unshift(arrayItem);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
subItem.arrayItem = true;
|
|
276
|
+
// TODO: Check schema to get arrayItemType and removable
|
|
277
|
+
subItem.arrayItemType = 'list';
|
|
278
|
+
subItem.removable = newNode.options.removable !== false;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (arrayItemGroup.length) {
|
|
282
|
+
newNode.items.push({
|
|
283
|
+
_id: uniqueId(),
|
|
284
|
+
arrayItem: true,
|
|
285
|
+
arrayItemType: newNode.options.tupleItems > newNode.items.length ?
|
|
286
|
+
'tuple' : 'list',
|
|
287
|
+
items: arrayItemGroup,
|
|
288
|
+
options: { removable: newNode.options.removable !== false, },
|
|
289
|
+
dataPointer: newNode.dataPointer + '/-',
|
|
290
|
+
type: 'section',
|
|
291
|
+
widget: widgetLibrary.getWidget('section'),
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
// TODO: Fix to hndle multiple items
|
|
297
|
+
newNode.items[0].arrayItem = true;
|
|
298
|
+
if (!newNode.items[0].dataPointer) {
|
|
299
|
+
newNode.items[0].dataPointer =
|
|
300
|
+
JsonPointer.toGenericPointer(itemRefPointer, jsf.arrayMap);
|
|
301
|
+
}
|
|
302
|
+
if (!JsonPointer.has(newNode, '/items/0/options/removable')) {
|
|
303
|
+
newNode.items[0].options.removable = true;
|
|
304
|
+
}
|
|
305
|
+
if (newNode.options.orderable === false) {
|
|
306
|
+
newNode.items[0].options.orderable = false;
|
|
307
|
+
}
|
|
308
|
+
newNode.items[0].arrayItemType =
|
|
309
|
+
newNode.options.tupleItems ? 'tuple' : 'list';
|
|
310
|
+
}
|
|
311
|
+
if (isArray(newNode.items)) {
|
|
312
|
+
const arrayListItems = newNode.items.filter(item => item.type !== '$ref').length -
|
|
313
|
+
newNode.options.tupleItems;
|
|
314
|
+
if (arrayListItems > newNode.options.listItems) {
|
|
315
|
+
newNode.options.listItems = arrayListItems;
|
|
316
|
+
nodeDataMap.set('listItems', arrayListItems);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (!hasOwn(jsf.layoutRefLibrary, itemRefPointer)) {
|
|
320
|
+
jsf.layoutRefLibrary[itemRefPointer] =
|
|
321
|
+
cloneDeep(newNode.items[newNode.items.length - 1]);
|
|
322
|
+
if (recursive) {
|
|
323
|
+
jsf.layoutRefLibrary[itemRefPointer].recursiveReference = true;
|
|
324
|
+
}
|
|
325
|
+
forEach(jsf.layoutRefLibrary[itemRefPointer], (item, key) => {
|
|
326
|
+
if (hasOwn(item, '_id')) {
|
|
327
|
+
item._id = null;
|
|
328
|
+
}
|
|
329
|
+
if (recursive) {
|
|
330
|
+
if (hasOwn(item, 'dataPointer')) {
|
|
331
|
+
item.dataPointer = item.dataPointer.slice(itemRefPointer.length);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}, 'top-down');
|
|
335
|
+
}
|
|
336
|
+
// Add any additional default items
|
|
337
|
+
if (!newNode.recursiveReference || newNode.options.required) {
|
|
338
|
+
const arrayLength = Math.min(Math.max(newNode.options.tupleItems + newNode.options.listItems, isArray(nodeValue) ? nodeValue.length : 0), newNode.options.maxItems);
|
|
339
|
+
for (let i = newNode.items.length; i < arrayLength; i++) {
|
|
340
|
+
newNode.items.push(getLayoutNode({
|
|
341
|
+
$ref: itemRefPointer,
|
|
342
|
+
dataPointer: newNode.dataPointer,
|
|
343
|
+
recursiveReference: newNode.recursiveReference,
|
|
344
|
+
}, jsf, widgetLibrary));
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// If needed, add button to add items to array
|
|
348
|
+
if (newNode.options.addable !== false &&
|
|
349
|
+
newNode.options.minItems < newNode.options.maxItems &&
|
|
350
|
+
(newNode.items[newNode.items.length - 1] || {}).type !== '$ref') {
|
|
351
|
+
let buttonText = 'Add';
|
|
352
|
+
if (newNode.options.title) {
|
|
353
|
+
if (/^add\b/i.test(newNode.options.title)) {
|
|
354
|
+
buttonText = newNode.options.title;
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
buttonText += ' ' + newNode.options.title;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
else if (newNode.name && !/^\d+$/.test(newNode.name)) {
|
|
361
|
+
if (/^add\b/i.test(newNode.name)) {
|
|
362
|
+
buttonText += ' ' + fixTitle(newNode.name);
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
buttonText = fixTitle(newNode.name);
|
|
366
|
+
}
|
|
367
|
+
// If newNode doesn't have a title, look for title of parent array item
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
const parentSchema = getFromSchema(jsf.schema, newNode.dataPointer, 'parentSchema');
|
|
371
|
+
if (hasOwn(parentSchema, 'title')) {
|
|
372
|
+
buttonText += ' to ' + parentSchema.title;
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
const pointerArray = JsonPointer.parse(newNode.dataPointer);
|
|
376
|
+
buttonText += ' to ' + fixTitle(pointerArray[pointerArray.length - 2]);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
newNode.items.push({
|
|
380
|
+
_id: uniqueId(),
|
|
381
|
+
arrayItem: true,
|
|
382
|
+
arrayItemType: 'list',
|
|
383
|
+
dataPointer: newNode.dataPointer + '/-',
|
|
384
|
+
options: {
|
|
385
|
+
listItems: newNode.options.listItems,
|
|
386
|
+
maxItems: newNode.options.maxItems,
|
|
387
|
+
minItems: newNode.options.minItems,
|
|
388
|
+
removable: false,
|
|
389
|
+
title: buttonText,
|
|
390
|
+
tupleItems: newNode.options.tupleItems,
|
|
391
|
+
},
|
|
392
|
+
recursiveReference: recursive,
|
|
393
|
+
type: '$ref',
|
|
394
|
+
widget: widgetLibrary.getWidget('$ref'),
|
|
395
|
+
$ref: itemRefPointer,
|
|
396
|
+
});
|
|
397
|
+
if (isString(JsonPointer.get(newNode, '/style/add'))) {
|
|
398
|
+
newNode.items[newNode.items.length - 1].options.fieldStyle =
|
|
399
|
+
newNode.style.add;
|
|
400
|
+
delete newNode.style.add;
|
|
401
|
+
if (isEmpty(newNode.style)) {
|
|
402
|
+
delete newNode.style;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
newNode.arrayItem = false;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
else if (hasOwn(newNode, 'type') || hasOwn(newNode, 'items')) {
|
|
412
|
+
const parentType = JsonPointer.get(jsf.layout, layoutPointer, 0, -2).type;
|
|
413
|
+
if (!hasOwn(newNode, 'type')) {
|
|
414
|
+
newNode.type =
|
|
415
|
+
inArray(parentType, ['tabs', 'tabarray']) ? 'tab' : 'array';
|
|
416
|
+
}
|
|
417
|
+
newNode.arrayItem = parentType === 'array';
|
|
418
|
+
newNode.widget = widgetLibrary.getWidget(newNode.type);
|
|
419
|
+
updateInputOptions(newNode, {}, jsf);
|
|
420
|
+
}
|
|
421
|
+
if (newNode.type === 'submit') {
|
|
422
|
+
hasSubmitButton = true;
|
|
423
|
+
}
|
|
424
|
+
return newNode;
|
|
425
|
+
});
|
|
426
|
+
if (jsf.hasRootReference) {
|
|
427
|
+
const fullLayout = cloneDeep(formLayout);
|
|
428
|
+
if (fullLayout[fullLayout.length - 1].type === 'submit') {
|
|
429
|
+
fullLayout.pop();
|
|
430
|
+
}
|
|
431
|
+
jsf.layoutRefLibrary[''] = {
|
|
432
|
+
_id: null,
|
|
433
|
+
dataPointer: '',
|
|
434
|
+
dataType: 'object',
|
|
435
|
+
items: fullLayout,
|
|
436
|
+
name: '',
|
|
437
|
+
options: cloneDeep(jsf.formOptions.defaultWidgetOptions),
|
|
438
|
+
recursiveReference: true,
|
|
439
|
+
required: false,
|
|
440
|
+
type: 'section',
|
|
441
|
+
widget: widgetLibrary.getWidget('section'),
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
if (!hasSubmitButton) {
|
|
445
|
+
formLayout.push({
|
|
446
|
+
_id: uniqueId(),
|
|
447
|
+
options: { title: 'Submit' },
|
|
448
|
+
type: 'submit',
|
|
449
|
+
widget: widgetLibrary.getWidget('submit'),
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
return formLayout;
|
|
453
|
+
}
|
|
454
|
+
//TODO-review:this implements a quick 'post' fix rather than an
|
|
455
|
+
//integrared ideal fix
|
|
456
|
+
export function buildLayout(jsf, widgetLibrary) {
|
|
457
|
+
let layout = buildLayout_original(jsf, widgetLibrary);
|
|
458
|
+
if (jsf.formValues) {
|
|
459
|
+
let fixedLayout = fixNestedArrayLayout({
|
|
460
|
+
builtLayout: layout,
|
|
461
|
+
formData: jsf.formValues
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
return layout;
|
|
465
|
+
}
|
|
466
|
+
function fixNestedArrayLayout(options) {
|
|
467
|
+
let { builtLayout, formData } = options;
|
|
468
|
+
let arrLengths = {};
|
|
469
|
+
let traverseObj = function (obj, path, onValue) {
|
|
470
|
+
if (_isArray(obj)) {
|
|
471
|
+
onValue && onValue(obj, path);
|
|
472
|
+
obj.forEach((item, ind) => {
|
|
473
|
+
onValue && onValue(item, path + "/" + ind);
|
|
474
|
+
traverseObj(item, path + "/" + ind, onValue);
|
|
475
|
+
});
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
if (_isPlainObject(obj)) {
|
|
479
|
+
onValue && onValue(obj, path);
|
|
480
|
+
Object.keys(obj).forEach(key => {
|
|
481
|
+
onValue && onValue(obj[key], path + "/" + key);
|
|
482
|
+
traverseObj(obj[key], path + "/" + key, onValue);
|
|
483
|
+
});
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
traverseObj(formData, "", (value, path) => {
|
|
488
|
+
if (_isArray(value)) {
|
|
489
|
+
arrLengths[path] = arrLengths[path] || value.length;
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
let getDataSize = (options) => {
|
|
493
|
+
let { data, dataPointer, indexArray } = options;
|
|
494
|
+
let dashCount = 0;
|
|
495
|
+
let dpInstance = dataPointer.substring(1).split("/").map((part, pind) => {
|
|
496
|
+
if (part == "-" && indexArray[dashCount] != undefined) {
|
|
497
|
+
return indexArray[dashCount++];
|
|
498
|
+
}
|
|
499
|
+
return part;
|
|
500
|
+
})
|
|
501
|
+
.join("/");
|
|
502
|
+
dpInstance = "/" + dpInstance;
|
|
503
|
+
let arrSize = arrLengths[dpInstance];
|
|
504
|
+
return arrSize;
|
|
505
|
+
};
|
|
506
|
+
//still too buggy
|
|
507
|
+
let createNonRefItem = (nodeWithRef) => {
|
|
508
|
+
let templateNode = {
|
|
509
|
+
"type": "section",
|
|
510
|
+
"recursiveReference": false,
|
|
511
|
+
"items": []
|
|
512
|
+
};
|
|
513
|
+
let clone = cloneDeep(nodeWithRef);
|
|
514
|
+
//commented out for now so that it behaves as ususal
|
|
515
|
+
//_.merge(clone,templateNode);
|
|
516
|
+
return clone;
|
|
517
|
+
};
|
|
518
|
+
let rebuildLayout = (options) => {
|
|
519
|
+
let { builtLayout, indices, parentDataPointer, indexPos } = options;
|
|
520
|
+
indices = indices || [];
|
|
521
|
+
indexPos = indexPos == undefined ? indexPos = -1 : indexPos;
|
|
522
|
+
if (_isArray(builtLayout)) {
|
|
523
|
+
builtLayout.forEach((item, index) => {
|
|
524
|
+
rebuildLayout({
|
|
525
|
+
builtLayout: item,
|
|
526
|
+
indices: indices,
|
|
527
|
+
indexPos: indexPos,
|
|
528
|
+
parentDataPointer: builtLayout.dataPointer || parentDataPointer
|
|
529
|
+
});
|
|
530
|
+
});
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
let dataTypes = ["array"]; //check only array for now
|
|
534
|
+
//for now added condition to ignore recursive references
|
|
535
|
+
if (builtLayout.items && dataTypes.indexOf(builtLayout.dataType) >= 0
|
|
536
|
+
&& builtLayout.dataPointer
|
|
537
|
+
&& !builtLayout.recursiveReference) {
|
|
538
|
+
let numDataItems = getDataSize({
|
|
539
|
+
data: formData,
|
|
540
|
+
dataPointer: builtLayout.dataPointer,
|
|
541
|
+
indexArray: indices
|
|
542
|
+
});
|
|
543
|
+
let numActualItems = builtLayout.items.length;
|
|
544
|
+
//check if there's ref items, if so ignore it and therefore
|
|
545
|
+
//decrement the item count
|
|
546
|
+
builtLayout.items.forEach(item => {
|
|
547
|
+
if (item.type && item.type == "$ref") {
|
|
548
|
+
numActualItems--;
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
numActualItems = Math.max(numActualItems, 0); //avoid dealing with negatives
|
|
552
|
+
if (numActualItems < numDataItems) {
|
|
553
|
+
let numItemsNeeded = numDataItems - numActualItems;
|
|
554
|
+
//added to ignore recursive references
|
|
555
|
+
if (numActualItems == 0 && builtLayout.items[0].recursiveReference) {
|
|
556
|
+
numItemsNeeded = 0;
|
|
557
|
+
}
|
|
558
|
+
for (let i = 0; i < numItemsNeeded; i++) {
|
|
559
|
+
//node must not be of type "type": "$ref"
|
|
560
|
+
//if it is then manufacture our own
|
|
561
|
+
let isRefNode = builtLayout.items[0].type && builtLayout.items[0].type == "$ref";
|
|
562
|
+
let newItem = isRefNode
|
|
563
|
+
? createNonRefItem(builtLayout.items[0])
|
|
564
|
+
: cloneDeep(builtLayout.items[0]); //copy first
|
|
565
|
+
newItem._id = uniqueId("new_");
|
|
566
|
+
builtLayout.items.unshift(newItem);
|
|
567
|
+
}
|
|
568
|
+
if (builtLayout.options.listItems) {
|
|
569
|
+
builtLayout.options.listItems = numDataItems;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
indices[builtLayout.dataPointer] = indices[builtLayout.dataPointer] || -1;
|
|
573
|
+
indexPos++;
|
|
574
|
+
builtLayout.items.forEach((item, index) => {
|
|
575
|
+
indices[indexPos] = index;
|
|
576
|
+
rebuildLayout({
|
|
577
|
+
builtLayout: item,
|
|
578
|
+
indices: indices,
|
|
579
|
+
parentDataPointer: builtLayout.dataPointer,
|
|
580
|
+
indexPos: indexPos
|
|
581
|
+
});
|
|
582
|
+
});
|
|
583
|
+
indexPos--;
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
if (builtLayout.items) {
|
|
587
|
+
builtLayout.items.forEach((item, index) => {
|
|
588
|
+
rebuildLayout({
|
|
589
|
+
builtLayout: item,
|
|
590
|
+
indices: indices,
|
|
591
|
+
parentDataPointer: parentDataPointer,
|
|
592
|
+
indexPos: indexPos
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
rebuildLayout({
|
|
599
|
+
builtLayout: builtLayout
|
|
600
|
+
});
|
|
601
|
+
//NB original is mutated
|
|
602
|
+
let fixedLayout = builtLayout;
|
|
603
|
+
return fixedLayout;
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* 'buildLayoutFromSchema' function
|
|
607
|
+
*
|
|
608
|
+
* // jsf -
|
|
609
|
+
* // widgetLibrary -
|
|
610
|
+
* // nodeValue -
|
|
611
|
+
* // { string = '' } schemaPointer -
|
|
612
|
+
* // { string = '' } dataPointer -
|
|
613
|
+
* // { boolean = false } arrayItem -
|
|
614
|
+
* // { string = null } arrayItemType -
|
|
615
|
+
* // { boolean = null } removable -
|
|
616
|
+
* // { boolean = false } forRefLibrary -
|
|
617
|
+
* // { string = '' } dataPointerPrefix -
|
|
618
|
+
* //
|
|
619
|
+
*/
|
|
620
|
+
export function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPointer = '', dataPointer = '', arrayItem = false, arrayItemType = null, removable = null, forRefLibrary = false, dataPointerPrefix = '') {
|
|
621
|
+
const schema = JsonPointer.get(jsf.schema, schemaPointer);
|
|
622
|
+
if (!hasOwn(schema, 'type') && !hasOwn(schema, '$ref') &&
|
|
623
|
+
!hasOwn(schema, 'x-schema-form')) {
|
|
624
|
+
return null;
|
|
625
|
+
}
|
|
626
|
+
const newNodeType = getInputType(schema);
|
|
627
|
+
if (!isDefined(nodeValue) && (jsf.formOptions.setSchemaDefaults === true ||
|
|
628
|
+
(jsf.formOptions.setSchemaDefaults === 'auto' && isEmpty(jsf.formValues)))) {
|
|
629
|
+
nodeValue = JsonPointer.get(jsf.schema, schemaPointer + '/default');
|
|
630
|
+
}
|
|
631
|
+
let newNode = {
|
|
632
|
+
_id: forRefLibrary ? null : uniqueId(),
|
|
633
|
+
arrayItem: arrayItem,
|
|
634
|
+
dataPointer: JsonPointer.toGenericPointer(dataPointer, jsf.arrayMap),
|
|
635
|
+
dataType: schema.type || (hasOwn(schema, '$ref') ? '$ref' : null),
|
|
636
|
+
options: {},
|
|
637
|
+
required: isInputRequired(jsf.schema, schemaPointer),
|
|
638
|
+
type: newNodeType,
|
|
639
|
+
widget: widgetLibrary.getWidget(newNodeType),
|
|
640
|
+
};
|
|
641
|
+
const lastDataKey = JsonPointer.toKey(newNode.dataPointer);
|
|
642
|
+
if (lastDataKey !== '-') {
|
|
643
|
+
newNode.name = lastDataKey;
|
|
644
|
+
}
|
|
645
|
+
if (newNode.arrayItem) {
|
|
646
|
+
newNode.arrayItemType = arrayItemType;
|
|
647
|
+
newNode.options.removable = removable !== false;
|
|
648
|
+
}
|
|
649
|
+
const shortDataPointer = removeRecursiveReferences(dataPointerPrefix + dataPointer, jsf.dataRecursiveRefMap, jsf.arrayMap);
|
|
650
|
+
const recursive = !shortDataPointer.length ||
|
|
651
|
+
shortDataPointer !== dataPointerPrefix + dataPointer;
|
|
652
|
+
if (!jsf.dataMap.has(shortDataPointer)) {
|
|
653
|
+
jsf.dataMap.set(shortDataPointer, new Map());
|
|
654
|
+
}
|
|
655
|
+
const nodeDataMap = jsf.dataMap.get(shortDataPointer);
|
|
656
|
+
if (!nodeDataMap.has('inputType')) {
|
|
657
|
+
nodeDataMap.set('schemaPointer', schemaPointer);
|
|
658
|
+
nodeDataMap.set('inputType', newNode.type);
|
|
659
|
+
nodeDataMap.set('widget', newNode.widget);
|
|
660
|
+
nodeDataMap.set('disabled', !!newNode.options.disabled);
|
|
661
|
+
}
|
|
662
|
+
updateInputOptions(newNode, schema, jsf);
|
|
663
|
+
if (!newNode.options.title && newNode.name && !/^\d+$/.test(newNode.name)) {
|
|
664
|
+
newNode.options.title = fixTitle(newNode.name);
|
|
665
|
+
}
|
|
666
|
+
if (newNode.dataType === 'object') {
|
|
667
|
+
if (isArray(schema.required) && !nodeDataMap.has('required')) {
|
|
668
|
+
nodeDataMap.set('required', schema.required);
|
|
669
|
+
}
|
|
670
|
+
if (isObject(schema.properties)) {
|
|
671
|
+
const newSection = [];
|
|
672
|
+
const propertyKeys = schema['ui:order'] || Object.keys(schema.properties);
|
|
673
|
+
if (propertyKeys.includes('*') && !hasOwn(schema.properties, '*')) {
|
|
674
|
+
const unnamedKeys = Object.keys(schema.properties)
|
|
675
|
+
.filter(key => !propertyKeys.includes(key));
|
|
676
|
+
for (let i = propertyKeys.length - 1; i >= 0; i--) {
|
|
677
|
+
if (propertyKeys[i] === '*') {
|
|
678
|
+
propertyKeys.splice(i, 1, ...unnamedKeys);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
propertyKeys
|
|
683
|
+
.filter(key => hasOwn(schema.properties, key) ||
|
|
684
|
+
hasOwn(schema, 'additionalProperties'))
|
|
685
|
+
.forEach(key => {
|
|
686
|
+
const keySchemaPointer = hasOwn(schema.properties, key) ?
|
|
687
|
+
'/properties/' + key : '/additionalProperties';
|
|
688
|
+
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, isObject(nodeValue) ? nodeValue[key] : null, schemaPointer + keySchemaPointer, dataPointer + '/' + key, false, null, null, forRefLibrary, dataPointerPrefix);
|
|
689
|
+
if (innerItem) {
|
|
690
|
+
if (isInputRequired(schema, '/' + key)) {
|
|
691
|
+
innerItem.options.required = true;
|
|
692
|
+
jsf.fieldsRequired = true;
|
|
693
|
+
}
|
|
694
|
+
newSection.push(innerItem);
|
|
695
|
+
}
|
|
696
|
+
});
|
|
697
|
+
if (dataPointer === '' && !forRefLibrary) {
|
|
698
|
+
newNode = newSection;
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
newNode.items = newSection;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
// TODO: Add patternProperties and additionalProperties inputs?
|
|
705
|
+
// ... possibly provide a way to enter both key names and values?
|
|
706
|
+
// if (isObject(schema.patternProperties)) { }
|
|
707
|
+
// if (isObject(schema.additionalProperties)) { }
|
|
708
|
+
}
|
|
709
|
+
else if (newNode.dataType === 'array') {
|
|
710
|
+
newNode.items = [];
|
|
711
|
+
newNode.options.maxItems = Math.min(schema.maxItems || 1000, newNode.options.maxItems || 1000);
|
|
712
|
+
newNode.options.minItems = Math.max(schema.minItems || 0, newNode.options.minItems || 0);
|
|
713
|
+
if (!newNode.options.minItems && isInputRequired(jsf.schema, schemaPointer)) {
|
|
714
|
+
newNode.options.minItems = 1;
|
|
715
|
+
}
|
|
716
|
+
if (!hasOwn(newNode.options, 'listItems')) {
|
|
717
|
+
newNode.options.listItems = 1;
|
|
718
|
+
}
|
|
719
|
+
newNode.options.tupleItems = isArray(schema.items) ? schema.items.length : 0;
|
|
720
|
+
if (newNode.options.maxItems <= newNode.options.tupleItems) {
|
|
721
|
+
newNode.options.tupleItems = newNode.options.maxItems;
|
|
722
|
+
newNode.options.listItems = 0;
|
|
723
|
+
}
|
|
724
|
+
else if (newNode.options.maxItems <
|
|
725
|
+
newNode.options.tupleItems + newNode.options.listItems) {
|
|
726
|
+
newNode.options.listItems = newNode.options.maxItems - newNode.options.tupleItems;
|
|
727
|
+
}
|
|
728
|
+
else if (newNode.options.minItems >
|
|
729
|
+
newNode.options.tupleItems + newNode.options.listItems) {
|
|
730
|
+
newNode.options.listItems = newNode.options.minItems - newNode.options.tupleItems;
|
|
731
|
+
}
|
|
732
|
+
if (!nodeDataMap.has('maxItems')) {
|
|
733
|
+
nodeDataMap.set('maxItems', newNode.options.maxItems);
|
|
734
|
+
nodeDataMap.set('minItems', newNode.options.minItems);
|
|
735
|
+
nodeDataMap.set('tupleItems', newNode.options.tupleItems);
|
|
736
|
+
nodeDataMap.set('listItems', newNode.options.listItems);
|
|
737
|
+
}
|
|
738
|
+
if (!jsf.arrayMap.has(shortDataPointer)) {
|
|
739
|
+
jsf.arrayMap.set(shortDataPointer, newNode.options.tupleItems);
|
|
740
|
+
}
|
|
741
|
+
removable = newNode.options.removable !== false;
|
|
742
|
+
let additionalItemsSchemaPointer = null;
|
|
743
|
+
// If 'items' is an array = tuple items
|
|
744
|
+
if (isArray(schema.items)) {
|
|
745
|
+
newNode.items = [];
|
|
746
|
+
for (let i = 0; i < newNode.options.tupleItems; i++) {
|
|
747
|
+
let newItem;
|
|
748
|
+
const itemRefPointer = removeRecursiveReferences(shortDataPointer + '/' + i, jsf.dataRecursiveRefMap, jsf.arrayMap);
|
|
749
|
+
const itemRecursive = !itemRefPointer.length ||
|
|
750
|
+
itemRefPointer !== shortDataPointer + '/' + i;
|
|
751
|
+
// If removable, add tuple item layout to layoutRefLibrary
|
|
752
|
+
if (removable && i >= newNode.options.minItems) {
|
|
753
|
+
if (!hasOwn(jsf.layoutRefLibrary, itemRefPointer)) {
|
|
754
|
+
// Set to null first to prevent recursive reference from causing endless loop
|
|
755
|
+
jsf.layoutRefLibrary[itemRefPointer] = null;
|
|
756
|
+
jsf.layoutRefLibrary[itemRefPointer] = buildLayoutFromSchema(jsf, widgetLibrary, isArray(nodeValue) ? nodeValue[i] : null, schemaPointer + '/items/' + i, itemRecursive ? '' : dataPointer + '/' + i, true, 'tuple', true, true, itemRecursive ? dataPointer + '/' + i : '');
|
|
757
|
+
if (itemRecursive) {
|
|
758
|
+
jsf.layoutRefLibrary[itemRefPointer].recursiveReference = true;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
newItem = getLayoutNode({
|
|
762
|
+
$ref: itemRefPointer,
|
|
763
|
+
dataPointer: dataPointer + '/' + i,
|
|
764
|
+
recursiveReference: itemRecursive,
|
|
765
|
+
}, jsf, widgetLibrary, isArray(nodeValue) ? nodeValue[i] : null);
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
newItem = buildLayoutFromSchema(jsf, widgetLibrary, isArray(nodeValue) ? nodeValue[i] : null, schemaPointer + '/items/' + i, dataPointer + '/' + i, true, 'tuple', false, forRefLibrary, dataPointerPrefix);
|
|
769
|
+
}
|
|
770
|
+
if (newItem) {
|
|
771
|
+
newNode.items.push(newItem);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
// If 'additionalItems' is an object = additional list items, after tuple items
|
|
775
|
+
if (isObject(schema.additionalItems)) {
|
|
776
|
+
additionalItemsSchemaPointer = schemaPointer + '/additionalItems';
|
|
777
|
+
}
|
|
778
|
+
// If 'items' is an object = list items only (no tuple items)
|
|
779
|
+
}
|
|
780
|
+
else if (isObject(schema.items)) {
|
|
781
|
+
additionalItemsSchemaPointer = schemaPointer + '/items';
|
|
782
|
+
}
|
|
783
|
+
if (additionalItemsSchemaPointer) {
|
|
784
|
+
const itemRefPointer = removeRecursiveReferences(shortDataPointer + '/-', jsf.dataRecursiveRefMap, jsf.arrayMap);
|
|
785
|
+
const itemRecursive = !itemRefPointer.length ||
|
|
786
|
+
itemRefPointer !== shortDataPointer + '/-';
|
|
787
|
+
const itemSchemaPointer = removeRecursiveReferences(additionalItemsSchemaPointer, jsf.schemaRecursiveRefMap, jsf.arrayMap);
|
|
788
|
+
// Add list item layout to layoutRefLibrary
|
|
789
|
+
if (itemRefPointer.length && !hasOwn(jsf.layoutRefLibrary, itemRefPointer)) {
|
|
790
|
+
// Set to null first to prevent recursive reference from causing endless loop
|
|
791
|
+
jsf.layoutRefLibrary[itemRefPointer] = null;
|
|
792
|
+
jsf.layoutRefLibrary[itemRefPointer] = buildLayoutFromSchema(jsf, widgetLibrary, null, itemSchemaPointer, itemRecursive ? '' : dataPointer + '/-', true, 'list', removable, true, itemRecursive ? dataPointer + '/-' : '');
|
|
793
|
+
if (itemRecursive) {
|
|
794
|
+
jsf.layoutRefLibrary[itemRefPointer].recursiveReference = true;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
// Add any additional default items
|
|
798
|
+
if (!itemRecursive || newNode.options.required) {
|
|
799
|
+
const arrayLength = Math.min(Math.max(itemRecursive ? 0 :
|
|
800
|
+
newNode.options.tupleItems + newNode.options.listItems, isArray(nodeValue) ? nodeValue.length : 0), newNode.options.maxItems);
|
|
801
|
+
if (newNode.items.length < arrayLength) {
|
|
802
|
+
for (let i = newNode.items.length; i < arrayLength; i++) {
|
|
803
|
+
newNode.items.push(getLayoutNode({
|
|
804
|
+
$ref: itemRefPointer,
|
|
805
|
+
dataPointer: dataPointer + '/-',
|
|
806
|
+
recursiveReference: itemRecursive,
|
|
807
|
+
}, jsf, widgetLibrary, isArray(nodeValue) ? nodeValue[i] : null));
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
// If needed, add button to add items to array
|
|
812
|
+
if (newNode.options.addable !== false &&
|
|
813
|
+
newNode.options.minItems < newNode.options.maxItems &&
|
|
814
|
+
(newNode.items[newNode.items.length - 1] || {}).type !== '$ref') {
|
|
815
|
+
let buttonText = ((jsf.layoutRefLibrary[itemRefPointer] || {}).options || {}).title;
|
|
816
|
+
const prefix = buttonText ? 'Add ' : 'Add to ';
|
|
817
|
+
if (!buttonText) {
|
|
818
|
+
buttonText = schema.title || fixTitle(JsonPointer.toKey(dataPointer));
|
|
819
|
+
}
|
|
820
|
+
if (!/^add\b/i.test(buttonText)) {
|
|
821
|
+
buttonText = prefix + buttonText;
|
|
822
|
+
}
|
|
823
|
+
newNode.items.push({
|
|
824
|
+
_id: uniqueId(),
|
|
825
|
+
arrayItem: true,
|
|
826
|
+
arrayItemType: 'list',
|
|
827
|
+
dataPointer: newNode.dataPointer + '/-',
|
|
828
|
+
options: {
|
|
829
|
+
listItems: newNode.options.listItems,
|
|
830
|
+
maxItems: newNode.options.maxItems,
|
|
831
|
+
minItems: newNode.options.minItems,
|
|
832
|
+
removable: false,
|
|
833
|
+
title: buttonText,
|
|
834
|
+
tupleItems: newNode.options.tupleItems,
|
|
835
|
+
},
|
|
836
|
+
recursiveReference: itemRecursive,
|
|
837
|
+
type: '$ref',
|
|
838
|
+
widget: widgetLibrary.getWidget('$ref'),
|
|
839
|
+
$ref: itemRefPointer,
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
else if (newNode.dataType === '$ref') {
|
|
845
|
+
const schemaRef = JsonPointer.compile(schema.$ref);
|
|
846
|
+
const dataRef = JsonPointer.toDataPointer(schemaRef, jsf.schema);
|
|
847
|
+
let buttonText = '';
|
|
848
|
+
// Get newNode title
|
|
849
|
+
if (newNode.options.add) {
|
|
850
|
+
buttonText = newNode.options.add;
|
|
851
|
+
}
|
|
852
|
+
else if (newNode.name && !/^\d+$/.test(newNode.name)) {
|
|
853
|
+
buttonText =
|
|
854
|
+
(/^add\b/i.test(newNode.name) ? '' : 'Add ') + fixTitle(newNode.name);
|
|
855
|
+
// If newNode doesn't have a title, look for title of parent array item
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
const parentSchema = JsonPointer.get(jsf.schema, schemaPointer, 0, -1);
|
|
859
|
+
if (hasOwn(parentSchema, 'title')) {
|
|
860
|
+
buttonText = 'Add to ' + parentSchema.title;
|
|
861
|
+
}
|
|
862
|
+
else {
|
|
863
|
+
const pointerArray = JsonPointer.parse(newNode.dataPointer);
|
|
864
|
+
buttonText = 'Add to ' + fixTitle(pointerArray[pointerArray.length - 2]);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
Object.assign(newNode, {
|
|
868
|
+
recursiveReference: true,
|
|
869
|
+
widget: widgetLibrary.getWidget('$ref'),
|
|
870
|
+
$ref: dataRef,
|
|
871
|
+
});
|
|
872
|
+
Object.assign(newNode.options, {
|
|
873
|
+
removable: false,
|
|
874
|
+
title: buttonText,
|
|
875
|
+
});
|
|
876
|
+
if (isNumber(JsonPointer.get(jsf.schema, schemaPointer, 0, -1).maxItems)) {
|
|
877
|
+
newNode.options.maxItems =
|
|
878
|
+
JsonPointer.get(jsf.schema, schemaPointer, 0, -1).maxItems;
|
|
879
|
+
}
|
|
880
|
+
// Add layout template to layoutRefLibrary
|
|
881
|
+
if (dataRef.length) {
|
|
882
|
+
if (!hasOwn(jsf.layoutRefLibrary, dataRef)) {
|
|
883
|
+
// Set to null first to prevent recursive reference from causing endless loop
|
|
884
|
+
jsf.layoutRefLibrary[dataRef] = null;
|
|
885
|
+
const newLayout = buildLayoutFromSchema(jsf, widgetLibrary, null, schemaRef, '', newNode.arrayItem, newNode.arrayItemType, true, true, dataPointer);
|
|
886
|
+
if (newLayout) {
|
|
887
|
+
newLayout.recursiveReference = true;
|
|
888
|
+
jsf.layoutRefLibrary[dataRef] = newLayout;
|
|
889
|
+
}
|
|
890
|
+
else {
|
|
891
|
+
delete jsf.layoutRefLibrary[dataRef];
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
else if (!jsf.layoutRefLibrary[dataRef].recursiveReference) {
|
|
895
|
+
jsf.layoutRefLibrary[dataRef].recursiveReference = true;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
return newNode;
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* 'mapLayout' function
|
|
903
|
+
*
|
|
904
|
+
* Creates a new layout by running each element in an existing layout through
|
|
905
|
+
* an iteratee. Recursively maps within array elements 'items' and 'tabs'.
|
|
906
|
+
* The iteratee is invoked with four arguments: (value, index, layout, path)
|
|
907
|
+
*
|
|
908
|
+
* The returned layout may be longer (or shorter) then the source layout.
|
|
909
|
+
*
|
|
910
|
+
* If an item from the source layout returns multiple items (as '*' usually will),
|
|
911
|
+
* this function will keep all returned items in-line with the surrounding items.
|
|
912
|
+
*
|
|
913
|
+
* If an item from the source layout causes an error and returns null, it is
|
|
914
|
+
* skipped without error, and the function will still return all non-null items.
|
|
915
|
+
*
|
|
916
|
+
* // layout - the layout to map
|
|
917
|
+
* // { (v: any, i?: number, l?: any, p?: string) => any }
|
|
918
|
+
* function - the funciton to invoke on each element
|
|
919
|
+
* // { string|string[] = '' } layoutPointer - the layoutPointer to layout, inside rootLayout
|
|
920
|
+
* // { any[] = layout } rootLayout - the root layout, which conatins layout
|
|
921
|
+
* //
|
|
922
|
+
*/
|
|
923
|
+
export function mapLayout(layout, fn, layoutPointer = '', rootLayout = layout) {
|
|
924
|
+
let indexPad = 0;
|
|
925
|
+
let newLayout = [];
|
|
926
|
+
forEach(layout, (item, index) => {
|
|
927
|
+
const realIndex = +index + indexPad;
|
|
928
|
+
const newLayoutPointer = layoutPointer + '/' + realIndex;
|
|
929
|
+
let newNode = copy(item);
|
|
930
|
+
let itemsArray = [];
|
|
931
|
+
if (isObject(item)) {
|
|
932
|
+
if (hasOwn(item, 'tabs')) {
|
|
933
|
+
item.items = item.tabs;
|
|
934
|
+
delete item.tabs;
|
|
935
|
+
}
|
|
936
|
+
if (hasOwn(item, 'items')) {
|
|
937
|
+
itemsArray = isArray(item.items) ? item.items : [item.items];
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
if (itemsArray.length) {
|
|
941
|
+
newNode.items = mapLayout(itemsArray, fn, newLayoutPointer + '/items', rootLayout);
|
|
942
|
+
}
|
|
943
|
+
newNode = fn(newNode, realIndex, newLayoutPointer, rootLayout);
|
|
944
|
+
if (!isDefined(newNode)) {
|
|
945
|
+
indexPad--;
|
|
946
|
+
}
|
|
947
|
+
else {
|
|
948
|
+
if (isArray(newNode)) {
|
|
949
|
+
indexPad += newNode.length - 1;
|
|
950
|
+
}
|
|
951
|
+
newLayout = newLayout.concat(newNode);
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
return newLayout;
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* 'getLayoutNode' function
|
|
958
|
+
* Copy a new layoutNode from layoutRefLibrary
|
|
959
|
+
*
|
|
960
|
+
* // refNode -
|
|
961
|
+
* // layoutRefLibrary -
|
|
962
|
+
* // { any = null } widgetLibrary -
|
|
963
|
+
* // { any = null } nodeValue -
|
|
964
|
+
* // copied layoutNode
|
|
965
|
+
*/
|
|
966
|
+
export function getLayoutNode(refNode, jsf, widgetLibrary = null, nodeValue = null) {
|
|
967
|
+
// If recursive reference and building initial layout, return Add button
|
|
968
|
+
if (refNode.recursiveReference && widgetLibrary) {
|
|
969
|
+
const newLayoutNode = cloneDeep(refNode);
|
|
970
|
+
if (!newLayoutNode.options) {
|
|
971
|
+
newLayoutNode.options = {};
|
|
972
|
+
}
|
|
973
|
+
Object.assign(newLayoutNode, {
|
|
974
|
+
recursiveReference: true,
|
|
975
|
+
widget: widgetLibrary.getWidget('$ref'),
|
|
976
|
+
});
|
|
977
|
+
Object.assign(newLayoutNode.options, {
|
|
978
|
+
removable: false,
|
|
979
|
+
title: 'Add ' + newLayoutNode.$ref,
|
|
980
|
+
});
|
|
981
|
+
return newLayoutNode;
|
|
982
|
+
// Otherwise, return referenced layout
|
|
983
|
+
}
|
|
984
|
+
else {
|
|
985
|
+
let newLayoutNode = jsf.layoutRefLibrary[refNode.$ref];
|
|
986
|
+
// If value defined, build new node from schema (to set array lengths)
|
|
987
|
+
if (isDefined(nodeValue)) {
|
|
988
|
+
newLayoutNode = buildLayoutFromSchema(jsf, widgetLibrary, nodeValue, JsonPointer.toSchemaPointer(refNode.$ref, jsf.schema), refNode.$ref, newLayoutNode.arrayItem, newLayoutNode.arrayItemType, newLayoutNode.options.removable, false);
|
|
989
|
+
}
|
|
990
|
+
else {
|
|
991
|
+
// If value not defined, copy node from layoutRefLibrary
|
|
992
|
+
newLayoutNode = cloneDeep(newLayoutNode);
|
|
993
|
+
JsonPointer.forEachDeep(newLayoutNode, (subNode, pointer) => {
|
|
994
|
+
// Reset all _id's in newLayoutNode to unique values
|
|
995
|
+
if (hasOwn(subNode, '_id')) {
|
|
996
|
+
subNode._id = uniqueId();
|
|
997
|
+
}
|
|
998
|
+
// If adding a recursive item, prefix current dataPointer
|
|
999
|
+
// to all dataPointers in new layoutNode
|
|
1000
|
+
if (refNode.recursiveReference && hasOwn(subNode, 'dataPointer')) {
|
|
1001
|
+
subNode.dataPointer = refNode.dataPointer + subNode.dataPointer;
|
|
1002
|
+
}
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
return newLayoutNode;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* 'buildTitleMap' function
|
|
1010
|
+
*
|
|
1011
|
+
* // titleMap -
|
|
1012
|
+
* // enumList -
|
|
1013
|
+
* // { boolean = true } fieldRequired -
|
|
1014
|
+
* // { boolean = true } flatList -
|
|
1015
|
+
* // { TitleMapItem[] }
|
|
1016
|
+
*/
|
|
1017
|
+
export function buildTitleMap(titleMap, enumList, fieldRequired = true, flatList = true) {
|
|
1018
|
+
let newTitleMap = [];
|
|
1019
|
+
let hasEmptyValue = false;
|
|
1020
|
+
if (titleMap) {
|
|
1021
|
+
if (isArray(titleMap)) {
|
|
1022
|
+
if (enumList) {
|
|
1023
|
+
for (const i of Object.keys(titleMap)) {
|
|
1024
|
+
if (isObject(titleMap[i])) { // JSON Form style
|
|
1025
|
+
const value = titleMap[i].value;
|
|
1026
|
+
if (enumList.includes(value)) {
|
|
1027
|
+
const name = titleMap[i].name;
|
|
1028
|
+
newTitleMap.push({ name, value });
|
|
1029
|
+
if (value === undefined || value === null) {
|
|
1030
|
+
hasEmptyValue = true;
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
else if (isString(titleMap[i])) { // React Jsonschema Form style
|
|
1035
|
+
if (i < enumList.length) {
|
|
1036
|
+
const name = titleMap[i];
|
|
1037
|
+
const value = enumList[i];
|
|
1038
|
+
newTitleMap.push({ name, value });
|
|
1039
|
+
if (value === undefined || value === null) {
|
|
1040
|
+
hasEmptyValue = true;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
else { // If array titleMap and no enum list, just return the titleMap - Angular Schema Form style
|
|
1047
|
+
newTitleMap = titleMap;
|
|
1048
|
+
if (!fieldRequired) {
|
|
1049
|
+
hasEmptyValue = !!newTitleMap
|
|
1050
|
+
.filter(i => i.value === undefined || i.value === null)
|
|
1051
|
+
.length;
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
else if (enumList) { // Alternate JSON Form style, with enum list
|
|
1056
|
+
for (const i of Object.keys(enumList)) {
|
|
1057
|
+
const value = enumList[i];
|
|
1058
|
+
if (hasOwn(titleMap, value)) {
|
|
1059
|
+
const name = titleMap[value];
|
|
1060
|
+
newTitleMap.push({ name, value });
|
|
1061
|
+
if (value === undefined || value === null) {
|
|
1062
|
+
hasEmptyValue = true;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
else { // Alternate JSON Form style, without enum list
|
|
1068
|
+
for (const value of Object.keys(titleMap)) {
|
|
1069
|
+
const name = titleMap[value];
|
|
1070
|
+
newTitleMap.push({ name, value });
|
|
1071
|
+
if (value === undefined || value === null) {
|
|
1072
|
+
hasEmptyValue = true;
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
else if (enumList) { // Build map from enum list alone
|
|
1078
|
+
for (const i of Object.keys(enumList)) {
|
|
1079
|
+
const name = enumList[i];
|
|
1080
|
+
const value = enumList[i];
|
|
1081
|
+
newTitleMap.push({ name, value });
|
|
1082
|
+
if (value === undefined || value === null) {
|
|
1083
|
+
hasEmptyValue = true;
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
else { // If no titleMap and no enum list, return default map of boolean values
|
|
1088
|
+
newTitleMap = [{ name: 'True', value: true }, { name: 'False', value: false }];
|
|
1089
|
+
}
|
|
1090
|
+
// Does titleMap have groups?
|
|
1091
|
+
if (newTitleMap.some(title => hasOwn(title, 'group'))) {
|
|
1092
|
+
hasEmptyValue = false;
|
|
1093
|
+
// If flatList = true, flatten items & update name to group: name
|
|
1094
|
+
if (flatList) {
|
|
1095
|
+
newTitleMap = newTitleMap.reduce((groupTitleMap, title) => {
|
|
1096
|
+
if (hasOwn(title, 'group')) {
|
|
1097
|
+
if (isArray(title.items)) {
|
|
1098
|
+
groupTitleMap = [
|
|
1099
|
+
...groupTitleMap,
|
|
1100
|
+
...title.items.map(item => ({ ...item, ...{ name: `${title.group}: ${item.name}` } }))
|
|
1101
|
+
];
|
|
1102
|
+
if (title.items.some(item => item.value === undefined || item.value === null)) {
|
|
1103
|
+
hasEmptyValue = true;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
if (hasOwn(title, 'name') && hasOwn(title, 'value')) {
|
|
1107
|
+
title.name = `${title.group}: ${title.name}`;
|
|
1108
|
+
delete title.group;
|
|
1109
|
+
groupTitleMap.push(title);
|
|
1110
|
+
if (title.value === undefined || title.value === null) {
|
|
1111
|
+
hasEmptyValue = true;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
else {
|
|
1116
|
+
groupTitleMap.push(title);
|
|
1117
|
+
if (title.value === undefined || title.value === null) {
|
|
1118
|
+
hasEmptyValue = true;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
return groupTitleMap;
|
|
1122
|
+
}, []);
|
|
1123
|
+
// If flatList = false, combine items from matching groups
|
|
1124
|
+
}
|
|
1125
|
+
else {
|
|
1126
|
+
newTitleMap = newTitleMap.reduce((groupTitleMap, title) => {
|
|
1127
|
+
if (hasOwn(title, 'group')) {
|
|
1128
|
+
if (title.group !== (groupTitleMap[groupTitleMap.length - 1] || {}).group) {
|
|
1129
|
+
groupTitleMap.push({ group: title.group, items: title.items || [] });
|
|
1130
|
+
}
|
|
1131
|
+
if (hasOwn(title, 'name') && hasOwn(title, 'value')) {
|
|
1132
|
+
groupTitleMap[groupTitleMap.length - 1].items
|
|
1133
|
+
.push({ name: title.name, value: title.value });
|
|
1134
|
+
if (title.value === undefined || title.value === null) {
|
|
1135
|
+
hasEmptyValue = true;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
else {
|
|
1140
|
+
groupTitleMap.push(title);
|
|
1141
|
+
if (title.value === undefined || title.value === null) {
|
|
1142
|
+
hasEmptyValue = true;
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
return groupTitleMap;
|
|
1146
|
+
}, []);
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
if (!fieldRequired && !hasEmptyValue) {
|
|
1150
|
+
newTitleMap.unshift({ name: '<em>None</em>', value: null });
|
|
1151
|
+
}
|
|
1152
|
+
return newTitleMap;
|
|
1153
|
+
}
|
|
1154
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5b3V0LmZ1bmN0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWZvcm13b3Jrcy1jb3JlL3NyYy9saWIvc2hhcmVkL2xheW91dC5mdW5jdGlvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxTQUFTLE1BQU0sa0JBQWtCLENBQUM7QUFDekMsT0FBTyxRQUFRLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEMsT0FBTyxjQUFjLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxRQUFRLE1BQU0saUJBQWlCLENBQUM7QUFFdkMsT0FBTyxFQUNMLGVBQWUsRUFDZixhQUFhLEVBQ2IsWUFBWSxFQUNaLGVBQWUsRUFDZix5QkFBeUIsRUFDekIsa0JBQWtCLEVBQ25CLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3RELE9BQU8sRUFDTCxJQUFJLEVBQ0osUUFBUSxFQUNSLE9BQU8sRUFDUCxNQUFNLEVBQ1AsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQ0wsT0FBTyxFQUNQLE9BQU8sRUFDUCxTQUFTLEVBQ1QsT0FBTyxFQUNQLFFBQVEsRUFDUixRQUFRLEVBQ1IsUUFBUSxFQUNULE1BQU0sdUJBQXVCLENBQUM7QUFLL0I7Ozs7Ozs7Ozs7OztHQVlHO0FBRUg7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEdBQUcsRUFBRSxhQUFhO0lBQ3JELElBQUksZUFBZSxHQUFHLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsd0JBQXdCLENBQUMsQ0FBQztJQUN0RSxNQUFNLFVBQVUsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLEVBQUU7UUFDNUUsTUFBTSxPQUFPLEdBQVE7WUFDbkIsR0FBRyxF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QUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO3FCQUN0RTtvQkFDRCxJQUFJLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsRUFBRTt3QkFDbkQsYUFBYSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSzs2QkFDMUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO3dCQUNsRCxJQUFJLEtBQUssQ0FBQyxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssQ0FBQyxLQUFLLEtBQUssSUFBSSxFQUFFOzRCQUNyRCxhQUFhLEdBQUcsSUFBSSxDQUFDO3lCQUN0QjtxQkFDRjtpQkFDRjtxQkFBTTtvQkFDTCxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUMxQixJQUFJLEtBQUssQ0FBQyxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssQ0FBQyxLQUFLLEtBQUssSUFBSSxFQUFFO3dCQUNyRCxhQUFhLEdBQUcsSUFBSSxDQUFDO3FCQUN0QjtpQkFDRjtnQkFDRCxPQUFPLGFBQWEsQ0FBQztZQUN2QixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDUjtLQUNGO0lBQ0QsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLGFBQWEsRUFBRTtRQUNwQyxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztLQUM3RDtJQUNELE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY2xvbmVEZWVwIGZyb20gJ2xvZGFzaC9jbG9uZURlZXAnO1xyXG5pbXBvcnQgX2lzQXJyYXkgZnJvbSAnbG9kYXNoL2lzQXJyYXknO1xyXG5pbXBvcnQgX2lzUGxhaW5PYmplY3QgZnJvbSAnbG9kYXNoL2lzUGxhaW5PYmplY3QnO1xyXG5pbXBvcnQgdW5pcXVlSWQgZnJvbSAnbG9kYXNoL3VuaXF1ZUlkJztcclxuaW1wb3J0IHsgVGl0bGVNYXBJdGVtIH0gZnJvbSAnLi4vanNvbi1zY2hlbWEtZm9ybS5zZXJ2aWNlJztcclxuaW1wb3J0IHtcclxuICBjaGVja0lubGluZVR5cGUsXHJcbiAgZ2V0RnJvbVNjaGVtYSxcclxuICBnZXRJbnB1dFR5cGUsXHJcbiAgaXNJbnB1dFJlcXVpcmVkLFxyXG4gIHJlbW92ZVJlY3Vyc2l2ZVJlZmVyZW5jZXMsXHJcbiAgdXBkYXRlSW5wdXRPcHRpb25zXHJcbn0gZnJvbSAnLi9qc29uLXNjaGVtYS5mdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBKc29uUG9pbnRlciB9IGZyb20gJy4vanNvbnBvaW50ZXIuZnVuY3Rpb25zJztcclxuaW1wb3J0IHtcclxuICBjb3B5LFxyXG4gIGZpeFRpdGxlLFxyXG4gIGZvckVhY2gsXHJcbiAgaGFzT3duXHJcbn0gZnJvbSAnLi91dGlsaXR5LmZ1bmN0aW9ucyc7XHJcbmltcG9ydCB7XHJcbiAgaW5BcnJheSxcclxuICBpc0FycmF5LFxyXG4gIGlzRGVmaW5lZCxcclxuICBpc0VtcHR5LFxyXG4gIGlzTnVtYmVyLFxyXG4gIGlzT2JqZWN0LFxyXG4gIGlzU3RyaW5nXHJcbn0gZnJvbSAnLi92YWxpZGF0b3IuZnVuY3Rpb25zJztcclxuXHJcblxyXG5cclxuXHJcbi8qKlxyXG4gKiBMYXlvdXQgZnVuY3Rpb24gbGlicmFyeTpcclxuICpcclxuICogYnVpbGRMYXlvdXQ6ICAgICAgICAgICAgQnVpbGRzIGEgY29tcGxldGUgbGF5b3V0IGZyb20gYW4gaW5wdXQgbGF5b3V0IGFuZCBzY2hlbWFcclxuICpcclxuICogYnVpbGRMYXlvdXRGcm9tU2NoZW1hOiAgQnVpbGRzIGEgY29tcGxldGUgbGF5b3V0IGVudGlyZWx5IGZyb20gYW4gaW5wdXQgc2NoZW1hXHJcbiAqXHJcbiAqIG1hcExheW91dDpcclxuICpcclxuICogZ2V0TGF5b3V0Tm9kZTpcclxuICpcclxuICogYnVpbGRUaXRsZU1hcDpcclxuICovXHJcblxyXG4vKipcclxuICogJ2J1aWxkTGF5b3V0JyBmdW5jdGlvblxyXG4gKlxyXG4gKiAvLyAgIGpzZlxyXG4gKiAvLyAgIHdpZGdldExpYnJhcnlcclxuICogLy9cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBidWlsZExheW91dF9vcmlnaW5hbChqc2YsIHdpZGdldExpYnJhcnkpIHtcclxuICBsZXQgaGFzU3VibWl0QnV0dG9uID0gIUpzb25Qb2ludGVyLmdldChqc2YsICcvZm9ybU9wdGlvbnMvYWRkU3VibWl0Jyk7XHJcbiAgY29uc3QgZm9ybUxheW91dCA9IG1hcExheW91dChqc2YubGF5b3V0LCAobGF5b3V0SXRlbSwgaW5kZXgsIGxheW91dFBvaW50ZXIpID0+IHtcclxuICAgIGNvbnN0IG5ld05vZGU6IGFueSA9IHtcclxuICAgICAgX2lkOiB1bmlxdWVJZCgpLFxyXG4gICAgICBvcHRpb25zOiB7fSxcclxuICAgIH07XHJcbiAgICBpZiAoaXNPYmplY3QobGF5b3V0SXRlbSkpIHtcclxuICAgICAgT2JqZWN0LmFzc2lnbihuZXdOb2RlLCBsYXlvdXRJdGVtKTtcclxuICAgICAgT2JqZWN0LmtleXMobmV3Tm9kZSlcclxuICAgICAgICAuZmlsdGVyKG9wdGlvbiA9PiAhaW5BcnJheShvcHRpb24sIFtcclxuICAgICAgICAgICdfaWQnLCAnJHJlZicsICdhcnJheUl0ZW0nLCAnYXJyYXlJdGVtVHlwZScsICdkYXRhUG9pbnRlcicsICdkYXRhVHlwZScsXHJcbiAgICAgICAgICAnaXRlbXMnLCAna2V5JywgJ25hbWUnLCAnb3B0aW9ucycsICdyZWN1cnNpdmVSZWZlcmVuY2UnLCAndHlwZScsICd3aWRnZXQnXHJcbiAgICAgICAgXSkpXHJcbiAgICAgICAgLmZvckVhY2gob3B0aW9uID0+IHtcclxuICAgICAgICAgIG5ld05vZGUub3B0aW9uc1tvcHRpb25dID0gbmV3Tm9kZVtvcHRpb25dO1xyXG4gICAgICAgICAgZGVsZXRlIG5ld05vZGVbb3B0aW9uXTtcclxuICAgICAgICB9KTtcclxuICAgICAgaWYgKCFoYXNPd24obmV3Tm9kZSwgJ3R5cGUnKSAmJiBpc1N0cmluZyhuZXdOb2RlLndpZGdldCkpIHtcclxuICAgICAgICBuZXdOb2RlLnR5cGUgPSBuZXdOb2RlLndpZGdldDtcclxuICAgICAgICBkZWxldGUgbmV3Tm9kZS53aWRnZXQ7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKCFoYXNPd24obmV3Tm9kZS5vcHRpb25zLCAndGl0bGUnKSkge1xyXG4gICAgICAgIGlmIChoYXNPd24obmV3Tm9kZS5vcHRpb25zLCAnbGVnZW5kJykpIHtcclxuICAgICAgICAgIG5ld05vZGUub3B0aW9ucy50aXRsZSA9IG5ld05vZGUub3B0aW9ucy5sZWdlbmQ7XHJcbiAgICAgICAgICBkZWxldGUgbmV3Tm9kZS5vcHRpb25zLmxlZ2VuZDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgaWYgKCFoYXNPd24obmV3Tm9kZS5vcHRpb25zLCAndmFsaWRhdGlvbk1lc3NhZ2VzJykpIHtcclxuICAgICAgICBpZiAoaGFzT3duKG5ld05vZGUub3B0aW9ucywgJ2Vycm9yTWVzc2FnZXMnKSkge1xyXG4gICAgICAgICAgbmV3Tm9kZS5vcHRpb25zLnZhbGlkYXRpb25NZXNzYWdlcyA9IG5ld05vZGUub3B0aW9ucy5lcnJvck1lc3NhZ2VzO1xyXG4gICAgICAgICAgZGVsZXRlIG5ld05vZGUub3B0aW9ucy5lcnJvck1lc3NhZ2VzO1xyXG5cclxuICAgICAgICAgIC8vIENvbnZlcnQgQW5ndWxhciBTY2hlbWEgRm9ybSAoQW5ndWxhckpTKSAndmFsaWRhdGlvbk1lc3NhZ2UnIHRvXHJcbiAgICAgICAgICAvLyBBbmd1bGFyIEpTT04gU2NoZW1hIEZvcm0gJ3ZhbGlkYXRpb25NZXNzYWdlcydcclxuICAgICAgICAgIC8vIFRWNCBjb2RlcyBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9nZXJhaW50bHVmZi90djQvYmxvYi9tYXN0ZXIvc291cmNlL2FwaS5qc1xyXG4gICAgICAgIH0gZWxzZSBpZiAoaGFzT3duKG5ld05vZGUub3B0aW9ucywgJ3ZhbGlkYXRpb25NZXNzYWdlJykpIHtcclxuICAgICAgICAgIGlmICh0eXBlb2YgbmV3Tm9kZS5vcHRpb25zLnZhbGlkYXRpb25NZXNzYWdlID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBuZXdOb2RlLm9wdGlvbnMudmFsaWRhdGlvbk1lc3NhZ2VzID0gbmV3Tm9kZS5vcHRpb25zLnZhbGlkYXRpb25NZXNzYWdlO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbmV3Tm9kZS5vcHRpb25zLnZhbGlkYXRpb25NZXNzYWdlcyA9IHt9O1xyXG4gICAgICAgICAgICBPYmplY3Qua2V5cyhuZXdOb2RlLm9wdGlvbnMudmFsaWRhdGlvbk1lc3NhZ2UpLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICAgICAgICBjb25zdCBjb2RlID0ga2V5ICsgJyc7XHJcbiAgICAgICAgICAgICAgY29uc3QgbmV3S2V5ID1cclxuICAgICAgICAgICAgICAgIGNvZGUgPT09ICcwJyA/ICd0eXBlJyA6XHJcbiAgICAgICAgICAgICAgICAgIGNvZGUgPT09ICcxJyA/ICdlbnVtJyA6XHJcbiAgICAgICAgICAgICAgICAgICAgY29kZSA9PT0gJzEwMCcgPyAnbXVsdGlwbGVPZicgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgY29kZSA9PT0gJzEwMScgPyAnbWluaW11bScgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlID09PSAnMTAyJyA/ICdleGNsdXNpdmVNaW5pbXVtJyA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZSA9PT0gJzEwMycgPyAnbWF4aW11bScgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZSA9PT0gJzEwNCcgPyAnZXhjbHVzaXZlTWF4aW11bScgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlID09PSAnMjAwJyA/ICdtaW5MZW5ndGgnIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlID09PSAnMjAxJyA/ICdtYXhMZW5ndGgnIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUgPT09ICcyMDInID8gJ3BhdHRlcm4nIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZSA9PT0gJzMwMCcgPyAnbWluUHJvcGVydGllcycgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUgPT09ICczMDEnID8gJ21heFByb3BlcnRpZXMnIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUgPT09ICczMDInID8gJ3JlcXVpcmVkJyA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUgPT09ICczMDQnID8gJ2RlcGVuZGVuY2llcycgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUgPT09ICc0MDAnID8gJ21pbkl0ZW1zJyA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlID09PSAnNDAxJyA/ICdtYXhJdGVtcycgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlID09PSAnNDAyJyA/ICd1bmlxdWVJdGVtcycgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUgPT09ICc1MDAnID8gJ2Zvcm1hdCcgOiBjb2RlICsgJyc7XHJcbiAgICAgICAgICAgICAgbmV3Tm9kZS5vcHRpb25zLnZhbGlkYXRpb25NZXNzYWdlc1tuZXdLZXldID0gbmV3Tm9kZS5vcHRpb25zLnZhbGlkYXRpb25NZXNzYWdlW2tleV07XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgZGVsZXRlIG5ld05vZGUub3B0aW9ucy52YWxpZGF0aW9uTWVzc2FnZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAoSnNvblBvaW50ZXIuaXNKc29uUG9pbnRlcihsYXlvdXRJdGVtKSkge1xyXG4gICAgICBuZXdOb2RlLmRhdGFQb2ludGVyID0gbGF5b3V0SXRlbTtcclxuICAgIH0gZWxzZSBpZiAoaXNTdHJpbmcobGF5b3V0SXRlbSkpIHtcclxuICAgICAgbmV3Tm9kZS5rZXkgPSBsYXlvdXRJdGVtO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc29sZS5lcnJvcignYnVpbGRMYXlvdXQgZXJyb3I6IEZvcm0gbGF5b3V0IGVsZW1lbnQgbm90IHJlY29nbml6ZWQ6Jyk7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IobGF5b3V0SXRlbSk7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgbGV0IG5vZGVTY2hlbWE6IGFueSA9IG51bGw7XHJcblxyXG4gICAgLy8gSWYgbmV3Tm9kZSBkb2VzIG5vdCBoYXZlIGEgZGF0YVBvaW50ZXIsIHRyeSB0byBmaW5kIGFuIGVxdWl2YWxlbnRcclxuICAgIGlmICghaGFzT3duKG5ld05vZGUsICdkYXRhUG9pbnRlcicpKSB7XHJcblxyXG4gICAgICAvLyBJZiBuZXdOb2RlIGhhcyBhIGtleSwgY2hhbmdlIGl0IHRvIGEgZGF0YVBvaW50ZXJcclxuICAgICAgaWYgKGhhc093bihuZXdOb2RlLCAna2V5JykpIHtcclxuICAgICAgICBuZXdOb2RlLmRhdGFQb2ludGVyID0gbmV3Tm9kZS5rZXkgPT09ICcqJyA/IG5ld05vZGUua2V5IDpcclxuICAgICAgICAgIEpzb25Qb2ludGVyLmNvbXBpbGUoSnNvblBvaW50ZXIucGFyc2VPYmplY3RQYXRoKG5ld05vZGUua2V5KSwgJy0nKTtcclxuICAgICAgICBkZWxldGUgbmV3Tm9kZS5rZXk7XHJcblxyXG4gICAgICAgIC8vIElmIG5ld05vZGUgaXMgYW4gYXJyYXksIHNlYXJjaCBmb3IgZGF0YVBvaW50ZXIgaW4gY2hpbGQgbm9kZXNcclxuICAgICAgfSBlbHNlIGlmIChoYXNPd24obmV3Tm9kZSwgJ3R5cGUnKSAmJiBuZXdOb2RlLnR5cGUuc2xpY2UoLTUpID09PSAnYXJyYXknKSB7XHJcbiAgICAgICAgY29uc3QgZmluZERhdGFQb2ludGVyID0gKGl0ZW1zKSA9PiB7XHJcbiAgICAgICAgICBpZiAoaXRlbXMgPT09IG51bGwgfHwgdHlwZW9mIGl0ZW1zICE9PSAnb2JqZWN0JykgeyByZXR1cm47IH1cclxuICAgICAgICAgIGlmIChoYXNPd24oaXRlbXMsICdkYXRhUG9pbnRlcicpKSB7IHJldHVybiBpdGVtcy5kYXRhUG9pbnRlcjsgfVxyXG4gICAgICAgICAgaWYgKGlzQXJyYXkoaXRlbXMuaXRlbXMpKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcy5pdGVtcykge1xyXG4gICAgICAgICAgICAgIGlmIChoYXNPd24oaXRlbSwgJ2RhdGFQb2ludGVyJykgJiYgaXRlbS5kYXRhUG9pbnRlci5pbmRleE9mKCcvLScpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0uZGF0YVBvaW50ZXI7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGlmIChoYXNPd24oaXRlbSwgJ2l0ZW1zJykpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNlYXJjaEl0ZW0gPSBmaW5kRGF0YVBvaW50ZXIoaXRlbSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VhcmNoSXRlbSkgeyByZXR1cm4gc2VhcmNoSXRlbTsgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgY29uc3QgY2hpbGREYXRhUG9pbnRlciA9IGZpbmREYXRhUG9pbnRlcihuZXdOb2RlKTtcclxuICAgICAgICBpZiAoY2hpbGREYXRhUG9pbnRlcikge1xyXG4gICAgICAgICAgbmV3Tm9kZS5kYXRhUG9pbnRlciA9XHJcbiAgICAgICAgICAgIGNoaWxkRGF0YVBvaW50ZXIuc2xpY2UoMCwgY2hpbGREYXRhUG9pbnRlci5sYXN0SW5kZXhPZignLy0nKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGhhc093bihuZXdOb2RlLCAnZGF0YVBvaW50ZXInKSkge1xyXG4gICAgICBpZiAobmV3Tm9kZS5kYXRhUG9pbnRlciA9PT0gJyonKSB7XHJcbiAgICAgICAgcmV0dXJuIGJ1aWxkTGF5b3V0RnJvbVNjaGVtYShqc2YsIHdpZGdldExpYnJhcnksIGpzZi5mb3JtVmFsdWVzKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBub2RlVmFsdWUgPVxyXG4gICAgICAgIEpzb25Qb2ludGVyLmdldChqc2YuZm9ybVZhbHVlcywgbmV3Tm9kZS5kYXRhUG9pbnRlci5yZXBsYWNlKC9cXC8tL2csICcvMScpKTtcclxuXHJcbiAgICAgIC8vIFRPRE86IENyZWF0ZSBmdW5jdGlvbiBnZXRGb3JtVmFsdWVzKGpzZiwgZGF0YVBvaW50ZXIsIGZvclJlZkxpYnJhcnkpXHJcbiAgICAgIC8vIGNoZWNrIGZvcm1PcHRpb25zLnNldFNjaGVtYURlZmF1bHRzIGFuZCBmb3JtT3B0aW9ucy5zZXRMYXlvdXREZWZhdWx0c1xyXG4gICAgICAvLyB0aGVuIHNldCBhcHJvcHJpYXRlIHZhbHVlcyBmcm9tIGluaXRpYWxWYXVlcywgc2NoZW1hLCBvciBsYXlvdXRcclxuXHJcbiAgICAgIG5ld05vZGUuZGF0YVBvaW50ZXIgPVxyXG4gICAgICAgIEpzb25Qb2ludGVyLnRvR2VuZXJpY1BvaW50ZXIobmV3Tm9kZS5kYXRhUG9pbnRlciwganNmLmFycmF5TWFwKTtcclxuICAgICAgY29uc3QgTGFzdEtleSA9IEpzb25Qb2ludGVyLnRvS2V5KG5ld05vZGUuZGF0YVBvaW50ZXIpO1xyXG4gICAgICBpZiAoIW5ld05vZGUubmFtZSAmJiBpc1N0cmluZyhMYXN0S2V5KSAmJiBMYXN0S2V5ICE9PSAnLScpIHtcclxuICAgICAgICBuZXdOb2RlLm5hbWUgPSBMYXN0S2V5O1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IHNob3J0RGF0YVBvaW50ZXIgPSByZW1vdmVSZWN1cnNpdmVSZWZlcmVuY2VzKFxyXG4gICAgICAgIG5ld05vZGUuZGF0YVBvaW50ZXIsIGpzZi5kYXRhUmVjdXJzaXZlUmVmTWFwLCBqc2YuYXJyYXlNYXBcclxuICAgICAgKTtcclxuICAgICAgY29uc3QgcmVjdXJzaXZlID0gIXNob3J0RGF0YVBvaW50ZXIubGVuZ3RoIHx8XHJcbiAgICAgICAgc2hvcnREYXRhUG9pbnRlciAhPT0gbmV3Tm9kZS5kYXRhUG9pbnRlcjtcclxuICAgICAgbGV0IHNjaGVtYVBvaW50ZXI6IHN0cmluZztcclxuICAgICAgaWYgKCFqc2YuZGF0YU1hcC5oYXMoc2hvcnREYXRhUG9pbnRlcikpIHtcclxuICAgICAgICBqc2YuZGF0YU1hcC5zZXQoc2hvcnREYXRhUG9pbnRlciwgbmV3IE1hcCgpKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBub2RlRGF0YU1hcCA9IGpzZi5kYXRhTWFwLmdldChzaG9ydERhdGFQb2ludGVyKTtcclxuICAgICAgaWYgKG5vZGVEYXRhTWFwLmhhcygnc2NoZW1hUG9pbnRlcicpKSB7XHJcbiAgICAgICAgc2NoZW1hUG9pbnRlciA9IG5vZGVEYXRhTWFwLmdldCgnc2NoZW1hUG9pbnRlcicpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNjaGVtYVBvaW50ZXIgPSBKc29uUG9pbnRlci50b1NjaGVtYVBvaW50ZXIoc2hvcnREYXRhUG9pbnRlciwganNmLnNjaGVtYSk7XHJcbiAgICAgICAgbm9kZURhdGFNYXAuc2V0KCdzY2hlbWFQb2ludGVyJywgc2NoZW1hUG9pbnRlcik7XHJcbiAgICAgIH1cclxuICAgICAgbm9kZURhdGFNYXAuc2V0KCdkaXNhYmxlZCcsICEhbmV3Tm9kZS5vcHRpb25zLmRpc2FibGVkKTtcclxuICAgICAgbm9kZVNjaGVtYSA9IEpzb25Qb2ludGVyLmdldChqc2Yuc2NoZW1hLCBzY2hlbWFQb2ludGVyKTtcclxuICAgICAgaWYgKG5vZGVTY2hlbWEpIHtcclxuICAgICAgICBpZiAoIWhhc093bihuZXdOb2RlLCAndHlwZScpKSB7XHJcbiAgICAgICAgICBuZXdOb2RlLnR5cGUgPSBnZXRJbnB1dFR5cGUobm9kZVNjaGVtYSwgbmV3Tm9kZSk7XHJcbiAgICAgICAgfSBlbHNlIGlmICghd2lkZ2V0TGlicmFyeS5oYXNXaWRnZXQobmV3Tm9kZS50eXBlKSkge1xyXG4gICAgICAgICAgY29uc3Qgb2xkV2lkZ2V0VHlwZSA9IG5ld05vZGUudHlwZTtcclxuICAgICAgICAgIG5ld05vZGUudHlwZSA9IGdldElucHV0VHlwZShub2RlU2NoZW1hLCBuZXdOb2RlKTtcclxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYGVycm9yOiB3aWRnZXQgdHlwZSBcIiR7b2xkV2lkZ2V0VHlwZX1cIiBgICtcclxuICAgICAgICAgICAgYG5vdCBmb3VuZCBpbiBsaWJyYXJ5LiBSZXBsYWNpbmcgd2l0aCBcIiR7bmV3Tm9kZS50eXBlfVwiLmApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBuZXdOb2RlLnR5cGUgPSBjaGVja0lubGluZVR5cGUobmV3Tm9kZS50eXBlLCBub2RlU2NoZW1hLCBuZXdOb2RlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKG5vZGVTY2hlbWEudHlwZSA9PT0gJ29iamVjdCcgJiYgaXNBcnJheShub2RlU2NoZW1hLnJlcXVpcmVkKSkge1xyXG4gICAgICAgICAgbm9kZURhdGFNYXAuc2V0KCdyZXF1aXJlZCcsIG5vZGVTY2hlbWEucmVxdWlyZWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBuZXdOb2RlLmRhdGFUeXBlID1cclxuICAgICAgICAgIG5vZGVTY2hlbWEudHlwZSB8fCAoaGFzT3duKG5vZGVTY2hlbWEsICckcmVmJykgPyAnJHJlZicgOiBudWxsKTtcclxuICAgICAgICB1cGRhdGVJbnB1dE9wdGlvbnMobmV3Tm9kZSwgbm9kZVNjaGVtYSwganNmKTtcclxuXHJcbiAgICAgICAgLy8gUHJlc2VudCBjaGVja2JveGVzIGFzIHNpbmdsZSBjb250cm9sLCByYXRoZXIgdGhhbiBhcnJheVxyXG4gICAgICAgIGlmIChuZXdOb2RlLnR5cGUgPT09ICdjaGVja2JveGVzJyAmJiBoYXNPd24obm9kZVNjaGVtYSwgJ2l0ZW1zJykpIHtcclxuICAgICAgICAgIHVwZGF0ZUlucHV0T3B0aW9ucyhuZXdOb2RlLCBub2RlU2NoZW1hLml0ZW1zLCBqc2YpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAobmV3Tm9kZS5kYXRhVHlwZSA9PT0gJ2FycmF5Jykge1xyXG4gICAgICAgICAgbmV3Tm9kZS5vcHRpb25zLm1heEl0ZW1zID0gTWF0aC5taW4oXHJcbiAgICAgICAgICAgIG5vZGVTY2hlbWEubWF4SXRlbXMgfHwgMTAwMCwgbmV3Tm9kZS5vcHRpb25zLm1heEl0ZW1zIHx8IDEwMDBcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBuZXdOb2RlLm9wdGlvbnMubWluSXRlbXMgPSBNYXRoLm1heChcclxuICAgICAgICAgICAgbm9kZVNjaGVtYS5taW5JdGVtcyB8fCAwLCBuZXdOb2RlLm9wdGlvbnMubWluSXRlbXMgfHwgMFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIG5ld05vZGUub3B0aW9ucy5saXN0SXRlbXMgPSBNYXRoLm1heChcclxuICAgICAgICAgICAgbmV3Tm9kZS5vcHRpb25zLmxpc3RJdGVtcyB8fCAwLCBpc0FycmF5KG5vZGVWYWx1ZSkgPyBub2RlVmFsdWUubGVuZ3RoIDogMFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIG5ld05vZGUub3B0aW9ucy50dXBsZUl0ZW1zID1cclxuICAgICAgICAgICAgaXNBcnJheShub2RlU2NoZW1hLml0ZW1zKSA/IG5vZGVTY2hlbWEuaXRlbXMubGVuZ3RoIDogMDtcclxuICAgICAgICAgIGlmIChuZXdOb2RlLm9wdGlvbnMubWF4SXRlbXMgPCBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcykge1xyXG4gICAgICAgICAgICBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcyA9IG5ld05vZGUub3B0aW9ucy5tYXhJdGVtcztcclxuICAgICAgICAgICAgbmV3Tm9kZS5vcHRpb25zLmxpc3RJdGVtcyA9IDA7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKG5ld05vZGUub3B0aW9ucy5tYXhJdGVtcyA8XHJcbiAgICAgICAgICAgIG5ld05vZGUub3B0aW9ucy50dXBsZUl0ZW1zICsgbmV3Tm9kZS5vcHRpb25zLmxpc3RJdGVtc1xyXG4gICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIG5ld05vZGUub3B0aW9ucy5saXN0SXRlbXMgPVxyXG4gICAgICAgICAgICAgIG5ld05vZGUub3B0aW9ucy5tYXhJdGVtcyAtIG5ld05vZGUub3B0aW9ucy50dXBsZUl0ZW1zO1xyXG4gICAgICAgICAgfSBlbHNlIGlmIChuZXdOb2RlLm9wdGlvbnMubWluSXRlbXMgPlxyXG4gICAgICAgICAgICBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcyArIG5ld05vZGUub3B0aW9ucy5saXN0SXRlbXNcclxuICAgICAgICAgICkge1xyXG4gICAgICAgICAgICBuZXdOb2RlLm9wdGlvbnMubGlzdEl0ZW1zID1cclxuICAgICAgICAgICAgICBuZXdOb2RlLm9wdGlvbnMubWluSXRlbXMgLSBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcztcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmICghbm9kZURhdGFNYXAuaGFzKCdtYXhJdGVtcycpKSB7XHJcbiAgICAgICAgICAgIG5vZGVEYXRhTWFwLnNldCgnbWF4SXRlbXMnLCBuZXdOb2RlLm9wdGlvbnMubWF4SXRlbXMpO1xyXG4gICAgICAgICAgICBub2RlRGF0YU1hcC5zZXQoJ21pbkl0ZW1zJywgbmV3Tm9kZS5vcHRpb25zLm1pbkl0ZW1zKTtcclxuICAgICAgICAgICAgbm9kZURhdGFNYXAuc2V0KCd0dXBsZUl0ZW1zJywgbmV3Tm9kZS5vcHRpb25zLnR1cGxlSXRlbXMpO1xyXG4gICAgICAgICAgICBub2RlRGF0YU1hcC5zZXQoJ2xpc3RJdGVtcycsIG5ld05vZGUub3B0aW9ucy5saXN0SXRlbXMpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKCFqc2YuYXJyYXlNYXAuaGFzKHNob3J0RGF0YVBvaW50ZXIpKSB7XHJcbiAgICAgICAgICAgIGpzZi5hcnJheU1hcC5zZXQoc2hvcnREYXRhUG9pbnRlciwgbmV3Tm9kZS5vcHRpb25zLnR1cGxlSXRlbXMpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaXNJbnB1dFJlcXVpcmVkKGpzZi5zY2hlbWEsIHNjaGVtYVBvaW50ZXIpKSB7XHJcbiAgICAgICAgICBuZXdOb2RlLm9wdGlvbnMucmVxdWlyZWQgPSB0cnVlO1xyXG4gICAgICAgICAganNmLmZpZWxkc1JlcXVpcmVkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gVE9ETzogY3JlYXRlIGl0ZW0gaW4gRm9ybUdyb3VwIG1vZGVsIGZyb20gbGF5b3V0IGtleSAoPylcclxuICAgICAgICB1cGRhdGVJbnB1dE9wdGlvbnMobmV3Tm9kZSwge30sIGpzZik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghbmV3Tm9kZS5vcHRpb25zLnRpdGxlICYmICEvXlxcZCskLy50ZXN0KG5ld05vZGUubmFtZSkpIHtcclxuICAgICAgICBuZXdOb2RlLm9wdGlvbnMudGl0bGUgPSBmaXhUaXRsZShuZXdOb2RlLm5hbWUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaGFzT3duKG5ld05vZGUub3B0aW9ucywgJ2NvcHlWYWx1ZVRvJykpIHtcclxuICAgICAgICBpZiAodHlwZW9mIG5ld05vZGUub3B0aW9ucy5jb3B5VmFsdWVUbyA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgIG5ld05vZGUub3B0aW9ucy5jb3B5VmFsdWVUbyA9IFtuZXdOb2RlLm9wdGlvbnMuY29weVZhbHVlVG9dO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaXNBcnJheShuZXdOb2RlLm9wdGlvbnMuY29weVZhbHVlVG8pKSB7XHJcbiAgICAgICAgICBuZXdOb2RlLm9wdGlvbnMuY29weVZhbHVlVG8gPSBuZXdOb2RlLm9wdGlvbnMuY29weVZhbHVlVG8ubWFwKGl0ZW0gPT5cclxuICAgICAgICAgICAgSnNvblBvaW50ZXIuY29tcGlsZShKc29uUG9pbnRlci5wYXJzZU9iamVjdFBhdGgoaXRlbSksICctJylcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBuZXdOb2RlLndpZGdldCA9IHdpZGdldExpYnJhcnkuZ2V0V2lkZ2V0KG5ld05vZGUudHlwZSk7XHJcbiAgICAgIG5vZGVEYXRhTWFwLnNldCgnaW5wdXRUeXBlJywgbmV3Tm9kZS50eXBlKTtcclxuICAgICAgbm9kZURhdGFNYXAuc2V0KCd3aWRnZXQnLCBuZXdOb2RlLndpZGdldCk7XHJcblxyXG4gICAgICBpZiAobmV3Tm9kZS5kYXRhVHlwZSA9PT0gJ2FycmF5JyAmJlxyXG4gICAgICAgIChoYXNPd24obmV3Tm9kZSwgJ2l0ZW1zJykgfHwgaGFzT3duKG5ld05vZGUsICdhZGRpdGlvbmFsSXRlbXMnKSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgY29uc3QgaXRlbVJlZlBvaW50ZXIgPSByZW1vdmVSZWN1cnNpdmVSZWZlcmVuY2VzKFxyXG4gICAgICAgICAgbmV3Tm9kZS5kYXRhUG9pbnRlciArICcvLScsIGpzZi5kYXRhUmVjdXJzaXZlUmVmTWFwLCBqc2YuYXJyYXlNYXBcclxuICAgICAgICApO1xyXG4gICAgICAgIGlmICghanNmLmRhdGFNYXAuaGFzKGl0ZW1SZWZQb2ludGVyKSkge1xyXG4gICAgICAgICAganNmLmRhdGFNYXAuc2V0KGl0ZW1SZWZQb2ludGVyLCBuZXcgTWFwKCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBqc2YuZGF0YU1hcC5nZXQoaXRlbVJlZlBvaW50ZXIpLnNldCgnaW5wdXRUeXBlJywgJ3NlY3Rpb24nKTtcclxuXHJcbiAgICAgICAgLy8gRml4IGluc3VmZmljaWVudGx5IG5lc3RlZCBhcnJheSBpdGVtIGdyb3Vwc1xyXG4gICAgICAgIGlmIChuZXdOb2RlLml0ZW1zLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgIGNvbnN0IGFycmF5SXRlbUdyb3VwID0gW107XHJcbiAgICAgICAgICBmb3IgKGxldCBpID0gbmV3Tm9kZS5pdGVtcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgICAgICBjb25zdCBzdWJJdGVtID0gbmV3Tm9kZS5pdGVtc1tpXTtcclxuICAgICAgICAgICAgaWYgKGhhc093bihzdWJJdGVtLCAnZGF0YVBvaW50ZXInKSAmJlxyXG4gICAgICAgICAgICAgIHN1Ykl0ZW0uZGF0YVBvaW50ZXIuc2xpY2UoMCwgaXRlbVJlZlBvaW50ZXIubGVuZ3RoKSA9PT0gaXRlbVJlZlBvaW50ZXJcclxuICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgYXJyYXlJdGVtID0gbmV3Tm9kZS5pdGVtcy5zcGxpY2UoaSwgMSlbMF07XHJcbiAgICAgICAgICAgICAgYXJyYXlJdGVtLmRhdGFQb2ludGVyID0gbmV3Tm9kZS5kYXRhUG9pbnRlciArICcvLScgK1xyXG4gICAgICAgICAgICAgICAgYXJyYXlJdGVtLmRhdGFQb2ludGVyLnNsaWNlKGl0ZW1SZWZQb2ludGVyLmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgYXJyYXlJdGVtR3JvdXAudW5zaGlmdChhcnJheUl0ZW0pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHN1Ykl0ZW0uYXJyYXlJdGVtID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAvLyBUT0RPOiBDaGVjayBzY2hlbWEgdG8gZ2V0IGFycmF5SXRlbVR5cGUgYW5kIHJlbW92YWJsZVxyXG4gICAgICAgICAgICAgIHN1Ykl0ZW0uYXJyYXlJdGVtVHlwZSA9ICdsaXN0JztcclxuICAgICAgICAgICAgICBzdWJJdGVtLnJlbW92YWJsZSA9IG5ld05vZGUub3B0aW9ucy5yZW1vdmFibGUgIT09IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAoYXJyYXlJdGVtR3JvdXAubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIG5ld05vZGUuaXRlbXMucHVzaCh7XHJcbiAgICAgICAgICAgICAgX2lkOiB1bmlxdWVJZCgpLFxyXG4gICAgICAgICAgICAgIGFycmF5SXRlbTogdHJ1ZSxcclxuICAgICAgICAgICAgICBhcnJheUl0ZW1UeXBlOiBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcyA+IG5ld05vZGUuaXRlbXMubGVuZ3RoID9cclxuICAgICAgICAgICAgICAgICd0dXBsZScgOiAnbGlzdCcsXHJcbiAgICAgICAgICAgICAgaXRlbXM6IGFycmF5SXRlbUdyb3VwLFxyXG4gICAgICAgICAgICAgIG9wdGlvbnM6IHsgcmVtb3ZhYmxlOiBuZXdOb2RlLm9wdGlvbnMucmVtb3ZhYmxlICE9PSBmYWxzZSwgfSxcclxuICAgICAgICAgICAgICBkYXRhUG9pbnRlcjogbmV3Tm9kZS5kYXRhUG9pbnRlciArICcvLScsXHJcbiAgICAgICAgICAgICAgdHlwZTogJ3NlY3Rpb24nLFxyXG4gICAgICAgICAgICAgIHdpZGdldDogd2lkZ2V0TGlicmFyeS5nZXRXaWRnZXQoJ3NlY3Rpb24nKSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIFRPRE86IEZpeCB0byBobmRsZSBtdWx0aXBsZSBpdGVtc1xyXG4gICAgICAgICAgbmV3Tm9kZS5pdGVtc1swXS5hcnJheUl0ZW0gPSB0cnVlO1xyXG4gICAgICAgICAgaWYgKCFuZXdOb2RlLml0ZW1zWzBdLmRhdGFQb2ludGVyKSB7XHJcbiAgICAgICAgICAgIG5ld05vZGUuaXRlbXNbMF0uZGF0YVBvaW50ZXIgPVxyXG4gICAgICAgICAgICAgIEpzb25Qb2ludGVyLnRvR2VuZXJpY1BvaW50ZXIoaXRlbVJlZlBvaW50ZXIsIGpzZi5hcnJheU1hcCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAoIUpzb25Qb2ludGVyLmhhcyhuZXdOb2RlLCAnL2l0ZW1zLzAvb3B0aW9ucy9yZW1vdmFibGUnKSkge1xyXG4gICAgICAgICAgICBuZXdOb2RlLml0ZW1zWzBdLm9wdGlvbnMucmVtb3ZhYmxlID0gdHJ1ZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmIChuZXdOb2RlLm9wdGlvbnMub3JkZXJhYmxlID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICBuZXdOb2RlLml0ZW1zWzBdLm9wdGlvbnMub3JkZXJhYmxlID0gZmFsc2U7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBuZXdOb2RlLml0ZW1zWzBdLmFycmF5SXRlbVR5cGUgPVxyXG4gICAgICAgICAgICBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcyA/ICd0dXBsZScgOiAnbGlzdCc7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoaXNBcnJheShuZXdOb2RlLml0ZW1zKSkge1xyXG4gICAgICAgICAgY29uc3QgYXJyYXlMaXN0SXRlbXMgPVxyXG4gICAgICAgICAgICBuZXdOb2RlLml0ZW1zLmZpbHRlcihpdGVtID0+IGl0ZW0udHlwZSAhPT0gJyRyZWYnKS5sZW5ndGggLVxyXG4gICAgICAgICAgICBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcztcclxuICAgICAgICAgIGlmIChhcnJheUxpc3RJdGVtcyA+IG5ld05vZGUub3B0aW9ucy5saXN0SXRlbXMpIHtcclxuICAgICAgICAgICAgbmV3Tm9kZS5vcHRpb25zLmxpc3RJdGVtcyA9IGFycmF5TGlzdEl0ZW1zO1xyXG4gICAgICAgICAgICBub2RlRGF0YU1hcC5zZXQoJ2xpc3RJdGVtcycsIGFycmF5TGlzdEl0ZW1zKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghaGFzT3duKGpzZi5sYXlvdXRSZWZMaWJyYXJ5LCBpdGVtUmVmUG9pbnRlcikpIHtcclxuICAgICAgICAgIGpzZi5sYXlvdXRSZWZMaWJyYXJ5W2l0ZW1SZWZQb2ludGVyXSA9XHJcbiAgICAgICAgICAgIGNsb25lRGVlcChuZXdOb2RlLml0ZW1zW25ld05vZGUuaXRlbXMubGVuZ3RoIC0gMV0pO1xyXG4gICAgICAgICAgaWYgKHJlY3Vyc2l2ZSkge1xyXG4gICAgICAgICAgICBqc2YubGF5b3V0UmVmTGlicmFyeVtpdGVtUmVmUG9pbnRlcl0ucmVjdXJzaXZlUmVmZXJlbmNlID0gdHJ1ZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGZvckVhY2goanNmLmxheW91dFJlZkxpYnJhcnlbaXRlbVJlZlBvaW50ZXJdLCAoaXRlbSwga2V5KSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChoYXNPd24oaXRlbSwgJ19pZCcpKSB7IGl0ZW0uX2lkID0gbnVsbDsgfVxyXG4gICAgICAgICAgICBpZiAocmVjdXJzaXZlKSB7XHJcbiAgICAgICAgICAgICAgaWYgKGhhc093bihpdGVtLCAnZGF0YVBvaW50ZXInKSkge1xyXG4gICAgICAgICAgICAgICAgaXRlbS5kYXRhUG9pbnRlciA9IGl0ZW0uZGF0YVBvaW50ZXIuc2xpY2UoaXRlbVJlZlBvaW50ZXIubGVuZ3RoKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0sICd0b3AtZG93bicpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQWRkIGFueSBhZGRpdGlvbmFsIGRlZmF1bHQgaXRlbXNcclxuICAgICAgICBpZiAoIW5ld05vZGUucmVjdXJzaXZlUmVmZXJlbmNlIHx8IG5ld05vZGUub3B0aW9ucy5yZXF1aXJlZCkge1xyXG4gICAgICAgICAgY29uc3QgYXJyYXlMZW5ndGggPSBNYXRoLm1pbihNYXRoLm1heChcclxuICAgICAgICAgICAgbmV3Tm9kZS5vcHRpb25zLnR1cGxlSXRlbXMgKyBuZXdOb2RlLm9wdGlvbnMubGlzdEl0ZW1zLFxyXG4gICAgICAgICAgICBpc0FycmF5KG5vZGVWYWx1ZSkgPyBub2RlVmFsdWUubGVuZ3RoIDogMFxyXG4gICAgICAgICAgKSwgbmV3Tm9kZS5vcHRpb25zLm1heEl0ZW1zKTtcclxuICAgICAgICAgIGZvciAobGV0IGkgPSBuZXdOb2RlLml0ZW1zLmxlbmd0aDsgaSA8IGFycmF5TGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbmV3Tm9kZS5pdGVtcy5wdXNoKGdldExheW91dE5vZGUoe1xyXG4gICAgICAgICAgICAgICRyZWY6IGl0ZW1SZWZQb2ludGVyLFxyXG4gICAgICAgICAgICAgIGRhdGFQb2ludGVyOiBuZXdOb2RlLmRhdGFQb2ludGVyLFxyXG4gICAgICAgICAgICAgIHJlY3Vyc2l2ZVJlZmVyZW5jZTogbmV3Tm9kZS5yZWN1cnNpdmVSZWZlcmVuY2UsXHJcbiAgICAgICAgICAgIH0sIGpzZiwgd2lkZ2V0TGlicmFyeSkpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSWYgbmVlZGVkLCBhZGQgYnV0dG9uIHRvIGFkZCBpdGVtcyB0byBhcnJheVxyXG4gICAgICAgIGlmIChuZXdOb2RlLm9wdGlvbnMuYWRkYWJsZSAhPT0gZmFsc2UgJiZcclxuICAgICAgICAgIG5ld05vZGUub3B0aW9ucy5taW5JdGVtcyA8IG5ld05vZGUub3B0aW9ucy5tYXhJdGVtcyAmJlxyXG4gICAgICAgICAgKG5ld05vZGUuaXRlbXNbbmV3Tm9kZS5pdGVtcy5sZW5ndGggLSAxXSB8fCB7fSkudHlwZSAhPT0gJyRyZWYnXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICBsZXQgYnV0dG9uVGV4dCA9ICdBZGQnO1xyXG4gICAgICAgICAgaWYgKG5ld05vZGUub3B0aW9ucy50aXRsZSkge1xyXG4gICAgICAgICAgICBpZiAoL15hZGRcXGIvaS50ZXN0KG5ld05vZGUub3B0aW9ucy50aXRsZSkpIHtcclxuICAgICAgICAgICAgICBidXR0b25UZXh0ID0gbmV3Tm9kZS5vcHRpb25zLnRpdGxlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIGJ1dHRvblRleHQgKz0gJyAnICsgbmV3Tm9kZS5vcHRpb25zLnRpdGxlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKG5ld05vZGUubmFtZSAmJiAhL15cXGQrJC8udGVzdChuZXdOb2RlLm5hbWUpKSB7XHJcbiAgICAgICAgICAgIGlmICgvXmFkZFxcYi9pLnRlc3QobmV3Tm9kZS5uYW1lKSkge1xyXG4gICAgICAgICAgICAgIGJ1dHRvblRleHQgKz0gJyAnICsgZml4VGl0bGUobmV3Tm9kZS5uYW1lKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBidXR0b25UZXh0ID0gZml4VGl0bGUobmV3Tm9kZS5uYW1lKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gSWYgbmV3Tm9kZSBkb2Vzbid0IGhhdmUgYSB0aXRsZSwgbG9vayBmb3IgdGl0bGUgb2YgcGFyZW50IGFycmF5IGl0ZW1cclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudFNjaGVtYSA9XHJcbiAgICAgICAgICAgICAgZ2V0RnJvbVNjaGVtYShqc2Yuc2NoZW1hLCBuZXdOb2RlLmRhdGFQb2ludGVyLCAncGFyZW50U2NoZW1hJyk7XHJcbiAgICAgICAgICAgIGlmIChoYXNPd24ocGFyZW50U2NoZW1hLCAndGl0bGUnKSkge1xyXG4gICAgICAgICAgICAgIGJ1dHRvblRleHQgKz0gJyB0byAnICsgcGFyZW50U2NoZW1hLnRpdGxlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIGNvbnN0IHBvaW50ZXJBcnJheSA9IEpzb25Qb2ludGVyLnBhcnNlKG5ld05vZGUuZGF0YVBvaW50ZXIpO1xyXG4gICAgICAgICAgICAgIGJ1dHRvblRleHQgKz0gJyB0byAnICsgZml4VGl0bGUocG9pbnRlckFycmF5W3BvaW50ZXJBcnJheS5sZW5ndGggLSAyXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIG5ld05vZGUuaXRlbXMucHVzaCh7XHJcbiAgICAgICAgICAgIF9pZDogdW5pcXVlSWQoKSxcclxuICAgICAgICAgICAgYXJyYXlJdGVtOiB0cnVlLFxyXG4gICAgICAgICAgICBhcnJheUl0ZW1UeXBlOiAnbGlzdCcsXHJcbiAgICAgICAgICAgIGRhdGFQb2ludGVyOiBuZXdOb2RlLmRhdGFQb2ludGVyICsgJy8tJyxcclxuICAgICAgICAgICAgb3B0aW9uczoge1xyXG4gICAgICAgICAgICAgIGxpc3RJdGVtczogbmV3Tm9kZS5vcHRpb25zLmxpc3RJdGVtcyxcclxuICAgICAgICAgICAgICBtYXhJdGVtczogbmV3Tm9kZS5vcHRpb25zLm1heEl0ZW1zLFxyXG4gICAgICAgICAgICAgIG1pbkl0ZW1zOiBuZXdOb2RlLm9wdGlvbnMubWluSXRlbXMsXHJcbiAgICAgICAgICAgICAgcmVtb3ZhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAgICB0aXRsZTogYnV0dG9uVGV4dCxcclxuICAgICAgICAgICAgICB0dXBsZUl0ZW1zOiBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcyxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcmVjdXJzaXZlUmVmZXJlbmNlOiByZWN1cnNpdmUsXHJcbiAgICAgICAgICAgIHR5cGU6ICckcmVmJyxcclxuICAgICAgICAgICAgd2lkZ2V0OiB3aWRnZXRMaWJyYXJ5LmdldFdpZGdldCgnJHJlZicpLFxyXG4gICAgICAgICAgICAkcmVmOiBpdGVtUmVmUG9pbnRlcixcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgaWYgKGlzU3RyaW5nKEpzb25Qb2ludGVyLmdldChuZXdOb2RlLCAnL3N0eWxlL2FkZCcpKSkge1xyXG4gICAgICAgICAgICBuZXdOb2RlLml0ZW1zW25ld05vZGUuaXRlbXMubGVuZ3RoIC0gMV0ub3B0aW9ucy5maWVsZFN0eWxlID1cclxuICAgICAgICAgICAgICBuZXdOb2RlLnN0eWxlLmFkZDtcclxuICAgICAgICAgICAgZGVsZXRlIG5ld05vZGUuc3R5bGUuYWRkO1xyXG4gICAgICAgICAgICBpZiAoaXNFbXB0eShuZXdOb2RlLnN0eWxlKSkgeyBkZWxldGUgbmV3Tm9kZS5zdHlsZTsgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBuZXdOb2RlLmFycmF5SXRlbSA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYgKGhhc093bihuZXdOb2RlLCAndHlwZScpIHx8IGhhc093bihuZXdOb2RlLCAnaXRlbXMnKSkge1xyXG4gICAgICBjb25zdCBwYXJlbnRUeXBlOiBzdHJpbmcgPVxyXG4gICAgICAgIEpzb25Qb2ludGVyLmdldChqc2YubGF5b3V0LCBsYXlvdXRQb2ludGVyLCAwLCAtMikudHlwZTtcclxuICAgICAgaWYgKCFoYXNPd24obmV3Tm9kZSwgJ3R5cGUnKSkge1xyXG4gICAgICAgIG5ld05vZGUudHlwZSA9XHJcbiAgICAgICAgICBpbkFycmF5KHBhcmVudFR5cGUsIFsndGFicycsICd0YWJhcnJheSddKSA/ICd0YWInIDogJ2FycmF5JztcclxuICAgICAgfVxyXG4gICAgICBuZXdOb2RlLmFycmF5SXRlbSA9IHBhcmVudFR5cGUgPT09ICdhcnJheSc7XHJcbiAgICAgIG5ld05vZGUud2lkZ2V0ID0gd2lkZ2V0TGlicmFyeS5nZXRXaWRnZXQobmV3Tm9kZS50eXBlKTtcclxuICAgICAgdXBkYXRlSW5wdXRPcHRpb25zKG5ld05vZGUsIHt9LCBqc2YpO1xyXG4gICAgfVxyXG4gICAgaWYgKG5ld05vZGUudHlwZSA9PT0gJ3N1Ym1pdCcpIHsgaGFzU3VibWl0QnV0dG9uID0gdHJ1ZTsgfVxyXG4gICAgcmV0dXJuIG5ld05vZGU7XHJcbiAgfSk7XHJcbiAgaWYgKGpzZi5oYXNSb290UmVmZXJlbmNlKSB7XHJcbiAgICBjb25zdCBmdWxsTGF5b3V0ID0gY2xvbmVEZWVwKGZvcm1MYXlvdXQpO1xyXG4gICAgaWYgKGZ1bGxMYXlvdXRbZnVsbExheW91dC5sZW5ndGggLSAxXS50eXBlID09PSAnc3VibWl0JykgeyBmdWxsTGF5b3V0LnBvcCgpOyB9XHJcbiAgICBqc2YubGF5b3V0UmVmTGlicmFyeVsnJ10gPSB7XHJcbiAgICAgIF9pZDogbnVsbCxcclxuICAgICAgZGF0YVBvaW50ZXI6ICcnLFxyXG4gICAgICBkYXRhVHlwZTogJ29iamVjdCcsXHJcbiAgICAgIGl0ZW1zOiBmdWxsTGF5b3V0LFxyXG4gICAgICBuYW1lOiAnJyxcclxuICAgICAgb3B0aW9uczogY2xvbmVEZWVwKGpzZi5mb3JtT3B0aW9ucy5kZWZhdWx0V2lkZ2V0T3B0aW9ucyksXHJcbiAgICAgIHJlY3Vyc2l2ZVJlZmVyZW5jZTogdHJ1ZSxcclxuICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxyXG4gICAgICB0eXBlOiAnc2VjdGlvbicsXHJcbiAgICAgIHdpZGdldDogd2lkZ2V0TGlicmFyeS5nZXRXaWRnZXQoJ3NlY3Rpb24nKSxcclxuICAgIH07XHJcbiAgfVxyXG4gIGlmICghaGFzU3VibWl0QnV0dG9uKSB7XHJcbiAgICBmb3JtTGF5b3V0LnB1c2goe1xyXG4gICAgICBfaWQ6IHVuaXF1ZUlkKCksXHJcbiAgICAgIG9wdGlvbnM6IHsgdGl0bGU6ICdTdWJtaXQnIH0sXHJcbiAgICAgIHR5cGU6ICdzdWJtaXQnLFxyXG4gICAgICB3aWRnZXQ6IHdpZGdldExpYnJhcnkuZ2V0V2lkZ2V0KCdzdWJtaXQnKSxcclxuICAgIH0pO1xyXG4gIH1cclxuICByZXR1cm4gZm9ybUxheW91dDtcclxufVxyXG5cclxuLy9UT0RPLXJldmlldzp0aGlzIGltcGxlbWVudHMgYSBxdWljayAncG9zdCcgZml4IHJhdGhlciB0aGFuIGFuXHJcbi8vaW50ZWdyYXJlZCBpZGVhbCBmaXhcclxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkTGF5b3V0KGpzZiwgd2lkZ2V0TGlicmFyeSkge1xyXG4gIGxldCBsYXlvdXQ9YnVpbGRMYXlvdXRfb3JpZ2luYWwoanNmLCB3aWRnZXRMaWJyYXJ5KTtcclxuICBpZiAoanNmLmZvcm1WYWx1ZXMpIHtcclxuICAgIGxldCBmaXhlZExheW91dCA9IGZpeE5lc3RlZEFycmF5TGF5b3V0KHtcclxuICAgICAgYnVpbHRMYXlvdXQ6IGxheW91dCxcclxuICAgICAgZm9ybURhdGE6IGpzZi5mb3JtVmFsdWVzXHJcbiAgICB9KTtcclxuICB9XHJcbiAgcmV0dXJuIGxheW91dDtcclxufVxyXG5cclxuXHJcblxyXG5mdW5jdGlvbiBmaXhOZXN0ZWRBcnJheUxheW91dChvcHRpb25zOiBhbnkpIHtcclxuICBsZXQgeyBidWlsdExheW91dCwgZm9ybURhdGEgfSA9IG9wdGlvbnM7XHJcbiAgbGV0IGFyckxlbmd0aHMgPSB7fTtcclxuICBsZXQgdHJhdmVyc2VPYmogPSBmdW5jdGlvbiAob2JqLCBwYXRoLCBvblZhbHVlPykge1xyXG4gICAgaWYgKF9pc0FycmF5KG9iaikpIHtcclxuICAgICAgb25WYWx1ZSAmJiBvblZhbHVlKG9iaiwgcGF0aCk7XHJcbiAgICAgIG9iai5mb3JFYWNoKChpdGVtLCBpbmQpID0+IHtcclxuICAgICAgICBvblZhbHVlICYmIG9uVmFsdWUoaXRlbSwgcGF0aCArIFwiL1wiICsgaW5kKTtcclxuICAgICAgICB0cmF2ZXJzZU9iaihpdGVtLCBwYXRoICsgXCIvXCIgKyBpbmQsIG9uVmFsdWUpO1xyXG4gICAgICB9KTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgaWYgKF9pc1BsYWluT2JqZWN0KG9iaikpIHtcclxuICAgICAgb25WYWx1ZSAmJiBvblZhbHVlKG9iaiwgcGF0aCk7XHJcbiAgICAgIE9iamVjdC5rZXlzKG9iaikuZm9yRWFjaChrZXkgPT4ge1xyXG4gICAgICAgIG9uVmFsdWUgJiYgb25WYWx1ZShvYmpba2V5XSwgcGF0aCArIFwiL1wiICsga2V5KTtcclxuICAgICAgICB0cmF2ZXJzZU9iaihvYmpba2V5XSwgcGF0aCArIFwiL1wiICsga2V5LCBvblZhbHVlKTtcclxuICAgICAgfSk7XHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG4gIH1cclxuICB0cmF2ZXJzZU9iaihmb3JtRGF0YSwgXCJcIiwgKHZhbHVlLCBwYXRoKSA9PiB7XHJcbiAgICBpZiAoX2lzQXJyYXkodmFsdWUpKSB7XHJcbiAgICAgIGFyckxlbmd0aHNbcGF0aF0gPSBhcnJMZW5ndGhzW3BhdGhdIHx8IHZhbHVlLmxlbmd0aDtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgbGV0IGdldERhdGFTaXplID0gKG9wdGlvbnM6IGFueSkgPT4ge1xyXG4gICAgbGV0IHsgZGF0YSwgZGF0YVBvaW50ZXIsIGluZGV4QXJyYXkgfSA9IG9wdGlvbnM7XHJcbiAgICBsZXQgZGFzaENvdW50ID0gMDtcclxuICAgIGxldCBkcEluc3RhbmNlID0gZGF0YVBvaW50ZXIuc3Vic3RyaW5nKDEpLnNwbGl0KFwiL1wiKS5tYXAoKHBhcnQsIHBpbmQpID0+IHtcclxuICAgICAgaWYgKHBhcnQgPT0gXCItXCIgJiYgaW5kZXhBcnJheVtkYXNoQ291bnRdICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiBpbmRleEFycmF5W2Rhc2hDb3VudCsrXTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gcGFydDtcclxuICAgIH0pXHJcbiAgICAgIC5qb2luKFwiL1wiKTtcclxuICAgIGRwSW5zdGFuY2UgPSBcIi9cIiArIGRwSW5zdGFuY2U7XHJcbiAgICBsZXQgYXJyU2l6ZSA9IGFyckxlbmd0aHNbZHBJbnN0YW5jZV07XHJcbiAgICByZXR1cm4gYXJyU2l6ZTtcclxuICB9XHJcbiAgLy9zdGlsbCB0b28gYnVnZ3lcclxuICBsZXQgY3JlYXRlTm9uUmVmSXRlbSA9IChub2RlV2l0aFJlZjogYW55KSA9PiB7XHJcbiAgICBsZXQgdGVtcGxhdGVOb2RlID0ge1xyXG4gICAgICBcInR5cGVcIjogXCJzZWN0aW9uXCIsIC8vY2hlY2sgdGhpcyBjb3VsZCBhbHNvIGJlIGFycmF5P1xyXG4gICAgICBcInJlY3Vyc2l2ZVJlZmVyZW5jZVwiOiBmYWxzZSwvL2NoZWNrIHRoaXMgXHJcbiAgICAgIFwiaXRlbXNcIjogW11cclxuICAgIH1cclxuICAgIGxldCBjbG9uZSA9IGNsb25lRGVlcChub2RlV2l0aFJlZik7XHJcbiAgICAvL2NvbW1lbnRlZCBvdXQgZm9yIG5vdyBzbyB0aGF0IGl0IGJlaGF2ZXMgYXMgdXN1c2FsXHJcbiAgICAvL18ubWVyZ2UoY2xvbmUsdGVtcGxhdGVOb2RlKTtcclxuICAgIHJldHVybiBjbG9uZTtcclxuICB9XHJcblxyXG4gIGxldCByZWJ1aWxkTGF5b3V0ID0gKG9wdGlvbnM6IGFueSkgPT4ge1xyXG4gICAgbGV0IHsgYnVpbHRMYXlvdXQsIGluZGljZXMsIHBhcmVudERhdGFQb2ludGVyLCBpbmRleFBvcyB9ID0gb3B0aW9ucztcclxuICAgIGluZGljZXMgPSBpbmRpY2VzIHx8IFtdO1xyXG4gICAgaW5kZXhQb3MgPSBpbmRleFBvcyA9PSB1bmRlZmluZWQgPyBpbmRleFBvcyA9IC0xIDogaW5kZXhQb3M7XHJcbiAgICBpZiAoX2lzQXJyYXkoYnVpbHRMYXlvdXQpKSB7XHJcbiAgICAgIGJ1aWx0TGF5b3V0LmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XHJcbiAgICAgICAgcmVidWlsZExheW91dCh7XHJcbiAgICAgICAgICBidWlsdExheW91dDogaXRlbSxcclxuICAgICAgICAgIGluZGljZXM6IGluZGljZXMsXHJcbiAgICAgICAgICBpbmRleFBvczogaW5kZXhQb3MsXHJcbiAgICAgICAgICBwYXJlbnREYXRhUG9pbnRlcjogYnVpbHRMYXlvdXQuZGF0YVBvaW50ZXIgfHwgcGFyZW50RGF0YVBvaW50ZXJcclxuICAgICAgICB9KVxyXG4gICAgICB9KVxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgXHJcbiAgICBsZXQgZGF0YVR5cGVzPVtcImFycmF5XCJdOy8vY2hlY2sgb25seSBhcnJheSBmb3Igbm93XHJcbiAgICAgLy9mb3Igbm93IGFkZGVkIGNvbmRpdGlvbiB0byBpZ25vcmUgcmVjdXJzaXZlIHJlZmVyZW5jZXNcclxuICAgIGlmIChidWlsdExheW91dC5pdGVtcyAmJiBkYXRhVHlwZXMuaW5kZXhPZihidWlsdExheW91dC5kYXRhVHlwZSk+PTBcclxuICAgICAgJiYgYnVpbHRMYXlvdXQuZGF0YVBvaW50ZXJcclxuICAgICAgJiYgIWJ1aWx0TGF5b3V0LnJlY3Vyc2l2ZVJlZmVyZW5jZVxyXG4gICAgKSB7XHJcbiAgICAgIGxldCBudW1EYXRhSXRlbXM6IGFueSA9IGdldERhdGFTaXplKHtcclxuICAgICAgICBkYXRhOiBmb3JtRGF0YSxcclxuICAgICAgICBkYXRhUG9pbnRlcjogYnVpbHRMYXlvdXQuZGF0YVBvaW50ZXIsXHJcbiAgICAgICAgaW5kZXhBcnJheTogaW5kaWNlc1xyXG4gICAgICB9KTtcclxuICAgICAgbGV0IG51bUFjdHVhbEl0ZW1zID0gYnVpbHRMYXlvdXQuaXRlbXMubGVuZ3RoO1xyXG4gICAgICAvL2NoZWNrIGlmIHRoZXJlJ3MgcmVmIGl0ZW1zLCBpZiBzbyBpZ25vcmUgaXQgYW5kIHRoZXJlZm9yZVxyXG4gICAgICAvL2RlY3JlbWVudCB0aGUgaXRlbSBjb3VudFxyXG4gICAgICBidWlsdExheW91dC5pdGVtcy5mb3JFYWNoKGl0ZW0gPT4ge1xyXG4gICAgICAgIGlmIChpdGVtLnR5cGUgJiYgaXRlbS50eXBlID09IFwiJHJlZlwiKSB7XHJcbiAgICAgICAgICBudW1BY3R1YWxJdGVtcy0tO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIG51bUFjdHVhbEl0ZW1zID0gTWF0aC5tYXgobnVtQWN0dWFsSXRlbXMsIDApOy8vYXZvaWQgZGVhbGluZyB3aXRoIG5lZ2F0aXZlc1xyXG4gICAgICBpZiAobnVtQWN0dWFsSXRlbXMgPCBudW1EYXRhSXRlbXMpIHtcclxuXHJcbiAgICAgICAgbGV0IG51bUl0ZW1zTmVlZGVkID0gbnVtRGF0YUl0ZW1zIC0gbnVtQWN0dWFsSXRlbXM7XHJcbiAgICAgICAgLy9hZGRlZCB0byBpZ25vcmUgcmVjdXJzaXZlIHJlZmVyZW5jZXNcclxuICAgICAgICBpZiAobnVtQWN0dWFsSXRlbXMgPT0gMCAmJiBidWlsdExheW91dC5pdGVtc1swXS5yZWN1cnNpdmVSZWZlcmVuY2UpIHtcclxuICAgICAgICAgIG51bUl0ZW1zTmVlZGVkID0gMFxyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bUl0ZW1zTmVlZGVkOyBpKyspIHtcclxuICAgICAgICAgIC8vbm9kZSBtdXN0IG5vdCBiZSBvZiB0eXBlIFwidHlwZVwiOiBcIiRyZWZcIlxyXG4gICAgICAgICAgLy9pZiBpdCBpcyB0aGVuIG1hbnVmYWN0dXJlIG91ciBvd25cclxuICAgICAgICAgIGxldCBpc1JlZk5vZGUgPSBidWlsdExheW91dC5pdGVtc1swXS50eXBlICYmIGJ1aWx0TGF5b3V0Lml0ZW1zWzBdLnR5cGUgPT0gXCIkcmVmXCI7XHJcbiAgICAgICAgICBsZXQgbmV3SXRlbSA9IGlzUmVmTm9kZVxyXG4gICAgICAgICAgICA/IGNyZWF0ZU5vblJlZkl0ZW0oYnVpbHRMYXlvdXQuaXRlbXNbMF0pXHJcbiAgICAgICAgICAgIDogY2xvbmVEZWVwKGJ1aWx0TGF5b3V0Lml0ZW1zWzBdKTsvL2NvcHkgZmlyc3RcclxuICAgICAgICAgIG5ld0l0ZW0uX2lkID0gdW5pcXVlSWQoXCJuZXdfXCIpO1xyXG4gICAgICAgICAgYnVpbHRMYXlvdXQuaXRlbXMudW5zaGlmdChuZXdJdGVtKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJ1aWx0TGF5b3V0Lm9wdGlvbnMubGlzdEl0ZW1zKSB7XHJcbiAgICAgICAgICBidWlsdExheW91dC5vcHRpb25zLmxpc3RJdGVtcyA9IG51bURhdGFJdGVtcztcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgaW5kaWNlc1tidWlsdExheW91dC5kYXRhUG9pbnRlcl0gPSBpbmRpY2VzW2J1aWx0TGF5b3V0LmRhdGFQb2ludGVyXSB8fCAtMTtcclxuICAgICAgaW5kZXhQb3MrKztcclxuICAgICAgYnVpbHRMYXlvdXQuaXRlbXMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcclxuICAgICAgICBpbmRpY2VzW2luZGV4UG9zXSA9IGluZGV4XHJcbiAgICAgICAgcmVidWlsZExheW91dCh7XHJcbiAgICAgICAgICBidWlsdExheW91dDogaXRlbSxcclxuICAgICAgICAgIGluZGljZXM6IGluZGljZXMsXHJcbiAgICAgICAgICBwYXJlbnREYXRhUG9pbnRlcjogYnVpbHRMYXlvdXQuZGF0YVBvaW50ZXIsXHJcbiAgICAgICAgICBpbmRleFBvczogaW5kZXhQb3NcclxuICAgICAgICB9KVxyXG4gICAgICB9KVxyXG4gICAgICBpbmRleFBvcy0tO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKGJ1aWx0TGF5b3V0Lml0ZW1zKSB7XHJcbiAgICAgICAgYnVpbHRMYXlvdXQuaXRlbXMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgIHJlYnVpbGRMYXlvdXQoe1xyXG4gICAgICAgICAgICBidWlsdExheW91dDogaXRlbSxcclxuICAgICAgICAgICAgaW5kaWNlczogaW5kaWNlcyxcclxuICAgICAgICAgICAgcGFyZW50RGF0YVBvaW50ZXI6IHBhcmVudERhdGFQb2ludGVyLFxyXG4gICAgICAgICAgICBpbmRleFBvczogaW5kZXhQb3NcclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgfSlcclxuXHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG4gIH1cclxuICByZWJ1aWxkTGF5b3V0KHtcclxuICAgIGJ1aWx0TGF5b3V0OiBidWlsdExheW91dFxyXG4gIH0pO1xyXG4gIC8vTkIgb3JpZ2luYWwgaXMgbXV0YXRlZFxyXG4gIGxldCBmaXhlZExheW91dCA9IGJ1aWx0TGF5b3V0O1xyXG4gIHJldHVybiBmaXhlZExheW91dDtcclxufVxyXG5cclxuLyoqXHJcbiAqICdidWlsZExheW91dEZyb21TY2hlbWEnIGZ1bmN0aW9uXHJcbiAqXHJcbiAqIC8vICAganNmIC1cclxuICogLy8gICB3aWRnZXRMaWJyYXJ5IC1cclxuICogLy8gICBub2RlVmFsdWUgLVxyXG4gKiAvLyAgeyBzdHJpbmcgPSAnJyB9IHNjaGVtYVBvaW50ZXIgLVxyXG4gKiAvLyAgeyBzdHJpbmcgPSAnJyB9IGRhdGFQb2ludGVyIC1cclxuICogLy8gIHsgYm9vbGVhbiA9IGZhbHNlIH0gYXJyYXlJdGVtIC1cclxuICogLy8gIHsgc3RyaW5nID0gbnVsbCB9IGFycmF5SXRlbVR5cGUgLVxyXG4gKiAvLyAgeyBib29sZWFuID0gbnVsbCB9IHJlbW92YWJsZSAtXHJcbiAqIC8vICB7IGJvb2xlYW4gPSBmYWxzZSB9IGZvclJlZkxpYnJhcnkgLVxyXG4gKiAvLyAgeyBzdHJpbmcgPSAnJyB9IGRhdGFQb2ludGVyUHJlZml4IC1cclxuICogLy9cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBidWlsZExheW91dEZyb21TY2hlbWEoXHJcbiAganNmLCB3aWRnZXRMaWJyYXJ5LCBub2RlVmFsdWUgPSBudWxsLCBzY2hlbWFQb2ludGVyID0gJycsXHJcbiAgZGF0YVBvaW50ZXIgPSAnJywgYXJyYXlJdGVtID0gZmFsc2UsIGFycmF5SXRlbVR5cGU6IHN0cmluZyA9IG51bGwsXHJcbiAgcmVtb3ZhYmxlOiBib29sZWFuID0gbnVsbCwgZm9yUmVmTGlicmFyeSA9IGZhbHNlLCBkYXRhUG9pbnRlclByZWZpeCA9ICcnXHJcbikge1xyXG4gIGNvbnN0IHNjaGVtYSA9IEpzb25Qb2ludGVyLmdldChqc2Yuc2NoZW1hLCBzY2hlbWFQb2ludGVyKTtcclxuICBpZiAoIWhhc093bihzY2hlbWEsICd0eXBlJykgJiYgIWhhc093bihzY2hlbWEsICckcmVmJykgJiZcclxuICAgICFoYXNPd24oc2NoZW1hLCAneC1zY2hlbWEtZm9ybScpXHJcbiAgKSB7IHJldHVybiBudWxsOyB9XHJcbiAgY29uc3QgbmV3Tm9kZVR5cGU6IHN0cmluZyA9IGdldElucHV0VHlwZShzY2hlbWEpO1xyXG4gIGlmICghaXNEZWZpbmVkKG5vZGVWYWx1ZSkgJiYgKFxyXG4gICAganNmLmZvcm1PcHRpb25zLnNldFNjaGVtYURlZmF1bHRzID09PSB0cnVlIHx8XHJcbiAgICAoanNmLmZvcm1PcHRpb25zLnNldFNjaGVtYURlZmF1bHRzID09PSAnYXV0bycgJiYgaXNFbXB0eShqc2YuZm9ybVZhbHVlcykpXHJcbiAgKSkge1xyXG4gICAgbm9kZVZhbHVlID0gSnNvblBvaW50ZXIuZ2V0KGpzZi5zY2hlbWEsIHNjaGVtYVBvaW50ZXIgKyAnL2RlZmF1bHQnKTtcclxuICB9XHJcbiAgbGV0IG5ld05vZGU6IGFueSA9IHtcclxuICAgIF9pZDogZm9yUmVmTGlicmFyeSA/IG51bGwgOiB1bmlxdWVJZCgpLFxyXG4gICAgYXJyYXlJdGVtOiBhcnJheUl0ZW0sXHJcbiAgICBkYXRhUG9pbnRlcjogSnNvblBvaW50ZXIudG9HZW5lcmljUG9pbnRlcihkYXRhUG9pbnRlciwganNmLmFycmF5TWFwKSxcclxuICAgIGRhdGFUeXBlOiBzY2hlbWEudHlwZSB8fCAoaGFzT3duKHNjaGVtYSwgJyRyZWYnKSA/ICckcmVmJyA6IG51bGwpLFxyXG4gICAgb3B0aW9uczoge30sXHJcbiAgICByZXF1aXJlZDogaXNJbnB1dFJlcXVpcmVkKGpzZi5zY2hlbWEsIHNjaGVtYVBvaW50ZXIpLFxyXG4gICAgdHlwZTogbmV3Tm9kZVR5cGUsXHJcbiAgICB3aWRnZXQ6IHdpZGdldExpYnJhcnkuZ2V0V2lkZ2V0KG5ld05vZGVUeXBlKSxcclxuICB9O1xyXG4gIGNvbnN0IGxhc3REYXRhS2V5ID0gSnNvblBvaW50ZXIudG9LZXkobmV3Tm9kZS5kYXRhUG9pbnRlcik7XHJcbiAgaWYgKGxhc3REYXRhS2V5ICE9PSAnLScpIHsgbmV3Tm9kZS5uYW1lID0gbGFzdERhdGFLZXk7IH1cclxuICBpZiAobmV3Tm9kZS5hcnJheUl0ZW0pIHtcclxuICAgIG5ld05vZGUuYXJyYXlJdGVtVHlwZSA9IGFycmF5SXRlbVR5cGU7XHJcbiAgICBuZXdOb2RlLm9wdGlvbnMucmVtb3ZhYmxlID0gcmVtb3ZhYmxlICE9PSBmYWxzZTtcclxuICB9XHJcbiAgY29uc3Qgc2hvcnREYXRhUG9pbnRlciA9IHJlbW92ZVJlY3Vyc2l2ZVJlZmVyZW5jZXMoXHJcbiAgICBkYXRhUG9pbnRlclByZWZpeCArIGRhdGFQb2ludGVyLCBqc2YuZGF0YVJlY3Vyc2l2ZVJlZk1hcCwganNmLmFycmF5TWFwXHJcbiAgKTtcclxuICBjb25zdCByZWN1cnNpdmUgPSAhc2hvcnREYXRhUG9pbnRlci5sZW5ndGggfHxcclxuICAgIHNob3J0RGF0YVBvaW50ZXIgIT09IGRhdGFQb2ludGVyUHJlZml4ICsgZGF0YVBvaW50ZXI7XHJcbiAgaWYgKCFqc2YuZGF0YU1hcC5oYXMoc2hvcnREYXRhUG9pbnRlcikpIHtcclxuICAgIGpzZi5kYXRhTWFwLnNldChzaG9ydERhdGFQb2ludGVyLCBuZXcgTWFwKCkpO1xyXG4gIH1cclxuICBjb25zdCBub2RlRGF0YU1hcCA9IGpzZi5kYXRhTWFwLmdldChzaG9ydERhdGFQb2ludGVyKTtcclxuICBpZiAoIW5vZGVEYXRhTWFwLmhhcygnaW5wdXRUeXBlJykpIHtcclxuICAgIG5vZGVEYXRhTWFwLnNldCgnc2NoZW1hUG9pbnRlcicsIHNjaGVtYVBvaW50ZXIpO1xyXG4gICAgbm9kZURhdGFNYXAuc2V0KCdpbnB1dFR5cGUnLCBuZXdOb2RlLnR5cGUpO1xyXG4gICAgbm9kZURhdGFNYXAuc2V0KCd3aWRnZXQnLCBuZXdOb2RlLndpZGdldCk7XHJcbiAgICBub2RlRGF0YU1hcC5zZXQoJ2Rpc2FibGVkJywgISFuZXdOb2RlLm9wdGlvbnMuZGlzYWJsZWQpO1xyXG4gIH1cclxuICB1cGRhdGVJbnB1dE9wdGlvbnMobmV3Tm9kZSwgc2NoZW1hLCBqc2YpO1xyXG4gIGlmICghbmV3Tm9kZS5vcHRpb25zLnRpdGxlICYmIG5ld05vZGUubmFtZSAmJiAhL15cXGQrJC8udGVzdChuZXdOb2RlLm5hbWUpKSB7XHJcbiAgICBuZXdOb2RlLm9wdGlvbnMudGl0bGUgPSBmaXhUaXRsZShuZXdOb2RlLm5hbWUpO1xyXG4gIH1cclxuXHJcbiAgaWYgKG5ld05vZGUuZGF0YVR5cGUgPT09ICdvYmplY3QnKSB7XHJcbiAgICBpZiAoaXNBcnJheShzY2hlbWEucmVxdWlyZWQpICYmICFub2RlRGF0YU1hcC5oYXMoJ3JlcXVpcmVkJykpIHtcclxuICAgICAgbm9kZURhdGFNYXAuc2V0KCdyZXF1aXJlZCcsIHNjaGVtYS5yZXF1aXJlZCk7XHJcbiAgICB9XHJcbiAgICBpZiAoaXNPYmplY3Qoc2NoZW1hLnByb3BlcnRpZXMpKSB7XHJcbiAgICAgIGNvbnN0IG5ld1NlY3Rpb246IGFueVtdID0gW107XHJcbiAgICAgIGNvbnN0IHByb3BlcnR5S2V5cyA9IHNjaGVtYVsndWk6b3JkZXInXSB8fCBPYmplY3Qua2V5cyhzY2hlbWEucHJvcGVydGllcyk7XHJcbiAgICAgIGlmIChwcm9wZXJ0eUtleXMuaW5jbHVkZXMoJyonKSAmJiAhaGFzT3duKHNjaGVtYS5wcm9wZXJ0aWVzLCAnKicpKSB7XHJcbiAgICAgICAgY29uc3QgdW5uYW1lZEtleXMgPSBPYmplY3Qua2V5cyhzY2hlbWEucHJvcGVydGllcylcclxuICAgICAgICAgIC5maWx0ZXIoa2V5ID0+ICFwcm9wZXJ0eUtleXMuaW5jbHVkZXMoa2V5KSk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IHByb3BlcnR5S2V5cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgICAgaWYgKHByb3BlcnR5S2V5c1tpXSA9PT0gJyonKSB7XHJcbiAgICAgICAgICAgIHByb3BlcnR5S2V5cy5zcGxpY2UoaSwgMSwgLi4udW5uYW1lZEtleXMpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBwcm9wZXJ0eUtleXNcclxuICAgICAgICAuZmlsdGVyKGtleSA9PiBoYXNPd24oc2NoZW1hLnByb3BlcnRpZXMsIGtleSkgfHxcclxuICAgICAgICAgIGhhc093bihzY2hlbWEsICdhZGRpdGlvbmFsUHJvcGVydGllcycpXHJcbiAgICAgICAgKVxyXG4gICAgICAgIC5mb3JFYWNoKGtleSA9PiB7XHJcbiAgICAgICAgICBjb25zdCBrZXlTY2hlbWFQb2ludGVyID0gaGFzT3duKHNjaGVtYS5wcm9wZXJ0aWVzLCBrZXkpID9cclxuICAgICAgICAgICAgJy9wcm9wZXJ0aWVzLycgKyBrZXkgOiAnL2FkZGl0aW9uYWxQcm9wZXJ0aWVzJztcclxuICAgICAgICAgIGNvbnN0IGlubmVySXRlbSA9IGJ1aWxkTGF5b3V0RnJvbVNjaGVtYShcclxuICAgICAgICAgICAganNmLCB3aWRnZXRMaWJyYXJ5LCBpc09iamVjdChub2RlVmFsdWUpID8gbm9kZVZhbHVlW2tleV0gOiBudWxsLFxyXG4gICAgICAgICAgICBzY2hlbWFQb2ludGVyICsga2V5U2NoZW1hUG9pbnRlcixcclxuICAgICAgICAgICAgZGF0YVBvaW50ZXIgKyAnLycgKyBrZXksXHJcbiAgICAgICAgICAgIGZhbHNlLCBudWxsLCBudWxsLCBmb3JSZWZMaWJyYXJ5LCBkYXRhUG9pbnRlclByZWZpeFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIGlmIChpbm5lckl0ZW0pIHtcclxuICAgICAgICAgICAgaWYgKGlzSW5wdXRSZXF1aXJlZChzY2hlbWEsICcvJyArIGtleSkpIHtcclxuICAgICAgICAgICAgICBpbm5lckl0ZW0ub3B0aW9ucy5yZXF1aXJlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAganNmLmZpZWxkc1JlcXVpcmVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBuZXdTZWN0aW9uLnB1c2goaW5uZXJJdGVtKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgaWYgKGRhdGFQb2ludGVyID09PSAnJyAmJiAhZm9yUmVmTGlicmFyeSkge1xyXG4gICAgICAgIG5ld05vZGUgPSBuZXdTZWN0aW9uO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG5ld05vZGUuaXRlbXMgPSBuZXdTZWN0aW9uO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBUT0RPOiBBZGQgcGF0dGVyblByb3BlcnRpZXMgYW5kIGFkZGl0aW9uYWxQcm9wZXJ0aWVzIGlucHV0cz9cclxuICAgIC8vIC4uLiBwb3NzaWJseSBwcm92aWRlIGEgd2F5IHRvIGVudGVyIGJvdGgga2V5IG5hbWVzIGFuZCB2YWx1ZXM/XHJcbiAgICAvLyBpZiAoaXNPYmplY3Qoc2NoZW1hLnBhdHRlcm5Qcm9wZXJ0aWVzKSkgeyB9XHJcbiAgICAvLyBpZiAoaXNPYmplY3Qoc2NoZW1hLmFkZGl0aW9uYWxQcm9wZXJ0aWVzKSkgeyB9XHJcblxyXG4gIH0gZWxzZSBpZiAobmV3Tm9kZS5kYXRhVHlwZSA9PT0gJ2FycmF5Jykge1xyXG4gICAgbmV3Tm9kZS5pdGVtcyA9IFtdO1xyXG4gICAgbmV3Tm9kZS5vcHRpb25zLm1heEl0ZW1zID0gTWF0aC5taW4oXHJcbiAgICAgIHNjaGVtYS5tYXhJdGVtcyB8fCAxMDAwLCBuZXdOb2RlLm9wdGlvbnMubWF4SXRlbXMgfHwgMTAwMFxyXG4gICAgKTtcclxuICAgIG5ld05vZGUub3B0aW9ucy5taW5JdGVtcyA9IE1hdGgubWF4KFxyXG4gICAgICBzY2hlbWEubWluSXRlbXMgfHwgMCwgbmV3Tm9kZS5vcHRpb25zLm1pbkl0ZW1zIHx8IDBcclxuICAgICk7XHJcbiAgICBpZiAoIW5ld05vZGUub3B0aW9ucy5taW5JdGVtcyAmJiBpc0lucHV0UmVxdWlyZWQoanNmLnNjaGVtYSwgc2NoZW1hUG9pbnRlcikpIHtcclxuICAgICAgbmV3Tm9kZS5vcHRpb25zLm1pbkl0ZW1zID0gMTtcclxuICAgIH1cclxuICAgIGlmICghaGFzT3duKG5ld05vZGUub3B0aW9ucywgJ2xpc3RJdGVtcycpKSB7IG5ld05vZGUub3B0aW9ucy5saXN0SXRlbXMgPSAxOyB9XHJcbiAgICBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcyA9IGlzQXJyYXkoc2NoZW1hLml0ZW1zKSA/IHNjaGVtYS5pdGVtcy5sZW5ndGggOiAwO1xyXG4gICAgaWYgKG5ld05vZGUub3B0aW9ucy5tYXhJdGVtcyA8PSBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcykge1xyXG4gICAgICBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcyA9IG5ld05vZGUub3B0aW9ucy5tYXhJdGVtcztcclxuICAgICAgbmV3Tm9kZS5vcHRpb25zLmxpc3RJdGVtcyA9IDA7XHJcbiAgICB9IGVsc2UgaWYgKG5ld05vZGUub3B0aW9ucy5tYXhJdGVtcyA8XHJcbiAgICAgIG5ld05vZGUub3B0aW9ucy50dXBsZUl0ZW1zICsgbmV3Tm9kZS5vcHRpb25zLmxpc3RJdGVtc1xyXG4gICAgKSB7XHJcbiAgICAgIG5ld05vZGUub3B0aW9ucy5saXN0SXRlbXMgPSBuZXdOb2RlLm9wdGlvbnMubWF4SXRlbXMgLSBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcztcclxuICAgIH0gZWxzZSBpZiAobmV3Tm9kZS5vcHRpb25zLm1pbkl0ZW1zID5cclxuICAgICAgbmV3Tm9kZS5vcHRpb25zLnR1cGxlSXRlbXMgKyBuZXdOb2RlLm9wdGlvbnMubGlzdEl0ZW1zXHJcbiAgICApIHtcclxuICAgICAgbmV3Tm9kZS5vcHRpb25zLmxpc3RJdGVtcyA9IG5ld05vZGUub3B0aW9ucy5taW5JdGVtcyAtIG5ld05vZGUub3B0aW9ucy50dXBsZUl0ZW1zO1xyXG4gICAgfVxyXG4gICAgaWYgKCFub2RlRGF0YU1hcC5oYXMoJ21heEl0ZW1zJykpIHtcclxuICAgICAgbm9kZURhdGFNYXAuc2V0KCdtYXhJdGVtcycsIG5ld05vZGUub3B0aW9ucy5tYXhJdGVtcyk7XHJcbiAgICAgIG5vZGVEYXRhTWFwLnNldCgnbWluSXRlbXMnLCBuZXdOb2RlLm9wdGlvbnMubWluSXRlbXMpO1xyXG4gICAgICBub2RlRGF0YU1hcC5zZXQoJ3R1cGxlSXRlbXMnLCBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcyk7XHJcbiAgICAgIG5vZGVEYXRhTWFwLnNldCgnbGlzdEl0ZW1zJywgbmV3Tm9kZS5vcHRpb25zLmxpc3RJdGVtcyk7XHJcbiAgICB9XHJcbiAgICBpZiAoIWpzZi5hcnJheU1hcC5oYXMoc2hvcnREYXRhUG9pbnRlcikpIHtcclxuICAgICAganNmLmFycmF5TWFwLnNldChzaG9ydERhdGFQb2ludGVyLCBuZXdOb2RlLm9wdGlvbnMudHVwbGVJdGVtcyk7XHJcbiAgICB9XHJcbiAgICByZW1vdmFibGUgPSBuZXdOb2RlLm9wdGlvbnMucmVtb3ZhYmxlICE9PSBmYWxzZTtcclxuICAgIGxldCBhZGRpdGlvbmFsSXRlbXNTY2hlbWFQb2ludGVyOiBzdHJpbmcgPSBudWxsO1xyXG5cclxuICAgIC8vIElmICdpdGVtcycgaXMgYW4gYXJyYXkgPSB0dXBsZSBpdGVtc1xyXG4gICAgaWYgKGlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xyXG4gICAgICBuZXdOb2RlLml0ZW1zID0gW107XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmV3Tm9kZS5vcHRpb25zLnR1cGxlSXRlbXM7IGkrKykge1xyXG4gICAgICAgIGxldCBuZXdJdGVtOiBhbnk7XHJcbiAgICAgICAgY29uc3QgaXRlbVJlZlBvaW50ZXIgPSByZW1vdmVSZWN1cnNpdmVSZWZlcmVuY2VzKFxyXG4gICAgICAgICAgc2hvcnREYXRhUG9pbnRlciArICcvJyArIGksIGpzZi5kYXRhUmVjdXJzaXZlUmVmTWFwLCBqc2YuYXJyYXlNYXBcclxuICAgICAgICApO1xyXG4gICAgICAgIGNvbnN0IGl0ZW1SZWN1cnNpdmUgPSAhaXRlbVJlZlBvaW50ZXIubGVuZ3RoIHx8XHJcbiAgICAgICAgICBpdGVtUmVmUG9pbnRlciAhPT0gc2hvcnREYXRhUG9pbnRlciArICcvJyArIGk7XHJcblxyXG4gICAgICAgIC8vIElmIHJlbW92YWJsZSwgYWRkIHR1cGxlIGl0ZW0gbGF5b3V0IHRvIGxheW91dFJlZkxpYnJhcnlcclxuICAgICAgICBpZiAocmVtb3ZhYmxlICYmIGkgPj0gbmV3Tm9kZS5vcHRpb25zLm1pbkl0ZW1zKSB7XHJcbiAgICAgICAgICBpZiAoIWhhc093bihqc2YubGF5b3V0UmVmTGlicmFyeSwgaXRlbVJlZlBvaW50ZXIpKSB7XHJcbiAgICAgICAgICAgIC8vIFNldCB0byBudWxsIGZpcnN0IHRvIHByZXZlbnQgcmVjdXJzaXZlIHJlZmVyZW5jZSBmcm9tIGNhdXNpbmcgZW5kbGVzcyBsb29wXHJcbiAgICAgICAgICAgIGpzZi5sYXlvdXRSZWZMaWJyYXJ5W2l0ZW1SZWZQb2ludGVyXSA9IG51bGw7XHJcbiAgICAgICAgICAgIGpzZi5sYXlvdXRSZWZMaWJyYXJ5W2l0ZW1SZWZQb2ludGVyXSA9IGJ1aWxkTGF5b3V0RnJvbVNjaGVtYShcclxuICAgICAgICAgICAgICBqc2YsIHdpZGdldExpYnJhcnksIGlzQXJyYXkobm9kZVZhbHVlKSA/IG5vZGVWYWx1ZVtpXSA6IG51bGwsXHJcbiAgICAgICAgICAgICAgc2NoZW1hUG9pbnRlciArICcvaXRlbXMvJyArIGksXHJcbiAgICAgICAgICAgICAgaXRlbVJlY3Vyc2l2ZSA/ICcnIDogZGF0YVBvaW50ZXIgKyAnLycgKyBpLFxyXG4gICAgICAgICAgICAgIHRydWUsICd0dXBsZScsIHRydWUsIHRydWUsIGl0ZW1SZWN1cnNpdmUgPyBkYXRhUG9pbnRlciArICcvJyArIGkgOiAnJ1xyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICBpZiAoaXRlbVJlY3Vyc2l2ZSkge1xyXG4gICAgICAgICAgICAgIGpzZi5sYXlvdXRSZWZMaWJyYXJ5W2l0ZW1SZWZQb2ludGVyXS5yZWN1cnNpdmVSZWZlcmVuY2UgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBuZXdJdGVtID0gZ2V0TGF5b3V0Tm9kZSh7XHJcbiAgICAgICAgICAgICRyZWY6IGl0ZW1SZWZQb2ludGVyLFxyXG4gICAgICAgICAgICBkYXRhUG9pbnRlcjogZGF0YVBvaW50ZXIgKyAnLycgKyBpLFxyXG4gICAgICAgICAgICByZWN1cnNpdmVSZWZlcmVuY2U6IGl0ZW1SZWN1cnNpdmUsXHJcbiAgICAgICAgICB9LCBqc2YsIHdpZGdldExpYnJhcnksIGlzQXJyYXkobm9kZVZhbHVlKSA/IG5vZGVWYWx1ZVtpXSA6IG51bGwpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBuZXdJdGVtID0gYnVpbGRMYXlvdXRGcm9tU2NoZW1hKFxyXG4gICAgICAgICAgICBqc2YsIHdpZGdldExpYnJhcnksIGlzQXJyYXkobm9kZVZhbHVlKSA/IG5vZGVWYWx1ZVtpXSA6IG51bGwsXHJcbiAgICAgICAgICAgIHNjaGVtYVBvaW50ZXIgKyAnL2l0ZW1zLycgKyBpLFxyXG4gICAgICAgICAgICBkYXRhUG9pbnRlciArICcvJyArIGksXHJcbiAgICAgICAgICAgIHRydWUsICd0dXBsZScsIGZhbHNlLCBmb3JSZWZMaWJyYXJ5LCBkYXRhUG9pbnRlclByZWZpeFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKG5ld0l0ZW0pIHsgbmV3Tm9kZS5pdGVtcy5wdXNoKG5ld0l0ZW0pOyB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIElmICdhZGRpdGlvbmFsSXRlbXMnIGlzIGFuIG9iamVjdCA9IGFkZGl0aW9uYWwgbGlzdCBpdGVtcywgYWZ0ZXIgdHVwbGUgaXRlbXNcclxuICAgICAgaWYgKGlzT2JqZWN0KHNjaGVtYS5hZGRpdGlvbmFsSXRlbXMpKSB7XHJcbiAgICAgICAgYWRkaXRpb25hbEl0ZW1zU2NoZW1hUG9pbnRlciA9IHNjaGVtYVBvaW50ZXIgKyAnL2FkZGl0aW9uYWxJdGVtcyc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIElmICdpdGVtcycgaXMgYW4gb2JqZWN0ID0gbGlzdCBpdGVtcyBvbmx5IChubyB0dXBsZSBpdGVtcylcclxuICAgIH0gZWxzZSBpZiAoaXNPYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xyXG4gICAgICBhZGRpdGlvbmFsSXRlbXNTY2hlbWFQb2ludGVyID0gc2NoZW1hUG9pbnRlciArICcvaXRlbXMnO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChhZGRpdGlvbmFsSXRlbXNTY2hlbWFQb2ludGVyKSB7XHJcbiAgICAgIGNvbnN0IGl0ZW1SZWZQb2ludGVyID0gcmVtb3ZlUmVjdXJzaXZlUmVmZXJlbmNlcyhcclxuICAgICAgICBzaG9ydERhdGFQb2ludGVyICsgJy8tJywganNmLmRhdGFSZWN1cnNpdmVSZWZNYXAsIGpzZi5hcnJheU1hcFxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCBpdGVtUmVjdXJzaXZlID0gIWl0ZW1SZWZQb2ludGVyLmxlbmd0aCB8fFxyXG4gICAgICAgIGl0ZW1SZWZQb2ludGVyICE9PSBzaG9ydERhdGFQb2ludGVyICsgJy8tJztcclxuICAgICAgY29uc3QgaXRlbVNjaGVtYVBvaW50ZXIgPSByZW1vdmVSZWN1cnNpdmVSZWZlcmVuY2VzKFxyXG4gICAgICAgIGFkZGl0aW9uYWxJdGVtc1NjaGVtYVBvaW50ZXIsIGpzZi5zY2hlbWFSZWN1cnNpdmVSZWZNYXAsIGpzZi5hcnJheU1hcFxyXG4gICAgICApO1xyXG4gICAgICAvLyBBZGQgbGlzdCBpdGVtIGxheW91dCB0byBsYXlvdXRSZWZMaWJyYXJ5XHJcbiAgICAgIGlmIChpdGVtUmVmUG9pbnRlci5sZW5ndGggJiYgIWhhc093bihqc2YubGF5b3V0UmVmTGlicmFyeSwgaXRlbVJlZlBvaW50ZXIpKSB7XHJcbiAgICAgICAgLy8gU2V0IHRvIG51bGwgZmlyc3QgdG8gcHJldmVudCByZWN1cnNpdmUgcmVmZXJlbmNlIGZyb20gY2F1c2luZyBlbmRsZXNzIGxvb3BcclxuICAgICAgICBqc2YubGF5b3V0UmVmTGlicmFyeVtpdGVtUmVmUG9pbnRlcl0gPSBudWxsO1xyXG4gICAgICAgIGpzZi5sYXlvdXRSZWZMaWJyYXJ5W2l0ZW1SZWZQb2ludGVyXSA9IGJ1aWxkTGF5b3V0RnJvbVNjaGVtYShcclxuICAgICAgICAgIGpzZiwgd2lkZ2V0TGlicmFyeSwgbnVsbCxcclxuICAgICAgICAgIGl0ZW1TY2hlbWFQb2ludGVyLFxyXG4gICAgICAgICAgaXRlbVJlY3Vyc2l2ZSA/ICcnIDogZGF0YVBvaW50ZXIgKyAnLy0nLFxyXG4gICAgICAgICAgdHJ1ZSwgJ2xpc3QnLCByZW1vdmFibGUsIHRydWUsIGl0ZW1SZWN1cnNpdmUgPyBkYXRhUG9pbnRlciArICcvLScgOiAnJ1xyXG4gICAgICAgICk7XHJcbiAgICAgICAgaWYgKGl0ZW1SZWN1cnNpdmUpIHtcclxuICAgICAgICAgIGpzZi5sYXlvdXRSZWZMaWJyYXJ5W2l0ZW1SZWZQb2ludGVyXS5yZWN1cnNpdmVSZWZlcmVuY2UgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gQWRkIGFueSBhZGRpdGlvbmFsIGRlZmF1bHQgaXRlbXNcclxuICAgICAgaWYgKCFpdGVtUmVjdXJzaXZlIHx8IG5ld05vZGUub3B0aW9ucy5yZXF1aXJlZCkge1xyXG4gICAgICAgIGNvbnN0IGFycmF5TGVuZ3RoID0gTWF0aC5taW4oTWF0aC5tYXgoXHJcbiAgICAgICAgICBpdGVtUmVjdXJzaXZlID8gMCA6XHJcbiAgICAgICAgICAgIG5ld05vZGUub3B0aW9ucy50dXBsZUl0ZW1zICsgbmV3Tm9kZS5vcHRpb25zLmxpc3RJdGVtcyxcclxuICAgICAgICAgIGlzQXJyYXkobm9kZVZhbHVlKSA/IG5vZGVWYWx1ZS5sZW5ndGggOiAwXHJcbiAgICAgICAgKSwgbmV3Tm9kZS5vcHRpb25zLm1heEl0ZW1zKTtcclxuICAgICAgICBpZiAobmV3Tm9kZS5pdGVtcy5sZW5ndGggPCBhcnJheUxlbmd0aCkge1xyXG4gICAgICAgICAgZm9yIChsZXQgaSA9IG5ld05vZGUuaXRlbXMubGVuZ3RoOyBpIDwgYXJyYXlMZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBuZXdOb2RlLml0ZW1zLnB1c2goZ2V0TGF5b3V0Tm9kZSh7XHJcbiAgICAgICAgICAgICAgJHJlZjogaXRlbVJlZlBvaW50ZXIsXHJcbiAgICAgICAgICAgICAgZGF0YVBvaW50ZXI6IGRhdGFQb2ludGVyICsgJy8tJyxcclxuICAgICAgICAgICAgICByZWN1cnNpdmVSZWZlcmVuY2U6IGl0ZW1SZWN1cnNpdmUsXHJcbiAgICAgICAgICAgIH0sIGpzZiwgd2lkZ2V0TGlicmFyeSwgaXNBcnJheShub2RlVmFsdWUpID8gbm9kZVZhbHVlW2ldIDogbnVsbCkpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gSWYgbmVlZGVkLCBhZGQgYnV0dG9uIHRvIGFkZCBpdGVtcyB0byBhcnJheVxyXG4gICAgICBpZiAobmV3Tm9kZS5vcHRpb25zLmFkZGFibGUgIT09IGZhbHNlICYmXHJcbiAgICAgICAgbmV3Tm9kZS5vcHRpb25zLm1pbkl0ZW1zIDwgbmV3Tm9kZS5vcHRpb25zLm1heEl0ZW1zICYmXHJcbiAgICAgICAgKG5ld05vZGUuaXRlbXNbbmV3Tm9kZS5pdGVtcy5sZW5ndGggLSAxXSB8fCB7fSkudHlwZSAhPT0gJyRyZWYnXHJcbiAgICAgICkge1xyXG4gICAgICAgIGxldCBidXR0b25UZXh0ID1cclxuICAgICAgICAgICgoanNmLmxheW91dFJlZkxpYnJhcnlbaXRlbVJlZlBvaW50ZXJdIHx8IHt9KS5vcHRpb25zIHx8IHt9KS50aXRsZTtcclxuICAgICAgICBjb25zdCBwcmVmaXggPSBidXR0b25UZXh0ID8gJ0FkZCAnIDogJ0FkZCB0byAnO1xyXG4gICAgICAgIGlmICghYnV0dG9uVGV4dCkge1xyXG4gICAgICAgICAgYnV0dG9uVGV4dCA9IHNjaGVtYS50aXRsZSB8fCBmaXhUaXRsZShKc29uUG9pbnRlci50b0tleShkYXRhUG9pbnRlcikpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIS9eYWRkXFxiL2kudGVzdChidXR0b25UZXh0KSkgeyBidXR0b25UZXh0ID0gcHJlZml4ICsgYnV0dG9uVGV4dDsgfVxyXG4gICAgICAgIG5ld05vZGUuaXRlbXMucHVzaCh7XHJcbiAgICAgICAgICBfaWQ6IHVuaXF1ZUlkKCksXHJcbiAgICAgICAgICBhcnJheUl0ZW06IHRydWUsXHJcbiAgICAgICAgICBhcnJheUl0ZW1UeXBlOiAnbGlzdCcsXHJcbiAgICAgICAgICBkYXRhUG9pbnRlcjogbmV3Tm9kZS5kYXRhUG9pbnRlciArICcvLScsXHJcbiAgICAgICAgICBvcHRpb25zOiB7XHJcbiAgICAgICAgICAgIGxpc3RJdGVtczogbmV3Tm9kZS5vcHRpb25zLmxpc3RJdGVtcyxcclxuICAgICAgICAgICAgbWF4SXRlbXM6IG5ld05vZGUub3B0aW9ucy5tYXhJdGVtcyxcclxuICAgICAgICAgICAgbWluSXRlbXM6IG5ld05vZGUub3B0aW9ucy5taW5JdGVtcyxcclxuICAgICAgICAgICAgcmVtb3ZhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAgdGl0bGU6IGJ1dHRvblRleHQsXHJcbiAgICAgICAgICAgIHR1cGxlSXRlbXM6IG5ld05vZGUub3B0aW9ucy50dXBsZUl0ZW1zLFxyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIHJlY3Vyc2l2ZVJlZmVyZW5jZTogaXRlbVJlY3Vyc2l2ZSxcclxuICAgICAgICAgIHR5cGU6ICckcmVmJyxcclxuICAgICAgICAgIHdpZGdldDogd2lkZ2V0TGlicmFyeS5nZXRXaWRnZXQoJyRyZWYnKSxcclxuICAgICAgICAgICRyZWY6IGl0ZW1SZWZQb2ludGVyLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gIH0gZWxzZSBpZiAobmV3Tm9kZS5kYXRhVHlwZSA9PT0gJyRyZWYnKSB7XHJcbiAgICBjb25zdCBzY2hlbWFSZWYgPSBKc29uUG9pbnRlci5jb21waWxlKHNjaGVtYS4kcmVmKTtcclxuICAgIGNvbnN0IGRhdGFSZWYgPSBKc29uUG9pbnRlci50b0RhdGFQb2ludGVyKHNjaGVtYVJlZiwganNmLnNjaGVtYSk7XHJcbiAgICBsZXQgYnV0dG9uVGV4dCA9ICcnO1xyXG5cclxuICAgIC8vIEdldCBuZXdOb2RlIHRpdGxlXHJcbiAgICBpZiAobmV3Tm9kZS5vcHRpb25zLmFkZCkge1xyXG4gICAgICBidXR0b25UZXh0ID0gbmV3Tm9kZS5vcHRpb25zLmFkZDtcclxuICAgIH0gZWxzZSBpZiAobmV3Tm9kZS5uYW1lICYmICEvXlxcZCskLy50ZXN0KG5ld05vZGUubmFtZSkpIHtcclxuICAgICAgYnV0dG9uVGV4dCA9XHJcbiAgICAgICAgKC9eYWRkXFxiL2kudGVzdChuZXdOb2RlLm5hbWUpID8gJycgOiAnQWRkICcpICsgZml4VGl0bGUobmV3Tm9kZS5uYW1lKTtcclxuXHJcbiAgICAgIC8vIElmIG5ld05vZGUgZG9lc24ndCBoYXZlIGEgdGl0bGUsIGxvb2sgZm9yIHRpdGxlIG9mIHBhcmVudCBhcnJheSBpdGVtXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBwYXJlbnRTY2hlbWEgPVxyXG4gICAgICAgIEpzb25Qb2ludGVyLmdldChqc2Yuc2NoZW1hLCBzY2hlbWFQb2ludGVyLCAwLCAtMSk7XHJcbiAgICAgIGlmIChoYXNPd24ocGFyZW50U2NoZW1hLCAndGl0bGUnKSkge1xyXG4gICAgICAgIGJ1dHRvblRleHQgPSAnQWRkIHRvICcgKyBwYXJlbnRTY2hlbWEudGl0bGU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgcG9pbnRlckFycmF5ID0gSnNvblBvaW50ZXIucGFyc2UobmV3Tm9kZS5kYXRhUG9pbnRlcik7XHJcbiAgICAgICAgYnV0dG9uVGV4dCA9ICdBZGQgdG8gJyArIGZpeFRpdGxlKHBvaW50ZXJBcnJheVtwb2ludGVyQXJyYXkubGVuZ3RoIC0gMl0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBPYmplY3QuYXNzaWduKG5ld05vZGUsIHtcclxuICAgICAgcmVjdXJzaXZlUmVmZXJlbmNlOiB0cnVlLFxyXG4gICAgICB3aWRnZXQ6IHdpZGdldExpYnJhcnkuZ2V0V2lkZ2V0KCckcmVmJyksXHJcbiAgICAgICRyZWY6IGRhdGFSZWYsXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5hc3NpZ24obmV3Tm9kZS5vcHRpb25zLCB7XHJcbiAgICAgIHJlbW92YWJsZTogZmFsc2UsXHJcbiAgICAgIHRpdGxlOiBidXR0b25UZXh0LFxyXG4gICAgfSk7XHJcbiAgICBpZiAoaXNOdW1iZXIoSnNvblBvaW50ZXIuZ2V0KGpzZi5zY2hlbWEsIHNjaGVtYVBvaW50ZXIsIDAsIC0xKS5tYXhJdGVtcykpIHtcclxuICAgICAgbmV3Tm9kZS5vcHRpb25zLm1heEl0ZW1zID1cclxuICAgICAgICBKc29uUG9pbnRlci5nZXQoanNmLnNjaGVtYSwgc2NoZW1hUG9pbnRlciwgMCwgLTEpLm1heEl0ZW1zO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEFkZCBsYXlvdXQgdGVtcGxhdGUgdG8gbGF5b3V0UmVmTGlicmFyeVxyXG4gICAgaWYgKGRhdGFSZWYubGVuZ3RoKSB7XHJcbiAgICAgIGlmICghaGFzT3duKGpzZi5sYXlvdXRSZWZMaWJyYXJ5LCBkYXRhUmVmKSkge1xyXG4gICAgICAgIC8vIFNldCB0byBudWxsIGZpcnN0IHRvIHByZXZlbnQgcmVjdXJzaXZlIHJlZmVyZW5jZSBmcm9tIGNhdXNpbmcgZW5kbGVzcyBsb29wXHJcbiAgICAgICAganNmLmxheW91dFJlZkxpYnJhcnlbZGF0YVJlZl0gPSBudWxsO1xyXG4gICAgICAgIGNvbnN0IG5ld0xheW91dCA9IGJ1aWxkTGF5b3V0RnJvbVNjaGVtYShcclxuICAgICAgICAgIGpzZiwgd2lkZ2V0TGlicmFyeSwgbnVsbCwgc2NoZW1hUmVmLCAnJyxcclxuICAgICAgICAgIG5ld05vZGUuYXJyYXlJdGVtLCBuZXdOb2RlLmFycmF5SXRlbVR5cGUsIHRydWUsIHRydWUsIGRhdGFQb2ludGVyXHJcbiAgICAgICAgKTtcclxuICAgICAgICBpZiAobmV3TGF5b3V0KSB7XHJcbiAgICAgICAgICBuZXdMYXlvdXQucmVjdXJzaXZlUmVmZXJlbmNlID0gdHJ1ZTtcclxuICAgICAgICAgIGpzZi5sYXlvdXRSZWZMaWJyYXJ5W2RhdGFSZWZdID0gbmV3TGF5b3V0O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBkZWxldGUganNmLmxheW91dFJlZkxpYnJhcnlbZGF0YVJlZl07XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2UgaWYgKCFqc2YubGF5b3V0UmVmTGlicmFyeVtkYXRhUmVmXS5yZWN1cnNpdmVSZWZlcmVuY2UpIHtcclxuICAgICAgICBqc2YubGF5b3V0UmVmTGlicmFyeVtkYXRhUmVmXS5yZWN1cnNpdmVSZWZlcmVuY2UgPSB0cnVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiBuZXdOb2RlO1xyXG59XHJcblxyXG4vKipcclxuICogJ21hcExheW91dCcgZnVuY3Rpb25cclxuICpcclxuICogQ3JlYXRlcyBhIG5ldyBsYXlvdXQgYnkgcnVubmluZyBlYWNoIGVsZW1lbnQgaW4gYW4gZXhpc3RpbmcgbGF5b3V0IHRocm91Z2hcclxuICogYW4gaXRlcmF0ZWUuIFJlY3Vyc2l2ZWx5IG1hcHMgd2l0aGluIGFycmF5IGVsZW1lbnRzICdpdGVtcycgYW5kICd0YWJzJy5cclxuICogVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBmb3VyIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleCwgbGF5b3V0LCBwYXRoKVxyXG4gKlxyXG4gKiBUaGUgcmV0dXJuZWQgbGF5b3V0IG1heSBiZSBsb25nZXIgKG9yIHNob3J0ZXIpIHRoZW4gdGhlIHNvdXJjZSBsYXlvdXQuXHJcbiAqXHJcbiAqIElmIGFuIGl0ZW0gZnJvbSB0aGUgc291cmNlIGxheW91dCByZXR1cm5zIG11bHRpcGxlIGl0ZW1zIChhcyAnKicgdXN1YWxseSB3aWxsKSxcclxuICogdGhpcyBmdW5jdGlvbiB3aWxsIGtlZXAgYWxsIHJldHVybmVkIGl0ZW1zIGluLWxpbmUgd2l0aCB0aGUgc3Vycm91bmRpbmcgaXRlbXMuXHJcbiAqXHJcbiAqIElmIGFuIGl0ZW0gZnJvbSB0aGUgc291cmNlIGxheW91dCBjYXVzZXMgYW4gZXJyb3IgYW5kIHJldHVybnMgbnVsbCwgaXQgaXNcclxuICogc2tpcHBlZCB3aXRob3V0IGVycm9yLCBhbmQgdGhlIGZ1bmN0aW9uIHdpbGwgc3RpbGwgcmV0dXJuIGFsbCBub24tbnVsbCBpdGVtcy5cclxuICpcclxuICogLy8gICBsYXlvdXQgLSB0aGUgbGF5b3V0IHRvIG1hcFxyXG4gKiAvLyAgeyAodjogYW55LCBpPzogbnVtYmVyLCBsPzogYW55LCBwPzogc3RyaW5nKSA9PiBhbnkgfVxyXG4gKiAgIGZ1bmN0aW9uIC0gdGhlIGZ1bmNpdG9uIHRvIGludm9rZSBvbiBlYWNoIGVsZW1lbnRcclxuICogLy8gIHsgc3RyaW5nfHN0cmluZ1tdID0gJycgfSBsYXlvdXRQb2ludGVyIC0gdGhlIGxheW91dFBvaW50ZXIgdG8gbGF5b3V0LCBpbnNpZGUgcm9vdExheW91dFxyXG4gKiAvLyAgeyBhbnlbXSA9IGxheW91dCB9IHJvb3RMYXlvdXQgLSB0aGUgcm9vdCBsYXlvdXQsIHdoaWNoIGNvbmF0aW5zIGxheW91dFxyXG4gKiAvL1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIG1hcExheW91dChsYXlvdXQsIGZuLCBsYXlvdXRQb2ludGVyID0gJycsIHJvb3RMYXlvdXQgPSBsYXlvdXQpIHtcclxuICBsZXQgaW5kZXhQYWQgPSAwO1xyXG4gIGxldCBuZXdMYXlvdXQ6IGFueVtdID0gW107XHJcbiAgZm9yRWFjaChsYXlvdXQsIChpdGVtLCBpbmRleCkgPT4ge1xyXG4gICAgY29uc3QgcmVhbEluZGV4ID0gK2luZGV4ICsgaW5kZXhQYWQ7XHJcbiAgICBjb25zdCBuZXdMYXlvdXRQb2ludGVyID0gbGF5b3V0UG9pbnRlciArICcvJyArIHJlYWxJbmRleDtcclxuICAgIGxldCBuZXdOb2RlOiBhbnkgPSBjb3B5KGl0ZW0pO1xyXG4gICAgbGV0IGl0ZW1zQXJyYXk6IGFueVtdID0gW107XHJcbiAgICBpZiAoaXNPYmplY3QoaXRlbSkpIHtcclxuICAgICAgaWYgKGhhc093bihpdGVtLCAndGFicycpKSB7XHJcbiAgICAgICAgaXRlbS5pdGVtcyA9IGl0ZW0udGFicztcclxuICAgICAgICBkZWxldGUgaXRlbS50YWJzO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChoYXNPd24oaXRlbSwgJ2l0ZW1zJykpIHtcclxuICAgICAgICBpdGVtc0FycmF5ID0gaXNBcnJheShpdGVtLml0ZW1zKSA/IGl0ZW0uaXRlbXMgOiBbaXRlbS5pdGVtc107XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChpdGVtc0FycmF5Lmxlbmd0aCkge1xyXG4gICAgICBuZXdOb2RlLml0ZW1zID0gbWFwTGF5b3V0KGl0ZW1zQXJyYXksIGZuLCBuZXdMYXlvdXRQb2ludGVyICsgJy9pdGVtcycsIHJvb3RMYXlvdXQpO1xyXG4gICAgfVxyXG4gICAgbmV3Tm9kZSA9IGZuKG5ld05vZGUsIHJlYWxJbmRleCwgbmV3TGF5b3V0UG9pbnRlciwgcm9vdExheW91dCk7XHJcbiAgICBpZiAoIWlzRGVmaW5lZChuZXdOb2RlKSkge1xyXG4gICAgICBpbmRleFBhZC0tO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKGlzQXJyYXkobmV3Tm9kZSkpIHsgaW5kZXhQYWQgKz0gbmV3Tm9kZS5sZW5ndGggLSAxOyB9XHJcbiAgICAgIG5ld0xheW91dCA9IG5ld0xheW91dC5jb25jYXQobmV3Tm9kZSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgcmV0dXJuIG5ld0xheW91dDtcclxufVxyXG5cclxuLyoqXHJcbiAqICdnZXRMYXlvdXROb2RlJyBmdW5jdGlvblxyXG4gKiBDb3B5IGEgbmV3IGxheW91dE5vZGUgZnJvbSBsYXlvdXRSZWZMaWJyYXJ5XHJcbiAqXHJcbiAqIC8vICAgcmVmTm9kZSAtXHJcbiAqIC8vICAgbGF5b3V0UmVmTGlicmFyeSAtXHJcbiAqIC8vICB7IGFueSA9IG51bGwgfSB3aWRnZXRMaWJyYXJ5IC1cclxuICogLy8gIHsgYW55ID0gbnVsbCB9IG5vZGVWYWx1ZSAtXHJcbiAqIC8vICBjb3BpZWQgbGF5b3V0Tm9kZVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldExheW91dE5vZGUoXHJcbiAgcmVmTm9kZSwganNmLCB3aWRnZXRMaWJyYXJ5OiBhbnkgPSBudWxsLCBub2RlVmFsdWU6IGFueSA9IG51bGxcclxuKSB7XHJcblxyXG4gIC8vIElmIHJlY3Vyc2l2ZSByZWZlcmVuY2UgYW5kIGJ1aWxkaW5nIGluaXRpYWwgbGF5b3V0LCByZXR1cm4gQWRkIGJ1dHRvblxyXG4gIGlmIChyZWZOb2RlLnJlY3Vyc2l2ZVJlZmVyZW5jZSAmJiB3aWRnZXRMaWJyYXJ5KSB7XHJcbiAgICBjb25zdCBuZXdMYXlvdXROb2RlID0gY2xvbmVEZWVwKHJlZk5vZGUpO1xyXG4gICAgaWYgKCFuZXdMYXlvdXROb2RlLm9wdGlvbnMpIHsgbmV3TGF5b3V0Tm9kZS5vcHRpb25zID0ge307IH1cclxuICAgIE9iamVjdC5hc3NpZ24obmV3TGF5b3V0Tm9kZSwge1xyXG4gICAgICByZWN1cnNpdmVSZWZlcmVuY2U6IHRydWUsXHJcbiAgICAgIHdpZGdldDogd2lkZ2V0TGlicmFyeS5nZXRXaWRnZXQoJyRyZWYnKSxcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmFzc2lnbihuZXdMYXlvdXROb2RlLm9wdGlvbnMsIHtcclxuICAgICAgcmVtb3ZhYmxlOiBmYWxzZSxcclxuICAgICAgdGl0bGU6ICdBZGQgJyArIG5ld0xheW91dE5vZGUuJHJlZixcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIG5ld0xheW91dE5vZGU7XHJcblxyXG4gICAgLy8gT3RoZXJ3aXNlLCByZXR1cm4gcmVmZXJlbmNlZCBsYXlvdXRcclxuICB9IGVsc2Uge1xyXG4gICAgbGV0IG5ld0xheW91dE5vZGUgPSBqc2YubGF5b3V0UmVmTGlicmFyeVtyZWZOb2RlLiRyZWZdO1xyXG4gICAgLy8gSWYgdmFsdWUgZGVmaW5lZCwgYnVpbGQgbmV3IG5vZGUgZnJvbSBzY2hlbWEgKHRvIHNldCBhcnJheSBsZW5ndGhzKVxyXG4gICAgaWYgKGlzRGVmaW5lZChub2RlVmFsdWUpKSB7XHJcbiAgICAgIG5ld0xheW91dE5vZGUgPSBidWlsZExheW91dEZyb21TY2hlbWEoXHJcbiAgICAgICAganNmLCB3aWRnZXRMaWJyYXJ5LCBub2RlVmFsdWUsXHJcbiAgICAgICAgSnNvblBvaW50ZXIudG9TY2hlbWFQb2ludGVyKHJlZk5vZGUuJHJlZiwganNmLnNjaGVtYSksXHJcbiAgICAgICAgcmVmTm9kZS4kcmVmLCBuZXdMYXlvdXROb2RlLmFycmF5SXRlbSxcclxuICAgICAgICBuZXdMYXlvdXROb2RlLmFycmF5SXRlbVR5cGUsIG5ld0xheW91dE5vZGUub3B0aW9ucy5yZW1vdmFibGUsIGZhbHNlXHJcbiAgICAgICk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBJZiB2YWx1ZSBub3QgZGVmaW5lZCwgY29weSBub2RlIGZyb20gbGF5b3V0UmVmTGlicmFyeVxyXG4gICAgICBuZXdMYXlvdXROb2RlID0gY2xvbmVEZWVwKG5ld0xheW91dE5vZGUpO1xyXG4gICAgICBKc29uUG9pbnRlci5mb3JFYWNoRGVlcChuZXdMYXlvdXROb2RlLCAoc3ViTm9kZSwgcG9pbnRlcikgPT4ge1xyXG5cclxuICAgICAgICAvLyBSZXNldCBhbGwgX2lkJ3MgaW4gbmV3TGF5b3V0Tm9kZSB0byB1bmlxdWUgdmFsdWVzXHJcbiAgICAgICAgaWYgKGhhc093bihzdWJOb2RlLCAnX2lkJykpIHsgc3ViTm9kZS5faWQgPSB1bmlxdWVJZCgpOyB9XHJcblxyXG4gICAgICAgIC8vIElmIGFkZGluZyBhIHJlY3Vyc2l2ZSBpdGVtLCBwcmVmaXggY3VycmVudCBkYXRhUG9pbnRlclxyXG4gICAgICAgIC8vIHRvIGFsbCBkYXRhUG9pbnRlcnMgaW4gbmV3IGxheW91dE5vZGVcclxuICAgICAgICBpZiAocmVmTm9kZS5yZWN1cnNpdmVSZWZlcmVuY2UgJiYgaGFzT3duKHN1Yk5vZGUsICdkYXRhUG9pbnRlcicpKSB7XHJcbiAgICAgICAgICBzdWJOb2RlLmRhdGFQb2ludGVyID0gcmVmTm9kZS5kYXRhUG9pbnRlciArIHN1Yk5vZGUuZGF0YVBvaW50ZXI7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXdMYXlvdXROb2RlO1xyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqICdidWlsZFRpdGxlTWFwJyBmdW5jdGlvblxyXG4gKlxyXG4gKiAvLyAgIHRpdGxlTWFwIC1cclxuICogLy8gICBlbnVtTGlzdCAtXHJcbiAqIC8vICB7IGJvb2xlYW4gPSB0cnVlIH0gZmllbGRSZXF1aXJlZCAtXHJcbiAqIC8vICB7IGJvb2xlYW4gPSB0cnVlIH0gZmxhdExpc3QgLVxyXG4gKiAvLyB7IFRpdGxlTWFwSXRlbVtdIH1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBidWlsZFRpdGxlTWFwKFxyXG4gIHRpdGxlTWFwLCBlbnVtTGlzdCwgZmllbGRSZXF1aXJlZCA9IHRydWUsIGZsYXRMaXN0ID0gdHJ1ZVxyXG4pIHtcclxuICBsZXQgbmV3VGl0bGVNYXA6IFRpdGxlTWFwSXRlbVtdID0gW107XHJcbiAgbGV0IGhhc0VtcHR5VmFsdWUgPSBmYWxzZTtcclxuICBpZiAodGl0bGVNYXApIHtcclxuICAgIGlmIChpc0FycmF5KHRpdGxlTWFwKSkge1xyXG4gICAgICBpZiAoZW51bUxpc3QpIHtcclxuICAgICAgICBmb3IgKGNvbnN0IGkgb2YgT2JqZWN0LmtleXModGl0bGVNYXApKSB7XHJcbiAgICAgICAgICBpZiAoaXNPYmplY3QodGl0bGVNYXBbaV0pKSB7IC8vIEpTT04gRm9ybSBzdHlsZVxyXG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHRpdGxlTWFwW2ldLnZhbHVlO1xyXG4gICAgICAgICAgICBpZiAoZW51bUxpc3QuaW5jbHVkZXModmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgbmFtZSA9IHRpdGxlTWFwW2ldLm5hbWU7XHJcbiAgICAgICAgICAgICAgbmV3VGl0bGVNYXAucHVzaCh7IG5hbWUsIHZhbHVlIH0pO1xyXG4gICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBudWxsKSB7IGhhc0VtcHR5VmFsdWUgPSB0cnVlOyB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0gZWxzZSBpZiAoaXNTdHJpbmcodGl0bGVNYXBbaV0pKSB7IC8vIFJlYWN0IEpzb25zY2hlbWEgRm9ybSBzdHlsZVxyXG4gICAgICAgICAgICBpZiAoaSA8IGVudW1MaXN0Lmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgIGNvbnN0IG5hbWUgPSB0aXRsZU1hcFtpXTtcclxuICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGVudW1MaXN0W2ldO1xyXG4gICAgICAgICAgICAgIG5ld1RpdGxlTWFwLnB1c2goeyBuYW1lLCB2YWx1ZSB9KTtcclxuICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCkgeyBoYXNFbXB0eVZhbHVlID0gdHJ1ZTsgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2UgeyAvLyBJZiBhcnJheSB0aXRsZU1hcCBhbmQgbm8gZW51bSBsaXN0LCBqdXN0IHJldHVybiB0aGUgdGl0bGVNYXAgLSBBbmd1bGFyIFNjaGVtYSBGb3JtIHN0eWxlXHJcbiAgICAgICAgbmV3VGl0bGVNYXAgPSB0aXRsZU1hcDtcclxuICAgICAgICBpZiAoIWZpZWxkUmVxdWlyZWQpIHtcclxuICAgICAgICAgIGhhc0VtcHR5VmFsdWUgPSAhIW5ld1RpdGxlTWFwXHJcbiAgICAgICAgICAgIC5maWx0ZXIoaSA9PiBpLnZhbHVlID09PSB1bmRlZmluZWQgfHwgaS52YWx1ZSA9PT0gbnVsbClcclxuICAgICAgICAgICAgLmxlbmd0aDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAoZW51bUxpc3QpIHsgLy8gQWx0ZXJuYXRlIEpTT04gRm9ybSBzdHlsZSwgd2l0aCBlbnVtIGxpc3RcclxuICAgICAgZm9yIChjb25zdCBpIG9mIE9iamVjdC5rZXlzKGVudW1MaXN0KSkge1xyXG4gICAgICAgIGNvbnN0IHZhbHVlID0gZW51bUxpc3RbaV07XHJcbiAgICAgICAgaWYgKGhhc093bih0aXRsZU1hcCwgdmFsdWUpKSB7XHJcbiAgICAgICAgICBjb25zdCBuYW1lID0gdGl0bGVNYXBbdmFsdWVdO1xyXG4gICAgICAgICAgbmV3VGl0bGVNYXAucHVzaCh7IG5hbWUsIHZhbHVlIH0pO1xyXG4gICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwpIHsgaGFzRW1wdHlWYWx1ZSA9IHRydWU7IH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7IC8vIEFsdGVybmF0ZSBKU09OIEZvcm0gc3R5bGUsIHdpdGhvdXQgZW51bSBsaXN0XHJcbiAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgT2JqZWN0LmtleXModGl0bGVNYXApKSB7XHJcbiAgICAgICAgY29uc3QgbmFtZSA9IHRpdGxlTWFwW3ZhbHVlXTtcclxuICAgICAgICBuZXdUaXRsZU1hcC5wdXNoKHsgbmFtZSwgdmFsdWUgfSk7XHJcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwpIHsgaGFzRW1wdHlWYWx1ZSA9IHRydWU7IH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0gZWxzZSBpZiAoZW51bUxpc3QpIHsgLy8gQnVpbGQgbWFwIGZyb20gZW51bSBsaXN0IGFsb25lXHJcbiAgICBmb3IgKGNvbnN0IGkgb2YgT2JqZWN0LmtleXMoZW51bUxpc3QpKSB7XHJcbiAgICAgIGNvbnN0IG5hbWUgPSBlbnVtTGlzdFtpXTtcclxuICAgICAgY29uc3QgdmFsdWUgPSBlbnVtTGlzdFtpXTtcclxuICAgICAgbmV3VGl0bGVNYXAucHVzaCh7IG5hbWUsIHZhbHVlIH0pO1xyXG4gICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCkgeyBoYXNFbXB0eVZhbHVlID0gdHJ1ZTsgfVxyXG4gICAgfVxyXG4gIH0gZWxzZSB7IC8vIElmIG5vIHRpdGxlTWFwIGFuZCBubyBlbnVtIGxpc3QsIHJldHVybiBkZWZhdWx0IG1hcCBvZiBib29sZWFuIHZhbHVlc1xyXG4gICAgbmV3VGl0bGVNYXAgPSBbeyBuYW1lOiAnVHJ1ZScsIHZhbHVlOiB0cnVlIH0sIHsgbmFtZTogJ0ZhbHNlJywgdmFsdWU6IGZhbHNlIH1dO1xyXG4gIH1cclxuXHJcbiAgLy8gRG9lcyB0aXRsZU1hcCBoYXZlIGdyb3Vwcz9cclxuICBpZiAobmV3VGl0bGVNYXAuc29tZSh0aXRsZSA9PiBoYXNPd24odGl0bGUsICdncm91cCcpKSkge1xyXG4gICAgaGFzRW1wdHlWYWx1ZSA9IGZhbHNlO1xyXG5cclxuICAgIC8vIElmIGZsYXRMaXN0ID0gdHJ1ZSwgZmxhdHRlbiBpdGVtcyAmIHVwZGF0ZSBuYW1lIHRvIGdyb3VwOiBuYW1lXHJcbiAgICBpZiAoZmxhdExpc3QpIHtcclxuICAgICAgbmV3VGl0bGVNYXAgPSBuZXdUaXRsZU1hcC5yZWR1Y2UoKGdyb3VwVGl0bGVNYXAsIHRpdGxlKSA9PiB7XHJcbiAgICAgICAgaWYgKGhhc093bih0aXRsZSwgJ2dyb3VwJykpIHtcclxuICAgICAgICAgIGlmIChpc0FycmF5KHRpdGxlLml0ZW1zKSkge1xyXG4gICAgICAgICAgICBncm91cFRpdGxlTWFwID0gW1xyXG4gICAgICAgICAgICAgIC4uLmdyb3VwVGl0bGVNYXAsXHJcbiAgICAgICAgICAgICAgLi4udGl0bGUuaXRlbXMubWFwKGl0ZW0gPT5cclxuICAgICAgICAgICAgICAgICh7IC4uLml0ZW0sIC4uLnsgbmFtZTogYCR7dGl0bGUuZ3JvdXB9OiAke2l0ZW0ubmFtZX1gIH0gfSlcclxuICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgIF07XHJcbiAgICAgICAgICAgIGlmICh0aXRsZS5pdGVtcy5zb21lKGl0ZW0gPT4gaXRlbS52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IGl0ZW0udmFsdWUgPT09IG51bGwpKSB7XHJcbiAgICAgICAgICAgICAgaGFzRW1wdHlWYWx1ZSA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmIChoYXNPd24odGl0bGUsICduYW1lJykgJiYgaGFzT3duKHRpdGxlLCAndmFsdWUnKSkge1xyXG4gICAgICAgICAgICB0aXRsZS5uYW1lID0gYCR7dGl0bGUuZ3JvdXB9OiAke3RpdGxlLm5hbWV9YDtcclxuICAgICAgICAgICAgZGVsZXRlIHRpdGxlLmdyb3VwO1xyXG4gICAgICAgICAgICBncm91cFRpdGxlTWFwLnB1c2godGl0bGUpO1xyXG4gICAgICAgICAgICBpZiAodGl0bGUudmFsdWUgPT09IHVuZGVmaW5lZCB8fCB0aXRsZS52YWx1ZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgIGhhc0VtcHR5VmFsdWUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGdyb3VwVGl0bGVNYXAucHVzaCh0aXRsZSk7XHJcbiAgICAgICAgICBpZiAodGl0bGUudmFsdWUgPT09IHVuZGVmaW5lZCB8fCB0aXRsZS52YWx1ZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICBoYXNFbXB0eVZhbHVlID0gdHJ1ZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGdyb3VwVGl0bGVNYXA7XHJcbiAgICAgIH0sIFtdKTtcclxuXHJcbiAgICAgIC8vIElmIGZsYXRMaXN0ID0gZmFsc2UsIGNvbWJpbmUgaXRlbXMgZnJvbSBtYXRjaGluZyBncm91cHNcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG5ld1RpdGxlTWFwID0gbmV3VGl0bGVNYXAucmVkdWNlKChncm91cFRpdGxlTWFwLCB0aXRsZSkgPT4ge1xyXG4gICAgICAgIGlmIChoYXNPd24odGl0bGUsICdncm91cCcpKSB7XHJcbiAgICAgICAgICBpZiAodGl0bGUuZ3JvdXAgIT09IChncm91cFRpdGxlTWFwW2dyb3VwVGl0bGVNYXAubGVuZ3RoIC0gMV0gfHwge30pLmdyb3VwKSB7XHJcbiAgICAgICAgICAgIGdyb3VwVGl0bGVNYXAucHVzaCh7IGdyb3VwOiB0aXRsZS5ncm91cCwgaXRlbXM6IHRpdGxlLml0ZW1zIHx8IFtdIH0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKGhhc093bih0aXRsZSwgJ25hbWUnKSAmJiBoYXNPd24odGl0bGUsICd2YWx1ZScpKSB7XHJcbiAgICAgICAgICAgIGdyb3VwVGl0bGVNYXBbZ3JvdXBUaXRsZU1hcC5sZW5ndGggLSAxXS5pdGVtc1xyXG4gICAgICAgICAgICAgIC5wdXNoKHsgbmFtZTogdGl0bGUubmFtZSwgdmFsdWU6IHRpdGxlLnZhbHVlIH0pO1xyXG4gICAgICAgICAgICBpZiAodGl0bGUudmFsdWUgPT09IHVuZGVmaW5lZCB8fCB0aXRsZS52YWx1ZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgIGhhc0VtcHR5VmFsdWUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGdyb3VwVGl0bGVNYXAucHVzaCh0aXRsZSk7XHJcbiAgICAgICAgICBpZiAodGl0bGUudmFsdWUgPT09IHVuZGVmaW5lZCB8fCB0aXRsZS52YWx1ZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICBoYXNFbXB0eVZhbHVlID0gdHJ1ZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGdyb3VwVGl0bGVNYXA7XHJcbiAgICAgIH0sIFtdKTtcclxuICAgIH1cclxuICB9XHJcbiAgaWYgKCFmaWVsZFJlcXVpcmVkICYmICFoYXNFbXB0eVZhbHVlKSB7XHJcbiAgICBuZXdUaXRsZU1hcC51bnNoaWZ0KHsgbmFtZTogJzxlbT5Ob25lPC9lbT4nLCB2YWx1ZTogbnVsbCB9KTtcclxuICB9XHJcbiAgcmV0dXJuIG5ld1RpdGxlTWFwO1xyXG59XHJcbiJdfQ==
|