@wertzui/ngx-restworld-client 7.2.0 → 8.0.0
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/esm2020/lib/components/restworld-file/restworld-file.component.mjs +57 -0
- package/esm2020/lib/components/restworld-form/restworld-form.component.mjs +188 -0
- package/esm2020/lib/components/restworld-id-navigation/restworld-id-navigation.component.mjs +65 -0
- package/esm2020/lib/components/restworld-image/restworld-image.component.mjs +164 -0
- package/esm2020/lib/components/restworld-inputs/restworld-inputs.mjs +306 -0
- package/esm2020/lib/components/restworld-label/restworld-label.component.mjs +24 -0
- package/esm2020/lib/components/restworld-menu-button/restworld-menu-button.component.mjs +40 -0
- package/esm2020/lib/components/restworld-table/restworld-table.component.mjs +157 -0
- package/esm2020/lib/components/restworld-validation-errors/restworld-validation-errors.component.mjs +21 -0
- package/esm2020/lib/models/o-data.mjs +2 -0
- package/esm2020/lib/models/restworld-image.mjs +2 -0
- package/esm2020/lib/models/restworld-options.mjs +2 -2
- package/esm2020/lib/models/special-properties.mjs +6 -0
- package/esm2020/lib/models/templating.mjs +2 -0
- package/esm2020/lib/restworld-client.module.mjs +83 -25
- package/esm2020/lib/services/o-data.service.mjs +6 -3
- package/esm2020/lib/services/restworld-client-collection.mjs +7 -7
- package/esm2020/lib/services/restworld-client.mjs +40 -29
- package/esm2020/lib/services/settings.service.mjs +5 -5
- package/esm2020/lib/views/restworld-edit-view/restworld-edit-view.component.mjs +24 -255
- package/esm2020/lib/views/restworld-list-view/restworld-list-view.component.mjs +49 -101
- package/esm2020/public-api.mjs +17 -6
- package/fesm2015/wertzui-ngx-restworld-client.mjs +1373 -1017
- package/fesm2015/wertzui-ngx-restworld-client.mjs.map +1 -1
- package/fesm2020/wertzui-ngx-restworld-client.mjs +1322 -978
- package/fesm2020/wertzui-ngx-restworld-client.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/components/restworld-avatar/restworld-avatar.component.d.ts +1 -0
- package/lib/components/restworld-avatar/restworld-avatar.component.d.ts.map +1 -0
- package/lib/{views/restworld-file-view/restworld-file-view.component.d.ts → components/restworld-file/restworld-file.component.d.ts} +4 -3
- package/lib/components/restworld-file/restworld-file.component.d.ts.map +1 -0
- package/lib/components/restworld-form/restworld-form.component.d.ts +53 -0
- package/lib/components/restworld-form/restworld-form.component.d.ts.map +1 -0
- package/lib/components/restworld-id-navigation/restworld-id-navigation.component.d.ts +27 -0
- package/lib/components/restworld-id-navigation/restworld-id-navigation.component.d.ts.map +1 -0
- package/lib/components/restworld-image/restworld-image.component.d.ts +62 -0
- package/lib/components/restworld-image/restworld-image.component.d.ts.map +1 -0
- package/lib/components/restworld-inputs/restworld-inputs.d.ts +146 -0
- package/lib/components/restworld-inputs/restworld-inputs.d.ts.map +1 -0
- package/lib/components/restworld-label/restworld-label.component.d.ts +14 -0
- package/lib/components/restworld-label/restworld-label.component.d.ts.map +1 -0
- package/lib/components/restworld-menu-button/restworld-menu-button.component.d.ts +12 -0
- package/lib/components/restworld-menu-button/restworld-menu-button.component.d.ts.map +1 -0
- package/lib/components/restworld-table/restworld-table.component.d.ts +54 -0
- package/lib/components/restworld-table/restworld-table.component.d.ts.map +1 -0
- package/lib/components/restworld-validation-errors/restworld-validation-errors.component.d.ts +15 -0
- package/lib/components/restworld-validation-errors/restworld-validation-errors.component.d.ts.map +1 -0
- package/lib/constants/link-names.d.ts +1 -0
- package/lib/constants/link-names.d.ts.map +1 -0
- package/lib/models/api-url.d.ts +1 -0
- package/lib/models/api-url.d.ts.map +1 -0
- package/lib/models/client-settings.d.ts +1 -0
- package/lib/models/client-settings.d.ts.map +1 -0
- package/lib/models/o-data.d.ts +7 -0
- package/lib/models/o-data.d.ts.map +1 -0
- package/lib/models/problem-details.d.ts +1 -0
- package/lib/models/problem-details.d.ts.map +1 -0
- package/lib/models/restworld-image.d.ts +28 -0
- package/lib/models/restworld-image.d.ts.map +1 -0
- package/lib/models/restworld-options.d.ts +2 -1
- package/lib/models/restworld-options.d.ts.map +1 -0
- package/lib/models/special-properties.d.ts +9 -0
- package/lib/models/special-properties.d.ts.map +1 -0
- package/lib/models/templating.d.ts +8 -0
- package/lib/models/templating.d.ts.map +1 -0
- package/lib/pipes/as.pipe.d.ts +1 -0
- package/lib/pipes/as.pipe.d.ts.map +1 -0
- package/lib/pipes/safe-url.pipe.d.ts +1 -0
- package/lib/pipes/safe-url.pipe.d.ts.map +1 -0
- package/lib/restworld-client.module.d.ts +45 -37
- package/lib/restworld-client.module.d.ts.map +1 -0
- package/lib/services/avatar-generator.d.ts +1 -0
- package/lib/services/avatar-generator.d.ts.map +1 -0
- package/lib/services/form.service.d.ts +1 -0
- package/lib/services/form.service.d.ts.map +1 -0
- package/lib/services/o-data.service.d.ts +1 -0
- package/lib/services/o-data.service.d.ts.map +1 -0
- package/lib/services/restworld-client-collection.d.ts +9 -8
- package/lib/services/restworld-client-collection.d.ts.map +1 -0
- package/lib/services/restworld-client.d.ts +12 -4
- package/lib/services/restworld-client.d.ts.map +1 -0
- package/lib/services/settings.service.d.ts +3 -2
- package/lib/services/settings.service.d.ts.map +1 -0
- package/lib/views/restworld-edit-view/restworld-edit-view.component.d.ts +16 -68
- package/lib/views/restworld-edit-view/restworld-edit-view.component.d.ts.map +1 -0
- package/lib/views/restworld-list-view/restworld-list-view.component.d.ts +25 -41
- package/lib/views/restworld-list-view/restworld-list-view.component.d.ts.map +1 -0
- package/package.json +6 -6
- package/public-api.d.ts +17 -5
- package/public-api.d.ts.map +1 -0
- package/wertzui-ngx-restworld-client.d.ts.map +1 -0
- package/esm2020/lib/views/restworld-edit-form/restworld-edit-form.component.mjs +0 -233
- package/esm2020/lib/views/restworld-file-view/restworld-file-view.component.mjs +0 -57
- package/esm2020/lib/views/restworld-image-view/restworld-image-view.component.mjs +0 -139
- package/lib/views/restworld-edit-form/restworld-edit-form.component.d.ts +0 -74
- package/lib/views/restworld-image-view/restworld-image-view.component.d.ts +0 -57
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { Component, ContentChild, Input } from '@angular/core';
|
|
2
|
+
import { ControlContainer, FormGroupDirective } from '@angular/forms';
|
|
3
|
+
import { NumberTemplate, PropertyType } from '@wertzui/ngx-hal-client';
|
|
4
|
+
import { ProblemDetails } from '../../models/problem-details';
|
|
5
|
+
import { PropertyWithOptions, PropertyWithImage } from '../../models/special-properties';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "../restworld-label/restworld-label.component";
|
|
8
|
+
import * as i2 from "@angular/common";
|
|
9
|
+
import * as i3 from "../restworld-validation-errors/restworld-validation-errors.component";
|
|
10
|
+
import * as i4 from "../../pipes/as.pipe";
|
|
11
|
+
import * as i5 from "@angular/forms";
|
|
12
|
+
import * as i6 from "../../services/form.service";
|
|
13
|
+
import * as i7 from "primeng/button";
|
|
14
|
+
import * as i8 from "primeng/ripple";
|
|
15
|
+
import * as i9 from "@angular/cdk/drag-drop";
|
|
16
|
+
import * as i10 from "primeng/api";
|
|
17
|
+
import * as i11 from "../../services/restworld-client-collection";
|
|
18
|
+
import * as i12 from "primeng/tooltip";
|
|
19
|
+
import * as i13 from "primeng/dropdown";
|
|
20
|
+
import * as i14 from "primeng/multiselect";
|
|
21
|
+
import * as i15 from "primeng/inputtext";
|
|
22
|
+
import * as i16 from "primeng/inputnumber";
|
|
23
|
+
import * as i17 from "primeng/calendar";
|
|
24
|
+
import * as i18 from "primeng/checkbox";
|
|
25
|
+
import * as i19 from "primeng/tristatecheckbox";
|
|
26
|
+
import * as i20 from "../restworld-image/restworld-image.component";
|
|
27
|
+
import * as i21 from "../restworld-file/restworld-file.component";
|
|
28
|
+
/**
|
|
29
|
+
* A form element with a label that is automatically created from a property in a form template.
|
|
30
|
+
* This may also be a complex object or a collection in which case multiple and nested input elements may be rendered.
|
|
31
|
+
* If you want a form element without a label, use RestWorldFormInput <rw-form-input>.
|
|
32
|
+
*/
|
|
33
|
+
export class RestWorldFormElementComponent {
|
|
34
|
+
}
|
|
35
|
+
RestWorldFormElementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldFormElementComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
36
|
+
RestWorldFormElementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.3", type: RestWorldFormElementComponent, selector: "rw-form-element", inputs: { property: "property", apiName: "apiName" }, ngImport: i0, template: "<div class=\"grid field\">\r\n <rw-label [property]=\"property\" class=\"col-12 md:col-2 flex align-items-center\"></rw-label>\r\n <rw-input [apiName]=\"apiName\" [property]=\"property\" class=\"col-12 md:col-10\"></rw-input>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "component", type: i0.forwardRef(function () { return RestWorldInputComponent; }), selector: "rw-input", inputs: ["property", "apiName"] }, { kind: "component", type: i0.forwardRef(function () { return i1.RestWorldLabelComponent; }), selector: "rw-label", inputs: ["property"] }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
|
|
37
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldFormElementComponent, decorators: [{
|
|
38
|
+
type: Component,
|
|
39
|
+
args: [{ selector: 'rw-form-element', viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: "<div class=\"grid field\">\r\n <rw-label [property]=\"property\" class=\"col-12 md:col-2 flex align-items-center\"></rw-label>\r\n <rw-input [apiName]=\"apiName\" [property]=\"property\" class=\"col-12 md:col-10\"></rw-input>\r\n</div>\r\n" }]
|
|
40
|
+
}], propDecorators: { property: [{
|
|
41
|
+
type: Input
|
|
42
|
+
}], apiName: [{
|
|
43
|
+
type: Input
|
|
44
|
+
}] } });
|
|
45
|
+
/**
|
|
46
|
+
* A form input element that is automatically created from a property in a form template.
|
|
47
|
+
* This may also be a complex object or a collection in which case multiple and nested input elements may be rendered.
|
|
48
|
+
* If you also want a label, use RestWorldFormElement <rw-form-element>.
|
|
49
|
+
* You can also use one of the different RestWorldInput... <rw-input-...> elements to render a specific input,
|
|
50
|
+
* but it is advised to control the rendered input through the passed in property.
|
|
51
|
+
*/
|
|
52
|
+
export class RestWorldInputComponent {
|
|
53
|
+
get PropertyType() {
|
|
54
|
+
return PropertyType;
|
|
55
|
+
}
|
|
56
|
+
get PropertyWithOptions() {
|
|
57
|
+
return PropertyWithOptions;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
RestWorldInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
61
|
+
RestWorldInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.3", type: RestWorldInputComponent, selector: "rw-input", inputs: { property: "property", apiName: "apiName" }, ngImport: i0, template: "<rw-input-dropdown *ngIf=\"property.options\" [apiName]=\"apiName\" [property]=\"property | as:PropertyWithOptions\"></rw-input-dropdown>\r\n\r\n<ng-container *ngIf=\"!property.options\">\r\n <ng-container [ngSwitch]=\"property.type\">\r\n <rw-input-object *ngSwitchCase=\"PropertyType.Object\" [apiName]=\"apiName\" [property]=\"property\"></rw-input-object>\r\n <rw-input-collection *ngSwitchCase=\"PropertyType.Collection\" [apiName]=\"apiName\" [property]=\"property\"></rw-input-collection>\r\n <rw-input-simple *ngSwitchDefault [property]=\"property\"></rw-input-simple>\r\n </ng-container>\r\n</ng-container>\r\n\r\n<rw-validation-errors [property]=\"property\"></rw-validation-errors>", styles: [""], dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i2.NgIf; }), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.NgSwitch; }), selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.NgSwitchCase; }), selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.NgSwitchDefault; }), selector: "[ngSwitchDefault]" }, { kind: "component", type: i0.forwardRef(function () { return RestWorldInputDropdownComponent; }), selector: "rw-input-dropdown", inputs: ["property", "apiName"] }, { kind: "component", type: i0.forwardRef(function () { return RestWorldInputCollectionComponent; }), selector: "rw-input-collection", inputs: ["property", "apiName"] }, { kind: "component", type: i0.forwardRef(function () { return RestWorldInputObjectComponent; }), selector: "rw-input-object", inputs: ["property", "apiName"] }, { kind: "component", type: i0.forwardRef(function () { return RestWorldInputSimpleComponent; }), selector: "rw-input-simple", inputs: ["property"] }, { kind: "component", type: i0.forwardRef(function () { return i3.RestWorldValidationErrorsComponent; }), selector: "rw-validation-errors", inputs: ["property", "form"] }, { kind: "pipe", type: i0.forwardRef(function () { return i4.AsPipe; }), name: "as" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
|
|
62
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputComponent, decorators: [{
|
|
63
|
+
type: Component,
|
|
64
|
+
args: [{ selector: 'rw-input', viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: "<rw-input-dropdown *ngIf=\"property.options\" [apiName]=\"apiName\" [property]=\"property | as:PropertyWithOptions\"></rw-input-dropdown>\r\n\r\n<ng-container *ngIf=\"!property.options\">\r\n <ng-container [ngSwitch]=\"property.type\">\r\n <rw-input-object *ngSwitchCase=\"PropertyType.Object\" [apiName]=\"apiName\" [property]=\"property\"></rw-input-object>\r\n <rw-input-collection *ngSwitchCase=\"PropertyType.Collection\" [apiName]=\"apiName\" [property]=\"property\"></rw-input-collection>\r\n <rw-input-simple *ngSwitchDefault [property]=\"property\"></rw-input-simple>\r\n </ng-container>\r\n</ng-container>\r\n\r\n<rw-validation-errors [property]=\"property\"></rw-validation-errors>" }]
|
|
65
|
+
}], propDecorators: { property: [{
|
|
66
|
+
type: Input
|
|
67
|
+
}], apiName: [{
|
|
68
|
+
type: Input
|
|
69
|
+
}] } });
|
|
70
|
+
/**
|
|
71
|
+
* A collection that is automatically created from the given property.
|
|
72
|
+
* The collection supports drag & drop to re order the elements and can also be nested.
|
|
73
|
+
* It is advised to use RestWorldInputComponent <rw-input> and control the rendered inputs with the passed in property
|
|
74
|
+
* instead of using this component directly.
|
|
75
|
+
*/
|
|
76
|
+
export class RestWorldInputCollectionComponent {
|
|
77
|
+
constructor(_controlContainer, _formService, _changeDetectorRef) {
|
|
78
|
+
this._controlContainer = _controlContainer;
|
|
79
|
+
this._formService = _formService;
|
|
80
|
+
this._changeDetectorRef = _changeDetectorRef;
|
|
81
|
+
this._templates = [];
|
|
82
|
+
}
|
|
83
|
+
get templates() {
|
|
84
|
+
return this._templates;
|
|
85
|
+
}
|
|
86
|
+
get defaultTemplate() {
|
|
87
|
+
if (this._defaultTemplate === undefined)
|
|
88
|
+
throw new Error("No default template found.");
|
|
89
|
+
return this._defaultTemplate;
|
|
90
|
+
}
|
|
91
|
+
get innerFormArray() {
|
|
92
|
+
if (this._innerFormArray === undefined)
|
|
93
|
+
throw new Error("formGroup is not set.");
|
|
94
|
+
return this._innerFormArray;
|
|
95
|
+
}
|
|
96
|
+
ngOnInit() {
|
|
97
|
+
const formGroup = this._controlContainer.control;
|
|
98
|
+
this._innerFormArray = formGroup.controls[this.property.name];
|
|
99
|
+
this._templates = RestWorldInputCollectionComponent.getCollectionEntryTemplates(this.property);
|
|
100
|
+
this._defaultTemplate = this.property._templates.default;
|
|
101
|
+
}
|
|
102
|
+
static getCollectionEntryTemplates(property) {
|
|
103
|
+
if (!property)
|
|
104
|
+
return [];
|
|
105
|
+
return Object.entries(property._templates)
|
|
106
|
+
.filter(([key, value]) => Number.isInteger(Number.parseInt(key)) && Number.isInteger(Number.parseInt(value.title ?? "")))
|
|
107
|
+
.map(([, value]) => new NumberTemplate(value));
|
|
108
|
+
}
|
|
109
|
+
addNewItemToCollection() {
|
|
110
|
+
const maxIndex = Math.max(...Object.keys(this.templates)
|
|
111
|
+
.map(key => Number.parseInt(key))
|
|
112
|
+
.filter(key => Number.isSafeInteger(key)));
|
|
113
|
+
const nextIndex = maxIndex < 0 ? 0 : maxIndex + 1;
|
|
114
|
+
const copiedTemplateDto = JSON.parse(JSON.stringify(this.defaultTemplate));
|
|
115
|
+
const copiedTemplate = new NumberTemplate(copiedTemplateDto);
|
|
116
|
+
copiedTemplate.title = nextIndex;
|
|
117
|
+
this.templates[copiedTemplate.title] = copiedTemplate;
|
|
118
|
+
this.innerFormArray.push(this._formService.createFormGroupFromTemplate(this.defaultTemplate));
|
|
119
|
+
}
|
|
120
|
+
deleteItemFromCollection(template) {
|
|
121
|
+
delete this.templates[template.title];
|
|
122
|
+
this.innerFormArray.removeAt(template.title);
|
|
123
|
+
}
|
|
124
|
+
collectionItemDropped($event) {
|
|
125
|
+
const previousIndex = $event.previousIndex;
|
|
126
|
+
const currentIndex = $event.currentIndex;
|
|
127
|
+
const movementDirection = currentIndex > previousIndex ? 1 : -1;
|
|
128
|
+
// Move in FormArray
|
|
129
|
+
// We do not need to move the item in the _templates object
|
|
130
|
+
const movedControl = this.innerFormArray.at(previousIndex);
|
|
131
|
+
for (let i = previousIndex; i * movementDirection < currentIndex * movementDirection; i = i + movementDirection) {
|
|
132
|
+
this.innerFormArray.setControl(i, this.innerFormArray.at(i + movementDirection));
|
|
133
|
+
}
|
|
134
|
+
this.innerFormArray.setControl(currentIndex, movedControl);
|
|
135
|
+
this._changeDetectorRef.markForCheck();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
RestWorldInputCollectionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputCollectionComponent, deps: [{ token: i5.ControlContainer }, { token: i6.FormService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
139
|
+
RestWorldInputCollectionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.3", type: RestWorldInputCollectionComponent, selector: "rw-input-collection", inputs: { property: "property", apiName: "apiName" }, queries: [{ propertyName: "inputCollectionRef", first: true, predicate: ["inputCollection"], descendants: true }], ngImport: i0, template: "<div class=\"flex align-items-center\">\n <div class=\"brace\">\n </div>\n <div class=\"w-full\" cdkDropList (cdkDropListDropped)=\"collectionItemDropped($event)\">\n <div *ngFor=\"let template of templates\" class=\"flex align-items-center\" cdkDrag>\n <i class=\"fas fa-grip-lines\" cdkDragHandle></i>\n <div class=\"brace\">\n </div>\n <div class=\"w-full flex justify-content-end\">\n <rw-input-template [formGroup]=\"innerFormArray.controls[template.title]\" [template]=\"defaultTemplate\" [apiName]=\"apiName\" class=\"w-full\"></rw-input-template>\n <button pButton pRipple type=\"button\" icon=\"fas fa-trash\" class=\"p-button-outlined p-button-danger ml-2 mb-3\" (click)=\"deleteItemFromCollection(template)\"></button>\n </div>\n </div>\n <div class=\"flex justify-content-end w-full\">\n <button pButton pRipple type=\"button\" icon=\"fas fa-plus\" class=\"p-button-outlined p-button-info\" (click)=\"addNewItemToCollection()\"></button>\n </div>\n </div>\n</div>", styles: [".cdk-drag-handle{cursor:move}.cdk-drag-preview{background-color:#ffffffd0;border:2px dashed rgb(206,212,218);cursor:move}.cdk-drag-placeholder{border:2px dashed rgb(206,212,218);margin:-2px}.brace{align-self:stretch;margin:.2rem .5rem;border-left:1px solid rgb(206,212,218);border-top:1px solid rgb(206,212,218);border-bottom:1px solid rgb(206,212,218);width:1rem}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i2.NgForOf; }), selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i0.forwardRef(function () { return i5.NgControlStatusGroup; }), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i0.forwardRef(function () { return i5.FormGroupDirective; }), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(function () { return i7.ButtonDirective; }), selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { kind: "directive", type: i0.forwardRef(function () { return i8.Ripple; }), selector: "[pRipple]" }, { kind: "directive", type: i0.forwardRef(function () { return i9.CdkDropList; }), selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i0.forwardRef(function () { return i9.CdkDrag; }), selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i0.forwardRef(function () { return i9.CdkDragHandle; }), selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: i0.forwardRef(function () { return RestWorldInputTemplateComponent; }), selector: "rw-input-template", inputs: ["apiName", "template"] }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
|
|
140
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputCollectionComponent, decorators: [{
|
|
141
|
+
type: Component,
|
|
142
|
+
args: [{ selector: 'rw-input-collection', viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: "<div class=\"flex align-items-center\">\n <div class=\"brace\">\n </div>\n <div class=\"w-full\" cdkDropList (cdkDropListDropped)=\"collectionItemDropped($event)\">\n <div *ngFor=\"let template of templates\" class=\"flex align-items-center\" cdkDrag>\n <i class=\"fas fa-grip-lines\" cdkDragHandle></i>\n <div class=\"brace\">\n </div>\n <div class=\"w-full flex justify-content-end\">\n <rw-input-template [formGroup]=\"innerFormArray.controls[template.title]\" [template]=\"defaultTemplate\" [apiName]=\"apiName\" class=\"w-full\"></rw-input-template>\n <button pButton pRipple type=\"button\" icon=\"fas fa-trash\" class=\"p-button-outlined p-button-danger ml-2 mb-3\" (click)=\"deleteItemFromCollection(template)\"></button>\n </div>\n </div>\n <div class=\"flex justify-content-end w-full\">\n <button pButton pRipple type=\"button\" icon=\"fas fa-plus\" class=\"p-button-outlined p-button-info\" (click)=\"addNewItemToCollection()\"></button>\n </div>\n </div>\n</div>", styles: [".cdk-drag-handle{cursor:move}.cdk-drag-preview{background-color:#ffffffd0;border:2px dashed rgb(206,212,218);cursor:move}.cdk-drag-placeholder{border:2px dashed rgb(206,212,218);margin:-2px}.brace{align-self:stretch;margin:.2rem .5rem;border-left:1px solid rgb(206,212,218);border-top:1px solid rgb(206,212,218);border-bottom:1px solid rgb(206,212,218);width:1rem}\n"] }]
|
|
143
|
+
}], ctorParameters: function () { return [{ type: i5.ControlContainer }, { type: i6.FormService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { property: [{
|
|
144
|
+
type: Input
|
|
145
|
+
}], apiName: [{
|
|
146
|
+
type: Input
|
|
147
|
+
}], inputCollectionRef: [{
|
|
148
|
+
type: ContentChild,
|
|
149
|
+
args: ['inputCollection', { static: false }]
|
|
150
|
+
}] } });
|
|
151
|
+
/**
|
|
152
|
+
* A dropdown that is automatically created from the given property.
|
|
153
|
+
* The dropdown supports searching through a RESTWorld list endpoint on the backend.
|
|
154
|
+
* It is advised to use RestWorldInputComponent <rw-input> and control the rendered inputs with the passed in property
|
|
155
|
+
* instead of using this component directly.
|
|
156
|
+
*/
|
|
157
|
+
export class RestWorldInputDropdownComponent {
|
|
158
|
+
constructor(_messageService, _clients) {
|
|
159
|
+
this._messageService = _messageService;
|
|
160
|
+
this._clients = _clients;
|
|
161
|
+
}
|
|
162
|
+
getDropdownElementTooltip(resource, keysToExclude) {
|
|
163
|
+
const tooltip = Object.entries(resource)
|
|
164
|
+
.filter(([key]) => !(key.startsWith('_') || ['createdAt', 'createdBy', 'lastChangedAt', 'lastChangedBy', 'timestamp'].includes(key) || keysToExclude?.includes(key)))
|
|
165
|
+
.reduce((prev, [key, value], index) => `${prev}${index === 0 ? '' : '\n'}${key}: ${RestWorldInputDropdownComponent.jsonStringifyWithElipsis(value)}`, '');
|
|
166
|
+
return tooltip;
|
|
167
|
+
}
|
|
168
|
+
async onOptionsFiltered(property, event) {
|
|
169
|
+
const options = property?.options;
|
|
170
|
+
if (!options?.link?.href || !event.filter || event.filter === '')
|
|
171
|
+
return;
|
|
172
|
+
const templatedUri = options.link.href;
|
|
173
|
+
let filter = `contains(${options.promptField}, '${event.filter}')`;
|
|
174
|
+
if (options.valueField?.toLowerCase() === 'id' && !Number.isNaN(Number.parseInt(event.filter)))
|
|
175
|
+
filter = `(${options.valueField} eq ${event.filter}) or (${filter})`;
|
|
176
|
+
const response = await this.getClient().getListByUri(templatedUri, { $filter: filter, $top: 10 });
|
|
177
|
+
if (!response.ok || ProblemDetails.isProblemDetails(response.body) || !response.body) {
|
|
178
|
+
const message = `An error occurred while getting the filtered items.`;
|
|
179
|
+
this._messageService.add({ severity: 'error', summary: 'Error', detail: message, data: response, sticky: true });
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const items = response.body._embedded.items;
|
|
183
|
+
options.inline = items;
|
|
184
|
+
}
|
|
185
|
+
getClient() {
|
|
186
|
+
if (!this.apiName)
|
|
187
|
+
throw new Error('Cannot get a client, because the apiName is not set.');
|
|
188
|
+
return this._clients.getClient(this.apiName);
|
|
189
|
+
}
|
|
190
|
+
static jsonStringifyWithElipsis(value) {
|
|
191
|
+
const maxLength = 200;
|
|
192
|
+
const end = 10;
|
|
193
|
+
const start = maxLength - end - 2;
|
|
194
|
+
const json = JSON.stringify(value);
|
|
195
|
+
const shortened = json.length > maxLength ? json.substring(0, start) + '…' + json.substring(json.length - end) : json;
|
|
196
|
+
return shortened;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
RestWorldInputDropdownComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputDropdownComponent, deps: [{ token: i10.MessageService }, { token: i11.RestWorldClientCollection }], target: i0.ɵɵFactoryTarget.Component });
|
|
200
|
+
RestWorldInputDropdownComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.3", type: RestWorldInputDropdownComponent, selector: "rw-input-dropdown", inputs: { property: "property", apiName: "apiName" }, queries: [{ propertyName: "inputOptionsSingleRef", first: true, predicate: ["inputOptionsSingle"], descendants: true }, { propertyName: "inputOptionsMultipleRef", first: true, predicate: ["inputOptionsMultiple"], descendants: true }], ngImport: i0, template: "<ng-template #defaultInputOptionsSingle let-property=\"property\" let-template=\"template\">\n <p-dropdown \n [formControlName]=\"property.name\" \n [id]=\"property.name\" \n [options]=\"property.options.inline\" \n [filterBy]=\"(property.options.promptField ?? 'prompt') + ',' + (property.options.valueField ?? 'value')\" \n [optionValue]=\"property.options.valueField ?? 'value'\" \n [readonly]=\"property.readOnly\" \n [required]=\"property.required || property.options.minItems > 0\" \n [filter]=\"true\" \n [autoDisplayFirst]=\"false\" \n [showClear]=\"!property.required || property.options.minItems <= 0\" \n (onFilter)=\"onOptionsFiltered(property, $event)\" \n styleClass=\"w-full\" \n [filterPlaceholder]=\"property?.options?.link?.href ? 'search for more results' : ''\">\n <ng-template let-item pTemplate=\"selectedItem\">\n <span [pTooltip]=\"getDropdownElementTooltip(item, [property.options.promptField ?? 'prompt', property.options.valueField ?? 'value'])\">{{item[property.options.promptField ?? 'prompt']}} ({{item[property.options.valueField ?? 'value']}})</span>\n </ng-template>\n <ng-template let-item pTemplate=\"item\">\n <span [pTooltip]=\"getDropdownElementTooltip(item, [property.options.promptField ?? 'prompt', property.options.valueField ?? 'value'])\">{{item[property.options.promptField ?? 'prompt']}} ({{item[property.options.valueField ?? 'value']}})</span>\n </ng-template>\n </p-dropdown>\n</ng-template>\n<ng-container *ngIf=\"!property.options.maxItems || property.options.maxItems == 1\">\n <ng-container *ngTemplateOutlet=\"inputOptionsSingleRef ?? defaultInputOptionsSingle; context: { property: property, apiName: apiName }\"></ng-container>\n</ng-container>\n\n<ng-template #defaultInputOptionsMultiple let-property=\"property\" let-template=\"template\">\n <p-multiSelect \n [formControlName]=\"property.name\" \n [id]=\"property.name\" \n [options]=\"property.options.inline\" \n [optionLabel]=\"property.options.promptField ?? 'prompt'\" \n [optionValue]=\"property.options.valueField ?? 'value'\" \n [readonly]=\"property.readOnly\" \n [selectionLimit]=\"property.options.maxItems\" \n [required]=\"property.required || property.options.minItems > 0\"></p-multiSelect>\n</ng-template>\n<ng-container *ngIf=\"(property.options.maxItems ?? 0) > 1\">\n <ng-container *ngTemplateOutlet=\"inputOptionsMultipleRef ?? defaultInputOptionsMultiple; context: { property: property, apiName: apiName }\"></ng-container>\n</ng-container>", styles: [""], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i10.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i12.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "fitContent", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: i13.Dropdown, selector: "p-dropdown", inputs: ["scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "filterPlaceholder", "filterLocale", "inputId", "selectId", "dataKey", "filterBy", "autofocus", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "overlayDirection", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "options", "filterValue"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i14.MultiSelect, selector: "p-multiSelect", inputs: ["style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "appendTo", "dataKey", "name", "label", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad"] }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
|
|
201
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputDropdownComponent, decorators: [{
|
|
202
|
+
type: Component,
|
|
203
|
+
args: [{ selector: 'rw-input-dropdown', viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: "<ng-template #defaultInputOptionsSingle let-property=\"property\" let-template=\"template\">\n <p-dropdown \n [formControlName]=\"property.name\" \n [id]=\"property.name\" \n [options]=\"property.options.inline\" \n [filterBy]=\"(property.options.promptField ?? 'prompt') + ',' + (property.options.valueField ?? 'value')\" \n [optionValue]=\"property.options.valueField ?? 'value'\" \n [readonly]=\"property.readOnly\" \n [required]=\"property.required || property.options.minItems > 0\" \n [filter]=\"true\" \n [autoDisplayFirst]=\"false\" \n [showClear]=\"!property.required || property.options.minItems <= 0\" \n (onFilter)=\"onOptionsFiltered(property, $event)\" \n styleClass=\"w-full\" \n [filterPlaceholder]=\"property?.options?.link?.href ? 'search for more results' : ''\">\n <ng-template let-item pTemplate=\"selectedItem\">\n <span [pTooltip]=\"getDropdownElementTooltip(item, [property.options.promptField ?? 'prompt', property.options.valueField ?? 'value'])\">{{item[property.options.promptField ?? 'prompt']}} ({{item[property.options.valueField ?? 'value']}})</span>\n </ng-template>\n <ng-template let-item pTemplate=\"item\">\n <span [pTooltip]=\"getDropdownElementTooltip(item, [property.options.promptField ?? 'prompt', property.options.valueField ?? 'value'])\">{{item[property.options.promptField ?? 'prompt']}} ({{item[property.options.valueField ?? 'value']}})</span>\n </ng-template>\n </p-dropdown>\n</ng-template>\n<ng-container *ngIf=\"!property.options.maxItems || property.options.maxItems == 1\">\n <ng-container *ngTemplateOutlet=\"inputOptionsSingleRef ?? defaultInputOptionsSingle; context: { property: property, apiName: apiName }\"></ng-container>\n</ng-container>\n\n<ng-template #defaultInputOptionsMultiple let-property=\"property\" let-template=\"template\">\n <p-multiSelect \n [formControlName]=\"property.name\" \n [id]=\"property.name\" \n [options]=\"property.options.inline\" \n [optionLabel]=\"property.options.promptField ?? 'prompt'\" \n [optionValue]=\"property.options.valueField ?? 'value'\" \n [readonly]=\"property.readOnly\" \n [selectionLimit]=\"property.options.maxItems\" \n [required]=\"property.required || property.options.minItems > 0\"></p-multiSelect>\n</ng-template>\n<ng-container *ngIf=\"(property.options.maxItems ?? 0) > 1\">\n <ng-container *ngTemplateOutlet=\"inputOptionsMultipleRef ?? defaultInputOptionsMultiple; context: { property: property, apiName: apiName }\"></ng-container>\n</ng-container>" }]
|
|
204
|
+
}], ctorParameters: function () { return [{ type: i10.MessageService }, { type: i11.RestWorldClientCollection }]; }, propDecorators: { property: [{
|
|
205
|
+
type: Input
|
|
206
|
+
}], apiName: [{
|
|
207
|
+
type: Input
|
|
208
|
+
}], inputOptionsSingleRef: [{
|
|
209
|
+
type: ContentChild,
|
|
210
|
+
args: ['inputOptionsSingle', { static: false }]
|
|
211
|
+
}], inputOptionsMultipleRef: [{
|
|
212
|
+
type: ContentChild,
|
|
213
|
+
args: ['inputOptionsMultiple', { static: false }]
|
|
214
|
+
}] } });
|
|
215
|
+
/**
|
|
216
|
+
* A complex object with multiple properties that is automatically created from the given property.
|
|
217
|
+
* The object can also be nested.
|
|
218
|
+
* It is advised to use RestWorldInputComponent <rw-input> and control the rendered inputs with the passed in property
|
|
219
|
+
* instead of using this component directly.
|
|
220
|
+
*/
|
|
221
|
+
export class RestWorldInputObjectComponent {
|
|
222
|
+
constructor(_controlContainer) {
|
|
223
|
+
this._controlContainer = _controlContainer;
|
|
224
|
+
}
|
|
225
|
+
get innerFormGroup() {
|
|
226
|
+
if (this._innerFormGroup === undefined)
|
|
227
|
+
throw new Error("formGroup is not set.");
|
|
228
|
+
return this._innerFormGroup;
|
|
229
|
+
}
|
|
230
|
+
ngOnInit() {
|
|
231
|
+
const formGroup = this._controlContainer.control;
|
|
232
|
+
this._innerFormGroup = formGroup.controls[this.property.name];
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
RestWorldInputObjectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputObjectComponent, deps: [{ token: i5.ControlContainer }], target: i0.ɵɵFactoryTarget.Component });
|
|
236
|
+
RestWorldInputObjectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.3", type: RestWorldInputObjectComponent, selector: "rw-input-object", inputs: { property: "property", apiName: "apiName" }, queries: [{ propertyName: "inputObjectRef", first: true, predicate: ["inputObject"], descendants: true }], ngImport: i0, template: "<ng-template #defaultInputObject let-property=\"property\" let-template=\"template\">\n <div class=\"flex align-items-center\">\n <div class=\"brace\">\n </div>\n <div class=\"w-full\">\n <rw-input-template [formGroup]=\"innerFormGroup\" [template]=\"property._templates.default\" [apiName]=\"apiName\"></rw-input-template>\n </div>\n </div>\n</ng-template>\n<ng-container>\n <ng-container *ngTemplateOutlet=\"inputObjectRef || defaultInputObject; context: { property: property, innerFormGroup: innerFormGroup, apiName: apiName }\"></ng-container>\n</ng-container>", styles: [".brace{align-self:stretch;margin:.2rem .5rem;border-left:1px solid rgb(206,212,218);border-top:1px solid rgb(206,212,218);border-bottom:1px solid rgb(206,212,218);width:1rem}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i2.NgTemplateOutlet; }), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(function () { return i5.NgControlStatusGroup; }), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i0.forwardRef(function () { return i5.FormGroupDirective; }), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i0.forwardRef(function () { return RestWorldInputTemplateComponent; }), selector: "rw-input-template", inputs: ["apiName", "template"] }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
|
|
237
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputObjectComponent, decorators: [{
|
|
238
|
+
type: Component,
|
|
239
|
+
args: [{ selector: 'rw-input-object', viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: "<ng-template #defaultInputObject let-property=\"property\" let-template=\"template\">\n <div class=\"flex align-items-center\">\n <div class=\"brace\">\n </div>\n <div class=\"w-full\">\n <rw-input-template [formGroup]=\"innerFormGroup\" [template]=\"property._templates.default\" [apiName]=\"apiName\"></rw-input-template>\n </div>\n </div>\n</ng-template>\n<ng-container>\n <ng-container *ngTemplateOutlet=\"inputObjectRef || defaultInputObject; context: { property: property, innerFormGroup: innerFormGroup, apiName: apiName }\"></ng-container>\n</ng-container>", styles: [".brace{align-self:stretch;margin:.2rem .5rem;border-left:1px solid rgb(206,212,218);border-top:1px solid rgb(206,212,218);border-bottom:1px solid rgb(206,212,218);width:1rem}\n"] }]
|
|
240
|
+
}], ctorParameters: function () { return [{ type: i5.ControlContainer }]; }, propDecorators: { property: [{
|
|
241
|
+
type: Input
|
|
242
|
+
}], apiName: [{
|
|
243
|
+
type: Input
|
|
244
|
+
}], inputObjectRef: [{
|
|
245
|
+
type: ContentChild,
|
|
246
|
+
args: ['inputObject', { static: false }]
|
|
247
|
+
}] } });
|
|
248
|
+
/**
|
|
249
|
+
* A simple input element, like a text, or a number that is automatically created from the given property.
|
|
250
|
+
* It is advised to use RestWorldInputComponent <rw-input> and control the rendered inputs with the passed in property
|
|
251
|
+
* instead of using this component directly.
|
|
252
|
+
*/
|
|
253
|
+
export class RestWorldInputSimpleComponent {
|
|
254
|
+
constructor(_controlContainer) {
|
|
255
|
+
this._controlContainer = _controlContainer;
|
|
256
|
+
}
|
|
257
|
+
get PropertyType() {
|
|
258
|
+
return PropertyType;
|
|
259
|
+
}
|
|
260
|
+
get dateFormat() {
|
|
261
|
+
return new Date(3333, 11, 22)
|
|
262
|
+
.toLocaleDateString()
|
|
263
|
+
.replace("22", "dd")
|
|
264
|
+
.replace("11", "mm")
|
|
265
|
+
.replace("3333", "yy")
|
|
266
|
+
.replace("33", "y");
|
|
267
|
+
}
|
|
268
|
+
get formControl() {
|
|
269
|
+
if (this._formControl === undefined)
|
|
270
|
+
throw new Error("formGroup is not set.");
|
|
271
|
+
return this._formControl;
|
|
272
|
+
}
|
|
273
|
+
get PropertyWithImage() {
|
|
274
|
+
return PropertyWithImage;
|
|
275
|
+
}
|
|
276
|
+
ngOnInit() {
|
|
277
|
+
const formGroup = this._controlContainer.control;
|
|
278
|
+
this._formControl = formGroup.controls[this.property.name];
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
RestWorldInputSimpleComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputSimpleComponent, deps: [{ token: i5.ControlContainer }], target: i0.ɵɵFactoryTarget.Component });
|
|
282
|
+
RestWorldInputSimpleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.3", type: RestWorldInputSimpleComponent, selector: "rw-input-simple", inputs: { property: "property" }, ngImport: i0, template: "<div [ngSwitch]=\"property.type\">\n\n <input *ngSwitchCase=\"PropertyType.Hidden\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"hidden\" [value]=\"property.value\" />\n \n <input *ngSwitchCase=\"PropertyType.Text\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"text\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <textarea *ngSwitchCase=\"PropertyType.Textarea\" [formControlName]=\"property.name\" [id]=\"property.name\" pInputTextarea class=\"w-full p-inputtextarea p-inputtext p-component p-element\" [class.p-disabled]=\"property.readOnly\" [cols]=\"property.cols\" [rows]=\"property.rows\"></textarea>\n \n <input *ngSwitchCase=\"PropertyType.Search\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"search\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <input *ngSwitchCase=\"PropertyType.Tel\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"tel\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <input *ngSwitchCase=\"PropertyType.Url\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"url\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <input *ngSwitchCase=\"PropertyType.Email\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"email\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <input *ngSwitchCase=\"PropertyType.Password\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"password\" pPassword class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <p-calendar *ngSwitchCase=\"PropertyType.Date\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showWeek]=\"true\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n \n <p-calendar *ngSwitchCase=\"PropertyType.Month\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showWeek]=\"false\" view=\"month\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n \n <input *ngSwitchCase=\"PropertyType.Week\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"week\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <p-calendar *ngSwitchCase=\"PropertyType.Time\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [timeOnly]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n \n <p-calendar *ngSwitchCase=\"PropertyType.DatetimeLocal\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n \n <p-inputNumber *ngSwitchCase=\"PropertyType.Number\" [formControlName]=\"property.name\" [id]=\"property.name\" mode=\"decimal\" [showButtons]=\"!property.readOnly\" class=\"w-full\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-inputNumber>\n \n <input *ngSwitchCase=\"PropertyType.Range\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"range\" [min]=\"property.min\" [max]=\"property.max\" [step]=\"property.step\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <input *ngSwitchCase=\"PropertyType.Color\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"color\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <ng-container *ngSwitchCase=\"PropertyType.Bool\">\n <p-checkbox *ngIf=\"property.required\" [binary]=\"true\" [formControl]=\"formControl\" [id]=\"property.name\" [readonly]=\"property.readOnly!\"></p-checkbox>\n <p-triStateCheckbox *ngIf=\"!property.required\" [formControl]=\"formControl\" [id]=\"property.name\" [readonly]=\"property.readOnly!\"></p-triStateCheckbox>\n </ng-container>\n \n <p-calendar *ngSwitchCase=\"PropertyType.DatetimeOffset\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n \n <p-calendar *ngSwitchCase=\"PropertyType.Duration\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [timeOnly]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n\n <rw-image *ngSwitchCase=\"PropertyType.Image\" [formControlName]=\"property.name\" [property]=\"property | as:PropertyWithImage\"></rw-image>\n\n <rw-file *ngSwitchCase=\"PropertyType.File\" [formControlName]=\"property.name\" [fileName]=\"property.name\" [accept]=\"property.placeholder\"></rw-file>\n\n <input *ngSwitchDefault [formControlName]=\"property.name\" [id]=\"property.name\" type=\"text\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i5.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: i5.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i15.InputText, selector: "[pInputText]" }, { kind: "component", type: i16.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: i17.Calendar, selector: "p-calendar", inputs: ["style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "view", "defaultDate", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "component", type: i18.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "trueValue", "falseValue"], outputs: ["onChange"] }, { kind: "component", type: i19.TriStateCheckbox, selector: "p-triStateCheckbox", inputs: ["disabled", "name", "ariaLabelledBy", "tabindex", "inputId", "style", "styleClass", "label", "readonly", "checkboxTrueIcon", "checkboxFalseIcon"], outputs: ["onChange"] }, { kind: "component", type: i20.RestWorldImageComponent, selector: "rw-image", inputs: ["property"] }, { kind: "component", type: i21.RestWorldFileComponent, selector: "rw-file", inputs: ["accept", "fileName"] }, { kind: "pipe", type: i4.AsPipe, name: "as" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
|
|
283
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputSimpleComponent, decorators: [{
|
|
284
|
+
type: Component,
|
|
285
|
+
args: [{ selector: 'rw-input-simple', viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: "<div [ngSwitch]=\"property.type\">\n\n <input *ngSwitchCase=\"PropertyType.Hidden\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"hidden\" [value]=\"property.value\" />\n \n <input *ngSwitchCase=\"PropertyType.Text\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"text\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <textarea *ngSwitchCase=\"PropertyType.Textarea\" [formControlName]=\"property.name\" [id]=\"property.name\" pInputTextarea class=\"w-full p-inputtextarea p-inputtext p-component p-element\" [class.p-disabled]=\"property.readOnly\" [cols]=\"property.cols\" [rows]=\"property.rows\"></textarea>\n \n <input *ngSwitchCase=\"PropertyType.Search\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"search\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <input *ngSwitchCase=\"PropertyType.Tel\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"tel\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <input *ngSwitchCase=\"PropertyType.Url\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"url\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <input *ngSwitchCase=\"PropertyType.Email\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"email\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <input *ngSwitchCase=\"PropertyType.Password\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"password\" pPassword class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <p-calendar *ngSwitchCase=\"PropertyType.Date\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showWeek]=\"true\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n \n <p-calendar *ngSwitchCase=\"PropertyType.Month\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showWeek]=\"false\" view=\"month\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n \n <input *ngSwitchCase=\"PropertyType.Week\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"week\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <p-calendar *ngSwitchCase=\"PropertyType.Time\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [timeOnly]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n \n <p-calendar *ngSwitchCase=\"PropertyType.DatetimeLocal\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n \n <p-inputNumber *ngSwitchCase=\"PropertyType.Number\" [formControlName]=\"property.name\" [id]=\"property.name\" mode=\"decimal\" [showButtons]=\"!property.readOnly\" class=\"w-full\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-inputNumber>\n \n <input *ngSwitchCase=\"PropertyType.Range\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"range\" [min]=\"property.min\" [max]=\"property.max\" [step]=\"property.step\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <input *ngSwitchCase=\"PropertyType.Color\" [formControlName]=\"property.name\" [id]=\"property.name\" type=\"color\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n \n <ng-container *ngSwitchCase=\"PropertyType.Bool\">\n <p-checkbox *ngIf=\"property.required\" [binary]=\"true\" [formControl]=\"formControl\" [id]=\"property.name\" [readonly]=\"property.readOnly!\"></p-checkbox>\n <p-triStateCheckbox *ngIf=\"!property.required\" [formControl]=\"formControl\" [id]=\"property.name\" [readonly]=\"property.readOnly!\"></p-triStateCheckbox>\n </ng-container>\n \n <p-calendar *ngSwitchCase=\"PropertyType.DatetimeOffset\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n \n <p-calendar *ngSwitchCase=\"PropertyType.Duration\" [formControlName]=\"property.name\" [id]=\"property.name\" [dateFormat]=\"dateFormat\" [showTime]=\"true\" [timeOnly]=\"true\" [showWeek]=\"false\" [showIcon]=\"true\" styleClass=\"w-full\" [class.p-disabled]=\"property.readOnly\"></p-calendar>\n\n <rw-image *ngSwitchCase=\"PropertyType.Image\" [formControlName]=\"property.name\" [property]=\"property | as:PropertyWithImage\"></rw-image>\n\n <rw-file *ngSwitchCase=\"PropertyType.File\" [formControlName]=\"property.name\" [fileName]=\"property.name\" [accept]=\"property.placeholder\"></rw-file>\n\n <input *ngSwitchDefault [formControlName]=\"property.name\" [id]=\"property.name\" type=\"text\" pInputText class=\"w-full\" [class.p-disabled]=\"property.readOnly\" />\n</div>" }]
|
|
286
|
+
}], ctorParameters: function () { return [{ type: i5.ControlContainer }]; }, propDecorators: { property: [{
|
|
287
|
+
type: Input
|
|
288
|
+
}] } });
|
|
289
|
+
/**
|
|
290
|
+
* A collection of rw-form-elemtns automatically created from a template.
|
|
291
|
+
* Does not have any buttons on its own.
|
|
292
|
+
* If you want buttons, use RestWorldForm <rw-form>.
|
|
293
|
+
*/
|
|
294
|
+
export class RestWorldInputTemplateComponent {
|
|
295
|
+
}
|
|
296
|
+
RestWorldInputTemplateComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputTemplateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
297
|
+
RestWorldInputTemplateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.3", type: RestWorldInputTemplateComponent, selector: "rw-input-template", inputs: { apiName: "apiName", template: "template" }, ngImport: i0, template: "<rw-form-element *ngFor=\"let property of template.properties\" [property]=\"property\" [apiName]=\"apiName\"></rw-form-element>", styles: [""], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: RestWorldFormElementComponent, selector: "rw-form-element", inputs: ["property", "apiName"] }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
|
|
298
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldInputTemplateComponent, decorators: [{
|
|
299
|
+
type: Component,
|
|
300
|
+
args: [{ selector: 'rw-input-template', viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: "<rw-form-element *ngFor=\"let property of template.properties\" [property]=\"property\" [apiName]=\"apiName\"></rw-form-element>" }]
|
|
301
|
+
}], propDecorators: { apiName: [{
|
|
302
|
+
type: Input
|
|
303
|
+
}], template: [{
|
|
304
|
+
type: Input
|
|
305
|
+
}] } });
|
|
306
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdHdvcmxkLWlucHV0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1yZXN0d29ybGQtY2xpZW50L3NyYy9saWIvY29tcG9uZW50cy9yZXN0d29ybGQtaW5wdXRzL3Jlc3R3b3JsZC1pbnB1dHMudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcmVzdHdvcmxkLWNsaWVudC9zcmMvbGliL2NvbXBvbmVudHMvcmVzdHdvcmxkLWlucHV0cy9yZXN0d29ybGQtZm9ybS1lbGVtZW50L3Jlc3R3b3JsZC1mb3JtLWVsZW1lbnQuY29tcG9uZW50Lmh0bWwiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcmVzdHdvcmxkLWNsaWVudC9zcmMvbGliL2NvbXBvbmVudHMvcmVzdHdvcmxkLWlucHV0cy9yZXN0d29ybGQtaW5wdXQvcmVzdHdvcmxkLWlucHV0LmNvbXBvbmVudC5odG1sIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXJlc3R3b3JsZC1jbGllbnQvc3JjL2xpYi9jb21wb25lbnRzL3Jlc3R3b3JsZC1pbnB1dHMvcmVzdHdvcmxkLWlucHV0LWNvbGxlY3Rpb24vcmVzdHdvcmxkLWlucHV0LWNvbGxlY3Rpb24uY29tcG9uZW50Lmh0bWwiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcmVzdHdvcmxkLWNsaWVudC9zcmMvbGliL2NvbXBvbmVudHMvcmVzdHdvcmxkLWlucHV0cy9yZXN0d29ybGQtaW5wdXQtZHJvcGRvd24vcmVzdHdvcmxkLWlucHV0LWRyb3Bkb3duLmNvbXBvbmVudC5odG1sIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXJlc3R3b3JsZC1jbGllbnQvc3JjL2xpYi9jb21wb25lbnRzL3Jlc3R3b3JsZC1pbnB1dHMvcmVzdHdvcmxkLWlucHV0LW9iamVjdC9yZXN0d29ybGQtaW5wdXQtb2JqZWN0LmNvbXBvbmVudC5odG1sIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXJlc3R3b3JsZC1jbGllbnQvc3JjL2xpYi9jb21wb25lbnRzL3Jlc3R3b3JsZC1pbnB1dHMvcmVzdHdvcmxkLWlucHV0LXNpbXBsZS9yZXN0d29ybGQtaW5wdXQtc2ltcGxlLmNvbXBvbmVudC5odG1sIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXJlc3R3b3JsZC1jbGllbnQvc3JjL2xpYi9jb21wb25lbnRzL3Jlc3R3b3JsZC1pbnB1dHMvcmVzdHdvcmxkLWlucHV0LXRlbXBsYXRlL3Jlc3R3b3JsZC1pbnB1dC10ZW1wbGF0ZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQXFCLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUF1QixNQUFNLGVBQWUsQ0FBQztBQUN2RyxPQUFPLEVBQW1CLGdCQUFnQixFQUFxQyxrQkFBa0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzFILE9BQU8sRUFBRSxjQUFjLEVBQXFCLFlBQVksRUFBbUMsTUFBTSx5QkFBeUIsQ0FBQztBQUczSCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFJOUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLE1BQU0saUNBQWlDLENBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRXhGOzs7O0dBSUc7QUFPSCxNQUFNLE9BQU8sNkJBQTZCOzswSEFBN0IsNkJBQTZCOzhHQUE3Qiw2QkFBNkIsNkdDdkIxQyx1UEFJQSw2RkR3Q2EsdUJBQXVCLDJOQXZCbkIsQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQzsyRkFFcEUsNkJBQTZCO2tCQU56QyxTQUFTOytCQUNFLGlCQUFpQixpQkFHWixDQUFDLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxDQUFDOzhCQUkvRSxR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LGtJQUEwSCx1TFB1QjdHLDZCQUE2QixrRkF3VXpCLENBQUMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLGtCQUFrQixFQUFFLENBQUM7MkZBRXBFLCtCQUErQjtrQkFOM0MsU0FBUzsrQkFDRSxtQkFBbUIsaUJBR2QsQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQzs4QkFJL0UsT0FBTztzQkFETixLQUFLO2dCQUlOLFFBQVE7c0JBRFAsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENka0RyYWdEcm9wIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XHJcbmltcG9ydCB7IENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIENvbnRlbnRDaGlsZCwgSW5wdXQsIE9uSW5pdCwgVGVtcGxhdGVSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBDb250cm9sQ29udGFpbmVyLCBGb3JtQXJyYXksIEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIEZvcm1Hcm91cERpcmVjdGl2ZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgTnVtYmVyVGVtcGxhdGUsIE9wdGlvbnMsIFByb3BlcnR5LCBQcm9wZXJ0eVR5cGUsIFJlc291cmNlLCBUZW1wbGF0ZSwgVGVtcGxhdGVEdG8gfSBmcm9tICdAd2VydHp1aS9uZ3gtaGFsLWNsaWVudCc7XHJcbmltcG9ydCB7IEZvcm1TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZm9ybS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTWVzc2FnZVNlcnZpY2UgfSBmcm9tICdwcmltZW5nL2FwaSc7XHJcbmltcG9ydCB7IFByb2JsZW1EZXRhaWxzIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3Byb2JsZW0tZGV0YWlscyc7XHJcbmltcG9ydCB7IFByb3BlcnR5VGVtcGxhdGVDb250ZXh0IH0gZnJvbSAnLi4vLi4vbW9kZWxzL3RlbXBsYXRpbmcnO1xyXG5pbXBvcnQgeyBSZXN0V29ybGRDbGllbnQgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9yZXN0d29ybGQtY2xpZW50JztcclxuaW1wb3J0IHsgUmVzdFdvcmxkQ2xpZW50Q29sbGVjdGlvbiB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3Jlc3R3b3JsZC1jbGllbnQtY29sbGVjdGlvbic7XHJcbmltcG9ydCB7IFByb3BlcnR5V2l0aE9wdGlvbnMsIFByb3BlcnR5V2l0aEltYWdlIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3NwZWNpYWwtcHJvcGVydGllcydcclxuXHJcbi8qKlxyXG4gKiBBIGZvcm0gZWxlbWVudCB3aXRoIGEgbGFiZWwgdGhhdCBpcyBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQgZnJvbSBhIHByb3BlcnR5IGluIGEgZm9ybSB0ZW1wbGF0ZS5cclxuICogVGhpcyBtYXkgYWxzbyBiZSBhIGNvbXBsZXggb2JqZWN0IG9yIGEgY29sbGVjdGlvbiBpbiB3aGljaCBjYXNlIG11bHRpcGxlIGFuZCBuZXN0ZWQgaW5wdXQgZWxlbWVudHMgbWF5IGJlIHJlbmRlcmVkLlxyXG4gKiBJZiB5b3Ugd2FudCBhIGZvcm0gZWxlbWVudCB3aXRob3V0IGEgbGFiZWwsIHVzZSBSZXN0V29ybGRGb3JtSW5wdXQgPHJ3LWZvcm0taW5wdXQ+LlxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdydy1mb3JtLWVsZW1lbnQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9yZXN0d29ybGQtZm9ybS1lbGVtZW50L3Jlc3R3b3JsZC1mb3JtLWVsZW1lbnQuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3Jlc3R3b3JsZC1mb3JtLWVsZW1lbnQvcmVzdHdvcmxkLWZvcm0tZWxlbWVudC5jb21wb25lbnQuY3NzJ10sXHJcbiAgdmlld1Byb3ZpZGVyczogW3sgcHJvdmlkZTogQ29udHJvbENvbnRhaW5lciwgdXNlRXhpc3Rpbmc6IEZvcm1Hcm91cERpcmVjdGl2ZSB9XVxyXG59KVxyXG5leHBvcnQgY2xhc3MgUmVzdFdvcmxkRm9ybUVsZW1lbnRDb21wb25lbnQ8VCBleHRlbmRzIHsgW0sgaW4ga2V5b2YgVF06IEFic3RyYWN0Q29udHJvbDxhbnksIGFueT47IH0+IHtcclxuICBASW5wdXQoKVxyXG4gIHByb3BlcnR5ITogUHJvcGVydHk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgYXBpTmFtZSE6IHN0cmluZztcclxufVxyXG5cclxuLyoqXHJcbiAqIEEgZm9ybSBpbnB1dCBlbGVtZW50IHRoYXQgaXMgYXV0b21hdGljYWxseSBjcmVhdGVkIGZyb20gYSBwcm9wZXJ0eSBpbiBhIGZvcm0gdGVtcGxhdGUuXHJcbiAqIFRoaXMgbWF5IGFsc28gYmUgYSBjb21wbGV4IG9iamVjdCBvciBhIGNvbGxlY3Rpb24gaW4gd2hpY2ggY2FzZSBtdWx0aXBsZSBhbmQgbmVzdGVkIGlucHV0IGVsZW1lbnRzIG1heSBiZSByZW5kZXJlZC5cclxuICogSWYgeW91IGFsc28gd2FudCBhIGxhYmVsLCB1c2UgUmVzdFdvcmxkRm9ybUVsZW1lbnQgPHJ3LWZvcm0tZWxlbWVudD4uXHJcbiAqIFlvdSBjYW4gYWxzbyB1c2Ugb25lIG9mIHRoZSBkaWZmZXJlbnQgUmVzdFdvcmxkSW5wdXQuLi4gPHJ3LWlucHV0LS4uLj4gZWxlbWVudHMgdG8gcmVuZGVyIGEgc3BlY2lmaWMgaW5wdXQsXHJcbiAqIGJ1dCBpdCBpcyBhZHZpc2VkIHRvIGNvbnRyb2wgdGhlIHJlbmRlcmVkIGlucHV0IHRocm91Z2ggdGhlIHBhc3NlZCBpbiBwcm9wZXJ0eS5cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAncnctaW5wdXQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9yZXN0d29ybGQtaW5wdXQvcmVzdHdvcmxkLWlucHV0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9yZXN0d29ybGQtaW5wdXQvcmVzdHdvcmxkLWlucHV0LmNvbXBvbmVudC5jc3MnXSxcclxuICB2aWV3UHJvdmlkZXJzOiBbeyBwcm92aWRlOiBDb250cm9sQ29udGFpbmVyLCB1c2VFeGlzdGluZzogRm9ybUdyb3VwRGlyZWN0aXZlIH1dXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBSZXN0V29ybGRJbnB1dENvbXBvbmVudCB7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgcHJvcGVydHkhOiBQcm9wZXJ0eTtcclxuXHJcbiAgQElucHV0KClcclxuICBhcGlOYW1lITogc3RyaW5nO1xyXG5cclxuICBwdWJsaWMgZ2V0IFByb3BlcnR5VHlwZSgpIHtcclxuICAgIHJldHVybiBQcm9wZXJ0eVR5cGU7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0IFByb3BlcnR5V2l0aE9wdGlvbnMoKSB7XHJcbiAgICByZXR1cm4gUHJvcGVydHlXaXRoT3B0aW9ucztcclxuICB9XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogQSBjb2xsZWN0aW9uIHRoYXQgaXMgYXV0b21hdGljYWxseSBjcmVhdGVkIGZyb20gdGhlIGdpdmVuIHByb3BlcnR5LlxyXG4gKiBUaGUgY29sbGVjdGlvbiBzdXBwb3J0cyBkcmFnICYgZHJvcCB0byByZSBvcmRlciB0aGUgZWxlbWVudHMgYW5kIGNhbiBhbHNvIGJlIG5lc3RlZC5cclxuICogSXQgaXMgYWR2aXNlZCB0byB1c2UgUmVzdFdvcmxkSW5wdXRDb21wb25lbnQgPHJ3LWlucHV0PiBhbmQgY29udHJvbCB0aGUgcmVuZGVyZWQgaW5wdXRzIHdpdGggdGhlIHBhc3NlZCBpbiBwcm9wZXJ0eVxyXG4gKiBpbnN0ZWFkIG9mIHVzaW5nIHRoaXMgY29tcG9uZW50IGRpcmVjdGx5LlxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdydy1pbnB1dC1jb2xsZWN0aW9uJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vcmVzdHdvcmxkLWlucHV0LWNvbGxlY3Rpb24vcmVzdHdvcmxkLWlucHV0LWNvbGxlY3Rpb24uY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3Jlc3R3b3JsZC1pbnB1dC1jb2xsZWN0aW9uL3Jlc3R3b3JsZC1pbnB1dC1jb2xsZWN0aW9uLmNvbXBvbmVudC5jc3MnXSxcclxuICB2aWV3UHJvdmlkZXJzOiBbeyBwcm92aWRlOiBDb250cm9sQ29udGFpbmVyLCB1c2VFeGlzdGluZzogRm9ybUdyb3VwRGlyZWN0aXZlIH1dXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBSZXN0V29ybGRJbnB1dENvbGxlY3Rpb25Db21wb25lbnQ8VCBleHRlbmRzIHsgW0sgaW4ga2V5b2YgVF06IEFic3RyYWN0Q29udHJvbDxhbnksIGFueT47IH0+IGltcGxlbWVudHMgT25Jbml0e1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHByb3BlcnR5ITogUHJvcGVydHk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgYXBpTmFtZSE6IHN0cmluZztcclxuXHJcbiAgQENvbnRlbnRDaGlsZCgnaW5wdXRDb2xsZWN0aW9uJywgeyBzdGF0aWM6IGZhbHNlIH0pXHJcbiAgaW5wdXRDb2xsZWN0aW9uUmVmPzogVGVtcGxhdGVSZWY8dW5rbm93bj47XHJcblxyXG5cclxuICBwcml2YXRlIF90ZW1wbGF0ZXM6IE51bWJlclRlbXBsYXRlW10gPSBbXTtcclxuICBwdWJsaWMgZ2V0IHRlbXBsYXRlcygpOiBOdW1iZXJUZW1wbGF0ZVtdIHtcclxuICAgIHJldHVybiB0aGlzLl90ZW1wbGF0ZXM7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9kZWZhdWx0VGVtcGxhdGU/OiBUZW1wbGF0ZTtcclxuICBwdWJsaWMgZ2V0IGRlZmF1bHRUZW1wbGF0ZSgpOiBUZW1wbGF0ZSB7XHJcbiAgICBpZih0aGlzLl9kZWZhdWx0VGVtcGxhdGUgPT09IHVuZGVmaW5lZClcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gZGVmYXVsdCB0ZW1wbGF0ZSBmb3VuZC5cIik7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRUZW1wbGF0ZTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2lubmVyRm9ybUFycmF5PzogRm9ybUFycmF5PEZvcm1Hcm91cDxUPj47XHJcbiAgcHVibGljIGdldCBpbm5lckZvcm1BcnJheSgpIHtcclxuICAgIGlmICh0aGlzLl9pbm5lckZvcm1BcnJheSA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmb3JtR3JvdXAgaXMgbm90IHNldC5cIik7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuX2lubmVyRm9ybUFycmF5O1xyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IgKFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBfY29udHJvbENvbnRhaW5lcjogQ29udHJvbENvbnRhaW5lcixcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2Zvcm1TZXJ2aWNlOiBGb3JtU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuICApIHtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgY29uc3QgZm9ybUdyb3VwID0gdGhpcy5fY29udHJvbENvbnRhaW5lci5jb250cm9sIGFzIEZvcm1Hcm91cDxhbnk+O1xyXG4gICAgdGhpcy5faW5uZXJGb3JtQXJyYXkgPSBmb3JtR3JvdXAuY29udHJvbHNbdGhpcy5wcm9wZXJ0eS5uYW1lXSBhcyBGb3JtQXJyYXk8Rm9ybUdyb3VwPFQ+PjtcclxuICAgIHRoaXMuX3RlbXBsYXRlcyA9IFJlc3RXb3JsZElucHV0Q29sbGVjdGlvbkNvbXBvbmVudC5nZXRDb2xsZWN0aW9uRW50cnlUZW1wbGF0ZXModGhpcy5wcm9wZXJ0eSk7XHJcbiAgICB0aGlzLl9kZWZhdWx0VGVtcGxhdGUgPSB0aGlzLnByb3BlcnR5Ll90ZW1wbGF0ZXMuZGVmYXVsdDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc3RhdGljIGdldENvbGxlY3Rpb25FbnRyeVRlbXBsYXRlcyhwcm9wZXJ0eT86IFByb3BlcnR5KTogTnVtYmVyVGVtcGxhdGVbXSB7XHJcbiAgICBpZiAoIXByb3BlcnR5KVxyXG4gICAgICByZXR1cm4gW107XHJcblxyXG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHByb3BlcnR5Ll90ZW1wbGF0ZXMpXHJcbiAgICAgIC5maWx0ZXIoKFtrZXksIHZhbHVlXSkgPT4gTnVtYmVyLmlzSW50ZWdlcihOdW1iZXIucGFyc2VJbnQoa2V5KSkgJiYgTnVtYmVyLmlzSW50ZWdlcihOdW1iZXIucGFyc2VJbnQodmFsdWUudGl0bGUgPz8gXCJcIikpKVxyXG4gICAgICAubWFwKChbLCB2YWx1ZV0pID0+IG5ldyBOdW1iZXJUZW1wbGF0ZSh2YWx1ZSkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFkZE5ld0l0ZW1Ub0NvbGxlY3Rpb24oKTogdm9pZCB7XHJcbiAgICBjb25zdCBtYXhJbmRleCA9IE1hdGgubWF4KC4uLk9iamVjdC5rZXlzKHRoaXMudGVtcGxhdGVzKVxyXG4gICAgICAubWFwKGtleSA9PiBOdW1iZXIucGFyc2VJbnQoa2V5KSlcclxuICAgICAgLmZpbHRlcihrZXkgPT4gTnVtYmVyLmlzU2FmZUludGVnZXIoa2V5KSkpO1xyXG4gICAgY29uc3QgbmV4dEluZGV4ID0gbWF4SW5kZXggPCAwID8gMCA6IG1heEluZGV4ICsgMTtcclxuXHJcbiAgICBjb25zdCBjb3BpZWRUZW1wbGF0ZUR0byA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5kZWZhdWx0VGVtcGxhdGUpKSBhcyBUZW1wbGF0ZUR0bztcclxuICAgIGNvbnN0IGNvcGllZFRlbXBsYXRlID0gbmV3IE51bWJlclRlbXBsYXRlKGNvcGllZFRlbXBsYXRlRHRvKTtcclxuICAgIGNvcGllZFRlbXBsYXRlLnRpdGxlID0gbmV4dEluZGV4O1xyXG5cclxuICAgIHRoaXMudGVtcGxhdGVzW2NvcGllZFRlbXBsYXRlLnRpdGxlXSA9IGNvcGllZFRlbXBsYXRlO1xyXG4gICAgdGhpcy5pbm5lckZvcm1BcnJheS5wdXNoKHRoaXMuX2Zvcm1TZXJ2aWNlLmNyZWF0ZUZvcm1Hcm91cEZyb21UZW1wbGF0ZSh0aGlzLmRlZmF1bHRUZW1wbGF0ZSkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGRlbGV0ZUl0ZW1Gcm9tQ29sbGVjdGlvbih0ZW1wbGF0ZTogTnVtYmVyVGVtcGxhdGUpOiB2b2lkIHtcclxuICAgIGRlbGV0ZSB0aGlzLnRlbXBsYXRlc1t0ZW1wbGF0ZS50aXRsZV07XHJcbiAgICB0aGlzLmlubmVyRm9ybUFycmF5LnJlbW92ZUF0KHRlbXBsYXRlLnRpdGxlKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjb2xsZWN0aW9uSXRlbURyb3BwZWQoJGV2ZW50OiBDZGtEcmFnRHJvcDx7IH0+KSB7XHJcbiAgICBjb25zdCBwcmV2aW91c0luZGV4ID0gJGV2ZW50LnByZXZpb3VzSW5kZXg7XHJcbiAgICBjb25zdCBjdXJyZW50SW5kZXggPSAkZXZlbnQuY3VycmVudEluZGV4O1xyXG4gICAgY29uc3QgbW92ZW1lbnREaXJlY3Rpb24gPSBjdXJyZW50SW5kZXggPiBwcmV2aW91c0luZGV4ID8gMSA6IC0xO1xyXG5cclxuICAgIC8vIE1vdmUgaW4gRm9ybUFycmF5XHJcbiAgICAvLyBXZSBkbyBub3QgbmVlZCB0byBtb3ZlIHRoZSBpdGVtIGluIHRoZSBfdGVtcGxhdGVzIG9iamVjdFxyXG4gICAgY29uc3QgbW92ZWRDb250cm9sID0gdGhpcy5pbm5lckZvcm1BcnJheS5hdChwcmV2aW91c0luZGV4KTtcclxuICAgIGZvciAobGV0IGkgPSBwcmV2aW91c0luZGV4OyBpICogbW92ZW1lbnREaXJlY3Rpb24gPCBjdXJyZW50SW5kZXggKiBtb3ZlbWVudERpcmVjdGlvbjsgaSA9IGkgKyBtb3ZlbWVudERpcmVjdGlvbikge1xyXG4gICAgICB0aGlzLmlubmVyRm9ybUFycmF5LnNldENvbnRyb2woaSwgdGhpcy5pbm5lckZvcm1BcnJheS5hdChpICsgbW92ZW1lbnREaXJlY3Rpb24pKTtcclxuICAgIH1cclxuICAgIHRoaXMuaW5uZXJGb3JtQXJyYXkuc2V0Q29udHJvbChjdXJyZW50SW5kZXgsIG1vdmVkQ29udHJvbCk7XHJcblxyXG4gICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogQSBkcm9wZG93biB0aGF0IGlzIGF1dG9tYXRpY2FsbHkgY3JlYXRlZCBmcm9tIHRoZSBnaXZlbiBwcm9wZXJ0eS5cclxuICogVGhlIGRyb3Bkb3duIHN1cHBvcnRzIHNlYXJjaGluZyB0aHJvdWdoIGEgUkVTVFdvcmxkIGxpc3QgZW5kcG9pbnQgb24gdGhlIGJhY2tlbmQuXHJcbiAqIEl0IGlzIGFkdmlzZWQgdG8gdXNlIFJlc3RXb3JsZElucHV0Q29tcG9uZW50IDxydy1pbnB1dD4gYW5kIGNvbnRyb2wgdGhlIHJlbmRlcmVkIGlucHV0cyB3aXRoIHRoZSBwYXNzZWQgaW4gcHJvcGVydHlcclxuICogaW5zdGVhZCBvZiB1c2luZyB0aGlzIGNvbXBvbmVudCBkaXJlY3RseS5cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAncnctaW5wdXQtZHJvcGRvd24nLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9yZXN0d29ybGQtaW5wdXQtZHJvcGRvd24vcmVzdHdvcmxkLWlucHV0LWRyb3Bkb3duLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9yZXN0d29ybGQtaW5wdXQtZHJvcGRvd24vcmVzdHdvcmxkLWlucHV0LWRyb3Bkb3duLmNvbXBvbmVudC5jc3MnXSxcclxuICB2aWV3UHJvdmlkZXJzOiBbeyBwcm92aWRlOiBDb250cm9sQ29udGFpbmVyLCB1c2VFeGlzdGluZzogRm9ybUdyb3VwRGlyZWN0aXZlIH1dXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBSZXN0V29ybGRJbnB1dERyb3Bkb3duQ29tcG9uZW50IHtcclxuICBASW5wdXQoKVxyXG4gIHByb3BlcnR5ITogUHJvcGVydHkgJiB7IG9wdGlvbnM6IE9wdGlvbnMgfTtcclxuXHJcbiAgQElucHV0KClcclxuICBhcGlOYW1lITogc3RyaW5nO1xyXG5cclxuICBAQ29udGVudENoaWxkKCdpbnB1dE9wdGlvbnNTaW5nbGUnLCB7IHN0YXRpYzogZmFsc2UgfSlcclxuICBpbnB1dE9wdGlvbnNTaW5nbGVSZWY/OiBUZW1wbGF0ZVJlZjxQcm9wZXJ0eVRlbXBsYXRlQ29udGV4dD47XHJcblxyXG4gIEBDb250ZW50Q2hpbGQoJ2lucHV0T3B0aW9uc011bHRpcGxlJywgeyBzdGF0aWM6IGZhbHNlIH0pXHJcbiAgaW5wdXRPcHRpb25zTXVsdGlwbGVSZWY/OiBUZW1wbGF0ZVJlZjxQcm9wZXJ0eVRlbXBsYXRlQ29udGV4dD47XHJcblxyXG4gIGNvbnN0cnVjdG9yIChcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgX21lc3NhZ2VTZXJ2aWNlOiBNZXNzYWdlU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NsaWVudHM6IFJlc3RXb3JsZENsaWVudENvbGxlY3Rpb25cclxuICApIHtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXREcm9wZG93bkVsZW1lbnRUb29sdGlwKHJlc291cmNlOiBSZXNvdXJjZSwga2V5c1RvRXhjbHVkZT86IHN0cmluZ1tdKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHRvb2x0aXAgPSBPYmplY3QuZW50cmllcyhyZXNvdXJjZSlcclxuICAgICAgLmZpbHRlcigoW2tleV0pID0+ICEoa2V5LnN0YXJ0c1dpdGgoJ18nKSB8fCBbJ2NyZWF0ZWRBdCcsICdjcmVhdGVkQnknLCAnbGFzdENoYW5nZWRBdCcsICdsYXN0Q2hhbmdlZEJ5JywgJ3RpbWVzdGFtcCddLmluY2x1ZGVzKGtleSkgfHwga2V5c1RvRXhjbHVkZT8uaW5jbHVkZXMoa2V5KSkpXHJcbiAgICAgIC5yZWR1Y2UoKHByZXYsIFtrZXksIHZhbHVlXSwgaW5kZXgpID0+IGAke3ByZXZ9JHtpbmRleCA9PT0gMCA/ICcnIDogJ1xcbid9JHtrZXl9OiAke1Jlc3RXb3JsZElucHV0RHJvcGRvd25Db21wb25lbnQuanNvblN0cmluZ2lmeVdpdGhFbGlwc2lzKHZhbHVlKX1gLCAnJyk7XHJcblxyXG4gICAgcmV0dXJuIHRvb2x0aXA7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgb25PcHRpb25zRmlsdGVyZWQocHJvcGVydHk6IFByb3BlcnR5LCBldmVudDogeyBvcmlnaW5hbEV2ZW50OiB1bmtub3duOyBmaWx0ZXI6IHN0cmluZyB8IG51bGwgfSkge1xyXG4gICAgY29uc3Qgb3B0aW9ucyA9IHByb3BlcnR5Py5vcHRpb25zO1xyXG5cclxuICAgIGlmICghb3B0aW9ucz8ubGluaz8uaHJlZiB8fCAhZXZlbnQuZmlsdGVyIHx8IGV2ZW50LmZpbHRlciA9PT0gJycpXHJcbiAgICAgIHJldHVybjtcclxuXHJcblxyXG4gICAgY29uc3QgdGVtcGxhdGVkVXJpID0gb3B0aW9ucy5saW5rLmhyZWY7XHJcbiAgICBsZXQgZmlsdGVyID0gYGNvbnRhaW5zKCR7b3B0aW9ucy5wcm9tcHRGaWVsZH0sICcke2V2ZW50LmZpbHRlcn0nKWA7XHJcbiAgICBpZiAob3B0aW9ucy52YWx1ZUZpZWxkPy50b0xvd2VyQ2FzZSgpID09PSAnaWQnICYmICFOdW1iZXIuaXNOYU4oTnVtYmVyLnBhcnNlSW50KGV2ZW50LmZpbHRlcikpKVxyXG4gICAgICBmaWx0ZXIgPSBgKCR7b3B0aW9ucy52YWx1ZUZpZWxkfSBlcSAke2V2ZW50LmZpbHRlcn0pICBvciAoJHtmaWx0ZXJ9KWA7XHJcblxyXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpLmdldExpc3RCeVVyaSh0ZW1wbGF0ZWRVcmksIHsgJGZpbHRlcjogZmlsdGVyLCAkdG9wOiAxMCB9KTtcclxuICAgIGlmICghcmVzcG9uc2Uub2sgfHwgUHJvYmxlbURldGFpbHMuaXNQcm9ibGVtRGV0YWlscyhyZXNwb25zZS5ib2R5KSB8fCAhcmVzcG9uc2UuYm9keSkge1xyXG4gICAgICBjb25zdCBtZXNzYWdlID0gYEFuIGVycm9yIG9jY3VycmVkIHdoaWxlIGdldHRpbmcgdGhlIGZpbHRlcmVkIGl0ZW1zLmA7XHJcbiAgICAgIHRoaXMuX21lc3NhZ2VTZXJ2aWNlLmFkZCh7IHNldmVyaXR5OiAnZXJyb3InLCBzdW1tYXJ5OiAnRXJyb3InLCBkZXRhaWw6IG1lc3NhZ2UsIGRhdGE6IHJlc3BvbnNlLCBzdGlja3k6IHRydWUgfSk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBpdGVtcyA9IHJlc3BvbnNlLmJvZHkuX2VtYmVkZGVkLml0ZW1zO1xyXG4gICAgb3B0aW9ucy5pbmxpbmUgPSBpdGVtcztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0Q2xpZW50KCk6IFJlc3RXb3JsZENsaWVudCB7XHJcbiAgICBpZiAoIXRoaXMuYXBpTmFtZSlcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZ2V0IGEgY2xpZW50LCBiZWNhdXNlIHRoZSBhcGlOYW1lIGlzIG5vdCBzZXQuJyk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudHMuZ2V0Q2xpZW50KHRoaXMuYXBpTmFtZSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN0YXRpYyBqc29uU3RyaW5naWZ5V2l0aEVsaXBzaXModmFsdWU6IHVua25vd24pIHtcclxuICAgIGNvbnN0IG1heExlbmd0aCA9IDIwMDtcclxuICAgIGNvbnN0IGVuZCA9IDEwO1xyXG4gICAgY29uc3Qgc3RhcnQgPSBtYXhMZW5ndGggLSBlbmQgLSAyO1xyXG4gICAgY29uc3QganNvbiA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcclxuICAgIGNvbnN0IHNob3J0ZW5lZCA9IGpzb24ubGVuZ3RoID4gbWF4TGVuZ3RoID8ganNvbi5zdWJzdHJpbmcoMCwgc3RhcnQpICsgJ+KApicgKyBqc29uLnN1YnN0cmluZyhqc29uLmxlbmd0aCAtIGVuZCkgOiBqc29uO1xyXG5cclxuICAgIHJldHVybiBzaG9ydGVuZWQ7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogQSBjb21wbGV4IG9iamVjdCB3aXRoIG11bHRpcGxlIHByb3BlcnRpZXMgdGhhdCBpcyBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQgZnJvbSB0aGUgZ2l2ZW4gcHJvcGVydHkuXHJcbiAqIFRoZSBvYmplY3QgY2FuIGFsc28gYmUgbmVzdGVkLlxyXG4gKiBJdCBpcyBhZHZpc2VkIHRvIHVzZSBSZXN0V29ybGRJbnB1dENvbXBvbmVudCA8cnctaW5wdXQ+IGFuZCBjb250cm9sIHRoZSByZW5kZXJlZCBpbnB1dHMgd2l0aCB0aGUgcGFzc2VkIGluIHByb3BlcnR5XHJcbiAqIGluc3RlYWQgb2YgdXNpbmcgdGhpcyBjb21wb25lbnQgZGlyZWN0bHkuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3J3LWlucHV0LW9iamVjdCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3Jlc3R3b3JsZC1pbnB1dC1vYmplY3QvcmVzdHdvcmxkLWlucHV0LW9iamVjdC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vcmVzdHdvcmxkLWlucHV0LW9iamVjdC9yZXN0d29ybGQtaW5wdXQtb2JqZWN0LmNvbXBvbmVudC5jc3MnXSxcclxuICB2aWV3UHJvdmlkZXJzOiBbeyBwcm92aWRlOiBDb250cm9sQ29udGFpbmVyLCB1c2VFeGlzdGluZzogRm9ybUdyb3VwRGlyZWN0aXZlIH1dXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBSZXN0V29ybGRJbnB1dE9iamVjdENvbXBvbmVudDxUIGV4dGVuZHMgeyBbSyBpbiBrZXlvZiBUXTogQWJzdHJhY3RDb250cm9sPGFueSwgYW55PjsgfT4gaW1wbGVtZW50cyBPbkluaXQge1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHByb3BlcnR5ITogUHJvcGVydHk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgYXBpTmFtZSE6IHN0cmluZztcclxuXHJcbiAgQENvbnRlbnRDaGlsZCgnaW5wdXRPYmplY3QnLCB7IHN0YXRpYzogZmFsc2UgfSlcclxuICBpbnB1dE9iamVjdFJlZj86IFRlbXBsYXRlUmVmPHVua25vd24+O1xyXG5cclxuICBwcml2YXRlIF9pbm5lckZvcm1Hcm91cD86IEZvcm1Hcm91cDxUPjtcclxuXHJcbiAgcHVibGljIGdldCBpbm5lckZvcm1Hcm91cCgpIHtcclxuICAgIGlmICh0aGlzLl9pbm5lckZvcm1Hcm91cCA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmb3JtR3JvdXAgaXMgbm90IHNldC5cIik7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuX2lubmVyRm9ybUdyb3VwO1xyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IgKFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBfY29udHJvbENvbnRhaW5lcjogQ29udHJvbENvbnRhaW5lclxyXG4gICkge1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICBjb25zdCBmb3JtR3JvdXAgPSB0aGlzLl9jb250cm9sQ29udGFpbmVyLmNvbnRyb2wgYXMgRm9ybUdyb3VwPGFueT47XHJcbiAgICB0aGlzLl9pbm5lckZvcm1Hcm91cCA9IGZvcm1Hcm91cC5jb250cm9sc1t0aGlzLnByb3BlcnR5Lm5hbWVdIGFzIEZvcm1Hcm91cDxUPjtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBIHNpbXBsZSBpbnB1dCBlbGVtZW50LCBsaWtlIGEgdGV4dCwgb3IgYSBudW1iZXIgdGhhdCBpcyBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQgZnJvbSB0aGUgZ2l2ZW4gcHJvcGVydHkuXHJcbiAqIEl0IGlzIGFkdmlzZWQgdG8gdXNlIFJlc3RXb3JsZElucHV0Q29tcG9uZW50IDxydy1pbnB1dD4gYW5kIGNvbnRyb2wgdGhlIHJlbmRlcmVkIGlucHV0cyB3aXRoIHRoZSBwYXNzZWQgaW4gcHJvcGVydHlcclxuICogaW5zdGVhZCBvZiB1c2luZyB0aGlzIGNvbXBvbmVudCBkaXJlY3RseS5cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAncnctaW5wdXQtc2ltcGxlJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vcmVzdHdvcmxkLWlucHV0LXNpbXBsZS9yZXN0d29ybGQtaW5wdXQtc2ltcGxlLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9yZXN0d29ybGQtaW5wdXQtc2ltcGxlL3Jlc3R3b3JsZC1pbnB1dC1zaW1wbGUuY29tcG9uZW50LmNzcyddLFxyXG4gIHZpZXdQcm92aWRlcnM6IFt7IHByb3ZpZGU6IENvbnRyb2xDb250YWluZXIsIHVzZUV4aXN0aW5nOiBGb3JtR3JvdXBEaXJlY3RpdmUgfV1cclxufSlcclxuZXhwb3J0IGNsYXNzIFJlc3RXb3JsZElucHV0U2ltcGxlQ29tcG9uZW50PFQ+IGltcGxlbWVudHMgT25Jbml0IHtcclxuXHJcbiAgQElucHV0KClcclxuICBwcm9wZXJ0eSE6IFByb3BlcnR5O1xyXG5cclxuICBwdWJsaWMgZ2V0IFByb3BlcnR5VHlwZSgpIHtcclxuICAgIHJldHVybiBQcm9wZXJ0eVR5cGU7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0IGRhdGVGb3JtYXQoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBuZXcgRGF0ZSgzMzMzLCAxMSwgMjIpXHJcbiAgICAgIC50b0xvY2FsZURhdGVTdHJpbmcoKVxyXG4gICAgICAucmVwbGFjZShcIjIyXCIsIFwiZGRcIilcclxuICAgICAgLnJlcGxhY2UoXCIxMVwiLCBcIm1tXCIpXHJcbiAgICAgIC5yZXBsYWNlKFwiMzMzM1wiLCBcInl5XCIpXHJcbiAgICAgIC5yZXBsYWNlKFwiMzNcIiwgXCJ5XCIpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfZm9ybUNvbnRyb2w/OiBGb3JtQ29udHJvbDxUPjtcclxuXHJcbiAgcHVibGljIGdldCBmb3JtQ29udHJvbCgpIHtcclxuICAgIGlmICh0aGlzLl9mb3JtQ29udHJvbCA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmb3JtR3JvdXAgaXMgbm90IHNldC5cIik7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuX2Zvcm1Db250cm9sO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBQcm9wZXJ0eVdpdGhJbWFnZSgpIHtcclxuICAgIHJldHVybiBQcm9wZXJ0eVdpdGhJbWFnZTtcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yIChcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NvbnRyb2xDb250YWluZXI6IENvbnRyb2xDb250YWluZXJcclxuICApIHtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgY29uc3QgZm9ybUdyb3VwID0gdGhpcy5fY29udHJvbENvbnRhaW5lci5jb250cm9sIGFzIEZvcm1Hcm91cDxhbnk+O1xyXG4gICAgdGhpcy5fZm9ybUNvbnRyb2wgPSBmb3JtR3JvdXAuY29udHJvbHNbdGhpcy5wcm9wZXJ0eS5uYW1lXSBhcyBGb3JtQ29udHJvbDxUPjtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBIGNvbGxlY3Rpb24gb2YgcnctZm9ybS1lbGVtdG5zIGF1dG9tYXRpY2FsbHkgY3JlYXRlZCBmcm9tIGEgdGVtcGxhdGUuXHJcbiAqIERvZXMgbm90IGhhdmUgYW55IGJ1dHRvbnMgb24gaXRzIG93bi5cclxuICogSWYgeW91IHdhbnQgYnV0dG9ucywgdXNlIFJlc3RXb3JsZEZvcm0gPHJ3LWZvcm0+LlxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdydy1pbnB1dC10ZW1wbGF0ZScsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3Jlc3R3b3JsZC1pbnB1dC10ZW1wbGF0ZS9yZXN0d29ybGQtaW5wdXQtdGVtcGxhdGUuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3Jlc3R3b3JsZC1pbnB1dC10ZW1wbGF0ZS9yZXN0d29ybGQtaW5wdXQtdGVtcGxhdGUuY29tcG9uZW50LmNzcyddLFxyXG4gIHZpZXdQcm92aWRlcnM6IFt7IHByb3ZpZGU6IENvbnRyb2xDb250YWluZXIsIHVzZUV4aXN0aW5nOiBGb3JtR3JvdXBEaXJlY3RpdmUgfV1cclxufSlcclxuZXhwb3J0IGNsYXNzIFJlc3RXb3JsZElucHV0VGVtcGxhdGVDb21wb25lbnQ8VCBleHRlbmRzIHsgW0sgaW4ga2V5b2YgVF06IEFic3RyYWN0Q29udHJvbDxhbnksIGFueT47IH0+IHtcclxuICBASW5wdXQoKVxyXG4gIGFwaU5hbWUhOiBzdHJpbmc7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgdGVtcGxhdGUhOiBUZW1wbGF0ZTtcclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiZ3JpZCBmaWVsZFwiPlxyXG4gICAgPHJ3LWxhYmVsIFtwcm9wZXJ0eV09XCJwcm9wZXJ0eVwiIGNsYXNzPVwiY29sLTEyIG1kOmNvbC0yIGZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+PC9ydy1sYWJlbD5cclxuICAgIDxydy1pbnB1dCBbYXBpTmFtZV09XCJhcGlOYW1lXCIgW3Byb3BlcnR5XT1cInByb3BlcnR5XCIgY2xhc3M9XCJjb2wtMTIgbWQ6Y29sLTEwXCI+PC9ydy1pbnB1dD5cclxuPC9kaXY+XHJcbiIsIjxydy1pbnB1dC1kcm9wZG93biAqbmdJZj1cInByb3BlcnR5Lm9wdGlvbnNcIiBbYXBpTmFtZV09XCJhcGlOYW1lXCIgW3Byb3BlcnR5XT1cInByb3BlcnR5IHwgYXM6UHJvcGVydHlXaXRoT3B0aW9uc1wiPjwvcnctaW5wdXQtZHJvcGRvd24+XHJcblxyXG48bmctY29udGFpbmVyICpuZ0lmPVwiIXByb3BlcnR5Lm9wdGlvbnNcIj5cclxuICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cInByb3BlcnR5LnR5cGVcIj5cclxuICAgICAgICA8cnctaW5wdXQtb2JqZWN0ICpuZ1N3aXRjaENhc2U9XCJQcm9wZXJ0eVR5cGUuT2JqZWN0XCIgW2FwaU5hbWVdPVwiYXBpTmFtZVwiIFtwcm9wZXJ0eV09XCJwcm9wZXJ0eVwiPjwvcnctaW5wdXQtb2JqZWN0PlxyXG4gICAgICAgIDxydy1pbnB1dC1jb2xsZWN0aW9uICpuZ1N3aXRjaENhc2U9XCJQcm9wZXJ0eVR5cGUuQ29sbGVjdGlvblwiIFthcGlOYW1lXT1cImFwaU5hbWVcIiBbcHJvcGVydHldPVwicHJvcGVydHlcIj48L3J3LWlucHV0LWNvbGxlY3Rpb24+XHJcbiAgICAgICAgPHJ3LWlucHV0LXNpbXBsZSAqbmdTd2l0Y2hEZWZhdWx0IFtwcm9wZXJ0eV09XCJwcm9wZXJ0eVwiPjwvcnctaW5wdXQtc2ltcGxlPlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcbjwvbmctY29udGFpbmVyPlxyXG5cclxuPHJ3LXZhbGlkYXRpb24tZXJyb3JzIFtwcm9wZXJ0eV09XCJwcm9wZXJ0eVwiPjwvcnctdmFsaWRhdGlvbi1lcnJvcnM+IiwiPGRpdiBjbGFzcz1cImZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgPGRpdiBjbGFzcz1cImJyYWNlXCI+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInctZnVsbFwiIGNka0Ryb3BMaXN0IChjZGtEcm9wTGlzdERyb3BwZWQpPVwiY29sbGVjdGlvbkl0ZW1Ecm9wcGVkKCRldmVudClcIj5cbiAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgdGVtcGxhdGUgb2YgdGVtcGxhdGVzXCIgY2xhc3M9XCJmbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiIGNka0RyYWc+XG4gICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1ncmlwLWxpbmVzXCIgY2RrRHJhZ0hhbmRsZT48L2k+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnJhY2VcIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctZnVsbCBmbGV4IGp1c3RpZnktY29udGVudC1lbmRcIj5cbiAgICAgICAgICAgICAgICA8cnctaW5wdXQtdGVtcGxhdGUgW2Zvcm1Hcm91cF09XCJpbm5lckZvcm1BcnJheS5jb250cm9sc1t0ZW1wbGF0ZS50aXRsZV1cIiBbdGVtcGxhdGVdPVwiZGVmYXVsdFRlbXBsYXRlXCIgW2FwaU5hbWVdPVwiYXBpTmFtZVwiIGNsYXNzPVwidy1mdWxsXCI+PC9ydy1pbnB1dC10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gcFJpcHBsZSB0eXBlPVwiYnV0dG9uXCIgaWNvbj1cImZhcyBmYS10cmFzaFwiIGNsYXNzPVwicC1idXR0b24tb3V0bGluZWQgcC1idXR0b24tZGFuZ2VyIG1sLTIgbWItM1wiIChjbGljayk9XCJkZWxldGVJdGVtRnJvbUNvbGxlY3Rpb24odGVtcGxhdGUpXCI+PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktY29udGVudC1lbmQgdy1mdWxsXCI+XG4gICAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gcFJpcHBsZSB0eXBlPVwiYnV0dG9uXCIgaWNvbj1cImZhcyBmYS1wbHVzXCIgY2xhc3M9XCJwLWJ1dHRvbi1vdXRsaW5lZCBwLWJ1dHRvbi1pbmZvXCIgKGNsaWNrKT1cImFkZE5ld0l0ZW1Ub0NvbGxlY3Rpb24oKVwiPjwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PiIsIjxuZy10ZW1wbGF0ZSAjZGVmYXVsdElucHV0T3B0aW9uc1NpbmdsZSBsZXQtcHJvcGVydHk9XCJwcm9wZXJ0eVwiIGxldC10ZW1wbGF0ZT1cInRlbXBsYXRlXCI+XG4gICAgPHAtZHJvcGRvd24gXG4gICAgW2Zvcm1Db250cm9sTmFtZV09XCJwcm9wZXJ0eS5uYW1lXCIgXG4gICAgW2lkXT1cInByb3BlcnR5Lm5hbWVcIiBcbiAgICBbb3B0aW9uc109XCJwcm9wZXJ0eS5vcHRpb25zLmlubGluZVwiIFxuICAgIFtmaWx0ZXJCeV09XCIocHJvcGVydHkub3B0aW9ucy5wcm9tcHRGaWVsZCA/PyAncHJvbXB0JykgKyAnLCcgKyAocHJvcGVydHkub3B0aW9ucy52YWx1ZUZpZWxkID8/ICd2YWx1ZScpXCIgXG4gICAgW29wdGlvblZhbHVlXT1cInByb3BlcnR5Lm9wdGlvbnMudmFsdWVGaWVsZCA/PyAndmFsdWUnXCIgXG4gICAgW3JlYWRvbmx5XT1cInByb3BlcnR5LnJlYWRPbmx5XCIgXG4gICAgW3JlcXVpcmVkXT1cInByb3BlcnR5LnJlcXVpcmVkIHx8IHByb3BlcnR5Lm9wdGlvbnMubWluSXRlbXMgPiAwXCIgXG4gICAgW2ZpbHRlcl09XCJ0cnVlXCIgXG4gICAgW2F1dG9EaXNwbGF5Rmlyc3RdPVwiZmFsc2VcIiBcbiAgICBbc2hvd0NsZWFyXT1cIiFwcm9wZXJ0eS5yZXF1aXJlZCB8fCBwcm9wZXJ0eS5vcHRpb25zLm1pbkl0ZW1zIDw9IDBcIiBcbiAgICAob25GaWx0ZXIpPVwib25PcHRpb25zRmlsdGVyZWQocHJvcGVydHksICRldmVudClcIiBcbiAgICBzdHlsZUNsYXNzPVwidy1mdWxsXCIgXG4gICAgW2ZpbHRlclBsYWNlaG9sZGVyXT1cInByb3BlcnR5Py5vcHRpb25zPy5saW5rPy5ocmVmID8gJ3NlYXJjaCBmb3IgbW9yZSByZXN1bHRzJyA6ICcnXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtaXRlbSBwVGVtcGxhdGU9XCJzZWxlY3RlZEl0ZW1cIj5cbiAgICAgICAgICAgIDxzcGFuIFtwVG9vbHRpcF09XCJnZXREcm9wZG93bkVsZW1lbnRUb29sdGlwKGl0ZW0sIFtwcm9wZXJ0eS5vcHRpb25zLnByb21wdEZpZWxkID8/ICdwcm9tcHQnLCBwcm9wZXJ0eS5vcHRpb25zLnZhbHVlRmllbGQgPz8gJ3ZhbHVlJ10pXCI+e3tpdGVtW3Byb3BlcnR5Lm9wdGlvbnMucHJvbXB0RmllbGQgPz8gJ3Byb21wdCddfX0gKHt7aXRlbVtwcm9wZXJ0eS5vcHRpb25zLnZhbHVlRmllbGQgPz8gJ3ZhbHVlJ119fSk8L3NwYW4+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtaXRlbSBwVGVtcGxhdGU9XCJpdGVtXCI+XG4gICAgICAgICAgICA8c3BhbiBbcFRvb2x0aXBdPVwiZ2V0RHJvcGRvd25FbGVtZW50VG9vbHRpcChpdGVtLCBbcHJvcGVydHkub3B0aW9ucy5wcm9tcHRGaWVsZCA/PyAncHJvbXB0JywgcHJvcGVydHkub3B0aW9ucy52YWx1ZUZpZWxkID8/ICd2YWx1ZSddKVwiPnt7aXRlbVtwcm9wZXJ0eS5vcHRpb25zLnByb21wdEZpZWxkID8/ICdwcm9tcHQnXX19ICh7e2l0ZW1bcHJvcGVydHkub3B0aW9ucy52YWx1ZUZpZWxkID8/ICd2YWx1ZSddfX0pPC9zcGFuPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvcC1kcm9wZG93bj5cbjwvbmctdGVtcGxhdGU+XG48bmctY29udGFpbmVyICpuZ0lmPVwiIXByb3BlcnR5Lm9wdGlvbnMubWF4SXRlbXMgfHwgcHJvcGVydHkub3B0aW9ucy5tYXhJdGVtcyA9PSAxXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImlucHV0T3B0aW9uc1NpbmdsZVJlZiA/PyBkZWZhdWx0SW5wdXRPcHRpb25zU2luZ2xlOyBjb250ZXh0OiB7IHByb3BlcnR5OiBwcm9wZXJ0eSwgYXBpTmFtZTogYXBpTmFtZSB9XCI+PC9uZy1jb250YWluZXI+XG48L25nLWNvbnRhaW5lcj5cblxuPG5nLXRlbXBsYXRlICNkZWZhdWx0SW5wdXRPcHRpb25zTXVsdGlwbGUgbGV0LXByb3BlcnR5PVwicHJvcGVydHlcIiBsZXQtdGVtcGxhdGU9XCJ0ZW1wbGF0ZVwiPlxuICAgIDxwLW11bHRpU2VsZWN0IFxuICAgIFtmb3JtQ29udHJvbE5hbWVdPVwicHJvcGVydHkubmFtZVwiIFxuICAgIFtpZF09XCJwcm9wZXJ0eS5uYW1lXCIgXG4gICAgW29wdGlvbnNdPVwicHJvcGVydHkub3B0aW9ucy5pbmxpbmVcIiBcbiAgICBbb3B0aW9uTGFiZWxdPVwicHJvcGVydHkub3B0aW9ucy5wcm9tcHRGaWVsZCA/PyAncHJvbXB0J1wiIFxuICAgIFtvcHRpb25WYWx1ZV09XCJwcm9wZXJ0eS5vcHRpb25zLnZhbHVlRmllbGQgPz8gJ3ZhbHVlJ1wiIFxuICAgIFtyZWFkb25seV09XCJwcm9wZXJ0eS5yZWFkT25seVwiIFxuICAgIFtzZWxlY3Rpb25MaW1pdF09XCJwcm9wZXJ0eS5vcHRpb25zLm1heEl0ZW1zXCIgXG4gICAgW3JlcXVpcmVkXT1cInByb3BlcnR5LnJlcXVpcmVkIHx8IHByb3BlcnR5Lm9wdGlvbnMubWluSXRlbXMgPiAwXCI+PC9wLW11bHRpU2VsZWN0PlxuPC9uZy10ZW1wbGF0ZT5cbjxuZy1jb250YWluZXIgKm5nSWY9XCIocHJvcGVydHkub3B0aW9ucy5tYXhJdGVtcyA/PyAwKSA+IDFcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaW5wdXRPcHRpb25zTXVsdGlwbGVSZWYgPz8gZGVmYXVsdElucHV0T3B0aW9uc011bHRpcGxlOyBjb250ZXh0OiB7IHByb3BlcnR5OiBwcm9wZXJ0eSwgYXBpTmFtZTogYXBpTmFtZSB9XCI+PC9uZy1jb250YWluZXI+XG48L25nLWNvbnRhaW5lcj4iLCI8bmctdGVtcGxhdGUgI2RlZmF1bHRJbnB1dE9iamVjdCBsZXQtcHJvcGVydHk9XCJwcm9wZXJ0eVwiIGxldC10ZW1wbGF0ZT1cInRlbXBsYXRlXCI+XG4gICAgPGRpdiBjbGFzcz1cImZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJicmFjZVwiPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInctZnVsbFwiPlxuICAgICAgICAgICAgPHJ3LWlucHV0LXRlbXBsYXRlIFtmb3JtR3JvdXBdPVwiaW5uZXJGb3JtR3JvdXBcIiBbdGVtcGxhdGVdPVwicHJvcGVydHkuX3RlbXBsYXRlcy5kZWZhdWx0XCIgW2FwaU5hbWVdPVwiYXBpTmFtZVwiPjwvcnctaW5wdXQtdGVtcGxhdGU+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbjxuZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImlucHV0T2JqZWN0UmVmIHx8IGRlZmF1bHRJbnB1dE9iamVjdDsgY29udGV4dDogeyBwcm9wZXJ0eTogcHJvcGVydHksIGlubmVyRm9ybUdyb3VwOiBpbm5lckZvcm1Hcm91cCwgYXBpTmFtZTogYXBpTmFtZSB9XCI+PC9uZy1jb250YWluZXI+XG48L25nLWNvbnRhaW5lcj4iLCI8ZGl2IFtuZ1N3aXRjaF09XCJwcm9wZXJ0eS50eXBlXCI+XG5cbiAgICA8aW5wdXQgKm5nU3dpdGNoQ2FzZT1cIlByb3BlcnR5VHlwZS5IaWRkZW5cIiBbZm9ybUNvbnRyb2xOYW1lXT1cInByb3BlcnR5Lm5hbWVcIiBbaWRdPVwicHJvcGVydHkubmFtZVwiIHR5cGU9XCJoaWRkZW5cIiBbdmFsdWVdPVwicHJvcGVydHkudmFsdWVcIiAvPlxuICBcbiAgICA8aW5wdXQgKm5nU3dpdGNoQ2FzZT1cIlByb3BlcnR5VHlwZS5UZXh0XCIgW2Zvcm1Db250cm9sTmFtZV09XCJwcm9wZXJ0eS5uYW1lXCIgW2lkXT1cInByb3BlcnR5Lm5hbWVcIiB0eXBlPVwidGV4dFwiIHBJbnB1dFRleHQgY2xhc3M9XCJ3LWZ1bGxcIiBbY2xhc3MucC1kaXNhYmxlZF09XCJwcm9wZXJ0eS5yZWFkT25seVwiIC8+XG4gICBcbiAgICA8dGV4dGFyZWEgKm5nU3dpdGNoQ2FzZT1cIlByb3BlcnR5VHlwZS5UZXh0YXJlYVwiIFtmb3JtQ29udHJvbE5hbWVdPVwicHJvcGVydHkubmFtZVwiIFtpZF09XCJwcm9wZXJ0eS5uYW1lXCIgcElucHV0VGV4dGFyZWEgY2xhc3M9XCJ3LWZ1bGwgcC1pbnB1dHRleHRhcmVhIHAtaW5wdXR0ZXh0IHAtY29tcG9uZW50IHAtZWxlbWVudFwiIFtjbGFzcy5wLWRpc2FibGVkXT1cInByb3BlcnR5LnJlYWRPbmx5XCIgW2NvbHNdPVwicHJvcGVydHkuY29sc1wiIFtyb3dzXT1cInByb3BlcnR5LnJvd3NcIj48L3RleHRhcmVhPlxuICAgXG4gICAgPGlucHV0ICpuZ1N3aXRjaENhc2U9XCJQcm9wZXJ0eVR5cGUuU2VhcmNoXCIgW2Zvcm1Db250cm9sTmFtZV09XCJwcm9wZXJ0eS5uYW1lXCIgW2lkXT1cInByb3BlcnR5Lm5hbWVcIiB0eXBlPVwic2VhcmNoXCIgcElucHV0VGV4dCBjbGFzcz1cInctZnVsbFwiIFtjbGFzcy5wLWRpc2FibGVkXT1cInByb3BlcnR5LnJlYWRPbmx5XCIgLz5cbiAgIFxuICAgIDxpbnB1dCAqbmdTd2l0Y2hDYXNlPVwiUHJvcGVydHlUeXBlLlRlbFwiIFtmb3JtQ29udHJvbE5hbWVdPVwicHJvcGVydHkubmFtZVwiIFtpZF09XCJwcm9wZXJ0eS5uYW1lXCIgdHlwZT1cInRlbFwiIHBJbnB1dFRleHQgY2xhc3M9XCJ3LWZ1bGxcIiBbY2xhc3MucC1kaXNhYmxlZF09XCJwcm9wZXJ0eS5yZWFkT25seVwiIC8+XG4gICBcbiAgICA8aW5wdXQgKm5nU3dpdGNoQ2FzZT1cIlByb3BlcnR5VHlwZS5VcmxcIiBbZm9ybUNvbnRyb2xOYW1lXT1cInByb3BlcnR5Lm5hbWVcIiBbaWRdPVwicHJvcGVydHkubmFtZVwiIHR5cGU9XCJ1cmxcIiBwSW5wdXRUZXh0IGNsYXNzPVwidy1mdWxsXCIgW2NsYXNzLnAtZGlzYWJsZWRdPVwicHJvcGVydHkucmVhZE9ubHlcIiAvPlxuICAgXG4gICAgPGlucHV0ICpuZ1N3aXRjaENhc2U9XCJQcm9wZXJ0eVR5cGUuRW1haWxcIiBbZm9ybUNvbnRyb2xOYW1lXT1cInByb3BlcnR5Lm5hbWVcIiBbaWRdPVwicHJvcGVydHkubmFtZVwiIHR5cGU9XCJlbWFpbFwiIHBJbnB1dFRleHQgY2xhc3M9XCJ3LWZ1bGxcIiBbY2xhc3MucC1kaXNhYmxlZF09XCJwcm9wZXJ0eS5yZWFkT25seVwiIC8+XG4gICBcbiAgICA8aW5wdXQgKm5nU3dpdGNoQ2FzZT1cIlByb3BlcnR5VHlwZS5QYXNzd29yZFwiIFtmb3JtQ29udHJvbE5hbWVdPVwicHJvcGVydHkubmFtZVwiIFtpZF09XCJwcm9wZXJ0eS5uYW1lXCIgdHlwZT1cInBhc3N3b3JkXCIgcFBhc3N3b3JkIGNsYXNzPVwidy1mdWxsXCIgW2NsYXNzLnAtZGlzYWJsZWRdPVwicHJvcGVydHkucmVhZE9ubHlcIiAvPlxuICAgXG4gICAgPHAtY2FsZW5kYXIgKm5nU3dpdGNoQ2FzZT1cIlByb3BlcnR5VHlwZS5EYXRlXCIgW2Zvcm1Db250cm9sTmFtZV09XCJwcm9wZXJ0eS5uYW1lXCIgW2lkXT1cInByb3BlcnR5Lm5hbWVcIiBbZGF0ZUZvcm1hdF09XCJkYXRlRm9ybWF0XCIgW3Nob3dXZWVrXT1cInRydWVcIiBbc2hvd0ljb25dPVwidHJ1ZVwiIHN0eWxlQ2xhc3M9XCJ3LWZ1bGxcIiBbY2xhc3MucC1kaXNhYmxlZF09XCJwcm9wZXJ0eS5yZWFkT25seVwiPjwvcC1jYWxlbmRhcj5cbiAgIFxuICAgIDxwLWNhbGVuZGFyICpuZ1N3aXRjaENhc2U9XCJQcm9wZXJ0eVR5cGUuTW9udGhcIiBbZm9ybUNvbnRyb2xOYW1lXT1cInByb3BlcnR5Lm5hbWVcIiBbaWRdPVwicHJvcGVydHkubmFtZVwiIFtkYXRlRm9ybWF0XT1cImRhdGVGb3JtYXRcIiBbc2hvd1dlZWtdPVwiZmFsc2VcIiB2aWV3PVwibW9udGhcIiBbc2hvd0ljb25dPVwidHJ1ZVwiIHN0eWxlQ2xhc3M9XCJ3LWZ1bGxcIiBbY2xhc3MucC1kaXNhYmxlZF09XCJwcm9wZXJ0eS5yZWFkT25seVwiPjwvcC1jYWxlbmRhcj5cbiAgICBcbiAgICA8aW5wdXQgKm5nU3dpdGNoQ2FzZT1cIlByb3BlcnR5VHlwZS5XZWVrXCIgW2Zvcm1Db250cm9sTmFtZV09XCJwcm9wZXJ0eS5uYW1lXCIgW2lkXT1cInByb3BlcnR5Lm5hbWVcIiB0eXBlPVwid2Vla1wiIHBJbnB1dFRleHQgY2xhc3M9XCJ3LWZ1bGxcIiBbY2xhc3MucC1kaXNhYmxlZF09XCJwcm9wZXJ0eS5yZWFkT25seVwiIC8+XG4gICBcbiAgICA8cC1jYWxlbmRhciAqbmdTd2l0Y2hDYXNlPVwiUHJvcGVydHlUeXBlLlRpbWVcIiBbZm9ybUNvbnRyb2xOYW1lXT1cInByb3BlcnR5Lm5hbWVcIiBbaWRdPVwicHJvcGVydHkubmFtZVwiIFtkYXRlRm9ybWF0XT1cImRhdGVGb3JtYXRcIiBbc2hvd1RpbWVdPVwidHJ1ZVwiIFt0aW1lT25seV09XCJ0cnVlXCIgW3Nob3dXZWVrXT1cImZhbHNlXCIgW3Nob3dJY29uXT1cInRydWVcIiBzdHlsZUNsYXNzPVwidy1mdWxsXCIgW2NsYXNzLnAtZGlzYWJsZWRdPVwicHJvcGVydHkucmVhZE9ubHlcIj48L3AtY2FsZW5kYXI+XG4gICAgXG4gICAgPHAtY2FsZW5kYXIgKm5nU3dpdGNoQ2FzZT1cIlByb3BlcnR5VHlwZS5EYXRldGltZUxvY2FsXCIgW2Zvcm1Db250cm9sTmFtZV09XCJwcm9wZXJ0eS5uYW1lXCIgW2lkXT1cInByb3BlcnR5Lm5hbWVcIiBbZGF0ZUZvcm1hdF09XCJkYXRlRm9ybWF0XCIgW3Nob3dUaW1lXT1cInRydWVcIiBbc2hvd1dlZWtdPVwiZmFsc2VcIiBbc2hvd0ljb25dPVwidHJ1ZVwiIHN0eWxlQ2xhc3M9XCJ3LWZ1bGxcIiBbY2xhc3MucC1kaXNhYmxlZF09XCJwcm9wZXJ0eS5yZWFkT25seVwiPjwvcC1jYWxlbmRhcj5cbiAgICBcbiAgICA8cC1pbnB1dE51bWJlciAqbmdTd2l0Y2hDYXNlPVwiUHJvcGVydHlUeXBlLk51bWJlclwiIFtmb3JtQ29udHJvbE5hbWVdPVwicHJvcGVydHkubmFtZVwiIFtpZF09XCJwcm9wZXJ0eS5uYW1lXCIgbW9kZT1cImRlY2ltYWxcIiBbc2hvd0J1dHRvbnNdPVwiIXByb3BlcnR5LnJlYWRPbmx5XCIgY2xhc3M9XCJ3LWZ1bGxcIiBzdHlsZUNsYXNzPVwidy1mdWxsXCIgW2NsYXNzLnAtZGlzYWJsZWRdPVwicHJvcGVydHkucmVhZE9ubHlcIj48L3AtaW5wdXROdW1iZXI+XG4gICAgXG4gICAgPGlucHV0ICpuZ1N3aXRjaENhc2U9XCJQcm9wZXJ0eVR5cGUuUmFuZ2VcIiBbZm9ybUNvbnRyb2xOYW1lXT1cInByb3BlcnR5Lm5hbWVcIiBbaWRdPVwicHJvcGVydHkubmFtZVwiIHR5cGU9XCJyYW5nZVwiIFttaW5dPVwicHJvcGVydHkubWluXCIgW21heF09XCJwcm9wZXJ0eS5tYXhcIiBbc3RlcF09XCJwcm9wZXJ0eS5zdGVwXCIgcElucHV0VGV4dCBjbGFzcz1cInctZnVsbFwiIFtjbGFzcy5wLWRpc2FibGVkXT1cInByb3BlcnR5LnJlYWRPbmx5XCIgLz5cbiAgICBcbiAgICA8aW5wdXQgKm5nU3dpdGNoQ2FzZT1cIlByb3BlcnR5VHlwZS5Db2xvclwiIFtmb3JtQ29udHJvbE5hbWVdPVwicHJvcGVydHkubmFtZVwiIFtpZF09XCJwcm9wZXJ0eS5uYW1lXCIgdHlwZT1cImNvbG9yXCIgcElucHV0VGV4dCBjbGFzcz1cInctZnVsbFwiIFtjbGFzcy5wLWRpc2FibGVkXT1cInByb3BlcnR5LnJlYWRPbmx5XCIgLz5cbiAgIFxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIlByb3BlcnR5VHlwZS5Cb29sXCI+XG4gICAgICAgIDxwLWNoZWNrYm94ICpuZ0lmPVwicHJvcGVydHkucmVxdWlyZWRcIiBbYmluYXJ5XT1cInRydWVcIiBbZm9ybUNvbnRyb2xdPVwiZm9ybUNvbnRyb2xcIiBbaWRdPVwicHJvcGVydHkubmFtZVwiIFtyZWFkb25seV09XCJwcm9wZXJ0eS5yZWFkT25seSFcIj48L3AtY2hlY2tib3g+XG4gICAgICAgIDxwLXRyaVN0YXRlQ2hlY2tib3ggKm5nSWY9XCIhcHJvcGVydHkucmVxdWlyZWRcIiBbZm9ybUNvbnRyb2xdPVwiZm9ybUNvbnRyb2xcIiBbaWRdPVwicHJvcGVydHkubmFtZVwiIFtyZWFkb25seV09XCJwcm9wZXJ0eS5yZWFkT25seSFcIj48L3AtdHJpU3RhdGVDaGVja2JveD5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICBcbiAgICA8cC1jYWxlbmRhciAqbmdTd2l0Y2hDYXNlPVwiUHJvcGVydHlUeXBlLkRhdGV0aW1lT2Zmc2V0XCIgW2Zvcm1Db250cm9sTmFtZV09XCJwcm9wZXJ0eS5uYW1lXCIgW2lkXT1cInByb3BlcnR5Lm5hbWVcIiBbZGF0ZUZvcm1hdF09XCJkYXRlRm9ybWF0XCIgW3Nob3dUaW1lXT1cInRydWVcIiBbc2hvd1dlZWtdPVwiZmFsc2VcIiBbc2hvd0ljb25dPVwidHJ1ZVwiIHN0eWxlQ2xhc3M9XCJ3LWZ1bGxcIiBbY2xhc3MucC1kaXNhYmxlZF09XCJwcm9wZXJ0eS5yZWFkT25seVwiPjwvcC1jYWxlbmRhcj5cbiAgICBcbiAgICA8cC1jYWxlbmRhciAqbmdTd2l0Y2hDYXNlPVwiUHJvcGVydHlUeXBlLkR1cmF0aW9uXCIgW2Zvcm1Db250cm9sTmFtZV09XCJwcm9wZXJ0eS5uYW1lXCIgW2lkXT1cInByb3BlcnR5Lm5hbWVcIiBbZGF0ZUZvcm1hdF09XCJkYXRlRm9ybWF0XCIgW3Nob3dUaW1lXT1cInRydWVcIiBbdGltZU9ubHldPVwidHJ1ZVwiIFtzaG93V2Vla109XCJmYWxzZVwiIFtzaG93SWNvbl09XCJ0cnVlXCIgc3R5bGVDbGFzcz1cInctZnVsbFwiIFtjbGFzcy5wLWRpc2FibGVkXT1cInByb3BlcnR5LnJlYWRPbmx5XCI+PC9wLWNhbGVuZGFyPlxuXG4gICAgPHJ3LWltYWdlICpuZ1N3aXRjaENhc2U9XCJQcm9wZXJ0eVR5cGUuSW1hZ2VcIiBbZm9ybUNvbnRyb2xOYW1lXT1cInByb3BlcnR5Lm5hbWVcIiBbcHJvcGVydHldPVwicHJvcGVydHkgfCBhczpQcm9wZXJ0eVdpdGhJbWFnZVwiPjwvcnctaW1hZ2U+XG5cbiAgICA8cnctZmlsZSAqbmdTd2l0Y2hDYXNlPVwiUHJvcGVydHlUeXBlLkZpbGVcIiBbZm9ybUNvbnRyb2xOYW1lXT1cInByb3BlcnR5Lm5hbWVcIiBbZmlsZU5hbWVdPVwicHJvcGVydHkubmFtZVwiIFthY2NlcHRdPVwicHJvcGVydHkucGxhY2Vob2xkZXJcIj48L3J3LWZpbGU+XG5cbiAgICA8aW5wdXQgKm5nU3dpdGNoRGVmYXVsdCBbZm9ybUNvbnRyb2xOYW1lXT1cInByb3BlcnR5Lm5hbWVcIiBbaWRdPVwicHJvcGVydHkubmFtZVwiIHR5cGU9XCJ0ZXh0XCIgcElucHV0VGV4dCBjbGFzcz1cInctZnVsbFwiIFtjbGFzcy5wLWRpc2FibGVkXT1cInByb3BlcnR5LnJlYWRPbmx5XCIgLz5cbjwvZGl2PiIsIjxydy1mb3JtLWVsZW1lbnQgKm5nRm9yPVwibGV0IHByb3BlcnR5IG9mIHRlbXBsYXRlLnByb3BlcnRpZXNcIiBbcHJvcGVydHldPVwicHJvcGVydHlcIiBbYXBpTmFtZV09XCJhcGlOYW1lXCI+PC9ydy1mb3JtLWVsZW1lbnQ+Il19
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Component, Input } from '@angular/core';
|
|
2
|
+
import { ControlContainer, FormGroupDirective } from '@angular/forms';
|
|
3
|
+
import { PropertyType } from '@wertzui/ngx-hal-client';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@angular/common";
|
|
6
|
+
/**
|
|
7
|
+
* A label that is generated from the given property.
|
|
8
|
+
* If you also want an input element, you can either use RestWorldFormElement <rw-form-element> to have a label and an input rendered,
|
|
9
|
+
* or use RestWorldInput <rw-input> which will just render the input element, so you can freely place this label.
|
|
10
|
+
*/
|
|
11
|
+
export class RestWorldLabelComponent {
|
|
12
|
+
get PropertyType() {
|
|
13
|
+
return PropertyType;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
RestWorldLabelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
17
|
+
RestWorldLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.3", type: RestWorldLabelComponent, selector: "rw-label", inputs: { property: "property" }, ngImport: i0, template: "<label \r\n *ngIf=\"property.type !== PropertyType.Hidden\" \r\n [attr.for]=\"property.name\"\r\n [class.p-disabled]=\"property.readOnly\">\r\n {{property.prompt ?? property.name}}\r\n</label>", styles: [".label-hidden{visibility:hidden}.label-collapsed{display:none}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
|
|
18
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldLabelComponent, decorators: [{
|
|
19
|
+
type: Component,
|
|
20
|
+
args: [{ selector: 'rw-label', viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: "<label \r\n *ngIf=\"property.type !== PropertyType.Hidden\" \r\n [attr.for]=\"property.name\"\r\n [class.p-disabled]=\"property.readOnly\">\r\n {{property.prompt ?? property.name}}\r\n</label>", styles: [".label-hidden{visibility:hidden}.label-collapsed{display:none}\n"] }]
|
|
21
|
+
}], propDecorators: { property: [{
|
|
22
|
+
type: Input
|
|
23
|
+
}] } });
|
|
24
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdHdvcmxkLWxhYmVsLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1yZXN0d29ybGQtY2xpZW50L3NyYy9saWIvY29tcG9uZW50cy9yZXN0d29ybGQtbGFiZWwvcmVzdHdvcmxkLWxhYmVsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1yZXN0d29ybGQtY2xpZW50L3NyYy9saWIvY29tcG9uZW50cy9yZXN0d29ybGQtbGFiZWwvcmVzdHdvcmxkLWxhYmVsLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RFLE9BQU8sRUFBWSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7O0FBRWpFOzs7O0dBSUc7QUFPSCxNQUFNLE9BQU8sdUJBQXVCO0lBSWxDLElBQVcsWUFBWTtRQUNyQixPQUFPLFlBQVksQ0FBQztJQUN0QixDQUFDOztvSEFOVSx1QkFBdUI7d0dBQXZCLHVCQUF1QixrRkNmcEMsOE1BS1EsbU5EUVMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQzsyRkFFcEUsdUJBQXVCO2tCQU5uQyxTQUFTOytCQUNFLFVBQVUsaUJBR0wsQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQzs4QkFJL0UsUUFBUTtzQkFEUCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbENvbnRhaW5lciwgRm9ybUdyb3VwRGlyZWN0aXZlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUHJvcGVydHksIFByb3BlcnR5VHlwZSB9IGZyb20gJ0B3ZXJ0enVpL25neC1oYWwtY2xpZW50JztcblxuLyoqXG4gKiBBIGxhYmVsIHRoYXQgaXMgZ2VuZXJhdGVkIGZyb20gdGhlIGdpdmVuIHByb3BlcnR5LlxuICogSWYgeW91IGFsc28gd2FudCBhbiBpbnB1dCBlbGVtZW50LCB5b3UgY2FuIGVpdGhlciB1c2UgUmVzdFdvcmxkRm9ybUVsZW1lbnQgPHJ3LWZvcm0tZWxlbWVudD4gdG8gaGF2ZSBhIGxhYmVsIGFuZCBhbiBpbnB1dCByZW5kZXJlZCxcbiAqIG9yIHVzZSBSZXN0V29ybGRJbnB1dCA8cnctaW5wdXQ+IHdoaWNoIHdpbGwganVzdCByZW5kZXIgdGhlIGlucHV0IGVsZW1lbnQsIHNvIHlvdSBjYW4gZnJlZWx5IHBsYWNlIHRoaXMgbGFiZWwuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3J3LWxhYmVsJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3Jlc3R3b3JsZC1sYWJlbC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3Jlc3R3b3JsZC1sYWJlbC5jb21wb25lbnQuY3NzJ10sXG4gIHZpZXdQcm92aWRlcnM6IFt7IHByb3ZpZGU6IENvbnRyb2xDb250YWluZXIsIHVzZUV4aXN0aW5nOiBGb3JtR3JvdXBEaXJlY3RpdmUgfV1cbn0pXG5leHBvcnQgY2xhc3MgUmVzdFdvcmxkTGFiZWxDb21wb25lbnQge1xuICBASW5wdXQoKVxuICBwcm9wZXJ0eSE6IFByb3BlcnR5O1xuXG4gIHB1YmxpYyBnZXQgUHJvcGVydHlUeXBlKCkge1xuICAgIHJldHVybiBQcm9wZXJ0eVR5cGU7XG4gIH1cbn1cbiIsIjxsYWJlbCBcclxuICAgICpuZ0lmPVwicHJvcGVydHkudHlwZSAhPT0gUHJvcGVydHlUeXBlLkhpZGRlblwiIFxyXG4gICAgW2F0dHIuZm9yXT1cInByb3BlcnR5Lm5hbWVcIlxyXG4gICAgW2NsYXNzLnAtZGlzYWJsZWRdPVwicHJvcGVydHkucmVhZE9ubHlcIj5cclxuICAgIHt7cHJvcGVydHkucHJvbXB0ID8/IHByb3BlcnR5Lm5hbWV9fVxyXG48L2xhYmVsPiJdfQ==
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Component, Input } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import * as i1 from "@angular/router";
|
|
4
|
+
import * as i2 from "@angular/common";
|
|
5
|
+
import * as i3 from "primeng/tooltip";
|
|
6
|
+
import * as i4 from "primeng/button";
|
|
7
|
+
import * as i5 from "primeng/splitbutton";
|
|
8
|
+
export class RestWorldMenuButtonComponent {
|
|
9
|
+
constructor(_router) {
|
|
10
|
+
this._router = _router;
|
|
11
|
+
this.items = [];
|
|
12
|
+
}
|
|
13
|
+
onClick(item) {
|
|
14
|
+
if (item.url) {
|
|
15
|
+
window.location.href = item.url;
|
|
16
|
+
}
|
|
17
|
+
else if (item.routerLink) {
|
|
18
|
+
this._router.navigate(item.routerLink, {
|
|
19
|
+
queryParams: item.queryParams,
|
|
20
|
+
fragment: item.fragment,
|
|
21
|
+
queryParamsHandling: item.queryParamsHandling,
|
|
22
|
+
preserveFragment: item.preserveFragment,
|
|
23
|
+
skipLocationChange: item.skipLocationChange,
|
|
24
|
+
replaceUrl: item.replaceUrl
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
else if (item.command) {
|
|
28
|
+
item.command();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
RestWorldMenuButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldMenuButtonComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
33
|
+
RestWorldMenuButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.3", type: RestWorldMenuButtonComponent, selector: "rw-menu-button", inputs: { items: "items" }, ngImport: i0, template: "<ng-container *ngFor=\"let item of items; index as i\">\n <p-button\n *ngIf=\"!item.items\"\n [label]=\"item.label!\"\n [icon]=\"item.icon!\"\n [disabled]=\"item.disabled!\"\n [style]=\"item.style\"\n [styleClass]=\"item.styleClass!\"\n [pTooltip]=\"item.tooltip!\"\n [tooltipPosition]=\"item.tooltipPosition!\"\n (onClick)=\"onClick(item)\"\n [class.ml-2]=\"i > 0\">\n </p-button>\n\n <p-splitButton\n *ngIf=\"item.items\"\n [label]=\"item.label!\"\n [icon]=\"item.icon!\"\n [model]=\"item.items\"\n appendTo=\"body\"\n [disabled]=\"item.disabled!\"\n [style]=\"item.style\"\n [styleClass]=\"item.styleClass!\"\n [pTooltip]=\"item.tooltip!\"\n [tooltipPosition]=\"item.tooltipPosition!\"\n (onClick)=\"onClick(item)\"\n [class.ml-2]=\"i > 0\">\n </p-splitButton>\n</ng-container>\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "fitContent", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "style", "styleClass", "badgeClass", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i5.SplitButton, selector: "p-splitButton", inputs: ["model", "icon", "iconPos", "label", "style", "styleClass", "menuStyle", "menuStyleClass", "disabled", "tabindex", "appendTo", "dir", "expandAriaLabel", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onClick", "onDropdownClick"] }] });
|
|
34
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: RestWorldMenuButtonComponent, decorators: [{
|
|
35
|
+
type: Component,
|
|
36
|
+
args: [{ selector: 'rw-menu-button', template: "<ng-container *ngFor=\"let item of items; index as i\">\n <p-button\n *ngIf=\"!item.items\"\n [label]=\"item.label!\"\n [icon]=\"item.icon!\"\n [disabled]=\"item.disabled!\"\n [style]=\"item.style\"\n [styleClass]=\"item.styleClass!\"\n [pTooltip]=\"item.tooltip!\"\n [tooltipPosition]=\"item.tooltipPosition!\"\n (onClick)=\"onClick(item)\"\n [class.ml-2]=\"i > 0\">\n </p-button>\n\n <p-splitButton\n *ngIf=\"item.items\"\n [label]=\"item.label!\"\n [icon]=\"item.icon!\"\n [model]=\"item.items\"\n appendTo=\"body\"\n [disabled]=\"item.disabled!\"\n [style]=\"item.style\"\n [styleClass]=\"item.styleClass!\"\n [pTooltip]=\"item.tooltip!\"\n [tooltipPosition]=\"item.tooltipPosition!\"\n (onClick)=\"onClick(item)\"\n [class.ml-2]=\"i > 0\">\n </p-splitButton>\n</ng-container>\n" }]
|
|
37
|
+
}], ctorParameters: function () { return [{ type: i1.Router }]; }, propDecorators: { items: [{
|
|
38
|
+
type: Input
|
|
39
|
+
}] } });
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdHdvcmxkLW1lbnUtYnV0dG9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1yZXN0d29ybGQtY2xpZW50L3NyYy9saWIvY29tcG9uZW50cy9yZXN0d29ybGQtbWVudS1idXR0b24vcmVzdHdvcmxkLW1lbnUtYnV0dG9uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1yZXN0d29ybGQtY2xpZW50L3NyYy9saWIvY29tcG9uZW50cy9yZXN0d29ybGQtbWVudS1idXR0b24vcmVzdHdvcmxkLW1lbnUtYnV0dG9uLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7Ozs7O0FBU2pELE1BQU0sT0FBTyw0QkFBNEI7SUFJdkMsWUFBNkIsT0FBZTtRQUFmLFlBQU8sR0FBUCxPQUFPLENBQVE7UUFGckMsVUFBSyxHQUFjLEVBQUUsQ0FBQztJQUk3QixDQUFDO0lBRUQsT0FBTyxDQUFDLElBQWM7UUFDcEIsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFO1lBQ1osTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztTQUNqQzthQUFNLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUMxQixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFO2dCQUNyQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7Z0JBQzdCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtnQkFDdkIsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLG1CQUFtQjtnQkFDN0MsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtnQkFDdkMsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLGtCQUFrQjtnQkFDM0MsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO2FBQzVCLENBQUMsQ0FBQztTQUNKO2FBQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztTQUNoQjtJQUNILENBQUM7O3lIQXZCVSw0QkFBNEI7NkdBQTVCLDRCQUE0QixrRkNUekMsczFCQTZCQTsyRkRwQmEsNEJBQTRCO2tCQUx4QyxTQUFTOytCQUNFLGdCQUFnQjs2RkFNbkIsS0FBSztzQkFEWCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IE1lbnVJdGVtIH0gZnJvbSAncHJpbWVuZy9hcGknO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdydy1tZW51LWJ1dHRvbicsXG4gIHRlbXBsYXRlVXJsOiAnLi9yZXN0d29ybGQtbWVudS1idXR0b24uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9yZXN0d29ybGQtbWVudS1idXR0b24uY29tcG9uZW50LmNzcyddXG59KVxuZXhwb3J0IGNsYXNzIFJlc3RXb3JsZE1lbnVCdXR0b25Db21wb25lbnQge1xuICBASW5wdXQoKVxuICBwdWJsaWMgaXRlbXM6IE1lbnVJdGVtW109IFtdO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgX3JvdXRlcjogUm91dGVyKSB7XG5cbiAgfVxuXG4gIG9uQ2xpY2soaXRlbTogTWVudUl0ZW0pIHtcbiAgICBpZiAoaXRlbS51cmwpIHtcbiAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gaXRlbS51cmw7XG4gICAgfSBlbHNlIGlmIChpdGVtLnJvdXRlckxpbmspIHtcbiAgICAgIHRoaXMuX3JvdXRlci5uYXZpZ2F0ZShpdGVtLnJvdXRlckxpbmssIHtcbiAgICAgICAgcXVlcnlQYXJhbXM6IGl0ZW0ucXVlcnlQYXJhbXMsXG4gICAgICAgIGZyYWdtZW50OiBpdGVtLmZyYWdtZW50LFxuICAgICAgICBxdWVyeVBhcmFtc0hhbmRsaW5nOiBpdGVtLnF1ZXJ5UGFyYW1zSGFuZGxpbmcsXG4gICAgICAgIHByZXNlcnZlRnJhZ21lbnQ6IGl0ZW0ucHJlc2VydmVGcmFnbWVudCxcbiAgICAgICAgc2tpcExvY2F0aW9uQ2hhbmdlOiBpdGVtLnNraXBMb2NhdGlvbkNoYW5nZSxcbiAgICAgICAgcmVwbGFjZVVybDogaXRlbS5yZXBsYWNlVXJsXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGl0ZW0uY29tbWFuZCkge1xuICAgICAgaXRlbS5jb21tYW5kKCk7XG4gICAgfVxuICB9XG59XG4iLCI8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGl0ZW1zOyBpbmRleCBhcyBpXCI+XG4gIDxwLWJ1dHRvblxuICAgICpuZ0lmPVwiIWl0ZW0uaXRlbXNcIlxuICAgIFtsYWJlbF09XCJpdGVtLmxhYmVsIVwiXG4gICAgW2ljb25dPVwiaXRlbS5pY29uIVwiXG4gICAgW2Rpc2FibGVkXT1cIml0ZW0uZGlzYWJsZWQhXCJcbiAgICBbc3R5bGVdPVwiaXRlbS5zdHlsZVwiXG4gICAgW3N0eWxlQ2xhc3NdPVwiaXRlbS5zdHlsZUNsYXNzIVwiXG4gICAgW3BUb29sdGlwXT1cIml0ZW0udG9vbHRpcCFcIlxuICAgIFt0b29sdGlwUG9zaXRpb25dPVwiaXRlbS50b29sdGlwUG9zaXRpb24hXCJcbiAgICAob25DbGljayk9XCJvbkNsaWNrKGl0ZW0pXCJcbiAgICBbY2xhc3MubWwtMl09XCJpID4gMFwiPlxuICA8L3AtYnV0dG9uPlxuXG4gIDxwLXNwbGl0QnV0dG9uXG4gICAgKm5nSWY9XCJpdGVtLml0ZW1zXCJcbiAgICBbbGFiZWxdPVwiaXRlbS5sYWJlbCFcIlxuICAgIFtpY29uXT1cIml0ZW0uaWNvbiFcIlxuICAgIFttb2RlbF09XCJpdGVtLml0ZW1zXCJcbiAgICBhcHBlbmRUbz1cImJvZHlcIlxuICAgIFtkaXNhYmxlZF09XCJpdGVtLmRpc2FibGVkIVwiXG4gICAgW3N0eWxlXT1cIml0ZW0uc3R5bGVcIlxuICAgIFtzdHlsZUNsYXNzXT1cIml0ZW0uc3R5bGVDbGFzcyFcIlxuICAgIFtwVG9vbHRpcF09XCJpdGVtLnRvb2x0aXAhXCJcbiAgICBbdG9vbHRpcFBvc2l0aW9uXT1cIml0ZW0udG9vbHRpcFBvc2l0aW9uIVwiXG4gICAgKG9uQ2xpY2spPVwib25DbGljayhpdGVtKVwiXG4gICAgW2NsYXNzLm1sLTJdPVwiaSA+IDBcIj5cbiAgPC9wLXNwbGl0QnV0dG9uPlxuPC9uZy1jb250YWluZXI+XG4iXX0=
|