UNPKG

ngx-crystal-gallery

Version:

Responsive gallery with support for masonry layout and lightbox.

315 lines (314 loc) 31.5 kB
/** * @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() { } var MasonryLayoutComponent = /** @class */ (function () { function MasonryLayoutComponent(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; } Object.defineProperty(MasonryLayoutComponent.prototype, "gutter", { set: /** * @param {?} value * @return {?} */ function (value) { this.GUTTER = value / 2; }, enumerable: true, configurable: true }); Object.defineProperty(MasonryLayoutComponent.prototype, "isMobile", { get: /** * @return {?} */ function () { /** @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; }, enumerable: true, configurable: true }); ; /** * @param {?} event * @return {?} */ MasonryLayoutComponent.prototype.onWindowResize = /** * @param {?} event * @return {?} */ function (event) { var _this = this; clearTimeout(this.resizeTimer); this.resizeTimer = setTimeout(function () { _this.gridState = 'not started'; _this.buildGrid(); }, 250); }; /** * @return {?} */ MasonryLayoutComponent.prototype.ngOnInit = /** * @return {?} */ function () { this.buildGrid(); }; /** * @return {?} */ MasonryLayoutComponent.prototype.ngOnChanges = /** * @return {?} */ function () { var _this = this; clearTimeout(this.changesTimer); this.changesTimer = setTimeout(function () { _this.gridState = 'not started'; _this.buildGrid(); }, 250); }; /** * @return {?} */ MasonryLayoutComponent.prototype.buildGrid = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var parentWidth = Math.floor(this.elem.parentNode.offsetWidth); /** @type {?} */ var totalRowWidth = 0; /** @type {?} */ var 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(function (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 {?} */ var scaling = row.totalWidth / parentWidth; _this.setColDimensions(scaling, row); row.totalWidth = 0; } }); }; /** * @param {?} scaling * @param {?} row * @return {?} */ MasonryLayoutComponent.prototype.setColDimensions = /** * @param {?} scaling * @param {?} row * @return {?} */ function (scaling, row) { var _this = this; /** @type {?} */ var totalRowWidth = 0; /** @type {?} */ var parentWidth = this.elem.parentNode.offsetWidth; scaling = (scaling < 1) ? 1 : scaling; this.images.forEach(function (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 {?} */ var nodeWidth = void 0; // 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(function () { _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 {?} */ var 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 {?} */ MasonryLayoutComponent.prototype.getComputedWidth = /** * @param {?} index * @return {?} */ function (index) { return this.images[index].width / (this.images[index].height / this.MAX_HEIGHT); }; /** * @param {?} index * @return {?} */ MasonryLayoutComponent.prototype.isLastChild = /** * @param {?} index * @return {?} */ function (index) { return index + 1 === this.images.length; }; /** * @param {?} parentWidth * @return {?} */ MasonryLayoutComponent.prototype.getNodeMargin = /** * @param {?} parentWidth * @return {?} */ function (parentWidth) { return 'calc(' + this.GUTTER / parentWidth * 100 + '%)'; }; /** * @param {?} image * @param {?} i * @return {?} */ MasonryLayoutComponent.prototype.clickOnImage = /** * @param {?} image * @param {?} i * @return {?} */ function (image, i) { this.events.emit({ type: 'click-on-image', image: image, index: i }); }; /** * @param {?} elem * @return {?} */ MasonryLayoutComponent.prototype.onImageLoaded = /** * @param {?} elem * @return {?} */ function (elem) { elem.style.opacity = 1; }; MasonryLayoutComponent.decorators = [ { type: Component, args: [{ selector: 'masonry-layout', template: "<div \n\t[ngClass]=\"CLASS_NAME\"\n\t*ngFor=\"let image of images; let i = index;\"\n [style.width]=\"image.computedWidth\"\n [style.height]=\"image.computedHeight\"\n [style.float]=\"'left'\"\n [style.margin]=\"image.margin\"\n [style.background]=\"'#eeeeee'\"\n [style.lineHeight]=\"0\">\n\t<img \n #imageElem\n [src]=\"image.preview || image.full\" \n [style.width.%]=\"100\" \n [style.height]=\"'auto'\"\n [style.opacity]=\"0\"\n (click)=\"clickOnImage(image, i)\"\n (load)=\"onImageLoaded(imageElem)\" />\n</div>", },] }, ]; /** @nocollapse */ MasonryLayoutComponent.ctorParameters = function () { return [ { 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'],] }] }; return MasonryLayoutComponent; }()); export { MasonryLayoutComponent }; 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFzb25yeS1sYXlvdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWNyeXN0YWwtZ2FsbGVyeS8iLCJzb3VyY2VzIjpbImxpYi9tYXNvbnJ5LWxheW91dC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFxQixZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBU25ILENBQUM7Ozs7OztJQXNERSxnQ0FBb0IsVUFBc0I7UUFBdEIsZUFBVSxHQUFWLFVBQVUsQ0FBWTtzQkEzQnpCLENBQUM7bUNBR1MsRUFBRTt5QkFFVCxhQUFhOzhCQUtXLElBQUk7MEJBQ04sR0FBRztzQkFRUCxJQUFJLFlBQVksRUFBTztRQVN6RCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO0tBQzdDO0lBZkQsc0JBQ0ksMENBQU07Ozs7O1FBRFYsVUFDVyxLQUFhO1lBQ3BCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQztTQUMzQjs7O09BQUE7SUFJRCxzQkFBSSw0Q0FBUTs7OztRQUFaOztZQUNJLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQztZQUNsQixDQUFDLFVBQVMsQ0FBQyxJQUFFLEVBQUUsQ0FBQSxDQUFDLDBUQUEwVCxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBRSx5a0RBQXlrRCxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsRUFBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFNBQVMsSUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDMStELE1BQU0sQ0FBQyxLQUFLLENBQUM7U0FDaEI7OztPQUFBO0lBQUEsQ0FBQzs7Ozs7SUFPRiwrQ0FBYzs7OztJQURkLFVBQ2UsS0FBSztRQURwQixpQkFRQztRQU5HLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFL0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxVQUFVLENBQUM7WUFDMUIsS0FBSSxDQUFDLFNBQVMsR0FBRyxhQUFhLENBQUM7WUFDL0IsS0FBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1NBQ3BCLEVBQUUsR0FBRyxDQUFDLENBQUM7S0FDWDs7OztJQUVELHlDQUFROzs7SUFBUjtRQUNJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztLQUNwQjs7OztJQUVELDRDQUFXOzs7SUFBWDtRQUFBLGlCQU9DO1FBTkcsWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVoQyxJQUFJLENBQUMsWUFBWSxHQUFHLFVBQVUsQ0FBQztZQUMzQixLQUFJLENBQUMsU0FBUyxHQUFHLGFBQWEsQ0FBQztZQUMvQixLQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7U0FDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQztLQUNYOzs7O0lBRUQsMENBQVM7OztJQUFUO1FBQUEsaUJBa0NDOztRQWpDRyxJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDOztRQUMvRCxJQUFJLGFBQWEsR0FBUSxDQUFDLENBQUM7O1FBQzNCLElBQUksR0FBRyxHQUFRO1lBQ1gsVUFBVSxFQUFFLENBQUM7WUFDYixRQUFRLEVBQUUsQ0FBQztZQUNYLE1BQU0sRUFBRSxDQUFDO1lBQ1QsVUFBVSxFQUFFLENBQUM7U0FDaEIsQ0FBQztRQUVGLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUEsQ0FBQztZQUNyQyxNQUFNLENBQUM7U0FDVjtRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxXQUFXLEdBQUUsSUFBSSxDQUFDO1FBQzFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFFbEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBQyxJQUFJLEVBQUUsS0FBSztZQUM1QixFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBVSxLQUFLLENBQUMsQ0FBQyxDQUFBLENBQUM7Z0JBQ3RCLEdBQUcsQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO2dCQUN2QixHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQzthQUNsQjtZQUVELEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNiLEdBQUcsQ0FBQyxVQUFVLElBQUksS0FBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRS9DLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksV0FBVyxJQUFJLEtBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQSxDQUFDO2dCQUMxRCxHQUFHLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQzs7Z0JBQ3JCLElBQUksT0FBTyxHQUFHLEdBQUcsQ0FBQyxVQUFVLEdBQUMsV0FBVyxDQUFDO2dCQUV6QyxLQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUNwQyxHQUFHLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQzthQUN0QjtTQUNKLENBQUMsQ0FBQztLQUNOOzs7Ozs7SUFFRCxpREFBZ0I7Ozs7O0lBQWhCLFVBQWlCLE9BQWUsRUFBRSxHQUFRO1FBQTFDLGlCQW1EQzs7UUFsREcsSUFBSSxhQUFhLEdBQVEsQ0FBQyxDQUFDOztRQUMzQixJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUM7UUFDbkQsT0FBTyxHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUV0QyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFDLElBQUksRUFBRSxLQUFLO1lBQzVCLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSSxDQUFDLGNBQWMsQ0FBQyxDQUFBLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7Z0JBQzdDLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQztnQkFDekQsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUM5QyxNQUFNLENBQUM7YUFDVjtZQUVELEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSSxHQUFHLENBQUMsVUFBVSxJQUFJLEtBQUssSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUEsQ0FBQzs7Z0JBQ2xELElBQUksU0FBUyxVQUFDOztnQkFHZCxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssR0FBRyxDQUFDLFFBQVEsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUEsQ0FBQztvQkFDdkMsU0FBUyxHQUFHLENBQUMsR0FBRyxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLFdBQVcsR0FBRyxHQUFHLENBQUMsQ0FBQztvQkFDNUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLEdBQUMsU0FBUyxHQUFDLElBQUksQ0FBQztvQkFFNUMsRUFBRSxDQUFDLENBQUMsS0FBSSxDQUFDLFNBQVMsS0FBSyxhQUFhLENBQUMsQ0FBQSxDQUFDO3dCQUNsQyxLQUFJLENBQUMsU0FBUyxHQUFHLGNBQWMsQ0FBQzt3QkFFaEMsVUFBVSxDQUFDOzRCQUNQLEtBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQzt5QkFDcEIsRUFBRSxHQUFHLENBQUMsQ0FBQztxQkFDWDtpQkFDSjtnQkFDRCxJQUFJLENBQUMsQ0FBQztvQkFDRixTQUFTLEdBQUcsQ0FBQyxDQUFDLEtBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsR0FBRyxPQUFPLENBQUMsR0FBRyxXQUFXLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxLQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEdBQUcsT0FBTyxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsV0FBVyxHQUFHLEdBQUcsQ0FBQztvQkFDN0wsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLEdBQUMsU0FBUyxHQUFDLElBQUksQ0FBQztvQkFFNUMsYUFBYSxJQUFJLFNBQVMsQ0FBQztvQkFDM0IsYUFBYSxJQUFJLENBQUMsS0FBSSxDQUFDLE1BQU0sR0FBRyxXQUFXLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2lCQUMxRDs7Z0JBR0QsRUFBRSxDQUFDLENBQUMsS0FBSyxLQUFLLEdBQUcsQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksS0FBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBLENBQUM7b0JBQ2hFLFNBQVMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEtBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsV0FBVyxHQUFHLEdBQUcsQ0FBQyxDQUFDOztvQkFDdkQsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFFLFdBQVcsR0FBRyxDQUFDLFNBQVMsR0FBRyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBRTNFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sR0FBQyxDQUFDLEdBQUcsS0FBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBLENBQUM7d0JBQzVCLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxHQUFDLFNBQVMsR0FBQyxJQUFJLENBQUM7cUJBQy9DO2lCQUNKO2dCQUVELElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDOUMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUUsV0FBVyxHQUFHLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUM7YUFDOUY7U0FDSixDQUFDLENBQUM7S0FDTjs7Ozs7SUFFRCxpREFBZ0I7Ozs7SUFBaEIsVUFBaUIsS0FBYTtRQUMxQixNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7S0FDbkY7Ozs7O0lBRUQsNENBQVc7Ozs7SUFBWCxVQUFZLEtBQWE7UUFDckIsTUFBTSxDQUFDLEtBQUssR0FBRyxDQUFDLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUM7S0FDM0M7Ozs7O0lBRUQsOENBQWE7Ozs7SUFBYixVQUFjLFdBQW1CO1FBQzdCLE1BQU0sQ0FBQyxPQUFPLEdBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxXQUFXLEdBQUcsR0FBRyxHQUFDLElBQUksQ0FBQztLQUN2RDs7Ozs7O0lBRUQsNkNBQVk7Ozs7O0lBQVosVUFBYSxLQUFVLEVBQUUsQ0FBUztRQUM5QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztZQUNiLElBQUksRUFBRSxnQkFBZ0I7WUFDdEIsS0FBSyxFQUFFLEtBQUs7WUFDWixLQUFLLEVBQUUsQ0FBQztTQUNYLENBQUMsQ0FBQztLQUNOOzs7OztJQUVELDhDQUFhOzs7O0lBQWIsVUFBYyxJQUFJO1FBQ2QsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO0tBQzFCOztnQkE1TEosU0FBUyxTQUFDO29CQUNQLFFBQVEsRUFBRSxnQkFBZ0I7b0JBQzFCLFFBQVEsRUFBRSwwa0JBaUJQO2lCQUNOOzs7O2dCQWpDbUIsVUFBVTs7O3lCQTZDekIsS0FBSyxTQUFDLFFBQVE7aUNBQ2QsS0FBSyxTQUFDLFNBQVM7NkJBQ2YsS0FBSyxTQUFDLFlBQVk7NkJBQ2xCLEtBQUssU0FBQyxZQUFZO3lCQUVsQixLQUFLLFNBQUMsUUFBUTt5QkFLZCxNQUFNO2lDQVlOLFlBQVksU0FBQyxlQUFlLEVBQUUsQ0FBQyxRQUFRLENBQUM7O2lDQW5FN0M7O1NBbUNhLHNCQUFzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT3V0cHV0LCBPbkluaXQsIE9uQ2hhbmdlcywgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1hZ2Uge1xuICAgIHBhdGg6IHN0cmluZzsgXG4gICAgd2lkdGg6IG51bWJlcjsgXG4gICAgaGVpZ2h0OiBudW1iZXI7XG4gICAgY29tcHV0ZWRIZWlnaHQ/OiBzdHJpbmc7XG4gICAgY29tcHV0ZWRXaWR0aD86IHN0cmluZztcbiAgICBtYXJnaW4/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEltYWdlcyBleHRlbmRzIEFycmF5PEltYWdlPnt9XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbWFzb25yeS1sYXlvdXQnLCBcbiAgICB0ZW1wbGF0ZTogYDxkaXYgXG5cdFtuZ0NsYXNzXT1cIkNMQVNTX05BTUVcIlxuXHQqbmdGb3I9XCJsZXQgaW1hZ2Ugb2YgaW1hZ2VzOyBsZXQgaSA9IGluZGV4O1wiXG4gICAgW3N0eWxlLndpZHRoXT1cImltYWdlLmNvbXB1dGVkV2lkdGhcIlxuICAgIFtzdHlsZS5oZWlnaHRdPVwiaW1hZ2UuY29tcHV0ZWRIZWlnaHRcIlxuICAgIFtzdHlsZS5mbG9hdF09XCInbGVmdCdcIlxuICAgIFtzdHlsZS5tYXJnaW5dPVwiaW1hZ2UubWFyZ2luXCJcbiAgICBbc3R5bGUuYmFja2dyb3VuZF09XCInI2VlZWVlZSdcIlxuICAgIFtzdHlsZS5saW5lSGVpZ2h0XT1cIjBcIj5cblx0PGltZyBcbiAgICAgICAgI2ltYWdlRWxlbVxuICAgICAgICBbc3JjXT1cImltYWdlLnByZXZpZXcgfHwgaW1hZ2UuZnVsbFwiIFxuICAgICAgICBbc3R5bGUud2lkdGguJV09XCIxMDBcIiBcbiAgICAgICAgW3N0eWxlLmhlaWdodF09XCInYXV0bydcIlxuICAgICAgICBbc3R5bGUub3BhY2l0eV09XCIwXCJcbiAgICAgICAgKGNsaWNrKT1cImNsaWNrT25JbWFnZShpbWFnZSwgaSlcIlxuICAgICAgICAobG9hZCk9XCJvbkltYWdlTG9hZGVkKGltYWdlRWxlbSlcIiAvPlxuPC9kaXY+YCxcbn0pXG5cbmV4cG9ydCBjbGFzcyBNYXNvbnJ5TGF5b3V0Q29tcG9uZW50IHtcbiAgICBHVVRURVI6IG51bWJlciA9IDA7XG4gICAgbm9kZXM6IGFueTtcbiAgICBlbGVtOiBhbnk7XG4gICAgc2F2ZWROb2RlRGltZW5zaW9uczogYW55ID0gW107XG4gICAgb2JzZXJ2ZXI6IGFueTtcbiAgICBncmlkU3RhdGU6IHN0cmluZyA9ICdub3Qgc3RhcnRlZCc7XG4gICAgcmVzaXplVGltZXI6IGFueTtcbiAgICBjaGFuZ2VzVGltZXI6IGFueTtcblxuICAgIEBJbnB1dCgnaW1hZ2VzJykgaW1hZ2VzOiBJbWFnZXM7IFxuICAgIEBJbnB1dCgnbWFzb25yeScpIEVOQUJMRV9NQVNPTlJZOiBib29sZWFuID0gdHJ1ZTsgXG4gICAgQElucHV0KCdtYXgtaGVpZ2h0JykgTUFYX0hFSUdIVDogbnVtYmVyID0gNDAwOyBcbiAgICBASW5wdXQoJ2NsYXNzLW5hbWUnKSBDTEFTU19OQU1FOiBzdHJpbmcgfCB7IFtrZXk6IHN0cmluZ106IGFueTsgfTtcblxuICAgIEBJbnB1dCgnZ3V0dGVyJylcbiAgICBzZXQgZ3V0dGVyKHZhbHVlOiBudW1iZXIpe1xuICAgICAgICB0aGlzLkdVVFRFUiA9IHZhbHVlIC8gMjtcbiAgICB9XG5cbiAgICBAT3V0cHV0KCkgZXZlbnRzOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICAgICBcbiAgICBnZXQgaXNNb2JpbGUoKTpib29sZWFuIHtcbiAgICAgICAgdmFyIGNoZWNrID0gZmFsc2U7XG4gICAgICAgIChmdW5jdGlvbihhKXtpZigvKGFuZHJvaWR8YmJcXGQrfG1lZWdvKS4rbW9iaWxlfGF2YW50Z298YmFkYVxcL3xibGFja2JlcnJ5fGJsYXplcnxjb21wYWx8ZWxhaW5lfGZlbm5lY3xoaXB0b3B8aWVtb2JpbGV8aXAoaG9uZXxvZCl8aXJpc3xraW5kbGV8bGdlIHxtYWVtb3xtaWRwfG1tcHxtb2JpbGUuK2ZpcmVmb3h8bmV0ZnJvbnR8b3BlcmEgbShvYnxpbilpfHBhbG0oIG9zKT98cGhvbmV8cChpeGl8cmUpXFwvfHBsdWNrZXJ8cG9ja2V0fHBzcHxzZXJpZXMoNHw2KTB8c3ltYmlhbnx0cmVvfHVwXFwuKGJyb3dzZXJ8bGluayl8dm9kYWZvbmV8d2FwfHdpbmRvd3MgY2V8eGRhfHhpaW5vL2kudGVzdChhKXx8LzEyMDd8NjMxMHw2NTkwfDNnc298NHRocHw1MFsxLTZdaXw3NzBzfDgwMnN8YSB3YXxhYmFjfGFjKGVyfG9vfHNcXC0pfGFpKGtvfHJuKXxhbChhdnxjYXxjbyl8YW1vaXxhbihleHxueXx5dyl8YXB0dXxhcihjaHxnbyl8YXModGV8dXMpfGF0dHd8YXUoZGl8XFwtbXxyIHxzICl8YXZhbnxiZShja3xsbHxucSl8YmkobGJ8cmQpfGJsKGFjfGF6KXxicihlfHYpd3xidW1ifGJ3XFwtKG58dSl8YzU1XFwvfGNhcGl8Y2N3YXxjZG1cXC18Y2VsbHxjaHRtfGNsZGN8Y21kXFwtfGNvKG1wfG5kKXxjcmF3fGRhKGl0fGxsfG5nKXxkYnRlfGRjXFwtc3xkZXZpfGRpY2F8ZG1vYnxkbyhjfHApb3xkcygxMnxcXC1kKXxlbCg0OXxhaSl8ZW0obDJ8dWwpfGVyKGljfGswKXxlc2w4fGV6KFs0LTddMHxvc3x3YXx6ZSl8ZmV0Y3xmbHkoXFwtfF8pfGcxIHV8ZzU2MHxnZW5lfGdmXFwtNXxnXFwtbW98Z28oXFwud3xvZCl8Z3IoYWR8dW4pfGhhaWV8aGNpdHxoZFxcLShtfHB8dCl8aGVpXFwtfGhpKHB0fHRhKXxocCggaXxpcCl8aHNcXC1jfGh0KGMoXFwtfCB8X3xhfGd8cHxzfHQpfHRwKXxodShhd3x0Yyl8aVxcLSgyMHxnb3xtYSl8aTIzMHxpYWMoIHxcXC18XFwvKXxpYnJvfGlkZWF8aWcwMXxpa29tfGltMWt8aW5ub3xpcGFxfGlyaXN8amEodHx2KWF8amJyb3xqZW11fGppZ3N8a2RkaXxrZWppfGtndCggfFxcLyl8a2xvbnxrcHQgfGt3Y1xcLXxreW8oY3xrKXxsZShub3x4aSl8bGcoIGd8XFwvKGt8bHx1KXw1MHw1NHxcXC1bYS13XSl8bGlid3xseW54fG0xXFwtd3xtM2dhfG01MFxcL3xtYSh0ZXx1aXx4byl8bWMoMDF8MjF8Y2EpfG1cXC1jcnxtZShyY3xyaSl8bWkobzh8b2F8dHMpfG1tZWZ8bW8oMDF8MDJ8Yml8ZGV8ZG98dChcXC18IHxvfHYpfHp6KXxtdCg1MHxwMXx2ICl8bXdicHxteXdhfG4xMFswLTJdfG4yMFsyLTNdfG4zMCgwfDIpfG41MCgwfDJ8NSl8bjcoMCgwfDEpfDEwKXxuZSgoY3xtKVxcLXxvbnx0Znx3Znx3Z3x3dCl8bm9rKDZ8aSl8bnpwaHxvMmltfG9wKHRpfHd2KXxvcmFufG93ZzF8cDgwMHxwYW4oYXxkfHQpfHBkeGd8cGcoMTN8XFwtKFsxLThdfGMpKXxwaGlsfHBpcmV8cGwoYXl8dWMpfHBuXFwtMnxwbyhja3xydHxzZSl8cHJveHxwc2lvfHB0XFwtZ3xxYVxcLWF8cWMoMDd8MTJ8MjF8MzJ8NjB8XFwtWzItN118aVxcLSl8cXRla3xyMzgwfHI2MDB8cmFrc3xyaW05fHJvKHZlfHpvKXxzNTVcXC98c2EoZ2V8bWF8bW18bXN8bnl8dmEpfHNjKDAxfGhcXC18b298cFxcLSl8c2RrXFwvfHNlKGMoXFwtfDB8MSl8NDd8bWN8bmR8cmkpfHNnaFxcLXxzaGFyfHNpZShcXC18bSl8c2tcXC0wfHNsKDQ1fGlkKXxzbShhbHxhcnxiM3xpdHx0NSl8c28oZnR8bnkpfHNwKDAxfGhcXC18dlxcLXx2ICl8c3koMDF8bWIpfHQyKDE4fDUwKXx0NigwMHwxMHwxOCl8dGEoZ3R8bGspfHRjbFxcLXx0ZGdcXC18dGVsKGl8bSl8dGltXFwtfHRcXC1tb3x0byhwbHxzaCl8dHMoNzB8bVxcLXxtM3xtNSl8dHhcXC05fHVwKFxcLmJ8ZzF8c2kpfHV0c3R8djQwMHx2NzUwfHZlcml8dmkocmd8dGUpfHZrKDQwfDVbMC0zXXxcXC12KXx2bTQwfHZvZGF8dnVsY3x2eCg1Mnw1M3w2MHw2MXw3MHw4MHw4MXw4M3w4NXw5OCl8dzNjKFxcLXwgKXx3ZWJjfHdoaXR8d2koZyB8bmN8bncpfHdtbGJ8d29udXx4NzAwfHlhc1xcLXx5b3VyfHpldG98enRlXFwtL2kudGVzdChhLnN1YnN0cigwLDQpKSkgY2hlY2sgPSB0cnVlO30pKG5hdmlnYXRvci51c2VyQWdlbnR8fG5hdmlnYXRvci52ZW5kb3IpO1xuICAgICAgICByZXR1cm4gY2hlY2s7XG4gICAgfTtcbiAgICAgXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmKXtcbiAgICAgICAgdGhpcy5lbGVtID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXG4gICAgb25XaW5kb3dSZXNpemUoZXZlbnQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucmVzaXplVGltZXIpO1xuXG4gICAgICAgIHRoaXMucmVzaXplVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ3JpZFN0YXRlID0gJ25vdCBzdGFydGVkJztcbiAgICAgICAgICAgIHRoaXMuYnVpbGRHcmlkKCk7IFxuICAgICAgICB9LCAyNTApO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmJ1aWxkR3JpZCgpO1xuICAgIH1cblxuICAgIG5nT25DaGFuZ2VzKCl7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmNoYW5nZXNUaW1lcik7XG5cbiAgICAgICAgdGhpcy5jaGFuZ2VzVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ3JpZFN0YXRlID0gJ25vdCBzdGFydGVkJztcbiAgICAgICAgICAgIHRoaXMuYnVpbGRHcmlkKCk7IFxuICAgICAgICB9LCAyNTApO1xuICAgIH1cblxuICAgIGJ1aWxkR3JpZCgpe1xuICAgICAgICBsZXQgcGFyZW50V2lkdGggPSBNYXRoLmZsb29yKHRoaXMuZWxlbS5wYXJlbnROb2RlLm9mZnNldFdpZHRoKTtcbiAgICAgICAgbGV0IHRvdGFsUm93V2lkdGg6IGFueSA9IDA7IFxuICAgICAgICBsZXQgcm93OiBhbnkgPSB7XG4gICAgICAgICAgICBzdGFydEluZGV4OiAwLFxuICAgICAgICAgICAgZW5kSW5kZXg6IDAsXG4gICAgICAgICAgICBsZW5ndGg6IDAsXG4gICAgICAgICAgICB0b3RhbFdpZHRoOiAwXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKCF0aGlzLmltYWdlcyB8fCAhdGhpcy5pbWFnZXMubGVuZ3RoKXtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWxlbS5zdHlsZS53aWR0aCA9IHBhcmVudFdpZHRoICsncHgnO1xuICAgICAgICB0aGlzLmVsZW0uc3R5bGUuZGlzcGxheSA9ICd0YWJsZSc7XG5cbiAgICAgICAgdGhpcy5pbWFnZXMuZm9yRWFjaCgobm9kZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGlmIChyb3cudG90YWxXaWR0aCA9PT0gMCl7XG4gICAgICAgICAgICAgICAgcm93LnN0YXJ0SW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgICAgICByb3cubGVuZ3RoID0gMDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcm93Lmxlbmd0aCsrO1xuICAgICAgICAgICAgcm93LnRvdGFsV2lkdGggKz0gdGhpcy5nZXRDb21wdXRlZFdpZHRoKGluZGV4KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKHJvdy50b3RhbFdpZHRoID49IHBhcmVudFdpZHRoIHx8IHRoaXMuaXNMYXN0Q2hpbGQoaW5kZXgpKXtcbiAgICAgICAgICAgICAgICByb3cuZW5kSW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgICAgICBsZXQgc2NhbGluZyA9IHJvdy50b3RhbFdpZHRoL3BhcmVudFdpZHRoO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRDb2xEaW1lbnNpb25zKHNjYWxpbmcsIHJvdyk7XG4gICAgICAgICAgICAgICAgcm93LnRvdGFsV2lkdGggPSAwOyBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2V0Q29sRGltZW5zaW9ucyhzY2FsaW5nOiBudW1iZXIsIHJvdzogYW55KXtcbiAgICAgICAgbGV0IHRvdGFsUm93V2lkdGg6IGFueSA9IDA7XG4gICAgICAgIGxldCBwYXJlbnRXaWR0aCA9IHRoaXMuZWxlbS5wYXJlbnROb2RlLm9mZnNldFdpZHRoO1xuICAgICAgICBzY2FsaW5nID0gKHNjYWxpbmcgPCAxKSA/IDEgOiBzY2FsaW5nO1xuXG4gICAgICAgIHRoaXMuaW1hZ2VzLmZvckVhY2goKG5vZGUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuRU5BQkxFX01BU09OUlkpe1xuICAgICAgICAgICAgICAgIG5vZGUuY29tcHV0ZWRIZWlnaHQgPSB0aGlzLk1BWF9IRUlHSFQgKyAncHgnO1xuICAgICAgICAgICAgICAgIG5vZGUuY29tcHV0ZWRXaWR0aCA9IHRoaXMuZ2V0Q29tcHV0ZWRXaWR0aChpbmRleCkgKyAncHgnO1xuICAgICAgICAgICAgICAgIG5vZGUubWFyZ2luID0gdGhpcy5nZXROb2RlTWFyZ2luKHBhcmVudFdpZHRoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpbmRleCA+PSByb3cuc3RhcnRJbmRleCAmJiBpbmRleCA8PSByb3cuZW5kSW5kZXgpe1xuICAgICAgICAgICAgICAgIGxldCBub2RlV2lkdGg7XG5cbiAgICAgICAgICAgICAgICAvLyBsYXN0IGltYWdlXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID09PSByb3cuZW5kSW5kZXggJiYgc2NhbGluZyA+IDEpeyBcbiAgICAgICAgICAgICAgICAgICAgbm9kZVdpZHRoID0gKDEwMCAtIHRvdGFsUm93V2lkdGgpIC0gKCh0aGlzLkdVVFRFUiAqIDIpIC8gcGFyZW50V2lkdGggKiAxMDApO1xuICAgICAgICAgICAgICAgICAgICBub2RlLmNvbXB1dGVkV2lkdGggPSAnY2FsYygnK25vZGVXaWR0aCsnJSknO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmdyaWRTdGF0ZSA9PT0gJ25vdCBzdGFydGVkJyl7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdyaWRTdGF0ZSA9ICdwcmUtYnVpbGRpbmcnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkR3JpZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGVXaWR0aCA9ICgodGhpcy5nZXRDb21wdXRlZFdpZHRoKGluZGV4KSAvIHNjYWxpbmcpIC8gcGFyZW50V2lkdGggKiAxMDApIC0gKChyb3cubGVuZ3RoICogKHRoaXMuR1VUVEVSICogMikpICogKHRoaXMuZ2V0Q29tcHV0ZWRXaWR0aChpbmRleCkgLyBzY2FsaW5nKSAvIHBhcmVudFdpZHRoKSAvIHBhcmVudFdpZHRoICogMTAwO1xuICAgICAgICAgICAgICAgICAgICBub2RlLmNvbXB1dGVkV2lkdGggPSAnY2FsYygnK25vZGVXaWR0aCsnJSknO1xuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgdG90YWxSb3dXaWR0aCArPSBub2RlV2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIHRvdGFsUm93V2lkdGggKz0gKHRoaXMuR1VUVEVSIC8gcGFyZW50V2lkdGggKiAxMDApICogMjsgIFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIGxhc3Qgcm93IGFuZCBsYXN0IGltYWdlXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID09PSByb3cuZW5kSW5kZXggJiYgcm93Lmxlbmd0aCA9PT0gMSAmJiB0aGlzLmlzTW9iaWxlKXtcbiAgICAgICAgICAgICAgICBcdG5vZGVXaWR0aCA9IDEwMCAtICgodGhpcy5HVVRURVIgKiAyKSAvIHBhcmVudFdpZHRoICogMTAwKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhlaWdodCA9IG5vZGUuaGVpZ2h0ICogKCBwYXJlbnRXaWR0aCAqIChub2RlV2lkdGggLyAxMDApIC8gbm9kZS53aWR0aCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGhlaWdodC8yIDwgdGhpcy5NQVhfSEVJR0hUKXtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY29tcHV0ZWRXaWR0aCA9ICdjYWxjKCcrbm9kZVdpZHRoKyclKSc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBub2RlLm1hcmdpbiA9IHRoaXMuZ2V0Tm9kZU1hcmdpbihwYXJlbnRXaWR0aCk7XG4gICAgICAgICAgICAgICAgbm9kZS5jb21wdXRlZEhlaWdodCA9IG5vZGUuaGVpZ2h0ICogKCBwYXJlbnRXaWR0aCAqIChub2RlV2lkdGggLyAxMDApIC8gbm9kZS53aWR0aCkgKyAncHgnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBnZXRDb21wdXRlZFdpZHRoKGluZGV4OiBudW1iZXIpe1xuICAgICAgICByZXR1cm4gdGhpcy5pbWFnZXNbaW5kZXhdLndpZHRoIC8gKHRoaXMuaW1hZ2VzW2luZGV4XS5oZWlnaHQgLyB0aGlzLk1BWF9IRUlHSFQpO1xuICAgIH1cblxuICAgIGlzTGFzdENoaWxkKGluZGV4OiBudW1iZXIpe1xuICAgICAgICByZXR1cm4gaW5kZXggKyAxID09PSB0aGlzLmltYWdlcy5sZW5ndGg7XG4gICAgfVxuXG4gICAgZ2V0Tm9kZU1hcmdpbihwYXJlbnRXaWR0aDogbnVtYmVyKXtcbiAgICAgICAgcmV0dXJuICdjYWxjKCcrdGhpcy5HVVRURVIgLyBwYXJlbnRXaWR0aCAqIDEwMCsnJSknO1xuICAgIH1cblxuICAgIGNsaWNrT25JbWFnZShpbWFnZTogYW55LCBpOiBudW1iZXIpe1xuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHtcbiAgICAgICAgICAgIHR5cGU6ICdjbGljay1vbi1pbWFnZScsXG4gICAgICAgICAgICBpbWFnZTogaW1hZ2UsXG4gICAgICAgICAgICBpbmRleDogaVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbkltYWdlTG9hZGVkKGVsZW0pe1xuICAgICAgICBlbGVtLnN0eWxlLm9wYWNpdHkgPSAxO1xuICAgIH1cbn0iXX0=