UNPKG

ng-cw-v12

Version:

Angular UI Component Library

382 lines 62.8 kB
import { Component, ViewChild, Input, HostListener } from '@angular/core'; import * as i0 from "@angular/core"; export class ShapeGridBackgroundComponent { constructor(ngZone) { this.ngZone = ngZone; /** 动画移动方向,可选值:right, left, up, down, diagonal */ this.ncDirection = 'diagonal'; /** 动画移动速度(0.1-2) */ this.ncSpeed = 0.5; /** 网格边框颜色 */ this.ncBorderColor = '#271e37'; /** 形状大小(10-100) */ this.ncSquareSize = 40; /** 悬停时的填充颜色 */ this.ncHoverFillColor = '#222222'; /** 形状类型,可选值:square, hexagon, triangle, circle */ this.ncShape = 'square'; /** 鼠标悬停尾迹长度(0-20) */ this.ncHoverTrailAmount = 0; /** 背景色 */ this.ncBgColor = '#000000'; this.ctx = null; this.rafId = null; this.gridOffset = { x: 0, y: 0 }; this.hoveredSquare = null; this.trailCells = []; this.cellOpacities = new Map(); } ngOnInit() { } ngAfterViewInit() { const canvas = this.canvasRef.nativeElement; this.ctx = canvas.getContext('2d'); // 需要在zone外执行的代码用this.ngZone.runOutsideAngular,比如Canvas 更新 this.ngZone.runOutsideAngular(() => { this.setupResizeObserver(canvas); this.resizeCanvas(); this.updateAnimation(); }); } ngOnDestroy() { if (this.rafId !== null) { cancelAnimationFrame(this.rafId); this.rafId = null; } if (this.resizeObserver) { this.resizeObserver.disconnect(); } } setupResizeObserver(canvas) { this.resizeObserver = new ResizeObserver(() => { this.resizeCanvas(); }); this.resizeObserver.observe(canvas.parentElement || canvas); } resizeCanvas() { const canvas = this.canvasRef.nativeElement; const parent = canvas.parentElement; if (parent) { canvas.width = parent.offsetWidth; canvas.height = parent.offsetHeight; } } drawHex(cx, cy, size) { if (!this.ctx) return; this.ctx.beginPath(); for (let i = 0; i < 6; i++) { const angle = (Math.PI / 3) * i; const vx = cx + size * Math.cos(angle); const vy = cy + size * Math.sin(angle); if (i === 0) this.ctx.moveTo(vx, vy); else this.ctx.lineTo(vx, vy); } this.ctx.closePath(); } drawCircle(cx, cy, size) { if (!this.ctx) return; this.ctx.beginPath(); this.ctx.arc(cx, cy, size / 2, 0, Math.PI * 2); this.ctx.closePath(); } drawTriangle(cx, cy, size, flip) { if (!this.ctx) return; this.ctx.beginPath(); if (flip) { this.ctx.moveTo(cx, cy + size / 2); this.ctx.lineTo(cx + size / 2, cy - size / 2); this.ctx.lineTo(cx - size / 2, cy - size / 2); } else { this.ctx.moveTo(cx, cy - size / 2); this.ctx.lineTo(cx + size / 2, cy + size / 2); this.ctx.lineTo(cx - size / 2, cy + size / 2); } this.ctx.closePath(); } drawGrid() { const canvas = this.canvasRef.nativeElement; const ctx = this.ctx; if (!ctx) return; ctx.clearRect(0, 0, canvas.width, canvas.height); const isHex = this.ncShape === 'hexagon'; const isTri = this.ncShape === 'triangle'; const hexHoriz = this.ncSquareSize * 1.5; const hexVert = this.ncSquareSize * Math.sqrt(3); if (isHex) { const colShift = Math.floor(this.gridOffset.x / hexHoriz); const offsetX = ((this.gridOffset.x % hexHoriz) + hexHoriz) % hexHoriz; const offsetY = ((this.gridOffset.y % hexVert) + hexVert) % hexVert; const cols = Math.ceil(canvas.width / hexHoriz) + 3; const rows = Math.ceil(canvas.height / hexVert) + 3; for (let col = -2; col < cols; col++) { for (let row = -2; row < rows; row++) { const cx = col * hexHoriz + offsetX; const cy = row * hexVert + ((col + colShift) % 2 !== 0 ? hexVert / 2 : 0) + offsetY; const cellKey = `${col},${row}`; const alpha = this.cellOpacities.get(cellKey); if (alpha) { ctx.globalAlpha = alpha; this.drawHex(cx, cy, this.ncSquareSize); ctx.fillStyle = this.ncHoverFillColor; ctx.fill(); ctx.globalAlpha = 1; } this.drawHex(cx, cy, this.ncSquareSize); ctx.strokeStyle = this.ncBorderColor; ctx.stroke(); } } } else if (isTri) { const halfW = this.ncSquareSize / 2; const colShift = Math.floor(this.gridOffset.x / halfW); const rowShift = Math.floor(this.gridOffset.y / this.ncSquareSize); const offsetX = ((this.gridOffset.x % halfW) + halfW) % halfW; const offsetY = ((this.gridOffset.y % this.ncSquareSize) + this.ncSquareSize) % this.ncSquareSize; const cols = Math.ceil(canvas.width / halfW) + 4; const rows = Math.ceil(canvas.height / this.ncSquareSize) + 4; for (let col = -2; col < cols; col++) { for (let row = -2; row < rows; row++) { const cx = col * halfW + offsetX; const cy = row * this.ncSquareSize + this.ncSquareSize / 2 + offsetY; const flip = ((col + colShift + row + rowShift) % 2 + 2) % 2 !== 0; const cellKey = `${col},${row}`; const alpha = this.cellOpacities.get(cellKey); if (alpha) { ctx.globalAlpha = alpha; this.drawTriangle(cx, cy, this.ncSquareSize, flip); ctx.fillStyle = this.ncHoverFillColor; ctx.fill(); ctx.globalAlpha = 1; } this.drawTriangle(cx, cy, this.ncSquareSize, flip); ctx.strokeStyle = this.ncBorderColor; ctx.stroke(); } } } else if (this.ncShape === 'circle') { const offsetX = ((this.gridOffset.x % this.ncSquareSize) + this.ncSquareSize) % this.ncSquareSize; const offsetY = ((this.gridOffset.y % this.ncSquareSize) + this.ncSquareSize) % this.ncSquareSize; const cols = Math.ceil(canvas.width / this.ncSquareSize) + 3; const rows = Math.ceil(canvas.height / this.ncSquareSize) + 3; for (let col = -2; col < cols; col++) { for (let row = -2; row < rows; row++) { const cx = col * this.ncSquareSize + this.ncSquareSize / 2 + offsetX; const cy = row * this.ncSquareSize + this.ncSquareSize / 2 + offsetY; const cellKey = `${col},${row}`; const alpha = this.cellOpacities.get(cellKey); if (alpha) { ctx.globalAlpha = alpha; this.drawCircle(cx, cy, this.ncSquareSize); ctx.fillStyle = this.ncHoverFillColor; ctx.fill(); ctx.globalAlpha = 1; } this.drawCircle(cx, cy, this.ncSquareSize); ctx.strokeStyle = this.ncBorderColor; ctx.stroke(); } } } else { const offsetX = ((this.gridOffset.x % this.ncSquareSize) + this.ncSquareSize) % this.ncSquareSize; const offsetY = ((this.gridOffset.y % this.ncSquareSize) + this.ncSquareSize) % this.ncSquareSize; const cols = Math.ceil(canvas.width / this.ncSquareSize) + 3; const rows = Math.ceil(canvas.height / this.ncSquareSize) + 3; for (let col = -2; col < cols; col++) { for (let row = -2; row < rows; row++) { const sx = col * this.ncSquareSize + offsetX; const sy = row * this.ncSquareSize + offsetY; const cellKey = `${col},${row}`; const alpha = this.cellOpacities.get(cellKey); if (alpha) { ctx.globalAlpha = alpha; ctx.fillStyle = this.ncHoverFillColor; ctx.fillRect(sx, sy, this.ncSquareSize, this.ncSquareSize); ctx.globalAlpha = 1; } ctx.strokeStyle = this.ncBorderColor; ctx.strokeRect(sx, sy, this.ncSquareSize, this.ncSquareSize); } } } const gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, Math.sqrt(Math.pow(canvas.width, 2) + Math.pow(canvas.height, 2)) / 2); gradient.addColorStop(0, 'rgba(0, 0, 0, 0)'); ctx.fillStyle = gradient; ctx.fillRect(0, 0, canvas.width, canvas.height); } updateAnimation() { const effectiveSpeed = Math.max(this.ncSpeed, 0.1); const isHex = this.ncShape === 'hexagon'; const isTri = this.ncShape === 'triangle'; const hexHoriz = this.ncSquareSize * 1.5; const hexVert = this.ncSquareSize * Math.sqrt(3); const wrapX = isHex ? hexHoriz * 2 : this.ncSquareSize; const wrapY = isHex ? hexVert : isTri ? this.ncSquareSize * 2 : this.ncSquareSize; switch (this.ncDirection) { case 'right': this.gridOffset.x = (this.gridOffset.x - effectiveSpeed + wrapX) % wrapX; break; case 'left': this.gridOffset.x = (this.gridOffset.x + effectiveSpeed + wrapX) % wrapX; break; case 'up': this.gridOffset.y = (this.gridOffset.y + effectiveSpeed + wrapY) % wrapY; break; case 'down': this.gridOffset.y = (this.gridOffset.y - effectiveSpeed + wrapY) % wrapY; break; case 'diagonal': this.gridOffset.x = (this.gridOffset.x - effectiveSpeed + wrapX) % wrapX; this.gridOffset.y = (this.gridOffset.y - effectiveSpeed + wrapY) % wrapY; break; default: break; } this.updateCellOpacities(); this.drawGrid(); // animation loop this.rafId = requestAnimationFrame(() => this.updateAnimation()); } updateCellOpacities() { const targets = new Map(); if (this.hoveredSquare) { targets.set(`${this.hoveredSquare.x},${this.hoveredSquare.y}`, 1); } if (this.ncHoverTrailAmount > 0) { for (let i = 0; i < this.trailCells.length; i++) { const t = this.trailCells[i]; const key = `${t.x},${t.y}`; if (!targets.has(key)) { targets.set(key, (this.trailCells.length - i) / (this.trailCells.length + 1)); } } } for (const [key] of targets) { if (!this.cellOpacities.has(key)) { this.cellOpacities.set(key, 0); } } for (const [key, opacity] of this.cellOpacities) { const target = targets.get(key) || 0; const next = opacity + (target - opacity) * 0.15; if (next < 0.005) { this.cellOpacities.delete(key); } else { this.cellOpacities.set(key, next); } } } onMouseMove(event) { var _a; const canvas = (_a = this.canvasRef) === null || _a === void 0 ? void 0 : _a.nativeElement; if (!canvas) return; const rect = canvas.getBoundingClientRect(); const mouseX = event.clientX - rect.left; const mouseY = event.clientY - rect.top; const isHex = this.ncShape === 'hexagon'; const isTri = this.ncShape === 'triangle'; const hexHoriz = this.ncSquareSize * 1.5; const hexVert = this.ncSquareSize * Math.sqrt(3); let col = 0; let row = 0; if (isHex) { const colShift = Math.floor(this.gridOffset.x / hexHoriz); const offsetX = ((this.gridOffset.x % hexHoriz) + hexHoriz) % hexHoriz; const offsetY = ((this.gridOffset.y % hexVert) + hexVert) % hexVert; const adjustedX = mouseX - offsetX; const adjustedY = mouseY - offsetY; col = Math.round(adjustedX / hexHoriz); const rowOffset = (col + colShift) % 2 !== 0 ? hexVert / 2 : 0; row = Math.round((adjustedY - rowOffset) / hexVert); } else if (isTri) { const halfW = this.ncSquareSize / 2; const offsetX = ((this.gridOffset.x % halfW) + halfW) % halfW; const offsetY = ((this.gridOffset.y % this.ncSquareSize) + this.ncSquareSize) % this.ncSquareSize; const adjustedX = mouseX - offsetX; const adjustedY = mouseY - offsetY; col = Math.round(adjustedX / halfW); row = Math.floor(adjustedY / this.ncSquareSize); } else if (this.ncShape === 'circle') { const offsetX = ((this.gridOffset.x % this.ncSquareSize) + this.ncSquareSize) % this.ncSquareSize; const offsetY = ((this.gridOffset.y % this.ncSquareSize) + this.ncSquareSize) % this.ncSquareSize; const adjustedX = mouseX - offsetX; const adjustedY = mouseY - offsetY; col = Math.round(adjustedX / this.ncSquareSize); row = Math.round(adjustedY / this.ncSquareSize); } else { const offsetX = ((this.gridOffset.x % this.ncSquareSize) + this.ncSquareSize) % this.ncSquareSize; const offsetY = ((this.gridOffset.y % this.ncSquareSize) + this.ncSquareSize) % this.ncSquareSize; const adjustedX = mouseX - offsetX; const adjustedY = mouseY - offsetY; col = Math.floor(adjustedX / this.ncSquareSize); row = Math.floor(adjustedY / this.ncSquareSize); } if (!this.hoveredSquare || this.hoveredSquare.x !== col || this.hoveredSquare.y !== row) { if (this.hoveredSquare && this.ncHoverTrailAmount > 0) { this.trailCells.unshift(Object.assign({}, this.hoveredSquare)); if (this.trailCells.length > this.ncHoverTrailAmount) { this.trailCells.length = this.ncHoverTrailAmount; } } this.hoveredSquare = { x: col, y: row }; } } onMouseLeave() { if (this.hoveredSquare && this.ncHoverTrailAmount > 0) { this.trailCells.unshift(Object.assign({}, this.hoveredSquare)); if (this.trailCells.length > this.ncHoverTrailAmount) { this.trailCells.length = this.ncHoverTrailAmount; } } this.hoveredSquare = null; } } ShapeGridBackgroundComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: ShapeGridBackgroundComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); ShapeGridBackgroundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: ShapeGridBackgroundComponent, selector: "nc-shape-grid-background", inputs: { ncDirection: "ncDirection", ncSpeed: "ncSpeed", ncBorderColor: "ncBorderColor", ncSquareSize: "ncSquareSize", ncHoverFillColor: "ncHoverFillColor", ncShape: "ncShape", ncHoverTrailAmount: "ncHoverTrailAmount", ncBgColor: "ncBgColor" }, host: { listeners: { "mousemove": "onMouseMove($event)", "mouseleave": "onMouseLeave()" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, static: true }], ngImport: i0, template: "<canvas #canvas class=\"nc-shape-grid-canvas\" [style.background-color]=\"ncBgColor\"></canvas>\r\n<div class=\"nc-content-wrapper\">\r\n <ng-content></ng-content>\r\n</div>", styles: [":host{display:block;position:relative;width:100%;height:100%;overflow:hidden}.nc-shape-grid-canvas{position:absolute;inset:0;z-index:0;width:100%;height:100%;border:none;display:block;pointer-events:none}.nc-content-wrapper{position:relative;z-index:1;width:100%;height:100%}\n"] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: ShapeGridBackgroundComponent, decorators: [{ type: Component, args: [{ selector: 'nc-shape-grid-background', templateUrl: './shape-grid-background.component.html', styleUrls: ['./shape-grid-background.component.less'] }] }], ctorParameters: function () { return [{ type: i0.NgZone }]; }, propDecorators: { canvasRef: [{ type: ViewChild, args: ['canvas', { static: true }] }], ncDirection: [{ type: Input }], ncSpeed: [{ type: Input }], ncBorderColor: [{ type: Input }], ncSquareSize: [{ type: Input }], ncHoverFillColor: [{ type: Input }], ncShape: [{ type: Input }], ncHoverTrailAmount: [{ type: Input }], ncBgColor: [{ type: Input }], onMouseMove: [{ type: HostListener, args: ['mousemove', ['$event']] }], onMouseLeave: [{ type: HostListener, args: ['mouseleave'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcGUtZ3JpZC1iYWNrZ3JvdW5kLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc2hhcGUtZ3JpZC1iYWNrZ3JvdW5kL3NoYXBlLWdyaWQtYmFja2dyb3VuZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NoYXBlLWdyaWQtYmFja2dyb3VuZC9zaGFwZS1ncmlkLWJhY2tncm91bmQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFJVCxTQUFTLEVBRVQsS0FBSyxFQUNMLFlBQVksRUFFYixNQUFNLGVBQWUsQ0FBQzs7QUFVdkIsTUFBTSxPQUFPLDRCQUE0QjtJQThCdkMsWUFBb0IsTUFBYztRQUFkLFdBQU0sR0FBTixNQUFNLENBQVE7UUEzQmxDLGlEQUFpRDtRQUN4QyxnQkFBVyxHQUFvQixVQUFVLENBQUM7UUFDbkQsb0JBQW9CO1FBQ1gsWUFBTyxHQUFXLEdBQUcsQ0FBQztRQUMvQixhQUFhO1FBQ0osa0JBQWEsR0FBVyxTQUFTLENBQUM7UUFDM0MsbUJBQW1CO1FBQ1YsaUJBQVksR0FBVyxFQUFFLENBQUM7UUFDbkMsZUFBZTtRQUNOLHFCQUFnQixHQUFXLFNBQVMsQ0FBQztRQUM5QyxpREFBaUQ7UUFDeEMsWUFBTyxHQUFnQixRQUFRLENBQUM7UUFDekMscUJBQXFCO1FBQ1osdUJBQWtCLEdBQVcsQ0FBQyxDQUFDO1FBQ3hDLFVBQVU7UUFDRCxjQUFTLEdBQVcsU0FBUyxDQUFDO1FBRS9CLFFBQUcsR0FBb0MsSUFBSSxDQUFDO1FBQzVDLFVBQUssR0FBa0IsSUFBSSxDQUFDO1FBSTVCLGVBQVUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQzVCLGtCQUFhLEdBQW9DLElBQUksQ0FBQztRQUN0RCxlQUFVLEdB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dXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIE9uSW5pdCxcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIE9uRGVzdHJveSxcclxuICBWaWV3Q2hpbGQsXHJcbiAgRWxlbWVudFJlZixcclxuICBJbnB1dCxcclxuICBIb3N0TGlzdGVuZXIsXHJcbiAgTmdab25lXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5leHBvcnQgdHlwZSBOY0RpcmVjdGlvblR5cGUgPSAncmlnaHQnIHwgJ2xlZnQnIHwgJ3VwJyB8ICdkb3duJyB8ICdkaWFnb25hbCc7XHJcbmV4cG9ydCB0eXBlIE5jU2hhcGVUeXBlID0gJ3NxdWFyZScgfCAnaGV4YWdvbicgfCAndHJpYW5nbGUnIHwgJ2NpcmNsZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25jLXNoYXBlLWdyaWQtYmFja2dyb3VuZCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3NoYXBlLWdyaWQtYmFja2dyb3VuZC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vc2hhcGUtZ3JpZC1iYWNrZ3JvdW5kLmNvbXBvbmVudC5sZXNzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIFNoYXBlR3JpZEJhY2tncm91bmRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XHJcbiAgQFZpZXdDaGlsZCgnY2FudmFzJywgeyBzdGF0aWM6IHRydWUgfSkgY2FudmFzUmVmITogRWxlbWVudFJlZjxIVE1MQ2FudmFzRWxlbWVudD47XHJcblxyXG4gIC8qKiDliqjnlLvnp7vliqjmlrnlkJHvvIzlj6/pgInlgLzvvJpyaWdodCwgbGVmdCwgdXAsIGRvd24sIGRpYWdvbmFsICovXHJcbiAgQElucHV0KCkgbmNEaXJlY3Rpb246IE5jRGlyZWN0aW9uVHlwZSA9ICdkaWFnb25hbCc7XHJcbiAgLyoqIOWKqOeUu+enu+WKqOmAn+W6pu+8iDAuMS0y77yJICovXHJcbiAgQElucHV0KCkgbmNTcGVlZDogbnVtYmVyID0gMC41O1xyXG4gIC8qKiDnvZHmoLzovrnmoYbpopzoibIgKi9cclxuICBASW5wdXQoKSBuY0JvcmRlckNvbG9yOiBzdHJpbmcgPSAnIzI3MWUzNyc7XHJcbiAgLyoqIOW9oueKtuWkp+Wwj++8iDEwLTEwMO+8iSAqL1xyXG4gIEBJbnB1dCgpIG5jU3F1YXJlU2l6ZTogbnVtYmVyID0gNDA7XHJcbiAgLyoqIOaCrOWBnOaXtueahOWhq+WFheminOiJsiAqL1xyXG4gIEBJbnB1dCgpIG5jSG92ZXJGaWxsQ29sb3I6IHN0cmluZyA9ICcjMjIyMjIyJztcclxuICAvKiog5b2i54q257G75Z6L77yM5Y+v6YCJ5YC877yac3F1YXJlLCBoZXhhZ29uLCB0cmlhbmdsZSwgY2lyY2xlICovXHJcbiAgQElucHV0KCkgbmNTaGFwZTogTmNTaGFwZVR5cGUgPSAnc3F1YXJlJztcclxuICAvKiog6byg5qCH5oKs5YGc5bC+6L+56ZW/5bqm77yIMC0yMO+8iSAqL1xyXG4gIEBJbnB1dCgpIG5jSG92ZXJUcmFpbEFtb3VudDogbnVtYmVyID0gMDtcclxuICAvKiog6IOM5pmv6ImyICovXHJcbiAgQElucHV0KCkgbmNCZ0NvbG9yOiBzdHJpbmcgPSAnIzAwMDAwMCc7XHJcblxyXG4gIHByaXZhdGUgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQgfCBudWxsID0gbnVsbDtcclxuICBwcml2YXRlIHJhZklkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcclxuICBwcml2YXRlIHJlc2l6ZU9ic2VydmVyITogUmVzaXplT2JzZXJ2ZXI7XHJcblxyXG5cclxuICBwcml2YXRlIGdyaWRPZmZzZXQgPSB7IHg6IDAsIHk6IDAgfTtcclxuICBwcml2YXRlIGhvdmVyZWRTcXVhcmU6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgdHJhaWxDZWxsczogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9W10gPSBbXTtcclxuICBwcml2YXRlIGNlbGxPcGFjaXRpZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG5nWm9uZTogTmdab25lKSB7IH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7IH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5jYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICAgIHRoaXMuY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XHJcblxyXG4gICAgLy8g6ZyA6KaB5Zyoem9uZeWkluaJp+ihjOeahOS7o+eggeeUqHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFy77yM5q+U5aaCQ2FudmFzIOabtOaWsFxyXG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG4gICAgICB0aGlzLnNldHVwUmVzaXplT2JzZXJ2ZXIoY2FudmFzKTtcclxuICAgICAgdGhpcy5yZXNpemVDYW52YXMoKTtcclxuICAgICAgdGhpcy51cGRhdGVBbmltYXRpb24oKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5yYWZJZCAhPT0gbnVsbCkge1xyXG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnJhZklkKTtcclxuICAgICAgdGhpcy5yYWZJZCA9IG51bGw7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5yZXNpemVPYnNlcnZlcikge1xyXG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2V0dXBSZXNpemVPYnNlcnZlcihjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50KTogdm9pZCB7XHJcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcclxuICAgICAgdGhpcy5yZXNpemVDYW52YXMoKTtcclxuICAgIH0pO1xyXG4gICAgdGhpcy5yZXNpemVPYnNlcnZlci5vYnNlcnZlKGNhbnZhcy5wYXJlbnRFbGVtZW50IHx8IGNhbnZhcyk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlc2l6ZUNhbnZhcygpOiB2b2lkIHtcclxuICAgIGNvbnN0IGNhbnZhcyA9IHRoaXMuY2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBjb25zdCBwYXJlbnQgPSBjYW52YXMucGFyZW50RWxlbWVudDtcclxuICAgIGlmIChwYXJlbnQpIHtcclxuICAgICAgY2FudmFzLndpZHRoID0gcGFyZW50Lm9mZnNldFdpZHRoO1xyXG4gICAgICBjYW52YXMuaGVpZ2h0ID0gcGFyZW50Lm9mZnNldEhlaWdodDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd0hleChjeDogbnVtYmVyLCBjeTogbnVtYmVyLCBzaXplOiBudW1iZXIpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5jdHgpIHJldHVybjtcclxuICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpKyspIHtcclxuICAgICAgY29uc3QgYW5nbGUgPSAoTWF0aC5QSSAvIDMpICogaTtcclxuICAgICAgY29uc3QgdnggPSBjeCArIHNpemUgKiBNYXRoLmNvcyhhbmdsZSk7XHJcbiAgICAgIGNvbnN0IHZ5ID0gY3kgKyBzaXplICogTWF0aC5zaW4oYW5nbGUpO1xyXG4gICAgICBpZiAoaSA9PT0gMCkgdGhpcy5jdHgubW92ZVRvKHZ4LCB2eSk7XHJcbiAgICAgIGVsc2UgdGhpcy5jdHgubGluZVRvKHZ4LCB2eSk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmN0eC5jbG9zZVBhdGgoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd0NpcmNsZShjeDogbnVtYmVyLCBjeTogbnVtYmVyLCBzaXplOiBudW1iZXIpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5jdHgpIHJldHVybjtcclxuICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgdGhpcy5jdHguYXJjKGN4LCBjeSwgc2l6ZSAvIDIsIDAsIE1hdGguUEkgKiAyKTtcclxuICAgIHRoaXMuY3R4LmNsb3NlUGF0aCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkcmF3VHJpYW5nbGUoY3g6IG51bWJlciwgY3k6IG51bWJlciwgc2l6ZTogbnVtYmVyLCBmbGlwOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuY3R4KSByZXR1cm47XHJcbiAgICB0aGlzLmN0eC5iZWdpblBhdGgoKTtcclxuICAgIGlmIChmbGlwKSB7XHJcbiAgICAgIHRoaXMuY3R4Lm1vdmVUbyhjeCwgY3kgKyBzaXplIC8gMik7XHJcbiAgICAgIHRoaXMuY3R4LmxpbmVUbyhjeCArIHNpemUgLyAyLCBjeSAtIHNpemUgLyAyKTtcclxuICAgICAgdGhpcy5jdHgubGluZVRvKGN4IC0gc2l6ZSAvIDIsIGN5IC0gc2l6ZSAvIDIpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5jdHgubW92ZVRvKGN4LCBjeSAtIHNpemUgLyAyKTtcclxuICAgICAgdGhpcy5jdHgubGluZVRvKGN4ICsgc2l6ZSAvIDIsIGN5ICsgc2l6ZSAvIDIpO1xyXG4gICAgICB0aGlzLmN0eC5saW5lVG8oY3ggLSBzaXplIC8gMiwgY3kgKyBzaXplIC8gMik7XHJcbiAgICB9XHJcbiAgICB0aGlzLmN0eC5jbG9zZVBhdGgoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd0dyaWQoKTogdm9pZCB7XHJcbiAgICBjb25zdCBjYW52YXMgPSB0aGlzLmNhbnZhc1JlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XHJcbiAgICBpZiAoIWN0eCkgcmV0dXJuO1xyXG5cclxuICAgIGN0eC5jbGVhclJlY3QoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcclxuXHJcbiAgICBjb25zdCBpc0hleCA9IHRoaXMubmNTaGFwZSA9PT0gJ2hleGFnb24nO1xyXG4gICAgY29uc3QgaXNUcmkgPSB0aGlzLm5jU2hhcGUgPT09ICd0cmlhbmdsZSc7XHJcbiAgICBjb25zdCBoZXhIb3JpeiA9IHRoaXMubmNTcXVhcmVTaXplICogMS41O1xyXG4gICAgY29uc3QgaGV4VmVydCA9IHRoaXMubmNTcXVhcmVTaXplICogTWF0aC5zcXJ0KDMpO1xyXG5cclxuICAgIGlmIChpc0hleCkge1xyXG4gICAgICBjb25zdCBjb2xTaGlmdCA9IE1hdGguZmxvb3IodGhpcy5ncmlkT2Zmc2V0LnggLyBoZXhIb3Jpeik7XHJcbiAgICAgIGNvbnN0IG9mZnNldFggPSAoKHRoaXMuZ3JpZE9mZnNldC54ICUgaGV4SG9yaXopICsgaGV4SG9yaXopICUgaGV4SG9yaXo7XHJcbiAgICAgIGNvbnN0IG9mZnNldFkgPSAoKHRoaXMuZ3JpZE9mZnNldC55ICUgaGV4VmVydCkgKyBoZXhWZXJ0KSAlIGhleFZlcnQ7XHJcblxyXG4gICAgICBjb25zdCBjb2xzID0gTWF0aC5jZWlsKGNhbnZhcy53aWR0aCAvIGhleEhvcml6KSArIDM7XHJcbiAgICAgIGNvbnN0IHJvd3MgPSBNYXRoLmNlaWwoY2FudmFzLmhlaWdodCAvIGhleFZlcnQpICsgMztcclxuXHJcbiAgICAgIGZvciAobGV0IGNvbCA9IC0yOyBjb2wgPCBjb2xzOyBjb2wrKykge1xyXG4gICAgICAgIGZvciAobGV0IHJvdyA9IC0yOyByb3cgPCByb3dzOyByb3crKykge1xyXG4gICAgICAgICAgY29uc3QgY3ggPSBjb2wgKiBoZXhIb3JpeiArIG9mZnNldFg7XHJcbiAgICAgICAgICBjb25zdCBjeSA9IHJvdyAqIGhleFZlcnQgKyAoKGNvbCArIGNvbFNoaWZ0KSAlIDIgIT09IDAgPyBoZXhWZXJ0IC8gMiA6IDApICsgb2Zmc2V0WTtcclxuXHJcbiAgICAgICAgICBjb25zdCBjZWxsS2V5ID0gYCR7Y29sfSwke3Jvd31gO1xyXG4gICAgICAgICAgY29uc3QgYWxwaGEgPSB0aGlzLmNlbGxPcGFjaXRpZXMuZ2V0KGNlbGxLZXkpO1xyXG4gICAgICAgICAgaWYgKGFscGhhKSB7XHJcbiAgICAgICAgICAgIGN0eC5nbG9iYWxBbHBoYSA9IGFscGhhO1xyXG4gICAgICAgICAgICB0aGlzLmRyYXdIZXgoY3gsIGN5LCB0aGlzLm5jU3F1YXJlU2l6ZSk7XHJcbiAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSB0aGlzLm5jSG92ZXJGaWxsQ29sb3I7XHJcbiAgICAgICAgICAgIGN0eC5maWxsKCk7XHJcbiAgICAgICAgICAgIGN0eC5nbG9iYWxBbHBoYSA9IDE7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgdGhpcy5kcmF3SGV4KGN4LCBjeSwgdGhpcy5uY1NxdWFyZVNpemUpO1xyXG4gICAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gdGhpcy5uY0JvcmRlckNvbG9yO1xyXG4gICAgICAgICAgY3R4LnN0cm9rZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmIChpc1RyaSkge1xyXG4gICAgICBjb25zdCBoYWxmVyA9IHRoaXMubmNTcXVhcmVTaXplIC8gMjtcclxuICAgICAgY29uc3QgY29sU2hpZnQgPSBNYXRoLmZsb29yKHRoaXMuZ3JpZE9mZnNldC54IC8gaGFsZlcpO1xyXG4gICAgICBjb25zdCByb3dTaGlmdCA9IE1hdGguZmxvb3IodGhpcy5ncmlkT2Zmc2V0LnkgLyB0aGlzLm5jU3F1YXJlU2l6ZSk7XHJcbiAgICAgIGNvbnN0IG9mZnNldFggPSAoKHRoaXMuZ3JpZE9mZnNldC54ICUgaGFsZlcpICsgaGFsZlcpICUgaGFsZlc7XHJcbiAgICAgIGNvbnN0IG9mZnNldFkgPSAoKHRoaXMuZ3JpZE9mZnNldC55ICUgdGhpcy5uY1NxdWFyZVNpemUpICsgdGhpcy5uY1NxdWFyZVNpemUpICUgdGhpcy5uY1NxdWFyZVNpemU7XHJcblxyXG4gICAgICBjb25zdCBjb2xzID0gTWF0aC5jZWlsKGNhbnZhcy53aWR0aCAvIGhhbGZXKSArIDQ7XHJcbiAgICAgIGNvbnN0IHJvd3MgPSBNYXRoLmNlaWwoY2FudmFzLmhlaWdodCAvIHRoaXMubmNTcXVhcmVTaXplKSArIDQ7XHJcblxyXG4gICAgICBmb3IgKGxldCBjb2wgPSAtMjsgY29sIDwgY29sczsgY29sKyspIHtcclxuICAgICAgICBmb3IgKGxldCByb3cgPSAtMjsgcm93IDwgcm93czsgcm93KyspIHtcclxuICAgICAgICAgIGNvbnN0IGN4ID0gY29sICogaGFsZlcgKyBvZmZ