@ng-formworks/core 17.2.7 → 18.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +834 -0
  3. package/esm2022/lib/framework-library/framework-library.service.mjs +175 -0
  4. package/esm2022/lib/framework-library/framework.mjs +15 -0
  5. package/esm2022/lib/framework-library/no-framework.component.mjs +18 -0
  6. package/esm2022/lib/framework-library/no-framework.module.mjs +27 -0
  7. package/esm2022/lib/framework-library/no.framework.mjs +19 -0
  8. package/esm2022/lib/json-schema-form.component.mjs +765 -0
  9. package/esm2022/lib/json-schema-form.module.mjs +26 -0
  10. package/esm2022/lib/json-schema-form.service.mjs +676 -0
  11. package/esm2022/lib/locale/de-validation-messages.mjs +60 -0
  12. package/esm2022/lib/locale/en-validation-messages.mjs +60 -0
  13. package/esm2022/lib/locale/es-validation-messages.mjs +57 -0
  14. package/esm2022/lib/locale/fr-validation-messages.mjs +60 -0
  15. package/esm2022/lib/locale/index.mjs +8 -0
  16. package/esm2022/lib/locale/it-validation-messages.mjs +60 -0
  17. package/esm2022/lib/locale/pt-validation-messages.mjs +60 -0
  18. package/esm2022/lib/locale/zh-validation-messages.mjs +60 -0
  19. package/esm2022/lib/shared/convert-schema-to-draft6.function.mjs +300 -0
  20. package/esm2022/lib/shared/form-group.functions.mjs +442 -0
  21. package/esm2022/lib/shared/format-regex.constants.mjs +54 -0
  22. package/esm2022/lib/shared/index.mjs +12 -0
  23. package/esm2022/lib/shared/json-schema.functions.mjs +784 -0
  24. package/esm2022/lib/shared/json.validators.mjs +884 -0
  25. package/esm2022/lib/shared/jsonpointer.functions.mjs +1026 -0
  26. package/esm2022/lib/shared/layout.functions.mjs +1158 -0
  27. package/esm2022/lib/shared/merge-schemas.function.mjs +345 -0
  28. package/esm2022/lib/shared/utility.functions.mjs +380 -0
  29. package/esm2022/lib/shared/validator.functions.mjs +584 -0
  30. package/esm2022/lib/widget-library/add-reference.component.mjs +61 -0
  31. package/esm2022/lib/widget-library/button.component.mjs +72 -0
  32. package/esm2022/lib/widget-library/checkbox.component.mjs +105 -0
  33. package/esm2022/lib/widget-library/checkboxes.component.mjs +147 -0
  34. package/esm2022/lib/widget-library/file.component.mjs +35 -0
  35. package/esm2022/lib/widget-library/hidden.component.mjs +54 -0
  36. package/esm2022/lib/widget-library/index.mjs +55 -0
  37. package/esm2022/lib/widget-library/input.component.mjs +119 -0
  38. package/esm2022/lib/widget-library/message.component.mjs +38 -0
  39. package/esm2022/lib/widget-library/none.component.mjs +21 -0
  40. package/esm2022/lib/widget-library/number.component.mjs +123 -0
  41. package/esm2022/lib/widget-library/one-of.component.mjs +35 -0
  42. package/esm2022/lib/widget-library/orderable.directive.mjs +123 -0
  43. package/esm2022/lib/widget-library/radios.component.mjs +153 -0
  44. package/esm2022/lib/widget-library/root.component.mjs +79 -0
  45. package/esm2022/lib/widget-library/section.component.mjs +199 -0
  46. package/esm2022/lib/widget-library/select-framework.component.mjs +51 -0
  47. package/esm2022/lib/widget-library/select-widget.component.mjs +46 -0
  48. package/esm2022/lib/widget-library/select.component.mjs +150 -0
  49. package/esm2022/lib/widget-library/submit.component.mjs +82 -0
  50. package/esm2022/lib/widget-library/tab.component.mjs +41 -0
  51. package/esm2022/lib/widget-library/tabs.component.mjs +108 -0
  52. package/esm2022/lib/widget-library/template.component.mjs +46 -0
  53. package/esm2022/lib/widget-library/textarea.component.mjs +104 -0
  54. package/esm2022/lib/widget-library/widget-library.module.mjs +42 -0
  55. package/esm2022/lib/widget-library/widget-library.service.mjs +226 -0
  56. package/esm2022/ng-formworks-core.mjs +5 -0
  57. package/esm2022/public_api.mjs +13 -0
  58. package/fesm2022/ng-formworks-core.mjs +10151 -0
  59. package/fesm2022/ng-formworks-core.mjs.map +1 -0
  60. package/index.d.ts +5 -0
  61. package/lib/framework-library/framework-library.service.d.ts +55 -0
  62. package/lib/framework-library/framework.d.ts +13 -0
  63. package/lib/framework-library/no-framework.component.d.ts +8 -0
  64. package/lib/framework-library/no-framework.module.d.ts +9 -0
  65. package/lib/framework-library/no.framework.d.ts +10 -0
  66. package/lib/json-schema-form.component.d.ts +218 -0
  67. package/lib/json-schema-form.module.d.ts +11 -0
  68. package/lib/json-schema-form.service.d.ts +115 -0
  69. package/lib/locale/de-validation-messages.d.ts +1 -0
  70. package/lib/locale/en-validation-messages.d.ts +1 -0
  71. package/lib/locale/es-validation-messages.d.ts +1 -0
  72. package/lib/locale/fr-validation-messages.d.ts +1 -0
  73. package/{src/lib/locale/index.ts → lib/locale/index.d.ts} +7 -7
  74. package/lib/locale/it-validation-messages.d.ts +1 -0
  75. package/lib/locale/pt-validation-messages.d.ts +1 -0
  76. package/lib/locale/zh-validation-messages.d.ts +1 -0
  77. package/lib/shared/convert-schema-to-draft6.function.d.ts +21 -0
  78. package/lib/shared/form-group.functions.d.ts +100 -0
  79. package/lib/shared/format-regex.constants.d.ts +19 -0
  80. package/lib/shared/index.d.ts +9 -0
  81. package/lib/shared/json-schema.functions.d.ts +193 -0
  82. package/lib/shared/json.validators.d.ts +441 -0
  83. package/lib/shared/jsonpointer.functions.d.ts +416 -0
  84. package/lib/shared/layout.functions.d.ts +83 -0
  85. package/lib/shared/merge-schemas.function.d.ts +19 -0
  86. package/lib/shared/utility.functions.d.ts +165 -0
  87. package/{src/lib/shared/validator.functions.ts → lib/shared/validator.functions.d.ts} +364 -601
  88. package/lib/widget-library/add-reference.component.d.ts +20 -0
  89. package/lib/widget-library/button.component.d.ts +21 -0
  90. package/lib/widget-library/checkbox.component.d.ts +24 -0
  91. package/lib/widget-library/checkboxes.component.d.ts +24 -0
  92. package/lib/widget-library/file.component.d.ts +21 -0
  93. package/lib/widget-library/hidden.component.d.ts +19 -0
  94. package/{src/lib/widget-library/index.ts → lib/widget-library/index.d.ts} +47 -56
  95. package/lib/widget-library/input.component.d.ts +22 -0
  96. package/lib/widget-library/message.component.d.ts +15 -0
  97. package/lib/widget-library/none.component.d.ts +8 -0
  98. package/lib/widget-library/number.component.d.ts +25 -0
  99. package/lib/widget-library/one-of.component.d.ts +21 -0
  100. package/lib/widget-library/orderable.directive.d.ts +41 -0
  101. package/lib/widget-library/radios.component.d.ts +23 -0
  102. package/lib/widget-library/root.component.d.ts +17 -0
  103. package/lib/widget-library/section.component.d.ts +19 -0
  104. package/lib/widget-library/select-framework.component.d.ts +18 -0
  105. package/lib/widget-library/select-widget.component.d.ts +18 -0
  106. package/lib/widget-library/select.component.d.ts +24 -0
  107. package/lib/widget-library/submit.component.d.ts +24 -0
  108. package/lib/widget-library/tab.component.d.ts +14 -0
  109. package/lib/widget-library/tabs.component.d.ts +20 -0
  110. package/lib/widget-library/template.component.d.ts +18 -0
  111. package/lib/widget-library/textarea.component.d.ts +21 -0
  112. package/lib/widget-library/widget-library.module.d.ts +31 -0
  113. package/lib/widget-library/widget-library.service.d.ts +22 -0
  114. package/package.json +66 -53
  115. package/{src/public_api.ts → public_api.d.ts} +9 -21
  116. package/karma.conf.js +0 -46
  117. package/ng-package.json +0 -11
  118. package/src/lib/framework-library/framework-library.service.ts +0 -195
  119. package/src/lib/framework-library/framework.ts +0 -11
  120. package/src/lib/framework-library/no-framework.component.html +0 -2
  121. package/src/lib/framework-library/no-framework.component.ts +0 -11
  122. package/src/lib/framework-library/no-framework.module.ts +0 -18
  123. package/src/lib/framework-library/no.framework.ts +0 -11
  124. package/src/lib/json-schema-form.component.html +0 -7
  125. package/src/lib/json-schema-form.component.ts +0 -809
  126. package/src/lib/json-schema-form.module.ts +0 -17
  127. package/src/lib/json-schema-form.service.ts +0 -907
  128. package/src/lib/locale/de-validation-messages.ts +0 -58
  129. package/src/lib/locale/en-validation-messages.ts +0 -58
  130. package/src/lib/locale/es-validation-messages.ts +0 -55
  131. package/src/lib/locale/fr-validation-messages.ts +0 -58
  132. package/src/lib/locale/it-validation-messages.ts +0 -58
  133. package/src/lib/locale/pt-validation-messages.ts +0 -58
  134. package/src/lib/locale/zh-validation-messages.ts +0 -58
  135. package/src/lib/locale-dates/en-US.ts +0 -5
  136. package/src/lib/shared/convert-schema-to-draft6.function.ts +0 -321
  137. package/src/lib/shared/form-group.functions.ts +0 -522
  138. package/src/lib/shared/format-regex.constants.ts +0 -73
  139. package/src/lib/shared/index.ts +0 -40
  140. package/src/lib/shared/json-schema.functions.ts +0 -788
  141. package/src/lib/shared/json.validators.ts +0 -878
  142. package/src/lib/shared/jsonpointer.functions.ts +0 -1012
  143. package/src/lib/shared/jspointer.functions.json.spec.ts +0 -103
  144. package/src/lib/shared/layout.functions.ts +0 -1233
  145. package/src/lib/shared/merge-schemas.function.ts +0 -329
  146. package/src/lib/shared/utility.functions.ts +0 -373
  147. package/src/lib/shared/validator.functions.spec.ts +0 -55
  148. package/src/lib/widget-library/add-reference.component.ts +0 -59
  149. package/src/lib/widget-library/button.component.ts +0 -54
  150. package/src/lib/widget-library/checkbox.component.ts +0 -74
  151. package/src/lib/widget-library/checkboxes.component.ts +0 -104
  152. package/src/lib/widget-library/file.component.ts +0 -36
  153. package/src/lib/widget-library/hidden.component.ts +0 -39
  154. package/src/lib/widget-library/input.component.ts +0 -76
  155. package/src/lib/widget-library/message.component.ts +0 -29
  156. package/src/lib/widget-library/none.component.ts +0 -12
  157. package/src/lib/widget-library/number.component.ts +0 -79
  158. package/src/lib/widget-library/one-of.component.ts +0 -36
  159. package/src/lib/widget-library/orderable.directive.ts +0 -130
  160. package/src/lib/widget-library/radios.component.ts +0 -101
  161. package/src/lib/widget-library/root.component.ts +0 -78
  162. package/src/lib/widget-library/section.component.ts +0 -133
  163. package/src/lib/widget-library/select-framework.component.ts +0 -50
  164. package/src/lib/widget-library/select-widget.component.ts +0 -46
  165. package/src/lib/widget-library/select.component.ts +0 -96
  166. package/src/lib/widget-library/submit.component.ts +0 -68
  167. package/src/lib/widget-library/tab.component.ts +0 -29
  168. package/src/lib/widget-library/tabs.component.ts +0 -83
  169. package/src/lib/widget-library/template.component.ts +0 -52
  170. package/src/lib/widget-library/textarea.component.ts +0 -68
  171. package/src/lib/widget-library/widget-library.module.ts +0 -13
  172. package/src/lib/widget-library/widget-library.service.ts +0 -234
  173. package/src/test.ts +0 -18
  174. package/tsconfig.lib.json +0 -25
  175. package/tsconfig.lib.prod.json +0 -9
  176. package/tsconfig.spec.json +0 -17
  177. package/tslint.json +0 -11
