UNPKG

ng-zorro-antd

Version:

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

256 lines 36.9 kB
/** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ import { DOCUMENT } from '@angular/common'; import { ChangeDetectionStrategy, Component, Inject, Input, numberAttribute } from '@angular/core'; import { getPixelRatio, getStyleStr, reRendering, rotateWatermark } from './util'; import * as i0 from "@angular/core"; /** * Base size of the canvas, 1 for parallel layout and 2 for alternate layout * Only alternate layout is currently supported */ const BaseSize = 2; const FontGap = 3; export class NzWaterMarkComponent { constructor(el, document, cdr) { this.el = el; this.document = document; this.cdr = cdr; this.nzWidth = 120; this.nzHeight = 64; this.nzRotate = -22; this.nzZIndex = 9; this.nzImage = ''; this.nzContent = ''; this.nzFont = {}; this.nzGap = [100, 100]; this.nzOffset = [this.nzGap[0] / 2, this.nzGap[1] / 2]; this.waterMarkElement = this.document.createElement('div'); this.stopObservation = false; this.observer = new MutationObserver(mutations => { if (this.stopObservation) { return; } mutations.forEach(mutation => { if (reRendering(mutation, this.waterMarkElement)) { this.destroyWatermark(); this.renderWatermark(); } }); }); } ngOnInit() { this.observer.observe(this.el.nativeElement, { subtree: true, childList: true, attributeFilter: ['style', 'class'] }); } ngAfterViewInit() { this.renderWatermark(); } ngOnChanges(changes) { const { nzRotate, nzZIndex, nzWidth, nzHeight, nzImage, nzContent, nzFont, gapX, gapY, offsetLeft, offsetTop } = changes; if (nzRotate || nzZIndex || nzWidth || nzHeight || nzImage || nzContent || nzFont || gapX || gapY || offsetLeft || offsetTop) { this.renderWatermark(); } } getFont() { const font = { color: 'rgba(0,0,0,.15)', fontSize: 16, fontWeight: 'normal', fontFamily: 'sans-serif', fontStyle: 'normal' }; this.nzFont = { ...font, ...this.nzFont }; this.cdr.markForCheck(); } getMarkStyle() { const markStyle = { zIndex: this.nzZIndex, position: 'absolute', left: 0, top: 0, width: '100%', height: '100%', pointerEvents: 'none', backgroundRepeat: 'repeat', visibility: 'visible' }; /** Calculate the style of the nzOffset */ let positionLeft = (this.nzOffset?.[0] ?? this.nzGap[0] / 2) - this.nzGap[0] / 2; let positionTop = (this.nzOffset?.[1] ?? this.nzGap[1] / 2) - this.nzGap[1] / 2; if (positionLeft > 0) { markStyle.left = `${positionLeft}px`; markStyle.width = `calc(100% - ${positionLeft}px)`; positionLeft = 0; } if (positionTop > 0) { markStyle.top = `${positionTop}px`; markStyle.height = `calc(100% - ${positionTop}px)`; positionTop = 0; } markStyle.backgroundPosition = `${positionLeft}px ${positionTop}px`; return markStyle; } destroyWatermark() { if (this.waterMarkElement) { this.waterMarkElement.remove(); } } appendWatermark(base64Url, markWidth) { this.stopObservation = true; this.waterMarkElement.setAttribute('style', getStyleStr({ ...this.getMarkStyle(), backgroundImage: `url('${base64Url}')`, backgroundSize: `${(this.nzGap[0] + markWidth) * BaseSize}px` })); this.el.nativeElement.append(this.waterMarkElement); this.cdr.markForCheck(); // Delayed execution setTimeout(() => { this.stopObservation = false; this.cdr.markForCheck(); }); } getMarkSize(ctx) { let defaultWidth = 120; let defaultHeight = 64; if (!this.nzImage && ctx.measureText) { ctx.font = `${Number(this.nzFont.fontSize)}px ${this.nzFont.fontFamily}`; const contents = Array.isArray(this.nzContent) ? this.nzContent : [this.nzContent]; const widths = contents.map(item => ctx.measureText(item).width); defaultWidth = Math.ceil(Math.max(...widths)); defaultHeight = Number(this.nzFont.fontSize) * contents.length + (contents.length - 1) * FontGap; } return [this.nzWidth ?? defaultWidth, this.nzHeight ?? defaultHeight]; } fillTexts(ctx, drawX, drawY, drawWidth, drawHeight) { const ratio = getPixelRatio(); const mergedFontSize = Number(this.nzFont.fontSize) * ratio; ctx.font = `${this.nzFont.fontStyle} normal ${this.nzFont.fontWeight} ${mergedFontSize}px/${drawHeight}px ${this.nzFont.fontFamily}`; if (this.nzFont.color) ctx.fillStyle = this.nzFont.color; ctx.textAlign = 'center'; ctx.textBaseline = 'top'; ctx.translate(drawWidth / 2, 0); const contents = Array.isArray(this.nzContent) ? this.nzContent : [this.nzContent]; contents?.forEach((item, index) => { ctx.fillText(item ?? '', drawX, drawY + index * (mergedFontSize + FontGap * ratio)); }); } drawText(canvas, ctx, drawX, drawY, drawWidth, drawHeight, alternateRotateX, alternateRotateY, alternateDrawX, alternateDrawY, markWidth) { this.fillTexts(ctx, drawX, drawY, drawWidth, drawHeight); /** Fill the interleaved text after rotation */ ctx.restore(); rotateWatermark(ctx, alternateRotateX, alternateRotateY, this.nzRotate); this.fillTexts(ctx, alternateDrawX, alternateDrawY, drawWidth, drawHeight); this.appendWatermark(canvas.toDataURL(), markWidth); } renderWatermark() { if (!this.nzContent && !this.nzImage) { return; } const canvas = this.document.createElement('canvas'); const ctx = canvas.getContext('2d'); if (ctx) { if (!this.waterMarkElement) { this.waterMarkElement = this.document.createElement('div'); } this.getFont(); const ratio = getPixelRatio(); const [markWidth, markHeight] = this.getMarkSize(ctx); const canvasWidth = (this.nzGap[0] + markWidth) * ratio; const canvasHeight = (this.nzGap[1] + markHeight) * ratio; canvas.setAttribute('width', `${canvasWidth * BaseSize}px`); canvas.setAttribute('height', `${canvasHeight * BaseSize}px`); const drawX = (this.nzGap[0] * ratio) / 2; const drawY = (this.nzGap[1] * ratio) / 2; const drawWidth = markWidth * ratio; const drawHeight = markHeight * ratio; const rotateX = (drawWidth + this.nzGap[0] * ratio) / 2; const rotateY = (drawHeight + this.nzGap[1] * ratio) / 2; /** Alternate drawing parameters */ const alternateDrawX = drawX + canvasWidth; const alternateDrawY = drawY + canvasHeight; const alternateRotateX = rotateX + canvasWidth; const alternateRotateY = rotateY + canvasHeight; ctx.save(); rotateWatermark(ctx, rotateX, rotateY, this.nzRotate); if (this.nzImage) { const img = new Image(); img.onload = () => { ctx.drawImage(img, drawX, drawY, drawWidth, drawHeight); /** Draw interleaved pictures after rotation */ ctx.restore(); rotateWatermark(ctx, alternateRotateX, alternateRotateY, this.nzRotate); ctx.drawImage(img, alternateDrawX, alternateDrawY, drawWidth, drawHeight); this.appendWatermark(canvas.toDataURL(), markWidth); }; img.onerror = () => this.drawText(canvas, ctx, drawX, drawY, drawWidth, drawHeight, alternateRotateX, alternateRotateY, alternateDrawX, alternateDrawY, markWidth); img.crossOrigin = 'anonymous'; img.referrerPolicy = 'no-referrer'; img.src = this.nzImage; } else { this.drawText(canvas, ctx, drawX, drawY, drawWidth, drawHeight, alternateRotateX, alternateRotateY, alternateDrawX, alternateDrawY, markWidth); } } } ngOnDestroy() { this.observer.disconnect(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NzWaterMarkComponent, deps: [{ token: i0.ElementRef }, { token: DOCUMENT }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "18.0.1", type: NzWaterMarkComponent, isStandalone: true, selector: "nz-water-mark", inputs: { nzWidth: ["nzWidth", "nzWidth", numberAttribute], nzHeight: ["nzHeight", "nzHeight", numberAttribute], nzRotate: ["nzRotate", "nzRotate", numberAttribute], nzZIndex: ["nzZIndex", "nzZIndex", numberAttribute], nzImage: "nzImage", nzContent: "nzContent", nzFont: "nzFont", nzGap: "nzGap", nzOffset: "nzOffset" }, host: { classAttribute: "ant-water-mark" }, exportAs: ["NzWaterMark"], usesOnChanges: true, ngImport: i0, template: ` <ng-content></ng-content> `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NzWaterMarkComponent, decorators: [{ type: Component, args: [{ selector: 'nz-water-mark', standalone: true, exportAs: 'NzWaterMark', changeDetection: ChangeDetectionStrategy.OnPush, template: ` <ng-content></ng-content> `, host: { class: 'ant-water-mark' } }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: i0.ChangeDetectorRef }], propDecorators: { nzWidth: [{ type: Input, args: [{ transform: numberAttribute }] }], nzHeight: [{ type: Input, args: [{ transform: numberAttribute }] }], nzRotate: [{ type: Input, args: [{ transform: numberAttribute }] }], nzZIndex: [{ type: Input, args: [{ transform: numberAttribute }] }], nzImage: [{ type: Input }], nzContent: [{ type: Input }], nzFont: [{ type: Input }], nzGap: [{ type: Input }], nzOffset: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F0ZXItbWFyay5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL3dhdGVyLW1hcmsvd2F0ZXItbWFyay5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFFTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULE1BQU0sRUFDTixLQUFLLEVBS0wsZUFBZSxFQUNoQixNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLE1BQU0sUUFBUSxDQUFDOztBQUVsRjs7O0dBR0c7QUFDSCxNQUFNLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFDbkIsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBWWxCLE1BQU0sT0FBTyxvQkFBb0I7SUEwQi9CLFlBQ1UsRUFBYyxFQUNJLFFBQWtCLEVBQ3BDLEdBQXNCO1FBRnRCLE9BQUUsR0FBRixFQUFFLENBQVk7UUFDSSxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ3BDLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBNUJPLFlBQU8sR0FBVyxHQUFHLENBQUM7UUFDdEIsYUFBUSxHQUFXLEVBQUUsQ0FBQztRQUN0QixhQUFRLEdBQVcsQ0FBQyxFQUFFLENBQUM7UUFDdkIsYUFBUSxHQUFXLENBQUMsQ0FBQztRQUNuRCxZQUFPLEdBQVcsRUFBRSxDQUFDO1FBQ3JCLGNBQVMsR0FBc0IsRUFBRSxDQUFDO1FBQ2xDLFdBQU0sR0FBYSxFQUFFLENBQUM7UUFDdEIsVUFBSyxHQUFxQixDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNyQyxhQUFRLEdBQXFCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FB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eUVBM0JxQixPQUFPO3NCQUE3QyxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRTtnQkFDRSxRQUFRO3NCQUE5QyxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRTtnQkFDRSxRQUFRO3NCQUE5QyxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRTtnQkFDRSxRQUFRO3NCQUE5QyxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRTtnQkFDNUIsT0FBTztzQkFBZixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIG51bWJlckF0dHJpYnV0ZVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgRm9udFR5cGUsIE1hcmtTdHlsZVR5cGUgfSBmcm9tICcuL3R5cGluZ3MnO1xuaW1wb3J0IHsgZ2V0UGl4ZWxSYXRpbywgZ2V0U3R5bGVTdHIsIHJlUmVuZGVyaW5nLCByb3RhdGVXYXRlcm1hcmsgfSBmcm9tICcuL3V0aWwnO1xuXG4vKipcbiAqIEJhc2Ugc2l6ZSBvZiB0aGUgY2FudmFzLCAxIGZvciBwYXJhbGxlbCBsYXlvdXQgYW5kIDIgZm9yIGFsdGVybmF0ZSBsYXlvdXRcbiAqIE9ubHkgYWx0ZXJuYXRlIGxheW91dCBpcyBjdXJyZW50bHkgc3VwcG9ydGVkXG4gKi9cbmNvbnN0IEJhc2VTaXplID0gMjtcbmNvbnN0IEZvbnRHYXAgPSAzO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei13YXRlci1tYXJrJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgZXhwb3J0QXM6ICdOeldhdGVyTWFyaycsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYCA8bmctY29udGVudD48L25nLWNvbnRlbnQ+IGAsXG4gIGhvc3Q6IHtcbiAgICBjbGFzczogJ2FudC13YXRlci1tYXJrJ1xuICB9XG59KVxuZXhwb3J0IGNsYXNzIE56V2F0ZXJNYXJrQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogbnVtYmVyQXR0cmlidXRlIH0pIG56V2lkdGg6IG51bWJlciA9IDEyMDtcbiAgQElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGUgfSkgbnpIZWlnaHQ6IG51bWJlciA9IDY0O1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IG51bWJlckF0dHJpYnV0ZSB9KSBuelJvdGF0ZTogbnVtYmVyID0gLTIyO1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IG51bWJlckF0dHJpYnV0ZSB9KSBuelpJbmRleDogbnVtYmVyID0gOTtcbiAgQElucHV0KCkgbnpJbWFnZTogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIG56Q29udGVudDogc3RyaW5nIHwgc3RyaW5nW10gPSAnJztcbiAgQElucHV0KCkgbnpGb250OiBGb250VHlwZSA9IHt9O1xuICBASW5wdXQoKSBuekdhcDogW251bWJlciwgbnVtYmVyXSA9IFsxMDAsIDEwMF07XG4gIEBJbnB1dCgpIG56T2Zmc2V0OiBbbnVtYmVyLCBudW1iZXJdID0gW3RoaXMubnpHYXBbMF0gLyAyLCB0aGlzLm56R2FwWzFdIC8gMl07XG5cbiAgd2F0ZXJNYXJrRWxlbWVudDogSFRNTERpdkVsZW1lbnQgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICBzdG9wT2JzZXJ2YXRpb246IGJvb2xlYW4gPSBmYWxzZTtcblxuICBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKG11dGF0aW9ucyA9PiB7XG4gICAgaWYgKHRoaXMuc3RvcE9ic2VydmF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG11dGF0aW9ucy5mb3JFYWNoKG11dGF0aW9uID0+IHtcbiAgICAgIGlmIChyZVJlbmRlcmluZyhtdXRhdGlvbiwgdGhpcy53YXRlck1hcmtFbGVtZW50KSkge1xuICAgICAgICB0aGlzLmRlc3Ryb3lXYXRlcm1hcmsoKTtcbiAgICAgICAgdGhpcy5yZW5kZXJXYXRlcm1hcmsoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZixcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudCxcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsIHtcbiAgICAgIHN1YnRyZWU6IHRydWUsXG4gICAgICBjaGlsZExpc3Q6IHRydWUsXG4gICAgICBhdHRyaWJ1dGVGaWx0ZXI6IFsnc3R5bGUnLCAnY2xhc3MnXVxuICAgIH0pO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyV2F0ZXJtYXJrKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3QgeyBuelJvdGF0ZSwgbnpaSW5kZXgsIG56V2lkdGgsIG56SGVpZ2h0LCBuekltYWdlLCBuekNvbnRlbnQsIG56Rm9udCwgZ2FwWCwgZ2FwWSwgb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wIH0gPVxuICAgICAgY2hhbmdlcztcblxuICAgIGlmIChcbiAgICAgIG56Um90YXRlIHx8XG4gICAgICBuelpJbmRleCB8fFxuICAgICAgbnpXaWR0aCB8fFxuICAgICAgbnpIZWlnaHQgfHxcbiAgICAgIG56SW1hZ2UgfHxcbiAgICAgIG56Q29udGVudCB8fFxuICAgICAgbnpGb250IHx8XG4gICAgICBnYXBYIHx8XG4gICAgICBnYXBZIHx8XG4gICAgICBvZmZzZXRMZWZ0IHx8XG4gICAgICBvZmZzZXRUb3BcbiAgICApIHtcbiAgICAgIHRoaXMucmVuZGVyV2F0ZXJtYXJrKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0Rm9udCgpOiB2b2lkIHtcbiAgICBjb25zdCBmb250OiBGb250VHlwZSA9IHtcbiAgICAgIGNvbG9yOiAncmdiYSgwLDAsMCwuMTUpJyxcbiAgICAgIGZvbnRTaXplOiAxNixcbiAgICAgIGZvbnRXZWlnaHQ6ICdub3JtYWwnLFxuICAgICAgZm9udEZhbWlseTogJ3NhbnMtc2VyaWYnLFxuICAgICAgZm9udFN0eWxlOiAnbm9ybWFsJ1xuICAgIH07XG5cbiAgICB0aGlzLm56Rm9udCA9IHsgLi4uZm9udCwgLi4udGhpcy5uekZvbnQgfTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIGdldE1hcmtTdHlsZSgpOiBNYXJrU3R5bGVUeXBlIHtcbiAgICBjb25zdCBtYXJrU3R5bGU6IE1hcmtTdHlsZVR5cGUgPSB7XG4gICAgICB6SW5kZXg6IHRoaXMubnpaSW5kZXgsXG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIGxlZnQ6IDAsXG4gICAgICB0b3A6IDAsXG4gICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICBwb2ludGVyRXZlbnRzOiAnbm9uZScsXG4gICAgICBiYWNrZ3JvdW5kUmVwZWF0OiAncmVwZWF0JyxcbiAgICAgIHZpc2liaWxpdHk6ICd2aXNpYmxlJ1xuICAgIH07XG5cbiAgICAvKiogQ2FsY3VsYXRlIHRoZSBzdHlsZSBvZiB0aGUgbnpPZmZzZXQgKi9cbiAgICBsZXQgcG9zaXRpb25MZWZ0ID0gKHRoaXMubnpPZmZzZXQ/LlswXSA/PyB0aGlzLm56R2FwWzBdIC8gMikgLSB0aGlzLm56R2FwWzBdIC8gMjtcbiAgICBsZXQgcG9zaXRpb25Ub3AgPSAodGhpcy5uek9mZnNldD8uWzFdID8/IHRoaXMubnpHYXBbMV0gLyAyKSAtIHRoaXMubnpHYXBbMV0gLyAyO1xuICAgIGlmIChwb3NpdGlvbkxlZnQgPiAwKSB7XG4gICAgICBtYXJrU3R5bGUubGVmdCA9IGAke3Bvc2l0aW9uTGVmdH1weGA7XG4gICAgICBtYXJrU3R5bGUud2lkdGggPSBgY2FsYygxMDAlIC0gJHtwb3NpdGlvbkxlZnR9cHgpYDtcbiAgICAgIHBvc2l0aW9uTGVmdCA9IDA7XG4gICAgfVxuICAgIGlmIChwb3NpdGlvblRvcCA+IDApIHtcbiAgICAgIG1hcmtTdHlsZS50b3AgPSBgJHtwb3NpdGlvblRvcH1weGA7XG4gICAgICBtYXJrU3R5bGUuaGVpZ2h0ID0gYGNhbGMoMTAwJSAtICR7cG9zaXRpb25Ub3B9cHgpYDtcbiAgICAgIHBvc2l0aW9uVG9wID0gMDtcbiAgICB9XG4gICAgbWFya1N0eWxlLmJhY2tncm91bmRQb3NpdGlvbiA9IGAke3Bvc2l0aW9uTGVmdH1weCAke3Bvc2l0aW9uVG9wfXB4YDtcblxuICAgIHJldHVybiBtYXJrU3R5bGU7XG4gIH1cblxuICBkZXN0cm95V2F0ZXJtYXJrKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLndhdGVyTWFya0VsZW1lbnQpIHtcbiAgICAgIHRoaXMud2F0ZXJNYXJrRWxlbWVudC5yZW1vdmUoKTtcbiAgICB9XG4gIH1cblxuICBhcHBlbmRXYXRlcm1hcmsoYmFzZTY0VXJsOiBzdHJpbmcsIG1hcmtXaWR0aDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wT2JzZXJ2YXRpb24gPSB0cnVlO1xuICAgIHRoaXMud2F0ZXJNYXJrRWxlbWVudC5zZXRBdHRyaWJ1dGUoXG4gICAgICAnc3R5bGUnLFxuICAgICAgZ2V0U3R5bGVTdHIoe1xuICAgICAgICAuLi50aGlzLmdldE1hcmtTdHlsZSgpLFxuICAgICAgICBiYWNrZ3JvdW5kSW1hZ2U6IGB1cmwoJyR7YmFzZTY0VXJsfScpYCxcbiAgICAgICAgYmFja2dyb3VuZFNpemU6IGAkeyh0aGlzLm56R2FwWzBdICsgbWFya1dpZHRoKSAqIEJhc2VTaXplfXB4YFxuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5hcHBlbmQodGhpcy53YXRlck1hcmtFbGVtZW50KTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcblxuICAgIC8vIERlbGF5ZWQgZXhlY3V0aW9uXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnN0b3BPYnNlcnZhdGlvbiA9IGZhbHNlO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRNYXJrU2l6ZShjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGxldCBkZWZhdWx0V2lkdGggPSAxMjA7XG4gICAgbGV0IGRlZmF1bHRIZWlnaHQgPSA2NDtcbiAgICBpZiAoIXRoaXMubnpJbWFnZSAmJiBjdHgubWVhc3VyZVRleHQpIHtcbiAgICAgIGN0eC5mb250ID0gYCR7TnVtYmVyKHRoaXMubnpGb250LmZvbnRTaXplKX1weCAke3RoaXMubnpGb250LmZvbnRGYW1pbHl9YDtcbiAgICAgIGNvbnN0IGNvbnRlbnRzID0gQXJyYXkuaXNBcnJheSh0aGlzLm56Q29udGVudCkgPyB0aGlzLm56Q29udGVudCA6IFt0aGlzLm56Q29udGVudF07XG4gICAgICBjb25zdCB3aWR0aHMgPSBjb250ZW50cy5tYXAoaXRlbSA9PiBjdHgubWVhc3VyZVRleHQoaXRlbSEpLndpZHRoKTtcbiAgICAgIGRlZmF1bHRXaWR0aCA9IE1hdGguY2VpbChNYXRoLm1heCguLi53aWR0aHMpKTtcbiAgICAgIGRlZmF1bHRIZWlnaHQgPSBOdW1iZXIodGhpcy5uekZvbnQuZm9udFNpemUpICogY29udGVudHMubGVuZ3RoICsgKGNvbnRlbnRzLmxlbmd0aCAtIDEpICogRm9udEdhcDtcbiAgICB9XG4gICAgcmV0dXJuIFt0aGlzLm56V2lkdGggPz8gZGVmYXVsdFdpZHRoLCB0aGlzLm56SGVpZ2h0ID8/IGRlZmF1bHRIZWlnaHRdO1xuICB9XG5cbiAgZmlsbFRleHRzKGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELCBkcmF3WDogbnVtYmVyLCBkcmF3WTogbnVtYmVyLCBkcmF3V2lkdGg6IG51bWJlciwgZHJhd0hlaWdodDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgcmF0aW8gPSBnZXRQaXhlbFJhdGlvKCk7XG4gICAgY29uc3QgbWVyZ2VkRm9udFNpemUgPSBOdW1iZXIodGhpcy5uekZvbnQuZm9udFNpemUpICogcmF0aW87XG4gICAgY3R4LmZvbnQgPSBgJHt0aGlzLm56Rm9udC5mb250U3R5bGV9IG5vcm1hbCAke3RoaXMubnpGb250LmZvbnRXZWlnaHR9ICR7bWVyZ2VkRm9udFNpemV9cHgvJHtkcmF3SGVpZ2h0fXB4ICR7dGhpcy5uekZvbnQuZm9udEZhbWlseX1gO1xuICAgIGlmICh0aGlzLm56Rm9udC5jb2xvcikgY3R4LmZpbGxTdHlsZSA9IHRoaXMubnpGb250LmNvbG9yO1xuICAgIGN0eC50ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICBjdHgudGV4dEJhc2VsaW5lID0gJ3RvcCc7XG4gICAgY3R4LnRyYW5zbGF0ZShkcmF3V2lkdGggLyAyLCAwKTtcbiAgICBjb25zdCBjb250ZW50cyA9IEFycmF5LmlzQXJyYXkodGhpcy5uekNvbnRlbnQpID8gdGhpcy5uekNvbnRlbnQgOiBbdGhpcy5uekNvbnRlbnRdO1xuICAgIGNvbnRlbnRzPy5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgY3R4LmZpbGxUZXh0KGl0ZW0gPz8gJycsIGRyYXdYLCBkcmF3WSArIGluZGV4ICogKG1lcmdlZEZvbnRTaXplICsgRm9udEdhcCAqIHJhdGlvKSk7XG4gICAgfSk7XG4gIH1cblxuICBkcmF3VGV4dChcbiAgICBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50LFxuICAgIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICAgIGRyYXdYOiBudW1iZXIsXG4gICAgZHJhd1k6IG51bWJlcixcbiAgICBkcmF3V2lkdGg6IG51bWJlcixcbiAgICBkcmF3SGVpZ2h0OiBudW1iZXIsXG4gICAgYWx0ZXJuYXRlUm90YXRlWDogbnVtYmVyLFxuICAgIGFsdGVybmF0ZVJvdGF0ZVk6IG51bWJlcixcbiAgICBhbHRlcm5hdGVEcmF3WDogbnVtYmVyLFxuICAgIGFsdGVybmF0ZURyYXdZOiBudW1iZXIsXG4gICAgbWFya1dpZHRoOiBudW1iZXJcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5maWxsVGV4dHMoY3R4LCBkcmF3WCwgZHJhd1ksIGRyYXdXaWR0aCwgZHJhd0hlaWdodCk7XG5cbiAgICAvKiogRmlsbCB0aGUgaW50ZXJsZWF2ZWQgdGV4dCBhZnRlciByb3RhdGlvbiAqL1xuICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgcm90YXRlV2F0ZXJtYXJrKGN0eCwgYWx0ZXJuYXRlUm90YXRlWCwgYWx0ZXJuYXRlUm90YXRlWSwgdGhpcy5uelJvdGF0ZSk7XG4gICAgdGhpcy5maWxsVGV4dHMoY3R4LCBhbHRlcm5hdGVEcmF3WCwgYWx0ZXJuYXRlRHJhd1ksIGRyYXdXaWR0aCwgZHJhd0hlaWdodCk7XG4gICAgdGhpcy5hcHBlbmRXYXRlcm1hcmsoY2FudmFzLnRvRGF0YVVSTCgpLCBtYXJrV2lkdGgpO1xuICB9XG5cbiAgcmVuZGVyV2F0ZXJtYXJrKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5uekNvbnRlbnQgJiYgIXRoaXMubnpJbWFnZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50ID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhcyBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XG5cbiAgICBpZiAoY3R4KSB7XG4gICAgICBpZiAoIXRoaXMud2F0ZXJNYXJrRWxlbWVudCkge1xuICAgICAgICB0aGlzLndhdGVyTWFya0VsZW1lbnQgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgfVxuICAgICAgdGhpcy5nZXRGb250KCk7XG4gICAgICBjb25zdCByYXRpbyA9IGdldFBpeGVsUmF0aW8oKTtcbiAgICAgIGNvbnN0IFttYXJrV2lkdGgsIG1hcmtIZWlnaHRdID0gdGhpcy5nZXRNYXJrU2l6ZShjdHgpO1xuICAgICAgY29uc3QgY2FudmFzV2lkdGggPSAodGhpcy5uekdhcFswXSArIG1hcmtXaWR0aCkgKiByYXRpbztcbiAgICAgIGNvbnN0IGNhbnZhc0hlaWdodCA9ICh0aGlzLm56R2FwWzFdICsgbWFya0hlaWdodCkgKiByYXRpbztcbiAgICAgIGNhbnZhcy5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgYCR7Y2FudmFzV2lkdGggKiBCYXNlU2l6ZX1weGApO1xuICAgICAgY2FudmFzLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgYCR7Y2FudmFzSGVpZ2h0ICogQmFzZVNpemV9cHhgKTtcblxuICAgICAgY29uc3QgZHJhd1ggPSAodGhpcy5uekdhcFswXSAqIHJhdGlvKSAvIDI7XG4gICAgICBjb25zdCBkcmF3WSA9ICh0aGlzLm56R2FwWzFdICogcmF0aW8pIC8gMjtcbiAgICAgIGNvbnN0IGRyYXdXaWR0aCA9IG1hcmtXaWR0aCAqIHJhdGlvO1xuICAgICAgY29uc3QgZHJhd0hlaWdodCA9IG1hcmtIZWlnaHQgKiByYXRpbztcbiAgICAgIGNvbnN0IHJvdGF0ZVggPSAoZHJhd1dpZHRoICsgdGhpcy5uekdhcFswXSAqIHJhdGlvKSAvIDI7XG4gICAgICBjb25zdCByb3RhdGVZID0gKGRyYXdIZWlnaHQgKyB0aGlzLm56R2FwWzFdICogcmF0aW8pIC8gMjtcblxuICAgICAgLyoqIEFsdGVybmF0ZSBkcmF3aW5nIHBhcmFtZXRlcnMgKi9cbiAgICAgIGNvbnN0IGFsdGVybmF0ZURyYXdYID0gZHJhd1ggKyBjYW52YXNXaWR0aDtcbiAgICAgIGNvbnN0IGFsdGVybmF0ZURyYXdZID0gZHJhd1kgKyBjYW52YXNIZWlnaHQ7XG4gICAgICBjb25zdCBhbHRlcm5hdGVSb3RhdGVYID0gcm90YXRlWCArIGNhbnZhc1dpZHRoO1xuICAgICAgY29uc3QgYWx0ZXJuYXRlUm90YXRlWSA9IHJvdGF0ZVkgKyBjYW52YXNIZWlnaHQ7XG5cbiAgICAgIGN0eC5zYXZlKCk7XG4gICAgICByb3RhdGVXYXRlcm1hcmsoY3R4LCByb3RhdGVYLCByb3RhdGVZLCB0aGlzLm56Um90YXRlKTtcblxuICAgICAgaWYgKHRoaXMubnpJbWFnZSkge1xuICAgICAgICBjb25zdCBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1nLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICBjdHguZHJhd0ltYWdlKGltZywgZHJhd1gsIGRyYXdZLCBkcmF3V2lkdGgsIGRyYXdIZWlnaHQpO1xuXG4gICAgICAgICAgLyoqIERyYXcgaW50ZXJsZWF2ZWQgcGljdHVyZXMgYWZ0ZXIgcm90YXRpb24gKi9cbiAgICAgICAgICBjdHgucmVzdG9yZSgpO1xuICAgICAgICAgIHJvdGF0ZVdhdGVybWFyayhjdHgsIGFsdGVybmF0ZVJvdGF0ZVgsIGFsdGVybmF0ZVJvdGF0ZVksIHRoaXMubnpSb3RhdGUpO1xuICAgICAgICAgIGN0eC5kcmF3SW1hZ2UoaW1nLCBhbHRlcm5hdGVEcmF3WCwgYWx0ZXJuYXRlRHJhd1ksIGRyYXdXaWR0aCwgZHJhd0hlaWdodCk7XG4gICAgICAgICAgdGhpcy5hcHBlbmRXYXRlcm1hcmsoY2FudmFzLnRvRGF0YVVSTCgpLCBtYXJrV2lkdGgpO1xuICAgICAgICB9O1xuICAgICAgICBpbWcub25lcnJvciA9ICgpID0+XG4gICAgICAgICAgdGhpcy5kcmF3VGV4dChcbiAgICAgICAgICAgIGNhbnZhcyxcbiAgICAgICAgICAgIGN0eCxcbiAgICAgICAgICAgIGRyYXdYLFxuICAgICAgICAgICAgZHJhd1ksXG4gICAgICAgICAgICBkcmF3V2lkdGgsXG4gICAgICAgICAgICBkcmF3SGVpZ2h0LFxuICAgICAgICAgICAgYWx0ZXJuYXRlUm90YXRlWCxcbiAgICAgICAgICAgIGFsdGVybmF0ZVJvdGF0ZVksXG4gICAgICAgICAgICBhbHRlcm5hdGVEcmF3WCxcbiAgICAgICAgICAgIGFsdGVybmF0ZURyYXdZLFxuICAgICAgICAgICAgbWFya1dpZHRoXG4gICAgICAgICAgKTtcbiAgICAgICAgaW1nLmNyb3NzT3JpZ2luID0gJ2Fub255bW91cyc7XG4gICAgICAgIGltZy5yZWZlcnJlclBvbGljeSA9ICduby1yZWZlcnJlcic7XG4gICAgICAgIGltZy5zcmMgPSB0aGlzLm56SW1hZ2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRyYXdUZXh0KFxuICAgICAgICAgIGNhbnZhcyxcbiAgICAgICAgICBjdHgsXG4gICAgICAgICAgZHJhd1gsXG4gICAgICAgICAgZHJhd1ksXG4gICAgICAgICAgZHJhd1dpZHRoLFxuICAgICAgICAgIGRyYXdIZWlnaHQsXG4gICAgICAgICAgYWx0ZXJuYXRlUm90YXRlWCxcbiAgICAgICAgICBhbHRlcm5hdGVSb3RhdGVZLFxuICAgICAgICAgIGFsdGVybmF0ZURyYXdYLFxuICAgICAgICAgIGFsdGVybmF0ZURyYXdZLFxuICAgICAgICAgIG1hcmtXaWR0aFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMub2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICB9XG59XG4iXX0=