UNPKG

ontotext-reusable-ui-components

Version:

Unified reusable UI components designed for the Ontotext ecosystem.

170 lines 29.5 kB
import { Component, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core'; import { debounce } from 'rxjs/operators'; import { interval } from 'rxjs'; export class RangeSliderComponent { constructor() { this._selectionChange = new EventEmitter(); // Add debounce of 2 s, as the event is emitted on every input change (drag of slider) this.selectionChange = this._selectionChange.pipe(debounce(() => interval(2000))); // Size of the circle range slider button. // It is used so that the both circles can hit each other without overlapping. this.rangeCircleSize = 14; } onResize() { } ngOnInit() { this.initializeData(); } ngAfterViewInit() { this.minElement = this.minSlider.nativeElement; this.maxElement = this.maxSlider.nativeElement; this.init(this.selectedMin, this.selectedMax); this.onResize = () => this.update(this.parseInt(this.maxElement.getAttribute('max'))); } ngOnChanges(changes) { var _a; if ((_a = changes === null || changes === void 0 ? void 0 : changes.data) === null || _a === void 0 ? void 0 : _a.currentValue) { this.initializeData(); this.init(this.selectedMin, this.selectedMax); } } initializeData() { var _a, _b; this.facetData = [...this.data.facetGroupData]; this.facetData.sort((a, b) => { try { return this.parseInt(a.label) - this.parseInt(b.label); } catch (e) { throw new Error('Facet labels must represent numbers! ' + e.message); } }); this.minValue = this.facetData[0].label; this.maxValue = this.facetData[this.facetData.length - 1].label; this.selectedMin = ((_a = this.data.selectedRange) === null || _a === void 0 ? void 0 : _a.start) || this.minValue; this.selectedMax = ((_b = this.data.selectedRange) === null || _b === void 0 ? void 0 : _b.end) || this.maxValue; this.sum = this.sumRange(); } draw(splitvalue) { const thumbsize = this.parseInt(this.slider.nativeElement.getAttribute('data-thumbsize')); const rangewidth = this.slider.nativeElement.clientWidth; const rangemin = this.parseInt(this.slider.nativeElement.getAttribute('data-rangemin')); const rangemax = this.parseInt(this.slider.nativeElement.getAttribute('data-rangemax')); this.minElement.setAttribute('max', splitvalue); this.maxElement.setAttribute('min', splitvalue); this.minElement.style.width = this.parseInt(thumbsize + ((splitvalue - rangemin) / (rangemax - rangemin)) * (rangewidth - (2 * thumbsize))) + 'px'; this.maxElement.style.width = this.parseInt(thumbsize + ((rangemax - splitvalue) / (rangemax - rangemin)) * (rangewidth - (2 * thumbsize))) + 'px'; this.minElement.style.left = '0px'; this.maxElement.style.left = this.parseInt(this.minElement.style.width) + 'px'; // correct for 1 off at the end of the max slider if (this.maxElement.value > (rangemax - 1)) { this.maxElement.setAttribute('data-value', rangemax); } this.maxElement.value = this.maxElement.getAttribute('data-value'); this.minElement.value = this.minElement.getAttribute('data-value'); } init(min, max) { if (!(this.minElement && this.maxElement)) { return; } this.minElement.removeEventListener('input', () => this.update); this.maxElement.removeEventListener('input', () => this.update); const rangemin = this.parseInt(this.minValue); const rangemax = this.parseInt(this.maxValue); const selectedMin = this.parseInt(min) || rangemin; const selectedMax = this.parseInt(max) || rangemax; const avgvalue = (selectedMin + selectedMax) / 2; this.minElement.setAttribute('data-value', selectedMin); this.maxElement.setAttribute('data-value', selectedMax); this.slider.nativeElement.setAttribute('data-rangemin', rangemin); this.slider.nativeElement.setAttribute('data-rangemax', rangemax); this.slider.nativeElement.setAttribute('data-thumbsize', this.rangeCircleSize); this.slider.nativeElement.setAttribute('data-rangewidth', this.slider.nativeElement.offsetWidth); this.draw(avgvalue); this.minElement.addEventListener('input', () => this.update(rangemax)); this.maxElement.addEventListener('input', () => this.update(rangemax)); } update(rangemax) { // correction for min value calculation let minvalue; if (this.minElement.value > (rangemax - 1)) { minvalue = Math.floor(this.minElement.value - 1); } else { minvalue = Math.floor(this.minElement.value); } // correction for max value calculation let maxvalue; if (this.maxElement.value > (rangemax - 1)) { maxvalue = Math.ceil(this.maxElement.value); } else { maxvalue = Math.floor(this.maxElement.value); } this.minElement.setAttribute('data-value', minvalue); this.maxElement.setAttribute('data-value', maxvalue); this.selectedMin = minvalue; this.selectedMax = maxvalue; this.updateSelection(); this.sum = this.sumRange(); const avgvalue = Math.ceil((minvalue + maxvalue) / 2); this.draw(avgvalue); } sumRange() { let sum = 0; this.data.facetGroupData.forEach((facet) => { if (this.isInRange(facet)) { sum += facet.count; } }); return sum; } onSelectionChange() { const selection = { name: this.data.facetGroupName, selected: this.data.selectedRange, count: this.sumRange() }; this._selectionChange.emit(selection); } updateSelection() { this.data.selectedRange = { start: this.selectedMin, end: this.selectedMax }; this.onSelectionChange(); } isInRange(facet) { const value = this.parseInt(facet.label); return value >= this.parseInt(this.selectedMin) && value <= this.parseInt(this.selectedMax); } parseInt(value) { try { return parseInt(value); } catch (e) { throw new Error(`Parsing ${value} to number failed! ` + e.message); } } ngOnDestroy() { this.onResize = function () { }; this.minElement.removeEventListener('input', () => this.update); this.maxElement.removeEventListener('input', () => this.update); } } RangeSliderComponent.decorators = [ { type: Component, args: [{ selector: 'onto-range-slider', template: "<div class=\"range-slider-wrapper\">\n <div class=\"range-slider\">\n <div class=\"slider\" #slider>\n <input class=\"range-slider-range min-range\" type=\"range\" min=\"{{minValue}}\" max=\"{{maxValue}}\" #minSlider\n appCypressData=\"min-range\"/>\n <input class=\"range-slider-range max-range\" type=\"range\" min=\"{{minValue}}\" max=\"{{maxValue}}\" #maxSlider\n appCypressData=\"max-range\"/>\n </div>\n </div>\n <div class=\"range-values\">\n <div class=\"range-slider-value value-min\">{{minValue}}</div>\n <div class=\"range-slider-value value-max\">{{maxValue}}</div>\n </div>\n <div class=\"range-selecton\">\n <ng-container *ngTemplateOutlet=\"facetTemplate; context: {$implicit: data.selectedRange, sum: sumRange()}\">\n </ng-container>\n </div>\n</div>\n\n", styles: [".range-slider{flex-direction:column;place-content:center space-around}.range-slider,.slider{align-items:center;cursor:pointer;display:flex;width:100%}.slider{flex-direction:row;max-height:100%;place-content:stretch center;text-align:center}.range-values{align-items:center;display:flex;flex-direction:row;place-content:space-between}.range-selecton,.range-values{margin-top:12px}.range-slider-range{-webkit-appearance:none;background:#d7dcdf;height:10px;margin:0;outline:none;padding:0;width:100%}.range-slider-range::-webkit-slider-thumb{-webkit-appearance:none;-webkit-transition:background .15s ease-in-out;appearance:none;background:#2c3e50;border-radius:50%;cursor:pointer;height:20px;transition:background .15s ease-in-out;width:20px}.range-slider-range::-webkit-slider-thumb:hover,.range-slider-range:active::-webkit-slider-thumb{background:#1abc9c}.range-slider-range::-moz-range-thumb{-moz-transition:background .15s ease-in-out;background:#2c3e50;border:0;border-radius:50%;cursor:pointer;height:20px;transition:background .15s ease-in-out;width:20px}.range-slider-range::-moz-range-thumb:hover,.range-slider-range:active::-moz-range-thumb{background:#1abc9c}.range-slider-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 3px #fff,0 0 0 6px #1abc9c}::-moz-range-track{background:#d7dcdf;border:0}input::-moz-focus-inner,input::-moz-focus-outer{border:0}"] },] } ]; RangeSliderComponent.propDecorators = { data: [{ type: Input }], facetTemplate: [{ type: Input }], slider: [{ type: ViewChild, args: ['slider',] }], minSlider: [{ type: ViewChild, args: ['minSlider',] }], maxSlider: [{ type: ViewChild, args: ['maxSlider',] }], selectionChange: [{ type: Output }], onResize: [{ type: HostListener, args: ['window:resize',] }] }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZ2Utc2xpZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIvb3B0L2plbmtpbnNfam9icy93b3Jrc3BhY2UvcmV1c2FibGUtdWktY29tcG9uZW50cy1yZWxlYXNlL3Byb2plY3RzL29udG8tc2VhcmNoL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9vbnRvLXNlYXJjaC1mYWNldC9yYW5nZS1mYWNldC9yYW5nZS1zbGlkZXIvcmFuZ2Utc2xpZGVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUVULFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFDTixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFJdkIsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFROUIsTUFBTSxPQUFPLG9CQUFvQjtJQUxqQztRQWtCUyxxQkFBZ0IsR0FBdUMsSUFBSSxZQUFZLEVBQXdCLENBQUM7UUFFdkcsc0ZBQXNGO1FBRS9FLG9CQUFlLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQVFwRiwwQ0FBMEM7UUFDMUMsOEVBQThFO1FBQ3RFLG9CQUFlLEdBQUcsRUFBRSxDQUFDO0lBK0svQixDQUFDO0lBdExDLFFBQVEsS0FBVSxDQUFDO0lBZW5CLFFBQVE7UUFDTixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVNLGVBQWU7UUFDcEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQztRQUMvQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDO1FBRS9DLElBQUksQ0FBQyxJ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LFFBQVEsQ0FBQyxHQUFHLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztRQUNuSixJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7UUFDbkosSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQztRQUNuQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUM7UUFFL0UsaURBQWlEO1FBQ2pELElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLEVBQUU7WUFDMUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQ3REO1FBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDbkUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVELElBQUksQ0FBQyxHQUFRLEVBQUUsR0FBUTtRQUNyQixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLElB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QVMsU0FBQyxXQUFXO3dCQUVyQixTQUFTLFNBQUMsV0FBVzs4QkFNckIsTUFBTTt1QkFHTixZQUFZLFNBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0TGlzdGVuZXIsXG4gIElucHV0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1NlYXJjaEZhY2V0TW9kZWx9IGZyb20gJy4uLy4uL21vZGVscy9zZWFyY2gtZmFjZXQtbW9kZWwnO1xuaW1wb3J0IHtTZWxlY3RlZFJhbmdlfSBmcm9tICcuLi9tb2RlbHMvc2VsZWN0ZWQtcmFuZ2UnO1xuaW1wb3J0IHtTZWFyY2hSYW5nZUZhY2V0R3JvdXBNb2RlbH0gZnJvbSAnLi4vbW9kZWxzL3NlYXJjaC1yYW5nZS1mYWNldC1ncm91cC1tb2RlbCc7XG5pbXBvcnQge2RlYm91bmNlfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge2ludGVydmFsfSBmcm9tICdyeGpzJztcbmltcG9ydCB7U2VhcmNoRmFjZXRTZWxlY3Rpb259IGZyb20gJy4uLy4uL21vZGVscy9zZWFyY2gtZmFjZXQtc2VsZWN0aW9uJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnb250by1yYW5nZS1zbGlkZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vcmFuZ2Utc2xpZGVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcmFuZ2Utc2xpZGVyLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgUmFuZ2VTbGlkZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcbiAgQElucHV0KClcbiAgcHVibGljIGRhdGE6IFNlYXJjaFJhbmdlRmFjZXRHcm91cE1vZGVsO1xuICBASW5wdXQoKVxuICBwdWJsaWMgZmFjZXRUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICBAVmlld0NoaWxkKCdzbGlkZXInKVxuICBwdWJsaWMgc2xpZGVyOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdtaW5TbGlkZXInKVxuICBwdWJsaWMgbWluU2xpZGVyOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdtYXhTbGlkZXInKVxuICBwdWJsaWMgbWF4U2xpZGVyOiBFbGVtZW50UmVmO1xuXG4gIHB1YmxpYyBfc2VsZWN0aW9uQ2hhbmdlOiBFdmVudEVtaXR0ZXI8U2VhcmNoRmFjZXRTZWxlY3Rpb24+ID0gbmV3IEV2ZW50RW1pdHRlcjxTZWFyY2hGYWNldFNlbGVjdGlvbj4oKTtcblxuICAvLyBBZGQgZGVib3VuY2Ugb2YgMiBzLCBhcyB0aGUgZXZlbnQgaXMgZW1pdHRlZCBvbiBldmVyeSBpbnB1dCBjaGFuZ2UgKGRyYWcgb2Ygc2xpZGVyKVxuICBAT3V0cHV0KClcbiAgcHVibGljIHNlbGVjdGlvbkNoYW5nZSA9IHRoaXMuX3NlbGVjdGlvbkNoYW5nZS5waXBlKGRlYm91bmNlKCgpID0+IGludGVydmFsKDIwMDApKSk7XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScpXG4gIG9uUmVzaXplKCk6IHZvaWQge31cblxuICBwcml2YXRlIGZhY2V0RGF0YTogU2VhcmNoRmFjZXRNb2RlbFtdO1xuICBwdWJsaWMgc3VtOiBudW1iZXI7XG5cbiAgLy8gU2l6ZSBvZiB0aGUgY2lyY2xlIHJhbmdlIHNsaWRlciBidXR0b24uXG4gIC8vIEl0IGlzIHVzZWQgc28gdGhhdCB0aGUgYm90aCBjaXJjbGVzIGNhbiBoaXQgZWFjaCBvdGhlciB3aXRob3V0IG92ZXJsYXBwaW5nLlxuICBwcml2YXRlIHJhbmdlQ2lyY2xlU2l6ZSA9IDE0O1xuICBwdWJsaWMgbWluVmFsdWU7XG4gIHB1YmxpYyBtYXhWYWx1ZTtcbiAgcHVibGljIHNlbGVjdGVkTWluO1xuICBwdWJsaWMgc2VsZWN0ZWRNYXg7XG4gIHB1YmxpYyBtaW5FbGVtZW50O1xuICBwdWJsaWMgbWF4RWxlbWVudDtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmluaXRpYWxpemVEYXRhKCk7XG4gIH1cblxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMubWluRWxlbWVudCA9IHRoaXMubWluU2xpZGVyLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5tYXhFbGVtZW50ID0gdGhpcy5tYXhTbGlkZXIubmF0aXZlRWxlbWVudDtcblxuICAgIHRoaXMuaW5pdCh0aGlzLnNlbGVjdGVkTWluLCB0aGlzLnNlbGVjdGVkTWF4KTtcbiAgICB0aGlzLm9uUmVzaXplID0gKCk6IHZvaWQgPT4gdGhpcy51cGRhdGUodGhpcy5wYXJzZUludCh0aGlzLm1heEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdtYXgnKSkpO1xuICB9XG5cbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlcz8uZGF0YT8uY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLmluaXRpYWxpemVEYXRhKCk7XG4gICAgICB0aGlzLmluaXQodGhpcy5zZWxlY3RlZE1pbiwgdGhpcy5zZWxlY3RlZE1heCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplRGF0YSgpOiB2b2lkIHtcbiAgICB0aGlzLmZhY2V0RGF0YSA9IFsuLi50aGlzLmRhdGEuZmFjZXRHcm91cERhdGFdO1xuICAgIHRoaXMuZmFjZXREYXRhLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlSW50KGEubGFiZWwpIC0gdGhpcy5wYXJzZUludChiLmxhYmVsKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWNldCBsYWJlbHMgbXVzdCByZXByZXNlbnQgbnVtYmVycyEgJyArIGUubWVzc2FnZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLm1pblZhbHVlID0gdGhpcy5mYWNldERhdGFbMF0ubGFiZWw7XG4gICAgdGhpcy5tYXhWYWx1ZSA9IHRoaXMuZmFjZXREYXRhW3RoaXMuZmFjZXREYXRhLmxlbmd0aCAtIDFdLmxhYmVsO1xuXG4gICAgdGhpcy5zZWxlY3RlZE1pbiA9IHRoaXMuZGF0YS5zZWxlY3RlZFJhbmdlPy5zdGFydCB8fCB0aGlzLm1pblZhbHVlO1xuICAgIHRoaXMuc2VsZWN0ZWRNYXggPSB0aGlzLmRhdGEuc2VsZWN0ZWRSYW5nZT8uZW5kIHx8IHRoaXMubWF4VmFsdWU7XG5cbiAgICB0aGlzLnN1bSA9IHRoaXMuc3VtUmFuZ2UoKTtcbiAgfVxuXG4gIGRyYXcoc3BsaXR2YWx1ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdGh1bWJzaXplOiBhbnkgPSB0aGlzLnBhcnNlSW50KHRoaXMuc2xpZGVyLm5hdGl2ZUVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXRodW1ic2l6ZScpKTtcbiAgICBjb25zdCByYW5nZXdpZHRoID0gdGhpcy5zbGlkZXIubmF0aXZlRWxlbWVudC5jbGllbnRXaWR0aDtcblxuICAgIGNvbnN0IHJhbmdlbWluID0gdGhpcy5wYXJzZUludCh0aGlzLnNsaWRlci5uYXRpdmVFbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1yYW5nZW1pbicpKTtcbiAgICBjb25zdCByYW5nZW1heCA9IHRoaXMucGFyc2VJbnQodGhpcy5zbGlkZXIubmF0aXZlRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtcmFuZ2VtYXgnKSk7XG5cbiAgICB0aGlzLm1pbkVsZW1lbnQuc2V0QXR0cmlidXRlKCdtYXgnLCBzcGxpdHZhbHVlKTtcbiAgICB0aGlzLm1heEVsZW1lbnQuc2V0QXR0cmlidXRlKCdtaW4nLCBzcGxpdHZhbHVlKTtcblxuICAgIHRoaXMubWluRWxlbWVudC5zdHlsZS53aWR0aCA9IHRoaXMucGFyc2VJbnQodGh1bWJzaXplICsgKChzcGxpdHZhbHVlIC0gcmFuZ2VtaW4pIC8gKHJhbmdlbWF4IC0gcmFuZ2VtaW4pKSAqIChyYW5nZXdpZHRoIC0gKDIgKiB0aHVtYnNpemUpKSkgKyAncHgnO1xuICAgIHRoaXMubWF4RWxlbWVudC5zdHlsZS53aWR0aCA9IHRoaXMucGFyc2VJbnQodGh1bWJzaXplICsgKChyYW5nZW1heCAtIHNwbGl0dmFsdWUpIC8gKHJhbmdlbWF4IC0gcmFuZ2VtaW4pKSAqIChyYW5nZXdpZHRoIC0gKDIgKiB0aHVtYnNpemUpKSkgKyAncHgnO1xuICAgIHRoaXMubWluRWxlbWVudC5zdHlsZS5sZWZ0ID0gJzBweCc7XG4gICAgdGhpcy5tYXhFbGVtZW50LnN0eWxlLmxlZnQgPSB0aGlzLnBhcnNlSW50KHRoaXMubWluRWxlbWVudC5zdHlsZS53aWR0aCkgKyAncHgnO1xuXG4gICAgLy8gY29ycmVjdCBmb3IgMSBvZmYgYXQgdGhlIGVuZCBvZiB0aGUgbWF4IHNsaWRlclxuICAgIGlmICh0aGlzLm1heEVsZW1lbnQudmFsdWUgPiAocmFuZ2VtYXggLSAxKSkge1xuICAgICAgdGhpcy5tYXhFbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS12YWx1ZScsIHJhbmdlbWF4KTtcbiAgICB9XG5cbiAgICB0aGlzLm1heEVsZW1lbnQudmFsdWUgPSB0aGlzLm1heEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyk7XG4gICAgdGhpcy5taW5FbGVtZW50LnZhbHVlID0gdGhpcy5taW5FbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS12YWx1ZScpO1xuICB9XG5cbiAgaW5pdChtaW46IGFueSwgbWF4OiBhbnkpOiB2b2lkIHtcbiAgICBpZiAoISh0aGlzLm1pbkVsZW1lbnQgJiYgdGhpcy5tYXhFbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLm1pbkVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignaW5wdXQnLCAoKSA9PiB0aGlzLnVwZGF0ZSk7XG4gICAgdGhpcy5tYXhFbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2lucHV0JywgKCkgPT4gdGhpcy51cGRhdGUpO1xuXG4gICAgY29uc3QgcmFuZ2VtaW46IGFueSA9IHRoaXMucGFyc2VJbnQodGhpcy5taW5WYWx1ZSk7XG4gICAgY29uc3QgcmFuZ2VtYXg6IGFueSA9IHRoaXMucGFyc2VJbnQodGhpcy5tYXhWYWx1ZSk7XG5cbiAgICBjb25zdCBzZWxlY3RlZE1pbiA9IHRoaXMucGFyc2VJbnQobWluKSB8fCByYW5nZW1pbjtcbiAgICBjb25zdCBzZWxlY3RlZE1heCA9IHRoaXMucGFyc2VJbnQobWF4KSB8fCByYW5nZW1heDtcblxuICAgIGNvbnN0IGF2Z3ZhbHVlID0gKHNlbGVjdGVkTWluICsgc2VsZWN0ZWRNYXgpIC8gMjtcblxuICAgIHRoaXMubWluRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnLCBzZWxlY3RlZE1pbik7XG4gICAgdGhpcy5tYXhFbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS12YWx1ZScsIHNlbGVjdGVkTWF4KTtcblxuICAgIHRoaXMuc2xpZGVyLm5hdGl2ZUVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLXJhbmdlbWluJywgcmFuZ2VtaW4pO1xuICAgIHRoaXMuc2xpZGVyLm5hdGl2ZUVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLXJhbmdlbWF4JywgcmFuZ2VtYXgpO1xuICAgIHRoaXMuc2xpZGVyLm5hdGl2ZUVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLXRodW1ic2l6ZScsIHRoaXMucmFuZ2VDaXJjbGVTaXplKTtcbiAgICB0aGlzLnNsaWRlci5uYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1yYW5nZXdpZHRoJywgdGhpcy5zbGlkZXIubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCk7XG5cbiAgICB0aGlzLmRyYXcoYXZndmFsdWUpO1xuXG4gICAgdGhpcy5taW5FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgKCkgPT4gdGhpcy51cGRhdGUocmFuZ2VtYXgpKTtcbiAgICB0aGlzLm1heEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCAoKSA9PiB0aGlzLnVwZGF0ZShyYW5nZW1heCkpO1xuICB9XG5cbiAgdXBkYXRlKHJhbmdlbWF4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAvLyBjb3JyZWN0aW9uIGZvciBtaW4gdmFsdWUgY2FsY3VsYXRpb25cbiAgICBsZXQgbWludmFsdWU7XG4gICAgaWYgKHRoaXMubWluRWxlbWVudC52YWx1ZSA+IChyYW5nZW1heCAtIDEpKSB7XG4gICAgICBtaW52YWx1ZSA9IE1hdGguZmxvb3IodGhpcy5taW5FbGVtZW50LnZhbHVlIC0gMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1pbnZhbHVlID0gTWF0aC5mbG9vcih0aGlzLm1pbkVsZW1lbnQudmFsdWUpO1xuICAgIH1cblxuICAgIC8vIGNvcnJlY3Rpb24gZm9yIG1heCB2YWx1ZSBjYWxjdWxhdGlvblxuICAgIGxldCBtYXh2YWx1ZTtcbiAgICBpZiAodGhpcy5tYXhFbGVtZW50LnZhbHVlID4gKHJhbmdlbWF4IC0gMSkpIHtcbiAgICAgIG1heHZhbHVlID0gTWF0aC5jZWlsKHRoaXMubWF4RWxlbWVudC52YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1heHZhbHVlID0gTWF0aC5mbG9vcih0aGlzLm1heEVsZW1lbnQudmFsdWUpO1xuICAgIH1cblxuICAgIHRoaXMubWluRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnLCBtaW52YWx1ZSk7XG4gICAgdGhpcy5tYXhFbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS12YWx1ZScsIG1heHZhbHVlKTtcblxuICAgIHRoaXMuc2VsZWN0ZWRNaW4gPSBtaW52YWx1ZTtcbiAgICB0aGlzLnNlbGVjdGVkTWF4ID0gbWF4dmFsdWU7XG5cbiAgICB0aGlzLnVwZGF0ZVNlbGVjdGlvbigpO1xuICAgIHRoaXMuc3VtID0gdGhpcy5zdW1SYW5nZSgpO1xuXG4gICAgY29uc3QgYXZndmFsdWUgPSBNYXRoLmNlaWwoKG1pbnZhbHVlICsgbWF4dmFsdWUpIC8gMik7XG4gICAgdGhpcy5kcmF3KGF2Z3ZhbHVlKTtcbiAgfVxuXG5cbiAgcHVibGljIHN1bVJhbmdlKCk6IG51bWJlciB7XG4gICAgbGV0IHN1bSA9IDA7XG4gICAgdGhpcy5kYXRhLmZhY2V0R3JvdXBEYXRhLmZvckVhY2goKGZhY2V0KSA9PiB7XG4gICAgICBpZiAodGhpcy5pc0luUmFuZ2UoZmFjZXQpKSB7XG4gICAgICAgIHN1bSArPSBmYWNldC5jb3VudDtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gc3VtO1xuICB9XG5cbiAgcHVibGljIG9uU2VsZWN0aW9uQ2hhbmdlKCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHtcbiAgICAgIG5hbWU6IHRoaXMuZGF0YS5mYWNldEdyb3VwTmFtZSxcbiAgICAgIHNlbGVjdGVkOiB0aGlzLmRhdGEuc2VsZWN0ZWRSYW5nZSxcbiAgICAgIGNvdW50OiB0aGlzLnN1bVJhbmdlKClcbiAgICB9IGFzIFNlYXJjaEZhY2V0U2VsZWN0aW9uO1xuICAgIHRoaXMuX3NlbGVjdGlvbkNoYW5nZS5lbWl0KHNlbGVjdGlvbik7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVNlbGVjdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLmRhdGEuc2VsZWN0ZWRSYW5nZSA9IHtcbiAgICAgIHN0YXJ0OiB0aGlzLnNlbGVjdGVkTWluLFxuICAgICAgZW5kOiB0aGlzLnNlbGVjdGVkTWF4XG4gICAgfSBhcyBTZWxlY3RlZFJhbmdlO1xuICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNJblJhbmdlKGZhY2V0OiBTZWFyY2hGYWNldE1vZGVsKTogYm9vbGVhbiB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLnBhcnNlSW50KGZhY2V0LmxhYmVsKTtcbiAgICByZXR1cm4gdmFsdWUgPj0gdGhpcy5wYXJzZUludCh0aGlzLnNlbGVjdGVkTWluKSAmJiB2YWx1ZSA8PSB0aGlzLnBhcnNlSW50KHRoaXMuc2VsZWN0ZWRNYXgpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUludCh2YWx1ZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KHZhbHVlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFBhcnNpbmcgJHt2YWx1ZX0gdG8gbnVtYmVyIGZhaWxlZCEgYCArIGUubWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMub25SZXNpemUgPSBmdW5jdGlvbigpOiB2b2lkIHt9O1xuICAgIHRoaXMubWluRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdpbnB1dCcsICgpID0+IHRoaXMudXBkYXRlKTtcbiAgICB0aGlzLm1heEVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignaW5wdXQnLCAoKSA9PiB0aGlzLnVwZGF0ZSk7XG4gIH1cbn1cbiJdfQ==