ng-cw-v12
Version:
Angular UI Component Library
482 lines (457 loc) • 59.9 kB
JavaScript
import { Component, ViewChild, Input, HostListener } from '@angular/core';
import * as THREE from 'three';
import * as i0 from "@angular/core";
;
const vertexShader = `
in vec3 position;
in vec2 uv;
out vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4(position, 1.0);
}
`;
const fragmentShader = `
precision highp float;
precision highp int;
out vec4 fragColor;
uniform vec2 uResolution;
uniform float uTime;
uniform float uIntensity;
uniform float uSpeed;
uniform int uAnimType;
uniform vec2 uMouse;
uniform int uColorCount;
uniform float uDistort;
uniform vec2 uOffset;
uniform sampler2D uGradient;
uniform float uNoiseAmount;
uniform int uRayCount;
float hash21(vec2 p){
p = floor(p);
float f = 52.9829189 * fract(dot(p, vec2(0.065, 0.005)));
return fract(f);
}
mat2 rot30(){ return mat2(0.8, -0.5, 0.5, 0.8); }
float layeredNoise(vec2 fragPx){
vec2 p = mod(fragPx + vec2(uTime * 30.0, -uTime * 21.0), 1024.0);
vec2 q = rot30() * p;
float n = 0.0;
n += 0.40 * hash21(q);
n += 0.25 * hash21(q * 2.0 + 17.0);
n += 0.20 * hash21(q * 4.0 + 47.0);
n += 0.10 * hash21(q * 8.0 + 113.0);
n += 0.05 * hash21(q * 16.0 + 191.0);
return n;
}
vec3 rayDir(vec2 frag, vec2 res, vec2 offset, float dist){
float focal = res.y * max(dist, 1e-3);
return normalize(vec3(2.0 * (frag - offset) - res, focal));
}
float edgeFade(vec2 frag, vec2 res, vec2 offset){
vec2 toC = frag - 0.5 * res - offset;
float r = length(toC) / (0.5 * min(res.x, res.y));
float x = clamp(r, 0.0, 1.0);
float q = x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
float s = q * 0.5;
s = pow(s, 1.5);
float tail = 1.0 - pow(1.0 - s, 2.0);
s = mix(s, tail, 0.2);
float dn = (layeredNoise(frag * 0.15) - 0.5) * 0.0015 * s;
return clamp(s + dn, 0.0, 1.0);
}
mat3 rotX(float a){ float c = cos(a), s = sin(a); return mat3(1.0,0.0,0.0, 0.0,c,-s, 0.0,s,c); }
mat3 rotY(float a){ float c = cos(a), s = sin(a); return mat3(c,0.0,s, 0.0,1.0,0.0, -s,0.0,c); }
mat3 rotZ(float a){ float c = cos(a), s = sin(a); return mat3(c,-s,0.0, s,c,0.0, 0.0,0.0,1.0); }
vec3 sampleGradient(float t){
t = clamp(t, 0.0, 1.0);
return texture(uGradient, vec2(t, 0.5)).rgb;
}
vec2 rot2(vec2 v, float a){
float s = sin(a), c = cos(a);
return mat2(c, -s, s, c) * v;
}
float bendAngle(vec3 q, float t){
float a = 0.8 * sin(q.x * 0.55 + t * 0.6)
+ 0.7 * sin(q.y * 0.50 - t * 0.5)
+ 0.6 * sin(q.z * 0.60 + t * 0.7);
return a;
}
void main(){
vec2 frag = gl_FragCoord.xy;
float t = uTime * uSpeed;
float jitterAmp = 0.1 * clamp(uNoiseAmount, 0.0, 1.0);
vec3 dir = rayDir(frag, uResolution, uOffset, 1.0);
float marchT = 0.0;
vec3 col = vec3(0.0);
float n = layeredNoise(frag);
vec4 c = cos(t * 0.2 + vec4(0.0, 33.0, 11.0, 0.0));
mat2 M2 = mat2(c.x, c.y, c.z, c.w);
float amp = clamp(uDistort, 0.0, 50.0) * 0.15;
mat3 rot3dMat = mat3(1.0);
if(uAnimType == 1){
vec3 ang = vec3(t * 0.31, t * 0.21, t * 0.17);
rot3dMat = rotZ(ang.z) * rotY(ang.y) * rotX(ang.x);
}
mat3 hoverMat = mat3(1.0);
if(uAnimType == 2){
vec2 m = uMouse * 2.0 - 1.0;
vec3 ang = vec3(m.y * 0.6, m.x * 0.6, 0.0);
hoverMat = rotY(ang.y) * rotX(ang.x);
}
for (int i = 0; i < 44; ++i) {
vec3 P = marchT * dir;
P.z -= 2.0;
float rad = length(P);
vec3 Pl = P * (10.0 / max(rad, 1e-6));
if(uAnimType == 0){
Pl.xz *= M2;
} else if(uAnimType == 1){
Pl = rot3dMat * Pl;
} else {
Pl = hoverMat * Pl;
}
float stepLen = min(rad - 0.3, n * jitterAmp) + 0.1;
float grow = smoothstep(0.35, 3.0, marchT);
float a1 = amp * grow * bendAngle(Pl * 0.6, t);
float a2 = 0.5 * amp * grow * bendAngle(Pl.zyx * 0.5 + 3.1, t * 0.9);
vec3 Pb = Pl;
Pb.xz = rot2(Pb.xz, a1);
Pb.xy = rot2(Pb.xy, a2);
float rayPattern = smoothstep(
0.5, 0.7,
sin(Pb.x + cos(Pb.y) * cos(Pb.z)) *
sin(Pb.z + sin(Pb.y) * cos(Pb.x + t))
);
if (uRayCount > 0) {
float ang = atan(Pb.y, Pb.x);
float comb = 0.5 + 0.5 * cos(float(uRayCount) * ang);
comb = pow(comb, 3.0);
rayPattern *= smoothstep(0.15, 0.95, comb);
}
vec3 spectralDefault = 1.0 + vec3(
cos(marchT * 3.0 + 0.0),
cos(marchT * 3.0 + 1.0),
cos(marchT * 3.0 + 2.0)
);
float saw = fract(marchT * 0.25);
float tRay = saw * saw * (3.0 - 2.0 * saw);
vec3 userGradient = 2.0 * sampleGradient(tRay);
vec3 spectral = (uColorCount > 0) ? userGradient : spectralDefault;
vec3 base = (0.05 / (0.4 + stepLen))
* smoothstep(5.0, 0.0, rad)
* spectral;
col += base * rayPattern;
marchT += stepLen;
}
col *= edgeFade(frag, uResolution, uOffset);
col *= uIntensity;
fragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
}
`;
const hexToRgb01 = (hex) => {
let h = hex.trim();
if (h.startsWith('#'))
h = h.slice(1);
if (h.length === 3) {
const r = h[0], g = h[1], b = h[2];
h = r + r + g + g + b + b;
}
const intVal = parseInt(h, 16);
if (isNaN(intVal) || (h.length !== 6 && h.length !== 8))
return [1, 1, 1];
const r = ((intVal >> 16) & 255) / 255;
const g = ((intVal >> 8) & 255) / 255;
const b = (intVal & 255) / 255;
return [r, g, b];
};
const toPx = (v) => {
if (v == null)
return 0;
if (typeof v === 'number')
return v;
const s = String(v).trim();
const num = parseFloat(s.replace('px', ''));
return isNaN(num) ? 0 : num;
};
export class PrismaticBurstBackgroundComponent {
constructor(ngZone) {
this.ngZone = ngZone;
/** 累加后应用整体亮度倍增器(0.1-5) */
this.ncIntensity = 2;
/** 控制光线运动和扭曲的全局时间倍增器(0-2) */
this.ncSpeed = 0.5;
/** 动画类型:'rotate' | '3drotate' | 'hover' */
this.ncAnimationType = '3drotate';
/** 设置特定颜色(十六进制字符串数组) */
this.ncColors = [];
/** 对行进空间施加的弯曲/扭曲程度(增加自然的摇摆感,0-10) */
this.ncDistort = 0;
/** 是否暂停动画 */
this._paused = false;
/** 中心点的偏移量 (x, y) */
this.ncOffset = { x: 0, y: 0 };
/** 当ncAnimationType='hover'时,指针跟踪的平滑因子(0-1) */
this.ncHoverDampness = 0;
/** 如果大于0,则应用角度梳状滤波器生成离散光线辐条(0-64) */
this.ncRayCount = 0;
this.mouseTarget = [0.5, 0.5];
this.mouseSmooth = [0.5, 0.5];
this.isVisible = true;
this.rafId = null;
this.lastTime = performance.now();
this.accumTime = 0;
this.onResizeBound = () => this.resizeCanvas();
this.updateLoop = (now) => {
const dt = Math.max(0, now - this.lastTime) * 0.001;
this.lastTime = now;
const visible = this.isVisible && !document.hidden;
if (!this.ncPaused) {
this.accumTime += dt;
}
if (!visible) {
this.rafId = requestAnimationFrame(this.updateLoop);
return;
}
const tau = 0.02 + Math.max(0, Math.min(1, this.ncHoverDampness)) * 0.5;
const alpha = 1 - Math.exp(-dt / tau);
const tgt = this.mouseTarget;
const sm = this.mouseSmooth;
sm[0] += (tgt[0] - sm[0]) * alpha;
sm[1] += (tgt[1] - sm[1]) * alpha;
if (this.material) {
this.material.uniforms['uMouse'].value.set(sm[0], sm[1]);
this.material.uniforms['uTime'].value = this.accumTime;
}
if (this.renderer && this.scene && this.camera) {
this.renderer.render(this.scene, this.camera);
}
this.rafId = requestAnimationFrame(this.updateLoop);
};
}
set ncPaused(val) {
this._paused = val !== null && val !== undefined && val !== false && val !== 'false';
}
get ncPaused() {
return this._paused;
}
ngOnInit() { }
ngAfterViewInit() {
this.ngZone.runOutsideAngular(() => {
this.initScene();
this.applyOptions();
this.setupObservers();
this.updateLoop(performance.now());
});
}
ngOnDestroy() {
this.cleanup();
}
ngOnChanges(changes) {
if (this.material) {
this.applyOptions();
}
}
onPointerMove(event) {
var _a;
if (!((_a = this.containerRef) === null || _a === void 0 ? void 0 : _a.nativeElement))
return;
const rect = this.containerRef.nativeElement.getBoundingClientRect();
const x = (event.clientX - rect.left) / Math.max(rect.width, 1);
const y = (event.clientY - rect.top) / Math.max(rect.height, 1);
this.mouseTarget = [Math.min(Math.max(x, 0), 1), Math.min(Math.max(y, 0), 1)];
}
onVisibilityChange() {
this.isVisible = !document.hidden;
}
initScene() {
const container = this.containerRef.nativeElement;
const dpr = Math.min(window.devicePixelRatio || 1, 2);
this.renderer = new THREE.WebGLRenderer({ alpha: false, antialias: false });
this.renderer.setPixelRatio(dpr);
// 初始化画布样式
const canvas = this.renderer.domElement;
canvas.style.position = 'absolute';
canvas.style.inset = '0';
canvas.style.width = '100%';
canvas.style.height = '100%';
container.appendChild(canvas);
this.scene = new THREE.Scene();
this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
const white = new Uint8Array([255, 255, 255, 255]);
this.gradientTex = new THREE.DataTexture(white, 1, 1, THREE.RGBAFormat);
this.gradientTex.minFilter = THREE.LinearFilter;
this.gradientTex.magFilter = THREE.LinearFilter;
this.gradientTex.wrapS = THREE.ClampToEdgeWrapping;
this.gradientTex.wrapT = THREE.ClampToEdgeWrapping;
this.gradientTex.generateMipmaps = false;
this.gradientTex.needsUpdate = true;
this.material = new THREE.RawShaderMaterial({
vertexShader: vertexShader,
fragmentShader: fragmentShader,
glslVersion: THREE.GLSL3,
uniforms: {
uResolution: { value: new THREE.Vector2(1, 1) },
uTime: { value: 0 },
uIntensity: { value: 1 },
uSpeed: { value: 1 },
uAnimType: { value: 0 },
uMouse: { value: new THREE.Vector2(0.5, 0.5) },
uColorCount: { value: 0 },
uDistort: { value: 0 },
uOffset: { value: new THREE.Vector2(0, 0) },
uGradient: { value: this.gradientTex },
uNoiseAmount: { value: 0.8 },
uRayCount: { value: 0 }
}
});
const geometry = new THREE.PlaneGeometry(2, 2);
this.mesh = new THREE.Mesh(geometry, this.material);
this.scene.add(this.mesh);
this.resizeCanvas();
}
setupObservers() {
const container = this.containerRef.nativeElement;
if (typeof ResizeObserver !== 'undefined') {
this.resizeObserver = new ResizeObserver(() => {
this.resizeCanvas();
});
this.resizeObserver.observe(container);
}
else {
window.addEventListener('resize', this.onResizeBound);
}
if (typeof IntersectionObserver !== 'undefined') {
this.intersectionObserver = new IntersectionObserver((entries) => {
if (entries[0]) {
this.isVisible = entries[0].isIntersecting;
}
}, { root: null, threshold: 0.01 });
this.intersectionObserver.observe(container);
}
}
resizeCanvas() {
if (!this.containerRef || !this.renderer)
return;
const container = this.containerRef.nativeElement;
const w = container.clientWidth || 1;
const h = container.clientHeight || 1;
// false 指代不修改 style 里面的 width 和 height
this.renderer.setSize(w, h, false);
const gl = this.renderer.getContext();
this.material.uniforms['uResolution'].value.set(gl.drawingBufferWidth, gl.drawingBufferHeight);
}
applyOptions() {
var _a, _b, _c, _d, _e, _f, _g;
if (!this.material)
return;
const uniforms = this.material.uniforms;
uniforms['uIntensity'].value = (_a = this.ncIntensity) !== null && _a !== void 0 ? _a : 1;
uniforms['uSpeed'].value = (_b = this.ncSpeed) !== null && _b !== void 0 ? _b : 1;
const animTypeMap = {
rotate: 0,
'3drotate': 1,
hover: 2
};
uniforms['uAnimType'].value = (_d = animTypeMap[(_c = this.ncAnimationType) !== null && _c !== void 0 ? _c : 'rotate']) !== null && _d !== void 0 ? _d : 0;
uniforms['uDistort'].value = typeof this.ncDistort === 'number' ? this.ncDistort : 0;
const ox = toPx((_e = this.ncOffset) === null || _e === void 0 ? void 0 : _e.x);
const oy = toPx((_f = this.ncOffset) === null || _f === void 0 ? void 0 : _f.y);
uniforms['uOffset'].value.set(ox, oy);
uniforms['uRayCount'].value = Math.max(0, Math.floor((_g = this.ncRayCount) !== null && _g !== void 0 ? _g : 0));
let count = 0;
if (Array.isArray(this.ncColors) && this.ncColors.length > 0) {
const capped = this.ncColors.slice(0, 64);
count = capped.length;
const data = new Uint8Array(count * 4);
for (let i = 0; i < count; i++) {
const [r, g, b] = hexToRgb01(capped[i]);
data[i * 4 + 0] = Math.round(r * 255);
data[i * 4 + 1] = Math.round(g * 255);
data[i * 4 + 2] = Math.round(b * 255);
data[i * 4 + 3] = 255;
}
if (this.gradientTex) {
this.gradientTex.dispose();
}
this.gradientTex = new THREE.DataTexture(data, count, 1, THREE.RGBAFormat);
this.gradientTex.minFilter = THREE.LinearFilter;
this.gradientTex.magFilter = THREE.LinearFilter;
this.gradientTex.wrapS = THREE.ClampToEdgeWrapping;
this.gradientTex.wrapT = THREE.ClampToEdgeWrapping;
this.gradientTex.generateMipmaps = false;
this.gradientTex.needsUpdate = true;
uniforms['uGradient'].value = this.gradientTex;
}
uniforms['uColorCount'].value = count;
}
cleanup() {
var _a;
if (this.rafId !== null) {
cancelAnimationFrame(this.rafId);
this.rafId = null;
}
if (this.resizeObserver) {
this.resizeObserver.disconnect();
}
window.removeEventListener('resize', this.onResizeBound);
if (this.intersectionObserver) {
this.intersectionObserver.disconnect();
}
if (this.mesh && this.scene) {
this.scene.remove(this.mesh);
this.mesh.geometry.dispose();
if (this.material) {
this.material.dispose();
}
}
if (this.gradientTex) {
this.gradientTex.dispose();
}
if (this.renderer) {
this.renderer.dispose();
const container = (_a = this.containerRef) === null || _a === void 0 ? void 0 : _a.nativeElement;
if (container && this.renderer.domElement.parentNode === container) {
container.removeChild(this.renderer.domElement);
}
}
}
}
PrismaticBurstBackgroundComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: PrismaticBurstBackgroundComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
PrismaticBurstBackgroundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: PrismaticBurstBackgroundComponent, selector: "nc-prismatic-burst-background", inputs: { ncIntensity: "ncIntensity", ncSpeed: "ncSpeed", ncAnimationType: "ncAnimationType", ncColors: "ncColors", ncDistort: "ncDistort", ncPaused: "ncPaused", ncOffset: "ncOffset", ncHoverDampness: "ncHoverDampness", ncRayCount: "ncRayCount" }, host: { listeners: { "pointermove": "onPointerMove($event)", "document:visibilitychange": "onVisibilityChange()" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #container class=\"nc-prismatic-burst-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-prismatic-burst-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: PrismaticBurstBackgroundComponent, decorators: [{
type: Component,
args: [{
selector: 'nc-prismatic-burst-background',
templateUrl: './prismatic-burst-background.component.html',
styleUrls: ['./prismatic-burst-background.component.less']
}]
}], ctorParameters: function () { return [{ type: i0.NgZone }]; }, propDecorators: { containerRef: [{
type: ViewChild,
args: ['container', { static: true }]
}], ncIntensity: [{
type: Input
}], ncSpeed: [{
type: Input
}], ncAnimationType: [{
type: Input
}], ncColors: [{
type: Input
}], ncDistort: [{
type: Input
}], ncPaused: [{
type: Input
}], ncOffset: [{
type: Input
}], ncHoverDampness: [{
type: Input
}], ncRayCount: [{
type: Input
}], onPointerMove: [{
type: HostListener,
args: ['pointermove', ['$event']]
}], onVisibilityChange: [{
type: HostListener,
args: ['document:visibilitychange']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpc21hdGljLWJ1cnN0LWJhY2tncm91bmQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9wcmlzbWF0aWMtYnVyc3QtYmFja2dyb3VuZC9wcmlzbWF0aWMtYnVyc3QtYmFja2dyb3VuZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3ByaXNtYXRpYy1idXJzdC1iYWNrZ3JvdW5kL3ByaXNtYXRpYy1idXJzdC1iYWNrZ3JvdW5kLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBSVQsU0FBUyxFQUVULEtBQUssRUFHTCxZQUFZLEVBRWIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxLQUFLLEtBQUssTUFBTSxPQUFPLENBQUM7O0FBTTlCLENBQUM7QUFFRixNQUFNLFlBQVksR0FBRzs7Ozs7Ozs7Q0FRcEIsQ0FBQztBQUVGLE1BQU0sY0FBYyxHQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FrS3RCLENBQUM7QUFFRixNQUFNLFVBQVUsR0FBRyxDQUFDLEdBQVcsRUFBNEIsRUFBRTtJQUMzRCxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbkIsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztRQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7UUFDbEIsTUFBTSxDQUFD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QWpCLEtBQUs7Z0JBSUYsUUFBUTtzQkFEWCxLQUFLO2dCQVFHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsZUFBZTtzQkFBdkIsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQTZDTixhQUFhO3NCQURaLFlBQVk7dUJBQUMsYUFBYSxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVV2QyxrQkFBa0I7c0JBRGpCLFlBQVk7dUJBQUMsMkJBQTJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgT25Jbml0LFxyXG4gIE9uRGVzdHJveSxcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIFZpZXdDaGlsZCxcclxuICBFbGVtZW50UmVmLFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBOZ1pvbmVcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0ICogYXMgVEhSRUUgZnJvbSAndGhyZWUnO1xyXG5cclxuZXhwb3J0IHR5cGUgTmNBbmltYXRpb25UeXBlVHlwZSA9ICdyb3RhdGUnIHwgJ2hvdmVyJyB8ICczZHJvdGF0ZSc7XHJcbmV4cG9ydCBpbnRlcmZhY2UgTmNPZmZzZXQge1xyXG4gIHg6IG51bWJlcjtcclxuICB5OiBudW1iZXJcclxufTtcclxuXHJcbmNvbnN0IHZlcnRleFNoYWRlciA9IGBcclxuaW4gdmVjMyBwb3NpdGlvbjtcclxuaW4gdmVjMiB1djtcclxub3V0IHZlYzIgdlV2O1xyXG52b2lkIG1haW4oKSB7XHJcbiAgICB2VXYgPSB1djtcclxuICAgIGdsX1Bvc2l0aW9uID0gdmVjNChwb3NpdGlvbiwgMS4wKTtcclxufVxyXG5gO1xyXG5cclxuY29uc3QgZnJhZ21lbnRTaGFkZXIgPSBgXHJcbnByZWNpc2lvbiBoaWdocCBmbG9hdDtcclxucHJlY2lzaW9uIGhpZ2hwIGludDtcclxuXHJcbm91dCB2ZWM0IGZyYWdDb2xvcjtcclxuXHJcbnVuaWZvcm0gdmVjMiAgdVJlc29sdXRpb247XHJcbnVuaWZvcm0gZmxvYXQgdVRpbWU7XHJcblxyXG51bmlmb3JtIGZsb2F0IHVJbnRlbnNpdHk7XHJcbnVuaWZvcm0gZmxvYXQgdVNwZWVkO1xyXG51bmlmb3JtIGludCAgIHVBbmltVHlwZTtcclxudW5pZm9ybSB2ZWMyICB1TW91c2U7XHJcbnVuaWZvcm0gaW50ICAgdUNvbG9yQ291bnQ7XHJcbnVuaWZvcm0gZmxvYXQgdURpc3RvcnQ7XHJcbnVuaWZvcm0gdmVjMiAgdU9mZnNldDtcclxudW5pZm9ybSBzYW1wbGVyMkQgdUdyYWRpZW50O1xyXG51bmlmb3JtIGZsb2F0IHVOb2lzZUFtb3VudDtcclxudW5pZm9ybSBpbnQgICB1UmF5Q291bnQ7XHJcblxyXG5mbG9hdCBoYXNoMjEodmVjMiBwKXtcclxuICAgIHAgPSBmbG9vcihwKTtcclxuICAgIGZsb2F0IGYgPSA1Mi45ODI5MTg5ICogZnJhY3QoZG90KHAsIHZlYzIoMC4wNjUsIDAuMDA1KSkpO1xyXG4gICAgcmV0dXJuIGZyYWN0KGYpO1xyXG59XHJcblxyXG5tYXQyIHJvdDMwKCl7IHJldHVybiBtYXQyKDAuOCwgLTAuNSwgMC41LCAwLjgpOyB9XHJcblxyXG5mbG9hdCBsYXllcmVkTm9pc2UodmVjMiBmcmFnUHgpe1xyXG4gICAgdmVjMiBwID0gbW9kKGZyYWdQeCArIHZlYzIodVRpbWUgKiAzMC4wLCAtdVRpbWUgKiAyMS4wKSwgMTAyNC4wKTtcclxuICAgIHZlYzIgcSA9IHJvdDMwKCkgKiBwO1xyXG4gICAgZmxvYXQgbiA9IDAuMDtcclxuICAgIG4gKz0gMC40MCAqIGhhc2gyMShxKTtcclxuICAgIG4gKz0gMC4yNSAqIGhhc2gyMShxICogMi4wICsgMTcuMCk7XHJcbiAgICBuICs9IDAuMjAgKiBoYXNoMjEocSAqIDQuMCArIDQ3LjApO1xyXG4gICAgbiArPSAwLjEwICogaGFzaDIxKHEgKiA4LjAgKyAxMTMuMCk7XHJcbiAgICBuICs9IDAuMDUgKiBoYXNoMjEocSAqIDE2LjAgKyAxOTEuMCk7XHJcbiAgICByZXR1cm4gbjtcclxufVxyXG5cclxudmVjMyByYXlEaXIodmVjMiBmcmFnLCB2ZWMyIHJlcywgdmVjMiBvZmZzZXQsIGZsb2F0IGRpc3Qpe1xyXG4gICAgZmxvYXQgZm9jYWwgPSByZXMueSAqIG1heChkaXN0LCAxZS0zKTtcclxuICAgIHJldHVybiBub3JtYWxpemUodmVjMygyLjAgKiAoZnJhZyAtIG9mZnNldCkgLSByZXMsIGZvY2FsKSk7XHJcbn1cclxuXHJcbmZsb2F0IGVkZ2VGYWRlKHZlYzIgZnJhZywgdmVjMiByZXMsIHZlYzIgb2Zmc2V0KXtcclxuICAgIHZlYzIgdG9DID0gZnJhZyAtIDAuNSAqIHJlcyAtIG9mZnNldDtcclxuICAgIGZsb2F0IHIgPSBsZW5ndGgodG9DKSAvICgwLjUgKiBtaW4ocmVzLngsIHJlcy55KSk7XHJcbiAgICBmbG9hdCB4ID0gY2xhbXAociwgMC4wLCAxLjApO1xyXG4gICAgZmxvYXQgcSA9IHggKiB4ICogeCAqICh4ICogKHggKiA2LjAgLSAxNS4wKSArIDEwLjApO1xyXG4gICAgZmxvYXQgcyA9IHEgKiAwLjU7XHJcbiAgICBzID0gcG93KHMsIDEuNSk7XHJcbiAgICBmbG9hdCB0YWlsID0gMS4wIC0gcG93KDEuMCAtIHMsIDIuMCk7XHJcbiAgICBzID0gbWl4KHMsIHRhaWwsIDAuMik7XHJcbiAgICBmbG9hdCBkbiA9IChsYXllcmVkTm9pc2UoZnJhZyAqIDAuMTUpIC0gMC41KSAqIDAuMDAxNSAqIHM7XHJcbiAgICByZXR1cm4gY2xhbXAocyArIGRuLCAwLjAsIDEuMCk7XHJcbn1cclxuXHJcbm1hdDMgcm90WChmbG9hdCBhKXsgZmxvYXQgYyA9IGNvcyhhKSwgcyA9IHNpbihhKTsgcmV0dXJuIG1hdDMoMS4wLDAuMCwwLjAsIDAuMCxjLC1zLCAwLjAscyxjKTsgfVxyXG5tYXQzIHJvdFkoZmxvYXQgYSl7IGZsb2F0IGMgPSBjb3MoYSksIHMgPSBzaW4oYSk7IHJldHVybiBtYXQzKGMsMC4wLHMsIDAuMCwxLjAsMC4wLCAtcywwLjAsYyk7IH1cclxubWF0MyByb3RaKGZsb2F0IGEpeyBmbG9hdCBjID0gY29zKGEpLCBzID0gc2luKGEpOyByZXR1cm4gbWF0MyhjLC1zLDAuMCwgcyxjLDAuMCwgMC4wLDAuMCwxLjApOyB9XHJcblxyXG52ZWMzIHNhbXBsZUdyYWRpZW50KGZsb2F0IHQpe1xyXG4gICAgdCA9IGNsYW1wKHQsIDAuMCwgMS4wKTtcclxuICAgIHJldHVybiB0ZXh0dXJlKHVHcmFkaWVudCwgdmVjMih0LCAwLjUpKS5yZ2I7XHJcbn1cclxuXHJcbnZlYzIgcm90Mih2ZWMyIHYsIGZsb2F0IGEpe1xyXG4gICAgZmxvYXQgcyA9IHNpbihhKSwgYyA9IGNvcyhhKTtcclxuICAgIHJldHVybiBtYXQyKGMsIC1zLCBzLCBjKSAqIHY7XHJcbn1cclxuXHJcbmZsb2F0IGJlbmRBbmdsZSh2ZWMzIHEsIGZsb2F0IHQpe1xyXG4gICAgZmxvYXQgYSA9IDAuOCAqIHNpbihxLnggKiAwLjU1ICsgdCAqIDAuNilcclxuICAgICAgICAgICAgKyAwLjcgKiBzaW4ocS55ICogMC41MCAtIHQgKiAwLjUpXHJcbiAgICAgICAgICAgICsgMC42ICogc2luKHEueiAqIDAuNjAgKyB0ICogMC43KTtcclxuICAgIHJldHVybiBhO1xyXG59XHJcblxyXG52b2lkIG1haW4oKXtcclxuICAgIHZlYzIgZnJhZyA9IGdsX0ZyYWdDb29yZC54eTtcclxuICAgIGZsb2F0IHQgPSB1VGltZSAqIHVTcGVlZDtcclxuICAgIGZsb2F0IGppdHRlckFtcCA9IDAuMSAqIGNsYW1wKHVOb2lzZUFtb3VudCwgMC4wLCAxLjApO1xyXG4gICAgdmVjMyBkaXIgPSByYXlEaXIoZnJhZywgdVJlc29sdXRpb24sIHVPZmZzZXQsIDEuMCk7XHJcbiAgICBmbG9hdCBtYXJjaFQgPSAwLjA7XHJcbiAgICB2ZWMzIGNvbCA9IHZlYzMoMC4wKTtcclxuICAgIGZsb2F0IG4gPSBsYXllcmVkTm9pc2UoZnJhZyk7XHJcbiAgICB2ZWM0IGMgPSBjb3ModCAqIDAuMiArIHZlYzQoMC4wLCAzMy4wLCAxMS4wLCAwLjApKTtcclxuICAgIG1hdDIgTTIgPSBtYXQyKGMueCwgYy55LCBjLnosIGMudyk7XHJcbiAgICBmbG9hdCBhbXAgPSBjbGFtcCh1RGlzdG9ydCwgMC4wLCA1MC4wKSAqIDAuMTU7XHJcblxyXG4gICAgbWF0MyByb3QzZE1hdCA9IG1hdDMoMS4wKTtcclxuICAgIGlmKHVBbmltVHlwZSA9PSAxKXtcclxuICAgICAgdmVjMyBhbmcgPSB2ZWMzKHQgKiAwLjMxLCB0ICogMC4yMSwgdCAqIDAuMTcpO1xyXG4gICAgICByb3QzZE1hdCA9IHJvdFooYW5nLnopICogcm90WShhbmcueSkgKiByb3RYKGFuZy54KTtcclxuICAgIH1cclxuICAgIG1hdDMgaG92ZXJNYXQgPSBtYXQzKDEuMCk7XHJcbiAgICBpZih1QW5pbVR5cGUgPT0gMil7XHJcbiAgICAgIHZlYzIgbSA9IHVNb3VzZSAqIDIuMCAtIDEuMDtcclxuICAgICAgdmVjMyBhbmcgPSB2ZWMzKG0ueSAqIDAuNiwgbS54ICogMC42LCAwLjApO1xyXG4gICAgICBob3Zlck1hdCA9IHJvdFkoYW5nLnkpICogcm90WChhbmcueCk7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0NDsgKytpKSB7XHJcbiAgICAgICAgdmVjMyBQID0gbWFyY2hUICogZGlyO1xyXG4gICAgICAgIFAueiAtPSAyLjA7XHJcbiAgICAgICAgZmxvYXQgcmFkID0gbGVuZ3RoKFApO1xyXG4gICAgICAgIHZlYzMgUGwgPSBQICogKDEwLjAgLyBtYXgocmFkLCAxZS02KSk7XHJcblxyXG4gICAgICAgIGlmKHVBbmltVHlwZSA9PSAwKXtcclxuICAgICAgICAgICAgUGwueHogKj0gTTI7XHJcbiAgICAgICAgfSBlbHNlIGlmKHVBbmltVHlwZSA9PSAxKXtcclxuICAgICAgUGwgPSByb3QzZE1hdCAqIFBsO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgIFBsID0gaG92ZXJNYXQgKiBQbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZsb2F0IHN0ZXBMZW4gPSBtaW4ocmFkIC0gMC4zLCBuICogaml0dGVyQW1wKSArIDAuMTtcclxuXHJcbiAgICAgICAgZmxvYXQgZ3JvdyA9IHNtb290aHN0ZXAoMC4zNSwgMy4wLCBtYXJjaFQpO1xyXG4gICAgICAgIGZsb2F0IGExID0gYW1wICogZ3JvdyAqIGJlbmRBbmdsZShQbCAqIDAuNiwgdCk7XHJcbiAgICAgICAgZmxvYXQgYTIgPSAwLjUgKiBhbXAgKiBncm93ICogYmVuZEFuZ2xlKFBsLnp5eCAqIDAuNSArIDMuMSwgdCAqIDAuOSk7XHJcbiAgICAgICAgdmVjMyBQYiA9IFBsO1xyXG4gICAgICAgIFBiLnh6ID0gcm90MihQYi54eiwgYTEpO1xyXG4gICAgICAgIFBiLnh5ID0gcm90MihQYi54eSwgYTIpO1xyXG5cclxuICAgICAgICBmbG9hdCByYXlQYXR0ZXJuID0gc21vb3Roc3RlcChcclxuICAgICAgICAgICAgMC41LCAwLjcsXHJcbiAgICAgICAgICAgIHNpbihQYi54ICsgY29zKFBiLnkpICogY29zKFBiLnopKSAqXHJcbiAgICAgICAgICAgIHNpbihQYi56ICsgc2luKFBiLnkpICogY29zKFBiLnggKyB0KSlcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICBpZiAodVJheUNvdW50ID4gMCkge1xyXG4gICAgICAgICAgICBmbG9hdCBhbmcgPSBhdGFuKFBiLnksIFBiLngpO1xyXG4gICAgICAgICAgICBmbG9hdCBjb21iID0gMC41ICsgMC41ICogY29zKGZsb2F0KHVSYXlDb3VudCkgKiBhbmcpO1xyXG4gICAgICAgICAgICBjb21iID0gcG93KGNvbWIsIDMuMCk7XHJcbiAgICAgICAgICAgIHJheVBhdHRlcm4gKj0gc21vb3Roc3RlcCgwLjE1LCAwLjk1LCBjb21iKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZlYzMgc3BlY3RyYWxEZWZhdWx0ID0gMS4wICsgdmVjMyhcclxuICAgICAgICAgICAgY29zKG1hcmNoVCAqIDMuMCArIDAuMCksXHJcbiAgICAgICAgICAgIGNvcyhtYXJjaFQgKiAzLjAgKyAxLjApLFxyXG4gICAgICAgICAgICBjb3MobWFyY2hUICogMy4wICsgMi4wKVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGZsb2F0IHNhdyA9IGZyYWN0KG1hcmNoVCAqIDAuMjUpO1xyXG4gICAgICAgIGZsb2F0IHRSYXkgPSBzYXcgKiBzYXcgKiAoMy4wIC0gMi4wICogc2F3KTtcclxuICAgICAgICB2ZWMzIHVzZXJHcmFkaWVudCA9IDIuMCAqIHNhbXBsZUdyYWRpZW50KHRSYXkpO1xyXG4gICAgICAgIHZlYzMgc3BlY3RyYWwgPSAodUNvbG9yQ291bnQgPiAwKSA/IHVzZXJHcmFkaWVudCA6IHNwZWN0cmFsRGVmYXVsdDtcclxuICAgICAgICB2ZWMzIGJhc2UgPSAoMC4wNSAvICgwLjQgKyBzdGVwTGVuKSlcclxuICAgICAgICAgICAgICAgICAgKiBzbW9vdGhzdGVwKDUuMCwgMC4wLCByYWQpXHJcbiAgICAgICAgICAgICAgICAgICogc3BlY3RyYWw7XHJcblxyXG4gICAgICAgIGNvbCArPSBiYXNlICogcmF5UGF0dGVybjtcclxuICAgICAgICBtYXJjaFQgKz0gc3RlcExlbjtcclxuICAgIH1cclxuXHJcbiAgICBjb2wgKj0gZWRnZUZhZGUoZnJhZywgdVJlc29sdXRpb24sIHVPZmZzZXQpO1xyXG4gICAgY29sICo9IHVJbnRlbnNpdHk7XHJcblxyXG4gICAgZnJhZ0NvbG9yID0gdmVjNChjbGFtcChjb2wsIDAuMCwgMS4wKSwgMS4wKTtcclxufVxyXG5gO1xyXG5cclxuY29uc3QgaGV4VG9SZ2IwMSA9IChoZXg6IHN0cmluZyk6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9PiB7XHJcbiAgbGV0IGggPSBoZXgudHJpbSgpO1xyXG4gIGlmIChoLnN0YXJ0c1dpdGgoJyMnKSkgaCA9IGguc2xpY2UoMSk7XHJcbiAgaWYgKGgubGVuZ3RoID09PSAzKSB7XHJcbiAgICBjb25zdCByID0gaFswXSxcclxuICAgICAgZyA9IGhbMV0sXHJcbiAgICAgIGIgPSBoWzJdO1xyXG4gICAgaCA9IHIgKyByICsgZyArIGcgKyBiICsgYjtcclxuICB9XHJcbiAgY29uc3QgaW50VmFsID0gcGFyc2VJbnQoaCwgMTYpO1xyXG4gIGlmIChpc05hTihpbnRWYWwpIHx8IChoLmxlbmd0aCAhPT0gNiAmJiBoLmxlbmd0aCAhPT0gOCkpIHJldHVybiBbMSwgMSwgMV07XHJcbiAgY29uc3QgciA9ICgoaW50VmFsID4+IDE2KSAmIDI1NSkgLyAyNTU7XHJcbiAgY29uc3QgZyA9ICgoaW50VmFsID4+IDgpICYgMjU1KSAvIDI1NTtcclxuICBjb25zdCBiID0gKGludFZhbCAmIDI1NSkgLyAyNTU7XHJcbiAgcmV0dXJuIFtyLCBnLCBiXTtcclxufTtcclxuXHJcbmNvbnN0IHRvUHggPSAodjogYW55KTogbnVtYmVyID0+IHtcclxuICBpZiAodiA9PSBudWxsKSByZXR1cm4gMDtcclxuICBpZiAodHlwZW9mIHYgPT09ICdudW1iZXInKSByZXR1cm4gdjtcclxuICBjb25zdCBzID0gU3RyaW5nKHYpLnRyaW0oKTtcclxuICBjb25zdCBudW0gPSBwYXJzZUZsb2F0KHMucmVwbGFjZSgncHgnLCAnJykpO1xyXG4gIHJldHVybiBpc05hTihudW0pID8gMCA6IG51bTtcclxufTtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbmMtcHJpc21hdGljLWJ1cnN0LWJhY2tncm91bmQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9wcmlzbWF0aWMtYnVyc3QtYmFja2dyb3VuZC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vcHJpc21hdGljLWJ1cnN0LWJhY2tncm91bmQuY29tcG9uZW50Lmxlc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgUHJpc21hdGljQnVyc3RCYWNrZ3JvdW5kQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcyB7XHJcbiAgQFZpZXdDaGlsZCgnY29udGFpbmVyJywgeyBzdGF0aWM6IHRydWUgfSkgY29udGFpbmVyUmVmITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XHJcblxyXG4gIC8qKiDntK/liqDlkI7lupTnlKjmlbTkvZPkuq7luqblgI3lop7lmajvvIgwLjEtNe+8iSAqL1xyXG4gIEBJbnB1dCgpIG5jSW50ZW5zaXR5OiBudW1iZXIgPSAyO1xyXG4gIC8qKiDmjqfliLblhYnnur/ov5Dliqjlkozmia3mm7LnmoTlhajlsYDml7bpl7TlgI3lop7lmajvvIgwLTLvvIkgKi9cclxuICBASW5wdXQoKSBuY1NwZWVkOiBudW1iZXIgPSAwLjU7XHJcbiAgLyoqIOWKqOeUu+exu+Wei++8midyb3RhdGUnIHwgJzNkcm90YXRlJyB8ICdob3ZlcicgKi9cclxuICBASW5wdXQoKSBuY0FuaW1hdGlvblR5cGU6IE5jQW5pbWF0aW9uVHlwZVR5cGUgPSAnM2Ryb3RhdGUnO1xyXG4gIC8qKiDorr7nva7nibnlrprpopzoibLvvIjljYHlha3ov5vliLblrZfnrKbkuLLmlbDnu4TvvIkgKi9cclxuICBASW5wdXQoKSBuY0NvbG9yczogc3RyaW5nW10gPSBbXTtcclxuICAvKiog5a+56KGM6L+b56m66Ze05pa95Yqg55qE5byv5puyL+aJreabsueoi+W6pu+8iOWinuWKoOiHqueEtueahOaRh+aRhuaEnywwLTEw77yJICovXHJcbiAgQElucHV0KCkgbmNEaXN0b3J0OiBudW1iZXIgPSAwO1xyXG4gIC8qKiDmmK/lkKbmmoLlgZzliqjnlLsgKi9cclxuICBwcml2YXRlIF9wYXVzZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKVxyXG4gIHNldCBuY1BhdXNlZCh2YWw6IGJvb2xlYW4gfCBzdHJpbmcpIHtcclxuICAgIHRoaXMuX3BhdXNlZCA9IHZhbCAhPT0gbnVsbCAmJiB2YWwgIT09IHVuZGVmaW5lZCAmJiB2YWwgIT09IGZhbHNlICYmIHZhbCAhPT0gJ2ZhbHNlJztcclxuICB9XHJcbiAgZ2V0IG5jUGF1c2VkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX3BhdXNlZDtcclxuICB9XHJcbiAgLyoqIOS4reW/g+eCueeahOWBj+enu+mHjyAoeCwgeSkgKi9cclxuICBASW5wdXQoKSBuY09mZnNldDogTmNPZmZzZXQgPSB7IHg6IDAsIHk6IDAgfTtcclxuICAvKiog5b2TbmNBbmltYXRpb25UeXBlPSdob3Zlcifml7bvvIzmjIfpkojot5/ouKrnmoTlubPmu5Hlm6DlrZDvvIgwLTHvvIkgKi9cclxuICBASW5wdXQoKSBuY0hvdmVyRGFtcG5lc3M6IG51bWJlciA9IDA7XHJcbiAgLyoqIOWmguaenOWkp+S6jjDvvIzliJnlupTnlKjop5LluqbmorPnirbmu6Tms6LlmajnlJ/miJDnprvmlaPlhYnnur/ovpDmnaHvvIgwLTY077yJICovXHJcbiAgQElucHV0KCkgbmNSYXlDb3VudDogbnVtYmVyID0gMDtcclxuXHJcblxyXG4gIHByaXZhdGUgcmVuZGVyZXIhOiBUSFJFRS5XZWJHTFJlbmRlcmVyO1xyXG4gIHByaXZhdGUgc2NlbmUhOiBUSFJFRS5TY2VuZTtcclxuICBwcml2YXRlIGNhbWVyYSE6IFRIUkVFLk9ydGhvZ3JhcGhpY0NhbWVyYTtcclxuICBwcml2YXRlIG1hdGVyaWFsITogVEhSRUUuUmF3U2hhZGVyTWF0ZXJpYWw7XHJcbiAgcHJpdmF0ZSBtZXNoITogVEhSRUUuTWVzaDtcclxuICBwcml2YXRlIGdyYWRpZW50VGV4ITogVEhSRUUuRGF0YVRleHR1cmU7XHJcblxyXG4gIHByaXZhdGUgbW91c2VUYXJnZXQ6IFtudW1iZXIsIG51bWJlcl0gPSBbMC41LCAwLjVdO1xyXG4gIHByaXZhdGUgbW91c2VTbW9vdGg6IFtudW1iZXIsIG51bWJlcl0gPSBbMC41LCAwLjVdO1xyXG4gIHByaXZhdGUgaXNWaXNpYmxlOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgcHJpdmF0ZSByYWZJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSByZXNpemVPYnNlcnZlciE6IFJlc2l6ZU9ic2VydmVyO1xyXG4gIHByaXZhdGUgaW50ZXJzZWN0aW9uT2JzZXJ2ZXIhOiBJbnRlcnNlY3Rpb25PYnNlcnZlcjtcclxuXHJcbiAgcHJpdmF0ZSBsYXN0VGltZTogbnVtYmVyID0gcGVyZm9ybWFuY2Uubm93KCk7XHJcbiAgcHJpdmF0ZSBhY2N1bVRpbWU6IG51bWJlciA9IDA7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbmdab25lOiBOZ1pvbmUpIHsgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHsgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcbiAgICAgIHRoaXMuaW5pdFNjZW5lKCk7XHJcbiAgICAgIHRoaXMuYXBwbHlPcHRpb25zKCk7XHJcbiAgICAgIHRoaXMuc2V0dXBPYnNlcnZlcnMoKTtcclxuICAgICAgdGhpcy51cGRhdGVMb29wKHBlcmZvcm1hbmNlLm5vdygpKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLmNsZWFudXAoKTtcclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLm1hdGVyaWFsKSB7XHJcbiAgICAgIHRoaXMuYXBwbHlPcHRpb25zKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdwb2ludGVybW92ZScsIFsnJGV2ZW50J10pXHJcbiAgb25Qb2ludGVyTW92ZShldmVudDogUG9pbnRlckV2ZW50KTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuY29udGFpbmVyUmVmPy5uYXRpdmVFbGVtZW50KSByZXR1cm47XHJcbiAgICBjb25zdCByZWN0ID0gdGhpcy5jb250YWluZXJSZWYubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIGNvbnN0IHggPSAoZXZlbnQuY2xpZW50WCAtIHJlY3QubGVmdCkgLyBNYXRoLm1heChyZWN0LndpZHRoLCAxKTtcclxuICAgIGNvbnN0IHkgPSAoZXZlbnQuY2xpZW50WSAtIHJlY3QudG9wKSAvIE1hdGgubWF4KHJlY3QuaGVpZ2h0LCAxKTtcclxuICAgIHRoaXMubW91c2VUYXJnZXQgPSBbTWF0aC5taW4oTWF0aC5tYXgoeCwgMCksIDEpLCBNYXRoLm1pbihNYXRoLm1heCh5LCAwKSwgMSldO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6dmlzaWJpbGl0eWNoYW5nZScpXHJcbiAgb25WaXNpYmlsaXR5Q2hhbmdlKCk6IHZvaWQge1xyXG4gICAgdGhpcy5pc1Zpc2libGUgPSAhZG9jdW1lbnQuaGlkZGVuO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbml0U2NlbmUoKTogdm9pZCB7XHJcbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lclJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgY29uc3QgZHByID0gTWF0aC5taW4od2luZG93LmRldmljZVBpeGVsUmF0aW8gfHwgMSwgMik7XHJcblxyXG4gICAgdGhpcy5yZW5kZXJlciA9IG5ldyBUSFJFRS5XZWJHTFJlbmRlcmVyKHsgYWxwaGE6IGZhbHNlLCBhbnRpYWxpYXM6IGZhbHNlIH0pO1xyXG4gICAgdGhpcy5yZW5kZXJlci5zZXRQaXhlbFJhdGlvKGRwcik7XHJcblxyXG4gICAgLy8g5Yid5aeL5YyW55S75biD5qC3