@@ -0,0 +1,442 @@
1
+ import cloneDeep from 'lodash/cloneDeep';
2
+ import filter from 'lodash/filter';
3
+ import map from 'lodash/map';
4
+ import { UntypedFormArray, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
5
+ import { forEach, hasOwn } from './utility.functions';
6
+ import { getControlValidators, removeRecursiveReferences } from './json-schema.functions';
7
+ import { hasValue, inArray, isArray, isDate, isDefined, isEmpty, isObject, isPrimitive, toJavaScriptType, toSchemaType } from './validator.functions';
8
+ import { JsonPointer } from './jsonpointer.functions';
9
+ import { JsonValidators } from './json.validators';
10
+ /**
11
+ * FormGroup function library:
12
+ *
13
+ * buildFormGroupTemplate: Builds a FormGroupTemplate from schema
14
+ *
15
+ * buildFormGroup: Builds an Angular FormGroup from a FormGroupTemplate
16
+ *
17
+ * mergeValues:
18
+ *
19
+ * setRequiredFields:
20
+ *
21
+ * formatFormData:
22
+ *
23
+ * getControl:
24
+ *
25
+ * ---- TODO: ----
26
+ * TODO: add buildFormGroupTemplateFromLayout function
27
+ * buildFormGroupTemplateFromLayout: Builds a FormGroupTemplate from a form layout
28
+ */
29
+ /**
30
+ * 'buildFormGroupTemplate' function
31
+ *
32
+ * Builds a template for an Angular FormGroup from a JSON Schema.
33
+ *
34
+ * TODO: add support for pattern properties
35
+ * https://spacetelescope.github.io/understanding-json-schema/reference/object.html
36
+ *
37
+ * // {any} jsf -
38
+ * // {any = null} nodeValue -
39
+ * // {boolean = true} mapArrays -
40
+ * // {string = ''} schemaPointer -
41
+ * // {string = ''} dataPointer -
42
+ * // {any = ''} templatePointer -
43
+ * // {any} -
44
+ */
45
+ export function buildFormGroupTemplate(jsf, nodeValue = null, setValues = true, schemaPointer = '', dataPointer = '', templatePointer = '') {
46
+ const schema = JsonPointer.get(jsf.schema, schemaPointer);
47
+ if (setValues) {
48
+ if (!isDefined(nodeValue) && (jsf.formOptions.setSchemaDefaults === true ||
49
+ (jsf.formOptions.setSchemaDefaults === 'auto' && isEmpty(jsf.formValues)))) {
50
+ nodeValue = JsonPointer.get(jsf.schema, schemaPointer + '/default');
51
+ }
52
+ }
53
+ else {
54
+ nodeValue = null;
55
+ }
56
+ // TODO: If nodeValue still not set, check layout for default value
57
+ const schemaType = JsonPointer.get(schema, '/type');
58
+ const controlType = (hasOwn(schema, 'properties') || hasOwn(schema, 'additionalProperties')) &&
59
+ schemaType === 'object' ? 'FormGroup' :
60
+ (hasOwn(schema, 'items') || hasOwn(schema, 'additionalItems')) &&
61
+ schemaType === 'array' ? 'FormArray' :
62
+ !schemaType && hasOwn(schema, '$ref') ? '$ref' : 'FormControl';
63
+ const shortDataPointer = removeRecursiveReferences(dataPointer, jsf.dataRecursiveRefMap, jsf.arrayMap);
64
+ if (!jsf.dataMap.has(shortDataPointer)) {
65
+ jsf.dataMap.set(shortDataPointer, new Map());
66
+ }
67
+ const nodeOptions = jsf.dataMap.get(shortDataPointer);
68
+ if (!nodeOptions.has('schemaType')) {
69
+ nodeOptions.set('schemaPointer', schemaPointer);
70
+ nodeOptions.set('schemaType', schema.type);
71
+ if (schema.format) {
72
+ nodeOptions.set('schemaFormat', schema.format);
73
+ if (!schema.type) {
74
+ nodeOptions.set('schemaType', 'string');
75
+ }
76
+ }
77
+ if (controlType) {
78
+ nodeOptions.set('templatePointer', templatePointer);
79
+ nodeOptions.set('templateType', controlType);
80
+ }
81
+ }
82
+ let controls;
83
+ const validators = getControlValidators(schema);
84
+ switch (controlType) {
85
+ case 'FormGroup':
86
+ controls = {};
87
+ if (hasOwn(schema, 'ui:order') || hasOwn(schema, 'properties')) {
88
+ const propertyKeys = schema['ui:order'] || Object.keys(schema.properties);
89
+ if (propertyKeys.includes('*') && !hasOwn(schema.properties, '*')) {
90
+ const unnamedKeys = Object.keys(schema.properties)
91
+ .filter(key => !propertyKeys.includes(key));
92
+ for (let i = propertyKeys.length - 1; i >= 0; i--) {
93
+ if (propertyKeys[i] === '*') {
94
+ propertyKeys.splice(i, 1, ...unnamedKeys);
95
+ }
96
+ }
97
+ }
98
+ propertyKeys
99
+ .filter(key => hasOwn(schema.properties, key) ||
100
+ hasOwn(schema, 'additionalProperties'))
101
+ .forEach(key => controls[key] = buildFormGroupTemplate(jsf, JsonPointer.get(nodeValue, [key]), setValues, schemaPointer + (hasOwn(schema.properties, key) ?
102
+ '/properties/' + key : '/additionalProperties'), dataPointer + '/' + key, templatePointer + '/controls/' + key));
103
+ jsf.formOptions.fieldsRequired = setRequiredFields(schema, controls);
104
+ }
105
+ return { controlType, controls, validators };
106
+ case 'FormArray':
107
+ controls = [];
108
+ const minItems = Math.max(schema.minItems || 0, nodeOptions.get('minItems') || 0);
109
+ const maxItems = Math.min(schema.maxItems || 1000, nodeOptions.get('maxItems') || 1000);
110
+ let additionalItemsPointer = null;
111
+ if (isArray(schema.items)) { // 'items' is an array = tuple items
112
+ const tupleItems = nodeOptions.get('tupleItems') ||
113
+ (isArray(schema.items) ? Math.min(schema.items.length, maxItems) : 0);
114
+ for (let i = 0; i < tupleItems; i++) {
115
+ if (i < minItems) {
116
+ controls.push(buildFormGroupTemplate(jsf, isArray(nodeValue) ? nodeValue[i] : nodeValue, setValues, schemaPointer + '/items/' + i, dataPointer + '/' + i, templatePointer + '/controls/' + i));
117
+ }
118
+ else {
119
+ const schemaRefPointer = removeRecursiveReferences(schemaPointer + '/items/' + i, jsf.schemaRecursiveRefMap);
120
+ const itemRefPointer = removeRecursiveReferences(shortDataPointer + '/' + i, jsf.dataRecursiveRefMap, jsf.arrayMap);
121
+ const itemRecursive = itemRefPointer !== shortDataPointer + '/' + i;
122
+ if (!hasOwn(jsf.templateRefLibrary, itemRefPointer)) {
123
+ jsf.templateRefLibrary[itemRefPointer] = null;
124
+ jsf.templateRefLibrary[itemRefPointer] = buildFormGroupTemplate(jsf, null, setValues, schemaRefPointer, itemRefPointer, templatePointer + '/controls/' + i);
125
+ }
126
+ controls.push(isArray(nodeValue) ?
127
+ buildFormGroupTemplate(jsf, nodeValue[i], setValues, schemaPointer + '/items/' + i, dataPointer + '/' + i, templatePointer + '/controls/' + i) :
128
+ itemRecursive ?
129
+ null : cloneDeep(jsf.templateRefLibrary[itemRefPointer]));
130
+ }
131
+ }
132
+ // If 'additionalItems' is an object = additional list items (after tuple items)
133
+ if (schema.items.length < maxItems && isObject(schema.additionalItems)) {
134
+ additionalItemsPointer = schemaPointer + '/additionalItems';
135
+ }
136
+ // If 'items' is an object = list items only (no tuple items)
137
+ }
138
+ else {
139
+ additionalItemsPointer = schemaPointer + '/items';
140
+ }
141
+ if (additionalItemsPointer) {
142
+ const schemaRefPointer = removeRecursiveReferences(additionalItemsPointer, jsf.schemaRecursiveRefMap);
143
+ const itemRefPointer = removeRecursiveReferences(shortDataPointer + '/-', jsf.dataRecursiveRefMap, jsf.arrayMap);
144
+ const itemRecursive = itemRefPointer !== shortDataPointer + '/-';
145
+ if (!hasOwn(jsf.templateRefLibrary, itemRefPointer)) {
146
+ jsf.templateRefLibrary[itemRefPointer] = null;
147
+ jsf.templateRefLibrary[itemRefPointer] = buildFormGroupTemplate(jsf, null, setValues, schemaRefPointer, itemRefPointer, templatePointer + '/controls/-');
148
+ }
149
+ // const itemOptions = jsf.dataMap.get(itemRefPointer) || new Map();
150
+ const itemOptions = nodeOptions;
151
+ if (!itemRecursive || hasOwn(validators, 'required')) {
152
+ const arrayLength = Math.min(Math.max(itemRecursive ? 0 :
153
+ (itemOptions.get('tupleItems') + itemOptions.get('listItems')) || 0, isArray(nodeValue) ? nodeValue.length : 0), maxItems);
154
+ for (let i = controls.length; i < arrayLength; i++) {
155
+ controls.push(isArray(nodeValue) ?
156
+ buildFormGroupTemplate(jsf, nodeValue[i], setValues, schemaRefPointer, dataPointer + '/-', templatePointer + '/controls/-') :
157
+ itemRecursive ?
158
+ null : cloneDeep(jsf.templateRefLibrary[itemRefPointer]));
159
+ }
160
+ }
161
+ }
162
+ return { controlType, controls, validators };
163
+ case '$ref':
164
+ const schemaRef = JsonPointer.compile(schema.$ref);
165
+ const dataRef = JsonPointer.toDataPointer(schemaRef, schema);
166
+ const refPointer = removeRecursiveReferences(dataRef, jsf.dataRecursiveRefMap, jsf.arrayMap);
167
+ if (refPointer && !hasOwn(jsf.templateRefLibrary, refPointer)) {
168
+ // Set to null first to prevent recursive reference from causing endless loop
169
+ jsf.templateRefLibrary[refPointer] = null;
170
+ const newTemplate = buildFormGroupTemplate(jsf, setValues, setValues, schemaRef);
171
+ if (newTemplate) {
172
+ jsf.templateRefLibrary[refPointer] = newTemplate;
173
+ }
174
+ else {
175
+ delete jsf.templateRefLibrary[refPointer];
176
+ }
177
+ }
178
+ return null;
179
+ case 'FormControl':
180
+ const value = {
181
+ value: setValues && isPrimitive(nodeValue) ? nodeValue : null,
182
+ disabled: nodeOptions.get('disabled') || false
183
+ };
184
+ return { controlType, value, validators };
185
+ default:
186
+ return null;
187
+ }
188
+ }
189
+ /**
190
+ * 'buildFormGroup' function
191
+ *
192
+ * // {any} template -
193
+ * // {AbstractControl}
194
+ */
195
+ export function buildFormGroup(template) {
196
+ const validatorFns = [];
197
+ let validatorFn = null;
198
+ if (hasOwn(template, 'validators')) {
199
+ forEach(template.validators, (parameters, validator) => {
200
+ if (typeof JsonValidators[validator] === 'function') {
201
+ validatorFns.push(JsonValidators[validator].apply(null, parameters));
202
+ }
203
+ });
204
+ if (validatorFns.length &&
205
+ inArray(template.controlType, ['FormGroup', 'FormArray'])) {
206
+ validatorFn = validatorFns.length > 1 ?
207
+ JsonValidators.compose(validatorFns) : validatorFns[0];
208
+ }
209
+ }
210
+ if (hasOwn(template, 'controlType')) {
211
+ switch (template.controlType) {
212
+ case 'FormGroup':
213
+ const groupControls = {};
214
+ forEach(template.controls, (controls, key) => {
215
+ const newControl = buildFormGroup(controls);
216
+ if (newControl) {
217
+ groupControls[key] = newControl;
218
+ }
219
+ });
220
+ return new UntypedFormGroup(groupControls, validatorFn);
221
+ case 'FormArray':
222
+ return new UntypedFormArray(filter(map(template.controls, controls => buildFormGroup(controls))), validatorFn);
223
+ case 'FormControl':
224
+ return new UntypedFormControl(template.value, validatorFns);
225
+ }
226
+ }
227
+ return null;
228
+ }
229
+ /**
230
+ * 'mergeValues' function
231
+ *
232
+ * // {any[]} ...valuesToMerge - Multiple values to merge
233
+ * // {any} - Merged values
234
+ */
235
+ export function mergeValues(...valuesToMerge) {
236
+ let mergedValues = null;
237
+ for (const currentValue of valuesToMerge) {
238
+ if (!isEmpty(currentValue)) {
239
+ if (typeof currentValue === 'object' &&
240
+ (isEmpty(mergedValues) || typeof mergedValues !== 'object')) {
241
+ if (isArray(currentValue)) {
242
+ mergedValues = [...currentValue];
243
+ }
244
+ else if (isObject(currentValue)) {
245
+ mergedValues = { ...currentValue };
246
+ }
247
+ }
248
+ else if (typeof currentValue !== 'object') {
249
+ mergedValues = currentValue;
250
+ }
251
+ else if (isObject(mergedValues) && isObject(currentValue)) {
252
+ Object.assign(mergedValues, currentValue);
253
+ }
254
+ else if (isObject(mergedValues) && isArray(currentValue)) {
255
+ const newValues = [];
256
+ for (const value of currentValue) {
257
+ newValues.push(mergeValues(mergedValues, value));
258
+ }
259
+ mergedValues = newValues;
260
+ }
261
+ else if (isArray(mergedValues) && isObject(currentValue)) {
262
+ const newValues = [];
263
+ for (const value of mergedValues) {
264
+ newValues.push(mergeValues(value, currentValue));
265
+ }
266
+ mergedValues = newValues;
267
+ }
268
+ else if (isArray(mergedValues) && isArray(currentValue)) {
269
+ const newValues = [];
270
+ for (let i = 0; i < Math.max(mergedValues.length, currentValue.length); i++) {
271
+ if (i < mergedValues.length && i < currentValue.length) {
272
+ newValues.push(mergeValues(mergedValues[i], currentValue[i]));
273
+ }
274
+ else if (i < mergedValues.length) {
275
+ newValues.push(mergedValues[i]);
276
+ }
277
+ else if (i < currentValue.length) {
278
+ newValues.push(currentValue[i]);
279
+ }
280
+ }
281
+ mergedValues = newValues;
282
+ }
283
+ }
284
+ }
285
+ return mergedValues;
286
+ }
287
+ /**
288
+ * 'setRequiredFields' function
289
+ *
290
+ * // {schema} schema - JSON Schema
291
+ * // {object} formControlTemplate - Form Control Template object
292
+ * // {boolean} - true if any fields have been set to required, false if not
293
+ */
294
+ export function setRequiredFields(schema, formControlTemplate) {
295
+ let fieldsRequired = false;
296
+ if (hasOwn(schema, 'required') && !isEmpty(schema.required)) {
297
+ fieldsRequired = true;
298
+ let requiredArray = isArray(schema.required) ? schema.required : [schema.required];
299
+ requiredArray = forEach(requiredArray, key => JsonPointer.set(formControlTemplate, '/' + key + '/validators/required', []));
300
+ }
301
+ return fieldsRequired;
302
+ // TODO: Add support for patternProperties
303
+ // https://spacetelescope.github.io/understanding-json-schema/reference/object.html#pattern-properties
304
+ }
305
+ /**
306
+ * 'formatFormData' function
307
+ *
308
+ * // {any} formData - Angular FormGroup data object
309
+ * // {Map<string, any>} dataMap -
310
+ * // {Map<string, string>} recursiveRefMap -
311
+ * // {Map<string, number>} arrayMap -
312
+ * // {boolean = false} fixErrors - if TRUE, tries to fix data
313
+ * // {any} - formatted data object
314
+ */
315
+ export function formatFormData(formData, dataMap, recursiveRefMap, arrayMap, returnEmptyFields = false, fixErrors = false) {
316
+ if (formData === null || typeof formData !== 'object') {
317
+ return formData;
318
+ }
319
+ const formattedData = isArray(formData) ? [] : {};
320
+ JsonPointer.forEachDeep(formData, (value, dataPointer) => {
321
+ // If returnEmptyFields === true,
322
+ // add empty arrays and objects to all allowed keys
323
+ if (returnEmptyFields && isArray(value)) {
324
+ JsonPointer.set(formattedData, dataPointer, []);
325
+ }
326
+ else if (returnEmptyFields && isObject(value) && !isDate(value)) {
327
+ JsonPointer.set(formattedData, dataPointer, {});
328
+ }
329
+ else {
330
+ const genericPointer = JsonPointer.has(dataMap, [dataPointer, 'schemaType']) ? dataPointer :
331
+ removeRecursiveReferences(dataPointer, recursiveRefMap, arrayMap);
332
+ if (JsonPointer.has(dataMap, [genericPointer, 'schemaType'])) {
333
+ const schemaType = dataMap.get(genericPointer).get('schemaType');
334
+ if (schemaType === 'null') {
335
+ JsonPointer.set(formattedData, dataPointer, null);
336
+ }
337
+ else if ((hasValue(value) || returnEmptyFields) &&
338
+ inArray(schemaType, ['string', 'integer', 'number', 'boolean'])) {
339
+ const newValue = (fixErrors || (value === null && returnEmptyFields)) ?
340
+ toSchemaType(value, schemaType) : toJavaScriptType(value, schemaType);
341
+ if (isDefined(newValue) || returnEmptyFields) {
342
+ JsonPointer.set(formattedData, dataPointer, newValue);
343
+ }
344
+ }
345
+ // Finish incomplete 'date-time' entries
346
+ if (dataMap.get(genericPointer).get('schemaFormat') === 'date-time') {
347
+ // "2000-03-14T01:59:26.535" -> "2000-03-14T01:59:26.535Z" (add "Z")
348
+ if (/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s][0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?$/i.test(value)) {
349
+ JsonPointer.set(formattedData, dataPointer, `${value}Z`);
350
+ // "2000-03-14T01:59" -> "2000-03-14T01:59:00Z" (add ":00Z")
351
+ }
352
+ else if (/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s][0-2]\d:[0-5]\d$/i.test(value)) {
353
+ JsonPointer.set(formattedData, dataPointer, `${value}:00Z`);
354
+ // "2000-03-14" -> "2000-03-14T00:00:00Z" (add "T00:00:00Z")
355
+ }
356
+ else if (fixErrors && /^\d\d\d\d-[0-1]\d-[0-3]\d$/i.test(value)) {
357
+ JsonPointer.set(formattedData, dataPointer, `${value}:00:00:00Z`);
358
+ }
359
+ }
360
+ }
361
+ else if (typeof value !== 'object' || isDate(value) ||
362
+ (value === null && returnEmptyFields)) {
363
+ console.error('formatFormData error: ' +
364
+ `Schema type not found for form value at ${genericPointer}`);
365
+ console.error('dataMap', dataMap);
366
+ console.error('recursiveRefMap', recursiveRefMap);
367
+ console.error('genericPointer', genericPointer);
368
+ }
369
+ }
370
+ });
371
+ return formattedData;
372
+ }
373
+ /**
374
+ * 'getControl' function
375
+ *
376
+ * Uses a JSON Pointer for a data object to retrieve a control from
377
+ * an Angular formGroup or formGroup template. (Note: though a formGroup
378
+ * template is much simpler, its basic structure is idential to a formGroup).
379
+ *
380
+ * If the optional third parameter 'returnGroup' is set to TRUE, the group
381
+ * containing the control is returned, rather than the control itself.
382
+ *
383
+ * // {FormGroup} formGroup - Angular FormGroup to get value from
384
+ * // {Pointer} dataPointer - JSON Pointer (string or array)
385
+ * // {boolean = false} returnGroup - If true, return group containing control
386
+ * // {group} - Located value (or null, if no control found)
387
+ */
388
+ export function getControl(formGroup, dataPointer, returnGroup = false) {
389
+ if (!isObject(formGroup) || !JsonPointer.isJsonPointer(dataPointer)) {
390
+ if (!JsonPointer.isJsonPointer(dataPointer)) {
391
+ // If dataPointer input is not a valid JSON pointer, check to
392
+ // see if it is instead a valid object path, using dot notaion
393
+ if (typeof dataPointer === 'string') {
394
+ const formControl = formGroup.get(dataPointer);
395
+ if (formControl) {
396
+ return formControl;
397
+ }
398
+ }
399
+ console.error(`getControl error: Invalid JSON Pointer: ${dataPointer}`);
400
+ }
401
+ if (!isObject(formGroup)) {
402
+ console.error(`getControl error: Invalid formGroup: ${formGroup}`);
403
+ }
404
+ return null;
405
+ }
406
+ let dataPointerArray = JsonPointer.parse(dataPointer);
407
+ if (returnGroup) {
408
+ dataPointerArray = dataPointerArray.slice(0, -1);
409
+ }
410
+ // If formGroup input is a real formGroup (not a formGroup template)
411
+ // try using formGroup.get() to return the control
412
+ if (typeof formGroup.get === 'function' &&
413
+ dataPointerArray.every(key => key.indexOf('.') === -1)) {
414
+ const formControl = formGroup.get(dataPointerArray.join('.'));
415
+ if (formControl) {
416
+ return formControl;
417
+ }
418
+ }
419
+ // If formGroup input is a formGroup template,
420
+ // or formGroup.get() failed to return the control,
421
+ // search the formGroup object for dataPointer's control
422
+ let subGroup = formGroup;
423
+ for (const key of dataPointerArray) {
424
+ if (hasOwn(subGroup, 'controls')) {
425
+ subGroup = subGroup.controls;
426
+ }
427
+ if (isArray(subGroup) && (key === '-')) {
428
+ subGroup = subGroup[subGroup.length - 1];
429
+ }
430
+ else if (hasOwn(subGroup, key)) {
431
+ subGroup = subGroup[key];
432
+ }
433
+ else {
434
+ console.error(`getControl error: Unable to find "${key}" item in FormGroup.`);
435
+ console.error(dataPointer);
436
+ console.error(formGroup);
437
+ return;
438
+ }
439
+ }
440
+ return subGroup;
441
+ }
442
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1ncm91cC5mdW5jdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1mb3Jtd29ya3MtY29yZS9zcmMvbGliL3NoYXJlZC9mb3JtLWdyb3VwLmZ1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLFNBQVMsTUFBTSxrQkFBa0IsQ0FBQztBQUN6QyxPQUFPLE1BQU0sTUFBTSxlQUFlLENBQUM7QUFDbkMsT0FBTyxHQUFHLE1BQU0sWUFBWSxDQUFDO0FBQzdCLE9BQU8sRUFFTCxnQkFBZ0IsRUFDaEIsa0JBQWtCLEVBQ2xCLGdCQUFnQixFQUVqQixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLHlCQUF5QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDMUYsT0FBTyxFQUNMLFFBQVEsRUFDUixPQUFPLEVBQ1AsT0FBTyxFQUNQLE1BQU0sRUFDTixTQUFTLEVBQ1QsT0FBTyxFQUNQLFFBQVEsRUFDUixXQUFXLEVBRVgsZ0JBQWdCLEVBQ2hCLFlBQVksRUFDYixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxXQUFXLEVBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFJbkQ7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUVIOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILE1BQU0sVUFBVSxzQkFBc0IsQ0FDcEMsR0FBUSxFQUFFLFlBQWlCLElBQUksRUFBRSxTQUFTLEdBQUcsSUFBSSxFQUNqRCxhQUFhLEdBQUcsRUFBRSxFQUFFLFdBQVcsR0FBRyxFQUFFLEVBQUUsZUFBZSxHQUFHLEVBQUU7SUFFMUQsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLEdBQUcs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QUFDLElBQUksQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2QyxRQUFRLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDM0MsQ0FBQzthQUFNLElBQUksTUFBTSxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2pDLFFBQVEsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDM0IsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLENBQUMsS0FBSyxDQUFDLHFDQUFxQyxHQUFHLHNCQUFzQixDQUFDLENBQUM7WUFDOUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUMzQixPQUFPLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3pCLE9BQU87UUFDVCxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY2xvbmVEZWVwIGZyb20gJ2xvZGFzaC9jbG9uZURlZXAnO1xyXG5pbXBvcnQgZmlsdGVyIGZyb20gJ2xvZGFzaC9maWx0ZXInO1xyXG5pbXBvcnQgbWFwIGZyb20gJ2xvZGFzaC9tYXAnO1xyXG5pbXBvcnQge1xyXG4gIEFic3RyYWN0Q29udHJvbCxcclxuICBVbnR5cGVkRm9ybUFycmF5LFxyXG4gIFVudHlwZWRGb3JtQ29udHJvbCxcclxuICBVbnR5cGVkRm9ybUdyb3VwLFxyXG4gIFZhbGlkYXRvckZuXHJcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBmb3JFYWNoLCBoYXNPd24gfSBmcm9tICcuL3V0aWxpdHkuZnVuY3Rpb25zJztcclxuaW1wb3J0IHsgZ2V0Q29udHJvbFZhbGlkYXRvcnMsIHJlbW92ZVJlY3Vyc2l2ZVJlZmVyZW5jZXMgfSBmcm9tICcuL2pzb24tc2NoZW1hLmZ1bmN0aW9ucyc7XHJcbmltcG9ydCB7XHJcbiAgaGFzVmFsdWUsXHJcbiAgaW5BcnJheSxcclxuICBpc0FycmF5LFxyXG4gIGlzRGF0ZSxcclxuICBpc0RlZmluZWQsXHJcbiAgaXNFbXB0eSxcclxuICBpc09iamVjdCxcclxuICBpc1ByaW1pdGl2ZSxcclxuICBTY2hlbWFQcmltaXRpdmVUeXBlLFxyXG4gIHRvSmF2YVNjcmlwdFR5cGUsXHJcbiAgdG9TY2hlbWFUeXBlXHJcbn0gZnJvbSAnLi92YWxpZGF0b3IuZnVuY3Rpb25zJztcclxuaW1wb3J0IHsgSnNvblBvaW50ZXIsIFBvaW50ZXIgfSBmcm9tICcuL2pzb25wb2ludGVyLmZ1bmN0aW9ucyc7XHJcbmltcG9ydCB7IEpzb25WYWxpZGF0b3JzIH0gZnJvbSAnLi9qc29uLnZhbGlkYXRvcnMnO1xyXG5cclxuXHJcblxyXG4vKipcclxuICogRm9ybUdyb3VwIGZ1bmN0aW9uIGxpYnJhcnk6XHJcbiAqXHJcbiAqIGJ1aWxkRm9ybUdyb3VwVGVtcGxhdGU6ICBCdWlsZHMgYSBGb3JtR3JvdXBUZW1wbGF0ZSBmcm9tIHNjaGVtYVxyXG4gKlxyXG4gKiBidWlsZEZvcm1Hcm91cDogICAgICAgICAgQnVpbGRzIGFuIEFuZ3VsYXIgRm9ybUdyb3VwIGZyb20gYSBGb3JtR3JvdXBUZW1wbGF0ZVxyXG4gKlxyXG4gKiBtZXJnZVZhbHVlczpcclxuICpcclxuICogc2V0UmVxdWlyZWRGaWVsZHM6XHJcbiAqXHJcbiAqIGZvcm1hdEZvcm1EYXRhOlxyXG4gKlxyXG4gKiBnZXRDb250cm9sOlxyXG4gKlxyXG4gKiAtLS0tIFRPRE86IC0tLS1cclxuICogVE9ETzogYWRkIGJ1aWxkRm9ybUdyb3VwVGVtcGxhdGVGcm9tTGF5b3V0IGZ1bmN0aW9uXHJcbiAqIGJ1aWxkRm9ybUdyb3VwVGVtcGxhdGVGcm9tTGF5b3V0OiBCdWlsZHMgYSBGb3JtR3JvdXBUZW1wbGF0ZSBmcm9tIGEgZm9ybSBsYXlvdXRcclxuICovXHJcblxyXG4vKipcclxuICogJ2J1aWxkRm9ybUdyb3VwVGVtcGxhdGUnIGZ1bmN0aW9uXHJcbiAqXHJcbiAqIEJ1aWxkcyBhIHRlbXBsYXRlIGZvciBhbiBBbmd1bGFyIEZvcm1Hcm91cCBmcm9tIGEgSlNPTiBTY2hlbWEuXHJcbiAqXHJcbiAqIFRPRE86IGFkZCBzdXBwb3J0IGZvciBwYXR0ZXJuIHByb3BlcnRpZXNcclxuICogaHR0cHM6Ly9zcGFjZXRlbGVzY29wZS5naXRodWIuaW8vdW5kZXJzdGFuZGluZy1qc29uLXNjaGVtYS9yZWZlcmVuY2Uvb2JqZWN0Lmh0bWxcclxuICpcclxuICogLy8gIHthbnl9IGpzZiAtXHJcbiAqIC8vICB7YW55ID0gbnVsbH0gbm9kZVZhbHVlIC1cclxuICogLy8gIHtib29sZWFuID0gdHJ1ZX0gbWFwQXJyYXlzIC1cclxuICogLy8gIHtzdHJpbmcgPSAnJ30gc2NoZW1hUG9pbnRlciAtXHJcbiAqIC8vICB7c3RyaW5nID0gJyd9IGRhdGFQb2ludGVyIC1cclxuICogLy8gIHthbnkgPSAnJ30gdGVtcGxhdGVQb2ludGVyIC1cclxuICogLy8ge2FueX0gLVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkRm9ybUdyb3VwVGVtcGxhdGUoXHJcbiAganNmOiBhbnksIG5vZGVWYWx1ZTogYW55ID0gbnVsbCwgc2V0VmFsdWVzID0gdHJ1ZSxcclxuICBzY2hlbWFQb2ludGVyID0gJycsIGRhdGFQb2ludGVyID0gJycsIHRlbXBsYXRlUG9pbnRlciA9ICcnXHJcbikge1xyXG4gIGNvbnN0IHNjaGVtYSA9IEpzb25Qb2ludGVyLmdldChqc2Yuc2NoZW1hLCBzY2hlbWFQb2ludGVyKTtcclxuICBpZiAoc2V0VmFsdWVzKSB7XHJcbiAgICBpZiAoIWlzRGVmaW5lZChub2RlVmFsdWUpICYmIChcclxuICAgICAganNmLmZvcm1PcHRpb25zLnNldFNjaGVtYURlZmF1bHRzID09PSB0cnVlIHx8XHJcbiAgICAgIChqc2YuZm9ybU9wdGlvbnMuc2V0U2NoZW1hRGVmYXVsdHMgPT09ICdhdXRvJyAmJiBpc0VtcHR5KGpzZi5mb3JtVmFsdWVzKSlcclxuICAgICkpIHtcclxuICAgICAgbm9kZVZhbHVlID0gSnNvblBvaW50ZXIuZ2V0KGpzZi5zY2hlbWEsIHNjaGVtYVBvaW50ZXIgKyAnL2RlZmF1bHQnKTtcclxuICAgIH1cclxuICB9IGVsc2Uge1xyXG4gICAgbm9kZVZhbHVlID0gbnVsbDtcclxuICB9XHJcbiAgLy8gVE9ETzogSWYgbm9kZVZhbHVlIHN0aWxsIG5vdCBzZXQsIGNoZWNrIGxheW91dCBmb3IgZGVmYXVsdCB2YWx1ZVxyXG4gIGNvbnN0IHNjaGVtYVR5cGU6IHN0cmluZyB8IHN0cmluZ1tdID0gSnNvblBvaW50ZXIuZ2V0KHNjaGVtYSwgJy90eXBlJyk7XHJcbiAgY29uc3QgY29udHJvbFR5cGUgPVxyXG4gICAgKGhhc093bihzY2hlbWEsICdwcm9wZXJ0aWVzJykgfHwgaGFzT3duKHNjaGVtYSwgJ2FkZGl0aW9uYWxQcm9wZXJ0aWVzJykpICYmXHJcbiAgICAgIHNjaGVtYVR5cGUgPT09ICdvYmplY3QnID8gJ0Zvcm1Hcm91cCcgOlxyXG4gICAgICAoaGFzT3duKHNjaGVtYSwgJ2l0ZW1zJykgfHwgaGFzT3duKHNjaGVtYSwgJ2FkZGl0aW9uYWxJdGVtcycpKSAmJlxyXG4gICAgICAgIHNjaGVtYVR5cGUgPT09ICdhcnJheScgPyAnRm9ybUFycmF5JyA6XHJcbiAgICAgICAgIXNjaGVtYVR5cGUgJiYgaGFzT3duKHNjaGVtYSwgJyRyZWYnKSA/ICckcmVmJyA6ICdGb3JtQ29udHJvbCc7XHJcbiAgY29uc3Qgc2hvcnREYXRhUG9pbnRlciA9XHJcbiAgICByZW1vdmVSZWN1cnNpdmVSZWZlcmVuY2VzKGRhdGFQb2ludGVyLCBqc2YuZGF0YVJlY3Vyc2l2ZVJlZk1hcCwganNmLmFycmF5TWFwKTtcclxuICBpZiAoIWpzZi5kYXRhTWFwLmhhcyhzaG9ydERhdGFQb2ludGVyKSkge1xyXG4gICAganNmLmRhdGFNYXAuc2V0KHNob3J0RGF0YVBvaW50ZXIsIG5ldyBNYXAoKSk7XHJcbiAgfVxyXG4gIGNvbnN0IG5vZGVPcHRpb25zID0ganNmLmRhdGFNYXAuZ2V0KHNob3J0RGF0YVBvaW50ZXIpO1xyXG4gIGlmICghbm9kZU9wdGlvbnMuaGFzKCdzY2hlbWFUeXBlJykpIHtcclxuICAgIG5vZGVPcHRpb25zLnNldCgnc2NoZW1hUG9pbnRlcicsIHNjaGVtYVBvaW50ZXIpO1xyXG4gICAgbm9kZU9wdGlvbnMuc2V0KCdzY2hlbWFUeXBlJywgc2NoZW1hLnR5cGUpO1xyXG4gICAgaWYgKHNjaGVtYS5mb3JtYXQpIHtcclxuICAgICAgbm9kZU9wdGlvbnMuc2V0KCdzY2hlbWFGb3JtYXQnLCBzY2hlbWEuZm9ybWF0KTtcclxuICAgICAgaWYgKCFzY2hlbWEudHlwZSkgeyBub2RlT3B0aW9ucy5zZXQoJ3NjaGVtYVR5cGUnLCAnc3RyaW5nJyk7IH1cclxuICAgIH1cclxuICAgIGlmIChjb250cm9sVHlwZSkge1xyXG4gICAgICBub2RlT3B0aW9ucy5zZXQoJ3RlbXBsYXRlUG9pbnRlcicsIHRlbXBsYXRlUG9pbnRlcik7XHJcbiAgICAgIG5vZGVPcHRpb25zLnNldCgndGVtcGxhdGVUeXBlJywgY29udHJvbFR5cGUpO1xyXG4gICAgfVxyXG4gIH1cclxuICBsZXQgY29udHJvbHM6IGFueTtcclxuICBjb25zdCB2YWxpZGF0b3JzID0gZ2V0Q29udHJvbFZhbGlkYXRvcnMoc2NoZW1hKTtcclxuICBzd2l0Y2ggKGNvbnRyb2xUeXBlKSB7XHJcblxyXG4gICAgY2FzZSAnRm9ybUdyb3VwJzpcclxuICAgICAgY29udHJvbHMgPSB7fTtcclxuICAgICAgaWYgKGhhc093bihzY2hlbWEsICd1aTpvcmRlcicpIHx8IGhhc093bihzY2hlbWEsICdwcm9wZXJ0aWVzJykpIHtcclxuICAgICAgICBjb25zdCBwcm9wZXJ0eUtleXMgPSBzY2hlbWFbJ3VpOm9yZGVyJ10gfHwgT2JqZWN0LmtleXMoc2NoZW1hLnByb3BlcnRpZXMpO1xyXG4gICAgICAgIGlmIChwcm9wZXJ0eUtleXMuaW5jbHVkZXMoJyonKSAmJiAhaGFzT3duKHNjaGVtYS5wcm9wZXJ0aWVzLCAnKicpKSB7XHJcbiAgICAgICAgICBjb25zdCB1bm5hbWVkS2V5cyA9IE9iamVjdC5rZXlzKHNjaGVtYS5wcm9wZXJ0aWVzKVxyXG4gICAgICAgICAgICAuZmlsdGVyKGtleSA9PiAhcHJvcGVydHlLZXlzLmluY2x1ZGVzKGtleSkpO1xyXG4gICAgICAgICAgZm9yIChsZXQgaSA9IHByb3BlcnR5S2V5cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgICAgICBpZiAocHJvcGVydHlLZXlzW2ldID09PSAnKicpIHtcclxuICAgICAgICAgICAgICBwcm9wZXJ0eUtleXMuc3BsaWNlKGksIDEsIC4uLnVubmFtZWRLZXlzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBwcm9wZXJ0eUtleXNcclxuICAgICAgICAgIC5maWx0ZXIoa2V5ID0+IGhhc093bihzY2hlbWEucHJvcGVydGllcywga2V5KSB8fFxyXG4gICAgICAgICAgICBoYXNPd24oc2NoZW1hLCAnYWRkaXRpb25hbFByb3BlcnRpZXMnKVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICAgLmZvckVhY2goa2V5ID0+IGNvbnRyb2xzW2tleV0gPSBidWlsZEZvcm1Hcm91cFRlbXBsYXRlKFxyXG4gICAgICAgICAgICBqc2YsIEpzb25Qb2ludGVyLmdldChub2RlVmFsdWUsIFs8c3RyaW5nPmtleV0pLCBzZXRWYWx1ZXMsXHJcbiAgICAgICAgICAgIHNjaGVtYVBvaW50ZXIgKyAoaGFzT3duKHNjaGVtYS5wcm9wZXJ0aWVzLCBrZXkpID9cclxuICAgICAgICAgICAgICAnL3Byb3BlcnRpZXMvJyArIGtleSA6ICcvYWRkaXRpb25hbFByb3BlcnRpZXMnXHJcbiAgICAgICAgICAgICksXHJcbiAgICAgICAgICAgIGRhdGFQb2ludGVyICsgJy8nICsga2V5LFxyXG4gICAgICAgICAgICB0ZW1wbGF0ZVBvaW50ZXIgKyAnL2NvbnRyb2xzLycgKyBrZXlcclxuICAgICAgICAgICkpO1xyXG4gICAgICAgIGpzZi5mb3JtT3B0aW9ucy5maWVsZHNSZXF1aXJlZCA9IHNldFJlcXVpcmVkRmllbGRzKHNjaGVtYSwgY29udHJvbHMpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB7IGNvbnRyb2xUeXBlLCBjb250cm9scywgdmFsaWRhdG9ycyB9O1xyXG5cclxuICAgIGNhc2UgJ0Zvcm1BcnJheSc6XHJcbiAgICAgIGNvbnRyb2xzID0gW107XHJcbiAgICAgIGNvbnN0IG1pbkl0ZW1zID1cclxuICAgICAgICBNYXRoLm1heChzY2hlbWEubWluSXRlbXMgfHwgMCwgbm9kZU9wdGlvbnMuZ2V0KCdtaW5JdGVtcycpIHx8IDApO1xyXG4gICAgICBjb25zdCBtYXhJdGVtcyA9XHJcbiAgICAgICAgTWF0aC5taW4oc2NoZW1hLm1heEl0ZW1zIHx8IDEwMDAsIG5vZGVPcHRpb25zLmdldCgnbWF4SXRlbXMnKSB8fCAxMDAwKTtcclxuICAgICAgbGV0IGFkZGl0aW9uYWxJdGVtc1BvaW50ZXI6IHN0cmluZyA9IG51bGw7XHJcbiAgICAgIGlmIChpc0FycmF5KHNjaGVtYS5pdGVtcykpIHsgLy8gJ2l0ZW1zJyBpcyBhbiBhcnJheSA9IHR1cGxlIGl0ZW1zXHJcbiAgICAgICAgY29uc3QgdHVwbGVJdGVtcyA9IG5vZGVPcHRpb25zLmdldCgndHVwbGVJdGVtcycpIHx8XHJcbiAgICAgICAgICAoaXNBcnJheShzY2hlbWEuaXRlbXMpID8gTWF0aC5taW4oc2NoZW1hLml0ZW1zLmxlbmd0aCwgbWF4SXRlbXMpIDogMCk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0dXBsZUl0ZW1zOyBpKyspIHtcclxuICAgICAgICAgIGlmIChpIDwgbWluSXRlbXMpIHtcclxuICAgICAgICAgICAgY29udHJvbHMucHVzaChidWlsZEZvcm1Hcm91cFRlbXBsYXRlKFxyXG4gICAgICAgICAgICAgIGpzZiwgaXNBcnJheShub2RlVmFsdWUpID8gbm9kZVZhbHVlW2ldIDogbm9kZVZhbHVlLCBzZXRWYWx1ZXMsXHJcbiAgICAgICAgICAgICAgc2NoZW1hUG9pbnRlciArICcvaXRlbXMvJyArIGksXHJcbiAgICAgICAgICAgICAgZGF0YVBvaW50ZXIgKyAnLycgKyBpLFxyXG4gICAgICAgICAgICAgIHRlbXBsYXRlUG9pbnRlciArICcvY29udHJvbHMvJyArIGlcclxuICAgICAgICAgICAgKSk7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBzY2hlbWFSZWZQb2ludGVyID0gcmVtb3ZlUmVjdXJzaXZlUmVmZXJlbmNlcyhcclxuICAgICAgICAgICAgICBzY2hlbWFQb2ludGVyICsgJy9pdGVtcy8nICsgaSwganNmLnNjaGVtYVJlY3Vyc2l2ZVJlZk1hcFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICBjb25zdCBpdGVtUmVmUG9pbnRlciA9IHJlbW92ZVJlY3Vyc2l2ZVJlZmVyZW5jZXMoXHJcbiAgICAgICAgICAgICAgc2hvcnREYXRhUG9pbnRlciArICcvJyArIGksIGpzZi5kYXRhUmVjdXJzaXZlUmVmTWFwLCBqc2YuYXJyYXlNYXBcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgY29uc3QgaXRlbVJlY3Vyc2l2ZSA9IGl0ZW1SZWZQb2ludGVyICE9PSBzaG9ydERhdGFQb2ludGVyICsgJy8nICsgaTtcclxuICAgICAgICAgICAgaWYgKCFoYXNPd24oanNmLnRlbXBsYXRlUmVmTGlicmFyeSwgaXRlbVJlZlBvaW50ZXIpKSB7XHJcbiAgICAgICAgICAgICAganNmLnRlbXBsYXRlUmVmTGlicmFyeVtpdGVtUmVmUG9pbnRlcl0gPSBudWxsO1xyXG4gICAgICAgICAgICAgIGpzZi50ZW1wbGF0ZVJlZkxpYnJhcnlbaXRlbVJlZlBvaW50ZXJdID0gYnVpbGRGb3JtR3JvdXBUZW1wbGF0ZShcclxuICAgICAgICAgICAgICAgIGpzZiwgbnVsbCwgc2V0VmFsdWVzLFxyXG4gICAgICAgICAgICAgICAgc2NoZW1hUmVmUG9pbnRlcixcclxuICAgICAgICAgICAgICAgIGl0ZW1SZWZQb2ludGVyLFxyXG4gICAgICAgICAgICAgICAgdGVtcGxhdGVQb2ludGVyICsgJy9jb250cm9scy8nICsgaVxyXG4gICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29udHJvbHMucHVzaChcclxuICAgICAgICAgICAgICBpc0FycmF5KG5vZGVWYWx1ZSkgP1xyXG4gICAgICAgICAgICAgICAgYnVpbGRGb3JtR3JvdXBUZW1wbGF0ZShcclxuICAgICAgICAgICAgICAgICAganNmLCBub2RlVmFsdWVbaV0sIHNldFZhbHVlcyxcclxuICAgICAgICAgICAgICAgICAgc2NoZW1hUG9pbnRlciArICcvaXRlbXMvJyArIGksXHJcbiAgICAgICAgICAgICAgICAgIGRhdGFQb2ludGVyICsgJy8nICsgaSxcclxuICAgICAgICAgICAgICAgICAgdGVtcGxhdGVQb2ludGVyICsgJy9jb250cm9scy8nICsgaVxyXG4gICAgICAgICAgICAgICAgKSA6XHJcbiAgICAgICAgICAgICAgICBpdGVtUmVjdXJzaXZlID9cclxuICAgICAgICAgICAgICAgICAgbnVsbCA6IGNsb25lRGVlcChqc2YudGVtcGxhdGVSZWZMaWJyYXJ5W2l0ZW1SZWZQb2ludGVyXSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIElmICdhZGRpdGlvbmFsSXRlbXMnIGlzIGFuIG9iamVjdCA9IGFkZGl0aW9uYWwgbGlzdCBpdGVtcyAoYWZ0ZXIgdHVwbGUgaXRlbXMpXHJcbiAgICAgICAgaWYgKHNjaGVtYS5pdGVtcy5sZW5ndGggPCBtYXhJdGVtcyAmJiBpc09iamVjdChzY2hlbWEuYWRkaXRpb25hbEl0ZW1zKSkge1xyXG4gICAgICAgICAgYWRkaXRpb25hbEl0ZW1zUG9pbnRlciA9IHNjaGVtYVBvaW50ZXIgKyAnL2FkZGl0aW9uYWxJdGVtcyc7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJZiAnaXRlbXMnIGlzIGFuIG9iamVjdCA9IGxpc3QgaXRlbXMgb25seSAobm8gdHVwbGUgaXRlbXMpXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgYWRkaXRpb25hbEl0ZW1zUG9pbnRlciA9IHNjaGVtYVBvaW50ZXIgKyAnL2l0ZW1zJztcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKGFkZGl0aW9uYWxJdGVtc1BvaW50ZXIpIHtcclxuICAgICAgICBjb25zdCBzY2hlbWFSZWZQb2ludGVyID0gcmVtb3ZlUmVjdXJzaXZlUmVmZXJlbmNlcyhcclxuICAgICAgICAgIGFkZGl0aW9uYWxJdGVtc1BvaW50ZXIsIGpzZi5zY2hlbWFSZWN1cnNpdmVSZWZNYXBcclxuICAgICAgICApO1xyXG4gICAgICAgIGNvbnN0IGl0ZW1SZWZQb2ludGVyID0gcmVtb3ZlUmVjdXJzaXZlUmVmZXJlbmNlcyhcclxuICAgICAgICAgIHNob3J0RGF0YVBvaW50ZXIgKyAnLy0nLCBqc2YuZGF0YVJlY3Vyc2l2ZVJlZk1hcCwganNmLmFycmF5TWFwXHJcbiAgICAgICAgKTtcclxuICAgICAgICBjb25zdCBpdGVtUmVjdXJzaXZlID0gaXRlbVJlZlBvaW50ZXIgIT09IHNob3J0RGF0YVBvaW50ZXIgKyAnLy0nO1xyXG4gICAgICAgIGlmICghaGFzT3duKGpzZi50ZW1wbGF0ZVJlZkxpYnJhcnksIGl0ZW1SZWZQb2ludGVyKSkge1xyXG4gICAgICAgICAganNmLnRlbXBsYXRlUmVmTGlicmFyeVtpdGVtUmVmUG9pbnRlcl0gPSBudWxsO1xyXG4gICAgICAgICAganNmLnRlbXBsYXRlUmVmTGlicmFyeVtpdGVtUmVmUG9pbnRlcl0gPSBidWlsZEZvcm1Hcm91cFRlbXBsYXRlKFxyXG4gICAgICAgICAgICBqc2YsIG51bGwsIHNldFZhbHVlcyxcclxuICAgICAgICAgICAgc2NoZW1hUmVmUG9pbnRlcixcclxuICAgICAgICAgICAgaXRlbVJlZlBvaW50ZXIsXHJcbiAgICAgICAgICAgIHRlbXBsYXRlUG9pbnRlciArICcvY29udHJvbHMvLSdcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNvbnN0IGl0ZW1PcHRpb25zID0ganNmLmRhdGFNYXAuZ2V0KGl0ZW1SZWZQb2ludGVyKSB8fCBuZXcgTWFwKCk7XHJcbiAgICAgICAgY29uc3QgaXRlbU9wdGlvbnMgPSBub2RlT3B0aW9ucztcclxuICAgICAgICBpZiAoIWl0ZW1SZWN1cnNpdmUgfHwgaGFzT3duKHZhbGlkYXRvcnMsICdyZXF1aXJlZCcpKSB7XHJcbiAgICAgICAgICBjb25zdCBhcnJheUxlbmd0aCA9IE1hdGgubWluKE1hdGgubWF4KFxyXG4gICAgICAgICAgICBpdGVtUmVjdXJzaXZlID8gMCA6XHJcbiAgICAgICAgICAgICAgKGl0ZW1PcHRpb25zLmdldCgndHVwbGVJdGVtcycpICsgaXRlbU9wdGlvbnMuZ2V0KCdsaXN0SXRlbXMnKSkgfHwgMCxcclxuICAgICAgICAgICAgaXNBcnJheShub2RlVmFsdWUpID8gbm9kZVZhbHVlLmxlbmd0aCA6IDBcclxuICAgICAgICAgICksIG1heEl0ZW1zKTtcclxuICAgICAgICAgIGZvciAobGV0IGkgPSBjb250cm9scy5sZW5ndGg7IGkgPCBhcnJheUxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnRyb2xzLnB1c2goXHJcbiAgICAgICAgICAgICAgaXNBcnJheShub2RlVmFsdWUpID9cclxuICAgICAgICAgICAgICAgIGJ1aWxkRm9ybUdyb3VwVGVtcGxhdGUoXHJcbiAgICAgICAgICAgICAgICAgIGpzZiwgbm9kZVZhbHVlW2ldLCBzZXRWYWx1ZXMsXHJcbiAgICAgICAgICAgICAgICAgIHNjaGVtYVJlZlBvaW50ZXIsXHJcbiAgICAgICAgICAgICAgICAgIGRhdGFQb2ludGVyICsgJy8tJyxcclxuICAgICAgICAgICAgICAgICAgdGVtcGxhdGVQb2ludGVyICsgJy9jb250cm9scy8tJ1xyXG4gICAgICAgICAgICAgICAgKSA6XHJcbiAgICAgICAgICAgICAgICBpdGVtUmVjdXJzaXZlID9cclxuICAgICAgICAgICAgICAgICAgbnVsbCA6IGNsb25lRGVlcChqc2YudGVtcGxhdGVSZWZMaWJyYXJ5W2l0ZW1SZWZQb2ludGVyXSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHsgY29udHJvbFR5cGUsIGNvbnRyb2xzLCB2YWxpZGF0b3JzIH07XHJcblxyXG4gICAgY2FzZSAnJHJlZic6XHJcbiAgICAgIGNvbnN0IHNjaGVtYVJlZiA9IEpzb25Qb2ludGVyLmNvbXBpbGUoc2NoZW1hLiRyZWYpO1xyXG4gICAgICBjb25zdCBkYXRhUmVmID0gSnNvblBvaW50ZXIudG9EYXRhUG9pbnRlcihzY2hlbWFSZWYsIHNjaGVtYSk7XHJcbiAgICAgIGNvbnN0IHJlZlBvaW50ZXIgPSByZW1vdmVSZWN1cnNpdmVSZWZlcmVuY2VzKFxyXG4gICAgICAgIGRhdGFSZWYsIGpzZi5kYXRhUmVjdXJzaXZlUmVmTWFwLCBqc2YuYXJyYXlNYXBcclxuICAgICAgKTtcclxuICAgICAgaWYgKHJlZlBvaW50ZXIgJiYgIWhhc093bihqc2YudGVtcGxhdGVSZWZMaWJyYXJ5LCByZWZQb2ludGVyKSkge1xyXG4gICAgICAgIC8vIFNldCB0byBudWxsIGZpcnN0IHRvIHByZXZlbnQgcmVjdXJzaXZlIHJlZmVyZW5jZSBmcm9tIGNhdXNpbmcgZW5kbGVzcyBsb29wXHJcbiAgICAgICAganNmLnRlbXBsYXRlUmVmTGlicmFyeVtyZWZQb2ludGVyXSA9IG51bGw7XHJcbiAgICAgICAgY29uc3QgbmV3VGVtcGxhdGUgPSBidWlsZEZvcm1Hcm91cFRlbXBsYXRlKGpzZiwgc2V0VmFsdWVzLCBzZXRWYWx1ZXMsIHNjaGVtYVJlZik7XHJcbiAgICAgICAgaWYgKG5ld1RlbXBsYXRlKSB7XHJcbiAgICAgICAgICBqc2YudGVtcGxhdGVSZWZMaWJyYXJ5W3JlZlBvaW50ZXJdID0gbmV3VGVtcGxhdGU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGRlbGV0ZSBqc2YudGVtcGxhdGVSZWZMaWJyYXJ5W3JlZlBvaW50ZXJdO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gbnVsbDtcclxuXHJcbiAgICBjYXNlICdGb3JtQ29udHJvbCc6XHJcbiAgICAgIGNvbnN0IHZhbHVlID0ge1xyXG4gICAgICAgIHZhbHVlOiBzZXRWYWx1ZXMgJiYgaXNQcmltaXRpdmUobm9kZVZhbHVlKSA/IG5vZGVWYWx1ZSA6IG51bGwsXHJcbiAgICAgICAgZGlzYWJsZWQ6IG5vZGVPcHRpb25zLmdldCgnZGlzYWJsZWQnKSB8fCBmYWxzZVxyXG4gICAgICB9O1xyXG4gICAgICByZXR1cm4geyBjb250cm9sVHlwZSwgdmFsdWUsIHZhbGlkYXRvcnMgfTtcclxuXHJcbiAgICBkZWZhdWx0OlxyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAnYnVpbGRGb3JtR3JvdXAnIGZ1bmN0aW9uXHJcbiAqXHJcbiAqIC8vIHthbnl9IHRlbXBsYXRlIC1cclxuICogLy8ge0Fic3RyYWN0Q29udHJvbH1cclxuKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkRm9ybUdyb3VwKHRlbXBsYXRlOiBhbnkpOiBBYnN0cmFjdENvbnRyb2wge1xyXG4gIGNvbnN0IHZhbGlkYXRvckZuczogVmFsaWRhdG9yRm5bXSA9IFtdO1xyXG4gIGxldCB2YWxpZGF0b3JGbjogVmFsaWRhdG9yRm4gPSBudWxsO1xyXG4gIGlmIChoYXNPd24odGVtcGxhdGUsICd2YWxpZGF0b3JzJykpIHtcclxuICAgIGZvckVhY2godGVtcGxhdGUudmFsaWRhdG9ycywgKHBhcmFtZXRlcnMsIHZhbGlkYXRvcikgPT4ge1xyXG4gICAgICBpZiAodHlwZW9mIEpzb25WYWxpZGF0b3JzW3ZhbGlkYXRvcl0gPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICB2YWxpZGF0b3JGbnMucHVzaChKc29uVmFsaWRhdG9yc1t2YWxpZGF0b3JdLmFwcGx5KG51bGwsIHBhcmFtZXRlcnMpKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICBpZiAodmFsaWRhdG9yRm5zLmxlbmd0aCAmJlxyXG4gICAgICBpbkFycmF5KHRlbXBsYXRlLmNvbnRyb2xUeXBlLCBbJ0Zvcm1Hcm91cCcsICdGb3JtQXJyYXknXSlcclxuICAgICkge1xyXG4gICAgICB2YWxpZGF0b3JGbiA9IHZhbGlkYXRvckZucy5sZW5ndGggPiAxID9cclxuICAgICAgICBKc29uVmFsaWRhdG9ycy5jb21wb3NlKHZhbGlkYXRvckZucykgOiB2YWxpZGF0b3JGbnNbMF07XHJcbiAgICB9XHJcbiAgfVxyXG4gIGlmIChoYXNPd24odGVtcGxhdGUsICdjb250cm9sVHlwZScpKSB7XHJcbiAgICBzd2l0Y2ggKHRlbXBsYXRlLmNvbnRyb2xUeXBlKSB7XHJcbiAgICAgIGNhc2UgJ0Zvcm1Hcm91cCc6XHJcbiAgICAgICAgY29uc3QgZ3JvdXBDb250cm9sczogeyBba2V5OiBzdHJpbmddOiBBYnN0cmFjdENvbnRyb2wgfSA9IHt9O1xyXG4gICAgICAgIGZvckVhY2godGVtcGxhdGUuY29udHJvbHMsIChjb250cm9scywga2V5KSA9PiB7XHJcbiAgICAgICAgICBjb25zdCBuZXdDb250cm9sOiBBYnN0cmFjdENvbnRyb2wgPSBidWlsZEZvcm1Hcm91cChjb250cm9scyk7XHJcbiAgICAgICAgICBpZiAobmV3Q29udHJvbCkgeyBncm91cENvbnRyb2xzW2tleV0gPSBuZXdDb250cm9sOyB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBVbnR5cGVkRm9ybUdyb3VwKGdyb3VwQ29udHJvbHMsIHZhbGlkYXRvckZuKTtcclxuICAgICAgY2FzZSAnRm9ybUFycmF5JzpcclxuICAgICAgICByZXR1cm4gbmV3IFVudHlwZWRGb3JtQXJyYXkoZmlsdGVyKG1hcCh0ZW1wbGF0ZS5jb250cm9scyxcclxuICAgICAgICAgIGNvbnRyb2xzID0+IGJ1aWxkRm9ybUdyb3VwKGNvbnRyb2xzKVxyXG4gICAgICAgICkpLCB2YWxpZGF0b3JGbik7XHJcbiAgICAgIGNhc2UgJ0Zvcm1Db250cm9sJzpcclxuICAgICAgICByZXR1cm4gbmV3IFVudHlwZWRGb3JtQ29udHJvbCh0ZW1wbGF0ZS52YWx1ZSwgdmFsaWRhdG9yRm5zKTtcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIG51bGw7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAnbWVyZ2VWYWx1ZXMnIGZ1bmN0aW9uXHJcbiAqXHJcbiAqIC8vICB7YW55W119IC4uLnZhbHVlc1RvTWVyZ2UgLSBNdWx0aXBsZSB2YWx1ZXMgdG8gbWVyZ2VcclxuICogLy8ge2FueX0gLSBNZXJnZWQgdmFsdWVzXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VWYWx1ZXMoLi4udmFsdWVzVG9NZXJnZSkge1xyXG4gIGxldCBtZXJnZWRWYWx1ZXM6IGFueSA9IG51bGw7XHJcbiAgZm9yIChjb25zdCBjdXJyZW50VmFsdWUgb2YgdmFsdWVzVG9NZXJnZSkge1xyXG4gICAgaWYgKCFpc0VtcHR5KGN1cnJlbnRWYWx1ZSkpIHtcclxuICAgICAgaWYgKHR5cGVvZiBjdXJyZW50VmFsdWUgPT09ICdvYmplY3QnICYmXHJcbiAgICAgICAgKGlzRW1wdHkobWVyZ2VkVmFsdWVzKSB8fCB0eXBlb2YgbWVyZ2VkVmFsdWVzICE9PSAnb2JqZWN0JylcclxuICAgICAgKSB7XHJcbiAgICAgICAgaWYgKGlzQXJyYXkoY3VycmVudFZhbHVlKSkge1xyXG4gICAgICAgICAgbWVyZ2VkVmFsdWVzID0gWy4uLmN1cnJlbnRWYWx1ZV07XHJcbiAgICAgICAgfSBlbHNlIGlmIChpc09iamVjdChjdXJyZW50VmFsdWUpKSB7XHJcbiAgICAgICAgICBtZXJnZWRWYWx1ZXMgPSB7IC4uLmN1cnJlbnRWYWx1ZSB9O1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgY3VycmVudFZhbHVlICE9PSAnb2JqZWN0Jykge1xyXG4gICAgICAgIG1lcmdlZFZhbHVlcyA9IGN1cnJlbnRWYWx1ZTtcclxuICAgICAgfSBlbHNlIGlmIChpc09iamVjdChtZXJnZWRWYWx1ZXMpICYmIGlzT2JqZWN0KGN1cnJlbnRWYWx1ZSkpIHtcclxuICAgICAgICBPYmplY3QuYXNzaWduKG1lcmdlZFZhbHVlcywgY3VycmVudFZhbHVlKTtcclxuICAgICAgfSBlbHNlIGlmIChpc09iamVjdChtZXJnZWRWYWx1ZXMpICYmIGlzQXJyYXkoY3VycmVudFZhbHVlKSkge1xyXG4gICAgICAgIGNvbnN0IG5ld1ZhbHVlcyA9IFtdO1xyXG4gICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgY3VycmVudFZhbHVlKSB7XHJcbiAgICAgICAgICBuZXdWYWx1ZXMucHVzaChtZXJnZVZhbHVlcyhtZXJnZWRWYWx1ZXMsIHZhbHVlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG1lcmdlZFZhbHVlcyA9IG5ld1ZhbHVlcztcclxuICAgICAgfSBlbHNlIGlmIChpc0FycmF5KG1lcmdlZFZhbHVlcykgJiYgaXNPYmplY3QoY3VycmVudFZhbHVlKSkge1xyXG4gICAgICAgIGNvbnN0IG5ld1ZhbHVlcyA9IFtdO1xyXG4gICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgbWVyZ2VkVmFsdWVzKSB7XHJcbiAgICAgICAgICBuZXdWYWx1ZXMucHVzaChtZXJnZVZhbHVlcyh2YWx1ZSwgY3VycmVudFZhbHVlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG1lcmdlZFZhbHVlcyA9IG5ld1ZhbHVlcztcclxuICAgICAgfSBlbHNlIGlmIChpc0FycmF5KG1lcmdlZFZhbHVlcykgJiYgaXNBcnJheShjdXJyZW50VmFsdWUpKSB7XHJcbiAgICAgICAgY29uc3QgbmV3VmFsdWVzID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBNYXRoLm1heChtZXJnZWRWYWx1ZXMubGVuZ3RoLCBjdXJyZW50VmFsdWUubGVuZ3RoKTsgaSsrKSB7XHJcbiAgICAgICAgICBpZiAoaSA8IG1lcmdlZFZhbHVlcy5sZW5ndGggJiYgaSA8IGN1cnJlbnRWYWx1ZS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgbmV3VmFsdWVzLnB1c2gobWVyZ2VWYWx1ZXMobWVyZ2VkVmFsdWVzW2ldLCBjdXJyZW50VmFsdWVbaV0pKTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IG1lcmdlZFZhbHVlcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgbmV3VmFsdWVzLnB1c2gobWVyZ2VkVmFsdWVzW2ldKTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IGN1cnJlbnRWYWx1ZS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgbmV3VmFsdWVzLnB1c2goY3VycmVudFZhbHVlW2ldKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgbWVyZ2VkVmFsdWVzID0gbmV3VmFsdWVzO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiBtZXJnZWRWYWx1ZXM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAnc2V0UmVxdWlyZWRGaWVsZHMnIGZ1bmN0aW9uXHJcbiAqXHJcbiAqIC8vIHtzY2hlbWF9IHNjaGVtYSAtIEpTT04gU2NoZW1hXHJcbiAqIC8vIHtvYmplY3R9IGZvcm1Db250cm9sVGVtcGxhdGUgLSBGb3JtIENvbnRyb2wgVGVtcGxhdGUgb2JqZWN0XHJcbiAqIC8vIHtib29sZWFufSAtIHRydWUgaWYgYW55IGZpZWxkcyBoYXZlIGJlZW4gc2V0IHRvIHJlcXVpcmVkLCBmYWxzZSBpZiBub3RcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBzZXRSZXF1aXJlZEZpZWxkcyhzY2hlbWE6IGFueSwgZm9ybUNvbnRyb2xUZW1wbGF0ZTogYW55KTogYm9vbGVhbiB7XHJcbiAgbGV0IGZpZWxkc1JlcXVpcmVkID0gZmFsc2U7XHJcbiAgaWYgKGhhc093bihzY2hlbWEsICdyZXF1aXJlZCcpICYmICFpc0VtcHR5KHNjaGVtYS5yZXF1aXJlZCkpIHtcclxuICAgIGZpZWxkc1JlcXVpcmVkID0gdHJ1ZTtcclxuICAgIGxldCByZXF1aXJlZEFycmF5ID0gaXNBcnJheShzY2hlbWEucmVxdWlyZWQpID8gc2NoZW1hLnJlcXVpcmVkIDogW3NjaGVtYS5yZXF1aXJlZF07XHJcbiAgICByZXF1aXJlZEFycmF5ID0gZm9yRWFjaChyZXF1aXJlZEFycmF5LFxyXG4gICAgICBrZXkgPT4gSnNvblBvaW50ZXIuc2V0KGZvcm1Db250cm9sVGVtcGxhdGUsICcvJyArIGtleSArICcvdmFsaWRhdG9ycy9yZXF1aXJlZCcsIFtdKVxyXG4gICAgKTtcclxuICB9XHJcbiAgcmV0dXJuIGZpZWxkc1JlcXVpcmVkO1xyXG5cclxuICAvLyBUT0RPOiBBZGQgc3VwcG9ydCBmb3IgcGF0dGVyblByb3BlcnRpZXNcclxuICAvLyBodHRwczovL3NwYWNldGVsZXNjb3BlLmdpdGh1Yi5pby91bmRlcnN0YW5kaW5nLWpzb24tc2NoZW1hL3JlZmVyZW5jZS9vYmplY3QuaHRtbCNwYXR0ZXJuLXByb3BlcnRpZXNcclxufVxyXG5cclxuLyoqXHJcbiAqICdmb3JtYXRGb3JtRGF0YScgZnVuY3Rpb25cclxuICpcclxuICogLy8ge2FueX0gZm9ybURhdGEgLSBBbmd1bGFyIEZvcm1Hcm91cCBkYXRhIG9iamVjdFxyXG4gKiAvLyB7TWFwPHN0cmluZywgYW55Pn0gZGF0YU1hcCAtXHJcbiAqIC8vIHtNYXA8c3RyaW5nLCBzdHJpbmc+fSByZWN1cnNpdmVSZWZNYXAgLVxyXG4gKiAvLyB7TWFwPHN0cmluZywgbnVtYmVyPn0gYXJyYXlNYXAgLVxyXG4gKiAvLyB7Ym9vbGVhbiA9IGZhbHNlfSBmaXhFcnJvcnMgLSBpZiBUUlVFLCB0cmllcyB0byBmaXggZGF0YVxyXG4gKiAvLyB7YW55fSAtIGZvcm1hdHRlZCBkYXRhIG9iamVjdFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdEZvcm1EYXRhKFxyXG4gIGZvcm1EYXRhOiBhbnksIGRhdGFNYXA6IE1hcDxzdHJpbmcsIGFueT4sXHJcbiAgcmVjdXJzaXZlUmVmTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmc+LCBhcnJheU1hcDogTWFwPHN0cmluZywgbnVtYmVyPixcclxuICByZXR1cm5FbXB0eUZpZWxkcyA9IGZhbHNlLCBmaXhFcnJvcnMgPSBmYWxzZVxyXG4pOiBhbnkge1xyXG4gIGlmIChmb3JtRGF0YSA9PT0gbnVsbCB8fCB0eXBlb2YgZm9ybURhdGEgIT09ICdvYmplY3QnKSB7IHJldHVybiBmb3JtRGF0YTsgfVxyXG4gIGNvbnN0IGZvcm1hdHRlZERhdGEgPSBpc0FycmF5KGZvcm1EYXRhKSA/IFtdIDoge307XHJcbiAgSnNvblBvaW50ZXIuZm9yRWFjaERlZXAoZm9ybURhdGEsICh2YWx1ZSwgZGF0YVBvaW50ZXIpID0+IHtcclxuXHJcbiAgICAvLyBJZiByZXR1cm5FbXB0eUZpZWxkcyA9PT0gdHJ1ZSxcclxuICAgIC8vIGFkZCBlbXB0eSBhcnJheXMgYW5kIG9iamVjdHMgdG8gYWxsIGFsbG93ZWQga2V5c1xyXG4gICAgaWYgKHJldHVybkVtcHR5RmllbGRzICYmIGlzQXJyYXkodmFsdWUpKSB7XHJcbiAgICAgIEpzb25Qb2ludGVyLnNldChmb3JtYXR0ZWREYXRhLCBkYXRhUG9pbnRlciwgW10pO1xyXG4gICAgfSBlbHNlIGlmIChyZXR1cm5FbXB0eUZpZWxkcyAmJiBpc09iamVjdCh2YWx1ZSkgJiYgIWlzRGF0ZSh2YWx1ZSkpIHtcclxuICAgICAgSnNvblBvaW50ZXIuc2V0KGZvcm1hdHRlZERhdGEsIGRhdGFQb2ludGVyLCB7fSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBnZW5lcmljUG9pbnRlciA9XHJcbiAgICAgICAgSnNvblBvaW50ZXIuaGFzKGRhdGFNYXAsIFtkYXRhUG9pbnRlciwgJ3NjaGVtYVR5cGUnXSkgPyBkYXRhUG9pbnRlciA6XHJcbiAgICAgICAgICByZW1vdmVSZWN1cnNpdmVSZWZlcmVuY2VzKGRhdGFQb2ludGVyLCByZWN1cnNpdmVSZWZNYXAsIGFycmF5TWFwKTtcclxuICAgICAgaWYgKEpzb25Qb2ludGVyLmhhcyhkYXRhTWFwLCBbZ2VuZXJpY1BvaW50ZXIsICdzY2hlbWFUeXBlJ10pKSB7XHJcbiAgICAgICAgY29uc3Qgc2NoZW1hVHlwZTogU2NoZW1hUHJpbWl0aXZlVHlwZSB8IFNjaGVtYVByaW1pdGl2ZVR5cGVbXSA9XHJcbiAgICAgICAgICBkYXRhTWFwLmdldChnZW5lcmljUG9pbnRlcikuZ2V0KCdzY2hlbWFUeXBlJyk7XHJcbiAgICAgICAgaWYgKHNjaGVtYVR5cGUgPT09ICdudWxsJykge1xyXG4gICAgICAgICAgSnNvblBvaW50ZXIuc2V0KGZvcm1hdHRlZERhdGEsIGRhdGFQb2ludGVyLCBudWxsKTtcclxuICAgICAgICB9IGVsc2UgaWYgKChoYXNWYWx1ZSh2YWx1ZSkgfHwgcmV0dXJuRW1wdHlGaWVsZHMpICYmXHJcbiAgICAgICAgICBpbkFycmF5KHNjaGVtYVR5cGUsIFsnc3RyaW5nJywgJ2ludGVnZXInLCAnbnVtYmVyJywgJ2Jvb2xlYW4nXSlcclxuICAgICAgICApIHtcclxuICAgICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gKGZpeEVycm9ycyB8fCAodmFsdWUgPT09IG51bGwgJiYgcmV0dXJuRW1wdHlGaWVsZHMpKSA/XHJcbiAgICAgICAgICAgIHRvU2NoZW1hVHlwZSh2YWx1ZSwgc2NoZW1hVHlwZSkgOiB0b0phdmFTY3JpcHRUeXBlKHZhbHVlLCBzY2hlbWFUeXBlKTtcclxuICAgICAgICAgIGlmIChpc0RlZmluZWQobmV3VmFsdWUpIHx8IHJldHVybkVtcHR5RmllbGRzKSB7XHJcbiAgICAgICAgICAgIEpzb25Qb2ludGVyLnNldChmb3JtYXR0ZWREYXRhLCBkYXRhUG9pbnRlciwgbmV3VmFsdWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRmluaXNoIGluY29tcGxldGUgJ2RhdGUtdGltZScgZW50cmllc1xyXG4gICAgICAgIGlmIChkYXRhTWFwLmdldChnZW5lcmljUG9pbnRlcikuZ2V0KCdzY2hlbWFGb3JtYXQnKSA9PT0gJ2RhdGUtdGltZScpIHtcclxuICAgICAgICAgIC8vIFwiMjAwMC0wMy0xNFQwMTo1OToyNi41MzVcIiAtPiBcIjIwMDAtMDMtMTRUMDE6NTk6MjYuNTM1WlwiIChhZGQgXCJaXCIpXHJcbiAgICAgICAgICBpZiAoL15cXGRcXGRcXGRcXGQtWzAtMV1cXGQtWzAtM11cXGRbdFxcc11bMC0yXVxcZDpbMC01XVxcZDpbMC01XVxcZCg/OlxcLlxcZCspPyQvaS50ZXN0KHZhbHVlKSkge1xyXG4gICAgICAgICAgICBKc29uUG9pbnRlci5zZXQoZm9ybWF0dGVkRGF0YSwgZGF0YVBvaW50ZXIsIGAke3ZhbHVlfVpgKTtcclxuICAgICAgICAgICAgLy8gXCIyMDAwLTAzLTE0VDAxOjU5XCIgLT4gXCIyMDAwLTAzLTE0VDAxOjU5OjAwWlwiIChhZGQgXCI6MDBaXCIpXHJcbiAgICAgICAgICB9IGVsc2UgaWYgKC9eXFxkXFxkXFxkXFxkLVswLTFdXFxkLVswLTNdXFxkW3RcXHNdWzAtMl1cXGQ6WzAtNV1cXGQkL2kudGVzdCh2YWx1ZSkpIHtcclxuICAgICAgICAgICAgSnNvblBvaW50ZXIuc2V0KGZvcm1hdHRlZERhdGEsIGRhdGFQb2ludGVyLCBgJHt2YWx1ZX06MDBaYCk7XHJcbiAgICAgICAgICAgIC8vIFwiMjAwMC0wMy0xNFwiIC0+IFwiMjAwMC0wMy0xNFQwMDowMDowMFpcIiAoYWRkIFwiVDAwOjAwOjAwWlwiKVxyXG4gICAgICAgICAgfSBlbHNlIGlmIChmaXhFcnJvcnMgJiYgL15cXGRcXGRcXGRcXGQtWzAtMV1cXGQtWzAtM11cXGQkL2kudGVzdCh2YWx1ZSkpIHtcclxuICAgICAgICAgICAgSnNvblBvaW50ZXIuc2V0KGZvcm1hdHRlZERhdGEsIGRhdGFQb2ludGVyLCBgJHt2YWx1ZX06MDA6MDA6MDBaYCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcgfHwgaXNEYXRlKHZhbHVlKSB8fFxyXG4gICAgICAgICh2YWx1ZSA9PT0gbnVsbCAmJiByZXR1cm5FbXB0eUZpZWxkcylcclxuICAgICAgKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcignZm9ybWF0Rm9ybURhdGEgZXJyb3I6ICcgK1xyXG4gICAgICAgICAgYFNjaGVtYSB0eXBlIG5vdCBmb3VuZCBmb3IgZm9ybSB2YWx1ZSBhdCAke2dlbmVyaWNQb2ludGVyfWApO1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ2RhdGFNYXAnLCBkYXRhTWFwKTtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdyZWN1cnNpdmVSZWZNYXAnLCByZWN1cnNpdmVSZWZNYXApO1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ2dlbmVyaWNQb2ludGVyJywgZ2VuZXJpY1BvaW50ZXIpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgcmV0dXJuIGZvcm1hdHRlZERhdGE7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAnZ2V0Q29udHJvbCcgZnVuY3Rpb25cclxuICpcclxuICogVXNlcyBhIEpTT04gUG9pbnRlciBmb3IgYSBkYXRhIG9iamVjdCB0byByZXRyaWV2ZSBhIGNvbnRyb2wgZnJvbVxyXG4gKiBhbiBBbmd1bGFyIGZvcm1Hcm91cCBvciBmb3JtR3JvdXAgdGVtcGxhdGUuIChOb3RlOiB0aG91Z2ggYSBmb3JtR3JvdXBcclxuICogdGVtcGxhdGUgaXMgbXVjaCBzaW1wbGVyLCBpdHMgYmFzaWMgc3RydWN0dXJlIGlzIGlkZW50aWFsIHRvIGEgZm9ybUdyb3VwKS5cclxuICpcclxuICogSWYgdGhlIG9wdGlvbmFsIHRoaXJkIHBhcmFtZXRlciAncmV0dXJuR3JvdXAnIGlzIHNldCB0byBUUlVFLCB0aGUgZ3JvdXBcclxuICogY29udGFpbmluZyB0aGUgY29udHJvbCBpcyByZXR1cm5lZCwgcmF0aGVyIHRoYW4gdGhlIGNvbnRyb2wgaXRzZWxmLlxyXG4gKlxyXG4gKiAvLyB7Rm9ybUdyb3VwfSBmb3JtR3JvdXAgLSBBbmd1bGFyIEZvcm1Hcm91cCB0byBnZXQgdmFsdWUgZnJvbVxyXG4gKiAvLyB7UG9pbnRlcn0gZGF0YVBvaW50ZXIgLSBKU09OIFBvaW50ZXIgKHN0cmluZyBvciBhcnJheSlcclxuICogLy8ge2Jvb2xlYW4gPSBmYWxzZX0gcmV0dXJuR3JvdXAgLSBJZiB0cnVlLCByZXR1cm4gZ3JvdXAgY29udGFpbmluZyBjb250cm9sXHJcbiAqIC8vIHtncm91cH0gLSBMb2NhdGVkIHZhbHVlIChvciBudWxsLCBpZiBubyBjb250cm9sIGZvdW5kKVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbnRyb2woXHJcbiAgZm9ybUdyb3VwOiBhbnksIGRhdGFQb2ludGVyOiBQb2ludGVyLCByZXR1cm5Hcm91cCA9IGZhbHNlXHJcbik6IGFueSB7XHJcbiAgaWYgKCFpc09iamVjdChmb3JtR3JvdXApIHx8ICFKc29uUG9pbnRlci5pc0pzb25Qb2ludGVyKGRhdGFQb2ludGVyKSkge1xyXG4gICAgaWYgKCFKc29uUG9pbnRlci5pc0pzb25Qb2ludGVyKGRhdGFQb2ludGVyKSkge1xyXG4gICAgICAvLyBJZiBkYXRhUG9pbnRlciBpbnB1dCBpcyBub3QgYSB2YWxpZCBKU09OIHBvaW50ZXIsIGNoZWNrIHRvXHJcbiAgICAgIC8vIHNlZSBpZiBpdCBpcyBpbnN0ZWFkIGEgdmFsaWQgb2JqZWN0IHBhdGgsIHVzaW5nIGRvdCBub3RhaW9uXHJcbiAgICAgIGlmICh0eXBlb2YgZGF0YVBvaW50ZXIgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgY29uc3QgZm9ybUNvbnRyb2wgPSBmb3JtR3JvdXAuZ2V0KGRhdGFQb2ludGVyKTtcclxuICAgICAgICBpZiAoZm9ybUNvbnRyb2wpIHsgcmV0dXJuIGZvcm1Db250cm9sOyB9XHJcbiAgICAgIH1cclxuICAgICAgY29uc29sZS5lcnJvcihgZ2V0Q29udHJvbCBlcnJvcjogSW52YWxpZCBKU09OIFBvaW50ZXI6ICR7ZGF0YVBvaW50ZXJ9YCk7XHJcbiAgICB9XHJcbiAgICBpZiAoIWlzT2JqZWN0KGZvcm1Hcm91cCkpIHtcclxuICAgICAgY29uc29sZS5lcnJvcihgZ2V0Q29udHJvbCBlcnJvcjogSW52YWxpZCBmb3JtR3JvdXA6ICR7Zm9ybUdyb3VwfWApO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG4gIGxldCBkYXRhUG9pbnRlckFycmF5ID0gSnNvblBvaW50ZXIucGFyc2UoZGF0YVBvaW50ZXIpO1xyXG4gIGlmIChyZXR1cm5Hcm91cCkgeyBkYXRhUG9pbnRlckFycmF5ID0gZGF0YVBvaW50ZXJBcnJheS5zbGljZSgwLCAtMSk7IH1cclxuXHJcbiAgLy8gSWYgZm9ybUdyb3VwIGlucHV0IGlzIGEgcmVhbCBmb3JtR3JvdXAgKG5vdCBhIGZvcm1Hcm91cCB0ZW1wbGF0ZSlcclxuICAvLyB0cnkgdXNpbmcgZm9ybUdyb3VwLmdldCgpIHRvIHJldHVybiB0aGUgY29udHJvbFxyXG4gIGlmICh0eXBlb2YgZm9ybUdyb3VwLmdldCA9PT0gJ2Z1bmN0aW9uJyAmJlxyXG4gICAgZGF0YVBvaW50ZXJBcnJheS5ldmVyeShrZXkgPT4ga2V5LmluZGV4T2YoJy4nKSA9PT0gLTEpXHJcbiAgKSB7XHJcbiAgICBjb25zdCBmb3JtQ29udHJvbCA9IGZvcm1Hcm91cC5nZXQoZGF0YVBvaW50ZXJBcnJheS5qb2luKCcuJykpO1xyXG4gICAgaWYgKGZvcm1Db250cm9sKSB7IHJldHVybiBmb3JtQ29udHJvbDsgfVxyXG4gIH1cclxuXHJcbiAgLy8gSWYgZm9ybUdyb3VwIGlucHV0IGlzIGEgZm9ybUdyb3VwIHRlbXBsYXRlLFxyXG4gIC8vIG9yIGZvcm1Hcm91cC5nZXQoKSBmYWlsZWQgdG8gcmV0dXJuIHRoZSBjb250cm9sLFxyXG4gIC8vIHNlYXJjaCB0aGUgZm9ybUdyb3VwIG9iamVjdCBmb3IgZGF0YVBvaW50ZXIncyBjb250cm9sXHJcbiAgbGV0IHN1Ykdyb3VwID0gZm9ybUdyb3VwO1xyXG4gIGZvciAoY29uc3Qga2V5IG9mIGRhdGFQb2ludGVyQXJyYXkpIHtcclxuICAgIGlmIChoYXNPd24oc3ViR3JvdXAsICdjb250cm9scycpKSB7IHN1Ykdyb3VwID0gc3ViR3JvdXAuY29udHJvbHM7IH1cclxuICAgIGlmIChpc0FycmF5KHN1Ykdyb3VwKSAmJiAoa2V5ID09PSAnLScpKSB7XHJcbiAgICAgIHN1Ykdyb3VwID0gc3ViR3JvdXBbc3ViR3JvdXAubGVuZ3RoIC0gMV07XHJcbiAgICB9IGVsc2UgaWYgKGhhc093bihzdWJHcm91cCwga2V5KSkge1xyXG4gICAgICBzdWJHcm91cCA9IHN1Ykdyb3VwW2tleV07XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBnZXRDb250cm9sIGVycm9yOiBVbmFibGUgdG8gZmluZCBcIiR7a2V5fVwiIGl0ZW0gaW4gRm9ybUdyb3VwLmApO1xyXG4gICAgICBjb25zb2xlLmVycm9yKGRhdGFQb2ludGVyKTtcclxuICAgICAgY29uc29sZS5lcnJvcihmb3JtR3JvdXApO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiBzdWJHcm91cDtcclxufVxyXG4iXX0=
@@ -0,0 +1,54 @@
1
+ // updated from AJV fast format regular expressions:
2
+ // https://github.com/epoberezkin/ajv/blob/master/lib/compile/formats.js
3
+ export const jsonSchemaFormatTests = {
4
+ 'date': /^\d\d\d\d-[0-1]\d-[0-3]\d$/,
5
+ 'time': /^[0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?(?:z|[+-]\d\d:\d\d)?$/i,
6
+ // Modified to allow incomplete entries, such as
7
+ // "2000-03-14T01:59:26.535" (needs "Z") or "2000-03-14T01:59" (needs ":00Z")
8
+ 'date-time': /^\d\d\d\d-[0-1]\d-[0-3]\d[t\s][0-2]\d:[0-5]\d(?::[0-5]\d)?(?:\.\d+)?(?:z|[+-]\d\d:\d\d)?$/i,
9
+ // email (sources from jsen validator):
10
+ // http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address#answer-8829363
11
+ // http://www.w3.org/TR/html5/forms.html#valid-e-mail-address (search for 'willful violation')
12
+ 'email': /^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i,
13
+ 'hostname': /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*$/i,
14
+ // optimized https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html
15
+ 'ipv4': /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,
16
+ // optimized http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
17
+ // tslint:disable-next-line:max-line-length
18
+ 'ipv6': /^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,
19
+ // uri: https://github.com/mafintosh/is-my-json-valid/blob/master/formats.js
20
+ 'uri': /^(?:[a-z][a-z0-9+-.]*)(?::|\/)\/?[^\s]*$/i,
21
+ // uri fragment: https://tools.ietf.org/html/rfc3986#appendix-A
22
+ 'uri-reference': /^(?:(?:[a-z][a-z0-9+-.]*:)?\/\/)?[^\s]*$/i,
23
+ // uri-template: https://tools.ietf.org/html/rfc6570
24
+ // tslint:disable-next-line:max-line-length
25
+ 'uri-template': /^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,
26
+ // For the source: https://gist.github.com/dperini/729294
27
+ // For test cases: https://mathiasbynens.be/demo/url-regex
28
+ // tslint:disable-next-line:max-line-length
29
+ // @todo Delete current URL in favour of the commented out URL rule when this ajv issue is fixed https://github.com/eslint/eslint/issues/7983.
30
+ // tslint:disable-next-line:max-line-length
31
+ // URL: /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)(?:\.(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu,
32
+ // tslint:disable-next-line:max-line-length
33
+ 'url': /^(?:(?:http[s\u017F]?|ftp):\/\/)(?:(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+(?::(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?@)?(?:(?!10(?:\.[0-9]{1,3}){3})(?!127(?:\.[0-9]{1,3}){3})(?!169\.254(?:\.[0-9]{1,3}){2})(?!192\.168(?:\.[0-9]{1,3}){2})(?!172\.(?:1[6-9]|2[0-9]|3[01])(?:\.[0-9]{1,3}){2})(?:[1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])(?:\.(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])){2}(?:\.(?:[1-9][0-9]?|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))|(?:(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)(?:\.(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)*(?:\.(?:(?:[KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]){2,})))(?::[0-9]{2,5})?(?:\/(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?$/i,
34
+ // uuid: http://tools.ietf.org/html/rfc4122
35
+ 'uuid': /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,
36
+ // optimized https://gist.github.com/olmokramer/82ccce673f86db7cda5e
37
+ // tslint:disable-next-line:max-line-length
38
+ 'color': /^\s*(#(?:[\da-f]{3}){1,2}|rgb\((?:\d{1,3},\s*){2}\d{1,3}\)|rgba\((?:\d{1,3},\s*){3}\d*\.?\d+\)|hsl\(\d{1,3}(?:,\s*\d{1,3}%){2}\)|hsla\(\d{1,3}(?:,\s*\d{1,3}%){2},\s*\d*\.?\d+\))\s*$/gi,
39
+ // JSON-pointer: https://tools.ietf.org/html/rfc6901
40
+ 'json-pointer': /^(?:\/(?:[^~/]|~0|~1)*)*$|^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,
41
+ 'relative-json-pointer': /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/,
42
+ 'regex': function (str) {
43
+ if (/[^\\]\\Z/.test(str)) {
44
+ return false;
45
+ }
46
+ try {
47
+ return true;
48
+ }
49
+ catch (e) {
50
+ return false;
51
+ }
52
+ }
53
+ };
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybWF0LXJlZ2V4LmNvbnN0YW50cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWZvcm13b3Jrcy1jb3JlL3NyYy9saWIvc2hhcmVkL2Zvcm1hdC1yZWdleC5jb25zdGFudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0RBQW9EO0FBQ3BELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRztJQUVuQyxNQUFNLEVBQUUsNEJBQTRCO0lBRXBDLE1BQU0sRUFBRSwwREFBMEQ7SUFFbEUsZ0RBQWdEO0lBQ2hELDZFQUE2RTtJQUM3RSxXQUFXLEVBQUUsNEZBQTRGO0lBRXpHLHVDQUF1QztJQUN2QyxtSEFBbUg7SUFDbkgsOEZBQThGO0lBQzlGLE9BQU8sRUFBRSxrSEFBa0g7SUFFM0gsVUFBVSxFQUFFLG9GQUFvRjtJQUVoRyxtSEFBbUg7SUFDbkgsTUFBTSxFQUFFLDJFQUEyRTtJQUVuRiwwR0FBMEc7SUFDMUcsMkNBQTJDO0lBQzNDLE1BQU0sRUFBRSxvcENBQW9wQztJQUU1cEMsNEVBQTRFO0lBQzVFLEtBQUssRUFBRSwyQ0FBMkM7SUFFbEQsK0RBQStEO0lBQy9ELGVBQWUsRUFBRSwyQ0FBMkM7SUFFNUQsb0RBQW9EO0lBQ3BELDJDQUEyQztJQUMzQyxjQUFjLEVBQUUsbUxBQW1MO0lBRW5NLHlEQUF5RDtJQUN6RCwwREFBMEQ7SUFDMUQsMkNBQTJDO0lBQzNDLDhJQUE4STtJQUM5SSwyQ0FBMkM7SUFDM0MsaWdCQUFpZ0I7SUFDamdCLDJDQUEyQztJQUMzQyxLQUFLLEVBQUUsMnJEQUEyckQ7SUFFbHNELDJDQUEyQztJQUMzQyxNQUFNLEVBQUUsOERBQThEO0lBRXRFLG9FQUFvRTtJQUNwRSwyQ0FBMkM7SUFDM0MsT0FBTyxFQUFFLHlMQUF5TDtJQUVsTSxvREFBb0Q7SUFDcEQsY0FBYyxFQUFFLHdGQUF3RjtJQUV4Ryx1QkFBdUIsRUFBRSxrREFBa0Q7SUFFM0UsT0FBTyxFQUFFLFVBQVUsR0FBRztRQUNwQixJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUFDLE9BQU8sS0FBSyxDQUFDO1FBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUM7WUFDSCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztDQUVGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB1cGRhdGVkIGZyb20gQUpWIGZhc3QgZm9ybWF0IHJlZ3VsYXIgZXhwcmVzc2lvbnM6XHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9lcG9iZXJlemtpbi9hanYvYmxvYi9tYXN0ZXIvbGliL2NvbXBpbGUvZm9ybWF0cy5qc1xyXG5cclxuZXhwb3J0IGNvbnN0IGpzb25TY2hlbWFGb3JtYXRUZXN0cyA9IHtcclxuXHJcbiAgJ2RhdGUnOiAvXlxcZFxcZFxcZFxcZC1bMC0xXVxcZC1bMC0zXVxcZCQvLFxyXG5cclxuICAndGltZSc6IC9eWzAtMl1cXGQ6WzAtNV1cXGQ6WzAtNV1cXGQoPzpcXC5cXGQrKT8oPzp6fFsrLV1cXGRcXGQ6XFxkXFxkKT8kL2ksXHJcblxyXG4gIC8vIE1vZGlmaWVkIHRvIGFsbG93IGluY29tcGxldGUgZW50cmllcywgc3VjaCBhc1xyXG4gIC8vIFwiMjAwMC0wMy0xNFQwMTo1OToyNi41MzVcIiAobmVlZHMgXCJaXCIpIG9yIFwiMjAwMC0wMy0xNFQwMTo1OVwiIChuZWVkcyBcIjowMFpcIilcclxuICAnZGF0ZS10aW1lJzogL15cXGRcXGRcXGRcXGQtWzAtMV1cXGQtWzAtM11cXGRbdFxcc11bMC0yXVxcZDpbMC01XVxcZCg/OjpbMC01XVxcZCk/KD86XFwuXFxkKyk/KD86enxbKy1dXFxkXFxkOlxcZFxcZCk/JC9pLFxyXG5cclxuICAvLyBlbWFpbCAoc291cmNlcyBmcm9tIGpzZW4gdmFsaWRhdG9yKTpcclxuICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzIwMTMyMy91c2luZy1hLXJlZ3VsYXItZXhwcmVzc2lvbi10by12YWxpZGF0ZS1hbi1lbWFpbC1hZGRyZXNzI2Fuc3dlci04ODI5MzYzXHJcbiAgLy8gaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDUvZm9ybXMuaHRtbCN2YWxpZC1lLW1haWwtYWRkcmVzcyAoc2VhcmNoIGZvciAnd2lsbGZ1bCB2aW9sYXRpb24nKVxyXG4gICdlbWFpbCc6IC9eW2EtejAtOS4hIyQlJicqKy89P15fYHt8fX4tXStAW2EtejAtOV0oPzpbYS16MC05LV17MCw2MX1bYS16MC05XSk/KD86XFwuW2EtejAtOV0oPzpbYS16MC05LV17MCw2MX1bYS16MC05XSk/KSokL2ksXHJcblxyXG4gICdob3N0bmFtZSc6IC9eW2EtejAtOV0oPzpbYS16MC05LV17MCw2MX1bYS16MC05XSk/KD86XFwuW2EtejAtOV0oPzpbLTAtOWEtel17MCw2MX1bMC05YS16XSk/KSokL2ksXHJcblxyXG4gIC8vIG9wdGltaXplZCBodHRwczovL3d3dy5zYWZhcmlib29rc29ubGluZS5jb20vbGlicmFyeS92aWV3L3JlZ3VsYXItZXhwcmVzc2lvbnMtY29va2Jvb2svOTc4MDU5NjgwMjgzNy9jaDA3czE2Lmh0bWxcclxuICAnaXB2NCc6IC9eKD86KD86MjVbMC01XXwyWzAtNF1cXGR8WzAxXT9cXGRcXGQ/KVxcLil7M30oPzoyNVswLTVdfDJbMC00XVxcZHxbMDFdP1xcZFxcZD8pJC8sXHJcblxyXG4gIC8vIG9wdGltaXplZCBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzUzNDk3L3JlZ3VsYXItZXhwcmVzc2lvbi10aGF0LW1hdGNoZXMtdmFsaWQtaXB2Ni1hZGRyZXNzZXNcclxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXHJcbiAgJ2lwdjYnOiAvXlxccyooPzooPzooPzpbMC05YS1mXXsxLDR9Oil7N30oPzpbMC05YS1mXXsxLDR9fDopKXwoPzooPzpbMC05YS1mXXsxLDR9Oil7Nn0oPzo6WzAtOWEtZl17MSw0fXwoPzooPzoyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoPzpcXC4oPzoyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkpezN9KXw6KSl8KD86KD86WzAtOWEtZl17MSw0fTopezV9KD86KD86KD86OlswLTlhLWZdezEsNH0pezEsMn0pfDooPzooPzoyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoPzpcXC4oPzoyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkpezN9KXw6KSl8KD86KD86WzAtOWEtZl17MSw0fTopezR9KD86KD86KD86OlswLTlhLWZdezEsNH0pezEsM30pfCg/Oig/OjpbMC05YS1mXXsxLDR9KT86KD86KD86MjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKD86XFwuKD86MjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSkpfDopKXwoPzooPzpbMC05YS1mXXsxLDR9Oil7M30oPzooPzooPzo6WzAtOWEtZl17MSw0fSl7MSw0fSl8KD86KD86OlswLTlhLWZdezEsNH0pezAsMn06KD86KD86MjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKD86XFwuKD86MjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSkpfDopKXwoPzooPzpbMC05YS1mXXsxLDR9Oil7Mn0oPzooPzooPzo6WzAtOWEtZl17MSw0fSl7MSw1fSl8KD86KD86OlswLTlhLWZdezEsNH0pezAsM306KD86KD86MjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKD86XFwuKD86MjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSkpfDopKXwoPzooPzpbMC05YS1mXXsxLDR9Oil7MX0oPzooPzooPzo6WzAtOWEtZl17MSw0fSl7MSw2fSl8KD86KD86OlswLTlhLWZdezEsNH0pezAsNH06KD86KD86MjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKD86XFwuKD86MjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSkpfDopKXwoPzo6KD86KD86KD86OlswLTlhLWZdezEsNH0pezEsN30pfCg/Oig/OjpbMC05YS1mXXsxLDR9KXswLDV9Oig/Oig/OjI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSg/OlxcLig/OjI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pKXw6KSkpKD86JS4rKT9cXHMqJC9pLFxyXG5cclxuICAvLyB1cmk6IGh0dHBzOi8vZ2l0aHViLmNvbS9tYWZpbnRvc2gvaXMtbXktanNvbi12YWxpZC9ibG9iL21hc3Rlci9mb3JtYXRzLmpzXHJcbiAgJ3VyaSc6IC9eKD86W2Etel1bYS16MC05Ky0uXSopKD86OnxcXC8pXFwvP1teXFxzXSokL2ksXHJcblxyXG4gIC8vIHVyaSBmcmFnbWVudDogaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzM5ODYjYXBwZW5kaXgtQVxyXG4gICd1cmktcmVmZXJlbmNlJzogL14oPzooPzpbYS16XVthLXowLTkrLS5dKjopP1xcL1xcLyk/W15cXHNdKiQvaSxcclxuXHJcbiAgLy8gdXJpLXRlbXBsYXRlOiBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNjU3MFxyXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcclxuICAndXJpLXRlbXBsYXRlJzogL14oPzooPzpbXlxceDAwLVxceDIwXCInPD4lXFxcXF5ge3x9XXwlWzAtOWEtZl17Mn0pfFxce1srIy4vOz8mPSwhQHxdPyg/OlthLXowLTlfXXwlWzAtOWEtZl17Mn0pKyg/OjpbMS05XVswLTldezAsM318XFwqKT8oPzosKD86W2EtejAtOV9dfCVbMC05YS1mXXsyfSkrKD86OlsxLTldWzAtOV17MCwzfXxcXCopPykqXFx9KSokL2ksXHJcblxyXG4gIC8vIEZvciB0aGUgc291cmNlOiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9kcGVyaW5pLzcyOTI5NFxyXG4gIC8vIEZvciB0ZXN0IGNhc2VzOiBodHRwczovL21hdGhpYXNieW5lbnMuYmUvZGVtby91cmwtcmVnZXhcclxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXHJcbiAgLy8gQHRvZG8gRGVsZXRlIGN1cnJlbnQgVVJMIGluIGZhdm91ciBvZiB0aGUgY29tbWVudGVkIG91dCBVUkwgcnVsZSB3aGVuIHRoaXMgYWp2IGlzc3VlIGlzIGZpeGVkIGh0dHBzOi8vZ2l0aHViLmNvbS9lc2xpbnQvZXNsaW50L2lzc3Vlcy83OTgzLlxyXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcclxuICAvLyBVUkw6IC9eKD86KD86aHR0cHM/fGZ0cCk6XFwvXFwvKSg/OlxcUysoPzo6XFxTKik/QCk/KD86KD8hMTAoPzpcXC5cXGR7MSwzfSl7M30pKD8hMTI3KD86XFwuXFxkezEsM30pezN9KSg/ITE2OVxcLjI1NCg/OlxcLlxcZHsxLDN9KXsyfSkoPyExOTJcXC4xNjgoPzpcXC5cXGR7MSwzfSl7Mn0pKD8hMTcyXFwuKD86MVs2LTldfDJcXGR8M1swLTFdKSg/OlxcLlxcZHsxLDN9KXsyfSkoPzpbMS05XVxcZD98MVxcZFxcZHwyWzAxXVxcZHwyMlswLTNdKSg/OlxcLig/OjE/XFxkezEsMn18MlswLTRdXFxkfDI1WzAtNV0pKXsyfSg/OlxcLig/OlsxLTldXFxkP3wxXFxkXFxkfDJbMC00XVxcZHwyNVswLTRdKSl8KD86KD86W2EtelxcdXswMGExfS1cXHV7ZmZmZn0wLTldKy0/KSpbYS16XFx1ezAwYTF9LVxcdXtmZmZmfTAtOV0rKSg/OlxcLig/OlthLXpcXHV7MDBhMX0tXFx1e2ZmZmZ9MC05XSstPykqW2EtelxcdXswMGExfS1cXHV7ZmZmZn0wLTldKykqKD86XFwuKD86W2EtelxcdXswMGExfS1cXHV7ZmZmZn1dezIsfSkpKSg/OjpcXGR7Miw1fSk/KD86XFwvW15cXHNdKik/JC9pdSxcclxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXHJcbiAgJ3VybCc6IC9eKD86KD86aHR0cFtzXFx1MDE3Rl0/fGZ0cCk6XFwvXFwvKSg/Oig/OltcXDAtXFx4MDhcXHgwRS1cXHgxRiEtXFx4OUZcXHhBMS1cXHUxNjdGXFx1MTY4MS1cXHUxRkZGXFx1MjAwQi1cXHUyMDI3XFx1MjAyQS1cXHUyMDJFXFx1MjAzMC1cXHUyMDVFXFx1MjA2MC1cXHUyRkZGXFx1MzAwMS1cXHVEN0ZGXFx1RTAwMC1cXHVGRUZFXFx1RkYwMC1cXHVGRkZGXXxbXFx1RDgwMC1cXHVEQkZGXVtcXHVEQzAwLVxcdURGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdKSsoPzo6KD86W1xcMC1cXHgwOFxceDBFLVxceDFGIS1cXHg5RlxceEExLVxcdTE2N0ZcXHUxNjgxLVxcdTFGRkZcXHUyMDBCLVxcdTIwMjdcXHUyMDJBLVxcdTIwMkVcXHUyMDMwLVxcdTIwNUVcXHUyMDYwLVxcdTJGRkZcXHUzMDAxLVxcdUQ3RkZcXHVFMDAwLVxcdUZFRkVcXHVGRjAwLVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdW1xcdURDMDAtXFx1REZGRl18W1xcdUQ4MDAtXFx1REJGRl0oPyFbXFx1REMwMC1cXHVERkZGXSl8KD86W15cXHVEODAwLVxcdURCRkZdfF4pW1xcdURDMDAtXFx1REZGRl0pKik/QCk/KD86KD8hMTAoPzpcXC5bMC05XXsxLDN9KXszfSkoPyExMjcoPzpcXC5bMC05XXsxLDN9KXszfSkoPyExNjlcXC4yNTQoPzpcXC5bMC05XXsxLDN9KXsyfSkoPyExOTJcXC4xNjgoPzpcXC5bMC05XXsxLDN9KXsyfSkoPyExNzJcXC4oPzoxWzYtOV18MlswLTldfDNbMDFdKSg/OlxcLlswLTldezEsM30pezJ9KSg/OlsxLTldWzAtOV0/fDFbMC05XVswLTldfDJbMDFdWzAtOV18MjJbMC0zXSkoPzpcXC4oPzoxP1swLTldezEsMn18MlswLTRdWzAtOV18MjVbMC01XSkpezJ9KD86XFwuKD86WzEtOV1bMC05XT98MVswLTldWzAtOV18MlswLTRdWzAtOV18MjVbMC00XSkpfCg/Oig/Oig/OlswLTlLU2EtelxceEExLVxcdUQ3RkZcXHVFMDAwLVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdKSstPykqKD86WzAtOUtTYS16XFx4QTEtXFx1RDdGRlxcdUUwMDAtXFx1RkZGRl18W1xcdUQ4MDAtXFx1REJGRl0oPyFbXFx1REMwMC1cXHVERkZGXSl8KD86W15cXHVEODAwLVxcdURCRkZdfF4pW1xcdURDMDAtXFx1REZGRl0pKykoPzpcXC4oPzooPzpbMC05S1NhLXpcXHhBMS1cXHVEN0ZGXFx1RTAwMC1cXHVGRkZGXXxbXFx1RDgwMC1cXHVEQkZGXSg/IVtcXHVEQzAwLVxcdURGRkZdKXwoPzpbXlxcdUQ4MDAtXFx1REJGRl18XilbXFx1REMwMC1cXHVERkZGXSkrLT8pKig/OlswLTlLU2EtelxceEExLVxcdUQ3RkZcXHVFMDAwLVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdKSspKig/OlxcLig/Oig/OltLU2EtelxceEExLVxcdUQ3RkZcXHVFMDAwLVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdKXsyLH0pKSkoPzo6WzAtOV17Miw1fSk/KD86XFwvKD86W1xcMC1cXHgwOFxceDBFLVxceDFGIS1cXHg5RlxceEExLVxcdTE2N0ZcXHUxNjgxLVxcdTFGRkZcXHUyMDBCLVxcdTIwMjdcXHUyMDJBLVxcdTIwMkVcXHUyMDMwLVxcdTIwNUVcXHUyMDYwLVxcdTJGRkZcXHUzMDAxLVxcdUQ3RkZcXHVFMDAwLVxcdUZFRkVcXHVGRjAwLVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdW1xcdURDMDAtXFx1REZGRl18W1xcdUQ4MDAtXFx1REJGRl0oPyFbXFx1REMwMC1cXHVERkZGXSl8KD86W15cXHVEODAwLVxcdURCRkZdfF4pW1xcdURDMDAtXFx1REZGRl0pKik/JC9pLFxyXG5cclxuICAvLyB1dWlkOiBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0MTIyXHJcbiAgJ3V1aWQnOiAvXig/OnVybjp1dWlkOik/WzAtOWEtZl17OH0tKD86WzAtOWEtZl17NH0tKXszfVswLTlhLWZdezEyfSQvaSxcclxuXHJcbiAgLy8gb3B0aW1pemVkIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL29sbW9rcmFtZXIvODJjY2NlNjczZjg2ZGI3Y2RhNWVcclxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXHJcbiAgJ2NvbG9yJzogL15cXHMqKCMoPzpbXFxkYS1mXXszfSl7MSwyfXxyZ2JcXCgoPzpcXGR7MSwzfSxcXHMqKXsyfVxcZHsxLDN9XFwpfHJnYmFcXCgoPzpcXGR7MSwzfSxcXHMqKXszfVxcZCpcXC4/XFxkK1xcKXxoc2xcXChcXGR7MSwzfSg/OixcXHMqXFxkezEsM30lKXsyfVxcKXxoc2xhXFwoXFxkezEsM30oPzosXFxzKlxcZHsxLDN9JSl7Mn0sXFxzKlxcZCpcXC4/XFxkK1xcKSlcXHMqJC9naSxcclxuXHJcbiAgLy8gSlNPTi1wb2ludGVyOiBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNjkwMVxyXG4gICdqc29uLXBvaW50ZXInOiAvXig/OlxcLyg/Oltefi9dfH4wfH4xKSopKiR8XiMoPzpcXC8oPzpbYS16MC05X1xcLS4hJCYnKCkqKyw7Oj1AXXwlWzAtOWEtZl17Mn18fjB8fjEpKikqJC9pLFxyXG5cclxuICAncmVsYXRpdmUtanNvbi1wb2ludGVyJzogL14oPzowfFsxLTldWzAtOV0qKSg/OiN8KD86XFwvKD86W15+L118fjB8fjEpKikqKSQvLFxyXG5cclxuICAncmVnZXgnOiBmdW5jdGlvbiAoc3RyKSB7XHJcbiAgICBpZiAoL1teXFxcXF1cXFxcWi8udGVzdChzdHIpKSB7IHJldHVybiBmYWxzZTsgfVxyXG4gICAgdHJ5IHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG59O1xyXG5cclxuZXhwb3J0IHR5cGUgSnNvblNjaGVtYUZvcm1hdE5hbWVzID1cclxuICAnZGF0ZScgfCAndGltZScgfCAnZGF0ZS10aW1lJyB8ICdlbWFpbCcgfCAnaG9zdG5hbWUnIHwgJ2lwdjQnIHwgJ2lwdjYnIHxcclxuICAndXJpJyB8ICd1cmktcmVmZXJlbmNlJyB8ICd1cmktdGVtcGxhdGUnIHwgJ3VybCcgfCAndXVpZCcgfCAnY29sb3InIHxcclxuICAnanNvbi1wb2ludGVyJyB8ICdyZWxhdGl2ZS1qc29uLXBvaW50ZXInIHwgJ3JlZ2V4JztcclxuIl19