@oneteme/jquery-organizer 0.0.5 → 0.0.7

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.
@@ -21,15 +21,11 @@ export class OrganizerButtonComponent {
21
21
  this.sliceStateChange = new EventEmitter();
22
22
  this.fieldDataCache = new Map();
23
23
  this.destroy$ = new Subject();
24
- }
25
- ngOnInit() {
26
- console.debug('[OrganizerButton] Initialized', {
27
- configFields: this.config?.fields?.length ?? 0,
28
- hasState: !!this.state,
29
- hideMenuValues: this.hideMenuValues
30
- });
24
+ this.destroyed = false;
25
+ this.sliceRequestId = 0;
31
26
  }
32
27
  ngOnDestroy() {
28
+ this.destroyed = true;
33
29
  this.destroy$.next();
34
30
  this.destroy$.complete();
35
31
  }
@@ -46,27 +42,27 @@ export class OrganizerButtonComponent {
46
42
  return `${visible}/${total}`;
47
43
  }
48
44
  onFieldToggle(fieldId, visible) {
49
- console.debug('[OrganizerButton] Field toggled', { fieldId, visible });
50
- const visibleFields = this.state?.visibleFields || [];
51
- const updated = visible
52
- ? [...visibleFields, fieldId]
53
- : visibleFields.filter(f => f !== fieldId);
45
+ const current = this.state?.visibleFields
46
+ ?? (this.config.fields ?? []).filter(f => f.visible !== false).map(f => f.id);
47
+ let updated;
48
+ if (visible) {
49
+ updated = current.includes(fieldId) ? current : [...current, fieldId];
50
+ }
51
+ else {
52
+ updated = current.filter(f => f !== fieldId);
53
+ }
54
54
  this.emitChange('fieldToggled', { visibleFields: updated });
55
55
  }
56
56
  onXFieldSelect(fieldId) {
57
- console.debug('[OrganizerButton] X field selected', { fieldId, current: this.state?.selectedX });
58
57
  // Évite une requête inutile si le X est déjà sélectionné
59
58
  if (this.state?.selectedX === fieldId) {
60
- console.debug('[OrganizerButton] X field already selected, skipping emit');
61
59
  return;
62
60
  }
63
61
  this.emitChange('xSelected', { selectedX: fieldId });
64
62
  }
