@gnggln/ng-ui-system 1.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/esm2022/gnggln-ng-ui-system.mjs +5 -0
  2. package/esm2022/lib/components/accordion/accordion.component.mjs +353 -0
  3. package/esm2022/lib/components/accordion/accordion.types.mjs +6 -0
  4. package/esm2022/lib/components/accordion/index.mjs +2 -0
  5. package/esm2022/lib/components/base-layout/base-layout.component.mjs +218 -0
  6. package/esm2022/lib/components/base-layout/base-layout.types.mjs +6 -0
  7. package/esm2022/lib/components/base-layout/index.mjs +14 -0
  8. package/esm2022/lib/components/button/button-area.component.mjs +196 -0
  9. package/esm2022/lib/components/button/button.component.mjs +164 -0
  10. package/esm2022/lib/components/button/button.types.mjs +6 -0
  11. package/esm2022/lib/components/button/index.mjs +16 -0
  12. package/esm2022/lib/components/crud-table/crud-table.component.mjs +789 -0
  13. package/esm2022/lib/components/crud-table/crud-table.types.mjs +6 -0
  14. package/esm2022/lib/components/crud-table/index.mjs +16 -0
  15. package/esm2022/lib/components/form-builder/adapters/it-date-adapter.mjs +82 -0
  16. package/esm2022/lib/components/form-builder/directives/currency-input.directive.mjs +184 -0
  17. package/esm2022/lib/components/form-builder/form-builder.component.mjs +824 -0
  18. package/esm2022/lib/components/form-builder/form-wizard.component.mjs +510 -0
  19. package/esm2022/lib/components/form-builder/index.mjs +19 -0
  20. package/esm2022/lib/components/form-builder/services/form-condition.service.mjs +132 -0
  21. package/esm2022/lib/components/form-builder/services/form-validation.service.mjs +381 -0
  22. package/esm2022/lib/components/form-builder/services/location.service.mjs +140 -0
  23. package/esm2022/lib/components/form-builder/services/wizard-sync.service.mjs +84 -0
  24. package/esm2022/lib/components/form-builder/sub-components/error-summary/form-error-summary.component.mjs +161 -0
  25. package/esm2022/lib/components/form-builder/sub-components/file-input/file-input.component.mjs +310 -0
  26. package/esm2022/lib/components/form-builder/sub-components/specifica-territoriale/specifica-territoriale.component.mjs +648 -0
  27. package/esm2022/lib/components/form-builder/sub-components/table-territoriale/table-territoriale.component.mjs +432 -0
  28. package/esm2022/lib/components/form-builder/types/condition.types.mjs +6 -0
  29. package/esm2022/lib/components/form-builder/types/field.types.mjs +6 -0
  30. package/esm2022/lib/components/form-builder/types/index.mjs +2 -0
  31. package/esm2022/lib/components/form-builder/types/schema.types.mjs +6 -0
  32. package/esm2022/lib/components/form-builder/types/territoriale.types.mjs +6 -0
  33. package/esm2022/lib/components/form-builder/types/validation.types.mjs +6 -0
  34. package/esm2022/lib/components/form-builder-editor/form-builder-editor.component.mjs +730 -0
  35. package/esm2022/lib/components/form-builder-editor/form-builder-editor.service.mjs +56 -0
  36. package/esm2022/lib/components/form-builder-editor/index.mjs +21 -0
  37. package/esm2022/lib/components/form-builder-editor/services/editor-persistence.service.mjs +190 -0
  38. package/esm2022/lib/components/form-builder-editor/services/editor-state.service.mjs +324 -0
  39. package/esm2022/lib/components/form-builder-editor/services/field-factory.service.mjs +188 -0
  40. package/esm2022/lib/components/form-builder-editor/sub-components/condition-editor/condition-editor.component.mjs +667 -0
  41. package/esm2022/lib/components/form-builder-editor/sub-components/editor-toolbar/editor-toolbar.component.mjs +317 -0
  42. package/esm2022/lib/components/form-builder-editor/sub-components/field-config-panel/field-config-panel.component.mjs +611 -0
  43. package/esm2022/lib/components/form-builder-editor/sub-components/field-palette/field-palette.component.mjs +267 -0
  44. package/esm2022/lib/components/form-builder-editor/sub-components/form-values-panel/form-values-panel.component.mjs +276 -0
  45. package/esm2022/lib/components/form-builder-editor/sub-components/options-editor/options-editor.component.mjs +323 -0
  46. package/esm2022/lib/components/form-builder-editor/sub-components/preview-container/preview-container.component.mjs +238 -0
  47. package/esm2022/lib/components/form-builder-editor/sub-components/section-editor/section-editor.component.mjs +472 -0
  48. package/esm2022/lib/components/form-builder-editor/sub-components/validation-editor/validation-editor.component.mjs +473 -0
  49. package/esm2022/lib/components/form-builder-editor/types/editor.types.mjs +6 -0
  50. package/esm2022/lib/components/layout-builder/index.mjs +18 -0
  51. package/esm2022/lib/components/layout-builder/layout-builder.component.mjs +1730 -0
  52. package/esm2022/lib/components/layout-builder/layout-builder.types.mjs +9 -0
  53. package/esm2022/lib/components/layout-builder/layout.service.mjs +239 -0
  54. package/esm2022/lib/components/modal/confirm-dialog.component.mjs +151 -0
  55. package/esm2022/lib/components/modal/index.mjs +4 -0
  56. package/esm2022/lib/components/modal/modal.component.mjs +139 -0
  57. package/esm2022/lib/components/modal/modal.service.mjs +194 -0
  58. package/esm2022/lib/components/modal/modal.types.mjs +6 -0
  59. package/esm2022/lib/components/page-header/breadcrumb.service.mjs +242 -0
  60. package/esm2022/lib/components/page-header/index.mjs +20 -0
  61. package/esm2022/lib/components/page-header/page-header.component.mjs +243 -0
  62. package/esm2022/lib/components/page-header/page-header.types.mjs +21 -0
  63. package/esm2022/lib/components/table/index.mjs +2 -0
  64. package/esm2022/lib/components/table/paginated-table.component.mjs +407 -0
  65. package/esm2022/lib/components/table/table.types.mjs +6 -0
  66. package/esm2022/lib/core/types/index.mjs +6 -0
  67. package/esm2022/lib/core/utils/index.mjs +53 -0
  68. package/esm2022/lib/sources/location-data.opt.json +8942 -0
  69. package/esm2022/lib/sources/nazioni.opt.json +215 -0
  70. package/esm2022/public-api.mjs +34 -0
  71. package/fesm2022/gnggln-ng-ui-system.mjs +55752 -0
  72. package/fesm2022/gnggln-ng-ui-system.mjs.map +1 -0
  73. package/index.d.ts +5 -0
  74. package/lib/components/accordion/accordion.component.d.ts +118 -0
  75. package/lib/components/accordion/accordion.types.d.ts +62 -0
  76. package/lib/components/accordion/index.d.ts +2 -0
  77. package/lib/components/base-layout/base-layout.component.d.ts +83 -0
  78. package/lib/components/base-layout/base-layout.types.d.ts +26 -0
  79. package/lib/components/base-layout/index.d.ts +13 -0
  80. package/lib/components/button/button-area.component.d.ts +88 -0
  81. package/lib/components/button/button.component.d.ts +55 -0
  82. package/lib/components/button/button.types.d.ts +70 -0
  83. package/lib/components/button/index.d.ts +15 -0
  84. package/lib/components/crud-table/crud-table.component.d.ts +143 -0
  85. package/lib/components/crud-table/crud-table.types.d.ts +207 -0
  86. package/lib/components/crud-table/index.d.ts +15 -0
  87. package/lib/components/form-builder/adapters/it-date-adapter.d.ts +32 -0
  88. package/lib/components/form-builder/directives/currency-input.directive.d.ts +48 -0
  89. package/lib/components/form-builder/form-builder.component.d.ts +183 -0
  90. package/lib/components/form-builder/form-wizard.component.d.ts +87 -0
  91. package/lib/components/form-builder/index.d.ts +13 -0
  92. package/lib/components/form-builder/services/form-condition.service.d.ts +46 -0
  93. package/lib/components/form-builder/services/form-validation.service.d.ts +63 -0
  94. package/lib/components/form-builder/services/location.service.d.ts +83 -0
  95. package/lib/components/form-builder/services/wizard-sync.service.d.ts +63 -0
  96. package/lib/components/form-builder/sub-components/error-summary/form-error-summary.component.d.ts +28 -0
  97. package/lib/components/form-builder/sub-components/file-input/file-input.component.d.ts +41 -0
  98. package/lib/components/form-builder/sub-components/specifica-territoriale/specifica-territoriale.component.d.ts +145 -0
  99. package/lib/components/form-builder/sub-components/table-territoriale/table-territoriale.component.d.ts +108 -0
  100. package/lib/components/form-builder/types/condition.types.d.ts +51 -0
  101. package/lib/components/form-builder/types/field.types.d.ts +288 -0
  102. package/lib/components/form-builder/types/index.d.ts +5 -0
  103. package/lib/components/form-builder/types/schema.types.d.ts +227 -0
  104. package/lib/components/form-builder/types/territoriale.types.d.ts +170 -0
  105. package/lib/components/form-builder/types/validation.types.d.ts +174 -0
  106. package/lib/components/form-builder-editor/form-builder-editor.component.d.ts +117 -0
  107. package/lib/components/form-builder-editor/form-builder-editor.service.d.ts +38 -0
  108. package/lib/components/form-builder-editor/index.d.ts +15 -0
  109. package/lib/components/form-builder-editor/services/editor-persistence.service.d.ts +42 -0
  110. package/lib/components/form-builder-editor/services/editor-state.service.d.ts +66 -0
  111. package/lib/components/form-builder-editor/services/field-factory.service.d.ts +28 -0
  112. package/lib/components/form-builder-editor/sub-components/condition-editor/condition-editor.component.d.ts +139 -0
  113. package/lib/components/form-builder-editor/sub-components/editor-toolbar/editor-toolbar.component.d.ts +43 -0
  114. package/lib/components/form-builder-editor/sub-components/field-config-panel/field-config-panel.component.d.ts +83 -0
  115. package/lib/components/form-builder-editor/sub-components/field-palette/field-palette.component.d.ts +40 -0
  116. package/lib/components/form-builder-editor/sub-components/form-values-panel/form-values-panel.component.d.ts +51 -0
  117. package/lib/components/form-builder-editor/sub-components/options-editor/options-editor.component.d.ts +63 -0
  118. package/lib/components/form-builder-editor/sub-components/preview-container/preview-container.component.d.ts +68 -0
  119. package/lib/components/form-builder-editor/sub-components/section-editor/section-editor.component.d.ts +82 -0
  120. package/lib/components/form-builder-editor/sub-components/validation-editor/validation-editor.component.d.ts +112 -0
  121. package/lib/components/form-builder-editor/types/editor.types.d.ts +124 -0
  122. package/lib/components/layout-builder/index.d.ts +16 -0
  123. package/lib/components/layout-builder/layout-builder.component.d.ts +85 -0
  124. package/lib/components/layout-builder/layout-builder.types.d.ts +436 -0
  125. package/lib/components/layout-builder/layout.service.d.ts +100 -0
  126. package/lib/components/modal/confirm-dialog.component.d.ts +46 -0
  127. package/lib/components/modal/index.d.ts +4 -0
  128. package/lib/components/modal/modal.component.d.ts +44 -0
  129. package/lib/components/modal/modal.service.d.ts +93 -0
  130. package/lib/components/modal/modal.types.d.ts +110 -0
  131. package/lib/components/page-header/breadcrumb.service.d.ts +96 -0
  132. package/lib/components/page-header/index.d.ts +16 -0
  133. package/lib/components/page-header/page-header.component.d.ts +59 -0
  134. package/lib/components/page-header/page-header.types.d.ts +96 -0
  135. package/lib/components/table/index.d.ts +2 -0
  136. package/lib/components/table/paginated-table.component.d.ts +85 -0
  137. package/lib/components/table/table.types.d.ts +81 -0
  138. package/lib/core/types/index.d.ts +57 -0
  139. package/lib/core/utils/index.d.ts +29 -0
  140. package/package.json +44 -0
  141. package/public-api.d.ts +22 -0
