ngx-crystal-gallery
Version:
Responsive gallery with support for masonry layout and lightbox.
282 lines (281 loc) • 29.6 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, ElementRef, HostListener, Input, Output, EventEmitter } from '@angular/core';
/**
* @record
*/
export function Image() { }
/** @type {?} */
Image.prototype.path;
/** @type {?} */
Image.prototype.width;
/** @type {?} */
Image.prototype.height;
/** @type {?|undefined} */
Image.prototype.computedHeight;
/** @type {?|undefined} */
Image.prototype.computedWidth;
/** @type {?|undefined} */
Image.prototype.margin;
;
/**
* @record
*/
export function Images() { }
export class MasonryLayoutComponent {
/**
* @param {?} elementRef
*/
constructor(elementRef) {
this.elementRef = elementRef;
this.GUTTER = 0;
this.savedNodeDimensions = [];
this.gridState = 'not started';
this.ENABLE_MASONRY = true;
this.MAX_HEIGHT = 400;
this.events = new EventEmitter();
this.elem = this.elementRef.nativeElement;
}
/**
* @param {?} value
* @return {?}
*/
set gutter(value) {
this.GUTTER = value / 2;
}
/**
* @return {?}
*/
get isMobile() {
/** @type {?} */
var check = false;
(function (a) { if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4)))
check = true; })(navigator.userAgent || navigator.vendor);
return check;
}
;
/**
* @param {?} event
* @return {?}
*/
onWindowResize(event) {
clearTimeout(this.resizeTimer);
this.resizeTimer = setTimeout(() => {
this.gridState = 'not started';
this.buildGrid();
}, 250);
}
/**
* @return {?}
*/
ngOnInit() {
this.buildGrid();
}
/**
* @return {?}
*/
ngOnChanges() {
clearTimeout(this.changesTimer);
this.changesTimer = setTimeout(() => {
this.gridState = 'not started';
this.buildGrid();
}, 250);
}
/**
* @return {?}
*/
buildGrid() {
/** @type {?} */
let parentWidth = Math.floor(this.elem.parentNode.offsetWidth);
/** @type {?} */
let totalRowWidth = 0;
/** @type {?} */
let row = {
startIndex: 0,
endIndex: 0,
length: 0,
totalWidth: 0
};
if (!this.images || !this.images.length) {
return;
}
this.elem.style.width = parentWidth + 'px';
this.elem.style.display = 'table';
this.images.forEach((node, index) => {
if (row.totalWidth === 0) {
row.startIndex = index;
row.length = 0;
}
row.length++;
row.totalWidth += this.getComputedWidth(index);
if (row.totalWidth >= parentWidth || this.isLastChild(index)) {
row.endIndex = index;
/** @type {?} */
let scaling = row.totalWidth / parentWidth;
this.setColDimensions(scaling, row);
row.totalWidth = 0;
}
});
}
/**
* @param {?} scaling
* @param {?} row
* @return {?}
*/
setColDimensions(scaling, row) {
/** @type {?} */
let totalRowWidth = 0;
/** @type {?} */
let parentWidth = this.elem.parentNode.offsetWidth;
scaling = (scaling < 1) ? 1 : scaling;
this.images.forEach((node, index) => {
if (!this.ENABLE_MASONRY) {
node.computedHeight = this.MAX_HEIGHT + 'px';
node.computedWidth = this.getComputedWidth(index) + 'px';
node.margin = this.getNodeMargin(parentWidth);
return;
}
if (index >= row.startIndex && index <= row.endIndex) {
/** @type {?} */
let nodeWidth;
// last image
if (index === row.endIndex && scaling > 1) {
nodeWidth = (100 - totalRowWidth) - ((this.GUTTER * 2) / parentWidth * 100);
node.computedWidth = 'calc(' + nodeWidth + '%)';
if (this.gridState === 'not started') {
this.gridState = 'pre-building';
setTimeout(() => {
this.buildGrid();
}, 100);
}
}
else {
nodeWidth = ((this.getComputedWidth(index) / scaling) / parentWidth * 100) - ((row.length * (this.GUTTER * 2)) * (this.getComputedWidth(index) / scaling) / parentWidth) / parentWidth * 100;
node.computedWidth = 'calc(' + nodeWidth + '%)';
totalRowWidth += nodeWidth;
totalRowWidth += (this.GUTTER / parentWidth * 100) * 2;
}
// last row and last image
if (index === row.endIndex && row.length === 1 && this.isMobile) {
nodeWidth = 100 - ((this.GUTTER * 2) / parentWidth * 100);
/** @type {?} */
let height = node.height * (parentWidth * (nodeWidth / 100) / node.width);
if (height / 2 < this.MAX_HEIGHT) {
node.computedWidth = 'calc(' + nodeWidth + '%)';
}
}
node.margin = this.getNodeMargin(parentWidth);
node.computedHeight = node.height * (parentWidth * (nodeWidth / 100) / node.width) + 'px';
}
});
}
/**
* @param {?} index
* @return {?}
*/
getComputedWidth(index) {
return this.images[index].width / (this.images[index].height / this.MAX_HEIGHT);
}
/**
* @param {?} index
* @return {?}
*/
isLastChild(index) {
return index + 1 === this.images.length;
}
/**
* @param {?} parentWidth
* @return {?}
*/
getNodeMargin(parentWidth) {
return 'calc(' + this.GUTTER / parentWidth * 100 + '%)';
}
/**
* @param {?} image
* @param {?} i
* @return {?}
*/
clickOnImage(image, i) {
this.events.emit({
type: 'click-on-image',
image: image,
index: i
});
}
/**
* @param {?} elem
* @return {?}
*/
onImageLoaded(elem) {
elem.style.opacity = 1;
}
}
MasonryLayoutComponent.decorators = [
{ type: Component, args: [{
selector: 'masonry-layout',
template: `<div
[ngClass]="CLASS_NAME"
*ngFor="let image of images; let i = index;"
[style.width]="image.computedWidth"
[style.height]="image.computedHeight"
[style.float]="'left'"
[style.margin]="image.margin"
[style.background]="'#eeeeee'"
[style.lineHeight]="0">
<img
#imageElem
[src]="image.preview || image.full"
[style.width.%]="100"
[style.height]="'auto'"
[style.opacity]="0"
(click)="clickOnImage(image, i)"
(load)="onImageLoaded(imageElem)" />
</div>`,
},] },
];
/** @nocollapse */
MasonryLayoutComponent.ctorParameters = () => [
{ type: ElementRef }
];
MasonryLayoutComponent.propDecorators = {
images: [{ type: Input, args: ['images',] }],
ENABLE_MASONRY: [{ type: Input, args: ['masonry',] }],
MAX_HEIGHT: [{ type: Input, args: ['max-height',] }],
CLASS_NAME: [{ type: Input, args: ['class-name',] }],
gutter: [{ type: Input, args: ['gutter',] }],
events: [{ type: Output }],
onWindowResize: [{ type: HostListener, args: ['window:resize', ['$event'],] }]
};
if (false) {
/** @type {?} */
MasonryLayoutComponent.prototype.GUTTER;
/** @type {?} */
MasonryLayoutComponent.prototype.nodes;
/** @type {?} */
MasonryLayoutComponent.prototype.elem;
/** @type {?} */
MasonryLayoutComponent.prototype.savedNodeDimensions;
/** @type {?} */
MasonryLayoutComponent.prototype.observer;
/** @type {?} */
MasonryLayoutComponent.prototype.gridState;
/** @type {?} */
MasonryLayoutComponent.prototype.resizeTimer;
/** @type {?} */
MasonryLayoutComponent.prototype.changesTimer;
/** @type {?} */
MasonryLayoutComponent.prototype.images;
/** @type {?} */
MasonryLayoutComponent.prototype.ENABLE_MASONRY;
/** @type {?} */
MasonryLayoutComponent.prototype.MAX_HEIGHT;
/** @type {?} */
MasonryLayoutComponent.prototype.CLASS_NAME;
/** @type {?} */
MasonryLayoutComponent.prototype.events;
/** @type {?} */
MasonryLayoutComponent.prototype.elementRef;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFzb25yeS1sYXlvdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWNyeXN0YWwtZ2FsbGVyeS8iLCJzb3VyY2VzIjpbImxpYi9tYXNvbnJ5LWxheW91dC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFxQixZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBU25ILENBQUM7Ozs7O0FBMEJGLE1BQU07Ozs7SUE0QkYsWUFBb0IsVUFBc0I7UUFBdEIsZUFBVSxHQUFWLFVBQVUsQ0FBWTtzQkEzQnpCLENBQUM7bUNBR1MsRUFBRTt5QkFFVCxhQUFhOzhCQUtXLElBQUk7MEJBQ04sR0FBRztzQkFRUCxJQUFJLFlBQVksRUFBTztRQVN6RCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO0tBQzdDOzs7OztJQWZELElBQ0ksTUFBTSxDQUFDLEtBQWE7UUFDcEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFDO0tBQzNCOzs7O0lBSUQsSUFBSSxRQUFROztRQUNSLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNsQixDQUFDLFVBQVMsQ0FBQyxJQUFFLEVBQUUsQ0FBQSxDQUFDLDBUQUEwVCxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBRSx5a0RBQXlrRCxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxFQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsU0FBUyxJQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxK0QsTUFBTSxDQUFDLEtBQUssQ0FBQztLQUNoQjtJQUFBLENBQUM7Ozs7O0lB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QUMsUUFBUTs2QkFDZCxLQUFLLFNBQUMsU0FBUzt5QkFDZixLQUFLLFNBQUMsWUFBWTt5QkFDbEIsS0FBSyxTQUFDLFlBQVk7cUJBRWxCLEtBQUssU0FBQyxRQUFRO3FCQUtkLE1BQU07NkJBWU4sWUFBWSxTQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT3V0cHV0LCBPbkluaXQsIE9uQ2hhbmdlcywgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1hZ2Uge1xuICAgIHBhdGg6IHN0cmluZzsgXG4gICAgd2lkdGg6IG51bWJlcjsgXG4gICAgaGVpZ2h0OiBudW1iZXI7XG4gICAgY29tcHV0ZWRIZWlnaHQ/OiBzdHJpbmc7XG4gICAgY29tcHV0ZWRXaWR0aD86IHN0cmluZztcbiAgICBtYXJnaW4/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEltYWdlcyBleHRlbmRzIEFycmF5PEltYWdlPnt9XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbWFzb25yeS1sYXlvdXQnLCBcbiAgICB0ZW1wbGF0ZTogYDxkaXYgXG5cdFtuZ0NsYXNzXT1cIkNMQVNTX05BTUVcIlxuXHQqbmdGb3I9XCJsZXQgaW1hZ2Ugb2YgaW1hZ2VzOyBsZXQgaSA9IGluZGV4O1wiXG4gICAgW3N0eWxlLndpZHRoXT1cImltYWdlLmNvbXB1dGVkV2lkdGhcIlxuICAgIFtzdHlsZS5oZWlnaHRdPVwiaW1hZ2UuY29tcHV0ZWRIZWlnaHRcIlxuICAgIFtzdHlsZS5mbG9hdF09XCInbGVmdCdcIlxuICAgIFtzdHlsZS5tYXJnaW5dPVwiaW1hZ2UubWFyZ2luXCJcbiAgICBbc3R5bGUuYmFja2dyb3VuZF09XCInI2VlZWVlZSdcIlxuICAgIFtzdHlsZS5saW5lSGVpZ2h0XT1cIjBcIj5cblx0PGltZyBcbiAgICAgICAgI2ltYWdlRWxlbVxuICAgICAgICBbc3JjXT1cImltYWdlLnByZXZpZXcgfHwgaW1hZ2UuZnVsbFwiIFxuICAgICAgICBbc3R5bGUud2lkdGguJV09XCIxMDBcIiBcbiAgICAgICAgW3N0eWxlLmhlaWdodF09XCInYXV0bydcIlxuICAgICAgICBbc3R5bGUub3BhY2l0eV09XCIwXCJcbiAgICAgICAgKGNsaWNrKT1cImNsaWNrT25JbWFnZShpbWFnZSwgaSlcIlxuICAgICAgICAobG9hZCk9XCJvbkltYWdlTG9hZGVkKGltYWdlRWxlbSlcIiAvPlxuPC9kaXY+YCxcbn0pXG5cbmV4cG9ydCBjbGFzcyBNYXNvbnJ5TGF5b3V0Q29tcG9uZW50IHtcbiAgICBHVVRURVI6IG51bWJlciA9IDA7XG4gICAgbm9kZXM6IGFueTtcbiAgICBlbGVtOiBhbnk7XG4gICAgc2F2ZWROb2RlRGltZW5zaW9uczogYW55ID0gW107XG4gICAgb2JzZXJ2ZXI6IGFueTtcbiAgICBncmlkU3RhdGU6IHN0cmluZyA9ICdub3Qgc3RhcnRlZCc7XG4gICAgcmVzaXplVGltZXI6IGFueTtcbiAgICBjaGFuZ2VzVGltZXI6IGFueTtcblxuICAgIEBJbnB1dCgnaW1hZ2VzJykgaW1hZ2VzOiBJbWFnZXM7IFxuICAgIEBJbnB1dCgnbWFzb25yeScpIEVOQUJMRV9NQVNPTlJZOiBib29sZWFuID0gdHJ1ZTsgXG4gICAgQElucHV0KCdtYXgtaGVpZ2h0JykgTUFYX0hFSUdIVDogbnVtYmVyID0gNDAwOyBcbiAgICBASW5wdXQoJ2NsYXNzLW5hbWUnKSBDTEFTU19OQU1FOiBzdHJpbmcgfCB7IFtrZXk6IHN0cmluZ106IGFueTsgfTtcblxuICAgIEBJbnB1dCgnZ3V0dGVyJylcbiAgICBzZXQgZ3V0dGVyKHZhbHVlOiBudW1iZXIpe1xuICAgICAgICB0aGlzLkdVVFRFUiA9IHZhbHVlIC8gMjtcbiAgICB9XG5cbiAgICBAT3V0cHV0KCkgZXZlbnRzOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICAgICBcbiAgICBnZXQgaXNNb2JpbGUoKTpib29sZWFuIHtcbiAgICAgICAgdmFyIGNoZWNrID0gZmFsc2U7XG4gICAgICAgIChmdW5jdGlvbihhKXtpZigvKGFuZHJvaWR8YmJcXGQrfG1lZWdvKS4rbW9iaWxlfGF2YW50Z298YmFkYVxcL3xibGFja2JlcnJ5fGJsYXplcnxjb21wYWx8ZWxhaW5lfGZlbm5lY3xoaXB0b3B8aWVtb2JpbGV8aXAoaG9uZXxvZCl8aXJpc3xraW5kbGV8bGdlIHxtYWVtb3xtaWRwfG1tcHxtb2JpbGUuK2ZpcmVmb3h8bmV0ZnJvbnR8b3BlcmEgbShvYnxpbilpfHBhbG0oIG9zKT98cGhvbmV8cChpeGl8cmUpXFwvfHBsdWNrZXJ8cG9ja2V0fHBzcHxzZXJpZXMoNHw2KTB8c3ltYmlhbnx0cmVvfHVwXFwuKGJyb3dzZXJ8bGluayl8dm9kYWZvbmV8d2FwfHdpbmRvd3MgY2V8eGRhfHhpaW5vL2kudGVzdChhKXx8LzEyMDd8NjMxMHw2NTkwfDNnc298NHRocHw1MFsxLTZdaXw3NzBzfDgwMnN8YSB3YXxhYmFjfGFjKGVyfG9vfHNcXC0pfGFpKGtvfHJuKXxhbChhdnxjYXxjbyl8YW1vaXxhbihleHxueXx5dyl8YXB0dXxhcihjaHxnbyl8YXModGV8dXMpfGF0dHd8YXUoZGl8XFwtbXxyIHxzICl8YXZhbnxiZShja3xsbHxucSl8YmkobGJ8cmQpfGJsKGFjfGF6KXxicihlfHYpd3xidW1ifGJ3XFwtKG58dSl8YzU1XFwvfGNhcGl8Y2N3YXxjZG1cXC18Y2VsbHxjaHRtfGNsZGN8Y21kXFwtfGNvKG1wfG5kKXxjcmF3fGRhKGl0fGxsfG5nKXxkYnRlfGRjXFwtc3xkZXZpfGRpY2F8ZG1vYnxkbyhjfHApb3xkcygxMnxcXC1kKXxlbCg0OXxhaSl8ZW0obDJ8dWwpfGVyKGljfGswKXxlc2w4fGV6KFs0LTddMHxvc3x3YXx6ZSl8ZmV0Y3xmbHkoXFwtfF8pfGcxIHV8ZzU2MHxnZW5lfGdmXFwtNXxnXFwtbW98Z28oXFwud3xvZCl8Z3IoYWR8dW4pfGhhaWV8aGNpdHxoZFxcLShtfHB8dCl8aGVpXFwtfGhpKHB0fHRhKXxocCggaXxpcCl8aHNcXC1jfGh0KGMoXFwtfCB8X3xhfGd8cHxzfHQpfHRwKXxodShhd3x0Yyl8aVxcLSgyMHxnb3xtYSl8aTIzMHxpYWMoIHxcXC18XFwvKXxpYnJvfGlkZWF8aWcwMXxpa29tfGltMWt8aW5ub3xpcGFxfGlyaXN8amEodHx2KWF8amJyb3xqZW11fGppZ3N8a2RkaXxrZWppfGtndCggfFxcLyl8a2xvbnxrcHQgfGt3Y1xcLXxreW8oY3xrKXxsZShub3x4aSl8bGcoIGd8XFwvKGt8bHx1KXw1MHw1NHxcXC1bYS13XSl8bGlid3xseW54fG0xXFwtd3xtM2dhfG01MFxcL3xtYSh0ZXx1aXx4byl8bWMoMDF8MjF8Y2EpfG1cXC1jcnxtZShyY3xyaSl8bWkobzh8b2F8dHMpfG1tZWZ8bW8oMDF8MDJ8Yml8ZGV8ZG98dChcXC18IHxvfHYpfHp6KXxtdCg1MHxwMXx2ICl8bXdicHxteXdhfG4xMFswLTJdfG4yMFsyLTNdfG4zMCgwfDIpfG41MCgwfDJ8NSl8bjcoMCgwfDEpfDEwKXxuZSgoY3xtKVxcLXxvbnx0Znx3Znx3Z3x3dCl8bm9rKDZ8aSl8bnpwaHxvMmltfG9wKHRpfHd2KXxvcmFufG93ZzF8cDgwMHxwYW4oYXxkfHQpfHBkeGd8cGcoMTN8XFwtKFsxLThdfGMpKXxwaGlsfHBpcmV8cGwoYXl8dWMpfHBuXFwtMnxwbyhja3xydHxzZSl8cHJveHxwc2lvfHB0XFwtZ3xxYVxcLWF8cWMoMDd8MTJ8MjF8MzJ8NjB8XFwtWzItN118aVxcLSl8cXRla3xyMzgwfHI2MDB8cmFrc3xyaW05fHJvKHZlfHpvKXxzNTVcXC98c2EoZ2V8bWF8bW18bXN8bnl8dmEpfHNjKDAxfGhcXC18b298cFxcLSl8c2RrXFwvfHNlKGMoXFwtfDB8MSl8NDd8bWN8bmR8cmkpfHNnaFxcLXxzaGFyfHNpZShcXC18bSl8c2tcXC0wfHNsKDQ1fGlkKXxzbShhbHxhcnxiM3xpdHx0NSl8c28oZnR8bnkpfHNwKDAxfGhcXC18dlxcLXx2ICl8c3koMDF8bWIpfHQyKDE4fDUwKXx0NigwMHwxMHwxOCl8dGEoZ3R8bGspfHRjbFxcLXx0ZGdcXC18dGVsKGl8bSl8dGltXFwtfHRcXC1tb3x0byhwbHxzaCl8dHMoNzB8bVxcLXxtM3xtNSl8dHhcXC05fHVwKFxcLmJ8ZzF8c2kpfHV0c3R8djQwMHx2NzUwfHZlcml8dmkocmd8dGUpfHZrKDQwfDVbMC0zXXxcXC12KXx2bTQwfHZvZGF8dnVsY3x2eCg1Mnw1M3w2MHw2MXw3MHw4MHw4MXw4M3w4NXw5OCl8dzNjKFxcLXwgKXx3ZWJjfHdoaXR8d2koZyB8bmN8bncpfHdtbGJ8d29udXx4NzAwfHlhc1xcLXx5b3VyfHpldG98enRlXFwtL2kudGVzdChhLnN1YnN0cigwLDQpKSkgY2hlY2sgPSB0cnVlO30pKG5hdmlnYXRvci51c2VyQWdlbnR8fG5hdmlnYXRvci52ZW5kb3IpO1xuICAgICAgICByZXR1cm4gY2hlY2s7XG4gICAgfTtcbiAgICAgXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmKXtcbiAgICAgICAgdGhpcy5lbGVtID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXG4gICAgb25XaW5kb3dSZXNpemUoZXZlbnQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucmVzaXplVGltZXIpO1xuXG4gICAgICAgIHRoaXMucmVzaXplVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ3JpZFN0YXRlID0gJ25vdCBzdGFydGVkJztcbiAgICAgICAgICAgIHRoaXMuYnVpbGRHcmlkKCk7IFxuICAgICAgICB9LCAyNTApO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmJ1aWxkR3JpZCgpO1xuICAgIH1cblxuICAgIG5nT25DaGFuZ2VzKCl7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmNoYW5nZXNUaW1lcik7XG5cbiAgICAgICAgdGhpcy5jaGFuZ2VzVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ3JpZFN0YXRlID0gJ25vdCBzdGFydGVkJztcbiAgICAgICAgICAgIHRoaXMuYnVpbGRHcmlkKCk7IFxuICAgICAgICB9LCAyNTApO1xuICAgIH1cblxuICAgIGJ1aWxkR3JpZCgpe1xuICAgICAgICBsZXQgcGFyZW50V2lkdGggPSBNYXRoLmZsb29yKHRoaXMuZWxlbS5wYXJlbnROb2RlLm9mZnNldFdpZHRoKTtcbiAgICAgICAgbGV0IHRvdGFsUm93V2lkdGg6IGFueSA9IDA7IFxuICAgICAgICBsZXQgcm93OiBhbnkgPSB7XG4gICAgICAgICAgICBzdGFydEluZGV4OiAwLFxuICAgICAgICAgICAgZW5kSW5kZXg6IDAsXG4gICAgICAgICAgICBsZW5ndGg6IDAsXG4gICAgICAgICAgICB0b3RhbFdpZHRoOiAwXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKCF0aGlzLmltYWdlcyB8fCAhdGhpcy5pbWFnZXMubGVuZ3RoKXtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWxlbS5zdHlsZS53aWR0aCA9IHBhcmVudFdpZHRoICsncHgnO1xuICAgICAgICB0aGlzLmVsZW0uc3R5bGUuZGlzcGxheSA9ICd0YWJsZSc7XG5cbiAgICAgICAgdGhpcy5pbWFnZXMuZm9yRWFjaCgobm9kZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGlmIChyb3cudG90YWxXaWR0aCA9PT0gMCl7XG4gICAgICAgICAgICAgICAgcm93LnN0YXJ0SW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgICAgICByb3cubGVuZ3RoID0gMDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcm93Lmxlbmd0aCsrO1xuICAgICAgICAgICAgcm93LnRvdGFsV2lkdGggKz0gdGhpcy5nZXRDb21wdXRlZFdpZHRoKGluZGV4KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKHJvdy50b3RhbFdpZHRoID49IHBhcmVudFdpZHRoIHx8IHRoaXMuaXNMYXN0Q2hpbGQoaW5kZXgpKXtcbiAgICAgICAgICAgICAgICByb3cuZW5kSW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgICAgICBsZXQgc2NhbGluZyA9IHJvdy50b3RhbFdpZHRoL3BhcmVudFdpZHRoO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRDb2xEaW1lbnNpb25zKHNjYWxpbmcsIHJvdyk7XG4gICAgICAgICAgICAgICAgcm93LnRvdGFsV2lkdGggPSAwOyBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2V0Q29sRGltZW5zaW9ucyhzY2FsaW5nOiBudW1iZXIsIHJvdzogYW55KXtcbiAgICAgICAgbGV0IHRvdGFsUm93V2lkdGg6IGFueSA9IDA7XG4gICAgICAgIGxldCBwYXJlbnRXaWR0aCA9IHRoaXMuZWxlbS5wYXJlbnROb2RlLm9mZnNldFdpZHRoO1xuICAgICAgICBzY2FsaW5nID0gKHNjYWxpbmcgPCAxKSA/IDEgOiBzY2FsaW5nO1xuXG4gICAgICAgIHRoaXMuaW1hZ2VzLmZvckVhY2goKG5vZGUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuRU5BQkxFX01BU09OUlkpe1xuICAgICAgICAgICAgICAgIG5vZGUuY29tcHV0ZWRIZWlnaHQgPSB0aGlzLk1BWF9IRUlHSFQgKyAncHgnO1xuICAgICAgICAgICAgICAgIG5vZGUuY29tcHV0ZWRXaWR0aCA9IHRoaXMuZ2V0Q29tcHV0ZWRXaWR0aChpbmRleCkgKyAncHgnO1xuICAgICAgICAgICAgICAgIG5vZGUubWFyZ2luID0gdGhpcy5nZXROb2RlTWFyZ2luKHBhcmVudFdpZHRoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpbmRleCA+PSByb3cuc3RhcnRJbmRleCAmJiBpbmRleCA8PSByb3cuZW5kSW5kZXgpe1xuICAgICAgICAgICAgICAgIGxldCBub2RlV2lkdGg7XG5cbiAgICAgICAgICAgICAgICAvLyBsYXN0IGltYWdlXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID09PSByb3cuZW5kSW5kZXggJiYgc2NhbGluZyA+IDEpeyBcbiAgICAgICAgICAgICAgICAgICAgbm9kZVdpZHRoID0gKDEwMCAtIHRvdGFsUm93V2lkdGgpIC0gKCh0aGlzLkdVVFRFUiAqIDIpIC8gcGFyZW50V2lkdGggKiAxMDApO1xuICAgICAgICAgICAgICAgICAgICBub2RlLmNvbXB1dGVkV2lkdGggPSAnY2FsYygnK25vZGVXaWR0aCsnJSknO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmdyaWRTdGF0ZSA9PT0gJ25vdCBzdGFydGVkJyl7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdyaWRTdGF0ZSA9ICdwcmUtYnVpbGRpbmcnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkR3JpZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGVXaWR0aCA9ICgodGhpcy5nZXRDb21wdXRlZFdpZHRoKGluZGV4KSAvIHNjYWxpbmcpIC8gcGFyZW50V2lkdGggKiAxMDApIC0gKChyb3cubGVuZ3RoICogKHRoaXMuR1VUVEVSICogMikpICogKHRoaXMuZ2V0Q29tcHV0ZWRXaWR0aChpbmRleCkgLyBzY2FsaW5nKSAvIHBhcmVudFdpZHRoKSAvIHBhcmVudFdpZHRoICogMTAwO1xuICAgICAgICAgICAgICAgICAgICBub2RlLmNvbXB1dGVkV2lkdGggPSAnY2FsYygnK25vZGVXaWR0aCsnJSknO1xuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgdG90YWxSb3dXaWR0aCArPSBub2RlV2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIHRvdGFsUm93V2lkdGggKz0gKHRoaXMuR1VUVEVSIC8gcGFyZW50V2lkdGggKiAxMDApICogMjsgIFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIGxhc3Qgcm93IGFuZCBsYXN0IGltYWdlXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID09PSByb3cuZW5kSW5kZXggJiYgcm93Lmxlbmd0aCA9PT0gMSAmJiB0aGlzLmlzTW9iaWxlKXtcbiAgICAgICAgICAgICAgICBcdG5vZGVXaWR0aCA9IDEwMCAtICgodGhpcy5HVVRURVIgKiAyKSAvIHBhcmVudFdpZHRoICogMTAwKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhlaWdodCA9IG5vZGUuaGVpZ2h0ICogKCBwYXJlbnRXaWR0aCAqIChub2RlV2lkdGggLyAxMDApIC8gbm9kZS53aWR0aCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGhlaWdodC8yIDwgdGhpcy5NQVhfSEVJR0hUKXtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY29tcHV0ZWRXaWR0aCA9ICdjYWxjKCcrbm9kZVdpZHRoKyclKSc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBub2RlLm1hcmdpbiA9IHRoaXMuZ2V0Tm9kZU1hcmdpbihwYXJlbnRXaWR0aCk7XG4gICAgICAgICAgICAgICAgbm9kZS5jb21wdXRlZEhlaWdodCA9IG5vZGUuaGVpZ2h0ICogKCBwYXJlbnRXaWR0aCAqIChub2RlV2lkdGggLyAxMDApIC8gbm9kZS53aWR0aCkgKyAncHgnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBnZXRDb21wdXRlZFdpZHRoKGluZGV4OiBudW1iZXIpe1xuICAgICAgICByZXR1cm4gdGhpcy5pbWFnZXNbaW5kZXhdLndpZHRoIC8gKHRoaXMuaW1hZ2VzW2luZGV4XS5oZWlnaHQgLyB0aGlzLk1BWF9IRUlHSFQpO1xuICAgIH1cblxuICAgIGlzTGFzdENoaWxkKGluZGV4OiBudW1iZXIpe1xuICAgICAgICByZXR1cm4gaW5kZXggKyAxID09PSB0aGlzLmltYWdlcy5sZW5ndGg7XG4gICAgfVxuXG4gICAgZ2V0Tm9kZU1hcmdpbihwYXJlbnRXaWR0aDogbnVtYmVyKXtcbiAgICAgICAgcmV0dXJuICdjYWxjKCcrdGhpcy5HVVRURVIgLyBwYXJlbnRXaWR0aCAqIDEwMCsnJSknO1xuICAgIH1cblxuICAgIGNsaWNrT25JbWFnZShpbWFnZTogYW55LCBpOiBudW1iZXIpe1xuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHtcbiAgICAgICAgICAgIHR5cGU6ICdjbGljay1vbi1pbWFnZScsXG4gICAgICAgICAgICBpbWFnZTogaW1hZ2UsXG4gICAgICAgICAgICBpbmRleDogaVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbkltYWdlTG9hZGVkKGVsZW0pe1xuICAgICAgICBlbGVtLnN0eWxlLm9wYWNpdHkgPSAxO1xuICAgIH1cbn0iXX0=