bways-report 0.1.5 → 0.1.6
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.
- package/README.md +75 -35
- package/esm2022/lib/core/services/index.mjs +2 -1
- package/esm2022/lib/core/services/report-data-discovery.service.mjs +135 -0
- package/esm2022/lib/core/tokens/reporting-config.token.mjs +1 -1
- package/esm2022/lib/core/utils/identifier-humanizer.mjs +15 -4
- package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +17 -8
- package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +69 -11
- package/esm2022/lib/features/designer/components/property-editor/parameter-binding-editor.component.mjs +345 -213
- package/esm2022/lib/features/designer/components/property-editor/property-editor-action.component.mjs +39 -32
- package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +35 -3
- package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +97 -5
- package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +112 -39
- package/esm2022/lib/features/designer/designer.component.mjs +3 -3
- package/esm2022/lib/features/designer/services/designer-state.service.mjs +62 -2
- package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +106 -14
- package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +31 -5
- package/esm2022/lib/provide-reporting.mjs +20 -5
- package/fesm2022/bways-report.mjs +1620 -896
- package/fesm2022/bways-report.mjs.map +1 -1
- package/lib/core/services/index.d.ts +1 -0
- package/lib/core/services/report-data-discovery.service.d.ts +38 -0
- package/lib/core/tokens/reporting-config.token.d.ts +2 -0
- package/lib/data-access/adapters/http-lookup.adapter.d.ts +2 -1
- package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +5 -1
- package/lib/features/designer/components/property-editor/parameter-binding-editor.component.d.ts +5 -0
- package/lib/features/designer/components/property-editor/property-editor-action.component.d.ts +3 -0
- package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +31 -1
- package/lib/features/designer/components/property-editor/property-editor.component.d.ts +19 -0
- package/lib/features/designer/services/designer-state.service.d.ts +12 -1
- package/lib/features/runtime/report-grid-bridge.component.d.ts +7 -58
- package/lib/primitives/components/dropdown/rpt-dropdown.component.d.ts +3 -0
- package/lib/provide-reporting.d.ts +6 -0
- package/package.json +1 -1
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { ChangeDetectionStrategy, Component, computed, effect, ElementRef, HostListener, inject, input, signal, untracked, viewChild, } from '@angular/core';
|
|
2
2
|
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
|
3
|
+
import { throwError } from 'rxjs';
|
|
4
|
+
import { timeout } from 'rxjs/operators';
|
|
3
5
|
import { getValidationMessage } from '../../../core/validation/validation-factory';
|
|
4
6
|
import { MasterDataProvider } from '../../../data-access/contracts/master-data.provider';
|
|
5
7
|
import { ReportLookupAdapter } from '../../../data-access/contracts/lookup.contract';
|
|
6
8
|
import { ReportSessionContextService } from '../../../core/services/report-session-context.service';
|
|
9
|
+
import { REPORTING_CONFIG } from '../../../core/tokens/reporting-config.token';
|
|
7
10
|
import { findMissingCanvasFields, resolveParameterMappings, } from '../../../core/utils/report-parameter.util';
|
|
8
11
|
import * as i0 from "@angular/core";
|
|
9
12
|
import * as i1 from "@angular/forms";
|
|
@@ -11,6 +14,7 @@ export class RptDropdownComponent {
|
|
|
11
14
|
masterDataProvider = inject(MasterDataProvider, { optional: true });
|
|
12
15
|
lookupAdapter = inject(ReportLookupAdapter, { optional: true });
|
|
13
16
|
sessionService = inject(ReportSessionContextService, { optional: true });
|
|
17
|
+
reportingConfig = inject(REPORTING_CONFIG, { optional: true });
|
|
14
18
|
elementRef = inject(ElementRef);
|
|
15
19
|
config = input.required();
|
|
16
20
|
control = input();
|
|
@@ -227,6 +231,16 @@ export class RptDropdownComponent {
|
|
|
227
231
|
this.searchTerm.set('');
|
|
228
232
|
this.focusedIndex.set(-1);
|
|
229
233
|
}
|
|
234
|
+
/** Manually retry loading dynamic lookup options (e.g. after database timeout). */
|
|
235
|
+
retryLookup(event) {
|
|
236
|
+
if (event) {
|
|
237
|
+
event.stopPropagation();
|
|
238
|
+
event.preventDefault();
|
|
239
|
+
}
|
|
240
|
+
this.lastRequestKey = '';
|
|
241
|
+
this.loadError.set(null);
|
|
242
|
+
this.reloadDataSourceOptions(this.sessionService?.sessionContext() ?? {});
|
|
243
|
+
}
|
|
230
244
|
clearSearch(event) {
|
|
231
245
|
event.stopPropagation();
|
|
232
246
|
this.searchTerm.set('');
|
|
@@ -315,7 +329,7 @@ export class RptDropdownComponent {
|
|
|
315
329
|
if (form && this.isDynamicSource()) {
|
|
316
330
|
this.formChangesSub = form.valueChanges.subscribe(() => this.scheduleReload());
|
|
317
331
|
}
|
|
318
|
-
untracked(() => this.
|
|
332
|
+
untracked(() => this.scheduleReload());
|
|
319
333
|
}, { allowSignalWrites: true });
|
|
320
334
|
}
|
|
321
335
|
ngOnDestroy() {
|
|
@@ -369,10 +383,22 @@ export class RptDropdownComponent {
|
|
|
369
383
|
if (requestKey === this.lastRequestKey)
|
|
370
384
|
return; // nothing changed
|
|
371
385
|
this.lastRequestKey = requestKey;
|
|
386
|
+
// Stored procedures on local databases can take a couple minutes to execute.
|
|
387
|
+
// Default timeout is 300,000ms (5 minutes), configurable via component properties or reportingConfig.
|
|
388
|
+
const timeoutMs = ds?.timeoutMs ||
|
|
389
|
+
this.config().properties?.['timeoutMs'] ||
|
|
390
|
+
this.reportingConfig?.lookupTimeoutMs ||
|
|
391
|
+
300000;
|
|
372
392
|
this.isLoading.set(true);
|
|
373
393
|
this.loadError.set(null);
|
|
374
394
|
this.lookupSub?.unsubscribe();
|
|
375
|
-
this.lookupSub = this.lookupAdapter
|
|
395
|
+
this.lookupSub = this.lookupAdapter
|
|
396
|
+
.fetchOptions(request)
|
|
397
|
+
.pipe(timeout({
|
|
398
|
+
each: timeoutMs,
|
|
399
|
+
with: () => throwError(() => new Error(`Lookup query timed out after ${Math.round(timeoutMs / 1000)}s (stored procedure took too long to respond on local database)`)),
|
|
400
|
+
}))
|
|
401
|
+
.subscribe({
|
|
376
402
|
next: (items) => {
|
|
377
403
|
this.isLoading.set(false);
|
|
378
404
|
this.hasLoaded.set(true);
|
|
@@ -422,14 +448,14 @@ export class RptDropdownComponent {
|
|
|
422
448
|
}
|
|
423
449
|
}
|
|
424
450
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RptDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
425
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: RptDropdownComponent, isStandalone: true, selector: "rpt-dropdown", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, parentForm: { classPropertyName: "parentForm", publicName: "parentForm", isSignal: true, isRequired: false, transformFunction: null }, showStatus: { classPropertyName: "showStatus", publicName: "showStatus", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" }, properties: { "class.is-open": "isOpen()", "class.opens-above": "opensAbove()" } }, viewQueries: [{ propertyName: "comboboxWrapperEl", first: true, predicate: ["comboboxWrapper"], descendants: true, isSignal: true }, { propertyName: "searchInputEl", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }, { propertyName: "optionsListEl", first: true, predicate: ["optionsListEl"], descendants: true, isSignal: true }], ngImport: i0, template: " <div class=\"rpt-field-group\">\n @if (config().label) {\n <label [for]=\"elementId()\" class=\"rpt-label\">\n {{ config().label }}\n @if (config().validation?.required) {\n <span class=\"rpt-required-marker\">*</span>\n }\n </label>\n }\n\n @if (isSearchable()) {\n <!-- Searchable Typeahead Combobox -->\n <div class=\"rpt-combobox-wrapper\" #comboboxWrapper>\n <button\n type=\"button\"\n class=\"rpt-combobox-trigger\"\n [id]=\"elementId()\"\n [class.rpt-invalid]=\"isInvalid()\"\n [class.is-open]=\"isOpen()\"\n [disabled]=\"formControl().disabled\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n (click)=\"toggleOpen($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"trigger-label\" [class.is-placeholder]=\"!selectedOption()\">\n {{ selectedOption() ? selectedOption()!.label : placeholder() }}\n </span>\n\n <div class=\"trigger-actions\">\n @if (selectedOption() && !formControl().disabled) {\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"trigger-clear-btn\"\n title=\"Clear selection\"\n aria-label=\"Clear selection\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n \u2715\n </span>\n }\n <span class=\"trigger-arrow\" [class.rotated]=\"isOpen()\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </div>\n </button>\n\n @if (isOpen()) {\n <div\n class=\"rpt-combobox-menu\"\n [class.opens-above]=\"opensAbove()\"\n role=\"listbox\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Real-time Filter Search Box -->\n <div class=\"combobox-search-box\">\n <span class=\"combobox-search-icon\" aria-hidden=\"true\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n </svg>\n </span>\n <input\n #searchInput\n type=\"text\"\n class=\"combobox-search-input\"\n placeholder=\"Type to filter...\"\n [value]=\"searchTerm()\"\n [attr.aria-activedescendant]=\"focusedIndex() >= 0 ? (elementId() + '_opt_' + focusedIndex()) : null\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n @if (searchTerm()) {\n <button\n type=\"button\"\n class=\"combobox-search-clear\"\n title=\"Clear filter\"\n (click)=\"clearSearch($event)\"\n >\n \u2715\n </button>\n }\n </div>\n\n <!-- Filtered Options List -->\n <div class=\"combobox-options-list\" #optionsListEl>\n @if (isLoading()) {\n <div class=\"combobox-status-row loading\">\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading options from database...</span>\n </div>\n } @else if (loadError()) {\n <div class=\"combobox-status-row error\">\n <span>Error: {{ loadError() }}</span>\n </div>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No records found (check parameters)</span>\n </div>\n } @else if (filteredOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No options matching \"{{ searchTerm() }}\"</span>\n </div>\n } @else {\n @for (opt of visibleFilteredOptions(); track opt.key; let i = $index) {\n <div\n role=\"option\"\n [id]=\"elementId() + '_opt_' + i\"\n class=\"combobox-option-item\"\n [class.is-selected]=\"isSelected(opt)\"\n [class.is-focused]=\"focusedIndex() === i\"\n [attr.aria-selected]=\"isSelected(opt)\"\n (click)=\"selectOption(opt)\"\n (mouseenter)=\"focusedIndex.set(i)\"\n >\n <span class=\"opt-label\">{{ opt.label }}</span>\n @if (isSelected(opt)) {\n <span class=\"opt-check\" aria-hidden=\"true\">\u2713</span>\n }\n </div>\n }\n @if (excessFilteredCount() > 0) {\n <div class=\"combobox-status-row hint\">\n <span>Showing {{ MAX_FILTER_RENDER }} of {{ filteredOptions().length }} matches. Type to refine.</span>\n </div>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <!-- Native Browser Select Fallback -->\n <div class=\"rpt-select-wrapper\">\n <select\n [id]=\"elementId()\"\n [formControl]=\"formControl()\"\n [class.rpt-invalid]=\"isInvalid()\"\n class=\"rpt-select\"\n >\n @if (isLoading()) {\n <option value=\"\" disabled selected>Loading options from database...</option>\n } @else if (loadError()) {\n <option value=\"\" disabled selected>Error: {{ loadError() }}</option>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <option value=\"\" disabled selected>-- No records found (check parameters) --</option>\n } @else if (placeholder()) {\n <option value=\"\" [disabled]=\"config().validation?.required\">{{ placeholder() }}</option>\n }\n @for (opt of renderedOptions(); track opt.key) {\n <option [value]=\"opt.key\">{{ opt.label }}</option>\n }\n @if (hasExcessOptions()) {\n <option value=\"\" disabled>... and {{ excessOptionsCount() }} more records (refine filter) ...</option>\n }\n </select>\n <div class=\"rpt-select-arrow\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n }\n\n @if (showStatus() && isDynamicSource() && statusText()) {\n <div class=\"rpt-status-badge\" [attr.data-status]=\"statusKind()\">\n @switch (statusKind()) {\n @case ('loading') {\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading from database\u2026</span>\n }\n @case ('ok') {\n <span class=\"status-dot dot-ok\"></span>\n <span>{{ dynamicOptions().length }} records loaded</span>\n }\n @case ('waiting') {\n <span class=\"status-dot dot-warn\"></span>\n <span>Waiting for:</span>\n <div class=\"waiting-tokens\">\n @for (k of waitingFor(); track k) {\n <span class=\"waiting-token\">{{ k }}</span>\n }\n </div>\n }\n @case ('error') {\n <span class=\"status-dot dot-err\"></span>\n <span>{{ loadError() }}</span>\n }\n @case ('empty') {\n <span class=\"status-dot\"></span>\n <span>No records found for parameters</span>\n }\n @default {\n <span class=\"status-dot\"></span>\n }\n }\n </div>\n }\n\n @if (errorMessage()) {\n <span class=\"rpt-error-text\">{{ errorMessage() }}</span>\n }\n </div>", styles: [":host{display:block;width:100%;max-width:100%;min-width:0;box-sizing:border-box;font-family:var(--rpt-font-family, inherit);position:relative}.rpt-status-badge{display:flex;flex-wrap:wrap;align-items:center;gap:4px;font-size:.6875rem;padding:3px 6px;border-radius:4px;margin-top:4px;font-weight:500;line-height:1.3;max-width:100%;box-sizing:border-box;overflow:hidden;word-break:break-word}.rpt-status-badge>span{overflow-wrap:anywhere;word-break:break-word}.rpt-status-badge[data-status=loading]{background:#eff6ff;color:#2563eb;border:1px solid #dbeafe}.rpt-status-badge[data-status=ok]{background:#f0fdf4;color:#16a34a;border:1px solid #dcfce7}.rpt-status-badge[data-status=waiting]{background:#fffbeb;color:#d97706;border:1px solid #fef3c7}.rpt-status-badge[data-status=error]{background:#fef2f2;color:#dc2626;border:1px solid #fee2e2}.rpt-status-badge[data-status=empty]{background:#f8fafc;color:#64748b;border:1px solid #e2e8f0}.waiting-tokens{display:inline-flex;flex-wrap:wrap;align-items:center;gap:3px;margin-left:2px;max-width:100%}.waiting-token{background:#b453091f;border:1px solid rgba(180,83,9,.3);padding:1px 5px;border-radius:3px;font-weight:700;font-size:.625rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;box-sizing:border-box}.status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.dot-pulse{animation:rpt-pulse 1s infinite alternate}@keyframes rpt-pulse{0%{opacity:.3}to{opacity:1}}.rpt-field-group{display:flex;flex-direction:column;max-width:100%;min-width:0;gap:4px;box-sizing:border-box;position:relative}.rpt-label{font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;color:var(--rpt-color-text, #0f172a);flex-shrink:0}.rpt-required-marker{color:var(--rpt-color-danger, #ef4444);margin-left:2px}.rpt-select-wrapper{position:relative;width:100%;flex:1;min-height:0;display:flex;align-items:center}.rpt-select{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 36px 6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);appearance:none;-webkit-appearance:none;outline:none;cursor:pointer;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-select:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-select:focus{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-select:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-select.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-select.rpt-invalid:focus{box-shadow:0 0 0 3px #ef444440}.rpt-select-arrow{position:absolute;right:12px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--rpt-color-text-muted, #64748b);display:flex;align-items:center}.rpt-combobox-wrapper{position:relative;width:100%;flex:1;min-height:0}.rpt-combobox-trigger{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 10px 6px 12px;display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:var(--rpt-font-size-base, .875rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);outline:none;cursor:pointer;text-align:left;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-combobox-trigger:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-combobox-trigger:focus-visible,.rpt-combobox-trigger.is-open{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-combobox-trigger:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-combobox-trigger.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-combobox-trigger.rpt-invalid:focus-visible{box-shadow:0 0 0 3px #ef444440}.trigger-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}.trigger-label.is-placeholder{color:var(--rpt-color-text-muted, #94a3b8)}.trigger-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.trigger-clear-btn{display:flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;font-size:.6875rem;color:var(--rpt-color-text-muted, #64748b);background-color:#f1f5f9;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease,color .15s ease}.trigger-clear-btn:hover{background-color:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.trigger-arrow{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);transition:transform .18s ease}.trigger-arrow.rotated{transform:rotate(180deg)}.rpt-combobox-menu{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:1050;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:0 10px 25px -5px #0000001f,0 8px 10px -6px #00000014;overflow:hidden;display:flex;flex-direction:column;animation:rpt-dropdown-pop .12s cubic-bezier(0,0,.2,1)}.rpt-combobox-menu.opens-above{top:auto;bottom:calc(100% + 4px);box-shadow:0 -10px 25px -5px #0000001f,0 -8px 10px -6px #00000014;animation:rpt-dropdown-pop-above .12s cubic-bezier(0,0,.2,1)}@keyframes rpt-dropdown-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes rpt-dropdown-pop-above{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.combobox-search-box{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);background-color:#f8fafc}.combobox-search-icon{color:var(--rpt-color-text-muted, #94a3b8);display:flex;align-items:center;flex-shrink:0}.combobox-search-input{flex:1;border:none;outline:none;background:transparent;font-size:var(--rpt-font-size-sm, .8125rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);min-width:0}.combobox-search-input::placeholder{color:#94a3b8}.combobox-search-clear{border:none;background:#e2e8f0;color:#64748b;width:16px;height:16px;border-radius:50%;font-size:.625rem;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}.combobox-search-clear:hover{background:#cbd5e1;color:#0f172a}.combobox-options-list{max-height:220px;overflow-y:auto;overscroll-behavior:contain;padding:4px}.combobox-option-item{display:flex;align-items:center;justify-content:space-between;padding:7px 10px;border-radius:4px;font-size:var(--rpt-font-size-base, .84rem);color:var(--rpt-color-text, #0f172a);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .1s ease}.combobox-option-item.is-focused{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.combobox-option-item.is-selected{background-color:#eff6ff;color:var(--rpt-color-primary, #2563eb);font-weight:600}.opt-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opt-check{font-size:.875rem;font-weight:700;color:var(--rpt-color-primary, #2563eb);margin-left:8px}.combobox-status-row{padding:10px 12px;font-size:.78rem;text-align:center;color:var(--rpt-color-text-muted, #64748b)}.combobox-status-row.loading{display:flex;align-items:center;justify-content:center;gap:6px;color:#2563eb}.combobox-status-row.error{color:var(--rpt-color-danger, #dc2626)}.combobox-status-row.hint{font-size:.72rem;color:#94a3b8;border-top:1px dashed #e2e8f0;margin-top:4px;padding:6px}.rpt-error-text{font-size:.7rem;color:var(--rpt-color-danger, #ef4444);margin-top:3px;line-height:1.25;max-width:100%;overflow-wrap:anywhere;word-break:break-word;display:block}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
451
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: RptDropdownComponent, isStandalone: true, selector: "rpt-dropdown", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, parentForm: { classPropertyName: "parentForm", publicName: "parentForm", isSignal: true, isRequired: false, transformFunction: null }, showStatus: { classPropertyName: "showStatus", publicName: "showStatus", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" }, properties: { "class.is-open": "isOpen()", "class.opens-above": "opensAbove()" } }, viewQueries: [{ propertyName: "comboboxWrapperEl", first: true, predicate: ["comboboxWrapper"], descendants: true, isSignal: true }, { propertyName: "searchInputEl", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }, { propertyName: "optionsListEl", first: true, predicate: ["optionsListEl"], descendants: true, isSignal: true }], ngImport: i0, template: " <div class=\"rpt-field-group\">\n @if (config().label) {\n <label [for]=\"elementId()\" class=\"rpt-label\">\n {{ config().label }}\n @if (config().validation?.required) {\n <span class=\"rpt-required-marker\">*</span>\n }\n </label>\n }\n\n @if (isSearchable()) {\n <!-- Searchable Typeahead Combobox -->\n <div class=\"rpt-combobox-wrapper\" #comboboxWrapper>\n <button\n type=\"button\"\n class=\"rpt-combobox-trigger\"\n [id]=\"elementId()\"\n [class.rpt-invalid]=\"isInvalid()\"\n [class.is-open]=\"isOpen()\"\n [disabled]=\"formControl().disabled\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n (click)=\"toggleOpen($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"trigger-label\" [class.is-placeholder]=\"!selectedOption()\">\n {{ selectedOption() ? selectedOption()!.label : placeholder() }}\n </span>\n\n <div class=\"trigger-actions\">\n @if (isLoading()) {\n <span class=\"status-dot dot-pulse\" style=\"color: #2563eb; margin-right: 4px;\" title=\"Executing query on database...\"></span>\n }\n @if (loadError() && !isLoading()) {\n <button\n type=\"button\"\n class=\"trigger-retry-btn\"\n title=\"Retry database query\"\n aria-label=\"Retry database query\"\n (click)=\"retryLookup($event)\"\n >\n \u21BB Retry\n </button>\n }\n @if (selectedOption() && !formControl().disabled) {\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"trigger-clear-btn\"\n title=\"Clear selection\"\n aria-label=\"Clear selection\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n \u2715\n </span>\n }\n <span class=\"trigger-arrow\" [class.rotated]=\"isOpen()\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </div>\n </button>\n\n @if (isOpen()) {\n <div\n class=\"rpt-combobox-menu\"\n [class.opens-above]=\"opensAbove()\"\n role=\"listbox\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Real-time Filter Search Box -->\n <div class=\"combobox-search-box\">\n <span class=\"combobox-search-icon\" aria-hidden=\"true\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n </svg>\n </span>\n <input\n #searchInput\n type=\"text\"\n class=\"combobox-search-input\"\n placeholder=\"Type to filter...\"\n [value]=\"searchTerm()\"\n [attr.aria-activedescendant]=\"focusedIndex() >= 0 ? (elementId() + '_opt_' + focusedIndex()) : null\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n @if (searchTerm()) {\n <button\n type=\"button\"\n class=\"combobox-search-clear\"\n title=\"Clear filter\"\n (click)=\"clearSearch($event)\"\n >\n \u2715\n </button>\n }\n </div>\n\n <!-- Filtered Options List -->\n <div class=\"combobox-options-list\" #optionsListEl>\n @if (waitingFor().length > 0) {\n <div class=\"combobox-status-row waiting\">\n <span>Waiting for {{ waitingLabel() }}...</span>\n </div>\n } @else if (isLoading()) {\n <div class=\"combobox-status-row loading\">\n <span class=\"status-dot dot-pulse\"></span>\n <span>Executing query on database (may take 1\u20132 minutes on local database)...</span>\n </div>\n } @else if (loadError()) {\n <div class=\"combobox-status-row error\">\n <span>Error: {{ loadError() }}</span>\n <button type=\"button\" class=\"combobox-retry-btn\" (click)=\"retryLookup($event)\">\u21BB Retry Query</button>\n </div>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No records found (check parameters)</span>\n </div>\n } @else if (filteredOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No options matching \"{{ searchTerm() }}\"</span>\n </div>\n } @else {\n @for (opt of visibleFilteredOptions(); track opt.key; let i = $index) {\n <div\n role=\"option\"\n [id]=\"elementId() + '_opt_' + i\"\n class=\"combobox-option-item\"\n [class.is-selected]=\"isSelected(opt)\"\n [class.is-focused]=\"focusedIndex() === i\"\n [attr.aria-selected]=\"isSelected(opt)\"\n (click)=\"selectOption(opt)\"\n (mouseenter)=\"focusedIndex.set(i)\"\n >\n <span class=\"opt-label\">{{ opt.label }}</span>\n @if (isSelected(opt)) {\n <span class=\"opt-check\" aria-hidden=\"true\">\u2713</span>\n }\n </div>\n }\n @if (excessFilteredCount() > 0) {\n <div class=\"combobox-status-row hint\">\n <span>Showing {{ MAX_FILTER_RENDER }} of {{ filteredOptions().length }} matches. Type to refine.</span>\n </div>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <!-- Native Browser Select Fallback -->\n <div class=\"rpt-select-wrapper\">\n <select\n [id]=\"elementId()\"\n [formControl]=\"formControl()\"\n [class.rpt-invalid]=\"isInvalid()\"\n class=\"rpt-select\"\n >\n @if (waitingFor().length > 0) {\n <option value=\"\" disabled selected>Waiting for {{ waitingLabel() }}...</option>\n } @else if (isLoading()) {\n <option value=\"\" disabled selected>Loading options from database...</option>\n } @else if (loadError()) {\n <option value=\"\" disabled selected>Error: {{ loadError() }}</option>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <option value=\"\" disabled selected>-- No records found (check parameters) --</option>\n } @else if (placeholder()) {\n <option value=\"\" [disabled]=\"config().validation?.required\">{{ placeholder() }}</option>\n }\n @for (opt of renderedOptions(); track opt.key) {\n <option [value]=\"opt.key\">{{ opt.label }}</option>\n }\n @if (hasExcessOptions()) {\n <option value=\"\" disabled>... and {{ excessOptionsCount() }} more records (refine filter) ...</option>\n }\n </select>\n <div class=\"rpt-select-arrow\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n }\n\n @if (showStatus() && isDynamicSource() && statusText()) {\n <div class=\"rpt-status-badge\" [attr.data-status]=\"statusKind()\">\n @switch (statusKind()) {\n @case ('loading') {\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading from database\u2026</span>\n }\n @case ('ok') {\n <span class=\"status-dot dot-ok\"></span>\n <span>{{ dynamicOptions().length }} records loaded</span>\n }\n @case ('waiting') {\n <span class=\"status-dot dot-warn\"></span>\n <span>Waiting for:</span>\n <div class=\"waiting-tokens\">\n @for (k of waitingFor(); track k) {\n <span class=\"waiting-token\">{{ k }}</span>\n }\n </div>\n }\n @case ('error') {\n <span class=\"status-dot dot-err\"></span>\n <span>{{ loadError() }}</span>\n <button type=\"button\" class=\"rpt-badge-retry-btn\" (click)=\"retryLookup($event)\">\u21BB Retry</button>\n }\n @case ('empty') {\n <span class=\"status-dot\"></span>\n <span>No records found for parameters</span>\n }\n @default {\n <span class=\"status-dot\"></span>\n }\n }\n </div>\n }\n\n @if (errorMessage()) {\n <span class=\"rpt-error-text\">{{ errorMessage() }}</span>\n }\n </div>", styles: [":host{display:block;width:100%;max-width:100%;min-width:0;box-sizing:border-box;font-family:var(--rpt-font-family, inherit);position:relative}.rpt-status-badge{display:flex;flex-wrap:wrap;align-items:center;gap:4px;font-size:.6875rem;padding:3px 6px;border-radius:4px;margin-top:4px;font-weight:500;line-height:1.3;max-width:100%;box-sizing:border-box;overflow:hidden;word-break:break-word}.rpt-status-badge>span{overflow-wrap:anywhere;word-break:break-word}.rpt-status-badge[data-status=loading]{background:#eff6ff;color:#2563eb;border:1px solid #dbeafe}.rpt-status-badge[data-status=ok]{background:#f0fdf4;color:#16a34a;border:1px solid #dcfce7}.rpt-status-badge[data-status=waiting]{background:#fffbeb;color:#d97706;border:1px solid #fef3c7}.rpt-status-badge[data-status=error]{background:#fef2f2;color:#dc2626;border:1px solid #fee2e2}.rpt-status-badge[data-status=empty]{background:#f8fafc;color:#64748b;border:1px solid #e2e8f0}.waiting-tokens{display:inline-flex;flex-wrap:wrap;align-items:center;gap:3px;margin-left:2px;max-width:100%}.waiting-token{background:#b453091f;border:1px solid rgba(180,83,9,.3);padding:1px 5px;border-radius:3px;font-weight:700;font-size:.625rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;box-sizing:border-box}.status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.dot-pulse{animation:rpt-pulse 1s infinite alternate}@keyframes rpt-pulse{0%{opacity:.3}to{opacity:1}}.rpt-field-group{display:flex;flex-direction:column;max-width:100%;min-width:0;gap:4px;box-sizing:border-box;position:relative}.rpt-label{font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;color:var(--rpt-color-text, #0f172a);flex-shrink:0}.rpt-required-marker{color:var(--rpt-color-danger, #ef4444);margin-left:2px}.rpt-select-wrapper{position:relative;width:100%;flex:1;min-height:0;display:flex;align-items:center}.rpt-select{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 36px 6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);appearance:none;-webkit-appearance:none;outline:none;cursor:pointer;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-select:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-select:focus{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-select:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-select.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-select.rpt-invalid:focus{box-shadow:0 0 0 3px #ef444440}.rpt-select-arrow{position:absolute;right:12px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--rpt-color-text-muted, #64748b);display:flex;align-items:center}.rpt-combobox-wrapper{position:relative;width:100%;flex:1;min-height:0}.rpt-combobox-trigger{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 10px 6px 12px;display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:var(--rpt-font-size-base, .875rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);outline:none;cursor:pointer;text-align:left;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-combobox-trigger:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-combobox-trigger:focus-visible,.rpt-combobox-trigger.is-open{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-combobox-trigger:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-combobox-trigger.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-combobox-trigger.rpt-invalid:focus-visible{box-shadow:0 0 0 3px #ef444440}.trigger-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}.trigger-label.is-placeholder{color:var(--rpt-color-text-muted, #94a3b8)}.trigger-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.trigger-clear-btn{display:flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;font-size:.6875rem;color:var(--rpt-color-text-muted, #64748b);background-color:#f1f5f9;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease,color .15s ease}.trigger-clear-btn:hover{background-color:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.trigger-arrow{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);transition:transform .18s ease}.trigger-arrow.rotated{transform:rotate(180deg)}.rpt-combobox-menu{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:1050;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:0 10px 25px -5px #0000001f,0 8px 10px -6px #00000014;overflow:hidden;display:flex;flex-direction:column;animation:rpt-dropdown-pop .12s cubic-bezier(0,0,.2,1)}.rpt-combobox-menu.opens-above{top:auto;bottom:calc(100% + 4px);box-shadow:0 -10px 25px -5px #0000001f,0 -8px 10px -6px #00000014;animation:rpt-dropdown-pop-above .12s cubic-bezier(0,0,.2,1)}@keyframes rpt-dropdown-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes rpt-dropdown-pop-above{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.combobox-search-box{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);background-color:#f8fafc}.combobox-search-icon{color:var(--rpt-color-text-muted, #94a3b8);display:flex;align-items:center;flex-shrink:0}.combobox-search-input{flex:1;border:none;outline:none;background:transparent;font-size:var(--rpt-font-size-sm, .8125rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);min-width:0}.combobox-search-input::placeholder{color:#94a3b8}.combobox-search-clear{border:none;background:#e2e8f0;color:#64748b;width:16px;height:16px;border-radius:50%;font-size:.625rem;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}.combobox-search-clear:hover{background:#cbd5e1;color:#0f172a}.combobox-options-list{max-height:220px;overflow-y:auto;overscroll-behavior:contain;padding:4px}.combobox-option-item{display:flex;align-items:center;justify-content:space-between;padding:7px 10px;border-radius:4px;font-size:var(--rpt-font-size-base, .84rem);color:var(--rpt-color-text, #0f172a);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .1s ease}.combobox-option-item.is-focused{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.combobox-option-item.is-selected{background-color:#eff6ff;color:var(--rpt-color-primary, #2563eb);font-weight:600}.opt-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opt-check{font-size:.875rem;font-weight:700;color:var(--rpt-color-primary, #2563eb);margin-left:8px}.combobox-status-row{padding:10px 12px;font-size:.78rem;text-align:center;color:var(--rpt-color-text-muted, #64748b)}.combobox-status-row.loading{display:flex;align-items:center;justify-content:center;gap:6px;color:#2563eb}.combobox-status-row.error{display:flex;flex-direction:column;align-items:center;gap:6px;color:var(--rpt-color-danger, #dc2626)}.trigger-retry-btn,.combobox-retry-btn,.rpt-badge-retry-btn{display:inline-flex;align-items:center;gap:3px;font-size:.6875rem;font-weight:600;color:#dc2626;background:#fee2e2;border:1px solid #fca5a5;border-radius:4px;padding:2px 7px;cursor:pointer;line-height:1.2;transition:background-color .12s ease,color .12s ease}.trigger-retry-btn:hover,.combobox-retry-btn:hover,.rpt-badge-retry-btn:hover{background:#fecaca;color:#b91c1c;border-color:#f87171}.combobox-status-row.hint{font-size:.72rem;color:#94a3b8;border-top:1px dashed #e2e8f0;margin-top:4px;padding:6px}.rpt-error-text{font-size:.7rem;color:var(--rpt-color-danger, #ef4444);margin-top:3px;line-height:1.25;max-width:100%;overflow-wrap:anywhere;word-break:break-word;display:block}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
426
452
|
}
|
|
427
453
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RptDropdownComponent, decorators: [{
|
|
428
454
|
type: Component,
|
|
429
455
|
args: [{ selector: 'rpt-dropdown', standalone: true, imports: [ReactiveFormsModule], host: {
|
|
430
456
|
'[class.is-open]': 'isOpen()',
|
|
431
457
|
'[class.opens-above]': 'opensAbove()',
|
|
432
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, template: " <div class=\"rpt-field-group\">\n @if (config().label) {\n <label [for]=\"elementId()\" class=\"rpt-label\">\n {{ config().label }}\n @if (config().validation?.required) {\n <span class=\"rpt-required-marker\">*</span>\n }\n </label>\n }\n\n @if (isSearchable()) {\n <!-- Searchable Typeahead Combobox -->\n <div class=\"rpt-combobox-wrapper\" #comboboxWrapper>\n <button\n type=\"button\"\n class=\"rpt-combobox-trigger\"\n [id]=\"elementId()\"\n [class.rpt-invalid]=\"isInvalid()\"\n [class.is-open]=\"isOpen()\"\n [disabled]=\"formControl().disabled\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n (click)=\"toggleOpen($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"trigger-label\" [class.is-placeholder]=\"!selectedOption()\">\n {{ selectedOption() ? selectedOption()!.label : placeholder() }}\n </span>\n\n <div class=\"trigger-actions\">\n @if (selectedOption() && !formControl().disabled) {\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"trigger-clear-btn\"\n title=\"Clear selection\"\n aria-label=\"Clear selection\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n \u2715\n </span>\n }\n <span class=\"trigger-arrow\" [class.rotated]=\"isOpen()\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </div>\n </button>\n\n @if (isOpen()) {\n <div\n class=\"rpt-combobox-menu\"\n [class.opens-above]=\"opensAbove()\"\n role=\"listbox\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Real-time Filter Search Box -->\n <div class=\"combobox-search-box\">\n <span class=\"combobox-search-icon\" aria-hidden=\"true\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n </svg>\n </span>\n <input\n #searchInput\n type=\"text\"\n class=\"combobox-search-input\"\n placeholder=\"Type to filter...\"\n [value]=\"searchTerm()\"\n [attr.aria-activedescendant]=\"focusedIndex() >= 0 ? (elementId() + '_opt_' + focusedIndex()) : null\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n @if (searchTerm()) {\n <button\n type=\"button\"\n class=\"combobox-search-clear\"\n title=\"Clear filter\"\n (click)=\"clearSearch($event)\"\n >\n \u2715\n </button>\n }\n </div>\n\n <!-- Filtered Options List -->\n <div class=\"combobox-options-list\" #optionsListEl>\n @if (isLoading()) {\n <div class=\"combobox-status-row loading\">\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading options from database...</span>\n </div>\n } @else if (loadError()) {\n <div class=\"combobox-status-row error\">\n <span>Error: {{ loadError() }}</span>\n </div>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No records found (check parameters)</span>\n </div>\n } @else if (filteredOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No options matching \"{{ searchTerm() }}\"</span>\n </div>\n } @else {\n @for (opt of visibleFilteredOptions(); track opt.key; let i = $index) {\n <div\n role=\"option\"\n [id]=\"elementId() + '_opt_' + i\"\n class=\"combobox-option-item\"\n [class.is-selected]=\"isSelected(opt)\"\n [class.is-focused]=\"focusedIndex() === i\"\n [attr.aria-selected]=\"isSelected(opt)\"\n (click)=\"selectOption(opt)\"\n (mouseenter)=\"focusedIndex.set(i)\"\n >\n <span class=\"opt-label\">{{ opt.label }}</span>\n @if (isSelected(opt)) {\n <span class=\"opt-check\" aria-hidden=\"true\">\u2713</span>\n }\n </div>\n }\n @if (excessFilteredCount() > 0) {\n <div class=\"combobox-status-row hint\">\n <span>Showing {{ MAX_FILTER_RENDER }} of {{ filteredOptions().length }} matches. Type to refine.</span>\n </div>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <!-- Native Browser Select Fallback -->\n <div class=\"rpt-select-wrapper\">\n <select\n [id]=\"elementId()\"\n [formControl]=\"formControl()\"\n [class.rpt-invalid]=\"isInvalid()\"\n class=\"rpt-select\"\n >\n @if (isLoading()) {\n <option value=\"\" disabled selected>Loading options from database...</option>\n } @else if (loadError()) {\n <option value=\"\" disabled selected>Error: {{ loadError() }}</option>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <option value=\"\" disabled selected>-- No records found (check parameters) --</option>\n } @else if (placeholder()) {\n <option value=\"\" [disabled]=\"config().validation?.required\">{{ placeholder() }}</option>\n }\n @for (opt of renderedOptions(); track opt.key) {\n <option [value]=\"opt.key\">{{ opt.label }}</option>\n }\n @if (hasExcessOptions()) {\n <option value=\"\" disabled>... and {{ excessOptionsCount() }} more records (refine filter) ...</option>\n }\n </select>\n <div class=\"rpt-select-arrow\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n }\n\n @if (showStatus() && isDynamicSource() && statusText()) {\n <div class=\"rpt-status-badge\" [attr.data-status]=\"statusKind()\">\n @switch (statusKind()) {\n @case ('loading') {\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading from database\u2026</span>\n }\n @case ('ok') {\n <span class=\"status-dot dot-ok\"></span>\n <span>{{ dynamicOptions().length }} records loaded</span>\n }\n @case ('waiting') {\n <span class=\"status-dot dot-warn\"></span>\n <span>Waiting for:</span>\n <div class=\"waiting-tokens\">\n @for (k of waitingFor(); track k) {\n <span class=\"waiting-token\">{{ k }}</span>\n }\n </div>\n }\n @case ('error') {\n <span class=\"status-dot dot-err\"></span>\n <span>{{ loadError() }}</span>\n }\n @case ('empty') {\n <span class=\"status-dot\"></span>\n <span>No records found for parameters</span>\n }\n @default {\n <span class=\"status-dot\"></span>\n }\n }\n </div>\n }\n\n @if (errorMessage()) {\n <span class=\"rpt-error-text\">{{ errorMessage() }}</span>\n }\n </div>", styles: [":host{display:block;width:100%;max-width:100%;min-width:0;box-sizing:border-box;font-family:var(--rpt-font-family, inherit);position:relative}.rpt-status-badge{display:flex;flex-wrap:wrap;align-items:center;gap:4px;font-size:.6875rem;padding:3px 6px;border-radius:4px;margin-top:4px;font-weight:500;line-height:1.3;max-width:100%;box-sizing:border-box;overflow:hidden;word-break:break-word}.rpt-status-badge>span{overflow-wrap:anywhere;word-break:break-word}.rpt-status-badge[data-status=loading]{background:#eff6ff;color:#2563eb;border:1px solid #dbeafe}.rpt-status-badge[data-status=ok]{background:#f0fdf4;color:#16a34a;border:1px solid #dcfce7}.rpt-status-badge[data-status=waiting]{background:#fffbeb;color:#d97706;border:1px solid #fef3c7}.rpt-status-badge[data-status=error]{background:#fef2f2;color:#dc2626;border:1px solid #fee2e2}.rpt-status-badge[data-status=empty]{background:#f8fafc;color:#64748b;border:1px solid #e2e8f0}.waiting-tokens{display:inline-flex;flex-wrap:wrap;align-items:center;gap:3px;margin-left:2px;max-width:100%}.waiting-token{background:#b453091f;border:1px solid rgba(180,83,9,.3);padding:1px 5px;border-radius:3px;font-weight:700;font-size:.625rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;box-sizing:border-box}.status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.dot-pulse{animation:rpt-pulse 1s infinite alternate}@keyframes rpt-pulse{0%{opacity:.3}to{opacity:1}}.rpt-field-group{display:flex;flex-direction:column;max-width:100%;min-width:0;gap:4px;box-sizing:border-box;position:relative}.rpt-label{font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;color:var(--rpt-color-text, #0f172a);flex-shrink:0}.rpt-required-marker{color:var(--rpt-color-danger, #ef4444);margin-left:2px}.rpt-select-wrapper{position:relative;width:100%;flex:1;min-height:0;display:flex;align-items:center}.rpt-select{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 36px 6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);appearance:none;-webkit-appearance:none;outline:none;cursor:pointer;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-select:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-select:focus{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-select:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-select.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-select.rpt-invalid:focus{box-shadow:0 0 0 3px #ef444440}.rpt-select-arrow{position:absolute;right:12px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--rpt-color-text-muted, #64748b);display:flex;align-items:center}.rpt-combobox-wrapper{position:relative;width:100%;flex:1;min-height:0}.rpt-combobox-trigger{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 10px 6px 12px;display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:var(--rpt-font-size-base, .875rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);outline:none;cursor:pointer;text-align:left;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-combobox-trigger:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-combobox-trigger:focus-visible,.rpt-combobox-trigger.is-open{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-combobox-trigger:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-combobox-trigger.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-combobox-trigger.rpt-invalid:focus-visible{box-shadow:0 0 0 3px #ef444440}.trigger-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}.trigger-label.is-placeholder{color:var(--rpt-color-text-muted, #94a3b8)}.trigger-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.trigger-clear-btn{display:flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;font-size:.6875rem;color:var(--rpt-color-text-muted, #64748b);background-color:#f1f5f9;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease,color .15s ease}.trigger-clear-btn:hover{background-color:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.trigger-arrow{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);transition:transform .18s ease}.trigger-arrow.rotated{transform:rotate(180deg)}.rpt-combobox-menu{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:1050;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:0 10px 25px -5px #0000001f,0 8px 10px -6px #00000014;overflow:hidden;display:flex;flex-direction:column;animation:rpt-dropdown-pop .12s cubic-bezier(0,0,.2,1)}.rpt-combobox-menu.opens-above{top:auto;bottom:calc(100% + 4px);box-shadow:0 -10px 25px -5px #0000001f,0 -8px 10px -6px #00000014;animation:rpt-dropdown-pop-above .12s cubic-bezier(0,0,.2,1)}@keyframes rpt-dropdown-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes rpt-dropdown-pop-above{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.combobox-search-box{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);background-color:#f8fafc}.combobox-search-icon{color:var(--rpt-color-text-muted, #94a3b8);display:flex;align-items:center;flex-shrink:0}.combobox-search-input{flex:1;border:none;outline:none;background:transparent;font-size:var(--rpt-font-size-sm, .8125rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);min-width:0}.combobox-search-input::placeholder{color:#94a3b8}.combobox-search-clear{border:none;background:#e2e8f0;color:#64748b;width:16px;height:16px;border-radius:50%;font-size:.625rem;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}.combobox-search-clear:hover{background:#cbd5e1;color:#0f172a}.combobox-options-list{max-height:220px;overflow-y:auto;overscroll-behavior:contain;padding:4px}.combobox-option-item{display:flex;align-items:center;justify-content:space-between;padding:7px 10px;border-radius:4px;font-size:var(--rpt-font-size-base, .84rem);color:var(--rpt-color-text, #0f172a);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .1s ease}.combobox-option-item.is-focused{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.combobox-option-item.is-selected{background-color:#eff6ff;color:var(--rpt-color-primary, #2563eb);font-weight:600}.opt-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opt-check{font-size:.875rem;font-weight:700;color:var(--rpt-color-primary, #2563eb);margin-left:8px}.combobox-status-row{padding:10px 12px;font-size:.78rem;text-align:center;color:var(--rpt-color-text-muted, #64748b)}.combobox-status-row.loading{display:flex;align-items:center;justify-content:center;gap:6px;color:#2563eb}.combobox-status-row.error{color:var(--rpt-color-danger, #dc2626)}.combobox-status-row.hint{font-size:.72rem;color:#94a3b8;border-top:1px dashed #e2e8f0;margin-top:4px;padding:6px}.rpt-error-text{font-size:.7rem;color:var(--rpt-color-danger, #ef4444);margin-top:3px;line-height:1.25;max-width:100%;overflow-wrap:anywhere;word-break:break-word;display:block}\n"] }]
|
|
458
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, template: " <div class=\"rpt-field-group\">\n @if (config().label) {\n <label [for]=\"elementId()\" class=\"rpt-label\">\n {{ config().label }}\n @if (config().validation?.required) {\n <span class=\"rpt-required-marker\">*</span>\n }\n </label>\n }\n\n @if (isSearchable()) {\n <!-- Searchable Typeahead Combobox -->\n <div class=\"rpt-combobox-wrapper\" #comboboxWrapper>\n <button\n type=\"button\"\n class=\"rpt-combobox-trigger\"\n [id]=\"elementId()\"\n [class.rpt-invalid]=\"isInvalid()\"\n [class.is-open]=\"isOpen()\"\n [disabled]=\"formControl().disabled\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n (click)=\"toggleOpen($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"trigger-label\" [class.is-placeholder]=\"!selectedOption()\">\n {{ selectedOption() ? selectedOption()!.label : placeholder() }}\n </span>\n\n <div class=\"trigger-actions\">\n @if (isLoading()) {\n <span class=\"status-dot dot-pulse\" style=\"color: #2563eb; margin-right: 4px;\" title=\"Executing query on database...\"></span>\n }\n @if (loadError() && !isLoading()) {\n <button\n type=\"button\"\n class=\"trigger-retry-btn\"\n title=\"Retry database query\"\n aria-label=\"Retry database query\"\n (click)=\"retryLookup($event)\"\n >\n \u21BB Retry\n </button>\n }\n @if (selectedOption() && !formControl().disabled) {\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"trigger-clear-btn\"\n title=\"Clear selection\"\n aria-label=\"Clear selection\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n \u2715\n </span>\n }\n <span class=\"trigger-arrow\" [class.rotated]=\"isOpen()\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </div>\n </button>\n\n @if (isOpen()) {\n <div\n class=\"rpt-combobox-menu\"\n [class.opens-above]=\"opensAbove()\"\n role=\"listbox\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Real-time Filter Search Box -->\n <div class=\"combobox-search-box\">\n <span class=\"combobox-search-icon\" aria-hidden=\"true\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n </svg>\n </span>\n <input\n #searchInput\n type=\"text\"\n class=\"combobox-search-input\"\n placeholder=\"Type to filter...\"\n [value]=\"searchTerm()\"\n [attr.aria-activedescendant]=\"focusedIndex() >= 0 ? (elementId() + '_opt_' + focusedIndex()) : null\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n @if (searchTerm()) {\n <button\n type=\"button\"\n class=\"combobox-search-clear\"\n title=\"Clear filter\"\n (click)=\"clearSearch($event)\"\n >\n \u2715\n </button>\n }\n </div>\n\n <!-- Filtered Options List -->\n <div class=\"combobox-options-list\" #optionsListEl>\n @if (waitingFor().length > 0) {\n <div class=\"combobox-status-row waiting\">\n <span>Waiting for {{ waitingLabel() }}...</span>\n </div>\n } @else if (isLoading()) {\n <div class=\"combobox-status-row loading\">\n <span class=\"status-dot dot-pulse\"></span>\n <span>Executing query on database (may take 1\u20132 minutes on local database)...</span>\n </div>\n } @else if (loadError()) {\n <div class=\"combobox-status-row error\">\n <span>Error: {{ loadError() }}</span>\n <button type=\"button\" class=\"combobox-retry-btn\" (click)=\"retryLookup($event)\">\u21BB Retry Query</button>\n </div>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No records found (check parameters)</span>\n </div>\n } @else if (filteredOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No options matching \"{{ searchTerm() }}\"</span>\n </div>\n } @else {\n @for (opt of visibleFilteredOptions(); track opt.key; let i = $index) {\n <div\n role=\"option\"\n [id]=\"elementId() + '_opt_' + i\"\n class=\"combobox-option-item\"\n [class.is-selected]=\"isSelected(opt)\"\n [class.is-focused]=\"focusedIndex() === i\"\n [attr.aria-selected]=\"isSelected(opt)\"\n (click)=\"selectOption(opt)\"\n (mouseenter)=\"focusedIndex.set(i)\"\n >\n <span class=\"opt-label\">{{ opt.label }}</span>\n @if (isSelected(opt)) {\n <span class=\"opt-check\" aria-hidden=\"true\">\u2713</span>\n }\n </div>\n }\n @if (excessFilteredCount() > 0) {\n <div class=\"combobox-status-row hint\">\n <span>Showing {{ MAX_FILTER_RENDER }} of {{ filteredOptions().length }} matches. Type to refine.</span>\n </div>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <!-- Native Browser Select Fallback -->\n <div class=\"rpt-select-wrapper\">\n <select\n [id]=\"elementId()\"\n [formControl]=\"formControl()\"\n [class.rpt-invalid]=\"isInvalid()\"\n class=\"rpt-select\"\n >\n @if (waitingFor().length > 0) {\n <option value=\"\" disabled selected>Waiting for {{ waitingLabel() }}...</option>\n } @else if (isLoading()) {\n <option value=\"\" disabled selected>Loading options from database...</option>\n } @else if (loadError()) {\n <option value=\"\" disabled selected>Error: {{ loadError() }}</option>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <option value=\"\" disabled selected>-- No records found (check parameters) --</option>\n } @else if (placeholder()) {\n <option value=\"\" [disabled]=\"config().validation?.required\">{{ placeholder() }}</option>\n }\n @for (opt of renderedOptions(); track opt.key) {\n <option [value]=\"opt.key\">{{ opt.label }}</option>\n }\n @if (hasExcessOptions()) {\n <option value=\"\" disabled>... and {{ excessOptionsCount() }} more records (refine filter) ...</option>\n }\n </select>\n <div class=\"rpt-select-arrow\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n }\n\n @if (showStatus() && isDynamicSource() && statusText()) {\n <div class=\"rpt-status-badge\" [attr.data-status]=\"statusKind()\">\n @switch (statusKind()) {\n @case ('loading') {\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading from database\u2026</span>\n }\n @case ('ok') {\n <span class=\"status-dot dot-ok\"></span>\n <span>{{ dynamicOptions().length }} records loaded</span>\n }\n @case ('waiting') {\n <span class=\"status-dot dot-warn\"></span>\n <span>Waiting for:</span>\n <div class=\"waiting-tokens\">\n @for (k of waitingFor(); track k) {\n <span class=\"waiting-token\">{{ k }}</span>\n }\n </div>\n }\n @case ('error') {\n <span class=\"status-dot dot-err\"></span>\n <span>{{ loadError() }}</span>\n <button type=\"button\" class=\"rpt-badge-retry-btn\" (click)=\"retryLookup($event)\">\u21BB Retry</button>\n }\n @case ('empty') {\n <span class=\"status-dot\"></span>\n <span>No records found for parameters</span>\n }\n @default {\n <span class=\"status-dot\"></span>\n }\n }\n </div>\n }\n\n @if (errorMessage()) {\n <span class=\"rpt-error-text\">{{ errorMessage() }}</span>\n }\n </div>", styles: [":host{display:block;width:100%;max-width:100%;min-width:0;box-sizing:border-box;font-family:var(--rpt-font-family, inherit);position:relative}.rpt-status-badge{display:flex;flex-wrap:wrap;align-items:center;gap:4px;font-size:.6875rem;padding:3px 6px;border-radius:4px;margin-top:4px;font-weight:500;line-height:1.3;max-width:100%;box-sizing:border-box;overflow:hidden;word-break:break-word}.rpt-status-badge>span{overflow-wrap:anywhere;word-break:break-word}.rpt-status-badge[data-status=loading]{background:#eff6ff;color:#2563eb;border:1px solid #dbeafe}.rpt-status-badge[data-status=ok]{background:#f0fdf4;color:#16a34a;border:1px solid #dcfce7}.rpt-status-badge[data-status=waiting]{background:#fffbeb;color:#d97706;border:1px solid #fef3c7}.rpt-status-badge[data-status=error]{background:#fef2f2;color:#dc2626;border:1px solid #fee2e2}.rpt-status-badge[data-status=empty]{background:#f8fafc;color:#64748b;border:1px solid #e2e8f0}.waiting-tokens{display:inline-flex;flex-wrap:wrap;align-items:center;gap:3px;margin-left:2px;max-width:100%}.waiting-token{background:#b453091f;border:1px solid rgba(180,83,9,.3);padding:1px 5px;border-radius:3px;font-weight:700;font-size:.625rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;box-sizing:border-box}.status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.dot-pulse{animation:rpt-pulse 1s infinite alternate}@keyframes rpt-pulse{0%{opacity:.3}to{opacity:1}}.rpt-field-group{display:flex;flex-direction:column;max-width:100%;min-width:0;gap:4px;box-sizing:border-box;position:relative}.rpt-label{font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;color:var(--rpt-color-text, #0f172a);flex-shrink:0}.rpt-required-marker{color:var(--rpt-color-danger, #ef4444);margin-left:2px}.rpt-select-wrapper{position:relative;width:100%;flex:1;min-height:0;display:flex;align-items:center}.rpt-select{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 36px 6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);appearance:none;-webkit-appearance:none;outline:none;cursor:pointer;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-select:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-select:focus{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-select:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-select.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-select.rpt-invalid:focus{box-shadow:0 0 0 3px #ef444440}.rpt-select-arrow{position:absolute;right:12px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--rpt-color-text-muted, #64748b);display:flex;align-items:center}.rpt-combobox-wrapper{position:relative;width:100%;flex:1;min-height:0}.rpt-combobox-trigger{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 10px 6px 12px;display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:var(--rpt-font-size-base, .875rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);outline:none;cursor:pointer;text-align:left;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-combobox-trigger:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-combobox-trigger:focus-visible,.rpt-combobox-trigger.is-open{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-combobox-trigger:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-combobox-trigger.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-combobox-trigger.rpt-invalid:focus-visible{box-shadow:0 0 0 3px #ef444440}.trigger-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}.trigger-label.is-placeholder{color:var(--rpt-color-text-muted, #94a3b8)}.trigger-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.trigger-clear-btn{display:flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;font-size:.6875rem;color:var(--rpt-color-text-muted, #64748b);background-color:#f1f5f9;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease,color .15s ease}.trigger-clear-btn:hover{background-color:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.trigger-arrow{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);transition:transform .18s ease}.trigger-arrow.rotated{transform:rotate(180deg)}.rpt-combobox-menu{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:1050;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:0 10px 25px -5px #0000001f,0 8px 10px -6px #00000014;overflow:hidden;display:flex;flex-direction:column;animation:rpt-dropdown-pop .12s cubic-bezier(0,0,.2,1)}.rpt-combobox-menu.opens-above{top:auto;bottom:calc(100% + 4px);box-shadow:0 -10px 25px -5px #0000001f,0 -8px 10px -6px #00000014;animation:rpt-dropdown-pop-above .12s cubic-bezier(0,0,.2,1)}@keyframes rpt-dropdown-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes rpt-dropdown-pop-above{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.combobox-search-box{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);background-color:#f8fafc}.combobox-search-icon{color:var(--rpt-color-text-muted, #94a3b8);display:flex;align-items:center;flex-shrink:0}.combobox-search-input{flex:1;border:none;outline:none;background:transparent;font-size:var(--rpt-font-size-sm, .8125rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);min-width:0}.combobox-search-input::placeholder{color:#94a3b8}.combobox-search-clear{border:none;background:#e2e8f0;color:#64748b;width:16px;height:16px;border-radius:50%;font-size:.625rem;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}.combobox-search-clear:hover{background:#cbd5e1;color:#0f172a}.combobox-options-list{max-height:220px;overflow-y:auto;overscroll-behavior:contain;padding:4px}.combobox-option-item{display:flex;align-items:center;justify-content:space-between;padding:7px 10px;border-radius:4px;font-size:var(--rpt-font-size-base, .84rem);color:var(--rpt-color-text, #0f172a);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .1s ease}.combobox-option-item.is-focused{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.combobox-option-item.is-selected{background-color:#eff6ff;color:var(--rpt-color-primary, #2563eb);font-weight:600}.opt-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opt-check{font-size:.875rem;font-weight:700;color:var(--rpt-color-primary, #2563eb);margin-left:8px}.combobox-status-row{padding:10px 12px;font-size:.78rem;text-align:center;color:var(--rpt-color-text-muted, #64748b)}.combobox-status-row.loading{display:flex;align-items:center;justify-content:center;gap:6px;color:#2563eb}.combobox-status-row.error{display:flex;flex-direction:column;align-items:center;gap:6px;color:var(--rpt-color-danger, #dc2626)}.trigger-retry-btn,.combobox-retry-btn,.rpt-badge-retry-btn{display:inline-flex;align-items:center;gap:3px;font-size:.6875rem;font-weight:600;color:#dc2626;background:#fee2e2;border:1px solid #fca5a5;border-radius:4px;padding:2px 7px;cursor:pointer;line-height:1.2;transition:background-color .12s ease,color .12s ease}.trigger-retry-btn:hover,.combobox-retry-btn:hover,.rpt-badge-retry-btn:hover{background:#fecaca;color:#b91c1c;border-color:#f87171}.combobox-status-row.hint{font-size:.72rem;color:#94a3b8;border-top:1px dashed #e2e8f0;margin-top:4px;padding:6px}.rpt-error-text{font-size:.7rem;color:var(--rpt-color-danger, #ef4444);margin-top:3px;line-height:1.25;max-width:100%;overflow-wrap:anywhere;word-break:break-word;display:block}\n"] }]
|
|
433
459
|
}], ctorParameters: () => [], propDecorators: { onDocumentClick: [{
|
|
434
460
|
type: HostListener,
|
|
435
461
|
args: ['document:click', ['$event']]
|
|
@@ -437,4 +463,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
437
463
|
type: HostListener,
|
|
438
464
|
args: ['document:keydown.escape']
|
|
439
465
|
}] } });
|
|
440
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnB0LWRyb3Bkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2J3YXlzLXJlcG9ydC9zcmMvbGliL3ByaW1pdGl2ZXMvY29tcG9uZW50cy9kcm9wZG93bi9ycHQtZHJvcGRvd24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvcHJpbWl0aXZlcy9jb21wb25lbnRzL2Ryb3Bkb3duL3JwdC1kcm9wZG93bi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFVBQVUsRUFDVixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNULFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsV0FBVyxFQUFhLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHN0UsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDbkYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scURBQXFELENBQUM7QUFDekYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFDckYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sdURBQXVELENBQUM7QUFFcEcsT0FBTyxFQUNMLHVCQUF1QixFQUN2Qix3QkFBd0IsR0FDekIsTUFBTSwyQ0FBMkMsQ0FBQzs7O0FBbUJuRCxNQUFNLE9BQU8sb0JBQW9CO0lBQ2Qsa0JBQWtCLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDcEUsYUFBYSxHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxFQUFF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Q3ZDLEtBQUssRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO3FCQUM1QyxDQUFDLENBQUMsQ0FDSixDQUFDO2dCQUNKLENBQUM7Z0JBQ0QsS0FBSyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUU7b0JBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQyxnREFBZ0QsRUFBRSxDQUFDLFVBQVUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO29CQUNyRixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDMUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ3pCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxPQUFPLElBQUksNEJBQTRCLENBQUMsQ0FBQztnQkFDbkUsQ0FBQzthQUNGLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO3dHQTFjVSxvQkFBb0I7NEZBQXBCLG9CQUFvQixpb0NDNUNqQyw2OFJBK01VLGs3UEQ1S0UsbUJBQW1COzs0RkFTbEIsb0JBQW9CO2tCQVpoQyxTQUFTOytCQUNFLGNBQWMsY0FDWixJQUFJLFdBQ1AsQ0FBQyxtQkFBbUIsQ0FBQyxRQUN4Qjt3QkFDSixpQkFBaUIsRUFBRSxVQUFVO3dCQUM3QixxQkFBcUIsRUFBRSxjQUFjO3FCQUN0QyxtQkFHZ0IsdUJBQXVCLENBQUMsTUFBTTt3REF1Sy9DLGVBQWU7c0JBRGQsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFVMUMsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLHlCQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIGNvbXB1dGVkLFxuICBlZmZlY3QsXG4gIEVsZW1lbnRSZWYsXG4gIEhvc3RMaXN0ZW5lcixcbiAgaW5qZWN0LFxuICBpbnB1dCxcbiAgT25EZXN0cm95LFxuICBzaWduYWwsXG4gIHVudHJhY2tlZCxcbiAgdmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtY29tcG9uZW50Lm1vZGVsJztcbmltcG9ydCB7IGdldFZhbGlkYXRpb25NZXNzYWdlIH0gZnJvbSAnLi4vLi4vLi4vY29yZS92YWxpZGF0aW9uL3ZhbGlkYXRpb24tZmFjdG9yeSc7XG5pbXBvcnQgeyBNYXN0ZXJEYXRhUHJvdmlkZXIgfSBmcm9tICcuLi8uLi8uLi9kYXRhLWFjY2Vzcy9jb250cmFjdHMvbWFzdGVyLWRhdGEucHJvdmlkZXInO1xuaW1wb3J0IHsgUmVwb3J0TG9va3VwQWRhcHRlciB9IGZyb20gJy4uLy4uLy4uL2RhdGEtYWNjZXNzL2NvbnRyYWN0cy9sb29rdXAuY29udHJhY3QnO1xuaW1wb3J0IHsgUmVwb3J0U2Vzc2lvbkNvbnRleHRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vY29yZS9zZXJ2aWNlcy9yZXBvcnQtc2Vzc2lvbi1jb250ZXh0LnNlcnZpY2UnO1xuaW1wb3J0IHsgU2Vzc2lvbkNvbnRleHRNYXAgfSBmcm9tICcuLi8uLi8uLi9jb3JlL3Rva2Vucy9zZXNzaW9uLWNvbnRleHQudG9rZW4nO1xuaW1wb3J0IHtcbiAgZmluZE1pc3NpbmdDYW52YXNGaWVsZHMsXG4gIHJlc29sdmVQYXJhbWV0ZXJNYXBwaW5ncyxcbn0gZnJvbSAnLi4vLi4vLi4vY29yZS91dGlscy9yZXBvcnQtcGFyYW1ldGVyLnV0aWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIERyb3Bkb3duT3B0aW9uIHtcbiAga2V5OiBzdHJpbmcgfCBudW1iZXI7XG4gIGxhYmVsOiBzdHJpbmc7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3JwdC1kcm9wZG93bicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtSZWFjdGl2ZUZvcm1zTW9kdWxlXSxcbiAgaG9zdDoge1xuICAgICdbY2xhc3MuaXMtb3Blbl0nOiAnaXNPcGVuKCknLFxuICAgICdbY2xhc3Mub3BlbnMtYWJvdmVdJzogJ29wZW5zQWJvdmUoKScsXG4gIH0sXG4gIHRlbXBsYXRlVXJsOiAnLi9ycHQtZHJvcGRvd24uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vcnB0LWRyb3Bkb3duLmNvbXBvbmVudC5jc3MnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgUnB0RHJvcGRvd25Db21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHJlYWRvbmx5IG1hc3RlckRhdGFQcm92aWRlciA9IGluamVjdChNYXN0ZXJEYXRhUHJvdmlkZXIsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9va3VwQWRhcHRlciA9IGluamVjdChSZXBvcnRMb29rdXBBZGFwdGVyLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuICBwcml2YXRlIHJlYWRvbmx5IHNlc3Npb25TZXJ2aWNlID0gaW5qZWN0KFJlcG9ydFNlc3Npb25Db250ZXh0U2VydmljZSwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbiAgcHJpdmF0ZSByZWFkb25seSBlbGVtZW50UmVmID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuXG4gIHJlYWRvbmx5IGNvbmZpZyA9IGlucHV0LnJlcXVpcmVkPFJlcG9ydENvbXBvbmVudERlZmluaXRpb24+KCk7XG4gIHJlYWRvbmx5IGNvbnRyb2wgPSBpbnB1dDxGb3JtQ29udHJvbCB8IG51bGwgfCB1bmRlZmluZWQ+KCk7XG4gIHJlYWRvbmx5IHBhcmVudEZvcm0gPSBpbnB1dDxGb3JtR3JvdXAgfCBudWxsPihudWxsKTtcbiAgLyoqIERlc2lnbmVyIG1vZGU6IHNob3dzIGEgc21hbGwgc3RhdHVzIGxpbmUgKExvYWRpbmcgLyBOIHJlY29yZHMgLyBXYWl0aW5nIGZvcuKApikuICovXG4gIHJlYWRvbmx5IHNob3dTdGF0dXMgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBmYWxsYmFja0NvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2woJycpO1xuICByZWFkb25seSBkeW5hbWljT3B0aW9ucyA9IHNpZ25hbDxEcm9wZG93bk9wdGlvbltdPihbXSk7XG4gIHByaXZhdGUgbG9va3VwU3ViPzogU3Vic2NyaXB0aW9uO1xuICBwcml2YXRlIG1hc3RlckRhdGFTdWI/OiBTdWJzY3JpcHRpb247XG4gIHByaXZhdGUgZm9ybUNoYW5nZXNTdWI/OiBTdWJzY3JpcHRpb247XG4gIHByaXZhdGUgcmVsb2FkVGltZXI/OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcbiAgcHJpdmF0ZSBsYXN0UmVxdWVzdEtleSA9ICcnO1xuXG4gIC8vIENvbWJvYm94IGludGVyYWN0aXZlIHN0YXRlXG4gIHJlYWRvbmx5IGlzT3BlbiA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IG9wZW5zQWJvdmUgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBzZWFyY2hUZXJtID0gc2lnbmFsPHN0cmluZz4oJycpO1xuICByZWFkb25seSBmb2N1c2VkSW5kZXggPSBzaWduYWw8bnVtYmVyPigtMSk7XG4gIHJlYWRvbmx5IGN1cnJlbnRWYWx1ZSA9IHNpZ25hbDx1bmtub3duPihudWxsKTtcbiAgcmVhZG9ubHkgY29tYm9ib3hXcmFwcGVyRWwgPSB2aWV3Q2hpbGQ8RWxlbWVudFJlZjxIVE1MRWxlbWVudD4+KCdjb21ib2JveFdyYXBwZXInKTtcbiAgcmVhZG9ubHkgc2VhcmNoSW5wdXRFbCA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+Pignc2VhcmNoSW5wdXQnKTtcbiAgcmVhZG9ubHkgb3B0aW9uc0xpc3RFbCA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPEhUTUxFbGVtZW50Pj4oJ29wdGlvbnNMaXN0RWwnKTtcblxuICBwcml2YXRlIGNvbnRyb2xTdWI/OiBTdWJzY3JpcHRpb247XG5cbiAgcmVhZG9ubHkgZm9ybUNvbnRyb2wgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmNvbnRyb2woKSA/PyB0aGlzLmZhbGxiYWNrQ29udHJvbCk7XG4gIHJlYWRvbmx5IGVsZW1lbnRJZCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29uZmlnKCkua2V5IHx8IHRoaXMuY29uZmlnKCkuaWQpO1xuICByZWFkb25seSBwbGFjZWhvbGRlciA9IGNvbXB1dGVkKFxuICAgICgpID0+ICh0aGlzLmNvbmZpZygpLnByb3BlcnRpZXM/LlsncGxhY2Vob2xkZXInXSBhcyBzdHJpbmcpID8/ICctLSBTZWxlY3QgLS0nXG4gICk7XG5cbiAgcmVhZG9ubHkgaXNTZWFyY2hhYmxlID0gY29tcHV0ZWQoXG4gICAgKCkgPT4gdGhpcy5jb25maWcoKS5wcm9wZXJ0aWVzPy5bJ25hdGl2ZVNlbGVjdCddICE9PSB0cnVlXG4gICk7XG5cbiAgcmVhZG9ubHkgaXNMb2FkaW5nID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgaGFzTG9hZGVkID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgbG9hZEVycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICAvKiogQ2FudmFzIGZpZWxkIGtleXMgdGhhdCBtdXN0IGJlIGZpbGxlZCBiZWZvcmUgdGhlIGxvb2t1cCBjYW4gcnVuLiAqL1xuICByZWFkb25seSB3YWl0aW5nRm9yID0gc2lnbmFsPHN0cmluZ1tdPihbXSk7XG5cbiAgcmVhZG9ubHkgaXNEeW5hbWljU291cmNlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGRzID0gdGhpcy5jb25maWcoKS5kYXRhU291cmNlO1xuICAgIHJldHVybiAhIShcbiAgICAgIGRzICYmXG4gICAgICAoZHMuc291cmNlVHlwZSA9PT0gJ3RhYmxlJyB8fFxuICAgICAgICBkcy5zb3VyY2VUeXBlID09PSAncHJvY2VkdXJlJyB8fFxuICAgICAgICBkcy5lbnRpdHlOYW1lIHx8XG4gICAgICAgIGRzLm1hc3Rlck5hbWUpXG4gICAgKTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgc3RhdGljT3B0aW9ucyA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uW10+KCgpID0+IHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5jb25maWcoKS5wcm9wZXJ0aWVzPy5bJ29wdGlvbnMnXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRzKSkge1xuICAgICAgcmV0dXJuIG9wdHM7XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgYWxsT3B0aW9ucyA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uW10+KCgpID0+IHtcbiAgICBpZiAodGhpcy5pc0R5bmFtaWNTb3VyY2UoKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZHluYW1pY09wdGlvbnMoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RhdGljT3B0aW9ucygpO1xuICB9KTtcblxuICByZWFkb25seSBzZWxlY3RlZE9wdGlvbiA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uIHwgbnVsbD4oKCkgPT4ge1xuICAgIGNvbnN0IHZhbCA9IHRoaXMuY3VycmVudFZhbHVlKCk7XG4gICAgaWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCB8fCB2YWwgPT09ICcnKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBzdHJWYWwgPSBTdHJpbmcodmFsKTtcbiAgICBjb25zdCBmb3VuZCA9IHRoaXMuYWxsT3B0aW9ucygpLmZpbmQoKG9wdCkgPT4gU3RyaW5nKG9wdC5rZXkpID09PSBzdHJWYWwpO1xuICAgIGlmIChmb3VuZCkgcmV0dXJuIGZvdW5kO1xuICAgIHJldHVybiB7IGtleTogdmFsIGFzIHN0cmluZyB8IG51bWJlciwgbGFiZWw6IHN0clZhbCB9O1xuICB9KTtcblxuICByZWFkb25seSBmaWx0ZXJlZE9wdGlvbnMgPSBjb21wdXRlZDxEcm9wZG93bk9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3QgdGVybSA9IHRoaXMuc2VhcmNoVGVybSgpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IGFsbCA9IHRoaXMuYWxsT3B0aW9ucygpO1xuICAgIGlmICghdGVybSkgcmV0dXJuIGFsbDtcbiAgICByZXR1cm4gYWxsLmZpbHRlcigob3B0KSA9PlxuICAgICAgb3B0LmxhYmVsLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybSkgfHwgU3RyaW5nKG9wdC5rZXkpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybSlcbiAgICApO1xuICB9KTtcblxuICByZWFkb25seSBNQVhfRklMVEVSX1JFTkRFUiA9IDIwMDtcbiAgcmVhZG9ubHkgdmlzaWJsZUZpbHRlcmVkT3B0aW9ucyA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uW10+KCgpID0+IHtcbiAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMuZmlsdGVyZWRPcHRpb25zKCk7XG4gICAgaWYgKGZpbHRlcmVkLmxlbmd0aCA8PSB0aGlzLk1BWF9GSUxURVJfUkVOREVSKSByZXR1cm4gZmlsdGVyZWQ7XG4gICAgcmV0dXJuIGZpbHRlcmVkLnNsaWNlKDAsIHRoaXMuTUFYX0ZJTFRFUl9SRU5ERVIpO1xuICB9KTtcblxuICByZWFkb25seSBleGNlc3NGaWx0ZXJlZENvdW50ID0gY29tcHV0ZWQ8bnVtYmVyPigoKSA9PiB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIHRoaXMuZmlsdGVyZWRPcHRpb25zKCkubGVuZ3RoIC0gdGhpcy5NQVhfRklMVEVSX1JFTkRFUik7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IE1BWF9SRU5ERVJFRF9PUFRJT05TID0gNTAwO1xuICByZWFkb25seSByZW5kZXJlZE9wdGlvbnMgPSBjb21wdXRlZDxEcm9wZG93bk9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMuYWxsT3B0aW9ucygpO1xuICAgIGlmIChvcHRzLmxlbmd0aCA8PSB0aGlzLk1BWF9SRU5ERVJFRF9PUFRJT05TKSByZXR1cm4gb3B0cztcbiAgICByZXR1cm4gb3B0cy5zbGljZSgwLCB0aGlzLk1BWF9SRU5ERVJFRF9PUFRJT05TKTtcbiAgfSk7XG4gIHJlYWRvbmx5IGhhc0V4Y2Vzc09wdGlvbnMgPSBjb21wdXRlZDxib29sZWFuPigoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuYWxsT3B0aW9ucygpLmxlbmd0aCA+IHRoaXMuTUFYX1JFTkRFUkVEX09QVElPTlM7XG4gIH0pO1xuICByZWFkb25seSBleGNlc3NPcHRpb25zQ291bnQgPSBjb21wdXRlZDxudW1iZXI+KCgpID0+IHtcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgdGhpcy5hbGxPcHRpb25zKCkubGVuZ3RoIC0gdGhpcy5NQVhfUkVOREVSRURfT1BUSU9OUyk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHdhaXRpbmdMYWJlbCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBrZXlzID0gdGhpcy53YWl0aW5nRm9yKCk7XG4gICAgaWYgKGtleXMubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIGtleXMuam9pbignLCAnKTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgc3RhdHVzS2luZCA9IGNvbXB1dGVkPCdpZGxlJyB8ICdsb2FkaW5nJyB8ICdvaycgfCAnd2FpdGluZycgfCAnZXJyb3InIHwgJ2VtcHR5Jz4oKCkgPT4ge1xuICAgIGlmICghdGhpcy5pc0R5bmFtaWNTb3VyY2UoKSkgcmV0dXJuICdpZGxlJztcbiAgICBpZiAodGhpcy5pc0xvYWRpbmcoKSkgcmV0dXJuICdsb2FkaW5nJztcbiAgICBpZiAodGhpcy5sb2FkRXJyb3IoKSkgcmV0dXJuICdlcnJvcic7XG4gICAgaWYgKHRoaXMud2FpdGluZ0ZvcigpLmxlbmd0aCA+IDApIHJldHVybiAnd2FpdGluZyc7XG4gICAgaWYgKHRoaXMuaGFzTG9hZGVkKCkpIHJldHVybiB0aGlzLmR5bmFtaWNPcHRpb25zKCkubGVuZ3RoID4gMCA/ICdvaycgOiAnZW1wdHknO1xuICAgIHJldHVybiAnaWRsZSc7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHN0YXR1c1RleHQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgc3dpdGNoICh0aGlzLnN0YXR1c0tpbmQoKSkge1xuICAgICAgY2FzZSAnbG9hZGluZyc6XG4gICAgICAgIHJldHVybiAnTG9hZGluZyBmcm9tIGRhdGFiYXNl4oCmJztcbiAgICAgIGNhc2UgJ29rJzpcbiAgICAgICAgcmV0dXJuIGAke3RoaXMuZHluYW1pY09wdGlvbnMoKS5sZW5ndGh9IHJlY29yZHMgbG9hZGVkYDtcbiAgICAgIGNhc2UgJ3dhaXRpbmcnOlxuICAgICAgICByZXR1cm4gYFdhaXRpbmcgZm9yOiAke3RoaXMud2FpdGluZ0xhYmVsKCl9YDtcbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgcmV0dXJuIHRoaXMubG9hZEVycm9yKCkgPz8gJ0ZhaWxlZCB0byBsb2FkJztcbiAgICAgIGNhc2UgJ2VtcHR5JzpcbiAgICAgICAgcmV0dXJuICdRdWVyeSByZXR1cm5lZCBubyByZWNvcmRzIGZvciB0aGVzZSBwYXJhbWV0ZXJzJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH0pO1xuXG4gIHJlYWRvbmx5IGlzSW52YWxpZCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBjdHJsID0gdGhpcy5mb3JtQ29udHJvbCgpO1xuICAgIHJldHVybiBjdHJsLmludmFsaWQgJiYgKGN0cmwuZGlydHkgfHwgY3RybC50b3VjaGVkKTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgZXJyb3JNZXNzYWdlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGN0cmwgPSB0aGlzLmZvcm1Db250cm9sKCk7XG4gICAgaWYgKCFjdHJsLmludmFsaWQgfHwgKCFjdHJsLmRpcnR5ICYmICFjdHJsLnRvdWNoZWQpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIGNvbnN0IGVycm9ycyA9IGN0cmwuZXJyb3JzO1xuICAgIGlmICghZXJyb3JzKSByZXR1cm4gJyc7XG4gICAgY29uc3QgZmlyc3RLZXkgPSBPYmplY3Qua2V5cyhlcnJvcnMpWzBdO1xuICAgIHJldHVybiBnZXRWYWxpZGF0aW9uTWVzc2FnZSh0aGlzLmNvbmZpZygpLnZhbGlkYXRpb24sIGZpcnN0S2V5KTtcbiAgfSk7XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICBvbkRvY3VtZW50Q2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNPcGVuKCkpIHJldHVybjtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgTm9kZTtcbiAgICBpZiAoIXRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKHRhcmdldCkpIHtcbiAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmtleWRvd24uZXNjYXBlJylcbiAgb25Fc2NhcGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgIH1cbiAgfVxuXG4gIGlzU2VsZWN0ZWQob3B0OiBEcm9wZG93bk9wdGlvbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGN1ciA9IHRoaXMuY3VycmVudFZhbHVlKCk7XG4gICAgaWYgKGN1ciA9PT0gbnVsbCB8fCBjdXIgPT09IHVuZGVmaW5lZCB8fCBjdXIgPT09ICcnKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIFN0cmluZyhjdXIpID09PSBTdHJpbmcob3B0LmtleSk7XG4gIH1cblxuICB0b2dnbGVPcGVuKGV2ZW50PzogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgICBpZiAodGhpcy5mb3JtQ29udHJvbCgpLmRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9wZW5Ecm9wZG93bigpO1xuICAgIH1cbiAgfVxuXG4gIG9wZW5Ecm9wZG93bigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5mb3JtQ29udHJvbCgpLmRpc2FibGVkKSByZXR1cm47XG5cbiAgICAvLyBDaGVjayBhdmFpbGFibGUgdmlld3BvcnQgc3BhY2UgdG8gZGV0ZXJtaW5lIGlmIG1lbnUgc2hvdWxkIG9wZW4gYWJvdmVcbiAgICBjb25zdCB3cmFwcGVyID0gdGhpcy5jb21ib2JveFdyYXBwZXJFbCgpPy5uYXRpdmVFbGVtZW50ID8/IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHJlY3QgPSB3cmFwcGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHNwYWNlQmVsb3cgPSB3aW5kb3cuaW5uZXJIZWlnaHQgLSByZWN0LmJvdHRvbTtcbiAgICBjb25zdCBzcGFjZUFib3ZlID0gcmVjdC50b3A7XG5cbiAgICBjb25zdCBwcmVmZXJBYm92ZSA9IHRoaXMuY29uZmlnKCk/LnByb3BlcnRpZXM/Llsnb3BlbkFib3ZlJ10gPT09IHRydWU7XG4gICAgY29uc3QgYXV0b0Fib3ZlID0gc3BhY2VCZWxvdyA8IDI2MCAmJiBzcGFjZUFib3ZlID4gMTYwO1xuICAgIHRoaXMub3BlbnNBYm92ZS5zZXQocHJlZmVyQWJvdmUgfHwgYXV0b0Fib3ZlKTtcblxuICAgIHRoaXMuaXNPcGVuLnNldCh0cnVlKTtcbiAgICB0aGlzLnNlYXJjaFRlcm0uc2V0KCcnKTtcbiAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQoLTEpO1xuXG4gICAgLy8gQXV0by1mb2N1cyBzZWFyY2ggaW5wdXQgYWZ0ZXIgcmVuZGVyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnNlYXJjaElucHV0RWwoKT8ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgIH0sIDEwKTtcbiAgfVxuXG4gIGNsb3NlRHJvcGRvd24oKTogdm9pZCB7XG4gICAgdGhpcy5pc09wZW4uc2V0KGZhbHNlKTtcbiAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQoLTEpO1xuICAgIHRoaXMuZm9ybUNvbnRyb2woKS5tYXJrQXNUb3VjaGVkKCk7XG4gIH1cblxuICBzZWxlY3RPcHRpb24ob3B0OiBEcm9wZG93bk9wdGlvbik6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudFZhbHVlLnNldChvcHQua2V5KTtcbiAgICB0aGlzLmZvcm1Db250cm9sKCkuc2V0VmFsdWUob3B0LmtleSk7XG4gICAgdGhpcy5mb3JtQ29udHJvbCgpLm1hcmtBc0RpcnR5KCk7XG4gICAgdGhpcy5mb3JtQ29udHJvbCgpLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLmNsb3NlRHJvcGRvd24oKTtcbiAgfVxuXG4gIGNsZWFyU2VsZWN0aW9uKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5jdXJyZW50VmFsdWUuc2V0KCcnKTtcbiAgICB0aGlzLmZvcm1Db250cm9sKCkuc2V0VmFsdWUoJycpO1xuICAgIHRoaXMuZm9ybUNvbnRyb2woKS5tYXJrQXNEaXJ0eSgpO1xuICAgIHRoaXMuZm9ybUNvbnRyb2woKS5tYXJrQXNUb3VjaGVkKCk7XG4gICAgdGhpcy5zZWFyY2hUZXJtLnNldCgnJyk7XG4gICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KC0xKTtcbiAgfVxuXG4gIGNsZWFyU2VhcmNoKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuc2VhcmNoVGVybS5zZXQoJycpO1xuICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldCgtMSk7XG4gICAgdGhpcy5zZWFyY2hJbnB1dEVsKCk/Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgfVxuXG4gIG9uU2VhcmNoSW5wdXQoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdmFsID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZTtcbiAgICB0aGlzLnNlYXJjaFRlcm0uc2V0KHZhbCk7XG4gICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KDApO1xuICB9XG5cbiAgb25UcmlnZ2VyS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudC5rZXkgPT09ICdBcnJvd0Rvd24nIHx8IGV2ZW50LmtleSA9PT0gJ0VudGVyJyB8fCBldmVudC5rZXkgPT09ICcgJykge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHRoaXMub3BlbkRyb3Bkb3duKCk7XG4gICAgfVxuICB9XG5cbiAgb25TZWFyY2hLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdmlzaWJsZSA9IHRoaXMudmlzaWJsZUZpbHRlcmVkT3B0aW9ucygpO1xuICAgIGNvbnN0IGNvdW50ID0gdmlzaWJsZS5sZW5ndGg7XG5cbiAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgY2FzZSAnQXJyb3dEb3duJzoge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICAgICAgY29uc3QgbmV4dCA9ICh0aGlzLmZvY3VzZWRJbmRleCgpICsgMSkgJSBjb3VudDtcbiAgICAgICAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQobmV4dCk7XG4gICAgICAgICAgdGhpcy5zY3JvbGxGb2N1c2VkSW50b1ZpZXcoKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ0Fycm93VXAnOiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGlmIChjb3VudCA+IDApIHtcbiAgICAgICAgICBjb25zdCBwcmV2ID0gdGhpcy5mb2N1c2VkSW5kZXgoKSA8PSAwID8gY291bnQgLSAxIDogdGhpcy5mb2N1c2VkSW5kZXgoKSAtIDE7XG4gICAgICAgICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KHByZXYpO1xuICAgICAgICAgIHRoaXMuc2Nyb2xsRm9jdXNlZEludG9WaWV3KCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdFbnRlcic6IHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgaWR4ID0gdGhpcy5mb2N1c2VkSW5kZXgoKTtcbiAgICAgICAgaWYgKGlkeCA+PSAwICYmIGlkeCA8IGNvdW50KSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RPcHRpb24odmlzaWJsZVtpZHhdKTtcbiAgICAgICAgfSBlbHNlIGlmIChjb3VudCA9PT0gMSkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0T3B0aW9uKHZpc2libGVbMF0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnRXNjYXBlJzoge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmNsb3NlRHJvcGRvd24oKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdUYWInOiB7XG4gICAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNjcm9sbEZvY3VzZWRJbnRvVmlldygpOiB2b2lkIHtcbiAgICBjb25zdCBsaXN0RWwgPSB0aGlzLm9wdGlvbnNMaXN0RWwoKT8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWxpc3RFbCkgcmV0dXJuO1xuICAgIGNvbnN0IGl0ZW1zID0gbGlzdEVsLnF1ZXJ5U2VsZWN0b3JBbGw8SFRNTEVsZW1lbnQ+KCcuY29tYm9ib3gtb3B0aW9uLWl0ZW0nKTtcbiAgICBjb25zdCBpZHggPSB0aGlzLmZvY3VzZWRJbmRleCgpO1xuICAgIGlmIChpdGVtcyAmJiBpdGVtc1tpZHhdKSB7XG4gICAgICBpdGVtc1tpZHhdLnNjcm9sbEludG9WaWV3KHsgYmxvY2s6ICduZWFyZXN0JyB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBTeW5jIHJlYWN0aXZlIGZvcm0gY29udHJvbCB2YWx1ZSBjaGFuZ2VzIHRvIGN1cnJlbnRWYWx1ZSBzaWduYWxcbiAgICBlZmZlY3QoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGN0cmwgPSB0aGlzLmZvcm1Db250cm9sKCk7XG4gICAgICAgIHVudHJhY2tlZCgoKSA9PiB0aGlzLmN1cnJlbnRWYWx1ZS5zZXQoY3RybC52YWx1ZSkpO1xuICAgICAgICB0aGlzLmNvbnRyb2xTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMuY29udHJvbFN1YiA9IGN0cmwudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSgodikgPT4gdGhpcy5jdXJyZW50VmFsdWUuc2V0KHYpKTtcbiAgICAgIH0sXG4gICAgICB7IGFsbG93U2lnbmFsV3JpdGVzOiB0cnVlIH1cbiAgICApO1xuXG4gICAgLy8gUmUtcnVuIHdoZW5ldmVyIHRoZSBib3VuZCBkYXRhIHNvdXJjZSwgdGhlIHNlc3Npb24sIG9yIHRoZSBwYXJlbnQgZm9ybSBjaGFuZ2VzLlxuICAgIGVmZmVjdChcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvblNlcnZpY2U/LnNlc3Npb25Db250ZXh0KCkgPz8ge307XG4gICAgICAgIGNvbnN0IGZvcm0gPSB0aGlzLnBhcmVudEZvcm0oKTtcbiAgICAgICAgdGhpcy5jb25maWcoKTsgLy8gZGVwZW5kZW5jeTogZGF0YSBzb3VyY2UgY29uZmlndXJhdGlvblxuXG4gICAgICAgIHRoaXMuZm9ybUNoYW5nZXNTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIGlmIChmb3JtICYmIHRoaXMuaXNEeW5hbWljU291cmNlKCkpIHtcbiAgICAgICAgICB0aGlzLmZvcm1DaGFuZ2VzU3ViID0gZm9ybS52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHRoaXMuc2NoZWR1bGVSZWxvYWQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgdW50cmFja2VkKCgpID0+IHRoaXMucmVsb2FkRGF0YVNvdXJjZU9wdGlvbnMoc2Vzc2lvbikpO1xuICAgICAgfSxcbiAgICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfVxuICAgICk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5sb29rdXBTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5tYXN0ZXJEYXRhU3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuZm9ybUNoYW5nZXNTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgaWYgKHRoaXMucmVsb2FkVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnJlbG9hZFRpbWVyKTtcbiAgfVxuXG4gIHByaXZhdGUgc2NoZWR1bGVSZWxvYWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVsb2FkVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnJlbG9hZFRpbWVyKTtcbiAgICB0aGlzLnJlbG9hZFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnJlbG9hZERhdGFTb3VyY2VPcHRpb25zKHRoaXMuc2Vzc2lvblNlcnZpY2U/LnNlc3Npb25Db250ZXh0KCkgPz8ge30pO1xuICAgIH0sIDI1MCk7XG4gIH1cblxuICBwcml2YXRlIHJlbG9hZERhdGFTb3VyY2VPcHRpb25zKHNlc3Npb246IFNlc3Npb25Db250ZXh0TWFwKTogdm9pZCB7XG4gICAgY29uc3QgZHMgPSB0aGlzLmNvbmZpZygpLmRhdGFTb3VyY2U7XG4gICAgaWYgKCFkcyB8fCAhdGhpcy5pc0R5bmFtaWNTb3VyY2UoKSkgcmV0dXJuO1xuXG4gICAgLy8gMS4gRGF0YWJhc2UgVGFibGUgLyBTdG9yZWQgUHJvY2VkdXJlIExvb2t1cFxuICAgIGlmIChkcy5lbnRpdHlOYW1lICYmIChkcy5zb3VyY2VUeXBlID09PSAndGFibGUnIHx8IGRzLnNvdXJjZVR5cGUgPT09ICdwcm9jZWR1cmUnKSAmJiB0aGlzLmxvb2t1cEFkYXB0ZXIpIHtcbiAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSB0aGlzLnBhcmVudEZvcm0oKT8uZ2V0UmF3VmFsdWUoKSA/PyB7fTtcblxuICAgICAgLy8gRG8gbm90IGNhbGwgdGhlIGRhdGFiYXNlIHVudGlsIGV2ZXJ5IGNhbnZhcyBmaWVsZCB0aGlzIGxvb2t1cCBkZXBlbmRzIG9uIGlzIGZpbGxlZC5cbiAgICAgIGNvbnN0IG1pc3NpbmcgPSBmaW5kTWlzc2luZ0NhbnZhc0ZpZWxkcyhkcy5wYXJhbWV0ZXJNYXBwaW5ncywgZm9ybVZhbHVlcyk7XG4gICAgICB0aGlzLndhaXRpbmdGb3Iuc2V0KG1pc3NpbmcpO1xuICAgICAgaWYgKG1pc3NpbmcubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmxvb2t1cFN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5pc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgdGhpcy5sb2FkRXJyb3Iuc2V0KG51bGwpO1xuICAgICAgICB0aGlzLmR5bmFtaWNPcHRpb25zLnNldChbXSk7XG4gICAgICAgIHRoaXMubGFzdFJlcXVlc3RLZXkgPSAnJztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBTdG9yZWQgcHJvY2VkdXJlcyBvbmx5IHJlY2VpdmUgZXhwbGljaXQgbWFwcGluZ3Mgc28gU1FMIFNlcnZlciBkb2Vzbid0IHJlamVjdCB1bmtub3duIGFyZ3VtZW50cy5cbiAgICAgIGNvbnN0IHJlc29sdmVkUGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHtcbiAgICAgICAgLi4uKGRzLnNvdXJjZVR5cGUgPT09ICd0YWJsZScgPyBzZXNzaW9uIDoge30pLFxuICAgICAgICAuLi5yZXNvbHZlUGFyYW1ldGVyTWFwcGluZ3MoZHMucGFyYW1ldGVyTWFwcGluZ3MsIHNlc3Npb24sIGZvcm1WYWx1ZXMpLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVxdWVzdCA9IHtcbiAgICAgICAgc291cmNlVHlwZTogZHMuc291cmNlVHlwZSA/PyAndGFibGUnLFxuICAgICAgICBlbnRpdHlOYW1lOiBkcy5lbnRpdHlOYW1lLFxuICAgICAgICBzY2hlbWE6IGRzLnNjaGVtYSA/PyAnZGJvJyxcbiAgICAgICAgdmFsdWVGaWVsZDogZHMudmFsdWVGaWVsZCB8fCAnaWQnLFxuICAgICAgICBkaXNwbGF5RmllbGQ6IGRzLmRpc3BsYXlGaWVsZCB8fCAnbmFtZScsXG4gICAgICAgIGZpbHRlcjogZHMuZmlsdGVyLFxuICAgICAgICBwYXJhbWV0ZXJzOiByZXNvbHZlZFBhcmFtcyxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXF1ZXN0S2V5ID0gSlNPTi5zdHJpbmdpZnkocmVxdWVzdCk7XG4gICAgICBpZiAocmVxdWVzdEtleSA9PT0gdGhpcy5sYXN0UmVxdWVzdEtleSkgcmV0dXJuOyAvLyBub3RoaW5nIGNoYW5nZWRcbiAgICAgIHRoaXMubGFzdFJlcXVlc3RLZXkgPSByZXF1ZXN0S2V5O1xuXG4gICAgICB0aGlzLmlzTG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgICB0aGlzLmxvYWRFcnJvci5zZXQobnVsbCk7XG4gICAgICB0aGlzLmxvb2t1cFN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMubG9va3VwU3ViID0gdGhpcy5sb29rdXBBZGFwdGVyLmZldGNoT3B0aW9ucyhyZXF1ZXN0KS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoaXRlbXMpID0+IHtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuaGFzTG9hZGVkLnNldCh0cnVlKTtcbiAgICAgICAgICAvLyBEZWR1cGxpY2F0ZSBpdGVtcyBieSBrZXkvdmFsdWUgdG8gZW5zdXJlIGNsZWFuIHNlbGVjdCBvcHRpb25zXG4gICAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgICAgIGNvbnN0IGRlZHVwZWQ6IERyb3Bkb3duT3B0aW9uW10gPSBbXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGl0IG9mIGl0ZW1zKSB7XG4gICAgICAgICAgICBjb25zdCBrID0gU3RyaW5nKGl0LnZhbHVlKTtcbiAgICAgICAgICAgIGlmICghc2Vlbi5oYXMoaykpIHtcbiAgICAgICAgICAgICAgc2Vlbi5hZGQoayk7XG4gICAgICAgICAgICAgIGRlZHVwZWQucHVzaCh7IGtleTogaywgbGFiZWw6IGl0LmxhYmVsIHx8IGsgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuZHluYW1pY09wdGlvbnMuc2V0KGRlZHVwZWQpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtScHREcm9wZG93bl0gRmFpbGVkIHRvIGxvYWQgbG9va3VwIG9wdGlvbnMgZm9yICR7ZHMuZW50aXR5TmFtZX06YCwgZXJyKTtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuaGFzTG9hZGVkLnNldCh0cnVlKTtcbiAgICAgICAgICB0aGlzLmR5bmFtaWNPcHRpb25zLnNldChbXSk7XG4gICAgICAgICAgdGhpcy5sYXN0UmVxdWVzdEtleSA9ICcnOyAvLyBhbGxvdyByZXRyeVxuICAgICAgICAgIHRoaXMubG9hZEVycm9yLnNldChlcnI/Lm1lc3NhZ2UgfHwgJ0RhdGFiYXNlIHF1ZXJ5IGVycm9yJyk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyAyLiBMZWdhY3kgTWFzdGVyIERhdGEgUHJvdmlkZXJcbiAgICBpZiAoZHMubWFzdGVyTmFtZSAmJiB0aGlzLm1hc3RlckRhdGFQcm92aWRlciAmJiAhdGhpcy5tYXN0ZXJEYXRhU3ViKSB7XG4gICAgICB0aGlzLmlzTG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgICB0aGlzLmxvYWRFcnJvci5zZXQobnVsbCk7XG4gICAgICB0aGlzLm1hc3RlckRhdGFTdWIgPSB0aGlzLm1hc3RlckRhdGFQcm92aWRlci5nZXRNYXN0ZXJEYXRhKGRzLm1hc3Rlck5hbWUpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChpdGVtcykgPT4ge1xuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgICAgdGhpcy5oYXNMb2FkZWQuc2V0KHRydWUpO1xuICAgICAgICAgIHRoaXMuZHluYW1pY09wdGlvbnMuc2V0KFxuICAgICAgICAgICAgaXRlbXMubWFwKChpdCkgPT4gKHtcbiAgICAgICAgICAgICAga2V5OiBTdHJpbmcoaXQudmFsdWUgPz8gaXRbJ2lkJ10gPz8gJycpLFxuICAgICAgICAgICAgICBsYWJlbDogU3RyaW5nKGl0LmxhYmVsID8/IGl0WyduYW1lJ10gPz8gJycpLFxuICAgICAgICAgICAgfSkpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGBbUnB0RHJvcGRvd25dIEZhaWxlZCB0byBsb2FkIG1hc3RlciBkYXRhIGZvciAke2RzLm1hc3Rlck5hbWV9OmAsIGVycik7XG4gICAgICAgICAgdGhpcy5pc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICB0aGlzLmhhc0xvYWRlZC5zZXQodHJ1ZSk7XG4gICAgICAgICAgdGhpcy5sb2FkRXJyb3Iuc2V0KGVycj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIGxvYWQgbWFzdGVyIGRhdGEnKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIiwiICAgIDxkaXYgY2xhc3M9XCJycHQtZmllbGQtZ3JvdXBcIj5cbiAgICAgIEBpZiAoY29uZmlnKCkubGFiZWwpIHtcbiAgICAgICAgPGxhYmVsIFtmb3JdPVwiZWxlbWVudElkKClcIiBjbGFzcz1cInJwdC1sYWJlbFwiPlxuICAgICAgICAgIHt7IGNvbmZpZygpLmxhYmVsIH19XG4gICAgICAgICAgQGlmIChjb25maWcoKS52YWxpZGF0aW9uPy5yZXF1aXJlZCkge1xuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJycHQtcmVxdWlyZWQtbWFya2VyXCI+Kjwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICB9XG5cbiAgICAgIEBpZiAoaXNTZWFyY2hhYmxlKCkpIHtcbiAgICAgICAgPCEtLSBTZWFyY2hhYmxlIFR5cGVhaGVhZCBDb21ib2JveCAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJwdC1jb21ib2JveC13cmFwcGVyXCIgI2NvbWJvYm94V3JhcHBlcj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwicnB0LWNvbWJvYm94LXRyaWdnZXJcIlxuICAgICAgICAgICAgW2lkXT1cImVsZW1lbnRJZCgpXCJcbiAgICAgICAgICAgIFtjbGFzcy5ycHQtaW52YWxpZF09XCJpc0ludmFsaWQoKVwiXG4gICAgICAgICAgICBbY2xhc3MuaXMtb3Blbl09XCJpc09wZW4oKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiZm9ybUNvbnRyb2woKS5kaXNhYmxlZFwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cImlzT3BlbigpXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtaGFzcG9wdXBdPVwiJ2xpc3Rib3gnXCJcbiAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVPcGVuKCRldmVudClcIlxuICAgICAgICAgICAgKGtleWRvd24pPVwib25UcmlnZ2VyS2V5ZG93bigkZXZlbnQpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRyaWdnZXItbGFiZWxcIiBbY2xhc3MuaXMtcGxhY2Vob2xkZXJdPVwiIXNlbGVjdGVkT3B0aW9uKClcIj5cbiAgICAgICAgICAgICAge3sgc2VsZWN0ZWRPcHRpb24oKSA/IHNlbGVjdGVkT3B0aW9uKCkhLmxhYmVsIDogcGxhY2Vob2xkZXIoKSB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHJpZ2dlci1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgIEBpZiAoc2VsZWN0ZWRPcHRpb24oKSAmJiAhZm9ybUNvbnRyb2woKS5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInRyaWdnZXItY2xlYXItYnRuXCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQ2xlYXIgc2VsZWN0aW9uXCJcbiAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJDbGVhciBzZWxlY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNsZWFyU2VsZWN0aW9uKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiY2xlYXJTZWxlY3Rpb24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAoa2V5ZG93bi5zcGFjZSk9XCJjbGVhclNlbGVjdGlvbigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICDinJVcbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0cmlnZ2VyLWFycm93XCIgW2NsYXNzLnJvdGF0ZWRdPVwiaXNPcGVuKClcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTJcIiBoZWlnaHQ9XCI4XCIgdmlld0JveD1cIjAgMCAxMiA4XCIgZmlsbD1cIm5vbmVcIj5cbiAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMSAxLjVMNiA2LjVMMTEgMS41XCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIvPlxuICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgIEBpZiAoaXNPcGVuKCkpIHtcbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgY2xhc3M9XCJycHQtY29tYm9ib3gtbWVudVwiXG4gICAgICAgICAgICAgIFtjbGFzcy5vcGVucy1hYm92ZV09XCJvcGVuc0Fib3ZlKClcIlxuICAgICAgICAgICAgICByb2xlPVwibGlzdGJveFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8IS0tIFJlYWwtdGltZSBGaWx0ZXIgU2VhcmNoIEJveCAtLT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LXNlYXJjaC1ib3hcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbWJvYm94LXNlYXJjaC1pY29uXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTNcIiBoZWlnaHQ9XCIxM1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjIuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiPlxuICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PVwiMTFcIiBjeT1cIjExXCIgcj1cIjhcIj48L2NpcmNsZT5cbiAgICAgICAgICAgICAgICAgICAgPGxpbmUgeDE9XCIyMVwiIHkxPVwiMjFcIiB4Mj1cIjE2LjY1XCIgeTI9XCIxNi42NVwiPjwvbGluZT5cbiAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICNzZWFyY2hJbnB1dFxuICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb21ib2JveC1zZWFyY2gtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJUeXBlIHRvIGZpbHRlci4uLlwiXG4gICAgICAgICAgICAgICAgICBbdmFsdWVdPVwic2VhcmNoVGVybSgpXCJcbiAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtYWN0aXZlZGVzY2VuZGFudF09XCJmb2N1c2VkSW5kZXgoKSA+PSAwID8gKGVsZW1lbnRJZCgpICsgJ19vcHRfJyArIGZvY3VzZWRJbmRleCgpKSA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgKGlucHV0KT1cIm9uU2VhcmNoSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAoa2V5ZG93bik9XCJvblNlYXJjaEtleWRvd24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICBAaWYgKHNlYXJjaFRlcm0oKSkge1xuICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb21ib2JveC1zZWFyY2gtY2xlYXJcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkNsZWFyIGZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjbGVhclNlYXJjaCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAg4pyVXG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgIDwhLS0gRmlsdGVyZWQgT3B0aW9ucyBMaXN0IC0tPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tYm9ib3gtb3B0aW9ucy1saXN0XCIgI29wdGlvbnNMaXN0RWw+XG4gICAgICAgICAgICAgICAgQGlmIChpc0xvYWRpbmcoKSkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LXN0YXR1cy1yb3cgbG9hZGluZ1wiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1kb3QgZG90LXB1bHNlXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5Mb2FkaW5nIG9wdGlvbnMgZnJvbSBkYXRhYmFzZS4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH0gQGVsc2UgaWYgKGxvYWRFcnJvcigpKSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tYm9ib3gtc3RhdHVzLXJvdyBlcnJvclwiPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5FcnJvcjoge3sgbG9hZEVycm9yKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9IEBlbHNlIGlmIChpc0R5bmFtaWNTb3VyY2UoKSAmJiBoYXNMb2FkZWQoKSAmJiBhbGxPcHRpb25zKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tYm9ib3gtc3RhdHVzLXJvdyBlbXB0eVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5ObyByZWNvcmRzIGZvdW5kIChjaGVjayBwYXJhbWV0ZXJzKTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH0gQGVsc2UgaWYgKGZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LXN0YXR1cy1yb3cgZW1wdHlcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+Tm8gb3B0aW9ucyBtYXRjaGluZyBcInt7IHNlYXJjaFRlcm0oKSB9fVwiPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICBAZm9yIChvcHQgb2YgdmlzaWJsZUZpbHRlcmVkT3B0aW9ucygpOyB0cmFjayBvcHQua2V5OyBsZXQgaSA9ICRpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgcm9sZT1cIm9wdGlvblwiXG4gICAgICAgICAgICAgICAgICAgICAgW2lkXT1cImVsZW1lbnRJZCgpICsgJ19vcHRfJyArIGlcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29tYm9ib3gtb3B0aW9uLWl0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1zZWxlY3RlZF09XCJpc1NlbGVjdGVkKG9wdClcIlxuICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1mb2N1c2VkXT1cImZvY3VzZWRJbmRleCgpID09PSBpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLXNlbGVjdGVkXT1cImlzU2VsZWN0ZWQob3B0KVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdE9wdGlvbihvcHQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAobW91c2VlbnRlcik9XCJmb2N1c2VkSW5kZXguc2V0KGkpXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwib3B0LWxhYmVsXCI+e3sgb3B0LmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAoaXNTZWxlY3RlZChvcHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm9wdC1jaGVja1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPuKckzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgQGlmIChleGNlc3NGaWx0ZXJlZENvdW50KCkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21ib2JveC1zdGF0dXMtcm93IGhpbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5TaG93aW5nIHt7IE1BWF9GSUxURVJfUkVOREVSIH19IG9mIHt7IGZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCB9fSBtYXRjaGVzLiBUeXBlIHRvIHJlZmluZS48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgfSBAZWxzZSB7XG4gICAgICAgIDwhLS0gTmF0aXZlIEJyb3dzZXIgU2VsZWN0IEZhbGxiYWNrIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXNlbGVjdC13cmFwcGVyXCI+XG4gICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgW2lkXT1cImVsZW1lbnRJZCgpXCJcbiAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbCgpXCJcbiAgICAgICAgICAgIFtjbGFzcy5ycHQtaW52YWxpZF09XCJpc0ludmFsaWQoKVwiXG4gICAgICAgICAgICBjbGFzcz1cInJwdC1zZWxlY3RcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEBpZiAoaXNMb2FkaW5nKCkpIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiIGRpc2FibGVkIHNlbGVjdGVkPkxvYWRpbmcgb3B0aW9ucyBmcm9tIGRhdGFiYXNlLi4uPC9vcHRpb24+XG4gICAgICAgICAgICB9IEBlbHNlIGlmIChsb2FkRXJyb3IoKSkge1xuICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCIgZGlzYWJsZWQgc2VsZWN0ZWQ+RXJyb3I6IHt7IGxvYWRFcnJvcigpIH19PC9vcHRpb24+XG4gICAgICAgICAgICB9IEBlbHNlIGlmIChpc0R5bmFtaWNTb3VyY2UoKSAmJiBoYXNMb2FkZWQoKSAmJiBhbGxPcHRpb25zKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIiBkaXNhYmxlZCBzZWxlY3RlZD4tLSBObyByZWNvcmRzIGZvdW5kIChjaGVjayBwYXJhbWV0ZXJzKSAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgfSBAZWxzZSBpZiAocGxhY2Vob2xkZXIoKSkge1xuICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCIgW2Rpc2FibGVkXT1cImNvbmZpZygpLnZhbGlkYXRpb24/LnJlcXVpcmVkXCI+e3sgcGxhY2Vob2xkZXIoKSB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGZvciAob3B0IG9mIHJlbmRlcmVkT3B0aW9ucygpOyB0cmFjayBvcHQua2V5KSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIm9wdC5rZXlcIj57eyBvcHQubGFiZWwgfX08L29wdGlvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBpZiAoaGFzRXhjZXNzT3B0aW9ucygpKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIiBkaXNhYmxlZD4uLi4gYW5kIHt7IGV4Y2Vzc09wdGlvbnNDb3VudCgpIH19IG1vcmUgcmVjb3JkcyAocmVmaW5lIGZpbHRlcikgLi4uPC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInJwdC1zZWxlY3QtYXJyb3dcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxMlwiIGhlaWdodD1cIjhcIiB2aWV3Qm94PVwiMCAwIDEyIDhcIiBmaWxsPVwibm9uZVwiPlxuICAgICAgICAgICAgICA8cGF0aCBkPVwiTTEgMS41TDYgNi41TDExIDEuNVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cblxuICAgICAgQGlmIChzaG93U3RhdHVzKCkgJiYgaXNEeW5hbWljU291cmNlKCkgJiYgc3RhdHVzVGV4dCgpKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJycHQtc3RhdHVzLWJhZGdlXCIgW2F0dHIuZGF0YS1zdGF0dXNdPVwic3RhdHVzS2luZCgpXCI+XG4gICAgICAgICAgQHN3aXRjaCAoc3RhdHVzS2luZCgpKSB7XG4gICAgICAgICAgICBAY2FzZSAoJ2xvYWRpbmcnKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdCBkb3QtcHVsc2VcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuPkxvYWRpbmcgZnJvbSBkYXRhYmFzZeKApjwvc3Bhbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBjYXNlICgnb2snKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdCBkb3Qtb2tcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuPnt7IGR5bmFtaWNPcHRpb25zKCkubGVuZ3RoIH19IHJlY29yZHMgbG9hZGVkPC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCd3YWl0aW5nJykge1xuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1kb3QgZG90LXdhcm5cIj48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuPldhaXRpbmcgZm9yOjwvc3Bhbj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIndhaXRpbmctdG9rZW5zXCI+XG4gICAgICAgICAgICAgICAgQGZvciAoayBvZiB3YWl0aW5nRm9yKCk7IHRyYWNrIGspIHtcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwid2FpdGluZy10b2tlblwiPnt7IGsgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBjYXNlICgnZXJyb3InKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdCBkb3QtZXJyXCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8c3Bhbj57eyBsb2FkRXJyb3IoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBjYXNlICgnZW1wdHknKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4+Tm8gcmVjb3JkcyBmb3VuZCBmb3IgcGFyYW1ldGVyczwvc3Bhbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBkZWZhdWx0IHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90XCI+PC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG5cbiAgICAgIEBpZiAoZXJyb3JNZXNzYWdlKCkpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJycHQtZXJyb3ItdGV4dFwiPnt7IGVycm9yTWVzc2FnZSgpIH19PC9zcGFuPlxuICAgICAgfVxuICAgIDwvZGl2PiJdfQ==
|
|
466
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnB0LWRyb3Bkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2J3YXlzLXJlcG9ydC9zcmMvbGliL3ByaW1pdGl2ZXMvY29tcG9uZW50cy9kcm9wZG93bi9ycHQtZHJvcGRvd24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvcHJpbWl0aXZlcy9jb21wb25lbnRzL2Ryb3Bkb3duL3JwdC1kcm9wZG93bi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFVBQVUsRUFDVixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNULFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsV0FBVyxFQUFhLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0UsT0FBTyxFQUFnQixVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDZDQUE2QyxDQUFDO0FBQ25GLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFEQUFxRCxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdEQUFnRCxDQUFDO0FBQ3JGLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLHVEQUF1RCxDQUFDO0FBQ3BHLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDZDQUE2QyxDQUFDO0FBRS9FLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsd0JBQXdCLEdBQ3pCLE1BQU0sMkNBQTJDLENBQUM7OztBQW1CbkQsTUFB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S0FBSyxJQUFJLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7cUJBQzVDLENBQUMsQ0FBQyxDQUNKLENBQUM7Z0JBQ0osQ0FBQztnQkFDRCxLQUFLLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtvQkFDYixPQUFPLENBQUMsS0FBSyxDQUFDLGdEQUFnRCxFQUFFLENBQUMsVUFBVSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7b0JBQ3JGLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUMxQixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDekIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLE9BQU8sSUFBSSw0QkFBNEIsQ0FBQyxDQUFDO2dCQUNuRSxDQUFDO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7d0dBNWVVLG9CQUFvQjs0RkFBcEIsb0JBQW9CLGlvQ0M5Q2pDLHVzVUFxT1UsbTdRRGhNRSxtQkFBbUI7OzRGQVNsQixvQkFBb0I7a0JBWmhDLFNBQVM7K0JBQ0UsY0FBYyxjQUNaLElBQUksV0FDUCxDQUFDLG1CQUFtQixDQUFDLFFBQ3hCO3dCQUNKLGlCQUFpQixFQUFFLFVBQVU7d0JBQzdCLHFCQUFxQixFQUFFLGNBQWM7cUJBQ3RDLG1CQUdnQix1QkFBdUIsQ0FBQyxNQUFNO3dEQXdLL0MsZUFBZTtzQkFEZCxZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVUxQyxRQUFRO3NCQURQLFlBQVk7dUJBQUMseUJBQXlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgY29tcHV0ZWQsXG4gIGVmZmVjdCxcbiAgRWxlbWVudFJlZixcbiAgSG9zdExpc3RlbmVyLFxuICBpbmplY3QsXG4gIGlucHV0LFxuICBPbkRlc3Ryb3ksXG4gIHNpZ25hbCxcbiAgdW50cmFja2VkLFxuICB2aWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiwgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGltZW91dCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtY29tcG9uZW50Lm1vZGVsJztcbmltcG9ydCB7IGdldFZhbGlkYXRpb25NZXNzYWdlIH0gZnJvbSAnLi4vLi4vLi4vY29yZS92YWxpZGF0aW9uL3ZhbGlkYXRpb24tZmFjdG9yeSc7XG5pbXBvcnQgeyBNYXN0ZXJEYXRhUHJvdmlkZXIgfSBmcm9tICcuLi8uLi8uLi9kYXRhLWFjY2Vzcy9jb250cmFjdHMvbWFzdGVyLWRhdGEucHJvdmlkZXInO1xuaW1wb3J0IHsgUmVwb3J0TG9va3VwQWRhcHRlciB9IGZyb20gJy4uLy4uLy4uL2RhdGEtYWNjZXNzL2NvbnRyYWN0cy9sb29rdXAuY29udHJhY3QnO1xuaW1wb3J0IHsgUmVwb3J0U2Vzc2lvbkNvbnRleHRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vY29yZS9zZXJ2aWNlcy9yZXBvcnQtc2Vzc2lvbi1jb250ZXh0LnNlcnZpY2UnO1xuaW1wb3J0IHsgUkVQT1JUSU5HX0NPTkZJRyB9IGZyb20gJy4uLy4uLy4uL2NvcmUvdG9rZW5zL3JlcG9ydGluZy1jb25maWcudG9rZW4nO1xuaW1wb3J0IHsgU2Vzc2lvbkNvbnRleHRNYXAgfSBmcm9tICcuLi8uLi8uLi9jb3JlL3Rva2Vucy9zZXNzaW9uLWNvbnRleHQudG9rZW4nO1xuaW1wb3J0IHtcbiAgZmluZE1pc3NpbmdDYW52YXNGaWVsZHMsXG4gIHJlc29sdmVQYXJhbWV0ZXJNYXBwaW5ncyxcbn0gZnJvbSAnLi4vLi4vLi4vY29yZS91dGlscy9yZXBvcnQtcGFyYW1ldGVyLnV0aWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIERyb3Bkb3duT3B0aW9uIHtcbiAga2V5OiBzdHJpbmcgfCBudW1iZXI7XG4gIGxhYmVsOiBzdHJpbmc7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3JwdC1kcm9wZG93bicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtSZWFjdGl2ZUZvcm1zTW9kdWxlXSxcbiAgaG9zdDoge1xuICAgICdbY2xhc3MuaXMtb3Blbl0nOiAnaXNPcGVuKCknLFxuICAgICdbY2xhc3Mub3BlbnMtYWJvdmVdJzogJ29wZW5zQWJvdmUoKScsXG4gIH0sXG4gIHRlbXBsYXRlVXJsOiAnLi9ycHQtZHJvcGRvd24uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vcnB0LWRyb3Bkb3duLmNvbXBvbmVudC5jc3MnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgUnB0RHJvcGRvd25Db21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHJlYWRvbmx5IG1hc3RlckRhdGFQcm92aWRlciA9IGluamVjdChNYXN0ZXJEYXRhUHJvdmlkZXIsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9va3VwQWRhcHRlciA9IGluamVjdChSZXBvcnRMb29rdXBBZGFwdGVyLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuICBwcml2YXRlIHJlYWRvbmx5IHNlc3Npb25TZXJ2aWNlID0gaW5qZWN0KFJlcG9ydFNlc3Npb25Db250ZXh0U2VydmljZSwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbiAgcHJpdmF0ZSByZWFkb25seSByZXBvcnRpbmdDb25maWcgPSBpbmplY3QoUkVQT1JUSU5HX0NPTkZJRywgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbiAgcHJpdmF0ZSByZWFkb25seSBlbGVtZW50UmVmID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuXG4gIHJlYWRvbmx5IGNvbmZpZyA9IGlucHV0LnJlcXVpcmVkPFJlcG9ydENvbXBvbmVudERlZmluaXRpb24+KCk7XG4gIHJlYWRvbmx5IGNvbnRyb2wgPSBpbnB1dDxGb3JtQ29udHJvbCB8IG51bGwgfCB1bmRlZmluZWQ+KCk7XG4gIHJlYWRvbmx5IHBhcmVudEZvcm0gPSBpbnB1dDxGb3JtR3JvdXAgfCBudWxsPihudWxsKTtcbiAgLyoqIERlc2lnbmVyIG1vZGU6IHNob3dzIGEgc21hbGwgc3RhdHVzIGxpbmUgKExvYWRpbmcgLyBOIHJlY29yZHMgLyBXYWl0aW5nIGZvcuKApikuICovXG4gIHJlYWRvbmx5IHNob3dTdGF0dXMgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBmYWxsYmFja0NvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2woJycpO1xuICByZWFkb25seSBkeW5hbWljT3B0aW9ucyA9IHNpZ25hbDxEcm9wZG93bk9wdGlvbltdPihbXSk7XG4gIHByaXZhdGUgbG9va3VwU3ViPzogU3Vic2NyaXB0aW9uO1xuICBwcml2YXRlIG1hc3RlckRhdGFTdWI/OiBTdWJzY3JpcHRpb247XG4gIHByaXZhdGUgZm9ybUNoYW5nZXNTdWI/OiBTdWJzY3JpcHRpb247XG4gIHByaXZhdGUgcmVsb2FkVGltZXI/OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcbiAgcHJpdmF0ZSBsYXN0UmVxdWVzdEtleSA9ICcnO1xuXG4gIC8vIENvbWJvYm94IGludGVyYWN0aXZlIHN0YXRlXG4gIHJlYWRvbmx5IGlzT3BlbiA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IG9wZW5zQWJvdmUgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBzZWFyY2hUZXJtID0gc2lnbmFsPHN0cmluZz4oJycpO1xuICByZWFkb25seSBmb2N1c2VkSW5kZXggPSBzaWduYWw8bnVtYmVyPigtMSk7XG4gIHJlYWRvbmx5IGN1cnJlbnRWYWx1ZSA9IHNpZ25hbDx1bmtub3duPihudWxsKTtcbiAgcmVhZG9ubHkgY29tYm9ib3hXcmFwcGVyRWwgPSB2aWV3Q2hpbGQ8RWxlbWVudFJlZjxIVE1MRWxlbWVudD4+KCdjb21ib2JveFdyYXBwZXInKTtcbiAgcmVhZG9ubHkgc2VhcmNoSW5wdXRFbCA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+Pignc2VhcmNoSW5wdXQnKTtcbiAgcmVhZG9ubHkgb3B0aW9uc0xpc3RFbCA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPEhUTUxFbGVtZW50Pj4oJ29wdGlvbnNMaXN0RWwnKTtcblxuICBwcml2YXRlIGNvbnRyb2xTdWI/OiBTdWJzY3JpcHRpb247XG5cbiAgcmVhZG9ubHkgZm9ybUNvbnRyb2wgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmNvbnRyb2woKSA/PyB0aGlzLmZhbGxiYWNrQ29udHJvbCk7XG4gIHJlYWRvbmx5IGVsZW1lbnRJZCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29uZmlnKCkua2V5IHx8IHRoaXMuY29uZmlnKCkuaWQpO1xuICByZWFkb25seSBwbGFjZWhvbGRlciA9IGNvbXB1dGVkKFxuICAgICgpID0+ICh0aGlzLmNvbmZpZygpLnByb3BlcnRpZXM/LlsncGxhY2Vob2xkZXInXSBhcyBzdHJpbmcpID8/ICctLSBTZWxlY3QgLS0nXG4gICk7XG5cbiAgcmVhZG9ubHkgaXNTZWFyY2hhYmxlID0gY29tcHV0ZWQoXG4gICAgKCkgPT4gdGhpcy5jb25maWcoKS5wcm9wZXJ0aWVzPy5bJ25hdGl2ZVNlbGVjdCddICE9PSB0cnVlXG4gICk7XG5cbiAgcmVhZG9ubHkgaXNMb2FkaW5nID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgaGFzTG9hZGVkID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgbG9hZEVycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICAvKiogQ2FudmFzIGZpZWxkIGtleXMgdGhhdCBtdXN0IGJlIGZpbGxlZCBiZWZvcmUgdGhlIGxvb2t1cCBjYW4gcnVuLiAqL1xuICByZWFkb25seSB3YWl0aW5nRm9yID0gc2lnbmFsPHN0cmluZ1tdPihbXSk7XG5cbiAgcmVhZG9ubHkgaXNEeW5hbWljU291cmNlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGRzID0gdGhpcy5jb25maWcoKS5kYXRhU291cmNlO1xuICAgIHJldHVybiAhIShcbiAgICAgIGRzICYmXG4gICAgICAoZHMuc291cmNlVHlwZSA9PT0gJ3RhYmxlJyB8fFxuICAgICAgICBkcy5zb3VyY2VUeXBlID09PSAncHJvY2VkdXJlJyB8fFxuICAgICAgICBkcy5lbnRpdHlOYW1lIHx8XG4gICAgICAgIGRzLm1hc3Rlck5hbWUpXG4gICAgKTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgc3RhdGljT3B0aW9ucyA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uW10+KCgpID0+IHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5jb25maWcoKS5wcm9wZXJ0aWVzPy5bJ29wdGlvbnMnXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRzKSkge1xuICAgICAgcmV0dXJuIG9wdHM7XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgYWxsT3B0aW9ucyA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uW10+KCgpID0+IHtcbiAgICBpZiAodGhpcy5pc0R5bmFtaWNTb3VyY2UoKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZHluYW1pY09wdGlvbnMoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RhdGljT3B0aW9ucygpO1xuICB9KTtcblxuICByZWFkb25seSBzZWxlY3RlZE9wdGlvbiA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uIHwgbnVsbD4oKCkgPT4ge1xuICAgIGNvbnN0IHZhbCA9IHRoaXMuY3VycmVudFZhbHVlKCk7XG4gICAgaWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCB8fCB2YWwgPT09ICcnKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBzdHJWYWwgPSBTdHJpbmcodmFsKTtcbiAgICBjb25zdCBmb3VuZCA9IHRoaXMuYWxsT3B0aW9ucygpLmZpbmQoKG9wdCkgPT4gU3RyaW5nKG9wdC5rZXkpID09PSBzdHJWYWwpO1xuICAgIGlmIChmb3VuZCkgcmV0dXJuIGZvdW5kO1xuICAgIHJldHVybiB7IGtleTogdmFsIGFzIHN0cmluZyB8IG51bWJlciwgbGFiZWw6IHN0clZhbCB9O1xuICB9KTtcblxuICByZWFkb25seSBmaWx0ZXJlZE9wdGlvbnMgPSBjb21wdXRlZDxEcm9wZG93bk9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3QgdGVybSA9IHRoaXMuc2VhcmNoVGVybSgpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IGFsbCA9IHRoaXMuYWxsT3B0aW9ucygpO1xuICAgIGlmICghdGVybSkgcmV0dXJuIGFsbDtcbiAgICByZXR1cm4gYWxsLmZpbHRlcigob3B0KSA9PlxuICAgICAgb3B0LmxhYmVsLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybSkgfHwgU3RyaW5nKG9wdC5rZXkpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybSlcbiAgICApO1xuICB9KTtcblxuICByZWFkb25seSBNQVhfRklMVEVSX1JFTkRFUiA9IDIwMDtcbiAgcmVhZG9ubHkgdmlzaWJsZUZpbHRlcmVkT3B0aW9ucyA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uW10+KCgpID0+IHtcbiAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMuZmlsdGVyZWRPcHRpb25zKCk7XG4gICAgaWYgKGZpbHRlcmVkLmxlbmd0aCA8PSB0aGlzLk1BWF9GSUxURVJfUkVOREVSKSByZXR1cm4gZmlsdGVyZWQ7XG4gICAgcmV0dXJuIGZpbHRlcmVkLnNsaWNlKDAsIHRoaXMuTUFYX0ZJTFRFUl9SRU5ERVIpO1xuICB9KTtcblxuICByZWFkb25seSBleGNlc3NGaWx0ZXJlZENvdW50ID0gY29tcHV0ZWQ8bnVtYmVyPigoKSA9PiB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIHRoaXMuZmlsdGVyZWRPcHRpb25zKCkubGVuZ3RoIC0gdGhpcy5NQVhfRklMVEVSX1JFTkRFUik7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IE1BWF9SRU5ERVJFRF9PUFRJT05TID0gNTAwO1xuICByZWFkb25seSByZW5kZXJlZE9wdGlvbnMgPSBjb21wdXRlZDxEcm9wZG93bk9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMuYWxsT3B0aW9ucygpO1xuICAgIGlmIChvcHRzLmxlbmd0aCA8PSB0aGlzLk1BWF9SRU5ERVJFRF9PUFRJT05TKSByZXR1cm4gb3B0cztcbiAgICByZXR1cm4gb3B0cy5zbGljZSgwLCB0aGlzLk1BWF9SRU5ERVJFRF9PUFRJT05TKTtcbiAgfSk7XG4gIHJlYWRvbmx5IGhhc0V4Y2Vzc09wdGlvbnMgPSBjb21wdXRlZDxib29sZWFuPigoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuYWxsT3B0aW9ucygpLmxlbmd0aCA+IHRoaXMuTUFYX1JFTkRFUkVEX09QVElPTlM7XG4gIH0pO1xuICByZWFkb25seSBleGNlc3NPcHRpb25zQ291bnQgPSBjb21wdXRlZDxudW1iZXI+KCgpID0+IHtcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgdGhpcy5hbGxPcHRpb25zKCkubGVuZ3RoIC0gdGhpcy5NQVhfUkVOREVSRURfT1BUSU9OUyk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHdhaXRpbmdMYWJlbCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBrZXlzID0gdGhpcy53YWl0aW5nRm9yKCk7XG4gICAgaWYgKGtleXMubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIGtleXMuam9pbignLCAnKTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgc3RhdHVzS2luZCA9IGNvbXB1dGVkPCdpZGxlJyB8ICdsb2FkaW5nJyB8ICdvaycgfCAnd2FpdGluZycgfCAnZXJyb3InIHwgJ2VtcHR5Jz4oKCkgPT4ge1xuICAgIGlmICghdGhpcy5pc0R5bmFtaWNTb3VyY2UoKSkgcmV0dXJuICdpZGxlJztcbiAgICBpZiAodGhpcy5pc0xvYWRpbmcoKSkgcmV0dXJuICdsb2FkaW5nJztcbiAgICBpZiAodGhpcy5sb2FkRXJyb3IoKSkgcmV0dXJuICdlcnJvcic7XG4gICAgaWYgKHRoaXMud2FpdGluZ0ZvcigpLmxlbmd0aCA+IDApIHJldHVybiAnd2FpdGluZyc7XG4gICAgaWYgKHRoaXMuaGFzTG9hZGVkKCkpIHJldHVybiB0aGlzLmR5bmFtaWNPcHRpb25zKCkubGVuZ3RoID4gMCA/ICdvaycgOiAnZW1wdHknO1xuICAgIHJldHVybiAnaWRsZSc7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHN0YXR1c1RleHQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgc3dpdGNoICh0aGlzLnN0YXR1c0tpbmQoKSkge1xuICAgICAgY2FzZSAnbG9hZGluZyc6XG4gICAgICAgIHJldHVybiAnTG9hZGluZyBmcm9tIGRhdGFiYXNl4oCmJztcbiAgICAgIGNhc2UgJ29rJzpcbiAgICAgICAgcmV0dXJuIGAke3RoaXMuZHluYW1pY09wdGlvbnMoKS5sZW5ndGh9IHJlY29yZHMgbG9hZGVkYDtcbiAgICAgIGNhc2UgJ3dhaXRpbmcnOlxuICAgICAgICByZXR1cm4gYFdhaXRpbmcgZm9yOiAke3RoaXMud2FpdGluZ0xhYmVsKCl9YDtcbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgcmV0dXJuIHRoaXMubG9hZEVycm9yKCkgPz8gJ0ZhaWxlZCB0byBsb2FkJztcbiAgICAgIGNhc2UgJ2VtcHR5JzpcbiAgICAgICAgcmV0dXJuICdRdWVyeSByZXR1cm5lZCBubyByZWNvcmRzIGZvciB0aGVzZSBwYXJhbWV0ZXJzJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH0pO1xuXG4gIHJlYWRvbmx5IGlzSW52YWxpZCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBjdHJsID0gdGhpcy5mb3JtQ29udHJvbCgpO1xuICAgIHJldHVybiBjdHJsLmludmFsaWQgJiYgKGN0cmwuZGlydHkgfHwgY3RybC50b3VjaGVkKTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgZXJyb3JNZXNzYWdlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGN0cmwgPSB0aGlzLmZvcm1Db250cm9sKCk7XG4gICAgaWYgKCFjdHJsLmludmFsaWQgfHwgKCFjdHJsLmRpcnR5ICYmICFjdHJsLnRvdWNoZWQpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIGNvbnN0IGVycm9ycyA9IGN0cmwuZXJyb3JzO1xuICAgIGlmICghZXJyb3JzKSByZXR1cm4gJyc7XG4gICAgY29uc3QgZmlyc3RLZXkgPSBPYmplY3Qua2V5cyhlcnJvcnMpWzBdO1xuICAgIHJldHVybiBnZXRWYWxpZGF0aW9uTWVzc2FnZSh0aGlzLmNvbmZpZygpLnZhbGlkYXRpb24sIGZpcnN0S2V5KTtcbiAgfSk7XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICBvbkRvY3VtZW50Q2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNPcGVuKCkpIHJldHVybjtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgTm9kZTtcbiAgICBpZiAoIXRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKHRhcmdldCkpIHtcbiAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmtleWRvd24uZXNjYXBlJylcbiAgb25Fc2NhcGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgIH1cbiAgfVxuXG4gIGlzU2VsZWN0ZWQob3B0OiBEcm9wZG93bk9wdGlvbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGN1ciA9IHRoaXMuY3VycmVudFZhbHVlKCk7XG4gICAgaWYgKGN1ciA9PT0gbnVsbCB8fCBjdXIgPT09IHVuZGVmaW5lZCB8fCBjdXIgPT09ICcnKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIFN0cmluZyhjdXIpID09PSBTdHJpbmcob3B0LmtleSk7XG4gIH1cblxuICB0b2dnbGVPcGVuKGV2ZW50PzogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgICBpZiAodGhpcy5mb3JtQ29udHJvbCgpLmRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9wZW5Ecm9wZG93bigpO1xuICAgIH1cbiAgfVxuXG4gIG9wZW5Ecm9wZG93bigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5mb3JtQ29udHJvbCgpLmRpc2FibGVkKSByZXR1cm47XG5cbiAgICAvLyBDaGVjayBhdmFpbGFibGUgdmlld3BvcnQgc3BhY2UgdG8gZGV0ZXJtaW5lIGlmIG1lbnUgc2hvdWxkIG9wZW4gYWJvdmVcbiAgICBjb25zdCB3cmFwcGVyID0gdGhpcy5jb21ib2JveFdyYXBwZXJFbCgpPy5uYXRpdmVFbGVtZW50ID8/IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHJlY3QgPSB3cmFwcGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHNwYWNlQmVsb3cgPSB3aW5kb3cuaW5uZXJIZWlnaHQgLSByZWN0LmJvdHRvbTtcbiAgICBjb25zdCBzcGFjZUFib3ZlID0gcmVjdC50b3A7XG5cbiAgICBjb25zdCBwcmVmZXJBYm92ZSA9IHRoaXMuY29uZmlnKCk/LnByb3BlcnRpZXM/Llsnb3BlbkFib3ZlJ10gPT09IHRydWU7XG4gICAgY29uc3QgYXV0b0Fib3ZlID0gc3BhY2VCZWxvdyA8IDI2MCAmJiBzcGFjZUFib3ZlID4gMTYwO1xuICAgIHRoaXMub3BlbnNBYm92ZS5zZXQocHJlZmVyQWJvdmUgfHwgYXV0b0Fib3ZlKTtcblxuICAgIHRoaXMuaXNPcGVuLnNldCh0cnVlKTtcbiAgICB0aGlzLnNlYXJjaFRlcm0uc2V0KCcnKTtcbiAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQoLTEpO1xuXG4gICAgLy8gQXV0by1mb2N1cyBzZWFyY2ggaW5wdXQgYWZ0ZXIgcmVuZGVyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnNlYXJjaElucHV0RWwoKT8ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgIH0sIDEwKTtcbiAgfVxuXG4gIGNsb3NlRHJvcGRvd24oKTogdm9pZCB7XG4gICAgdGhpcy5pc09wZW4uc2V0KGZhbHNlKTtcbiAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQoLTEpO1xuICAgIHRoaXMuZm9ybUNvbnRyb2woKS5tYXJrQXNUb3VjaGVkKCk7XG4gIH1cblxuICBzZWxlY3RPcHRpb24ob3B0OiBEcm9wZG93bk9wdGlvbik6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudFZhbHVlLnNldChvcHQua2V5KTtcbiAgICB0aGlzLmZvcm1Db250cm9sKCkuc2V0VmFsdWUob3B0LmtleSk7XG4gICAgdGhpcy5mb3JtQ29udHJvbCgpLm1hcmtBc0RpcnR5KCk7XG4gICAgdGhpcy5mb3JtQ29udHJvbCgpLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLmNsb3NlRHJvcGRvd24oKTtcbiAgfVxuXG4gIGNsZWFyU2VsZWN0aW9uKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5jdXJyZW50VmFsdWUuc2V0KCcnKTtcbiAgICB0aGlzLmZvcm1Db250cm9sKCkuc2V0VmFsdWUoJycpO1xuICAgIHRoaXMuZm9ybUNvbnRyb2woKS5tYXJrQXNEaXJ0eSgpO1xuICAgIHRoaXMuZm9ybUNvbnRyb2woKS5tYXJrQXNUb3VjaGVkKCk7XG4gICAgdGhpcy5zZWFyY2hUZXJtLnNldCgnJyk7XG4gICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KC0xKTtcbiAgfVxuXG4gIC8qKiBNYW51YWxseSByZXRyeSBsb2FkaW5nIGR5bmFtaWMgbG9va3VwIG9wdGlvbnMgKGUuZy4gYWZ0ZXIgZGF0YWJhc2UgdGltZW91dCkuICovXG4gIHJldHJ5TG9va3VwKGV2ZW50PzogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgdGhpcy5sYXN0UmVxdWVzdEtleSA9ICcnO1xuICAgIHRoaXMubG9hZEVycm9yLnNldChudWxsKTtcbiAgICB0aGlzLnJlbG9hZERhdGFTb3VyY2VPcHRpb25zKHRoaXMuc2Vzc2lvblNlcnZpY2U/LnNlc3Npb25Db250ZXh0KCkgPz8ge30pO1xuICB9XG5cbiAgY2xlYXJTZWFyY2goZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5zZWFyY2hUZXJtLnNldCgnJyk7XG4gICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KC0xKTtcbiAgICB0aGlzLnNlYXJjaElucHV0RWwoKT8ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICB9XG5cbiAgb25TZWFyY2hJbnB1dChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB2YWwgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLnZhbHVlO1xuICAgIHRoaXMuc2VhcmNoVGVybS5zZXQodmFsKTtcbiAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQoMCk7XG4gIH1cblxuICBvblRyaWdnZXJLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0Fycm93RG93bicgfHwgZXZlbnQua2V5ID09PSAnRW50ZXInIHx8IGV2ZW50LmtleSA9PT0gJyAnKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy5vcGVuRHJvcGRvd24oKTtcbiAgICB9XG4gIH1cblxuICBvblNlYXJjaEtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB2aXNpYmxlID0gdGhpcy52aXNpYmxlRmlsdGVyZWRPcHRpb25zKCk7XG4gICAgY29uc3QgY291bnQgPSB2aXNpYmxlLmxlbmd0aDtcblxuICAgIHN3aXRjaCAoZXZlbnQua2V5KSB7XG4gICAgICBjYXNlICdBcnJvd0Rvd24nOiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGlmIChjb3VudCA+IDApIHtcbiAgICAgICAgICBjb25zdCBuZXh0ID0gKHRoaXMuZm9jdXNlZEluZGV4KCkgKyAxKSAlIGNvdW50O1xuICAgICAgICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldChuZXh0KTtcbiAgICAgICAgICB0aGlzLnNjcm9sbEZvY3VzZWRJbnRvVmlldygpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnQXJyb3dVcCc6IHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKGNvdW50ID4gMCkge1xuICAgICAgICAgIGNvbnN0IHByZXYgPSB0aGlzLmZvY3VzZWRJbmRleCgpIDw9IDAgPyBjb3VudCAtIDEgOiB0aGlzLmZvY3VzZWRJbmRleCgpIC0gMTtcbiAgICAgICAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQocHJldik7XG4gICAgICAgICAgdGhpcy5zY3JvbGxGb2N1c2VkSW50b1ZpZXcoKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ0VudGVyJzoge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCBpZHggPSB0aGlzLmZvY3VzZWRJbmRleCgpO1xuICAgICAgICBpZiAoaWR4ID49IDAgJiYgaWR4IDwgY291bnQpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdE9wdGlvbih2aXNpYmxlW2lkeF0pO1xuICAgICAgICB9IGVsc2UgaWYgKGNvdW50ID09PSAxKSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RPcHRpb24odmlzaWJsZVswXSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdFc2NhcGUnOiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ1RhYic6IHtcbiAgICAgICAgdGhpcy5jbG9zZURyb3Bkb3duKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2Nyb2xsRm9jdXNlZEludG9WaWV3KCk6IHZvaWQge1xuICAgIGNvbnN0IGxpc3RFbCA9IHRoaXMub3B0aW9uc0xpc3RFbCgpPy5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghbGlzdEVsKSByZXR1cm47XG4gICAgY29uc3QgaXRlbXMgPSBsaXN0RWwucXVlcnlTZWxlY3RvckFsbDxIVE1MRWxlbWVudD4oJy5jb21ib2JveC1vcHRpb24taXRlbScpO1xuICAgIGNvbnN0IGlkeCA9IHRoaXMuZm9jdXNlZEluZGV4KCk7XG4gICAgaWYgKGl0ZW1zICYmIGl0ZW1zW2lkeF0pIHtcbiAgICAgIGl0ZW1zW2lkeF0uc2Nyb2xsSW50b1ZpZXcoeyBibG9jazogJ25lYXJlc3QnIH0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIFN5bmMgcmVhY3RpdmUgZm9ybSBjb250cm9sIHZhbHVlIGNoYW5nZXMgdG8gY3VycmVudFZhbHVlIHNpZ25hbFxuICAgIGVmZmVjdChcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3QgY3RybCA9IHRoaXMuZm9ybUNvbnRyb2woKTtcbiAgICAgICAgdW50cmFja2VkKCgpID0+IHRoaXMuY3VycmVudFZhbHVlLnNldChjdHJsLnZhbHVlKSk7XG4gICAgICAgIHRoaXMuY29udHJvbFN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5jb250cm9sU3ViID0gY3RybC52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCh2KSA9PiB0aGlzLmN1cnJlbnRWYWx1ZS5zZXQodikpO1xuICAgICAgfSxcbiAgICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfVxuICAgICk7XG5cbiAgICAvLyBSZS1ydW4gd2hlbmV2ZXIgdGhlIGJvdW5kIGRhdGEgc291cmNlLCB0aGUgc2Vzc2lvbiwgb3IgdGhlIHBhcmVudCBmb3JtIGNoYW5nZXMuXG4gICAgZWZmZWN0KFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5zZXNzaW9uU2VydmljZT8uc2Vzc2lvbkNvbnRleHQoKSA/PyB7fTtcbiAgICAgICAgY29uc3QgZm9ybSA9IHRoaXMucGFyZW50Rm9ybSgpO1xuICAgICAgICB0aGlzLmNvbmZpZygpOyAvLyBkZXBlbmRlbmN5OiBkYXRhIHNvdXJjZSBjb25maWd1cmF0aW9uXG5cbiAgICAgICAgdGhpcy5mb3JtQ2hhbmdlc1N1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgaWYgKGZvcm0gJiYgdGhpcy5pc0R5bmFtaWNTb3VyY2UoKSkge1xuICAgICAgICAgIHRoaXMuZm9ybUNoYW5nZXNTdWIgPSBmb3JtLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4gdGhpcy5zY2hlZHVsZVJlbG9hZCgpKTtcbiAgICAgICAgfVxuICAgICAgICB1bnRyYWNrZWQoKCkgPT4gdGhpcy5zY2hlZHVsZVJlbG9hZCgpKTtcbiAgICAgIH0sXG4gICAgICB7IGFsbG93U2lnbmFsV3JpdGVzOiB0cnVlIH1cbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9sU3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMubG9va3VwU3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMubWFzdGVyRGF0YVN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmZvcm1DaGFuZ2VzU3ViPy51bnN1YnNjcmliZSgpO1xuICAgIGlmICh0aGlzLnJlbG9hZFRpbWVyKSBjbGVhclRpbWVvdXQodGhpcy5yZWxvYWRUaW1lcik7XG4gIH1cblxuICBwcml2YXRlIHNjaGVkdWxlUmVsb2FkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnJlbG9hZFRpbWVyKSBjbGVhclRpbWVvdXQodGhpcy5yZWxvYWRUaW1lcik7XG4gICAgdGhpcy5yZWxvYWRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5yZWxvYWREYXRhU291cmNlT3B0aW9ucyh0aGlzLnNlc3Npb25TZXJ2aWNlPy5zZXNzaW9uQ29udGV4dCgpID8/IHt9KTtcbiAgICB9LCAyNTApO1xuICB9XG5cbiAgcHJpdmF0ZSByZWxvYWREYXRhU291cmNlT3B0aW9ucyhzZXNzaW9uOiBTZXNzaW9uQ29udGV4dE1hcCk6IHZvaWQge1xuICAgIGNvbnN0IGRzID0gdGhpcy5jb25maWcoKS5kYXRhU291cmNlO1xuICAgIGlmICghZHMgfHwgIXRoaXMuaXNEeW5hbWljU291cmNlKCkpIHJldHVybjtcblxuICAgIC8vIDEuIERhdGFiYXNlIFRhYmxlIC8gU3RvcmVkIFByb2NlZHVyZSBMb29rdXBcbiAgICBpZiAoZHMuZW50aXR5TmFtZSAmJiAoZHMuc291cmNlVHlwZSA9PT0gJ3RhYmxlJyB8fCBkcy5zb3VyY2VUeXBlID09PSAncHJvY2VkdXJlJykgJiYgdGhpcy5sb29rdXBBZGFwdGVyKSB7XG4gICAgICBjb25zdCBmb3JtVmFsdWVzID0gdGhpcy5wYXJlbnRGb3JtKCk/LmdldFJhd1ZhbHVlKCkgPz8ge307XG5cbiAgICAgIC8vIERvIG5vdCBjYWxsIHRoZSBkYXRhYmFzZSB1bnRpbCBldmVyeSBjYW52YXMgZmllbGQgdGhpcyBsb29rdXAgZGVwZW5kcyBvbiBpcyBmaWxsZWQuXG4gICAgICBjb25zdCBtaXNzaW5nID0gZmluZE1pc3NpbmdDYW52YXNGaWVsZHMoZHMucGFyYW1ldGVyTWFwcGluZ3MsIGZvcm1WYWx1ZXMpO1xuICAgICAgdGhpcy53YWl0aW5nRm9yLnNldChtaXNzaW5nKTtcbiAgICAgIGlmIChtaXNzaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5sb29rdXBTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMuaXNMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgIHRoaXMubG9hZEVycm9yLnNldChudWxsKTtcbiAgICAgICAgdGhpcy5keW5hbWljT3B0aW9ucy5zZXQoW10pO1xuICAgICAgICB0aGlzLmxhc3RSZXF1ZXN0S2V5ID0gJyc7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gU3RvcmVkIHByb2NlZHVyZXMgb25seSByZWNlaXZlIGV4cGxpY2l0IG1hcHBpbmdzIHNvIFNRTCBTZXJ2ZXIgZG9lc24ndCByZWplY3QgdW5rbm93biBhcmd1bWVudHMuXG4gICAgICBjb25zdCByZXNvbHZlZFBhcmFtczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7XG4gICAgICAgIC4uLihkcy5zb3VyY2VUeXBlID09PSAndGFibGUnID8gc2Vzc2lvbiA6IHt9KSxcbiAgICAgICAgLi4ucmVzb2x2ZVBhcmFtZXRlck1hcHBpbmdzKGRzLnBhcmFtZXRlck1hcHBpbmdzLCBzZXNzaW9uLCBmb3JtVmFsdWVzKSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgICAgIHNvdXJjZVR5cGU6IGRzLnNvdXJjZVR5cGUgPz8gJ3RhYmxlJyxcbiAgICAgICAgZW50aXR5TmFtZTogZHMuZW50aXR5TmFtZSxcbiAgICAgICAgc2NoZW1hOiBkcy5zY2hlbWEgPz8gJ2RibycsXG4gICAgICAgIHZhbHVlRmllbGQ6IGRzLnZhbHVlRmllbGQgfHwgJ2lkJyxcbiAgICAgICAgZGlzcGxheUZpZWxkOiBkcy5kaXNwbGF5RmllbGQgfHwgJ25hbWUnLFxuICAgICAgICBmaWx0ZXI6IGRzLmZpbHRlcixcbiAgICAgICAgcGFyYW1ldGVyczogcmVzb2x2ZWRQYXJhbXMsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVxdWVzdEtleSA9IEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpO1xuICAgICAgaWYgKHJlcXVlc3RLZXkgPT09IHRoaXMubGFzdFJlcXVlc3RLZXkpIHJldHVybjsgLy8gbm90aGluZyBjaGFuZ2VkXG4gICAgICB0aGlzLmxhc3RSZXF1ZXN0S2V5ID0gcmVxdWVzdEtleTtcblxuICAgICAgLy8gU3RvcmVkIHByb2NlZHVyZXMgb24gbG9jYWwgZGF0YWJhc2VzIGNhbiB0YWtlIGEgY291cGxlIG1pbnV0ZXMgdG8gZXhlY3V0ZS5cbiAgICAgIC8vIERlZmF1bHQgdGltZW91dCBpcyAzMDAsMDAwbXMgKDUgbWludXRlcyksIGNvbmZpZ3VyYWJsZSB2aWEgY29tcG9uZW50IHByb3BlcnRpZXMgb3IgcmVwb3J0aW5nQ29uZmlnLlxuICAgICAgY29uc3QgdGltZW91dE1zID1cbiAgICAgICAgKChkcyBhcyBhbnkpPy50aW1lb3V0TXMgYXMgbnVtYmVyKSB8fFxuICAgICAgICAodGhpcy5jb25maWcoKS5wcm9wZXJ0aWVzPy5bJ3RpbWVvdXRNcyddIGFzIG51bWJlcikgfHxcbiAgICAgICAgdGhpcy5yZXBvcnRpbmdDb25maWc/Lmxvb2t1cFRpbWVvdXRNcyB8fFxuICAgICAgICAzMDAwMDA7XG5cbiAgICAgIHRoaXMuaXNMb2FkaW5nLnNldCh0cnVlKTtcbiAgICAgIHRoaXMubG9hZEVycm9yLnNldChudWxsKTtcbiAgICAgIHRoaXMubG9va3VwU3ViPy51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy5sb29rdXBTdWIgPSB0aGlzLmxvb2t1cEFkYXB0ZXJcbiAgICAgICAgLmZldGNoT3B0aW9ucyhyZXF1ZXN0KVxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0aW1lb3V0KHtcbiAgICAgICAgICAgIGVhY2g6IHRpbWVvdXRNcyxcbiAgICAgICAgICAgIHdpdGg6ICgpID0+XG4gICAgICAgICAgICAgIHRocm93RXJyb3IoXG4gICAgICAgICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYExvb2t1cCBxdWVyeSB0aW1lZCBvdXQgYWZ0ZXIgJHtNYXRoLnJvdW5kKHRpbWVvdXRNcyAvIDEwMDApfXMgKHN0b3JlZCBwcm9jZWR1cmUgdG9vayB0b28gbG9uZyB0byByZXNwb25kIG9uIGxvY2FsIGRhdGFiYXNlKWBcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoaXRlbXMpID0+IHtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuaGFzTG9hZGVkLnNldCh0cnVlKTtcbiAgICAgICAgICAvLyBEZWR1cGxpY2F0ZSBpdGVtcyBieSBrZXkvdmFsdWUgdG8gZW5zdXJlIGNsZWFuIHNlbGVjdCBvcHRpb25zXG4gICAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgICAgIGNvbnN0IGRlZHVwZWQ6IERyb3Bkb3duT3B0aW9uW10gPSBbXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGl0IG9mIGl0ZW1zKSB7XG4gICAgICAgICAgICBjb25zdCBrID0gU3RyaW5nKGl0LnZhbHVlKTtcbiAgICAgICAgICAgIGlmICghc2Vlbi5oYXMoaykpIHtcbiAgICAgICAgICAgICAgc2Vlbi5hZGQoayk7XG4gICAgICAgICAgICAgIGRlZHVwZWQucHVzaCh7IGtleTogaywgbGFiZWw6IGl0LmxhYmVsIHx8IGsgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuZHluYW1pY09wdGlvbnMuc2V0KGRlZHVwZWQpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtScHREcm9wZG93bl0gRmFpbGVkIHRvIGxvYWQgbG9va3VwIG9wdGlvbnMgZm9yICR7ZHMuZW50aXR5TmFtZX06YCwgZXJyKTtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuaGFzTG9hZGVkLnNldCh0cnVlKTtcbiAgICAgICAgICB0aGlzLmR5bmFtaWNPcHRpb25zLnNldChbXSk7XG4gICAgICAgICAgdGhpcy5sYXN0UmVxdWVzdEtleSA9ICcnOyAvLyBhbGxvdyByZXRyeVxuICAgICAgICAgIHRoaXMubG9hZEVycm9yLnNldChlcnI/Lm1lc3NhZ2UgfHwgJ0RhdGFiYXNlIHF1ZXJ5IGVycm9yJyk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyAyLiBMZWdhY3kgTWFzdGVyIERhdGEgUHJvdmlkZXJcbiAgICBpZiAoZHMubWFzdGVyTmFtZSAmJiB0aGlzLm1hc3RlckRhdGFQcm92aWRlciAmJiAhdGhpcy5tYXN0ZXJEYXRhU3ViKSB7XG4gICAgICB0aGlzLmlzTG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgICB0aGlzLmxvYWRFcnJvci5zZXQobnVsbCk7XG4gICAgICB0aGlzLm1hc3RlckRhdGFTdWIgPSB0aGlzLm1hc3RlckRhdGFQcm92aWRlci5nZXRNYXN0ZXJEYXRhKGRzLm1hc3Rlck5hbWUpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChpdGVtcykgPT4ge1xuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgICAgdGhpcy5oYXNMb2FkZWQuc2V0KHRydWUpO1xuICAgICAgICAgIHRoaXMuZHluYW1pY09wdGlvbnMuc2V0KFxuICAgICAgICAgICAgaXRlbXMubWFwKChpdCkgPT4gKHtcbiAgICAgICAgICAgICAga2V5OiBTdHJpbmcoaXQudmFsdWUgPz8gaXRbJ2lkJ10gPz8gJycpLFxuICAgICAgICAgICAgICBsYWJlbDogU3RyaW5nKGl0LmxhYmVsID8/IGl0WyduYW1lJ10gPz8gJycpLFxuICAgICAgICAgICAgfSkpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGBbUnB0RHJvcGRvd25dIEZhaWxlZCB0byBsb2FkIG1hc3RlciBkYXRhIGZvciAke2RzLm1hc3Rlck5hbWV9OmAsIGVycik7XG4gICAgICAgICAgdGhpcy5pc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICB0aGlzLmhhc0xvYWRlZC5zZXQodHJ1ZSk7XG4gICAgICAgICAgdGhpcy5sb2FkRXJyb3Iuc2V0KGVycj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIGxvYWQgbWFzdGVyIGRhdGEnKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIiwiICAgIDxkaXYgY2xhc3M9XCJycHQtZmllbGQtZ3JvdXBcIj5cbiAgICAgIEBpZiAoY29uZmlnKCkubGFiZWwpIHtcbiAgICAgICAgPGxhYmVsIFtmb3JdPVwiZWxlbWVudElkKClcIiBjbGFzcz1cInJwdC1sYWJlbFwiPlxuICAgICAgICAgIHt7IGNvbmZpZygpLmxhYmVsIH19XG4gICAgICAgICAgQGlmIChjb25maWcoKS52YWxpZGF0aW9uPy5yZXF1aXJlZCkge1xuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJycHQtcmVxdWlyZWQtbWFya2VyXCI+Kjwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICB9XG5cbiAgICAgIEBpZiAoaXNTZWFyY2hhYmxlKCkpIHtcbiAgICAgICAgPCEtLSBTZWFyY2hhYmxlIFR5cGVhaGVhZCBDb21ib2JveCAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJwdC1jb21ib2JveC13cmFwcGVyXCIgI2NvbWJvYm94V3JhcHBlcj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwicnB0LWNvbWJvYm94LXRyaWdnZXJcIlxuICAgICAgICAgICAgW2lkXT1cImVsZW1lbnRJZCgpXCJcbiAgICAgICAgICAgIFtjbGFzcy5ycHQtaW52YWxpZF09XCJpc0ludmFsaWQoKVwiXG4gICAgICAgICAgICBbY2xhc3MuaXMtb3Blbl09XCJpc09wZW4oKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiZm9ybUNvbnRyb2woKS5kaXNhYmxlZFwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cImlzT3BlbigpXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtaGFzcG9wdXBdPVwiJ2xpc3Rib3gnXCJcbiAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVPcGVuKCRldmVudClcIlxuICAgICAgICAgICAgKGtleWRvd24pPVwib25UcmlnZ2VyS2V5ZG93bigkZXZlbnQpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRyaWdnZXItbGFiZWxcIiBbY2xhc3MuaXMtcGxhY2Vob2xkZXJdPVwiIXNlbGVjdGVkT3B0aW9uKClcIj5cbiAgICAgICAgICAgICAge3sgc2VsZWN0ZWRPcHRpb24oKSA/IHNlbGVjdGVkT3B0aW9uKCkhLmxhYmVsIDogcGxhY2Vob2xkZXIoKSB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHJpZ2dlci1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgIEBpZiAoaXNMb2FkaW5nKCkpIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1kb3QgZG90LXB1bHNlXCIgc3R5bGU9XCJjb2xvcjogIzI1NjNlYjsgbWFyZ2luLXJpZ2h0OiA0cHg7XCIgdGl0bGU9XCJFeGVjdXRpbmcgcXVlcnkgb24gZGF0YWJhc2UuLi5cIj48L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgQGlmIChsb2FkRXJyb3IoKSAmJiAhaXNMb2FkaW5nKCkpIHtcbiAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwidHJpZ2dlci1yZXRyeS1idG5cIlxuICAgICAgICAgICAgICAgICAgdGl0bGU9XCJSZXRyeSBkYXRhYmFzZSBxdWVyeVwiXG4gICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiUmV0cnkgZGF0YWJhc2UgcXVlcnlcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJldHJ5TG9va3VwKCRldmVudClcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIOKGuyBSZXRyeVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIEBpZiAoc2VsZWN0ZWRPcHRpb24oKSAmJiAhZm9ybUNvbnRyb2woKS5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInRyaWdnZXItY2xlYXItYnRuXCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQ2xlYXIgc2VsZWN0aW9uXCJcbiAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJDbGVhciBzZWxlY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNsZWFyU2VsZWN0aW9uKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiY2xlYXJTZWxlY3Rpb24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAoa2V5ZG93bi5zcGFjZSk9XCJjbGVhclNlbGVjdGlvbigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICDinJVcbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0cmlnZ2VyLWFycm93XCIgW2NsYXNzLnJvdGF0ZWRdPVwiaXNPcGVuKClcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTJcIiBoZWlnaHQ9XCI4XCIgdmlld0JveD1cIjAgMCAxMiA4XCIgZmlsbD1cIm5vbmVcIj5cbiAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMSAxLjVMNiA2LjVMMTEgMS41XCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIvPlxuICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgIEBpZiAoaXNPcGVuKCkpIHtcbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgY2xhc3M9XCJycHQtY29tYm9ib3gtbWVudVwiXG4gICAgICAgICAgICAgIFtjbGFzcy5vcGVucy1hYm92ZV09XCJvcGVuc0Fib3ZlKClcIlxuICAgICAgICAgICAgICByb2xlPVwibGlzdGJveFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8IS0tIFJlYWwtdGltZSBGaWx0ZXIgU2VhcmNoIEJveCAtLT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LXNlYXJjaC1ib3hcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbWJvYm94LXNlYXJjaC1pY29uXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTNcIiBoZWlnaHQ9XCIxM1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjIuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiPlxuICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PVwiMTFcIiBjeT1cIjExXCIgcj1cIjhcIj48L2NpcmNsZT5cbiAgICAgICAgICAgICAgICAgICAgPGxpbmUgeDE9XCIyMVwiIHkxPVwiMjFcIiB4Mj1cIjE2LjY1XCIgeTI9XCIxNi42NVwiPjwvbGluZT5cbiAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICNzZWFyY2hJbnB1dFxuICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb21ib2JveC1zZWFyY2gtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJUeXBlIHRvIGZpbHRlci4uLlwiXG4gICAgICAgICAgICAgICAgICBbdmFsdWVdPVwic2VhcmNoVGVybSgpXCJcbiAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtYWN0aXZlZGVzY2VuZGFudF09XCJmb2N1c2VkSW5kZXgoKSA+PSAwID8gKGVsZW1lbnRJZCgpICsgJ19vcHRfJyArIGZvY3VzZWRJbmRleCgpKSA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgKGlucHV0KT1cIm9uU2VhcmNoSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAoa2V5ZG93bik9XCJvblNlYXJjaEtleWRvd24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICBAaWYgKHNlYXJjaFRlcm0oKSkge1xuICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb21ib2JveC1zZWFyY2gtY2xlYXJcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkNsZWFyIGZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjbGVhclNlYXJjaCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAg4pyVXG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgIDwhLS0gRmlsdGVyZWQgT3B0aW9ucyBMaXN0IC0tPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tYm9ib3gtb3B0aW9ucy1saXN0XCIgI29wdGlvbnNMaXN0RWw+XG4gICAgICAgICAgICAgICAgQGlmICh3YWl0aW5nRm9yKCkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LXN0YXR1cy1yb3cgd2FpdGluZ1wiPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5XYWl0aW5nIGZvciB7eyB3YWl0aW5nTGFiZWwoKSB9fS4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH0gQGVsc2UgaWYgKGlzTG9hZGluZygpKSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tYm9ib3gtc3RhdHVzLXJvdyBsb2FkaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdCBkb3QtcHVsc2VcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPkV4ZWN1dGluZyBxdWVyeSBvbiBkYXRhYmFzZSAobWF5IHRha2UgMeKAkzIgbWludXRlcyBvbiBsb2NhbCBkYXRhYmFzZSkuLi48L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9IEBlbHNlIGlmIChsb2FkRXJyb3IoKSkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LXN0YXR1cy1yb3cgZXJyb3JcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+RXJyb3I6IHt7IGxvYWRFcnJvcigpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNvbWJvYm94LXJldHJ5LWJ0blwiIChjbGljayk9XCJyZXRyeUxvb2t1cCgkZXZlbnQpXCI+4oa7IFJldHJ5IFF1ZXJ5PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9IEBlbHNlIGlmIChpc0R5bmFtaWNTb3VyY2UoKSAmJiBoYXNMb2FkZWQoKSAmJiBhbGxPcHRpb25zKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tYm9ib3gtc3RhdHVzLXJvdyBlbXB0eVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5ObyByZWNvcmRzIGZvdW5kIChjaGVjayBwYXJhbWV0ZXJzKTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH0gQGVsc2UgaWYgKGZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LXN0YXR1cy1yb3cgZW1wdHlcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+Tm8gb3B0aW9ucyBtYXRjaGluZyBcInt7IHNlYXJjaFRlcm0oKSB9fVwiPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICBAZm9yIChvcHQgb2YgdmlzaWJsZUZpbHRlcmVkT3B0aW9ucygpOyB0cmFjayBvcHQua2V5OyBsZXQgaSA9ICRpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgcm9sZT1cIm9wdGlvblwiXG4gICAgICAgICAgICAgICAgICAgICAgW2lkXT1cImVsZW1lbnRJZCgpICsgJ19vcHRfJyArIGlcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29tYm9ib3gtb3B0aW9uLWl0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1zZWxlY3RlZF09XCJpc1NlbGVjdGVkKG9wdClcIlxuICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1mb2N1c2VkXT1cImZvY3VzZWRJbmRleCgpID09PSBpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLXNlbGVjdGVkXT1cImlzU2VsZWN0ZWQob3B0KVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdE9wdGlvbihvcHQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAobW91c2VlbnRlcik9XCJmb2N1c2VkSW5kZXguc2V0KGkpXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwib3B0LWxhYmVsXCI+e3sgb3B0LmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAoaXNTZWxlY3RlZChvcHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm9wdC1jaGVja1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPuKckzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgQGlmIChleGNlc3NGaWx0ZXJlZENvdW50KCkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21ib2JveC1zdGF0dXMtcm93IGhpbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5TaG93aW5nIHt7IE1BWF9GSUxURVJfUkVOREVSIH19IG9mIHt7IGZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCB9fSBtYXRjaGVzLiBUeXBlIHRvIHJlZmluZS48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgfSBAZWxzZSB7XG4gICAgICAgIDwhLS0gTmF0aXZlIEJyb3dzZXIgU2VsZWN0IEZhbGxiYWNrIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXNlbGVjdC13cmFwcGVyXCI+XG4gICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgW2lkXT1cImVsZW1lbnRJZCgpXCJcbiAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbCgpXCJcbiAgICAgICAgICAgIFtjbGFzcy5ycHQtaW52YWxpZF09XCJpc0ludmFsaWQoKVwiXG4gICAgICAgICAgICBjbGFzcz1cInJwdC1zZWxlY3RcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEBpZiAod2FpdGluZ0ZvcigpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiIGRpc2FibGVkIHNlbGVjdGVkPldhaXRpbmcgZm9yIHt7IHdhaXRpbmdMYWJlbCgpIH19Li4uPC9vcHRpb24+XG4gICAgICAgICAgICB9IEBlbHNlIGlmIChpc0xvYWRpbmcoKSkge1xuICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCIgZGlzYWJsZWQgc2VsZWN0ZWQ+TG9hZGluZyBvcHRpb25zIGZyb20gZGF0YWJhc2UuLi48L29wdGlvbj5cbiAgICAgICAgICAgIH0gQGVsc2UgaWYgKGxvYWRFcnJvcigpKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIiBkaXNhYmxlZCBzZWxlY3RlZD5FcnJvcjoge3sgbG9hZEVycm9yKCkgfX08L29wdGlvbj5cbiAgICAgICAgICAgIH0gQGVsc2UgaWYgKGlzRHluYW1pY1NvdXJjZSgpICYmIGhhc0xvYWRlZCgpICYmIGFsbE9wdGlvbnMoKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiIGRpc2FibGVkIHNlbGVjdGVkPi0tIE5vIHJlY29yZHMgZm91bmQgKGNoZWNrIHBhcmFtZXRlcnMpIC0tPC9vcHRpb24+XG4gICAgICAgICAgICB9IEBlbHNlIGlmIChwbGFjZWhvbGRlcigpKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIiBbZGlzYWJsZWRdPVwiY29uZmlnKCkudmFsaWRhdGlvbj8ucmVxdWlyZWRcIj57eyBwbGFjZWhvbGRlcigpIH19PC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZm9yIChvcHQgb2YgcmVuZGVyZWRPcHRpb25zKCk7IHRyYWNrIG9wdC5rZXkpIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwib3B0LmtleVwiPnt7IG9wdC5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmIChoYXNFeGNlc3NPcHRpb25zKCkpIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiIGRpc2FibGVkPi4uLiBhbmQge3sgZXhjZXNzT3B0aW9uc0NvdW50KCkgfX0gbW9yZSByZWNvcmRzIChyZWZpbmUgZmlsdGVyKSAuLi48L29wdGlvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXNlbGVjdC1hcnJvd1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjEyXCIgaGVpZ2h0PVwiOFwiIHZpZXdCb3g9XCIwIDAgMTIgOFwiIGZpbGw9XCJub25lXCI+XG4gICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMSAxLjVMNiA2LjVMMTEgMS41XCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIvPlxuICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgfVxuXG4gICAgICBAaWYgKHNob3dTdGF0dXMoKSAmJiBpc0R5bmFtaWNTb3VyY2UoKSAmJiBzdGF0dXNUZXh0KCkpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cInJwdC1zdGF0dXMtYmFkZ2VcIiBbYXR0ci5kYXRhLXN0YXR1c109XCJzdGF0dXNLaW5kKClcIj5cbiAgICAgICAgICBAc3dpdGNoIChzdGF0dXNLaW5kKCkpIHtcbiAgICAgICAgICAgIEBjYXNlICgnbG9hZGluZycpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90IGRvdC1wdWxzZVwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4+TG9hZGluZyBmcm9tIGRhdGFiYXNl4oCmPC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCdvaycpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90IGRvdC1va1wiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4+e3sgZHluYW1pY09wdGlvbnMoKS5sZW5ndGggfX0gcmVjb3JkcyBsb2FkZWQ8L3NwYW4+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAY2FzZSAoJ3dhaXRpbmcnKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdCBkb3Qtd2FyblwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4+V2FpdGluZyBmb3I6PC9zcGFuPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwid2FpdGluZy10b2tlbnNcIj5cbiAgICAgICAgICAgICAgICBAZm9yIChrIG9mIHdhaXRpbmdGb3IoKTsgdHJhY2sgaykge1xuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ3YWl0aW5nLXRva2VuXCI+e3sgayB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCdlcnJvcicpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90IGRvdC1lcnJcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuPnt7IGxvYWRFcnJvcigpIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInJwdC1iYWRnZS1yZXRyeS1idG5cIiAoY2xpY2spPVwicmV0cnlMb29rdXAoJGV2ZW50KVwiPuKGuyBSZXRyeTwvYnV0dG9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCdlbXB0eScpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90XCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8c3Bhbj5ObyByZWNvcmRzIGZvdW5kIGZvciBwYXJhbWV0ZXJzPC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGRlZmF1bHQge1xuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1kb3RcIj48L3NwYW4+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cblxuICAgICAgQGlmIChlcnJvck1lc3NhZ2UoKSkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cInJwdC1lcnJvci10ZXh0XCI+e3sgZXJyb3JNZXNzYWdlKCkgfX08L3NwYW4+XG4gICAgICB9XG4gICAgPC9kaXY+Il19
|