tango-app-ui-store-builder 1.0.1-beta-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +24 -0
  2. package/esm2022/lib/components/create-layout/create-layout.component.mjs +1815 -0
  3. package/esm2022/lib/components/create-layout/popups/add-floor/add-floor.component.mjs +40 -0
  4. package/esm2022/lib/components/create-layout/popups/clear-all-steps/clear-all-steps.component.mjs +16 -0
  5. package/esm2022/lib/components/create-layout/popups/delete-layout/delete-layout.component.mjs +16 -0
  6. package/esm2022/lib/components/custom-select/custom-select.component.mjs +155 -0
  7. package/esm2022/lib/components/layout-builder/layout-builder.component.mjs +56 -0
  8. package/esm2022/lib/components/layout-summary/layout-summary.component.mjs +809 -0
  9. package/esm2022/lib/components/layout-summary/popups/complete-layout/complete-layout.component.mjs +16 -0
  10. package/esm2022/lib/components/reactive-select/reactive-select.component.mjs +87 -0
  11. package/esm2022/lib/components/store-layout-table/store-layout-table.component.mjs +709 -0
  12. package/esm2022/lib/components/store-offcanvas-component/store-offcanvas-component.component.mjs +99 -0
  13. package/esm2022/lib/interfaces/layout-builder.interface.mjs +2 -0
  14. package/esm2022/lib/services/store-builder.service.mjs +99 -0
  15. package/esm2022/lib/tango-store-builder-routing.module.mjs +41 -0
  16. package/esm2022/lib/tango-store-builder.module.mjs +71 -0
  17. package/esm2022/public-api.mjs +5 -0
  18. package/esm2022/tango-app-ui-store-builder.mjs +5 -0
  19. package/esm2022/tango-store-builder.mjs +5 -0
  20. package/fesm2022/tango-app-ui-store-builder.mjs +3947 -0
  21. package/fesm2022/tango-app-ui-store-builder.mjs.map +1 -0
  22. package/fesm2022/tango-store-builder.mjs +3947 -0
  23. package/fesm2022/tango-store-builder.mjs.map +1 -0
  24. package/index.d.ts +5 -0
  25. package/lib/components/create-layout/create-layout.component.d.ts +197 -0
  26. package/lib/components/create-layout/popups/add-floor/add-floor.component.d.ts +16 -0
  27. package/lib/components/create-layout/popups/clear-all-steps/clear-all-steps.component.d.ts +8 -0
  28. package/lib/components/create-layout/popups/delete-layout/delete-layout.component.d.ts +8 -0
  29. package/lib/components/custom-select/custom-select.component.d.ts +33 -0
  30. package/lib/components/layout-builder/layout-builder.component.d.ts +18 -0
  31. package/lib/components/layout-summary/layout-summary.component.d.ts +92 -0
  32. package/lib/components/layout-summary/popups/complete-layout/complete-layout.component.d.ts +8 -0
  33. package/lib/components/reactive-select/reactive-select.component.d.ts +26 -0
  34. package/lib/components/store-layout-table/store-layout-table.component.d.ts +73 -0
  35. package/lib/components/store-offcanvas-component/store-offcanvas-component.component.d.ts +26 -0
  36. package/lib/interfaces/layout-builder.interface.d.ts +23 -0
  37. package/lib/services/store-builder.service.d.ts +33 -0
  38. package/lib/tango-store-builder-routing.module.d.ts +7 -0
  39. package/lib/tango-store-builder.module.d.ts +22 -0
  40. package/package.json +25 -0
  41. package/public-api.d.ts +1 -0
