@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,141 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output, ViewChild, } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { ReactiveFormsModule, Validators, } from '@angular/forms';
|
|
4
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
5
|
+
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
6
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
7
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
8
|
+
import { MatInputModule } from '@angular/material/input';
|
|
9
|
+
import { MatSelectModule } from '@angular/material/select';
|
|
10
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
11
|
+
import * as i0 from "@angular/core";
|
|
12
|
+
import * as i1 from "@angular/forms";
|
|
13
|
+
import * as i2 from "@angular/common";
|
|
14
|
+
import * as i3 from "@angular/material/button";
|
|
15
|
+
import * as i4 from "@angular/material/form-field";
|
|
16
|
+
import * as i5 from "@angular/material/icon";
|
|
17
|
+
import * as i6 from "@angular/material/input";
|
|
18
|
+
import * as i7 from "@angular/material/tooltip";
|
|
19
|
+
export class AnimationVarsComponent {
|
|
20
|
+
get vars() {
|
|
21
|
+
return this._vars;
|
|
22
|
+
}
|
|
23
|
+
set vars(value) {
|
|
24
|
+
if (this._vars === value) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
this._vars = value;
|
|
28
|
+
this.updateForm(value);
|
|
29
|
+
}
|
|
30
|
+
constructor(formBuilder) {
|
|
31
|
+
this._vars = {};
|
|
32
|
+
this.varsChange = new EventEmitter();
|
|
33
|
+
this.editedVars = [];
|
|
34
|
+
this.name = formBuilder.control('', {
|
|
35
|
+
nonNullable: true,
|
|
36
|
+
validators: [Validators.required, Validators.maxLength(100)],
|
|
37
|
+
});
|
|
38
|
+
this.value = formBuilder.control('', {
|
|
39
|
+
nonNullable: true,
|
|
40
|
+
validators: [Validators.required, Validators.maxLength(1000)],
|
|
41
|
+
});
|
|
42
|
+
this.form = formBuilder.group({
|
|
43
|
+
name: this.name,
|
|
44
|
+
value: this.value,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
updateForm(vars) {
|
|
48
|
+
this.editedVars = Object.entries(vars)
|
|
49
|
+
.map(([name, value]) => ({ name, value }))
|
|
50
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
51
|
+
}
|
|
52
|
+
getVars() {
|
|
53
|
+
return this.editedVars.reduce((acc, { name, value }) => ({ ...acc, [name]: value }), {});
|
|
54
|
+
}
|
|
55
|
+
addVar() {
|
|
56
|
+
this.form.reset();
|
|
57
|
+
// focus the name input
|
|
58
|
+
setTimeout(() => this.nameInput?.nativeElement.focus(), 0);
|
|
59
|
+
}
|
|
60
|
+
editVar(index) {
|
|
61
|
+
const { name, value } = this.editedVars[index];
|
|
62
|
+
this.form.setValue({ name, value });
|
|
63
|
+
this.form.markAsPristine();
|
|
64
|
+
// focus the name input
|
|
65
|
+
setTimeout(() => this.nameInput?.nativeElement.focus(), 0);
|
|
66
|
+
}
|
|
67
|
+
deleteVar(index) {
|
|
68
|
+
this.editedVars = this.editedVars.filter((_, i) => i !== index);
|
|
69
|
+
this.varsChange.emit(this.getVars());
|
|
70
|
+
}
|
|
71
|
+
parseValue(value) {
|
|
72
|
+
if (!value) {
|
|
73
|
+
return '';
|
|
74
|
+
}
|
|
75
|
+
if (value === 'true') {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
else if (value === 'false') {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
else if (/^\d+$/.test(value)) {
|
|
82
|
+
return parseInt(value, 10);
|
|
83
|
+
}
|
|
84
|
+
else if (/^\d+\.\d+$/.test(value)) {
|
|
85
|
+
return parseFloat(value);
|
|
86
|
+
}
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
saveVar() {
|
|
90
|
+
if (this.form.invalid) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const { name, value } = this.form.value;
|
|
94
|
+
// parse value assuming that if it looks like a boolean/number
|
|
95
|
+
// its value should be a boolean/number rather than a string
|
|
96
|
+
const v = this.parseValue(value);
|
|
97
|
+
const editedVars = [...this.editedVars];
|
|
98
|
+
// if name already exists, update the value; else add it
|
|
99
|
+
const existingIndex = this.editedVars.findIndex((vr) => vr.name === name);
|
|
100
|
+
if (existingIndex !== -1) {
|
|
101
|
+
editedVars[existingIndex] = { name, value: v };
|
|
102
|
+
this.editedVars = editedVars;
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
editedVars.push({ name, value: v });
|
|
107
|
+
this.editedVars = editedVars.sort((a, b) => a.name.localeCompare(b.name));
|
|
108
|
+
}
|
|
109
|
+
this.varsChange.emit(this.getVars());
|
|
110
|
+
setTimeout(() => {
|
|
111
|
+
this.nameInput?.nativeElement.focus();
|
|
112
|
+
this.form.reset();
|
|
113
|
+
this.form.markAsPristine();
|
|
114
|
+
this.form.updateValueAndValidity();
|
|
115
|
+
}, 0);
|
|
116
|
+
}
|
|
117
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: AnimationVarsComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
118
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.4", type: AnimationVarsComponent, isStandalone: true, selector: "gve-animation-vars", inputs: { vars: "vars" }, outputs: { varsChange: "varsChange" }, viewQueries: [{ propertyName: "nameInput", first: true, predicate: ["vname"], descendants: true, static: true }], ngImport: i0, template: "<div>\r\n <div>\r\n <button type=\"button\" mat-raised-button color=\"primary\" (click)=\"addVar()\">\r\n <mat-icon>add</mat-icon>\r\n property\r\n </button>\r\n </div>\r\n\r\n @if (editedVars.length) {\r\n <table>\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>name</th>\r\n <th>value</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (v of editedVars; track v.name; let index=$index) {\r\n <tr>\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"editVar(index)\"\r\n matTooltip=\"Edit this property\"\r\n >\r\n <mat-icon class=\"mat-primary\">edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"deleteVar(index)\"\r\n matTooltip=\"Delete this property\"\r\n >\r\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ v.name }}</td>\r\n <td>{{ v.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n } @else {\r\n <p class=\"muted\">(no vars)</p>\r\n }\r\n\r\n <form [formGroup]=\"form\" (submit)=\"saveVar()\">\r\n <fieldset>\r\n <div class=\"form-row\">\r\n <!-- name -->\r\n <mat-form-field>\r\n <mat-label>name</mat-label>\r\n <input matInput [formControl]=\"name\" #vname />\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 <mat-error\r\n *ngIf=\"$any(name).errors?.maxLength && (name.dirty || name.touched)\"\r\n >name too long</mat-error\r\n >\r\n </mat-form-field>\r\n\r\n <!-- value -->\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n <mat-error\r\n *ngIf=\"\r\n $any(value).errors?.required && (value.dirty || value.touched)\r\n \"\r\n >value required</mat-error\r\n >\r\n <mat-error\r\n *ngIf=\"\r\n $any(value).errors?.maxLength && (value.dirty || value.touched)\r\n \"\r\n >value too long</mat-error\r\n >\r\n </mat-form-field>\r\n\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </div>\r\n </fieldset>\r\n </form>\r\n</div>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}fieldset{border:1px solid silver;border-radius:4px;padding:8px;margin:8px 0}table{width:100%;border-collapse:collapse}th{color:#909090;font-weight:400;text-align:left;background-color:#e1e0e0}th,td{padding:4px;border-bottom:1px solid silver}tbody tr:nth-child(2n){background-color:#e8e8e8}td.fit-width{width:1px;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.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: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
|
|
119
|
+
}
|
|
120
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: AnimationVarsComponent, decorators: [{
|
|
121
|
+
type: Component,
|
|
122
|
+
args: [{ selector: 'gve-animation-vars', standalone: true, imports: [
|
|
123
|
+
CommonModule,
|
|
124
|
+
ReactiveFormsModule,
|
|
125
|
+
MatButtonModule,
|
|
126
|
+
MatCheckboxModule,
|
|
127
|
+
MatFormFieldModule,
|
|
128
|
+
MatIconModule,
|
|
129
|
+
MatInputModule,
|
|
130
|
+
MatSelectModule,
|
|
131
|
+
MatTooltipModule,
|
|
132
|
+
], template: "<div>\r\n <div>\r\n <button type=\"button\" mat-raised-button color=\"primary\" (click)=\"addVar()\">\r\n <mat-icon>add</mat-icon>\r\n property\r\n </button>\r\n </div>\r\n\r\n @if (editedVars.length) {\r\n <table>\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>name</th>\r\n <th>value</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (v of editedVars; track v.name; let index=$index) {\r\n <tr>\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"editVar(index)\"\r\n matTooltip=\"Edit this property\"\r\n >\r\n <mat-icon class=\"mat-primary\">edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"deleteVar(index)\"\r\n matTooltip=\"Delete this property\"\r\n >\r\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ v.name }}</td>\r\n <td>{{ v.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n } @else {\r\n <p class=\"muted\">(no vars)</p>\r\n }\r\n\r\n <form [formGroup]=\"form\" (submit)=\"saveVar()\">\r\n <fieldset>\r\n <div class=\"form-row\">\r\n <!-- name -->\r\n <mat-form-field>\r\n <mat-label>name</mat-label>\r\n <input matInput [formControl]=\"name\" #vname />\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 <mat-error\r\n *ngIf=\"$any(name).errors?.maxLength && (name.dirty || name.touched)\"\r\n >name too long</mat-error\r\n >\r\n </mat-form-field>\r\n\r\n <!-- value -->\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n <mat-error\r\n *ngIf=\"\r\n $any(value).errors?.required && (value.dirty || value.touched)\r\n \"\r\n >value required</mat-error\r\n >\r\n <mat-error\r\n *ngIf=\"\r\n $any(value).errors?.maxLength && (value.dirty || value.touched)\r\n \"\r\n >value too long</mat-error\r\n >\r\n </mat-form-field>\r\n\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </div>\r\n </fieldset>\r\n </form>\r\n</div>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}fieldset{border:1px solid silver;border-radius:4px;padding:8px;margin:8px 0}table{width:100%;border-collapse:collapse}th{color:#909090;font-weight:400;text-align:left;background-color:#e1e0e0}th,td{padding:4px;border-bottom:1px solid silver}tbody tr:nth-child(2n){background-color:#e8e8e8}td.fit-width{width:1px;white-space:nowrap}\n"] }]
|
|
133
|
+
}], ctorParameters: () => [{ type: i1.FormBuilder }], propDecorators: { vars: [{
|
|
134
|
+
type: Input
|
|
135
|
+
}], varsChange: [{
|
|
136
|
+
type: Output
|
|
137
|
+
}], nameInput: [{
|
|
138
|
+
type: ViewChild,
|
|
139
|
+
args: ['vname', { static: true }]
|
|
140
|
+
}] } });
|
|
141
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5pbWF0aW9uLXZhcnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbXlybWlkb24vZ3ZlLWNvcmUvc3JjL2xpYi9jb21wb25lbnRzL2FuaW1hdGlvbi12YXJzL2FuaW1hdGlvbi12YXJzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2d2ZS1jb3JlL3NyYy9saWIvY29tcG9uZW50cy9hbmltYXRpb24tdmFycy9hbmltYXRpb24tdmFycy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUlMLG1CQUFtQixFQUNuQixVQUFVLEdBQ1gsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7Ozs7Ozs7OztBQTBCN0QsTUFBTSxPQUFPLHNCQUFzQjtJQUdqQyxJQUNXLElBQUk7UUFDYixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDcEIsQ0FB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ZSx3VUFDZixpQkFBaUIsOEJBQ2pCLGtCQUFrQix1WUFDbEIsYUFBYSxtTEFDYixjQUFjLDBXQUNkLGVBQWUsOEJBQ2YsZ0JBQWdCOzsyRkFLUCxzQkFBc0I7a0JBakJsQyxTQUFTOytCQUNFLG9CQUFvQixjQUNsQixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixtQkFBbUI7d0JBQ25CLGVBQWU7d0JBQ2YsaUJBQWlCO3dCQUNqQixrQkFBa0I7d0JBQ2xCLGFBQWE7d0JBQ2IsY0FBYzt3QkFDZCxlQUFlO3dCQUNmLGdCQUFnQjtxQkFDakI7Z0ZBUVUsSUFBSTtzQkFEZCxLQUFLO2dCQWFDLFVBQVU7c0JBRGhCLE1BQU07Z0JBS0EsU0FBUztzQkFEZixTQUFTO3VCQUFDLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBJbnB1dCxcclxuICBPdXRwdXQsXHJcbiAgVmlld0NoaWxkLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHtcclxuICBGb3JtQnVpbGRlcixcclxuICBGb3JtQ29udHJvbCxcclxuICBGb3JtR3JvdXAsXHJcbiAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcclxuICBWYWxpZGF0b3JzLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgTWF0QnV0dG9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcclxuaW1wb3J0IHsgTWF0Q2hlY2tib3hNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jaGVja2JveCc7XHJcbmltcG9ydCB7IE1hdEZvcm1GaWVsZE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xyXG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XHJcbmltcG9ydCB7IE1hdElucHV0TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xyXG5pbXBvcnQgeyBNYXRTZWxlY3RNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xyXG5pbXBvcnQgeyBNYXRUb29sdGlwTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdG9vbHRpcCc7XHJcblxyXG5pbXBvcnQgeyBHdmVBbmltYXRpb25WYXJzIH0gZnJvbSAnQG15cm1pZG9uL2d2ZS1zbmFwc2hvdC12aWV3JztcclxuXHJcbmludGVyZmFjZSBWYXJWaWV3TW9kZWwge1xyXG4gIG5hbWU6IHN0cmluZztcclxuICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbjtcclxufVxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdndmUtYW5pbWF0aW9uLXZhcnMnLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW1xyXG4gICAgQ29tbW9uTW9kdWxlLFxyXG4gICAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcclxuICAgIE1hdEJ1dHRvbk1vZHVsZSxcclxuICAgIE1hdENoZWNrYm94TW9kdWxlLFxyXG4gICAgTWF0Rm9ybUZpZWxkTW9kdWxlLFxyXG4gICAgTWF0SWNvbk1vZHVsZSxcclxuICAgIE1hdElucHV0TW9kdWxlLFxyXG4gICAgTWF0U2VsZWN0TW9kdWxlLFxyXG4gICAgTWF0VG9vbHRpcE1vZHVsZSxcclxuICBdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9hbmltYXRpb24tdmFycy5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL2FuaW1hdGlvbi12YXJzLmNvbXBvbmVudC5jc3MnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQW5pbWF0aW9uVmFyc0NvbXBvbmVudCB7XHJcbiAgcHJpdmF0ZSBfdmFyczogR3ZlQW5pbWF0aW9uVmFycyA9IHt9O1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHB1YmxpYyBnZXQgdmFycygpOiBHdmVBbmltYXRpb25WYXJzIHtcclxuICAgIHJldHVybiB0aGlzLl92YXJzO1xyXG4gIH1cclxuICBwdWJsaWMgc2V0IHZhcnModmFsdWU6IEd2ZUFuaW1hdGlvblZhcnMpIHtcclxuICAgIGlmICh0aGlzLl92YXJzID09PSB2YWx1ZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLl92YXJzID0gdmFsdWU7XHJcbiAgICB0aGlzLnVwZGF0ZUZvcm0odmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgQE91dHB1dCgpXHJcbiAgcHVibGljIHZhcnNDaGFuZ2U6IEV2ZW50RW1pdHRlcjxHdmVBbmltYXRpb25WYXJzPiA9XHJcbiAgICBuZXcgRXZlbnRFbWl0dGVyPEd2ZUFuaW1hdGlvblZhcnM+KCk7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ3ZuYW1lJywgeyBzdGF0aWM6IHRydWUgfSlcclxuICBwdWJsaWMgbmFtZUlucHV0PzogRWxlbWVudFJlZjtcclxuXHJcbiAgcHVibGljIG5hbWU6IEZvcm1Db250cm9sPHN0cmluZz47XHJcbiAgcHVibGljIHZhbHVlOiBGb3JtQ29udHJvbDxzdHJpbmc+O1xyXG4gIHB1YmxpYyBmb3JtOiBGb3JtR3JvdXA7XHJcblxyXG4gIHB1YmxpYyBlZGl0ZWRWYXJzOiBWYXJWaWV3TW9kZWxbXSA9IFtdO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihmb3JtQnVpbGRlcjogRm9ybUJ1aWxkZXIpIHtcclxuICAgIHRoaXMubmFtZSA9IGZvcm1CdWlsZGVyLmNvbnRyb2w8c3RyaW5nPignJywge1xyXG4gICAgICBub25OdWxsYWJsZTogdHJ1ZSxcclxuICAgICAgdmFsaWRhdG9yczogW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWF4TGVuZ3RoKDEwMCldLFxyXG4gICAgfSk7XHJcbiAgICB0aGlzLnZhbHVlID0gZm9ybUJ1aWxkZXIuY29udHJvbDxzdHJpbmc+KCcnLCB7XHJcbiAgICAgIG5vbk51bGxhYmxlOiB0cnVlLFxyXG4gICAgICB2YWxpZGF0b3JzOiBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5tYXhMZW5ndGgoMTAwMCldLFxyXG4gICAgfSk7XHJcbiAgICB0aGlzLmZvcm0gPSBmb3JtQnVpbGRlci5ncm91cCh7XHJcbiAgICAgIG5hbWU6IHRoaXMubmFtZSxcclxuICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBkYXRlRm9ybSh2YXJzOiBHdmVBbmltYXRpb25WYXJzKTogdm9pZCB7XHJcbiAgICB0aGlzLmVkaXRlZFZhcnMgPSBPYmplY3QuZW50cmllcyh2YXJzKVxyXG4gICAgICAubWFwKChbbmFtZSwgdmFsdWVdKSA9PiAoeyBuYW1lLCB2YWx1ZSB9KSlcclxuICAgICAgLnNvcnQoKGEsIGIpID0+IGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRWYXJzKCk6IEd2ZUFuaW1hdGlvblZhcnMge1xyXG4gICAgcmV0dXJuIHRoaXMuZWRpdGVkVmFycy5yZWR1Y2UoXHJcbiAgICAgIChhY2MsIHsgbmFtZSwgdmFsdWUgfSkgPT4gKHsgLi4uYWNjLCBbbmFtZV06IHZhbHVlIH0pLFxyXG4gICAgICB7fVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhZGRWYXIoKTogdm9pZCB7XHJcbiAgICB0aGlzLmZvcm0ucmVzZXQoKTtcclxuICAgIC8vIGZvY3VzIHRoZSBuYW1lIGlucHV0XHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMubmFtZUlucHV0Py5uYXRpdmVFbGVtZW50LmZvY3VzKCksIDApO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGVkaXRWYXIoaW5kZXg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgY29uc3QgeyBuYW1lLCB2YWx1ZSB9ID0gdGhpcy5lZGl0ZWRWYXJzW2luZGV4XTtcclxuICAgIHRoaXMuZm9ybS5zZXRWYWx1ZSh7IG5hbWUsIHZhbHVlIH0pO1xyXG4gICAgdGhpcy5mb3JtLm1hcmtBc1ByaXN0aW5lKCk7XHJcbiAgICAvLyBmb2N1cyB0aGUgbmFtZSBpbnB1dFxyXG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLm5hbWVJbnB1dD8ubmF0aXZlRWxlbWVudC5mb2N1cygpLCAwKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBkZWxldGVWYXIoaW5kZXg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgdGhpcy5lZGl0ZWRWYXJzID0gdGhpcy5lZGl0ZWRWYXJzLmZpbHRlcigoXywgaSkgPT4gaSAhPT0gaW5kZXgpO1xyXG4gICAgdGhpcy52YXJzQ2hhbmdlLmVtaXQodGhpcy5nZXRWYXJzKCkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBwYXJzZVZhbHVlKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHtcclxuICAgIGlmICghdmFsdWUpIHtcclxuICAgICAgcmV0dXJuICcnO1xyXG4gICAgfVxyXG4gICAgaWYgKHZhbHVlID09PSAndHJ1ZScpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9IGVsc2UgaWYgKHZhbHVlID09PSAnZmFsc2UnKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH0gZWxzZSBpZiAoL15cXGQrJC8udGVzdCh2YWx1ZSkpIHtcclxuICAgICAgcmV0dXJuIHBhcnNlSW50KHZhbHVlLCAxMCk7XHJcbiAgICB9IGVsc2UgaWYgKC9eXFxkK1xcLlxcZCskLy50ZXN0KHZhbHVlKSkge1xyXG4gICAgICByZXR1cm4gcGFyc2VGbG9hdCh2YWx1ZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2F2ZVZhcigpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmZvcm0uaW52YWxpZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCB7IG5hbWUsIHZhbHVlIH0gPSB0aGlzLmZvcm0udmFsdWU7XHJcblxyXG4gICAgLy8gcGFyc2UgdmFsdWUgYXNzdW1pbmcgdGhhdCBpZiBpdCBsb29rcyBsaWtlIGEgYm9vbGVhbi9udW1iZXJcclxuICAgIC8vIGl0cyB2YWx1ZSBzaG91bGQgYmUgYSBib29sZWFuL251bWJlciByYXRoZXIgdGhhbiBhIHN0cmluZ1xyXG4gICAgY29uc3QgdiA9IHRoaXMucGFyc2VWYWx1ZSh2YWx1ZSk7XHJcblxyXG4gICAgY29uc3QgZWRpdGVkVmFycyA9IFsuLi50aGlzLmVkaXRlZFZhcnNdO1xyXG5cclxuICAgIC8vIGlmIG5hbWUgYWxyZWFkeSBleGlzdHMsIHVwZGF0ZSB0aGUgdmFsdWU7IGVsc2UgYWRkIGl0XHJcbiAgICBjb25zdCBleGlzdGluZ0luZGV4ID0gdGhpcy5lZGl0ZWRWYXJzLmZpbmRJbmRleCgodnIpID0+IHZyLm5hbWUgPT09IG5hbWUpO1xyXG4gICAgaWYgKGV4aXN0aW5nSW5kZXggIT09IC0xKSB7XHJcbiAgICAgIGVkaXRlZFZhcnNbZXhpc3RpbmdJbmRleF0gPSB7IG5hbWUsIHZhbHVlOiB2IH07XHJcbiAgICAgIHRoaXMuZWRpdGVkVmFycyA9IGVkaXRlZFZhcnM7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGVkaXRlZFZhcnMucHVzaCh7IG5hbWUsIHZhbHVlOiB2IH0pO1xyXG4gICAgICB0aGlzLmVkaXRlZFZhcnMgPSBlZGl0ZWRWYXJzLnNvcnQoKGEsIGIpID0+IGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSkpO1xyXG4gICAgfVxyXG4gICAgdGhpcy52YXJzQ2hhbmdlLmVtaXQodGhpcy5nZXRWYXJzKCkpO1xyXG5cclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICB0aGlzLm5hbWVJbnB1dD8ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xyXG4gICAgICB0aGlzLmZvcm0ucmVzZXQoKTtcclxuICAgICAgdGhpcy5mb3JtLm1hcmtBc1ByaXN0aW5lKCk7XHJcbiAgICAgIHRoaXMuZm9ybS51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICB9LCAwKTtcclxuICB9XHJcbn1cclxuIiwiPGRpdj5cclxuICA8ZGl2PlxyXG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LXJhaXNlZC1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cImFkZFZhcigpXCI+XHJcbiAgICAgIDxtYXQtaWNvbj5hZGQ8L21hdC1pY29uPlxyXG4gICAgICBwcm9wZXJ0eVxyXG4gICAgPC9idXR0b24+XHJcbiAgPC9kaXY+XHJcblxyXG4gIEBpZiAoZWRpdGVkVmFycy5sZW5ndGgpIHtcclxuICA8dGFibGU+XHJcbiAgICA8dGhlYWQ+XHJcbiAgICAgIDx0cj5cclxuICAgICAgICA8dGg+PC90aD5cclxuICAgICAgICA8dGg+bmFtZTwvdGg+XHJcbiAgICAgICAgPHRoPnZhbHVlPC90aD5cclxuICAgICAgPC90cj5cclxuICAgIDwvdGhlYWQ+XHJcbiAgICA8dGJvZHk+XHJcbiAgICAgIEBmb3IgKHYgb2YgZWRpdGVkVmFyczsgdHJhY2sgdi5uYW1lOyBsZXQgaW5kZXg9JGluZGV4KSB7XHJcbiAgICAgIDx0cj5cclxuICAgICAgICA8dGQgY2xhc3M9XCJmaXQtd2lkdGhcIj5cclxuICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgICAgICAgICAoY2xpY2spPVwiZWRpdFZhcihpbmRleClcIlxyXG4gICAgICAgICAgICBtYXRUb29sdGlwPVwiRWRpdCB0aGlzIHByb3BlcnR5XCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibWF0LXByaW1hcnlcIj5lZGl0PC9tYXQtaWNvbj5cclxuICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgIGNvbG9yPVwid2FyblwiXHJcbiAgICAgICAgICAgIChjbGljayk9XCJkZWxldGVWYXIoaW5kZXgpXCJcclxuICAgICAgICAgICAgbWF0VG9vbHRpcD1cIkRlbGV0ZSB0aGlzIHByb3BlcnR5XCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibWF0LXdhcm5cIj5yZW1vdmVfY2lyY2xlPC9tYXQtaWNvbj5cclxuICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDwvdGQ+XHJcbiAgICAgICAgPHRkPnt7IHYubmFtZSB9fTwvdGQ+XHJcbiAgICAgICAgPHRkPnt7IHYudmFsdWUgfX08L3RkPlxyXG4gICAgICA8L3RyPlxyXG4gICAgICB9XHJcbiAgICA8L3Rib2R5PlxyXG4gIDwvdGFibGU+XHJcbiAgfSBAZWxzZSB7XHJcbiAgPHAgY2xhc3M9XCJtdXRlZFwiPihubyB2YXJzKTwvcD5cclxuICB9XHJcblxyXG4gIDxmb3JtIFtmb3JtR3JvdXBdPVwiZm9ybVwiIChzdWJtaXQpPVwic2F2ZVZhcigpXCI+XHJcbiAgICA8ZmllbGRzZXQ+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXJvd1wiPlxyXG4gICAgICAgIDwhLS0gbmFtZSAtLT5cclxuICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICA8bWF0LWxhYmVsPm5hbWU8L21hdC1sYWJlbD5cclxuICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbZm9ybUNvbnRyb2xdPVwibmFtZVwiICN2bmFtZSAvPlxyXG4gICAgICAgICAgPG1hdC1lcnJvclxyXG4gICAgICAgICAgICAqbmdJZj1cIiRhbnkobmFtZSkuZXJyb3JzPy5yZXF1aXJlZCAmJiAobmFtZS5kaXJ0eSB8fCBuYW1lLnRvdWNoZWQpXCJcclxuICAgICAgICAgICAgPm5hbWUgcmVxdWlyZWQ8L21hdC1lcnJvclxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgPG1hdC1lcnJvclxyXG4gICAgICAgICAgICAqbmdJZj1cIiRhbnkobmFtZSkuZXJyb3JzPy5tYXhMZW5ndGggJiYgKG5hbWUuZGlydHkgfHwgbmFtZS50b3VjaGVkKVwiXHJcbiAgICAgICAgICAgID5uYW1lIHRvbyBsb25nPC9tYXQtZXJyb3JcclxuICAgICAgICAgID5cclxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG5cclxuICAgICAgICA8IS0tIHZhbHVlIC0tPlxyXG4gICAgICAgIDxtYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgIDxtYXQtbGFiZWw+dmFsdWU8L21hdC1sYWJlbD5cclxuICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbZm9ybUNvbnRyb2xdPVwidmFsdWVcIiAvPlxyXG4gICAgICAgICAgPG1hdC1lcnJvclxyXG4gICAgICAgICAgICAqbmdJZj1cIlxyXG4gICAgICAgICAgICAgICRhbnkodmFsdWUpLmVycm9ycz8ucmVxdWlyZWQgJiYgKHZhbHVlLmRpcnR5IHx8IHZhbHVlLnRvdWNoZWQpXHJcbiAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICAgID52YWx1ZSByZXF1aXJlZDwvbWF0LWVycm9yXHJcbiAgICAgICAgICA+XHJcbiAgICAgICAgICA8bWF0LWVycm9yXHJcbiAgICAgICAgICAgICpuZ0lmPVwiXHJcbiAgICAgICAgICAgICAgJGFueSh2YWx1ZSkuZXJyb3JzPy5tYXhMZW5ndGggJiYgKHZhbHVlLmRpcnR5IHx8IHZhbHVlLnRvdWNoZWQpXHJcbiAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICAgID52YWx1ZSB0b28gbG9uZzwvbWF0LWVycm9yXHJcbiAgICAgICAgICA+XHJcbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuXHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cInN1Ym1pdFwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiZm9ybS5pbnZhbGlkXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtYXQtcHJpbWFyeVwiPmFkZF9jaXJjbGU8L21hdC1pY29uPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZmllbGRzZXQ+XHJcbiAgPC9mb3JtPlxyXG48L2Rpdj5cclxuIl19
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import { MatRippleModule } from '@angular/material/core';
|
|
3
|
+
import { NgToolsModule } from '@myrmidon/ng-tools';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@angular/material/core";
|
|
6
|
+
import * as i2 from "@myrmidon/ng-tools";
|
|
7
|
+
/**
|
|
8
|
+
* A component that displays a single character from a base text.
|
|
9
|
+
*/
|
|
10
|
+
export class BaseTextCharComponent {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.defaultColor = '#D8D8D8';
|
|
13
|
+
this.defaultBorderColor = '#D8D8D8';
|
|
14
|
+
this.defaultEmSize = 1.5;
|
|
15
|
+
this.charPick = new EventEmitter();
|
|
16
|
+
}
|
|
17
|
+
get char() {
|
|
18
|
+
return this._char;
|
|
19
|
+
}
|
|
20
|
+
set char(value) {
|
|
21
|
+
this._char = value || undefined;
|
|
22
|
+
}
|
|
23
|
+
onCharClick(event) {
|
|
24
|
+
this.charPick.emit({ char: this._char, event });
|
|
25
|
+
}
|
|
26
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: BaseTextCharComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
27
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.4", type: BaseTextCharComponent, isStandalone: true, selector: "gve-base-text-char", inputs: { char: "char" }, outputs: { charPick: "charPick" }, ngImport: i0, template: "@if (char) {\r\n<div matRipple id=\"container\" (click)=\"onCharClick($event)\">\r\n <div\r\n id=\"c-label\"\r\n [style.fontSize]=\"char.emSize + 'em'\"\r\n [style.borderColor]=\"char.borderColor\"\r\n >\r\n {{ char.label }}\r\n </div>\r\n <div\r\n id=\"c-id\"\r\n [style.fontSize]=\"char.emSize / 2 + 'em'\"\r\n [style.color]=\"char.color | colorToContrast\"\r\n [style.borderColor]=\"char.borderColor\"\r\n [style.backgroundColor]=\"char.color\"\r\n >\r\n {{ char.id }}\r\n </div>\r\n</div>\r\n}\r\n", styles: ["div#container{cursor:pointer;flex-direction:column;align-items:center}div#c-label{border:1px solid silver;border-radius:6px;padding:6px;height:1.5em;align-items:center;justify-content:center;text-align:center}div#c-id{margin-top:4px;margin-bottom:16px;border:1px solid silver;border-radius:6px;padding:6px;align-items:center;justify-content:center;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i1.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "ngmodule", type: NgToolsModule }, { kind: "pipe", type: i2.ColorToContrastPipe, name: "colorToContrast" }] }); }
|
|
28
|
+
}
|
|
29
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: BaseTextCharComponent, decorators: [{
|
|
30
|
+
type: Component,
|
|
31
|
+
args: [{ selector: 'gve-base-text-char', standalone: true, imports: [MatRippleModule, NgToolsModule], template: "@if (char) {\r\n<div matRipple id=\"container\" (click)=\"onCharClick($event)\">\r\n <div\r\n id=\"c-label\"\r\n [style.fontSize]=\"char.emSize + 'em'\"\r\n [style.borderColor]=\"char.borderColor\"\r\n >\r\n {{ char.label }}\r\n </div>\r\n <div\r\n id=\"c-id\"\r\n [style.fontSize]=\"char.emSize / 2 + 'em'\"\r\n [style.color]=\"char.color | colorToContrast\"\r\n [style.borderColor]=\"char.borderColor\"\r\n [style.backgroundColor]=\"char.color\"\r\n >\r\n {{ char.id }}\r\n </div>\r\n</div>\r\n}\r\n", styles: ["div#container{cursor:pointer;flex-direction:column;align-items:center}div#c-label{border:1px solid silver;border-radius:6px;padding:6px;height:1.5em;align-items:center;justify-content:center;text-align:center}div#c-id{margin-top:4px;margin-bottom:16px;border:1px solid silver;border-radius:6px;padding:6px;align-items:center;justify-content:center;text-align:center}\n"] }]
|
|
32
|
+
}], propDecorators: { char: [{
|
|
33
|
+
type: Input
|
|
34
|
+
}], charPick: [{
|
|
35
|
+
type: Output
|
|
36
|
+
}] } });
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS10ZXh0LWNoYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbXlybWlkb24vZ3ZlLWNvcmUvc3JjL2xpYi9jb21wb25lbnRzL2Jhc2UtdGV4dC1jaGFyL2Jhc2UtdGV4dC1jaGFyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2d2ZS1jb3JlL3NyYy9saWIvY29tcG9uZW50cy9iYXNlLXRleHQtY2hhci9iYXNlLXRleHQtY2hhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7Ozs7QUFnQm5EOztHQUVHO0FBUUgsTUFBTSxPQUFPLHFCQUFxQjtJQVBsQztRQVVTLGlCQUFZLEdBQUcsU0FBUyxDQUFDO1FBQ3pCLHVCQUFrQixHQUFHLFNBQVMsQ0FBQztRQUMvQixrQkFBYSxHQUFHLEdBQUcsQ0FBQztRQVdwQixhQUFRLEdBQ2IsSUFBSSxZQUFZLEVBQXFCLENBQUM7S0FLekM7SUFmQyxJQUNXLElBQUk7UUFDYixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDcEIsQ0FBQztJQUNELElBQVcsSUFBSSxDQUFDLEtBQXNDO1FBQ3BELElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxJQUFJLFNBQVMsQ0FBQztJQUNsQyxDQUFDO0lBTU0sV0FBVyxDQUFDLEtBQWlCO1FBQ2xDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNuRCxDQUFDOzhHQXJCVSxxQkFBcUI7a0dBQXJCLHFCQUFxQiwySUM3QmxDLDJoQkFvQkEseWFES1ksZUFBZSxrU0FBRSxhQUFhOzsyRkFJN0IscUJBQXFCO2tCQVBqQyxTQUFTOytCQUNFLG9CQUFvQixjQUNsQixJQUFJLFdBQ1AsQ0FBQyxlQUFlLEVBQUUsYUFBYSxDQUFDOzhCQVk5QixJQUFJO3NCQURkLEtBQUs7Z0JBU0MsUUFBUTtzQkFEZCxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTWF0UmlwcGxlTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY29yZSc7XHJcblxyXG5pbXBvcnQgeyBOZ1Rvb2xzTW9kdWxlIH0gZnJvbSAnQG15cm1pZG9uL25nLXRvb2xzJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQmFzZVRleHRDaGFyIHtcclxuICBpZDogbnVtYmVyO1xyXG4gIHZhbHVlOiBzdHJpbmc7XHJcbiAgbGFiZWw6IHN0cmluZztcclxuICBjb2xvcjogc3RyaW5nO1xyXG4gIGJvcmRlckNvbG9yOiBzdHJpbmc7XHJcbiAgZW1TaXplOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQmFzZVRleHRDaGFyRXZlbnQge1xyXG4gIGNoYXI6IEJhc2VUZXh0Q2hhcjtcclxuICBldmVudDogTW91c2VFdmVudDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEEgY29tcG9uZW50IHRoYXQgZGlzcGxheXMgYSBzaW5nbGUgY2hhcmFjdGVyIGZyb20gYSBiYXNlIHRleHQuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2d2ZS1iYXNlLXRleHQtY2hhcicsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbTWF0UmlwcGxlTW9kdWxlLCBOZ1Rvb2xzTW9kdWxlXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vYmFzZS10ZXh0LWNoYXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi9iYXNlLXRleHQtY2hhci5jb21wb25lbnQuY3NzJyxcclxufSlcclxuZXhwb3J0IGNsYXNzIEJhc2VUZXh0Q2hhckNvbXBvbmVudCB7XHJcbiAgcHJpdmF0ZSBfY2hhcjogQmFzZVRleHRDaGFyIHwgdW5kZWZpbmVkO1xyXG5cclxuICBwdWJsaWMgZGVmYXVsdENvbG9yID0gJyNEOEQ4RDgnO1xyXG4gIHB1YmxpYyBkZWZhdWx0Qm9yZGVyQ29sb3IgPSAnI0Q4RDhEOCc7XHJcbiAgcHVibGljIGRlZmF1bHRFbVNpemUgPSAxLjU7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgcHVibGljIGdldCBjaGFyKCk6IEJhc2VUZXh0Q2hhciB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gdGhpcy5fY2hhcjtcclxuICB9XHJcbiAgcHVibGljIHNldCBjaGFyKHZhbHVlOiBCYXNlVGV4dENoYXIgfCB1bmRlZmluZWQgfCBudWxsKSB7XHJcbiAgICB0aGlzLl9jaGFyID0gdmFsdWUgfHwgdW5kZWZpbmVkO1xyXG4gIH1cclxuXHJcbiAgQE91dHB1dCgpXHJcbiAgcHVibGljIGNoYXJQaWNrOiBFdmVudEVtaXR0ZXI8QmFzZVRleHRDaGFyRXZlbnQ+ID1cclxuICAgIG5ldyBFdmVudEVtaXR0ZXI8QmFzZVRleHRDaGFyRXZlbnQ+KCk7XHJcblxyXG4gIHB1YmxpYyBvbkNoYXJDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xyXG4gICAgdGhpcy5jaGFyUGljay5lbWl0KHsgY2hhcjogdGhpcy5fY2hhciEsIGV2ZW50IH0pO1xyXG4gIH1cclxufVxyXG4iLCJAaWYgKGNoYXIpIHtcclxuPGRpdiBtYXRSaXBwbGUgaWQ9XCJjb250YWluZXJcIiAoY2xpY2spPVwib25DaGFyQ2xpY2soJGV2ZW50KVwiPlxyXG4gIDxkaXZcclxuICAgIGlkPVwiYy1sYWJlbFwiXHJcbiAgICBbc3R5bGUuZm9udFNpemVdPVwiY2hhci5lbVNpemUgKyAnZW0nXCJcclxuICAgIFtzdHlsZS5ib3JkZXJDb2xvcl09XCJjaGFyLmJvcmRlckNvbG9yXCJcclxuICA+XHJcbiAgICB7eyBjaGFyLmxhYmVsIH19XHJcbiAgPC9kaXY+XHJcbiAgPGRpdlxyXG4gICAgaWQ9XCJjLWlkXCJcclxuICAgIFtzdHlsZS5mb250U2l6ZV09XCJjaGFyLmVtU2l6ZSAvIDIgKyAnZW0nXCJcclxuICAgIFtzdHlsZS5jb2xvcl09XCJjaGFyLmNvbG9yIHwgY29sb3JUb0NvbnRyYXN0XCJcclxuICAgIFtzdHlsZS5ib3JkZXJDb2xvcl09XCJjaGFyLmJvcmRlckNvbG9yXCJcclxuICAgIFtzdHlsZS5iYWNrZ3JvdW5kQ29sb3JdPVwiY2hhci5jb2xvclwiXHJcbiAgPlxyXG4gICAge3sgY2hhci5pZCB9fVxyXG4gIDwvZGl2PlxyXG48L2Rpdj5cclxufVxyXG4iXX0=
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
3
|
+
import { ReactiveFormsModule, Validators, } from '@angular/forms';
|
|
4
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
5
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
6
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
7
|
+
import { MatInputModule } from '@angular/material/input';
|
|
8
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
9
|
+
import { SnapshotViewService, } from '@myrmidon/gve-snapshot-view';
|
|
10
|
+
import { BaseTextViewComponent, } from '../base-text-view/base-text-view.component';
|
|
11
|
+
import { FeatureSetEditorComponent } from '../feature-set-editor/feature-set-editor.component';
|
|
12
|
+
import * as i0 from "@angular/core";
|
|
13
|
+
import * as i1 from "@angular/forms";
|
|
14
|
+
import * as i2 from "@myrmidon/ng-mat-tools";
|
|
15
|
+
import * as i3 from "@angular/common";
|
|
16
|
+
import * as i4 from "@angular/material/button";
|
|
17
|
+
import * as i5 from "@angular/material/form-field";
|
|
18
|
+
import * as i6 from "@angular/material/input";
|
|
19
|
+
import * as i7 from "@angular/material/tooltip";
|
|
20
|
+
/**
|
|
21
|
+
* Editor for snapshot's base text. This can receive a string or an array
|
|
22
|
+
* of `CharNode` objects, and lets the user edit the text, character by
|
|
23
|
+
* character, optionally also setting its features.
|
|
24
|
+
*/
|
|
25
|
+
export class BaseTextEditorComponent {
|
|
26
|
+
/**
|
|
27
|
+
* The text to edit. In input this can be a string, an array of `CharNode`
|
|
28
|
+
* objects. In output this will be an array of `CharNode` objects.
|
|
29
|
+
*/
|
|
30
|
+
get text() {
|
|
31
|
+
return this._text;
|
|
32
|
+
}
|
|
33
|
+
set text(value) {
|
|
34
|
+
this.resetSelectedChar();
|
|
35
|
+
if (this._text === value) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (!value) {
|
|
39
|
+
this._text = [];
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
this._text = Array.isArray(value)
|
|
43
|
+
? value
|
|
44
|
+
: SnapshotViewService.stringToBaseChars(value);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
constructor(formBuilder, _dialogService) {
|
|
48
|
+
this._dialogService = _dialogService;
|
|
49
|
+
this._text = [];
|
|
50
|
+
/**
|
|
51
|
+
* Emits the edited text as an array of `CharNode`'s whenever it changes.
|
|
52
|
+
*/
|
|
53
|
+
this.textChange = new EventEmitter();
|
|
54
|
+
this.userText = formBuilder.control('', {
|
|
55
|
+
nonNullable: true,
|
|
56
|
+
validators: [Validators.required, Validators.maxLength(10000)],
|
|
57
|
+
});
|
|
58
|
+
this.form = formBuilder.group({
|
|
59
|
+
userText: this.userText,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
resetSelectedChar() {
|
|
63
|
+
this.selectedChar = undefined;
|
|
64
|
+
this.selectedCharLabel = undefined;
|
|
65
|
+
}
|
|
66
|
+
onSelectedChar(event) {
|
|
67
|
+
this.selectedChar = this._text.find((c) => c.id === event.char.id);
|
|
68
|
+
this.selectedCharLabel = event.char.label;
|
|
69
|
+
}
|
|
70
|
+
onFeaturesChange(features) {
|
|
71
|
+
this.selectedChar.features = features;
|
|
72
|
+
this.textChange.emit(this._text);
|
|
73
|
+
}
|
|
74
|
+
onRangePick(range) {
|
|
75
|
+
this.textRange = range;
|
|
76
|
+
}
|
|
77
|
+
patchTextFromUser() {
|
|
78
|
+
// TODO
|
|
79
|
+
}
|
|
80
|
+
setTextFromUser() {
|
|
81
|
+
this._dialogService
|
|
82
|
+
.confirm('Confirm', 'Reset text?')
|
|
83
|
+
.subscribe((yes) => {
|
|
84
|
+
if (yes) {
|
|
85
|
+
this.text = this.userText.value;
|
|
86
|
+
this.textChange.emit(this._text);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: BaseTextEditorComponent, deps: [{ token: i1.FormBuilder }, { token: i2.DialogService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
91
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.4", type: BaseTextEditorComponent, isStandalone: true, selector: "gve-base-text-editor", inputs: { text: "text" }, outputs: { textChange: "textChange" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"setTextFromUser()\">\r\n <!-- text -->\r\n <div>\r\n <mat-form-field class=\"full-width\">\r\n <mat-label>text</mat-label>\r\n <textarea matInput [formControl]=\"userText\" rows=\"5\"></textarea>\r\n <mat-error\r\n *ngIf=\"\r\n $any(userText).errors?.required &&\r\n (userText.dirty || userText.touched)\r\n \"\r\n >text required</mat-error\r\n >\r\n <mat-error\r\n *ngIf=\"\r\n $any(userText).errors?.maxLength &&\r\n (userText.dirty || userText.touched)\r\n \"\r\n >text too long</mat-error\r\n >\r\n </mat-form-field>\r\n </div>\r\n <!-- buttons -->\r\n <div class=\"form-row\">\r\n <!-- set -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-warn\"\r\n matTooltip=\"Reset characters to newly entered text\"\r\n [disabled]=\"!userText.value\"\r\n (click)=\"setTextFromUser()\"\r\n >\r\n set\r\n </button>\r\n <!-- patch -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-primary\"\r\n matTooltip=\"Patch characters with newly entered text\"\r\n [disabled]=\"!userText.value\"\r\n (click)=\"patchTextFromUser()\"\r\n >\r\n patch\r\n </button>\r\n </div>\r\n\r\n <!-- base text -->\r\n <div id=\"text-view\">\r\n <gve-base-text-view\r\n [text]=\"text\"\r\n (charPick)=\"onSelectedChar($event)\"\r\n (rangePick)=\"textRange = $event\"\r\n />\r\n\r\n <!-- text range -->\r\n @if (textRange) {\r\n <div id=\"text-range\">{{ textRange.at }} \u00D7 {{ textRange.run }}</div>\r\n }\r\n </div>\r\n\r\n <!-- char features -->\r\n @if (selectedChar) {\r\n <fieldset>\r\n <legend>features</legend>\r\n <gve-feature-set-editor\r\n [features]=\"selectedChar.features || []\"\r\n (featuresChange)=\"onFeaturesChange($event)\"\r\n />\r\n </fieldset>\r\n }\r\n</form>\r\n", styles: [".full-width{width:100%}#text-view{margin:8px 0}fieldset{border:1px solid #ccc;padding:10px;margin:10px 0;border-radius:5px}legend{color:silver}.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: i3.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: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { 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: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.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: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: BaseTextViewComponent, selector: "gve-base-text-view", inputs: ["defaultColor", "defaultBorderColor", "selectionColor", "hasLineNumber", "text"], outputs: ["charPick", "rangePick"] }, { kind: "component", type: FeatureSetEditorComponent, selector: "gve-feature-set-editor", inputs: ["isVar", "featNames", "featValues", "noFilter", "features"], outputs: ["featuresChange"] }] }); }
|
|
92
|
+
}
|
|
93
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: BaseTextEditorComponent, decorators: [{
|
|
94
|
+
type: Component,
|
|
95
|
+
args: [{ selector: 'gve-base-text-editor', standalone: true, imports: [
|
|
96
|
+
CommonModule,
|
|
97
|
+
ReactiveFormsModule,
|
|
98
|
+
MatButtonModule,
|
|
99
|
+
MatFormFieldModule,
|
|
100
|
+
MatIconModule,
|
|
101
|
+
MatInputModule,
|
|
102
|
+
MatTooltipModule,
|
|
103
|
+
BaseTextViewComponent,
|
|
104
|
+
FeatureSetEditorComponent,
|
|
105
|
+
], template: "<form [formGroup]=\"form\" (submit)=\"setTextFromUser()\">\r\n <!-- text -->\r\n <div>\r\n <mat-form-field class=\"full-width\">\r\n <mat-label>text</mat-label>\r\n <textarea matInput [formControl]=\"userText\" rows=\"5\"></textarea>\r\n <mat-error\r\n *ngIf=\"\r\n $any(userText).errors?.required &&\r\n (userText.dirty || userText.touched)\r\n \"\r\n >text required</mat-error\r\n >\r\n <mat-error\r\n *ngIf=\"\r\n $any(userText).errors?.maxLength &&\r\n (userText.dirty || userText.touched)\r\n \"\r\n >text too long</mat-error\r\n >\r\n </mat-form-field>\r\n </div>\r\n <!-- buttons -->\r\n <div class=\"form-row\">\r\n <!-- set -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-warn\"\r\n matTooltip=\"Reset characters to newly entered text\"\r\n [disabled]=\"!userText.value\"\r\n (click)=\"setTextFromUser()\"\r\n >\r\n set\r\n </button>\r\n <!-- patch -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-primary\"\r\n matTooltip=\"Patch characters with newly entered text\"\r\n [disabled]=\"!userText.value\"\r\n (click)=\"patchTextFromUser()\"\r\n >\r\n patch\r\n </button>\r\n </div>\r\n\r\n <!-- base text -->\r\n <div id=\"text-view\">\r\n <gve-base-text-view\r\n [text]=\"text\"\r\n (charPick)=\"onSelectedChar($event)\"\r\n (rangePick)=\"textRange = $event\"\r\n />\r\n\r\n <!-- text range -->\r\n @if (textRange) {\r\n <div id=\"text-range\">{{ textRange.at }} \u00D7 {{ textRange.run }}</div>\r\n }\r\n </div>\r\n\r\n <!-- char features -->\r\n @if (selectedChar) {\r\n <fieldset>\r\n <legend>features</legend>\r\n <gve-feature-set-editor\r\n [features]=\"selectedChar.features || []\"\r\n (featuresChange)=\"onFeaturesChange($event)\"\r\n />\r\n </fieldset>\r\n }\r\n</form>\r\n", styles: [".full-width{width:100%}#text-view{margin:8px 0}fieldset{border:1px solid #ccc;padding:10px;margin:10px 0;border-radius:5px}legend{color:silver}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"] }]
|
|
106
|
+
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i2.DialogService }], propDecorators: { text: [{
|
|
107
|
+
type: Input
|
|
108
|
+
}], textChange: [{
|
|
109
|
+
type: Output
|
|
110
|
+
}] } });
|
|
111
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS10ZXh0LWVkaXRvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9teXJtaWRvbi9ndmUtY29yZS9zcmMvbGliL2NvbXBvbmVudHMvYmFzZS10ZXh0LWVkaXRvci9iYXNlLXRleHQtZWRpdG9yLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2d2ZS1jb3JlL3NyYy9saWIvY29tcG9uZW50cy9iYXNlLXRleHQtZWRpdG9yL2Jhc2UtdGV4dC1lZGl0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkUsT0FBTyxFQUlMLG1CQUFtQixFQUNuQixVQUFVLEdBQ1gsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUU3RCxPQUFPLEVBR0wsbUJBQW1CLEdBQ3BCLE1BQU0sNkJBQTZCLENBQUM7QUFJckMsT0FBTyxFQUNMLHFCQUFxQixHQUV0QixNQUFNLDRDQUE0QyxDQUFDO0FBQ3BELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLG9EQUFvRCxDQUFDOzs7Ozs7Ozs7QUFFL0Y7Ozs7R0FJRztBQWtCSCxNQUFNLE9BQU8s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LDhCQUNiLGNBQWMsMFdBQ2QsZ0JBQWdCLDZUQUNoQixxQkFBcUIsOExBQ3JCLHlCQUF5Qjs7MkZBS2hCLHVCQUF1QjtrQkFqQm5DLFNBQVM7K0JBQ0Usc0JBQXNCLGNBQ3BCLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLG1CQUFtQjt3QkFDbkIsZUFBZTt3QkFDZixrQkFBa0I7d0JBQ2xCLGFBQWE7d0JBQ2IsY0FBYzt3QkFDZCxnQkFBZ0I7d0JBQ2hCLHFCQUFxQjt3QkFDckIseUJBQXlCO3FCQUMxQjs0R0FZVSxJQUFJO3NCQURkLEtBQUs7Z0JBc0JVLFVBQVU7c0JBRHpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gIEZvcm1CdWlsZGVyLFxyXG4gIEZvcm1Db250cm9sLFxyXG4gIEZvcm1Hcm91cCxcclxuICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxyXG4gIFZhbGlkYXRvcnMsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xyXG5pbXBvcnQgeyBNYXRGb3JtRmllbGRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcclxuaW1wb3J0IHsgTWF0SWNvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2ljb24nO1xyXG5pbXBvcnQgeyBNYXRJbnB1dE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcclxuaW1wb3J0IHsgTWF0VG9vbHRpcE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3Rvb2x0aXAnO1xyXG5cclxuaW1wb3J0IHtcclxuICBDaGFyTm9kZSxcclxuICBGZWF0dXJlLFxyXG4gIFNuYXBzaG90Vmlld1NlcnZpY2UsXHJcbn0gZnJvbSAnQG15cm1pZG9uL2d2ZS1zbmFwc2hvdC12aWV3JztcclxuaW1wb3J0IHsgRGlhbG9nU2VydmljZSB9IGZyb20gJ0BteXJtaWRvbi9uZy1tYXQtdG9vbHMnO1xyXG5cclxuaW1wb3J0IHsgQmFzZVRleHRDaGFyRXZlbnQgfSBmcm9tICcuLi9iYXNlLXRleHQtY2hhci9iYXNlLXRleHQtY2hhci5jb21wb25lbnQnO1xyXG5pbXBvcnQge1xyXG4gIEJhc2VUZXh0Vmlld0NvbXBvbmVudCxcclxuICBWYXJCYXNlVGV4dFJhbmdlLFxyXG59IGZyb20gJy4uL2Jhc2UtdGV4dC12aWV3L2Jhc2UtdGV4dC12aWV3LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEZlYXR1cmVTZXRFZGl0b3JDb21wb25lbnQgfSBmcm9tICcuLi9mZWF0dXJlLXNldC1lZGl0b3IvZmVhdHVyZS1zZXQtZWRpdG9yLmNvbXBvbmVudCc7XHJcblxyXG4vKipcclxuICogRWRpdG9yIGZvciBzbmFwc2hvdCdzIGJhc2UgdGV4dC4gVGhpcyBjYW4gcmVjZWl2ZSBhIHN0cmluZyBvciBhbiBhcnJheVxyXG4gKiBvZiBgQ2hhck5vZGVgIG9iamVjdHMsIGFuZCBsZXRzIHRoZSB1c2VyIGVkaXQgdGhlIHRleHQsIGNoYXJhY3RlciBieVxyXG4gKiBjaGFyYWN0ZXIsIG9wdGlvbmFsbHkgYWxzbyBzZXR0aW5nIGl0cyBmZWF0dXJlcy5cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZ3ZlLWJhc2UtdGV4dC1lZGl0b3InLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW1xyXG4gICAgQ29tbW9uTW9kdWxlLFxyXG4gICAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcclxuICAgIE1hdEJ1dHRvbk1vZHVsZSxcclxuICAgIE1hdEZvcm1GaWVsZE1vZHVsZSxcclxuICAgIE1hdEljb25Nb2R1bGUsXHJcbiAgICBNYXRJbnB1dE1vZHVsZSxcclxuICAgIE1hdFRvb2x0aXBNb2R1bGUsXHJcbiAgICBCYXNlVGV4dFZpZXdDb21wb25lbnQsXHJcbiAgICBGZWF0dXJlU2V0RWRpdG9yQ29tcG9uZW50LFxyXG4gIF0sXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2Jhc2UtdGV4dC1lZGl0b3IuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi9iYXNlLXRleHQtZWRpdG9yLmNvbXBvbmVudC5jc3MnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQmFzZVRleHRFZGl0b3JDb21wb25lbnQge1xyXG4gIHByaXZhdGUgX3RleHQ6IENoYXJOb2RlW10gPSBbXTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIHRleHQgdG8gZWRpdC4gSW4gaW5wdXQgdGhpcyBjYW4gYmUgYSBzdHJpbmcsIGFuIGFycmF5IG9mIGBDaGFyTm9kZWBcclxuICAgKiBvYmplY3RzLiBJbiBvdXRwdXQgdGhpcyB3aWxsIGJlIGFuIGFycmF5IG9mIGBDaGFyTm9kZWAgb2JqZWN0cy5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHB1YmxpYyBnZXQgdGV4dCgpOiBDaGFyTm9kZVtdIHtcclxuICAgIHJldHVybiB0aGlzLl90ZXh0O1xyXG4gIH1cclxuICBwdWJsaWMgc2V0IHRleHQodmFsdWU6IHN0cmluZyB8IENoYXJOb2RlW10gfCB1bmRlZmluZWQgfCBudWxsKSB7XHJcbiAgICB0aGlzLnJlc2V0U2VsZWN0ZWRDaGFyKCk7XHJcbiAgICBpZiAodGhpcy5fdGV4dCA9PT0gdmFsdWUpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgaWYgKCF2YWx1ZSkge1xyXG4gICAgICB0aGlzLl90ZXh0ID0gW107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLl90ZXh0ID0gQXJyYXkuaXNBcnJheSh2YWx1ZSlcclxuICAgICAgICA/IHZhbHVlXHJcbiAgICAgICAgOiBTbmFwc2hvdFZpZXdTZXJ2aWNlLnN0cmluZ1RvQmFzZUNoYXJzKHZhbHVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEVtaXRzIHRoZSBlZGl0ZWQgdGV4dCBhcyBhbiBhcnJheSBvZiBgQ2hhck5vZGVgJ3Mgd2hlbmV2ZXIgaXQgY2hhbmdlcy5cclxuICAgKi9cclxuICBAT3V0cHV0KClcclxuICBwdWJsaWMgcmVhZG9ubHkgdGV4dENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhck5vZGVbXT4oKTtcclxuXHJcbiAgcHVibGljIHVzZXJUZXh0OiBGb3JtQ29udHJvbDxzdHJpbmc+O1xyXG4gIHB1YmxpYyBmb3JtOiBGb3JtR3JvdXA7XHJcblxyXG4gIHB1YmxpYyBzZWxlY3RlZENoYXI/OiBDaGFyTm9kZTtcclxuICBwdWJsaWMgc2VsZWN0ZWRDaGFyTGFiZWw/OiBzdHJpbmc7XHJcbiAgcHVibGljIHRleHRSYW5nZT86IFZhckJhc2VUZXh0UmFuZ2U7XHJcblxyXG4gIGNvbnN0cnVjdG9yKGZvcm1CdWlsZGVyOiBGb3JtQnVpbGRlciwgcHJpdmF0ZSBfZGlhbG9nU2VydmljZTogRGlhbG9nU2VydmljZSkge1xyXG4gICAgdGhpcy51c2VyVGV4dCA9IGZvcm1CdWlsZGVyLmNvbnRyb2woJycsIHtcclxuICAgICAgbm9uTnVsbGFibGU6IHRydWUsXHJcbiAgICAgIHZhbGlkYXRvcnM6IFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1heExlbmd0aCgxMDAwMCldLFxyXG4gICAgfSk7XHJcbiAgICB0aGlzLmZvcm0gPSBmb3JtQnVpbGRlci5ncm91cCh7XHJcbiAgICAgIHVzZXJUZXh0OiB0aGlzLnVzZXJUZXh0LFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlc2V0U2VsZWN0ZWRDaGFyKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zZWxlY3RlZENoYXIgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLnNlbGVjdGVkQ2hhckxhYmVsID0gdW5kZWZpbmVkO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uU2VsZWN0ZWRDaGFyKGV2ZW50OiBCYXNlVGV4dENoYXJFdmVudCk6IHZvaWQge1xyXG4gICAgdGhpcy5zZWxlY3RlZENoYXIgPSB0aGlzLl90ZXh0LmZpbmQoKGMpID0+IGMuaWQgPT09IGV2ZW50LmNoYXIuaWQpO1xyXG4gICAgdGhpcy5zZWxlY3RlZENoYXJMYWJlbCA9IGV2ZW50LmNoYXIubGFiZWw7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25GZWF0dXJlc0NoYW5nZShmZWF0dXJlczogRmVhdHVyZVtdKTogdm9pZCB7XHJcbiAgICB0aGlzLnNlbGVjdGVkQ2hhciEuZmVhdHVyZXMgPSBmZWF0dXJlcztcclxuICAgIHRoaXMudGV4dENoYW5nZS5lbWl0KHRoaXMuX3RleHQpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uUmFuZ2VQaWNrKHJhbmdlOiBWYXJCYXNlVGV4dFJhbmdlKSB7XHJcbiAgICB0aGlzLnRleHRSYW5nZSA9IHJhbmdlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHBhdGNoVGV4dEZyb21Vc2VyKCk6IHZvaWQge1xyXG4gICAgLy8gVE9ET1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldFRleHRGcm9tVXNlcigpOiB2b2lkIHtcclxuICAgIHRoaXMuX2RpYWxvZ1NlcnZpY2VcclxuICAgICAgLmNvbmZpcm0oJ0NvbmZpcm0nLCAnUmVzZXQgdGV4dD8nKVxyXG4gICAgICAuc3Vic2NyaWJlKCh5ZXM6IGJvb2xlYW4pID0+IHtcclxuICAgICAgICBpZiAoeWVzKSB7XHJcbiAgICAgICAgICB0aGlzLnRleHQgPSB0aGlzLnVzZXJUZXh0LnZhbHVlO1xyXG4gICAgICAgICAgdGhpcy50ZXh0Q2hhbmdlLmVtaXQodGhpcy5fdGV4dCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcbn1cclxuIiwiPGZvcm0gW2Zvcm1Hcm91cF09XCJmb3JtXCIgKHN1Ym1pdCk9XCJzZXRUZXh0RnJvbVVzZXIoKVwiPlxyXG4gIDwhLS0gdGV4dCAtLT5cclxuICA8ZGl2PlxyXG4gICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxyXG4gICAgICA8bWF0LWxhYmVsPnRleHQ8L21hdC1sYWJlbD5cclxuICAgICAgPHRleHRhcmVhIG1hdElucHV0IFtmb3JtQ29udHJvbF09XCJ1c2VyVGV4dFwiIHJvd3M9XCI1XCI+PC90ZXh0YXJlYT5cclxuICAgICAgPG1hdC1lcnJvclxyXG4gICAgICAgICpuZ0lmPVwiXHJcbiAgICAgICAgICAkYW55KHVzZXJUZXh0KS5lcnJvcnM/LnJlcXVpcmVkICYmXHJcbiAgICAgICAgICAodXNlclRleHQuZGlydHkgfHwgdXNlclRleHQudG91Y2hlZClcclxuICAgICAgICBcIlxyXG4gICAgICAgID50ZXh0IHJlcXVpcmVkPC9tYXQtZXJyb3JcclxuICAgICAgPlxyXG4gICAgICA8bWF0LWVycm9yXHJcbiAgICAgICAgKm5nSWY9XCJcclxuICAgICAgICAgICRhbnkodXNlclRleHQpLmVycm9ycz8ubWF4TGVuZ3RoICYmXHJcbiAgICAgICAgICAodXNlclRleHQuZGlydHkgfHwgdXNlclRleHQudG91Y2hlZClcclxuICAgICAgICBcIlxyXG4gICAgICAgID50ZXh0IHRvbyBsb25nPC9tYXQtZXJyb3JcclxuICAgICAgPlxyXG4gICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICA8L2Rpdj5cclxuICA8IS0tIGJ1dHRvbnMgLS0+XHJcbiAgPGRpdiBjbGFzcz1cImZvcm0tcm93XCI+XHJcbiAgICA8IS0tIHNldCAtLT5cclxuICAgIDxidXR0b25cclxuICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgIG1hdC1mbGF0LWJ1dHRvblxyXG4gICAgICBjbGFzcz1cIm1hdC13YXJuXCJcclxuICAgICAgbWF0VG9vbHRpcD1cIlJlc2V0IGNoYXJhY3RlcnMgdG8gbmV3bHkgZW50ZXJlZCB0ZXh0XCJcclxuICAgICAgW2Rpc2FibGVkXT1cIiF1c2VyVGV4dC52YWx1ZVwiXHJcbiAgICAgIChjbGljayk9XCJzZXRUZXh0RnJvbVVzZXIoKVwiXHJcbiAgICA+XHJcbiAgICAgIHNldFxyXG4gICAgPC9idXR0b24+XHJcbiAgICA8IS0tIHBhdGNoIC0tPlxyXG4gICAgPGJ1dHRvblxyXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgbWF0LWZsYXQtYnV0dG9uXHJcbiAgICAgIGNsYXNzPVwibWF0LXByaW1hcnlcIlxyXG4gICAgICBtYXRUb29sdGlwPVwiUGF0Y2ggY2hhcmFjdGVycyB3aXRoIG5ld2x5IGVudGVyZWQgdGV4dFwiXHJcbiAgICAgIFtkaXNhYmxlZF09XCIhdXNlclRleHQudmFsdWVcIlxyXG4gICAgICAoY2xpY2spPVwicGF0Y2hUZXh0RnJvbVVzZXIoKVwiXHJcbiAgICA+XHJcbiAgICAgIHBhdGNoXHJcbiAgICA8L2J1dHRvbj5cclxuICA8L2Rpdj5cclxuXHJcbiAgPCEtLSBiYXNlIHRleHQgLS0+XHJcbiAgPGRpdiBpZD1cInRleHQtdmlld1wiPlxyXG4gICAgPGd2ZS1iYXNlLXRleHQtdmlld1xyXG4gICAgICBbdGV4dF09XCJ0ZXh0XCJcclxuICAgICAgKGNoYXJQaWNrKT1cIm9uU2VsZWN0ZWRDaGFyKCRldmVudClcIlxyXG4gICAgICAocmFuZ2VQaWNrKT1cInRleHRSYW5nZSA9ICRldmVudFwiXHJcbiAgICAvPlxyXG5cclxuICAgIDwhLS0gdGV4dCByYW5nZSAtLT5cclxuICAgIEBpZiAodGV4dFJhbmdlKSB7XHJcbiAgICA8ZGl2IGlkPVwidGV4dC1yYW5nZVwiPnt7IHRleHRSYW5nZS5hdCB9fSDDlyB7eyB0ZXh0UmFuZ2UucnVuIH19PC9kaXY+XHJcbiAgICB9XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gY2hhciBmZWF0dXJlcyAtLT5cclxuICBAaWYgKHNlbGVjdGVkQ2hhcikge1xyXG4gIDxmaWVsZHNldD5cclxuICAgIDxsZWdlbmQ+ZmVhdHVyZXM8L2xlZ2VuZD5cclxuICAgIDxndmUtZmVhdHVyZS1zZXQtZWRpdG9yXHJcbiAgICAgIFtmZWF0dXJlc109XCJzZWxlY3RlZENoYXIuZmVhdHVyZXMgfHwgW11cIlxyXG4gICAgICAoZmVhdHVyZXNDaGFuZ2UpPVwib25GZWF0dXJlc0NoYW5nZSgkZXZlbnQpXCJcclxuICAgIC8+XHJcbiAgPC9maWVsZHNldD5cclxuICB9XHJcbjwvZm9ybT5cclxuIl19
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
3
|
+
import { BaseTextCharComponent, } from '../base-text-char/base-text-char.component';
|
|
4
|
+
import { SnapshotViewService } from '@myrmidon/gve-snapshot-view';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/**
|
|
7
|
+
* A component to display a selectable base text.
|
|
8
|
+
*/
|
|
9
|
+
export class BaseTextViewComponent {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.defaultColor = '#DBDBDB';
|
|
12
|
+
this.defaultBorderColor = '#DBDBDB';
|
|
13
|
+
this.selectionColor = '#3E92CC';
|
|
14
|
+
this.hasLineNumber = false;
|
|
15
|
+
this.charPick = new EventEmitter();
|
|
16
|
+
this.rangePick = new EventEmitter();
|
|
17
|
+
this.lines = [];
|
|
18
|
+
}
|
|
19
|
+
get text() {
|
|
20
|
+
return this._text;
|
|
21
|
+
}
|
|
22
|
+
set text(value) {
|
|
23
|
+
this._text = value || undefined;
|
|
24
|
+
this.buildLines();
|
|
25
|
+
}
|
|
26
|
+
buildLines() {
|
|
27
|
+
if (!this._text) {
|
|
28
|
+
this.lines = [];
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const newLines = [];
|
|
32
|
+
newLines.push([]);
|
|
33
|
+
if (Array.isArray(this._text)) {
|
|
34
|
+
const nodes = this._text;
|
|
35
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
36
|
+
const char = {
|
|
37
|
+
id: nodes[i].id,
|
|
38
|
+
value: nodes[i].data,
|
|
39
|
+
label: nodes[i].label,
|
|
40
|
+
color: this.defaultColor,
|
|
41
|
+
borderColor: this.defaultBorderColor,
|
|
42
|
+
emSize: 1.5,
|
|
43
|
+
};
|
|
44
|
+
newLines[newLines.length - 1].push(char);
|
|
45
|
+
if (char.value === '\n') {
|
|
46
|
+
newLines.push([]);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
for (let i = 0; i < this._text.length; i++) {
|
|
52
|
+
const char = {
|
|
53
|
+
id: i + 1,
|
|
54
|
+
value: this._text[i],
|
|
55
|
+
label: SnapshotViewService.translateSpecialChar(this._text[i]),
|
|
56
|
+
color: this.defaultColor,
|
|
57
|
+
borderColor: this.defaultBorderColor,
|
|
58
|
+
emSize: 1.5,
|
|
59
|
+
};
|
|
60
|
+
newLines[newLines.length - 1].push(char);
|
|
61
|
+
if (char.value === '\n') {
|
|
62
|
+
newLines.push([]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
this.lines = newLines;
|
|
67
|
+
}
|
|
68
|
+
resetColors() {
|
|
69
|
+
for (const line of this.lines) {
|
|
70
|
+
for (const c of line) {
|
|
71
|
+
c.color = this.defaultColor;
|
|
72
|
+
c.borderColor = this.defaultBorderColor;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
onCharPick(event) {
|
|
77
|
+
this.resetColors();
|
|
78
|
+
if (this._lastSelectedChar &&
|
|
79
|
+
this._lastSelectedChar !== event.char &&
|
|
80
|
+
event.event.ctrlKey) {
|
|
81
|
+
const minId = Math.min(this._lastSelectedChar.id, event.char.id);
|
|
82
|
+
const maxId = Math.max(this._lastSelectedChar.id, event.char.id);
|
|
83
|
+
for (const line of this.lines) {
|
|
84
|
+
for (const c of line) {
|
|
85
|
+
if (c.id >= minId && c.id <= maxId) {
|
|
86
|
+
c.color = this.selectionColor;
|
|
87
|
+
c.borderColor = this.selectionColor;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
this.charPick.emit(event);
|
|
92
|
+
this.rangePick.emit({ at: minId, run: maxId - minId + 1 });
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// select current char
|
|
97
|
+
event.char.color = this.selectionColor;
|
|
98
|
+
event.char.borderColor = this.selectionColor;
|
|
99
|
+
this.charPick.emit(event);
|
|
100
|
+
this.rangePick.emit({ at: event.char.id, run: 1 });
|
|
101
|
+
}
|
|
102
|
+
this._lastSelectedChar = event.char;
|
|
103
|
+
}
|
|
104
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: BaseTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
105
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.4", type: BaseTextViewComponent, isStandalone: true, selector: "gve-base-text-view", inputs: { defaultColor: "defaultColor", defaultBorderColor: "defaultBorderColor", selectionColor: "selectionColor", hasLineNumber: "hasLineNumber", text: "text" }, outputs: { charPick: "charPick", rangePick: "rangePick" }, ngImport: i0, template: "<div id=\"text\">\r\n @for (line of lines; track line) {\r\n <div class=\"line\">\r\n @if (hasLineNumber) {\r\n <div class=\"nr\">\r\n {{ lines.indexOf(line) + 1 }}\r\n </div>\r\n } @for (c of line; track c.id) {\r\n <gve-base-text-char [char]=\"c\" (charPick)=\"onCharPick($event)\" />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".line{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.line *{flex:0 0 auto}.nr{font-size:.8em;font-weight:700;color:silver;margin:0 4px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: BaseTextCharComponent, selector: "gve-base-text-char", inputs: ["char"], outputs: ["charPick"] }] }); }
|
|
106
|
+
}
|
|
107
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: BaseTextViewComponent, decorators: [{
|
|
108
|
+
type: Component,
|
|
109
|
+
args: [{ selector: 'gve-base-text-view', standalone: true, imports: [CommonModule, BaseTextCharComponent], template: "<div id=\"text\">\r\n @for (line of lines; track line) {\r\n <div class=\"line\">\r\n @if (hasLineNumber) {\r\n <div class=\"nr\">\r\n {{ lines.indexOf(line) + 1 }}\r\n </div>\r\n } @for (c of line; track c.id) {\r\n <gve-base-text-char [char]=\"c\" (charPick)=\"onCharPick($event)\" />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".line{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.line *{flex:0 0 auto}.nr{font-size:.8em;font-weight:700;color:silver;margin:0 4px}\n"] }]
|
|
110
|
+
}], propDecorators: { defaultColor: [{
|
|
111
|
+
type: Input
|
|
112
|
+
}], defaultBorderColor: [{
|
|
113
|
+
type: Input
|
|
114
|
+
}], selectionColor: [{
|
|
115
|
+
type: Input
|
|
116
|
+
}], hasLineNumber: [{
|
|
117
|
+
type: Input
|
|
118
|
+
}], text: [{
|
|
119
|
+
type: Input
|
|
120
|
+
}], charPick: [{
|
|
121
|
+
type: Output
|
|
122
|
+
}], rangePick: [{
|
|
123
|
+
type: Output
|
|
124
|
+
}] } });
|
|
125
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS10ZXh0LXZpZXcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbXlybWlkb24vZ3ZlLWNvcmUvc3JjL2xpYi9jb21wb25lbnRzL2Jhc2UtdGV4dC12aWV3L2Jhc2UtdGV4dC12aWV3LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2d2ZS1jb3JlL3NyYy9saWIvY29tcG9uZW50cy9iYXNlLXRleHQtdmlldy9iYXNlLXRleHQtdmlldy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV2RSxPQUFPLEVBRUwscUJBQXFCLEdBRXRCLE1BQU0sNENBQTRDLENBQUM7QUFDcEQsT0FBTyxFQUFZLG1CQUFtQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7O0FBTzVFOztHQUVHO0FBUUgsTUFBTSxPQUFPLHFCQUFxQjtJQVBsQztRQVlTLGlCQUFZLEdBQUcsU0FBUyxDQUFDO1FBR3pCLHVCQUFrQixHQUFHLFNBQVMsQ0FBQztRQUcvQixtQkFBYyxHQUFHLFNBQVMsQ0FBQztRQUczQixrQkFBYSxHQUFHLEtBQUssQ0FBQztRQVl0QixhQUFRLEdBQ2IsSUFBSSxZQUFZLEVBQXFCLENBQUM7UUFHakMsY0FBUyxHQUNkLElBQUksWUFBWSxFQUFvQixDQUFDO1FBRWhDLFVBQUssR0FBcUIsRUFBRSxDQUFDO0tBMkZyQztJQTVHQyxJQUNXLElBQUk7UUFDYixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDcEIsQ0FBQztJQUNELElBQVcsSUFBSSxDQUFDLEtBQTZDO1FBQzNELElBQUksQ0FBQyxLQUFLLEdBQUcsS0FB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QUMsV0FBVyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7WUFDN0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDckQsQ0FBQztRQUVELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO0lBQ3RDLENBQUM7OEdBM0hVLHFCQUFxQjtrR0FBckIscUJBQXFCLDZTQ3pCbEMsZ1dBYUEsMk1EUVksWUFBWSwrQkFBRSxxQkFBcUI7OzJGQUlsQyxxQkFBcUI7a0JBUGpDLFNBQVM7K0JBQ0Usb0JBQW9CLGNBQ2xCLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxxQkFBcUIsQ0FBQzs4QkFTdkMsWUFBWTtzQkFEbEIsS0FBSztnQkFJQyxrQkFBa0I7c0JBRHhCLEtBQUs7Z0JBSUMsY0FBYztzQkFEcEIsS0FBSztnQkFJQyxhQUFhO3NCQURuQixLQUFLO2dCQUlLLElBQUk7c0JBRGQsS0FBSztnQkFVQyxRQUFRO3NCQURkLE1BQU07Z0JBS0EsU0FBUztzQkFEZixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7XHJcbiAgQmFzZVRleHRDaGFyLFxyXG4gIEJhc2VUZXh0Q2hhckNvbXBvbmVudCxcclxuICBCYXNlVGV4dENoYXJFdmVudCxcclxufSBmcm9tICcuLi9iYXNlLXRleHQtY2hhci9iYXNlLXRleHQtY2hhci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDaGFyTm9kZSwgU25hcHNob3RWaWV3U2VydmljZSB9IGZyb20gJ0BteXJtaWRvbi9ndmUtc25hcHNob3Qtdmlldyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFZhckJhc2VUZXh0UmFuZ2Uge1xyXG4gIGF0OiBudW1iZXI7XHJcbiAgcnVuOiBudW1iZXI7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBIGNvbXBvbmVudCB0byBkaXNwbGF5IGEgc2VsZWN0YWJsZSBiYXNlIHRleHQuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2d2ZS1iYXNlLXRleHQtdmlldycsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBCYXNlVGV4dENoYXJDb21wb25lbnRdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9iYXNlLXRleHQtdmlldy5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL2Jhc2UtdGV4dC12aWV3LmNvbXBvbmVudC5jc3MnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQmFzZVRleHRWaWV3Q29tcG9uZW50IHtcclxuICBwcml2YXRlIF90ZXh0Pzogc3RyaW5nIHwgQ2hhck5vZGVbXTtcclxuICBwcml2YXRlIF9sYXN0U2VsZWN0ZWRDaGFyPzogQmFzZVRleHRDaGFyO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHB1YmxpYyBkZWZhdWx0Q29sb3IgPSAnI0RCREJEQic7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgcHVibGljIGRlZmF1bHRCb3JkZXJDb2xvciA9ICcjREJEQkRCJztcclxuXHJcbiAgQElucHV0KClcclxuICBwdWJsaWMgc2VsZWN0aW9uQ29sb3IgPSAnIzNFOTJDQyc7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgcHVibGljIGhhc0xpbmVOdW1iZXIgPSBmYWxzZTtcclxuXHJcbiAgQElucHV0KClcclxuICBwdWJsaWMgZ2V0IHRleHQoKTogc3RyaW5nIHwgQ2hhck5vZGVbXSB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gdGhpcy5fdGV4dDtcclxuICB9XHJcbiAgcHVibGljIHNldCB0ZXh0KHZhbHVlOiBzdHJpbmcgfCBDaGFyTm9kZVtdIHwgdW5kZWZpbmVkIHwgbnVsbCkge1xyXG4gICAgdGhpcy5fdGV4dCA9IHZhbHVlIHx8IHVuZGVmaW5lZDtcclxuICAgIHRoaXMuYnVpbGRMaW5lcygpO1xyXG4gIH1cclxuXHJcbiAgQE91dHB1dCgpXHJcbiAgcHVibGljIGNoYXJQaWNrOiBFdmVudEVtaXR0ZXI8QmFzZVRleHRDaGFyRXZlbnQ+ID1cclxuICAgIG5ldyBFdmVudEVtaXR0ZXI8QmFzZVRleHRDaGFyRXZlbnQ+KCk7XHJcblxyXG4gIEBPdXRwdXQoKVxyXG4gIHB1YmxpYyByYW5nZVBpY2s6IEV2ZW50RW1pdHRlcjxWYXJCYXNlVGV4dFJhbmdlPiA9XHJcbiAgICBuZXcgRXZlbnRFbWl0dGVyPFZhckJhc2VUZXh0UmFuZ2U+KCk7XHJcblxyXG4gIHB1YmxpYyBsaW5lczogQmFzZVRleHRDaGFyW11bXSA9IFtdO1xyXG5cclxuICBwcml2YXRlIGJ1aWxkTGluZXMoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuX3RleHQpIHtcclxuICAgICAgdGhpcy5saW5lcyA9IFtdO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgbmV3TGluZXM6IEJhc2VUZXh0Q2hhcltdW10gPSBbXTtcclxuICAgIG5ld0xpbmVzLnB1c2goW10pO1xyXG5cclxuICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMuX3RleHQpKSB7XHJcbiAgICAgIGNvbnN0IG5vZGVzID0gdGhpcy5fdGV4dCBhcyBDaGFyTm9kZVtdO1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgY29uc3QgY2hhcjogQmFzZVRleHRDaGFyID0ge1xyXG4gICAgICAgICAgaWQ6IG5vZGVzW2ldLmlkLFxyXG4gICAgICAgICAgdmFsdWU6IG5vZGVzW2ldLmRhdGEsXHJcbiAgICAgICAgICBsYWJlbDogbm9kZXNbaV0ubGFiZWwsXHJcbiAgICAgICAgICBjb2xvcjogdGhpcy5kZWZhdWx0Q29sb3IsXHJcbiAgICAgICAgICBib3JkZXJDb2xvcjogdGhpcy5kZWZhdWx0Qm9yZGVyQ29sb3IsXHJcbiAgICAgICAgICBlbVNpemU6IDEuNSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIG5ld0xpbmVzW25ld0xpbmVzLmxlbmd0aCAtIDFdLnB1c2goY2hhcik7XHJcblxyXG4gICAgICAgIGlmIChjaGFyLnZhbHVlID09PSAnXFxuJykge1xyXG4gICAgICAgICAgbmV3TGluZXMucHVzaChbXSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX3RleHQubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCBjaGFyOiBCYXNlVGV4dENoYXIgPSB7XHJcbiAgICAgICAgICBpZDogaSArIDEsXHJcbiAgICAgICAgICB2YWx1ZTogdGhpcy5fdGV4dFtpXSxcclxuICAgICAgICAgIGxhYmVsOiBTbmFwc2hvdFZpZXdTZXJ2aWNlLnRyYW5zbGF0ZVNwZWNpYWxDaGFyKHRoaXMuX3RleHRbaV0pLFxyXG4gICAgICAgICAgY29sb3I6IHRoaXMuZGVmYXVsdENvbG9yLFxyXG4gICAgICAgICAgYm9yZGVyQ29sb3I6IHRoaXMuZGVmYXVsdEJvcmRlckNvbG9yLFxyXG4gICAgICAgICAgZW1TaXplOiAxLjUsXHJcbiAgICAgICAgfTtcclxuICAgICAgICBuZXdMaW5lc1tuZXdMaW5lcy5sZW5ndGggLSAxXS5wdXNoKGNoYXIpO1xyXG5cclxuICAgICAgICBpZiAoY2hhci52YWx1ZSA9PT0gJ1xcbicpIHtcclxuICAgICAgICAgIG5ld0xpbmVzLnB1c2goW10pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMubGluZXMgPSBuZXdMaW5lcztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVzZXRDb2xvcnMoKTogdm9pZCB7XHJcbiAgICBmb3IgKGNvbnN0IGxpbmUgb2YgdGhpcy5saW5lcykge1xyXG4gICAgICBmb3IgKGNvbnN0IGMgb2YgbGluZSkge1xyXG4gICAgICAgIGMuY29sb3IgPSB0aGlzLmRlZmF1bHRDb2xvcjtcclxuICAgICAgICBjLmJvcmRlckNvbG9yID0gdGhpcy5kZWZhdWx0Qm9yZGVyQ29sb3I7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBvbkNoYXJQaWNrKGV2ZW50OiBCYXNlVGV4dENoYXJFdmVudCk6IHZvaWQge1xyXG4gICAgdGhpcy5yZXNldENvbG9ycygpO1xyXG5cclxuICAgIGlmIChcclxuICAgICAgdGhpcy5fbGFzdFNlbGVjdGVkQ2hhciAmJlxyXG4gICAgICB0aGlzLl9sYXN0U2VsZWN0ZWRDaGFyICE9PSBldmVudC5jaGFyICYmXHJcbiAgICAgIGV2ZW50LmV2ZW50LmN0cmxLZXlcclxuICAgICkge1xyXG4gICAgICBjb25zdCBtaW5JZCA9IE1hdGgubWluKHRoaXMuX2xhc3RTZWxlY3RlZENoYXIuaWQsIGV2ZW50LmNoYXIuaWQpO1xyXG4gICAgICBjb25zdCBtYXhJZCA9IE1hdGgubWF4KHRoaXMuX2xhc3RTZWxlY3RlZENoYXIuaWQsIGV2ZW50LmNoYXIuaWQpO1xyXG5cclxuICAgICAgZm9yIChjb25zdCBsaW5lIG9mIHRoaXMubGluZXMpIHtcclxuICAgICAgICBmb3IgKGNvbnN0IGMgb2YgbGluZSkge1xyXG4gICAgICAgICAgaWYgKGMuaWQgPj0gbWluSWQgJiYgYy5pZCA8PSBtYXhJZCkge1xyXG4gICAgICAgICAgICBjLmNvbG9yID0gdGhpcy5zZWxlY3Rpb25Db2xvcjtcclxuICAgICAgICAgICAgYy5ib3JkZXJDb2xvciA9IHRoaXMuc2VsZWN0aW9uQ29sb3I7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLmNoYXJQaWNrLmVtaXQoZXZlbnQpO1xyXG4gICAgICB0aGlzLnJhbmdlUGljay5lbWl0KHsgYXQ6IG1pbklkLCBydW46IG1heElkIC0gbWluSWQgKyAxIH0pO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBzZWxlY3QgY3VycmVudCBjaGFyXHJcbiAgICAgIGV2ZW50LmNoYXIuY29sb3IgPSB0aGlzLnNlbGVjdGlvbkNvbG9yO1xyXG4gICAgICBldmVudC5jaGFyLmJvcmRlckNvbG9yID0gdGhpcy5zZWxlY3Rpb25Db2xvcjtcclxuICAgICAgdGhpcy5jaGFyUGljay5lbWl0KGV2ZW50KTtcclxuICAgICAgdGhpcy5yYW5nZVBpY2suZW1pdCh7IGF0OiBldmVudC5jaGFyLmlkLCBydW46IDEgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fbGFzdFNlbGVjdGVkQ2hhciA9IGV2ZW50LmNoYXI7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgaWQ9XCJ0ZXh0XCI+XHJcbiAgQGZvciAobGluZSBvZiBsaW5lczsgdHJhY2sgbGluZSkge1xyXG4gIDxkaXYgY2xhc3M9XCJsaW5lXCI+XHJcbiAgICBAaWYgKGhhc0xpbmVOdW1iZXIpIHtcclxuICAgIDxkaXYgY2xhc3M9XCJuclwiPlxyXG4gICAgICB7eyBsaW5lcy5pbmRleE9mKGxpbmUpICsgMSB9fVxyXG4gICAgPC9kaXY+XHJcbiAgICB9IEBmb3IgKGMgb2YgbGluZTsgdHJhY2sgYy5pZCkge1xyXG4gICAgPGd2ZS1iYXNlLXRleHQtY2hhciBbY2hhcl09XCJjXCIgKGNoYXJQaWNrKT1cIm9uQ2hhclBpY2soJGV2ZW50KVwiIC8+XHJcbiAgICB9XHJcbiAgPC9kaXY+XHJcbiAgfVxyXG48L2Rpdj5cclxuIl19
|