bways-report 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +463 -316
  2. package/esm2022/lib/core/config/bways-report-config.mjs +31 -32
  3. package/esm2022/lib/core/models/index.mjs +1 -1
  4. package/esm2022/lib/core/models/report-api-endpoint.model.mjs +8 -0
  5. package/esm2022/lib/core/models/report-component.model.mjs +1 -1
  6. package/esm2022/lib/core/models/report-datasource.model.mjs +1 -1
  7. package/esm2022/lib/core/services/index.mjs +2 -1
  8. package/esm2022/lib/core/services/report-api-execution.service.mjs +210 -0
  9. package/esm2022/lib/core/services/report-data-discovery.service.mjs +76 -4
  10. package/esm2022/lib/core/services/report-session-context.service.mjs +72 -3
  11. package/esm2022/lib/core/tokens/designer-config.token.mjs +4 -0
  12. package/esm2022/lib/core/tokens/reporting-config.token.mjs +1 -1
  13. package/esm2022/lib/core/utils/report-endpoint.util.mjs +22 -0
  14. package/esm2022/lib/core/utils/report-request-scope.mjs +48 -0
  15. package/esm2022/lib/data-access/adapters/endpoint-datasource.adapter.mjs +31 -1
  16. package/esm2022/lib/data-access/adapters/endpoint-lookup.adapter.mjs +27 -2
  17. package/esm2022/lib/data-access/adapters/endpoint-masterdata.adapter.mjs +5 -2
  18. package/esm2022/lib/data-access/adapters/endpoint-persistence.adapter.mjs +30 -14
  19. package/esm2022/lib/data-access/adapters/endpoint-schema-discovery.adapter.mjs +32 -28
  20. package/esm2022/lib/data-access/adapters/endpoint-tokens.mjs +1 -1
  21. package/esm2022/lib/data-access/adapters/http-datasource.adapter.mjs +4 -37
  22. package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +28 -51
  23. package/esm2022/lib/data-access/adapters/http-persistence.adapter.mjs +43 -194
  24. package/esm2022/lib/data-access/adapters/http-schema-discovery.adapter.mjs +17 -65
  25. package/esm2022/lib/data-access/adapters/index.mjs +1 -1
  26. package/esm2022/lib/data-access/adapters/local-storage-persistence.adapter.mjs +13 -4
  27. package/esm2022/lib/data-access/adapters/report-id-availability.mjs +20 -0
  28. package/esm2022/lib/data-access/adapters/session-headers.mjs +11 -0
  29. package/esm2022/lib/data-access/contracts/index.mjs +1 -1
  30. package/esm2022/lib/data-access/contracts/lookup.contract.mjs +1 -1
  31. package/esm2022/lib/data-access/contracts/report-persistence.contract.mjs +13 -1
  32. package/esm2022/lib/features/designer/components/component-palette/component-palette.component.mjs +536 -6
  33. package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +55 -17
  34. package/esm2022/lib/features/designer/components/dialogs/report-saved-dialog.component.mjs +546 -119
  35. package/esm2022/lib/features/designer/components/property-editor/parameter-binding-editor.component.mjs +3 -3
  36. package/esm2022/lib/features/designer/components/property-editor/property-editor-action.component.mjs +3 -3
  37. package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +142 -8
  38. package/esm2022/lib/features/designer/components/property-editor/property-editor-general.component.mjs +3 -3
  39. package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +129 -28
  40. package/esm2022/lib/features/designer/components/property-editor/property-editor-layout.component.mjs +3 -3
  41. package/esm2022/lib/features/designer/components/property-editor/property-editor-report.component.mjs +3 -3
  42. package/esm2022/lib/features/designer/components/property-editor/property-editor-validation.component.mjs +3 -3
  43. package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +27 -13
  44. package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +54 -32
  45. package/esm2022/lib/features/designer/designer.component.mjs +109 -75
  46. package/esm2022/lib/features/designer/rpt-report-designer.component.mjs +10 -4
  47. package/esm2022/lib/features/designer/services/designer-config.service.mjs +56 -0
  48. package/esm2022/lib/features/designer/services/designer-endpoints.service.mjs +155 -0
  49. package/esm2022/lib/features/designer/services/designer-state.service.mjs +3 -2
  50. package/esm2022/lib/features/designer/utilities/canvas-layout.util.mjs +2 -1
  51. package/esm2022/lib/features/embed/bways-report-builder.component.mjs +3 -3
  52. package/esm2022/lib/features/export/services/report-export.service.mjs +11 -6
  53. package/esm2022/lib/features/persistence/services/report-store.service.mjs +78 -23
  54. package/esm2022/lib/features/persistence/services/schema-validator.service.mjs +59 -3
  55. package/esm2022/lib/features/routing/components/routed-report-designer.component.mjs +12 -17
  56. package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +6 -4
  57. package/esm2022/lib/features/routing/report-routes.mjs +6 -6
  58. package/esm2022/lib/features/routing/resolvers/report-route-identifier.mjs +5 -0
  59. package/esm2022/lib/features/routing/resolvers/report.resolver.mjs +3 -2
  60. package/esm2022/lib/features/runtime/dynamic-renderer.component.mjs +23 -4
  61. package/esm2022/lib/features/runtime/report-execution.service.mjs +36 -6
  62. package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +54 -11
  63. package/esm2022/lib/features/runtime/report-runtime.component.mjs +105 -68
  64. package/esm2022/lib/features/runtime/rpt-report.component.mjs +50 -42
  65. package/esm2022/lib/primitives/components/chart-bridge/report-chart-bridge.component.mjs +7 -2
  66. package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +16 -7
  67. package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +53 -1
  68. package/esm2022/lib/primitives/components/index.mjs +2 -1
  69. package/esm2022/lib/primitives/components/radio/rpt-radio.component.mjs +428 -0
  70. package/esm2022/lib/primitives/register-builtins.mjs +51 -2
  71. package/esm2022/lib/provide-reporting.mjs +11 -29
  72. package/fesm2022/bways-report.mjs +3745 -1281
  73. package/fesm2022/bways-report.mjs.map +1 -1
  74. package/lib/core/config/bways-report-config.d.ts +27 -5
  75. package/lib/core/models/index.d.ts +2 -1
  76. package/lib/core/models/report-api-endpoint.model.d.ts +30 -0
  77. package/lib/core/models/report-component.model.d.ts +16 -4
  78. package/lib/core/models/report-datasource.model.d.ts +21 -2
  79. package/lib/core/services/index.d.ts +1 -0
  80. package/lib/core/services/report-api-execution.service.d.ts +41 -0
  81. package/lib/core/services/report-data-discovery.service.d.ts +23 -1
  82. package/lib/core/services/report-session-context.service.d.ts +9 -0
  83. package/lib/core/tokens/designer-config.token.d.ts +4 -0
  84. package/lib/core/tokens/reporting-config.token.d.ts +4 -0
  85. package/lib/core/utils/report-endpoint.util.d.ts +12 -0
  86. package/lib/core/utils/report-request-scope.d.ts +14 -0
  87. package/lib/data-access/adapters/endpoint-datasource.adapter.d.ts +2 -0
  88. package/lib/data-access/adapters/endpoint-lookup.adapter.d.ts +1 -0
  89. package/lib/data-access/adapters/endpoint-persistence.adapter.d.ts +6 -2
  90. package/lib/data-access/adapters/endpoint-schema-discovery.adapter.d.ts +4 -2
  91. package/lib/data-access/adapters/endpoint-tokens.d.ts +7 -0
  92. package/lib/data-access/adapters/http-datasource.adapter.d.ts +1 -3
  93. package/lib/data-access/adapters/http-lookup.adapter.d.ts +3 -4
  94. package/lib/data-access/adapters/http-persistence.adapter.d.ts +11 -16
  95. package/lib/data-access/adapters/http-schema-discovery.adapter.d.ts +3 -5
  96. package/lib/data-access/adapters/index.d.ts +1 -1
  97. package/lib/data-access/adapters/local-storage-persistence.adapter.d.ts +2 -2
  98. package/lib/data-access/adapters/report-id-availability.d.ts +6 -0
  99. package/lib/data-access/adapters/session-headers.d.ts +3 -0
  100. package/lib/data-access/contracts/index.d.ts +1 -0
  101. package/lib/data-access/contracts/lookup.contract.d.ts +3 -0
  102. package/lib/data-access/contracts/report-persistence.contract.d.ts +16 -1
  103. package/lib/features/designer/components/component-palette/component-palette.component.d.ts +16 -0
  104. package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +2 -0
  105. package/lib/features/designer/components/dialogs/report-saved-dialog.component.d.ts +37 -5
  106. package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +21 -3
  107. package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +20 -7
  108. package/lib/features/designer/components/property-editor/property-editor.component.d.ts +2 -1
  109. package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +7 -1
  110. package/lib/features/designer/designer.component.d.ts +16 -2
  111. package/lib/features/designer/rpt-report-designer.component.d.ts +5 -1
  112. package/lib/features/designer/services/designer-config.service.d.ts +13 -0
  113. package/lib/features/designer/services/designer-endpoints.service.d.ts +25 -0
  114. package/lib/features/persistence/services/report-store.service.d.ts +15 -1
  115. package/lib/features/persistence/services/schema-validator.service.d.ts +2 -0
  116. package/lib/features/routing/resolvers/report-route-identifier.d.ts +2 -0
  117. package/lib/features/runtime/report-execution.service.d.ts +4 -0
  118. package/lib/features/runtime/report-grid-bridge.component.d.ts +4 -1
  119. package/lib/features/runtime/report-runtime.component.d.ts +14 -1
  120. package/lib/features/runtime/rpt-report.component.d.ts +5 -0
  121. package/lib/primitives/components/chart-bridge/report-chart-bridge.component.d.ts +3 -1
  122. package/lib/primitives/components/index.d.ts +2 -0
  123. package/lib/primitives/components/radio/rpt-radio.component.d.ts +77 -0
  124. package/package.json +2 -1
@@ -1,12 +1,15 @@
1
- import { ChangeDetectionStrategy, Component, computed, HostListener, inject, signal, } from '@angular/core';
1
+ import { ReportRequestScope } from '../../../../core/utils/report-request-scope';
2
+ import { ChangeDetectionStrategy, Component, computed, effect, HostListener, inject, signal, untracked, } from '@angular/core';
2
3
  import { CommonModule } from '@angular/common';
3
4
  import { ReactiveFormsModule, FormControl, FormGroup } from '@angular/forms';
4
5
  import { DragDropModule, } from '@angular/cdk/drag-drop';
5
6
  import { DesignerStateService } from '../../services/designer-state.service';
6
7
  import { ReportTemplateService } from '../../services/report-template.service';
8
+ import { humanizeIdentifier } from '../../../../core/utils/identifier-humanizer';
7
9
  import { RptIconComponent } from '../../../../primitives/components/icon/rpt-icon.component';
8
10
  import { RptDropdownComponent } from '../../../../primitives/components/dropdown/rpt-dropdown.component';
9
11
  import { RptDateRangeComponent } from '../../../../primitives/components/date-range/rpt-date-range.component';
12
+ import { RptRadioComponent } from '../../../../primitives/components/radio/rpt-radio.component';
10
13
  import { ReportGridBridgeComponent } from '../../../runtime/report-grid-bridge.component';
11
14
  import { DynamicFormBuilder } from '../../../../core/services/dynamic-form-builder.service';
12
15
  import { ReportExecutionService } from '../../../runtime/report-execution.service';
@@ -15,6 +18,17 @@ import * as i0 from "@angular/core";
15
18
  import * as i1 from "@angular/cdk/drag-drop";
16
19
  import * as i2 from "@angular/forms";
17
20
  export class DesignCanvasComponent {
21
+ requests = new ReportRequestScope();
22
+ constructor() {
23
+ let previous = '';
24
+ effect(() => {
25
+ const key = JSON.stringify([this.requests.context(), this.definition().id]);
26
+ if (key === previous)
27
+ return;
28
+ previous = key;
29
+ untracked(() => { this.requests.cancelAll(); this.canvasGridData.set([]); this.isExecutingGrid.set(false); this.gridExecError.set(null); });
30
+ }, { allowSignalWrites: true });
31
+ }
18
32
  designerState = inject(DesignerStateService);
19
33
  gridFilterDebounceTimer = null;
20
34
  pendingGridState = null;
@@ -307,18 +321,40 @@ export class DesignCanvasComponent {
307
321
  }
308
322
  this.isExecutingGrid.set(true);
309
323
  this.gridExecError.set(null);
310
- this.executionService.execute(this.definition(), formValues).subscribe({
311
- next: (rows) => {
312
- this.canvasGridData.set(rows || []);
313
- this.isExecutingGrid.set(false);
314
- },
315
- error: (err) => {
316
- console.error('[DesignCanvas] Query execution error:', err);
317
- const msg = err instanceof Error ? err.message : String(err);
318
- this.gridExecError.set(msg || 'Execution failed');
319
- this.isExecutingGrid.set(false);
320
- },
321
- });
324
+ this.requests.run('canvas-execution', () => this.executionService.execute(this.definition(), formValues), (rows) => {
325
+ this.canvasGridData.set(rows || []);
326
+ this.isExecutingGrid.set(false);
327
+ // Auto-populate grid columns if grid has dummy columns that don't match the executed rows
328
+ if (rows && rows.length > 0 && typeof rows[0] === 'object' && rows[0] !== null) {
329
+ const currentGrid = this.definition().grid;
330
+ if (currentGrid) {
331
+ const firstRow = rows[0];
332
+ const keys = Object.keys(firstRow).filter((k) => k.trim().length > 0);
333
+ const matchesAny = currentGrid.columns.some((c) => keys.includes(c.field));
334
+ if (!matchesAny && keys.length > 0) {
335
+ const detectedCols = keys.map((k) => ({
336
+ field: k,
337
+ label: humanizeIdentifier(k),
338
+ dataType: typeof firstRow[k] === 'number' ? 'number' : typeof firstRow[k] === 'boolean' ? 'boolean' : 'string',
339
+ visible: true,
340
+ sortable: true,
341
+ }));
342
+ const cleanOptions = { ...(currentGrid.options || {}) };
343
+ delete cleanOptions.reportState;
344
+ this.designerState.updateGridSettings({
345
+ ...currentGrid,
346
+ options: cleanOptions,
347
+ columns: detectedCols,
348
+ });
349
+ }
350
+ }
351
+ }
352
+ }, (err) => {
353
+ console.error('[DesignCanvas] Query execution error:', err);
354
+ const msg = err instanceof Error ? err.message : String(err);
355
+ this.gridExecError.set(msg || 'Execution failed');
356
+ this.isExecutingGrid.set(false);
357
+ }, () => this.isExecutingGrid.set(false));
322
358
  }
323
359
  onCanvasButtonClick(comp, event) {
324
360
  event.stopPropagation();
@@ -327,6 +363,7 @@ export class DesignCanvasComponent {
327
363
  this.executeCanvasReport();
328
364
  }
329
365
  else if (action === 'reset') {
366
+ this.requests.cancel('canvas-execution');
330
367
  this.canvasForm().reset();
331
368
  this.canvasGridData.set([]);
332
369
  }
@@ -451,7 +488,7 @@ export class DesignCanvasComponent {
451
488
  this.designerState.addComponent(type);
452
489
  }
453
490
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DesignCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
454
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: DesignCanvasComponent, isStandalone: true, selector: "rpt-design-canvas", host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: " <div class=\"canvas-wrapper\" (click)=\"onCanvasBackgroundClick($event)\">\n <!-- Canvas Status / Quick Controls -->\n <div class=\"canvas-toolbar\">\n <div class=\"canvas-info\">\n <span class=\"info-label\">Grid Layout:</span>\n <span class=\"info-value\">{{ totalColumns() }} Columns</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"info-label\">Components:</span>\n <span class=\"info-value\">{{ components().length }}</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"live-mode-badge\" title=\"Interactive canvas: Values typed here run live queries and test dropdowns.\">\n \u26A1 Live Interactive Mode\n </span>\n </div>\n\n <div class=\"canvas-actions\">\n @if (!definition().grid) {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-add\"\n (click)=\"addResultGrid($event)\"\n title=\"Add a Result Grid to this report\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>+ Add Grid</span>\n </button>\n } @else {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-configured\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure Result Data Grid\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>Grid ({{ definition().grid?.columns?.length ?? 0 }})</span>\n </button>\n }\n\n <button\n type=\"button\"\n class=\"canvas-action-btn\"\n (click)=\"selectReportSettings($event)\"\n title=\"Configure Page Layout & Grid Settings\"\n >\n <rpt-icon name=\"settings\" [size]=\"14\" />\n <span>Report Settings</span>\n </button>\n </div>\n </div>\n\n <!-- Canvas Drop Area -->\n <div class=\"canvas-scroll-area\">\n <div\n class=\"canvas-artboard\"\n [style.padding.px]=\"definition().layout.padding ?? 24\"\n >\n <!-- Report Header Preview -->\n <div class=\"canvas-report-header\">\n <h2 class=\"canvas-report-title\">{{ definition().name || 'Untitled Report' }}</h2>\n @if (definition().description) {\n <p class=\"canvas-report-desc\">{{ definition().description }}</p>\n }\n </div>\n\n <!-- Component Drop List Grid with 2D mixed orientation and data binding -->\n <div\n cdkDropList\n id=\"designer-canvas-drop-list\"\n class=\"canvas-grid\"\n cdkDropListOrientation=\"mixed\"\n [cdkDropListData]=\"sortedComponents()\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.gap.px]=\"definition().layout.gap ?? 16\"\n (cdkDropListDropped)=\"onDrop($event)\"\n >\n @for (comp of sortedComponents(); track comp.id; let idx = $index) {\n <div\n cdkDrag\n [cdkDragData]=\"comp\"\n [cdkDragDisabled]=\"isAnyResizing()\"\n class=\"canvas-component-card\"\n [class.is-selected]=\"isSelected(comp.id)\"\n [class.is-resizing]=\"resizingCompId() === comp.id\"\n [class.is-field-highlighted]=\"isFieldHighlighted(comp)\"\n [class.is-narrow]=\"getSpan(comp) <= 4\"\n [class.is-compact]=\"getSpan(comp) <= 2\"\n [style.grid-column]=\"getGridColumn(comp)\"\n [style.grid-row]=\"getGridRow(comp)\"\n [style.width]=\"comp.layout?.width || 'auto'\"\n [style.height]=\"getComponentHeight(comp)\"\n [style.min-height]=\"getComponentMinHeight(comp)\"\n (click)=\"onSelect(comp.id, $event)\"\n >\n <!-- Card Header with Drag Handle & Actions -->\n <div class=\"card-header\">\n <div class=\"card-title-group\" cdkDragHandle title=\"Drag to reorder\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"comp-title\" [title]=\"comp.label || comp.key || comp.type\">\n {{ comp.label || comp.key || comp.type }}\n </span>\n </div>\n\n <div class=\"card-actions\">\n <!-- Static span pill & new row / start col pill when not hovered / not selected -->\n @if (comp.layout?.column; as col) {\n <span class=\"new-row-pill-static\" title=\"Starts at Column {{ col }}\">Col {{ col }}</span>\n } @else if (comp.layout?.newRow) {\n <span class=\"new-row-pill-static\" title=\"Starts on separate row\">\u21B3 Row</span>\n }\n <span\n class=\"span-pill-static\"\n title=\"Column span: {{ getSpan(comp) }} of {{ totalColumns() }} columns\"\n >\n {{ getSpan(comp) }}/{{ totalColumns() }}\n </span>\n\n <!-- Quick Action Stepper & Buttons (revealed on hover or selection) -->\n <div class=\"card-quick-controls\">\n <button\n type=\"button\"\n class=\"card-action-btn\"\n [class.btn-active-toggle]=\"comp.layout?.newRow\"\n (click)=\"toggleNewRow(comp, $event)\"\n title=\"{{ comp.layout?.newRow ? 'Starts on new row (Click to place inline)' : 'Start on separate row (Row Break)' }}\"\n >\n <rpt-icon name=\"corner-down-right\" [size]=\"11\" />\n </button>\n\n <div class=\"span-control-group\" title=\"Adjust Column Span\">\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) <= 1\"\n (click)=\"adjustSpan(comp, -1, $event)\"\n title=\"Shrink Column Span\"\n >\n <rpt-icon name=\"minus\" [size]=\"9\" />\n </button>\n <span class=\"span-badge\" [title]=\"'Column span: ' + getSpan(comp) + ' of ' + totalColumns()\">\n <span class=\"span-num\">{{ getSpan(comp) }}</span><span class=\"span-total\">/{{ totalColumns() }}</span>\n </span>\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) >= totalColumns()\"\n (click)=\"adjustSpan(comp, 1, $event)\"\n title=\"Expand Column Span\"\n >\n <rpt-icon name=\"plus\" [size]=\"9\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"card-action-btn\"\n (click)=\"onDuplicate(comp.id, $event)\"\n title=\"Duplicate component\"\n >\n <rpt-icon name=\"copy\" [size]=\"12\" />\n </button>\n <button\n type=\"button\"\n class=\"card-action-btn btn-delete\"\n (click)=\"onDelete(comp.id, $event)\"\n title=\"Remove component\"\n >\n <rpt-icon name=\"trash\" [size]=\"12\" />\n </button>\n </div>\n </div>\n </div>\n\n <!-- Card Body Visual Preview -->\n <div class=\"card-body\">\n\n @switch (comp.type) {\n @case ('input') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Input' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"text\"\n class=\"canvas-active-input\"\n [placeholder]=\"comp.properties?.['placeholder'] || 'Enter text...'\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">{{ comp.properties?.['placeholder'] || 'Enter text...' }}</div>\n }\n </div>\n }\n @case ('dropdown') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-dropdown\n [config]=\"comp\"\n [showStatus]=\"true\"\n [parentForm]=\"canvasForm()\"\n [control]=\"getCanvasControl(comp)\"\n (dropdownClick)=\"onControlInteract(comp)\"\n />\n </div>\n }\n @case ('date') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Date' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"date\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-select-box\">\n <span>YYYY-MM-DD</span>\n <rpt-icon name=\"calendar\" [size]=\"12\" />\n </div>\n }\n </div>\n }\n @case ('date-range') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-date-range\n [config]=\"comp\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('number') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Number' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"number\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">\n {{ comp.properties?.['prefix'] || '' }} 0.00 {{ comp.properties?.['suffix'] || '' }}\n </div>\n }\n </div>\n }\n @case ('checkbox') {\n <div class=\"mock-checkbox-field\" (click)=\"onControlInteract(comp, $event)\">\n @if (getCanvasControl(comp); as ctrl) {\n <label class=\"canvas-active-checkbox-lbl\">\n <input type=\"checkbox\" [formControl]=\"ctrl\" (focus)=\"onControlInteract(comp, $event)\" />\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n </label>\n } @else {\n <span class=\"mock-check-box\">\n <rpt-icon name=\"check\" [size]=\"10\" />\n </span>\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n }\n </div>\n }\n @case ('button') {\n <div class=\"mock-btn-wrapper\">\n <button\n type=\"button\"\n class=\"mock-btn\"\n [class]=\"'btn-' + (comp.properties?.['variant'] || 'primary')\"\n [class.mock-btn-full]=\"comp.properties?.['fullWidth'] === true || comp.layout?.width === '100%'\"\n [style.height]=\"getCustomBtnHeight(comp)\"\n [style.width]=\"getCustomBtnWidth(comp)\"\n (click)=\"onCanvasButtonClick(comp, $event)\"\n >\n @if (getCustomBtnIcon(comp); as btnIcon) {\n <rpt-icon [name]=\"btnIcon\" [size]=\"15\" />\n }\n <span>{{ comp.label || 'Button' }}</span>\n </button>\n </div>\n }\n @case ('kpi-card') {\n <div class=\"mock-kpi-field\">\n <div class=\"mock-kpi-header\">\n <span class=\"mock-label\">{{ comp.label || 'KPI Metric' }}</span>\n <rpt-icon name=\"kpi\" [size]=\"14\" />\n </div>\n <div class=\"mock-kpi-value\">{{ comp.properties?.['value'] || '$128,450' }}</div>\n <div class=\"mock-kpi-footer\">\n <span class=\"mock-kpi-trend\">+12.5%</span>\n <span class=\"mock-kpi-sub\">vs last period</span>\n </div>\n </div>\n }\n @case ('chart') {\n <div class=\"mock-chart-field\">\n <div class=\"mock-chart-header\">\n <span class=\"mock-label\">{{ comp.label || 'Quarterly Sales Revenue ($000)' }}</span>\n </div>\n <div class=\"mock-chart-bars\">\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 44%\"></div>\n <span class=\"mock-bar-lbl\">Q1 Jan-Mar</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 61%\"></div>\n <span class=\"mock-bar-lbl\">Q2 Apr-Jun</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 79%\"></div>\n <span class=\"mock-bar-lbl\">Q3 Jul-Sep</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 100%\"></div>\n <span class=\"mock-bar-lbl\">Q4 Oct-Dec</span>\n </div>\n </div>\n </div>\n }\n @default {\n <div class=\"mock-generic-box\">\n <span>{{ comp.type }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Resizing Handles (East, South, South-East) -->\n <div\n class=\"resize-handle handle-e\"\n (pointerdown)=\"startResize($event, comp, 'e')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize column width \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-s\"\n (pointerdown)=\"startResize($event, comp, 's')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize height \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-se\"\n (pointerdown)=\"startResize($event, comp, 'se')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize width and height \u2022 Double-click to reset\"\n ></div>\n\n <!-- Resizing Dimension Ghost / Badge -->\n @if (resizingCompId() === comp.id) {\n <div class=\"resize-dimension-tooltip\">\n {{ resizingTooltip(comp) }}\n </div>\n }\n\n <!-- Drag placeholder with matched grid column span -->\n <div\n *cdkDragPlaceholder\n class=\"canvas-drag-placeholder\"\n [style.grid-column]=\"getGridColumn(comp)\"\n ></div>\n\n <!-- Drag preview -->\n <div *cdkDragPreview class=\"canvas-drag-preview\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"preview-title\">{{ comp.label || comp.key || comp.type }}</span>\n <span class=\"preview-span\">{{ getSpan(comp) }}/{{ totalColumns() }}</span>\n </div>\n </div>\n }\n\n @if (components().length === 0) {\n <div class=\"canvas-empty-state\" role=\"region\" aria-label=\"Empty canvas starter options\">\n <div class=\"empty-hero-badge\">\n <rpt-icon name=\"design\" [size]=\"28\" />\n </div>\n <h3 class=\"empty-hero-title\">Start Designing Your Custom Report</h3>\n <p class=\"empty-hero-desc\">\n Drag controls from the left component palette, or jumpstart your design with pre-configured enterprise blueprints.\n </p>\n\n <div class=\"empty-hero-actions\">\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-primary\"\n (click)=\"applyBlueprint('blueprint-audit-register')\"\n title=\"Load complete Audit Register blueprint with parameters and result grid\"\n >\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span>Audit Register Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-secondary\"\n (click)=\"applyBlueprint('blueprint-kpi-summary')\"\n title=\"Load Executive KPI summary blueprint\"\n >\n <rpt-icon name=\"chart-bar\" [size]=\"15\" />\n <span>KPI Summary Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('date-range')\"\n title=\"Add a Date Range filter component\"\n >\n <rpt-icon name=\"calendar\" [size]=\"14\" />\n <span>+ Add Date Filter</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('button')\"\n title=\"Add an Execute Action button\"\n >\n <rpt-icon name=\"play\" [size]=\"14\" />\n <span>+ Add Run Button</span>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Live Result Grid Preview with Bways-Grid Features -->\n @if (definition().grid) {\n <div class=\"canvas-grid-box\">\n <div class=\"grid-preview-header\">\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span class=\"grid-title\">Bways Grid ({{ definition().grid?.columns?.length ?? 0 }} columns)</span>\n @if (isExecutingGrid()) {\n <span class=\"grid-exec-badge is-loading\">Loading data from database...</span>\n } @else if (gridExecError()) {\n <span class=\"grid-exec-badge is-error\">{{ gridExecError() }}</span>\n } @else if (canvasGridData().length > 0) {\n <span class=\"grid-exec-badge is-success\">{{ canvasGridData().length }} rows loaded</span>\n }\n </div>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <button\n type=\"button\"\n class=\"btn-canvas-run-grid\"\n (click)=\"executeCanvasReport($event)\"\n [disabled]=\"isExecutingGrid()\"\n title=\"Execute query and load data into Bways Grid\"\n >\n <rpt-icon name=\"play\" [size]=\"11\" />\n <span>{{ isExecutingGrid() ? 'Running...' : 'Run / Refresh Grid' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-canvas-edit-grid\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure columns and grid options\"\n >\n <rpt-icon name=\"settings\" [size]=\"11\" />\n <span>Configure</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-remove-grid\"\n (click)=\"removeGrid($event)\"\n title=\"Remove Result Grid from this report\"\n >\n <rpt-icon name=\"trash\" [size]=\"13\" />\n </button>\n </div>\n </div>\n\n @if (getGridSummaryText(); as summary) {\n <div class=\"grid-layout-status-strip\">\n <div class=\"grid-status-info\">\n <rpt-icon name=\"table\" [size]=\"12\" />\n <span>{{ summary }}</span>\n </div>\n <div class=\"grid-status-sync\" [class.is-pulsing]=\"layoutJustUpdated()\">\n <rpt-icon name=\"check\" [size]=\"11\" />\n <span>Layout auto-persisted</span>\n </div>\n </div>\n }\n\n <!-- Live Bways Grid bridge -->\n <div class=\"canvas-live-grid-container\" (click)=\"$event.stopPropagation()\" style=\"position: relative; min-height: 250px;\">\n @if (isExecutingGrid()) {\n <div class=\"canvas-grid-loading-overlay\">\n <span class=\"status-dot dot-pulse\" style=\"width: 14px; height: 14px; color: #2563eb; background: #2563eb; border-radius: 50%;\"></span>\n <span class=\"grid-loading-title\">Executing stored procedure on SQL Server...</span>\n <span class=\"grid-loading-sub\">Calculating outstanding balances and ledger amounts. Please wait...</span>\n </div>\n }\n <rpt-grid-bridge\n [gridDefinition]=\"definition().grid!\"\n [data]=\"canvasGridData()\"\n (gridStateChange)=\"onCanvasGridStateChange($event)\"\n (columnDefsChange)=\"onCanvasColumnDefsChange($event)\"\n />\n </div>\n </div>\n } @else {\n <div class=\"canvas-add-grid-banner\" (click)=\"addResultGrid($event)\">\n <div class=\"add-grid-icon\">\n <rpt-icon name=\"table\" [size]=\"20\" />\n </div>\n <div class=\"add-grid-text\">\n <span class=\"add-grid-title\">+ Add Result Data Grid</span>\n <span class=\"add-grid-sub\">Attach an interactive data table or UltraGrid to display report execution output</span>\n </div>\n <button type=\"button\" class=\"btn-banner-add\">Add Grid</button>\n </div>\n }\n </div>\n </div>\n </div>", styles: [":host{display:block;height:100%;background-color:#f1f5f9;font-family:var(--rpt-font-family, inherit);box-sizing:border-box}.canvas-wrapper{display:flex;flex-direction:column;height:100%}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;min-height:42px;height:42px;padding:0 24px;background:var(--rpt-color-surface, #ffffff);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);box-sizing:border-box;gap:12px;overflow-x:auto;scrollbar-width:none;font-family:var(--rpt-font-family, inherit);flex-shrink:0}.canvas-toolbar::-webkit-scrollbar{display:none}.canvas-info{display:flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #64748b);white-space:nowrap;line-height:1}.info-label{color:var(--rpt-color-text-muted, #64748b);font-weight:500;font-size:var(--rpt-font-size-sm, .75rem)}.info-value{font-weight:600;color:var(--rpt-color-text, #0f172a);font-size:var(--rpt-font-size-sm, .75rem)}.info-divider{color:var(--rpt-color-border, #cbd5e1);margin:0 2px}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-xs, .7rem);font-weight:600;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:2px 8px;border-radius:9999px;line-height:1}.canvas-actions{display:flex;align-items:center;gap:8px;white-space:nowrap}.canvas-action-btn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;letter-spacing:-.01em;color:var(--rpt-color-text-secondary, #334155);background:var(--rpt-color-surface, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);cursor:pointer;line-height:1;white-space:nowrap;box-shadow:0 1px 2px #0000000a;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-action-btn:hover{background:var(--rpt-color-surface-hover, #f8fafc);border-color:var(--rpt-color-border-hover, #94a3b8);color:var(--rpt-color-text, #0f172a);box-shadow:0 2px 4px #0000000f}.canvas-action-btn.btn-grid-configured{background:#eff6ff;border-color:#bfdbfe;color:#2563eb;font-weight:600}.canvas-action-btn.btn-grid-configured:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.canvas-action-btn.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a;font-weight:600}.canvas-action-btn.btn-grid-add:hover{background:#dcfce7;color:#15803d;border-color:#86efac}.canvas-action-btn:active{transform:translateY(1px)}.canvas-scroll-area{flex:1;overflow-y:auto;padding:16px}.canvas-artboard{width:100%;max-width:1400px;margin:0 auto;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-lg, 8px);box-shadow:0 4px 6px -1px #0000000d;min-height:480px;box-sizing:border-box}@media (max-width: 900px){.canvas-toolbar{min-height:36px;height:36px;padding:0 10px;gap:6px}.live-mode-badge{display:none}.canvas-info{font-size:.75rem;gap:5px}.canvas-action-btn{padding:0 8px;font-size:.725rem;height:28px;gap:4px}.canvas-scroll-area{padding:10px}.canvas-artboard{min-height:360px}}@media (max-width: 600px){.canvas-toolbar{padding:0 8px;gap:4px}.canvas-info .info-label,.canvas-action-btn span{display:none}.canvas-action-btn{padding:0 6px;min-width:28px;justify-content:center}}.canvas-report-header{margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.canvas-report-title{font-size:var(--rpt-font-size-xl, 1.5rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 6px}.canvas-report-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);margin:0}.canvas-grid{display:grid;width:100%;min-height:180px;align-items:start;border-radius:6px;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-component-card{container-type:inline-size;background:#fff;border:1.5px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:var(--rpt-box-shadow, 0 1px 2px rgba(0, 0, 0, .05));box-sizing:border-box;transition:all var(--rpt-transition-speed, .15s) ease;cursor:pointer;position:relative;overflow:visible;display:flex;flex-direction:column;min-height:104px;z-index:1}.canvas-component-card:hover{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 4px 6px -1px #2563eb1a;z-index:2}.canvas-component-card.is-selected{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40;z-index:10}.canvas-component-card:focus-within,.canvas-component-card:has(.rpt-combobox-menu),.canvas-component-card:has(.is-open){z-index:100}.canvas-component-card.is-resizing{-webkit-user-select:none;user-select:none;border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb59;z-index:30;transition:none!important}.resize-handle{position:absolute;z-index:20;touch-action:none;opacity:0;pointer-events:none;transition:opacity .15s ease}.canvas-component-card.is-selected .resize-handle{opacity:1;pointer-events:auto}.resize-handle.handle-e{top:0;right:0;width:6px;height:100%;cursor:ew-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-e:after{content:\"\";width:3px;height:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-e:hover:after,.canvas-component-card.is-selected .resize-handle.handle-e:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-s{bottom:0;left:0;height:6px;width:100%;cursor:ns-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-s:after{content:\"\";height:3px;width:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-s:hover:after,.canvas-component-card.is-selected .resize-handle.handle-s:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-se{bottom:0;right:0;width:12px;height:12px;cursor:nwse-resize;display:flex;align-items:flex-end;justify-content:flex-end;padding:2px}.resize-handle.handle-se:after{content:\"\";width:5px;height:5px;border-right:2px solid #cbd5e1;border-bottom:2px solid #cbd5e1;transition:border-color .15s ease}.resize-handle.handle-se:hover:after,.canvas-component-card.is-selected .resize-handle.handle-se:after{border-color:var(--rpt-color-primary, #2563eb)}.resize-dimension-tooltip{position:absolute;top:38px;right:8px;background:#0f172ae6;color:#fff;font-size:.7rem;font-weight:600;padding:3px 8px;border-radius:4px;white-space:nowrap;pointer-events:none;z-index:50;box-shadow:0 2px 4px #0003}.card-header{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:5px 8px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #e2e8f0);border-top-left-radius:var(--rpt-border-radius, 6px);border-top-right-radius:var(--rpt-border-radius, 6px);min-height:32px;box-sizing:border-box;overflow:hidden;position:relative}.canvas-component-card.is-selected .card-header{overflow:visible}.card-title-group{display:flex;align-items:center;gap:5px;cursor:grab;min-width:0;flex:1;overflow:hidden}.drag-handle-dots{color:var(--rpt-color-text-muted, #94a3b8);font-size:.85rem;letter-spacing:-2px;flex-shrink:0;-webkit-user-select:none;user-select:none}.comp-title{font-size:.75rem;font-weight:600;color:var(--rpt-color-text, #0f172a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.card-actions{display:flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.new-row-pill-static{font-size:.65rem;font-weight:600;color:#7c3aed;background:#f5f3ff;border:1px solid #ddd6fe;padding:1px 5px;border-radius:9999px;white-space:nowrap;line-height:1;flex-shrink:0}.span-pill-static{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:var(--rpt-color-surface, #f1f5f9);border:1px solid var(--rpt-color-border, #e2e8f0);padding:1px 6px;border-radius:9999px;line-height:1.2;white-space:nowrap;-webkit-user-select:none;user-select:none}.card-quick-controls{display:none;align-items:center;gap:3px;flex-shrink:0}.canvas-component-card:hover .span-pill-static,.canvas-component-card.is-selected .span-pill-static,.canvas-component-card:hover .new-row-pill-static,.canvas-component-card.is-selected .new-row-pill-static{display:none}.canvas-component-card:hover .card-quick-controls,.canvas-component-card.is-selected .card-quick-controls{display:inline-flex}.canvas-component-card.is-narrow .card-header{padding:4px 6px;gap:3px}.canvas-component-card.is-narrow:hover .comp-title,.canvas-component-card.is-narrow.is-selected .comp-title,.canvas-component-card.is-narrow:hover .drag-handle-dots,.canvas-component-card.is-narrow.is-selected .drag-handle-dots{display:none}.canvas-component-card.is-narrow .card-quick-controls{gap:2px}.canvas-component-card.is-narrow .span-control-group{height:18px}.canvas-component-card.is-narrow .span-btn{width:14px;height:16px}.canvas-component-card.is-narrow .span-badge{font-size:.6rem;padding:0 2px}.canvas-component-card.is-narrow .span-total{display:none}.canvas-component-card.is-narrow .card-action-btn{width:18px;height:18px}@container (max-width: 250px){.card-header{padding:4px 6px;gap:3px}.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.span-total{display:none}.card-quick-controls{gap:2px}.card-action-btn{width:18px;height:18px}.span-control-group{height:18px}.span-btn{width:14px;height:16px}.span-badge{font-size:.6rem;padding:0 2px}}@container (max-width: 160px){.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}@media (max-width: 900px){.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.canvas-component-card .span-total{display:none}.canvas-component-card.is-selected .card-header{overflow:visible}.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}.span-control-group{display:inline-flex;align-items:center;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;height:20px;padding:0 1px;white-space:nowrap;flex-shrink:0}.span-btn{width:16px;height:18px;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:0;color:var(--rpt-color-text-muted, #64748b);cursor:pointer;border-radius:2px;transition:all .12s ease}.span-btn:hover:not(:disabled){background:var(--rpt-color-surface-hover, #f1f5f9);color:var(--rpt-color-primary, #2563eb)}.span-btn:disabled{opacity:.3;cursor:not-allowed}.span-badge{font-size:.65rem;font-weight:600;color:var(--rpt-color-text, #0f172a);padding:0 3px;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}.span-total{font-size:.6rem;color:var(--rpt-color-text-muted, #64748b);font-weight:500}.card-action-btn{width:20px;height:20px;border:none;background:transparent;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;padding:0;cursor:pointer;color:var(--rpt-color-text-muted, #64748b);transition:all .12s ease;flex-shrink:0}.card-action-btn:hover{background:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.card-action-btn.btn-active-toggle{background:#7c3aed;color:#fff;border-color:#7c3aed}.card-action-btn.btn-active-toggle:hover{background:#6d28d9;color:#fff}.btn-delete:hover{background:#fee2e2;color:#ef4444}.card-body{padding:8px 10px 14px;flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;max-width:100%;box-sizing:border-box;overflow:visible}.mock-input-field{display:flex;flex-direction:column;gap:4px;flex:1;height:100%;min-height:0}.mock-label{font-size:.7rem;font-weight:600;color:var(--rpt-color-text-muted, #475569);flex-shrink:0}.mock-input-box,.mock-select-box{border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:6px;padding:6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #94a3b8);background:#fff;flex:1;min-height:38px;height:100%;display:flex;align-items:center;justify-content:space-between;box-sizing:border-box}.mock-checkbox-field{display:flex;align-items:center;gap:6px;flex:1;height:100%;min-height:0;padding-top:14px}.mock-check-box{width:18px;height:18px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:.65rem;color:var(--rpt-color-primary, #2563eb);flex-shrink:0}.mock-btn-wrapper{display:flex;flex:1;height:100%;min-height:38px;align-items:center;justify-content:flex-start;width:100%;min-width:0;box-sizing:border-box}.mock-btn{border-radius:var(--rpt-border-radius, 6px);padding:0 16px;height:36px;font-size:var(--rpt-font-size-base, .875rem);font-weight:500;border:1px solid transparent;cursor:pointer;width:auto;max-width:100%;display:inline-flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:all .15s ease}.mock-btn.mock-btn-full{width:100%}.canvas-component-card.is-narrow .mock-btn{padding:0 6px;font-size:.775rem;width:100%;height:34px}.mock-kpi-field{display:flex;flex-direction:column;justify-content:space-between;flex:1;height:100%;min-height:0}.mock-kpi-header{display:flex;align-items:center;justify-content:space-between}.mock-kpi-value{font-size:1.25rem;font-weight:700;color:var(--rpt-color-text, #0f172a);margin:2px 0}.mock-kpi-footer{display:flex;align-items:center;gap:6px;font-size:.65rem}.mock-kpi-trend{color:#16a34a;font-weight:600}.mock-kpi-sub{color:#64748b}.mock-chart-field{display:flex;flex-direction:column;flex:1;height:100%;min-height:140px}.mock-chart-bars{display:flex;align-items:flex-end;justify-content:space-around;gap:16px;flex:1;min-height:100px;padding-top:12px;box-sizing:border-box}.mock-chart-col{flex:1;display:flex;flex-direction:column;align-items:center;height:100%;min-width:60px;max-width:140px}.mock-chart-bar{width:38px;max-width:44px;margin:0 auto;background:var(--rpt-color-primary, #2563eb);border-radius:6px 6px 0 0;opacity:.85;min-height:10px;transition:height .2s ease}.mock-bar-lbl{font-size:.6875rem;color:#64748b;margin-top:6px;text-align:center;white-space:normal;line-height:1.2}.btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff}.btn-secondary{background:#f1f5f9;color:#0f172a;border:1px solid #cbd5e1}.btn-outline{background:transparent;color:#2563eb;border:1px solid #2563eb}.btn-danger{background:#ef4444;color:#fff}.mock-generic-box{border:1px dashed #cbd5e1;border-radius:4px;padding:8px;font-size:.75rem;text-align:center;color:#64748b}.canvas-drag-placeholder{background:#2563eb0f;border:2px dashed var(--rpt-color-primary, #2563eb);border-radius:6px;min-height:80px;box-sizing:border-box;transition:transform .15s ease}.canvas-drag-preview,::ng-deep .canvas-drag-preview{background:#fff;border:2px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:8px 14px;display:inline-flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif)!important;font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a);box-shadow:0 12px 24px -4px #00000040;z-index:10000}.preview-title,::ng-deep .preview-title{font-family:inherit!important;max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-span,::ng-deep .preview-span{font-family:inherit!important;font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px}.canvas-empty-state{grid-column:1 / -1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:56px 28px;border:2px dashed var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-surface, #ffffff);text-align:center;box-shadow:var(--rpt-box-shadow-xs, 0 1px 2px 0 rgba(0, 0, 0, .04));transition:border-color var(--rpt-transition-speed, .15s) ease}.canvas-empty-state:hover{border-color:var(--rpt-color-primary, #2563eb)}.empty-hero-badge{width:56px;height:56px;border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-primary-light, #eff6ff);color:var(--rpt-color-primary, #2563eb);display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 2px 8px #2563eb1f}.empty-hero-title{font-size:var(--rpt-font-size-lg, 1.125rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 8px;letter-spacing:-.01em}.empty-hero-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);max-width:520px;line-height:1.5;margin:0 0 24px}.empty-hero-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px}.empty-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 16px;font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;border-radius:var(--rpt-border-radius, 6px);cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease;font-family:inherit}.empty-btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff;border:1px solid var(--rpt-color-primary, #2563eb);box-shadow:0 1px 3px #2563eb33}.empty-btn-primary:hover{background:var(--rpt-color-primary-hover, #1d4ed8);border-color:var(--rpt-color-primary-hover, #1d4ed8);transform:translateY(-1px)}.empty-btn-secondary{background:#f8fafc;color:#334155;border:1px solid var(--rpt-color-border, #cbd5e1)}.empty-btn-secondary:hover{background:#f1f5f9;color:#0f172a;border-color:#94a3b8;transform:translateY(-1px)}.empty-btn-outline{background:#fff;color:var(--rpt-color-primary, #2563eb);border:1px solid #bfdbfe}.empty-btn-outline:hover{background:#eff6ff;border-color:var(--rpt-color-primary, #2563eb);transform:translateY(-1px)}.canvas-active-input{width:100%;height:32px;padding:4px 8px;font-size:.8125rem;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;outline:none;box-sizing:border-box;background:#fff;color:#0f172a;transition:border-color .15s ease}.canvas-active-input:focus{border-color:var(--rpt-color-primary, #2563eb)}.canvas-active-checkbox-lbl{display:inline-flex;align-items:center;gap:6px;cursor:pointer}.canvas-live-control-wrapper{width:100%;max-width:100%;min-width:0;position:relative;z-index:1;box-sizing:border-box}.canvas-grid-box{margin-top:24px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:8px;background:#fff;box-shadow:0 1px 3px #0000000d;overflow:hidden}.grid-preview-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a)}.grid-title{font-weight:700}.grid-exec-badge{font-size:.6875rem;font-weight:600;padding:2px 8px;border-radius:10px}.grid-exec-badge.is-loading{background:#eff6ff;color:#2563eb}.grid-exec-badge.is-error{background:#fee2e2;color:#ef4444}.grid-exec-badge.is-success{background:#ecfdf5;color:#059669}.btn-canvas-run-grid{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:.72rem;font-weight:600;color:#fff;background:var(--rpt-color-primary, #2563eb);border:none;border-radius:4px;cursor:pointer;transition:background .15s ease}.btn-canvas-run-grid:hover:not(:disabled){background:#1d4ed8}.btn-canvas-run-grid:disabled{opacity:.6;cursor:not-allowed}.btn-canvas-edit-grid{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;font-size:.72rem;font-weight:500;color:#334155;background:#fff;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-canvas-edit-grid:hover{background:#f1f5f9}.canvas-live-grid-container{width:100%;min-height:480px;background:#fff}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-size:.6875rem;font-weight:700;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:1px 8px;border-radius:9999px}.canvas-component-card.is-field-highlighted{border-color:#f59e0b!important;box-shadow:0 0 0 3px #f59e0b59!important;animation:rpt-pulse-border 1s ease-in-out infinite alternate}@keyframes rpt-pulse-border{0%{box-shadow:0 0 0 2px #f59e0b40}to{box-shadow:0 0 0 5px #f59e0b80}}.grid-layout-status-strip{display:flex;align-items:center;justify-content:space-between;padding:6px 16px;background:#f1f5f9;border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.6875rem;color:#475569}.grid-status-info{display:inline-flex;align-items:center;gap:6px;font-weight:600}.grid-status-sync{display:inline-flex;align-items:center;gap:4px;color:#059669;font-weight:600;transition:transform .2s ease}.grid-status-sync.is-pulsing{transform:scale(1.08);color:#047857}.canvas-actions{display:flex;align-items:center;gap:8px}.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.btn-grid-add:hover{background:#dcfce7;border-color:#86efac;color:#15803d}.btn-remove-grid{display:inline-flex;align-items:center;justify-content:center;padding:4px;border:none;background:transparent;color:#94a3b8;border-radius:4px;cursor:pointer;transition:all .15s ease}.btn-remove-grid:hover{background:#fee2e2;color:#ef4444}.canvas-add-grid-banner{margin-top:24px;border:2px dashed #cbd5e1;border-radius:8px;background:#fff;padding:16px 20px;display:flex;align-items:center;gap:16px;cursor:pointer;transition:all .15s ease}.canvas-add-grid-banner:hover{border-color:#2563eb;background:#f8fafc;box-shadow:0 2px 8px #2563eb14}.add-grid-icon{width:40px;height:40px;border-radius:8px;background:#eff6ff;color:#2563eb;display:flex;align-items:center;justify-content:center;flex-shrink:0}.add-grid-text{display:flex;flex-direction:column;gap:2px;flex:1}.add-grid-title{font-size:.875rem;font-weight:600;color:#0f172a}.add-grid-sub{font-size:.75rem;color:#64748b}.btn-banner-add{padding:6px 14px;font-size:.75rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:6px;cursor:pointer;white-space:nowrap;transition:all .15s ease}.canvas-add-grid-banner:hover .btn-banner-add{background:#2563eb;color:#fff;border-color:#2563eb}.canvas-grid-loading-overlay{position:absolute;inset:0;background:#ffffffe6;backdrop-filter:blur(2px);z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;font-family:inherit;border-radius:6px}.grid-loading-title{font-weight:600;font-size:.95rem;color:#1e293b}.grid-loading-sub{font-size:.8rem;color:#64748b}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,.canvas-active-input::-webkit-inner-spin-button,.canvas-active-input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number],.canvas-active-input{-moz-appearance:textfield;appearance:textfield}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i1.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i1.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: RptIconComponent, selector: "rpt-icon", inputs: ["name", "size", "color", "strokeWidth"] }, { kind: "component", type: RptDropdownComponent, selector: "rpt-dropdown", inputs: ["config", "control", "parentForm", "showStatus"], outputs: ["dropdownClick"] }, { kind: "component", type: RptDateRangeComponent, selector: "rpt-date-range", inputs: ["config", "control"] }, { kind: "component", type: ReportGridBridgeComponent, selector: "rpt-grid-bridge", inputs: ["gridDefinition", "data"], outputs: ["gridStateChange", "columnDefsChange", "rowClick", "selectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
491
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: DesignCanvasComponent, isStandalone: true, selector: "rpt-design-canvas", host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: " <div class=\"canvas-wrapper\" (click)=\"onCanvasBackgroundClick($event)\">\n <!-- Canvas Status / Quick Controls -->\n <div class=\"canvas-toolbar\">\n <div class=\"canvas-info\">\n <span class=\"info-label\">Grid Layout:</span>\n <span class=\"info-value\">{{ totalColumns() }} Columns</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"info-label\">Components:</span>\n <span class=\"info-value\">{{ components().length }}</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"live-mode-badge\" title=\"Interactive canvas: Values typed here run live queries and test dropdowns.\">\n \u26A1 Live Interactive Mode\n </span>\n </div>\n\n <div class=\"canvas-actions\">\n @if (!definition().grid) {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-add\"\n (click)=\"addResultGrid($event)\"\n title=\"Add a Result Grid to this report\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>+ Add Grid</span>\n </button>\n } @else {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-configured\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure Result Data Grid\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>Grid ({{ definition().grid?.columns?.length ?? 0 }})</span>\n </button>\n }\n\n <button\n type=\"button\"\n class=\"canvas-action-btn\"\n (click)=\"selectReportSettings($event)\"\n title=\"Configure Page Layout & Grid Settings\"\n >\n <rpt-icon name=\"settings\" [size]=\"14\" />\n <span>Report Settings</span>\n </button>\n </div>\n </div>\n\n <!-- Canvas Drop Area -->\n <div class=\"canvas-scroll-area\">\n <div\n class=\"canvas-artboard\"\n [style.padding.px]=\"definition().layout.padding ?? 24\"\n >\n <!-- Report Header Preview -->\n <div class=\"canvas-report-header\">\n <h2 class=\"canvas-report-title\">{{ definition().name || 'Untitled Report' }}</h2>\n @if (definition().description) {\n <p class=\"canvas-report-desc\">{{ definition().description }}</p>\n }\n </div>\n\n <!-- Component Drop List Grid with 2D mixed orientation and data binding -->\n <div\n cdkDropList\n id=\"designer-canvas-drop-list\"\n class=\"canvas-grid\"\n cdkDropListOrientation=\"mixed\"\n [cdkDropListData]=\"sortedComponents()\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.gap.px]=\"definition().layout.gap ?? 16\"\n (cdkDropListDropped)=\"onDrop($event)\"\n >\n @for (comp of sortedComponents(); track comp.id; let idx = $index) {\n <div\n cdkDrag\n [cdkDragData]=\"comp\"\n [cdkDragDisabled]=\"isAnyResizing()\"\n class=\"canvas-component-card\"\n [class.is-selected]=\"isSelected(comp.id)\"\n [class.is-resizing]=\"resizingCompId() === comp.id\"\n [class.is-field-highlighted]=\"isFieldHighlighted(comp)\"\n [class.is-narrow]=\"getSpan(comp) <= 4\"\n [class.is-compact]=\"getSpan(comp) <= 2\"\n [style.grid-column]=\"getGridColumn(comp)\"\n [style.grid-row]=\"getGridRow(comp)\"\n [style.width]=\"comp.layout?.width || 'auto'\"\n [style.height]=\"getComponentHeight(comp)\"\n [style.min-height]=\"getComponentMinHeight(comp)\"\n (click)=\"onSelect(comp.id, $event)\"\n >\n <!-- Card Header with Drag Handle & Actions -->\n <div class=\"card-header\">\n <div class=\"card-title-group\" cdkDragHandle title=\"Drag to reorder\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"comp-title\" [title]=\"comp.label || comp.key || comp.type\">\n {{ comp.label || comp.key || comp.type }}\n </span>\n </div>\n\n <div class=\"card-actions\">\n <!-- Static span pill & new row / start col pill when not hovered / not selected -->\n @if (comp.layout?.column; as col) {\n <span class=\"new-row-pill-static\" title=\"Starts at Column {{ col }}\">Col {{ col }}</span>\n } @else if (comp.layout?.newRow) {\n <span class=\"new-row-pill-static\" title=\"Starts on separate row\">\u21B3 Row</span>\n }\n <span\n class=\"span-pill-static\"\n title=\"Column span: {{ getSpan(comp) }} of {{ totalColumns() }} columns\"\n >\n {{ getSpan(comp) }}/{{ totalColumns() }}\n </span>\n\n <!-- Quick Action Stepper & Buttons (revealed on hover or selection) -->\n <div class=\"card-quick-controls\">\n <button\n type=\"button\"\n class=\"card-action-btn\"\n [class.btn-active-toggle]=\"comp.layout?.newRow\"\n (click)=\"toggleNewRow(comp, $event)\"\n title=\"{{ comp.layout?.newRow ? 'Starts on new row (Click to place inline)' : 'Start on separate row (Row Break)' }}\"\n >\n <rpt-icon name=\"corner-down-right\" [size]=\"11\" />\n </button>\n\n <div class=\"span-control-group\" title=\"Adjust Column Span\">\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) <= 1\"\n (click)=\"adjustSpan(comp, -1, $event)\"\n title=\"Shrink Column Span\"\n >\n <rpt-icon name=\"minus\" [size]=\"9\" />\n </button>\n <span class=\"span-badge\" [title]=\"'Column span: ' + getSpan(comp) + ' of ' + totalColumns()\">\n <span class=\"span-num\">{{ getSpan(comp) }}</span><span class=\"span-total\">/{{ totalColumns() }}</span>\n </span>\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) >= totalColumns()\"\n (click)=\"adjustSpan(comp, 1, $event)\"\n title=\"Expand Column Span\"\n >\n <rpt-icon name=\"plus\" [size]=\"9\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"card-action-btn\"\n (click)=\"onDuplicate(comp.id, $event)\"\n title=\"Duplicate component\"\n >\n <rpt-icon name=\"copy\" [size]=\"12\" />\n </button>\n <button\n type=\"button\"\n class=\"card-action-btn btn-delete\"\n (click)=\"onDelete(comp.id, $event)\"\n title=\"Remove component\"\n >\n <rpt-icon name=\"trash\" [size]=\"12\" />\n </button>\n </div>\n </div>\n </div>\n\n <!-- Card Body Visual Preview -->\n <div class=\"card-body\">\n\n @switch (comp.type) {\n @case ('input') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Input' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"text\"\n class=\"canvas-active-input\"\n [placeholder]=\"comp.properties?.['placeholder'] || 'Enter text...'\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">{{ comp.properties?.['placeholder'] || 'Enter text...' }}</div>\n }\n </div>\n }\n @case ('dropdown') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-dropdown\n [config]=\"comp\"\n [showStatus]=\"true\"\n [parentForm]=\"canvasForm()\"\n [control]=\"getCanvasControl(comp)\"\n (dropdownClick)=\"onControlInteract(comp)\"\n />\n </div>\n }\n @case ('date') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Date' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"date\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-select-box\">\n <span>YYYY-MM-DD</span>\n <rpt-icon name=\"calendar\" [size]=\"12\" />\n </div>\n }\n </div>\n }\n @case ('date-range') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-date-range\n [config]=\"comp\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('number') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Number' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"number\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">\n {{ comp.properties?.['prefix'] || '' }} 0.00 {{ comp.properties?.['suffix'] || '' }}\n </div>\n }\n </div>\n }\n @case ('checkbox') {\n <div class=\"mock-checkbox-field\" (click)=\"onControlInteract(comp, $event)\">\n @if (getCanvasControl(comp); as ctrl) {\n <label class=\"canvas-active-checkbox-lbl\">\n <input type=\"checkbox\" [formControl]=\"ctrl\" (focus)=\"onControlInteract(comp, $event)\" />\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n </label>\n } @else {\n <span class=\"mock-check-box\">\n <rpt-icon name=\"check\" [size]=\"10\" />\n </span>\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n }\n </div>\n }\n @case ('radio') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-radio\n [config]=\"comp\"\n [control]=\"getCanvasControl(comp)\"\n [parentForm]=\"canvasForm()\"\n />\n </div>\n }\n @case ('button') {\n <div class=\"mock-btn-wrapper\">\n <button\n type=\"button\"\n class=\"mock-btn\"\n [class]=\"'btn-' + (comp.properties?.['variant'] || 'primary')\"\n [class.mock-btn-full]=\"comp.properties?.['fullWidth'] === true || comp.layout?.width === '100%'\"\n [style.height]=\"getCustomBtnHeight(comp)\"\n [style.width]=\"getCustomBtnWidth(comp)\"\n (click)=\"onCanvasButtonClick(comp, $event)\"\n >\n @if (getCustomBtnIcon(comp); as btnIcon) {\n <rpt-icon [name]=\"btnIcon\" [size]=\"15\" />\n }\n <span>{{ comp.label || 'Button' }}</span>\n </button>\n </div>\n }\n @case ('kpi-card') {\n <div class=\"mock-kpi-field\">\n <div class=\"mock-kpi-header\">\n <span class=\"mock-label\">{{ comp.label || 'KPI Metric' }}</span>\n <rpt-icon name=\"kpi\" [size]=\"14\" />\n </div>\n <div class=\"mock-kpi-value\">{{ comp.properties?.['value'] || '$128,450' }}</div>\n <div class=\"mock-kpi-footer\">\n <span class=\"mock-kpi-trend\">+12.5%</span>\n <span class=\"mock-kpi-sub\">vs last period</span>\n </div>\n </div>\n }\n @case ('chart') {\n <div class=\"mock-chart-field\">\n <div class=\"mock-chart-header\">\n <span class=\"mock-label\">{{ comp.label || 'Quarterly Sales Revenue ($000)' }}</span>\n </div>\n <div class=\"mock-chart-bars\">\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 44%\"></div>\n <span class=\"mock-bar-lbl\">Q1 Jan-Mar</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 61%\"></div>\n <span class=\"mock-bar-lbl\">Q2 Apr-Jun</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 79%\"></div>\n <span class=\"mock-bar-lbl\">Q3 Jul-Sep</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 100%\"></div>\n <span class=\"mock-bar-lbl\">Q4 Oct-Dec</span>\n </div>\n </div>\n </div>\n }\n @default {\n <div class=\"mock-generic-box\">\n <span>{{ comp.type }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Resizing Handles (East, South, South-East) -->\n <div\n class=\"resize-handle handle-e\"\n (pointerdown)=\"startResize($event, comp, 'e')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize column width \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-s\"\n (pointerdown)=\"startResize($event, comp, 's')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize height \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-se\"\n (pointerdown)=\"startResize($event, comp, 'se')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize width and height \u2022 Double-click to reset\"\n ></div>\n\n <!-- Resizing Dimension Ghost / Badge -->\n @if (resizingCompId() === comp.id) {\n <div class=\"resize-dimension-tooltip\">\n {{ resizingTooltip(comp) }}\n </div>\n }\n\n <!-- Drag placeholder with matched grid column span -->\n <div\n *cdkDragPlaceholder\n class=\"canvas-drag-placeholder\"\n [style.grid-column]=\"getGridColumn(comp)\"\n ></div>\n\n <!-- Drag preview -->\n <div *cdkDragPreview class=\"canvas-drag-preview\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"preview-title\">{{ comp.label || comp.key || comp.type }}</span>\n <span class=\"preview-span\">{{ getSpan(comp) }}/{{ totalColumns() }}</span>\n </div>\n </div>\n }\n\n @if (components().length === 0) {\n <div class=\"canvas-empty-state\" role=\"region\" aria-label=\"Empty canvas starter options\">\n <div class=\"empty-hero-badge\">\n <rpt-icon name=\"design\" [size]=\"28\" />\n </div>\n <h3 class=\"empty-hero-title\">Start Designing Your Custom Report</h3>\n <p class=\"empty-hero-desc\">\n Drag controls from the left component palette, or jumpstart your design with pre-configured enterprise blueprints.\n </p>\n\n <div class=\"empty-hero-actions\">\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-primary\"\n (click)=\"applyBlueprint('blueprint-audit-register')\"\n title=\"Load complete Audit Register blueprint with parameters and result grid\"\n >\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span>Audit Register Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-secondary\"\n (click)=\"applyBlueprint('blueprint-kpi-summary')\"\n title=\"Load Executive KPI summary blueprint\"\n >\n <rpt-icon name=\"chart-bar\" [size]=\"15\" />\n <span>KPI Summary Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('date-range')\"\n title=\"Add a Date Range filter component\"\n >\n <rpt-icon name=\"calendar\" [size]=\"14\" />\n <span>+ Add Date Filter</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('button')\"\n title=\"Add an Execute Action button\"\n >\n <rpt-icon name=\"play\" [size]=\"14\" />\n <span>+ Add Run Button</span>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Live Result Grid Preview with Bways-Grid Features -->\n @if (definition().grid) {\n <div class=\"canvas-grid-box\">\n <div class=\"grid-preview-header\">\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span class=\"grid-title\">Bways Grid ({{ definition().grid?.columns?.length ?? 0 }} columns)</span>\n @if (isExecutingGrid()) {\n <span class=\"grid-exec-badge is-loading\">Loading data from database...</span>\n } @else if (gridExecError()) {\n <span class=\"grid-exec-badge is-error\">{{ gridExecError() }}</span>\n } @else if (canvasGridData().length > 0) {\n <span class=\"grid-exec-badge is-success\">{{ canvasGridData().length }} rows loaded</span>\n }\n </div>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <button\n type=\"button\"\n class=\"btn-canvas-run-grid\"\n (click)=\"executeCanvasReport($event)\"\n [disabled]=\"isExecutingGrid()\"\n title=\"Execute query and load data into Bways Grid\"\n >\n <rpt-icon name=\"play\" [size]=\"11\" />\n <span>{{ isExecutingGrid() ? 'Running...' : 'Run / Refresh Grid' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-canvas-edit-grid\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure columns and grid options\"\n >\n <rpt-icon name=\"settings\" [size]=\"11\" />\n <span>Configure</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-remove-grid\"\n (click)=\"removeGrid($event)\"\n title=\"Remove Result Grid from this report\"\n >\n <rpt-icon name=\"trash\" [size]=\"13\" />\n </button>\n </div>\n </div>\n\n @if (getGridSummaryText(); as summary) {\n <div class=\"grid-layout-status-strip\">\n <div class=\"grid-status-info\">\n <rpt-icon name=\"table\" [size]=\"12\" />\n <span>{{ summary }}</span>\n </div>\n <div class=\"grid-status-sync\" [class.is-pulsing]=\"layoutJustUpdated()\">\n <rpt-icon name=\"check\" [size]=\"11\" />\n <span>Layout auto-persisted</span>\n </div>\n </div>\n }\n\n <!-- Live Bways Grid bridge -->\n <div class=\"canvas-live-grid-container\" (click)=\"$event.stopPropagation()\" style=\"position: relative; min-height: 250px;\">\n @if (isExecutingGrid()) {\n <div class=\"canvas-grid-loading-overlay\">\n <span class=\"status-dot dot-pulse\" style=\"width: 14px; height: 14px; color: #2563eb; background: #2563eb; border-radius: 50%;\"></span>\n <span class=\"grid-loading-title\">Executing stored procedure on SQL Server...</span>\n <span class=\"grid-loading-sub\">Calculating outstanding balances and ledger amounts. Please wait...</span>\n </div>\n }\n <rpt-grid-bridge\n [gridDefinition]=\"definition().grid!\"\n [data]=\"canvasGridData()\"\n (gridStateChange)=\"onCanvasGridStateChange($event)\"\n (columnDefsChange)=\"onCanvasColumnDefsChange($event)\"\n />\n </div>\n </div>\n } @else {\n <div class=\"canvas-add-grid-banner\" (click)=\"addResultGrid($event)\">\n <div class=\"add-grid-icon\">\n <rpt-icon name=\"table\" [size]=\"20\" />\n </div>\n <div class=\"add-grid-text\">\n <span class=\"add-grid-title\">+ Add Result Data Grid</span>\n <span class=\"add-grid-sub\">Attach an interactive data table or UltraGrid to display report execution output</span>\n </div>\n <button type=\"button\" class=\"btn-banner-add\">Add Grid</button>\n </div>\n }\n </div>\n </div>\n </div>", styles: [":host{display:block;flex:1;min-height:0;min-width:0;height:100%;background-color:#f1f5f9;font-family:var(--rpt-font-family, inherit);box-sizing:border-box}.canvas-wrapper{min-height:0;display:flex;flex-direction:column;height:100%}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;min-height:42px;height:42px;padding:0 24px;background:var(--rpt-color-surface, #ffffff);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);box-sizing:border-box;gap:12px;overflow-x:auto;scrollbar-width:none;font-family:var(--rpt-font-family, inherit);flex-shrink:0}.canvas-toolbar::-webkit-scrollbar{display:none}.canvas-info{display:flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #64748b);white-space:nowrap;line-height:1}.info-label{color:var(--rpt-color-text-muted, #64748b);font-weight:500;font-size:var(--rpt-font-size-sm, .75rem)}.info-value{font-weight:600;color:var(--rpt-color-text, #0f172a);font-size:var(--rpt-font-size-sm, .75rem)}.info-divider{color:var(--rpt-color-border, #cbd5e1);margin:0 2px}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-xs, .7rem);font-weight:600;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:2px 8px;border-radius:9999px;line-height:1}.canvas-actions{display:flex;align-items:center;gap:8px;white-space:nowrap}.canvas-action-btn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;letter-spacing:-.01em;color:var(--rpt-color-text-secondary, #334155);background:var(--rpt-color-surface, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);cursor:pointer;line-height:1;white-space:nowrap;box-shadow:0 1px 2px #0000000a;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-action-btn:hover{background:var(--rpt-color-surface-hover, #f8fafc);border-color:var(--rpt-color-border-hover, #94a3b8);color:var(--rpt-color-text, #0f172a);box-shadow:0 2px 4px #0000000f}.canvas-action-btn.btn-grid-configured{background:#eff6ff;border-color:#bfdbfe;color:#2563eb;font-weight:600}.canvas-action-btn.btn-grid-configured:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.canvas-action-btn.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a;font-weight:600}.canvas-action-btn.btn-grid-add:hover{background:#dcfce7;color:#15803d;border-color:#86efac}.canvas-action-btn:active{transform:translateY(1px)}.canvas-scroll-area{flex:1;min-height:0;overflow-y:auto;padding:16px}.canvas-artboard{width:100%;max-width:1400px;margin:0 auto;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-lg, 8px);box-shadow:0 4px 6px -1px #0000000d;min-height:480px;box-sizing:border-box}@media (max-width: 900px){.canvas-toolbar{min-height:36px;height:36px;padding:0 10px;gap:6px}.live-mode-badge{display:none}.canvas-info{font-size:.75rem;gap:5px}.canvas-action-btn{padding:0 8px;font-size:.725rem;height:28px;gap:4px}.canvas-scroll-area{padding:10px}.canvas-artboard{min-height:360px}}@media (max-width: 600px){.canvas-toolbar{padding:0 8px;gap:4px}.canvas-info .info-label,.canvas-action-btn span{display:none}.canvas-action-btn{padding:0 6px;min-width:28px;justify-content:center}}.canvas-report-header{margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.canvas-report-title{font-size:var(--rpt-font-size-xl, 1.5rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 6px}.canvas-report-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);margin:0}.canvas-grid{display:grid;width:100%;min-height:180px;align-items:start;border-radius:6px;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-component-card{container-type:inline-size;background:#fff;border:1.5px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:var(--rpt-box-shadow, 0 1px 2px rgba(0, 0, 0, .05));box-sizing:border-box;transition:all var(--rpt-transition-speed, .15s) ease;cursor:pointer;position:relative;overflow:visible;display:flex;flex-direction:column;min-height:104px;z-index:1}.canvas-component-card:hover{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 4px 6px -1px #2563eb1a;z-index:2}.canvas-component-card.is-selected{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40;z-index:10}.canvas-component-card:focus-within,.canvas-component-card:has(.rpt-combobox-menu),.canvas-component-card:has(.is-open){z-index:100}.canvas-component-card.is-resizing{-webkit-user-select:none;user-select:none;border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb59;z-index:30;transition:none!important}.resize-handle{position:absolute;z-index:20;touch-action:none;opacity:0;pointer-events:none;transition:opacity .15s ease}.canvas-component-card.is-selected .resize-handle{opacity:1;pointer-events:auto}.resize-handle.handle-e{top:0;right:0;width:6px;height:100%;cursor:ew-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-e:after{content:\"\";width:3px;height:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-e:hover:after,.canvas-component-card.is-selected .resize-handle.handle-e:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-s{bottom:0;left:0;height:6px;width:100%;cursor:ns-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-s:after{content:\"\";height:3px;width:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-s:hover:after,.canvas-component-card.is-selected .resize-handle.handle-s:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-se{bottom:0;right:0;width:12px;height:12px;cursor:nwse-resize;display:flex;align-items:flex-end;justify-content:flex-end;padding:2px}.resize-handle.handle-se:after{content:\"\";width:5px;height:5px;border-right:2px solid #cbd5e1;border-bottom:2px solid #cbd5e1;transition:border-color .15s ease}.resize-handle.handle-se:hover:after,.canvas-component-card.is-selected .resize-handle.handle-se:after{border-color:var(--rpt-color-primary, #2563eb)}.resize-dimension-tooltip{position:absolute;top:38px;right:8px;background:#0f172ae6;color:#fff;font-size:.7rem;font-weight:600;padding:3px 8px;border-radius:4px;white-space:nowrap;pointer-events:none;z-index:50;box-shadow:0 2px 4px #0003}.card-header{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:5px 8px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #e2e8f0);border-top-left-radius:var(--rpt-border-radius, 6px);border-top-right-radius:var(--rpt-border-radius, 6px);min-height:32px;box-sizing:border-box;overflow:hidden;position:relative}.canvas-component-card.is-selected .card-header{overflow:visible}.card-title-group{display:flex;align-items:center;gap:5px;cursor:grab;min-width:0;flex:1;overflow:hidden}.drag-handle-dots{color:var(--rpt-color-text-muted, #94a3b8);font-size:.85rem;letter-spacing:-2px;flex-shrink:0;-webkit-user-select:none;user-select:none}.comp-title{font-size:.75rem;font-weight:600;color:var(--rpt-color-text, #0f172a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.card-actions{display:flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.new-row-pill-static{font-size:.65rem;font-weight:600;color:#7c3aed;background:#f5f3ff;border:1px solid #ddd6fe;padding:1px 5px;border-radius:9999px;white-space:nowrap;line-height:1;flex-shrink:0}.span-pill-static{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:var(--rpt-color-surface, #f1f5f9);border:1px solid var(--rpt-color-border, #e2e8f0);padding:1px 6px;border-radius:9999px;line-height:1.2;white-space:nowrap;-webkit-user-select:none;user-select:none}.card-quick-controls{display:none;align-items:center;gap:3px;flex-shrink:0}.canvas-component-card:hover .span-pill-static,.canvas-component-card.is-selected .span-pill-static,.canvas-component-card:hover .new-row-pill-static,.canvas-component-card.is-selected .new-row-pill-static{display:none}.canvas-component-card:hover .card-quick-controls,.canvas-component-card.is-selected .card-quick-controls{display:inline-flex}.canvas-component-card.is-narrow .card-header{padding:4px 6px;gap:3px}.canvas-component-card.is-narrow:hover .comp-title,.canvas-component-card.is-narrow.is-selected .comp-title,.canvas-component-card.is-narrow:hover .drag-handle-dots,.canvas-component-card.is-narrow.is-selected .drag-handle-dots{display:none}.canvas-component-card.is-narrow .card-quick-controls{gap:2px}.canvas-component-card.is-narrow .span-control-group{height:18px}.canvas-component-card.is-narrow .span-btn{width:14px;height:16px}.canvas-component-card.is-narrow .span-badge{font-size:.6rem;padding:0 2px}.canvas-component-card.is-narrow .span-total{display:none}.canvas-component-card.is-narrow .card-action-btn{width:18px;height:18px}@container (max-width: 250px){.card-header{padding:4px 6px;gap:3px}.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.span-total{display:none}.card-quick-controls{gap:2px}.card-action-btn{width:18px;height:18px}.span-control-group{height:18px}.span-btn{width:14px;height:16px}.span-badge{font-size:.6rem;padding:0 2px}}@container (max-width: 160px){.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}@media (max-width: 900px){.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.canvas-component-card .span-total{display:none}.canvas-component-card.is-selected .card-header{overflow:visible}.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}.span-control-group{display:inline-flex;align-items:center;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;height:20px;padding:0 1px;white-space:nowrap;flex-shrink:0}.span-btn{width:16px;height:18px;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:0;color:var(--rpt-color-text-muted, #64748b);cursor:pointer;border-radius:2px;transition:all .12s ease}.span-btn:hover:not(:disabled){background:var(--rpt-color-surface-hover, #f1f5f9);color:var(--rpt-color-primary, #2563eb)}.span-btn:disabled{opacity:.3;cursor:not-allowed}.span-badge{font-size:.65rem;font-weight:600;color:var(--rpt-color-text, #0f172a);padding:0 3px;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}.span-total{font-size:.6rem;color:var(--rpt-color-text-muted, #64748b);font-weight:500}.card-action-btn{width:20px;height:20px;border:none;background:transparent;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;padding:0;cursor:pointer;color:var(--rpt-color-text-muted, #64748b);transition:all .12s ease;flex-shrink:0}.card-action-btn:hover{background:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.card-action-btn.btn-active-toggle{background:#7c3aed;color:#fff;border-color:#7c3aed}.card-action-btn.btn-active-toggle:hover{background:#6d28d9;color:#fff}.btn-delete:hover{background:#fee2e2;color:#ef4444}.card-body{padding:8px 10px 14px;flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;max-width:100%;box-sizing:border-box;overflow:visible}.mock-input-field{display:flex;flex-direction:column;gap:4px;flex:1;height:100%;min-height:0}.mock-label{font-size:.7rem;font-weight:600;color:var(--rpt-color-text-muted, #475569);flex-shrink:0}.mock-input-box,.mock-select-box{border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:6px;padding:6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #94a3b8);background:#fff;flex:1;min-height:38px;height:100%;display:flex;align-items:center;justify-content:space-between;box-sizing:border-box}.mock-checkbox-field{display:flex;align-items:center;gap:6px;flex:1;height:100%;min-height:0;padding-top:14px}.mock-check-box{width:18px;height:18px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:.65rem;color:var(--rpt-color-primary, #2563eb);flex-shrink:0}.mock-btn-wrapper{display:flex;flex:1;height:100%;min-height:38px;align-items:center;justify-content:flex-start;width:100%;min-width:0;box-sizing:border-box}.mock-btn{border-radius:var(--rpt-border-radius, 6px);padding:0 16px;height:36px;font-size:var(--rpt-font-size-base, .875rem);font-weight:500;border:1px solid transparent;cursor:pointer;width:auto;max-width:100%;display:inline-flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:all .15s ease}.mock-btn.mock-btn-full{width:100%}.canvas-component-card.is-narrow .mock-btn{padding:0 6px;font-size:.775rem;width:100%;height:34px}.mock-kpi-field{display:flex;flex-direction:column;justify-content:space-between;flex:1;height:100%;min-height:0}.mock-kpi-header{display:flex;align-items:center;justify-content:space-between}.mock-kpi-value{font-size:1.25rem;font-weight:700;color:var(--rpt-color-text, #0f172a);margin:2px 0}.mock-kpi-footer{display:flex;align-items:center;gap:6px;font-size:.65rem}.mock-kpi-trend{color:#16a34a;font-weight:600}.mock-kpi-sub{color:#64748b}.mock-chart-field{display:flex;flex-direction:column;flex:1;height:100%;min-height:140px}.mock-chart-bars{display:flex;align-items:flex-end;justify-content:space-around;gap:16px;flex:1;min-height:100px;padding-top:12px;box-sizing:border-box}.mock-chart-col{flex:1;display:flex;flex-direction:column;align-items:center;height:100%;min-width:60px;max-width:140px}.mock-chart-bar{width:38px;max-width:44px;margin:0 auto;background:var(--rpt-color-primary, #2563eb);border-radius:6px 6px 0 0;opacity:.85;min-height:10px;transition:height .2s ease}.mock-bar-lbl{font-size:.6875rem;color:#64748b;margin-top:6px;text-align:center;white-space:normal;line-height:1.2}.btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff}.btn-secondary{background:#f1f5f9;color:#0f172a;border:1px solid #cbd5e1}.btn-outline{background:transparent;color:#2563eb;border:1px solid #2563eb}.btn-danger{background:#ef4444;color:#fff}.mock-generic-box{border:1px dashed #cbd5e1;border-radius:4px;padding:8px;font-size:.75rem;text-align:center;color:#64748b}.canvas-drag-placeholder{background:#2563eb0f;border:2px dashed var(--rpt-color-primary, #2563eb);border-radius:6px;min-height:80px;box-sizing:border-box;transition:transform .15s ease}.canvas-drag-preview,::ng-deep .canvas-drag-preview{background:#fff;border:2px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:8px 14px;display:inline-flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif)!important;font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a);box-shadow:0 12px 24px -4px #00000040;z-index:10000}.preview-title,::ng-deep .preview-title{font-family:inherit!important;max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-span,::ng-deep .preview-span{font-family:inherit!important;font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px}.canvas-empty-state{grid-column:1 / -1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:56px 28px;border:2px dashed var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-surface, #ffffff);text-align:center;box-shadow:var(--rpt-box-shadow-xs, 0 1px 2px 0 rgba(0, 0, 0, .04));transition:border-color var(--rpt-transition-speed, .15s) ease}.canvas-empty-state:hover{border-color:var(--rpt-color-primary, #2563eb)}.empty-hero-badge{width:56px;height:56px;border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-primary-light, #eff6ff);color:var(--rpt-color-primary, #2563eb);display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 2px 8px #2563eb1f}.empty-hero-title{font-size:var(--rpt-font-size-lg, 1.125rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 8px;letter-spacing:-.01em}.empty-hero-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);max-width:520px;line-height:1.5;margin:0 0 24px}.empty-hero-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px}.empty-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 16px;font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;border-radius:var(--rpt-border-radius, 6px);cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease;font-family:inherit}.empty-btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff;border:1px solid var(--rpt-color-primary, #2563eb);box-shadow:0 1px 3px #2563eb33}.empty-btn-primary:hover{background:var(--rpt-color-primary-hover, #1d4ed8);border-color:var(--rpt-color-primary-hover, #1d4ed8);transform:translateY(-1px)}.empty-btn-secondary{background:#f8fafc;color:#334155;border:1px solid var(--rpt-color-border, #cbd5e1)}.empty-btn-secondary:hover{background:#f1f5f9;color:#0f172a;border-color:#94a3b8;transform:translateY(-1px)}.empty-btn-outline{background:#fff;color:var(--rpt-color-primary, #2563eb);border:1px solid #bfdbfe}.empty-btn-outline:hover{background:#eff6ff;border-color:var(--rpt-color-primary, #2563eb);transform:translateY(-1px)}.canvas-active-input{width:100%;height:32px;padding:4px 8px;font-size:.8125rem;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;outline:none;box-sizing:border-box;background:#fff;color:#0f172a;transition:border-color .15s ease}.canvas-active-input:focus{border-color:var(--rpt-color-primary, #2563eb)}.canvas-active-checkbox-lbl{display:inline-flex;align-items:center;gap:6px;cursor:pointer}.canvas-live-control-wrapper{width:100%;max-width:100%;min-width:0;position:relative;z-index:1;box-sizing:border-box}.canvas-grid-box{margin-top:24px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:8px;background:#fff;box-shadow:0 1px 3px #0000000d;overflow:hidden}.grid-preview-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a)}.grid-title{font-weight:700}.grid-exec-badge{font-size:.6875rem;font-weight:600;padding:2px 8px;border-radius:10px}.grid-exec-badge.is-loading{background:#eff6ff;color:#2563eb}.grid-exec-badge.is-error{background:#fee2e2;color:#ef4444}.grid-exec-badge.is-success{background:#ecfdf5;color:#059669}.btn-canvas-run-grid{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:.72rem;font-weight:600;color:#fff;background:var(--rpt-color-primary, #2563eb);border:none;border-radius:4px;cursor:pointer;transition:background .15s ease}.btn-canvas-run-grid:hover:not(:disabled){background:#1d4ed8}.btn-canvas-run-grid:disabled{opacity:.6;cursor:not-allowed}.btn-canvas-edit-grid{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;font-size:.72rem;font-weight:500;color:#334155;background:#fff;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-canvas-edit-grid:hover{background:#f1f5f9}.canvas-live-grid-container{width:100%;min-height:480px;background:#fff}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-size:.6875rem;font-weight:700;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:1px 8px;border-radius:9999px}.canvas-component-card.is-field-highlighted{border-color:#f59e0b!important;box-shadow:0 0 0 3px #f59e0b59!important;animation:rpt-pulse-border 1s ease-in-out infinite alternate}@keyframes rpt-pulse-border{0%{box-shadow:0 0 0 2px #f59e0b40}to{box-shadow:0 0 0 5px #f59e0b80}}.grid-layout-status-strip{display:flex;align-items:center;justify-content:space-between;padding:6px 16px;background:#f1f5f9;border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.6875rem;color:#475569}.grid-status-info{display:inline-flex;align-items:center;gap:6px;font-weight:600}.grid-status-sync{display:inline-flex;align-items:center;gap:4px;color:#059669;font-weight:600;transition:transform .2s ease}.grid-status-sync.is-pulsing{transform:scale(1.08);color:#047857}.canvas-actions{display:flex;align-items:center;gap:8px}.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.btn-grid-add:hover{background:#dcfce7;border-color:#86efac;color:#15803d}.btn-remove-grid{display:inline-flex;align-items:center;justify-content:center;padding:4px;border:none;background:transparent;color:#94a3b8;border-radius:4px;cursor:pointer;transition:all .15s ease}.btn-remove-grid:hover{background:#fee2e2;color:#ef4444}.canvas-add-grid-banner{margin-top:24px;border:2px dashed #cbd5e1;border-radius:8px;background:#fff;padding:16px 20px;display:flex;align-items:center;gap:16px;cursor:pointer;transition:all .15s ease}.canvas-add-grid-banner:hover{border-color:#2563eb;background:#f8fafc;box-shadow:0 2px 8px #2563eb14}.add-grid-icon{width:40px;height:40px;border-radius:8px;background:#eff6ff;color:#2563eb;display:flex;align-items:center;justify-content:center;flex-shrink:0}.add-grid-text{display:flex;flex-direction:column;gap:2px;flex:1}.add-grid-title{font-size:.875rem;font-weight:600;color:#0f172a}.add-grid-sub{font-size:.75rem;color:#64748b}.btn-banner-add{padding:6px 14px;font-size:.75rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:6px;cursor:pointer;white-space:nowrap;transition:all .15s ease}.canvas-add-grid-banner:hover .btn-banner-add{background:#2563eb;color:#fff;border-color:#2563eb}.canvas-grid-loading-overlay{position:absolute;inset:0;background:#ffffffe6;backdrop-filter:blur(2px);z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;font-family:inherit;border-radius:6px}.grid-loading-title{font-weight:600;font-size:.95rem;color:#1e293b}.grid-loading-sub{font-size:.8rem;color:#64748b}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,.canvas-active-input::-webkit-inner-spin-button,.canvas-active-input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number],.canvas-active-input{-moz-appearance:textfield;appearance:textfield}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i1.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i1.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: RptIconComponent, selector: "rpt-icon", inputs: ["name", "size", "color", "strokeWidth"] }, { kind: "component", type: RptDropdownComponent, selector: "rpt-dropdown", inputs: ["config", "control", "parentForm", "showStatus"], outputs: ["dropdownClick"] }, { kind: "component", type: RptDateRangeComponent, selector: "rpt-date-range", inputs: ["config", "control"] }, { kind: "component", type: RptRadioComponent, selector: "rpt-radio", inputs: ["config", "control", "parentForm"] }, { kind: "component", type: ReportGridBridgeComponent, selector: "rpt-grid-bridge", inputs: ["gridDefinition", "data"], outputs: ["gridStateChange", "columnDefsChange", "rowClick", "selectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
455
492
  }
456
493
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DesignCanvasComponent, decorators: [{
457
494
  type: Component,
@@ -462,10 +499,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
462
499
  RptIconComponent,
463
500
  RptDropdownComponent,
464
501
  RptDateRangeComponent,
502
+ RptRadioComponent,
465
503
  ReportGridBridgeComponent,
466
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: " <div class=\"canvas-wrapper\" (click)=\"onCanvasBackgroundClick($event)\">\n <!-- Canvas Status / Quick Controls -->\n <div class=\"canvas-toolbar\">\n <div class=\"canvas-info\">\n <span class=\"info-label\">Grid Layout:</span>\n <span class=\"info-value\">{{ totalColumns() }} Columns</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"info-label\">Components:</span>\n <span class=\"info-value\">{{ components().length }}</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"live-mode-badge\" title=\"Interactive canvas: Values typed here run live queries and test dropdowns.\">\n \u26A1 Live Interactive Mode\n </span>\n </div>\n\n <div class=\"canvas-actions\">\n @if (!definition().grid) {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-add\"\n (click)=\"addResultGrid($event)\"\n title=\"Add a Result Grid to this report\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>+ Add Grid</span>\n </button>\n } @else {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-configured\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure Result Data Grid\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>Grid ({{ definition().grid?.columns?.length ?? 0 }})</span>\n </button>\n }\n\n <button\n type=\"button\"\n class=\"canvas-action-btn\"\n (click)=\"selectReportSettings($event)\"\n title=\"Configure Page Layout & Grid Settings\"\n >\n <rpt-icon name=\"settings\" [size]=\"14\" />\n <span>Report Settings</span>\n </button>\n </div>\n </div>\n\n <!-- Canvas Drop Area -->\n <div class=\"canvas-scroll-area\">\n <div\n class=\"canvas-artboard\"\n [style.padding.px]=\"definition().layout.padding ?? 24\"\n >\n <!-- Report Header Preview -->\n <div class=\"canvas-report-header\">\n <h2 class=\"canvas-report-title\">{{ definition().name || 'Untitled Report' }}</h2>\n @if (definition().description) {\n <p class=\"canvas-report-desc\">{{ definition().description }}</p>\n }\n </div>\n\n <!-- Component Drop List Grid with 2D mixed orientation and data binding -->\n <div\n cdkDropList\n id=\"designer-canvas-drop-list\"\n class=\"canvas-grid\"\n cdkDropListOrientation=\"mixed\"\n [cdkDropListData]=\"sortedComponents()\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.gap.px]=\"definition().layout.gap ?? 16\"\n (cdkDropListDropped)=\"onDrop($event)\"\n >\n @for (comp of sortedComponents(); track comp.id; let idx = $index) {\n <div\n cdkDrag\n [cdkDragData]=\"comp\"\n [cdkDragDisabled]=\"isAnyResizing()\"\n class=\"canvas-component-card\"\n [class.is-selected]=\"isSelected(comp.id)\"\n [class.is-resizing]=\"resizingCompId() === comp.id\"\n [class.is-field-highlighted]=\"isFieldHighlighted(comp)\"\n [class.is-narrow]=\"getSpan(comp) <= 4\"\n [class.is-compact]=\"getSpan(comp) <= 2\"\n [style.grid-column]=\"getGridColumn(comp)\"\n [style.grid-row]=\"getGridRow(comp)\"\n [style.width]=\"comp.layout?.width || 'auto'\"\n [style.height]=\"getComponentHeight(comp)\"\n [style.min-height]=\"getComponentMinHeight(comp)\"\n (click)=\"onSelect(comp.id, $event)\"\n >\n <!-- Card Header with Drag Handle & Actions -->\n <div class=\"card-header\">\n <div class=\"card-title-group\" cdkDragHandle title=\"Drag to reorder\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"comp-title\" [title]=\"comp.label || comp.key || comp.type\">\n {{ comp.label || comp.key || comp.type }}\n </span>\n </div>\n\n <div class=\"card-actions\">\n <!-- Static span pill & new row / start col pill when not hovered / not selected -->\n @if (comp.layout?.column; as col) {\n <span class=\"new-row-pill-static\" title=\"Starts at Column {{ col }}\">Col {{ col }}</span>\n } @else if (comp.layout?.newRow) {\n <span class=\"new-row-pill-static\" title=\"Starts on separate row\">\u21B3 Row</span>\n }\n <span\n class=\"span-pill-static\"\n title=\"Column span: {{ getSpan(comp) }} of {{ totalColumns() }} columns\"\n >\n {{ getSpan(comp) }}/{{ totalColumns() }}\n </span>\n\n <!-- Quick Action Stepper & Buttons (revealed on hover or selection) -->\n <div class=\"card-quick-controls\">\n <button\n type=\"button\"\n class=\"card-action-btn\"\n [class.btn-active-toggle]=\"comp.layout?.newRow\"\n (click)=\"toggleNewRow(comp, $event)\"\n title=\"{{ comp.layout?.newRow ? 'Starts on new row (Click to place inline)' : 'Start on separate row (Row Break)' }}\"\n >\n <rpt-icon name=\"corner-down-right\" [size]=\"11\" />\n </button>\n\n <div class=\"span-control-group\" title=\"Adjust Column Span\">\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) <= 1\"\n (click)=\"adjustSpan(comp, -1, $event)\"\n title=\"Shrink Column Span\"\n >\n <rpt-icon name=\"minus\" [size]=\"9\" />\n </button>\n <span class=\"span-badge\" [title]=\"'Column span: ' + getSpan(comp) + ' of ' + totalColumns()\">\n <span class=\"span-num\">{{ getSpan(comp) }}</span><span class=\"span-total\">/{{ totalColumns() }}</span>\n </span>\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) >= totalColumns()\"\n (click)=\"adjustSpan(comp, 1, $event)\"\n title=\"Expand Column Span\"\n >\n <rpt-icon name=\"plus\" [size]=\"9\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"card-action-btn\"\n (click)=\"onDuplicate(comp.id, $event)\"\n title=\"Duplicate component\"\n >\n <rpt-icon name=\"copy\" [size]=\"12\" />\n </button>\n <button\n type=\"button\"\n class=\"card-action-btn btn-delete\"\n (click)=\"onDelete(comp.id, $event)\"\n title=\"Remove component\"\n >\n <rpt-icon name=\"trash\" [size]=\"12\" />\n </button>\n </div>\n </div>\n </div>\n\n <!-- Card Body Visual Preview -->\n <div class=\"card-body\">\n\n @switch (comp.type) {\n @case ('input') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Input' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"text\"\n class=\"canvas-active-input\"\n [placeholder]=\"comp.properties?.['placeholder'] || 'Enter text...'\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">{{ comp.properties?.['placeholder'] || 'Enter text...' }}</div>\n }\n </div>\n }\n @case ('dropdown') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-dropdown\n [config]=\"comp\"\n [showStatus]=\"true\"\n [parentForm]=\"canvasForm()\"\n [control]=\"getCanvasControl(comp)\"\n (dropdownClick)=\"onControlInteract(comp)\"\n />\n </div>\n }\n @case ('date') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Date' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"date\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-select-box\">\n <span>YYYY-MM-DD</span>\n <rpt-icon name=\"calendar\" [size]=\"12\" />\n </div>\n }\n </div>\n }\n @case ('date-range') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-date-range\n [config]=\"comp\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('number') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Number' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"number\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">\n {{ comp.properties?.['prefix'] || '' }} 0.00 {{ comp.properties?.['suffix'] || '' }}\n </div>\n }\n </div>\n }\n @case ('checkbox') {\n <div class=\"mock-checkbox-field\" (click)=\"onControlInteract(comp, $event)\">\n @if (getCanvasControl(comp); as ctrl) {\n <label class=\"canvas-active-checkbox-lbl\">\n <input type=\"checkbox\" [formControl]=\"ctrl\" (focus)=\"onControlInteract(comp, $event)\" />\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n </label>\n } @else {\n <span class=\"mock-check-box\">\n <rpt-icon name=\"check\" [size]=\"10\" />\n </span>\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n }\n </div>\n }\n @case ('button') {\n <div class=\"mock-btn-wrapper\">\n <button\n type=\"button\"\n class=\"mock-btn\"\n [class]=\"'btn-' + (comp.properties?.['variant'] || 'primary')\"\n [class.mock-btn-full]=\"comp.properties?.['fullWidth'] === true || comp.layout?.width === '100%'\"\n [style.height]=\"getCustomBtnHeight(comp)\"\n [style.width]=\"getCustomBtnWidth(comp)\"\n (click)=\"onCanvasButtonClick(comp, $event)\"\n >\n @if (getCustomBtnIcon(comp); as btnIcon) {\n <rpt-icon [name]=\"btnIcon\" [size]=\"15\" />\n }\n <span>{{ comp.label || 'Button' }}</span>\n </button>\n </div>\n }\n @case ('kpi-card') {\n <div class=\"mock-kpi-field\">\n <div class=\"mock-kpi-header\">\n <span class=\"mock-label\">{{ comp.label || 'KPI Metric' }}</span>\n <rpt-icon name=\"kpi\" [size]=\"14\" />\n </div>\n <div class=\"mock-kpi-value\">{{ comp.properties?.['value'] || '$128,450' }}</div>\n <div class=\"mock-kpi-footer\">\n <span class=\"mock-kpi-trend\">+12.5%</span>\n <span class=\"mock-kpi-sub\">vs last period</span>\n </div>\n </div>\n }\n @case ('chart') {\n <div class=\"mock-chart-field\">\n <div class=\"mock-chart-header\">\n <span class=\"mock-label\">{{ comp.label || 'Quarterly Sales Revenue ($000)' }}</span>\n </div>\n <div class=\"mock-chart-bars\">\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 44%\"></div>\n <span class=\"mock-bar-lbl\">Q1 Jan-Mar</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 61%\"></div>\n <span class=\"mock-bar-lbl\">Q2 Apr-Jun</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 79%\"></div>\n <span class=\"mock-bar-lbl\">Q3 Jul-Sep</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 100%\"></div>\n <span class=\"mock-bar-lbl\">Q4 Oct-Dec</span>\n </div>\n </div>\n </div>\n }\n @default {\n <div class=\"mock-generic-box\">\n <span>{{ comp.type }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Resizing Handles (East, South, South-East) -->\n <div\n class=\"resize-handle handle-e\"\n (pointerdown)=\"startResize($event, comp, 'e')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize column width \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-s\"\n (pointerdown)=\"startResize($event, comp, 's')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize height \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-se\"\n (pointerdown)=\"startResize($event, comp, 'se')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize width and height \u2022 Double-click to reset\"\n ></div>\n\n <!-- Resizing Dimension Ghost / Badge -->\n @if (resizingCompId() === comp.id) {\n <div class=\"resize-dimension-tooltip\">\n {{ resizingTooltip(comp) }}\n </div>\n }\n\n <!-- Drag placeholder with matched grid column span -->\n <div\n *cdkDragPlaceholder\n class=\"canvas-drag-placeholder\"\n [style.grid-column]=\"getGridColumn(comp)\"\n ></div>\n\n <!-- Drag preview -->\n <div *cdkDragPreview class=\"canvas-drag-preview\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"preview-title\">{{ comp.label || comp.key || comp.type }}</span>\n <span class=\"preview-span\">{{ getSpan(comp) }}/{{ totalColumns() }}</span>\n </div>\n </div>\n }\n\n @if (components().length === 0) {\n <div class=\"canvas-empty-state\" role=\"region\" aria-label=\"Empty canvas starter options\">\n <div class=\"empty-hero-badge\">\n <rpt-icon name=\"design\" [size]=\"28\" />\n </div>\n <h3 class=\"empty-hero-title\">Start Designing Your Custom Report</h3>\n <p class=\"empty-hero-desc\">\n Drag controls from the left component palette, or jumpstart your design with pre-configured enterprise blueprints.\n </p>\n\n <div class=\"empty-hero-actions\">\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-primary\"\n (click)=\"applyBlueprint('blueprint-audit-register')\"\n title=\"Load complete Audit Register blueprint with parameters and result grid\"\n >\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span>Audit Register Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-secondary\"\n (click)=\"applyBlueprint('blueprint-kpi-summary')\"\n title=\"Load Executive KPI summary blueprint\"\n >\n <rpt-icon name=\"chart-bar\" [size]=\"15\" />\n <span>KPI Summary Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('date-range')\"\n title=\"Add a Date Range filter component\"\n >\n <rpt-icon name=\"calendar\" [size]=\"14\" />\n <span>+ Add Date Filter</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('button')\"\n title=\"Add an Execute Action button\"\n >\n <rpt-icon name=\"play\" [size]=\"14\" />\n <span>+ Add Run Button</span>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Live Result Grid Preview with Bways-Grid Features -->\n @if (definition().grid) {\n <div class=\"canvas-grid-box\">\n <div class=\"grid-preview-header\">\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span class=\"grid-title\">Bways Grid ({{ definition().grid?.columns?.length ?? 0 }} columns)</span>\n @if (isExecutingGrid()) {\n <span class=\"grid-exec-badge is-loading\">Loading data from database...</span>\n } @else if (gridExecError()) {\n <span class=\"grid-exec-badge is-error\">{{ gridExecError() }}</span>\n } @else if (canvasGridData().length > 0) {\n <span class=\"grid-exec-badge is-success\">{{ canvasGridData().length }} rows loaded</span>\n }\n </div>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <button\n type=\"button\"\n class=\"btn-canvas-run-grid\"\n (click)=\"executeCanvasReport($event)\"\n [disabled]=\"isExecutingGrid()\"\n title=\"Execute query and load data into Bways Grid\"\n >\n <rpt-icon name=\"play\" [size]=\"11\" />\n <span>{{ isExecutingGrid() ? 'Running...' : 'Run / Refresh Grid' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-canvas-edit-grid\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure columns and grid options\"\n >\n <rpt-icon name=\"settings\" [size]=\"11\" />\n <span>Configure</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-remove-grid\"\n (click)=\"removeGrid($event)\"\n title=\"Remove Result Grid from this report\"\n >\n <rpt-icon name=\"trash\" [size]=\"13\" />\n </button>\n </div>\n </div>\n\n @if (getGridSummaryText(); as summary) {\n <div class=\"grid-layout-status-strip\">\n <div class=\"grid-status-info\">\n <rpt-icon name=\"table\" [size]=\"12\" />\n <span>{{ summary }}</span>\n </div>\n <div class=\"grid-status-sync\" [class.is-pulsing]=\"layoutJustUpdated()\">\n <rpt-icon name=\"check\" [size]=\"11\" />\n <span>Layout auto-persisted</span>\n </div>\n </div>\n }\n\n <!-- Live Bways Grid bridge -->\n <div class=\"canvas-live-grid-container\" (click)=\"$event.stopPropagation()\" style=\"position: relative; min-height: 250px;\">\n @if (isExecutingGrid()) {\n <div class=\"canvas-grid-loading-overlay\">\n <span class=\"status-dot dot-pulse\" style=\"width: 14px; height: 14px; color: #2563eb; background: #2563eb; border-radius: 50%;\"></span>\n <span class=\"grid-loading-title\">Executing stored procedure on SQL Server...</span>\n <span class=\"grid-loading-sub\">Calculating outstanding balances and ledger amounts. Please wait...</span>\n </div>\n }\n <rpt-grid-bridge\n [gridDefinition]=\"definition().grid!\"\n [data]=\"canvasGridData()\"\n (gridStateChange)=\"onCanvasGridStateChange($event)\"\n (columnDefsChange)=\"onCanvasColumnDefsChange($event)\"\n />\n </div>\n </div>\n } @else {\n <div class=\"canvas-add-grid-banner\" (click)=\"addResultGrid($event)\">\n <div class=\"add-grid-icon\">\n <rpt-icon name=\"table\" [size]=\"20\" />\n </div>\n <div class=\"add-grid-text\">\n <span class=\"add-grid-title\">+ Add Result Data Grid</span>\n <span class=\"add-grid-sub\">Attach an interactive data table or UltraGrid to display report execution output</span>\n </div>\n <button type=\"button\" class=\"btn-banner-add\">Add Grid</button>\n </div>\n }\n </div>\n </div>\n </div>", styles: [":host{display:block;height:100%;background-color:#f1f5f9;font-family:var(--rpt-font-family, inherit);box-sizing:border-box}.canvas-wrapper{display:flex;flex-direction:column;height:100%}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;min-height:42px;height:42px;padding:0 24px;background:var(--rpt-color-surface, #ffffff);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);box-sizing:border-box;gap:12px;overflow-x:auto;scrollbar-width:none;font-family:var(--rpt-font-family, inherit);flex-shrink:0}.canvas-toolbar::-webkit-scrollbar{display:none}.canvas-info{display:flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #64748b);white-space:nowrap;line-height:1}.info-label{color:var(--rpt-color-text-muted, #64748b);font-weight:500;font-size:var(--rpt-font-size-sm, .75rem)}.info-value{font-weight:600;color:var(--rpt-color-text, #0f172a);font-size:var(--rpt-font-size-sm, .75rem)}.info-divider{color:var(--rpt-color-border, #cbd5e1);margin:0 2px}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-xs, .7rem);font-weight:600;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:2px 8px;border-radius:9999px;line-height:1}.canvas-actions{display:flex;align-items:center;gap:8px;white-space:nowrap}.canvas-action-btn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;letter-spacing:-.01em;color:var(--rpt-color-text-secondary, #334155);background:var(--rpt-color-surface, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);cursor:pointer;line-height:1;white-space:nowrap;box-shadow:0 1px 2px #0000000a;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-action-btn:hover{background:var(--rpt-color-surface-hover, #f8fafc);border-color:var(--rpt-color-border-hover, #94a3b8);color:var(--rpt-color-text, #0f172a);box-shadow:0 2px 4px #0000000f}.canvas-action-btn.btn-grid-configured{background:#eff6ff;border-color:#bfdbfe;color:#2563eb;font-weight:600}.canvas-action-btn.btn-grid-configured:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.canvas-action-btn.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a;font-weight:600}.canvas-action-btn.btn-grid-add:hover{background:#dcfce7;color:#15803d;border-color:#86efac}.canvas-action-btn:active{transform:translateY(1px)}.canvas-scroll-area{flex:1;overflow-y:auto;padding:16px}.canvas-artboard{width:100%;max-width:1400px;margin:0 auto;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-lg, 8px);box-shadow:0 4px 6px -1px #0000000d;min-height:480px;box-sizing:border-box}@media (max-width: 900px){.canvas-toolbar{min-height:36px;height:36px;padding:0 10px;gap:6px}.live-mode-badge{display:none}.canvas-info{font-size:.75rem;gap:5px}.canvas-action-btn{padding:0 8px;font-size:.725rem;height:28px;gap:4px}.canvas-scroll-area{padding:10px}.canvas-artboard{min-height:360px}}@media (max-width: 600px){.canvas-toolbar{padding:0 8px;gap:4px}.canvas-info .info-label,.canvas-action-btn span{display:none}.canvas-action-btn{padding:0 6px;min-width:28px;justify-content:center}}.canvas-report-header{margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.canvas-report-title{font-size:var(--rpt-font-size-xl, 1.5rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 6px}.canvas-report-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);margin:0}.canvas-grid{display:grid;width:100%;min-height:180px;align-items:start;border-radius:6px;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-component-card{container-type:inline-size;background:#fff;border:1.5px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:var(--rpt-box-shadow, 0 1px 2px rgba(0, 0, 0, .05));box-sizing:border-box;transition:all var(--rpt-transition-speed, .15s) ease;cursor:pointer;position:relative;overflow:visible;display:flex;flex-direction:column;min-height:104px;z-index:1}.canvas-component-card:hover{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 4px 6px -1px #2563eb1a;z-index:2}.canvas-component-card.is-selected{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40;z-index:10}.canvas-component-card:focus-within,.canvas-component-card:has(.rpt-combobox-menu),.canvas-component-card:has(.is-open){z-index:100}.canvas-component-card.is-resizing{-webkit-user-select:none;user-select:none;border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb59;z-index:30;transition:none!important}.resize-handle{position:absolute;z-index:20;touch-action:none;opacity:0;pointer-events:none;transition:opacity .15s ease}.canvas-component-card.is-selected .resize-handle{opacity:1;pointer-events:auto}.resize-handle.handle-e{top:0;right:0;width:6px;height:100%;cursor:ew-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-e:after{content:\"\";width:3px;height:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-e:hover:after,.canvas-component-card.is-selected .resize-handle.handle-e:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-s{bottom:0;left:0;height:6px;width:100%;cursor:ns-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-s:after{content:\"\";height:3px;width:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-s:hover:after,.canvas-component-card.is-selected .resize-handle.handle-s:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-se{bottom:0;right:0;width:12px;height:12px;cursor:nwse-resize;display:flex;align-items:flex-end;justify-content:flex-end;padding:2px}.resize-handle.handle-se:after{content:\"\";width:5px;height:5px;border-right:2px solid #cbd5e1;border-bottom:2px solid #cbd5e1;transition:border-color .15s ease}.resize-handle.handle-se:hover:after,.canvas-component-card.is-selected .resize-handle.handle-se:after{border-color:var(--rpt-color-primary, #2563eb)}.resize-dimension-tooltip{position:absolute;top:38px;right:8px;background:#0f172ae6;color:#fff;font-size:.7rem;font-weight:600;padding:3px 8px;border-radius:4px;white-space:nowrap;pointer-events:none;z-index:50;box-shadow:0 2px 4px #0003}.card-header{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:5px 8px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #e2e8f0);border-top-left-radius:var(--rpt-border-radius, 6px);border-top-right-radius:var(--rpt-border-radius, 6px);min-height:32px;box-sizing:border-box;overflow:hidden;position:relative}.canvas-component-card.is-selected .card-header{overflow:visible}.card-title-group{display:flex;align-items:center;gap:5px;cursor:grab;min-width:0;flex:1;overflow:hidden}.drag-handle-dots{color:var(--rpt-color-text-muted, #94a3b8);font-size:.85rem;letter-spacing:-2px;flex-shrink:0;-webkit-user-select:none;user-select:none}.comp-title{font-size:.75rem;font-weight:600;color:var(--rpt-color-text, #0f172a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.card-actions{display:flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.new-row-pill-static{font-size:.65rem;font-weight:600;color:#7c3aed;background:#f5f3ff;border:1px solid #ddd6fe;padding:1px 5px;border-radius:9999px;white-space:nowrap;line-height:1;flex-shrink:0}.span-pill-static{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:var(--rpt-color-surface, #f1f5f9);border:1px solid var(--rpt-color-border, #e2e8f0);padding:1px 6px;border-radius:9999px;line-height:1.2;white-space:nowrap;-webkit-user-select:none;user-select:none}.card-quick-controls{display:none;align-items:center;gap:3px;flex-shrink:0}.canvas-component-card:hover .span-pill-static,.canvas-component-card.is-selected .span-pill-static,.canvas-component-card:hover .new-row-pill-static,.canvas-component-card.is-selected .new-row-pill-static{display:none}.canvas-component-card:hover .card-quick-controls,.canvas-component-card.is-selected .card-quick-controls{display:inline-flex}.canvas-component-card.is-narrow .card-header{padding:4px 6px;gap:3px}.canvas-component-card.is-narrow:hover .comp-title,.canvas-component-card.is-narrow.is-selected .comp-title,.canvas-component-card.is-narrow:hover .drag-handle-dots,.canvas-component-card.is-narrow.is-selected .drag-handle-dots{display:none}.canvas-component-card.is-narrow .card-quick-controls{gap:2px}.canvas-component-card.is-narrow .span-control-group{height:18px}.canvas-component-card.is-narrow .span-btn{width:14px;height:16px}.canvas-component-card.is-narrow .span-badge{font-size:.6rem;padding:0 2px}.canvas-component-card.is-narrow .span-total{display:none}.canvas-component-card.is-narrow .card-action-btn{width:18px;height:18px}@container (max-width: 250px){.card-header{padding:4px 6px;gap:3px}.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.span-total{display:none}.card-quick-controls{gap:2px}.card-action-btn{width:18px;height:18px}.span-control-group{height:18px}.span-btn{width:14px;height:16px}.span-badge{font-size:.6rem;padding:0 2px}}@container (max-width: 160px){.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}@media (max-width: 900px){.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.canvas-component-card .span-total{display:none}.canvas-component-card.is-selected .card-header{overflow:visible}.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}.span-control-group{display:inline-flex;align-items:center;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;height:20px;padding:0 1px;white-space:nowrap;flex-shrink:0}.span-btn{width:16px;height:18px;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:0;color:var(--rpt-color-text-muted, #64748b);cursor:pointer;border-radius:2px;transition:all .12s ease}.span-btn:hover:not(:disabled){background:var(--rpt-color-surface-hover, #f1f5f9);color:var(--rpt-color-primary, #2563eb)}.span-btn:disabled{opacity:.3;cursor:not-allowed}.span-badge{font-size:.65rem;font-weight:600;color:var(--rpt-color-text, #0f172a);padding:0 3px;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}.span-total{font-size:.6rem;color:var(--rpt-color-text-muted, #64748b);font-weight:500}.card-action-btn{width:20px;height:20px;border:none;background:transparent;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;padding:0;cursor:pointer;color:var(--rpt-color-text-muted, #64748b);transition:all .12s ease;flex-shrink:0}.card-action-btn:hover{background:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.card-action-btn.btn-active-toggle{background:#7c3aed;color:#fff;border-color:#7c3aed}.card-action-btn.btn-active-toggle:hover{background:#6d28d9;color:#fff}.btn-delete:hover{background:#fee2e2;color:#ef4444}.card-body{padding:8px 10px 14px;flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;max-width:100%;box-sizing:border-box;overflow:visible}.mock-input-field{display:flex;flex-direction:column;gap:4px;flex:1;height:100%;min-height:0}.mock-label{font-size:.7rem;font-weight:600;color:var(--rpt-color-text-muted, #475569);flex-shrink:0}.mock-input-box,.mock-select-box{border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:6px;padding:6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #94a3b8);background:#fff;flex:1;min-height:38px;height:100%;display:flex;align-items:center;justify-content:space-between;box-sizing:border-box}.mock-checkbox-field{display:flex;align-items:center;gap:6px;flex:1;height:100%;min-height:0;padding-top:14px}.mock-check-box{width:18px;height:18px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:.65rem;color:var(--rpt-color-primary, #2563eb);flex-shrink:0}.mock-btn-wrapper{display:flex;flex:1;height:100%;min-height:38px;align-items:center;justify-content:flex-start;width:100%;min-width:0;box-sizing:border-box}.mock-btn{border-radius:var(--rpt-border-radius, 6px);padding:0 16px;height:36px;font-size:var(--rpt-font-size-base, .875rem);font-weight:500;border:1px solid transparent;cursor:pointer;width:auto;max-width:100%;display:inline-flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:all .15s ease}.mock-btn.mock-btn-full{width:100%}.canvas-component-card.is-narrow .mock-btn{padding:0 6px;font-size:.775rem;width:100%;height:34px}.mock-kpi-field{display:flex;flex-direction:column;justify-content:space-between;flex:1;height:100%;min-height:0}.mock-kpi-header{display:flex;align-items:center;justify-content:space-between}.mock-kpi-value{font-size:1.25rem;font-weight:700;color:var(--rpt-color-text, #0f172a);margin:2px 0}.mock-kpi-footer{display:flex;align-items:center;gap:6px;font-size:.65rem}.mock-kpi-trend{color:#16a34a;font-weight:600}.mock-kpi-sub{color:#64748b}.mock-chart-field{display:flex;flex-direction:column;flex:1;height:100%;min-height:140px}.mock-chart-bars{display:flex;align-items:flex-end;justify-content:space-around;gap:16px;flex:1;min-height:100px;padding-top:12px;box-sizing:border-box}.mock-chart-col{flex:1;display:flex;flex-direction:column;align-items:center;height:100%;min-width:60px;max-width:140px}.mock-chart-bar{width:38px;max-width:44px;margin:0 auto;background:var(--rpt-color-primary, #2563eb);border-radius:6px 6px 0 0;opacity:.85;min-height:10px;transition:height .2s ease}.mock-bar-lbl{font-size:.6875rem;color:#64748b;margin-top:6px;text-align:center;white-space:normal;line-height:1.2}.btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff}.btn-secondary{background:#f1f5f9;color:#0f172a;border:1px solid #cbd5e1}.btn-outline{background:transparent;color:#2563eb;border:1px solid #2563eb}.btn-danger{background:#ef4444;color:#fff}.mock-generic-box{border:1px dashed #cbd5e1;border-radius:4px;padding:8px;font-size:.75rem;text-align:center;color:#64748b}.canvas-drag-placeholder{background:#2563eb0f;border:2px dashed var(--rpt-color-primary, #2563eb);border-radius:6px;min-height:80px;box-sizing:border-box;transition:transform .15s ease}.canvas-drag-preview,::ng-deep .canvas-drag-preview{background:#fff;border:2px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:8px 14px;display:inline-flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif)!important;font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a);box-shadow:0 12px 24px -4px #00000040;z-index:10000}.preview-title,::ng-deep .preview-title{font-family:inherit!important;max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-span,::ng-deep .preview-span{font-family:inherit!important;font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px}.canvas-empty-state{grid-column:1 / -1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:56px 28px;border:2px dashed var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-surface, #ffffff);text-align:center;box-shadow:var(--rpt-box-shadow-xs, 0 1px 2px 0 rgba(0, 0, 0, .04));transition:border-color var(--rpt-transition-speed, .15s) ease}.canvas-empty-state:hover{border-color:var(--rpt-color-primary, #2563eb)}.empty-hero-badge{width:56px;height:56px;border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-primary-light, #eff6ff);color:var(--rpt-color-primary, #2563eb);display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 2px 8px #2563eb1f}.empty-hero-title{font-size:var(--rpt-font-size-lg, 1.125rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 8px;letter-spacing:-.01em}.empty-hero-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);max-width:520px;line-height:1.5;margin:0 0 24px}.empty-hero-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px}.empty-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 16px;font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;border-radius:var(--rpt-border-radius, 6px);cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease;font-family:inherit}.empty-btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff;border:1px solid var(--rpt-color-primary, #2563eb);box-shadow:0 1px 3px #2563eb33}.empty-btn-primary:hover{background:var(--rpt-color-primary-hover, #1d4ed8);border-color:var(--rpt-color-primary-hover, #1d4ed8);transform:translateY(-1px)}.empty-btn-secondary{background:#f8fafc;color:#334155;border:1px solid var(--rpt-color-border, #cbd5e1)}.empty-btn-secondary:hover{background:#f1f5f9;color:#0f172a;border-color:#94a3b8;transform:translateY(-1px)}.empty-btn-outline{background:#fff;color:var(--rpt-color-primary, #2563eb);border:1px solid #bfdbfe}.empty-btn-outline:hover{background:#eff6ff;border-color:var(--rpt-color-primary, #2563eb);transform:translateY(-1px)}.canvas-active-input{width:100%;height:32px;padding:4px 8px;font-size:.8125rem;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;outline:none;box-sizing:border-box;background:#fff;color:#0f172a;transition:border-color .15s ease}.canvas-active-input:focus{border-color:var(--rpt-color-primary, #2563eb)}.canvas-active-checkbox-lbl{display:inline-flex;align-items:center;gap:6px;cursor:pointer}.canvas-live-control-wrapper{width:100%;max-width:100%;min-width:0;position:relative;z-index:1;box-sizing:border-box}.canvas-grid-box{margin-top:24px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:8px;background:#fff;box-shadow:0 1px 3px #0000000d;overflow:hidden}.grid-preview-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a)}.grid-title{font-weight:700}.grid-exec-badge{font-size:.6875rem;font-weight:600;padding:2px 8px;border-radius:10px}.grid-exec-badge.is-loading{background:#eff6ff;color:#2563eb}.grid-exec-badge.is-error{background:#fee2e2;color:#ef4444}.grid-exec-badge.is-success{background:#ecfdf5;color:#059669}.btn-canvas-run-grid{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:.72rem;font-weight:600;color:#fff;background:var(--rpt-color-primary, #2563eb);border:none;border-radius:4px;cursor:pointer;transition:background .15s ease}.btn-canvas-run-grid:hover:not(:disabled){background:#1d4ed8}.btn-canvas-run-grid:disabled{opacity:.6;cursor:not-allowed}.btn-canvas-edit-grid{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;font-size:.72rem;font-weight:500;color:#334155;background:#fff;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-canvas-edit-grid:hover{background:#f1f5f9}.canvas-live-grid-container{width:100%;min-height:480px;background:#fff}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-size:.6875rem;font-weight:700;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:1px 8px;border-radius:9999px}.canvas-component-card.is-field-highlighted{border-color:#f59e0b!important;box-shadow:0 0 0 3px #f59e0b59!important;animation:rpt-pulse-border 1s ease-in-out infinite alternate}@keyframes rpt-pulse-border{0%{box-shadow:0 0 0 2px #f59e0b40}to{box-shadow:0 0 0 5px #f59e0b80}}.grid-layout-status-strip{display:flex;align-items:center;justify-content:space-between;padding:6px 16px;background:#f1f5f9;border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.6875rem;color:#475569}.grid-status-info{display:inline-flex;align-items:center;gap:6px;font-weight:600}.grid-status-sync{display:inline-flex;align-items:center;gap:4px;color:#059669;font-weight:600;transition:transform .2s ease}.grid-status-sync.is-pulsing{transform:scale(1.08);color:#047857}.canvas-actions{display:flex;align-items:center;gap:8px}.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.btn-grid-add:hover{background:#dcfce7;border-color:#86efac;color:#15803d}.btn-remove-grid{display:inline-flex;align-items:center;justify-content:center;padding:4px;border:none;background:transparent;color:#94a3b8;border-radius:4px;cursor:pointer;transition:all .15s ease}.btn-remove-grid:hover{background:#fee2e2;color:#ef4444}.canvas-add-grid-banner{margin-top:24px;border:2px dashed #cbd5e1;border-radius:8px;background:#fff;padding:16px 20px;display:flex;align-items:center;gap:16px;cursor:pointer;transition:all .15s ease}.canvas-add-grid-banner:hover{border-color:#2563eb;background:#f8fafc;box-shadow:0 2px 8px #2563eb14}.add-grid-icon{width:40px;height:40px;border-radius:8px;background:#eff6ff;color:#2563eb;display:flex;align-items:center;justify-content:center;flex-shrink:0}.add-grid-text{display:flex;flex-direction:column;gap:2px;flex:1}.add-grid-title{font-size:.875rem;font-weight:600;color:#0f172a}.add-grid-sub{font-size:.75rem;color:#64748b}.btn-banner-add{padding:6px 14px;font-size:.75rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:6px;cursor:pointer;white-space:nowrap;transition:all .15s ease}.canvas-add-grid-banner:hover .btn-banner-add{background:#2563eb;color:#fff;border-color:#2563eb}.canvas-grid-loading-overlay{position:absolute;inset:0;background:#ffffffe6;backdrop-filter:blur(2px);z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;font-family:inherit;border-radius:6px}.grid-loading-title{font-weight:600;font-size:.95rem;color:#1e293b}.grid-loading-sub{font-size:.8rem;color:#64748b}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,.canvas-active-input::-webkit-inner-spin-button,.canvas-active-input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number],.canvas-active-input{-moz-appearance:textfield;appearance:textfield}\n"] }]
467
- }], propDecorators: { onEscape: [{
504
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: " <div class=\"canvas-wrapper\" (click)=\"onCanvasBackgroundClick($event)\">\n <!-- Canvas Status / Quick Controls -->\n <div class=\"canvas-toolbar\">\n <div class=\"canvas-info\">\n <span class=\"info-label\">Grid Layout:</span>\n <span class=\"info-value\">{{ totalColumns() }} Columns</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"info-label\">Components:</span>\n <span class=\"info-value\">{{ components().length }}</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"live-mode-badge\" title=\"Interactive canvas: Values typed here run live queries and test dropdowns.\">\n \u26A1 Live Interactive Mode\n </span>\n </div>\n\n <div class=\"canvas-actions\">\n @if (!definition().grid) {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-add\"\n (click)=\"addResultGrid($event)\"\n title=\"Add a Result Grid to this report\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>+ Add Grid</span>\n </button>\n } @else {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-configured\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure Result Data Grid\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>Grid ({{ definition().grid?.columns?.length ?? 0 }})</span>\n </button>\n }\n\n <button\n type=\"button\"\n class=\"canvas-action-btn\"\n (click)=\"selectReportSettings($event)\"\n title=\"Configure Page Layout & Grid Settings\"\n >\n <rpt-icon name=\"settings\" [size]=\"14\" />\n <span>Report Settings</span>\n </button>\n </div>\n </div>\n\n <!-- Canvas Drop Area -->\n <div class=\"canvas-scroll-area\">\n <div\n class=\"canvas-artboard\"\n [style.padding.px]=\"definition().layout.padding ?? 24\"\n >\n <!-- Report Header Preview -->\n <div class=\"canvas-report-header\">\n <h2 class=\"canvas-report-title\">{{ definition().name || 'Untitled Report' }}</h2>\n @if (definition().description) {\n <p class=\"canvas-report-desc\">{{ definition().description }}</p>\n }\n </div>\n\n <!-- Component Drop List Grid with 2D mixed orientation and data binding -->\n <div\n cdkDropList\n id=\"designer-canvas-drop-list\"\n class=\"canvas-grid\"\n cdkDropListOrientation=\"mixed\"\n [cdkDropListData]=\"sortedComponents()\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.gap.px]=\"definition().layout.gap ?? 16\"\n (cdkDropListDropped)=\"onDrop($event)\"\n >\n @for (comp of sortedComponents(); track comp.id; let idx = $index) {\n <div\n cdkDrag\n [cdkDragData]=\"comp\"\n [cdkDragDisabled]=\"isAnyResizing()\"\n class=\"canvas-component-card\"\n [class.is-selected]=\"isSelected(comp.id)\"\n [class.is-resizing]=\"resizingCompId() === comp.id\"\n [class.is-field-highlighted]=\"isFieldHighlighted(comp)\"\n [class.is-narrow]=\"getSpan(comp) <= 4\"\n [class.is-compact]=\"getSpan(comp) <= 2\"\n [style.grid-column]=\"getGridColumn(comp)\"\n [style.grid-row]=\"getGridRow(comp)\"\n [style.width]=\"comp.layout?.width || 'auto'\"\n [style.height]=\"getComponentHeight(comp)\"\n [style.min-height]=\"getComponentMinHeight(comp)\"\n (click)=\"onSelect(comp.id, $event)\"\n >\n <!-- Card Header with Drag Handle & Actions -->\n <div class=\"card-header\">\n <div class=\"card-title-group\" cdkDragHandle title=\"Drag to reorder\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"comp-title\" [title]=\"comp.label || comp.key || comp.type\">\n {{ comp.label || comp.key || comp.type }}\n </span>\n </div>\n\n <div class=\"card-actions\">\n <!-- Static span pill & new row / start col pill when not hovered / not selected -->\n @if (comp.layout?.column; as col) {\n <span class=\"new-row-pill-static\" title=\"Starts at Column {{ col }}\">Col {{ col }}</span>\n } @else if (comp.layout?.newRow) {\n <span class=\"new-row-pill-static\" title=\"Starts on separate row\">\u21B3 Row</span>\n }\n <span\n class=\"span-pill-static\"\n title=\"Column span: {{ getSpan(comp) }} of {{ totalColumns() }} columns\"\n >\n {{ getSpan(comp) }}/{{ totalColumns() }}\n </span>\n\n <!-- Quick Action Stepper & Buttons (revealed on hover or selection) -->\n <div class=\"card-quick-controls\">\n <button\n type=\"button\"\n class=\"card-action-btn\"\n [class.btn-active-toggle]=\"comp.layout?.newRow\"\n (click)=\"toggleNewRow(comp, $event)\"\n title=\"{{ comp.layout?.newRow ? 'Starts on new row (Click to place inline)' : 'Start on separate row (Row Break)' }}\"\n >\n <rpt-icon name=\"corner-down-right\" [size]=\"11\" />\n </button>\n\n <div class=\"span-control-group\" title=\"Adjust Column Span\">\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) <= 1\"\n (click)=\"adjustSpan(comp, -1, $event)\"\n title=\"Shrink Column Span\"\n >\n <rpt-icon name=\"minus\" [size]=\"9\" />\n </button>\n <span class=\"span-badge\" [title]=\"'Column span: ' + getSpan(comp) + ' of ' + totalColumns()\">\n <span class=\"span-num\">{{ getSpan(comp) }}</span><span class=\"span-total\">/{{ totalColumns() }}</span>\n </span>\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) >= totalColumns()\"\n (click)=\"adjustSpan(comp, 1, $event)\"\n title=\"Expand Column Span\"\n >\n <rpt-icon name=\"plus\" [size]=\"9\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"card-action-btn\"\n (click)=\"onDuplicate(comp.id, $event)\"\n title=\"Duplicate component\"\n >\n <rpt-icon name=\"copy\" [size]=\"12\" />\n </button>\n <button\n type=\"button\"\n class=\"card-action-btn btn-delete\"\n (click)=\"onDelete(comp.id, $event)\"\n title=\"Remove component\"\n >\n <rpt-icon name=\"trash\" [size]=\"12\" />\n </button>\n </div>\n </div>\n </div>\n\n <!-- Card Body Visual Preview -->\n <div class=\"card-body\">\n\n @switch (comp.type) {\n @case ('input') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Input' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"text\"\n class=\"canvas-active-input\"\n [placeholder]=\"comp.properties?.['placeholder'] || 'Enter text...'\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">{{ comp.properties?.['placeholder'] || 'Enter text...' }}</div>\n }\n </div>\n }\n @case ('dropdown') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-dropdown\n [config]=\"comp\"\n [showStatus]=\"true\"\n [parentForm]=\"canvasForm()\"\n [control]=\"getCanvasControl(comp)\"\n (dropdownClick)=\"onControlInteract(comp)\"\n />\n </div>\n }\n @case ('date') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Date' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"date\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-select-box\">\n <span>YYYY-MM-DD</span>\n <rpt-icon name=\"calendar\" [size]=\"12\" />\n </div>\n }\n </div>\n }\n @case ('date-range') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-date-range\n [config]=\"comp\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('number') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Number' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"number\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">\n {{ comp.properties?.['prefix'] || '' }} 0.00 {{ comp.properties?.['suffix'] || '' }}\n </div>\n }\n </div>\n }\n @case ('checkbox') {\n <div class=\"mock-checkbox-field\" (click)=\"onControlInteract(comp, $event)\">\n @if (getCanvasControl(comp); as ctrl) {\n <label class=\"canvas-active-checkbox-lbl\">\n <input type=\"checkbox\" [formControl]=\"ctrl\" (focus)=\"onControlInteract(comp, $event)\" />\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n </label>\n } @else {\n <span class=\"mock-check-box\">\n <rpt-icon name=\"check\" [size]=\"10\" />\n </span>\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n }\n </div>\n }\n @case ('radio') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-radio\n [config]=\"comp\"\n [control]=\"getCanvasControl(comp)\"\n [parentForm]=\"canvasForm()\"\n />\n </div>\n }\n @case ('button') {\n <div class=\"mock-btn-wrapper\">\n <button\n type=\"button\"\n class=\"mock-btn\"\n [class]=\"'btn-' + (comp.properties?.['variant'] || 'primary')\"\n [class.mock-btn-full]=\"comp.properties?.['fullWidth'] === true || comp.layout?.width === '100%'\"\n [style.height]=\"getCustomBtnHeight(comp)\"\n [style.width]=\"getCustomBtnWidth(comp)\"\n (click)=\"onCanvasButtonClick(comp, $event)\"\n >\n @if (getCustomBtnIcon(comp); as btnIcon) {\n <rpt-icon [name]=\"btnIcon\" [size]=\"15\" />\n }\n <span>{{ comp.label || 'Button' }}</span>\n </button>\n </div>\n }\n @case ('kpi-card') {\n <div class=\"mock-kpi-field\">\n <div class=\"mock-kpi-header\">\n <span class=\"mock-label\">{{ comp.label || 'KPI Metric' }}</span>\n <rpt-icon name=\"kpi\" [size]=\"14\" />\n </div>\n <div class=\"mock-kpi-value\">{{ comp.properties?.['value'] || '$128,450' }}</div>\n <div class=\"mock-kpi-footer\">\n <span class=\"mock-kpi-trend\">+12.5%</span>\n <span class=\"mock-kpi-sub\">vs last period</span>\n </div>\n </div>\n }\n @case ('chart') {\n <div class=\"mock-chart-field\">\n <div class=\"mock-chart-header\">\n <span class=\"mock-label\">{{ comp.label || 'Quarterly Sales Revenue ($000)' }}</span>\n </div>\n <div class=\"mock-chart-bars\">\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 44%\"></div>\n <span class=\"mock-bar-lbl\">Q1 Jan-Mar</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 61%\"></div>\n <span class=\"mock-bar-lbl\">Q2 Apr-Jun</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 79%\"></div>\n <span class=\"mock-bar-lbl\">Q3 Jul-Sep</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 100%\"></div>\n <span class=\"mock-bar-lbl\">Q4 Oct-Dec</span>\n </div>\n </div>\n </div>\n }\n @default {\n <div class=\"mock-generic-box\">\n <span>{{ comp.type }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Resizing Handles (East, South, South-East) -->\n <div\n class=\"resize-handle handle-e\"\n (pointerdown)=\"startResize($event, comp, 'e')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize column width \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-s\"\n (pointerdown)=\"startResize($event, comp, 's')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize height \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-se\"\n (pointerdown)=\"startResize($event, comp, 'se')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize width and height \u2022 Double-click to reset\"\n ></div>\n\n <!-- Resizing Dimension Ghost / Badge -->\n @if (resizingCompId() === comp.id) {\n <div class=\"resize-dimension-tooltip\">\n {{ resizingTooltip(comp) }}\n </div>\n }\n\n <!-- Drag placeholder with matched grid column span -->\n <div\n *cdkDragPlaceholder\n class=\"canvas-drag-placeholder\"\n [style.grid-column]=\"getGridColumn(comp)\"\n ></div>\n\n <!-- Drag preview -->\n <div *cdkDragPreview class=\"canvas-drag-preview\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"preview-title\">{{ comp.label || comp.key || comp.type }}</span>\n <span class=\"preview-span\">{{ getSpan(comp) }}/{{ totalColumns() }}</span>\n </div>\n </div>\n }\n\n @if (components().length === 0) {\n <div class=\"canvas-empty-state\" role=\"region\" aria-label=\"Empty canvas starter options\">\n <div class=\"empty-hero-badge\">\n <rpt-icon name=\"design\" [size]=\"28\" />\n </div>\n <h3 class=\"empty-hero-title\">Start Designing Your Custom Report</h3>\n <p class=\"empty-hero-desc\">\n Drag controls from the left component palette, or jumpstart your design with pre-configured enterprise blueprints.\n </p>\n\n <div class=\"empty-hero-actions\">\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-primary\"\n (click)=\"applyBlueprint('blueprint-audit-register')\"\n title=\"Load complete Audit Register blueprint with parameters and result grid\"\n >\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span>Audit Register Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-secondary\"\n (click)=\"applyBlueprint('blueprint-kpi-summary')\"\n title=\"Load Executive KPI summary blueprint\"\n >\n <rpt-icon name=\"chart-bar\" [size]=\"15\" />\n <span>KPI Summary Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('date-range')\"\n title=\"Add a Date Range filter component\"\n >\n <rpt-icon name=\"calendar\" [size]=\"14\" />\n <span>+ Add Date Filter</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('button')\"\n title=\"Add an Execute Action button\"\n >\n <rpt-icon name=\"play\" [size]=\"14\" />\n <span>+ Add Run Button</span>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Live Result Grid Preview with Bways-Grid Features -->\n @if (definition().grid) {\n <div class=\"canvas-grid-box\">\n <div class=\"grid-preview-header\">\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span class=\"grid-title\">Bways Grid ({{ definition().grid?.columns?.length ?? 0 }} columns)</span>\n @if (isExecutingGrid()) {\n <span class=\"grid-exec-badge is-loading\">Loading data from database...</span>\n } @else if (gridExecError()) {\n <span class=\"grid-exec-badge is-error\">{{ gridExecError() }}</span>\n } @else if (canvasGridData().length > 0) {\n <span class=\"grid-exec-badge is-success\">{{ canvasGridData().length }} rows loaded</span>\n }\n </div>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <button\n type=\"button\"\n class=\"btn-canvas-run-grid\"\n (click)=\"executeCanvasReport($event)\"\n [disabled]=\"isExecutingGrid()\"\n title=\"Execute query and load data into Bways Grid\"\n >\n <rpt-icon name=\"play\" [size]=\"11\" />\n <span>{{ isExecutingGrid() ? 'Running...' : 'Run / Refresh Grid' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-canvas-edit-grid\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure columns and grid options\"\n >\n <rpt-icon name=\"settings\" [size]=\"11\" />\n <span>Configure</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-remove-grid\"\n (click)=\"removeGrid($event)\"\n title=\"Remove Result Grid from this report\"\n >\n <rpt-icon name=\"trash\" [size]=\"13\" />\n </button>\n </div>\n </div>\n\n @if (getGridSummaryText(); as summary) {\n <div class=\"grid-layout-status-strip\">\n <div class=\"grid-status-info\">\n <rpt-icon name=\"table\" [size]=\"12\" />\n <span>{{ summary }}</span>\n </div>\n <div class=\"grid-status-sync\" [class.is-pulsing]=\"layoutJustUpdated()\">\n <rpt-icon name=\"check\" [size]=\"11\" />\n <span>Layout auto-persisted</span>\n </div>\n </div>\n }\n\n <!-- Live Bways Grid bridge -->\n <div class=\"canvas-live-grid-container\" (click)=\"$event.stopPropagation()\" style=\"position: relative; min-height: 250px;\">\n @if (isExecutingGrid()) {\n <div class=\"canvas-grid-loading-overlay\">\n <span class=\"status-dot dot-pulse\" style=\"width: 14px; height: 14px; color: #2563eb; background: #2563eb; border-radius: 50%;\"></span>\n <span class=\"grid-loading-title\">Executing stored procedure on SQL Server...</span>\n <span class=\"grid-loading-sub\">Calculating outstanding balances and ledger amounts. Please wait...</span>\n </div>\n }\n <rpt-grid-bridge\n [gridDefinition]=\"definition().grid!\"\n [data]=\"canvasGridData()\"\n (gridStateChange)=\"onCanvasGridStateChange($event)\"\n (columnDefsChange)=\"onCanvasColumnDefsChange($event)\"\n />\n </div>\n </div>\n } @else {\n <div class=\"canvas-add-grid-banner\" (click)=\"addResultGrid($event)\">\n <div class=\"add-grid-icon\">\n <rpt-icon name=\"table\" [size]=\"20\" />\n </div>\n <div class=\"add-grid-text\">\n <span class=\"add-grid-title\">+ Add Result Data Grid</span>\n <span class=\"add-grid-sub\">Attach an interactive data table or UltraGrid to display report execution output</span>\n </div>\n <button type=\"button\" class=\"btn-banner-add\">Add Grid</button>\n </div>\n }\n </div>\n </div>\n </div>", styles: [":host{display:block;flex:1;min-height:0;min-width:0;height:100%;background-color:#f1f5f9;font-family:var(--rpt-font-family, inherit);box-sizing:border-box}.canvas-wrapper{min-height:0;display:flex;flex-direction:column;height:100%}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;min-height:42px;height:42px;padding:0 24px;background:var(--rpt-color-surface, #ffffff);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);box-sizing:border-box;gap:12px;overflow-x:auto;scrollbar-width:none;font-family:var(--rpt-font-family, inherit);flex-shrink:0}.canvas-toolbar::-webkit-scrollbar{display:none}.canvas-info{display:flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #64748b);white-space:nowrap;line-height:1}.info-label{color:var(--rpt-color-text-muted, #64748b);font-weight:500;font-size:var(--rpt-font-size-sm, .75rem)}.info-value{font-weight:600;color:var(--rpt-color-text, #0f172a);font-size:var(--rpt-font-size-sm, .75rem)}.info-divider{color:var(--rpt-color-border, #cbd5e1);margin:0 2px}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-xs, .7rem);font-weight:600;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:2px 8px;border-radius:9999px;line-height:1}.canvas-actions{display:flex;align-items:center;gap:8px;white-space:nowrap}.canvas-action-btn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;letter-spacing:-.01em;color:var(--rpt-color-text-secondary, #334155);background:var(--rpt-color-surface, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);cursor:pointer;line-height:1;white-space:nowrap;box-shadow:0 1px 2px #0000000a;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-action-btn:hover{background:var(--rpt-color-surface-hover, #f8fafc);border-color:var(--rpt-color-border-hover, #94a3b8);color:var(--rpt-color-text, #0f172a);box-shadow:0 2px 4px #0000000f}.canvas-action-btn.btn-grid-configured{background:#eff6ff;border-color:#bfdbfe;color:#2563eb;font-weight:600}.canvas-action-btn.btn-grid-configured:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.canvas-action-btn.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a;font-weight:600}.canvas-action-btn.btn-grid-add:hover{background:#dcfce7;color:#15803d;border-color:#86efac}.canvas-action-btn:active{transform:translateY(1px)}.canvas-scroll-area{flex:1;min-height:0;overflow-y:auto;padding:16px}.canvas-artboard{width:100%;max-width:1400px;margin:0 auto;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-lg, 8px);box-shadow:0 4px 6px -1px #0000000d;min-height:480px;box-sizing:border-box}@media (max-width: 900px){.canvas-toolbar{min-height:36px;height:36px;padding:0 10px;gap:6px}.live-mode-badge{display:none}.canvas-info{font-size:.75rem;gap:5px}.canvas-action-btn{padding:0 8px;font-size:.725rem;height:28px;gap:4px}.canvas-scroll-area{padding:10px}.canvas-artboard{min-height:360px}}@media (max-width: 600px){.canvas-toolbar{padding:0 8px;gap:4px}.canvas-info .info-label,.canvas-action-btn span{display:none}.canvas-action-btn{padding:0 6px;min-width:28px;justify-content:center}}.canvas-report-header{margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.canvas-report-title{font-size:var(--rpt-font-size-xl, 1.5rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 6px}.canvas-report-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);margin:0}.canvas-grid{display:grid;width:100%;min-height:180px;align-items:start;border-radius:6px;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-component-card{container-type:inline-size;background:#fff;border:1.5px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:var(--rpt-box-shadow, 0 1px 2px rgba(0, 0, 0, .05));box-sizing:border-box;transition:all var(--rpt-transition-speed, .15s) ease;cursor:pointer;position:relative;overflow:visible;display:flex;flex-direction:column;min-height:104px;z-index:1}.canvas-component-card:hover{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 4px 6px -1px #2563eb1a;z-index:2}.canvas-component-card.is-selected{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40;z-index:10}.canvas-component-card:focus-within,.canvas-component-card:has(.rpt-combobox-menu),.canvas-component-card:has(.is-open){z-index:100}.canvas-component-card.is-resizing{-webkit-user-select:none;user-select:none;border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb59;z-index:30;transition:none!important}.resize-handle{position:absolute;z-index:20;touch-action:none;opacity:0;pointer-events:none;transition:opacity .15s ease}.canvas-component-card.is-selected .resize-handle{opacity:1;pointer-events:auto}.resize-handle.handle-e{top:0;right:0;width:6px;height:100%;cursor:ew-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-e:after{content:\"\";width:3px;height:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-e:hover:after,.canvas-component-card.is-selected .resize-handle.handle-e:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-s{bottom:0;left:0;height:6px;width:100%;cursor:ns-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-s:after{content:\"\";height:3px;width:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-s:hover:after,.canvas-component-card.is-selected .resize-handle.handle-s:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-se{bottom:0;right:0;width:12px;height:12px;cursor:nwse-resize;display:flex;align-items:flex-end;justify-content:flex-end;padding:2px}.resize-handle.handle-se:after{content:\"\";width:5px;height:5px;border-right:2px solid #cbd5e1;border-bottom:2px solid #cbd5e1;transition:border-color .15s ease}.resize-handle.handle-se:hover:after,.canvas-component-card.is-selected .resize-handle.handle-se:after{border-color:var(--rpt-color-primary, #2563eb)}.resize-dimension-tooltip{position:absolute;top:38px;right:8px;background:#0f172ae6;color:#fff;font-size:.7rem;font-weight:600;padding:3px 8px;border-radius:4px;white-space:nowrap;pointer-events:none;z-index:50;box-shadow:0 2px 4px #0003}.card-header{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:5px 8px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #e2e8f0);border-top-left-radius:var(--rpt-border-radius, 6px);border-top-right-radius:var(--rpt-border-radius, 6px);min-height:32px;box-sizing:border-box;overflow:hidden;position:relative}.canvas-component-card.is-selected .card-header{overflow:visible}.card-title-group{display:flex;align-items:center;gap:5px;cursor:grab;min-width:0;flex:1;overflow:hidden}.drag-handle-dots{color:var(--rpt-color-text-muted, #94a3b8);font-size:.85rem;letter-spacing:-2px;flex-shrink:0;-webkit-user-select:none;user-select:none}.comp-title{font-size:.75rem;font-weight:600;color:var(--rpt-color-text, #0f172a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.card-actions{display:flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.new-row-pill-static{font-size:.65rem;font-weight:600;color:#7c3aed;background:#f5f3ff;border:1px solid #ddd6fe;padding:1px 5px;border-radius:9999px;white-space:nowrap;line-height:1;flex-shrink:0}.span-pill-static{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:var(--rpt-color-surface, #f1f5f9);border:1px solid var(--rpt-color-border, #e2e8f0);padding:1px 6px;border-radius:9999px;line-height:1.2;white-space:nowrap;-webkit-user-select:none;user-select:none}.card-quick-controls{display:none;align-items:center;gap:3px;flex-shrink:0}.canvas-component-card:hover .span-pill-static,.canvas-component-card.is-selected .span-pill-static,.canvas-component-card:hover .new-row-pill-static,.canvas-component-card.is-selected .new-row-pill-static{display:none}.canvas-component-card:hover .card-quick-controls,.canvas-component-card.is-selected .card-quick-controls{display:inline-flex}.canvas-component-card.is-narrow .card-header{padding:4px 6px;gap:3px}.canvas-component-card.is-narrow:hover .comp-title,.canvas-component-card.is-narrow.is-selected .comp-title,.canvas-component-card.is-narrow:hover .drag-handle-dots,.canvas-component-card.is-narrow.is-selected .drag-handle-dots{display:none}.canvas-component-card.is-narrow .card-quick-controls{gap:2px}.canvas-component-card.is-narrow .span-control-group{height:18px}.canvas-component-card.is-narrow .span-btn{width:14px;height:16px}.canvas-component-card.is-narrow .span-badge{font-size:.6rem;padding:0 2px}.canvas-component-card.is-narrow .span-total{display:none}.canvas-component-card.is-narrow .card-action-btn{width:18px;height:18px}@container (max-width: 250px){.card-header{padding:4px 6px;gap:3px}.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.span-total{display:none}.card-quick-controls{gap:2px}.card-action-btn{width:18px;height:18px}.span-control-group{height:18px}.span-btn{width:14px;height:16px}.span-badge{font-size:.6rem;padding:0 2px}}@container (max-width: 160px){.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}@media (max-width: 900px){.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.canvas-component-card .span-total{display:none}.canvas-component-card.is-selected .card-header{overflow:visible}.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}.span-control-group{display:inline-flex;align-items:center;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;height:20px;padding:0 1px;white-space:nowrap;flex-shrink:0}.span-btn{width:16px;height:18px;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:0;color:var(--rpt-color-text-muted, #64748b);cursor:pointer;border-radius:2px;transition:all .12s ease}.span-btn:hover:not(:disabled){background:var(--rpt-color-surface-hover, #f1f5f9);color:var(--rpt-color-primary, #2563eb)}.span-btn:disabled{opacity:.3;cursor:not-allowed}.span-badge{font-size:.65rem;font-weight:600;color:var(--rpt-color-text, #0f172a);padding:0 3px;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}.span-total{font-size:.6rem;color:var(--rpt-color-text-muted, #64748b);font-weight:500}.card-action-btn{width:20px;height:20px;border:none;background:transparent;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;padding:0;cursor:pointer;color:var(--rpt-color-text-muted, #64748b);transition:all .12s ease;flex-shrink:0}.card-action-btn:hover{background:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.card-action-btn.btn-active-toggle{background:#7c3aed;color:#fff;border-color:#7c3aed}.card-action-btn.btn-active-toggle:hover{background:#6d28d9;color:#fff}.btn-delete:hover{background:#fee2e2;color:#ef4444}.card-body{padding:8px 10px 14px;flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;max-width:100%;box-sizing:border-box;overflow:visible}.mock-input-field{display:flex;flex-direction:column;gap:4px;flex:1;height:100%;min-height:0}.mock-label{font-size:.7rem;font-weight:600;color:var(--rpt-color-text-muted, #475569);flex-shrink:0}.mock-input-box,.mock-select-box{border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:6px;padding:6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #94a3b8);background:#fff;flex:1;min-height:38px;height:100%;display:flex;align-items:center;justify-content:space-between;box-sizing:border-box}.mock-checkbox-field{display:flex;align-items:center;gap:6px;flex:1;height:100%;min-height:0;padding-top:14px}.mock-check-box{width:18px;height:18px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:.65rem;color:var(--rpt-color-primary, #2563eb);flex-shrink:0}.mock-btn-wrapper{display:flex;flex:1;height:100%;min-height:38px;align-items:center;justify-content:flex-start;width:100%;min-width:0;box-sizing:border-box}.mock-btn{border-radius:var(--rpt-border-radius, 6px);padding:0 16px;height:36px;font-size:var(--rpt-font-size-base, .875rem);font-weight:500;border:1px solid transparent;cursor:pointer;width:auto;max-width:100%;display:inline-flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:all .15s ease}.mock-btn.mock-btn-full{width:100%}.canvas-component-card.is-narrow .mock-btn{padding:0 6px;font-size:.775rem;width:100%;height:34px}.mock-kpi-field{display:flex;flex-direction:column;justify-content:space-between;flex:1;height:100%;min-height:0}.mock-kpi-header{display:flex;align-items:center;justify-content:space-between}.mock-kpi-value{font-size:1.25rem;font-weight:700;color:var(--rpt-color-text, #0f172a);margin:2px 0}.mock-kpi-footer{display:flex;align-items:center;gap:6px;font-size:.65rem}.mock-kpi-trend{color:#16a34a;font-weight:600}.mock-kpi-sub{color:#64748b}.mock-chart-field{display:flex;flex-direction:column;flex:1;height:100%;min-height:140px}.mock-chart-bars{display:flex;align-items:flex-end;justify-content:space-around;gap:16px;flex:1;min-height:100px;padding-top:12px;box-sizing:border-box}.mock-chart-col{flex:1;display:flex;flex-direction:column;align-items:center;height:100%;min-width:60px;max-width:140px}.mock-chart-bar{width:38px;max-width:44px;margin:0 auto;background:var(--rpt-color-primary, #2563eb);border-radius:6px 6px 0 0;opacity:.85;min-height:10px;transition:height .2s ease}.mock-bar-lbl{font-size:.6875rem;color:#64748b;margin-top:6px;text-align:center;white-space:normal;line-height:1.2}.btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff}.btn-secondary{background:#f1f5f9;color:#0f172a;border:1px solid #cbd5e1}.btn-outline{background:transparent;color:#2563eb;border:1px solid #2563eb}.btn-danger{background:#ef4444;color:#fff}.mock-generic-box{border:1px dashed #cbd5e1;border-radius:4px;padding:8px;font-size:.75rem;text-align:center;color:#64748b}.canvas-drag-placeholder{background:#2563eb0f;border:2px dashed var(--rpt-color-primary, #2563eb);border-radius:6px;min-height:80px;box-sizing:border-box;transition:transform .15s ease}.canvas-drag-preview,::ng-deep .canvas-drag-preview{background:#fff;border:2px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:8px 14px;display:inline-flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif)!important;font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a);box-shadow:0 12px 24px -4px #00000040;z-index:10000}.preview-title,::ng-deep .preview-title{font-family:inherit!important;max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-span,::ng-deep .preview-span{font-family:inherit!important;font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px}.canvas-empty-state{grid-column:1 / -1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:56px 28px;border:2px dashed var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-surface, #ffffff);text-align:center;box-shadow:var(--rpt-box-shadow-xs, 0 1px 2px 0 rgba(0, 0, 0, .04));transition:border-color var(--rpt-transition-speed, .15s) ease}.canvas-empty-state:hover{border-color:var(--rpt-color-primary, #2563eb)}.empty-hero-badge{width:56px;height:56px;border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-primary-light, #eff6ff);color:var(--rpt-color-primary, #2563eb);display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 2px 8px #2563eb1f}.empty-hero-title{font-size:var(--rpt-font-size-lg, 1.125rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 8px;letter-spacing:-.01em}.empty-hero-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);max-width:520px;line-height:1.5;margin:0 0 24px}.empty-hero-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px}.empty-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 16px;font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;border-radius:var(--rpt-border-radius, 6px);cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease;font-family:inherit}.empty-btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff;border:1px solid var(--rpt-color-primary, #2563eb);box-shadow:0 1px 3px #2563eb33}.empty-btn-primary:hover{background:var(--rpt-color-primary-hover, #1d4ed8);border-color:var(--rpt-color-primary-hover, #1d4ed8);transform:translateY(-1px)}.empty-btn-secondary{background:#f8fafc;color:#334155;border:1px solid var(--rpt-color-border, #cbd5e1)}.empty-btn-secondary:hover{background:#f1f5f9;color:#0f172a;border-color:#94a3b8;transform:translateY(-1px)}.empty-btn-outline{background:#fff;color:var(--rpt-color-primary, #2563eb);border:1px solid #bfdbfe}.empty-btn-outline:hover{background:#eff6ff;border-color:var(--rpt-color-primary, #2563eb);transform:translateY(-1px)}.canvas-active-input{width:100%;height:32px;padding:4px 8px;font-size:.8125rem;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;outline:none;box-sizing:border-box;background:#fff;color:#0f172a;transition:border-color .15s ease}.canvas-active-input:focus{border-color:var(--rpt-color-primary, #2563eb)}.canvas-active-checkbox-lbl{display:inline-flex;align-items:center;gap:6px;cursor:pointer}.canvas-live-control-wrapper{width:100%;max-width:100%;min-width:0;position:relative;z-index:1;box-sizing:border-box}.canvas-grid-box{margin-top:24px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:8px;background:#fff;box-shadow:0 1px 3px #0000000d;overflow:hidden}.grid-preview-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a)}.grid-title{font-weight:700}.grid-exec-badge{font-size:.6875rem;font-weight:600;padding:2px 8px;border-radius:10px}.grid-exec-badge.is-loading{background:#eff6ff;color:#2563eb}.grid-exec-badge.is-error{background:#fee2e2;color:#ef4444}.grid-exec-badge.is-success{background:#ecfdf5;color:#059669}.btn-canvas-run-grid{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:.72rem;font-weight:600;color:#fff;background:var(--rpt-color-primary, #2563eb);border:none;border-radius:4px;cursor:pointer;transition:background .15s ease}.btn-canvas-run-grid:hover:not(:disabled){background:#1d4ed8}.btn-canvas-run-grid:disabled{opacity:.6;cursor:not-allowed}.btn-canvas-edit-grid{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;font-size:.72rem;font-weight:500;color:#334155;background:#fff;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-canvas-edit-grid:hover{background:#f1f5f9}.canvas-live-grid-container{width:100%;min-height:480px;background:#fff}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-size:.6875rem;font-weight:700;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:1px 8px;border-radius:9999px}.canvas-component-card.is-field-highlighted{border-color:#f59e0b!important;box-shadow:0 0 0 3px #f59e0b59!important;animation:rpt-pulse-border 1s ease-in-out infinite alternate}@keyframes rpt-pulse-border{0%{box-shadow:0 0 0 2px #f59e0b40}to{box-shadow:0 0 0 5px #f59e0b80}}.grid-layout-status-strip{display:flex;align-items:center;justify-content:space-between;padding:6px 16px;background:#f1f5f9;border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.6875rem;color:#475569}.grid-status-info{display:inline-flex;align-items:center;gap:6px;font-weight:600}.grid-status-sync{display:inline-flex;align-items:center;gap:4px;color:#059669;font-weight:600;transition:transform .2s ease}.grid-status-sync.is-pulsing{transform:scale(1.08);color:#047857}.canvas-actions{display:flex;align-items:center;gap:8px}.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.btn-grid-add:hover{background:#dcfce7;border-color:#86efac;color:#15803d}.btn-remove-grid{display:inline-flex;align-items:center;justify-content:center;padding:4px;border:none;background:transparent;color:#94a3b8;border-radius:4px;cursor:pointer;transition:all .15s ease}.btn-remove-grid:hover{background:#fee2e2;color:#ef4444}.canvas-add-grid-banner{margin-top:24px;border:2px dashed #cbd5e1;border-radius:8px;background:#fff;padding:16px 20px;display:flex;align-items:center;gap:16px;cursor:pointer;transition:all .15s ease}.canvas-add-grid-banner:hover{border-color:#2563eb;background:#f8fafc;box-shadow:0 2px 8px #2563eb14}.add-grid-icon{width:40px;height:40px;border-radius:8px;background:#eff6ff;color:#2563eb;display:flex;align-items:center;justify-content:center;flex-shrink:0}.add-grid-text{display:flex;flex-direction:column;gap:2px;flex:1}.add-grid-title{font-size:.875rem;font-weight:600;color:#0f172a}.add-grid-sub{font-size:.75rem;color:#64748b}.btn-banner-add{padding:6px 14px;font-size:.75rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:6px;cursor:pointer;white-space:nowrap;transition:all .15s ease}.canvas-add-grid-banner:hover .btn-banner-add{background:#2563eb;color:#fff;border-color:#2563eb}.canvas-grid-loading-overlay{position:absolute;inset:0;background:#ffffffe6;backdrop-filter:blur(2px);z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;font-family:inherit;border-radius:6px}.grid-loading-title{font-weight:600;font-size:.95rem;color:#1e293b}.grid-loading-sub{font-size:.8rem;color:#64748b}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,.canvas-active-input::-webkit-inner-spin-button,.canvas-active-input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number],.canvas-active-input{-moz-appearance:textfield;appearance:textfield}\n"] }]
505
+ }], ctorParameters: () => [], propDecorators: { onEscape: [{
468
506
  type: HostListener,
469
507
  args: ['document:keydown.escape']
470
508
  }] } });
471
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVzaWduLWNhbnZhcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9kZXNpZ25lci9jb21wb25lbnRzL2Rlc2lnbi1jYW52YXMvZGVzaWduLWNhbnZhcy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9kZXNpZ25lci9jb21wb25lbnRzL2Rlc2lnbi1jYW52YXMvZGVzaWduLWNhbnZhcy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsWUFBWSxFQUNaLE1BQU0sRUFFTixNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0UsT0FBTyxFQU9MLGNBQWMsR0FDZixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBSS9FLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJEQUEyRCxDQUFDO0FBQzdGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG1FQUFtRSxDQUFDO0FBQ3pHLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVFQUF1RSxDQUFDO0FBQzlHLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBQzFGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdEQUF3RCxDQUFDO0FBQzVGLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQ25GLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsZ0JBQWdCLEVBQ2hCLHNCQUFzQixFQUN0QixvQkFBb0IsRUFDcEIsb0JBQW9CLEVBQ3BCLG9CQUFvQixFQUNwQiw0QkFBNEIsRUFDNUIsdUJBQXVCLEVBQ3ZCLDBCQUEwQixFQUMxQixvQkFBb0IsR0FDckIsTUFBTSxvQ0FBb0MsQ0FBQzs7OztBQW1CNUMsTUFBTSxPQUFPLHFCQUFxQjtJQUNmLGFBQWEsR0FBRyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN0RCx1QkFBdUIsR0FBeUMsSUFBSSxDQUFDO0lBQ3JFLGdCQUFnQixHQUFRLElBQUksQ0FBQztJQUNwQixlQUFlLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDaEQsV0FBVyxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3pDLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0lBRTFELFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQztJQUMzQyxVQUFVLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxRCxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQztJQUU1QyxpQkFBaUIsR0FBRyxJQUFJLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM5QyxVQUFVLEdBQUcsUUFBUSxDQUFZLEdBQUcsRUFBRTtRQUM3QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDaEMsTUFBTSxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUV0QyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRztnQkFBRSxTQUFTO1lBQ3hCLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRTFCLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMvQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDaEcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDM0UsQ0FBQztRQUNILENBQUM7UUFFRCxLQUFLLE1BQU0sV0FBVyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDdkUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztnQkFDbEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNwRCxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDO0lBQ2hDLENBQUMsQ0FBQyxDQUFDO0lBRUgsZ0JBQWdCLENBQUMsSUFBK0I7UUFDOUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDM0IsT0FBUSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQWlCLElBQUksSUFBSSxDQUFDO0lBQ2xFLENBQUM7SUFFUSxvQkFBb0IsR0FBRyxNQUFNLENBQWMsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQ3RELGlCQUFpQixHQUFHLE1BQU0sQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUVwRCxrQkFBa0IsQ0FBQyxJQUErQjtRQUNoRCxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUVELGlCQUFpQixDQUFDLElBQStCLEVBQUUsS0FBYTtRQUM5RCxLQUFLLEVBQUUsZUFBZSxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRCxrQkFBa0I7UUFDaEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLElBQUksQ0FBQztRQUNwQyxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLE1BQU0sS0FBSyxHQUFhLEVBQUUsQ0FBQztRQUMzQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQztRQUN4QyxJQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2hDLEtBQUssQ0FBQyxJQUFJLENBQUMsZUFBZSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3BFLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxrQkFBa0IsQ0FBQyxDQUFDO1FBQzdDLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRUQsc0JBQXNCLENBQUMsTUFBZ0I7UUFDckMsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQztRQUMzQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDWCxDQUFDO0lBRVEsY0FBYyxHQUFHLE1BQU0sQ0FBWSxFQUFFLENBQUMsQ0FBQztJQUN2QyxlQUFlLEdBQUcsTUFBTSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQ3pDLGFBQWEsR0FBRyxNQUFNLENBQWdCLElBQUksQ0FBQyxDQUFDO0lBRTVDLFlBQVksR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUM7SUFFdEUsbUJBQW1CLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtRQUMzQyxPQUFPLFVBQVUsSUFBSSxDQUFDLFlBQVksRUFBRSxtQkFBbUIsQ0FBQztJQUMxRCxDQUFDLENBQUMsQ0FBQztJQUVNLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7UUFDeEMsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hGLENBQUMsQ0FBQyxDQUFDO0lBRU0sY0FBYyxHQUFHLE1BQU0sQ0FBZ0IsSUFBSSxDQUFDLENBQUM7SUFDN0MsWUFBWSxHQUFHLE1BQU0sQ0FBZ0IsSUFBSSxDQUFDLENBQUM7SUFDM0MsY0FBYyxHQUFHLE1BQU0sQ0FBZ0IsSUFBSSxDQUFDLENBQUM7SUFDN0MsYUFBYSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUM7SUFFeEUsVUFBVSxDQUFDLEVBQVU7UUFDbkIsT0FBTyxJQUFJLENBQUMsVUFBVSxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxPQUFPLENBQUMsSUFBK0I7UUFDckMsT0FBTyxvQkFBb0IsQ0FDekIsSUFBSSxFQUNKLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFDbkIsSUFBSSxDQUFDLGNBQWMsRUFBRSxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUMvRCxDQUFDO0lBQ0osQ0FBQztJQUVELGFBQWEsQ0FBQyxJQUErQjtRQUMzQyxPQUFPLG1CQUFtQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzVFLENBQUM7SUFFRCxZQUFZLENBQUMsSUFBK0IsRUFBRSxLQUFpQjtRQUM3RCxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxhQUFhLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDMUUsQ0FBQztJQUVELFVBQVUsQ0FBQyxJQUErQjtRQUN4QyxPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxJQUErQjtRQUNoRCxPQUFPLHVCQUF1QixDQUM1QixJQUFJLEVBQ0osSUFBSSxDQUFDLGNBQWMsRUFBRSxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUNqRSxDQUFDO0lBQ0osQ0FBQztJQUVELHFCQUFxQixDQUFDLElBQStCO1FBQ25ELE9BQU8sMEJBQTBCLENBQy9CLElBQUksRUFDSixJQUFJLENBQUMsY0FBYyxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQ2pFLENBQUM7SUFDSixDQUFDO0lBRUQsa0JBQWtCLENBQUMsSUFBK0I7UUFDaEQsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUM7UUFDOUIsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDdEMsQ0FBQztJQUVELGlCQUFpQixDQUFDLElBQStCO1FBQy9DLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDO1FBQzdCLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3RDLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxJQUErQjtRQUM5QyxPQUFRLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxNQUFNLENBQVksSUFBSSxFQUFFLENBQUM7SUFDckQsQ0FBQztJQUVELGVBQWUsQ0FBQyxJQUErQjtRQUM3QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3RHLE9BQU8sR0FBRyxJQUFJLFdBQVcsTUFBTSxJQUFJLENBQUM7SUFDdEMsQ0FBQztJQUVRLG9CQUFvQixHQUFHLG9CQUFvQixDQUFDO0lBRXJELFFBQVEsQ0FBQyxFQUFVLEVBQUUsS0FBaUI7UUFDcEMsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQUUsT0FBTztRQUNqQyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVELFVBQVUsQ0FBQyxJQUErQixFQUFFLEtBQWEsRUFBRSxLQUFpQjtRQUMxRSxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBRSxPQUFPLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUN6RSxJQUFJLENBQUMsYUFBYSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRUQsV0FBVyxDQUFDLEVBQVUsRUFBRSxLQUFpQjtRQUN2QyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQsUUFBUSxDQUFDLEVBQVUsRUFBRSxLQUFpQjtRQUNwQyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUdELFFBQVE7UUFDTixJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNDLENBQUM7SUFDSCxDQUFDO0lBRUQsdUJBQXVCLENBQUMsS0FBaUI7UUFDdkMsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQUUsT0FBTztRQUNqQyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBcUIsQ0FBQztRQUMzQyxJQUNFLE1BQU0sQ0FBQyxPQUFPLENBQUMsd0JBQXdCLENBQUM7WUFDeEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQztZQUNwQyxNQUFNLENBQUMsT0FBTyxDQUFDLDBCQUEwQixDQUFDLEVBQzFDLENBQUM7WUFDRCxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxLQUFrQjtRQUNyQyxLQUFLLEVBQUUsZUFBZSxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVELGtCQUFrQixDQUFDLEtBQWtCO1FBQ25DLEtBQUssRUFBRSxlQUFlLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsYUFBYSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsV0FBVyxDQUFDLEtBQW1CLEVBQUUsSUFBK0IsRUFBRSxTQUEyQjtRQUMzRixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdkIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBRXhCLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUU1QyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBcUIsQ0FBQztRQUMzQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRTFDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsd0JBQXdCLENBQWdCLENBQUM7UUFDckUsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQWdCLENBQUM7UUFDM0QsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPO1FBRTNCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDN0IsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUM3QixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLFVBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlFLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3pGLE1BQU0sV0FBVyxHQUFHLGtCQUFrQixJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxZQUFZLEdBQUcsb0JBQW9CLENBQUMsQ0FBQztRQUNqRyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdEMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDO1FBQy9DLE1BQU0sUUFBUSxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxTQUFTLENBQUM7UUFFeEUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRXJDLElBQUksV0FBVyxHQUFHLFNBQVMsQ0FBQztRQUM1QixJQUFJLGFBQWEsR0FBRyxXQUFXLENBQUM7UUFFaEMsTUFBTSxhQUFhLEdBQUcsQ0FBQyxTQUF1QixFQUFFLEVBQUU7WUFDaEQsSUFBSSxTQUFTLEtBQUssR0FBRyxJQUFJLFNBQVMsS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDNUMsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7Z0JBQzFDLFdBQVcsR0FBRyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQ2hGLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3JDLENBQUM7WUFFRCxJQUFJLFNBQVMsS0FBSyxHQUFHLElBQUksU0FBUyxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUM1QyxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztnQkFDMUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsNEJBQTRCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3pFLGFBQWEsR0FBRyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUN4RSxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN6QyxDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBRUYsTUFBTSxXQUFXLEdBQUcsQ0FBQyxPQUFxQixFQUFFLEVBQUU7WUFDNUMsSUFBSSxDQUFDO2dCQUNILE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbEQsQ0FBQztZQUFDLE1BQU0sQ0FBQyxDQUFBLENBQUM7WUFFVixNQUFNLENBQUMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1lBQ3pELE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDckQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLGVBQWUsRUFBRSxXQUFXLENBQUMsQ0FBQztZQUV6RCxNQUFNLGFBQWEsR0FBdUMsRUFBRSxDQUFDO1lBQzdELElBQUksU0FBUyxLQUFLLEdBQUcsSUFBSSxTQUFTLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQzVDLGFBQWEsQ0FBQyxVQUFVLEdBQUcsV0FBVyxDQUFDO1lBQ3pDLENBQUM7WUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLENBQUM7WUFDbEQsSUFBSSxTQUFTLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxLQUFLLElBQUksSUFBSSxNQUFNLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDN0QsYUFBYSxDQUFDLE1BQU0sR0FBRyxHQUFHLGFBQWEsSUFBSSxDQUFDO2dCQUM1QyxhQUFhLENBQUMsU0FBUyxHQUFHLEdBQUcsYUFBYSxJQUFJLENBQUM7WUFDakQsQ0FBQztZQUVELElBQUksQ0FBQyxhQUFhLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxhQUFhLENBQUMsQ0FBQztZQUVqRSxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM5QixJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoQyxDQUFDLENBQUM7UUFFRixNQUFNLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQ3RELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDbEQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQsZUFBZSxDQUFDLElBQStCLEVBQUUsS0FBa0I7UUFDakUsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN4QixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDekIsQ0FBQztRQUNELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsYUFBYSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUU7WUFDaEQsVUFBVSxFQUFFLFdBQVc7WUFDdkIsTUFBTSxFQUFFLFNBQVM7WUFDakIsU0FBUyxFQUFFLFNBQVM7WUFDcEIsS0FBSyxFQUFFLFNBQVM7U0FDakIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFpRTtRQUN0RSxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFBRSxPQUFPO1FBRWpDLElBQUksS0FBSyxDQUFDLGlCQUFpQixLQUFLLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNoRCwyQkFBMkI7WUFDM0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDNUUsQ0FBQzthQUFNLENBQUM7WUFDTixtQ0FBbUM7WUFDbkMsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUE4QyxDQUFDO1lBQzFFLE1BQU0sYUFBYSxHQUFHLE9BQU8sT0FBTyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDO1lBQzVFLElBQUksYUFBYSxFQUFFLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDckUsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQWtCO1FBQzlCLEtBQUssRUFBRSxlQUFlLEVBQUUsQ0FBQztRQUN6QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sV0FBVyxHQUF5QjtZQUN4QyxZQUFZLEVBQUUsVUFBVSxFQUFFLEVBQUUsSUFBSSxTQUFTO1lBQ3pDLE9BQU8sRUFBRTtnQkFDUCxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRTtnQkFDL0UsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7YUFDcEY7WUFDRCxPQUFPLEVBQUU7Z0JBQ1AsVUFBVSxFQUFFLElBQUk7Z0JBQ2hCLFFBQVEsRUFBRSxFQUFFO2dCQUNaLGNBQWMsRUFBRSxJQUFJO2dCQUNwQixVQUFVLEVBQUUsSUFBSTtnQkFDaEIsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsWUFBWSxFQUFFLElBQUk7Z0JBQ2xCLFNBQVMsRUFBRSxJQUFJO2FBQ2hCO1NBQ0YsQ0FBQztRQUNGLElBQUksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVELG1CQUFtQixDQUFDLEtBQWtCO1FBQ3BDLElBQUksS0FBSztZQUFFLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUNuQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN2QixDQUFDO1FBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25ELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDdEYsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLGtDQUFrQyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcscUNBQXFDLENBQUMsQ0FBQztZQUN4SCxJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDckMsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUU3QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsRUFBRSxVQUFVLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDckUsSUFBSSxFQUFFLENBQUMsSUFBZSxFQUFFLEVBQUU7Z0JBQ3hCLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbEMsQ0FBQztZQUNELEtBQUssRUFBRSxDQUFDLEdBQVksRUFBRSxFQUFFO2dCQUN0QixPQUFPLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUM1RCxNQUFNLEdBQUcsR0FBRyxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzdELElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxrQkFBa0IsQ0FBQyxDQUFDO2dCQUNsRCxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNsQyxDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELG1CQUFtQixDQUFDLElBQStCLEVBQUUsS0FBaUI7UUFDcEUsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3hCLE1BQU0sTUFBTSxHQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxRQUFRLENBQVksSUFBSSxnQkFBZ0IsQ0FBQztRQUMzRSxJQUFJLE1BQU0sS0FBSyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQzdCLENBQUM7YUFBTSxJQUFJLE1BQU0sS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDOUIsQ0FBQzthQUFNLElBQUksTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLDhGQUE4RixDQUFDLENBQUM7WUFDdkgsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3ZELENBQUM7YUFBTSxJQUFJLE1BQU0sS0FBSyxjQUFjLEVBQUUsQ0FBQztZQUNyQyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQywwRkFBMEYsQ0FBQyxDQUFDO1lBQ25ILFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN2RCxDQUFDO0lBQ0gsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1lBQ2pDLFlBQVksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUMzQyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDO1FBQ3RDLENBQUM7SUFDSCxDQUFDO0lBRUQsdUJBQXVCLENBQUMsS0FBVTtRQUNoQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLElBQUk7WUFBRSxPQUFPO1FBQzlDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFLLENBQUM7UUFFNUMsNkRBQTZEO1FBQzdELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLFdBQVcsSUFBSSxJQUFJLENBQUMsQ0FBQztRQUNuRixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQztRQUNwRCxJQUFJLGlCQUFpQixLQUFLLGFBQWE7WUFBRSxPQUFPO1FBRWhELDZFQUE2RTtRQUM3RSwwRUFBMEU7UUFDMUUsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLFVBQVUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMzRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxVQUFVLElBQUksRUFBRSxDQUFDLENBQUM7UUFDeEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN6RSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdEQsTUFBTSxjQUFjLEdBQUcsWUFBWSxLQUFLLFFBQVEsSUFBSSxXQUFXLEtBQUssT0FBTyxDQUFDO1FBRTVFLE1BQU0sY0FBYyxHQUFHO1lBQ3JCLEdBQUcsQ0FBQyxXQUFXLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUM5QixVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVUsSUFBSSxXQUFXLENBQUMsT0FBTyxFQUFFLFVBQVU7WUFDL0QsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTLElBQUksV0FBVyxDQUFDLE9BQU8sRUFBRSxTQUFTO1lBQzVELFdBQVcsRUFBRSxLQUFLO1NBQ25CLENBQUM7UUFFRixJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ25CLDRDQUE0QztZQUM1QyxJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO2dCQUNqQyxZQUFZLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7Z0JBQzNDLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUM7WUFDdEMsQ0FBQztZQUNELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7WUFFN0Isb0ZBQW9GO1lBQ3BGLElBQUksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUM7Z0JBQ3BDLEdBQUcsV0FBVztnQkFDZCxPQUFPLEVBQUUsY0FBYzthQUN4QixDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2pDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzVELENBQUM7YUFBTSxDQUFDO1lBQ04sb0VBQW9FO1lBQ3BFLG1HQUFtRztZQUNuRyw0RUFBNEU7WUFDNUUseUVBQXlFO1lBQ3pFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7WUFDOUIsSUFBSSxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztnQkFDakMsWUFBWSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1lBQzdDLENBQUM7WUFDRCxJQUFJLENBQUMsdUJBQXVCLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDN0MsSUFBSSxDQUFDLHVCQUF1QixHQUFHLElBQUksQ0FBQztnQkFDcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJO29CQUFFLE9BQU87Z0JBQzlELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFLLENBQUM7Z0JBQzNDLE1BQU0sYUFBYSxHQUFHO29CQUNwQixHQUFHLENBQUMsVUFBVSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUM7b0JBQzdCLFdBQVcsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO2lCQUNuQyxDQUFDO2dCQUNGLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQ25DO29CQUNFLEdBQUcsVUFBVTtvQkFDYixPQUFPLEVBQUUsYUFBYTtpQkFDdkIsRUFDRCxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FDdEIsQ0FBQztZQUNKLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNYLENBQUM7SUFDSCxDQUFDO0lBRUQsd0JBQXdCLENBQUMsSUFBVztRQUNsQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUM1RCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsSUFBSyxDQUFDO1FBQzVDLElBQUksVUFBVSxHQUFHLEtBQUssQ0FBQztRQUV2QixNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ2hELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3pELElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQ1YsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7Z0JBQzVELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDO2dCQUN2QyxJQUFJLFFBQVEsS0FBSyxDQUFDLENBQUMsS0FBSyxJQUFJLFVBQVUsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQ3JELFVBQVUsR0FBRyxJQUFJLENBQUM7Z0JBQ3BCLENBQUM7Z0JBQ0QsT0FBTztvQkFDTCxHQUFHLENBQUM7b0JBQ0osS0FBSyxFQUFFLFFBQVE7b0JBQ2YsT0FBTyxFQUFFLFVBQVU7aUJBQ3BCLENBQUM7WUFDSixDQUFDO1lBQ0QsT0FBTyxDQUFDLENBQUM7UUFDWCxDQUFDLENBQUMsQ0FBQztRQUVILG9GQUFvRjtRQUNwRixJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU87UUFFeEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQztZQUNwQyxHQUFHLFdBQVc7WUFDZCxPQUFPLEVBQUUsV0FBVztTQUNyQixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCxVQUFVLENBQUMsS0FBa0I7UUFDM0IsS0FBSyxFQUFFLGVBQWUsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVELGNBQWMsQ0FBQyxXQUFtQjtRQUNoQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3JFLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxJQUFZO1FBQzlCLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hDLENBQUM7d0dBM2ZVLHFCQUFxQjs0RkFBckIscUJBQXFCLCtJQzlEbEMsb215QkFnZ0JVLGlndUJEL2NOLFlBQVksOEJBQ1osY0FBYyxzMUNBQ2QsbUJBQW1CLDY1QkFDbkIsZ0JBQWdCLHVHQUNoQixvQkFBb0IsZ0pBQ3BCLHFCQUFxQiwwRkFDckIseUJBQXlCOzs0RkFPaEIscUJBQXFCO2tCQWpCakMsU0FBUzsrQkFDRSxtQkFBbUIsY0FDakIsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osY0FBYzt3QkFDZCxtQkFBbUI7d0JBQ25CLGdCQUFnQjt3QkFDaEIsb0JBQW9CO3dCQUNwQixxQkFBcUI7d0JBQ3JCLHlCQUF5QjtxQkFDMUIsbUJBSWdCLHVCQUF1QixDQUFDLE1BQU07OEJBcUwvQyxRQUFRO3NCQURQLFlBQVk7dUJBQUMseUJBQXlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgY29tcHV0ZWQsXG4gIEhvc3RMaXN0ZW5lcixcbiAgaW5qZWN0LFxuICBPbkRlc3Ryb3ksXG4gIHNpZ25hbCxcbiAgdW50cmFja2VkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBSZWFjdGl2ZUZvcm1zTW9kdWxlLCBGb3JtQ29udHJvbCwgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgQ2RrRHJhZyxcbiAgQ2RrRHJhZ0Ryb3AsXG4gIENka0RyYWdIYW5kbGUsXG4gIENka0RyYWdQbGFjZWhvbGRlcixcbiAgQ2RrRHJhZ1ByZXZpZXcsXG4gIENka0Ryb3BMaXN0LFxuICBEcmFnRHJvcE1vZHVsZSxcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XG5pbXBvcnQgeyBEZXNpZ25lclN0YXRlU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2Rlc2lnbmVyLXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUmVwb3J0VGVtcGxhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvcmVwb3J0LXRlbXBsYXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvbW9kZWxzL3JlcG9ydC1jb21wb25lbnQubW9kZWwnO1xuaW1wb3J0IHsgQ29tcG9uZW50TGF5b3V0RGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvbW9kZWxzL3JlcG9ydC1sYXlvdXQubW9kZWwnO1xuaW1wb3J0IHsgUmVwb3J0R3JpZERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtZ3JpZC5tb2RlbCc7XG5pbXBvcnQgeyBScHRJY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vcHJpbWl0aXZlcy9jb21wb25lbnRzL2ljb24vcnB0LWljb24uY29tcG9uZW50JztcbmltcG9ydCB7IFJwdERyb3Bkb3duQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vcHJpbWl0aXZlcy9jb21wb25lbnRzL2Ryb3Bkb3duL3JwdC1kcm9wZG93bi5jb21wb25lbnQnO1xuaW1wb3J0IHsgUnB0RGF0ZVJhbmdlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vcHJpbWl0aXZlcy9jb21wb25lbnRzL2RhdGUtcmFuZ2UvcnB0LWRhdGUtcmFuZ2UuY29tcG9uZW50JztcbmltcG9ydCB7IFJlcG9ydEdyaWRCcmlkZ2VDb21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi9ydW50aW1lL3JlcG9ydC1ncmlkLWJyaWRnZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgRHluYW1pY0Zvcm1CdWlsZGVyIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9zZXJ2aWNlcy9keW5hbWljLWZvcm0tYnVpbGRlci5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydEV4ZWN1dGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9ydW50aW1lL3JlcG9ydC1leGVjdXRpb24uc2VydmljZSc7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVHcmlkQ29sdW1uLFxuICBjYWxjdWxhdGVHcmlkUm93LFxuICBjYWxjdWxhdGVTbmFwcGVkSGVpZ2h0LFxuICBjYWxjdWxhdGVTbmFwcGVkU3BhbixcbiAgQ0FOVkFTX0NBUkRfT1ZFUkhFQUQsXG4gIGdldENvbXBvbmVudEljb25OYW1lLFxuICBnZXRDb21wb25lbnROYXR1cmFsTWluSGVpZ2h0LFxuICByZXNvbHZlQ2FudmFzQ2FyZEhlaWdodCxcbiAgcmVzb2x2ZUNhbnZhc0NhcmRNaW5IZWlnaHQsXG4gIHJlc29sdmVDb21wb25lbnRTcGFuLFxufSBmcm9tICcuLi8uLi91dGlsaXRpZXMvY2FudmFzLWxheW91dC51dGlsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncnB0LWRlc2lnbi1jYW52YXMnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIERyYWdEcm9wTW9kdWxlLFxuICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gICAgUnB0SWNvbkNvbXBvbmVudCxcbiAgICBScHREcm9wZG93bkNvbXBvbmVudCxcbiAgICBScHREYXRlUmFuZ2VDb21wb25lbnQsXG4gICAgUmVwb3J0R3JpZEJyaWRnZUNvbXBvbmVudCxcbiAgXSxcblxuICB0ZW1wbGF0ZVVybDogJy4vZGVzaWduLWNhbnZhcy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9kZXNpZ24tY2FudmFzLmNvbXBvbmVudC5jc3MnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgRGVzaWduQ2FudmFzQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXNpZ25lclN0YXRlID0gaW5qZWN0KERlc2lnbmVyU3RhdGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBncmlkRmlsdGVyRGVib3VuY2VUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBwZW5kaW5nR3JpZFN0YXRlOiBhbnkgPSBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5IHRlbXBsYXRlU2VydmljZSA9IGluamVjdChSZXBvcnRUZW1wbGF0ZVNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IGZvcm1CdWlsZGVyID0gaW5qZWN0KER5bmFtaWNGb3JtQnVpbGRlcik7XG4gIHByaXZhdGUgcmVhZG9ubHkgZXhlY3V0aW9uU2VydmljZSA9IGluamVjdChSZXBvcnRFeGVjdXRpb25TZXJ2aWNlKTtcblxuICByZWFkb25seSBkZWZpbml0aW9uID0gdGhpcy5kZXNpZ25lclN0YXRlLmRlZmluaXRpb247XG4gIHJlYWRvbmx5IGNvbXBvbmVudHMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmRlZmluaXRpb24oKS5jb21wb25lbnRzKTtcbiAgcmVhZG9ubHkgc2VsZWN0ZWRJZCA9IHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RlZENvbXBvbmVudElkO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX3N0YWJsZUNhbnZhc0Zvcm0gPSBuZXcgRm9ybUdyb3VwKHt9KTtcbiAgcmVhZG9ubHkgY2FudmFzRm9ybSA9IGNvbXB1dGVkPEZvcm1Hcm91cD4oKCkgPT4ge1xuICAgIGNvbnN0IGNvbXBzID0gdGhpcy5jb21wb25lbnRzKCk7XG4gICAgY29uc3QgY3VycmVudEtleXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIGZvciAoY29uc3QgY29tcCBvZiBjb21wcykge1xuICAgICAgaWYgKCFjb21wLmtleSkgY29udGludWU7XG4gICAgICBjdXJyZW50S2V5cy5hZGQoY29tcC5rZXkpO1xuXG4gICAgICBpZiAoIXRoaXMuX3N0YWJsZUNhbnZhc0Zvcm0uY29udGFpbnMoY29tcC5rZXkpKSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRWYWwgPSBjb21wLnByb3BlcnRpZXM/LlsnZGVmYXVsdFZhbHVlJ10gPz8gKGNvbXAudHlwZSA9PT0gJ2NoZWNrYm94JyA/IGZhbHNlIDogJycpO1xuICAgICAgICB0aGlzLl9zdGFibGVDYW52YXNGb3JtLmFkZENvbnRyb2woY29tcC5rZXksIG5ldyBGb3JtQ29udHJvbChkZWZhdWx0VmFsKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBleGlzdGluZ0tleSBvZiBPYmplY3Qua2V5cyh0aGlzLl9zdGFibGVDYW52YXNGb3JtLmNvbnRyb2xzKSkge1xuICAgICAgaWYgKCFjdXJyZW50S2V5cy5oYXMoZXhpc3RpbmdLZXkpKSB7XG4gICAgICAgIHRoaXMuX3N0YWJsZUNhbnZhc0Zvcm0ucmVtb3ZlQ29udHJvbChleGlzdGluZ0tleSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3N0YWJsZUNhbnZhc0Zvcm07XG4gIH0pO1xuXG4gIGdldENhbnZhc0NvbnRyb2woY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IEZvcm1Db250cm9sIHwgbnVsbCB7XG4gICAgaWYgKCFjb21wLmtleSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuICh0aGlzLmNhbnZhc0Zvcm0oKS5nZXQoY29tcC5rZXkpIGFzIEZvcm1Db250cm9sKSA/PyBudWxsO1xuICB9XG5cbiAgcmVhZG9ubHkgaGlnaGxpZ2h0ZWRGaWVsZEtleXMgPSBzaWduYWw8U2V0PHN0cmluZz4+KG5ldyBTZXQoKSk7XG4gIHJlYWRvbmx5IGxheW91dEp1c3RVcGRhdGVkID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcblxuICBpc0ZpZWxkSGlnaGxpZ2h0ZWQoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIWNvbXAua2V5ICYmIHRoaXMuaGlnaGxpZ2h0ZWRGaWVsZEtleXMoKS5oYXMoY29tcC5rZXkudG9Mb3dlckNhc2UoKSk7XG4gIH1cblxuICBvbkNvbnRyb2xJbnRlcmFjdChjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLCBldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoY29tcC5pZCk7XG4gIH1cblxuICBnZXRHcmlkU3VtbWFyeVRleHQoKTogc3RyaW5nIHtcbiAgICBjb25zdCBncmlkID0gdGhpcy5kZWZpbml0aW9uKCkuZ3JpZDtcbiAgICBpZiAoIWdyaWQpIHJldHVybiAnJztcbiAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBncm91cHMgPSBncmlkLm9wdGlvbnM/Lmdyb3VwTW9kZWw7XG4gICAgaWYgKGdyb3VwcyAmJiBncm91cHMubGVuZ3RoID4gMCkge1xuICAgICAgcGFydHMucHVzaChgR3JvdXBlZCBieTogJHtncm91cHMuam9pbignLCAnKX1gKTtcbiAgICB9XG4gICAgY29uc3QgY29scyA9IGdyaWQuY29sdW1ucz8uZmlsdGVyKChjKSA9PiBjLnZpc2libGUgIT09IGZhbHNlKSA/PyBbXTtcbiAgICBwYXJ0cy5wdXNoKGAke2NvbHMubGVuZ3RofSB2aXNpYmxlIGNvbHVtbnNgKTtcbiAgICByZXR1cm4gcGFydHMuam9pbignIOKAoiAnKTtcbiAgfVxuXG4gIGhpZ2hsaWdodE1pc3NpbmdGaWVsZHMoZmllbGRzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IGtleXMgPSBuZXcgU2V0KGZpZWxkcy5tYXAoKGYpID0+IGYudG9Mb3dlckNhc2UoKSkpO1xuICAgIHRoaXMuaGlnaGxpZ2h0ZWRGaWVsZEtleXMuc2V0KGtleXMpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5oaWdobGlnaHRlZEZpZWxkS2V5cy5zZXQobmV3IFNldCgpKTtcbiAgICB9LCAyODAwKTtcbiAgfVxuXG4gIHJlYWRvbmx5IGNhbnZhc0dyaWREYXRhID0gc2lnbmFsPHVua25vd25bXT4oW10pO1xuICByZWFkb25seSBpc0V4ZWN1dGluZ0dyaWQgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBncmlkRXhlY0Vycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuXG4gIHJlYWRvbmx5IHRvdGFsQ29sdW1ucyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGVmaW5pdGlvbigpLmxheW91dC5jb2x1bW5zIHx8IDEyKTtcblxuICByZWFkb25seSBncmlkVGVtcGxhdGVDb2x1bW5zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHJldHVybiBgcmVwZWF0KCR7dGhpcy50b3RhbENvbHVtbnMoKX0sIG1pbm1heCgwLCAxZnIpKWA7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHNvcnRlZENvbXBvbmVudHMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgcmV0dXJuIFsuLi50aGlzLmNvbXBvbmVudHMoKV0uc29ydCgoYSwgYikgPT4gKGEub3JkZXIgPz8gMCkgLSAoYi5vcmRlciA/PyAwKSk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHJlc2l6aW5nQ29tcElkID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICByZWFkb25seSByZXNpemluZ1NwYW4gPSBzaWduYWw8bnVtYmVyIHwgbnVsbD4obnVsbCk7XG4gIHJlYWRvbmx5IHJlc2l6aW5nSGVpZ2h0ID0gc2lnbmFsPG51bWJlciB8IG51bGw+KG51bGwpO1xuICByZWFkb25seSBpc0FueVJlc2l6aW5nID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5yZXNpemluZ0NvbXBJZCgpICE9PSBudWxsKTtcblxuICBpc1NlbGVjdGVkKGlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZElkKCkgPT09IGlkO1xuICB9XG5cbiAgZ2V0U3Bhbihjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogbnVtYmVyIHtcbiAgICByZXR1cm4gcmVzb2x2ZUNvbXBvbmVudFNwYW4oXG4gICAgICBjb21wLFxuICAgICAgdGhpcy50b3RhbENvbHVtbnMoKSxcbiAgICAgIHRoaXMucmVzaXppbmdDb21wSWQoKSA9PT0gY29tcC5pZCA/IHRoaXMucmVzaXppbmdTcGFuKCkgOiBudWxsXG4gICAgKTtcbiAgfVxuXG4gIGdldEdyaWRDb2x1bW4oY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZUdyaWRDb2x1bW4oY29tcCwgdGhpcy50b3RhbENvbHVtbnMoKSwgdGhpcy5nZXRTcGFuKGNvbXApKTtcbiAgfVxuXG4gIHRvZ2dsZU5ld1Jvdyhjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSAhIWNvbXAubGF5b3V0Py5uZXdSb3c7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUNvbXBvbmVudExheW91dChjb21wLmlkLCB7IG5ld1JvdzogIWN1cnJlbnQgfSk7XG4gIH1cblxuICBnZXRHcmlkUm93KGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiBjYWxjdWxhdGVHcmlkUm93KGNvbXApO1xuICB9XG5cbiAgZ2V0Q29tcG9uZW50SGVpZ2h0KGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiByZXNvbHZlQ2FudmFzQ2FyZEhlaWdodChcbiAgICAgIGNvbXAsXG4gICAgICB0aGlzLnJlc2l6aW5nQ29tcElkKCkgPT09IGNvbXAuaWQgPyB0aGlzLnJlc2l6aW5nSGVpZ2h0KCkgOiBudWxsXG4gICAgKTtcbiAgfVxuXG4gIGdldENvbXBvbmVudE1pbkhlaWdodChjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcmVzb2x2ZUNhbnZhc0NhcmRNaW5IZWlnaHQoXG4gICAgICBjb21wLFxuICAgICAgdGhpcy5yZXNpemluZ0NvbXBJZCgpID09PSBjb21wLmlkID8gdGhpcy5yZXNpemluZ0hlaWdodCgpIDogbnVsbFxuICAgICk7XG4gIH1cblxuICBnZXRDdXN0b21CdG5IZWlnaHQoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IGggPSBjb21wLmxheW91dD8uaGVpZ2h0O1xuICAgIHJldHVybiBoICYmIGggIT09ICdhdXRvJyA/IGggOiBudWxsO1xuICB9XG5cbiAgZ2V0Q3VzdG9tQnRuV2lkdGgoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IHcgPSBjb21wLmxheW91dD8ud2lkdGg7XG4gICAgcmV0dXJuIHcgJiYgdyAhPT0gJ2F1dG8nID8gdyA6IG51bGw7XG4gIH1cblxuICBnZXRDdXN0b21CdG5JY29uKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiAoY29tcC5wcm9wZXJ0aWVzPy5bJ2ljb24nXSBhcyBzdHJpbmcpIHx8ICcnO1xuICB9XG5cbiAgcmVzaXppbmdUb29sdGlwKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIGNvbnN0IHNwYW4gPSB0aGlzLmdldFNwYW4oY29tcCk7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5yZXNpemluZ0hlaWdodCgpID8/IChjb21wLmxheW91dD8uaGVpZ2h0ID8gcGFyc2VJbnQoY29tcC5sYXlvdXQuaGVpZ2h0LCAxMCkgOiA1OCk7XG4gICAgcmV0dXJuIGAke3NwYW59IGNvbHMgw5cgJHtoZWlnaHR9cHhgO1xuICB9XG5cbiAgcmVhZG9ubHkgZ2V0Q29tcG9uZW50SWNvbk5hbWUgPSBnZXRDb21wb25lbnRJY29uTmFtZTtcblxuICBvblNlbGVjdChpZDogc3RyaW5nLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW55UmVzaXppbmcoKSkgcmV0dXJuO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoaWQpO1xuICB9XG5cbiAgYWRqdXN0U3Bhbihjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLCBkZWx0YTogbnVtYmVyLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmdldFNwYW4oY29tcCk7XG4gICAgY29uc3QgbmV4dCA9IE1hdGgubWF4KDEsIE1hdGgubWluKHRoaXMudG90YWxDb2x1bW5zKCksIGN1cnJlbnQgKyBkZWx0YSkpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVDb21wb25lbnRMYXlvdXQoY29tcC5pZCwgeyBjb2x1bW5TcGFuOiBuZXh0IH0pO1xuICB9XG5cbiAgb25EdXBsaWNhdGUoaWQ6IHN0cmluZywgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuZHVwbGljYXRlQ29tcG9uZW50KGlkKTtcbiAgfVxuXG4gIG9uRGVsZXRlKGlkOiBzdHJpbmcsIGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnJlbW92ZUNvbXBvbmVudChpZCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duLmVzY2FwZScpXG4gIG9uRXNjYXBlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkSWQoKSkge1xuICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLnNlbGVjdENvbXBvbmVudChudWxsKTtcbiAgICB9XG4gIH1cblxuICBvbkNhbnZhc0JhY2tncm91bmRDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW55UmVzaXppbmcoKSkgcmV0dXJuO1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBpZiAoXG4gICAgICB0YXJnZXQuY2xvc2VzdCgnLmNhbnZhcy1jb21wb25lbnQtY2FyZCcpIHx8XG4gICAgICB0YXJnZXQuY2xvc2VzdCgnLmNhbnZhcy1hY3Rpb24tYnRuJykgfHxcbiAgICAgIHRhcmdldC5jbG9zZXN0KCcuY2FudmFzLWdyaWQtcHJldmlldy1ib3gnKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuc2VsZWN0Q29tcG9uZW50KG51bGwpO1xuICB9XG5cbiAgc2VsZWN0UmVwb3J0U2V0dGluZ3MoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQobnVsbCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnNldEFjdGl2ZVRhYigncmVwb3J0Jyk7XG4gIH1cblxuICBzZWxlY3RHcmlkU2V0dGluZ3MoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQobnVsbCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnNldEFjdGl2ZVRhYignZ3JpZCcpO1xuICB9XG5cbiAgc3RhcnRSZXNpemUoZXZlbnQ6IFBvaW50ZXJFdmVudCwgY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbiwgZGlyZWN0aW9uOiAnZScgfCAncycgfCAnc2UnKTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoY29tcC5pZCk7XG5cbiAgICBjb25zdCBoYW5kbGUgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgaGFuZGxlLnNldFBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG5cbiAgICBjb25zdCBjYXJkID0gaGFuZGxlLmNsb3Nlc3QoJy5jYW52YXMtY29tcG9uZW50LWNhcmQnKSBhcyBIVE1MRWxlbWVudDtcbiAgICBjb25zdCBncmlkID0gaGFuZGxlLmNsb3Nlc3QoJy5jYW52YXMtZ3JpZCcpIGFzIEhUTUxFbGVtZW50O1xuICAgIGlmICghY2FyZCB8fCAhZ3JpZCkgcmV0dXJuO1xuXG4gICAgY29uc3Qgc3RhcnRYID0gZXZlbnQuY2xpZW50WDtcbiAgICBjb25zdCBzdGFydFkgPSBldmVudC5jbGllbnRZO1xuICAgIGNvbnN0IHN0YXJ0U3BhbiA9IGNvbXAubGF5b3V0Py5jb2x1bW5TcGFuID8/IChjb21wLnR5cGUgPT09ICdidXR0b24nID8gMiA6IDQpO1xuICAgIGNvbnN0IGV4aXN0aW5nQ29tcEhlaWdodCA9IGNvbXAubGF5b3V0Py5oZWlnaHQgPyBwYXJzZUludChjb21wLmxheW91dC5oZWlnaHQsIDEwKSA6IG51bGw7XG4gICAgY29uc3Qgc3RhcnRIZWlnaHQgPSBleGlzdGluZ0NvbXBIZWlnaHQgPz8gTWF0aC5tYXgoMzgsIGNhcmQub2Zmc2V0SGVpZ2h0IC0gQ0FOVkFTX0NBUkRfT1ZFUkhFQUQpO1xuICAgIGNvbnN0IHRvdGFsQ29scyA9IHRoaXMudG90YWxDb2x1bW5zKCk7XG4gICAgY29uc3QgZ2FwID0gdGhpcy5kZWZpbml0aW9uKCkubGF5b3V0LmdhcCA/PyAxNjtcbiAgICBjb25zdCBjb2xXaWR0aCA9IChncmlkLm9mZnNldFdpZHRoIC0gKHRvdGFsQ29scyAtIDEpICogZ2FwKSAvIHRvdGFsQ29scztcblxuICAgIHRoaXMucmVzaXppbmdDb21wSWQuc2V0KGNvbXAuaWQpO1xuICAgIHRoaXMucmVzaXppbmdTcGFuLnNldChzdGFydFNwYW4pO1xuICAgIHRoaXMucmVzaXppbmdIZWlnaHQuc2V0KHN0YXJ0SGVpZ2h0KTtcblxuICAgIGxldCBjdXJyZW50U3BhbiA9IHN0YXJ0U3BhbjtcbiAgICBsZXQgY3VycmVudEhlaWdodCA9IHN0YXJ0SGVpZ2h0O1xuXG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9IChtb3ZlRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ2UnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlJykge1xuICAgICAgICBjb25zdCBkZWx0YVggPSBtb3ZlRXZlbnQuY2xpZW50WCAtIHN0YXJ0WDtcbiAgICAgICAgY3VycmVudFNwYW4gPSBjYWxjdWxhdGVTbmFwcGVkU3BhbihkZWx0YVgsIHN0YXJ0U3BhbiwgY29sV2lkdGgsIGdhcCwgdG90YWxDb2xzKTtcbiAgICAgICAgdGhpcy5yZXNpemluZ1NwYW4uc2V0KGN1cnJlbnRTcGFuKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ3MnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlJykge1xuICAgICAgICBjb25zdCBkZWx0YVkgPSBtb3ZlRXZlbnQuY2xpZW50WSAtIHN0YXJ0WTtcbiAgICAgICAgY29uc3QgbmF0dXJhbE1pbiA9IE1hdGgubWF4KDM4LCBnZXRDb21wb25lbnROYXR1cmFsTWluSGVpZ2h0KGNvbXAudHlwZSkpO1xuICAgICAgICBjdXJyZW50SGVpZ2h0ID0gY2FsY3VsYXRlU25hcHBlZEhlaWdodChkZWx0YVksIHN0YXJ0SGVpZ2h0LCBuYXR1cmFsTWluKTtcbiAgICAgICAgdGhpcy5yZXNpemluZ0hlaWdodC5zZXQoY3VycmVudEhlaWdodCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IG9uUG9pbnRlclVwID0gKHVwRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaGFuZGxlLnJlbGVhc2VQb2ludGVyQ2FwdHVyZSh1cEV2ZW50LnBvaW50ZXJJZCk7XG4gICAgICB9IGNhdGNoIHt9XG5cbiAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgaGFuZGxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIG9uUG9pbnRlclVwKTtcbiAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgb25Qb2ludGVyVXApO1xuXG4gICAgICBjb25zdCBsYXlvdXRDaGFuZ2VzOiBQYXJ0aWFsPENvbXBvbmVudExheW91dERlZmluaXRpb24+ID0ge307XG4gICAgICBpZiAoZGlyZWN0aW9uID09PSAnZScgfHwgZGlyZWN0aW9uID09PSAnc2UnKSB7XG4gICAgICAgIGxheW91dENoYW5nZXMuY29sdW1uU3BhbiA9IGN1cnJlbnRTcGFuO1xuICAgICAgfVxuICAgICAgY29uc3QgZGVsdGFZID0gTWF0aC5hYnModXBFdmVudC5jbGllbnRZIC0gc3RhcnRZKTtcbiAgICAgIGlmIChkaXJlY3Rpb24gPT09ICdzJyB8fCAoZGlyZWN0aW9uID09PSAnc2UnICYmIGRlbHRhWSA+IDE2KSkge1xuICAgICAgICBsYXlvdXRDaGFuZ2VzLmhlaWdodCA9IGAke2N1cnJlbnRIZWlnaHR9cHhgO1xuICAgICAgICBsYXlvdXRDaGFuZ2VzLm1pbkhlaWdodCA9IGAke2N1cnJlbnRIZWlnaHR9cHhgO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlQ29tcG9uZW50TGF5b3V0KGNvbXAuaWQsIGxheW91dENoYW5nZXMpO1xuXG4gICAgICB0aGlzLnJlc2l6aW5nQ29tcElkLnNldChudWxsKTtcbiAgICAgIHRoaXMucmVzaXppbmdTcGFuLnNldChudWxsKTtcbiAgICAgIHRoaXMucmVzaXppbmdIZWlnaHQuc2V0KG51bGwpO1xuICAgIH07XG5cbiAgICBoYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBvblBvaW50ZXJNb3ZlKTtcbiAgICBoYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgb25Qb2ludGVyVXApO1xuICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgb25Qb2ludGVyVXApO1xuICB9XG5cbiAgcmVzZXREaW1lbnNpb25zKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24sIGV2ZW50PzogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudCkge1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgICBjb25zdCBkZWZhdWx0U3BhbiA9IGNvbXAudHlwZSA9PT0gJ2J1dHRvbicgPyAyIDogNDtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlQ29tcG9uZW50TGF5b3V0KGNvbXAuaWQsIHtcbiAgICAgIGNvbHVtblNwYW46IGRlZmF1bHRTcGFuLFxuICAgICAgaGVpZ2h0OiB1bmRlZmluZWQsXG4gICAgICBtaW5IZWlnaHQ6IHVuZGVmaW5lZCxcbiAgICAgIHdpZHRoOiB1bmRlZmluZWQsXG4gICAgfSk7XG4gIH1cblxuICBvbkRyb3AoZXZlbnQ6IENka0RyYWdEcm9wPFJlcG9ydENvbXBvbmVudERlZmluaXRpb25bXSwgdW5rbm93biwgdW5rbm93bj4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0FueVJlc2l6aW5nKCkpIHJldHVybjtcblxuICAgIGlmIChldmVudC5wcmV2aW91c0NvbnRhaW5lciA9PT0gZXZlbnQuY29udGFpbmVyKSB7XG4gICAgICAvLyBSZW9yZGVyaW5nIHdpdGhpbiBjYW52YXNcbiAgICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5tb3ZlQ29tcG9uZW50KGV2ZW50LnByZXZpb3VzSW5kZXgsIGV2ZW50LmN1cnJlbnRJbmRleCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERyYWdnZWQgZnJvbSBwYWxldHRlIGludG8gY2FudmFzXG4gICAgICBjb25zdCByYXdEYXRhID0gZXZlbnQuaXRlbS5kYXRhIGFzIHN0cmluZyB8IHsgdHlwZT86IHN0cmluZyB9IHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgY29tcG9uZW50VHlwZSA9IHR5cGVvZiByYXdEYXRhID09PSAnc3RyaW5nJyA/IHJhd0RhdGEgOiByYXdEYXRhPy50eXBlO1xuICAgICAgaWYgKGNvbXBvbmVudFR5cGUpIHtcbiAgICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLmFkZENvbXBvbmVudChjb21wb25lbnRUeXBlLCBldmVudC5jdXJyZW50SW5kZXgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFkZFJlc3VsdEdyaWQoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGV4aXN0aW5nRHMgPSB0aGlzLmRlZmluaXRpb24oKS5kYXRhU291cmNlc1swXTtcbiAgICBjb25zdCBkZWZhdWx0R3JpZDogUmVwb3J0R3JpZERlZmluaXRpb24gPSB7XG4gICAgICBkYXRhU291cmNlSWQ6IGV4aXN0aW5nRHM/LmlkID8/ICdkZWZhdWx0JyxcbiAgICAgIGNvbHVtbnM6IFtcbiAgICAgICAgeyBmaWVsZDogJ2lkJywgbGFiZWw6ICdJRCcsIGRhdGFUeXBlOiAnbnVtYmVyJywgdmlzaWJsZTogdHJ1ZSwgc29ydGFibGU6IHRydWUgfSxcbiAgICAgICAgeyBmaWVsZDogJ25hbWUnLCBsYWJlbDogJ05hbWUnLCBkYXRhVHlwZTogJ3N0cmluZycsIHZpc2libGU6IHRydWUsIHNvcnRhYmxlOiB0cnVlIH0sXG4gICAgICBdLFxuICAgICAgb3B0aW9uczoge1xuICAgICAgICBwYWdpbmF0aW9uOiB0cnVlLFxuICAgICAgICBwYWdlU2l6ZTogMjUsXG4gICAgICAgIHNob3dSb3dOdW1iZXJzOiB0cnVlLFxuICAgICAgICBzaG93Rm9vdGVyOiB0cnVlLFxuICAgICAgICBzaWRlQmFyOiB0cnVlLFxuICAgICAgICBnbG9iYWxTZWFyY2g6IHRydWUsXG4gICAgICAgIHN0YXR1c0JhcjogdHJ1ZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlR3JpZFNldHRpbmdzKGRlZmF1bHRHcmlkKTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuc2VsZWN0Q29tcG9uZW50KG51bGwpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZXRBY3RpdmVUYWIoJ2dyaWQnKTtcbiAgfVxuXG4gIGV4ZWN1dGVDYW52YXNSZXBvcnQoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50KSBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoIXRoaXMuZGVmaW5pdGlvbigpLmdyaWQpIHtcbiAgICAgIHRoaXMuYWRkUmVzdWx0R3JpZCgpO1xuICAgIH1cblxuICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSB0aGlzLmNhbnZhc0Zvcm0oKS5nZXRSYXdWYWx1ZSgpO1xuICAgIGNvbnN0IG1pc3NpbmcgPSB0aGlzLmV4ZWN1dGlvblNlcnZpY2UuZ2V0TWlzc2luZ0ZpZWxkcyh0aGlzLmRlZmluaXRpb24oKSwgZm9ybVZhbHVlcyk7XG4gICAgaWYgKG1pc3NpbmcubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5ncmlkRXhlY0Vycm9yLnNldCgnTWlzc2luZyByZXF1aXJlZCBmaWx0ZXIgdmFsdWVzOiAnICsgbWlzc2luZy5qb2luKCcsICcpICsgJy4gUGxlYXNlIGVudGVyIHZhbHVlcyBhYm92ZSB0byBydW4uJyk7XG4gICAgICB0aGlzLmhpZ2hsaWdodE1pc3NpbmdGaWVsZHMobWlzc2luZyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5pc0V4ZWN1dGluZ0dyaWQuc2V0KHRydWUpO1xuICAgIHRoaXMuZ3JpZEV4ZWNFcnJvci5zZXQobnVsbCk7XG5cbiAgICB0aGlzLmV4ZWN1dGlvblNlcnZpY2UuZXhlY3V0ZSh0aGlzLmRlZmluaXRpb24oKSwgZm9ybVZhbHVlcykuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyb3dzOiB1bmtub3duW10pID0+IHtcbiAgICAgICAgdGhpcy5jYW52YXNHcmlkRGF0YS5zZXQocm93cyB8fCBbXSk7XG4gICAgICAgIHRoaXMuaXNFeGVjdXRpbmdHcmlkLnNldChmYWxzZSk7XG4gICAgICB9LFxuICAgICAgZXJyb3I6IChlcnI6IHVua25vd24pID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignW0Rlc2lnbkNhbnZhc10gUXVlcnkgZXhlY3V0aW9uIGVycm9yOicsIGVycik7XG4gICAgICAgIGNvbnN0IG1zZyA9IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKTtcbiAgICAgICAgdGhpcy5ncmlkRXhlY0Vycm9yLnNldChtc2cgfHwgJ0V4ZWN1dGlvbiBmYWlsZWQnKTtcbiAgICAgICAgdGhpcy5pc0V4ZWN1dGluZ0dyaWQuc2V0KGZhbHNlKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBvbkNhbnZhc0J1dHRvbkNsaWNrKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24sIGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgYWN0aW9uID0gKGNvbXAucHJvcGVydGllcz8uWydhY3Rpb24nXSBhcyBzdHJpbmcpIHx8ICdleGVjdXRlLXJlcG9ydCc7XG4gICAgaWYgKGFjdGlvbiA9PT0gJ2V4ZWN1dGUtcmVwb3J0Jykge1xuICAgICAgdGhpcy5leGVjdXRlQ2FudmFzUmVwb3J0KCk7XG4gICAgfSBlbHNlIGlmIChhY3Rpb24gPT09ICdyZXNldCcpIHtcbiAgICAgIHRoaXMuY2FudmFzRm9ybSgpLnJlc2V0KCk7XG4gICAgICB0aGlzLmNhbnZhc0dyaWREYXRhLnNldChbXSk7XG4gICAgfSBlbHNlIGlmIChhY3Rpb24gPT09ICdleHBvcnQnKSB7XG4gICAgICB0aGlzLmdyaWRFeGVjRXJyb3Iuc2V0KCfwn5KhIEV4cG9ydCBhY3Rpb24gaXMgY29uZmlndXJlZC4gUnVuIHRoZSByZXBvcnQgYW5kIHN3aXRjaCB0byBSdW50aW1lIHZpZXcgdG8gZG93bmxvYWQgZmlsZXMuJyk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuZ3JpZEV4ZWNFcnJvci5zZXQobnVsbCksIDQwMDApO1xuICAgIH0gZWxzZSBpZiAoYWN0aW9uID09PSAncHJpbnQtcmVwb3J0Jykge1xuICAgICAgdGhpcy5ncmlkRXhlY0Vycm9yLnNldCgn8J+SoSBQcmludCBSZXBvcnQgYWN0aW9uIGlzIGNvbmZpZ3VyZWQuIFN3aXRjaCB0byBSdW50aW1lIHZpZXcgdG8gc3VibWl0IHRvIHByaW50IHNlcnZpY2UuJyk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuZ3JpZEV4ZWNFcnJvci5zZXQobnVsbCksIDQwMDApO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmdyaWRGaWx0ZXJEZWJvdW5jZVRpbWVyKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5ncmlkRmlsdGVyRGVib3VuY2VUaW1lcik7XG4gICAgICB0aGlzLmdyaWRGaWx0ZXJEZWJvdW5jZVRpbWVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBvbkNhbnZhc0dyaWRTdGF0ZUNoYW5nZShzdGF0ZTogYW55KTogdm9pZCB7XG4gICAgaWYgKCFzdGF0ZSB8fCAhdGhpcy5kZWZpbml0aW9uKCkuZ3JpZCkgcmV0dXJuO1xuICAgIGNvbnN0IGN1cnJlbnRHcmlkID0gdGhpcy5kZWZpbml0aW9uKCkuZ3JpZCE7XG5cbiAgICAvLyBBdm9pZCBkaXJ0eSBjaHVybiBhbmQgZXZlbnQgbG9vcHMgaWYgc3RhdGUgaGFzIG5vdCBjaGFuZ2VkXG4gICAgY29uc3QgY3VycmVudFNlcmlhbGl6ZWQgPSBKU09OLnN0cmluZ2lmeShjdXJyZW50R3JpZC5vcHRpb25zPy5yZXBvcnRTdGF0ZSA/PyBudWxsKTtcbiAgICBjb25zdCBuZXdTZXJpYWxpemVkID0gSlNPTi5zdHJpbmdpZnkoc3RhdGUgPz8gbnVsbCk7XG4gICAgaWYgKGN1cnJlbnRTZXJpYWxpemVkID09PSBuZXdTZXJpYWxpemVkKSByZXR1cm47XG5cbiAgICAvLyBEaXN0aW5ndWlzaCBiZXR3ZWVuIHRydWUgc3RydWN0dXJhbCBsYXlvdXQgY2hhbmdlcyAoZ3JvdXBNb2RlbCwgc29ydE1vZGVsKVxuICAgIC8vIHZzIGludGVyYWN0aXZlIGNvbHVtbiBkYXRhIGZpbHRlcmluZyAoYWN0aXZlRmlsdGVycywgY29uZGl0aW9uRmlsdGVycykuXG4gICAgY29uc3QgY3VycmVudEdyb3VwID0gSlNPTi5zdHJpbmdpZnkoY3VycmVudEdyaWQub3B0aW9ucz8uZ3JvdXBNb2RlbCA/PyBbXSk7XG4gICAgY29uc3QgbmV3R3JvdXAgPSBKU09OLnN0cmluZ2lmeShzdGF0ZS5ncm91cE1vZGVsID8/IFtdKTtcbiAgICBjb25zdCBjdXJyZW50U29ydCA9IEpTT04uc3RyaW5naWZ5KGN1cnJlbnRHcmlkLm9wdGlvbnM/LnNvcnRNb2RlbCA/PyBbXSk7XG4gICAgY29uc3QgbmV3U29ydCA9IEpTT04uc3RyaW5naWZ5KHN0YXRlLnNvcnRNb2RlbCA/PyBbXSk7XG4gICAgY29uc3QgaXNMYXlvdXRDaGFuZ2UgPSBjdXJyZW50R3JvdXAgIT09IG5ld0dyb3VwIHx8IGN1cnJlbnRTb3J0ICE9PSBuZXdTb3J0O1xuXG4gICAgY29uc3QgdXBkYXRlZE9wdGlvbnMgPSB7XG4gICAgICAuLi4oY3VycmVudEdyaWQub3B0aW9ucyB8fCB7fSksXG4gICAgICBncm91cE1vZGVsOiBzdGF0ZS5ncm91cE1vZGVsID8/IGN1cnJlbnRHcmlkLm9wdGlvbnM/Lmdyb3VwTW9kZWwsXG4gICAgICBzb3J0TW9kZWw6IHN0YXRlLnNvcnRNb2RlbCA/PyBjdXJyZW50R3JpZC5vcHRpb25zPy5zb3J0TW9kZWwsXG4gICAgICByZXBvcnRTdGF0ZTogc3RhdGUsXG4gICAgfTtcblxuICAgIGlmIChpc0xheW91dENoYW5nZSkge1xuICAgICAgLy8gQ2xlYXIgYW55IHBlbmRpbmcgZGVib3VuY2VkIGZpbHRlciB1cGRhdGVcbiAgICAgIGlmICh0aGlzLmdyaWRGaWx0ZXJEZWJvdW5jZVRpbWVyKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmdyaWRGaWx0ZXJEZWJvdW5jZVRpbWVyKTtcbiAgICAgICAgdGhpcy5ncmlkRmlsdGVyRGVib3VuY2VUaW1lciA9IG51bGw7XG4gICAgICB9XG4gICAgICB0aGlzLnBlbmRpbmdHcmlkU3RhdGUgPSBudWxsO1xuXG4gICAgICAvLyBHcm91cGluZyBvciBzb3J0aW5nIGNoYW5nZWQg4oCUIHVwZGF0ZSBsYXlvdXQgaW1tZWRpYXRlbHkgYW5kIHNob3cgdmlzdWFsIGluZGljYXRvclxuICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUdyaWRTZXR0aW5ncyh7XG4gICAgICAgIC4uLmN1cnJlbnRHcmlkLFxuICAgICAgICBvcHRpb25zOiB1cGRhdGVkT3B0aW9ucyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5sYXlvdXRKdXN0VXBkYXRlZC5zZXQodHJ1ZSk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMubGF5b3V0SnVzdFVwZGF0ZWQuc2V0KGZhbHNlKSwgMTIwMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFB1cmUgY29sdW1uIGZpbHRlciBhZGp1c3RtZW50IChhY3RpdmVGaWx0ZXJzIC8gY29uZGl0aW9uRmlsdGVycykuXG4gICAgICAvLyAxLiBEbyBOT1QgdHJpZ2dlciB0aGUgXCJMYXlvdXQgYXV0by1wZXJzaXN0ZWRcIiBpbmRpY2F0b3IgKGZpbHRlcmluZyByb3dzIGlzIG5vdCBhIGxheW91dCBjaGFuZ2UpLlxuICAgICAgLy8gMi4gRGVib3VuY2Ugc2F2aW5nIHRoZSBzdGF0ZSB3aXRoIHNraXBIaXN0b3J5IHNvIHR5cGluZyBvciBjaGVja2luZyBib3hlc1xuICAgICAgLy8gICAgZG9lcyBub3QgZmxvb2QgdW5kbyBoaXN0b3J5IG9yIGludGVycnVwdCBjb2x1bW4gZmlsdGVyIGludGVyYWN0aW9uLlxuICAgICAgdGhpcy5wZW5kaW5nR3JpZFN0YXRlID0gc3RhdGU7XG4gICAgICBpZiAodGhpcy5ncmlkRmlsdGVyRGVib3VuY2VUaW1lcikge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5ncmlkRmlsdGVyRGVib3VuY2VUaW1lcik7XG4gICAgICB9XG4gICAgICB0aGlzLmdyaWRGaWx0ZXJEZWJvdW5jZVRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZ3JpZEZpbHRlckRlYm91bmNlVGltZXIgPSBudWxsO1xuICAgICAgICBpZiAoIXRoaXMucGVuZGluZ0dyaWRTdGF0ZSB8fCAhdGhpcy5kZWZpbml0aW9uKCkuZ3JpZCkgcmV0dXJuO1xuICAgICAgICBjb25zdCBsYXRlc3RHcmlkID0gdGhpcy5kZWZpbml0aW9uKCkuZ3JpZCE7XG4gICAgICAgIGNvbnN0IGxhdGVzdE9wdGlvbnMgPSB7XG4gICAgICAgICAgLi4uKGxhdGVzdEdyaWQub3B0aW9ucyB8fCB7fSksXG4gICAgICAgICAgcmVwb3J0U3RhdGU6IHRoaXMucGVuZGluZ0dyaWRTdGF0ZSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wZW5kaW5nR3JpZFN0YXRlID0gbnVsbDtcbiAgICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUdyaWRTZXR0aW5ncyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5sYXRlc3RHcmlkLFxuICAgICAgICAgICAgb3B0aW9uczogbGF0ZXN0T3B0aW9ucyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgc2tpcEhpc3Rvcnk6IHRydWUgfVxuICAgICAgICApO1xuICAgICAgfSwgMTIwMCk7XG4gICAgfVxuICB9XG5cbiAgb25DYW52YXNDb2x1bW5EZWZzQ2hhbmdlKGRlZnM6IGFueVtdKTogdm9pZCB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGRlZnMpIHx8ICF0aGlzLmRlZmluaXRpb24oKS5ncmlkKSByZXR1cm47XG4gICAgY29uc3QgY3VycmVudEdyaWQgPSB0aGlzLmRlZmluaXRpb24oKS5ncmlkITtcbiAgICBsZXQgYW55Q2hhbmdlZCA9IGZhbHNlO1xuXG4gICAgY29uc3QgdXBkYXRlZENvbHMgPSBjdXJyZW50R3JpZC5jb2x1bW5zLm1hcCgoYykgPT4ge1xuICAgICAgY29uc3QgbWF0Y2ggPSBkZWZzLmZpbmQoKGQ6IGFueSkgPT4gZC5maWVsZCA9PT0gYy5maWVsZCk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgY29uc3QgbmV3V2lkdGggPSBtYXRjaC53aWR0aCA/IGAke21hdGNoLndpZHRofXB4YCA6IGMud2lkdGg7XG4gICAgICAgIGNvbnN0IG5ld1Zpc2libGUgPSBtYXRjaC5oaWRlICE9PSB0cnVlO1xuICAgICAgICBpZiAobmV3V2lkdGggIT09IGMud2lkdGggfHwgbmV3VmlzaWJsZSAhPT0gYy52aXNpYmxlKSB7XG4gICAgICAgICAgYW55Q2hhbmdlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5jLFxuICAgICAgICAgIHdpZHRoOiBuZXdXaWR0aCxcbiAgICAgICAgICB2aXNpYmxlOiBuZXdWaXNpYmxlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGM7XG4gICAgfSk7XG5cbiAgICAvLyBJZiBubyBjb2x1bW4gd2lkdGhzIG9yIHZpc2liaWxpdGllcyBhY3R1YWxseSBjaGFuZ2VkLCBkbyBub3QgdHJpZ2dlciBhdXRvLXBlcnNpc3RcbiAgICBpZiAoIWFueUNoYW5nZWQpIHJldHVybjtcblxuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVHcmlkU2V0dGluZ3Moe1xuICAgICAgLi4uY3VycmVudEdyaWQsXG4gICAgICBjb2x1bW5zOiB1cGRhdGVkQ29scyxcbiAgICB9KTtcbiAgICB0aGlzLmxheW91dEp1c3RVcGRhdGVkLnNldCh0cnVlKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMubGF5b3V0SnVzdFVwZGF0ZWQuc2V0KGZhbHNlKSwgMTIwMCk7XG4gIH1cblxuICByZW1vdmVHcmlkKGV2ZW50PzogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50Py5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlR3JpZFNldHRpbmdzKHVuZGVmaW5lZCk7XG4gIH1cblxuICBhcHBseUJsdWVwcmludChibHVlcHJpbnRJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgbmV3RGVmID0gdGhpcy50ZW1wbGF0ZVNlcnZpY2UuaW5zdGFudGlhdGVUZW1wbGF0ZShibHVlcHJpbnRJZCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLmxvYWREZWZpbml0aW9uKG5ld0RlZik7XG4gIH1cblxuICBhZGRTdGFydGVyQ29tcG9uZW50KHR5cGU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5hZGRDb21wb25lbnQodHlwZSk7XG4gIH1cbn1cbiIsIiAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLXdyYXBwZXJcIiAoY2xpY2spPVwib25DYW52YXNCYWNrZ3JvdW5kQ2xpY2soJGV2ZW50KVwiPlxuICAgICAgPCEtLSBDYW52YXMgU3RhdHVzIC8gUXVpY2sgQ29udHJvbHMgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLXRvb2xiYXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1pbmZvXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbmZvLWxhYmVsXCI+R3JpZCBMYXlvdXQ6PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5mby12YWx1ZVwiPnt7IHRvdGFsQ29sdW1ucygpIH19IENvbHVtbnM8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbmZvLWRpdmlkZXJcIj7igKI8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbmZvLWxhYmVsXCI+Q29tcG9uZW50czo8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbmZvLXZhbHVlXCI+e3sgY29tcG9uZW50cygpLmxlbmd0aCB9fTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImluZm8tZGl2aWRlclwiPuKAojwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImxpdmUtbW9kZS1iYWRnZVwiIHRpdGxlPVwiSW50ZXJhY3RpdmUgY2FudmFzOiBWYWx1ZXMgdHlwZWQgaGVyZSBydW4gbGl2ZSBxdWVyaWVzIGFuZCB0ZXN0IGRyb3Bkb3ducy5cIj5cbiAgICAgICAgICAgIOKaoSBMaXZlIEludGVyYWN0aXZlIE1vZGVcbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtYWN0aW9uc1wiPlxuICAgICAgICAgIEBpZiAoIWRlZmluaXRpb24oKS5ncmlkKSB7XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1hY3Rpb24tYnRuIGJ0bi1ncmlkLWFkZFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJhZGRSZXN1bHRHcmlkKCRldmVudClcIlxuICAgICAgICAgICAgICB0aXRsZT1cIkFkZCBhIFJlc3VsdCBHcmlkIHRvIHRoaXMgcmVwb3J0XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0YWJsZVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgPHNwYW4+KyBBZGQgR3JpZDwvc3Bhbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtYWN0aW9uLWJ0biBidG4tZ3JpZC1jb25maWd1cmVkXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdEdyaWRTZXR0aW5ncygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJDb25maWd1cmUgUmVzdWx0IERhdGEgR3JpZFwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwidGFibGVcIiBbc2l6ZV09XCIxNFwiIC8+XG4gICAgICAgICAgICAgIDxzcGFuPkdyaWQgKHt7IGRlZmluaXRpb24oKS5ncmlkPy5jb2x1bW5zPy5sZW5ndGggPz8gMCB9fSk8L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWFjdGlvbi1idG5cIlxuICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFJlcG9ydFNldHRpbmdzKCRldmVudClcIlxuICAgICAgICAgICAgdGl0bGU9XCJDb25maWd1cmUgUGFnZSBMYXlvdXQgJiBHcmlkIFNldHRpbmdzXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInNldHRpbmdzXCIgW3NpemVdPVwiMTRcIiAvPlxuICAgICAgICAgICAgPHNwYW4+UmVwb3J0IFNldHRpbmdzPC9zcGFuPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIENhbnZhcyBEcm9wIEFyZWEgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLXNjcm9sbC1hcmVhXCI+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzcz1cImNhbnZhcy1hcnRib2FyZFwiXG4gICAgICAgICAgW3N0eWxlLnBhZGRpbmcucHhdPVwiZGVmaW5pdGlvbigpLmxheW91dC5wYWRkaW5nID8/IDI0XCJcbiAgICAgICAgPlxuICAgICAgICAgIDwhLS0gUmVwb3J0IEhlYWRlciBQcmV2aWV3IC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtcmVwb3J0LWhlYWRlclwiPlxuICAgICAgICAgICAgPGgyIGNsYXNzPVwiY2FudmFzLXJlcG9ydC10aXRsZVwiPnt7IGRlZmluaXRpb24oKS5uYW1lIHx8ICdVbnRpdGxlZCBSZXBvcnQnIH19PC9oMj5cbiAgICAgICAgICAgIEBpZiAoZGVmaW5pdGlvbigpLmRlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgIDxwIGNsYXNzPVwiY2FudmFzLXJlcG9ydC1kZXNjXCI+e3sgZGVmaW5pdGlvbigpLmRlc2NyaXB0aW9uIH19PC9wPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBDb21wb25lbnQgRHJvcCBMaXN0IEdyaWQgd2l0aCAyRCBtaXhlZCBvcmllbnRhdGlvbiBhbmQgZGF0YSBiaW5kaW5nIC0tPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNka0Ryb3BMaXN0XG4gICAgICAgICAgICBpZD1cImRlc2lnbmVyLWNhbnZhcy1kcm9wLWxpc3RcIlxuICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtZ3JpZFwiXG4gICAgICAgICAgICBjZGtEcm9wTGlzdE9yaWVudGF0aW9uPVwibWl4ZWRcIlxuICAgICAgICAgICAgW2Nka0Ryb3BMaXN0RGF0YV09XCJzb3J0ZWRDb21wb25lbnRzKClcIlxuICAgICAgICAgICAgW3N0eWxlLmdyaWQtdGVtcGxhdGUtY29sdW1uc109XCJncmlkVGVtcGxhdGVDb2x1bW5zKClcIlxuICAgICAgICAgICAgW3N0eWxlLmdhcC5weF09XCJkZWZpbml0aW9uKCkubGF5b3V0LmdhcCA/PyAxNlwiXG4gICAgICAgICAgICAoY2RrRHJvcExpc3REcm9wcGVkKT1cIm9uRHJvcCgkZXZlbnQpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBAZm9yIChjb21wIG9mIHNvcnRlZENvbXBvbmVudHMoKTsgdHJhY2sgY29tcC5pZDsgbGV0IGlkeCA9ICRpbmRleCkge1xuICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgY2RrRHJhZ1xuICAgICAgICAgICAgICAgIFtjZGtEcmFnRGF0YV09XCJjb21wXCJcbiAgICAgICAgICAgICAgICBbY2RrRHJhZ0Rpc2FibGVkXT1cImlzQW55UmVzaXppbmcoKVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtY29tcG9uZW50LWNhcmRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1zZWxlY3RlZF09XCJpc1NlbGVjdGVkKGNvbXAuaWQpXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuaXMtcmVzaXppbmddPVwicmVzaXppbmdDb21wSWQoKSA9PT0gY29tcC5pZFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmlzLWZpZWxkLWhpZ2hsaWdodGVkXT1cImlzRmllbGRIaWdobGlnaHRlZChjb21wKVwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmlzLW5hcnJvd109XCJnZXRTcGFuKGNvbXApIDw9IDRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1jb21wYWN0XT1cImdldFNwYW4oY29tcCkgPD0gMlwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmdyaWQtY29sdW1uXT1cImdldEdyaWRDb2x1bW4oY29tcClcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5ncmlkLXJvd109XCJnZXRHcmlkUm93KGNvbXApXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiY29tcC5sYXlvdXQ/LndpZHRoIHx8ICdhdXRvJ1wiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmhlaWdodF09XCJnZXRDb21wb25lbnRIZWlnaHQoY29tcClcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5taW4taGVpZ2h0XT1cImdldENvbXBvbmVudE1pbkhlaWdodChjb21wKVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uU2VsZWN0KGNvbXAuaWQsICRldmVudClcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPCEtLSBDYXJkIEhlYWRlciB3aXRoIERyYWcgSGFuZGxlICYgQWN0aW9ucyAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLXRpdGxlLWdyb3VwXCIgY2RrRHJhZ0hhbmRsZSB0aXRsZT1cIkRyYWcgdG8gcmVvcmRlclwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRyYWctaGFuZGxlLWRvdHNcIj7ii67ii648L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBbbmFtZV09XCJnZXRDb21wb25lbnRJY29uTmFtZShjb21wLnR5cGUpXCIgW3NpemVdPVwiMTRcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbXAtdGl0bGVcIiBbdGl0bGVdPVwiY29tcC5sYWJlbCB8fCBjb21wLmtleSB8fCBjb21wLnR5cGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBjb21wLmxhYmVsIHx8IGNvbXAua2V5IHx8IGNvbXAudHlwZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtYWN0aW9uc1wiPlxuICAgICAgICAgICAgICAgICAgICA8IS0tIFN0YXRpYyBzcGFuIHBpbGwgJiBuZXcgcm93IC8gc3RhcnQgY29sIHBpbGwgd2hlbiBub3QgaG92ZXJlZCAvIG5vdCBzZWxlY3RlZCAtLT5cbiAgICAgICAgICAgICAgICAgICAgQGlmIChjb21wLmxheW91dD8uY29sdW1uOyBhcyBjb2wpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5ldy1yb3ctcGlsbC1zdGF0aWNcIiB0aXRsZT1cIlN0YXJ0cyBhdCBDb2x1bW4ge3sgY29sIH19XCI+Q29sIHt7IGNvbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoY29tcC5sYXlvdXQ/Lm5ld1Jvdykge1xuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibmV3LXJvdy1waWxsLXN0YXRpY1wiIHRpdGxlPVwiU3RhcnRzIG9uIHNlcGFyYXRlIHJvd1wiPuKGsyBSb3c8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNwYW4tcGlsbC1zdGF0aWNcIlxuICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQ29sdW1uIHNwYW46IHt7IGdldFNwYW4oY29tcCkgfX0gb2Yge3sgdG90YWxDb2x1bW5zKCkgfX0gY29sdW1uc1wiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBnZXRTcGFuKGNvbXApIH19L3t7IHRvdGFsQ29sdW1ucygpIH19XG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIFF1aWNrIEFjdGlvbiBTdGVwcGVyICYgQnV0dG9ucyAocmV2ZWFsZWQgb24gaG92ZXIgb3Igc2VsZWN0aW9uKSAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtcXVpY2stY29udHJvbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY2FyZC1hY3Rpb24tYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5idG4tYWN0aXZlLXRvZ2dsZV09XCJjb21wLmxheW91dD8ubmV3Um93XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVOZXdSb3coY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cInt7IGNvbXAubGF5b3V0Py5uZXdSb3cgPyAnU3RhcnRzIG9uIG5ldyByb3cgKENsaWNrIHRvIHBsYWNlIGlubGluZSknIDogJ1N0YXJ0IG9uIHNlcGFyYXRlIHJvdyAoUm93IEJyZWFrKScgfX1cIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY29ybmVyLWRvd24tcmlnaHRcIiBbc2l6ZV09XCIxMVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3Bhbi1jb250cm9sLWdyb3VwXCIgdGl0bGU9XCJBZGp1c3QgQ29sdW1uIFNwYW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3Bhbi1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZ2V0U3Bhbihjb21wKSA8PSAxXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFkanVzdFNwYW4oY29tcCwgLTEsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIlNocmluayBDb2x1bW4gU3BhblwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwibWludXNcIiBbc2l6ZV09XCI5XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcGFuLWJhZGdlXCIgW3RpdGxlXT1cIidDb2x1bW4gc3BhbjogJyArIGdldFNwYW4oY29tcCkgKyAnIG9mICcgKyB0b3RhbENvbHVtbnMoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNwYW4tbnVtXCI+e3sgZ2V0U3Bhbihjb21wKSB9fTwvc3Bhbj48c3BhbiBjbGFzcz1cInNwYW4tdG90YWxcIj4ve3sgdG90YWxDb2x1bW5zKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNwYW4tYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImdldFNwYW4oY29tcCkgPj0gdG90YWxDb2x1bW5zKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYWRqdXN0U3Bhbihjb21wLCAxLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJFeHBhbmQgQ29sdW1uIFNwYW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInBsdXNcIiBbc2l6ZV09XCI5XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNhcmQtYWN0aW9uLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25EdXBsaWNhdGUoY29tcC5pZCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkR1cGxpY2F0ZSBjb21wb25lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY29weVwiIFtzaXplXT1cIjEyXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY2FyZC1hY3Rpb24tYnRuIGJ0bi1kZWxldGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uRGVsZXRlKGNvbXAuaWQsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJSZW1vdmUgY29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRyYXNoXCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBDYXJkIEJvZHkgVmlzdWFsIFByZXZpZXcgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keVwiPlxuXG4gICAgICAgICAgICAgICAgICBAc3dpdGNoIChjb21wLnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdpbnB1dCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1pbnB1dC1maWVsZFwiIChjbGljayk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stbGFiZWxcIj57eyBjb21wLmxhYmVsIHx8ICdJbnB1dCcgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGdldENhbnZhc0NvbnRyb2woY29tcCk7IGFzIGN0cmwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWFjdGl2ZS1pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImNvbXAucHJvcGVydGllcz8uWydwbGFjZWhvbGRlciddIHx8ICdFbnRlciB0ZXh0Li4uJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImN0cmxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb2N1cyk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1pbnB1dC1ib3hcIj57eyBjb21wLnByb3BlcnRpZXM/LlsncGxhY2Vob2xkZXInXSB8fCAnRW50ZXIgdGV4dC4uLicgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoJ2Ryb3Bkb3duJykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtbGl2ZS1jb250cm9sLXdyYXBwZXJcIiAoY2xpY2spPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1kcm9wZG93blxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY29uZmlnXT1cImNvbXBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1N0YXR1c109XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW3BhcmVudEZvcm1dPVwiY2FudmFzRm9ybSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2NvbnRyb2xdPVwiZ2V0Q2FudmFzQ29udHJvbChjb21wKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChkcm9wZG93bkNsaWNrKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXApXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWlucHV0LWZpZWxkXCIgKGNsaWNrKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0RhdGUnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChnZXRDYW52YXNDb250cm9sKGNvbXApOyBhcyBjdHJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJkYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1hY3RpdmUtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJjdHJsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9jdXMpPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stc2VsZWN0LWJveFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPllZWVktTU0tREQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjYWxlbmRhclwiIFtzaXplXT1cIjEyXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdkYXRlLXJhbmdlJykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtbGl2ZS1jb250cm9sLXdyYXBwZXJcIiAoY2xpY2spPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1kYXRlLXJhbmdlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjb25maWddPVwiY29tcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjb250cm9sXT1cImdldENhbnZhc0NvbnRyb2woY29tcClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1pbnB1dC1maWVsZFwiIChjbGljayk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stbGFiZWxcIj57eyBjb21wLmxhYmVsIHx8ICdOdW1iZXInIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChnZXRDYW52YXNDb250cm9sKGNvbXApOyBhcyBjdHJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWFjdGl2ZS1pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImN0cmxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb2N1cyk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1pbnB1dC1ib3hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb21wLnByb3BlcnRpZXM/LlsncHJlZml4J10gfHwgJycgfX0gMC4wMCB7eyBjb21wLnByb3BlcnRpZXM/Llsnc3VmZml4J10gfHwgJycgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdjaGVja2JveCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGVja2JveC1maWVsZFwiIChjbGljayk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGdldENhbnZhc0NvbnRyb2woY29tcCk7IGFzIGN0cmwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2FudmFzLWFjdGl2ZS1jaGVja2JveC1sYmxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgW2Zvcm1Db250cm9sXT1cImN0cmxcIiAoZm9jdXMpPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2NrLWxhYmVsXCI+e3sgY29tcC5sYWJlbCB8fCAnQ2hlY2tib3gnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1jaGVjay1ib3hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoZWNrXCIgW3NpemVdPVwiMTBcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0NoZWNrYm94JyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoJ2J1dHRvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1idG4td3JhcHBlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtb2NrLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCInYnRuLScgKyAoY29tcC5wcm9wZXJ0aWVzPy5bJ3ZhcmlhbnQnXSB8fCAncHJpbWFyeScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLm1vY2stYnRuLWZ1bGxdPVwiY29tcC5wcm9wZXJ0aWVzPy5bJ2Z1bGxXaWR0aCddID09PSB0cnVlIHx8IGNvbXAubGF5b3V0Py53aWR0aCA9PT0gJzEwMCUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLmhlaWdodF09XCJnZXRDdXN0b21CdG5IZWlnaHQoY29tcClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0Q3VzdG9tQnRuV2lkdGgoY29tcClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25DYW52YXNCdXR0b25DbGljayhjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChnZXRDdXN0b21CdG5JY29uKGNvbXApOyBhcyBidG5JY29uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIFtuYW1lXT1cImJ0bkljb25cIiBbc2l6ZV09XCIxNVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgY29tcC5sYWJlbCB8fCAnQnV0dG9uJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgna3BpLWNhcmQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2sta3BpLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1rcGktaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0tQSSBNZXRyaWMnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImtwaVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2sta3BpLXZhbHVlXCI+e3sgY29tcC5wcm9wZXJ0aWVzPy5bJ3ZhbHVlJ10gfHwgJyQxMjgsNDUwJyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2sta3BpLWZvb3RlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2sta3BpLXRyZW5kXCI+KzEyLjUlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2sta3BpLXN1YlwiPnZzIGxhc3QgcGVyaW9kPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdjaGFydCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1maWVsZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ1F1YXJ0ZXJseSBTYWxlcyBSZXZlbnVlICgkMDAwKScgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWJhcnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtY29sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtYmFyXCIgc3R5bGU9XCJoZWlnaHQ6IDQ0JVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1iYXItbGJsXCI+UTEgSmFuLU1hcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWNvbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWJhclwiIHN0eWxlPVwiaGVpZ2h0OiA2MSVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stYmFyLWxibFwiPlEyIEFwci1KdW48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1jb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1iYXJcIiBzdHlsZT1cImhlaWdodDogNzklXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2NrLWJhci1sYmxcIj5RMyBKdWwtU2VwPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtY29sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtYmFyXCIgc3R5bGU9XCJoZWlnaHQ6IDEwMCVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stYmFyLWxibFwiPlE0IE9jdC1EZWM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGRlZmF1bHQge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWdlbmVyaWMtYm94XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBjb21wLnR5cGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gUmVzaXppbmcgSGFuZGxlcyAoRWFzdCwgU291dGgsIFNvdXRoLUVhc3QpIC0tPlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwicmVzaXplLWhhbmRsZSBoYW5kbGUtZVwiXG4gICAgICAgICAgICAgICAgICAocG9pbnRlcmRvd24pPVwic3RhcnRSZXNpemUoJGV2ZW50LCBjb21wLCAnZScpXCJcbiAgICAgICAgICAgICAgICAgIChkYmxjbGljayk9XCJyZXNldERpbWVuc2lvbnMoY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICB0aXRsZT1cIkRyYWcgdG8gcmVzaXplIGNvbHVtbiB3aWR0aCDigKIgRG91YmxlLWNsaWNrIHRvIHJlc2V0XCJcbiAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyZXNpemUtaGFuZGxlIGhhbmRsZS1zXCJcbiAgICAgICAgICAgICAgICAgIChwb2ludGVyZG93bik9XCJzdGFydFJlc2l6ZSgkZXZlbnQsIGNvbXAsICdzJylcIlxuICAgICAgICAgICAgICAgICAgKGRibGNsaWNrKT1cInJlc2V0RGltZW5zaW9ucyhjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiRHJhZyB0byByZXNpemUgaGVpZ2h0IOKAoiBEb3VibGUtY2xpY2sgdG8gcmVzZXRcIlxuICAgICAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInJlc2l6ZS1oYW5kbGUgaGFuZGxlLXNlXCJcbiAgICAgICAgICAgICAgICAgIChwb2ludGVyZG93bik9XCJzdGFydFJlc2l6ZSgkZXZlbnQsIGNvbXAsICdzZScpXCJcbiAgICAgICAgICAgICAgICAgIChkYmxjbGljayk9XCJyZXNldERpbWVuc2lvbnMoY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICB0aXRsZT1cIkRyYWcgdG8gcmVzaXplIHdpZHRoIGFuZCBoZWlnaHQg4oCiIERvdWJsZS1jbGljayB0byByZXNldFwiXG4gICAgICAgICAgICAgICAgPjwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBSZXNpemluZyBEaW1lbnNpb24gR2hvc3QgLyBCYWRnZSAtLT5cbiAgICAgICAgICAgICAgICBAaWYgKHJlc2l6aW5nQ29tcElkKCkgPT09IGNvbXAuaWQpIHtcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpemUtZGltZW5zaW9uLXRvb2x0aXBcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgcmVzaXppbmdUb29sdGlwKGNvbXApIH19XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICA8IS0tIERyYWcgcGxhY2Vob2xkZXIgd2l0aCBtYXRjaGVkIGdyaWQgY29sdW1uIHNwYW4gLS0+XG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgKmNka0RyYWdQbGFjZWhvbGRlclxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtZHJhZy1wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICAgICAgICBbc3R5bGUuZ3JpZC1jb2x1bW5dPVwiZ2V0R3JpZENvbHVtbihjb21wKVwiXG4gICAgICAgICAgICAgICAgPjwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBEcmFnIHByZXZpZXcgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiAqY2RrRHJhZ1ByZXZpZXcgY2xhc3M9XCJjYW52YXMtZHJhZy1wcmV2aWV3XCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRyYWctaGFuZGxlLWRvdHNcIj7ii67ii648L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8cnB0LWljb24gW25hbWVdPVwiZ2V0Q29tcG9uZW50SWNvbk5hbWUoY29tcC50eXBlKVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicHJldmlldy10aXRsZVwiPnt7IGNvbXAubGFiZWwgfHwgY29tcC5rZXkgfHwgY29tcC50eXBlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwcmV2aWV3LXNwYW5cIj57eyBnZXRTcGFuKGNvbXApIH19L3t7IHRvdGFsQ29sdW1ucygpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgQGlmIChjb21wb25lbnRzKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtZW1wdHktc3RhdGVcIiByb2xlPVwicmVnaW9uXCIgYXJpYS1sYWJlbD1cIkVtcHR5IGNhbnZhcyBzdGFydGVyIG9wdGlvbnNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktaGVyby1iYWRnZVwiPlxuICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJkZXNpZ25cIiBbc2l6ZV09XCIyOFwiIC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwiZW1wdHktaGVyby10aXRsZVwiPlN0YXJ0IERlc2lnbmluZyBZb3VyIEN1c3RvbSBSZXBvcnQ8L2gzPlxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiZW1wdHktaGVyby1kZXNjXCI+XG4gICAgICAgICAgICAgICAgICBEcmFnIGNvbnRyb2xzIGZyb20gdGhlIGxlZnQgY29tcG9uZW50IHBhbGV0dGUsIG9yIGp1bXBzdGFydCB5b3VyIGRlc2lnbiB3aXRoIHByZS1jb25maWd1cmVkIGVudGVycHJpc2UgYmx1ZXByaW50cy5cbiAgICAgICAgICAgICAgICA8L3A+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktaGVyby1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImVtcHR5LWJ0biBlbXB0eS1idG4tcHJpbWFyeVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhcHBseUJsdWVwcmludCgnYmx1ZXByaW50LWF1ZGl0LXJlZ2lzdGVyJylcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkxvYWQgY29tcGxldGUgQXVkaXQgUmVnaXN0ZXIgYmx1ZXByaW50IHdpdGggcGFyYW1ldGVycyBhbmQgcmVzdWx0IGdyaWRcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMTVcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5BdWRpdCBSZWdpc3RlciBCbHVlcHJpbnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZW1wdHktYnRuIGVtcHR5LWJ0bi1zZWNvbmRhcnlcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlCbHVlcHJpbnQoJ2JsdWVwcmludC1rcGktc3VtbWFyeScpXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJMb2FkIEV4ZWN1dGl2ZSBLUEkgc3VtbWFyeSBibHVlcHJpbnRcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoYXJ0LWJhclwiIFtzaXplXT1cIjE1XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+S1BJIFN1bW1hcnkgQmx1ZXByaW50PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImVtcHR5LWJ0biBlbXB0eS1idG4tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRTdGFydGVyQ29tcG9uZW50KCdkYXRlLXJhbmdlJylcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkFkZCBhIERhdGUgUmFuZ2UgZmlsdGVyIGNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY2FsZW5kYXJcIiBbc2l6ZV09XCIxNFwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPisgQWRkIERhdGUgRmlsdGVyPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImVtcHR5LWJ0biBlbXB0eS1idG4tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRTdGFydGVyQ29tcG9uZW50KCdidXR0b24nKVwiXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQWRkIGFuIEV4ZWN1dGUgQWN0aW9uIGJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwicGxheVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+KyBBZGQgUnVuIEJ1dHRvbjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gTGl2ZSBSZXN1bHQgR3JpZCBQcmV2aWV3IHdpdGggQndheXMtR3JpZCBGZWF0dXJlcyAtLT5cbiAgICAgICAgICBAaWYgKGRlZmluaXRpb24oKS5ncmlkKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWdyaWQtYm94XCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkLXByZXZpZXctaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4O1wiPlxuICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0YWJsZVwiIFtzaXplXT1cIjE1XCIgLz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpZC10aXRsZVwiPkJ3YXlzIEdyaWQgKHt7IGRlZmluaXRpb24oKS5ncmlkPy5jb2x1bW5zPy5sZW5ndGggPz8gMCB9fSBjb2x1bW5zKTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIEBpZiAoaXNFeGVjdXRpbmdHcmlkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncmlkLWV4ZWMtYmFkZ2UgaXMtbG9hZGluZ1wiPkxvYWRpbmcgZGF0YSBmcm9tIGRhdGFiYXNlLi4uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoZ3JpZEV4ZWNFcnJvcigpKSB7XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpZC1leGVjLWJhZGdlIGlzLWVycm9yXCI+e3sgZ3JpZEV4ZWNFcnJvcigpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoY2FudmFzR3JpZERhdGEoKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpZC1leGVjLWJhZGdlIGlzLXN1Y2Nlc3NcIj57eyBjYW52YXNHcmlkRGF0YSgpLmxlbmd0aCB9fSByb3dzIGxvYWRlZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1jYW52YXMtcnVuLWdyaWRcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZXhlY3V0ZUNhbnZhc1JlcG9ydCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzRXhlY3V0aW5nR3JpZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJFeGVjdXRlIHF1ZXJ5IGFuZCBsb2FkIGRhdGEgaW50byBCd2F5cyBHcmlkXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJwbGF5XCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBpc0V4ZWN1dGluZ0dyaWQoKSA/ICdSdW5uaW5nLi4uJyA6ICdSdW4gLyBSZWZyZXNoIEdyaWQnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1jYW52YXMtZWRpdC1ncmlkXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdEdyaWRTZXR0aW5ncygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJDb25maWd1cmUgY29sdW1ucyBhbmQgZ3JpZCBvcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJzZXR0aW5nc1wiIFtzaXplXT1cIjExXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+Q29uZmlndXJlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1yZW1vdmUtZ3JpZFwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVHcmlkKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIlJlbW92ZSBSZXN1bHQgR3JpZCBmcm9tIHRoaXMgcmVwb3J0XCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0cmFzaFwiIFtzaXplXT1cIjEzXCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICBAaWYgKGdldEdyaWRTdW1tYXJ5VGV4dCgpOyBhcyBzdW1tYXJ5KSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtbGF5b3V0LXN0YXR1cy1zdHJpcFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtc3RhdHVzLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0YWJsZVwiIFtzaXplXT1cIjEyXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgc3VtbWFyeSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtc3RhdHVzLXN5bmNcIiBbY2xhc3MuaXMtcHVsc2luZ109XCJsYXlvdXRKdXN0VXBkYXRlZCgpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY2hlY2tcIiBbc2l6ZV09XCIxMVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPkxheW91dCBhdXRvLXBlcnNpc3RlZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgPCEtLSBMaXZlIEJ3YXlzIEdyaWQgYnJpZGdlIC0tPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWxpdmUtZ3JpZC1jb250YWluZXJcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgc3R5bGU9XCJwb3NpdGlvbjogcmVsYXRpdmU7IG1pbi1oZWlnaHQ6IDI1MHB4O1wiPlxuICAgICAgICAgICAgICAgIEBpZiAoaXNFeGVjdXRpbmdHcmlkKCkpIHtcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtZ3JpZC1sb2FkaW5nLW92ZXJsYXlcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90IGRvdC1wdWxzZVwiIHN0eWxlPVwid2lkdGg6IDE0cHg7IGhlaWdodDogMTRweDsgY29sb3I6ICMyNTYzZWI7IGJhY2tncm91bmQ6ICMyNTYzZWI7IGJvcmRlci1yYWRpdXM6IDUwJTtcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpZC1sb2FkaW5nLXRpdGxlXCI+RXhlY3V0aW5nIHN0b3JlZCBwcm9jZWR1cmUgb24gU1FMIFNlcnZlci4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncmlkLWxvYWRpbmctc3ViXCI+Q2FsY3VsYXRpbmcgb3V0c3RhbmRpbmcgYmFsYW5jZXMgYW5kIGxlZGdlciBhbW91bnRzLiBQbGVhc2Ugd2FpdC4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8cnB0LWdyaWQtYnJpZGdlXG4gICAgICAgICAgICAgICAgICBbZ3JpZERlZmluaXRpb25dPVwiZGVmaW5pdGlvbigpLmdyaWQhXCJcbiAgICAgICAgICAgICAgICAgIFtkYXRhXT1cImNhbnZhc0dyaWREYXRhKClcIlxuICAgICAgICAgICAgICAgICAgKGdyaWRTdGF0ZUNoYW5nZSk9XCJvbkNhbnZhc0dyaWRTdGF0ZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIChjb2x1bW5EZWZzQ2hhbmdlKT1cIm9uQ2FudmFzQ29sdW1uRGVmc0NoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1hZGQtZ3JpZC1iYW5uZXJcIiAoY2xpY2spPVwiYWRkUmVzdWx0R3JpZCgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGQtZ3JpZC1pY29uXCI+XG4gICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0YWJsZVwiIFtzaXplXT1cIjIwXCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGQtZ3JpZC10ZXh0XCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhZGQtZ3JpZC10aXRsZVwiPisgQWRkIFJlc3VsdCBEYXRhIEdyaWQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhZGQtZ3JpZC1zdWJcIj5BdHRhY2ggYW4gaW50ZXJhY3RpdmUgZGF0YSB0YWJsZSBvciBVbHRyYUdyaWQgdG8gZGlzcGxheSByZXBvcnQgZXhlY3V0aW9uIG91dHB1dDwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWJhbm5lci1hZGRcIj5BZGQgR3JpZDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PiJdfQ==
509
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVzaWduLWNhbnZhcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9kZXNpZ25lci9jb21wb25lbnRzL2Rlc2lnbi1jYW52YXMvZGVzaWduLWNhbnZhcy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9kZXNpZ25lci9jb21wb25lbnRzL2Rlc2lnbi1jYW52YXMvZGVzaWduLWNhbnZhcy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUNqRixPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFlBQVksRUFDWixNQUFNLEVBRU4sTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RSxPQUFPLEVBT0wsY0FBYyxHQUNmLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDN0UsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFJL0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDakYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMkRBQTJELENBQUM7QUFDN0YsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sbUVBQW1FLENBQUM7QUFDekcsT0FBTyxF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aEJVLHFCQUFxQjs0RkFBckIscUJBQXFCLCtJQ25FbEMscWh6QkF5Z0JVLDJqdUJEcGROLFlBQVksOEJBQ1osY0FBYyxzMUNBQ2QsbUJBQW1CLDY1QkFDbkIsZ0JBQWdCLHVHQUNoQixvQkFBb0IsZ0pBQ3BCLHFCQUFxQiwwRkFDckIsaUJBQWlCLG1HQUNqQix5QkFBeUI7OzRGQU9oQixxQkFBcUI7a0JBbEJqQyxTQUFTOytCQUNFLG1CQUFtQixjQUNqQixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixjQUFjO3dCQUNkLG1CQUFtQjt3QkFDbkIsZ0JBQWdCO3dCQUNoQixvQkFBb0I7d0JBQ3BCLHFCQUFxQjt3QkFDckIsaUJBQWlCO3dCQUNqQix5QkFBeUI7cUJBQzFCLG1CQUlnQix1QkFBdUIsQ0FBQyxNQUFNO3dEQStML0MsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLHlCQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlcG9ydFJlcXVlc3RTY29wZSB9IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvdXRpbHMvcmVwb3J0LXJlcXVlc3Qtc2NvcGUnO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgY29tcHV0ZWQsXG4gIGVmZmVjdCxcbiAgSG9zdExpc3RlbmVyLFxuICBpbmplY3QsXG4gIE9uRGVzdHJveSxcbiAgc2lnbmFsLFxuICB1bnRyYWNrZWQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFJlYWN0aXZlRm9ybXNNb2R1bGUsIEZvcm1Db250cm9sLCBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICBDZGtEcmFnLFxuICBDZGtEcmFnRHJvcCxcbiAgQ2RrRHJhZ0hhbmRsZSxcbiAgQ2RrRHJhZ1BsYWNlaG9sZGVyLFxuICBDZGtEcmFnUHJldmlldyxcbiAgQ2RrRHJvcExpc3QsXG4gIERyYWdEcm9wTW9kdWxlLFxufSBmcm9tICdAYW5ndWxhci9jZGsvZHJhZy1kcm9wJztcbmltcG9ydCB7IERlc2lnbmVyU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZGVzaWduZXItc3RhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBSZXBvcnRUZW1wbGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9yZXBvcnQtdGVtcGxhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9tb2RlbHMvcmVwb3J0LWNvbXBvbmVudC5tb2RlbCc7XG5pbXBvcnQgeyBDb21wb25lbnRMYXlvdXREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9tb2RlbHMvcmVwb3J0LWxheW91dC5tb2RlbCc7XG5pbXBvcnQgeyBHcmlkQ29sdW1uRGVmaW5pdGlvbiwgUmVwb3J0R3JpZERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtZ3JpZC5tb2RlbCc7XG5pbXBvcnQgeyBodW1hbml6ZUlkZW50aWZpZXIgfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL3V0aWxzL2lkZW50aWZpZXItaHVtYW5pemVyJztcbmltcG9ydCB7IFJwdEljb25Db21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9wcmltaXRpdmVzL2NvbXBvbmVudHMvaWNvbi9ycHQtaWNvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgUnB0RHJvcGRvd25Db21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9wcmltaXRpdmVzL2NvbXBvbmVudHMvZHJvcGRvd24vcnB0LWRyb3Bkb3duLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBScHREYXRlUmFuZ2VDb21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9wcmltaXRpdmVzL2NvbXBvbmVudHMvZGF0ZS1yYW5nZS9ycHQtZGF0ZS1yYW5nZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgUnB0UmFkaW9Db21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9wcmltaXRpdmVzL2NvbXBvbmVudHMvcmFkaW8vcnB0LXJhZGlvLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZXBvcnRHcmlkQnJpZGdlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vcnVudGltZS9yZXBvcnQtZ3JpZC1icmlkZ2UuY29tcG9uZW50JztcbmltcG9ydCB7IER5bmFtaWNGb3JtQnVpbGRlciB9IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvc2VydmljZXMvZHluYW1pYy1mb3JtLWJ1aWxkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBSZXBvcnRFeGVjdXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vcnVudGltZS9yZXBvcnQtZXhlY3V0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgY2FsY3VsYXRlR3JpZENvbHVtbixcbiAgY2FsY3VsYXRlR3JpZFJvdyxcbiAgY2FsY3VsYXRlU25hcHBlZEhlaWdodCxcbiAgY2FsY3VsYXRlU25hcHBlZFNwYW4sXG4gIENBTlZBU19DQVJEX09WRVJIRUFELFxuICBnZXRDb21wb25lbnRJY29uTmFtZSxcbiAgZ2V0Q29tcG9uZW50TmF0dXJhbE1pbkhlaWdodCxcbiAgcmVzb2x2ZUNhbnZhc0NhcmRIZWlnaHQsXG4gIHJlc29sdmVDYW52YXNDYXJkTWluSGVpZ2h0LFxuICByZXNvbHZlQ29tcG9uZW50U3Bhbixcbn0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2NhbnZhcy1sYXlvdXQudXRpbCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3JwdC1kZXNpZ24tY2FudmFzJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBEcmFnRHJvcE1vZHVsZSxcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgIFJwdEljb25Db21wb25lbnQsXG4gICAgUnB0RHJvcGRvd25Db21wb25lbnQsXG4gICAgUnB0RGF0ZVJhbmdlQ29tcG9uZW50LFxuICAgIFJwdFJhZGlvQ29tcG9uZW50LFxuICAgIFJlcG9ydEdyaWRCcmlkZ2VDb21wb25lbnQsXG4gIF0sXG5cbiAgdGVtcGxhdGVVcmw6ICcuL2Rlc2lnbi1jYW52YXMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vZGVzaWduLWNhbnZhcy5jb21wb25lbnQuY3NzJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIERlc2lnbkNhbnZhc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVxdWVzdHMgPSBuZXcgUmVwb3J0UmVxdWVzdFNjb3BlKCk7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGxldCBwcmV2aW91cyA9ICcnO1xuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICBjb25zdCBrZXkgPSBKU09OLnN0cmluZ2lmeShbdGhpcy5yZXF1ZXN0cy5jb250ZXh0KCksIHRoaXMuZGVmaW5pdGlvbigpLmlkXSk7XG4gICAgICBpZiAoa2V5ID09PSBwcmV2aW91cykgcmV0dXJuO1xuICAgICAgcHJldmlvdXMgPSBrZXk7XG4gICAgICB1bnRyYWNrZWQoKCkgPT4geyB0aGlzLnJlcXVlc3RzLmNhbmNlbEFsbCgpOyB0aGlzLmNhbnZhc0dyaWREYXRhLnNldChbXSk7IHRoaXMuaXNFeGVjdXRpbmdHcmlkLnNldChmYWxzZSk7IHRoaXMuZ3JpZEV4ZWNFcnJvci5zZXQobnVsbCk7IH0pO1xuICAgIH0sIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfSk7XG4gIH1cbiAgcHJpdmF0ZSByZWFkb25seSBkZXNpZ25lclN0YXRlID0gaW5qZWN0KERlc2lnbmVyU3RhdGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBncmlkRmlsdGVyRGVib3VuY2VUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBwZW5kaW5nR3JpZFN0YXRlOiBhbnkgPSBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5IHRlbXBsYXRlU2VydmljZSA9IGluamVjdChSZXBvcnRUZW1wbGF0ZVNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IGZvcm1CdWlsZGVyID0gaW5qZWN0KER5bmFtaWNGb3JtQnVpbGRlcik7XG4gIHByaXZhdGUgcmVhZG9ubHkgZXhlY3V0aW9uU2VydmljZSA9IGluamVjdChSZXBvcnRFeGVjdXRpb25TZXJ2aWNlKTtcblxuICByZWFkb25seSBkZWZpbml0aW9uID0gdGhpcy5kZXNpZ25lclN0YXRlLmRlZmluaXRpb247XG4gIHJlYWRvbmx5IGNvbXBvbmVudHMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmRlZmluaXRpb24oKS5jb21wb25lbnRzKTtcbiAgcmVhZG9ubHkgc2VsZWN0ZWRJZCA9IHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RlZENvbXBvbmVudElkO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX3N0YWJsZUNhbnZhc0Zvcm0gPSBuZXcgRm9ybUdyb3VwKHt9KTtcbiAgcmVhZG9ubHkgY2FudmFzRm9ybSA9IGNvbXB1dGVkPEZvcm1Hcm91cD4oKCkgPT4ge1xuICAgIGNvbnN0IGNvbXBzID0gdGhpcy5jb21wb25lbnRzKCk7XG4gICAgY29uc3QgY3VycmVudEtleXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIGZvciAoY29uc3QgY29tcCBvZiBjb21wcykge1xuICAgICAgaWYgKCFjb21wLmtleSkgY29udGludWU7XG4gICAgICBjdXJyZW50S2V5cy5hZGQoY29tcC5rZXkpO1xuXG4gICAgICBpZiAoIXRoaXMuX3N0YWJsZUNhbnZhc0Zvcm0uY29udGFpbnMoY29tcC5rZXkpKSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRWYWwgPSBjb21wLnByb3BlcnRpZXM/LlsnZGVmYXVsdFZhbHVlJ10gPz8gKGNvbXAudHlwZSA9PT0gJ2NoZWNrYm94JyA/IGZhbHNlIDogJycpO1xuICAgICAgICB0aGlzLl9zdGFibGVDYW52YXNGb3JtLmFkZENvbnRyb2woY29tcC5rZXksIG5ldyBGb3JtQ29udHJvbChkZWZhdWx0VmFsKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBleGlzdGluZ0tleSBvZiBPYmplY3Qua2V5cyh0aGlzLl9zdGFibGVDYW52YXNGb3JtLmNvbnRyb2xzKSkge1xuICAgICAgaWYgKCFjdXJyZW50S2V5cy5oYXMoZXhpc3RpbmdLZXkpKSB7XG4gICAgICAgIHRoaXMuX3N0YWJsZUNhbnZhc0Zvcm0ucmVtb3ZlQ29udHJvbChleGlzdGluZ0tleSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3N0YWJsZUNhbnZhc0Zvcm07XG4gIH0pO1xuXG4gIGdldENhbnZhc0NvbnRyb2woY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IEZvcm1Db250cm9sIHwgbnVsbCB7XG4gICAgaWYgKCFjb21wLmtleSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuICh0aGlzLmNhbnZhc0Zvcm0oKS5nZXQoY29tcC5rZXkpIGFzIEZvcm1Db250cm9sKSA/PyBudWxsO1xuICB9XG5cbiAgcmVhZG9ubHkgaGlnaGxpZ2h0ZWRGaWVsZEtleXMgPSBzaWduYWw8U2V0PHN0cmluZz4+KG5ldyBTZXQoKSk7XG4gIHJlYWRvbmx5IGxheW91dEp1c3RVcGRhdGVkID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcblxuICBpc0ZpZWxkSGlnaGxpZ2h0ZWQoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIWNvbXAua2V5ICYmIHRoaXMuaGlnaGxpZ2h0ZWRGaWVsZEtleXMoKS5oYXMoY29tcC5rZXkudG9Mb3dlckNhc2UoKSk7XG4gIH1cblxuICBvbkNvbnRyb2xJbnRlcmFjdChjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLCBldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoY29tcC5pZCk7XG4gIH1cblxuICBnZXRHcmlkU3VtbWFyeVRleHQoKTogc3RyaW5nIHtcbiAgICBjb25zdCBncmlkID0gdGhpcy5kZWZpbml0aW9uKCkuZ3JpZDtcbiAgICBpZiAoIWdyaWQpIHJldHVybiAnJztcbiAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBncm91cHMgPSBncmlkLm9wdGlvbnM/Lmdyb3VwTW9kZWw7XG4gICAgaWYgKGdyb3VwcyAmJiBncm91cHMubGVuZ3RoID4gMCkge1xuICAgICAgcGFydHMucHVzaChgR3JvdXBlZCBieTogJHtncm91cHMuam9pbignLCAnKX1gKTtcbiAgICB9XG4gICAgY29uc3QgY29scyA9IGdyaWQuY29sdW1ucz8uZmlsdGVyKChjKSA9PiBjLnZpc2libGUgIT09IGZhbHNlKSA/PyBbXTtcbiAgICBwYXJ0cy5wdXNoKGAke2NvbHMubGVuZ3RofSB2aXNpYmxlIGNvbHVtbnNgKTtcbiAgICByZXR1cm4gcGFydHMuam9pbignIOKAoiAnKTtcbiAgfVxuXG4gIGhpZ2hsaWdodE1pc3NpbmdGaWVsZHMoZmllbGRzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IGtleXMgPSBuZXcgU2V0KGZpZWxkcy5tYXAoKGYpID0+IGYudG9Mb3dlckNhc2UoKSkpO1xuICAgIHRoaXMuaGlnaGxpZ2h0ZWRGaWVsZEtleXMuc2V0KGtleXMpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5oaWdobGlnaHRlZEZpZWxkS2V5cy5zZXQobmV3IFNldCgpKTtcbiAgICB9LCAyODAwKTtcbiAgfVxuXG4gIHJlYWRvbmx5IGNhbnZhc0dyaWREYXRhID0gc2lnbmFsPHVua25vd25bXT4oW10pO1xuICByZWFkb25seSBpc0V4ZWN1dGluZ0dyaWQgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBncmlkRXhlY0Vycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuXG4gIHJlYWRvbmx5IHRvdGFsQ29sdW1ucyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGVmaW5pdGlvbigpLmxheW91dC5jb2x1bW5zIHx8IDEyKTtcblxuICByZWFkb25seSBncmlkVGVtcGxhdGVDb2x1bW5zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHJldHVybiBgcmVwZWF0KCR7dGhpcy50b3RhbENvbHVtbnMoKX0sIG1pbm1heCgwLCAxZnIpKWA7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHNvcnRlZENvbXBvbmVudHMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgcmV0dXJuIFsuLi50aGlzLmNvbXBvbmVudHMoKV0uc29ydCgoYSwgYikgPT4gKGEub3JkZXIgPz8gMCkgLSAoYi5vcmRlciA/PyAwKSk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHJlc2l6aW5nQ29tcElkID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICByZWFkb25seSByZXNpemluZ1NwYW4gPSBzaWduYWw8bnVtYmVyIHwgbnVsbD4obnVsbCk7XG4gIHJlYWRvbmx5IHJlc2l6aW5nSGVpZ2h0ID0gc2lnbmFsPG51bWJlciB8IG51bGw+KG51bGwpO1xuICByZWFkb25seSBpc0FueVJlc2l6aW5nID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5yZXNpemluZ0NvbXBJZCgpICE9PSBudWxsKTtcblxuICBpc1NlbGVjdGVkKGlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZElkKCkgPT09IGlkO1xuICB9XG5cbiAgZ2V0U3Bhbihjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogbnVtYmVyIHtcbiAgICByZXR1cm4gcmVzb2x2ZUNvbXBvbmVudFNwYW4oXG4gICAgICBjb21wLFxuICAgICAgdGhpcy50b3RhbENvbHVtbnMoKSxcbiAgICAgIHRoaXMucmVzaXppbmdDb21wSWQoKSA9PT0gY29tcC5pZCA/IHRoaXMucmVzaXppbmdTcGFuKCkgOiBudWxsXG4gICAgKTtcbiAgfVxuXG4gIGdldEdyaWRDb2x1bW4oY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZUdyaWRDb2x1bW4oY29tcCwgdGhpcy50b3RhbENvbHVtbnMoKSwgdGhpcy5nZXRTcGFuKGNvbXApKTtcbiAgfVxuXG4gIHRvZ2dsZU5ld1Jvdyhjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSAhIWNvbXAubGF5b3V0Py5uZXdSb3c7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUNvbXBvbmVudExheW91dChjb21wLmlkLCB7IG5ld1JvdzogIWN1cnJlbnQgfSk7XG4gIH1cblxuICBnZXRHcmlkUm93KGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiBjYWxjdWxhdGVHcmlkUm93KGNvbXApO1xuICB9XG5cbiAgZ2V0Q29tcG9uZW50SGVpZ2h0KGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiByZXNvbHZlQ2FudmFzQ2FyZEhlaWdodChcbiAgICAgIGNvbXAsXG4gICAgICB0aGlzLnJlc2l6aW5nQ29tcElkKCkgPT09IGNvbXAuaWQgPyB0aGlzLnJlc2l6aW5nSGVpZ2h0KCkgOiBudWxsXG4gICAgKTtcbiAgfVxuXG4gIGdldENvbXBvbmVudE1pbkhlaWdodChjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcmVzb2x2ZUNhbnZhc0NhcmRNaW5IZWlnaHQoXG4gICAgICBjb21wLFxuICAgICAgdGhpcy5yZXNpemluZ0NvbXBJZCgpID09PSBjb21wLmlkID8gdGhpcy5yZXNpemluZ0hlaWdodCgpIDogbnVsbFxuICAgICk7XG4gIH1cblxuICBnZXRDdXN0b21CdG5IZWlnaHQoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IGggPSBjb21wLmxheW91dD8uaGVpZ2h0O1xuICAgIHJldHVybiBoICYmIGggIT09ICdhdXRvJyA/IGggOiBudWxsO1xuICB9XG5cbiAgZ2V0Q3VzdG9tQnRuV2lkdGgoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IHcgPSBjb21wLmxheW91dD8ud2lkdGg7XG4gICAgcmV0dXJuIHcgJiYgdyAhPT0gJ2F1dG8nID8gdyA6IG51bGw7XG4gIH1cblxuICBnZXRDdXN0b21CdG5JY29uKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiAoY29tcC5wcm9wZXJ0aWVzPy5bJ2ljb24nXSBhcyBzdHJpbmcpIHx8ICcnO1xuICB9XG5cbiAgcmVzaXppbmdUb29sdGlwKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIGNvbnN0IHNwYW4gPSB0aGlzLmdldFNwYW4oY29tcCk7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5yZXNpemluZ0hlaWdodCgpID8/IChjb21wLmxheW91dD8uaGVpZ2h0ID8gcGFyc2VJbnQoY29tcC5sYXlvdXQuaGVpZ2h0LCAxMCkgOiA1OCk7XG4gICAgcmV0dXJuIGAke3NwYW59IGNvbHMgw5cgJHtoZWlnaHR9cHhgO1xuICB9XG5cbiAgcmVhZG9ubHkgZ2V0Q29tcG9uZW50SWNvbk5hbWUgPSBnZXRDb21wb25lbnRJY29uTmFtZTtcblxuICBvblNlbGVjdChpZDogc3RyaW5nLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW55UmVzaXppbmcoKSkgcmV0dXJuO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoaWQpO1xuICB9XG5cbiAgYWRqdXN0U3Bhbihjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLCBkZWx0YTogbnVtYmVyLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmdldFNwYW4oY29tcCk7XG4gICAgY29uc3QgbmV4dCA9IE1hdGgubWF4KDEsIE1hdGgubWluKHRoaXMudG90YWxDb2x1bW5zKCksIGN1cnJlbnQgKyBkZWx0YSkpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVDb21wb25lbnRMYXlvdXQoY29tcC5pZCwgeyBjb2x1bW5TcGFuOiBuZXh0IH0pO1xuICB9XG5cbiAgb25EdXBsaWNhdGUoaWQ6IHN0cmluZywgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuZHVwbGljYXRlQ29tcG9uZW50KGlkKTtcbiAgfVxuXG4gIG9uRGVsZXRlKGlkOiBzdHJpbmcsIGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnJlbW92ZUNvbXBvbmVudChpZCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duLmVzY2FwZScpXG4gIG9uRXNjYXBlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkSWQoKSkge1xuICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLnNlbGVjdENvbXBvbmVudChudWxsKTtcbiAgICB9XG4gIH1cblxuICBvbkNhbnZhc0JhY2tncm91bmRDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW55UmVzaXppbmcoKSkgcmV0dXJuO1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBpZiAoXG4gICAgICB0YXJnZXQuY2xvc2VzdCgnLmNhbnZhcy1jb21wb25lbnQtY2FyZCcpIHx8XG4gICAgICB0YXJnZXQuY2xvc2VzdCgnLmNhbnZhcy1hY3Rpb24tYnRuJykgfHxcbiAgICAgIHRhcmdldC5jbG9zZXN0KCcuY2FudmFzLWdyaWQtcHJldmlldy1ib3gnKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuc2VsZWN0Q29tcG9uZW50KG51bGwpO1xuICB9XG5cbiAgc2VsZWN0UmVwb3J0U2V0dGluZ3MoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQobnVsbCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnNldEFjdGl2ZVRhYigncmVwb3J0Jyk7XG4gIH1cblxuICBzZWxlY3RHcmlkU2V0dGluZ3MoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQobnVsbCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnNldEFjdGl2ZVRhYignZ3JpZCcpO1xuICB9XG5cbiAgc3RhcnRSZXNpemUoZXZlbnQ6IFBvaW50ZXJFdmVudCwgY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbiwgZGlyZWN0aW9uOiAnZScgfCAncycgfCAnc2UnKTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoY29tcC5pZCk7XG5cbiAgICBjb25zdCBoYW5kbGUgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgaGFuZGxlLnNldFBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG5cbiAgICBjb25zdCBjYXJkID0gaGFuZGxlLmNsb3Nlc3QoJy5jYW52YXMtY29tcG9uZW50LWNhcmQnKSBhcyBIVE1MRWxlbWVudDtcbiAgICBjb25zdCBncmlkID0gaGFuZGxlLmNsb3Nlc3QoJy5jYW52YXMtZ3JpZCcpIGFzIEhUTUxFbGVtZW50O1xuICAgIGlmICghY2FyZCB8fCAhZ3JpZCkgcmV0dXJuO1xuXG4gICAgY29uc3Qgc3RhcnRYID0gZXZlbnQuY2xpZW50WDtcbiAgICBjb25zdCBzdGFydFkgPSBldmVudC5jbGllbnRZO1xuICAgIGNvbnN0IHN0YXJ0U3BhbiA9IGNvbXAubGF5b3V0Py5jb2x1bW5TcGFuID8/IChjb21wLnR5cGUgPT09ICdidXR0b24nID8gMiA6IDQpO1xuICAgIGNvbnN0IGV4aXN0aW5nQ29tcEhlaWdodCA9IGNvbXAubGF5b3V0Py5oZWlnaHQgPyBwYXJzZUludChjb21wLmxheW91dC5oZWlnaHQsIDEwKSA6IG51bGw7XG4gICAgY29uc3Qgc3RhcnRIZWlnaHQgPSBleGlzdGluZ0NvbXBIZWlnaHQgPz8gTWF0aC5tYXgoMzgsIGNhcmQub2Zmc2V0SGVpZ2h0IC0gQ0FOVkFTX0NBUkRfT1ZFUkhFQUQpO1xuICAgIGNvbnN0IHRvdGFsQ29scyA9IHRoaXMudG90YWxDb2x1bW5zKCk7XG4gICAgY29uc3QgZ2FwID0gdGhpcy5kZWZpbml0aW9uKCkubGF5b3V0LmdhcCA/PyAxNjtcbiAgICBjb25zdCBjb2xXaWR0aCA9IChncmlkLm9mZnNldFdpZHRoIC0gKHRvdGFsQ29scyAtIDEpICogZ2FwKSAvIHRvdGFsQ29scztcblxuICAgIHRoaXMucmVzaXppbmdDb21wSWQuc2V0KGNvbXAuaWQpO1xuICAgIHRoaXMucmVzaXppbmdTcGFuLnNldChzdGFydFNwYW4pO1xuICAgIHRoaXMucmVzaXppbmdIZWlnaHQuc2V0KHN0YXJ0SGVpZ2h0KTtcblxuICAgIGxldCBjdXJyZW50U3BhbiA9IHN0YXJ0U3BhbjtcbiAgICBsZXQgY3VycmVudEhlaWdodCA9IHN0YXJ0SGVpZ2h0O1xuXG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9IChtb3ZlRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ2UnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlJykge1xuICAgICAgICBjb25zdCBkZWx0YVggPSBtb3ZlRXZlbnQuY2xpZW50WCAtIHN0YXJ0WDtcbiAgICAgICAgY3VycmVudFNwYW4gPSBjYWxjdWxhdGVTbmFwcGVkU3BhbihkZWx0YVgsIHN0YXJ0U3BhbiwgY29sV2lkdGgsIGdhcCwgdG90YWxDb2xzKTtcbiAgICAgICAgdGhpcy5yZXNpemluZ1NwYW4uc2V0KGN1cnJlbnRTcGFuKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ3MnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlJykge1xuICAgICAgICBjb25zdCBkZWx0YVkgPSBtb3ZlRXZlbnQuY2xpZW50WSAtIHN0YXJ0WTtcbiAgICAgICAgY29uc3QgbmF0dXJhbE1pbiA9IE1hdGgubWF4KDM4LCBnZXRDb21wb25lbnROYXR1cmFsTWluSGVpZ2h0KGNvbXAudHlwZSkpO1xuICAgICAgICBjdXJyZW50SGVpZ2h0ID0gY2FsY3VsYXRlU25hcHBlZEhlaWdodChkZWx0YVksIHN0YXJ0SGVpZ2h0LCBuYXR1cmFsTWluKTtcbiAgICAgICAgdGhpcy5yZXNpemluZ0hlaWdodC5zZXQoY3VycmVudEhlaWdodCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IG9uUG9pbnRlclVwID0gKHVwRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaGFuZGxlLnJlbGVhc2VQb2ludGVyQ2FwdHVyZSh1cEV2ZW50LnBvaW50ZXJJZCk7XG4gICAgICB9IGNhdGNoIHt9XG5cbiAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgaGFuZGxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIG9uUG9pbnRlclVwKTtcbiAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgb25Qb2ludGVyVXApO1xuXG4gICAgICBjb25zdCBsYXlvdXRDaGFuZ2VzOiBQYXJ0aWFsPENvbXBvbmVudExheW91dERlZmluaXRpb24+ID0ge307XG4gICAgICBpZiAoZGlyZWN0aW9uID09PSAnZScgfHwgZGlyZWN0aW9uID09PSAnc2UnKSB7XG4gICAgICAgIGxheW91dENoYW5nZXMuY29sdW1uU3BhbiA9IGN1cnJlbnRTcGFuO1xuICAgICAgfVxuICAgICAgY29uc3QgZGVsdGFZID0gTWF0aC5hYnModXBFdmVudC5jbGllbnRZIC0gc3RhcnRZKTtcbiAgICAgIGlmIChkaXJlY3Rpb24gPT09ICdzJyB8fCAoZGlyZWN0aW9uID09PSAnc2UnICYmIGRlbHRhWSA+IDE2KSkge1xuICAgICAgICBsYXlvdXRDaGFuZ2VzLmhlaWdodCA9IGAke2N1cnJlbnRIZWlnaHR9cHhgO1xuICAgICAgICBsYXlvdXRDaGFuZ2VzLm1pbkhlaWdodCA9IGAke2N1cnJlbnRIZWlnaHR9cHhgO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlQ29tcG9uZW50TGF5b3V0KGNvbXAuaWQsIGxheW91dENoYW5nZXMpO1xuXG4gICAgICB0aGlzLnJlc2l6aW5nQ29tcElkLnNldChudWxsKTtcbiAgICAgIHRoaXMucmVzaXppbmdTcGFuLnNldChudWxsKTtcbiAgICAgIHRoaXMucmVzaXppbmdIZWlnaHQuc2V0KG51bGwpO1xuICAgIH07XG5cbiAgICBoYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBvblBvaW50ZXJNb3ZlKTtcbiAgICBoYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgb25Qb2ludGVyVXApO1xuICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgb25Qb2ludGVyVXApO1xuICB9XG5cbiAgcmVzZXREaW1lbnNpb25zKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24sIGV2ZW50PzogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudCkge1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgICBjb25zdCBkZWZhdWx0U3BhbiA9IGNvbXAudHlwZSA9PT0gJ2J1dHRvbicgPyAyIDogNDtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlQ29tcG9uZW50TGF5b3V0KGNvbXAuaWQsIHtcbiAgICAgIGNvbHVtblNwYW46IGRlZmF1bHRTcGFuLFxuICAgICAgaGVpZ2h0OiB1bmRlZmluZWQsXG4gICAgICBtaW5IZWlnaHQ6IHVuZGVmaW5lZCxcbiAgICAgIHdpZHRoOiB1bmRlZmluZWQsXG4gICAgfSk7XG4gIH1cblxuICBvbkRyb3AoZXZlbnQ6IENka0RyYWdEcm9wPFJlcG9ydENvbXBvbmVudERlZmluaXRpb25bXSwgdW5rbm93biwgdW5rbm93bj4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0FueVJlc2l6aW5nKCkpIHJldHVybjtcblxuICAgIGlmIChldmVudC5wcmV2aW91c0NvbnRhaW5lciA9PT0gZXZlbnQuY29udGFpbmVyKSB7XG4gICAgICAvLyBSZW9yZGVyaW5nIHdpdGhpbiBjYW52YXNcbiAgICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5tb3ZlQ29tcG9uZW50KGV2ZW50LnByZXZpb3VzSW5kZXgsIGV2ZW50LmN1cnJlbnRJbmRleCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERyYWdnZWQgZnJvbSBwYWxldHRlIGludG8gY2FudmFzXG4gICAgICBjb25zdCByYXdEYXRhID0gZXZlbnQuaXRlbS5kYXRhIGFzIHN0cmluZyB8IHsgdHlwZT86IHN0cmluZyB9IHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgY29tcG9uZW50VHlwZSA9IHR5cGVvZiByYXdEYXRhID09PSAnc3RyaW5nJyA/IHJhd0RhdGEgOiByYXdEYXRhPy50eXBlO1xuICAgICAgaWYgKGNvbXBvbmVudFR5cGUpIHtcbiAgICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLmFkZENvbXBvbmVudChjb21wb25lbnRUeXBlLCBldmVudC5jdXJyZW50SW5kZXgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFkZFJlc3VsdEdyaWQoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGV4aXN0aW5nRHMgPSB0aGlzLmRlZmluaXRpb24oKS5kYXRhU291cmNlc1swXTtcbiAgICBjb25zdCBkZWZhdWx0R3JpZDogUmVwb3J0R3JpZERlZmluaXRpb24gPSB7XG4gICAgICBkYXRhU291cmNlSWQ6IGV4aXN0aW5nRHM/LmlkID8/ICdkZWZhdWx0JyxcbiAgICAgIGNvbHVtbnM6IFtcbiAgICAgICAgeyBmaWVsZDogJ2lkJywgbGFiZWw6ICdJRCcsIGRhdGFUeXBlOiAnbnVtYmVyJywgdmlzaWJsZTogdHJ1ZSwgc29ydGFibGU6IHRydWUgfSxcbiAgICAgICAgeyBmaWVsZDogJ25hbWUnLCBsYWJlbDogJ05hbWUnLCBkYXRhVHlwZTogJ3N0cmluZycsIHZpc2libGU6IHRydWUsIHNvcnRhYmxlOiB0cnVlIH0sXG4gICAgICBdLFxuICAgICAgb3B0aW9uczoge1xuICAgICAgICBwYWdpbmF0aW9uOiB0cnVlLFxuICAgICAgICBwYWdlU2l6ZTogMjUsXG4gICAgICAgIHNob3dSb3dOdW1iZXJzOiB0cnVlLFxuICAgICAgICBzaG93Rm9vdGVyOiB0cnVlLFxuICAgICAgICBzaWRlQmFyOiB0cnVlLFxuICAgICAgICBnbG9iYWxTZWFyY2g6IHRydWUsXG4gICAgICAgIHN0YXR1c0JhcjogdHJ1ZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlR3JpZFNldHRpbmdzKGRlZmF1bHRHcmlkKTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuc2VsZWN0Q29tcG9uZW50KG51bGwpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZXRBY3RpdmVUYWIoJ2dyaWQnKTtcbiAgfVxuXG4gIGV4ZWN1dGVDYW52YXNSZXBvcnQoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50KSBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoIXRoaXMuZGVmaW5pdGlvbigpLmdyaWQpIHtcbiAgICAgIHRoaXMuYWRkUmVzdWx0R3JpZCgpO1xuICAgIH1cblxuICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSB0aGlzLmNhbnZhc0Zvcm0oKS5nZXRSYXdWYWx1ZSgpO1xuICAgIGNvbnN0IG1pc3NpbmcgPSB0aGlzLmV4ZWN1dGlvblNlcnZpY2UuZ2V0TWlzc2luZ0ZpZWxkcyh0aGlzLmRlZmluaXRpb24oKSwgZm9ybVZhbHVlcyk7XG4gICAgaWYgKG1pc3NpbmcubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5ncmlkRXhlY0Vycm9yLnNldCgnTWlzc2luZyByZXF1aXJlZCBmaWx0ZXIgdmFsdWVzOiAnICsgbWlzc2luZy5qb2luKCcsICcpICsgJy4gUGxlYXNlIGVudGVyIHZhbHVlcyBhYm92ZSB0byBydW4uJyk7XG4gICAgICB0aGlzLmhpZ2hsaWdodE1pc3NpbmdGaWVsZHMobWlzc2luZyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5pc0V4ZWN1dGluZ0dyaWQuc2V0KHRydWUpO1xuICAgIHRoaXMuZ3JpZEV4ZWNFcnJvci5zZXQobnVsbCk7XG5cbiAgICB0aGlzLnJlcXVlc3RzLnJ1bignY2FudmFzLWV4ZWN1dGlvbicsICgpID0+IHRoaXMuZXhlY3V0aW9uU2VydmljZS5leGVjdXRlKHRoaXMuZGVmaW5pdGlvbigpLCBmb3JtVmFsdWVzKSxcbiAgICAgIChyb3dzOiB1bmtub3duW10pID0+IHtcbiAgICAgICAgdGhpcy5jYW52YXNHcmlkRGF0YS5zZXQocm93cyB8fCBbXSk7XG4gICAgICAgIHRoaXMuaXNFeGVjdXRpbmdHcmlkLnNldChmYWxzZSk7XG5cbiAgICAgICAgLy8gQXV0by1wb3B1bGF0ZSBncmlkIGNvbHVtbnMgaWYgZ3JpZCBoYXMgZHVtbXkgY29sdW1ucyB0aGF0IGRvbid0IG1hdGNoIHRoZSBleGVjdXRlZCByb3dzXG4gICAgICAgIGlmIChyb3dzICYmIHJvd3MubGVuZ3RoID4gMCAmJiB0eXBlb2Ygcm93c1swXSA9PT0gJ29iamVjdCcgJiYgcm93c1swXSAhPT0gbnVsbCkge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRHcmlkID0gdGhpcy5kZWZpbml0aW9uKCkuZ3JpZDtcbiAgICAgICAgICBpZiAoY3VycmVudEdyaWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0Um93ID0gcm93c1swXSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhmaXJzdFJvdykuZmlsdGVyKChrKSA9PiBrLnRyaW0oKS5sZW5ndGggPiAwKTtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoZXNBbnkgPSBjdXJyZW50R3JpZC5jb2x1bW5zLnNvbWUoKGMpID0+IGtleXMuaW5jbHVkZXMoYy5maWVsZCkpO1xuICAgICAgICAgICAgaWYgKCFtYXRjaGVzQW55ICYmIGtleXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBjb25zdCBkZXRlY3RlZENvbHM6IEdyaWRDb2x1bW5EZWZpbml0aW9uW10gPSBrZXlzLm1hcCgoaykgPT4gKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogayxcbiAgICAgICAgICAgICAgICBsYWJlbDogaHVtYW5pemVJZGVudGlmaWVyKGspLFxuICAgICAgICAgICAgICAgIGRhdGFUeXBlOiB0eXBlb2YgZmlyc3RSb3dba10gPT09ICdudW1iZXInID8gJ251bWJlcicgOiB0eXBlb2YgZmlyc3RSb3dba10gPT09ICdib29sZWFuJyA/ICdib29sZWFuJyA6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICAgICAgc29ydGFibGU6IHRydWUsXG4gICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgY29uc3QgY2xlYW5PcHRpb25zID0geyAuLi4oY3VycmVudEdyaWQub3B0aW9ucyB8fCB7fSkgfTtcbiAgICAgICAgICAgICAgZGVsZXRlIGNsZWFuT3B0aW9ucy5yZXBvcnRTdGF0ZTtcbiAgICAgICAgICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUdyaWRTZXR0aW5ncyh7XG4gICAgICAgICAgICAgICAgLi4uY3VycmVudEdyaWQsXG4gICAgICAgICAgICAgICAgb3B0aW9uczogY2xlYW5PcHRpb25zLFxuICAgICAgICAgICAgICAgIGNvbHVtbnM6IGRldGVjdGVkQ29scyxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKGVycjogdW5rbm93bikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdbRGVzaWduQ2FudmFzXSBRdWVyeSBleGVjdXRpb24gZXJyb3I6JywgZXJyKTtcbiAgICAgICAgY29uc3QgbXNnID0gZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpO1xuICAgICAgICB0aGlzLmdyaWRFeGVjRXJyb3Iuc2V0KG1zZyB8fCAnRXhlY3V0aW9uIGZhaWxlZCcpO1xuICAgICAgICB0aGlzLmlzRXhlY3V0aW5nR3JpZC5zZXQoZmFsc2UpO1xuICAgICAgfSwgKCkgPT4gdGhpcy5pc0V4ZWN1dGluZ0dyaWQuc2V0KGZhbHNlKSk7XG4gIH1cblxuICBvbkNhbnZhc0J1dHRvbkNsaWNrKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24sIGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgYWN0aW9uID0gKGNvbXAucHJvcGVydGllcz8uWydhY3Rpb24nXSBhcyBzdHJpbmcpIHx8ICdleGVjdXRlLXJlcG9ydCc7XG4gICAgaWYgKGFjdGlvbiA9PT0gJ2V4ZWN1dGUtcmVwb3J0Jykge1xuICAgICAgdGhpcy5leGVjdXRlQ2FudmFzUmVwb3J0KCk7XG4gICAgfSBlbHNlIGlmIChhY3Rpb24gPT09ICdyZXNldCcpIHtcbiAgICAgIHRoaXMucmVxdWVzdHMuY2FuY2VsKCdjYW52YXMtZXhlY3V0aW9uJyk7XG4gICAgICB0aGlzLmNhbnZhc0Zvcm0oKS5yZXNldCgpO1xuICAgICAgdGhpcy5jYW52YXNHcmlkRGF0YS5zZXQoW10pO1xuICAgIH0gZWxzZSBpZiAoYWN0aW9uID09PSAnZXhwb3J0Jykge1xuICAgICAgdGhpcy5ncmlkRXhlY0Vycm9yLnNldCgn8J+SoSBFeHBvcnQgYWN0aW9uIGlzIGNvbmZpZ3VyZWQuIFJ1biB0aGUgcmVwb3J0IGFuZCBzd2l0Y2ggdG8gUnVudGltZSB2aWV3IHRvIGRvd25sb2FkIGZpbGVzLicpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmdyaWRFeGVjRXJyb3Iuc2V0KG51bGwpLCA0MDAwKTtcbiAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PT0gJ3ByaW50LXJlcG9ydCcpIHtcbiAgICAgIHRoaXMuZ3JpZEV4ZWNFcnJvci5zZXQoJ/CfkqEgUHJpbnQgUmVwb3J0IGFjdGlvbiBpcyBjb25maWd1cmVkLiBTd2l0Y2ggdG8gUnVudGltZSB2aWV3IHRvIHN1Ym1pdCB0byBwcmludCBzZXJ2aWNlLicpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmdyaWRFeGVjRXJyb3Iuc2V0KG51bGwpLCA0MDAwKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5ncmlkRmlsdGVyRGVib3VuY2VUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZ3JpZEZpbHRlckRlYm91bmNlVGltZXIpO1xuICAgICAgdGhpcy5ncmlkRmlsdGVyRGVib3VuY2VUaW1lciA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgb25DYW52YXNHcmlkU3RhdGVDaGFuZ2Uoc3RhdGU6IGFueSk6IHZvaWQge1xuICAgIGlmICghc3RhdGUgfHwgIXRoaXMuZGVmaW5pdGlvbigpLmdyaWQpIHJldHVybjtcbiAgICBjb25zdCBjdXJyZW50R3JpZCA9IHRoaXMuZGVmaW5pdGlvbigpLmdyaWQhO1xuXG4gICAgLy8gQXZvaWQgZGlydHkgY2h1cm4gYW5kIGV2ZW50IGxvb3BzIGlmIHN0YXRlIGhhcyBub3QgY2hhbmdlZFxuICAgIGNvbnN0IGN1cnJlbnRTZXJpYWxpemVkID0gSlNPTi5zdHJpbmdpZnkoY3VycmVudEdyaWQub3B0aW9ucz8ucmVwb3J0U3RhdGUgPz8gbnVsbCk7XG4gICAgY29uc3QgbmV3U2VyaWFsaXplZCA9IEpTT04uc3RyaW5naWZ5KHN0YXRlID8/IG51bGwpO1xuICAgIGlmIChjdXJyZW50U2VyaWFsaXplZCA9PT0gbmV3U2VyaWFsaXplZCkgcmV0dXJuO1xuXG4gICAgLy8gRGlzdGluZ3Vpc2ggYmV0d2VlbiB0cnVlIHN0cnVjdHVyYWwgbGF5b3V0IGNoYW5nZXMgKGdyb3VwTW9kZWwsIHNvcnRNb2RlbClcbiAgICAvLyB2cyBpbnRlcmFjdGl2ZSBjb2x1bW4gZGF0YSBmaWx0ZXJpbmcgKGFjdGl2ZUZpbHRlcnMsIGNvbmRpdGlvbkZpbHRlcnMpLlxuICAgIGNvbnN0IGN1cnJlbnRHcm91cCA9IEpTT04uc3RyaW5naWZ5KGN1cnJlbnRHcmlkLm9wdGlvbnM/Lmdyb3VwTW9kZWwgPz8gW10pO1xuICAgIGNvbnN0IG5ld0dyb3VwID0gSlNPTi5zdHJpbmdpZnkoc3RhdGUuZ3JvdXBNb2RlbCA/PyBbXSk7XG4gICAgY29uc3QgY3VycmVudFNvcnQgPSBKU09OLnN0cmluZ2lmeShjdXJyZW50R3JpZC5vcHRpb25zPy5zb3J0TW9kZWwgPz8gW10pO1xuICAgIGNvbnN0IG5ld1NvcnQgPSBKU09OLnN0cmluZ2lmeShzdGF0ZS5zb3J0TW9kZWwgPz8gW10pO1xuICAgIGNvbnN0IGlzTGF5b3V0Q2hhbmdlID0gY3VycmVudEdyb3VwICE9PSBuZXdHcm91cCB8fCBjdXJyZW50U29ydCAhPT0gbmV3U29ydDtcblxuICAgIGNvbnN0IHVwZGF0ZWRPcHRpb25zID0ge1xuICAgICAgLi4uKGN1cnJlbnRHcmlkLm9wdGlvbnMgfHwge30pLFxuICAgICAgZ3JvdXBNb2RlbDogc3RhdGUuZ3JvdXBNb2RlbCA/PyBjdXJyZW50R3JpZC5vcHRpb25zPy5ncm91cE1vZGVsLFxuICAgICAgc29ydE1vZGVsOiBzdGF0ZS5zb3J0TW9kZWwgPz8gY3VycmVudEdyaWQub3B0aW9ucz8uc29ydE1vZGVsLFxuICAgICAgcmVwb3J0U3RhdGU6IHN0YXRlLFxuICAgIH07XG5cbiAgICBpZiAoaXNMYXlvdXRDaGFuZ2UpIHtcbiAgICAgIC8vIENsZWFyIGFueSBwZW5kaW5nIGRlYm91bmNlZCBmaWx0ZXIgdXBkYXRlXG4gICAgICBpZiAodGhpcy5ncmlkRmlsdGVyRGVib3VuY2VUaW1lcikge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5ncmlkRmlsdGVyRGVib3VuY2VUaW1lcik7XG4gICAgICAgIHRoaXMuZ3JpZEZpbHRlckRlYm91bmNlVGltZXIgPSBudWxsO1xuICAgICAgfVxuICAgICAgdGhpcy5wZW5kaW5nR3JpZFN0YXRlID0gbnVsbDtcblxuICAgICAgLy8gR3JvdXBpbmcgb3Igc29ydGluZyBjaGFuZ2VkIOKAlCB1cGRhdGUgbGF5b3V0IGltbWVkaWF0ZWx5IGFuZCBzaG93IHZpc3VhbCBpbmRpY2F0b3JcbiAgICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVHcmlkU2V0dGluZ3Moe1xuICAgICAgICAuLi5jdXJyZW50R3JpZCxcbiAgICAgICAgb3B0aW9uczogdXBkYXRlZE9wdGlvbnMsXG4gICAgICB9KTtcbiAgICAgIHRoaXMubGF5b3V0SnVzdFVwZGF0ZWQuc2V0KHRydWUpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmxheW91dEp1c3RVcGRhdGVkLnNldChmYWxzZSksIDEyMDApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBQdXJlIGNvbHVtbiBmaWx0ZXIgYWRqdXN0bWVudCAoYWN0aXZlRmlsdGVycyAvIGNvbmRpdGlvbkZpbHRlcnMpLlxuICAgICAgLy8gMS4gRG8gTk9UIHRyaWdnZXIgdGhlIFwiTGF5b3V0IGF1dG8tcGVyc2lzdGVkXCIgaW5kaWNhdG9yIChmaWx0ZXJpbmcgcm93cyBpcyBub3QgYSBsYXlvdXQgY2hhbmdlKS5cbiAgICAgIC8vIDIuIERlYm91bmNlIHNhdmluZyB0aGUgc3RhdGUgd2l0aCBza2lwSGlzdG9yeSBzbyB0eXBpbmcgb3IgY2hlY2tpbmcgYm94ZXNcbiAgICAgIC8vICAgIGRvZXMgbm90IGZsb29kIHVuZG8gaGlzdG9yeSBvciBpbnRlcnJ1cHQgY29sdW1uIGZpbHRlciBpbnRlcmFjdGlvbi5cbiAgICAgIHRoaXMucGVuZGluZ0dyaWRTdGF0ZSA9IHN0YXRlO1xuICAgICAgaWYgKHRoaXMuZ3JpZEZpbHRlckRlYm91bmNlVGltZXIpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZ3JpZEZpbHRlckRlYm91bmNlVGltZXIpO1xuICAgICAgfVxuICAgICAgdGhpcy5ncmlkRmlsdGVyRGVib3VuY2VUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmdyaWRGaWx0ZXJEZWJvdW5jZVRpbWVyID0gbnVsbDtcbiAgICAgICAgaWYgKCF0aGlzLnBlbmRpbmdHcmlkU3RhdGUgfHwgIXRoaXMuZGVmaW5pdGlvbigpLmdyaWQpIHJldHVybjtcbiAgICAgICAgY29uc3QgbGF0ZXN0R3JpZCA9IHRoaXMuZGVmaW5pdGlvbigpLmdyaWQhO1xuICAgICAgICBjb25zdCBsYXRlc3RPcHRpb25zID0ge1xuICAgICAgICAgIC4uLihsYXRlc3RHcmlkLm9wdGlvbnMgfHwge30pLFxuICAgICAgICAgIHJlcG9ydFN0YXRlOiB0aGlzLnBlbmRpbmdHcmlkU3RhdGUsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucGVuZGluZ0dyaWRTdGF0ZSA9IG51bGw7XG4gICAgICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVHcmlkU2V0dGluZ3MoXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4ubGF0ZXN0R3JpZCxcbiAgICAgICAgICAgIG9wdGlvbnM6IGxhdGVzdE9wdGlvbnMsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IHNraXBIaXN0b3J5OiB0cnVlIH1cbiAgICAgICAgKTtcbiAgICAgIH0sIDEyMDApO1xuICAgIH1cbiAgfVxuXG4gIG9uQ2FudmFzQ29sdW1uRGVmc0NoYW5nZShkZWZzOiBhbnlbXSk6IHZvaWQge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShkZWZzKSB8fCAhdGhpcy5kZWZpbml0aW9uKCkuZ3JpZCkgcmV0dXJuO1xuICAgIGNvbnN0IGN1cnJlbnRHcmlkID0gdGhpcy5kZWZpbml0aW9uKCkuZ3JpZCE7XG4gICAgbGV0IGFueUNoYW5nZWQgPSBmYWxzZTtcblxuICAgIGNvbnN0IHVwZGF0ZWRDb2xzID0gY3VycmVudEdyaWQuY29sdW1ucy5tYXAoKGMpID0+IHtcbiAgICAgIGNvbnN0IG1hdGNoID0gZGVmcy5maW5kKChkOiBhbnkpID0+IGQuZmllbGQgPT09IGMuZmllbGQpO1xuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIGNvbnN0IG5ld1dpZHRoID0gbWF0Y2gud2lkdGggPyBgJHttYXRjaC53aWR0aH1weGAgOiBjLndpZHRoO1xuICAgICAgICBjb25zdCBuZXdWaXNpYmxlID0gbWF0Y2guaGlkZSAhPT0gdHJ1ZTtcbiAgICAgICAgaWYgKG5ld1dpZHRoICE9PSBjLndpZHRoIHx8IG5ld1Zpc2libGUgIT09IGMudmlzaWJsZSkge1xuICAgICAgICAgIGFueUNoYW5nZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uYyxcbiAgICAgICAgICB3aWR0aDogbmV3V2lkdGgsXG4gICAgICAgICAgdmlzaWJsZTogbmV3VmlzaWJsZSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjO1xuICAgIH0pO1xuXG4gICAgLy8gSWYgbm8gY29sdW1uIHdpZHRocyBvciB2aXNpYmlsaXRpZXMgYWN0dWFsbHkgY2hhbmdlZCwgZG8gbm90IHRyaWdnZXIgYXV0by1wZXJzaXN0XG4gICAgaWYgKCFhbnlDaGFuZ2VkKSByZXR1cm47XG5cbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlR3JpZFNldHRpbmdzKHtcbiAgICAgIC4uLmN1cnJlbnRHcmlkLFxuICAgICAgY29sdW1uczogdXBkYXRlZENvbHMsXG4gICAgfSk7XG4gICAgdGhpcy5sYXlvdXRKdXN0VXBkYXRlZC5zZXQodHJ1ZSk7XG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmxheW91dEp1c3RVcGRhdGVkLnNldChmYWxzZSksIDEyMDApO1xuICB9XG5cbiAgcmVtb3ZlR3JpZChldmVudD86IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUdyaWRTZXR0aW5ncyh1bmRlZmluZWQpO1xuICB9XG5cbiAgYXBwbHlCbHVlcHJpbnQoYmx1ZXByaW50SWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG5ld0RlZiA9IHRoaXMudGVtcGxhdGVTZXJ2aWNlLmluc3RhbnRpYXRlVGVtcGxhdGUoYmx1ZXByaW50SWQpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5sb2FkRGVmaW5pdGlvbihuZXdEZWYpO1xuICB9XG5cbiAgYWRkU3RhcnRlckNvbXBvbmVudCh0eXBlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuYWRkQ29tcG9uZW50KHR5cGUpO1xuICB9XG59XG4iLCIgICAgPGRpdiBjbGFzcz1cImNhbnZhcy13cmFwcGVyXCIgKGNsaWNrKT1cIm9uQ2FudmFzQmFja2dyb3VuZENsaWNrKCRldmVudClcIj5cbiAgICAgIDwhLS0gQ2FudmFzIFN0YXR1cyAvIFF1aWNrIENvbnRyb2xzIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy10b29sYmFyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtaW5mb1wiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5mby1sYWJlbFwiPkdyaWQgTGF5b3V0Ojwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImluZm8tdmFsdWVcIj57eyB0b3RhbENvbHVtbnMoKSB9fSBDb2x1bW5zPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5mby1kaXZpZGVyXCI+4oCiPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5mby1sYWJlbFwiPkNvbXBvbmVudHM6PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5mby12YWx1ZVwiPnt7IGNvbXBvbmVudHMoKS5sZW5ndGggfX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbmZvLWRpdmlkZXJcIj7igKI8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJsaXZlLW1vZGUtYmFkZ2VcIiB0aXRsZT1cIkludGVyYWN0aXZlIGNhbnZhczogVmFsdWVzIHR5cGVkIGhlcmUgcnVuIGxpdmUgcXVlcmllcyBhbmQgdGVzdCBkcm9wZG93bnMuXCI+XG4gICAgICAgICAgICDimqEgTGl2ZSBJbnRlcmFjdGl2ZSBNb2RlXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWFjdGlvbnNcIj5cbiAgICAgICAgICBAaWYgKCFkZWZpbml0aW9uKCkuZ3JpZCkge1xuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtYWN0aW9uLWJ0biBidG4tZ3JpZC1hZGRcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiYWRkUmVzdWx0R3JpZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJBZGQgYSBSZXN1bHQgR3JpZCB0byB0aGlzIHJlcG9ydFwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwidGFibGVcIiBbc2l6ZV09XCIxNFwiIC8+XG4gICAgICAgICAgICAgIDxzcGFuPisgQWRkIEdyaWQ8L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWFjdGlvbi1idG4gYnRuLWdyaWQtY29uZmlndXJlZFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RHcmlkU2V0dGluZ3MoJGV2ZW50KVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwiQ29uZmlndXJlIFJlc3VsdCBEYXRhIEdyaWRcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMTRcIiAvPlxuICAgICAgICAgICAgICA8c3Bhbj5HcmlkICh7eyBkZWZpbml0aW9uKCkuZ3JpZD8uY29sdW1ucz8ubGVuZ3RoID8/IDAgfX0pPC9zcGFuPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1hY3Rpb24tYnRuXCJcbiAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RSZXBvcnRTZXR0aW5ncygkZXZlbnQpXCJcbiAgICAgICAgICAgIHRpdGxlPVwiQ29uZmlndXJlIFBhZ2UgTGF5b3V0ICYgR3JpZCBTZXR0aW5nc1wiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJzZXR0aW5nc1wiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgIDxzcGFuPlJlcG9ydCBTZXR0aW5nczwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBDYW52YXMgRHJvcCBBcmVhIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1zY3JvbGwtYXJlYVwiPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJjYW52YXMtYXJ0Ym9hcmRcIlxuICAgICAgICAgIFtzdHlsZS5wYWRkaW5nLnB4XT1cImRlZmluaXRpb24oKS5sYXlvdXQucGFkZGluZyA/PyAyNFwiXG4gICAgICAgID5cbiAgICAgICAgICA8IS0tIFJlcG9ydCBIZWFkZXIgUHJldmlldyAtLT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLXJlcG9ydC1oZWFkZXJcIj5cbiAgICAgICAgICAgIDxoMiBjbGFzcz1cImNhbnZhcy1yZXBvcnQtdGl0bGVcIj57eyBkZWZpbml0aW9uKCkubmFtZSB8fCAnVW50aXRsZWQgUmVwb3J0JyB9fTwvaDI+XG4gICAgICAgICAgICBAaWYgKGRlZmluaXRpb24oKS5kZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICA8cCBjbGFzcz1cImNhbnZhcy1yZXBvcnQtZGVzY1wiPnt7IGRlZmluaXRpb24oKS5kZXNjcmlwdGlvbiB9fTwvcD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gQ29tcG9uZW50IERyb3AgTGlzdCBHcmlkIHdpdGggMkQgbWl4ZWQgb3JpZW50YXRpb24gYW5kIGRhdGEgYmluZGluZyAtLT5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjZGtEcm9wTGlzdFxuICAgICAgICAgICAgaWQ9XCJkZXNpZ25lci1jYW52YXMtZHJvcC1saXN0XCJcbiAgICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWdyaWRcIlxuICAgICAgICAgICAgY2RrRHJvcExpc3RPcmllbnRhdGlvbj1cIm1peGVkXCJcbiAgICAgICAgICAgIFtjZGtEcm9wTGlzdERhdGFdPVwic29ydGVkQ29tcG9uZW50cygpXCJcbiAgICAgICAgICAgIFtzdHlsZS5ncmlkLXRlbXBsYXRlLWNvbHVtbnNdPVwiZ3JpZFRlbXBsYXRlQ29sdW1ucygpXCJcbiAgICAgICAgICAgIFtzdHlsZS5nYXAucHhdPVwiZGVmaW5pdGlvbigpLmxheW91dC5nYXAgPz8gMTZcIlxuICAgICAgICAgICAgKGNka0Ryb3BMaXN0RHJvcHBlZCk9XCJvbkRyb3AoJGV2ZW50KVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgQGZvciAoY29tcCBvZiBzb3J0ZWRDb21wb25lbnRzKCk7IHRyYWNrIGNvbXAuaWQ7IGxldCBpZHggPSAkaW5kZXgpIHtcbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIGNka0RyYWdcbiAgICAgICAgICAgICAgICBbY2RrRHJhZ0RhdGFdPVwiY29tcFwiXG4gICAgICAgICAgICAgICAgW2Nka0RyYWdEaXNhYmxlZF09XCJpc0FueVJlc2l6aW5nKClcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWNvbXBvbmVudC1jYXJkXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuaXMtc2VsZWN0ZWRdPVwiaXNTZWxlY3RlZChjb21wLmlkKVwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmlzLXJlc2l6aW5nXT1cInJlc2l6aW5nQ29tcElkKCkgPT09IGNvbXAuaWRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1maWVsZC1oaWdobGlnaHRlZF09XCJpc0ZpZWxkSGlnaGxpZ2h0ZWQoY29tcClcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1uYXJyb3ddPVwiZ2V0U3Bhbihjb21wKSA8PSA0XCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuaXMtY29tcGFjdF09XCJnZXRTcGFuKGNvbXApIDw9IDJcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5ncmlkLWNvbHVtbl09XCJnZXRHcmlkQ29sdW1uKGNvbXApXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuZ3JpZC1yb3ddPVwiZ2V0R3JpZFJvdyhjb21wKVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImNvbXAubGF5b3V0Py53aWR0aCB8fCAnYXV0bydcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHRdPVwiZ2V0Q29tcG9uZW50SGVpZ2h0KGNvbXApXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUubWluLWhlaWdodF09XCJnZXRDb21wb25lbnRNaW5IZWlnaHQoY29tcClcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJvblNlbGVjdChjb21wLmlkLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDwhLS0gQ2FyZCBIZWFkZXIgd2l0aCBEcmFnIEhhbmRsZSAmIEFjdGlvbnMgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC10aXRsZS1ncm91cFwiIGNka0RyYWdIYW5kbGUgdGl0bGU9XCJEcmFnIHRvIHJlb3JkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkcmFnLWhhbmRsZS1kb3RzXCI+4ouu4ouuPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gW25hbWVdPVwiZ2V0Q29tcG9uZW50SWNvbk5hbWUoY29tcC50eXBlKVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb21wLXRpdGxlXCIgW3RpdGxlXT1cImNvbXAubGFiZWwgfHwgY29tcC5rZXkgfHwgY29tcC50eXBlXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgY29tcC5sYWJlbCB8fCBjb21wLmtleSB8fCBjb21wLnR5cGUgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWFjdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBTdGF0aWMgc3BhbiBwaWxsICYgbmV3IHJvdyAvIHN0YXJ0IGNvbCBwaWxsIHdoZW4gbm90IGhvdmVyZWQgLyBub3Qgc2VsZWN0ZWQgLS0+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoY29tcC5sYXlvdXQ/LmNvbHVtbjsgYXMgY29sKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZXctcm93LXBpbGwtc3RhdGljXCIgdGl0bGU9XCJTdGFydHMgYXQgQ29sdW1uIHt7IGNvbCB9fVwiPkNvbCB7eyBjb2wgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIH0gQGVsc2UgaWYgKGNvbXAubGF5b3V0Py5uZXdSb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5ldy1yb3ctcGlsbC1zdGF0aWNcIiB0aXRsZT1cIlN0YXJ0cyBvbiBzZXBhcmF0ZSByb3dcIj7ihrMgUm93PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzcGFuLXBpbGwtc3RhdGljXCJcbiAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkNvbHVtbiBzcGFuOiB7eyBnZXRTcGFuKGNvbXApIH19IG9mIHt7IHRvdGFsQ29sdW1ucygpIH19IGNvbHVtbnNcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAge3sgZ2V0U3Bhbihjb21wKSB9fS97eyB0b3RhbENvbHVtbnMoKSB9fVxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBRdWljayBBY3Rpb24gU3RlcHBlciAmIEJ1dHRvbnMgKHJldmVhbGVkIG9uIGhvdmVyIG9yIHNlbGVjdGlvbikgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLXF1aWNrLWNvbnRyb2xzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNhcmQtYWN0aW9uLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuYnRuLWFjdGl2ZS10b2dnbGVdPVwiY29tcC5sYXlvdXQ/Lm5ld1Jvd1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlTmV3Um93KGNvbXAsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJ7eyBjb21wLmxheW91dD8ubmV3Um93ID8gJ1N0YXJ0cyBvbiBuZXcgcm93IChDbGljayB0byBwbGFjZSBpbmxpbmUpJyA6ICdTdGFydCBvbiBzZXBhcmF0ZSByb3cgKFJvdyBCcmVhayknIH19XCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNvcm5lci1kb3duLXJpZ2h0XCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwYW4tY29udHJvbC1ncm91cFwiIHRpdGxlPVwiQWRqdXN0IENvbHVtbiBTcGFuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNwYW4tYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImdldFNwYW4oY29tcCkgPD0gMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGp1c3RTcGFuKGNvbXAsIC0xLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJTaHJpbmsgQ29sdW1uIFNwYW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cIm1pbnVzXCIgW3NpemVdPVwiOVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3Bhbi1iYWRnZVwiIFt0aXRsZV09XCInQ29sdW1uIHNwYW46ICcgKyBnZXRTcGFuKGNvbXApICsgJyBvZiAnICsgdG90YWxDb2x1bW5zKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcGFuLW51bVwiPnt7IGdldFNwYW4oY29tcCkgfX08L3NwYW4+PHNwYW4gY2xhc3M9XCJzcGFuLXRvdGFsXCI+L3t7IHRvdGFsQ29sdW1ucygpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzcGFuLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJnZXRTcGFuKGNvbXApID49IHRvdGFsQ29sdW1ucygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFkanVzdFNwYW4oY29tcCwgMSwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiRXhwYW5kIENvbHVtbiBTcGFuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJwbHVzXCIgW3NpemVdPVwiOVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYXJkLWFjdGlvbi1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uRHVwbGljYXRlKGNvbXAuaWQsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJEdXBsaWNhdGUgY29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNvcHlcIiBbc2l6ZV09XCIxMlwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNhcmQtYWN0aW9uLWJ0biBidG4tZGVsZXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkRlbGV0ZShjb21wLmlkLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiUmVtb3ZlIGNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0cmFzaFwiIFtzaXplXT1cIjEyXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gQ2FyZCBCb2R5IFZpc3VhbCBQcmV2aWV3IC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHlcIj5cblxuICAgICAgICAgICAgICAgICAgQHN3aXRjaCAoY29tcC50eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgnaW5wdXQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2staW5wdXQtZmllbGRcIiAoY2xpY2spPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2NrLWxhYmVsXCI+e3sgY29tcC5sYWJlbCB8fCAnSW5wdXQnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChnZXRDYW52YXNDb250cm9sKGNvbXApOyBhcyBjdHJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1hY3RpdmUtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJjb21wLnByb3BlcnRpZXM/LlsncGxhY2Vob2xkZXInXSB8fCAnRW50ZXIgdGV4dC4uLidcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJjdHJsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9jdXMpPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2staW5wdXQtYm94XCI+e3sgY29tcC5wcm9wZXJ0aWVzPy5bJ3BsYWNlaG9sZGVyJ10gfHwgJ0VudGVyIHRleHQuLi4nIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdkcm9wZG93bicpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWxpdmUtY29udHJvbC13cmFwcGVyXCIgKGNsaWNrKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtZHJvcGRvd25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2NvbmZpZ109XCJjb21wXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dTdGF0dXNdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtwYXJlbnRGb3JtXT1cImNhbnZhc0Zvcm0oKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjb250cm9sXT1cImdldENhbnZhc0NvbnRyb2woY29tcClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoZHJvcGRvd25DbGljayk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgnZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1pbnB1dC1maWVsZFwiIChjbGljayk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stbGFiZWxcIj57eyBjb21wLmxhYmVsIHx8ICdEYXRlJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZ2V0Q2FudmFzQ29udHJvbChjb21wKTsgYXMgY3RybCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiZGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtYWN0aXZlLWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiY3RybFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvY3VzKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLXNlbGVjdC1ib3hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5ZWVlZLU1NLUREPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY2FsZW5kYXJcIiBbc2l6ZV09XCIxMlwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgnZGF0ZS1yYW5nZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWxpdmUtY29udHJvbC13cmFwcGVyXCIgKGNsaWNrKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtZGF0ZS1yYW5nZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY29uZmlnXT1cImNvbXBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY29udHJvbF09XCJnZXRDYW52YXNDb250cm9sKGNvbXApXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2staW5wdXQtZmllbGRcIiAoY2xpY2spPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2NrLWxhYmVsXCI+e3sgY29tcC5sYWJlbCB8fCAnTnVtYmVyJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZ2V0Q2FudmFzQ29udHJvbChjb21wKTsgYXMgY3RybCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1hY3RpdmUtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJjdHJsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9jdXMpPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2staW5wdXQtYm94XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY29tcC5wcm9wZXJ0aWVzPy5bJ3ByZWZpeCddIHx8ICcnIH19IDAuMDAge3sgY29tcC5wcm9wZXJ0aWVzPy5bJ3N1ZmZpeCddIHx8ICcnIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgnY2hlY2tib3gnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hlY2tib3gtZmllbGRcIiAoY2xpY2spPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChnZXRDYW52YXNDb250cm9sKGNvbXApOyBhcyBjdHJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNhbnZhcy1hY3RpdmUtY2hlY2tib3gtbGJsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtmb3JtQ29udHJvbF09XCJjdHJsXCIgKGZvY3VzKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0NoZWNrYm94JyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stY2hlY2stYm94XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjaGVja1wiIFtzaXplXT1cIjEwXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stbGFiZWxcIj57eyBjb21wLmxhYmVsIHx8ICdDaGVja2JveCcgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdyYWRpbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWxpdmUtY29udHJvbC13cmFwcGVyXCIgKGNsaWNrKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtcmFkaW9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2NvbmZpZ109XCJjb21wXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2NvbnRyb2xdPVwiZ2V0Q2FudmFzQ29udHJvbChjb21wKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtwYXJlbnRGb3JtXT1cImNhbnZhc0Zvcm0oKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgnYnV0dG9uJykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWJ0bi13cmFwcGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1vY2stYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzXT1cIididG4tJyArIChjb21wLnByb3BlcnRpZXM/LlsndmFyaWFudCddIHx8ICdwcmltYXJ5JylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MubW9jay1idG4tZnVsbF09XCJjb21wLnByb3BlcnRpZXM/LlsnZnVsbFdpZHRoJ10gPT09IHRydWUgfHwgY29tcC5sYXlvdXQ/LndpZHRoID09PSAnMTAwJSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0XT1cImdldEN1c3RvbUJ0bkhlaWdodChjb21wKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJnZXRDdXN0b21CdG5XaWR0aChjb21wKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkNhbnZhc0J1dHRvbkNsaWNrKGNvbXAsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGdldEN1c3RvbUJ0bkljb24oY29tcCk7IGFzIGJ0bkljb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gW25hbWVdPVwiYnRuSWNvblwiIFtzaXplXT1cIjE1XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBjb21wLmxhYmVsIHx8ICdCdXR0b24nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdrcGktY2FyZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1rcGktZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWtwaS1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2NrLWxhYmVsXCI+e3sgY29tcC5sYWJlbCB8fCAnS1BJIE1ldHJpYycgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwia3BpXCIgW3NpemVdPVwiMTRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1rcGktdmFsdWVcIj57eyBjb21wLnByb3BlcnRpZXM/LlsndmFsdWUnXSB8fCAnJDEyOCw0NTAnIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1rcGktZm9vdGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1rcGktdHJlbmRcIj4rMTIuNSU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1rcGktc3ViXCI+dnMgbGFzdCBwZXJpb2Q8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoJ2NoYXJ0Jykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2NrLWxhYmVsXCI+e3sgY29tcC5sYWJlbCB8fCAnUXVhcnRlcmx5IFNhbGVzIFJldmVudWUgKCQwMDApJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtYmFyc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1jb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1iYXJcIiBzdHlsZT1cImhlaWdodDogNDQlXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2NrLWJhci1sYmxcIj5RMSBKYW4tTWFyPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtY29sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtYmFyXCIgc3R5bGU9XCJoZWlnaHQ6IDYxJVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1iYXItbGJsXCI+UTIgQXByLUp1bjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWNvbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWJhclwiIHN0eWxlPVwiaGVpZ2h0OiA3OSVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stYmFyLWxibFwiPlEzIEp1bC1TZXA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1jb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1iYXJcIiBzdHlsZT1cImhlaWdodDogMTAwJVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1iYXItbGJsXCI+UTQgT2N0LURlYzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAZGVmYXVsdCB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stZ2VuZXJpYy1ib3hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGNvbXAudHlwZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBSZXNpemluZyBIYW5kbGVzIChFYXN0LCBTb3V0aCwgU291dGgtRWFzdCkgLS0+XG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyZXNpemUtaGFuZGxlIGhhbmRsZS1lXCJcbiAgICAgICAgICAgICAgICAgIChwb2ludGVyZG93bik9XCJzdGFydFJlc2l6ZSgkZXZlbnQsIGNvbXAsICdlJylcIlxuICAgICAgICAgICAgICAgICAgKGRibGNsaWNrKT1cInJlc2V0RGltZW5zaW9ucyhjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiRHJhZyB0byByZXNpemUgY29sdW1uIHdpZHRoIOKAoiBEb3VibGUtY2xpY2sgdG8gcmVzZXRcIlxuICAgICAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInJlc2l6ZS1oYW5kbGUgaGFuZGxlLXNcIlxuICAgICAgICAgICAgICAgICAgKHBvaW50ZXJkb3duKT1cInN0YXJ0UmVzaXplKCRldmVudCwgY29tcCwgJ3MnKVwiXG4gICAgICAgICAgICAgICAgICAoZGJsY2xpY2spPVwicmVzZXREaW1lbnNpb25zKGNvbXAsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgdGl0bGU9XCJEcmFnIHRvIHJlc2l6ZSBoZWlnaHQg4oCiIERvdWJsZS1jbGljayB0byByZXNldFwiXG4gICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwicmVzaXplLWhhbmRsZSBoYW5kbGUtc2VcIlxuICAgICAgICAgICAgICAgICAgKHBvaW50ZXJkb3duKT1cInN0YXJ0UmVzaXplKCRldmVudCwgY29tcCwgJ3NlJylcIlxuICAgICAgICAgICAgICAgICAgKGRibGNsaWNrKT1cInJlc2V0RGltZW5zaW9ucyhjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiRHJhZyB0byByZXNpemUgd2lkdGggYW5kIGhlaWdodCDigKIgRG91YmxlLWNsaWNrIHRvIHJlc2V0XCJcbiAgICAgICAgICAgICAgICA+PC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8IS0tIFJlc2l6aW5nIERpbWVuc2lvbiBHaG9zdCAvIEJhZGdlIC0tPlxuICAgICAgICAgICAgICAgIEBpZiAocmVzaXppbmdDb21wSWQoKSA9PT0gY29tcC5pZCkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc2l6ZS1kaW1lbnNpb24tdG9vbHRpcFwiPlxuICAgICAgICAgICAgICAgICAgICB7eyByZXNpemluZ1Rvb2x0aXAoY29tcCkgfX1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIDwhLS0gRHJhZyBwbGFjZWhvbGRlciB3aXRoIG1hdGNoZWQgZ3JpZCBjb2x1bW4gc3BhbiAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAqY2RrRHJhZ1BsYWNlaG9sZGVyXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1kcmFnLXBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS5ncmlkLWNvbHVtbl09XCJnZXRHcmlkQ29sdW1uKGNvbXApXCJcbiAgICAgICAgICAgICAgICA+PC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8IS0tIERyYWcgcHJldmlldyAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2ICpjZGtEcmFnUHJldmlldyBjbGFzcz1cImNhbnZhcy1kcmFnLXByZXZpZXdcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZHJhZy1oYW5kbGUtZG90c1wiPuKLruKLrjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBbbmFtZV09XCJnZXRDb21wb25lbnRJY29uTmFtZShjb21wLnR5cGUpXCIgW3NpemVdPVwiMTRcIiAvPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwcmV2aWV3LXRpdGxlXCI+e3sgY29tcC5sYWJlbCB8fCBjb21wLmtleSB8fCBjb21wLnR5cGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInByZXZpZXctc3BhblwiPnt7IGdldFNwYW4oY29tcCkgfX0ve3sgdG90YWxDb2x1bW5zKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBAaWYgKGNvbXBvbmVudHMoKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1lbXB0eS1zdGF0ZVwiIHJvbGU9XCJyZWdpb25cIiBhcmlhLWxhYmVsPVwiRW1wdHkgY2FudmFzIHN0YXJ0ZXIgb3B0aW9uc1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlbXB0eS1oZXJvLWJhZGdlXCI+XG4gICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImRlc2lnblwiIFtzaXplXT1cIjI4XCIgLz5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJlbXB0eS1oZXJvLXRpdGxlXCI+U3RhcnQgRGVzaWduaW5nIFlvdXIgQ3VzdG9tIFJlcG9ydDwvaDM+XG4gICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJlbXB0eS1oZXJvLWRlc2NcIj5cbiAgICAgICAgICAgICAgICAgIERyYWcgY29udHJvbHMgZnJvbSB0aGUgbGVmdCBjb21wb25lbnQgcGFsZXR0ZSwgb3IganVtcHN0YXJ0IHlvdXIgZGVzaWduIHdpdGggcHJlLWNvbmZpZ3VyZWQgZW50ZXJwcmlzZSBibHVlcHJpbnRzLlxuICAgICAgICAgICAgICAgIDwvcD5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlbXB0eS1oZXJvLWFjdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZW1wdHktYnRuIGVtcHR5LWJ0bi1wcmltYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFwcGx5Qmx1ZXByaW50KCdibHVlcHJpbnQtYXVkaXQtcmVnaXN0ZXInKVwiXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiTG9hZCBjb21wbGV0ZSBBdWRpdCBSZWdpc3RlciBibHVlcHJpbnQgd2l0aCBwYXJhbWV0ZXJzIGFuZCByZXN1bHQgZ3JpZFwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwidGFibGVcIiBbc2l6ZV09XCIxNVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPkF1ZGl0IFJlZ2lzdGVyIEJsdWVwcmludDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJlbXB0eS1idG4gZW1wdHktYnRuLXNlY29uZGFyeVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhcHBseUJsdWVwcmludCgnYmx1ZXByaW50LWtwaS1zdW1tYXJ5JylcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkxvYWQgRXhlY3V0aXZlIEtQSSBzdW1tYXJ5IGJsdWVwcmludFwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY2hhcnQtYmFyXCIgW3NpemVdPVwiMTVcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5LUEkgU3VtbWFyeSBCbHVlcHJpbnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZW1wdHktYnRuIGVtcHR5LWJ0bi1vdXRsaW5lXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFkZFN0YXJ0ZXJDb21wb25lbnQoJ2RhdGUtcmFuZ2UnKVwiXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQWRkIGEgRGF0ZSBSYW5nZSBmaWx0ZXIgY29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjYWxlbmRhclwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+KyBBZGQgRGF0ZSBGaWx0ZXI8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZW1wdHktYnRuIGVtcHR5LWJ0bi1vdXRsaW5lXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFkZFN0YXJ0ZXJDb21wb25lbnQoJ2J1dHRvbicpXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJBZGQgYW4gRXhlY3V0ZSBBY3Rpb24gYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJwbGF5XCIgW3NpemVdPVwiMTRcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj4rIEFkZCBSdW4gQnV0dG9uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBMaXZlIFJlc3VsdCBHcmlkIFByZXZpZXcgd2l0aCBCd2F5cy1HcmlkIEZlYXR1cmVzIC0tPlxuICAgICAgICAgIEBpZiAoZGVmaW5pdGlvbigpLmdyaWQpIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtZ3JpZC1ib3hcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtcHJldmlldy1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMTVcIiAvPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncmlkLXRpdGxlXCI+QndheXMgR3JpZCAoe3sgZGVmaW5pdGlvbigpLmdyaWQ/LmNvbHVtbnM/Lmxlbmd0aCA/PyAwIH19IGNvbHVtbnMpPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgQGlmIChpc0V4ZWN1dGluZ0dyaWQoKSkge1xuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImdyaWQtZXhlYy1iYWRnZSBpcy1sb2FkaW5nXCI+TG9hZGluZyBkYXRhIGZyb20gZGF0YWJhc2UuLi48L3NwYW4+XG4gICAgICAgICAgICAgICAgICB9IEBlbHNlIGlmIChncmlkRXhlY0Vycm9yKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncmlkLWV4ZWMtYmFkZ2UgaXMtZXJyb3JcIj57eyBncmlkRXhlY0Vycm9yKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICB9IEBlbHNlIGlmIChjYW52YXNHcmlkRGF0YSgpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncmlkLWV4ZWMtYmFkZ2UgaXMtc3VjY2Vzc1wiPnt7IGNhbnZhc0dyaWREYXRhKCkubGVuZ3RoIH19IHJvd3MgbG9hZGVkPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDhweDtcIj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuLWNhbnZhcy1ydW4tZ3JpZFwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJleGVjdXRlQ2FudmFzUmVwb3J0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiaXNFeGVjdXRpbmdHcmlkKClcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkV4ZWN1dGUgcXVlcnkgYW5kIGxvYWQgZGF0YSBpbnRvIEJ3YXlzIEdyaWRcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInBsYXlcIiBbc2l6ZV09XCIxMVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGlzRXhlY3V0aW5nR3JpZCgpID8gJ1J1bm5pbmcuLi4nIDogJ1J1biAvIFJlZnJlc2ggR3JpZCcgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuLWNhbnZhcy1lZGl0LWdyaWRcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0R3JpZFNldHRpbmdzKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkNvbmZpZ3VyZSBjb2x1bW5zIGFuZCBncmlkIG9wdGlvbnNcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInNldHRpbmdzXCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5Db25maWd1cmU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuLXJlbW92ZS1ncmlkXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZUdyaWQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiUmVtb3ZlIFJlc3VsdCBHcmlkIGZyb20gdGhpcyByZXBvcnRcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRyYXNoXCIgW3NpemVdPVwiMTNcIiAvPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgIEBpZiAoZ2V0R3JpZFN1bW1hcnlUZXh0KCk7IGFzIHN1bW1hcnkpIHtcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JpZC1sYXlvdXQtc3RhdHVzLXN0cmlwXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JpZC1zdGF0dXMtaW5mb1wiPlxuICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBzdW1tYXJ5IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JpZC1zdGF0dXMtc3luY1wiIFtjbGFzcy5pcy1wdWxzaW5nXT1cImxheW91dEp1c3RVcGRhdGVkKClcIj5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjaGVja1wiIFtzaXplXT1cIjExXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+TGF5b3V0IGF1dG8tcGVyc2lzdGVkPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICA8IS0tIExpdmUgQndheXMgR3JpZCBicmlkZ2UgLS0+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtbGl2ZS1ncmlkLWNvbnRhaW5lclwiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiBzdHlsZT1cInBvc2l0aW9uOiByZWxhdGl2ZTsgbWluLWhlaWdodDogMjUwcHg7XCI+XG4gICAgICAgICAgICAgICAgQGlmIChpc0V4ZWN1dGluZ0dyaWQoKSkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1ncmlkLWxvYWRpbmctb3ZlcmxheVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1kb3QgZG90LXB1bHNlXCIgc3R5bGU9XCJ3aWR0aDogMTRweDsgaGVpZ2h0OiAxNHB4OyBjb2xvcjogIzI1NjNlYjsgYmFja2dyb3VuZDogIzI1NjNlYjsgYm9yZGVyLXJhZGl1czogNTAlO1wiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncmlkLWxvYWRpbmctdGl0bGVcIj5FeGVjdXRpbmcgc3RvcmVkIHByb2NlZHVyZSBvbiBTUUwgU2VydmVyLi4uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImdyaWQtbG9hZGluZy1zdWJcIj5DYWxjdWxhdGluZyBvdXRzdGFuZGluZyBiYWxhbmNlcyBhbmQgbGVkZ2VyIGFtb3VudHMuIFBsZWFzZSB3YWl0Li4uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDxycHQtZ3JpZC1icmlkZ2VcbiAgICAgICAgICAgICAgICAgIFtncmlkRGVmaW5pdGlvbl09XCJkZWZpbml0aW9uKCkuZ3JpZCFcIlxuICAgICAgICAgICAgICAgICAgW2RhdGFdPVwiY2FudmFzR3JpZERhdGEoKVwiXG4gICAgICAgICAgICAgICAgICAoZ3JpZFN0YXRlQ2hhbmdlKT1cIm9uQ2FudmFzR3JpZFN0YXRlQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKGNvbHVtbkRlZnNDaGFuZ2UpPVwib25DYW52YXNDb2x1bW5EZWZzQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWFkZC1ncmlkLWJhbm5lclwiIChjbGljayk9XCJhZGRSZXN1bHRHcmlkKCRldmVudClcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFkZC1ncmlkLWljb25cIj5cbiAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMjBcIiAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFkZC1ncmlkLXRleHRcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFkZC1ncmlkLXRpdGxlXCI+KyBBZGQgUmVzdWx0IERhdGEgR3JpZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFkZC1ncmlkLXN1YlwiPkF0dGFjaCBhbiBpbnRlcmFjdGl2ZSBkYXRhIHRhYmxlIG9yIFVsdHJhR3JpZCB0byBkaXNwbGF5IHJlcG9ydCBleGVjdXRpb24gb3V0cHV0PC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tYmFubmVyLWFkZFwiPkFkZCBHcmlkPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+Il19