@@ -0,0 +1,16 @@
1
+ import { Component } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@ng-bootstrap/ng-bootstrap";
4
+ export class CompleteLayoutComponent {
5
+ modal;
6
+ constructor(modal) {
7
+ this.modal = modal;
8
+ }
9
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CompleteLayoutComponent, deps: [{ token: i1.NgbActiveModal }], target: i0.ɵɵFactoryTarget.Component });
10
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CompleteLayoutComponent, selector: "lib-complete-layout", ngImport: i0, template: "<div class=\"header mb-5\" >\r\n Complete layout\r\n</div>\r\n<div class=\"description mb-7\">\r\n Are you sure you want to finalize this layout? You can always return and make edits before submitting it for fixture validation.\r\n</div>\r\n<div class=\"d-flex align-items-center justify-content-end\">\r\n <button class=\"btn btn-outline bg-white me-5\" (click)=\"modal.close()\" >Cancel</button>\r\n <button class=\"btn btn-sm btn-primary\" (click)=\"modal.close({message:'confirm'})\">Complete</button>\r\n</div>", styles: [":host{padding:24px}.header{color:#000;font-family:Inter;font-size:18px;font-style:normal;font-weight:600;line-height:28px}.description{color:#1d2939;font-family:Inter;font-size:16px;font-style:normal;font-weight:400;line-height:24px}\n"] });
11
+ }
12
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CompleteLayoutComponent, decorators: [{
13
+ type: Component,
14
+ args: [{ selector: 'lib-complete-layout', standalone: false, template: "<div class=\"header mb-5\" >\r\n Complete layout\r\n</div>\r\n<div class=\"description mb-7\">\r\n Are you sure you want to finalize this layout? You can always return and make edits before submitting it for fixture validation.\r\n</div>\r\n<div class=\"d-flex align-items-center justify-content-end\">\r\n <button class=\"btn btn-outline bg-white me-5\" (click)=\"modal.close()\" >Cancel</button>\r\n <button class=\"btn btn-sm btn-primary\" (click)=\"modal.close({message:'confirm'})\">Complete</button>\r\n</div>", styles: [":host{padding:24px}.header{color:#000;font-family:Inter;font-size:18px;font-style:normal;font-weight:600;line-height:28px}.description{color:#1d2939;font-family:Inter;font-size:16px;font-style:normal;font-weight:400;line-height:24px}\n"] }]
15
+ }], ctorParameters: () => [{ type: i1.NgbActiveModal }] });
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxldGUtbGF5b3V0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLXN0b3JlLWJ1aWxkZXIvc3JjL2xpYi9jb21wb25lbnRzL2xheW91dC1zdW1tYXJ5L3BvcHVwcy9jb21wbGV0ZS1sYXlvdXQvY29tcGxldGUtbGF5b3V0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLXN0b3JlLWJ1aWxkZXIvc3JjL2xpYi9jb21wb25lbnRzL2xheW91dC1zdW1tYXJ5L3BvcHVwcy9jb21wbGV0ZS1sYXlvdXQvY29tcGxldGUtbGF5b3V0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7OztBQVMxQyxNQUFNLE9BQU8sdUJBQXVCO0lBQ2I7SUFBbkIsWUFBbUIsS0FBb0I7UUFBcEIsVUFBSyxHQUFMLEtBQUssQ0FBZTtJQUFFLENBQUM7d0dBRGpDLHVCQUF1Qjs0RkFBdkIsdUJBQXVCLDJEQ1RwQyxpaEJBU007OzRGREFPLHVCQUF1QjtrQkFObkMsU0FBUzsrQkFDRSxxQkFBcUIsY0FDbkIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBOZ2JBY3RpdmVNb2RhbCB9IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbGliLWNvbXBsZXRlLWxheW91dCcsXHJcbiAgc3RhbmRhbG9uZTogZmFsc2UsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2NvbXBsZXRlLWxheW91dC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL2NvbXBsZXRlLWxheW91dC5jb21wb25lbnQuc2NzcydcclxufSlcclxuZXhwb3J0IGNsYXNzIENvbXBsZXRlTGF5b3V0Q29tcG9uZW50IHtcclxuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBtb2RhbDpOZ2JBY3RpdmVNb2RhbCl7fVxyXG4gIFxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJoZWFkZXIgbWItNVwiID5cclxuICAgIENvbXBsZXRlIGxheW91dFxyXG48L2Rpdj5cclxuPGRpdiBjbGFzcz1cImRlc2NyaXB0aW9uIG1iLTdcIj5cclxuICAgIEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBmaW5hbGl6ZSB0aGlzIGxheW91dD8gWW91IGNhbiBhbHdheXMgcmV0dXJuIGFuZCBtYWtlIGVkaXRzIGJlZm9yZSBzdWJtaXR0aW5nIGl0IGZvciBmaXh0dXJlIHZhbGlkYXRpb24uXHJcbjwvZGl2PlxyXG48ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtZW5kXCI+XHJcbiAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lIGJnLXdoaXRlIG1lLTVcIiAoY2xpY2spPVwibW9kYWwuY2xvc2UoKVwiID5DYW5jZWw8L2J1dHRvbj5cclxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1wcmltYXJ5XCIgKGNsaWNrKT1cIm1vZGFsLmNsb3NlKHttZXNzYWdlOidjb25maXJtJ30pXCI+Q29tcGxldGU8L2J1dHRvbj5cclxuPC9kaXY+Il19
@@ -0,0 +1,87 @@
1
+ import { Component, HostListener, Input, forwardRef } from '@angular/core';
2
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/common";
5
+ const SELECT_CONTROL_VALUE_ACCESSOR = {
6
+ provide: NG_VALUE_ACCESSOR,
7
+ useExisting: forwardRef(() => ReactiveSelectComponent),
8
+ multi: true,
9
+ };
10
+ export class ReactiveSelectComponent {
11
+ cd;
12
+ onTouched;
13
+ onChanged;
14
+ isDisabled;
15
+ idField;
16
+ nameField;
17
+ label;
18
+ data;
19
+ isOpened = false;
20
+ selected = null;
21
+ selectedId;
22
+ constructor(cd) {
23
+ this.cd = cd;
24
+ }
25
+ writeValue(val) {
26
+ setTimeout(() => {
27
+ this.selectedId = val;
28
+ this.selected = this.data.filter((item) => item?.[this.idField] === val)[0];
29
+ this.cd.detectChanges();
30
+ }, 0);
31
+ }
32
+ registerOnChange(fn) {
33
+ this.onChanged = fn;
34
+ }
35
+ registerOnTouched(fn) {
36
+ this.onTouched = fn;
37
+ }
38
+ setDisabledState(isDisabled) {
39
+ this.isDisabled = isDisabled;
40
+ }
41
+ onSelect(item) {
42
+ this.onTouched();
43
+ this.selected = item;
44
+ this.selectedId = item?.[this.idField];
45
+ this.isOpened = false;
46
+ this.onChanged(this.selectedId);
47
+ }
48
+ onClick(event) {
49
+ if (!this.isDisabled) {
50
+ const targetElement = event.target;
51
+ if (!this.isComponentClicked(targetElement)) {
52
+ this.isOpened = false;
53
+ }
54
+ }
55
+ }
56
+ isComponentClicked(targetElement) {
57
+ const parentElement = targetElement.parentElement;
58
+ if (parentElement) {
59
+ const clickedOnComponent = parentElement.classList.contains('custom-select');
60
+ if (clickedOnComponent) {
61
+ return true;
62
+ }
63
+ else {
64
+ return this.isComponentClicked(parentElement);
65
+ }
66
+ }
67
+ return false;
68
+ }
69
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ReactiveSelectComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
70
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ReactiveSelectComponent, selector: "lib-reactive-select", inputs: { idField: "idField", nameField: "nameField", label: "label", data: "data" }, host: { listeners: { "document:click": "onClick($event)" } }, providers: [SELECT_CONTROL_VALUE_ACCESSOR], ngImport: i0, template: "<div class=\"custom-select\">\r\n <div class=\"form-group\">\r\n <label *ngIf=\"label\" class=\"form-label\">{{label}}</label>\r\n <div class=\"position-relative\">\r\n <div (click)=\"isOpened = !isOpened;\" [ngClass]=\"isDisabled ? 'disable' : ''\" class=\"form-select dropselect\">\r\n {{selected?.[nameField]}}</div>\r\n <div *ngIf=\"isOpened\" class=\"card py-2 w-100 position-absolute end-0 z-1 drop-list\">\r\n <ul class=\"list-unstyled mb-2\">\r\n <li *ngFor=\"let item of data\" (click)=\"onSelect(item)\"\r\n [ngClass]=\"item?.[idField] === selected?.[idField] ? 'active' : ''\"\r\n class=\"text px-5 items cursor-pointer py-4\">\r\n {{item?.[nameField]}}\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".custom-select{min-width:100px}.custom-select .items:hover,.custom-select .tems.focus,.custom-select .items.active,.custom-select .camera.focus-visible{background:var(--Gray-50, #F9FAFB)}.custom-select .drop-list{max-height:300px;overflow-y:auto}.custom-select .dropselect{color:var(--Gray-500, #667085);font-size:14px;font-style:normal;font-weight:600;line-height:20px;height:45px!important;cursor:default;white-space:nowrap}.custom-select .text{color:var(--Gray-700, #344054);font-size:14px;font-weight:500;line-height:20px}.custom-select .disable{pointer-events:none;background-color:#f9fafb!important}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
71
+ }
72
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ReactiveSelectComponent, decorators: [{
73
+ type: Component,
74
+ args: [{ selector: 'lib-reactive-select', providers: [SELECT_CONTROL_VALUE_ACCESSOR], template: "<div class=\"custom-select\">\r\n <div class=\"form-group\">\r\n <label *ngIf=\"label\" class=\"form-label\">{{label}}</label>\r\n <div class=\"position-relative\">\r\n <div (click)=\"isOpened = !isOpened;\" [ngClass]=\"isDisabled ? 'disable' : ''\" class=\"form-select dropselect\">\r\n {{selected?.[nameField]}}</div>\r\n <div *ngIf=\"isOpened\" class=\"card py-2 w-100 position-absolute end-0 z-1 drop-list\">\r\n <ul class=\"list-unstyled mb-2\">\r\n <li *ngFor=\"let item of data\" (click)=\"onSelect(item)\"\r\n [ngClass]=\"item?.[idField] === selected?.[idField] ? 'active' : ''\"\r\n class=\"text px-5 items cursor-pointer py-4\">\r\n {{item?.[nameField]}}\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".custom-select{min-width:100px}.custom-select .items:hover,.custom-select .tems.focus,.custom-select .items.active,.custom-select .camera.focus-visible{background:var(--Gray-50, #F9FAFB)}.custom-select .drop-list{max-height:300px;overflow-y:auto}.custom-select .dropselect{color:var(--Gray-500, #667085);font-size:14px;font-style:normal;font-weight:600;line-height:20px;height:45px!important;cursor:default;white-space:nowrap}.custom-select .text{color:var(--Gray-700, #344054);font-size:14px;font-weight:500;line-height:20px}.custom-select .disable{pointer-events:none;background-color:#f9fafb!important}\n"] }]
75
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { idField: [{
76
+ type: Input
77
+ }], nameField: [{
78
+ type: Input
79
+ }], label: [{
80
+ type: Input
81
+ }], data: [{
82
+ type: Input
83
+ }], onClick: [{
84
+ type: HostListener,
85
+ args: ['document:click', ['$event']]
86
+ }] } });
87
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3RpdmUtc2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLXN0b3JlLWJ1aWxkZXIvc3JjL2xpYi9jb21wb25lbnRzL3JlYWN0aXZlLXNlbGVjdC9yZWFjdGl2ZS1zZWxlY3QuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tc3RvcmUtYnVpbGRlci9zcmMvbGliL2NvbXBvbmVudHMvcmVhY3RpdmUtc2VsZWN0L3JlYWN0aXZlLXNlbGVjdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXFCLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFZLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RyxPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztBQUV6RSxNQUFNLDZCQUE2QixHQUFhO0lBQzlDLE9BQU8sRUFBRSxpQkFBaUI7SUFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQztJQUN0RCxLQUFLLEVBQUUsSUFBSTtDQUNaLENBQUM7QUFRRixNQUFNLE9BQU8sdUJBQXVCO0lBYWQ7SUFYWixTQUFTLENBQVc7SUFDcEIsU0FBUyxDQUFXO0lBQ2xCLFVBQVUsQ0FBVTtJQUNyQixPQUFPLENBQVE7SUFDZixTQUFTLENBQVE7SUFDakIsS0FBSyxDQUFRO0lBQ2IsSUFBSSxDQUFLO0lBQ1IsUUFBUSxHQUFZLEtBQUssQ0FBQTtJQUN6QixRQUFRLEdBQStCLElBQUksQ0FBQTtJQUMzQyxVQUFVLENBQWlCO0lBRXJDLFlBQW9CLEVBQW9CO1FBQXBCLE9BQUUsR0FBRixFQUFFLENBQWtCO0lBQUUsQ0FBQztJQUUzQyxVQUFVLENBQUMsR0FBb0I7UUFDN0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNoQixJQUFJLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQTtZQUNyQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBd0IsRUFBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQzlGLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLENBQUE7UUFDdkIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQztJQUNELGdCQUFnQixDQUFDLEVBQU87UUFDdEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUE7SUFDckIsQ0FBQztJQUNELGlCQUFpQixDQUFDLEVBQU87UUFDdkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUE7SUFDckIsQ0FBQztJQUNELGdCQUFnQixDQUFFLFVBQW1CO1FBQ25DLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFBO0lBQzlCLENBQUM7SUFFRCxRQUFRLENBQUMsSUFBeUI7UUFDaEMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFBO1FBQ2hCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFBO1FBQ3BCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ3RDLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFBO1FBQ3JCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ2pDLENBQUM7SUFHRCxPQUFPLENBQUMsS0FBaUI7UUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDcEIsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLE1BQXFCLENBQUM7WUFDbEQsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLENBQUMsRUFBRTtnQkFDM0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7YUFDdkI7U0FDRjtJQUNILENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxhQUEwQjtRQUMzQyxNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUMsYUFBYSxDQUFDO1FBQ2xELElBQUksYUFBYSxFQUFFO1lBQ2pCLE1BQU0sa0JBQWtCLEdBQUcsYUFBYSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDN0UsSUFBSSxrQkFBa0IsRUFBRTtnQkFDdEIsT0FBTyxJQUFJLENBQUM7YUFDYjtpQkFBTTtnQkFDTCxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLENBQUMsQ0FBQzthQUMvQztTQUNGO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO3dHQTdEVSx1QkFBdUI7NEZBQXZCLHVCQUF1QixrTUFGdkIsQ0FBQyw2QkFBNkIsQ0FBQywwQkNiNUMsNjZCQWlCTTs7NEZERk8sdUJBQXVCO2tCQU5uQyxTQUFTOytCQUNFLHFCQUFxQixhQUdwQixDQUFDLDZCQUE2QixDQUFDO3NGQU9qQyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQWlDTixPQUFPO3NCQUROLFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBIb3N0TGlzdGVuZXIsIElucHV0LCBQcm92aWRlciwgZm9yd2FyZFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcblxyXG5jb25zdCBTRUxFQ1RfQ09OVFJPTF9WQUxVRV9BQ0NFU1NPUjogUHJvdmlkZXIgPSB7XHJcbiAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gUmVhY3RpdmVTZWxlY3RDb21wb25lbnQpLFxyXG4gIG11bHRpOiB0cnVlLFxyXG59O1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdsaWItcmVhY3RpdmUtc2VsZWN0JyxcclxuICB0ZW1wbGF0ZVVybDogJy4vcmVhY3RpdmUtc2VsZWN0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybDogJy4vcmVhY3RpdmUtc2VsZWN0LmNvbXBvbmVudC5zY3NzJyxcclxuICBwcm92aWRlcnM6IFtTRUxFQ1RfQ09OVFJPTF9WQUxVRV9BQ0NFU1NPUl1cclxufSlcclxuZXhwb3J0IGNsYXNzIFJlYWN0aXZlU2VsZWN0Q29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xyXG5cclxuICBwcml2YXRlIG9uVG91Y2hlZDogRnVuY3Rpb247XHJcbiAgcHJpdmF0ZSBvbkNoYW5nZWQ6IEZ1bmN0aW9uO1xyXG4gIHByb3RlY3RlZCBpc0Rpc2FibGVkOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGlkRmllbGQ6IHN0cmluZ1xyXG4gIEBJbnB1dCgpIG5hbWVGaWVsZDogc3RyaW5nXHJcbiAgQElucHV0KCkgbGFiZWw6IHN0cmluZ1xyXG4gIEBJbnB1dCgpIGRhdGE6IGFueVxyXG4gIHByb3RlY3RlZCBpc09wZW5lZDogYm9vbGVhbiA9IGZhbHNlXHJcbiAgcHJvdGVjdGVkIHNlbGVjdGVkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgbnVsbCA9IG51bGxcclxuICBwcm90ZWN0ZWQgc2VsZWN0ZWRJZDogc3RyaW5nIHwgbnVtYmVyXHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2Q6Q2hhbmdlRGV0ZWN0b3JSZWYpe31cclxuXHJcbiAgd3JpdGVWYWx1ZSh2YWw6IHN0cmluZyB8IG51bWJlcik6IHZvaWQge1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7ICAgICAgXHJcbiAgICB0aGlzLnNlbGVjdGVkSWQgPSB2YWxcclxuICAgIHRoaXMuc2VsZWN0ZWQgPSB0aGlzLmRhdGEuZmlsdGVyKChpdGVtOlJlY29yZDxzdHJpbmcsIGFueT4pPT4gaXRlbT8uW3RoaXMuaWRGaWVsZF0gPT09IHZhbClbMF0gIFxyXG4gICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKClcclxuICAgIH0sIDApOyAgXHJcbiAgfVxyXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5vbkNoYW5nZWQgPSBmblxyXG4gIH1cclxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuXHJcbiAgfVxyXG4gIHNldERpc2FibGVkU3RhdGU/KGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIHRoaXMuaXNEaXNhYmxlZCA9IGlzRGlzYWJsZWRcclxuICB9XHJcblxyXG4gIG9uU2VsZWN0KGl0ZW06IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcclxuICAgIHRoaXMub25Ub3VjaGVkKClcclxuICAgIHRoaXMuc2VsZWN0ZWQgPSBpdGVtXHJcbiAgICB0aGlzLnNlbGVjdGVkSWQgPSBpdGVtPy5bdGhpcy5pZEZpZWxkXSAgICBcclxuICAgIHRoaXMuaXNPcGVuZWQgPSBmYWxzZVxyXG4gICAgdGhpcy5vbkNoYW5nZWQodGhpcy5zZWxlY3RlZElkKVxyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxyXG4gIG9uQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIGlmICghdGhpcy5pc0Rpc2FibGVkKSB7XHJcbiAgICAgIGNvbnN0IHRhcmdldEVsZW1lbnQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgIGlmICghdGhpcy5pc0NvbXBvbmVudENsaWNrZWQodGFyZ2V0RWxlbWVudCkpIHtcclxuICAgICAgICB0aGlzLmlzT3BlbmVkID0gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlzQ29tcG9uZW50Q2xpY2tlZCh0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgcGFyZW50RWxlbWVudCA9IHRhcmdldEVsZW1lbnQucGFyZW50RWxlbWVudDtcclxuICAgIGlmIChwYXJlbnRFbGVtZW50KSB7XHJcbiAgICAgIGNvbnN0IGNsaWNrZWRPbkNvbXBvbmVudCA9IHBhcmVudEVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdjdXN0b20tc2VsZWN0Jyk7XHJcbiAgICAgIGlmIChjbGlja2VkT25Db21wb25lbnQpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pc0NvbXBvbmVudENsaWNrZWQocGFyZW50RWxlbWVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG5cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiY3VzdG9tLXNlbGVjdFwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cclxuICAgICAgICA8bGFiZWwgKm5nSWY9XCJsYWJlbFwiIGNsYXNzPVwiZm9ybS1sYWJlbFwiPnt7bGFiZWx9fTwvbGFiZWw+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInBvc2l0aW9uLXJlbGF0aXZlXCI+XHJcbiAgICAgICAgICAgIDxkaXYgKGNsaWNrKT1cImlzT3BlbmVkID0gIWlzT3BlbmVkO1wiIFtuZ0NsYXNzXT1cImlzRGlzYWJsZWQgPyAnZGlzYWJsZScgOiAnJ1wiIGNsYXNzPVwiZm9ybS1zZWxlY3QgZHJvcHNlbGVjdFwiPlxyXG4gICAgICAgICAgICAgICAge3tzZWxlY3RlZD8uW25hbWVGaWVsZF19fTwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNPcGVuZWRcIiBjbGFzcz1cImNhcmQgcHktMiB3LTEwMCBwb3NpdGlvbi1hYnNvbHV0ZSBlbmQtMCB6LTEgZHJvcC1saXN0XCI+XHJcbiAgICAgICAgICAgICAgICA8dWwgY2xhc3M9XCJsaXN0LXVuc3R5bGVkIG1iLTJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bGkgKm5nRm9yPVwibGV0IGl0ZW0gb2YgZGF0YVwiIChjbGljayk9XCJvblNlbGVjdChpdGVtKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIml0ZW0/LltpZEZpZWxkXSA9PT0gc2VsZWN0ZWQ/LltpZEZpZWxkXSA/ICdhY3RpdmUnIDogJydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQgcHgtNSBpdGVtcyBjdXJzb3ItcG9pbnRlciBweS00XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHt7aXRlbT8uW25hbWVGaWVsZF19fVxyXG4gICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICA8L3VsPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L2Rpdj4iXX0=