UNPKG

@offensichtbar-codestock/ngx-flex-masonry-grid

Version:

Angular Module for displaying items in a flex-based masonry layout without any third party dependencies

171 lines (169 loc) 25.9 kB
import { Component, ElementRef, ContentChildren, HostListener, Output, EventEmitter } from '@angular/core'; import { NgxFlexMasonryGridItemComponent } from './ngx-flex-masonry-grid-item.component'; import { NgxFlexMasonryGridService } from "./ngx-flex-masonry-grid.service"; import { CIRCULAR_IMPORT_PARENT } from './circular-imports'; import { takeWhile } from 'rxjs/operators'; export class NgxFlexMasonryGridComponent { constructor(_element, service) { this._element = _element; this.service = service; // Outputs this.layoutComplete = new EventEmitter(); this.itemRemoved = new EventEmitter(); this.itemLoaded = new EventEmitter(); this.itemsLoaded = new EventEmitter(); this._timeoutID = 0; this._cols = 0; this._rows = 0; this._item_heights = []; this._row_heights = []; this.isAlive = true; this.service.layoutshouldbeupdated.pipe(takeWhile(() => this.isAlive)).subscribe((item) => { this.itemLoaded.emit(item); item.playAnimation(); item.isready = true; this.layout(); }); this.service.imageobserved.pipe(takeWhile(() => this.isAlive)).subscribe((param) => { this.add(param); }); this.service.itemremoved.pipe(takeWhile(() => this.isAlive)).subscribe((item) => { this.itemRemoved.emit(item); this.layout(); }); this.service.allitemsloaded.pipe(takeWhile(() => this.isAlive)).subscribe(() => { this.itemsLoaded.emit(this.items.length); this.layout(); }); } onResize(event) { clearTimeout(this._timeoutID); this._timeoutID = setTimeout(() => { this.layout(); }, 40); } ngOnInit() { } forceUpdateLayout() { var _a, _b; if (((_a = this.items) === null || _a === void 0 ? void 0 : _a.length) && ((_b = this.items) === null || _b === void 0 ? void 0 : _b.length) !== 0) { let items = this.items.toArray().filter((item) => { return item.isready; }); if (this.service.loadeditems.length === items.length) { this.layout(); } } } layout() { var _a; if (!((_a = this.items) === null || _a === void 0 ? void 0 : _a.length)) return; this._cols = Math.round(this._element.nativeElement.offsetWidth / this.items.toArray()[0].width); this._rows = Math.ceil(this.items.length / this._cols); this._item_heights = this.items.map(el => el.height); this._row_heights = this.getRowHeights(); const offsets = this.getElementOffsets(); this.translateElements(offsets); if (this.service.loadeditems.length === this.items.length) { this.layoutComplete.emit(); } } add(params) { this.service.addItem(params.item, this.items.length); } getRowHeights() { let rowheights = []; for (let row = 0; row < this._rows; row++) { const heightgroup = this._item_heights.slice(row * this._cols, (row + 1) * this._cols); // heightgroup caches slice (slice length === cols length) of _el_heights array const rowHeights = Math.max(...heightgroup); rowheights.push(rowHeights); } return rowheights; } getElementOffsets() { const el_heightgap = [...Array(this._cols)].map(e => []); this._item_heights.forEach((height, index) => { const current_gap = this._row_heights[Math.floor(index / this._cols)] - height; el_heightgap[index % this._cols].push(current_gap); }); const el_offsets = [...Array(this._cols)].map(e => []); /** * Accumulates element offsets (final translation values) from el_heightgap array * Resets translation for first row by unshifting value zero to each subarray */ for (let gap = 0; gap < el_heightgap.length; gap++) { let accumulation = 0; // Cache for accumulated height differences for each col el_offsets[gap] = el_heightgap[gap].map((val) => accumulation += val); // Maps accumulated height difference values to offset array el_offsets[gap].pop(); // Removes last value, because the last element needs to be translated by the value of its predecessor el_offsets[gap].unshift(0); // Adds zero offsets for first item per col, because first item doesn't need to be translated } let elementoffsets = []; for (let i = 0; i < this.items.length; i++) { const iterator = i % el_offsets.length; const counter = Math.floor(i / el_offsets.length); elementoffsets.push(el_offsets[iterator][counter]); } this.setContainerHeight(); return elementoffsets; } setContainerHeight() { var _a; if (this.items.length <= 0) return; let containerHeight = []; for (let col = 0; col < this._cols; col++) { containerHeight.push([0]); let i = 0; while (col + this._cols * i < this.items.length) { let currVal = containerHeight[col % this._cols]; let newVal = (_a = this.items.toArray()[col + i * this._cols]) === null || _a === void 0 ? void 0 : _a.height; containerHeight[col % this._cols] = parseInt(currVal) + newVal; i++; } } this._element.nativeElement.style.height = `${Math.max(...containerHeight)}px`; } translateElements(heights) { this.items.forEach((child, index) => { child.translateY = heights[index]; }); } ngAfterContentInit() { } ngOnDestroy() { this.isAlive = false; this.service.clearStack(); } } NgxFlexMasonryGridComponent.decorators = [ { type: Component, args: [{ selector: 'osb-ngx-flexmasonry-grid', template: '<ng-content></ng-content> ', providers: [ NgxFlexMasonryGridService, { provide: CIRCULAR_IMPORT_PARENT, useExisting: NgxFlexMasonryGridComponent } ], styles: [` :host::ng-deep > * { visibility: hidden; box-sizing: border-box; backface-visibility:hidden; } `] },] } ]; NgxFlexMasonryGridComponent.ctorParameters = () => [ { type: ElementRef }, { type: NgxFlexMasonryGridService } ]; NgxFlexMasonryGridComponent.propDecorators = { layoutComplete: [{ type: Output }], itemRemoved: [{ type: Output }], itemLoaded: [{ type: Output }], itemsLoaded: [{ type: Output }], items: [{ type: ContentChildren, args: [NgxFlexMasonryGridItemComponent,] }], onResize: [{ type: HostListener, args: ['window:resize', ['$event'],] }] }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWZsZXgtbWFzb25yeS1ncmlkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1mbGV4LW1hc29ucnktZ3JpZC9zcmMvbGliL25neC1mbGV4LW1hc29ucnktZ3JpZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILFNBQVMsRUFHVCxVQUFVLEVBQ1YsZUFBZSxFQUVmLFlBQVksRUFFWixNQUFNLEVBQ04sWUFBWSxFQUNmLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBRXpGLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzVFLE9BQU8sRUFBQyxzQkFBc0IsRUFBd0IsTUFBTSxvQkFBb0IsQ0FBQztBQUNqRixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUF3QjNDLE1BQU0sT0FBTywyQkFBMkI7SUE0QnBDLFlBQW9CLFFBQW9CLEVBQVMsT0FBa0M7UUFBL0QsYUFBUSxHQUFSLFFBQVEsQ0FBWTtRQUFTLFlBQU8sR0FBUCxPQUFPLENBQTJCO1FBMUJuRixVQUFVO1FBQ0EsbUJBQWMsR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUM1RCxnQkFBVyxHQUFrRCxJQUFJLFlBQVksRUFBbUMsQ0FBQztRQUNqSCxlQUFVLEdBQWtELElBQUksWUFBWSxFQUFtQyxDQUFDO1FBQ2hILGdCQUFXLEdBQXlCLElBQUksWUFBWSxFQUFVLENBQUM7UUFjakUsZUFBVSxHQUFRLENBQUMsQ0FBQztRQUNuQixVQUFLLEdBQVcsQ0FBQyxDQUFDO1FBQ2xCLFVBQUssR0FBVyxDQUFDLENBQUM7UUFDbkIsa0JBQWEsR0FBa0IsRUFBRSxDQUFDO1FBQ2xDLGlCQUFZLEdBQWtCLEVBQUUsQ0FBQztRQUNqQyxZQUFPLEdBQWEsSUFBSSxDQUFDO1FBSzdC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LFNBQUMsK0JBQStCO3VCQUMvQyxZQUFZLFNBQUMsZUFBZSxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDb21wb25lbnQsIFxuICAgIE9uSW5pdCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgRWxlbWVudFJlZiwgXG4gICAgQ29udGVudENoaWxkcmVuLCBcbiAgICBRdWVyeUxpc3QsIFxuICAgIEhvc3RMaXN0ZW5lciwgXG4gICAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgICBPdXRwdXQsXG4gICAgRXZlbnRFbWl0dGVyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTmd4RmxleE1hc29ucnlHcmlkSXRlbUNvbXBvbmVudCB9IGZyb20gJy4vbmd4LWZsZXgtbWFzb25yeS1ncmlkLWl0ZW0uY29tcG9uZW50JztcbmltcG9ydCB7Tmd4RmxleE1hc29ucnlHcmlkTG9hZGluZ1BhcmFtc30gZnJvbSAnLi9uZ3gtZmxleC1tYXNvbnJ5LWdyaWQtb3B0aW9ucyc7XG5pbXBvcnQgeyBOZ3hGbGV4TWFzb25yeUdyaWRTZXJ2aWNlIH0gZnJvbSBcIi4vbmd4LWZsZXgtbWFzb25yeS1ncmlkLnNlcnZpY2VcIjtcbmltcG9ydCB7Q0lSQ1VMQVJfSU1QT1JUX1BBUkVOVCwgQ2lyY3VsYXJJbXBvcnRzUGFyZW50fSBmcm9tICcuL2NpcmN1bGFyLWltcG9ydHMnO1xuaW1wb3J0IHsgdGFrZVdoaWxlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5AQ29tcG9uZW50KHsgXG4gICAgc2VsZWN0b3I6ICdvc2Itbmd4LWZsZXhtYXNvbnJ5LWdyaWQnLFxuICAgICB0ZW1wbGF0ZTogJzxuZy1jb250ZW50PjwvbmctY29udGVudD4gJywgXG4gICAgIHN0eWxlczogW2BcbiAgICAgICAgXG5cbiAgICAgICAgOmhvc3Q6Om5nLWRlZXAgID4gKiB7ICAgICAgICBcbiAgICAgICAgICAgIHZpc2liaWxpdHk6IGhpZGRlbjtcbiAgICAgICAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgICAgICAgICBiYWNrZmFjZS12aXNpYmlsaXR5OmhpZGRlbjtcbiAgICAgICAgfVxuICAgIGBdLFxuICAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgTmd4RmxleE1hc29ucnlHcmlkU2VydmljZSxcbiAgICAgICAge1xuICAgICAgICAgIHByb3ZpZGU6IENJUkNVTEFSX0lNUE9SVF9QQVJFTlQsXG4gICAgICAgICAgdXNlRXhpc3Rpbmc6IE5neEZsZXhNYXNvbnJ5R3JpZENvbXBvbmVudFxuICAgICAgICB9XG4gICAgICBdXG5cbn0pIFxuICAgICBcbmV4cG9ydCBjbGFzcyBOZ3hGbGV4TWFzb25yeUdyaWRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgQWZ0ZXJDb250ZW50SW5pdCwgQ2lyY3VsYXJJbXBvcnRzUGFyZW50ICB7XG5cbiAgICAvLyBPdXRwdXRzXG4gICAgQE91dHB1dCgpIGxheW91dENvbXBsZXRlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICAgIEBPdXRwdXQoKSBpdGVtUmVtb3ZlZDogRXZlbnRFbWl0dGVyPE5neEZsZXhNYXNvbnJ5R3JpZEl0ZW1Db21wb25lbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxOZ3hGbGV4TWFzb25yeUdyaWRJdGVtQ29tcG9uZW50PigpO1xuICAgIEBPdXRwdXQoKSBpdGVtTG9hZGVkOiBFdmVudEVtaXR0ZXI8Tmd4RmxleE1hc29ucnlHcmlkSXRlbUNvbXBvbmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPE5neEZsZXhNYXNvbnJ5R3JpZEl0ZW1Db21wb25lbnQ+KCk7XG4gICAgQE91dHB1dCgpIGl0ZW1zTG9hZGVkOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG4gICAgLy8gSW5wdXRzXG4gICAgQENvbnRlbnRDaGlsZHJlbihOZ3hGbGV4TWFzb25yeUdyaWRJdGVtQ29tcG9uZW50KSAgaXRlbXMhOiBRdWVyeUxpc3Q8Tmd4RmxleE1hc29ucnlHcmlkSXRlbUNvbXBvbmVudD47XG4gICAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXG4gICAgb25SZXNpemUoZXZlbnQ6YW55KSB7XG5cbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXRJRCk7XG4gICAgICAgIHRoaXMuX3RpbWVvdXRJRCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5sYXlvdXQoKTtcbiAgICAgICAgfSw0MCk7XG4gICAgICAgIFxuICAgIH1cblxuICAgIHByaXZhdGUgX3RpbWVvdXRJRDogYW55ID0gMDtcbiAgICBwcml2YXRlICBfY29sczogbnVtYmVyID0gMDtcbiAgICBwcml2YXRlICBfcm93czogbnVtYmVyID0gMDtcbiAgICBwcml2YXRlIF9pdGVtX2hlaWdodHM6IEFycmF5PG51bWJlcj4gPSBbXTtcbiAgICBwcml2YXRlIF9yb3dfaGVpZ2h0czogQXJyYXk8bnVtYmVyPiA9IFtdO1xuICAgIHByaXZhdGUgaXNBbGl2ZSA6IGJvb2xlYW4gPSB0cnVlO1xuXG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9lbGVtZW50OiBFbGVtZW50UmVmLCBwdWJsaWMgc2VydmljZTogTmd4RmxleE1hc29ucnlHcmlkU2VydmljZSkge1xuXG4gICAgICAgIHRoaXMuc2VydmljZS5sYXlvdXRzaG91bGRiZXVwZGF0ZWQucGlwZSh0YWtlV2hpbGUoKCkgPT4gdGhpcy5pc0FsaXZlKSkuc3Vic2NyaWJlKChpdGVtOk5neEZsZXhNYXNvbnJ5R3JpZEl0ZW1Db21wb25lbnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaXRlbUxvYWRlZC5lbWl0KGl0ZW0pXG4gICAgICAgICAgICBpdGVtLnBsYXlBbmltYXRpb24oKTsgICAgICAgICAgIFxuICAgICAgICAgICAgaXRlbS5pc3JlYWR5ID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMubGF5b3V0KCk7XG4gICAgICAgICAgXG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgdGhpcy5zZXJ2aWNlLmltYWdlb2JzZXJ2ZWQucGlwZSh0YWtlV2hpbGUoKCkgPT4gdGhpcy5pc0FsaXZlKSkuc3Vic2NyaWJlKChwYXJhbTogTmd4RmxleE1hc29ucnlHcmlkTG9hZGluZ1BhcmFtcykgPT4ge1xuICAgICAgICAgICAgdGhpcy5hZGQocGFyYW0pO1xuICAgICAgICB9KTtcblxuICAgICAgIHRoaXMuc2VydmljZS5pdGVtcmVtb3ZlZC5waXBlKHRha2VXaGlsZSgoKSA9PiB0aGlzLmlzQWxpdmUpKS5zdWJzY3JpYmUoKGl0ZW06Tmd4RmxleE1hc29ucnlHcmlkSXRlbUNvbXBvbmVudCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pdGVtUmVtb3ZlZC5lbWl0KGl0ZW0pXG4gICAgICAgICAgICB0aGlzLmxheW91dCgpO1xuICAgICAgICAgICBcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zZXJ2aWNlLmFsbGl0ZW1zbG9hZGVkLnBpcGUodGFrZVdoaWxlKCgpID0+IHRoaXMuaXNBbGl2ZSkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLml0ZW1zTG9hZGVkLmVtaXQodGhpcy5pdGVtcy5sZW5ndGgpO1xuICAgICAgICAgICAgdGhpcy5sYXlvdXQoKTtcbiAgICAgICAgICAgIFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpIHt9XG5cbiAgICBwdWJsaWMgZm9yY2VVcGRhdGVMYXlvdXQoKSB7XG4gICAgICAgIGlmKHRoaXMuaXRlbXM/Lmxlbmd0aCAmJiB0aGlzLml0ZW1zPy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgIGxldCBpdGVtczpBcnJheTxOZ3hGbGV4TWFzb25yeUdyaWRJdGVtQ29tcG9uZW50PiA9IHRoaXMuaXRlbXMudG9BcnJheSgpLmZpbHRlcigoaXRlbTogTmd4RmxleE1hc29ucnlHcmlkSXRlbUNvbXBvbmVudCkgPT4ge1xuICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLmlzcmVhZHk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYodGhpcy5zZXJ2aWNlLmxvYWRlZGl0ZW1zLmxlbmd0aCA9PT0gaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXlvdXQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgbGF5b3V0KCkge1xuICAgICAgICBpZighdGhpcy5pdGVtcz8ubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB0aGlzLl9jb2xzID0gTWF0aC5yb3VuZCh0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGggLyB0aGlzLml0ZW1zLnRvQXJyYXkoKVswXS53aWR0aCApOyBcbiAgICAgICAgdGhpcy5fcm93cyA9IE1hdGguY2VpbCh0aGlzLml0ZW1zLmxlbmd0aCAvIHRoaXMuX2NvbHMpO1xuICAgICAgICB0aGlzLl9pdGVtX2hlaWdodHMgPSB0aGlzLml0ZW1zLm1hcChlbCA9PiBlbC5oZWlnaHQpOyAgICAgIFxuICAgICAgICBcbiAgICAgICAgdGhpcy5fcm93X2hlaWdodHMgPSB0aGlzLmdldFJvd0hlaWdodHMoKTtcblxuICAgICAgICBjb25zdCBvZmZzZXRzID0gdGhpcy5nZXRFbGVtZW50T2Zmc2V0cygpO1xuICAgICAgICB0aGlzLnRyYW5zbGF0ZUVsZW1lbnRzKG9mZnNldHMpOyAgIFxuXG4gICAgICAgIFxuICAgICAgICBpZih0aGlzLnNlcnZpY2UubG9hZGVkaXRlbXMubGVuZ3RoID09PSB0aGlzLml0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5sYXlvdXRDb21wbGV0ZS5lbWl0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkKHBhcmFtczogTmd4RmxleE1hc29ucnlHcmlkTG9hZGluZ1BhcmFtcykge1xuICAgICAgICB0aGlzLnNlcnZpY2UuYWRkSXRlbShwYXJhbXMuaXRlbSwgdGhpcy5pdGVtcy5sZW5ndGgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Um93SGVpZ2h0cygpOiBBcnJheTxudW1iZXI+IHtcblxuICAgICAgICBsZXQgcm93aGVpZ2h0cyA9IFtdO1xuICAgICAgICBmb3IobGV0IHJvdyA9IDA7IHJvdyA8IHRoaXMuX3Jvd3M7IHJvdysrKSB7XG4gICAgICAgICAgICBjb25zdCBoZWlnaHRncm91cCA9IHRoaXMuX2l0ZW1faGVpZ2h0cy5zbGljZShyb3cgKiB0aGlzLl9jb2xzLCAocm93ICsgMSkgKiB0aGlzLl9jb2xzKTsgLy8gaGVpZ2h0Z3JvdXAgY2FjaGVzIHNsaWNlIChzbGljZSBsZW5ndGggPT09IGNvbHMgbGVuZ3RoKSBvZiBfZWxfaGVpZ2h0cyBhcnJheVxuICAgICAgICAgICAgY29uc3Qgcm93SGVpZ2h0cyA9IE1hdGgubWF4KC4uLmhlaWdodGdyb3VwKTtcbiAgICAgICAgICAgIHJvd2hlaWdodHMucHVzaChyb3dIZWlnaHRzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByb3doZWlnaHRzO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RWxlbWVudE9mZnNldHMoKTogQXJyYXk8bnVtYmVyPiB7XG5cbiAgICAgICAgY29uc3QgZWxfaGVpZ2h0Z2FwOmFueVtdID0gWy4uLkFycmF5KHRoaXMuX2NvbHMpXS5tYXAoZSA9PiBbXSk7XG4gICAgICAgIHRoaXMuX2l0ZW1faGVpZ2h0cy5mb3JFYWNoKChoZWlnaHQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50X2dhcDpudW1iZXIgID0gdGhpcy5fcm93X2hlaWdodHNbTWF0aC5mbG9vcihpbmRleCAvIHRoaXMuX2NvbHMpXSAtIGhlaWdodDtcbiAgICAgICAgICAgIGVsX2hlaWdodGdhcFtpbmRleCAlIHRoaXMuX2NvbHNdLnB1c2goY3VycmVudF9nYXApO1xuICAgICAgICB9KTtcblxuICAgICAgICBcbiAgICAgICAgY29uc3QgZWxfb2Zmc2V0czphbnlbXSA9IFsuLi5BcnJheSh0aGlzLl9jb2xzKV0ubWFwKGUgPT4gW10pO1xuICAgICAgICBcbiAgICAgICAgLyoqXG4gICAgICAgICAqICBBY2N1bXVsYXRlcyBlbGVtZW50IG9mZnNldHMgKGZpbmFsIHRyYW5zbGF0aW9uIHZhbHVlcykgZnJvbSBlbF9oZWlnaHRnYXAgYXJyYXlcbiAgICAgICAgICogIFJlc2V0cyB0cmFuc2xhdGlvbiBmb3IgZmlyc3Qgcm93IGJ5IHVuc2hpZnRpbmcgdmFsdWUgemVybyB0byBlYWNoIHN1YmFycmF5XG4gICAgICAgICAqL1xuICAgICAgICBmb3IobGV0IGdhcCA9IDA7IGdhcCA8IGVsX2hlaWdodGdhcC5sZW5ndGg7IGdhcCsrKSB7XG5cbiAgICAgICAgICAgIGxldCBhY2N1bXVsYXRpb24gPSAwOyAvLyBDYWNoZSBmb3IgYWNjdW11bGF0ZWQgaGVpZ2h0IGRpZmZlcmVuY2VzIGZvciBlYWNoIGNvbFxuICAgICAgICAgICAgZWxfb2Zmc2V0c1tnYXBdID0gZWxfaGVpZ2h0Z2FwW2dhcF0ubWFwKCh2YWw6bnVtYmVyKSA9PiBhY2N1bXVsYXRpb24gKz0gdmFsKTsgLy8gTWFwcyBhY2N1bXVsYXRlZCBoZWlnaHQgZGlmZmVyZW5jZSB2YWx1ZXMgdG8gb2Zmc2V0IGFycmF5XG4gICAgICAgICAgICBlbF9vZmZzZXRzW2dhcF0ucG9wKCk7IC8vIFJlbW92ZXMgbGFzdCB2YWx1ZSwgYmVjYXVzZSB0aGUgbGFzdCBlbGVtZW50IG5lZWRzIHRvIGJlIHRyYW5zbGF0ZWQgYnkgdGhlIHZhbHVlIG9mIGl0cyBwcmVkZWNlc3NvclxuICAgICAgICAgICAgZWxfb2Zmc2V0c1tnYXBdLnVuc2hpZnQoMCk7IC8vIEFkZHMgemVybyBvZmZzZXRzIGZvciBmaXJzdCBpdGVtIHBlciBjb2wsIGJlY2F1c2UgZmlyc3QgaXRlbSBkb2Vzbid0IG5lZWQgdG8gYmUgdHJhbnNsYXRlZFxuICAgICAgICB9XG5cbiAgICAgICAgXG4gICAgICAgIGxldCBlbGVtZW50b2Zmc2V0czphbnlbXSA9IFtdO1xuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdGhpcy5pdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgaXRlcmF0b3IgPSBpICUgZWxfb2Zmc2V0cy5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBjb3VudGVyID0gTWF0aC5mbG9vcihpIC8gZWxfb2Zmc2V0cy5sZW5ndGgpO1xuICAgICAgICAgICAgZWxlbWVudG9mZnNldHMucHVzaChlbF9vZmZzZXRzW2l0ZXJhdG9yXVtjb3VudGVyXSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldENvbnRhaW5lckhlaWdodCgpO1xuXG4gICAgICAgIHJldHVybiBlbGVtZW50b2Zmc2V0cztcbiAgICAgICBcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldENvbnRhaW5lckhlaWdodCgpIHtcbiAgICAgICAgaWYodGhpcy5pdGVtcy5sZW5ndGggPD0gMClcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBsZXQgY29udGFpbmVySGVpZ2h0OmFueVtdID0gW107XG4gICAgICAgIGZvcihsZXQgY29sOm51bWJlciA9IDA7IGNvbCA8IHRoaXMuX2NvbHM7IGNvbCsrKSB7XG4gICAgICAgICAgICBjb250YWluZXJIZWlnaHQucHVzaChbMF0pO1xuICAgICAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICAgICAgd2hpbGUoY29sICsgdGhpcy5fY29scyAqIGkgPCB0aGlzLml0ZW1zLmxlbmd0aCl7XG4gICAgICAgICAgICAgICAgbGV0IGN1cnJWYWw6YW55ID0gY29udGFpbmVySGVpZ2h0W2NvbCAlIHRoaXMuX2NvbHNdO1xuICAgICAgICAgICAgICAgIGxldCBuZXdWYWw6YW55ID0gdGhpcy5pdGVtcy50b0FycmF5KClbY29sICsgaSAqIHRoaXMuX2NvbHNdPy5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgY29udGFpbmVySGVpZ2h0W2NvbCAlIHRoaXMuX2NvbHNdID0gcGFyc2VJbnQoY3VyclZhbCkgKyBuZXdWYWw7XG4gICAgICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fZWxlbWVudC5uYXRpdmVFbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke01hdGgubWF4KC4uLmNvbnRhaW5lckhlaWdodCl9cHhgO1xuICAgIH1cblxuICAgIHByaXZhdGUgdHJhbnNsYXRlRWxlbWVudHMoaGVpZ2h0czogQXJyYXk8YW55Pikge1xuICAgICAgICB0aGlzLml0ZW1zLmZvckVhY2goKGNoaWxkLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY2hpbGQudHJhbnNsYXRlWSA9IGhlaWdodHNbaW5kZXhdOyBcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCkge31cbiAgICBcblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLmlzQWxpdmUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zZXJ2aWNlLmNsZWFyU3RhY2soKTtcbiAgICB9XG4gICAgXG5cbn1cbiJdfQ==