@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.
Files changed (96) hide show
  1. package/esm2020/lib/components/restworld-file/restworld-file.component.mjs +57 -0
  2. package/esm2020/lib/components/restworld-form/restworld-form.component.mjs +188 -0
  3. package/esm2020/lib/components/restworld-id-navigation/restworld-id-navigation.component.mjs +65 -0
  4. package/esm2020/lib/components/restworld-image/restworld-image.component.mjs +164 -0
  5. package/esm2020/lib/components/restworld-inputs/restworld-inputs.mjs +306 -0
  6. package/esm2020/lib/components/restworld-label/restworld-label.component.mjs +24 -0
  7. package/esm2020/lib/components/restworld-menu-button/restworld-menu-button.component.mjs +40 -0
  8. package/esm2020/lib/components/restworld-table/restworld-table.component.mjs +157 -0
  9. package/esm2020/lib/components/restworld-validation-errors/restworld-validation-errors.component.mjs +21 -0
  10. package/esm2020/lib/models/o-data.mjs +2 -0
  11. package/esm2020/lib/models/restworld-image.mjs +2 -0
  12. package/esm2020/lib/models/restworld-options.mjs +2 -2
  13. package/esm2020/lib/models/special-properties.mjs +6 -0
  14. package/esm2020/lib/models/templating.mjs +2 -0
  15. package/esm2020/lib/restworld-client.module.mjs +83 -25
  16. package/esm2020/lib/services/o-data.service.mjs +6 -3
  17. package/esm2020/lib/services/restworld-client-collection.mjs +7 -7
  18. package/esm2020/lib/services/restworld-client.mjs +40 -29
  19. package/esm2020/lib/services/settings.service.mjs +5 -5
  20. package/esm2020/lib/views/restworld-edit-view/restworld-edit-view.component.mjs +24 -255
  21. package/esm2020/lib/views/restworld-list-view/restworld-list-view.component.mjs +49 -101
  22. package/esm2020/public-api.mjs +17 -6
  23. package/fesm2015/wertzui-ngx-restworld-client.mjs +1373 -1017
  24. package/fesm2015/wertzui-ngx-restworld-client.mjs.map +1 -1
  25. package/fesm2020/wertzui-ngx-restworld-client.mjs +1322 -978
  26. package/fesm2020/wertzui-ngx-restworld-client.mjs.map +1 -1
  27. package/index.d.ts +1 -0
  28. package/lib/components/restworld-avatar/restworld-avatar.component.d.ts +1 -0
  29. package/lib/components/restworld-avatar/restworld-avatar.component.d.ts.map +1 -0
  30. package/lib/{views/restworld-file-view/restworld-file-view.component.d.ts → components/restworld-file/restworld-file.component.d.ts} +4 -3
  31. package/lib/components/restworld-file/restworld-file.component.d.ts.map +1 -0
  32. package/lib/components/restworld-form/restworld-form.component.d.ts +53 -0
  33. package/lib/components/restworld-form/restworld-form.component.d.ts.map +1 -0
  34. package/lib/components/restworld-id-navigation/restworld-id-navigation.component.d.ts +27 -0
  35. package/lib/components/restworld-id-navigation/restworld-id-navigation.component.d.ts.map +1 -0
  36. package/lib/components/restworld-image/restworld-image.component.d.ts +62 -0
  37. package/lib/components/restworld-image/restworld-image.component.d.ts.map +1 -0
  38. package/lib/components/restworld-inputs/restworld-inputs.d.ts +146 -0
  39. package/lib/components/restworld-inputs/restworld-inputs.d.ts.map +1 -0
  40. package/lib/components/restworld-label/restworld-label.component.d.ts +14 -0
  41. package/lib/components/restworld-label/restworld-label.component.d.ts.map +1 -0
  42. package/lib/components/restworld-menu-button/restworld-menu-button.component.d.ts +12 -0
  43. package/lib/components/restworld-menu-button/restworld-menu-button.component.d.ts.map +1 -0
  44. package/lib/components/restworld-table/restworld-table.component.d.ts +54 -0
  45. package/lib/components/restworld-table/restworld-table.component.d.ts.map +1 -0
  46. package/lib/components/restworld-validation-errors/restworld-validation-errors.component.d.ts +15 -0
  47. package/lib/components/restworld-validation-errors/restworld-validation-errors.component.d.ts.map +1 -0
  48. package/lib/constants/link-names.d.ts +1 -0
  49. package/lib/constants/link-names.d.ts.map +1 -0
  50. package/lib/models/api-url.d.ts +1 -0
  51. package/lib/models/api-url.d.ts.map +1 -0
  52. package/lib/models/client-settings.d.ts +1 -0
  53. package/lib/models/client-settings.d.ts.map +1 -0
  54. package/lib/models/o-data.d.ts +7 -0
  55. package/lib/models/o-data.d.ts.map +1 -0
  56. package/lib/models/problem-details.d.ts +1 -0
  57. package/lib/models/problem-details.d.ts.map +1 -0
  58. package/lib/models/restworld-image.d.ts +28 -0
  59. package/lib/models/restworld-image.d.ts.map +1 -0
  60. package/lib/models/restworld-options.d.ts +2 -1
  61. package/lib/models/restworld-options.d.ts.map +1 -0
  62. package/lib/models/special-properties.d.ts +9 -0
  63. package/lib/models/special-properties.d.ts.map +1 -0
  64. package/lib/models/templating.d.ts +8 -0
  65. package/lib/models/templating.d.ts.map +1 -0
  66. package/lib/pipes/as.pipe.d.ts +1 -0
  67. package/lib/pipes/as.pipe.d.ts.map +1 -0
  68. package/lib/pipes/safe-url.pipe.d.ts +1 -0
  69. package/lib/pipes/safe-url.pipe.d.ts.map +1 -0
  70. package/lib/restworld-client.module.d.ts +45 -37
  71. package/lib/restworld-client.module.d.ts.map +1 -0
  72. package/lib/services/avatar-generator.d.ts +1 -0
  73. package/lib/services/avatar-generator.d.ts.map +1 -0
  74. package/lib/services/form.service.d.ts +1 -0
  75. package/lib/services/form.service.d.ts.map +1 -0
  76. package/lib/services/o-data.service.d.ts +1 -0
  77. package/lib/services/o-data.service.d.ts.map +1 -0
  78. package/lib/services/restworld-client-collection.d.ts +9 -8
  79. package/lib/services/restworld-client-collection.d.ts.map +1 -0
  80. package/lib/services/restworld-client.d.ts +12 -4
  81. package/lib/services/restworld-client.d.ts.map +1 -0
  82. package/lib/services/settings.service.d.ts +3 -2
  83. package/lib/services/settings.service.d.ts.map +1 -0
  84. package/lib/views/restworld-edit-view/restworld-edit-view.component.d.ts +16 -68
  85. package/lib/views/restworld-edit-view/restworld-edit-view.component.d.ts.map +1 -0
  86. package/lib/views/restworld-list-view/restworld-list-view.component.d.ts +25 -41
  87. package/lib/views/restworld-list-view/restworld-list-view.component.d.ts.map +1 -0
  88. package/package.json +6 -6
  89. package/public-api.d.ts +17 -5
  90. package/public-api.d.ts.map +1 -0
  91. package/wertzui-ngx-restworld-client.d.ts.map +1 -0
  92. package/esm2020/lib/views/restworld-edit-form/restworld-edit-form.component.mjs +0 -233
  93. package/esm2020/lib/views/restworld-file-view/restworld-file-view.component.mjs +0 -57
  94. package/esm2020/lib/views/restworld-image-view/restworld-image-view.component.mjs +0 -139
  95. package/lib/views/restworld-edit-form/restworld-edit-form.component.d.ts +0 -74
  96. 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=