UNPKG

ng-cw-v12

Version:

Angular UI Component Library

248 lines (236 loc) 32 kB
import { Component, ViewChild, Input } from '@angular/core'; import * as i0 from "@angular/core"; export class LightningBackgroundComponent { constructor(ngZone) { this.ngZone = ngZone; /** 闪电的色调(度数,0到360) */ this.ncHue = 230; /** 闪电水平偏移量(-2~2) */ this.ncXOffset = 0; /** 闪电动画速度倍率(0.5-2) */ this.ncSpeed = 1; /** 闪电强度(0.1-2) */ this.ncIntensity = 1; /** 闪电密集程度(0.1-3) */ this.ncSize = 1; this.gl = null; this.program = null; this.rafId = null; this.startTime = 0; // WebGL Uniform locations this.locResolution = null; this.locTime = null; this.locHue = null; this.locXOffset = null; this.locSpeed = null; this.locIntensity = null; this.locSize = null; this.vertexShaderSource = ` attribute vec2 aPosition; void main() { gl_Position = vec4(aPosition, 0.0, 1.0); } `; this.fragmentShaderSource = ` precision mediump float; uniform vec2 iResolution; uniform float iTime; uniform float uHue; uniform float uXOffset; uniform float uSpeed; uniform float uIntensity; uniform float uSize; #define OCTAVE_COUNT 10 vec3 hsv2rgb(vec3 c) { vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0); return c.z * mix(vec3(1.0), rgb, c.y); } float hash11(float p) { p = fract(p * .1031); p *= p + 33.33; p *= p + p; return fract(p); } float hash12(vec2 p) { vec3 p3 = fract(vec3(p.xyx) * .1031); p3 += dot(p3, p3.yzx + 33.33); return fract((p3.x + p3.y) * p3.z); } mat2 rotate2d(float theta) { float c = cos(theta); float s = sin(theta); return mat2(c, -s, s, c); } float noise(vec2 p) { vec2 ip = floor(p); vec2 fp = fract(p); float a = hash12(ip); float b = hash12(ip + vec2(1.0, 0.0)); float c = hash12(ip + vec2(0.0, 1.0)); float d = hash12(ip + vec2(1.0, 1.0)); vec2 t = smoothstep(0.0, 1.0, fp); return mix(mix(a, b, t.x), mix(c, d, t.x), t.y); } float fbm(vec2 p) { float value = 0.0; float amplitude = 0.5; for (int i = 0; i < OCTAVE_COUNT; ++i) { value += amplitude * noise(p); p *= rotate2d(0.45); p *= 2.0; amplitude *= 0.5; } return value; } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; uv = 2.0 * uv - 1.0; uv.x *= iResolution.x / iResolution.y; uv.x += uXOffset; uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0; float dist = abs(uv.x); vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8)); vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity; col = pow(col, vec3(1.0)); fragColor = vec4(col, 1.0); } void main() { mainImage(gl_FragColor, gl_FragCoord.xy); } `; this.render = () => { if (!this.gl || !this.program) return; this.gl.viewport(0, 0, this.canvas.width, this.canvas.height); this.gl.uniform2f(this.locResolution, this.canvas.width, this.canvas.height); const currentTime = performance.now(); this.gl.uniform1f(this.locTime, (currentTime - this.startTime) / 1000.0); this.gl.uniform1f(this.locHue, this.ncHue); this.gl.uniform1f(this.locXOffset, this.ncXOffset); this.gl.uniform1f(this.locSpeed, this.ncSpeed); this.gl.uniform1f(this.locIntensity, this.ncIntensity); this.gl.uniform1f(this.locSize, this.ncSize); this.gl.drawArrays(this.gl.TRIANGLES, 0, 6); this.rafId = requestAnimationFrame(this.render); }; } ngOnInit() { } ngAfterViewInit() { this.initWebGL(); } ngOnChanges(changes) { // WebGL loops read parameters dynamically, no need for extra updates unless structural or texture-based changing. } ngOnDestroy() { if (this.rafId !== null) { cancelAnimationFrame(this.rafId); } if (this.resizeObserver) { this.resizeObserver.disconnect(); } if (this.gl && this.program) { this.gl.deleteProgram(this.program); } } initWebGL() { const container = this.containerRef.nativeElement; this.canvas = document.createElement('canvas'); this.canvas.style.width = '100%'; this.canvas.style.height = '100%'; this.canvas.style.display = 'block'; container.appendChild(this.canvas); this.gl = this.canvas.getContext('webgl'); if (!this.gl) { console.error('WebGL not supported'); return; } const vertexShader = this.compileShader(this.vertexShaderSource, this.gl.VERTEX_SHADER); const fragmentShader = this.compileShader(this.fragmentShaderSource, this.gl.FRAGMENT_SHADER); if (!vertexShader || !fragmentShader) return; this.program = this.gl.createProgram(); if (!this.program) return; this.gl.attachShader(this.program, vertexShader); this.gl.attachShader(this.program, fragmentShader); this.gl.linkProgram(this.program); if (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) { console.error('Program linking error:', this.gl.getProgramInfoLog(this.program)); return; } this.gl.useProgram(this.program); const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]); const vertexBuffer = this.gl.createBuffer(); this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer); this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW); const aPosition = this.gl.getAttribLocation(this.program, 'aPosition'); this.gl.enableVertexAttribArray(aPosition); this.gl.vertexAttribPointer(aPosition, 2, this.gl.FLOAT, false, 0, 0); this.locResolution = this.gl.getUniformLocation(this.program, 'iResolution'); this.locTime = this.gl.getUniformLocation(this.program, 'iTime'); this.locHue = this.gl.getUniformLocation(this.program, 'uHue'); this.locXOffset = this.gl.getUniformLocation(this.program, 'uXOffset'); this.locSpeed = this.gl.getUniformLocation(this.program, 'uSpeed'); this.locIntensity = this.gl.getUniformLocation(this.program, 'uIntensity'); this.locSize = this.gl.getUniformLocation(this.program, 'uSize'); this.startTime = performance.now(); this.resizeObserver = new ResizeObserver(() => { this.resizeCanvas(); }); this.resizeObserver.observe(container); this.resizeCanvas(); this.ngZone.runOutsideAngular(() => { this.render(); }); } compileShader(source, type) { if (!this.gl) return null; const shader = this.gl.createShader(type); if (!shader) return null; this.gl.shaderSource(shader, source); this.gl.compileShader(shader); if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) { console.error('Shader compile error:', this.gl.getShaderInfoLog(shader)); this.gl.deleteShader(shader); return null; } return shader; } resizeCanvas() { if (!this.canvas) return; const width = this.canvas.clientWidth; const height = this.canvas.clientHeight; if (this.canvas.width !== width || this.canvas.height !== height) { this.canvas.width = width; this.canvas.height = height; } } } LightningBackgroundComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: LightningBackgroundComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); LightningBackgroundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: LightningBackgroundComponent, selector: "nc-lightning-background", inputs: { ncHue: "ncHue", ncXOffset: "ncXOffset", ncSpeed: "ncSpeed", ncIntensity: "ncIntensity", ncSize: "ncSize" }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #container class=\"nc-lightning-canvas-container\"></div>\r\n<div class=\"nc-content-wrapper\">\r\n <ng-content></ng-content>\r\n</div>\r\n", styles: [":host{display:block;position:relative;width:100%;height:100%;overflow:hidden}.nc-lightning-canvas-container{position:absolute;inset:0;z-index:0}.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: LightningBackgroundComponent, decorators: [{ type: Component, args: [{ selector: 'nc-lightning-background', templateUrl: './lightning-background.component.html', styleUrls: ['./lightning-background.component.less'] }] }], ctorParameters: function () { return [{ type: i0.NgZone }]; }, propDecorators: { containerRef: [{ type: ViewChild, args: ['container', { static: true }] }], ncHue: [{ type: Input }], ncXOffset: [{ type: Input }], ncSpeed: [{ type: Input }], ncIntensity: [{ type: Input }], ncSize: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRuaW5nLWJhY2tncm91bmQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9saWdodG5pbmctYmFja2dyb3VuZC9saWdodG5pbmctYmFja2dyb3VuZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL2xpZ2h0bmluZy1iYWNrZ3JvdW5kL2xpZ2h0bmluZy1iYWNrZ3JvdW5kLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBSVQsU0FBUyxFQUVULEtBQUssRUFJTixNQUFNLGVBQWUsQ0FBQzs7QUFPdkIsTUFBTSxPQUFPLDRCQUE0QjtJQXFIdkMsWUFBb0IsTUFBYztRQUFkLFdBQU0sR0FBTixNQUFNLENBQVE7UUFsSGxDLHNCQUFzQjtRQUNiLFVBQUssR0FBVyxHQUFHLENBQUM7UUFDN0Isb0JBQW9CO1FBQ1gsY0FBUyxHQUFXLENBQUMsQ0FBQztRQUMvQixzQkFBc0I7UUFDYixZQUFPLEdBQVcsQ0FBQyxDQUFDO1FBQzdCLGtCQUFrQjtRQUNULGdCQUFXLEdBQVcsQ0FBQyxDQUFDO1FBQ2pDLG9CQUFvQjtRQUNYLFdBQU0sR0FBVyxDQUFDLENBQUM7UUFHcEIsT0FBRSxHQUFpQyxJQUFJLENBQUM7UUFDeEMsWUFBTyxHQUF3QixJQUFJLENBQUM7UUFDcEMsVUFBSyxHQUFrQixJQUFJLENBQUM7UUFFNUIsY0FBUyxHQUFXLENBQUMsQ0FBQztRQUU5QiwwQkFBMEI7UUFDbEIsa0JBQWEsR0FBZ0MsSUFBSSxDQUFDO1FBQ2xELFlBQU8sR0FBZ0MsSUFBSSxDQUFDO1FBQzVDLFdBQU0sR0FBZ0MsSUFBSSxDQUFDO1FBQzNDLGVBQVUsR0FBZ0MsSUFBSSxDQUFDO1FBQy9DLGFBQVEsR0FBZ0MsSUFBSSxDQUFDO1FBQzdDLGlCQUFZLEdBQWdDLElBQUksQ0FBQztRQUNqRCxZQUFPLEdBQWdDLElBQUksQ0FBQztRQUU1Qyx1QkFBa0IsR0FBRzs7Ozs7R0FLNUIsQ0FBQztRQUVNLHlCQUFvQixHQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4RTlCLENBQUM7UUFtSE0sV0FBTSxHQUFHLEdBQVMsRUFBRTtZQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO2dCQUFFLE9BQU87WUFFdEMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlELElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUU3RSxNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUM7WUFDekUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDM0MsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbkQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDL0MsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDdkQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFN0MsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBRTVDLElBQUksQ0FBQyxLQUFLLEdBQUcscUJBQXFCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2xELENBQUMsQ0FBQztJQWxJb0MsQ0FBQztJQUV2QyxRQUFRO0lBQ1IsQ0FBQztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUFzQjtRQUNoQyxrSEFBa0g7SUFDcEgsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssSUFBSSxFQUFFO1lBQ3ZCLG9CQUFvQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNsQztRQUNELElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUN2QixJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsRUFBRSxDQUFDO1NBQ2xDO1FBQ0QsSUFBSSxJQUFJLENBQUMsRUFBRSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDM0IsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3JDO0lBQ0gsQ0FBQztJQUVPLFNBQVM7UUFDZixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQztRQUVsRCxJQUFJLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQztRQUNqQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDcEMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFbkMsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRTtZQUNaLE9BQU8sQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUNyQyxPQUFPO1NBQ1I7UUFFRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3hGLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFOUYsSUFBSSxDQUFDLFlBQVksSUFBSSxDQUFDLGNBQWM7WUFBRSxPQUFPO1FBRTdDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBRTFCLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxjQUFjLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFbEMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQ25FLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0JBQXdCLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNqRixPQUFPO1NBQ1I7UUFFRCxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFakMsTUFBTSxRQUFRLEdBQUcsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUUsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM1QyxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUV4RSxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUV0RSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQztRQUM3RSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNqRSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUN2RSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUVqRSxJQUFJLENBQUMsU0FBUyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUVuQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksY0FBYyxDQUFDLEdBQUcsRUFBRTtZQUM1QyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFcEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUU7WUFDakMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLGFBQWEsQ0FBQyxNQUFjLEVBQUUsSUFBWTtRQUNoRCxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFBRSxPQUFPLElBQUksQ0FBQztRQUMxQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsRUFBRTtZQUMvRCxPQUFPLENBQUMsS0FBSyxDQUFDLHVCQUF1QixFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUN6RSxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM3QixPQUFPLElBQUksQ0FBQztTQUNiO1FBQ0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVPLFlBQVk7UUFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUN6QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQztRQUN0QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQztRQUN4QyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxNQUFNLEVBQUU7WUFDaEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1lBQzFCLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztTQUM3QjtJQUNILENBQUM7O3lIQXBPVSw0QkFBNEI7NkdBQTVCLDRCQUE0QixtVUNsQnpDLHFKQUlBOzJGRGNhLDRCQUE0QjtrQkFMeEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUseUJBQXlCO29CQUNuQyxXQUFXLEVBQUUsdUNBQXVDO29CQUNwRCxTQUFTLEVBQUUsQ0FBQyx1Q0FBdUMsQ0FBQztpQkFDckQ7NkZBRTJDLFlBQVk7c0JBQXJELFNBQVM7dUJBQUMsV0FBVyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFHL0IsS0FBSztzQkFBYixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUcsT0FBTztzQkFBZixLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgT25Jbml0LFxyXG4gIE9uRGVzdHJveSxcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIFZpZXdDaGlsZCxcclxuICBFbGVtZW50UmVmLFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIE5nWm9uZVxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICduYy1saWdodG5pbmctYmFja2dyb3VuZCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2xpZ2h0bmluZy1iYWNrZ3JvdW5kLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9saWdodG5pbmctYmFja2dyb3VuZC5jb21wb25lbnQubGVzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBMaWdodG5pbmdCYWNrZ3JvdW5kQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcyB7XHJcbiAgQFZpZXdDaGlsZCgnY29udGFpbmVyJywgeyBzdGF0aWM6IHRydWUgfSkgY29udGFpbmVyUmVmITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XHJcblxyXG4gIC8qKiDpl6rnlLXnmoToibLosIPvvIjluqbmlbDvvIww5YiwMzYw77yJICovXHJcbiAgQElucHV0KCkgbmNIdWU6IG51bWJlciA9IDIzMDtcclxuICAvKiog6Zeq55S15rC05bmz5YGP56e76YeP77yILTJ+Mu+8iSAqL1xyXG4gIEBJbnB1dCgpIG5jWE9mZnNldDogbnVtYmVyID0gMDtcclxuICAvKiog6Zeq55S15Yqo55S76YCf5bqm5YCN546H77yIMC41LTLvvIkgKi9cclxuICBASW5wdXQoKSBuY1NwZWVkOiBudW1iZXIgPSAxO1xyXG4gIC8qKiDpl6rnlLXlvLrluqbvvIgwLjEtMu+8iSAqL1xyXG4gIEBJbnB1dCgpIG5jSW50ZW5zaXR5OiBudW1iZXIgPSAxO1xyXG4gIC8qKiDpl6rnlLXlr4bpm4bnqIvluqbvvIgwLjEtM++8iSAqL1xyXG4gIEBJbnB1dCgpIG5jU2l6ZTogbnVtYmVyID0gMTtcclxuXHJcbiAgcHJpdmF0ZSBjYW52YXMhOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuICBwcml2YXRlIGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQgfCBudWxsID0gbnVsbDtcclxuICBwcml2YXRlIHByb2dyYW06IFdlYkdMUHJvZ3JhbSB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgcmFmSWQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgcmVzaXplT2JzZXJ2ZXIhOiBSZXNpemVPYnNlcnZlcjtcclxuICBwcml2YXRlIHN0YXJ0VGltZTogbnVtYmVyID0gMDtcclxuXHJcbiAgLy8gV2ViR0wgVW5pZm9ybSBsb2NhdGlvbnNcclxuICBwcml2YXRlIGxvY1Jlc29sdXRpb246IFdlYkdMVW5pZm9ybUxvY2F0aW9uIHwgbnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSBsb2NUaW1lOiBXZWJHTFVuaWZvcm1Mb2NhdGlvbiB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgbG9jSHVlOiBXZWJHTFVuaWZvcm1Mb2NhdGlvbiB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgbG9jWE9mZnNldDogV2ViR0xVbmlmb3JtTG9jYXRpb24gfCBudWxsID0gbnVsbDtcclxuICBwcml2YXRlIGxvY1NwZWVkOiBXZWJHTFVuaWZvcm1Mb2NhdGlvbiB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgbG9jSW50ZW5zaXR5OiBXZWJHTFVuaWZvcm1Mb2NhdGlvbiB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgbG9jU2l6ZTogV2ViR0xVbmlmb3JtTG9jYXRpb24gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgcHJpdmF0ZSB2ZXJ0ZXhTaGFkZXJTb3VyY2UgPSBgXHJcbiAgICBhdHRyaWJ1dGUgdmVjMiBhUG9zaXRpb247XHJcbiAgICB2b2lkIG1haW4oKSB7XHJcbiAgICAgIGdsX1Bvc2l0aW9uID0gdmVjNChhUG9zaXRpb24sIDAuMCwgMS4wKTtcclxuICAgIH1cclxuICBgO1xyXG5cclxuICBwcml2YXRlIGZyYWdtZW50U2hhZGVyU291cmNlID0gYFxyXG4gICAgcHJlY2lzaW9uIG1lZGl1bXAgZmxvYXQ7XHJcbiAgICB1bmlmb3JtIHZlYzIgaVJlc29sdXRpb247XHJcbiAgICB1bmlmb3JtIGZsb2F0IGlUaW1lO1xyXG4gICAgdW5pZm9ybSBmbG9hdCB1SHVlO1xyXG4gICAgdW5pZm9ybSBmbG9hdCB1WE9mZnNldDtcclxuICAgIHVuaWZvcm0gZmxvYXQgdVNwZWVkO1xyXG4gICAgdW5pZm9ybSBmbG9hdCB1SW50ZW5zaXR5O1xyXG4gICAgdW5pZm9ybSBmbG9hdCB1U2l6ZTtcclxuICAgIFxyXG4gICAgI2RlZmluZSBPQ1RBVkVfQ09VTlQgMTBcclxuXHJcbiAgICB2ZWMzIGhzdjJyZ2IodmVjMyBjKSB7XHJcbiAgICAgICAgdmVjMyByZ2IgPSBjbGFtcChhYnMobW9kKGMueCAqIDYuMCArIHZlYzMoMC4wLDQuMCwyLjApLCA2LjApIC0gMy4wKSAtIDEuMCwgMC4wLCAxLjApO1xyXG4gICAgICAgIHJldHVybiBjLnogKiBtaXgodmVjMygxLjApLCByZ2IsIGMueSk7XHJcbiAgICB9XHJcblxyXG4gICAgZmxvYXQgaGFzaDExKGZsb2F0IHApIHtcclxuICAgICAgICBwID0gZnJhY3QocCAqIC4xMDMxKTtcclxuICAgICAgICBwICo9IHAgKyAzMy4zMztcclxuICAgICAgICBwICo9IHAgKyBwO1xyXG4gICAgICAgIHJldHVybiBmcmFjdChwKTtcclxuICAgIH1cclxuXHJcbiAgICBmbG9hdCBoYXNoMTIodmVjMiBwKSB7XHJcbiAgICAgICAgdmVjMyBwMyA9IGZyYWN0KHZlYzMocC54eXgpICogLjEwMzEpO1xyXG4gICAgICAgIHAzICs9IGRvdChwMywgcDMueXp4ICsgMzMuMzMpO1xyXG4gICAgICAgIHJldHVybiBmcmFjdCgocDMueCArIHAzLnkpICogcDMueik7XHJcbiAgICB9XHJcblxyXG4gICAgbWF0MiByb3RhdGUyZChmbG9hdCB0aGV0YSkge1xyXG4gICAgICAgIGZsb2F0IGMgPSBjb3ModGhldGEpO1xyXG4gICAgICAgIGZsb2F0IHMgPSBzaW4odGhldGEpO1xyXG4gICAgICAgIHJldHVybiBtYXQyKGMsIC1zLCBzLCBjKTtcclxuICAgIH1cclxuXHJcbiAgICBmbG9hdCBub2lzZSh2ZWMyIHApIHtcclxuICAgICAgICB2ZWMyIGlwID0gZmxvb3IocCk7XHJcbiAgICAgICAgdmVjMiBmcCA9IGZyYWN0KHApO1xyXG4gICAgICAgIGZsb2F0IGEgPSBoYXNoMTIoaXApO1xyXG4gICAgICAgIGZsb2F0IGIgPSBoYXNoMTIoaXAgKyB2ZWMyKDEuMCwgMC4wKSk7XHJcbiAgICAgICAgZmxvYXQgYyA9IGhhc2gxMihpcCArIHZlYzIoMC4wLCAxLjApKTtcclxuICAgICAgICBmbG9hdCBkID0gaGFzaDEyKGlwICsgdmVjMigxLjAsIDEuMCkpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHZlYzIgdCA9IHNtb290aHN0ZXAoMC4wLCAxLjAsIGZwKTtcclxuICAgICAgICByZXR1cm4gbWl4KG1peChhLCBiLCB0LngpLCBtaXgoYywgZCwgdC54KSwgdC55KTtcclxuICAgIH1cclxuXHJcbiAgICBmbG9hdCBmYm0odmVjMiBwKSB7XHJcbiAgICAgICAgZmxvYXQgdmFsdWUgPSAwLjA7XHJcbiAgICAgICAgZmxvYXQgYW1wbGl0dWRlID0gMC41O1xyXG4gICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgT0NUQVZFX0NPVU5UOyArK2kpIHtcclxuICAgICAgICAgICAgdmFsdWUgKz0gYW1wbGl0dWRlICogbm9pc2UocCk7XHJcbiAgICAgICAgICAgIHAgKj0gcm90YXRlMmQoMC40NSk7XHJcbiAgICAgICAgICAgIHAgKj0gMi4wO1xyXG4gICAgICAgICAgICBhbXBsaXR1ZGUgKj0gMC41O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgdm9pZCBtYWluSW1hZ2UoIG91dCB2ZWM0IGZyYWdDb2xvciwgaW4gdmVjMiBmcmFnQ29vcmQgKSB7XHJcbiAgICAgICAgdmVjMiB1diA9IGZyYWdDb29yZCAvIGlSZXNvbHV0aW9uLnh5O1xyXG4gICAgICAgIHV2ID0gMi4wICogdXYgLSAxLjA7XHJcbiAgICAgICAgdXYueCAqPSBpUmVzb2x1dGlvbi54IC8gaVJlc29sdXRpb24ueTtcclxuICAgICAgICB1di54ICs9IHVYT2Zmc2V0O1xyXG4gICAgICAgIFxyXG4gICAgICAgIHV2ICs9IDIuMCAqIGZibSh1diAqIHVTaXplICsgMC44ICogaVRpbWUgKiB1U3BlZWQpIC0gMS4wO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGZsb2F0IGRpc3QgPSBhYnModXYueCk7XHJcbiAgICAgICAgdmVjMyBiYXNlQ29sb3IgPSBoc3YycmdiKHZlYzModUh1ZSAvIDM2MC4wLCAwLjcsIDAuOCkpO1xyXG4gICAgICAgIHZlYzMgY29sID0gYmFzZUNvbG9yICogcG93KG1peCgwLjAsIDAuMDcsIGhhc2gxMShpVGltZSAqIHVTcGVlZCkpIC8gZGlzdCwgMS4wKSAqIHVJbnRlbnNpdHk7XHJcbiAgICAgICAgY29sID0gcG93KGNvbCwgdmVjMygxLjApKTtcclxuICAgICAgICBmcmFnQ29sb3IgPSB2ZWM0KGNvbCwgMS4wKTtcclxuICAgIH1cclxuXHJcbiAgICB2b2lkIG1haW4oKSB7XHJcbiAgICAgICAgbWFpbkltYWdlKGdsX0ZyYWdDb2xvciwgZ2xfRnJhZ0Nvb3JkLnh5KTtcclxuICAgIH1cclxuICBgO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG5nWm9uZTogTmdab25lKSB7IH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmluaXRXZWJHTCgpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgLy8gV2ViR0wgbG9vcHMgcmVhZCBwYXJhbWV0ZXJzIGR5bmFtaWNhbGx5LCBubyBuZWVkIGZvciBleHRyYSB1cGRhdGVzIHVubGVzcyBzdHJ1Y3R1cmFsIG9yIHRleHR1cmUtYmFzZWQgY2hhbmdpbmcuXHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnJhZklkICE9PSBudWxsKSB7XHJcbiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMucmFmSWQpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMucmVzaXplT2JzZXJ2ZXIpIHtcclxuICAgICAgdGhpcy5yZXNpemVPYnNlcnZlci5kaXNjb25uZWN0KCk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5nbCAmJiB0aGlzLnByb2dyYW0pIHtcclxuICAgICAgdGhpcy5nbC5kZWxldGVQcm9ncmFtKHRoaXMucHJvZ3JhbSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluaXRXZWJHTCgpOiB2b2lkIHtcclxuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyUmVmLm5hdGl2ZUVsZW1lbnQ7XHJcblxyXG4gICAgdGhpcy5jYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcclxuICAgIHRoaXMuY2FudmFzLnN0eWxlLndpZHRoID0gJzEwMCUnO1xyXG4gICAgdGhpcy5jYW52YXMuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xyXG4gICAgdGhpcy5jYW52YXMuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5jYW52YXMpO1xyXG5cclxuICAgIHRoaXMuZ2wgPSB0aGlzLmNhbnZhcy5nZXRDb250ZXh0KCd3ZWJnbCcpO1xyXG4gICAgaWYgKCF0aGlzLmdsKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1dlYkdMIG5vdCBzdXBwb3J0ZWQnKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHZlcnRleFNoYWRlciA9IHRoaXMuY29tcGlsZVNoYWRlcih0aGlzLnZlcnRleFNoYWRlclNvdXJjZSwgdGhpcy5nbC5WRVJURVhfU0hBREVSKTtcclxuICAgIGNvbnN0IGZyYWdtZW50U2hhZGVyID0gdGhpcy5jb21waWxlU2hhZGVyKHRoaXMuZnJhZ21lbnRTaGFkZXJTb3VyY2UsIHRoaXMuZ2wuRlJBR01FTlRfU0hBREVSKTtcclxuXHJcbiAgICBpZiAoIXZlcnRleFNoYWRlciB8fCAhZnJhZ21lbnRTaGFkZXIpIHJldHVybjtcclxuXHJcbiAgICB0aGlzLnByb2dyYW0gPSB0aGlzLmdsLmNyZWF0ZVByb2dyYW0oKTtcclxuICAgIGlmICghdGhpcy5wcm9ncmFtKSByZXR1cm47XHJcblxyXG4gICAgdGhpcy5nbC5hdHRhY2hTaGFkZXIodGhpcy5wcm9ncmFtLCB2ZXJ0ZXhTaGFkZXIpO1xyXG4gICAgdGhpcy5nbC5hdHRhY2hTaGFkZXIodGhpcy5wcm9ncmFtLCBmcmFnbWVudFNoYWRlcik7XHJcbiAgICB0aGlzLmdsLmxpbmtQcm9ncmFtKHRoaXMucHJvZ3JhbSk7XHJcblxyXG4gICAgaWYgKCF0aGlzLmdsLmdldFByb2dyYW1QYXJhbWV0ZXIodGhpcy5wcm9ncmFtLCB0aGlzLmdsLkxJTktfU1RBVFVTKSkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdQcm9ncmFtIGxpbmtpbmcgZXJyb3I6JywgdGhpcy5nbC5nZXRQcm9ncmFtSW5mb0xvZyh0aGlzLnByb2dyYW0pKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuZ2wudXNlUHJvZ3JhbSh0aGlzLnByb2dyYW0pO1xyXG5cclxuICAgIGNvbnN0IHZlcnRpY2VzID0gbmV3IEZsb2F0MzJBcnJheShbLTEsIC0xLCAxLCAtMSwgLTEsIDEsIC0xLCAxLCAxLCAtMSwgMSwgMV0pO1xyXG4gICAgY29uc3QgdmVydGV4QnVmZmVyID0gdGhpcy5nbC5jcmVhdGVCdWZmZXIoKTtcclxuICAgIHRoaXMuZ2wuYmluZEJ1ZmZlcih0aGlzLmdsLkFSUkFZX0JVRkZFUiwgdmVydGV4QnVmZmVyKTtcclxuICAgIHRoaXMuZ2wuYnVmZmVyRGF0YSh0aGlzLmdsLkFSUkFZX0JVRkZFUiwgdmVydGljZXMsIHRoaXMuZ2wuU1RBVElDX0RSQVcpO1xyXG5cclxuICAgIGNvbnN0IGFQb3NpdGlvbiA9IHRoaXMuZ2wuZ2V0QXR0cmliTG9jYXRpb24odGhpcy5wcm9ncmFtLCAnYVBvc2l0aW9uJyk7XHJcbiAgICB0aGlzLmdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KGFQb3NpdGlvbik7XHJcbiAgICB0aGlzLmdsLnZlcnRleEF0dHJpYlBvaW50ZXIoYVBvc2l0aW9uLCAyLCB0aGlzLmdsLkZMT0FULCBmYWxzZSwgMCwgMCk7XHJcblxyXG4gICAgdGhpcy5sb2NSZXNvbHV0aW9uID0gdGhpcy5nbC5nZXRVbmlmb3JtTG9jYXRpb24odGhpcy5wcm9ncmFtLCAnaVJlc29sdXRpb24nKTtcclxuICAgIHRoaXMubG9jVGltZSA9IHRoaXMuZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgJ2lUaW1lJyk7XHJcbiAgICB0aGlzLmxvY0h1ZSA9IHRoaXMuZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgJ3VIdWUnKTtcclxuICAgIHRoaXMubG9jWE9mZnNldCA9IHRoaXMuZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgJ3VYT2Zmc2V0Jyk7XHJcbiAgICB0aGlzLmxvY1NwZWVkID0gdGhpcy5nbC5nZXRVbmlmb3JtTG9jYXRpb24odGhpcy5wcm9ncmFtLCAndVNwZWVkJyk7XHJcbiAgICB0aGlzLmxvY0ludGVuc2l0eSA9IHRoaXMuZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgJ3VJbnRlbnNpdHknKTtcclxuICAgIHRoaXMubG9jU2l6ZSA9IHRoaXMuZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgJ3VTaXplJyk7XHJcblxyXG4gICAgdGhpcy5zdGFydFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcclxuXHJcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcclxuICAgICAgdGhpcy5yZXNpemVDYW52YXMoKTtcclxuICAgIH0pO1xyXG4gICAgdGhpcy5yZXNpemVPYnNlcnZlci5vYnNlcnZlKGNvbnRhaW5lcik7XHJcbiAgICB0aGlzLnJlc2l6ZUNhbnZhcygpO1xyXG5cclxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcclxuICAgICAgdGhpcy5yZW5kZXIoKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb21waWxlU2hhZGVyKHNvdXJjZTogc3RyaW5nLCB0eXBlOiBudW1iZXIpOiBXZWJHTFNoYWRlciB8IG51bGwge1xyXG4gICAgaWYgKCF0aGlzLmdsKSByZXR1cm4gbnVsbDtcclxuICAgIGNvbnN0IHNoYWRlciA9IHRoaXMuZ2wuY3JlYXRlU2hhZGVyKHR5cGUpO1xyXG4gICAgaWYgKCFzaGFkZXIpIHJldHVybiBudWxsO1xyXG4gICAgdGhpcy5nbC5zaGFkZXJTb3VyY2Uoc2hhZGVyLCBzb3VyY2UpO1xyXG4gICAgdGhpcy5nbC5jb21waWxlU2hhZGVyKHNoYWRlcik7XHJcbiAgICBpZiAoIXRoaXMuZ2wuZ2V0U2hhZGVyUGFyYW1ldGVyKHNoYWRlciwgdGhpcy5nbC5DT01QSUxFX1NUQVRVUykpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignU2hhZGVyIGNvbXBpbGUgZXJyb3I6JywgdGhpcy5nbC5nZXRTaGFkZXJJbmZvTG9nKHNoYWRlcikpO1xyXG4gICAgICB0aGlzLmdsLmRlbGV0ZVNoYWRlcihzaGFkZXIpO1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIHJldHVybiBzaGFkZXI7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlc2l6ZUNhbnZhcygpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5jYW52YXMpIHJldHVybjtcclxuICAgIGNvbnN0IHdpZHRoID0gdGhpcy5jYW52YXMuY2xpZW50V2lkdGg7XHJcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLmNhbnZhcy5jbGllbnRIZWlnaHQ7XHJcbiAgICBpZiAodGhpcy5jYW52YXMud2lkdGggIT09IHdpZHRoIHx8IHRoaXMuY2FudmFzLmhlaWdodCAhPT0gaGVpZ2h0KSB7XHJcbiAgICAgIHRoaXMuY2FudmFzLndpZHRoID0gd2lkdGg7XHJcbiAgICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IGhlaWdodDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVuZGVyID0gKCk6IHZvaWQgPT4ge1xyXG4gICAgaWYgKCF0aGlzLmdsIHx8ICF0aGlzLnByb2dyYW0pIHJldHVybjtcclxuXHJcbiAgICB0aGlzLmdsLnZpZXdwb3J0KDAsIDAsIHRoaXMuY2FudmFzLndpZHRoLCB0aGlzLmNhbnZhcy5oZWlnaHQpO1xyXG4gICAgdGhpcy5nbC51bmlmb3JtMmYodGhpcy5sb2NSZXNvbHV0aW9uLCB0aGlzLmNhbnZhcy53aWR0aCwgdGhpcy5jYW52YXMuaGVpZ2h0KTtcclxuXHJcbiAgICBjb25zdCBjdXJyZW50VGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xyXG4gICAgdGhpcy5nbC51bmlmb3JtMWYodGhpcy5sb2NUaW1lLCAoY3VycmVudFRpbWUgLSB0aGlzLnN0YXJ0VGltZSkgLyAxMDAwLjApO1xyXG4gICAgdGhpcy5nbC51bmlmb3JtMWYodGhpcy5sb2NIdWUsIHRoaXMubmNIdWUpO1xyXG4gICAgdGhpcy5nbC51bmlmb3JtMWYodGhpcy5sb2NYT2Zmc2V0LCB0aGlzLm5jWE9mZnNldCk7XHJcbiAgICB0aGlzLmdsLnVuaWZvcm0xZih0aGlzLmxvY1NwZWVkLCB0aGlzLm5jU3BlZWQpO1xyXG4gICAgdGhpcy5nbC51bmlmb3JtMWYodGhpcy5sb2NJbnRlbnNpdHksIHRoaXMubmNJbnRlbnNpdHkpO1xyXG4gICAgdGhpcy5nbC51bmlmb3JtMWYodGhpcy5sb2NTaXplLCB0aGlzLm5jU2l6ZSk7XHJcblxyXG4gICAgdGhpcy5nbC5kcmF3QXJyYXlzKHRoaXMuZ2wuVFJJQU5HTEVTLCAwLCA2KTtcclxuXHJcbiAgICB0aGlzLnJhZklkID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMucmVuZGVyKTtcclxuICB9O1xyXG59XHJcbiIsIjxkaXYgI2NvbnRhaW5lciBjbGFzcz1cIm5jLWxpZ2h0bmluZy1jYW52YXMtY29udGFpbmVyXCI+PC9kaXY+XHJcbjxkaXYgY2xhc3M9XCJuYy1jb250ZW50LXdyYXBwZXJcIj5cclxuICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cclxuPC9kaXY+XHJcbiJdfQ==