@aquera/ngx-smart-table 0.0.2-alpha

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 (169) hide show
  1. package/README.md +152 -0
  2. package/aquera-ngx-smart-table.d.ts +5 -0
  3. package/esm2020/aquera-ngx-smart-table.mjs +5 -0
  4. package/esm2020/lib/builder/components/builder-preview/builder-preview.component.mjs +63 -0
  5. package/esm2020/lib/builder/components/builder-toolbar/builder-toolbar.component.mjs +115 -0
  6. package/esm2020/lib/builder/components/column-editor/column-editor.component.mjs +206 -0
  7. package/esm2020/lib/builder/components/column-list/column-list.component.mjs +125 -0
  8. package/esm2020/lib/builder/components/definition-builder/definition-builder.component.mjs +105 -0
  9. package/esm2020/lib/builder/components/table-config-editor/table-config-editor.component.mjs +132 -0
  10. package/esm2020/lib/builder/definition-builder.module.mjs +70 -0
  11. package/esm2020/lib/builder/models/builder-state.interface.mjs +5 -0
  12. package/esm2020/lib/builder/services/definition-builder.service.mjs +251 -0
  13. package/esm2020/lib/builder/services/definition-export.service.mjs +167 -0
  14. package/esm2020/lib/builder/services/definition-import.service.mjs +193 -0
  15. package/esm2020/lib/builder/services/sample-data-generator.service.mjs +126 -0
  16. package/esm2020/lib/builder/utils/config-validator.util.mjs +165 -0
  17. package/esm2020/lib/builder/utils/typescript-generator.util.mjs +206 -0
  18. package/esm2020/lib/editors/index.mjs +9 -0
  19. package/esm2020/lib/editors/nile-autocomplete-editor.mjs +228 -0
  20. package/esm2020/lib/editors/nile-calendar-editor.mjs +214 -0
  21. package/esm2020/lib/editors/nile-date-picker-editor.mjs +227 -0
  22. package/esm2020/lib/editors/nile-input-editor.mjs +235 -0
  23. package/esm2020/lib/editors/nile-select-editor.mjs +317 -0
  24. package/esm2020/lib/factories/column-config.factory.mjs +231 -0
  25. package/esm2020/lib/models/autosave-config.interface.mjs +8 -0
  26. package/esm2020/lib/models/base-column-config.class.mjs +253 -0
  27. package/esm2020/lib/models/cell-strategies.interface.mjs +6 -0
  28. package/esm2020/lib/models/cell-types.mjs +147 -0
  29. package/esm2020/lib/models/column-action.interface.mjs +6 -0
  30. package/esm2020/lib/models/column-config.interface.mjs +43 -0
  31. package/esm2020/lib/models/column-config.utils.mjs +101 -0
  32. package/esm2020/lib/models/row-action.interface.mjs +5 -0
  33. package/esm2020/lib/models/row-validator.interface.mjs +2 -0
  34. package/esm2020/lib/models/schema-validation.interface.mjs +2 -0
  35. package/esm2020/lib/models/sheet-action.interface.mjs +5 -0
  36. package/esm2020/lib/models/sheet-config.interface.mjs +5 -0
  37. package/esm2020/lib/models/table-config.interface.mjs +106 -0
  38. package/esm2020/lib/models/table-validator.interface.mjs +2 -0
  39. package/esm2020/lib/models/workbook-action.interface.mjs +5 -0
  40. package/esm2020/lib/models/workbook-config.interface.mjs +5 -0
  41. package/esm2020/lib/renderer/components/st-add-column-button/st-add-column-button.component.mjs +24 -0
  42. package/esm2020/lib/renderer/components/st-cell/st-cell.component.mjs +391 -0
  43. package/esm2020/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.mjs +103 -0
  44. package/esm2020/lib/renderer/components/st-column-filter/st-column-filter.component.mjs +383 -0
  45. package/esm2020/lib/renderer/components/st-column-menu/st-column-menu.component.mjs +232 -0
  46. package/esm2020/lib/renderer/components/st-column-visibility/st-column-visibility.component.mjs +97 -0
  47. package/esm2020/lib/renderer/components/st-header/st-header.component.mjs +157 -0
  48. package/esm2020/lib/renderer/components/st-pagination/st-pagination.component.mjs +87 -0
  49. package/esm2020/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.mjs +167 -0
  50. package/esm2020/lib/renderer/components/st-sheet/st-sheet.component.mjs +165 -0
  51. package/esm2020/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.mjs +112 -0
  52. package/esm2020/lib/renderer/components/st-table/st-table.component.mjs +1246 -0
  53. package/esm2020/lib/renderer/components/st-table-actions/st-table-actions.component.mjs +171 -0
  54. package/esm2020/lib/renderer/components/st-workbook/st-workbook.component.mjs +489 -0
  55. package/esm2020/lib/renderer/directives/click-outside.directive.mjs +28 -0
  56. package/esm2020/lib/renderer/directives/st-column-resize.directive.mjs +108 -0
  57. package/esm2020/lib/renderer/directives/st-keyboard-navigation.directive.mjs +73 -0
  58. package/esm2020/lib/renderer/models/cell-state.interface.mjs +66 -0
  59. package/esm2020/lib/renderer/models/cell.class.mjs +389 -0
  60. package/esm2020/lib/renderer/models/row-validation-state.interface.mjs +7 -0
  61. package/esm2020/lib/renderer/models/sheet-state.class.mjs +90 -0
  62. package/esm2020/lib/renderer/models/sheet-state.interface.mjs +5 -0
  63. package/esm2020/lib/renderer/models/table-state.class.mjs +841 -0
  64. package/esm2020/lib/renderer/models/table-state.interface.mjs +5 -0
  65. package/esm2020/lib/renderer/models/table-types.mjs +29 -0
  66. package/esm2020/lib/renderer/models/table-validation-state.interface.mjs +7 -0
  67. package/esm2020/lib/renderer/models/workbook-state.class.mjs +174 -0
  68. package/esm2020/lib/renderer/models/workbook-state.interface.mjs +5 -0
  69. package/esm2020/lib/renderer/models/z-index.enum.mjs +55 -0
  70. package/esm2020/lib/schemas/table-config.schema.mjs +472 -0
  71. package/esm2020/lib/services/autosave.service.mjs +92 -0
  72. package/esm2020/lib/services/custom-validation-rules.util.mjs +124 -0
  73. package/esm2020/lib/services/json-schema-validator.service.mjs +216 -0
  74. package/esm2020/lib/services/row-validation.service.mjs +42 -0
  75. package/esm2020/lib/services/validation-logger.service.mjs +177 -0
  76. package/esm2020/lib/services/virtual-scroll.service.mjs +52 -0
  77. package/esm2020/lib/shared/shared-table-components.module.mjs +35 -0
  78. package/esm2020/lib/smart-table.module.mjs +124 -0
  79. package/esm2020/lib/strategies/default-editors.mjs +433 -0
  80. package/esm2020/lib/strategies/default-formatters.mjs +238 -0
  81. package/esm2020/lib/strategies/default-validators.mjs +327 -0
  82. package/esm2020/public-api.mjs +146 -0
  83. package/fesm2015/aquera-ngx-smart-table.mjs +11860 -0
  84. package/fesm2015/aquera-ngx-smart-table.mjs.map +1 -0
  85. package/fesm2020/aquera-ngx-smart-table.mjs +11897 -0
  86. package/fesm2020/aquera-ngx-smart-table.mjs.map +1 -0
  87. package/lib/builder/components/builder-preview/builder-preview.component.d.ts +31 -0
  88. package/lib/builder/components/builder-toolbar/builder-toolbar.component.d.ts +53 -0
  89. package/lib/builder/components/column-editor/column-editor.component.d.ts +69 -0
  90. package/lib/builder/components/column-list/column-list.component.d.ts +65 -0
  91. package/lib/builder/components/definition-builder/definition-builder.component.d.ts +58 -0
  92. package/lib/builder/components/table-config-editor/table-config-editor.component.d.ts +32 -0
  93. package/lib/builder/definition-builder.module.d.ts +15 -0
  94. package/lib/builder/models/builder-state.interface.d.ts +93 -0
  95. package/lib/builder/services/definition-builder.service.d.ts +80 -0
  96. package/lib/builder/services/definition-export.service.d.ts +59 -0
  97. package/lib/builder/services/definition-import.service.d.ts +31 -0
  98. package/lib/builder/services/sample-data-generator.service.d.ts +41 -0
  99. package/lib/builder/utils/config-validator.util.d.ts +32 -0
  100. package/lib/builder/utils/typescript-generator.util.d.ts +29 -0
  101. package/lib/editors/index.d.ts +8 -0
  102. package/lib/editors/nile-autocomplete-editor.d.ts +102 -0
  103. package/lib/editors/nile-calendar-editor.d.ts +89 -0
  104. package/lib/editors/nile-date-picker-editor.d.ts +95 -0
  105. package/lib/editors/nile-input-editor.d.ts +67 -0
  106. package/lib/editors/nile-select-editor.d.ts +109 -0
  107. package/lib/factories/column-config.factory.d.ts +73 -0
  108. package/lib/models/autosave-config.interface.d.ts +23 -0
  109. package/lib/models/base-column-config.class.d.ts +115 -0
  110. package/lib/models/cell-strategies.interface.d.ts +181 -0
  111. package/lib/models/cell-types.d.ts +337 -0
  112. package/lib/models/column-action.interface.d.ts +86 -0
  113. package/lib/models/column-config.interface.d.ts +272 -0
  114. package/lib/models/column-config.utils.d.ts +37 -0
  115. package/lib/models/row-action.interface.d.ts +86 -0
  116. package/lib/models/row-validator.interface.d.ts +37 -0
  117. package/lib/models/schema-validation.interface.d.ts +42 -0
  118. package/lib/models/sheet-action.interface.d.ts +59 -0
  119. package/lib/models/sheet-config.interface.d.ts +41 -0
  120. package/lib/models/table-config.interface.d.ts +245 -0
  121. package/lib/models/table-validator.interface.d.ts +40 -0
  122. package/lib/models/workbook-action.interface.d.ts +90 -0
  123. package/lib/models/workbook-config.interface.d.ts +107 -0
  124. package/lib/renderer/components/st-add-column-button/st-add-column-button.component.d.ts +9 -0
  125. package/lib/renderer/components/st-cell/st-cell.component.d.ts +69 -0
  126. package/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.d.ts +39 -0
  127. package/lib/renderer/components/st-column-filter/st-column-filter.component.d.ts +139 -0
  128. package/lib/renderer/components/st-column-menu/st-column-menu.component.d.ts +81 -0
  129. package/lib/renderer/components/st-column-visibility/st-column-visibility.component.d.ts +44 -0
  130. package/lib/renderer/components/st-header/st-header.component.d.ts +93 -0
  131. package/lib/renderer/components/st-pagination/st-pagination.component.d.ts +42 -0
  132. package/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.d.ts +67 -0
  133. package/lib/renderer/components/st-sheet/st-sheet.component.d.ts +98 -0
  134. package/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.d.ts +58 -0
  135. package/lib/renderer/components/st-table/st-table.component.d.ts +349 -0
  136. package/lib/renderer/components/st-table-actions/st-table-actions.component.d.ts +77 -0
  137. package/lib/renderer/components/st-workbook/st-workbook.component.d.ts +235 -0
  138. package/lib/renderer/directives/click-outside.directive.d.ts +10 -0
  139. package/lib/renderer/directives/st-column-resize.directive.d.ts +44 -0
  140. package/lib/renderer/directives/st-keyboard-navigation.directive.d.ts +15 -0
  141. package/lib/renderer/models/cell-state.interface.d.ts +118 -0
  142. package/lib/renderer/models/cell.class.d.ts +174 -0
  143. package/lib/renderer/models/row-validation-state.interface.d.ts +27 -0
  144. package/lib/renderer/models/sheet-state.class.d.ts +67 -0
  145. package/lib/renderer/models/sheet-state.interface.d.ts +55 -0
  146. package/lib/renderer/models/table-state.class.d.ts +313 -0
  147. package/lib/renderer/models/table-state.interface.d.ts +18 -0
  148. package/lib/renderer/models/table-types.d.ts +228 -0
  149. package/lib/renderer/models/table-validation-state.interface.d.ts +34 -0
  150. package/lib/renderer/models/workbook-state.class.d.ts +117 -0
  151. package/lib/renderer/models/workbook-state.interface.d.ts +71 -0
  152. package/lib/renderer/models/z-index.enum.d.ts +44 -0
  153. package/lib/schemas/table-config.schema.d.ts +455 -0
  154. package/lib/services/autosave.service.d.ts +73 -0
  155. package/lib/services/custom-validation-rules.util.d.ts +12 -0
  156. package/lib/services/json-schema-validator.service.d.ts +49 -0
  157. package/lib/services/row-validation.service.d.ts +17 -0
  158. package/lib/services/validation-logger.service.d.ts +87 -0
  159. package/lib/services/virtual-scroll.service.d.ts +44 -0
  160. package/lib/shared/shared-table-components.module.d.ts +9 -0
  161. package/lib/smart-table.module.d.ts +26 -0
  162. package/lib/strategies/default-editors.d.ts +109 -0
  163. package/lib/strategies/default-formatters.d.ts +116 -0
  164. package/lib/strategies/default-validators.d.ts +113 -0
  165. package/package.json +42 -0
  166. package/public-api.d.ts +70 -0
  167. package/src/lib/builder/README.md +30 -0
  168. package/src/lib/editors/README.md +303 -0
  169. package/src/lib/renderer/components/st-column-filter/README.md +286 -0
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Default formatter implementations
3
+ */
4
+ import { isNullOrUndefined, isValidDate } from '../models/cell-types';
5
+ /**
6
+ * String formatter - default string display
7
+ */
8
+ export class StringFormatter {
9
+ constructor(options) {
10
+ this.options = options;
11
+ }
12
+ format(value) {
13
+ if (isNullOrUndefined(value)) {
14
+ return '';
15
+ }
16
+ let result = String(value);
17
+ if (this.options?.trim) {
18
+ result = result.trim();
19
+ }
20
+ if (this.options?.toUpperCase) {
21
+ result = result.toUpperCase();
22
+ }
23
+ if (this.options?.toLowerCase) {
24
+ result = result.toLowerCase();
25
+ }
26
+ if (this.options?.maxLength && result.length > this.options.maxLength) {
27
+ const ellipsis = this.options.ellipsis ?? '...';
28
+ result = result.substring(0, this.options.maxLength - ellipsis.length) + ellipsis;
29
+ }
30
+ return result;
31
+ }
32
+ }
33
+ /**
34
+ * Number formatter - formats numbers with decimals
35
+ */
36
+ export class NumberFormatter {
37
+ constructor(options) {
38
+ this.options = options;
39
+ }
40
+ format(value) {
41
+ if (isNullOrUndefined(value) || isNaN(value)) {
42
+ return '';
43
+ }
44
+ const decimals = this.options?.decimals ?? 2;
45
+ const fixed = value.toFixed(decimals);
46
+ const [integerPart, decimalPart] = fixed.split('.');
47
+ // Add thousands separator
48
+ const thousandsSeparator = this.options?.thousandsSeparator ?? ',';
49
+ const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator);
50
+ // Combine integer and decimal parts
51
+ const decimalSeparator = this.options?.decimalSeparator ?? '.';
52
+ const result = decimalPart ? `${formattedInteger}${decimalSeparator}${decimalPart}` : formattedInteger;
53
+ // Add prefix and suffix
54
+ const prefix = this.options?.prefix ?? '';
55
+ const suffix = this.options?.suffix ?? '';
56
+ return `${prefix}${result}${suffix}`;
57
+ }
58
+ }
59
+ /**
60
+ * Currency formatter - formats currency values
61
+ */
62
+ export class CurrencyFormatter {
63
+ constructor(options) {
64
+ this.options = options;
65
+ }
66
+ format(value) {
67
+ if (isNullOrUndefined(value) || isNaN(value)) {
68
+ return '';
69
+ }
70
+ const locale = this.options?.locale ?? 'en-US';
71
+ const currency = this.options?.currency ?? 'USD';
72
+ const decimals = this.options?.decimals ?? 2;
73
+ try {
74
+ return new Intl.NumberFormat(locale, {
75
+ style: 'currency',
76
+ currency,
77
+ minimumFractionDigits: decimals,
78
+ maximumFractionDigits: decimals
79
+ }).format(value);
80
+ }
81
+ catch (error) {
82
+ // Fallback if Intl is not supported
83
+ return `$${value.toFixed(decimals)}`;
84
+ }
85
+ }
86
+ }
87
+ /**
88
+ * Percentage formatter
89
+ */
90
+ export class PercentageFormatter {
91
+ constructor(options) {
92
+ this.options = options;
93
+ }
94
+ format(value) {
95
+ if (isNullOrUndefined(value) || isNaN(value)) {
96
+ return '';
97
+ }
98
+ const decimals = this.options?.decimals ?? 2;
99
+ const multiplier = this.options?.multiplier ?? 1;
100
+ const percentage = value * multiplier;
101
+ return `${percentage.toFixed(decimals)}%`;
102
+ }
103
+ }
104
+ /**
105
+ * Date formatter - locale-aware date formatting
106
+ */
107
+ export class DateFormatter {
108
+ constructor(options) {
109
+ this.options = options;
110
+ }
111
+ format(value) {
112
+ if (isNullOrUndefined(value)) {
113
+ return '';
114
+ }
115
+ // Convert to Date if it's a string or number
116
+ let date;
117
+ if (value instanceof Date) {
118
+ date = value;
119
+ }
120
+ else {
121
+ date = new Date(value);
122
+ }
123
+ if (!isValidDate(date)) {
124
+ return '';
125
+ }
126
+ const locale = this.options?.locale ?? 'en-US';
127
+ try {
128
+ if (this.options?.format) {
129
+ return this.formatCustom(date);
130
+ }
131
+ return new Intl.DateTimeFormat(locale, {
132
+ dateStyle: this.options?.dateStyle ?? 'medium',
133
+ timeStyle: this.options?.timeStyle
134
+ }).format(date);
135
+ }
136
+ catch (error) {
137
+ return date.toLocaleDateString();
138
+ }
139
+ }
140
+ formatCustom(date) {
141
+ // Simple custom formatting (can be extended)
142
+ const format = this.options?.format ?? 'YYYY-MM-DD';
143
+ const year = date.getFullYear();
144
+ const month = String(date.getMonth() + 1).padStart(2, '0');
145
+ const day = String(date.getDate()).padStart(2, '0');
146
+ const hours = String(date.getHours()).padStart(2, '0');
147
+ const minutes = String(date.getMinutes()).padStart(2, '0');
148
+ const seconds = String(date.getSeconds()).padStart(2, '0');
149
+ return format
150
+ .replace('YYYY', String(year))
151
+ .replace('MM', month)
152
+ .replace('DD', day)
153
+ .replace('HH', hours)
154
+ .replace('mm', minutes)
155
+ .replace('ss', seconds);
156
+ }
157
+ }
158
+ /**
159
+ * Boolean formatter - formats boolean values
160
+ */
161
+ export class BooleanFormatter {
162
+ constructor(options) {
163
+ this.options = options;
164
+ }
165
+ format(value) {
166
+ if (isNullOrUndefined(value)) {
167
+ return this.options?.nullValue ?? '';
168
+ }
169
+ return value
170
+ ? (this.options?.trueValue ?? 'Yes')
171
+ : (this.options?.falseValue ?? 'No');
172
+ }
173
+ }
174
+ /**
175
+ * Array formatter - formats array values
176
+ */
177
+ export class ArrayFormatter {
178
+ constructor(options) {
179
+ this.options = options;
180
+ }
181
+ format(value) {
182
+ if (isNullOrUndefined(value) || !Array.isArray(value)) {
183
+ return '';
184
+ }
185
+ if (value.length === 0) {
186
+ return '';
187
+ }
188
+ const separator = this.options?.separator ?? ', ';
189
+ const maxItems = this.options?.maxItems;
190
+ const itemFormatter = this.options?.itemFormatter ?? ((item) => String(item));
191
+ let items = value.map(itemFormatter);
192
+ if (maxItems && items.length > maxItems) {
193
+ const ellipsis = this.options?.ellipsis ?? '...';
194
+ items = items.slice(0, maxItems);
195
+ items.push(ellipsis);
196
+ }
197
+ return items.join(separator);
198
+ }
199
+ }
200
+ /**
201
+ * Template formatter - formats values using a template string
202
+ */
203
+ export class TemplateFormatter {
204
+ constructor(template) {
205
+ this.template = template;
206
+ }
207
+ format(value) {
208
+ if (isNullOrUndefined(value)) {
209
+ return '';
210
+ }
211
+ return this.template.replace(/\{(\w+)\}/g, (match, key) => {
212
+ return value[key] ?? match;
213
+ });
214
+ }
215
+ }
216
+ /**
217
+ * Function formatter - formats values using a custom function
218
+ */
219
+ export class FunctionFormatter {
220
+ constructor(formatFn) {
221
+ this.formatFn = formatFn;
222
+ }
223
+ format(value) {
224
+ return this.formatFn(value);
225
+ }
226
+ }
227
+ /**
228
+ * Default formatter - returns string representation
229
+ */
230
+ export class DefaultFormatter {
231
+ format(value) {
232
+ if (isNullOrUndefined(value)) {
233
+ return '';
234
+ }
235
+ return String(value);
236
+ }
237
+ }
238
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdC1mb3JtYXR0ZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc21hcnQtdGFibGUvc3JjL2xpYi9zdHJhdGVnaWVzL2RlZmF1bHQtZm9ybWF0dGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUdILE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV0RTs7R0FFRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBQzFCLFlBQ21CLE9BTWhCO1FBTmdCLFlBQU8sR0FBUCxPQUFPLENBTXZCO0lBQ0EsQ0FBQztJQUVKLE1BQU0sQ0FBQyxLQUFhO1FBQ2xCLElBQUksaUJBQWlCLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDNUIsT0FBTyxFQUFFLENBQUM7U0FDWDtRQUVELElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUUzQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFO1lBQ3RCLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDeEI7UUFFRCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFO1lBQzdCLE1BQU0sR0FBRyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7U0FDL0I7UUFFRCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFO1lBQzdCLE1BQU0sR0FBRyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7U0FDL0I7UUFFRCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsU0FBUyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDckUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLElBQUksS0FBSyxDQUFDO1lBQ2hELE1BQU0sR0FBRyxNQUFNLENBQUMsU0FBUyxD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TSxPQUFPLGlCQUFpQjtJQUM1QixZQUE2QixRQUE4QjtRQUE5QixhQUFRLEdBQVIsUUFBUSxDQUFzQjtJQUFHLENBQUM7SUFFL0QsTUFBTSxDQUFDLEtBQVE7UUFDYixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDOUIsQ0FBQztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZ0JBQWdCO0lBQzNCLE1BQU0sQ0FBQyxLQUFVO1FBQ2YsSUFBSSxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUM1QixPQUFPLEVBQUUsQ0FBQztTQUNYO1FBQ0QsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEZWZhdWx0IGZvcm1hdHRlciBpbXBsZW1lbnRhdGlvbnNcbiAqL1xuXG5pbXBvcnQgeyBDZWxsRm9ybWF0dGVyIH0gZnJvbSAnLi4vbW9kZWxzL2NlbGwtc3RyYXRlZ2llcy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgaXNOdWxsT3JVbmRlZmluZWQsIGlzVmFsaWREYXRlIH0gZnJvbSAnLi4vbW9kZWxzL2NlbGwtdHlwZXMnO1xuXG4vKipcbiAqIFN0cmluZyBmb3JtYXR0ZXIgLSBkZWZhdWx0IHN0cmluZyBkaXNwbGF5XG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJpbmdGb3JtYXR0ZXIgaW1wbGVtZW50cyBDZWxsRm9ybWF0dGVyPHN0cmluZz4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM/OiB7XG4gICAgICBtYXhMZW5ndGg/OiBudW1iZXI7XG4gICAgICBlbGxpcHNpcz86IHN0cmluZztcbiAgICAgIHRyaW0/OiBib29sZWFuO1xuICAgICAgdG9VcHBlckNhc2U/OiBib29sZWFuO1xuICAgICAgdG9Mb3dlckNhc2U/OiBib29sZWFuO1xuICAgIH1cbiAgKSB7fVxuXG4gIGZvcm1hdCh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoaXNOdWxsT3JVbmRlZmluZWQodmFsdWUpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgbGV0IHJlc3VsdCA9IFN0cmluZyh2YWx1ZSk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zPy50cmltKSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQudHJpbSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnM/LnRvVXBwZXJDYXNlKSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQudG9VcHBlckNhc2UoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zPy50b0xvd2VyQ2FzZSkge1xuICAgICAgcmVzdWx0ID0gcmVzdWx0LnRvTG93ZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucz8ubWF4TGVuZ3RoICYmIHJlc3VsdC5sZW5ndGggPiB0aGlzLm9wdGlvbnMubWF4TGVuZ3RoKSB7XG4gICAgICBjb25zdCBlbGxpcHNpcyA9IHRoaXMub3B0aW9ucy5lbGxpcHNpcyA/PyAnLi4uJztcbiAgICAgIHJlc3VsdCA9IHJlc3VsdC5zdWJzdHJpbmcoMCwgdGhpcy5vcHRpb25zLm1heExlbmd0aCAtIGVsbGlwc2lzLmxlbmd0aCkgKyBlbGxpcHNpcztcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG5cbi8qKlxuICogTnVtYmVyIGZvcm1hdHRlciAtIGZvcm1hdHMgbnVtYmVycyB3aXRoIGRlY2ltYWxzXG4gKi9cbmV4cG9ydCBjbGFzcyBOdW1iZXJGb3JtYXR0ZXIgaW1wbGVtZW50cyBDZWxsRm9ybWF0dGVyPG51bWJlcj4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM/OiB7XG4gICAgICBkZWNpbWFscz86IG51bWJlcjtcbiAgICAgIHRob3VzYW5kc1NlcGFyYXRvcj86IHN0cmluZztcbiAgICAgIGRlY2ltYWxTZXBhcmF0b3I/OiBzdHJpbmc7XG4gICAgICBwcmVmaXg/OiBzdHJpbmc7XG4gICAgICBzdWZmaXg/OiBzdHJpbmc7XG4gICAgfVxuICApIHt9XG5cbiAgZm9ybWF0KHZhbHVlOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGlmIChpc051bGxPclVuZGVmaW5lZCh2YWx1ZSkgfHwgaXNOYU4odmFsdWUpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgY29uc3QgZGVjaW1hbHMgPSB0aGlzLm9wdGlvbnM/LmRlY2ltYWxzID8/IDI7XG4gICAgY29uc3QgZml4ZWQgPSB2YWx1ZS50b0ZpeGVkKGRlY2ltYWxzKTtcbiAgICBcbiAgICBjb25zdCBbaW50ZWdlclBhcnQsIGRlY2ltYWxQYXJ0XSA9IGZpeGVkLnNwbGl0KCcuJyk7XG4gICAgXG4gICAgLy8gQWRkIHRob3VzYW5kcyBzZXBhcmF0b3JcbiAgICBjb25zdCB0aG91c2FuZHNTZXBhcmF0b3IgPSB0aGlzLm9wdGlvbnM/LnRob3VzYW5kc1NlcGFyYXRvciA/PyAnLCc7XG4gICAgY29uc3QgZm9ybWF0dGVkSW50ZWdlciA9IGludGVnZXJQYXJ0LnJlcGxhY2UoL1xcQig/PShcXGR7M30pKyg/IVxcZCkpL2csIHRob3VzYW5kc1NlcGFyYXRvcik7XG4gICAgXG4gICAgLy8gQ29tYmluZSBpbnRlZ2VyIGFuZCBkZWNpbWFsIHBhcnRzXG4gICAgY29uc3QgZGVjaW1hbFNlcGFyYXRvciA9IHRoaXMub3B0aW9ucz8uZGVjaW1hbFNlcGFyYXRvciA/PyAnLic7XG4gICAgY29uc3QgcmVzdWx0ID0gZGVjaW1hbFBhcnQgPyBgJHtmb3JtYXR0ZWRJbnRlZ2VyfSR7ZGVjaW1hbFNlcGFyYXRvcn0ke2RlY2ltYWxQYXJ0fWAgOiBmb3JtYXR0ZWRJbnRlZ2VyO1xuICAgIFxuICAgIC8vIEFkZCBwcmVmaXggYW5kIHN1ZmZpeFxuICAgIGNvbnN0IHByZWZpeCA9IHRoaXMub3B0aW9ucz8ucHJlZml4ID8/ICcnO1xuICAgIGNvbnN0IHN1ZmZpeCA9IHRoaXMub3B0aW9ucz8uc3VmZml4ID8/ICcnO1xuICAgIFxuICAgIHJldHVybiBgJHtwcmVmaXh9JHtyZXN1bHR9JHtzdWZmaXh9YDtcbiAgfVxufVxuXG4vKipcbiAqIEN1cnJlbmN5IGZvcm1hdHRlciAtIGZvcm1hdHMgY3VycmVuY3kgdmFsdWVzXG4gKi9cbmV4cG9ydCBjbGFzcyBDdXJyZW5jeUZvcm1hdHRlciBpbXBsZW1lbnRzIENlbGxGb3JtYXR0ZXI8bnVtYmVyPiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9ucz86IHtcbiAgICAgIGN1cnJlbmN5Pzogc3RyaW5nO1xuICAgICAgbG9jYWxlPzogc3RyaW5nO1xuICAgICAgZGVjaW1hbHM/OiBudW1iZXI7XG4gICAgfVxuICApIHt9XG5cbiAgZm9ybWF0KHZhbHVlOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGlmIChpc051bGxPclVuZGVmaW5lZCh2YWx1ZSkgfHwgaXNOYU4odmFsdWUpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgY29uc3QgbG9jYWxlID0gdGhpcy5vcHRpb25zPy5sb2NhbGUgPz8gJ2VuLVVTJztcbiAgICBjb25zdCBjdXJyZW5jeSA9IHRoaXMub3B0aW9ucz8uY3VycmVuY3kgPz8gJ1VTRCc7XG4gICAgY29uc3QgZGVjaW1hbHMgPSB0aGlzLm9wdGlvbnM/LmRlY2ltYWxzID8/IDI7XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG5ldyBJbnRsLk51bWJlckZvcm1hdChsb2NhbGUsIHtcbiAgICAgICAgc3R5bGU6ICdjdXJyZW5jeScsXG4gICAgICAgIGN1cnJlbmN5LFxuICAgICAgICBtaW5pbXVtRnJhY3Rpb25EaWdpdHM6IGRlY2ltYWxzLFxuICAgICAgICBtYXhpbXVtRnJhY3Rpb25EaWdpdHM6IGRlY2ltYWxzXG4gICAgICB9KS5mb3JtYXQodmFsdWUpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBGYWxsYmFjayBpZiBJbnRsIGlzIG5vdCBzdXBwb3J0ZWRcbiAgICAgIHJldHVybiBgJCR7dmFsdWUudG9GaXhlZChkZWNpbWFscyl9YDtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBQZXJjZW50YWdlIGZvcm1hdHRlclxuICovXG5leHBvcnQgY2xhc3MgUGVyY2VudGFnZUZvcm1hdHRlciBpbXBsZW1lbnRzIENlbGxGb3JtYXR0ZXI8bnVtYmVyPiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9ucz86IHtcbiAgICAgIGRlY2ltYWxzPzogbnVtYmVyO1xuICAgICAgbXVsdGlwbGllcj86IG51bWJlcjsgLy8gZS5nLiwgMTAwIGlmIHZhbHVlIGlzIDAuMjUgYW5kIHNob3VsZCBkaXNwbGF5IGFzIDI1JVxuICAgIH1cbiAgKSB7fVxuXG4gIGZvcm1hdCh2YWx1ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBpZiAoaXNOdWxsT3JVbmRlZmluZWQodmFsdWUpIHx8IGlzTmFOKHZhbHVlKSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIGNvbnN0IGRlY2ltYWxzID0gdGhpcy5vcHRpb25zPy5kZWNpbWFscyA/PyAyO1xuICAgIGNvbnN0IG11bHRpcGxpZXIgPSB0aGlzLm9wdGlvbnM/Lm11bHRpcGxpZXIgPz8gMTtcbiAgICBjb25zdCBwZXJjZW50YWdlID0gdmFsdWUgKiBtdWx0aXBsaWVyO1xuXG4gICAgcmV0dXJuIGAke3BlcmNlbnRhZ2UudG9GaXhlZChkZWNpbWFscyl9JWA7XG4gIH1cbn1cblxuLyoqXG4gKiBEYXRlIGZvcm1hdHRlciAtIGxvY2FsZS1hd2FyZSBkYXRlIGZvcm1hdHRpbmdcbiAqL1xuZXhwb3J0IGNsYXNzIERhdGVGb3JtYXR0ZXIgaW1wbGVtZW50cyBDZWxsRm9ybWF0dGVyPERhdGU+IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zPzoge1xuICAgICAgbG9jYWxlPzogc3RyaW5nO1xuICAgICAgZGF0ZVN0eWxlPzogJ2Z1bGwnIHwgJ2xvbmcnIHwgJ21lZGl1bScgfCAnc2hvcnQnO1xuICAgICAgdGltZVN0eWxlPzogJ2Z1bGwnIHwgJ2xvbmcnIHwgJ21lZGl1bScgfCAnc2hvcnQnO1xuICAgICAgZm9ybWF0Pzogc3RyaW5nOyAvLyBDdXN0b20gZm9ybWF0IHN0cmluZ1xuICAgIH1cbiAgKSB7fVxuXG4gIGZvcm1hdCh2YWx1ZTogRGF0ZSk6IHN0cmluZyB7XG4gICAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8vIENvbnZlcnQgdG8gRGF0ZSBpZiBpdCdzIGEgc3RyaW5nIG9yIG51bWJlclxuICAgIGxldCBkYXRlOiBEYXRlO1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIGRhdGUgPSB2YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0ZSA9IG5ldyBEYXRlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAoIWlzVmFsaWREYXRlKGRhdGUpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgY29uc3QgbG9jYWxlID0gdGhpcy5vcHRpb25zPy5sb2NhbGUgPz8gJ2VuLVVTJztcblxuICAgIHRyeSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zPy5mb3JtYXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0Q3VzdG9tKGRhdGUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IEludGwuRGF0ZVRpbWVGb3JtYXQobG9jYWxlLCB7XG4gICAgICAgIGRhdGVTdHlsZTogdGhpcy5vcHRpb25zPy5kYXRlU3R5bGUgPz8gJ21lZGl1bScsXG4gICAgICAgIHRpbWVTdHlsZTogdGhpcy5vcHRpb25zPy50aW1lU3R5bGVcbiAgICAgIH0pLmZvcm1hdChkYXRlKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIGRhdGUudG9Mb2NhbGVEYXRlU3RyaW5nKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRDdXN0b20oZGF0ZTogRGF0ZSk6IHN0cmluZyB7XG4gICAgLy8gU2ltcGxlIGN1c3RvbSBmb3JtYXR0aW5nIChjYW4gYmUgZXh0ZW5kZWQpXG4gICAgY29uc3QgZm9ybWF0ID0gdGhpcy5vcHRpb25zPy5mb3JtYXQgPz8gJ1lZWVktTU0tREQnO1xuICAgIFxuICAgIGNvbnN0IHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG4gICAgY29uc3QgbW9udGggPSBTdHJpbmcoZGF0ZS5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBjb25zdCBkYXkgPSBTdHJpbmcoZGF0ZS5nZXREYXRlKCkpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgY29uc3QgaG91cnMgPSBTdHJpbmcoZGF0ZS5nZXRIb3VycygpKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIGNvbnN0IG1pbnV0ZXMgPSBTdHJpbmcoZGF0ZS5nZXRNaW51dGVzKCkpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgY29uc3Qgc2Vjb25kcyA9IFN0cmluZyhkYXRlLmdldFNlY29uZHMoKSkucGFkU3RhcnQoMiwgJzAnKTtcblxuICAgIHJldHVybiBmb3JtYXRcbiAgICAgIC5yZXBsYWNlKCdZWVlZJywgU3RyaW5nKHllYXIpKVxuICAgICAgLnJlcGxhY2UoJ01NJywgbW9udGgpXG4gICAgICAucmVwbGFjZSgnREQnLCBkYXkpXG4gICAgICAucmVwbGFjZSgnSEgnLCBob3VycylcbiAgICAgIC5yZXBsYWNlKCdtbScsIG1pbnV0ZXMpXG4gICAgICAucmVwbGFjZSgnc3MnLCBzZWNvbmRzKTtcbiAgfVxufVxuXG4vKipcbiAqIEJvb2xlYW4gZm9ybWF0dGVyIC0gZm9ybWF0cyBib29sZWFuIHZhbHVlc1xuICovXG5leHBvcnQgY2xhc3MgQm9vbGVhbkZvcm1hdHRlciBpbXBsZW1lbnRzIENlbGxGb3JtYXR0ZXI8Ym9vbGVhbj4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM/OiB7XG4gICAgICB0cnVlVmFsdWU/OiBzdHJpbmc7XG4gICAgICBmYWxzZVZhbHVlPzogc3RyaW5nO1xuICAgICAgbnVsbFZhbHVlPzogc3RyaW5nO1xuICAgIH1cbiAgKSB7fVxuXG4gIGZvcm1hdCh2YWx1ZTogYm9vbGVhbik6IHN0cmluZyB7XG4gICAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucz8ubnVsbFZhbHVlID8/ICcnO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZSBcbiAgICAgID8gKHRoaXMub3B0aW9ucz8udHJ1ZVZhbHVlID8/ICdZZXMnKVxuICAgICAgOiAodGhpcy5vcHRpb25zPy5mYWxzZVZhbHVlID8/ICdObycpO1xuICB9XG59XG5cbi8qKlxuICogQXJyYXkgZm9ybWF0dGVyIC0gZm9ybWF0cyBhcnJheSB2YWx1ZXNcbiAqL1xuZXhwb3J0IGNsYXNzIEFycmF5Rm9ybWF0dGVyPFQgPSBhbnk+IGltcGxlbWVudHMgQ2VsbEZvcm1hdHRlcjxUW10+IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zPzoge1xuICAgICAgc2VwYXJhdG9yPzogc3RyaW5nO1xuICAgICAgbWF4SXRlbXM/OiBudW1iZXI7XG4gICAgICBlbGxpcHNpcz86IHN0cmluZztcbiAgICAgIGl0ZW1Gb3JtYXR0ZXI/OiAoaXRlbTogVCkgPT4gc3RyaW5nO1xuICAgIH1cbiAgKSB7fVxuXG4gIGZvcm1hdCh2YWx1ZTogVFtdKTogc3RyaW5nIHtcbiAgICBpZiAoaXNOdWxsT3JVbmRlZmluZWQodmFsdWUpIHx8ICFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICBjb25zdCBzZXBhcmF0b3IgPSB0aGlzLm9wdGlvbnM/LnNlcGFyYXRvciA/PyAnLCAnO1xuICAgIGNvbnN0IG1heEl0ZW1zID0gdGhpcy5vcHRpb25zPy5tYXhJdGVtcztcbiAgICBjb25zdCBpdGVtRm9ybWF0dGVyID0gdGhpcy5vcHRpb25zPy5pdGVtRm9ybWF0dGVyID8/ICgoaXRlbTogVCkgPT4gU3RyaW5nKGl0ZW0pKTtcblxuICAgIGxldCBpdGVtcyA9IHZhbHVlLm1hcChpdGVtRm9ybWF0dGVyKTtcblxuICAgIGlmIChtYXhJdGVtcyAmJiBpdGVtcy5sZW5ndGggPiBtYXhJdGVtcykge1xuICAgICAgY29uc3QgZWxsaXBzaXMgPSB0aGlzLm9wdGlvbnM/LmVsbGlwc2lzID8/ICcuLi4nO1xuICAgICAgaXRlbXMgPSBpdGVtcy5zbGljZSgwLCBtYXhJdGVtcyk7XG4gICAgICBpdGVtcy5wdXNoKGVsbGlwc2lzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaXRlbXMuam9pbihzZXBhcmF0b3IpO1xuICB9XG59XG5cbi8qKlxuICogVGVtcGxhdGUgZm9ybWF0dGVyIC0gZm9ybWF0cyB2YWx1ZXMgdXNpbmcgYSB0ZW1wbGF0ZSBzdHJpbmdcbiAqL1xuZXhwb3J0IGNsYXNzIFRlbXBsYXRlRm9ybWF0dGVyIGltcGxlbWVudHMgQ2VsbEZvcm1hdHRlcjxhbnk+IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSB0ZW1wbGF0ZTogc3RyaW5nKSB7fVxuXG4gIGZvcm1hdCh2YWx1ZTogYW55KTogc3RyaW5nIHtcbiAgICBpZiAoaXNOdWxsT3JVbmRlZmluZWQodmFsdWUpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMudGVtcGxhdGUucmVwbGFjZSgvXFx7KFxcdyspXFx9L2csIChtYXRjaCwga2V5KSA9PiB7XG4gICAgICByZXR1cm4gdmFsdWVba2V5XSA/PyBtYXRjaDtcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uIGZvcm1hdHRlciAtIGZvcm1hdHMgdmFsdWVzIHVzaW5nIGEgY3VzdG9tIGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBGdW5jdGlvbkZvcm1hdHRlcjxUID0gYW55PiBpbXBsZW1lbnRzIENlbGxGb3JtYXR0ZXI8VD4ge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGZvcm1hdEZuOiAodmFsdWU6IFQpID0+IHN0cmluZykge31cblxuICBmb3JtYXQodmFsdWU6IFQpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmZvcm1hdEZuKHZhbHVlKTtcbiAgfVxufVxuXG4vKipcbiAqIERlZmF1bHQgZm9ybWF0dGVyIC0gcmV0dXJucyBzdHJpbmcgcmVwcmVzZW50YXRpb25cbiAqL1xuZXhwb3J0IGNsYXNzIERlZmF1bHRGb3JtYXR0ZXIgaW1wbGVtZW50cyBDZWxsRm9ybWF0dGVyPGFueT4ge1xuICBmb3JtYXQodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgfVxufVxuXG4iXX0=
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Default validator implementations
3
+ */
4
+ import { isNullOrUndefined } from '../models/cell-types';
5
+ /**
6
+ * Required validator - ensures value is not empty
7
+ */
8
+ export class RequiredValidator {
9
+ constructor(customMessage) {
10
+ this.customMessage = customMessage;
11
+ this.errorMessage = 'This field is required';
12
+ if (customMessage) {
13
+ this.errorMessage = customMessage;
14
+ }
15
+ }
16
+ validate(value) {
17
+ const isEmpty = isNullOrUndefined(value) ||
18
+ (typeof value === 'string' && value.trim() === '') ||
19
+ (Array.isArray(value) && value.length === 0);
20
+ return {
21
+ valid: !isEmpty,
22
+ error: isEmpty ? this.errorMessage : undefined
23
+ };
24
+ }
25
+ }
26
+ /**
27
+ * Range validator - validates numeric range
28
+ */
29
+ export class RangeValidator {
30
+ constructor(min, max, customMessage) {
31
+ this.min = min;
32
+ this.max = max;
33
+ this.errorMessage = customMessage ?? this.buildErrorMessage();
34
+ }
35
+ validate(value) {
36
+ if (isNullOrUndefined(value)) {
37
+ return { valid: true }; // Use RequiredValidator for required checks
38
+ }
39
+ if (typeof value !== 'number' || isNaN(value)) {
40
+ return {
41
+ valid: false,
42
+ error: 'Value must be a number'
43
+ };
44
+ }
45
+ if (this.min !== undefined && value < this.min) {
46
+ return {
47
+ valid: false,
48
+ error: `Value must be at least ${this.min}`
49
+ };
50
+ }
51
+ if (this.max !== undefined && value > this.max) {
52
+ return {
53
+ valid: false,
54
+ error: `Value must be at most ${this.max}`
55
+ };
56
+ }
57
+ return { valid: true };
58
+ }
59
+ buildErrorMessage() {
60
+ if (this.min !== undefined && this.max !== undefined) {
61
+ return `Value must be between ${this.min} and ${this.max}`;
62
+ }
63
+ else if (this.min !== undefined) {
64
+ return `Value must be at least ${this.min}`;
65
+ }
66
+ else if (this.max !== undefined) {
67
+ return `Value must be at most ${this.max}`;
68
+ }
69
+ return 'Invalid value';
70
+ }
71
+ }
72
+ /**
73
+ * String length validator
74
+ */
75
+ export class LengthValidator {
76
+ constructor(minLength, maxLength, customMessage) {
77
+ this.minLength = minLength;
78
+ this.maxLength = maxLength;
79
+ this.errorMessage = customMessage ?? this.buildErrorMessage();
80
+ }
81
+ validate(value) {
82
+ if (isNullOrUndefined(value)) {
83
+ return { valid: true };
84
+ }
85
+ const length = String(value).length;
86
+ if (this.minLength !== undefined && length < this.minLength) {
87
+ return {
88
+ valid: false,
89
+ error: `Minimum length is ${this.minLength} characters`
90
+ };
91
+ }
92
+ if (this.maxLength !== undefined && length > this.maxLength) {
93
+ return {
94
+ valid: false,
95
+ error: `Maximum length is ${this.maxLength} characters`
96
+ };
97
+ }
98
+ return { valid: true };
99
+ }
100
+ buildErrorMessage() {
101
+ if (this.minLength !== undefined && this.maxLength !== undefined) {
102
+ return `Length must be between ${this.minLength} and ${this.maxLength} characters`;
103
+ }
104
+ else if (this.minLength !== undefined) {
105
+ return `Minimum length is ${this.minLength} characters`;
106
+ }
107
+ else if (this.maxLength !== undefined) {
108
+ return `Maximum length is ${this.maxLength} characters`;
109
+ }
110
+ return 'Invalid length';
111
+ }
112
+ }
113
+ /**
114
+ * Regex validator - validates against regular expression
115
+ */
116
+ export class RegexValidator {
117
+ constructor(pattern, customMessage) {
118
+ this.pattern = pattern;
119
+ this.errorMessage = 'Invalid format';
120
+ if (customMessage) {
121
+ this.errorMessage = customMessage;
122
+ }
123
+ }
124
+ validate(value) {
125
+ if (isNullOrUndefined(value)) {
126
+ return { valid: true };
127
+ }
128
+ const regex = typeof this.pattern === 'string'
129
+ ? new RegExp(this.pattern)
130
+ : this.pattern;
131
+ const isValid = regex.test(String(value));
132
+ return {
133
+ valid: isValid,
134
+ error: isValid ? undefined : this.errorMessage
135
+ };
136
+ }
137
+ }
138
+ /**
139
+ * Email validator
140
+ */
141
+ export class EmailValidator {
142
+ constructor(customMessage) {
143
+ this.errorMessage = 'Invalid email address';
144
+ this.emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
145
+ if (customMessage) {
146
+ this.errorMessage = customMessage;
147
+ }
148
+ }
149
+ validate(value) {
150
+ if (isNullOrUndefined(value)) {
151
+ return { valid: true };
152
+ }
153
+ const isValid = this.emailPattern.test(String(value));
154
+ return {
155
+ valid: isValid,
156
+ error: isValid ? undefined : this.errorMessage
157
+ };
158
+ }
159
+ }
160
+ /**
161
+ * URL validator
162
+ */
163
+ export class UrlValidator {
164
+ constructor(customMessage) {
165
+ this.errorMessage = 'Invalid URL';
166
+ if (customMessage) {
167
+ this.errorMessage = customMessage;
168
+ }
169
+ }
170
+ validate(value) {
171
+ if (isNullOrUndefined(value)) {
172
+ return { valid: true };
173
+ }
174
+ try {
175
+ new URL(String(value));
176
+ return { valid: true };
177
+ }
178
+ catch {
179
+ return {
180
+ valid: false,
181
+ error: this.errorMessage
182
+ };
183
+ }
184
+ }
185
+ }
186
+ /**
187
+ * Date range validator
188
+ */
189
+ export class DateRangeValidator {
190
+ constructor(minDate, maxDate, customMessage) {
191
+ this.minDate = minDate;
192
+ this.maxDate = maxDate;
193
+ this.errorMessage = customMessage ?? this.buildErrorMessage();
194
+ }
195
+ validate(value) {
196
+ if (isNullOrUndefined(value)) {
197
+ return { valid: true };
198
+ }
199
+ const date = value instanceof Date ? value : new Date(value);
200
+ if (isNaN(date.getTime())) {
201
+ return {
202
+ valid: false,
203
+ error: 'Invalid date'
204
+ };
205
+ }
206
+ if (this.minDate && date < this.minDate) {
207
+ return {
208
+ valid: false,
209
+ error: `Date must be on or after ${this.minDate.toLocaleDateString()}`
210
+ };
211
+ }
212
+ if (this.maxDate && date > this.maxDate) {
213
+ return {
214
+ valid: false,
215
+ error: `Date must be on or before ${this.maxDate.toLocaleDateString()}`
216
+ };
217
+ }
218
+ return { valid: true };
219
+ }
220
+ buildErrorMessage() {
221
+ if (this.minDate && this.maxDate) {
222
+ return `Date must be between ${this.minDate.toLocaleDateString()} and ${this.maxDate.toLocaleDateString()}`;
223
+ }
224
+ else if (this.minDate) {
225
+ return `Date must be on or after ${this.minDate.toLocaleDateString()}`;
226
+ }
227
+ else if (this.maxDate) {
228
+ return `Date must be on or before ${this.maxDate.toLocaleDateString()}`;
229
+ }
230
+ return 'Invalid date';
231
+ }
232
+ }
233
+ /**
234
+ * Custom function validator
235
+ */
236
+ export class FunctionValidator {
237
+ constructor(validateFn, customMessage) {
238
+ this.validateFn = validateFn;
239
+ this.errorMessage = 'Validation failed';
240
+ if (customMessage) {
241
+ this.errorMessage = customMessage;
242
+ }
243
+ }
244
+ validate(value) {
245
+ const result = this.validateFn(value);
246
+ if (typeof result === 'boolean') {
247
+ return {
248
+ valid: result,
249
+ error: result ? undefined : this.errorMessage
250
+ };
251
+ }
252
+ return result;
253
+ }
254
+ }
255
+ /**
256
+ * Composite validator - chains multiple validators (Chain of Responsibility)
257
+ */
258
+ export class ChainValidator {
259
+ constructor(validators) {
260
+ this.errorMessage = 'Validation failed';
261
+ this.validators = [];
262
+ if (validators) {
263
+ this.validators = validators;
264
+ }
265
+ }
266
+ addValidator(validator) {
267
+ this.validators.push(validator);
268
+ return this;
269
+ }
270
+ getValidators() {
271
+ return [...this.validators];
272
+ }
273
+ validate(value) {
274
+ const errors = {};
275
+ let allValid = true;
276
+ for (let i = 0; i < this.validators.length; i++) {
277
+ const validator = this.validators[i];
278
+ const result = validator.validate(value);
279
+ if (!result.valid) {
280
+ allValid = false;
281
+ errors[`validator_${i}`] = result.error || 'Validation failed';
282
+ }
283
+ }
284
+ if (!allValid) {
285
+ const firstError = Object.values(errors)[0];
286
+ return {
287
+ valid: false,
288
+ error: firstError,
289
+ errors
290
+ };
291
+ }
292
+ return { valid: true };
293
+ }
294
+ }
295
+ /**
296
+ * Pattern validators for common use cases
297
+ */
298
+ export class PatternValidators {
299
+ static email(message) {
300
+ return new EmailValidator(message);
301
+ }
302
+ static url(message) {
303
+ return new UrlValidator(message);
304
+ }
305
+ static required(message) {
306
+ return new RequiredValidator(message);
307
+ }
308
+ static range(min, max, message) {
309
+ return new RangeValidator(min, max, message);
310
+ }
311
+ static stringLength(min, max, message) {
312
+ return new LengthValidator(min, max, message);
313
+ }
314
+ static regex(pattern, message) {
315
+ return new RegexValidator(pattern, message);
316
+ }
317
+ static dateRange(min, max, message) {
318
+ return new DateRangeValidator(min, max, message);
319
+ }
320
+ static custom(fn, message) {
321
+ return new FunctionValidator(fn, message);
322
+ }
323
+ static chain(...validators) {
324
+ return new ChainValidator(validators);
325
+ }
326
+ }
327
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdC12YWxpZGF0b3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc21hcnQtdGFibGUvc3JjL2xpYi9zdHJhdGVnaWVzL2RlZmF1bHQtdmFsaWRhdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUdILE9BQU8sRUFBb0IsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUUzRTs7R0FFRztBQUNILE1BQU0sT0FBTyxpQkFBaUI7SUFHNUIsWUFBNkIsYUFBc0I7UUFBdEIsa0JBQWEsR0FBYixhQUFhLENBQVM7UUFGbkQsaUJBQVksR0FBRyx3QkFBd0IsQ0FBQztRQUd0QyxJQUFJLGFBQWEsRUFBRTtZQUNqQixJQUFJLENBQUMsWUFBWSxHQUFHLGFBQWEsQ0FBQztTQUNuQztJQUNILENBQUM7SUFFRCxRQUFRLENBQUMsS0FBVTtRQUNqQixNQUFNLE9BQU8sR0FBRyxpQkFBaUIsQ0FBQyxLQUFLLENBQUM7WUFDekIsQ0FBQyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQztZQUNsRCxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQztRQUU1RCxPQUFPO1lBQ0wsS0FBSyxFQUFFLENBQUMsT0FBTztZQUNmLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLFNBQVM7U0FDL0MsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGNBQWM7SUFHekIsWUFDbUIsR0FBWSxFQUNaLEdBQVksRUFDN0IsYUFBc0I7UUFGTCxRQUFHLEdBQUgsR0FBRyxDQUFTO1FBQ1osUUFBRyxHQUFILEdBQUcsQ0FBUztRQUc3QixJQUFJLENBQUMsWUFBWSxH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QUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVELE1BQU0sQ0FBQyxNQUFNLENBQUksRUFBNEMsRUFBRSxPQUFnQjtRQUM3RSxPQUFPLElBQUksaUJBQWlCLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxNQUFNLENBQUMsS0FBSyxDQUFJLEdBQUcsVUFBOEI7UUFDL0MsT0FBTyxJQUFJLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN4QyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIERlZmF1bHQgdmFsaWRhdG9yIGltcGxlbWVudGF0aW9uc1xuICovXG5cbmltcG9ydCB7IENlbGxWYWxpZGF0b3IsIENvbXBvc2l0ZVZhbGlkYXRvciB9IGZyb20gJy4uL21vZGVscy9jZWxsLXN0cmF0ZWdpZXMuaW50ZXJmYWNlJztcbmltcG9ydCB7IFZhbGlkYXRpb25SZXN1bHQsIGlzTnVsbE9yVW5kZWZpbmVkIH0gZnJvbSAnLi4vbW9kZWxzL2NlbGwtdHlwZXMnO1xuXG4vKipcbiAqIFJlcXVpcmVkIHZhbGlkYXRvciAtIGVuc3VyZXMgdmFsdWUgaXMgbm90IGVtcHR5XG4gKi9cbmV4cG9ydCBjbGFzcyBSZXF1aXJlZFZhbGlkYXRvciBpbXBsZW1lbnRzIENlbGxWYWxpZGF0b3I8YW55PiB7XG4gIGVycm9yTWVzc2FnZSA9ICdUaGlzIGZpZWxkIGlzIHJlcXVpcmVkJztcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGN1c3RvbU1lc3NhZ2U/OiBzdHJpbmcpIHtcbiAgICBpZiAoY3VzdG9tTWVzc2FnZSkge1xuICAgICAgdGhpcy5lcnJvck1lc3NhZ2UgPSBjdXN0b21NZXNzYWdlO1xuICAgIH1cbiAgfVxuXG4gIHZhbGlkYXRlKHZhbHVlOiBhbnkpOiBWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBjb25zdCBpc0VtcHR5ID0gaXNOdWxsT3JVbmRlZmluZWQodmFsdWUpIHx8IFxuICAgICAgICAgICAgICAgICAgICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlLnRyaW0oKSA9PT0gJycpIHx8XG4gICAgICAgICAgICAgICAgICAgKEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA9PT0gMCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6ICFpc0VtcHR5LFxuICAgICAgZXJyb3I6IGlzRW1wdHkgPyB0aGlzLmVycm9yTWVzc2FnZSA6IHVuZGVmaW5lZFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBSYW5nZSB2YWxpZGF0b3IgLSB2YWxpZGF0ZXMgbnVtZXJpYyByYW5nZVxuICovXG5leHBvcnQgY2xhc3MgUmFuZ2VWYWxpZGF0b3IgaW1wbGVtZW50cyBDZWxsVmFsaWRhdG9yPG51bWJlcj4ge1xuICBlcnJvck1lc3NhZ2U6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1pbj86IG51bWJlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1heD86IG51bWJlcixcbiAgICBjdXN0b21NZXNzYWdlPzogc3RyaW5nXG4gICkge1xuICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gY3VzdG9tTWVzc2FnZSA/PyB0aGlzLmJ1aWxkRXJyb3JNZXNzYWdlKCk7XG4gIH1cblxuICB2YWxpZGF0ZSh2YWx1ZTogbnVtYmVyKTogVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHsgdmFsaWQ6IHRydWUgfTsgLy8gVXNlIFJlcXVpcmVkVmFsaWRhdG9yIGZvciByZXF1aXJlZCBjaGVja3NcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCBpc05hTih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgICAgZXJyb3I6ICdWYWx1ZSBtdXN0IGJlIGEgbnVtYmVyJ1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5taW4gIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSA8IHRoaXMubWluKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogZmFsc2UsXG4gICAgICAgIGVycm9yOiBgVmFsdWUgbXVzdCBiZSBhdCBsZWFzdCAke3RoaXMubWlufWBcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWF4ICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgPiB0aGlzLm1heCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICBlcnJvcjogYFZhbHVlIG11c3QgYmUgYXQgbW9zdCAke3RoaXMubWF4fWBcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdmFsaWQ6IHRydWUgfTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRFcnJvck1lc3NhZ2UoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5taW4gIT09IHVuZGVmaW5lZCAmJiB0aGlzLm1heCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gYFZhbHVlIG11c3QgYmUgYmV0d2VlbiAke3RoaXMubWlufSBhbmQgJHt0aGlzLm1heH1gO1xuICAgIH0gZWxzZSBpZiAodGhpcy5taW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGBWYWx1ZSBtdXN0IGJlIGF0IGxlYXN0ICR7dGhpcy5taW59YDtcbiAgICB9IGVsc2UgaWYgKHRoaXMubWF4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBgVmFsdWUgbXVzdCBiZSBhdCBtb3N0ICR7dGhpcy5tYXh9YDtcbiAgICB9XG4gICAgcmV0dXJuICdJbnZhbGlkIHZhbHVlJztcbiAgfVxufVxuXG4vKipcbiAqIFN0cmluZyBsZW5ndGggdmFsaWRhdG9yXG4gKi9cbmV4cG9ydCBjbGFzcyBMZW5ndGhWYWxpZGF0b3IgaW1wbGVtZW50cyBDZWxsVmFsaWRhdG9yPHN0cmluZz4ge1xuICBlcnJvck1lc3NhZ2U6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1pbkxlbmd0aD86IG51bWJlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1heExlbmd0aD86IG51bWJlcixcbiAgICBjdXN0b21NZXNzYWdlPzogc3RyaW5nXG4gICkge1xuICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gY3VzdG9tTWVzc2FnZSA/PyB0aGlzLmJ1aWxkRXJyb3JNZXNzYWdlKCk7XG4gIH1cblxuICB2YWxpZGF0ZSh2YWx1ZTogc3RyaW5nKTogVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHsgdmFsaWQ6IHRydWUgfTtcbiAgICB9XG5cbiAgICBjb25zdCBsZW5ndGggPSBTdHJpbmcodmFsdWUpLmxlbmd0aDtcblxuICAgIGlmICh0aGlzLm1pbkxlbmd0aCAhPT0gdW5kZWZpbmVkICYmIGxlbmd0aCA8IHRoaXMubWluTGVuZ3RoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogZmFsc2UsXG4gICAgICAgIGVycm9yOiBgTWluaW11bSBsZW5ndGggaXMgJHt0aGlzLm1pbkxlbmd0aH0gY2hhcmFjdGVyc2BcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWF4TGVuZ3RoICE9PSB1bmRlZmluZWQgJiYgbGVuZ3RoID4gdGhpcy5tYXhMZW5ndGgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgICAgZXJyb3I6IGBNYXhpbXVtIGxlbmd0aCBpcyAke3RoaXMubWF4TGVuZ3RofSBjaGFyYWN0ZXJzYFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSB9O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEVycm9yTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLm1pbkxlbmd0aCAhPT0gdW5kZWZpbmVkICYmIHRoaXMubWF4TGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBgTGVuZ3RoIG11c3QgYmUgYmV0d2VlbiAke3RoaXMubWluTGVuZ3RofSBhbmQgJHt0aGlzLm1heExlbmd0aH0gY2hhcmFjdGVyc2A7XG4gICAgfSBlbHNlIGlmICh0aGlzLm1pbkxlbmd0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gYE1pbmltdW0gbGVuZ3RoIGlzICR7dGhpcy5taW5MZW5ndGh9IGNoYXJhY3RlcnNgO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tYXhMZW5ndGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGBNYXhpbXVtIGxlbmd0aCBpcyAke3RoaXMubWF4TGVuZ3RofSBjaGFyYWN0ZXJzYDtcbiAgICB9XG4gICAgcmV0dXJuICdJbnZhbGlkIGxlbmd0aCc7XG4gIH1cbn1cblxuLyoqXG4gKiBSZWdleCB2YWxpZGF0b3IgLSB2YWxpZGF0ZXMgYWdhaW5zdCByZWd1bGFyIGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGNsYXNzIFJlZ2V4VmFsaWRhdG9yIGltcGxlbWVudHMgQ2VsbFZhbGlkYXRvcjxzdHJpbmc+IHtcbiAgZXJyb3JNZXNzYWdlID0gJ0ludmFsaWQgZm9ybWF0JztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBhdHRlcm46IFJlZ0V4cCB8IHN0cmluZyxcbiAgICBjdXN0b21NZXNzYWdlPzogc3RyaW5nXG4gICkge1xuICAgIGlmIChjdXN0b21NZXNzYWdlKSB7XG4gICAgICB0aGlzLmVycm9yTWVzc2FnZSA9IGN1c3RvbU1lc3NhZ2U7XG4gICAgfVxuICB9XG5cbiAgdmFsaWRhdGUodmFsdWU6IHN0cmluZyk6IFZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmIChpc051bGxPclVuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB7IHZhbGlkOiB0cnVlIH07XG4gICAgfVxuXG4gICAgY29uc3QgcmVnZXggPSB0eXBlb2YgdGhpcy5wYXR0ZXJuID09PSAnc3RyaW5nJyBcbiAgICAgID8gbmV3IFJlZ0V4cCh0aGlzLnBhdHRlcm4pIFxuICAgICAgOiB0aGlzLnBhdHRlcm47XG5cbiAgICBjb25zdCBpc1ZhbGlkID0gcmVnZXgudGVzdChTdHJpbmcodmFsdWUpKTtcblxuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogaXNWYWxpZCxcbiAgICAgIGVycm9yOiBpc1ZhbGlkID8gdW5kZWZpbmVkIDogdGhpcy5lcnJvck1lc3NhZ2VcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogRW1haWwgdmFsaWRhdG9yXG4gKi9cbmV4cG9ydCBjbGFzcyBFbWFpbFZhbGlkYXRvciBpbXBsZW1lbnRzIENlbGxWYWxpZGF0b3I8c3RyaW5nPiB7XG4gIGVycm9yTWVzc2FnZSA9ICdJbnZhbGlkIGVtYWlsIGFkZHJlc3MnO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZW1haWxQYXR0ZXJuID0gL15bXlxcc0BdK0BbXlxcc0BdK1xcLlteXFxzQF0rJC87XG5cbiAgY29uc3RydWN0b3IoY3VzdG9tTWVzc2FnZT86IHN0cmluZykge1xuICAgIGlmIChjdXN0b21NZXNzYWdlKSB7XG4gICAgICB0aGlzLmVycm9yTWVzc2FnZSA9IGN1c3RvbU1lc3NhZ2U7XG4gICAgfVxuICB9XG5cbiAgdmFsaWRhdGUodmFsdWU6IHN0cmluZyk6IFZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmIChpc051bGxPclVuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB7IHZhbGlkOiB0cnVlIH07XG4gICAgfVxuXG4gICAgY29uc3QgaXNWYWxpZCA9IHRoaXMuZW1haWxQYXR0ZXJuLnRlc3QoU3RyaW5nKHZhbHVlKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGlzVmFsaWQsXG4gICAgICBlcnJvcjogaXNWYWxpZCA/IHVuZGVmaW5lZCA6IHRoaXMuZXJyb3JNZXNzYWdlXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIFVSTCB2YWxpZGF0b3JcbiAqL1xuZXhwb3J0IGNsYXNzIFVybFZhbGlkYXRvciBpbXBsZW1lbnRzIENlbGxWYWxpZGF0b3I8c3RyaW5nPiB7XG4gIGVycm9yTWVzc2FnZSA9ICdJbnZhbGlkIFVSTCc7XG5cbiAgY29uc3RydWN0b3IoY3VzdG9tTWVzc2FnZT86IHN0cmluZykge1xuICAgIGlmIChjdXN0b21NZXNzYWdlKSB7XG4gICAgICB0aGlzLmVycm9yTWVzc2FnZSA9IGN1c3RvbU1lc3NhZ2U7XG4gICAgfVxuICB9XG5cbiAgdmFsaWRhdGUodmFsdWU6IHN0cmluZyk6IFZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmIChpc051bGxPclVuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB7IHZhbGlkOiB0cnVlIH07XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIG5ldyBVUkwoU3RyaW5nKHZhbHVlKSk7XG4gICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSB9O1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICBlcnJvcjogdGhpcy5lcnJvck1lc3NhZ2VcbiAgICAgIH07XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGF0ZSByYW5nZSB2YWxpZGF0b3JcbiAqL1xuZXhwb3J0IGNsYXNzIERhdGVSYW5nZVZhbGlkYXRvciBpbXBsZW1lbnRzIENlbGxWYWxpZGF0b3I8RGF0ZT4ge1xuICBlcnJvck1lc3NhZ2U6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1pbkRhdGU/OiBEYXRlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbWF4RGF0ZT86IERhdGUsXG4gICAgY3VzdG9tTWVzc2FnZT86IHN0cmluZ1xuICApIHtcbiAgICB0aGlzLmVycm9yTWVzc2FnZSA9IGN1c3RvbU1lc3NhZ2UgPz8gdGhpcy5idWlsZEVycm9yTWVzc2FnZSgpO1xuICB9XG5cbiAgdmFsaWRhdGUodmFsdWU6IERhdGUpOiBWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoaXNOdWxsT3JVbmRlZmluZWQodmFsdWUpKSB7XG4gICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSB9O1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGUgPSB2YWx1ZSBpbnN0YW5jZW9mIERhdGUgPyB2YWx1ZSA6IG5ldyBEYXRlKHZhbHVlKTtcblxuICAgIGlmIChpc05hTihkYXRlLmdldFRpbWUoKSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgICAgZXJyb3I6ICdJbnZhbGlkIGRhdGUnXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1pbkRhdGUgJiYgZGF0ZSA8IHRoaXMubWluRGF0ZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICBlcnJvcjogYERhdGUgbXVzdCBiZSBvbiBvciBhZnRlciAke3RoaXMubWluRGF0ZS50b0xvY2FsZURhdGVTdHJpbmcoKX1gXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1heERhdGUgJiYgZGF0ZSA+IHRoaXMubWF4RGF0ZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICBlcnJvcjogYERhdGUgbXVzdCBiZSBvbiBvciBiZWZvcmUgJHt0aGlzLm1heERhdGUudG9Mb2NhbGVEYXRlU3RyaW5nKCl9YFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSB9O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEVycm9yTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLm1pbkRhdGUgJiYgdGhpcy5tYXhEYXRlKSB7XG4gICAgICByZXR1cm4gYERhdGUgbXVzdCBiZSBiZXR3ZWVuICR7dGhpcy5taW5EYXRlLnRvTG9jYWxlRGF0ZVN0cmluZygpfSBhbmQgJHt0aGlzLm1heERhdGUudG9Mb2NhbGVEYXRlU3RyaW5nKCl9YDtcbiAgICB9IGVsc2UgaWYgKHRoaXMubWluRGF0ZSkge1xuICAgICAgcmV0dXJuIGBEYXRlIG11c3QgYmUgb24gb3IgYWZ0ZXIgJHt0aGlzLm1pbkRhdGUudG9Mb2NhbGVEYXRlU3RyaW5nKCl9YDtcbiAgICB9IGVsc2UgaWYgKHRoaXMubWF4RGF0ZSkge1xuICAgICAgcmV0dXJuIGBEYXRlIG11c3QgYmUgb24gb3IgYmVmb3JlICR7dGhpcy5tYXhEYXRlLnRvTG9jYWxlRGF0ZVN0cmluZygpfWA7XG4gICAgfVxuICAgIHJldHVybiAnSW52YWxpZCBkYXRlJztcbiAgfVxufVxuXG4vKipcbiAqIEN1c3RvbSBmdW5jdGlvbiB2YWxpZGF0b3JcbiAqL1xuZXhwb3J0IGNsYXNzIEZ1bmN0aW9uVmFsaWRhdG9yPFQgPSBhbnk+IGltcGxlbWVudHMgQ2VsbFZhbGlkYXRvcjxUPiB7XG4gIGVycm9yTWVzc2FnZSA9ICdWYWxpZGF0aW9uIGZhaWxlZCc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSB2YWxpZGF0ZUZuOiAodmFsdWU6IFQpID0+IGJvb2xlYW4gfCBWYWxpZGF0aW9uUmVzdWx0LFxuICAgIGN1c3RvbU1lc3NhZ2U/OiBzdHJpbmdcbiAgKSB7XG4gICAgaWYgKGN1c3RvbU1lc3NhZ2UpIHtcbiAgICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gY3VzdG9tTWVzc2FnZTtcbiAgICB9XG4gIH1cblxuICB2YWxpZGF0ZSh2YWx1ZTogVCk6IFZhbGlkYXRpb25SZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMudmFsaWRhdGVGbih2YWx1ZSk7XG5cbiAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogcmVzdWx0LFxuICAgICAgICBlcnJvcjogcmVzdWx0ID8gdW5kZWZpbmVkIDogdGhpcy5lcnJvck1lc3NhZ2VcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuXG4vKipcbiAqIENvbXBvc2l0ZSB2YWxpZGF0b3IgLSBjaGFpbnMgbXVsdGlwbGUgdmFsaWRhdG9ycyAoQ2hhaW4gb2YgUmVzcG9uc2liaWxpdHkpXG4gKi9cbmV4cG9ydCBjbGFzcyBDaGFpblZhbGlkYXRvcjxUID0gYW55PiBpbXBsZW1lbnRzIENvbXBvc2l0ZVZhbGlkYXRvcjxUPiB7XG4gIGVycm9yTWVzc2FnZSA9ICdWYWxpZGF0aW9uIGZhaWxlZCc7XG5cbiAgcHJpdmF0ZSB2YWxpZGF0b3JzOiBDZWxsVmFsaWRhdG9yPFQ+W10gPSBbXTtcblxuICBjb25zdHJ1Y3Rvcih2YWxpZGF0b3JzPzogQ2VsbFZhbGlkYXRvcjxUPltdKSB7XG4gICAgaWYgKHZhbGlkYXRvcnMpIHtcbiAgICAgIHRoaXMudmFsaWRhdG9ycyA9IHZhbGlkYXRvcnM7XG4gICAgfVxuICB9XG5cbiAgYWRkVmFsaWRhdG9yKHZhbGlkYXRvcjogQ2VsbFZhbGlkYXRvcjxUPik6IHRoaXMge1xuICAgIHRoaXMudmFsaWRhdG9ycy5wdXNoKHZhbGlkYXRvcik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBnZXRWYWxpZGF0b3JzKCk6IENlbGxWYWxpZGF0b3I8VD5bXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLnZhbGlkYXRvcnNdO1xuICB9XG5cbiAgdmFsaWRhdGUodmFsdWU6IFQpOiBWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBjb25zdCBlcnJvcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgICBsZXQgYWxsVmFsaWQgPSB0cnVlO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZhbGlkYXRvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IHRoaXMudmFsaWRhdG9yc1tpXTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRvci52YWxpZGF0ZSh2YWx1ZSk7XG5cbiAgICAgIGlmICghcmVzdWx0LnZhbGlkKSB7XG4gICAgICAgIGFsbFZhbGlkID0gZmFsc2U7XG4gICAgICAgIGVycm9yc1tgdmFsaWRhdG9yXyR7aX1gXSA9IHJlc3VsdC5lcnJvciB8fCAnVmFsaWRhdGlvbiBmYWlsZWQnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghYWxsVmFsaWQpIHtcbiAgICAgIGNvbnN0IGZpcnN0RXJyb3IgPSBPYmplY3QudmFsdWVzKGVycm9ycylbMF07XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogZmFsc2UsXG4gICAgICAgIGVycm9yOiBmaXJzdEVycm9yLFxuICAgICAgICBlcnJvcnNcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdmFsaWQ6IHRydWUgfTtcbiAgfVxufVxuXG4vKipcbiAqIEFzeW5jIHZhbGlkYXRvciBpbnRlcmZhY2UgKGZvciBmdXR1cmUgaW1wbGVtZW50YXRpb24pXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXN5bmNDZWxsVmFsaWRhdG9yPFQgPSBhbnk+IHtcbiAgdmFsaWRhdGVBc3luYyh2YWx1ZTogVCk6IFByb21pc2U8VmFsaWRhdGlvblJlc3VsdD47XG59XG5cbi8qKlxuICogUGF0dGVybiB2YWxpZGF0b3JzIGZvciBjb21tb24gdXNlIGNhc2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBQYXR0ZXJuVmFsaWRhdG9ycyB7XG4gIHN0YXRpYyBlbWFpbChtZXNzYWdlPzogc3RyaW5nKTogRW1haWxWYWxpZGF0b3Ige1xuICAgIHJldHVybiBuZXcgRW1haWxWYWxpZGF0b3IobWVzc2FnZSk7XG4gIH1cblxuICBzdGF0aWMgdXJsKG1lc3NhZ2U/OiBzdHJpbmcpOiBVcmxWYWxpZGF0b3Ige1xuICAgIHJldHVybiBuZXcgVXJsVmFsaWRhdG9yKG1lc3NhZ2UpO1xuICB9XG5cbiAgc3RhdGljIHJlcXVpcmVkKG1lc3NhZ2U/OiBzdHJpbmcpOiBSZXF1aXJlZFZhbGlkYXRvciB7XG4gICAgcmV0dXJuIG5ldyBSZXF1aXJlZFZhbGlkYXRvcihtZXNzYWdlKTtcbiAgfVxuXG4gIHN0YXRpYyByYW5nZShtaW4/OiBudW1iZXIsIG1heD86IG51bWJlciwgbWVzc2FnZT86IHN0cmluZyk6IFJhbmdlVmFsaWRhdG9yIHtcbiAgICByZXR1cm4gbmV3IFJhbmdlVmFsaWRhdG9yKG1pbiwgbWF4LCBtZXNzYWdlKTtcbiAgfVxuXG4gIHN0YXRpYyBzdHJpbmdMZW5ndGgobWluPzogbnVtYmVyLCBtYXg/OiBudW1iZXIsIG1lc3NhZ2U/OiBzdHJpbmcpOiBMZW5ndGhWYWxpZGF0b3Ige1xuICAgIHJldHVybiBuZXcgTGVuZ3RoVmFsaWRhdG9yKG1pbiwgbWF4LCBtZXNzYWdlKTtcbiAgfVxuXG4gIHN0YXRpYyByZWdleChwYXR0ZXJuOiBSZWdFeHAgfCBzdHJpbmcsIG1lc3NhZ2U/OiBzdHJpbmcpOiBSZWdleFZhbGlkYXRvciB7XG4gICAgcmV0dXJuIG5ldyBSZWdleFZhbGlkYXRvcihwYXR0ZXJuLCBtZXNzYWdlKTtcbiAgfVxuXG4gIHN0YXRpYyBkYXRlUmFuZ2UobWluPzogRGF0ZSwgbWF4PzogRGF0ZSwgbWVzc2FnZT86IHN0cmluZyk6IERhdGVSYW5nZVZhbGlkYXRvciB7XG4gICAgcmV0dXJuIG5ldyBEYXRlUmFuZ2VWYWxpZGF0b3IobWluLCBtYXgsIG1lc3NhZ2UpO1xuICB9XG5cbiAgc3RhdGljIGN1c3RvbTxUPihmbjogKHZhbHVlOiBUKSA9PiBib29sZWFuIHwgVmFsaWRhdGlvblJlc3VsdCwgbWVzc2FnZT86IHN0cmluZyk6IEZ1bmN0aW9uVmFsaWRhdG9yPFQ+IHtcbiAgICByZXR1cm4gbmV3IEZ1bmN0aW9uVmFsaWRhdG9yKGZuLCBtZXNzYWdlKTtcbiAgfVxuXG4gIHN0YXRpYyBjaGFpbjxUPiguLi52YWxpZGF0b3JzOiBDZWxsVmFsaWRhdG9yPFQ+W10pOiBDaGFpblZhbGlkYXRvcjxUPiB7XG4gICAgcmV0dXJuIG5ldyBDaGFpblZhbGlkYXRvcih2YWxpZGF0b3JzKTtcbiAgfVxufVxuXG4iXX0=