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