@firestitch/report 18.0.11 → 18.0.12
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/app/reports/dialogs/entity-functions/entity-functions.component.d.ts +22 -0
- package/app/reports/dialogs/global-settings/components/semantic-database/semantic-database.component.d.ts +6 -21
- package/app/reports/dialogs/global-settings/global-settings.component.d.ts +3 -3
- package/app/reports/dialogs/instruction-history/instruction-history.component.d.ts +16 -0
- package/app/reports/interfaces/report.interface.d.ts +6 -1
- package/esm2022/app/reports/dialogs/entity-functions/entity-functions.component.mjs +81 -0
- package/esm2022/app/reports/dialogs/global-settings/components/semantic-database/semantic-database.component.mjs +23 -71
- package/esm2022/app/reports/dialogs/global-settings/global-settings.component.mjs +31 -22
- package/esm2022/app/reports/dialogs/instruction-history/instruction-history.component.mjs +60 -0
- package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
- package/fesm2022/{firestitch-report-echarts-DaBOoR9Z.mjs → firestitch-report-echarts-1VNsyco5.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-DaBOoR9Z.mjs.map → firestitch-report-echarts-1VNsyco5.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-Cwsww3Jz.mjs → firestitch-report-firestitch-report-BNHGwPj2.mjs} +163 -115
- package/fesm2022/firestitch-report-firestitch-report-BNHGwPj2.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +1 -1
- package/app/reports/dialogs/global-settings/components/history/history.component.d.ts +0 -8
- package/esm2022/app/reports/dialogs/global-settings/components/history/history.component.mjs +0 -32
- package/fesm2022/firestitch-report-firestitch-report-Cwsww3Jz.mjs.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, signal } from '@angular/core';
|
|
2
2
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
3
|
+
import { MatDialog } from '@angular/material/dialog';
|
|
3
4
|
import { MatExpansionModule } from '@angular/material/expansion';
|
|
4
5
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
5
6
|
import { StreamEventType } from '@firestitch/api';
|
|
@@ -11,6 +12,7 @@ import { FsPrompt } from '@firestitch/prompt';
|
|
|
11
12
|
import { FsSkeletonModule } from '@firestitch/skeleton';
|
|
12
13
|
import { filter, map, switchMap, take, tap } from 'rxjs/operators';
|
|
13
14
|
import { ReportData } from '../../../../data/report.data';
|
|
15
|
+
import { EntityFunctionsComponent } from '../../../entity-functions/entity-functions.component';
|
|
14
16
|
import * as i0 from "@angular/core";
|
|
15
17
|
import * as i1 from "@angular/material/expansion";
|
|
16
18
|
import * as i2 from "@angular/material/tooltip";
|
|
@@ -18,13 +20,13 @@ import * as i3 from "@firestitch/chip";
|
|
|
18
20
|
import * as i4 from "@firestitch/date";
|
|
19
21
|
import * as i5 from "@firestitch/message";
|
|
20
22
|
import * as i6 from "@firestitch/skeleton";
|
|
21
|
-
// The Semantic Database tab: the
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
// entity to reveal its shape, inlined
|
|
25
|
-
//
|
|
26
|
-
// functions
|
|
27
|
-
//
|
|
23
|
+
// The Semantic Database tab: the entity scoreboard the report AI is built from
|
|
24
|
+
// (an entity = a table + a model + a handler). Shows the last build's status,
|
|
25
|
+
// runs (or stops) a build — streamed into the FsProcess dock so it survives the
|
|
26
|
+
// dialog closing — and drills into every entity to reveal its shape, inlined
|
|
27
|
+
// enum values, computed fields and its cached function counts, whose links open
|
|
28
|
+
// the functions dialog (the full function set across all entities is far too
|
|
29
|
+
// big to ship with the scoreboard).
|
|
28
30
|
export class SemanticDatabaseComponent {
|
|
29
31
|
// The build-in-flight states of the ff_processes row (queued/running/stopping).
|
|
30
32
|
static ACTIVE_STATES = ['Q', 'R', 'X'];
|
|
@@ -41,17 +43,6 @@ export class SemanticDatabaseComponent {
|
|
|
41
43
|
// failure.
|
|
42
44
|
static DONE_COLOR = '#2e7d32';
|
|
43
45
|
static PENDING_COLOR = '#9e9e9e';
|
|
44
|
-
// One color per AI classification kind, so a function's nature reads at a glance.
|
|
45
|
-
static KIND_COLORS = {
|
|
46
|
-
'calculation': '#1565c0',
|
|
47
|
-
'business-rule': '#6a1b9a',
|
|
48
|
-
'query': '#00695c',
|
|
49
|
-
'mutation': '#e65100',
|
|
50
|
-
'accessor': '#546e7a',
|
|
51
|
-
'other': '#757575',
|
|
52
|
-
};
|
|
53
|
-
// Interesting logic first: derived values and rules, then data access, then the rest.
|
|
54
|
-
static KIND_ORDER = ['calculation', 'business-rule', 'query', 'mutation', 'accessor', 'other'];
|
|
55
46
|
// The scoreboard's per-entity stage chips, left to right.
|
|
56
47
|
stageKeys = ['introspected', 'enumsInlined', 'computed', 'functions'];
|
|
57
48
|
stageLabels = {
|
|
@@ -67,12 +58,10 @@ export class SemanticDatabaseComponent {
|
|
|
67
58
|
buildActive = computed(() => this.building()
|
|
68
59
|
|| SemanticDatabaseComponent.ACTIVE_STATES.includes(this.status()?.build?.state));
|
|
69
60
|
buildStateLabel = computed(() => SemanticDatabaseComponent.STATE_LABELS[this.status()?.build?.state] ?? '');
|
|
70
|
-
// Per-entity function caches, loaded on first expand. undefined = not
|
|
71
|
-
// requested yet, null = request in flight (the skeleton window), object = loaded.
|
|
72
|
-
_entityFunctions = signal({});
|
|
73
61
|
// Guards the outcome message to fire exactly once per run — whether the stream
|
|
74
62
|
// completes (build finished, possibly failed) or errors outright.
|
|
75
63
|
_buildFinalized = false;
|
|
64
|
+
_dialog = inject(MatDialog);
|
|
76
65
|
_reportData = inject(ReportData);
|
|
77
66
|
_process = inject(FsProcess);
|
|
78
67
|
_prompt = inject(FsPrompt);
|
|
@@ -140,9 +129,6 @@ export class SemanticDatabaseComponent {
|
|
|
140
129
|
}
|
|
141
130
|
this._buildFinalized = true;
|
|
142
131
|
this.building.set(false);
|
|
143
|
-
// The build rewrote every entity's function cache — drop the loaded copies
|
|
144
|
-
// so the next expand refetches fresh data.
|
|
145
|
-
this._entityFunctions.set({});
|
|
146
132
|
if (streamError) {
|
|
147
133
|
this._message.error('The semantic database build could not run — check the AI connection and try again.');
|
|
148
134
|
this._refreshStatus();
|
|
@@ -177,37 +163,18 @@ export class SemanticDatabaseComponent {
|
|
|
177
163
|
stageTooltip(stage) {
|
|
178
164
|
return stage === 'done' ? 'Built' : 'Needs building';
|
|
179
165
|
}
|
|
180
|
-
kindColor(kind) {
|
|
181
|
-
return SemanticDatabaseComponent.KIND_COLORS[kind] ?? SemanticDatabaseComponent.KIND_COLORS.other;
|
|
182
|
-
}
|
|
183
166
|
/**
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
* the
|
|
167
|
+
* Open the child dialog listing one group of an entity's cached functions —
|
|
168
|
+
* the model class's or the handler class's. The dialog fetches fresh on open,
|
|
169
|
+
* so the tab never holds function payloads.
|
|
187
170
|
*/
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
*/
|
|
196
|
-
entityOpened(entity) {
|
|
197
|
-
if (this._entityFunctions()[entity.key] !== undefined) {
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
this._entityFunctions.update((loaded) => ({ ...loaded, [entity.key]: null }));
|
|
201
|
-
this._reportData.semanticEntityFunctions(entity.key)
|
|
202
|
-
.pipe(takeUntilDestroyed(this._destroyRef))
|
|
203
|
-
.subscribe((entityFunctions) => {
|
|
204
|
-
this._entityFunctions.update((loaded) => ({
|
|
205
|
-
...loaded,
|
|
206
|
-
[entity.key]: {
|
|
207
|
-
...entityFunctions,
|
|
208
|
-
functions: this._sortFunctions(entityFunctions),
|
|
209
|
-
},
|
|
210
|
-
}));
|
|
171
|
+
openFunctions(entity, source) {
|
|
172
|
+
this._dialog.open(EntityFunctionsComponent, {
|
|
173
|
+
width: '700px',
|
|
174
|
+
maxWidth: '95vw',
|
|
175
|
+
maxHeight: '85vh',
|
|
176
|
+
autoFocus: false,
|
|
177
|
+
data: { entityKey: entity.key, source },
|
|
211
178
|
});
|
|
212
179
|
}
|
|
213
180
|
_init() {
|
|
@@ -218,23 +185,8 @@ export class SemanticDatabaseComponent {
|
|
|
218
185
|
.pipe(takeUntilDestroyed(this._destroyRef))
|
|
219
186
|
.subscribe((status) => this.status.set(status));
|
|
220
187
|
}
|
|
221
|
-
/**
|
|
222
|
-
* Order once at load time (kind priority, then method name) so the template
|
|
223
|
-
* renders the list as-is.
|
|
224
|
-
*/
|
|
225
|
-
_sortFunctions(entityFunctions) {
|
|
226
|
-
return [...entityFunctions.functions]
|
|
227
|
-
.sort((a, b) => {
|
|
228
|
-
const kindDiff = this._kindRank(a.kind) - this._kindRank(b.kind);
|
|
229
|
-
return kindDiff !== 0 ? kindDiff : a.method.localeCompare(b.method);
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
_kindRank(kind) {
|
|
233
|
-
const rank = SemanticDatabaseComponent.KIND_ORDER.indexOf(kind);
|
|
234
|
-
return rank === -1 ? SemanticDatabaseComponent.KIND_ORDER.length : rank;
|
|
235
|
-
}
|
|
236
188
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SemanticDatabaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
237
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SemanticDatabaseComponent, isStandalone: true, selector: "fs-ai-report-global-settings-semantic-database", ngImport: i0, template: "<div class=\"fs-column tab-body\">\n <p class=\"hint\">\n The semantic database is what the report AI uses to understand your data \u2014\n tables, relationships and the calculations in code. Rebuild it after\n significant application updates. The build runs in the background; progress\n appears in the dock at the bottom right and this dialog can be closed while\n it runs.\n </p>\n\n <div *fsSkeleton=\"status()\">\n @if (status(); as buildStatus) {\n <div class=\"build-status\">\n @if (buildStatus.detail.generatedAt) {\n <div class=\"stat\">\n <span class=\"label\">Last built</span>\n <fs-date\n [date]=\"buildStatus.detail.generatedAt\"\n format=\"date-time\">\n </fs-date>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Coverage</span>\n <span>\n {{ buildStatus.detail.entityCount }} entities \u00B7\n {{ buildStatus.detail.functionCount }} code functions\n </span>\n </div>\n } @else {\n <fs-message-warning>\n The semantic database has not been built yet \u2014 the report AI can't\n answer data questions until it is. Run the first build.\n </fs-message-warning>\n }\n @if (buildStatus.build) {\n <div class=\"stat\">\n <span class=\"label\">Last build run</span>\n <span>\n {{ buildStateLabel() }}\n @if (buildStatus.build.message) {\n \u2014 {{ buildStatus.build.message }}\n }\n </span>\n </div>\n }\n </div>\n\n <!-- The model scoreboard: every entity the AI knows about, its\n built-vs-needs-building stages, and a drill-down into its shape, enum\n values, computed fields and AI-classified code functions. -->\n @if (buildStatus.detail.entities?.length) {\n <mat-accordion class=\"entities\">\n @for (entity of buildStatus.detail.entities; track entity.key) {\n <mat-expansion-panel (opened)=\"entityOpened(entity)\">\n <mat-expansion-panel-header>\n <mat-panel-title>{{ entity.key }}</mat-panel-title>\n <mat-panel-description>\n <div class=\"stage-chips\">\n @for (stage of stageKeys; track stage) {\n <fs-chip\n size=\"tiny\"\n [backgroundColor]=\"stageColor(entity.stages[stage])\"\n color=\"#ffffff\"\n [matTooltip]=\"stageTooltip(entity.stages[stage])\">\n {{ stageLabels[stage] }}\n </fs-chip>\n }\n </div>\n </mat-panel-description>\n </mat-expansion-panel-header>\n\n <!-- Deferred: the body (and its functions request) only exists\n once expanded. -->\n <ng-template matExpansionPanelContent>\n <div class=\"entity-detail\">\n <div><strong>Table:</strong> {{ entity.table }}</div>\n <div><strong>Columns:</strong> {{ entity.columns }}</div>\n <div><strong>Relationships:</strong> {{ entity.relationships }}</div>\n @if (entity.enums.length) {\n <div class=\"enum-list\">\n <strong>Enum values:</strong>\n @for (enumColumn of entity.enums; track enumColumn.column) {\n <div class=\"enum-row\">\n <span class=\"enum-column\">{{ enumColumn.column }}</span>\n <span class=\"enum-values\">{{ enumColumn.values.join(', ') }}</span>\n </div>\n }\n </div>\n }\n @if (entity.computedFields.length) {\n <div><strong>Computed fields:</strong> {{ entity.computedFields.join(', ') }}</div>\n }\n\n <div class=\"functions-section\">\n <h3 class=\"functions-heading\">\n Code functions\n @if (entity.functionCount) {\n <span class=\"functions-count\">({{ entity.functionCount }})</span>\n }\n </h3>\n\n <div class=\"functions-body\" *fsSkeleton=\"entityFunctions(entity.key)\">\n @if (entityFunctions(entity.key); as fns) {\n @if (fns.functions.length) {\n @if (fns.generatedAt) {\n <div class=\"hint functions-generated\">\n Discovered from {{ fns.class }} ·\n <fs-date\n [date]=\"fns.generatedAt\"\n format=\"date-time\">\n </fs-date>\n </div>\n }\n <div class=\"functions-list\">\n @for (fn of fns.functions; track fn.method) {\n <div class=\"function-row\">\n <div class=\"function-head\">\n <fs-chip\n size=\"tiny\"\n [backgroundColor]=\"kindColor(fn.kind)\"\n color=\"#ffffff\">\n {{ fn.kind }}\n </fs-chip>\n <code class=\"function-method\">{{ fn.method }}</code>\n </div>\n <div class=\"function-summary\">{{ fn.summary }}</div>\n @if (fn.produces) {\n <div class=\"function-produces hint\">Produces: {{ fn.produces }}</div>\n }\n </div>\n }\n </div>\n } @else {\n <div class=\"hint\">\n No functions cached for this entity yet \u2014 run a build to discover its code.\n </div>\n }\n }\n </div>\n </div>\n </div>\n </ng-template>\n </mat-expansion-panel>\n }\n </mat-accordion>\n }\n }\n </div>\n</div>\n", styles: [".tab-body{padding-top:16px}.hint{margin:0 0 12px;color:#0009;font-size:13px;line-height:1.5}.build-status{display:flex;flex-direction:column;gap:8px}.build-status .stat{display:flex;gap:8px}.build-status .stat .label{min-width:110px;color:#0009}.entities{display:block;padding:3px}.entities .stage-chips{display:flex;flex-wrap:wrap;gap:4px}.entities .entity-detail{display:flex;flex-direction:column;gap:5px}.entities .entity-detail .enum-list{display:flex;flex-direction:column;gap:3px}.entities .entity-detail .enum-list .enum-row{display:flex;gap:10px;padding-left:10px}.entities .entity-detail .enum-list .enum-row .enum-column{min-width:140px;font-weight:600}.entities .entity-detail .enum-list .enum-row .enum-values{color:#0009}.entities .entity-detail .functions-section{margin-top:10px}.entities .entity-detail .functions-section .functions-heading{margin:0 0 5px;font-size:15px}.entities .entity-detail .functions-section .functions-heading .functions-count{font-weight:400;color:#0009}.entities .entity-detail .functions-section .functions-generated{margin-bottom:10px}.entities .entity-detail .functions-section .functions-list{display:flex;flex-direction:column}.entities .entity-detail .functions-section .functions-list .function-row{display:flex;flex-direction:column;gap:3px;padding:10px 0}.entities .entity-detail .functions-section .functions-list .function-row+.function-row{border-top:1px solid rgba(0,0,0,.08)}.entities .entity-detail .functions-section .functions-list .function-row .function-head{display:flex;align-items:center;gap:8px}.entities .entity-detail .functions-section .functions-list .function-row .function-method{font-family:monospace;font-size:13px;font-weight:600}.entities .entity-detail .functions-section .functions-list .function-row .function-summary{color:#000000bf}.entities .entity-detail .functions-section .functions-list .function-row .function-produces{padding-left:10px}\n"], dependencies: [{ kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i1.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i1.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "directive", type: i1.MatExpansionPanelContent, selector: "ng-template[matExpansionPanelContent]" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FsChipModule }, { kind: "component", type: i3.FsChipComponent, selector: "fs-chip", inputs: ["selectable", "removable", "value", "maxWidth", "width", "backgroundColor", "borderColor", "color", "shape", "outlined", "outlineDash", "icon", "image", "selected", "disabled", "padding", "contrastColor", "size"], outputs: ["selectedToggled", "removed", "click"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "component", type: i4.FsDateComponent, selector: "fs-date", inputs: ["date", "format", "timezone"] }, { kind: "ngmodule", type: FsMessageModule }, { kind: "component", type: i5.FsMessageWarningComponent, selector: "fs-message-warning" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i6.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
189
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SemanticDatabaseComponent, isStandalone: true, selector: "fs-ai-report-global-settings-semantic-database", ngImport: i0, template: "<div class=\"fs-column tab-body\">\n <p class=\"hint\">\n The semantic database is what the report AI uses to understand your data \u2014\n tables, relationships and the calculations in code. Rebuild it after\n significant application updates. The build runs in the background; progress\n appears in the dock at the bottom right and this dialog can be closed while\n it runs.\n </p>\n\n <div *fsSkeleton=\"status()\">\n @if (status(); as buildStatus) {\n <div class=\"build-status\">\n @if (buildStatus.detail.generatedAt) {\n <div class=\"stat\">\n <span class=\"label\">Last built</span>\n <fs-date\n [date]=\"buildStatus.detail.generatedAt\"\n format=\"date-time\">\n </fs-date>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Coverage</span>\n <span>\n {{ buildStatus.detail.entityCount }} entities \u00B7\n {{ buildStatus.detail.functionCount }} code functions\n </span>\n </div>\n } @else {\n <fs-message-warning>\n The semantic database has not been built yet \u2014 the report AI can't\n answer data questions until it is. Run the first build.\n </fs-message-warning>\n }\n @if (buildStatus.build) {\n <div class=\"stat\">\n <span class=\"label\">Last build run</span>\n <span>\n {{ buildStateLabel() }}\n @if (buildStatus.build.message) {\n \u2014 {{ buildStatus.build.message }}\n }\n </span>\n </div>\n }\n </div>\n\n <!-- The entity scoreboard: every entity the AI knows about (an entity =\n a table + a model + a handler), its built-vs-needs-building stages,\n and a drill-down into its shape, enum values, computed fields and\n cached function counts \u2014 the counts link into the functions dialog. -->\n @if (buildStatus.detail.entities?.length) {\n <h2>Entities</h2>\n <mat-accordion class=\"entities\">\n @for (entity of buildStatus.detail.entities; track entity.key) {\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>{{ entity.key }}</mat-panel-title>\n <mat-panel-description>\n <div class=\"stage-chips\">\n @for (stage of stageKeys; track stage) {\n <fs-chip\n size=\"tiny\"\n [backgroundColor]=\"stageColor(entity.stages[stage])\"\n color=\"#ffffff\"\n [matTooltip]=\"stageTooltip(entity.stages[stage])\">\n {{ stageLabels[stage] }}\n </fs-chip>\n }\n </div>\n </mat-panel-description>\n </mat-expansion-panel-header>\n\n <!-- Deferred: the body only exists once expanded. -->\n <ng-template matExpansionPanelContent>\n <div class=\"entity-detail\">\n <div class=\"stat\">\n <span class=\"label\">Table</span>\n <span>{{ entity.table }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Columns</span>\n <span>{{ entity.columns }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Relationships</span>\n <span>{{ entity.relationships }}</span>\n </div>\n @if (entity.enums.length) {\n <div class=\"stat\">\n <span class=\"label\">Enumeration values</span>\n <div class=\"enum-list\">\n @for (enumColumn of entity.enums; track enumColumn.column) {\n <div class=\"enum-row\">\n <span class=\"enum-column\">{{ enumColumn.column }}</span>\n <span>{{ enumColumn.values.join(', ') }}</span>\n </div>\n }\n </div>\n </div>\n }\n @if (entity.computedFields.length) {\n <div class=\"stat\">\n <span class=\"label\">Computed fields</span>\n <span>{{ entity.computedFields.join(', ') }}</span>\n </div>\n }\n <div class=\"stat\">\n <span class=\"label\">Model functions</span>\n @if (entity.modelFunctionCount) {\n <a\n class=\"count-link\"\n (click)=\"openFunctions(entity, 'model')\">\n {{ entity.modelFunctionCount }}\n </a>\n } @else {\n <span>0</span>\n }\n </div>\n <div class=\"stat\">\n <span class=\"label\">Handler functions</span>\n @if (entity.handlerFunctionCount) {\n <a\n class=\"count-link\"\n (click)=\"openFunctions(entity, 'handler')\">\n {{ entity.handlerFunctionCount }}\n </a>\n } @else {\n <span>0</span>\n }\n </div>\n </div>\n </ng-template>\n </mat-expansion-panel>\n }\n </mat-accordion>\n }\n }\n </div>\n</div>\n", styles: [".hint{margin:0 0 12px;color:#0009;font-size:13px;line-height:1.5}.stat{display:flex;align-items:baseline;gap:12px}.stat>.label{flex:0 0 150px;white-space:nowrap;color:#0009}.build-status{display:flex;flex-direction:column;gap:8px}.entities{display:block;padding:3px}.entities mat-panel-description{justify-content:flex-end;margin-right:8px}.entities .stage-chips{display:flex;gap:4px}.entities .entity-detail{display:flex;flex-direction:column;gap:8px}.entities .entity-detail .enum-list{display:flex;flex-direction:column;gap:3px}.entities .entity-detail .enum-list .enum-row{display:flex;gap:12px}.entities .entity-detail .enum-list .enum-row .enum-column{flex:0 0 140px;white-space:nowrap;color:#0009}\n"], dependencies: [{ kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i1.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i1.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "directive", type: i1.MatExpansionPanelContent, selector: "ng-template[matExpansionPanelContent]" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FsChipModule }, { kind: "component", type: i3.FsChipComponent, selector: "fs-chip", inputs: ["selectable", "removable", "value", "maxWidth", "width", "backgroundColor", "borderColor", "color", "shape", "outlined", "outlineDash", "icon", "image", "selected", "disabled", "padding", "contrastColor", "size"], outputs: ["selectedToggled", "removed", "click"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "component", type: i4.FsDateComponent, selector: "fs-date", inputs: ["date", "format", "timezone"] }, { kind: "ngmodule", type: FsMessageModule }, { kind: "component", type: i5.FsMessageWarningComponent, selector: "fs-message-warning" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i6.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
238
190
|
}
|
|
239
191
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SemanticDatabaseComponent, decorators: [{
|
|
240
192
|
type: Component,
|
|
@@ -245,6 +197,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
245
197
|
FsDateModule,
|
|
246
198
|
FsMessageModule,
|
|
247
199
|
FsSkeletonModule,
|
|
248
|
-
], template: "<div class=\"fs-column tab-body\">\n <p class=\"hint\">\n The semantic database is what the report AI uses to understand your data \u2014\n tables, relationships and the calculations in code. Rebuild it after\n significant application updates. The build runs in the background; progress\n appears in the dock at the bottom right and this dialog can be closed while\n it runs.\n </p>\n\n <div *fsSkeleton=\"status()\">\n @if (status(); as buildStatus) {\n <div class=\"build-status\">\n @if (buildStatus.detail.generatedAt) {\n <div class=\"stat\">\n <span class=\"label\">Last built</span>\n <fs-date\n [date]=\"buildStatus.detail.generatedAt\"\n format=\"date-time\">\n </fs-date>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Coverage</span>\n <span>\n {{ buildStatus.detail.entityCount }} entities \u00B7\n {{ buildStatus.detail.functionCount }} code functions\n </span>\n </div>\n } @else {\n <fs-message-warning>\n The semantic database has not been built yet \u2014 the report AI can't\n answer data questions until it is. Run the first build.\n </fs-message-warning>\n }\n @if (buildStatus.build) {\n <div class=\"stat\">\n <span class=\"label\">Last build run</span>\n <span>\n {{ buildStateLabel() }}\n @if (buildStatus.build.message) {\n \u2014 {{ buildStatus.build.message }}\n }\n </span>\n </div>\n }\n </div>\n\n <!-- The
|
|
200
|
+
], template: "<div class=\"fs-column tab-body\">\n <p class=\"hint\">\n The semantic database is what the report AI uses to understand your data \u2014\n tables, relationships and the calculations in code. Rebuild it after\n significant application updates. The build runs in the background; progress\n appears in the dock at the bottom right and this dialog can be closed while\n it runs.\n </p>\n\n <div *fsSkeleton=\"status()\">\n @if (status(); as buildStatus) {\n <div class=\"build-status\">\n @if (buildStatus.detail.generatedAt) {\n <div class=\"stat\">\n <span class=\"label\">Last built</span>\n <fs-date\n [date]=\"buildStatus.detail.generatedAt\"\n format=\"date-time\">\n </fs-date>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Coverage</span>\n <span>\n {{ buildStatus.detail.entityCount }} entities \u00B7\n {{ buildStatus.detail.functionCount }} code functions\n </span>\n </div>\n } @else {\n <fs-message-warning>\n The semantic database has not been built yet \u2014 the report AI can't\n answer data questions until it is. Run the first build.\n </fs-message-warning>\n }\n @if (buildStatus.build) {\n <div class=\"stat\">\n <span class=\"label\">Last build run</span>\n <span>\n {{ buildStateLabel() }}\n @if (buildStatus.build.message) {\n \u2014 {{ buildStatus.build.message }}\n }\n </span>\n </div>\n }\n </div>\n\n <!-- The entity scoreboard: every entity the AI knows about (an entity =\n a table + a model + a handler), its built-vs-needs-building stages,\n and a drill-down into its shape, enum values, computed fields and\n cached function counts \u2014 the counts link into the functions dialog. -->\n @if (buildStatus.detail.entities?.length) {\n <h2>Entities</h2>\n <mat-accordion class=\"entities\">\n @for (entity of buildStatus.detail.entities; track entity.key) {\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>{{ entity.key }}</mat-panel-title>\n <mat-panel-description>\n <div class=\"stage-chips\">\n @for (stage of stageKeys; track stage) {\n <fs-chip\n size=\"tiny\"\n [backgroundColor]=\"stageColor(entity.stages[stage])\"\n color=\"#ffffff\"\n [matTooltip]=\"stageTooltip(entity.stages[stage])\">\n {{ stageLabels[stage] }}\n </fs-chip>\n }\n </div>\n </mat-panel-description>\n </mat-expansion-panel-header>\n\n <!-- Deferred: the body only exists once expanded. -->\n <ng-template matExpansionPanelContent>\n <div class=\"entity-detail\">\n <div class=\"stat\">\n <span class=\"label\">Table</span>\n <span>{{ entity.table }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Columns</span>\n <span>{{ entity.columns }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Relationships</span>\n <span>{{ entity.relationships }}</span>\n </div>\n @if (entity.enums.length) {\n <div class=\"stat\">\n <span class=\"label\">Enumeration values</span>\n <div class=\"enum-list\">\n @for (enumColumn of entity.enums; track enumColumn.column) {\n <div class=\"enum-row\">\n <span class=\"enum-column\">{{ enumColumn.column }}</span>\n <span>{{ enumColumn.values.join(', ') }}</span>\n </div>\n }\n </div>\n </div>\n }\n @if (entity.computedFields.length) {\n <div class=\"stat\">\n <span class=\"label\">Computed fields</span>\n <span>{{ entity.computedFields.join(', ') }}</span>\n </div>\n }\n <div class=\"stat\">\n <span class=\"label\">Model functions</span>\n @if (entity.modelFunctionCount) {\n <a\n class=\"count-link\"\n (click)=\"openFunctions(entity, 'model')\">\n {{ entity.modelFunctionCount }}\n </a>\n } @else {\n <span>0</span>\n }\n </div>\n <div class=\"stat\">\n <span class=\"label\">Handler functions</span>\n @if (entity.handlerFunctionCount) {\n <a\n class=\"count-link\"\n (click)=\"openFunctions(entity, 'handler')\">\n {{ entity.handlerFunctionCount }}\n </a>\n } @else {\n <span>0</span>\n }\n </div>\n </div>\n </ng-template>\n </mat-expansion-panel>\n }\n </mat-accordion>\n }\n }\n </div>\n</div>\n", styles: [".hint{margin:0 0 12px;color:#0009;font-size:13px;line-height:1.5}.stat{display:flex;align-items:baseline;gap:12px}.stat>.label{flex:0 0 150px;white-space:nowrap;color:#0009}.build-status{display:flex;flex-direction:column;gap:8px}.entities{display:block;padding:3px}.entities mat-panel-description{justify-content:flex-end;margin-right:8px}.entities .stage-chips{display:flex;gap:4px}.entities .entity-detail{display:flex;flex-direction:column;gap:8px}.entities .entity-detail .enum-list{display:flex;flex-direction:column;gap:3px}.entities .entity-detail .enum-list .enum-row{display:flex;gap:12px}.entities .entity-detail .enum-list .enum-row .enum-column{flex:0 0 140px;white-space:nowrap;color:#0009}\n"] }]
|
|
249
201
|
}], ctorParameters: () => [] });
|
|
250
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VtYW50aWMtZGF0YWJhc2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvZ2xvYmFsLXNldHRpbmdzL2NvbXBvbmVudHMvc2VtYW50aWMtZGF0YWJhc2Uvc2VtYW50aWMtZGF0YWJhc2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvZ2xvYmFsLXNldHRpbmdzL2NvbXBvbmVudHMvc2VtYW50aWMtZGF0YWJhc2Uvc2VtYW50aWMtZGF0YWJhc2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekcsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFaEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFN0QsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FB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QUksR0FBRyx5QkFBeUIsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWhFLE9BQU8sSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyx5QkFBeUIsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDMUUsQ0FBQzt3R0FwUVUseUJBQXlCOzRGQUF6Qix5QkFBeUIsMEdDL0N0Qyxtbk5Bb0pBLCs3REQ3R0ksa0JBQWtCLHEwQkFDbEIsZ0JBQWdCLDRUQUNoQixZQUFZLHFYQUNaLFlBQVksNElBQ1osZUFBZSx5SEFDZixnQkFBZ0I7OzRGQUdQLHlCQUF5QjtrQkFmckMsU0FBUzsrQkFDRSxnREFBZ0QsbUJBR3pDLHVCQUF1QixDQUFDLE1BQU0sY0FDbkMsSUFBSSxXQUNQO3dCQUNQLGtCQUFrQjt3QkFDbEIsZ0JBQWdCO3dCQUNoQixZQUFZO3dCQUNaLFlBQVk7d0JBQ1osZUFBZTt3QkFDZixnQkFBZ0I7cUJBQ2pCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRGVzdHJveVJlZiwgY29tcHV0ZWQsIGluamVjdCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5cbmltcG9ydCB7IE1hdEV4cGFuc2lvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2V4cGFuc2lvbic7XG5pbXBvcnQgeyBNYXRUb29sdGlwTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdG9vbHRpcCc7XG5cbmltcG9ydCB7IFN0cmVhbUV2ZW50VHlwZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2FwaSc7XG5pbXBvcnQgeyBGc0NoaXBNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9jaGlwJztcbmltcG9ydCB7IEZzRGF0ZU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RhdGUnO1xuaW1wb3J0IHsgRnNNZXNzYWdlLCBGc01lc3NhZ2VNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9tZXNzYWdlJztcbmltcG9ydCB7IEZzUHJvY2VzcyB9IGZyb20gJ0BmaXJlc3RpdGNoL3Byb2Nlc3MnO1xuaW1wb3J0IHsgRnNQcm9tcHQgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9tcHQnO1xuaW1wb3J0IHsgRnNTa2VsZXRvbk1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL3NrZWxldG9uJztcblxuaW1wb3J0IHsgZmlsdGVyLCBtYXAsIHN3aXRjaE1hcCwgdGFrZSwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBSZXBvcnREYXRhIH0gZnJvbSAnLi4vLi4vLi4vLi4vZGF0YS9yZXBvcnQuZGF0YSc7XG5pbXBvcnQge1xuICBTZW1hbnRpY0J1aWxkRW50aXR5LFxuICBTZW1hbnRpY0J1aWxkU3RhZ2UsXG4gIFNlbWFudGljQnVpbGRTdGF0dXMsXG4gIFNlbWFudGljRW50aXR5RnVuY3Rpb25zLFxufSBmcm9tICcuLi8uLi8uLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuXG5cbi8vIFRoZSBTZW1hbnRpYyBEYXRhYmFzZSB0YWI6IHRoZSBtb2RlbCBzY29yZWJvYXJkIHRoZSByZXBvcnQgQUkgaXMgYnVpbHQgZnJvbS5cbi8vIFNob3dzIHRoZSBsYXN0IGJ1aWxkJ3Mgc3RhdHVzLCBydW5zIChvciBzdG9wcykgYSBidWlsZCDigJQgc3RyZWFtZWQgaW50byB0aGVcbi8vIEZzUHJvY2VzcyBkb2NrIHNvIGl0IHN1cnZpdmVzIHRoZSBkaWFsb2cgY2xvc2luZyDigJQgYW5kIGRyaWxscyBpbnRvIGV2ZXJ5XG4vLyBlbnRpdHkgdG8gcmV2ZWFsIGl0cyBzaGFwZSwgaW5saW5lZCBlbnVtIHZhbHVlcywgY29tcHV0ZWQgZmllbGRzIGFuZCB0aGVcbi8vIEFJLWNsYXNzaWZpZWQgY29kZSBmdW5jdGlvbnMgY2FjaGVkIGZyb20gaXRzIG1vZGVsIGNsYXNzLiBFYWNoIGVudGl0eSdzXG4vLyBmdW5jdGlvbnMgbG9hZCBsYXppbHkgb24gZmlyc3QgZXhwYW5kLCBiZWNhdXNlIHRoZSBmdWxsIHNldCBhY3Jvc3MgYWxsXG4vLyBlbnRpdGllcyBpcyBmYXIgdG9vIGJpZyB0byBzaGlwIHdpdGggdGhlIHNjb3JlYm9hcmQuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdmcy1haS1yZXBvcnQtZ2xvYmFsLXNldHRpbmdzLXNlbWFudGljLWRhdGFiYXNlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3NlbWFudGljLWRhdGFiYXNlLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc2VtYW50aWMtZGF0YWJhc2UuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBNYXRFeHBhbnNpb25Nb2R1bGUsXG4gICAgTWF0VG9vbHRpcE1vZHVsZSxcbiAgICBGc0NoaXBNb2R1bGUsXG4gICAgRnNEYXRlTW9kdWxlLFxuICAgIEZzTWVzc2FnZU1vZHVsZSxcbiAgICBGc1NrZWxldG9uTW9kdWxlLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBTZW1hbnRpY0RhdGFiYXNlQ29tcG9uZW50IHtcblxuICAvLyBUaGUgYnVpbGQtaW4tZmxpZ2h0IHN0YXRlcyBvZiB0aGUgZmZfcHJvY2Vzc2VzIHJvdyAocXVldWVkL3J1bm5pbmcvc3RvcHBpbmcpLlxuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBBQ1RJVkVfU1RBVEVTID0gWydRJywgJ1InLCAnWCddO1xuXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IFNUQVRFX0xBQkVMUzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICBROiAnUXVldWVkJyxcbiAgICBSOiAnUnVubmluZycsXG4gICAgWDogJ1N0b3BwaW5nJyxcbiAgICBDOiAnQ29tcGxldGVkJyxcbiAgICBLOiAnU3RvcHBlZCcsXG4gICAgRjogJ0ZhaWxlZCcsXG4gIH07XG5cbiAgLy8gU2NvcmVib2FyZCBjb21wbGV0aW9uIHBhbGV0dGU6IGJ1aWx0ID0gZ3JlZW4sIGV2ZXJ5dGhpbmcgZWxzZSAobmVlZHNcbiAgLy8gYnVpbGRpbmcpID0gZ3JleS4gTm8gZXJyb3IgcmVkIOKAlCBhIG1pc3Npbmcgc3RhZ2UgaXMgdW5idWlsdCBjb250ZW50LCBub3QgYVxuICAvLyBmYWlsdXJlLlxuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBET05FX0NPTE9SID0gJyMyZTdkMzInO1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBQRU5ESU5HX0NPTE9SID0gJyM5ZTllOWUnO1xuXG4gIC8vIE9uZSBjb2xvciBwZXIgQUkgY2xhc3NpZmljYXRpb24ga2luZCwgc28gYSBmdW5jdGlvbidzIG5hdHVyZSByZWFkcyBhdCBhIGdsYW5jZS5cbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgS0lORF9DT0xPUlM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgJ2NhbGN1bGF0aW9uJzogJyMxNTY1YzAnLFxuICAgICdidXNpbmVzcy1ydWxlJzogJyM2YTFiOWEnLFxuICAgICdxdWVyeSc6ICcjMDA2OTVjJyxcbiAgICAnbXV0YXRpb24nOiAnI2U2NTEwMCcsXG4gICAgJ2FjY2Vzc29yJzogJyM1NDZlN2EnLFxuICAgICdvdGhlcic6ICcjNzU3NTc1JyxcbiAgfTtcblxuICAvLyBJbnRlcmVzdGluZyBsb2dpYyBmaXJzdDogZGVyaXZlZCB2YWx1ZXMgYW5kIHJ1bGVzLCB0aGVuIGRhdGEgYWNjZXNzLCB0aGVuIHRoZSByZXN0LlxuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBLSU5EX09SREVSID0gWydjYWxjdWxhdGlvbicsICdidXNpbmVzcy1ydWxlJywgJ3F1ZXJ5JywgJ211dGF0aW9uJywgJ2FjY2Vzc29yJywgJ290aGVyJ107XG5cbiAgLy8gVGhlIHNjb3JlYm9hcmQncyBwZXItZW50aXR5IHN0YWdlIGNoaXBzLCBsZWZ0IHRvIHJpZ2h0LlxuICBwdWJsaWMgcmVhZG9ubHkgc3RhZ2VLZXlzID0gWydpbnRyb3NwZWN0ZWQnLCAnZW51bXNJbmxpbmVkJywgJ2NvbXB1dGVkJywgJ2Z1bmN0aW9ucyddO1xuXG4gIHB1YmxpYyByZWFkb25seSBzdGFnZUxhYmVsczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICBpbnRyb3NwZWN0ZWQ6ICdJbnRyb3NwZWN0ZWQnLFxuICAgIGVudW1zSW5saW5lZDogJ0VudW0gY2FzZXMnLFxuICAgIGNvbXB1dGVkOiAnQ29tcHV0ZWQnLFxuICAgIGZ1bmN0aW9uczogJ0Z1bmN0aW9ucycsXG4gIH07XG5cbiAgLy8gbnVsbCB1bnRpbCBsb2FkZWQg4oCUIGdhdGVzIHRoZSB0YWIgYmVoaW5kIHRoZSBza2VsZXRvbi5cbiAgcHVibGljIHJlYWRvbmx5IHN0YXR1cyA9IHNpZ25hbDxTZW1hbnRpY0J1aWxkU3RhdHVzIHwgbnVsbD4obnVsbCk7XG5cbiAgLy8gVHJ1ZSB3aGlsZSBhIGJ1aWxkIHN0YXJ0ZWQgZnJvbSB0aGlzIHRhYiBpcyBzdHJlYW1pbmcgaW50byB0aGUgZG9jay5cbiAgcHVibGljIHJlYWRvbmx5IGJ1aWxkaW5nID0gc2lnbmFsKGZhbHNlKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgYnVpbGRBY3RpdmUgPSBjb21wdXRlZDxib29sZWFuPigoKSA9PlxuICAgIHRoaXMuYnVpbGRpbmcoKVxuICAgICAgfHwgU2VtYW50aWNEYXRhYmFzZUNvbXBvbmVudC5BQ1RJVkVfU1RBVEVTLmluY2x1ZGVzKHRoaXMuc3RhdHVzKCk/LmJ1aWxkPy5zdGF0ZSksXG4gICk7XG5cbiAgcHVibGljIHJlYWRvbmx5IGJ1aWxkU3RhdGVMYWJlbCA9IGNvbXB1dGVkPHN0cmluZz4oKCkgPT5cbiAgICBTZW1hbnRpY0RhdGFiYXNlQ29tcG9uZW50LlNUQVRFX0xBQkVMU1t0aGlzLnN0YXR1cygpPy5idWlsZD8uc3RhdGVdID8/ICcnLFxuICApO1xuXG4gIC8vIFBlci1lbnRpdHkgZnVuY3Rpb24gY2FjaGVzLCBsb2FkZWQgb24gZmlyc3QgZXhwYW5kLiB1bmRlZmluZWQgPSBub3RcbiAgLy8gcmVxdWVzdGVkIHlldCwgbnVsbCA9IHJlcXVlc3QgaW4gZmxpZ2h0ICh0aGUgc2tlbGV0b24gd2luZG93KSwgb2JqZWN0ID0gbG9hZGVkLlxuICBwcml2YXRlIHJlYWRvbmx5IF9lbnRpdHlGdW5jdGlvbnMgPSBzaWduYWw8UmVjb3JkPHN0cmluZywgU2VtYW50aWNFbnRpdHlGdW5jdGlvbnMgfCBudWxsPj4oe30pO1xuXG4gIC8vIEd1YXJkcyB0aGUgb3V0Y29tZSBtZXNzYWdlIHRvIGZpcmUgZXhhY3RseSBvbmNlIHBlciBydW4g4oCUIHdoZXRoZXIgdGhlIHN0cmVhbVxuICAvLyBjb21wbGV0ZXMgKGJ1aWxkIGZpbmlzaGVkLCBwb3NzaWJseSBmYWlsZWQpIG9yIGVycm9ycyBvdXRyaWdodC5cbiAgcHJpdmF0ZSBfYnVpbGRGaW5hbGl6ZWQgPSBmYWxzZTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9yZXBvcnREYXRhID0gaW5qZWN0KFJlcG9ydERhdGEpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9wcm9jZXNzID0gaW5qZWN0KEZzUHJvY2Vzcyk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3Byb21wdCA9IGluamVjdChGc1Byb21wdCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX21lc3NhZ2UgPSBpbmplY3QoRnNNZXNzYWdlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9pbml0KCk7XG4gIH1cblxuICAvLyBDb25maXJtIGJlZm9yZSBraWNraW5nIG9mZiBhIGJ1aWxkIOKAlCBhIHJlYnVpbGQgcmVwbGFjZXMgdGhlIGN1cnJlbnRcbiAgLy8gc2VtYW50aWMgZGF0YWJhc2UsIHNvIGl0IHNob3VsZCBuZXZlciBmaXJlIG9uIGEgc3RyYXkgY2xpY2suXG4gIHB1YmxpYyBidWlsZCgpOiB2b2lkIHtcbiAgICBjb25zdCByZWJ1aWxkID0gISF0aGlzLnN0YXR1cygpPy5kZXRhaWw/LmdlbmVyYXRlZEF0O1xuXG4gICAgdGhpcy5fcHJvbXB0LmNvbmZpcm0oe1xuICAgICAgdGl0bGU6IHJlYnVpbGQgPyAnUmVidWlsZCBzZW1hbnRpYyBkYXRhYmFzZScgOiAnQnVpbGQgc2VtYW50aWMgZGF0YWJhc2UnLFxuICAgICAgdGVtcGxhdGU6IHJlYnVpbGRcbiAgICAgICAgPyAnUmVidWlsZCB0aGUgc2VtYW50aWMgZGF0YWJhc2U/IEl0IHJ1bnMgaW4gdGhlIGJhY2tncm91bmQgYW5kIHJlcGxhY2VzIHRoZSBjdXJyZW50IG9uZSB3aGVuIGl0IGZpbmlzaGVzLidcbiAgICAgICAgOiAnQnVpbGQgdGhlIHNlbWFudGljIGRhdGFiYXNlPyBJdCBydW5zIGluIHRoZSBiYWNrZ3JvdW5kLicsXG4gICAgICBjb21taXRMYWJlbDogcmVidWlsZCA/ICdSZWJ1aWxkJyA6ICdCdWlsZCcsXG4gICAgfSlcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fcnVuQnVpbGQoKSk7XG4gIH1cblxuICBwdWJsaWMgc3RvcEJ1aWxkKCk6IHZvaWQge1xuICAgIHRoaXMuX3Byb21wdC5jb25maXJtKHtcbiAgICAgIHRpdGxlOiAnU3RvcCBidWlsZCcsXG4gICAgICB0ZW1wbGF0ZTogJ1N0b3AgdGhlIHJ1bm5pbmcgYnVpbGQ/IFRoZSBjdXJyZW50IHNlbWFudGljIGRhdGFiYXNlIHN0YXlzIGluIHBsYWNlIHVudGlsIGEgYnVpbGQgZmluaXNoZXMuJyxcbiAgICAgIGNvbW1pdExhYmVsOiAnU3RvcCcsXG4gICAgfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5fcmVwb3J0RGF0YS5zZW1hbnRpY0J1aWxkU3RvcCgpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuYnVpbGRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdTdG9wcGluZyB0aGUgYnVpbGTigKYnKTtcbiAgICAgICAgdGhpcy5fcmVmcmVzaFN0YXR1cygpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBSdW4gdGhlIHNlbWFudGljLWRhdGFiYXNlIGJ1aWxkLiBUaGUgbGl2ZSBmZWVkIHN0cmVhbXMgaW50byB0aGUgRnNQcm9jZXNzXG4gIC8vIGRvY2sgKGJvdHRvbS1yaWdodCksIHdob3NlIHN1YnNjcmlwdGlvbiBzdXJ2aXZlcyB0aGlzIGRpYWxvZyBjbG9zaW5nIOKAlCBzb1xuICAvLyBkaXNtaXNzaW5nIHRoZSBkaWFsb2cgbmV2ZXIgaW50ZXJydXB0cyBhIHJ1bm5pbmcgYnVpbGQuXG4gIHByaXZhdGUgX3J1bkJ1aWxkKCk6IHZvaWQge1xuICAgIHRoaXMuYnVpbGRpbmcuc2V0KHRydWUpO1xuICAgIHRoaXMuX2J1aWxkRmluYWxpemVkID0gZmFsc2U7XG5cbiAgICBjb25zdCB0YXJnZXQkID0gdGhpcy5fcmVwb3J0RGF0YS5zZW1hbnRpY0J1aWxkKClcbiAgICAgIC5waXBlKFxuICAgICAgICAvLyBBIGhhcmQgc3RyZWFtL3RyYW5zcG9ydCBmYWlsdXJlICh0aGUgYnVpbGQgY291bGRuJ3QgZXZlbiBzdGFydClcbiAgICAgICAgLy8gZmluYWxpemVzIGhlcmUg4oCUIGNvbXBsZXRlZCQgd29uJ3QgZmlyZSBpbiB0aGF0IGNhc2UuXG4gICAgICAgIHRhcCh7IGVycm9yOiAoZXJyb3IpID0+IHRoaXMuX2ZpbmFsaXplQnVpbGQoZXJyb3IpIH0pLFxuICAgICAgICBmaWx0ZXIoKGV2ZW50KSA9PlxuICAgICAgICAgIGV2ZW50Py50eXBlID09PSBTdHJlYW1FdmVudFR5cGUuRGF0YVxuICAgICAgICAgICYmIGV2ZW50LmRhdGE/LmtpbmQgPT09ICdsb2cnXG4gICAgICAgICAgJiYgdHlwZW9mIGV2ZW50LmRhdGEubGluZSA9PT0gJ3N0cmluZycpLFxuICAgICAgICBtYXAoKGV2ZW50KSA9PiBldmVudC5kYXRhLmxpbmUgYXMgc3RyaW5nKSxcbiAgICAgICk7XG5cbiAgICB0aGlzLl9wcm9jZXNzXG4gICAgICAucnVuKCdTZW1hbnRpYyBkYXRhYmFzZSBidWlsZCcsIHRhcmdldCQpXG4gICAgICAuY29tcGxldGVkJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2UoMSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fZmluYWxpemVCdWlsZChudWxsKSk7XG4gIH1cblxuICAvKipcbiAgICogV3JhcCB1cCBvbmUgYnVpbGQgcnVuIGV4YWN0bHkgb25jZS4gT24gYSBoYXJkIHN0cmVhbSBlcnJvciB0aGVyZSBpcyBub1xuICAgKiBzdGF0dXMgdG8gcmVhZCwgc28gc2F5IHNvIGRpcmVjdGx5OyBvdGhlcndpc2UgcmVmcmVzaCB0aGUgc3RhdHVzIGFuZFxuICAgKiBhbm5vdW5jZSBob3cgdGhlIGJ1aWxkIGFjdHVhbGx5IGVuZGVkIOKAlCBhIGJ1aWxkIHRoYXQgZmFpbGVkIChlLmcuIHRoZSBBSVxuICAgKiBjb3VsZG4ndCBiZSByZWFjaGVkKSByZXBvcnRzICdGYWlsZWQnIHdpdGggYSByZWFzb24sIGFuZCB0aGF0IG11c3Qgc3VyZmFjZVxuICAgKiBpbnN0ZWFkIG9mIHRoZSBydW4gc2lsZW50bHkgZG9pbmcgbm90aGluZy5cbiAgICovXG4gIHByaXZhdGUgX2ZpbmFsaXplQnVpbGQoc3RyZWFtRXJyb3I6IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fYnVpbGRGaW5hbGl6ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fYnVpbGRGaW5hbGl6ZWQgPSB0cnVlO1xuXG4gICAgdGhpcy5idWlsZGluZy5zZXQoZmFsc2UpO1xuICAgIC8vIFRoZSBidWlsZCByZXdyb3RlIGV2ZXJ5IGVudGl0eSdzIGZ1bmN0aW9uIGNhY2hlIOKAlCBkcm9wIHRoZSBsb2FkZWQgY29waWVzXG4gICAgLy8gc28gdGhlIG5leHQgZXhwYW5kIHJlZmV0Y2hlcyBmcmVzaCBkYXRhLlxuICAgIHRoaXMuX2VudGl0eUZ1bmN0aW9ucy5zZXQoe30pO1xuXG4gICAgaWYgKHN0cmVhbUVycm9yKSB7XG4gICAgICB0aGlzLl9tZXNzYWdlLmVycm9yKCdUaGUgc2VtYW50aWMgZGF0YWJhc2UgYnVpbGQgY291bGQgbm90IHJ1biDigJQgY2hlY2sgdGhlIEFJIGNvbm5lY3Rpb24gYW5kIHRyeSBhZ2Fpbi4nKTtcbiAgICAgIHRoaXMuX3JlZnJlc2hTdGF0dXMoKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3JlcG9ydERhdGEuc2VtYW50aWNCdWlsZFN0YXR1cygpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChzdGF0dXM6IFNlbWFudGljQnVpbGRTdGF0dXMpID0+IHtcbiAgICAgICAgdGhpcy5zdGF0dXMuc2V0KHN0YXR1cyk7XG4gICAgICAgIHRoaXMuX2Fubm91bmNlT3V0Y29tZShzdGF0dXMpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVGVsbCB0aGUgb3BlcmF0b3IgaG93IHRoZSBidWlsZCBlbmRlZDogYSBmYWlsZWQvc3RvcHBlZCBidWlsZCBzdXJmYWNlcyBpdHNcbiAgICogcmVhc29uIChzbyBhbiBBSSBjb25uZWN0aW9uIHByb2JsZW0gaXMgbmV2ZXIgc2lsZW50KSwgYSBjb21wbGV0ZWQgb25lXG4gICAqIGNvbmZpcm1zIHN1Y2Nlc3MuXG4gICAqL1xuICBwcml2YXRlIF9hbm5vdW5jZU91dGNvbWUoc3RhdHVzOiBTZW1hbnRpY0J1aWxkU3RhdHVzKTogdm9pZCB7XG4gICAgY29uc3QgYnVpbGQgPSBzdGF0dXM/LmJ1aWxkO1xuICAgIGlmIChidWlsZD8uc3RhdGUgPT09ICdGJyB8fCBidWlsZD8uc3RhdGUgPT09ICdLJykge1xuICAgICAgdGhpcy5fbWVzc2FnZS5lcnJvcihidWlsZC5tZXNzYWdlIHx8ICdUaGUgc2VtYW50aWMgZGF0YWJhc2UgYnVpbGQgZGlkIG5vdCBmaW5pc2guJyk7XG4gICAgfSBlbHNlIGlmIChidWlsZD8uc3RhdGUgPT09ICdDJykge1xuICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdTZW1hbnRpYyBkYXRhYmFzZSBidWlsZCBjb21wbGV0ZS4nKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc3RhZ2VDb2xvcihzdGFnZTogU2VtYW50aWNCdWlsZFN0YWdlKTogc3RyaW5nIHtcbiAgICByZXR1cm4gc3RhZ2UgPT09ICdkb25lJ1xuICAgICAgPyBTZW1hbnRpY0RhdGFiYXNlQ29tcG9uZW50LkRPTkVfQ09MT1JcbiAgICAgIDogU2VtYW50aWNEYXRhYmFzZUNvbXBvbmVudC5QRU5ESU5HX0NPTE9SO1xuICB9XG5cbiAgcHVibGljIHN0YWdlVG9vbHRpcChzdGFnZTogU2VtYW50aWNCdWlsZFN0YWdlKTogc3RyaW5nIHtcbiAgICByZXR1cm4gc3RhZ2UgPT09ICdkb25lJyA/ICdCdWlsdCcgOiAnTmVlZHMgYnVpbGRpbmcnO1xuICB9XG5cbiAgcHVibGljIGtpbmRDb2xvcihraW5kOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBTZW1hbnRpY0RhdGFiYXNlQ29tcG9uZW50LktJTkRfQ09MT1JTW2tpbmRdID8/IFNlbWFudGljRGF0YWJhc2VDb21wb25lbnQuS0lORF9DT0xPUlMub3RoZXI7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGxvYWRlZCBmdW5jdGlvbiBjYWNoZSBmb3IgYW4gZW50aXR5OiB1bmRlZmluZWQgdW50aWwgdGhlIHBhbmVsIGlzIGZpcnN0XG4gICAqIGV4cGFuZGVkLCBudWxsIHdoaWxlIHRoZSByZXF1ZXN0IGlzIGluIGZsaWdodCAodGhlIHNrZWxldG9uIHdpbmRvdyksIHRoZW5cbiAgICogdGhlIGxvYWRlZCBjYWNoZS5cbiAgICovXG4gIHB1YmxpYyBlbnRpdHlGdW5jdGlvbnMoa2V5OiBzdHJpbmcpOiBTZW1hbnRpY0VudGl0eUZ1bmN0aW9ucyB8IG51bGwgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9lbnRpdHlGdW5jdGlvbnMoKVtrZXldO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpcnN0IGV4cGFuZCBvZiBhbiBlbnRpdHk6IGZldGNoIGl0cyBjYWNoZWQgZnVuY3Rpb25zIHRocm91Z2ggdGhlIHBlci1lbnRpdHlcbiAgICogZW5kcG9pbnQuIFN1YnNlcXVlbnQgZXhwYW5kcyByZXVzZSB0aGUgbG9hZGVkIGNvcHkgKGEgZmluaXNoZWQgYnVpbGQgY2xlYXJzXG4gICAqIHRoZSBjb3BpZXMgc28gYSByZS1leHBhbmQgcmVmZXRjaGVzIGZyZXNoIGRhdGEpLlxuICAgKi9cbiAgcHVibGljIGVudGl0eU9wZW5lZChlbnRpdHk6IFNlbWFudGljQnVpbGRFbnRpdHkpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fZW50aXR5RnVuY3Rpb25zKClbZW50aXR5LmtleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2VudGl0eUZ1bmN0aW9ucy51cGRhdGUoKGxvYWRlZCkgPT4gKHsgLi4ubG9hZGVkLCBbZW50aXR5LmtleV06IG51bGwgfSkpO1xuXG4gICAgdGhpcy5fcmVwb3J0RGF0YS5zZW1hbnRpY0VudGl0eUZ1bmN0aW9ucyhlbnRpdHkua2V5KVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoZW50aXR5RnVuY3Rpb25zOiBTZW1hbnRpY0VudGl0eUZ1bmN0aW9ucykgPT4ge1xuICAgICAgICB0aGlzLl9lbnRpdHlGdW5jdGlvbnMudXBkYXRlKChsb2FkZWQpID0+ICh7XG4gICAgICAgICAgLi4ubG9hZGVkLFxuICAgICAgICAgIFtlbnRpdHkua2V5XToge1xuICAgICAgICAgICAgLi4uZW50aXR5RnVuY3Rpb25zLFxuICAgICAgICAgICAgZnVuY3Rpb25zOiB0aGlzLl9zb3J0RnVuY3Rpb25zKGVudGl0eUZ1bmN0aW9ucyksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSkpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9pbml0KCk6IHZvaWQge1xuICAgIHRoaXMuX3JlZnJlc2hTdGF0dXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlZnJlc2hTdGF0dXMoKTogdm9pZCB7XG4gICAgdGhpcy5fcmVwb3J0RGF0YS5zZW1hbnRpY0J1aWxkU3RhdHVzKClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKHN0YXR1czogU2VtYW50aWNCdWlsZFN0YXR1cykgPT4gdGhpcy5zdGF0dXMuc2V0KHN0YXR1cykpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9yZGVyIG9uY2UgYXQgbG9hZCB0aW1lIChraW5kIHByaW9yaXR5LCB0aGVuIG1ldGhvZCBuYW1lKSBzbyB0aGUgdGVtcGxhdGVcbiAgICogcmVuZGVycyB0aGUgbGlzdCBhcy1pcy5cbiAgICovXG4gIHByaXZhdGUgX3NvcnRGdW5jdGlvbnMoZW50aXR5RnVuY3Rpb25zOiBTZW1hbnRpY0VudGl0eUZ1bmN0aW9ucyk6IFNlbWFudGljRW50aXR5RnVuY3Rpb25zWydmdW5jdGlvbnMnXSB7XG4gICAgcmV0dXJuIFsuLi5lbnRpdHlGdW5jdGlvbnMuZnVuY3Rpb25zXVxuICAgICAgLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgY29uc3Qga2luZERpZmYgPSB0aGlzLl9raW5kUmFuayhhLmtpbmQpIC0gdGhpcy5fa2luZFJhbmsoYi5raW5kKTtcblxuICAgICAgICByZXR1cm4ga2luZERpZmYgIT09IDAgPyBraW5kRGlmZiA6IGEubWV0aG9kLmxvY2FsZUNvbXBhcmUoYi5tZXRob2QpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9raW5kUmFuayhraW5kOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGNvbnN0IHJhbmsgPSBTZW1hbnRpY0RhdGFiYXNlQ29tcG9uZW50LktJTkRfT1JERVIuaW5kZXhPZihraW5kKTtcblxuICAgIHJldHVybiByYW5rID09PSAtMSA/IFNlbWFudGljRGF0YWJhc2VDb21wb25lbnQuS0lORF9PUkRFUi5sZW5ndGggOiByYW5rO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiZnMtY29sdW1uIHRhYi1ib2R5XCI+XG4gIDxwIGNsYXNzPVwiaGludFwiPlxuICAgIFRoZSBzZW1hbnRpYyBkYXRhYmFzZSBpcyB3aGF0IHRoZSByZXBvcnQgQUkgdXNlcyB0byB1bmRlcnN0YW5kIHlvdXIgZGF0YSDigJRcbiAgICB0YWJsZXMsIHJlbGF0aW9uc2hpcHMgYW5kIHRoZSBjYWxjdWxhdGlvbnMgaW4gY29kZS4gUmVidWlsZCBpdCBhZnRlclxuICAgIHNpZ25pZmljYW50IGFwcGxpY2F0aW9uIHVwZGF0ZXMuIFRoZSBidWlsZCBydW5zIGluIHRoZSBiYWNrZ3JvdW5kOyBwcm9ncmVzc1xuICAgIGFwcGVhcnMgaW4gdGhlIGRvY2sgYXQgdGhlIGJvdHRvbSByaWdodCBhbmQgdGhpcyBkaWFsb2cgY2FuIGJlIGNsb3NlZCB3aGlsZVxuICAgIGl0IHJ1bnMuXG4gIDwvcD5cblxuICA8ZGl2ICpmc1NrZWxldG9uPVwic3RhdHVzKClcIj5cbiAgICBAaWYgKHN0YXR1cygpOyBhcyBidWlsZFN0YXR1cykge1xuICAgICAgPGRpdiBjbGFzcz1cImJ1aWxkLXN0YXR1c1wiPlxuICAgICAgICBAaWYgKGJ1aWxkU3RhdHVzLmRldGFpbC5nZW5lcmF0ZWRBdCkge1xuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxhYmVsXCI+TGFzdCBidWlsdDwvc3Bhbj5cbiAgICAgICAgICAgIDxmcy1kYXRlXG4gICAgICAgICAgICAgICAgW2RhdGVdPVwiYnVpbGRTdGF0dXMuZGV0YWlsLmdlbmVyYXRlZEF0XCJcbiAgICAgICAgICAgICAgICBmb3JtYXQ9XCJkYXRlLXRpbWVcIj5cbiAgICAgICAgICAgIDwvZnMtZGF0ZT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdFwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbFwiPkNvdmVyYWdlPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgIHt7IGJ1aWxkU3RhdHVzLmRldGFpbC5lbnRpdHlDb3VudCB9fSBlbnRpdGllcyDCt1xuICAgICAgICAgICAgICB7eyBidWlsZFN0YXR1cy5kZXRhaWwuZnVuY3Rpb25Db3VudCB9fSBjb2RlIGZ1bmN0aW9uc1xuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICA8ZnMtbWVzc2FnZS13YXJuaW5nPlxuICAgICAgICAgICAgVGhlIHNlbWFudGljIGRhdGFiYXNlIGhhcyBub3QgYmVlbiBidWlsdCB5ZXQg4oCUIHRoZSByZXBvcnQgQUkgY2FuJ3RcbiAgICAgICAgICAgIGFuc3dlciBkYXRhIHF1ZXN0aW9ucyB1bnRpbCBpdCBpcy4gUnVuIHRoZSBmaXJzdCBidWlsZC5cbiAgICAgICAgICA8L2ZzLW1lc3NhZ2Utd2FybmluZz5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGJ1aWxkU3RhdHVzLmJ1aWxkKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInN0YXRcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGFiZWxcIj5MYXN0IGJ1aWxkIHJ1bjwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICB7eyBidWlsZFN0YXRlTGFiZWwoKSB9fVxuICAgICAgICAgICAgICBAaWYgKGJ1aWxkU3RhdHVzLmJ1aWxkLm1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICDigJQge3sgYnVpbGRTdGF0dXMuYnVpbGQubWVzc2FnZSB9fVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRoZSBtb2RlbCBzY29yZWJvYXJkOiBldmVyeSBlbnRpdHkgdGhlIEFJIGtub3dzIGFib3V0LCBpdHNcbiAgICAgICAgICAgYnVpbHQtdnMtbmVlZHMtYnVpbGRpbmcgc3RhZ2VzLCBhbmQgYSBkcmlsbC1kb3duIGludG8gaXRzIHNoYXBlLCBlbnVtXG4gICAgICAgICAgIHZhbHVlcywgY29tcHV0ZWQgZmllbGRzIGFuZCBBSS1jbGFzc2lmaWVkIGNvZGUgZnVuY3Rpb25zLiAtLT5cbiAgICAgIEBpZiAoYnVpbGRTdGF0dXMuZGV0YWlsLmVudGl0aWVzPy5sZW5ndGgpIHtcbiAgICAgICAgPG1hdC1hY2NvcmRpb24gY2xhc3M9XCJlbnRpdGllc1wiPlxuICAgICAgICAgIEBmb3IgKGVudGl0eSBvZiBidWlsZFN0YXR1cy5kZXRhaWwuZW50aXRpZXM7IHRyYWNrIGVudGl0eS5rZXkpIHtcbiAgICAgICAgICAgIDxtYXQtZXhwYW5zaW9uLXBhbmVsIChvcGVuZWQpPVwiZW50aXR5T3BlbmVkKGVudGl0eSlcIj5cbiAgICAgICAgICAgICAgPG1hdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxuICAgICAgICAgICAgICAgIDxtYXQtcGFuZWwtdGl0bGU+e3sgZW50aXR5LmtleSB9fTwvbWF0LXBhbmVsLXRpdGxlPlxuICAgICAgICAgICAgICAgIDxtYXQtcGFuZWwtZGVzY3JpcHRpb24+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhZ2UtY2hpcHNcIj5cbiAgICAgICAgICAgICAgICAgICAgQGZvciAoc3RhZ2Ugb2Ygc3RhZ2VLZXlzOyB0cmFjayBzdGFnZSkge1xuICAgICAgICAgICAgICAgICAgICAgIDxmcy1jaGlwXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9XCJ0aW55XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRDb2xvcl09XCJzdGFnZUNvbG9yKGVudGl0eS5zdGFnZXNbc3RhZ2VdKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPVwiI2ZmZmZmZlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cInN0YWdlVG9vbHRpcChlbnRpdHkuc3RhZ2VzW3N0YWdlXSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IHN0YWdlTGFiZWxzW3N0YWdlXSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvZnMtY2hpcD5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtcGFuZWwtZGVzY3JpcHRpb24+XG4gICAgICAgICAgICAgIDwvbWF0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XG5cbiAgICAgICAgICAgICAgPCEtLSBEZWZlcnJlZDogdGhlIGJvZHkgKGFuZCBpdHMgZnVuY3Rpb25zIHJlcXVlc3QpIG9ubHkgZXhpc3RzXG4gICAgICAgICAgICAgICAgICAgb25jZSBleHBhbmRlZC4gLS0+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBtYXRFeHBhbnNpb25QYW5lbENvbnRlbnQ+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVudGl0eS1kZXRhaWxcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXY+PHN0cm9uZz5UYWJsZTo8L3N0cm9uZz4ge3sgZW50aXR5LnRhYmxlIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICA8ZGl2PjxzdHJvbmc+Q29sdW1uczo8L3N0cm9uZz4ge3sgZW50aXR5LmNvbHVtbnMgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXY+PHN0cm9uZz5SZWxhdGlvbnNoaXBzOjwvc3Ryb25nPiB7eyBlbnRpdHkucmVsYXRpb25zaGlwcyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgQGlmIChlbnRpdHkuZW51bXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlbnVtLWxpc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPkVudW0gdmFsdWVzOjwvc3Ryb25nPlxuICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKGVudW1Db2x1bW4gb2YgZW50aXR5LmVudW1zOyB0cmFjayBlbnVtQ29sdW1uLmNvbHVtbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVudW0tcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZW51bS1jb2x1bW5cIj57eyBlbnVtQ29sdW1uLmNvbHVtbiB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJlbnVtLXZhbHVlc1wiPnt7IGVudW1Db2x1bW4udmFsdWVzLmpvaW4oJywgJykgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgQGlmIChlbnRpdHkuY29tcHV0ZWRGaWVsZHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIDxkaXY+PHN0cm9uZz5Db21wdXRlZCBmaWVsZHM6PC9zdHJvbmc+IHt7IGVudGl0eS5jb21wdXRlZEZpZWxkcy5qb2luKCcsICcpIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdW5jdGlvbnMtc2VjdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJmdW5jdGlvbnMtaGVhZGluZ1wiPlxuICAgICAgICAgICAgICAgICAgICAgIENvZGUgZnVuY3Rpb25zXG4gICAgICAgICAgICAgICAgICAgICAgQGlmIChlbnRpdHkuZnVuY3Rpb25Db3VudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmdW5jdGlvbnMtY291bnRcIj4oe3sgZW50aXR5LmZ1bmN0aW9uQ291bnQgfX0pPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgPC9oMz5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnVuY3Rpb25zLWJvZHlcIiAqZnNTa2VsZXRvbj1cImVudGl0eUZ1bmN0aW9ucyhlbnRpdHkua2V5KVwiPlxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZW50aXR5RnVuY3Rpb25zKGVudGl0eS5rZXkpOyBhcyBmbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZm5zLmZ1bmN0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChmbnMuZ2VuZXJhdGVkQXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGludCBmdW5jdGlvbnMtZ2VuZXJhdGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaXNjb3ZlcmVkIGZyb20ge3sgZm5zLmNsYXNzIH19ICZtaWRkb3Q7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZnMtZGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRlXT1cImZucy5nZW5lcmF0ZWRBdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0PVwiZGF0ZS10aW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2ZzLWRhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZ1bmN0aW9ucy1saXN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGZvciAoZm4gb2YgZm5zLmZ1bmN0aW9uczsgdHJhY2sgZm4ubWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnVuY3Rpb24tcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdW5jdGlvbi1oZWFkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGZzLWNoaXBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT1cInRpbnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZENvbG9yXT1cImtpbmRDb2xvcihmbi5raW5kKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPVwiI2ZmZmZmZlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZm4ua2luZCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZnMtY2hpcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImZ1bmN0aW9uLW1ldGhvZFwiPnt7IGZuLm1ldGhvZCB9fTwvY29kZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdW5jdGlvbi1zdW1tYXJ5XCI+e3sgZm4uc3VtbWFyeSB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGZuLnByb2R1Y2VzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZ1bmN0aW9uLXByb2R1Y2VzIGhpbnRcIj5Qcm9kdWNlczoge3sgZm4ucHJvZHVjZXMgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGludFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vIGZ1bmN0aW9ucyBjYWNoZWQgZm9yIHRoaXMgZW50aXR5IHlldCDigJQgcnVuIGEgYnVpbGQgdG8gZGlzY292ZXIgaXRzIGNvZGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvbWF0LWV4cGFuc2lvbi1wYW5lbD5cbiAgICAgICAgICB9XG4gICAgICAgIDwvbWF0LWFjY29yZGlvbj5cbiAgICAgIH1cbiAgICB9XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=
|
|
202
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VtYW50aWMtZGF0YWJhc2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvZ2xvYmFsLXNldHRpbmdzL2NvbXBvbmVudHMvc2VtYW50aWMtZGF0YWJhc2Uvc2VtYW50aWMtZGF0YWJhc2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvZ2xvYmFsLXNldHRpbmdzL2NvbXBvbmVudHMvc2VtYW50aWMtZGF0YWJhc2Uvc2VtYW50aWMtZGF0YWJhc2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekcsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFaEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTdELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5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MkI7UUFDM0UsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUU7WUFDMUMsS0FBSyxFQUFFLE9BQU87WUFDZCxRQUFRLEVBQUUsTUFBTTtZQUNoQixTQUFTLEVBQUUsTUFBTTtZQUNqQixTQUFTLEVBQUUsS0FBSztZQUNoQixJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUU7U0FDeEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLEtBQUs7UUFDWCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVPLGNBQWM7UUFDcEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxtQkFBbUIsRUFBRTthQUNuQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2FBQzFDLFNBQVMsQ0FBQyxDQUFDLE1BQTJCLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDekUsQ0FBQzt3R0F2TVUseUJBQXlCOzRGQUF6Qix5QkFBeUIsMEdDaER0Qyx1dkxBMklBLDJ2QkRuR0ksa0JBQWtCLHEwQkFDbEIsZ0JBQWdCLDRUQUNoQixZQUFZLHFYQUNaLFlBQVksNElBQ1osZUFBZSx5SEFDZixnQkFBZ0I7OzRGQUdQLHlCQUF5QjtrQkFmckMsU0FBUzsrQkFDRSxnREFBZ0QsbUJBR3pDLHVCQUF1QixDQUFDLE1BQU0sY0FDbkMsSUFBSSxXQUNQO3dCQUNQLGtCQUFrQjt3QkFDbEIsZ0JBQWdCO3dCQUNoQixZQUFZO3dCQUNaLFlBQVk7d0JBQ1osZUFBZTt3QkFDZixnQkFBZ0I7cUJBQ2pCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRGVzdHJveVJlZiwgY29tcHV0ZWQsIGluamVjdCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5cbmltcG9ydCB7IE1hdERpYWxvZyB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBNYXRFeHBhbnNpb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9leHBhbnNpb24nO1xuaW1wb3J0IHsgTWF0VG9vbHRpcE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3Rvb2x0aXAnO1xuXG5pbXBvcnQgeyBTdHJlYW1FdmVudFR5cGUgfSBmcm9tICdAZmlyZXN0aXRjaC9hcGknO1xuaW1wb3J0IHsgRnNDaGlwTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvY2hpcCc7XG5pbXBvcnQgeyBGc0RhdGVNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9kYXRlJztcbmltcG9ydCB7IEZzTWVzc2FnZSwgRnNNZXNzYWdlTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVzc2FnZSc7XG5pbXBvcnQgeyBGc1Byb2Nlc3MgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9jZXNzJztcbmltcG9ydCB7IEZzUHJvbXB0IH0gZnJvbSAnQGZpcmVzdGl0Y2gvcHJvbXB0JztcbmltcG9ydCB7IEZzU2tlbGV0b25Nb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9za2VsZXRvbic7XG5cbmltcG9ydCB7IGZpbHRlciwgbWFwLCBzd2l0Y2hNYXAsIHRha2UsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uLy4uLy4uLy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHtcbiAgU2VtYW50aWNCdWlsZEVudGl0eSxcbiAgU2VtYW50aWNCdWlsZFN0YWdlLFxuICBTZW1hbnRpY0J1aWxkU3RhdHVzLFxufSBmcm9tICcuLi8uLi8uLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgRW50aXR5RnVuY3Rpb25zQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vZW50aXR5LWZ1bmN0aW9ucy9lbnRpdHktZnVuY3Rpb25zLmNvbXBvbmVudCc7XG5cblxuLy8gVGhlIFNlbWFudGljIERhdGFiYXNlIHRhYjogdGhlIGVudGl0eSBzY29yZWJvYXJkIHRoZSByZXBvcnQgQUkgaXMgYnVpbHQgZnJvbVxuLy8gKGFuIGVudGl0eSA9IGEgdGFibGUgKyBhIG1vZGVsICsgYSBoYW5kbGVyKS4gU2hvd3MgdGhlIGxhc3QgYnVpbGQncyBzdGF0dXMsXG4vLyBydW5zIChvciBzdG9wcykgYSBidWlsZCDigJQgc3RyZWFtZWQgaW50byB0aGUgRnNQcm9jZXNzIGRvY2sgc28gaXQgc3Vydml2ZXMgdGhlXG4vLyBkaWFsb2cgY2xvc2luZyDigJQgYW5kIGRyaWxscyBpbnRvIGV2ZXJ5IGVudGl0eSB0byByZXZlYWwgaXRzIHNoYXBlLCBpbmxpbmVkXG4vLyBlbnVtIHZhbHVlcywgY29tcHV0ZWQgZmllbGRzIGFuZCBpdHMgY2FjaGVkIGZ1bmN0aW9uIGNvdW50cywgd2hvc2UgbGlua3Mgb3BlblxuLy8gdGhlIGZ1bmN0aW9ucyBkaWFsb2cgKHRoZSBmdWxsIGZ1bmN0aW9uIHNldCBhY3Jvc3MgYWxsIGVudGl0aWVzIGlzIGZhciB0b29cbi8vIGJpZyB0byBzaGlwIHdpdGggdGhlIHNjb3JlYm9hcmQpLlxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZnMtYWktcmVwb3J0LWdsb2JhbC1zZXR0aW5ncy1zZW1hbnRpYy1kYXRhYmFzZScsXG4gIHRlbXBsYXRlVXJsOiAnLi9zZW1hbnRpYy1kYXRhYmFzZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NlbWFudGljLWRhdGFiYXNlLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgTWF0RXhwYW5zaW9uTW9kdWxlLFxuICAgIE1hdFRvb2x0aXBNb2R1bGUsXG4gICAgRnNDaGlwTW9kdWxlLFxuICAgIEZzRGF0ZU1vZHVsZSxcbiAgICBGc01lc3NhZ2VNb2R1bGUsXG4gICAgRnNTa2VsZXRvbk1vZHVsZSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgU2VtYW50aWNEYXRhYmFzZUNvbXBvbmVudCB7XG5cbiAgLy8gVGhlIGJ1aWxkLWluLWZsaWdodCBzdGF0ZXMgb2YgdGhlIGZmX3Byb2Nlc3NlcyByb3cgKHF1ZXVlZC9ydW5uaW5nL3N0b3BwaW5nKS5cbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQUNUSVZFX1NUQVRFUyA9IFsnUScsICdSJywgJ1gnXTtcblxuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBTVEFURV9MQUJFTFM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgUTogJ1F1ZXVlZCcsXG4gICAgUjogJ1J1bm5pbmcnLFxuICAgIFg6ICdTdG9wcGluZycsXG4gICAgQzogJ0NvbXBsZXRlZCcsXG4gICAgSzogJ1N0b3BwZWQnLFxuICAgIEY6ICdGYWlsZWQnLFxuICB9O1xuXG4gIC8vIFNjb3JlYm9hcmQgY29tcGxldGlvbiBwYWxldHRlOiBidWlsdCA9IGdyZWVuLCBldmVyeXRoaW5nIGVsc2UgKG5lZWRzXG4gIC8vIGJ1aWxkaW5nKSA9IGdyZXkuIE5vIGVycm9yIHJlZCDigJQgYSBtaXNzaW5nIHN0YWdlIGlzIHVuYnVpbHQgY29udGVudCwgbm90IGFcbiAgLy8gZmFpbHVyZS5cbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgRE9ORV9DT0xPUiA9ICcjMmU3ZDMyJztcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgUEVORElOR19DT0xPUiA9ICcjOWU5ZTllJztcblxuICAvLyBUaGUgc2NvcmVib2FyZCdzIHBlci1lbnRpdHkgc3RhZ2UgY2hpcHMsIGxlZnQgdG8gcmlnaHQuXG4gIHB1YmxpYyByZWFkb25seSBzdGFnZUtleXMgPSBbJ2ludHJvc3BlY3RlZCcsICdlbnVtc0lubGluZWQnLCAnY29tcHV0ZWQnLCAnZnVuY3Rpb25zJ107XG5cbiAgcHVibGljIHJlYWRvbmx5IHN0YWdlTGFiZWxzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIGludHJvc3BlY3RlZDogJ0ludHJvc3BlY3RlZCcsXG4gICAgZW51bXNJbmxpbmVkOiAnRW51bSBjYXNlcycsXG4gICAgY29tcHV0ZWQ6ICdDb21wdXRlZCcsXG4gICAgZnVuY3Rpb25zOiAnRnVuY3Rpb25zJyxcbiAgfTtcblxuICAvLyBudWxsIHVudGlsIGxvYWRlZCDigJQgZ2F0ZXMgdGhlIHRhYiBiZWhpbmQgdGhlIHNrZWxldG9uLlxuICBwdWJsaWMgcmVhZG9ubHkgc3RhdHVzID0gc2lnbmFsPFNlbWFudGljQnVpbGRTdGF0dXMgfCBudWxsPihudWxsKTtcblxuICAvLyBUcnVlIHdoaWxlIGEgYnVpbGQgc3RhcnRlZCBmcm9tIHRoaXMgdGFiIGlzIHN0cmVhbWluZyBpbnRvIHRoZSBkb2NrLlxuICBwdWJsaWMgcmVhZG9ubHkgYnVpbGRpbmcgPSBzaWduYWwoZmFsc2UpO1xuXG4gIHB1YmxpYyByZWFkb25seSBidWlsZEFjdGl2ZSA9IGNvbXB1dGVkPGJvb2xlYW4+KCgpID0+XG4gICAgdGhpcy5idWlsZGluZygpXG4gICAgICB8fCBTZW1hbnRpY0RhdGFiYXNlQ29tcG9uZW50LkFDVElWRV9TVEFURVMuaW5jbHVkZXModGhpcy5zdGF0dXMoKT8uYnVpbGQ/LnN0YXRlKSxcbiAgKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgYnVpbGRTdGF0ZUxhYmVsID0gY29tcHV0ZWQ8c3RyaW5nPigoKSA9PlxuICAgIFNlbWFudGljRGF0YWJhc2VDb21wb25lbnQuU1RBVEVfTEFCRUxTW3RoaXMuc3RhdHVzKCk/LmJ1aWxkPy5zdGF0ZV0gPz8gJycsXG4gICk7XG5cbiAgLy8gR3VhcmRzIHRoZSBvdXRjb21lIG1lc3NhZ2UgdG8gZmlyZSBleGFjdGx5IG9uY2UgcGVyIHJ1biDigJQgd2hldGhlciB0aGUgc3RyZWFtXG4gIC8vIGNvbXBsZXRlcyAoYnVpbGQgZmluaXNoZWQsIHBvc3NpYmx5IGZhaWxlZCkgb3IgZXJyb3JzIG91dHJpZ2h0LlxuICBwcml2YXRlIF9idWlsZEZpbmFsaXplZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2RpYWxvZyA9IGluamVjdChNYXREaWFsb2cpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9yZXBvcnREYXRhID0gaW5qZWN0KFJlcG9ydERhdGEpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9wcm9jZXNzID0gaW5qZWN0KEZzUHJvY2Vzcyk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3Byb21wdCA9IGluamVjdChGc1Byb21wdCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX21lc3NhZ2UgPSBpbmplY3QoRnNNZXNzYWdlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9pbml0KCk7XG4gIH1cblxuICAvLyBDb25maXJtIGJlZm9yZSBraWNraW5nIG9mZiBhIGJ1aWxkIOKAlCBhIHJlYnVpbGQgcmVwbGFjZXMgdGhlIGN1cnJlbnRcbiAgLy8gc2VtYW50aWMgZGF0YWJhc2UsIHNvIGl0IHNob3VsZCBuZXZlciBmaXJlIG9uIGEgc3RyYXkgY2xpY2suXG4gIHB1YmxpYyBidWlsZCgpOiB2b2lkIHtcbiAgICBjb25zdCByZWJ1aWxkID0gISF0aGlzLnN0YXR1cygpPy5kZXRhaWw/LmdlbmVyYXRlZEF0O1xuXG4gICAgdGhpcy5fcHJvbXB0LmNvbmZpcm0oe1xuICAgICAgdGl0bGU6IHJlYnVpbGQgPyAnUmVidWlsZCBzZW1hbnRpYyBkYXRhYmFzZScgOiAnQnVpbGQgc2VtYW50aWMgZGF0YWJhc2UnLFxuICAgICAgdGVtcGxhdGU6IHJlYnVpbGRcbiAgICAgICAgPyAnUmVidWlsZCB0aGUgc2VtYW50aWMgZGF0YWJhc2U/IEl0IHJ1bnMgaW4gdGhlIGJhY2tncm91bmQgYW5kIHJlcGxhY2VzIHRoZSBjdXJyZW50IG9uZSB3aGVuIGl0IGZpbmlzaGVzLidcbiAgICAgICAgOiAnQnVpbGQgdGhlIHNlbWFudGljIGRhdGFiYXNlPyBJdCBydW5zIGluIHRoZSBiYWNrZ3JvdW5kLicsXG4gICAgICBjb21taXRMYWJlbDogcmVidWlsZCA/ICdSZWJ1aWxkJyA6ICdCdWlsZCcsXG4gICAgfSlcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fcnVuQnVpbGQoKSk7XG4gIH1cblxuICBwdWJsaWMgc3RvcEJ1aWxkKCk6IHZvaWQge1xuICAgIHRoaXMuX3Byb21wdC5jb25maXJtKHtcbiAgICAgIHRpdGxlOiAnU3RvcCBidWlsZCcsXG4gICAgICB0ZW1wbGF0ZTogJ1N0b3AgdGhlIHJ1bm5pbmcgYnVpbGQ/IFRoZSBjdXJyZW50IHNlbWFudGljIGRhdGFiYXNlIHN0YXlzIGluIHBsYWNlIHVudGlsIGEgYnVpbGQgZmluaXNoZXMuJyxcbiAgICAgIGNvbW1pdExhYmVsOiAnU3RvcCcsXG4gICAgfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5fcmVwb3J0RGF0YS5zZW1hbnRpY0J1aWxkU3RvcCgpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuYnVpbGRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdTdG9wcGluZyB0aGUgYnVpbGTigKYnKTtcbiAgICAgICAgdGhpcy5fcmVmcmVzaFN0YXR1cygpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBSdW4gdGhlIHNlbWFudGljLWRhdGFiYXNlIGJ1aWxkLiBUaGUgbGl2ZSBmZWVkIHN0cmVhbXMgaW50byB0aGUgRnNQcm9jZXNzXG4gIC8vIGRvY2sgKGJvdHRvbS1yaWdodCksIHdob3NlIHN1YnNjcmlwdGlvbiBzdXJ2aXZlcyB0aGlzIGRpYWxvZyBjbG9zaW5nIOKAlCBzb1xuICAvLyBkaXNtaXNzaW5nIHRoZSBkaWFsb2cgbmV2ZXIgaW50ZXJydXB0cyBhIHJ1bm5pbmcgYnVpbGQuXG4gIHByaXZhdGUgX3J1bkJ1aWxkKCk6IHZvaWQge1xuICAgIHRoaXMuYnVpbGRpbmcuc2V0KHRydWUpO1xuICAgIHRoaXMuX2J1aWxkRmluYWxpemVkID0gZmFsc2U7XG5cbiAgICBjb25zdCB0YXJnZXQkID0gdGhpcy5fcmVwb3J0RGF0YS5zZW1hbnRpY0J1aWxkKClcbiAgICAgIC5waXBlKFxuICAgICAgICAvLyBBIGhhcmQgc3RyZWFtL3RyYW5zcG9ydCBmYWlsdXJlICh0aGUgYnVpbGQgY291bGRuJ3QgZXZlbiBzdGFydClcbiAgICAgICAgLy8gZmluYWxpemVzIGhlcmUg4oCUIGNvbXBsZXRlZCQgd29uJ3QgZmlyZSBpbiB0aGF0IGNhc2UuXG4gICAgICAgIHRhcCh7IGVycm9yOiAoZXJyb3IpID0+IHRoaXMuX2ZpbmFsaXplQnVpbGQoZXJyb3IpIH0pLFxuICAgICAgICBmaWx0ZXIoKGV2ZW50KSA9PlxuICAgICAgICAgIGV2ZW50Py50eXBlID09PSBTdHJlYW1FdmVudFR5cGUuRGF0YVxuICAgICAgICAgICYmIGV2ZW50LmRhdGE/LmtpbmQgPT09ICdsb2cnXG4gICAgICAgICAgJiYgdHlwZW9mIGV2ZW50LmRhdGEubGluZSA9PT0gJ3N0cmluZycpLFxuICAgICAgICBtYXAoKGV2ZW50KSA9PiBldmVudC5kYXRhLmxpbmUgYXMgc3RyaW5nKSxcbiAgICAgICk7XG5cbiAgICB0aGlzLl9wcm9jZXNzXG4gICAgICAucnVuKCdTZW1hbnRpYyBkYXRhYmFzZSBidWlsZCcsIHRhcmdldCQpXG4gICAgICAuY29tcGxldGVkJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2UoMSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fZmluYWxpemVCdWlsZChudWxsKSk7XG4gIH1cblxuICAvKipcbiAgICogV3JhcCB1cCBvbmUgYnVpbGQgcnVuIGV4YWN0bHkgb25jZS4gT24gYSBoYXJkIHN0cmVhbSBlcnJvciB0aGVyZSBpcyBub1xuICAgKiBzdGF0dXMgdG8gcmVhZCwgc28gc2F5IHNvIGRpcmVjdGx5OyBvdGhlcndpc2UgcmVmcmVzaCB0aGUgc3RhdHVzIGFuZFxuICAgKiBhbm5vdW5jZSBob3cgdGhlIGJ1aWxkIGFjdHVhbGx5IGVuZGVkIOKAlCBhIGJ1aWxkIHRoYXQgZmFpbGVkIChlLmcuIHRoZSBBSVxuICAgKiBjb3VsZG4ndCBiZSByZWFjaGVkKSByZXBvcnRzICdGYWlsZWQnIHdpdGggYSByZWFzb24sIGFuZCB0aGF0IG11c3Qgc3VyZmFjZVxuICAgKiBpbnN0ZWFkIG9mIHRoZSBydW4gc2lsZW50bHkgZG9pbmcgbm90aGluZy5cbiAgICovXG4gIHByaXZhdGUgX2ZpbmFsaXplQnVpbGQoc3RyZWFtRXJyb3I6IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fYnVpbGRGaW5hbGl6ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fYnVpbGRGaW5hbGl6ZWQgPSB0cnVlO1xuXG4gICAgdGhpcy5idWlsZGluZy5zZXQoZmFsc2UpO1xuXG4gICAgaWYgKHN0cmVhbUVycm9yKSB7XG4gICAgICB0aGlzLl9tZXNzYWdlLmVycm9yKCdUaGUgc2VtYW50aWMgZGF0YWJhc2UgYnVpbGQgY291bGQgbm90IHJ1biDigJQgY2hlY2sgdGhlIEFJIGNvbm5lY3Rpb24gYW5kIHRyeSBhZ2Fpbi4nKTtcbiAgICAgIHRoaXMuX3JlZnJlc2hTdGF0dXMoKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3JlcG9ydERhdGEuc2VtYW50aWNCdWlsZFN0YXR1cygpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChzdGF0dXM6IFNlbWFudGljQnVpbGRTdGF0dXMpID0+IHtcbiAgICAgICAgdGhpcy5zdGF0dXMuc2V0KHN0YXR1cyk7XG4gICAgICAgIHRoaXMuX2Fubm91bmNlT3V0Y29tZShzdGF0dXMpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVGVsbCB0aGUgb3BlcmF0b3IgaG93IHRoZSBidWlsZCBlbmRlZDogYSBmYWlsZWQvc3RvcHBlZCBidWlsZCBzdXJmYWNlcyBpdHNcbiAgICogcmVhc29uIChzbyBhbiBBSSBjb25uZWN0aW9uIHByb2JsZW0gaXMgbmV2ZXIgc2lsZW50KSwgYSBjb21wbGV0ZWQgb25lXG4gICAqIGNvbmZpcm1zIHN1Y2Nlc3MuXG4gICAqL1xuICBwcml2YXRlIF9hbm5vdW5jZU91dGNvbWUoc3RhdHVzOiBTZW1hbnRpY0J1aWxkU3RhdHVzKTogdm9pZCB7XG4gICAgY29uc3QgYnVpbGQgPSBzdGF0dXM/LmJ1aWxkO1xuICAgIGlmIChidWlsZD8uc3RhdGUgPT09ICdGJyB8fCBidWlsZD8uc3RhdGUgPT09ICdLJykge1xuICAgICAgdGhpcy5fbWVzc2FnZS5lcnJvcihidWlsZC5tZXNzYWdlIHx8ICdUaGUgc2VtYW50aWMgZGF0YWJhc2UgYnVpbGQgZGlkIG5vdCBmaW5pc2guJyk7XG4gICAgfSBlbHNlIGlmIChidWlsZD8uc3RhdGUgPT09ICdDJykge1xuICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdTZW1hbnRpYyBkYXRhYmFzZSBidWlsZCBjb21wbGV0ZS4nKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc3RhZ2VDb2xvcihzdGFnZTogU2VtYW50aWNCdWlsZFN0YWdlKTogc3RyaW5nIHtcbiAgICByZXR1cm4gc3RhZ2UgPT09ICdkb25lJ1xuICAgICAgPyBTZW1hbnRpY0RhdGFiYXNlQ29tcG9uZW50LkRPTkVfQ09MT1JcbiAgICAgIDogU2VtYW50aWNEYXRhYmFzZUNvbXBvbmVudC5QRU5ESU5HX0NPTE9SO1xuICB9XG5cbiAgcHVibGljIHN0YWdlVG9vbHRpcChzdGFnZTogU2VtYW50aWNCdWlsZFN0YWdlKTogc3RyaW5nIHtcbiAgICByZXR1cm4gc3RhZ2UgPT09ICdkb25lJyA/ICdCdWlsdCcgOiAnTmVlZHMgYnVpbGRpbmcnO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW4gdGhlIGNoaWxkIGRpYWxvZyBsaXN0aW5nIG9uZSBncm91cCBvZiBhbiBlbnRpdHkncyBjYWNoZWQgZnVuY3Rpb25zIOKAlFxuICAgKiB0aGUgbW9kZWwgY2xhc3MncyBvciB0aGUgaGFuZGxlciBjbGFzcydzLiBUaGUgZGlhbG9nIGZldGNoZXMgZnJlc2ggb24gb3BlbixcbiAgICogc28gdGhlIHRhYiBuZXZlciBob2xkcyBmdW5jdGlvbiBwYXlsb2Fkcy5cbiAgICovXG4gIHB1YmxpYyBvcGVuRnVuY3Rpb25zKGVudGl0eTogU2VtYW50aWNCdWlsZEVudGl0eSwgc291cmNlOiAnbW9kZWwnIHwgJ2hhbmRsZXInKTogdm9pZCB7XG4gICAgdGhpcy5fZGlhbG9nLm9wZW4oRW50aXR5RnVuY3Rpb25zQ29tcG9uZW50LCB7XG4gICAgICB3aWR0aDogJzcwMHB4JyxcbiAgICAgIG1heFdpZHRoOiAnOTV2dycsXG4gICAgICBtYXhIZWlnaHQ6ICc4NXZoJyxcbiAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgICBkYXRhOiB7IGVudGl0eUtleTogZW50aXR5LmtleSwgc291cmNlIH0sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9pbml0KCk6IHZvaWQge1xuICAgIHRoaXMuX3JlZnJlc2hTdGF0dXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlZnJlc2hTdGF0dXMoKTogdm9pZCB7XG4gICAgdGhpcy5fcmVwb3J0RGF0YS5zZW1hbnRpY0J1aWxkU3RhdHVzKClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKHN0YXR1czogU2VtYW50aWNCdWlsZFN0YXR1cykgPT4gdGhpcy5zdGF0dXMuc2V0KHN0YXR1cykpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiZnMtY29sdW1uIHRhYi1ib2R5XCI+XG4gIDxwIGNsYXNzPVwiaGludFwiPlxuICAgIFRoZSBzZW1hbnRpYyBkYXRhYmFzZSBpcyB3aGF0IHRoZSByZXBvcnQgQUkgdXNlcyB0byB1bmRlcnN0YW5kIHlvdXIgZGF0YSDigJRcbiAgICB0YWJsZXMsIHJlbGF0aW9uc2hpcHMgYW5kIHRoZSBjYWxjdWxhdGlvbnMgaW4gY29kZS4gUmVidWlsZCBpdCBhZnRlclxuICAgIHNpZ25pZmljYW50IGFwcGxpY2F0aW9uIHVwZGF0ZXMuIFRoZSBidWlsZCBydW5zIGluIHRoZSBiYWNrZ3JvdW5kOyBwcm9ncmVzc1xuICAgIGFwcGVhcnMgaW4gdGhlIGRvY2sgYXQgdGhlIGJvdHRvbSByaWdodCBhbmQgdGhpcyBkaWFsb2cgY2FuIGJlIGNsb3NlZCB3aGlsZVxuICAgIGl0IHJ1bnMuXG4gIDwvcD5cblxuICA8ZGl2ICpmc1NrZWxldG9uPVwic3RhdHVzKClcIj5cbiAgICBAaWYgKHN0YXR1cygpOyBhcyBidWlsZFN0YXR1cykge1xuICAgICAgPGRpdiBjbGFzcz1cImJ1aWxkLXN0YXR1c1wiPlxuICAgICAgICBAaWYgKGJ1aWxkU3RhdHVzLmRldGFpbC5nZW5lcmF0ZWRBdCkge1xuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxhYmVsXCI+TGFzdCBidWlsdDwvc3Bhbj5cbiAgICAgICAgICAgIDxmcy1kYXRlXG4gICAgICAgICAgICAgICAgW2RhdGVdPVwiYnVpbGRTdGF0dXMuZGV0YWlsLmdlbmVyYXRlZEF0XCJcbiAgICAgICAgICAgICAgICBmb3JtYXQ9XCJkYXRlLXRpbWVcIj5cbiAgICAgICAgICAgIDwvZnMtZGF0ZT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdFwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbFwiPkNvdmVyYWdlPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgIHt7IGJ1aWxkU3RhdHVzLmRldGFpbC5lbnRpdHlDb3VudCB9fSBlbnRpdGllcyDCt1xuICAgICAgICAgICAgICB7eyBidWlsZFN0YXR1cy5kZXRhaWwuZnVuY3Rpb25Db3VudCB9fSBjb2RlIGZ1bmN0aW9uc1xuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICA8ZnMtbWVzc2FnZS13YXJuaW5nPlxuICAgICAgICAgICAgVGhlIHNlbWFudGljIGRhdGFiYXNlIGhhcyBub3QgYmVlbiBidWlsdCB5ZXQg4oCUIHRoZSByZXBvcnQgQUkgY2FuJ3RcbiAgICAgICAgICAgIGFuc3dlciBkYXRhIHF1ZXN0aW9ucyB1bnRpbCBpdCBpcy4gUnVuIHRoZSBmaXJzdCBidWlsZC5cbiAgICAgICAgICA8L2ZzLW1lc3NhZ2Utd2FybmluZz5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGJ1aWxkU3RhdHVzLmJ1aWxkKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInN0YXRcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGFiZWxcIj5MYXN0IGJ1aWxkIHJ1bjwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICB7eyBidWlsZFN0YXRlTGFiZWwoKSB9fVxuICAgICAgICAgICAgICBAaWYgKGJ1aWxkU3RhdHVzLmJ1aWxkLm1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICDigJQge3sgYnVpbGRTdGF0dXMuYnVpbGQubWVzc2FnZSB9fVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRoZSBlbnRpdHkgc2NvcmVib2FyZDogZXZlcnkgZW50aXR5IHRoZSBBSSBrbm93cyBhYm91dCAoYW4gZW50aXR5ID1cbiAgICAgICAgICAgYSB0YWJsZSArIGEgbW9kZWwgKyBhIGhhbmRsZXIpLCBpdHMgYnVpbHQtdnMtbmVlZHMtYnVpbGRpbmcgc3RhZ2VzLFxuICAgICAgICAgICBhbmQgYSBkcmlsbC1kb3duIGludG8gaXRzIHNoYXBlLCBlbnVtIHZhbHVlcywgY29tcHV0ZWQgZmllbGRzIGFuZFxuICAgICAgICAgICBjYWNoZWQgZnVuY3Rpb24gY291bnRzIOKAlCB0aGUgY291bnRzIGxpbmsgaW50byB0aGUgZnVuY3Rpb25zIGRpYWxvZy4gLS0+XG4gICAgICBAaWYgKGJ1aWxkU3RhdHVzLmRldGFpbC5lbnRpdGllcz8ubGVuZ3RoKSB7XG4gICAgICAgIDxoMj5FbnRpdGllczwvaDI+XG4gICAgICAgIDxtYXQtYWNjb3JkaW9uIGNsYXNzPVwiZW50aXRpZXNcIj5cbiAgICAgICAgICBAZm9yIChlbnRpdHkgb2YgYnVpbGRTdGF0dXMuZGV0YWlsLmVudGl0aWVzOyB0cmFjayBlbnRpdHkua2V5KSB7XG4gICAgICAgICAgICA8bWF0LWV4cGFuc2lvbi1wYW5lbD5cbiAgICAgICAgICAgICAgPG1hdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxuICAgICAgICAgICAgICAgIDxtYXQtcGFuZWwtdGl0bGU+e3sgZW50aXR5LmtleSB9fTwvbWF0LXBhbmVsLXRpdGxlPlxuICAgICAgICAgICAgICAgIDxtYXQtcGFuZWwtZGVzY3JpcHRpb24+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhZ2UtY2hpcHNcIj5cbiAgICAgICAgICAgICAgICAgICAgQGZvciAoc3RhZ2Ugb2Ygc3RhZ2VLZXlzOyB0cmFjayBzdGFnZSkge1xuICAgICAgICAgICAgICAgICAgICAgIDxmcy1jaGlwXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9XCJ0aW55XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRDb2xvcl09XCJzdGFnZUNvbG9yKGVudGl0eS5zdGFnZXNbc3RhZ2VdKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPVwiI2ZmZmZmZlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cInN0YWdlVG9vbHRpcChlbnRpdHkuc3RhZ2VzW3N0YWdlXSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IHN0YWdlTGFiZWxzW3N0YWdlXSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvZnMtY2hpcD5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtcGFuZWwtZGVzY3JpcHRpb24+XG4gICAgICAgICAgICAgIDwvbWF0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XG5cbiAgICAgICAgICAgICAgPCEtLSBEZWZlcnJlZDogdGhlIGJvZHkgb25seSBleGlzdHMgb25jZSBleHBhbmRlZC4gLS0+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBtYXRFeHBhbnNpb25QYW5lbENvbnRlbnQ+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVudGl0eS1kZXRhaWxcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGFiZWxcIj5UYWJsZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgZW50aXR5LnRhYmxlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdFwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxhYmVsXCI+Q29sdW1uczwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgZW50aXR5LmNvbHVtbnMgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGFiZWxcIj5SZWxhdGlvbnNoaXBzPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBlbnRpdHkucmVsYXRpb25zaGlwcyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgQGlmIChlbnRpdHkuZW51bXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbFwiPkVudW1lcmF0aW9uIHZhbHVlczwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW51bS1saXN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChlbnVtQ29sdW1uIG9mIGVudGl0eS5lbnVtczsgdHJhY2sgZW51bUNvbHVtbi5jb2x1bW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVudW0tcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJlbnVtLWNvbHVtblwiPnt7IGVudW1Db2x1bW4uY29sdW1uIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGVudW1Db2x1bW4udmFsdWVzLmpvaW4oJywgJykgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIEBpZiAoZW50aXR5LmNvbXB1dGVkRmllbGRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGFiZWxcIj5Db21wdXRlZCBmaWVsZHM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgZW50aXR5LmNvbXB1dGVkRmllbGRzLmpvaW4oJywgJykgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0YXRcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbFwiPk1vZGVsIGZ1bmN0aW9uczwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgQGlmIChlbnRpdHkubW9kZWxGdW5jdGlvbkNvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb3VudC1saW5rXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wZW5GdW5jdGlvbnMoZW50aXR5LCAnbW9kZWwnKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgZW50aXR5Lm1vZGVsRnVuY3Rpb25Db3VudCB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4+MDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdFwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxhYmVsXCI+SGFuZGxlciBmdW5jdGlvbnM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoZW50aXR5LmhhbmRsZXJGdW5jdGlvbkNvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb3VudC1saW5rXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wZW5GdW5jdGlvbnMoZW50aXR5LCAnaGFuZGxlcicpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBlbnRpdHkuaGFuZGxlckZ1bmN0aW9uQ291bnQgfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPjA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPC9tYXQtZXhwYW5zaW9uLXBhbmVsPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9tYXQtYWNjb3JkaW9uPlxuICAgICAgfVxuICAgIH1cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==
|