@rangertechnologies/ngnxt 2.1.230 → 2.1.232
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/environments/version.mjs +5 -5
- package/esm2022/lib/components/datatable/datatable.component.mjs +6 -1
- package/esm2022/lib/components/icon-selector/icon-selector.component.mjs +139 -0
- package/esm2022/lib/components/list-view-filter/list-view-filter.component.mjs +3 -3
- package/esm2022/lib/nxt-app.module.mjs +7 -1
- package/esm2022/lib/pages/booklet/booklet.component.mjs +14 -38
- package/esm2022/lib/pages/builder/element/element.component.mjs +4 -3
- package/esm2022/lib/pages/builder/properties/properties.component.mjs +2 -1
- package/esm2022/lib/pages/questionbook/questionbook.component.mjs +15 -52
- package/esm2022/lib/pages/questionnaire/questionnaire.component.mjs +3 -4
- package/esm2022/lib/services/change.service.mjs +7 -8
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/rangertechnologies-ngnxt.mjs +225 -147
- package/fesm2022/rangertechnologies-ngnxt.mjs.map +1 -1
- package/lib/components/icon-selector/icon-selector.component.d.ts +43 -0
- package/lib/nxt-app.module.d.ts +5 -4
- package/lib/pages/booklet/booklet.component.d.ts +4 -1
- package/lib/pages/builder/properties/properties.component.d.ts +5 -0
- package/lib/pages/questionbook/questionbook.component.d.ts +4 -1
- package/lib/services/change.service.d.ts +4 -5
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/rangertechnologies-ngnxt-2.1.232.tgz +0 -0
- package/rangertechnologies-ngnxt-2.1.230.tgz +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
//MSM10JUL25
|
|
2
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { finalize, map, Subject, takeUntil } from 'rxjs';
|
|
5
|
+
import { FormsModule } from '@angular/forms';
|
|
6
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "@angular/common/http";
|
|
9
|
+
import * as i2 from "@angular/platform-browser";
|
|
10
|
+
import * as i3 from "@angular/common";
|
|
11
|
+
import * as i4 from "@angular/forms";
|
|
12
|
+
import * as i5 from "@angular/material/tooltip";
|
|
13
|
+
export class IconSelectorComponent {
|
|
14
|
+
http;
|
|
15
|
+
sanitizer;
|
|
16
|
+
cdr;
|
|
17
|
+
allIcons;
|
|
18
|
+
themeColor = '#ff0000'; // Default theme color
|
|
19
|
+
height = '300px'; // Default height
|
|
20
|
+
tooltipPosition = "above"; // above, below, left, right, before, after
|
|
21
|
+
selectedIcon; // Selected icon name
|
|
22
|
+
cdnIconURL = ""; // CDN URL for icons
|
|
23
|
+
label = ''; // Input label
|
|
24
|
+
labelFont = ''; // Input label font
|
|
25
|
+
labelWeight = ''; // Input label Weight
|
|
26
|
+
inputWeight = ''; // Input Weight
|
|
27
|
+
labelSize = ''; // Input label Size
|
|
28
|
+
labelColor = ''; // Input label Color
|
|
29
|
+
showLabel = ''; // Input label Color
|
|
30
|
+
required = false; // Required validation
|
|
31
|
+
mode = 'edit'; // New mode input
|
|
32
|
+
question = {};
|
|
33
|
+
options = []; // For radio buttons
|
|
34
|
+
iconSelected = new EventEmitter(); // Event emitter for selected icon
|
|
35
|
+
svgCache = new Map(); // Cache for better performance
|
|
36
|
+
destroyed = new Subject();
|
|
37
|
+
filteredIcons = [];
|
|
38
|
+
searchQuery = '';
|
|
39
|
+
showDropdown = false;
|
|
40
|
+
constructor(http, sanitizer, cdr) {
|
|
41
|
+
this.http = http;
|
|
42
|
+
this.sanitizer = sanitizer;
|
|
43
|
+
this.cdr = cdr;
|
|
44
|
+
}
|
|
45
|
+
ngOnInit() {
|
|
46
|
+
this.filteredIcons = this.allIcons != null && this.allIcons.length > 0 ? [...this.allIcons] : [];
|
|
47
|
+
}
|
|
48
|
+
filterIcons() {
|
|
49
|
+
if (!this.searchQuery) {
|
|
50
|
+
this.filteredIcons = this.allIcons != null && this.allIcons.length > 0 ? [...this.allIcons] : [];
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
this.filteredIcons = this.allIcons?.filter((icon) => icon?.name?.toLowerCase().includes(this.searchQuery?.toLowerCase()));
|
|
54
|
+
}
|
|
55
|
+
selectIcon(icon) {
|
|
56
|
+
this.selectedIcon = icon;
|
|
57
|
+
this.iconSelected.emit(icon);
|
|
58
|
+
}
|
|
59
|
+
getSanitizedSvg(filename) {
|
|
60
|
+
// Return cached or loading SVG
|
|
61
|
+
return this.svgCache.get(filename) || this.loadSvg(filename);
|
|
62
|
+
}
|
|
63
|
+
loadSvg(filename) {
|
|
64
|
+
const loadingSvg = this.sanitizer.bypassSecurityTrustHtml(`<svg width="48" height="48" viewBox="0 0 24 24"></svg>`);
|
|
65
|
+
this.svgCache.set(filename, loadingSvg);
|
|
66
|
+
this.http.get(this.getIconUrl(filename), { responseType: 'text' })
|
|
67
|
+
.pipe(takeUntil(this.destroyed), map(svgData => this.processSvg(svgData, this.themeColor)), finalize(() => this.cdr.markForCheck()) // Safe change detection
|
|
68
|
+
)
|
|
69
|
+
.subscribe({
|
|
70
|
+
next: processedSvg => this.svgCache.set(filename, processedSvg),
|
|
71
|
+
error: () => this.svgCache.set(filename, loadingSvg)
|
|
72
|
+
});
|
|
73
|
+
return loadingSvg;
|
|
74
|
+
}
|
|
75
|
+
processSvg(svgData, color) {
|
|
76
|
+
const div = document.createElement('div');
|
|
77
|
+
div.innerHTML = svgData;
|
|
78
|
+
const svg = div.querySelector('svg');
|
|
79
|
+
if (svg) {
|
|
80
|
+
svg.querySelectorAll('[fill]:not([fill="none"]), [stroke]:not([stroke="none"])')
|
|
81
|
+
.forEach(el => {
|
|
82
|
+
if (el.hasAttribute('fill'))
|
|
83
|
+
el.setAttribute('fill', color);
|
|
84
|
+
if (el.hasAttribute('stroke'))
|
|
85
|
+
el.setAttribute('stroke', color);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return this.sanitizer.bypassSecurityTrustHtml(div.innerHTML);
|
|
89
|
+
}
|
|
90
|
+
getIconUrl(fileName) {
|
|
91
|
+
return `${this.cdnIconURL}${fileName}`;
|
|
92
|
+
}
|
|
93
|
+
toggleDropdown() {
|
|
94
|
+
this.showDropdown = !this.showDropdown;
|
|
95
|
+
}
|
|
96
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: IconSelectorComponent, deps: [{ token: i1.HttpClient }, { token: i2.DomSanitizer }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
97
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: IconSelectorComponent, isStandalone: true, selector: "nxt-icon-selector", inputs: { allIcons: "allIcons", themeColor: "themeColor", height: "height", tooltipPosition: "tooltipPosition", selectedIcon: "selectedIcon", cdnIconURL: "cdnIconURL", label: "label", labelFont: "labelFont", labelWeight: "labelWeight", inputWeight: "inputWeight", labelSize: "labelSize", labelColor: "labelColor", showLabel: "showLabel", required: "required", mode: "mode", question: "question", options: "options" }, outputs: { iconSelected: "iconSelected" }, ngImport: i0, template: "<!-- MSM10JUL25 for icon selector UI -->\n<div class=\"icon-selector\">\n <div class=\"selected-icon\" (click)=\"toggleDropdown()\">\n <span *ngIf=\"!selectedIcon\">Choose Icon</span>\n <div *ngIf=\"selectedIcon\" [innerHTML]=\"getSanitizedSvg(selectedIcon)\" class=\"svg-container\"></div><span\n class=\"material-icons\">arrow_drop_down</span>\n </div>\n\n <div class=\"icon-selector-container\" [style.height]=\"height\" *ngIf=\"showDropdown\">\n <div class=\"search-container\">\n <div class=\"search-box\">\n <input type=\"text\" [(ngModel)]=\"searchQuery\" (input)=\"filterIcons()\" placeholder=\"Search icons...\"\n class=\"search-input\">\n </div>\n </div>\n\n <div class=\"icon-grid-container\" [style.max-height]=\"'calc(' + height + ' - 120px)'\">\n <div *ngIf=\"filteredIcons.length === 0\" class=\"no-results\">\n No icons found matching \"{{searchQuery}}\"\n </div>\n\n <div class=\"icon-grid\">\n <div *ngFor=\"let icon of filteredIcons\" class=\"icon-option\" [matTooltip]=icon.name\n [matTooltipPosition]=tooltipPosition (click)=\"selectIcon(icon.file);toggleDropdown()\">\n <div [innerHTML]=\"getSanitizedSvg(icon.file)\" class=\"svg-container\"></div>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".icon-item svg{color:red}.icon-selector-container{padding:16px;max-width:400px;margin:0 auto;display:flex;flex-direction:column;border-radius:8px;box-shadow:0 2px 10px #0000001a;background-color:#fff;overflow:hidden}.search-container{margin:8px 0 16px}.icon-grid-container{overflow-y:scroll!important;padding-right:4px}.icon-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:5px}.icon-option{display:flex;align-items:center;justify-content:center;padding:6px;border-radius:8px;cursor:pointer;transition:all .2s ease;background-color:#f5f5f5;aspect-ratio:1/1}.icon-option:hover{background-color:#e0e0e0;transform:scale(1.05)}.icon-option.selected{background-color:#e3f2fd;border:2px solid #2196f3}.no-results{text-align:center;padding:20px;color:#757575;font-style:italic}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}::-webkit-scrollbar-thumb{background:#888;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#555}.icon-selector{position:relative;display:inline-block}.selected-icon{display:flex;align-items:center;gap:4px;cursor:pointer;padding:3px;border:1px solid #ccc;border-radius:4px}.icon-dropdown{position:absolute;top:100%;left:0;z-index:1000;background:#fff;border:1px solid #ccc;border-radius:4px;max-height:200px;overflow-y:auto;display:grid;grid-template-columns:repeat(10,1fr);gap:5px;padding:3px}.icon-option{padding:3px;cursor:pointer;border-radius:4px;display:flex;justify-content:center}.icon-option:hover{background-color:#f0f0f0}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;line-height:1}svg{width:20px!important;height:20px!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
98
|
+
}
|
|
99
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: IconSelectorComponent, decorators: [{
|
|
100
|
+
type: Component,
|
|
101
|
+
args: [{ selector: 'nxt-icon-selector', imports: [CommonModule, FormsModule, MatTooltipModule], standalone: true, template: "<!-- MSM10JUL25 for icon selector UI -->\n<div class=\"icon-selector\">\n <div class=\"selected-icon\" (click)=\"toggleDropdown()\">\n <span *ngIf=\"!selectedIcon\">Choose Icon</span>\n <div *ngIf=\"selectedIcon\" [innerHTML]=\"getSanitizedSvg(selectedIcon)\" class=\"svg-container\"></div><span\n class=\"material-icons\">arrow_drop_down</span>\n </div>\n\n <div class=\"icon-selector-container\" [style.height]=\"height\" *ngIf=\"showDropdown\">\n <div class=\"search-container\">\n <div class=\"search-box\">\n <input type=\"text\" [(ngModel)]=\"searchQuery\" (input)=\"filterIcons()\" placeholder=\"Search icons...\"\n class=\"search-input\">\n </div>\n </div>\n\n <div class=\"icon-grid-container\" [style.max-height]=\"'calc(' + height + ' - 120px)'\">\n <div *ngIf=\"filteredIcons.length === 0\" class=\"no-results\">\n No icons found matching \"{{searchQuery}}\"\n </div>\n\n <div class=\"icon-grid\">\n <div *ngFor=\"let icon of filteredIcons\" class=\"icon-option\" [matTooltip]=icon.name\n [matTooltipPosition]=tooltipPosition (click)=\"selectIcon(icon.file);toggleDropdown()\">\n <div [innerHTML]=\"getSanitizedSvg(icon.file)\" class=\"svg-container\"></div>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".icon-item svg{color:red}.icon-selector-container{padding:16px;max-width:400px;margin:0 auto;display:flex;flex-direction:column;border-radius:8px;box-shadow:0 2px 10px #0000001a;background-color:#fff;overflow:hidden}.search-container{margin:8px 0 16px}.icon-grid-container{overflow-y:scroll!important;padding-right:4px}.icon-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:5px}.icon-option{display:flex;align-items:center;justify-content:center;padding:6px;border-radius:8px;cursor:pointer;transition:all .2s ease;background-color:#f5f5f5;aspect-ratio:1/1}.icon-option:hover{background-color:#e0e0e0;transform:scale(1.05)}.icon-option.selected{background-color:#e3f2fd;border:2px solid #2196f3}.no-results{text-align:center;padding:20px;color:#757575;font-style:italic}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}::-webkit-scrollbar-thumb{background:#888;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#555}.icon-selector{position:relative;display:inline-block}.selected-icon{display:flex;align-items:center;gap:4px;cursor:pointer;padding:3px;border:1px solid #ccc;border-radius:4px}.icon-dropdown{position:absolute;top:100%;left:0;z-index:1000;background:#fff;border:1px solid #ccc;border-radius:4px;max-height:200px;overflow-y:auto;display:grid;grid-template-columns:repeat(10,1fr);gap:5px;padding:3px}.icon-option{padding:3px;cursor:pointer;border-radius:4px;display:flex;justify-content:center}.icon-option:hover{background-color:#f0f0f0}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;line-height:1}svg{width:20px!important;height:20px!important}\n"] }]
|
|
102
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.DomSanitizer }, { type: i0.ChangeDetectorRef }], propDecorators: { allIcons: [{
|
|
103
|
+
type: Input
|
|
104
|
+
}], themeColor: [{
|
|
105
|
+
type: Input
|
|
106
|
+
}], height: [{
|
|
107
|
+
type: Input
|
|
108
|
+
}], tooltipPosition: [{
|
|
109
|
+
type: Input
|
|
110
|
+
}], selectedIcon: [{
|
|
111
|
+
type: Input
|
|
112
|
+
}], cdnIconURL: [{
|
|
113
|
+
type: Input
|
|
114
|
+
}], label: [{
|
|
115
|
+
type: Input
|
|
116
|
+
}], labelFont: [{
|
|
117
|
+
type: Input
|
|
118
|
+
}], labelWeight: [{
|
|
119
|
+
type: Input
|
|
120
|
+
}], inputWeight: [{
|
|
121
|
+
type: Input
|
|
122
|
+
}], labelSize: [{
|
|
123
|
+
type: Input
|
|
124
|
+
}], labelColor: [{
|
|
125
|
+
type: Input
|
|
126
|
+
}], showLabel: [{
|
|
127
|
+
type: Input
|
|
128
|
+
}], required: [{
|
|
129
|
+
type: Input
|
|
130
|
+
}], mode: [{
|
|
131
|
+
type: Input
|
|
132
|
+
}], question: [{
|
|
133
|
+
type: Input
|
|
134
|
+
}], options: [{
|
|
135
|
+
type: Input
|
|
136
|
+
}], iconSelected: [{
|
|
137
|
+
type: Output
|
|
138
|
+
}] } });
|
|
139
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWNvbi1zZWxlY3Rvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ueHQtYXBwL3NyYy9saWIvY29tcG9uZW50cy9pY29uLXNlbGVjdG9yL2ljb24tc2VsZWN0b3IuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL2NvbXBvbmVudHMvaWNvbi1zZWxlY3Rvci9pY29uLXNlbGVjdG9yLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFDWixPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUMxRixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFL0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUV6RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7Ozs7Ozs7QUFTN0QsTUFBTSxPQUFPLHFCQUFxQjtJQTBCWjtJQUEwQjtJQUFpQztJQXpCdEUsUUFBUSxDQUFLO0lBQ2IsVUFBVSxHQUFXLFNBQVMsQ0FBQyxDQUFDLHNCQUFzQjtJQUN0RCxNQUFNLEdBQVcsT0FBTyxDQUFDLENBQUMsaUJBQWlCO0lBQzNDLGVBQWUsR0FBVyxPQUFPLENBQUMsQ0FBQywyQ0FBMkM7SUFDOUUsWUFBWSxDQUFTLENBQUMscUJBQXFCO0lBQzNDLFVBQVUsR0FBVyxFQUFFLENBQUMsQ0FBQyxvQkFBb0I7SUFFN0MsS0FBSyxHQUFXLEVBQUUsQ0FBQyxDQUFFLGNBQWM7SUFDbkMsU0FBUyxHQUFXLEVBQUUsQ0FBQyxDQUFFLG1CQUFtQjtJQUM1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UCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBQ0QsVUFBVSxDQUFDLFFBQWdCO1FBQ3pCLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLFFBQVEsRUFBRSxDQUFDO0lBQ3pDLENBQUM7SUFDRCxjQUFjO1FBQ1osSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDekMsQ0FBQzt3R0ExRlUscUJBQXFCOzRGQUFyQixxQkFBcUIsMGhCQ2hCbEMsZ3pDQTZCTSxnc0REakJNLFlBQVksK1BBQUUsV0FBVyw4bUJBQUUsZ0JBQWdCOzs0RkFJMUMscUJBQXFCO2tCQVBqQyxTQUFTOytCQUNFLG1CQUFtQixXQUVwQixDQUFDLFlBQVksRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsY0FFMUMsSUFBSTswSUFHUCxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFFSSxZQUFZO3NCQUFyQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLy9NU00xMEpVTDI1XG5pbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCwgQ2hhbmdlRGV0ZWN0b3JSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIsIFNhZmVIdG1sIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBmaW5hbGl6ZSwgbWFwLCBTdWJqZWN0LCB0YWtlVW50aWwgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE1hdFRvb2x0aXBNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90b29sdGlwJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbnh0LWljb24tc2VsZWN0b3InLFxuICB0ZW1wbGF0ZVVybDogJy4vaWNvbi1zZWxlY3Rvci5jb21wb25lbnQuaHRtbCcsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEZvcm1zTW9kdWxlLCBNYXRUb29sdGlwTW9kdWxlXSxcbiAgc3R5bGVVcmxzOiBbJy4vaWNvbi1zZWxlY3Rvci5jb21wb25lbnQuY3NzJ10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIEljb25TZWxlY3RvckNvbXBvbmVudCB7XG4gIEBJbnB1dCgpIGFsbEljb25zOiBbXTtcbiAgQElucHV0KCkgdGhlbWVDb2xvcjogc3RyaW5nID0gJyNmZjAwMDAnOyAvLyBEZWZhdWx0IHRoZW1lIGNvbG9yXG4gIEBJbnB1dCgpIGhlaWdodDogc3RyaW5nID0gJzMwMHB4JzsgLy8gRGVmYXVsdCBoZWlnaHRcbiAgQElucHV0KCkgdG9vbHRpcFBvc2l0aW9uOiBzdHJpbmcgPSBcImFib3ZlXCI7IC8vIGFib3ZlLCBiZWxvdywgbGVmdCwgcmlnaHQsIGJlZm9yZSwgYWZ0ZXJcbiAgQElucHV0KCkgc2VsZWN0ZWRJY29uOiBzdHJpbmc7IC8vIFNlbGVjdGVkIGljb24gbmFtZVxuICBASW5wdXQoKSBjZG5JY29uVVJMOiBzdHJpbmcgPSBcIlwiOyAvLyBDRE4gVVJMIGZvciBpY29uc1xuXG4gIEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgPSAnJzsgIC8vIElucHV0IGxhYmVsXG4gIEBJbnB1dCgpIGxhYmVsRm9udDogc3RyaW5nID0gJyc7ICAvLyBJbnB1dCBsYWJlbCBmb250XG4gIEBJbnB1dCgpIGxhYmVsV2VpZ2h0OiBzdHJpbmcgPSAnJzsgIC8vIElucHV0IGxhYmVsIFdlaWdodFxuICBASW5wdXQoKSBpbnB1dFdlaWdodDogc3RyaW5nID0gJyc7ICAvLyBJbnB1dCBXZWlnaHRcbiAgQElucHV0KCkgbGFiZWxTaXplOiBzdHJpbmcgPSAnJzsgIC8vIElucHV0IGxhYmVsIFNpemVcbiAgQElucHV0KCkgbGFiZWxDb2xvcjogc3RyaW5nID0gJyc7ICAvLyBJbnB1dCBsYWJlbCBDb2xvclxuICBASW5wdXQoKSBzaG93TGFiZWw6IHN0cmluZyA9ICcnOyAgLy8gSW5wdXQgbGFiZWwgQ29sb3JcbiAgQElucHV0KCkgcmVxdWlyZWQ6IGJvb2xlYW4gPSBmYWxzZTsgIC8vIFJlcXVpcmVkIHZhbGlkYXRpb25cbiAgQElucHV0KCkgbW9kZTogJ3ZpZXcnIHwgJ2VkaXQnIHwgJ3ByaW50JyA9ICdlZGl0JzsgLy8gTmV3IG1vZGUgaW5wdXRcbiAgQElucHV0KCkgcXVlc3Rpb246IGFueSA9IHt9XG4gIEBJbnB1dCgpIG9wdGlvbnM6IGFueVtdID0gW107IC8vIEZvciByYWRpbyBidXR0b25zXG5cbiAgQE91dHB1dCgpIGljb25TZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpOyAvLyBFdmVudCBlbWl0dGVyIGZvciBzZWxlY3RlZCBpY29uXG4gIHN2Z0NhY2hlID0gbmV3IE1hcDxzdHJpbmcsIFNhZmVIdG1sPigpOyAvLyBDYWNoZSBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlXG4gIHByaXZhdGUgZGVzdHJveWVkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgZmlsdGVyZWRJY29uczogYW55W10gPSBbXTtcbiAgc2VhcmNoUXVlcnkgPSAnJztcbiAgc2hvd0Ryb3Bkb3duID0gZmFsc2U7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaHR0cDogSHR0cENsaWVudCwgcHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplciwgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7IH1cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5maWx0ZXJlZEljb25zID0gdGhpcy5hbGxJY29ucyAhPSBudWxsICYmIHRoaXMuYWxsSWNvbnMubGVuZ3RoID4gMCA/IFsuLi50aGlzLmFsbEljb25zXSA6IFtdO1xuICB9XG4gIGZpbHRlckljb25zKCkge1xuICAgIGlmICghdGhpcy5zZWFyY2hRdWVyeSkge1xuICAgICAgdGhpcy5maWx0ZXJlZEljb25zID0gdGhpcy5hbGxJY29ucyAhPSBudWxsICYmIHRoaXMuYWxsSWNvbnMubGVuZ3RoID4gMCA/IFsuLi50aGlzLmFsbEljb25zXSA6IFtdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmZpbHRlcmVkSWNvbnMgPSB0aGlzLmFsbEljb25zPy5maWx0ZXIoKGljb246IGFueSkgPT5cbiAgICAgIGljb24/Lm5hbWU/LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGhpcy5zZWFyY2hRdWVyeT8udG9Mb3dlckNhc2UoKSlcbiAgICApO1xuICB9XG5cbiAgc2VsZWN0SWNvbihpY29uOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNlbGVjdGVkSWNvbiA9IGljb247XG4gICAgdGhpcy5pY29uU2VsZWN0ZWQuZW1pdChpY29uKTtcbiAgfVxuXG4gIGdldFNhbml0aXplZFN2ZyhmaWxlbmFtZTogc3RyaW5nKTogU2FmZUh0bWwge1xuICAgIC8vIFJldHVybiBjYWNoZWQgb3IgbG9hZGluZyBTVkdcbiAgICByZXR1cm4gdGhpcy5zdmdDYWNoZS5nZXQoZmlsZW5hbWUpIHx8IHRoaXMubG9hZFN2ZyhmaWxlbmFtZSk7XG4gIH1cblxuICBwcml2YXRlIGxvYWRTdmcoZmlsZW5hbWU6IHN0cmluZyk6IFNhZmVIdG1sIHtcbiAgICBjb25zdCBsb2FkaW5nU3ZnID0gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdEh0bWwoXG4gICAgICBgPHN2ZyB3aWR0aD1cIjQ4XCIgaGVpZ2h0PVwiNDhcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+PC9zdmc+YFxuICAgICk7XG4gICAgdGhpcy5zdmdDYWNoZS5zZXQoZmlsZW5hbWUsIGxvYWRpbmdTdmcpO1xuXG4gICAgdGhpcy5odHRwLmdldCh0aGlzLmdldEljb25VcmwoZmlsZW5hbWUpLCB7IHJlc3BvbnNlVHlwZTogJ3RleHQnIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveWVkKSxcbiAgICAgICAgbWFwKHN2Z0RhdGEgPT4gdGhpcy5wcm9jZXNzU3ZnKHN2Z0RhdGEsIHRoaXMudGhlbWVDb2xvcikpLFxuICAgICAgICBmaW5hbGl6ZSgoKSA9PiB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKSkgLy8gU2FmZSBjaGFuZ2UgZGV0ZWN0aW9uXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogcHJvY2Vzc2VkU3ZnID0+IHRoaXMuc3ZnQ2FjaGUuc2V0KGZpbGVuYW1lLCBwcm9jZXNzZWRTdmcpLFxuICAgICAgICBlcnJvcjogKCkgPT4gdGhpcy5zdmdDYWNoZS5zZXQoZmlsZW5hbWUsIGxvYWRpbmdTdmcpXG4gICAgICB9KTtcblxuICAgIHJldHVybiBsb2FkaW5nU3ZnO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzU3ZnKHN2Z0RhdGE6IHN0cmluZywgY29sb3I6IHN0cmluZyk6IFNhZmVIdG1sIHtcbiAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkaXYuaW5uZXJIVE1MID0gc3ZnRGF0YTtcbiAgICBjb25zdCBzdmcgPSBkaXYucXVlcnlTZWxlY3Rvcignc3ZnJyk7XG5cbiAgICBpZiAoc3ZnKSB7XG4gICAgICBzdmcucXVlcnlTZWxlY3RvckFsbCgnW2ZpbGxdOm5vdChbZmlsbD1cIm5vbmVcIl0pLCBbc3Ryb2tlXTpub3QoW3N0cm9rZT1cIm5vbmVcIl0pJylcbiAgICAgICAgLmZvckVhY2goZWwgPT4ge1xuICAgICAgICAgIGlmIChlbC5oYXNBdHRyaWJ1dGUoJ2ZpbGwnKSkgZWwuc2V0QXR0cmlidXRlKCdmaWxsJywgY29sb3IpO1xuICAgICAgICAgIGlmIChlbC5oYXNBdHRyaWJ1dGUoJ3N0cm9rZScpKSBlbC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIGNvbG9yKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RIdG1sKGRpdi5pbm5lckhUTUwpO1xuICB9XG4gIGdldEljb25VcmwoZmlsZU5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3RoaXMuY2RuSWNvblVSTH0ke2ZpbGVOYW1lfWA7XG4gIH1cbiAgdG9nZ2xlRHJvcGRvd24oKTogdm9pZCB7XG4gICAgdGhpcy5zaG93RHJvcGRvd24gPSAhdGhpcy5zaG93RHJvcGRvd247XG4gIH1cbn1cbiIsIjwhLS0gTVNNMTBKVUwyNSBmb3IgaWNvbiBzZWxlY3RvciBVSSAtLT5cbjxkaXYgY2xhc3M9XCJpY29uLXNlbGVjdG9yXCI+XG4gIDxkaXYgY2xhc3M9XCJzZWxlY3RlZC1pY29uXCIgKGNsaWNrKT1cInRvZ2dsZURyb3Bkb3duKClcIj5cbiAgICA8c3BhbiAqbmdJZj1cIiFzZWxlY3RlZEljb25cIj5DaG9vc2UgSWNvbjwvc3Bhbj5cbiAgICA8ZGl2ICpuZ0lmPVwic2VsZWN0ZWRJY29uXCIgW2lubmVySFRNTF09XCJnZXRTYW5pdGl6ZWRTdmcoc2VsZWN0ZWRJY29uKVwiIGNsYXNzPVwic3ZnLWNvbnRhaW5lclwiPjwvZGl2PjxzcGFuXG4gICAgICBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+YXJyb3dfZHJvcF9kb3duPC9zcGFuPlxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwiaWNvbi1zZWxlY3Rvci1jb250YWluZXJcIiBbc3R5bGUuaGVpZ2h0XT1cImhlaWdodFwiICpuZ0lmPVwic2hvd0Ryb3Bkb3duXCI+XG4gICAgPGRpdiBjbGFzcz1cInNlYXJjaC1jb250YWluZXJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzZWFyY2gtYm94XCI+XG4gICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFsobmdNb2RlbCldPVwic2VhcmNoUXVlcnlcIiAoaW5wdXQpPVwiZmlsdGVySWNvbnMoKVwiIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGljb25zLi4uXCJcbiAgICAgICAgICBjbGFzcz1cInNlYXJjaC1pbnB1dFwiPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaWNvbi1ncmlkLWNvbnRhaW5lclwiIFtzdHlsZS5tYXgtaGVpZ2h0XT1cIidjYWxjKCcgKyBoZWlnaHQgKyAnIC0gMTIwcHgpJ1wiPlxuICAgICAgPGRpdiAqbmdJZj1cImZpbHRlcmVkSWNvbnMubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJuby1yZXN1bHRzXCI+XG4gICAgICAgIE5vIGljb25zIGZvdW5kIG1hdGNoaW5nIFwie3tzZWFyY2hRdWVyeX19XCJcbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwiaWNvbi1ncmlkXCI+XG4gICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGljb24gb2YgZmlsdGVyZWRJY29uc1wiIGNsYXNzPVwiaWNvbi1vcHRpb25cIiBbbWF0VG9vbHRpcF09aWNvbi5uYW1lXG4gICAgICAgICAgW21hdFRvb2x0aXBQb3NpdGlvbl09dG9vbHRpcFBvc2l0aW9uIChjbGljayk9XCJzZWxlY3RJY29uKGljb24uZmlsZSk7dG9nZ2xlRHJvcGRvd24oKVwiPlxuICAgICAgICAgIDxkaXYgW2lubmVySFRNTF09XCJnZXRTYW5pdGl6ZWRTdmcoaWNvbi5maWxlKVwiIGNsYXNzPVwic3ZnLWNvbnRhaW5lclwiPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PiJdfQ==
|