@myrmidon/gve-core 0.0.1
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 +83 -0
- package/esm2022/lib/components/animation-timeline/animation-timeline.component.mjs +176 -0
- package/esm2022/lib/components/animation-tween/animation-tween.component.mjs +161 -0
- package/esm2022/lib/components/animation-vars/animation-vars.component.mjs +141 -0
- package/esm2022/lib/components/base-text-char/base-text-char.component.mjs +37 -0
- package/esm2022/lib/components/base-text-editor/base-text-editor.component.mjs +111 -0
- package/esm2022/lib/components/base-text-view/base-text-view.component.mjs +125 -0
- package/esm2022/lib/components/chain-operation-editor/chain-operation-editor.component.mjs +512 -0
- package/esm2022/lib/components/chain-result-view/chain-result-view.component.mjs +190 -0
- package/esm2022/lib/components/feature-editor/feature-editor.component.mjs +185 -0
- package/esm2022/lib/components/feature-set-editor/feature-set-editor.component.mjs +152 -0
- package/esm2022/lib/components/feature-set-view/feature-set-view.component.mjs +80 -0
- package/esm2022/lib/components/ln-heights-editor/ln-heights-editor.component.mjs +95 -0
- package/esm2022/lib/components/operation-source-editor/operation-source-editor.component.mjs +106 -0
- package/esm2022/lib/components/simple-tree/simple-tree.component.mjs +56 -0
- package/esm2022/lib/components/snapshot-editor/snapshot-editor.component.mjs +510 -0
- package/esm2022/lib/components/steps-map/steps-map.component.mjs +55 -0
- package/esm2022/lib/models.mjs +2 -0
- package/esm2022/lib/services/gve-api.service.mjs +52 -0
- package/esm2022/lib/services/settings.service.mjs +86 -0
- package/esm2022/lib/validators/svg-validators.mjs +28 -0
- package/esm2022/myrmidon-gve-core.mjs +5 -0
- package/esm2022/public-api.mjs +23 -0
- package/fesm2022/myrmidon-gve-core.mjs +2592 -0
- package/fesm2022/myrmidon-gve-core.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/components/animation-timeline/animation-timeline.component.d.ts +42 -0
- package/lib/components/animation-tween/animation-tween.component.d.ts +47 -0
- package/lib/components/animation-vars/animation-vars.component.d.ts +30 -0
- package/lib/components/base-text-char/base-text-char.component.d.ts +29 -0
- package/lib/components/base-text-editor/base-text-editor.component.d.ts +40 -0
- package/lib/components/base-text-view/base-text-view.component.d.ts +29 -0
- package/lib/components/chain-operation-editor/chain-operation-editor.component.d.ts +102 -0
- package/lib/components/chain-result-view/chain-result-view.component.d.ts +44 -0
- package/lib/components/feature-editor/feature-editor.component.d.ts +72 -0
- package/lib/components/feature-set-editor/feature-set-editor.component.d.ts +55 -0
- package/lib/components/feature-set-view/feature-set-view.component.d.ts +36 -0
- package/lib/components/ln-heights-editor/ln-heights-editor.component.d.ts +22 -0
- package/lib/components/operation-source-editor/operation-source-editor.component.d.ts +24 -0
- package/lib/components/simple-tree/simple-tree.component.d.ts +16 -0
- package/lib/components/snapshot-editor/snapshot-editor.component.d.ts +105 -0
- package/lib/components/steps-map/steps-map.component.d.ts +29 -0
- package/lib/models.d.ts +7 -0
- package/lib/services/gve-api.service.d.ts +57 -0
- package/lib/services/settings.service.d.ts +53 -0
- package/lib/validators/svg-validators.d.ts +4 -0
- package/package.json +45 -0
- package/public-api.d.ts +19 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component, EventEmitter, Input, Output, } from '@angular/core';
|
|
3
|
+
import { ReactiveFormsModule } from '@angular/forms';
|
|
4
|
+
import { debounceTime, distinctUntilChanged } from 'rxjs';
|
|
5
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
6
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
7
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
8
|
+
import { MatSelectModule } from '@angular/material/select';
|
|
9
|
+
import { FeatureSetViewComponent } from '../feature-set-view/feature-set-view.component';
|
|
10
|
+
import { StepsMapComponent } from '../steps-map/steps-map.component';
|
|
11
|
+
import { BaseTextViewComponent, } from '../base-text-view/base-text-view.component';
|
|
12
|
+
import * as i0 from "@angular/core";
|
|
13
|
+
import * as i1 from "@angular/forms";
|
|
14
|
+
import * as i2 from "@angular/common";
|
|
15
|
+
import * as i3 from "@angular/material/form-field";
|
|
16
|
+
import * as i4 from "@angular/material/select";
|
|
17
|
+
import * as i5 from "@angular/material/core";
|
|
18
|
+
/**
|
|
19
|
+
* Component to display a chain result.
|
|
20
|
+
*/
|
|
21
|
+
export class ChainResultViewComponent {
|
|
22
|
+
/**
|
|
23
|
+
* The result to display.
|
|
24
|
+
*/
|
|
25
|
+
get result() {
|
|
26
|
+
return this._result;
|
|
27
|
+
}
|
|
28
|
+
set result(value) {
|
|
29
|
+
if (this._result === value) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
this._result = value || undefined;
|
|
33
|
+
this.updateForm(this._result);
|
|
34
|
+
// select last step by default
|
|
35
|
+
if (this._result?.steps?.length) {
|
|
36
|
+
this._stepPickFrozen = true;
|
|
37
|
+
this.step = this._result.steps[this._result.steps.length - 1];
|
|
38
|
+
this.tag.setValue(this.step.outputTag);
|
|
39
|
+
this._stepPickFrozen = false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
constructor(formBuilder) {
|
|
43
|
+
/**
|
|
44
|
+
* Emits when a result's step is picked.
|
|
45
|
+
*/
|
|
46
|
+
this.stepPick = new EventEmitter();
|
|
47
|
+
this.versionTags = [];
|
|
48
|
+
this.tags = [];
|
|
49
|
+
this.selectionFeatures = [];
|
|
50
|
+
this.versionTag = formBuilder.control(null);
|
|
51
|
+
this.tag = formBuilder.control(null);
|
|
52
|
+
}
|
|
53
|
+
ngOnInit() {
|
|
54
|
+
this._subs = [
|
|
55
|
+
this.versionTag.valueChanges
|
|
56
|
+
.pipe(distinctUntilChanged(), debounceTime(200))
|
|
57
|
+
.subscribe((value) => {
|
|
58
|
+
this.tag.setValue(this.getTagFromVersion(value) || null);
|
|
59
|
+
}),
|
|
60
|
+
this.tag.valueChanges
|
|
61
|
+
.pipe(distinctUntilChanged(), debounceTime(200))
|
|
62
|
+
.subscribe((value) => {
|
|
63
|
+
this.step = this._result?.steps.find((step) => step.outputTag === value);
|
|
64
|
+
if (this.step && !this._stepPickFrozen) {
|
|
65
|
+
this.stepPick.emit(this.step);
|
|
66
|
+
}
|
|
67
|
+
}),
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
ngOnDestroy() {
|
|
71
|
+
this._subs?.forEach((sub) => sub.unsubscribe());
|
|
72
|
+
}
|
|
73
|
+
updateVersionTags() {
|
|
74
|
+
if (!this._result) {
|
|
75
|
+
this.versionTags = [];
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// extract version tags from result steps features named 'version'
|
|
79
|
+
const tags = new Set();
|
|
80
|
+
for (const step of this._result.steps) {
|
|
81
|
+
for (const feature of step.featureSet.features) {
|
|
82
|
+
if (feature.name === 'version') {
|
|
83
|
+
tags.add(feature.value);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
this.versionTags = Array.from(tags).sort();
|
|
88
|
+
}
|
|
89
|
+
getTagFromVersion(version) {
|
|
90
|
+
if (!this._result || !version) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
for (const step of this._result.steps) {
|
|
94
|
+
for (const feature of step.featureSet.features) {
|
|
95
|
+
if (feature.name === 'version' && feature.value === version) {
|
|
96
|
+
return step.outputTag;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
updateForm(result) {
|
|
103
|
+
this.selectionFeatures = [];
|
|
104
|
+
if (!result) {
|
|
105
|
+
this.step = undefined;
|
|
106
|
+
this.selection = undefined;
|
|
107
|
+
this.tags = [];
|
|
108
|
+
this.versionTags = [];
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
this.tags = result.chainTags;
|
|
112
|
+
this.updateVersionTags();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
getNodeFeatures(id) {
|
|
116
|
+
if (!this.step) {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
return (this.step.featureSet.nodeFeatures[this.step.outputTag + '_' + id] || []);
|
|
120
|
+
}
|
|
121
|
+
findNode(id) {
|
|
122
|
+
if (!this.step) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
for (let key of Object.keys(this._result.taggedNodes)) {
|
|
126
|
+
const node = this._result.taggedNodes[key].find((n) => n.id === id);
|
|
127
|
+
if (node) {
|
|
128
|
+
return node;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
onStepCharPick(event) {
|
|
134
|
+
const features = this.getNodeFeatures(event.char.id);
|
|
135
|
+
const node = this.findNode(event.char.id);
|
|
136
|
+
this.selection = `${event.char.label} (${node.sourceTag})`;
|
|
137
|
+
this.selectionFeatures = [...features];
|
|
138
|
+
}
|
|
139
|
+
onStepRangePick(range) {
|
|
140
|
+
if (range.run === 1) {
|
|
141
|
+
// already handled by onStepCharPick
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
this.selection = range.at + '×' + range.run;
|
|
145
|
+
const end = range.at + range.run;
|
|
146
|
+
const features = [];
|
|
147
|
+
const tagNodes = this._result.taggedNodes[this.tag.value];
|
|
148
|
+
for (let node of tagNodes) {
|
|
149
|
+
// if in range, intersect features
|
|
150
|
+
if (node.id >= range.at && node.id < end) {
|
|
151
|
+
const nodeFeatures = this.getNodeFeatures(node.id);
|
|
152
|
+
if (node.id === range.at) {
|
|
153
|
+
for (let f of nodeFeatures) {
|
|
154
|
+
features.push(f);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// features = intersection of features and charFeatures
|
|
159
|
+
features.splice(0, features.length, ...features.filter((f) => nodeFeatures.some((cf) => cf.name === f.name)));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
this.selectionFeatures = features;
|
|
164
|
+
}
|
|
165
|
+
onStepChange(step) {
|
|
166
|
+
this.tag.setValue(step.outputTag);
|
|
167
|
+
this.selectionFeatures = [];
|
|
168
|
+
}
|
|
169
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ChainResultViewComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
170
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.4", type: ChainResultViewComponent, isStandalone: true, selector: "gve-chain-result-view", inputs: { result: "result" }, outputs: { stepPick: "stepPick" }, ngImport: i0, template: "@if (result) {\r\n<div id=\"container\">\r\n <div id=\"bar\" class=\"form-row\">\r\n <!-- version -->\r\n <mat-form-field *ngIf=\"versionTags?.length\">\r\n <mat-label>version</mat-label>\r\n <mat-select [formControl]=\"versionTag\">\r\n <mat-option [value]=\"null\">-</mat-option>\r\n <mat-option *ngFor=\"let t of versionTags\" [value]=\"t\">{{\r\n t\r\n }}</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <!-- tag -->\r\n <mat-form-field *ngIf=\"tags?.length\">\r\n <mat-label>tag</mat-label>\r\n <mat-select [formControl]=\"tag\">\r\n <mat-option *ngFor=\"let t of tags\" [value]=\"t\">{{ t }}</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- step -->\r\n @if (step) {\r\n <div id=\"step\">\r\n <!-- text -->\r\n <div id=\"text\">\r\n <gve-base-text-view\r\n [text]=\"result.taggedNodes[step.outputTag]\"\r\n (charPick)=\"onStepCharPick($event)\"\r\n (rangePick)=\"onStepRangePick($event)\"\r\n />\r\n </div>\r\n <!-- features -->\r\n <div id=\"feats\" class=\"form-row-top\">\r\n <div id=\"g-feats\">\r\n <div class=\"feat-header\">{{ step.outputTag }}</div>\r\n <gve-feature-set-view [features]=\"step.featureSet.features\" />\r\n </div>\r\n <div id=\"n-feats\">\r\n @if (selectionFeatures.length) {\r\n <div class=\"feat-header\">{{ selection }}</div>\r\n <gve-feature-set-view [features]=\"selectionFeatures\" />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- steps map -->\r\n <div id=\"map\">\r\n <gve-steps-map\r\n [steps]=\"result.steps\"\r\n [selectedStep]=\"step\"\r\n (selectedStepChange)=\"onStepChange($event)\"\r\n />\r\n </div>\r\n</div>\r\n}\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.form-row-top{display:flex;gap:8px;align-items:start;flex-wrap:wrap}div#container{display:grid;grid-template-rows:auto 1fr;grid-template-columns:3fr 1fr;grid-template-areas:\"bar map\" \"step map\";gap:8px}div#bar{grid-area:bar}div#map{grid-area:map}div#step{grid-area:step}.feat-header{background-color:#3e92cc;color:#fff;text-align:center;border:1px solid #3e92cc;border-top-left-radius:4px;border-top-right-radius:4px}@media only screen and (max-width: 959px){div#container{grid-template-columns:1fr;grid-template-areas:\"bar\" \"step\"}#map{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: FeatureSetViewComponent, selector: "gve-feature-set-view", inputs: ["features", "featNames", "featValues", "minFilterCount"] }, { kind: "component", type: StepsMapComponent, selector: "gve-steps-map", inputs: ["steps", "selectedStep", "textFontSize"], outputs: ["selectedStepChange"] }, { kind: "component", type: BaseTextViewComponent, selector: "gve-base-text-view", inputs: ["defaultColor", "defaultBorderColor", "selectionColor", "hasLineNumber", "text"], outputs: ["charPick", "rangePick"] }] }); }
|
|
171
|
+
}
|
|
172
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ChainResultViewComponent, decorators: [{
|
|
173
|
+
type: Component,
|
|
174
|
+
args: [{ selector: 'gve-chain-result-view', standalone: true, imports: [
|
|
175
|
+
CommonModule,
|
|
176
|
+
ReactiveFormsModule,
|
|
177
|
+
MatButtonModule,
|
|
178
|
+
MatFormFieldModule,
|
|
179
|
+
MatIconModule,
|
|
180
|
+
MatSelectModule,
|
|
181
|
+
FeatureSetViewComponent,
|
|
182
|
+
StepsMapComponent,
|
|
183
|
+
BaseTextViewComponent,
|
|
184
|
+
], template: "@if (result) {\r\n<div id=\"container\">\r\n <div id=\"bar\" class=\"form-row\">\r\n <!-- version -->\r\n <mat-form-field *ngIf=\"versionTags?.length\">\r\n <mat-label>version</mat-label>\r\n <mat-select [formControl]=\"versionTag\">\r\n <mat-option [value]=\"null\">-</mat-option>\r\n <mat-option *ngFor=\"let t of versionTags\" [value]=\"t\">{{\r\n t\r\n }}</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n <!-- tag -->\r\n <mat-form-field *ngIf=\"tags?.length\">\r\n <mat-label>tag</mat-label>\r\n <mat-select [formControl]=\"tag\">\r\n <mat-option *ngFor=\"let t of tags\" [value]=\"t\">{{ t }}</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- step -->\r\n @if (step) {\r\n <div id=\"step\">\r\n <!-- text -->\r\n <div id=\"text\">\r\n <gve-base-text-view\r\n [text]=\"result.taggedNodes[step.outputTag]\"\r\n (charPick)=\"onStepCharPick($event)\"\r\n (rangePick)=\"onStepRangePick($event)\"\r\n />\r\n </div>\r\n <!-- features -->\r\n <div id=\"feats\" class=\"form-row-top\">\r\n <div id=\"g-feats\">\r\n <div class=\"feat-header\">{{ step.outputTag }}</div>\r\n <gve-feature-set-view [features]=\"step.featureSet.features\" />\r\n </div>\r\n <div id=\"n-feats\">\r\n @if (selectionFeatures.length) {\r\n <div class=\"feat-header\">{{ selection }}</div>\r\n <gve-feature-set-view [features]=\"selectionFeatures\" />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- steps map -->\r\n <div id=\"map\">\r\n <gve-steps-map\r\n [steps]=\"result.steps\"\r\n [selectedStep]=\"step\"\r\n (selectedStepChange)=\"onStepChange($event)\"\r\n />\r\n </div>\r\n</div>\r\n}\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.form-row-top{display:flex;gap:8px;align-items:start;flex-wrap:wrap}div#container{display:grid;grid-template-rows:auto 1fr;grid-template-columns:3fr 1fr;grid-template-areas:\"bar map\" \"step map\";gap:8px}div#bar{grid-area:bar}div#map{grid-area:map}div#step{grid-area:step}.feat-header{background-color:#3e92cc;color:#fff;text-align:center;border:1px solid #3e92cc;border-top-left-radius:4px;border-top-right-radius:4px}@media only screen and (max-width: 959px){div#container{grid-template-columns:1fr;grid-template-areas:\"bar\" \"step\"}#map{display:none}}\n"] }]
|
|
185
|
+
}], ctorParameters: () => [{ type: i1.FormBuilder }], propDecorators: { result: [{
|
|
186
|
+
type: Input
|
|
187
|
+
}], stepPick: [{
|
|
188
|
+
type: Output
|
|
189
|
+
}] } });
|
|
190
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhaW4tcmVzdWx0LXZpZXcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbXlybWlkb24vZ3ZlLWNvcmUvc3JjL2xpYi9jb21wb25lbnRzL2NoYWluLXJlc3VsdC12aWV3L2NoYWluLXJlc3VsdC12aWV3LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2d2ZS1jb3JlL3NyYy9saWIvY29tcG9uZW50cy9jaGFpbi1yZXN1bHQtdmlldy9jaGFpbi1yZXN1bHQtdmlldy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUNMLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQTRCLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDL0UsT0FBTyxFQUFnQixZQUFZLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFeEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFRM0QsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFDekYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUNMLHFCQUFxQixHQUV0QixNQUFNLDRDQUE0QyxDQUFDOzs7Ozs7O0FBT3BEOztHQUVHO0FBa0JILE1BQU0sT0FBTyx3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QkFBcUI7cUJBQ3RCO2dGQWFVLE1BQU07c0JBRGhCLEtBQUs7Z0JBd0JDLFFBQVE7c0JBRGQsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBJbnB1dCxcclxuICBPbkRlc3Ryb3ksXHJcbiAgT25Jbml0LFxyXG4gIE91dHB1dCxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Db250cm9sLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIGRlYm91bmNlVGltZSwgZGlzdGluY3RVbnRpbENoYW5nZWQgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7IE1hdEJ1dHRvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XHJcbmltcG9ydCB7IE1hdEZvcm1GaWVsZE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xyXG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XHJcbmltcG9ydCB7IE1hdFNlbGVjdE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NlbGVjdCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIENoYXJOb2RlLFxyXG4gIEZlYXR1cmUsXHJcbiAgT3BlcmF0aW9uRmVhdHVyZSxcclxufSBmcm9tICdAbXlybWlkb24vZ3ZlLXNuYXBzaG90LXZpZXcnO1xyXG5cclxuaW1wb3J0IHsgRmVhdHVyZVNldFZpZXdDb21wb25lbnQgfSBmcm9tICcuLi9mZWF0dXJlLXNldC12aWV3L2ZlYXR1cmUtc2V0LXZpZXcuY29tcG9uZW50JztcclxuaW1wb3J0IHsgU3RlcHNNYXBDb21wb25lbnQgfSBmcm9tICcuLi9zdGVwcy1tYXAvc3RlcHMtbWFwLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7XHJcbiAgQmFzZVRleHRWaWV3Q29tcG9uZW50LFxyXG4gIFZhckJhc2VUZXh0UmFuZ2UsXHJcbn0gZnJvbSAnLi4vYmFzZS10ZXh0LXZpZXcvYmFzZS10ZXh0LXZpZXcuY29tcG9uZW50JztcclxuaW1wb3J0IHtcclxuICBDaGFpbk9wZXJhdGlvbkNvbnRleHRTdGVwLFxyXG4gIENoYXJDaGFpblJlc3VsdCxcclxufSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9ndmUtYXBpLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBCYXNlVGV4dENoYXJFdmVudCB9IGZyb20gJy4uL2Jhc2UtdGV4dC1jaGFyL2Jhc2UtdGV4dC1jaGFyLmNvbXBvbmVudCc7XHJcblxyXG4vKipcclxuICogQ29tcG9uZW50IHRvIGRpc3BsYXkgYSBjaGFpbiByZXN1bHQuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2d2ZS1jaGFpbi1yZXN1bHQtdmlldycsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbXHJcbiAgICBDb21tb25Nb2R1bGUsXHJcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxyXG4gICAgTWF0QnV0dG9uTW9kdWxlLFxyXG4gICAgTWF0Rm9ybUZpZWxkTW9kdWxlLFxyXG4gICAgTWF0SWNvbk1vZHVsZSxcclxuICAgIE1hdFNlbGVjdE1vZHVsZSxcclxuICAgIEZlYXR1cmVTZXRWaWV3Q29tcG9uZW50LFxyXG4gICAgU3RlcHNNYXBDb21wb25lbnQsXHJcbiAgICBCYXNlVGV4dFZpZXdDb21wb25lbnQsXHJcbiAgXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vY2hhaW4tcmVzdWx0LXZpZXcuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi9jaGFpbi1yZXN1bHQtdmlldy5jb21wb25lbnQuY3NzJyxcclxufSlcclxuZXhwb3J0IGNsYXNzIENoYWluUmVzdWx0Vmlld0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuICBwcml2YXRlIF9zdWJzPzogU3Vic2NyaXB0aW9uW107XHJcbiAgcHJpdmF0ZSBfcmVzdWx0PzogQ2hhckNoYWluUmVzdWx0O1xyXG4gIHByaXZhdGUgX3N0ZXBQaWNrRnJvemVuPzogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIHJlc3VsdCB0byBkaXNwbGF5LlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgcHVibGljIGdldCByZXN1bHQoKTogQ2hhckNoYWluUmVzdWx0IHwgdW5kZWZpbmVkIHtcclxuICAgIHJldHVybiB0aGlzLl9yZXN1bHQ7XHJcbiAgfVxyXG4gIHB1YmxpYyBzZXQgcmVzdWx0KHZhbHVlOiBDaGFyQ2hhaW5SZXN1bHQgfCB1bmRlZmluZWQgfCBudWxsKSB7XHJcbiAgICBpZiAodGhpcy5fcmVzdWx0ID09PSB2YWx1ZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLl9yZXN1bHQgPSB2YWx1ZSB8fCB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLnVwZGF0ZUZvcm0odGhpcy5fcmVzdWx0KTtcclxuXHJcbiAgICAvLyBzZWxlY3QgbGFzdCBzdGVwIGJ5IGRlZmF1bHRcclxuICAgIGlmICh0aGlzLl9yZXN1bHQ/LnN0ZXBzPy5sZW5ndGgpIHtcclxuICAgICAgdGhpcy5fc3RlcFBpY2tGcm96ZW4gPSB0cnVlO1xyXG4gICAgICB0aGlzLnN0ZXAgPSB0aGlzLl9yZXN1bHQuc3RlcHNbdGhpcy5fcmVzdWx0LnN0ZXBzLmxlbmd0aCAtIDFdO1xyXG4gICAgICB0aGlzLnRhZy5zZXRWYWx1ZSh0aGlzLnN0ZXAub3V0cHV0VGFnKTtcclxuICAgICAgdGhpcy5fc3RlcFBpY2tGcm96ZW4gPSBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEVtaXRzIHdoZW4gYSByZXN1bHQncyBzdGVwIGlzIHBpY2tlZC5cclxuICAgKi9cclxuICBAT3V0cHV0KClcclxuICBwdWJsaWMgc3RlcFBpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPENoYWluT3BlcmF0aW9uQ29udGV4dFN0ZXA+KCk7XHJcblxyXG4gIHB1YmxpYyB2ZXJzaW9uVGFnczogc3RyaW5nW10gPSBbXTtcclxuICBwdWJsaWMgdGFnczogc3RyaW5nW10gPSBbXTtcclxuICBwdWJsaWMgdmVyc2lvblRhZzogRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD47XHJcbiAgcHVibGljIHRhZzogRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD47XHJcbiAgcHVibGljIHN0ZXA/OiBDaGFpbk9wZXJhdGlvbkNvbnRleHRTdGVwO1xyXG4gIHB1YmxpYyBzZWxlY3Rpb24/OiBzdHJpbmc7XHJcbiAgcHVibGljIHNlbGVjdGlvbkZlYXR1cmVzOiBPcGVyYXRpb25GZWF0dXJlW10gPSBbXTtcclxuXHJcbiAgY29uc3RydWN0b3IoZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyKSB7XHJcbiAgICB0aGlzLnZlcnNpb25UYWcgPSBmb3JtQnVpbGRlci5jb250cm9sPHN0cmluZyB8IG51bGw+KG51bGwpO1xyXG4gICAgdGhpcy50YWcgPSBmb3JtQnVpbGRlci5jb250cm9sPHN0cmluZyB8IG51bGw+KG51bGwpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5fc3VicyA9IFtcclxuICAgICAgdGhpcy52ZXJzaW9uVGFnLnZhbHVlQ2hhbmdlc1xyXG4gICAgICAgIC5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksIGRlYm91bmNlVGltZSgyMDApKVxyXG4gICAgICAgIC5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLnRhZy5zZXRWYWx1ZSh0aGlzLmdldFRhZ0Zyb21WZXJzaW9uKHZhbHVlKSB8fCBudWxsKTtcclxuICAgICAgICB9KSxcclxuICAgICAgdGhpcy50YWcudmFsdWVDaGFuZ2VzXHJcbiAgICAgICAgLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSwgZGVib3VuY2VUaW1lKDIwMCkpXHJcbiAgICAgICAgLnN1YnNjcmliZSgodmFsdWUpID0+IHtcclxuICAgICAgICAgIHRoaXMuc3RlcCA9IHRoaXMuX3Jlc3VsdD8uc3RlcHMuZmluZChcclxuICAgICAgICAgICAgKHN0ZXApID0+IHN0ZXAub3V0cHV0VGFnID09PSB2YWx1ZVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIGlmICh0aGlzLnN0ZXAgJiYgIXRoaXMuX3N0ZXBQaWNrRnJvemVuKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RlcFBpY2suZW1pdCh0aGlzLnN0ZXAhKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KSxcclxuICAgIF07XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLl9zdWJzPy5mb3JFYWNoKChzdWIpID0+IHN1Yi51bnN1YnNjcmliZSgpKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBkYXRlVmVyc2lvblRhZ3MoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuX3Jlc3VsdCkge1xyXG4gICAgICB0aGlzLnZlcnNpb25UYWdzID0gW107XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBleHRyYWN0IHZlcnNpb24gdGFncyBmcm9tIHJlc3VsdCBzdGVwcyBmZWF0dXJlcyBuYW1lZCAndmVyc2lvbidcclxuICAgIGNvbnN0IHRhZ3MgPSBuZXcgU2V0PHN0cmluZz4oKTtcclxuICAgIGZvciAoY29uc3Qgc3RlcCBvZiB0aGlzLl9yZXN1bHQuc3RlcHMpIHtcclxuICAgICAgZm9yIChjb25zdCBmZWF0dXJlIG9mIHN0ZXAuZmVhdHVyZVNldC5mZWF0dXJlcykge1xyXG4gICAgICAgIGlmIChmZWF0dXJlLm5hbWUgPT09ICd2ZXJzaW9uJykge1xyXG4gICAgICAgICAgdGFncy5hZGQoZmVhdHVyZS52YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLnZlcnNpb25UYWdzID0gQXJyYXkuZnJvbSh0YWdzKS5zb3J0KCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldFRhZ0Zyb21WZXJzaW9uKHZlcnNpb24/OiBzdHJpbmcgfCBudWxsKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcclxuICAgIGlmICghdGhpcy5fcmVzdWx0IHx8ICF2ZXJzaW9uKSB7XHJcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgICBmb3IgKGNvbnN0IHN0ZXAgb2YgdGhpcy5fcmVzdWx0LnN0ZXBzKSB7XHJcbiAgICAgIGZvciAoY29uc3QgZmVhdHVyZSBvZiBzdGVwLmZlYXR1cmVTZXQuZmVhdHVyZXMpIHtcclxuICAgICAgICBpZiAoZmVhdHVyZS5uYW1lID09PSAndmVyc2lvbicgJiYgZmVhdHVyZS52YWx1ZSA9PT0gdmVyc2lvbikge1xyXG4gICAgICAgICAgcmV0dXJuIHN0ZXAub3V0cHV0VGFnO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBkYXRlRm9ybShyZXN1bHQ/OiBDaGFyQ2hhaW5SZXN1bHQpOiB2b2lkIHtcclxuICAgIHRoaXMuc2VsZWN0aW9uRmVhdHVyZXMgPSBbXTtcclxuXHJcbiAgICBpZiAoIXJlc3VsdCkge1xyXG4gICAgICB0aGlzLnN0ZXAgPSB1bmRlZmluZWQ7XHJcbiAgICAgIHRoaXMuc2VsZWN0aW9uID0gdW5kZWZpbmVkO1xyXG4gICAgICB0aGlzLnRhZ3MgPSBbXTtcclxuICAgICAgdGhpcy52ZXJzaW9uVGFncyA9IFtdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy50YWdzID0gcmVzdWx0LmNoYWluVGFncztcclxuICAgICAgdGhpcy51cGRhdGVWZXJzaW9uVGFncygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXROb2RlRmVhdHVyZXMoaWQ6IG51bWJlcik6IEZlYXR1cmVbXSB7XHJcbiAgICBpZiAoIXRoaXMuc3RlcCkge1xyXG4gICAgICByZXR1cm4gW107XHJcbiAgICB9XHJcbiAgICByZXR1cm4gKFxyXG4gICAgICB0aGlzLnN0ZXAuZmVhdHVyZVNldC5ub2RlRmVhdHVyZXNbdGhpcy5zdGVwLm91dHB1dFRhZyArICdfJyArIGlkXSB8fCBbXVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZmluZE5vZGUoaWQ6IG51bWJlcik6IENoYXJOb2RlIHwgbnVsbCB7XHJcbiAgICBpZiAoIXRoaXMuc3RlcCkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIGZvciAobGV0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLl9yZXN1bHQhLnRhZ2dlZE5vZGVzKSkge1xyXG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fcmVzdWx0IS50YWdnZWROb2Rlc1trZXldLmZpbmQoKG4pID0+IG4uaWQgPT09IGlkKTtcclxuICAgICAgaWYgKG5vZGUpIHtcclxuICAgICAgICByZXR1cm4gbm9kZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25TdGVwQ2hhclBpY2soZXZlbnQ6IEJhc2VUZXh0Q2hhckV2ZW50KTogdm9pZCB7XHJcbiAgICBjb25zdCBmZWF0dXJlcyA9IHRoaXMuZ2V0Tm9kZUZlYXR1cmVzKGV2ZW50LmNoYXIuaWQpO1xyXG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZmluZE5vZGUoZXZlbnQuY2hhci5pZCkhO1xyXG4gICAgdGhpcy5zZWxlY3Rpb24gPSBgJHtldmVudC5jaGFyLmxhYmVsfSAoJHtub2RlLnNvdXJjZVRhZ30pYDtcclxuICAgIHRoaXMuc2VsZWN0aW9uRmVhdHVyZXMgPSBbLi4uZmVhdHVyZXNdO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uU3RlcFJhbmdlUGljayhyYW5nZTogVmFyQmFzZVRleHRSYW5nZSk6IHZvaWQge1xyXG4gICAgaWYgKHJhbmdlLnJ1biA9PT0gMSkge1xyXG4gICAgICAvLyBhbHJlYWR5IGhhbmRsZWQgYnkgb25TdGVwQ2hhclBpY2tcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5zZWxlY3Rpb24gPSByYW5nZS5hdCArICfDlycgKyByYW5nZS5ydW47XHJcbiAgICBjb25zdCBlbmQgPSByYW5nZS5hdCArIHJhbmdlLnJ1bjtcclxuXHJcbiAgICBjb25zdCBmZWF0dXJlczogRmVhdHVyZVtdID0gW107XHJcbiAgICBjb25zdCB0YWdOb2RlcyA9IHRoaXMuX3Jlc3VsdCEudGFnZ2VkTm9kZXNbdGhpcy50YWcudmFsdWUhXTtcclxuXHJcbiAgICBmb3IgKGxldCBub2RlIG9mIHRhZ05vZGVzKSB7XHJcbiAgICAgIC8vIGlmIGluIHJhbmdlLCBpbnRlcnNlY3QgZmVhdHVyZXNcclxuICAgICAgaWYgKG5vZGUuaWQgPj0gcmFuZ2UuYXQgJiYgbm9kZS5pZCA8IGVuZCkge1xyXG4gICAgICAgIGNvbnN0IG5vZGVGZWF0dXJlcyA9IHRoaXMuZ2V0Tm9kZUZlYXR1cmVzKG5vZGUuaWQpO1xyXG5cclxuICAgICAgICBpZiAobm9kZS5pZCA9PT0gcmFuZ2UuYXQpIHtcclxuICAgICAgICAgIGZvciAobGV0IGYgb2Ygbm9kZUZlYXR1cmVzKSB7XHJcbiAgICAgICAgICAgIGZlYXR1cmVzLnB1c2goZik7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIGZlYXR1cmVzID0gaW50ZXJzZWN0aW9uIG9mIGZlYXR1cmVzIGFuZCBjaGFyRmVhdHVyZXNcclxuICAgICAgICAgIGZlYXR1cmVzLnNwbGljZShcclxuICAgICAgICAgICAgMCxcclxuICAgICAgICAgICAgZmVhdHVyZXMubGVuZ3RoLFxyXG4gICAgICAgICAgICAuLi5mZWF0dXJlcy5maWx0ZXIoKGYpID0+XHJcbiAgICAgICAgICAgICAgbm9kZUZlYXR1cmVzLnNvbWUoKGNmKSA9PiBjZi5uYW1lID09PSBmLm5hbWUpXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5zZWxlY3Rpb25GZWF0dXJlcyA9IGZlYXR1cmVzO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uU3RlcENoYW5nZShzdGVwOiBDaGFpbk9wZXJhdGlvbkNvbnRleHRTdGVwKTogdm9pZCB7XHJcbiAgICB0aGlzLnRhZy5zZXRWYWx1ZShzdGVwLm91dHB1dFRhZyk7XHJcbiAgICB0aGlzLnNlbGVjdGlvbkZlYXR1cmVzID0gW107XHJcbiAgfVxyXG59XHJcbiIsIkBpZiAocmVzdWx0KSB7XHJcbjxkaXYgaWQ9XCJjb250YWluZXJcIj5cclxuICA8ZGl2IGlkPVwiYmFyXCIgY2xhc3M9XCJmb3JtLXJvd1wiPlxyXG4gICAgPCEtLSB2ZXJzaW9uIC0tPlxyXG4gICAgPG1hdC1mb3JtLWZpZWxkICpuZ0lmPVwidmVyc2lvblRhZ3M/Lmxlbmd0aFwiPlxyXG4gICAgICA8bWF0LWxhYmVsPnZlcnNpb248L21hdC1sYWJlbD5cclxuICAgICAgPG1hdC1zZWxlY3QgW2Zvcm1Db250cm9sXT1cInZlcnNpb25UYWdcIj5cclxuICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwibnVsbFwiPi08L21hdC1vcHRpb24+XHJcbiAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IHQgb2YgdmVyc2lvblRhZ3NcIiBbdmFsdWVdPVwidFwiPnt7XHJcbiAgICAgICAgICB0XHJcbiAgICAgICAgfX08L21hdC1vcHRpb24+XHJcbiAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICA8IS0tIHRhZyAtLT5cclxuICAgIDxtYXQtZm9ybS1maWVsZCAqbmdJZj1cInRhZ3M/Lmxlbmd0aFwiPlxyXG4gICAgICA8bWF0LWxhYmVsPnRhZzwvbWF0LWxhYmVsPlxyXG4gICAgICA8bWF0LXNlbGVjdCBbZm9ybUNvbnRyb2xdPVwidGFnXCI+XHJcbiAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IHQgb2YgdGFnc1wiIFt2YWx1ZV09XCJ0XCI+e3sgdCB9fTwvbWF0LW9wdGlvbj5cclxuICAgICAgPC9tYXQtc2VsZWN0PlxyXG4gICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICA8L2Rpdj5cclxuXHJcbiAgPCEtLSBzdGVwIC0tPlxyXG4gIEBpZiAoc3RlcCkge1xyXG4gIDxkaXYgaWQ9XCJzdGVwXCI+XHJcbiAgICA8IS0tIHRleHQgLS0+XHJcbiAgICA8ZGl2IGlkPVwidGV4dFwiPlxyXG4gICAgICA8Z3ZlLWJhc2UtdGV4dC12aWV3XHJcbiAgICAgICAgW3RleHRdPVwicmVzdWx0LnRhZ2dlZE5vZGVzW3N0ZXAub3V0cHV0VGFnXVwiXHJcbiAgICAgICAgKGNoYXJQaWNrKT1cIm9uU3RlcENoYXJQaWNrKCRldmVudClcIlxyXG4gICAgICAgIChyYW5nZVBpY2spPVwib25TdGVwUmFuZ2VQaWNrKCRldmVudClcIlxyXG4gICAgICAvPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8IS0tIGZlYXR1cmVzIC0tPlxyXG4gICAgPGRpdiBpZD1cImZlYXRzXCIgY2xhc3M9XCJmb3JtLXJvdy10b3BcIj5cclxuICAgICAgPGRpdiBpZD1cImctZmVhdHNcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmVhdC1oZWFkZXJcIj57eyBzdGVwLm91dHB1dFRhZyB9fTwvZGl2PlxyXG4gICAgICAgIDxndmUtZmVhdHVyZS1zZXQtdmlldyBbZmVhdHVyZXNdPVwic3RlcC5mZWF0dXJlU2V0LmZlYXR1cmVzXCIgLz5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgaWQ9XCJuLWZlYXRzXCI+XHJcbiAgICAgICAgQGlmIChzZWxlY3Rpb25GZWF0dXJlcy5sZW5ndGgpIHtcclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmVhdC1oZWFkZXJcIj57eyBzZWxlY3Rpb24gfX08L2Rpdj5cclxuICAgICAgICA8Z3ZlLWZlYXR1cmUtc2V0LXZpZXcgW2ZlYXR1cmVzXT1cInNlbGVjdGlvbkZlYXR1cmVzXCIgLz5cclxuICAgICAgICB9XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbiAgfVxyXG5cclxuICA8IS0tIHN0ZXBzIG1hcCAtLT5cclxuICA8ZGl2IGlkPVwibWFwXCI+XHJcbiAgICA8Z3ZlLXN0ZXBzLW1hcFxyXG4gICAgICBbc3RlcHNdPVwicmVzdWx0LnN0ZXBzXCJcclxuICAgICAgW3NlbGVjdGVkU3RlcF09XCJzdGVwXCJcclxuICAgICAgKHNlbGVjdGVkU3RlcENoYW5nZSk9XCJvblN0ZXBDaGFuZ2UoJGV2ZW50KVwiXHJcbiAgICAvPlxyXG4gIDwvZGl2PlxyXG48L2Rpdj5cclxufVxyXG4iXX0=
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output, ViewChild, } from '@angular/core';
|
|
2
|
+
import { ReactiveFormsModule, Validators, } from '@angular/forms';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { debounceTime, distinctUntilChanged } from 'rxjs';
|
|
5
|
+
// material
|
|
6
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
7
|
+
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
8
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
9
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
10
|
+
import { MatInputModule } from '@angular/material/input';
|
|
11
|
+
import { MatSelectModule } from '@angular/material/select';
|
|
12
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
13
|
+
import { FeatureSetPolicy, } from '@myrmidon/gve-snapshot-view';
|
|
14
|
+
import * as i0 from "@angular/core";
|
|
15
|
+
import * as i1 from "@angular/forms";
|
|
16
|
+
import * as i2 from "@angular/common";
|
|
17
|
+
import * as i3 from "@angular/material/button";
|
|
18
|
+
import * as i4 from "@angular/material/checkbox";
|
|
19
|
+
import * as i5 from "@angular/material/form-field";
|
|
20
|
+
import * as i6 from "@angular/material/icon";
|
|
21
|
+
import * as i7 from "@angular/material/input";
|
|
22
|
+
import * as i8 from "@angular/material/select";
|
|
23
|
+
import * as i9 from "@angular/material/core";
|
|
24
|
+
import * as i10 from "@angular/material/tooltip";
|
|
25
|
+
/**
|
|
26
|
+
* Feature editor. This edits a single feature, either free or from
|
|
27
|
+
* a closed set. In the latter case you must define the set via
|
|
28
|
+
* the `labeledIds` input. Also, you can provide a map of features
|
|
29
|
+
* to values via the `map` input. This is useful when you want to
|
|
30
|
+
* provide a set of features and values to the user, and you want
|
|
31
|
+
* to provide human-readable labels for the values.
|
|
32
|
+
*/
|
|
33
|
+
export class FeatureEditorComponent {
|
|
34
|
+
/**
|
|
35
|
+
* The feature values map. When specified and the user selects a feature
|
|
36
|
+
* name present in the map keys, the corresponding values will be used
|
|
37
|
+
* to populate the value selection.
|
|
38
|
+
*/
|
|
39
|
+
get featValues() {
|
|
40
|
+
return this._map;
|
|
41
|
+
}
|
|
42
|
+
set featValues(value) {
|
|
43
|
+
this._map = value || undefined;
|
|
44
|
+
this.nameIds = this.getLabeledIdsFor(this.name.value);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The feature to edit.
|
|
48
|
+
*/
|
|
49
|
+
get feature() {
|
|
50
|
+
return this._feature;
|
|
51
|
+
}
|
|
52
|
+
set feature(value) {
|
|
53
|
+
if (this._feature === value) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this._feature = value || undefined;
|
|
57
|
+
this.updateForm(this._feature);
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
this.nameControl?.nativeElement?.focus();
|
|
60
|
+
}, 500);
|
|
61
|
+
}
|
|
62
|
+
constructor(formBuilder) {
|
|
63
|
+
/**
|
|
64
|
+
* True if the feature is a variant operation feature, which has
|
|
65
|
+
* additional properties like negation, global, and short-lived.
|
|
66
|
+
*/
|
|
67
|
+
this.isVar = false;
|
|
68
|
+
/**
|
|
69
|
+
* Event emitted when the user cancels the feature editing.
|
|
70
|
+
*/
|
|
71
|
+
this.featureCancel = new EventEmitter();
|
|
72
|
+
/**
|
|
73
|
+
* Event emitted when the user saves the edited feature.
|
|
74
|
+
*/
|
|
75
|
+
this.featureChange = new EventEmitter();
|
|
76
|
+
this.name = formBuilder.control('', {
|
|
77
|
+
validators: [Validators.required, Validators.maxLength(50)],
|
|
78
|
+
nonNullable: true,
|
|
79
|
+
});
|
|
80
|
+
this.value = formBuilder.control('', {
|
|
81
|
+
validators: [Validators.maxLength(5000)],
|
|
82
|
+
nonNullable: true,
|
|
83
|
+
});
|
|
84
|
+
this.setPolicy = formBuilder.control(FeatureSetPolicy.multiple, {
|
|
85
|
+
nonNullable: true,
|
|
86
|
+
});
|
|
87
|
+
this.isNegated = formBuilder.control(false, { nonNullable: true });
|
|
88
|
+
this.isGlobal = formBuilder.control(false, { nonNullable: true });
|
|
89
|
+
this.isShortLived = formBuilder.control(false, { nonNullable: true });
|
|
90
|
+
this.form = formBuilder.group({
|
|
91
|
+
name: this.name,
|
|
92
|
+
value: this.value,
|
|
93
|
+
setPolicy: this.setPolicy,
|
|
94
|
+
isNegated: this.isNegated,
|
|
95
|
+
isGlobal: this.isGlobal,
|
|
96
|
+
isShortLived: this.isShortLived,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
ngOnInit() {
|
|
100
|
+
// whenever the name changes, update the value selection
|
|
101
|
+
this._sub = this.name.valueChanges
|
|
102
|
+
.pipe(debounceTime(300), distinctUntilChanged())
|
|
103
|
+
.subscribe((name) => {
|
|
104
|
+
this.value.reset();
|
|
105
|
+
this.nameIds = this.getLabeledIdsFor(name);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
ngOnDestroy() {
|
|
109
|
+
this._sub?.unsubscribe();
|
|
110
|
+
}
|
|
111
|
+
getLabeledIdsFor(id) {
|
|
112
|
+
if (!id) {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
return this.featValues ? this.featValues[id] : undefined;
|
|
116
|
+
}
|
|
117
|
+
updateForm(feature) {
|
|
118
|
+
if (!feature) {
|
|
119
|
+
this.form.reset();
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
this.name.setValue(feature.name);
|
|
123
|
+
this.value.setValue(feature.value);
|
|
124
|
+
this.setPolicy.setValue(feature.setPolicy || FeatureSetPolicy.multiple);
|
|
125
|
+
this.isNegated.setValue(feature.isNegated || false);
|
|
126
|
+
this.isGlobal.setValue(feature.isGlobal || false);
|
|
127
|
+
this.isShortLived.setValue(feature.isShortLived || false);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
cancel() {
|
|
131
|
+
this.featureCancel.emit();
|
|
132
|
+
}
|
|
133
|
+
save() {
|
|
134
|
+
if (!this.form.valid) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
this.feature = this.isVar
|
|
138
|
+
? {
|
|
139
|
+
name: this.name.value.trim(),
|
|
140
|
+
value: this.value.value.trim(),
|
|
141
|
+
setPolicy: this.setPolicy.value,
|
|
142
|
+
isNegated: this.isNegated.value,
|
|
143
|
+
isGlobal: this.isGlobal.value,
|
|
144
|
+
isShortLived: this.isShortLived.value,
|
|
145
|
+
}
|
|
146
|
+
: {
|
|
147
|
+
name: this.name.value.trim(),
|
|
148
|
+
value: this.value.value.trim(),
|
|
149
|
+
setPolicy: this.setPolicy.value,
|
|
150
|
+
};
|
|
151
|
+
this.featureChange.emit(this.feature);
|
|
152
|
+
}
|
|
153
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: FeatureEditorComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
154
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.4", type: FeatureEditorComponent, isStandalone: true, selector: "gve-feature-editor", inputs: { featNames: "featNames", featValues: "featValues", feature: "feature", isVar: "isVar" }, outputs: { featureCancel: "featureCancel", featureChange: "featureChange" }, viewQueries: [{ propertyName: "nameControl", first: true, predicate: ["nameCtl"], descendants: true }], ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div class=\"form-row\">\r\n @if (featNames?.length) {\r\n <!-- name (bound) -->\r\n <mat-form-field>\r\n <mat-label>name</mat-label>\r\n <mat-select #nameCtl [formControl]=\"name\">\r\n <mat-option *ngFor=\"let i of featNames\" [value]=\"i.id\">{{\r\n i.label\r\n }}</mat-option>\r\n </mat-select>\r\n @if ($any(name).errors?.required && (name.dirty || name.touched)) {\r\n <mat-error>name required</mat-error>\r\n }\r\n </mat-form-field>\r\n } @else {\r\n <!-- name (free) -->\r\n <mat-form-field>\r\n <mat-label>name</mat-label>\r\n <input #nameCtl matInput [formControl]=\"name\" />\r\n <mat-error\r\n *ngIf=\"$any(name).errors?.required && (name.dirty || name.touched)\"\r\n >name required</mat-error\r\n >\r\n @if ($any(name).errors?.maxLength && (name.dirty || name.touched)) {\r\n <mat-error>name too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- value (bound) -->\r\n @if (nameIds?.length) {\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <mat-select [formControl]=\"value\">\r\n <mat-option *ngFor=\"let e of nameIds\" [value]=\"e.id\">{{\r\n e.label\r\n }}</mat-option>\r\n </mat-select>\r\n @if ($any(value).errors?.required && (value.dirty || value.touched)) {\r\n <mat-error>value required</mat-error>\r\n }\r\n </mat-form-field>\r\n } @else {\r\n <!-- value (free) -->\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n @if ($any(value).errors?.required && (value.dirty || value.touched)) {\r\n <mat-error>value required</mat-error>\r\n } @if ($any(value).errors?.maxLength && (value.dirty || value.touched)) {\r\n <mat-error>value too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- setPolicy -->\r\n <mat-form-field>\r\n <mat-label>set policy</mat-label>\r\n <mat-select [formControl]=\"setPolicy\">\r\n <mat-option [value]=\"0\">multiple</mat-option>\r\n <mat-option [value]=\"1\">single</mat-option>\r\n <mat-option [value]=\"2\">single first</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n\r\n @if (isVar) {\r\n <div class=\"form-row\">\r\n <!-- isNegated -->\r\n <mat-checkbox [formControl]=\"isNegated\">negated</mat-checkbox>\r\n\r\n <!-- isShortLived -->\r\n <mat-checkbox [formControl]=\"isShortLived\">short-lived</mat-checkbox>\r\n\r\n <!-- isGlobal -->\r\n <mat-checkbox [formControl]=\"isGlobal\">global</mat-checkbox>\r\n </div>\r\n }\r\n\r\n <!-- buttons -->\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n mat-icon-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"cancel()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n color=\"primary\"\r\n mat-icon-button\r\n matTooltip=\"Accept changes\"\r\n [disabled]=\"form.invalid || form.pristine\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i4.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i8.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
|
|
155
|
+
}
|
|
156
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: FeatureEditorComponent, decorators: [{
|
|
157
|
+
type: Component,
|
|
158
|
+
args: [{ selector: 'gve-feature-editor', standalone: true, imports: [
|
|
159
|
+
CommonModule,
|
|
160
|
+
ReactiveFormsModule,
|
|
161
|
+
MatButtonModule,
|
|
162
|
+
MatCheckboxModule,
|
|
163
|
+
MatFormFieldModule,
|
|
164
|
+
MatIconModule,
|
|
165
|
+
MatInputModule,
|
|
166
|
+
MatSelectModule,
|
|
167
|
+
MatTooltipModule,
|
|
168
|
+
], template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div class=\"form-row\">\r\n @if (featNames?.length) {\r\n <!-- name (bound) -->\r\n <mat-form-field>\r\n <mat-label>name</mat-label>\r\n <mat-select #nameCtl [formControl]=\"name\">\r\n <mat-option *ngFor=\"let i of featNames\" [value]=\"i.id\">{{\r\n i.label\r\n }}</mat-option>\r\n </mat-select>\r\n @if ($any(name).errors?.required && (name.dirty || name.touched)) {\r\n <mat-error>name required</mat-error>\r\n }\r\n </mat-form-field>\r\n } @else {\r\n <!-- name (free) -->\r\n <mat-form-field>\r\n <mat-label>name</mat-label>\r\n <input #nameCtl matInput [formControl]=\"name\" />\r\n <mat-error\r\n *ngIf=\"$any(name).errors?.required && (name.dirty || name.touched)\"\r\n >name required</mat-error\r\n >\r\n @if ($any(name).errors?.maxLength && (name.dirty || name.touched)) {\r\n <mat-error>name too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- value (bound) -->\r\n @if (nameIds?.length) {\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <mat-select [formControl]=\"value\">\r\n <mat-option *ngFor=\"let e of nameIds\" [value]=\"e.id\">{{\r\n e.label\r\n }}</mat-option>\r\n </mat-select>\r\n @if ($any(value).errors?.required && (value.dirty || value.touched)) {\r\n <mat-error>value required</mat-error>\r\n }\r\n </mat-form-field>\r\n } @else {\r\n <!-- value (free) -->\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n @if ($any(value).errors?.required && (value.dirty || value.touched)) {\r\n <mat-error>value required</mat-error>\r\n } @if ($any(value).errors?.maxLength && (value.dirty || value.touched)) {\r\n <mat-error>value too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- setPolicy -->\r\n <mat-form-field>\r\n <mat-label>set policy</mat-label>\r\n <mat-select [formControl]=\"setPolicy\">\r\n <mat-option [value]=\"0\">multiple</mat-option>\r\n <mat-option [value]=\"1\">single</mat-option>\r\n <mat-option [value]=\"2\">single first</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n\r\n @if (isVar) {\r\n <div class=\"form-row\">\r\n <!-- isNegated -->\r\n <mat-checkbox [formControl]=\"isNegated\">negated</mat-checkbox>\r\n\r\n <!-- isShortLived -->\r\n <mat-checkbox [formControl]=\"isShortLived\">short-lived</mat-checkbox>\r\n\r\n <!-- isGlobal -->\r\n <mat-checkbox [formControl]=\"isGlobal\">global</mat-checkbox>\r\n </div>\r\n }\r\n\r\n <!-- buttons -->\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n mat-icon-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"cancel()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n color=\"primary\"\r\n mat-icon-button\r\n matTooltip=\"Accept changes\"\r\n [disabled]=\"form.invalid || form.pristine\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"] }]
|
|
169
|
+
}], ctorParameters: () => [{ type: i1.FormBuilder }], propDecorators: { nameControl: [{
|
|
170
|
+
type: ViewChild,
|
|
171
|
+
args: ['nameCtl']
|
|
172
|
+
}], featNames: [{
|
|
173
|
+
type: Input
|
|
174
|
+
}], featValues: [{
|
|
175
|
+
type: Input
|
|
176
|
+
}], feature: [{
|
|
177
|
+
type: Input
|
|
178
|
+
}], isVar: [{
|
|
179
|
+
type: Input
|
|
180
|
+
}], featureCancel: [{
|
|
181
|
+
type: Output
|
|
182
|
+
}], featureChange: [{
|
|
183
|
+
type: Output
|
|
184
|
+
}] } });
|
|
185
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVhdHVyZS1lZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbXlybWlkb24vZ3ZlLWNvcmUvc3JjL2xpYi9jb21wb25lbnRzL2ZlYXR1cmUtZWRpdG9yL2ZlYXR1cmUtZWRpdG9yLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2d2ZS1jb3JlL3NyYy9saWIvY29tcG9uZW50cy9mZWF0dXJlLWVkaXRvci9mZWF0dXJlLWVkaXRvci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBSUwsbUJBQW1CLEVBQ25CLFVBQVUsR0FDWCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQWdCLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUV4RSxXQUFXO0FBQ1gsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTdELE9BQU8sRUFFTCxnQkFBZ0IsR0FHakIsTUFBTSw2QkFBNkIsQ0FBQzs7Ozs7Ozs7Ozs7O0FBVXJDOzs7Ozs7O0dBT0c7QUFrQkgsTUFBTSxPQUFPLHNCQUFzQjtJQWNqQzs7OztPQUlHO0lBQ0gsSUFDVyxVQUFVO1FBQ25CLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQztJQUNuQixDQUFDO0lBQ0QsSUFBVyxVQUFVLENBQUMsS0FBb0M7UUFDeEQsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLElBQUksU0FBUyxDQUFDO1FBQy9CLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFDVyxPQUFPO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBQ0QsSUFBVyxPQUFPLENBQUMsS0FBb0Q7UUFDckUsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLEtBQUssRUFBRSxDQUFDO1lBQzVCLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLElBQUksU0FBUyxDQUFDO1FBRW5DLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQy9CLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsV0FBVyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUMzQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDVixDQUFDO0lBaUNELFlBQVksV0FBd0I7UUEvQnBDOzs7V0FHRztRQUVJLFVBQUssR0FBRyxLQUFLLENBQUM7UUFFckI7O1dBRUc7UUFFSSxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFFaEQ7O1dBRUc7UUFFSSxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUE4QixDQUFDO1FBZXBFLElBQUksQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBUyxFQUFFLEVBQUU7WUFDMUMsVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzNELFdBQVcsRUFBRSxJQUFJO1NBQ2xCLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUU7WUFDbkMsVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4QyxXQUFXLEVBQUUsSUFBSTtTQUNsQixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsU0FBUyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFO1lBQzlELFdBQVcsRUFBRSxJQUFJO1NBQ2xCLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxTQUFTLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsUUFBUSxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDbEUsSUFBSSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3RFLElBQUksQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQztZQUM1QixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7WUFDakIsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO1lBQ3pCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO1NBQ2hDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxRQUFRO1FBQ2Isd0RBQXdEO1FBQ3hELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZO2FBQy9CLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQzthQUMvQyxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNsQixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVNLFdBQVc7UUFDaEIsSUFBSSxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRU8sZ0JBQWdCLENBQUMsRUFBVztRQUNsQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDUixPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDM0QsQ0FBQztJQUVPLFVBQVUsQ0FBQyxPQUEwQjtRQUMzQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3BCLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBUyxJQUFJLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3hFLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxTQUFTLElBQUksS0FBSyxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxLQUFLLENBQUMsQ0FBQztZQUNsRCxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsWUFBWSxJQUFJLEtBQUssQ0FBQyxDQUFDO1FBQzVELENBQUM7SUFDSCxDQUFDO0lBRU0sTUFBTTtRQUNYLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVNLElBQUk7UUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNyQixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUs7WUFDdkIsQ0FBQyxDQUFDO2dCQUNFLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUU7Z0JBQzVCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUU7Z0JBQzlCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUs7Z0JBQy9CLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUs7Z0JBQy9CLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUs7Z0JBQzdCLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUs7YUFDdEM7WUFDSCxDQUFDLENBQUM7Z0JBQ0UsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRTtnQkFDNUIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRTtnQkFDOUIsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSzthQUNoQyxDQUFDO1FBQ04sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3hDLENBQUM7OEdBaEtVLHNCQUFzQjtrR0FBdEIsc0JBQXNCLHFXQ3JFbkMscXhHQXNHQSxzSkQ5Q0ksWUFBWSwrUEFDWixtQkFBbUIsKzlCQUNuQixlQUFlLDJJQUNmLGlCQUFpQiw2V0FDakIsa0JBQWtCLHVZQUNsQixhQUFhLG1MQUNiLGNBQWMsMFdBQ2QsZUFBZSxtckJBQ2YsZ0JBQWdCOzsyRkFLUCxzQkFBc0I7a0JBakJsQyxTQUFTOytCQUNFLG9CQUFvQixjQUNsQixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixtQkFBbUI7d0JBQ25CLGVBQWU7d0JBQ2YsaUJBQWlCO3dCQUNqQixrQkFBa0I7d0JBQ2xCLGFBQWE7d0JBQ2IsY0FBYzt3QkFDZCxlQUFlO3dCQUNmLGdCQUFnQjtxQkFDakI7Z0ZBU3FCLFdBQVc7c0JBQWhDLFNBQVM7dUJBQUMsU0FBUztnQkFPYixTQUFTO3NCQURmLEtBQUs7Z0JBU0ssVUFBVTtzQkFEcEIsS0FBSztnQkFhSyxPQUFPO3NCQURqQixLQUFLO2dCQXFCQyxLQUFLO3NCQURYLEtBQUs7Z0JBT0MsYUFBYTtzQkFEbkIsTUFBTTtnQkFPQSxhQUFhO3NCQURuQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgRWxlbWVudFJlZixcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgT25EZXN0cm95LFxyXG4gIE9uSW5pdCxcclxuICBPdXRwdXQsXHJcbiAgVmlld0NoaWxkLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gIEZvcm1CdWlsZGVyLFxyXG4gIEZvcm1Db250cm9sLFxyXG4gIEZvcm1Hcm91cCxcclxuICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxyXG4gIFZhbGlkYXRvcnMsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIGRlYm91bmNlVGltZSwgZGlzdGluY3RVbnRpbENoYW5nZWQgfSBmcm9tICdyeGpzJztcclxuXHJcbi8vIG1hdGVyaWFsXHJcbmltcG9ydCB7IE1hdEJ1dHRvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XHJcbmltcG9ydCB7IE1hdENoZWNrYm94TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY2hlY2tib3gnO1xyXG5pbXBvcnQgeyBNYXRGb3JtRmllbGRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcclxuaW1wb3J0IHsgTWF0SWNvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2ljb24nO1xyXG5pbXBvcnQgeyBNYXRJbnB1dE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcclxuaW1wb3J0IHsgTWF0U2VsZWN0TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc2VsZWN0JztcclxuaW1wb3J0IHsgTWF0VG9vbHRpcE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3Rvb2x0aXAnO1xyXG5cclxuaW1wb3J0IHtcclxuICBGZWF0dXJlLFxyXG4gIEZlYXR1cmVTZXRQb2xpY3ksXHJcbiAgTGFiZWxlZElkLFxyXG4gIE9wZXJhdGlvbkZlYXR1cmUsXHJcbn0gZnJvbSAnQG15cm1pZG9uL2d2ZS1zbmFwc2hvdC12aWV3JztcclxuXHJcbi8qKlxyXG4gKiBGZWF0dXJlcyBtYXAuIFRoaXMgaXMgdXNlZCBmb3IgZmVhdHVyZXMgZnJvbSBjbG9zZWQgc2V0cyxcclxuICogYW5kIGxpc3RzIHRoZSBwb3NzaWJsZSB2YWx1ZXMgZm9yIGVhY2ggZmVhdHVyZS5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRmVhdHVyZU1hcCB7XHJcbiAgW2tleTogc3RyaW5nXTogTGFiZWxlZElkW107XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGZWF0dXJlIGVkaXRvci4gVGhpcyBlZGl0cyBhIHNpbmdsZSBmZWF0dXJlLCBlaXRoZXIgZnJlZSBvciBmcm9tXHJcbiAqIGEgY2xvc2VkIHNldC4gSW4gdGhlIGxhdHRlciBjYXNlIHlvdSBtdXN0IGRlZmluZSB0aGUgc2V0IHZpYVxyXG4gKiB0aGUgYGxhYmVsZWRJZHNgIGlucHV0LiBBbHNvLCB5b3UgY2FuIHByb3ZpZGUgYSBtYXAgb2YgZmVhdHVyZXNcclxuICogdG8gdmFsdWVzIHZpYSB0aGUgYG1hcGAgaW5wdXQuIFRoaXMgaXMgdXNlZnVsIHdoZW4geW91IHdhbnQgdG9cclxuICogcHJvdmlkZSBhIHNldCBvZiBmZWF0dXJlcyBhbmQgdmFsdWVzIHRvIHRoZSB1c2VyLCBhbmQgeW91IHdhbnRcclxuICogdG8gcHJvdmlkZSBodW1hbi1yZWFkYWJsZSBsYWJlbHMgZm9yIHRoZSB2YWx1ZXMuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2d2ZS1mZWF0dXJlLWVkaXRvcicsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbXHJcbiAgICBDb21tb25Nb2R1bGUsXHJcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxyXG4gICAgTWF0QnV0dG9uTW9kdWxlLFxyXG4gICAgTWF0Q2hlY2tib3hNb2R1bGUsXHJcbiAgICBNYXRGb3JtRmllbGRNb2R1bGUsXHJcbiAgICBNYXRJY29uTW9kdWxlLFxyXG4gICAgTWF0SW5wdXRNb2R1bGUsXHJcbiAgICBNYXRTZWxlY3RNb2R1bGUsXHJcbiAgICBNYXRUb29sdGlwTW9kdWxlLFxyXG4gIF0sXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2ZlYXR1cmUtZWRpdG9yLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybDogJy4vZmVhdHVyZS1lZGl0b3IuY29tcG9uZW50LmNzcycsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBGZWF0dXJlRWRpdG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG4gIHByaXZhdGUgX3N1Yj86IFN1YnNjcmlwdGlvbjtcclxuICBwcml2YXRlIF9mZWF0dXJlPzogT3BlcmF0aW9uRmVhdHVyZTtcclxuICBwcml2YXRlIF9tYXA/OiBGZWF0dXJlTWFwO1xyXG5cclxuICBAVmlld0NoaWxkKCduYW1lQ3RsJykgbmFtZUNvbnRyb2w/OiBFbGVtZW50UmVmO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgbGlzdCBvZiBmZWF0dXJlIG5hbWVzIHRvIGRpc3BsYXkgaW4gdGhlIG5hbWUgc2VsZWN0aW9uLlxyXG4gICAqIFRoaXMgaXMgdXNlZCB3aGVuIHlvdSBoYXZlIGEgY2xvc2VkIGxpc3Qgb2YgZmVhdHVyZXMuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBwdWJsaWMgZmVhdE5hbWVzOiBMYWJlbGVkSWRbXSB8IHVuZGVmaW5lZDtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGZlYXR1cmUgdmFsdWVzIG1hcC4gV2hlbiBzcGVjaWZpZWQgYW5kIHRoZSB1c2VyIHNlbGVjdHMgYSBmZWF0dXJlXHJcbiAgICogbmFtZSBwcmVzZW50IGluIHRoZSBtYXAga2V5cywgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVzIHdpbGwgYmUgdXNlZFxyXG4gICAqIHRvIHBvcHVsYXRlIHRoZSB2YWx1ZSBzZWxlY3Rpb24uXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBwdWJsaWMgZ2V0IGZlYXRWYWx1ZXMoKTogRmVhdHVyZU1hcCB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gdGhpcy5fbWFwO1xyXG4gIH1cclxuICBwdWJsaWMgc2V0IGZlYXRWYWx1ZXModmFsdWU6IEZlYXR1cmVNYXAgfCB1bmRlZmluZWQgfCBudWxsKSB7XHJcbiAgICB0aGlzLl9tYXAgPSB2YWx1ZSB8fCB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLm5hbWVJZHMgPSB0aGlzLmdldExhYmVsZWRJZHNGb3IodGhpcy5uYW1lLnZhbHVlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBmZWF0dXJlIHRvIGVkaXQuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBwdWJsaWMgZ2V0IGZlYXR1cmUoKTogRmVhdHVyZSB8IE9wZXJhdGlvbkZlYXR1cmUgfCB1bmRlZmluZWQge1xyXG4gICAgcmV0dXJuIHRoaXMuX2ZlYXR1cmU7XHJcbiAgfVxyXG4gIHB1YmxpYyBzZXQgZmVhdHVyZSh2YWx1ZTogRmVhdHVyZSB8IE9wZXJhdGlvbkZlYXR1cmUgfCB1bmRlZmluZWQgfCBudWxsKSB7XHJcbiAgICBpZiAodGhpcy5fZmVhdHVyZSA9PT0gdmFsdWUpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5fZmVhdHVyZSA9IHZhbHVlIHx8IHVuZGVmaW5lZDtcclxuXHJcbiAgICB0aGlzLnVwZGF0ZUZvcm0odGhpcy5fZmVhdHVyZSk7XHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgdGhpcy5uYW1lQ29udHJvbD8ubmF0aXZlRWxlbWVudD8uZm9jdXMoKTtcclxuICAgIH0sIDUwMCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUcnVlIGlmIHRoZSBmZWF0dXJlIGlzIGEgdmFyaWFudCBvcGVyYXRpb24gZmVhdHVyZSwgd2hpY2ggaGFzXHJcbiAgICogYWRkaXRpb25hbCBwcm9wZXJ0aWVzIGxpa2UgbmVnYXRpb24sIGdsb2JhbCwgYW5kIHNob3J0LWxpdmVkLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgcHVibGljIGlzVmFyID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgdXNlciBjYW5jZWxzIHRoZSBmZWF0dXJlIGVkaXRpbmcuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpXHJcbiAgcHVibGljIGZlYXR1cmVDYW5jZWwgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgdXNlciBzYXZlcyB0aGUgZWRpdGVkIGZlYXR1cmUuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpXHJcbiAgcHVibGljIGZlYXR1cmVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPEZlYXR1cmUgfCBPcGVyYXRpb25GZWF0dXJlPigpO1xyXG5cclxuICBwdWJsaWMgbmFtZTogRm9ybUNvbnRyb2w8c3RyaW5nPjtcclxuICBwdWJsaWMgdmFsdWU6IEZvcm1Db250cm9sPHN0cmluZz47XHJcbiAgcHVibGljIHNldFBvbGljeTogRm9ybUNvbnRyb2w8RmVhdHVyZVNldFBvbGljeT47XHJcbiAgLy8gdmFyIGZlYXR1cmUgY29udHJvbHNcclxuICBwdWJsaWMgaXNOZWdhdGVkOiBGb3JtQ29udHJvbDxib29sZWFuPjtcclxuICBwdWJsaWMgaXNHbG9iYWw6IEZvcm1Db250cm9sPGJvb2xlYW4+O1xyXG4gIHB1YmxpYyBpc1Nob3J0TGl2ZWQ6IEZvcm1Db250cm9sPGJvb2xlYW4+O1xyXG5cclxuICBwdWJsaWMgZm9ybTogRm9ybUdyb3VwO1xyXG5cclxuICBwdWJsaWMgbmFtZUlkcz86IExhYmVsZWRJZFtdO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihmb3JtQnVpbGRlcjogRm9ybUJ1aWxkZXIpIHtcclxuICAgIHRoaXMubmFtZSA9IGZvcm1CdWlsZGVyLmNvbnRyb2w8c3RyaW5nPignJywge1xyXG4gICAgICB2YWxpZGF0b3JzOiBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5tYXhMZW5ndGgoNTApXSxcclxuICAgICAgbm9uTnVsbGFibGU6IHRydWUsXHJcbiAgICB9KTtcclxuICAgIHRoaXMudmFsdWUgPSBmb3JtQnVpbGRlci5jb250cm9sKCcnLCB7XHJcbiAgICAgIHZhbGlkYXRvcnM6IFtWYWxpZGF0b3JzLm1heExlbmd0aCg1MDAwKV0sXHJcbiAgICAgIG5vbk51bGxhYmxlOiB0cnVlLFxyXG4gICAgfSk7XHJcbiAgICB0aGlzLnNldFBvbGljeSA9IGZvcm1CdWlsZGVyLmNvbnRyb2woRmVhdHVyZVNldFBvbGljeS5tdWx0aXBsZSwge1xyXG4gICAgICBub25OdWxsYWJsZTogdHJ1ZSxcclxuICAgIH0pO1xyXG4gICAgdGhpcy5pc05lZ2F0ZWQgPSBmb3JtQnVpbGRlci5jb250cm9sKGZhbHNlLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pO1xyXG4gICAgdGhpcy5pc0dsb2JhbCA9IGZvcm1CdWlsZGVyLmNvbnRyb2woZmFsc2UsIHsgbm9uTnVsbGFibGU6IHRydWUgfSk7XHJcbiAgICB0aGlzLmlzU2hvcnRMaXZlZCA9IGZvcm1CdWlsZGVyLmNvbnRyb2woZmFsc2UsIHsgbm9uTnVsbGFibGU6IHRydWUgfSk7XHJcbiAgICB0aGlzLmZvcm0gPSBmb3JtQnVpbGRlci5ncm91cCh7XHJcbiAgICAgIG5hbWU6IHRoaXMubmFtZSxcclxuICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXHJcbiAgICAgIHNldFBvbGljeTogdGhpcy5zZXRQb2xpY3ksXHJcbiAgICAgIGlzTmVnYXRlZDogdGhpcy5pc05lZ2F0ZWQsXHJcbiAgICAgIGlzR2xvYmFsOiB0aGlzLmlzR2xvYmFsLFxyXG4gICAgICBpc1Nob3J0TGl2ZWQ6IHRoaXMuaXNTaG9ydExpdmVkLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICAvLyB3aGVuZXZlciB0aGUgbmFtZSBjaGFuZ2VzLCB1cGRhdGUgdGhlIHZhbHVlIHNlbGVjdGlvblxyXG4gICAgdGhpcy5fc3ViID0gdGhpcy5uYW1lLnZhbHVlQ2hhbmdlc1xyXG4gICAgICAucGlwZShkZWJvdW5jZVRpbWUoMzAwKSwgZGlzdGluY3RVbnRpbENoYW5nZWQoKSlcclxuICAgICAgLnN1YnNjcmliZSgobmFtZSkgPT4ge1xyXG4gICAgICAgIHRoaXMudmFsdWUucmVzZXQoKTtcclxuICAgICAgICB0aGlzLm5hbWVJZHMgPSB0aGlzLmdldExhYmVsZWRJZHNGb3IobmFtZSk7XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5fc3ViPy51bnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRMYWJlbGVkSWRzRm9yKGlkPzogc3RyaW5nKTogTGFiZWxlZElkW10gfCB1bmRlZmluZWQge1xyXG4gICAgaWYgKCFpZCkge1xyXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuZmVhdFZhbHVlcyA/IHRoaXMuZmVhdFZhbHVlc1tpZF0gOiB1bmRlZmluZWQ7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwZGF0ZUZvcm0oZmVhdHVyZT86IE9wZXJhdGlvbkZlYXR1cmUpOiB2b2lkIHtcclxuICAgIGlmICghZmVhdHVyZSkge1xyXG4gICAgICB0aGlzLmZvcm0ucmVzZXQoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMubmFtZS5zZXRWYWx1ZShmZWF0dXJlLm5hbWUpO1xyXG4gICAgICB0aGlzLnZhbHVlLnNldFZhbHVlKGZlYXR1cmUudmFsdWUpO1xyXG4gICAgICB0aGlzLnNldFBvbGljeS5zZXRWYWx1ZShmZWF0dXJlLnNldFBvbGljeSB8fCBGZWF0dXJlU2V0UG9saWN5Lm11bHRpcGxlKTtcclxuICAgICAgdGhpcy5pc05lZ2F0ZWQuc2V0VmFsdWUoZmVhdHVyZS5pc05lZ2F0ZWQgfHwgZmFsc2UpO1xyXG4gICAgICB0aGlzLmlzR2xvYmFsLnNldFZhbHVlKGZlYXR1cmUuaXNHbG9iYWwgfHwgZmFsc2UpO1xyXG4gICAgICB0aGlzLmlzU2hvcnRMaXZlZC5zZXRWYWx1ZShmZWF0dXJlLmlzU2hvcnRMaXZlZCB8fCBmYWxzZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY2FuY2VsKCk6IHZvaWQge1xyXG4gICAgdGhpcy5mZWF0dXJlQ2FuY2VsLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzYXZlKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmZvcm0udmFsaWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5mZWF0dXJlID0gdGhpcy5pc1ZhclxyXG4gICAgICA/IHtcclxuICAgICAgICAgIG5hbWU6IHRoaXMubmFtZS52YWx1ZS50cmltKCksXHJcbiAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZS52YWx1ZS50cmltKCksXHJcbiAgICAgICAgICBzZXRQb2xpY3k6IHRoaXMuc2V0UG9saWN5LnZhbHVlLFxyXG4gICAgICAgICAgaXNOZWdhdGVkOiB0aGlzLmlzTmVnYXRlZC52YWx1ZSxcclxuICAgICAgICAgIGlzR2xvYmFsOiB0aGlzLmlzR2xvYmFsLnZhbHVlLFxyXG4gICAgICAgICAgaXNTaG9ydExpdmVkOiB0aGlzLmlzU2hvcnRMaXZlZC52YWx1ZSxcclxuICAgICAgICB9XHJcbiAgICAgIDoge1xyXG4gICAgICAgICAgbmFtZTogdGhpcy5uYW1lLnZhbHVlLnRyaW0oKSxcclxuICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlLnZhbHVlLnRyaW0oKSxcclxuICAgICAgICAgIHNldFBvbGljeTogdGhpcy5zZXRQb2xpY3kudmFsdWUsXHJcbiAgICAgICAgfTtcclxuICAgIHRoaXMuZmVhdHVyZUNoYW5nZS5lbWl0KHRoaXMuZmVhdHVyZSk7XHJcbiAgfVxyXG59XHJcbiIsIjxmb3JtIFtmb3JtR3JvdXBdPVwiZm9ybVwiIChzdWJtaXQpPVwic2F2ZSgpXCI+XHJcbiAgPGRpdiBjbGFzcz1cImZvcm0tcm93XCI+XHJcbiAgICBAaWYgKGZlYXROYW1lcz8ubGVuZ3RoKSB7XHJcbiAgICA8IS0tIG5hbWUgKGJvdW5kKSAtLT5cclxuICAgIDxtYXQtZm9ybS1maWVsZD5cclxuICAgICAgPG1hdC1sYWJlbD5uYW1lPC9tYXQtbGFiZWw+XHJcbiAgICAgIDxtYXQtc2VsZWN0ICNuYW1lQ3RsIFtmb3JtQ29udHJvbF09XCJuYW1lXCI+XHJcbiAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGkgb2YgZmVhdE5hbWVzXCIgW3ZhbHVlXT1cImkuaWRcIj57e1xyXG4gICAgICAgICAgaS5sYWJlbFxyXG4gICAgICAgIH19PC9tYXQtb3B0aW9uPlxyXG4gICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgIEBpZiAoJGFueShuYW1lKS5lcnJvcnM/LnJlcXVpcmVkICYmIChuYW1lLmRpcnR5IHx8IG5hbWUudG91Y2hlZCkpIHtcclxuICAgICAgPG1hdC1lcnJvcj5uYW1lIHJlcXVpcmVkPC9tYXQtZXJyb3I+XHJcbiAgICAgIH1cclxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICB9IEBlbHNlIHtcclxuICAgIDwhLS0gbmFtZSAoZnJlZSkgLS0+XHJcbiAgICA8bWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgIDxtYXQtbGFiZWw+bmFtZTwvbWF0LWxhYmVsPlxyXG4gICAgICA8aW5wdXQgI25hbWVDdGwgbWF0SW5wdXQgW2Zvcm1Db250cm9sXT1cIm5hbWVcIiAvPlxyXG4gICAgICA8bWF0LWVycm9yXHJcbiAgICAgICAgKm5nSWY9XCIkYW55KG5hbWUpLmVycm9ycz8ucmVxdWlyZWQgJiYgKG5hbWUuZGlydHkgfHwgbmFtZS50b3VjaGVkKVwiXHJcbiAgICAgICAgPm5hbWUgcmVxdWlyZWQ8L21hdC1lcnJvclxyXG4gICAgICA+XHJcbiAgICAgIEBpZiAoJGFueShuYW1lKS5lcnJvcnM/Lm1heExlbmd0aCAmJiAobmFtZS5kaXJ0eSB8fCBuYW1lLnRvdWNoZWQpKSB7XHJcbiAgICAgIDxtYXQtZXJyb3I+bmFtZSB0b28gbG9uZzwvbWF0LWVycm9yPlxyXG4gICAgICB9XHJcbiAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgfVxyXG5cclxuICAgIDwhLS0gdmFsdWUgKGJvdW5kKSAtLT5cclxuICAgIEBpZiAobmFtZUlkcz8ubGVuZ3RoKSB7XHJcbiAgICA8bWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgIDxtYXQtbGFiZWw+dmFsdWU8L21hdC1sYWJlbD5cclxuICAgICAgPG1hdC1zZWxlY3QgW2Zvcm1Db250cm9sXT1cInZhbHVlXCI+XHJcbiAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGUgb2YgbmFtZUlkc1wiIFt2YWx1ZV09XCJlLmlkXCI+e3tcclxuICAgICAgICAgIGUubGFiZWxcclxuICAgICAgICB9fTwvbWF0LW9wdGlvbj5cclxuICAgICAgPC9tYXQtc2VsZWN0PlxyXG4gICAgICBAaWYgKCRhbnkodmFsdWUpLmVycm9ycz8ucmVxdWlyZWQgJiYgKHZhbHVlLmRpcnR5IHx8IHZhbHVlLnRvdWNoZWQpKSB7XHJcbiAgICAgIDxtYXQtZXJyb3I+dmFsdWUgcmVxdWlyZWQ8L21hdC1lcnJvcj5cclxuICAgICAgfVxyXG4gICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIH0gQGVsc2Uge1xyXG4gICAgPCEtLSB2YWx1ZSAoZnJlZSkgLS0+XHJcbiAgICA8bWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgIDxtYXQtbGFiZWw+dmFsdWU8L21hdC1sYWJlbD5cclxuICAgICAgPGlucHV0IG1hdElucHV0IFtmb3JtQ29udHJvbF09XCJ2YWx1ZVwiIC8+XHJcbiAgICAgIEBpZiAoJGFueSh2YWx1ZSkuZXJyb3JzPy5yZXF1aXJlZCAmJiAodmFsdWUuZGlydHkgfHwgdmFsdWUudG91Y2hlZCkpIHtcclxuICAgICAgPG1hdC1lcnJvcj52YWx1ZSByZXF1aXJlZDwvbWF0LWVycm9yPlxyXG4gICAgICB9IEBpZiAoJGFueSh2YWx1ZSkuZXJyb3JzPy5tYXhMZW5ndGggJiYgKHZhbHVlLmRpcnR5IHx8IHZhbHVlLnRvdWNoZWQpKSB7XHJcbiAgICAgIDxtYXQtZXJyb3I+dmFsdWUgdG9vIGxvbmc8L21hdC1lcnJvcj5cclxuICAgICAgfVxyXG4gICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIH1cclxuXHJcbiAgICA8IS0tIHNldFBvbGljeSAtLT5cclxuICAgIDxtYXQtZm9ybS1maWVsZD5cclxuICAgICAgPG1hdC1sYWJlbD5zZXQgcG9saWN5PC9tYXQtbGFiZWw+XHJcbiAgICAgIDxtYXQtc2VsZWN0IFtmb3JtQ29udHJvbF09XCJzZXRQb2xpY3lcIj5cclxuICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwiMFwiPm11bHRpcGxlPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCIxXCI+c2luZ2xlPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCIyXCI+c2luZ2xlIGZpcnN0PC9tYXQtb3B0aW9uPlxyXG4gICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gIDwvZGl2PlxyXG5cclxuICBAaWYgKGlzVmFyKSB7XHJcbiAgPGRpdiBjbGFzcz1cImZvcm0tcm93XCI+XHJcbiAgICA8IS0tIGlzTmVnYXRlZCAtLT5cclxuICAgIDxtYXQtY2hlY2tib3ggW2Zvcm1Db250cm9sXT1cImlzTmVnYXRlZFwiPm5lZ2F0ZWQ8L21hdC1jaGVja2JveD5cclxuXHJcbiAgICA8IS0tIGlzU2hvcnRMaXZlZCAtLT5cclxuICAgIDxtYXQtY2hlY2tib3ggW2Zvcm1Db250cm9sXT1cImlzU2hvcnRMaXZlZFwiPnNob3J0LWxpdmVkPC9tYXQtY2hlY2tib3g+XHJcblxyXG4gICAgPCEtLSBpc0dsb2JhbCAtLT5cclxuICAgIDxtYXQtY2hlY2tib3ggW2Zvcm1Db250cm9sXT1cImlzR2xvYmFsXCI+Z2xvYmFsPC9tYXQtY2hlY2tib3g+XHJcbiAgPC9kaXY+XHJcbiAgfVxyXG5cclxuICA8IS0tIGJ1dHRvbnMgLS0+XHJcbiAgPGRpdiBjbGFzcz1cImZvcm0tcm93XCI+XHJcbiAgICA8YnV0dG9uXHJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICBjb2xvcj1cIndhcm5cIlxyXG4gICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgbWF0VG9vbHRpcD1cIkRpc2NhcmQgY2hhbmdlc1wiXHJcbiAgICAgIChjbGljayk9XCJjYW5jZWwoKVwiXHJcbiAgICA+XHJcbiAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1hdC13YXJuXCI+Y2xlYXI8L21hdC1pY29uPlxyXG4gICAgPC9idXR0b24+XHJcbiAgICA8YnV0dG9uXHJcbiAgICAgIHR5cGU9XCJzdWJtaXRcIlxyXG4gICAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgbWF0VG9vbHRpcD1cIkFjY2VwdCBjaGFuZ2VzXCJcclxuICAgICAgW2Rpc2FibGVkXT1cImZvcm0uaW52YWxpZCB8fCBmb3JtLnByaXN0aW5lXCJcclxuICAgID5cclxuICAgICAgPG1hdC1pY29uIGNsYXNzPVwibWF0LXByaW1hcnlcIj5jaGVja19jaXJjbGU8L21hdC1pY29uPlxyXG4gICAgPC9idXR0b24+XHJcbiAgPC9kaXY+XHJcbjwvZm9ybT5cclxuIl19
|