@seniorsistemas/components-ai 0.0.0-master-d4a804fe

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 (76) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/CONTRIBUTING.md +317 -0
  3. package/README.md +161 -0
  4. package/docs/API.md +486 -0
  5. package/docs/COMPONENTS.md +272 -0
  6. package/docs/EXAMPLES.md +559 -0
  7. package/docs/MIGRATION.md +367 -0
  8. package/esm2022/lib/angular-components.module.mjs +25 -0
  9. package/esm2022/lib/components/breadcrumb/breadcrumb.component.mjs +121 -0
  10. package/esm2022/lib/components/bulk-delete-dialog/bulk-delete-dialog.component.mjs +176 -0
  11. package/esm2022/lib/components/dynamic-form/dynamic-form.component.mjs +625 -0
  12. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-date.component.mjs +86 -0
  13. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-dropdown.component.mjs +103 -0
  14. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-lookup.component.mjs +599 -0
  15. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-number.component.mjs +92 -0
  16. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-text.component.mjs +163 -0
  17. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-textarea.component.mjs +81 -0
  18. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-wrapper.component.mjs +93 -0
  19. package/esm2022/lib/components/dynamic-form/fields/index.mjs +8 -0
  20. package/esm2022/lib/components/dynamic-form/models/dynamic-form.models.mjs +2 -0
  21. package/esm2022/lib/components/export-dialog/export-dialog.component.mjs +219 -0
  22. package/esm2022/lib/config/translation.config.mjs +70 -0
  23. package/esm2022/lib/directives/cep-mask.directive.mjs +79 -0
  24. package/esm2022/lib/directives/document-mask.directive.mjs +62 -0
  25. package/esm2022/lib/directives/phone-mask.directive.mjs +59 -0
  26. package/esm2022/lib/interceptors/api.interceptor.mjs +55 -0
  27. package/esm2022/lib/models/base-entity.interface.mjs +2 -0
  28. package/esm2022/lib/models/entity-list.config.mjs +2 -0
  29. package/esm2022/lib/pipes/translate.pipe.mjs +74 -0
  30. package/esm2022/lib/services/auth.service.mjs +169 -0
  31. package/esm2022/lib/services/cookie.service.mjs +90 -0
  32. package/esm2022/lib/services/entity.service.mjs +208 -0
  33. package/esm2022/lib/services/mask.service.mjs +121 -0
  34. package/esm2022/lib/services/permission.service.mjs +180 -0
  35. package/esm2022/lib/services/senior-token.service.mjs +209 -0
  36. package/esm2022/lib/services/theme.service.mjs +85 -0
  37. package/esm2022/lib/services/translation.service.mjs +232 -0
  38. package/esm2022/public-api.mjs +90 -0
  39. package/esm2022/seniorsistemas-components-ai.mjs +5 -0
  40. package/fesm2022/seniorsistemas-components-ai.mjs +4006 -0
  41. package/fesm2022/seniorsistemas-components-ai.mjs.map +1 -0
  42. package/index.d.ts +5 -0
  43. package/lib/angular-components.module.d.ts +13 -0
  44. package/lib/components/breadcrumb/breadcrumb.component.d.ts +23 -0
  45. package/lib/components/bulk-delete-dialog/bulk-delete-dialog.component.d.ts +46 -0
  46. package/lib/components/dynamic-form/dynamic-form.component.d.ts +97 -0
  47. package/lib/components/dynamic-form/fields/dynamic-field-date.component.d.ts +16 -0
  48. package/lib/components/dynamic-form/fields/dynamic-field-dropdown.component.d.ts +17 -0
  49. package/lib/components/dynamic-form/fields/dynamic-field-lookup.component.d.ts +52 -0
  50. package/lib/components/dynamic-form/fields/dynamic-field-number.component.d.ts +16 -0
  51. package/lib/components/dynamic-form/fields/dynamic-field-text.component.d.ts +17 -0
  52. package/lib/components/dynamic-form/fields/dynamic-field-textarea.component.d.ts +16 -0
  53. package/lib/components/dynamic-form/fields/dynamic-field-wrapper.component.d.ts +20 -0
  54. package/lib/components/dynamic-form/fields/index.d.ts +7 -0
  55. package/lib/components/dynamic-form/models/dynamic-form.models.d.ts +178 -0
  56. package/lib/components/export-dialog/export-dialog.component.d.ts +56 -0
  57. package/lib/config/translation.config.d.ts +24 -0
  58. package/lib/directives/cep-mask.directive.d.ts +13 -0
  59. package/lib/directives/document-mask.directive.d.ts +19 -0
  60. package/lib/directives/phone-mask.directive.d.ts +11 -0
  61. package/lib/interceptors/api.interceptor.d.ts +2 -0
  62. package/lib/models/base-entity.interface.d.ts +7 -0
  63. package/lib/models/entity-list.config.d.ts +161 -0
  64. package/lib/pipes/translate.pipe.d.ts +21 -0
  65. package/lib/services/auth.service.d.ts +82 -0
  66. package/lib/services/cookie.service.d.ts +31 -0
  67. package/lib/services/entity.service.d.ts +99 -0
  68. package/lib/services/mask.service.d.ts +36 -0
  69. package/lib/services/permission.service.d.ts +91 -0
  70. package/lib/services/senior-token.service.d.ts +70 -0
  71. package/lib/services/theme.service.d.ts +16 -0
  72. package/lib/services/translation.service.d.ts +54 -0
  73. package/package.json +53 -0
  74. package/public-api.d.ts +17 -0
  75. package/src/lib/styles/entity-list.shared.scss +383 -0
  76. package/src/lib/styles/index.scss +10 -0