@@ -0,0 +1,730 @@
1
+ /**
2
+ * @module ng-ui-system/form-builder-editor
3
+ * Componente principale dell'editor visuale del form builder.
4
+ *
5
+ * Layout a tre pannelli:
6
+ * - Sinistra: palette dei tipi di campo (drag source)
7
+ * - Centro: sezioni con campi (drop target + editor inline)
8
+ * - Destra: pannello di configurazione del campo selezionato
9
+ *
10
+ * Funzionalita principali:
11
+ * - Drag & drop dei campi dalla palette alle sezioni
12
+ * - Riordino campi all'interno e tra sezioni
13
+ * - Configurazione campi in tempo reale
14
+ * - Preview live del form
15
+ * - Import/export JSON
16
+ * - Auto-save su localStorage
17
+ */
18
+ import { Component, ChangeDetectionStrategy, ChangeDetectorRef, inject, Optional, Inject, } from '@angular/core';
19
+ import { DragDropModule } from '@angular/cdk/drag-drop';
20
+ import { MAT_DIALOG_DATA } from '@angular/material/dialog';
21
+ import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
22
+ import { MatTabsModule } from '@angular/material/tabs';
23
+ import { LucideAngularModule } from 'lucide-angular';
24
+ import { Subject, interval } from 'rxjs';
25
+ import { takeUntil } from 'rxjs/operators';
26
+ import { UiEditorStateService } from './services/editor-state.service';
27
+ import { UiEditorPersistenceService } from './services/editor-persistence.service';
28
+ import { UiEditorFieldFactoryService } from './services/field-factory.service';
29
+ // Sotto-componenti
30
+ import { UiEditorToolbarComponent } from './sub-components/editor-toolbar/editor-toolbar.component';
31
+ import { UiFieldPaletteComponent } from './sub-components/field-palette/field-palette.component';
32
+ import { UiSectionEditorComponent } from './sub-components/section-editor/section-editor.component';
33
+ import { UiEditorFieldConfigPanelComponent } from './sub-components/field-config-panel/field-config-panel.component';
34
+ import { UiEditorPreviewContainerComponent } from './sub-components/preview-container/preview-container.component';
35
+ import { UiButtonComponent } from '../button/index';
36
+ import * as i0 from "@angular/core";
37
+ import * as i1 from "@angular/material/dialog";
38
+ import * as i2 from "@angular/cdk/drag-drop";
39
+ import * as i3 from "@angular/material/tabs";
40
+ import * as i4 from "lucide-angular";
41
+ export class UiFormBuilderEditorComponent {
42
+ constructor(dialogRef, dialogData) {
43
+ this.dialogRef = dialogRef;
44
+ this.dialogData = dialogData;
45
+ /** @internal Servizio per lo stato dell'editor. */
46
+ this.stateService = inject(UiEditorStateService);
47
+ /** @internal Servizio per la persistenza. */
48
+ this.persistenceService = inject(UiEditorPersistenceService);
49
+ /** @internal Factory per i campi. */
50
+ this.fieldFactory = inject(UiEditorFieldFactoryService);
51
+ /** @internal Snack bar per i messaggi. */
52
+ this.snackBar = inject(MatSnackBar);
53
+ /** @internal Change detector. */
54
+ this.cdr = inject(ChangeDetectorRef);
55
+ /** @internal Subject per la distruzione. */
56
+ this.destroy$ = new Subject();
57
+ /** Indice del tab selezionato (0=Editor, 1=Preview). */
58
+ this.selectedTabIndex = 0;
59
+ /** Breadcrumb di navigazione. */
60
+ this.breadcrumb = [];
61
+ /** Se il componente e aperto in modalita dialog. */
62
+ this.isDialogMode = false;
63
+ /** Chiave per forzare il re-render del preview. */
64
+ this.previewKey = 0;
65
+ /** Campi disponibili per le condizioni (cache). */
66
+ this.availableFields = [];
67
+ /** Larghezza della sidebar sinistra (px). */
68
+ this.leftSidebarWidth = 280;
69
+ /** Larghezza della sidebar destra (px). */
70
+ this.rightSidebarWidth = 460;
71
+ /** Se e in corso il resize della sidebar destra. */
72
+ this.isResizing = false;
73
+ /** Se e in corso il resize della sidebar sinistra. */
74
+ this.isResizingLeft = false;
75
+ /** @internal Limiti di resize sidebar destra. */
76
+ this.MIN_SIDEBAR_WIDTH = 400;
77
+ this.MAX_SIDEBAR_WIDTH = 1200;
78
+ /** @internal Limiti di resize sidebar sinistra. */
79
+ this.MIN_LEFT_SIDEBAR_WIDTH = 200;
80
+ this.MAX_LEFT_SIDEBAR_WIDTH = 500;
81
+ this.resizeStartX = 0;
82
+ this.resizeStartWidth = 0;
83
+ this.SIDEBAR_WIDTH_KEY = 'ui-editor-right-sidebar-width';
84
+ this.LEFT_SIDEBAR_WIDTH_KEY = 'ui-editor-left-sidebar-width';
85
+ this.onResizeMove = (event) => {
86
+ if (!this.isResizing)
87
+ return;
88
+ const delta = this.resizeStartX - event.clientX;
89
+ this.rightSidebarWidth = Math.max(this.MIN_SIDEBAR_WIDTH, Math.min(this.MAX_SIDEBAR_WIDTH, this.resizeStartWidth + delta));
90
+ this.cdr.markForCheck();
91
+ };
92
+ this.onResizeEnd = () => {
93
+ if (!this.isResizing)
94
+ return;
95
+ this.isResizing = false;
96
+ document.removeEventListener('mousemove', this.onResizeMove);
97
+ document.removeEventListener('mouseup', this.onResizeEnd);
98
+ document.body.style.cursor = '';
99
+ document.body.style.userSelect = '';
100
+ this.saveSidebarWidth();
101
+ };
102
+ this.onLeftResizeMove = (event) => {
103
+ if (!this.isResizingLeft)
104
+ return;
105
+ const delta = event.clientX - this.resizeStartX;
106
+ this.leftSidebarWidth = Math.max(this.MIN_LEFT_SIDEBAR_WIDTH, Math.min(this.MAX_LEFT_SIDEBAR_WIDTH, this.resizeStartWidth + delta));
107
+ this.cdr.markForCheck();
108
+ };
109
+ this.onLeftResizeEnd = () => {
110
+ if (!this.isResizingLeft)
111
+ return;
112
+ this.isResizingLeft = false;
113
+ document.removeEventListener('mousemove', this.onLeftResizeMove);
114
+ document.removeEventListener('mouseup', this.onLeftResizeEnd);
115
+ document.body.style.cursor = '';
116
+ document.body.style.userSelect = '';
117
+ this.saveLeftSidebarWidth();
118
+ };
119
+ this.state = this.stateService.getCurrentState();
120
+ this.isDialogMode = !!this.dialogRef;
121
+ // Carica schema iniziale se fornito via dialog data
122
+ if (this.dialogData?.initialSchema) {
123
+ this.stateService.setSchema(this.dialogData.initialSchema);
124
+ }
125
+ this.loadSidebarWidth();
126
+ }
127
+ ngOnInit() {
128
+ // Sottoscrizione allo stato
129
+ this.stateService.state$.pipe(takeUntil(this.destroy$)).subscribe((state) => {
130
+ this.state = state;
131
+ this.updateBreadcrumb();
132
+ this.updateAvailableFields();
133
+ this.cdr.markForCheck();
134
+ });
135
+ // Controlla salvataggi precedenti da recuperare
136
+ this.checkForRecovery();
137
+ // Auto-save ogni 30 secondi
138
+ interval(30000)
139
+ .pipe(takeUntil(this.destroy$))
140
+ .subscribe(() => {
141
+ if (this.state.isDirty) {
142
+ this.autoSave();
143
+ }
144
+ });
145
+ }
146
+ ngOnDestroy() {
147
+ this.destroy$.next();
148
+ this.destroy$.complete();
149
+ }
150
+ // ─── Toolbar actions ─────────────────────────────────────────
151
+ /** Aggiunge una nuova sezione. */
152
+ onAddSection() {
153
+ this.stateService.addSection();
154
+ this.showMessage('Sezione aggiunta');
155
+ }
156
+ /** Salva nel localStorage. */
157
+ onSave() {
158
+ try {
159
+ this.persistenceService.saveToLocalStorage(this.state.schema);
160
+ this.stateService.markAsSaved();
161
+ this.showMessage('Salvato con successo');
162
+ }
163
+ catch (error) {
164
+ this.showMessage(error.message || 'Errore durante il salvataggio', true);
165
+ }
166
+ }
167
+ /** Crea un nuovo form. */
168
+ onNewForm() {
169
+ if (this.state.isDirty && !confirm('Ci sono modifiche non salvate. Continuare?')) {
170
+ return;
171
+ }
172
+ this.stateService.reset();
173
+ this.showMessage('Nuovo form creato');
174
+ }
175
+ /** Importa da file JSON. */
176
+ onImportJson() {
177
+ const input = document.createElement('input');
178
+ input.type = 'file';
179
+ input.accept = '.json';
180
+ input.onchange = async (e) => {
181
+ const file = e.target.files[0];
182
+ if (!file)
183
+ return;
184
+ try {
185
+ const schema = await this.persistenceService.importFromJSON(file);
186
+ if (this.state.isDirty && !confirm('Ci sono modifiche non salvate. Sovrascrivere?')) {
187
+ return;
188
+ }
189
+ this.stateService.setSchema(schema);
190
+ this.showMessage('Schema importato con successo');
191
+ }
192
+ catch (error) {
193
+ this.showMessage(error.message || "Errore durante l'import", true);
194
+ }
195
+ };
196
+ input.click();
197
+ }
198
+ /** Esporta come file JSON. */
199
+ onExportJson() {
200
+ try {
201
+ const validation = this.stateService.validateSchema();
202
+ if (!validation.valid) {
203
+ const message = `Schema con errori:\n${validation.errors.map((e) => e.message).join('\n')}`;
204
+ if (!confirm(`${message}\n\nEsportare comunque?`))
205
+ return;
206
+ }
207
+ this.persistenceService.exportToJSON(this.state.schema);
208
+ this.showMessage('Schema esportato con successo');
209
+ }
210
+ catch (error) {
211
+ this.showMessage(error.message || "Errore durante l'export", true);
212
+ }
213
+ }
214
+ /** Pulisce tutto lo schema. */
215
+ onClear() {
216
+ if (!confirm('Vuoi davvero eliminare tutto? Questa azione non puo essere annullata.'))
217
+ return;
218
+ this.persistenceService.createBackup(this.state.schema);
219
+ this.stateService.clearSchema();
220
+ this.showMessage('Schema pulito');
221
+ }
222
+ // ─── Sezioni ─────────────────────────────────────────────────
223
+ onSectionDuplicate(sectionId) {
224
+ this.stateService.duplicateSection(sectionId);
225
+ this.showMessage('Sezione duplicata');
226
+ }
227
+ onSectionDelete(sectionId) {
228
+ if (!confirm('Vuoi davvero eliminare questa sezione?'))
229
+ return;
230
+ this.stateService.removeSection(sectionId);
231
+ this.showMessage('Sezione eliminata');
232
+ }
233
+ // ─── Campi ───────────────────────────────────────────────────
234
+ onFieldSelect(sectionId, fieldKey) {
235
+ this.stateService.selectField(sectionId, fieldKey);
236
+ }
237
+ onFieldDuplicate(sectionId, fieldKey) {
238
+ this.stateService.duplicateField(sectionId, fieldKey);
239
+ this.showMessage('Campo duplicato');
240
+ }
241
+ onFieldDelete(sectionId, fieldKey) {
242
+ if (!confirm('Vuoi davvero eliminare questo campo?'))
243
+ return;
244
+ this.stateService.removeField(sectionId, fieldKey);
245
+ this.showMessage('Campo eliminato');
246
+ }
247
+ onFieldUpdate(sectionId, fieldKey, updates) {
248
+ this.stateService.updateField(sectionId, fieldKey, updates);
249
+ }
250
+ /** Gestisce il drop di un campo (dalla palette o tra sezioni). */
251
+ onFieldDrop(event) {
252
+ const prevId = event.previousContainer.id;
253
+ if (prevId.startsWith('palette-')) {
254
+ // Drop dalla palette
255
+ const paletteItem = event.item.data;
256
+ const section = event.container.data;
257
+ const newField = this.fieldFactory.createDefaultField(paletteItem.type);
258
+ this.stateService.addFieldAtIndex(section.id, newField, event.currentIndex);
259
+ this.showMessage(`Campo ${paletteItem.label} aggiunto`);
260
+ }
261
+ else if (event.previousContainer !== event.container) {
262
+ // Spostamento tra sezioni
263
+ const field = event.item.data;
264
+ const fromSection = event.previousContainer.data;
265
+ const toSection = event.container.data;
266
+ this.stateService.moveFieldBetweenSections(fromSection.id, toSection.id, field.key, event.currentIndex);
267
+ this.showMessage('Campo spostato');
268
+ }
269
+ else {
270
+ // Riordino nella stessa sezione
271
+ const section = event.container.data;
272
+ this.stateService.moveFieldInSection(section.id, event.previousIndex, event.currentIndex);
273
+ }
274
+ this.cdr.markForCheck();
275
+ }
276
+ // ─── Computed properties ─────────────────────────────────────
277
+ /** Campo attualmente selezionato. */
278
+ get selectedField() {
279
+ if (!this.state.selectedFieldKey)
280
+ return null;
281
+ return this.stateService.findFieldByKey(this.state.selectedFieldKey);
282
+ }
283
+ /** ID della sezione del campo selezionato. */
284
+ get selectedFieldSectionId() {
285
+ if (!this.state.selectedFieldKey)
286
+ return null;
287
+ return this.stateService.findSectionByFieldKey(this.state.selectedFieldKey)?.id || null;
288
+ }
289
+ // ─── Tab / Preview ───────────────────────────────────────────
290
+ onTabChange(index) {
291
+ this.selectedTabIndex = index;
292
+ if (index === 1)
293
+ this.refreshPreview();
294
+ }
295
+ refreshPreview() {
296
+ this.previewKey++;
297
+ this.cdr.markForCheck();
298
+ }
299
+ // ─── Dialog ──────────────────────────────────────────────────
300
+ /** Chiude la modale restituendo lo schema corrente. */
301
+ closeDialog() {
302
+ this.dialogRef?.close(this.state.schema);
303
+ }
304
+ // ─── Resize sidebar ──────────────────────────────────────────
305
+ onResizeStart(event) {
306
+ event.preventDefault();
307
+ this.isResizing = true;
308
+ this.resizeStartX = event.clientX;
309
+ this.resizeStartWidth = this.rightSidebarWidth;
310
+ document.addEventListener('mousemove', this.onResizeMove);
311
+ document.addEventListener('mouseup', this.onResizeEnd);
312
+ document.body.style.cursor = 'ew-resize';
313
+ document.body.style.userSelect = 'none';
314
+ }
315
+ // ─── Resize sidebar sinistra ─────────────────────────────────
316
+ onLeftResizeStart(event) {
317
+ event.preventDefault();
318
+ this.isResizingLeft = true;
319
+ this.resizeStartX = event.clientX;
320
+ this.resizeStartWidth = this.leftSidebarWidth;
321
+ document.addEventListener('mousemove', this.onLeftResizeMove);
322
+ document.addEventListener('mouseup', this.onLeftResizeEnd);
323
+ document.body.style.cursor = 'ew-resize';
324
+ document.body.style.userSelect = 'none';
325
+ }
326
+ // ─── Private ─────────────────────────────────────────────────
327
+ checkForRecovery() {
328
+ if (this.persistenceService.hasLocalStorageData()) {
329
+ const age = this.persistenceService.getLocalStorageAge();
330
+ const message = age
331
+ ? `Trovato salvataggio del ${age.toLocaleString('it-IT')}. Vuoi recuperarlo?`
332
+ : 'Trovato salvataggio precedente. Vuoi recuperarlo?';
333
+ const ref = this.snackBar.open(message, 'Recupera', { duration: 10000 });
334
+ ref.onAction().subscribe(() => {
335
+ const schema = this.persistenceService.loadFromLocalStorage();
336
+ if (schema) {
337
+ this.stateService.setSchema(schema);
338
+ this.showMessage('Schema recuperato');
339
+ }
340
+ });
341
+ }
342
+ }
343
+ autoSave() {
344
+ try {
345
+ this.persistenceService.saveToLocalStorage(this.state.schema);
346
+ this.stateService.markAsSaved();
347
+ }
348
+ catch {
349
+ // Silenzioso per auto-save
350
+ }
351
+ }
352
+ updateBreadcrumb() {
353
+ this.breadcrumb = [
354
+ {
355
+ label: this.state.schema.title || 'Form',
356
+ id: this.state.schema.id,
357
+ type: 'form',
358
+ active: !this.state.selectedSectionId && !this.state.selectedFieldKey,
359
+ },
360
+ ];
361
+ if (this.state.selectedSectionId) {
362
+ const section = this.state.schema.sections.find((s) => s.id === this.state.selectedSectionId);
363
+ if (section) {
364
+ this.breadcrumb.push({
365
+ label: section.title || 'Sezione',
366
+ id: section.id,
367
+ type: 'section',
368
+ active: !this.state.selectedFieldKey,
369
+ });
370
+ }
371
+ }
372
+ if (this.state.selectedFieldKey) {
373
+ const field = this.stateService.findFieldByKey(this.state.selectedFieldKey);
374
+ if (field) {
375
+ this.breadcrumb.push({
376
+ label: field.label,
377
+ id: field.key,
378
+ type: 'field',
379
+ active: true,
380
+ });
381
+ }
382
+ }
383
+ }
384
+ updateAvailableFields() {
385
+ const fields = [];
386
+ this.state.schema.sections.forEach((section) => {
387
+ section.fields.forEach((field) => {
388
+ const af = {
389
+ key: field.key,
390
+ label: field.label,
391
+ type: field.type,
392
+ };
393
+ if (field.options && Array.isArray(field.options) && field.options.length > 0) {
394
+ af.options = field.options.map((opt) => ({
395
+ value: opt.value,
396
+ label: opt.label,
397
+ }));
398
+ }
399
+ fields.push(af);
400
+ });
401
+ });
402
+ this.availableFields = fields;
403
+ }
404
+ showMessage(message, isError = false) {
405
+ this.snackBar.open(message, 'Chiudi', {
406
+ duration: 3000,
407
+ panelClass: isError ? ['ui-snackbar-error'] : [],
408
+ });
409
+ }
410
+ loadSidebarWidth() {
411
+ try {
412
+ const savedRight = localStorage.getItem(this.SIDEBAR_WIDTH_KEY);
413
+ if (savedRight) {
414
+ const w = parseInt(savedRight, 10);
415
+ if (!isNaN(w) && w >= this.MIN_SIDEBAR_WIDTH && w <= this.MAX_SIDEBAR_WIDTH) {
416
+ this.rightSidebarWidth = w;
417
+ }
418
+ }
419
+ const savedLeft = localStorage.getItem(this.LEFT_SIDEBAR_WIDTH_KEY);
420
+ if (savedLeft) {
421
+ const w = parseInt(savedLeft, 10);
422
+ if (!isNaN(w) && w >= this.MIN_LEFT_SIDEBAR_WIDTH && w <= this.MAX_LEFT_SIDEBAR_WIDTH) {
423
+ this.leftSidebarWidth = w;
424
+ }
425
+ }
426
+ }
427
+ catch {
428
+ // Silenzioso
429
+ }
430
+ }
431
+ saveSidebarWidth() {
432
+ try {
433
+ localStorage.setItem(this.SIDEBAR_WIDTH_KEY, this.rightSidebarWidth.toString());
434
+ }
435
+ catch {
436
+ // Silenzioso
437
+ }
438
+ }
439
+ saveLeftSidebarWidth() {
440
+ try {
441
+ localStorage.setItem(this.LEFT_SIDEBAR_WIDTH_KEY, this.leftSidebarWidth.toString());
442
+ }
443
+ catch {
444
+ // Silenzioso
445
+ }
446
+ }
447
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UiFormBuilderEditorComponent, deps: [{ token: i1.MatDialogRef, optional: true }, { token: MAT_DIALOG_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
448
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: UiFormBuilderEditorComponent, isStandalone: true, selector: "ui-form-builder-editor", providers: [UiEditorStateService, UiEditorPersistenceService, UiEditorFieldFactoryService], ngImport: i0, template: `
449
+ <div class="editor-root" [class.dialog-mode]="isDialogMode">
450
+ <!-- Header con chiusura (solo in modale) -->
451
+ @if (isDialogMode) {
452
+ <div class="editor-dialog-header">
453
+ <h2>Form Builder - Editor Visuale</h2>
454
+ <ui-button
455
+ icon="x"
456
+ variant="ghost"
457
+ size="md"
458
+ ariaLabel="Chiudi editor"
459
+ tooltip="Chiudi editor"
460
+ (click)="closeDialog()"
461
+ />
462
+ </div>
463
+ }
464
+
465
+ <!-- Toolbar -->
466
+ <ui-editor-toolbar
467
+ [breadcrumb]="breadcrumb"
468
+ [isDirty]="state.isDirty"
469
+ [lastSaved]="state.lastSaved"
470
+ (newForm)="onNewForm()"
471
+ (importJson)="onImportJson()"
472
+ (exportJson)="onExportJson()"
473
+ (save)="onSave()"
474
+ (clear)="onClear()"
475
+ (addSection)="onAddSection()"
476
+ />
477
+
478
+ <!-- Tabs: Editor / Preview -->
479
+ <mat-tab-group
480
+ [selectedIndex]="selectedTabIndex"
481
+ (selectedIndexChange)="onTabChange($event)"
482
+ class="editor-tabs"
483
+ >
484
+ <!-- Tab Editor -->
485
+ <mat-tab label="Editor">
486
+ <div class="editor-layout" cdkDropListGroup>
487
+ <!-- Palette (sidebar sinistra) -->
488
+ <div
489
+ class="editor-sidebar left"
490
+ [style.width.px]="leftSidebarWidth"
491
+ >
492
+ <ui-field-palette />
493
+ <div
494
+ class="resize-handle resize-handle--right"
495
+ [class.resizing]="isResizingLeft"
496
+ (mousedown)="onLeftResizeStart($event)"
497
+ ></div>
498
+ </div>
499
+
500
+ <!-- Area centrale con sezioni -->
501
+ <div class="editor-main">
502
+ <div class="sections-container">
503
+ @for (section of state.schema.sections; track section.id) {
504
+ <ui-section-editor
505
+ [section]="section"
506
+ [isSelected]="state.selectedSectionId === section.id"
507
+ [selectedFieldKey]="state.selectedFieldKey"
508
+ (sectionUpdate)="
509
+ stateService.updateSection(section.id, $event)
510
+ "
511
+ (sectionDelete)="onSectionDelete(section.id)"
512
+ (sectionDuplicate)="onSectionDuplicate(section.id)"
513
+ (fieldSelect)="onFieldSelect(section.id, $event)"
514
+ (fieldDuplicate)="onFieldDuplicate(section.id, $event)"
515
+ (fieldDelete)="onFieldDelete(section.id, $event)"
516
+ (fieldDrop)="onFieldDrop($event)"
517
+ />
518
+ }
519
+
520
+ @if (state.schema.sections.length === 0) {
521
+ <div class="empty-state">
522
+ <lucide-icon
523
+ name="layout-template"
524
+ [size]="64"
525
+ ></lucide-icon>
526
+ <h3>Nessuna sezione presente</h3>
527
+ <p>
528
+ Clicca su "Sezione" nella toolbar per aggiungere la prima
529
+ sezione
530
+ </p>
531
+ <ui-button
532
+ label="Aggiungi Prima Sezione"
533
+ variant="primary"
534
+ icon="plus"
535
+ (click)="onAddSection()"
536
+ />
537
+ </div>
538
+ }
539
+ </div>
540
+ </div>
541
+
542
+ <!-- Config panel (sidebar destra) -->
543
+ <div
544
+ class="editor-sidebar right"
545
+ [style.width.px]="rightSidebarWidth"
546
+ >
547
+ <div
548
+ class="resize-handle"
549
+ [class.resizing]="isResizing"
550
+ (mousedown)="onResizeStart($event)"
551
+ ></div>
552
+ <ui-editor-field-config-panel
553
+ [field]="selectedField"
554
+ [availableFields]="availableFields"
555
+ (fieldUpdate)="
556
+ onFieldUpdate(
557
+ selectedFieldSectionId!,
558
+ state.selectedFieldKey!,
559
+ $event
560
+ )
561
+ "
562
+ />
563
+ </div>
564
+ </div>
565
+ </mat-tab>
566
+
567
+ <!-- Tab Preview -->
568
+ <mat-tab label="Anteprima">
569
+ <ui-editor-preview-container
570
+ [schema]="state.schema"
571
+ [key]="previewKey"
572
+ (refresh)="refreshPreview()"
573
+ />
574
+ </mat-tab>
575
+ </mat-tab-group>
576
+ </div>
577
+ `, isInline: true, styles: ["@use \"../../../core/tokens/mixins\" as ui;.editor-root{display:flex;flex-direction:column;height:100vh;background:var(--ui-color-bg-subtle);&.dialog-mode{height:100%}}.editor-dialog-header{display:flex;align-items:center;justify-content:space-between;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);border-bottom:1px solid var(--ui-color-border);box-shadow:var(--ui-shadow-sm);h2{margin:0;font-size:var(--ui-font-size-lg);font-weight:500;color:var(--ui-color-text)}}.editor-tabs{flex:1;display:flex;flex-direction:column;overflow:hidden;::ng-deep .mat-mdc-tab-header{background:var(--ui-color-surface);border-bottom:1px solid var(--ui-color-border)}::ng-deep .mat-mdc-tab .mdc-tab__text-label{color:var(--ui-color-text-secondary);font-weight:500;font-size:var(--ui-font-size-sm);letter-spacing:.02em}::ng-deep .mat-mdc-tab.mdc-tab--active .mdc-tab__text-label{color:var(--ui-color-primary);font-weight:600}::ng-deep .mat-mdc-tab-header .mdc-tab-indicator__content--underline{border-color:var(--ui-color-primary);border-width:3px}::ng-deep .mat-mdc-tab-body-wrapper{flex:1;overflow:hidden}::ng-deep .mat-mdc-tab-body{height:100%}::ng-deep .mat-mdc-tab-body-content{height:100%;overflow:hidden}}.editor-layout{display:flex;height:100%;overflow:hidden}.editor-sidebar{height:100%;overflow-y:auto;background:var(--ui-color-surface);flex-shrink:0;&.left{position:relative;border-right:1px solid var(--ui-color-border);min-width:200px;max-width:500px}&.right{position:relative;border-left:1px solid var(--ui-color-border);min-width:400px;max-width:1200px}}.editor-main{flex:1;min-width:0;height:100%;overflow-y:auto;padding:var(--ui-spacing-4);background:var(--ui-color-bg-subtle)}.sections-container{max-width:1200px;margin:0 auto;display:flex;flex-direction:column;gap:var(--ui-spacing-4)}.resize-handle{position:absolute;top:0;bottom:0;width:6px;cursor:ew-resize;z-index:10;transition:background-color var(--ui-transition-fast);left:0;&:before{content:\"\";position:absolute;left:-3px;top:0;bottom:0;width:12px}&:hover,&.resizing{background-color:color-mix(in srgb,var(--ui-color-primary) 30%,transparent)}&.resizing{background-color:color-mix(in srgb,var(--ui-color-primary) 50%,transparent)}}.resize-handle--right{left:auto;right:0;&:before{left:auto;right:-3px}}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--ui-spacing-12) var(--ui-spacing-8);text-align:center;color:var(--ui-color-text-muted);lucide-icon{opacity:.4}h3{margin:0 0 var(--ui-spacing-2) 0;font-size:var(--ui-font-size-xl);font-weight:400;color:var(--ui-color-text-secondary)}p{margin:0 0 var(--ui-spacing-6) 0;font-size:var(--ui-font-size-md);color:var(--ui-color-text-muted)}}@media (max-width: 1280px){.editor-sidebar.left{width:250px}}@media (max-width: 960px){.editor-layout{flex-direction:column}.editor-sidebar{&.left{display:none}&.right{position:fixed;right:0;top:64px;width:100%!important;max-width:350px;height:calc(100vh - 64px);z-index:1000;box-shadow:var(--ui-shadow-lg);transform:translate(100%);transition:transform var(--ui-transition-normal);.resize-handle{display:none}}}}\n"], dependencies: [{ kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i3.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i4.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: UiEditorToolbarComponent, selector: "ui-editor-toolbar", inputs: ["breadcrumb", "isDirty", "lastSaved"], outputs: ["newForm", "importJson", "exportJson", "save", "clear", "addSection"] }, { kind: "component", type: UiFieldPaletteComponent, selector: "ui-field-palette" }, { kind: "component", type: UiSectionEditorComponent, selector: "ui-section-editor", inputs: ["section", "isSelected", "selectedFieldKey"], outputs: ["sectionUpdate", "sectionDelete", "sectionDuplicate", "fieldSelect", "fieldDuplicate", "fieldDelete", "fieldDrop"] }, { kind: "component", type: UiEditorFieldConfigPanelComponent, selector: "ui-editor-field-config-panel", inputs: ["field", "availableFields"], outputs: ["fieldUpdate"] }, { kind: "component", type: UiEditorPreviewContainerComponent, selector: "ui-editor-preview-container", inputs: ["schema", "key"], outputs: ["refresh"] }, { kind: "component", type: UiButtonComponent, selector: "ui-button", inputs: ["label", "tooltip", "variant", "size", "icon", "iconPosition", "loading", "disabled", "fullWidth", "type", "ariaLabel", "customClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
578
+ }
579
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UiFormBuilderEditorComponent, decorators: [{
580
+ type: Component,
581
+ args: [{ selector: 'ui-form-builder-editor', standalone: true, imports: [
582
+ DragDropModule,
583
+ MatSnackBarModule,
584
+ MatTabsModule,
585
+ LucideAngularModule,
586
+ UiEditorToolbarComponent,
587
+ UiFieldPaletteComponent,
588
+ UiSectionEditorComponent,
589
+ UiEditorFieldConfigPanelComponent,
590
+ UiEditorPreviewContainerComponent,
591
+ UiButtonComponent,
592
+ ], providers: [UiEditorStateService, UiEditorPersistenceService, UiEditorFieldFactoryService], changeDetection: ChangeDetectionStrategy.OnPush, template: `
593
+ <div class="editor-root" [class.dialog-mode]="isDialogMode">
594
+ <!-- Header con chiusura (solo in modale) -->
595
+ @if (isDialogMode) {
596
+ <div class="editor-dialog-header">
597
+ <h2>Form Builder - Editor Visuale</h2>
598
+ <ui-button
599
+ icon="x"
600
+ variant="ghost"
601
+ size="md"
602
+ ariaLabel="Chiudi editor"
603
+ tooltip="Chiudi editor"
604
+ (click)="closeDialog()"
605
+ />
606
+ </div>
607
+ }
608
+
609
+ <!-- Toolbar -->
610
+ <ui-editor-toolbar
611
+ [breadcrumb]="breadcrumb"
612
+ [isDirty]="state.isDirty"
613
+ [lastSaved]="state.lastSaved"
614
+ (newForm)="onNewForm()"
615
+ (importJson)="onImportJson()"
616
+ (exportJson)="onExportJson()"
617
+ (save)="onSave()"
618
+ (clear)="onClear()"
619
+ (addSection)="onAddSection()"
620
+ />
621
+
622
+ <!-- Tabs: Editor / Preview -->
623
+ <mat-tab-group
624
+ [selectedIndex]="selectedTabIndex"
625
+ (selectedIndexChange)="onTabChange($event)"
626
+ class="editor-tabs"
627
+ >
628
+ <!-- Tab Editor -->
629
+ <mat-tab label="Editor">
630
+ <div class="editor-layout" cdkDropListGroup>
631
+ <!-- Palette (sidebar sinistra) -->
632
+ <div
633
+ class="editor-sidebar left"
634
+ [style.width.px]="leftSidebarWidth"
635
+ >
636
+ <ui-field-palette />
637
+ <div
638
+ class="resize-handle resize-handle--right"
639
+ [class.resizing]="isResizingLeft"
640
+ (mousedown)="onLeftResizeStart($event)"
641
+ ></div>
642
+ </div>
643
+
644
+ <!-- Area centrale con sezioni -->
645
+ <div class="editor-main">
646
+ <div class="sections-container">
647
+ @for (section of state.schema.sections; track section.id) {
648
+ <ui-section-editor
649
+ [section]="section"
650
+ [isSelected]="state.selectedSectionId === section.id"
651
+ [selectedFieldKey]="state.selectedFieldKey"
652
+ (sectionUpdate)="
653
+ stateService.updateSection(section.id, $event)
654
+ "
655
+ (sectionDelete)="onSectionDelete(section.id)"
656
+ (sectionDuplicate)="onSectionDuplicate(section.id)"
657
+ (fieldSelect)="onFieldSelect(section.id, $event)"
658
+ (fieldDuplicate)="onFieldDuplicate(section.id, $event)"
659
+ (fieldDelete)="onFieldDelete(section.id, $event)"
660
+ (fieldDrop)="onFieldDrop($event)"
661
+ />
662
+ }
663
+
664
+ @if (state.schema.sections.length === 0) {
665
+ <div class="empty-state">
666
+ <lucide-icon
667
+ name="layout-template"
668
+ [size]="64"
669
+ ></lucide-icon>
670
+ <h3>Nessuna sezione presente</h3>
671
+ <p>
672
+ Clicca su "Sezione" nella toolbar per aggiungere la prima
673
+ sezione
674
+ </p>
675
+ <ui-button
676
+ label="Aggiungi Prima Sezione"
677
+ variant="primary"
678
+ icon="plus"
679
+ (click)="onAddSection()"
680
+ />
681
+ </div>
682
+ }
683
+ </div>
684
+ </div>
685
+
686
+ <!-- Config panel (sidebar destra) -->
687
+ <div
688
+ class="editor-sidebar right"
689
+ [style.width.px]="rightSidebarWidth"
690
+ >
691
+ <div
692
+ class="resize-handle"
693
+ [class.resizing]="isResizing"
694
+ (mousedown)="onResizeStart($event)"
695
+ ></div>
696
+ <ui-editor-field-config-panel
697
+ [field]="selectedField"
698
+ [availableFields]="availableFields"
699
+ (fieldUpdate)="
700
+ onFieldUpdate(
701
+ selectedFieldSectionId!,
702
+ state.selectedFieldKey!,
703
+ $event
704
+ )
705
+ "
706
+ />
707
+ </div>
708
+ </div>
709
+ </mat-tab>
710
+
711
+ <!-- Tab Preview -->
712
+ <mat-tab label="Anteprima">
713
+ <ui-editor-preview-container
714
+ [schema]="state.schema"
715
+ [key]="previewKey"
716
+ (refresh)="refreshPreview()"
717
+ />
718
+ </mat-tab>
719
+ </mat-tab-group>
720
+ </div>
721
+ `, styles: ["@use \"../../../core/tokens/mixins\" as ui;.editor-root{display:flex;flex-direction:column;height:100vh;background:var(--ui-color-bg-subtle);&.dialog-mode{height:100%}}.editor-dialog-header{display:flex;align-items:center;justify-content:space-between;padding:var(--ui-spacing-3) var(--ui-spacing-4);background:var(--ui-color-surface);border-bottom:1px solid var(--ui-color-border);box-shadow:var(--ui-shadow-sm);h2{margin:0;font-size:var(--ui-font-size-lg);font-weight:500;color:var(--ui-color-text)}}.editor-tabs{flex:1;display:flex;flex-direction:column;overflow:hidden;::ng-deep .mat-mdc-tab-header{background:var(--ui-color-surface);border-bottom:1px solid var(--ui-color-border)}::ng-deep .mat-mdc-tab .mdc-tab__text-label{color:var(--ui-color-text-secondary);font-weight:500;font-size:var(--ui-font-size-sm);letter-spacing:.02em}::ng-deep .mat-mdc-tab.mdc-tab--active .mdc-tab__text-label{color:var(--ui-color-primary);font-weight:600}::ng-deep .mat-mdc-tab-header .mdc-tab-indicator__content--underline{border-color:var(--ui-color-primary);border-width:3px}::ng-deep .mat-mdc-tab-body-wrapper{flex:1;overflow:hidden}::ng-deep .mat-mdc-tab-body{height:100%}::ng-deep .mat-mdc-tab-body-content{height:100%;overflow:hidden}}.editor-layout{display:flex;height:100%;overflow:hidden}.editor-sidebar{height:100%;overflow-y:auto;background:var(--ui-color-surface);flex-shrink:0;&.left{position:relative;border-right:1px solid var(--ui-color-border);min-width:200px;max-width:500px}&.right{position:relative;border-left:1px solid var(--ui-color-border);min-width:400px;max-width:1200px}}.editor-main{flex:1;min-width:0;height:100%;overflow-y:auto;padding:var(--ui-spacing-4);background:var(--ui-color-bg-subtle)}.sections-container{max-width:1200px;margin:0 auto;display:flex;flex-direction:column;gap:var(--ui-spacing-4)}.resize-handle{position:absolute;top:0;bottom:0;width:6px;cursor:ew-resize;z-index:10;transition:background-color var(--ui-transition-fast);left:0;&:before{content:\"\";position:absolute;left:-3px;top:0;bottom:0;width:12px}&:hover,&.resizing{background-color:color-mix(in srgb,var(--ui-color-primary) 30%,transparent)}&.resizing{background-color:color-mix(in srgb,var(--ui-color-primary) 50%,transparent)}}.resize-handle--right{left:auto;right:0;&:before{left:auto;right:-3px}}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--ui-spacing-12) var(--ui-spacing-8);text-align:center;color:var(--ui-color-text-muted);lucide-icon{opacity:.4}h3{margin:0 0 var(--ui-spacing-2) 0;font-size:var(--ui-font-size-xl);font-weight:400;color:var(--ui-color-text-secondary)}p{margin:0 0 var(--ui-spacing-6) 0;font-size:var(--ui-font-size-md);color:var(--ui-color-text-muted)}}@media (max-width: 1280px){.editor-sidebar.left{width:250px}}@media (max-width: 960px){.editor-layout{flex-direction:column}.editor-sidebar{&.left{display:none}&.right{position:fixed;right:0;top:64px;width:100%!important;max-width:350px;height:calc(100vh - 64px);z-index:1000;box-shadow:var(--ui-shadow-lg);transform:translate(100%);transition:transform var(--ui-transition-normal);.resize-handle{display:none}}}}\n"] }]
722
+ }], ctorParameters: () => [{ type: i1.MatDialogRef, decorators: [{
723
+ type: Optional
724
+ }] }, { type: undefined, decorators: [{
725
+ type: Optional
726
+ }, {
727
+ type: Inject,
728
+ args: [MAT_DIALOG_DATA]
729
+ }] }] });
730
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1idWlsZGVyLWVkaXRvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9uZy11aS1zeXN0ZW0vc3JjL2xpYi9jb21wb25lbnRzL2Zvcm0tYnVpbGRlci1lZGl0b3IvZm9ybS1idWlsZGVyLWVkaXRvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFFSCxPQUFPLEVBQ0wsU0FBUyxFQUNULHVCQUF1QixFQUN2QixpQkFBaUIsRUFHakIsTUFBTSxFQUNOLFFBQVEsRUFDUixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFlLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3JFLE9BQU8sRUFBZ0IsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDekUsT0FBTyxFQUFFLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzdFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN6QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFZM0MsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDdkUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDbkYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFL0UsbUJBQW1CO0FBQ25CLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDBEQUEwRCxDQUFDO0FBQ3BHLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHdEQUF3RCxD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UUFBUTs7MEJBQUksTUFBTTsyQkFBQyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIEBtb2R1bGUgbmctdWktc3lzdGVtL2Zvcm0tYnVpbGRlci1lZGl0b3JcclxuICogQ29tcG9uZW50ZSBwcmluY2lwYWxlIGRlbGwnZWRpdG9yIHZpc3VhbGUgZGVsIGZvcm0gYnVpbGRlci5cclxuICpcclxuICogTGF5b3V0IGEgdHJlIHBhbm5lbGxpOlxyXG4gKiAtIFNpbmlzdHJhOiBwYWxldHRlIGRlaSB0aXBpIGRpIGNhbXBvIChkcmFnIHNvdXJjZSlcclxuICogLSBDZW50cm86IHNlemlvbmkgY29uIGNhbXBpIChkcm9wIHRhcmdldCArIGVkaXRvciBpbmxpbmUpXHJcbiAqIC0gRGVzdHJhOiBwYW5uZWxsbyBkaSBjb25maWd1cmF6aW9uZSBkZWwgY2FtcG8gc2VsZXppb25hdG9cclxuICpcclxuICogRnVuemlvbmFsaXRhIHByaW5jaXBhbGk6XHJcbiAqIC0gRHJhZyAmIGRyb3AgZGVpIGNhbXBpIGRhbGxhIHBhbGV0dGUgYWxsZSBzZXppb25pXHJcbiAqIC0gUmlvcmRpbm8gY2FtcGkgYWxsJ2ludGVybm8gZSB0cmEgc2V6aW9uaVxyXG4gKiAtIENvbmZpZ3VyYXppb25lIGNhbXBpIGluIHRlbXBvIHJlYWxlXHJcbiAqIC0gUHJldmlldyBsaXZlIGRlbCBmb3JtXHJcbiAqIC0gSW1wb3J0L2V4cG9ydCBKU09OXHJcbiAqIC0gQXV0by1zYXZlIHN1IGxvY2FsU3RvcmFnZVxyXG4gKi9cclxuXHJcbmltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIE9uSW5pdCxcclxuICBPbkRlc3Ryb3ksXHJcbiAgaW5qZWN0LFxyXG4gIE9wdGlvbmFsLFxyXG4gIEluamVjdCxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ2RrRHJhZ0Ryb3AsIERyYWdEcm9wTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XHJcbmltcG9ydCB7IE1hdERpYWxvZ1JlZiwgTUFUX0RJQUxPR19EQVRBIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcclxuaW1wb3J0IHsgTWF0U25hY2tCYXIsIE1hdFNuYWNrQmFyTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc25hY2stYmFyJztcclxuaW1wb3J0IHsgTWF0VGFic01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYnMnO1xyXG5pbXBvcnQgeyBMdWNpZGVBbmd1bGFyTW9kdWxlIH0gZnJvbSAnbHVjaWRlLWFuZ3VsYXInO1xyXG5pbXBvcnQgeyBTdWJqZWN0LCBpbnRlcnZhbCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQgeyBVaUZvcm1TY2hlbWEsIFVpRm9ybVNlY3Rpb24sIFVpRm9ybUZpZWxkRGVzY3JpcHRvciB9IGZyb20gJy4uL2Zvcm0tYnVpbGRlci90eXBlcy9pbmRleCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIFVpRWRpdG9yU3RhdGUsXHJcbiAgVWlFZGl0b3JCcmVhZGNydW1iSXRlbSxcclxuICBVaUVkaXRvckZpZWxkUGFsZXR0ZUl0ZW0sXHJcbiAgVWlFZGl0b3JBdmFpbGFibGVGaWVsZCxcclxuICBVaUVkaXRvckRpYWxvZ0RhdGEsXHJcbn0gZnJvbSAnLi90eXBlcy9lZGl0b3IudHlwZXMnO1xyXG5cclxuaW1wb3J0IHsgVWlFZGl0b3JTdGF0ZVNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2VkaXRvci1zdGF0ZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVWlFZGl0b3JQZXJzaXN0ZW5jZVNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2VkaXRvci1wZXJzaXN0ZW5jZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVWlFZGl0b3JGaWVsZEZhY3RvcnlTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9maWVsZC1mYWN0b3J5LnNlcnZpY2UnO1xyXG5cclxuLy8gU290dG8tY29tcG9uZW50aVxyXG5pbXBvcnQgeyBVaUVkaXRvclRvb2xiYXJDb21wb25lbnQgfSBmcm9tICcuL3N1Yi1jb21wb25lbnRzL2VkaXRvci10b29sYmFyL2VkaXRvci10b29sYmFyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IFVpRmllbGRQYWxldHRlQ29tcG9uZW50IH0gZnJvbSAnLi9zdWItY29tcG9uZW50cy9maWVsZC1wYWxldHRlL2ZpZWxkLXBhbGV0dGUuY29tcG9uZW50JztcclxuaW1wb3J0IHsgVWlTZWN0aW9uRWRpdG9yQ29tcG9uZW50IH0gZnJvbSAnLi9zdWItY29tcG9uZW50cy9zZWN0aW9uLWVkaXRvci9zZWN0aW9uLWVkaXRvci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBVaUVkaXRvckZpZWxkQ29uZmlnUGFuZWxDb21wb25lbnQgfSBmcm9tICcuL3N1Yi1jb21wb25lbnRzL2ZpZWxkLWNvbmZpZy1wYW5lbC9maWVsZC1jb25maWctcGFuZWwuY29tcG9uZW50JztcclxuaW1wb3J0IHsgVWlFZGl0b3JQcmV2aWV3Q29udGFpbmVyQ29tcG9uZW50IH0gZnJvbSAnLi9zdWItY29tcG9uZW50cy9wcmV2aWV3LWNvbnRhaW5lci9wcmV2aWV3LWNvbnRhaW5lci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBVaUJ1dHRvbkNvbXBvbmVudCB9IGZyb20gJy4uL2J1dHRvbi9pbmRleCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3VpLWZvcm0tYnVpbGRlci1lZGl0b3InLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW1xyXG4gICAgRHJhZ0Ryb3BNb2R1bGUsXHJcbiAgICBNYXRTbmFja0Jhck1vZHVsZSxcclxuICAgIE1hdFRhYnNNb2R1bGUsXHJcbiAgICBMdWNpZGVBbmd1bGFyTW9kdWxlLFxyXG4gICAgVWlFZGl0b3JUb29sYmFyQ29tcG9uZW50LFxyXG4gICAgVWlGaWVsZFBhbGV0dGVDb21wb25lbnQsXHJcbiAgICBVaVNlY3Rpb25FZGl0b3JDb21wb25lbnQsXHJcbiAgICBVaUVkaXRvckZpZWxkQ29uZmlnUGFuZWxDb21wb25lbnQsXHJcbiAgICBVaUVkaXRvclByZXZpZXdDb250YWluZXJDb21wb25lbnQsXHJcbiAgICBVaUJ1dHRvbkNvbXBvbmVudCxcclxuICBdLFxyXG4gIHByb3ZpZGVyczogW1VpRWRpdG9yU3RhdGVTZXJ2aWNlLCBVaUVkaXRvclBlcnNpc3RlbmNlU2VydmljZSwgVWlFZGl0b3JGaWVsZEZhY3RvcnlTZXJ2aWNlXSxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxuICB0ZW1wbGF0ZTogYFxyXG4gICAgPGRpdiBjbGFzcz1cImVkaXRvci1yb290XCIgW2NsYXNzLmRpYWxvZy1tb2RlXT1cImlzRGlhbG9nTW9kZVwiPlxyXG4gICAgICA8IS0tIEhlYWRlciBjb24gY2hpdXN1cmEgKHNvbG8gaW4gbW9kYWxlKSAtLT5cclxuICAgICAgQGlmIChpc0RpYWxvZ01vZGUpIHtcclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZWRpdG9yLWRpYWxvZy1oZWFkZXJcIj5cclxuICAgICAgICAgIDxoMj5Gb3JtIEJ1aWxkZXIgLSBFZGl0b3IgVmlzdWFsZTwvaDI+XHJcbiAgICAgICAgICA8dWktYnV0dG9uXHJcbiAgICAgICAgICAgIGljb249XCJ4XCJcclxuICAgICAgICAgICAgdmFyaWFudD1cImdob3N0XCJcclxuICAgICAgICAgICAgc2l6ZT1cIm1kXCJcclxuICAgICAgICAgICAgYXJpYUxhYmVsPVwiQ2hpdWRpIGVkaXRvclwiXHJcbiAgICAgICAgICAgIHRvb2x0aXA9XCJDaGl1ZGkgZWRpdG9yXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cImNsb3NlRGlhbG9nKClcIlxyXG4gICAgICAgICAgLz5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgfVxyXG5cclxuICAgICAgPCEtLSBUb29sYmFyIC0tPlxyXG4gICAgICA8dWktZWRpdG9yLXRvb2xiYXJcclxuICAgICAgICBbYnJlYWRjcnVtYl09XCJicmVhZGNydW1iXCJcclxuICAgICAgICBbaXNEaXJ0eV09XCJzdGF0ZS5pc0RpcnR5XCJcclxuICAgICAgICBbbGFzdFNhdmVkXT1cInN0YXRlLmxhc3RTYXZlZFwiXHJcbiAgICAgICAgKG5ld0Zvcm0pPVwib25OZXdGb3JtKClcIlxyXG4gICAgICAgIChpbXBvcnRKc29uKT1cIm9uSW1wb3J0SnNvbigpXCJcclxuICAgICAgICAoZXhwb3J0SnNvbik9XCJvbkV4cG9ydEpzb24oKVwiXHJcbiAgICAgICAgKHNhdmUpPVwib25TYXZlKClcIlxyXG4gICAgICAgIChjbGVhcik9XCJvbkNsZWFyKClcIlxyXG4gICAgICAgIChhZGRTZWN0aW9uKT1cIm9uQWRkU2VjdGlvbigpXCJcclxuICAgICAgLz5cclxuXHJcbiAgICAgIDwhLS0gVGFiczogRWRpdG9yIC8gUHJldmlldyAtLT5cclxuICAgICAgPG1hdC10YWItZ3JvdXBcclxuICAgICAgICBbc2VsZWN0ZWRJbmRleF09XCJzZWxlY3RlZFRhYkluZGV4XCJcclxuICAgICAgICAoc2VsZWN0ZWRJbmRleENoYW5nZSk9XCJvblRhYkNoYW5nZSgkZXZlbnQpXCJcclxuICAgICAgICBjbGFzcz1cImVkaXRvci10YWJzXCJcclxuICAgICAgPlxyXG4gICAgICAgIDwhLS0gVGFiIEVkaXRvciAtLT5cclxuICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkVkaXRvclwiPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImVkaXRvci1sYXlvdXRcIiBjZGtEcm9wTGlzdEdyb3VwPlxyXG4gICAgICAgICAgICA8IS0tIFBhbGV0dGUgKHNpZGViYXIgc2luaXN0cmEpIC0tPlxyXG4gICAgICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgICAgY2xhc3M9XCJlZGl0b3Itc2lkZWJhciBsZWZ0XCJcclxuICAgICAgICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwibGVmdFNpZGViYXJXaWR0aFwiXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICA8dWktZmllbGQtcGFsZXR0ZSAvPlxyXG4gICAgICAgICAgICAgIDxkaXZcclxuICAgICAgICAgICAgICAgIGNsYXNzPVwicmVzaXplLWhhbmRsZSByZXNpemUtaGFuZGxlLS1yaWdodFwiXHJcbiAgICAgICAgICAgICAgICBbY2xhc3MucmVzaXppbmddPVwiaXNSZXNpemluZ0xlZnRcIlxyXG4gICAgICAgICAgICAgICAgKG1vdXNlZG93bik9XCJvbkxlZnRSZXNpemVTdGFydCgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICA+PC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgPCEtLSBBcmVhIGNlbnRyYWxlIGNvbiBzZXppb25pIC0tPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZWRpdG9yLW1haW5cIj5cclxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbnMtY29udGFpbmVyXCI+XHJcbiAgICAgICAgICAgICAgICBAZm9yIChzZWN0aW9uIG9mIHN0YXRlLnNjaGVtYS5zZWN0aW9uczsgdHJhY2sgc2VjdGlvbi5pZCkge1xyXG4gICAgICAgICAgICAgICAgICA8dWktc2VjdGlvbi1lZGl0b3JcclxuICAgICAgICAgICAgICAgICAgICBbc2VjdGlvbl09XCJzZWN0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICBbaXNTZWxlY3RlZF09XCJzdGF0ZS5zZWxlY3RlZFNlY3Rpb25JZCA9PT0gc2VjdGlvbi5pZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3NlbGVjdGVkRmllbGRLZXldPVwic3RhdGUuc2VsZWN0ZWRGaWVsZEtleVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKHNlY3Rpb25VcGRhdGUpPVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICBzdGF0ZVNlcnZpY2UudXBkYXRlU2VjdGlvbihzZWN0aW9uLmlkLCAkZXZlbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgICAgICAgICAoc2VjdGlvbkRlbGV0ZSk9XCJvblNlY3Rpb25EZWxldGUoc2VjdGlvbi5pZClcIlxyXG4gICAgICAgICAgICAgICAgICAgIChzZWN0aW9uRHVwbGljYXRlKT1cIm9uU2VjdGlvbkR1cGxpY2F0ZShzZWN0aW9uLmlkKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKGZpZWxkU2VsZWN0KT1cIm9uRmllbGRTZWxlY3Qoc2VjdGlvbi5pZCwgJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKGZpZWxkRHVwbGljYXRlKT1cIm9uRmllbGREdXBsaWNhdGUoc2VjdGlvbi5pZCwgJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKGZpZWxkRGVsZXRlKT1cIm9uRmllbGREZWxldGUoc2VjdGlvbi5pZCwgJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgKGZpZWxkRHJvcCk9XCJvbkZpZWxkRHJvcCgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBAaWYgKHN0YXRlLnNjaGVtYS5zZWN0aW9ucy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LXN0YXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGx1Y2lkZS1pY29uXHJcbiAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwibGF5b3V0LXRlbXBsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgIFtzaXplXT1cIjY0XCJcclxuICAgICAgICAgICAgICAgICAgICA+PC9sdWNpZGUtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICA8aDM+TmVzc3VuYSBzZXppb25lIHByZXNlbnRlPC9oMz5cclxuICAgICAgICAgICAgICAgICAgICA8cD5cclxuICAgICAgICAgICAgICAgICAgICAgIENsaWNjYSBzdSBcIlNlemlvbmVcIiBuZWxsYSB0b29sYmFyIHBlciBhZ2dpdW5nZXJlIGxhIHByaW1hXHJcbiAgICAgICAgICAgICAgICAgICAgICBzZXppb25lXHJcbiAgICAgICAgICAgICAgICAgICAgPC9wPlxyXG4gICAgICAgICAgICAgICAgICAgIDx1aS1idXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPVwiQWdnaXVuZ2kgUHJpbWEgU2V6aW9uZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICB2YXJpYW50PVwicHJpbWFyeVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICBpY29uPVwicGx1c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25BZGRTZWN0aW9uKClcIlxyXG4gICAgICAgICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgIDwhLS0gQ29uZmlnIHBhbmVsIChzaWRlYmFyIGRlc3RyYSkgLS0+XHJcbiAgICAgICAgICAgIDxkaXZcclxuICAgICAgICAgICAgICBjbGFzcz1cImVkaXRvci1zaWRlYmFyIHJpZ2h0XCJcclxuICAgICAgICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwicmlnaHRTaWRlYmFyV2lkdGhcIlxyXG4gICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJyZXNpemUtaGFuZGxlXCJcclxuICAgICAgICAgICAgICAgIFtjbGFzcy5yZXNpemluZ109XCJpc1Jlc2l6aW5nXCJcclxuICAgICAgICAgICAgICAgIChtb3VzZWRvd24pPVwib25SZXNpemVTdGFydCgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICA+PC9kaXY+XHJcbiAgICAgICAgICAgICAgPHVpLWVkaXRvci1maWVsZC1jb25maWctcGFuZWxcclxuICAgICAgICAgICAgICAgIFtmaWVsZF09XCJzZWxlY3RlZEZpZWxkXCJcclxuICAgICAgICAgICAgICAgIFthdmFpbGFibGVGaWVsZHNdPVwiYXZhaWxhYmxlRmllbGRzXCJcclxuICAgICAgICAgICAgICAgIChmaWVsZFVwZGF0ZSk9XCJcclxuICAgICAgICAgICAgICAgICAgb25GaWVsZFVwZGF0ZShcclxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEZpZWxkU2VjdGlvbklkISxcclxuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5zZWxlY3RlZEZpZWxkS2V5ISxcclxuICAgICAgICAgICAgICAgICAgICAkZXZlbnRcclxuICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvbWF0LXRhYj5cclxuXHJcbiAgICAgICAgPCEtLSBUYWIgUHJldmlldyAtLT5cclxuICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkFudGVwcmltYVwiPlxyXG4gICAgICAgICAgPHVpLWVkaXRvci1wcmV2aWV3LWNvbnRhaW5lclxyXG4gICAgICAgICAgICBbc2NoZW1hXT1cInN0YXRlLnNjaGVtYVwiXHJcbiAgICAgICAgICAgIFtrZXldPVwicHJldmlld0tleVwiXHJcbiAgICAgICAgICAgIChyZWZyZXNoKT1cInJlZnJlc2hQcmV2aWV3KClcIlxyXG4gICAgICAgICAgLz5cclxuICAgICAgICA8L21hdC10YWI+XHJcbiAgICAgIDwvbWF0LXRhYi1ncm91cD5cclxuICAgIDwvZGl2PlxyXG4gIGAsXHJcbiAgc3R5bGVzOiBbXHJcbiAgICBgXHJcbiAgICAgIEB1c2UgJy4uLy4uLy4uL2NvcmUvdG9rZW5zL21peGlucycgYXMgdWk7XHJcblxyXG4gICAgICAuZWRpdG9yLXJvb3Qge1xyXG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XHJcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcclxuICAgICAgICBoZWlnaHQ6IDEwMHZoO1xyXG4gICAgICAgIGJhY2tncm91bmQ6IHZhcigtLXVpLWNvbG9yLWJnLXN1YnRsZSk7XHJcblxyXG4gICAgICAgICYuZGlhbG9nLW1vZGUge1xyXG4gICAgICAgICAgaGVpZ2h0OiAxMDAlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLmVkaXRvci1kaWFsb2ctaGVhZGVyIHtcclxuICAgICAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XHJcbiAgICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xyXG4gICAgICAgIHBhZGRpbmc6IHZhcigtLXVpLXNwYWNpbmctMykgdmFyKC0tdWktc3BhY2luZy00KTtcclxuICAgICAgICBiYWNrZ3JvdW5kOiB2YXIoLS11aS1jb2xvci1zdXJmYWNlKTtcclxuICAgICAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tdWktY29sb3ItYm9yZGVyKTtcclxuICAgICAgICBib3gtc2hhZG93OiB2YXIoLS11aS1zaGFkb3ctc20pO1xyXG5cclxuICAgICAgICBoMiB7XHJcbiAgICAgICAgICBtYXJnaW46IDA7XHJcbiAgICAgICAgICBmb250LXNpemU6IHZhcigtLXVpLWZvbnQtc2l6ZS1sZyk7XHJcbiAgICAgICAgICBmb250LXdlaWdodDogNTAwO1xyXG4gICAgICAgICAgY29sb3I6IHZhcigtLXVpLWNvbG9yLXRleHQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogU3RpbGUgcGVyIGlsIHB1bHNhbnRlIGRpIGNoaXVzdXJhIChnZXN0aXRvIGRhIFVpQnV0dG9uKSAqL1xyXG4gICAgICB9XHJcblxyXG4gICAgICAuZWRpdG9yLXRhYnMge1xyXG4gICAgICAgIGZsZXg6IDE7XHJcbiAgICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xyXG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XHJcblxyXG4gICAgICAgIC8qIFN0aWxlIGludGVzdGF6aW9uZSB0YWIgKi9cclxuICAgICAgICA6Om5nLWRlZXAgLm1hdC1tZGMtdGFiLWhlYWRlciB7XHJcbiAgICAgICAgICBiYWNrZ3JvdW5kOiB2YXIoLS11aS1jb2xvci1zdXJmYWNlKTtcclxuICAgICAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS11aS1jb2xvci1ib3JkZXIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogU3RpbGUgZXRpY2hldHRhIHRhYiAqL1xyXG4gICAgICAgIDo6bmctZGVlcCAubWF0LW1kYy10YWIgLm1kYy10YWJfX3RleHQtbGFiZWwge1xyXG4gICAgICAgICAgY29sb3I6IHZhcigtLXVpLWNvbG9yLXRleHQtc2Vjb25kYXJ5KTtcclxuICAgICAgICAgIGZvbnQtd2VpZ2h0OiA1MDA7XHJcbiAgICAgICAgICBmb250LXNpemU6IHZhcigtLXVpLWZvbnQtc2l6ZS1zbSk7XHJcbiAgICAgICAgICBsZXR0ZXItc3BhY2luZzogMC4wMmVtO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogVGFiIGF0dGl2bzogdGVzdG8gZXZpZGVuemlhdG8gKi9cclxuICAgICAgICA6Om5nLWRlZXAgLm1hdC1tZGMtdGFiLm1kYy10YWItLWFjdGl2ZSAubWRjLXRhYl9fdGV4dC1sYWJlbCB7XHJcbiAgICAgICAgICBjb2xvcjogdmFyKC0tdWktY29sb3ItcHJpbWFyeSk7XHJcbiAgICAgICAgICBmb250LXdlaWdodDogNjAwO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogSW5kaWNhdG9yZSB0YWIgYXR0aXZvIChpbmsgYmFyKSAqL1xyXG4gICAgICAgIDo6bmctZGVlcCAubWF0LW1kYy10YWItaGVhZGVyIC5tZGMtdGFiLWluZGljYXRvcl9fY29udGVudC0tdW5kZXJsaW5lIHtcclxuICAgICAgICAgIGJvcmRlci1jb2xvcjogdmFyKC0tdWktY29sb3ItcHJpbWFyeSk7XHJcbiAgICAgICAgICBib3JkZXItd2lkdGg6IDNweDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIDo6bmctZGVlcCAubWF0LW1kYy10YWItYm9keS13cmFwcGVyIHtcclxuICAgICAgICAgIGZsZXg6IDE7XHJcbiAgICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgOjpuZy1kZWVwIC5tYXQtbWRjLXRhYi1ib2R5IHtcclxuICAgICAgICAgIGhlaWdodDogMTAwJTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIDo6bmctZGVlcCAubWF0LW1kYy10YWItYm9keS1jb250ZW50IHtcclxuICAgICAgICAgIGhlaWdodDogMTAwJTtcclxuICAgICAgICAgIG92ZXJmbG93OiBoaWRkZW47XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAuZWRpdG9yLWxheW91dCB7XHJcbiAgICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgICBoZWlnaHQ6IDEwMCU7XHJcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcclxuICAgICAgfVxyXG5cclxuICAgICAgLmVkaXRvci1zaWRlYmFyIHtcclxuICAgICAgICBoZWlnaHQ6IDEwMCU7XHJcbiAgICAgICAgb3ZlcmZsb3cteTogYXV0bztcclxuICAgICAgICBiYWNrZ3JvdW5kOiB2YXIoLS11aS1jb2xvci1zdXJmYWNlKTtcclxuICAgICAgICBmbGV4LXNocmluazogMDtcclxuXHJcbiAgICAgICAgJi5sZWZ0IHtcclxuICAgICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcclxuICAgICAgICAgIGJvcmRlci1yaWdodDogMXB4IHNvbGlkIHZhcigtLXVpLWNvbG9yLWJvcmRlcik7XHJcbiAgICAgICAgICBtaW4td2lkdGg6IDIwMHB4O1xyXG4gICAgICAgICAgbWF4LXdpZHRoOiA1MDBweDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgICYucmlnaHQge1xyXG4gICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xyXG4gICAgICAgICAgYm9yZGVyLWxlZnQ6IDFweCBzb2xpZCB2YXIoLS11aS1jb2xvci1ib3JkZXIpO1xyXG4gICAgICAgICAgbWluLXdpZHRoOiA0MDBweDtcclxuICAgICAgICAgIG1heC13aWR0aDogMTIwMHB4O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLmVkaXRvci1tYWluIHtcclxuICAgICAgICBmbGV4OiAxO1xyXG4gICAgICAgIG1pbi13aWR0aDogMDtcclxuICAgICAgICBoZWlnaHQ6IDEwMCU7XHJcbiAgICAgICAgb3ZlcmZsb3cteTogYXV0bztcclxuICAgICAgICBwYWRkaW5nOiB2YXIoLS11aS1zcGFjaW5nLTQpO1xyXG4gICAgICAgIGJhY2tncm91bmQ6IHZhcigtLXVpLWNvbG9yLWJnLXN1YnRsZSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC5zZWN0aW9ucy1jb250YWluZXIge1xyXG4gICAgICAgIG1heC13aWR0aDogMTIwMHB4O1xyXG4gICAgICAgIG1hcmdpbjogMCBhdXRvO1xyXG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XHJcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcclxuICAgICAgICBnYXA6IHZhcigtLXVpLXNwYWNpbmctNCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC5yZXNpemUtaGFuZGxlIHtcclxuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XHJcbiAgICAgICAgdG9wOiAwO1xyXG4gICAgICAgIGJvdHRvbTogMDtcclxuICAgICAgICB3aWR0aDogNnB4O1xyXG4gICAgICAgIGN1cnNvcjogZXctcmVzaXplO1xyXG4gICAgICAgIHotaW5kZXg6IDEwO1xyXG4gICAgICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQtY29sb3IgdmFyKC0tdWktdHJhbnNpdGlvbi1mYXN0KTtcclxuXHJcbiAgICAgICAgLyogSGFuZGxlIHNpbmlzdHJvIChwZXIgc2lkZWJhciBkZXN0cmEpICovXHJcbiAgICAgICAgbGVmdDogMDtcclxuXHJcbiAgICAgICAgJjo6YmVmb3JlIHtcclxuICAgICAgICAgIGNvbnRlbnQ6ICcnO1xyXG4gICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgICAgICAgbGVmdDogLTNweDtcclxuICAgICAgICAgIHRvcDogMDtcclxuICAgICAgICAgIGJvdHRvbTogMDtcclxuICAgICAgICAgIHdpZHRoOiAxMnB4O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJjpob3ZlcixcclxuICAgICAgICAmLnJlc2l6aW5nIHtcclxuICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IGNvbG9yLW1peChcclxuICAgICAgICAgICAgaW4gc3JnYixcclxuICAgICAgICAgICAgdmFyKC0tdWktY29sb3ItcHJpbWFyeSkgMzAlLFxyXG4gICAgICAgICAgICB0cmFuc3BhcmVudFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgICYucmVzaXppbmcge1xyXG4gICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogY29sb3ItbWl4KFxyXG4gICAgICAgICAgICBpbiBzcmdiLFxyXG4gICAgICAgICAgICB2YXIoLS11aS1jb2xvci1wcmltYXJ5KSA1MCUsXHJcbiAgICAgICAgICAgIHRyYW5zcGFyZW50XHJcbiAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLyogSGFuZGxlIGRlc3RybyAocGVyIHNpZGViYXIgc2luaXN0cmEpICovXHJcbiAgICAgIC5yZXNpemUtaGFuZGxlLS1yaWdodCB7XHJcbiAgICAgICAgbGVmdDogYXV0bztcclxuICAgICAgICByaWdodDogMDtcclxuXHJcbiAgICAgICAgJjo6YmVmb3JlIHtcclxuICAgICAgICAgIGxlZnQ6IGF1dG87XHJcbiAgICAgICAgICByaWdodDogLTNweDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC5lbXB0eS1zdGF0ZSB7XHJcbiAgICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xyXG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XHJcbiAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XHJcbiAgICAgICAgcGFkZGluZzogdmFyKC0tdWktc3BhY2luZy0xMikgdmFyKC0tdWktc3BhY2luZy04KTtcclxuICAgICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XHJcbiAgICAgICAgY29sb3I6IHZhcigtLXVpLWNvbG9yLXRleHQtbXV0ZWQpO1xyXG5cclxuICAgICAgICBsdWNpZGUtaWNvbiB7XHJcbiAgICAgICAgICBvcGFjaXR5OiAwLjQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBoMyB7XHJcbiAgICAgICAgICBtYXJnaW46IDAgMCB2YXIoLS11aS1zcGFjaW5nLTIpIDA7XHJcbiAgICAgICAgICBmb250LXNpemU6IHZhcigtLXVpLWZvbnQtc2l6ZS14bCk7XHJcbiAgICAgICAgICBmb250LXdlaWdodDogNDAwO1xyXG4gICAgICAgICAgY29sb3I6IHZhcigtLXVpLWNvbG9yLXRleHQtc2Vjb25kYXJ5KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHAge1xyXG4gICAgICAgICAgbWFyZ2luOiAwIDAgdmFyKC0tdWktc3BhY2luZy02KSAwO1xyXG4gICAgICAgICAgZm9udC1zaXplOiB2YXIoLS11aS1mb250LXNpemUtbWQpO1xyXG4gICAgICAgICAgY29sb3I6IHZhcigtLXVpLWNvbG9yLXRleHQtbXV0ZWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLyogUmVzcG9uc2l2ZSAqL1xyXG4gICAgICBAbWVkaWEgKG1heC13aWR0aDogMTI4MHB4KSB7XHJcbiAgICAgICAgLmVkaXRvci1zaWRlYmFyLmxlZnQge1xyXG4gICAgICAgICAgd2lkdGg6IDI1MHB4O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgQG1lZGlhIChtYXgtd2lkdGg6IDk2MHB4KSB7XHJcbiAgICAgICAgLmVkaXRvci1sYXlvdXQge1xyXG4gICAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC5lZGl0b3Itc2lkZWJhciB7XHJcbiAgICAgICAgICAmLmxlZnQge1xyXG4gICAgICAgICAgICBkaXNwbGF5OiBub25lO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICYucmlnaHQge1xyXG4gICAgICAgICAgICBwb3NpdGlvbjogZml4ZWQ7XHJcbiAgICAgICAgICAgIHJpZ2h0OiAwO1xyXG4gICAgICAgICAgICB0b3A6IDY0cHg7XHJcbiAgICAgICAgICAgIHdpZHRoOiAxMDAlICFpbXBvcnRhbnQ7XHJcbiAgICAgICAgICAgIG1heC13aWR0aDogMzUwcHg7XHJcbiAgICAgICAgICAgIGhlaWdodDogY2FsYygxMDB2aCAtIDY0cHgpO1xyXG4gICAgICAgICAgICB6LWluZGV4OiAxMDAwO1xyXG4gICAgICAgICAgICBib3gtc2hhZG93OiB2YXIoLS11aS1zaGFkb3ctbGcpO1xyXG4gICAgICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMTAwJSk7XHJcbiAgICAgICAgICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSB2YXIoLS11aS10cmFuc2l0aW9uLW5vcm1hbCk7XHJcblxyXG4gICAgICAgICAgICAucmVzaXplLWhhbmRsZSB7XHJcbiAgICAgICAgICAgICAgZGlzcGxheTogbm9uZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgYCxcclxuICBdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgVWlGb3JtQnVpbGRlckVkaXRvckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuICAvKiogQGludGVybmFsIFNlcnZpemlvIHBlciBsbyBzdGF0byBkZWxsJ2VkaXRvci4gKi9cclxuICByZWFkb25seSBzdGF0ZVNlcnZpY2UgPSBpbmplY3QoVWlFZGl0b3JTdGF0ZVNlcnZpY2UpO1xyXG5cclxuICAvKiogQGludGVybmFsIFNlcnZpemlvIHBlciBsYSBwZXJzaXN0ZW56YS4gKi9cclxuICBwcml2YXRlIHJlYWRvbmx5IHBlcnNpc3RlbmNlU2VydmljZSA9IGluamVjdChVaUVkaXRvclBlcnNpc3RlbmNlU2VydmljZSk7XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgRmFjdG9yeSBwZXIgaSBjYW1waS4gKi9cclxuICBwcml2YXRlIHJlYWRvbmx5IGZpZWxkRmFjdG9yeSA9IGluamVjdChVaUVkaXRvckZpZWxkRmFjdG9yeVNlcnZpY2UpO1xyXG5cclxuICAvKiogQGludGVybmFsIFNuYWNrIGJhciBwZXIgaSBtZXNzYWdnaS4gKi9cclxuICBwcml2YXRlIHJlYWRvbmx5IHNuYWNrQmFyID0gaW5qZWN0KE1hdFNuYWNrQmFyKTtcclxuXHJcbiAgLyoqIEBpbnRlcm5hbCBDaGFuZ2UgZGV0ZWN0b3IuICovXHJcbiAgcHJpdmF0ZSByZWFkb25seSBjZHIgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xyXG5cclxuICAvKiogQGludGVybmFsIFN1YmplY3QgcGVyIGxhIGRpc3RydXppb25lLiAqL1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG5cclxuICAvKiogU3RhdG8gY29ycmVudGUgZGVsbCdlZGl0b3IuICovXHJcbiAgc3RhdGU6IFVpRWRpdG9yU3RhdGU7XHJcblxyXG4gIC8qKiBJbmRpY2UgZGVsIHRhYiBzZWxlemlvbmF0byAoMD1FZGl0b3IsIDE9UHJldmlldykuICovXHJcbiAgc2VsZWN0ZWRUYWJJbmRleCA9IDA7XHJcblxyXG4gIC8qKiBCcmVhZGNydW1iIGRpIG5hdmlnYXppb25lLiAqL1xyXG4gIGJyZWFkY3J1bWI6IFVpRWRpdG9yQnJlYWRjcnVtYkl0ZW1bXSA9IFtdO1xyXG5cclxuICAvKiogU2UgaWwgY29tcG9uZW50ZSBlIGFwZXJ0byBpbiBtb2RhbGl0YSBkaWFsb2cuICovXHJcbiAgaXNEaWFsb2dNb2RlID0gZmFsc2U7XHJcblxyXG4gIC8qKiBDaGlhdmUgcGVyIGZvcnphcmUgaWwgcmUtcmVuZGVyIGRlbCBwcmV2aWV3LiAqL1xyXG4gIHByZXZpZXdLZXkgPSAwO1xyXG5cclxuICAvKiogQ2FtcGkgZGlzcG9uaWJpbGkgcGVyIGxlIGNvbmRpemlvbmkgKGNhY2hlKS4gKi9cclxuICBhdmFpbGFibGVGaWVsZHM6IFVpRWRpdG9yQXZhaWxhYmxlRmllbGRbXSA9IFtdO1xyXG5cclxuICAvKiogTGFyZ2hlenphIGRlbGxhIHNpZGViYXIgc2luaXN0cmEgKHB4KS4gKi9cclxuICBsZWZ0U2lkZWJhcldpZHRoID0gMjgwO1xyXG5cclxuICAvKiogTGFyZ2hlenphIGRlbGxhIHNpZGViYXIgZGVzdHJhIChweCkuICovXHJcbiAgcmlnaHRTaWRlYmFyV2lkdGggPSA0NjA7XHJcblxyXG4gIC8qKiBTZSBlIGluIGNvcnNvIGlsIHJlc2l6ZSBkZWxsYSBzaWRlYmFyIGRlc3RyYS4gKi9cclxuICBpc1Jlc2l6aW5nID0gZmFsc2U7XHJcblxyXG4gIC8qKiBTZSBlIGluIGNvcnNvIGlsIHJlc2l6ZSBkZWxsYSBzaWRlYmFyIHNpbmlzdHJhLiAqL1xyXG4gIGlzUmVzaXppbmdMZWZ0ID0gZmFsc2U7XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgTGltaXRpIGRpIHJlc2l6ZSBzaWRlYmFyIGRlc3RyYS4gKi9cclxuICBwcml2YXRlIHJlYWRvbmx5IE1JTl9TSURFQkFSX1dJRFRIID0gNDAwO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgTUFYX1NJREVCQVJfV0lEVEggPSAxMjAwO1xyXG5cclxuICAvKiogQGludGVybmFsIExpbWl0aSBkaSByZXNpemUgc2lkZWJhciBzaW5pc3RyYS4gKi9cclxuICBwcml2YXRlIHJlYWRvbmx5IE1JTl9MRUZUX1NJREVCQVJfV0lEVEggPSAyMDA7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBNQVhfTEVGVF9TSURFQkFSX1dJRFRIID0gNTAwO1xyXG5cclxuICBwcml2YXRlIHJlc2l6ZVN0YXJ0WCA9IDA7XHJcbiAgcHJpdmF0ZSByZXNpemVTdGFydFdpZHRoID0gMDtcclxuICBwcml2YXRlIHJlYWRvbmx5IFNJREVCQVJfV0lEVEhfS0VZID0gJ3VpLWVkaXRvci1yaWdodC1zaWRlYmFyLXdpZHRoJztcclxuICBwcml2YXRlIHJlYWRvbmx5IExFRlRfU0lERUJBUl9XSURUSF9LRVkgPSAndWktZWRpdG9yLWxlZnQtc2lkZWJhci13aWR0aCc7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgQE9wdGlvbmFsKCkgcHVibGljIGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPFVpRm9ybUJ1aWxkZXJFZGl0b3JDb21wb25lbnQ+LFxyXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChNQVRfRElBTE9HX0RBVEEpIHB1YmxpYyBkaWFsb2dEYXRhOiBVaUVkaXRvckRpYWxvZ0RhdGEsXHJcbiAgKSB7XHJcbiAgICB0aGlzLnN0YXRlID0gdGhpcy5zdGF0ZVNlcnZpY2UuZ2V0Q3VycmVudFN0YXRlKCk7XHJcbiAgICB0aGlzLmlzRGlhbG9nTW9kZSA9ICEhdGhpcy5kaWFsb2dSZWY7XHJcblxyXG4gICAgLy8gQ2FyaWNhIHNjaGVtYSBpbml6aWFsZSBzZSBmb3JuaXRvIHZpYSBkaWFsb2cgZGF0YVxyXG4gICAgaWYgKHRoaXMuZGlhbG9nRGF0YT8uaW5pdGlhbFNjaGVtYSkge1xyXG4gICAgICB0aGlzLnN0YXRlU2VydmljZS5zZXRTY2hlbWEodGhpcy5kaWFsb2dEYXRhLmluaXRpYWxTY2hlbWEpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMubG9hZFNpZGViYXJXaWR0aCgpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICAvLyBTb3R0b3Njcml6aW9uZSBhbGxvIHN0YXRvXHJcbiAgICB0aGlzLnN0YXRlU2VydmljZS5zdGF0ZSQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoc3RhdGUpID0+IHtcclxuICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xyXG4gICAgICB0aGlzLnVwZGF0ZUJyZWFkY3J1bWIoKTtcclxuICAgICAgdGhpcy51cGRhdGVBdmFpbGFibGVGaWVsZHMoKTtcclxuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBDb250cm9sbGEgc2FsdmF0YWdnaSBwcmVjZWRlbnRpIGRhIHJlY3VwZXJhcmVcclxuICAgIHRoaXMuY2hlY2tGb3JSZWNvdmVyeSgpO1xyXG5cclxuICAgIC8vIEF1dG8tc2F2ZSBvZ25pIDMwIHNlY29uZGlcclxuICAgIGludGVydmFsKDMwMDAwKVxyXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXHJcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmlzRGlydHkpIHtcclxuICAgICAgICAgIHRoaXMuYXV0b1NhdmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcclxuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcclxuICB9XHJcblxyXG4gIC8vIOKUgOKUgOKUgCBUb29sYmFyIGFjdGlvbnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcblxyXG4gIC8qKiBBZ2dpdW5nZSB1bmEgbnVvdmEgc2V6aW9uZS4gKi9cclxuICBvbkFkZFNlY3Rpb24oKTogdm9pZCB7XHJcbiAgICB0aGlzLnN0YXRlU2VydmljZS5hZGRTZWN0aW9uKCk7XHJcbiAgICB0aGlzLnNob3dNZXNzYWdlKCdTZXppb25lIGFnZ2l1bnRhJyk7XHJcbiAgfVxyXG5cclxuICAvKiogU2FsdmEgbmVsIGxvY2FsU3RvcmFnZS4gKi9cclxuICBvblNhdmUoKTogdm9pZCB7XHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLnBlcnNpc3RlbmNlU2VydmljZS5zYXZlVG9Mb2NhbFN0b3JhZ2UodGhpcy5zdGF0ZS5zY2hlbWEpO1xyXG4gICAgICB0aGlzLnN0YXRlU2VydmljZS5tYXJrQXNTYXZlZCgpO1xyXG4gICAgICB0aGlzLnNob3dNZXNzYWdlKCdTYWx2YXRvIGNvbiBzdWNjZXNzbycpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xyXG4gICAgICB0aGlzLnNob3dNZXNzYWdlKGVycm9yLm1lc3NhZ2UgfHwgJ0Vycm9yZSBkdXJhbnRlIGlsIHNhbHZhdGFnZ2lvJywgdHJ1ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogQ3JlYSB1biBudW92byBmb3JtLiAqL1xyXG4gIG9uTmV3Rm9ybSgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnN0YXRlLmlzRGlydHkgJiYgIWNvbmZpcm0oJ0NpIHNvbm8gbW9kaWZpY2hlIG5vbiBzYWx2YXRlLiBDb250aW51YXJlPycpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMuc3RhdGVTZXJ2aWNlLnJlc2V0KCk7XHJcbiAgICB0aGlzLnNob3dNZXNzYWdlKCdOdW92byBmb3JtIGNyZWF0bycpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEltcG9ydGEgZGEgZmlsZSBKU09OLiAqL1xyXG4gIG9uSW1wb3J0SnNvbigpOiB2b2lkIHtcclxuICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcclxuICAgIGlucHV0LnR5cGUgPSAnZmlsZSc7XHJcbiAgICBpbnB1dC5hY2NlcHQgPSAnLmpzb24nO1xyXG5cclxuICAgIGlucHV0Lm9uY2hhbmdlID0gYXN5bmMgKGU6IGFueSkgPT4ge1xyXG4gICAgICBjb25zdCBmaWxlID0gZS50YXJnZXQuZmlsZXNbMF07XHJcbiAgICAgIGlmICghZmlsZSkgcmV0dXJuO1xyXG5cclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCB0aGlzLnBlcnNpc3RlbmNlU2VydmljZS5pbXBvcnRGcm9tSlNPTihmaWxlKTtcclxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5pc0RpcnR5ICYmICFjb25maXJtKCdDaSBzb25vIG1vZGlmaWNoZSBub24gc2FsdmF0ZS4gU292cmFzY3JpdmVyZT8nKSkge1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnN0YXRlU2VydmljZS5zZXRTY2hlbWEoc2NoZW1hKTtcclxuICAgICAgICB0aGlzLnNob3dNZXNzYWdlKCdTY2hlbWEgaW1wb3J0YXRvIGNvbiBzdWNjZXNzbycpO1xyXG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XHJcbiAgICAgICAgdGhpcy5zaG93TWVzc2FnZShlcnJvci5tZXNzYWdlIHx8IFwiRXJyb3JlIGR1cmFudGUgbCdpbXBvcnRcIiwgdHJ1ZSk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgaW5wdXQuY2xpY2soKTtcclxuICB9XHJcblxyXG4gIC8qKiBFc3BvcnRhIGNvbWUgZmlsZSBKU09OLiAqL1xyXG4gIG9uRXhwb3J0SnNvbigpOiB2b2lkIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIGNvbnN0IHZhbGlkYXRpb24gPSB0aGlzLnN0YXRlU2VydmljZS52YWxpZGF0ZVNjaGVtYSgpO1xyXG4gICAgICBpZiAoIXZhbGlkYXRpb24udmFsaWQpIHtcclxuICAgICAgICBjb25zdCBtZXNzYWdlID0gYFNjaGVtYSBjb24gZXJyb3JpOlxcbiR7dmFsaWRhdGlvbi5lcnJvcnMubWFwKChlKSA9PiBlLm1lc3NhZ2UpLmpvaW4oJ1xcbicpfWA7XHJcbiAgICAgICAgaWYgKCFjb25maXJtKGAke21lc3NhZ2V9XFxuXFxuRXNwb3J0YXJlIGNvbXVucXVlP2ApKSByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5wZXJzaXN0ZW5jZVNlcnZpY2UuZXhwb3J0VG9KU09OKHRoaXMuc3RhdGUuc2NoZW1hKTtcclxuICAgICAgdGhpcy5zaG93TWVzc2FnZSgnU2NoZW1hIGVzcG9ydGF0byBjb24gc3VjY2Vzc28nKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcclxuICAgICAgdGhpcy5zaG93TWVzc2FnZShlcnJvci5tZXNzYWdlIHx8IFwiRXJyb3JlIGR1cmFudGUgbCdleHBvcnRcIiwgdHJ1ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogUHVsaXNjZSB0dXR0byBsbyBzY2hlbWEuICovXHJcbiAgb25DbGVhcigpOiB2b2lkIHtcclxuICAgIGlmICghY29uZmlybSgnVnVvaSBkYXZ2ZXJvIGVsaW1pbmFyZSB0dXR0bz8gUXVlc3RhIGF6aW9uZSBub24gcHVvIGVzc2VyZSBhbm51bGxhdGEuJykpIHJldHVybjtcclxuICAgIHRoaXMucGVyc2lzdGVuY2VTZXJ2aWNlLmNyZWF0ZUJhY2t1cCh0aGlzLnN0YXRlLnNjaGVtYSk7XHJcbiAgICB0aGlzLnN0YXRlU2VydmljZS5jbGVhclNjaGVtYSgpO1xyXG4gICAgdGhpcy5zaG93TWVzc2FnZSgnU2NoZW1hIHB1bGl0bycpO1xyXG4gIH1cclxuXHJcbiAgLy8g4pSA4pSA4pSAIFNlemlvbmkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcblxyXG4gIG9uU2VjdGlvbkR1cGxpY2F0ZShzZWN0aW9uSWQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy5zdGF0ZVNlcnZpY2UuZHVwbGljYXRlU2VjdGlvbihzZWN0aW9uSWQpO1xyXG4gICAgdGhpcy5zaG93TWVzc2FnZSgnU2V6aW9uZSBkdXBsaWNhdGEnKTtcclxuICB9XHJcblxyXG4gIG9uU2VjdGlvbkRlbGV0ZShzZWN0aW9uSWQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgaWYgKCFjb25maXJtKCdWdW9pIGRhdnZlcm8gZWxpbWluYXJlIHF1ZXN0YSBzZXppb25lPycpKSByZXR1cm47XHJcbiAgICB0aGlzLnN0YXRlU2VydmljZS5yZW1vdmVTZWN0aW9uKHNlY3Rpb25JZCk7XHJcbiAgICB0aGlzLnNob3dNZXNzYWdlKCdTZXppb25lIGVsaW1pbmF0YScpO1xyXG4gIH1cclxuXHJcbiAgLy8g4pSA4pSA4pSAIENhbXBpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuICBvbkZpZWxkU2VsZWN0KHNlY3Rpb25JZDogc3RyaW5nLCBmaWVsZEtleTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICB0aGlzLnN0YXRlU2VydmljZS5zZWxlY3RGaWVsZChzZWN0aW9uSWQsIGZpZWxkS2V5KTtcclxuICB9XHJcblxyXG4gIG9uRmllbGREdXBsaWNhdGUoc2VjdGlvbklkOiBzdHJpbmcsIGZpZWxkS2V5OiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRoaXMuc3RhdGVTZXJ2aWNlLmR1cGxpY2F0ZUZpZWxkKHNlY3Rpb25JZCwgZmllbGRLZXkpO1xyXG4gICAgdGhpcy5zaG93TWVzc2FnZSgnQ2FtcG8gZHVwbGljYXRvJyk7XHJcbiAgfVxyXG5cclxuICBvbkZpZWxkRGVsZXRlKHNlY3Rpb25JZDogc3RyaW5nLCBmaWVsZEtleTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBpZiAoIWNvbmZpcm0oJ1Z1b2kgZGF2dmVybyBlbGltaW5hcmUgcXVlc3RvIGNhbXBvPycpKSByZXR1cm47XHJcbiAgICB0aGlzLnN0YXRlU2VydmljZS5yZW1vdmVGaWVsZChzZWN0aW9uSWQsIGZpZWxkS2V5KTtcclxuICAgIHRoaXMuc2hvd01lc3NhZ2UoJ0NhbXBvIGVsaW1pbmF0bycpO1xyXG4gIH1cclxuXHJcbiAgb25GaWVsZFVwZGF0ZShzZWN0aW9uSWQ6IHN0cmluZywgZmllbGRLZXk6IHN0cmluZywgdXBkYXRlczogUGFydGlhbDxVaUZvcm1GaWVsZERlc2NyaXB0b3I+KTogdm9pZCB7XHJcbiAgICB0aGlzLnN0YXRlU2VydmljZS51cGRhdGVGaWVsZChzZWN0aW9uSWQsIGZpZWxkS2V5LCB1cGRhdGVzKTtcclxuICB9XHJcblxyXG4gIC8qKiBHZXN0aXNjZSBpbCBkcm9wIGRpIHVuIGNhbXBvIChkYWxsYSBwYWxldHRlIG8gdHJhIHNlemlvbmkpLiAqL1xyXG4gIG9uRmllbGREcm9wKGV2ZW50OiBDZGtEcmFnRHJvcDxhbnk+KTogdm9pZCB7XHJcbiAgICBjb25zdCBwcmV2SWQgPSBldmVudC5wcmV2aW91c0NvbnRhaW5lci5pZDtcclxuXHJcbiAgICBpZiAocHJldklkLnN0YXJ0c1dpdGgoJ3BhbGV0dGUtJykpIHtcclxuICAgICAgLy8gRHJvcCBkYWxsYSBwYWxldHRlXHJcbiAgICAgIGNvbnN0IHBhbGV0dGVJdGVtOiBVaUVkaXRvckZpZWxkUGFsZXR0ZUl0ZW0gPSBldmVudC5pdGVtLmRhdGE7XHJcbiAgICAgIGNvbnN0IHNlY3Rpb246IFVpRm9ybVNlY3Rpb24gPSBldmVudC5jb250YWluZXIuZGF0YTtcclxuICAgICAgY29uc3QgbmV3RmllbGQgPSB0aGlzLmZpZWxkRmFjdG9yeS5jcmVhdGVEZWZhdWx0RmllbGQocGFsZXR0ZUl0ZW0udHlwZSk7XHJcbiAgICAgIHRoaXMuc3RhdGVTZXJ2aWNlLmFkZEZpZWxkQXRJbmRleChzZWN0aW9uLmlkLCBuZXdGaWVsZCwgZXZlbnQuY3VycmVudEluZGV4KTtcclxuICAgICAgdGhpcy5zaG93TWVzc2FnZShgQ2FtcG8gJHtwYWxldHRlSXRlbS5sYWJlbH0gYWdnaXVudG9gKTtcclxuICAgIH0gZWxzZSBpZiAoZXZlbnQucHJldmlvdXNDb250YWluZXIgIT09IGV2ZW50LmNvbnRhaW5lcikge1xyXG4gICAgICAvLyBTcG9zdGFtZW50byB0cmEgc2V6aW9uaVxyXG4gICAgICBjb25zdCBmaWVsZDogVWlGb3JtRmllbGREZXNjcmlwdG9yID0gZXZlbnQuaXRlbS5kYXRhO1xyXG4gICAgICBjb25zdCBmcm9tU2VjdGlvbjogVWlGb3JtU2VjdGlvbiA9IGV2ZW50LnByZXZpb3VzQ29udGFpbmVyLmRhdGE7XHJcbiAgICAgIGNvbnN0IHRvU2VjdGlvbjogVWlGb3JtU2VjdGlvbiA9IGV2ZW50LmNvbnRhaW5lci5kYXRhO1xyXG4gICAgICB0aGlzLnN0YXRlU2VydmljZS5tb3ZlRmllbGRCZXR3ZWVuU2VjdGlvbnMoZnJvbVNlY3Rpb24uaWQsIHRvU2VjdGlvbi5pZCwgZmllbGQua2V5LCBldmVudC5jdXJyZW50SW5kZXgpO1xyXG4gICAgICB0aGlzLnNob3dNZXNzYWdlKCdDYW1wbyBzcG9zdGF0bycpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gUmlvcmRpbm8gbmVsbGEgc3Rlc3NhIHNlemlvbmVcclxuICAgICAgY29uc3Qgc2VjdGlvbjogVWlGb3JtU2VjdGlvbiA9IGV2ZW50LmNvbnRhaW5lci5kYXRhO1xyXG4gICAgICB0aGlzLnN0YXRlU2VydmljZS5tb3ZlRmllbGRJblNlY3Rpb24oc2VjdGlvbi5pZCwgZXZlbnQucHJldmlvdXNJbmRleCwgZXZlbnQuY3VycmVudEluZGV4KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcclxuICB9XHJcblxyXG4gIC8vIOKUgOKUgOKUgCBDb21wdXRlZCBwcm9wZXJ0aWVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuICAvKiogQ2FtcG8gYXR0dWFsbWVudGUgc2VsZXppb25hdG8uICovXHJcbiAgZ2V0IHNlbGVjdGVkRmllbGQoKTogVWlGb3JtRmllbGREZXNjcmlwdG9yIHwgbnVsbCB7XHJcbiAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0ZWRGaWVsZEtleSkgcmV0dXJuIG51bGw7XHJcbiAgICByZXR1cm4gdGhpcy5zdGF0ZVNlcnZpY2UuZmluZEZpZWxkQnlLZXkodGhpcy5zdGF0ZS5zZWxlY3RlZEZpZWxkS2V5KTtcclxuICB9XHJcblxyXG4gIC8qKiBJRCBkZWxsYSBzZXppb25lIGRlbCBjYW1wbyBzZWxlemlvbmF0by4gKi9cclxuICBnZXQgc2VsZWN0ZWRGaWVsZFNlY3Rpb25JZCgpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGlmICghdGhpcy5zdGF0ZS5zZWxlY3RlZEZpZWxkS2V5KSByZXR1cm4gbnVsbDtcclxuICAgIHJldHVybiB0aGlzLnN0YXRlU2VydmljZS5maW5kU2VjdGlvbkJ5RmllbGRLZXkodGhpcy5zdGF0ZS5zZWxlY3RlZEZpZWxkS2V5KT8uaWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIC8vIOKUgOKUgOKUgCBUYWIgLyBQcmV2aWV3IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuICBvblRhYkNoYW5nZShpbmRleDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICB0aGlzLnNlbGVjdGVkVGFiSW5kZXggPSBpbmRleDtcclxuICAgIGlmIChpbmRleCA9PT0gMSkgdGhpcy5yZWZyZXNoUHJldmlldygpO1xyXG4gIH1cclxuXHJcbiAgcmVmcmVzaFByZXZpZXcoKTogdm9pZCB7XHJcbiAgICB0aGlzLnByZXZpZXdLZXkrKztcclxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gIH1cclxuXHJcbiAgLy8g4pSA4pSA4pSAIERpYWxvZyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbiAgLyoqIENoaXVkZSBsYSBtb2RhbGUgcmVzdGl0dWVuZG8gbG8gc2NoZW1hIGNvcnJlbnRlLiAqL1xyXG4gIGNsb3NlRGlhbG9nKCk6IHZvaWQge1xyXG4gICAgdGhpcy5kaWFsb2dSZWY/LmNsb3NlKHRoaXMuc3RhdGUuc2NoZW1hKTtcclxuICB9XHJcblxyXG4gIC8vIOKUgOKUgOKUgCBSZXNpemUgc2lkZWJhciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbiAgb25SZXNpemVTdGFydChldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xyXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIHRoaXMuaXNSZXNpemluZyA9IHRydWU7XHJcbiAgICB0aGlzLnJlc2l6ZVN0YXJ0WCA9IGV2ZW50LmNsaWVudFg7XHJcbiAgICB0aGlzLnJlc2l6ZVN0YXJ0V2lkdGggPSB0aGlzLnJpZ2h0U2lkZWJhcldpZHRoO1xyXG5cclxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMub25SZXNpemVNb3ZlKTtcclxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm9uUmVzaXplRW5kKTtcclxuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUuY3Vyc29yID0gJ2V3LXJlc2l6ZSc7XHJcbiAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnVzZXJTZWxlY3QgPSAnbm9uZSc7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIG9uUmVzaXplTW92ZSA9IChldmVudDogTW91c2VFdmVudCk6IHZvaWQgPT4ge1xyXG4gICAgaWYgKCF0aGlzLmlzUmVzaXppbmcpIHJldHVybjtcclxuICAgIGNvbnN0IGRlbHRhID0gdGhpcy5yZXNpemVTdGFydFggLSBldmVudC5jbGllbnRYO1xyXG4gICAgdGhpcy5yaWdodFNpZGViYXJXaWR0aCA9IE1hdGgubWF4KFxyXG4gICAgICB0aGlzLk1JTl9TSURFQkFSX1dJRFRILFxyXG4gICAgICBNYXRoLm1pbih0aGlzLk1BWF9TSURFQkFSX1dJRFRILCB0aGlzLnJlc2l6ZVN0YXJ0V2lkdGggKyBkZWx0YSksXHJcbiAgICApO1xyXG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgfTtcclxuXHJcbiAgcHJpdmF0ZSBvblJlc2l6ZUVuZCA9ICgpOiB2b2lkID0+IHtcclxuICAgIGlmICghdGhpcy5pc1Jlc2l6aW5nKSByZXR1cm47XHJcbiAgICB0aGlzLmlzUmVzaXppbmcgPSBmYWxzZTtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMub25SZXNpemVNb3ZlKTtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm9uUmVzaXplRW5kKTtcclxuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUuY3Vyc29yID0gJyc7XHJcbiAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnVzZXJTZWxlY3QgPSAnJztcclxuICAgIHRoaXMuc2F2ZVNpZGViYXJXaWR0aCgpO1xyXG4gIH07XHJcblxyXG4gIC8vIOKUgOKUgOKUgCBSZXNpemUgc2lkZWJhciBzaW5pc3RyYSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbiAgb25MZWZ0UmVzaXplU3RhcnQoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcclxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB0aGlzLmlzUmVzaXppbmdMZWZ0ID0gdHJ1ZTtcclxuICAgIHRoaXMucmVzaXplU3RhcnRYID0gZXZlbnQuY2xpZW50WDtcclxuICAgIHRoaXMucmVzaXplU3RhcnRXaWR0aCA9IHRoaXMubGVmdFNpZGViYXJXaWR0aDtcclxuXHJcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLm9uTGVmdFJlc2l6ZU1vdmUpO1xyXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMub25MZWZ0UmVzaXplRW5kKTtcclxuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUuY3Vyc29yID0gJ2V3LXJlc2l6ZSc7XHJcbiAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnVzZXJTZWxlY3QgPSAnbm9uZSc7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIG9uTGVmdFJlc2l6ZU1vdmUgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcclxuICAgIGlmICghdGhpcy5pc1Jlc2l6aW5nTGVmdCkgcmV0dXJuO1xyXG4gICAgY29uc3QgZGVsdGEgPSBldmVudC5jbGllbnRYIC0gdGhpcy5yZXNpemVTdGFydFg7XHJcbiAgICB0aGlzLmxlZnRTaWRlYmFyV2lkdGggPSBNYXRoLm1heChcclxuICAgICAgdGhpcy5NSU5fTEVGVF9TSURFQkFSX1dJRFRILFxyXG4gICAgICBNYXRoLm1pbih0aGlzLk1BWF9MRUZUX1NJREVCQVJfV0lEVEgsIHRoaXMucmVzaXplU3RhcnRXaWR0aCArIGRlbHRhKSxcclxuICAgICk7XHJcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcclxuICB9O1xyXG5cclxuICBwcml2YXRlIG9uTGVmdFJlc2l6ZUVuZCA9ICgpOiB2b2lkID0+IHtcclxuICAgIGlmICghdGhpcy5pc1Jlc2l6aW5nTGVmdCkgcmV0dXJuO1xyXG4gICAgdGhpcy5pc1Jlc2l6aW5nTGVmdCA9IGZhbHNlO1xyXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5vbkxlZnRSZXNpemVNb3ZlKTtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm9uTGVmdFJlc2l6ZUVuZCk7XHJcbiAgICBkb2N1bWVudC5ib2R5LnN0eWxlLmN1cnNvciA9ICcnO1xyXG4gICAgZG9jdW1lbnQuYm9keS5zdHlsZS51c2VyU2VsZWN0ID0gJyc7XHJcbiAgICB0aGlzLnNhdmVMZWZ0U2lkZWJhcldpZHRoKCk7XHJcbiAgfTtcclxuXHJcbiAgLy8g4pSA4pSA4pSAIFByaXZhdGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcblxyXG4gIHByaXZhdGUgY2hlY2tGb3JSZWNvdmVyeSgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnBlcnNpc3RlbmNlU2VydmljZS5oYXNMb2NhbFN0b3JhZ2VEYXRhKCkpIHtcclxuICAgICAgY29uc3QgYWdlID0gdGhpcy5wZXJzaXN0ZW5jZVNlcnZpY2UuZ2V0TG9jYWxTdG9yYWdlQWdlKCk7XHJcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBhZ2VcclxuICAgICAgICA/IGBUcm92YXRvIHNhbHZhdGFnZ2lvIGRlbCAke2FnZS50b0xvY2FsZVN0cmluZygnaXQtSVQnKX0uIFZ1b2kgcmVjdXBlcmFybG8/YFxyXG4gICAgICAgIDogJ1Ryb3ZhdG8gc2FsdmF0YWdnaW8gcHJlY2VkZW50ZS4gVnVvaSByZWN1cGVyYXJsbz8nO1xyXG5cclxuICAgICAgY29uc3QgcmVmID0gdGhpcy5zbmFja0Jhci5vcGVuKG1lc3NhZ2UsICdSZWN1cGVyYScsIHsgZHVyYXRpb246IDEwMDAwIH0pO1xyXG4gICAgICByZWYub25BY3Rpb24oKS5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IHRoaXMucGVyc2lzdGVuY2VTZXJ2aWNlLmxvYWRGcm9tTG9jYWxTdG9yYWdlKCk7XHJcbiAgICAgICAgaWYgKHNjaGVtYSkge1xyXG4gICAgICAgICAgdGhpcy5zdGF0ZVNlcnZpY2Uuc2V0U2NoZW1hKHNjaGVtYSk7XHJcbiAgICAgICAgICB0aGlzLnNob3dNZXNzYWdlKCdTY2hlbWEgcmVjdXBlcmF0bycpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGF1dG9TYXZlKCk6IHZvaWQge1xyXG4gICAgdHJ5IHtcclxuICAgICAgdGhpcy5wZXJzaXN0ZW5jZVNlcnZpY2Uuc2F2ZVRvTG9jYWxTdG9yYWdlKHRoaXMuc3RhdGUuc2NoZW1hKTtcclxuICAgICAgdGhpcy5zdGF0ZVNlcnZpY2UubWFya0FzU2F2ZWQoKTtcclxuICAgIH0gY2F0Y2gge1xyXG4gICAgICAvLyBTaWxlbnppb3NvIHBlciBhdXRvLXNhdmVcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBkYXRlQnJlYWRjcnVtYigpOiB2b2lkIHtcclxuICAgIHRoaXMuYnJlYWRjcnVtYiA9IFtcclxuICAgICAge1xyXG4gICAgICAgIGxhYmVsOiB0aGlzLnN0YXRlLnNjaGVtYS50aXRsZSB8fCAnRm9ybScsXHJcbiAgICAgICAgaWQ6IHRoaXMuc3RhdGUuc2NoZW1hLmlkLFxyXG4gICAgICAgIHR5cGU6ICdmb3JtJyxcclxuICAgICAgICBhY3RpdmU6ICF0aGlzLnN0YXRlLnNlbGVjdGVkU2VjdGlvbklkICYmICF0aGlzLnN0YXRlLnNlbGVjdGVkRmllbGRLZXksXHJcbiAgICAgIH0sXHJcbiAgICBdO1xyXG5cclxuICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkU2VjdGlvbklkKSB7XHJcbiAgICAgIGNvbnN0IHNlY3Rpb24gPSB0aGlzLnN0YXRlLnNjaGVtYS5zZWN0aW9ucy5maW5kKChzKSA9PiBzLmlkID09PSB0aGlzLnN0YXRlLnNlbGVjdGVkU2VjdGlvbklkKTtcclxuICAgICAgaWYgKHNlY3Rpb24pIHtcclxuICAgICAgICB0aGlzLmJyZWFkY3J1bWIucHVzaCh7XHJcbiAgICAgICAgICBsYWJlbDogc2VjdGlvbi50aXRsZSB8fCAnU2V6aW9uZScsXHJcbiAgICAgICAgICBpZDogc2VjdGlvbi5pZCxcclxuICAgICAgICAgIHR5cGU6ICdzZWN0aW9uJyxcclxuICAgICAgICAgIGFjdGl2ZTogIXRoaXMuc3RhdGUuc2VsZWN0ZWRGaWVsZEtleSxcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkRmllbGRLZXkpIHtcclxuICAgICAgY29uc3QgZmllbGQgPSB0aGlzLnN0YXRlU2VydmljZS5maW5kRmllbGRCeUtleSh0aGlzLnN0YXRlLnNlbGVjdGVkRmllbGRLZXkpO1xyXG4gICAgICBpZiAoZmllbGQpIHtcclxuICAgICAgICB0aGlzLmJyZWFkY3J1bWIucHVzaCh7XHJcbiAgICAgICAgICBsYWJlbDogZmllbGQubGFiZWwsXHJcbiAgICAgICAgICBpZDogZmllbGQua2V5LFxyXG4gICAgICAgICAgdHlwZTogJ2ZpZWxkJyxcclxuICAgICAgICAgIGFjdGl2ZTogdHJ1ZSxcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVBdmFpbGFibGVGaWVsZHMoKTogdm9pZCB7XHJcbiAgICBjb25zdCBmaWVsZHM6IFVpRWRpdG9yQXZhaWxhYmxlRmllbGRbXSA9IFtdO1xyXG4gICAgdGhpcy5zdGF0ZS5zY2hlbWEuc2VjdGlvbnMuZm9yRWFjaCgoc2VjdGlvbikgPT4ge1xyXG4gICAgICBzZWN0aW9uLmZpZWxkcy5mb3JFYWNoKChmaWVsZCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGFmOiBVaUVkaXRvckF2YWlsYWJsZUZpZWxkID0ge1xyXG4gICAgICAgICAga2V5OiBmaWVsZC5rZXksXHJcbiAgICAgICAgICBsYWJlbDogZmllbGQubGFiZWwsXHJcbiAgICAgICAgICB0eXBlOiBmaWVsZC50eXBlLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgaWYgKGZpZWxkLm9wdGlvbnMgJiYgQXJyYXkuaXNBcnJheShmaWVsZC5vcHRpb25zKSAmJiBmaWVsZC5vcHRpb25zLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIGFmLm9wdGlvbnMgPSBmaWVsZC5vcHRpb25zLm1hcCgob3B0KSA9PiAoe1xyXG4gICAgICAgICAgICB2YWx1ZTogb3B0LnZhbHVlLFxyXG4gICAgICAgICAgICBsYWJlbDogb3B0LmxhYmVsLFxyXG4gICAgICAgICAgfSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaWVsZHMucHVzaChhZik7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgICB0aGlzLmF2YWlsYWJsZUZpZWxkcyA9IGZpZWxkcztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2hvd01lc3NhZ2UobWVzc2FnZTogc3RyaW5nLCBpc0Vycm9yID0gZmFsc2UpOiB2b2lkIHtcclxuICAgIHRoaXMuc25hY2tCYXIub3BlbihtZXNzYWdlLCAnQ2hpdWRpJywge1xyXG4gICAgICBkdXJhdGlvbjogMzAwMCxcclxuICAgICAgcGFuZWxDbGFzczogaXNFcnJvciA/IFsndWktc25hY2tiYXItZXJyb3InXSA6IFtdLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGxvYWRTaWRlYmFyV2lkdGgoKTogdm9pZCB7XHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCBzYXZlZFJpZ2h0ID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5TSURFQkFSX1dJRFRIX0tFWSk7XHJcbiAgICAgIGlmIChzYXZlZFJpZ2h0KSB7XHJcbiAgICAgICAgY29uc3QgdyA9IHBhcnNlSW50KHNhdmVkUmlnaHQsIDEwKTtcclxuICAgICAgICBpZiAoIWlzTmFOKHcpICYmIHcgPj0gdGhpcy5NSU5fU0lERUJBUl9XSURUSCAmJiB3IDw9IHRoaXMuTUFYX1NJREVCQVJfV0lEVEgpIHtcclxuICAgICAgICAgIHRoaXMucmlnaHRTaWRlYmFyV2lkdGggPSB3O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBjb25zdCBzYXZlZExlZnQgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLkxFRlRfU0lERUJBUl9XSURUSF9LRVkpO1xyXG4gICAgICBpZiAoc2F2ZWRMZWZ0KSB7XHJcbiAgICAgICAgY29uc3QgdyA9IHBhcnNlSW50KHNhdmVkTGVmdCwgMTApO1xyXG4gICAgICAgIGlmICghaXNOYU4odykgJiYgdyA+PSB0aGlzLk1JTl9MRUZUX1NJREVCQVJfV0lEVEggJiYgdyA8PSB0aGlzLk1BWF9MRUZUX1NJREVCQVJfV0lEVEgpIHtcclxuICAgICAgICAgIHRoaXMubGVmdFNpZGViYXJXaWR0aCA9IHc7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9IGNhdGNoIHtcclxuICAgICAgLy8gU2lsZW56aW9zb1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzYXZlU2lkZWJhcldpZHRoKCk6IHZvaWQge1xyXG4gICAgdHJ5IHtcclxuICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0odGhpcy5TSURFQkFSX1dJRFRIX0tFWSwgdGhpcy5yaWdodFNpZGViYXJXaWR0aC50b1N0cmluZygpKTtcclxuICAgIH0gY2F0Y2gge1xyXG4gICAgICAvLyBTaWxlbnppb3NvXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNhdmVMZWZ0U2lkZWJhcldpZHRoKCk6IHZvaWQge1xyXG4gICAgdHJ5IHtcclxuICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0odGhpcy5MRUZUX1NJREVCQVJfV0lEVEhfS0VZLCB0aGlzLmxlZnRTaWRlYmFyV2lkdGgudG9TdHJpbmcoKSk7XHJcbiAgICB9IGNhdGNoIHtcclxuICAgICAgLy8gU2lsZW56aW9zb1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iXX0=