65
63
  onYFieldSelect(fieldId) {
66
- console.debug('[OrganizerButton] Y field selected', { fieldId, current: this.state?.selectedY });
67
64
  // Évite une requête inutile si le Y est déjà sélectionné
68
65
  if (this.state?.selectedY === fieldId) {
69
- console.debug('[OrganizerButton] Y field already selected, skipping emit');
70
66
  return;
71
67
  }
72
68
  this.emitChange('ySelected', {
@@ -75,10 +71,8 @@ export class OrganizerButtonComponent {
75
71
  });
76
72
  }
77
73
  onYAggregateSelect(yFieldId, aggregateId) {
78
- console.debug('[OrganizerButton] Y aggregate selected', { yFieldId, aggregateId, current: this.state?.selectedYAggregate });
79
74
  // Évite une requête inutile si l'aggregate est déjà sélectionné
80
75
  if (this.state?.selectedYAggregate === aggregateId && this.state?.selectedY === yFieldId) {
81
- console.debug('[OrganizerButton] Y aggregate already selected, skipping emit');
82
76
  return;
83
77
  }
84
78
  this.emitChange('ySelected', {
@@ -87,12 +81,16 @@ export class OrganizerButtonComponent {
87
81
  });
88
82
  }
89
83
  onGroupBySelect(groupId) {
90
- console.debug('[OrganizerButton] Group by selected', { groupId });
91
- const current = this.state.selectedGroupBy;
84
+ const current = this.state?.selectedGroupBy;
92
85
  this.emitChange('groupBySelected', { selectedGroupBy: current === groupId ? undefined : groupId });
93
86
  }
87
+ onChartTypeSelect(chartType) {
88
+ const option = this.config.chartTypes?.find(type => type.id === chartType);
89
+ if (!option || option.disabled || this.state?.selectedChartType === chartType)
90
+ return;
91
+ this.emitChange('chartTypeSelected', { selectedChartType: chartType });
92
+ }
94
93
  onTemplateSelect(templateId) {
95
- console.debug('[OrganizerButton] Template selected', { templateId });
96
94
  if (!this.config.templates?.length)
97
95
  return;
98
96
  const template = this.config.templates?.find(t => t.id === templateId);
@@ -103,7 +101,6 @@ export class OrganizerButtonComponent {
103
101
  this.syncSliceState(newState.selectedSlices);
104
102
  }
105
103
  onSliceClick(sliceId) {
106
- console.debug('[OrganizerButton] Slice clicked', { sliceId });
107
104
  if (this.config.onSliceClick) {
108
105
  this.config.onSliceClick();
109
106
  }
@@ -127,6 +124,10 @@ export class OrganizerButtonComponent {
127
124
  });
128
125
  }
129
126
  syncSliceState(selectedSlices, onLoaded) {
127
+ // Une nouvelle demande annule la précédente : seule la réponse la plus récente est prise en compte.
128
+ const requestId = ++this.sliceRequestId;
129
+ this.sliceSubscription?.unsubscribe();
130
+ this.sliceSubscription = undefined;
130
131
  const sliceId = selectedSlices?.[0];
131
132
  if (!sliceId || !this.config.onFetchSliceData) {
132
133
  this.sliceStateChange.emit(null);
@@ -141,6 +142,8 @@ export class OrganizerButtonComponent {
141
142
  }
142
143
  const result = this.config.onFetchSliceData(sliceId);
143
144
  const handleData = (tasks) => {
145
+ if (this.destroyed || requestId !== this.sliceRequestId)
146
+ return;
144
147
  this.sliceStateChange.emit({
145
148
  sliceConfigs: [{ title: slice.label ?? sliceId, columnKey: sliceId }],
146
149
  tasks,
@@ -148,11 +151,18 @@ export class OrganizerButtonComponent {
148
151
  });
149
152
  onLoaded?.();
150
153
  };
154
+ const handleError = (error) => {
155
+ if (this.destroyed || requestId !== this.sliceRequestId)
156
+ return;
157
+ console.error('[OrganizerButton] Slice data loading failed', error);
158
+ this.sliceStateChange.emit(null);
159
+ onLoaded?.();
160
+ };
151
161
  if (isObservable(result)) {
152
- result.pipe(takeUntil(this.destroy$)).subscribe({ next: handleData });
162
+ this.sliceSubscription = result.pipe(takeUntil(this.destroy$)).subscribe({ next: handleData, error: handleError });
153
163
  }
154
164
  else {
155
- result.then(handleData);
165
+ void result.then(handleData, handleError);
156
166
  }
157
167
  }
158
168
  async loadFieldData(fieldId) {
@@ -169,6 +179,9 @@ export class OrganizerButtonComponent {
169
179
  const data = await this.config.onFetchFieldData(fieldId);
170
180
  this.fieldDataCache.set(fieldId, data);
171
181
  }
182
+ catch (error) {
183
+ console.error('[OrganizerButton] Field data loading failed', error);
184
+ }
172
185
  finally {
173
186
  this.loadingFieldId = undefined;
174
187
  this.cdr.markForCheck();
@@ -204,6 +217,7 @@ export class OrganizerButtonComponent {
204
217
  hasMenuItemsBeforeActions() {
205
218
  return this.hasChartFields()
206
219
  || this.hasTableFields()
220
+ || (this.config.chartTypes?.length ?? 0) > 0
207
221
  || (this.config.groups?.length ?? 0) > 0
208
222
  || (this.config.slices?.length ?? 0) > 0
209
223
  || (this.config.templates?.length ?? 0) > 0;
@@ -255,14 +269,18 @@ export class OrganizerButtonComponent {
255
269
  this.mainMenuTrigger?.closeMenu();
256
270
  }
257
271
  onReset() {
272
+ const visibleFields = this.config.fields
273
+ ?.filter(field => field.visible !== false)
274
+ .map(field => field.id);
258
275
  this.emitChange('reset', {
259
- visibleFields: [],
276
+ visibleFields,
260
277
  selectedX: undefined,
261
278
  selectedY: undefined,
262
279
  selectedYAggregate: undefined,
263
280
  selectedGroupBy: undefined,
264
281
  selectedSlices: []
265
282
  });
283
+ this.mainMenuTrigger?.closeMenu();
266
284
  }
267
285
  activeXLabel() {
268
286
  const id = this.state?.selectedX;
@@ -288,6 +306,12 @@ export class OrganizerButtonComponent {
288
306
  return '';
289
307
  return this.config.groups?.find(g => g.id === id)?.label ?? id;
290
308
  }
309
+ activeChartTypeLabel() {
310
+ const id = this.state?.selectedChartType;
311
+ if (!id)
312
+ return '';
313
+ return this.config.chartTypes?.find(type => type.id === id)?.label ?? id;
314
+ }
291
315
  activeSlicesLabel() {
292
316
  const ids = this.state?.selectedSlices;
293
317
  if (!ids?.length)
@@ -306,6 +330,9 @@ export class OrganizerButtonComponent {
306
330
  hasChartFields() {
307
331
  return (this.config.xFields?.length ?? 0) > 0 || (this.config.yFields?.length ?? 0) > 0;
308
332
  }
333
+ hasChartTypes() {
334
+ return (this.config.chartTypes?.length ?? 0) > 0;
335
+ }
309
336
  hasTableFields() {
310
337
  return (this.config.fields?.length ?? 0) > 0;
311
338
  }
@@ -315,6 +342,9 @@ export class OrganizerButtonComponent {
315
342
  isYAggregateActive(yFieldId, aggregateId) {
316
343
  return this.state?.selectedY === yFieldId && this.state?.selectedYAggregate === aggregateId;
317
344
  }
345
+ isChartTypeActive(chartType) {
346
+ return this.state?.selectedChartType === chartType;
347
+ }
318
348
  emitChange(type, stateUpdate) {
319
349
  const isFullState = 'selectedX' in stateUpdate && 'selectedTemplate' in stateUpdate;
320
350
  const rawState = isFullState ? stateUpdate : { ...this.state, ...stateUpdate };
@@ -330,11 +360,11 @@ export class OrganizerButtonComponent {
330
360
  this.viewChange.emit(event);
331
361
  }
332
362
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: OrganizerButtonComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
333
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: OrganizerButtonComponent, isStandalone: true, selector: "organizer-button", inputs: { config: "config", state: "state", hideMenuValues: "hideMenuValues" }, outputs: { viewChange: "viewChange", sliceStateChange: "sliceStateChange" }, viewQueries: [{ propertyName: "mainMenuTrigger", first: true, predicate: ["mainMenuTrigger"], descendants: true }], ngImport: i0, template: "<button type=\"button\" class=\"organizer-btn\" [matMenuTriggerFor]=\"viewMenu\" #mainMenuTrigger=\"matMenuTrigger\" [attr.aria-label]=\"'View'\">\n <mat-icon class=\"organizer-btn-icon\">{{ config.buttonIcon || 'settings' }}</mat-icon>\n</button>\n\n<mat-menu #viewMenu=\"matMenu\" panelClass=\"organizer-menu-panel\">\n\n <!-- Champs : mode chart (X + Y) -->\n <button *ngIf=\"hasChartFields()\" mat-menu-item [matMenuTriggerFor]=\"champsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Champs</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && (activeXLabel() || activeYLabel())\">\n {{ activeXLabel() }}<ng-container *ngIf=\"activeXLabel() && activeYLabel()\"> / </ng-container>{{ activeYLabel() }}\n </span>\n </button>\n\n <!-- Champs : mode table (toggle colonnes) -->\n <button *ngIf=\"hasTableFields()\" mat-menu-item [matMenuTriggerFor]=\"fieldsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Champs</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues\">{{ fieldsSummary() }}</span>\n </button>\n\n <!-- Grouper par -->\n <button *ngIf=\"config.groups?.length\" mat-menu-item [matMenuTriggerFor]=\"groupsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Grouper par</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeGroupByLabel()\">{{ activeGroupByLabel() }}</span>\n </button>\n\n <!-- Filtrer par -->\n <button *ngIf=\"config.slices?.length\" mat-menu-item [matMenuTriggerFor]=\"slicesSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Filtrer par</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeSlicesLabel()\">{{ activeSlicesLabel() }}</span>\n </button>\n\n <!-- Template -->\n <button *ngIf=\"config.templates?.length\" mat-menu-item [matMenuTriggerFor]=\"templateSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Template</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeTemplateLabel()\">{{ activeTemplateLabel() }}</span>\n </button>\n\n <!-- Actions du visuel courant -->\n <mat-divider *ngIf=\"hasActions() && hasMenuItemsBeforeActions()\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"hasActions() && hasOtherMenuItems()\" mat-menu-item [matMenuTriggerFor]=\"actionsSubMenu\" class=\"organizer-menu-trigger\">\n <mat-icon *ngIf=\"config.actions?.icon\" class=\"organizer-menu-export-icon\">{{ config.actions?.icon }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ actionsLabel() }}</span>\n </button>\n\n <!-- Actions directes lorsqu'il n'y a aucun autre item principal -->\n <ng-container *ngIf=\"hasActions() && !hasOtherMenuItems()\">\n <button *ngIf=\"isCopyActionVisible()\" mat-menu-item type=\"button\" (click)=\"onCopyVisual()\">\n <mat-icon class=\"organizer-menu-export-icon\">content_copy</mat-icon>\n <span class=\"organizer-menu-label\">Copier</span>\n </button>\n <button *ngIf=\"isFullscreenActionVisible()\" mat-menu-item type=\"button\" (click)=\"onToggleFullscreen()\">\n <mat-icon class=\"organizer-menu-export-icon\">{{ config.isFullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ config.isFullscreen ? 'Quitter le plein \u00E9cran' : 'Plein \u00E9cran' }}</span>\n </button>\n </ng-container>\n\n <!-- Export direct (mode table) -->\n <mat-divider *ngIf=\"config.showExport\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"config.showExport && !hasExportSubMenu()\" mat-menu-item type=\"button\" class=\"organizer-menu-export\" (click)=\"onExport()\">\n <mat-icon class=\"organizer-menu-export-icon\">download</mat-icon>\n <span class=\"organizer-menu-label\">Exporter</span>\n </button>\n\n <!-- Export graphique (mode chart) \u2014 ouvre un sous-menu -->\n <button *ngIf=\"config.showExport && hasExportSubMenu()\" mat-menu-item [matMenuTriggerFor]=\"exportSubMenu\" class=\"organizer-menu-trigger organizer-menu-export\">\n <mat-icon class=\"organizer-menu-export-icon\">download</mat-icon>\n <span class=\"organizer-menu-label\">Exporter</span>\n </button>\n\n <!-- Pr\u00E9f\u00E9rences -->\n <mat-divider *ngIf=\"config.showPreferences\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"config.showPreferences\" mat-menu-item [matMenuTriggerFor]=\"preferencesSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Pr\u00E9f\u00E9rences</span>\n </button>\n\n <!-- Switch chart / table -->\n <mat-divider *ngIf=\"hasSwitchView()\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"hasSwitchView()\" mat-menu-item type=\"button\" class=\"organizer-menu-trigger\" (click)=\"onSwitchView()\">\n <mat-icon class=\"organizer-menu-export-icon\">{{ config.switchView?.currentView === 'chart' ? 'table_chart' : 'bar_chart' }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ config.switchView?.currentView === 'chart' ? 'Tableau' : 'Graphique' }}</span>\n </button>\n\n</mat-menu>\n\n<!-- Sous-menu : actions du visuel -->\n<mat-menu #actionsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button *ngIf=\"isCopyActionVisible()\" type=\"button\" class=\"organizer-submenu-item\"\n (mousedown)=\"onCopyVisual()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">content_copy</mat-icon>\n Copier\n </button>\n <button *ngIf=\"isFullscreenActionVisible()\" type=\"button\" class=\"organizer-submenu-item\"\n (mousedown)=\"onToggleFullscreen()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">{{ config.isFullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\n {{ config.isFullscreen ? 'Quitter le plein \u00E9cran' : 'Plein \u00E9cran' }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Export graphique -->\n<mat-menu #exportSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button *ngIf=\"config.onExportVisual\" type=\"button\" class=\"organizer-submenu-item\"\n (mousedown)=\"onExportVisual()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">image</mat-icon>\n Visuel\n </button>\n <button *ngIf=\"config.onExportData\" type=\"button\" class=\"organizer-submenu-item\"\n (mousedown)=\"onExportData()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">table_chart</mat-icon>\n Donn\u00E9es\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Champs chart (X + Y) -->\n<mat-menu #champsSubMenu=\"matMenu\" panelClass=\"organizer-champs-panel\">\n <div class=\"organizer-champs-wrapper\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n\n <!-- Bloc X -->\n <div class=\"organizer-champs-block\" *ngIf=\"config.xFields?.length\">\n <span class=\"organizer-champs-block-title\">Axe horizontal \u2014 X</span>\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let xField of config.xFields\"\n [class.active]=\"state?.selectedX === xField.id\"\n [disabled]=\"xField.disabled\"\n (mousedown)=\"onXFieldSelect(xField.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedX === xField.id ? '\u2713' : '' }}</span>\n {{ xField.label }}\n </button>\n </div>\n\n <mat-divider *ngIf=\"config.xFields?.length && config.yFields?.length\" class=\"organizer-champs-divider\"></mat-divider>\n\n <!-- Bloc Y -->\n <div class=\"organizer-champs-block\" *ngIf=\"config.yFields?.length\">\n <span class=\"organizer-champs-block-title\">Axe vertical \u2014 Y</span>\n <ng-container *ngFor=\"let yField of config.yFields\">\n\n <!-- Y simple (Count sans agr\u00E9gat ni stack) -->\n <!-- Y simple (Count ou m\u00E9trique directe) -->\n <button *ngIf=\"!yField.aggregates?.length\"\n type=\"button\" class=\"organizer-submenu-item\"\n [class.active]=\"isYActive(yField.id)\"\n [disabled]=\"yField.disabled\"\n (mousedown)=\"onYFieldSelect(yField.id)\">\n <span class=\"organizer-submenu-check\">{{ isYActive(yField.id) ? '\u2713' : '' }}</span>\n {{ yField.label }}\n </button>\n\n <!-- Y avec agr\u00E9gats \u2192 sous-menu -->\n <button *ngIf=\"yField.aggregates?.length\"\n type=\"button\" class=\"organizer-submenu-item organizer-submenu-item--has-children\"\n [class.active]=\"isYActive(yField.id)\"\n [disabled]=\"yField.disabled\"\n [matMenuTriggerFor]=\"yAggSubMenu\"\n [matMenuTriggerData]=\"{ yField: yField }\"\n (mousedown)=\"$event.stopPropagation()\">\n <span class=\"organizer-submenu-check\">{{ isYActive(yField.id) ? '\u2713' : '' }}</span>\n {{ yField.label }}\n <mat-icon class=\"organizer-submenu-arrow\">chevron_right</mat-icon>\n </button>\n\n </ng-container>\n </div>\n\n </div>\n</mat-menu>\n\n<!-- Sous-menu dynamique : agr\u00E9gats d'un champ Y -->\n<mat-menu #yAggSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <ng-template matMenuContent let-yField=\"yField\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let agg of yField.aggregates\"\n [class.active]=\"isYAggregateActive(yField.id, agg.id)\"\n (mousedown)=\"onYAggregateSelect(yField.id, agg.id)\">\n <span class=\"organizer-submenu-check\">{{ isYAggregateActive(yField.id, agg.id) ? '\u2713' : '' }}</span>\n {{ agg.label }}\n </button>\n </div>\n </ng-template>\n</mat-menu>\n\n<!-- Sous-menu : Champs table (toggle colonnes) -->\n<mat-menu #fieldsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let field of config.fields\"\n [class.active]=\"isFieldVisible(field.id)\"\n (mousedown)=\"onFieldToggle(field.id, !isFieldVisible(field.id))\">\n <span class=\"organizer-submenu-check\">{{ isFieldVisible(field.id) ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"field.icon\" class=\"organizer-submenu-icon\">{{ field.icon }}</mat-icon> {{ field.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Grouper par -->\n<mat-menu #groupsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let group of config.groups\"\n [class.active]=\"state?.selectedGroupBy === group.id\"\n (mousedown)=\"onGroupBySelect(group.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedGroupBy === group.id ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"group.icon\" class=\"organizer-submenu-icon\">{{ group.icon }}</mat-icon> {{ group.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Filtrer par -->\n<mat-menu #slicesSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let slice of config.slices\"\n [class.active]=\"state?.selectedSlices?.includes(slice.id)\"\n (mousedown)=\"onSliceClick(slice.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedSlices?.includes(slice.id) ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"slice.icon\" class=\"organizer-submenu-icon\">{{ slice.icon }}</mat-icon> {{ slice.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Template -->\n<mat-menu #templateSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let tmpl of config.templates\"\n [class.active]=\"state?.selectedTemplate === tmpl.id\"\n [title]=\"tmpl.description || ''\"\n (mousedown)=\"onTemplateSelect(tmpl.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedTemplate === tmpl.id ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"tmpl.icon\" class=\"organizer-submenu-icon\">{{ tmpl.icon }}</mat-icon>\n {{ tmpl.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Pr\u00E9f\u00E9rences -->\n<mat-menu #preferencesSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\" (mousedown)=\"onPreferencesEdit()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">edit</mat-icon>\u00C9diter\n </button>\n <button type=\"button\" class=\"organizer-submenu-item\" (mousedown)=\"onPreferencesSave()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">save</mat-icon>Sauvegarder\n </button>\n <button type=\"button\" class=\"organizer-submenu-item\" [disabled]=\"!config.hasSavedPreferences\" (mousedown)=\"onPreferencesClear()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">delete_outline</mat-icon>R\u00E9initialiser\n </button>\n </div>\n</mat-menu>\n\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}.organizer-btn{position:relative;display:block;height:34px;width:34px;border:1px solid #e0e0e0;border-radius:8px;background:#fff;padding:0;overflow:hidden;cursor:pointer;box-sizing:border-box}.organizer-btn:hover{border-color:#9e9e9e}.organizer-btn-icon.mat-icon,.organizer-btn-icon.material-icons{position:absolute;inset:0;display:block!important;width:18px!important;height:18px!important;margin:auto!important;padding:0!important;font-size:18px!important;line-height:18px!important;text-align:center;vertical-align:middle;transform:none;color:#000}.mat-mdc-menu-panel:has(.organizer-menu-label){min-width:170px!important;max-width:320px!important;overflow:visible!important}.mat-mdc-menu-panel:has(.organizer-menu-label) .mat-mdc-menu-content{padding:4px 0!important}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item{min-height:42px;padding:0 14px;display:flex;align-items:center;box-sizing:border-box}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item .mdc-list-item__primary-text{display:flex;align-items:center;width:100%;overflow:hidden}.organizer-menu-label{font-size:13px;font-weight:500;color:#212121;flex:0 0 auto;white-space:nowrap;padding-right:8px}.organizer-menu-value{font-size:12px;color:#757575;flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:right}.organizer-submenu{padding:4px 6px;min-width:180px;box-sizing:border-box}.organizer-submenu .organizer-submenu-item{display:flex;align-items:center;gap:6px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;color:#212121;cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}.organizer-submenu .organizer-submenu-item:hover{background:#f5f5f5}.organizer-submenu .organizer-submenu-item.active{font-weight:600}.organizer-submenu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:#212121}.organizer-submenu-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#212121;margin-right:4px}.organizer-menu-export.mat-mdc-menu-item{min-height:42px;padding:0 14px}.organizer-menu-export-icon{font-size:16px!important;width:16px!important;height:16px!important;color:#424242;margin-right:8px}.organizer-divider{margin:4px 0!important}.organizer-champs-wrapper{padding:4px 6px;min-width:200px;box-sizing:border-box;display:flex;flex-direction:column}.organizer-champs-block{display:flex;flex-direction:column}.organizer-champs-block-title{font-size:10px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:#9e9e9e;padding:6px 2px 2px}.organizer-champs-divider{margin:4px 0!important}.organizer-champs-wrapper .organizer-submenu-item{display:flex;align-items:center;gap:6px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;font-family:inherit;color:#212121;cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}.organizer-champs-wrapper .organizer-submenu-item:hover:not([disabled]){background:#f5f5f5}.organizer-champs-wrapper .organizer-submenu-item.active{font-weight:600}.organizer-champs-wrapper .organizer-submenu-item[disabled]{opacity:.38;cursor:default}.organizer-champs-wrapper .organizer-submenu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:#212121}.organizer-champs-wrapper .organizer-submenu-item--has-children{padding-right:8px}.organizer-champs-wrapper .organizer-submenu-arrow{font-size:18px!important;width:18px!important;height:18px!important;color:#00000061;margin-left:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i4.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
363
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: OrganizerButtonComponent, isStandalone: true, selector: "organizer-button", inputs: { config: "config", state: "state", hideMenuValues: "hideMenuValues" }, outputs: { viewChange: "viewChange", sliceStateChange: "sliceStateChange" }, viewQueries: [{ propertyName: "mainMenuTrigger", first: true, predicate: ["mainMenuTrigger"], descendants: true }], ngImport: i0, template: "<button type=\"button\" class=\"organizer-btn\" [class.organizer-btn--labeled]=\"!!config.buttonLabel\" [matMenuTriggerFor]=\"viewMenu\" #mainMenuTrigger=\"matMenuTrigger\" [attr.aria-label]=\"config.buttonLabel || 'Personnaliser la vue'\" [attr.title]=\"config.buttonLabel || 'Personnaliser la vue'\">\n <mat-icon *ngIf=\"config.showButtonIcon !== false\" class=\"organizer-btn-icon\">{{ config.buttonIcon || 'settings' }}</mat-icon>\n <span *ngIf=\"config.buttonLabel\" class=\"organizer-btn-label\">{{ config.buttonLabel }}</span>\n</button>\n\n<mat-menu #viewMenu=\"matMenu\" panelClass=\"organizer-menu-panel\">\n\n <!-- Type -->\n <button *ngIf=\"hasChartTypes()\" mat-menu-item [matMenuTriggerFor]=\"chartTypesSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Type</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeChartTypeLabel()\">{{ activeChartTypeLabel() }}</span>\n </button>\n\n <!-- Champs : mode chart (X + Y) -->\n <button *ngIf=\"hasChartFields()\" mat-menu-item [matMenuTriggerFor]=\"champsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Champs</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && (activeXLabel() || activeYLabel())\">\n {{ activeXLabel() }}<ng-container *ngIf=\"activeXLabel() && activeYLabel()\"> / </ng-container>{{ activeYLabel() }}\n </span>\n </button>\n\n <!-- Champs : mode table (toggle colonnes) -->\n <button *ngIf=\"hasTableFields()\" mat-menu-item [matMenuTriggerFor]=\"fieldsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Champs</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues\">{{ fieldsSummary() }}</span>\n </button>\n\n <!-- Grouper par -->\n <button *ngIf=\"config.groups?.length\" mat-menu-item [matMenuTriggerFor]=\"groupsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Grouper par</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeGroupByLabel()\">{{ activeGroupByLabel() }}</span>\n </button>\n\n <!-- Filtrer par -->\n <button *ngIf=\"config.slices?.length\" mat-menu-item [matMenuTriggerFor]=\"slicesSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Filtrer par</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeSlicesLabel()\">{{ activeSlicesLabel() }}</span>\n </button>\n\n <!-- Template -->\n <button *ngIf=\"config.templates?.length\" mat-menu-item [matMenuTriggerFor]=\"templateSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Template</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeTemplateLabel()\">{{ activeTemplateLabel() }}</span>\n </button>\n\n <!-- Actions du visuel courant -->\n <mat-divider *ngIf=\"hasActions() && hasMenuItemsBeforeActions()\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"hasActions() && hasOtherMenuItems()\" mat-menu-item [matMenuTriggerFor]=\"actionsSubMenu\" class=\"organizer-menu-trigger\">\n <mat-icon *ngIf=\"config.actions?.icon\" class=\"organizer-menu-export-icon\">{{ config.actions?.icon }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ actionsLabel() }}</span>\n </button>\n\n <!-- Actions directes lorsqu'il n'y a aucun autre item principal -->\n <ng-container *ngIf=\"hasActions() && !hasOtherMenuItems()\">\n <button *ngIf=\"isCopyActionVisible()\" mat-menu-item type=\"button\" (click)=\"onCopyVisual()\">\n <mat-icon class=\"organizer-menu-export-icon\">content_copy</mat-icon>\n <span class=\"organizer-menu-label\">Copier</span>\n </button>\n <button *ngIf=\"isFullscreenActionVisible()\" mat-menu-item type=\"button\" (click)=\"onToggleFullscreen()\">\n <mat-icon class=\"organizer-menu-export-icon\">{{ config.isFullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ config.isFullscreen ? 'Quitter le plein \u00E9cran' : 'Plein \u00E9cran' }}</span>\n </button>\n </ng-container>\n\n <!-- Export direct (mode table) -->\n <mat-divider *ngIf=\"config.showExport\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"config.showExport && !hasExportSubMenu()\" mat-menu-item type=\"button\" class=\"organizer-menu-export\" (click)=\"onExport()\">\n <mat-icon class=\"organizer-menu-export-icon\">download</mat-icon>\n <span class=\"organizer-menu-label\">Exporter</span>\n </button>\n\n <!-- Export graphique (mode chart) \u2014 ouvre un sous-menu -->\n <button *ngIf=\"config.showExport && hasExportSubMenu()\" mat-menu-item [matMenuTriggerFor]=\"exportSubMenu\" class=\"organizer-menu-trigger organizer-menu-export\">\n <mat-icon class=\"organizer-menu-export-icon\">download</mat-icon>\n <span class=\"organizer-menu-label\">Exporter</span>\n </button>\n\n <!-- Pr\u00E9f\u00E9rences -->\n <mat-divider *ngIf=\"config.showPreferences\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"config.showPreferences\" mat-menu-item [matMenuTriggerFor]=\"preferencesSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Pr\u00E9f\u00E9rences</span>\n </button>\n\n <mat-divider *ngIf=\"config.showReset === true\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"config.showReset === true\" mat-menu-item type=\"button\" class=\"organizer-menu-reset\" (click)=\"onReset()\">\n <mat-icon class=\"organizer-menu-export-icon\">restart_alt</mat-icon>\n <span class=\"organizer-menu-label\">R\u00E9initialiser la vue</span>\n </button>\n\n <!-- Switch chart / table -->\n <mat-divider *ngIf=\"hasSwitchView()\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"hasSwitchView()\" mat-menu-item type=\"button\" class=\"organizer-menu-trigger\" (click)=\"onSwitchView()\">\n <mat-icon class=\"organizer-menu-export-icon\">{{ config.switchView?.currentView === 'chart' ? 'table_chart' : 'bar_chart' }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ config.switchView?.currentView === 'chart' ? 'Tableau' : 'Graphique' }}</span>\n </button>\n\n</mat-menu>\n\n<!-- Sous-menu : types de graphique -->\n<mat-menu #chartTypesSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let chartType of config.chartTypes\"\n [class.active]=\"isChartTypeActive(chartType.id)\"\n [disabled]=\"chartType.disabled\"\n (click)=\"onChartTypeSelect(chartType.id)\">\n <span class=\"organizer-submenu-check\">{{ isChartTypeActive(chartType.id) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"chartType.icon\" class=\"organizer-submenu-icon\">{{ chartType.icon }}</mat-icon>\n {{ chartType.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : actions du visuel -->\n<mat-menu #actionsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button *ngIf=\"isCopyActionVisible()\" type=\"button\" class=\"organizer-submenu-item\"\n (click)=\"onCopyVisual()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">content_copy</mat-icon>\n Copier\n </button>\n <button *ngIf=\"isFullscreenActionVisible()\" type=\"button\" class=\"organizer-submenu-item\"\n (click)=\"onToggleFullscreen()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">{{ config.isFullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\n {{ config.isFullscreen ? 'Quitter le plein \u00E9cran' : 'Plein \u00E9cran' }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Export graphique -->\n<mat-menu #exportSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button *ngIf=\"config.onExportVisual\" type=\"button\" class=\"organizer-submenu-item\"\n (click)=\"onExportVisual()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">image</mat-icon>\n Visuel\n </button>\n <button *ngIf=\"config.onExportData\" type=\"button\" class=\"organizer-submenu-item\"\n (click)=\"onExportData()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">table_chart</mat-icon>\n Donn\u00E9es\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Champs chart (X + Y) -->\n<mat-menu #champsSubMenu=\"matMenu\" panelClass=\"organizer-champs-panel\">\n <div class=\"organizer-champs-wrapper\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n\n <!-- Bloc X -->\n <div class=\"organizer-champs-block\" *ngIf=\"config.xFields?.length\">\n <span class=\"organizer-champs-block-title\">Axe horizontal \u2014 X</span>\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let xField of config.xFields\"\n [class.active]=\"state?.selectedX === xField.id\"\n [disabled]=\"xField.disabled\"\n (click)=\"onXFieldSelect(xField.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedX === xField.id ? '\u2713' : '' }}</span>\n {{ xField.label }}\n </button>\n </div>\n\n <mat-divider *ngIf=\"config.xFields?.length && config.yFields?.length\" class=\"organizer-champs-divider\"></mat-divider>\n\n <!-- Bloc Y -->\n <div class=\"organizer-champs-block\" *ngIf=\"config.yFields?.length\">\n <span class=\"organizer-champs-block-title\">Axe vertical \u2014 Y</span>\n <ng-container *ngFor=\"let yField of config.yFields\">\n\n <!-- Y simple (Count sans agr\u00E9gat ni stack) -->\n <!-- Y simple (Count ou m\u00E9trique directe) -->\n <button *ngIf=\"!yField.aggregates?.length\"\n type=\"button\" class=\"organizer-submenu-item\"\n [class.active]=\"isYActive(yField.id)\"\n [disabled]=\"yField.disabled\"\n (click)=\"onYFieldSelect(yField.id)\">\n <span class=\"organizer-submenu-check\">{{ isYActive(yField.id) ? '\u2713' : '' }}</span>\n {{ yField.label }}\n </button>\n\n <!-- Y avec agr\u00E9gats \u2192 sous-menu -->\n <button *ngIf=\"yField.aggregates?.length\"\n type=\"button\" class=\"organizer-submenu-item organizer-submenu-item--has-children\"\n [class.active]=\"isYActive(yField.id)\"\n [disabled]=\"yField.disabled\"\n [matMenuTriggerFor]=\"yAggSubMenu\"\n [matMenuTriggerData]=\"{ yField: yField }\"\n (mousedown)=\"$event.stopPropagation()\">\n <span class=\"organizer-submenu-check\">{{ isYActive(yField.id) ? '\u2713' : '' }}</span>\n {{ yField.label }}\n <mat-icon class=\"organizer-submenu-arrow\">chevron_right</mat-icon>\n </button>\n\n </ng-container>\n </div>\n\n </div>\n</mat-menu>\n\n<!-- Sous-menu dynamique : agr\u00E9gats d'un champ Y -->\n<mat-menu #yAggSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <ng-template matMenuContent let-yField=\"yField\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let agg of yField.aggregates\"\n [class.active]=\"isYAggregateActive(yField.id, agg.id)\"\n (click)=\"onYAggregateSelect(yField.id, agg.id)\">\n <span class=\"organizer-submenu-check\">{{ isYAggregateActive(yField.id, agg.id) ? '\u2713' : '' }}</span>\n {{ agg.label }}\n </button>\n </div>\n </ng-template>\n</mat-menu>\n\n<!-- Sous-menu : Champs table (toggle colonnes) -->\n<mat-menu #fieldsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let field of config.fields\"\n [class.active]=\"isFieldVisible(field.id)\"\n (click)=\"onFieldToggle(field.id, !isFieldVisible(field.id))\">\n <span class=\"organizer-submenu-check\">{{ isFieldVisible(field.id) ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"field.icon\" class=\"organizer-submenu-icon\">{{ field.icon }}</mat-icon> {{ field.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Grouper par -->\n<mat-menu #groupsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let group of config.groups\"\n [class.active]=\"state?.selectedGroupBy === group.id\"\n (click)=\"onGroupBySelect(group.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedGroupBy === group.id ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"group.icon\" class=\"organizer-submenu-icon\">{{ group.icon }}</mat-icon> {{ group.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Filtrer par -->\n<mat-menu #slicesSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let slice of config.slices\"\n [class.active]=\"state?.selectedSlices?.includes(slice.id)\"\n (click)=\"onSliceClick(slice.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedSlices?.includes(slice.id) ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"slice.icon\" class=\"organizer-submenu-icon\">{{ slice.icon }}</mat-icon> {{ slice.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Template -->\n<mat-menu #templateSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let tmpl of config.templates\"\n [class.active]=\"state?.selectedTemplate === tmpl.id\"\n [title]=\"tmpl.description || ''\"\n (click)=\"onTemplateSelect(tmpl.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedTemplate === tmpl.id ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"tmpl.icon\" class=\"organizer-submenu-icon\">{{ tmpl.icon }}</mat-icon>\n {{ tmpl.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Pr\u00E9f\u00E9rences -->\n<mat-menu #preferencesSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\" (click)=\"onPreferencesEdit()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">edit</mat-icon>\u00C9diter\n </button>\n <button type=\"button\" class=\"organizer-submenu-item\" (click)=\"onPreferencesSave()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">save</mat-icon>Sauvegarder\n </button>\n <button type=\"button\" class=\"organizer-submenu-item\" [disabled]=\"!config.hasSavedPreferences\" (click)=\"onPreferencesClear()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">delete_outline</mat-icon>R\u00E9initialiser\n </button>\n </div>\n</mat-menu>\n\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}.organizer-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;height:var(--jqt-organizer-button-height, 34px);width:var(--jqt-organizer-button-width, 34px);min-width:var(--jqt-organizer-button-min-width, 34px);border:1px solid var(--jqt-organizer-button-border-color, #e0e0e0);border-radius:var(--jqt-organizer-button-radius, 8px);background:var(--jqt-organizer-button-background, #fff);padding:0;overflow:hidden;cursor:pointer;box-sizing:border-box}.organizer-btn:hover{border-color:var(--jqt-organizer-button-hover-border-color, #9e9e9e);background:var(--jqt-organizer-button-hover-background, var(--jqt-organizer-button-background, #fff))}.organizer-btn--labeled{width:auto;padding:0 12px}.organizer-btn-label{font-size:13px;font-weight:600;line-height:1;white-space:nowrap}.organizer-btn-icon.mat-icon,.organizer-btn-icon.material-icons{position:static;display:block!important;width:18px!important;height:18px!important;margin:0!important;padding:0!important;font-size:18px!important;line-height:18px!important;text-align:center;vertical-align:middle;transform:none;color:var(--jqt-organizer-button-icon-color, #000000)}.mat-mdc-menu-panel:has(.organizer-menu-label){min-width:170px!important;max-width:320px!important;overflow:visible!important}.mat-mdc-menu-panel:has(.organizer-menu-label) .mat-mdc-menu-content{padding:4px 0!important}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item{min-height:42px;padding:0 14px;display:flex;align-items:center;box-sizing:border-box}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item .mat-mdc-menu-item-text{display:flex;align-items:center;flex:1 1 auto;min-width:0;max-width:calc(100% - 20px);overflow:hidden;white-space:nowrap}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item .organizer-menu-label,.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item .organizer-menu-value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item .organizer-menu-value{display:block}.organizer-menu-label{font-size:13px;font-weight:500;color:#212121;flex:0 0 auto;white-space:nowrap;padding-right:8px}.organizer-menu-value{font-size:12px;color:#757575;flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:right}.organizer-submenu{padding:4px 6px;min-width:180px;box-sizing:border-box}.organizer-submenu .organizer-submenu-item{display:flex;align-items:center;gap:6px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;color:#212121;cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}.organizer-submenu .organizer-submenu-item:hover{background:#f5f5f5}.organizer-submenu .organizer-submenu-item.active{font-weight:600}.organizer-submenu .organizer-submenu-item[disabled]{opacity:.38;cursor:default}.organizer-submenu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:#212121}.organizer-submenu-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#212121;margin-right:4px}.organizer-menu-export.mat-mdc-menu-item{min-height:42px;padding:0 14px}.organizer-menu-export-icon{font-size:16px!important;width:16px!important;height:16px!important;color:#424242;margin-right:8px}.organizer-divider{margin:4px 0!important}.organizer-champs-wrapper{padding:4px 6px;min-width:200px;box-sizing:border-box;display:flex;flex-direction:column}.organizer-champs-block{display:flex;flex-direction:column}.organizer-champs-block-title{font-size:10px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:#9e9e9e;padding:6px 2px 2px}.organizer-champs-divider{margin:4px 0!important}.organizer-champs-wrapper .organizer-submenu-item{display:flex;align-items:center;gap:6px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;font-family:inherit;color:#212121;cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}.organizer-champs-wrapper .organizer-submenu-item:hover:not([disabled]){background:#f5f5f5}.organizer-champs-wrapper .organizer-submenu-item.active{font-weight:600}.organizer-champs-wrapper .organizer-submenu-item[disabled]{opacity:.38;cursor:default}.organizer-champs-wrapper .organizer-submenu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:#212121}.organizer-champs-wrapper .organizer-submenu-item--has-children{padding-right:8px}.organizer-champs-wrapper .organizer-submenu-arrow{font-size:18px!important;width:18px!important;height:18px!important;color:#00000061;margin-left:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i3.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i4.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
334
364
  }
335
365
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: OrganizerButtonComponent, decorators: [{
336
366
  type: Component,
337
- args: [{ standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, MatMenuModule, MatDividerModule], selector: 'organizer-button', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<button type=\"button\" class=\"organizer-btn\" [matMenuTriggerFor]=\"viewMenu\" #mainMenuTrigger=\"matMenuTrigger\" [attr.aria-label]=\"'View'\">\n <mat-icon class=\"organizer-btn-icon\">{{ config.buttonIcon || 'settings' }}</mat-icon>\n</button>\n\n<mat-menu #viewMenu=\"matMenu\" panelClass=\"organizer-menu-panel\">\n\n <!-- Champs : mode chart (X + Y) -->\n <button *ngIf=\"hasChartFields()\" mat-menu-item [matMenuTriggerFor]=\"champsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Champs</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && (activeXLabel() || activeYLabel())\">\n {{ activeXLabel() }}<ng-container *ngIf=\"activeXLabel() && activeYLabel()\"> / </ng-container>{{ activeYLabel() }}\n </span>\n </button>\n\n <!-- Champs : mode table (toggle colonnes) -->\n <button *ngIf=\"hasTableFields()\" mat-menu-item [matMenuTriggerFor]=\"fieldsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Champs</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues\">{{ fieldsSummary() }}</span>\n </button>\n\n <!-- Grouper par -->\n <button *ngIf=\"config.groups?.length\" mat-menu-item [matMenuTriggerFor]=\"groupsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Grouper par</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeGroupByLabel()\">{{ activeGroupByLabel() }}</span>\n </button>\n\n <!-- Filtrer par -->\n <button *ngIf=\"config.slices?.length\" mat-menu-item [matMenuTriggerFor]=\"slicesSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Filtrer par</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeSlicesLabel()\">{{ activeSlicesLabel() }}</span>\n </button>\n\n <!-- Template -->\n <button *ngIf=\"config.templates?.length\" mat-menu-item [matMenuTriggerFor]=\"templateSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Template</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeTemplateLabel()\">{{ activeTemplateLabel() }}</span>\n </button>\n\n <!-- Actions du visuel courant -->\n <mat-divider *ngIf=\"hasActions() && hasMenuItemsBeforeActions()\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"hasActions() && hasOtherMenuItems()\" mat-menu-item [matMenuTriggerFor]=\"actionsSubMenu\" class=\"organizer-menu-trigger\">\n <mat-icon *ngIf=\"config.actions?.icon\" class=\"organizer-menu-export-icon\">{{ config.actions?.icon }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ actionsLabel() }}</span>\n </button>\n\n <!-- Actions directes lorsqu'il n'y a aucun autre item principal -->\n <ng-container *ngIf=\"hasActions() && !hasOtherMenuItems()\">\n <button *ngIf=\"isCopyActionVisible()\" mat-menu-item type=\"button\" (click)=\"onCopyVisual()\">\n <mat-icon class=\"organizer-menu-export-icon\">content_copy</mat-icon>\n <span class=\"organizer-menu-label\">Copier</span>\n </button>\n <button *ngIf=\"isFullscreenActionVisible()\" mat-menu-item type=\"button\" (click)=\"onToggleFullscreen()\">\n <mat-icon class=\"organizer-menu-export-icon\">{{ config.isFullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ config.isFullscreen ? 'Quitter le plein \u00E9cran' : 'Plein \u00E9cran' }}</span>\n </button>\n </ng-container>\n\n <!-- Export direct (mode table) -->\n <mat-divider *ngIf=\"config.showExport\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"config.showExport && !hasExportSubMenu()\" mat-menu-item type=\"button\" class=\"organizer-menu-export\" (click)=\"onExport()\">\n <mat-icon class=\"organizer-menu-export-icon\">download</mat-icon>\n <span class=\"organizer-menu-label\">Exporter</span>\n </button>\n\n <!-- Export graphique (mode chart) \u2014 ouvre un sous-menu -->\n <button *ngIf=\"config.showExport && hasExportSubMenu()\" mat-menu-item [matMenuTriggerFor]=\"exportSubMenu\" class=\"organizer-menu-trigger organizer-menu-export\">\n <mat-icon class=\"organizer-menu-export-icon\">download</mat-icon>\n <span class=\"organizer-menu-label\">Exporter</span>\n </button>\n\n <!-- Pr\u00E9f\u00E9rences -->\n <mat-divider *ngIf=\"config.showPreferences\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"config.showPreferences\" mat-menu-item [matMenuTriggerFor]=\"preferencesSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Pr\u00E9f\u00E9rences</span>\n </button>\n\n <!-- Switch chart / table -->\n <mat-divider *ngIf=\"hasSwitchView()\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"hasSwitchView()\" mat-menu-item type=\"button\" class=\"organizer-menu-trigger\" (click)=\"onSwitchView()\">\n <mat-icon class=\"organizer-menu-export-icon\">{{ config.switchView?.currentView === 'chart' ? 'table_chart' : 'bar_chart' }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ config.switchView?.currentView === 'chart' ? 'Tableau' : 'Graphique' }}</span>\n </button>\n\n</mat-menu>\n\n<!-- Sous-menu : actions du visuel -->\n<mat-menu #actionsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button *ngIf=\"isCopyActionVisible()\" type=\"button\" class=\"organizer-submenu-item\"\n (mousedown)=\"onCopyVisual()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">content_copy</mat-icon>\n Copier\n </button>\n <button *ngIf=\"isFullscreenActionVisible()\" type=\"button\" class=\"organizer-submenu-item\"\n (mousedown)=\"onToggleFullscreen()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">{{ config.isFullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\n {{ config.isFullscreen ? 'Quitter le plein \u00E9cran' : 'Plein \u00E9cran' }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Export graphique -->\n<mat-menu #exportSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button *ngIf=\"config.onExportVisual\" type=\"button\" class=\"organizer-submenu-item\"\n (mousedown)=\"onExportVisual()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">image</mat-icon>\n Visuel\n </button>\n <button *ngIf=\"config.onExportData\" type=\"button\" class=\"organizer-submenu-item\"\n (mousedown)=\"onExportData()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">table_chart</mat-icon>\n Donn\u00E9es\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Champs chart (X + Y) -->\n<mat-menu #champsSubMenu=\"matMenu\" panelClass=\"organizer-champs-panel\">\n <div class=\"organizer-champs-wrapper\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n\n <!-- Bloc X -->\n <div class=\"organizer-champs-block\" *ngIf=\"config.xFields?.length\">\n <span class=\"organizer-champs-block-title\">Axe horizontal \u2014 X</span>\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let xField of config.xFields\"\n [class.active]=\"state?.selectedX === xField.id\"\n [disabled]=\"xField.disabled\"\n (mousedown)=\"onXFieldSelect(xField.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedX === xField.id ? '\u2713' : '' }}</span>\n {{ xField.label }}\n </button>\n </div>\n\n <mat-divider *ngIf=\"config.xFields?.length && config.yFields?.length\" class=\"organizer-champs-divider\"></mat-divider>\n\n <!-- Bloc Y -->\n <div class=\"organizer-champs-block\" *ngIf=\"config.yFields?.length\">\n <span class=\"organizer-champs-block-title\">Axe vertical \u2014 Y</span>\n <ng-container *ngFor=\"let yField of config.yFields\">\n\n <!-- Y simple (Count sans agr\u00E9gat ni stack) -->\n <!-- Y simple (Count ou m\u00E9trique directe) -->\n <button *ngIf=\"!yField.aggregates?.length\"\n type=\"button\" class=\"organizer-submenu-item\"\n [class.active]=\"isYActive(yField.id)\"\n [disabled]=\"yField.disabled\"\n (mousedown)=\"onYFieldSelect(yField.id)\">\n <span class=\"organizer-submenu-check\">{{ isYActive(yField.id) ? '\u2713' : '' }}</span>\n {{ yField.label }}\n </button>\n\n <!-- Y avec agr\u00E9gats \u2192 sous-menu -->\n <button *ngIf=\"yField.aggregates?.length\"\n type=\"button\" class=\"organizer-submenu-item organizer-submenu-item--has-children\"\n [class.active]=\"isYActive(yField.id)\"\n [disabled]=\"yField.disabled\"\n [matMenuTriggerFor]=\"yAggSubMenu\"\n [matMenuTriggerData]=\"{ yField: yField }\"\n (mousedown)=\"$event.stopPropagation()\">\n <span class=\"organizer-submenu-check\">{{ isYActive(yField.id) ? '\u2713' : '' }}</span>\n {{ yField.label }}\n <mat-icon class=\"organizer-submenu-arrow\">chevron_right</mat-icon>\n </button>\n\n </ng-container>\n </div>\n\n </div>\n</mat-menu>\n\n<!-- Sous-menu dynamique : agr\u00E9gats d'un champ Y -->\n<mat-menu #yAggSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <ng-template matMenuContent let-yField=\"yField\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let agg of yField.aggregates\"\n [class.active]=\"isYAggregateActive(yField.id, agg.id)\"\n (mousedown)=\"onYAggregateSelect(yField.id, agg.id)\">\n <span class=\"organizer-submenu-check\">{{ isYAggregateActive(yField.id, agg.id) ? '\u2713' : '' }}</span>\n {{ agg.label }}\n </button>\n </div>\n </ng-template>\n</mat-menu>\n\n<!-- Sous-menu : Champs table (toggle colonnes) -->\n<mat-menu #fieldsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let field of config.fields\"\n [class.active]=\"isFieldVisible(field.id)\"\n (mousedown)=\"onFieldToggle(field.id, !isFieldVisible(field.id))\">\n <span class=\"organizer-submenu-check\">{{ isFieldVisible(field.id) ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"field.icon\" class=\"organizer-submenu-icon\">{{ field.icon }}</mat-icon> {{ field.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Grouper par -->\n<mat-menu #groupsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let group of config.groups\"\n [class.active]=\"state?.selectedGroupBy === group.id\"\n (mousedown)=\"onGroupBySelect(group.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedGroupBy === group.id ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"group.icon\" class=\"organizer-submenu-icon\">{{ group.icon }}</mat-icon> {{ group.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Filtrer par -->\n<mat-menu #slicesSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let slice of config.slices\"\n [class.active]=\"state?.selectedSlices?.includes(slice.id)\"\n (mousedown)=\"onSliceClick(slice.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedSlices?.includes(slice.id) ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"slice.icon\" class=\"organizer-submenu-icon\">{{ slice.icon }}</mat-icon> {{ slice.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Template -->\n<mat-menu #templateSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let tmpl of config.templates\"\n [class.active]=\"state?.selectedTemplate === tmpl.id\"\n [title]=\"tmpl.description || ''\"\n (mousedown)=\"onTemplateSelect(tmpl.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedTemplate === tmpl.id ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"tmpl.icon\" class=\"organizer-submenu-icon\">{{ tmpl.icon }}</mat-icon>\n {{ tmpl.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Pr\u00E9f\u00E9rences -->\n<mat-menu #preferencesSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\" (mousedown)=\"onPreferencesEdit()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">edit</mat-icon>\u00C9diter\n </button>\n <button type=\"button\" class=\"organizer-submenu-item\" (mousedown)=\"onPreferencesSave()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">save</mat-icon>Sauvegarder\n </button>\n <button type=\"button\" class=\"organizer-submenu-item\" [disabled]=\"!config.hasSavedPreferences\" (mousedown)=\"onPreferencesClear()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">delete_outline</mat-icon>R\u00E9initialiser\n </button>\n </div>\n</mat-menu>\n\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}.organizer-btn{position:relative;display:block;height:34px;width:34px;border:1px solid #e0e0e0;border-radius:8px;background:#fff;padding:0;overflow:hidden;cursor:pointer;box-sizing:border-box}.organizer-btn:hover{border-color:#9e9e9e}.organizer-btn-icon.mat-icon,.organizer-btn-icon.material-icons{position:absolute;inset:0;display:block!important;width:18px!important;height:18px!important;margin:auto!important;padding:0!important;font-size:18px!important;line-height:18px!important;text-align:center;vertical-align:middle;transform:none;color:#000}.mat-mdc-menu-panel:has(.organizer-menu-label){min-width:170px!important;max-width:320px!important;overflow:visible!important}.mat-mdc-menu-panel:has(.organizer-menu-label) .mat-mdc-menu-content{padding:4px 0!important}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item{min-height:42px;padding:0 14px;display:flex;align-items:center;box-sizing:border-box}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item .mdc-list-item__primary-text{display:flex;align-items:center;width:100%;overflow:hidden}.organizer-menu-label{font-size:13px;font-weight:500;color:#212121;flex:0 0 auto;white-space:nowrap;padding-right:8px}.organizer-menu-value{font-size:12px;color:#757575;flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:right}.organizer-submenu{padding:4px 6px;min-width:180px;box-sizing:border-box}.organizer-submenu .organizer-submenu-item{display:flex;align-items:center;gap:6px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;color:#212121;cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}.organizer-submenu .organizer-submenu-item:hover{background:#f5f5f5}.organizer-submenu .organizer-submenu-item.active{font-weight:600}.organizer-submenu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:#212121}.organizer-submenu-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#212121;margin-right:4px}.organizer-menu-export.mat-mdc-menu-item{min-height:42px;padding:0 14px}.organizer-menu-export-icon{font-size:16px!important;width:16px!important;height:16px!important;color:#424242;margin-right:8px}.organizer-divider{margin:4px 0!important}.organizer-champs-wrapper{padding:4px 6px;min-width:200px;box-sizing:border-box;display:flex;flex-direction:column}.organizer-champs-block{display:flex;flex-direction:column}.organizer-champs-block-title{font-size:10px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:#9e9e9e;padding:6px 2px 2px}.organizer-champs-divider{margin:4px 0!important}.organizer-champs-wrapper .organizer-submenu-item{display:flex;align-items:center;gap:6px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;font-family:inherit;color:#212121;cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}.organizer-champs-wrapper .organizer-submenu-item:hover:not([disabled]){background:#f5f5f5}.organizer-champs-wrapper .organizer-submenu-item.active{font-weight:600}.organizer-champs-wrapper .organizer-submenu-item[disabled]{opacity:.38;cursor:default}.organizer-champs-wrapper .organizer-submenu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:#212121}.organizer-champs-wrapper .organizer-submenu-item--has-children{padding-right:8px}.organizer-champs-wrapper .organizer-submenu-arrow{font-size:18px!important;width:18px!important;height:18px!important;color:#00000061;margin-left:auto}\n"] }]
367
+ args: [{ standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, MatMenuModule, MatDividerModule], selector: 'organizer-button', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<button type=\"button\" class=\"organizer-btn\" [class.organizer-btn--labeled]=\"!!config.buttonLabel\" [matMenuTriggerFor]=\"viewMenu\" #mainMenuTrigger=\"matMenuTrigger\" [attr.aria-label]=\"config.buttonLabel || 'Personnaliser la vue'\" [attr.title]=\"config.buttonLabel || 'Personnaliser la vue'\">\n <mat-icon *ngIf=\"config.showButtonIcon !== false\" class=\"organizer-btn-icon\">{{ config.buttonIcon || 'settings' }}</mat-icon>\n <span *ngIf=\"config.buttonLabel\" class=\"organizer-btn-label\">{{ config.buttonLabel }}</span>\n</button>\n\n<mat-menu #viewMenu=\"matMenu\" panelClass=\"organizer-menu-panel\">\n\n <!-- Type -->\n <button *ngIf=\"hasChartTypes()\" mat-menu-item [matMenuTriggerFor]=\"chartTypesSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Type</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeChartTypeLabel()\">{{ activeChartTypeLabel() }}</span>\n </button>\n\n <!-- Champs : mode chart (X + Y) -->\n <button *ngIf=\"hasChartFields()\" mat-menu-item [matMenuTriggerFor]=\"champsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Champs</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && (activeXLabel() || activeYLabel())\">\n {{ activeXLabel() }}<ng-container *ngIf=\"activeXLabel() && activeYLabel()\"> / </ng-container>{{ activeYLabel() }}\n </span>\n </button>\n\n <!-- Champs : mode table (toggle colonnes) -->\n <button *ngIf=\"hasTableFields()\" mat-menu-item [matMenuTriggerFor]=\"fieldsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Champs</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues\">{{ fieldsSummary() }}</span>\n </button>\n\n <!-- Grouper par -->\n <button *ngIf=\"config.groups?.length\" mat-menu-item [matMenuTriggerFor]=\"groupsSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Grouper par</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeGroupByLabel()\">{{ activeGroupByLabel() }}</span>\n </button>\n\n <!-- Filtrer par -->\n <button *ngIf=\"config.slices?.length\" mat-menu-item [matMenuTriggerFor]=\"slicesSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Filtrer par</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeSlicesLabel()\">{{ activeSlicesLabel() }}</span>\n </button>\n\n <!-- Template -->\n <button *ngIf=\"config.templates?.length\" mat-menu-item [matMenuTriggerFor]=\"templateSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Template</span>\n <span class=\"organizer-menu-value\" *ngIf=\"!hideMenuValues && activeTemplateLabel()\">{{ activeTemplateLabel() }}</span>\n </button>\n\n <!-- Actions du visuel courant -->\n <mat-divider *ngIf=\"hasActions() && hasMenuItemsBeforeActions()\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"hasActions() && hasOtherMenuItems()\" mat-menu-item [matMenuTriggerFor]=\"actionsSubMenu\" class=\"organizer-menu-trigger\">\n <mat-icon *ngIf=\"config.actions?.icon\" class=\"organizer-menu-export-icon\">{{ config.actions?.icon }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ actionsLabel() }}</span>\n </button>\n\n <!-- Actions directes lorsqu'il n'y a aucun autre item principal -->\n <ng-container *ngIf=\"hasActions() && !hasOtherMenuItems()\">\n <button *ngIf=\"isCopyActionVisible()\" mat-menu-item type=\"button\" (click)=\"onCopyVisual()\">\n <mat-icon class=\"organizer-menu-export-icon\">content_copy</mat-icon>\n <span class=\"organizer-menu-label\">Copier</span>\n </button>\n <button *ngIf=\"isFullscreenActionVisible()\" mat-menu-item type=\"button\" (click)=\"onToggleFullscreen()\">\n <mat-icon class=\"organizer-menu-export-icon\">{{ config.isFullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ config.isFullscreen ? 'Quitter le plein \u00E9cran' : 'Plein \u00E9cran' }}</span>\n </button>\n </ng-container>\n\n <!-- Export direct (mode table) -->\n <mat-divider *ngIf=\"config.showExport\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"config.showExport && !hasExportSubMenu()\" mat-menu-item type=\"button\" class=\"organizer-menu-export\" (click)=\"onExport()\">\n <mat-icon class=\"organizer-menu-export-icon\">download</mat-icon>\n <span class=\"organizer-menu-label\">Exporter</span>\n </button>\n\n <!-- Export graphique (mode chart) \u2014 ouvre un sous-menu -->\n <button *ngIf=\"config.showExport && hasExportSubMenu()\" mat-menu-item [matMenuTriggerFor]=\"exportSubMenu\" class=\"organizer-menu-trigger organizer-menu-export\">\n <mat-icon class=\"organizer-menu-export-icon\">download</mat-icon>\n <span class=\"organizer-menu-label\">Exporter</span>\n </button>\n\n <!-- Pr\u00E9f\u00E9rences -->\n <mat-divider *ngIf=\"config.showPreferences\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"config.showPreferences\" mat-menu-item [matMenuTriggerFor]=\"preferencesSubMenu\" class=\"organizer-menu-trigger\">\n <span class=\"organizer-menu-label\">Pr\u00E9f\u00E9rences</span>\n </button>\n\n <mat-divider *ngIf=\"config.showReset === true\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"config.showReset === true\" mat-menu-item type=\"button\" class=\"organizer-menu-reset\" (click)=\"onReset()\">\n <mat-icon class=\"organizer-menu-export-icon\">restart_alt</mat-icon>\n <span class=\"organizer-menu-label\">R\u00E9initialiser la vue</span>\n </button>\n\n <!-- Switch chart / table -->\n <mat-divider *ngIf=\"hasSwitchView()\" class=\"organizer-divider\"></mat-divider>\n <button *ngIf=\"hasSwitchView()\" mat-menu-item type=\"button\" class=\"organizer-menu-trigger\" (click)=\"onSwitchView()\">\n <mat-icon class=\"organizer-menu-export-icon\">{{ config.switchView?.currentView === 'chart' ? 'table_chart' : 'bar_chart' }}</mat-icon>\n <span class=\"organizer-menu-label\">{{ config.switchView?.currentView === 'chart' ? 'Tableau' : 'Graphique' }}</span>\n </button>\n\n</mat-menu>\n\n<!-- Sous-menu : types de graphique -->\n<mat-menu #chartTypesSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let chartType of config.chartTypes\"\n [class.active]=\"isChartTypeActive(chartType.id)\"\n [disabled]=\"chartType.disabled\"\n (click)=\"onChartTypeSelect(chartType.id)\">\n <span class=\"organizer-submenu-check\">{{ isChartTypeActive(chartType.id) ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"chartType.icon\" class=\"organizer-submenu-icon\">{{ chartType.icon }}</mat-icon>\n {{ chartType.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : actions du visuel -->\n<mat-menu #actionsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button *ngIf=\"isCopyActionVisible()\" type=\"button\" class=\"organizer-submenu-item\"\n (click)=\"onCopyVisual()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">content_copy</mat-icon>\n Copier\n </button>\n <button *ngIf=\"isFullscreenActionVisible()\" type=\"button\" class=\"organizer-submenu-item\"\n (click)=\"onToggleFullscreen()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">{{ config.isFullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>\n {{ config.isFullscreen ? 'Quitter le plein \u00E9cran' : 'Plein \u00E9cran' }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Export graphique -->\n<mat-menu #exportSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button *ngIf=\"config.onExportVisual\" type=\"button\" class=\"organizer-submenu-item\"\n (click)=\"onExportVisual()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">image</mat-icon>\n Visuel\n </button>\n <button *ngIf=\"config.onExportData\" type=\"button\" class=\"organizer-submenu-item\"\n (click)=\"onExportData()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">table_chart</mat-icon>\n Donn\u00E9es\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Champs chart (X + Y) -->\n<mat-menu #champsSubMenu=\"matMenu\" panelClass=\"organizer-champs-panel\">\n <div class=\"organizer-champs-wrapper\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n\n <!-- Bloc X -->\n <div class=\"organizer-champs-block\" *ngIf=\"config.xFields?.length\">\n <span class=\"organizer-champs-block-title\">Axe horizontal \u2014 X</span>\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let xField of config.xFields\"\n [class.active]=\"state?.selectedX === xField.id\"\n [disabled]=\"xField.disabled\"\n (click)=\"onXFieldSelect(xField.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedX === xField.id ? '\u2713' : '' }}</span>\n {{ xField.label }}\n </button>\n </div>\n\n <mat-divider *ngIf=\"config.xFields?.length && config.yFields?.length\" class=\"organizer-champs-divider\"></mat-divider>\n\n <!-- Bloc Y -->\n <div class=\"organizer-champs-block\" *ngIf=\"config.yFields?.length\">\n <span class=\"organizer-champs-block-title\">Axe vertical \u2014 Y</span>\n <ng-container *ngFor=\"let yField of config.yFields\">\n\n <!-- Y simple (Count sans agr\u00E9gat ni stack) -->\n <!-- Y simple (Count ou m\u00E9trique directe) -->\n <button *ngIf=\"!yField.aggregates?.length\"\n type=\"button\" class=\"organizer-submenu-item\"\n [class.active]=\"isYActive(yField.id)\"\n [disabled]=\"yField.disabled\"\n (click)=\"onYFieldSelect(yField.id)\">\n <span class=\"organizer-submenu-check\">{{ isYActive(yField.id) ? '\u2713' : '' }}</span>\n {{ yField.label }}\n </button>\n\n <!-- Y avec agr\u00E9gats \u2192 sous-menu -->\n <button *ngIf=\"yField.aggregates?.length\"\n type=\"button\" class=\"organizer-submenu-item organizer-submenu-item--has-children\"\n [class.active]=\"isYActive(yField.id)\"\n [disabled]=\"yField.disabled\"\n [matMenuTriggerFor]=\"yAggSubMenu\"\n [matMenuTriggerData]=\"{ yField: yField }\"\n (mousedown)=\"$event.stopPropagation()\">\n <span class=\"organizer-submenu-check\">{{ isYActive(yField.id) ? '\u2713' : '' }}</span>\n {{ yField.label }}\n <mat-icon class=\"organizer-submenu-arrow\">chevron_right</mat-icon>\n </button>\n\n </ng-container>\n </div>\n\n </div>\n</mat-menu>\n\n<!-- Sous-menu dynamique : agr\u00E9gats d'un champ Y -->\n<mat-menu #yAggSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <ng-template matMenuContent let-yField=\"yField\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let agg of yField.aggregates\"\n [class.active]=\"isYAggregateActive(yField.id, agg.id)\"\n (click)=\"onYAggregateSelect(yField.id, agg.id)\">\n <span class=\"organizer-submenu-check\">{{ isYAggregateActive(yField.id, agg.id) ? '\u2713' : '' }}</span>\n {{ agg.label }}\n </button>\n </div>\n </ng-template>\n</mat-menu>\n\n<!-- Sous-menu : Champs table (toggle colonnes) -->\n<mat-menu #fieldsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let field of config.fields\"\n [class.active]=\"isFieldVisible(field.id)\"\n (click)=\"onFieldToggle(field.id, !isFieldVisible(field.id))\">\n <span class=\"organizer-submenu-check\">{{ isFieldVisible(field.id) ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"field.icon\" class=\"organizer-submenu-icon\">{{ field.icon }}</mat-icon> {{ field.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Grouper par -->\n<mat-menu #groupsSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let group of config.groups\"\n [class.active]=\"state?.selectedGroupBy === group.id\"\n (click)=\"onGroupBySelect(group.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedGroupBy === group.id ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"group.icon\" class=\"organizer-submenu-icon\">{{ group.icon }}</mat-icon> {{ group.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Filtrer par -->\n<mat-menu #slicesSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let slice of config.slices\"\n [class.active]=\"state?.selectedSlices?.includes(slice.id)\"\n (click)=\"onSliceClick(slice.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedSlices?.includes(slice.id) ? '\u2713' : '' }}</span> <mat-icon *ngIf=\"slice.icon\" class=\"organizer-submenu-icon\">{{ slice.icon }}</mat-icon> {{ slice.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Template -->\n<mat-menu #templateSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\"\n *ngFor=\"let tmpl of config.templates\"\n [class.active]=\"state?.selectedTemplate === tmpl.id\"\n [title]=\"tmpl.description || ''\"\n (click)=\"onTemplateSelect(tmpl.id)\">\n <span class=\"organizer-submenu-check\">{{ state?.selectedTemplate === tmpl.id ? '\u2713' : '' }}</span>\n <mat-icon *ngIf=\"tmpl.icon\" class=\"organizer-submenu-icon\">{{ tmpl.icon }}</mat-icon>\n {{ tmpl.label }}\n </button>\n </div>\n</mat-menu>\n\n<!-- Sous-menu : Pr\u00E9f\u00E9rences -->\n<mat-menu #preferencesSubMenu=\"matMenu\" panelClass=\"organizer-submenu-panel\">\n <div class=\"organizer-submenu\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"organizer-submenu-item\" (click)=\"onPreferencesEdit()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">edit</mat-icon>\u00C9diter\n </button>\n <button type=\"button\" class=\"organizer-submenu-item\" (click)=\"onPreferencesSave()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">save</mat-icon>Sauvegarder\n </button>\n <button type=\"button\" class=\"organizer-submenu-item\" [disabled]=\"!config.hasSavedPreferences\" (click)=\"onPreferencesClear()\">\n <span class=\"organizer-submenu-check\"></span>\n <mat-icon class=\"organizer-submenu-icon\">delete_outline</mat-icon>R\u00E9initialiser\n </button>\n </div>\n</mat-menu>\n\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}.organizer-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;height:var(--jqt-organizer-button-height, 34px);width:var(--jqt-organizer-button-width, 34px);min-width:var(--jqt-organizer-button-min-width, 34px);border:1px solid var(--jqt-organizer-button-border-color, #e0e0e0);border-radius:var(--jqt-organizer-button-radius, 8px);background:var(--jqt-organizer-button-background, #fff);padding:0;overflow:hidden;cursor:pointer;box-sizing:border-box}.organizer-btn:hover{border-color:var(--jqt-organizer-button-hover-border-color, #9e9e9e);background:var(--jqt-organizer-button-hover-background, var(--jqt-organizer-button-background, #fff))}.organizer-btn--labeled{width:auto;padding:0 12px}.organizer-btn-label{font-size:13px;font-weight:600;line-height:1;white-space:nowrap}.organizer-btn-icon.mat-icon,.organizer-btn-icon.material-icons{position:static;display:block!important;width:18px!important;height:18px!important;margin:0!important;padding:0!important;font-size:18px!important;line-height:18px!important;text-align:center;vertical-align:middle;transform:none;color:var(--jqt-organizer-button-icon-color, #000000)}.mat-mdc-menu-panel:has(.organizer-menu-label){min-width:170px!important;max-width:320px!important;overflow:visible!important}.mat-mdc-menu-panel:has(.organizer-menu-label) .mat-mdc-menu-content{padding:4px 0!important}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item{min-height:42px;padding:0 14px;display:flex;align-items:center;box-sizing:border-box}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item .mat-mdc-menu-item-text{display:flex;align-items:center;flex:1 1 auto;min-width:0;max-width:calc(100% - 20px);overflow:hidden;white-space:nowrap}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item .organizer-menu-label,.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item .organizer-menu-value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mat-mdc-menu-panel:has(.organizer-menu-label) .organizer-menu-trigger.mat-mdc-menu-item .organizer-menu-value{display:block}.organizer-menu-label{font-size:13px;font-weight:500;color:#212121;flex:0 0 auto;white-space:nowrap;padding-right:8px}.organizer-menu-value{font-size:12px;color:#757575;flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:right}.organizer-submenu{padding:4px 6px;min-width:180px;box-sizing:border-box}.organizer-submenu .organizer-submenu-item{display:flex;align-items:center;gap:6px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;color:#212121;cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}.organizer-submenu .organizer-submenu-item:hover{background:#f5f5f5}.organizer-submenu .organizer-submenu-item.active{font-weight:600}.organizer-submenu .organizer-submenu-item[disabled]{opacity:.38;cursor:default}.organizer-submenu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:#212121}.organizer-submenu-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#212121;margin-right:4px}.organizer-menu-export.mat-mdc-menu-item{min-height:42px;padding:0 14px}.organizer-menu-export-icon{font-size:16px!important;width:16px!important;height:16px!important;color:#424242;margin-right:8px}.organizer-divider{margin:4px 0!important}.organizer-champs-wrapper{padding:4px 6px;min-width:200px;box-sizing:border-box;display:flex;flex-direction:column}.organizer-champs-block{display:flex;flex-direction:column}.organizer-champs-block-title{font-size:10px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:#9e9e9e;padding:6px 2px 2px}.organizer-champs-divider{margin:4px 0!important}.organizer-champs-wrapper .organizer-submenu-item{display:flex;align-items:center;gap:6px;width:100%;padding:7px 8px;border:none;background:transparent;border-radius:6px;font-size:13px;font-family:inherit;color:#212121;cursor:pointer;text-align:left;box-sizing:border-box;white-space:nowrap}.organizer-champs-wrapper .organizer-submenu-item:hover:not([disabled]){background:#f5f5f5}.organizer-champs-wrapper .organizer-submenu-item.active{font-weight:600}.organizer-champs-wrapper .organizer-submenu-item[disabled]{opacity:.38;cursor:default}.organizer-champs-wrapper .organizer-submenu-check{flex-shrink:0;width:16px;text-align:center;font-size:12px;color:#212121}.organizer-champs-wrapper .organizer-submenu-item--has-children{padding-right:8px}.organizer-champs-wrapper .organizer-submenu-arrow{font-size:18px!important;width:18px!important;height:18px!important;color:#00000061;margin-left:auto}\n"] }]
338
368
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { config: [{
339
369
  type: Input
340
370
  }], state: [{
@@ -349,4 +379,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
349
379
  type: ViewChild,
350
380
  args: ['mainMenuTrigger']
351
381
  }] } });
352
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnYW5pemVyLWJ1dHRvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbmV0ZW1lL2pxdWVyeS1vcmdhbml6ZXIvc3JjL2xpYi9vcmdhbml6ZXItYnV0dG9uL29yZ2FuaXplci1idXR0b24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb25ldGVtZS9qcXVlcnktb3JnYW5pemVyL3NyYy9saWIvb3JnYW5pemVyLWJ1dHRvbi9vcmdhbml6ZXItYnV0dG9uLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQVUsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQWEsU0FBUyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3BLLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDN0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDN0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRzNDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQy9GLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7Ozs7O0FBVzdELE1BQU0sT0FBTyx3QkFBd0I7SUFjbkMsWUFBb0Is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QjtzQkFBekIsTUFBTTtnQkFPdUIsZUFBZTtzQkFBNUMsU0FBUzt1QkFBQyxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgT25Jbml0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIE9uRGVzdHJveSwgVmlld0NoaWxkLCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE1hdEJ1dHRvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyBNYXRNZW51TW9kdWxlLCBNYXRNZW51VHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL21lbnUnO1xuaW1wb3J0IHsgTWF0RGl2aWRlck1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpdmlkZXInO1xuaW1wb3J0IHsgU3ViamVjdCwgaXNPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE9yZ2FuaXplckNvbmZpZywgT3JnYW5pemVyQnV0dG9uRXZlbnQsIE9yZ2FuaXplclNsaWNlU3RhdGUsIE9yZ2FuaXplclN0YXRlIH0gZnJvbSAnLi4vbW9kZWxzJztcbmltcG9ydCB7IG5vcm1hbGl6ZU9yZ2FuaXplclN0YXRlLCByZXNvbHZlTWF0Y2hpbmdUZW1wbGF0ZUlkIH0gZnJvbSAnLi4vbW9kZWxzL29yZ2FuaXplci11dGlscyc7XG5pbXBvcnQgeyBUZW1wbGF0ZU1hbmFnZXIgfSBmcm9tICcuL3RlbXBsYXRlLW1hbmFnZXIudXRpbGl0eSc7XG5cbkBDb21wb25lbnQoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbIENvbW1vbk1vZHVsZSwgTWF0QnV0dG9uTW9kdWxlLCBNYXRJY29uTW9kdWxlLCBNYXRNZW51TW9kdWxlLCBNYXREaXZpZGVyTW9kdWxlIF0sXG4gIHNlbGVjdG9yOiAnb3JnYW5pemVyLWJ1dHRvbicsXG4gIHRlbXBsYXRlVXJsOiAnLi9vcmdhbml6ZXItYnV0dG9uLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vb3JnYW5pemVyLWJ1dHRvbi5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBPcmdhbml6ZXJCdXR0b25Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIGNvbmZpZyE6IE9yZ2FuaXplckNvbmZpZztcbiAgQElucHV0KCkgc3RhdGU/OiBPcmdhbml6ZXJTdGF0ZTtcbiAgQElucHV0KCkgaGlkZU1lbnVWYWx1ZXMgPSBmYWxzZTtcbiAgQE91dHB1dCgpIHZpZXdDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPE9yZ2FuaXplckJ1dHRvbkV2ZW50PigpO1xuICBAT3V0cHV0KCkgc2xpY2VTdGF0ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8T3JnYW5pemVyU2xpY2VTdGF0ZSB8IG51bGw+KCk7XG5cbiAgbG9hZGluZ0ZpZWxkSWQ/OiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBmaWVsZERhdGFDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBhbnlbXT4oKTtcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgQFZpZXdDaGlsZCgnbWFpbk1lbnVUcmlnZ2VyJykgbWFpbk1lbnVUcmlnZ2VyPzogTWF0TWVudVRyaWdnZXI7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGNvbnNvbGUuZGVidWcoJ1tPcmdhbml6ZXJCdXR0b25dIEluaXRpYWxpemVkJywge1xuICAgICAgY29uZmlnRmllbGRzOiB0aGlzLmNvbmZpZz8uZmllbGRzPy5sZW5ndGggPz8gMCxcbiAgICAgIGhhc1N0YXRlOiAhIXRoaXMuc3RhdGUsXG4gICAgICBoaWRlTWVudVZhbHVlczogdGhpcy5oaWRlTWVudVZhbHVlc1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgaXNGaWVsZFZpc2libGUoZmllbGRJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgdmlzaWJsZSA9IHRoaXMuc3RhdGU/LnZpc2libGVGaWVsZHM7XG4gICAgaWYgKCF2aXNpYmxlKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuZmllbGRzPy5maW5kKGYgPT4gZi5pZCA9PT0gZmllbGRJZCk/LnZpc2libGUgIT09IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdmlzaWJsZS5pbmNsdWRlcyhmaWVsZElkKTtcbiAgfVxuXG4gIGZpZWxkc1N1bW1hcnkoKTogc3RyaW5nIHtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMuY29uZmlnLmZpZWxkcz8ubGVuZ3RoID8/IDA7XG4gICAgY29uc3QgdmlzaWJsZSA9IHRoaXMuc3RhdGU/LnZpc2libGVGaWVsZHM/Lmxlbmd0aCA/PyB0b3RhbDtcbiAgICByZXR1cm4gYCR7dmlzaWJsZX0vJHt0b3RhbH1gO1xuICB9XG5cbiAgb25GaWVsZFRvZ2dsZShmaWVsZElkOiBzdHJpbmcsIHZpc2libGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zb2xlLmRlYnVnKCdbT3JnYW5pemVyQnV0dG9uXSBGaWVsZCB0b2dnbGVkJywgeyBmaWVsZElkLCB2aXNpYmxlIH0pO1xuICAgIGNvbnN0IHZpc2libGVGaWVsZHMgPSB0aGlzLnN0YXRlPy52aXNpYmxlRmllbGRzIHx8IFtdO1xuICAgIGNvbnN0IHVwZGF0ZWQgPSB2aXNpYmxlXG4gICAgICA/IFsuLi52aXNpYmxlRmllbGRzLCBmaWVsZElkXVxuICAgICAgOiB2aXNpYmxlRmllbGRzLmZpbHRlcihmID0+IGYgIT09IGZpZWxkSWQpO1xuICAgIHRoaXMuZW1pdENoYW5nZSgnZmllbGRUb2dnbGVkJywgeyB2aXNpYmxlRmllbGRzOiB1cGRhdGVkIH0pO1xuICB9XG5cbiAgb25YRmllbGRTZWxlY3QoZmllbGRJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc29sZS5kZWJ1ZygnW09yZ2FuaXplckJ1dHRvbl0gWCBmaWVsZCBzZWxlY3RlZCcsIHsgZmllbGRJZCwgY3VycmVudDogdGhpcy5zdGF0ZT8uc2VsZWN0ZWRYIH0pO1xuICAgIC8vIMOJdml0ZSB1bmUgcmVxdcOqdGUgaW51dGlsZSBzaSBsZSBYIGVzdCBkw6lqw6Agc8OpbGVjdGlvbm7DqVxuICAgIGlmICh0aGlzLnN0YXRlPy5zZWxlY3RlZFggPT09IGZpZWxkSWQpIHtcbiAgICAgIGNvbnNvbGUuZGVidWcoJ1tPcmdhbml6ZXJCdXR0b25dIFggZmllbGQgYWxyZWFkeSBzZWxlY3RlZCwgc2tpcHBpbmcgZW1pdCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVtaXRDaGFuZ2UoJ3hTZWxlY3RlZCcsIHsgc2VsZWN0ZWRYOiBmaWVsZElkIH0pO1xuICB9XG5cbiAgb25ZRmllbGRTZWxlY3QoZmllbGRJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc29sZS5kZWJ1ZygnW09yZ2FuaXplckJ1dHRvbl0gWSBmaWVsZCBzZWxlY3RlZCcsIHsgZmllbGRJZCwgY3VycmVudDogdGhpcy5zdGF0ZT8uc2VsZWN0ZWRZIH0pO1xuICAgIC8vIMOJdml0ZSB1bmUgcmVxdcOqdGUgaW51dGlsZSBzaSBsZSBZIGVzdCBkw6lqw6Agc8OpbGVjdGlvbm7DqVxuICAgIGlmICh0aGlzLnN0YXRlPy5zZWxlY3RlZFkgPT09IGZpZWxkSWQpIHtcbiAgICAgIGNvbnNvbGUuZGVidWcoJ1tPcmdhbml6ZXJCdXR0b25dIFkgZmllbGQgYWxyZWFkeSBzZWxlY3RlZCwgc2tpcHBpbmcgZW1pdCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVtaXRDaGFuZ2UoJ3lTZWxlY3RlZCcsIHtcbiAgICAgIHNlbGVjdGVkWTogZmllbGRJZCxcbiAgICAgIHNlbGVjdGVkWUFnZ3JlZ2F0ZTogdW5kZWZpbmVkXG4gICAgfSk7XG4gIH1cblxuICBvbllBZ2dyZWdhdGVTZWxlY3QoeUZpZWxkSWQ6IHN0cmluZywgYWdncmVnYXRlSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnNvbGUuZGVidWcoJ1tPcmdhbml6ZXJCdXR0b25dIFkgYWdncmVnYXRlIHNlbGVjdGVkJywgeyB5RmllbGRJZCwgYWdncmVnYXRlSWQsIGN1cnJlbnQ6IHRoaXMuc3RhdGU/LnNlbGVjdGVkWUFnZ3JlZ2F0ZSB9KTtcbiAgICAvLyDDiXZpdGUgdW5lIHJlcXXDqnRlIGludXRpbGUgc2kgbCdhZ2dyZWdhdGUgZXN0IGTDqWrDoCBzw6lsZWN0aW9ubsOpXG4gICAgaWYgKHRoaXMuc3RhdGU/LnNlbGVjdGVkWUFnZ3JlZ2F0ZSA9PT0gYWdncmVnYXRlSWQgJiYgdGhpcy5zdGF0ZT8uc2VsZWN0ZWRZID09PSB5RmllbGRJZCkge1xuICAgICAgY29uc29sZS5kZWJ1ZygnW09yZ2FuaXplckJ1dHRvbl0gWSBhZ2dyZWdhdGUgYWxyZWFkeSBzZWxlY3RlZCwgc2tpcHBpbmcgZW1pdCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVtaXRDaGFuZ2UoJ3lTZWxlY3RlZCcsIHtcbiAgICAgIHNlbGVjdGVkWTogeUZpZWxkSWQsXG4gICAgICBzZWxlY3RlZFlBZ2dyZWdhdGU6IGFnZ3JlZ2F0ZUlkXG4gICAgfSk7XG4gIH1cblxuICBvbkdyb3VwQnlTZWxlY3QoZ3JvdXBJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc29sZS5kZWJ1ZygnW09yZ2FuaXplckJ1dHRvbl0gR3JvdXAgYnkgc2VsZWN0ZWQnLCB7IGdyb3VwSWQgfSk7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuc3RhdGUuc2VsZWN0ZWRHcm91cEJ5O1xuICAgIHRoaXMuZW1pdENoYW5nZSgnZ3JvdXBCeVNlbGVjdGVkJywgeyBzZWxlY3RlZEdyb3VwQnk6IGN1cnJlbnQgPT09IGdyb3VwSWQgPyB1bmRlZmluZWQgOiBncm91cElkIH0pO1xuICB9XG5cbiAgb25UZW1wbGF0ZVNlbGVjdCh0ZW1wbGF0ZUlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zb2xlLmRlYnVnKCdbT3JnYW5pemVyQnV0dG9uXSBUZW1wbGF0ZSBzZWxlY3RlZCcsIHsgdGVtcGxhdGVJZCB9KTtcbiAgICBpZiAoIXRoaXMuY29uZmlnLnRlbXBsYXRlcz8ubGVuZ3RoKSByZXR1cm47XG5cbiAgICBjb25zdCB0ZW1wbGF0ZSA9IHRoaXMuY29uZmlnLnRlbXBsYXRlcz8uZmluZCh0ID0+IHQuaWQgPT09IHRlbXBsYXRlSWQpO1xuICAgIGlmICghdGVtcGxhdGUpIHJldHVybjtcblxuICAgIGNvbnN0IG5ld1N0YXRlID0gVGVtcGxhdGVNYW5hZ2VyLmFwcGx5VGVtcGxhdGUodGVtcGxhdGUsIHRoaXMuc3RhdGUsIHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLmVtaXRDaGFuZ2UoJ3RlbXBsYXRlU2VsZWN0ZWQnLCBuZXdTdGF0ZSk7XG4gICAgdGhpcy5zeW5jU2xpY2VTdGF0ZShuZXdTdGF0ZS5zZWxlY3RlZFNsaWNlcyk7XG4gIH1cblxuICBvblNsaWNlQ2xpY2soc2xpY2VJZD86IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnNvbGUuZGVidWcoJ1tPcmdhbml6ZXJCdXR0b25dIFNsaWNlIGNsaWNrZWQnLCB7IHNsaWNlSWQgfSk7XG4gICAgaWYgKHRoaXMuY29uZmlnLm9uU2xpY2VDbGljaykge1xuICAgICAgdGhpcy5jb25maWcub25TbGljZUNsaWNrKCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZWN0ZWRTbGljZXMgPSB0aGlzLnN0YXRlPy5zZWxlY3RlZFNsaWNlcyB8fCBbXTtcbiAgICBsZXQgdXBkYXRlZDogc3RyaW5nW107XG4gICAgaWYgKHNsaWNlSWQpIHtcbiAgICAgIHVwZGF0ZWQgPSBzZWxlY3RlZFNsaWNlcy5pbmNsdWRlcyhzbGljZUlkKVxuICAgICAgICA/IHNlbGVjdGVkU2xpY2VzLmZpbHRlcihpZCA9PiBpZCAhPT0gc2xpY2VJZClcbiAgICAgICAgOiBbLi4uc2VsZWN0ZWRTbGljZXMsIHNsaWNlSWRdO1xuICAgIH0gZWxzZSB7XG4gICAgICB1cGRhdGVkID0gc2VsZWN0ZWRTbGljZXM7XG4gICAgfVxuXG4gICAgaWYgKHVwZGF0ZWQubGVuZ3RoID09PSAwIHx8ICFzbGljZUlkIHx8ICF0aGlzLmNvbmZpZy5vbkZldGNoU2xpY2VEYXRhKSB7XG4gICAgICB0aGlzLnNsaWNlU3RhdGVDaGFuZ2UuZW1pdChudWxsKTtcbiAgICAgIHRoaXMuZW1pdENoYW5nZSgnc2xpY2VTZWxlY3RlZCcsIHsgc2VsZWN0ZWRTbGljZXM6IHVwZGF0ZWQgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zeW5jU2xpY2VTdGF0ZSh1cGRhdGVkLCAoKSA9PiB7XG4gICAgICB0aGlzLmVtaXRDaGFuZ2UoJ3NsaWNlU2VsZWN0ZWQnLCB7IHNlbGVjdGVkU2xpY2VzOiB1cGRhdGVkIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW5jU2xpY2VTdGF0ZShzZWxlY3RlZFNsaWNlczogc3RyaW5nW10gfCB1bmRlZmluZWQsIG9uTG9hZGVkPzogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IHNsaWNlSWQgPSBzZWxlY3RlZFNsaWNlcz8uWzBdO1xuICAgIGlmICghc2xpY2VJZCB8fCAhdGhpcy5jb25maWcub25GZXRjaFNsaWNlRGF0YSkge1xuICAgICAgdGhpcy5zbGljZVN0YXRlQ2hhbmdlLmVtaXQobnVsbCk7XG4gICAgICBvbkxvYWRlZD8uKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc2xpY2UgPSB0aGlzLmNvbmZpZy5zbGljZXM/LmZpbmQocyA9PiBzLmlkID09PSBzbGljZUlkKTtcbiAgICBpZiAoIXNsaWNlKSB7XG4gICAgICB0aGlzLnNsaWNlU3RhdGVDaGFuZ2UuZW1pdChudWxsKTtcbiAgICAgIG9uTG9hZGVkPy4oKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLmNvbmZpZy5vbkZldGNoU2xpY2VEYXRhKHNsaWNlSWQpO1xuICAgIGNvbnN0IGhhbmRsZURhdGEgPSAodGFza3M6IGFueVtdKSA9PiB7XG4gICAgICB0aGlzLnNsaWNlU3RhdGVDaGFuZ2UuZW1pdCh7XG4gICAgICAgIHNsaWNlQ29uZmlnczogW3sgdGl0bGU6IHNsaWNlLmxhYmVsID8/IHNsaWNlSWQsIGNvbHVtbktleTogc2xpY2VJZCB9XSxcbiAgICAgICAgdGFza3MsXG4gICAgICAgIGZpbHRlckFwcGxpZWQ6IGZhbHNlICAvLyBQYW5lbCB2aWVudCBkJ8OqdHJlIG91dmVydCwgcGFzIGRlIGZpbHRyZSBzw6lsZWN0aW9ubsOpIGVuY29yZVxuICAgICAgfSk7XG4gICAgICBvbkxvYWRlZD8uKCk7XG4gICAgfTtcblxuICAgIGlmIChpc09ic2VydmFibGUocmVzdWx0KSkge1xuICAgICAgcmVzdWx0LnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoeyBuZXh0OiBoYW5kbGVEYXRhIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQudGhlbihoYW5kbGVEYXRhKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBsb2FkRmllbGREYXRhKGZpZWxkSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmZpZWxkRGF0YUNhY2hlLmhhcyhmaWVsZElkKSkgcmV0dXJuO1xuICAgIGlmICghdGhpcy5jb25maWcub25GZXRjaEZpZWxkRGF0YSkgcmV0dXJuO1xuXG4gICAgY29uc3QgZmllbGQgPSB0aGlzLmNvbmZpZy5maWVsZHM/LmZpbmQoZiA9PiBmLmlkID09PSBmaWVsZElkKTtcbiAgICBpZiAoIWZpZWxkKSByZXR1cm47XG5cbiAgICB0aGlzLmxvYWRpbmdGaWVsZElkID0gZmllbGRJZDtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy5jb25maWcub25GZXRjaEZpZWxkRGF0YShmaWVsZElkKTtcbiAgICAgIHRoaXMuZmllbGREYXRhQ2FjaGUuc2V0KGZpZWxkSWQsIGRhdGEpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmxvYWRpbmdGaWVsZElkID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgb25FeHBvcnQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29uZmlnLm9uRXhwb3J0KSB0aGlzLmNvbmZpZy5vbkV4cG9ydCgpO1xuICAgIHRoaXMubWFpbk1lbnVUcmlnZ2VyPy5jbG9zZU1lbnUoKTtcbiAgfVxuXG4gIG9uRXhwb3J0VmlzdWFsKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbmZpZy5vbkV4cG9ydFZpc3VhbCkgdGhpcy5jb25maWcub25FeHBvcnRWaXN1YWwoKTtcbiAgICB0aGlzLm1haW5NZW51VHJpZ2dlcj8uY2xvc2VNZW51KCk7XG4gIH1cblxuICBvbkV4cG9ydERhdGEoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29uZmlnLm9uRXhwb3J0RGF0YSkgdGhpcy5jb25maWcub25FeHBvcnREYXRhKCk7XG4gICAgdGhpcy5tYWluTWVudVRyaWdnZXI/LmNsb3NlTWVudSgpO1xuICB9XG5cbiAgaGFzRXhwb3J0U3ViTWVudSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISEodGhpcy5jb25maWcub25FeHBvcnRWaXN1YWwgfHwgdGhpcy5jb25maWcub25FeHBvcnREYXRhKTtcbiAgfVxuXG4gIGlzQ29weUFjdGlvblZpc2libGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5jb25maWcub25Db3B5VmlzdWFsICYmIHRoaXMuY29uZmlnLmFjdGlvbnM/LnNob3dDb3B5ICE9PSBmYWxzZTtcbiAgfVxuXG4gIGlzRnVsbHNjcmVlbkFjdGlvblZpc2libGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5jb25maWcub25Ub2dnbGVGdWxsc2NyZWVuICYmIHRoaXMuY29uZmlnLmFjdGlvbnM/LnNob3dGdWxsc2NyZWVuICE9PSBmYWxzZTtcbiAgfVxuXG4gIGhhc0FjdGlvbnMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnNob3dBY3Rpb25zID09PSB0cnVlICYmICh0aGlzLmlzQ29weUFjdGlvblZpc2libGUoKSB8fCB0aGlzLmlzRnVsbHNjcmVlbkFjdGlvblZpc2libGUoKSk7XG4gIH1cblxuICBoYXNNZW51SXRlbXNCZWZvcmVBY3Rpb25zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmhhc0NoYXJ0RmllbGRzKClcbiAgICAgIHx8IHRoaXMuaGFzVGFibGVGaWVsZHMoKVxuICAgICAgfHwgKHRoaXMuY29uZmlnLmdyb3Vwcz8ubGVuZ3RoID8/IDApID4gMFxuICAgICAgfHwgKHRoaXMuY29uZmlnLnNsaWNlcz8ubGVuZ3RoID8/IDApID4gMFxuICAgICAgfHwgKHRoaXMuY29uZmlnLnRlbXBsYXRlcz8ubGVuZ3RoID8/IDApID4gMDtcbiAgfVxuXG4gIGhhc090aGVyTWVudUl0ZW1zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmhhc01lbnVJdGVtc0JlZm9yZUFjdGlvbnMoKVxuICAgICAgfHwgISF0aGlzLmNvbmZpZy5zaG93RXhwb3J0XG4gICAgICB8fCAhIXRoaXMuY29uZmlnLnNob3dQcmVmZXJlbmNlc1xuICAgICAgfHwgdGhpcy5oYXNTd2l0Y2hWaWV3KCk7XG4gIH1cblxuICBhY3Rpb25zTGFiZWwoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5jb25maWcuYWN0aW9ucz8ubGFiZWwpIHJldHVybiB0aGlzLmNvbmZpZy5hY3Rpb25zLmxhYmVsO1xuICAgIHJldHVybiB0aGlzLmlzQ29weUFjdGlvblZpc2libGUoKSAmJiB0aGlzLmlzRnVsbHNjcmVlbkFjdGlvblZpc2libGUoKSA/ICdBY3Rpb25zJyA6ICdBY3Rpb24nO1xuICB9XG5cbiAgb25Db3B5VmlzdWFsKCk6IHZvaWQge1xuICAgIHRoaXMuY29uZmlnLm9uQ29weVZpc3VhbD8uKCk7XG4gICAgdGhpcy5tYWluTWVudVRyaWdnZXI/LmNsb3NlTWVudSgpO1xuICB9XG5cbiAgb25Ub2dnbGVGdWxsc2NyZWVuKCk6IHZvaWQge1xuICAgIHRoaXMuY29uZmlnLm9uVG9nZ2xlRnVsbHNjcmVlbj8uKCk7XG4gICAgdGhpcy5tYWluTWVudVRyaWdnZXI/LmNsb3NlTWVudSgpO1xuICB9XG5cbiAgaGFzU3dpdGNoVmlldygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmNvbmZpZy5zd2l0Y2hWaWV3O1xuICB9XG5cbiAgb25Td2l0Y2hWaWV3KCk6IHZvaWQge1xuICAgIGNvbnN0IHN2ID0gdGhpcy5jb25maWcuc3dpdGNoVmlldztcbiAgICBpZiAoIXN2KSByZXR1cm47XG4gICAgY29uc3QgbmV3VmlldzogJ2NoYXJ0JyB8ICd0YWJsZScgPSBzdi5jdXJyZW50VmlldyA9PT0gJ2NoYXJ0JyA/ICd0YWJsZScgOiAnY2hhcnQnO1xuICAgIHN2Lm9uU3dpdGNoKG5ld1ZpZXcpO1xuICAgIHRoaXMuZW1pdENoYW5nZSgndmlld1N3aXRjaGVkJywgeyB2aWV3TW9kZTogbmV3VmlldyB9KTtcbiAgICB0aGlzLm1haW5NZW51VHJpZ2dlcj8uY2xvc2VNZW51KCk7XG4gIH1cblxuICBvblByZWZlcmVuY2VzRWRpdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jb25maWcub25QcmVmZXJlbmNlc0VkaXQpIHRoaXMuY29uZmlnLm9uUHJlZmVyZW5jZXNFZGl0KCk7XG4gICAgdGhpcy5tYWluTWVudVRyaWdnZXI/LmNsb3NlTWVudSgpO1xuICB9XG5cbiAgb25QcmVmZXJlbmNlc1NhdmUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29uZmlnLm9uUHJlZmVyZW5jZXNTYXZlKSB0aGlzLmNvbmZpZy5vblByZWZlcmVuY2VzU2F2ZSgpO1xuICAgIHRoaXMubWFpbk1lbnVUcmlnZ2VyPy5jbG9zZU1lbnUoKTtcbiAgfVxuXG4gIG9uUHJlZmVyZW5jZXNDbGVhcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jb25maWcub25QcmVmZXJlbmNlc0NsZWFyKSB0aGlzLmNvbmZpZy5vblByZWZlcmVuY2VzQ2xlYXIoKTtcbiAgICB0aGlzLm1haW5NZW51VHJpZ2dlcj8uY2xvc2VNZW51KCk7XG4gIH1cblxuICBvblJlc2V0KCk6IHZvaWQge1xuICAgIHRoaXMuZW1pdENoYW5nZSgncmVzZXQnLCB7XG4gICAgICB2aXNpYmxlRmllbGRzOiBbXSxcbiAgICAgIHNlbGVjdGVkWDogdW5kZWZpbmVkLFxuICAgICAgc2VsZWN0ZWRZOiB1bmRlZmluZWQsXG4gICAgICBzZWxlY3RlZFlBZ2dyZWdhdGU6IHVuZGVmaW5lZCxcbiAgICAgIHNlbGVjdGVkR3JvdXBCeTogdW5kZWZpbmVkLFxuICAgICAgc2VsZWN0ZWRTbGljZXM6IFtdXG4gICAgfSk7XG4gIH1cblxuICBhY3RpdmVYTGFiZWwoKTogc3RyaW5nIHtcbiAgICBjb25zdCBpZCA9IHRoaXMuc3RhdGU/LnNlbGVjdGVkWDtcbiAgICBpZiAoIWlkKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnhGaWVsZHM/LmZpbmQoZiA9PiBmLmlkID09PSBpZCk/LmxhYmVsID8/IGlkO1xuICB9XG5cbiAgYWN0aXZlWUxhYmVsKCk6IHN0cmluZyB7XG4gICAgY29uc3QgeUlkID0gdGhpcy5zdGF0ZT8uc2VsZWN0ZWRZO1xuICAgIGlmICgheUlkKSByZXR1cm4gJyc7XG4gICAgY29uc3QgeUZpZWxkID0gdGhpcy5jb25maWcueUZpZWxkcz8uZmluZChmID0+IGYuaWQgPT09IHlJZCk7XG4gICAgY29uc3QgYmFzZSA9IHlGaWVsZD8ubGFiZWwgPz8geUlkO1xuXG4gICAgaWYgKHRoaXMuc3RhdGU/LnNlbGVjdGVkWUFnZ3JlZ2F0ZSkge1xuICAgICAgY29uc3QgYWdnID0geUZpZWxkPy5hZ2dyZWdhdGVzPy5maW5kKGEgPT4gYS5pZCA9PT0gdGhpcy5zdGF0ZSEuc2VsZWN0ZWRZQWdncmVnYXRlKTtcbiAgICAgIHJldHVybiBhZ2cgPyBgJHtiYXNlfSDCtyAke2FnZy5sYWJlbH1gIDogYmFzZTtcbiAgICB9XG4gICAgcmV0dXJuIGJhc2U7XG4gIH1cblxuICBhY3RpdmVHcm91cEJ5TGFiZWwoKTogc3RyaW5nIHtcbiAgICBjb25zdCBpZCA9IHRoaXMuc3RhdGU/LnNlbGVjdGVkR3JvdXBCeTtcbiAgICBpZiAoIWlkKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmdyb3Vwcz8uZmluZChnID0+IGcuaWQgPT09IGlkKT8ubGFiZWwgPz8gaWQ7XG4gIH1cblxuICBhY3RpdmVTbGljZXNMYWJlbCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGlkcyA9IHRoaXMuc3RhdGU/LnNlbGVjdGVkU2xpY2VzO1xuICAgIGlmICghaWRzPy5sZW5ndGgpIHJldHVybiAnJztcbiAgICBpZiAoaWRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLnNsaWNlcz8uZmluZChzID0+IHMuaWQgPT09IGlkc1swXSk/LmxhYmVsID8/IGlkc1swXTtcbiAgICB9XG4gICAgcmV0dXJuIGAke2lkcy5sZW5ndGh9IHPDqWxlY3Rpb25uw6lzYDtcbiAgfVxuXG4gIGFjdGl2ZVRlbXBsYXRlTGFiZWwoKTogc3RyaW5nIHtcbiAgICBjb25zdCBpZCA9IHRoaXMuc3RhdGU/LnNlbGVjdGVkVGVtcGxhdGU7XG4gICAgaWYgKCFpZCkgcmV0dXJuICcnO1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy50ZW1wbGF0ZXM/LmZpbmQodCA9PiB0LmlkID09PSBpZCk/LmxhYmVsID8/IGlkO1xuICB9XG5cbiAgaGFzQ2hhcnRGaWVsZHMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLmNvbmZpZy54RmllbGRzPy5sZW5ndGggPz8gMCkgPiAwIHx8ICh0aGlzLmNvbmZpZy55RmllbGRzPy5sZW5ndGggPz8gMCkgPiAwO1xuICB9XG5cbiAgaGFzVGFibGVGaWVsZHMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLmNvbmZpZy5maWVsZHM/Lmxlbmd0aCA/PyAwKSA+IDA7XG4gIH1cblxuICBpc1lBY3RpdmUoeUZpZWxkSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXRlPy5zZWxlY3RlZFkgPT09IHlGaWVsZElkO1xuICB9XG5cbiAgaXNZQWdncmVnYXRlQWN0aXZlKHlGaWVsZElkOiBzdHJpbmcsIGFnZ3JlZ2F0ZUlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZT8uc2VsZWN0ZWRZID09PSB5RmllbGRJZCAmJiB0aGlzLnN0YXRlPy5zZWxlY3RlZFlBZ2dyZWdhdGUgPT09IGFnZ3JlZ2F0ZUlkO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0Q2hhbmdlKHR5cGU6IE9yZ2FuaXplckJ1dHRvbkV2ZW50Wyd0eXBlJ10sIHN0YXRlVXBkYXRlOiBQYXJ0aWFsPE9yZ2FuaXplclN0YXRlPiB8IE9yZ2FuaXplclN0YXRlKTogdm9pZCB7XG4gICAgY29uc3QgaXNGdWxsU3RhdGUgPSAnc2VsZWN0ZWRYJyBpbiBzdGF0ZVVwZGF0ZSAmJiAnc2VsZWN0ZWRUZW1wbGF0ZScgaW4gc3RhdGVVcGRhdGU7XG4gICAgY29uc3QgcmF3U3RhdGUgPSBpc0Z1bGxTdGF0ZSA/IChzdGF0ZVVwZGF0ZSBhcyBPcmdhbml6ZXJTdGF0ZSkgOiB7IC4uLnRoaXMuc3RhdGUsIC4uLnN0YXRlVXBkYXRlIH07XG4gICAgY29uc3Qgbm9ybWFsaXplZFN0YXRlID0gbm9ybWFsaXplT3JnYW5pemVyU3RhdGUocmF3U3RhdGUsIHRoaXMuY29uZmlnKTtcbiAgICBjb25zdCBldmVudDogT3JnYW5pemVyQnV0dG9uRXZlbnQgPSB7XG4gICAgICB0eXBlLFxuICAgICAgc3RhdGU6IHtcbiAgICAgICAgLi4ubm9ybWFsaXplZFN0YXRlLFxuICAgICAgICBzZWxlY3RlZFRlbXBsYXRlOiByZXNvbHZlTWF0Y2hpbmdUZW1wbGF0ZUlkKHRoaXMuY29uZmlnLnRlbXBsYXRlcywgbm9ybWFsaXplZFN0YXRlLCB0aGlzLmNvbmZpZylcbiAgICAgIH0sXG4gICAgICBzb3VyY2U6ICd1c2VyJ1xuICAgIH07XG4gICAgdGhpcy52aWV3Q2hhbmdlLmVtaXQoZXZlbnQpO1xuICB9XG59XG4iLCI8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1idG5cIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwidmlld01lbnVcIiAjbWFpbk1lbnVUcmlnZ2VyPVwibWF0TWVudVRyaWdnZXJcIiBbYXR0ci5hcmlhLWxhYmVsXT1cIidWaWV3J1wiPlxuICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItYnRuLWljb25cIj57eyBjb25maWcuYnV0dG9uSWNvbiB8fCAnc2V0dGluZ3MnIH19PC9tYXQtaWNvbj5cbjwvYnV0dG9uPlxuXG48bWF0LW1lbnUgI3ZpZXdNZW51PVwibWF0TWVudVwiIHBhbmVsQ2xhc3M9XCJvcmdhbml6ZXItbWVudS1wYW5lbFwiPlxuXG4gIDwhLS0gQ2hhbXBzIDogbW9kZSBjaGFydCAoWCArIFkpIC0tPlxuICA8YnV0dG9uICpuZ0lmPVwiaGFzQ2hhcnRGaWVsZHMoKVwiIG1hdC1tZW51LWl0ZW0gW21hdE1lbnVUcmlnZ2VyRm9yXT1cImNoYW1wc1N1Yk1lbnVcIiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXRyaWdnZXJcIj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+Q2hhbXBzPC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtdmFsdWVcIiAqbmdJZj1cIiFoaWRlTWVudVZhbHVlcyAmJiAoYWN0aXZlWExhYmVsKCkgfHwgYWN0aXZlWUxhYmVsKCkpXCI+XG4gICAgICB7eyBhY3RpdmVYTGFiZWwoKSB9fTxuZy1jb250YWluZXIgKm5nSWY9XCJhY3RpdmVYTGFiZWwoKSAmJiBhY3RpdmVZTGFiZWwoKVwiPiAvIDwvbmctY29udGFpbmVyPnt7IGFjdGl2ZVlMYWJlbCgpIH19XG4gICAgPC9zcGFuPlxuICA8L2J1dHRvbj5cblxuICA8IS0tIENoYW1wcyA6IG1vZGUgdGFibGUgKHRvZ2dsZSBjb2xvbm5lcykgLS0+XG4gIDxidXR0b24gKm5nSWY9XCJoYXNUYWJsZUZpZWxkcygpXCIgbWF0LW1lbnUtaXRlbSBbbWF0TWVudVRyaWdnZXJGb3JdPVwiZmllbGRzU3ViTWVudVwiIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtdHJpZ2dlclwiPlxuICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtbGFiZWxcIj5DaGFtcHM8L3NwYW4+XG4gICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItbWVudS12YWx1ZVwiICpuZ0lmPVwiIWhpZGVNZW51VmFsdWVzXCI+e3sgZmllbGRzU3VtbWFyeSgpIH19PC9zcGFuPlxuICA8L2J1dHRvbj5cblxuICA8IS0tIEdyb3VwZXIgcGFyIC0tPlxuICA8YnV0dG9uICpuZ0lmPVwiY29uZmlnLmdyb3Vwcz8ubGVuZ3RoXCIgbWF0LW1lbnUtaXRlbSBbbWF0TWVudVRyaWdnZXJGb3JdPVwiZ3JvdXBzU3ViTWVudVwiIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtdHJpZ2dlclwiPlxuICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtbGFiZWxcIj5Hcm91cGVyIHBhcjwvc3Bhbj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXZhbHVlXCIgKm5nSWY9XCIhaGlkZU1lbnVWYWx1ZXMgJiYgYWN0aXZlR3JvdXBCeUxhYmVsKClcIj57eyBhY3RpdmVHcm91cEJ5TGFiZWwoKSB9fTwvc3Bhbj5cbiAgPC9idXR0b24+XG5cbiAgPCEtLSBGaWx0cmVyIHBhciAtLT5cbiAgPGJ1dHRvbiAqbmdJZj1cImNvbmZpZy5zbGljZXM/Lmxlbmd0aFwiIG1hdC1tZW51LWl0ZW0gW21hdE1lbnVUcmlnZ2VyRm9yXT1cInNsaWNlc1N1Yk1lbnVcIiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXRyaWdnZXJcIj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+RmlsdHJlciBwYXI8L3NwYW4+XG4gICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItbWVudS12YWx1ZVwiICpuZ0lmPVwiIWhpZGVNZW51VmFsdWVzICYmIGFjdGl2ZVNsaWNlc0xhYmVsKClcIj57eyBhY3RpdmVTbGljZXNMYWJlbCgpIH19PC9zcGFuPlxuICA8L2J1dHRvbj5cblxuICA8IS0tIFRlbXBsYXRlIC0tPlxuICA8YnV0dG9uICpuZ0lmPVwiY29uZmlnLnRlbXBsYXRlcz8ubGVuZ3RoXCIgbWF0LW1lbnUtaXRlbSBbbWF0TWVudVRyaWdnZXJGb3JdPVwidGVtcGxhdGVTdWJNZW51XCIgY2xhc3M9XCJvcmdhbml6ZXItbWVudS10cmlnZ2VyXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1sYWJlbFwiPlRlbXBsYXRlPC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtdmFsdWVcIiAqbmdJZj1cIiFoaWRlTWVudVZhbHVlcyAmJiBhY3RpdmVUZW1wbGF0ZUxhYmVsKClcIj57eyBhY3RpdmVUZW1wbGF0ZUxhYmVsKCkgfX08L3NwYW4+XG4gIDwvYnV0dG9uPlxuXG4gIDwhLS0gQWN0aW9ucyBkdSB2aXN1ZWwgY291cmFudCAtLT5cbiAgPG1hdC1kaXZpZGVyICpuZ0lmPVwiaGFzQWN0aW9ucygpICYmIGhhc01lbnVJdGVtc0JlZm9yZUFjdGlvbnMoKVwiIGNsYXNzPVwib3JnYW5pemVyLWRpdmlkZXJcIj48L21hdC1kaXZpZGVyPlxuICA8YnV0dG9uICpuZ0lmPVwiaGFzQWN0aW9ucygpICYmIGhhc090aGVyTWVudUl0ZW1zKClcIiBtYXQtbWVudS1pdGVtIFttYXRNZW51VHJpZ2dlckZvcl09XCJhY3Rpb25zU3ViTWVudVwiIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtdHJpZ2dlclwiPlxuICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbmZpZy5hY3Rpb25zPy5pY29uXCIgY2xhc3M9XCJvcmdhbml6ZXItbWVudS1leHBvcnQtaWNvblwiPnt7IGNvbmZpZy5hY3Rpb25zPy5pY29uIH19PC9tYXQtaWNvbj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+e3sgYWN0aW9uc0xhYmVsKCkgfX08L3NwYW4+XG4gIDwvYnV0dG9uPlxuXG4gIDwhLS0gQWN0aW9ucyBkaXJlY3RlcyBsb3JzcXUnaWwgbid5IGEgYXVjdW4gYXV0cmUgaXRlbSBwcmluY2lwYWwgLS0+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJoYXNBY3Rpb25zKCkgJiYgIWhhc090aGVyTWVudUl0ZW1zKClcIj5cbiAgICA8YnV0dG9uICpuZ0lmPVwiaXNDb3B5QWN0aW9uVmlzaWJsZSgpXCIgbWF0LW1lbnUtaXRlbSB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cIm9uQ29weVZpc3VhbCgpXCI+XG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1leHBvcnQtaWNvblwiPmNvbnRlbnRfY29weTwvbWF0LWljb24+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+Q29waWVyPC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b24gKm5nSWY9XCJpc0Z1bGxzY3JlZW5BY3Rpb25WaXNpYmxlKClcIiBtYXQtbWVudS1pdGVtIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25Ub2dnbGVGdWxsc2NyZWVuKClcIj5cbiAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWV4cG9ydC1pY29uXCI+e3sgY29uZmlnLmlzRnVsbHNjcmVlbiA/ICdmdWxsc2NyZWVuX2V4aXQnIDogJ2Z1bGxzY3JlZW4nIH19PC9tYXQtaWNvbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtbGFiZWxcIj57eyBjb25maWcuaXNGdWxsc2NyZWVuID8gJ1F1aXR0ZXIgbGUgcGxlaW4gw6ljcmFuJyA6ICdQbGVpbiDDqWNyYW4nIH19PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8IS0tIEV4cG9ydCBkaXJlY3QgKG1vZGUgdGFibGUpIC0tPlxuICA8bWF0LWRpdmlkZXIgKm5nSWY9XCJjb25maWcuc2hvd0V4cG9ydFwiIGNsYXNzPVwib3JnYW5pemVyLWRpdmlkZXJcIj48L21hdC1kaXZpZGVyPlxuICA8YnV0dG9uICpuZ0lmPVwiY29uZmlnLnNob3dFeHBvcnQgJiYgIWhhc0V4cG9ydFN1Yk1lbnUoKVwiIG1hdC1tZW51LWl0ZW0gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtZXhwb3J0XCIgKGNsaWNrKT1cIm9uRXhwb3J0KClcIj5cbiAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1leHBvcnQtaWNvblwiPmRvd25sb2FkPC9tYXQtaWNvbj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+RXhwb3J0ZXI8L3NwYW4+XG4gIDwvYnV0dG9uPlxuXG4gIDwhLS0gRXhwb3J0IGdyYXBoaXF1ZSAobW9kZSBjaGFydCkg4oCUIG91dnJlIHVuIHNvdXMtbWVudSAtLT5cbiAgPGJ1dHRvbiAqbmdJZj1cImNvbmZpZy5zaG93RXhwb3J0ICYmIGhhc0V4cG9ydFN1Yk1lbnUoKVwiIG1hdC1tZW51LWl0ZW0gW21hdE1lbnVUcmlnZ2VyRm9yXT1cImV4cG9ydFN1Yk1lbnVcIiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXRyaWdnZXIgb3JnYW5pemVyLW1lbnUtZXhwb3J0XCI+XG4gICAgPG1hdC1pY29uIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtZXhwb3J0LWljb25cIj5kb3dubG9hZDwvbWF0LWljb24+XG4gICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1sYWJlbFwiPkV4cG9ydGVyPC9zcGFuPlxuICA8L2J1dHRvbj5cblxuICA8IS0tIFByw6lmw6lyZW5jZXMgLS0+XG4gIDxtYXQtZGl2aWRlciAqbmdJZj1cImNvbmZpZy5zaG93UHJlZmVyZW5jZXNcIiBjbGFzcz1cIm9yZ2FuaXplci1kaXZpZGVyXCI+PC9tYXQtZGl2aWRlcj5cbiAgPGJ1dHRvbiAqbmdJZj1cImNvbmZpZy5zaG93UHJlZmVyZW5jZXNcIiBtYXQtbWVudS1pdGVtIFttYXRNZW51VHJpZ2dlckZvcl09XCJwcmVmZXJlbmNlc1N1Yk1lbnVcIiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXRyaWdnZXJcIj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+UHLDqWbDqXJlbmNlczwvc3Bhbj5cbiAgPC9idXR0b24+XG5cbiAgPCEtLSBTd2l0Y2ggY2hhcnQgLyB0YWJsZSAtLT5cbiAgPG1hdC1kaXZpZGVyICpuZ0lmPVwiaGFzU3dpdGNoVmlldygpXCIgY2xhc3M9XCJvcmdhbml6ZXItZGl2aWRlclwiPjwvbWF0LWRpdmlkZXI+XG4gIDxidXR0b24gKm5nSWY9XCJoYXNTd2l0Y2hWaWV3KClcIiBtYXQtbWVudS1pdGVtIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXRyaWdnZXJcIiAoY2xpY2spPVwib25Td2l0Y2hWaWV3KClcIj5cbiAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1leHBvcnQtaWNvblwiPnt7IGNvbmZpZy5zd2l0Y2hWaWV3Py5jdXJyZW50VmlldyA9PT0gJ2NoYXJ0JyA/ICd0YWJsZV9jaGFydCcgOiAnYmFyX2NoYXJ0JyB9fTwvbWF0LWljb24+XG4gICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1sYWJlbFwiPnt7IGNvbmZpZy5zd2l0Y2hWaWV3Py5jdXJyZW50VmlldyA9PT0gJ2NoYXJ0JyA/ICdUYWJsZWF1JyA6ICdHcmFwaGlxdWUnIH19PC9zcGFuPlxuICA8L2J1dHRvbj5cblxuPC9tYXQtbWVudT5cblxuPCEtLSBTb3VzLW1lbnUgOiBhY3Rpb25zIGR1IHZpc3VlbCAtLT5cbjxtYXQtbWVudSAjYWN0aW9uc1N1Yk1lbnU9XCJtYXRNZW51XCIgcGFuZWxDbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LXBhbmVsXCI+XG4gIDxkaXYgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudVwiXG4gICAgICAgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChrZXlkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgIDxidXR0b24gKm5nSWY9XCJpc0NvcHlBY3Rpb25WaXNpYmxlKClcIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pdGVtXCJcbiAgICAgIChtb3VzZWRvd24pPVwib25Db3B5VmlzdWFsKClcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtY2hlY2tcIj48L3NwYW4+XG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pY29uXCI+Y29udGVudF9jb3B5PC9tYXQtaWNvbj5cbiAgICAgIENvcGllclxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b24gKm5nSWY9XCJpc0Z1bGxzY3JlZW5BY3Rpb25WaXNpYmxlKClcIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pdGVtXCJcbiAgICAgIChtb3VzZWRvd24pPVwib25Ub2dnbGVGdWxsc2NyZWVuKClcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtY2hlY2tcIj48L3NwYW4+XG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pY29uXCI+e3sgY29uZmlnLmlzRnVsbHNjcmVlbiA/ICdmdWxsc2NyZWVuX2V4aXQnIDogJ2Z1bGxzY3JlZW4nIH19PC9tYXQtaWNvbj5cbiAgICAgIHt7IGNvbmZpZy5pc0Z1bGxzY3JlZW4gPyAnUXVpdHRlciBsZSBwbGVpbiDDqWNyYW4nIDogJ1BsZWluIMOpY3JhbicgfX1cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L21hdC1tZW51PlxuXG48IS0tIFNvdXMtbWVudSA6IEV4cG9ydCBncmFwaGlxdWUgLS0+XG48bWF0LW1lbnUgI2V4cG9ydFN1Yk1lbnU9XCJtYXRNZW51XCIgcGFuZWxDbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LXBhbmVsXCI+XG4gIDxkaXYgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudVwiXG4gICAgICAgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChrZXlkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgIDxidXR0b24gKm5nSWY9XCJjb25maWcub25FeHBvcnRWaXN1YWxcIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pdGVtXCJcbiAgICAgIChtb3VzZWRvd24pPVwib25FeHBvcnRWaXN1YWwoKVwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1jaGVja1wiPjwvc3Bhbj5cbiAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWljb25cIj5pbWFnZTwvbWF0LWljb24+XG4gICAgICBWaXN1ZWxcbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uICpuZ0lmPVwiY29uZmlnLm9uRXhwb3J0RGF0YVwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIlxuICAgICAgKG1vdXNlZG93bik9XCJvbkV4cG9ydERhdGEoKVwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1jaGVja1wiPjwvc3Bhbj5cbiAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWljb25cIj50YWJsZV9jaGFydDwvbWF0LWljb24+XG4gICAgICBEb25uw6llc1xuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvbWF0LW1lbnU+XG5cbjwhLS0gU291cy1tZW51IDogQ2hhbXBzIGNoYXJ0IChYICsgWSkgLS0+XG48bWF0LW1lbnUgI2NoYW1wc1N1Yk1lbnU9XCJtYXRNZW51XCIgcGFuZWxDbGFzcz1cIm9yZ2FuaXplci1jaGFtcHMtcGFuZWxcIj5cbiAgPGRpdiBjbGFzcz1cIm9yZ2FuaXplci1jaGFtcHMtd3JhcHBlclwiXG4gICAgICAgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChrZXlkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuXG4gICAgPCEtLSBCbG9jIFggLS0+XG4gICAgPGRpdiBjbGFzcz1cIm9yZ2FuaXplci1jaGFtcHMtYmxvY2tcIiAqbmdJZj1cImNvbmZpZy54RmllbGRzPy5sZW5ndGhcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLWNoYW1wcy1ibG9jay10aXRsZVwiPkF4ZSBob3Jpem9udGFsIOKAlCBYPC9zcGFuPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pdGVtXCJcbiAgICAgICAgKm5nRm9yPVwibGV0IHhGaWVsZCBvZiBjb25maWcueEZpZWxkc1wiXG4gICAgICAgIFtjbGFzcy5hY3RpdmVdPVwic3RhdGU/LnNlbGVjdGVkWCA9PT0geEZpZWxkLmlkXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cInhGaWVsZC5kaXNhYmxlZFwiXG4gICAgICAgIChtb3VzZWRvd24pPVwib25YRmllbGRTZWxlY3QoeEZpZWxkLmlkKVwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWNoZWNrXCI+e3sgc3RhdGU/LnNlbGVjdGVkWCA9PT0geEZpZWxkLmlkID8gJ+KckycgOiAnJyB9fTwvc3Bhbj5cbiAgICAgICAge3sgeEZpZWxkLmxhYmVsIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cblxuICAgIDxtYXQtZGl2aWRlciAqbmdJZj1cImNvbmZpZy54RmllbGRzPy5sZW5ndGggJiYgY29uZmlnLnlGaWVsZHM/Lmxlbmd0aFwiIGNsYXNzPVwib3JnYW5pemVyLWNoYW1wcy1kaXZpZGVyXCI+PC9tYXQtZGl2aWRlcj5cblxuICAgIDwhLS0gQmxvYyBZIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJvcmdhbml6ZXItY2hhbXBzLWJsb2NrXCIgKm5nSWY9XCJjb25maWcueUZpZWxkcz8ubGVuZ3RoXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1jaGFtcHMtYmxvY2stdGl0bGVcIj5BeGUgdmVydGljYWwg4oCUIFk8L3NwYW4+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCB5RmllbGQgb2YgY29uZmlnLnlGaWVsZHNcIj5cblxuICAgICAgICA8IS0tIFkgc2ltcGxlIChDb3VudCBzYW5zIGFncsOpZ2F0IG5pIHN0YWNrKSAtLT5cbiAgICAgICAgPCEtLSBZIHNpbXBsZSAoQ291bnQgb3UgbcOpdHJpcXVlIGRpcmVjdGUpIC0tPlxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiIXlGaWVsZC5hZ2dyZWdhdGVzPy5sZW5ndGhcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIlxuICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiaXNZQWN0aXZlKHlGaWVsZC5pZClcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJ5RmllbGQuZGlzYWJsZWRcIlxuICAgICAgICAgIChtb3VzZWRvd24pPVwib25ZRmllbGRTZWxlY3QoeUZpZWxkLmlkKVwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtY2hlY2tcIj57eyBpc1lBY3RpdmUoeUZpZWxkLmlkKSA/ICfinJMnIDogJycgfX08L3NwYW4+XG4gICAgICAgICAge3sgeUZpZWxkLmxhYmVsIH19XG4gICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgIDwhLS0gWSBhdmVjIGFncsOpZ2F0cyDihpIgc291cy1tZW51IC0tPlxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwieUZpZWxkLmFnZ3JlZ2F0ZXM/Lmxlbmd0aFwiXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaXRlbSBvcmdhbml6ZXItc3VibWVudS1pdGVtLS1oYXMtY2hpbGRyZW5cIlxuICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiaXNZQWN0aXZlKHlGaWVsZC5pZClcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJ5RmllbGQuZGlzYWJsZWRcIlxuICAgICAgICAgIFttYXRNZW51VHJpZ2dlckZvcl09XCJ5QWdnU3ViTWVudVwiXG4gICAgICAgICAgW21hdE1lbnVUcmlnZ2VyRGF0YV09XCJ7IHlGaWVsZDogeUZpZWxkIH1cIlxuICAgICAgICAgIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1jaGVja1wiPnt7IGlzWUFjdGl2ZSh5RmllbGQuaWQpID8gJ+KckycgOiAnJyB9fTwvc3Bhbj5cbiAgICAgICAgICB7eyB5RmllbGQubGFiZWwgfX1cbiAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1hcnJvd1wiPmNoZXZyb25fcmlnaHQ8L21hdC1pY29uPlxuICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgPC9kaXY+XG48L21hdC1tZW51PlxuXG48IS0tIFNvdXMtbWVudSBkeW5hbWlxdWUgOiBhZ3LDqWdhdHMgZCd1biBjaGFtcCBZIC0tPlxuPG1hdC1tZW51ICN5QWdnU3ViTWVudT1cIm1hdE1lbnVcIiBwYW5lbENsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtcGFuZWxcIj5cbiAgPG5nLXRlbXBsYXRlIG1hdE1lbnVDb250ZW50IGxldC15RmllbGQ9XCJ5RmllbGRcIj5cbiAgICA8ZGl2IGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnVcIlxuICAgICAgICAgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaXRlbVwiXG4gICAgICAgICpuZ0Zvcj1cImxldCBhZ2cgb2YgeUZpZWxkLmFnZ3JlZ2F0ZXNcIlxuICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImlzWUFnZ3JlZ2F0ZUFjdGl2ZSh5RmllbGQuaWQsIGFnZy5pZClcIlxuICAgICAgICAobW91c2Vkb3duKT1cIm9uWUFnZ3JlZ2F0ZVNlbGVjdCh5RmllbGQuaWQsIGFnZy5pZClcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1jaGVja1wiPnt7IGlzWUFnZ3JlZ2F0ZUFjdGl2ZSh5RmllbGQuaWQsIGFnZy5pZCkgPyAn4pyTJyA6ICcnIH19PC9zcGFuPlxuICAgICAgICB7eyBhZ2cubGFiZWwgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L25nLXRlbXBsYXRlPlxuPC9tYXQtbWVudT5cblxuPCEtLSBTb3VzLW1lbnUgOiBDaGFtcHMgdGFibGUgKHRvZ2dsZSBjb2xvbm5lcykgLS0+XG48bWF0LW1lbnUgI2ZpZWxkc1N1Yk1lbnU9XCJtYXRNZW51XCIgcGFuZWxDbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LXBhbmVsXCI+XG4gIDxkaXYgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudVwiXG4gICAgICAgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChrZXlkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaXRlbVwiXG4gICAgICAqbmdGb3I9XCJsZXQgZmllbGQgb2YgY29uZmlnLmZpZWxkc1wiXG4gICAgICBbY2xhc3MuYWN0aXZlXT1cImlzRmllbGRWaXNpYmxlKGZpZWxkLmlkKVwiXG4gICAgICAobW91c2Vkb3duKT1cIm9uRmllbGRUb2dnbGUoZmllbGQuaWQsICFpc0ZpZWxkVmlzaWJsZShmaWVsZC5pZCkpXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWNoZWNrXCI+e3sgaXNGaWVsZFZpc2libGUoZmllbGQuaWQpID8gJ+KckycgOiAnJyB9fTwvc3Bhbj4gICAgICA8bWF0LWljb24gKm5nSWY9XCJmaWVsZC5pY29uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pY29uXCI+e3sgZmllbGQuaWNvbiB9fTwvbWF0LWljb24+ICAgICAge3sgZmllbGQubGFiZWwgfX1cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L21hdC1tZW51PlxuXG48IS0tIFNvdXMtbWVudSA6IEdyb3VwZXIgcGFyIC0tPlxuPG1hdC1tZW51ICNncm91cHNTdWJNZW51PVwibWF0TWVudVwiIHBhbmVsQ2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1wYW5lbFwiPlxuICA8ZGl2IGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnVcIlxuICAgICAgIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIlxuICAgICAgKm5nRm9yPVwibGV0IGdyb3VwIG9mIGNvbmZpZy5ncm91cHNcIlxuICAgICAgW2NsYXNzLmFjdGl2ZV09XCJzdGF0ZT8uc2VsZWN0ZWRHcm91cEJ5ID09PSBncm91cC5pZFwiXG4gICAgICAobW91c2Vkb3duKT1cIm9uR3JvdXBCeVNlbGVjdChncm91cC5pZClcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtY2hlY2tcIj57eyBzdGF0ZT8uc2VsZWN0ZWRHcm91cEJ5ID09PSBncm91cC5pZCA/ICfinJMnIDogJycgfX08L3NwYW4+ICAgICAgPG1hdC1pY29uICpuZ0lmPVwiZ3JvdXAuaWNvblwiIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaWNvblwiPnt7IGdyb3VwLmljb24gfX08L21hdC1pY29uPiAgICAgIHt7IGdyb3VwLmxhYmVsIH19XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuPC9tYXQtbWVudT5cblxuPCEtLSBTb3VzLW1lbnUgOiBGaWx0cmVyIHBhciAtLT5cbjxtYXQtbWVudSAjc2xpY2VzU3ViTWVudT1cIm1hdE1lbnVcIiBwYW5lbENsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtcGFuZWxcIj5cbiAgPGRpdiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51XCJcbiAgICAgICAobW91c2Vkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgKGtleWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pdGVtXCJcbiAgICAgICpuZ0Zvcj1cImxldCBzbGljZSBvZiBjb25maWcuc2xpY2VzXCJcbiAgICAgIFtjbGFzcy5hY3RpdmVdPVwic3RhdGU/LnNlbGVjdGVkU2xpY2VzPy5pbmNsdWRlcyhzbGljZS5pZClcIlxuICAgICAgKG1vdXNlZG93bik9XCJvblNsaWNlQ2xpY2soc2xpY2UuaWQpXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWNoZWNrXCI+e3sgc3RhdGU/LnNlbGVjdGVkU2xpY2VzPy5pbmNsdWRlcyhzbGljZS5pZCkgPyAn4pyTJyA6ICcnIH19PC9zcGFuPiAgICAgIDxtYXQtaWNvbiAqbmdJZj1cInNsaWNlLmljb25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWljb25cIj57eyBzbGljZS5pY29uIH19PC9tYXQtaWNvbj4gICAgICB7eyBzbGljZS5sYWJlbCB9fVxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvbWF0LW1lbnU+XG5cbjwhLS0gU291cy1tZW51IDogVGVtcGxhdGUgLS0+XG48bWF0LW1lbnUgI3RlbXBsYXRlU3ViTWVudT1cIm1hdE1lbnVcIiBwYW5lbENsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtcGFuZWxcIj5cbiAgPGRpdiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51XCJcbiAgICAgICAobW91c2Vkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgKGtleWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pdGVtXCJcbiAgICAgICpuZ0Zvcj1cImxldCB0bXBsIG9mIGNvbmZpZy50ZW1wbGF0ZXNcIlxuICAgICAgW2NsYXNzLmFjdGl2ZV09XCJzdGF0ZT8uc2VsZWN0ZWRUZW1wbGF0ZSA9PT0gdG1wbC5pZFwiXG4gICAgICBbdGl0bGVdPVwidG1wbC5kZXNjcmlwdGlvbiB8fCAnJ1wiXG4gICAgICAobW91c2Vkb3duKT1cIm9uVGVtcGxhdGVTZWxlY3QodG1wbC5pZClcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtY2hlY2tcIj57eyBzdGF0ZT8uc2VsZWN0ZWRUZW1wbGF0ZSA9PT0gdG1wbC5pZCA/ICfinJMnIDogJycgfX08L3NwYW4+XG4gICAgICA8bWF0LWljb24gKm5nSWY9XCJ0bXBsLmljb25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWljb25cIj57eyB0bXBsLmljb24gfX08L21hdC1pY29uPlxuICAgICAge3sgdG1wbC5sYWJlbCB9fVxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvbWF0LW1lbnU+XG5cbjwhLS0gU291cy1tZW51IDogUHLDqWbDqXJlbmNlcyAtLT5cbjxtYXQtbWVudSAjcHJlZmVyZW5jZXNTdWJNZW51PVwibWF0TWVudVwiIHBhbmVsQ2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1wYW5lbFwiPlxuICA8ZGl2IGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnVcIlxuICAgICAgIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIiAobW91c2Vkb3duKT1cIm9uUHJlZmVyZW5jZXNFZGl0KClcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtY2hlY2tcIj48L3NwYW4+XG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pY29uXCI+ZWRpdDwvbWF0LWljb24+w4lkaXRlclxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaXRlbVwiIChtb3VzZWRvd24pPVwib25QcmVmZXJlbmNlc1NhdmUoKVwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1jaGVja1wiPjwvc3Bhbj5cbiAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWljb25cIj5zYXZlPC9tYXQtaWNvbj5TYXV2ZWdhcmRlclxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaXRlbVwiIFtkaXNhYmxlZF09XCIhY29uZmlnLmhhc1NhdmVkUHJlZmVyZW5jZXNcIiAobW91c2Vkb3duKT1cIm9uUHJlZmVyZW5jZXNDbGVhcigpXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWNoZWNrXCI+PC9zcGFuPlxuICAgICAgPG1hdC1pY29uIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaWNvblwiPmRlbGV0ZV9vdXRsaW5lPC9tYXQtaWNvbj5Sw6lpbml0aWFsaXNlclxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvbWF0LW1lbnU+XG5cbiJdfQ==
382
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnYW5pemVyLWJ1dHRvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbmV0ZW1lL2pxdWVyeS1vcmdhbml6ZXIvc3JjL2xpYi9vcmdhbml6ZXItYnV0dG9uL29yZ2FuaXplci1idXR0b24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb25ldGVtZS9qcXVlcnktb3JnYW5pemVyL3NyYy9saWIvb3JnYW5pemVyLWJ1dHRvbi9vcmdhbml6ZXItYnV0dG9uLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQWEsU0FBUyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzVKLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDN0QsT0FBTyxFQUFFLE9BQU8sRUFBZ0IsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUczQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUseUJBQXlCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7Ozs7OztBQVc3RCxNQUFNLE9BQU8sd0JBQXdCO0lBaUJuQyxZQUFv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QUNoRixrQkFBa0IsaUJBR2IsaUJBQWlCLENBQUMsSUFBSSxtQkFDcEIsdUJBQXVCLENBQUMsTUFBTTt3R0FHdEMsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNJLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csZ0JBQWdCO3NCQUF6QixNQUFNO2dCQVV1QixlQUFlO3NCQUE1QyxTQUFTO3VCQUFDLGlCQUFpQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIE9uRGVzdHJveSwgVmlld0NoaWxkLCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE1hdEJ1dHRvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyBNYXRNZW51TW9kdWxlLCBNYXRNZW51VHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL21lbnUnO1xuaW1wb3J0IHsgTWF0RGl2aWRlck1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpdmlkZXInO1xuaW1wb3J0IHsgU3ViamVjdCwgU3Vic2NyaXB0aW9uLCBpc09ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgT3JnYW5pemVyQ29uZmlnLCBPcmdhbml6ZXJCdXR0b25FdmVudCwgT3JnYW5pemVyU2xpY2VTdGF0ZSwgT3JnYW5pemVyU3RhdGUgfSBmcm9tICcuLi9tb2RlbHMnO1xuaW1wb3J0IHsgbm9ybWFsaXplT3JnYW5pemVyU3RhdGUsIHJlc29sdmVNYXRjaGluZ1RlbXBsYXRlSWQgfSBmcm9tICcuLi9tb2RlbHMvb3JnYW5pemVyLXV0aWxzJztcbmltcG9ydCB7IFRlbXBsYXRlTWFuYWdlciB9IGZyb20gJy4vdGVtcGxhdGUtbWFuYWdlci51dGlsaXR5JztcblxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFsgQ29tbW9uTW9kdWxlLCBNYXRCdXR0b25Nb2R1bGUsIE1hdEljb25Nb2R1bGUsIE1hdE1lbnVNb2R1bGUsIE1hdERpdmlkZXJNb2R1bGUgXSxcbiAgc2VsZWN0b3I6ICdvcmdhbml6ZXItYnV0dG9uJyxcbiAgdGVtcGxhdGVVcmw6ICcuL29yZ2FuaXplci1idXR0b24uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9vcmdhbml6ZXItYnV0dG9uLmNvbXBvbmVudC5zY3NzJ10sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIE9yZ2FuaXplckJ1dHRvbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIGNvbmZpZyE6IE9yZ2FuaXplckNvbmZpZztcbiAgQElucHV0KCkgc3RhdGU/OiBPcmdhbml6ZXJTdGF0ZTtcbiAgQElucHV0KCkgaGlkZU1lbnVWYWx1ZXMgPSBmYWxzZTtcbiAgQE91dHB1dCgpIHZpZXdDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPE9yZ2FuaXplckJ1dHRvbkV2ZW50PigpO1xuICBAT3V0cHV0KCkgc2xpY2VTdGF0ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8T3JnYW5pemVyU2xpY2VTdGF0ZSB8IG51bGw+KCk7XG5cbiAgbG9hZGluZ0ZpZWxkSWQ/OiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBmaWVsZERhdGFDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBhbnlbXT4oKTtcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgZGVzdHJveWVkID0gZmFsc2U7XG4gIHByaXZhdGUgc2xpY2VSZXF1ZXN0SWQgPSAwO1xuICBwcml2YXRlIHNsaWNlU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXG4gIEBWaWV3Q2hpbGQoJ21haW5NZW51VHJpZ2dlcicpIG1haW5NZW51VHJpZ2dlcj86IE1hdE1lbnVUcmlnZ2VyO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZikge31cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3llZCA9IHRydWU7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgaXNGaWVsZFZpc2libGUoZmllbGRJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgdmlzaWJsZSA9IHRoaXMuc3RhdGU/LnZpc2libGVGaWVsZHM7XG4gICAgaWYgKCF2aXNpYmxlKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuZmllbGRzPy5maW5kKGYgPT4gZi5pZCA9PT0gZmllbGRJZCk/LnZpc2libGUgIT09IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdmlzaWJsZS5pbmNsdWRlcyhmaWVsZElkKTtcbiAgfVxuXG4gIGZpZWxkc1N1bW1hcnkoKTogc3RyaW5nIHtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMuY29uZmlnLmZpZWxkcz8ubGVuZ3RoID8/IDA7XG4gICAgY29uc3QgdmlzaWJsZSA9IHRoaXMuc3RhdGU/LnZpc2libGVGaWVsZHM/Lmxlbmd0aCA/PyB0b3RhbDtcbiAgICByZXR1cm4gYCR7dmlzaWJsZX0vJHt0b3RhbH1gO1xuICB9XG5cbiAgb25GaWVsZFRvZ2dsZShmaWVsZElkOiBzdHJpbmcsIHZpc2libGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5zdGF0ZT8udmlzaWJsZUZpZWxkc1xuICAgICAgPz8gKHRoaXMuY29uZmlnLmZpZWxkcyA/PyBbXSkuZmlsdGVyKGYgPT4gZi52aXNpYmxlICE9PSBmYWxzZSkubWFwKGYgPT4gZi5pZCk7XG4gICAgbGV0IHVwZGF0ZWQ6IHN0cmluZ1tdO1xuICAgIGlmICh2aXNpYmxlKSB7XG4gICAgICB1cGRhdGVkID0gY3VycmVudC5pbmNsdWRlcyhmaWVsZElkKSA/IGN1cnJlbnQgOiBbLi4uY3VycmVudCwgZmllbGRJZF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHVwZGF0ZWQgPSBjdXJyZW50LmZpbHRlcihmID0+IGYgIT09IGZpZWxkSWQpO1xuICAgIH1cbiAgICB0aGlzLmVtaXRDaGFuZ2UoJ2ZpZWxkVG9nZ2xlZCcsIHsgdmlzaWJsZUZpZWxkczogdXBkYXRlZCB9KTtcbiAgfVxuXG4gIG9uWEZpZWxkU2VsZWN0KGZpZWxkSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIC8vIMOJdml0ZSB1bmUgcmVxdcOqdGUgaW51dGlsZSBzaSBsZSBYIGVzdCBkw6lqw6Agc8OpbGVjdGlvbm7DqVxuICAgIGlmICh0aGlzLnN0YXRlPy5zZWxlY3RlZFggPT09IGZpZWxkSWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5lbWl0Q2hhbmdlKCd4U2VsZWN0ZWQnLCB7IHNlbGVjdGVkWDogZmllbGRJZCB9KTtcbiAgfVxuXG4gIG9uWUZpZWxkU2VsZWN0KGZpZWxkSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIC8vIMOJdml0ZSB1bmUgcmVxdcOqdGUgaW51dGlsZSBzaSBsZSBZIGVzdCBkw6lqw6Agc8OpbGVjdGlvbm7DqVxuICAgIGlmICh0aGlzLnN0YXRlPy5zZWxlY3RlZFkgPT09IGZpZWxkSWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5lbWl0Q2hhbmdlKCd5U2VsZWN0ZWQnLCB7XG4gICAgICBzZWxlY3RlZFk6IGZpZWxkSWQsXG4gICAgICBzZWxlY3RlZFlBZ2dyZWdhdGU6IHVuZGVmaW5lZFxuICAgIH0pO1xuICB9XG5cbiAgb25ZQWdncmVnYXRlU2VsZWN0KHlGaWVsZElkOiBzdHJpbmcsIGFnZ3JlZ2F0ZUlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAvLyDDiXZpdGUgdW5lIHJlcXXDqnRlIGludXRpbGUgc2kgbCdhZ2dyZWdhdGUgZXN0IGTDqWrDoCBzw6lsZWN0aW9ubsOpXG4gICAgaWYgKHRoaXMuc3RhdGU/LnNlbGVjdGVkWUFnZ3JlZ2F0ZSA9PT0gYWdncmVnYXRlSWQgJiYgdGhpcy5zdGF0ZT8uc2VsZWN0ZWRZID09PSB5RmllbGRJZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVtaXRDaGFuZ2UoJ3lTZWxlY3RlZCcsIHtcbiAgICAgIHNlbGVjdGVkWTogeUZpZWxkSWQsXG4gICAgICBzZWxlY3RlZFlBZ2dyZWdhdGU6IGFnZ3JlZ2F0ZUlkXG4gICAgfSk7XG4gIH1cblxuICBvbkdyb3VwQnlTZWxlY3QoZ3JvdXBJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuc3RhdGU/LnNlbGVjdGVkR3JvdXBCeTtcbiAgICB0aGlzLmVtaXRDaGFuZ2UoJ2dyb3VwQnlTZWxlY3RlZCcsIHsgc2VsZWN0ZWRHcm91cEJ5OiBjdXJyZW50ID09PSBncm91cElkID8gdW5kZWZpbmVkIDogZ3JvdXBJZCB9KTtcbiAgfVxuXG4gIG9uQ2hhcnRUeXBlU2VsZWN0KGNoYXJ0VHlwZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3Qgb3B0aW9uID0gdGhpcy5jb25maWcuY2hhcnRUeXBlcz8uZmluZCh0eXBlID0+IHR5cGUuaWQgPT09IGNoYXJ0VHlwZSk7XG4gICAgaWYgKCFvcHRpb24gfHwgb3B0aW9uLmRpc2FibGVkIHx8IHRoaXMuc3RhdGU/LnNlbGVjdGVkQ2hhcnRUeXBlID09PSBjaGFydFR5cGUpIHJldHVybjtcbiAgICB0aGlzLmVtaXRDaGFuZ2UoJ2NoYXJ0VHlwZVNlbGVjdGVkJywgeyBzZWxlY3RlZENoYXJ0VHlwZTogY2hhcnRUeXBlIH0pO1xuICB9XG5cbiAgb25UZW1wbGF0ZVNlbGVjdCh0ZW1wbGF0ZUlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnLnRlbXBsYXRlcz8ubGVuZ3RoKSByZXR1cm47XG5cbiAgICBjb25zdCB0ZW1wbGF0ZSA9IHRoaXMuY29uZmlnLnRlbXBsYXRlcz8uZmluZCh0ID0+IHQuaWQgPT09IHRlbXBsYXRlSWQpO1xuICAgIGlmICghdGVtcGxhdGUpIHJldHVybjtcblxuICAgIGNvbnN0IG5ld1N0YXRlID0gVGVtcGxhdGVNYW5hZ2VyLmFwcGx5VGVtcGxhdGUodGVtcGxhdGUsIHRoaXMuc3RhdGUsIHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLmVtaXRDaGFuZ2UoJ3RlbXBsYXRlU2VsZWN0ZWQnLCBuZXdTdGF0ZSk7XG4gICAgdGhpcy5zeW5jU2xpY2VTdGF0ZShuZXdTdGF0ZS5zZWxlY3RlZFNsaWNlcyk7XG4gIH1cblxuICBvblNsaWNlQ2xpY2soc2xpY2VJZD86IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbmZpZy5vblNsaWNlQ2xpY2spIHtcbiAgICAgIHRoaXMuY29uZmlnLm9uU2xpY2VDbGljaygpO1xuICAgIH1cblxuICAgIGNvbnN0IHNlbGVjdGVkU2xpY2VzID0gdGhpcy5zdGF0ZT8uc2VsZWN0ZWRTbGljZXMgfHwgW107XG4gICAgbGV0IHVwZGF0ZWQ6IHN0cmluZ1tdO1xuICAgIGlmIChzbGljZUlkKSB7XG4gICAgICB1cGRhdGVkID0gc2VsZWN0ZWRTbGljZXMuaW5jbHVkZXMoc2xpY2VJZClcbiAgICAgICAgPyBzZWxlY3RlZFNsaWNlcy5maWx0ZXIoaWQgPT4gaWQgIT09IHNsaWNlSWQpXG4gICAgICAgIDogWy4uLnNlbGVjdGVkU2xpY2VzLCBzbGljZUlkXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXBkYXRlZCA9IHNlbGVjdGVkU2xpY2VzO1xuICAgIH1cblxuICAgIGlmICh1cGRhdGVkLmxlbmd0aCA9PT0gMCB8fCAhc2xpY2VJZCB8fCAhdGhpcy5jb25maWcub25GZXRjaFNsaWNlRGF0YSkge1xuICAgICAgdGhpcy5zbGljZVN0YXRlQ2hhbmdlLmVtaXQobnVsbCk7XG4gICAgICB0aGlzLmVtaXRDaGFuZ2UoJ3NsaWNlU2VsZWN0ZWQnLCB7IHNlbGVjdGVkU2xpY2VzOiB1cGRhdGVkIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc3luY1NsaWNlU3RhdGUodXBkYXRlZCwgKCkgPT4ge1xuICAgICAgdGhpcy5lbWl0Q2hhbmdlKCdzbGljZVNlbGVjdGVkJywgeyBzZWxlY3RlZFNsaWNlczogdXBkYXRlZCB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3luY1NsaWNlU3RhdGUoc2VsZWN0ZWRTbGljZXM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkLCBvbkxvYWRlZD86ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICAvLyBVbmUgbm91dmVsbGUgZGVtYW5kZSBhbm51bGUgbGEgcHLDqWPDqWRlbnRlIDogc2V1bGUgbGEgcsOpcG9uc2UgbGEgcGx1cyByw6ljZW50ZSBlc3QgcHJpc2UgZW4gY29tcHRlLlxuICAgIGNvbnN0IHJlcXVlc3RJZCA9ICsrdGhpcy5zbGljZVJlcXVlc3RJZDtcbiAgICB0aGlzLnNsaWNlU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuc2xpY2VTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBzbGljZUlkID0gc2VsZWN0ZWRTbGljZXM/LlswXTtcbiAgICBpZiAoIXNsaWNlSWQgfHwgIXRoaXMuY29uZmlnLm9uRmV0Y2hTbGljZURhdGEpIHtcbiAgICAgIHRoaXMuc2xpY2VTdGF0ZUNoYW5nZS5lbWl0KG51bGwpO1xuICAgICAgb25Mb2FkZWQ/LigpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHNsaWNlID0gdGhpcy5jb25maWcuc2xpY2VzPy5maW5kKHMgPT4gcy5pZCA9PT0gc2xpY2VJZCk7XG4gICAgaWYgKCFzbGljZSkge1xuICAgICAgdGhpcy5zbGljZVN0YXRlQ2hhbmdlLmVtaXQobnVsbCk7XG4gICAgICBvbkxvYWRlZD8uKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jb25maWcub25GZXRjaFNsaWNlRGF0YShzbGljZUlkKTtcbiAgICBjb25zdCBoYW5kbGVEYXRhID0gKHRhc2tzOiBhbnlbXSkgPT4ge1xuICAgICAgaWYgKHRoaXMuZGVzdHJveWVkIHx8IHJlcXVlc3RJZCAhPT0gdGhpcy5zbGljZVJlcXVlc3RJZCkgcmV0dXJuO1xuICAgICAgdGhpcy5zbGljZVN0YXRlQ2hhbmdlLmVtaXQoe1xuICAgICAgICBzbGljZUNvbmZpZ3M6IFt7IHRpdGxlOiBzbGljZS5sYWJlbCA/PyBzbGljZUlkLCBjb2x1bW5LZXk6IHNsaWNlSWQgfV0sXG4gICAgICAgIHRhc2tzLFxuICAgICAgICBmaWx0ZXJBcHBsaWVkOiBmYWxzZSAgLy8gUGFuZWwgdmllbnQgZCfDqnRyZSBvdXZlcnQsIHBhcyBkZSBmaWx0cmUgc8OpbGVjdGlvbm7DqSBlbmNvcmVcbiAgICAgIH0pO1xuICAgICAgb25Mb2FkZWQ/LigpO1xuICAgIH07XG4gICAgY29uc3QgaGFuZGxlRXJyb3IgPSAoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgIGlmICh0aGlzLmRlc3Ryb3llZCB8fCByZXF1ZXN0SWQgIT09IHRoaXMuc2xpY2VSZXF1ZXN0SWQpIHJldHVybjtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tPcmdhbml6ZXJCdXR0b25dIFNsaWNlIGRhdGEgbG9hZGluZyBmYWlsZWQnLCBlcnJvcik7XG4gICAgICB0aGlzLnNsaWNlU3RhdGVDaGFuZ2UuZW1pdChudWxsKTtcbiAgICAgIG9uTG9hZGVkPy4oKTtcbiAgICB9O1xuXG4gICAgaWYgKGlzT2JzZXJ2YWJsZShyZXN1bHQpKSB7XG4gICAgICB0aGlzLnNsaWNlU3Vic2NyaXB0aW9uID0gcmVzdWx0LnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoeyBuZXh0OiBoYW5kbGVEYXRhLCBlcnJvcjogaGFuZGxlRXJyb3IgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZvaWQgcmVzdWx0LnRoZW4oaGFuZGxlRGF0YSwgaGFuZGxlRXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGxvYWRGaWVsZERhdGEoZmllbGRJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuZmllbGREYXRhQ2FjaGUuaGFzKGZpZWxkSWQpKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLmNvbmZpZy5vbkZldGNoRmllbGREYXRhKSByZXR1cm47XG5cbiAgICBjb25zdCBmaWVsZCA9IHRoaXMuY29uZmlnLmZpZWxkcz8uZmluZChmID0+IGYuaWQgPT09IGZpZWxkSWQpO1xuICAgIGlmICghZmllbGQpIHJldHVybjtcblxuICAgIHRoaXMubG9hZGluZ0ZpZWxkSWQgPSBmaWVsZElkO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmNvbmZpZy5vbkZldGNoRmllbGREYXRhKGZpZWxkSWQpO1xuICAgICAgdGhpcy5maWVsZERhdGFDYWNoZS5zZXQoZmllbGRJZCwgZGF0YSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tPcmdhbml6ZXJCdXR0b25dIEZpZWxkIGRhdGEgbG9hZGluZyBmYWlsZWQnLCBlcnJvcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMubG9hZGluZ0ZpZWxkSWQgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBvbkV4cG9ydCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jb25maWcub25FeHBvcnQpIHRoaXMuY29uZmlnLm9uRXhwb3J0KCk7XG4gICAgdGhpcy5tYWluTWVudVRyaWdnZXI/LmNsb3NlTWVudSgpO1xuICB9XG5cbiAgb25FeHBvcnRWaXN1YWwoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29uZmlnLm9uRXhwb3J0VmlzdWFsKSB0aGlzLmNvbmZpZy5vbkV4cG9ydFZpc3VhbCgpO1xuICAgIHRoaXMubWFpbk1lbnVUcmlnZ2VyPy5jbG9zZU1lbnUoKTtcbiAgfVxuXG4gIG9uRXhwb3J0RGF0YSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jb25maWcub25FeHBvcnREYXRhKSB0aGlzLmNvbmZpZy5vbkV4cG9ydERhdGEoKTtcbiAgICB0aGlzLm1haW5NZW51VHJpZ2dlcj8uY2xvc2VNZW51KCk7XG4gIH1cblxuICBoYXNFeHBvcnRTdWJNZW51KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhISh0aGlzLmNvbmZpZy5vbkV4cG9ydFZpc3VhbCB8fCB0aGlzLmNvbmZpZy5vbkV4cG9ydERhdGEpO1xuICB9XG5cbiAgaXNDb3B5QWN0aW9uVmlzaWJsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmNvbmZpZy5vbkNvcHlWaXN1YWwgJiYgdGhpcy5jb25maWcuYWN0aW9ucz8uc2hvd0NvcHkgIT09IGZhbHNlO1xuICB9XG5cbiAgaXNGdWxsc2NyZWVuQWN0aW9uVmlzaWJsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmNvbmZpZy5vblRvZ2dsZUZ1bGxzY3JlZW4gJiYgdGhpcy5jb25maWcuYWN0aW9ucz8uc2hvd0Z1bGxzY3JlZW4gIT09IGZhbHNlO1xuICB9XG5cbiAgaGFzQWN0aW9ucygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuc2hvd0FjdGlvbnMgPT09IHRydWUgJiYgKHRoaXMuaXNDb3B5QWN0aW9uVmlzaWJsZSgpIHx8IHRoaXMuaXNGdWxsc2NyZWVuQWN0aW9uVmlzaWJsZSgpKTtcbiAgfVxuXG4gIGhhc01lbnVJdGVtc0JlZm9yZUFjdGlvbnMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaGFzQ2hhcnRGaWVsZHMoKVxuICAgICAgfHwgdGhpcy5oYXNUYWJsZUZpZWxkcygpXG4gICAgICB8fCAodGhpcy5jb25maWcuY2hhcnRUeXBlcz8ubGVuZ3RoID8/IDApID4gMFxuICAgICAgfHwgKHRoaXMuY29uZmlnLmdyb3Vwcz8ubGVuZ3RoID8/IDApID4gMFxuICAgICAgfHwgKHRoaXMuY29uZmlnLnNsaWNlcz8ubGVuZ3RoID8/IDApID4gMFxuICAgICAgfHwgKHRoaXMuY29uZmlnLnRlbXBsYXRlcz8ubGVuZ3RoID8/IDApID4gMDtcbiAgfVxuXG4gIGhhc090aGVyTWVudUl0ZW1zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmhhc01lbnVJdGVtc0JlZm9yZUFjdGlvbnMoKVxuICAgICAgfHwgISF0aGlzLmNvbmZpZy5zaG93RXhwb3J0XG4gICAgICB8fCAhIXRoaXMuY29uZmlnLnNob3dQcmVmZXJlbmNlc1xuICAgICAgfHwgdGhpcy5oYXNTd2l0Y2hWaWV3KCk7XG4gIH1cblxuICBhY3Rpb25zTGFiZWwoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5jb25maWcuYWN0aW9ucz8ubGFiZWwpIHJldHVybiB0aGlzLmNvbmZpZy5hY3Rpb25zLmxhYmVsO1xuICAgIHJldHVybiB0aGlzLmlzQ29weUFjdGlvblZpc2libGUoKSAmJiB0aGlzLmlzRnVsbHNjcmVlbkFjdGlvblZpc2libGUoKSA/ICdBY3Rpb25zJyA6ICdBY3Rpb24nO1xuICB9XG5cbiAgb25Db3B5VmlzdWFsKCk6IHZvaWQge1xuICAgIHRoaXMuY29uZmlnLm9uQ29weVZpc3VhbD8uKCk7XG4gICAgdGhpcy5tYWluTWVudVRyaWdnZXI/LmNsb3NlTWVudSgpO1xuICB9XG5cbiAgb25Ub2dnbGVGdWxsc2NyZWVuKCk6IHZvaWQge1xuICAgIHRoaXMuY29uZmlnLm9uVG9nZ2xlRnVsbHNjcmVlbj8uKCk7XG4gICAgdGhpcy5tYWluTWVudVRyaWdnZXI/LmNsb3NlTWVudSgpO1xuICB9XG5cbiAgaGFzU3dpdGNoVmlldygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmNvbmZpZy5zd2l0Y2hWaWV3O1xuICB9XG5cbiAgb25Td2l0Y2hWaWV3KCk6IHZvaWQge1xuICAgIGNvbnN0IHN2ID0gdGhpcy5jb25maWcuc3dpdGNoVmlldztcbiAgICBpZiAoIXN2KSByZXR1cm47XG4gICAgY29uc3QgbmV3VmlldzogJ2NoYXJ0JyB8ICd0YWJsZScgPSBzdi5jdXJyZW50VmlldyA9PT0gJ2NoYXJ0JyA/ICd0YWJsZScgOiAnY2hhcnQnO1xuICAgIHN2Lm9uU3dpdGNoKG5ld1ZpZXcpO1xuICAgIHRoaXMuZW1pdENoYW5nZSgndmlld1N3aXRjaGVkJywgeyB2aWV3TW9kZTogbmV3VmlldyB9KTtcbiAgICB0aGlzLm1haW5NZW51VHJpZ2dlcj8uY2xvc2VNZW51KCk7XG4gIH1cblxuICBvblByZWZlcmVuY2VzRWRpdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jb25maWcub25QcmVmZXJlbmNlc0VkaXQpIHRoaXMuY29uZmlnLm9uUHJlZmVyZW5jZXNFZGl0KCk7XG4gICAgdGhpcy5tYWluTWVudVRyaWdnZXI/LmNsb3NlTWVudSgpO1xuICB9XG5cbiAgb25QcmVmZXJlbmNlc1NhdmUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29uZmlnLm9uUHJlZmVyZW5jZXNTYXZlKSB0aGlzLmNvbmZpZy5vblByZWZlcmVuY2VzU2F2ZSgpO1xuICAgIHRoaXMubWFpbk1lbnVUcmlnZ2VyPy5jbG9zZU1lbnUoKTtcbiAgfVxuXG4gIG9uUHJlZmVyZW5jZXNDbGVhcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jb25maWcub25QcmVmZXJlbmNlc0NsZWFyKSB0aGlzLmNvbmZpZy5vblByZWZlcmVuY2VzQ2xlYXIoKTtcbiAgICB0aGlzLm1haW5NZW51VHJpZ2dlcj8uY2xvc2VNZW51KCk7XG4gIH1cblxuICBvblJlc2V0KCk6IHZvaWQge1xuICAgIGNvbnN0IHZpc2libGVGaWVsZHMgPSB0aGlzLmNvbmZpZy5maWVsZHNcbiAgICAgID8uZmlsdGVyKGZpZWxkID0+IGZpZWxkLnZpc2libGUgIT09IGZhbHNlKVxuICAgICAgLm1hcChmaWVsZCA9PiBmaWVsZC5pZCk7XG4gICAgdGhpcy5lbWl0Q2hhbmdlKCdyZXNldCcsIHtcbiAgICAgIHZpc2libGVGaWVsZHMsXG4gICAgICBzZWxlY3RlZFg6IHVuZGVmaW5lZCxcbiAgICAgIHNlbGVjdGVkWTogdW5kZWZpbmVkLFxuICAgICAgc2VsZWN0ZWRZQWdncmVnYXRlOiB1bmRlZmluZWQsXG4gICAgICBzZWxlY3RlZEdyb3VwQnk6IHVuZGVmaW5lZCxcbiAgICAgIHNlbGVjdGVkU2xpY2VzOiBbXVxuICAgIH0pO1xuICAgIHRoaXMubWFpbk1lbnVUcmlnZ2VyPy5jbG9zZU1lbnUoKTtcbiAgfVxuXG4gIGFjdGl2ZVhMYWJlbCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGlkID0gdGhpcy5zdGF0ZT8uc2VsZWN0ZWRYO1xuICAgIGlmICghaWQpIHJldHVybiAnJztcbiAgICByZXR1cm4gdGhpcy5jb25maWcueEZpZWxkcz8uZmluZChmID0+IGYuaWQgPT09IGlkKT8ubGFiZWwgPz8gaWQ7XG4gIH1cblxuICBhY3RpdmVZTGFiZWwoKTogc3RyaW5nIHtcbiAgICBjb25zdCB5SWQgPSB0aGlzLnN0YXRlPy5zZWxlY3RlZFk7XG4gICAgaWYgKCF5SWQpIHJldHVybiAnJztcbiAgICBjb25zdCB5RmllbGQgPSB0aGlzLmNvbmZpZy55RmllbGRzPy5maW5kKGYgPT4gZi5pZCA9PT0geUlkKTtcbiAgICBjb25zdCBiYXNlID0geUZpZWxkPy5sYWJlbCA/PyB5SWQ7XG5cbiAgICBpZiAodGhpcy5zdGF0ZT8uc2VsZWN0ZWRZQWdncmVnYXRlKSB7XG4gICAgICBjb25zdCBhZ2cgPSB5RmllbGQ/LmFnZ3JlZ2F0ZXM/LmZpbmQoYSA9PiBhLmlkID09PSB0aGlzLnN0YXRlIS5zZWxlY3RlZFlBZ2dyZWdhdGUpO1xuICAgICAgcmV0dXJuIGFnZyA/IGAke2Jhc2V9IMK3ICR7YWdnLmxhYmVsfWAgOiBiYXNlO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZTtcbiAgfVxuXG4gIGFjdGl2ZUdyb3VwQnlMYWJlbCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGlkID0gdGhpcy5zdGF0ZT8uc2VsZWN0ZWRHcm91cEJ5O1xuICAgIGlmICghaWQpIHJldHVybiAnJztcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZ3JvdXBzPy5maW5kKGcgPT4gZy5pZCA9PT0gaWQpPy5sYWJlbCA/PyBpZDtcbiAgfVxuXG4gIGFjdGl2ZUNoYXJ0VHlwZUxhYmVsKCk6IHN0cmluZyB7XG4gICAgY29uc3QgaWQgPSB0aGlzLnN0YXRlPy5zZWxlY3RlZENoYXJ0VHlwZTtcbiAgICBpZiAoIWlkKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmNoYXJ0VHlwZXM/LmZpbmQodHlwZSA9PiB0eXBlLmlkID09PSBpZCk/LmxhYmVsID8/IGlkO1xuICB9XG5cbiAgYWN0aXZlU2xpY2VzTGFiZWwoKTogc3RyaW5nIHtcbiAgICBjb25zdCBpZHMgPSB0aGlzLnN0YXRlPy5zZWxlY3RlZFNsaWNlcztcbiAgICBpZiAoIWlkcz8ubGVuZ3RoKSByZXR1cm4gJyc7XG4gICAgaWYgKGlkcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5zbGljZXM/LmZpbmQocyA9PiBzLmlkID09PSBpZHNbMF0pPy5sYWJlbCA/PyBpZHNbMF07XG4gICAgfVxuICAgIHJldHVybiBgJHtpZHMubGVuZ3RofSBzw6lsZWN0aW9ubsOpc2A7XG4gIH1cblxuICBhY3RpdmVUZW1wbGF0ZUxhYmVsKCk6IHN0cmluZyB7XG4gICAgY29uc3QgaWQgPSB0aGlzLnN0YXRlPy5zZWxlY3RlZFRlbXBsYXRlO1xuICAgIGlmICghaWQpIHJldHVybiAnJztcbiAgICByZXR1cm4gdGhpcy5jb25maWcudGVtcGxhdGVzPy5maW5kKHQgPT4gdC5pZCA9PT0gaWQpPy5sYWJlbCA/PyBpZDtcbiAgfVxuXG4gIGhhc0NoYXJ0RmllbGRzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAodGhpcy5jb25maWcueEZpZWxkcz8ubGVuZ3RoID8/IDApID4gMCB8fCAodGhpcy5jb25maWcueUZpZWxkcz8ubGVuZ3RoID8/IDApID4gMDtcbiAgfVxuXG4gIGhhc0NoYXJ0VHlwZXMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLmNvbmZpZy5jaGFydFR5cGVzPy5sZW5ndGggPz8gMCkgPiAwO1xuICB9XG5cbiAgaGFzVGFibGVGaWVsZHMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLmNvbmZpZy5maWVsZHM/Lmxlbmd0aCA/PyAwKSA+IDA7XG4gIH1cblxuICBpc1lBY3RpdmUoeUZpZWxkSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXRlPy5zZWxlY3RlZFkgPT09IHlGaWVsZElkO1xuICB9XG5cbiAgaXNZQWdncmVnYXRlQWN0aXZlKHlGaWVsZElkOiBzdHJpbmcsIGFnZ3JlZ2F0ZUlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZT8uc2VsZWN0ZWRZID09PSB5RmllbGRJZCAmJiB0aGlzLnN0YXRlPy5zZWxlY3RlZFlBZ2dyZWdhdGUgPT09IGFnZ3JlZ2F0ZUlkO1xuICB9XG5cbiAgaXNDaGFydFR5cGVBY3RpdmUoY2hhcnRUeXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZT8uc2VsZWN0ZWRDaGFydFR5cGUgPT09IGNoYXJ0VHlwZTtcbiAgfVxuXG4gIHByaXZhdGUgZW1pdENoYW5nZSh0eXBlOiBPcmdhbml6ZXJCdXR0b25FdmVudFsndHlwZSddLCBzdGF0ZVVwZGF0ZTogUGFydGlhbDxPcmdhbml6ZXJTdGF0ZT4gfCBPcmdhbml6ZXJTdGF0ZSk6IHZvaWQge1xuICAgIGNvbnN0IGlzRnVsbFN0YXRlID0gJ3NlbGVjdGVkWCcgaW4gc3RhdGVVcGRhdGUgJiYgJ3NlbGVjdGVkVGVtcGxhdGUnIGluIHN0YXRlVXBkYXRlO1xuICAgIGNvbnN0IHJhd1N0YXRlID0gaXNGdWxsU3RhdGUgPyAoc3RhdGVVcGRhdGUgYXMgT3JnYW5pemVyU3RhdGUpIDogeyAuLi50aGlzLnN0YXRlLCAuLi5zdGF0ZVVwZGF0ZSB9O1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRTdGF0ZSA9IG5vcm1hbGl6ZU9yZ2FuaXplclN0YXRlKHJhd1N0YXRlLCB0aGlzLmNvbmZpZyk7XG4gICAgY29uc3QgZXZlbnQ6IE9yZ2FuaXplckJ1dHRvbkV2ZW50ID0ge1xuICAgICAgdHlwZSxcbiAgICAgIHN0YXRlOiB7XG4gICAgICAgIC4uLm5vcm1hbGl6ZWRTdGF0ZSxcbiAgICAgICAgc2VsZWN0ZWRUZW1wbGF0ZTogcmVzb2x2ZU1hdGNoaW5nVGVtcGxhdGVJZCh0aGlzLmNvbmZpZy50ZW1wbGF0ZXMsIG5vcm1hbGl6ZWRTdGF0ZSwgdGhpcy5jb25maWcpXG4gICAgICB9LFxuICAgICAgc291cmNlOiAndXNlcidcbiAgICB9O1xuICAgIHRoaXMudmlld0NoYW5nZS5lbWl0KGV2ZW50KTtcbiAgfVxufVxuIiwiPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJvcmdhbml6ZXItYnRuXCIgW2NsYXNzLm9yZ2FuaXplci1idG4tLWxhYmVsZWRdPVwiISFjb25maWcuYnV0dG9uTGFiZWxcIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwidmlld01lbnVcIiAjbWFpbk1lbnVUcmlnZ2VyPVwibWF0TWVudVRyaWdnZXJcIiBbYXR0ci5hcmlhLWxhYmVsXT1cImNvbmZpZy5idXR0b25MYWJlbCB8fCAnUGVyc29ubmFsaXNlciBsYSB2dWUnXCIgW2F0dHIudGl0bGVdPVwiY29uZmlnLmJ1dHRvbkxhYmVsIHx8ICdQZXJzb25uYWxpc2VyIGxhIHZ1ZSdcIj5cbiAgPG1hdC1pY29uICpuZ0lmPVwiY29uZmlnLnNob3dCdXR0b25JY29uICE9PSBmYWxzZVwiIGNsYXNzPVwib3JnYW5pemVyLWJ0bi1pY29uXCI+e3sgY29uZmlnLmJ1dHRvbkljb24gfHwgJ3NldHRpbmdzJyB9fTwvbWF0LWljb24+XG4gIDxzcGFuICpuZ0lmPVwiY29uZmlnLmJ1dHRvbkxhYmVsXCIgY2xhc3M9XCJvcmdhbml6ZXItYnRuLWxhYmVsXCI+e3sgY29uZmlnLmJ1dHRvbkxhYmVsIH19PC9zcGFuPlxuPC9idXR0b24+XG5cbjxtYXQtbWVudSAjdmlld01lbnU9XCJtYXRNZW51XCIgcGFuZWxDbGFzcz1cIm9yZ2FuaXplci1tZW51LXBhbmVsXCI+XG5cbiAgPCEtLSBUeXBlIC0tPlxuICA8YnV0dG9uICpuZ0lmPVwiaGFzQ2hhcnRUeXBlcygpXCIgbWF0LW1lbnUtaXRlbSBbbWF0TWVudVRyaWdnZXJGb3JdPVwiY2hhcnRUeXBlc1N1Yk1lbnVcIiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXRyaWdnZXJcIj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+VHlwZTwvc3Bhbj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXZhbHVlXCIgKm5nSWY9XCIhaGlkZU1lbnVWYWx1ZXMgJiYgYWN0aXZlQ2hhcnRUeXBlTGFiZWwoKVwiPnt7IGFjdGl2ZUNoYXJ0VHlwZUxhYmVsKCkgfX08L3NwYW4+XG4gIDwvYnV0dG9uPlxuXG4gIDwhLS0gQ2hhbXBzIDogbW9kZSBjaGFydCAoWCArIFkpIC0tPlxuICA8YnV0dG9uICpuZ0lmPVwiaGFzQ2hhcnRGaWVsZHMoKVwiIG1hdC1tZW51LWl0ZW0gW21hdE1lbnVUcmlnZ2VyRm9yXT1cImNoYW1wc1N1Yk1lbnVcIiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXRyaWdnZXJcIj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+Q2hhbXBzPC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtdmFsdWVcIiAqbmdJZj1cIiFoaWRlTWVudVZhbHVlcyAmJiAoYWN0aXZlWExhYmVsKCkgfHwgYWN0aXZlWUxhYmVsKCkpXCI+XG4gICAgICB7eyBhY3RpdmVYTGFiZWwoKSB9fTxuZy1jb250YWluZXIgKm5nSWY9XCJhY3RpdmVYTGFiZWwoKSAmJiBhY3RpdmVZTGFiZWwoKVwiPiAvIDwvbmctY29udGFpbmVyPnt7IGFjdGl2ZVlMYWJlbCgpIH19XG4gICAgPC9zcGFuPlxuICA8L2J1dHRvbj5cblxuICA8IS0tIENoYW1wcyA6IG1vZGUgdGFibGUgKHRvZ2dsZSBjb2xvbm5lcykgLS0+XG4gIDxidXR0b24gKm5nSWY9XCJoYXNUYWJsZUZpZWxkcygpXCIgbWF0LW1lbnUtaXRlbSBbbWF0TWVudVRyaWdnZXJGb3JdPVwiZmllbGRzU3ViTWVudVwiIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtdHJpZ2dlclwiPlxuICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtbGFiZWxcIj5DaGFtcHM8L3NwYW4+XG4gICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItbWVudS12YWx1ZVwiICpuZ0lmPVwiIWhpZGVNZW51VmFsdWVzXCI+e3sgZmllbGRzU3VtbWFyeSgpIH19PC9zcGFuPlxuICA8L2J1dHRvbj5cblxuICA8IS0tIEdyb3VwZXIgcGFyIC0tPlxuICA8YnV0dG9uICpuZ0lmPVwiY29uZmlnLmdyb3Vwcz8ubGVuZ3RoXCIgbWF0LW1lbnUtaXRlbSBbbWF0TWVudVRyaWdnZXJGb3JdPVwiZ3JvdXBzU3ViTWVudVwiIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtdHJpZ2dlclwiPlxuICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtbGFiZWxcIj5Hcm91cGVyIHBhcjwvc3Bhbj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXZhbHVlXCIgKm5nSWY9XCIhaGlkZU1lbnVWYWx1ZXMgJiYgYWN0aXZlR3JvdXBCeUxhYmVsKClcIj57eyBhY3RpdmVHcm91cEJ5TGFiZWwoKSB9fTwvc3Bhbj5cbiAgPC9idXR0b24+XG5cbiAgPCEtLSBGaWx0cmVyIHBhciAtLT5cbiAgPGJ1dHRvbiAqbmdJZj1cImNvbmZpZy5zbGljZXM/Lmxlbmd0aFwiIG1hdC1tZW51LWl0ZW0gW21hdE1lbnVUcmlnZ2VyRm9yXT1cInNsaWNlc1N1Yk1lbnVcIiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXRyaWdnZXJcIj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+RmlsdHJlciBwYXI8L3NwYW4+XG4gICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItbWVudS12YWx1ZVwiICpuZ0lmPVwiIWhpZGVNZW51VmFsdWVzICYmIGFjdGl2ZVNsaWNlc0xhYmVsKClcIj57eyBhY3RpdmVTbGljZXNMYWJlbCgpIH19PC9zcGFuPlxuICA8L2J1dHRvbj5cblxuICA8IS0tIFRlbXBsYXRlIC0tPlxuICA8YnV0dG9uICpuZ0lmPVwiY29uZmlnLnRlbXBsYXRlcz8ubGVuZ3RoXCIgbWF0LW1lbnUtaXRlbSBbbWF0TWVudVRyaWdnZXJGb3JdPVwidGVtcGxhdGVTdWJNZW51XCIgY2xhc3M9XCJvcmdhbml6ZXItbWVudS10cmlnZ2VyXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1sYWJlbFwiPlRlbXBsYXRlPC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtdmFsdWVcIiAqbmdJZj1cIiFoaWRlTWVudVZhbHVlcyAmJiBhY3RpdmVUZW1wbGF0ZUxhYmVsKClcIj57eyBhY3RpdmVUZW1wbGF0ZUxhYmVsKCkgfX08L3NwYW4+XG4gIDwvYnV0dG9uPlxuXG4gIDwhLS0gQWN0aW9ucyBkdSB2aXN1ZWwgY291cmFudCAtLT5cbiAgPG1hdC1kaXZpZGVyICpuZ0lmPVwiaGFzQWN0aW9ucygpICYmIGhhc01lbnVJdGVtc0JlZm9yZUFjdGlvbnMoKVwiIGNsYXNzPVwib3JnYW5pemVyLWRpdmlkZXJcIj48L21hdC1kaXZpZGVyPlxuICA8YnV0dG9uICpuZ0lmPVwiaGFzQWN0aW9ucygpICYmIGhhc090aGVyTWVudUl0ZW1zKClcIiBtYXQtbWVudS1pdGVtIFttYXRNZW51VHJpZ2dlckZvcl09XCJhY3Rpb25zU3ViTWVudVwiIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtdHJpZ2dlclwiPlxuICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbmZpZy5hY3Rpb25zPy5pY29uXCIgY2xhc3M9XCJvcmdhbml6ZXItbWVudS1leHBvcnQtaWNvblwiPnt7IGNvbmZpZy5hY3Rpb25zPy5pY29uIH19PC9tYXQtaWNvbj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+e3sgYWN0aW9uc0xhYmVsKCkgfX08L3NwYW4+XG4gIDwvYnV0dG9uPlxuXG4gIDwhLS0gQWN0aW9ucyBkaXJlY3RlcyBsb3JzcXUnaWwgbid5IGEgYXVjdW4gYXV0cmUgaXRlbSBwcmluY2lwYWwgLS0+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJoYXNBY3Rpb25zKCkgJiYgIWhhc090aGVyTWVudUl0ZW1zKClcIj5cbiAgICA8YnV0dG9uICpuZ0lmPVwiaXNDb3B5QWN0aW9uVmlzaWJsZSgpXCIgbWF0LW1lbnUtaXRlbSB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cIm9uQ29weVZpc3VhbCgpXCI+XG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1leHBvcnQtaWNvblwiPmNvbnRlbnRfY29weTwvbWF0LWljb24+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+Q29waWVyPC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b24gKm5nSWY9XCJpc0Z1bGxzY3JlZW5BY3Rpb25WaXNpYmxlKClcIiBtYXQtbWVudS1pdGVtIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25Ub2dnbGVGdWxsc2NyZWVuKClcIj5cbiAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWV4cG9ydC1pY29uXCI+e3sgY29uZmlnLmlzRnVsbHNjcmVlbiA/ICdmdWxsc2NyZWVuX2V4aXQnIDogJ2Z1bGxzY3JlZW4nIH19PC9tYXQtaWNvbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtbGFiZWxcIj57eyBjb25maWcuaXNGdWxsc2NyZWVuID8gJ1F1aXR0ZXIgbGUgcGxlaW4gw6ljcmFuJyA6ICdQbGVpbiDDqWNyYW4nIH19PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8IS0tIEV4cG9ydCBkaXJlY3QgKG1vZGUgdGFibGUpIC0tPlxuICA8bWF0LWRpdmlkZXIgKm5nSWY9XCJjb25maWcuc2hvd0V4cG9ydFwiIGNsYXNzPVwib3JnYW5pemVyLWRpdmlkZXJcIj48L21hdC1kaXZpZGVyPlxuICA8YnV0dG9uICpuZ0lmPVwiY29uZmlnLnNob3dFeHBvcnQgJiYgIWhhc0V4cG9ydFN1Yk1lbnUoKVwiIG1hdC1tZW51LWl0ZW0gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtZXhwb3J0XCIgKGNsaWNrKT1cIm9uRXhwb3J0KClcIj5cbiAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1leHBvcnQtaWNvblwiPmRvd25sb2FkPC9tYXQtaWNvbj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+RXhwb3J0ZXI8L3NwYW4+XG4gIDwvYnV0dG9uPlxuXG4gIDwhLS0gRXhwb3J0IGdyYXBoaXF1ZSAobW9kZSBjaGFydCkg4oCUIG91dnJlIHVuIHNvdXMtbWVudSAtLT5cbiAgPGJ1dHRvbiAqbmdJZj1cImNvbmZpZy5zaG93RXhwb3J0ICYmIGhhc0V4cG9ydFN1Yk1lbnUoKVwiIG1hdC1tZW51LWl0ZW0gW21hdE1lbnVUcmlnZ2VyRm9yXT1cImV4cG9ydFN1Yk1lbnVcIiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXRyaWdnZXIgb3JnYW5pemVyLW1lbnUtZXhwb3J0XCI+XG4gICAgPG1hdC1pY29uIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtZXhwb3J0LWljb25cIj5kb3dubG9hZDwvbWF0LWljb24+XG4gICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1sYWJlbFwiPkV4cG9ydGVyPC9zcGFuPlxuICA8L2J1dHRvbj5cblxuICA8IS0tIFByw6lmw6lyZW5jZXMgLS0+XG4gIDxtYXQtZGl2aWRlciAqbmdJZj1cImNvbmZpZy5zaG93UHJlZmVyZW5jZXNcIiBjbGFzcz1cIm9yZ2FuaXplci1kaXZpZGVyXCI+PC9tYXQtZGl2aWRlcj5cbiAgPGJ1dHRvbiAqbmdJZj1cImNvbmZpZy5zaG93UHJlZmVyZW5jZXNcIiBtYXQtbWVudS1pdGVtIFttYXRNZW51VHJpZ2dlckZvcl09XCJwcmVmZXJlbmNlc1N1Yk1lbnVcIiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXRyaWdnZXJcIj5cbiAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LWxhYmVsXCI+UHLDqWbDqXJlbmNlczwvc3Bhbj5cbiAgPC9idXR0b24+XG5cbiAgPG1hdC1kaXZpZGVyICpuZ0lmPVwiY29uZmlnLnNob3dSZXNldCA9PT0gdHJ1ZVwiIGNsYXNzPVwib3JnYW5pemVyLWRpdmlkZXJcIj48L21hdC1kaXZpZGVyPlxuICA8YnV0dG9uICpuZ0lmPVwiY29uZmlnLnNob3dSZXNldCA9PT0gdHJ1ZVwiIG1hdC1tZW51LWl0ZW0gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtcmVzZXRcIiAoY2xpY2spPVwib25SZXNldCgpXCI+XG4gICAgPG1hdC1pY29uIGNsYXNzPVwib3JnYW5pemVyLW1lbnUtZXhwb3J0LWljb25cIj5yZXN0YXJ0X2FsdDwvbWF0LWljb24+XG4gICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1sYWJlbFwiPlLDqWluaXRpYWxpc2VyIGxhIHZ1ZTwvc3Bhbj5cbiAgPC9idXR0b24+XG5cbiAgPCEtLSBTd2l0Y2ggY2hhcnQgLyB0YWJsZSAtLT5cbiAgPG1hdC1kaXZpZGVyICpuZ0lmPVwiaGFzU3dpdGNoVmlldygpXCIgY2xhc3M9XCJvcmdhbml6ZXItZGl2aWRlclwiPjwvbWF0LWRpdmlkZXI+XG4gIDxidXR0b24gKm5nSWY9XCJoYXNTd2l0Y2hWaWV3KClcIiBtYXQtbWVudS1pdGVtIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1tZW51LXRyaWdnZXJcIiAoY2xpY2spPVwib25Td2l0Y2hWaWV3KClcIj5cbiAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1leHBvcnQtaWNvblwiPnt7IGNvbmZpZy5zd2l0Y2hWaWV3Py5jdXJyZW50VmlldyA9PT0gJ2NoYXJ0JyA/ICd0YWJsZV9jaGFydCcgOiAnYmFyX2NoYXJ0JyB9fTwvbWF0LWljb24+XG4gICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItbWVudS1sYWJlbFwiPnt7IGNvbmZpZy5zd2l0Y2hWaWV3Py5jdXJyZW50VmlldyA9PT0gJ2NoYXJ0JyA/ICdUYWJsZWF1JyA6ICdHcmFwaGlxdWUnIH19PC9zcGFuPlxuICA8L2J1dHRvbj5cblxuPC9tYXQtbWVudT5cblxuPCEtLSBTb3VzLW1lbnUgOiB0eXBlcyBkZSBncmFwaGlxdWUgLS0+XG48bWF0LW1lbnUgI2NoYXJ0VHlwZXNTdWJNZW51PVwibWF0TWVudVwiIHBhbmVsQ2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1wYW5lbFwiPlxuICA8ZGl2IGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnVcIlxuICAgICAgIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIlxuICAgICAgKm5nRm9yPVwibGV0IGNoYXJ0VHlwZSBvZiBjb25maWcuY2hhcnRUeXBlc1wiXG4gICAgICBbY2xhc3MuYWN0aXZlXT1cImlzQ2hhcnRUeXBlQWN0aXZlKGNoYXJ0VHlwZS5pZClcIlxuICAgICAgW2Rpc2FibGVkXT1cImNoYXJ0VHlwZS5kaXNhYmxlZFwiXG4gICAgICAoY2xpY2spPVwib25DaGFydFR5cGVTZWxlY3QoY2hhcnRUeXBlLmlkKVwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1jaGVja1wiPnt7IGlzQ2hhcnRUeXBlQWN0aXZlKGNoYXJ0VHlwZS5pZCkgPyAn4pyTJyA6ICcnIH19PC9zcGFuPlxuICAgICAgPG1hdC1pY29uICpuZ0lmPVwiY2hhcnRUeXBlLmljb25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWljb25cIj57eyBjaGFydFR5cGUuaWNvbiB9fTwvbWF0LWljb24+XG4gICAgICB7eyBjaGFydFR5cGUubGFiZWwgfX1cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L21hdC1tZW51PlxuXG48IS0tIFNvdXMtbWVudSA6IGFjdGlvbnMgZHUgdmlzdWVsIC0tPlxuPG1hdC1tZW51ICNhY3Rpb25zU3ViTWVudT1cIm1hdE1lbnVcIiBwYW5lbENsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtcGFuZWxcIj5cbiAgPGRpdiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51XCJcbiAgICAgICAobW91c2Vkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgKGtleWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgPGJ1dHRvbiAqbmdJZj1cImlzQ29weUFjdGlvblZpc2libGUoKVwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIlxuICAgICAgKGNsaWNrKT1cIm9uQ29weVZpc3VhbCgpXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWNoZWNrXCI+PC9zcGFuPlxuICAgICAgPG1hdC1pY29uIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaWNvblwiPmNvbnRlbnRfY29weTwvbWF0LWljb24+XG4gICAgICBDb3BpZXJcbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uICpuZ0lmPVwiaXNGdWxsc2NyZWVuQWN0aW9uVmlzaWJsZSgpXCIgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaXRlbVwiXG4gICAgICAoY2xpY2spPVwib25Ub2dnbGVGdWxsc2NyZWVuKClcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtY2hlY2tcIj48L3NwYW4+XG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pY29uXCI+e3sgY29uZmlnLmlzRnVsbHNjcmVlbiA/ICdmdWxsc2NyZWVuX2V4aXQnIDogJ2Z1bGxzY3JlZW4nIH19PC9tYXQtaWNvbj5cbiAgICAgIHt7IGNvbmZpZy5pc0Z1bGxzY3JlZW4gPyAnUXVpdHRlciBsZSBwbGVpbiDDqWNyYW4nIDogJ1BsZWluIMOpY3JhbicgfX1cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L21hdC1tZW51PlxuXG48IS0tIFNvdXMtbWVudSA6IEV4cG9ydCBncmFwaGlxdWUgLS0+XG48bWF0LW1lbnUgI2V4cG9ydFN1Yk1lbnU9XCJtYXRNZW51XCIgcGFuZWxDbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LXBhbmVsXCI+XG4gIDxkaXYgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudVwiXG4gICAgICAgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChrZXlkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgIDxidXR0b24gKm5nSWY9XCJjb25maWcub25FeHBvcnRWaXN1YWxcIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pdGVtXCJcbiAgICAgIChjbGljayk9XCJvbkV4cG9ydFZpc3VhbCgpXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWNoZWNrXCI+PC9zcGFuPlxuICAgICAgPG1hdC1pY29uIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaWNvblwiPmltYWdlPC9tYXQtaWNvbj5cbiAgICAgIFZpc3VlbFxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b24gKm5nSWY9XCJjb25maWcub25FeHBvcnREYXRhXCIgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaXRlbVwiXG4gICAgICAoY2xpY2spPVwib25FeHBvcnREYXRhKClcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtY2hlY2tcIj48L3NwYW4+XG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pY29uXCI+dGFibGVfY2hhcnQ8L21hdC1pY29uPlxuICAgICAgRG9ubsOpZXNcbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L21hdC1tZW51PlxuXG48IS0tIFNvdXMtbWVudSA6IENoYW1wcyBjaGFydCAoWCArIFkpIC0tPlxuPG1hdC1tZW51ICNjaGFtcHNTdWJNZW51PVwibWF0TWVudVwiIHBhbmVsQ2xhc3M9XCJvcmdhbml6ZXItY2hhbXBzLXBhbmVsXCI+XG4gIDxkaXYgY2xhc3M9XCJvcmdhbml6ZXItY2hhbXBzLXdyYXBwZXJcIlxuICAgICAgIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cblxuICAgIDwhLS0gQmxvYyBYIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJvcmdhbml6ZXItY2hhbXBzLWJsb2NrXCIgKm5nSWY9XCJjb25maWcueEZpZWxkcz8ubGVuZ3RoXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1jaGFtcHMtYmxvY2stdGl0bGVcIj5BeGUgaG9yaXpvbnRhbCDigJQgWDwvc3Bhbj5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaXRlbVwiXG4gICAgICAgICpuZ0Zvcj1cImxldCB4RmllbGQgb2YgY29uZmlnLnhGaWVsZHNcIlxuICAgICAgICBbY2xhc3MuYWN0aXZlXT1cInN0YXRlPy5zZWxlY3RlZFggPT09IHhGaWVsZC5pZFwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJ4RmllbGQuZGlzYWJsZWRcIlxuICAgICAgICAoY2xpY2spPVwib25YRmllbGRTZWxlY3QoeEZpZWxkLmlkKVwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWNoZWNrXCI+e3sgc3RhdGU/LnNlbGVjdGVkWCA9PT0geEZpZWxkLmlkID8gJ+KckycgOiAnJyB9fTwvc3Bhbj5cbiAgICAgICAge3sgeEZpZWxkLmxhYmVsIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cblxuICAgIDxtYXQtZGl2aWRlciAqbmdJZj1cImNvbmZpZy54RmllbGRzPy5sZW5ndGggJiYgY29uZmlnLnlGaWVsZHM/Lmxlbmd0aFwiIGNsYXNzPVwib3JnYW5pemVyLWNoYW1wcy1kaXZpZGVyXCI+PC9tYXQtZGl2aWRlcj5cblxuICAgIDwhLS0gQmxvYyBZIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJvcmdhbml6ZXItY2hhbXBzLWJsb2NrXCIgKm5nSWY9XCJjb25maWcueUZpZWxkcz8ubGVuZ3RoXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1jaGFtcHMtYmxvY2stdGl0bGVcIj5BeGUgdmVydGljYWwg4oCUIFk8L3NwYW4+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCB5RmllbGQgb2YgY29uZmlnLnlGaWVsZHNcIj5cblxuICAgICAgICA8IS0tIFkgc2ltcGxlIChDb3VudCBzYW5zIGFncsOpZ2F0IG5pIHN0YWNrKSAtLT5cbiAgICAgICAgPCEtLSBZIHNpbXBsZSAoQ291bnQgb3UgbcOpdHJpcXVlIGRpcmVjdGUpIC0tPlxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiIXlGaWVsZC5hZ2dyZWdhdGVzPy5sZW5ndGhcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIlxuICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiaXNZQWN0aXZlKHlGaWVsZC5pZClcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJ5RmllbGQuZGlzYWJsZWRcIlxuICAgICAgICAgIChjbGljayk9XCJvbllGaWVsZFNlbGVjdCh5RmllbGQuaWQpXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1jaGVja1wiPnt7IGlzWUFjdGl2ZSh5RmllbGQuaWQpID8gJ+KckycgOiAnJyB9fTwvc3Bhbj5cbiAgICAgICAgICB7eyB5RmllbGQubGFiZWwgfX1cbiAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgPCEtLSBZIGF2ZWMgYWdyw6lnYXRzIOKGkiBzb3VzLW1lbnUgLS0+XG4gICAgICAgIDxidXR0b24gKm5nSWY9XCJ5RmllbGQuYWdncmVnYXRlcz8ubGVuZ3RoXCJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pdGVtIG9yZ2FuaXplci1zdWJtZW51LWl0ZW0tLWhhcy1jaGlsZHJlblwiXG4gICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJpc1lBY3RpdmUoeUZpZWxkLmlkKVwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cInlGaWVsZC5kaXNhYmxlZFwiXG4gICAgICAgICAgW21hdE1lbnVUcmlnZ2VyRm9yXT1cInlBZ2dTdWJNZW51XCJcbiAgICAgICAgICBbbWF0TWVudVRyaWdnZXJEYXRhXT1cInsgeUZpZWxkOiB5RmllbGQgfVwiXG4gICAgICAgICAgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWNoZWNrXCI+e3sgaXNZQWN0aXZlKHlGaWVsZC5pZCkgPyAn4pyTJyA6ICcnIH19PC9zcGFuPlxuICAgICAgICAgIHt7IHlGaWVsZC5sYWJlbCB9fVxuICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWFycm93XCI+Y2hldnJvbl9yaWdodDwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cblxuICA8L2Rpdj5cbjwvbWF0LW1lbnU+XG5cbjwhLS0gU291cy1tZW51IGR5bmFtaXF1ZSA6IGFncsOpZ2F0cyBkJ3VuIGNoYW1wIFkgLS0+XG48bWF0LW1lbnUgI3lBZ2dTdWJNZW51PVwibWF0TWVudVwiIHBhbmVsQ2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1wYW5lbFwiPlxuICA8bmctdGVtcGxhdGUgbWF0TWVudUNvbnRlbnQgbGV0LXlGaWVsZD1cInlGaWVsZFwiPlxuICAgIDxkaXYgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudVwiXG4gICAgICAgICAobW91c2Vkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgIChrZXlkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pdGVtXCJcbiAgICAgICAgKm5nRm9yPVwibGV0IGFnZyBvZiB5RmllbGQuYWdncmVnYXRlc1wiXG4gICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiaXNZQWdncmVnYXRlQWN0aXZlKHlGaWVsZC5pZCwgYWdnLmlkKVwiXG4gICAgICAgIChjbGljayk9XCJvbllBZ2dyZWdhdGVTZWxlY3QoeUZpZWxkLmlkLCBhZ2cuaWQpXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtY2hlY2tcIj57eyBpc1lBZ2dyZWdhdGVBY3RpdmUoeUZpZWxkLmlkLCBhZ2cuaWQpID8gJ+KckycgOiAnJyB9fTwvc3Bhbj5cbiAgICAgICAge3sgYWdnLmxhYmVsIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvbWF0LW1lbnU+XG5cbjwhLS0gU291cy1tZW51IDogQ2hhbXBzIHRhYmxlICh0b2dnbGUgY29sb25uZXMpIC0tPlxuPG1hdC1tZW51ICNmaWVsZHNTdWJNZW51PVwibWF0TWVudVwiIHBhbmVsQ2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1wYW5lbFwiPlxuICA8ZGl2IGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnVcIlxuICAgICAgIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIlxuICAgICAgKm5nRm9yPVwibGV0IGZpZWxkIG9mIGNvbmZpZy5maWVsZHNcIlxuICAgICAgW2NsYXNzLmFjdGl2ZV09XCJpc0ZpZWxkVmlzaWJsZShmaWVsZC5pZClcIlxuICAgICAgKGNsaWNrKT1cIm9uRmllbGRUb2dnbGUoZmllbGQuaWQsICFpc0ZpZWxkVmlzaWJsZShmaWVsZC5pZCkpXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWNoZWNrXCI+e3sgaXNGaWVsZFZpc2libGUoZmllbGQuaWQpID8gJ+KckycgOiAnJyB9fTwvc3Bhbj4gICAgICA8bWF0LWljb24gKm5nSWY9XCJmaWVsZC5pY29uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pY29uXCI+e3sgZmllbGQuaWNvbiB9fTwvbWF0LWljb24+ICAgICAge3sgZmllbGQubGFiZWwgfX1cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L21hdC1tZW51PlxuXG48IS0tIFNvdXMtbWVudSA6IEdyb3VwZXIgcGFyIC0tPlxuPG1hdC1tZW51ICNncm91cHNTdWJNZW51PVwibWF0TWVudVwiIHBhbmVsQ2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1wYW5lbFwiPlxuICA8ZGl2IGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnVcIlxuICAgICAgIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIlxuICAgICAgKm5nRm9yPVwibGV0IGdyb3VwIG9mIGNvbmZpZy5ncm91cHNcIlxuICAgICAgW2NsYXNzLmFjdGl2ZV09XCJzdGF0ZT8uc2VsZWN0ZWRHcm91cEJ5ID09PSBncm91cC5pZFwiXG4gICAgICAoY2xpY2spPVwib25Hcm91cEJ5U2VsZWN0KGdyb3VwLmlkKVwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1jaGVja1wiPnt7IHN0YXRlPy5zZWxlY3RlZEdyb3VwQnkgPT09IGdyb3VwLmlkID8gJ+KckycgOiAnJyB9fTwvc3Bhbj4gICAgICA8bWF0LWljb24gKm5nSWY9XCJncm91cC5pY29uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pY29uXCI+e3sgZ3JvdXAuaWNvbiB9fTwvbWF0LWljb24+ICAgICAge3sgZ3JvdXAubGFiZWwgfX1cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L21hdC1tZW51PlxuXG48IS0tIFNvdXMtbWVudSA6IEZpbHRyZXIgcGFyIC0tPlxuPG1hdC1tZW51ICNzbGljZXNTdWJNZW51PVwibWF0TWVudVwiIHBhbmVsQ2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1wYW5lbFwiPlxuICA8ZGl2IGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnVcIlxuICAgICAgIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIlxuICAgICAgKm5nRm9yPVwibGV0IHNsaWNlIG9mIGNvbmZpZy5zbGljZXNcIlxuICAgICAgW2NsYXNzLmFjdGl2ZV09XCJzdGF0ZT8uc2VsZWN0ZWRTbGljZXM/LmluY2x1ZGVzKHNsaWNlLmlkKVwiXG4gICAgICAoY2xpY2spPVwib25TbGljZUNsaWNrKHNsaWNlLmlkKVwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1jaGVja1wiPnt7IHN0YXRlPy5zZWxlY3RlZFNsaWNlcz8uaW5jbHVkZXMoc2xpY2UuaWQpID8gJ+KckycgOiAnJyB9fTwvc3Bhbj4gICAgICA8bWF0LWljb24gKm5nSWY9XCJzbGljZS5pY29uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pY29uXCI+e3sgc2xpY2UuaWNvbiB9fTwvbWF0LWljb24+ICAgICAge3sgc2xpY2UubGFiZWwgfX1cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L21hdC1tZW51PlxuXG48IS0tIFNvdXMtbWVudSA6IFRlbXBsYXRlIC0tPlxuPG1hdC1tZW51ICN0ZW1wbGF0ZVN1Yk1lbnU9XCJtYXRNZW51XCIgcGFuZWxDbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LXBhbmVsXCI+XG4gIDxkaXYgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudVwiXG4gICAgICAgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChrZXlkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaXRlbVwiXG4gICAgICAqbmdGb3I9XCJsZXQgdG1wbCBvZiBjb25maWcudGVtcGxhdGVzXCJcbiAgICAgIFtjbGFzcy5hY3RpdmVdPVwic3RhdGU/LnNlbGVjdGVkVGVtcGxhdGUgPT09IHRtcGwuaWRcIlxuICAgICAgW3RpdGxlXT1cInRtcGwuZGVzY3JpcHRpb24gfHwgJydcIlxuICAgICAgKGNsaWNrKT1cIm9uVGVtcGxhdGVTZWxlY3QodG1wbC5pZClcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtY2hlY2tcIj57eyBzdGF0ZT8uc2VsZWN0ZWRUZW1wbGF0ZSA9PT0gdG1wbC5pZCA/ICfinJMnIDogJycgfX08L3NwYW4+XG4gICAgICA8bWF0LWljb24gKm5nSWY9XCJ0bXBsLmljb25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWljb25cIj57eyB0bXBsLmljb24gfX08L21hdC1pY29uPlxuICAgICAge3sgdG1wbC5sYWJlbCB9fVxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvbWF0LW1lbnU+XG5cbjwhLS0gU291cy1tZW51IDogUHLDqWbDqXJlbmNlcyAtLT5cbjxtYXQtbWVudSAjcHJlZmVyZW5jZXNTdWJNZW51PVwibWF0TWVudVwiIHBhbmVsQ2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1wYW5lbFwiPlxuICA8ZGl2IGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnVcIlxuICAgICAgIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAoa2V5ZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIiAoY2xpY2spPVwib25QcmVmZXJlbmNlc0VkaXQoKVwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1jaGVja1wiPjwvc3Bhbj5cbiAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWljb25cIj5lZGl0PC9tYXQtaWNvbj7DiWRpdGVyXG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pdGVtXCIgKGNsaWNrKT1cIm9uUHJlZmVyZW5jZXNTYXZlKClcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtY2hlY2tcIj48L3NwYW4+XG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJvcmdhbml6ZXItc3VibWVudS1pY29uXCI+c2F2ZTwvbWF0LWljb24+U2F1dmVnYXJkZXJcbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWl0ZW1cIiBbZGlzYWJsZWRdPVwiIWNvbmZpZy5oYXNTYXZlZFByZWZlcmVuY2VzXCIgKGNsaWNrKT1cIm9uUHJlZmVyZW5jZXNDbGVhcigpXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm9yZ2FuaXplci1zdWJtZW51LWNoZWNrXCI+PC9zcGFuPlxuICAgICAgPG1hdC1pY29uIGNsYXNzPVwib3JnYW5pemVyLXN1Ym1lbnUtaWNvblwiPmRlbGV0ZV9vdXRsaW5lPC9tYXQtaWNvbj5Sw6lpbml0aWFsaXNlclxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvbWF0LW1lbnU+XG5cbiJdfQ==