UNPKG

ng-zorro-antd

Version:

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

252 lines 36.1 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 } 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: "17.3.4", ngImport: i0, type: NzWaterMarkComponent, deps: [{ token: i0.ElementRef }, { token: DOCUMENT }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: NzWaterMarkComponent, isStandalone: true, selector: "nz-water-mark", inputs: { nzWidth: "nzWidth", nzHeight: "nzHeight", nzRotate: "nzRotate", nzZIndex: "nzZIndex", 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: "17.3.4", 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 }], nzHeight: [{ type: Input }], nzRotate: [{ type: Input }], nzZIndex: [{ type: Input }], nzImage: [{ type: Input }], nzContent: [{ type: Input }], nzFont: [{ type: Input }], nzGap: [{ type: Input }], nzOffset: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F0ZXItbWFyay5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL3dhdGVyLW1hcmsvd2F0ZXItbWFyay5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFFTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULE1BQU0sRUFDTixLQUFLLEVBS04sTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFFLGFBQWEsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLGVBQWUsRUFBRSxNQUFNLFFBQVEsQ0FBQzs7QUFFbEY7OztHQUdHO0FBQ0gsTUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBQ25CLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQztBQVlsQixNQUFNLE9BQU8sb0JBQW9CO0lBMEIvQixZQUNVLEVBQWMsRUFDSSxRQUFrQixFQUNwQyxHQUFzQjtRQUZ0QixPQUFFLEdBQUYsRUFBRSxDQUFZO1FBQ0ksYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNwQyxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQTVCdkIsWUFBTyxHQUFXLEdBQUcsQ0FBQztRQUN0QixhQUFRLEdBQVcsRUFBRSxDQUFDO1FBQ3RCLGFBQVEsR0FBVyxDQUFDLEVBQUUsQ0FBQztRQUN2QixhQUFRLEdBQVcsQ0FBQyxDQUFDO1FBQ3JCLFlBQU8sR0FBVyxFQUFFLENBQUM7UUFDckIsY0FBUyxHQUFzQixFQUFFLENBQUM7UUFDbEMsV0FBTSxHQUFhLEVBQUUsQ0FBQztRQUN0QixVQUFLLEdBQXFCLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLGFBQVEsR0FBcUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FB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QVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgU2ltcGxlQ2hhbmdlc1xufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgTWFya1N0eWxlVHlwZSwgRm9udFR5cGUgfSBmcm9tICcuL3R5cGluZ3MnO1xuaW1wb3J0IHsgZ2V0UGl4ZWxSYXRpbywgZ2V0U3R5bGVTdHIsIHJlUmVuZGVyaW5nLCByb3RhdGVXYXRlcm1hcmsgfSBmcm9tICcuL3V0aWwnO1xuXG4vKipcbiAqIEJhc2Ugc2l6ZSBvZiB0aGUgY2FudmFzLCAxIGZvciBwYXJhbGxlbCBsYXlvdXQgYW5kIDIgZm9yIGFsdGVybmF0ZSBsYXlvdXRcbiAqIE9ubHkgYWx0ZXJuYXRlIGxheW91dCBpcyBjdXJyZW50bHkgc3VwcG9ydGVkXG4gKi9cbmNvbnN0IEJhc2VTaXplID0gMjtcbmNvbnN0IEZvbnRHYXAgPSAzO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei13YXRlci1tYXJrJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgZXhwb3J0QXM6ICdOeldhdGVyTWFyaycsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYCA8bmctY29udGVudD48L25nLWNvbnRlbnQ+IGAsXG4gIGhvc3Q6IHtcbiAgICBjbGFzczogJ2FudC13YXRlci1tYXJrJ1xuICB9XG59KVxuZXhwb3J0IGNsYXNzIE56V2F0ZXJNYXJrQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIG56V2lkdGg6IG51bWJlciA9IDEyMDtcbiAgQElucHV0KCkgbnpIZWlnaHQ6IG51bWJlciA9IDY0O1xuICBASW5wdXQoKSBuelJvdGF0ZTogbnVtYmVyID0gLTIyO1xuICBASW5wdXQoKSBuelpJbmRleDogbnVtYmVyID0gOTtcbiAgQElucHV0KCkgbnpJbWFnZTogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIG56Q29udGVudDogc3RyaW5nIHwgc3RyaW5nW10gPSAnJztcbiAgQElucHV0KCkgbnpGb250OiBGb250VHlwZSA9IHt9O1xuICBASW5wdXQoKSBuekdhcDogW251bWJlciwgbnVtYmVyXSA9IFsxMDAsIDEwMF07XG4gIEBJbnB1dCgpIG56T2Zmc2V0OiBbbnVtYmVyLCBudW1iZXJdID0gW3RoaXMubnpHYXBbMF0gLyAyLCB0aGlzLm56R2FwWzFdIC8gMl07XG5cbiAgd2F0ZXJNYXJrRWxlbWVudDogSFRNTERpdkVsZW1lbnQgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICBzdG9wT2JzZXJ2YXRpb246IGJvb2xlYW4gPSBmYWxzZTtcblxuICBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKG11dGF0aW9ucyA9PiB7XG4gICAgaWYgKHRoaXMuc3RvcE9ic2VydmF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG11dGF0aW9ucy5mb3JFYWNoKG11dGF0aW9uID0+IHtcbiAgICAgIGlmIChyZVJlbmRlcmluZyhtdXRhdGlvbiwgdGhpcy53YXRlck1hcmtFbGVtZW50KSkge1xuICAgICAgICB0aGlzLmRlc3Ryb3lXYXRlcm1hcmsoKTtcbiAgICAgICAgdGhpcy5yZW5kZXJXYXRlcm1hcmsoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZixcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudCxcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsIHtcbiAgICAgIHN1YnRyZWU6IHRydWUsXG4gICAgICBjaGlsZExpc3Q6IHRydWUsXG4gICAgICBhdHRyaWJ1dGVGaWx0ZXI6IFsnc3R5bGUnLCAnY2xhc3MnXVxuICAgIH0pO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyV2F0ZXJtYXJrKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3QgeyBuelJvdGF0ZSwgbnpaSW5kZXgsIG56V2lkdGgsIG56SGVpZ2h0LCBuekltYWdlLCBuekNvbnRlbnQsIG56Rm9udCwgZ2FwWCwgZ2FwWSwgb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wIH0gPVxuICAgICAgY2hhbmdlcztcblxuICAgIGlmIChcbiAgICAgIG56Um90YXRlIHx8XG4gICAgICBuelpJbmRleCB8fFxuICAgICAgbnpXaWR0aCB8fFxuICAgICAgbnpIZWlnaHQgfHxcbiAgICAgIG56SW1hZ2UgfHxcbiAgICAgIG56Q29udGVudCB8fFxuICAgICAgbnpGb250IHx8XG4gICAgICBnYXBYIHx8XG4gICAgICBnYXBZIHx8XG4gICAgICBvZmZzZXRMZWZ0IHx8XG4gICAgICBvZmZzZXRUb3BcbiAgICApIHtcbiAgICAgIHRoaXMucmVuZGVyV2F0ZXJtYXJrKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0Rm9udCgpOiB2b2lkIHtcbiAgICBjb25zdCBmb250OiBGb250VHlwZSA9IHtcbiAgICAgIGNvbG9yOiAncmdiYSgwLDAsMCwuMTUpJyxcbiAgICAgIGZvbnRTaXplOiAxNixcbiAgICAgIGZvbnRXZWlnaHQ6ICdub3JtYWwnLFxuICAgICAgZm9udEZhbWlseTogJ3NhbnMtc2VyaWYnLFxuICAgICAgZm9udFN0eWxlOiAnbm9ybWFsJ1xuICAgIH07XG5cbiAgICB0aGlzLm56Rm9udCA9IHsgLi4uZm9udCwgLi4udGhpcy5uekZvbnQgfTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIGdldE1hcmtTdHlsZSgpOiBNYXJrU3R5bGVUeXBlIHtcbiAgICBjb25zdCBtYXJrU3R5bGU6IE1hcmtTdHlsZVR5cGUgPSB7XG4gICAgICB6SW5kZXg6IHRoaXMubnpaSW5kZXgsXG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIGxlZnQ6IDAsXG4gICAgICB0b3A6IDAsXG4gICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICBwb2ludGVyRXZlbnRzOiAnbm9uZScsXG4gICAgICBiYWNrZ3JvdW5kUmVwZWF0OiAncmVwZWF0JyxcbiAgICAgIHZpc2liaWxpdHk6ICd2aXNpYmxlJ1xuICAgIH07XG5cbiAgICAvKiogQ2FsY3VsYXRlIHRoZSBzdHlsZSBvZiB0aGUgbnpPZmZzZXQgKi9cbiAgICBsZXQgcG9zaXRpb25MZWZ0ID0gKHRoaXMubnpPZmZzZXQ/LlswXSA/PyB0aGlzLm56R2FwWzBdIC8gMikgLSB0aGlzLm56R2FwWzBdIC8gMjtcbiAgICBsZXQgcG9zaXRpb25Ub3AgPSAodGhpcy5uek9mZnNldD8uWzFdID8/IHRoaXMubnpHYXBbMV0gLyAyKSAtIHRoaXMubnpHYXBbMV0gLyAyO1xuICAgIGlmIChwb3NpdGlvbkxlZnQgPiAwKSB7XG4gICAgICBtYXJrU3R5bGUubGVmdCA9IGAke3Bvc2l0aW9uTGVmdH1weGA7XG4gICAgICBtYXJrU3R5bGUud2lkdGggPSBgY2FsYygxMDAlIC0gJHtwb3NpdGlvbkxlZnR9cHgpYDtcbiAgICAgIHBvc2l0aW9uTGVmdCA9IDA7XG4gICAgfVxuICAgIGlmIChwb3NpdGlvblRvcCA+IDApIHtcbiAgICAgIG1hcmtTdHlsZS50b3AgPSBgJHtwb3NpdGlvblRvcH1weGA7XG4gICAgICBtYXJrU3R5bGUuaGVpZ2h0ID0gYGNhbGMoMTAwJSAtICR7cG9zaXRpb25Ub3B9cHgpYDtcbiAgICAgIHBvc2l0aW9uVG9wID0gMDtcbiAgICB9XG4gICAgbWFya1N0eWxlLmJhY2tncm91bmRQb3NpdGlvbiA9IGAke3Bvc2l0aW9uTGVmdH1weCAke3Bvc2l0aW9uVG9wfXB4YDtcblxuICAgIHJldHVybiBtYXJrU3R5bGU7XG4gIH1cblxuICBkZXN0cm95V2F0ZXJtYXJrKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLndhdGVyTWFya0VsZW1lbnQpIHtcbiAgICAgIHRoaXMud2F0ZXJNYXJrRWxlbWVudC5yZW1vdmUoKTtcbiAgICB9XG4gIH1cblxuICBhcHBlbmRXYXRlcm1hcmsoYmFzZTY0VXJsOiBzdHJpbmcsIG1hcmtXaWR0aDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wT2JzZXJ2YXRpb24gPSB0cnVlO1xuICAgIHRoaXMud2F0ZXJNYXJrRWxlbWVudC5zZXRBdHRyaWJ1dGUoXG4gICAgICAnc3R5bGUnLFxuICAgICAgZ2V0U3R5bGVTdHIoe1xuICAgICAgICAuLi50aGlzLmdldE1hcmtTdHlsZSgpLFxuICAgICAgICBiYWNrZ3JvdW5kSW1hZ2U6IGB1cmwoJyR7YmFzZTY0VXJsfScpYCxcbiAgICAgICAgYmFja2dyb3VuZFNpemU6IGAkeyh0aGlzLm56R2FwWzBdICsgbWFya1dpZHRoKSAqIEJhc2VTaXplfXB4YFxuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5hcHBlbmQodGhpcy53YXRlck1hcmtFbGVtZW50KTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcblxuICAgIC8vIERlbGF5ZWQgZXhlY3V0aW9uXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnN0b3BPYnNlcnZhdGlvbiA9IGZhbHNlO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRNYXJrU2l6ZShjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGxldCBkZWZhdWx0V2lkdGggPSAxMjA7XG4gICAgbGV0IGRlZmF1bHRIZWlnaHQgPSA2NDtcbiAgICBpZiAoIXRoaXMubnpJbWFnZSAmJiBjdHgubWVhc3VyZVRleHQpIHtcbiAgICAgIGN0eC5mb250ID0gYCR7TnVtYmVyKHRoaXMubnpGb250LmZvbnRTaXplKX1weCAke3RoaXMubnpGb250LmZvbnRGYW1pbHl9YDtcbiAgICAgIGNvbnN0IGNvbnRlbnRzID0gQXJyYXkuaXNBcnJheSh0aGlzLm56Q29udGVudCkgPyB0aGlzLm56Q29udGVudCA6IFt0aGlzLm56Q29udGVudF07XG4gICAgICBjb25zdCB3aWR0aHMgPSBjb250ZW50cy5tYXAoaXRlbSA9PiBjdHgubWVhc3VyZVRleHQoaXRlbSEpLndpZHRoKTtcbiAgICAgIGRlZmF1bHRXaWR0aCA9IE1hdGguY2VpbChNYXRoLm1heCguLi53aWR0aHMpKTtcbiAgICAgIGRlZmF1bHRIZWlnaHQgPSBOdW1iZXIodGhpcy5uekZvbnQuZm9udFNpemUpICogY29udGVudHMubGVuZ3RoICsgKGNvbnRlbnRzLmxlbmd0aCAtIDEpICogRm9udEdhcDtcbiAgICB9XG4gICAgcmV0dXJuIFt0aGlzLm56V2lkdGggPz8gZGVmYXVsdFdpZHRoLCB0aGlzLm56SGVpZ2h0ID8/IGRlZmF1bHRIZWlnaHRdO1xuICB9XG5cbiAgZmlsbFRleHRzKGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELCBkcmF3WDogbnVtYmVyLCBkcmF3WTogbnVtYmVyLCBkcmF3V2lkdGg6IG51bWJlciwgZHJhd0hlaWdodDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgcmF0aW8gPSBnZXRQaXhlbFJhdGlvKCk7XG4gICAgY29uc3QgbWVyZ2VkRm9udFNpemUgPSBOdW1iZXIodGhpcy5uekZvbnQuZm9udFNpemUpICogcmF0aW87XG4gICAgY3R4LmZvbnQgPSBgJHt0aGlzLm56Rm9udC5mb250U3R5bGV9IG5vcm1hbCAke3RoaXMubnpGb250LmZvbnRXZWlnaHR9ICR7bWVyZ2VkRm9udFNpemV9cHgvJHtkcmF3SGVpZ2h0fXB4ICR7dGhpcy5uekZvbnQuZm9udEZhbWlseX1gO1xuICAgIGlmICh0aGlzLm56Rm9udC5jb2xvcikgY3R4LmZpbGxTdHlsZSA9IHRoaXMubnpGb250LmNvbG9yO1xuICAgIGN0eC50ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICBjdHgudGV4dEJhc2VsaW5lID0gJ3RvcCc7XG4gICAgY3R4LnRyYW5zbGF0ZShkcmF3V2lkdGggLyAyLCAwKTtcbiAgICBjb25zdCBjb250ZW50cyA9IEFycmF5LmlzQXJyYXkodGhpcy5uekNvbnRlbnQpID8gdGhpcy5uekNvbnRlbnQgOiBbdGhpcy5uekNvbnRlbnRdO1xuICAgIGNvbnRlbnRzPy5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgY3R4LmZpbGxUZXh0KGl0ZW0gPz8gJycsIGRyYXdYLCBkcmF3WSArIGluZGV4ICogKG1lcmdlZEZvbnRTaXplICsgRm9udEdhcCAqIHJhdGlvKSk7XG4gICAgfSk7XG4gIH1cblxuICBkcmF3VGV4dChcbiAgICBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50LFxuICAgIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICAgIGRyYXdYOiBudW1iZXIsXG4gICAgZHJhd1k6IG51bWJlcixcbiAgICBkcmF3V2lkdGg6IG51bWJlcixcbiAgICBkcmF3SGVpZ2h0OiBudW1iZXIsXG4gICAgYWx0ZXJuYXRlUm90YXRlWDogbnVtYmVyLFxuICAgIGFsdGVybmF0ZVJvdGF0ZVk6IG51bWJlcixcbiAgICBhbHRlcm5hdGVEcmF3WDogbnVtYmVyLFxuICAgIGFsdGVybmF0ZURyYXdZOiBudW1iZXIsXG4gICAgbWFya1dpZHRoOiBudW1iZXJcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5maWxsVGV4dHMoY3R4LCBkcmF3WCwgZHJhd1ksIGRyYXdXaWR0aCwgZHJhd0hlaWdodCk7XG5cbiAgICAvKiogRmlsbCB0aGUgaW50ZXJsZWF2ZWQgdGV4dCBhZnRlciByb3RhdGlvbiAqL1xuICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgcm90YXRlV2F0ZXJtYXJrKGN0eCwgYWx0ZXJuYXRlUm90YXRlWCwgYWx0ZXJuYXRlUm90YXRlWSwgdGhpcy5uelJvdGF0ZSk7XG4gICAgdGhpcy5maWxsVGV4dHMoY3R4LCBhbHRlcm5hdGVEcmF3WCwgYWx0ZXJuYXRlRHJhd1ksIGRyYXdXaWR0aCwgZHJhd0hlaWdodCk7XG4gICAgdGhpcy5hcHBlbmRXYXRlcm1hcmsoY2FudmFzLnRvRGF0YVVSTCgpLCBtYXJrV2lkdGgpO1xuICB9XG5cbiAgcmVuZGVyV2F0ZXJtYXJrKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5uekNvbnRlbnQgJiYgIXRoaXMubnpJbWFnZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50ID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhcyBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XG5cbiAgICBpZiAoY3R4KSB7XG4gICAgICBpZiAoIXRoaXMud2F0ZXJNYXJrRWxlbWVudCkge1xuICAgICAgICB0aGlzLndhdGVyTWFya0VsZW1lbnQgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgfVxuICAgICAgdGhpcy5nZXRGb250KCk7XG4gICAgICBjb25zdCByYXRpbyA9IGdldFBpeGVsUmF0aW8oKTtcbiAgICAgIGNvbnN0IFttYXJrV2lkdGgsIG1hcmtIZWlnaHRdID0gdGhpcy5nZXRNYXJrU2l6ZShjdHgpO1xuICAgICAgY29uc3QgY2FudmFzV2lkdGggPSAodGhpcy5uekdhcFswXSArIG1hcmtXaWR0aCkgKiByYXRpbztcbiAgICAgIGNvbnN0IGNhbnZhc0hlaWdodCA9ICh0aGlzLm56R2FwWzFdICsgbWFya0hlaWdodCkgKiByYXRpbztcbiAgICAgIGNhbnZhcy5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgYCR7Y2FudmFzV2lkdGggKiBCYXNlU2l6ZX1weGApO1xuICAgICAgY2FudmFzLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgYCR7Y2FudmFzSGVpZ2h0ICogQmFzZVNpemV9cHhgKTtcblxuICAgICAgY29uc3QgZHJhd1ggPSAodGhpcy5uekdhcFswXSAqIHJhdGlvKSAvIDI7XG4gICAgICBjb25zdCBkcmF3WSA9ICh0aGlzLm56R2FwWzFdICogcmF0aW8pIC8gMjtcbiAgICAgIGNvbnN0IGRyYXdXaWR0aCA9IG1hcmtXaWR0aCAqIHJhdGlvO1xuICAgICAgY29uc3QgZHJhd0hlaWdodCA9IG1hcmtIZWlnaHQgKiByYXRpbztcbiAgICAgIGNvbnN0IHJvdGF0ZVggPSAoZHJhd1dpZHRoICsgdGhpcy5uekdhcFswXSAqIHJhdGlvKSAvIDI7XG4gICAgICBjb25zdCByb3RhdGVZID0gKGRyYXdIZWlnaHQgKyB0aGlzLm56R2FwWzFdICogcmF0aW8pIC8gMjtcblxuICAgICAgLyoqIEFsdGVybmF0ZSBkcmF3aW5nIHBhcmFtZXRlcnMgKi9cbiAgICAgIGNvbnN0IGFsdGVybmF0ZURyYXdYID0gZHJhd1ggKyBjYW52YXNXaWR0aDtcbiAgICAgIGNvbnN0IGFsdGVybmF0ZURyYXdZID0gZHJhd1kgKyBjYW52YXNIZWlnaHQ7XG4gICAgICBjb25zdCBhbHRlcm5hdGVSb3RhdGVYID0gcm90YXRlWCArIGNhbnZhc1dpZHRoO1xuICAgICAgY29uc3QgYWx0ZXJuYXRlUm90YXRlWSA9IHJvdGF0ZVkgKyBjYW52YXNIZWlnaHQ7XG5cbiAgICAgIGN0eC5zYXZlKCk7XG4gICAgICByb3RhdGVXYXRlcm1hcmsoY3R4LCByb3RhdGVYLCByb3RhdGVZLCB0aGlzLm56Um90YXRlKTtcblxuICAgICAgaWYgKHRoaXMubnpJbWFnZSkge1xuICAgICAgICBjb25zdCBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1nLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICBjdHguZHJhd0ltYWdlKGltZywgZHJhd1gsIGRyYXdZLCBkcmF3V2lkdGgsIGRyYXdIZWlnaHQpO1xuXG4gICAgICAgICAgLyoqIERyYXcgaW50ZXJsZWF2ZWQgcGljdHVyZXMgYWZ0ZXIgcm90YXRpb24gKi9cbiAgICAgICAgICBjdHgucmVzdG9yZSgpO1xuICAgICAgICAgIHJvdGF0ZVdhdGVybWFyayhjdHgsIGFsdGVybmF0ZVJvdGF0ZVgsIGFsdGVybmF0ZVJvdGF0ZVksIHRoaXMubnpSb3RhdGUpO1xuICAgICAgICAgIGN0eC5kcmF3SW1hZ2UoaW1nLCBhbHRlcm5hdGVEcmF3WCwgYWx0ZXJuYXRlRHJhd1ksIGRyYXdXaWR0aCwgZHJhd0hlaWdodCk7XG4gICAgICAgICAgdGhpcy5hcHBlbmRXYXRlcm1hcmsoY2FudmFzLnRvRGF0YVVSTCgpLCBtYXJrV2lkdGgpO1xuICAgICAgICB9O1xuICAgICAgICBpbWcub25lcnJvciA9ICgpID0+XG4gICAgICAgICAgdGhpcy5kcmF3VGV4dChcbiAgICAgICAgICAgIGNhbnZhcyxcbiAgICAgICAgICAgIGN0eCxcbiAgICAgICAgICAgIGRyYXdYLFxuICAgICAgICAgICAgZHJhd1ksXG4gICAgICAgICAgICBkcmF3V2lkdGgsXG4gICAgICAgICAgICBkcmF3SGVpZ2h0LFxuICAgICAgICAgICAgYWx0ZXJuYXRlUm90YXRlWCxcbiAgICAgICAgICAgIGFsdGVybmF0ZVJvdGF0ZVksXG4gICAgICAgICAgICBhbHRlcm5hdGVEcmF3WCxcbiAgICAgICAgICAgIGFsdGVybmF0ZURyYXdZLFxuICAgICAgICAgICAgbWFya1dpZHRoXG4gICAgICAgICAgKTtcbiAgICAgICAgaW1nLmNyb3NzT3JpZ2luID0gJ2Fub255bW91cyc7XG4gICAgICAgIGltZy5yZWZlcnJlclBvbGljeSA9ICduby1yZWZlcnJlcic7XG4gICAgICAgIGltZy5zcmMgPSB0aGlzLm56SW1hZ2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRyYXdUZXh0KFxuICAgICAgICAgIGNhbnZhcyxcbiAgICAgICAgICBjdHgsXG4gICAgICAgICAgZHJhd1gsXG4gICAgICAgICAgZHJhd1ksXG4gICAgICAgICAgZHJhd1dpZHRoLFxuICAgICAgICAgIGRyYXdIZWlnaHQsXG4gICAgICAgICAgYWx0ZXJuYXRlUm90YXRlWCxcbiAgICAgICAgICBhbHRlcm5hdGVSb3RhdGVZLFxuICAgICAgICAgIGFsdGVybmF0ZURyYXdYLFxuICAgICAgICAgIGFsdGVybmF0ZURyYXdZLFxuICAgICAgICAgIG1hcmtXaWR0aFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMub2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICB9XG59XG4iXX0=