@myrmidon/gve-core 7.0.3 → 7.0.4

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.
@@ -3585,7 +3585,7 @@ class SnapshotEditorComponent {
3585
3585
  this.snapshot.set(this.getSnapshot());
3586
3586
  }
3587
3587
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SnapshotEditorComponent, deps: [{ token: i1$1.FormBuilder }, { token: GveApiService }, { token: i3$2.MatDialog }, { token: i4$1.DialogService }, { token: i2$3.MatSnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
3588
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: SnapshotEditorComponent, isStandalone: true, selector: "gve-snapshot-editor", inputs: { snapshot: { classPropertyName: "snapshot", publicName: "snapshot", isSignal: true, isRequired: false, transformFunction: null }, batchOps: { classPropertyName: "batchOps", publicName: "batchOps", isSignal: true, isRequired: false, transformFunction: null }, noSave: { classPropertyName: "noSave", publicName: "noSave", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, noDecoration: { classPropertyName: "noDecoration", publicName: "noDecoration", isSignal: true, isRequired: false, transformFunction: null }, featureDefs: { classPropertyName: "featureDefs", publicName: "featureDefs", isSignal: true, isRequired: false, transformFunction: null }, multiValuedFeatureIds: { classPropertyName: "multiValuedFeatureIds", publicName: "multiValuedFeatureIds", isSignal: true, isRequired: false, transformFunction: null }, sourceIds: { classPropertyName: "sourceIds", publicName: "sourceIds", isSignal: true, isRequired: false, transformFunction: null }, sourceTypes: { classPropertyName: "sourceTypes", publicName: "sourceTypes", isSignal: true, isRequired: false, transformFunction: null }, renditionSettings: { classPropertyName: "renditionSettings", publicName: "renditionSettings", isSignal: true, isRequired: false, transformFunction: null }, opListMaxHeight: { classPropertyName: "opListMaxHeight", publicName: "opListMaxHeight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { snapshot: "snapshotChange", snapshotCancel: "snapshotCancel" }, viewQueries: [{ propertyName: "renditionRef", first: true, predicate: ["rendition"], descendants: true, isSignal: true }, { propertyName: "operationEditorPanelRef", first: true, predicate: ["operationEditorPanel"], descendants: true, isSignal: true }], ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <mat-tab-group>\r\n <!-- text -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>article</mat-icon> <span class=\"label\">text</span>\r\n </ng-template>\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>\r\n <mat-panel-title> base text </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <!-- base text -->\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n color=\"mat-warn\"\r\n matTooltip=\"Enter base text\"\r\n (click)=\"inputBaseText()\"\r\n [disabled]=\"busy()\"\r\n >\r\n <mat-icon>edit</mat-icon> base text\r\n </button>\r\n\r\n @if (textRange()) {\r\n <span id=\"text-range\"\r\n >{{ textRange()!.at }}\u00D7{{ textRange()!.run }}</span\r\n >\r\n }\r\n </div>\r\n\r\n <!-- text characters -->\r\n <gve-base-text-view\r\n [text]=\"baseText.value\"\r\n [hasLineNumber]=\"true\"\r\n (rangePick)=\"onRangePick($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </mat-tab>\r\n\r\n <!-- operations -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>edit</mat-icon> <span class=\"label\">operations</span>\r\n </ng-template>\r\n\r\n <div id=\"snapshot-container\">\r\n <div id=\"general\">\r\n <div class=\"form-row\">\r\n <!-- feat details -->\r\n <mat-slide-toggle\r\n [formControl]=\"featDetails\"\r\n matTooltip=\"Toggle feature details\"\r\n >feat. details</mat-slide-toggle\r\n >\r\n <!-- auto run on edit -->\r\n <mat-slide-toggle\r\n [formControl]=\"autoRun\"\r\n matTooltip=\"Auto-run operations on edit\"\r\n >auto-run</mat-slide-toggle\r\n >\r\n\r\n <div class=\"form-row right\">\r\n <!-- copy ops DSL -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as DSL to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsDsl()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n\r\n <!-- copy ops JSON -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as JSON to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsJson()\"\r\n >\r\n <mat-icon>copy_all</mat-icon>\r\n </button>\r\n\r\n <!-- remove ops -->\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Remove all the operations\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"clearOperations()\"\r\n >\r\n <mat-icon>delete_forever</mat-icon> clear\r\n </button>\r\n\r\n <!-- batch add ops -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n matTooltip=\"Add a batch of operations\"\r\n class=\"mat-primary\"\r\n [disabled]=\"busy()\"\r\n (click)=\"parseOperations()\"\r\n >\r\n <mat-icon>post_add</mat-icon> batch\r\n </button>\r\n\r\n <!-- edit operations feats/sources -->\r\n <form\r\n (submit)=\"editOperationsFeats()\"\r\n [formGroup]=\"editFeatsForm\"\r\n >\r\n <mat-form-field>\r\n <mat-label>operations (e.g. 2, 5-7, 9)</mat-label>\r\n <input matInput [formControl]=\"editFeatsRange\" />\r\n @if (\r\n $any(editFeatsRange).errors?.required &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>range required</mat-error>\r\n }\r\n @if (\r\n $any(editFeatsRange).errors?.pattern &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>invalid range (use e.g. 2, 5-7, 9)</mat-error>\r\n }\r\n <button\r\n type=\"button\"\r\n matIconButton\r\n matSuffix\r\n matTooltip=\"Edit sources for range\"\r\n (click)=\"editOperationSources()\"\r\n >\r\n <mat-icon>people</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n matIconButton\r\n matSuffix\r\n matTooltip=\"Edit features for range\"\r\n >\r\n <mat-icon>edit_note</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </form>\r\n\r\n <!-- add op -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-primary\"\r\n [disabled]=\"\r\n busy() || !operations.value.length || !baseText.value\r\n \"\r\n (click)=\"editNewOperation()\"\r\n matTooltip=\"Add a new operation\"\r\n >\r\n <mat-icon>add_circle</mat-icon> operation\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- feature set editor -->\r\n @if (operationFeats() !== undefined) {\r\n <mat-expansion-panel #featsEditorPanel [expanded]=\"true\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Features of {{ batchRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-feature-set-editor\r\n [batchMode]=\"true\"\r\n [features]=\"operationFeats() || []\"\r\n [isVar]=\"true\"\r\n [featNames]=\"featureDefs()?.names\"\r\n [featValues]=\"featureDefs()?.values\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n (close)=\"closeOperationFeats()\"\r\n (featuresChange)=\"saveOperationsFeats($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation source editor -->\r\n @if (batchForSource() && batchOpNumbers()?.length) {\r\n <mat-expansion-panel #sourcesEditorPanel [expanded]=\"true\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Sources of {{ batchRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-operation-source-editor\r\n [ids]=\"sourceIds()\"\r\n [types]=\"sourceTypes()\"\r\n (sourceCancel)=\"closeOperationSources()\"\r\n (sourceChange)=\"saveOperationSources($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation editor -->\r\n @if (editedOp()) {\r\n <mat-expansion-panel\r\n #operationEditorPanel\r\n [expanded]=\"editedOp()\"\r\n [disabled]=\"!editedOp()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>operation {{ editedOp()?.id }}</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-chain-operation-editor\r\n [featureDefs]=\"featureDefs()\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n [hidePreview]=\"editedOpIndex() === -1\"\r\n [operation]=\"editedOp()\"\r\n [rangePatch]=\"editedOpRangePatch()\"\r\n [sourceIds]=\"sourceIds()\"\r\n [sourceTypes]=\"sourceTypes()\"\r\n (operationCancel)=\"onOperationCancel()\"\r\n (operationChange)=\"onOperationChange($event)\"\r\n (operationPreview)=\"onOperationPreview($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- ops -->\r\n <div\r\n id=\"ops\"\r\n [style.max-height]=\"opListMaxHeight()\"\r\n [style.overflow-y]=\"opListMaxHeight() ? 'auto' : null\"\r\n >\r\n <!-- operations list -->\r\n @if (operations.value.length) {\r\n <table id=\"list\">\r\n <thead>\r\n <tr>\r\n <th>nr.</th>\r\n <th></th>\r\n <th>ID</th>\r\n <th>type</th>\r\n <th>at</th>\r\n <th>run</th>\r\n <th>value</th>\r\n <th>itag</th>\r\n <th>otag</th>\r\n <th>gid</th>\r\n <th>feats</th>\r\n <th>src</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (\r\n operation of operations.value;\r\n track operation.id;\r\n let index = $index\r\n ) {\r\n <tr\r\n [class.selected]=\"operation.id === editedOp()?.id\"\r\n [class.feat-editing]=\"batchOpNumbers()?.includes(index + 1)\"\r\n >\r\n <td class=\"fit-width\">{{ index + 1 }}.</td>\r\n <td class=\"fit-width\">\r\n <!-- edit -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-primary\"\r\n (click)=\"editOperation(index)\"\r\n matTooltip=\"Edit operation\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <!-- delete -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-warn\"\r\n (click)=\"deleteOperation(index)\"\r\n matTooltip=\"Delete operation\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n <!-- run to -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-accent\"\r\n (click)=\"runTo(index)\"\r\n matTooltip=\"Run to this operation\"\r\n >\r\n <mat-icon class=\"mat-accent\">subscriptions</mat-icon>\r\n </button>\r\n <!-- duplicate -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"duplicateOperation(index)\"\r\n matTooltip=\"Duplicate operation\"\r\n >\r\n <mat-icon>control_point_duplicate</mat-icon>\r\n </button>\r\n <!-- move up -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationUp(index)\"\r\n matTooltip=\"Move operation up\"\r\n [disabled]=\"index === 0\"\r\n >\r\n <mat-icon>arrow_circle_up</mat-icon>\r\n </button>\r\n <!-- move down -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationDown(index)\"\r\n matTooltip=\"Move operation down\"\r\n [disabled]=\"index === operations.value.length - 1\"\r\n >\r\n <mat-icon>arrow_circle_down</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ operation.id }}</td>\r\n <td>{{ operation.type | flatLookup: opTypeMap }}</td>\r\n <td>{{ operation.at }}</td>\r\n <td>{{ operation.run }}</td>\r\n <td>{{ operation.value }}</td>\r\n <td>{{ operation.inputTag }}</td>\r\n <td>{{ operation.outputTag }}</td>\r\n <td>{{ operation.groupId }}</td>\r\n <td>\r\n @if (operation.features?.length) {\r\n @if (featDetails.value) {\r\n <div class=\"form-row\">\r\n @for (\r\n feat of operation.features;\r\n track $index;\r\n let i = $index\r\n ) {\r\n <div class=\"feature\">\r\n <span class=\"fname\">{{\r\n feat.name\r\n | flatLookup\r\n : featureDefs()?.names\r\n : \"id\"\r\n : \"label\"\r\n }}</span\r\n >=<span class=\"fvalue\">{{\r\n feat.value\r\n | flatLookup\r\n : featureDefs()?.values?.[feat.name]\r\n : \"id\"\r\n : \"label\"\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <!-- version badge -->\r\n @if (\r\n operation.features?.some(f => f.name === 'version')\r\n ) {\r\n <span\r\n matBadge=\"{{ operation.features?.find(f => f.name === 'version')?.value }}\"\r\n matBadgeOverlap=\"false\"\r\n >{{ operation.features?.length }}</span\r\n >\r\n }\r\n }\r\n }\r\n </td>\r\n <td>{{ operation.sources?.length || \"\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n </div>\r\n </div>\r\n </mat-tab>\r\n </mat-tab-group>\r\n\r\n <!-- progress -->\r\n <div class=\"margin-bottom\">\r\n @if (busy()) {\r\n <mat-progress-bar mode=\"indeterminate\" />\r\n }\r\n </div>\r\n\r\n <!-- result -->\r\n @if (result()) {\r\n <fieldset id=\"result\">\r\n <legend>result</legend>\r\n <gve-chain-result-view\r\n [result]=\"result()!\"\r\n [initialStepIndex]=\"initialStepIndex()\"\r\n [disabledRangePick]=\"editedOp() ? false : true\"\r\n (stepPick)=\"onStepPick($event)\"\r\n (rangePick)=\"onRangePick($event, true)\"\r\n />\r\n </fieldset>\r\n }\r\n\r\n <!-- snapshot view -->\r\n @if (result()) {\r\n <div id=\"preview\">\r\n <gve-snapshot-rendition #rendition class=\"rendition\">\r\n </gve-snapshot-rendition>\r\n </div>\r\n }\r\n\r\n <!--buttons -->\r\n <div class=\"form-row-center\">\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"close()\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n close\r\n </button>\r\n @if (!noSave()) {\r\n <button\r\n type=\"submit\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save changes\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon>check_circle</mat-icon>\r\n save\r\n </button>\r\n }\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row-center{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.form-row,.form-row-center *{flex:0 0 auto}.form-row .right{margin-left:auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.button-row *{flex:0 0 auto}.long-text{width:100%;max-width:800px}.margin-bottom{margin-bottom:8px}#text-range{margin:8px;border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:var(--mat-sys-on-surface-variant);margin:8px}#result{max-height:800px;overflow:auto}#snapshot-container{margin-top:6px}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.feat-editing{background-color:var(--mat-sys-tertiary-container);color:var(--mat-sys-on-tertiary-container)}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}fieldset{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}legend{color:var(--mat-sys-on-surface-variant)}.error{color:var(--mat-sys-error)}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}.boxed{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}span.label{margin-left:8px}.feature{color:var(--mat-sys-on-surface-variant)}.fname{font-size:.9em;color:var(--mat-sys-on-surface-variant)}.fvalue{font-size:.9em;color:var(--mat-sys-on-surface-variant);background-color:var(--mat-sys-surface-container);padding:2px 4px;border-radius:4px}gve-animation-timeline-set{margin:8px 0}div#image{display:grid;gap:8px;grid-template-rows:auto;grid-template-columns:1fr auto;grid-template-areas:\"image-ctl image-view\"}div#image-ctl{grid-area:image-ctl}div#image-view{grid-area:image-view}div#chain-view{margin-bottom:8px}#preview{margin:8px 0}.rendition{display:block;width:100%;min-height:600px;max-height:80vh;border:1px solid var(--mat-sys-on-surface-variant);overflow:auto}@media only screen and (max-width:959px){div#image{grid-template-columns:1fr;grid-template-areas:\"image-ctl\" \"image-view\"}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i7$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i7$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { 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: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i11.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i12.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i12.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i12.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: ChainOperationEditorComponent, selector: "gve-chain-operation-editor", inputs: ["operation", "snapshot", "hidePreview", "featureDefs", "rangePatch", "multiValuedFeatureIds", "sourceIds", "sourceTypes"], outputs: ["operationChange", "operationPreview", "operationCancel"] }, { kind: "component", type: ChainResultViewComponent, selector: "gve-chain-result-view", inputs: ["result", "initialStepIndex", "disabledRangePick"], outputs: ["stepPick", "rangePick"] }, { kind: "component", type: BaseTextViewComponent, selector: "gve-base-text-view", inputs: ["defaultColor", "defaultBorderColor", "selectionColor", "searchHighlightColor", "hasLineNumber", "text", "colorCallback", "borderColorCallback"], outputs: ["charPick", "rangePick"] }, { kind: "component", type: FeatureSetEditorComponent, selector: "gve-feature-set-editor", inputs: ["isVar", "featNames", "featValues", "filterThreshold", "multiValuedFeatureIds", "batchMode", "features"], outputs: ["close", "featuresChange"] }, { kind: "component", type: OperationSourceEditorComponent, selector: "gve-operation-source-editor", inputs: ["source", "ids", "types"], outputs: ["sourceChange", "sourceCancel"] }, { kind: "pipe", type: FlatLookupPipe, name: "flatLookup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3588
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: SnapshotEditorComponent, isStandalone: true, selector: "gve-snapshot-editor", inputs: { snapshot: { classPropertyName: "snapshot", publicName: "snapshot", isSignal: true, isRequired: false, transformFunction: null }, batchOps: { classPropertyName: "batchOps", publicName: "batchOps", isSignal: true, isRequired: false, transformFunction: null }, noSave: { classPropertyName: "noSave", publicName: "noSave", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, noDecoration: { classPropertyName: "noDecoration", publicName: "noDecoration", isSignal: true, isRequired: false, transformFunction: null }, featureDefs: { classPropertyName: "featureDefs", publicName: "featureDefs", isSignal: true, isRequired: false, transformFunction: null }, multiValuedFeatureIds: { classPropertyName: "multiValuedFeatureIds", publicName: "multiValuedFeatureIds", isSignal: true, isRequired: false, transformFunction: null }, sourceIds: { classPropertyName: "sourceIds", publicName: "sourceIds", isSignal: true, isRequired: false, transformFunction: null }, sourceTypes: { classPropertyName: "sourceTypes", publicName: "sourceTypes", isSignal: true, isRequired: false, transformFunction: null }, renditionSettings: { classPropertyName: "renditionSettings", publicName: "renditionSettings", isSignal: true, isRequired: false, transformFunction: null }, opListMaxHeight: { classPropertyName: "opListMaxHeight", publicName: "opListMaxHeight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { snapshot: "snapshotChange", snapshotCancel: "snapshotCancel" }, viewQueries: [{ propertyName: "renditionRef", first: true, predicate: ["rendition"], descendants: true, isSignal: true }, { propertyName: "operationEditorPanelRef", first: true, predicate: ["operationEditorPanel"], descendants: true, isSignal: true }], ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <mat-tab-group>\r\n <!-- text -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>article</mat-icon> <span class=\"label\">text</span>\r\n </ng-template>\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>\r\n <mat-panel-title> base text </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <!-- base text -->\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n color=\"mat-warn\"\r\n matTooltip=\"Enter base text\"\r\n (click)=\"inputBaseText()\"\r\n [disabled]=\"busy()\"\r\n >\r\n <mat-icon>edit</mat-icon> base text\r\n </button>\r\n\r\n @if (textRange()) {\r\n <span id=\"text-range\"\r\n >{{ textRange()!.at }}\u00D7{{ textRange()!.run }}</span\r\n >\r\n }\r\n </div>\r\n\r\n <!-- text characters -->\r\n <gve-base-text-view\r\n [text]=\"baseText.value\"\r\n [hasLineNumber]=\"true\"\r\n (rangePick)=\"onRangePick($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </mat-tab>\r\n\r\n <!-- operations -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>edit</mat-icon> <span class=\"label\">operations</span>\r\n </ng-template>\r\n\r\n <div id=\"snapshot-container\">\r\n <div id=\"general\">\r\n <div class=\"form-row\">\r\n <!-- feat details -->\r\n <mat-slide-toggle\r\n [formControl]=\"featDetails\"\r\n matTooltip=\"Toggle feature details\"\r\n >feat. details</mat-slide-toggle\r\n >\r\n <!-- auto run on edit -->\r\n <mat-slide-toggle\r\n [formControl]=\"autoRun\"\r\n matTooltip=\"Auto-run operations on edit\"\r\n >auto-run</mat-slide-toggle\r\n >\r\n\r\n <div class=\"form-row right\">\r\n <!-- copy ops DSL -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as DSL to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsDsl()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n\r\n <!-- copy ops JSON -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as JSON to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsJson()\"\r\n >\r\n <mat-icon>copy_all</mat-icon>\r\n </button>\r\n\r\n <!-- remove ops -->\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Remove all the operations\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"clearOperations()\"\r\n >\r\n <mat-icon>delete_forever</mat-icon> clear\r\n </button>\r\n\r\n <!-- batch add ops -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n matTooltip=\"Add a batch of operations\"\r\n class=\"mat-primary\"\r\n [disabled]=\"busy()\"\r\n (click)=\"parseOperations()\"\r\n >\r\n <mat-icon>post_add</mat-icon> batch\r\n </button>\r\n\r\n <!-- edit operations feats/sources -->\r\n <form\r\n (submit)=\"editOperationsFeats()\"\r\n [formGroup]=\"editFeatsForm\"\r\n >\r\n <mat-form-field>\r\n <mat-label>operations (e.g. 2, 5-7, 9)</mat-label>\r\n <input matInput [formControl]=\"editFeatsRange\" />\r\n @if (\r\n $any(editFeatsRange).errors?.required &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>range required</mat-error>\r\n }\r\n @if (\r\n $any(editFeatsRange).errors?.pattern &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>invalid range (use e.g. 2, 5-7, 9)</mat-error>\r\n }\r\n <button\r\n type=\"button\"\r\n matIconButton\r\n matSuffix\r\n matTooltip=\"Edit sources for range\"\r\n (click)=\"editOperationSources()\"\r\n >\r\n <mat-icon>people</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n matIconButton\r\n matSuffix\r\n matTooltip=\"Edit features for range\"\r\n >\r\n <mat-icon>edit_note</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </form>\r\n\r\n <!-- add op -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-primary\"\r\n [disabled]=\"busy() || !baseText.value\"\r\n (click)=\"editNewOperation()\"\r\n matTooltip=\"Add a new operation\"\r\n >\r\n <mat-icon>add_circle</mat-icon> operation\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- feature set editor -->\r\n @if (operationFeats() !== undefined) {\r\n <mat-expansion-panel #featsEditorPanel [expanded]=\"true\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Features of {{ batchRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-feature-set-editor\r\n [batchMode]=\"true\"\r\n [features]=\"operationFeats() || []\"\r\n [isVar]=\"true\"\r\n [featNames]=\"featureDefs()?.names\"\r\n [featValues]=\"featureDefs()?.values\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n (close)=\"closeOperationFeats()\"\r\n (featuresChange)=\"saveOperationsFeats($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation source editor -->\r\n @if (batchForSource() && batchOpNumbers()?.length) {\r\n <mat-expansion-panel #sourcesEditorPanel [expanded]=\"true\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Sources of {{ batchRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-operation-source-editor\r\n [ids]=\"sourceIds()\"\r\n [types]=\"sourceTypes()\"\r\n (sourceCancel)=\"closeOperationSources()\"\r\n (sourceChange)=\"saveOperationSources($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation editor -->\r\n @if (editedOp()) {\r\n <mat-expansion-panel\r\n #operationEditorPanel\r\n [expanded]=\"editedOp()\"\r\n [disabled]=\"!editedOp()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>operation {{ editedOp()?.id }}</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-chain-operation-editor\r\n [featureDefs]=\"featureDefs()\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n [hidePreview]=\"editedOpIndex() === -1\"\r\n [operation]=\"editedOp()\"\r\n [rangePatch]=\"editedOpRangePatch()\"\r\n [sourceIds]=\"sourceIds()\"\r\n [sourceTypes]=\"sourceTypes()\"\r\n (operationCancel)=\"onOperationCancel()\"\r\n (operationChange)=\"onOperationChange($event)\"\r\n (operationPreview)=\"onOperationPreview($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- ops -->\r\n <div\r\n id=\"ops\"\r\n [style.max-height]=\"opListMaxHeight()\"\r\n [style.overflow-y]=\"opListMaxHeight() ? 'auto' : null\"\r\n >\r\n <!-- operations list -->\r\n @if (operations.value.length) {\r\n <table id=\"list\">\r\n <thead>\r\n <tr>\r\n <th>nr.</th>\r\n <th></th>\r\n <th>ID</th>\r\n <th>type</th>\r\n <th>at</th>\r\n <th>run</th>\r\n <th>value</th>\r\n <th>itag</th>\r\n <th>otag</th>\r\n <th>gid</th>\r\n <th>feats</th>\r\n <th>src</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (\r\n operation of operations.value;\r\n track operation.id;\r\n let index = $index\r\n ) {\r\n <tr\r\n [class.selected]=\"operation.id === editedOp()?.id\"\r\n [class.feat-editing]=\"batchOpNumbers()?.includes(index + 1)\"\r\n >\r\n <td class=\"fit-width\">{{ index + 1 }}.</td>\r\n <td class=\"fit-width\">\r\n <!-- edit -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-primary\"\r\n (click)=\"editOperation(index)\"\r\n matTooltip=\"Edit operation\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <!-- delete -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-warn\"\r\n (click)=\"deleteOperation(index)\"\r\n matTooltip=\"Delete operation\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n <!-- run to -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-accent\"\r\n (click)=\"runTo(index)\"\r\n matTooltip=\"Run to this operation\"\r\n >\r\n <mat-icon class=\"mat-accent\">subscriptions</mat-icon>\r\n </button>\r\n <!-- duplicate -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"duplicateOperation(index)\"\r\n matTooltip=\"Duplicate operation\"\r\n >\r\n <mat-icon>control_point_duplicate</mat-icon>\r\n </button>\r\n <!-- move up -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationUp(index)\"\r\n matTooltip=\"Move operation up\"\r\n [disabled]=\"index === 0\"\r\n >\r\n <mat-icon>arrow_circle_up</mat-icon>\r\n </button>\r\n <!-- move down -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationDown(index)\"\r\n matTooltip=\"Move operation down\"\r\n [disabled]=\"index === operations.value.length - 1\"\r\n >\r\n <mat-icon>arrow_circle_down</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ operation.id }}</td>\r\n <td>{{ operation.type | flatLookup: opTypeMap }}</td>\r\n <td>{{ operation.at }}</td>\r\n <td>{{ operation.run }}</td>\r\n <td>{{ operation.value }}</td>\r\n <td>{{ operation.inputTag }}</td>\r\n <td>{{ operation.outputTag }}</td>\r\n <td>{{ operation.groupId }}</td>\r\n <td>\r\n @if (operation.features?.length) {\r\n @if (featDetails.value) {\r\n <div class=\"form-row\">\r\n @for (\r\n feat of operation.features;\r\n track $index;\r\n let i = $index\r\n ) {\r\n <div class=\"feature\">\r\n <span class=\"fname\">{{\r\n feat.name\r\n | flatLookup\r\n : featureDefs()?.names\r\n : \"id\"\r\n : \"label\"\r\n }}</span\r\n >=<span class=\"fvalue\">{{\r\n feat.value\r\n | flatLookup\r\n : featureDefs()?.values?.[feat.name]\r\n : \"id\"\r\n : \"label\"\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <!-- version badge -->\r\n @if (\r\n operation.features?.some(f => f.name === 'version')\r\n ) {\r\n <span\r\n matBadge=\"{{ operation.features?.find(f => f.name === 'version')?.value }}\"\r\n matBadgeOverlap=\"false\"\r\n >{{ operation.features?.length }}</span\r\n >\r\n }\r\n }\r\n }\r\n </td>\r\n <td>{{ operation.sources?.length || \"\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n </div>\r\n </div>\r\n </mat-tab>\r\n </mat-tab-group>\r\n\r\n <!-- progress -->\r\n <div class=\"margin-bottom\">\r\n @if (busy()) {\r\n <mat-progress-bar mode=\"indeterminate\" />\r\n }\r\n </div>\r\n\r\n <!-- result -->\r\n @if (result()) {\r\n <fieldset id=\"result\">\r\n <legend>result</legend>\r\n <gve-chain-result-view\r\n [result]=\"result()!\"\r\n [initialStepIndex]=\"initialStepIndex()\"\r\n [disabledRangePick]=\"editedOp() ? false : true\"\r\n (stepPick)=\"onStepPick($event)\"\r\n (rangePick)=\"onRangePick($event, true)\"\r\n />\r\n </fieldset>\r\n }\r\n\r\n <!-- snapshot view -->\r\n @if (result()) {\r\n <div id=\"preview\">\r\n <gve-snapshot-rendition #rendition class=\"rendition\">\r\n </gve-snapshot-rendition>\r\n </div>\r\n }\r\n\r\n <!--buttons -->\r\n <div class=\"form-row-center\">\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"close()\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n close\r\n </button>\r\n @if (!noSave()) {\r\n <button\r\n type=\"submit\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save changes\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon>check_circle</mat-icon>\r\n save\r\n </button>\r\n }\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row-center{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.form-row,.form-row-center *{flex:0 0 auto}.form-row .right{margin-left:auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.button-row *{flex:0 0 auto}.long-text{width:100%;max-width:800px}.margin-bottom{margin-bottom:8px}#text-range{margin:8px;border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:var(--mat-sys-on-surface-variant);margin:8px}#result{max-height:800px;overflow:auto}#snapshot-container{margin-top:6px}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.feat-editing{background-color:var(--mat-sys-tertiary-container);color:var(--mat-sys-on-tertiary-container)}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}fieldset{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}legend{color:var(--mat-sys-on-surface-variant)}.error{color:var(--mat-sys-error)}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}.boxed{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}span.label{margin-left:8px}.feature{color:var(--mat-sys-on-surface-variant)}.fname{font-size:.9em;color:var(--mat-sys-on-surface-variant)}.fvalue{font-size:.9em;color:var(--mat-sys-on-surface-variant);background-color:var(--mat-sys-surface-container);padding:2px 4px;border-radius:4px}gve-animation-timeline-set{margin:8px 0}div#image{display:grid;gap:8px;grid-template-rows:auto;grid-template-columns:1fr auto;grid-template-areas:\"image-ctl image-view\"}div#image-ctl{grid-area:image-ctl}div#image-view{grid-area:image-view}div#chain-view{margin-bottom:8px}#preview{margin:8px 0}.rendition{display:block;width:100%;min-height:600px;max-height:80vh;border:1px solid var(--mat-sys-on-surface-variant);overflow:auto}@media only screen and (max-width:959px){div#image{grid-template-columns:1fr;grid-template-areas:\"image-ctl\" \"image-view\"}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i7$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i7$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { 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: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i11.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i12.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i12.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i12.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: ChainOperationEditorComponent, selector: "gve-chain-operation-editor", inputs: ["operation", "snapshot", "hidePreview", "featureDefs", "rangePatch", "multiValuedFeatureIds", "sourceIds", "sourceTypes"], outputs: ["operationChange", "operationPreview", "operationCancel"] }, { kind: "component", type: ChainResultViewComponent, selector: "gve-chain-result-view", inputs: ["result", "initialStepIndex", "disabledRangePick"], outputs: ["stepPick", "rangePick"] }, { kind: "component", type: BaseTextViewComponent, selector: "gve-base-text-view", inputs: ["defaultColor", "defaultBorderColor", "selectionColor", "searchHighlightColor", "hasLineNumber", "text", "colorCallback", "borderColorCallback"], outputs: ["charPick", "rangePick"] }, { kind: "component", type: FeatureSetEditorComponent, selector: "gve-feature-set-editor", inputs: ["isVar", "featNames", "featValues", "filterThreshold", "multiValuedFeatureIds", "batchMode", "features"], outputs: ["close", "featuresChange"] }, { kind: "component", type: OperationSourceEditorComponent, selector: "gve-operation-source-editor", inputs: ["source", "ids", "types"], outputs: ["sourceChange", "sourceCancel"] }, { kind: "pipe", type: FlatLookupPipe, name: "flatLookup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3589
3589
  }
3590
3590
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SnapshotEditorComponent, decorators: [{
3591
3591
  type: Component,
@@ -3613,7 +3613,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
3613
3613
  FeatureSetEditorComponent,
3614
3614
  OperationSourceEditorComponent,
3615
3615
  FlatLookupPipe,
3616
- ], schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <mat-tab-group>\r\n <!-- text -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>article</mat-icon> <span class=\"label\">text</span>\r\n </ng-template>\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>\r\n <mat-panel-title> base text </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <!-- base text -->\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n color=\"mat-warn\"\r\n matTooltip=\"Enter base text\"\r\n (click)=\"inputBaseText()\"\r\n [disabled]=\"busy()\"\r\n >\r\n <mat-icon>edit</mat-icon> base text\r\n </button>\r\n\r\n @if (textRange()) {\r\n <span id=\"text-range\"\r\n >{{ textRange()!.at }}\u00D7{{ textRange()!.run }}</span\r\n >\r\n }\r\n </div>\r\n\r\n <!-- text characters -->\r\n <gve-base-text-view\r\n [text]=\"baseText.value\"\r\n [hasLineNumber]=\"true\"\r\n (rangePick)=\"onRangePick($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </mat-tab>\r\n\r\n <!-- operations -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>edit</mat-icon> <span class=\"label\">operations</span>\r\n </ng-template>\r\n\r\n <div id=\"snapshot-container\">\r\n <div id=\"general\">\r\n <div class=\"form-row\">\r\n <!-- feat details -->\r\n <mat-slide-toggle\r\n [formControl]=\"featDetails\"\r\n matTooltip=\"Toggle feature details\"\r\n >feat. details</mat-slide-toggle\r\n >\r\n <!-- auto run on edit -->\r\n <mat-slide-toggle\r\n [formControl]=\"autoRun\"\r\n matTooltip=\"Auto-run operations on edit\"\r\n >auto-run</mat-slide-toggle\r\n >\r\n\r\n <div class=\"form-row right\">\r\n <!-- copy ops DSL -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as DSL to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsDsl()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n\r\n <!-- copy ops JSON -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as JSON to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsJson()\"\r\n >\r\n <mat-icon>copy_all</mat-icon>\r\n </button>\r\n\r\n <!-- remove ops -->\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Remove all the operations\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"clearOperations()\"\r\n >\r\n <mat-icon>delete_forever</mat-icon> clear\r\n </button>\r\n\r\n <!-- batch add ops -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n matTooltip=\"Add a batch of operations\"\r\n class=\"mat-primary\"\r\n [disabled]=\"busy()\"\r\n (click)=\"parseOperations()\"\r\n >\r\n <mat-icon>post_add</mat-icon> batch\r\n </button>\r\n\r\n <!-- edit operations feats/sources -->\r\n <form\r\n (submit)=\"editOperationsFeats()\"\r\n [formGroup]=\"editFeatsForm\"\r\n >\r\n <mat-form-field>\r\n <mat-label>operations (e.g. 2, 5-7, 9)</mat-label>\r\n <input matInput [formControl]=\"editFeatsRange\" />\r\n @if (\r\n $any(editFeatsRange).errors?.required &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>range required</mat-error>\r\n }\r\n @if (\r\n $any(editFeatsRange).errors?.pattern &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>invalid range (use e.g. 2, 5-7, 9)</mat-error>\r\n }\r\n <button\r\n type=\"button\"\r\n matIconButton\r\n matSuffix\r\n matTooltip=\"Edit sources for range\"\r\n (click)=\"editOperationSources()\"\r\n >\r\n <mat-icon>people</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n matIconButton\r\n matSuffix\r\n matTooltip=\"Edit features for range\"\r\n >\r\n <mat-icon>edit_note</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </form>\r\n\r\n <!-- add op -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-primary\"\r\n [disabled]=\"\r\n busy() || !operations.value.length || !baseText.value\r\n \"\r\n (click)=\"editNewOperation()\"\r\n matTooltip=\"Add a new operation\"\r\n >\r\n <mat-icon>add_circle</mat-icon> operation\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- feature set editor -->\r\n @if (operationFeats() !== undefined) {\r\n <mat-expansion-panel #featsEditorPanel [expanded]=\"true\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Features of {{ batchRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-feature-set-editor\r\n [batchMode]=\"true\"\r\n [features]=\"operationFeats() || []\"\r\n [isVar]=\"true\"\r\n [featNames]=\"featureDefs()?.names\"\r\n [featValues]=\"featureDefs()?.values\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n (close)=\"closeOperationFeats()\"\r\n (featuresChange)=\"saveOperationsFeats($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation source editor -->\r\n @if (batchForSource() && batchOpNumbers()?.length) {\r\n <mat-expansion-panel #sourcesEditorPanel [expanded]=\"true\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Sources of {{ batchRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-operation-source-editor\r\n [ids]=\"sourceIds()\"\r\n [types]=\"sourceTypes()\"\r\n (sourceCancel)=\"closeOperationSources()\"\r\n (sourceChange)=\"saveOperationSources($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation editor -->\r\n @if (editedOp()) {\r\n <mat-expansion-panel\r\n #operationEditorPanel\r\n [expanded]=\"editedOp()\"\r\n [disabled]=\"!editedOp()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>operation {{ editedOp()?.id }}</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-chain-operation-editor\r\n [featureDefs]=\"featureDefs()\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n [hidePreview]=\"editedOpIndex() === -1\"\r\n [operation]=\"editedOp()\"\r\n [rangePatch]=\"editedOpRangePatch()\"\r\n [sourceIds]=\"sourceIds()\"\r\n [sourceTypes]=\"sourceTypes()\"\r\n (operationCancel)=\"onOperationCancel()\"\r\n (operationChange)=\"onOperationChange($event)\"\r\n (operationPreview)=\"onOperationPreview($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- ops -->\r\n <div\r\n id=\"ops\"\r\n [style.max-height]=\"opListMaxHeight()\"\r\n [style.overflow-y]=\"opListMaxHeight() ? 'auto' : null\"\r\n >\r\n <!-- operations list -->\r\n @if (operations.value.length) {\r\n <table id=\"list\">\r\n <thead>\r\n <tr>\r\n <th>nr.</th>\r\n <th></th>\r\n <th>ID</th>\r\n <th>type</th>\r\n <th>at</th>\r\n <th>run</th>\r\n <th>value</th>\r\n <th>itag</th>\r\n <th>otag</th>\r\n <th>gid</th>\r\n <th>feats</th>\r\n <th>src</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (\r\n operation of operations.value;\r\n track operation.id;\r\n let index = $index\r\n ) {\r\n <tr\r\n [class.selected]=\"operation.id === editedOp()?.id\"\r\n [class.feat-editing]=\"batchOpNumbers()?.includes(index + 1)\"\r\n >\r\n <td class=\"fit-width\">{{ index + 1 }}.</td>\r\n <td class=\"fit-width\">\r\n <!-- edit -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-primary\"\r\n (click)=\"editOperation(index)\"\r\n matTooltip=\"Edit operation\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <!-- delete -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-warn\"\r\n (click)=\"deleteOperation(index)\"\r\n matTooltip=\"Delete operation\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n <!-- run to -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-accent\"\r\n (click)=\"runTo(index)\"\r\n matTooltip=\"Run to this operation\"\r\n >\r\n <mat-icon class=\"mat-accent\">subscriptions</mat-icon>\r\n </button>\r\n <!-- duplicate -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"duplicateOperation(index)\"\r\n matTooltip=\"Duplicate operation\"\r\n >\r\n <mat-icon>control_point_duplicate</mat-icon>\r\n </button>\r\n <!-- move up -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationUp(index)\"\r\n matTooltip=\"Move operation up\"\r\n [disabled]=\"index === 0\"\r\n >\r\n <mat-icon>arrow_circle_up</mat-icon>\r\n </button>\r\n <!-- move down -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationDown(index)\"\r\n matTooltip=\"Move operation down\"\r\n [disabled]=\"index === operations.value.length - 1\"\r\n >\r\n <mat-icon>arrow_circle_down</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ operation.id }}</td>\r\n <td>{{ operation.type | flatLookup: opTypeMap }}</td>\r\n <td>{{ operation.at }}</td>\r\n <td>{{ operation.run }}</td>\r\n <td>{{ operation.value }}</td>\r\n <td>{{ operation.inputTag }}</td>\r\n <td>{{ operation.outputTag }}</td>\r\n <td>{{ operation.groupId }}</td>\r\n <td>\r\n @if (operation.features?.length) {\r\n @if (featDetails.value) {\r\n <div class=\"form-row\">\r\n @for (\r\n feat of operation.features;\r\n track $index;\r\n let i = $index\r\n ) {\r\n <div class=\"feature\">\r\n <span class=\"fname\">{{\r\n feat.name\r\n | flatLookup\r\n : featureDefs()?.names\r\n : \"id\"\r\n : \"label\"\r\n }}</span\r\n >=<span class=\"fvalue\">{{\r\n feat.value\r\n | flatLookup\r\n : featureDefs()?.values?.[feat.name]\r\n : \"id\"\r\n : \"label\"\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <!-- version badge -->\r\n @if (\r\n operation.features?.some(f => f.name === 'version')\r\n ) {\r\n <span\r\n matBadge=\"{{ operation.features?.find(f => f.name === 'version')?.value }}\"\r\n matBadgeOverlap=\"false\"\r\n >{{ operation.features?.length }}</span\r\n >\r\n }\r\n }\r\n }\r\n </td>\r\n <td>{{ operation.sources?.length || \"\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n </div>\r\n </div>\r\n </mat-tab>\r\n </mat-tab-group>\r\n\r\n <!-- progress -->\r\n <div class=\"margin-bottom\">\r\n @if (busy()) {\r\n <mat-progress-bar mode=\"indeterminate\" />\r\n }\r\n </div>\r\n\r\n <!-- result -->\r\n @if (result()) {\r\n <fieldset id=\"result\">\r\n <legend>result</legend>\r\n <gve-chain-result-view\r\n [result]=\"result()!\"\r\n [initialStepIndex]=\"initialStepIndex()\"\r\n [disabledRangePick]=\"editedOp() ? false : true\"\r\n (stepPick)=\"onStepPick($event)\"\r\n (rangePick)=\"onRangePick($event, true)\"\r\n />\r\n </fieldset>\r\n }\r\n\r\n <!-- snapshot view -->\r\n @if (result()) {\r\n <div id=\"preview\">\r\n <gve-snapshot-rendition #rendition class=\"rendition\">\r\n </gve-snapshot-rendition>\r\n </div>\r\n }\r\n\r\n <!--buttons -->\r\n <div class=\"form-row-center\">\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"close()\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n close\r\n </button>\r\n @if (!noSave()) {\r\n <button\r\n type=\"submit\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save changes\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon>check_circle</mat-icon>\r\n save\r\n </button>\r\n }\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row-center{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.form-row,.form-row-center *{flex:0 0 auto}.form-row .right{margin-left:auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.button-row *{flex:0 0 auto}.long-text{width:100%;max-width:800px}.margin-bottom{margin-bottom:8px}#text-range{margin:8px;border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:var(--mat-sys-on-surface-variant);margin:8px}#result{max-height:800px;overflow:auto}#snapshot-container{margin-top:6px}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.feat-editing{background-color:var(--mat-sys-tertiary-container);color:var(--mat-sys-on-tertiary-container)}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}fieldset{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}legend{color:var(--mat-sys-on-surface-variant)}.error{color:var(--mat-sys-error)}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}.boxed{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}span.label{margin-left:8px}.feature{color:var(--mat-sys-on-surface-variant)}.fname{font-size:.9em;color:var(--mat-sys-on-surface-variant)}.fvalue{font-size:.9em;color:var(--mat-sys-on-surface-variant);background-color:var(--mat-sys-surface-container);padding:2px 4px;border-radius:4px}gve-animation-timeline-set{margin:8px 0}div#image{display:grid;gap:8px;grid-template-rows:auto;grid-template-columns:1fr auto;grid-template-areas:\"image-ctl image-view\"}div#image-ctl{grid-area:image-ctl}div#image-view{grid-area:image-view}div#chain-view{margin-bottom:8px}#preview{margin:8px 0}.rendition{display:block;width:100%;min-height:600px;max-height:80vh;border:1px solid var(--mat-sys-on-surface-variant);overflow:auto}@media only screen and (max-width:959px){div#image{grid-template-columns:1fr;grid-template-areas:\"image-ctl\" \"image-view\"}}\n"] }]
3616
+ ], schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <mat-tab-group>\r\n <!-- text -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>article</mat-icon> <span class=\"label\">text</span>\r\n </ng-template>\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>\r\n <mat-panel-title> base text </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <!-- base text -->\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n color=\"mat-warn\"\r\n matTooltip=\"Enter base text\"\r\n (click)=\"inputBaseText()\"\r\n [disabled]=\"busy()\"\r\n >\r\n <mat-icon>edit</mat-icon> base text\r\n </button>\r\n\r\n @if (textRange()) {\r\n <span id=\"text-range\"\r\n >{{ textRange()!.at }}\u00D7{{ textRange()!.run }}</span\r\n >\r\n }\r\n </div>\r\n\r\n <!-- text characters -->\r\n <gve-base-text-view\r\n [text]=\"baseText.value\"\r\n [hasLineNumber]=\"true\"\r\n (rangePick)=\"onRangePick($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </mat-tab>\r\n\r\n <!-- operations -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>edit</mat-icon> <span class=\"label\">operations</span>\r\n </ng-template>\r\n\r\n <div id=\"snapshot-container\">\r\n <div id=\"general\">\r\n <div class=\"form-row\">\r\n <!-- feat details -->\r\n <mat-slide-toggle\r\n [formControl]=\"featDetails\"\r\n matTooltip=\"Toggle feature details\"\r\n >feat. details</mat-slide-toggle\r\n >\r\n <!-- auto run on edit -->\r\n <mat-slide-toggle\r\n [formControl]=\"autoRun\"\r\n matTooltip=\"Auto-run operations on edit\"\r\n >auto-run</mat-slide-toggle\r\n >\r\n\r\n <div class=\"form-row right\">\r\n <!-- copy ops DSL -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as DSL to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsDsl()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n\r\n <!-- copy ops JSON -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as JSON to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsJson()\"\r\n >\r\n <mat-icon>copy_all</mat-icon>\r\n </button>\r\n\r\n <!-- remove ops -->\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Remove all the operations\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"clearOperations()\"\r\n >\r\n <mat-icon>delete_forever</mat-icon> clear\r\n </button>\r\n\r\n <!-- batch add ops -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n matTooltip=\"Add a batch of operations\"\r\n class=\"mat-primary\"\r\n [disabled]=\"busy()\"\r\n (click)=\"parseOperations()\"\r\n >\r\n <mat-icon>post_add</mat-icon> batch\r\n </button>\r\n\r\n <!-- edit operations feats/sources -->\r\n <form\r\n (submit)=\"editOperationsFeats()\"\r\n [formGroup]=\"editFeatsForm\"\r\n >\r\n <mat-form-field>\r\n <mat-label>operations (e.g. 2, 5-7, 9)</mat-label>\r\n <input matInput [formControl]=\"editFeatsRange\" />\r\n @if (\r\n $any(editFeatsRange).errors?.required &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>range required</mat-error>\r\n }\r\n @if (\r\n $any(editFeatsRange).errors?.pattern &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>invalid range (use e.g. 2, 5-7, 9)</mat-error>\r\n }\r\n <button\r\n type=\"button\"\r\n matIconButton\r\n matSuffix\r\n matTooltip=\"Edit sources for range\"\r\n (click)=\"editOperationSources()\"\r\n >\r\n <mat-icon>people</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n matIconButton\r\n matSuffix\r\n matTooltip=\"Edit features for range\"\r\n >\r\n <mat-icon>edit_note</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </form>\r\n\r\n <!-- add op -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-primary\"\r\n [disabled]=\"busy() || !baseText.value\"\r\n (click)=\"editNewOperation()\"\r\n matTooltip=\"Add a new operation\"\r\n >\r\n <mat-icon>add_circle</mat-icon> operation\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- feature set editor -->\r\n @if (operationFeats() !== undefined) {\r\n <mat-expansion-panel #featsEditorPanel [expanded]=\"true\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Features of {{ batchRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-feature-set-editor\r\n [batchMode]=\"true\"\r\n [features]=\"operationFeats() || []\"\r\n [isVar]=\"true\"\r\n [featNames]=\"featureDefs()?.names\"\r\n [featValues]=\"featureDefs()?.values\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n (close)=\"closeOperationFeats()\"\r\n (featuresChange)=\"saveOperationsFeats($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation source editor -->\r\n @if (batchForSource() && batchOpNumbers()?.length) {\r\n <mat-expansion-panel #sourcesEditorPanel [expanded]=\"true\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Sources of {{ batchRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-operation-source-editor\r\n [ids]=\"sourceIds()\"\r\n [types]=\"sourceTypes()\"\r\n (sourceCancel)=\"closeOperationSources()\"\r\n (sourceChange)=\"saveOperationSources($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation editor -->\r\n @if (editedOp()) {\r\n <mat-expansion-panel\r\n #operationEditorPanel\r\n [expanded]=\"editedOp()\"\r\n [disabled]=\"!editedOp()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>operation {{ editedOp()?.id }}</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-chain-operation-editor\r\n [featureDefs]=\"featureDefs()\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n [hidePreview]=\"editedOpIndex() === -1\"\r\n [operation]=\"editedOp()\"\r\n [rangePatch]=\"editedOpRangePatch()\"\r\n [sourceIds]=\"sourceIds()\"\r\n [sourceTypes]=\"sourceTypes()\"\r\n (operationCancel)=\"onOperationCancel()\"\r\n (operationChange)=\"onOperationChange($event)\"\r\n (operationPreview)=\"onOperationPreview($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- ops -->\r\n <div\r\n id=\"ops\"\r\n [style.max-height]=\"opListMaxHeight()\"\r\n [style.overflow-y]=\"opListMaxHeight() ? 'auto' : null\"\r\n >\r\n <!-- operations list -->\r\n @if (operations.value.length) {\r\n <table id=\"list\">\r\n <thead>\r\n <tr>\r\n <th>nr.</th>\r\n <th></th>\r\n <th>ID</th>\r\n <th>type</th>\r\n <th>at</th>\r\n <th>run</th>\r\n <th>value</th>\r\n <th>itag</th>\r\n <th>otag</th>\r\n <th>gid</th>\r\n <th>feats</th>\r\n <th>src</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (\r\n operation of operations.value;\r\n track operation.id;\r\n let index = $index\r\n ) {\r\n <tr\r\n [class.selected]=\"operation.id === editedOp()?.id\"\r\n [class.feat-editing]=\"batchOpNumbers()?.includes(index + 1)\"\r\n >\r\n <td class=\"fit-width\">{{ index + 1 }}.</td>\r\n <td class=\"fit-width\">\r\n <!-- edit -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-primary\"\r\n (click)=\"editOperation(index)\"\r\n matTooltip=\"Edit operation\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <!-- delete -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-warn\"\r\n (click)=\"deleteOperation(index)\"\r\n matTooltip=\"Delete operation\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n <!-- run to -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-accent\"\r\n (click)=\"runTo(index)\"\r\n matTooltip=\"Run to this operation\"\r\n >\r\n <mat-icon class=\"mat-accent\">subscriptions</mat-icon>\r\n </button>\r\n <!-- duplicate -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"duplicateOperation(index)\"\r\n matTooltip=\"Duplicate operation\"\r\n >\r\n <mat-icon>control_point_duplicate</mat-icon>\r\n </button>\r\n <!-- move up -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationUp(index)\"\r\n matTooltip=\"Move operation up\"\r\n [disabled]=\"index === 0\"\r\n >\r\n <mat-icon>arrow_circle_up</mat-icon>\r\n </button>\r\n <!-- move down -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationDown(index)\"\r\n matTooltip=\"Move operation down\"\r\n [disabled]=\"index === operations.value.length - 1\"\r\n >\r\n <mat-icon>arrow_circle_down</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ operation.id }}</td>\r\n <td>{{ operation.type | flatLookup: opTypeMap }}</td>\r\n <td>{{ operation.at }}</td>\r\n <td>{{ operation.run }}</td>\r\n <td>{{ operation.value }}</td>\r\n <td>{{ operation.inputTag }}</td>\r\n <td>{{ operation.outputTag }}</td>\r\n <td>{{ operation.groupId }}</td>\r\n <td>\r\n @if (operation.features?.length) {\r\n @if (featDetails.value) {\r\n <div class=\"form-row\">\r\n @for (\r\n feat of operation.features;\r\n track $index;\r\n let i = $index\r\n ) {\r\n <div class=\"feature\">\r\n <span class=\"fname\">{{\r\n feat.name\r\n | flatLookup\r\n : featureDefs()?.names\r\n : \"id\"\r\n : \"label\"\r\n }}</span\r\n >=<span class=\"fvalue\">{{\r\n feat.value\r\n | flatLookup\r\n : featureDefs()?.values?.[feat.name]\r\n : \"id\"\r\n : \"label\"\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <!-- version badge -->\r\n @if (\r\n operation.features?.some(f => f.name === 'version')\r\n ) {\r\n <span\r\n matBadge=\"{{ operation.features?.find(f => f.name === 'version')?.value }}\"\r\n matBadgeOverlap=\"false\"\r\n >{{ operation.features?.length }}</span\r\n >\r\n }\r\n }\r\n }\r\n </td>\r\n <td>{{ operation.sources?.length || \"\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n </div>\r\n </div>\r\n </mat-tab>\r\n </mat-tab-group>\r\n\r\n <!-- progress -->\r\n <div class=\"margin-bottom\">\r\n @if (busy()) {\r\n <mat-progress-bar mode=\"indeterminate\" />\r\n }\r\n </div>\r\n\r\n <!-- result -->\r\n @if (result()) {\r\n <fieldset id=\"result\">\r\n <legend>result</legend>\r\n <gve-chain-result-view\r\n [result]=\"result()!\"\r\n [initialStepIndex]=\"initialStepIndex()\"\r\n [disabledRangePick]=\"editedOp() ? false : true\"\r\n (stepPick)=\"onStepPick($event)\"\r\n (rangePick)=\"onRangePick($event, true)\"\r\n />\r\n </fieldset>\r\n }\r\n\r\n <!-- snapshot view -->\r\n @if (result()) {\r\n <div id=\"preview\">\r\n <gve-snapshot-rendition #rendition class=\"rendition\">\r\n </gve-snapshot-rendition>\r\n </div>\r\n }\r\n\r\n <!--buttons -->\r\n <div class=\"form-row-center\">\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"close()\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n close\r\n </button>\r\n @if (!noSave()) {\r\n <button\r\n type=\"submit\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save changes\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon>check_circle</mat-icon>\r\n save\r\n </button>\r\n }\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row-center{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.form-row,.form-row-center *{flex:0 0 auto}.form-row .right{margin-left:auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.button-row *{flex:0 0 auto}.long-text{width:100%;max-width:800px}.margin-bottom{margin-bottom:8px}#text-range{margin:8px;border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:var(--mat-sys-on-surface-variant);margin:8px}#result{max-height:800px;overflow:auto}#snapshot-container{margin-top:6px}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.feat-editing{background-color:var(--mat-sys-tertiary-container);color:var(--mat-sys-on-tertiary-container)}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}fieldset{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}legend{color:var(--mat-sys-on-surface-variant)}.error{color:var(--mat-sys-error)}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}.boxed{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}span.label{margin-left:8px}.feature{color:var(--mat-sys-on-surface-variant)}.fname{font-size:.9em;color:var(--mat-sys-on-surface-variant)}.fvalue{font-size:.9em;color:var(--mat-sys-on-surface-variant);background-color:var(--mat-sys-surface-container);padding:2px 4px;border-radius:4px}gve-animation-timeline-set{margin:8px 0}div#image{display:grid;gap:8px;grid-template-rows:auto;grid-template-columns:1fr auto;grid-template-areas:\"image-ctl image-view\"}div#image-ctl{grid-area:image-ctl}div#image-view{grid-area:image-view}div#chain-view{margin-bottom:8px}#preview{margin:8px 0}.rendition{display:block;width:100%;min-height:600px;max-height:80vh;border:1px solid var(--mat-sys-on-surface-variant);overflow:auto}@media only screen and (max-width:959px){div#image{grid-template-columns:1fr;grid-template-areas:\"image-ctl\" \"image-view\"}}\n"] }]
3617
3617
  }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: GveApiService }, { type: i3$2.MatDialog }, { type: i4$1.DialogService }, { type: i2$3.MatSnackBar }], propDecorators: { renditionRef: [{ type: i0.ViewChild, args: ['rendition', { isSignal: true }] }], operationEditorPanelRef: [{ type: i0.ViewChild, args: ['operationEditorPanel', { isSignal: true }] }], snapshot: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapshot", required: false }] }, { type: i0.Output, args: ["snapshotChange"] }], batchOps: [{ type: i0.Input, args: [{ isSignal: true, alias: "batchOps", required: false }] }], noSave: [{ type: i0.Input, args: [{ isSignal: true, alias: "noSave", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], noDecoration: [{ type: i0.Input, args: [{ isSignal: true, alias: "noDecoration", required: false }] }], featureDefs: [{ type: i0.Input, args: [{ isSignal: true, alias: "featureDefs", required: false }] }], multiValuedFeatureIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiValuedFeatureIds", required: false }] }], sourceIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "sourceIds", required: false }] }], sourceTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "sourceTypes", required: false }] }], renditionSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "renditionSettings", required: false }] }], opListMaxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "opListMaxHeight", required: false }] }], snapshotCancel: [{ type: i0.Output, args: ["snapshotCancel"] }] } });
3618
3618
 
3619
3619
  class GveGraphvizService {