UNPKG

ng-zorro-antd-mobile

Version:

An enterprise-class mobile UI components based on Ant Design and Angular

203 lines 32.3 kB
import { Component, Input, Output, EventEmitter, TemplateRef, HostBinding } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "ng-zorro-antd-mobile/flex"; import * as i2 from "ng-zorro-antd-mobile/icon"; import * as i3 from "@angular/common"; import * as i4 from "ng-zorro-antd-mobile/carousel"; import * as i5 from "ng-zorro-antd-mobile/core"; import * as i6 from "ng-zorro-antd-mobile/pipes"; export class GridComponent { get columnNum() { return this.defaultProps.columnNum; } set columnNum(value) { if (typeof value === 'number') { this.defaultProps.columnNum = value; this.init(); } } get carouselMaxRow() { return this.defaultProps.carouselMaxRow; } set carouselMaxRow(value) { if (typeof value === 'number') { this.defaultProps.carouselMaxRow = value; this.init(); } } get isCarousel() { return this.defaultProps.isCarousel; } set isCarousel(value) { this.defaultProps.isCarousel = value; this.init(); } set data(value) { this._data = value; this.init(); } get amGridSquare() { return true === this.square; } get amGridLine() { return true === this.hasLine; } get amGridCarousel() { return true === this.isCarousel; } constructor() { this.wrapCls = {}; this.itemCls = {}; this.carouselProps = { dots: false, dragging: false }; this.defaultProps = { data: [], hasLine: true, isCarousel: false, columnNum: 4, carouselMaxRow: 2, prefixCls: 'am-grid', square: true, itemStyle: {} }; this.carouselData = []; this.carouselDataTmp = []; this.gridData = []; this._data = []; this.itemStyle = {}; this.square = true; this.hasLine = true; this.activeStyle = true; this.onClick = new EventEmitter(); this.amGrid = true; } getContentType(value) { if ((value.indexOf('http') >= 0 || value.indexOf('assets') >= 0) && value.indexOf('<') < 0) { return 'url'; } else if (value.indexOf('<') >= 0) { return 'innerHTML'; } else if (value instanceof TemplateRef) { return 'TemplateRef'; } else { return 'icon'; } } init() { const dataLength = (this._data && this._data.length) || 0; let rowCount = Math.ceil(dataLength / this.columnNum); let rowsArr; if (this.defaultProps.isCarousel) { if (rowCount % this.carouselMaxRow !== 0) { rowCount = rowCount + this.carouselMaxRow - (rowCount % this.carouselMaxRow); } const pageCount = Math.ceil(rowCount / this.carouselMaxRow); rowsArr = this.getRows(rowCount, dataLength); if (pageCount <= 1) { this.carouselProps = { dots: false, dragging: false }; } else { this.carouselProps = { dots: true, dragging: true }; } this.carouselDataTmp = this.getCarouselData(rowsArr, pageCount, rowCount); } else { this.gridData = this.getRows(rowCount, dataLength); } } getCarouselData(rowsArr, pageCount, rowCount) { const pagesArr = []; for (let pageIndex = 0; pageIndex < pageCount; pageIndex++) { const pageRows = []; for (let ii = 0; ii < this.carouselMaxRow; ii++) { const rowIndex = pageIndex * this.carouselMaxRow + ii; if (rowIndex < rowCount) { pageRows.push(rowsArr[rowIndex]); } else { // 空节点为了确保末尾页的最后未到底的行有底线(样式中last-child会没线) pageRows.push(null); } } pagesArr.push(pageRows); } return pagesArr; } getRows(rowCount, dataLength) { const columnNum = this.columnNum; const rowArr = new Array(); for (let i = 0; i < rowCount; i++) { rowArr[i] = new Array(); for (let j = 0; j < columnNum; j++) { const dataIndex = i * columnNum + j; if (dataIndex < dataLength) { rowArr[i][j] = this._data[dataIndex]; } else { rowArr[i][j] = null; } } } return rowArr; } click(data, index) { const outputData = { data: data, index: index }; this.onClick.emit(outputData); } ngOnInit() { this.itemCls = { [`${this.defaultProps.prefixCls}-item`]: true, [`${this.defaultProps.prefixCls}-active-item`]: false }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: GridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: GridComponent, selector: "Grid, nzm-grid", inputs: { columnNum: "columnNum", carouselMaxRow: "carouselMaxRow", itemStyle: "itemStyle", square: "square", hasLine: "hasLine", isCarousel: "isCarousel", activeStyle: "activeStyle", data: "data" }, outputs: { onClick: "onClick" }, host: { properties: { "class.am-grid": "this.amGrid", "class.am-grid-square": "this.amGridSquare", "class.am-grid-line": "this.amGridLine", "class.am-grid-carousel": "this.amGridCarousel" } }, ngImport: i0, template: "<ng-container *ngIf=\"!isCarousel\">\n <Flex *ngFor=\"let item of gridData; let i = index\" [justify]=\"'center'\" [align]=\"'stretch'\">\n <FlexItem\n TouchFeedbackDirective\n *ngFor=\"let subItem of item; let j = index\"\n [ngClass]=\"itemCls\"\n [ngStyle]=\"itemStyle\"\n [className]=\"['am-grid-item-active']\"\n [activeStyle]=\"activeStyle\"\n >\n <div\n *ngIf=\"subItem !== null\"\n class=\"{{ defaultProps.prefixCls }}-item-content\"\n (click)=\"click(subItem, i * columnNum + j)\"\n >\n <div class=\"{{ defaultProps.prefixCls }}-item-inner-content column-num-{{ columnNum }}\">\n <img\n *ngIf=\"subItem.icon && getContentType(subItem.icon) === 'url'\"\n src=\"{{ subItem.icon }}\"\n class=\"{{ defaultProps.prefixCls }}-icon\"\n />\n <Icon\n *ngIf=\"subItem.icon && getContentType(subItem.icon) === 'icon'\"\n [type]=\"subItem.icon\"\n [size]=\"subItem.size\"\n ></Icon>\n <div\n *ngIf=\"subItem.icon && getContentType(subItem.icon) === 'innerHTML'\"\n [innerHTML]=\"subItem.icon | safeHTML\"\n ></div>\n <ng-template\n *ngIf=\"subItem.icon && getContentType(subItem.icon) === 'TemplateRef'\"\n [ngTemplateOutlet]=\"subItem.icon\"\n ></ng-template>\n <div class=\"{{ defaultProps.prefixCls }}-text\">{{ subItem.text }}</div>\n </div>\n </div>\n <div *ngIf=\"subItem === null\" class=\"{{ defaultProps.prefixCls }}-null-item\"></div>\n </FlexItem>\n </Flex>\n <ng-content></ng-content>\n</ng-container>\n\n<Carousel\n *ngIf=\"isCarousel && carouselDataTmp.length > 0\"\n [autoplay]=\"false\"\n [infinite]=\"true\"\n [selectedIndex]=\"0\"\n [autoplayInterval]=\"3000\"\n [dots]=\"carouselProps.dots\"\n [dragging]=\"carouselProps.dragging\"\n>\n <CarouselSlide\n *ngFor=\"let gridData of carouselDataTmp\"\n class=\"{{ defaultProps.prefixCls }}-carousel-page\"\n style=\"display: block;\"\n >\n <Flex *ngFor=\"let item of gridData; let i = index\" [justify]=\"'center'\" [align]=\"'stretch'\">\n <FlexItem\n TouchFeedbackDirective\n *ngFor=\"let subItem of item; let j = index\"\n class=\"{{ defaultProps.prefixCls }}-item\"\n [ngStyle]=\"itemStyle\"\n [className]=\"['am-grid-item-active']\"\n >\n <div\n *ngIf=\"subItem !== null\"\n class=\"{{ defaultProps.prefixCls }}-item-content\"\n (click)=\"click(subItem, i * columnNum + j)\"\n >\n <div class=\"{{ defaultProps.prefixCls }}-item-inner-content column-num-4\">\n <img class=\"{{ defaultProps.prefixCls }}-icon\" src=\"{{ subItem.icon }}\" />\n <div class=\"{{ defaultProps.prefixCls }}-text\">{{ subItem.text }}</div>\n </div>\n </div>\n <div *ngIf=\"subItem === null\" class=\"{{ defaultProps.prefixCls }}-null-item\"></div>\n </FlexItem>\n </Flex>\n </CarouselSlide>\n</Carousel>\n", dependencies: [{ kind: "component", type: i1.FlexComponent, selector: "Flex, nzm-flex", inputs: ["direction", "wrap", "justify", "align", "alignContent"] }, { kind: "component", type: i1.FlexItemComponent, selector: "FlexItem, nzm-flex-item" }, { kind: "component", type: i2.IconComponent, selector: "Icon, nzm-icon", inputs: ["color", "type", "src", "size"] }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.CarouselComponent, selector: "Carousel, nzm-carousel", inputs: ["speed", "dots", "vertical", "autoplay", "autoplayInterval", "infinite", "dotStyle", "dotActiveStyle", "frameOverflow", "cellSpacing", "slideWidth", "swipeSpeed", "dragging", "selectedIndex"], outputs: ["afterChange", "beforeChange"] }, { kind: "component", type: i4.CarouselSlideComponent, selector: "CarouselSlide, nzm-carousel-slide" }, { kind: "directive", type: i5.TouchFeedbackDirective, selector: "[TouchFeedbackDirective]", inputs: ["className", "activeStyle"], outputs: ["clickStart", "clickEnd"] }, { kind: "pipe", type: i6.SafeHTMLPipe, name: "safeHTML" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: GridComponent, decorators: [{ type: Component, args: [{ selector: 'Grid, nzm-grid', template: "<ng-container *ngIf=\"!isCarousel\">\n <Flex *ngFor=\"let item of gridData; let i = index\" [justify]=\"'center'\" [align]=\"'stretch'\">\n <FlexItem\n TouchFeedbackDirective\n *ngFor=\"let subItem of item; let j = index\"\n [ngClass]=\"itemCls\"\n [ngStyle]=\"itemStyle\"\n [className]=\"['am-grid-item-active']\"\n [activeStyle]=\"activeStyle\"\n >\n <div\n *ngIf=\"subItem !== null\"\n class=\"{{ defaultProps.prefixCls }}-item-content\"\n (click)=\"click(subItem, i * columnNum + j)\"\n >\n <div class=\"{{ defaultProps.prefixCls }}-item-inner-content column-num-{{ columnNum }}\">\n <img\n *ngIf=\"subItem.icon && getContentType(subItem.icon) === 'url'\"\n src=\"{{ subItem.icon }}\"\n class=\"{{ defaultProps.prefixCls }}-icon\"\n />\n <Icon\n *ngIf=\"subItem.icon && getContentType(subItem.icon) === 'icon'\"\n [type]=\"subItem.icon\"\n [size]=\"subItem.size\"\n ></Icon>\n <div\n *ngIf=\"subItem.icon && getContentType(subItem.icon) === 'innerHTML'\"\n [innerHTML]=\"subItem.icon | safeHTML\"\n ></div>\n <ng-template\n *ngIf=\"subItem.icon && getContentType(subItem.icon) === 'TemplateRef'\"\n [ngTemplateOutlet]=\"subItem.icon\"\n ></ng-template>\n <div class=\"{{ defaultProps.prefixCls }}-text\">{{ subItem.text }}</div>\n </div>\n </div>\n <div *ngIf=\"subItem === null\" class=\"{{ defaultProps.prefixCls }}-null-item\"></div>\n </FlexItem>\n </Flex>\n <ng-content></ng-content>\n</ng-container>\n\n<Carousel\n *ngIf=\"isCarousel && carouselDataTmp.length > 0\"\n [autoplay]=\"false\"\n [infinite]=\"true\"\n [selectedIndex]=\"0\"\n [autoplayInterval]=\"3000\"\n [dots]=\"carouselProps.dots\"\n [dragging]=\"carouselProps.dragging\"\n>\n <CarouselSlide\n *ngFor=\"let gridData of carouselDataTmp\"\n class=\"{{ defaultProps.prefixCls }}-carousel-page\"\n style=\"display: block;\"\n >\n <Flex *ngFor=\"let item of gridData; let i = index\" [justify]=\"'center'\" [align]=\"'stretch'\">\n <FlexItem\n TouchFeedbackDirective\n *ngFor=\"let subItem of item; let j = index\"\n class=\"{{ defaultProps.prefixCls }}-item\"\n [ngStyle]=\"itemStyle\"\n [className]=\"['am-grid-item-active']\"\n >\n <div\n *ngIf=\"subItem !== null\"\n class=\"{{ defaultProps.prefixCls }}-item-content\"\n (click)=\"click(subItem, i * columnNum + j)\"\n >\n <div class=\"{{ defaultProps.prefixCls }}-item-inner-content column-num-4\">\n <img class=\"{{ defaultProps.prefixCls }}-icon\" src=\"{{ subItem.icon }}\" />\n <div class=\"{{ defaultProps.prefixCls }}-text\">{{ subItem.text }}</div>\n </div>\n </div>\n <div *ngIf=\"subItem === null\" class=\"{{ defaultProps.prefixCls }}-null-item\"></div>\n </FlexItem>\n </Flex>\n </CarouselSlide>\n</Carousel>\n" }] }], ctorParameters: () => [], propDecorators: { columnNum: [{ type: Input }], carouselMaxRow: [{ type: Input }], itemStyle: [{ type: Input }], square: [{ type: Input }], hasLine: [{ type: Input }], isCarousel: [{ type: Input }], activeStyle: [{ type: Input }], data: [{ type: Input }], onClick: [{ type: Output }], amGrid: [{ type: HostBinding, args: ['class.am-grid'] }], amGridSquare: [{ type: HostBinding, args: ['class.am-grid-square'] }], amGridLine: [{ type: HostBinding, args: ['class.am-grid-line'] }], amGridCarousel: [{ type: HostBinding, args: ['class.am-grid-carousel'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL2dyaWQvZ3JpZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi9jb21wb25lbnRzL2dyaWQvZ3JpZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7Ozs7Ozs7O0FBTXpHLE1BQU0sT0FBTyxhQUFhO0lBdUJ4QixJQUNJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDO0lBQ3JDLENBQUM7SUFDRCxJQUFJLFNBQVMsQ0FBQyxLQUFhO1FBQ3pCLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFO1lBQzdCLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztZQUNwQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDYjtJQUNILENBQUM7SUFDRCxJQUNJLGNBQWM7UUFDaEIsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQztJQUMxQyxDQUFDO0lBQ0QsSUFBSSxjQUFjLENBQUMsS0FBYTtRQUM5QixJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRTtZQUM3QixJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7WUFDekMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1NBQ2I7SUFDSCxDQUFDO0lBT0QsSUFDSSxVQUFVO1FBQ1osT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQztJQUN0QyxDQUFDO0lBQ0QsSUFBSSxVQUFVLENBQUMsS0FBYztRQUMzQixJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFDckMsSUFBSSxDQUFDLElBQUks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QUMsRUFBRSxJQUFJO1lBQzdDLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsY0FBYyxDQUFDLEVBQUUsS0FBSztTQUN0RCxDQUFDO0lBQ0osQ0FBQzs4R0EzS1UsYUFBYTtrR0FBYixhQUFhLGdlQ04xQixraUdBZ0ZBOzsyRkQxRWEsYUFBYTtrQkFKekIsU0FBUzsrQkFDRSxnQkFBZ0I7d0RBMkJ0QixTQUFTO3NCQURaLEtBQUs7Z0JBV0YsY0FBYztzQkFEakIsS0FBSztnQkFXTixTQUFTO3NCQURSLEtBQUs7Z0JBR04sTUFBTTtzQkFETCxLQUFLO2dCQUdOLE9BQU87c0JBRE4sS0FBSztnQkFHRixVQUFVO3NCQURiLEtBQUs7Z0JBU04sV0FBVztzQkFEVixLQUFLO2dCQUdGLElBQUk7c0JBRFAsS0FBSztnQkFNTixPQUFPO3NCQUROLE1BQU07Z0JBSVAsTUFBTTtzQkFETCxXQUFXO3VCQUFDLGVBQWU7Z0JBR3hCLFlBQVk7c0JBRGYsV0FBVzt1QkFBQyxzQkFBc0I7Z0JBSy9CLFVBQVU7c0JBRGIsV0FBVzt1QkFBQyxvQkFBb0I7Z0JBSzdCLGNBQWM7c0JBRGpCLFdBQVc7dUJBQUMsd0JBQXdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgVGVtcGxhdGVSZWYsIEhvc3RCaW5kaW5nIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ0dyaWQsIG56bS1ncmlkJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2dyaWQuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIEdyaWRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICB3cmFwQ2xzID0ge307XG4gIGl0ZW1DbHMgPSB7fTtcbiAgY2Fyb3VzZWxQcm9wcyA9IHtcbiAgICBkb3RzOiBmYWxzZSxcbiAgICBkcmFnZ2luZzogZmFsc2VcbiAgfTtcbiAgZGVmYXVsdFByb3BzID0ge1xuICAgIGRhdGE6IFtdLFxuICAgIGhhc0xpbmU6IHRydWUsXG4gICAgaXNDYXJvdXNlbDogZmFsc2UsXG4gICAgY29sdW1uTnVtOiA0LFxuICAgIGNhcm91c2VsTWF4Um93OiAyLFxuICAgIHByZWZpeENsczogJ2FtLWdyaWQnLFxuICAgIHNxdWFyZTogdHJ1ZSxcbiAgICBpdGVtU3R5bGU6IHt9XG4gIH07XG4gIGNhcm91c2VsRGF0YSA9IFtdO1xuICBjYXJvdXNlbERhdGFUbXAgPSBbXTtcbiAgZ3JpZERhdGEgPSBbXTtcblxuICBwcml2YXRlIF9kYXRhID0gW107XG5cbiAgQElucHV0KClcbiAgZ2V0IGNvbHVtbk51bSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmRlZmF1bHRQcm9wcy5jb2x1bW5OdW07XG4gIH1cbiAgc2V0IGNvbHVtbk51bSh2YWx1ZTogbnVtYmVyKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIHRoaXMuZGVmYXVsdFByb3BzLmNvbHVtbk51bSA9IHZhbHVlO1xuICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgpXG4gIGdldCBjYXJvdXNlbE1heFJvdygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmRlZmF1bHRQcm9wcy5jYXJvdXNlbE1heFJvdztcbiAgfVxuICBzZXQgY2Fyb3VzZWxNYXhSb3codmFsdWU6IG51bWJlcikge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICB0aGlzLmRlZmF1bHRQcm9wcy5jYXJvdXNlbE1heFJvdyA9IHZhbHVlO1xuICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgpXG4gIGl0ZW1TdHlsZTogb2JqZWN0ID0ge307XG4gIEBJbnB1dCgpXG4gIHNxdWFyZTogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpXG4gIGhhc0xpbmU6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKVxuICBnZXQgaXNDYXJvdXNlbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kZWZhdWx0UHJvcHMuaXNDYXJvdXNlbDtcbiAgfVxuICBzZXQgaXNDYXJvdXNlbCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuZGVmYXVsdFByb3BzLmlzQ2Fyb3VzZWwgPSB2YWx1ZTtcbiAgICB0aGlzLmluaXQoKTtcbiAgfVxuICBASW5wdXQoKVxuICBhY3RpdmVTdHlsZTogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpXG4gIHNldCBkYXRhKHZhbHVlOiBBcnJheTxhbnk+KSB7XG4gICAgdGhpcy5fZGF0YSA9IHZhbHVlO1xuICAgIHRoaXMuaW5pdCgpO1xuICB9XG4gIEBPdXRwdXQoKVxuICBvbkNsaWNrOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmFtLWdyaWQnKVxuICBhbUdyaWQ6IGJvb2xlYW4gPSB0cnVlO1xuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmFtLWdyaWQtc3F1YXJlJylcbiAgZ2V0IGFtR3JpZFNxdWFyZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZSA9PT0gdGhpcy5zcXVhcmU7XG4gIH1cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5hbS1ncmlkLWxpbmUnKVxuICBnZXQgYW1HcmlkTGluZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZSA9PT0gdGhpcy5oYXNMaW5lO1xuICB9XG4gIEBIb3N0QmluZGluZygnY2xhc3MuYW0tZ3JpZC1jYXJvdXNlbCcpXG4gIGdldCBhbUdyaWRDYXJvdXNlbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZSA9PT0gdGhpcy5pc0Nhcm91c2VsO1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIGdldENvbnRlbnRUeXBlKHZhbHVlOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICgodmFsdWUuaW5kZXhPZignaHR0cCcpID49IDAgfHwgdmFsdWUuaW5kZXhPZignYXNzZXRzJykgPj0gMCkgJiYgdmFsdWUuaW5kZXhPZignPCcpIDwgMCkge1xuICAgICAgcmV0dXJuICd1cmwnO1xuICAgIH0gZWxzZSBpZiAodmFsdWUuaW5kZXhPZignPCcpID49IDApIHtcbiAgICAgIHJldHVybiAnaW5uZXJIVE1MJztcbiAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgVGVtcGxhdGVSZWYpIHtcbiAgICAgIHJldHVybiAnVGVtcGxhdGVSZWYnO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gJ2ljb24nO1xuICAgIH1cbiAgfVxuXG4gIGluaXQoKSB7XG4gICAgY29uc3QgZGF0YUxlbmd0aCA9ICh0aGlzLl9kYXRhICYmIHRoaXMuX2RhdGEubGVuZ3RoKSB8fCAwO1xuICAgIGxldCByb3dDb3VudCA9IE1hdGguY2VpbChkYXRhTGVuZ3RoIC8gdGhpcy5jb2x1bW5OdW0pO1xuICAgIGxldCByb3dzQXJyO1xuICAgIGlmICh0aGlzLmRlZmF1bHRQcm9wcy5pc0Nhcm91c2VsKSB7XG4gICAgICBpZiAocm93Q291bnQgJSB0aGlzLmNhcm91c2VsTWF4Um93ICE9PSAwKSB7XG4gICAgICAgIHJvd0NvdW50ID0gcm93Q291bnQgKyB0aGlzLmNhcm91c2VsTWF4Um93IC0gKHJvd0NvdW50ICUgdGhpcy5jYXJvdXNlbE1heFJvdyk7XG4gICAgICB9XG4gICAgICBjb25zdCBwYWdlQ291bnQgPSBNYXRoLmNlaWwocm93Q291bnQgLyB0aGlzLmNhcm91c2VsTWF4Um93KTtcbiAgICAgIHJvd3NBcnIgPSB0aGlzLmdldFJvd3Mocm93Q291bnQsIGRhdGFMZW5ndGgpO1xuICAgICAgaWYgKHBhZ2VDb3VudCA8PSAxKSB7XG4gICAgICAgIHRoaXMuY2Fyb3VzZWxQcm9wcyA9IHtcbiAgICAgICAgICBkb3RzOiBmYWxzZSxcbiAgICAgICAgICBkcmFnZ2luZzogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY2Fyb3VzZWxQcm9wcyA9IHtcbiAgICAgICAgICBkb3RzOiB0cnVlLFxuICAgICAgICAgIGRyYWdnaW5nOiB0cnVlXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICB0aGlzLmNhcm91c2VsRGF0YVRtcCA9IHRoaXMuZ2V0Q2Fyb3VzZWxEYXRhKHJvd3NBcnIsIHBhZ2VDb3VudCwgcm93Q291bnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmdyaWREYXRhID0gdGhpcy5nZXRSb3dzKHJvd0NvdW50LCBkYXRhTGVuZ3RoKTtcbiAgICB9XG4gIH1cblxuICBnZXRDYXJvdXNlbERhdGEocm93c0FycjogYW55W10sIHBhZ2VDb3VudDogbnVtYmVyLCByb3dDb3VudDogbnVtYmVyKSB7XG4gICAgY29uc3QgcGFnZXNBcnI6IGFueVtdID0gW107XG4gICAgZm9yIChsZXQgcGFnZUluZGV4ID0gMDsgcGFnZUluZGV4IDwgcGFnZUNvdW50OyBwYWdlSW5kZXgrKykge1xuICAgICAgY29uc3QgcGFnZVJvd3M6IGFueVtdID0gW107XG4gICAgICBmb3IgKGxldCBpaSA9IDA7IGlpIDwgdGhpcy5jYXJvdXNlbE1heFJvdzsgaWkrKykge1xuICAgICAgICBjb25zdCByb3dJbmRleCA9IHBhZ2VJbmRleCAqIHRoaXMuY2Fyb3VzZWxNYXhSb3cgKyBpaTtcbiAgICAgICAgaWYgKHJvd0luZGV4IDwgcm93Q291bnQpIHtcbiAgICAgICAgICBwYWdlUm93cy5wdXNoKHJvd3NBcnJbcm93SW5kZXhdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyDnqbroioLngrnkuLrkuobnoa7kv53mnKvlsL7pobXnmoTmnIDlkI7mnKrliLDlupXnmoTooYzmnInlupXnur8o5qC35byP5LitbGFzdC1jaGlsZOS8muayoee6vylcbiAgICAgICAgICBwYWdlUm93cy5wdXNoKG51bGwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBwYWdlc0Fyci5wdXNoKHBhZ2VSb3dzKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhZ2VzQXJyO1xuICB9XG5cbiAgZ2V0Um93cyhyb3dDb3VudDogbnVtYmVyLCBkYXRhTGVuZ3RoOiBudW1iZXIpIHtcbiAgICBjb25zdCBjb2x1bW5OdW0gPSB0aGlzLmNvbHVtbk51bTtcbiAgICBjb25zdCByb3dBcnIgPSBuZXcgQXJyYXkoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd0NvdW50OyBpKyspIHtcbiAgICAgIHJvd0FycltpXSA9IG5ldyBBcnJheSgpO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjb2x1bW5OdW07IGorKykge1xuICAgICAgICBjb25zdCBkYXRhSW5kZXggPSBpICogY29sdW1uTnVtICsgajtcbiAgICAgICAgaWYgKGRhdGFJbmRleCA8IGRhdGFMZW5ndGgpIHtcbiAgICAgICAgICByb3dBcnJbaV1bal0gPSB0aGlzLl9kYXRhW2RhdGFJbmRleF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcm93QXJyW2ldW2pdID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcm93QXJyO1xuICB9XG5cbiAgY2xpY2soZGF0YSwgaW5kZXgpIHtcbiAgICBjb25zdCBvdXRwdXREYXRhID0ge1xuICAgICAgZGF0YTogZGF0YSxcbiAgICAgIGluZGV4OiBpbmRleFxuICAgIH07XG4gICAgdGhpcy5vbkNsaWNrLmVtaXQob3V0cHV0RGF0YSk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLml0ZW1DbHMgPSB7XG4gICAgICBbYCR7dGhpcy5kZWZhdWx0UHJvcHMucHJlZml4Q2xzfS1pdGVtYF06IHRydWUsXG4gICAgICBbYCR7dGhpcy5kZWZhdWx0UHJvcHMucHJlZml4Q2xzfS1hY3RpdmUtaXRlbWBdOiBmYWxzZVxuICAgIH07XG4gIH1cbn1cbiIsIjxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNDYXJvdXNlbFwiPlxuICA8RmxleCAqbmdGb3I9XCJsZXQgaXRlbSBvZiBncmlkRGF0YTsgbGV0IGkgPSBpbmRleFwiIFtqdXN0aWZ5XT1cIidjZW50ZXInXCIgW2FsaWduXT1cIidzdHJldGNoJ1wiPlxuICAgIDxGbGV4SXRlbVxuICAgICAgVG91Y2hGZWVkYmFja0RpcmVjdGl2ZVxuICAgICAgKm5nRm9yPVwibGV0IHN1Ykl0ZW0gb2YgaXRlbTsgbGV0IGogPSBpbmRleFwiXG4gICAgICBbbmdDbGFzc109XCJpdGVtQ2xzXCJcbiAgICAgIFtuZ1N0eWxlXT1cIml0ZW1TdHlsZVwiXG4gICAgICBbY2xhc3NOYW1lXT1cIlsnYW0tZ3JpZC1pdGVtLWFjdGl2ZSddXCJcbiAgICAgIFthY3RpdmVTdHlsZV09XCJhY3RpdmVTdHlsZVwiXG4gICAgPlxuICAgICAgPGRpdlxuICAgICAgICAqbmdJZj1cInN1Ykl0ZW0gIT09IG51bGxcIlxuICAgICAgICBjbGFzcz1cInt7IGRlZmF1bHRQcm9wcy5wcmVmaXhDbHMgfX0taXRlbS1jb250ZW50XCJcbiAgICAgICAgKGNsaWNrKT1cImNsaWNrKHN1Ykl0ZW0sIGkgKiBjb2x1bW5OdW0gKyBqKVwiXG4gICAgICA+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ7eyBkZWZhdWx0UHJvcHMucHJlZml4Q2xzIH19LWl0ZW0taW5uZXItY29udGVudCBjb2x1bW4tbnVtLXt7IGNvbHVtbk51bSB9fVwiPlxuICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICpuZ0lmPVwic3ViSXRlbS5pY29uICYmIGdldENvbnRlbnRUeXBlKHN1Ykl0ZW0uaWNvbikgPT09ICd1cmwnXCJcbiAgICAgICAgICAgIHNyYz1cInt7IHN1Ykl0ZW0uaWNvbiB9fVwiXG4gICAgICAgICAgICBjbGFzcz1cInt7IGRlZmF1bHRQcm9wcy5wcmVmaXhDbHMgfX0taWNvblwiXG4gICAgICAgICAgLz5cbiAgICAgICAgICA8SWNvblxuICAgICAgICAgICAgKm5nSWY9XCJzdWJJdGVtLmljb24gJiYgZ2V0Q29udGVudFR5cGUoc3ViSXRlbS5pY29uKSA9PT0gJ2ljb24nXCJcbiAgICAgICAgICAgIFt0eXBlXT1cInN1Ykl0ZW0uaWNvblwiXG4gICAgICAgICAgICBbc2l6ZV09XCJzdWJJdGVtLnNpemVcIlxuICAgICAgICAgID48L0ljb24+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgKm5nSWY9XCJzdWJJdGVtLmljb24gJiYgZ2V0Q29udGVudFR5cGUoc3ViSXRlbS5pY29uKSA9PT0gJ2lubmVySFRNTCdcIlxuICAgICAgICAgICAgW2lubmVySFRNTF09XCJzdWJJdGVtLmljb24gfCBzYWZlSFRNTFwiXG4gICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgKm5nSWY9XCJzdWJJdGVtLmljb24gJiYgZ2V0Q29udGVudFR5cGUoc3ViSXRlbS5pY29uKSA9PT0gJ1RlbXBsYXRlUmVmJ1wiXG4gICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJzdWJJdGVtLmljb25cIlxuICAgICAgICAgID48L25nLXRlbXBsYXRlPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ7eyBkZWZhdWx0UHJvcHMucHJlZml4Q2xzIH19LXRleHRcIj57eyBzdWJJdGVtLnRleHQgfX08L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgKm5nSWY9XCJzdWJJdGVtID09PSBudWxsXCIgY2xhc3M9XCJ7eyBkZWZhdWx0UHJvcHMucHJlZml4Q2xzIH19LW51bGwtaXRlbVwiPjwvZGl2PlxuICAgIDwvRmxleEl0ZW0+XG4gIDwvRmxleD5cbiAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuPC9uZy1jb250YWluZXI+XG5cbjxDYXJvdXNlbFxuICAqbmdJZj1cImlzQ2Fyb3VzZWwgJiYgY2Fyb3VzZWxEYXRhVG1wLmxlbmd0aCA+IDBcIlxuICBbYXV0b3BsYXldPVwiZmFsc2VcIlxuICBbaW5maW5pdGVdPVwidHJ1ZVwiXG4gIFtzZWxlY3RlZEluZGV4XT1cIjBcIlxuICBbYXV0b3BsYXlJbnRlcnZhbF09XCIzMDAwXCJcbiAgW2RvdHNdPVwiY2Fyb3VzZWxQcm9wcy5kb3RzXCJcbiAgW2RyYWdnaW5nXT1cImNhcm91c2VsUHJvcHMuZHJhZ2dpbmdcIlxuPlxuICA8Q2Fyb3VzZWxTbGlkZVxuICAgICpuZ0Zvcj1cImxldCBncmlkRGF0YSBvZiBjYXJvdXNlbERhdGFUbXBcIlxuICAgIGNsYXNzPVwie3sgZGVmYXVsdFByb3BzLnByZWZpeENscyB9fS1jYXJvdXNlbC1wYWdlXCJcbiAgICBzdHlsZT1cImRpc3BsYXk6IGJsb2NrO1wiXG4gID5cbiAgICA8RmxleCAqbmdGb3I9XCJsZXQgaXRlbSBvZiBncmlkRGF0YTsgbGV0IGkgPSBpbmRleFwiIFtqdXN0aWZ5XT1cIidjZW50ZXInXCIgW2FsaWduXT1cIidzdHJldGNoJ1wiPlxuICAgICAgPEZsZXhJdGVtXG4gICAgICAgIFRvdWNoRmVlZGJhY2tEaXJlY3RpdmVcbiAgICAgICAgKm5nRm9yPVwibGV0IHN1Ykl0ZW0gb2YgaXRlbTsgbGV0IGogPSBpbmRleFwiXG4gICAgICAgIGNsYXNzPVwie3sgZGVmYXVsdFByb3BzLnByZWZpeENscyB9fS1pdGVtXCJcbiAgICAgICAgW25nU3R5bGVdPVwiaXRlbVN0eWxlXCJcbiAgICAgICAgW2NsYXNzTmFtZV09XCJbJ2FtLWdyaWQtaXRlbS1hY3RpdmUnXVwiXG4gICAgICA+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAqbmdJZj1cInN1Ykl0ZW0gIT09IG51bGxcIlxuICAgICAgICAgIGNsYXNzPVwie3sgZGVmYXVsdFByb3BzLnByZWZpeENscyB9fS1pdGVtLWNvbnRlbnRcIlxuICAgICAgICAgIChjbGljayk9XCJjbGljayhzdWJJdGVtLCBpICogY29sdW1uTnVtICsgailcIlxuICAgICAgICA+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInt7IGRlZmF1bHRQcm9wcy5wcmVmaXhDbHMgfX0taXRlbS1pbm5lci1jb250ZW50IGNvbHVtbi1udW0tNFwiPlxuICAgICAgICAgICAgPGltZyBjbGFzcz1cInt7IGRlZmF1bHRQcm9wcy5wcmVmaXhDbHMgfX0taWNvblwiIHNyYz1cInt7IHN1Ykl0ZW0uaWNvbiB9fVwiIC8+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwie3sgZGVmYXVsdFByb3BzLnByZWZpeENscyB9fS10ZXh0XCI+e3sgc3ViSXRlbS50ZXh0IH19PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICpuZ0lmPVwic3ViSXRlbSA9PT0gbnVsbFwiIGNsYXNzPVwie3sgZGVmYXVsdFByb3BzLnByZWZpeENscyB9fS1udWxsLWl0ZW1cIj48L2Rpdj5cbiAgICAgIDwvRmxleEl0ZW0+XG4gICAgPC9GbGV4PlxuICA8L0Nhcm91c2VsU2xpZGU+XG48L0Nhcm91c2VsPlxuIl19