@@ -0,0 +1,625 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { ReactiveFormsModule } from '@angular/forms';
4
+ import { PanelModule } from 'primeng/panel';
5
+ import { DialogModule } from 'primeng/dialog';
6
+ import { DrawerModule } from 'primeng/drawer';
7
+ import { ButtonModule } from 'primeng/button';
8
+ import { TranslatePipe } from '../../pipes/translate.pipe';
9
+ import { DynamicFieldTextComponent } from './fields/dynamic-field-text.component';
10
+ import { DynamicFieldNumberComponent } from './fields/dynamic-field-number.component';
11
+ import { DynamicFieldDateComponent } from './fields/dynamic-field-date.component';
12
+ import { DynamicFieldDropdownComponent } from './fields/dynamic-field-dropdown.component';
13
+ import { DynamicFieldLookupComponent } from './fields/dynamic-field-lookup.component';
14
+ import { DynamicFieldTextareaComponent } from './fields/dynamic-field-textarea.component';
15
+ import * as i0 from "@angular/core";
16
+ import * as i1 from "@angular/forms";
17
+ import * as i2 from "../../services/translation.service";
18
+ import * as i3 from "@angular/common";
19
+ import * as i4 from "primeng/panel";
20
+ import * as i5 from "primeng/api";
21
+ import * as i6 from "primeng/dialog";
22
+ import * as i7 from "primeng/drawer";
23
+ import * as i8 from "primeng/button";
24
+ export class DynamicFormComponent {
25
+ fb;
26
+ translationService;
27
+ formFields = [];
28
+ formSections = [];
29
+ fixedFilters = []; // Filtros fixos (sempre visíveis no topo)
30
+ filterSections = []; // Seções de filtros (colapsáveis)
31
+ entityData = null;
32
+ mode = 'form';
33
+ // Display Mode Configuration
34
+ displayMode = 'inline';
35
+ visible = false;
36
+ dialogConfig = {};
37
+ drawerConfig = {};
38
+ // Button Configuration
39
+ showSubmitButton = false;
40
+ showCancelButton = false;
41
+ submitButtonLabel;
42
+ cancelButtonLabel;
43
+ submitButtonIcon = 'pi pi-check';
44
+ cancelButtonIcon = 'pi pi-times';
45
+ formReady = new EventEmitter();
46
+ formSubmit = new EventEmitter();
47
+ visibleChange = new EventEmitter();
48
+ onCancel = new EventEmitter();
49
+ fieldSave = new EventEmitter();
50
+ form;
51
+ loading = false;
52
+ // Inline edit mode state
53
+ editingField = null;
54
+ savingField = false;
55
+ get hasFields() {
56
+ return this.formFields.length > 0;
57
+ }
58
+ get hasSections() {
59
+ return this.formSections.length > 0;
60
+ }
61
+ get hasFixedFilters() {
62
+ return this.fixedFilters.length > 0;
63
+ }
64
+ get hasFilterSections() {
65
+ return this.filterSections.length > 0;
66
+ }
67
+ get allFields() {
68
+ // Retorna todos os campos (diretos + das seções + filtros fixos + seções de filtros)
69
+ const sectionFields = this.formSections.flatMap(section => section.fields);
70
+ const filterSectionFields = this.filterSections.flatMap(section => section.fields);
71
+ return [...this.formFields, ...sectionFields, ...this.fixedFilters, ...filterSectionFields];
72
+ }
73
+ get isInlineMode() {
74
+ return this.displayMode === 'inline';
75
+ }
76
+ get isInlineEditMode() {
77
+ return this.mode === 'inline-edit';
78
+ }
79
+ get fieldMode() {
80
+ return this.isInlineEditMode ? 'form' : this.mode;
81
+ }
82
+ get isDialogMode() {
83
+ return this.displayMode === 'dialog';
84
+ }
85
+ get isDrawerMode() {
86
+ return this.displayMode === 'drawer';
87
+ }
88
+ // Dialog configuration with defaults
89
+ get dialogHeader() {
90
+ return this.dialogConfig.header || this.translationService.translate('crmx.business.form');
91
+ }
92
+ get dialogWidth() {
93
+ return this.dialogConfig.width || '600px';
94
+ }
95
+ get dialogDraggable() {
96
+ return this.dialogConfig.draggable !== undefined ? this.dialogConfig.draggable : false;
97
+ }
98
+ get dialogResizable() {
99
+ return this.dialogConfig.resizable !== undefined ? this.dialogConfig.resizable : false;
100
+ }
101
+ get dialogMaximizable() {
102
+ return this.dialogConfig.maximizable !== undefined ? this.dialogConfig.maximizable : false;
103
+ }
104
+ get dialogCloseOnEscape() {
105
+ return this.dialogConfig.closeOnEscape !== undefined ? this.dialogConfig.closeOnEscape : true;
106
+ }
107
+ get dialogDismissableMask() {
108
+ return this.dialogConfig.dismissableMask !== undefined ? this.dialogConfig.dismissableMask : false;
109
+ }
110
+ // Drawer configuration with defaults
111
+ get drawerHeader() {
112
+ return this.drawerConfig.header || this.translationService.translate('crmx.business.form');
113
+ }
114
+ get drawerPosition() {
115
+ return this.drawerConfig.position || 'right';
116
+ }
117
+ get drawerShowCloseIcon() {
118
+ return this.drawerConfig.showCloseIcon !== undefined ? this.drawerConfig.showCloseIcon : true;
119
+ }
120
+ get drawerCloseOnEscape() {
121
+ return this.drawerConfig.closeOnEscape !== undefined ? this.drawerConfig.closeOnEscape : true;
122
+ }
123
+ get drawerDismissable() {
124
+ return this.drawerConfig.dismissable !== undefined ? this.drawerConfig.dismissable : true;
125
+ }
126
+ get drawerStyle() {
127
+ const position = this.drawerPosition;
128
+ const isHorizontal = position === 'left' || position === 'right';
129
+ // Se tem customWidth, usa ela
130
+ if (this.drawerConfig.customWidth) {
131
+ return isHorizontal
132
+ ? { width: this.drawerConfig.customWidth }
133
+ : { height: this.drawerConfig.customWidth };
134
+ }
135
+ // Usa o tamanho padronizado
136
+ const size = this.drawerConfig.size || 'medium';
137
+ const sizeMap = {
138
+ 'small': isHorizontal ? '25%' : '25vh',
139
+ 'medium': isHorizontal ? '40%' : '40vh',
140
+ 'large': isHorizontal ? '60%' : '60vh',
141
+ 'xlarge': isHorizontal ? '80%' : '80vh',
142
+ 'full': isHorizontal ? '100%' : '100vh'
143
+ };
144
+ const sizeValue = sizeMap[size];
145
+ return isHorizontal
146
+ ? { width: sizeValue }
147
+ : { height: sizeValue };
148
+ }
149
+ get submitLabel() {
150
+ return this.submitButtonLabel || this.translationService.translate('crmx.business.save');
151
+ }
152
+ get cancelLabel() {
153
+ return this.cancelButtonLabel || this.translationService.translate('crmx.business.cancel');
154
+ }
155
+ constructor(fb, translationService) {
156
+ this.fb = fb;
157
+ this.translationService = translationService;
158
+ }
159
+ ngOnInit() {
160
+ this.initForm();
161
+ this.setupConditionalFieldsWatcher();
162
+ this.formReady.emit(this.form);
163
+ }
164
+ ngOnChanges(changes) {
165
+ if (changes['entityData'] && this.form) {
166
+ if (this.entityData) {
167
+ this.loadEntityData();
168
+ }
169
+ else {
170
+ this.resetForm();
171
+ }
172
+ }
173
+ // Reset loading and form when dialog/drawer is opened
174
+ if (changes['visible'] && changes['visible'].currentValue === true) {
175
+ this.loading = false;
176
+ // If opening without entityData (new record), reset form
177
+ if (!this.entityData && this.form) {
178
+ this.resetForm();
179
+ }
180
+ }
181
+ }
182
+ initForm() {
183
+ const formControls = {};
184
+ // Processa todos os campos (diretos + das seções)
185
+ this.allFields.forEach(field => {
186
+ const defaultValue = this.getDefaultValue(field);
187
+ const validators = this.mode === 'filter' ? [] : (field.validators || []);
188
+ const control = this.fb.control({ value: defaultValue, disabled: field.disabled || false }, validators);
189
+ formControls[field.field] = control;
190
+ });
191
+ this.form = this.fb.group(formControls);
192
+ this.applyInitialDisabledState();
193
+ }
194
+ getDefaultValue(field) {
195
+ if (field.defaultValue !== undefined) {
196
+ return field.defaultValue;
197
+ }
198
+ switch (field.type) {
199
+ case 'number':
200
+ case 'date':
201
+ return null;
202
+ case 'dropdown':
203
+ case 'enum':
204
+ return this.mode === 'filter' ? null : '';
205
+ default:
206
+ return '';
207
+ }
208
+ }
209
+ applyInitialDisabledState() {
210
+ this.allFields.forEach(field => {
211
+ if (field.disabledWhen) {
212
+ const control = this.form.get(field.field);
213
+ if (control && this.isFieldDisabled(field)) {
214
+ control.disable();
215
+ }
216
+ }
217
+ });
218
+ }
219
+ loadEntityData() {
220
+ if (this.entityData && this.form) {
221
+ const processedData = this.processEntityData(this.entityData);
222
+ this.form.patchValue(processedData);
223
+ }
224
+ }
225
+ processEntityData(entity) {
226
+ const processedData = { ...entity };
227
+ this.allFields.forEach(field => {
228
+ if (field.type === 'lookup' && processedData[field.field]) {
229
+ const lookupValue = processedData[field.field];
230
+ // Keep the full object if it has display data, otherwise extract ID
231
+ if (typeof lookupValue === 'object' && lookupValue.id) {
232
+ const hasDisplayData = field.lookupDisplayFields
233
+ ? field.lookupDisplayFields.some(f => this.getNestedValue(lookupValue, f))
234
+ : lookupValue[field.lookupDisplayField || 'name'];
235
+ if (hasDisplayData) {
236
+ // Keep the full object to avoid unnecessary API calls
237
+ processedData[field.field] = lookupValue;
238
+ }
239
+ else {
240
+ // Only has ID, extract it
241
+ processedData[field.field] = lookupValue.id;
242
+ }
243
+ }
244
+ }
245
+ });
246
+ return processedData;
247
+ }
248
+ getNestedValue(obj, path) {
249
+ return path.split('.').reduce((current, key) => current?.[key], obj);
250
+ }
251
+ resetForm() {
252
+ if (this.form) {
253
+ const resetValues = {};
254
+ this.allFields.forEach(field => {
255
+ resetValues[field.field] = this.getDefaultValue(field);
256
+ });
257
+ this.form.reset(resetValues);
258
+ }
259
+ }
260
+ processFilterValue(formValue) {
261
+ const processedValue = { ...formValue };
262
+ this.allFields.forEach(field => {
263
+ const fieldValue = processedValue[field.field];
264
+ if (field.type === 'lookup') {
265
+ if (fieldValue && typeof fieldValue === 'object' && fieldValue.id) {
266
+ processedValue[field.field] = fieldValue;
267
+ }
268
+ else if (fieldValue && typeof fieldValue === 'string') {
269
+ processedValue[field.field] = { id: fieldValue };
270
+ }
271
+ else {
272
+ processedValue[field.field] = null;
273
+ }
274
+ }
275
+ });
276
+ return processedValue;
277
+ }
278
+ processFormValue(formValue) {
279
+ const processedValue = { ...formValue };
280
+ if (this.entityData?.id) {
281
+ processedValue.id = this.entityData.id;
282
+ }
283
+ this.allFields.forEach(field => {
284
+ const fieldValue = processedValue[field.field];
285
+ if (field.type === 'lookup') {
286
+ // If it's an object, extract the ID
287
+ if (fieldValue && typeof fieldValue === 'object') {
288
+ processedValue[field.field] = fieldValue.id || fieldValue[field.lookupValueField || 'id'] || null;
289
+ }
290
+ else if (fieldValue && fieldValue !== '') {
291
+ // If it's already an ID, keep it
292
+ processedValue[field.field] = { id: fieldValue };
293
+ }
294
+ else {
295
+ processedValue[field.field] = null;
296
+ }
297
+ }
298
+ else if (field.type === 'date') {
299
+ if (fieldValue instanceof Date) {
300
+ processedValue[field.field] = fieldValue.toISOString().split('T')[0];
301
+ }
302
+ else if (!fieldValue) {
303
+ processedValue[field.field] = null;
304
+ }
305
+ }
306
+ else if (['text', 'textarea', 'number', 'enum', 'dropdown'].includes(field.type)) {
307
+ if (fieldValue === '' || fieldValue === undefined) {
308
+ processedValue[field.field] = null;
309
+ }
310
+ }
311
+ });
312
+ return processedValue;
313
+ }
314
+ getFieldGridClass(field) {
315
+ const classes = [];
316
+ // Colspan base (padrão: 6)
317
+ let baseColspan = field.colspan || 6;
318
+ // Verifica condições de colspan dinâmico
319
+ if (field.colspanWhen && field.colspanWhen.length > 0) {
320
+ for (const condition of field.colspanWhen) {
321
+ const dependentFieldValue = this.form.get(condition.field)?.value;
322
+ if (dependentFieldValue === condition.value) {
323
+ baseColspan = condition.colspan;
324
+ break;
325
+ }
326
+ }
327
+ }
328
+ // Adiciona classe base
329
+ classes.push(`col-${baseColspan}`);
330
+ // Suporta tanto o objeto size quanto as propriedades antigas (para compatibilidade)
331
+ const sizeXs = field.size?.xs ?? field.colspanXs;
332
+ const sizeSm = field.size?.sm ?? field.colspanSm;
333
+ const sizeMd = field.size?.md ?? field.colspanMd;
334
+ const sizeLg = field.size?.lg ?? field.colspanLg;
335
+ const sizeXl = field.size?.xl ?? field.colspanXl;
336
+ // Adiciona classes responsivas se definidas
337
+ if (sizeXs !== undefined) {
338
+ classes.push(`col-xs-${sizeXs}`);
339
+ }
340
+ if (sizeSm !== undefined) {
341
+ classes.push(`col-sm-${sizeSm}`);
342
+ }
343
+ if (sizeMd !== undefined) {
344
+ classes.push(`col-md-${sizeMd}`);
345
+ }
346
+ if (sizeLg !== undefined) {
347
+ classes.push(`col-lg-${sizeLg}`);
348
+ }
349
+ if (sizeXl !== undefined) {
350
+ classes.push(`col-xl-${sizeXl}`);
351
+ }
352
+ return classes.join(' ');
353
+ }
354
+ isFieldVisible(field) {
355
+ if (this.mode === 'filter') {
356
+ return true;
357
+ }
358
+ if (!field.visibleWhen) {
359
+ return true;
360
+ }
361
+ const dependentFieldValue = this.form.get(field.visibleWhen.field)?.value;
362
+ return dependentFieldValue === field.visibleWhen.value;
363
+ }
364
+ isFieldDisabled(field) {
365
+ if (field.disabled) {
366
+ return true;
367
+ }
368
+ if (!('disabledWhen' in field) || !field.disabledWhen) {
369
+ return false;
370
+ }
371
+ const dependentFieldValue = this.form.get(field.disabledWhen.field)?.value;
372
+ if (field.disabledWhen.value === null) {
373
+ return !dependentFieldValue;
374
+ }
375
+ return dependentFieldValue === field.disabledWhen.value;
376
+ }
377
+ setupConditionalFieldsWatcher() {
378
+ const visibleDependentFields = this.allFields.filter(field => field.visibleWhen);
379
+ const visibleWatchedFields = [...new Set(visibleDependentFields.map(field => field.visibleWhen.field))];
380
+ const disabledDependentFields = this.allFields.filter(field => field.disabledWhen);
381
+ const disabledWatchedFields = [...new Set(disabledDependentFields.map(field => field.disabledWhen.field))];
382
+ const allWatchedFields = [...new Set([...visibleWatchedFields, ...disabledWatchedFields])];
383
+ allWatchedFields.forEach(fieldName => {
384
+ const control = this.form.get(fieldName);
385
+ if (control) {
386
+ control.valueChanges.subscribe(() => {
387
+ this.clearHiddenFields();
388
+ this.updateDisabledFields();
389
+ });
390
+ }
391
+ });
392
+ }
393
+ updateDisabledFields() {
394
+ this.allFields.forEach(field => {
395
+ if (field.disabledWhen) {
396
+ const control = this.form.get(field.field);
397
+ if (control) {
398
+ const shouldBeDisabled = this.isFieldDisabled(field);
399
+ if (shouldBeDisabled && control.enabled) {
400
+ control.setValue(null);
401
+ control.disable();
402
+ }
403
+ else if (!shouldBeDisabled && control.disabled && !field.disabled) {
404
+ control.enable();
405
+ }
406
+ }
407
+ }
408
+ });
409
+ }
410
+ clearHiddenFields() {
411
+ this.allFields.forEach(field => {
412
+ if (field.visibleWhen && !this.isFieldVisible(field)) {
413
+ const control = this.form.get(field.field);
414
+ if (control) {
415
+ const resetValue = this.getDefaultValue(field);
416
+ control.setValue(resetValue);
417
+ control.markAsUntouched();
418
+ control.markAsPristine();
419
+ }
420
+ }
421
+ });
422
+ }
423
+ getForm() {
424
+ return this.form;
425
+ }
426
+ clearFilters() {
427
+ if (this.mode === 'filter') {
428
+ this.resetForm();
429
+ }
430
+ }
431
+ getTypePersonValue() {
432
+ const typePersonValue = this.form?.get('typePerson')?.value;
433
+ return typePersonValue || 'JURIDICAL_PERSON';
434
+ }
435
+ // Display Mode Control Methods
436
+ open(entity) {
437
+ if (entity) {
438
+ this.entityData = entity;
439
+ }
440
+ else {
441
+ this.entityData = null;
442
+ this.resetForm(); // Reset form when opening for new entity
443
+ }
444
+ this.loading = false; // Reset loading state
445
+ this.visible = true;
446
+ this.visibleChange.emit(true);
447
+ }
448
+ close() {
449
+ this.loading = false; // Reset loading state
450
+ this.visible = false;
451
+ this.visibleChange.emit(false);
452
+ this.resetForm(); // Reset form when closing
453
+ this.onCancel.emit();
454
+ }
455
+ handleCancel() {
456
+ this.close();
457
+ }
458
+ handleSubmit() {
459
+ if (this.mode === 'form' && this.form.invalid) {
460
+ this.form.markAllAsTouched();
461
+ return;
462
+ }
463
+ this.loading = true;
464
+ const formValue = this.mode === 'filter'
465
+ ? this.processFilterValue(this.form.value)
466
+ : this.processFormValue(this.form.value);
467
+ this.formSubmit.emit(formValue);
468
+ }
469
+ // Inline Edit Mode Methods
470
+ startEditField(fieldName) {
471
+ if (this.isInlineEditMode) {
472
+ this.editingField = fieldName;
473
+ // Ensure the field has the current value from entityData
474
+ if (this.entityData) {
475
+ const control = this.form.get(fieldName);
476
+ if (control) {
477
+ const field = this.allFields.find(f => f.field === fieldName);
478
+ const value = this.entityData[fieldName];
479
+ // For lookup fields in inline-edit mode, keep the full object
480
+ // This prevents unnecessary API calls since we already have the data
481
+ if (field?.type === 'lookup' && value && typeof value === 'object') {
482
+ // Keep the full object - the lookup component will use it
483
+ control.setValue(value);
484
+ }
485
+ else {
486
+ control.setValue(value);
487
+ }
488
+ }
489
+ }
490
+ }
491
+ }
492
+ isFieldEditing(fieldName) {
493
+ return this.editingField === fieldName;
494
+ }
495
+ saveInlineField(fieldName) {
496
+ if (!this.isInlineEditMode)
497
+ return;
498
+ const control = this.form.get(fieldName);
499
+ if (!control || control.invalid) {
500
+ control?.markAsTouched();
501
+ return;
502
+ }
503
+ this.savingField = true;
504
+ let fieldValue = control.value;
505
+ // For lookup fields, extract the ID if it's an object
506
+ const field = this.allFields.find(f => f.field === fieldName);
507
+ if (field?.type === 'lookup' && fieldValue && typeof fieldValue === 'object') {
508
+ fieldValue = fieldValue.id || fieldValue[field.lookupValueField || 'id'];
509
+ }
510
+ this.fieldSave.emit({ field: fieldName, value: fieldValue });
511
+ }
512
+ cancelInlineEdit() {
513
+ if (this.isInlineEditMode && this.editingField) {
514
+ const control = this.form.get(this.editingField);
515
+ if (control && this.entityData) {
516
+ // Restore original value
517
+ const originalValue = this.entityData[this.editingField];
518
+ control.setValue(originalValue);
519
+ control.markAsPristine();
520
+ control.markAsUntouched();
521
+ }
522
+ this.editingField = null;
523
+ this.savingField = false;
524
+ }
525
+ }
526
+ // Method to be called by parent after save completes
527
+ completeInlineEdit() {
528
+ this.editingField = null;
529
+ this.savingField = false;
530
+ }
531
+ getFieldDisplayValue(fieldName) {
532
+ if (!this.entityData)
533
+ return '';
534
+ const field = this.allFields.find(f => f.field === fieldName);
535
+ const value = this.entityData[fieldName];
536
+ if (!value)
537
+ return '';
538
+ // For lookup fields, return the display name
539
+ if (field?.type === 'lookup' && typeof value === 'object' && value.name) {
540
+ return value.name;
541
+ }
542
+ // For number fields, format appropriately
543
+ if (field?.type === 'number' && typeof value === 'number') {
544
+ if (field.numberMode === 'currency') {
545
+ return new Intl.NumberFormat(field.locale || 'pt-BR', {
546
+ style: 'currency',
547
+ currency: field.currency || 'BRL'
548
+ }).format(value);
549
+ }
550
+ return new Intl.NumberFormat(field.locale || 'pt-BR', {
551
+ minimumFractionDigits: field.minFractionDigits || 0,
552
+ maximumFractionDigits: field.maxFractionDigits || 2
553
+ }).format(value);
554
+ }
555
+ // For date fields, format as date
556
+ if (field?.type === 'date' && value) {
557
+ const date = typeof value === 'string' ? new Date(value) : value;
558
+ return date.toLocaleDateString('pt-BR');
559
+ }
560
+ return String(value);
561
+ }
562
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFormComponent, deps: [{ token: i1.FormBuilder }, { token: i2.TranslationService }], target: i0.ɵɵFactoryTarget.Component });
563
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DynamicFormComponent, isStandalone: true, selector: "sia-dynamic-form", inputs: { formFields: "formFields", formSections: "formSections", fixedFilters: "fixedFilters", filterSections: "filterSections", entityData: "entityData", mode: "mode", displayMode: "displayMode", visible: "visible", dialogConfig: "dialogConfig", drawerConfig: "drawerConfig", showSubmitButton: "showSubmitButton", showCancelButton: "showCancelButton", submitButtonLabel: "submitButtonLabel", cancelButtonLabel: "cancelButtonLabel", submitButtonIcon: "submitButtonIcon", cancelButtonIcon: "cancelButtonIcon" }, outputs: { formReady: "formReady", formSubmit: "formSubmit", visibleChange: "visibleChange", onCancel: "onCancel", fieldSave: "fieldSave" }, usesOnChanges: true, ngImport: i0, template: "<!-- Modo Inline (padr\u00E3o) -->\n<ng-container *ngIf=\"isInlineMode\">\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n</ng-container>\n\n<!-- Modo Dialog -->\n<p-dialog\n *ngIf=\"isDialogMode\"\n [(visible)]=\"visible\"\n [header]=\"dialogHeader | translate\"\n [modal]=\"true\"\n [style]=\"{ width: dialogWidth }\"\n [draggable]=\"dialogDraggable\"\n [resizable]=\"dialogResizable\"\n [maximizable]=\"dialogMaximizable\"\n [closeOnEscape]=\"dialogCloseOnEscape\"\n [dismissableMask]=\"dialogDismissableMask\"\n (onHide)=\"close()\">\n \n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n \n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"dialog-footer\">\n <p-button\n *ngIf=\"showCancelButton\"\n [label]=\"cancelLabel | translate\"\n [icon]=\"cancelButtonIcon\"\n severity=\"secondary\"\n (onClick)=\"handleCancel()\"\n [disabled]=\"loading\">\n </p-button>\n <p-button\n *ngIf=\"showSubmitButton\"\n [label]=\"submitLabel | translate\"\n [icon]=\"submitButtonIcon\"\n (onClick)=\"handleSubmit()\"\n [loading]=\"loading\"\n [disabled]=\"form.invalid\">\n </p-button>\n </div>\n </ng-template>\n</p-dialog>\n\n<!-- Modo Drawer -->\n<p-drawer\n *ngIf=\"isDrawerMode\"\n [(visible)]=\"visible\"\n [header]=\"drawerHeader | translate\"\n [position]=\"drawerPosition\"\n [style]=\"drawerStyle\"\n [showCloseIcon]=\"drawerShowCloseIcon\"\n [closeOnEscape]=\"drawerCloseOnEscape\"\n [modal]=\"drawerDismissable\"\n (onHide)=\"close()\">\n \n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n \n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"drawer-footer\">\n <p-button\n *ngIf=\"showCancelButton\"\n [label]=\"cancelLabel | translate\"\n [icon]=\"cancelButtonIcon\"\n severity=\"secondary\"\n (onClick)=\"handleCancel()\"\n [disabled]=\"loading\">\n </p-button>\n <p-button\n *ngIf=\"showSubmitButton\"\n [label]=\"submitLabel | translate\"\n [icon]=\"submitButtonIcon\"\n (onClick)=\"handleSubmit()\"\n [loading]=\"loading\"\n [disabled]=\"form.invalid\">\n </p-button>\n </div>\n </ng-template>\n</p-drawer>\n\n<!-- Template do Formul\u00E1rio (reutiliz\u00E1vel) -->\n<ng-template #formContent>\n <form [formGroup]=\"form\" class=\"dynamic-form\">\n \n <!-- Filtros Fixos (apenas no modo filter) -->\n <div *ngIf=\"mode === 'filter' && hasFixedFilters\" class=\"fixed-filters-section\">\n <div class=\"grid\">\n <ng-container *ngFor=\"let field of fixedFilters\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Campos Diretos (sem se\u00E7\u00E3o) -->\n <div *ngIf=\"hasFields\">\n <!-- Modo Inline Edit -->\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of formFields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n\n <!-- Modo Form Normal -->\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of formFields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Se\u00E7\u00F5es de Campos (modo form) -->\n <div *ngIf=\"hasSections\" class=\"sections-container\">\n <p-panel \n *ngFor=\"let section of formSections\"\n [toggleable]=\"section.toggleable !== false\"\n [collapsed]=\"section.collapsed || false\"\n [styleClass]=\"'section-panel'\">\n \n <ng-template pTemplate=\"header\">\n <div class=\"section-header\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n <span class=\"section-title\">{{ section.title }}</span>\n </div>\n </ng-template>\n\n <!-- Modo Inline Edit -->\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n\n <!-- Modo Form Normal -->\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n </div>\n\n <!-- Se\u00E7\u00F5es de Filtros (apenas no modo filter) -->\n <div *ngIf=\"mode === 'filter' && hasFilterSections\" class=\"filter-sections-container\">\n <p-panel \n *ngFor=\"let section of filterSections\"\n [header]=\"section.title\"\n [toggleable]=\"true\"\n [collapsed]=\"true\">\n\n <div class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n </div>\n\n <!-- Bot\u00F5es inline (apenas para modo inline) -->\n <div *ngIf=\"isInlineMode && (showSubmitButton || showCancelButton)\" class=\"form-actions\">\n <p-button\n *ngIf=\"showCancelButton\"\n [label]=\"cancelLabel | translate\"\n [icon]=\"cancelButtonIcon\"\n severity=\"secondary\"\n (onClick)=\"handleCancel()\"\n [disabled]=\"loading\">\n </p-button>\n <p-button\n *ngIf=\"showSubmitButton\"\n [label]=\"submitLabel | translate\"\n [icon]=\"submitButtonIcon\"\n (onClick)=\"handleSubmit()\"\n [loading]=\"loading\"\n [disabled]=\"form.invalid\">\n </p-button>\n </div>\n\n </form>\n</ng-template>\n\n<!-- Template de Campo (reutiliz\u00E1vel) -->\n<ng-template #fieldTemplate let-field=\"field\">\n <!-- Text Field -->\n <sia-dynamic-field-text\n *ngIf=\"field.type === 'text'\"\n [field]=\"field\"\n [form]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-text>\n\n <!-- Textarea Field -->\n <sia-dynamic-field-textarea\n *ngIf=\"field.type === 'textarea'\"\n [field]=\"field\"\n [form]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-textarea>\n\n <!-- Number Field -->\n <sia-dynamic-field-number\n *ngIf=\"field.type === 'number'\"\n [field]=\"field\"\n [form]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-number>\n\n <!-- Date Field -->\n <sia-dynamic-field-date\n *ngIf=\"field.type === 'date'\"\n [field]=\"field\"\n [form]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-date>\n\n <!-- Dropdown/Enum Field -->\n <sia-dynamic-field-dropdown\n *ngIf=\"field.type === 'dropdown' || field.type === 'enum'\"\n [field]=\"field\"\n [form]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-dropdown>\n\n <!-- Lookup Field -->\n <sia-dynamic-field-lookup\n *ngIf=\"field.type === 'lookup'\"\n [field]=\"field\"\n [form]=\"form\"\n [formGroup]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-lookup>\n</ng-template>\n\n\n<!-- Template de Campo Inline Edit -->\n<ng-template #inlineEditFieldTemplate let-field=\"field\">\n <div class=\"edit-inline-field\">\n <label class=\"field-label\">{{ field.label | translate }}</label>\n \n <!-- Display Mode -->\n <div class=\"field-display\" \n *ngIf=\"!isFieldEditing(field.field)\" \n (click)=\"startEditField(field.field)\"\n [class.disabled]=\"field.disabled\">\n <span class=\"display-value\" \n [attr.data-placeholder]=\"field.placeholder || ('crmx.business.not_informed' | translate)\">\n {{ getFieldDisplayValue(field.field) }}\n </span>\n <i class=\"pi pi-pencil edit-icon\" *ngIf=\"!field.disabled\"></i>\n </div>\n \n <!-- Edit Mode -->\n <div class=\"field-edit\" *ngIf=\"isFieldEditing(field.field)\">\n <div class=\"input-container\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n \n <!-- Action Buttons -->\n <div class=\"edit-actions\">\n <p-button \n type=\"button\" \n icon=\"pi pi-check\" \n [rounded]=\"true\"\n severity=\"primary\"\n (onClick)=\"saveInlineField(field.field)\" \n [loading]=\"savingField\"\n [disabled]=\"form.get(field.field)?.invalid\">\n </p-button>\n <p-button \n type=\"button\" \n icon=\"pi pi-times\" \n [rounded]=\"true\"\n severity=\"secondary\"\n (onClick)=\"cancelInlineEdit()\"\n [disabled]=\"savingField\">\n </p-button>\n </div>\n \n <!-- Error Message -->\n <div class=\"field-error\" *ngIf=\"form.get(field.field)?.invalid && form.get(field.field)?.touched\">\n <small class=\"p-error\">\n {{ form.get(field.field)?.errors?.['required'] ? ('crmx.business.required_field' | translate) : '' }}\n </small>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".dynamic-form{width:100%}.dynamic-form .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}.dynamic-form .grid>div.col-1{grid-column:span 1}.dynamic-form .grid>div.col-2{grid-column:span 2}.dynamic-form .grid>div.col-3{grid-column:span 3}.dynamic-form .grid>div.col-4{grid-column:span 4}.dynamic-form .grid>div.col-5{grid-column:span 5}.dynamic-form .grid>div.col-6{grid-column:span 6}.dynamic-form .grid>div.col-7{grid-column:span 7}.dynamic-form .grid>div.col-8{grid-column:span 8}.dynamic-form .grid>div.col-9{grid-column:span 9}.dynamic-form .grid>div.col-10{grid-column:span 10}.dynamic-form .grid>div.col-11{grid-column:span 11}.dynamic-form .grid>div.col-12{grid-column:span 12}@media (max-width: 575.98px){.dynamic-form .grid>div.col-xs-1{grid-column:span 1}.dynamic-form .grid>div.col-xs-2{grid-column:span 2}.dynamic-form .grid>div.col-xs-3{grid-column:span 3}.dynamic-form .grid>div.col-xs-4{grid-column:span 4}.dynamic-form .grid>div.col-xs-5{grid-column:span 5}.dynamic-form .grid>div.col-xs-6{grid-column:span 6}.dynamic-form .grid>div.col-xs-7{grid-column:span 7}.dynamic-form .grid>div.col-xs-8{grid-column:span 8}.dynamic-form .grid>div.col-xs-9{grid-column:span 9}.dynamic-form .grid>div.col-xs-10{grid-column:span 10}.dynamic-form .grid>div.col-xs-11{grid-column:span 11}.dynamic-form .grid>div.col-xs-12{grid-column:span 12}}@media (min-width: 576px){.dynamic-form .grid>div.col-sm-1{grid-column:span 1}.dynamic-form .grid>div.col-sm-2{grid-column:span 2}.dynamic-form .grid>div.col-sm-3{grid-column:span 3}.dynamic-form .grid>div.col-sm-4{grid-column:span 4}.dynamic-form .grid>div.col-sm-5{grid-column:span 5}.dynamic-form .grid>div.col-sm-6{grid-column:span 6}.dynamic-form .grid>div.col-sm-7{grid-column:span 7}.dynamic-form .grid>div.col-sm-8{grid-column:span 8}.dynamic-form .grid>div.col-sm-9{grid-column:span 9}.dynamic-form .grid>div.col-sm-10{grid-column:span 10}.dynamic-form .grid>div.col-sm-11{grid-column:span 11}.dynamic-form .grid>div.col-sm-12{grid-column:span 12}}@media (min-width: 768px){.dynamic-form .grid>div.col-md-1{grid-column:span 1}.dynamic-form .grid>div.col-md-2{grid-column:span 2}.dynamic-form .grid>div.col-md-3{grid-column:span 3}.dynamic-form .grid>div.col-md-4{grid-column:span 4}.dynamic-form .grid>div.col-md-5{grid-column:span 5}.dynamic-form .grid>div.col-md-6{grid-column:span 6}.dynamic-form .grid>div.col-md-7{grid-column:span 7}.dynamic-form .grid>div.col-md-8{grid-column:span 8}.dynamic-form .grid>div.col-md-9{grid-column:span 9}.dynamic-form .grid>div.col-md-10{grid-column:span 10}.dynamic-form .grid>div.col-md-11{grid-column:span 11}.dynamic-form .grid>div.col-md-12{grid-column:span 12}}@media (min-width: 992px){.dynamic-form .grid>div.col-lg-1{grid-column:span 1}.dynamic-form .grid>div.col-lg-2{grid-column:span 2}.dynamic-form .grid>div.col-lg-3{grid-column:span 3}.dynamic-form .grid>div.col-lg-4{grid-column:span 4}.dynamic-form .grid>div.col-lg-5{grid-column:span 5}.dynamic-form .grid>div.col-lg-6{grid-column:span 6}.dynamic-form .grid>div.col-lg-7{grid-column:span 7}.dynamic-form .grid>div.col-lg-8{grid-column:span 8}.dynamic-form .grid>div.col-lg-9{grid-column:span 9}.dynamic-form .grid>div.col-lg-10{grid-column:span 10}.dynamic-form .grid>div.col-lg-11{grid-column:span 11}.dynamic-form .grid>div.col-lg-12{grid-column:span 12}}@media (min-width: 1200px){.dynamic-form .grid>div.col-xl-1{grid-column:span 1}.dynamic-form .grid>div.col-xl-2{grid-column:span 2}.dynamic-form .grid>div.col-xl-3{grid-column:span 3}.dynamic-form .grid>div.col-xl-4{grid-column:span 4}.dynamic-form .grid>div.col-xl-5{grid-column:span 5}.dynamic-form .grid>div.col-xl-6{grid-column:span 6}.dynamic-form .grid>div.col-xl-7{grid-column:span 7}.dynamic-form .grid>div.col-xl-8{grid-column:span 8}.dynamic-form .grid>div.col-xl-9{grid-column:span 9}.dynamic-form .grid>div.col-xl-10{grid-column:span 10}.dynamic-form .grid>div.col-xl-11{grid-column:span 11}.dynamic-form .grid>div.col-xl-12{grid-column:span 12}}.dynamic-form .sections-container{display:flex;flex-direction:column;gap:1rem;margin-top:1rem}.dynamic-form .sections-container ::ng-deep .section-panel .p-panel-header{background-color:var(--surface-50);border-color:var(--surface-200)}.dynamic-form .sections-container ::ng-deep .section-panel .p-panel-header .section-header{display:flex;align-items:center;gap:.5rem;width:100%}.dynamic-form .sections-container ::ng-deep .section-panel .p-panel-header .section-header .section-icon{font-size:1.1rem;color:var(--primary-color)}.dynamic-form .sections-container ::ng-deep .section-panel .p-panel-header .section-header .section-title{font-weight:600;color:var(--text-color)}.dynamic-form .sections-container ::ng-deep .section-panel .p-panel-content{padding:1.5rem}.dynamic-form .fixed-filters-section{margin-bottom:1rem;padding-bottom:1rem;border-bottom:1px solid var(--surface-200)}.dynamic-form .filter-sections-container{display:flex;flex-direction:column;gap:1rem;margin-top:1rem}.dynamic-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--surface-200)}.dialog-footer{display:flex;justify-content:flex-end;gap:.5rem}.drawer-footer{display:flex;justify-content:flex-end;gap:.5rem;padding:1rem;border-top:1px solid var(--surface-200)}.inline-edit-fields{display:flex;flex-direction:column;gap:1rem}.inline-edit-fields .inline-edit-field{display:flex;flex-direction:column;gap:.25rem}.inline-edit-fields .inline-edit-field .field-label{font-weight:500;font-size:.875rem;color:var(--text-color-secondary);margin-bottom:.25rem}.inline-edit-fields .inline-edit-field .field-display{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background-color:var(--surface-50);border:1px solid var(--surface-200);border-radius:var(--border-radius);cursor:pointer;transition:all .2s ease;min-height:42px}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled){background-color:var(--surface-100);border-color:var(--primary-color)}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled) .edit-icon{opacity:1}.inline-edit-fields .inline-edit-field .field-display.disabled{cursor:not-allowed;opacity:.6}.inline-edit-fields .inline-edit-field .field-display .display-value{flex:1;color:var(--text-color)}.inline-edit-fields .inline-edit-field .field-display .display-value:empty:before{content:attr(data-placeholder);color:var(--text-color-secondary);font-style:italic}.inline-edit-fields .inline-edit-field .field-display .edit-icon{color:var(--primary-color);font-size:.875rem;opacity:.5;transition:opacity .2s ease}.inline-edit-fields .inline-edit-field .field-edit{display:flex;flex-direction:column;gap:.5rem}.inline-edit-fields .inline-edit-field .field-edit .input-container{flex:1}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field{gap:0}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field label{display:none}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field small.p-error{display:none}.inline-edit-fields .inline-edit-field .field-edit .edit-actions{display:flex;gap:.5rem;justify-content:flex-end}.inline-edit-fields .inline-edit-field .field-edit .field-error small.p-error{color:var(--p-red-500);font-size:.875rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PanelModule }, { kind: "component", type: i4.Panel, selector: "p-panel", inputs: ["toggleable", "header", "collapsed", "style", "styleClass", "iconPos", "expandIcon", "collapseIcon", "showHeader", "toggler", "transitionOptions", "toggleButtonProps"], outputs: ["collapsedChange", "onBeforeToggle", "onAfterToggle"] }, { kind: "directive", type: i5.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i6.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i7.Drawer, selector: "p-drawer", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i8.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: DynamicFieldTextComponent, selector: "sia-dynamic-field-text", inputs: ["field", "form", "mode"] }, { kind: "component", type: DynamicFieldNumberComponent, selector: "sia-dynamic-field-number", inputs: ["field", "form", "mode"] }, { kind: "component", type: DynamicFieldDateComponent, selector: "sia-dynamic-field-date", inputs: ["field", "form", "mode"] }, { kind: "component", type: DynamicFieldDropdownComponent, selector: "sia-dynamic-field-dropdown", inputs: ["field", "form", "mode"] }, { kind: "component", type: DynamicFieldLookupComponent, selector: "sia-dynamic-field-lookup", inputs: ["field", "form", "formGroup", "mode"] }, { kind: "component", type: DynamicFieldTextareaComponent, selector: "sia-dynamic-field-textarea", inputs: ["field", "form", "mode"] }] });
564
+ }
565
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFormComponent, decorators: [{
566
+ type: Component,
567
+ args: [{ selector: 'sia-dynamic-form', standalone: true, imports: [
568
+ CommonModule,
569
+ ReactiveFormsModule,
570
+ PanelModule,
571
+ DialogModule,
572
+ DrawerModule,
573
+ ButtonModule,
574
+ TranslatePipe,
575
+ DynamicFieldTextComponent,
576
+ DynamicFieldNumberComponent,
577
+ DynamicFieldDateComponent,
578
+ DynamicFieldDropdownComponent,
579
+ DynamicFieldLookupComponent,
580
+ DynamicFieldTextareaComponent
581
+ ], template: "<!-- Modo Inline (padr\u00E3o) -->\n<ng-container *ngIf=\"isInlineMode\">\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n</ng-container>\n\n<!-- Modo Dialog -->\n<p-dialog\n *ngIf=\"isDialogMode\"\n [(visible)]=\"visible\"\n [header]=\"dialogHeader | translate\"\n [modal]=\"true\"\n [style]=\"{ width: dialogWidth }\"\n [draggable]=\"dialogDraggable\"\n [resizable]=\"dialogResizable\"\n [maximizable]=\"dialogMaximizable\"\n [closeOnEscape]=\"dialogCloseOnEscape\"\n [dismissableMask]=\"dialogDismissableMask\"\n (onHide)=\"close()\">\n \n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n \n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"dialog-footer\">\n <p-button\n *ngIf=\"showCancelButton\"\n [label]=\"cancelLabel | translate\"\n [icon]=\"cancelButtonIcon\"\n severity=\"secondary\"\n (onClick)=\"handleCancel()\"\n [disabled]=\"loading\">\n </p-button>\n <p-button\n *ngIf=\"showSubmitButton\"\n [label]=\"submitLabel | translate\"\n [icon]=\"submitButtonIcon\"\n (onClick)=\"handleSubmit()\"\n [loading]=\"loading\"\n [disabled]=\"form.invalid\">\n </p-button>\n </div>\n </ng-template>\n</p-dialog>\n\n<!-- Modo Drawer -->\n<p-drawer\n *ngIf=\"isDrawerMode\"\n [(visible)]=\"visible\"\n [header]=\"drawerHeader | translate\"\n [position]=\"drawerPosition\"\n [style]=\"drawerStyle\"\n [showCloseIcon]=\"drawerShowCloseIcon\"\n [closeOnEscape]=\"drawerCloseOnEscape\"\n [modal]=\"drawerDismissable\"\n (onHide)=\"close()\">\n \n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n \n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"drawer-footer\">\n <p-button\n *ngIf=\"showCancelButton\"\n [label]=\"cancelLabel | translate\"\n [icon]=\"cancelButtonIcon\"\n severity=\"secondary\"\n (onClick)=\"handleCancel()\"\n [disabled]=\"loading\">\n </p-button>\n <p-button\n *ngIf=\"showSubmitButton\"\n [label]=\"submitLabel | translate\"\n [icon]=\"submitButtonIcon\"\n (onClick)=\"handleSubmit()\"\n [loading]=\"loading\"\n [disabled]=\"form.invalid\">\n </p-button>\n </div>\n </ng-template>\n</p-drawer>\n\n<!-- Template do Formul\u00E1rio (reutiliz\u00E1vel) -->\n<ng-template #formContent>\n <form [formGroup]=\"form\" class=\"dynamic-form\">\n \n <!-- Filtros Fixos (apenas no modo filter) -->\n <div *ngIf=\"mode === 'filter' && hasFixedFilters\" class=\"fixed-filters-section\">\n <div class=\"grid\">\n <ng-container *ngFor=\"let field of fixedFilters\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Campos Diretos (sem se\u00E7\u00E3o) -->\n <div *ngIf=\"hasFields\">\n <!-- Modo Inline Edit -->\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of formFields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n\n <!-- Modo Form Normal -->\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of formFields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Se\u00E7\u00F5es de Campos (modo form) -->\n <div *ngIf=\"hasSections\" class=\"sections-container\">\n <p-panel \n *ngFor=\"let section of formSections\"\n [toggleable]=\"section.toggleable !== false\"\n [collapsed]=\"section.collapsed || false\"\n [styleClass]=\"'section-panel'\">\n \n <ng-template pTemplate=\"header\">\n <div class=\"section-header\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n <span class=\"section-title\">{{ section.title }}</span>\n </div>\n </ng-template>\n\n <!-- Modo Inline Edit -->\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n\n <!-- Modo Form Normal -->\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n </div>\n\n <!-- Se\u00E7\u00F5es de Filtros (apenas no modo filter) -->\n <div *ngIf=\"mode === 'filter' && hasFilterSections\" class=\"filter-sections-container\">\n <p-panel \n *ngFor=\"let section of filterSections\"\n [header]=\"section.title\"\n [toggleable]=\"true\"\n [collapsed]=\"true\">\n\n <div class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n </div>\n\n <!-- Bot\u00F5es inline (apenas para modo inline) -->\n <div *ngIf=\"isInlineMode && (showSubmitButton || showCancelButton)\" class=\"form-actions\">\n <p-button\n *ngIf=\"showCancelButton\"\n [label]=\"cancelLabel | translate\"\n [icon]=\"cancelButtonIcon\"\n severity=\"secondary\"\n (onClick)=\"handleCancel()\"\n [disabled]=\"loading\">\n </p-button>\n <p-button\n *ngIf=\"showSubmitButton\"\n [label]=\"submitLabel | translate\"\n [icon]=\"submitButtonIcon\"\n (onClick)=\"handleSubmit()\"\n [loading]=\"loading\"\n [disabled]=\"form.invalid\">\n </p-button>\n </div>\n\n </form>\n</ng-template>\n\n<!-- Template de Campo (reutiliz\u00E1vel) -->\n<ng-template #fieldTemplate let-field=\"field\">\n <!-- Text Field -->\n <sia-dynamic-field-text\n *ngIf=\"field.type === 'text'\"\n [field]=\"field\"\n [form]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-text>\n\n <!-- Textarea Field -->\n <sia-dynamic-field-textarea\n *ngIf=\"field.type === 'textarea'\"\n [field]=\"field\"\n [form]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-textarea>\n\n <!-- Number Field -->\n <sia-dynamic-field-number\n *ngIf=\"field.type === 'number'\"\n [field]=\"field\"\n [form]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-number>\n\n <!-- Date Field -->\n <sia-dynamic-field-date\n *ngIf=\"field.type === 'date'\"\n [field]=\"field\"\n [form]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-date>\n\n <!-- Dropdown/Enum Field -->\n <sia-dynamic-field-dropdown\n *ngIf=\"field.type === 'dropdown' || field.type === 'enum'\"\n [field]=\"field\"\n [form]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-dropdown>\n\n <!-- Lookup Field -->\n <sia-dynamic-field-lookup\n *ngIf=\"field.type === 'lookup'\"\n [field]=\"field\"\n [form]=\"form\"\n [formGroup]=\"form\"\n [mode]=\"fieldMode\">\n </sia-dynamic-field-lookup>\n</ng-template>\n\n\n<!-- Template de Campo Inline Edit -->\n<ng-template #inlineEditFieldTemplate let-field=\"field\">\n <div class=\"edit-inline-field\">\n <label class=\"field-label\">{{ field.label | translate }}</label>\n \n <!-- Display Mode -->\n <div class=\"field-display\" \n *ngIf=\"!isFieldEditing(field.field)\" \n (click)=\"startEditField(field.field)\"\n [class.disabled]=\"field.disabled\">\n <span class=\"display-value\" \n [attr.data-placeholder]=\"field.placeholder || ('crmx.business.not_informed' | translate)\">\n {{ getFieldDisplayValue(field.field) }}\n </span>\n <i class=\"pi pi-pencil edit-icon\" *ngIf=\"!field.disabled\"></i>\n </div>\n \n <!-- Edit Mode -->\n <div class=\"field-edit\" *ngIf=\"isFieldEditing(field.field)\">\n <div class=\"input-container\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n \n <!-- Action Buttons -->\n <div class=\"edit-actions\">\n <p-button \n type=\"button\" \n icon=\"pi pi-check\" \n [rounded]=\"true\"\n severity=\"primary\"\n (onClick)=\"saveInlineField(field.field)\" \n [loading]=\"savingField\"\n [disabled]=\"form.get(field.field)?.invalid\">\n </p-button>\n <p-button \n type=\"button\" \n icon=\"pi pi-times\" \n [rounded]=\"true\"\n severity=\"secondary\"\n (onClick)=\"cancelInlineEdit()\"\n [disabled]=\"savingField\">\n </p-button>\n </div>\n \n <!-- Error Message -->\n <div class=\"field-error\" *ngIf=\"form.get(field.field)?.invalid && form.get(field.field)?.touched\">\n <small class=\"p-error\">\n {{ form.get(field.field)?.errors?.['required'] ? ('crmx.business.required_field' | translate) : '' }}\n </small>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".dynamic-form{width:100%}.dynamic-form .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}.dynamic-form .grid>div.col-1{grid-column:span 1}.dynamic-form .grid>div.col-2{grid-column:span 2}.dynamic-form .grid>div.col-3{grid-column:span 3}.dynamic-form .grid>div.col-4{grid-column:span 4}.dynamic-form .grid>div.col-5{grid-column:span 5}.dynamic-form .grid>div.col-6{grid-column:span 6}.dynamic-form .grid>div.col-7{grid-column:span 7}.dynamic-form .grid>div.col-8{grid-column:span 8}.dynamic-form .grid>div.col-9{grid-column:span 9}.dynamic-form .grid>div.col-10{grid-column:span 10}.dynamic-form .grid>div.col-11{grid-column:span 11}.dynamic-form .grid>div.col-12{grid-column:span 12}@media (max-width: 575.98px){.dynamic-form .grid>div.col-xs-1{grid-column:span 1}.dynamic-form .grid>div.col-xs-2{grid-column:span 2}.dynamic-form .grid>div.col-xs-3{grid-column:span 3}.dynamic-form .grid>div.col-xs-4{grid-column:span 4}.dynamic-form .grid>div.col-xs-5{grid-column:span 5}.dynamic-form .grid>div.col-xs-6{grid-column:span 6}.dynamic-form .grid>div.col-xs-7{grid-column:span 7}.dynamic-form .grid>div.col-xs-8{grid-column:span 8}.dynamic-form .grid>div.col-xs-9{grid-column:span 9}.dynamic-form .grid>div.col-xs-10{grid-column:span 10}.dynamic-form .grid>div.col-xs-11{grid-column:span 11}.dynamic-form .grid>div.col-xs-12{grid-column:span 12}}@media (min-width: 576px){.dynamic-form .grid>div.col-sm-1{grid-column:span 1}.dynamic-form .grid>div.col-sm-2{grid-column:span 2}.dynamic-form .grid>div.col-sm-3{grid-column:span 3}.dynamic-form .grid>div.col-sm-4{grid-column:span 4}.dynamic-form .grid>div.col-sm-5{grid-column:span 5}.dynamic-form .grid>div.col-sm-6{grid-column:span 6}.dynamic-form .grid>div.col-sm-7{grid-column:span 7}.dynamic-form .grid>div.col-sm-8{grid-column:span 8}.dynamic-form .grid>div.col-sm-9{grid-column:span 9}.dynamic-form .grid>div.col-sm-10{grid-column:span 10}.dynamic-form .grid>div.col-sm-11{grid-column:span 11}.dynamic-form .grid>div.col-sm-12{grid-column:span 12}}@media (min-width: 768px){.dynamic-form .grid>div.col-md-1{grid-column:span 1}.dynamic-form .grid>div.col-md-2{grid-column:span 2}.dynamic-form .grid>div.col-md-3{grid-column:span 3}.dynamic-form .grid>div.col-md-4{grid-column:span 4}.dynamic-form .grid>div.col-md-5{grid-column:span 5}.dynamic-form .grid>div.col-md-6{grid-column:span 6}.dynamic-form .grid>div.col-md-7{grid-column:span 7}.dynamic-form .grid>div.col-md-8{grid-column:span 8}.dynamic-form .grid>div.col-md-9{grid-column:span 9}.dynamic-form .grid>div.col-md-10{grid-column:span 10}.dynamic-form .grid>div.col-md-11{grid-column:span 11}.dynamic-form .grid>div.col-md-12{grid-column:span 12}}@media (min-width: 992px){.dynamic-form .grid>div.col-lg-1{grid-column:span 1}.dynamic-form .grid>div.col-lg-2{grid-column:span 2}.dynamic-form .grid>div.col-lg-3{grid-column:span 3}.dynamic-form .grid>div.col-lg-4{grid-column:span 4}.dynamic-form .grid>div.col-lg-5{grid-column:span 5}.dynamic-form .grid>div.col-lg-6{grid-column:span 6}.dynamic-form .grid>div.col-lg-7{grid-column:span 7}.dynamic-form .grid>div.col-lg-8{grid-column:span 8}.dynamic-form .grid>div.col-lg-9{grid-column:span 9}.dynamic-form .grid>div.col-lg-10{grid-column:span 10}.dynamic-form .grid>div.col-lg-11{grid-column:span 11}.dynamic-form .grid>div.col-lg-12{grid-column:span 12}}@media (min-width: 1200px){.dynamic-form .grid>div.col-xl-1{grid-column:span 1}.dynamic-form .grid>div.col-xl-2{grid-column:span 2}.dynamic-form .grid>div.col-xl-3{grid-column:span 3}.dynamic-form .grid>div.col-xl-4{grid-column:span 4}.dynamic-form .grid>div.col-xl-5{grid-column:span 5}.dynamic-form .grid>div.col-xl-6{grid-column:span 6}.dynamic-form .grid>div.col-xl-7{grid-column:span 7}.dynamic-form .grid>div.col-xl-8{grid-column:span 8}.dynamic-form .grid>div.col-xl-9{grid-column:span 9}.dynamic-form .grid>div.col-xl-10{grid-column:span 10}.dynamic-form .grid>div.col-xl-11{grid-column:span 11}.dynamic-form .grid>div.col-xl-12{grid-column:span 12}}.dynamic-form .sections-container{display:flex;flex-direction:column;gap:1rem;margin-top:1rem}.dynamic-form .sections-container ::ng-deep .section-panel .p-panel-header{background-color:var(--surface-50);border-color:var(--surface-200)}.dynamic-form .sections-container ::ng-deep .section-panel .p-panel-header .section-header{display:flex;align-items:center;gap:.5rem;width:100%}.dynamic-form .sections-container ::ng-deep .section-panel .p-panel-header .section-header .section-icon{font-size:1.1rem;color:var(--primary-color)}.dynamic-form .sections-container ::ng-deep .section-panel .p-panel-header .section-header .section-title{font-weight:600;color:var(--text-color)}.dynamic-form .sections-container ::ng-deep .section-panel .p-panel-content{padding:1.5rem}.dynamic-form .fixed-filters-section{margin-bottom:1rem;padding-bottom:1rem;border-bottom:1px solid var(--surface-200)}.dynamic-form .filter-sections-container{display:flex;flex-direction:column;gap:1rem;margin-top:1rem}.dynamic-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--surface-200)}.dialog-footer{display:flex;justify-content:flex-end;gap:.5rem}.drawer-footer{display:flex;justify-content:flex-end;gap:.5rem;padding:1rem;border-top:1px solid var(--surface-200)}.inline-edit-fields{display:flex;flex-direction:column;gap:1rem}.inline-edit-fields .inline-edit-field{display:flex;flex-direction:column;gap:.25rem}.inline-edit-fields .inline-edit-field .field-label{font-weight:500;font-size:.875rem;color:var(--text-color-secondary);margin-bottom:.25rem}.inline-edit-fields .inline-edit-field .field-display{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background-color:var(--surface-50);border:1px solid var(--surface-200);border-radius:var(--border-radius);cursor:pointer;transition:all .2s ease;min-height:42px}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled){background-color:var(--surface-100);border-color:var(--primary-color)}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled) .edit-icon{opacity:1}.inline-edit-fields .inline-edit-field .field-display.disabled{cursor:not-allowed;opacity:.6}.inline-edit-fields .inline-edit-field .field-display .display-value{flex:1;color:var(--text-color)}.inline-edit-fields .inline-edit-field .field-display .display-value:empty:before{content:attr(data-placeholder);color:var(--text-color-secondary);font-style:italic}.inline-edit-fields .inline-edit-field .field-display .edit-icon{color:var(--primary-color);font-size:.875rem;opacity:.5;transition:opacity .2s ease}.inline-edit-fields .inline-edit-field .field-edit{display:flex;flex-direction:column;gap:.5rem}.inline-edit-fields .inline-edit-field .field-edit .input-container{flex:1}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field{gap:0}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field label{display:none}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field small.p-error{display:none}.inline-edit-fields .inline-edit-field .field-edit .edit-actions{display:flex;gap:.5rem;justify-content:flex-end}.inline-edit-fields .inline-edit-field .field-edit .field-error small.p-error{color:var(--p-red-500);font-size:.875rem}\n"] }]
582
+ }], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i2.TranslationService }], propDecorators: { formFields: [{
583
+ type: Input
584
+ }], formSections: [{
585
+ type: Input
586
+ }], fixedFilters: [{
587
+ type: Input
588
+ }], filterSections: [{
589
+ type: Input
590
+ }], entityData: [{
591
+ type: Input
592
+ }], mode: [{
593
+ type: Input
594
+ }], displayMode: [{
595
+ type: Input
596
+ }], visible: [{
597
+ type: Input
598
+ }], dialogConfig: [{
599
+ type: Input
600
+ }], drawerConfig: [{
601
+ type: Input
602
+ }], showSubmitButton: [{
603
+ type: Input
604
+ }], showCancelButton: [{
605
+ type: Input
606
+ }], submitButtonLabel: [{
607
+ type: Input
608
+ }], cancelButtonLabel: [{
609
+ type: Input
610
+ }], submitButtonIcon: [{
611
+ type: Input
612
+ }], cancelButtonIcon: [{
613
+ type: Input
614
+ }], formReady: [{
615
+ type: Output
616
+ }], formSubmit: [{
617
+ type: Output
618
+ }], visibleChange: [{
619
+ type: Output
620
+ }], onCancel: [{
621
+ type: Output
622
+ }], fieldSave: [{
623
+ type: Output
624
+ }] } });
625
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMtYWkvc3JjL2xpYi9jb21wb25lbnRzL2R5bmFtaWMtZm9ybS9keW5hbWljLWZvcm0uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy1haS9zcmMvbGliL2NvbXBvbmVudHMvZHluYW1pYy1mb3JtL2R5bmFtaWMtZm9ybS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUE0QixNQUFNLGVBQWUsQ0FBQztBQUN6RyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUEwQixtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFTOUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzNELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQ2xGLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQ3RGLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQ2xGLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQzFGLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQ3RG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T25Jbml0LCBPdXRwdXQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBQYW5lbE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvcGFuZWwnO1xuaW1wb3J0IHsgRGlhbG9nTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kaWFsb2cnO1xuaW1wb3J0IHsgRHJhd2VyTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kcmF3ZXInO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgXG4gIER5bmFtaWNGb3JtRmllbGRDb25maWcsIFxuICBEeW5hbWljRm9ybVNlY3Rpb24sXG4gIER5bmFtaWNGb3JtRGlzcGxheU1vZGUsXG4gIER5bmFtaWNGb3JtRGlhbG9nQ29uZmlnLFxuICBEeW5hbWljRm9ybURyYXdlckNvbmZpZ1xufSBmcm9tICcuL21vZGVscy9keW5hbWljLWZvcm0ubW9kZWxzJztcbmltcG9ydCB7IFRyYW5zbGF0aW9uU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3RyYW5zbGF0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgVHJhbnNsYXRlUGlwZSB9IGZyb20gJy4uLy4uL3BpcGVzL3RyYW5zbGF0ZS5waXBlJztcbmltcG9ydCB7IER5bmFtaWNGaWVsZFRleHRDb21wb25lbnQgfSBmcm9tICcuL2ZpZWxkcy9keW5hbWljLWZpZWxkLXRleHQuY29tcG9uZW50JztcbmltcG9ydCB7IER5bmFtaWNGaWVsZE51bWJlckNvbXBvbmVudCB9IGZyb20gJy4vZmllbGRzL2R5bmFtaWMtZmllbGQtbnVtYmVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEeW5hbWljRmllbGREYXRlQ29tcG9uZW50IH0gZnJvbSAnLi9maWVsZHMvZHluYW1pYy1maWVsZC1kYXRlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEeW5hbWljRmllbGREcm9wZG93bkNvbXBvbmVudCB9IGZyb20gJy4vZmllbGRzL2R5bmFtaWMtZmllbGQtZHJvcGRvd24uY29tcG9uZW50JztcbmltcG9ydCB7IER5bmFtaWNGaWVsZExvb2t1cENvbXBvbmVudCB9IGZyb20gJy4vZmllbGRzL2R5bmFtaWMtZmllbGQtbG9va3VwLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEeW5hbWljRmllbGRUZXh0YXJlYUNvbXBvbmVudCB9IGZyb20gJy4vZmllbGRzL2R5bmFtaWMtZmllbGQtdGV4dGFyZWEuY29tcG9uZW50JztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc2lhLWR5bmFtaWMtZm9ybScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcbiAgICBQYW5lbE1vZHVsZSxcbiAgICBEaWFsb2dNb2R1bGUsXG4gICAgRHJhd2VyTW9kdWxlLFxuICAgIEJ1dHRvbk1vZHVsZSxcbiAgICBUcmFuc2xhdGVQaXBlLFxuICAgIER5bmFtaWNGaWVsZFRleHRDb21wb25lbnQsXG4gICAgRHluYW1pY0ZpZWxkTnVtYmVyQ29tcG9uZW50LFxuICAgIER5bmFtaWNGaWVsZERhdGVDb21wb25lbnQsXG4gICAgRHluYW1pY0ZpZWxkRHJvcGRvd25Db21wb25lbnQsXG4gICAgRHluYW1pY0ZpZWxkTG9va3VwQ29tcG9uZW50LFxuICAgIER5bmFtaWNGaWVsZFRleHRhcmVhQ29tcG9uZW50XG4gIF0sXG4gIHRlbXBsYXRlVXJsOiAnLi9keW5hbWljLWZvcm0uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vZHluYW1pYy1mb3JtLmNvbXBvbmVudC5zY3NzJ1xufSlcbmV4cG9ydCBjbGFzcyBEeW5hbWljRm9ybUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgZm9ybUZpZWxkczogRHluYW1pY0Zvcm1GaWVsZENvbmZpZ1tdID0gW107XG4gIEBJbnB1dCgpIGZvcm1TZWN0aW9uczogRHluYW1pY0Zvcm1TZWN0aW9uW10gPSBbXTtcbiAgQElucHV0KCkgZml4ZWRGaWx0ZXJzOiBEeW5hbWljRm9ybUZpZWxkQ29uZmlnW10gPSBbXTsgLy8gRmlsdHJvcyBmaXhvcyAoc2VtcHJlIHZpc8OtdmVpcyBubyB0b3BvKVxuICBASW5wdXQoKSBmaWx0ZXJTZWN0aW9uczogRHluYW1pY0Zvcm1TZWN0aW9uW10gPSBbXTsgLy8gU2XDp8O1ZXMgZGUgZmlsdHJvcyAoY29sYXBzw6F2ZWlzKVxuICBASW5wdXQoKSBlbnRpdHlEYXRhOiBhbnkgPSBudWxsO1xuICBASW5wdXQoKSBtb2RlOiAnZm9ybScgfCAnZmlsdGVyJyB8ICdpbmxpbmUtZWRpdCcgPSAnZm9ybSc7XG4gIFxuICAvLyBEaXNwbGF5IE1vZGUgQ29uZmlndXJhdGlvblxuICBASW5wdXQoKSBkaXNwbGF5TW9kZTogRHluYW1pY0Zvcm1EaXNwbGF5TW9kZSA9ICdpbmxpbmUnO1xuICBASW5wdXQoKSB2aXNpYmxlOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGRpYWxvZ0NvbmZpZzogRHluYW1pY0Zvcm1EaWFsb2dDb25maWcgPSB7fTtcbiAgQElucHV0KCkgZHJhd2VyQ29uZmlnOiBEeW5hbWljRm9ybURyYXdlckNvbmZpZyA9IHt9O1xuICBcbiAgLy8gQnV0dG9uIENvbmZpZ3VyYXRpb25cbiAgQElucHV0KCkgc2hvd1N1Ym1pdEJ1dHRvbjogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBzaG93Q2FuY2VsQnV0dG9uOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHN1Ym1pdEJ1dHRvbkxhYmVsPzogc3RyaW5nO1xuICBASW5wdXQoKSBjYW5jZWxCdXR0b25MYWJlbD86IHN0cmluZztcbiAgQElucHV0KCkgc3VibWl0QnV0dG9uSWNvbjogc3RyaW5nID0gJ3BpIHBpLWNoZWNrJztcbiAgQElucHV0KCkgY2FuY2VsQnV0dG9uSWNvbjogc3RyaW5nID0gJ3BpIHBpLXRpbWVzJztcbiAgXG4gIEBPdXRwdXQoKSBmb3JtUmVhZHkgPSBuZXcgRXZlbnRFbWl0dGVyPEZvcm1Hcm91cD4oKTtcbiAgQE91dHB1dCgpIGZvcm1TdWJtaXQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIHZpc2libGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG4gIEBPdXRwdXQoKSBvbkNhbmNlbCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIGZpZWxkU2F2ZSA9IG5ldyBFdmVudEVtaXR0ZXI8eyBmaWVsZDogc3RyaW5nLCB2YWx1ZTogYW55IH0+KCk7XG5cbiAgZm9ybSE6IEZvcm1Hcm91cDtcbiAgbG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xuICBcbiAgLy8gSW5saW5lIGVkaXQgbW9kZSBzdGF0ZVxuICBlZGl0aW5nRmllbGQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBzYXZpbmdGaWVsZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIGdldCBoYXNGaWVsZHMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybUZpZWxkcy5sZW5ndGggPiAwO1xuICB9XG5cbiAgZ2V0IGhhc1NlY3Rpb25zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmZvcm1TZWN0aW9ucy5sZW5ndGggPiAwO1xuICB9XG5cbiAgZ2V0IGhhc0ZpeGVkRmlsdGVycygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5maXhlZEZpbHRlcnMubGVuZ3RoID4gMDtcbiAgfVxuXG4gIGdldCBoYXNGaWx0ZXJTZWN0aW9ucygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5maWx0ZXJTZWN0aW9ucy5sZW5ndGggPiAwO1xuICB9XG5cbiAgZ2V0IGFsbEZpZWxkcygpOiBEeW5hbWljRm9ybUZpZWxkQ29uZmlnW10ge1xuICAgIC8vIFJldG9ybmEgdG9kb3Mgb3MgY2FtcG9zIChkaXJldG9zICsgZGFzIHNlw6fDtWVzICsgZmlsdHJvcyBmaXhvcyArIHNlw6fDtWVzIGRlIGZpbHRyb3MpXG4gICAgY29uc3Qgc2VjdGlvbkZpZWxkcyA9IHRoaXMuZm9ybVNlY3Rpb25zLmZsYXRNYXAoc2VjdGlvbiA9PiBzZWN0aW9uLmZpZWxkcyk7XG4gICAgY29uc3QgZmlsdGVyU2VjdGlvbkZpZWxkcyA9IHRoaXMuZmlsdGVyU2VjdGlvbnMuZmxhdE1hcChzZWN0aW9uID0+IHNlY3Rpb24uZmllbGRzKTtcbiAgICByZXR1cm4gWy4uLnRoaXMuZm9ybUZpZWxkcywgLi4uc2VjdGlvbkZpZWxkcywgLi4udGhpcy5maXhlZEZpbHRlcnMsIC4uLmZpbHRlclNlY3Rpb25GaWVsZHNdO1xuICB9XG5cbiAgZ2V0IGlzSW5saW5lTW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwbGF5TW9kZSA9PT0gJ2lubGluZSc7XG4gIH1cblxuICBnZXQgaXNJbmxpbmVFZGl0TW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlID09PSAnaW5saW5lLWVkaXQnO1xuICB9XG5cbiAgZ2V0IGZpZWxkTW9kZSgpOiAnZm9ybScgfCAnZmlsdGVyJyB7XG4gICAgcmV0dXJuIHRoaXMuaXNJbmxpbmVFZGl0TW9kZSA/ICdmb3JtJyA6IHRoaXMubW9kZSBhcyAnZm9ybScgfCAnZmlsdGVyJztcbiAgfVxuXG4gIGdldCBpc0RpYWxvZ01vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGxheU1vZGUgPT09ICdkaWFsb2cnO1xuICB9XG5cbiAgZ2V0IGlzRHJhd2VyTW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwbGF5TW9kZSA9PT0gJ2RyYXdlcic7XG4gIH1cblxuICAvLyBEaWFsb2cgY29uZmlndXJhdGlvbiB3aXRoIGRlZmF1bHRzXG4gIGdldCBkaWFsb2dIZWFkZXIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5kaWFsb2dDb25maWcuaGVhZGVyIHx8IHRoaXMudHJhbnNsYXRpb25TZXJ2aWNlLnRyYW5zbGF0ZSgnY3JteC5idXNpbmVzcy5mb3JtJyk7XG4gIH1cblxuICBnZXQgZGlhbG9nV2lkdGgoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5kaWFsb2dDb25maWcud2lkdGggfHwgJzYwMHB4JztcbiAgfVxuXG4gIGdldCBkaWFsb2dEcmFnZ2FibGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZGlhbG9nQ29uZmlnLmRyYWdnYWJsZSAhPT0gdW5kZWZpbmVkID8gdGhpcy5kaWFsb2dDb25maWcuZHJhZ2dhYmxlIDogZmFsc2U7XG4gIH1cblxuICBnZXQgZGlhbG9nUmVzaXphYmxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmRpYWxvZ0NvbmZpZy5yZXNpemFibGUgIT09IHVuZGVmaW5lZCA/IHRoaXMuZGlhbG9nQ29uZmlnLnJlc2l6YWJsZSA6IGZhbHNlO1xuICB9XG5cbiAgZ2V0IGRpYWxvZ01heGltaXphYmxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmRpYWxvZ0NvbmZpZy5tYXhpbWl6YWJsZSAhPT0gdW5kZWZpbmVkID8gdGhpcy5kaWFsb2dDb25maWcubWF4aW1pemFibGUgOiBmYWxzZTtcbiAgfVxuXG4gIGdldCBkaWFsb2dDbG9zZU9uRXNjYXBlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmRpYWxvZ0NvbmZpZy5jbG9zZU9uRXNjYXBlICE9PSB1bmRlZmluZWQgPyB0aGlzLmRpYWxvZ0NvbmZpZy5jbG9zZU9uRXNjYXBlIDogdHJ1ZTtcbiAgfVxuXG4gIGdldCBkaWFsb2dEaXNtaXNzYWJsZU1hc2soKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZGlhbG9nQ29uZmlnLmRpc21pc3NhYmxlTWFzayAhPT0gdW5kZWZpbmVkID8gdGhpcy5kaWFsb2dDb25maWcuZGlzbWlzc2FibGVNYXNrIDogZmFsc2U7XG4gIH1cblxuICAvLyBEcmF3ZXIgY29uZmlndXJhdGlvbiB3aXRoIGRlZmF1bHRzXG4gIGdldCBkcmF3ZXJIZWFkZXIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5kcmF3ZXJDb25maWcuaGVhZGVyIHx8IHRoaXMudHJhbnNsYXRpb25TZXJ2aWNlLnRyYW5zbGF0ZSgnY3JteC5idXNpbmVzcy5mb3JtJyk7XG4gIH1cblxuICBnZXQgZHJhd2VyUG9zaXRpb24oKTogJ2xlZnQnIHwgJ3JpZ2h0JyB8ICd0b3AnIHwgJ2JvdHRvbScge1xuICAgIHJldHVybiB0aGlzLmRyYXdlckNvbmZpZy5wb3NpdGlvbiB8fCAncmlnaHQnO1xuICB9XG5cbiAgZ2V0IGRyYXdlclNob3dDbG9zZUljb24oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZHJhd2VyQ29uZmlnLnNob3dDbG9zZUljb24gIT09IHVuZGVmaW5lZCA/IHRoaXMuZHJhd2VyQ29uZmlnLnNob3dDbG9zZUljb24gOiB0cnVlO1xuICB9XG5cbiAgZ2V0IGRyYXdlckNsb3NlT25Fc2NhcGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZHJhd2VyQ29uZmlnLmNsb3NlT25Fc2NhcGUgIT09IHVuZGVmaW5lZCA/IHRoaXMuZHJhd2VyQ29uZmlnLmNsb3NlT25Fc2NhcGUgOiB0cnVlO1xuICB9XG5cbiAgZ2V0IGRyYXdlckRpc21pc3NhYmxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmRyYXdlckNvbmZpZy5kaXNtaXNzYWJsZSAhPT0gdW5kZWZpbmVkID8gdGhpcy5kcmF3ZXJDb25maWcuZGlzbWlzc2FibGUgOiB0cnVlO1xuICB9XG5cbiAgZ2V0IGRyYXdlclN0eWxlKCk6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5kcmF3ZXJQb3NpdGlvbjtcbiAgICBjb25zdCBpc0hvcml6b250YWwgPSBwb3NpdGlvbiA9PT0gJ2xlZnQnIHx8IHBvc2l0aW9uID09PSAncmlnaHQnO1xuICAgIFxuICAgIC8vIFNlIHRlbSBjdXN0b21XaWR0aCwgdXNhIGVsYVxuICAgIGlmICh0aGlzLmRyYXdlckNvbmZpZy5jdXN0b21XaWR0aCkge1xuICAgICAgcmV0dXJuIGlzSG9yaXpvbnRhbCBcbiAgICAgICAgPyB7IHdpZHRoOiB0aGlzLmRyYXdlckNvbmZpZy5jdXN0b21XaWR0aCB9XG4gICAgICAgIDogeyBoZWlnaHQ6IHRoaXMuZHJhd2VyQ29uZmlnLmN1c3RvbVdpZHRoIH07XG4gICAgfVxuICAgIFxuICAgIC8vIFVzYSBvIHRhbWFuaG8gcGFkcm9uaXphZG9cbiAgICBjb25zdCBzaXplID0gdGhpcy5kcmF3ZXJDb25maWcuc2l6ZSB8fCAnbWVkaXVtJztcbiAgICBjb25zdCBzaXplTWFwID0ge1xuICAgICAgJ3NtYWxsJzogaXNIb3Jpem9udGFsID8gJzI1JScgOiAnMjV2aCcsXG4gICAgICAnbWVkaXVtJzogaXNIb3Jpem9udGFsID8gJzQwJScgOiAnNDB2aCcsXG4gICAgICAnbGFyZ2UnOiBpc0hvcml6b250YWwgPyAnNjAlJyA6ICc2MHZoJyxcbiAgICAgICd4bGFyZ2UnOiBpc0hvcml6b250YWwgPyAnODAlJyA6ICc4MHZoJyxcbiAgICAgICdmdWxsJzogaXNIb3Jpem9udGFsID8gJzEwMCUnIDogJzEwMHZoJ1xuICAgIH07XG4gICAgXG4gICAgY29uc3Qgc2l6ZVZhbHVlID0gc2l6ZU1hcFtzaXplXTtcbiAgICByZXR1cm4gaXNIb3Jpem9udGFsIFxuICAgICAgPyB7IHdpZHRoOiBzaXplVmFsdWUgfVxuICAgICAgOiB7IGhlaWdodDogc2l6ZVZhbHVlIH07XG4gIH1cblxuICBnZXQgc3VibWl0TGFiZWwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5zdWJtaXRCdXR0b25MYWJlbCB8fCB0aGlzLnRyYW5zbGF0aW9uU2VydmljZS50cmFuc2xhdGUoJ2NybXguYnVzaW5lc3Muc2F2ZScpO1xuICB9XG5cbiAgZ2V0IGNhbmNlbExhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY2FuY2VsQnV0dG9uTGFiZWwgfHwgdGhpcy50cmFuc2xhdGlvblNlcnZpY2UudHJhbnNsYXRlKCdjcm14LmJ1c2luZXNzLmNhbmNlbCcpO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGlvblNlcnZpY2U6IFRyYW5zbGF0aW9uU2VydmljZVxuICApIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5pbml0Rm9ybSgpO1xuICAgIHRoaXMuc2V0dXBDb25kaXRpb25hbEZpZWxkc1dhdGNoZXIoKTtcbiAgICB0aGlzLmZvcm1SZWFkeS5lbWl0KHRoaXMuZm9ybSk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbJ2VudGl0eURhdGEnXSAmJiB0aGlzLmZvcm0pIHtcbiAgICAgIGlmICh0aGlzLmVudGl0eURhdGEpIHtcbiAgICAgICAgdGhpcy5sb2FkRW50aXR5RGF0YSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZXNldEZvcm0oKTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLy8gUmVzZXQgbG9hZGluZyBhbmQgZm9ybSB3aGVuIGRpYWxvZy9kcmF3ZXIgaXMgb3BlbmVkXG4gICAgaWYgKGNoYW5nZXNbJ3Zpc2libGUnXSAmJiBjaGFuZ2VzWyd2aXNpYmxlJ10uY3VycmVudFZhbHVlID09PSB0cnVlKSB7XG4gICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgIFxuICAgICAgLy8gSWYgb3BlbmluZyB3aXRob3V0IGVudGl0eURhdGEgKG5ldyByZWNvcmQpLCByZXNldCBmb3JtXG4gICAgICBpZiAoIXRoaXMuZW50aXR5RGF0YSAmJiB0aGlzLmZvcm0pIHtcbiAgICAgICAgdGhpcy5yZXNldEZvcm0oKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpbml0Rm9ybSgpOiB2b2lkIHtcbiAgICBjb25zdCBmb3JtQ29udHJvbHM6IGFueSA9IHt9O1xuICAgIFxuICAgIC8vIFByb2Nlc3NhIHRvZG9zIG9zIGNhbXBvcyAoZGlyZXRvcyArIGRhcyBzZcOnw7VlcylcbiAgICB0aGlzLmFsbEZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IHRoaXMuZ2V0RGVmYXVsdFZhbHVlKGZpZWxkKTtcbiAgICAgIGNvbnN0IHZhbGlkYXRvcnMgPSB0aGlzLm1vZGUgPT09ICdmaWx0ZXInID8gW10gOiAoZmllbGQudmFsaWRhdG9ycyB8fCBbXSk7XG4gICAgICBcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLmZiLmNvbnRyb2woXG4gICAgICAgIHsgdmFsdWU6IGRlZmF1bHRWYWx1ZSwgZGlzYWJsZWQ6IGZpZWxkLmRpc2FibGVkIHx8IGZhbHNlIH0sXG4gICAgICAgIHZhbGlkYXRvcnNcbiAgICAgICk7XG4gICAgICBcbiAgICAgIGZvcm1Db250cm9sc1tmaWVsZC5maWVsZF0gPSBjb250cm9sO1xuICAgIH0pO1xuICAgIFxuICAgIHRoaXMuZm9ybSA9IHRoaXMuZmIuZ3JvdXAoZm9ybUNvbnRyb2xzKTtcbiAgICB0aGlzLmFwcGx5SW5pdGlhbERpc2FibGVkU3RhdGUoKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RGVmYXVsdFZhbHVlKGZpZWxkOiBEeW5hbWljRm9ybUZpZWxkQ29uZmlnKTogYW55IHtcbiAgICBpZiAoZmllbGQuZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmaWVsZC5kZWZhdWx0VmFsdWU7XG4gICAgfVxuXG4gICAgc3dpdGNoIChmaWVsZC50eXBlKSB7XG4gICAgICBjYXNlICdudW1iZXInOlxuICAgICAgY2FzZSAnZGF0ZSc6XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgY2FzZSAnZHJvcGRvd24nOlxuICAgICAgY2FzZSAnZW51bSc6XG4gICAgICAgIHJldHVybiB0aGlzLm1vZGUgPT09ICdmaWx0ZXInID8gbnVsbCA6ICcnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlJbml0aWFsRGlzYWJsZWRTdGF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLmFsbEZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgIGlmIChmaWVsZC5kaXNhYmxlZFdoZW4pIHtcbiAgICAgICAgY29uc3QgY29udHJvbCA9IHRoaXMuZm9ybS5nZXQoZmllbGQuZmllbGQpO1xuICAgICAgICBpZiAoY29udHJvbCAmJiB0aGlzLmlzRmllbGREaXNhYmxlZChmaWVsZCkpIHtcbiAgICAgICAgICBjb250cm9sLmRpc2FibGUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgbG9hZEVudGl0eURhdGEoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZW50aXR5RGF0YSAmJiB0aGlzLmZvcm0pIHtcbiAgICAgIGNvbnN0IHByb2Nlc3NlZERhdGEgPSB0aGlzLnByb2Nlc3NFbnRpdHlEYXRhKHRoaXMuZW50aXR5RGF0YSk7XG4gICAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZShwcm9jZXNzZWREYXRhKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NFbnRpdHlEYXRhKGVudGl0eTogYW55KTogYW55IHtcbiAgICBjb25zdCBwcm9jZXNzZWREYXRhID0geyAuLi5lbnRpdHkgfTtcbiAgICBcbiAgICB0aGlzLmFsbEZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgIGlmIChmaWVsZC50eXBlID09PSAnbG9va3VwJyAmJiBwcm9jZXNzZWREYXRhW2ZpZWxkLmZpZWxkXSkge1xuICAgICAgICBjb25zdCBsb29rdXBWYWx1ZSA9IHByb2Nlc3NlZERhdGFbZmllbGQuZmllbGRdO1xuICAgICAgICAvLyBLZWVwIHRoZSBmdWxsIG9iamVjdCBpZiBpdCBoYXMgZGlzcGxheSBkYXRhLCBvdGhlcndpc2UgZXh0cmFjdCBJRFxuICAgICAgICBpZiAodHlwZW9mIGxvb2t1cFZhbHVlID09PSAnb2JqZWN0JyAmJiBsb29rdXBWYWx1ZS5pZCkge1xuICAgICAgICAgIGNvbnN0IGhhc0Rpc3BsYXlEYXRhID0gZmllbGQubG9va3VwRGlzcGxheUZpZWxkcyBcbiAgICAgICAgICAgID8gZmllbGQubG9va3VwRGlzcGxheUZpZWxkcy5zb21lKGYgPT4gdGhpcy5nZXROZXN0ZWRWYWx1ZShsb29rdXBWYWx1ZSwgZikpXG4gICAgICAgICAgICA6IGxvb2t1cFZhbHVlW2ZpZWxkLmxvb2t1cERpc3BsYXlGaWVsZCB8fCAnbmFtZSddO1xuICAgICAgICAgIFxuICAgICAgICAgIGlmIChoYXNEaXNwbGF5RGF0YSkge1xuICAgICAgICAgICAgLy8gS2VlcCB0aGUgZnVsbCBvYmplY3QgdG8gYXZvaWQgdW5uZWNlc3NhcnkgQVBJIGNhbGxzXG4gICAgICAgICAgICBwcm9jZXNzZWREYXRhW2ZpZWxkLmZpZWxkXSA9IGxvb2t1cFZhbHVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPbmx5IGhhcyBJRCwgZXh0cmFjdCBpdFxuICAgICAgICAgICAgcHJvY2Vzc2VkRGF0YVtmaWVsZC5maWVsZF0gPSBsb29rdXBWYWx1ZS5pZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICByZXR1cm4gcHJvY2Vzc2VkRGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TmVzdGVkVmFsdWUob2JqOiBhbnksIHBhdGg6IHN0cmluZyk6IGFueSB7XG4gICAgcmV0dXJuIHBhdGguc3BsaXQoJy4nKS5yZWR1Y2UoKGN1cnJlbnQsIGtleSkgPT4gY3VycmVudD8uW2tleV0sIG9iaik7XG4gIH1cblxuICByZXNldEZvcm0oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZm9ybSkge1xuICAgICAgY29uc3QgcmVzZXRWYWx1ZXM6IGFueSA9IHt9O1xuICAgICAgdGhpcy5hbGxGaWVsZHMuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICAgIHJlc2V0VmFsdWVzW2ZpZWxkLmZpZWxkXSA9IHRoaXMuZ2V0RGVmYXVsdFZhbHVlKGZpZWxkKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5mb3JtLnJlc2V0KHJlc2V0VmFsdWVzKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NGaWx0ZXJWYWx1ZShmb3JtVmFsdWU6IGFueSk6IGFueSB7XG4gICAgY29uc3QgcHJvY2Vzc2VkVmFsdWUgPSB7IC4uLmZvcm1WYWx1ZSB9O1xuICAgIFxuICAgIHRoaXMuYWxsRmllbGRzLmZvckVhY2goZmllbGQgPT4ge1xuICAgICAgY29uc3QgZmllbGRWYWx1ZSA9IHByb2Nlc3NlZFZhbHVlW2ZpZWxkLmZpZWxkXTtcbiAgICAgIFxuICAgICAgaWYgKGZpZWxkLnR5cGUgPT09ICdsb29rdXAnKSB7XG4gICAgICAgIGlmIChmaWVsZFZhbHVlICYmIHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0JyAmJiBmaWVsZFZhbHVlLmlkKSB7XG4gICAgICAgICAgcHJvY2Vzc2VkVmFsdWVbZmllbGQuZmllbGRdID0gZmllbGRWYWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlICYmIHR5cGVvZiBmaWVsZFZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHByb2Nlc3NlZFZhbHVlW2ZpZWxkLmZpZWxkXSA9IHsgaWQ6IGZpZWxkVmFsdWUgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcm9jZXNzZWRWYWx1ZVtmaWVsZC5maWVsZF0gPSBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgXG4gICAgcmV0dXJuIHByb2Nlc3NlZFZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzRm9ybVZhbHVlKGZvcm1WYWx1ZTogYW55KTogYW55IHtcbiAgICBjb25zdCBwcm9jZXNzZWRWYWx1ZSA9IHsgLi4uZm9ybVZhbHVlIH07XG4gICAgXG4gICAgaWYgKHRoaXMuZW50aXR5RGF0YT8uaWQpIHtcbiAgICAgIHByb2Nlc3NlZFZhbHVlLmlkID0gdGhpcy5lbnRpdHlEYXRhLmlkO1xuICAgIH1cbiAgICBcbiAgICB0aGlzLmFsbEZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkVmFsdWUgPSBwcm9jZXNzZWRWYWx1ZVtmaWVsZC5maWVsZF07XG4gICAgICBcbiAgICAgIGlmIChmaWVsZC50eXBlID09PSAnbG9va3VwJykge1xuICAgICAgICAvLyBJZiBpdCdzIGFuIG9iamVjdCwgZXh0cmFjdCB0aGUgSURcbiAgICAgICAgaWYgKGZpZWxkVmFsdWUgJiYgdHlwZW9mIGZpZWxkVmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgcHJvY2Vzc2VkVmFsdWVbZmllbGQuZmllbGRdID0gZmllbGRWYWx1ZS5pZCB8fCBmaWVsZFZhbHVlW2ZpZWxkLmxvb2t1cFZhbHVlRmllbGQgfHwgJ2lkJ10gfHwgbnVsbDtcbiAgICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlICYmIGZpZWxkVmFsdWUgIT09ICcnKSB7XG4gICAgICAgICAgLy8gSWYgaXQncyBhbHJlYWR5IGFuIElELCBrZWVwIGl0XG4gICAgICAgICAgcHJvY2Vzc2VkVmFsdWVbZmllbGQuZmllbGRdID0geyBpZDogZmllbGRWYWx1ZSB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByb2Nlc3NlZFZhbHVlW2ZpZWxkLmZpZWxkXSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZmllbGQudHlwZSA9PT0gJ2RhdGUnKSB7XG4gICAgICAgIGlmIChmaWVsZFZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgIHByb2Nlc3NlZFZhbHVlW2ZpZWxkLmZpZWxkXSA9IGZpZWxkVmFsdWUudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdO1xuICAgICAgICB9IGVsc2UgaWYgKCFmaWVsZFZhbHVlKSB7XG4gICAgICAgICAgcHJvY2Vzc2VkVmFsdWVbZmllbGQuZmllbGRdID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChbJ3RleHQnLCAndGV4dGFyZWEnLCAnbnVtYmVyJywgJ2VudW0nLCAnZHJvcGRvd24nXS5pbmNsdWRlcyhmaWVsZC50eXBlKSkge1xuICAgICAgICBpZiAoZmllbGRWYWx1ZSA9PT0gJycgfHwgZmllbGRWYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcHJvY2Vzc2VkVmFsdWVbZmllbGQuZmllbGRdID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIFxuICAgIHJldHVybiBwcm9jZXNzZWRWYWx1ZTtcbiAgfVxuXG4gIGdldEZpZWxkR3JpZENsYXNzKGZpZWxkOiBEeW5hbWljRm9ybUZpZWxkQ29uZmlnKTogc3RyaW5nIHtcbiAgICBjb25zdCBjbGFzc2VzOiBzdHJpbmdbXSA9IFtdO1xuICAgIFxuICAgIC8vIENvbHNwYW4gYmFzZSAocGFkcsOjbzogNilcbiAgICBsZXQgYmFzZUNvbHNwYW4gPSBmaWVsZC5jb2xzcGFuIHx8IDY7XG4gICAgXG4gICAgLy8gVmVyaWZpY2EgY29uZGnDp8O1ZXMgZGUgY29sc3BhbiBkaW7Dom1pY29cbiAgICBpZiAoZmllbGQuY29sc3BhbldoZW4gJiYgZmllbGQuY29sc3BhbldoZW4ubGVuZ3RoID4gMCkge1xuICAgICAgZm9yIChjb25zdCBjb25kaXRpb24gb2YgZmllbGQuY29sc3BhbldoZW4pIHtcbiAgICAgICAgY29uc3QgZGVwZW5kZW50RmllbGRWYWx1ZSA9IHRoaXMuZm9ybS5nZXQoY29uZGl0aW9uLmZpZWxkKT8udmFsdWU7XG4gICAgICAgIGlmIChkZXBlbmRlbnRGaWVsZFZhbHVlID09PSBjb25kaXRpb24udmFsdWUpIHtcbiAgICAgICAgICBiYXNlQ29sc3BhbiA9IGNvbmRpdGlvbi5jb2xzcGFuO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIC8vIEFkaWNpb25hIGNsYXNzZSBiYXNlXG4gICAgY2xhc3Nlcy5wdXNoKGBjb2wtJHtiYXNlQ29sc3Bhbn1gKTtcbiAgICBcbiAgICAvLyBTdXBvcnRhIHRhbnRvIG8gb2JqZXRvIHNpemUgcXVhbnRvIGFzIHByb3ByaWVkYWRlcyBhbnRpZ2FzIChwYXJhIGNvbXBhdGliaWxpZGFkZSlcbiAgICBjb25zdCBzaXplWHMgPSBmaWVsZC5zaXplPy54cyA/PyBmaWVsZC5jb2xzcGFuWHM7XG4gICAgY29uc3Qgc2l6ZVNtID0gZmllbGQuc2l6ZT8uc20gPz8gZmllbGQuY29sc3BhblNtO1xuICAgIGNvbnN0IHNpemVNZCA9IGZpZWxkLnNpemU/Lm1kID8/IGZpZWxkLmNvbHNwYW5NZDtcbiAgICBjb25zdCBzaXplTGcgPSBmaWVsZC5zaXplPy5sZyA/PyBmaWVsZC5jb2xzcGFuTGc7XG4gICAgY29uc3Qgc2l6ZVhsID0gZmllbGQuc2l6ZT8ueGwgPz8gZmllbGQuY29sc3BhblhsO1xuICAgIFxuICAgIC8vIEFkaWNpb25hIGNsYXNzZXMgcmVzcG9uc2l2YXMgc2UgZGVmaW5pZGFzXG4gICAgaWYgKHNpemVYcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjbGFzc2VzLnB1c2goYGNvbC14cy0ke3NpemVYc31gKTtcbiAgICB9XG4gICAgaWYgKHNpemVTbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjbGFzc2VzLnB1c2goYGNvbC1zbS0ke3NpemVTbX1gKTtcbiAgICB9XG4gICAgaWYgKHNpemVNZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjbGFzc2VzLnB1c2goYGNvbC1tZC0ke3NpemVNZH1gKTtcbiAgICB9XG4gICAgaWYgKHNpemVMZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjbGFzc2VzLnB1c2goYGNvbC1sZy0ke3NpemVMZ31gKTtcbiAgICB9XG4gICAgaWYgKHNpemVYbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjbGFzc2VzLnB1c2goYGNvbC14bC0ke3NpemVYbH1gKTtcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIGNsYXNzZXMuam9pbignICcpO1xuICB9XG5cbiAgaXNGaWVsZFZpc2libGUoZmllbGQ6IER5bmFtaWNGb3JtRmllbGRDb25maWcpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5tb2RlID09PSAnZmlsdGVyJykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIFxuICAgIGlmICghZmllbGQudmlzaWJsZVdoZW4pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGRlcGVuZGVudEZpZWxkVmFsdWUgPSB0aGlzLmZvcm0uZ2V0KGZpZWxkLnZpc2libGVXaGVuLmZpZWxkKT8udmFsdWU7XG4gICAgcmV0dXJuIGRlcGVuZGVudEZpZWxkVmFsdWUgPT09IGZpZWxkLnZpc2libGVXaGVuLnZhbHVlO1xuICB9XG5cbiAgaXNGaWVsZERpc2FibGVkKGZpZWxkOiBEeW5hbWljRm9ybUZpZWxkQ29uZmlnKTogYm9vbGVhbiB7XG4gICAgaWYgKGZpZWxkLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgXG4gICAgaWYgKCEoJ2Rpc2FibGVkV2hlbicgaW4gZmllbGQpIHx8ICFmaWVsZC5kaXNhYmxlZFdoZW4pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBkZXBlbmRlbnRGaWVsZFZhbHVlID0gdGhpcy5mb3JtLmdldChmaWVsZC5kaXNhYmxlZFdoZW4hLmZpZWxkKT8udmFsdWU7XG4gICAgXG4gICAgaWYgKGZpZWxkLmRpc2FibGVkV2hlbiEudmFsdWUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiAhZGVwZW5kZW50RmllbGRWYWx1ZTtcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIGRlcGVuZGVudEZpZWxkVmFsdWUgPT09IGZpZWxkLmRpc2FibGVkV2hlbiEudmFsdWU7XG4gIH1cblxuICBzZXR1cENvbmRpdGlvbmFsRmllbGRzV2F0Y2hlcigpOiB2b2lkIHtcbiAgICBjb25zdCB2aXNpYmxlRGVwZW5kZW50RmllbGRzID0gdGhpcy5hbGxGaWVsZHMuZmlsdGVyKGZpZWxkID0+IGZpZWxkLnZpc2libGVXaGVuKTtcbiAgICBjb25zdCB2aXNpYmxlV2F0Y2hlZEZpZWxkcyA9IFsuLi5uZXcgU2V0KHZpc2libGVEZXBlbmRlbnRGaWVsZHMubWFwKGZpZWxkID0+IGZpZWxkLnZpc2libGVXaGVuIS5maWVsZCkpXTtcblxuICAgIGNvbnN0IGRpc2FibGVkRGVwZW5kZW50RmllbGRzID0gdGhpcy5hbGxGaWVsZHMuZmlsdGVyKGZpZWxkID0+IGZpZWxkLmRpc2FibGVkV2hlbik7XG4gICAgY29uc3QgZGlzYWJsZWRXYXRjaGVkRmllbGRzID0gWy4uLm5ldyBTZXQoZGlzYWJsZWREZXBlbmRlbnRGaWVsZHMubWFwKGZpZWxkID0+IGZpZWxkLmRpc2FibGVkV2hlbiEuZmllbGQpKV07XG5cbiAgICBjb25zdCBhbGxXYXRjaGVkRmllbGRzID0gWy4uLm5ldyBTZXQoWy4uLnZpc2libGVXYXRjaGVkRmllbGRzLCAuLi5kaXNhYmxlZFdhdGNoZWRGaWVsZHNdKV07XG5cbiAgICBhbGxXYXRjaGVkRmllbGRzLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLmZvcm0uZ2V0KGZpZWxkTmFtZSk7XG4gICAgICBpZiAoY29udHJvbCkge1xuICAgICAgICBjb250cm9sLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuY2xlYXJIaWRkZW5GaWVsZHMoKTtcbiAgICAgICAgICB0aGlzLnVwZGF0ZURpc2FibGVkRmllbGRzKCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlRGlzYWJsZWRGaWVsZHMoKTogdm9pZCB7XG4gICAgdGhpcy5hbGxGaWVsZHMuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICBpZiAoZmllbGQuZGlzYWJsZWRXaGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLmZvcm0uZ2V0KGZpZWxkLmZpZWxkKTtcbiAgICAgICAgaWYgKGNvbnRyb2wpIHtcbiAgICAgICAgICBjb25zdCBzaG91bGRCZURpc2FibGVkID0gdGhpcy5pc0ZpZWxkRGlzYWJsZWQoZmllbGQpO1xuICAgICAgICAgIFxuICAgICAgICAgIGlmIChzaG91bGRCZURpc2FibGVkICYmIGNvbnRyb2wuZW5hYmxlZCkge1xuICAgICAgICAgICAgY29udHJvbC5zZXRWYWx1ZShudWxsKTtcbiAgICAgICAgICAgIGNvbnRyb2wuZGlzYWJsZSgpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIXNob3VsZEJlRGlzYWJsZWQgJiYgY29udHJvbC5kaXNhYmxlZCAmJiAhZmllbGQuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIGNvbnRyb2wuZW5hYmxlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBjbGVhckhpZGRlbkZpZWxkcygpOiB2b2lkIHtcbiAgICB0aGlzLmFsbEZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgIGlmIChmaWVsZC52aXNpYmxlV2hlbiAmJiAhdGhpcy5pc0ZpZWxkVmlzaWJsZShmaWVsZCkpIHtcbiAgICAgICAgY29uc3QgY29udHJvbCA9IHRoaXMuZm9ybS5nZXQoZmllbGQuZmllbGQpO1xuICAgICAgICBpZiAoY29udHJvbCkge1xuICAgICAgICAgIGNvbnN0IHJlc2V0VmFsdWUgPSB0aGlzLmdldERlZmF1bHRWYWx1ZShmaWVsZCk7XG4gICAgICAgICAgY29udHJvbC5zZXRWYWx1ZShyZXNldFZhbHVlKTtcbiAgICAgICAgICBjb250cm9sLm1hcmtBc1VudG91Y2hlZCgpO1xuICAgICAgICAgIGNvbnRyb2wubWFya0FzUHJpc3RpbmUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZ2V0Rm9ybSgpOiBGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmZvcm07XG4gIH1cblxuICBjbGVhckZpbHRlcnMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2ZpbHRlcicpIHtcbiAgICAgIHRoaXMucmVzZXRGb3JtKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0VHlwZVBlcnNvblZhbHVlKCk6ICdOQVRVUkFMX1BFUlNPTicgfCAnSlVSSURJQ0FMX1BFUlNPTicge1xuICAgIGNvbnN0IHR5cGVQZXJzb25WYWx1ZSA9IHRoaXMuZm9ybT8uZ2V0KCd0eXBlUGVyc29uJyk/LnZhbHVlO1xuICAgIHJldHVybiB0eXBlUGVyc29uVmFsdWUgfHwgJ0pVUklESUNBTF9QRVJTT04nO1xuICB9XG5cbiAgLy8gRGlzcGxheSBNb2RlIENvbnRyb2wgTWV0aG9kc1xuICBvcGVuKGVudGl0eT86IGFueSk6IHZvaWQge1xuICAgIGlmIChlbnRpdHkpIHtcbiAgICAgIHRoaXMuZW50aXR5RGF0YSA9IGVudGl0eTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbnRpdHlEYXRhID0gbnVsbDtcbiAgICAgIHRoaXMucmVzZXRGb3JtKCk7IC8vIFJlc2V0IGZvcm0gd2hlbiBvcGVuaW5nIGZvciBuZXcgZW50aXR5XG4gICAgfVxuICAgIHRoaXMubG9hZGluZyA9IGZhbHNlOyAvLyBSZXNldCBsb2FkaW5nIHN0YXRlXG4gICAgdGhpcy52aXNpYmxlID0gdHJ1ZTtcbiAgICB0aGlzLnZpc2libGVDaGFuZ2UuZW1pdCh0cnVlKTtcbiAgfVxuXG4gIGNsb3NlKCk6IHZvaWQge1xuICAgIHRoaXMubG9hZGluZyA9IGZhbHNlOyAvLyBSZXNldCBsb2FkaW5nIHN0YXRlXG4gICAgdGhpcy52aXNpYmxlID0gZmFsc2U7XG4gICAgdGhpcy52aXNpYmxlQ2hhbmdlLmVtaXQoZmFsc2UpO1xuICAgIHRoaXMucmVzZXRGb3JtKCk7IC8vIFJlc2V0IGZvcm0gd2hlbiBjbG9zaW5nXG4gICAgdGhpcy5vbkNhbmNlbC5lbWl0KCk7XG4gIH1cblxuICBoYW5kbGVDYW5jZWwoKTogdm9pZCB7XG4gICAgdGhpcy5jbG9zZSgpO1xuICB9XG5cbiAgaGFuZGxlU3VibWl0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1vZGUgPT09ICdmb3JtJyAmJiB0aGlzLmZvcm0uaW52YWxpZCkge1xuICAgICAgdGhpcy5mb3JtLm1hcmtBbGxBc1RvdWNoZWQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgXG4gICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcbiAgICBcbiAgICBjb25zdCBmb3JtVmFsdWUgPSB0aGlzLm1vZGUgPT09ICdmaWx0ZXInIFxuICAgICAgPyB0aGlzLnByb2Nlc3NGaWx0ZXJWYWx1ZSh0aGlzLmZvcm0udmFsdWUpXG4gICAgICA6IHRoaXMucHJvY2Vzc0Zvcm1WYWx1ZSh0aGlzLmZvcm0udmFsdWUpO1xuICAgIFxuICAgIHRoaXMuZm9ybVN1Ym1pdC5lbWl0KGZvcm1WYWx1ZSk7XG4gIH1cblxuICAvLyBJbmxpbmUgRWRpdCBNb2RlIE1ldGhvZHNcbiAgc3RhcnRFZGl0RmllbGQoZmllbGROYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0lubGluZUVkaXRNb2RlKSB7XG4gICAgICB0aGlzLmVkaXRpbmdGaWVsZCA9IGZpZWxkTmFtZTtcbiAgICAgIFxuICAgICAgLy8gRW5zdXJlIHRoZSBmaWVsZCBoYXMgdGhlIGN1cnJlbnQgdmFsdWUgZnJvbSBlbnRpdHlEYXRhXG4gICAgICBpZiAodGhpcy5lbnRpdHlEYXRhKSB7XG4gICAgICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLmZvcm0uZ2V0KGZpZWxkTmFtZSk7XG4gICAgICAgIGlmIChjb250cm9sKSB7XG4gICAgICAgICAgY29uc3QgZmllbGQgPSB0aGlzLmFsbEZpZWxkcy5maW5kKGYgPT4gZi5maWVsZCA9PT0gZmllbGROYW1lKTtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZW50aXR5RGF0YVtmaWVsZE5hbWVdO1xuICAgICAgICAgIFxuICAgICAgICAgIC8vIEZvciBsb29rdXAgZmllbGRzIGluIGlubGluZS1lZGl0IG1vZGUsIGtlZXAgdGhlIGZ1bGwgb2JqZWN0XG4gICAgICAgICAgLy8gVGhpcyBwcmV2ZW50cyB1bm5lY2Vzc2FyeSBBUEkgY2FsbHMgc2luY2Ugd2UgYWxyZWFkeSBoYXZlIHRoZSBkYXRhXG4gICAgICAgICAgaWYgKGZpZWxkPy50eXBlID09PSAnbG9va3VwJyAmJiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAvLyBLZWVwIHRoZSBmdWxsIG9iamVjdCAtIHRoZSBsb29rdXAgY29tcG9uZW50IHdpbGwgdXNlIGl0XG4gICAgICAgICAgICBjb250cm9sLnNldFZhbHVlKHZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udHJvbC5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaXNGaWVsZEVkaXRpbmcoZmllbGROYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lZGl0aW5nRmllbGQgPT09IGZpZWxkTmFtZTtcbiAgfVxuXG4gIHNhdmVJbmxpbmVGaWVsZChmaWVsZE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc0lubGluZUVkaXRNb2RlKSByZXR1cm47XG5cbiAgICBjb25zdCBjb250cm9sID0gdGhpcy5mb3JtLmdldChmaWVsZE5hbWUpO1xuICAgIGlmICghY29udHJvbCB8fCBjb250cm9sLmludmFsaWQpIHtcbiAgICAgIGNvbnRyb2w/Lm1hcmtBc1RvdWNoZWQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNhdmluZ0ZpZWxkID0gdHJ1ZTtcbiAgICBcbiAgICBsZXQgZmllbGRWYWx1ZSA9IGNvbnRyb2wudmFsdWU7XG4gICAgXG4gICAgLy8gRm9yIGxvb2t1cCBmaWVsZHMsIGV4dHJhY3QgdGhlIElEIGlmIGl0J3MgYW4gb2JqZWN0XG4gICAgY29uc3QgZmllbGQgPSB0aGlzLmFsbEZpZWxkcy5maW5kKGYgPT4gZi5maWVsZCA9PT0gZmllbGROYW1lKTtcbiAgICBpZiAoZmllbGQ/LnR5cGUgPT09ICdsb29rdXAnICYmIGZpZWxkVmFsdWUgJiYgdHlwZW9mIGZpZWxkVmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICBmaWVsZFZhbHVlID0gZmllbGRWYWx1ZS5pZCB8fCBmaWVsZFZhbHVlW2ZpZWxkLmxvb2t1cFZhbHVlRmllbGQgfHwgJ2lkJ107XG4gICAgfVxuICAgIFxuICAgIHRoaXMuZmllbGRTYXZlLmVtaXQoeyBmaWVsZDogZmllbGROYW1lLCB2YWx1ZTogZmllbGRWYWx1ZSB9KTtcbiAgfVxuXG4gIGNhbmNlbElubGluZUVkaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNJbmxpbmVFZGl0TW9kZSAmJiB0aGlzLmVkaXRpbmdGaWVsZCkge1xuICAgICAgY29uc3QgY29udHJvbCA9IHRoaXMuZm9ybS5nZXQodGhpcy5lZGl0aW5nRmllbGQpO1xuICAgICAgaWYgKGNvbnRyb2wgJiYgdGhpcy5lbnRpdHlEYXRhKSB7XG4gICAgICAgIC8vIFJlc3RvcmUgb3JpZ2luYWwgdmFsdWVcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxWYWx1ZSA9IHRoaXMuZW50aXR5RGF0YVt0aGlzLmVkaXRpbmdGaWVsZF07XG4gICAgICAgIGNvbnRyb2wuc2V0VmFsdWUob3JpZ2luYWxWYWx1ZSk7XG4gICAgICAgIGNvbnRyb2wubWFya0FzUHJpc3RpbmUoKTtcbiAgICAgICAgY29udHJvbC5tYXJrQXNVbnRvdWNoZWQoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZWRpdGluZ0ZpZWxkID0gbnVsbDtcbiAgICAgIHRoaXMuc2F2aW5nRmllbGQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvLyBNZXRob2QgdG8gYmUgY2FsbGVkIGJ5IHBhcmVudCBhZnRlciBzYXZlIGNvbXBsZXRlc1xuICBjb21wbGV0ZUlubGluZUVkaXQoKTogdm9pZCB7XG4gICAgdGhpcy5lZGl0aW5nRmllbGQgPSBudWxsO1xuICAgIHRoaXMuc2F2aW5nRmllbGQgPSBmYWxzZTtcbiAgfVxuXG4gIGdldEZpZWxkRGlzcGxheVZhbHVlKGZpZWxkTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuZW50aXR5RGF0YSkgcmV0dXJuICcnO1xuXG4gICAgY29uc3QgZmllbGQgPSB0aGlzLmFsbEZpZWxkcy5maW5kKGYgPT4gZi5maWVsZCA9PT0gZmllbGROYW1lKTtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZW50aXR5RGF0YVtmaWVsZE5hbWVdO1xuXG4gICAgaWYgKCF2YWx1ZSkgcmV0dXJuICcnO1xuXG4gICAgLy8gRm9yIGxvb2t1cCBmaWVsZHMsIHJldHVybiB0aGUgZGlzcGxheSBuYW1lXG4gICAgaWYgKGZpZWxkPy50eXBlID09PSAnbG9va3VwJyAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlLm5hbWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5uYW1lO1xuICAgIH1cblxuICAgIC8vIEZvciBudW1iZXIgZmllbGRzLCBmb3JtYXQgYXBwcm9wcmlhdGVseVxuICAgIGlmIChmaWVsZD8udHlwZSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgaWYgKGZpZWxkLm51bWJlck1vZGUgPT09ICdjdXJyZW5jeScpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnRsLk51bWJlckZvcm1hdChmaWVsZC5sb2NhbGUgfHwgJ3B0LUJSJywge1xuICAgICAgICAgIHN0eWxlOiAnY3VycmVuY3knLFxuICAgICAgICAgIGN1cnJlbmN5OiBmaWVsZC5jdXJyZW5jeSB8fCAnQlJMJ1xuICAgICAgICB9KS5mb3JtYXQodmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBJbnRsLk51bWJlckZvcm1hdChmaWVsZC5sb2NhbGUgfHwgJ3B0LUJSJywge1xuICAgICAgICBtaW5pbXVtRnJhY3Rpb25EaWdpdHM6IGZpZWxkLm1pbkZyYWN0aW9uRGlnaXRzIHx8IDAsXG4gICAgICAgIG1heGltdW1GcmFjdGlvbkRpZ2l0czogZmllbGQubWF4RnJhY3Rpb25EaWdpdHMgfHwgMlxuICAgICAgfSkuZm9ybWF0KHZhbHVlKTtcbiAgICB9XG5cbiAgICAvLyBGb3IgZGF0ZSBmaWVsZHMsIGZvcm1hdCBhcyBkYXRlXG4gICAgaWYgKGZpZWxkPy50eXBlID09PSAnZGF0ZScgJiYgdmFsdWUpIHtcbiAgICAgIGNvbnN0IGRhdGUgPSB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gbmV3IERhdGUodmFsdWUpIDogdmFsdWU7XG4gICAgICByZXR1cm4gZGF0ZS50b0xvY2FsZURhdGVTdHJpbmcoJ3B0LUJSJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gIH1cbn1cbiIsIjwhLS0gTW9kbyBJbmxpbmUgKHBhZHLDo28pIC0tPlxuPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzSW5saW5lTW9kZVwiPlxuICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZm9ybUNvbnRlbnRcIj48L25nLWNvbnRhaW5lcj5cbjwvbmctY29udGFpbmVyPlxuXG48IS0tIE1vZG8gRGlhbG9nIC0tPlxuPHAtZGlhbG9nXG4gICpuZ0lmPVwiaXNEaWFsb2dNb2RlXCJcbiAgWyh2aXNpYmxlKV09XCJ2aXNpYmxlXCJcbiAgW2hlYWRlcl09XCJkaWFsb2dIZWFkZXIgfCB0cmFuc2xhdGVcIlxuICBbbW9kYWxdPVwidHJ1ZVwiXG4gIFtzdHlsZV09XCJ7IHdpZHRoOiBkaWFsb2dXaWR0aCB9XCJcbiAgW2RyYWdnYWJsZV09XCJkaWFsb2dEcmFnZ2FibGVcIlxuICBbcmVzaXphYmxlXT1cImRpYWxvZ1Jlc2l6YWJsZVwiXG4gIFttYXhpbWl6YWJsZV09XCJkaWFsb2dNYXhpbWl6YWJsZVwiXG4gIFtjbG9zZU9uRXNjYXBlXT1cImRpYWxvZ0Nsb3NlT25Fc2NhcGVcIlxuICBbZGlzbWlzc2FibGVNYXNrXT1cImRpYWxvZ0Rpc21pc3NhYmxlTWFza1wiXG4gIChvbkhpZGUpPVwiY2xvc2UoKVwiPlxuICBcbiAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZvcm1Db250ZW50XCI+PC9uZy1jb250YWluZXI+XG4gIFxuICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZm9vdGVyXCIgKm5nSWY9XCJzaG93U3VibWl0QnV0dG9uIHx8IHNob3dDYW5jZWxCdXR0b25cIj5cbiAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nLWZvb3RlclwiPlxuICAgICAgPHAtYnV0dG9uXG4gICAgICAgICpuZ0lmPVwic2hvd0NhbmNlbEJ1dHRvblwiXG4gICAgICAgIFtsYWJlbF09XCJjYW5jZWxMYWJlbCB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIFtpY29uXT1cImNhbmNlbEJ1dHRvbkljb25cIlxuICAgICAgICBzZXZlcml0eT1cInNlY29uZGFyeVwiXG4gICAgICAgIChvbkNsaWNrKT1cImhhbmRsZUNhbmNlbCgpXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdcIj5cbiAgICAgIDwvcC1idXR0b24+XG4gICAgICA8cC1idXR0b25cbiAgICAgICAgKm5nSWY9XCJzaG93U3VibWl0QnV0dG9uXCJcbiAgICAgICAgW2xhYmVsXT1cInN1Ym1pdExhYmVsIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgW2ljb25dPVwic3VibWl0QnV0dG9uSWNvblwiXG4gICAgICAgIChvbkNsaWNrKT1cImhhbmRsZVN1Ym1pdCgpXCJcbiAgICAgICAgW2xvYWRpbmddPVwibG9hZGluZ1wiXG4gICAgICAgIFtkaXNhYmxlZF09XCJmb3JtLmludmFsaWRcIj5cbiAgICAgIDwvcC1idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvbmctdGVtcGxhdGU+XG48L3AtZGlhbG9nPlxuXG48IS0tIE1vZG8gRHJhd2VyIC0tPlxuPHAtZHJhd2VyXG4gICpuZ0lmPVwiaXNEcmF3ZXJNb2RlXCJcbiAgWyh2aXNpYmxlKV09XCJ2aXNpYmxlXCJcbiAgW2hlYWRlcl09XCJkcmF3ZXJIZWFkZXIgfCB0cmFuc2xhdGVcIlxuICBbcG9zaXRpb25dPVwiZHJhd2VyUG9zaXRpb25cIlxuICBbc3R5bGVdPVwiZHJhd2VyU3R5bGVcIlxuICBbc2hvd0Nsb3NlSWNvbl09XCJkcmF3ZXJTaG93Q2xvc2VJY29uXCJcbiAgW2Nsb3NlT25Fc2NhcGVdPVwiZHJhd2VyQ2xvc2VPbkVzY2FwZVwiXG4gIFttb2RhbF09XCJkcmF3ZXJEaXNtaXNzYWJsZVwiXG4gIChvbkhpZGUpPVwiY2xvc2UoKVwiPlxuICBcbiAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZvcm1Db250ZW50XCI+PC9uZy1jb250YWluZXI+XG4gIFxuICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZm9vdGVyXCIgKm5nSWY9XCJzaG93U3VibWl0QnV0dG9uIHx8IHNob3dDYW5jZWxCdXR0b25cIj5cbiAgICA8ZGl2IGNsYXNzPVwiZHJhd2VyLWZvb3RlclwiPlxuICAgICAgPHAtYnV0dG9uXG4gICAgICAgICpuZ0lmPVwic2hvd0NhbmNlbEJ1dHRvblwiXG4gICAgICAgIFtsYWJlbF09XCJjYW5jZWxMYWJlbCB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIFtpY29uXT1cImNhbmNlbEJ1dHRvbkljb25cIlxuICAgICAgICBzZXZlcml0eT1cInNlY29uZGFyeVwiXG4gICAgICAgIChvbkNsaWNrKT1cImhhbmRsZUNhbmNlbCgpXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdcIj5cbiAgICAgIDwvcC1idXR0b24+XG4gICAgICA8cC1idXR0b25cbiAgICAgICAgKm5nSWY9XCJzaG93U3VibWl0QnV0dG9uXCJcbiAgICAgICAgW2xhYmVsXT1cInN1Ym1pdExhYmVsIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgW2ljb25dPVwic3VibWl0QnV0dG9uSWNvblwiXG4gICAgICAgIChvbkNsaWNrKT1cImhhbmRsZVN1Ym1pdCgpXCJcbiAgICAgICAgW2xvYWRpbmddPVwibG9hZGluZ1wiXG4gICAgICAgIFtkaXNhYmxlZF09XCJmb3JtLmludmFsaWRcIj5cbiAgICAgIDwvcC1idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvbmctdGVtcGxhdGU+XG48L3AtZHJhd2VyPlxuXG48IS0tIFRlbXBsYXRlIGRvIEZvcm11bMOhcmlvIChyZXV0aWxpesOhdmVsKSAtLT5cbjxuZy10ZW1wbGF0ZSAjZm9ybUNvbnRlbnQ+XG4gIDxmb3JtIFtmb3JtR3JvdXBdPVwiZm9ybVwiIGNsYXNzPVwiZHluYW1pYy1mb3JtXCI+XG4gICAgXG4gICAgPCEtLSBGaWx0cm9zIEZpeG9zIChhcGVuYXMgbm8gbW9kbyBmaWx0ZXIpIC0tPlxuICAgIDxkaXYgKm5nSWY9XCJtb2RlID09PSAnZmlsdGVyJyAmJiBoYXNGaXhlZEZpbHRlcnNcIiBjbGFzcz1cImZpeGVkLWZpbHRlcnMtc2VjdGlvblwiPlxuICAgICAgPGRpdiBjbGFzcz1cImdyaWRcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZmllbGQgb2YgZml4ZWRGaWx0ZXJzXCI+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImlzRmllbGRWaXNpYmxlKGZpZWxkKVwiIFtuZ0NsYXNzXT1cImdldEZpZWxkR3JpZENsYXNzKGZpZWxkKVwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZpZWxkVGVtcGxhdGU7IGNvbnRleHQ6IHsgZmllbGQ6IGZpZWxkIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gQ2FtcG9zIERpcmV0b3MgKHNlbSBzZcOnw6NvKSAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwiaGFzRmllbGRzXCI+XG4gICAgICA8IS0tIE1vZG8gSW5saW5lIEVkaXQgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiaXNJbmxpbmVFZGl0TW9kZVwiIGNsYXNzPVwiaW5saW5lLWVkaXQtZmllbGRzXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGZvcm1GaWVsZHNcIj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNGaWVsZFZpc2libGUoZmllbGQpXCIgY2xhc3M9XCJpbmxpbmUtZWRpdC1maWVsZFwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImlubGluZUVkaXRGaWVsZFRlbXBsYXRlOyBjb250ZXh0OiB7IGZpZWxkOiBmaWVsZCB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gTW9kbyBGb3JtIE5vcm1hbCAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCIhaXNJbmxpbmVFZGl0TW9kZVwiIGNsYXNzPVwiZ3JpZFwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBmaWVsZCBvZiBmb3JtRmllbGRzXCI+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImlzRmllbGRWaXNpYmxlKGZpZWxkKVwiIFtuZ0NsYXNzXT1cImdldEZpZWxkR3JpZENsYXNzKGZpZWxkKVwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZpZWxkVGVtcGxhdGU7IGNvbnRleHQ6IHsgZmllbGQ6IGZpZWxkIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gU2XDp8O1ZXMgZGUgQ2FtcG9zIChtb2RvIGZvcm0pIC0tPlxuICAgIDxkaXYgKm5nSWY9XCJoYXNTZWN0aW9uc1wiIGNsYXNzPVwic2VjdGlvbnMtY29udGFpbmVyXCI+XG4gICAgICA8cC1wYW5lbCBcbiAgICAgICAgKm5nRm9yPVwibGV0IHNlY3Rpb24gb2YgZm9ybVNlY3Rpb25zXCJcbiAgICAgICAgW3RvZ2dsZWFibGVdPVwic2VjdGlvbi50b2dnbGVhYmxlICE9PSBmYWxzZVwiXG4gICAgICAgIFtjb2xsYXBzZWRdPVwic2VjdGlvbi5jb2xsYXBzZWQgfHwgZmFsc2VcIlxuICAgICAgICBbc3R5bGVDbGFzc109XCInc2VjdGlvbi1wYW5lbCdcIj5cbiAgICAgICAgXG4gICAgICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJoZWFkZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi1oZWFkZXJcIj5cbiAgICAgICAgICAgIDxpICpuZ0lmPVwic2VjdGlvbi5pY29uXCIgW2NsYXNzXT1cInNlY3Rpb24uaWNvbiArICcgc2VjdGlvbi1pY29uJ1wiPjwvaT5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2VjdGlvbi10aXRsZVwiPnt7IHNlY3Rpb24udGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgPCEtLSBNb2RvIElubGluZSBFZGl0IC0tPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNJbmxpbmVFZGl0TW9kZVwiIGNsYXNzPVwiaW5saW5lLWVkaXQtZmllbGRzXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZmllbGQgb2Ygc2VjdGlvbi5maWVsZHNcIj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc0ZpZWxkVmlzaWJsZShmaWVsZClcIiBjbGFzcz1cImlubGluZS1lZGl0LWZpZWxkXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJpbmxpbmVFZGl0RmllbGRUZW1wbGF0ZTsgY29udGV4dDogeyBmaWVsZDogZmllbGQgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gTW9kbyBGb3JtIE5vcm1hbCAtLT5cbiAgICAgICAgPGRpdiAqbmdJZj1cIiFpc0lubGluZUVkaXRNb2RlXCIgY2xhc3M9XCJncmlkXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZmllbGQgb2Ygc2VjdGlvbi5maWVsZHNcIj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc0ZpZWxkVmlzaWJsZShmaWVsZClcIiBbbmdDbGFzc109XCJnZXRGaWVsZEdyaWRDbGFzcyhmaWVsZClcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZpZWxkVGVtcGxhdGU7IGNvbnRleHQ6IHsgZmllbGQ6IGZpZWxkIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvcC1wYW5lbD5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gU2XDp8O1ZXMgZGUgRmlsdHJvcyAoYXBlbmFzIG5vIG1vZG8gZmlsdGVyKSAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwibW9kZSA9PT0gJ2ZpbHRlcicgJiYgaGFzRmlsdGVyU2VjdGlvbnNcIiBjbGFzcz1cImZpbHRlci1zZWN0aW9ucy1jb250YWluZXJcIj5cbiAgICAgIDxwLXBhbmVsIFxuICAgICAgICAqbmdGb3I9XCJsZXQgc2VjdGlvbiBvZiBmaWx0ZXJTZWN0aW9uc1wiXG4gICAgICAgIFtoZWFkZXJdPVwic2VjdGlvbi50aXRsZVwiXG4gICAgICAgIFt0b2dnbGVhYmxlXT1cInRydWVcIlxuICAgICAgICBbY29sbGFwc2VkXT1cInRydWVcIj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JpZFwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGZpZWxkIG9mIHNlY3Rpb24uZmllbGRzXCI+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNGaWVsZFZpc2libGUoZmllbGQpXCIgW25nQ2xhc3NdPVwiZ2V0RmllbGRHcmlkQ2xhc3MoZmllbGQpXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJmaWVsZFRlbXBsYXRlOyBjb250ZXh0OiB7IGZpZWxkOiBmaWVsZCB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L3AtcGFuZWw+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIEJvdMO1ZXMgaW5saW5lIChhcGVuYXMgcGFyYSBtb2RvIGlubGluZSkgLS0+XG4gICAgPGRpdiAqbmdJZj1cImlzSW5saW5lTW9kZSAmJiAoc2hvd1N1Ym1pdEJ1dHRvbiB8fCBzaG93Q2FuY2VsQnV0dG9uKVwiIGNsYXNzPVwiZm9ybS1hY3Rpb25zXCI+XG4gICAgICA8cC1idXR0b25cbiAgICAgICAgKm5nSWY9XCJzaG93Q2FuY2VsQnV0dG9uXCJcbiAgICAgICAgW2xhYmVsXT1cImNhbmNlbExhYmVsIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgW2ljb25dPVwiY2FuY2VsQnV0dG9uSWNvblwiXG4gICAgICAgIHNldmVyaXR5PVwic2Vjb25kYXJ5XCJcbiAgICAgICAgKG9uQ2xpY2spPVwiaGFuZGxlQ2FuY2VsKClcIlxuICAgICAgICBbZGlzYWJsZWRdPVwibG9hZGluZ1wiPlxuICAgICAgPC9wLWJ1dHRvbj5cbiAgICAgIDxwLWJ1dHRvblxuICAgICAgICAqbmdJZj1cInNob3dTdWJtaXRCdXR0b25cIlxuICAgICAgICBbbGFiZWxdPVwic3VibWl0TGFiZWwgfCB0cmFuc2xhdGVcIlxuICAgICAgICBbaWNvbl09XCJzdWJtaXRCdXR0b25JY29uXCJcbiAgICAgICAgKG9uQ2xpY2spPVwiaGFuZGxlU3VibWl0KClcIlxuICAgICAgICBbbG9hZGluZ109XCJsb2FkaW5nXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImZvcm0uaW52YWxpZFwiPlxuICAgICAgPC9wLWJ1dHRvbj5cbiAgICA8L2Rpdj5cblxuICA8L2Zvcm0+XG48L25nLXRlbXBsYXRlPlxuXG48IS0tIFRlbXBsYXRlIGRlIENhbXBvIChyZXV0aWxpesOhdmVsKSAtLT5cbjxuZy10ZW1wbGF0ZSAjZmllbGRUZW1wbGF0ZSBsZXQtZmllbGQ9XCJmaWVsZFwiPlxuICA8IS0tIFRleHQgRmllbGQgLS0+XG4gIDxzaWEtZHluYW1pYy1maWVsZC10ZXh0XG4gICAgKm5nSWY9XCJmaWVsZC50eXBlID09PSAndGV4dCdcIlxuICAgIFtmaWVsZF09XCJmaWVsZFwiXG4gICAgW2Zvcm1dPVwiZm9ybVwiXG4gICAgW21vZGVdPVwiZmllbGRNb2RlXCI+XG4gIDwvc2lhLWR5bmFtaWMtZmllbGQtdGV4dD5cblxuICA8IS0tIFRleHRhcmVhIEZpZWxkIC0tPlxuICA8c2lhLWR5bmFtaWMtZmllbGQtdGV4dGFyZWFcbiAgICAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICd0ZXh0YXJlYSdcIlxuICAgIFtmaWVsZF09XCJmaWVsZFwiXG4gICAgW2Zvcm1dPVwiZm9ybVwiXG4gICAgW21vZGVdPVwiZmllbGRNb2RlXCI+XG4gIDwvc2lhLWR5bmFtaWMtZmllbGQtdGV4dGFyZWE+XG5cbiAgPCEtLSBOdW1iZXIgRmllbGQgLS0+XG4gIDxzaWEtZHluYW1pYy1maWVsZC1udW1iZXJcbiAgICAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdudW1iZXInXCJcbiAgICBbZmllbGRdPVwiZmllbGRcIlxuICAgIFtmb3JtXT1cImZvcm1cIlxuICAgIFttb2RlXT1cImZpZWxkTW9kZVwiPlxuICA8L3NpYS1keW5hbWljLWZpZWxkLW51bWJlcj5cblxuICA8IS0tIERhdGUgRmllbGQgLS0+XG4gIDxzaWEtZHluYW1pYy1maWVsZC1kYXRlXG4gICAgKm5nSWY9XCJmaWVsZC50eXBlID09PSAnZGF0ZSdcIlxuICAgIFtmaWVsZF09XCJmaWVsZFwiXG4gICAgW2Zvcm1dPVwiZm9ybVwiXG4gICAgW21vZGVdPVwiZmllbGRNb2RlXCI+XG4gIDwvc2lhLWR5bmFtaWMtZmllbGQtZGF0ZT5cblxuICA8IS0tIERyb3Bkb3duL0VudW0gRmllbGQgLS0+XG4gIDxzaWEtZHluYW1pYy1maWVsZC1kcm9wZG93blxuICAgICpuZ0lmPVwiZmllbGQudHlwZSA9PT0gJ2Ryb3Bkb3duJyB8fCBmaWVsZC50eXBlID09PSAnZW51bSdcIlxuICAgIFtmaWVsZF09XCJmaWVsZFwiXG4gICAgW2Zvcm1dPVwiZm9ybVwiXG4gICAgW21vZGVdPVwiZmllbGRNb2RlXCI+XG4gIDwvc2lhLWR5bmFtaWMtZmllbGQtZHJvcGRvd24+XG5cbiAgPCEtLSBMb29rdXAgRmllbGQgLS0+XG4gIDxzaWEtZHluYW1pYy1maWVsZC1sb29rdXBcbiAgICAqbmdJZj1cImZpZWxkLnR5cGUgPT09ICdsb29rdXAnXCJcbiAgICBbZmllbGRdPVwiZmllbGRcIlxuICAgIFtmb3JtXT1cImZvcm1cIlxuICAgIFtmb3JtR3JvdXBdPVwiZm9ybVwiXG4gICAgW21vZGVdPVwiZmllbGRNb2RlXCI+XG4gIDwvc2lhLWR5bmFtaWMtZmllbGQtbG9va3VwPlxuPC9uZy10ZW1wbGF0ZT5cblxuXG48IS0tIFRlbXBsYXRlIGRlIENhbXBvIElubGluZSBFZGl0IC0tPlxuPG5nLXRlbXBsYXRlICNpbmxpbmVFZGl0RmllbGRUZW1wbGF0ZSBsZXQtZmllbGQ9XCJmaWVsZFwiPlxuICA8ZGl2IGNsYXNzPVwiZWRpdC1pbmxpbmUtZmllbGRcIj5cbiAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPnt7IGZpZWxkLmxhYmVsIHwgdHJhbnNsYXRlIH19PC9sYWJlbD5cbiAgICBcbiAgICA8IS0tIERpc3BsYXkgTW9kZSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiZmllbGQtZGlzcGxheVwiIFxuICAgICAgICAgKm5nSWY9XCIhaXNGaWVsZEVkaXRpbmcoZmllbGQuZmllbGQpXCIgXG4gICAgICAgICAoY2xpY2spPVwic3RhcnRFZGl0RmllbGQoZmllbGQuZmllbGQpXCJcbiAgICAgICAgIFtjbGFzcy5kaXNhYmxlZF09XCJmaWVsZC5kaXNhYmxlZFwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJkaXNwbGF5LXZhbHVlXCIgXG4gICAgICAgICAgICBbYXR0ci5kYXRhLXBsYWNlaG9sZGVyXT1cImZpZWxkLnBsYWNlaG9sZGVyIHx8ICgnY3JteC5idXNpbmVzcy5ub3RfaW5mb3JtZWQnIHwgdHJhbnNsYXRlKVwiPlxuICAgICAgICB7eyBnZXRGaWVsZERpc3BsYXlWYWx1ZShmaWVsZC5maWVsZCkgfX1cbiAgICAgIDwvc3Bhbj5cbiAgICAgIDxpIGNsYXNzPVwicGkgcGktcGVuY2lsIGVkaXQtaWNvblwiICpuZ0lmPVwiIWZpZWxkLmRpc2FibGVkXCI+PC9pPlxuICAgIDwvZGl2PlxuICAgIFxuICAgIDwhLS0gRWRpdCBNb2RlIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1lZGl0XCIgKm5nSWY9XCJpc0ZpZWxkRWRpdGluZyhmaWVsZC5maWVsZClcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1jb250YWluZXJcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZpZWxkVGVtcGxhdGU7IGNvbnRleHQ6IHsgZmllbGQ6IGZpZWxkIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgICAgXG4gICAgICA8IS0tIEFjdGlvbiBCdXR0b25zIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImVkaXQtYWN0aW9uc1wiPlxuICAgICAgICA8cC1idXR0b24gXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiIFxuICAgICAgICAgIGljb249XCJwaSBwaS1jaGVja1wiIFxuICAgICAgICAgIFtyb3VuZGVkXT1cInRydWVcIlxuICAgICAgICAgIHNldmVyaXR5PVwicHJpbWFyeVwiXG4gICAgICAgICAgKG9uQ2xpY2spPVwic2F2ZUlubGluZUZpZWxkKGZpZWxkLmZpZWxkKVwiIFxuICAgICAgICAgIFtsb2FkaW5nXT1cInNhdmluZ0ZpZWxkXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiZm9ybS5nZXQoZmllbGQuZmllbGQpPy5pbnZhbGlkXCI+XG4gICAgICAgIDwvcC1idXR0b24+XG4gICAgICAgIDxwLWJ1dHRvbiBcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCIgXG4gICAgICAgICAgaWNvbj1cInBpIHBpLXRpbWVzXCIgXG4gICAgICAgICAgW3JvdW5kZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgc2V2ZXJpdHk9XCJzZWNvbmRhcnlcIlxuICAgICAgICAgIChvbkNsaWNrKT1cImNhbmNlbElubGluZUVkaXQoKVwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cInNhdmluZ0ZpZWxkXCI+XG4gICAgICAgIDwvcC1idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICAgIFxuICAgICAgPCEtLSBFcnJvciBNZXNzYWdlIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWVycm9yXCIgKm5nSWY9XCJmb3JtLmdldChmaWVsZC5maWVsZCk/LmludmFsaWQgJiYgZm9ybS5nZXQoZmllbGQuZmllbGQpPy50b3VjaGVkXCI+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInAtZXJyb3JcIj5cbiAgICAgICAgICB7eyBmb3JtLmdldChmaWVsZC5maWVsZCk/LmVycm9ycz8uWydyZXF1aXJlZCddID8gKCdjcm14LmJ1c2luZXNzLnJlcXVpcmVkX2ZpZWxkJyB8IHRyYW5zbGF0ZSkgOiAnJyB9fVxuICAgICAgICA8L3NtYWxsPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==